diff options
| author | Greg Kroah-Hartman <gregkh@suse.de> | 2009-01-25 13:09:33 -0800 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-01-25 13:09:33 -0800 |
| commit | 53aa7b785b8cd367068f565006620f9e3eb68108 (patch) | |
| tree | 32aa4e93145e77647ac484edb5a0362024521812 | |
| parent | 4ded3df0a291c4217b76288e8817ee52d3c12945 (diff) | |
| download | patches-53aa7b785b8cd367068f565006620f9e3eb68108.tar.gz | |
usb musb patches, finally...
| -rw-r--r-- | series | 16 | ||||
| -rw-r--r-- | usb.current/usb-musb-cppi-bugfixes.patch | 75 | ||||
| -rw-r--r-- | usb.current/usb-musb-cppi-dma-fix.patch | 33 | ||||
| -rw-r--r-- | usb.current/usb-musb-davinci-buildfix.patch | 60 | ||||
| -rw-r--r-- | usb.current/usb-musb-free_irq-bugfix.patch | 38 | ||||
| -rw-r--r-- | usb.current/usb-musb-tusb6010-buildfix.patch | 39 | ||||
| -rw-r--r-- | usb.current/usb-musb-uses-endpoint-functions.patch | 110 | ||||
| -rw-r--r-- | usb.current/usb-musb_hdrc-another-davinci-buildfix.patch | 66 | ||||
| -rw-r--r-- | usb.current/usb-omap1-ohci-buildfix.patch | 57 | ||||
| -rw-r--r-- | usb.current/usb-prevent-musb-init-oops.patch | 39 | ||||
| -rw-r--r-- | usb/usb-gpio_vbus-add-delayed-vbus_session-calls.patch | 197 | ||||
| -rw-r--r-- | usb/usb-pxa27x_udc-add-otg-transceiver-support.patch | 122 | ||||
| -rw-r--r-- | usb/usb-pxa27x_udc-add-vbus-session-handling.patch | 123 | ||||
| -rw-r--r-- | usb/usb-pxa27x_udc-add-vbus_draw-callback.patch | 66 | ||||
| -rw-r--r-- | usb/usb-pxa27x_udc-factor-pullup-code-to-prepare-otg-transceiver.patch | 315 |
15 files changed, 1354 insertions, 2 deletions
@@ -27,7 +27,15 @@ usb.current/usb-storage-add-unusual-devs-entry.patch usb.current/usb-don-t-enable-wakeup-by-default-for-pci-host-controllers.patch usb.current/usb-fix-suspend-resume-of-pci-usb-controllers.patch usb.current/usb-fix-char-device-disconnect-handling.patch - +usb.current/usb-omap1-ohci-buildfix.patch +usb.current/usb-musb-davinci-buildfix.patch +usb.current/usb-musb_hdrc-another-davinci-buildfix.patch +usb.current/usb-musb-free_irq-bugfix.patch +usb.current/usb-prevent-musb-init-oops.patch +usb.current/usb-musb-tusb6010-buildfix.patch +usb.current/usb-musb-uses-endpoint-functions.patch +usb.current/usb-musb-cppi-bugfixes.patch +usb.current/usb-musb-cppi-dma-fix.patch ##################################################################### @@ -82,6 +90,11 @@ driver-core/warn-when-statically-allocated-kobjects-are-used.patch # USB stuff (after 2.6.29 is out) ################################# usb/usblp-continuously-poll-for-status.patch +usb/usb-gpio_vbus-add-delayed-vbus_session-calls.patch +usb/usb-pxa27x_udc-factor-pullup-code-to-prepare-otg-transceiver.patch +usb/usb-pxa27x_udc-add-vbus-session-handling.patch +usb/usb-pxa27x_udc-add-otg-transceiver-support.patch +usb/usb-pxa27x_udc-add-vbus_draw-callback.patch # stuff I want in my tree, but not to go into -next gregkh.post/usb-gotemp.patch @@ -186,4 +199,3 @@ staging/staging-dst-fix-build-dependancy.patch staging/staging-add-stlc45xx-wi-fi-driver-for-stlc4550-4560.patch - diff --git a/usb.current/usb-musb-cppi-bugfixes.patch b/usb.current/usb-musb-cppi-bugfixes.patch new file mode 100644 index 00000000000000..a1f6a8fdc2d787 --- /dev/null +++ b/usb.current/usb-musb-cppi-bugfixes.patch @@ -0,0 +1,75 @@ +From david-b@pacbell.net Sun Jan 25 12:55:57 2009 +From: Hugo Villeneuve <hugo@hugovil.com> +Date: Sat, 24 Jan 2009 17:57:30 -0800 +Subject: USB: musb cppi bugfixes +To: linux-usb@vger.kernel.org +Cc: Greg KH <greg@kroah.com>, Felipe Balbi <felipebalbi@users.sourceforge.net>, Hugo Villeneuve <hugo@hugovil.com> +Message-ID: <200901241757.30836.david-b@pacbell.net> +Content-Disposition: inline + + +From: Hugo Villeneuve <hugo@hugovil.com> + +These compilation errors are related to incorrect +debugging macro and variable names and generated the +following errors: + + drivers/usb/musb/cppi_dma.c:437:5: warning: "MUSB_DEBUG" is not defined + drivers/usb/musb/cppi_dma.c: In function 'cppi_next_rx_segment': + drivers/usb/musb/cppi_dma.c:884: error: 'debug' undeclared (first use in this function) + +Signed-off-by: Hugo Villeneuve <hugo@hugovil.com> +Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/musb/cppi_dma.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/drivers/usb/musb/cppi_dma.c ++++ b/drivers/usb/musb/cppi_dma.c +@@ -9,6 +9,7 @@ + #include <linux/usb.h> + + #include "musb_core.h" ++#include "musb_debug.h" + #include "cppi_dma.h" + + +@@ -423,6 +424,7 @@ cppi_rndis_update(struct cppi_channel *c + } + } + ++#ifdef CONFIG_USB_MUSB_DEBUG + static void cppi_dump_rxbd(const char *tag, struct cppi_descriptor *bd) + { + pr_debug("RXBD/%s %08x: " +@@ -431,10 +433,11 @@ static void cppi_dump_rxbd(const char *t + bd->hw_next, bd->hw_bufp, bd->hw_off_len, + bd->hw_options); + } ++#endif + + static void cppi_dump_rxq(int level, const char *tag, struct cppi_channel *rx) + { +-#if MUSB_DEBUG > 0 ++#ifdef CONFIG_USB_MUSB_DEBUG + struct cppi_descriptor *bd; + + if (!_dbg_level(level)) +@@ -881,12 +884,14 @@ cppi_next_rx_segment(struct musb *musb, + bd->hw_options |= CPPI_SOP_SET; + tail->hw_options |= CPPI_EOP_SET; + +- if (debug >= 5) { ++#ifdef CONFIG_USB_MUSB_DEBUG ++ if (_dbg_level(5)) { + struct cppi_descriptor *d; + + for (d = rx->head; d; d = d->next) + cppi_dump_rxbd("S", d); + } ++#endif + + /* in case the preceding transfer left some state... */ + tail = rx->last_processed; diff --git a/usb.current/usb-musb-cppi-dma-fix.patch b/usb.current/usb-musb-cppi-dma-fix.patch new file mode 100644 index 00000000000000..274f4c28c3e7ba --- /dev/null +++ b/usb.current/usb-musb-cppi-dma-fix.patch @@ -0,0 +1,33 @@ +From david-b@pacbell.net Sun Jan 25 12:56:13 2009 +From: Swaminathan S <swami.iyer@ti.com> +Date: Sat, 24 Jan 2009 17:57:37 -0800 +Subject: USB: musb cppi dma fix +To: linux-usb@vger.kernel.org +Cc: Greg KH <greg@kroah.com>, Felipe Balbi <felipebalbi@users.sourceforge.net> +Message-ID: <200901241757.37411.david-b@pacbell.net> +Content-Disposition: inline + + +From: Swaminathan S <swami.iyer@ti.com> + +Initializes the actual_len field to 0 before every DMA transaction. + +Signed-off-by: Swaminathan S <swami.iyer@ti.com> +Acked-by: Felipe Balbi <felipe.balbi@nokia.com> +Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/musb/cppi_dma.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/musb/cppi_dma.c ++++ b/drivers/usb/musb/cppi_dma.c +@@ -995,6 +995,7 @@ static int cppi_channel_program(struct d + cppi_ch->offset = 0; + cppi_ch->maxpacket = maxpacket; + cppi_ch->buf_len = len; ++ cppi_ch->channel.actual_len = 0; + + /* TX channel? or RX? */ + if (cppi_ch->transmit) diff --git a/usb.current/usb-musb-davinci-buildfix.patch b/usb.current/usb-musb-davinci-buildfix.patch new file mode 100644 index 00000000000000..b4551e48cf3336 --- /dev/null +++ b/usb.current/usb-musb-davinci-buildfix.patch @@ -0,0 +1,60 @@ +From david-b@pacbell.net Sun Jan 25 12:53:56 2009 +From: David Brownell <david-b@pacbell.net> +Date: Sat, 24 Jan 2009 17:56:17 -0800 +Subject: USB: musb davinci buildfix +To: linux-usb@vger.kernel.org +Cc: Greg KH <greg@kroah.com>, Felipe Balbi <felipebalbi@users.sourceforge.net>, Kevin Hilman <khilman@deeprootsystems.com> +Message-ID: <200901241756.17172.david-b@pacbell.net> +Content-Disposition: inline + + +From: David Brownell <dbrownell@users.sourceforge.net> + +Trying once more to get this merged. The original was submitted +for 2.6.27-rc2 or so, and never got correctly merged. Neither +were any of the numerous subsequent resends. Sigh. + + CC drivers/usb/musb/davinci.o +drivers/usb/musb/davinci.c:35:32: error: mach/arch/hardware.h: No such file or directory +drivers/usb/musb/davinci.c:36:30: error: mach/arch/memory.h: No such file or directory +drivers/usb/musb/davinci.c:37:28: error: mach/arch/gpio.h: No such file or directory +drivers/usb/musb/davinci.c:373: error: redefinition of 'musb_platform_set_mode' +drivers/usb/musb/davinci.c:368: error: previous definition of 'musb_platform_set_mode' was here + +Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> +Acked-by: Felipe Balbi <felipe.balbi@nokia.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/musb/davinci.c | 13 ++++--------- + 1 file changed, 4 insertions(+), 9 deletions(-) + +--- a/drivers/usb/musb/davinci.c ++++ b/drivers/usb/musb/davinci.c +@@ -32,9 +32,10 @@ + #include <linux/io.h> + #include <linux/gpio.h> + +-#include <mach/arch/hardware.h> +-#include <mach/arch/memory.h> +-#include <mach/arch/gpio.h> ++#include <mach/hardware.h> ++#include <mach/memory.h> ++#include <mach/gpio.h> ++ + #include <asm/mach-types.h> + + #include "musb_core.h" +@@ -370,12 +371,6 @@ int musb_platform_set_mode(struct musb * + return -EIO; + } + +-int musb_platform_set_mode(struct musb *musb, u8 mode) +-{ +- /* EVM can't do this (right?) */ +- return -EIO; +-} +- + int __init musb_platform_init(struct musb *musb) + { + void __iomem *tibase = musb->ctrl_base; diff --git a/usb.current/usb-musb-free_irq-bugfix.patch b/usb.current/usb-musb-free_irq-bugfix.patch new file mode 100644 index 00000000000000..0e86c86de558ae --- /dev/null +++ b/usb.current/usb-musb-free_irq-bugfix.patch @@ -0,0 +1,38 @@ +From david-b@pacbell.net Sun Jan 25 12:54:30 2009 +From: Ajay Kumar Gupta <ajay.gupta@ti.com> +Date: Sat, 24 Jan 2009 17:56:39 -0800 +Subject: USB: musb free_irq bugfix +To: linux-usb@vger.kernel.org +Cc: Greg KH <greg@kroah.com>, Felipe Balbi <felipebalbi@users.sourceforge.net>, Ajay Kumar Gupta <ajay.gupta@ti.com> +Message-ID: <200901241756.39927.david-b@pacbell.net> +Content-Disposition: inline + + +From: Ajay Kumar Gupta <ajay.gupta@ti.com> + +Fixes insert module failure as free_irq() was not +done in previous rmmod. + +Signed-off-by: Ajay Kumar Gupta <ajay.gupta@ti.com> +Acked-by: Felipe Balbi <felipe.balbi@nokia.com> +Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/musb/musb_core.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/usb/musb/musb_core.c ++++ b/drivers/usb/musb/musb_core.c +@@ -1824,8 +1824,9 @@ static void musb_free(struct musb *musb) + musb_gadget_cleanup(musb); + #endif + +- if (musb->nIrq >= 0 && musb->irq_wake) { +- disable_irq_wake(musb->nIrq); ++ if (musb->nIrq >= 0) { ++ if (musb->irq_wake) ++ disable_irq_wake(musb->nIrq); + free_irq(musb->nIrq, musb); + } + if (is_dma_capable() && musb->dma_controller) { diff --git a/usb.current/usb-musb-tusb6010-buildfix.patch b/usb.current/usb-musb-tusb6010-buildfix.patch new file mode 100644 index 00000000000000..14a6c1c6174594 --- /dev/null +++ b/usb.current/usb-musb-tusb6010-buildfix.patch @@ -0,0 +1,39 @@ +From david-b@pacbell.net Sun Jan 25 12:55:14 2009 +From: Kalle Valo <kalle.valo@nokia.com> +Date: Sat, 24 Jan 2009 17:57:15 -0800 +Subject: USB: musb: tusb6010 buildfix +To: linux-usb@vger.kernel.org +Cc: Greg KH <greg@kroah.com>, Felipe Balbi <felipebalbi@users.sourceforge.net>, Kalle Valo <kalle.valo@nokia.com> +Message-ID: <200901241757.15282.david-b@pacbell.net> +Content-Disposition: inline + + +From: Kalle Valo <kalle.valo@nokia.com> + +drivers/usb/musb/tusb6010_omap.c:18:26: error: asm/arch/dma.h: + No such file or directory +drivers/usb/musb/tusb6010_omap.c:19:26: error: asm/arch/mux.h: + No such file or directory + +Signed-off-by: Kalle Valo <kalle.valo@nokia.com> +Acked-by: Felipe Balbi <felipe.balbi@nokia.com> +Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/musb/tusb6010_omap.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/usb/musb/tusb6010_omap.c ++++ b/drivers/usb/musb/tusb6010_omap.c +@@ -15,8 +15,8 @@ + #include <linux/usb.h> + #include <linux/platform_device.h> + #include <linux/dma-mapping.h> +-#include <asm/arch/dma.h> +-#include <asm/arch/mux.h> ++#include <mach/dma.h> ++#include <mach/mux.h> + + #include "musb_core.h" + diff --git a/usb.current/usb-musb-uses-endpoint-functions.patch b/usb.current/usb-musb-uses-endpoint-functions.patch new file mode 100644 index 00000000000000..d85b9c80a80e68 --- /dev/null +++ b/usb.current/usb-musb-uses-endpoint-functions.patch @@ -0,0 +1,110 @@ +From david-b@pacbell.net Sun Jan 25 12:55:33 2009 +From: Julia Lawall <julia@diku.dk> +Date: Sat, 24 Jan 2009 17:57:24 -0800 +Subject: USB: musb uses endpoint functions +To: linux-usb@vger.kernel.org +Cc: Greg KH <greg@kroah.com>, Felipe Balbi <felipebalbi@users.sourceforge.net>, Julia Lawall <julia@diku.dk> +Message-ID: <200901241757.25111.david-b@pacbell.net> +Content-Disposition: inline + + +From: Julia Lawall <julia@diku.dk> + +This set of patches introduces calls to the following set of functions: + +usb_endpoint_dir_in(epd) +usb_endpoint_dir_out(epd) +usb_endpoint_is_bulk_in(epd) +usb_endpoint_is_bulk_out(epd) +usb_endpoint_is_int_in(epd) +usb_endpoint_is_int_out(epd) +usb_endpoint_num(epd) +usb_endpoint_type(epd) +usb_endpoint_xfer_bulk(epd) +usb_endpoint_xfer_control(epd) +usb_endpoint_xfer_int(epd) +usb_endpoint_xfer_isoc(epd) + +In some cases, introducing one of these functions is not possible, and it +just replaces an explicit integer value by one of the following constants: + +USB_ENDPOINT_XFER_BULK +USB_ENDPOINT_XFER_CONTROL +USB_ENDPOINT_XFER_INT +USB_ENDPOINT_XFER_ISOC + +An extract of the semantic patch that makes these changes is as follows: +(http://www.emn.fr/x-info/coccinelle/) + +// <smpl> +@r1@ struct usb_endpoint_descriptor *epd; @@ + +- ((epd->bmAttributes & \(USB_ENDPOINT_XFERTYPE_MASK\|3\)) == +- \(USB_ENDPOINT_XFER_CONTROL\|0\)) ++ usb_endpoint_xfer_control(epd) + +@r5@ struct usb_endpoint_descriptor *epd; @@ + +- ((epd->bEndpointAddress & \(USB_ENDPOINT_DIR_MASK\|0x80\)) == +- \(USB_DIR_IN\|0x80\)) ++ usb_endpoint_dir_in(epd) + +@inc@ +@@ + +#include <linux/usb.h> + +@depends on !inc && (r1||r5)@ +@@ + ++ #include <linux/usb.h> + #include <linux/usb/...> +// </smpl> + +Signed-off-by: Julia Lawall <julia@diku.dk> +Acked-by: Felipe Balbi <felipe.balbi@nokia.com> +Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/musb/musb_gadget.c | 6 +++--- + drivers/usb/musb/musb_host.c | 4 ++-- + 2 files changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/usb/musb/musb_gadget.c ++++ b/drivers/usb/musb/musb_gadget.c +@@ -874,10 +874,10 @@ static int musb_gadget_enable(struct usb + status = -EBUSY; + goto fail; + } +- musb_ep->type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; ++ musb_ep->type = usb_endpoint_type(desc); + + /* check direction and (later) maxpacket size against endpoint */ +- if ((desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) != epnum) ++ if (usb_endpoint_num(desc) != epnum) + goto fail; + + /* REVISIT this rules out high bandwidth periodic transfers */ +@@ -890,7 +890,7 @@ static int musb_gadget_enable(struct usb + * packet size (or fail), set the mode, clear the fifo + */ + musb_ep_select(mbase, epnum); +- if (desc->bEndpointAddress & USB_DIR_IN) { ++ if (usb_endpoint_dir_in(desc)) { + u16 int_txe = musb_readw(mbase, MUSB_INTRTXE); + + if (hw_ep->is_shared_fifo) +--- a/drivers/usb/musb/musb_host.c ++++ b/drivers/usb/musb/musb_host.c +@@ -1847,8 +1847,8 @@ static int musb_urb_enqueue( + goto done; + } + +- qh->epnum = epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; +- qh->type = epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; ++ qh->epnum = usb_endpoint_num(epd); ++ qh->type = usb_endpoint_type(epd); + + /* NOTE: urb->dev->devnum is wrong during SET_ADDRESS */ + qh->addr_reg = (u8) usb_pipedevice(urb->pipe); diff --git a/usb.current/usb-musb_hdrc-another-davinci-buildfix.patch b/usb.current/usb-musb_hdrc-another-davinci-buildfix.patch new file mode 100644 index 00000000000000..9bd7ee93ae114c --- /dev/null +++ b/usb.current/usb-musb_hdrc-another-davinci-buildfix.patch @@ -0,0 +1,66 @@ +From david-b@pacbell.net Sun Jan 25 12:54:12 2009 +From: David Brownell <david-b@pacbell.net> +Date: Sat, 24 Jan 2009 17:56:25 -0800 +Subject: USB: musb_hdrc: another davinci buildfix (otg related) +To: linux-usb@vger.kernel.org +Cc: Greg KH <greg@kroah.com>, Felipe Balbi <felipebalbi@users.sourceforge.net>, Kevin Hilman <khilman@deeprootsystems.com> +Message-ID: <200901241756.25190.david-b@pacbell.net> +Content-Disposition: inline + + +From: David Brownell <dbrownell@users.sourceforge.net> + +The DaVinci code had an implementation of the OTG transceiver glue +too; make it use the new-standard one. + +Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> +Acked-by: Felipe Balbi <felipe.balbi@nokia.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + arch/arm/mach-davinci/usb.c | 23 ----------------------- + drivers/usb/musb/Kconfig | 1 + + 2 files changed, 1 insertion(+), 23 deletions(-) + +--- a/arch/arm/mach-davinci/usb.c ++++ b/arch/arm/mach-davinci/usb.c +@@ -76,29 +76,6 @@ static struct platform_device usb_dev = + .num_resources = ARRAY_SIZE(usb_resources), + }; + +-#ifdef CONFIG_USB_MUSB_OTG +- +-static struct otg_transceiver *xceiv; +- +-struct otg_transceiver *otg_get_transceiver(void) +-{ +- if (xceiv) +- get_device(xceiv->dev); +- return xceiv; +-} +-EXPORT_SYMBOL(otg_get_transceiver); +- +-int otg_set_transceiver(struct otg_transceiver *x) +-{ +- if (xceiv && x) +- return -EBUSY; +- xceiv = x; +- return 0; +-} +-EXPORT_SYMBOL(otg_set_transceiver); +- +-#endif +- + void __init setup_usb(unsigned mA, unsigned potpgt_msec) + { + usb_data.power = mA / 2; +--- a/drivers/usb/musb/Kconfig ++++ b/drivers/usb/musb/Kconfig +@@ -11,6 +11,7 @@ config USB_MUSB_HDRC + depends on (USB || USB_GADGET) && HAVE_CLK + depends on !SUPERH + select TWL4030_USB if MACH_OMAP_3430SDP ++ select USB_OTG_UTILS + tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)' + help + Say Y here if your system has a dual role high speed USB diff --git a/usb.current/usb-omap1-ohci-buildfix.patch b/usb.current/usb-omap1-ohci-buildfix.patch new file mode 100644 index 00000000000000..4b535f83d12cd7 --- /dev/null +++ b/usb.current/usb-omap1-ohci-buildfix.patch @@ -0,0 +1,57 @@ +From david-b@pacbell.net Sun Jan 25 12:53:37 2009 +From: David Brownell <david-b@pacbell.net> +Date: Sat, 24 Jan 2009 17:55:57 -0800 +Subject: USB: omap1 ohci buildfix (otg related) +To: linux-usb@vger.kernel.org +Cc: Greg KH <greg@kroah.com>, Russell King <rmk@arm.linux.org.uk>, Tony Lindgren <tony@atomide.com> +Message-ID: <200901241755.57741.david-b@pacbell.net> +Content-Disposition: inline + + +From: David Brownell <dbrownell@users.sourceforge.net> + + > > drivers/built-in.o: In function `ohci_omap_init': + > > hid-quirks.c:(.text+0x6c608): undefined reference to `otg_get_transceiver' + > > drivers/built-in.o: In function `omap_udc_probe': + > > hid-quirks.c:(.init.text+0x34c0): undefined reference to `otg_get_transceiver' + > > hid-quirks.c:(.init.text+0x3d40): undefined reference to `otg_put_transceiver' + +Reported-by: Russell King <linux@arm.linux.org.uk> +Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> +Acked-by: Tony Lindgren <tony@atomide.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/host/Kconfig | 1 + + drivers/usb/otg/Kconfig | 4 ++-- + 2 files changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/usb/host/Kconfig ++++ b/drivers/usb/host/Kconfig +@@ -140,6 +140,7 @@ config USB_OHCI_HCD + tristate "OHCI HCD support" + depends on USB && USB_ARCH_HAS_OHCI + select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 ++ select USB_OTG_UTILS if ARCH_OMAP + ---help--- + The Open Host Controller Interface (OHCI) is a standard for accessing + USB 1.1 host controller hardware. It does more in hardware than Intel's +--- a/drivers/usb/otg/Kconfig ++++ b/drivers/usb/otg/Kconfig +@@ -6,14 +6,14 @@ + + comment "OTG and related infrastructure" + +-if USB || USB_GADGET +- + config USB_OTG_UTILS + bool + help + Select this to make sure the build includes objects from + the OTG infrastructure directory. + ++if USB || USB_GADGET ++ + # + # USB Transceiver Drivers + # diff --git a/usb.current/usb-prevent-musb-init-oops.patch b/usb.current/usb-prevent-musb-init-oops.patch new file mode 100644 index 00000000000000..359e9c31b2aa3f --- /dev/null +++ b/usb.current/usb-prevent-musb-init-oops.patch @@ -0,0 +1,39 @@ +From david-b@pacbell.net Sun Jan 25 12:54:56 2009 +From: Ajay Kumar Gupta <ajay.gupta@ti.com> +Date: Sat, 24 Jan 2009 17:57:06 -0800 +Subject: USB: prevent musb init oops (otg related) +To: linux-usb@vger.kernel.org +Cc: Greg KH <greg@kroah.com>, Felipe Balbi <felipebalbi@users.sourceforge.net>, Ajay Kumar Gupta <ajay.gupta@ti.com> +Message-ID: <200901241757.06185.david-b@pacbell.net> +Content-Disposition: inline + + +From: Ajay Kumar Gupta <ajay.gupta@ti.com> + +Subject: usb: musb: fix null pointer check in musb_platform_init() + +Fixes kernel panic when musb is selected for OMAP35x EVM but twl4030 is not +selected as in this case otg_get_transceiver() returns null. + +Signed-off-by: Ajay Kumar Gupta <ajay.gupta@ti.com> +Acked-by: Felipe Balbi <felipe.balbi@nokia.com> +Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/musb/omap2430.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/usb/musb/omap2430.c ++++ b/drivers/usb/musb/omap2430.c +@@ -231,6 +231,10 @@ int __init musb_platform_init(struct mus + #if defined(CONFIG_ARCH_OMAP2430) + omap_cfg_reg(AE5_2430_USB0HS_STP); + #endif ++ if (!x) { ++ pr_err("omap: musb: null transceiver found\n"); ++ return -ENODEV; ++ } + + musb_platform_resume(musb); + diff --git a/usb/usb-gpio_vbus-add-delayed-vbus_session-calls.patch b/usb/usb-gpio_vbus-add-delayed-vbus_session-calls.patch new file mode 100644 index 00000000000000..25f65675972e17 --- /dev/null +++ b/usb/usb-gpio_vbus-add-delayed-vbus_session-calls.patch @@ -0,0 +1,197 @@ +From david-b@pacbell.net Sun Jan 25 12:56:37 2009 +From: Robert Jarzmik <robert.jarzmik@free.fr> +Date: Sat, 24 Jan 2009 23:54:31 -0800 +Subject: USB: gpio_vbus: add delayed vbus_session calls +To: Greg KH <greg@kroah.com> +Cc: linux-usb@vger.kernel.org, Robert Jarzmik <robert.jarzmik@free.fr> +Message-ID: <200901242354.31639.david-b@pacbell.net> +Content-Disposition: inline + + +From: Robert Jarzmik <robert.jarzmik@free.fr> + +Call usb_gadget_vbus_connect() and ...disconnect() from a +workqueue rather than from an irq handler, allowing msleep() +calls in vbus_session. Update kerneldoc to match. + +[ dbrownell@users.sourceforge.net: more kerneldoc updates ] + +Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr> +Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/otg/gpio_vbus.c | 42 +++++++++++++++++++++++++++++++----------- + include/linux/usb/gadget.h | 6 ++++-- + include/linux/usb/otg.h | 4 ++++ + 3 files changed, 39 insertions(+), 13 deletions(-) + +--- a/drivers/usb/otg/gpio_vbus.c ++++ b/drivers/usb/otg/gpio_vbus.c +@@ -13,6 +13,7 @@ + #include <linux/gpio.h> + #include <linux/interrupt.h> + #include <linux/usb.h> ++#include <linux/workqueue.h> + + #include <linux/regulator/consumer.h> + +@@ -34,6 +35,7 @@ struct gpio_vbus_data { + struct regulator *vbus_draw; + int vbus_draw_enabled; + unsigned mA; ++ struct work_struct work; + }; + + +@@ -76,24 +78,26 @@ static void set_vbus_draw(struct gpio_vb + gpio_vbus->mA = mA; + } + +-/* VBUS change IRQ handler */ +-static irqreturn_t gpio_vbus_irq(int irq, void *data) ++static int is_vbus_powered(struct gpio_vbus_mach_info *pdata) + { +- struct platform_device *pdev = data; +- struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data; +- struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev); +- int gpio, vbus; ++ int vbus; + + vbus = gpio_get_value(pdata->gpio_vbus); + if (pdata->gpio_vbus_inverted) + vbus = !vbus; + +- dev_dbg(&pdev->dev, "VBUS %s (gadget: %s)\n", +- vbus ? "supplied" : "inactive", +- gpio_vbus->otg.gadget ? gpio_vbus->otg.gadget->name : "none"); ++ return vbus; ++} ++ ++static void gpio_vbus_work(struct work_struct *work) ++{ ++ struct gpio_vbus_data *gpio_vbus = ++ container_of(work, struct gpio_vbus_data, work); ++ struct gpio_vbus_mach_info *pdata = gpio_vbus->dev->platform_data; ++ int gpio; + + if (!gpio_vbus->otg.gadget) +- return IRQ_HANDLED; ++ return; + + /* Peripheral controllers which manage the pullup themselves won't have + * gpio_pullup configured here. If it's configured here, we'll do what +@@ -101,7 +105,7 @@ static irqreturn_t gpio_vbus_irq(int irq + * that may complicate usb_gadget_{,dis}connect() support. + */ + gpio = pdata->gpio_pullup; +- if (vbus) { ++ if (is_vbus_powered(pdata)) { + gpio_vbus->otg.state = OTG_STATE_B_PERIPHERAL; + usb_gadget_vbus_connect(gpio_vbus->otg.gadget); + +@@ -121,6 +125,21 @@ static irqreturn_t gpio_vbus_irq(int irq + usb_gadget_vbus_disconnect(gpio_vbus->otg.gadget); + gpio_vbus->otg.state = OTG_STATE_B_IDLE; + } ++} ++ ++/* VBUS change IRQ handler */ ++static irqreturn_t gpio_vbus_irq(int irq, void *data) ++{ ++ struct platform_device *pdev = data; ++ struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data; ++ struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev); ++ ++ dev_dbg(&pdev->dev, "VBUS %s (gadget: %s)\n", ++ is_vbus_powered(pdata) ? "supplied" : "inactive", ++ gpio_vbus->otg.gadget ? gpio_vbus->otg.gadget->name : "none"); ++ ++ if (gpio_vbus->otg.gadget) ++ schedule_work(&gpio_vbus->work); + + return IRQ_HANDLED; + } +@@ -257,6 +276,7 @@ static int __init gpio_vbus_probe(struct + irq, err); + goto err_irq; + } ++ INIT_WORK(&gpio_vbus->work, gpio_vbus_work); + + /* only active when a gadget is registered */ + err = otg_set_transceiver(&gpio_vbus->otg); +--- a/include/linux/usb/gadget.h ++++ b/include/linux/usb/gadget.h +@@ -598,6 +598,7 @@ static inline int usb_gadget_clear_selfp + /** + * usb_gadget_vbus_connect - Notify controller that VBUS is powered + * @gadget:The device which now has VBUS power. ++ * Context: can sleep + * + * This call is used by a driver for an external transceiver (or GPIO) + * that detects a VBUS power session starting. Common responses include +@@ -636,6 +637,7 @@ static inline int usb_gadget_vbus_draw(s + /** + * usb_gadget_vbus_disconnect - notify controller about VBUS session end + * @gadget:the device whose VBUS supply is being described ++ * Context: can sleep + * + * This call is used by a driver for an external transceiver (or GPIO) + * that detects a VBUS power session ending. Common responses include +@@ -792,19 +794,20 @@ struct usb_gadget_driver { + /** + * usb_gadget_register_driver - register a gadget driver + * @driver:the driver being registered ++ * Context: can sleep + * + * Call this in your gadget driver's module initialization function, + * to tell the underlying usb controller driver about your driver. + * The driver's bind() function will be called to bind it to a + * gadget before this registration call returns. It's expected that + * the bind() functions will be in init sections. +- * This function must be called in a context that can sleep. + */ + int usb_gadget_register_driver(struct usb_gadget_driver *driver); + + /** + * usb_gadget_unregister_driver - unregister a gadget driver + * @driver:the driver being unregistered ++ * Context: can sleep + * + * Call this in your gadget driver's module cleanup function, + * to tell the underlying usb controller that your driver is +@@ -813,7 +816,6 @@ int usb_gadget_register_driver(struct us + * to unbind() and clean up any device state, before this procedure + * finally returns. It's expected that the unbind() functions + * will in in exit sections, so may not be linked in some kernels. +- * This function must be called in a context that can sleep. + */ + int usb_gadget_unregister_driver(struct usb_gadget_driver *driver); + +--- a/include/linux/usb/otg.h ++++ b/include/linux/usb/otg.h +@@ -86,6 +86,7 @@ extern int otg_set_transceiver(struct ot + extern struct otg_transceiver *otg_get_transceiver(void); + extern void otg_put_transceiver(struct otg_transceiver *); + ++/* Context: can sleep */ + static inline int + otg_start_hnp(struct otg_transceiver *otg) + { +@@ -102,6 +103,8 @@ otg_set_host(struct otg_transceiver *otg + + + /* for usb peripheral controller drivers */ ++ ++/* Context: can sleep */ + static inline int + otg_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *periph) + { +@@ -114,6 +117,7 @@ otg_set_power(struct otg_transceiver *ot + return otg->set_power(otg, mA); + } + ++/* Context: can sleep */ + static inline int + otg_set_suspend(struct otg_transceiver *otg, int suspend) + { diff --git a/usb/usb-pxa27x_udc-add-otg-transceiver-support.patch b/usb/usb-pxa27x_udc-add-otg-transceiver-support.patch new file mode 100644 index 00000000000000..d3a5d9d5dfc6df --- /dev/null +++ b/usb/usb-pxa27x_udc-add-otg-transceiver-support.patch @@ -0,0 +1,122 @@ +From david-b@pacbell.net Sun Jan 25 12:57:27 2009 +From: Robert Jarzmik <robert.jarzmik@free.fr> +Date: Sat, 24 Jan 2009 23:57:30 -0800 +Subject: USB: pxa27x_udc: add otg transceiver support +To: Greg KH <greg@kroah.com> +Cc: linux-usb@vger.kernel.org, Robert Jarzmik <robert.jarzmik@free.fr> +Message-ID: <200901242357.30720.david-b@pacbell.net> +Content-Disposition: inline + + +From: Robert Jarzmik <robert.jarzmik@free.fr> + +When a transceiver driver is used, no automatic udc enable +is done. The transceiver (OTG or not) should : + - take care of VBus sensing + - call usb_gadget_vbus_connect() + - call usb_gadget_vbus_disconnect() + +The pullup should remain within this driver's management, +either by gpio_pullup of udc_command() fields. + +Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr> +Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/gadget/Kconfig | 1 + + drivers/usb/gadget/pxa27x_udc.c | 19 ++++++++++++++++++- + drivers/usb/gadget/pxa27x_udc.h | 3 +++ + 3 files changed, 22 insertions(+), 1 deletion(-) + +--- a/drivers/usb/gadget/Kconfig ++++ b/drivers/usb/gadget/Kconfig +@@ -253,6 +253,7 @@ config USB_PXA25X_SMALL + config USB_GADGET_PXA27X + boolean "PXA 27x" + depends on ARCH_PXA && PXA27x ++ select USB_OTG_UTILS + help + Intel's PXA 27x series XScale ARM v5TE processors include + an integrated full speed USB 1.1 device controller. +--- a/drivers/usb/gadget/pxa27x_udc.c ++++ b/drivers/usb/gadget/pxa27x_udc.c +@@ -1779,10 +1779,21 @@ int usb_gadget_register_driver(struct us + dev_dbg(udc->dev, "registered gadget driver '%s'\n", + driver->driver.name); + ++ if (udc->transceiver) { ++ retval = otg_set_peripheral(udc->transceiver, &udc->gadget); ++ if (retval) { ++ dev_err(udc->dev, "can't bind to transceiver\n"); ++ goto transceiver_fail; ++ } ++ } ++ + if (should_enable_udc(udc)) + udc_enable(udc); + return 0; + ++transceiver_fail: ++ if (driver->unbind) ++ driver->unbind(&udc->gadget); + bind_fail: + device_del(&udc->gadget.dev); + add_fail: +@@ -1840,9 +1851,11 @@ int usb_gadget_unregister_driver(struct + udc->driver = NULL; + + device_del(&udc->gadget.dev); +- + dev_info(udc->dev, "unregistered gadget driver '%s'\n", + driver->driver.name); ++ ++ if (udc->transceiver) ++ return otg_set_peripheral(udc->transceiver, NULL); + return 0; + } + EXPORT_SYMBOL(usb_gadget_unregister_driver); +@@ -2359,6 +2372,7 @@ static int __init pxa_udc_probe(struct p + + udc->dev = &pdev->dev; + udc->mach = pdev->dev.platform_data; ++ udc->transceiver = otg_get_transceiver(); + + gpio = udc->mach->gpio_pullup; + if (gpio_is_valid(gpio)) { +@@ -2431,6 +2445,9 @@ static int __exit pxa_udc_remove(struct + if (gpio_is_valid(gpio)) + gpio_free(gpio); + ++ otg_put_transceiver(udc->transceiver); ++ ++ udc->transceiver = NULL; + platform_set_drvdata(_dev, NULL); + the_controller = NULL; + clk_put(udc->clk); +--- a/drivers/usb/gadget/pxa27x_udc.h ++++ b/drivers/usb/gadget/pxa27x_udc.h +@@ -26,6 +26,7 @@ + #include <linux/types.h> + #include <linux/spinlock.h> + #include <linux/io.h> ++#include <linux/usb/otg.h> + + /* + * Register definitions +@@ -421,6 +422,7 @@ struct udc_stats { + * @driver: bound gadget (zero, g_ether, g_file_storage, ...) + * @dev: device + * @mach: machine info, used to activate specific GPIO ++ * @transceiver: external transceiver to handle vbus sense and D+ pullup + * @ep0state: control endpoint state machine state + * @stats: statistics on udc usage + * @udc_usb_ep: array of usb endpoints offered by the gadget +@@ -446,6 +448,7 @@ struct pxa_udc { + struct usb_gadget_driver *driver; + struct device *dev; + struct pxa2xx_udc_mach_info *mach; ++ struct otg_transceiver *transceiver; + + enum ep0_state ep0state; + struct udc_stats stats; diff --git a/usb/usb-pxa27x_udc-add-vbus-session-handling.patch b/usb/usb-pxa27x_udc-add-vbus-session-handling.patch new file mode 100644 index 00000000000000..8755de62f082d7 --- /dev/null +++ b/usb/usb-pxa27x_udc-add-vbus-session-handling.patch @@ -0,0 +1,123 @@ +From david-b@pacbell.net Sun Jan 25 12:57:11 2009 +From: Robert Jarzmik <robert.jarzmik@free.fr> +Date: Sat, 24 Jan 2009 23:56:42 -0800 +Subject: USB: pxa27x_udc: add vbus session handling +To: Greg KH <greg@kroah.com> +Cc: linux-usb@vger.kernel.org, Robert Jarzmik <robert.jarzmik@free.fr> +Message-ID: <200901242356.42280.david-b@pacbell.net> +Content-Disposition: inline + + +From: Robert Jarzmik <robert.jarzmik@free.fr> + +On vbus_session() call, optionally activate D+ pullup +resistor and enable the udc, or deactivate D+ pullup +resistor and disable the udc. + +It is intentional to not handle any VBus sense related irq. +An external transceiver driver (like gpio_vbus) should +catch VBus sense signal, and call usb_gadget_vbus_connect() +or usb_gadget_vbus_disconnect(). + +Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr> +Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/gadget/pxa27x_udc.c | 33 +++++++++++++++++++++++++++++++++ + drivers/usb/gadget/pxa27x_udc.h | 1 + + 2 files changed, 34 insertions(+) + +--- a/drivers/usb/gadget/pxa27x_udc.c ++++ b/drivers/usb/gadget/pxa27x_udc.c +@@ -1536,8 +1536,10 @@ static void udc_disable(struct pxa_udc * + * Context: any + * + * The UDC should be enabled if : ++ + * - the pullup resistor is connected + * - and a gadget driver is bound ++ * - and vbus is sensed (or no vbus sense is available) + * + * Returns 1 if UDC should be enabled, 0 otherwise + */ +@@ -1546,6 +1548,7 @@ static int should_enable_udc(struct pxa_ + int put_on; + + put_on = ((udc->pullup_on) && (udc->driver)); ++ put_on &= ((udc->vbus_sensed) || (!udc->transceiver)); + return put_on; + } + +@@ -1557,6 +1560,7 @@ static int should_enable_udc(struct pxa_ + * The UDC should be disabled if : + * - the pullup resistor is not connected + * - or no gadget driver is bound ++ * - or no vbus is sensed (when vbus sesing is available) + * + * Returns 1 if UDC should be disabled + */ +@@ -1565,6 +1569,7 @@ static int should_disable_udc(struct pxa + int put_off; + + put_off = ((!udc->pullup_on) || (!udc->driver)); ++ put_off |= ((!udc->vbus_sensed) && (udc->transceiver)); + return put_off; + } + +@@ -1592,10 +1597,37 @@ static int pxa_udc_pullup(struct usb_gad + return 0; + } + ++static void udc_enable(struct pxa_udc *udc); ++static void udc_disable(struct pxa_udc *udc); ++ ++/** ++ * pxa_udc_vbus_session - Called by external transceiver to enable/disable udc ++ * @_gadget: usb gadget ++ * @is_active: 0 if should disable the udc, 1 if should enable ++ * ++ * Enables the udc, and optionnaly activates D+ pullup resistor. Or disables the ++ * udc, and deactivates D+ pullup resistor. ++ * ++ * Returns 0 ++ */ ++static int pxa_udc_vbus_session(struct usb_gadget *_gadget, int is_active) ++{ ++ struct pxa_udc *udc = to_gadget_udc(_gadget); ++ ++ udc->vbus_sensed = is_active; ++ if (should_enable_udc(udc)) ++ udc_enable(udc); ++ if (should_disable_udc(udc)) ++ udc_disable(udc); ++ ++ return 0; ++} ++ + static const struct usb_gadget_ops pxa_udc_ops = { + .get_frame = pxa_udc_get_frame, + .wakeup = pxa_udc_wakeup, + .pullup = pxa_udc_pullup, ++ .vbus_session = pxa_udc_vbus_session, + /* current versions must always be self-powered */ + }; + +@@ -2357,6 +2389,7 @@ static int __init pxa_udc_probe(struct p + device_initialize(&udc->gadget.dev); + udc->gadget.dev.parent = &pdev->dev; + udc->gadget.dev.dma_mask = NULL; ++ udc->vbus_sensed = 0; + + the_controller = udc; + platform_set_drvdata(pdev, udc); +--- a/drivers/usb/gadget/pxa27x_udc.h ++++ b/drivers/usb/gadget/pxa27x_udc.h +@@ -456,6 +456,7 @@ struct pxa_udc { + unsigned enabled:1; + unsigned pullup_on:1; + unsigned pullup_resume:1; ++ unsigned vbus_sensed:1; + unsigned config:2; + unsigned last_interface:3; + unsigned last_alternate:3; diff --git a/usb/usb-pxa27x_udc-add-vbus_draw-callback.patch b/usb/usb-pxa27x_udc-add-vbus_draw-callback.patch new file mode 100644 index 00000000000000..b211b4c6d719bb --- /dev/null +++ b/usb/usb-pxa27x_udc-add-vbus_draw-callback.patch @@ -0,0 +1,66 @@ +From david-b@pacbell.net Sun Jan 25 12:57:42 2009 +From: Robert Jarzmik <robert.jarzmik@free.fr> +Date: Sat, 24 Jan 2009 23:59:38 -0800 +Subject: USB: pxa27x_udc: add vbus_draw callback +To: Greg KH <greg@kroah.com> +Cc: linux-usb@vger.kernel.org, Robert Jarzmik <robert.jarzmik@free.fr> +Message-ID: <200901242359.38658.david-b@pacbell.net> +Content-Disposition: inline + + +From: Robert Jarzmik <robert.jarzmik@free.fr> + +Add the vbus_draw() callback to inform the transceiver, if +it exists, how much current may be drawn. The decision is +taken on gadget driver side using the configuration chosen +by the host and its bMaxPower field. Some systems can use +the host's VBUS supply to augment or recharge a battery. +(There's also a default of 100 mA for unconfigured devices, +or 8 mA if they're OTG devices.) + +Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr> +Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/gadget/pxa27x_udc.c | 24 +++++++++++++++++++++++- + 1 file changed, 23 insertions(+), 1 deletion(-) + +--- a/drivers/usb/gadget/pxa27x_udc.c ++++ b/drivers/usb/gadget/pxa27x_udc.c +@@ -1623,12 +1623,34 @@ static int pxa_udc_vbus_session(struct u + return 0; + } + ++/** ++ * pxa_udc_vbus_draw - Called by gadget driver after SET_CONFIGURATION completed ++ * @_gadget: usb gadget ++ * @mA: current drawn ++ * ++ * Context: !in_interrupt() ++ * ++ * Called after a configuration was chosen by a USB host, to inform how much ++ * current can be drawn by the device from VBus line. ++ * ++ * Returns 0 or -EOPNOTSUPP if no transceiver is handling the udc ++ */ ++static int pxa_udc_vbus_draw(struct usb_gadget *_gadget, unsigned mA) ++{ ++ struct pxa_udc *udc; ++ ++ udc = to_gadget_udc(_gadget); ++ if (udc->transceiver) ++ return otg_set_power(udc->transceiver, mA); ++ return -EOPNOTSUPP; ++} ++ + static const struct usb_gadget_ops pxa_udc_ops = { + .get_frame = pxa_udc_get_frame, + .wakeup = pxa_udc_wakeup, + .pullup = pxa_udc_pullup, + .vbus_session = pxa_udc_vbus_session, +- /* current versions must always be self-powered */ ++ .vbus_draw = pxa_udc_vbus_draw, + }; + + /** diff --git a/usb/usb-pxa27x_udc-factor-pullup-code-to-prepare-otg-transceiver.patch b/usb/usb-pxa27x_udc-factor-pullup-code-to-prepare-otg-transceiver.patch new file mode 100644 index 00000000000000..788a3110d3b099 --- /dev/null +++ b/usb/usb-pxa27x_udc-factor-pullup-code-to-prepare-otg-transceiver.patch @@ -0,0 +1,315 @@ +From david-b@pacbell.net Sun Jan 25 12:56:56 2009 +From: Robert Jarzmik <robert.jarzmik@free.fr> +Date: Sat, 24 Jan 2009 23:55:34 -0800 +Subject: USB: pxa27x_udc: factor pullup code to prepare otg transceiver +To: Greg KH <greg@kroah.com> +Cc: linux-usb@vger.kernel.org, Robert Jarzmik <robert.jarzmik@free.fr> +Message-ID: <200901242355.34350.david-b@pacbell.net> +Content-Disposition: inline + + +From: Robert Jarzmik <robert.jarzmik@free.fr> + +Prepare pxa27x_udc to handle usb D+ pullup properly : it +should connect the pullup resistor and disconnect it only +if no external transceiver is handling it. + +[ dbrownell@users.sourceforge.net: kerneldoc and gpio fixes ] + +Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr> +Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/gadget/pxa27x_udc.c | 140 +++++++++++++++++++++++++++++++++++++--- + drivers/usb/gadget/pxa27x_udc.h | 6 + + 2 files changed, 138 insertions(+), 8 deletions(-) + +--- a/drivers/usb/gadget/pxa27x_udc.c ++++ b/drivers/usb/gadget/pxa27x_udc.c +@@ -30,6 +30,7 @@ + #include <linux/proc_fs.h> + #include <linux/clk.h> + #include <linux/irq.h> ++#include <linux/gpio.h> + + #include <asm/byteorder.h> + #include <mach/hardware.h> +@@ -1471,6 +1472,32 @@ static struct usb_ep_ops pxa_ep_ops = { + .fifo_flush = pxa_ep_fifo_flush, + }; + ++/** ++ * dplus_pullup - Connect or disconnect pullup resistor to D+ pin ++ * @udc: udc device ++ * @on: 0 if disconnect pullup resistor, 1 otherwise ++ * Context: any ++ * ++ * Handle D+ pullup resistor, make the device visible to the usb bus, and ++ * declare it as a full speed usb device ++ */ ++static void dplus_pullup(struct pxa_udc *udc, int on) ++{ ++ if (on) { ++ if (gpio_is_valid(udc->mach->gpio_pullup)) ++ gpio_set_value(udc->mach->gpio_pullup, ++ !udc->mach->gpio_pullup_inverted); ++ if (udc->mach->udc_command) ++ udc->mach->udc_command(PXA2XX_UDC_CMD_CONNECT); ++ } else { ++ if (gpio_is_valid(udc->mach->gpio_pullup)) ++ gpio_set_value(udc->mach->gpio_pullup, ++ udc->mach->gpio_pullup_inverted); ++ if (udc->mach->udc_command) ++ udc->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT); ++ } ++ udc->pullup_on = on; ++} + + /** + * pxa_udc_get_frame - Returns usb frame number +@@ -1500,21 +1527,91 @@ static int pxa_udc_wakeup(struct usb_gad + return 0; + } + ++static void udc_enable(struct pxa_udc *udc); ++static void udc_disable(struct pxa_udc *udc); ++ ++/** ++ * should_enable_udc - Tells if UDC should be enabled ++ * @udc: udc device ++ * Context: any ++ * ++ * The UDC should be enabled if : ++ * - the pullup resistor is connected ++ * - and a gadget driver is bound ++ * ++ * Returns 1 if UDC should be enabled, 0 otherwise ++ */ ++static int should_enable_udc(struct pxa_udc *udc) ++{ ++ int put_on; ++ ++ put_on = ((udc->pullup_on) && (udc->driver)); ++ return put_on; ++} ++ ++/** ++ * should_disable_udc - Tells if UDC should be disabled ++ * @udc: udc device ++ * Context: any ++ * ++ * The UDC should be disabled if : ++ * - the pullup resistor is not connected ++ * - or no gadget driver is bound ++ * ++ * Returns 1 if UDC should be disabled ++ */ ++static int should_disable_udc(struct pxa_udc *udc) ++{ ++ int put_off; ++ ++ put_off = ((!udc->pullup_on) || (!udc->driver)); ++ return put_off; ++} ++ ++/** ++ * pxa_udc_pullup - Offer manual D+ pullup control ++ * @_gadget: usb gadget using the control ++ * @is_active: 0 if disconnect, else connect D+ pullup resistor ++ * Context: !in_interrupt() ++ * ++ * Returns 0 if OK, -EOPNOTSUPP if udc driver doesn't handle D+ pullup ++ */ ++static int pxa_udc_pullup(struct usb_gadget *_gadget, int is_active) ++{ ++ struct pxa_udc *udc = to_gadget_udc(_gadget); ++ ++ if (!gpio_is_valid(udc->mach->gpio_pullup) && !udc->mach->udc_command) ++ return -EOPNOTSUPP; ++ ++ dplus_pullup(udc, is_active); ++ ++ if (should_enable_udc(udc)) ++ udc_enable(udc); ++ if (should_disable_udc(udc)) ++ udc_disable(udc); ++ return 0; ++} ++ + static const struct usb_gadget_ops pxa_udc_ops = { + .get_frame = pxa_udc_get_frame, + .wakeup = pxa_udc_wakeup, ++ .pullup = pxa_udc_pullup, + /* current versions must always be self-powered */ + }; + + /** + * udc_disable - disable udc device controller + * @udc: udc device ++ * Context: any + * + * Disables the udc device : disables clocks, udc interrupts, control endpoint + * interrupts. + */ + static void udc_disable(struct pxa_udc *udc) + { ++ if (!udc->enabled) ++ return; ++ + udc_writel(udc, UDCICR0, 0); + udc_writel(udc, UDCICR1, 0); + +@@ -1523,8 +1620,8 @@ static void udc_disable(struct pxa_udc * + + ep0_idle(udc); + udc->gadget.speed = USB_SPEED_UNKNOWN; +- if (udc->mach->udc_command) +- udc->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT); ++ ++ udc->enabled = 0; + } + + /** +@@ -1570,6 +1667,9 @@ static __init void udc_init_data(struct + */ + static void udc_enable(struct pxa_udc *udc) + { ++ if (udc->enabled) ++ return; ++ + udc_writel(udc, UDCICR0, 0); + udc_writel(udc, UDCICR1, 0); + udc_clear_mask_UDCCR(udc, UDCCR_UDE); +@@ -1598,9 +1698,7 @@ static void udc_enable(struct pxa_udc *u + /* enable ep0 irqs */ + pio_irq_enable(&udc->pxa_ep[0]); + +- dev_info(udc->dev, "UDC connecting\n"); +- if (udc->mach->udc_command) +- udc->mach->udc_command(PXA2XX_UDC_CMD_CONNECT); ++ udc->enabled = 1; + } + + /** +@@ -1612,6 +1710,9 @@ static void udc_enable(struct pxa_udc *u + * usb traffic follows until a disconnect is reported. Then a host may connect + * again, or the driver might get unbound. + * ++ * Note that the udc is not automatically enabled. Check function ++ * should_enable_udc(). ++ * + * Returns 0 if no error, -EINVAL, -ENODEV, -EBUSY otherwise + */ + int usb_gadget_register_driver(struct usb_gadget_driver *driver) +@@ -1630,6 +1731,7 @@ int usb_gadget_register_driver(struct us + /* first hook up the driver ... */ + udc->driver = driver; + udc->gadget.dev.driver = &driver->driver; ++ dplus_pullup(udc, 1); + + retval = device_add(&udc->gadget.dev); + if (retval) { +@@ -1645,7 +1747,8 @@ int usb_gadget_register_driver(struct us + dev_dbg(udc->dev, "registered gadget driver '%s'\n", + driver->driver.name); + +- udc_enable(udc); ++ if (should_enable_udc(udc)) ++ udc_enable(udc); + return 0; + + bind_fail: +@@ -1699,6 +1802,7 @@ int usb_gadget_unregister_driver(struct + + stop_activity(udc, driver); + udc_disable(udc); ++ dplus_pullup(udc, 0); + + driver->unbind(&udc->gadget); + udc->driver = NULL; +@@ -2212,7 +2316,7 @@ static int __init pxa_udc_probe(struct p + { + struct resource *regs; + struct pxa_udc *udc = &memory; +- int retval; ++ int retval = 0, gpio; + + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!regs) +@@ -2224,6 +2328,19 @@ static int __init pxa_udc_probe(struct p + udc->dev = &pdev->dev; + udc->mach = pdev->dev.platform_data; + ++ gpio = udc->mach->gpio_pullup; ++ if (gpio_is_valid(gpio)) { ++ retval = gpio_request(gpio, "USB D+ pullup"); ++ if (retval == 0) ++ gpio_direction_output(gpio, ++ udc->mach->gpio_pullup_inverted); ++ } ++ if (retval) { ++ dev_err(&pdev->dev, "Couldn't request gpio %d : %d\n", ++ gpio, retval); ++ return retval; ++ } ++ + udc->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(udc->clk)) { + retval = PTR_ERR(udc->clk); +@@ -2273,10 +2390,13 @@ err_clk: + static int __exit pxa_udc_remove(struct platform_device *_dev) + { + struct pxa_udc *udc = platform_get_drvdata(_dev); ++ int gpio = udc->mach->gpio_pullup; + + usb_gadget_unregister_driver(udc->driver); + free_irq(udc->irq, udc); + pxa_cleanup_debugfs(udc); ++ if (gpio_is_valid(gpio)) ++ gpio_free(gpio); + + platform_set_drvdata(_dev, NULL); + the_controller = NULL; +@@ -2319,6 +2439,8 @@ static int pxa_udc_suspend(struct platfo + } + + udc_disable(udc); ++ udc->pullup_resume = udc->pullup_on; ++ dplus_pullup(udc, 0); + + return 0; + } +@@ -2346,7 +2468,9 @@ static int pxa_udc_resume(struct platfor + ep->udccsr_value, ep->udccr_value); + } + +- udc_enable(udc); ++ dplus_pullup(udc, udc->pullup_resume); ++ if (should_enable_udc(udc)) ++ udc_enable(udc); + /* + * We do not handle OTG yet. + * +--- a/drivers/usb/gadget/pxa27x_udc.h ++++ b/drivers/usb/gadget/pxa27x_udc.h +@@ -425,6 +425,9 @@ struct udc_stats { + * @stats: statistics on udc usage + * @udc_usb_ep: array of usb endpoints offered by the gadget + * @pxa_ep: array of pxa available endpoints ++ * @enabled: UDC was enabled by a previous udc_enable() ++ * @pullup_on: if pullup resistor connected to D+ pin ++ * @pullup_resume: if pullup resistor should be connected to D+ pin on resume + * @config: UDC active configuration + * @last_interface: UDC interface of the last SET_INTERFACE host request + * @last_alternate: UDC altsetting of the last SET_INTERFACE host request +@@ -450,6 +453,9 @@ struct pxa_udc { + struct udc_usb_ep udc_usb_ep[NR_USB_ENDPOINTS]; + struct pxa_ep pxa_ep[NR_PXA_ENDPOINTS]; + ++ unsigned enabled:1; ++ unsigned pullup_on:1; ++ unsigned pullup_resume:1; + unsigned config:2; + unsigned last_interface:3; + unsigned last_alternate:3; |
