aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/renesas_usbhs/mod_gadget.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/renesas_usbhs/mod_gadget.c')
-rw-r--r--drivers/usb/renesas_usbhs/mod_gadget.c41
1 files changed, 37 insertions, 4 deletions
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c
index 2d17c10a0428..8697e6efcabf 100644
--- a/drivers/usb/renesas_usbhs/mod_gadget.c
+++ b/drivers/usb/renesas_usbhs/mod_gadget.c
@@ -56,6 +56,7 @@ struct usbhsg_gpriv {
56#define USBHSG_STATUS_REGISTERD (1 << 1) 56#define USBHSG_STATUS_REGISTERD (1 << 1)
57#define USBHSG_STATUS_WEDGE (1 << 2) 57#define USBHSG_STATUS_WEDGE (1 << 2)
58#define USBHSG_STATUS_SELF_POWERED (1 << 3) 58#define USBHSG_STATUS_SELF_POWERED (1 << 3)
59#define USBHSG_STATUS_SOFT_CONNECT (1 << 4)
59}; 60};
60 61
61struct usbhsg_recip_handle { 62struct usbhsg_recip_handle {
@@ -484,6 +485,9 @@ static int usbhsg_irq_ctrl_stage(struct usbhs_priv *priv,
484 case NODATA_STATUS_STAGE: 485 case NODATA_STATUS_STAGE:
485 pipe->handler = &usbhs_ctrl_stage_end_handler; 486 pipe->handler = &usbhs_ctrl_stage_end_handler;
486 break; 487 break;
488 case READ_STATUS_STAGE:
489 case WRITE_STATUS_STAGE:
490 usbhs_dcp_control_transfer_done(pipe);
487 default: 491 default:
488 return ret; 492 return ret;
489 } 493 }
@@ -602,6 +606,9 @@ static int usbhsg_ep_disable(struct usb_ep *ep)
602 struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); 606 struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep);
603 struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 607 struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
604 608
609 if (!pipe)
610 return -EINVAL;
611
605 usbhsg_pipe_disable(uep); 612 usbhsg_pipe_disable(uep);
606 usbhs_pipe_free(pipe); 613 usbhs_pipe_free(pipe);
607 614
@@ -723,6 +730,25 @@ static struct usb_ep_ops usbhsg_ep_ops = {
723}; 730};
724 731
725/* 732/*
733 * pullup control
734 */
735static int usbhsg_can_pullup(struct usbhs_priv *priv)
736{
737 struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv);
738
739 return gpriv->driver &&
740 usbhsg_status_has(gpriv, USBHSG_STATUS_SOFT_CONNECT);
741}
742
743static void usbhsg_update_pullup(struct usbhs_priv *priv)
744{
745 if (usbhsg_can_pullup(priv))
746 usbhs_sys_function_pullup(priv, 1);
747 else
748 usbhs_sys_function_pullup(priv, 0);
749}
750
751/*
726 * usb module start/end 752 * usb module start/end
727 */ 753 */
728static int usbhsg_try_start(struct usbhs_priv *priv, u32 status) 754static int usbhsg_try_start(struct usbhs_priv *priv, u32 status)
@@ -756,9 +782,9 @@ static int usbhsg_try_start(struct usbhs_priv *priv, u32 status)
756 /* 782 /*
757 * pipe initialize and enable DCP 783 * pipe initialize and enable DCP
758 */ 784 */
785 usbhs_fifo_init(priv);
759 usbhs_pipe_init(priv, 786 usbhs_pipe_init(priv,
760 usbhsg_dma_map_ctrl); 787 usbhsg_dma_map_ctrl);
761 usbhs_fifo_init(priv);
762 788
763 /* dcp init instead of usbhsg_ep_enable() */ 789 /* dcp init instead of usbhsg_ep_enable() */
764 dcp->pipe = usbhs_dcp_malloc(priv); 790 dcp->pipe = usbhs_dcp_malloc(priv);
@@ -772,6 +798,7 @@ static int usbhsg_try_start(struct usbhs_priv *priv, u32 status)
772 * - usb module 798 * - usb module
773 */ 799 */
774 usbhs_sys_function_ctrl(priv, 1); 800 usbhs_sys_function_ctrl(priv, 1);
801 usbhsg_update_pullup(priv);
775 802
776 /* 803 /*
777 * enable irq callback 804 * enable irq callback
@@ -851,8 +878,7 @@ static int usbhsg_gadget_start(struct usb_gadget *gadget,
851 return usbhsg_try_start(priv, USBHSG_STATUS_REGISTERD); 878 return usbhsg_try_start(priv, USBHSG_STATUS_REGISTERD);
852} 879}
853 880
854static int usbhsg_gadget_stop(struct usb_gadget *gadget, 881static int usbhsg_gadget_stop(struct usb_gadget *gadget)
855 struct usb_gadget_driver *driver)
856{ 882{
857 struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); 883 struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget);
858 struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); 884 struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv);
@@ -878,8 +904,15 @@ static int usbhsg_pullup(struct usb_gadget *gadget, int is_on)
878{ 904{
879 struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); 905 struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget);
880 struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); 906 struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv);
907 unsigned long flags;
881 908
882 usbhs_sys_function_pullup(priv, is_on); 909 usbhs_lock(priv, flags);
910 if (is_on)
911 usbhsg_status_set(gpriv, USBHSG_STATUS_SOFT_CONNECT);
912 else
913 usbhsg_status_clr(gpriv, USBHSG_STATUS_SOFT_CONNECT);
914 usbhsg_update_pullup(priv);
915 usbhs_unlock(priv, flags);
883 916
884 return 0; 917 return 0;
885} 918}