Commit 9068a4c6 authored by Milan Svoboda's avatar Milan Svoboda Committed by Greg Kroah-Hartman

USB: pxa2xx_udc: use generic gpio layer

This patch lets the pxa2xx_udc use the generic gpio layer,
on the relevant PXA and IXP systems.
Signed-off-by: default avatarMilan Svoboda <msvoboda@ra.rockwell.com>
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent e4f74737
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#undef DEBUG #undef DEBUG
// #define VERBOSE DBG_VERBOSE // #define VERBOSE DBG_VERBOSE
#include <linux/device.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/ioport.h> #include <linux/ioport.h>
...@@ -46,19 +47,17 @@ ...@@ -46,19 +47,17 @@
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <asm/dma.h> #include <asm/dma.h>
#include <asm/gpio.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#ifdef CONFIG_ARCH_PXA
#include <asm/arch/pxa-regs.h>
#endif
#include <linux/usb/ch9.h> #include <linux/usb/ch9.h>
#include <linux/usb_gadget.h> #include <linux/usb_gadget.h>
#include <asm/arch/udc.h> #include <asm/mach/udc_pxa2xx.h>
/* /*
...@@ -155,7 +154,7 @@ static int is_vbus_present(void) ...@@ -155,7 +154,7 @@ static int is_vbus_present(void)
struct pxa2xx_udc_mach_info *mach = the_controller->mach; struct pxa2xx_udc_mach_info *mach = the_controller->mach;
if (mach->gpio_vbus) if (mach->gpio_vbus)
return udc_gpio_get(mach->gpio_vbus); return gpio_get_value(mach->gpio_vbus);
if (mach->udc_is_connected) if (mach->udc_is_connected)
return mach->udc_is_connected(); return mach->udc_is_connected();
return 1; return 1;
...@@ -167,7 +166,7 @@ static void pullup_off(void) ...@@ -167,7 +166,7 @@ static void pullup_off(void)
struct pxa2xx_udc_mach_info *mach = the_controller->mach; struct pxa2xx_udc_mach_info *mach = the_controller->mach;
if (mach->gpio_pullup) if (mach->gpio_pullup)
udc_gpio_set(mach->gpio_pullup, 0); gpio_set_value(mach->gpio_pullup, 0);
else if (mach->udc_command) else if (mach->udc_command)
mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT); mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT);
} }
...@@ -177,7 +176,7 @@ static void pullup_on(void) ...@@ -177,7 +176,7 @@ static void pullup_on(void)
struct pxa2xx_udc_mach_info *mach = the_controller->mach; struct pxa2xx_udc_mach_info *mach = the_controller->mach;
if (mach->gpio_pullup) if (mach->gpio_pullup)
udc_gpio_set(mach->gpio_pullup, 1); gpio_set_value(mach->gpio_pullup, 1);
else if (mach->udc_command) else if (mach->udc_command)
mach->udc_command(PXA2XX_UDC_CMD_CONNECT); mach->udc_command(PXA2XX_UDC_CMD_CONNECT);
} }
...@@ -1742,7 +1741,7 @@ lubbock_vbus_irq(int irq, void *_dev) ...@@ -1742,7 +1741,7 @@ lubbock_vbus_irq(int irq, void *_dev)
static irqreturn_t udc_vbus_irq(int irq, void *_dev) static irqreturn_t udc_vbus_irq(int irq, void *_dev)
{ {
struct pxa2xx_udc *dev = _dev; struct pxa2xx_udc *dev = _dev;
int vbus = udc_gpio_get(dev->mach->gpio_vbus); int vbus = gpio_get_value(dev->mach->gpio_vbus);
pxa2xx_udc_vbus_session(&dev->gadget, vbus); pxa2xx_udc_vbus_session(&dev->gadget, vbus);
return IRQ_HANDLED; return IRQ_HANDLED;
...@@ -2535,14 +2534,33 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev) ...@@ -2535,14 +2534,33 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev)
/* other non-static parts of init */ /* other non-static parts of init */
dev->dev = &pdev->dev; dev->dev = &pdev->dev;
dev->mach = pdev->dev.platform_data; dev->mach = pdev->dev.platform_data;
if (dev->mach->gpio_vbus) { if (dev->mach->gpio_vbus) {
udc_gpio_init_vbus(dev->mach->gpio_vbus); if ((retval = gpio_request(dev->mach->gpio_vbus,
vbus_irq = udc_gpio_to_irq(dev->mach->gpio_vbus); "pxa2xx_udc GPIO VBUS"))) {
dev_dbg(&pdev->dev,
"can't get vbus gpio %d, err: %d\n",
dev->mach->gpio_vbus, retval);
return -EBUSY;
}
gpio_direction_input(dev->mach->gpio_vbus);
vbus_irq = gpio_to_irq(dev->mach->gpio_vbus);
set_irq_type(vbus_irq, IRQT_BOTHEDGE); set_irq_type(vbus_irq, IRQT_BOTHEDGE);
} else } else
vbus_irq = 0; vbus_irq = 0;
if (dev->mach->gpio_pullup)
udc_gpio_init_pullup(dev->mach->gpio_pullup); if (dev->mach->gpio_pullup) {
if ((retval = gpio_request(dev->mach->gpio_pullup,
"pca2xx_udc GPIO PULLUP"))) {
dev_dbg(&pdev->dev,
"can't get pullup gpio %d, err: %d\n",
dev->mach->gpio_pullup, retval);
if (dev->mach->gpio_vbus)
gpio_free(dev->mach->gpio_vbus);
return -EBUSY;
}
gpio_direction_output(dev->mach->gpio_pullup, 0);
}
init_timer(&dev->timer); init_timer(&dev->timer);
dev->timer.function = udc_watchdog; dev->timer.function = udc_watchdog;
...@@ -2566,6 +2584,10 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev) ...@@ -2566,6 +2584,10 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev)
if (retval != 0) { if (retval != 0) {
printk(KERN_ERR "%s: can't get irq %d, err %d\n", printk(KERN_ERR "%s: can't get irq %d, err %d\n",
driver_name, irq, retval); driver_name, irq, retval);
if (dev->mach->gpio_pullup)
gpio_free(dev->mach->gpio_pullup);
if (dev->mach->gpio_vbus)
gpio_free(dev->mach->gpio_vbus);
return -EBUSY; return -EBUSY;
} }
dev->got_irq = 1; dev->got_irq = 1;
...@@ -2581,6 +2603,10 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev) ...@@ -2581,6 +2603,10 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev)
driver_name, LUBBOCK_USB_DISC_IRQ, retval); driver_name, LUBBOCK_USB_DISC_IRQ, retval);
lubbock_fail0: lubbock_fail0:
free_irq(irq, dev); free_irq(irq, dev);
if (dev->mach->gpio_pullup)
gpio_free(dev->mach->gpio_pullup);
if (dev->mach->gpio_vbus)
gpio_free(dev->mach->gpio_vbus);
return -EBUSY; return -EBUSY;
} }
retval = request_irq(LUBBOCK_USB_IRQ, retval = request_irq(LUBBOCK_USB_IRQ,
...@@ -2608,6 +2634,10 @@ lubbock_fail0: ...@@ -2608,6 +2634,10 @@ lubbock_fail0:
printk(KERN_ERR "%s: can't get irq %i, err %d\n", printk(KERN_ERR "%s: can't get irq %i, err %d\n",
driver_name, vbus_irq, retval); driver_name, vbus_irq, retval);
free_irq(irq, dev); free_irq(irq, dev);
if (dev->mach->gpio_pullup)
gpio_free(dev->mach->gpio_pullup);
if (dev->mach->gpio_vbus)
gpio_free(dev->mach->gpio_vbus);
return -EBUSY; return -EBUSY;
} }
} }
...@@ -2641,8 +2671,13 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev) ...@@ -2641,8 +2671,13 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev)
free_irq(LUBBOCK_USB_IRQ, dev); free_irq(LUBBOCK_USB_IRQ, dev);
} }
#endif #endif
if (dev->mach->gpio_vbus) if (dev->mach->gpio_vbus) {
free_irq(IRQ_GPIO(dev->mach->gpio_vbus), dev); free_irq(gpio_to_irq(dev->mach->gpio_vbus), dev);
gpio_free(dev->mach->gpio_vbus);
}
if (dev->mach->gpio_pullup)
gpio_free(dev->mach->gpio_pullup);
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
the_controller = NULL; the_controller = NULL;
return 0; return 0;
......
...@@ -6,25 +6,3 @@ ...@@ -6,25 +6,3 @@
extern void ixp4xx_set_udc_info(struct pxa2xx_udc_mach_info *info); extern void ixp4xx_set_udc_info(struct pxa2xx_udc_mach_info *info);
static inline int udc_gpio_to_irq(unsigned gpio)
{
return 0;
}
static inline void udc_gpio_init_vbus(unsigned gpio)
{
}
static inline void udc_gpio_init_pullup(unsigned gpio)
{
}
static inline int udc_gpio_get(unsigned gpio)
{
return 0;
}
static inline void udc_gpio_set(unsigned gpio, int is_on)
{
}
/* /*
* linux/include/asm-arm/arch-pxa/udc.h * linux/include/asm-arm/arch-pxa/udc.h
* *
* This supports machine-specific differences in how the PXA2xx
* USB Device Controller (UDC) is wired.
*
*/ */
#include <asm/mach/udc_pxa2xx.h> #include <asm/mach/udc_pxa2xx.h>
extern void pxa_set_udc_info(struct pxa2xx_udc_mach_info *info); extern void pxa_set_udc_info(struct pxa2xx_udc_mach_info *info);
static inline int udc_gpio_to_irq(unsigned gpio)
{
return IRQ_GPIO(gpio & GPIO_MD_MASK_NR);
}
static inline void udc_gpio_init_vbus(unsigned gpio)
{
pxa_gpio_mode((gpio & GPIO_MD_MASK_NR) | GPIO_IN);
}
static inline void udc_gpio_init_pullup(unsigned gpio)
{
pxa_gpio_mode((gpio & GPIO_MD_MASK_NR) | GPIO_OUT | GPIO_DFLT_LOW);
}
static inline int udc_gpio_get(unsigned gpio)
{
return (GPLR(gpio) & GPIO_bit(gpio)) != 0;
}
static inline void udc_gpio_set(unsigned gpio, int is_on)
{
int mask = GPIO_bit(gpio);
if (is_on)
GPSR(gpio) = mask;
else
GPCR(gpio) = mask;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment