[PATCH 1/1] ARM: at91: sam9rl pass the toggle bias via pdata for ATMEL USBA UDC
Jean-Christophe PLAGNIOL-VILLARD
plagnioj at jcrosoft.com
Wed Apr 11 09:55:10 EDT 2012
The toggle bias is soc specific we need to pass it via plarform_data to be able
to have multiple soc in the same kernel.
This will also fix the modules support.
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
Cc: Nicolas Ferre <nicolas.ferre at atmel.com>
Cc: linux-usb at vger.kernel.org
---
Hi Greg,
If it's ok with you we will apply it via at91 tree
Best Regards,
J.
arch/arm/mach-at91/at91sam9rl_devices.c | 12 ++++++++++
drivers/usb/gadget/atmel_usba_udc.c | 35 +++++++++---------------------
drivers/usb/gadget/atmel_usba_udc.h | 2 +
include/linux/usb/atmel_usba_udc.h | 1 +
4 files changed, 26 insertions(+), 24 deletions(-)
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
index fe4ae22..409cee6 100644
--- a/arch/arm/mach-at91/at91sam9rl_devices.c
+++ b/arch/arm/mach-at91/at91sam9rl_devices.c
@@ -72,6 +72,16 @@ void __init at91_add_device_hdmac(void) {}
#if defined(CONFIG_USB_ATMEL_USBA) || defined(CONFIG_USB_ATMEL_USBA_MODULE)
+static void toggle_bias(int is_on)
+{
+ unsigned int uckr = at91_pmc_read(AT91_CKGR_UCKR);
+
+ if (is_on)
+ at91_pmc_write(AT91_CKGR_UCKR, uckr | AT91_PMC_BIASEN);
+ else
+ at91_pmc_write(AT91_CKGR_UCKR, uckr & ~(AT91_PMC_BIASEN));
+}
+
static struct resource usba_udc_resources[] = {
[0] = {
.start = AT91SAM9RL_UDPHS_FIFO,
@@ -148,6 +158,8 @@ void __init at91_add_device_usba(struct usba_platform_data *data)
usba_udc_data.pdata.vbus_pin = data->vbus_pin;
}
+ usba_udc_data.pdata.toggle_bias = toggle_bias;
+
/* Pullup pin is handled internally by USB device peripheral */
platform_device_register(&at91_usba_udc_device);
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
index 9f98508..54d3303 100644
--- a/drivers/usb/gadget/atmel_usba_udc.c
+++ b/drivers/usb/gadget/atmel_usba_udc.c
@@ -326,28 +326,10 @@ static int vbus_is_present(struct usba_udc *udc)
return 1;
}
-#if defined(CONFIG_ARCH_AT91SAM9RL)
-
-#include <mach/at91_pmc.h>
-
static void toggle_bias(int is_on)
{
- unsigned int uckr = at91_pmc_read(AT91_CKGR_UCKR);
-
- if (is_on)
- at91_pmc_write(AT91_CKGR_UCKR, uckr | AT91_PMC_BIASEN);
- else
- at91_pmc_write(AT91_CKGR_UCKR, uckr & ~(AT91_PMC_BIASEN));
}
-#else
-
-static void toggle_bias(int is_on)
-{
-}
-
-#endif /* CONFIG_ARCH_AT91SAM9RL */
-
static void next_fifo_transaction(struct usba_ep *ep, struct usba_request *req)
{
unsigned int transaction_len;
@@ -1667,7 +1649,7 @@ static irqreturn_t usba_udc_irq(int irq, void *devid)
}
if (status & USBA_WAKE_UP) {
- toggle_bias(1);
+ udc->toggle_bias(1);
usba_writel(udc, INT_CLR, USBA_WAKE_UP);
DBG(DBG_BUS, "Wake Up CPU detected\n");
}
@@ -1772,13 +1754,13 @@ static irqreturn_t usba_vbus_irq(int irq, void *devid)
vbus = vbus_is_present(udc);
if (vbus != udc->vbus_prev) {
if (vbus) {
- toggle_bias(1);
+ udc->toggle_bias(1);
usba_writel(udc, CTRL, USBA_ENABLE_MASK);
usba_writel(udc, INT_ENB, USBA_END_OF_RESET);
} else {
udc->gadget.speed = USB_SPEED_UNKNOWN;
reset_all_endpoints(udc);
- toggle_bias(0);
+ udc->toggle_bias(0);
usba_writel(udc, CTRL, USBA_DISABLE_MASK);
if (udc->driver->disconnect) {
spin_unlock(&udc->lock);
@@ -1835,7 +1817,7 @@ static int atmel_usba_start(struct usb_gadget_driver *driver,
/* If Vbus is present, enable the controller and wait for reset */
spin_lock_irqsave(&udc->lock, flags);
if (vbus_is_present(udc) && udc->vbus_prev == 0) {
- toggle_bias(1);
+ udc->toggle_bias(1);
usba_writel(udc, CTRL, USBA_ENABLE_MASK);
usba_writel(udc, INT_ENB, USBA_END_OF_RESET);
}
@@ -1868,7 +1850,7 @@ static int atmel_usba_stop(struct usb_gadget_driver *driver)
spin_unlock_irqrestore(&udc->lock, flags);
/* This will also disable the DP pullup */
- toggle_bias(0);
+ udc->toggle_bias(0);
usba_writel(udc, CTRL, USBA_DISABLE_MASK);
if (udc->driver->disconnect)
@@ -1940,9 +1922,14 @@ static int __init usba_udc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, udc);
+ if (pdata->toggle_bias)
+ udc->toggle_bias = pdata->toggle_bias;
+ else
+ udc->toggle_bias = toggle_bias;
+
/* Make sure we start from a clean slate */
clk_enable(pclk);
- toggle_bias(0);
+ udc->toggle_bias(0);
usba_writel(udc, CTRL, USBA_DISABLE_MASK);
clk_disable(pclk);
diff --git a/drivers/usb/gadget/atmel_usba_udc.h b/drivers/usb/gadget/atmel_usba_udc.h
index 88a2e07..edfb6d5 100644
--- a/drivers/usb/gadget/atmel_usba_udc.h
+++ b/drivers/usb/gadget/atmel_usba_udc.h
@@ -318,6 +318,8 @@ struct usba_udc {
void __iomem *regs;
void __iomem *fifo;
+ void (*toggle_bias)(int is_on);
+
struct usb_gadget gadget;
struct usb_gadget_driver *driver;
struct platform_device *pdev;
diff --git a/include/linux/usb/atmel_usba_udc.h b/include/linux/usb/atmel_usba_udc.h
index ba99af2..87326a5 100644
--- a/include/linux/usb/atmel_usba_udc.h
+++ b/include/linux/usb/atmel_usba_udc.h
@@ -18,6 +18,7 @@ struct usba_platform_data {
int vbus_pin_inverted;
int num_ep;
struct usba_ep_data ep[0];
+ void (*toggle_bias)(int is_on);
};
#endif /* __LINUX_USB_USBA_H */
--
1.7.9.1
More information about the linux-arm-kernel
mailing list