diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/usb/gadget/pxa25x_udc.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'drivers/usb/gadget/pxa25x_udc.c')
-rw-r--r-- | drivers/usb/gadget/pxa25x_udc.c | 91 |
1 files changed, 15 insertions, 76 deletions
diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index be5fb34d9602..774545494cf2 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <linux/seq_file.h> | 46 | #include <linux/seq_file.h> |
47 | #include <linux/debugfs.h> | 47 | #include <linux/debugfs.h> |
48 | #include <linux/io.h> | 48 | #include <linux/io.h> |
49 | #include <linux/prefetch.h> | ||
49 | 50 | ||
50 | #include <asm/byteorder.h> | 51 | #include <asm/byteorder.h> |
51 | #include <asm/dma.h> | 52 | #include <asm/dma.h> |
@@ -139,24 +140,6 @@ static const char ep0name [] = "ep0"; | |||
139 | static void pxa25x_ep_fifo_flush (struct usb_ep *ep); | 140 | static void pxa25x_ep_fifo_flush (struct usb_ep *ep); |
140 | static void nuke (struct pxa25x_ep *, int status); | 141 | static void nuke (struct pxa25x_ep *, int status); |
141 | 142 | ||
142 | /* one GPIO should be used to detect VBUS from the host */ | ||
143 | static int is_vbus_present(void) | ||
144 | { | ||
145 | struct pxa2xx_udc_mach_info *mach = the_controller->mach; | ||
146 | |||
147 | if (gpio_is_valid(mach->gpio_vbus)) { | ||
148 | int value = gpio_get_value(mach->gpio_vbus); | ||
149 | |||
150 | if (mach->gpio_vbus_inverted) | ||
151 | return !value; | ||
152 | else | ||
153 | return !!value; | ||
154 | } | ||
155 | if (mach->udc_is_connected) | ||
156 | return mach->udc_is_connected(); | ||
157 | return 1; | ||
158 | } | ||
159 | |||
160 | /* one GPIO should control a D+ pullup, so host sees this device (or not) */ | 143 | /* one GPIO should control a D+ pullup, so host sees this device (or not) */ |
161 | static void pullup_off(void) | 144 | static void pullup_off(void) |
162 | { | 145 | { |
@@ -1055,7 +1038,7 @@ udc_seq_show(struct seq_file *m, void *_d) | |||
1055 | "%s version: %s\nGadget driver: %s\nHost %s\n\n", | 1038 | "%s version: %s\nGadget driver: %s\nHost %s\n\n", |
1056 | driver_name, DRIVER_VERSION SIZE_STR "(pio)", | 1039 | driver_name, DRIVER_VERSION SIZE_STR "(pio)", |
1057 | dev->driver ? dev->driver->driver.name : "(none)", | 1040 | dev->driver ? dev->driver->driver.name : "(none)", |
1058 | is_vbus_present() ? "full speed" : "disconnected"); | 1041 | dev->gadget.speed == USB_SPEED_FULL ? "full speed" : "disconnected"); |
1059 | 1042 | ||
1060 | /* registers for device and ep0 */ | 1043 | /* registers for device and ep0 */ |
1061 | seq_printf(m, | 1044 | seq_printf(m, |
@@ -1094,7 +1077,7 @@ udc_seq_show(struct seq_file *m, void *_d) | |||
1094 | (tmp & UDCCFR_ACM) ? " acm" : ""); | 1077 | (tmp & UDCCFR_ACM) ? " acm" : ""); |
1095 | } | 1078 | } |
1096 | 1079 | ||
1097 | if (!is_vbus_present() || !dev->driver) | 1080 | if (dev->gadget.speed != USB_SPEED_FULL || !dev->driver) |
1098 | goto done; | 1081 | goto done; |
1099 | 1082 | ||
1100 | seq_printf(m, "ep0 IN %lu/%lu, OUT %lu/%lu\nirqs %lu\n\n", | 1083 | seq_printf(m, "ep0 IN %lu/%lu, OUT %lu/%lu\nirqs %lu\n\n", |
@@ -1280,14 +1263,15 @@ static void udc_enable (struct pxa25x_udc *dev) | |||
1280 | * disconnect is reported. then a host may connect again, or | 1263 | * disconnect is reported. then a host may connect again, or |
1281 | * the driver might get unbound. | 1264 | * the driver might get unbound. |
1282 | */ | 1265 | */ |
1283 | int usb_gadget_register_driver(struct usb_gadget_driver *driver) | 1266 | int usb_gadget_probe_driver(struct usb_gadget_driver *driver, |
1267 | int (*bind)(struct usb_gadget *)) | ||
1284 | { | 1268 | { |
1285 | struct pxa25x_udc *dev = the_controller; | 1269 | struct pxa25x_udc *dev = the_controller; |
1286 | int retval; | 1270 | int retval; |
1287 | 1271 | ||
1288 | if (!driver | 1272 | if (!driver |
1289 | || driver->speed < USB_SPEED_FULL | 1273 | || driver->speed < USB_SPEED_FULL |
1290 | || !driver->bind | 1274 | || !bind |
1291 | || !driver->disconnect | 1275 | || !driver->disconnect |
1292 | || !driver->setup) | 1276 | || !driver->setup) |
1293 | return -EINVAL; | 1277 | return -EINVAL; |
@@ -1308,7 +1292,7 @@ fail: | |||
1308 | dev->gadget.dev.driver = NULL; | 1292 | dev->gadget.dev.driver = NULL; |
1309 | return retval; | 1293 | return retval; |
1310 | } | 1294 | } |
1311 | retval = driver->bind(&dev->gadget); | 1295 | retval = bind(&dev->gadget); |
1312 | if (retval) { | 1296 | if (retval) { |
1313 | DMSG("bind to driver %s --> error %d\n", | 1297 | DMSG("bind to driver %s --> error %d\n", |
1314 | driver->driver.name, retval); | 1298 | driver->driver.name, retval); |
@@ -1338,7 +1322,7 @@ fail: | |||
1338 | bind_fail: | 1322 | bind_fail: |
1339 | return retval; | 1323 | return retval; |
1340 | } | 1324 | } |
1341 | EXPORT_SYMBOL(usb_gadget_register_driver); | 1325 | EXPORT_SYMBOL(usb_gadget_probe_driver); |
1342 | 1326 | ||
1343 | static void | 1327 | static void |
1344 | stop_activity(struct pxa25x_udc *dev, struct usb_gadget_driver *driver) | 1328 | stop_activity(struct pxa25x_udc *dev, struct usb_gadget_driver *driver) |
@@ -1434,14 +1418,6 @@ lubbock_vbus_irq(int irq, void *_dev) | |||
1434 | 1418 | ||
1435 | #endif | 1419 | #endif |
1436 | 1420 | ||
1437 | static irqreturn_t udc_vbus_irq(int irq, void *_dev) | ||
1438 | { | ||
1439 | struct pxa25x_udc *dev = _dev; | ||
1440 | |||
1441 | pxa25x_udc_vbus_session(&dev->gadget, is_vbus_present()); | ||
1442 | return IRQ_HANDLED; | ||
1443 | } | ||
1444 | |||
1445 | 1421 | ||
1446 | /*-------------------------------------------------------------------------*/ | 1422 | /*-------------------------------------------------------------------------*/ |
1447 | 1423 | ||
@@ -1765,12 +1741,9 @@ pxa25x_udc_irq(int irq, void *_dev) | |||
1765 | if (unlikely(udccr & UDCCR_SUSIR)) { | 1741 | if (unlikely(udccr & UDCCR_SUSIR)) { |
1766 | udc_ack_int_UDCCR(UDCCR_SUSIR); | 1742 | udc_ack_int_UDCCR(UDCCR_SUSIR); |
1767 | handled = 1; | 1743 | handled = 1; |
1768 | DBG(DBG_VERBOSE, "USB suspend%s\n", is_vbus_present() | 1744 | DBG(DBG_VERBOSE, "USB suspend\n"); |
1769 | ? "" : "+disconnect"); | ||
1770 | 1745 | ||
1771 | if (!is_vbus_present()) | 1746 | if (dev->gadget.speed != USB_SPEED_UNKNOWN |
1772 | stop_activity(dev, dev->driver); | ||
1773 | else if (dev->gadget.speed != USB_SPEED_UNKNOWN | ||
1774 | && dev->driver | 1747 | && dev->driver |
1775 | && dev->driver->suspend) | 1748 | && dev->driver->suspend) |
1776 | dev->driver->suspend(&dev->gadget); | 1749 | dev->driver->suspend(&dev->gadget); |
@@ -1785,8 +1758,7 @@ pxa25x_udc_irq(int irq, void *_dev) | |||
1785 | 1758 | ||
1786 | if (dev->gadget.speed != USB_SPEED_UNKNOWN | 1759 | if (dev->gadget.speed != USB_SPEED_UNKNOWN |
1787 | && dev->driver | 1760 | && dev->driver |
1788 | && dev->driver->resume | 1761 | && dev->driver->resume) |
1789 | && is_vbus_present()) | ||
1790 | dev->driver->resume(&dev->gadget); | 1762 | dev->driver->resume(&dev->gadget); |
1791 | } | 1763 | } |
1792 | 1764 | ||
@@ -2136,7 +2108,7 @@ static struct pxa25x_udc memory = { | |||
2136 | static int __init pxa25x_udc_probe(struct platform_device *pdev) | 2108 | static int __init pxa25x_udc_probe(struct platform_device *pdev) |
2137 | { | 2109 | { |
2138 | struct pxa25x_udc *dev = &memory; | 2110 | struct pxa25x_udc *dev = &memory; |
2139 | int retval, vbus_irq, irq; | 2111 | int retval, irq; |
2140 | u32 chiprev; | 2112 | u32 chiprev; |
2141 | 2113 | ||
2142 | /* insist on Intel/ARM/XScale */ | 2114 | /* insist on Intel/ARM/XScale */ |
@@ -2198,19 +2170,6 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) | |||
2198 | 2170 | ||
2199 | dev->transceiver = otg_get_transceiver(); | 2171 | dev->transceiver = otg_get_transceiver(); |
2200 | 2172 | ||
2201 | if (gpio_is_valid(dev->mach->gpio_vbus)) { | ||
2202 | if ((retval = gpio_request(dev->mach->gpio_vbus, | ||
2203 | "pxa25x_udc GPIO VBUS"))) { | ||
2204 | dev_dbg(&pdev->dev, | ||
2205 | "can't get vbus gpio %d, err: %d\n", | ||
2206 | dev->mach->gpio_vbus, retval); | ||
2207 | goto err_gpio_vbus; | ||
2208 | } | ||
2209 | gpio_direction_input(dev->mach->gpio_vbus); | ||
2210 | vbus_irq = gpio_to_irq(dev->mach->gpio_vbus); | ||
2211 | } else | ||
2212 | vbus_irq = 0; | ||
2213 | |||
2214 | if (gpio_is_valid(dev->mach->gpio_pullup)) { | 2173 | if (gpio_is_valid(dev->mach->gpio_pullup)) { |
2215 | if ((retval = gpio_request(dev->mach->gpio_pullup, | 2174 | if ((retval = gpio_request(dev->mach->gpio_pullup, |
2216 | "pca25x_udc GPIO PULLUP"))) { | 2175 | "pca25x_udc GPIO PULLUP"))) { |
@@ -2236,7 +2195,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) | |||
2236 | udc_disable(dev); | 2195 | udc_disable(dev); |
2237 | udc_reinit(dev); | 2196 | udc_reinit(dev); |
2238 | 2197 | ||
2239 | dev->vbus = !!is_vbus_present(); | 2198 | dev->vbus = 0; |
2240 | 2199 | ||
2241 | /* irq setup after old hardware state is cleaned up */ | 2200 | /* irq setup after old hardware state is cleaned up */ |
2242 | retval = request_irq(irq, pxa25x_udc_irq, | 2201 | retval = request_irq(irq, pxa25x_udc_irq, |
@@ -2257,7 +2216,6 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) | |||
2257 | if (retval != 0) { | 2216 | if (retval != 0) { |
2258 | pr_err("%s: can't get irq %i, err %d\n", | 2217 | pr_err("%s: can't get irq %i, err %d\n", |
2259 | driver_name, LUBBOCK_USB_DISC_IRQ, retval); | 2218 | driver_name, LUBBOCK_USB_DISC_IRQ, retval); |
2260 | lubbock_fail0: | ||
2261 | goto err_irq_lub; | 2219 | goto err_irq_lub; |
2262 | } | 2220 | } |
2263 | retval = request_irq(LUBBOCK_USB_IRQ, | 2221 | retval = request_irq(LUBBOCK_USB_IRQ, |
@@ -2267,39 +2225,24 @@ lubbock_fail0: | |||
2267 | if (retval != 0) { | 2225 | if (retval != 0) { |
2268 | pr_err("%s: can't get irq %i, err %d\n", | 2226 | pr_err("%s: can't get irq %i, err %d\n", |
2269 | driver_name, LUBBOCK_USB_IRQ, retval); | 2227 | driver_name, LUBBOCK_USB_IRQ, retval); |
2270 | free_irq(LUBBOCK_USB_DISC_IRQ, dev); | ||
2271 | goto lubbock_fail0; | 2228 | goto lubbock_fail0; |
2272 | } | 2229 | } |
2273 | } else | 2230 | } else |
2274 | #endif | 2231 | #endif |
2275 | if (vbus_irq) { | ||
2276 | retval = request_irq(vbus_irq, udc_vbus_irq, | ||
2277 | IRQF_DISABLED | IRQF_SAMPLE_RANDOM | | ||
2278 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | ||
2279 | driver_name, dev); | ||
2280 | if (retval != 0) { | ||
2281 | pr_err("%s: can't get irq %i, err %d\n", | ||
2282 | driver_name, vbus_irq, retval); | ||
2283 | goto err_vbus_irq; | ||
2284 | } | ||
2285 | } | ||
2286 | create_debug_files(dev); | 2232 | create_debug_files(dev); |
2287 | 2233 | ||
2288 | return 0; | 2234 | return 0; |
2289 | 2235 | ||
2290 | err_vbus_irq: | ||
2291 | #ifdef CONFIG_ARCH_LUBBOCK | 2236 | #ifdef CONFIG_ARCH_LUBBOCK |
2237 | lubbock_fail0: | ||
2292 | free_irq(LUBBOCK_USB_DISC_IRQ, dev); | 2238 | free_irq(LUBBOCK_USB_DISC_IRQ, dev); |
2293 | err_irq_lub: | 2239 | err_irq_lub: |
2294 | #endif | ||
2295 | free_irq(irq, dev); | 2240 | free_irq(irq, dev); |
2241 | #endif | ||
2296 | err_irq1: | 2242 | err_irq1: |
2297 | if (gpio_is_valid(dev->mach->gpio_pullup)) | 2243 | if (gpio_is_valid(dev->mach->gpio_pullup)) |
2298 | gpio_free(dev->mach->gpio_pullup); | 2244 | gpio_free(dev->mach->gpio_pullup); |
2299 | err_gpio_pullup: | 2245 | err_gpio_pullup: |
2300 | if (gpio_is_valid(dev->mach->gpio_vbus)) | ||
2301 | gpio_free(dev->mach->gpio_vbus); | ||
2302 | err_gpio_vbus: | ||
2303 | if (dev->transceiver) { | 2246 | if (dev->transceiver) { |
2304 | otg_put_transceiver(dev->transceiver); | 2247 | otg_put_transceiver(dev->transceiver); |
2305 | dev->transceiver = NULL; | 2248 | dev->transceiver = NULL; |
@@ -2336,10 +2279,6 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev) | |||
2336 | free_irq(LUBBOCK_USB_IRQ, dev); | 2279 | free_irq(LUBBOCK_USB_IRQ, dev); |
2337 | } | 2280 | } |
2338 | #endif | 2281 | #endif |
2339 | if (gpio_is_valid(dev->mach->gpio_vbus)) { | ||
2340 | free_irq(gpio_to_irq(dev->mach->gpio_vbus), dev); | ||
2341 | gpio_free(dev->mach->gpio_vbus); | ||
2342 | } | ||
2343 | if (gpio_is_valid(dev->mach->gpio_pullup)) | 2282 | if (gpio_is_valid(dev->mach->gpio_pullup)) |
2344 | gpio_free(dev->mach->gpio_pullup); | 2283 | gpio_free(dev->mach->gpio_pullup); |
2345 | 2284 | ||