diff options
author | David Brownell <david-b@pacbell.net> | 2005-04-11 18:38:25 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2005-06-27 17:43:41 -0400 |
commit | 313980c92724cf42877a7bdafdef439ee9d68ccb (patch) | |
tree | e97b170530d30013eb16f2f5a6b1d79e0ca98f4f /drivers | |
parent | d794ac7ae3613c2abfb678617ac7d74c8ff0099c (diff) |
[PATCH] USB: omap_udc updates (mostly cleanups)
Various USB patches, mostly for portability:
- Fifo mode 1 didn't work previously (oopsed), so now it's fixed and
(why not) defines even more endpoints for composite devices.
- OMAP 1710 doesn't have an internal transceiver.
- Small PM update: if the USB link is suspended, don't disconnect on
entry to deep sleep.
- Be more correct about handling zero length control reads. OMAP
seems to mis-handle that protocol peculiarity though; best avoided.
- Platform device resources (for UDC and OTG controllers) now use
physical addresses, so /proc/iomem is more consistent.
- Minor cleanups, notably (by volume) for "sparse" NULL warnings.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/gadget/omap_udc.c | 150 |
1 files changed, 93 insertions, 57 deletions
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 98cbcbc16cc1..4ec91a68f96c 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c | |||
@@ -52,7 +52,6 @@ | |||
52 | #include <asm/mach-types.h> | 52 | #include <asm/mach-types.h> |
53 | 53 | ||
54 | #include <asm/arch/dma.h> | 54 | #include <asm/arch/dma.h> |
55 | #include <asm/arch/mux.h> | ||
56 | #include <asm/arch/usb.h> | 55 | #include <asm/arch/usb.h> |
57 | 56 | ||
58 | #include "omap_udc.h" | 57 | #include "omap_udc.h" |
@@ -253,7 +252,7 @@ static int omap_ep_disable(struct usb_ep *_ep) | |||
253 | } | 252 | } |
254 | 253 | ||
255 | spin_lock_irqsave(&ep->udc->lock, flags); | 254 | spin_lock_irqsave(&ep->udc->lock, flags); |
256 | ep->desc = 0; | 255 | ep->desc = NULL; |
257 | nuke (ep, -ESHUTDOWN); | 256 | nuke (ep, -ESHUTDOWN); |
258 | ep->ep.maxpacket = ep->maxpacket; | 257 | ep->ep.maxpacket = ep->maxpacket; |
259 | ep->has_dma = 0; | 258 | ep->has_dma = 0; |
@@ -388,8 +387,8 @@ done(struct omap_ep *ep, struct omap_req *req, int status) | |||
388 | 387 | ||
389 | /*-------------------------------------------------------------------------*/ | 388 | /*-------------------------------------------------------------------------*/ |
390 | 389 | ||
391 | #define FIFO_FULL (UDC_NON_ISO_FIFO_FULL | UDC_ISO_FIFO_FULL) | 390 | #define UDC_FIFO_FULL (UDC_NON_ISO_FIFO_FULL | UDC_ISO_FIFO_FULL) |
392 | #define FIFO_UNWRITABLE (UDC_EP_HALTED | FIFO_FULL) | 391 | #define UDC_FIFO_UNWRITABLE (UDC_EP_HALTED | UDC_FIFO_FULL) |
393 | 392 | ||
394 | #define FIFO_EMPTY (UDC_NON_ISO_FIFO_EMPTY | UDC_ISO_FIFO_EMPTY) | 393 | #define FIFO_EMPTY (UDC_NON_ISO_FIFO_EMPTY | UDC_ISO_FIFO_EMPTY) |
395 | #define FIFO_UNREADABLE (UDC_EP_HALTED | FIFO_EMPTY) | 394 | #define FIFO_UNREADABLE (UDC_EP_HALTED | FIFO_EMPTY) |
@@ -433,7 +432,7 @@ static int write_fifo(struct omap_ep *ep, struct omap_req *req) | |||
433 | 432 | ||
434 | /* PIO-IN isn't double buffered except for iso */ | 433 | /* PIO-IN isn't double buffered except for iso */ |
435 | ep_stat = UDC_STAT_FLG_REG; | 434 | ep_stat = UDC_STAT_FLG_REG; |
436 | if (ep_stat & FIFO_UNWRITABLE) | 435 | if (ep_stat & UDC_FIFO_UNWRITABLE) |
437 | return 0; | 436 | return 0; |
438 | 437 | ||
439 | count = ep->ep.maxpacket; | 438 | count = ep->ep.maxpacket; |
@@ -504,7 +503,7 @@ static int read_fifo(struct omap_ep *ep, struct omap_req *req) | |||
504 | if (ep_stat & UDC_EP_HALTED) | 503 | if (ep_stat & UDC_EP_HALTED) |
505 | break; | 504 | break; |
506 | 505 | ||
507 | if (ep_stat & FIFO_FULL) | 506 | if (ep_stat & UDC_FIFO_FULL) |
508 | avail = ep->ep.maxpacket; | 507 | avail = ep->ep.maxpacket; |
509 | else { | 508 | else { |
510 | avail = UDC_RXFSTAT_REG; | 509 | avail = UDC_RXFSTAT_REG; |
@@ -856,7 +855,7 @@ static void dma_channel_release(struct omap_ep *ep) | |||
856 | if (!list_empty(&ep->queue)) | 855 | if (!list_empty(&ep->queue)) |
857 | req = container_of(ep->queue.next, struct omap_req, queue); | 856 | req = container_of(ep->queue.next, struct omap_req, queue); |
858 | else | 857 | else |
859 | req = 0; | 858 | req = NULL; |
860 | 859 | ||
861 | active = ((1 << 7) & omap_readl(OMAP_DMA_CCR(ep->lch))) != 0; | 860 | active = ((1 << 7) & omap_readl(OMAP_DMA_CCR(ep->lch))) != 0; |
862 | 861 | ||
@@ -997,18 +996,19 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, int gfp_flags) | |||
997 | UDC_IRQ_EN_REG = irq_en; | 996 | UDC_IRQ_EN_REG = irq_en; |
998 | } | 997 | } |
999 | 998 | ||
1000 | /* STATUS is reverse direction */ | 999 | /* STATUS for zero length DATA stages is |
1001 | UDC_EP_NUM_REG = is_in | 1000 | * always an IN ... even for IN transfers, |
1002 | ? UDC_EP_SEL | 1001 | * a wierd case which seem to stall OMAP. |
1003 | : (UDC_EP_SEL|UDC_EP_DIR); | 1002 | */ |
1003 | UDC_EP_NUM_REG = (UDC_EP_SEL|UDC_EP_DIR); | ||
1004 | UDC_CTRL_REG = UDC_CLR_EP; | 1004 | UDC_CTRL_REG = UDC_CLR_EP; |
1005 | UDC_CTRL_REG = UDC_SET_FIFO_EN; | 1005 | UDC_CTRL_REG = UDC_SET_FIFO_EN; |
1006 | UDC_EP_NUM_REG = udc->ep0_in ? 0 : UDC_EP_DIR; | 1006 | UDC_EP_NUM_REG = UDC_EP_DIR; |
1007 | 1007 | ||
1008 | /* cleanup */ | 1008 | /* cleanup */ |
1009 | udc->ep0_pending = 0; | 1009 | udc->ep0_pending = 0; |
1010 | done(ep, req, 0); | 1010 | done(ep, req, 0); |
1011 | req = 0; | 1011 | req = NULL; |
1012 | 1012 | ||
1013 | /* non-empty DATA stage */ | 1013 | /* non-empty DATA stage */ |
1014 | } else if (is_in) { | 1014 | } else if (is_in) { |
@@ -1029,7 +1029,7 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, int gfp_flags) | |||
1029 | (is_in ? next_in_dma : next_out_dma)(ep, req); | 1029 | (is_in ? next_in_dma : next_out_dma)(ep, req); |
1030 | else if (req) { | 1030 | else if (req) { |
1031 | if ((is_in ? write_fifo : read_fifo)(ep, req) == 1) | 1031 | if ((is_in ? write_fifo : read_fifo)(ep, req) == 1) |
1032 | req = 0; | 1032 | req = NULL; |
1033 | deselect_ep(); | 1033 | deselect_ep(); |
1034 | if (!is_in) { | 1034 | if (!is_in) { |
1035 | UDC_CTRL_REG = UDC_SET_FIFO_EN; | 1035 | UDC_CTRL_REG = UDC_SET_FIFO_EN; |
@@ -1041,7 +1041,7 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, int gfp_flags) | |||
1041 | 1041 | ||
1042 | irq_wait: | 1042 | irq_wait: |
1043 | /* irq handler advances the queue */ | 1043 | /* irq handler advances the queue */ |
1044 | if (req != 0) | 1044 | if (req != NULL) |
1045 | list_add_tail(&req->queue, &ep->queue); | 1045 | list_add_tail(&req->queue, &ep->queue); |
1046 | spin_unlock_irqrestore(&udc->lock, flags); | 1046 | spin_unlock_irqrestore(&udc->lock, flags); |
1047 | 1047 | ||
@@ -1238,6 +1238,8 @@ static int can_pullup(struct omap_udc *udc) | |||
1238 | 1238 | ||
1239 | static void pullup_enable(struct omap_udc *udc) | 1239 | static void pullup_enable(struct omap_udc *udc) |
1240 | { | 1240 | { |
1241 | udc->gadget.dev.parent->power.power_state = PMSG_ON; | ||
1242 | udc->gadget.dev.power.power_state = PMSG_ON; | ||
1241 | UDC_SYSCON1_REG |= UDC_PULLUP_EN; | 1243 | UDC_SYSCON1_REG |= UDC_PULLUP_EN; |
1242 | #ifndef CONFIG_USB_OTG | 1244 | #ifndef CONFIG_USB_OTG |
1243 | if (!cpu_is_omap15xx()) | 1245 | if (!cpu_is_omap15xx()) |
@@ -1382,7 +1384,7 @@ static void update_otg(struct omap_udc *udc) | |||
1382 | static void ep0_irq(struct omap_udc *udc, u16 irq_src) | 1384 | static void ep0_irq(struct omap_udc *udc, u16 irq_src) |
1383 | { | 1385 | { |
1384 | struct omap_ep *ep0 = &udc->ep[0]; | 1386 | struct omap_ep *ep0 = &udc->ep[0]; |
1385 | struct omap_req *req = 0; | 1387 | struct omap_req *req = NULL; |
1386 | 1388 | ||
1387 | ep0->irqs++; | 1389 | ep0->irqs++; |
1388 | 1390 | ||
@@ -1438,7 +1440,7 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) | |||
1438 | if (req) | 1440 | if (req) |
1439 | done(ep0, req, 0); | 1441 | done(ep0, req, 0); |
1440 | } | 1442 | } |
1441 | req = 0; | 1443 | req = NULL; |
1442 | } else if (stat & UDC_STALL) { | 1444 | } else if (stat & UDC_STALL) { |
1443 | UDC_CTRL_REG = UDC_CLR_HALT; | 1445 | UDC_CTRL_REG = UDC_CLR_HALT; |
1444 | UDC_EP_NUM_REG = UDC_EP_DIR; | 1446 | UDC_EP_NUM_REG = UDC_EP_DIR; |
@@ -1511,9 +1513,6 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) | |||
1511 | u.word[3] = UDC_DATA_REG; | 1513 | u.word[3] = UDC_DATA_REG; |
1512 | UDC_EP_NUM_REG = 0; | 1514 | UDC_EP_NUM_REG = 0; |
1513 | } while (UDC_IRQ_SRC_REG & UDC_SETUP); | 1515 | } while (UDC_IRQ_SRC_REG & UDC_SETUP); |
1514 | le16_to_cpus (&u.r.wValue); | ||
1515 | le16_to_cpus (&u.r.wIndex); | ||
1516 | le16_to_cpus (&u.r.wLength); | ||
1517 | 1516 | ||
1518 | /* Delegate almost all control requests to the gadget driver, | 1517 | /* Delegate almost all control requests to the gadget driver, |
1519 | * except for a handful of ch9 status/feature requests that | 1518 | * except for a handful of ch9 status/feature requests that |
@@ -1566,6 +1565,11 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) | |||
1566 | UDC_CTRL_REG = UDC_SET_FIFO_EN; | 1565 | UDC_CTRL_REG = UDC_SET_FIFO_EN; |
1567 | ep->ackwait = 1 + ep->double_buf; | 1566 | ep->ackwait = 1 + ep->double_buf; |
1568 | } | 1567 | } |
1568 | /* NOTE: assumes the host behaves sanely, | ||
1569 | * only clearing real halts. Else we may | ||
1570 | * need to kill pending transfers and then | ||
1571 | * restart the queue... very messy for DMA! | ||
1572 | */ | ||
1569 | } | 1573 | } |
1570 | VDBG("%s halt cleared by host\n", ep->name); | 1574 | VDBG("%s halt cleared by host\n", ep->name); |
1571 | goto ep0out_status_stage; | 1575 | goto ep0out_status_stage; |
@@ -2013,7 +2017,7 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) | |||
2013 | udc->softconnect = 1; | 2017 | udc->softconnect = 1; |
2014 | 2018 | ||
2015 | /* hook up the driver */ | 2019 | /* hook up the driver */ |
2016 | driver->driver.bus = 0; | 2020 | driver->driver.bus = NULL; |
2017 | udc->driver = driver; | 2021 | udc->driver = driver; |
2018 | udc->gadget.dev.driver = &driver->driver; | 2022 | udc->gadget.dev.driver = &driver->driver; |
2019 | spin_unlock_irqrestore(&udc->lock, flags); | 2023 | spin_unlock_irqrestore(&udc->lock, flags); |
@@ -2021,8 +2025,8 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) | |||
2021 | status = driver->bind (&udc->gadget); | 2025 | status = driver->bind (&udc->gadget); |
2022 | if (status) { | 2026 | if (status) { |
2023 | DBG("bind to %s --> %d\n", driver->driver.name, status); | 2027 | DBG("bind to %s --> %d\n", driver->driver.name, status); |
2024 | udc->gadget.dev.driver = 0; | 2028 | udc->gadget.dev.driver = NULL; |
2025 | udc->driver = 0; | 2029 | udc->driver = NULL; |
2026 | goto done; | 2030 | goto done; |
2027 | } | 2031 | } |
2028 | DBG("bound to driver %s\n", driver->driver.name); | 2032 | DBG("bound to driver %s\n", driver->driver.name); |
@@ -2035,8 +2039,8 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) | |||
2035 | if (status < 0) { | 2039 | if (status < 0) { |
2036 | ERR("can't bind to transceiver\n"); | 2040 | ERR("can't bind to transceiver\n"); |
2037 | driver->unbind (&udc->gadget); | 2041 | driver->unbind (&udc->gadget); |
2038 | udc->gadget.dev.driver = 0; | 2042 | udc->gadget.dev.driver = NULL; |
2039 | udc->driver = 0; | 2043 | udc->driver = NULL; |
2040 | goto done; | 2044 | goto done; |
2041 | } | 2045 | } |
2042 | } else { | 2046 | } else { |
@@ -2071,7 +2075,7 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver) | |||
2071 | omap_vbus_session(&udc->gadget, 0); | 2075 | omap_vbus_session(&udc->gadget, 0); |
2072 | 2076 | ||
2073 | if (udc->transceiver) | 2077 | if (udc->transceiver) |
2074 | (void) otg_set_peripheral(udc->transceiver, 0); | 2078 | (void) otg_set_peripheral(udc->transceiver, NULL); |
2075 | else | 2079 | else |
2076 | pullup_disable(udc); | 2080 | pullup_disable(udc); |
2077 | 2081 | ||
@@ -2080,9 +2084,8 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver) | |||
2080 | spin_unlock_irqrestore(&udc->lock, flags); | 2084 | spin_unlock_irqrestore(&udc->lock, flags); |
2081 | 2085 | ||
2082 | driver->unbind(&udc->gadget); | 2086 | driver->unbind(&udc->gadget); |
2083 | udc->gadget.dev.driver = 0; | 2087 | udc->gadget.dev.driver = NULL; |
2084 | udc->driver = 0; | 2088 | udc->driver = NULL; |
2085 | |||
2086 | 2089 | ||
2087 | DBG("unregistered driver '%s'\n", driver->driver.name); | 2090 | DBG("unregistered driver '%s'\n", driver->driver.name); |
2088 | return status; | 2091 | return status; |
@@ -2178,7 +2181,7 @@ static int proc_otg_show(struct seq_file *s) | |||
2178 | 2181 | ||
2179 | tmp = OTG_REV_REG; | 2182 | tmp = OTG_REV_REG; |
2180 | trans = USB_TRANSCEIVER_CTRL_REG; | 2183 | trans = USB_TRANSCEIVER_CTRL_REG; |
2181 | seq_printf(s, "OTG rev %d.%d, transceiver_ctrl %03x\n", | 2184 | seq_printf(s, "\nOTG rev %d.%d, transceiver_ctrl %03x\n", |
2182 | tmp >> 4, tmp & 0xf, trans); | 2185 | tmp >> 4, tmp & 0xf, trans); |
2183 | tmp = OTG_SYSCON_1_REG; | 2186 | tmp = OTG_SYSCON_1_REG; |
2184 | seq_printf(s, "otg_syscon1 %08x usb2 %s, usb1 %s, usb0 %s," | 2187 | seq_printf(s, "otg_syscon1 %08x usb2 %s, usb1 %s, usb0 %s," |
@@ -2235,6 +2238,7 @@ static int proc_otg_show(struct seq_file *s) | |||
2235 | seq_printf(s, "otg_outctrl %04x" "\n", tmp); | 2238 | seq_printf(s, "otg_outctrl %04x" "\n", tmp); |
2236 | tmp = OTG_TEST_REG; | 2239 | tmp = OTG_TEST_REG; |
2237 | seq_printf(s, "otg_test %04x" "\n", tmp); | 2240 | seq_printf(s, "otg_test %04x" "\n", tmp); |
2241 | return 0; | ||
2238 | } | 2242 | } |
2239 | 2243 | ||
2240 | static int proc_udc_show(struct seq_file *s, void *_) | 2244 | static int proc_udc_show(struct seq_file *s, void *_) |
@@ -2378,7 +2382,7 @@ static int proc_udc_show(struct seq_file *s, void *_) | |||
2378 | 2382 | ||
2379 | static int proc_udc_open(struct inode *inode, struct file *file) | 2383 | static int proc_udc_open(struct inode *inode, struct file *file) |
2380 | { | 2384 | { |
2381 | return single_open(file, proc_udc_show, 0); | 2385 | return single_open(file, proc_udc_show, NULL); |
2382 | } | 2386 | } |
2383 | 2387 | ||
2384 | static struct file_operations proc_ops = { | 2388 | static struct file_operations proc_ops = { |
@@ -2399,7 +2403,7 @@ static void create_proc_file(void) | |||
2399 | 2403 | ||
2400 | static void remove_proc_file(void) | 2404 | static void remove_proc_file(void) |
2401 | { | 2405 | { |
2402 | remove_proc_entry(proc_filename, 0); | 2406 | remove_proc_entry(proc_filename, NULL); |
2403 | } | 2407 | } |
2404 | 2408 | ||
2405 | #else | 2409 | #else |
@@ -2505,7 +2509,7 @@ static void omap_udc_release(struct device *dev) | |||
2505 | { | 2509 | { |
2506 | complete(udc->done); | 2510 | complete(udc->done); |
2507 | kfree (udc); | 2511 | kfree (udc); |
2508 | udc = 0; | 2512 | udc = NULL; |
2509 | } | 2513 | } |
2510 | 2514 | ||
2511 | static int __init | 2515 | static int __init |
@@ -2577,23 +2581,33 @@ omap_udc_setup(struct platform_device *odev, struct otg_transceiver *xceiv) | |||
2577 | case 1: | 2581 | case 1: |
2578 | OMAP_BULK_EP("ep1in", USB_DIR_IN | 1); | 2582 | OMAP_BULK_EP("ep1in", USB_DIR_IN | 1); |
2579 | OMAP_BULK_EP("ep2out", USB_DIR_OUT | 2); | 2583 | OMAP_BULK_EP("ep2out", USB_DIR_OUT | 2); |
2584 | OMAP_INT_EP("ep9in", USB_DIR_IN | 9, 16); | ||
2585 | |||
2580 | OMAP_BULK_EP("ep3in", USB_DIR_IN | 3); | 2586 | OMAP_BULK_EP("ep3in", USB_DIR_IN | 3); |
2581 | OMAP_BULK_EP("ep4out", USB_DIR_OUT | 4); | 2587 | OMAP_BULK_EP("ep4out", USB_DIR_OUT | 4); |
2588 | OMAP_INT_EP("ep10in", USB_DIR_IN | 10, 16); | ||
2582 | 2589 | ||
2583 | OMAP_BULK_EP("ep5in", USB_DIR_IN | 5); | 2590 | OMAP_BULK_EP("ep5in", USB_DIR_IN | 5); |
2584 | OMAP_BULK_EP("ep5out", USB_DIR_OUT | 5); | 2591 | OMAP_BULK_EP("ep5out", USB_DIR_OUT | 5); |
2592 | OMAP_INT_EP("ep11in", USB_DIR_IN | 11, 16); | ||
2593 | |||
2585 | OMAP_BULK_EP("ep6in", USB_DIR_IN | 6); | 2594 | OMAP_BULK_EP("ep6in", USB_DIR_IN | 6); |
2586 | OMAP_BULK_EP("ep6out", USB_DIR_OUT | 6); | 2595 | OMAP_BULK_EP("ep6out", USB_DIR_OUT | 6); |
2596 | OMAP_INT_EP("ep12in", USB_DIR_IN | 12, 16); | ||
2587 | 2597 | ||
2588 | OMAP_BULK_EP("ep7in", USB_DIR_IN | 7); | 2598 | OMAP_BULK_EP("ep7in", USB_DIR_IN | 7); |
2589 | OMAP_BULK_EP("ep7out", USB_DIR_OUT | 7); | 2599 | OMAP_BULK_EP("ep7out", USB_DIR_OUT | 7); |
2600 | OMAP_INT_EP("ep13in", USB_DIR_IN | 13, 16); | ||
2601 | OMAP_INT_EP("ep13out", USB_DIR_OUT | 13, 16); | ||
2602 | |||
2590 | OMAP_BULK_EP("ep8in", USB_DIR_IN | 8); | 2603 | OMAP_BULK_EP("ep8in", USB_DIR_IN | 8); |
2591 | OMAP_BULK_EP("ep8out", USB_DIR_OUT | 8); | 2604 | OMAP_BULK_EP("ep8out", USB_DIR_OUT | 8); |
2605 | OMAP_INT_EP("ep14in", USB_DIR_IN | 14, 16); | ||
2606 | OMAP_INT_EP("ep14out", USB_DIR_OUT | 14, 16); | ||
2607 | |||
2608 | OMAP_BULK_EP("ep15in", USB_DIR_IN | 15); | ||
2609 | OMAP_BULK_EP("ep15out", USB_DIR_OUT | 15); | ||
2592 | 2610 | ||
2593 | OMAP_INT_EP("ep9in", USB_DIR_IN | 9, 16); | ||
2594 | OMAP_INT_EP("ep10out", USB_DIR_IN | 10, 16); | ||
2595 | OMAP_INT_EP("ep11in", USB_DIR_IN | 9, 16); | ||
2596 | OMAP_INT_EP("ep12out", USB_DIR_IN | 10, 16); | ||
2597 | break; | 2611 | break; |
2598 | 2612 | ||
2599 | #ifdef USE_ISO | 2613 | #ifdef USE_ISO |
@@ -2640,8 +2654,8 @@ static int __init omap_udc_probe(struct device *dev) | |||
2640 | struct platform_device *odev = to_platform_device(dev); | 2654 | struct platform_device *odev = to_platform_device(dev); |
2641 | int status = -ENODEV; | 2655 | int status = -ENODEV; |
2642 | int hmc; | 2656 | int hmc; |
2643 | struct otg_transceiver *xceiv = 0; | 2657 | struct otg_transceiver *xceiv = NULL; |
2644 | const char *type = 0; | 2658 | const char *type = NULL; |
2645 | struct omap_usb_config *config = dev->platform_data; | 2659 | struct omap_usb_config *config = dev->platform_data; |
2646 | 2660 | ||
2647 | /* NOTE: "knows" the order of the resources! */ | 2661 | /* NOTE: "knows" the order of the resources! */ |
@@ -2678,6 +2692,15 @@ static int __init omap_udc_probe(struct device *dev) | |||
2678 | } else { | 2692 | } else { |
2679 | hmc = HMC_1610; | 2693 | hmc = HMC_1610; |
2680 | switch (hmc) { | 2694 | switch (hmc) { |
2695 | case 0: /* POWERUP DEFAULT == 0 */ | ||
2696 | case 4: | ||
2697 | case 12: | ||
2698 | case 20: | ||
2699 | if (!cpu_is_omap1710()) { | ||
2700 | type = "integrated"; | ||
2701 | break; | ||
2702 | } | ||
2703 | /* FALL THROUGH */ | ||
2681 | case 3: | 2704 | case 3: |
2682 | case 11: | 2705 | case 11: |
2683 | case 16: | 2706 | case 16: |
@@ -2688,21 +2711,15 @@ static int __init omap_udc_probe(struct device *dev) | |||
2688 | DBG("external transceiver not registered!\n"); | 2711 | DBG("external transceiver not registered!\n"); |
2689 | if (config->otg) | 2712 | if (config->otg) |
2690 | goto cleanup0; | 2713 | goto cleanup0; |
2691 | type = "(unknown external)"; | 2714 | type = "unknown"; |
2692 | } else | 2715 | } else |
2693 | type = xceiv->label; | 2716 | type = xceiv->label; |
2694 | break; | 2717 | break; |
2695 | case 0: /* POWERUP DEFAULT == 0 */ | ||
2696 | case 4: | ||
2697 | case 12: | ||
2698 | case 20: | ||
2699 | type = "INTEGRATED"; | ||
2700 | break; | ||
2701 | case 21: /* internal loopback */ | 2718 | case 21: /* internal loopback */ |
2702 | type = "(loopback)"; | 2719 | type = "loopback"; |
2703 | break; | 2720 | break; |
2704 | case 14: /* transceiverless */ | 2721 | case 14: /* transceiverless */ |
2705 | type = "(none)"; | 2722 | type = "no"; |
2706 | break; | 2723 | break; |
2707 | 2724 | ||
2708 | default: | 2725 | default: |
@@ -2710,14 +2727,14 @@ static int __init omap_udc_probe(struct device *dev) | |||
2710 | return -ENODEV; | 2727 | return -ENODEV; |
2711 | } | 2728 | } |
2712 | } | 2729 | } |
2713 | INFO("hmc mode %d, transceiver %s\n", hmc, type); | 2730 | INFO("hmc mode %d, %s transceiver\n", hmc, type); |
2714 | 2731 | ||
2715 | /* a "gadget" abstracts/virtualizes the controller */ | 2732 | /* a "gadget" abstracts/virtualizes the controller */ |
2716 | status = omap_udc_setup(odev, xceiv); | 2733 | status = omap_udc_setup(odev, xceiv); |
2717 | if (status) { | 2734 | if (status) { |
2718 | goto cleanup0; | 2735 | goto cleanup0; |
2719 | } | 2736 | } |
2720 | xceiv = 0; | 2737 | xceiv = NULL; |
2721 | // "udc" is now valid | 2738 | // "udc" is now valid |
2722 | pullup_disable(udc); | 2739 | pullup_disable(udc); |
2723 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | 2740 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) |
@@ -2765,7 +2782,7 @@ cleanup2: | |||
2765 | 2782 | ||
2766 | cleanup1: | 2783 | cleanup1: |
2767 | kfree (udc); | 2784 | kfree (udc); |
2768 | udc = 0; | 2785 | udc = NULL; |
2769 | 2786 | ||
2770 | cleanup0: | 2787 | cleanup0: |
2771 | if (xceiv) | 2788 | if (xceiv) |
@@ -2788,7 +2805,7 @@ static int __exit omap_udc_remove(struct device *dev) | |||
2788 | pullup_disable(udc); | 2805 | pullup_disable(udc); |
2789 | if (udc->transceiver) { | 2806 | if (udc->transceiver) { |
2790 | put_device(udc->transceiver->dev); | 2807 | put_device(udc->transceiver->dev); |
2791 | udc->transceiver = 0; | 2808 | udc->transceiver = NULL; |
2792 | } | 2809 | } |
2793 | UDC_SYSCON1_REG = 0; | 2810 | UDC_SYSCON1_REG = 0; |
2794 | 2811 | ||
@@ -2809,13 +2826,32 @@ static int __exit omap_udc_remove(struct device *dev) | |||
2809 | return 0; | 2826 | return 0; |
2810 | } | 2827 | } |
2811 | 2828 | ||
2812 | static int omap_udc_suspend(struct device *dev, pm_message_t state, u32 level) | 2829 | /* suspend/resume/wakeup from sysfs (echo > power/state) or when the |
2830 | * system is forced into deep sleep | ||
2831 | * | ||
2832 | * REVISIT we should probably reject suspend requests when there's a host | ||
2833 | * session active, rather than disconnecting, at least on boards that can | ||
2834 | * report VBUS irqs (UDC_DEVSTAT_REG.UDC_ATT). And in any case, we need to | ||
2835 | * make host resumes and VBUS detection trigger OMAP wakeup events; that | ||
2836 | * may involve talking to an external transceiver (e.g. isp1301). | ||
2837 | */ | ||
2838 | static int omap_udc_suspend(struct device *dev, pm_message_t message, u32 level) | ||
2813 | { | 2839 | { |
2814 | if (level != 0) | 2840 | u32 devstat; |
2841 | |||
2842 | if (level != SUSPEND_POWER_DOWN) | ||
2815 | return 0; | 2843 | return 0; |
2844 | devstat = UDC_DEVSTAT_REG; | ||
2845 | |||
2846 | /* we're requesting 48 MHz clock if the pullup is enabled | ||
2847 | * (== we're attached to the host) and we're not suspended, | ||
2848 | * which would prevent entry to deep sleep... | ||
2849 | */ | ||
2850 | if ((devstat & UDC_ATT) != 0 && (devstat & UDC_SUS) == 0) { | ||
2851 | WARN("session active; suspend requires disconnect\n"); | ||
2852 | omap_pullup(&udc->gadget, 0); | ||
2853 | } | ||
2816 | 2854 | ||
2817 | DBG("suspend, state %d\n", state); | ||
2818 | omap_pullup(&udc->gadget, 0); | ||
2819 | udc->gadget.dev.power.power_state = PMSG_SUSPEND; | 2855 | udc->gadget.dev.power.power_state = PMSG_SUSPEND; |
2820 | udc->gadget.dev.parent->power.power_state = PMSG_SUSPEND; | 2856 | udc->gadget.dev.parent->power.power_state = PMSG_SUSPEND; |
2821 | return 0; | 2857 | return 0; |
@@ -2823,7 +2859,7 @@ static int omap_udc_suspend(struct device *dev, pm_message_t state, u32 level) | |||
2823 | 2859 | ||
2824 | static int omap_udc_resume(struct device *dev, u32 level) | 2860 | static int omap_udc_resume(struct device *dev, u32 level) |
2825 | { | 2861 | { |
2826 | if (level != 0) | 2862 | if (level != RESUME_POWER_ON) |
2827 | return 0; | 2863 | return 0; |
2828 | 2864 | ||
2829 | DBG("resume + wakeup/SRP\n"); | 2865 | DBG("resume + wakeup/SRP\n"); |