diff options
Diffstat (limited to 'drivers/usb/dwc2/gadget.c')
-rw-r--r-- | drivers/usb/dwc2/gadget.c | 387 |
1 files changed, 169 insertions, 218 deletions
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 8b5c079c7b7d..200168ec2d75 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
22 | #include <linux/dma-mapping.h> | 22 | #include <linux/dma-mapping.h> |
23 | #include <linux/debugfs.h> | 23 | #include <linux/debugfs.h> |
24 | #include <linux/mutex.h> | ||
24 | #include <linux/seq_file.h> | 25 | #include <linux/seq_file.h> |
25 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
26 | #include <linux/io.h> | 27 | #include <linux/io.h> |
@@ -36,6 +37,7 @@ | |||
36 | #include <linux/platform_data/s3c-hsotg.h> | 37 | #include <linux/platform_data/s3c-hsotg.h> |
37 | 38 | ||
38 | #include "core.h" | 39 | #include "core.h" |
40 | #include "hw.h" | ||
39 | 41 | ||
40 | /* conversion functions */ | 42 | /* conversion functions */ |
41 | static inline struct s3c_hsotg_req *our_req(struct usb_request *req) | 43 | static inline struct s3c_hsotg_req *our_req(struct usb_request *req) |
@@ -48,9 +50,9 @@ static inline struct s3c_hsotg_ep *our_ep(struct usb_ep *ep) | |||
48 | return container_of(ep, struct s3c_hsotg_ep, ep); | 50 | return container_of(ep, struct s3c_hsotg_ep, ep); |
49 | } | 51 | } |
50 | 52 | ||
51 | static inline struct s3c_hsotg *to_hsotg(struct usb_gadget *gadget) | 53 | static inline struct dwc2_hsotg *to_hsotg(struct usb_gadget *gadget) |
52 | { | 54 | { |
53 | return container_of(gadget, struct s3c_hsotg, gadget); | 55 | return container_of(gadget, struct dwc2_hsotg, gadget); |
54 | } | 56 | } |
55 | 57 | ||
56 | static inline void __orr32(void __iomem *ptr, u32 val) | 58 | static inline void __orr32(void __iomem *ptr, u32 val) |
@@ -64,7 +66,7 @@ static inline void __bic32(void __iomem *ptr, u32 val) | |||
64 | } | 66 | } |
65 | 67 | ||
66 | /* forward decleration of functions */ | 68 | /* forward decleration of functions */ |
67 | static void s3c_hsotg_dump(struct s3c_hsotg *hsotg); | 69 | static void s3c_hsotg_dump(struct dwc2_hsotg *hsotg); |
68 | 70 | ||
69 | /** | 71 | /** |
70 | * using_dma - return the DMA status of the driver. | 72 | * using_dma - return the DMA status of the driver. |
@@ -85,7 +87,7 @@ static void s3c_hsotg_dump(struct s3c_hsotg *hsotg); | |||
85 | * | 87 | * |
86 | * Until this issue is sorted out, we always return 'false'. | 88 | * Until this issue is sorted out, we always return 'false'. |
87 | */ | 89 | */ |
88 | static inline bool using_dma(struct s3c_hsotg *hsotg) | 90 | static inline bool using_dma(struct dwc2_hsotg *hsotg) |
89 | { | 91 | { |
90 | return false; /* support is not complete */ | 92 | return false; /* support is not complete */ |
91 | } | 93 | } |
@@ -95,7 +97,7 @@ static inline bool using_dma(struct s3c_hsotg *hsotg) | |||
95 | * @hsotg: The device state | 97 | * @hsotg: The device state |
96 | * @ints: A bitmask of the interrupts to enable | 98 | * @ints: A bitmask of the interrupts to enable |
97 | */ | 99 | */ |
98 | static void s3c_hsotg_en_gsint(struct s3c_hsotg *hsotg, u32 ints) | 100 | static void s3c_hsotg_en_gsint(struct dwc2_hsotg *hsotg, u32 ints) |
99 | { | 101 | { |
100 | u32 gsintmsk = readl(hsotg->regs + GINTMSK); | 102 | u32 gsintmsk = readl(hsotg->regs + GINTMSK); |
101 | u32 new_gsintmsk; | 103 | u32 new_gsintmsk; |
@@ -113,7 +115,7 @@ static void s3c_hsotg_en_gsint(struct s3c_hsotg *hsotg, u32 ints) | |||
113 | * @hsotg: The device state | 115 | * @hsotg: The device state |
114 | * @ints: A bitmask of the interrupts to enable | 116 | * @ints: A bitmask of the interrupts to enable |
115 | */ | 117 | */ |
116 | static void s3c_hsotg_disable_gsint(struct s3c_hsotg *hsotg, u32 ints) | 118 | static void s3c_hsotg_disable_gsint(struct dwc2_hsotg *hsotg, u32 ints) |
117 | { | 119 | { |
118 | u32 gsintmsk = readl(hsotg->regs + GINTMSK); | 120 | u32 gsintmsk = readl(hsotg->regs + GINTMSK); |
119 | u32 new_gsintmsk; | 121 | u32 new_gsintmsk; |
@@ -134,7 +136,7 @@ static void s3c_hsotg_disable_gsint(struct s3c_hsotg *hsotg, u32 ints) | |||
134 | * Set or clear the mask for an individual endpoint's interrupt | 136 | * Set or clear the mask for an individual endpoint's interrupt |
135 | * request. | 137 | * request. |
136 | */ | 138 | */ |
137 | static void s3c_hsotg_ctrl_epint(struct s3c_hsotg *hsotg, | 139 | static void s3c_hsotg_ctrl_epint(struct dwc2_hsotg *hsotg, |
138 | unsigned int ep, unsigned int dir_in, | 140 | unsigned int ep, unsigned int dir_in, |
139 | unsigned int en) | 141 | unsigned int en) |
140 | { | 142 | { |
@@ -159,7 +161,7 @@ static void s3c_hsotg_ctrl_epint(struct s3c_hsotg *hsotg, | |||
159 | * s3c_hsotg_init_fifo - initialise non-periodic FIFOs | 161 | * s3c_hsotg_init_fifo - initialise non-periodic FIFOs |
160 | * @hsotg: The device instance. | 162 | * @hsotg: The device instance. |
161 | */ | 163 | */ |
162 | static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg) | 164 | static void s3c_hsotg_init_fifo(struct dwc2_hsotg *hsotg) |
163 | { | 165 | { |
164 | unsigned int ep; | 166 | unsigned int ep; |
165 | unsigned int addr; | 167 | unsigned int addr; |
@@ -283,7 +285,7 @@ static inline int is_ep_periodic(struct s3c_hsotg_ep *hs_ep) | |||
283 | * This is the reverse of s3c_hsotg_map_dma(), called for the completion | 285 | * This is the reverse of s3c_hsotg_map_dma(), called for the completion |
284 | * of a request to ensure the buffer is ready for access by the caller. | 286 | * of a request to ensure the buffer is ready for access by the caller. |
285 | */ | 287 | */ |
286 | static void s3c_hsotg_unmap_dma(struct s3c_hsotg *hsotg, | 288 | static void s3c_hsotg_unmap_dma(struct dwc2_hsotg *hsotg, |
287 | struct s3c_hsotg_ep *hs_ep, | 289 | struct s3c_hsotg_ep *hs_ep, |
288 | struct s3c_hsotg_req *hs_req) | 290 | struct s3c_hsotg_req *hs_req) |
289 | { | 291 | { |
@@ -312,7 +314,7 @@ static void s3c_hsotg_unmap_dma(struct s3c_hsotg *hsotg, | |||
312 | * | 314 | * |
313 | * This routine is only needed for PIO | 315 | * This routine is only needed for PIO |
314 | */ | 316 | */ |
315 | static int s3c_hsotg_write_fifo(struct s3c_hsotg *hsotg, | 317 | static int s3c_hsotg_write_fifo(struct dwc2_hsotg *hsotg, |
316 | struct s3c_hsotg_ep *hs_ep, | 318 | struct s3c_hsotg_ep *hs_ep, |
317 | struct s3c_hsotg_req *hs_req) | 319 | struct s3c_hsotg_req *hs_req) |
318 | { | 320 | { |
@@ -517,7 +519,7 @@ static unsigned get_ep_limit(struct s3c_hsotg_ep *hs_ep) | |||
517 | * Start the given request running by setting the endpoint registers | 519 | * Start the given request running by setting the endpoint registers |
518 | * appropriately, and writing any data to the FIFOs. | 520 | * appropriately, and writing any data to the FIFOs. |
519 | */ | 521 | */ |
520 | static void s3c_hsotg_start_req(struct s3c_hsotg *hsotg, | 522 | static void s3c_hsotg_start_req(struct dwc2_hsotg *hsotg, |
521 | struct s3c_hsotg_ep *hs_ep, | 523 | struct s3c_hsotg_ep *hs_ep, |
522 | struct s3c_hsotg_req *hs_req, | 524 | struct s3c_hsotg_req *hs_req, |
523 | bool continuing) | 525 | bool continuing) |
@@ -707,7 +709,7 @@ static void s3c_hsotg_start_req(struct s3c_hsotg *hsotg, | |||
707 | * DMA memory, then we map the memory and mark our request to allow us to | 709 | * DMA memory, then we map the memory and mark our request to allow us to |
708 | * cleanup on completion. | 710 | * cleanup on completion. |
709 | */ | 711 | */ |
710 | static int s3c_hsotg_map_dma(struct s3c_hsotg *hsotg, | 712 | static int s3c_hsotg_map_dma(struct dwc2_hsotg *hsotg, |
711 | struct s3c_hsotg_ep *hs_ep, | 713 | struct s3c_hsotg_ep *hs_ep, |
712 | struct usb_request *req) | 714 | struct usb_request *req) |
713 | { | 715 | { |
@@ -736,7 +738,7 @@ static int s3c_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req, | |||
736 | { | 738 | { |
737 | struct s3c_hsotg_req *hs_req = our_req(req); | 739 | struct s3c_hsotg_req *hs_req = our_req(req); |
738 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); | 740 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); |
739 | struct s3c_hsotg *hs = hs_ep->parent; | 741 | struct dwc2_hsotg *hs = hs_ep->parent; |
740 | bool first; | 742 | bool first; |
741 | 743 | ||
742 | dev_dbg(hs->dev, "%s: req %p: %d@%p, noi=%d, zero=%d, snok=%d\n", | 744 | dev_dbg(hs->dev, "%s: req %p: %d@%p, noi=%d, zero=%d, snok=%d\n", |
@@ -768,7 +770,7 @@ static int s3c_hsotg_ep_queue_lock(struct usb_ep *ep, struct usb_request *req, | |||
768 | gfp_t gfp_flags) | 770 | gfp_t gfp_flags) |
769 | { | 771 | { |
770 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); | 772 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); |
771 | struct s3c_hsotg *hs = hs_ep->parent; | 773 | struct dwc2_hsotg *hs = hs_ep->parent; |
772 | unsigned long flags = 0; | 774 | unsigned long flags = 0; |
773 | int ret = 0; | 775 | int ret = 0; |
774 | 776 | ||
@@ -799,7 +801,7 @@ static void s3c_hsotg_complete_oursetup(struct usb_ep *ep, | |||
799 | struct usb_request *req) | 801 | struct usb_request *req) |
800 | { | 802 | { |
801 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); | 803 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); |
802 | struct s3c_hsotg *hsotg = hs_ep->parent; | 804 | struct dwc2_hsotg *hsotg = hs_ep->parent; |
803 | 805 | ||
804 | dev_dbg(hsotg->dev, "%s: ep %p, req %p\n", __func__, ep, req); | 806 | dev_dbg(hsotg->dev, "%s: ep %p, req %p\n", __func__, ep, req); |
805 | 807 | ||
@@ -814,7 +816,7 @@ static void s3c_hsotg_complete_oursetup(struct usb_ep *ep, | |||
814 | * Convert the given wIndex into a pointer to an driver endpoint | 816 | * Convert the given wIndex into a pointer to an driver endpoint |
815 | * structure, or return NULL if it is not a valid endpoint. | 817 | * structure, or return NULL if it is not a valid endpoint. |
816 | */ | 818 | */ |
817 | static struct s3c_hsotg_ep *ep_from_windex(struct s3c_hsotg *hsotg, | 819 | static struct s3c_hsotg_ep *ep_from_windex(struct dwc2_hsotg *hsotg, |
818 | u32 windex) | 820 | u32 windex) |
819 | { | 821 | { |
820 | struct s3c_hsotg_ep *ep = &hsotg->eps[windex & 0x7F]; | 822 | struct s3c_hsotg_ep *ep = &hsotg->eps[windex & 0x7F]; |
@@ -843,7 +845,7 @@ static struct s3c_hsotg_ep *ep_from_windex(struct s3c_hsotg *hsotg, | |||
843 | * Create a request and queue it on the given endpoint. This is useful as | 845 | * Create a request and queue it on the given endpoint. This is useful as |
844 | * an internal method of sending replies to certain control requests, etc. | 846 | * an internal method of sending replies to certain control requests, etc. |
845 | */ | 847 | */ |
846 | static int s3c_hsotg_send_reply(struct s3c_hsotg *hsotg, | 848 | static int s3c_hsotg_send_reply(struct dwc2_hsotg *hsotg, |
847 | struct s3c_hsotg_ep *ep, | 849 | struct s3c_hsotg_ep *ep, |
848 | void *buff, | 850 | void *buff, |
849 | int length) | 851 | int length) |
@@ -884,7 +886,7 @@ static int s3c_hsotg_send_reply(struct s3c_hsotg *hsotg, | |||
884 | * @hsotg: The device state | 886 | * @hsotg: The device state |
885 | * @ctrl: USB control request | 887 | * @ctrl: USB control request |
886 | */ | 888 | */ |
887 | static int s3c_hsotg_process_req_status(struct s3c_hsotg *hsotg, | 889 | static int s3c_hsotg_process_req_status(struct dwc2_hsotg *hsotg, |
888 | struct usb_ctrlrequest *ctrl) | 890 | struct usb_ctrlrequest *ctrl) |
889 | { | 891 | { |
890 | struct s3c_hsotg_ep *ep0 = &hsotg->eps[0]; | 892 | struct s3c_hsotg_ep *ep0 = &hsotg->eps[0]; |
@@ -955,7 +957,7 @@ static struct s3c_hsotg_req *get_ep_head(struct s3c_hsotg_ep *hs_ep) | |||
955 | * @hsotg: The device state | 957 | * @hsotg: The device state |
956 | * @ctrl: USB control request | 958 | * @ctrl: USB control request |
957 | */ | 959 | */ |
958 | static int s3c_hsotg_process_req_feature(struct s3c_hsotg *hsotg, | 960 | static int s3c_hsotg_process_req_feature(struct dwc2_hsotg *hsotg, |
959 | struct usb_ctrlrequest *ctrl) | 961 | struct usb_ctrlrequest *ctrl) |
960 | { | 962 | { |
961 | struct s3c_hsotg_ep *ep0 = &hsotg->eps[0]; | 963 | struct s3c_hsotg_ep *ep0 = &hsotg->eps[0]; |
@@ -1028,8 +1030,7 @@ static int s3c_hsotg_process_req_feature(struct s3c_hsotg *hsotg, | |||
1028 | return 1; | 1030 | return 1; |
1029 | } | 1031 | } |
1030 | 1032 | ||
1031 | static void s3c_hsotg_enqueue_setup(struct s3c_hsotg *hsotg); | 1033 | static void s3c_hsotg_enqueue_setup(struct dwc2_hsotg *hsotg); |
1032 | static void s3c_hsotg_disconnect(struct s3c_hsotg *hsotg); | ||
1033 | 1034 | ||
1034 | /** | 1035 | /** |
1035 | * s3c_hsotg_stall_ep0 - stall ep0 | 1036 | * s3c_hsotg_stall_ep0 - stall ep0 |
@@ -1037,7 +1038,7 @@ static void s3c_hsotg_disconnect(struct s3c_hsotg *hsotg); | |||
1037 | * | 1038 | * |
1038 | * Set stall for ep0 as response for setup request. | 1039 | * Set stall for ep0 as response for setup request. |
1039 | */ | 1040 | */ |
1040 | static void s3c_hsotg_stall_ep0(struct s3c_hsotg *hsotg) | 1041 | static void s3c_hsotg_stall_ep0(struct dwc2_hsotg *hsotg) |
1041 | { | 1042 | { |
1042 | struct s3c_hsotg_ep *ep0 = &hsotg->eps[0]; | 1043 | struct s3c_hsotg_ep *ep0 = &hsotg->eps[0]; |
1043 | u32 reg; | 1044 | u32 reg; |
@@ -1076,7 +1077,7 @@ static void s3c_hsotg_stall_ep0(struct s3c_hsotg *hsotg) | |||
1076 | * needs to work out what to do next (and whether to pass it on to the | 1077 | * needs to work out what to do next (and whether to pass it on to the |
1077 | * gadget driver). | 1078 | * gadget driver). |
1078 | */ | 1079 | */ |
1079 | static void s3c_hsotg_process_control(struct s3c_hsotg *hsotg, | 1080 | static void s3c_hsotg_process_control(struct dwc2_hsotg *hsotg, |
1080 | struct usb_ctrlrequest *ctrl) | 1081 | struct usb_ctrlrequest *ctrl) |
1081 | { | 1082 | { |
1082 | struct s3c_hsotg_ep *ep0 = &hsotg->eps[0]; | 1083 | struct s3c_hsotg_ep *ep0 = &hsotg->eps[0]; |
@@ -1107,7 +1108,6 @@ static void s3c_hsotg_process_control(struct s3c_hsotg *hsotg, | |||
1107 | if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) { | 1108 | if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) { |
1108 | switch (ctrl->bRequest) { | 1109 | switch (ctrl->bRequest) { |
1109 | case USB_REQ_SET_ADDRESS: | 1110 | case USB_REQ_SET_ADDRESS: |
1110 | s3c_hsotg_disconnect(hsotg); | ||
1111 | dcfg = readl(hsotg->regs + DCFG); | 1111 | dcfg = readl(hsotg->regs + DCFG); |
1112 | dcfg &= ~DCFG_DEVADDR_MASK; | 1112 | dcfg &= ~DCFG_DEVADDR_MASK; |
1113 | dcfg |= (le16_to_cpu(ctrl->wValue) << | 1113 | dcfg |= (le16_to_cpu(ctrl->wValue) << |
@@ -1161,7 +1161,7 @@ static void s3c_hsotg_complete_setup(struct usb_ep *ep, | |||
1161 | struct usb_request *req) | 1161 | struct usb_request *req) |
1162 | { | 1162 | { |
1163 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); | 1163 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); |
1164 | struct s3c_hsotg *hsotg = hs_ep->parent; | 1164 | struct dwc2_hsotg *hsotg = hs_ep->parent; |
1165 | 1165 | ||
1166 | if (req->status < 0) { | 1166 | if (req->status < 0) { |
1167 | dev_dbg(hsotg->dev, "%s: failed %d\n", __func__, req->status); | 1167 | dev_dbg(hsotg->dev, "%s: failed %d\n", __func__, req->status); |
@@ -1183,7 +1183,7 @@ static void s3c_hsotg_complete_setup(struct usb_ep *ep, | |||
1183 | * Enqueue a request on EP0 if necessary to received any SETUP packets | 1183 | * Enqueue a request on EP0 if necessary to received any SETUP packets |
1184 | * received from the host. | 1184 | * received from the host. |
1185 | */ | 1185 | */ |
1186 | static void s3c_hsotg_enqueue_setup(struct s3c_hsotg *hsotg) | 1186 | static void s3c_hsotg_enqueue_setup(struct dwc2_hsotg *hsotg) |
1187 | { | 1187 | { |
1188 | struct usb_request *req = hsotg->ctrl_req; | 1188 | struct usb_request *req = hsotg->ctrl_req; |
1189 | struct s3c_hsotg_req *hs_req = our_req(req); | 1189 | struct s3c_hsotg_req *hs_req = our_req(req); |
@@ -1226,7 +1226,7 @@ static void s3c_hsotg_enqueue_setup(struct s3c_hsotg *hsotg) | |||
1226 | * | 1226 | * |
1227 | * Note, expects the ep to already be locked as appropriate. | 1227 | * Note, expects the ep to already be locked as appropriate. |
1228 | */ | 1228 | */ |
1229 | static void s3c_hsotg_complete_request(struct s3c_hsotg *hsotg, | 1229 | static void s3c_hsotg_complete_request(struct dwc2_hsotg *hsotg, |
1230 | struct s3c_hsotg_ep *hs_ep, | 1230 | struct s3c_hsotg_ep *hs_ep, |
1231 | struct s3c_hsotg_req *hs_req, | 1231 | struct s3c_hsotg_req *hs_req, |
1232 | int result) | 1232 | int result) |
@@ -1291,7 +1291,7 @@ static void s3c_hsotg_complete_request(struct s3c_hsotg *hsotg, | |||
1291 | * endpoint, so sort out whether we need to read the data into a request | 1291 | * endpoint, so sort out whether we need to read the data into a request |
1292 | * that has been made for that endpoint. | 1292 | * that has been made for that endpoint. |
1293 | */ | 1293 | */ |
1294 | static void s3c_hsotg_rx_data(struct s3c_hsotg *hsotg, int ep_idx, int size) | 1294 | static void s3c_hsotg_rx_data(struct dwc2_hsotg *hsotg, int ep_idx, int size) |
1295 | { | 1295 | { |
1296 | struct s3c_hsotg_ep *hs_ep = &hsotg->eps[ep_idx]; | 1296 | struct s3c_hsotg_ep *hs_ep = &hsotg->eps[ep_idx]; |
1297 | struct s3c_hsotg_req *hs_req = hs_ep->req; | 1297 | struct s3c_hsotg_req *hs_req = hs_ep->req; |
@@ -1356,7 +1356,7 @@ static void s3c_hsotg_rx_data(struct s3c_hsotg *hsotg, int ep_idx, int size) | |||
1356 | * currently believed that we do not need to wait for any space in | 1356 | * currently believed that we do not need to wait for any space in |
1357 | * the TxFIFO. | 1357 | * the TxFIFO. |
1358 | */ | 1358 | */ |
1359 | static void s3c_hsotg_send_zlp(struct s3c_hsotg *hsotg, | 1359 | static void s3c_hsotg_send_zlp(struct dwc2_hsotg *hsotg, |
1360 | struct s3c_hsotg_req *req) | 1360 | struct s3c_hsotg_req *req) |
1361 | { | 1361 | { |
1362 | u32 ctrl; | 1362 | u32 ctrl; |
@@ -1398,7 +1398,7 @@ static void s3c_hsotg_send_zlp(struct s3c_hsotg *hsotg, | |||
1398 | * transfer for an OUT endpoint has been completed, either by a short | 1398 | * transfer for an OUT endpoint has been completed, either by a short |
1399 | * packet or by the finish of a transfer. | 1399 | * packet or by the finish of a transfer. |
1400 | */ | 1400 | */ |
1401 | static void s3c_hsotg_handle_outdone(struct s3c_hsotg *hsotg, | 1401 | static void s3c_hsotg_handle_outdone(struct dwc2_hsotg *hsotg, |
1402 | int epnum, bool was_setup) | 1402 | int epnum, bool was_setup) |
1403 | { | 1403 | { |
1404 | u32 epsize = readl(hsotg->regs + DOEPTSIZ(epnum)); | 1404 | u32 epsize = readl(hsotg->regs + DOEPTSIZ(epnum)); |
@@ -1471,7 +1471,7 @@ static void s3c_hsotg_handle_outdone(struct s3c_hsotg *hsotg, | |||
1471 | * | 1471 | * |
1472 | * Return the current frame number | 1472 | * Return the current frame number |
1473 | */ | 1473 | */ |
1474 | static u32 s3c_hsotg_read_frameno(struct s3c_hsotg *hsotg) | 1474 | static u32 s3c_hsotg_read_frameno(struct dwc2_hsotg *hsotg) |
1475 | { | 1475 | { |
1476 | u32 dsts; | 1476 | u32 dsts; |
1477 | 1477 | ||
@@ -1498,7 +1498,7 @@ static u32 s3c_hsotg_read_frameno(struct s3c_hsotg *hsotg) | |||
1498 | * as the actual data should be sent to the memory directly and we turn | 1498 | * as the actual data should be sent to the memory directly and we turn |
1499 | * on the completion interrupts to get notifications of transfer completion. | 1499 | * on the completion interrupts to get notifications of transfer completion. |
1500 | */ | 1500 | */ |
1501 | static void s3c_hsotg_handle_rx(struct s3c_hsotg *hsotg) | 1501 | static void s3c_hsotg_handle_rx(struct dwc2_hsotg *hsotg) |
1502 | { | 1502 | { |
1503 | u32 grxstsr = readl(hsotg->regs + GRXSTSP); | 1503 | u32 grxstsr = readl(hsotg->regs + GRXSTSP); |
1504 | u32 epnum, status, size; | 1504 | u32 epnum, status, size; |
@@ -1590,7 +1590,7 @@ static u32 s3c_hsotg_ep0_mps(unsigned int mps) | |||
1590 | * Configure the maximum packet size for the given endpoint, updating | 1590 | * Configure the maximum packet size for the given endpoint, updating |
1591 | * the hardware control registers to reflect this. | 1591 | * the hardware control registers to reflect this. |
1592 | */ | 1592 | */ |
1593 | static void s3c_hsotg_set_ep_maxpacket(struct s3c_hsotg *hsotg, | 1593 | static void s3c_hsotg_set_ep_maxpacket(struct dwc2_hsotg *hsotg, |
1594 | unsigned int ep, unsigned int mps) | 1594 | unsigned int ep, unsigned int mps) |
1595 | { | 1595 | { |
1596 | struct s3c_hsotg_ep *hs_ep = &hsotg->eps[ep]; | 1596 | struct s3c_hsotg_ep *hs_ep = &hsotg->eps[ep]; |
@@ -1645,7 +1645,7 @@ bad_mps: | |||
1645 | * @hsotg: The driver state | 1645 | * @hsotg: The driver state |
1646 | * @idx: The index for the endpoint (0..15) | 1646 | * @idx: The index for the endpoint (0..15) |
1647 | */ | 1647 | */ |
1648 | static void s3c_hsotg_txfifo_flush(struct s3c_hsotg *hsotg, unsigned int idx) | 1648 | static void s3c_hsotg_txfifo_flush(struct dwc2_hsotg *hsotg, unsigned int idx) |
1649 | { | 1649 | { |
1650 | int timeout; | 1650 | int timeout; |
1651 | int val; | 1651 | int val; |
@@ -1681,7 +1681,7 @@ static void s3c_hsotg_txfifo_flush(struct s3c_hsotg *hsotg, unsigned int idx) | |||
1681 | * Check to see if there is a request that has data to send, and if so | 1681 | * Check to see if there is a request that has data to send, and if so |
1682 | * make an attempt to write data into the FIFO. | 1682 | * make an attempt to write data into the FIFO. |
1683 | */ | 1683 | */ |
1684 | static int s3c_hsotg_trytx(struct s3c_hsotg *hsotg, | 1684 | static int s3c_hsotg_trytx(struct dwc2_hsotg *hsotg, |
1685 | struct s3c_hsotg_ep *hs_ep) | 1685 | struct s3c_hsotg_ep *hs_ep) |
1686 | { | 1686 | { |
1687 | struct s3c_hsotg_req *hs_req = hs_ep->req; | 1687 | struct s3c_hsotg_req *hs_req = hs_ep->req; |
@@ -1714,7 +1714,7 @@ static int s3c_hsotg_trytx(struct s3c_hsotg *hsotg, | |||
1714 | * An IN transfer has been completed, update the transfer's state and then | 1714 | * An IN transfer has been completed, update the transfer's state and then |
1715 | * call the relevant completion routines. | 1715 | * call the relevant completion routines. |
1716 | */ | 1716 | */ |
1717 | static void s3c_hsotg_complete_in(struct s3c_hsotg *hsotg, | 1717 | static void s3c_hsotg_complete_in(struct dwc2_hsotg *hsotg, |
1718 | struct s3c_hsotg_ep *hs_ep) | 1718 | struct s3c_hsotg_ep *hs_ep) |
1719 | { | 1719 | { |
1720 | struct s3c_hsotg_req *hs_req = hs_ep->req; | 1720 | struct s3c_hsotg_req *hs_req = hs_ep->req; |
@@ -1791,7 +1791,7 @@ static void s3c_hsotg_complete_in(struct s3c_hsotg *hsotg, | |||
1791 | * | 1791 | * |
1792 | * Process and clear any interrupt pending for an individual endpoint | 1792 | * Process and clear any interrupt pending for an individual endpoint |
1793 | */ | 1793 | */ |
1794 | static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx, | 1794 | static void s3c_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx, |
1795 | int dir_in) | 1795 | int dir_in) |
1796 | { | 1796 | { |
1797 | struct s3c_hsotg_ep *hs_ep = &hsotg->eps[idx]; | 1797 | struct s3c_hsotg_ep *hs_ep = &hsotg->eps[idx]; |
@@ -1916,7 +1916,7 @@ static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx, | |||
1916 | * Handle updating the device settings after the enumeration phase has | 1916 | * Handle updating the device settings after the enumeration phase has |
1917 | * been completed. | 1917 | * been completed. |
1918 | */ | 1918 | */ |
1919 | static void s3c_hsotg_irq_enumdone(struct s3c_hsotg *hsotg) | 1919 | static void s3c_hsotg_irq_enumdone(struct dwc2_hsotg *hsotg) |
1920 | { | 1920 | { |
1921 | u32 dsts = readl(hsotg->regs + DSTS); | 1921 | u32 dsts = readl(hsotg->regs + DSTS); |
1922 | int ep0_mps = 0, ep_mps = 8; | 1922 | int ep0_mps = 0, ep_mps = 8; |
@@ -1993,7 +1993,7 @@ static void s3c_hsotg_irq_enumdone(struct s3c_hsotg *hsotg) | |||
1993 | * Go through the requests on the given endpoint and mark them | 1993 | * Go through the requests on the given endpoint and mark them |
1994 | * completed with the given result code. | 1994 | * completed with the given result code. |
1995 | */ | 1995 | */ |
1996 | static void kill_all_requests(struct s3c_hsotg *hsotg, | 1996 | static void kill_all_requests(struct dwc2_hsotg *hsotg, |
1997 | struct s3c_hsotg_ep *ep, | 1997 | struct s3c_hsotg_ep *ep, |
1998 | int result, bool force) | 1998 | int result, bool force) |
1999 | { | 1999 | { |
@@ -2027,22 +2027,27 @@ static void kill_all_requests(struct s3c_hsotg *hsotg, | |||
2027 | * transactions and signal the gadget driver that this | 2027 | * transactions and signal the gadget driver that this |
2028 | * has happened. | 2028 | * has happened. |
2029 | */ | 2029 | */ |
2030 | static void s3c_hsotg_disconnect(struct s3c_hsotg *hsotg) | 2030 | void s3c_hsotg_disconnect(struct dwc2_hsotg *hsotg) |
2031 | { | 2031 | { |
2032 | unsigned ep; | 2032 | unsigned ep; |
2033 | 2033 | ||
2034 | if (!hsotg->connected) | ||
2035 | return; | ||
2036 | |||
2037 | hsotg->connected = 0; | ||
2034 | for (ep = 0; ep < hsotg->num_of_eps; ep++) | 2038 | for (ep = 0; ep < hsotg->num_of_eps; ep++) |
2035 | kill_all_requests(hsotg, &hsotg->eps[ep], -ESHUTDOWN, true); | 2039 | kill_all_requests(hsotg, &hsotg->eps[ep], -ESHUTDOWN, true); |
2036 | 2040 | ||
2037 | call_gadget(hsotg, disconnect); | 2041 | call_gadget(hsotg, disconnect); |
2038 | } | 2042 | } |
2043 | EXPORT_SYMBOL_GPL(s3c_hsotg_disconnect); | ||
2039 | 2044 | ||
2040 | /** | 2045 | /** |
2041 | * s3c_hsotg_irq_fifoempty - TX FIFO empty interrupt handler | 2046 | * s3c_hsotg_irq_fifoempty - TX FIFO empty interrupt handler |
2042 | * @hsotg: The device state: | 2047 | * @hsotg: The device state: |
2043 | * @periodic: True if this is a periodic FIFO interrupt | 2048 | * @periodic: True if this is a periodic FIFO interrupt |
2044 | */ | 2049 | */ |
2045 | static void s3c_hsotg_irq_fifoempty(struct s3c_hsotg *hsotg, bool periodic) | 2050 | static void s3c_hsotg_irq_fifoempty(struct dwc2_hsotg *hsotg, bool periodic) |
2046 | { | 2051 | { |
2047 | struct s3c_hsotg_ep *ep; | 2052 | struct s3c_hsotg_ep *ep; |
2048 | int epno, ret; | 2053 | int epno, ret; |
@@ -2076,7 +2081,7 @@ static void s3c_hsotg_irq_fifoempty(struct s3c_hsotg *hsotg, bool periodic) | |||
2076 | * | 2081 | * |
2077 | * Issue a soft reset to the core, and await the core finishing it. | 2082 | * Issue a soft reset to the core, and await the core finishing it. |
2078 | */ | 2083 | */ |
2079 | static int s3c_hsotg_corereset(struct s3c_hsotg *hsotg) | 2084 | static int s3c_hsotg_corereset(struct dwc2_hsotg *hsotg) |
2080 | { | 2085 | { |
2081 | int timeout; | 2086 | int timeout; |
2082 | u32 grstctl; | 2087 | u32 grstctl; |
@@ -2124,7 +2129,7 @@ static int s3c_hsotg_corereset(struct s3c_hsotg *hsotg) | |||
2124 | * | 2129 | * |
2125 | * Issue a soft reset to the core, and await the core finishing it. | 2130 | * Issue a soft reset to the core, and await the core finishing it. |
2126 | */ | 2131 | */ |
2127 | static void s3c_hsotg_core_init(struct s3c_hsotg *hsotg) | 2132 | void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg) |
2128 | { | 2133 | { |
2129 | s3c_hsotg_corereset(hsotg); | 2134 | s3c_hsotg_corereset(hsotg); |
2130 | 2135 | ||
@@ -2241,12 +2246,23 @@ static void s3c_hsotg_core_init(struct s3c_hsotg *hsotg) | |||
2241 | readl(hsotg->regs + DOEPCTL0)); | 2246 | readl(hsotg->regs + DOEPCTL0)); |
2242 | 2247 | ||
2243 | /* clear global NAKs */ | 2248 | /* clear global NAKs */ |
2244 | writel(DCTL_CGOUTNAK | DCTL_CGNPINNAK, | 2249 | writel(DCTL_CGOUTNAK | DCTL_CGNPINNAK | DCTL_SFTDISCON, |
2245 | hsotg->regs + DCTL); | 2250 | hsotg->regs + DCTL); |
2246 | 2251 | ||
2247 | /* must be at-least 3ms to allow bus to see disconnect */ | 2252 | /* must be at-least 3ms to allow bus to see disconnect */ |
2248 | mdelay(3); | 2253 | mdelay(3); |
2249 | 2254 | ||
2255 | hsotg->last_rst = jiffies; | ||
2256 | } | ||
2257 | |||
2258 | static void s3c_hsotg_core_disconnect(struct dwc2_hsotg *hsotg) | ||
2259 | { | ||
2260 | /* set the soft-disconnect bit */ | ||
2261 | __orr32(hsotg->regs + DCTL, DCTL_SFTDISCON); | ||
2262 | } | ||
2263 | |||
2264 | void s3c_hsotg_core_connect(struct dwc2_hsotg *hsotg) | ||
2265 | { | ||
2250 | /* remove the soft-disconnect and let's go */ | 2266 | /* remove the soft-disconnect and let's go */ |
2251 | __bic32(hsotg->regs + DCTL, DCTL_SFTDISCON); | 2267 | __bic32(hsotg->regs + DCTL, DCTL_SFTDISCON); |
2252 | } | 2268 | } |
@@ -2258,7 +2274,7 @@ static void s3c_hsotg_core_init(struct s3c_hsotg *hsotg) | |||
2258 | */ | 2274 | */ |
2259 | static irqreturn_t s3c_hsotg_irq(int irq, void *pw) | 2275 | static irqreturn_t s3c_hsotg_irq(int irq, void *pw) |
2260 | { | 2276 | { |
2261 | struct s3c_hsotg *hsotg = pw; | 2277 | struct dwc2_hsotg *hsotg = pw; |
2262 | int retry_count = 8; | 2278 | int retry_count = 8; |
2263 | u32 gintsts; | 2279 | u32 gintsts; |
2264 | u32 gintmsk; | 2280 | u32 gintmsk; |
@@ -2273,31 +2289,11 @@ irq_retry: | |||
2273 | 2289 | ||
2274 | gintsts &= gintmsk; | 2290 | gintsts &= gintmsk; |
2275 | 2291 | ||
2276 | if (gintsts & GINTSTS_OTGINT) { | ||
2277 | u32 otgint = readl(hsotg->regs + GOTGINT); | ||
2278 | |||
2279 | dev_info(hsotg->dev, "OTGInt: %08x\n", otgint); | ||
2280 | |||
2281 | writel(otgint, hsotg->regs + GOTGINT); | ||
2282 | } | ||
2283 | |||
2284 | if (gintsts & GINTSTS_SESSREQINT) { | ||
2285 | dev_dbg(hsotg->dev, "%s: SessReqInt\n", __func__); | ||
2286 | writel(GINTSTS_SESSREQINT, hsotg->regs + GINTSTS); | ||
2287 | } | ||
2288 | |||
2289 | if (gintsts & GINTSTS_ENUMDONE) { | 2292 | if (gintsts & GINTSTS_ENUMDONE) { |
2290 | writel(GINTSTS_ENUMDONE, hsotg->regs + GINTSTS); | 2293 | writel(GINTSTS_ENUMDONE, hsotg->regs + GINTSTS); |
2291 | 2294 | ||
2292 | s3c_hsotg_irq_enumdone(hsotg); | 2295 | s3c_hsotg_irq_enumdone(hsotg); |
2293 | } | 2296 | hsotg->connected = 1; |
2294 | |||
2295 | if (gintsts & GINTSTS_CONIDSTSCHNG) { | ||
2296 | dev_dbg(hsotg->dev, "ConIDStsChg (DSTS=0x%08x, GOTCTL=%08x)\n", | ||
2297 | readl(hsotg->regs + DSTS), | ||
2298 | readl(hsotg->regs + GOTGCTL)); | ||
2299 | |||
2300 | writel(GINTSTS_CONIDSTSCHNG, hsotg->regs + GINTSTS); | ||
2301 | } | 2297 | } |
2302 | 2298 | ||
2303 | if (gintsts & (GINTSTS_OEPINT | GINTSTS_IEPINT)) { | 2299 | if (gintsts & (GINTSTS_OEPINT | GINTSTS_IEPINT)) { |
@@ -2340,8 +2336,8 @@ irq_retry: | |||
2340 | kill_all_requests(hsotg, &hsotg->eps[0], | 2336 | kill_all_requests(hsotg, &hsotg->eps[0], |
2341 | -ECONNRESET, true); | 2337 | -ECONNRESET, true); |
2342 | 2338 | ||
2343 | s3c_hsotg_core_init(hsotg); | 2339 | s3c_hsotg_core_init_disconnected(hsotg); |
2344 | hsotg->last_rst = jiffies; | 2340 | s3c_hsotg_core_connect(hsotg); |
2345 | } | 2341 | } |
2346 | } | 2342 | } |
2347 | } | 2343 | } |
@@ -2380,25 +2376,6 @@ irq_retry: | |||
2380 | s3c_hsotg_handle_rx(hsotg); | 2376 | s3c_hsotg_handle_rx(hsotg); |
2381 | } | 2377 | } |
2382 | 2378 | ||
2383 | if (gintsts & GINTSTS_MODEMIS) { | ||
2384 | dev_warn(hsotg->dev, "warning, mode mismatch triggered\n"); | ||
2385 | writel(GINTSTS_MODEMIS, hsotg->regs + GINTSTS); | ||
2386 | } | ||
2387 | |||
2388 | if (gintsts & GINTSTS_USBSUSP) { | ||
2389 | dev_info(hsotg->dev, "GINTSTS_USBSusp\n"); | ||
2390 | writel(GINTSTS_USBSUSP, hsotg->regs + GINTSTS); | ||
2391 | |||
2392 | call_gadget(hsotg, suspend); | ||
2393 | } | ||
2394 | |||
2395 | if (gintsts & GINTSTS_WKUPINT) { | ||
2396 | dev_info(hsotg->dev, "GINTSTS_WkUpIn\n"); | ||
2397 | writel(GINTSTS_WKUPINT, hsotg->regs + GINTSTS); | ||
2398 | |||
2399 | call_gadget(hsotg, resume); | ||
2400 | } | ||
2401 | |||
2402 | if (gintsts & GINTSTS_ERLYSUSP) { | 2379 | if (gintsts & GINTSTS_ERLYSUSP) { |
2403 | dev_dbg(hsotg->dev, "GINTSTS_ErlySusp\n"); | 2380 | dev_dbg(hsotg->dev, "GINTSTS_ErlySusp\n"); |
2404 | writel(GINTSTS_ERLYSUSP, hsotg->regs + GINTSTS); | 2381 | writel(GINTSTS_ERLYSUSP, hsotg->regs + GINTSTS); |
@@ -2450,7 +2427,7 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep, | |||
2450 | const struct usb_endpoint_descriptor *desc) | 2427 | const struct usb_endpoint_descriptor *desc) |
2451 | { | 2428 | { |
2452 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); | 2429 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); |
2453 | struct s3c_hsotg *hsotg = hs_ep->parent; | 2430 | struct dwc2_hsotg *hsotg = hs_ep->parent; |
2454 | unsigned long flags; | 2431 | unsigned long flags; |
2455 | int index = hs_ep->index; | 2432 | int index = hs_ep->index; |
2456 | u32 epctrl_reg; | 2433 | u32 epctrl_reg; |
@@ -2593,7 +2570,7 @@ error: | |||
2593 | static int s3c_hsotg_ep_disable(struct usb_ep *ep) | 2570 | static int s3c_hsotg_ep_disable(struct usb_ep *ep) |
2594 | { | 2571 | { |
2595 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); | 2572 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); |
2596 | struct s3c_hsotg *hsotg = hs_ep->parent; | 2573 | struct dwc2_hsotg *hsotg = hs_ep->parent; |
2597 | int dir_in = hs_ep->dir_in; | 2574 | int dir_in = hs_ep->dir_in; |
2598 | int index = hs_ep->index; | 2575 | int index = hs_ep->index; |
2599 | unsigned long flags; | 2576 | unsigned long flags; |
@@ -2658,7 +2635,7 @@ static int s3c_hsotg_ep_dequeue(struct usb_ep *ep, struct usb_request *req) | |||
2658 | { | 2635 | { |
2659 | struct s3c_hsotg_req *hs_req = our_req(req); | 2636 | struct s3c_hsotg_req *hs_req = our_req(req); |
2660 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); | 2637 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); |
2661 | struct s3c_hsotg *hs = hs_ep->parent; | 2638 | struct dwc2_hsotg *hs = hs_ep->parent; |
2662 | unsigned long flags; | 2639 | unsigned long flags; |
2663 | 2640 | ||
2664 | dev_dbg(hs->dev, "ep_dequeue(%p,%p)\n", ep, req); | 2641 | dev_dbg(hs->dev, "ep_dequeue(%p,%p)\n", ep, req); |
@@ -2684,7 +2661,7 @@ static int s3c_hsotg_ep_dequeue(struct usb_ep *ep, struct usb_request *req) | |||
2684 | static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value) | 2661 | static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value) |
2685 | { | 2662 | { |
2686 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); | 2663 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); |
2687 | struct s3c_hsotg *hs = hs_ep->parent; | 2664 | struct dwc2_hsotg *hs = hs_ep->parent; |
2688 | int index = hs_ep->index; | 2665 | int index = hs_ep->index; |
2689 | u32 epreg; | 2666 | u32 epreg; |
2690 | u32 epctl; | 2667 | u32 epctl; |
@@ -2748,7 +2725,7 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value) | |||
2748 | static int s3c_hsotg_ep_sethalt_lock(struct usb_ep *ep, int value) | 2725 | static int s3c_hsotg_ep_sethalt_lock(struct usb_ep *ep, int value) |
2749 | { | 2726 | { |
2750 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); | 2727 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); |
2751 | struct s3c_hsotg *hs = hs_ep->parent; | 2728 | struct dwc2_hsotg *hs = hs_ep->parent; |
2752 | unsigned long flags = 0; | 2729 | unsigned long flags = 0; |
2753 | int ret = 0; | 2730 | int ret = 0; |
2754 | 2731 | ||
@@ -2777,7 +2754,7 @@ static struct usb_ep_ops s3c_hsotg_ep_ops = { | |||
2777 | * A wrapper for platform code responsible for controlling | 2754 | * A wrapper for platform code responsible for controlling |
2778 | * low-level USB code | 2755 | * low-level USB code |
2779 | */ | 2756 | */ |
2780 | static void s3c_hsotg_phy_enable(struct s3c_hsotg *hsotg) | 2757 | static void s3c_hsotg_phy_enable(struct dwc2_hsotg *hsotg) |
2781 | { | 2758 | { |
2782 | struct platform_device *pdev = to_platform_device(hsotg->dev); | 2759 | struct platform_device *pdev = to_platform_device(hsotg->dev); |
2783 | 2760 | ||
@@ -2800,7 +2777,7 @@ static void s3c_hsotg_phy_enable(struct s3c_hsotg *hsotg) | |||
2800 | * A wrapper for platform code responsible for controlling | 2777 | * A wrapper for platform code responsible for controlling |
2801 | * low-level USB code | 2778 | * low-level USB code |
2802 | */ | 2779 | */ |
2803 | static void s3c_hsotg_phy_disable(struct s3c_hsotg *hsotg) | 2780 | static void s3c_hsotg_phy_disable(struct dwc2_hsotg *hsotg) |
2804 | { | 2781 | { |
2805 | struct platform_device *pdev = to_platform_device(hsotg->dev); | 2782 | struct platform_device *pdev = to_platform_device(hsotg->dev); |
2806 | 2783 | ||
@@ -2818,7 +2795,7 @@ static void s3c_hsotg_phy_disable(struct s3c_hsotg *hsotg) | |||
2818 | * s3c_hsotg_init - initalize the usb core | 2795 | * s3c_hsotg_init - initalize the usb core |
2819 | * @hsotg: The driver state | 2796 | * @hsotg: The driver state |
2820 | */ | 2797 | */ |
2821 | static void s3c_hsotg_init(struct s3c_hsotg *hsotg) | 2798 | static void s3c_hsotg_init(struct dwc2_hsotg *hsotg) |
2822 | { | 2799 | { |
2823 | /* unmask subset of endpoint interrupts */ | 2800 | /* unmask subset of endpoint interrupts */ |
2824 | 2801 | ||
@@ -2868,7 +2845,8 @@ static void s3c_hsotg_init(struct s3c_hsotg *hsotg) | |||
2868 | static int s3c_hsotg_udc_start(struct usb_gadget *gadget, | 2845 | static int s3c_hsotg_udc_start(struct usb_gadget *gadget, |
2869 | struct usb_gadget_driver *driver) | 2846 | struct usb_gadget_driver *driver) |
2870 | { | 2847 | { |
2871 | struct s3c_hsotg *hsotg = to_hsotg(gadget); | 2848 | struct dwc2_hsotg *hsotg = to_hsotg(gadget); |
2849 | unsigned long flags; | ||
2872 | int ret; | 2850 | int ret; |
2873 | 2851 | ||
2874 | if (!hsotg) { | 2852 | if (!hsotg) { |
@@ -2889,6 +2867,7 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget, | |||
2889 | return -EINVAL; | 2867 | return -EINVAL; |
2890 | } | 2868 | } |
2891 | 2869 | ||
2870 | mutex_lock(&hsotg->init_mutex); | ||
2892 | WARN_ON(hsotg->driver); | 2871 | WARN_ON(hsotg->driver); |
2893 | 2872 | ||
2894 | driver->driver.bus = NULL; | 2873 | driver->driver.bus = NULL; |
@@ -2905,11 +2884,22 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget, | |||
2905 | goto err; | 2884 | goto err; |
2906 | } | 2885 | } |
2907 | 2886 | ||
2908 | hsotg->last_rst = jiffies; | 2887 | s3c_hsotg_phy_enable(hsotg); |
2888 | |||
2889 | spin_lock_irqsave(&hsotg->lock, flags); | ||
2890 | s3c_hsotg_init(hsotg); | ||
2891 | s3c_hsotg_core_init_disconnected(hsotg); | ||
2892 | hsotg->enabled = 0; | ||
2893 | spin_unlock_irqrestore(&hsotg->lock, flags); | ||
2894 | |||
2909 | dev_info(hsotg->dev, "bound driver %s\n", driver->driver.name); | 2895 | dev_info(hsotg->dev, "bound driver %s\n", driver->driver.name); |
2896 | |||
2897 | mutex_unlock(&hsotg->init_mutex); | ||
2898 | |||
2910 | return 0; | 2899 | return 0; |
2911 | 2900 | ||
2912 | err: | 2901 | err: |
2902 | mutex_unlock(&hsotg->init_mutex); | ||
2913 | hsotg->driver = NULL; | 2903 | hsotg->driver = NULL; |
2914 | return ret; | 2904 | return ret; |
2915 | } | 2905 | } |
@@ -2921,16 +2911,17 @@ err: | |||
2921 | * | 2911 | * |
2922 | * Stop udc hw block and stay tunned for future transmissions | 2912 | * Stop udc hw block and stay tunned for future transmissions |
2923 | */ | 2913 | */ |
2924 | static int s3c_hsotg_udc_stop(struct usb_gadget *gadget, | 2914 | static int s3c_hsotg_udc_stop(struct usb_gadget *gadget) |
2925 | struct usb_gadget_driver *driver) | ||
2926 | { | 2915 | { |
2927 | struct s3c_hsotg *hsotg = to_hsotg(gadget); | 2916 | struct dwc2_hsotg *hsotg = to_hsotg(gadget); |
2928 | unsigned long flags = 0; | 2917 | unsigned long flags = 0; |
2929 | int ep; | 2918 | int ep; |
2930 | 2919 | ||
2931 | if (!hsotg) | 2920 | if (!hsotg) |
2932 | return -ENODEV; | 2921 | return -ENODEV; |
2933 | 2922 | ||
2923 | mutex_lock(&hsotg->init_mutex); | ||
2924 | |||
2934 | /* all endpoints should be shutdown */ | 2925 | /* all endpoints should be shutdown */ |
2935 | for (ep = 1; ep < hsotg->num_of_eps; ep++) | 2926 | for (ep = 1; ep < hsotg->num_of_eps; ep++) |
2936 | s3c_hsotg_ep_disable(&hsotg->eps[ep].ep); | 2927 | s3c_hsotg_ep_disable(&hsotg->eps[ep].ep); |
@@ -2939,13 +2930,18 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget, | |||
2939 | 2930 | ||
2940 | hsotg->driver = NULL; | 2931 | hsotg->driver = NULL; |
2941 | hsotg->gadget.speed = USB_SPEED_UNKNOWN; | 2932 | hsotg->gadget.speed = USB_SPEED_UNKNOWN; |
2933 | hsotg->enabled = 0; | ||
2942 | 2934 | ||
2943 | spin_unlock_irqrestore(&hsotg->lock, flags); | 2935 | spin_unlock_irqrestore(&hsotg->lock, flags); |
2944 | 2936 | ||
2937 | s3c_hsotg_phy_disable(hsotg); | ||
2938 | |||
2945 | regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); | 2939 | regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); |
2946 | 2940 | ||
2947 | clk_disable(hsotg->clk); | 2941 | clk_disable(hsotg->clk); |
2948 | 2942 | ||
2943 | mutex_unlock(&hsotg->init_mutex); | ||
2944 | |||
2949 | return 0; | 2945 | return 0; |
2950 | } | 2946 | } |
2951 | 2947 | ||
@@ -2969,23 +2965,26 @@ static int s3c_hsotg_gadget_getframe(struct usb_gadget *gadget) | |||
2969 | */ | 2965 | */ |
2970 | static int s3c_hsotg_pullup(struct usb_gadget *gadget, int is_on) | 2966 | static int s3c_hsotg_pullup(struct usb_gadget *gadget, int is_on) |
2971 | { | 2967 | { |
2972 | struct s3c_hsotg *hsotg = to_hsotg(gadget); | 2968 | struct dwc2_hsotg *hsotg = to_hsotg(gadget); |
2973 | unsigned long flags = 0; | 2969 | unsigned long flags = 0; |
2974 | 2970 | ||
2975 | dev_dbg(hsotg->dev, "%s: is_on: %d\n", __func__, is_on); | 2971 | dev_dbg(hsotg->dev, "%s: is_on: %d\n", __func__, is_on); |
2976 | 2972 | ||
2973 | mutex_lock(&hsotg->init_mutex); | ||
2977 | spin_lock_irqsave(&hsotg->lock, flags); | 2974 | spin_lock_irqsave(&hsotg->lock, flags); |
2978 | if (is_on) { | 2975 | if (is_on) { |
2979 | s3c_hsotg_phy_enable(hsotg); | ||
2980 | clk_enable(hsotg->clk); | 2976 | clk_enable(hsotg->clk); |
2981 | s3c_hsotg_core_init(hsotg); | 2977 | hsotg->enabled = 1; |
2978 | s3c_hsotg_core_connect(hsotg); | ||
2982 | } else { | 2979 | } else { |
2980 | s3c_hsotg_core_disconnect(hsotg); | ||
2981 | hsotg->enabled = 0; | ||
2983 | clk_disable(hsotg->clk); | 2982 | clk_disable(hsotg->clk); |
2984 | s3c_hsotg_phy_disable(hsotg); | ||
2985 | } | 2983 | } |
2986 | 2984 | ||
2987 | hsotg->gadget.speed = USB_SPEED_UNKNOWN; | 2985 | hsotg->gadget.speed = USB_SPEED_UNKNOWN; |
2988 | spin_unlock_irqrestore(&hsotg->lock, flags); | 2986 | spin_unlock_irqrestore(&hsotg->lock, flags); |
2987 | mutex_unlock(&hsotg->init_mutex); | ||
2989 | 2988 | ||
2990 | return 0; | 2989 | return 0; |
2991 | } | 2990 | } |
@@ -3007,7 +3006,7 @@ static const struct usb_gadget_ops s3c_hsotg_gadget_ops = { | |||
3007 | * creation) to give to the gadget driver. Setup the endpoint name, any | 3006 | * creation) to give to the gadget driver. Setup the endpoint name, any |
3008 | * direction information and other state that may be required. | 3007 | * direction information and other state that may be required. |
3009 | */ | 3008 | */ |
3010 | static void s3c_hsotg_initep(struct s3c_hsotg *hsotg, | 3009 | static void s3c_hsotg_initep(struct dwc2_hsotg *hsotg, |
3011 | struct s3c_hsotg_ep *hs_ep, | 3010 | struct s3c_hsotg_ep *hs_ep, |
3012 | int epnum) | 3011 | int epnum) |
3013 | { | 3012 | { |
@@ -3056,7 +3055,7 @@ static void s3c_hsotg_initep(struct s3c_hsotg *hsotg, | |||
3056 | * | 3055 | * |
3057 | * Read the USB core HW configuration registers | 3056 | * Read the USB core HW configuration registers |
3058 | */ | 3057 | */ |
3059 | static void s3c_hsotg_hw_cfg(struct s3c_hsotg *hsotg) | 3058 | static void s3c_hsotg_hw_cfg(struct dwc2_hsotg *hsotg) |
3060 | { | 3059 | { |
3061 | u32 cfg2, cfg3, cfg4; | 3060 | u32 cfg2, cfg3, cfg4; |
3062 | /* check hardware configuration */ | 3061 | /* check hardware configuration */ |
@@ -3080,7 +3079,7 @@ static void s3c_hsotg_hw_cfg(struct s3c_hsotg *hsotg) | |||
3080 | * s3c_hsotg_dump - dump state of the udc | 3079 | * s3c_hsotg_dump - dump state of the udc |
3081 | * @param: The device state | 3080 | * @param: The device state |
3082 | */ | 3081 | */ |
3083 | static void s3c_hsotg_dump(struct s3c_hsotg *hsotg) | 3082 | static void s3c_hsotg_dump(struct dwc2_hsotg *hsotg) |
3084 | { | 3083 | { |
3085 | #ifdef DEBUG | 3084 | #ifdef DEBUG |
3086 | struct device *dev = hsotg->dev; | 3085 | struct device *dev = hsotg->dev; |
@@ -3139,7 +3138,7 @@ static void s3c_hsotg_dump(struct s3c_hsotg *hsotg) | |||
3139 | */ | 3138 | */ |
3140 | static int state_show(struct seq_file *seq, void *v) | 3139 | static int state_show(struct seq_file *seq, void *v) |
3141 | { | 3140 | { |
3142 | struct s3c_hsotg *hsotg = seq->private; | 3141 | struct dwc2_hsotg *hsotg = seq->private; |
3143 | void __iomem *regs = hsotg->regs; | 3142 | void __iomem *regs = hsotg->regs; |
3144 | int idx; | 3143 | int idx; |
3145 | 3144 | ||
@@ -3209,7 +3208,7 @@ static const struct file_operations state_fops = { | |||
3209 | */ | 3208 | */ |
3210 | static int fifo_show(struct seq_file *seq, void *v) | 3209 | static int fifo_show(struct seq_file *seq, void *v) |
3211 | { | 3210 | { |
3212 | struct s3c_hsotg *hsotg = seq->private; | 3211 | struct dwc2_hsotg *hsotg = seq->private; |
3213 | void __iomem *regs = hsotg->regs; | 3212 | void __iomem *regs = hsotg->regs; |
3214 | u32 val; | 3213 | u32 val; |
3215 | int idx; | 3214 | int idx; |
@@ -3265,7 +3264,7 @@ static const char *decode_direction(int is_in) | |||
3265 | static int ep_show(struct seq_file *seq, void *v) | 3264 | static int ep_show(struct seq_file *seq, void *v) |
3266 | { | 3265 | { |
3267 | struct s3c_hsotg_ep *ep = seq->private; | 3266 | struct s3c_hsotg_ep *ep = seq->private; |
3268 | struct s3c_hsotg *hsotg = ep->parent; | 3267 | struct dwc2_hsotg *hsotg = ep->parent; |
3269 | struct s3c_hsotg_req *req; | 3268 | struct s3c_hsotg_req *req; |
3270 | void __iomem *regs = hsotg->regs; | 3269 | void __iomem *regs = hsotg->regs; |
3271 | int index = ep->index; | 3270 | int index = ep->index; |
@@ -3342,7 +3341,7 @@ static const struct file_operations ep_fops = { | |||
3342 | * with the same name as the device itself, in case we end up | 3341 | * with the same name as the device itself, in case we end up |
3343 | * with multiple blocks in future systems. | 3342 | * with multiple blocks in future systems. |
3344 | */ | 3343 | */ |
3345 | static void s3c_hsotg_create_debug(struct s3c_hsotg *hsotg) | 3344 | static void s3c_hsotg_create_debug(struct dwc2_hsotg *hsotg) |
3346 | { | 3345 | { |
3347 | struct dentry *root; | 3346 | struct dentry *root; |
3348 | unsigned epidx; | 3347 | unsigned epidx; |
@@ -3388,7 +3387,7 @@ static void s3c_hsotg_create_debug(struct s3c_hsotg *hsotg) | |||
3388 | * | 3387 | * |
3389 | * Cleanup (remove) the debugfs files for use on module exit. | 3388 | * Cleanup (remove) the debugfs files for use on module exit. |
3390 | */ | 3389 | */ |
3391 | static void s3c_hsotg_delete_debug(struct s3c_hsotg *hsotg) | 3390 | static void s3c_hsotg_delete_debug(struct dwc2_hsotg *hsotg) |
3392 | { | 3391 | { |
3393 | unsigned epidx; | 3392 | unsigned epidx; |
3394 | 3393 | ||
@@ -3403,27 +3402,21 @@ static void s3c_hsotg_delete_debug(struct s3c_hsotg *hsotg) | |||
3403 | } | 3402 | } |
3404 | 3403 | ||
3405 | /** | 3404 | /** |
3406 | * s3c_hsotg_probe - probe function for hsotg driver | 3405 | * dwc2_gadget_init - init function for gadget |
3407 | * @pdev: The platform information for the driver | 3406 | * @dwc2: The data structure for the DWC2 driver. |
3407 | * @irq: The IRQ number for the controller. | ||
3408 | */ | 3408 | */ |
3409 | 3409 | int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) | |
3410 | static int s3c_hsotg_probe(struct platform_device *pdev) | ||
3411 | { | 3410 | { |
3412 | struct s3c_hsotg_plat *plat = dev_get_platdata(&pdev->dev); | 3411 | struct device *dev = hsotg->dev; |
3412 | struct s3c_hsotg_plat *plat = dev->platform_data; | ||
3413 | struct phy *phy; | 3413 | struct phy *phy; |
3414 | struct usb_phy *uphy; | 3414 | struct usb_phy *uphy; |
3415 | struct device *dev = &pdev->dev; | ||
3416 | struct s3c_hsotg_ep *eps; | 3415 | struct s3c_hsotg_ep *eps; |
3417 | struct s3c_hsotg *hsotg; | ||
3418 | struct resource *res; | ||
3419 | int epnum; | 3416 | int epnum; |
3420 | int ret; | 3417 | int ret; |
3421 | int i; | 3418 | int i; |
3422 | 3419 | ||
3423 | hsotg = devm_kzalloc(&pdev->dev, sizeof(struct s3c_hsotg), GFP_KERNEL); | ||
3424 | if (!hsotg) | ||
3425 | return -ENOMEM; | ||
3426 | |||
3427 | /* Set default UTMI width */ | 3420 | /* Set default UTMI width */ |
3428 | hsotg->phyif = GUSBCFG_PHYIF16; | 3421 | hsotg->phyif = GUSBCFG_PHYIF16; |
3429 | 3422 | ||
@@ -3431,14 +3424,14 @@ static int s3c_hsotg_probe(struct platform_device *pdev) | |||
3431 | * Attempt to find a generic PHY, then look for an old style | 3424 | * Attempt to find a generic PHY, then look for an old style |
3432 | * USB PHY, finally fall back to pdata | 3425 | * USB PHY, finally fall back to pdata |
3433 | */ | 3426 | */ |
3434 | phy = devm_phy_get(&pdev->dev, "usb2-phy"); | 3427 | phy = devm_phy_get(dev, "usb2-phy"); |
3435 | if (IS_ERR(phy)) { | 3428 | if (IS_ERR(phy)) { |
3436 | uphy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); | 3429 | uphy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); |
3437 | if (IS_ERR(uphy)) { | 3430 | if (IS_ERR(uphy)) { |
3438 | /* Fallback for pdata */ | 3431 | /* Fallback for pdata */ |
3439 | plat = dev_get_platdata(&pdev->dev); | 3432 | plat = dev_get_platdata(dev); |
3440 | if (!plat) { | 3433 | if (!plat) { |
3441 | dev_err(&pdev->dev, | 3434 | dev_err(dev, |
3442 | "no platform data or transceiver defined\n"); | 3435 | "no platform data or transceiver defined\n"); |
3443 | return -EPROBE_DEFER; | 3436 | return -EPROBE_DEFER; |
3444 | } | 3437 | } |
@@ -3455,43 +3448,24 @@ static int s3c_hsotg_probe(struct platform_device *pdev) | |||
3455 | hsotg->phyif = GUSBCFG_PHYIF8; | 3448 | hsotg->phyif = GUSBCFG_PHYIF8; |
3456 | } | 3449 | } |
3457 | 3450 | ||
3458 | hsotg->dev = dev; | 3451 | hsotg->clk = devm_clk_get(dev, "otg"); |
3459 | |||
3460 | hsotg->clk = devm_clk_get(&pdev->dev, "otg"); | ||
3461 | if (IS_ERR(hsotg->clk)) { | 3452 | if (IS_ERR(hsotg->clk)) { |
3462 | dev_err(dev, "cannot get otg clock\n"); | 3453 | hsotg->clk = NULL; |
3463 | return PTR_ERR(hsotg->clk); | 3454 | dev_dbg(dev, "cannot get otg clock\n"); |
3464 | } | ||
3465 | |||
3466 | platform_set_drvdata(pdev, hsotg); | ||
3467 | |||
3468 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
3469 | |||
3470 | hsotg->regs = devm_ioremap_resource(&pdev->dev, res); | ||
3471 | if (IS_ERR(hsotg->regs)) { | ||
3472 | ret = PTR_ERR(hsotg->regs); | ||
3473 | goto err_clk; | ||
3474 | } | 3455 | } |
3475 | 3456 | ||
3476 | ret = platform_get_irq(pdev, 0); | ||
3477 | if (ret < 0) { | ||
3478 | dev_err(dev, "cannot find IRQ\n"); | ||
3479 | goto err_clk; | ||
3480 | } | ||
3481 | |||
3482 | spin_lock_init(&hsotg->lock); | ||
3483 | |||
3484 | hsotg->irq = ret; | ||
3485 | |||
3486 | dev_info(dev, "regs %p, irq %d\n", hsotg->regs, hsotg->irq); | ||
3487 | |||
3488 | hsotg->gadget.max_speed = USB_SPEED_HIGH; | 3457 | hsotg->gadget.max_speed = USB_SPEED_HIGH; |
3489 | hsotg->gadget.ops = &s3c_hsotg_gadget_ops; | 3458 | hsotg->gadget.ops = &s3c_hsotg_gadget_ops; |
3490 | hsotg->gadget.name = dev_name(dev); | 3459 | hsotg->gadget.name = dev_name(dev); |
3491 | 3460 | ||
3492 | /* reset the system */ | 3461 | /* reset the system */ |
3493 | 3462 | ||
3494 | clk_prepare_enable(hsotg->clk); | 3463 | ret = clk_prepare_enable(hsotg->clk); |
3464 | if (ret) { | ||
3465 | dev_err(dev, "failed to enable otg clk\n"); | ||
3466 | goto err_clk; | ||
3467 | } | ||
3468 | |||
3495 | 3469 | ||
3496 | /* regulators */ | 3470 | /* regulators */ |
3497 | 3471 | ||
@@ -3509,7 +3483,7 @@ static int s3c_hsotg_probe(struct platform_device *pdev) | |||
3509 | hsotg->supplies); | 3483 | hsotg->supplies); |
3510 | 3484 | ||
3511 | if (ret) { | 3485 | if (ret) { |
3512 | dev_err(hsotg->dev, "failed to enable supplies: %d\n", ret); | 3486 | dev_err(dev, "failed to enable supplies: %d\n", ret); |
3513 | goto err_supplies; | 3487 | goto err_supplies; |
3514 | } | 3488 | } |
3515 | 3489 | ||
@@ -3520,14 +3494,14 @@ static int s3c_hsotg_probe(struct platform_device *pdev) | |||
3520 | s3c_hsotg_hw_cfg(hsotg); | 3494 | s3c_hsotg_hw_cfg(hsotg); |
3521 | s3c_hsotg_init(hsotg); | 3495 | s3c_hsotg_init(hsotg); |
3522 | 3496 | ||
3523 | ret = devm_request_irq(&pdev->dev, hsotg->irq, s3c_hsotg_irq, 0, | 3497 | ret = devm_request_irq(hsotg->dev, irq, s3c_hsotg_irq, IRQF_SHARED, |
3524 | dev_name(dev), hsotg); | 3498 | dev_name(hsotg->dev), hsotg); |
3525 | if (ret < 0) { | 3499 | if (ret < 0) { |
3526 | s3c_hsotg_phy_disable(hsotg); | 3500 | s3c_hsotg_phy_disable(hsotg); |
3527 | clk_disable_unprepare(hsotg->clk); | 3501 | clk_disable_unprepare(hsotg->clk); |
3528 | regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), | 3502 | regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), |
3529 | hsotg->supplies); | 3503 | hsotg->supplies); |
3530 | dev_err(dev, "cannot claim IRQ\n"); | 3504 | dev_err(dev, "cannot claim IRQ for gadget\n"); |
3531 | goto err_clk; | 3505 | goto err_clk; |
3532 | } | 3506 | } |
3533 | 3507 | ||
@@ -3573,11 +3547,11 @@ static int s3c_hsotg_probe(struct platform_device *pdev) | |||
3573 | ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), | 3547 | ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), |
3574 | hsotg->supplies); | 3548 | hsotg->supplies); |
3575 | if (ret) { | 3549 | if (ret) { |
3576 | dev_err(hsotg->dev, "failed to disable supplies: %d\n", ret); | 3550 | dev_err(dev, "failed to disable supplies: %d\n", ret); |
3577 | goto err_ep_mem; | 3551 | goto err_ep_mem; |
3578 | } | 3552 | } |
3579 | 3553 | ||
3580 | ret = usb_add_gadget_udc(&pdev->dev, &hsotg->gadget); | 3554 | ret = usb_add_gadget_udc(dev, &hsotg->gadget); |
3581 | if (ret) | 3555 | if (ret) |
3582 | goto err_ep_mem; | 3556 | goto err_ep_mem; |
3583 | 3557 | ||
@@ -3596,47 +3570,44 @@ err_clk: | |||
3596 | 3570 | ||
3597 | return ret; | 3571 | return ret; |
3598 | } | 3572 | } |
3573 | EXPORT_SYMBOL_GPL(dwc2_gadget_init); | ||
3599 | 3574 | ||
3600 | /** | 3575 | /** |
3601 | * s3c_hsotg_remove - remove function for hsotg driver | 3576 | * s3c_hsotg_remove - remove function for hsotg driver |
3602 | * @pdev: The platform information for the driver | 3577 | * @pdev: The platform information for the driver |
3603 | */ | 3578 | */ |
3604 | static int s3c_hsotg_remove(struct platform_device *pdev) | 3579 | int s3c_hsotg_remove(struct dwc2_hsotg *hsotg) |
3605 | { | 3580 | { |
3606 | struct s3c_hsotg *hsotg = platform_get_drvdata(pdev); | ||
3607 | |||
3608 | usb_del_gadget_udc(&hsotg->gadget); | 3581 | usb_del_gadget_udc(&hsotg->gadget); |
3609 | |||
3610 | s3c_hsotg_delete_debug(hsotg); | 3582 | s3c_hsotg_delete_debug(hsotg); |
3611 | |||
3612 | if (hsotg->driver) { | ||
3613 | /* should have been done already by driver model core */ | ||
3614 | usb_gadget_unregister_driver(hsotg->driver); | ||
3615 | } | ||
3616 | |||
3617 | clk_disable_unprepare(hsotg->clk); | 3583 | clk_disable_unprepare(hsotg->clk); |
3618 | 3584 | ||
3619 | return 0; | 3585 | return 0; |
3620 | } | 3586 | } |
3587 | EXPORT_SYMBOL_GPL(s3c_hsotg_remove); | ||
3621 | 3588 | ||
3622 | static int s3c_hsotg_suspend(struct platform_device *pdev, pm_message_t state) | 3589 | int s3c_hsotg_suspend(struct dwc2_hsotg *hsotg) |
3623 | { | 3590 | { |
3624 | struct s3c_hsotg *hsotg = platform_get_drvdata(pdev); | ||
3625 | unsigned long flags; | 3591 | unsigned long flags; |
3626 | int ret = 0; | 3592 | int ret = 0; |
3627 | 3593 | ||
3628 | if (hsotg->driver) | 3594 | mutex_lock(&hsotg->init_mutex); |
3595 | |||
3596 | if (hsotg->driver) { | ||
3597 | int ep; | ||
3598 | |||
3629 | dev_info(hsotg->dev, "suspending usb gadget %s\n", | 3599 | dev_info(hsotg->dev, "suspending usb gadget %s\n", |
3630 | hsotg->driver->driver.name); | 3600 | hsotg->driver->driver.name); |
3631 | 3601 | ||
3632 | spin_lock_irqsave(&hsotg->lock, flags); | 3602 | spin_lock_irqsave(&hsotg->lock, flags); |
3633 | s3c_hsotg_disconnect(hsotg); | 3603 | if (hsotg->enabled) |
3634 | s3c_hsotg_phy_disable(hsotg); | 3604 | s3c_hsotg_core_disconnect(hsotg); |
3635 | hsotg->gadget.speed = USB_SPEED_UNKNOWN; | 3605 | s3c_hsotg_disconnect(hsotg); |
3636 | spin_unlock_irqrestore(&hsotg->lock, flags); | 3606 | hsotg->gadget.speed = USB_SPEED_UNKNOWN; |
3607 | spin_unlock_irqrestore(&hsotg->lock, flags); | ||
3608 | |||
3609 | s3c_hsotg_phy_disable(hsotg); | ||
3637 | 3610 | ||
3638 | if (hsotg->driver) { | ||
3639 | int ep; | ||
3640 | for (ep = 0; ep < hsotg->num_of_eps; ep++) | 3611 | for (ep = 0; ep < hsotg->num_of_eps; ep++) |
3641 | s3c_hsotg_ep_disable(&hsotg->eps[ep].ep); | 3612 | s3c_hsotg_ep_disable(&hsotg->eps[ep].ep); |
3642 | 3613 | ||
@@ -3645,57 +3616,37 @@ static int s3c_hsotg_suspend(struct platform_device *pdev, pm_message_t state) | |||
3645 | clk_disable(hsotg->clk); | 3616 | clk_disable(hsotg->clk); |
3646 | } | 3617 | } |
3647 | 3618 | ||
3619 | mutex_unlock(&hsotg->init_mutex); | ||
3620 | |||
3648 | return ret; | 3621 | return ret; |
3649 | } | 3622 | } |
3623 | EXPORT_SYMBOL_GPL(s3c_hsotg_suspend); | ||
3650 | 3624 | ||
3651 | static int s3c_hsotg_resume(struct platform_device *pdev) | 3625 | int s3c_hsotg_resume(struct dwc2_hsotg *hsotg) |
3652 | { | 3626 | { |
3653 | struct s3c_hsotg *hsotg = platform_get_drvdata(pdev); | ||
3654 | unsigned long flags; | 3627 | unsigned long flags; |
3655 | int ret = 0; | 3628 | int ret = 0; |
3656 | 3629 | ||
3630 | mutex_lock(&hsotg->init_mutex); | ||
3631 | |||
3657 | if (hsotg->driver) { | 3632 | if (hsotg->driver) { |
3658 | dev_info(hsotg->dev, "resuming usb gadget %s\n", | 3633 | dev_info(hsotg->dev, "resuming usb gadget %s\n", |
3659 | hsotg->driver->driver.name); | 3634 | hsotg->driver->driver.name); |
3660 | 3635 | ||
3661 | clk_enable(hsotg->clk); | 3636 | clk_enable(hsotg->clk); |
3662 | ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies), | 3637 | ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies), |
3663 | hsotg->supplies); | 3638 | hsotg->supplies); |
3664 | } | ||
3665 | 3639 | ||
3666 | spin_lock_irqsave(&hsotg->lock, flags); | 3640 | s3c_hsotg_phy_enable(hsotg); |
3667 | hsotg->last_rst = jiffies; | 3641 | |
3668 | s3c_hsotg_phy_enable(hsotg); | 3642 | spin_lock_irqsave(&hsotg->lock, flags); |
3669 | s3c_hsotg_core_init(hsotg); | 3643 | s3c_hsotg_core_init_disconnected(hsotg); |
3670 | spin_unlock_irqrestore(&hsotg->lock, flags); | 3644 | if (hsotg->enabled) |
3645 | s3c_hsotg_core_connect(hsotg); | ||
3646 | spin_unlock_irqrestore(&hsotg->lock, flags); | ||
3647 | } | ||
3648 | mutex_unlock(&hsotg->init_mutex); | ||
3671 | 3649 | ||
3672 | return ret; | 3650 | return ret; |
3673 | } | 3651 | } |
3674 | 3652 | EXPORT_SYMBOL_GPL(s3c_hsotg_resume); | |
3675 | #ifdef CONFIG_OF | ||
3676 | static const struct of_device_id s3c_hsotg_of_ids[] = { | ||
3677 | { .compatible = "samsung,s3c6400-hsotg", }, | ||
3678 | { .compatible = "snps,dwc2", }, | ||
3679 | { /* sentinel */ } | ||
3680 | }; | ||
3681 | MODULE_DEVICE_TABLE(of, s3c_hsotg_of_ids); | ||
3682 | #endif | ||
3683 | |||
3684 | static struct platform_driver s3c_hsotg_driver = { | ||
3685 | .driver = { | ||
3686 | .name = "s3c-hsotg", | ||
3687 | .owner = THIS_MODULE, | ||
3688 | .of_match_table = of_match_ptr(s3c_hsotg_of_ids), | ||
3689 | }, | ||
3690 | .probe = s3c_hsotg_probe, | ||
3691 | .remove = s3c_hsotg_remove, | ||
3692 | .suspend = s3c_hsotg_suspend, | ||
3693 | .resume = s3c_hsotg_resume, | ||
3694 | }; | ||
3695 | |||
3696 | module_platform_driver(s3c_hsotg_driver); | ||
3697 | |||
3698 | MODULE_DESCRIPTION("Samsung S3C USB High-speed/OtG device"); | ||
3699 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); | ||
3700 | MODULE_LICENSE("GPL"); | ||
3701 | MODULE_ALIAS("platform:s3c-hsotg"); | ||