diff options
Diffstat (limited to 'drivers/usb/renesas_usbhs')
-rw-r--r-- | drivers/usb/renesas_usbhs/common.c | 5 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/common.h | 1 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/fifo.c | 14 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/mod.c | 3 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/mod_gadget.c | 11 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/mod_host.c | 45 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/pipe.c | 101 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/pipe.h | 1 |
8 files changed, 157 insertions, 24 deletions
diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index 072edc1cc55f..3bf922ab045e 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c | |||
@@ -132,6 +132,11 @@ void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable) | |||
132 | usbhs_bset(priv, SYSCFG, mask, enable ? val : 0); | 132 | usbhs_bset(priv, SYSCFG, mask, enable ? val : 0); |
133 | } | 133 | } |
134 | 134 | ||
135 | void usbhs_sys_function_pullup(struct usbhs_priv *priv, int enable) | ||
136 | { | ||
137 | usbhs_bset(priv, SYSCFG, DPRPU, enable ? DPRPU : 0); | ||
138 | } | ||
139 | |||
135 | void usbhs_sys_set_test_mode(struct usbhs_priv *priv, u16 mode) | 140 | void usbhs_sys_set_test_mode(struct usbhs_priv *priv, u16 mode) |
136 | { | 141 | { |
137 | usbhs_write(priv, TESTMODE, mode); | 142 | usbhs_write(priv, TESTMODE, mode); |
diff --git a/drivers/usb/renesas_usbhs/common.h b/drivers/usb/renesas_usbhs/common.h index dddf40a59ded..c69dd2fba360 100644 --- a/drivers/usb/renesas_usbhs/common.h +++ b/drivers/usb/renesas_usbhs/common.h | |||
@@ -285,6 +285,7 @@ void usbhs_bset(struct usbhs_priv *priv, u32 reg, u16 mask, u16 data); | |||
285 | */ | 285 | */ |
286 | void usbhs_sys_host_ctrl(struct usbhs_priv *priv, int enable); | 286 | void usbhs_sys_host_ctrl(struct usbhs_priv *priv, int enable); |
287 | void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable); | 287 | void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable); |
288 | void usbhs_sys_function_pullup(struct usbhs_priv *priv, int enable); | ||
288 | void usbhs_sys_set_test_mode(struct usbhs_priv *priv, u16 mode); | 289 | void usbhs_sys_set_test_mode(struct usbhs_priv *priv, u16 mode); |
289 | 290 | ||
290 | /* | 291 | /* |
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index c021b202c0f3..9538f0feafe2 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c | |||
@@ -163,7 +163,7 @@ static int usbhsf_pkt_handler(struct usbhs_pipe *pipe, int type) | |||
163 | func = pkt->handler->dma_done; | 163 | func = pkt->handler->dma_done; |
164 | break; | 164 | break; |
165 | default: | 165 | default: |
166 | dev_err(dev, "unknown pkt hander\n"); | 166 | dev_err(dev, "unknown pkt handler\n"); |
167 | goto __usbhs_pkt_handler_end; | 167 | goto __usbhs_pkt_handler_end; |
168 | } | 168 | } |
169 | 169 | ||
@@ -192,8 +192,8 @@ void usbhs_pkt_start(struct usbhs_pipe *pipe) | |||
192 | /* | 192 | /* |
193 | * irq enable/disable function | 193 | * irq enable/disable function |
194 | */ | 194 | */ |
195 | #define usbhsf_irq_empty_ctrl(p, e) usbhsf_irq_callback_ctrl(p, bempsts, e) | 195 | #define usbhsf_irq_empty_ctrl(p, e) usbhsf_irq_callback_ctrl(p, irq_bempsts, e) |
196 | #define usbhsf_irq_ready_ctrl(p, e) usbhsf_irq_callback_ctrl(p, brdysts, e) | 196 | #define usbhsf_irq_ready_ctrl(p, e) usbhsf_irq_callback_ctrl(p, irq_brdysts, e) |
197 | #define usbhsf_irq_callback_ctrl(pipe, status, enable) \ | 197 | #define usbhsf_irq_callback_ctrl(pipe, status, enable) \ |
198 | ({ \ | 198 | ({ \ |
199 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); \ | 199 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); \ |
@@ -202,9 +202,9 @@ void usbhs_pkt_start(struct usbhs_pipe *pipe) | |||
202 | if (!mod) \ | 202 | if (!mod) \ |
203 | return; \ | 203 | return; \ |
204 | if (enable) \ | 204 | if (enable) \ |
205 | mod->irq_##status |= status; \ | 205 | mod->status |= status; \ |
206 | else \ | 206 | else \ |
207 | mod->irq_##status &= ~status; \ | 207 | mod->status &= ~status; \ |
208 | usbhs_irq_callback_update(priv, mod); \ | 208 | usbhs_irq_callback_update(priv, mod); \ |
209 | }) | 209 | }) |
210 | 210 | ||
@@ -488,6 +488,8 @@ static int usbhsf_pio_try_push(struct usbhs_pkt *pkt, int *is_done) | |||
488 | usbhs_pipe_data_sequence(pipe, pkt->sequence); | 488 | usbhs_pipe_data_sequence(pipe, pkt->sequence); |
489 | pkt->sequence = -1; /* -1 sequence will be ignored */ | 489 | pkt->sequence = -1; /* -1 sequence will be ignored */ |
490 | 490 | ||
491 | usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->length); | ||
492 | |||
491 | ret = usbhsf_fifo_select(pipe, fifo, 1); | 493 | ret = usbhsf_fifo_select(pipe, fifo, 1); |
492 | if (ret < 0) | 494 | if (ret < 0) |
493 | return 0; | 495 | return 0; |
@@ -594,6 +596,7 @@ static int usbhsf_prepare_pop(struct usbhs_pkt *pkt, int *is_done) | |||
594 | usbhs_pipe_data_sequence(pipe, pkt->sequence); | 596 | usbhs_pipe_data_sequence(pipe, pkt->sequence); |
595 | pkt->sequence = -1; /* -1 sequence will be ignored */ | 597 | pkt->sequence = -1; /* -1 sequence will be ignored */ |
596 | 598 | ||
599 | usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->length); | ||
597 | usbhs_pipe_enable(pipe); | 600 | usbhs_pipe_enable(pipe); |
598 | usbhsf_rx_irq_ctrl(pipe, 1); | 601 | usbhsf_rx_irq_ctrl(pipe, 1); |
599 | 602 | ||
@@ -795,6 +798,7 @@ static void xfer_work(struct work_struct *work) | |||
795 | dev_dbg(dev, " %s %d (%d/ %d)\n", | 798 | dev_dbg(dev, " %s %d (%d/ %d)\n", |
796 | fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero); | 799 | fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero); |
797 | 800 | ||
801 | usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->trans); | ||
798 | usbhs_pipe_enable(pipe); | 802 | usbhs_pipe_enable(pipe); |
799 | usbhsf_dma_start(pipe, fifo); | 803 | usbhsf_dma_start(pipe, fifo); |
800 | dma_async_issue_pending(chan); | 804 | dma_async_issue_pending(chan); |
diff --git a/drivers/usb/renesas_usbhs/mod.c b/drivers/usb/renesas_usbhs/mod.c index 61933a90e5bf..6a030b931a3b 100644 --- a/drivers/usb/renesas_usbhs/mod.c +++ b/drivers/usb/renesas_usbhs/mod.c | |||
@@ -151,7 +151,7 @@ int usbhs_mod_probe(struct usbhs_priv *priv) | |||
151 | goto mod_init_host_err; | 151 | goto mod_init_host_err; |
152 | 152 | ||
153 | /* irq settings */ | 153 | /* irq settings */ |
154 | ret = request_irq(priv->irq, usbhs_interrupt, | 154 | ret = devm_request_irq(dev, priv->irq, usbhs_interrupt, |
155 | priv->irqflags, dev_name(dev), priv); | 155 | priv->irqflags, dev_name(dev), priv); |
156 | if (ret) { | 156 | if (ret) { |
157 | dev_err(dev, "irq request err\n"); | 157 | dev_err(dev, "irq request err\n"); |
@@ -172,7 +172,6 @@ void usbhs_mod_remove(struct usbhs_priv *priv) | |||
172 | { | 172 | { |
173 | usbhs_mod_host_remove(priv); | 173 | usbhs_mod_host_remove(priv); |
174 | usbhs_mod_gadget_remove(priv); | 174 | usbhs_mod_gadget_remove(priv); |
175 | free_irq(priv->irq, priv); | ||
176 | } | 175 | } |
177 | 176 | ||
178 | /* | 177 | /* |
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index 28478ce26c34..dd41f61893ef 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c | |||
@@ -883,6 +883,16 @@ static int usbhsg_get_frame(struct usb_gadget *gadget) | |||
883 | return usbhs_frame_get_num(priv); | 883 | return usbhs_frame_get_num(priv); |
884 | } | 884 | } |
885 | 885 | ||
886 | static int usbhsg_pullup(struct usb_gadget *gadget, int is_on) | ||
887 | { | ||
888 | struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); | ||
889 | struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); | ||
890 | |||
891 | usbhs_sys_function_pullup(priv, is_on); | ||
892 | |||
893 | return 0; | ||
894 | } | ||
895 | |||
886 | static int usbhsg_set_selfpowered(struct usb_gadget *gadget, int is_self) | 896 | static int usbhsg_set_selfpowered(struct usb_gadget *gadget, int is_self) |
887 | { | 897 | { |
888 | struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); | 898 | struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); |
@@ -900,6 +910,7 @@ static struct usb_gadget_ops usbhsg_gadget_ops = { | |||
900 | .set_selfpowered = usbhsg_set_selfpowered, | 910 | .set_selfpowered = usbhsg_set_selfpowered, |
901 | .udc_start = usbhsg_gadget_start, | 911 | .udc_start = usbhsg_gadget_start, |
902 | .udc_stop = usbhsg_gadget_stop, | 912 | .udc_stop = usbhsg_gadget_stop, |
913 | .pullup = usbhsg_pullup, | ||
903 | }; | 914 | }; |
904 | 915 | ||
905 | static int usbhsg_start(struct usbhs_priv *priv) | 916 | static int usbhsg_start(struct usbhs_priv *priv) |
diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c index 069cd765400c..3d3cd6ca2689 100644 --- a/drivers/usb/renesas_usbhs/mod_host.c +++ b/drivers/usb/renesas_usbhs/mod_host.c | |||
@@ -85,6 +85,7 @@ struct usbhsh_ep { | |||
85 | struct usbhsh_device *udev; /* attached udev */ | 85 | struct usbhsh_device *udev; /* attached udev */ |
86 | struct usb_host_endpoint *ep; | 86 | struct usb_host_endpoint *ep; |
87 | struct list_head ep_list; /* list to usbhsh_device */ | 87 | struct list_head ep_list; /* list to usbhsh_device */ |
88 | unsigned int counter; /* pipe attach counter */ | ||
88 | }; | 89 | }; |
89 | 90 | ||
90 | #define USBHSH_DEVICE_MAX 10 /* see DEVADDn / DCPMAXP / PIPEMAXP */ | 91 | #define USBHSH_DEVICE_MAX 10 /* see DEVADDn / DCPMAXP / PIPEMAXP */ |
@@ -271,8 +272,12 @@ static int usbhsh_pipe_attach(struct usbhsh_hpriv *hpriv, | |||
271 | /******************** spin lock ********************/ | 272 | /******************** spin lock ********************/ |
272 | usbhs_lock(priv, flags); | 273 | usbhs_lock(priv, flags); |
273 | 274 | ||
274 | if (unlikely(usbhsh_uep_to_pipe(uep))) { | 275 | /* |
275 | dev_err(dev, "uep already has pipe\n"); | 276 | * if uep has been attached to pipe, |
277 | * reuse it | ||
278 | */ | ||
279 | if (usbhsh_uep_to_pipe(uep)) { | ||
280 | ret = 0; | ||
276 | goto usbhsh_pipe_attach_done; | 281 | goto usbhsh_pipe_attach_done; |
277 | } | 282 | } |
278 | 283 | ||
@@ -320,6 +325,9 @@ static int usbhsh_pipe_attach(struct usbhsh_hpriv *hpriv, | |||
320 | } | 325 | } |
321 | 326 | ||
322 | usbhsh_pipe_attach_done: | 327 | usbhsh_pipe_attach_done: |
328 | if (0 == ret) | ||
329 | uep->counter++; | ||
330 | |||
323 | usbhs_unlock(priv, flags); | 331 | usbhs_unlock(priv, flags); |
324 | /******************** spin unlock ******************/ | 332 | /******************** spin unlock ******************/ |
325 | 333 | ||
@@ -346,7 +354,7 @@ static void usbhsh_pipe_detach(struct usbhsh_hpriv *hpriv, | |||
346 | 354 | ||
347 | if (unlikely(!pipe)) { | 355 | if (unlikely(!pipe)) { |
348 | dev_err(dev, "uep doens't have pipe\n"); | 356 | dev_err(dev, "uep doens't have pipe\n"); |
349 | } else { | 357 | } else if (1 == uep->counter--) { /* last user */ |
350 | struct usb_host_endpoint *ep = usbhsh_uep_to_ep(uep); | 358 | struct usb_host_endpoint *ep = usbhsh_uep_to_ep(uep); |
351 | struct usbhsh_device *udev = usbhsh_uep_to_udev(uep); | 359 | struct usbhsh_device *udev = usbhsh_uep_to_udev(uep); |
352 | 360 | ||
@@ -391,6 +399,7 @@ static int usbhsh_endpoint_attach(struct usbhsh_hpriv *hpriv, | |||
391 | /* | 399 | /* |
392 | * init endpoint | 400 | * init endpoint |
393 | */ | 401 | */ |
402 | uep->counter = 0; | ||
394 | INIT_LIST_HEAD(&uep->ep_list); | 403 | INIT_LIST_HEAD(&uep->ep_list); |
395 | list_add_tail(&uep->ep_list, &udev->ep_list_head); | 404 | list_add_tail(&uep->ep_list, &udev->ep_list_head); |
396 | 405 | ||
@@ -686,9 +695,9 @@ static int usbhsh_queue_push(struct usb_hcd *hcd, | |||
686 | } | 695 | } |
687 | 696 | ||
688 | if (usb_pipein(urb->pipe)) | 697 | if (usb_pipein(urb->pipe)) |
689 | pipe->handler = &usbhs_fifo_pio_pop_handler; | 698 | pipe->handler = &usbhs_fifo_dma_pop_handler; |
690 | else | 699 | else |
691 | pipe->handler = &usbhs_fifo_pio_push_handler; | 700 | pipe->handler = &usbhs_fifo_dma_push_handler; |
692 | 701 | ||
693 | buf = (void *)(urb->transfer_buffer + urb->actual_length); | 702 | buf = (void *)(urb->transfer_buffer + urb->actual_length); |
694 | len = urb->transfer_buffer_length - urb->actual_length; | 703 | len = urb->transfer_buffer_length - urb->actual_length; |
@@ -921,6 +930,19 @@ static int usbhsh_dcp_queue_push(struct usb_hcd *hcd, | |||
921 | */ | 930 | */ |
922 | static int usbhsh_dma_map_ctrl(struct usbhs_pkt *pkt, int map) | 931 | static int usbhsh_dma_map_ctrl(struct usbhs_pkt *pkt, int map) |
923 | { | 932 | { |
933 | if (map) { | ||
934 | struct usbhsh_request *ureq = usbhsh_pkt_to_ureq(pkt); | ||
935 | struct urb *urb = ureq->urb; | ||
936 | |||
937 | /* it can not use scatter/gather */ | ||
938 | if (urb->num_sgs) | ||
939 | return -EINVAL; | ||
940 | |||
941 | pkt->dma = urb->transfer_dma; | ||
942 | if (!pkt->dma) | ||
943 | return -EINVAL; | ||
944 | } | ||
945 | |||
924 | return 0; | 946 | return 0; |
925 | } | 947 | } |
926 | 948 | ||
@@ -946,7 +968,6 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd, | |||
946 | struct usb_host_endpoint *ep = urb->ep; | 968 | struct usb_host_endpoint *ep = urb->ep; |
947 | struct usbhsh_device *new_udev = NULL; | 969 | struct usbhsh_device *new_udev = NULL; |
948 | int is_dir_in = usb_pipein(urb->pipe); | 970 | int is_dir_in = usb_pipein(urb->pipe); |
949 | int i; | ||
950 | int ret; | 971 | int ret; |
951 | 972 | ||
952 | dev_dbg(dev, "%s (%s)\n", __func__, is_dir_in ? "in" : "out"); | 973 | dev_dbg(dev, "%s (%s)\n", __func__, is_dir_in ? "in" : "out"); |
@@ -992,13 +1013,7 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd, | |||
992 | * attach pipe to endpoint | 1013 | * attach pipe to endpoint |
993 | * see [image of mod_host] | 1014 | * see [image of mod_host] |
994 | */ | 1015 | */ |
995 | for (i = 0; i < 1024; i++) { | 1016 | ret = usbhsh_pipe_attach(hpriv, urb); |
996 | ret = usbhsh_pipe_attach(hpriv, urb); | ||
997 | if (ret < 0) | ||
998 | msleep(100); | ||
999 | else | ||
1000 | break; | ||
1001 | } | ||
1002 | if (ret < 0) { | 1017 | if (ret < 0) { |
1003 | dev_err(dev, "pipe attach failed\n"); | 1018 | dev_err(dev, "pipe attach failed\n"); |
1004 | goto usbhsh_urb_enqueue_error_free_endpoint; | 1019 | goto usbhsh_urb_enqueue_error_free_endpoint; |
@@ -1072,8 +1087,6 @@ static void usbhsh_endpoint_disable(struct usb_hcd *hcd, | |||
1072 | static int usbhsh_hub_status_data(struct usb_hcd *hcd, char *buf) | 1087 | static int usbhsh_hub_status_data(struct usb_hcd *hcd, char *buf) |
1073 | { | 1088 | { |
1074 | struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); | 1089 | struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); |
1075 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); | ||
1076 | struct device *dev = usbhs_priv_to_dev(priv); | ||
1077 | int roothub_id = 1; /* only 1 root hub */ | 1090 | int roothub_id = 1; /* only 1 root hub */ |
1078 | 1091 | ||
1079 | /* | 1092 | /* |
@@ -1085,8 +1098,6 @@ static int usbhsh_hub_status_data(struct usb_hcd *hcd, char *buf) | |||
1085 | else | 1098 | else |
1086 | *buf = 0; | 1099 | *buf = 0; |
1087 | 1100 | ||
1088 | dev_dbg(dev, "%s (%02x)\n", __func__, *buf); | ||
1089 | |||
1090 | return !!(*buf); | 1101 | return !!(*buf); |
1091 | } | 1102 | } |
1092 | 1103 | ||
diff --git a/drivers/usb/renesas_usbhs/pipe.c b/drivers/usb/renesas_usbhs/pipe.c index 122526cfd32b..7926e1c700f1 100644 --- a/drivers/usb/renesas_usbhs/pipe.c +++ b/drivers/usb/renesas_usbhs/pipe.c | |||
@@ -93,6 +93,82 @@ static void usbhsp_pipe_cfg_set(struct usbhs_pipe *pipe, u16 mask, u16 val) | |||
93 | } | 93 | } |
94 | 94 | ||
95 | /* | 95 | /* |
96 | * PIPEnTRN/PIPEnTRE functions | ||
97 | */ | ||
98 | static void usbhsp_pipe_trn_set(struct usbhs_pipe *pipe, u16 mask, u16 val) | ||
99 | { | ||
100 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); | ||
101 | struct device *dev = usbhs_priv_to_dev(priv); | ||
102 | int num = usbhs_pipe_number(pipe); | ||
103 | u16 reg; | ||
104 | |||
105 | /* | ||
106 | * It is impossible to calculate address, | ||
107 | * since PIPEnTRN addresses were mapped randomly. | ||
108 | */ | ||
109 | #define CASE_PIPExTRN(a) \ | ||
110 | case 0x ## a: \ | ||
111 | reg = PIPE ## a ## TRN; \ | ||
112 | break; | ||
113 | |||
114 | switch (num) { | ||
115 | CASE_PIPExTRN(1); | ||
116 | CASE_PIPExTRN(2); | ||
117 | CASE_PIPExTRN(3); | ||
118 | CASE_PIPExTRN(4); | ||
119 | CASE_PIPExTRN(5); | ||
120 | CASE_PIPExTRN(B); | ||
121 | CASE_PIPExTRN(C); | ||
122 | CASE_PIPExTRN(D); | ||
123 | CASE_PIPExTRN(E); | ||
124 | CASE_PIPExTRN(F); | ||
125 | CASE_PIPExTRN(9); | ||
126 | CASE_PIPExTRN(A); | ||
127 | default: | ||
128 | dev_err(dev, "unknown pipe (%d)\n", num); | ||
129 | return; | ||
130 | } | ||
131 | __usbhsp_pipe_xxx_set(pipe, 0, reg, mask, val); | ||
132 | } | ||
133 | |||
134 | static void usbhsp_pipe_tre_set(struct usbhs_pipe *pipe, u16 mask, u16 val) | ||
135 | { | ||
136 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); | ||
137 | struct device *dev = usbhs_priv_to_dev(priv); | ||
138 | int num = usbhs_pipe_number(pipe); | ||
139 | u16 reg; | ||
140 | |||
141 | /* | ||
142 | * It is impossible to calculate address, | ||
143 | * since PIPEnTRE addresses were mapped randomly. | ||
144 | */ | ||
145 | #define CASE_PIPExTRE(a) \ | ||
146 | case 0x ## a: \ | ||
147 | reg = PIPE ## a ## TRE; \ | ||
148 | break; | ||
149 | |||
150 | switch (num) { | ||
151 | CASE_PIPExTRE(1); | ||
152 | CASE_PIPExTRE(2); | ||
153 | CASE_PIPExTRE(3); | ||
154 | CASE_PIPExTRE(4); | ||
155 | CASE_PIPExTRE(5); | ||
156 | CASE_PIPExTRE(B); | ||
157 | CASE_PIPExTRE(C); | ||
158 | CASE_PIPExTRE(D); | ||
159 | CASE_PIPExTRE(E); | ||
160 | CASE_PIPExTRE(F); | ||
161 | CASE_PIPExTRE(9); | ||
162 | CASE_PIPExTRE(A); | ||
163 | default: | ||
164 | dev_err(dev, "unknown pipe (%d)\n", num); | ||
165 | return; | ||
166 | } | ||
167 | |||
168 | __usbhsp_pipe_xxx_set(pipe, 0, reg, mask, val); | ||
169 | } | ||
170 | |||
171 | /* | ||
96 | * PIPEBUF | 172 | * PIPEBUF |
97 | */ | 173 | */ |
98 | static void usbhsp_pipe_buf_set(struct usbhs_pipe *pipe, u16 mask, u16 val) | 174 | static void usbhsp_pipe_buf_set(struct usbhs_pipe *pipe, u16 mask, u16 val) |
@@ -264,6 +340,31 @@ int usbhs_pipe_is_stall(struct usbhs_pipe *pipe) | |||
264 | return (int)(pid == PID_STALL10 || pid == PID_STALL11); | 340 | return (int)(pid == PID_STALL10 || pid == PID_STALL11); |
265 | } | 341 | } |
266 | 342 | ||
343 | void usbhs_pipe_set_trans_count_if_bulk(struct usbhs_pipe *pipe, int len) | ||
344 | { | ||
345 | if (!usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK)) | ||
346 | return; | ||
347 | |||
348 | /* | ||
349 | * clear and disable transfer counter for IN/OUT pipe | ||
350 | */ | ||
351 | usbhsp_pipe_tre_set(pipe, TRCLR | TRENB, TRCLR); | ||
352 | |||
353 | /* | ||
354 | * Only IN direction bulk pipe can use transfer count. | ||
355 | * Without using this function, | ||
356 | * received data will break if it was large data size. | ||
357 | * see PIPEnTRN/PIPEnTRE for detail | ||
358 | */ | ||
359 | if (usbhs_pipe_is_dir_in(pipe)) { | ||
360 | int maxp = usbhs_pipe_get_maxpacket(pipe); | ||
361 | |||
362 | usbhsp_pipe_trn_set(pipe, 0xffff, DIV_ROUND_UP(len, maxp)); | ||
363 | usbhsp_pipe_tre_set(pipe, TRENB, TRENB); /* enable */ | ||
364 | } | ||
365 | } | ||
366 | |||
367 | |||
267 | /* | 368 | /* |
268 | * pipe setup | 369 | * pipe setup |
269 | */ | 370 | */ |
diff --git a/drivers/usb/renesas_usbhs/pipe.h b/drivers/usb/renesas_usbhs/pipe.h index 3d80c7b1fd1b..b476fde955bf 100644 --- a/drivers/usb/renesas_usbhs/pipe.h +++ b/drivers/usb/renesas_usbhs/pipe.h | |||
@@ -88,6 +88,7 @@ void usbhs_pipe_enable(struct usbhs_pipe *pipe); | |||
88 | void usbhs_pipe_disable(struct usbhs_pipe *pipe); | 88 | void usbhs_pipe_disable(struct usbhs_pipe *pipe); |
89 | void usbhs_pipe_stall(struct usbhs_pipe *pipe); | 89 | void usbhs_pipe_stall(struct usbhs_pipe *pipe); |
90 | int usbhs_pipe_is_stall(struct usbhs_pipe *pipe); | 90 | int usbhs_pipe_is_stall(struct usbhs_pipe *pipe); |
91 | void usbhs_pipe_set_trans_count_if_bulk(struct usbhs_pipe *pipe, int len); | ||
91 | void usbhs_pipe_select_fifo(struct usbhs_pipe *pipe, struct usbhs_fifo *fifo); | 92 | void usbhs_pipe_select_fifo(struct usbhs_pipe *pipe, struct usbhs_fifo *fifo); |
92 | void usbhs_pipe_config_update(struct usbhs_pipe *pipe, u16 devsel, | 93 | void usbhs_pipe_config_update(struct usbhs_pipe *pipe, u16 devsel, |
93 | u16 epnum, u16 maxp); | 94 | u16 epnum, u16 maxp); |