diff options
author | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-21 03:01:06 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-21 03:01:06 -0500 |
commit | fb34d203d0b5ac1b8284973eb0db3fdff101fc5e (patch) | |
tree | d882cb10f1bb69f0058881df5dad6bd433cd28e5 /drivers/usb/gadget | |
parent | 5576d187a0eef3bb3c47500eaab33fb5485bc352 (diff) | |
parent | c3052905033f8785bcb2c71d5ce40b84259e3a80 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6: (34 commits)
USB Storage: remove duplicate Nokia entry in unusual_devs.h
[PATCH] bluetooth: add support for another Kensington dongle
[PATCH] usb serial: add support for Novatel S720/U720 CDMA/EV-DO modems
[PATCH] USB: Nokia E70 is an unusual device
USB: fix to usbfs_snoop logging of user defined control urbs
USB: at91_udc: Additional checks
USB: at91_udc: Cleanup variables after failure in usb_gadget_register_driver()
USB: at91_udc: allow drivers that support high speed
USB: u132-hcd/ftdi-elan: add support for Option GT 3G Quad card
USB: at91_udc, misc fixes
USB: at91 udc, support at91sam926x addresses
USB: OHCI support for PNX8550
USB: ohci handles hardware faults during root port resets
USB: ohci at91 warning fix
USB: ohci whitespace/comment fixups
USB: MAINTAINERS update, EHCI and OHCI
USB: gadget driver unbind() is optional; section fixes; misc
UHCI: module parameter to ignore overcurrent changes
USB: Nokia E70 is an unusual device
USB AUERSWALD: replace kmalloc+memset with kzalloc
...
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r-- | drivers/usb/gadget/at91_udc.c | 236 | ||||
-rw-r--r-- | drivers/usb/gadget/at91_udc.h | 7 | ||||
-rw-r--r-- | drivers/usb/gadget/dummy_hcd.c | 7 | ||||
-rw-r--r-- | drivers/usb/gadget/file_storage.c | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/gmidi.c | 12 | ||||
-rw-r--r-- | drivers/usb/gadget/goku_udc.c | 12 | ||||
-rw-r--r-- | drivers/usb/gadget/lh7a40x_udc.c | 13 | ||||
-rw-r--r-- | drivers/usb/gadget/net2280.c | 11 | ||||
-rw-r--r-- | drivers/usb/gadget/omap_udc.c | 13 | ||||
-rw-r--r-- | drivers/usb/gadget/pxa2xx_udc.c | 7 | ||||
-rw-r--r-- | drivers/usb/gadget/serial.c | 2 |
11 files changed, 180 insertions, 142 deletions
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 3e0abbb49fe1..812c733ba8ce 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c | |||
@@ -43,14 +43,16 @@ | |||
43 | #include <linux/usb_gadget.h> | 43 | #include <linux/usb_gadget.h> |
44 | 44 | ||
45 | #include <asm/byteorder.h> | 45 | #include <asm/byteorder.h> |
46 | #include <asm/hardware.h> | ||
46 | #include <asm/io.h> | 47 | #include <asm/io.h> |
47 | #include <asm/irq.h> | 48 | #include <asm/irq.h> |
48 | #include <asm/system.h> | 49 | #include <asm/system.h> |
49 | #include <asm/mach-types.h> | 50 | #include <asm/mach-types.h> |
50 | 51 | ||
51 | #include <asm/arch/hardware.h> | ||
52 | #include <asm/arch/gpio.h> | 52 | #include <asm/arch/gpio.h> |
53 | #include <asm/arch/board.h> | 53 | #include <asm/arch/board.h> |
54 | #include <asm/arch/cpu.h> | ||
55 | #include <asm/arch/at91sam9261_matrix.h> | ||
54 | 56 | ||
55 | #include "at91_udc.h" | 57 | #include "at91_udc.h" |
56 | 58 | ||
@@ -78,27 +80,11 @@ | |||
78 | static const char driver_name [] = "at91_udc"; | 80 | static const char driver_name [] = "at91_udc"; |
79 | static const char ep0name[] = "ep0"; | 81 | static const char ep0name[] = "ep0"; |
80 | 82 | ||
81 | /*-------------------------------------------------------------------------*/ | ||
82 | 83 | ||
83 | /* | 84 | #define at91_udp_read(dev, reg) \ |
84 | * Read from a UDP register. | 85 | __raw_readl((dev)->udp_baseaddr + (reg)) |
85 | */ | 86 | #define at91_udp_write(dev, reg, val) \ |
86 | static inline unsigned long at91_udp_read(unsigned int reg) | 87 | __raw_writel((val), (dev)->udp_baseaddr + (reg)) |
87 | { | ||
88 | void __iomem *udp_base = (void __iomem *)AT91_VA_BASE_UDP; | ||
89 | |||
90 | return __raw_readl(udp_base + reg); | ||
91 | } | ||
92 | |||
93 | /* | ||
94 | * Write to a UDP register. | ||
95 | */ | ||
96 | static inline void at91_udp_write(unsigned int reg, unsigned long value) | ||
97 | { | ||
98 | void __iomem *udp_base = (void __iomem *)AT91_VA_BASE_UDP; | ||
99 | |||
100 | __raw_writel(value, udp_base + reg); | ||
101 | } | ||
102 | 88 | ||
103 | /*-------------------------------------------------------------------------*/ | 89 | /*-------------------------------------------------------------------------*/ |
104 | 90 | ||
@@ -210,13 +196,13 @@ static int proc_udc_show(struct seq_file *s, void *unused) | |||
210 | return 0; | 196 | return 0; |
211 | } | 197 | } |
212 | 198 | ||
213 | tmp = at91_udp_read(AT91_UDP_FRM_NUM); | 199 | tmp = at91_udp_read(udc, AT91_UDP_FRM_NUM); |
214 | seq_printf(s, "frame %05x:%s%s frame=%d\n", tmp, | 200 | seq_printf(s, "frame %05x:%s%s frame=%d\n", tmp, |
215 | (tmp & AT91_UDP_FRM_OK) ? " ok" : "", | 201 | (tmp & AT91_UDP_FRM_OK) ? " ok" : "", |
216 | (tmp & AT91_UDP_FRM_ERR) ? " err" : "", | 202 | (tmp & AT91_UDP_FRM_ERR) ? " err" : "", |
217 | (tmp & AT91_UDP_NUM)); | 203 | (tmp & AT91_UDP_NUM)); |
218 | 204 | ||
219 | tmp = at91_udp_read(AT91_UDP_GLB_STAT); | 205 | tmp = at91_udp_read(udc, AT91_UDP_GLB_STAT); |
220 | seq_printf(s, "glbstate %02x:%s" FOURBITS "\n", tmp, | 206 | seq_printf(s, "glbstate %02x:%s" FOURBITS "\n", tmp, |
221 | (tmp & AT91_UDP_RMWUPE) ? " rmwupe" : "", | 207 | (tmp & AT91_UDP_RMWUPE) ? " rmwupe" : "", |
222 | (tmp & AT91_UDP_RSMINPR) ? " rsminpr" : "", | 208 | (tmp & AT91_UDP_RSMINPR) ? " rsminpr" : "", |
@@ -224,13 +210,13 @@ static int proc_udc_show(struct seq_file *s, void *unused) | |||
224 | (tmp & AT91_UDP_CONFG) ? " confg" : "", | 210 | (tmp & AT91_UDP_CONFG) ? " confg" : "", |
225 | (tmp & AT91_UDP_FADDEN) ? " fadden" : ""); | 211 | (tmp & AT91_UDP_FADDEN) ? " fadden" : ""); |
226 | 212 | ||
227 | tmp = at91_udp_read(AT91_UDP_FADDR); | 213 | tmp = at91_udp_read(udc, AT91_UDP_FADDR); |
228 | seq_printf(s, "faddr %03x:%s fadd=%d\n", tmp, | 214 | seq_printf(s, "faddr %03x:%s fadd=%d\n", tmp, |
229 | (tmp & AT91_UDP_FEN) ? " fen" : "", | 215 | (tmp & AT91_UDP_FEN) ? " fen" : "", |
230 | (tmp & AT91_UDP_FADD)); | 216 | (tmp & AT91_UDP_FADD)); |
231 | 217 | ||
232 | proc_irq_show(s, "imr ", at91_udp_read(AT91_UDP_IMR)); | 218 | proc_irq_show(s, "imr ", at91_udp_read(udc, AT91_UDP_IMR)); |
233 | proc_irq_show(s, "isr ", at91_udp_read(AT91_UDP_ISR)); | 219 | proc_irq_show(s, "isr ", at91_udp_read(udc, AT91_UDP_ISR)); |
234 | 220 | ||
235 | if (udc->enabled && udc->vbus) { | 221 | if (udc->enabled && udc->vbus) { |
236 | proc_ep_show(s, &udc->ep[0]); | 222 | proc_ep_show(s, &udc->ep[0]); |
@@ -286,6 +272,7 @@ static inline void remove_debug_file(struct at91_udc *udc) {} | |||
286 | static void done(struct at91_ep *ep, struct at91_request *req, int status) | 272 | static void done(struct at91_ep *ep, struct at91_request *req, int status) |
287 | { | 273 | { |
288 | unsigned stopped = ep->stopped; | 274 | unsigned stopped = ep->stopped; |
275 | struct at91_udc *udc = ep->udc; | ||
289 | 276 | ||
290 | list_del_init(&req->queue); | 277 | list_del_init(&req->queue); |
291 | if (req->req.status == -EINPROGRESS) | 278 | if (req->req.status == -EINPROGRESS) |
@@ -301,7 +288,7 @@ static void done(struct at91_ep *ep, struct at91_request *req, int status) | |||
301 | 288 | ||
302 | /* ep0 is always ready; other endpoints need a non-empty queue */ | 289 | /* ep0 is always ready; other endpoints need a non-empty queue */ |
303 | if (list_empty(&ep->queue) && ep->int_mask != (1 << 0)) | 290 | if (list_empty(&ep->queue) && ep->int_mask != (1 << 0)) |
304 | at91_udp_write(AT91_UDP_IDR, ep->int_mask); | 291 | at91_udp_write(udc, AT91_UDP_IDR, ep->int_mask); |
305 | } | 292 | } |
306 | 293 | ||
307 | /*-------------------------------------------------------------------------*/ | 294 | /*-------------------------------------------------------------------------*/ |
@@ -554,8 +541,8 @@ ok: | |||
554 | * reset/init endpoint fifo. NOTE: leaves fifo_bank alone, | 541 | * reset/init endpoint fifo. NOTE: leaves fifo_bank alone, |
555 | * since endpoint resets don't reset hw pingpong state. | 542 | * since endpoint resets don't reset hw pingpong state. |
556 | */ | 543 | */ |
557 | at91_udp_write(AT91_UDP_RST_EP, ep->int_mask); | 544 | at91_udp_write(dev, AT91_UDP_RST_EP, ep->int_mask); |
558 | at91_udp_write(AT91_UDP_RST_EP, 0); | 545 | at91_udp_write(dev, AT91_UDP_RST_EP, 0); |
559 | 546 | ||
560 | local_irq_restore(flags); | 547 | local_irq_restore(flags); |
561 | return 0; | 548 | return 0; |
@@ -564,6 +551,7 @@ ok: | |||
564 | static int at91_ep_disable (struct usb_ep * _ep) | 551 | static int at91_ep_disable (struct usb_ep * _ep) |
565 | { | 552 | { |
566 | struct at91_ep *ep = container_of(_ep, struct at91_ep, ep); | 553 | struct at91_ep *ep = container_of(_ep, struct at91_ep, ep); |
554 | struct at91_udc *udc = ep->udc; | ||
567 | unsigned long flags; | 555 | unsigned long flags; |
568 | 556 | ||
569 | if (ep == &ep->udc->ep[0]) | 557 | if (ep == &ep->udc->ep[0]) |
@@ -579,8 +567,8 @@ static int at91_ep_disable (struct usb_ep * _ep) | |||
579 | 567 | ||
580 | /* reset fifos and endpoint */ | 568 | /* reset fifos and endpoint */ |
581 | if (ep->udc->clocked) { | 569 | if (ep->udc->clocked) { |
582 | at91_udp_write(AT91_UDP_RST_EP, ep->int_mask); | 570 | at91_udp_write(udc, AT91_UDP_RST_EP, ep->int_mask); |
583 | at91_udp_write(AT91_UDP_RST_EP, 0); | 571 | at91_udp_write(udc, AT91_UDP_RST_EP, 0); |
584 | __raw_writel(0, ep->creg); | 572 | __raw_writel(0, ep->creg); |
585 | } | 573 | } |
586 | 574 | ||
@@ -695,10 +683,10 @@ static int at91_ep_queue(struct usb_ep *_ep, | |||
695 | * reconfigures the endpoints. | 683 | * reconfigures the endpoints. |
696 | */ | 684 | */ |
697 | if (dev->wait_for_config_ack) { | 685 | if (dev->wait_for_config_ack) { |
698 | tmp = at91_udp_read(AT91_UDP_GLB_STAT); | 686 | tmp = at91_udp_read(dev, AT91_UDP_GLB_STAT); |
699 | tmp ^= AT91_UDP_CONFG; | 687 | tmp ^= AT91_UDP_CONFG; |
700 | VDBG("toggle config\n"); | 688 | VDBG("toggle config\n"); |
701 | at91_udp_write(AT91_UDP_GLB_STAT, tmp); | 689 | at91_udp_write(dev, AT91_UDP_GLB_STAT, tmp); |
702 | } | 690 | } |
703 | if (req->req.length == 0) { | 691 | if (req->req.length == 0) { |
704 | ep0_in_status: | 692 | ep0_in_status: |
@@ -727,7 +715,7 @@ ep0_in_status: | |||
727 | 715 | ||
728 | if (req && !status) { | 716 | if (req && !status) { |
729 | list_add_tail (&req->queue, &ep->queue); | 717 | list_add_tail (&req->queue, &ep->queue); |
730 | at91_udp_write(AT91_UDP_IER, ep->int_mask); | 718 | at91_udp_write(dev, AT91_UDP_IER, ep->int_mask); |
731 | } | 719 | } |
732 | done: | 720 | done: |
733 | local_irq_restore(flags); | 721 | local_irq_restore(flags); |
@@ -758,6 +746,7 @@ static int at91_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) | |||
758 | static int at91_ep_set_halt(struct usb_ep *_ep, int value) | 746 | static int at91_ep_set_halt(struct usb_ep *_ep, int value) |
759 | { | 747 | { |
760 | struct at91_ep *ep = container_of(_ep, struct at91_ep, ep); | 748 | struct at91_ep *ep = container_of(_ep, struct at91_ep, ep); |
749 | struct at91_udc *udc = ep->udc; | ||
761 | u32 __iomem *creg; | 750 | u32 __iomem *creg; |
762 | u32 csr; | 751 | u32 csr; |
763 | unsigned long flags; | 752 | unsigned long flags; |
@@ -785,8 +774,8 @@ static int at91_ep_set_halt(struct usb_ep *_ep, int value) | |||
785 | csr |= AT91_UDP_FORCESTALL; | 774 | csr |= AT91_UDP_FORCESTALL; |
786 | VDBG("halt %s\n", ep->ep.name); | 775 | VDBG("halt %s\n", ep->ep.name); |
787 | } else { | 776 | } else { |
788 | at91_udp_write(AT91_UDP_RST_EP, ep->int_mask); | 777 | at91_udp_write(udc, AT91_UDP_RST_EP, ep->int_mask); |
789 | at91_udp_write(AT91_UDP_RST_EP, 0); | 778 | at91_udp_write(udc, AT91_UDP_RST_EP, 0); |
790 | csr &= ~AT91_UDP_FORCESTALL; | 779 | csr &= ~AT91_UDP_FORCESTALL; |
791 | } | 780 | } |
792 | __raw_writel(csr, creg); | 781 | __raw_writel(csr, creg); |
@@ -813,9 +802,11 @@ static struct usb_ep_ops at91_ep_ops = { | |||
813 | 802 | ||
814 | static int at91_get_frame(struct usb_gadget *gadget) | 803 | static int at91_get_frame(struct usb_gadget *gadget) |
815 | { | 804 | { |
805 | struct at91_udc *udc = to_udc(gadget); | ||
806 | |||
816 | if (!to_udc(gadget)->clocked) | 807 | if (!to_udc(gadget)->clocked) |
817 | return -EINVAL; | 808 | return -EINVAL; |
818 | return at91_udp_read(AT91_UDP_FRM_NUM) & AT91_UDP_NUM; | 809 | return at91_udp_read(udc, AT91_UDP_FRM_NUM) & AT91_UDP_NUM; |
819 | } | 810 | } |
820 | 811 | ||
821 | static int at91_wakeup(struct usb_gadget *gadget) | 812 | static int at91_wakeup(struct usb_gadget *gadget) |
@@ -833,11 +824,11 @@ static int at91_wakeup(struct usb_gadget *gadget) | |||
833 | 824 | ||
834 | /* NOTE: some "early versions" handle ESR differently ... */ | 825 | /* NOTE: some "early versions" handle ESR differently ... */ |
835 | 826 | ||
836 | glbstate = at91_udp_read(AT91_UDP_GLB_STAT); | 827 | glbstate = at91_udp_read(udc, AT91_UDP_GLB_STAT); |
837 | if (!(glbstate & AT91_UDP_ESR)) | 828 | if (!(glbstate & AT91_UDP_ESR)) |
838 | goto done; | 829 | goto done; |
839 | glbstate |= AT91_UDP_ESR; | 830 | glbstate |= AT91_UDP_ESR; |
840 | at91_udp_write(AT91_UDP_GLB_STAT, glbstate); | 831 | at91_udp_write(udc, AT91_UDP_GLB_STAT, glbstate); |
841 | 832 | ||
842 | done: | 833 | done: |
843 | local_irq_restore(flags); | 834 | local_irq_restore(flags); |
@@ -861,6 +852,7 @@ static void udc_reinit(struct at91_udc *udc) | |||
861 | ep->stopped = 0; | 852 | ep->stopped = 0; |
862 | ep->fifo_bank = 0; | 853 | ep->fifo_bank = 0; |
863 | ep->ep.maxpacket = ep->maxpacket; | 854 | ep->ep.maxpacket = ep->maxpacket; |
855 | ep->creg = (void __iomem *) udc->udp_baseaddr + AT91_UDP_CSR(i); | ||
864 | // initialiser une queue par endpoint | 856 | // initialiser une queue par endpoint |
865 | INIT_LIST_HEAD(&ep->queue); | 857 | INIT_LIST_HEAD(&ep->queue); |
866 | } | 858 | } |
@@ -915,14 +907,41 @@ static void pullup(struct at91_udc *udc, int is_on) | |||
915 | if (!udc->enabled || !udc->vbus) | 907 | if (!udc->enabled || !udc->vbus) |
916 | is_on = 0; | 908 | is_on = 0; |
917 | DBG("%sactive\n", is_on ? "" : "in"); | 909 | DBG("%sactive\n", is_on ? "" : "in"); |
910 | |||
918 | if (is_on) { | 911 | if (is_on) { |
919 | clk_on(udc); | 912 | clk_on(udc); |
920 | at91_udp_write(AT91_UDP_TXVC, 0); | 913 | at91_udp_write(udc, AT91_UDP_TXVC, 0); |
921 | at91_set_gpio_value(udc->board.pullup_pin, 1); | 914 | if (cpu_is_at91rm9200()) |
922 | } else { | 915 | at91_set_gpio_value(udc->board.pullup_pin, 1); |
916 | else if (cpu_is_at91sam9260()) { | ||
917 | u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC); | ||
918 | |||
919 | txvc |= AT91_UDP_TXVC_PUON; | ||
920 | at91_udp_write(udc, AT91_UDP_TXVC, txvc); | ||
921 | } else if (cpu_is_at91sam9261()) { | ||
922 | u32 usbpucr; | ||
923 | |||
924 | usbpucr = at91_sys_read(AT91_MATRIX_USBPUCR); | ||
925 | usbpucr |= AT91_MATRIX_USBPUCR_PUON; | ||
926 | at91_sys_write(AT91_MATRIX_USBPUCR, usbpucr); | ||
927 | } | ||
928 | } else { | ||
923 | stop_activity(udc); | 929 | stop_activity(udc); |
924 | at91_udp_write(AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); | 930 | at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); |
925 | at91_set_gpio_value(udc->board.pullup_pin, 0); | 931 | if (cpu_is_at91rm9200()) |
932 | at91_set_gpio_value(udc->board.pullup_pin, 0); | ||
933 | else if (cpu_is_at91sam9260()) { | ||
934 | u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC); | ||
935 | |||
936 | txvc &= ~AT91_UDP_TXVC_PUON; | ||
937 | at91_udp_write(udc, AT91_UDP_TXVC, txvc); | ||
938 | } else if (cpu_is_at91sam9261()) { | ||
939 | u32 usbpucr; | ||
940 | |||
941 | usbpucr = at91_sys_read(AT91_MATRIX_USBPUCR); | ||
942 | usbpucr &= ~AT91_MATRIX_USBPUCR_PUON; | ||
943 | at91_sys_write(AT91_MATRIX_USBPUCR, usbpucr); | ||
944 | } | ||
926 | clk_off(udc); | 945 | clk_off(udc); |
927 | } | 946 | } |
928 | } | 947 | } |
@@ -936,7 +955,10 @@ static int at91_vbus_session(struct usb_gadget *gadget, int is_active) | |||
936 | // VDBG("vbus %s\n", is_active ? "on" : "off"); | 955 | // VDBG("vbus %s\n", is_active ? "on" : "off"); |
937 | local_irq_save(flags); | 956 | local_irq_save(flags); |
938 | udc->vbus = (is_active != 0); | 957 | udc->vbus = (is_active != 0); |
939 | pullup(udc, is_active); | 958 | if (udc->driver) |
959 | pullup(udc, is_active); | ||
960 | else | ||
961 | pullup(udc, 0); | ||
940 | local_irq_restore(flags); | 962 | local_irq_restore(flags); |
941 | return 0; | 963 | return 0; |
942 | } | 964 | } |
@@ -1086,7 +1108,7 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr) | |||
1086 | 1108 | ||
1087 | case ((USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8) | 1109 | case ((USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8) |
1088 | | USB_REQ_SET_CONFIGURATION: | 1110 | | USB_REQ_SET_CONFIGURATION: |
1089 | tmp = at91_udp_read(AT91_UDP_GLB_STAT) & AT91_UDP_CONFG; | 1111 | tmp = at91_udp_read(udc, AT91_UDP_GLB_STAT) & AT91_UDP_CONFG; |
1090 | if (pkt.r.wValue) | 1112 | if (pkt.r.wValue) |
1091 | udc->wait_for_config_ack = (tmp == 0); | 1113 | udc->wait_for_config_ack = (tmp == 0); |
1092 | else | 1114 | else |
@@ -1103,7 +1125,7 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr) | |||
1103 | case ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8) | 1125 | case ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8) |
1104 | | USB_REQ_GET_STATUS: | 1126 | | USB_REQ_GET_STATUS: |
1105 | tmp = (udc->selfpowered << USB_DEVICE_SELF_POWERED); | 1127 | tmp = (udc->selfpowered << USB_DEVICE_SELF_POWERED); |
1106 | if (at91_udp_read(AT91_UDP_GLB_STAT) & AT91_UDP_ESR) | 1128 | if (at91_udp_read(udc, AT91_UDP_GLB_STAT) & AT91_UDP_ESR) |
1107 | tmp |= (1 << USB_DEVICE_REMOTE_WAKEUP); | 1129 | tmp |= (1 << USB_DEVICE_REMOTE_WAKEUP); |
1108 | PACKET("get device status\n"); | 1130 | PACKET("get device status\n"); |
1109 | __raw_writeb(tmp, dreg); | 1131 | __raw_writeb(tmp, dreg); |
@@ -1114,17 +1136,17 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr) | |||
1114 | | USB_REQ_SET_FEATURE: | 1136 | | USB_REQ_SET_FEATURE: |
1115 | if (w_value != USB_DEVICE_REMOTE_WAKEUP) | 1137 | if (w_value != USB_DEVICE_REMOTE_WAKEUP) |
1116 | goto stall; | 1138 | goto stall; |
1117 | tmp = at91_udp_read(AT91_UDP_GLB_STAT); | 1139 | tmp = at91_udp_read(udc, AT91_UDP_GLB_STAT); |
1118 | tmp |= AT91_UDP_ESR; | 1140 | tmp |= AT91_UDP_ESR; |
1119 | at91_udp_write(AT91_UDP_GLB_STAT, tmp); | 1141 | at91_udp_write(udc, AT91_UDP_GLB_STAT, tmp); |
1120 | goto succeed; | 1142 | goto succeed; |
1121 | case ((USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8) | 1143 | case ((USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8) |
1122 | | USB_REQ_CLEAR_FEATURE: | 1144 | | USB_REQ_CLEAR_FEATURE: |
1123 | if (w_value != USB_DEVICE_REMOTE_WAKEUP) | 1145 | if (w_value != USB_DEVICE_REMOTE_WAKEUP) |
1124 | goto stall; | 1146 | goto stall; |
1125 | tmp = at91_udp_read(AT91_UDP_GLB_STAT); | 1147 | tmp = at91_udp_read(udc, AT91_UDP_GLB_STAT); |
1126 | tmp &= ~AT91_UDP_ESR; | 1148 | tmp &= ~AT91_UDP_ESR; |
1127 | at91_udp_write(AT91_UDP_GLB_STAT, tmp); | 1149 | at91_udp_write(udc, AT91_UDP_GLB_STAT, tmp); |
1128 | goto succeed; | 1150 | goto succeed; |
1129 | 1151 | ||
1130 | /* | 1152 | /* |
@@ -1206,8 +1228,8 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr) | |||
1206 | } else if (ep->is_in) | 1228 | } else if (ep->is_in) |
1207 | goto stall; | 1229 | goto stall; |
1208 | 1230 | ||
1209 | at91_udp_write(AT91_UDP_RST_EP, ep->int_mask); | 1231 | at91_udp_write(udc, AT91_UDP_RST_EP, ep->int_mask); |
1210 | at91_udp_write(AT91_UDP_RST_EP, 0); | 1232 | at91_udp_write(udc, AT91_UDP_RST_EP, 0); |
1211 | tmp = __raw_readl(ep->creg); | 1233 | tmp = __raw_readl(ep->creg); |
1212 | tmp |= CLR_FX; | 1234 | tmp |= CLR_FX; |
1213 | tmp &= ~(SET_FX | AT91_UDP_FORCESTALL); | 1235 | tmp &= ~(SET_FX | AT91_UDP_FORCESTALL); |
@@ -1222,7 +1244,10 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr) | |||
1222 | #undef w_length | 1244 | #undef w_length |
1223 | 1245 | ||
1224 | /* pass request up to the gadget driver */ | 1246 | /* pass request up to the gadget driver */ |
1225 | status = udc->driver->setup(&udc->gadget, &pkt.r); | 1247 | if (udc->driver) |
1248 | status = udc->driver->setup(&udc->gadget, &pkt.r); | ||
1249 | else | ||
1250 | status = -ENODEV; | ||
1226 | if (status < 0) { | 1251 | if (status < 0) { |
1227 | stall: | 1252 | stall: |
1228 | VDBG("req %02x.%02x protocol STALL; stat %d\n", | 1253 | VDBG("req %02x.%02x protocol STALL; stat %d\n", |
@@ -1300,13 +1325,13 @@ static void handle_ep0(struct at91_udc *udc) | |||
1300 | if (udc->wait_for_addr_ack) { | 1325 | if (udc->wait_for_addr_ack) { |
1301 | u32 tmp; | 1326 | u32 tmp; |
1302 | 1327 | ||
1303 | at91_udp_write(AT91_UDP_FADDR, | 1328 | at91_udp_write(udc, AT91_UDP_FADDR, |
1304 | AT91_UDP_FEN | udc->addr); | 1329 | AT91_UDP_FEN | udc->addr); |
1305 | tmp = at91_udp_read(AT91_UDP_GLB_STAT); | 1330 | tmp = at91_udp_read(udc, AT91_UDP_GLB_STAT); |
1306 | tmp &= ~AT91_UDP_FADDEN; | 1331 | tmp &= ~AT91_UDP_FADDEN; |
1307 | if (udc->addr) | 1332 | if (udc->addr) |
1308 | tmp |= AT91_UDP_FADDEN; | 1333 | tmp |= AT91_UDP_FADDEN; |
1309 | at91_udp_write(AT91_UDP_GLB_STAT, tmp); | 1334 | at91_udp_write(udc, AT91_UDP_GLB_STAT, tmp); |
1310 | 1335 | ||
1311 | udc->wait_for_addr_ack = 0; | 1336 | udc->wait_for_addr_ack = 0; |
1312 | VDBG("address %d\n", udc->addr); | 1337 | VDBG("address %d\n", udc->addr); |
@@ -1374,28 +1399,28 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc) | |||
1374 | while (rescans--) { | 1399 | while (rescans--) { |
1375 | u32 status; | 1400 | u32 status; |
1376 | 1401 | ||
1377 | status = at91_udp_read(AT91_UDP_ISR) | 1402 | status = at91_udp_read(udc, AT91_UDP_ISR) |
1378 | & at91_udp_read(AT91_UDP_IMR); | 1403 | & at91_udp_read(udc, AT91_UDP_IMR); |
1379 | if (!status) | 1404 | if (!status) |
1380 | break; | 1405 | break; |
1381 | 1406 | ||
1382 | /* USB reset irq: not maskable */ | 1407 | /* USB reset irq: not maskable */ |
1383 | if (status & AT91_UDP_ENDBUSRES) { | 1408 | if (status & AT91_UDP_ENDBUSRES) { |
1384 | at91_udp_write(AT91_UDP_IDR, ~MINIMUS_INTERRUPTUS); | 1409 | at91_udp_write(udc, AT91_UDP_IDR, ~MINIMUS_INTERRUPTUS); |
1385 | at91_udp_write(AT91_UDP_IER, MINIMUS_INTERRUPTUS); | 1410 | at91_udp_write(udc, AT91_UDP_IER, MINIMUS_INTERRUPTUS); |
1386 | /* Atmel code clears this irq twice */ | 1411 | /* Atmel code clears this irq twice */ |
1387 | at91_udp_write(AT91_UDP_ICR, AT91_UDP_ENDBUSRES); | 1412 | at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_ENDBUSRES); |
1388 | at91_udp_write(AT91_UDP_ICR, AT91_UDP_ENDBUSRES); | 1413 | at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_ENDBUSRES); |
1389 | VDBG("end bus reset\n"); | 1414 | VDBG("end bus reset\n"); |
1390 | udc->addr = 0; | 1415 | udc->addr = 0; |
1391 | stop_activity(udc); | 1416 | stop_activity(udc); |
1392 | 1417 | ||
1393 | /* enable ep0 */ | 1418 | /* enable ep0 */ |
1394 | at91_udp_write(AT91_UDP_CSR(0), | 1419 | at91_udp_write(udc, AT91_UDP_CSR(0), |
1395 | AT91_UDP_EPEDS | AT91_UDP_EPTYPE_CTRL); | 1420 | AT91_UDP_EPEDS | AT91_UDP_EPTYPE_CTRL); |
1396 | udc->gadget.speed = USB_SPEED_FULL; | 1421 | udc->gadget.speed = USB_SPEED_FULL; |
1397 | udc->suspended = 0; | 1422 | udc->suspended = 0; |
1398 | at91_udp_write(AT91_UDP_IER, AT91_UDP_EP(0)); | 1423 | at91_udp_write(udc, AT91_UDP_IER, AT91_UDP_EP(0)); |
1399 | 1424 | ||
1400 | /* | 1425 | /* |
1401 | * NOTE: this driver keeps clocks off unless the | 1426 | * NOTE: this driver keeps clocks off unless the |
@@ -1406,9 +1431,9 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc) | |||
1406 | 1431 | ||
1407 | /* host initiated suspend (3+ms bus idle) */ | 1432 | /* host initiated suspend (3+ms bus idle) */ |
1408 | } else if (status & AT91_UDP_RXSUSP) { | 1433 | } else if (status & AT91_UDP_RXSUSP) { |
1409 | at91_udp_write(AT91_UDP_IDR, AT91_UDP_RXSUSP); | 1434 | at91_udp_write(udc, AT91_UDP_IDR, AT91_UDP_RXSUSP); |
1410 | at91_udp_write(AT91_UDP_IER, AT91_UDP_RXRSM); | 1435 | at91_udp_write(udc, AT91_UDP_IER, AT91_UDP_RXRSM); |
1411 | at91_udp_write(AT91_UDP_ICR, AT91_UDP_RXSUSP); | 1436 | at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_RXSUSP); |
1412 | // VDBG("bus suspend\n"); | 1437 | // VDBG("bus suspend\n"); |
1413 | if (udc->suspended) | 1438 | if (udc->suspended) |
1414 | continue; | 1439 | continue; |
@@ -1425,9 +1450,9 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc) | |||
1425 | 1450 | ||
1426 | /* host initiated resume */ | 1451 | /* host initiated resume */ |
1427 | } else if (status & AT91_UDP_RXRSM) { | 1452 | } else if (status & AT91_UDP_RXRSM) { |
1428 | at91_udp_write(AT91_UDP_IDR, AT91_UDP_RXRSM); | 1453 | at91_udp_write(udc, AT91_UDP_IDR, AT91_UDP_RXRSM); |
1429 | at91_udp_write(AT91_UDP_IER, AT91_UDP_RXSUSP); | 1454 | at91_udp_write(udc, AT91_UDP_IER, AT91_UDP_RXSUSP); |
1430 | at91_udp_write(AT91_UDP_ICR, AT91_UDP_RXRSM); | 1455 | at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_RXRSM); |
1431 | // VDBG("bus resume\n"); | 1456 | // VDBG("bus resume\n"); |
1432 | if (!udc->suspended) | 1457 | if (!udc->suspended) |
1433 | continue; | 1458 | continue; |
@@ -1485,8 +1510,6 @@ static struct at91_udc controller = { | |||
1485 | }, | 1510 | }, |
1486 | .udc = &controller, | 1511 | .udc = &controller, |
1487 | .maxpacket = 8, | 1512 | .maxpacket = 8, |
1488 | .creg = (void __iomem *)(AT91_VA_BASE_UDP | ||
1489 | + AT91_UDP_CSR(0)), | ||
1490 | .int_mask = 1 << 0, | 1513 | .int_mask = 1 << 0, |
1491 | }, | 1514 | }, |
1492 | .ep[1] = { | 1515 | .ep[1] = { |
@@ -1497,8 +1520,6 @@ static struct at91_udc controller = { | |||
1497 | .udc = &controller, | 1520 | .udc = &controller, |
1498 | .is_pingpong = 1, | 1521 | .is_pingpong = 1, |
1499 | .maxpacket = 64, | 1522 | .maxpacket = 64, |
1500 | .creg = (void __iomem *)(AT91_VA_BASE_UDP | ||
1501 | + AT91_UDP_CSR(1)), | ||
1502 | .int_mask = 1 << 1, | 1523 | .int_mask = 1 << 1, |
1503 | }, | 1524 | }, |
1504 | .ep[2] = { | 1525 | .ep[2] = { |
@@ -1509,8 +1530,6 @@ static struct at91_udc controller = { | |||
1509 | .udc = &controller, | 1530 | .udc = &controller, |
1510 | .is_pingpong = 1, | 1531 | .is_pingpong = 1, |
1511 | .maxpacket = 64, | 1532 | .maxpacket = 64, |
1512 | .creg = (void __iomem *)(AT91_VA_BASE_UDP | ||
1513 | + AT91_UDP_CSR(2)), | ||
1514 | .int_mask = 1 << 2, | 1533 | .int_mask = 1 << 2, |
1515 | }, | 1534 | }, |
1516 | .ep[3] = { | 1535 | .ep[3] = { |
@@ -1521,8 +1540,6 @@ static struct at91_udc controller = { | |||
1521 | }, | 1540 | }, |
1522 | .udc = &controller, | 1541 | .udc = &controller, |
1523 | .maxpacket = 8, | 1542 | .maxpacket = 8, |
1524 | .creg = (void __iomem *)(AT91_VA_BASE_UDP | ||
1525 | + AT91_UDP_CSR(3)), | ||
1526 | .int_mask = 1 << 3, | 1543 | .int_mask = 1 << 3, |
1527 | }, | 1544 | }, |
1528 | .ep[4] = { | 1545 | .ep[4] = { |
@@ -1533,8 +1550,6 @@ static struct at91_udc controller = { | |||
1533 | .udc = &controller, | 1550 | .udc = &controller, |
1534 | .is_pingpong = 1, | 1551 | .is_pingpong = 1, |
1535 | .maxpacket = 256, | 1552 | .maxpacket = 256, |
1536 | .creg = (void __iomem *)(AT91_VA_BASE_UDP | ||
1537 | + AT91_UDP_CSR(4)), | ||
1538 | .int_mask = 1 << 4, | 1553 | .int_mask = 1 << 4, |
1539 | }, | 1554 | }, |
1540 | .ep[5] = { | 1555 | .ep[5] = { |
@@ -1545,8 +1560,6 @@ static struct at91_udc controller = { | |||
1545 | .udc = &controller, | 1560 | .udc = &controller, |
1546 | .is_pingpong = 1, | 1561 | .is_pingpong = 1, |
1547 | .maxpacket = 256, | 1562 | .maxpacket = 256, |
1548 | .creg = (void __iomem *)(AT91_VA_BASE_UDP | ||
1549 | + AT91_UDP_CSR(5)), | ||
1550 | .int_mask = 1 << 5, | 1563 | .int_mask = 1 << 5, |
1551 | }, | 1564 | }, |
1552 | /* ep6 and ep7 are also reserved (custom silicon might use them) */ | 1565 | /* ep6 and ep7 are also reserved (custom silicon might use them) */ |
@@ -1572,9 +1585,8 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) | |||
1572 | int retval; | 1585 | int retval; |
1573 | 1586 | ||
1574 | if (!driver | 1587 | if (!driver |
1575 | || driver->speed != USB_SPEED_FULL | 1588 | || driver->speed < USB_SPEED_FULL |
1576 | || !driver->bind | 1589 | || !driver->bind |
1577 | || !driver->unbind | ||
1578 | || !driver->setup) { | 1590 | || !driver->setup) { |
1579 | DBG("bad parameter.\n"); | 1591 | DBG("bad parameter.\n"); |
1580 | return -EINVAL; | 1592 | return -EINVAL; |
@@ -1595,6 +1607,10 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) | |||
1595 | if (retval) { | 1607 | if (retval) { |
1596 | DBG("driver->bind() returned %d\n", retval); | 1608 | DBG("driver->bind() returned %d\n", retval); |
1597 | udc->driver = NULL; | 1609 | udc->driver = NULL; |
1610 | udc->gadget.dev.driver = NULL; | ||
1611 | udc->gadget.dev.driver_data = NULL; | ||
1612 | udc->enabled = 0; | ||
1613 | udc->selfpowered = 0; | ||
1598 | return retval; | 1614 | return retval; |
1599 | } | 1615 | } |
1600 | 1616 | ||
@@ -1611,12 +1627,12 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver) | |||
1611 | { | 1627 | { |
1612 | struct at91_udc *udc = &controller; | 1628 | struct at91_udc *udc = &controller; |
1613 | 1629 | ||
1614 | if (!driver || driver != udc->driver) | 1630 | if (!driver || driver != udc->driver || !driver->unbind) |
1615 | return -EINVAL; | 1631 | return -EINVAL; |
1616 | 1632 | ||
1617 | local_irq_disable(); | 1633 | local_irq_disable(); |
1618 | udc->enabled = 0; | 1634 | udc->enabled = 0; |
1619 | at91_udp_write(AT91_UDP_IDR, ~0); | 1635 | at91_udp_write(udc, AT91_UDP_IDR, ~0); |
1620 | pullup(udc, 0); | 1636 | pullup(udc, 0); |
1621 | local_irq_enable(); | 1637 | local_irq_enable(); |
1622 | 1638 | ||
@@ -1641,6 +1657,7 @@ static int __devinit at91udc_probe(struct platform_device *pdev) | |||
1641 | struct device *dev = &pdev->dev; | 1657 | struct device *dev = &pdev->dev; |
1642 | struct at91_udc *udc; | 1658 | struct at91_udc *udc; |
1643 | int retval; | 1659 | int retval; |
1660 | struct resource *res; | ||
1644 | 1661 | ||
1645 | if (!dev->platform_data) { | 1662 | if (!dev->platform_data) { |
1646 | /* small (so we copy it) but critical! */ | 1663 | /* small (so we copy it) but critical! */ |
@@ -1658,7 +1675,13 @@ static int __devinit at91udc_probe(struct platform_device *pdev) | |||
1658 | return -ENODEV; | 1675 | return -ENODEV; |
1659 | } | 1676 | } |
1660 | 1677 | ||
1661 | if (!request_mem_region(AT91RM9200_BASE_UDP, SZ_16K, driver_name)) { | 1678 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1679 | if (!res) | ||
1680 | return -ENXIO; | ||
1681 | |||
1682 | if (!request_mem_region(res->start, | ||
1683 | res->end - res->start + 1, | ||
1684 | driver_name)) { | ||
1662 | DBG("someone's using UDC memory\n"); | 1685 | DBG("someone's using UDC memory\n"); |
1663 | return -EBUSY; | 1686 | return -EBUSY; |
1664 | } | 1687 | } |
@@ -1668,15 +1691,23 @@ static int __devinit at91udc_probe(struct platform_device *pdev) | |||
1668 | udc->gadget.dev.parent = dev; | 1691 | udc->gadget.dev.parent = dev; |
1669 | udc->board = *(struct at91_udc_data *) dev->platform_data; | 1692 | udc->board = *(struct at91_udc_data *) dev->platform_data; |
1670 | udc->pdev = pdev; | 1693 | udc->pdev = pdev; |
1671 | udc_reinit(udc); | ||
1672 | udc->enabled = 0; | 1694 | udc->enabled = 0; |
1673 | 1695 | ||
1696 | udc->udp_baseaddr = ioremap(res->start, res->end - res->start + 1); | ||
1697 | if (!udc->udp_baseaddr) { | ||
1698 | release_mem_region(res->start, res->end - res->start + 1); | ||
1699 | return -ENOMEM; | ||
1700 | } | ||
1701 | |||
1702 | udc_reinit(udc); | ||
1703 | |||
1674 | /* get interface and function clocks */ | 1704 | /* get interface and function clocks */ |
1675 | udc->iclk = clk_get(dev, "udc_clk"); | 1705 | udc->iclk = clk_get(dev, "udc_clk"); |
1676 | udc->fclk = clk_get(dev, "udpck"); | 1706 | udc->fclk = clk_get(dev, "udpck"); |
1677 | if (IS_ERR(udc->iclk) || IS_ERR(udc->fclk)) { | 1707 | if (IS_ERR(udc->iclk) || IS_ERR(udc->fclk)) { |
1678 | DBG("clocks missing\n"); | 1708 | DBG("clocks missing\n"); |
1679 | return -ENODEV; | 1709 | retval = -ENODEV; |
1710 | goto fail0; | ||
1680 | } | 1711 | } |
1681 | 1712 | ||
1682 | retval = device_register(&udc->gadget.dev); | 1713 | retval = device_register(&udc->gadget.dev); |
@@ -1685,8 +1716,10 @@ static int __devinit at91udc_probe(struct platform_device *pdev) | |||
1685 | 1716 | ||
1686 | /* don't do anything until we have both gadget driver and VBUS */ | 1717 | /* don't do anything until we have both gadget driver and VBUS */ |
1687 | clk_enable(udc->iclk); | 1718 | clk_enable(udc->iclk); |
1688 | at91_udp_write(AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); | 1719 | at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); |
1689 | at91_udp_write(AT91_UDP_IDR, 0xffffffff); | 1720 | at91_udp_write(udc, AT91_UDP_IDR, 0xffffffff); |
1721 | /* Clear all pending interrupts - UDP may be used by bootloader. */ | ||
1722 | at91_udp_write(udc, AT91_UDP_ICR, 0xffffffff); | ||
1690 | clk_disable(udc->iclk); | 1723 | clk_disable(udc->iclk); |
1691 | 1724 | ||
1692 | /* request UDC and maybe VBUS irqs */ | 1725 | /* request UDC and maybe VBUS irqs */ |
@@ -1698,6 +1731,11 @@ static int __devinit at91udc_probe(struct platform_device *pdev) | |||
1698 | goto fail1; | 1731 | goto fail1; |
1699 | } | 1732 | } |
1700 | if (udc->board.vbus_pin > 0) { | 1733 | if (udc->board.vbus_pin > 0) { |
1734 | /* | ||
1735 | * Get the initial state of VBUS - we cannot expect | ||
1736 | * a pending interrupt. | ||
1737 | */ | ||
1738 | udc->vbus = at91_get_gpio_value(udc->board.vbus_pin); | ||
1701 | if (request_irq(udc->board.vbus_pin, at91_vbus_irq, | 1739 | if (request_irq(udc->board.vbus_pin, at91_vbus_irq, |
1702 | IRQF_DISABLED, driver_name, udc)) { | 1740 | IRQF_DISABLED, driver_name, udc)) { |
1703 | DBG("request vbus irq %d failed\n", | 1741 | DBG("request vbus irq %d failed\n", |
@@ -1720,7 +1758,7 @@ static int __devinit at91udc_probe(struct platform_device *pdev) | |||
1720 | fail1: | 1758 | fail1: |
1721 | device_unregister(&udc->gadget.dev); | 1759 | device_unregister(&udc->gadget.dev); |
1722 | fail0: | 1760 | fail0: |
1723 | release_mem_region(AT91RM9200_BASE_UDP, SZ_16K); | 1761 | release_mem_region(res->start, res->end - res->start + 1); |
1724 | DBG("%s probe failed, %d\n", driver_name, retval); | 1762 | DBG("%s probe failed, %d\n", driver_name, retval); |
1725 | return retval; | 1763 | return retval; |
1726 | } | 1764 | } |
@@ -1728,13 +1766,14 @@ fail0: | |||
1728 | static int __devexit at91udc_remove(struct platform_device *pdev) | 1766 | static int __devexit at91udc_remove(struct platform_device *pdev) |
1729 | { | 1767 | { |
1730 | struct at91_udc *udc = platform_get_drvdata(pdev); | 1768 | struct at91_udc *udc = platform_get_drvdata(pdev); |
1769 | struct resource *res; | ||
1731 | 1770 | ||
1732 | DBG("remove\n"); | 1771 | DBG("remove\n"); |
1733 | 1772 | ||
1734 | pullup(udc, 0); | 1773 | if (udc->driver) |
1774 | return -EBUSY; | ||
1735 | 1775 | ||
1736 | if (udc->driver != 0) | 1776 | pullup(udc, 0); |
1737 | usb_gadget_unregister_driver(udc->driver); | ||
1738 | 1777 | ||
1739 | device_init_wakeup(&pdev->dev, 0); | 1778 | device_init_wakeup(&pdev->dev, 0); |
1740 | remove_debug_file(udc); | 1779 | remove_debug_file(udc); |
@@ -1742,7 +1781,10 @@ static int __devexit at91udc_remove(struct platform_device *pdev) | |||
1742 | free_irq(udc->board.vbus_pin, udc); | 1781 | free_irq(udc->board.vbus_pin, udc); |
1743 | free_irq(udc->udp_irq, udc); | 1782 | free_irq(udc->udp_irq, udc); |
1744 | device_unregister(&udc->gadget.dev); | 1783 | device_unregister(&udc->gadget.dev); |
1745 | release_mem_region(AT91RM9200_BASE_UDP, SZ_16K); | 1784 | |
1785 | iounmap(udc->udp_baseaddr); | ||
1786 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1787 | release_mem_region(res->start, res->end - res->start + 1); | ||
1746 | 1788 | ||
1747 | clk_put(udc->iclk); | 1789 | clk_put(udc->iclk); |
1748 | clk_put(udc->fclk); | 1790 | clk_put(udc->fclk); |
diff --git a/drivers/usb/gadget/at91_udc.h b/drivers/usb/gadget/at91_udc.h index 882af42e86cc..677089baa59d 100644 --- a/drivers/usb/gadget/at91_udc.h +++ b/drivers/usb/gadget/at91_udc.h | |||
@@ -51,10 +51,10 @@ | |||
51 | #define AT91_UDP_EP(n) (1 << (n)) /* Endpoint Interrupt Status */ | 51 | #define AT91_UDP_EP(n) (1 << (n)) /* Endpoint Interrupt Status */ |
52 | #define AT91_UDP_RXSUSP (1 << 8) /* USB Suspend Interrupt Status */ | 52 | #define AT91_UDP_RXSUSP (1 << 8) /* USB Suspend Interrupt Status */ |
53 | #define AT91_UDP_RXRSM (1 << 9) /* USB Resume Interrupt Status */ | 53 | #define AT91_UDP_RXRSM (1 << 9) /* USB Resume Interrupt Status */ |
54 | #define AT91_UDP_EXTRSM (1 << 10) /* External Resume Interrupt Status */ | 54 | #define AT91_UDP_EXTRSM (1 << 10) /* External Resume Interrupt Status [AT91RM9200 only] */ |
55 | #define AT91_UDP_SOFINT (1 << 11) /* Start of Frame Interrupt Status */ | 55 | #define AT91_UDP_SOFINT (1 << 11) /* Start of Frame Interrupt Status */ |
56 | #define AT91_UDP_ENDBUSRES (1 << 12) /* End of Bus Reset Interrpt Status */ | 56 | #define AT91_UDP_ENDBUSRES (1 << 12) /* End of Bus Reset Interrpt Status */ |
57 | #define AT91_UDP_WAKEUP (1 << 13) /* USB Wakeup Interrupt Status */ | 57 | #define AT91_UDP_WAKEUP (1 << 13) /* USB Wakeup Interrupt Status [AT91RM9200 only] */ |
58 | 58 | ||
59 | #define AT91_UDP_ICR 0x20 /* Interrupt Clear Register */ | 59 | #define AT91_UDP_ICR 0x20 /* Interrupt Clear Register */ |
60 | #define AT91_UDP_RST_EP 0x28 /* Reset Endpoint Register */ | 60 | #define AT91_UDP_RST_EP 0x28 /* Reset Endpoint Register */ |
@@ -84,7 +84,7 @@ | |||
84 | 84 | ||
85 | #define AT91_UDP_TXVC 0x74 /* Transceiver Control Register */ | 85 | #define AT91_UDP_TXVC 0x74 /* Transceiver Control Register */ |
86 | #define AT91_UDP_TXVC_TXVDIS (1 << 8) /* Transceiver Disable */ | 86 | #define AT91_UDP_TXVC_TXVDIS (1 << 8) /* Transceiver Disable */ |
87 | 87 | #define AT91_UDP_TXVC_PUON (1 << 9) /* PullUp On [AT91SAM9260 only] */ | |
88 | 88 | ||
89 | /*-------------------------------------------------------------------------*/ | 89 | /*-------------------------------------------------------------------------*/ |
90 | 90 | ||
@@ -141,6 +141,7 @@ struct at91_udc { | |||
141 | struct clk *iclk, *fclk; | 141 | struct clk *iclk, *fclk; |
142 | struct platform_device *pdev; | 142 | struct platform_device *pdev; |
143 | struct proc_dir_entry *pde; | 143 | struct proc_dir_entry *pde; |
144 | void __iomem *udp_baseaddr; | ||
144 | int udp_irq; | 145 | int udp_irq; |
145 | }; | 146 | }; |
146 | 147 | ||
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index f1f32d7be5f9..3c2bc075ef4f 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
@@ -779,7 +779,7 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver) | |||
779 | return -EINVAL; | 779 | return -EINVAL; |
780 | if (dum->driver) | 780 | if (dum->driver) |
781 | return -EBUSY; | 781 | return -EBUSY; |
782 | if (!driver->bind || !driver->unbind || !driver->setup | 782 | if (!driver->bind || !driver->setup |
783 | || driver->speed == USB_SPEED_UNKNOWN) | 783 | || driver->speed == USB_SPEED_UNKNOWN) |
784 | return -EINVAL; | 784 | return -EINVAL; |
785 | 785 | ||
@@ -837,7 +837,8 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver) | |||
837 | err_bind_driver: | 837 | err_bind_driver: |
838 | driver_unregister (&driver->driver); | 838 | driver_unregister (&driver->driver); |
839 | err_register: | 839 | err_register: |
840 | driver->unbind (&dum->gadget); | 840 | if (driver->unbind) |
841 | driver->unbind (&dum->gadget); | ||
841 | spin_lock_irq (&dum->lock); | 842 | spin_lock_irq (&dum->lock); |
842 | dum->pullup = 0; | 843 | dum->pullup = 0; |
843 | set_link_state (dum); | 844 | set_link_state (dum); |
@@ -857,7 +858,7 @@ usb_gadget_unregister_driver (struct usb_gadget_driver *driver) | |||
857 | 858 | ||
858 | if (!dum) | 859 | if (!dum) |
859 | return -ENODEV; | 860 | return -ENODEV; |
860 | if (!driver || driver != dum->driver) | 861 | if (!driver || driver != dum->driver || !driver->unbind) |
861 | return -EINVAL; | 862 | return -EINVAL; |
862 | 863 | ||
863 | dev_dbg (udc_dev(dum), "unregister gadget driver '%s'\n", | 864 | dev_dbg (udc_dev(dum), "unregister gadget driver '%s'\n", |
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index a265e262a2ee..72f2ae96fbf3 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -4100,7 +4100,7 @@ static struct usb_gadget_driver fsg_driver = { | |||
4100 | #endif | 4100 | #endif |
4101 | .function = (char *) longname, | 4101 | .function = (char *) longname, |
4102 | .bind = fsg_bind, | 4102 | .bind = fsg_bind, |
4103 | .unbind = __exit_p(fsg_unbind), | 4103 | .unbind = fsg_unbind, |
4104 | .disconnect = fsg_disconnect, | 4104 | .disconnect = fsg_disconnect, |
4105 | .setup = fsg_setup, | 4105 | .setup = fsg_setup, |
4106 | .suspend = fsg_suspend, | 4106 | .suspend = fsg_suspend, |
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index 31351826f2ba..f1a679656c96 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c | |||
@@ -123,7 +123,7 @@ struct gmidi_device { | |||
123 | struct usb_request *req; /* for control responses */ | 123 | struct usb_request *req; /* for control responses */ |
124 | u8 config; | 124 | u8 config; |
125 | struct usb_ep *in_ep, *out_ep; | 125 | struct usb_ep *in_ep, *out_ep; |
126 | struct snd_card *card; | 126 | struct snd_card *card; |
127 | struct snd_rawmidi *rmidi; | 127 | struct snd_rawmidi *rmidi; |
128 | struct snd_rawmidi_substream *in_substream; | 128 | struct snd_rawmidi_substream *in_substream; |
129 | struct snd_rawmidi_substream *out_substream; | 129 | struct snd_rawmidi_substream *out_substream; |
@@ -490,7 +490,7 @@ static void gmidi_complete(struct usb_ep *ep, struct usb_request *req) | |||
490 | int status = req->status; | 490 | int status = req->status; |
491 | 491 | ||
492 | switch (status) { | 492 | switch (status) { |
493 | case 0: /* normal completion */ | 493 | case 0: /* normal completion */ |
494 | if (ep == dev->out_ep) { | 494 | if (ep == dev->out_ep) { |
495 | /* we received stuff. | 495 | /* we received stuff. |
496 | req is queued again, below */ | 496 | req is queued again, below */ |
@@ -505,7 +505,7 @@ static void gmidi_complete(struct usb_ep *ep, struct usb_request *req) | |||
505 | break; | 505 | break; |
506 | 506 | ||
507 | /* this endpoint is normally active while we're configured */ | 507 | /* this endpoint is normally active while we're configured */ |
508 | case -ECONNABORTED: /* hardware forced ep reset */ | 508 | case -ECONNABORTED: /* hardware forced ep reset */ |
509 | case -ECONNRESET: /* request dequeued */ | 509 | case -ECONNRESET: /* request dequeued */ |
510 | case -ESHUTDOWN: /* disconnect from host */ | 510 | case -ESHUTDOWN: /* disconnect from host */ |
511 | VDBG(dev, "%s gone (%d), %d/%d\n", ep->name, status, | 511 | VDBG(dev, "%s gone (%d), %d/%d\n", ep->name, status, |
@@ -656,7 +656,7 @@ gmidi_set_config(struct gmidi_device *dev, unsigned number, gfp_t gfp_flags) | |||
656 | case USB_SPEED_LOW: speed = "low"; break; | 656 | case USB_SPEED_LOW: speed = "low"; break; |
657 | case USB_SPEED_FULL: speed = "full"; break; | 657 | case USB_SPEED_FULL: speed = "full"; break; |
658 | case USB_SPEED_HIGH: speed = "high"; break; | 658 | case USB_SPEED_HIGH: speed = "high"; break; |
659 | default: speed = "?"; break; | 659 | default: speed = "?"; break; |
660 | } | 660 | } |
661 | 661 | ||
662 | dev->config = number; | 662 | dev->config = number; |
@@ -1308,7 +1308,7 @@ static struct usb_gadget_driver gmidi_driver = { | |||
1308 | .speed = USB_SPEED_FULL, | 1308 | .speed = USB_SPEED_FULL, |
1309 | .function = (char *)longname, | 1309 | .function = (char *)longname, |
1310 | .bind = gmidi_bind, | 1310 | .bind = gmidi_bind, |
1311 | .unbind = __exit_p(gmidi_unbind), | 1311 | .unbind = gmidi_unbind, |
1312 | 1312 | ||
1313 | .setup = gmidi_setup, | 1313 | .setup = gmidi_setup, |
1314 | .disconnect = gmidi_disconnect, | 1314 | .disconnect = gmidi_disconnect, |
@@ -1316,7 +1316,7 @@ static struct usb_gadget_driver gmidi_driver = { | |||
1316 | .suspend = gmidi_suspend, | 1316 | .suspend = gmidi_suspend, |
1317 | .resume = gmidi_resume, | 1317 | .resume = gmidi_resume, |
1318 | 1318 | ||
1319 | .driver = { | 1319 | .driver = { |
1320 | .name = (char *)shortname, | 1320 | .name = (char *)shortname, |
1321 | .owner = THIS_MODULE, | 1321 | .owner = THIS_MODULE, |
1322 | }, | 1322 | }, |
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index 805a9826842d..d0ef1d6b3fac 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c | |||
@@ -1432,7 +1432,6 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
1432 | if (!driver | 1432 | if (!driver |
1433 | || driver->speed != USB_SPEED_FULL | 1433 | || driver->speed != USB_SPEED_FULL |
1434 | || !driver->bind | 1434 | || !driver->bind |
1435 | || !driver->unbind | ||
1436 | || !driver->disconnect | 1435 | || !driver->disconnect |
1437 | || !driver->setup) | 1436 | || !driver->setup) |
1438 | return -EINVAL; | 1437 | return -EINVAL; |
@@ -1495,7 +1494,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
1495 | 1494 | ||
1496 | if (!dev) | 1495 | if (!dev) |
1497 | return -ENODEV; | 1496 | return -ENODEV; |
1498 | if (!driver || driver != dev->driver) | 1497 | if (!driver || driver != dev->driver || !driver->unbind) |
1499 | return -EINVAL; | 1498 | return -EINVAL; |
1500 | 1499 | ||
1501 | spin_lock_irqsave(&dev->lock, flags); | 1500 | spin_lock_irqsave(&dev->lock, flags); |
@@ -1808,13 +1807,8 @@ static void goku_remove(struct pci_dev *pdev) | |||
1808 | struct goku_udc *dev = pci_get_drvdata(pdev); | 1807 | struct goku_udc *dev = pci_get_drvdata(pdev); |
1809 | 1808 | ||
1810 | DBG(dev, "%s\n", __FUNCTION__); | 1809 | DBG(dev, "%s\n", __FUNCTION__); |
1811 | /* start with the driver above us */ | 1810 | |
1812 | if (dev->driver) { | 1811 | BUG_ON(dev->driver); |
1813 | /* should have been done already by driver model core */ | ||
1814 | WARN(dev, "pci remove, driver '%s' is still registered\n", | ||
1815 | dev->driver->driver.name); | ||
1816 | usb_gadget_unregister_driver(dev->driver); | ||
1817 | } | ||
1818 | 1812 | ||
1819 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES | 1813 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES |
1820 | remove_proc_entry(proc_node_name, NULL); | 1814 | remove_proc_entry(proc_node_name, NULL); |
diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c index 4a991564a03e..a0a73c08a344 100644 --- a/drivers/usb/gadget/lh7a40x_udc.c +++ b/drivers/usb/gadget/lh7a40x_udc.c | |||
@@ -422,9 +422,10 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
422 | DEBUG("%s: %s\n", __FUNCTION__, driver->driver.name); | 422 | DEBUG("%s: %s\n", __FUNCTION__, driver->driver.name); |
423 | 423 | ||
424 | if (!driver | 424 | if (!driver |
425 | || driver->speed != USB_SPEED_FULL | 425 | || driver->speed != USB_SPEED_FULL |
426 | || !driver->bind | 426 | || !driver->bind |
427 | || !driver->unbind || !driver->disconnect || !driver->setup) | 427 | || !driver->disconnect |
428 | || !driver->setup) | ||
428 | return -EINVAL; | 429 | return -EINVAL; |
429 | if (!dev) | 430 | if (!dev) |
430 | return -ENODEV; | 431 | return -ENODEV; |
@@ -471,7 +472,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
471 | 472 | ||
472 | if (!dev) | 473 | if (!dev) |
473 | return -ENODEV; | 474 | return -ENODEV; |
474 | if (!driver || driver != dev->driver) | 475 | if (!driver || driver != dev->driver || !driver->unbind) |
475 | return -EINVAL; | 476 | return -EINVAL; |
476 | 477 | ||
477 | spin_lock_irqsave(&dev->lock, flags); | 478 | spin_lock_irqsave(&dev->lock, flags); |
@@ -2125,9 +2126,11 @@ static int lh7a40x_udc_remove(struct platform_device *pdev) | |||
2125 | 2126 | ||
2126 | DEBUG("%s: %p\n", __FUNCTION__, pdev); | 2127 | DEBUG("%s: %p\n", __FUNCTION__, pdev); |
2127 | 2128 | ||
2129 | if (dev->driver) | ||
2130 | return -EBUSY; | ||
2131 | |||
2128 | udc_disable(dev); | 2132 | udc_disable(dev); |
2129 | remove_proc_files(); | 2133 | remove_proc_files(); |
2130 | usb_gadget_unregister_driver(dev->driver); | ||
2131 | 2134 | ||
2132 | free_irq(IRQ_USBINTR, dev); | 2135 | free_irq(IRQ_USBINTR, dev); |
2133 | 2136 | ||
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index 3024c679e38e..569eb8ccf232 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c | |||
@@ -2020,7 +2020,6 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) | |||
2020 | if (!driver | 2020 | if (!driver |
2021 | || driver->speed != USB_SPEED_HIGH | 2021 | || driver->speed != USB_SPEED_HIGH |
2022 | || !driver->bind | 2022 | || !driver->bind |
2023 | || !driver->unbind | ||
2024 | || !driver->setup) | 2023 | || !driver->setup) |
2025 | return -EINVAL; | 2024 | return -EINVAL; |
2026 | if (!dev) | 2025 | if (!dev) |
@@ -2107,7 +2106,7 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver) | |||
2107 | 2106 | ||
2108 | if (!dev) | 2107 | if (!dev) |
2109 | return -ENODEV; | 2108 | return -ENODEV; |
2110 | if (!driver || driver != dev->driver) | 2109 | if (!driver || driver != dev->driver || !driver->unbind) |
2111 | return -EINVAL; | 2110 | return -EINVAL; |
2112 | 2111 | ||
2113 | spin_lock_irqsave (&dev->lock, flags); | 2112 | spin_lock_irqsave (&dev->lock, flags); |
@@ -2803,13 +2802,7 @@ static void net2280_remove (struct pci_dev *pdev) | |||
2803 | { | 2802 | { |
2804 | struct net2280 *dev = pci_get_drvdata (pdev); | 2803 | struct net2280 *dev = pci_get_drvdata (pdev); |
2805 | 2804 | ||
2806 | /* start with the driver above us */ | 2805 | BUG_ON(dev->driver); |
2807 | if (dev->driver) { | ||
2808 | /* should have been done already by driver model core */ | ||
2809 | WARN (dev, "pci remove, driver '%s' is still registered\n", | ||
2810 | dev->driver->driver.name); | ||
2811 | usb_gadget_unregister_driver (dev->driver); | ||
2812 | } | ||
2813 | 2806 | ||
2814 | /* then clean up the resources we allocated during probe() */ | 2807 | /* then clean up the resources we allocated during probe() */ |
2815 | net2280_led_shutdown (dev); | 2808 | net2280_led_shutdown (dev); |
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 030d87c28c2f..15d77c307930 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c | |||
@@ -2043,7 +2043,6 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) | |||
2043 | // FIXME if otg, check: driver->is_otg | 2043 | // FIXME if otg, check: driver->is_otg |
2044 | || driver->speed < USB_SPEED_FULL | 2044 | || driver->speed < USB_SPEED_FULL |
2045 | || !driver->bind | 2045 | || !driver->bind |
2046 | || !driver->unbind | ||
2047 | || !driver->setup) | 2046 | || !driver->setup) |
2048 | return -EINVAL; | 2047 | return -EINVAL; |
2049 | 2048 | ||
@@ -2087,9 +2086,11 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) | |||
2087 | status = otg_set_peripheral(udc->transceiver, &udc->gadget); | 2086 | status = otg_set_peripheral(udc->transceiver, &udc->gadget); |
2088 | if (status < 0) { | 2087 | if (status < 0) { |
2089 | ERR("can't bind to transceiver\n"); | 2088 | ERR("can't bind to transceiver\n"); |
2090 | driver->unbind (&udc->gadget); | 2089 | if (driver->unbind) { |
2091 | udc->gadget.dev.driver = NULL; | 2090 | driver->unbind (&udc->gadget); |
2092 | udc->driver = NULL; | 2091 | udc->gadget.dev.driver = NULL; |
2092 | udc->driver = NULL; | ||
2093 | } | ||
2093 | goto done; | 2094 | goto done; |
2094 | } | 2095 | } |
2095 | } else { | 2096 | } else { |
@@ -2117,7 +2118,7 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver) | |||
2117 | 2118 | ||
2118 | if (!udc) | 2119 | if (!udc) |
2119 | return -ENODEV; | 2120 | return -ENODEV; |
2120 | if (!driver || driver != udc->driver) | 2121 | if (!driver || driver != udc->driver || !driver->unbind) |
2121 | return -EINVAL; | 2122 | return -EINVAL; |
2122 | 2123 | ||
2123 | if (machine_is_omap_innovator() || machine_is_omap_osk()) | 2124 | if (machine_is_omap_innovator() || machine_is_omap_osk()) |
@@ -2870,6 +2871,8 @@ static int __exit omap_udc_remove(struct platform_device *pdev) | |||
2870 | 2871 | ||
2871 | if (!udc) | 2872 | if (!udc) |
2872 | return -ENODEV; | 2873 | return -ENODEV; |
2874 | if (udc->driver) | ||
2875 | return -EBUSY; | ||
2873 | 2876 | ||
2874 | udc->done = &done; | 2877 | udc->done = &done; |
2875 | 2878 | ||
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index 1ed506e95985..b78de9694665 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c | |||
@@ -1623,7 +1623,6 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
1623 | if (!driver | 1623 | if (!driver |
1624 | || driver->speed < USB_SPEED_FULL | 1624 | || driver->speed < USB_SPEED_FULL |
1625 | || !driver->bind | 1625 | || !driver->bind |
1626 | || !driver->unbind | ||
1627 | || !driver->disconnect | 1626 | || !driver->disconnect |
1628 | || !driver->setup) | 1627 | || !driver->setup) |
1629 | return -EINVAL; | 1628 | return -EINVAL; |
@@ -1694,7 +1693,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
1694 | 1693 | ||
1695 | if (!dev) | 1694 | if (!dev) |
1696 | return -ENODEV; | 1695 | return -ENODEV; |
1697 | if (!driver || driver != dev->driver) | 1696 | if (!driver || driver != dev->driver || !driver->unbind) |
1698 | return -EINVAL; | 1697 | return -EINVAL; |
1699 | 1698 | ||
1700 | local_irq_disable(); | 1699 | local_irq_disable(); |
@@ -2638,9 +2637,11 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev) | |||
2638 | { | 2637 | { |
2639 | struct pxa2xx_udc *dev = platform_get_drvdata(pdev); | 2638 | struct pxa2xx_udc *dev = platform_get_drvdata(pdev); |
2640 | 2639 | ||
2640 | if (dev->driver) | ||
2641 | return -EBUSY; | ||
2642 | |||
2641 | udc_disable(dev); | 2643 | udc_disable(dev); |
2642 | remove_proc_files(); | 2644 | remove_proc_files(); |
2643 | usb_gadget_unregister_driver(dev->driver); | ||
2644 | 2645 | ||
2645 | if (dev->got_irq) { | 2646 | if (dev->got_irq) { |
2646 | free_irq(IRQ_USB, dev); | 2647 | free_irq(IRQ_USB, dev); |
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index 2d12bf9f19d6..f8a3ec64635d 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c | |||
@@ -296,7 +296,7 @@ static struct usb_gadget_driver gs_gadget_driver = { | |||
296 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | 296 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ |
297 | .function = GS_LONG_NAME, | 297 | .function = GS_LONG_NAME, |
298 | .bind = gs_bind, | 298 | .bind = gs_bind, |
299 | .unbind = __exit_p(gs_unbind), | 299 | .unbind = gs_unbind, |
300 | .setup = gs_setup, | 300 | .setup = gs_setup, |
301 | .disconnect = gs_disconnect, | 301 | .disconnect = gs_disconnect, |
302 | .driver = { | 302 | .driver = { |