aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget
diff options
context:
space:
mode:
authorDmitry Baryshkov <dbaryshkov@gmail.com>2008-02-22 20:17:19 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2008-03-04 17:57:44 -0500
commit64cc2dd937298324c77c7d584495052547c64a6a (patch)
treef6409ea83ad3a905fa7211256b9a9c0d4d975760 /drivers/usb/gadget
parent546d7eec389a3df3173b3131d92829c14e614601 (diff)
USB: pxa2xx_udc: fix misuse of clock enable/disable calls
Fix pxa2xx_udc to balance calls to clk_enable/clk_disable. [db: remove inline #ifdefs for IXP non-support of <linux/clk.h> calls] Signed-off-by: Dmitry Baryshkov dbaryshkov@gmail.com Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r--drivers/usb/gadget/pxa2xx_udc.c88
-rw-r--r--drivers/usb/gadget/pxa2xx_udc.h4
2 files changed, 53 insertions, 39 deletions
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c
index 4402d6f042d..096c41cc40d 100644
--- a/drivers/usb/gadget/pxa2xx_udc.c
+++ b/drivers/usb/gadget/pxa2xx_udc.c
@@ -103,6 +103,12 @@ static const char ep0name [] = "ep0";
103#error "Can't configure both IXP and PXA" 103#error "Can't configure both IXP and PXA"
104#endif 104#endif
105 105
106/* IXP doesn't yet support <linux/clk.h> */
107#define clk_get(dev,name) NULL
108#define clk_enable(clk) do { } while (0)
109#define clk_disable(clk) do { } while (0)
110#define clk_put(clk) do { } while (0)
111
106#endif 112#endif
107 113
108#include "pxa2xx_udc.h" 114#include "pxa2xx_udc.h"
@@ -934,20 +940,31 @@ static void udc_disable(struct pxa2xx_udc *);
934/* We disable the UDC -- and its 48 MHz clock -- whenever it's not 940/* We disable the UDC -- and its 48 MHz clock -- whenever it's not
935 * in active use. 941 * in active use.
936 */ 942 */
937static int pullup(struct pxa2xx_udc *udc, int is_active) 943static int pullup(struct pxa2xx_udc *udc)
938{ 944{
939 is_active = is_active && udc->vbus && udc->pullup; 945 int is_active = udc->vbus && udc->pullup && !udc->suspended;
940 DMSG("%s\n", is_active ? "active" : "inactive"); 946 DMSG("%s\n", is_active ? "active" : "inactive");
941 if (is_active) 947 if (is_active) {
942 udc_enable(udc); 948 if (!udc->active) {
943 else { 949 udc->active = 1;
944 if (udc->gadget.speed != USB_SPEED_UNKNOWN) { 950 /* Enable clock for USB device */
945 DMSG("disconnect %s\n", udc->driver 951 clk_enable(udc->clk);
946 ? udc->driver->driver.name 952 udc_enable(udc);
947 : "(no driver)");
948 stop_activity(udc, udc->driver);
949 } 953 }
950 udc_disable(udc); 954 } else {
955 if (udc->active) {
956 if (udc->gadget.speed != USB_SPEED_UNKNOWN) {
957 DMSG("disconnect %s\n", udc->driver
958 ? udc->driver->driver.name
959 : "(no driver)");
960 stop_activity(udc, udc->driver);
961 }
962 udc_disable(udc);
963 /* Disable clock for USB device */
964 clk_disable(udc->clk);
965 udc->active = 0;
966 }
967
951 } 968 }
952 return 0; 969 return 0;
953} 970}
@@ -958,9 +975,9 @@ static int pxa2xx_udc_vbus_session(struct usb_gadget *_gadget, int is_active)
958 struct pxa2xx_udc *udc; 975 struct pxa2xx_udc *udc;
959 976
960 udc = container_of(_gadget, struct pxa2xx_udc, gadget); 977 udc = container_of(_gadget, struct pxa2xx_udc, gadget);
961 udc->vbus = is_active = (is_active != 0); 978 udc->vbus = (is_active != 0);
962 DMSG("vbus %s\n", is_active ? "supplied" : "inactive"); 979 DMSG("vbus %s\n", is_active ? "supplied" : "inactive");
963 pullup(udc, is_active); 980 pullup(udc);
964 return 0; 981 return 0;
965} 982}
966 983
@@ -975,9 +992,8 @@ static int pxa2xx_udc_pullup(struct usb_gadget *_gadget, int is_active)
975 if (!udc->mach->gpio_pullup && !udc->mach->udc_command) 992 if (!udc->mach->gpio_pullup && !udc->mach->udc_command)
976 return -EOPNOTSUPP; 993 return -EOPNOTSUPP;
977 994
978 is_active = (is_active != 0); 995 udc->pullup = (is_active != 0);
979 udc->pullup = is_active; 996 pullup(udc);
980 pullup(udc, is_active);
981 return 0; 997 return 0;
982} 998}
983 999
@@ -997,7 +1013,7 @@ static const struct usb_gadget_ops pxa2xx_udc_ops = {
997#ifdef CONFIG_USB_GADGET_DEBUG_FS 1013#ifdef CONFIG_USB_GADGET_DEBUG_FS
998 1014
999static int 1015static int
1000udc_seq_show(struct seq_file *m, void *d) 1016udc_seq_show(struct seq_file *m, void *_d)
1001{ 1017{
1002 struct pxa2xx_udc *dev = m->private; 1018 struct pxa2xx_udc *dev = m->private;
1003 unsigned long flags; 1019 unsigned long flags;
@@ -1146,11 +1162,6 @@ static void udc_disable(struct pxa2xx_udc *dev)
1146 1162
1147 udc_clear_mask_UDCCR(UDCCR_UDE); 1163 udc_clear_mask_UDCCR(UDCCR_UDE);
1148 1164
1149#ifdef CONFIG_ARCH_PXA
1150 /* Disable clock for USB device */
1151 clk_disable(dev->clk);
1152#endif
1153
1154 ep0_idle (dev); 1165 ep0_idle (dev);
1155 dev->gadget.speed = USB_SPEED_UNKNOWN; 1166 dev->gadget.speed = USB_SPEED_UNKNOWN;
1156} 1167}
@@ -1191,11 +1202,6 @@ static void udc_enable (struct pxa2xx_udc *dev)
1191{ 1202{
1192 udc_clear_mask_UDCCR(UDCCR_UDE); 1203 udc_clear_mask_UDCCR(UDCCR_UDE);
1193 1204
1194#ifdef CONFIG_ARCH_PXA
1195 /* Enable clock for USB device */
1196 clk_enable(dev->clk);
1197#endif
1198
1199 /* try to clear these bits before we enable the udc */ 1205 /* try to clear these bits before we enable the udc */
1200 udc_ack_int_UDCCR(UDCCR_SUSIR|/*UDCCR_RSTIR|*/UDCCR_RESIR); 1206 udc_ack_int_UDCCR(UDCCR_SUSIR|/*UDCCR_RSTIR|*/UDCCR_RESIR);
1201 1207
@@ -1286,7 +1292,7 @@ fail:
1286 * for set_configuration as well as eventual disconnect. 1292 * for set_configuration as well as eventual disconnect.
1287 */ 1293 */
1288 DMSG("registered gadget driver '%s'\n", driver->driver.name); 1294 DMSG("registered gadget driver '%s'\n", driver->driver.name);
1289 pullup(dev, 1); 1295 pullup(dev);
1290 dump_state(dev); 1296 dump_state(dev);
1291 return 0; 1297 return 0;
1292} 1298}
@@ -1329,7 +1335,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
1329 return -EINVAL; 1335 return -EINVAL;
1330 1336
1331 local_irq_disable(); 1337 local_irq_disable();
1332 pullup(dev, 0); 1338 dev->pullup = 0;
1339 pullup(dev);
1333 stop_activity(dev, driver); 1340 stop_activity(dev, driver);
1334 local_irq_enable(); 1341 local_irq_enable();
1335 1342
@@ -2131,13 +2138,11 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev)
2131 if (irq < 0) 2138 if (irq < 0)
2132 return -ENODEV; 2139 return -ENODEV;
2133 2140
2134#ifdef CONFIG_ARCH_PXA
2135 dev->clk = clk_get(&pdev->dev, "UDCCLK"); 2141 dev->clk = clk_get(&pdev->dev, "UDCCLK");
2136 if (IS_ERR(dev->clk)) { 2142 if (IS_ERR(dev->clk)) {
2137 retval = PTR_ERR(dev->clk); 2143 retval = PTR_ERR(dev->clk);
2138 goto err_clk; 2144 goto err_clk;
2139 } 2145 }
2140#endif
2141 2146
2142 pr_debug("%s: IRQ %d%s%s\n", driver_name, irq, 2147 pr_debug("%s: IRQ %d%s%s\n", driver_name, irq,
2143 dev->has_cfr ? "" : " (!cfr)", 2148 dev->has_cfr ? "" : " (!cfr)",
@@ -2250,10 +2255,8 @@ lubbock_fail0:
2250 if (dev->mach->gpio_vbus) 2255 if (dev->mach->gpio_vbus)
2251 gpio_free(dev->mach->gpio_vbus); 2256 gpio_free(dev->mach->gpio_vbus);
2252 err_gpio_vbus: 2257 err_gpio_vbus:
2253#ifdef CONFIG_ARCH_PXA
2254 clk_put(dev->clk); 2258 clk_put(dev->clk);
2255 err_clk: 2259 err_clk:
2256#endif
2257 return retval; 2260 return retval;
2258} 2261}
2259 2262
@@ -2269,7 +2272,9 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev)
2269 if (dev->driver) 2272 if (dev->driver)
2270 return -EBUSY; 2273 return -EBUSY;
2271 2274
2272 udc_disable(dev); 2275 dev->pullup = 0;
2276 pullup(dev);
2277
2273 remove_debug_files(dev); 2278 remove_debug_files(dev);
2274 2279
2275 if (dev->got_irq) { 2280 if (dev->got_irq) {
@@ -2289,9 +2294,7 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev)
2289 if (dev->mach->gpio_pullup) 2294 if (dev->mach->gpio_pullup)
2290 gpio_free(dev->mach->gpio_pullup); 2295 gpio_free(dev->mach->gpio_pullup);
2291 2296
2292#ifdef CONFIG_ARCH_PXA
2293 clk_put(dev->clk); 2297 clk_put(dev->clk);
2294#endif
2295 2298
2296 platform_set_drvdata(pdev, NULL); 2299 platform_set_drvdata(pdev, NULL);
2297 the_controller = NULL; 2300 the_controller = NULL;
@@ -2317,10 +2320,15 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev)
2317static int pxa2xx_udc_suspend(struct platform_device *dev, pm_message_t state) 2320static int pxa2xx_udc_suspend(struct platform_device *dev, pm_message_t state)
2318{ 2321{
2319 struct pxa2xx_udc *udc = platform_get_drvdata(dev); 2322 struct pxa2xx_udc *udc = platform_get_drvdata(dev);
2323 unsigned long flags;
2320 2324
2321 if (!udc->mach->gpio_pullup && !udc->mach->udc_command) 2325 if (!udc->mach->gpio_pullup && !udc->mach->udc_command)
2322 WARN("USB host won't detect disconnect!\n"); 2326 WARN("USB host won't detect disconnect!\n");
2323 pullup(udc, 0); 2327 udc->suspended = 1;
2328
2329 local_irq_save(flags);
2330 pullup(udc);
2331 local_irq_restore(flags);
2324 2332
2325 return 0; 2333 return 0;
2326} 2334}
@@ -2328,8 +2336,12 @@ static int pxa2xx_udc_suspend(struct platform_device *dev, pm_message_t state)
2328static int pxa2xx_udc_resume(struct platform_device *dev) 2336static int pxa2xx_udc_resume(struct platform_device *dev)
2329{ 2337{
2330 struct pxa2xx_udc *udc = platform_get_drvdata(dev); 2338 struct pxa2xx_udc *udc = platform_get_drvdata(dev);
2339 unsigned long flags;
2331 2340
2332 pullup(udc, 1); 2341 udc->suspended = 0;
2342 local_irq_save(flags);
2343 pullup(udc);
2344 local_irq_restore(flags);
2333 2345
2334 return 0; 2346 return 0;
2335} 2347}
diff --git a/drivers/usb/gadget/pxa2xx_udc.h b/drivers/usb/gadget/pxa2xx_udc.h
index b67e3ff5e4e..e2c19e88c87 100644
--- a/drivers/usb/gadget/pxa2xx_udc.h
+++ b/drivers/usb/gadget/pxa2xx_udc.h
@@ -119,7 +119,9 @@ struct pxa2xx_udc {
119 has_cfr : 1, 119 has_cfr : 1,
120 req_pending : 1, 120 req_pending : 1,
121 req_std : 1, 121 req_std : 1,
122 req_config : 1; 122 req_config : 1,
123 suspended : 1,
124 active : 1;
123 125
124#define start_watchdog(dev) mod_timer(&dev->timer, jiffies + (HZ/200)) 126#define start_watchdog(dev) mod_timer(&dev->timer, jiffies + (HZ/200))
125 struct timer_list timer; 127 struct timer_list timer;