diff options
Diffstat (limited to 'drivers/usb/renesas_usbhs/mod_gadget.c')
-rw-r--r-- | drivers/usb/renesas_usbhs/mod_gadget.c | 134 |
1 files changed, 49 insertions, 85 deletions
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index cb2d451d511e..d9717e0bc1ff 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c | |||
@@ -39,7 +39,6 @@ struct usbhsg_uep { | |||
39 | char ep_name[EP_NAME_SIZE]; | 39 | char ep_name[EP_NAME_SIZE]; |
40 | 40 | ||
41 | struct usbhsg_gpriv *gpriv; | 41 | struct usbhsg_gpriv *gpriv; |
42 | struct usbhs_pkt_handle *handler; | ||
43 | }; | 42 | }; |
44 | 43 | ||
45 | struct usbhsg_gpriv { | 44 | struct usbhsg_gpriv { |
@@ -128,25 +127,6 @@ LIST_HEAD(the_controller_link); | |||
128 | /* | 127 | /* |
129 | * queue push/pop | 128 | * queue push/pop |
130 | */ | 129 | */ |
131 | static void usbhsg_queue_push(struct usbhsg_uep *uep, | ||
132 | struct usbhsg_request *ureq) | ||
133 | { | ||
134 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); | ||
135 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); | ||
136 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); | ||
137 | struct usbhs_pkt *pkt = usbhsg_ureq_to_pkt(ureq); | ||
138 | struct usb_request *req = &ureq->req; | ||
139 | |||
140 | req->actual = 0; | ||
141 | req->status = -EINPROGRESS; | ||
142 | usbhs_pkt_push(pipe, pkt, uep->handler, | ||
143 | req->buf, req->length, req->zero); | ||
144 | |||
145 | dev_dbg(dev, "pipe %d : queue push (%d)\n", | ||
146 | usbhs_pipe_number(pipe), | ||
147 | req->length); | ||
148 | } | ||
149 | |||
150 | static void usbhsg_queue_pop(struct usbhsg_uep *uep, | 130 | static void usbhsg_queue_pop(struct usbhsg_uep *uep, |
151 | struct usbhsg_request *ureq, | 131 | struct usbhsg_request *ureq, |
152 | int status) | 132 | int status) |
@@ -161,7 +141,7 @@ static void usbhsg_queue_pop(struct usbhsg_uep *uep, | |||
161 | ureq->req.complete(&uep->ep, &ureq->req); | 141 | ureq->req.complete(&uep->ep, &ureq->req); |
162 | } | 142 | } |
163 | 143 | ||
164 | static void usbhsg_queue_done(struct usbhs_pkt *pkt) | 144 | static void usbhsg_queue_done(struct usbhs_priv *priv, struct usbhs_pkt *pkt) |
165 | { | 145 | { |
166 | struct usbhs_pipe *pipe = pkt->pipe; | 146 | struct usbhs_pipe *pipe = pkt->pipe; |
167 | struct usbhsg_uep *uep = usbhsg_pipe_to_uep(pipe); | 147 | struct usbhsg_uep *uep = usbhsg_pipe_to_uep(pipe); |
@@ -172,6 +152,26 @@ static void usbhsg_queue_done(struct usbhs_pkt *pkt) | |||
172 | usbhsg_queue_pop(uep, ureq, 0); | 152 | usbhsg_queue_pop(uep, ureq, 0); |
173 | } | 153 | } |
174 | 154 | ||
155 | static void usbhsg_queue_push(struct usbhsg_uep *uep, | ||
156 | struct usbhsg_request *ureq) | ||
157 | { | ||
158 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); | ||
159 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); | ||
160 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); | ||
161 | struct usbhs_pkt *pkt = usbhsg_ureq_to_pkt(ureq); | ||
162 | struct usb_request *req = &ureq->req; | ||
163 | |||
164 | req->actual = 0; | ||
165 | req->status = -EINPROGRESS; | ||
166 | usbhs_pkt_push(pipe, pkt, usbhsg_queue_done, | ||
167 | req->buf, req->length, req->zero); | ||
168 | usbhs_pkt_start(pipe); | ||
169 | |||
170 | dev_dbg(dev, "pipe %d : queue push (%d)\n", | ||
171 | usbhs_pipe_number(pipe), | ||
172 | req->length); | ||
173 | } | ||
174 | |||
175 | /* | 175 | /* |
176 | * dma map/unmap | 176 | * dma map/unmap |
177 | */ | 177 | */ |
@@ -265,7 +265,7 @@ static int usbhsg_recip_handler_std_clear_endpoint(struct usbhs_priv *priv, | |||
265 | 265 | ||
266 | if (!usbhsg_status_has(gpriv, USBHSG_STATUS_WEDGE)) { | 266 | if (!usbhsg_status_has(gpriv, USBHSG_STATUS_WEDGE)) { |
267 | usbhs_pipe_disable(pipe); | 267 | usbhs_pipe_disable(pipe); |
268 | usbhs_pipe_clear_sequence(pipe); | 268 | usbhs_pipe_sequence_data0(pipe); |
269 | usbhs_pipe_enable(pipe); | 269 | usbhs_pipe_enable(pipe); |
270 | } | 270 | } |
271 | 271 | ||
@@ -355,7 +355,7 @@ static int usbhsg_irq_dev_state(struct usbhs_priv *priv, | |||
355 | struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); | 355 | struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); |
356 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); | 356 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); |
357 | 357 | ||
358 | gpriv->gadget.speed = usbhs_status_get_usb_speed(irq_state); | 358 | gpriv->gadget.speed = usbhs_bus_get_speed(priv); |
359 | 359 | ||
360 | dev_dbg(dev, "state = %x : speed : %d\n", | 360 | dev_dbg(dev, "state = %x : speed : %d\n", |
361 | usbhs_status_get_device_state(irq_state), | 361 | usbhs_status_get_device_state(irq_state), |
@@ -389,13 +389,13 @@ static int usbhsg_irq_ctrl_stage(struct usbhs_priv *priv, | |||
389 | 389 | ||
390 | switch (stage) { | 390 | switch (stage) { |
391 | case READ_DATA_STAGE: | 391 | case READ_DATA_STAGE: |
392 | dcp->handler = &usbhs_fifo_pio_push_handler; | 392 | pipe->handler = &usbhs_fifo_pio_push_handler; |
393 | break; | 393 | break; |
394 | case WRITE_DATA_STAGE: | 394 | case WRITE_DATA_STAGE: |
395 | dcp->handler = &usbhs_fifo_pio_pop_handler; | 395 | pipe->handler = &usbhs_fifo_pio_pop_handler; |
396 | break; | 396 | break; |
397 | case NODATA_STATUS_STAGE: | 397 | case NODATA_STATUS_STAGE: |
398 | dcp->handler = &usbhs_ctrl_stage_end_handler; | 398 | pipe->handler = &usbhs_ctrl_stage_end_handler; |
399 | break; | 399 | break; |
400 | default: | 400 | default: |
401 | return ret; | 401 | return ret; |
@@ -479,24 +479,31 @@ static int usbhsg_ep_enable(struct usb_ep *ep, | |||
479 | */ | 479 | */ |
480 | if (uep->pipe) { | 480 | if (uep->pipe) { |
481 | usbhs_pipe_clear(uep->pipe); | 481 | usbhs_pipe_clear(uep->pipe); |
482 | usbhs_pipe_clear_sequence(uep->pipe); | 482 | usbhs_pipe_sequence_data0(uep->pipe); |
483 | return 0; | 483 | return 0; |
484 | } | 484 | } |
485 | 485 | ||
486 | pipe = usbhs_pipe_malloc(priv, desc); | 486 | pipe = usbhs_pipe_malloc(priv, |
487 | usb_endpoint_type(desc), | ||
488 | usb_endpoint_dir_in(desc)); | ||
487 | if (pipe) { | 489 | if (pipe) { |
488 | uep->pipe = pipe; | 490 | uep->pipe = pipe; |
489 | pipe->mod_private = uep; | 491 | pipe->mod_private = uep; |
490 | 492 | ||
493 | /* set epnum / maxp */ | ||
494 | usbhs_pipe_config_update(pipe, 0, | ||
495 | usb_endpoint_num(desc), | ||
496 | usb_endpoint_maxp(desc)); | ||
497 | |||
491 | /* | 498 | /* |
492 | * usbhs_fifo_dma_push/pop_handler try to | 499 | * usbhs_fifo_dma_push/pop_handler try to |
493 | * use dmaengine if possible. | 500 | * use dmaengine if possible. |
494 | * It will use pio handler if impossible. | 501 | * It will use pio handler if impossible. |
495 | */ | 502 | */ |
496 | if (usb_endpoint_dir_in(desc)) | 503 | if (usb_endpoint_dir_in(desc)) |
497 | uep->handler = &usbhs_fifo_dma_push_handler; | 504 | pipe->handler = &usbhs_fifo_dma_push_handler; |
498 | else | 505 | else |
499 | uep->handler = &usbhs_fifo_dma_pop_handler; | 506 | pipe->handler = &usbhs_fifo_dma_pop_handler; |
500 | 507 | ||
501 | ret = 0; | 508 | ret = 0; |
502 | } | 509 | } |
@@ -659,7 +666,6 @@ static int usbhsg_try_start(struct usbhs_priv *priv, u32 status) | |||
659 | * pipe initialize and enable DCP | 666 | * pipe initialize and enable DCP |
660 | */ | 667 | */ |
661 | usbhs_pipe_init(priv, | 668 | usbhs_pipe_init(priv, |
662 | usbhsg_queue_done, | ||
663 | usbhsg_dma_map_ctrl); | 669 | usbhsg_dma_map_ctrl); |
664 | usbhs_fifo_init(priv); | 670 | usbhs_fifo_init(priv); |
665 | usbhsg_uep_init(gpriv); | 671 | usbhsg_uep_init(gpriv); |
@@ -667,6 +673,7 @@ static int usbhsg_try_start(struct usbhs_priv *priv, u32 status) | |||
667 | /* dcp init */ | 673 | /* dcp init */ |
668 | dcp->pipe = usbhs_dcp_malloc(priv); | 674 | dcp->pipe = usbhs_dcp_malloc(priv); |
669 | dcp->pipe->mod_private = dcp; | 675 | dcp->pipe->mod_private = dcp; |
676 | usbhs_pipe_config_update(dcp->pipe, 0, 0, 64); | ||
670 | 677 | ||
671 | /* | 678 | /* |
672 | * system config enble | 679 | * system config enble |
@@ -730,10 +737,6 @@ static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status) | |||
730 | 737 | ||
731 | usbhsg_pipe_disable(dcp); | 738 | usbhsg_pipe_disable(dcp); |
732 | 739 | ||
733 | if (gpriv->driver && | ||
734 | gpriv->driver->disconnect) | ||
735 | gpriv->driver->disconnect(&gpriv->gadget); | ||
736 | |||
737 | dev_dbg(dev, "stop gadget\n"); | 740 | dev_dbg(dev, "stop gadget\n"); |
738 | 741 | ||
739 | return 0; | 742 | return 0; |
@@ -744,31 +747,19 @@ static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status) | |||
744 | * linux usb function | 747 | * linux usb function |
745 | * | 748 | * |
746 | */ | 749 | */ |
747 | static int usbhsg_gadget_start(struct usb_gadget_driver *driver, | 750 | static int usbhsg_gadget_start(struct usb_gadget *gadget, |
748 | int (*bind)(struct usb_gadget *)) | 751 | struct usb_gadget_driver *driver) |
749 | { | 752 | { |
750 | struct usbhsg_gpriv *gpriv; | 753 | struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); |
751 | struct usbhs_priv *priv; | 754 | struct usbhs_priv *priv; |
752 | struct device *dev; | 755 | struct device *dev; |
753 | int ret; | 756 | int ret; |
754 | 757 | ||
755 | if (!bind || | 758 | if (!driver || |
756 | !driver || | ||
757 | !driver->setup || | 759 | !driver->setup || |
758 | driver->speed != USB_SPEED_HIGH) | 760 | driver->speed != USB_SPEED_HIGH) |
759 | return -EINVAL; | 761 | return -EINVAL; |
760 | 762 | ||
761 | /* | ||
762 | * find unused controller | ||
763 | */ | ||
764 | usbhsg_for_each_controller(gpriv) { | ||
765 | if (!gpriv->driver) | ||
766 | goto find_unused_controller; | ||
767 | } | ||
768 | return -ENODEV; | ||
769 | |||
770 | find_unused_controller: | ||
771 | |||
772 | dev = usbhsg_gpriv_to_dev(gpriv); | 763 | dev = usbhsg_gpriv_to_dev(gpriv); |
773 | priv = usbhsg_gpriv_to_priv(gpriv); | 764 | priv = usbhsg_gpriv_to_priv(gpriv); |
774 | 765 | ||
@@ -782,19 +773,8 @@ find_unused_controller: | |||
782 | goto add_fail; | 773 | goto add_fail; |
783 | } | 774 | } |
784 | 775 | ||
785 | ret = bind(&gpriv->gadget); | ||
786 | if (ret) { | ||
787 | dev_err(dev, "bind to driver %s error %d\n", | ||
788 | driver->driver.name, ret); | ||
789 | goto bind_fail; | ||
790 | } | ||
791 | |||
792 | dev_dbg(dev, "bind %s\n", driver->driver.name); | ||
793 | |||
794 | return usbhsg_try_start(priv, USBHSG_STATUS_REGISTERD); | 776 | return usbhsg_try_start(priv, USBHSG_STATUS_REGISTERD); |
795 | 777 | ||
796 | bind_fail: | ||
797 | device_del(&gpriv->gadget.dev); | ||
798 | add_fail: | 778 | add_fail: |
799 | gpriv->driver = NULL; | 779 | gpriv->driver = NULL; |
800 | gpriv->gadget.dev.driver = NULL; | 780 | gpriv->gadget.dev.driver = NULL; |
@@ -802,9 +782,10 @@ add_fail: | |||
802 | return ret; | 782 | return ret; |
803 | } | 783 | } |
804 | 784 | ||
805 | static int usbhsg_gadget_stop(struct usb_gadget_driver *driver) | 785 | static int usbhsg_gadget_stop(struct usb_gadget *gadget, |
786 | struct usb_gadget_driver *driver) | ||
806 | { | 787 | { |
807 | struct usbhsg_gpriv *gpriv; | 788 | struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); |
808 | struct usbhs_priv *priv; | 789 | struct usbhs_priv *priv; |
809 | struct device *dev; | 790 | struct device *dev; |
810 | 791 | ||
@@ -812,17 +793,6 @@ static int usbhsg_gadget_stop(struct usb_gadget_driver *driver) | |||
812 | !driver->unbind) | 793 | !driver->unbind) |
813 | return -EINVAL; | 794 | return -EINVAL; |
814 | 795 | ||
815 | /* | ||
816 | * find controller | ||
817 | */ | ||
818 | usbhsg_for_each_controller(gpriv) { | ||
819 | if (gpriv->driver == driver) | ||
820 | goto find_matching_controller; | ||
821 | } | ||
822 | return -ENODEV; | ||
823 | |||
824 | find_matching_controller: | ||
825 | |||
826 | dev = usbhsg_gpriv_to_dev(gpriv); | 796 | dev = usbhsg_gpriv_to_dev(gpriv); |
827 | priv = usbhsg_gpriv_to_priv(gpriv); | 797 | priv = usbhsg_gpriv_to_priv(gpriv); |
828 | 798 | ||
@@ -830,12 +800,6 @@ find_matching_controller: | |||
830 | device_del(&gpriv->gadget.dev); | 800 | device_del(&gpriv->gadget.dev); |
831 | gpriv->driver = NULL; | 801 | gpriv->driver = NULL; |
832 | 802 | ||
833 | if (driver->disconnect) | ||
834 | driver->disconnect(&gpriv->gadget); | ||
835 | |||
836 | driver->unbind(&gpriv->gadget); | ||
837 | dev_dbg(dev, "unbind %s\n", driver->driver.name); | ||
838 | |||
839 | return 0; | 803 | return 0; |
840 | } | 804 | } |
841 | 805 | ||
@@ -852,8 +816,8 @@ static int usbhsg_get_frame(struct usb_gadget *gadget) | |||
852 | 816 | ||
853 | static struct usb_gadget_ops usbhsg_gadget_ops = { | 817 | static struct usb_gadget_ops usbhsg_gadget_ops = { |
854 | .get_frame = usbhsg_get_frame, | 818 | .get_frame = usbhsg_get_frame, |
855 | .start = usbhsg_gadget_start, | 819 | .udc_start = usbhsg_gadget_start, |
856 | .stop = usbhsg_gadget_stop, | 820 | .udc_stop = usbhsg_gadget_stop, |
857 | }; | 821 | }; |
858 | 822 | ||
859 | static int usbhsg_start(struct usbhs_priv *priv) | 823 | static int usbhsg_start(struct usbhs_priv *priv) |
@@ -866,7 +830,7 @@ static int usbhsg_stop(struct usbhs_priv *priv) | |||
866 | return usbhsg_try_stop(priv, USBHSG_STATUS_STARTED); | 830 | return usbhsg_try_stop(priv, USBHSG_STATUS_STARTED); |
867 | } | 831 | } |
868 | 832 | ||
869 | int __devinit usbhs_mod_gadget_probe(struct usbhs_priv *priv) | 833 | int usbhs_mod_gadget_probe(struct usbhs_priv *priv) |
870 | { | 834 | { |
871 | struct usbhsg_gpriv *gpriv; | 835 | struct usbhsg_gpriv *gpriv; |
872 | struct usbhsg_uep *uep; | 836 | struct usbhsg_uep *uep; |
@@ -963,7 +927,7 @@ usbhs_mod_gadget_probe_err_gpriv: | |||
963 | return ret; | 927 | return ret; |
964 | } | 928 | } |
965 | 929 | ||
966 | void __devexit usbhs_mod_gadget_remove(struct usbhs_priv *priv) | 930 | void usbhs_mod_gadget_remove(struct usbhs_priv *priv) |
967 | { | 931 | { |
968 | struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); | 932 | struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); |
969 | 933 | ||