Re: [PATCH v4 1/3] usb: ehci: add freescale imx28 special write register method

2013-11-12 Thread Greg KH
On Tue, Nov 12, 2013 at 09:15:18AM +0800, Peter Chen wrote:
> On Mon, Nov 11, 2013 at 10:32:51PM +0100, Marc Kleine-Budde wrote:
> > On 10/30/2013 04:06 AM, Peter Chen wrote:
> > > According to Freescale imx28 Errata, "ENGR119653 USB: ARM to USB
> > > register error issue", All USB register write operations must
> > > use the ARM SWP instruction. So, we implement a special ehci_write
> > > for imx28.
> > > 
> > > Discussion for it at below:
> > > http://marc.info/?l=linux-usb&m=137996395529294&w=2
> > > 
> > > Signed-off-by: Peter Chen 
> > > Acked-by: Alan Stern 
> > > ---
> > >  drivers/usb/host/ehci.h |   13 +
> > >  1 files changed, 13 insertions(+), 0 deletions(-)
> > > 
> > > diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
> > > index e8f41c5..535aa8b 100644
> > > --- a/drivers/usb/host/ehci.h
> > > +++ b/drivers/usb/host/ehci.h
> > > @@ -225,6 +225,7 @@ struct ehci_hcd { /* one per 
> > > controller */
> > >   unsignedhas_synopsys_hc_bug:1; /* Synopsys HC */
> > >   unsignedframe_index_bug:1; /* MosChip (AKA NetMos) */
> > >   unsignedneed_oc_pp_cycle:1; /* MPC834X port power */
> > > + unsignedimx28_write_fix:1; /* For Freescale i.MX28 */
> > >  
> > >   /* required for usb32 quirk */
> > >   #define OHCI_CTRL_HCFS  (3 << 6)
> > > @@ -728,6 +729,13 @@ static inline unsigned int ehci_readl(const struct 
> > > ehci_hcd *ehci,
> > >  #endif
> > >  }
> > >  
> > > +#ifdef CONFIG_SOC_IMX28
> > > +static inline void imx28_ehci_writel(u32 val32, volatile u32 *addr)
> > 
> > You should annotate the addr pointer with __iomem, or better use the
> > signature of ehci_writel():
> > 
> > static inline void imx28_ehci_writel(const unsinged int val32, __u32
> > __iomem *addr)
> > 
> 
> I agree, but volatile is needed as it needs to read/write from io address.

Then the code is wrong, please fix it.
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] usb: chipidea: udc: first start device on pullup

2013-11-12 Thread Peter Chen
On Tue, Nov 12, 2013 at 08:36:47AM +0100, Michael Grzeschik wrote:
> Hi Peter,
> 
> On Tue, Nov 12, 2013 at 10:59:09AM +0800, Peter Chen wrote:
> > On Mon, Nov 11, 2013 at 04:37:26PM +0100, Michael Grzeschik wrote:
> > > On Mon, Nov 11, 2013 at 09:42:35PM +0800, Peter Chen wrote:
> > > > On Mon, Nov 11, 2013 at 12:39:30PM +0100, Michael Grzeschik wrote:
> > > > > Don't pullup the resistors on hw_device_state. The gadget framework 
> > > > > has
> > > > > the prepared callback for this. This is necessary if we use gadgets
> > > > > which need to be enabled after an userspace application got prepared, 
> > > > > or
> > > > > other delayed conditiions have passed.
> > > > > 
> > > > > Signed-off-by: Michael Grzeschik 
> > > > > ---
> > > > >  drivers/usb/chipidea/udc.c | 2 --
> > > > >  1 file changed, 2 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
> > > > > index b34c819..976153f 100644
> > > > > --- a/drivers/usb/chipidea/udc.c
> > > > > +++ b/drivers/usb/chipidea/udc.c
> > > > > @@ -84,10 +84,8 @@ static int hw_device_state(struct ci_hdrc *ci, u32 
> > > > > dma)
> > > > >   /* interrupt, error, port change, reset, sleep/suspend 
> > > > > */
> > > > >   hw_write(ci, OP_USBINTR, ~0,
> > > > >
> > > > > USBi_UI|USBi_UEI|USBi_PCI|USBi_URI|USBi_SLI);
> > > > > - hw_write(ci, OP_USBCMD, USBCMD_RS, USBCMD_RS);
> > > > >   } else {
> > > > >   hw_write(ci, OP_USBINTR, ~0, 0);
> > > > > - hw_write(ci, OP_USBCMD, USBCMD_RS, 0);
> > > > >   }
> > > > >   return 0;
> > > > >  }
> > > > 
> > > > Hi Michael, you submitted a similar patch before to fix uvc problem,
> > > > but you can't simply delete it, it will cause the udc can't work
> > > > if we load gadget first, then plug in the usb cable.
> > > 
> > > Yes, you also mentioned this the last time. But here, when the
> > > gadget was loaded first and plugged in afterwarts works as well.
> > > 
> > 
> > It can't work at my place, how it can work? There is no place to
> > set usbcmd.rs, you can read the register usbcmd after load gadget module.
> > 
> > > Did you see when the pullup function get called? I did also send a
> > > patch that is changing the pullup call inside the gadget drivers.
> > > 
> > 
> > Current, usbcmd.rs is only set by two places at udc.c
> > 
> > - hw_device_state
> > - ci_duc_pullup (if vbus is there)
> > 
> > If you delete it at hw_device_state, the usb_gadget_connect can't
> > set it without vbus. I don't know why it can work at your place
> > since there is no place to set USBCMD_RS if we load gadget first, then
> > plug in usb cable.
> > 
> > Besides, if the port support dual role switch, if the gadget is loaded
> > first, then do peripheral->host and host->peripheral,(the usbcmd.rs is 
> > cleared
> > at that time), then connect vbus, no place to pull up dp.
> > 
> 
> I checked it again. Yes we miss the RS toggle in vbus_session with that
> patch. Sorry for the confusion. But we somehow need to miss the first RS
> toggle in ci_udc_start. How about givin hw_device_state an parameter for
> that.

Yes, In fact, there are two places you need to modify:

- hw_device_state at chipidea/udc.c
- udc_bind_to_driver at gadget/udc-core.c (it will call .pullup,
if vbus is there, the usbcmd.rs will still be set)

Peter

> 
> > > > To fix it, it is better mark that gadget as defer_connect, and
> > > > introduce such condition at udc driver.
> > > 
> > > No, I don't see why this needs to be specially handled inside this
> > > driver. We have the framework for this. USBCMD_RS does pullup the
> > > DP resistor.
> > > 
> > > The datasheet says, that we have to ensure that the device needs to be
> > > properly setup before touching this bit. As the framework does call
> > > usb_gadget_connect after the gadget has started and connected to the udc
> > > this should be the case.
> > > 
> > 
> > We all hope all things can be done at udc core, but it still has lots
> > of work to do, we had a discussion it before, see below thread:
> > 
> > http://marc.info/?l=linux-usb&m=136335043303602&w=2
> 
> I did miss that thread.
> 
> Thanks,
> Michael
> 
> -- 
> Pengutronix e.K.   | |
> Industrial Linux Solutions | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0|
> Amtsgericht Hildesheim, HRA 2686   | Fax:   +49-5121-206917- |
> 

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 1/3] usb: ehci: add freescale imx28 special write register method

2013-11-12 Thread Peter Chen
On Tue, Nov 12, 2013 at 12:02:26AM -0800, Greg KH wrote:
> On Tue, Nov 12, 2013 at 09:15:18AM +0800, Peter Chen wrote:
> > On Mon, Nov 11, 2013 at 10:32:51PM +0100, Marc Kleine-Budde wrote:
> > > On 10/30/2013 04:06 AM, Peter Chen wrote:
> > > > According to Freescale imx28 Errata, "ENGR119653 USB: ARM to USB
> > > > register error issue", All USB register write operations must
> > > > use the ARM SWP instruction. So, we implement a special ehci_write
> > > > for imx28.
> > > > 
> > > > Discussion for it at below:
> > > > http://marc.info/?l=linux-usb&m=137996395529294&w=2
> > > > 
> > > > Signed-off-by: Peter Chen 
> > > > Acked-by: Alan Stern 
> > > > ---
> > > >  drivers/usb/host/ehci.h |   13 +
> > > >  1 files changed, 13 insertions(+), 0 deletions(-)
> > > > 
> > > > diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
> > > > index e8f41c5..535aa8b 100644
> > > > --- a/drivers/usb/host/ehci.h
> > > > +++ b/drivers/usb/host/ehci.h
> > > > @@ -225,6 +225,7 @@ struct ehci_hcd {   /* one per 
> > > > controller */
> > > > unsignedhas_synopsys_hc_bug:1; /* Synopsys HC */
> > > > unsignedframe_index_bug:1; /* MosChip (AKA 
> > > > NetMos) */
> > > > unsignedneed_oc_pp_cycle:1; /* MPC834X port 
> > > > power */
> > > > +   unsignedimx28_write_fix:1; /* For Freescale 
> > > > i.MX28 */
> > > >  
> > > > /* required for usb32 quirk */
> > > > #define OHCI_CTRL_HCFS  (3 << 6)
> > > > @@ -728,6 +729,13 @@ static inline unsigned int ehci_readl(const struct 
> > > > ehci_hcd *ehci,
> > > >  #endif
> > > >  }
> > > >  
> > > > +#ifdef CONFIG_SOC_IMX28
> > > > +static inline void imx28_ehci_writel(u32 val32, volatile u32 *addr)
> > > 
> > > You should annotate the addr pointer with __iomem, or better use the
> > > signature of ehci_writel():
> > > 
> > > static inline void imx28_ehci_writel(const unsinged int val32, __u32
> > > __iomem *addr)
> > > 
> > 
> > I agree, but volatile is needed as it needs to read/write from io address.
> 
> Then the code is wrong, please fix it.

Yes, please omit v4, I will send v5 patchset.

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH] usb: xhci: Link TRB must not occur with a USB payload burst.

2013-11-12 Thread David Laight
> You're right.  I do wish the spec had been written more clearly.

I've read a lot of hardware specs in my time ...

> > Reading it all again makes me think that a LINK trb is only
> > allowed on the burst boundary (which might be 16k bytes).
> > The only real way to implement that is to ensure that TD never
> > contain LINK TRB.
> 
> That's one way to do it.  Or you could allow a Link TRB at an
> intermediate MBP boundary.

If all the fragments are larger than the MBP (assume 16k) then
that would be relatively easy. However that is very dependant
on the source of the data. It might be true for disk data, but
is unlikely to be true for ethernet data.

For bulk data the link TRB can be forced at a packet boundary
by splitting the TD up - the receiving end won't know the difference.

> It comes down to a question of how often you want the controller to
> issue an interrupt.  If a ring segment is 4 KB (one page), then it can
> hold 256 TRBs.  With scatter-gather transfers, each SG element
> typically refers to something like a 2-page buffer (depends on how
> fragmented the memory is).  Therefore a ring segment will describe
> somewhere around 512 pages of data, i.e., something like 2 MB.  Since
> SuperSpeed is 500 MB/s, you'd end up getting in the vicinity of 250
> interrupts every second just because of ring segment crossings.

250 interrupts/sec is noise. Send/receive 13000 ethernet packets/sec
and then look at the interrupt rate!

There is no necessity for taking an interrupt from every link segment.
OTOH an interrupt is requested for every bulk TD.
I'm sending ethernet data (with TSO) and each TD is just under 64k
mostly made up of 3 or 4 fragments.
The receive side is interrupting for every receive packet.

> Using larger ring segments would help.

The current ring segments contain 64 entries, a strange choice
since they are created with 2 segments.
(The ring expansion code soon doubles that for my ethernet traffic.)

I would change the code to use a single segment (for coding simplicity)
and queue bulk URB when there isn't enough ring space.
URB with too many fragments could either be rejected, sent in sections,
or partially linearised (and probably still sent in sections).

David



--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: huawei_cdc_ncm driver

2013-11-12 Thread Thomas Schäfer
Hi,


> I do not have any Huawei NCM device, so I cannot really test the new
> huawei_cdc_ncm. 

> A simple test would be just reverting commit 9fea037de5f3 ("net:
> cdc_ncm: remove non-standard NCM device IDs"), to make the cdc_ncm
> driver (with all the recent changes) handle this device again.

I have done the steps above. The two devices bind now to cdc_ncm again, but 
they still don't work.


> 
> If that still does not change anything, then I'd really appreciate it if
> you could run through (assuming the v3.11 driver was OK):
> 
>   git bisect start 9fea037de5f3 v3.11 -- drivers/net/usb/cdc_ncm.c
> 
> This should pinpoint the exact change to cdc_ncm.c that made your device
> start failing, assuming it is a cdc_ncm change that is the cause...

This test is ongoing (compiling on cheap netbooks takes time)


> 
> Actually it would be good to first verify that v3.11 version of cdc_ncm
> still works on top of net-next, eliminating any core changes:
> 
>   git reset v3.11 drivers/net/usb/cdc_ncm.c include/linux/usb/cdc_ncm.h
>   git checkout drivers/net/usb/cdc_ncm.c include/linux/usb/cdc_ncm.h

If compiling fails, I will do that.

Thanks so far for your support.

> 
> Run
> 
>   git reset --hard
> 
> to get back to a clean HEAD after that test.  If that didn't work, then
> there is no need to run the limited bisect command above.  But you might
> consider doing a full bisect from the last working kernel version
> instead.  This will be a few more steps, though.

The last working version is release 3.12. 

Don't worry to much. Maybe the netfilter people made some things temporally 
broken, or I inherit the wrong .config of the kernel.

The chance is good, that the error is sitting in front of my desk.

Thomas 



--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] usb: chipidea: udc: first start device on pullup

2013-11-12 Thread Michael Grzeschik
Don't start hw_device_state on udc_start. The gadget framework has
the prepared pullup callback for this. This is necessary if we use gadgets
which need to be enabled after an userspace application got prepared, or
other delayed conditiions have passed.

Signed-off-by: Michael Grzeschik 
---

Hi Peter,

I checked ci_udc_start again and realized that one problem is
that we ignore the pullup call and start the device on udc_start.

What do you think of the following patch? Any objections?

 drivers/usb/chipidea/udc.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index b34c819..e673263 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1647,11 +1647,6 @@ static int ci_udc_start(struct usb_gadget *gadget,
return retval;
}
 
-   retval = hw_device_state(ci, ci->ep0out->qh.dma);
-   spin_unlock_irqrestore(&ci->lock, flags);
-   if (retval)
-   pm_runtime_put_sync(&ci->gadget.dev);
-
return retval;
 }
 
-- 
1.8.4.2

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] usb: chipidea: udc: first start device on pullup

2013-11-12 Thread Peter Chen
On Tue, Nov 12, 2013 at 7:50 PM, Michael Grzeschik
 wrote:
> Don't start hw_device_state on udc_start. The gadget framework has
> the prepared pullup callback for this. This is necessary if we use gadgets
> which need to be enabled after an userspace application got prepared, or
> other delayed conditiions have passed.
>
> Signed-off-by: Michael Grzeschik 
> ---
>
> Hi Peter,
>
> I checked ci_udc_start again and realized that one problem is
> that we ignore the pullup call and start the device on udc_start.
>
> What do you think of the following patch? Any objections?
>
>  drivers/usb/chipidea/udc.c | 5 -
>  1 file changed, 5 deletions(-)
>
> diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
> index b34c819..e673263 100644
> --- a/drivers/usb/chipidea/udc.c
> +++ b/drivers/usb/chipidea/udc.c
> @@ -1647,11 +1647,6 @@ static int ci_udc_start(struct usb_gadget *gadget,
> return retval;
> }
>
> -   retval = hw_device_state(ci, ci->ep0out->qh.dma);
> -   spin_unlock_irqrestore(&ci->lock, flags);
> -   if (retval)
> -   pm_runtime_put_sync(&ci->gadget.dev);
> -
> return retval;
>  }
>
Hi Michael,

Your code base seems out of date.

The reason why we need start controller(call hw_device_state) at ci_udc_start:

- For vbus is already there before modprobe gadget, in that case, there
is no vbus interrupt due to vbus has not changed during the initialization.
- For the platforms which have no vbus interrupt, it needs to start controller
before connection otherwise the enumeration can't be started due to
usbcmd.rs is 0.

-- 
BR,
Peter Chen
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 2/5] usb: gadget: add quirk_ep_out_aligned_size field to struct usb_gadget

2013-11-12 Thread Michal Nazarewicz
On Tue, Nov 12 2013, David Cohen wrote:
> On 11/11/2013 03:55 PM, Michal Nazarewicz wrote:
>> Come to think of it, perhaps even better helper would be:
>>
>> static inline size_t usb_ep_align_maybe(
>>  struct usb_gadget *gadget, struct usb_ep *ep, size_t len) {
>>  return gadget->quir_ep_out_aligned_size ?
>>  round_up(len, (size_t)ep->desc->wMaxPacketSize) : len;
>> }
>
> The CPU time to check unsigned:1 and possibly jump is about the same as
> round_up() itself. For readability matters, we can round_up() directly.

I was proposing to have this function and than not have functions check
for the flag.  I.e. instead of

if (gadget->quirk_ep_out_aligned_size)
len = usb_ep_align_maxpacketsize(ep, len);

the code would just be:

len = usb_ep_align_maybe(gadget, ep, len);

-- 
Best regards, _ _
.o. | Liege of Serenely Enlightened Majesty of  o' \,=./ `o
..o | Computer Science,  Michał “mina86” Nazarewicz(o o)
ooo +--ooO--(_)--Ooo--


signature.asc
Description: PGP signature


Re: [PATCHv5.1 4/5] check quirk to pad epout buf size when not aligned to maxpacketsize

2013-11-12 Thread Michal Nazarewicz
On Tue, Nov 12 2013, David Cohen wrote:
> You need to update req->length otherwise it's going to crash DWC3.
> I'd rather to keep your previous version.

That's unfortunate.  Do you want me to resend it or will you just send
a v6 of your whole series?

-- 
Best regards, _ _
.o. | Liege of Serenely Enlightened Majesty of  o' \,=./ `o
..o | Computer Science,  Michał “mina86” Nazarewicz(o o)
ooo +--ooO--(_)--Ooo--


signature.asc
Description: PGP signature


[PATCH] usb: xhci: Add 2nd memory barrier to giveback_first_trb()

2013-11-12 Thread David Laight

There needs to be a wmb() barrier between the write to the cycle bit
in the first TRB and the write to the doorbell register.

Since it isn't needed in the other places the doobell is rung
(because the ring contents haven't been changed) add it to
giveback_first_trb() rather than somewhere later.

Signed-off-by: David Laight 
---
This patch will only apply cleanly if my earlier patch that affects
the previous line has also been applied.

 drivers/usb/host/xhci-ring.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 35dfed0..8bce4c3 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -3136,6 +3136,7 @@ static void giveback_first_trb(struct xhci_hcd *xhci, int 
slot_id,
 */
wmb();
start_trb->field[3] ^= cpu_to_le32(TRB_CYCLE);
+   wmb();
xhci_ring_ep_doorbell(xhci, slot_id, ep_index, stream_id);
 }
 
-- 
1.8.1.2



--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] usb: chipidea: udc: first start device on pullup

2013-11-12 Thread Michael Grzeschik
On Tue, Nov 12, 2013 at 08:12:04PM +0800, Peter Chen wrote:
> On Tue, Nov 12, 2013 at 7:50 PM, Michael Grzeschik
>  wrote:
> > Don't start hw_device_state on udc_start. The gadget framework has
> > the prepared pullup callback for this. This is necessary if we use gadgets
> > which need to be enabled after an userspace application got prepared, or
> > other delayed conditiions have passed.
> >
> > Signed-off-by: Michael Grzeschik 
> > ---
> >
> > Hi Peter,
> >
> > I checked ci_udc_start again and realized that one problem is
> > that we ignore the pullup call and start the device on udc_start.
> >
> > What do you think of the following patch? Any objections?
> >
> >  drivers/usb/chipidea/udc.c | 5 -
> >  1 file changed, 5 deletions(-)
> >
> > diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
> > index b34c819..e673263 100644
> > --- a/drivers/usb/chipidea/udc.c
> > +++ b/drivers/usb/chipidea/udc.c
> > @@ -1647,11 +1647,6 @@ static int ci_udc_start(struct usb_gadget *gadget,
> > return retval;
> > }
> >
> > -   retval = hw_device_state(ci, ci->ep0out->qh.dma);
> > -   spin_unlock_irqrestore(&ci->lock, flags);
> > -   if (retval)
> > -   pm_runtime_put_sync(&ci->gadget.dev);
> > -
> > return retval;
> >  }
> >
> Hi Michael,
>
> Your code base seems out of date.

I used linux/master.

> The reason why we need start controller(call hw_device_state) at ci_udc_start:
>
> - For vbus is already there before modprobe gadget, in that case, there
> is no vbus interrupt due to vbus has not changed during the initialization.

Don't we have another possibility to ask the hardware if the vbus is
connected. We could limit the enabled Interrupts in udc_start to
USBi_PCI. Will it than trigger an interrupt while having the cable
_already_ plugged?

> - For the platforms which have no vbus interrupt, it needs to start controller
> before connection otherwise the enumeration can't be started due to
> usbcmd.rs is 0.

Then we need to force to start the controller conditionally for those platforms.
IMHO this should not be the case for all platforms.

Michael

--
Pengutronix e.K.   | |
Industrial Linux Solutions | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0|
Amtsgericht Hildesheim, HRA 2686   | Fax:   +49-5121-206917- |
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 13/15] usb: phy: msm: Correct USB PHY Reset sequence for newer platform

2013-11-12 Thread Ivan T. Ivanov
From: "Ivan T. Ivanov" 

On few legacy platforms, USB PHY is having dedicated reset clk.
It is used to reset USB PHY after putting USB PHY into low power
mode and for calibration of USB PHY. Putting USB PHY into low
power mode is causing ulpi read/write timeout as expected. USB PHY
reset clk is not available on newer platform.

For 28nm PHY, reset USB PHY after resestting USB LINK.
Also reset USB PHY using USB_PHY_PON bit with USB_OTG_HS_PHY_CTRL
register after programming USB PHY Override registers as suggested
with hardware programming guidelines.

Signed-off-by: Ivan T. Ivanov 
Cc: Mayank Rana 
---
 drivers/usb/phy/phy-msm-usb.c|  141 --
 include/linux/usb/msm_hsusb_hw.h |5 ++
 2 files changed, 94 insertions(+), 52 deletions(-)

diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c
index 01b571ff..1d88ff8 100644
--- a/drivers/usb/phy/phy-msm-usb.c
+++ b/drivers/usb/phy/phy-msm-usb.c
@@ -48,6 +48,7 @@
 #define DRIVER_NAME"msm_otg"
 
 #define ULPI_IO_TIMEOUT_USEC   (10 * 1000)
+#define LINK_RESET_TIMEOUT_USEC(250 * 1000)
 
 #define USB_PHY_3P3_VOL_MIN305 /* uV */
 #define USB_PHY_3P3_VOL_MAX330 /* uV */
@@ -293,77 +294,35 @@ static int msm_otg_phy_clk_reset(struct msm_otg *motg)
return ret;
 }
 
-static int msm_otg_phy_reset(struct msm_otg *motg)
+static int msm_link_reset(struct msm_otg *motg)
 {
u32 val;
int ret;
-   int retries;
 
ret = msm_otg_link_clk_reset(motg, 1);
if (ret)
return ret;
-   ret = msm_otg_phy_clk_reset(motg);
-   if (ret)
-   return ret;
-   ret = msm_otg_link_clk_reset(motg, 0);
-   if (ret)
-   return ret;
 
-   val = readl(USB_PORTSC) & ~PORTSC_PTS_MASK;
-   writel(val | PORTSC_PTS_ULPI, USB_PORTSC);
-
-   for (retries = 3; retries > 0; retries--) {
-   ret = ulpi_write(&motg->phy, ULPI_FUNC_CTRL_SUSPENDM,
-   ULPI_CLR(ULPI_FUNC_CTRL));
-   if (!ret)
-   break;
-   ret = msm_otg_phy_clk_reset(motg);
-   if (ret)
-   return ret;
-   }
-   if (!retries)
-   return -ETIMEDOUT;
+   /* wait for 1ms delay as suggested in HPG. */
+   usleep_range(1000, 1200);
 
-   /* This reset calibrates the phy, if the above write succeeded */
-   ret = msm_otg_phy_clk_reset(motg);
+   ret = msm_otg_link_clk_reset(motg, 0);
if (ret)
return ret;
 
-   for (retries = 3; retries > 0; retries--) {
-   ret = ulpi_read(&motg->phy, ULPI_DEBUG);
-   if (ret != -ETIMEDOUT)
-   break;
-   ret = msm_otg_phy_clk_reset(motg);
-   if (ret)
-   return ret;
-   }
-   if (!retries)
-   return -ETIMEDOUT;
-
if (motg->phy_number)
writel(readl(USB_PHY_CTRL2) | BIT(16), USB_PHY_CTRL2);
 
-   dev_info(motg->phy.dev, "phy_reset: success\n");
+   val = readl(USB_PORTSC) & ~PORTSC_PTS_MASK;
+   writel(val | PORTSC_PTS_ULPI, USB_PORTSC);
+
return 0;
 }
 
-#define LINK_RESET_TIMEOUT_USEC(250 * 1000)
 static int msm_otg_reset(struct usb_phy *phy)
 {
struct msm_otg *motg = container_of(phy, struct msm_otg, phy);
-   struct msm_otg_platform_data *pdata = motg->pdata;
int cnt = 0;
-   int ret;
-   u32 val = 0;
-   u32 ulpi_val = 0;
-
-   ret = msm_otg_phy_reset(motg);
-   if (ret) {
-   dev_err(phy->dev, "phy_reset failed\n");
-   return ret;
-   }
-
-   ulpi_init(motg);
 
writel(USBCMD_RESET, USB_USBCMD);
while (cnt < LINK_RESET_TIMEOUT_USEC) {
@@ -377,11 +336,87 @@ static int msm_otg_reset(struct usb_phy *phy)
 
/* select ULPI phy */
writel(0x8000, USB_PORTSC);
+   writel(0x0, USB_AHBBURST);
+   writel(0x08, USB_AHBMODE);
+
+   if (motg->phy_number)
+   writel(readl(USB_PHY_CTRL2) | BIT(16), USB_PHY_CTRL2);
+   return 0;
+}
+
+static void msm_phy_reset(struct msm_otg *motg)
+{
+   void __iomem *addr;
+   u32 val;
+
+   if (motg->pdata->phy_type != SNPS_28NM_INTEGRATED_PHY) {
+   msm_otg_phy_clk_reset(motg);
+   return;
+   }
+
+   addr = USB_PHY_CTRL;
+   if (motg->phy_number)
+   addr = USB_PHY_CTRL2;
+
+   /* Assert USB PHY_PON */
+   val =  readl(addr);
+   val |= PHY_POR_ASSERT;
+   writel(val, addr);
+
+   /* wait for minimum 10 microseconds as suggested in HPG. */
+   usleep_range(10, 15);
+
+   /* Deassert USB PHY_PON */
+   val =  readl(addr);
+   val &= ~PHY_POR_ASSERT;
+   writel(val, addr);
+}
+
+static int msm_usb_reset(struct usb_phy *phy)
+{
+   struct msm_otg *motg = container_of(phy, struct msm_otg, phy);
+   int ret;
+
+   

[PATCH v4 15/15] usb: phy: msm: Vote for corner of VDD CX instead of voltage of VDD CX

2013-11-12 Thread Ivan T. Ivanov
From: "Ivan T. Ivanov" 

New platform uses RBCPR hardware feature, with that voting for
absolute voltage of VDD CX is not required. Hence vote for corner of
VDD CX which uses nominal corner voltage on VDD CX.

Signed-off-by: Ivan T. Ivanov 
Cc: Mayank Rana 
Cc: devicet...@vger.kernel.org
---
 .../devicetree/bindings/usb/msm-hsusb.txt  |6 
 drivers/usb/phy/phy-msm-usb.c  |   35 +++-
 include/linux/usb/msm_hsusb.h  |1 +
 3 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/msm-hsusb.txt 
b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
index d105ba9..7b46395 100644
--- a/Documentation/devicetree/bindings/usb/msm-hsusb.txt
+++ b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
@@ -78,6 +78,11 @@ Optional properties:
Some platforms may have configuration to allow 
USB
controller work with any of the two HSPHYs 
present.
 
+- qcom,vdd-levels: This property must be a list of three integer
+   values (no, min, max) where each value 
represents
+   either a voltage in microvolts or a value 
corresponding
+   to voltage corner.
+
 Example HSUSB OTG controller device node:
 
usb@f9a55000 {
@@ -100,4 +105,5 @@ Example HSUSB OTG controller device node:
 
qcom,otg-control = <1>;
qcom,phy-init-sequence = <0x01 0x90 0x>;
+   qcom,vdd-levels = <1 5 7>;
};
diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c
index 970f96b..b6e18b6 100644
--- a/drivers/usb/phy/phy-msm-usb.c
+++ b/drivers/usb/phy/phy-msm-usb.c
@@ -62,6 +62,13 @@
 
 #define USB_PHY_VDD_DIG_VOL_MIN100 /* uV */
 #define USB_PHY_VDD_DIG_VOL_MAX132 /* uV */
+#define USB_PHY_SUSP_DIG_VOL   50  /* uV */
+
+enum vdd_levels {
+   VDD_LEVEL_NONE = 0,
+   VDD_LEVEL_MIN,
+   VDD_LEVEL_MAX,
+};
 
 static int msm_hsusb_init_vddcx(struct msm_otg *motg, int init)
 {
@@ -69,8 +76,8 @@ static int msm_hsusb_init_vddcx(struct msm_otg *motg, int 
init)
 
if (init) {
ret = regulator_set_voltage(motg->vddcx,
-   USB_PHY_VDD_DIG_VOL_MIN,
-   USB_PHY_VDD_DIG_VOL_MAX);
+   motg->vdd_levels[VDD_LEVEL_MIN],
+   motg->vdd_levels[VDD_LEVEL_MAX]);
if (ret) {
dev_err(motg->phy.dev, "Cannot set vddcx voltage\n");
return ret;
@@ -81,7 +88,7 @@ static int msm_hsusb_init_vddcx(struct msm_otg *motg, int 
init)
dev_err(motg->phy.dev, "unable to enable hsusb 
vddcx\n");
} else {
ret = regulator_set_voltage(motg->vddcx, 0,
-   USB_PHY_VDD_DIG_VOL_MAX);
+   motg->vdd_levels[VDD_LEVEL_MAX]);
if (ret)
dev_err(motg->phy.dev, "Cannot set vddcx voltage\n");
ret = regulator_disable(motg->vddcx);
@@ -131,17 +138,16 @@ exit:
 }
 
 #ifdef CONFIG_PM_SLEEP
-#define USB_PHY_SUSP_DIG_VOL  50
 static int msm_hsusb_config_vddcx(struct msm_otg *motg, int high)
 {
-   int max_vol = USB_PHY_VDD_DIG_VOL_MAX;
+   int max_vol = motg->vdd_levels[VDD_LEVEL_MAX];
int min_vol;
int ret;
 
if (high)
-   min_vol = USB_PHY_VDD_DIG_VOL_MIN;
+   min_vol = motg->vdd_levels[VDD_LEVEL_MIN];
else
-   min_vol = USB_PHY_SUSP_DIG_VOL;
+   min_vol = motg->vdd_levels[VDD_LEVEL_NONE];
 
ret = regulator_set_voltage(motg->vddcx, min_vol, max_vol);
if (ret) {
@@ -1437,7 +1443,7 @@ static int msm_otg_read_dt(struct platform_device *pdev, 
struct msm_otg *motg)
const struct of_device_id *id;
struct device_node *node = pdev->dev.of_node;
int len = 0;
-   u32 val;
+   u32 val, tmp[3];
 
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
@@ -1467,6 +1473,19 @@ static int msm_otg_read_dt(struct platform_device *pdev, 
struct msm_otg *motg)
if (!of_property_read_u32(node, "qcom,phy-num", &val))
motg->phy_number = val;
 
+   motg->vdd_levels[VDD_LEVEL_NONE] = USB_PHY_SUSP_DIG_VOL;
+   motg->vdd_levels[VDD_LEVEL_MIN] = USB_PHY_VDD_DIG_VOL_MIN;
+   motg->vdd_levels[VDD_LEVEL_MAX] = USB_PHY_VDD_DIG_VOL_MAX;
+
+   if (of_get_property(node, "qcom,vdd-levels", &len) &&
+   len == sizeof(tmp)) {
+   of_property_read_u32_array(node, "qcom,vdd-levels",
+  tmp, len / sizeof(*tmp));
+   motg->vdd_levels[VDD_LEVEL_NONE] = tmp[VDD_LEVEL_NONE];
+   motg->vdd_levels[VDD_LEVEL_MIN] = tmp[VDD_LEVEL_MIN];
+   

[PATCH v4 09/15] usb: phy: msm: Properly check result from platform_get_irq()

2013-11-12 Thread Ivan T. Ivanov
From: "Ivan T. Ivanov" 

Function return negative code on error.

Signed-off-by: Ivan T. Ivanov 
---
 drivers/usb/phy/phy-msm-usb.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c
index 258bca2..fa8e672d 100644
--- a/drivers/usb/phy/phy-msm-usb.c
+++ b/drivers/usb/phy/phy-msm-usb.c
@@ -1412,7 +1412,7 @@ static int __init msm_otg_probe(struct platform_device 
*pdev)
dev_info(&pdev->dev, "OTG regs = %p\n", motg->regs);
 
motg->irq = platform_get_irq(pdev, 0);
-   if (!motg->irq) {
+   if (motg->irq < 0) {
dev_err(&pdev->dev, "platform_get_irq failed\n");
return motg->irq;
}
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 12/15] usb: phy: msm: Add support for secondary PHY control

2013-11-12 Thread Ivan T. Ivanov
From: "Ivan T. Ivanov" 

Allow support to use 2nd HSPHY with USB2 Core.
Some platforms may have configuration to allow USB controller
work with any of the two HSPHYs present. By default driver
configures USB core to use primary HSPHY. Add support to allow
user select 2nd HSPHY using DT parameter.

Signed-off-by: Ivan T. Ivanov 
Cc: Manu Gautam 
Cc: devicet...@vger.kernel.org
---
 .../devicetree/bindings/usb/msm-hsusb.txt  |6 +
 drivers/usb/phy/phy-msm-usb.c  |   24 ++--
 include/linux/usb/msm_hsusb.h  |1 +
 include/linux/usb/msm_hsusb_hw.h   |1 +
 4 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/msm-hsusb.txt 
b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
index 3f21204..d105ba9 100644
--- a/Documentation/devicetree/bindings/usb/msm-hsusb.txt
+++ b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
@@ -72,6 +72,12 @@ Optional properties:
 - qcom,phy-init-sequence: PHY configuration sequence. val, reg pairs
terminate with -1
 
+- qcom,phy-num:Select number of pyco-phy to use, can be one of
+   0 - PHY one, default
+   1 - Second PHY
+   Some platforms may have configuration to allow 
USB
+   controller work with any of the two HSPHYs 
present.
+
 Example HSUSB OTG controller device node:
 
usb@f9a55000 {
diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c
index 53fc645..01b571ff 100644
--- a/drivers/usb/phy/phy-msm-usb.c
+++ b/drivers/usb/phy/phy-msm-usb.c
@@ -340,6 +340,9 @@ static int msm_otg_phy_reset(struct msm_otg *motg)
if (!retries)
return -ETIMEDOUT;
 
+   if (motg->phy_number)
+   writel(readl(USB_PHY_CTRL2) | BIT(16), USB_PHY_CTRL2);
+
dev_info(motg->phy.dev, "phy_reset: success\n");
return 0;
 }
@@ -394,6 +397,9 @@ static int msm_otg_reset(struct usb_phy *phy)
ulpi_write(phy, ulpi_val, ULPI_USB_INT_EN_FALL);
}
 
+   if (motg->phy_number)
+   writel(readl(USB_PHY_CTRL2) | BIT(16), USB_PHY_CTRL2);
+
return 0;
 }
 
@@ -406,6 +412,7 @@ static int msm_otg_suspend(struct msm_otg *motg)
struct usb_phy *phy = &motg->phy;
struct usb_bus *bus = phy->otg->host;
struct msm_otg_platform_data *pdata = motg->pdata;
+   void __iomem *addr;
int cnt = 0;
 
if (atomic_read(&motg->in_lpm))
@@ -465,9 +472,13 @@ static int msm_otg_suspend(struct msm_otg *motg)
 */
writel(readl(USB_USBCMD) | ASYNC_INTR_CTRL | ULPI_STP_CTRL, USB_USBCMD);
 
+   addr = USB_PHY_CTRL;
+   if (motg->phy_number)
+   addr = USB_PHY_CTRL2;
+
if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY &&
motg->pdata->otg_control == OTG_PMIC_CONTROL)
-   writel(readl(USB_PHY_CTRL) | PHY_RETEN, USB_PHY_CTRL);
+   writel(readl(addr) | PHY_RETEN, addr);
 
clk_disable_unprepare(motg->pclk);
clk_disable_unprepare(motg->clk);
@@ -497,6 +508,7 @@ static int msm_otg_resume(struct msm_otg *motg)
 {
struct usb_phy *phy = &motg->phy;
struct usb_bus *bus = phy->otg->host;
+   void __iomem *addr;
int cnt = 0;
unsigned temp;
 
@@ -510,9 +522,14 @@ static int msm_otg_resume(struct msm_otg *motg)
 
if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY &&
motg->pdata->otg_control == OTG_PMIC_CONTROL) {
+
+   addr = USB_PHY_CTRL;
+   if (motg->phy_number)
+   addr = USB_PHY_CTRL2;
+
msm_hsusb_ldo_set_mode(motg, 1);
msm_hsusb_config_vddcx(motg, 1);
-   writel(readl(USB_PHY_CTRL) & ~PHY_RETEN, USB_PHY_CTRL);
+   writel(readl(addr) & ~PHY_RETEN, addr);
}
 
temp = readl(USB_USBCMD);
@@ -1395,6 +1412,9 @@ static int msm_otg_read_dt(struct platform_device *pdev, 
struct msm_otg *motg)
if (!of_property_read_u32(node, "qcom,otg-control", &val))
pdata->otg_control = val;
 
+   if (!of_property_read_u32(node, "qcom,phy-num", &val))
+   motg->phy_number = val;
+
if (!of_get_property(node, "qcom,phy-init-sequence", &len) || !len)
return 0;
 
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 9bf8943..da3a974 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -156,6 +156,7 @@ struct msm_otg {
atomic_t in_lpm;
int async_int;
unsigned cur_power;
+   int phy_number;
struct delayed_work chg_work;
enum usb_chg_state chg_state;
enum usb_chg_type chg_type;
diff --git a/include/linux/usb/msm_hsusb_hw.h b/include/linux/usb/msm_hsusb_hw.h
index 6e97a2d..

[PATCH v4 01/15] usb: phy: msm: Move mach dependent code to platform data

2013-11-12 Thread Ivan T. Ivanov
From: "Ivan T. Ivanov" 

This patch fix compilation error when driver is compiled
in multi-platform builds.

drivers/built-in.o: In function `msm_otg_link_clk_reset':
./drivers/usb/phy/phy-msm-usb.c:314: undefined reference to `clk_reset'
./drivers/usb/phy/phy-msm-usb.c:318: undefined reference to `clk_reset'

Use platform data supplied reset handlers and adjust error
messages reported when reset sequence fail.

This is an intermediate step before adding support for reset
framework and newer targets.

Signed-off-by: Ivan T. Ivanov 
Acked-by: David Brown 
Cc: Daniel Walker 
Cc: Felipe Balbi 
Cc: Greg Kroah-Hartman 
---
 arch/arm/mach-msm/board-msm7x30.c |   35 +++
 arch/arm/mach-msm/board-qsd8x50.c |   35 +++
 drivers/usb/phy/phy-msm-usb.c |   35 +++
 include/linux/usb/msm_hsusb.h |3 +++
 4 files changed, 88 insertions(+), 20 deletions(-)

diff --git a/arch/arm/mach-msm/board-msm7x30.c 
b/arch/arm/mach-msm/board-msm7x30.c
index f9af5a4..46de789 100644
--- a/arch/arm/mach-msm/board-msm7x30.c
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 
+#include 
 #include 
 #include 
 
@@ -60,10 +61,44 @@ static int hsusb_phy_init_seq[] = {
-1
 };
 
+static int hsusb_link_clk_reset(struct clk *link_clk, bool assert)
+{
+   int ret;
+
+   if (assert) {
+   ret = clk_reset(link_clk, CLK_RESET_ASSERT);
+   if (ret)
+   pr_err("usb hs_clk assert failed\n");
+   } else {
+   ret = clk_reset(link_clk, CLK_RESET_DEASSERT);
+   if (ret)
+   pr_err("usb hs_clk deassert failed\n");
+   }
+   return ret;
+}
+
+static int hsusb_phy_clk_reset(struct clk *phy_clk)
+{
+   int ret;
+
+   ret = clk_reset(phy_clk, CLK_RESET_ASSERT);
+   if (ret) {
+   pr_err("usb phy clk assert failed\n");
+   return ret;
+   }
+   usleep_range(1, 12000);
+   ret = clk_reset(phy_clk, CLK_RESET_DEASSERT);
+   if (ret)
+   pr_err("usb phy clk deassert failed\n");
+   return ret;
+}
+
 static struct msm_otg_platform_data msm_otg_pdata = {
.phy_init_seq   = hsusb_phy_init_seq,
.mode   = USB_PERIPHERAL,
.otg_control= OTG_PHY_CONTROL,
+   .link_clk_reset = hsusb_link_clk_reset,
+   .phy_clk_reset  = hsusb_phy_clk_reset,
 };
 
 struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = {
diff --git a/arch/arm/mach-msm/board-qsd8x50.c 
b/arch/arm/mach-msm/board-qsd8x50.c
index 5f933bc..9169ec3 100644
--- a/arch/arm/mach-msm/board-qsd8x50.c
+++ b/arch/arm/mach-msm/board-qsd8x50.c
@@ -31,6 +31,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "devices.h"
@@ -81,10 +82,44 @@ static int hsusb_phy_init_seq[] = {
-1
 };
 
+static int hsusb_link_clk_reset(struct clk *link_clk, bool assert)
+{
+   int ret;
+
+   if (assert) {
+   ret = clk_reset(link_clk, CLK_RESET_ASSERT);
+   if (ret)
+   pr_err("usb hs_clk assert failed\n");
+   } else {
+   ret = clk_reset(link_clk, CLK_RESET_DEASSERT);
+   if (ret)
+   pr_err("usb hs_clk deassert failed\n");
+   }
+   return ret;
+}
+
+static int hsusb_phy_clk_reset(struct clk *phy_clk)
+{
+   int ret;
+
+   ret = clk_reset(phy_clk, CLK_RESET_ASSERT);
+   if (ret) {
+   pr_err("usb phy clk assert failed\n");
+   return ret;
+   }
+   usleep_range(1, 12000);
+   ret = clk_reset(phy_clk, CLK_RESET_DEASSERT);
+   if (ret)
+   pr_err("usb phy clk deassert failed\n");
+   return ret;
+}
+
 static struct msm_otg_platform_data msm_otg_pdata = {
.phy_init_seq   = hsusb_phy_init_seq,
.mode   = USB_PERIPHERAL,
.otg_control= OTG_PHY_CONTROL,
+   .link_clk_reset = hsusb_link_clk_reset,
+   .phy_clk_reset  = hsusb_phy_clk_reset,
 };
 
 static struct platform_device *devices[] __initdata = {
diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c
index e9d4cd9..9a47d44 100644
--- a/drivers/usb/phy/phy-msm-usb.c
+++ b/drivers/usb/phy/phy-msm-usb.c
@@ -40,8 +40,6 @@
 #include 
 #include 
 
-#include 
-
 #define MSM_USB_BASE   (motg->regs)
 #define DRIVER_NAME"msm_otg"
 
@@ -308,33 +306,30 @@ static void ulpi_init(struct msm_otg *motg)
 
 static int msm_otg_link_clk_reset(struct msm_otg *motg, bool assert)
 {
-   int ret;
+   int ret = 0;
+
+   if (!motg->pdata->link_clk_reset)
+   return ret;
+
+   ret = motg->pdata->link_clk_reset(motg->clk, assert);
+   if (ret)
+   dev_err(motg->phy.dev, "usb link clk reset %s failed\n",
+   assert ? "assert" : "deassert");
 
-

[PATCH v4 05/15] usb: phy: msm: Fix checkpatch.pl warnings

2013-11-12 Thread Ivan T. Ivanov
From: "Ivan T. Ivanov" 

This fixes following:

WARNING: quoted string split across lines
WARNING: Prefer seq_puts to seq_printf

Signed-off-by: Ivan T. Ivanov 
---
 drivers/usb/phy/phy-msm-usb.c |   39 ++-
 1 file changed, 14 insertions(+), 25 deletions(-)

diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c
index 0bd9614..8f148a6 100644
--- a/drivers/usb/phy/phy-msm-usb.c
+++ b/drivers/usb/phy/phy-msm-usb.c
@@ -67,8 +67,7 @@ static int msm_hsusb_init_vddcx(struct msm_otg *motg, int 
init)
USB_PHY_VDD_DIG_VOL_MIN,
USB_PHY_VDD_DIG_VOL_MAX);
if (ret) {
-   dev_err(motg->phy.dev, "unable to set the voltage "
-   "for hsusb vddcx\n");
+   dev_err(motg->phy.dev, "Cannot set vddcx voltage\n");
return ret;
}
 
@@ -79,8 +78,7 @@ static int msm_hsusb_init_vddcx(struct msm_otg *motg, int 
init)
ret = regulator_set_voltage(motg->vddcx, 0,
USB_PHY_VDD_DIG_VOL_MAX);
if (ret)
-   dev_err(motg->phy.dev, "unable to set the voltage "
-   "for hsusb vddcx\n");
+   dev_err(motg->phy.dev, "Cannot set vddcx voltage\n");
ret = regulator_disable(motg->vddcx);
if (ret)
dev_err(motg->phy.dev, "unable to disable hsusb 
vddcx\n");
@@ -97,8 +95,7 @@ static int msm_hsusb_ldo_init(struct msm_otg *motg, int init)
rc = regulator_set_voltage(motg->v3p3, USB_PHY_3P3_VOL_MIN,
USB_PHY_3P3_VOL_MAX);
if (rc) {
-   dev_err(motg->phy.dev, "unable to set voltage level "
-   "for hsusb 3p3\n");
+   dev_err(motg->phy.dev, "Cannot set v3p3 voltage\n");
goto exit;
}
rc = regulator_enable(motg->v3p3);
@@ -109,8 +106,7 @@ static int msm_hsusb_ldo_init(struct msm_otg *motg, int 
init)
rc = regulator_set_voltage(motg->v1p8, USB_PHY_1P8_VOL_MIN,
USB_PHY_1P8_VOL_MAX);
if (rc) {
-   dev_err(motg->phy.dev, "unable to set voltage level "
-   "for hsusb 1p8\n");
+   dev_err(motg->phy.dev, "Cannot set v1p8 voltage\n");
goto disable_3p3;
}
rc = regulator_enable(motg->v1p8);
@@ -144,8 +140,7 @@ static int msm_hsusb_config_vddcx(struct msm_otg *motg, int 
high)
 
ret = regulator_set_voltage(motg->vddcx, min_vol, max_vol);
if (ret) {
-   pr_err("%s: unable to set the voltage for regulator "
-   "HSUSB_VDDCX\n", __func__);
+   dev_err(motg->phy.dev, "Cannot set vddcx voltage\n");
return ret;
}
 
@@ -163,15 +158,13 @@ static int msm_hsusb_ldo_set_mode(struct msm_otg *motg, 
int on)
ret = regulator_set_optimum_mode(motg->v1p8,
USB_PHY_1P8_HPM_LOAD);
if (ret < 0) {
-   pr_err("%s: Unable to set HPM of the regulator "
-   "HSUSB_1p8\n", __func__);
+   pr_err("Could not set HPM for v1p8\n");
return ret;
}
ret = regulator_set_optimum_mode(motg->v3p3,
USB_PHY_3P3_HPM_LOAD);
if (ret < 0) {
-   pr_err("%s: Unable to set HPM of the regulator "
-   "HSUSB_3p3\n", __func__);
+   pr_err("Could not set HPM for v3p3\n");
regulator_set_optimum_mode(motg->v1p8,
USB_PHY_1P8_LPM_LOAD);
return ret;
@@ -180,13 +173,11 @@ static int msm_hsusb_ldo_set_mode(struct msm_otg *motg, 
int on)
ret = regulator_set_optimum_mode(motg->v1p8,
USB_PHY_1P8_LPM_LOAD);
if (ret < 0)
-   pr_err("%s: Unable to set LPM of the regulator "
-   "HSUSB_1p8\n", __func__);
+   pr_err("Could not set LPM for v1p8\n");
ret = regulator_set_optimum_mode(motg->v3p3,
USB_PHY_3P3_LPM_LOAD);
if (ret < 0)
-   pr_err("%s: Unable to set LPM of the regulator "
-   "HSUSB_3p3\n", __func__);
+   pr_err("Could not set LPM for v3p3\n");
}
 
pr_debug("reg (%s)\n", on ? "HPM" : "LPM");
@@ -547,8 +538,7 @@ static int msm_otg_resume(struct msm_otg *motg)
 * PHY. USB

[PATCH v4 14/15] usb: phy: msm: Handle disconnect events

2013-11-12 Thread Ivan T. Ivanov
From: "Ivan T. Ivanov" 

Put the transceiver in non-driving mode. Otherwise host
may not detect soft-disconnection.

Signed-off-by: Ivan T. Ivanov 
Cc: Pavankumar Kondeti 
---
 drivers/usb/phy/phy-msm-usb.c |   18 ++
 1 file changed, 18 insertions(+)

diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c
index 1d88ff8..970f96b 100644
--- a/drivers/usb/phy/phy-msm-usb.c
+++ b/drivers/usb/phy/phy-msm-usb.c
@@ -260,6 +260,23 @@ static void ulpi_init(struct msm_otg *motg)
}
 }
 
+static int msm_phy_notify_disconnect(struct usb_phy *phy,
+  enum usb_device_speed speed)
+{
+   int val;
+
+   /*
+* Put the transceiver in non-driving mode. Otherwise host
+* may not detect soft-disconnection.
+*/
+   val = ulpi_read(phy, ULPI_FUNC_CTRL);
+   val &= ~ULPI_FUNC_CTRL_OPMODE_MASK;
+   val |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING;
+   ulpi_write(phy, val, ULPI_FUNC_CTRL);
+
+   return 0;
+}
+
 static int msm_otg_link_clk_reset(struct msm_otg *motg, bool assert)
 {
int ret;
@@ -1597,6 +1614,7 @@ static int __init msm_otg_probe(struct platform_device 
*pdev)
 
phy->init = msm_phy_init;
phy->set_power = msm_otg_set_power;
+   phy->notify_disconnect = msm_phy_notify_disconnect;
 
phy->io_ops = &msm_otg_io_ops;
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 11/15] usb: phy: msm: Use reset framework for LINK and PHY resets

2013-11-12 Thread Ivan T. Ivanov
From: "Ivan T. Ivanov" 

Signed-off-by: Ivan T. Ivanov 
Cc: devicet...@vger.kernel.org
---
 .../devicetree/bindings/usb/msm-hsusb.txt  |9 ++
 drivers/usb/phy/phy-msm-usb.c  |   30 ++--
 include/linux/usb/msm_hsusb.h  |3 ++
 3 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/msm-hsusb.txt 
b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
index f1045e3..3f21204 100644
--- a/Documentation/devicetree/bindings/usb/msm-hsusb.txt
+++ b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
@@ -57,6 +57,12 @@ Required properties:
 - v1p8-supply: phandle to the regulator for the 1.8V supply
 - v3p3-supply: phandle to the regulator for the 3.3V supply
 
+- resets:  A list of phandle + reset-specifier pairs for the
+   resets listed in reset-names
+- reset-names: Should contain the following:
+  "phy"USB PHY controller reset
+  "link"   USB LINK controller reset
+
 - qcom,otg-control: OTG control (VBUS and ID notifications) can be one of
1 - PHY control
2 - PMIC control
@@ -83,6 +89,9 @@ Example HSUSB OTG controller device node:
v1p8-supply = <&pm8941_l6>;
v3p3-supply = <&pm8941_l24>;
 
+   resets = <&gcc GCC_USB2A_PHY_BCR>, <&gcc GCC_USB_HS_BCR>;
+   reset-names = "phy", "link";
+
qcom,otg-control = <1>;
qcom,phy-init-sequence = <0x01 0x90 0x>;
};
diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c
index cc230c8..53fc645 100644
--- a/drivers/usb/phy/phy-msm-usb.c
+++ b/drivers/usb/phy/phy-msm-usb.c
@@ -32,6 +32,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -260,12 +261,16 @@ static void ulpi_init(struct msm_otg *motg)
 
 static int msm_otg_link_clk_reset(struct msm_otg *motg, bool assert)
 {
-   int ret = 0;
+   int ret;
 
-   if (!motg->pdata->link_clk_reset)
-   return ret;
+   if (motg->pdata->link_clk_reset)
+   ret = motg->pdata->link_clk_reset(motg->clk, assert);
+   else
+   if (assert)
+   ret = reset_control_assert(motg->link_rst);
+   else
+   ret = reset_control_deassert(motg->link_rst);
 
-   ret = motg->pdata->link_clk_reset(motg->clk, assert);
if (ret)
dev_err(motg->phy.dev, "usb link clk reset %s failed\n",
assert ? "assert" : "deassert");
@@ -275,12 +280,13 @@ static int msm_otg_link_clk_reset(struct msm_otg *motg, 
bool assert)
 
 static int msm_otg_phy_clk_reset(struct msm_otg *motg)
 {
-   int ret = 0;
+   int ret;
 
-   if (!motg->pdata->phy_clk_reset)
-   return ret;
+   if (motg->pdata->phy_clk_reset)
+   ret = motg->pdata->phy_clk_reset(motg->phy_reset_clk);
+   else
+   ret = reset_control_reset(motg->phy_rst);
 
-   ret = motg->pdata->phy_clk_reset(motg->phy_reset_clk);
if (ret)
dev_err(motg->phy.dev, "usb phy clk reset failed\n");
 
@@ -1373,6 +1379,14 @@ static int msm_otg_read_dt(struct platform_device *pdev, 
struct msm_otg *motg)
id = of_match_device(msm_otg_dt_match, &pdev->dev);
pdata->phy_type = (int) id->data;
 
+   motg->link_rst = devm_reset_control_get(&pdev->dev, "link");
+   if (IS_ERR(motg->link_rst))
+   return PTR_ERR(motg->link_rst);
+
+   motg->phy_rst = devm_reset_control_get(&pdev->dev, "phy");
+   if (IS_ERR(motg->phy_rst))
+   return PTR_ERR(motg->phy_rst);
+
pdata->mode = of_usb_get_dr_mode(node);
if (pdata->mode == USB_DR_MODE_UNKNOWN)
pdata->mode = USB_DR_MODE_OTG;
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 262ed80..9bf8943 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -163,6 +163,9 @@ struct msm_otg {
struct regulator *v3p3;
struct regulator *v1p8;
struct regulator *vddcx;
+
+   struct reset_control *phy_rst;
+   struct reset_control *link_rst;
 };
 
 #endif
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 02/15] usb: phy: msm: Move global regulators variables to driver state

2013-11-12 Thread Ivan T. Ivanov
From: "Ivan T. Ivanov" 

Signed-off-by: Ivan T. Ivanov 
---
 drivers/usb/phy/phy-msm-usb.c |   82 -
 include/linux/usb/msm_hsusb.h |3 ++
 2 files changed, 42 insertions(+), 43 deletions(-)

diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c
index 9a47d44..c22cbd8 100644
--- a/drivers/usb/phy/phy-msm-usb.c
+++ b/drivers/usb/phy/phy-msm-usb.c
@@ -58,47 +58,43 @@
 #define USB_PHY_VDD_DIG_VOL_MIN100 /* uV */
 #define USB_PHY_VDD_DIG_VOL_MAX132 /* uV */
 
-static struct regulator *hsusb_3p3;
-static struct regulator *hsusb_1p8;
-static struct regulator *hsusb_vddcx;
-
 static int msm_hsusb_init_vddcx(struct msm_otg *motg, int init)
 {
int ret = 0;
 
if (init) {
-   hsusb_vddcx = regulator_get(motg->phy.dev, "HSUSB_VDDCX");
-   if (IS_ERR(hsusb_vddcx)) {
+   motg->vddcx = regulator_get(motg->phy.dev, "HSUSB_VDDCX");
+   if (IS_ERR(motg->vddcx)) {
dev_err(motg->phy.dev, "unable to get hsusb vddcx\n");
-   return PTR_ERR(hsusb_vddcx);
+   return PTR_ERR(motg->vddcx);
}
 
-   ret = regulator_set_voltage(hsusb_vddcx,
+   ret = regulator_set_voltage(motg->vddcx,
USB_PHY_VDD_DIG_VOL_MIN,
USB_PHY_VDD_DIG_VOL_MAX);
if (ret) {
dev_err(motg->phy.dev, "unable to set the voltage "
"for hsusb vddcx\n");
-   regulator_put(hsusb_vddcx);
+   regulator_put(motg->vddcx);
return ret;
}
 
-   ret = regulator_enable(hsusb_vddcx);
+   ret = regulator_enable(motg->vddcx);
if (ret) {
dev_err(motg->phy.dev, "unable to enable hsusb 
vddcx\n");
-   regulator_put(hsusb_vddcx);
+   regulator_put(motg->vddcx);
}
} else {
-   ret = regulator_set_voltage(hsusb_vddcx, 0,
+   ret = regulator_set_voltage(motg->vddcx, 0,
USB_PHY_VDD_DIG_VOL_MAX);
if (ret)
dev_err(motg->phy.dev, "unable to set the voltage "
"for hsusb vddcx\n");
-   ret = regulator_disable(hsusb_vddcx);
+   ret = regulator_disable(motg->vddcx);
if (ret)
dev_err(motg->phy.dev, "unable to disable hsusb 
vddcx\n");
 
-   regulator_put(hsusb_vddcx);
+   regulator_put(motg->vddcx);
}
 
return ret;
@@ -109,38 +105,38 @@ static int msm_hsusb_ldo_init(struct msm_otg *motg, int 
init)
int rc = 0;
 
if (init) {
-   hsusb_3p3 = regulator_get(motg->phy.dev, "HSUSB_3p3");
-   if (IS_ERR(hsusb_3p3)) {
+   motg->v3p3 = regulator_get(motg->phy.dev, "HSUSB_3p3");
+   if (IS_ERR(motg->v3p3)) {
dev_err(motg->phy.dev, "unable to get hsusb 3p3\n");
-   return PTR_ERR(hsusb_3p3);
+   return PTR_ERR(motg->v3p3);
}
 
-   rc = regulator_set_voltage(hsusb_3p3, USB_PHY_3P3_VOL_MIN,
+   rc = regulator_set_voltage(motg->v3p3, USB_PHY_3P3_VOL_MIN,
USB_PHY_3P3_VOL_MAX);
if (rc) {
dev_err(motg->phy.dev, "unable to set voltage level "
"for hsusb 3p3\n");
goto put_3p3;
}
-   rc = regulator_enable(hsusb_3p3);
+   rc = regulator_enable(motg->v3p3);
if (rc) {
dev_err(motg->phy.dev, "unable to enable the hsusb 
3p3\n");
goto put_3p3;
}
-   hsusb_1p8 = regulator_get(motg->phy.dev, "HSUSB_1p8");
-   if (IS_ERR(hsusb_1p8)) {
+   motg->v1p8 = regulator_get(motg->phy.dev, "HSUSB_1p8");
+   if (IS_ERR(motg->v1p8)) {
dev_err(motg->phy.dev, "unable to get hsusb 1p8\n");
-   rc = PTR_ERR(hsusb_1p8);
+   rc = PTR_ERR(motg->v1p8);
goto disable_3p3;
}
-   rc = regulator_set_voltage(hsusb_1p8, USB_PHY_1P8_VOL_MIN,
+   rc = regulator_set_voltage(motg->v1p8, USB_PHY_1P8_VOL_MIN,
USB_PHY_1P8_VOL_MAX);
if (rc) {
dev_err(motg->phy.dev, "unable to set voltage level "
"for hsusb 1p8\n");
goto put_1p8;
}
-   rc = regulator_enable(hsusb_1p8);
+   rc = 

[PATCH v4 00/15] usb: phy: msm: Fixes, cleanups and DT support

2013-11-12 Thread Ivan T. Ivanov
From: "Ivan T. Ivanov" 

Hi, 

Patches have been tested on top of Stephen's clock controller
patches[1] and recent fixes for chipidea msm glue layer driver
posted here[2]. Hardware platform AP8074 DragonBoard. Only gadget
mode utilized for now. 

CV Test Suite engine "Chapter 9 tests" are passing except
"Halt Endpoint Test".

usbtest driver report following failure:
test 13 --> 32 (Broken pipe)ep 81 couldn't set halt, -32

This will be investigated further. 
Patches could be applied cleanly on top of the usb-3.13-rc1.

Regards,
Ivan

[1] http://comments.gmane.org/gmane.linux.ports.arm.msm/5375
[2] https://lkml.org/lkml/2013/11/11/310

v4
-- 
* Squashed checkpatch.pl warning fixes patches
* Squashed dr_mode refactoring with default mode removal
* Dropped patch 10 - usb: phy: msm: Switch clock consumer strings
* Fixed comments from review.
* Utilize reset-framework for LINK and PHY resets if DT is used.
* Added support from second PHY device control.
* Ported reset procedure from codeaurora tree for new chipsets
 
v3
--
* In patch 1 - functions for reseting PHY and LINK controller just
  call platform code if available.
* New stuff is: cleaning up unneeded/unused driver state variables
* Simplified regulator names. There is no references to these names
  in tree, so there should not be a problem with this.
* Replace the USB specific clock names with the more standard 'core' 
  and 'iface' ... names.   
* Added devicetree support 

v2
--
* Fix compilation issue in patch 1
* Separate regulator changes
* Merge devm_ related changes to one commit
* Drop Lindent patch

v1
--
Following patches make initial cleanup of usb phy found in the Qualcomm
chipsets. Changes include:
* Build time error fix.
* Move driver to Managed Device Resource allocation.
* Checkpatch warnings and error fixes
* Removed usage of global regulators variables.

Ivan T. Ivanov (15):
  usb: phy: msm: Move mach dependent code to platform data
  usb: phy: msm: Move global regulators variables to driver state
  usb: phy: msm: Migrate to Managed Device Resource allocation
  usb: phy: msm: Remove unnecessarily check for valid regulators.
  usb: phy: msm: Fix checkpatch.pl warnings
  usb: phy: msm: Replace custom enum usb_mode_type with enum
usb_dr_mode
  usb: phy: msm: Remove unused pclk_src_name
  usb: phy: msm: Remove HSUSB prefix from regulator names
  usb: phy: msm: Properly check result from platform_get_irq()
  usb: phy: msm: Add device tree support and binding information
  usb: phy: msm: Use reset framework for LINK and PHY resets
  usb: phy: msm: Add support for secondary PHY control
  usb: phy: msm: Correct USB PHY Reset sequence for newer platform
  usb: phy: msm: Handle disconnect events
  usb: phy: msm: Vote for corner of VDD CX instead of voltage of VDD CX

 .../devicetree/bindings/usb/msm-hsusb.txt  |   78 ++-
 arch/arm/mach-msm/board-msm7x30.c  |   37 +-
 arch/arm/mach-msm/board-qsd8x50.c  |   37 +-
 drivers/usb/phy/phy-msm-usb.c  |  664 +++-
 include/linux/usb/msm_hsusb.h  |   36 +-
 include/linux/usb/msm_hsusb_hw.h   |6 +
 6 files changed, 529 insertions(+), 329 deletions(-)

-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 08/15] usb: phy: msm: Remove HSUSB prefix from regulator names

2013-11-12 Thread Ivan T. Ivanov
From: "Ivan T. Ivanov" 

Prefix did not bring any useful information. Currently none
of the MSM platforms define these regulators, so it is safe
to rename them.

Signed-off-by: Ivan T. Ivanov 
---
 drivers/usb/phy/phy-msm-usb.c |6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c
index 9e9d4a3..258bca2 100644
--- a/drivers/usb/phy/phy-msm-usb.c
+++ b/drivers/usb/phy/phy-msm-usb.c
@@ -1417,19 +1417,19 @@ static int __init msm_otg_probe(struct platform_device 
*pdev)
return motg->irq;
}
 
-   motg->vddcx = devm_regulator_get(motg->phy.dev, "HSUSB_VDDCX");
+   motg->vddcx = devm_regulator_get(motg->phy.dev, "vddcx");
if (IS_ERR(motg->vddcx)) {
dev_err(motg->phy.dev, "unable to get hsusb vddcx\n");
return PTR_ERR(motg->vddcx);
}
 
-   motg->v3p3 = devm_regulator_get(motg->phy.dev, "HSUSB_3p3");
+   motg->v3p3 = devm_regulator_get(motg->phy.dev, "v3p3");
if (IS_ERR(motg->v3p3)) {
dev_err(motg->phy.dev, "unable to get hsusb 3p3\n");
return PTR_ERR(motg->v3p3);
}
 
-   motg->v1p8 = devm_regulator_get(motg->phy.dev, "HSUSB_1p8");
+   motg->v1p8 = devm_regulator_get(motg->phy.dev, "v1p8");
if (IS_ERR(motg->v1p8)) {
dev_err(motg->phy.dev, "unable to get hsusb 1p8\n");
return PTR_ERR(motg->v1p8);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 04/15] usb: phy: msm: Remove unnecessarily check for valid regulators.

2013-11-12 Thread Ivan T. Ivanov
From: "Ivan T. Ivanov" 

Whether regulators are available or not is checked at driver
probe. If they are not available driver will refuse to load,
so no need to check them again.

Signed-off-by: Ivan T. Ivanov 
---
 drivers/usb/phy/phy-msm-usb.c |   10 --
 1 file changed, 10 deletions(-)

diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c
index dac2b22..0bd9614 100644
--- a/drivers/usb/phy/phy-msm-usb.c
+++ b/drivers/usb/phy/phy-msm-usb.c
@@ -159,16 +159,6 @@ static int msm_hsusb_ldo_set_mode(struct msm_otg *motg, 
int on)
 {
int ret = 0;
 
-   if (!motg->v1p8 || IS_ERR(motg->v1p8)) {
-   pr_err("%s: HSUSB_1p8 is not initialized\n", __func__);
-   return -ENODEV;
-   }
-
-   if (!motg->v3p3 || IS_ERR(motg->v3p3)) {
-   pr_err("%s: HSUSB_3p3 is not initialized\n", __func__);
-   return -ENODEV;
-   }
-
if (on) {
ret = regulator_set_optimum_mode(motg->v1p8,
USB_PHY_1P8_HPM_LOAD);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 10/15] usb: phy: msm: Add device tree support and binding information

2013-11-12 Thread Ivan T. Ivanov
From: "Ivan T. Ivanov" 

Allows MSM OTG controller to be specified via device tree.

Signed-off-by: Ivan T. Ivanov 
Cc: devicet...@vger.kernel.org
---
 .../devicetree/bindings/usb/msm-hsusb.txt  |   57 +-
 drivers/usb/phy/phy-msm-usb.c  |   79 +---
 2 files changed, 124 insertions(+), 12 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/msm-hsusb.txt 
b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
index 0a85eba..f1045e3 100644
--- a/Documentation/devicetree/bindings/usb/msm-hsusb.txt
+++ b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
@@ -30,4 +30,59 @@ Required properties:
dr_mode = "peripheral";
interrupts = <0 134 0>;
usb-phy = <&usb_otg>;
-   };
\ No newline at end of file
+   };
+
+USB PHY with optional OTG:
+
+Required properties:
+- compatible:  should contain "qcom,usb-otg-ci" for chipsets with
+   Chipidea 45nm PHY or "qcom,usb-otg-snps" for 
chipsets
+   with Synopsys 28nm PHY
+- regs:offset and length of the register set in the 
memory map
+- interrupts:  interrupt-specifier for the OTG interrupt.
+
+- clocks:  A list of phandle + clock-specifier pairs for the
+   clocks listed in clock-names
+- clock-names: Should contain the following:
+  "phy"USB PHY reference clock
+  "core"   Protocol engine clock
+  "iface"  Interface bus clock
+  "alt_core"   Optional: Protocol engine clock for targets with asynchronous
+   reset methodology.
+
+- dr_mode: One of "host", "peripheral" or "otg". Defaults to "otg"
+
+- vdccx-supply:phandle to the regulator for the vdd supply for
+   digital circuit operation.
+- v1p8-supply: phandle to the regulator for the 1.8V supply
+- v3p3-supply: phandle to the regulator for the 3.3V supply
+
+- qcom,otg-control: OTG control (VBUS and ID notifications) can be one of
+   1 - PHY control
+   2 - PMIC control
+   3 - User control (via debugfs)
+
+Optional properties:
+- qcom,phy-init-sequence: PHY configuration sequence. val, reg pairs
+   terminate with -1
+
+Example HSUSB OTG controller device node:
+
+   usb@f9a55000 {
+   compatible = "qcom,usb-otg-snps";
+   reg = <0xf9a55000 0x400>;
+   interrupts = <0 134 0>;;
+   dr_mode = "peripheral";
+
+   clocks = <&gcc GCC_XO_CLK>, <&gcc GCC_USB_HS_SYSTEM_CLK>,
+   <&gcc GCC_USB_HS_AHB_CLK>;
+
+   clock-names = "phy", "core", "iface";
+
+   vddcx-supply = <&pm8841_s2_corner>;
+   v1p8-supply = <&pm8941_l6>;
+   v3p3-supply = <&pm8941_l24>;
+
+   qcom,otg-control = <1>;
+   qcom,phy-init-sequence = <0x01 0x90 0x>;
+   };
diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c
index fa8e672d..cc230c8 100644
--- a/drivers/usb/phy/phy-msm-usb.c
+++ b/drivers/usb/phy/phy-msm-usb.c
@@ -30,9 +30,12 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1343,25 +1346,75 @@ static void msm_otg_debugfs_cleanup(void)
debugfs_remove(msm_otg_dbg_root);
 }
 
+static struct of_device_id msm_otg_dt_match[] = {
+   {
+   .compatible = "qcom,usb-otg-ci",
+   .data = (void *) CI_45NM_INTEGRATED_PHY
+   }, {
+   .compatible = "qcom,usb-otg-snps",
+   .data = (void *) SNPS_28NM_INTEGRATED_PHY
+   }, {}
+};
+
+static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg)
+{
+   struct msm_otg_platform_data *pdata;
+   const struct of_device_id *id;
+   struct device_node *node = pdev->dev.of_node;
+   int len = 0;
+   u32 val;
+
+   pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+   if (!pdata)
+   return -ENOMEM;
+
+   motg->pdata = pdata;
+
+   id = of_match_device(msm_otg_dt_match, &pdev->dev);
+   pdata->phy_type = (int) id->data;
+
+   pdata->mode = of_usb_get_dr_mode(node);
+   if (pdata->mode == USB_DR_MODE_UNKNOWN)
+   pdata->mode = USB_DR_MODE_OTG;
+
+   pdata->otg_control = OTG_PHY_CONTROL;
+   if (!of_property_read_u32(node, "qcom,otg-control", &val))
+   pdata->otg_control = val;
+
+   if (!of_get_property(node, "qcom,phy-init-sequence", &len) || !len)
+   return 0;
+
+   pdata->phy_init_seq = devm_kzalloc(&pdev->dev, len, GFP_KERNEL);
+   if (!pdata->phy_init_seq)
+   return 0;
+
+   of_property_read_u32_array(node, "qcom,phy-init-sequence",
+  

[PATCH v4 06/15] usb: phy: msm: Replace custom enum usb_mode_type with enum usb_dr_mode

2013-11-12 Thread Ivan T. Ivanov
From: "Ivan T. Ivanov" 

Use enum usb_dr_mode and drop default usb_dr_mode from platform data.

USB DT bindings states: dr_mode: "...In case this attribute isn't
passed via DT, USB DRD controllers should default to OTG...",
so remove redundand field.

Signed-off-by: Ivan T. Ivanov 
---
 arch/arm/mach-msm/board-msm7x30.c |2 +-
 arch/arm/mach-msm/board-qsd8x50.c |2 +-
 drivers/usb/phy/phy-msm-usb.c |   41 +++--
 include/linux/usb/msm_hsusb.h |   20 +-
 4 files changed, 20 insertions(+), 45 deletions(-)

diff --git a/arch/arm/mach-msm/board-msm7x30.c 
b/arch/arm/mach-msm/board-msm7x30.c
index 46de789..0c4c200 100644
--- a/arch/arm/mach-msm/board-msm7x30.c
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -95,7 +95,7 @@ static int hsusb_phy_clk_reset(struct clk *phy_clk)
 
 static struct msm_otg_platform_data msm_otg_pdata = {
.phy_init_seq   = hsusb_phy_init_seq,
-   .mode   = USB_PERIPHERAL,
+   .mode   = USB_DR_MODE_PERIPHERAL,
.otg_control= OTG_PHY_CONTROL,
.link_clk_reset = hsusb_link_clk_reset,
.phy_clk_reset  = hsusb_phy_clk_reset,
diff --git a/arch/arm/mach-msm/board-qsd8x50.c 
b/arch/arm/mach-msm/board-qsd8x50.c
index 9169ec3..4c74861 100644
--- a/arch/arm/mach-msm/board-qsd8x50.c
+++ b/arch/arm/mach-msm/board-qsd8x50.c
@@ -116,7 +116,7 @@ static int hsusb_phy_clk_reset(struct clk *phy_clk)
 
 static struct msm_otg_platform_data msm_otg_pdata = {
.phy_init_seq   = hsusb_phy_init_seq,
-   .mode   = USB_PERIPHERAL,
+   .mode   = USB_DR_MODE_PERIPHERAL,
.otg_control= OTG_PHY_CONTROL,
.link_clk_reset = hsusb_link_clk_reset,
.phy_clk_reset  = hsusb_phy_clk_reset,
diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c
index 8f148a6..00ee7b3 100644
--- a/drivers/usb/phy/phy-msm-usb.c
+++ b/drivers/usb/phy/phy-msm-usb.c
@@ -373,10 +373,10 @@ static int msm_otg_reset(struct usb_phy *phy)
 
if (pdata->otg_control == OTG_PHY_CONTROL) {
val = readl(USB_OTGSC);
-   if (pdata->mode == USB_OTG) {
+   if (pdata->mode == USB_DR_MODE_OTG) {
ulpi_val = ULPI_INT_IDGRD | ULPI_INT_SESS_VALID;
val |= OTGSC_IDIE | OTGSC_BSVIE;
-   } else if (pdata->mode == USB_PERIPHERAL) {
+   } else if (pdata->mode == USB_DR_MODE_PERIPHERAL) {
ulpi_val = ULPI_INT_SESS_VALID;
val |= OTGSC_BSVIE;
}
@@ -637,7 +637,7 @@ static int msm_otg_set_host(struct usb_otg *otg, struct 
usb_bus *host)
 * Fail host registration if this board can support
 * only peripheral configuration.
 */
-   if (motg->pdata->mode == USB_PERIPHERAL) {
+   if (motg->pdata->mode == USB_DR_MODE_PERIPHERAL) {
dev_info(otg->phy->dev, "Host mode is not supported\n");
return -ENODEV;
}
@@ -666,7 +666,7 @@ static int msm_otg_set_host(struct usb_otg *otg, struct 
usb_bus *host)
 * Kick the state machine work, if peripheral is not supported
 * or peripheral is already registered with us.
 */
-   if (motg->pdata->mode == USB_HOST || otg->gadget) {
+   if (motg->pdata->mode == USB_DR_MODE_HOST || otg->gadget) {
pm_runtime_get_sync(otg->phy->dev);
schedule_work(&motg->sm_work);
}
@@ -710,7 +710,7 @@ static int msm_otg_set_peripheral(struct usb_otg *otg,
 * Fail peripheral registration if this board can support
 * only host configuration.
 */
-   if (motg->pdata->mode == USB_HOST) {
+   if (motg->pdata->mode == USB_DR_MODE_HOST) {
dev_info(otg->phy->dev, "Peripheral mode is not supported\n");
return -ENODEV;
}
@@ -735,7 +735,7 @@ static int msm_otg_set_peripheral(struct usb_otg *otg,
 * Kick the state machine work, if host is not supported
 * or host is already registered with us.
 */
-   if (motg->pdata->mode == USB_PERIPHERAL || otg->host) {
+   if (motg->pdata->mode == USB_DR_MODE_PERIPHERAL || otg->host) {
pm_runtime_get_sync(otg->phy->dev);
schedule_work(&motg->sm_work);
}
@@ -1056,7 +1056,7 @@ static void msm_otg_init_sm(struct msm_otg *motg)
u32 otgsc = readl(USB_OTGSC);
 
switch (pdata->mode) {
-   case USB_OTG:
+   case USB_DR_MODE_OTG:
if (pdata->otg_control == OTG_PHY_CONTROL) {
if (otgsc & OTGSC_ID)
set_bit(ID, &motg->inputs);
@@ -1068,21 +1068,14 @@ static void msm_otg_init_sm(struct msm_otg *motg)
else
clear_bit(B_SESS_VLD, &motg->inputs);
} else if (pdat

[PATCH v4 03/15] usb: phy: msm: Migrate to Managed Device Resource allocation

2013-11-12 Thread Ivan T. Ivanov
From: "Ivan T. Ivanov" 

Move memory, regulators, clocks and irq allocation to
devm_* variants. Properly check for valid clk handles.

Signed-off-by: Ivan T. Ivanov 
---
 drivers/usb/phy/phy-msm-usb.c |  192 -
 1 file changed, 74 insertions(+), 118 deletions(-)

diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c
index c22cbd8..dac2b22 100644
--- a/drivers/usb/phy/phy-msm-usb.c
+++ b/drivers/usb/phy/phy-msm-usb.c
@@ -63,27 +63,18 @@ static int msm_hsusb_init_vddcx(struct msm_otg *motg, int 
init)
int ret = 0;
 
if (init) {
-   motg->vddcx = regulator_get(motg->phy.dev, "HSUSB_VDDCX");
-   if (IS_ERR(motg->vddcx)) {
-   dev_err(motg->phy.dev, "unable to get hsusb vddcx\n");
-   return PTR_ERR(motg->vddcx);
-   }
-
ret = regulator_set_voltage(motg->vddcx,
USB_PHY_VDD_DIG_VOL_MIN,
USB_PHY_VDD_DIG_VOL_MAX);
if (ret) {
dev_err(motg->phy.dev, "unable to set the voltage "
"for hsusb vddcx\n");
-   regulator_put(motg->vddcx);
return ret;
}
 
ret = regulator_enable(motg->vddcx);
-   if (ret) {
+   if (ret)
dev_err(motg->phy.dev, "unable to enable hsusb 
vddcx\n");
-   regulator_put(motg->vddcx);
-   }
} else {
ret = regulator_set_voltage(motg->vddcx, 0,
USB_PHY_VDD_DIG_VOL_MAX);
@@ -93,8 +84,6 @@ static int msm_hsusb_init_vddcx(struct msm_otg *motg, int 
init)
ret = regulator_disable(motg->vddcx);
if (ret)
dev_err(motg->phy.dev, "unable to disable hsusb 
vddcx\n");
-
-   regulator_put(motg->vddcx);
}
 
return ret;
@@ -105,53 +94,38 @@ static int msm_hsusb_ldo_init(struct msm_otg *motg, int 
init)
int rc = 0;
 
if (init) {
-   motg->v3p3 = regulator_get(motg->phy.dev, "HSUSB_3p3");
-   if (IS_ERR(motg->v3p3)) {
-   dev_err(motg->phy.dev, "unable to get hsusb 3p3\n");
-   return PTR_ERR(motg->v3p3);
-   }
-
rc = regulator_set_voltage(motg->v3p3, USB_PHY_3P3_VOL_MIN,
USB_PHY_3P3_VOL_MAX);
if (rc) {
dev_err(motg->phy.dev, "unable to set voltage level "
"for hsusb 3p3\n");
-   goto put_3p3;
+   goto exit;
}
rc = regulator_enable(motg->v3p3);
if (rc) {
dev_err(motg->phy.dev, "unable to enable the hsusb 
3p3\n");
-   goto put_3p3;
-   }
-   motg->v1p8 = regulator_get(motg->phy.dev, "HSUSB_1p8");
-   if (IS_ERR(motg->v1p8)) {
-   dev_err(motg->phy.dev, "unable to get hsusb 1p8\n");
-   rc = PTR_ERR(motg->v1p8);
-   goto disable_3p3;
+   goto exit;
}
rc = regulator_set_voltage(motg->v1p8, USB_PHY_1P8_VOL_MIN,
USB_PHY_1P8_VOL_MAX);
if (rc) {
dev_err(motg->phy.dev, "unable to set voltage level "
"for hsusb 1p8\n");
-   goto put_1p8;
+   goto disable_3p3;
}
rc = regulator_enable(motg->v1p8);
if (rc) {
dev_err(motg->phy.dev, "unable to enable the hsusb 
1p8\n");
-   goto put_1p8;
+   goto disable_3p3;
}
 
return 0;
}
 
regulator_disable(motg->v1p8);
-put_1p8:
-   regulator_put(motg->v1p8);
 disable_3p3:
regulator_disable(motg->v3p3);
-put_3p3:
-   regulator_put(motg->v3p3);
+exit:
return rc;
 }
 
@@ -507,7 +481,7 @@ static int msm_otg_suspend(struct msm_otg *motg)
 
clk_disable_unprepare(motg->pclk);
clk_disable_unprepare(motg->clk);
-   if (motg->core_clk)
+   if (!IS_ERR(motg->core_clk))
clk_disable_unprepare(motg->core_clk);
 
if (!IS_ERR(motg->pclk_src))
@@ -547,7 +521,7 @@ static int msm_otg_resume(struct msm_otg *motg)
 
clk_prepare_enable(motg->pclk);
clk_prepare_enable(motg->clk);
-   if (motg->core_clk)
+   if (!IS_ERR(motg->core_clk))
clk_prepare_enable(motg->core_clk);
 
if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY &&
@@ -1415,13 +1389,14 @@ static int __init msm_otg_probe(struct platform_device 
*pdev)

[PATCH v4 07/15] usb: phy: msm: Remove unused pclk_src_name

2013-11-12 Thread Ivan T. Ivanov
From: "Ivan T. Ivanov" 

There are no references to 'pclk_src_name' in plaform code,
so it is unused.

Signed-off-by: Ivan T. Ivanov 
---
 drivers/usb/phy/phy-msm-usb.c |   26 +-
 include/linux/usb/msm_hsusb.h |5 -
 2 files changed, 1 insertion(+), 30 deletions(-)

diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c
index 00ee7b3..9e9d4a3 100644
--- a/drivers/usb/phy/phy-msm-usb.c
+++ b/drivers/usb/phy/phy-msm-usb.c
@@ -465,9 +465,6 @@ static int msm_otg_suspend(struct msm_otg *motg)
if (!IS_ERR(motg->core_clk))
clk_disable_unprepare(motg->core_clk);
 
-   if (!IS_ERR(motg->pclk_src))
-   clk_disable_unprepare(motg->pclk_src);
-
if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY &&
motg->pdata->otg_control == OTG_PMIC_CONTROL) {
msm_hsusb_ldo_set_mode(motg, 0);
@@ -497,9 +494,6 @@ static int msm_otg_resume(struct msm_otg *motg)
if (!atomic_read(&motg->in_lpm))
return 0;
 
-   if (!IS_ERR(motg->pclk_src))
-   clk_prepare_enable(motg->pclk_src);
-
clk_prepare_enable(motg->pclk);
clk_prepare_enable(motg->clk);
if (!IS_ERR(motg->core_clk))
@@ -1395,17 +1389,8 @@ static int __init msm_otg_probe(struct platform_device 
*pdev)
 * If USB Core is running its protocol engine based on CORE CLK,
 * CORE CLK  must be running at >55Mhz for correct HSUSB
 * operation and USB core cannot tolerate frequency changes on
-* CORE CLK. For such USB cores, vote for maximum clk frequency
-* on pclk source
+* CORE CLK.
 */
-motg->pclk_src = ERR_PTR(-ENOENT);
-if (motg->pdata->pclk_src_name) {
-   motg->pclk_src = devm_clk_get(&pdev->dev,
-   motg->pdata->pclk_src_name);
-   if (IS_ERR(motg->pclk_src))
-   return PTR_ERR(motg->pclk_src);
-   }
-
motg->pclk = devm_clk_get(&pdev->dev, "usb_hs_pclk");
if (IS_ERR(motg->pclk)) {
dev_err(&pdev->dev, "failed to get usb_hs_pclk\n");
@@ -1451,10 +1436,6 @@ static int __init msm_otg_probe(struct platform_device 
*pdev)
}
 
clk_set_rate(motg->clk, 6000);
-   if (!IS_ERR(motg->pclk_src)) {
-   clk_set_rate(motg->pclk_src, INT_MAX);
-   clk_prepare_enable(motg->pclk_src);
-   }
 
clk_prepare_enable(motg->clk);
clk_prepare_enable(motg->pclk);
@@ -1530,8 +1511,6 @@ disable_clks:
clk_disable_unprepare(motg->clk);
if (!IS_ERR(motg->core_clk))
clk_disable_unprepare(motg->core_clk);
-   if (!IS_ERR(motg->pclk_src))
-   clk_disable_unprepare(motg->pclk_src);
return ret;
 }
 
@@ -1576,9 +1555,6 @@ static int msm_otg_remove(struct platform_device *pdev)
clk_disable_unprepare(motg->clk);
if (!IS_ERR(motg->core_clk))
clk_disable_unprepare(motg->core_clk);
-   if (!IS_ERR(motg->pclk_src))
-   clk_disable_unprepare(motg->pclk_src);
-
msm_hsusb_ldo_init(motg, 0);
 
pm_runtime_set_suspended(&pdev->dev);
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 72c5830..262ed80 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -106,8 +106,6 @@ enum usb_chg_type {
  * @power_budget: VBUS power budget in mA (0 will be treated as 500mA).
  * @mode: Supported mode (OTG/peripheral/host).
  * @otg_control: OTG switch controlled by user/Id pin
- * @pclk_src_name: pclk is derived from ebi1_usb_clk in case of 7x27 and 8k
- *  dfab_usb_hs_clk in case of 8660 and 8960.
  */
 struct msm_otg_platform_data {
int *phy_init_seq;
@@ -117,7 +115,6 @@ struct msm_otg_platform_data {
enum otg_control_type otg_control;
enum msm_usb_phy_type phy_type;
void (*setup_gpio)(enum usb_otg_state state);
-   char *pclk_src_name;
int (*link_clk_reset)(struct clk *link_clk, bool assert);
int (*phy_clk_reset)(struct clk *phy_clk);
 };
@@ -129,7 +126,6 @@ struct msm_otg_platform_data {
  * @irq: IRQ number assigned for HSUSB controller.
  * @clk: clock struct of usb_hs_clk.
  * @pclk: clock struct of usb_hs_pclk.
- * @pclk_src: pclk source for voting.
  * @phy_reset_clk: clock struct of usb_phy_clk.
  * @core_clk: clock struct of usb_hs_core_clk.
  * @regs: ioremapped register base address.
@@ -150,7 +146,6 @@ struct msm_otg {
int irq;
struct clk *clk;
struct clk *pclk;
-   struct clk *pclk_src;
struct clk *phy_reset_clk;
struct clk *core_clk;
void __iomem *regs;
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] usb: phy: generic: re-factor the way we find out about our resources

2013-11-12 Thread Felipe Balbi
instead of having each user of generic phy find
out about its own resources and pass it to the
core layer, have th core layer itself figure that
out. It's as simple as moving a piece of code
around.

Signed-off-by: Felipe Balbi 
---
 drivers/usb/phy/phy-am335x.c  |  3 +--
 drivers/usb/phy/phy-generic.c | 61 +--
 drivers/usb/phy/phy-generic.h |  4 ++-
 3 files changed, 34 insertions(+), 34 deletions(-)

diff --git a/drivers/usb/phy/phy-am335x.c b/drivers/usb/phy/phy-am335x.c
index 48d41ab..0e3c60c 100644
--- a/drivers/usb/phy/phy-am335x.c
+++ b/drivers/usb/phy/phy-am335x.c
@@ -52,8 +52,7 @@ static int am335x_phy_probe(struct platform_device *pdev)
return am_phy->id;
}
 
-   ret = usb_phy_gen_create_phy(dev, &am_phy->usb_phy_gen,
-   USB_PHY_TYPE_USB2, 0, false);
+   ret = usb_phy_gen_create_phy(dev, &am_phy->usb_phy_gen, NULL);
if (ret)
return ret;
 
diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c
index db4fc22..0c3b241 100644
--- a/drivers/usb/phy/phy-generic.c
+++ b/drivers/usb/phy/phy-generic.c
@@ -150,10 +150,38 @@ static int nop_set_host(struct usb_otg *otg, struct 
usb_bus *host)
 }
 
 int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_gen_xceiv *nop,
-   enum usb_phy_type type, u32 clk_rate, bool needs_vcc)
+   struct usb_phy_gen_xceiv_platform_data *pdata)
 {
+   enum usb_phy_type type = USB_PHY_TYPE_USB2;
int err;
 
+   u32 clk_rate = 0;
+   bool needs_vcc = false;
+
+   nop->reset_active_low = true;   /* default behaviour */
+
+   if (dev->of_node) {
+   struct device_node *node = dev->of_node;
+   enum of_gpio_flags flags;
+
+   if (of_property_read_u32(node, "clock-frequency", &clk_rate))
+   clk_rate = 0;
+
+   needs_vcc = of_property_read_bool(node, "vcc-supply");
+   nop->gpio_reset = of_get_named_gpio_flags(node, "reset-gpios",
+   0, &flags);
+   if (nop->gpio_reset == -EPROBE_DEFER)
+   return -EPROBE_DEFER;
+
+   nop->reset_active_low = flags & OF_GPIO_ACTIVE_LOW;
+
+   } else if (pdata) {
+   type = pdata->type;
+   clk_rate = pdata->clk_rate;
+   needs_vcc = pdata->needs_vcc;
+   nop->gpio_reset = pdata->gpio_reset;
+   }
+
nop->phy.otg = devm_kzalloc(dev, sizeof(*nop->phy.otg),
GFP_KERNEL);
if (!nop->phy.otg)
@@ -218,43 +246,14 @@ EXPORT_SYMBOL_GPL(usb_phy_gen_create_phy);
 static int usb_phy_gen_xceiv_probe(struct platform_device *pdev)
 {
struct device *dev = &pdev->dev;
-   struct usb_phy_gen_xceiv_platform_data *pdata =
-   dev_get_platdata(&pdev->dev);
struct usb_phy_gen_xceiv*nop;
-   enum usb_phy_type   type = USB_PHY_TYPE_USB2;
int err;
-   u32 clk_rate = 0;
-   bool needs_vcc = false;
 
nop = devm_kzalloc(dev, sizeof(*nop), GFP_KERNEL);
if (!nop)
return -ENOMEM;
 
-   nop->reset_active_low = true;   /* default behaviour */
-
-   if (dev->of_node) {
-   struct device_node *node = dev->of_node;
-   enum of_gpio_flags flags;
-
-   if (of_property_read_u32(node, "clock-frequency", &clk_rate))
-   clk_rate = 0;
-
-   needs_vcc = of_property_read_bool(node, "vcc-supply");
-   nop->gpio_reset = of_get_named_gpio_flags(node, "reset-gpios",
-   0, &flags);
-   if (nop->gpio_reset == -EPROBE_DEFER)
-   return -EPROBE_DEFER;
-
-   nop->reset_active_low = flags & OF_GPIO_ACTIVE_LOW;
-
-   } else if (pdata) {
-   type = pdata->type;
-   clk_rate = pdata->clk_rate;
-   needs_vcc = pdata->needs_vcc;
-   nop->gpio_reset = pdata->gpio_reset;
-   }
-
-   err = usb_phy_gen_create_phy(dev, nop, type, clk_rate, needs_vcc);
+   err = usb_phy_gen_create_phy(dev, nop, dev_get_platdata(&pdev->dev));
if (err)
return err;
 
diff --git a/drivers/usb/phy/phy-generic.h b/drivers/usb/phy/phy-generic.h
index d2a220d..38a81f3 100644
--- a/drivers/usb/phy/phy-generic.h
+++ b/drivers/usb/phy/phy-generic.h
@@ -1,6 +1,8 @@
 #ifndef _PHY_GENERIC_H_
 #define _PHY_GENERIC_H_
 
+#include 
+
 struct usb_phy_gen_xceiv {
struct usb_phy phy;
struct device *dev;
@@ -14,6 +16,6 @@ int usb_gen_phy_init(struct usb_phy *phy);
 void usb_gen_phy_shutdown(struct usb_phy *phy);
 
 int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_gen_xceiv *nop,
-   enum usb_phy_type type, u32 clk_rate, bool needs_vcc);
+   struct usb_phy_gen

Re: [PATCH] usb: phy: remove dead code

2013-11-12 Thread Felipe Balbi
On Sun, Nov 10, 2013 at 07:37:37PM +0100, Michal Nazarewicz wrote:
> From: Michal Nazarewicz 


no SoB, cannot apply. I already had this patch in my tree but didn't
send it. I'm fine with using yours but I need SoB and commit log.

-- 
balbi


signature.asc
Description: Digital signature


[PATCH 1/2] usb: musb: musb_cppi41: factor most of cppi41_dma_callback() into cppi41_trans_done()

2013-11-12 Thread Sebastian Andrzej Siewior
This patch moves most of the logic in cppi41_dma_callback() into
cppi41_trans_done() where it can be called from another function.
Instead of computing "transferred" (the number of bytes transferred in
the last transaction) in cppi41_trans_done() the member
"cppi41_channel->prog_len" is now set to 0 if the transfer as a whole
can be considered as done. If it is != 0 then the next iteration is
assumed.
This is a preparation for a workaround.

Cc: sta...@vger.kernel.org
Signed-off-by: Sebastian Andrzej Siewior 
---
 drivers/usb/musb/musb_cppi41.c | 59 ++
 1 file changed, 36 insertions(+), 23 deletions(-)

diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c
index ff9d6de..83a8a1d 100644
--- a/drivers/usb/musb/musb_cppi41.c
+++ b/drivers/usb/musb/musb_cppi41.c
@@ -96,31 +96,15 @@ static void update_rx_toggle(struct cppi41_dma_channel 
*cppi41_channel)
cppi41_channel->usb_toggle = toggle;
 }
 
-static void cppi41_dma_callback(void *private_data)
+static void cppi41_dma_callback(void *private_data);
+
+static void cppi41_trans_done(struct dma_channel *channel)
 {
-   struct dma_channel *channel = private_data;
struct cppi41_dma_channel *cppi41_channel = channel->private_data;
struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep;
struct musb *musb = hw_ep->musb;
-   unsigned long flags;
-   struct dma_tx_state txstate;
-   u32 transferred;
 
-   spin_lock_irqsave(&musb->lock, flags);
-
-   dmaengine_tx_status(cppi41_channel->dc, cppi41_channel->cookie,
-   &txstate);
-   transferred = cppi41_channel->prog_len - txstate.residue;
-   cppi41_channel->transferred += transferred;
-
-   dev_dbg(musb->controller, "DMA transfer done on hw_ep=%d bytes=%d/%d\n",
-   hw_ep->epnum, cppi41_channel->transferred,
-   cppi41_channel->total_len);
-
-   update_rx_toggle(cppi41_channel);
-
-   if (cppi41_channel->transferred == cppi41_channel->total_len ||
-   transferred < cppi41_channel->packet_sz) {
+   if (!cppi41_channel->prog_len) {
 
/* done, complete */
cppi41_channel->channel.actual_len =
@@ -150,10 +134,8 @@ static void cppi41_dma_callback(void *private_data)
remain_bytes,
direction,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
-   if (WARN_ON(!dma_desc)) {
-   spin_unlock_irqrestore(&musb->lock, flags);
+   if (WARN_ON(!dma_desc))
return;
-   }
 
dma_desc->callback = cppi41_dma_callback;
dma_desc->callback_param = channel;
@@ -166,6 +148,37 @@ static void cppi41_dma_callback(void *private_data)
musb_writew(epio, MUSB_RXCSR, csr);
}
}
+}
+
+static void cppi41_dma_callback(void *private_data)
+{
+   struct dma_channel *channel = private_data;
+   struct cppi41_dma_channel *cppi41_channel = channel->private_data;
+   struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep;
+   struct musb *musb = hw_ep->musb;
+   unsigned long flags;
+   struct dma_tx_state txstate;
+   u32 transferred;
+
+   spin_lock_irqsave(&musb->lock, flags);
+
+   dmaengine_tx_status(cppi41_channel->dc, cppi41_channel->cookie,
+   &txstate);
+   transferred = cppi41_channel->prog_len - txstate.residue;
+   cppi41_channel->transferred += transferred;
+
+   dev_dbg(musb->controller, "DMA transfer done on hw_ep=%d bytes=%d/%d\n",
+   hw_ep->epnum, cppi41_channel->transferred,
+   cppi41_channel->total_len);
+
+   update_rx_toggle(cppi41_channel);
+
+   if (cppi41_channel->transferred == cppi41_channel->total_len ||
+   transferred < cppi41_channel->packet_sz)
+   cppi41_channel->prog_len = 0;
+
+   cppi41_trans_done(channel);
+
spin_unlock_irqrestore(&musb->lock, flags);
 }
 
-- 
1.8.4.2

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] usb: musb: musb_cppi41: handle pre-mature TX complete interrupt

2013-11-12 Thread Sebastian Andrzej Siewior
The TX-complete interrupt of the CPPI41 on AM335x fires too early.
Adding a loop and counting how long it takes until the
MUSB_TXCSR_TXPKTRDY bit is cleared I see
FS:
|musb-hdrc musb-hdrc.0.auto: configure ep1/80 packet_sz=64, mode=0, 
dma_addr=0xadc54002, len=1514 is_tx=1
|cppi41_dma_callback() 74 loops
|musb-hdrc musb-hdrc.0.auto: configure ep1/80 packet_sz=64, mode=0, 
dma_addr=0xadcd8802, len=1514 is_tx=1
|cppi41_dma_callback() 66 loops
|musb-hdrc musb-hdrc.0.auto: configure ep1/80 packet_sz=64, mode=0, 
dma_addr=0xadcd8002, len=1514 is_tx=1
|cppi41_dma_callback() 136 loops
|musb-hdrc musb-hdrc.0.auto: configure ep1/80 packet_sz=64, mode=0, 
dma_addr=0xadf55802, len=1514 is_tx=1
|cppi41_dma_callback() 136 loops

avg: 110 - 150us

HS:
|musb-hdrc musb-hdrc.0.auto: configure ep1/80 packet_sz=512, mode=0, 
dma_addr=0xaca6f002, len=1514 is_tx=1
|cppi41_dma_callback() 0 loops
|musb-hdrc musb-hdrc.0.auto: configure ep1/80 packet_sz=512, mode=0, 
dma_addr=0xadd6f802, len=1514 is_tx=1
|cppi41_dma_callback() 2 loops
|musb-hdrc musb-hdrc.0.auto: configure ep1/80 packet_sz=512, mode=0, 
dma_addr=0xadd6f002, len=1514 is_tx=1
|cppi41_dma_callback() 13 loops

avg: 2us

for the same test case. One loop means a udelay(1). The delay seems to
depend on the packet size. On HS the bit is always cleared for small
packet sizes while on FS it is never the case, it mostly around 110us.
This testing has been performed with g_ether (musb as device) and using BULK
transfers.

INTR transfers are way more fun: during init the gadget sends a INT
packet to the host and cppi41 says "transfer done" shortly after. The
MUSB_TXCSR_TXPKTRDY bit is set even seconds later. The reason is that the host
did not try to receive it, it does so after the interface (on host side) has
been configured. Until this happens, that packet remains in musb's FIFO.

To fix this, two things are done:
- No DMA transfers for INT based endpoints. These transfer are usually
  very small and rare so it is likely better to skip the DMA engine and
  stuff the four bytes directly into the FIFO
- on HS we poll up to 25us and hope that bit goes away. If not we setup
  a hrtimer to poll for it. The 140us delay is a rule of thumb. In FS
  the command
  | ping 10.10.10.10 -c1 -s65130
  creates about 44 1514bytes transfers. About 19 of them need a second
  timer to complete.

Reported-by: Bin Liu 
Cc: sta...@vger.kernel.org
Signed-off-by: Sebastian Andrzej Siewior 
---
 drivers/usb/musb/musb_cppi41.c | 113 +++--
 1 file changed, 108 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c
index 83a8a1d..a12bd30 100644
--- a/drivers/usb/musb/musb_cppi41.c
+++ b/drivers/usb/musb/musb_cppi41.c
@@ -38,6 +38,7 @@ struct cppi41_dma_channel {
u32 prog_len;
u32 transferred;
u32 packet_sz;
+   struct list_head tx_check;
 };
 
 #define MUSB_DMA_NUM_CHANNELS 15
@@ -47,6 +48,8 @@ struct cppi41_dma_controller {
struct cppi41_dma_channel rx_channel[MUSB_DMA_NUM_CHANNELS];
struct cppi41_dma_channel tx_channel[MUSB_DMA_NUM_CHANNELS];
struct musb *musb;
+   struct hrtimer early_tx;
+   struct list_head early_tx_list;
u32 rx_mode;
u32 tx_mode;
u32 auto_req;
@@ -96,11 +99,23 @@ static void update_rx_toggle(struct cppi41_dma_channel 
*cppi41_channel)
cppi41_channel->usb_toggle = toggle;
 }
 
+static bool musb_is_tx_fifo_empty(struct musb_hw_ep *hw_ep)
+{
+   u8  epnum = hw_ep->epnum;
+   struct musb *musb = hw_ep->musb;
+   void __iomem*epio = musb->endpoints[epnum].regs;
+   u16 csr;
+
+   csr = musb_readw(epio, MUSB_TXCSR);
+   if (csr & MUSB_TXCSR_TXPKTRDY)
+   return false;
+   return true;
+}
+
 static void cppi41_dma_callback(void *private_data);
 
-static void cppi41_trans_done(struct dma_channel *channel)
+static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel)
 {
-   struct cppi41_dma_channel *cppi41_channel = channel->private_data;
struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep;
struct musb *musb = hw_ep->musb;
 
@@ -138,7 +153,7 @@ static void cppi41_trans_done(struct dma_channel *channel)
return;
 
dma_desc->callback = cppi41_dma_callback;
-   dma_desc->callback_param = channel;
+   dma_desc->callback_param = &cppi41_channel->channel;
cppi41_channel->cookie = dma_desc->tx_submit(dma_desc);
dma_async_issue_pending(dc);
 
@@ -150,6 +165,41 @@ static void cppi41_trans_done(struct dma_channel *channel)
}
 }
 
+static enum hrtimer_restart cppi41_recheck_tx_req(struct hrtimer *timer)
+{
+   struct cppi41_dma_controller *controller;
+   struct cppi41_dma_channel *cppi41_channel, *n;
+   struct musb *musb;
+   unsigned long flags;
+   enum hrtimer_restart ret = HRTIMER_NORESTART;
+
+

Re: [PATCHv2 2/2] check quirk to pad epout buf size when not aligned to maxpacketsize

2013-11-12 Thread Alan Stern
On Mon, 11 Nov 2013, David Cohen wrote:

> Hi Alan, Michal,
> 
> On 11/11/2013 01:09 PM, Michal Nazarewicz wrote:
> > On Mon, Nov 11 2013, Alan Stern wrote:
> >> On Mon, 11 Nov 2013, Michal Nazarewicz wrote:
> >>
> >>> Check gadget.quirk_ep_out_aligned_size to decide if buffer size requires
> >>> to be aligned to maxpacketsize of an out endpoint.  ffs_epfile_io() needs
> >>> to pad epout buffer to match above condition if quirk is found.
> >>>
> >>> Signed-off-by: Michal Nazarewicz 
> >>
> >> I think this is still wrong.
> >>
> >>> @@ -824,7 +832,7 @@ static ssize_t ffs_epfile_io(struct file *file,
> >>>   req->context  = &done;
> >>>   req->complete = ffs_epfile_io_complete;
> >>>   req->buf  = data;
> >>> - req->length   = len;
> >>> + req->length   = data_len;
> >>
> >> IIUC, req->length should still be set to len, not to data_len.
> 
> I misunderstood the first time I read it:
> In order to avoid DWC3 to stall, we need to update req->length (this is
> the most important fix). kmalloc() is updated too to prevent USB
> controller to overflow buffer boundaries.

Here I disagree.

If the DWC3 hardware stalls, it is up to the DWC3 UDC driver to fix it.  
Gadget drivers should not have to worry.  Most especially, gadget 
drivers should not lie about a request length.

If the UDC driver decides to round up req->length before sending it to
the hardware, that's okay.  But req->length should be set to len, not
data_len.  And if the hardware receives more than len bytes of data,
the UDC driver should set req->status to -EOVERFLOW.

Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 1/3] ohci: convert printk to dev_dbg

2013-11-12 Thread oliver
From: Oliver Neukum 

This converts the DEBUG level printk to dynamic debugging

Signed-off-by: Oliver Neukum 
---
 drivers/usb/host/ohci-dbg.c | 104 ++--
 drivers/usb/host/ohci-hcd.c |   4 --
 drivers/usb/host/ohci-q.c   |   2 -
 3 files changed, 51 insertions(+), 59 deletions(-)

diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c
index 3fca52e..f0523c8 100644
--- a/drivers/usb/host/ohci-dbg.c
+++ b/drivers/usb/host/ohci-dbg.c
@@ -9,8 +9,6 @@
 
 /*-*/
 
-#ifdef DEBUG
-
 #define edstring(ed_type) ({ char *temp; \
switch (ed_type) { \
case PIPE_CONTROL:  temp = "ctrl"; break; \
@@ -20,57 +18,6 @@
} temp;})
 #define pipestring(pipe) edstring(usb_pipetype(pipe))
 
-/* debug| print the main components of an URB
- * small: 0) header + data packets 1) just header
- */
-static void __maybe_unused
-urb_print(struct urb * urb, char * str, int small, int status)
-{
-   unsigned int pipe= urb->pipe;
-
-   if (!urb->dev || !urb->dev->bus) {
-   printk(KERN_DEBUG "%s URB: no dev\n", str);
-   return;
-   }
-
-#ifndefOHCI_VERBOSE_DEBUG
-   if (status != 0)
-#endif
-   printk(KERN_DEBUG "%s %p dev=%d ep=%d%s-%s flags=%x len=%d/%d 
stat=%d\n",
-   str,
-   urb,
-   usb_pipedevice (pipe),
-   usb_pipeendpoint (pipe),
-   usb_pipeout (pipe)? "out" : "in",
-   pipestring (pipe),
-   urb->transfer_flags,
-   urb->actual_length,
-   urb->transfer_buffer_length,
-   status);
-
-#ifdef OHCI_VERBOSE_DEBUG
-   if (!small) {
-   int i, len;
-
-   if (usb_pipecontrol (pipe)) {
-   printk (KERN_DEBUG "%s: setup(8):", __FILE__);
-   for (i = 0; i < 8 ; i++)
-   printk (" %02x", ((__u8 *) urb->setup_packet) 
[i]);
-   printk ("\n");
-   }
-   if (urb->transfer_buffer_length > 0 && urb->transfer_buffer) {
-   printk (KERN_DEBUG "%s: data(%d/%d):", __FILE__,
-   urb->actual_length,
-   urb->transfer_buffer_length);
-   len = usb_pipeout (pipe)?
-   urb->transfer_buffer_length: 
urb->actual_length;
-   for (i = 0; i < 16 && i < len; i++)
-   printk (" %02x", ((__u8 *) 
urb->transfer_buffer) [i]);
-   printk ("%s stat:%d\n", i < len? "...": "", status);
-   }
-   }
-#endif
-}
 
 #define ohci_dbg_sw(ohci, next, size, format, arg...) \
do { \
@@ -91,6 +38,7 @@ urb_print(struct urb * urb, char * str, int small, int status)
} while (0);
 
 
+#ifdef DEBUG
 static void ohci_dump_intr_mask (
struct ohci_hcd *ohci,
char *label,
@@ -873,5 +821,55 @@ static inline void remove_debug_files (struct ohci_hcd 
*ohci)
 
 #endif
 
+/* debug| print the main components of an URB
+ * small: 0) header + data packets 1) just header
+ */
+static void __maybe_unused
+urb_print(struct urb * urb, char * str, int small, int status)
+{
+   unsigned int pipe= urb->pipe;
+   struct device *ddev;
+
+   if (!urb->dev || !urb->dev->bus) {
+   pr_debug("%s URB: no dev\n", str);
+   return;
+   }
+
+   ddev = &urb->dev->dev;
+
+   dev_dbg(ddev, "%s %p dev=%d ep=%d%s-%s flags=%x len=%d/%d stat=%d\n",
+   str,
+   urb,
+   usb_pipedevice (pipe),
+   usb_pipeendpoint (pipe),
+   usb_pipeout (pipe)? "out" : "in",
+   pipestring (pipe),
+   urb->transfer_flags,
+   urb->actual_length,
+   urb->transfer_buffer_length,
+   status);
+
+   if (!small) {
+   int i, len;
+
+   if (usb_pipecontrol (pipe)) {
+   dev_dbg(ddev, "%s: setup(8):", __FILE__);
+   for (i = 0; i < 8 ; i++)
+   dev_dbg(ddev," %02x", ((__u8 *) 
urb->setup_packet) [i]);
+   dev_dbg(ddev,"\n");
+   }
+   if (urb->transfer_buffer_length > 0 && urb->transfer_buffer) {
+   dev_dbg(ddev, "%s: data(%d/%d):", __FILE__,
+   urb->actual_length,
+   urb->transfer_buffer_length);
+   len = usb_pipeout (pipe)?
+   urb->transfer_buffer_length: 
urb->actual_length;
+   for (i = 0; i < 16 && i < len; i++)
+   dev_dbg(ddev," %02x", ((__u8 *) 
urb->tra

[RFC 2/3] ohci: compile all debug stuff always

2013-11-12 Thread oliver
From: Oliver Neukum 

There's no reason to leave out the debugfs files
under normal conditions.

Signed-off-by: Oliver Neukum 
---
 drivers/usb/host/ohci-dbg.c | 10 +-
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c
index f0523c8..5592c2b 100644
--- a/drivers/usb/host/ohci-dbg.c
+++ b/drivers/usb/host/ohci-dbg.c
@@ -1,3 +1,4 @@
+
 /*
  * OHCI HCD (Host Controller Driver) for USB.
  *
@@ -37,8 +38,6 @@
*size -= s_len; *next += s_len; \
} while (0);
 
-
-#ifdef DEBUG
 static void ohci_dump_intr_mask (
struct ohci_hcd *ohci,
char *label,
@@ -355,13 +354,6 @@ ohci_dump_ed (const struct ohci_hcd *ohci, const char 
*label,
}
 }
 
-#else
-static inline void ohci_dump (struct ohci_hcd *controller, int verbose) {}
-
-#undef OHCI_VERBOSE_DEBUG
-
-#endif /* DEBUG */
-
 /*-*/
 
 #ifdef STUB_DEBUG_FILES
-- 
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 3/3] ohci: rewrite ohci_dump() for dynamic debug

2013-11-12 Thread oliver
From: Oliver Neukum 

As this function is called from interrupt care must
be taken that as little as possible overhead is used
if dynamic debbuging is not enabled.

Signed-off-by: Oliver Neukum 
---
 drivers/usb/host/ohci-dbg.c | 91 -
 1 file changed, 90 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c
index 5592c2b..2a67971 100644
--- a/drivers/usb/host/ohci-dbg.c
+++ b/drivers/usb/host/ohci-dbg.c
@@ -38,6 +38,8 @@
*size -= s_len; *next += s_len; \
} while (0);
 
+static void ohci_dump_status (struct ohci_hcd *controller, char **next, 
unsigned *size);
+
 static void ohci_dump_intr_mask (
struct ohci_hcd *ohci,
char *label,
@@ -60,6 +62,25 @@ static void ohci_dump_intr_mask (
);
 }
 
+static void ohci_print_intr_mask(struct ohci_hcd *ohci,
+char *label,
+u32 mask)
+{
+   ohci_dbg(ohci, "%s 0x%08x%s%s%s%s%s%s%s%s%s\n",
+   label,
+   mask,
+   (mask & OHCI_INTR_MIE) ? " MIE" : "",
+   (mask & OHCI_INTR_OC) ? " OC" : "",
+   (mask & OHCI_INTR_RHSC) ? " RHSC" : "",
+   (mask & OHCI_INTR_FNO) ? " FNO" : "",
+   (mask & OHCI_INTR_UE) ? " UE" : "",
+   (mask & OHCI_INTR_RD) ? " RD" : "",
+   (mask & OHCI_INTR_SF) ? " SF" : "",
+   (mask & OHCI_INTR_WDH) ? " WDH" : "",
+   (mask & OHCI_INTR_SO) ? " SO" : ""
+   );
+}
+
 static void maybe_print_eds (
struct ohci_hcd *ohci,
char *label,
@@ -71,6 +92,15 @@ static void maybe_print_eds (
ohci_dbg_sw (ohci, next, size, "%s %08x\n", label, value);
 }
 
+static inline void dbg_eds(
+   struct ohci_hcd *ohci,
+   char *label,
+   u32 value)
+{
+   if (value)
+   ohci_dbg(ohci, "%s %08x\n", label, value);
+}
+
 static char *hcfs2string (int state)
 {
switch (state) {
@@ -97,6 +127,65 @@ static const char *rh_state_string(struct ohci_hcd *ohci)
 
 // dump control and status registers
 static void
+ohci_print_status(struct ohci_hcd *controller)
+{
+   struct ohci_regs __iomem *regs = controller->regs;
+   struct device *ddev = ohci_to_hcd(controller)->self.controller;
+   u32 temp = 0x;
+
+   dev_dbg(ddev, "OHCI %d.", 0x03 & ((temp = ohci_readl(controller, 
®s->revision) & 0xff)>> 4));
+   dev_dbg(ddev, "%d, %s legacy support registers, rh state %s\n",
+   (temp & 0x0f),
+   (temp & 0x0100) ? "with" : "NO",
+   rh_state_string(controller));
+
+   dev_dbg(ddev, "control 0x%03x", temp = ohci_readl(controller, 
®s->control));
+   dev_dbg(ddev, "%s%s%s HCFS=%s%s%s%s%s CBSR=%d\n",
+   (temp & OHCI_CTRL_RWE) ? " RWE" : "",
+   (temp & OHCI_CTRL_RWC) ? " RWC" : "",
+   (temp & OHCI_CTRL_IR) ? " IR" : "",
+   hcfs2string (temp & OHCI_CTRL_HCFS),
+   (temp & OHCI_CTRL_BLE) ? " BLE" : "",
+   (temp & OHCI_CTRL_CLE) ? " CLE" : "",
+   (temp & OHCI_CTRL_IE) ? " IE" : "",
+   (temp & OHCI_CTRL_PLE) ? " PLE" : "",
+   temp & OHCI_CTRL_CBSR
+   );
+
+   dev_dbg(ddev, "cmdstatus 0x%05x ", temp = ohci_readl(controller, 
®s->cmdstatus));
+   dev_dbg(ddev, "SOC=%d%s%s%s%s\n",
+   (temp & OHCI_SOC) >> 16,
+   (temp & OHCI_OCR) ? " OCR" : "",
+   (temp & OHCI_BLF) ? " BLF" : "",
+   (temp & OHCI_CLF) ? " CLF" : "",
+   (temp & OHCI_HCR) ? " HCR" : ""
+   );
+
+   ohci_print_intr_mask(controller, "intrstatus",
+   ohci_readl(controller, ®s->intrstatus));
+   ohci_print_intr_mask(controller, "intrenable",
+   ohci_readl(controller, ®s->intrenable));
+   // intrdisable always same as intrenable
+
+   dbg_eds(controller, "ed_periodcurrent",
+   ohci_readl(controller, ®s->ed_periodcurrent));
+
+   dbg_eds(controller, "ed_controlhead",
+   ohci_readl(controller, ®s->ed_controlhead));
+   dbg_eds(controller, "ed_controlcurrent",
+   ohci_readl(controller, ®s->ed_controlcurrent));
+
+   dbg_eds(controller, "ed_bulkhead",
+   ohci_readl(controller, ®s->ed_bulkhead));
+   dbg_eds(controller, "ed_bulkcurrent",
+   ohci_readl(controller, ®s->ed_bulkcurrent));
+
+   dbg_eds(controller, "donehead",
+   ohci_readl(controller, ®s->donehead));
+}
+
+// dump control and status registers
+static void
 ohci_dump_status (struct ohci_hcd *controller, char **next, unsigned *size)
 {
struct ohci_regs __iomem *regs = controller->regs;
@@ -241,7 +330,7 @@ static void ohci_dump (struct ohci_hcd *controller, int 
verbose)
o

[PATCH] usbnet: fix status interrupt urb handling

2013-11-12 Thread Felix Fietkau
Since commit 7b0c5f21f348a66de495868b8df0284e8dfd6bbf
"sierra_net: keep status interrupt URB active", sierra_net triggers
status interrupt polling before the net_device is opened (in order to
properly receive the sync message response).

To be able to receive further interrupts, the interrupt urb needs to be
re-submitted, so this patch removes the bogus check for netif_running().

Cc: sta...@vger.kernel.org
Signed-off-by: Felix Fietkau 
---
 drivers/net/usb/usbnet.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 90a429b..8494bb5 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -204,9 +204,6 @@ static void intr_complete (struct urb *urb)
break;
}
 
-   if (!netif_running (dev->net))
-   return;
-
status = usb_submit_urb (urb, GFP_ATOMIC);
if (status != 0)
netif_err(dev, timer, dev->net,
-- 
1.8.3.4 (Apple Git-47)

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] usb: phy: remove dead code

2013-11-12 Thread Michal Nazarewicz
Commit [4d175f34: usb: phy: nop: Defer clock prepare until PHY init]
removed a goto reaching behind a “return ret” at the end of the function
thus removing the only possible way that statement could be reached, and
so rendering it a dead code.  This commit cleans it up by removing said
dead code.

Signed-off-by: Michal Nazarewicz 
---
 drivers/usb/phy/phy-am335x.c  | 2 --
 drivers/usb/phy/phy-generic.c | 2 --
 2 files changed, 4 deletions(-)

On Tue, Nov 12 2013, Felipe Balbi wrote:
> no SoB, cannot apply.

Sorry about that.

> I already had this patch in my tree but didn't send it.  I'm fine with
> using yours but I need SoB and commit log.

I don't mind either way as long as the code gets deleted. ;)

diff --git a/drivers/usb/phy/phy-am335x.c b/drivers/usb/phy/phy-am335x.c
index 6370e50..48d41ab 100644
--- a/drivers/usb/phy/phy-am335x.c
+++ b/drivers/usb/phy/phy-am335x.c
@@ -66,8 +66,6 @@ static int am335x_phy_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, am_phy);

return 0;
-
-   return ret;
 }

 static int am335x_phy_remove(struct platform_device *pdev)
diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c
index fce3a9e..db4fc22 100644
--- a/drivers/usb/phy/phy-generic.c
+++ b/drivers/usb/phy/phy-generic.c
@@ -271,8 +271,6 @@ static int usb_phy_gen_xceiv_probe(struct platform_device 
*pdev)
platform_set_drvdata(pdev, nop);

return 0;
-
-   return err;
 }

 static int usb_phy_gen_xceiv_remove(struct platform_device *pdev)
--
1.8.3.2
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH] usb: xhci: Link TRB must not occur with a USB payload burst.

2013-11-12 Thread Alan Stern
On Tue, 12 Nov 2013, David Laight wrote:

> > You're right.  I do wish the spec had been written more clearly.
> 
> I've read a lot of hardware specs in my time ...
> 
> > > Reading it all again makes me think that a LINK trb is only
> > > allowed on the burst boundary (which might be 16k bytes).
> > > The only real way to implement that is to ensure that TD never
> > > contain LINK TRB.
> > 
> > That's one way to do it.  Or you could allow a Link TRB at an
> > intermediate MBP boundary.
> 
> If all the fragments are larger than the MBP (assume 16k) then
> that would be relatively easy. However that is very dependant
> on the source of the data. It might be true for disk data, but
> is unlikely to be true for ethernet data.

I don't quite understand your point.  Are you saying that if all the 
TRBs are very short, you might need more than 64 TRBs to reach a 16-KB 
boundary?

> For bulk data the link TRB can be forced at a packet boundary
> by splitting the TD up - the receiving end won't know the difference.

That won't work.  What happens if you split a TD up into two pieces and 
the first piece receives a short packet?  The host controller will 
automatically move to the start of the second piece.  That's not what 
we want.

> > It comes down to a question of how often you want the controller to
> > issue an interrupt.  If a ring segment is 4 KB (one page), then it can
> > hold 256 TRBs.  With scatter-gather transfers, each SG element
> > typically refers to something like a 2-page buffer (depends on how
> > fragmented the memory is).  Therefore a ring segment will describe
> > somewhere around 512 pages of data, i.e., something like 2 MB.  Since
> > SuperSpeed is 500 MB/s, you'd end up getting in the vicinity of 250
> > interrupts every second just because of ring segment crossings.
> 
> 250 interrupts/sec is noise. Send/receive 13000 ethernet packets/sec
> and then look at the interrupt rate!
> 
> There is no necessity for taking an interrupt from every link segment.

Yes, there is.  The HCD needs to know when the dequeue pointer has
moved beyond the end of the ring segment, so that it can start reusing
the TRB slots in that segment.

Suppose you have queued a bulk URB because there weren't enough free 
TRB slots.  How else would you know when the occupied slots became 
available?

> The current ring segments contain 64 entries, a strange choice
> since they are created with 2 segments.
> (The ring expansion code soon doubles that for my ethernet traffic.)
> 
> I would change the code to use a single segment (for coding simplicity)
> and queue bulk URB when there isn't enough ring space.
> URB with too many fragments could either be rejected, sent in sections,
> or partially linearised (and probably still sent in sections).

Rejecting an URB is not feasible.  Splitting it up into multiple TDs is
not acceptable, as explained above.  Sending it in sections (i.e.,
queueing only some of the TRBs at any time) would work, provided you
got at least two interrupts every time the queue wrapped around (which
suggests you might want at least two ring segments).

Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] Revert "sierra_net: keep status interrupt URB active"

2013-11-12 Thread Dan Williams
On Fri, 2013-11-08 at 15:29 -0600, Dan Williams wrote:
> On Fri, 2013-11-08 at 21:44 +0100, Bjørn Mork wrote:
> > Dan Williams  writes:
> > > On Mon, 2013-11-04 at 14:27 -0600, Dan Williams wrote:
> > >> On Fri, 2013-11-01 at 13:53 +0100, Bjørn Mork wrote:
> > >> > This reverts commit 7b0c5f21f348a66de495868b8df0284e8dfd6bbf.
> > >> > 
> > >> > It's not easy to create a driver for all the various firmware
> > >> > bugs out there.
> > >> > 
> > >> > This change caused regressions for a number of devices, which
> > >> > started to fail link detection and therefore became completely
> > >> > non-functional. The exact reason is yet unknown, it looks like
> > >> > the affected firmwares might actually need all or some of the
> > >> > additional SYNC messages the patch got rid of.
> > >> > 
> > >> > Reverting is not optimal, as it will re-introduce the original
> > >> > problem, but it is currently the only alternative known to fix
> > >> > this issue.
> > >> 
> > >> Instead, how does the following patch work for you?
> > >
> > > Bjorn, did you have a chance to try this patch out on your devices?
> > 
> > The only DirectIP device I have is the MC7710, which never had any of
> > the firmware issues you are trying to fix. I only tried to forward Johns
> > issue.
> > 
> > When this patch worked for John, then I am pretty confident that you
> > have solved the problem here.
> 
> Well, "solved", since I still have no idea why the original patch would
> cause the device behavior based on what I know and have read about the
> expected firmware/host handshaking sequence.  But the patch there
> appears to fix the problem *and* not blindly send tons of SYNCs forever.
> 
> So I'll go ahead and submit a proper version of it.

Actually, is "[PATCH] usbnet: fix status interrupt urb handling" the
real fix for this problem?

John, any chance you could revert my RFC patch and try Felix's patch in
that mail?

Dan

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC 1/3] ohci: convert printk to dev_dbg

2013-11-12 Thread Alan Stern
On Tue, 12 Nov 2013 oli...@neukum.org wrote:

> From: Oliver Neukum 
> 
> This converts the DEBUG level printk to dynamic debugging

I would prefer to get rid of the urb_print() function entirely.  As far 
as I know, nobody has used it in years.

Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC 2/3] ohci: compile all debug stuff always

2013-11-12 Thread Alan Stern
On Tue, 12 Nov 2013 oli...@neukum.org wrote:

> From: Oliver Neukum 
> 
> There's no reason to leave out the debugfs files
> under normal conditions.
> 
> Signed-off-by: Oliver Neukum 
> ---
>  drivers/usb/host/ohci-dbg.c | 10 +-
>  1 file changed, 1 insertion(+), 9 deletions(-)

This patch should also get rid of the definition of STUB_DEBUG_FILES in
ohci.h and the corresponding test in ohci-dbg.c.  Otherwise you might
end up building all the code to populate the debugfs files but leaving
out the code to register them!

Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH] usb: xhci: Link TRB must not occur with a USB payload burst.

2013-11-12 Thread David Laight
> > If all the fragments are larger than the MBP (assume 16k) then
> > that would be relatively easy. However that is very dependant
> > on the source of the data. It might be true for disk data, but
> > is unlikely to be true for ethernet data.
> 
> I don't quite understand your point.  Are you saying that if all the
> TRBs are very short, you might need more than 64 TRBs to reach a 16-KB
> boundary?

Since you don't really want to do all the work twice, the sensible
way is to add each input fragment to the ring one a time.
If you need to cross a link TRB and the last MBP boundary is within
the previous data TRB then you can split the previous data TRB at the
MBP boundary and continue.
If the previous TRB is short then you'd need to go back through the
earlier TRB until you found the one that contains a TRB boundary,
split it, and write a link TRB in the following slot.
If you are within the first MBP then you'd need to replace the first
TRB of the message with a link TRB.

And yes, if the data is really fragmented you might need a lot of
TRB for even 1k of data.

> > For bulk data the link TRB can be forced at a packet boundary
> > by splitting the TD up - the receiving end won't know the difference.
> 
> That won't work.  What happens if you split a TD up into two pieces and
> the first piece receives a short packet?  The host controller will
> automatically move to the start of the second piece.  That's not what
> we want.

You can split a bulk TD on a 1k boundary and the target won't know the
difference.

> > There is no necessity for taking an interrupt from every link segment.
> 
> Yes, there is.  The HCD needs to know when the dequeue pointer has
> moved beyond the end of the ring segment, so that it can start reusing
> the TRB slots in that segment.

You already know that because of the interrupts for the data packets
themselves.

> > I would change the code to use a single segment (for coding simplicity)
> > and queue bulk URB when there isn't enough ring space.
> > URB with too many fragments could either be rejected, sent in sections,
> > or partially linearised (and probably still sent in sections).
> 
> Rejecting an URB is not feasible.  Splitting it up into multiple TDs is
> not acceptable, as explained above.  Sending it in sections (i.e.,
> queueing only some of the TRBs at any time) would work, provided you
> got at least two interrupts every time the queue wrapped around (which
> suggests you might want at least two ring segments).

Rejecting badly fragmented URB is almost certainly ok. You really don't
want the hardware overhead of processing a TRB every few bytes.
This would be especially bad on iommu systems.
Before the ring expansion code was added there was an implicit
limit of (probably) 125 fragments for a URB. Exceeding this limit
wasn't the reason for adding the ring expansion code.

And, as I've pointed out, both bulk and isoc URB can be split unless
they are using too many fragments for a short piece of data.

The current code refuses to write into a TRB segment until it is
empty - I think that restriction is only there so that it can
add another segment when the space runs out.

David





--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC 3/3] ohci: rewrite ohci_dump() for dynamic debug

2013-11-12 Thread Alan Stern
On Tue, 12 Nov 2013 oli...@neukum.org wrote:

> From: Oliver Neukum 
> 
> As this function is called from interrupt care must
> be taken that as little as possible overhead is used
> if dynamic debbuging is not enabled.

Firstly, the function is called in interrupt context only when an 
Unrecoverable Error occurs.  I think we can afford a little extra 
overhead in that case.

Secondly, this patch creates a duplicate copy of ohci_dump_status(), 
which is a rather lengthy debugging function.  This is hardly elegant.

Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] usb: xhci: Link TRB must not occur with a USB payload burst.

2013-11-12 Thread Sarah Sharp
On Mon, Nov 11, 2013 at 03:34:53PM -0500, Alan Stern wrote:
> On Mon, 11 Nov 2013, David Laight wrote:
> 
> > > Suppose, for example, the MBP is 1024.  If you have a TD with length
> > > 1500, and if it had only one fragment, the last (and only) fragment's
> > > length would not less than the MBP and it would not be an exact
> > > multiple of the MBP.
> > 
> > That doesn't matter - eg example 2 in figure 25
> 
> You're right.  I do wish the spec had been written more clearly.
> 
> > Reading it all again makes me think that a LINK trb is only
> > allowed on the burst boundary (which might be 16k bytes).
> > The only real way to implement that is to ensure that TD never
> > contain LINK TRB.
> 
> That's one way to do it.  Or you could allow a Link TRB at an 
> intermediate MBP boundary.

I like this idea instead.  The xHCI driver should be modified to be able
to handle link TRBs in the middle of the segments (the cancellation code
would have to be touched as well).  We would keep a running count
of the number of bytes left in a TD fragment, as we fill in the TRBs.
If we find the TD fragment would span a link TRB, we backtrack to the
end of the last TD fragment, put in a link TRB, and then continue on the
next segment.

> It comes down to a question of how often you want the controller to
> issue an interrupt.  If a ring segment is 4 KB (one page), then it can
> hold 256 TRBs.  With scatter-gather transfers, each SG element
> typically refers to something like a 2-page buffer (depends on how
> fragmented the memory is).  Therefore a ring segment will describe
> somewhere around 512 pages of data, i.e., something like 2 MB.  Since
> SuperSpeed is 500 MB/s, you'd end up getting in the vicinity of 250
> interrupts every second just because of ring segment crossings.

The driver is currently defined to have 64 TRBs per ring segment.  But
that doesn't matter; we don't get an interrupt when a ring segment is
crossed.  Instead we set the interrupt-on-completion flag on the last
TRB of the TD, not on any earlier fragment or link TRB.

> Using larger ring segments would help.

Ring segments have to be physically contiguous, so I'm not sure if we
want to ask for segments that are bigger than a page.  I've already got
a report from someone else about the ring expansion getting out of
control, so I would like to figure that out before we talk about using
even bigger segments.

Finally, it's interesting to note that the USB mass storage driver is
using scatter gather lists just fine without the driver following the TD
fragment rules.  Or at least no one has reported any issues.  I wonder
why it works?

Sarah Sharp
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] usb: xhci: Link TRB must not occur with a USB payload burst.

2013-11-12 Thread Sarah Sharp
On Fri, Nov 08, 2013 at 11:07:41AM -, David Laight wrote:
> > While this change improves things a lot (it runs for 20 minutes rather than
> > a few seconds), there is still something else wrong.
> 
> Almost certainly caused by an unrelated local change.

Ok, good, I was concerned there was another issue we were missing.

Sarah Sharp
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: huawei_cdc_ncm driver

2013-11-12 Thread Thomas Schäfer



> If that still does not change anything, then I'd really appreciate it if
> you could run through (assuming the v3.11 driver was OK):
> 
>   git bisect start 9fea037de5f3 v3.11 -- drivers/net/usb/cdc_ncm.c
> 

That failed too. 
(switching was ok, compiling was ok, booting, recognizing the devices ok, but 
dhcp / RA not ok)
So problem seems to be somewhere but not in you driver.

Thomas


--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Pull Request] xhci: Bug fixes, now with more tags!

2013-11-12 Thread Sarah Sharp
On Mon, Nov 11, 2013 at 11:27:13AM +0100, Vincent Thiele wrote:
> This Bug is still not completely solved (Ubuntu 13.10 newest kernel 3.11)

Have you tried compiling 3.12 instead?  I don't have any control over
when Ubuntu picks up bug fixes for their kernel.

> Syslog:
> Nov 2 18:44:29 Arbeits-PC whoopsie[961]: online
> Nov 2 18:45:41 whoopsie[961]: last message repeated 2 times
> Nov 2 18:56:27 Arbeits-PC kernel: [ 8411.030685] usb 3-2: USB
> disconnect, device number 21
> Nov 2 18:56:27 Arbeits-PC colord: device removed: sysfs-LGE-Nexus_4
> Nov 2 18:56:28 Arbeits-PC kernel: [ 8412.253950] usb 3-2: new
> high-speed USB device number 25 using xhci_hcd
> Nov 2 18:56:28 Arbeits-PC kernel: [ 8412.270843] usb 3-2: New USB
> device found, idVendor=18d1, idProduct=4ee1
> Nov 2 18:56:28 Arbeits-PC kernel: [ 8412.270848] usb 3-2: New USB
> device strings: Mfr=1, Product=2, SerialNumber=3
> Nov 2 18:56:28 Arbeits-PC kernel: [ 8412.270851] usb 3-2: Product: Nexus 4
> Nov 2 18:56:28 Arbeits-PC kernel: [ 8412.270854] usb 3-2: Manufacturer: LGE
> Nov 2 18:56:28 Arbeits-PC kernel: [ 8412.270856] usb 3-2:
> SerialNumber: 00294807ce91f316
> Nov 2 18:56:28 Arbeits-PC colord: Device added: sysfs-LGE-Nexus_4
> Nov 2 18:56:28 Arbeits-PC dbus[651]: [system] Activating service
> name='org.freedesktop.hostname1' (using servicehelper)
> Nov 2 18:56:28 Arbeits-PC dbus[651]: [system] Successfully activated
> service 'org.freedesktop.hostname1'
> Nov 2 18:56:28 Arbeits-PC kernel: [ 8412.451541] usb 3-2: USB
> disconnect, device number 25
> Nov 2 18:56:28 Arbeits-PC colord: device removed: sysfs-LGE-Nexus_4
> Nov 2 18:56:29 Arbeits-PC kernel: [ 8413.735802] usb 3-2: new
> high-speed USB device number 30 using xhci_hcd
> Nov 2 18:56:45 Arbeits-PC kernel: [ 8418.728670] xhci_hcd
> :03:00.0: Timeout while waiting for address device command
> Nov 2 18:56:45 Arbeits-PC kernel: [ 8429.521172] [sched_delayed]
> sched: RT throttling activated
> Nov 2 18:56:45 Arbeits-PC rtkit-daemon[1321]: The canary thread is
> apparently starving. Taking action.
> Nov 2 18:56:45 Arbeits-PC rtkit-daemon[1321]: Demoting known real-time 
> threads.
> Nov 2 18:56:45 Arbeits-PC rtkit-daemon[1321]: Successfully demoted
> thread 2186 of process 2142 (n/a).
> Nov 2 18:56:45 Arbeits-PC rtkit-daemon[1321]: Successfully demoted
> thread 2185 of process 2142 (n/a).
> Nov 2 18:56:45 Arbeits-PC rtkit-daemon[1321]: Successfully demoted
> thread 2184 of process 2142 (n/a).
> Nov 2 18:56:45 Arbeits-PC rtkit-daemon[1321]: Successfully demoted
> thread 2142 of process 2142 (n/a).
> Nov 2 18:56:45 Arbeits-PC rtkit-daemon[1321]: Demoted 4 threads.
> Nov 2 18:56:45 Arbeits-PC kernel: [ 8429.720909] usb 3-2: Device not
> responding to set address.
> Nov 2 18:56:45 Arbeits-PC kernel: [ 8429.924616] usb 3-2: device not
> accepting address 30, error -71
> Nov 2 18:57:05 Arbeits-PC kernel: [ 8434.917500] xhci_hcd
> :03:00.0: Timeout while waiting for a slot
> Nov 2 18:57:05 Arbeits-PC kernel: [ 8449.102462] xhci_hcd
> :03:00.0: Stopped the command ring failed, maybe the host is dead
> Nov 2 18:57:05 Arbeits-PC kernel: [ 8449.102479] xhci_hcd
> :03:00.0: Abort command ring failed
> Nov 2 18:57:05 Arbeits-PC kernel: [ 8449.102677] xhci_hcd
> :03:00.0: HC died; cleaning up
> Nov 2 18:57:05 Arbeits-PC kernel: [ 8449.104659] xHCI xhci_free_dev
> called with unaddressed device
> Nov 2 18:57:10 Arbeits-PC kernel: [ 8454.094047] xhci_hcd
> :03:00.0: Timeout while waiting for a slot
> Nov 2 18:57:10 Arbeits-PC kernel: [ 8454.094051] xhci_hcd
> :03:00.0: Abort the command ring, but the xHCI is dead.
> Nov 2 18:57:10 Arbeits-PC kernel: [ 8454.094060] xHCI xhci_free_dev
> called with unaddressed device
> Nov 2 18:57:15 Arbeits-PC kernel: [ 8459.086911] xhci_hcd
> :03:00.0: Timeout while waiting for a slot
> Nov 2 18:57:15 Arbeits-PC kernel: [ 8459.086917] xhci_hcd
> :03:00.0: Abort the command ring, but the xHCI is dead.
> Nov 2 18:57:15 Arbeits-PC kernel: [ 8459.086930] xHCI xhci_free_dev
> called with unaddressed device
> Nov 2 18:57:15 Arbeits-PC kernel: [ 8459.086940] usb 3-1: USB
> disconnect, device number 2
> Nov 2 18:57:15 Arbeits-PC udisksd[2260]: Cleaning up mount point
> /media/vincent/Elements (device 8:33 no longer exist)
> Nov 2 18:57:15 Arbeits-PC ntfs-3g[2477]: Unmounting /dev/sdc1 (Elements)
> Short system hang with looping audio after that every usb-device which
> is connected with this usb-controller is disconnected until i reboot
> the system.
> 
> 2013/11/3 Vincent Thiele :
> > This Bug is still not completely solved (Ubuntu 13.10 newest kernel 3.11)
> > Syslog:
> > Nov 2 18:44:29 Arbeits-PC whoopsie[961]: online
> > Nov 2 18:45:41 whoopsie[961]: last message repeated 2 times
> > Nov 2 18:56:27 Arbeits-PC kernel: [ 8411.030685] usb 3-2: USB
> > disconnect, device number 21
> > Nov 2 18:56:27 Arbeits-PC colord: device removed: sysfs-LGE-Nexus_4
> > Nov 2 18:56:28 Arbeits-PC kernel: [ 8412.253950] usb 3-2: new
> > high-speed USB device num

RE: [PATCH] usb: xhci: Link TRB must not occur with a USB payload burst.

2013-11-12 Thread David Laight
> On Fri, Nov 08, 2013 at 11:07:41AM -, David Laight wrote:
> > > While this change improves things a lot (it runs for 20 minutes rather 
> > > than
> > > a few seconds), there is still something else wrong.
> >
> > Almost certainly caused by an unrelated local change.
> 
> Ok, good, I was concerned there was another issue we were missing.

My modified code wasn't setting the td_size properly.
That is fixed and verified in the later patch I sent.

David



--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] Revert "sierra_net: keep status interrupt URB active"

2013-11-12 Thread Dan Williams
On Tue, 2013-11-12 at 10:25 -0600, Dan Williams wrote:
> On Fri, 2013-11-08 at 15:29 -0600, Dan Williams wrote:
> > On Fri, 2013-11-08 at 21:44 +0100, Bjørn Mork wrote:
> > > Dan Williams  writes:
> > > > On Mon, 2013-11-04 at 14:27 -0600, Dan Williams wrote:
> > > >> On Fri, 2013-11-01 at 13:53 +0100, Bjørn Mork wrote:
> > > >> > This reverts commit 7b0c5f21f348a66de495868b8df0284e8dfd6bbf.
> > > >> > 
> > > >> > It's not easy to create a driver for all the various firmware
> > > >> > bugs out there.
> > > >> > 
> > > >> > This change caused regressions for a number of devices, which
> > > >> > started to fail link detection and therefore became completely
> > > >> > non-functional. The exact reason is yet unknown, it looks like
> > > >> > the affected firmwares might actually need all or some of the
> > > >> > additional SYNC messages the patch got rid of.
> > > >> > 
> > > >> > Reverting is not optimal, as it will re-introduce the original
> > > >> > problem, but it is currently the only alternative known to fix
> > > >> > this issue.
> > > >> 
> > > >> Instead, how does the following patch work for you?
> > > >
> > > > Bjorn, did you have a chance to try this patch out on your devices?
> > > 
> > > The only DirectIP device I have is the MC7710, which never had any of
> > > the firmware issues you are trying to fix. I only tried to forward Johns
> > > issue.
> > > 
> > > When this patch worked for John, then I am pretty confident that you
> > > have solved the problem here.
> > 
> > Well, "solved", since I still have no idea why the original patch would
> > cause the device behavior based on what I know and have read about the
> > expected firmware/host handshaking sequence.  But the patch there
> > appears to fix the problem *and* not blindly send tons of SYNCs forever.
> > 
> > So I'll go ahead and submit a proper version of it.
> 
> Actually, is "[PATCH] usbnet: fix status interrupt urb handling" the
> real fix for this problem?
> 
> John, any chance you could revert my RFC patch and try Felix's patch in
> that mail?

It fixes the problem for me without requiring the revert or my RFC
patch

Dan

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH] usb: xhci: Link TRB must not occur with a USB payload burst.

2013-11-12 Thread David Laight
> > That's one way to do it.  Or you could allow a Link TRB at an
> > intermediate MBP boundary.
> 
> I like this idea instead.  The xHCI driver should be modified to be able
> to handle link TRBs in the middle of the segments (the cancellation code
> would have to be touched as well).  We would keep a running count
> of the number of bytes left in a TD fragment, as we fill in the TRBs.
> If we find the TD fragment would span a link TRB, we backtrack to the
> end of the last TD fragment, put in a link TRB, and then continue on the
> next segment.

I'd do that as a later change.
It needs a fair amount of other stuff fixing first and the current
code is rather broken - and needs a fix for stable.

> > It comes down to a question of how often you want the controller to
> > issue an interrupt.  If a ring segment is 4 KB (one page), then it can
> > hold 256 TRBs.  With scatter-gather transfers, each SG element
> > typically refers to something like a 2-page buffer (depends on how
> > fragmented the memory is).  Therefore a ring segment will describe
> > somewhere around 512 pages of data, i.e., something like 2 MB.  Since
> > SuperSpeed is 500 MB/s, you'd end up getting in the vicinity of 250
> > interrupts every second just because of ring segment crossings.
> 
> The driver is currently defined to have 64 TRBs per ring segment.  But
> that doesn't matter; we don't get an interrupt when a ring segment is
> crossed.  Instead we set the interrupt-on-completion flag on the last
> TRB of the TD, not on any earlier fragment or link TRB.
> 
> > Using larger ring segments would help.
> 
> Ring segments have to be physically contiguous, so I'm not sure if we
> want to ask for segments that are bigger than a page.  I've already got
> a report from someone else about the ring expansion getting out of
> control, so I would like to figure that out before we talk about using
> even bigger segments.

I'd vote for a single segment containing either 128 or 256 TRBs.
That is less than a single page.

> Finally, it's interesting to note that the USB mass storage driver is
> using scatter gather lists just fine without the driver following the TD
> fragment rules.  Or at least no one has reported any issues.  I wonder
> why it works?

I suspect that breaking the rules just generates two TD.
The mass storage driver is probably almost always presenting
buffer fragments that are page sized and page aligned.
In which case the split is invisible at the target.

David



--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] usbnet: fix status interrupt urb handling

2013-11-12 Thread Dan Williams
On Tue, 2013-11-12 at 16:34 +0100, Felix Fietkau wrote:
> Since commit 7b0c5f21f348a66de495868b8df0284e8dfd6bbf
> "sierra_net: keep status interrupt URB active", sierra_net triggers
> status interrupt polling before the net_device is opened (in order to
> properly receive the sync message response).
> 
> To be able to receive further interrupts, the interrupt urb needs to be
> re-submitted, so this patch removes the bogus check for netif_running().
> 
> Cc: sta...@vger.kernel.org
> Signed-off-by: Felix Fietkau 

Tested-by: Dan Williams 

> ---
>  drivers/net/usb/usbnet.c | 3 ---
>  1 file changed, 3 deletions(-)
> 
> diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
> index 90a429b..8494bb5 100644
> --- a/drivers/net/usb/usbnet.c
> +++ b/drivers/net/usb/usbnet.c
> @@ -204,9 +204,6 @@ static void intr_complete (struct urb *urb)
>   break;
>   }
>  
> - if (!netif_running (dev->net))
> - return;
> -
>   status = usb_submit_urb (urb, GFP_ATOMIC);
>   if (status != 0)
>   netif_err(dev, timer, dev->net,


--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 2/4] usb: usbtest: support usb2 extension descriptor test

2013-11-12 Thread Sarah Sharp
On Mon, Oct 28, 2013 at 11:31:33PM +0800, Huang Rui wrote:
> In Test 9 of usbtest module, it is used for performing chapter 9 tests N
> times.
> 
> USB2.0 Extension descriptor is one of the generic device-level capbility
> descriptors which added in section 9.6.2.1 of USB 3.0 spec.
> 
> This patch adds to support getting usb2.0 extension descriptor test
> scenario for USB 3.0.

Why not check the USB 2.0 extension BOS descriptor for USB 2.1 devices
as well?  Just change you check to be bcdUSB >= 0x0210.  You would have
to make sure you fail a USB 2.1 device with a the USB 3.0 BOS extension
descriptor or the Container ID BOS extension.

More comments below.

> Signed-off-by: Huang Rui 
> ---
>  drivers/usb/misc/usbtest.c | 77 
> ++
>  1 file changed, 77 insertions(+)
> 
> diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
> index 38ebe1d..d9ac215 100644
> --- a/drivers/usb/misc/usbtest.c
> +++ b/drivers/usb/misc/usbtest.c
> @@ -606,6 +606,28 @@ static int is_good_config(struct usbtest_dev *tdev, int 
> len)
>   return 0;
>  }
>  
> +static int is_good_ext(struct usbtest_dev *tdev, char *buf)
> +{
> + struct usb_ext_cap_descriptor *ext;
> + u32 attr;
> +
> + ext = (struct usb_ext_cap_descriptor *) buf;
> +
> + if (ext->bLength != USB_DT_USB_EXT_CAP_SIZE) {
> + ERROR(tdev, "bogus usb 2.0 extension descriptor length\n");
> + return 0;
> + }
> +
> + attr = le32_to_cpu(ext->bmAttributes);
> + /* bits[1:4] is used and others are reserved */
> + if (attr & ~0x1e) { /* reserved == 0 */
> + ERROR(tdev, "reserved bits set\n");
> + return 0;
> + }

New errata for USB 2.1 Link PM that adds support for the BESL and DBESL
encoding uses bits[1:15].  See the "USB2-LPM-Errata-final.pdf" file in
the latest download of the USB 2.0 spec.  This code should be fixed to
reflect those changes (bitmask should be 0xfffe rather than 0x1e).

> +
> + return 1;
> +}
> +
>  /* sanity test for standard requests working with usb_control_mesg() and some
>   * of the utility functions which use it.
>   *
> @@ -694,12 +716,67 @@ static int ch9_postconfig(struct usbtest_dev *dev)
>* 3.0 spec
>*/
>   if (le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0300) {
> + struct usb_bos_descriptor *bos = NULL;
> + struct usb_dev_cap_header *header = NULL;
> + unsigned total, num, length;
> + char *buf;
> +
>   retval = usb_get_descriptor(udev, USB_DT_BOS, 0, dev->buf,
>   sizeof(*udev->bos->desc));
>   if (retval != sizeof(*udev->bos->desc)) {
>   dev_err(&iface->dev, "bos descriptor --> %d\n", retval);
>   return (retval < 0) ? retval : -EDOM;
>   }
> +
> + bos = (struct usb_bos_descriptor *)dev->buf;
> + total = le16_to_cpu(bos->wTotalLength);
> + num = bos->bNumDeviceCaps;
> +
> + if (total > TBUF_SIZE)
> + total = TBUF_SIZE;
> +
> + /*
> +  * get generic device-level capability descriptors [9.6.2]
> +  * in USB 3.0 spec
> +  */
> + retval = usb_get_descriptor(udev, USB_DT_BOS, 0, dev->buf,
> + total);
> + if (retval != total) {
> + dev_err(&iface->dev, "bos descriptor set --> %d\n",
> + retval);
> + return (retval < 0) ? retval : -EDOM;
> + }
> +
> + length = sizeof(*udev->bos->desc);
> + buf = (char *)dev->buf;
> + for (i = 0; i < num; i++) {
> + buf += length;
> + if (buf + sizeof(struct usb_dev_cap_header) >
> + dev->buf + total)
> + break;
> +
> + header = (struct usb_dev_cap_header *)buf;
> + length = header->bLength;
> +
> + if (header->bDescriptorType !=
> + USB_DT_DEVICE_CAPABILITY) {
> + dev_warn(&udev->dev, "not device capability 
> descriptor, skip\n");
> + continue;
> + }
> +
> + switch (header->bDevCapabilityType) {
> + case USB_CAP_TYPE_EXT:
> + if (buf + USB_DT_USB_EXT_CAP_SIZE >
> + dev->buf + total ||
> + !is_good_ext(dev, buf)) {
> + dev_err(&iface->dev, "bogus usb 2.0 
> extension descriptor\n");
> + return -EDOM;
> + }
> + break;
> + default:
> +

Re: [PATCH v4 2/4] usb: usbtest: support usb2 extension descriptor test

2013-11-12 Thread Sarah Sharp
On Wed, Oct 30, 2013 at 11:27:38AM +0800, Huang Rui wrote:
> In Test 9 of usbtest module, it is used for performing chapter 9 tests N
> times.
> 
> USB2.0 Extension descriptor is one of the generic device-level capbility
> descriptors which added in section 9.6.2.1 of USB 3.0 spec.
> 
> This patch adds to support getting usb2.0 extension descriptor test
> scenario for USB 3.0.

I accidentally replied to the last patch revision, but my comments are
still true for this revision.  You need to:
 - Also check USB 2.1 devices for the USB 2.0 extension BOS descriptor
 - Change the bit mask check on bmAttributes to be 0xFFFE rather than
   0x1e.

Sarah Sharp

> 
> Signed-off-by: Huang Rui 
> Acked-by: Alan Stern 
> ---
>  drivers/usb/misc/usbtest.c | 77 
> ++
>  1 file changed, 77 insertions(+)
> 
> diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
> index 38ebe1d..84d491d 100644
> --- a/drivers/usb/misc/usbtest.c
> +++ b/drivers/usb/misc/usbtest.c
> @@ -606,6 +606,28 @@ static int is_good_config(struct usbtest_dev *tdev, int 
> len)
>   return 0;
>  }
>  
> +static int is_good_ext(struct usbtest_dev *tdev, u8 *buf)
> +{
> + struct usb_ext_cap_descriptor *ext;
> + u32 attr;
> +
> + ext = (struct usb_ext_cap_descriptor *) buf;
> +
> + if (ext->bLength != USB_DT_USB_EXT_CAP_SIZE) {
> + ERROR(tdev, "bogus usb 2.0 extension descriptor length\n");
> + return 0;
> + }
> +
> + attr = le32_to_cpu(ext->bmAttributes);
> + /* bits[1:4] is used and others are reserved */
> + if (attr & ~0x1e) { /* reserved == 0 */
> + ERROR(tdev, "reserved bits set\n");
> + return 0;
> + }
> +
> + return 1;
> +}
> +
>  /* sanity test for standard requests working with usb_control_mesg() and some
>   * of the utility functions which use it.
>   *
> @@ -694,12 +716,67 @@ static int ch9_postconfig(struct usbtest_dev *dev)
>* 3.0 spec
>*/
>   if (le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0300) {
> + struct usb_bos_descriptor *bos = NULL;
> + struct usb_dev_cap_header *header = NULL;
> + unsigned total, num, length;
> + u8 *buf;
> +
>   retval = usb_get_descriptor(udev, USB_DT_BOS, 0, dev->buf,
>   sizeof(*udev->bos->desc));
>   if (retval != sizeof(*udev->bos->desc)) {
>   dev_err(&iface->dev, "bos descriptor --> %d\n", retval);
>   return (retval < 0) ? retval : -EDOM;
>   }
> +
> + bos = (struct usb_bos_descriptor *)dev->buf;
> + total = le16_to_cpu(bos->wTotalLength);
> + num = bos->bNumDeviceCaps;
> +
> + if (total > TBUF_SIZE)
> + total = TBUF_SIZE;
> +
> + /*
> +  * get generic device-level capability descriptors [9.6.2]
> +  * in USB 3.0 spec
> +  */
> + retval = usb_get_descriptor(udev, USB_DT_BOS, 0, dev->buf,
> + total);
> + if (retval != total) {
> + dev_err(&iface->dev, "bos descriptor set --> %d\n",
> + retval);
> + return (retval < 0) ? retval : -EDOM;
> + }
> +
> + length = sizeof(*udev->bos->desc);
> + buf = dev->buf;
> + for (i = 0; i < num; i++) {
> + buf += length;
> + if (buf + sizeof(struct usb_dev_cap_header) >
> + dev->buf + total)
> + break;
> +
> + header = (struct usb_dev_cap_header *)buf;
> + length = header->bLength;
> +
> + if (header->bDescriptorType !=
> + USB_DT_DEVICE_CAPABILITY) {
> + dev_warn(&udev->dev, "not device capability 
> descriptor, skip\n");
> + continue;
> + }
> +
> + switch (header->bDevCapabilityType) {
> + case USB_CAP_TYPE_EXT:
> + if (buf + USB_DT_USB_EXT_CAP_SIZE >
> + dev->buf + total ||
> + !is_good_ext(dev, buf)) {
> + dev_err(&iface->dev, "bogus usb 2.0 
> extension descriptor\n");
> + return -EDOM;
> + }
> + break;
> + default:
> + break;
> + }
> + }
>   }
>  
>   /* there's always [9.4.3] at least one config descriptor [9.6.3] */
> -- 
> 1.7.11.7
> 
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a mes

Re: [PATCH v4 2/4] usb: usbtest: support usb2 extension descriptor test

2013-11-12 Thread Sarah Sharp
On Tue, Nov 12, 2013 at 09:59:13AM -0800, Sarah Sharp wrote:
> On Wed, Oct 30, 2013 at 11:27:38AM +0800, Huang Rui wrote:
> > In Test 9 of usbtest module, it is used for performing chapter 9 tests N
> > times.
> > 
> > USB2.0 Extension descriptor is one of the generic device-level capbility
> > descriptors which added in section 9.6.2.1 of USB 3.0 spec.
> > 
> > This patch adds to support getting usb2.0 extension descriptor test
> > scenario for USB 3.0.
> 
> I accidentally replied to the last patch revision, but my comments are
> still true for this revision.  You need to:
>  - Also check USB 2.1 devices for the USB 2.0 extension BOS descriptor
>  - Change the bit mask check on bmAttributes to be 0xFFFE rather than
>0x1e.

Since it looks like Greg already has this patch in usb-next, can you
send a bug fix patch to fix the bit mask?

Thanks,
Sarah Sharp

> > Signed-off-by: Huang Rui 
> > Acked-by: Alan Stern 
> > ---
> >  drivers/usb/misc/usbtest.c | 77 
> > ++
> >  1 file changed, 77 insertions(+)
> > 
> > diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
> > index 38ebe1d..84d491d 100644
> > --- a/drivers/usb/misc/usbtest.c
> > +++ b/drivers/usb/misc/usbtest.c
> > @@ -606,6 +606,28 @@ static int is_good_config(struct usbtest_dev *tdev, 
> > int len)
> > return 0;
> >  }
> >  
> > +static int is_good_ext(struct usbtest_dev *tdev, u8 *buf)
> > +{
> > +   struct usb_ext_cap_descriptor *ext;
> > +   u32 attr;
> > +
> > +   ext = (struct usb_ext_cap_descriptor *) buf;
> > +
> > +   if (ext->bLength != USB_DT_USB_EXT_CAP_SIZE) {
> > +   ERROR(tdev, "bogus usb 2.0 extension descriptor length\n");
> > +   return 0;
> > +   }
> > +
> > +   attr = le32_to_cpu(ext->bmAttributes);
> > +   /* bits[1:4] is used and others are reserved */
> > +   if (attr & ~0x1e) { /* reserved == 0 */
> > +   ERROR(tdev, "reserved bits set\n");
> > +   return 0;
> > +   }
> > +
> > +   return 1;
> > +}
> > +
> >  /* sanity test for standard requests working with usb_control_mesg() and 
> > some
> >   * of the utility functions which use it.
> >   *
> > @@ -694,12 +716,67 @@ static int ch9_postconfig(struct usbtest_dev *dev)
> >  * 3.0 spec
> >  */
> > if (le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0300) {
> > +   struct usb_bos_descriptor *bos = NULL;
> > +   struct usb_dev_cap_header *header = NULL;
> > +   unsigned total, num, length;
> > +   u8 *buf;
> > +
> > retval = usb_get_descriptor(udev, USB_DT_BOS, 0, dev->buf,
> > sizeof(*udev->bos->desc));
> > if (retval != sizeof(*udev->bos->desc)) {
> > dev_err(&iface->dev, "bos descriptor --> %d\n", retval);
> > return (retval < 0) ? retval : -EDOM;
> > }
> > +
> > +   bos = (struct usb_bos_descriptor *)dev->buf;
> > +   total = le16_to_cpu(bos->wTotalLength);
> > +   num = bos->bNumDeviceCaps;
> > +
> > +   if (total > TBUF_SIZE)
> > +   total = TBUF_SIZE;
> > +
> > +   /*
> > +* get generic device-level capability descriptors [9.6.2]
> > +* in USB 3.0 spec
> > +*/
> > +   retval = usb_get_descriptor(udev, USB_DT_BOS, 0, dev->buf,
> > +   total);
> > +   if (retval != total) {
> > +   dev_err(&iface->dev, "bos descriptor set --> %d\n",
> > +   retval);
> > +   return (retval < 0) ? retval : -EDOM;
> > +   }
> > +
> > +   length = sizeof(*udev->bos->desc);
> > +   buf = dev->buf;
> > +   for (i = 0; i < num; i++) {
> > +   buf += length;
> > +   if (buf + sizeof(struct usb_dev_cap_header) >
> > +   dev->buf + total)
> > +   break;
> > +
> > +   header = (struct usb_dev_cap_header *)buf;
> > +   length = header->bLength;
> > +
> > +   if (header->bDescriptorType !=
> > +   USB_DT_DEVICE_CAPABILITY) {
> > +   dev_warn(&udev->dev, "not device capability 
> > descriptor, skip\n");
> > +   continue;
> > +   }
> > +
> > +   switch (header->bDevCapabilityType) {
> > +   case USB_CAP_TYPE_EXT:
> > +   if (buf + USB_DT_USB_EXT_CAP_SIZE >
> > +   dev->buf + total ||
> > +   !is_good_ext(dev, buf)) {
> > +   dev_err(&iface->dev, "bogus usb 2.0 
> > extension descriptor\n");
> > +   return -EDOM;
> > +   }
> > +   break;
> > +   default:
>

Re: [PATCHv2 2/2] check quirk to pad epout buf size when not aligned to maxpacketsize

2013-11-12 Thread David Cohen
 IIUC, req->length should still be set to len, not to data_len.
>>
>> I misunderstood the first time I read it:
>> In order to avoid DWC3 to stall, we need to update req->length (this is
>> the most important fix). kmalloc() is updated too to prevent USB
>> controller to overflow buffer boundaries.
> 
> Here I disagree.
> 
> If the DWC3 hardware stalls, it is up to the DWC3 UDC driver to fix it.  
> Gadget drivers should not have to worry.  Most especially, gadget 
> drivers should not lie about a request length.
> 
> If the UDC driver decides to round up req->length before sending it to
> the hardware, that's okay.  But req->length should be set to len, not
> data_len.  And if the hardware receives more than len bytes of data,
> the UDC driver should set req->status to -EOVERFLOW.

Got your point. As long as buffer allocation has enough size, DWC3 is
able to fix itself. I'm fine with this approach too. But in this case I
will need to redo my DWC3 patch and my validation.

Br, David

> 
> Alan Stern
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 01/15] usb: phy: msm: Move mach dependent code to platform data

2013-11-12 Thread Christopher Covington
Hi Ivan,

On 11/12/2013 09:51 AM, Ivan T. Ivanov wrote:
> From: "Ivan T. Ivanov" 
> 
> This patch fix compilation error when driver is compiled
> in multi-platform builds.
> 
> drivers/built-in.o: In function `msm_otg_link_clk_reset':
> ./drivers/usb/phy/phy-msm-usb.c:314: undefined reference to `clk_reset'
> ./drivers/usb/phy/phy-msm-usb.c:318: undefined reference to `clk_reset'
> 
> Use platform data supplied reset handlers and adjust error
> messages reported when reset sequence fail.
> 
> This is an intermediate step before adding support for reset
> framework and newer targets.
> 
> Signed-off-by: Ivan T. Ivanov 
> Acked-by: David Brown 
> Cc: Daniel Walker 
> Cc: Felipe Balbi 
> Cc: Greg Kroah-Hartman 
> ---
>  arch/arm/mach-msm/board-msm7x30.c |   35 +++
>  arch/arm/mach-msm/board-qsd8x50.c |   35 +++
>  drivers/usb/phy/phy-msm-usb.c |   35 +++
>  include/linux/usb/msm_hsusb.h |3 +++
>  4 files changed, 88 insertions(+), 20 deletions(-)
> 
> diff --git a/arch/arm/mach-msm/board-msm7x30.c 
> b/arch/arm/mach-msm/board-msm7x30.c
> index f9af5a4..46de789 100644
> --- a/arch/arm/mach-msm/board-msm7x30.c
> +++ b/arch/arm/mach-msm/board-msm7x30.c
> @@ -30,6 +30,7 @@
>  #include 
>  #include 
>  
> +#include 
>  #include 
>  #include 
>  
> @@ -60,10 +61,44 @@ static int hsusb_phy_init_seq[] = {
>   -1
>  };
>  
> +static int hsusb_link_clk_reset(struct clk *link_clk, bool assert)
> +{
> + int ret;
> +
> + if (assert) {
> + ret = clk_reset(link_clk, CLK_RESET_ASSERT);
> + if (ret)
> + pr_err("usb hs_clk assert failed\n");
> + } else {
> + ret = clk_reset(link_clk, CLK_RESET_DEASSERT);
> + if (ret)
> + pr_err("usb hs_clk deassert failed\n");
> + }
> + return ret;
> +}
> +
> +static int hsusb_phy_clk_reset(struct clk *phy_clk)
> +{
> + int ret;
> +
> + ret = clk_reset(phy_clk, CLK_RESET_ASSERT);
> + if (ret) {
> + pr_err("usb phy clk assert failed\n");
> + return ret;
> + }
> + usleep_range(1, 12000);
> + ret = clk_reset(phy_clk, CLK_RESET_DEASSERT);
> + if (ret)
> + pr_err("usb phy clk deassert failed\n");
> + return ret;
> +}
> +
>  static struct msm_otg_platform_data msm_otg_pdata = {
>   .phy_init_seq   = hsusb_phy_init_seq,
>   .mode   = USB_PERIPHERAL,
>   .otg_control= OTG_PHY_CONTROL,
> + .link_clk_reset = hsusb_link_clk_reset,
> + .phy_clk_reset  = hsusb_phy_clk_reset,
>  };
>  
>  struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = {
> diff --git a/arch/arm/mach-msm/board-qsd8x50.c 
> b/arch/arm/mach-msm/board-qsd8x50.c
> index 5f933bc..9169ec3 100644
> --- a/arch/arm/mach-msm/board-qsd8x50.c
> +++ b/arch/arm/mach-msm/board-qsd8x50.c
> @@ -31,6 +31,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  
>  #include "devices.h"
> @@ -81,10 +82,44 @@ static int hsusb_phy_init_seq[] = {
>   -1
>  };
>  
> +static int hsusb_link_clk_reset(struct clk *link_clk, bool assert)
> +{
> + int ret;
> +
> + if (assert) {
> + ret = clk_reset(link_clk, CLK_RESET_ASSERT);
> + if (ret)
> + pr_err("usb hs_clk assert failed\n");
> + } else {
> + ret = clk_reset(link_clk, CLK_RESET_DEASSERT);
> + if (ret)
> + pr_err("usb hs_clk deassert failed\n");
> + }
> + return ret;
> +}
> +
> +static int hsusb_phy_clk_reset(struct clk *phy_clk)
> +{
> + int ret;
> +
> + ret = clk_reset(phy_clk, CLK_RESET_ASSERT);
> + if (ret) {
> + pr_err("usb phy clk assert failed\n");
> + return ret;
> + }
> + usleep_range(1, 12000);
> + ret = clk_reset(phy_clk, CLK_RESET_DEASSERT);
> + if (ret)
> + pr_err("usb phy clk deassert failed\n");
> + return ret;
> +}

Why are there identical, static definitions of hsusb_link_clk_reset and
hsusb_phy_clk_reset across the two board files? Why not share a single
non-static set of definitions?

Thanks,
Christopher

-- 
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by the Linux Foundation.
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCHv5.1 4/5] check quirk to pad epout buf size when not aligned to maxpacketsize

2013-11-12 Thread David Cohen
On 11/12/2013 04:59 AM, Michal Nazarewicz wrote:
> On Tue, Nov 12 2013, David Cohen wrote:
>> You need to update req->length otherwise it's going to crash DWC3.
>> I'd rather to keep your previous version.
> 
> That's unfortunate.  Do you want me to resend it or will you just send
> a v6 of your whole series?

Alan disagreed and proposed a good approach to fix req->length inside
DWC3. We can keep this patch of yours but I'll need to change mine to
DWC3. I'll send a v6 with update on my patch.

Br, David

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH] usb: xhci: Link TRB must not occur with a USB payload burst.

2013-11-12 Thread Alan Stern
On Tue, 12 Nov 2013, David Laight wrote:

> > > If all the fragments are larger than the MBP (assume 16k) then
> > > that would be relatively easy. However that is very dependant
> > > on the source of the data. It might be true for disk data, but
> > > is unlikely to be true for ethernet data.
> > 
> > I don't quite understand your point.  Are you saying that if all the
> > TRBs are very short, you might need more than 64 TRBs to reach a 16-KB
> > boundary?
> 
> Since you don't really want to do all the work twice, the sensible
> way is to add each input fragment to the ring one a time.
> If you need to cross a link TRB and the last MBP boundary is within
> the previous data TRB then you can split the previous data TRB at the
> MBP boundary and continue.
> If the previous TRB is short then you'd need to go back through the
> earlier TRB until you found the one that contains a TRB boundary,
> split it, and write a link TRB in the following slot.

Right.  You could avoid doing a lot of work twice by using two passes.  
In the first pass, keep track of the number of bytes allotted to each
TRB and the MBP boundaries, without doing anything else.  That way,
you'll know where to put a Link TRB without any need for backtracking.  
Then in the second pass, fill in the actual contents of the TRBs.

> If you are within the first MBP then you'd need to replace the first
> TRB of the message with a link TRB.

Unless the first TRB of the message is the first TRB of the ring 
segment.  Then you're in trouble...  Hopefully, real URBs will never be 
that badly fragmented.

> And yes, if the data is really fragmented you might need a lot of
> TRB for even 1k of data.

Until somebody needs more than 16 TRBs for each KB of data, we should 
be okay.

> > > For bulk data the link TRB can be forced at a packet boundary
> > > by splitting the TD up - the receiving end won't know the difference.
> > 
> > That won't work.  What happens if you split a TD up into two pieces and
> > the first piece receives a short packet?  The host controller will
> > automatically move to the start of the second piece.  That's not what
> > we want.
> 
> You can split a bulk TD on a 1k boundary and the target won't know the
> difference.

The target won't know the difference, but the host will.  Here's an
example: Suppose the driver submits two URBs, each for a data-in
transfer of 32 KB.  You split each URB up into two 16-KB TDs; let's 
call them A, B, C, and D (where A and B make up the first URB, and C 
and D make up the second URB).

Now suppose the device terminates the first transfer after only 7200 
bytes, with a short packet.  It then sends a complete 32 KB of data for 
the second transfer.  What will happen in this case?

7200 bytes is somewhere in the middle of TD A.  That TD will terminate 
early.  The host controller will then proceed to TD B.  As a result, 
the next 32 KB of data will be stored in TD B and C -- not in TD C and 
D as it should be.

This example shows why you must not split IN URBs into multiple TDs.

> > > There is no necessity for taking an interrupt from every link segment.
> > 
> > Yes, there is.  The HCD needs to know when the dequeue pointer has
> > moved beyond the end of the ring segment, so that it can start reusing
> > the TRB slots in that segment.
> 
> You already know that because of the interrupts for the data packets
> themselves.

I don't know what you mean by this.  The host controller does not 
generate an interrupt for each data packet.  In generates interrupts 
only for TRBs with the IOC bit set (which is generally the last TRB in 
each TD).

Suppose you have only two ring segments, and a driver submits an URB 
which is so fragmented that it requires more TRBs than you have room 
for in those two segments.  When do you want the interrupts to arrive?  
Answer: At each segment crossing.

> > > I would change the code to use a single segment (for coding simplicity)
> > > and queue bulk URB when there isn't enough ring space.
> > > URB with too many fragments could either be rejected, sent in sections,
> > > or partially linearised (and probably still sent in sections).
> > 
> > Rejecting an URB is not feasible.  Splitting it up into multiple TDs is
> > not acceptable, as explained above.  Sending it in sections (i.e.,
> > queueing only some of the TRBs at any time) would work, provided you
> > got at least two interrupts every time the queue wrapped around (which
> > suggests you might want at least two ring segments).
> 
> Rejecting badly fragmented URB is almost certainly ok. You really don't
> want the hardware overhead of processing a TRB every few bytes.
> This would be especially bad on iommu systems.

I disagree.  Sure, it would be bad.  But if you can handle it, you 
should.

> Before the ring expansion code was added there was an implicit
> limit of (probably) 125 fragments for a URB. Exceeding this limit
> wasn't the reason for adding the ring expansion code.
> 
> And, as I've pointed out, both 

[PATCH 11/12] usb: gadget: Remove superfluous name casts

2013-11-12 Thread Geert Uytterhoeven
device_driver.name is "const char *"

Signed-off-by: Geert Uytterhoeven 
Cc: Felipe Balbi 
Cc: linux-usb@vger.kernel.org
---
 drivers/usb/gadget/fsl_qe_udc.c   |2 +-
 drivers/usb/gadget/fsl_udc_core.c |2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c
index 807127d56fa3..6315ee698d4d 100644
--- a/drivers/usb/gadget/fsl_qe_udc.c
+++ b/drivers/usb/gadget/fsl_qe_udc.c
@@ -2717,7 +2717,7 @@ MODULE_DEVICE_TABLE(of, qe_udc_match);
 
 static struct platform_driver udc_driver = {
.driver = {
-   .name = (char *)driver_name,
+   .name = driver_name,
.owner = THIS_MODULE,
.of_match_table = qe_udc_match,
},
diff --git a/drivers/usb/gadget/fsl_udc_core.c 
b/drivers/usb/gadget/fsl_udc_core.c
index 36ac7cfba91d..b7dea4eec32c 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -2666,7 +2666,7 @@ static struct platform_driver udc_driver = {
.suspend= fsl_udc_suspend,
.resume = fsl_udc_resume,
.driver = {
-   .name = (char *)driver_name,
+   .name = driver_name,
.owner = THIS_MODULE,
/* udc suspend/resume called from OTG driver */
.suspend = fsl_udc_otg_suspend,
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 09/12] usb: core: Remove superfluous name casts

2013-11-12 Thread Geert Uytterhoeven
device_driver.name is "const char *"

Signed-off-by: Geert Uytterhoeven 
Cc: Greg Kroah-Hartman 
Cc: linux-usb@vger.kernel.org
---
 drivers/usb/core/driver.c |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 47aade2a5e74..8d989b1d3dc5 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -839,7 +839,7 @@ int usb_register_device_driver(struct usb_device_driver 
*new_udriver,
return -ENODEV;
 
new_udriver->drvwrap.for_devices = 1;
-   new_udriver->drvwrap.driver.name = (char *) new_udriver->name;
+   new_udriver->drvwrap.driver.name = new_udriver->name;
new_udriver->drvwrap.driver.bus = &usb_bus_type;
new_udriver->drvwrap.driver.probe = usb_probe_device;
new_udriver->drvwrap.driver.remove = usb_unbind_device;
@@ -900,7 +900,7 @@ int usb_register_driver(struct usb_driver *new_driver, 
struct module *owner,
return -ENODEV;
 
new_driver->drvwrap.for_devices = 0;
-   new_driver->drvwrap.driver.name = (char *) new_driver->name;
+   new_driver->drvwrap.driver.name = new_driver->name;
new_driver->drvwrap.driver.bus = &usb_bus_type;
new_driver->drvwrap.driver.probe = usb_probe_interface;
new_driver->drvwrap.driver.remove = usb_unbind_interface;
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 12/12] usb: host: Remove superfluous name casts

2013-11-12 Thread Geert Uytterhoeven
device_driver.name is "const char *"

Signed-off-by: Geert Uytterhoeven 
Cc: Greg Kroah-Hartman 
Cc: linux-usb@vger.kernel.org
---
 drivers/usb/host/imx21-hcd.c|2 +-
 drivers/usb/host/isp116x-hcd.c  |2 +-
 drivers/usb/host/isp1362-hcd.c  |2 +-
 drivers/usb/host/r8a66597-hcd.c |2 +-
 drivers/usb/host/u132-hcd.c |2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c
index adb01d950a16..3fb2315dcb47 100644
--- a/drivers/usb/host/imx21-hcd.c
+++ b/drivers/usb/host/imx21-hcd.c
@@ -1926,7 +1926,7 @@ failed_request_mem:
 
 static struct platform_driver imx21_hcd_driver = {
.driver = {
-  .name = (char *)hcd_name,
+  .name = hcd_name,
   },
.probe = imx21_probe,
.remove = imx21_remove,
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
index c06739705d24..ab536637842d 100644
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -1775,7 +1775,7 @@ static struct platform_driver isp116x_driver = {
.suspend = isp116x_suspend,
.resume = isp116x_resume,
.driver = {
-   .name = (char *)hcd_name,
+   .name = hcd_name,
.owner  = THIS_MODULE,
},
 };
diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c
index 935a2dd367a8..cd94b108b57f 100644
--- a/drivers/usb/host/isp1362-hcd.c
+++ b/drivers/usb/host/isp1362-hcd.c
@@ -2829,7 +2829,7 @@ static struct platform_driver isp1362_driver = {
.suspend = isp1362_suspend,
.resume = isp1362_resume,
.driver = {
-   .name = (char *)hcd_name,
+   .name = hcd_name,
.owner = THIS_MODULE,
},
 };
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index 2ad004ae747c..3bddfcfafb79 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -2534,7 +2534,7 @@ static struct platform_driver r8a66597_driver = {
.probe =r8a66597_probe,
.remove =   r8a66597_remove,
.driver = {
-   .name = (char *) hcd_name,
+   .name = hcd_name,
.owner  = THIS_MODULE,
.pm = R8A66597_DEV_PM_OPS,
},
diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c
index e402beb5a069..46236e9fc87f 100644
--- a/drivers/usb/host/u132-hcd.c
+++ b/drivers/usb/host/u132-hcd.c
@@ -3217,7 +3217,7 @@ static struct platform_driver u132_platform_driver = {
.suspend = u132_suspend,
.resume = u132_resume,
.driver = {
-  .name = (char *)hcd_name,
+  .name = hcd_name,
   .owner = THIS_MODULE,
   },
 };
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 01/15] usb: phy: msm: Move mach dependent code to platform data

2013-11-12 Thread Ivan T. Ivanov

Hi Christopher,

On Tue, 2013-11-12 at 13:27 -0500, Christopher Covington wrote:
> Hi Ivan,
> 
> On 11/12/2013 09:51 AM, Ivan T. Ivanov wrote:
> > From: "Ivan T. Ivanov" 
> > 
> > This patch fix compilation error when driver is compiled
> > in multi-platform builds.
> > 
> > drivers/built-in.o: In function `msm_otg_link_clk_reset':
> > ./drivers/usb/phy/phy-msm-usb.c:314: undefined reference to `clk_reset'
> > ./drivers/usb/phy/phy-msm-usb.c:318: undefined reference to `clk_reset'
> > 
> > Use platform data supplied reset handlers and adjust error
> > messages reported when reset sequence fail.
> > 
> > This is an intermediate step before adding support for reset
> > framework and newer targets.
> > 
> > Signed-off-by: Ivan T. Ivanov 
> > Acked-by: David Brown 
> > Cc: Daniel Walker 
> > Cc: Felipe Balbi 
> > Cc: Greg Kroah-Hartman 
> > ---
> >  arch/arm/mach-msm/board-msm7x30.c |   35 
> > +++
> >  arch/arm/mach-msm/board-qsd8x50.c |   35 
> > +++
> >  drivers/usb/phy/phy-msm-usb.c |   35 
> > +++
> >  include/linux/usb/msm_hsusb.h |3 +++
> >  4 files changed, 88 insertions(+), 20 deletions(-)
> > 
> > diff --git a/arch/arm/mach-msm/board-msm7x30.c 
> > b/arch/arm/mach-msm/board-msm7x30.c
> > index f9af5a4..46de789 100644
> > --- a/arch/arm/mach-msm/board-msm7x30.c
> > +++ b/arch/arm/mach-msm/board-msm7x30.c
> > @@ -30,6 +30,7 @@
> >  #include 
> >  #include 
> >  
> > +#include 
> >  #include 
> >  #include 
> >  
> > @@ -60,10 +61,44 @@ static int hsusb_phy_init_seq[] = {
> > -1
> >  };
> >  
> > +static int hsusb_link_clk_reset(struct clk *link_clk, bool assert)
> > +{
> > +   int ret;
> > +
> > +   if (assert) {
> > +   ret = clk_reset(link_clk, CLK_RESET_ASSERT);
> > +   if (ret)
> > +   pr_err("usb hs_clk assert failed\n");
> > +   } else {
> > +   ret = clk_reset(link_clk, CLK_RESET_DEASSERT);
> > +   if (ret)
> > +   pr_err("usb hs_clk deassert failed\n");
> > +   }
> > +   return ret;
> > +}
> > +
> > +static int hsusb_phy_clk_reset(struct clk *phy_clk)
> > +{
> > +   int ret;
> > +
> > +   ret = clk_reset(phy_clk, CLK_RESET_ASSERT);
> > +   if (ret) {
> > +   pr_err("usb phy clk assert failed\n");
> > +   return ret;
> > +   }
> > +   usleep_range(1, 12000);
> > +   ret = clk_reset(phy_clk, CLK_RESET_DEASSERT);
> > +   if (ret)
> > +   pr_err("usb phy clk deassert failed\n");
> > +   return ret;
> > +}
> > +
> >  static struct msm_otg_platform_data msm_otg_pdata = {
> > .phy_init_seq   = hsusb_phy_init_seq,
> > .mode   = USB_PERIPHERAL,
> > .otg_control= OTG_PHY_CONTROL,
> > +   .link_clk_reset = hsusb_link_clk_reset,
> > +   .phy_clk_reset  = hsusb_phy_clk_reset,
> >  };
> >  
> >  struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = {
> > diff --git a/arch/arm/mach-msm/board-qsd8x50.c 
> > b/arch/arm/mach-msm/board-qsd8x50.c
> > index 5f933bc..9169ec3 100644
> > --- a/arch/arm/mach-msm/board-qsd8x50.c
> > +++ b/arch/arm/mach-msm/board-qsd8x50.c
> > @@ -31,6 +31,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  #include 
> >  
> >  #include "devices.h"
> > @@ -81,10 +82,44 @@ static int hsusb_phy_init_seq[] = {
> > -1
> >  };
> >  
> > +static int hsusb_link_clk_reset(struct clk *link_clk, bool assert)
> > +{
> > +   int ret;
> > +
> > +   if (assert) {
> > +   ret = clk_reset(link_clk, CLK_RESET_ASSERT);
> > +   if (ret)
> > +   pr_err("usb hs_clk assert failed\n");
> > +   } else {
> > +   ret = clk_reset(link_clk, CLK_RESET_DEASSERT);
> > +   if (ret)
> > +   pr_err("usb hs_clk deassert failed\n");
> > +   }
> > +   return ret;
> > +}
> > +
> > +static int hsusb_phy_clk_reset(struct clk *phy_clk)
> > +{
> > +   int ret;
> > +
> > +   ret = clk_reset(phy_clk, CLK_RESET_ASSERT);
> > +   if (ret) {
> > +   pr_err("usb phy clk assert failed\n");
> > +   return ret;
> > +   }
> > +   usleep_range(1, 12000);
> > +   ret = clk_reset(phy_clk, CLK_RESET_DEASSERT);
> > +   if (ret)
> > +   pr_err("usb phy clk deassert failed\n");
> > +   return ret;
> > +}
> 
> Why are there identical, static definitions of hsusb_link_clk_reset and
> hsusb_phy_clk_reset across the two board files? Why not share a single
> non-static set of definitions?

One file which is used by both boards and is compiled unconditionally 
is clock.c, but I don't think that it will be appropriate to put USB
specific functions there. Creating new file for just these functions
also do not sound good to me.

Regards,
Ivan

> 
> Thanks,
> Christopher
> 


--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] usb: xhci: Link TRB must not occur with a USB payload burst.

2013-11-12 Thread Alan Stern
On Tue, 12 Nov 2013, Sarah Sharp wrote:

> > It comes down to a question of how often you want the controller to
> > issue an interrupt.  If a ring segment is 4 KB (one page), then it can
> > hold 256 TRBs.  With scatter-gather transfers, each SG element
> > typically refers to something like a 2-page buffer (depends on how
> > fragmented the memory is).  Therefore a ring segment will describe
> > somewhere around 512 pages of data, i.e., something like 2 MB.  Since
> > SuperSpeed is 500 MB/s, you'd end up getting in the vicinity of 250
> > interrupts every second just because of ring segment crossings.
> 
> The driver is currently defined to have 64 TRBs per ring segment.  But

A TRB is 16 bytes, right?  So a page can hold 256 TRBs.  Why use only 
64 per segment?

> that doesn't matter; we don't get an interrupt when a ring segment is
> crossed.  Instead we set the interrupt-on-completion flag on the last
> TRB of the TD, not on any earlier fragment or link TRB.

That's because you don't worry about handling URBs which require too 
many TRBs (i.e., more than are available).  You just add more ring 
segments.  Instead, you could re-use segments on the fly.

For example, suppose you have only two ring segments and you get an URB
which requires enough TRBs to fill up four segments.  You could fill in
the first two segments worth, and get an interrupt when the controller
traverses the Link TRB between them.  At that point you store the third
set of TRBs in the first segment, which is now vacant.  Similarly, when
the second Link TRB is traversed, you fill in the fourth set of TRBs.

> > Using larger ring segments would help.
> 
> Ring segments have to be physically contiguous, so I'm not sure if we
> want to ask for segments that are bigger than a page.  I've already got
> a report from someone else about the ring expansion getting out of
> control, so I would like to figure that out before we talk about using
> even bigger segments.

Maybe you can get away with fewer segments, if they are bigger.

> Finally, it's interesting to note that the USB mass storage driver is
> using scatter gather lists just fine without the driver following the TD
> fragment rules.  Or at least no one has reported any issues.  I wonder
> why it works?

I'd guess this is because the hardware is actually a lot more flexible
than the "No Link TRBs in the middle of a TD fragment" rule.

The whole idea of TD fragments makes no sense to begin with.  What
point is there in grouping packets into MaxBurst-sized collections?  
The hardware does not have to finish one burst before beginning the
next one.  For example, suppose the MaxBurst size is 8.  The host
starts by bursting packets 1-8.  When it receives the ACK for packet 4,
the host could then burst packets 9-12.  It doesn't have to wait for
the ACK to packet 8.  (Unless I have misunderstood the USB-3 spec.)

If the host does this, the burst boundaries won't occur on MBP 
boundaries, and hence won't occur on TD fragment boundaries.  The 
fragment boundaries will be essentially meaningless.

Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] Revert "sierra_net: keep status interrupt URB active"

2013-11-12 Thread Bjørn Mork


Dan Williams  wrote:

>> Actually, is "[PATCH] usbnet: fix status interrupt urb handling" the
>> real fix for this problem?
>> 
>> John, any chance you could revert my RFC patch and try Felix's patch
>in
>> that mail?
>
>It fixes the problem for me without requiring the revert or my RFC
>patch

Yes, this looks like a reasonable explanation. Good timing. 


Bjørn

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: huawei_cdc_ncm driver

2013-11-12 Thread Bjørn Mork


"Thomas Schäfer"  wrote:

>So problem seems to be somewhere but not in you driver.

Let's hope so. I always worry when making changes, no matter how insignificant 
they are. I often feel like my bug to line ratio is a two digit number...

Thanks for checking.


Bjørn

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 0/5] add gadget quirk to adapt f_fs for DWC3

2013-11-12 Thread David Cohen
Hi,

These patches are a proposal to add gadget quirks in an immediate objective to
adapt f_fs when using DWC3 controller. But the quirk solution is generic and
can be used by other controllers to adapt gadget functions to their
non-standard restrictions.

This change is necessary to make Android's adbd service to work on Intel
Merrifield with f_fs instead of out-of-tree android gadget.

This new patch set was tested and validated in my environment:
 - Intel Merrifield was able to use DWC3/f_fs with adbd service (it wasn't
   before).

Changes from v45 to v6:
 - Updated patches from Michal Nazarewicz to address comments from Alan Stern
   and mine.
 - Modified patch 5/5 to apply request->length's pad internally to DWC3.

---
David Cohen (3):
  usb: gadget: move bitflags to the end of usb_gadget struct
  usb: gadget: add quirk_ep_out_aligned_size field to struct usb_gadget
  usb: dwc3: implement gadget's quirk ep_out_align_size

Michal Nazarewicz (2):
  usb: gadget: f_fs: remove loop from I/O function
  check quirk to pad epout buf size when not aligned to maxpacketsize

 drivers/usb/dwc3/core.h|   6 +++
 drivers/usb/dwc3/gadget.c  |  23 ++
 drivers/usb/gadget/f_fs.c  | 102 +
 include/linux/usb/gadget.h |  35 
 4 files changed, 103 insertions(+), 63 deletions(-)

-- 
1.8.4.2

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 1/5] usb: gadget: move bitflags to the end of usb_gadget struct

2013-11-12 Thread David Cohen
This patch moves all bitflags to the end of usb_gadget struct in order
to improve readability.

Signed-off-by: David Cohen 
Acked-by: Michal Nazarewicz 
---
 include/linux/usb/gadget.h | 19 ++-
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 942ef5e053bf..23b3bfd0a842 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -485,6 +485,11 @@ struct usb_gadget_ops {
  * @max_speed: Maximal speed the UDC can handle.  UDC must support this
  *  and all slower speeds.
  * @state: the state we are now (attached, suspended, configured, etc)
+ * @name: Identifies the controller hardware type.  Used in diagnostics
+ * and sometimes configuration.
+ * @dev: Driver model state for this abstract device.
+ * @out_epnum: last used out ep number
+ * @in_epnum: last used in ep number
  * @sg_supported: true if we can handle scatter-gather
  * @is_otg: True if the USB device port uses a Mini-AB jack, so that the
  * gadget driver must provide a USB OTG descriptor.
@@ -497,11 +502,6 @@ struct usb_gadget_ops {
  * only supports HNP on a different root port.
  * @b_hnp_enable: OTG device feature flag, indicating that the A-Host
  * enabled HNP support.
- * @name: Identifies the controller hardware type.  Used in diagnostics
- * and sometimes configuration.
- * @dev: Driver model state for this abstract device.
- * @out_epnum: last used out ep number
- * @in_epnum: last used in ep number
  *
  * Gadgets have a mostly-portable "gadget driver" implementing device
  * functions, handling all usb configurations and interfaces.  Gadget
@@ -530,16 +530,17 @@ struct usb_gadget {
enum usb_device_speed   speed;
enum usb_device_speed   max_speed;
enum usb_device_state   state;
+   const char  *name;
+   struct device   dev;
+   unsignedout_epnum;
+   unsignedin_epnum;
+
unsignedsg_supported:1;
unsignedis_otg:1;
unsignedis_a_peripheral:1;
unsignedb_hnp_enable:1;
unsigneda_hnp_support:1;
unsigneda_alt_hnp_support:1;
-   const char  *name;
-   struct device   dev;
-   unsignedout_epnum;
-   unsignedin_epnum;
 };
 #define work_to_gadget(w)  (container_of((w), struct usb_gadget, work))
 
-- 
1.8.4.2

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 2/5] usb: gadget: add quirk_ep_out_aligned_size field to struct usb_gadget

2013-11-12 Thread David Cohen
Due to USB controllers may have different restrictions, usb gadget layer
needs to provide a generic way to inform gadget functions to complain
with non-standard requirements.

This patch adds 'quirk_ep_out_aligned_size' field to struct usb_gadget
to inform when controller's epout requires buffer size to be aligned to
MaxPacketSize. A helper is also provided to align buffer size when
necessary.

Signed-off-by: David Cohen 
Acked-by: Alan Stern 
Acked-by: Michal Nazarewicz 
---
 include/linux/usb/gadget.h | 16 
 1 file changed, 16 insertions(+)

diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 23b3bfd0a842..41e8834af57d 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -441,6 +441,19 @@ static inline void usb_ep_fifo_flush(struct usb_ep *ep)
ep->ops->fifo_flush(ep);
 }
 
+/**
+ * usb_ep_align_maxpacketsize - returns @len aligned to ep's maxpacketsize
+ * @ep: the endpoint whose maxpacketsize is used to align @len
+ * @len: buffer size's length to align to @ep's maxpacketsize
+ *
+ * This helper is used in case it's required for any reason to align buffer's
+ * size to an ep's maxpacketsize.
+ */
+static inline size_t usb_ep_align_maxpacketsize(struct usb_ep *ep, size_t len)
+{
+   return round_up(len, (size_t)ep->desc->wMaxPacketSize);
+}
+
 
 /*-*/
 
@@ -502,6 +515,8 @@ struct usb_gadget_ops {
  * only supports HNP on a different root port.
  * @b_hnp_enable: OTG device feature flag, indicating that the A-Host
  * enabled HNP support.
+ * @quirk_ep_out_aligned_size: epout requires buffer size to be aligned to
+ * MaxPacketSize.
  *
  * Gadgets have a mostly-portable "gadget driver" implementing device
  * functions, handling all usb configurations and interfaces.  Gadget
@@ -541,6 +556,7 @@ struct usb_gadget {
unsignedb_hnp_enable:1;
unsigneda_hnp_support:1;
unsigneda_alt_hnp_support:1;
+   unsignedquirk_ep_out_aligned_size:1;
 };
 #define work_to_gadget(w)  (container_of((w), struct usb_gadget, work))
 
-- 
1.8.4.2

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 4/5] check quirk to pad epout buf size when not aligned to maxpacketsize

2013-11-12 Thread David Cohen
From: Michal Nazarewicz 

Check gadget.quirk_ep_out_aligned_size to decide if buffer size requires
to be aligned to maxpacketsize of an out endpoint.  ffs_epfile_io() needs
to pad epout buffer to match above condition if quirk is found.

Signed-off-by: Michal Nazarewicz 
Acked-by: David Cohen 
---
 drivers/usb/gadget/f_fs.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
index efa1152a4c15..688cfa005b4d 100644
--- a/drivers/usb/gadget/f_fs.c
+++ b/drivers/usb/gadget/f_fs.c
@@ -755,6 +755,7 @@ static ssize_t ffs_epfile_io(struct file *file,
 char __user *buf, size_t len, int read)
 {
struct ffs_epfile *epfile = file->private_data;
+   struct usb_gadget *gadget = epfile->ffs->gadget;
struct ffs_ep *ep;
char *data = NULL;
ssize_t ret;
@@ -790,7 +791,14 @@ static ssize_t ffs_epfile_io(struct file *file,
 
/* Allocate & copy */
if (!halt) {
-   data = kmalloc(len, GFP_KERNEL);
+   /*
+* Controller requires buffer size to be aligned to
+* maxpacketsize of an out endpoint.
+*/
+   size_t data_len = read && gadget->quirk_ep_out_aligned_size ?
+   usb_ep_align_maxpacketsize(ep->ep, len) : len;
+
+   data = kmalloc(data_len, GFP_KERNEL);
if (unlikely(!data))
return -ENOMEM;
 
-- 
1.8.4.2

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 3/5] usb: gadget: f_fs: remove loop from I/O function

2013-11-12 Thread David Cohen
From: Michal Nazarewicz 

When endpoint changes (due to it being disabled or alt setting changed),
mimic the action as if the change happened after the request has been
queued, instead of retrying with the new endpoint.

Signed-off-by: Michal Nazarewicz 
Cc: David Cohen 
---
 drivers/usb/gadget/f_fs.c | 94 ---
 1 file changed, 40 insertions(+), 54 deletions(-)

diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
index 75e4b7846a8d..efa1152a4c15 100644
--- a/drivers/usb/gadget/f_fs.c
+++ b/drivers/usb/gadget/f_fs.c
@@ -760,73 +760,59 @@ static ssize_t ffs_epfile_io(struct file *file,
ssize_t ret;
int halt;
 
-   goto first_try;
-   do {
-   spin_unlock_irq(&epfile->ffs->eps_lock);
-   mutex_unlock(&epfile->mutex);
+   /* Are we still active? */
+   if (WARN_ON(epfile->ffs->state != FFS_ACTIVE)) {
+   ret = -ENODEV;
+   goto error;
+   }
 
-first_try:
-   /* Are we still active? */
-   if (WARN_ON(epfile->ffs->state != FFS_ACTIVE)) {
-   ret = -ENODEV;
+   /* Wait for endpoint to be enabled */
+   ep = epfile->ep;
+   if (!ep) {
+   if (file->f_flags & O_NONBLOCK) {
+   ret = -EAGAIN;
goto error;
}
 
-   /* Wait for endpoint to be enabled */
-   ep = epfile->ep;
-   if (!ep) {
-   if (file->f_flags & O_NONBLOCK) {
-   ret = -EAGAIN;
-   goto error;
-   }
-
-   if (wait_event_interruptible(epfile->wait,
-(ep = epfile->ep))) {
-   ret = -EINTR;
-   goto error;
-   }
-   }
-
-   /* Do we halt? */
-   halt = !read == !epfile->in;
-   if (halt && epfile->isoc) {
-   ret = -EINVAL;
+   ret = wait_event_interruptible(epfile->wait, (ep = epfile->ep));
+   if (ret) {
+   ret = -EINTR;
goto error;
}
+   }
 
-   /* Allocate & copy */
-   if (!halt && !data) {
-   data = kzalloc(len, GFP_KERNEL);
-   if (unlikely(!data))
-   return -ENOMEM;
+   /* Do we halt? */
+   halt = !read == !epfile->in;
+   if (halt && epfile->isoc) {
+   ret = -EINVAL;
+   goto error;
+   }
 
-   if (!read &&
-   unlikely(__copy_from_user(data, buf, len))) {
-   ret = -EFAULT;
-   goto error;
-   }
-   }
+   /* Allocate & copy */
+   if (!halt) {
+   data = kmalloc(len, GFP_KERNEL);
+   if (unlikely(!data))
+   return -ENOMEM;
 
-   /* We will be using request */
-   ret = ffs_mutex_lock(&epfile->mutex,
-file->f_flags & O_NONBLOCK);
-   if (unlikely(ret))
+   if (!read && unlikely(copy_from_user(data, buf, len))) {
+   ret = -EFAULT;
goto error;
+   }
+   }
 
-   /*
-* We're called from user space, we can use _irq rather then
-* _irqsave
-*/
-   spin_lock_irq(&epfile->ffs->eps_lock);
+   /* We will be using request */
+   ret = ffs_mutex_lock(&epfile->mutex, file->f_flags & O_NONBLOCK);
+   if (unlikely(ret))
+   goto error;
 
-   /*
-* While we were acquiring mutex endpoint got disabled
-* or changed?
-*/
-   } while (unlikely(epfile->ep != ep));
+   spin_lock_irq(&epfile->ffs->eps_lock);
 
-   /* Halt */
-   if (unlikely(halt)) {
+   if (epfile->ep != ep) {
+   /* In the meantime, endpoint got disabled or changed. */
+   ret = -ESHUTDOWN;
+   spin_unlock_irq(&epfile->ffs->eps_lock);
+   } else if (halt) {
+   /* Halt */
if (likely(epfile->ep == ep) && !WARN_ON(!ep->ep))
usb_ep_set_halt(ep->ep);
spin_unlock_irq(&epfile->ffs->eps_lock);
-- 
1.8.4.2

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v6 0/5] add gadget quirk to adapt f_fs for DWC3

2013-11-12 Thread David Cohen

On 11/12/2013 01:04 PM, David Cohen wrote:

Hi,

These patches are a proposal to add gadget quirks in an immediate objective to
adapt f_fs when using DWC3 controller. But the quirk solution is generic and
can be used by other controllers to adapt gadget functions to their
non-standard restrictions.

This change is necessary to make Android's adbd service to work on Intel
Merrifield with f_fs instead of out-of-tree android gadget.

This new patch set was tested and validated in my environment:
  - Intel Merrifield was able to use DWC3/f_fs with adbd service (it wasn't
before).

Changes from v45 to v6:


I hope not have to get to v45 :) but I meant v5.
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 02/17] ARM: at91: add Kconfig options for common clk support

2013-11-12 Thread Boris BREZILLON
This patch adds the following Kconfig options to prepare the transition to
common clk framework:

- AT91_USE_OLD_CLK: this option is selected by every SoC which does not
  support new at91 clks based on common clk framework (SoC which does not
  define the clock tree in its device tree).
  This options is also selected when the user choose non dt boards support
  (new at91 clks can only be registered from a device tree definition).

- COMMON_CLK_AT91: this option cannot be selected directly. Instead it is
  enabled if these 3 conditions are met:
   * at least one of the selected SoCs have a PMC (Power Management
 Controller) Unit
   * device tree support is enabled
   * the old at91 clk implementation is disabled (every selected SoC define
 its clks in its device tree and non dt boards support is disabled)

- OLD_CLK_AT91: this option cannot be selected directly. Instead it is
  enabled if these 2 conditions are met:
   * at least one of the selected SoCs have a PMC (Power Management
 Controller) Unit
   * at least one of the selected SoCs does not define its clks in its
 device tree or non dt-boards support is enabled

This patch selects AT91_USE_OLD_CLK in all currently supported SoCs. These
selects will be removed after clk definitions are properly added in each
soc's device tree.
It also selects AT91_USE_OLD_CLK in all non-dt boards support.

AT91_PMC_UNIT references are replaced by OLD_CLK_AT91, because PMC Unit is
enabled for both old and common clk implementations, and old clk
implementation should not be compiled if COMMON_CLK is enabled.

To avoid future link errors, a new stub is created for at91_dt_clock_init
function if OLD_CLK_AT91 is disabled.

A new check is added in dt init functions (setup.c) to prepare for SoCs
supporting new clk implementation. These SoCs won't setup the
register_clocks callback (clk registration is done using of_clk_init).

Signed-off-by: Boris BREZILLON 
Acked-by: Nicolas Ferre 
---
 arch/arm/mach-at91/Kconfig|   21 +
 arch/arm/mach-at91/Kconfig.non_dt |6 ++
 arch/arm/mach-at91/Makefile   |2 +-
 arch/arm/mach-at91/generic.h  |3 ++-
 arch/arm/mach-at91/setup.c|6 --
 5 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 699b71e..85b53a4 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -6,10 +6,22 @@ config HAVE_AT91_DBGU0
 config HAVE_AT91_DBGU1
bool
 
+config AT91_USE_OLD_CLK
+   bool
+
 config AT91_PMC_UNIT
bool
default !ARCH_AT91X40
 
+config COMMON_CLK_AT91
+   bool
+   default AT91_PMC_UNIT && USE_OF && !AT91_USE_OLD_CLK
+   select COMMON_CLK
+
+config OLD_CLK_AT91
+   bool
+   default AT91_PMC_UNIT && AT91_USE_OLD_CLK
+
 config AT91_SAM9_ALT_RESET
bool
default !ARCH_AT91X40
@@ -65,6 +77,7 @@ config SOC_SAMA5D3
select SOC_SAMA5
select HAVE_FB_ATMEL
select HAVE_AT91_DBGU1
+   select AT91_USE_OLD_CLK
help
  Select this if you are using one of Atmel's SAMA5D3 family SoC.
  This support covers SAMA5D31, SAMA5D33, SAMA5D34, SAMA5D35.
@@ -78,11 +91,13 @@ config SOC_AT91RM9200
select HAVE_AT91_DBGU0
select MULTI_IRQ_HANDLER
select SPARSE_IRQ
+   select AT91_USE_OLD_CLK
 
 config SOC_AT91SAM9260
bool "AT91SAM9260, AT91SAM9XE or AT91SAM9G20"
select HAVE_AT91_DBGU0
select SOC_AT91SAM9
+   select AT91_USE_OLD_CLK
help
  Select this if you are using one of Atmel's AT91SAM9260, AT91SAM9XE
  or AT91SAM9G20 SoC.
@@ -92,6 +107,7 @@ config SOC_AT91SAM9261
select HAVE_AT91_DBGU0
select HAVE_FB_ATMEL
select SOC_AT91SAM9
+   select AT91_USE_OLD_CLK
help
  Select this if you are using one of Atmel's AT91SAM9261 or 
AT91SAM9G10 SoC.
 
@@ -100,18 +116,21 @@ config SOC_AT91SAM9263
select HAVE_AT91_DBGU1
select HAVE_FB_ATMEL
select SOC_AT91SAM9
+   select AT91_USE_OLD_CLK
 
 config SOC_AT91SAM9RL
bool "AT91SAM9RL"
select HAVE_AT91_DBGU0
select HAVE_FB_ATMEL
select SOC_AT91SAM9
+   select AT91_USE_OLD_CLK
 
 config SOC_AT91SAM9G45
bool "AT91SAM9G45 or AT91SAM9M10 families"
select HAVE_AT91_DBGU1
select HAVE_FB_ATMEL
select SOC_AT91SAM9
+   select AT91_USE_OLD_CLK
help
  Select this if you are using one of Atmel's AT91SAM9G45 family SoC.
  This support covers AT91SAM9G45, AT91SAM9G46, AT91SAM9M10 and 
AT91SAM9M11.
@@ -121,6 +140,7 @@ config SOC_AT91SAM9X5
select HAVE_AT91_DBGU0
select HAVE_FB_ATMEL
select SOC_AT91SAM9
+   select AT91_USE_OLD_CLK
help
  Select this if you are using one of Atmel's AT91SAM9x5 family SoC.
  This means that your SAM9 name finishes with a '5' (except if it is
@@ -133,6 +153,7 @

[PATCH v6 5/5] usb: dwc3: implement gadget's quirk ep_out_align_size

2013-11-12 Thread David Cohen
DWC3 requires epout to have buffer size aligned to MaxPacketSize value.
This patch implements necessary quirk for it.

Signed-off-by: David Cohen 
---
 drivers/usb/dwc3/core.h   |  6 ++
 drivers/usb/dwc3/gadget.c | 23 +++
 2 files changed, 29 insertions(+)

diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index f8af8d44af85..ff42d7ddc546 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -571,6 +571,12 @@ struct dwc3_request {
struct dwc3_ep  *dep;
u32 start_slot;
 
+   /*
+* If gadget/epout, we need to pad buffer size to align with
+* maxpacketsize.
+*/
+   size_t  pad;
+
u8  epnum;
struct dwc3_trb *trb;
dma_addr_t  trb_dma;
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 5452c0fce360..7c2d36f6ad4b 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1130,6 +1130,14 @@ static int dwc3_gadget_ep_queue(struct usb_ep *ep, 
struct usb_request *request,
dev_vdbg(dwc->dev, "queing request %p to %s length %d\n",
request, ep->name, request->length);
 
+   /* If ep out, roundup request->length to epout maxpacketsize */
+   if (!(dep->number & 1)) {
+   unsigned int aligned = roundup(request->length,
+  ep->desc->wMaxPacketSize);
+   req->pad = aligned - request->length;
+   request->length = aligned;
+   }
+
spin_lock_irqsave(&dwc->lock, flags);
ret = __dwc3_gadget_ep_queue(dep, req);
spin_unlock_irqrestore(&dwc->lock, flags);
@@ -1173,6 +1181,15 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
}
 
 out1:
+   if (!(dep->number & 1)) {
+   /*
+* Sanitize request->length after pad was applied before
+* queue.
+*/
+   request->length -= req->pad;
+   req->pad = 0;
+   }
+
/* giveback the request */
dwc3_gadget_giveback(dep, req, -ECONNRESET);
 
@@ -2600,6 +2617,12 @@ int dwc3_gadget_init(struct dwc3 *dwc)
dwc->gadget.name= "dwc3-gadget";
 
/*
+* Per databook, DWC3 needs buffer size to be aligned to MaxPacketSize
+* on ep out.
+*/
+   dwc->gadget.quirk_ep_out_aligned_size = true;
+
+   /*
 * REVISIT: Here we should clear all pending IRQs to be
 * sure we're starting from a well known location.
 */
-- 
1.8.4.2

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 01/17] ARM: at91: move at91_pmc.h to include/linux/clk/at91_pmc.h

2013-11-12 Thread Boris BREZILLON
This patch moves at91_pmc.h header from machine specific directory
(arch/arm/mach-at91/include/mach/at91_pmc.h) to clk include directory
(include/linux/clk/at91_pmc.h).
We need this to avoid reference to machine specific headers in clk
drivers.

Signed-off-by: Boris BREZILLON 
Acked-by: Felipe Balbi 
Acked-by: Nicolas Ferre 
---
 arch/arm/mach-at91/at91rm9200.c|2 +-
 arch/arm/mach-at91/at91sam9260.c   |2 +-
 arch/arm/mach-at91/at91sam9261.c   |2 +-
 arch/arm/mach-at91/at91sam9263.c   |2 +-
 arch/arm/mach-at91/at91sam9g45.c   |2 +-
 arch/arm/mach-at91/at91sam9n12.c   |2 +-
 arch/arm/mach-at91/at91sam9rl.c|2 +-
 arch/arm/mach-at91/at91sam9x5.c|2 +-
 arch/arm/mach-at91/clock.c |2 +-
 arch/arm/mach-at91/pm.c|2 +-
 arch/arm/mach-at91/pm_slowclock.S  |2 +-
 arch/arm/mach-at91/sama5d3.c   |2 +-
 arch/arm/mach-at91/setup.c |2 +-
 drivers/usb/gadget/atmel_usba_udc.c|2 +-
 .../include/mach => include/linux/clk}/at91_pmc.h  |2 +-
 15 files changed, 15 insertions(+), 15 deletions(-)
 rename {arch/arm/mach-at91/include/mach => include/linux/clk}/at91_pmc.h (99%)

diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c
index 4aad93d..102dac6 100644
--- a/arch/arm/mach-at91/at91rm9200.c
+++ b/arch/arm/mach-at91/at91rm9200.c
@@ -12,13 +12,13 @@
 
 #include 
 #include 
+#include 
 
 #include 
 #include 
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
index 5de6074..16d7817 100644
--- a/arch/arm/mach-at91/at91sam9260.c
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -11,6 +11,7 @@
  */
 
 #include 
+#include 
 
 #include 
 #include 
@@ -20,7 +21,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #include "at91_aic.h"
 #include "at91_rstc.h"
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
index 0e07932..c8f5958 100644
--- a/arch/arm/mach-at91/at91sam9261.c
+++ b/arch/arm/mach-at91/at91sam9261.c
@@ -11,6 +11,7 @@
  */
 
 #include 
+#include 
 
 #include 
 #include 
@@ -19,7 +20,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #include "at91_aic.h"
 #include "at91_rstc.h"
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
index 6ce7d18..cd8ad95 100644
--- a/arch/arm/mach-at91/at91sam9263.c
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -11,6 +11,7 @@
  */
 
 #include 
+#include 
 
 #include 
 #include 
@@ -18,7 +19,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #include "at91_aic.h"
 #include "at91_rstc.h"
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c
index 474ee04..9794b20 100644
--- a/arch/arm/mach-at91/at91sam9g45.c
+++ b/arch/arm/mach-at91/at91sam9g45.c
@@ -12,13 +12,13 @@
 
 #include 
 #include 
+#include 
 
 #include 
 #include 
 #include 
 #include 
 #include 
-#include 
 #include 
 
 #include "at91_aic.h"
diff --git a/arch/arm/mach-at91/at91sam9n12.c b/arch/arm/mach-at91/at91sam9n12.c
index 2d895a2..deafab2 100644
--- a/arch/arm/mach-at91/at91sam9n12.c
+++ b/arch/arm/mach-at91/at91sam9n12.c
@@ -8,12 +8,12 @@
 
 #include 
 #include 
+#include 
 
 #include 
 #include 
 #include 
 #include 
-#include 
 #include 
 
 #include "board.h"
diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c
index d4ec0d9..947da95 100644
--- a/arch/arm/mach-at91/at91sam9rl.c
+++ b/arch/arm/mach-at91/at91sam9rl.c
@@ -10,6 +10,7 @@
  */
 
 #include 
+#include 
 
 #include 
 #include 
@@ -19,7 +20,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #include "at91_aic.h"
 #include "at91_rstc.h"
diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c
index 916e5a1..a930d73 100644
--- a/arch/arm/mach-at91/at91sam9x5.c
+++ b/arch/arm/mach-at91/at91sam9x5.c
@@ -8,12 +8,12 @@
 
 #include 
 #include 
+#include 
 
 #include 
 #include 
 #include 
 #include 
-#include 
 #include 
 
 #include "board.h"
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c
index 6b2630a..5f02aea 100644
--- a/arch/arm/mach-at91/clock.c
+++ b/arch/arm/mach-at91/clock.c
@@ -24,9 +24,9 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
-#include 
 #include 
 
 #include 
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 15afb5d..692cacd 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -19,13 +19,13 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
 #include 
 #include 
 
-#include 
 #include 
 
 #include "at91_aic.h"
diff --git a/arch/arm/mach-at91/pm_slowclock.S 
b/arch/arm/mach-at91/pm_slowclock.S
index 098c28d..2001877 100644
--- a/arch/arm/mach-at91/pm_slowclock.S
+++ b/arch/arm/mach-at91/pm_slowclock.S
@@ 

[PATCH v5 00/17] ARM: at91: move to common clk framework

2013-11-12 Thread Boris BREZILLON
Hello,

This patch series is the 5th version of the at91 clk implementations
using the Common Clk Framework.

Most of the clock provided by the PMC (Power Management Controller) are
implemented :
- main clock (main oscillator)
- pll clocks
- master clock
- programmable clocks
- utmi clock
- peripheral clocks
- system clocks

Actually some clk drivers are missing (slow clk, main clk and processor
clk), and some drivers only implement a subset of the hardware capabilities
(master clk rate change is missing).
But this series implements all the already available clks, and I will hopefully
add missing features in a near future.

This implementation is only compatible with device tree definition.
The goal is to define the whole clock tree using the device tree.

BTW, could a dt maintainer take a look at these dt bindinds ?

Just a note to let you know these bindings are currently unstable and might
change in the future.


Mike, I know you already acked the previous version, but I slighty changed
the dt bindings, according to some feedbacks I got during ELCE.
Could you take a look at this new version (at least the new dt bindings),
and add your acked-by if you agree with these changes ?

Best Regards,
Boris

Changes since v4:
 - rework dt bindings:
   * replace "atmel,clk-id" property by the standard "reg" property
   * reference system, peripheral and programmable clks using the direct
 clk node instead of the parent node plus a clk id
 - provide a new helper function (of_at91_get_clk_range) to retrieve a clk
   range from the device tree

Changes since v3:
 - simplify master clk implementation (drop set_rate/parent support)
 - fix bug in set_rate function of pll driver
 - fix coding style issues
 - define macros and constants where needed
 - remove peripheral id macro references
 - remove sam9g35 specific handling (sam9g35 = sam9x5)
 - rework main clk prepare function to handle automatic rate calculation

Changes since v2:
 - fix several bugs in clk implementations
 - drop non-dt boards support
 - split the series to ease review and tests:
   * 1 patch series for new clk implementations (this series)
   * 1 patch series to move each at91 SoC to common clk framework (coming soon)
 - modify dt-bindings (add atmel,clk- prefix to atmel specific properties)
 - add clk macros for dt-bindings
 - add pmc framework (helper function to access pmc registers)
 - add interrupt support to enable passive wait in clk_prepare functions

Changes since v1:
 - fix bugs in pll, programmable and system clock implementations
   (wrong bit position).
 - add usb clock configuration support (ohci and udc drivers +
   clk_lookup for non dt boards)
 - rework of the system clock interfaces (no need to define a parent clock,
   system clock is a gate with no rate info)
 - change system, peripheral and programmable clk dt bindings (1 master node
   and multiple child nodes each defining a system/peripheral or prog clock)
 - fix bugs in sama5 dt definition

Boris BREZILLON (17):
  ARM: at91: move at91_pmc.h to include/linux/clk/at91_pmc.h
  ARM: at91: add Kconfig options for common clk support
  clk: at91: add PMC base support
  clk: at91: add PMC macro file for dt definitions
  clk: at91: add PMC main clock
  clk: at91: add PMC pll clocks
  clk: at91: add PMC master clock
  clk: at91: add PMC system clocks
  clk: at91: add PMC peripheral clocks
  clk: at91: add peripheral clk macros for peripheral clk dt bindings
  clk: at91: add PMC programmable clocks
  clk: at91: add PMC utmi clock
  clk: at91: add PMC usb clock
  clk: at91: add PMC smd clock
  clk: at91: add PMC clk device tree binding doc.
  ARM: at91: move pit timer to common clk framework
  ARM: at91: add new compatible strings for pmc driver

 .../devicetree/bindings/clock/at91-clock.txt   |  339 +
 arch/arm/mach-at91/Kconfig |   44 ++
 arch/arm/mach-at91/Kconfig.non_dt  |6 +
 arch/arm/mach-at91/Makefile|2 +-
 arch/arm/mach-at91/at91rm9200.c|2 +-
 arch/arm/mach-at91/at91sam9260.c   |2 +-
 arch/arm/mach-at91/at91sam9261.c   |2 +-
 arch/arm/mach-at91/at91sam9263.c   |2 +-
 arch/arm/mach-at91/at91sam926x_time.c  |   14 +-
 arch/arm/mach-at91/at91sam9g45.c   |2 +-
 arch/arm/mach-at91/at91sam9n12.c   |2 +-
 arch/arm/mach-at91/at91sam9rl.c|2 +-
 arch/arm/mach-at91/at91sam9x5.c|2 +-
 arch/arm/mach-at91/clock.c |7 +-
 arch/arm/mach-at91/generic.h   |3 +-
 arch/arm/mach-at91/pm.c|2 +-
 arch/arm/mach-at91/pm_slowclock.S  |2 +-
 arch/arm/mach-at91/sama5d3.c   |2 +-
 arch/arm/mach-at91/setup.c |8 +-
 drivers/clk/Makefile   |1 +
 drivers/clk

[PATCH v5 03/17] clk: at91: add PMC base support

2013-11-12 Thread Boris BREZILLON
This patch adds at91 PMC (Power Management Controller) base support.

All at91 clocks managed by the PMC unit will use this framework.

This framework provides the following fonctionalities:
- define a new struct at91_pmc to hide PMC internals (lock, PMC memory
  mapping, irq domain, ...)
- read/write helper functions (pmc_read/write) to access PMC registers
- lock/unlock helper functions (pmc_lock/unlock) to lock/unlock access to
  pmc registers
- a new irq domain and its associated irq chip to request PMC specific
  interrupts (useful for clk prepare callbacks)

The PMC unit is declared as a dt clk provider (CLK_OF_DECLARE), and every
clk using this framework will declare a table of of_at91_clk_init_cb_t
and add it to the pmc_clk_ids table.

When the pmc dt clock setup function is called (by of_clk_init function),
it triggers the registration of every supported child clk (those matching
the definitions in pmc_clk_ids).

This patch copies at91_pmc_base (memory mapping) and at91sam9_idle
(function) from arch/arm/mach-at91/clock.c (which is not compiled if
COMMON_CLK_AT91 is enabled).

Signed-off-by: Boris BREZILLON 
Acked-by: Nicolas Ferre 
---
 drivers/clk/Makefile  |1 +
 drivers/clk/at91/Makefile |5 +
 drivers/clk/at91/pmc.c|  306 +
 drivers/clk/at91/pmc.h|   61 +
 4 files changed, 373 insertions(+)
 create mode 100644 drivers/clk/at91/Makefile
 create mode 100644 drivers/clk/at91/pmc.c
 create mode 100644 drivers/clk/at91/pmc.h

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 7b11106..28c2678 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
 obj-$(CONFIG_ARCH_ZYNQ)+= zynq/
 obj-$(CONFIG_ARCH_TEGRA)   += tegra/
 obj-$(CONFIG_PLAT_SAMSUNG) += samsung/
+obj-$(CONFIG_COMMON_CLK_AT91)  += at91/
 
 obj-$(CONFIG_X86)  += x86/
 
diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
new file mode 100644
index 000..1d4fb21
--- /dev/null
+++ b/drivers/clk/at91/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for at91 specific clk
+#
+
+obj-y += pmc.o
diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
new file mode 100644
index 000..c8a9a63
--- /dev/null
+++ b/drivers/clk/at91/pmc.c
@@ -0,0 +1,306 @@
+/*
+ * drivers/clk/at91/pmc.c
+ *
+ *  Copyright (C) 2013 Boris BREZILLON 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "pmc.h"
+
+void __iomem *at91_pmc_base;
+EXPORT_SYMBOL_GPL(at91_pmc_base);
+
+void at91sam9_idle(void)
+{
+   at91_pmc_write(AT91_PMC_SCDR, AT91_PMC_PCK);
+   cpu_do_idle();
+}
+
+int of_at91_get_clk_range(struct device_node *np, const char *propname,
+ struct clk_range *range)
+{
+   u32 min, max;
+   int ret;
+
+   ret = of_property_read_u32_index(np, propname, 0, &min);
+   if (ret)
+   return ret;
+
+   ret = of_property_read_u32_index(np, propname, 1, &max);
+   if (ret)
+   return ret;
+
+   if (range) {
+   range->min = min;
+   range->max = max;
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(of_at91_get_clk_range);
+
+static void pmc_irq_mask(struct irq_data *d)
+{
+   struct at91_pmc *pmc = irq_data_get_irq_chip_data(d);
+
+   pmc_write(pmc, AT91_PMC_IDR, 1 << d->hwirq);
+}
+
+static void pmc_irq_unmask(struct irq_data *d)
+{
+   struct at91_pmc *pmc = irq_data_get_irq_chip_data(d);
+
+   pmc_write(pmc, AT91_PMC_IER, 1 << d->hwirq);
+}
+
+static int pmc_irq_set_type(struct irq_data *d, unsigned type)
+{
+   if (type != IRQ_TYPE_LEVEL_HIGH) {
+   pr_warn("PMC: type not supported (support only 
IRQ_TYPE_LEVEL_HIGH type)\n");
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+static struct irq_chip pmc_irq = {
+   .name = "PMC",
+   .irq_disable = pmc_irq_mask,
+   .irq_mask = pmc_irq_mask,
+   .irq_unmask = pmc_irq_unmask,
+   .irq_set_type = pmc_irq_set_type,
+};
+
+static struct lock_class_key pmc_lock_class;
+
+static int pmc_irq_map(struct irq_domain *h, unsigned int virq,
+  irq_hw_number_t hw)
+{
+   struct at91_pmc *pmc = h->host_data;
+
+   irq_set_lockdep_class(virq, &pmc_lock_class);
+
+   irq_set_chip_and_handler(virq, &pmc_irq,
+handle_level_irq);
+   set_irq_flags(virq, IRQF_VALID);
+   irq_set_chip_data(virq, pmc);
+
+   return 0;
+}
+
+static int pmc_irq_domain_xlate(struct irq_domain *d,
+   struct device_node *ctrl

[PATCH v5 04/17] clk: at91: add PMC macro file for dt definitions

2013-11-12 Thread Boris BREZILLON
This patch adds a new macro file for PMC macros.

This macro file includes the definitions of SR (status register) bit
offsets and will be use to reference PMC irqs.

Signed-off-by: Boris BREZILLON 
Acked-by: Nicolas Ferre 
---
 include/dt-bindings/clk/at91.h |   22 ++
 1 file changed, 22 insertions(+)
 create mode 100644 include/dt-bindings/clk/at91.h

diff --git a/include/dt-bindings/clk/at91.h b/include/dt-bindings/clk/at91.h
new file mode 100644
index 000..0b4cb99
--- /dev/null
+++ b/include/dt-bindings/clk/at91.h
@@ -0,0 +1,22 @@
+/*
+ * This header provides constants for AT91 pmc status.
+ *
+ * The constants defined in this header are being used in dts.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef _DT_BINDINGS_CLK_AT91_H
+#define _DT_BINDINGS_CLK_AT91_H
+
+#define AT91_PMC_MOSCS 0   /* MOSCS Flag */
+#define AT91_PMC_LOCKA 1   /* PLLA Lock */
+#define AT91_PMC_LOCKB 2   /* PLLB Lock */
+#define AT91_PMC_MCKRDY3   /* Master Clock */
+#define AT91_PMC_LOCKU 6   /* UPLL Lock */
+#define AT91_PMC_PCKRDY(id)(8 + (id))  /* Programmable Clock */
+#define AT91_PMC_MOSCSELS  16  /* Main Oscillator Selection */
+#define AT91_PMC_MOSCRCS   17  /* Main On-Chip RC */
+#define AT91_PMC_CFDEV 18  /* Clock Failure Detector Event 
*/
+
+#endif
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 04/15] PM / Runtime: Allow drivers to intercept pm qos flag changes

2013-11-12 Thread Sarah Sharp
On Thu, Oct 24, 2013 at 05:42:13PM -0700, Dan Williams wrote:
> Hi Rafael, sorry about the email mix up.
> 
> On Thu, Oct 24, 2013 at 4:08 PM, Rafael J. Wysocki  wrote:
> >> > +
> >> > +What:  /sys/devices/.../power/pm_qos_no_notify_flags
> >> > +Date:  October 2013
> >> > +Contact:   Dan Williams 
> >> > +Description:
> >> > +   The /sys/devices/.../power/pm_qos_no_notify_flags 
> >> > attribute is
> >> > +   used for determining whether the kernel is permitted to 
> >> > forward
> >> > +   changes to the the PM QoS flags (no_power_off, 
> >> > remote_wakeup) to
> >> > +   other devices it deems to be related in the system.  
> >> > When this
> >> > +   flag is set userspace is indicating that it wants 
> >> > exclusive
> >> > +   control
> >
> > This is aganist the way the PM QoS flags were designed.  There is no 
> > exclusive
> > control over them and user space cannot expect specific behavior when one of
> > them is unset in sysfs.  Specifically, "no power off" unset doesn't mean 
> > "power
> > off is required".  It merely means "I have no objections against powering 
> > off
> > if that's what you decide to do".
> 
> 'Exclusive control' was the wrong choice of terms.  This admittedly
> ugly pm_qos_no_notify_flags flag would disable propagating the
> pm_qos_no_power_off setting to another device.
>
> The problem I am trying to solve is that deviceA can only safely be
> powered off depending on the state of deviceB.  The kernel knows this
> relationship and in most cases when userspace says "I don't have any
> objections to powering off deviceA it almost certainly means I have no
> objections to you coordinating poweroff of deviceA + deviceB".

So your plan was to automatically change the pm_qos_no_port_poweroff
flag for deviceB whenever userspace set deviceA pm_qos_no_port_poweroff?
And userspace could tell the kernel not to do that with the
pm_qos_no_notify_flags file?

> I could skip this flag and keep this knowledge internal.  I.e.
> userspace would just need to know that clearing pm_qos_no_power_off on
> deviceA will not enable power off until the same setting is performed
> on deviceB.  I do place a link from deviceA to deviceB in sysfs.

That seems to be the easier solution.  I suspect that what userspace
will do is clear pm_qos_no_power_off for all ports marked as hardwired,
and then never touch pm_qos_no_power_off again.  It seems like
unnecessary optimization to try to pair the two device states.

> Although ordering becomes trickier without notification...

What situations specifically are trickier?

> Alternatively I could just power manage deviceB behind userspace's
> back when taking action on deviceA, but I think that is even more of a
> hack and takes away configuration ability from userspace.

Yeah, I don't think that's a good idea.

Sarah Sharp
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 06/17] clk: at91: add PMC pll clocks

2013-11-12 Thread Boris BREZILLON
This patch adds new at91 pll clock implementation using common clk framework.

The pll clock layout describe the PLLX register layout.
There are four pll clock layouts:
- at91rm9200
- at91sam9g20
- at91sam9g45
- sama5d3

PLL clocks are given characteristics:
- min/max clock source rate
- ranges of valid clock output rates
- values to set in out and icpll fields for each supported output range

These characteristics are checked during rate change to avoid
over/underclocking.

These characteristics are described in atmel's SoC datasheet in
"Electrical Characteristics" paragraph.

Signed-off-by: Boris BREZILLON 
Acked-by: Nicolas Ferre 
---
 drivers/clk/at91/Makefile |2 +-
 drivers/clk/at91/clk-pll.c|  540 +
 drivers/clk/at91/clk-plldiv.c |  137 +++
 drivers/clk/at91/pmc.c|   21 ++
 drivers/clk/at91/pmc.h|   11 +
 include/linux/clk/at91_pmc.h  |2 +
 6 files changed, 712 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/at91/clk-pll.c
 create mode 100644 drivers/clk/at91/clk-plldiv.c

diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index 44105bd..902bbf1 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -3,4 +3,4 @@
 #
 
 obj-y += pmc.o
-obj-y += clk-main.o
+obj-y += clk-main.o clk-pll.o clk-plldiv.o
diff --git a/drivers/clk/at91/clk-pll.c b/drivers/clk/at91/clk-pll.c
new file mode 100644
index 000..57cedb5
--- /dev/null
+++ b/drivers/clk/at91/clk-pll.c
@@ -0,0 +1,540 @@
+/*
+ * drivers/clk/at91/clk-pll.c
+ *
+ *  Copyright (C) 2013 Boris BREZILLON 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "pmc.h"
+
+#define PLL_STATUS_MASK(id)(1 << (1 + (id)))
+#define PLL_REG(id)(AT91_CKGR_PLLAR + ((id) * 4))
+#define PLL_DIV_MASK   0xff
+#define PLL_DIV_MAXPLL_DIV_MASK
+#define PLL_DIV(reg)   ((reg) & PLL_DIV_MASK)
+#define PLL_MUL(reg, layout)   (((reg) >> (layout)->mul_shift) & \
+(layout)->mul_mask)
+#define PLL_ICPR_SHIFT(id) ((id) * 16)
+#define PLL_ICPR_MASK(id)  (0x << PLL_ICPR_SHIFT(id))
+#define PLL_MAX_COUNT  0x3ff
+#define PLL_COUNT_SHIFT8
+#define PLL_OUT_SHIFT  14
+#define PLL_MAX_ID 1
+
+struct clk_pll_characteristics {
+   struct clk_range input;
+   int num_output;
+   struct clk_range *output;
+   u16 *icpll;
+   u8 *out;
+};
+
+struct clk_pll_layout {
+   u32 pllr_mask;
+   u16 mul_mask;
+   u8 mul_shift;
+};
+
+#define to_clk_pll(hw) container_of(hw, struct clk_pll, hw)
+
+struct clk_pll {
+   struct clk_hw hw;
+   struct at91_pmc *pmc;
+   unsigned int irq;
+   wait_queue_head_t wait;
+   u8 id;
+   u8 div;
+   u8 range;
+   u16 mul;
+   const struct clk_pll_layout *layout;
+   const struct clk_pll_characteristics *characteristics;
+};
+
+static irqreturn_t clk_pll_irq_handler(int irq, void *dev_id)
+{
+   struct clk_pll *pll = (struct clk_pll *)dev_id;
+
+   wake_up(&pll->wait);
+   disable_irq_nosync(pll->irq);
+
+   return IRQ_HANDLED;
+}
+
+static int clk_pll_prepare(struct clk_hw *hw)
+{
+   struct clk_pll *pll = to_clk_pll(hw);
+   struct at91_pmc *pmc = pll->pmc;
+   const struct clk_pll_layout *layout = pll->layout;
+   u8 id = pll->id;
+   u32 mask = PLL_STATUS_MASK(id);
+   int offset = PLL_REG(id);
+   u8 out = 0;
+   u32 pllr, icpr;
+   u8 div;
+   u16 mul;
+
+   pllr = pmc_read(pmc, offset);
+   div = PLL_DIV(pllr);
+   mul = PLL_MUL(pllr, layout);
+
+   if ((pmc_read(pmc, AT91_PMC_SR) & mask) &&
+   (div == pll->div && mul == pll->mul))
+   return 0;
+
+   if (characteristics->out)
+   out = characteristics->out[pll->range];
+   if (characteristics->icpll) {
+   icpr = pmc_read(pmc, AT91_PMC_PLLICPR) & ~PLL_ICPR_MASK(id);
+   icpr |= (characteristics->icpll[pll->range] <<
+   PLL_ICPR_SHIFT(id));
+   pmc_write(pmc, AT91_PMC_PLLICPR, icpr);
+   }
+
+   pllr &= ~layout->pllr_mask;
+   pllr |= layout->pllr_mask &
+  (pll->div | (PLL_MAX_COUNT << PLL_COUNT_SHIFT) |
+   (out << PLL_OUT_SHIFT) |
+   ((pll->mul & layout->mul_mask) << layout->mul_shift));
+   pmc_write(pmc, offset, pllr);
+
+   while (!(pmc_read(pmc, AT91_PMC_SR) & mask)) {
+   enable_irq(pll->irq);
+   wait_event(pll->wait,
+  pmc_read(pmc, AT91_PMC_SR) & mask);
+   }

[PATCH v5 07/17] clk: at91: add PMC master clock

2013-11-12 Thread Boris BREZILLON
This patch adds new at91 master clock implementation using common clk
framework.

The master clock layout describe the MCKR register layout.
There are 2 master clock layouts:
- at91rm9200
- at91sam9x5

Master clocks are given characteristics:
- min/max clock output rate

These characteristics are checked during rate change to avoid
over/underclocking.

These characteristics are described in atmel's SoC datasheet in
"Electrical Characteristics" paragraph.

Signed-off-by: Boris BREZILLON 
Acked-by: Nicolas Ferre 
---
 drivers/clk/at91/Makefile |2 +-
 drivers/clk/at91/clk-master.c |  272 +
 drivers/clk/at91/clk-pll.c|   10 +-
 drivers/clk/at91/pmc.c|9 ++
 drivers/clk/at91/pmc.h|5 +
 5 files changed, 289 insertions(+), 9 deletions(-)
 create mode 100644 drivers/clk/at91/clk-master.c

diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index 902bbf1..e28fb2b 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -3,4 +3,4 @@
 #
 
 obj-y += pmc.o
-obj-y += clk-main.o clk-pll.o clk-plldiv.o
+obj-y += clk-main.o clk-pll.o clk-plldiv.o clk-master.o
diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c
new file mode 100644
index 000..65b81de
--- /dev/null
+++ b/drivers/clk/at91/clk-master.c
@@ -0,0 +1,272 @@
+/*
+ * drivers/clk/at91/clk-master.c
+ *
+ *  Copyright (C) 2013 Boris BREZILLON 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "pmc.h"
+
+#define MASTER_SOURCE_MAX  4
+
+#define MASTER_PRES_MASK   0x7
+#define MASTER_PRES_MAXMASTER_PRES_MASK
+#define MASTER_DIV_SHIFT   8
+#define MASTER_DIV_MASK0x3
+
+struct clk_master_characteristics {
+   struct clk_range output;
+   u32 divisors[4];
+   u8 have_div3_pres;
+};
+
+struct clk_master_layout {
+   u32 mask;
+   u8 pres_shift;
+};
+
+#define to_clk_master(hw) container_of(hw, struct clk_master, hw)
+
+struct clk_master {
+   struct clk_hw hw;
+   struct at91_pmc *pmc;
+   unsigned int irq;
+   wait_queue_head_t wait;
+   const struct clk_master_layout *layout;
+   const struct clk_master_characteristics *characteristics;
+};
+
+static irqreturn_t clk_master_irq_handler(int irq, void *dev_id)
+{
+   struct clk_master *master = (struct clk_master *)dev_id;
+
+   wake_up(&master->wait);
+   disable_irq_nosync(master->irq);
+
+   return IRQ_HANDLED;
+}
+static int clk_master_prepare(struct clk_hw *hw)
+{
+   struct clk_master *master = to_clk_master(hw);
+   struct at91_pmc *pmc = master->pmc;
+
+   while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MCKRDY)) {
+   enable_irq(master->irq);
+   wait_event(master->wait,
+  pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MCKRDY);
+   }
+
+   return 0;
+}
+
+static int clk_master_is_prepared(struct clk_hw *hw)
+{
+   struct clk_master *master = to_clk_master(hw);
+
+   return !!(pmc_read(master->pmc, AT91_PMC_SR) & AT91_PMC_MCKRDY);
+}
+
+static unsigned long clk_master_recalc_rate(struct clk_hw *hw,
+   unsigned long parent_rate)
+{
+   u8 pres;
+   u8 div;
+   unsigned long rate = parent_rate;
+   struct clk_master *master = to_clk_master(hw);
+   struct at91_pmc *pmc = master->pmc;
+   const struct clk_master_layout *layout = master->layout;
+   const struct clk_master_characteristics *characteristics =
+   master->characteristics;
+   u32 tmp;
+
+   pmc_lock(pmc);
+   tmp = pmc_read(pmc, AT91_PMC_MCKR) & layout->mask;
+   pmc_unlock(pmc);
+
+   pres = (tmp >> layout->pres_shift) & MASTER_PRES_MASK;
+   div = (tmp >> MASTER_DIV_SHIFT) & MASTER_DIV_MASK;
+
+   if (characteristics->have_div3_pres && pres == MASTER_PRES_MAX)
+   rate /= 3;
+   else
+   rate >>= pres;
+
+   rate /= characteristics->divisors[div];
+
+   if (rate < characteristics->output.min)
+   pr_warn("master clk is underclocked");
+   else if (rate > characteristics->output.max)
+   pr_warn("master clk is overclocked");
+
+   return rate;
+}
+
+static u8 clk_master_get_parent(struct clk_hw *hw)
+{
+   struct clk_master *master = to_clk_master(hw);
+   struct at91_pmc *pmc = master->pmc;
+
+   return pmc_read(pmc, AT91_PMC_MCKR) & AT91_PMC_CSS;
+}
+
+static const struct clk_ops master_ops = {
+   .prepare = clk_master_prepare,
+   .is_prepared = clk_master_is_prepared,
+   .recalc

[PATCH v5 05/17] clk: at91: add PMC main clock

2013-11-12 Thread Boris BREZILLON
This patch adds new at91 main oscillator clock implementation using common
clk framework.

If rate is not provided during clock registration it is calculated using
the slow clock (main clk parent in this case) rate and MCFR register.

Signed-off-by: Boris BREZILLON 
Acked-by: Nicolas Ferre 
---
 drivers/clk/at91/Makefile   |1 +
 drivers/clk/at91/clk-main.c |  189 +++
 drivers/clk/at91/pmc.c  |5 ++
 drivers/clk/at91/pmc.h  |3 +
 4 files changed, 198 insertions(+)
 create mode 100644 drivers/clk/at91/clk-main.c

diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index 1d4fb21..44105bd 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -3,3 +3,4 @@
 #
 
 obj-y += pmc.o
+obj-y += clk-main.o
diff --git a/drivers/clk/at91/clk-main.c b/drivers/clk/at91/clk-main.c
new file mode 100644
index 000..905ceff
--- /dev/null
+++ b/drivers/clk/at91/clk-main.c
@@ -0,0 +1,189 @@
+/*
+ * drivers/clk/at91/clk-main.c
+ *
+ *  Copyright (C) 2013 Boris BREZILLON 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "pmc.h"
+
+#define SLOW_CLOCK_FREQ32768
+#define MAINF_DIV  16
+#define MAINFRDY_TIMEOUT   (((MAINF_DIV + 1) * USEC_PER_SEC) / \
+SLOW_CLOCK_FREQ)
+#define MAINF_LOOP_MIN_WAIT(USEC_PER_SEC / SLOW_CLOCK_FREQ)
+#define MAINF_LOOP_MAX_WAITMAINFRDY_TIMEOUT
+
+struct clk_main {
+   struct clk_hw hw;
+   struct at91_pmc *pmc;
+   unsigned long rate;
+   unsigned int irq;
+   wait_queue_head_t wait;
+};
+
+#define to_clk_main(hw) container_of(hw, struct clk_main, hw)
+
+static irqreturn_t clk_main_irq_handler(int irq, void *dev_id)
+{
+   struct clk_main *clkmain = (struct clk_main *)dev_id;
+
+   wake_up(&clkmain->wait);
+   disable_irq_nosync(clkmain->irq);
+
+   return IRQ_HANDLED;
+}
+
+static int clk_main_prepare(struct clk_hw *hw)
+{
+   struct clk_main *clkmain = to_clk_main(hw);
+   struct at91_pmc *pmc = clkmain->pmc;
+   unsigned long halt_time, timeout;
+   u32 tmp;
+
+   while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCS)) {
+   enable_irq(clkmain->irq);
+   wait_event(clkmain->wait,
+  pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCS);
+   }
+
+   if (clkmain->rate)
+   return 0;
+
+   timeout = jiffies + usecs_to_jiffies(MAINFRDY_TIMEOUT);
+   do {
+   halt_time = jiffies;
+   tmp = pmc_read(pmc, AT91_CKGR_MCFR);
+   if (tmp & AT91_PMC_MAINRDY)
+   return 0;
+   usleep_range(MAINF_LOOP_MIN_WAIT, MAINF_LOOP_MAX_WAIT);
+   } while (time_before(halt_time, timeout));
+
+   return 0;
+}
+
+static int clk_main_is_prepared(struct clk_hw *hw)
+{
+   struct clk_main *clkmain = to_clk_main(hw);
+
+   return !!(pmc_read(clkmain->pmc, AT91_PMC_SR) & AT91_PMC_MOSCS);
+}
+
+static unsigned long clk_main_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+   u32 tmp;
+   struct clk_main *clkmain = to_clk_main(hw);
+   struct at91_pmc *pmc = clkmain->pmc;
+
+   if (clkmain->rate)
+   return clkmain->rate;
+
+   tmp = pmc_read(pmc, AT91_CKGR_MCFR) & AT91_PMC_MAINF;
+   clkmain->rate = (tmp * parent_rate) / MAINF_DIV;
+
+   return clkmain->rate;
+}
+
+static const struct clk_ops main_ops = {
+   .prepare = clk_main_prepare,
+   .is_prepared = clk_main_is_prepared,
+   .recalc_rate = clk_main_recalc_rate,
+};
+
+static struct clk * __init
+at91_clk_register_main(struct at91_pmc *pmc,
+  unsigned int irq,
+  const char *name,
+  const char *parent_name,
+  unsigned long rate)
+{
+   int ret;
+   struct clk_main *clkmain;
+   struct clk *clk = NULL;
+   struct clk_init_data init;
+
+   if (!pmc || !irq || !name)
+   return ERR_PTR(-EINVAL);
+
+   if (!rate && !parent_name)
+   return ERR_PTR(-EINVAL);
+
+   clkmain = kzalloc(sizeof(*clkmain), GFP_KERNEL);
+   if (!clkmain)
+   return ERR_PTR(-ENOMEM);
+
+   init.name = name;
+   init.ops = &main_ops;
+   init.parent_names = parent_name ? &parent_name : NULL;
+   init.num_parents = parent_name ? 1 : 0;
+   init.flags = parent_name ? 0 : CLK_IS_ROOT;
+
+   clkmain->hw.init = &init;
+   clkmain->rate = rate;
+   clkmain->pmc = pmc;
+   clkmain->irq = irq;
+   init

[PATCH v5 08/17] clk: at91: add PMC system clocks

2013-11-12 Thread Boris BREZILLON
This patch adds new at91 system clock implementation using common clk
framework.

Some peripherals need to enable a "system" clock in order to work properly.
Each system clock is given an id based on the bit position in SCER/SCDR
registers.

Signed-off-by: Boris BREZILLON 
Acked-by: Nicolas Ferre 
---
 drivers/clk/at91/Makefile |1 +
 drivers/clk/at91/clk-system.c |  137 +
 drivers/clk/at91/pmc.c|5 ++
 drivers/clk/at91/pmc.h|3 +
 4 files changed, 146 insertions(+)
 create mode 100644 drivers/clk/at91/clk-system.c

diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index e28fb2b..c2b7068 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -4,3 +4,4 @@
 
 obj-y += pmc.o
 obj-y += clk-main.o clk-pll.o clk-plldiv.o clk-master.o
+obj-y += clk-system.o
diff --git a/drivers/clk/at91/clk-system.c b/drivers/clk/at91/clk-system.c
new file mode 100644
index 000..1c086f4
--- /dev/null
+++ b/drivers/clk/at91/clk-system.c
@@ -0,0 +1,137 @@
+/*
+ * drivers/clk/at91/clk-system.c
+ *
+ *  Copyright (C) 2013 Boris BREZILLON 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "pmc.h"
+
+#define SYSTEM_MAX_ID  31
+
+#define SYSTEM_MAX_NAME_SZ 32
+
+#define to_clk_system(hw) container_of(hw, struct clk_system, hw)
+struct clk_system {
+   struct clk_hw hw;
+   struct at91_pmc *pmc;
+   u8 id;
+};
+
+static int clk_system_enable(struct clk_hw *hw)
+{
+   struct clk_system *sys = to_clk_system(hw);
+   struct at91_pmc *pmc = sys->pmc;
+
+   pmc_write(pmc, AT91_PMC_SCER, 1 << sys->id);
+   return 0;
+}
+
+static void clk_system_disable(struct clk_hw *hw)
+{
+   struct clk_system *sys = to_clk_system(hw);
+   struct at91_pmc *pmc = sys->pmc;
+
+   pmc_write(pmc, AT91_PMC_SCDR, 1 << sys->id);
+}
+
+static int clk_system_is_enabled(struct clk_hw *hw)
+{
+   struct clk_system *sys = to_clk_system(hw);
+   struct at91_pmc *pmc = sys->pmc;
+
+   return !!(pmc_read(pmc, AT91_PMC_SCSR) & (1 << sys->id));
+}
+
+static const struct clk_ops system_ops = {
+   .enable = clk_system_enable,
+   .disable = clk_system_disable,
+   .is_enabled = clk_system_is_enabled,
+};
+
+static struct clk * __init
+at91_clk_register_system(struct at91_pmc *pmc, const char *name,
+const char *parent_name, u8 id)
+{
+   struct clk_system *sys;
+   struct clk *clk = NULL;
+   struct clk_init_data init;
+
+   if (!parent_name || id > SYSTEM_MAX_ID)
+   return ERR_PTR(-EINVAL);
+
+   sys = kzalloc(sizeof(*sys), GFP_KERNEL);
+   if (!sys)
+   return ERR_PTR(-ENOMEM);
+
+   init.name = name;
+   init.ops = &system_ops;
+   init.parent_names = &parent_name;
+   init.num_parents = 1;
+   /*
+* CLK_IGNORE_UNUSED is used to avoid ddrck switch off.
+* TODO : we should implement a driver supporting at91 ddr controller
+* (see drivers/memory) which would request and enable the ddrck clock.
+* When this is done we will be able to remove CLK_IGNORE_UNUSED flag.
+*/
+   init.flags = CLK_IGNORE_UNUSED;
+
+   sys->id = id;
+   sys->hw.init = &init;
+   sys->pmc = pmc;
+
+   clk = clk_register(NULL, &sys->hw);
+   if (IS_ERR(clk))
+   kfree(sys);
+
+   return clk;
+}
+
+static void __init
+of_at91_clk_sys_setup(struct device_node *np, struct at91_pmc *pmc)
+{
+   int num;
+   u32 id;
+   struct clk *clk;
+   const char *name;
+   struct device_node *sysclknp;
+   const char *parent_name;
+
+   num = of_get_child_count(np);
+   if (num > (SYSTEM_MAX_ID + 1))
+   return;
+
+   for_each_child_of_node(np, sysclknp) {
+   if (of_property_read_u32(sysclknp, "reg", &id))
+   continue;
+
+   if (of_property_read_string(np, "clock-output-names", &name))
+   name = sysclknp->name;
+
+   parent_name = of_clk_get_parent_name(sysclknp, 0);
+
+   clk = at91_clk_register_system(pmc, name, parent_name, id);
+   if (IS_ERR(clk))
+   continue;
+
+   of_clk_add_provider(sysclknp, of_clk_src_simple_get, clk);
+   }
+}
+
+void __init of_at91rm9200_clk_sys_setup(struct device_node *np,
+   struct at91_pmc *pmc)
+{
+   of_at91_clk_sys_setup(np, pmc);
+}
diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index d9975e7..6adc5be 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -266,6 +266,11 @@ static const st

[PATCH v5 09/17] clk: at91: add PMC peripheral clocks

2013-11-12 Thread Boris BREZILLON
This patch adds new at91 peripheral clock implementation using common clk
framework.

Almost all peripherals provided by at91 SoCs need a clock to work properly.
This clock is enabled/disabled using PCER/PCDR resgisters.

Each peripheral is given an id (see atmel's datasheets) which is used to
define and reference peripheral clocks.

Some new SoCs (at91sam9x5 and sama5d3) provide a new register (PCR) where you
can configure the peripheral clock as a division of the master clock.
This will help reducing the peripherals power comsumption.

Signed-off-by: Boris BREZILLON 
Acked-by: Nicolas Ferre 
---
 drivers/clk/at91/Makefile |2 +-
 drivers/clk/at91/clk-peripheral.c |  412 +
 drivers/clk/at91/pmc.c|9 +
 drivers/clk/at91/pmc.h|5 +
 4 files changed, 427 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/at91/clk-peripheral.c

diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index c2b7068..04deba3 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -4,4 +4,4 @@
 
 obj-y += pmc.o
 obj-y += clk-main.o clk-pll.o clk-plldiv.o clk-master.o
-obj-y += clk-system.o
+obj-y += clk-system.o clk-peripheral.o
diff --git a/drivers/clk/at91/clk-peripheral.c 
b/drivers/clk/at91/clk-peripheral.c
new file mode 100644
index 000..15c9518
--- /dev/null
+++ b/drivers/clk/at91/clk-peripheral.c
@@ -0,0 +1,412 @@
+/*
+ * drivers/clk/at91/clk-peripheral.c
+ *
+ *  Copyright (C) 2013 Boris BREZILLON 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "pmc.h"
+
+#define PERIPHERAL_MAX 64
+
+#define PERIPHERAL_AT91RM9200  0
+#define PERIPHERAL_AT91SAM9X5  1
+
+#define PERIPHERAL_ID_MIN  2
+#define PERIPHERAL_ID_MAX  31
+#define PERIPHERAL_MASK(id)(1 << ((id) & PERIPHERAL_ID_MAX))
+
+#define PERIPHERAL_RSHIFT_MASK 0x3
+#define PERIPHERAL_RSHIFT(val) (((val) >> 16) & PERIPHERAL_RSHIFT_MASK)
+
+#define PERIPHERAL_MAX_SHIFT   4
+
+struct clk_peripheral {
+   struct clk_hw hw;
+   struct at91_pmc *pmc;
+   u32 id;
+};
+
+#define to_clk_peripheral(hw) container_of(hw, struct clk_peripheral, hw)
+
+struct clk_sam9x5_peripheral {
+   struct clk_hw hw;
+   struct at91_pmc *pmc;
+   struct clk_range range;
+   u32 id;
+   u32 div;
+   bool auto_div;
+};
+
+#define to_clk_sam9x5_peripheral(hw) \
+   container_of(hw, struct clk_sam9x5_peripheral, hw)
+
+static int clk_peripheral_enable(struct clk_hw *hw)
+{
+   struct clk_peripheral *periph = to_clk_peripheral(hw);
+   struct at91_pmc *pmc = periph->pmc;
+   int offset = AT91_PMC_PCER;
+   u32 id = periph->id;
+
+   if (id < PERIPHERAL_ID_MIN)
+   return 0;
+   if (id > PERIPHERAL_ID_MAX)
+   offset = AT91_PMC_PCER1;
+   pmc_write(pmc, offset, PERIPHERAL_MASK(id));
+   return 0;
+}
+
+static void clk_peripheral_disable(struct clk_hw *hw)
+{
+   struct clk_peripheral *periph = to_clk_peripheral(hw);
+   struct at91_pmc *pmc = periph->pmc;
+   int offset = AT91_PMC_PCDR;
+   u32 id = periph->id;
+
+   if (id < PERIPHERAL_ID_MIN)
+   return;
+   if (id > PERIPHERAL_ID_MAX)
+   offset = AT91_PMC_PCDR1;
+   pmc_write(pmc, offset, PERIPHERAL_MASK(id));
+}
+
+static int clk_peripheral_is_enabled(struct clk_hw *hw)
+{
+   struct clk_peripheral *periph = to_clk_peripheral(hw);
+   struct at91_pmc *pmc = periph->pmc;
+   int offset = AT91_PMC_PCSR;
+   u32 id = periph->id;
+
+   if (id < PERIPHERAL_ID_MIN)
+   return 1;
+   if (id > PERIPHERAL_ID_MAX)
+   offset = AT91_PMC_PCSR1;
+   return !!(pmc_read(pmc, offset) & PERIPHERAL_MASK(id));
+}
+
+static const struct clk_ops peripheral_ops = {
+   .enable = clk_peripheral_enable,
+   .disable = clk_peripheral_disable,
+   .is_enabled = clk_peripheral_is_enabled,
+};
+
+static struct clk * __init
+at91_clk_register_peripheral(struct at91_pmc *pmc, const char *name,
+const char *parent_name, u32 id)
+{
+   struct clk_peripheral *periph;
+   struct clk *clk = NULL;
+   struct clk_init_data init;
+
+   if (!pmc || !name || !parent_name || id > PERIPHERAL_ID_MAX)
+   return ERR_PTR(-EINVAL);
+
+   periph = kzalloc(sizeof(*periph), GFP_KERNEL);
+   if (!periph)
+   return ERR_PTR(-ENOMEM);
+
+   init.name = name;
+   init.ops = &peripheral_ops;
+   init.parent_names = (parent_name ? &parent_name : NULL);
+   init.num_parents = (parent_name ? 1 : 0);
+   init.flags = 0;
+
+   periph->id = id;
+   periph->hw.init = &in

Re: [RFC PATCH 00/15] rework port power control

2013-11-12 Thread Sarah Sharp
On Mon, Oct 28, 2013 at 06:49:37PM -0700, Dan Williams wrote:
> On Sat, Oct 26, 2013 at 7:40 AM, Alan Stern  wrote:
> > On Fri, 25 Oct 2013, Dan Williams wrote:
> >> > This patch set makes a large number of significant changes to important
> >> > and subtle aspects of the USB stack.  It would be a lot easier to
> >> > discuss in pieces; I can't possibly review the whole series in a
> >> > reasonable time.
> >> >
> >> > And I wish the basic approach had been discussed beforehand...  Some of
> >> > the ideas are quite nice, but there are a lot of details that need
> >> > close attention.
> >>
> >> I wanted to at least have a working implementation that tackled the
> >> peer disconnect case, I did not expect 15 patches to fall out of that.
> >>  However, after talking through this I think it can be abbreviated.
> >
> > Yes.  It looks like we're talking about several major changes:
> >
> > Redefining what it means for a port to be in runtime suspend.
> >
> > Rearranging the device model tree.
> >
> > Implementing connectors.
> >
> > Changing the port-power-off policy.
> >
> > The patch set also changes khubd into a workqueue, but now it looks
> > like we don't need to do that (although I'm not ruling it out as a
> > future clean-up).
> >
> > Does this leave anything out?
> 
> No, but that last one can be subdivided into:
>  - implement hotplug vs hardwired policy

I think the original agreement when the USB 2.0 port power off work
went in was that hotplug vs hardwired shouldn't make a difference in the
kernel.  It would be up to userspace to read the port connection type,
and decide whether to enable port power off.

What in-kernel policy were you thinking of?

>  - consider/handle connector peers in port power policy
> 
> >> In the existing code at usb_port_runtime_resume() time we know the
> >> port is off.  By calling usb_autopm_get_interface(intf) before turning
> >> on the power we are simply causing an unnecessary check of the port
> >> status registers.  We do have the power_is_on check to block
> >> hub_activate() from setting the change_bits, but that was not enough
> >> to prevent khubd from triggering a disconnect.
> >
> > In fact, the reason for calling usb_autopm_get_interface was to prevent
> > the hub from being suspended while we change the port's power state.
> > Something like this may still be needed.
> >
> 
> With the device model change and no longer telling the hub interface
> device to pm_suspend_ignore_children() the pm subsystem will manage
> this wake up for us.
> 
> > Have you considered what would happen if the user changed the port's
> > pm_qos setting while the port was suspended?  Ideally, such changes
> > should immediately affect the port's power state.  For example, if the
> > port was suspended with power off when the user sets the no_power_off
> > flag, we should immediately turn port power back on.  I don't know if
> > the PM QoS design permits this sort of thing, though.
> >
> 
> Yes, every flag change triggers a wake up of the port and, as a
> pre-requisite, its parent hub.
> 
> >> > You should also explain at the start of the description what you mean
> >> > by related (or peer) ports.  Then the idea of a connector is clear --
> >> > although I got the impression that the implementation may be a little
> >> > over-engineered.
> >>
> >> Hence the RFC, yes, not opposed to backing up and simplifying this.
> >
> > Since a port never needs to be connected to more than one other port,
> > you could implement connectors simply by storing a "peer" pointer in
> > the usb_port structure.
> 
> Yes, no need to design for the non-existent 3 connection types in a
> port case now.
> 
> Another simplification is that a "struct usb_domain" is currently
> known to never span a controller boundary.  So, rather than adding
> ports to a usb_connector / usb_domain container hierarchy I think we
> can simply scan the child devices under the xhci device and look for
> is_usb_port() instances.
> 
> In the meantime I am still thinking of the approach to reliably link
> USB3 hub ports to their peers.  The spec mandates that they be
> labelled the same for this purpose (USB3 spec section 10.3.3).

The USB 3.0 specification does provide a way to uniquely identify a USB
3.0 hub and its paired USB 2.0 hub.  That's in the Container ID BOS
descriptor described in section 9.6.2.3.  Each USB hub manufactured by a
vendor is supposed to provide a unique ID in order for the OS to pair
the USB 2.0 and USB 3.0 hubs.

However, just like the Device descriptor serial number, very few USB 3.0
hubs actually set the Container ID.  They have the BOS descriptor (since
they need it to pass compliance testing), but they set it to all zeros
or 1234567890...  It's basically useless.

> However, to determine peer relationships for downstream hubs I think
> we will need walk the hierarchy back to the root connector and compare
> paths.  Tier mismatch makes it so we can not look at the path ba

RE: [PATCHv2 2/2] check quirk to pad epout buf size when not aligned to maxpacketsize

2013-11-12 Thread Paul Zimmerman
> From: linux-usb-ow...@vger.kernel.org 
> [mailto:linux-usb-ow...@vger.kernel.org] On Behalf Of Alan Stern
> Sent: Tuesday, November 12, 2013 7:51 AM
> 
> On Mon, 11 Nov 2013, David Cohen wrote:
> 
> > Hi Alan, Michal,
> >
> > On 11/11/2013 01:09 PM, Michal Nazarewicz wrote:
> > > On Mon, Nov 11 2013, Alan Stern wrote:
> > >> On Mon, 11 Nov 2013, Michal Nazarewicz wrote:
> > >>
> > >>> Check gadget.quirk_ep_out_aligned_size to decide if buffer size requires
> > >>> to be aligned to maxpacketsize of an out endpoint.  ffs_epfile_io() 
> > >>> needs
> > >>> to pad epout buffer to match above condition if quirk is found.
> > >>>
> > >>> Signed-off-by: Michal Nazarewicz 
> > >>
> > >> I think this is still wrong.
> > >>
> > >>> @@ -824,7 +832,7 @@ static ssize_t ffs_epfile_io(struct file *file,
> > >>> req->context  = &done;
> > >>> req->complete = ffs_epfile_io_complete;
> > >>> req->buf  = data;
> > >>> -   req->length   = len;
> > >>> +   req->length   = data_len;
> > >>
> > >> IIUC, req->length should still be set to len, not to data_len.
> >
> > I misunderstood the first time I read it:
> > In order to avoid DWC3 to stall, we need to update req->length (this is
> > the most important fix). kmalloc() is updated too to prevent USB
> > controller to overflow buffer boundaries.
> 
> Here I disagree.
> 
> If the DWC3 hardware stalls, it is up to the DWC3 UDC driver to fix it.
> Gadget drivers should not have to worry.  Most especially, gadget
> drivers should not lie about a request length.

The whole point of this quirk is to lie to the DWC3 driver. The quirk is
only enabled for the DWC3 driver.

> If the UDC driver decides to round up req->length before sending it to
> the hardware, that's okay.

Not really. If the DWC3 driver unconditionally rounds up req->length,
then in the case where the buffer has not been expanded to a multiple of
maxpacket, by this quirk or otherwise, there is the potential to write
beyond the end of the allocation.

If we do what you suggest, then all the gadgets will have to be audited
to make sure an OUT buffer with a non-aligned length is never passed to
the DWC3 driver.

I still think that's the best solution anyway. Just make that the rule,
and then there is no need for this quirk at all. And there is no need to
round up req->length in the DWC3 driver either.

> But req->length should be set to len, not data_len.

According to gadget.h:

@buf: Buffer used for data
@length: Length of that data

So why shouldn't length be the length of the allocated data buffer?
Remember, this is for the OUT direction only, so the host has control
over how much data is actually sent. You could even argue that an OUT
data buffer should always be a multiple of the max packet size, given
how USB works.

> And if the hardware receives more than len bytes of data,
> the UDC driver should set req->status to -EOVERFLOW.

That would be nice, but I don't see how to accomplish that given the
above.

-- 
Paul

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: xhci ring expansion

2013-11-12 Thread Sarah Sharp
On Thu, Oct 31, 2013 at 04:16:14PM -, David Laight wrote:
> Code was recently added to the xhci driver to dynamically add extra ring
> segments if there is insufficient space for all the fragments of the
> URB being sent.
> 
> ISTM that it would be better to just queue the URB (on the ring)
> and process it when space becomes available.

Hmm, better why?  I'm reluctant to touch code that Just Works (TM).
Especially anything having do with the xHCI ring code, since it's quite
complex.

> This wouldn't solve the problem of pathologically badly fragmented,
> or very long URB, but there are simpler solutions to that.
> 
> I believe that very long bulk transfers can be split into
> separate TD on USB block boundaries - so they can be safely
> added to the ring in several pieces.

No, that's not a good idea.  Think about the case where the device
driver sets up an IN transfer to receive a specific amount of data from
the device.  The device can choose to send less data, resulting in a
short packet TD completion event.

If you queue the URB as one TD, when the short packet occurs, the host
returns the short status, and stops requesting any further packets from
the device.  It then goes on to process the next TD in the ring.

Now, assume you queue the URB as multiple TDs.  Say you split the URB
into five TDs, and the short packet occurs on TD three.  The host will
return a short packet completion event, and then go on to request data
from the device for TDs four and five.  This is not what you want,
because it changes the bus behavior.

> I don't know if any other data type is allowed to exceed the
> block length?
> 
> Badly fragmented URB are probably best copied into a linear buffer.
> 
> This would make the code a lot simpler, especially since the
> tx setup could be started if there were a 'reasonable' number
> of free entries in the TRB ring without having to calculate
> the actual number needed (and 
> 
> Additionally it would make it possible to ensure that LINK TRB
> only happen on the appropriate boundary. This might require
> some fragments be copied to a linear buffer.
> 
> If this is a reasonable idea I'll volunteer to do the changes.
> We are seeing some issues with the xhci driver, and parts of it
> are just to contorted!

The code is complex, especially the interaction between the code to
queue to the xHCI rings, the URB cancellation code, and the command ring
cancellation code.  Any big changes like this would be bound to
introduce new bugs.

Frankly, since these are your first kernel patches, I can't trust any
big sweeping changes you make unless I can throughly understand them.
That's just a fact about being a kernel maintainer; I have to understand
the code that gets contributed because the contributor is highly likely
to disappear, leaving me to fix bugs in their code years later.

So, I would recommend you work on small fixes and earn my trust before
making big sweeping changes.  Let's get the scatter gather issue fixed
before you completely re-architect the xHCI driver, okay? :)

Sarah Sharp
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCHv2 2/2] check quirk to pad epout buf size when not aligned to maxpacketsize

2013-11-12 Thread David Cohen

Hi Paul,

On 11/12/2013 03:09 PM, Paul Zimmerman wrote:

From: linux-usb-ow...@vger.kernel.org [mailto:linux-usb-ow...@vger.kernel.org] 
On Behalf Of Alan Stern
Sent: Tuesday, November 12, 2013 7:51 AM

On Mon, 11 Nov 2013, David Cohen wrote:


Hi Alan, Michal,

On 11/11/2013 01:09 PM, Michal Nazarewicz wrote:

On Mon, Nov 11 2013, Alan Stern wrote:

On Mon, 11 Nov 2013, Michal Nazarewicz wrote:


Check gadget.quirk_ep_out_aligned_size to decide if buffer size requires
to be aligned to maxpacketsize of an out endpoint.  ffs_epfile_io() needs
to pad epout buffer to match above condition if quirk is found.

Signed-off-by: Michal Nazarewicz 


I think this is still wrong.


@@ -824,7 +832,7 @@ static ssize_t ffs_epfile_io(struct file *file,
req->context  = &done;
req->complete = ffs_epfile_io_complete;
req->buf  = data;
-   req->length   = len;
+   req->length   = data_len;


IIUC, req->length should still be set to len, not to data_len.


I misunderstood the first time I read it:
In order to avoid DWC3 to stall, we need to update req->length (this is
the most important fix). kmalloc() is updated too to prevent USB
controller to overflow buffer boundaries.


Here I disagree.

If the DWC3 hardware stalls, it is up to the DWC3 UDC driver to fix it.
Gadget drivers should not have to worry.  Most especially, gadget
drivers should not lie about a request length.


The whole point of this quirk is to lie to the DWC3 driver. The quirk is
only enabled for the DWC3 driver.


If the UDC driver decides to round up req->length before sending it to
the hardware, that's okay.


Not really. If the DWC3 driver unconditionally rounds up req->length,
then in the case where the buffer has not been expanded to a multiple of
maxpacket, by this quirk or otherwise, there is the potential to write
beyond the end of the allocation.

If we do what you suggest, then all the gadgets will have to be audited
to make sure an OUT buffer with a non-aligned length is never passed to
the DWC3 driver.


I was really convinced about not updating rep->length was a better idea
until I read this argument of yours: with this approach buffer overflow
can silently happen.



I still think that's the best solution anyway. Just make that the rule,
and then there is no need for this quirk at all. And there is no need to
round up req->length in the DWC3 driver either.


I'd have nothing against that, but I'm not sure how it would affect
other environments, given embedded environments are pretty sensitive to
memory consumption (and performance).




But req->length should be set to len, not data_len.


According to gadget.h:

@buf: Buffer used for data
@length: Length of that data

So why shouldn't length be the length of the allocated data buffer?
Remember, this is for the OUT direction only, so the host has control
over how much data is actually sent. You could even argue that an OUT
data buffer should always be a multiple of the max packet size, given
how USB works.


How about something like this, to let USB controllers to know about
whole allocated memory and avoid hidden overflows. Does that make sense
to you?

diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 25a5007f92e3..973b57b709ab 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -31,13 +31,16 @@ struct usb_ep;
  * struct usb_request - describes one i/o request
  * @buf: Buffer used for data.  Always provide this; some controllers
  * only use PIO, or don't use DMA for some endpoints.
+ * @length: Length of that data
+ * @buf_pad: Some USB controllers may need to pad buffer size due to 
alignment
+ * constraints. This keeps track of how much memory was allocated 
to @buf

+ * in addition to @length.
  * @dma: DMA address corresponding to 'buf'.  If you don't set this
  * field, and the usb controller needs one, it is responsible
  * for mapping and unmapping the buffer.
  * @sg: a scatterlist for SG-capable controllers.
  * @num_sgs: number of SG entries
  * @num_mapped_sgs: number of SG entries mapped to DMA (internal)
- * @length: Length of that data
  * @stream_id: The stream id, when USB3.0 bulk streams are being used
  * @no_interrupt: If true, hints that no completion irq is needed.
  * Helpful sometimes with deep request queues that are handled
@@ -91,6 +94,7 @@ struct usb_ep;
 struct usb_request {
void*buf;
unsignedlength;
+   unsignedbuf_pad;
dma_addr_t  dma;

struct scatterlist  *sg;


Br, David Cohen
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCHv2 2/2] check quirk to pad epout buf size when not aligned to maxpacketsize

2013-11-12 Thread Paul Zimmerman
> From: David Cohen [mailto:david.a.co...@linux.intel.com]
> Sent: Tuesday, November 12, 2013 3:44 PM
> 
> On 11/12/2013 03:09 PM, Paul Zimmerman wrote:
> 
> >> From: linux-usb-ow...@vger.kernel.org 
> >> [mailto:linux-usb-ow...@vger.kernel.org] On Behalf Of Alan Stern
> >> Sent: Tuesday, November 12, 2013 7:51 AM
> >>
> >> On Mon, 11 Nov 2013, David Cohen wrote:
> >>
> >>> In order to avoid DWC3 to stall, we need to update req->length (this is
> >>> the most important fix). kmalloc() is updated too to prevent USB
> >>> controller to overflow buffer boundaries.
> >>
> >> Here I disagree.
> >>
> >> If the DWC3 hardware stalls, it is up to the DWC3 UDC driver to fix it.
> >> Gadget drivers should not have to worry.  Most especially, gadget
> >> drivers should not lie about a request length.
> >
> > The whole point of this quirk is to lie to the DWC3 driver. The quirk is
> > only enabled for the DWC3 driver.
> >
> >> If the UDC driver decides to round up req->length before sending it to
> >> the hardware, that's okay.
> >
> > Not really. If the DWC3 driver unconditionally rounds up req->length,
> > then in the case where the buffer has not been expanded to a multiple of
> > maxpacket, by this quirk or otherwise, there is the potential to write
> > beyond the end of the allocation.
> >
> > If we do what you suggest, then all the gadgets will have to be audited
> > to make sure an OUT buffer with a non-aligned length is never passed to
> > the DWC3 driver.
> 
> I was really convinced about not updating rep->length was a better idea
> until I read this argument of yours: with this approach buffer overflow
> can silently happen.
> 
> >
> > I still think that's the best solution anyway. Just make that the rule,
> > and then there is no need for this quirk at all. And there is no need to
> > round up req->length in the DWC3 driver either.
> 
> I'd have nothing against that, but I'm not sure how it would affect
> other environments, given embedded environments are pretty sensitive to
> memory consumption (and performance).

There would be no performance impact. The memory impact would be less than
1024 bytes per OUT ep (worst case), and most gadget devices only have a
couple of OUT eps. I don't think it's a problem.

> >
> >> But req->length should be set to len, not data_len.
> >
> > According to gadget.h:
> >
> > @buf: Buffer used for data
> > @length: Length of that data
> >
> > So why shouldn't length be the length of the allocated data buffer?
> > Remember, this is for the OUT direction only, so the host has control
> > over how much data is actually sent. You could even argue that an OUT
> > data buffer should always be a multiple of the max packet size, given
> > how USB works.
> 
> How about something like this, to let USB controllers to know about
> whole allocated memory and avoid hidden overflows. Does that make sense
> to you?
> 
> diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
> index 25a5007f92e3..973b57b709ab 100644
> --- a/include/linux/usb/gadget.h
> +++ b/include/linux/usb/gadget.h
> @@ -31,13 +31,16 @@ struct usb_ep;
>* struct usb_request - describes one i/o request
>* @buf: Buffer used for data.  Always provide this; some controllers
>* only use PIO, or don't use DMA for some endpoints.
> + * @length: Length of that data
> + * @buf_pad: Some USB controllers may need to pad buffer size due to
> alignment
> + * constraints. This keeps track of how much memory was allocated
> to @buf
> + * in addition to @length.
>* @dma: DMA address corresponding to 'buf'.  If you don't set this
>* field, and the usb controller needs one, it is responsible
>* for mapping and unmapping the buffer.
>* @sg: a scatterlist for SG-capable controllers.
>* @num_sgs: number of SG entries
>* @num_mapped_sgs: number of SG entries mapped to DMA (internal)
> - * @length: Length of that data
>* @stream_id: The stream id, when USB3.0 bulk streams are being used
>* @no_interrupt: If true, hints that no completion irq is needed.
>* Helpful sometimes with deep request queues that are handled
> @@ -91,6 +94,7 @@ struct usb_ep;
>   struct usb_request {
>  void*buf;
>  unsignedlength;
> +   unsignedbuf_pad;
>  dma_addr_t  dma;
> 
>  struct scatterlist  *sg;

Yes, I think that would work. But you only need 11 bits or so for
buf_pad, so make it 'unsigned buf_pad:11" and move it down with the
rest of the bitfields.

And you could also report -EOVERFLOW in the DWC3 driver, as Alan
suggested, if the received data is more than 'length'.

-- 
Paul

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V2] usbnet: fix race condition caused spinlock bad magic issue

2013-11-12 Thread wangbiao
From: wang, biao 
Date: Mon, 11 Nov 2013 10:23:40 +0800
Subject: [PATCH] usbnet: fix race condition caused spinlock bad magic issue

1, there is race between usbnet_terminate_urbs and usbnet_bh, when
unlink_wakeup used in usbnet_bh, it may be already freed and used by
other function as unlink_wakeup was a local var on stack.
for example:
cpu 0:  cpu 1:
usb_suspend_both
->usbnet_suspend
usbnet_bh   ->usbnet_terminate_urbs
->__wake_up
->_raw_spin_unlock_irqrestore
->do_raw_spin_unlock
->spin_bug
when usbnet_terminate_urbs complete execution and memory of unlink_wakeup was
used by other function, then usbnet_bh may still use it.

2, for the same reason,dev->wait should be judged again before use it,
as between the judge point(if(dev->wait)) and use point(wakeup(dev->wait)),
the dev->wait may be set NULL by another cpu.

for issue 1, declare  unlink_wakeup in global section instead of on stack.
for issue 2, use a temporary local var to keep the value of dev->wait
in stack and judge it before using.

Signed-off-by: wang, biao 
Acked-by: Ingo Molnar 
Acked-by: Oliver Neukum 
Acked-by: Zhang, Di 
---
 drivers/net/usb/usbnet.c |6 --
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 90a429b..0603ef6 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -86,6 +86,7 @@ static const char driver_name [] = "usbnet";
 
 /* use ethtool to change the level for any given device */
 static int msg_level = -1;
+static DECLARE_WAIT_QUEUE_HEAD(unlink_wakeup);
 module_param (msg_level, int, 0);
 MODULE_PARM_DESC (msg_level, "Override default message level");
 
@@ -761,7 +762,6 @@ EXPORT_SYMBOL_GPL(usbnet_unlink_rx_urbs);
 // precondition: never called in_interrupt
 static void usbnet_terminate_urbs(struct usbnet *dev)
 {
-   DECLARE_WAIT_QUEUE_HEAD_ONSTACK(unlink_wakeup);
DECLARE_WAITQUEUE(wait, current);
int temp;
 
@@ -1449,7 +1449,9 @@ static void usbnet_bh (unsigned long param)
// waiting for all pending urbs to complete?
if (dev->wait) {
if ((dev->txq.qlen + dev->rxq.qlen + dev->done.qlen) == 0) {
-   wake_up (dev->wait);
+   wait_queue_head_t *wait_d = dev->wait;
+   if (wait_d)
+   wake_up(wait_d);
}
 
// or are we maybe short a few urbs?
-- 
1.7.0.4



--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] usb: xhci: Add 2nd memory barrier to giveback_first_trb()

2013-11-12 Thread Greg KH
On Tue, Nov 12, 2013 at 01:58:05PM -, David Laight wrote:
> 
> There needs to be a wmb() barrier between the write to the cycle bit
> in the first TRB and the write to the doorbell register.
> 
> Since it isn't needed in the other places the doobell is rung
> (because the ring contents haven't been changed) add it to
> giveback_first_trb() rather than somewhere later.
> 
> Signed-off-by: David Laight 
> ---
> This patch will only apply cleanly if my earlier patch that affects
> the previous line has also been applied.
> 
>  drivers/usb/host/xhci-ring.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
> index 35dfed0..8bce4c3 100644
> --- a/drivers/usb/host/xhci-ring.c
> +++ b/drivers/usb/host/xhci-ring.c
> @@ -3136,6 +3136,7 @@ static void giveback_first_trb(struct xhci_hcd *xhci, 
> int slot_id,
>*/
>   wmb();
>   start_trb->field[3] ^= cpu_to_le32(TRB_CYCLE);
> + wmb();

I don't understand, why is this needed?  field[] isn't being used
elsewhere at this point in time, is it?

When adding barriers, you need to also add a big comment as to exactly
why this is needed, in the code itself, which this patch does not do, so
we can't take it (well, I will not take it, Sarah might, but then I'll
complain to her...)

thanks,

greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 00/15] rework port power control

2013-11-12 Thread Dan Williams
On Tue, Nov 12, 2013 at 3:10 PM, Sarah Sharp
 wrote:
> On Mon, Oct 28, 2013 at 06:49:37PM -0700, Dan Williams wrote:
>> On Sat, Oct 26, 2013 at 7:40 AM, Alan Stern  
>> wrote:
>> > On Fri, 25 Oct 2013, Dan Williams wrote:
>> >> > This patch set makes a large number of significant changes to important
>> >> > and subtle aspects of the USB stack.  It would be a lot easier to
>> >> > discuss in pieces; I can't possibly review the whole series in a
>> >> > reasonable time.
>> >> >
>> >> > And I wish the basic approach had been discussed beforehand...  Some of
>> >> > the ideas are quite nice, but there are a lot of details that need
>> >> > close attention.
>> >>
>> >> I wanted to at least have a working implementation that tackled the
>> >> peer disconnect case, I did not expect 15 patches to fall out of that.
>> >>  However, after talking through this I think it can be abbreviated.
>> >
>> > Yes.  It looks like we're talking about several major changes:
>> >
>> > Redefining what it means for a port to be in runtime suspend.
>> >
>> > Rearranging the device model tree.
>> >
>> > Implementing connectors.
>> >
>> > Changing the port-power-off policy.
>> >
>> > The patch set also changes khubd into a workqueue, but now it looks
>> > like we don't need to do that (although I'm not ruling it out as a
>> > future clean-up).
>> >
>> > Does this leave anything out?
>>
>> No, but that last one can be subdivided into:
>>  - implement hotplug vs hardwired policy
>
> I think the original agreement when the USB 2.0 port power off work
> went in was that hotplug vs hardwired shouldn't make a difference in the
> kernel.  It would be up to userspace to read the port connection type,
> and decide whether to enable port power off.
>
> What in-kernel policy were you thinking of?

The same, but forcing userspace to explicitly override the
connection_type to "hardwired" before allowing power off.

We're already in the situation where multiple settings (remote wakeup
enabled, peer port power state) will keep a port powered.  My intent
is adding connection_type to that list and making it configurable as
another port power_off gate.  It takes the implementation in the
direction of making it safer to aggressively clear the
pm_qos_no_power_off flag on usb ports... not that we would ever go so
far as to make pm_qos_no_power_off=0 the default.

>
>>  - consider/handle connector peers in port power policy
>>
>> >> In the existing code at usb_port_runtime_resume() time we know the
>> >> port is off.  By calling usb_autopm_get_interface(intf) before turning
>> >> on the power we are simply causing an unnecessary check of the port
>> >> status registers.  We do have the power_is_on check to block
>> >> hub_activate() from setting the change_bits, but that was not enough
>> >> to prevent khubd from triggering a disconnect.
>> >
>> > In fact, the reason for calling usb_autopm_get_interface was to prevent
>> > the hub from being suspended while we change the port's power state.
>> > Something like this may still be needed.
>> >
>>
>> With the device model change and no longer telling the hub interface
>> device to pm_suspend_ignore_children() the pm subsystem will manage
>> this wake up for us.
>>
>> > Have you considered what would happen if the user changed the port's
>> > pm_qos setting while the port was suspended?  Ideally, such changes
>> > should immediately affect the port's power state.  For example, if the
>> > port was suspended with power off when the user sets the no_power_off
>> > flag, we should immediately turn port power back on.  I don't know if
>> > the PM QoS design permits this sort of thing, though.
>> >
>>
>> Yes, every flag change triggers a wake up of the port and, as a
>> pre-requisite, its parent hub.
>>
>> >> > You should also explain at the start of the description what you mean
>> >> > by related (or peer) ports.  Then the idea of a connector is clear --
>> >> > although I got the impression that the implementation may be a little
>> >> > over-engineered.
>> >>
>> >> Hence the RFC, yes, not opposed to backing up and simplifying this.
>> >
>> > Since a port never needs to be connected to more than one other port,
>> > you could implement connectors simply by storing a "peer" pointer in
>> > the usb_port structure.
>>
>> Yes, no need to design for the non-existent 3 connection types in a
>> port case now.
>>
>> Another simplification is that a "struct usb_domain" is currently
>> known to never span a controller boundary.  So, rather than adding
>> ports to a usb_connector / usb_domain container hierarchy I think we
>> can simply scan the child devices under the xhci device and look for
>> is_usb_port() instances.
>>
>> In the meantime I am still thinking of the approach to reliably link
>> USB3 hub ports to their peers.  The spec mandates that they be
>> labelled the same for this purpose (USB3 spec section 10.3.3).
>
> The USB 3.0 specification does provide a way to uniquely identify

Re: [PATCH] usb: chipidea: udc: first start device on pullup

2013-11-12 Thread Peter Chen
On Tue, Nov 12, 2013 at 03:39:30PM +0100, Michael Grzeschik wrote:
> On Tue, Nov 12, 2013 at 08:12:04PM +0800, Peter Chen wrote:
> > On Tue, Nov 12, 2013 at 7:50 PM, Michael Grzeschik
> >  wrote:
> > > Don't start hw_device_state on udc_start. The gadget framework has
> > > the prepared pullup callback for this. This is necessary if we use gadgets
> > > which need to be enabled after an userspace application got prepared, or
> > > other delayed conditiions have passed.
> > >
> > > Signed-off-by: Michael Grzeschik 
> > > ---
> > >
> > > Hi Peter,
> > >
> > > I checked ci_udc_start again and realized that one problem is
> > > that we ignore the pullup call and start the device on udc_start.
> > >
> > > What do you think of the following patch? Any objections?
> > >
> > >  drivers/usb/chipidea/udc.c | 5 -
> > >  1 file changed, 5 deletions(-)
> > >
> > > diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
> > > index b34c819..e673263 100644
> > > --- a/drivers/usb/chipidea/udc.c
> > > +++ b/drivers/usb/chipidea/udc.c
> > > @@ -1647,11 +1647,6 @@ static int ci_udc_start(struct usb_gadget *gadget,
> > > return retval;
> > > }
> > >
> > > -   retval = hw_device_state(ci, ci->ep0out->qh.dma);
> > > -   spin_unlock_irqrestore(&ci->lock, flags);
> > > -   if (retval)
> > > -   pm_runtime_put_sync(&ci->gadget.dev);
> > > -
> > > return retval;
> > >  }
> > >
> > Hi Michael,
> >
> > Your code base seems out of date.
> 
> I used linux/master.

Please use usb-next if possible

> 
> > The reason why we need start controller(call hw_device_state) at 
> > ci_udc_start:
> >
> > - For vbus is already there before modprobe gadget, in that case, there
> > is no vbus interrupt due to vbus has not changed during the initialization.
> 
> Don't we have another possibility to ask the hardware if the vbus is
> connected. We could limit the enabled Interrupts in udc_start to
> USBi_PCI. Will it than trigger an interrupt while having the cable
> _already_ plugged?

If the usbcm.rs is 0, there is no any USB interrupts except USB OTG interrupt,
like vbus and ID and USB wakeup interrupt.

> 
> > - For the platforms which have no vbus interrupt, it needs to start 
> > controller
> > before connection otherwise the enumeration can't be started due to
> > usbcmd.rs is 0.
> 
> Then we need to force to start the controller conditionally for those 
> platforms.
> IMHO this should not be the case for all platforms.
> 
Of cos, it is not for all platforms.

In a word, in order to support uvc use case, there are two places need to
be changed like I said at previous email.

-- 

Best Regards,
Peter Chen

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 10/17] clk: at91: add peripheral clk macros for peripheral clk dt bindings

2013-11-12 Thread Boris BREZILLON
This patch adds the peripheral divisors macros (for sam9x5 compatible IPs)
which will be used by peripheral clk dt definitions.

Signed-off-by: Boris BREZILLON 
Acked-by: Nicolas Ferre 
---
 include/dt-bindings/clk/at91.h |6 ++
 1 file changed, 6 insertions(+)

diff --git a/include/dt-bindings/clk/at91.h b/include/dt-bindings/clk/at91.h
index 0b4cb99..a3b07ca 100644
--- a/include/dt-bindings/clk/at91.h
+++ b/include/dt-bindings/clk/at91.h
@@ -19,4 +19,10 @@
 #define AT91_PMC_MOSCRCS   17  /* Main On-Chip RC */
 #define AT91_PMC_CFDEV 18  /* Clock Failure Detector Event 
*/
 
+/* sam9x5 peripheral divisors */
+#define AT91SAM9X5_PERIPH_CLK_DIV1 0
+#define AT91SAM9X5_PERIPH_CLK_DIV2 1
+#define AT91SAM9X5_PERIPH_CLK_DIV4 2
+#define AT91SAM9X5_PERIPH_CLK_DIV8 3
+
 #endif
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 11/17] clk: at91: add PMC programmable clocks

2013-11-12 Thread Boris BREZILLON
This patch adds new at91 programmable clocks implementation using common clk
framework.
A programmable clock is a clock which can be exported on a given pin to clock
external devices.
Each programmable clock is given an id (from 0 to 8).
The number of available programmable clocks depends on the SoC you're using.
Programmable clock driver only implements the clock setting (clock rate and
parent setting). It must be chained to a system clock in order to
enable/disable the generated clock.
The PCKX pins used to output the clock signals must be assigned to the
appropriate peripheral (see atmel's datasheets).

Signed-off-by: Boris BREZILLON 
Acked-by: Nicolas Ferre 
---
 drivers/clk/at91/Makefile   |2 +
 drivers/clk/at91/clk-programmable.c |  368 +++
 drivers/clk/at91/pmc.c  |   15 ++
 drivers/clk/at91/pmc.h  |9 +
 4 files changed, 394 insertions(+)
 create mode 100644 drivers/clk/at91/clk-programmable.c

diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index 04deba3..3873b62 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -5,3 +5,5 @@
 obj-y += pmc.o
 obj-y += clk-main.o clk-pll.o clk-plldiv.o clk-master.o
 obj-y += clk-system.o clk-peripheral.o
+
+obj-$(CONFIG_AT91_PROGRAMMABLE_CLOCKS) += clk-programmable.o
diff --git a/drivers/clk/at91/clk-programmable.c 
b/drivers/clk/at91/clk-programmable.c
new file mode 100644
index 000..1daa05f
--- /dev/null
+++ b/drivers/clk/at91/clk-programmable.c
@@ -0,0 +1,368 @@
+/*
+ * drivers/clk/at91/clk-programmable.c
+ *
+ *  Copyright (C) 2013 Boris BREZILLON 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "pmc.h"
+
+#define PROG_SOURCE_MAX5
+#define PROG_ID_MAX7
+
+#define PROG_STATUS_MASK(id)   (1 << ((id) + 8))
+#define PROG_PRES_MASK 0x7
+#define PROG_MAX_RM9200_CSS3
+
+struct clk_programmable_layout {
+   u8 pres_shift;
+   u8 css_mask;
+   u8 have_slck_mck;
+};
+
+struct clk_programmable {
+   struct clk_hw hw;
+   struct at91_pmc *pmc;
+   unsigned int irq;
+   wait_queue_head_t wait;
+   u8 id;
+   u8 css;
+   u8 pres;
+   u8 slckmck;
+   const struct clk_programmable_layout *layout;
+};
+
+#define to_clk_programmable(hw) container_of(hw, struct clk_programmable, hw)
+
+
+static irqreturn_t clk_programmable_irq_handler(int irq, void *dev_id)
+{
+   struct clk_programmable *prog = (struct clk_programmable *)dev_id;
+
+   wake_up(&prog->wait);
+
+   return IRQ_HANDLED;
+}
+
+static int clk_programmable_prepare(struct clk_hw *hw)
+{
+   u32 tmp;
+   struct clk_programmable *prog = to_clk_programmable(hw);
+   struct at91_pmc *pmc = prog->pmc;
+   const struct clk_programmable_layout *layout = prog->layout;
+   u8 id = prog->id;
+   u32 mask = PROG_STATUS_MASK(id);
+
+   tmp = prog->css | (prog->pres << layout->pres_shift);
+   if (layout->have_slck_mck && prog->slckmck)
+   tmp |= AT91_PMC_CSSMCK_MCK;
+
+   pmc_write(pmc, AT91_PMC_PCKR(id), tmp);
+
+   while (!(pmc_read(pmc, AT91_PMC_SR) & mask))
+   wait_event(prog->wait, pmc_read(pmc, AT91_PMC_SR) & mask);
+
+   return 0;
+}
+
+static int clk_programmable_is_ready(struct clk_hw *hw)
+{
+   struct clk_programmable *prog = to_clk_programmable(hw);
+   struct at91_pmc *pmc = prog->pmc;
+
+   return !!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_PCKR(prog->id));
+}
+
+static unsigned long clk_programmable_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+   u32 tmp;
+   struct clk_programmable *prog = to_clk_programmable(hw);
+   struct at91_pmc *pmc = prog->pmc;
+   const struct clk_programmable_layout *layout = prog->layout;
+
+   tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id));
+   prog->pres = (tmp >> layout->pres_shift) & PROG_PRES_MASK;
+
+   return parent_rate >> prog->pres;
+}
+
+static long clk_programmable_round_rate(struct clk_hw *hw, unsigned long rate,
+   unsigned long *parent_rate)
+{
+   unsigned long best_rate = *parent_rate;
+   unsigned long best_diff;
+   unsigned long new_diff;
+   unsigned long cur_rate;
+   int shift = shift;
+
+   if (rate > *parent_rate)
+   return *parent_rate;
+   else
+   best_diff = *parent_rate - rate;
+
+   if (!best_diff)
+   return best_rate;
+
+   for (shift = 1; shift < PROG_PRES_MASK; shift++) {
+   cur_rate = *parent_rate >> shi

[PATCH v5 12/17] clk: at91: add PMC utmi clock

2013-11-12 Thread Boris BREZILLON
This adds new at91 utmi clock implementation using common clk framework.

This clock is a pll with a fixed factor (x40).
It is used as a source for usb clock.

Signed-off-by: Boris BREZILLON 
Acked-by: Nicolas Ferre 
---
 arch/arm/mach-at91/Kconfig  |7 ++
 drivers/clk/at91/Makefile   |1 +
 drivers/clk/at91/clk-utmi.c |  162 +++
 drivers/clk/at91/pmc.c  |7 ++
 drivers/clk/at91/pmc.h  |5 ++
 5 files changed, 182 insertions(+)
 create mode 100644 drivers/clk/at91/clk-utmi.c

diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 85b53a4..6ad37da 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -1,5 +1,8 @@
 if ARCH_AT91
 
+config HAVE_AT91_UTMI
+   bool
+
 config HAVE_AT91_DBGU0
bool
 
@@ -78,6 +81,7 @@ config SOC_SAMA5D3
select HAVE_FB_ATMEL
select HAVE_AT91_DBGU1
select AT91_USE_OLD_CLK
+   select HAVE_AT91_UTMI
help
  Select this if you are using one of Atmel's SAMA5D3 family SoC.
  This support covers SAMA5D31, SAMA5D33, SAMA5D34, SAMA5D35.
@@ -124,6 +128,7 @@ config SOC_AT91SAM9RL
select HAVE_FB_ATMEL
select SOC_AT91SAM9
select AT91_USE_OLD_CLK
+   select HAVE_AT91_UTMI
 
 config SOC_AT91SAM9G45
bool "AT91SAM9G45 or AT91SAM9M10 families"
@@ -131,6 +136,7 @@ config SOC_AT91SAM9G45
select HAVE_FB_ATMEL
select SOC_AT91SAM9
select AT91_USE_OLD_CLK
+   select HAVE_AT91_UTMI
help
  Select this if you are using one of Atmel's AT91SAM9G45 family SoC.
  This support covers AT91SAM9G45, AT91SAM9G46, AT91SAM9M10 and 
AT91SAM9M11.
@@ -141,6 +147,7 @@ config SOC_AT91SAM9X5
select HAVE_FB_ATMEL
select SOC_AT91SAM9
select AT91_USE_OLD_CLK
+   select HAVE_AT91_UTMI
help
  Select this if you are using one of Atmel's AT91SAM9x5 family SoC.
  This means that your SAM9 name finishes with a '5' (except if it is
diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index 3873b62..a824883 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -7,3 +7,4 @@ obj-y += clk-main.o clk-pll.o clk-plldiv.o clk-master.o
 obj-y += clk-system.o clk-peripheral.o
 
 obj-$(CONFIG_AT91_PROGRAMMABLE_CLOCKS) += clk-programmable.o
+obj-$(CONFIG_HAVE_AT91_UTMI)   += clk-utmi.o
diff --git a/drivers/clk/at91/clk-utmi.c b/drivers/clk/at91/clk-utmi.c
new file mode 100644
index 000..9a133df
--- /dev/null
+++ b/drivers/clk/at91/clk-utmi.c
@@ -0,0 +1,162 @@
+/*
+ * drivers/clk/at91/clk-utmi.c
+ *
+ *  Copyright (C) 2013 Boris BREZILLON 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "pmc.h"
+
+#define UTMI_FIXED_MUL 40
+
+struct clk_utmi {
+   struct clk_hw hw;
+   struct at91_pmc *pmc;
+   unsigned int irq;
+   wait_queue_head_t wait;
+};
+
+#define to_clk_utmi(hw) container_of(hw, struct clk_utmi, hw)
+
+static irqreturn_t clk_utmi_irq_handler(int irq, void *dev_id)
+{
+   struct clk_utmi *utmi = (struct clk_utmi *)dev_id;
+
+   wake_up(&utmi->wait);
+   disable_irq_nosync(utmi->irq);
+
+   return IRQ_HANDLED;
+}
+
+static int clk_utmi_prepare(struct clk_hw *hw)
+{
+   struct clk_utmi *utmi = to_clk_utmi(hw);
+   struct at91_pmc *pmc = utmi->pmc;
+   u32 tmp = at91_pmc_read(AT91_CKGR_UCKR) | AT91_PMC_UPLLEN |
+ AT91_PMC_UPLLCOUNT | AT91_PMC_BIASEN;
+
+   pmc_write(pmc, AT91_CKGR_UCKR, tmp);
+
+   while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_LOCKU)) {
+   enable_irq(utmi->irq);
+   wait_event(utmi->wait,
+  pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_LOCKU);
+   }
+
+   return 0;
+}
+
+static int clk_utmi_is_ready(struct clk_hw *hw)
+{
+   struct clk_utmi *utmi = to_clk_utmi(hw);
+   struct at91_pmc *pmc = utmi->pmc;
+
+   return !!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_LOCKU);
+}
+
+static void clk_utmi_disable(struct clk_hw *hw)
+{
+   struct clk_utmi *utmi = to_clk_utmi(hw);
+   struct at91_pmc *pmc = utmi->pmc;
+   u32 tmp = at91_pmc_read(AT91_CKGR_UCKR) & ~AT91_PMC_UPLLEN;
+
+   pmc_write(pmc, AT91_CKGR_UCKR, tmp);
+}
+
+static unsigned long clk_utmi_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+   /* UTMI clk is a fixed clk multiplier */
+   return parent_rate * UTMI_FIXED_MUL;
+}
+
+static const struct clk_ops utmi_ops = {
+   .prepare = clk_utmi_prepare,
+   .is_prepared = clk_utmi_is_ready,
+   .disable = clk_ut

[PATCH v5 13/17] clk: at91: add PMC usb clock

2013-11-12 Thread Boris BREZILLON
This patch adds new at91 usb clock implementation using common clk framework.
This clock is used to clock usb ports (ohci, ehci and udc).

Signed-off-by: Boris BREZILLON 
Acked-by: Nicolas Ferre 
---
 arch/arm/mach-at91/Kconfig |   11 ++
 drivers/clk/at91/Makefile  |1 +
 drivers/clk/at91/clk-usb.c |  400 
 drivers/clk/at91/pmc.c |   15 ++
 drivers/clk/at91/pmc.h |9 +
 5 files changed, 436 insertions(+)
 create mode 100644 drivers/clk/at91/clk-usb.c

diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 6ad37da..b76dc4c 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -3,6 +3,9 @@ if ARCH_AT91
 config HAVE_AT91_UTMI
bool
 
+config HAVE_AT91_USB_CLK
+   bool
+
 config HAVE_AT91_DBGU0
bool
 
@@ -82,6 +85,7 @@ config SOC_SAMA5D3
select HAVE_AT91_DBGU1
select AT91_USE_OLD_CLK
select HAVE_AT91_UTMI
+   select HAVE_AT91_USB_CLK
help
  Select this if you are using one of Atmel's SAMA5D3 family SoC.
  This support covers SAMA5D31, SAMA5D33, SAMA5D34, SAMA5D35.
@@ -96,12 +100,14 @@ config SOC_AT91RM9200
select MULTI_IRQ_HANDLER
select SPARSE_IRQ
select AT91_USE_OLD_CLK
+   select HAVE_AT91_USB_CLK
 
 config SOC_AT91SAM9260
bool "AT91SAM9260, AT91SAM9XE or AT91SAM9G20"
select HAVE_AT91_DBGU0
select SOC_AT91SAM9
select AT91_USE_OLD_CLK
+   select HAVE_AT91_USB_CLK
help
  Select this if you are using one of Atmel's AT91SAM9260, AT91SAM9XE
  or AT91SAM9G20 SoC.
@@ -112,6 +118,7 @@ config SOC_AT91SAM9261
select HAVE_FB_ATMEL
select SOC_AT91SAM9
select AT91_USE_OLD_CLK
+   select HAVE_AT91_USB_CLK
help
  Select this if you are using one of Atmel's AT91SAM9261 or 
AT91SAM9G10 SoC.
 
@@ -121,6 +128,7 @@ config SOC_AT91SAM9263
select HAVE_FB_ATMEL
select SOC_AT91SAM9
select AT91_USE_OLD_CLK
+   select HAVE_AT91_USB_CLK
 
 config SOC_AT91SAM9RL
bool "AT91SAM9RL"
@@ -137,6 +145,7 @@ config SOC_AT91SAM9G45
select SOC_AT91SAM9
select AT91_USE_OLD_CLK
select HAVE_AT91_UTMI
+   select HAVE_AT91_USB_CLK
help
  Select this if you are using one of Atmel's AT91SAM9G45 family SoC.
  This support covers AT91SAM9G45, AT91SAM9G46, AT91SAM9M10 and 
AT91SAM9M11.
@@ -148,6 +157,7 @@ config SOC_AT91SAM9X5
select SOC_AT91SAM9
select AT91_USE_OLD_CLK
select HAVE_AT91_UTMI
+   select HAVE_AT91_USB_CLK
help
  Select this if you are using one of Atmel's AT91SAM9x5 family SoC.
  This means that your SAM9 name finishes with a '5' (except if it is
@@ -161,6 +171,7 @@ config SOC_AT91SAM9N12
select HAVE_FB_ATMEL
select SOC_AT91SAM9
select AT91_USE_OLD_CLK
+   select HAVE_AT91_USB_CLK
help
  Select this if you are using Atmel's AT91SAM9N12 SoC.
 
diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index a824883..61db058 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -8,3 +8,4 @@ obj-y += clk-system.o clk-peripheral.o
 
 obj-$(CONFIG_AT91_PROGRAMMABLE_CLOCKS) += clk-programmable.o
 obj-$(CONFIG_HAVE_AT91_UTMI)   += clk-utmi.o
+obj-$(CONFIG_HAVE_AT91_USB_CLK)+= clk-usb.o
diff --git a/drivers/clk/at91/clk-usb.c b/drivers/clk/at91/clk-usb.c
new file mode 100644
index 000..0454555
--- /dev/null
+++ b/drivers/clk/at91/clk-usb.c
@@ -0,0 +1,400 @@
+/*
+ * drivers/clk/at91/clk-usb.c
+ *
+ *  Copyright (C) 2013 Boris BREZILLON 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "pmc.h"
+
+#define USB_SOURCE_MAX 2
+
+#define SAM9X5_USB_DIV_SHIFT   8
+#define SAM9X5_USB_MAX_DIV 0xf
+
+#define RM9200_USB_DIV_SHIFT   28
+#define RM9200_USB_DIV_TAB_SIZE4
+
+struct at91sam9x5_clk_usb {
+   struct clk_hw hw;
+   struct at91_pmc *pmc;
+};
+
+#define to_at91sam9x5_clk_usb(hw) \
+   container_of(hw, struct at91sam9x5_clk_usb, hw)
+
+struct at91rm9200_clk_usb {
+   struct clk_hw hw;
+   struct at91_pmc *pmc;
+   u32 divisors[4];
+};
+
+#define to_at91rm9200_clk_usb(hw) \
+   container_of(hw, struct at91rm9200_clk_usb, hw)
+
+static unsigned long at91sam9x5_clk_usb_recalc_rate(struct clk_hw *hw,
+   unsigned long parent_rate)
+{
+   u32 tmp;
+   u8 usbdiv;
+   struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
+   struct at91_pmc *pmc = usb->pmc;
+
+   tmp = pmc_read(pmc, AT91_PMC_USB);
+   usbdiv = (

[PATCH v5 14/17] clk: at91: add PMC smd clock

2013-11-12 Thread Boris BREZILLON
This patch adds at91 smd (Soft Modem) clock implementation using common clk
framework.

Not used by any driver right now.

Signed-off-by: Boris BREZILLON 
Acked-by: Nicolas Ferre 
---
 arch/arm/mach-at91/Kconfig |5 ++
 drivers/clk/at91/Makefile  |1 +
 drivers/clk/at91/clk-smd.c |  173 
 drivers/clk/at91/pmc.c |7 ++
 drivers/clk/at91/pmc.h |5 ++
 5 files changed, 191 insertions(+)
 create mode 100644 drivers/clk/at91/clk-smd.c

diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index b76dc4c..97033f7 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -39,6 +39,9 @@ config AT91_SAM9G45_RESET
 config AT91_SAM9_TIME
bool
 
+config HAVE_AT91_SMD
+   bool
+
 config SOC_AT91SAM9
bool
select AT91_SAM9_TIME
@@ -85,6 +88,7 @@ config SOC_SAMA5D3
select HAVE_AT91_DBGU1
select AT91_USE_OLD_CLK
select HAVE_AT91_UTMI
+   select HAVE_AT91_SMD
select HAVE_AT91_USB_CLK
help
  Select this if you are using one of Atmel's SAMA5D3 family SoC.
@@ -157,6 +161,7 @@ config SOC_AT91SAM9X5
select SOC_AT91SAM9
select AT91_USE_OLD_CLK
select HAVE_AT91_UTMI
+   select HAVE_AT91_SMD
select HAVE_AT91_USB_CLK
help
  Select this if you are using one of Atmel's AT91SAM9x5 family SoC.
diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index 61db058..0e92b71 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -9,3 +9,4 @@ obj-y += clk-system.o clk-peripheral.o
 obj-$(CONFIG_AT91_PROGRAMMABLE_CLOCKS) += clk-programmable.o
 obj-$(CONFIG_HAVE_AT91_UTMI)   += clk-utmi.o
 obj-$(CONFIG_HAVE_AT91_USB_CLK)+= clk-usb.o
+obj-$(CONFIG_HAVE_AT91_SMD)+= clk-smd.o
diff --git a/drivers/clk/at91/clk-smd.c b/drivers/clk/at91/clk-smd.c
new file mode 100644
index 000..9f3fa39
--- /dev/null
+++ b/drivers/clk/at91/clk-smd.c
@@ -0,0 +1,173 @@
+/*
+ * drivers/clk/at91/clk-smd.c
+ *
+ *  Copyright (C) 2013 Boris BREZILLON 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "pmc.h"
+
+#define SMD_SOURCE_MAX 2
+
+#define SMD_DIV_SHIFT  8
+#define SMD_MAX_DIV0xf
+
+struct at91sam9x5_clk_smd {
+   struct clk_hw hw;
+   struct at91_pmc *pmc;
+};
+
+#define to_at91sam9x5_clk_smd(hw) \
+   container_of(hw, struct at91sam9x5_clk_smd, hw)
+
+static unsigned long at91sam9x5_clk_smd_recalc_rate(struct clk_hw *hw,
+   unsigned long parent_rate)
+{
+   u32 tmp;
+   u8 smddiv;
+   struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw);
+   struct at91_pmc *pmc = smd->pmc;
+
+   tmp = pmc_read(pmc, AT91_PMC_SMD);
+   smddiv = (tmp & AT91_PMC_SMD_DIV) >> SMD_DIV_SHIFT;
+   return parent_rate / (smddiv + 1);
+}
+
+static long at91sam9x5_clk_smd_round_rate(struct clk_hw *hw, unsigned long 
rate,
+ unsigned long *parent_rate)
+{
+   unsigned long div;
+   unsigned long bestrate;
+   unsigned long tmp;
+
+   if (rate >= *parent_rate)
+   return *parent_rate;
+
+   div = *parent_rate / rate;
+   if (div > SMD_MAX_DIV)
+   return *parent_rate / (SMD_MAX_DIV + 1);
+
+   bestrate = *parent_rate / div;
+   tmp = *parent_rate / (div + 1);
+   if (bestrate - rate > rate - tmp)
+   bestrate = tmp;
+
+   return bestrate;
+}
+
+static int at91sam9x5_clk_smd_set_parent(struct clk_hw *hw, u8 index)
+{
+   u32 tmp;
+   struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw);
+   struct at91_pmc *pmc = smd->pmc;
+
+   if (index > 1)
+   return -EINVAL;
+   tmp = pmc_read(pmc, AT91_PMC_SMD) & ~AT91_PMC_SMDS;
+   if (index)
+   tmp |= AT91_PMC_SMDS;
+   pmc_write(pmc, AT91_PMC_SMD, tmp);
+   return 0;
+}
+
+static u8 at91sam9x5_clk_smd_get_parent(struct clk_hw *hw)
+{
+   struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw);
+   struct at91_pmc *pmc = smd->pmc;
+
+   return pmc_read(pmc, AT91_PMC_SMD) & AT91_PMC_SMDS;
+}
+
+static int at91sam9x5_clk_smd_set_rate(struct clk_hw *hw, unsigned long rate,
+  unsigned long parent_rate)
+{
+   u32 tmp;
+   struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw);
+   struct at91_pmc *pmc = smd->pmc;
+   unsigned long div = parent_rate / rate;
+
+   if (parent_rate % rate || div < 1 || div > (SMD_MAX_DIV + 1))
+   return -EINVAL;
+   tmp = pmc_read(pmc, AT91_PMC_SMD) & ~AT9

[PATCH v5 15/17] dt: binding: add at91 clks dt bindings documentation

2013-11-12 Thread Boris BREZILLON
This patch adds new at91 clks dt bindings documentation.

Signed-off-by: Boris BREZILLON 
Acked-by: Nicolas Ferre 
---
 .../devicetree/bindings/clock/at91-clock.txt   |  339 
 1 file changed, 339 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/at91-clock.txt

diff --git a/Documentation/devicetree/bindings/clock/at91-clock.txt 
b/Documentation/devicetree/bindings/clock/at91-clock.txt
new file mode 100644
index 000..cd5e239
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/at91-clock.txt
@@ -0,0 +1,339 @@
+Device Tree Clock bindings for arch-at91
+
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties:
+- compatible : shall be one of the following:
+   "atmel,at91rm9200-pmc" or
+   "atmel,at91sam9g45-pmc" or
+   "atmel,at91sam9n12-pmc" or
+   "atmel,at91sam9x5-pmc" or
+   "atmel,sama5d3-pmc":
+   at91 PMC (Power Management Controller)
+   All at91 specific clocks (clocks defined below) must be child
+   node of the PMC node.
+
+   "atmel,at91rm9200-clk-main":
+   at91 main oscillator
+
+   "atmel,at91rm9200-clk-master" or
+   "atmel,at91sam9x5-clk-master":
+   at91 master clock
+
+   "atmel,at91sam9x5-clk-peripheral" or
+   "atmel,at91rm9200-clk-peripheral":
+   at91 peripheral clocks
+
+   "atmel,at91rm9200-clk-pll" or
+   "atmel,at91sam9g45-clk-pll" or
+   "atmel,at91sam9g20-clk-pllb" or
+   "atmel,sama5d3-clk-pll":
+   at91 pll clocks
+
+   "atmel,at91sam9x5-clk-plldiv":
+   at91 plla divisor
+
+   "atmel,at91rm9200-clk-programmable" or
+   "atmel,at91sam9g45-clk-programmable" or
+   "atmel,at91sam9x5-clk-programmable":
+   at91 programmable clocks
+
+   "atmel,at91sam9x5-clk-smd":
+   at91 SMD (Soft Modem) clock
+
+   "atmel,at91rm9200-clk-system":
+   at91 system clocks
+
+   "atmel,at91rm9200-clk-usb" or
+   "atmel,at91sam9x5-clk-usb" or
+   "atmel,at91sam9n12-clk-usb":
+   at91 usb clock
+
+   "atmel,at91sam9x5-clk-utmi":
+   at91 utmi clock
+
+Required properties for PMC node:
+- reg : defines the IO memory reserved for the PMC.
+- #size-cells : shall be 0 (reg is used to encode clk id).
+- #address-cells : shall be 1 (reg is used to encode clk id).
+- interrupts : shall be set to PMC interrupt line.
+- interrupt-controller : tell that the PMC is an interrupt controller.
+- #interrupt-cells : must be set to 1. The first cell encodes the interrupt id,
+   and reflect the bit position in the PMC_ER/DR/SR registers.
+   You can use the dt macros defined in dt-bindings/clk/at91.h.
+   0 (AT91_PMC_MOSCS) -> main oscillator ready
+   1 (AT91_PMC_LOCKA) -> PLL A ready
+   2 (AT91_PMC_LOCKB) -> PLL B ready
+   3 (AT91_PMC_MCKRDY) -> master clock ready
+   6 (AT91_PMC_LOCKU) -> UTMI PLL clock ready
+   8 .. 15 (AT91_PMC_PCKRDY(id)) -> programmable clock ready
+   16 (AT91_PMC_MOSCSELS) -> main oscillator selected
+   17 (AT91_PMC_MOSCRCS) -> RC main oscillator stabilized
+   18 (AT91_PMC_CFDEV) -> clock failure detected
+
+For example:
+   pmc: pmc@fc00 {
+   compatible = "atmel,sama5d3-pmc";
+   interrupts = <1 4 7>;
+   interrupt-controller;
+   #interrupt-cells = <2>;
+   #size-cells = <0>;
+   #address-cells = <1>;
+
+   /* put at91 clocks here */
+   };
+
+Required properties for main clock:
+- interrupt-parent : must reference the PMC node.
+- interrupts : shall be set to "<0>".
+- #clock-cells : from common clock binding; shall be set to 0.
+- clocks (optional if clock-frequency is provided) : shall be the slow clock
+   phandle. This clock is used to calculate the main clock rate if
+   "clock-frequency" is not provided.
+- clock-frequency : the main oscillator frequency.Prefer the use of
+   "clock-frequency" over automatic clock rate calculation.
+
+For example:
+   main: mainck {
+   compatible = "atmel,at91rm9200-clk-main";
+   interrupt-parent = <&pmc>;
+   interrupts = <0>;
+   #clock-cells = <0>;
+   clocks = <&ck32k>;
+   clock-frequency = <18432000>;
+   };
+
+Required properties for master clock:
+- interrupt-parent : must reference the PMC node.
+- interrupts : shall be set to "<3>".
+- #clock-cells : from common clock binding; shall be set to 0.
+- clocks : shall be the master clock sources (see atmel datasheet) phandles.
+   e.g. "<&ck32k>, <&main>, <&plla>, <&pllb>".
+- atmel,clk-output-range : minimum and maximum clock frequency (two u32
+  fields).
+  e.g. output = <0 13300>; <=> 0 to 133MHz.
+- atmel,clk-divisors : master cloc

[PATCH v5 17/17] ARM: at91: add new compatible strings for pmc driver

2013-11-12 Thread Boris BREZILLON
This patch adds new compatible string for PMC node to prepare the
transition to common clk.

These compatible string come from pmc driver in clk subsystem and are
needed to provide new device tree compatibility with old at91 clks
(device tree using common clks will use the new compatible strings).

Signed-off-by: Boris BREZILLON 
Acked-by: Nicolas Ferre 
---
 arch/arm/mach-at91/clock.c |5 +
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c
index 5f02aea..72b2579 100644
--- a/arch/arm/mach-at91/clock.c
+++ b/arch/arm/mach-at91/clock.c
@@ -884,6 +884,11 @@ static int __init at91_pmc_init(unsigned long main_clock)
 #if defined(CONFIG_OF)
 static struct of_device_id pmc_ids[] = {
{ .compatible = "atmel,at91rm9200-pmc" },
+   { .compatible = "atmel,at91sam9260-pmc" },
+   { .compatible = "atmel,at91sam9g45-pmc" },
+   { .compatible = "atmel,at91sam9n12-pmc" },
+   { .compatible = "atmel,at91sam9x5-pmc" },
+   { .compatible = "atmel,sama5d3-pmc" },
{ /*sentinel*/ }
 };
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 16/17] ARM: at91: move pit timer to common clk framework

2013-11-12 Thread Boris BREZILLON
Use device tree to get the source clock of the PIT (Periodic Interval Timer).
If the clock is not found in device tree (or dt is not enabled) we'll try to
get it using clk_lookup definitions.

Signed-off-by: Boris BREZILLON 
Acked-by: Nicolas Ferre 
---
 arch/arm/mach-at91/at91sam926x_time.c |   14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-at91/at91sam926x_time.c 
b/arch/arm/mach-at91/at91sam926x_time.c
index bb39232..0f04ffe 100644
--- a/arch/arm/mach-at91/at91sam926x_time.c
+++ b/arch/arm/mach-at91/at91sam926x_time.c
@@ -39,6 +39,7 @@
 static u32 pit_cycle;  /* write-once */
 static u32 pit_cnt;/* access only w/system irq blocked */
 static void __iomem *pit_base_addr __read_mostly;
+static struct clk *mck;
 
 static inline unsigned int pit_read(unsigned int reg_offset)
 {
@@ -195,10 +196,14 @@ static int __init of_at91sam926x_pit_init(void)
if (!pit_base_addr)
goto node_err;
 
+   mck = of_clk_get(np, 0);
+
/* Get the interrupts property */
ret = irq_of_parse_and_map(np, 0);
if (!ret) {
pr_crit("AT91: PIT: Unable to get IRQ from DT\n");
+   if (!IS_ERR(mck))
+   clk_put(mck);
goto ioremap_err;
}
at91sam926x_pit_irq.irq = ret;
@@ -230,6 +235,8 @@ void __init at91sam926x_pit_init(void)
unsignedbits;
int ret;
 
+   mck = ERR_PTR(-ENOENT);
+
/* For device tree enabled device: initialize here */
of_at91sam926x_pit_init();
 
@@ -237,7 +244,12 @@ void __init at91sam926x_pit_init(void)
 * Use our actual MCK to figure out how many MCK/16 ticks per
 * 1/HZ period (instead of a compile-time constant LATCH).
 */
-   pit_rate = clk_get_rate(clk_get(NULL, "mck")) / 16;
+   if (IS_ERR(mck))
+   mck = clk_get(NULL, "mck");
+
+   if (IS_ERR(mck))
+   panic("AT91: PIT: Unable to get mck clk\n");
+   pit_rate = clk_get_rate(mck) / 16;
pit_cycle = (pit_rate + HZ/2) / HZ;
WARN_ON(((pit_cycle - 1) & ~AT91_PIT_PIV) != 0);
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


  1   2   >