balloon3: drop udc_is_connected
Subsystems (4)
PATCH 1/7 balloon3: drop udc_is_connected
Balloon3 is a pxa270 machins and pxa27x_udc driver doesn't pay any attention to udc_is_connected, so drop it.
--- arch/arm/mach-pxa/balloon3.c | 6 ------ 1 files changed, 0 insertions(+), 6 deletions(-)
arch/arm/mach-pxa/balloon3.c +0 -6
@@ -317,14 +317,8 @@ static void balloon3_udc_command(int cmd)UP2OCR &= ~UP2OCR_DPPUE ; } -static int balloon3_udc_is_connected (void ) -{ -return 1 ; -} -static struct pxa2xx_udc_mach_info balloon3_udc_info__initdata = { .udc_command = balloon3_udc_command, - .udc_is_connected = balloon3_udc_is_connected, .gpio_pullup =-1 , };
Signature · 1 line
1.7.4.1
PATCH 2/7 mioa701: drop udc_is_connected
Mioa701 is a pxa270 machine and pxa27x_udc driver doesn't pay any attention to udc_is_connected, so drop it.
--- arch/arm/mach-pxa/mioa701.c | 11 +++++------ 1 files changed, 5 insertions(+), 6 deletions(-)
arch/arm/mach-pxa/mioa701.c +5 -6
@@ -402,13 +402,7 @@ static void gsm_exit(void)/* * USB UDC */ -static int is_usb_connected (void ) -{ -return !gpio_get_value (GPIO13_nUSB_DETECT); -} -static struct pxa2xx_udc_mach_info mioa701_udc_info = { - .udc_is_connected = is_usb_connected, .gpio_pullup =GPIO22_USB_ENABLE , };
@@ -596,6 +590,11 @@ static int is_ac_connected(void)return gpio_get_value (GPIO96_AC_DETECT ); } +static int is_usb_connected (void ) +{ +return !gpio_get_value (GPIO13_nUSB_DETECT); +} +static void mioa701_set_charge (int flags) {gpio_set_value (GPIO9_CHARGE_EN , (flags ==PDA_POWER_CHARGE_USB ));
Signature · 1 line
1.7.4.1
PATCH 2/7 mioa701: drop udc_is_connected
Quoted 2 lines · Dmitry Eremin-Solenikov
Mioa701 is a pxa270 machine and
pxa27x_udcdriver doesn't pay any attention toudc_is_connected, so drop it.
You seem to be moving is_usb_connected(), not dropping it...
Quoted 25 lines
Signed-off-by Dmitry Eremin-Solenikov <[email protected]>--- arch/arm/mach-pxa/mioa701.c | 11 +++++------ 1 files changed, 5 insertions(+), 6 deletions(-)arch/arm/mach-pxa/mioa701.c +0
-6@@ -402,13 +402,7 @@ static void gsm_exit(void)/* * USB UDC */ -static int is_usb_connected (void ) -{ -return !gpio_get_value (GPIO13_nUSB_DETECT); -} -static struct pxa2xx_udc_mach_info mioa701_udc_info = { - .udc_is_connected = is_usb_connected, .gpio_pullup =GPIO22_USB_ENABLE , };@@ -596,6 +590,11 @@ static int is_ac_connected(void)return gpio_get_value (GPIO96_AC_DETECT );
arch/arm/mach-pxa/mioa701.c static int is_ac_connected(void) · line 600
Quoted 10 lines
arch/arm/mach-pxa/mioa701.c +5
-0} +static int is_usb_connected (void ) +{ +return !gpio_get_value (GPIO13_nUSB_DETECT); +} +static void mioa701_set_charge (int flags) {gpio_set_value (GPIO9_CHARGE_EN , (flags ==PDA_POWER_CHARGE_USB ));
WBR, Sergei
PATCH 2/7 mioa701: drop udc_is_connected
Quoted 7 lines · Sergei Shtylyov
Quoted 3 lines · Dmitry Eremin-Solenikov
Mioa701 is a pxa270 machine and
pxa27x_udcdriver doesn't pay any attention
toudc_is_connected, so drop it.You seem to be moving
is_usb_connected(), not dropping it...
It may seem to be a bad wording. I'm dropping pxa2xx_udc_mach_info.udc_is_connected() callback assignment. The is_usb_connected() function is still used by pda-power driver.
Quoted 38 lines
Quoted 26 lines
Signed-off-by Dmitry Eremin-Solenikov <[email protected]>---
arch/arm/mach-pxa/mioa701.c| 11 +++++------1 files changed, 5 insertions(+), 6 deletions(-)arch/arm/mach-pxa/mioa701.c +0
-6@@ -402,13 +402,7 @@ static void gsm_exit(void)/* * USB UDC */ -static int is_usb_connected (void ) -{ -return !gpio_get_value (GPIO13_nUSB_DETECT); -} -static struct pxa2xx_udc_mach_info mioa701_udc_info = { - .udc_is_connected = is_usb_connected, .gpio_pullup =GPIO22_USB_ENABLE , };@@ -596,6 +590,11 @@ static int is_ac_connected(void)return gpio_get_value (GPIO96_AC_DETECT );arch/arm/mach-pxa/mioa701.c static int is_ac_connected(void) · line 600
Quoted 10 lines
arch/arm/mach-pxa/mioa701.c +5
-0} +static int is_usb_connected (void ) +{ +return !gpio_get_value (GPIO13_nUSB_DETECT); +} +static void mioa701_set_charge (int flags) {gpio_set_value (GPIO9_CHARGE_EN , (flags ==PDA_POWER_CHARGE_USB ));WBR, Sergei
Signature · 2 lines
With best wishes Dmitry
PATCH 2/7 mioa701: drop udc_is_connected
Quoted 8 lines · Dmitry Eremin-Solenikov
Quoted 7 lines · Sergei Shtylyov
Quoted 3 lines · Dmitry Eremin-Solenikov
Mioa701 is a pxa270 machine and
pxa27x_udcdriver doesn't pay any attention
toudc_is_connected, so drop it.
Quoted 5 lines
Quoted 1 line
You seem to be moving
is_usb_connected(), not dropping it...It may seem to be a bad wording. I'm dropping
pxa2xx_udc_mach_info.udc_is_connected()callback assignment. Theis_usb_connected()function is still used by pda-power driver.
I'll apply this patch as is. However, this does reveal another problem at least, that pda-power should have a way to know usb connected status, maybe through gpio_vbus.
Quoted 46 lines
Quoted 29 lines
Quoted 29 lines
Signed-off-by Dmitry Eremin-Solenikov <[email protected]>---
arch/arm/mach-pxa/mioa701.c| 11 +++++------1 files changed, 5 insertions(+), 6 deletions(-)arch/arm/mach-pxa/mioa701.c +0
-6@@ -402,13 +402,7 @@ static void gsm_exit(void)/* * USB UDC */ -static int is_usb_connected (void ) -{ -return !gpio_get_value (GPIO13_nUSB_DETECT); -} -static struct pxa2xx_udc_mach_info mioa701_udc_info = { - .udc_is_connected = is_usb_connected, .gpio_pullup =GPIO22_USB_ENABLE , };@@ -596,6 +590,11 @@ static int is_ac_connected(void)return gpio_get_value (GPIO96_AC_DETECT ); }Quoted 10 lines
arch/arm/mach-pxa/mioa701.c static int is_ac_connected(void) · line 600
Quoted 8 lines
arch/arm/mach-pxa/mioa701.c +5
-0+static int is_usb_connected (void ) +{ +return !gpio_get_value (GPIO13_nUSB_DETECT); +} +static void mioa701_set_charge (int flags) {gpio_set_value (GPIO9_CHARGE_EN , (flags ==PDA_POWER_CHARGE_USB ));WBR, Sergei
--
With best wishes
Dmitry
PATCH 3/7 stargate2: udc_is_connected is ignored for pxa27x, drop it
In reply to Dmitry Eremin-Solenikov--- arch/arm/mach-pxa/stargate2.c | 6 ------ 1 files changed, 0 insertions(+), 6 deletions(-)
arch/arm/mach-pxa/stargate2.c +0 -6
@@ -956,13 +956,7 @@ static struct i2c_board_info __initdata stargate2_i2c_board_info[] = {/* Board doesn't support cable detection - so always lie and say * something is there. */ -static int sg2_udc_detect (void ) -{ -return 1 ; -} -static struct pxa2xx_udc_mach_info stargate2_udc_info__initdata = { - .udc_is_connected = sg2_udc_detect, .udc_command = sg2_udc_command, };
Signature · 1 line
1.7.4.1
PATCH 4/7 pxa25x: separate lubbock handling to lubbock-usb transceiver
In reply to Dmitry Eremin-SolenikovMove all handling of lubbock board to separate lubbock-usb transceiver, removing cruft from pxa25x_udc.
--- drivers/usb/gadget/pxa25x_udc.c | 74 ---------------- drivers/usb/otg/Kconfig | 8 ++ drivers/usb/otg/Makefile | 1 + drivers/usb/otg/lubbock-usb.c | 178 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 187 insertions(+), 74 deletions(-) create mode 100644 drivers/usb/otg/lubbock-usb.c
drivers/usb/gadget/pxa25x_udc.c +0 -74
@@ -65,10 +65,6 @@#include <mach/pxa25x-udc.h> #endif -#ifdef CONFIG_ARCH_LUBBOCK -#include <mach/lubbock.h> -#endif -#include <asm/mach/udc_pxa2xx.h>
@@ -1383,42 +1379,6 @@ EXPORT_SYMBOL(usb_gadget_unregister_driver);/*-------------------------------------------------------------------------*/ -#ifdef CONFIG_ARCH_LUBBOCK - -/* Lubbock has separate connect and disconnect irqs. More typical designs -* use one GPIO as the VBUS IRQ, and another to control the D+ pullup. -*/ - -static irqreturn_t -lubbock_vbus_irq (int irq,void *_dev) -{ -struct pxa25x_udc *dev = _dev; -int vbus; - - dev->stats.irqs++; -switch (irq) { -case LUBBOCK_USB_IRQ : - vbus =1 ; -disable_irq (LUBBOCK_USB_IRQ ); -enable_irq (LUBBOCK_USB_DISC_IRQ ); -break ; -case LUBBOCK_USB_DISC_IRQ : - vbus =0 ; -disable_irq (LUBBOCK_USB_DISC_IRQ ); -enable_irq (LUBBOCK_USB_IRQ ); -break ; -default : -return IRQ_NONE ; - } - -pxa25x_udc_vbus_session (&dev->gadget, vbus); -return IRQ_HANDLED ; -} - -#endif - - -/*-------------------------------------------------------------------------*/ static inline void clear_ep_state (struct pxa25x_udc *dev) {
@@ -2206,38 +2166,10 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) } dev->got_irq =1 ; -#ifdef CONFIG_ARCH_LUBBOCK -if (machine_is_lubbock ()) { - retval =request_irq (LUBBOCK_USB_DISC_IRQ , - lubbock_vbus_irq, -IRQF_DISABLED |IRQF_SAMPLE_RANDOM , - driver_name, dev); -if (retval !=0 ) { -pr_err ("%s: can't get irq %i, err %d\n" , - driver_name,LUBBOCK_USB_DISC_IRQ , retval); -lubbock_fail0: - goto err_irq_lub; - } - retval =request_irq (LUBBOCK_USB_IRQ , - lubbock_vbus_irq, -IRQF_DISABLED |IRQF_SAMPLE_RANDOM , - driver_name, dev); -if (retval !=0 ) { -pr_err ("%s: can't get irq %i, err %d\n" , - driver_name,LUBBOCK_USB_IRQ , retval); -free_irq (LUBBOCK_USB_DISC_IRQ , dev); - goto lubbock_fail0; - } - } else -#endif create_debug_files (dev);return 0 ; -#ifdef CONFIG_ARCH_LUBBOCK -free_irq (LUBBOCK_USB_DISC_IRQ , dev); - err_irq_lub: -#endif free_irq (irq, dev); err_irq1:if (gpio_is_valid (dev->mach->gpio_pullup))
@@ -2273,12 +2205,6 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev)free_irq (platform_get_irq (pdev,0 ), dev); dev->got_irq =0 ; } -#ifdef CONFIG_ARCH_LUBBOCK -if (machine_is_lubbock ()) { -free_irq (LUBBOCK_USB_DISC_IRQ , dev); -free_irq (LUBBOCK_USB_IRQ , dev); - } -#endif if (gpio_is_valid (dev->mach->gpio_pullup))gpio_free (dev->mach->gpio_pullup);
drivers/usb/otg/Kconfig +8 -0
@@ -122,4 +122,12 @@ config AB8500_USB This transceiver supports high and full speed devices plus, in host mode, low speed. +config LUBBOCK_USB + tristate "Intel DBPXA250 (Lubbock) Tranceiver Driver" + depends on ARCH_LUBBOCK + select USB_OTG_UTILS + help + Enable this to support the USB UDC connectivity on Intel DBPXA250 + development platform (so-called Lubbock). + endif # USB || OTG
drivers/usb/otg/Makefile +1 -0
@@ -19,3 +19,4 @@ obj-$(CONFIG_USB_ULPI) += ulpi.o obj-$(CONFIG_USB_ULPI_VIEWPORT) += ulpi_viewport.o obj-$(CONFIG_USB_MSM_OTG) += msm_otg.o obj-$(CONFIG_AB8500_USB) += ab8500-usb.o +obj-$(CONFIG_LUBBOCK_USB) += lubbock-usb.o
drivers/usb/otg/lubbock-usb.c new file +178 -0
178 lines not on this page · raw message
Signature · 1 line
1.7.4.1
PATCH 4/7 pxa25x: separate lubbock handling to lubbock-usb transceiver
Quoted 4 lines · Dmitry Eremin-Solenikov
Move all handling of lubbock board to separate lubbock-usb transceiver, removing cruft from
pxa25x_udc.Signed-off-by Dmitry Eremin-Solenikov <[email protected]>
I like this change very much. It would be perfect if someone can actually test this, but provided Lubbock is no way popular these days, it would just be fine.
Quoted 332 lines
---
?drivers/usb/gadget/pxa25x_udc.c | ? 74 ---------------- ?drivers/usb/otg/Kconfig ? ? ? ? | ? ?8 ++ ?drivers/usb/otg/Makefile ? ? ? ?| ? ?1 + ?drivers/usb/otg/lubbock-usb.c ? | ?178 +++++++++++++++++++++++++++++++++++++++?4 files changed, 187 insertions(+), 74 deletions(-) ?create mode 100644
drivers/usb/otg/lubbock-usb.cdrivers/usb/gadget/pxa25x_udc.c +0
-0@@ -65,10 +65,6 @@?#include <
mach/pxa25x-udc.h>
?#endifdrivers/usb/gadget/pxa25x_udc.c +0
-4-#ifdef CONFIG_ARCH_LUBBOCK -#include <mach/lubbock.h> -#endif -?#include <
asm/mach/udc_pxa2xx.h>drivers/usb/gadget/pxa25x_udc.c +0
-0@@ -1383,42 +1379,6 @@ EXPORT_SYMBOL(usb_gadget_unregister_driver);?/*-------------------------------------------------------------------------*/
drivers/usb/gadget/pxa25x_udc.c +0
-36-#ifdef CONFIG_ARCH_LUBBOCK - -/* Lubbock has separate connect and disconnect irqs. ?More typical designs -* use one GPIO as the VBUS IRQ, and another to control the D+ pullup. -*/ - -static irqreturn_t -lubbock_vbus_irq (int irq,void *_dev) -{ - ? ? ? struct pxa25x_udc ? ? ? *dev = _dev; - ? ? ? int ? ? ? ? ? ? ? ? ? ? vbus; - - ? ? ? dev->stats.irqs++; - ? ? ? switch (irq) { - ? ? ? case LUBBOCK_USB_IRQ: - ? ? ? ? ? ? ? vbus = 1; - ? ? ? ? ? ? ? disable_irq(LUBBOCK_USB_IRQ); - ? ? ? ? ? ? ? enable_irq(LUBBOCK_USB_DISC_IRQ); - ? ? ? ? ? ? ? break; - ? ? ? case LUBBOCK_USB_DISC_IRQ: - ? ? ? ? ? ? ? vbus = 0; - ? ? ? ? ? ? ? disable_irq(LUBBOCK_USB_DISC_IRQ); - ? ? ? ? ? ? ? enable_irq(LUBBOCK_USB_IRQ); - ? ? ? ? ? ? ? break; - ? ? ? default: - ? ? ? ? ? ? ? return IRQ_NONE; - ? ? ? } - - ? ? ? pxa25x_udc_vbus_session(&dev->gadget, vbus); - ? ? ? return IRQ_HANDLED; -} - -#endif - - -/*-------------------------------------------------------------------------*/ ?static inline void
clear_ep_state(structpxa25x_udc*dev) ?{drivers/usb/gadget/pxa25x_udc.c +0
-28@@ -2206,38 +2166,10 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) ? ? ? ?} ? ? ? ?dev->got_irq = 1; -#ifdef CONFIG_ARCH_LUBBOCK - ? ? ? if (machine_is_lubbock()) { - ? ? ? ? ? ? ? retval = request_irq(LUBBOCK_USB_DISC_IRQ, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? lubbock_vbus_irq, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? IRQF_DISABLED | IRQF_SAMPLE_RANDOM, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? driver_name, dev); - ? ? ? ? ? ? ? if (retval != 0) { - ? ? ? ? ? ? ? ? ? ? ? pr_err("%s: can't get irq %i, err %d\n", - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? driver_name, LUBBOCK_USB_DISC_IRQ, retval); -lubbock_fail0: - ? ? ? ? ? ? ? ? ? ? ? goto err_irq_lub; - ? ? ? ? ? ? ? } - ? ? ? ? ? ? ? retval = request_irq(LUBBOCK_USB_IRQ, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? lubbock_vbus_irq, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? IRQF_DISABLED | IRQF_SAMPLE_RANDOM, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? driver_name, dev); - ? ? ? ? ? ? ? if (retval != 0) { - ? ? ? ? ? ? ? ? ? ? ? pr_err("%s: can't get irq %i, err %d\n", - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? driver_name, LUBBOCK_USB_IRQ, retval); - ? ? ? ? ? ? ? ? ? ? ? free_irq(LUBBOCK_USB_DISC_IRQ, dev); - ? ? ? ? ? ? ? ? ? ? ? goto lubbock_fail0; - ? ? ? ? ? ? ? } - ? ? ? } else -#endif ? ? ? ?create_debug_files(dev); ? ? ? ?return 0; -#ifdef CONFIG_ARCH_LUBBOCK - ? ? ? free_irq(LUBBOCK_USB_DISC_IRQ, dev); - err_irq_lub: -#endif ? ? ? ?free_irq(irq, dev);?err_irq1:
? ? ? ?if (gpio_is_valid(dev->mach->gpio_pullup))drivers/usb/gadget/pxa25x_udc.c +0
-6@@ -2273,12 +2205,6 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev) ? ? ? ? ? ? ? ?free_irq(platform_get_irq(pdev, 0), dev); ? ? ? ? ? ? ? ?dev->got_irq = 0; ? ? ? ?} -#ifdef CONFIG_ARCH_LUBBOCK - ? ? ? if (machine_is_lubbock()) { - ? ? ? ? ? ? ? free_irq(LUBBOCK_USB_DISC_IRQ, dev); - ? ? ? ? ? ? ? free_irq(LUBBOCK_USB_IRQ, dev); - ? ? ? } -#endif ? ? ? ?if (gpio_is_valid(dev->mach->gpio_pullup)) ? ? ? ? ? ? ? ?gpio_free(dev->mach->gpio_pullup);drivers/usb/otg/Kconfig +0
-0@@ -122,4 +122,12 @@ config AB8500_USB ? ? ? ? ? This transceiver supports high and full speed devices plus,? ? ? ? ? in host mode, low speed.
drivers/usb/otg/Kconfig +8
-0+config LUBBOCK_USB + ? ? ? tristate "Intel DBPXA250 (Lubbock) Tranceiver Driver" + ? ? ? depends on ARCH_LUBBOCK + ? ? ? ?select USB_OTG_UTILS + ? ? ? help + ? ? ? ? Enable this to support the USB UDC connectivity on Intel DBPXA250 + ? ? ? ? development platform (so-called Lubbock). +?endif # USB || OTG
drivers/usb/otg/Makefile +0
-0@@ -19,3 +19,4 @@ obj-$(CONFIG_USB_ULPI) ? ? ? ? ? ? ? ?+= ulpi.o?obj-$(CONFIG_USB_ULPI_VIEWPORT) ? ? ? ?+= ulpi_viewport.o ?obj-$(CONFIG_USB_MSM_OTG) ? ? ?+= msm_otg.o ?obj-$(CONFIG_AB8500_USB) ? ? ? += ab8500-usb.o
drivers/usb/otg/Makefile +1
-0+obj-$(CONFIG_LUBBOCK_USB) ? ? ?+= lubbock-usb.odrivers/usb/otg/lubbock-usb.c new file +178
-1@@ -0,0 +1,178 @@ +/* + * Intel DBPXA250 Development Platform USB UDC support + * + * Copyright (C) 2011 Dmitry Eremin-Solenikov + * + * Based on pxa25x_udc driver: + * Copyright (C) 2002 Intrinsyc, Inc. (Frank Becker) + * Copyright (C) 2003 Robert Schwebel, Pengutronix + * Copyright (C) 2003 Benedikt Spranger, Pengutronix + * Copyright (C) 2003 David Brownell + * Copyright (C) 2003 Joshua Wise + * + * Largely based on lubbock-usb-xceiv: + * Copyright (C) 2009 Texas Instruments Inc + */ +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/dma-mapping.h> +#include <linux/usb.h> +#include <linux/usb/gadget.h> +#include <linux/usb/otg.h> +#include <linux/slab.h> +#include <linux/interrupt.h> + +#include <mach/lubbock.h> + +static int lubbock_udc_is_connected(void) +{ + ? ? ? return (LUB_MISC_RD & (1 << 9)) == 0; +} + +static int lubbock_set_peripheral(struct otg_transceiver *lubbock, + ? ? ? ? ? ? ? struct usb_gadget *gadget) +{ + ? ? ? if (!lubbock) + ? ? ? ? ? ? ? return -ENODEV; + + ? ? ? if (!gadget) { + ? ? ? ? ? ? ? lubbock->gadget = NULL; + ? ? ? ? ? ? ? return 0; + ? ? ? } + + ? ? ? lubbock->gadget = gadget; + ? ? ? lubbock->state = OTG_STATE_B_IDLE; + ? ? ? if (lubbock_udc_is_connected()) { + ? ? ? ? ? ? ? lubbock->state = OTG_STATE_B_PERIPHERAL; + ? ? ? ? ? ? ? usb_gadget_vbus_connect(lubbock->gadget); + ? ? ? } + + ? ? ? return 0; +} + +/* Lubbock has separate connect and disconnect irqs. ?More typical designs + * use one GPIO as the VBUS IRQ, and another to control the D+ pullup. + */ + +static irqreturn_t +lubbock_vbus_irq(int irq, void *_dev) +{ + ? ? ? struct otg_transceiver *lubbock = _dev; + ? ? ? switch (irq) { + ? ? ? case LUBBOCK_USB_IRQ: + ? ? ? ? ? ? ? lubbock->state = OTG_STATE_B_PERIPHERAL; + ? ? ? ? ? ? ? usb_gadget_vbus_connect(lubbock->gadget); + + ? ? ? ? ? ? ? disable_irq(LUBBOCK_USB_IRQ); + ? ? ? ? ? ? ? enable_irq(LUBBOCK_USB_DISC_IRQ); + ? ? ? ? ? ? ? break; + ? ? ? case LUBBOCK_USB_DISC_IRQ: + ? ? ? ? ? ? ? usb_gadget_vbus_disconnect(lubbock->gadget); + ? ? ? ? ? ? ? lubbock->state = OTG_STATE_B_IDLE; + + ? ? ? ? ? ? ? disable_irq(LUBBOCK_USB_DISC_IRQ); + ? ? ? ? ? ? ? enable_irq(LUBBOCK_USB_IRQ); + ? ? ? ? ? ? ? break; + ? ? ? default: + ? ? ? ? ? ? ? return IRQ_NONE; + ? ? ? } + + ? ? ? return IRQ_HANDLED; +} + + +static int __devinit lubbock_usb_xceiv_probe(struct platform_device *pdev) +{ + ? ? ? struct otg_transceiver ?*lubbock; + ? ? ? int err; + + ? ? ? lubbock = kzalloc(sizeof *lubbock, GFP_KERNEL); + ? ? ? if (!lubbock) + ? ? ? ? ? ? ? return -ENOMEM; + + ? ? ? lubbock->dev ? ? ? ? ? ?= &pdev->dev; + ? ? ? lubbock->label ? ? ? ? ?= "lubbock-xceiv"; + ? ? ? lubbock->state ? ? ? ? ?= OTG_STATE_UNDEFINED; + ? ? ? lubbock->set_peripheral = lubbock_set_peripheral; + + ? ? ? err = request_irq(LUBBOCK_USB_DISC_IRQ, + ? ? ? ? ? ? ? ? ? ? ? lubbock_vbus_irq, + ? ? ? ? ? ? ? ? ? ? ? IRQF_DISABLED | IRQF_SAMPLE_RANDOM, + ? ? ? ? ? ? ? ? ? ? ? lubbock->label, lubbock); + ? ? ? if (err != 0) { + ? ? ? ? ? ? ? pr_err("%s: can't get irq %i, err %d\n", + ? ? ? ? ? ? ? ? ? ? ? lubbock->label, LUBBOCK_USB_DISC_IRQ, err); + ? ? ? ? ? ? ? goto err_irq_lub; + ? ? ? } + ? ? ? err = request_irq(LUBBOCK_USB_IRQ, + ? ? ? ? ? ? ? ? ? ? ? lubbock_vbus_irq, + ? ? ? ? ? ? ? ? ? ? ? IRQF_DISABLED | IRQF_SAMPLE_RANDOM, + ? ? ? ? ? ? ? ? ? ? ? lubbock->label, lubbock); + ? ? ? if (err != 0) { + ? ? ? ? ? ? ? pr_err("%s: can't get irq %i, err %d\n", + ? ? ? ? ? ? ? ? ? ? ? lubbock->label, LUBBOCK_USB_IRQ, err); + ? ? ? ? ? ? ? goto err_irq_lub2; + ? ? ? } + + ? ? ? err = otg_set_transceiver(lubbock); + ? ? ? if (err) { + ? ? ? ? ? ? ? dev_err(&pdev->dev, "can't register transceiver, err: %d\n", + ? ? ? ? ? ? ? ? ? ? ? err); + ? ? ? ? ? ? ? goto exit; + ? ? ? } + + ? ? ? platform_set_drvdata(pdev, lubbock); + + ? ? ? BLOCKING_INIT_NOTIFIER_HEAD(&lubbock->notifier); + + ? ? ? return 0; +exit: + ? ? ? free_irq(LUBBOCK_USB_IRQ, lubbock); +err_irq_lub2: + ? ? ? free_irq(LUBBOCK_USB_DISC_IRQ, lubbock); +err_irq_lub: + ? ? ? kfree(lubbock); + ? ? ? return err; +} + +static int __devexit lubbock_usb_xceiv_remove(struct platform_device *pdev) +{ + ? ? ? struct otg_transceiver *lubbock = platform_get_drvdata(pdev); + + ? ? ? otg_set_transceiver(NULL); + + ? ? ? platform_set_drvdata(pdev, NULL); + + ? ? ? free_irq(LUBBOCK_USB_IRQ, lubbock); + ? ? ? free_irq(LUBBOCK_USB_DISC_IRQ, lubbock); + + ? ? ? kfree(lubbock); + + ? ? ? return 0; +} + +static struct platform_driver lubbock_usb_xceiv_driver = { + ? ? ? .probe ? ? ? ? ?= lubbock_usb_xceiv_probe, + ? ? ? .remove ? ? ? ? = __devexit_p(lubbock_usb_xceiv_remove), + ? ? ? .driver ? ? ? ? = { + ? ? ? ? ? ? ? .name ? = "lubbock_usb_xceiv", + ? ? ? ? ? ? ? .owner ?= THIS_MODULE, + ? ? ? }, +}; + +static int __init lubbock_usb_xceiv_init(void) +{ + ? ? ? return platform_driver_register(&lubbock_usb_xceiv_driver); +} +subsys_initcall(lubbock_usb_xceiv_init); + +static void __exit lubbock_usb_xceiv_exit(void) +{ + ? ? ? platform_driver_unregister(&lubbock_usb_xceiv_driver); +} +module_exit(lubbock_usb_xceiv_exit); + +MODULE_ALIAS("platform:lubbock_usb_xceiv"); +MODULE_DESCRIPTION("lubbock USB Transceiver driver"); +MODULE_LICENSE("GPL"); + --1.7.4.1
PATCH 4/7 pxa25x: separate lubbock handling to lubbock-usb transceiver
David,
Let me know if you're OK I take this patch, as several others following have dependency on this one.
Quoted 346 lines · Eric Miao
Quoted 4 lines · Dmitry Eremin-Solenikov
Move all handling of lubbock board to separate lubbock-usb transceiver, removing cruft from
pxa25x_udc.Signed-off-by Dmitry Eremin-Solenikov <[email protected]>I like this change very much. It would be perfect if someone can actually test this, but provided Lubbock is no way popular these days, it would just be fine.
Acked-by Eric Miao <[email protected]>Quoted 332 lines
---
?drivers/usb/gadget/pxa25x_udc.c | ? 74 ---------------- ?drivers/usb/otg/Kconfig ? ? ? ? | ? ?8 ++ ?drivers/usb/otg/Makefile ? ? ? ?| ? ?1 + ?drivers/usb/otg/lubbock-usb.c ? | ?178 +++++++++++++++++++++++++++++++++++++++?4 files changed, 187 insertions(+), 74 deletions(-) ?create mode 100644
drivers/usb/otg/lubbock-usb.cdrivers/usb/gadget/pxa25x_udc.c +0
-0@@ -65,10 +65,6 @@?#include <
mach/pxa25x-udc.h>
?#endifdrivers/usb/gadget/pxa25x_udc.c +0
-4-#ifdef CONFIG_ARCH_LUBBOCK -#include <mach/lubbock.h> -#endif -?#include <
asm/mach/udc_pxa2xx.h>drivers/usb/gadget/pxa25x_udc.c +0
-0@@ -1383,42 +1379,6 @@ EXPORT_SYMBOL(usb_gadget_unregister_driver);?/*-------------------------------------------------------------------------*/
drivers/usb/gadget/pxa25x_udc.c +0
-36-#ifdef CONFIG_ARCH_LUBBOCK - -/* Lubbock has separate connect and disconnect irqs. ?More typical designs -* use one GPIO as the VBUS IRQ, and another to control the D+ pullup. -*/ - -static irqreturn_t -lubbock_vbus_irq (int irq,void *_dev) -{ - ? ? ? struct pxa25x_udc ? ? ? *dev = _dev; - ? ? ? int ? ? ? ? ? ? ? ? ? ? vbus; - - ? ? ? dev->stats.irqs++; - ? ? ? switch (irq) { - ? ? ? case LUBBOCK_USB_IRQ: - ? ? ? ? ? ? ? vbus = 1; - ? ? ? ? ? ? ? disable_irq(LUBBOCK_USB_IRQ); - ? ? ? ? ? ? ? enable_irq(LUBBOCK_USB_DISC_IRQ); - ? ? ? ? ? ? ? break; - ? ? ? case LUBBOCK_USB_DISC_IRQ: - ? ? ? ? ? ? ? vbus = 0; - ? ? ? ? ? ? ? disable_irq(LUBBOCK_USB_DISC_IRQ); - ? ? ? ? ? ? ? enable_irq(LUBBOCK_USB_IRQ); - ? ? ? ? ? ? ? break; - ? ? ? default: - ? ? ? ? ? ? ? return IRQ_NONE; - ? ? ? } - - ? ? ? pxa25x_udc_vbus_session(&dev->gadget, vbus); - ? ? ? return IRQ_HANDLED; -} - -#endif - - -/*-------------------------------------------------------------------------*/ ?static inline void
clear_ep_state(structpxa25x_udc*dev) ?{drivers/usb/gadget/pxa25x_udc.c +0
-28@@ -2206,38 +2166,10 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) ? ? ? ?} ? ? ? ?dev->got_irq = 1; -#ifdef CONFIG_ARCH_LUBBOCK - ? ? ? if (machine_is_lubbock()) { - ? ? ? ? ? ? ? retval = request_irq(LUBBOCK_USB_DISC_IRQ, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? lubbock_vbus_irq, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? IRQF_DISABLED | IRQF_SAMPLE_RANDOM, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? driver_name, dev); - ? ? ? ? ? ? ? if (retval != 0) { - ? ? ? ? ? ? ? ? ? ? ? pr_err("%s: can't get irq %i, err %d\n", - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? driver_name, LUBBOCK_USB_DISC_IRQ, retval); -lubbock_fail0: - ? ? ? ? ? ? ? ? ? ? ? goto err_irq_lub; - ? ? ? ? ? ? ? } - ? ? ? ? ? ? ? retval = request_irq(LUBBOCK_USB_IRQ, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? lubbock_vbus_irq, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? IRQF_DISABLED | IRQF_SAMPLE_RANDOM, - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? driver_name, dev); - ? ? ? ? ? ? ? if (retval != 0) { - ? ? ? ? ? ? ? ? ? ? ? pr_err("%s: can't get irq %i, err %d\n", - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? driver_name, LUBBOCK_USB_IRQ, retval); - ? ? ? ? ? ? ? ? ? ? ? free_irq(LUBBOCK_USB_DISC_IRQ, dev); - ? ? ? ? ? ? ? ? ? ? ? goto lubbock_fail0; - ? ? ? ? ? ? ? } - ? ? ? } else -#endif ? ? ? ?create_debug_files(dev); ? ? ? ?return 0; -#ifdef CONFIG_ARCH_LUBBOCK - ? ? ? free_irq(LUBBOCK_USB_DISC_IRQ, dev); - err_irq_lub: -#endif ? ? ? ?free_irq(irq, dev);?err_irq1:
? ? ? ?if (gpio_is_valid(dev->mach->gpio_pullup))drivers/usb/gadget/pxa25x_udc.c +0
-6@@ -2273,12 +2205,6 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev) ? ? ? ? ? ? ? ?free_irq(platform_get_irq(pdev, 0), dev); ? ? ? ? ? ? ? ?dev->got_irq = 0; ? ? ? ?} -#ifdef CONFIG_ARCH_LUBBOCK - ? ? ? if (machine_is_lubbock()) { - ? ? ? ? ? ? ? free_irq(LUBBOCK_USB_DISC_IRQ, dev); - ? ? ? ? ? ? ? free_irq(LUBBOCK_USB_IRQ, dev); - ? ? ? } -#endif ? ? ? ?if (gpio_is_valid(dev->mach->gpio_pullup)) ? ? ? ? ? ? ? ?gpio_free(dev->mach->gpio_pullup);drivers/usb/otg/Kconfig +0
-0@@ -122,4 +122,12 @@ config AB8500_USB ? ? ? ? ? This transceiver supports high and full speed devices plus,? ? ? ? ? in host mode, low speed.
drivers/usb/otg/Kconfig +8
-0+config LUBBOCK_USB + ? ? ? tristate "Intel DBPXA250 (Lubbock) Tranceiver Driver" + ? ? ? depends on ARCH_LUBBOCK + ? ? ? ?select USB_OTG_UTILS + ? ? ? help + ? ? ? ? Enable this to support the USB UDC connectivity on Intel DBPXA250 + ? ? ? ? development platform (so-called Lubbock). +?endif # USB || OTG
drivers/usb/otg/Makefile +0
-0@@ -19,3 +19,4 @@ obj-$(CONFIG_USB_ULPI) ? ? ? ? ? ? ? ?+= ulpi.o?obj-$(CONFIG_USB_ULPI_VIEWPORT) ? ? ? ?+= ulpi_viewport.o ?obj-$(CONFIG_USB_MSM_OTG) ? ? ?+= msm_otg.o ?obj-$(CONFIG_AB8500_USB) ? ? ? += ab8500-usb.o
drivers/usb/otg/Makefile +1
-0+obj-$(CONFIG_LUBBOCK_USB) ? ? ?+= lubbock-usb.odrivers/usb/otg/lubbock-usb.c new file +178
-1@@ -0,0 +1,178 @@ +/* + * Intel DBPXA250 Development Platform USB UDC support + * + * Copyright (C) 2011 Dmitry Eremin-Solenikov + * + * Based on pxa25x_udc driver: + * Copyright (C) 2002 Intrinsyc, Inc. (Frank Becker) + * Copyright (C) 2003 Robert Schwebel, Pengutronix + * Copyright (C) 2003 Benedikt Spranger, Pengutronix + * Copyright (C) 2003 David Brownell + * Copyright (C) 2003 Joshua Wise + * + * Largely based on lubbock-usb-xceiv: + * Copyright (C) 2009 Texas Instruments Inc + */ +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/dma-mapping.h> +#include <linux/usb.h> +#include <linux/usb/gadget.h> +#include <linux/usb/otg.h> +#include <linux/slab.h> +#include <linux/interrupt.h> + +#include <mach/lubbock.h> + +static int lubbock_udc_is_connected(void) +{ + ? ? ? return (LUB_MISC_RD & (1 << 9)) == 0; +} + +static int lubbock_set_peripheral(struct otg_transceiver *lubbock, + ? ? ? ? ? ? ? struct usb_gadget *gadget) +{ + ? ? ? if (!lubbock) + ? ? ? ? ? ? ? return -ENODEV; + + ? ? ? if (!gadget) { + ? ? ? ? ? ? ? lubbock->gadget = NULL; + ? ? ? ? ? ? ? return 0; + ? ? ? } + + ? ? ? lubbock->gadget = gadget; + ? ? ? lubbock->state = OTG_STATE_B_IDLE; + ? ? ? if (lubbock_udc_is_connected()) { + ? ? ? ? ? ? ? lubbock->state = OTG_STATE_B_PERIPHERAL; + ? ? ? ? ? ? ? usb_gadget_vbus_connect(lubbock->gadget); + ? ? ? } + + ? ? ? return 0; +} + +/* Lubbock has separate connect and disconnect irqs. ?More typical designs + * use one GPIO as the VBUS IRQ, and another to control the D+ pullup. + */ + +static irqreturn_t +lubbock_vbus_irq(int irq, void *_dev) +{ + ? ? ? struct otg_transceiver *lubbock = _dev; + ? ? ? switch (irq) { + ? ? ? case LUBBOCK_USB_IRQ: + ? ? ? ? ? ? ? lubbock->state = OTG_STATE_B_PERIPHERAL; + ? ? ? ? ? ? ? usb_gadget_vbus_connect(lubbock->gadget); + + ? ? ? ? ? ? ? disable_irq(LUBBOCK_USB_IRQ); + ? ? ? ? ? ? ? enable_irq(LUBBOCK_USB_DISC_IRQ); + ? ? ? ? ? ? ? break; + ? ? ? case LUBBOCK_USB_DISC_IRQ: + ? ? ? ? ? ? ? usb_gadget_vbus_disconnect(lubbock->gadget); + ? ? ? ? ? ? ? lubbock->state = OTG_STATE_B_IDLE; + + ? ? ? ? ? ? ? disable_irq(LUBBOCK_USB_DISC_IRQ); + ? ? ? ? ? ? ? enable_irq(LUBBOCK_USB_IRQ); + ? ? ? ? ? ? ? break; + ? ? ? default: + ? ? ? ? ? ? ? return IRQ_NONE; + ? ? ? } + + ? ? ? return IRQ_HANDLED; +} + + +static int __devinit lubbock_usb_xceiv_probe(struct platform_device *pdev) +{ + ? ? ? struct otg_transceiver ?*lubbock; + ? ? ? int err; + + ? ? ? lubbock = kzalloc(sizeof *lubbock, GFP_KERNEL); + ? ? ? if (!lubbock) + ? ? ? ? ? ? ? return -ENOMEM; + + ? ? ? lubbock->dev ? ? ? ? ? ?= &pdev->dev; + ? ? ? lubbock->label ? ? ? ? ?= "lubbock-xceiv"; + ? ? ? lubbock->state ? ? ? ? ?= OTG_STATE_UNDEFINED; + ? ? ? lubbock->set_peripheral = lubbock_set_peripheral; + + ? ? ? err = request_irq(LUBBOCK_USB_DISC_IRQ, + ? ? ? ? ? ? ? ? ? ? ? lubbock_vbus_irq, + ? ? ? ? ? ? ? ? ? ? ? IRQF_DISABLED | IRQF_SAMPLE_RANDOM, + ? ? ? ? ? ? ? ? ? ? ? lubbock->label, lubbock); + ? ? ? if (err != 0) { + ? ? ? ? ? ? ? pr_err("%s: can't get irq %i, err %d\n", + ? ? ? ? ? ? ? ? ? ? ? lubbock->label, LUBBOCK_USB_DISC_IRQ, err); + ? ? ? ? ? ? ? goto err_irq_lub; + ? ? ? } + ? ? ? err = request_irq(LUBBOCK_USB_IRQ, + ? ? ? ? ? ? ? ? ? ? ? lubbock_vbus_irq, + ? ? ? ? ? ? ? ? ? ? ? IRQF_DISABLED | IRQF_SAMPLE_RANDOM, + ? ? ? ? ? ? ? ? ? ? ? lubbock->label, lubbock); + ? ? ? if (err != 0) { + ? ? ? ? ? ? ? pr_err("%s: can't get irq %i, err %d\n", + ? ? ? ? ? ? ? ? ? ? ? lubbock->label, LUBBOCK_USB_IRQ, err); + ? ? ? ? ? ? ? goto err_irq_lub2; + ? ? ? } + + ? ? ? err = otg_set_transceiver(lubbock); + ? ? ? if (err) { + ? ? ? ? ? ? ? dev_err(&pdev->dev, "can't register transceiver, err: %d\n", + ? ? ? ? ? ? ? ? ? ? ? err); + ? ? ? ? ? ? ? goto exit; + ? ? ? } + + ? ? ? platform_set_drvdata(pdev, lubbock); + + ? ? ? BLOCKING_INIT_NOTIFIER_HEAD(&lubbock->notifier); + + ? ? ? return 0; +exit: + ? ? ? free_irq(LUBBOCK_USB_IRQ, lubbock); +err_irq_lub2: + ? ? ? free_irq(LUBBOCK_USB_DISC_IRQ, lubbock); +err_irq_lub: + ? ? ? kfree(lubbock); + ? ? ? return err; +} + +static int __devexit lubbock_usb_xceiv_remove(struct platform_device *pdev) +{ + ? ? ? struct otg_transceiver *lubbock = platform_get_drvdata(pdev); + + ? ? ? otg_set_transceiver(NULL); + + ? ? ? platform_set_drvdata(pdev, NULL); + + ? ? ? free_irq(LUBBOCK_USB_IRQ, lubbock); + ? ? ? free_irq(LUBBOCK_USB_DISC_IRQ, lubbock); + + ? ? ? kfree(lubbock); + + ? ? ? return 0; +} + +static struct platform_driver lubbock_usb_xceiv_driver = { + ? ? ? .probe ? ? ? ? ?= lubbock_usb_xceiv_probe, + ? ? ? .remove ? ? ? ? = __devexit_p(lubbock_usb_xceiv_remove), + ? ? ? .driver ? ? ? ? = { + ? ? ? ? ? ? ? .name ? = "lubbock_usb_xceiv", + ? ? ? ? ? ? ? .owner ?= THIS_MODULE, + ? ? ? }, +}; + +static int __init lubbock_usb_xceiv_init(void) +{ + ? ? ? return platform_driver_register(&lubbock_usb_xceiv_driver); +} +subsys_initcall(lubbock_usb_xceiv_init); + +static void __exit lubbock_usb_xceiv_exit(void) +{ + ? ? ? platform_driver_unregister(&lubbock_usb_xceiv_driver); +} +module_exit(lubbock_usb_xceiv_exit); + +MODULE_ALIAS("platform:lubbock_usb_xceiv"); +MODULE_DESCRIPTION("lubbock USB Transceiver driver"); +MODULE_LICENSE("GPL"); + --1.7.4.1
PATCH 4/7 pxa25x: separate lubbock handling to lubbock-usb transceiver
Quoted 4 lines · Eric Miao
David,
Let me know if you're OK I take this patch, as several others following have dependency on this one.
So, what is the current status of this patch?
Quoted 361 lines · Eric Miao
Quoted 358 lines
Quoted 4 lines · Dmitry Eremin-Solenikov
Move all handling of lubbock board to separate lubbock-usb transceiver, removing cruft from
pxa25x_udc.Signed-off-by Dmitry Eremin-Solenikov <[email protected]>I like this change very much. It would be perfect if someone can actually test this, but provided Lubbock is no way popular these days, it would just be fine.
Acked-by Eric Miao <[email protected]>Quoted 344 lines
--- drivers/usb/gadget/pxa25x_udc.c | 74 ---------------- drivers/usb/otg/Kconfig | 8 ++ drivers/usb/otg/Makefile | 1 + drivers/usb/otg/lubbock-usb.c | 178 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 187 insertions(+), 74 deletions(-) create mode 100644 drivers/usb/otg/lubbock-usb.cdrivers/usb/gadget/pxa25x_udc.c +0
-7@@ -65,10 +65,6 @@#include <mach/pxa25x-udc.h> #endif -#ifdef CONFIG_ARCH_LUBBOCK -#include <mach/lubbock.h> -#endif -#include <asm/mach/udc_pxa2xx.h> @@ -1383,42 +1379,6 @@ EXPORT_SYMBOL(usb_gadget_unregister_driver);/*-------------------------------------------------------------------------*/ -#ifdef CONFIG_ARCH_LUBBOCK - -/* Lubbock has separate connect and disconnect irqs. More typical designs
- * use one GPIO as the VBUS IRQ, and another to control the D+ pullup.
- */drivers/usb/gadget/pxa25x_udc.c +0
-59- -static irqreturn_t -lubbock_vbus_irq (int irq,void *_dev) -{ -struct pxa25x_udc *dev = _dev; -int vbus; - - dev->stats.irqs++; -switch (irq) { -case LUBBOCK_USB_IRQ : - vbus =1 ; -disable_irq (LUBBOCK_USB_IRQ ); -enable_irq (LUBBOCK_USB_DISC_IRQ ); -break ; -case LUBBOCK_USB_DISC_IRQ : - vbus =0 ; -disable_irq (LUBBOCK_USB_DISC_IRQ ); -enable_irq (LUBBOCK_USB_IRQ ); -break ; -default : -return IRQ_NONE ; - } - -pxa25x_udc_vbus_session (&dev->gadget, vbus); -return IRQ_HANDLED ; -} - -#endif - - -/*-------------------------------------------------------------------------*/ static inline void clear_ep_state (struct pxa25x_udc *dev) {@@ -2206,38 +2166,10 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) } dev->got_irq =1 ; -#ifdef CONFIG_ARCH_LUBBOCK -if (machine_is_lubbock ()) { - retval =request_irq (LUBBOCK_USB_DISC_IRQ , - lubbock_vbus_irq, -IRQF_DISABLED |IRQF_SAMPLE_RANDOM , - driver_name, dev); -if (retval !=0 ) { -pr_err ("%s: can't get irq %i, err %d\n" , - driver_name,LUBBOCK_USB_DISC_IRQ , retval); -lubbock_fail0: - goto err_irq_lub; - } - retval =request_irq (LUBBOCK_USB_IRQ , - lubbock_vbus_irq, -IRQF_DISABLED |IRQF_SAMPLE_RANDOM , - driver_name, dev); -if (retval !=0 ) { -pr_err ("%s: can't get irq %i, err %d\n" , - driver_name,LUBBOCK_USB_IRQ , retval); -free_irq (LUBBOCK_USB_DISC_IRQ , dev); - goto lubbock_fail0; - } - } else -#endif create_debug_files (dev);return 0 ; -#ifdef CONFIG_ARCH_LUBBOCK -free_irq (LUBBOCK_USB_DISC_IRQ , dev); - err_irq_lub: -#endif free_irq (irq, dev);
err_irq1:if (gpio_is_valid(dev->mach->gpio_pullup))drivers/usb/gadget/pxa25x_udc.c +0
-6@@ -2273,12 +2205,6 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev) free_irq(platform_get_irq(pdev, 0), dev); dev->got_irq =0 ; } -#ifdef CONFIG_ARCH_LUBBOCK -if (machine_is_lubbock ()) { -free_irq (LUBBOCK_USB_DISC_IRQ , dev); -free_irq (LUBBOCK_USB_IRQ , dev); - } -#endif if (gpio_is_valid (dev->mach->gpio_pullup))gpio_free (dev->mach->gpio_pullup);drivers/usb/otg/Kconfig +6
-0@@ -122,4 +122,12 @@ config AB8500_USB This transceiver supports high and full speed devices plus, in host mode, low speed. +config LUBBOCK_USB + tristate "Intel DBPXA250 (Lubbock) Tranceiver Driver" + depends on ARCH_LUBBOCK + select USB_OTG_UTILS + help + Enable this to support the USB UDC connectivity on IntelDBPXA250
drivers/usb/otg/Kconfig +2
-0+ development platform (so-called Lubbock). + endif # USB || OTGdrivers/usb/otg/Makefile +1
-0@@ -19,3 +19,4 @@ obj-$(CONFIG_USB_ULPI) += ulpi.o obj-$(CONFIG_USB_ULPI_VIEWPORT) += ulpi_viewport.o obj-$(CONFIG_USB_MSM_OTG) += msm_otg.o obj-$(CONFIG_AB8500_USB) += ab8500-usb.o +obj-$(CONFIG_LUBBOCK_USB) += lubbock-usb.odrivers/usb/otg/lubbock-usb.c new file +53
-0@@ -0,0 +1,178 @@ +/* +* Intel DBPXA250 Development Platform USB UDC support +* +* Copyright (C) 2011 Dmitry Eremin-Solenikov +* +* Based on pxa25x_udc driver: +* Copyright (C) 2002 Intrinsyc, Inc. (Frank Becker) +* Copyright (C) 2003 Robert Schwebel, Pengutronix +* Copyright (C) 2003 Benedikt Spranger, Pengutronix +* Copyright (C) 2003 David Brownell +* Copyright (C) 2003 Joshua Wise +* +* Largely based on lubbock-usb-xceiv: +* Copyright (C) 2009 Texas Instruments Inc +*/ +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/dma-mapping.h> +#include <linux/usb.h> +#include <linux/usb/gadget.h> +#include <linux/usb/otg.h> +#include <linux/slab.h> +#include <linux/interrupt.h> + +#include <mach/lubbock.h> + +static int lubbock_udc_is_connected (void ) +{ +return (LUB_MISC_RD & (1 <<9 )) ==0 ; +} + +static int lubbock_set_peripheral (struct otg_transceiver *lubbock, +struct usb_gadget *gadget) +{ +if (!lubbock) +return -ENODEV ; + +if (!gadget) { + lubbock->gadget =NULL ; +return 0 ; + } + + lubbock->gadget = gadget; + lubbock->state =OTG_STATE_B_IDLE ; +if (lubbock_udc_is_connected ()) { + lubbock->state =OTG_STATE_B_PERIPHERAL ; +usb_gadget_vbus_connect (lubbock->gadget); + } + +return 0 ; +} + +/* Lubbock has separate connect and disconnect irqs. More typical designs
+ * use one GPIO as the VBUS IRQ, and another to control the D+ pullup.
+ */drivers/usb/otg/lubbock-usb.c new file +29
-0+ +static irqreturn_t +lubbock_vbus_irq (int irq,void *_dev) +{ +struct otg_transceiver *lubbock = _dev; +switch (irq) { +case LUBBOCK_USB_IRQ : + lubbock->state =OTG_STATE_B_PERIPHERAL ; +usb_gadget_vbus_connect (lubbock->gadget); + +disable_irq (LUBBOCK_USB_IRQ ); +enable_irq (LUBBOCK_USB_DISC_IRQ ); +break ; +case LUBBOCK_USB_DISC_IRQ : +usb_gadget_vbus_disconnect (lubbock->gadget); + lubbock->state =OTG_STATE_B_IDLE ; + +disable_irq (LUBBOCK_USB_DISC_IRQ ); +enable_irq (LUBBOCK_USB_IRQ ); +break ; +default : +return IRQ_NONE ; + } + +return IRQ_HANDLED ; +} + + +static int __devinit lubbock_usb_xceiv_probe(struct platform_device*pdev)
drivers/usb/otg/lubbock-usb.c new file +35
-0+{ +struct otg_transceiver *lubbock; +int err; + + lubbock =kzalloc (sizeof *lubbock,GFP_KERNEL ); +if (!lubbock) +return -ENOMEM ; + + lubbock->dev = &pdev->dev; + lubbock->label ="lubbock-xceiv" ; + lubbock->state =OTG_STATE_UNDEFINED ; + lubbock->set_peripheral = lubbock_set_peripheral; + + err =request_irq (LUBBOCK_USB_DISC_IRQ , + lubbock_vbus_irq, +IRQF_DISABLED |IRQF_SAMPLE_RANDOM , + lubbock->label, lubbock); +if (err !=0 ) { +pr_err ("%s: can't get irq %i, err %d\n" , + lubbock->label,LUBBOCK_USB_DISC_IRQ , err); + goto err_irq_lub; + } + err =request_irq (LUBBOCK_USB_IRQ , + lubbock_vbus_irq, +IRQF_DISABLED |IRQF_SAMPLE_RANDOM , + lubbock->label, lubbock); +if (err !=0 ) { +pr_err ("%s: can't get irq %i, err %d\n" , + lubbock->label,LUBBOCK_USB_IRQ , err); + goto err_irq_lub2; + } + + err =otg_set_transceiver (lubbock); +if (err) { + dev_err(&pdev->dev, "can't register transceiver, err:%d\n",
drivers/usb/otg/lubbock-usb.c new file +19
-0+ err); + goto exit; + } + +platform_set_drvdata (pdev, lubbock); + +BLOCKING_INIT_NOTIFIER_HEAD (&lubbock->notifier); + +return 0 ; +exit: +free_irq (LUBBOCK_USB_IRQ , lubbock); +err_irq_lub2: +free_irq (LUBBOCK_USB_DISC_IRQ , lubbock); +err_irq_lub: +kfree (lubbock); +return err; +} + +static int __devexit lubbock_usb_xceiv_remove(struct platform_device*pdev)
drivers/usb/otg/lubbock-usb.c new file +40
-1+{ +struct otg_transceiver *lubbock =platform_get_drvdata (pdev); + +otg_set_transceiver (NULL ); + +platform_set_drvdata (pdev,NULL ); + +free_irq (LUBBOCK_USB_IRQ , lubbock); +free_irq (LUBBOCK_USB_DISC_IRQ , lubbock); + +kfree (lubbock); + +return 0 ; +} + +static struct platform_driver lubbock_usb_xceiv_driver = { + .probe = lubbock_usb_xceiv_probe, + .remove =__devexit_p (lubbock_usb_xceiv_remove), + .driver = { + .name ="lubbock_usb_xceiv" , + .owner =THIS_MODULE , + }, +}; + +static int __init lubbock_usb_xceiv_init (void ) +{ +return platform_driver_register (&lubbock_usb_xceiv_driver); +} +subsys_initcall (lubbock_usb_xceiv_init); + +static void __exit lubbock_usb_xceiv_exit(void) +{ +platform_driver_unregister (&lubbock_usb_xceiv_driver); +} +module_exit (lubbock_usb_xceiv_exit); + +MODULE_ALIAS ("platform:lubbock_usb_xceiv" ); +MODULE_DESCRIPTION ("lubbock USB Transceiver driver" ); +MODULE_LICENSE ("GPL" ); + --1.7.4.1
Signature · 2 lines
With best wishes Dmitry
PATCH 4/7 pxa25x: separate lubbock handling to lubbock-usb transceiver
Quoted 7 lines · Dmitry Eremin-Solenikov
Quoted 4 lines · Eric Miao
David,
Let me know if you're OK I take this patch, as several others following have dependency on this one.
So, what is the current status of this patch?
Unfortunately, David passed away as Greg KH announced days ago. I'll take these patches.
PATCH 4/7 pxa25x: separate lubbock handling to lubbock-usb transceiver
Hello,
Quoted 5 lines · Eric Miao
Quoted 3 lines · Dmitry Eremin-Solenikov
Quoted 2 lines · Eric Miao
David,
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
Let me know if you're OK I take this patch, as several others following have dependency on this one.
So, what is the current status of this patch?
Unfortunately, David passed away as Greg KH announced days ago. I'll take these patches.
I'v seen these patches rest a bit in your tree. It wasn't merged for 3.0. Does it stand a chance to be merged into 3.1, or it's better to resubmit these patches to usb/gadget subtree to Felipe/Greg?
Signature · 2 lines
With best wishes Dmitry
PATCH 4/7 pxa25x: separate lubbock handling to lubbock-usb transceiver
Felipe, ping?
Cc'ed Greg KH. Any possibility for this to go quicker, this series has been delayed for 2 cycles. And the patches look good to me.
Dmitry,
If this is going to be merged through the usb tree, what are the other patches that have no dependency?
- eric
Quoted 29 lines · Dmitry Eremin-Solenikov
Hello,
Quoted 8 lines · Eric Miao
Quoted 5 lines · On Thu, Apr 7, 2011 at 5:21 AM, Dmitry Eremin-Solenikov <[email protected]>…
Quoted 3 lines · On 4/4/11, Eric Miao<[email protected]> ?wrote:
David,
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
Let me know if you're OK I take this patch, as several others following have dependency on this one.
So, what is the current status of this patch?
Unfortunately, David passed away as Greg KH announced days ago. I'll take these patches.
I'v seen these patches rest a bit in your tree. It wasn't merged for 3.0. Does it stand a chance to be merged into 3.1, or it's better to resubmit these patches to usb/gadget subtree to Felipe/Greg?
--
With best wishes
Dmitry
PATCH 4/7 pxa25x: separate lubbock handling to lubbock-usb transceiver
Quoted 4 lines · Eric Miao
Felipe, ping?
Cc'ed Greg KH. Any possibility for this to go quicker, this series has been delayed for 2 cycles. And the patches look good to me.
Someone should have said something sooner then :)
I can take them, if someone resends them, with the proper acked-by lines, and queue them up for 3.1.
thanks,
greg k-h
PATCH 4/7 pxa25x: separate lubbock handling to lubbock-usb transceiver
Quoted 11 lines · Greg KH
Quoted 5 lines · Eric Miao
Felipe, ping?
Cc'ed Greg KH. Any possibility for this to go quicker, this series has been
delayed for 2 cycles. And the patches look good to me.Someone should have said something sooner then :)
I can take them, if someone resends them, with the proper acked-by lines, and queue them up for 3.1.
I've resent them + several more patches which waited for them to be applied.
Signature · 2 lines
With best wishes Dmitry
PATCH 5/7 lubbock: switch to using lubbock_usb_xceiv transceiver
In reply to Dmitry Eremin-Solenikov--- arch/arm/mach-pxa/lubbock.c | 17 ++++++----------- 1 files changed, 6 insertions(+), 11 deletions(-)
arch/arm/mach-pxa/lubbock.c +6 -11
@@ -207,16 +207,6 @@ device_initcall(lubbock_irq_device_init);#endif -static int lubbock_udc_is_connected (void ) -{ -return (LUB_MISC_RD & (1 <<9 )) ==0 ; -} - -static struct pxa2xx_udc_mach_info udc_info__initdata = { - .udc_is_connected = lubbock_udc_is_connected, -// no D+ pullup; lubbock can't connect/disconnect in software -}; -static struct resource sa1111_resources[] = { [0 ] = { .start =0x10000000 ,
@@ -388,11 +378,17 @@ static struct platform_device lubbock_flash_device[2] = { }, }; +static struct platform_device lubbock_usb_xceiv = { + .name ="lubbock_usb_xceiv" , + .id =-1 , +}; +static struct platform_device *devices[]__initdata = { &sa1111_device, &smc91x_device, &lubbock_flash_device[0 ], &lubbock_flash_device[1 ], + &lubbock_usb_xceiv, };static struct pxafb_mode_info sharp_lm8v31_mode = {
@@ -520,7 +516,6 @@ static void __init lubbock_init(void)pxa_set_stuart_info (NULL );clk_add_alias ("SA1111_CLK" ,NULL ,"GPIO11_CLK" ,NULL ); -pxa_set_udc_info (&udc_info);pxa_set_fb_info (NULL , &sharp_lm8v31);pxa_set_mci_info (&lubbock_mci_platform_data);pxa_set_ficp_info (&lubbock_ficp_platform_data);
Signature · 1 line
1.7.4.1
PATCH 6/7 pxa25x: drop handling of udc_is_connected
In reply to Dmitry Eremin-SolenikovThere are no more users of udc_is_connected. Drop this field from mach_info and stop using it in pxa25x_udc.
--- arch/arm/include/asm/mach/udc_pxa2xx.h | 1 - drivers/usb/gadget/pxa25x_udc.c | 13 +++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-)
arch/arm/include/asm/mach/udc_pxa2xx.h +0 -1
@@ -10,7 +10,6 @@*/ struct pxa2xx_udc_mach_info { -int (*udc_is_connected)(void );/* do we see host? */ void (*udc_command)(int cmd);#define PXA2XX_UDC_CMD_CONNECT 0/* let host see us */ #define PXA2XX_UDC_CMD_DISCONNECT 1/* so host won't see us */
drivers/usb/gadget/pxa25x_udc.c +9 -4
@@ -1072,7 +1072,7 @@ udc_seq_show(struct seq_file *m, void *_d) (tmp & UDCCFR_ACM) ? " acm" : ""); } -if (dev->gadget.speed !=USB_SPEED_FULL || !dev->driver) +if (dev->gadget.speed ==USB_SPEED_UNKNOWN || !dev->driver) goto done; seq_printf(m, "ep0 IN %lu/%lu, OUT %lu/%lu\nirqs %lu\n\n",
@@ -1700,9 +1700,13 @@ pxa25x_udc_irq(int irq, void *_dev)if (unlikely (udccr &UDCCR_SUSIR )) {udc_ack_int_UDCCR (UDCCR_SUSIR ); handled =1 ; -DBG (DBG_VERBOSE ,"USB suspend\n" ); +DBG (DBG_VERBOSE ,"USB suspend%s\n" , + dev->gadget.speed !=USB_SPEED_UNKNOWN + ?"" :"+disconnect" ); -if (dev->gadget.speed !=USB_SPEED_UNKNOWN +if (dev->gadget.speed ==USB_SPEED_UNKNOWN ) +stop_activity (dev, dev->driver); +else if (dev->gadget.speed !=USB_SPEED_UNKNOWN && dev->driver && dev->driver->suspend) dev->driver->suspend (&dev->gadget);
@@ -1717,7 +1721,8 @@ pxa25x_udc_irq(int irq, void *_dev)if (dev->gadget.speed !=USB_SPEED_UNKNOWN && dev->driver - && dev->driver->resume) + && dev->driver->resume + && dev->gadget.speed !=USB_SPEED_UNKNOWN ) dev->driver->resume (&dev->gadget); }
Signature · 1 line
1.7.4.1
PATCH 6/7 pxa25x: drop handling of udc_is_connected
Hello.
Quoted 1 line · Dmitry Eremin-Solenikov
There are no more users of
udc_is_connected. Drop this field frommach_info
If I don't mistake, this patch does more than just that.
Quoted 1 line
and stop using it in
pxa25x_udc.
Hm, I don't see where you're doing that. Instead you're changing some checks
for gadget speed and adding some code. And you've said that the driver never used that thing before. Hm?
Quoted 1 line
Signed-off-by Dmitry Eremin-Solenikov <[email protected]>
[...]
Quoted 16 lines
drivers/usb/gadget/pxa25x_udc.c +1
-1@@ -1072,7 +1072,7 @@ udc_seq_show(struct seq_file *m, void *_d) (tmp & UDCCFR_ACM) ? " acm" : ""); } -if (dev->gadget.speed !=USB_SPEED_FULL || !dev->driver) +if (dev->gadget.speed ==USB_SPEED_UNKNOWN || !dev->driver) goto done; seq_printf(m, "ep0 IN %lu/%lu, OUT %lu/%lu\nirqs %lu\n\n",@@ -1700,9 +1700,13 @@ pxa25x_udc_irq(int irq, void *_dev)if (unlikely (udccr &UDCCR_SUSIR )) {udc_ack_int_UDCCR (UDCCR_SUSIR );
drivers/usb/gadget/pxa25x_udc.c pxa25x_udc_irq(int irq, void *_dev) · line 1709
Quoted 10 lines
drivers/usb/gadget/pxa25x_udc.c +6
-2handled =1 ; -DBG (DBG_VERBOSE ,"USB suspend\n" ); +DBG (DBG_VERBOSE ,"USB suspend%s\n" , + dev->gadget.speed !=USB_SPEED_UNKNOWN + ?"" :"+disconnect" ); - if (dev->gadget.speed != USB_SPEED_UNKNOWN +if (dev->gadget.speed ==USB_SPEED_UNKNOWN ) +stop_activity (dev, dev->driver); + else if (dev->gadget.speed != USB_SPEED_UNKNOWN
This is redundant, as it will always be true after your first *if*.
WBR, Sergei
PATCH 6/7 pxa25x: drop handling of udc_is_connected
Quoted 7 lines · Sergei Shtylyov
Hello.
Quoted 2 lines · Dmitry Eremin-Solenikov
There are no more users of
udc_is_connected. Drop this field frommach_info
Quoted 8 lines
If I don't mistake, this patch does more than just that.
Quoted 1 line
and stop using it in
pxa25x_udc.Hm, I don't see where you're doing that. Instead you're changing some
checks
for gadget speed and adding some code. And you've said that the driver never used that thing before. Hm?
Strange. I thought I cleaned up this patch. There are some leftovers from previous
rebases. Correct patch as it is now includes only the part regarding udc_is_connected
field.
I'll wait for more review comments and then resend the whole serie.
Signature · 2 lines
With best wishes Dmitry
PATCH 7/7 gpio-vbus: ask for vbus_draw regulator before registering xceiv
In reply to Dmitry Eremin-SolenikovAsk for vbus_draw regulator before registering tranceiver to disallow possible race between registration and set_power/etc.
--- drivers/usb/otg/gpio_vbus.c | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-)
drivers/usb/otg/gpio_vbus.c +7 -7
@@ -279,6 +279,13 @@ static int __init gpio_vbus_probe(struct platform_device *pdev) }INIT_WORK (&gpio_vbus->work, gpio_vbus_work); + gpio_vbus->vbus_draw =regulator_get (&pdev->dev,"vbus_draw" ); +if (IS_ERR (gpio_vbus->vbus_draw)) { +dev_dbg (&pdev->dev,"can't get vbus_draw regulator, err: %ld\n" , +PTR_ERR (gpio_vbus->vbus_draw)); + gpio_vbus->vbus_draw =NULL ; + } +/* only active when a gadget is registered */ err =otg_set_transceiver (&gpio_vbus->otg);if (err) {
@@ -287,13 +294,6 @@ static int __init gpio_vbus_probe(struct platform_device *pdev) goto err_otg; } - gpio_vbus->vbus_draw =regulator_get (&pdev->dev,"vbus_draw" ); -if (IS_ERR (gpio_vbus->vbus_draw)) { -dev_dbg (&pdev->dev,"can't get vbus_draw regulator, err: %ld\n" , -PTR_ERR (gpio_vbus->vbus_draw)); - gpio_vbus->vbus_draw =NULL ; - } -return 0 ; err_otg:free_irq (irq, &pdev->dev);
Signature · 1 line
1.7.4.1
PATCH 7/7 gpio-vbus: ask for vbus_draw regulator before registering xceiv
Quoted 4 lines · Dmitry Eremin-Solenikov
Ask for
vbus_drawregulator before registering tranceiver to disallow possible race between registration and set_power/etc.Signed-off-by Dmitry Eremin-Solenikov <[email protected]>
Greg, can you help take this patch. This looks like a good fix.
Quoted 40 lines
---
?drivers/usb/otg/gpio_vbus.c | ? 14 +++++++------- ?1 files changed, 7 insertions(+), 7 deletions(-)drivers/usb/otg/gpio_vbus.c +7
-0@@ -279,6 +279,13 @@ static int __init gpio_vbus_probe(struct platform_device *pdev) ? ? ? ?} ? ? ? ?INIT_WORK(&gpio_vbus->work, gpio_vbus_work); + ? ? ? gpio_vbus->vbus_draw = regulator_get(&pdev->dev, "vbus_draw"); + ? ? ? if (IS_ERR(gpio_vbus->vbus_draw)) { + ? ? ? ? ? ? ? dev_dbg(&pdev->dev, "can't get vbus_draw regulator, err: %ld\n", + ? ? ? ? ? ? ? ? ? ? ? PTR_ERR(gpio_vbus->vbus_draw)); + ? ? ? ? ? ? ? gpio_vbus->vbus_draw = NULL; + ? ? ? } +? ? ? ?/* only active when a gadget is registered */ ? ? ? ?err =
otg_set_transceiver(&gpio_vbus->otg); ? ? ? ?if (err) {drivers/usb/otg/gpio_vbus.c +0
-7@@ -287,13 +294,6 @@ static int __init gpio_vbus_probe(struct platform_device *pdev) ? ? ? ? ? ? ? ?goto err_otg; ? ? ? ?} - ? ? ? gpio_vbus->vbus_draw = regulator_get(&pdev->dev, "vbus_draw"); - ? ? ? if (IS_ERR(gpio_vbus->vbus_draw)) { - ? ? ? ? ? ? ? dev_dbg(&pdev->dev, "can't get vbus_draw regulator, err: %ld\n", - ? ? ? ? ? ? ? ? ? ? ? PTR_ERR(gpio_vbus->vbus_draw)); - ? ? ? ? ? ? ? gpio_vbus->vbus_draw = NULL; - ? ? ? } - ? ? ? ?return 0;?err_otg:
? ? ? ?free_irq(irq,&pdev->dev);
--
1.7.4.1
PATCH 7/7 gpio-vbus: ask for vbus_draw regulator before registering xceiv
Quoted 10 lines · Eric Miao
Quoted 4 lines · Dmitry Eremin-Solenikov
Ask for
vbus_drawregulator before registering tranceiver to disallow possible race between registration and set_power/etc.Signed-off-by Dmitry Eremin-Solenikov <[email protected]>Acked-by Eric Miao <[email protected]>Greg, can you help take this patch. This looks like a good fix.
I could if I could get it in a format I could apply it in :(
Can someone resend it?
thanks,
greg k-h
PATCH 1/1 gpio-vbus: ask for vbus_draw regulator before registering xceiv
Ask for vbus_draw regulator before registering tranceiver to disallow possible race between registration and set_power/etc.
--- drivers/usb/otg/gpio_vbus.c | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-)
drivers/usb/otg/gpio_vbus.c +7 -7
@@ -279,6 +279,13 @@ static int __init gpio_vbus_probe(struct platform_device *pdev) }INIT_WORK (&gpio_vbus->work, gpio_vbus_work); + gpio_vbus->vbus_draw =regulator_get (&pdev->dev,"vbus_draw" ); +if (IS_ERR (gpio_vbus->vbus_draw)) { +dev_dbg (&pdev->dev,"can't get vbus_draw regulator, err: %ld\n" , +PTR_ERR (gpio_vbus->vbus_draw)); + gpio_vbus->vbus_draw =NULL ; + } +/* only active when a gadget is registered */ err =otg_set_transceiver (&gpio_vbus->otg);if (err) {
@@ -287,13 +294,6 @@ static int __init gpio_vbus_probe(struct platform_device *pdev) goto err_otg; } - gpio_vbus->vbus_draw =regulator_get (&pdev->dev,"vbus_draw" ); -if (IS_ERR (gpio_vbus->vbus_draw)) { -dev_dbg (&pdev->dev,"can't get vbus_draw regulator, err: %ld\n" , -PTR_ERR (gpio_vbus->vbus_draw)); - gpio_vbus->vbus_draw =NULL ; - } -return 0 ; err_otg:free_irq (irq, &pdev->dev);
Signature · 1 line
1.7.4.4