USB: pxa27x_udc: compatibility with pxa320 SoC
Got pxa27x_udc working on the pxa320 Nomad platform. The problem was that the pxa3xx UDC is not quite compatible with the pxa27x UDC in how it handles back-to-back control packets. The pxa27x probably drops them by default, but the pxa320 does not, and you have to detect it and set the OPC bit to clear the zero-length packet. Signed-off-by: Aric Blumer <aric@sdgsystems.com> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr> Acked-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
f6d529f936
commit
9f5351b743
|
@ -253,7 +253,7 @@ config USB_PXA25X_SMALL
|
||||||
|
|
||||||
config USB_GADGET_PXA27X
|
config USB_GADGET_PXA27X
|
||||||
boolean "PXA 27x"
|
boolean "PXA 27x"
|
||||||
depends on ARCH_PXA && PXA27x
|
depends on ARCH_PXA && (PXA27x || PXA3xx)
|
||||||
select USB_OTG_UTILS
|
select USB_OTG_UTILS
|
||||||
help
|
help
|
||||||
Intel's PXA 27x series XScale ARM v5TE processors include
|
Intel's PXA 27x series XScale ARM v5TE processors include
|
||||||
|
|
|
@ -1892,6 +1892,15 @@ static void handle_ep0_ctrl_req(struct pxa_udc *udc,
|
||||||
|
|
||||||
nuke(ep, -EPROTO);
|
nuke(ep, -EPROTO);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In the PXA320 manual, in the section about Back-to-Back setup
|
||||||
|
* packets, it describes this situation. The solution is to set OPC to
|
||||||
|
* get rid of the status packet, and then continue with the setup
|
||||||
|
* packet. Generalize to pxa27x CPUs.
|
||||||
|
*/
|
||||||
|
if (epout_has_pkt(ep) && (ep_count_bytes_remain(ep) == 0))
|
||||||
|
udc_ep_writel(ep, UDCCSR, UDCCSR0_OPC);
|
||||||
|
|
||||||
/* read SETUP packet */
|
/* read SETUP packet */
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
if (unlikely(ep_is_empty(ep)))
|
if (unlikely(ep_is_empty(ep)))
|
||||||
|
@ -1965,6 +1974,8 @@ stall:
|
||||||
* cleared by software.
|
* cleared by software.
|
||||||
* - clearing UDCCSR0_OPC always flushes ep0. If in setup stage, never do it
|
* - clearing UDCCSR0_OPC always flushes ep0. If in setup stage, never do it
|
||||||
* before reading ep0.
|
* before reading ep0.
|
||||||
|
* This is true only for PXA27x. This is not true anymore for PXA3xx family
|
||||||
|
* (check Back-to-Back setup packet in developers guide).
|
||||||
* - irq can be called on a "packet complete" event (opc_irq=1), while
|
* - irq can be called on a "packet complete" event (opc_irq=1), while
|
||||||
* UDCCSR0_OPC is not yet raised (delta can be as big as 100ms
|
* UDCCSR0_OPC is not yet raised (delta can be as big as 100ms
|
||||||
* from experimentation).
|
* from experimentation).
|
||||||
|
@ -2575,7 +2586,7 @@ static struct platform_driver udc_driver = {
|
||||||
|
|
||||||
static int __init udc_init(void)
|
static int __init udc_init(void)
|
||||||
{
|
{
|
||||||
if (!cpu_is_pxa27x())
|
if (!cpu_is_pxa27x() && !cpu_is_pxa3xx())
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
printk(KERN_INFO "%s: version %s\n", driver_name, DRIVER_VERSION);
|
printk(KERN_INFO "%s: version %s\n", driver_name, DRIVER_VERSION);
|
||||||
|
|
Loading…
Reference in New Issue