aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/renesas_usbhs/mod_gadget.c55
1 files changed, 41 insertions, 14 deletions
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c
index cc3ad634d4f..ba79dbf5adb 100644
--- a/drivers/usb/renesas_usbhs/mod_gadget.c
+++ b/drivers/usb/renesas_usbhs/mod_gadget.c
@@ -44,6 +44,7 @@ struct usbhsg_uep {
44struct usbhsg_gpriv { 44struct usbhsg_gpriv {
45 struct usb_gadget gadget; 45 struct usb_gadget gadget;
46 struct usbhs_mod mod; 46 struct usbhs_mod mod;
47 struct list_head link;
47 48
48 struct usbhsg_uep *uep; 49 struct usbhsg_uep *uep;
49 int uep_size; 50 int uep_size;
@@ -113,6 +114,16 @@ struct usbhsg_recip_handle {
113#define usbhsg_status_clr(gp, b) (gp->status &= ~b) 114#define usbhsg_status_clr(gp, b) (gp->status &= ~b)
114#define usbhsg_status_has(gp, b) (gp->status & b) 115#define usbhsg_status_has(gp, b) (gp->status & b)
115 116
117/* controller */
118LIST_HEAD(the_controller_link);
119
120#define usbhsg_for_each_controller(gpriv)\
121 list_for_each_entry(gpriv, &the_controller_link, link)
122#define usbhsg_controller_register(gpriv)\
123 list_add_tail(&(gpriv)->link, &the_controller_link)
124#define usbhsg_controller_unregister(gpriv)\
125 list_del_init(&(gpriv)->link)
126
116/* 127/*
117 * queue push/pop 128 * queue push/pop
118 */ 129 */
@@ -732,11 +743,10 @@ static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status)
732 * linux usb function 743 * linux usb function
733 * 744 *
734 */ 745 */
735struct usbhsg_gpriv *the_controller;
736static int usbhsg_gadget_start(struct usb_gadget_driver *driver, 746static int usbhsg_gadget_start(struct usb_gadget_driver *driver,
737 int (*bind)(struct usb_gadget *)) 747 int (*bind)(struct usb_gadget *))
738{ 748{
739 struct usbhsg_gpriv *gpriv = the_controller; 749 struct usbhsg_gpriv *gpriv;
740 struct usbhs_priv *priv; 750 struct usbhs_priv *priv;
741 struct device *dev; 751 struct device *dev;
742 int ret; 752 int ret;
@@ -746,10 +756,17 @@ static int usbhsg_gadget_start(struct usb_gadget_driver *driver,
746 !driver->setup || 756 !driver->setup ||
747 driver->speed != USB_SPEED_HIGH) 757 driver->speed != USB_SPEED_HIGH)
748 return -EINVAL; 758 return -EINVAL;
749 if (!gpriv) 759
750 return -ENODEV; 760 /*
751 if (gpriv->driver) 761 * find unused controller
752 return -EBUSY; 762 */
763 usbhsg_for_each_controller(gpriv) {
764 if (!gpriv->driver)
765 goto find_unused_controller;
766 }
767 return -ENODEV;
768
769find_unused_controller:
753 770
754 dev = usbhsg_gpriv_to_dev(gpriv); 771 dev = usbhsg_gpriv_to_dev(gpriv);
755 priv = usbhsg_gpriv_to_priv(gpriv); 772 priv = usbhsg_gpriv_to_priv(gpriv);
@@ -786,18 +803,25 @@ add_fail:
786 803
787static int usbhsg_gadget_stop(struct usb_gadget_driver *driver) 804static int usbhsg_gadget_stop(struct usb_gadget_driver *driver)
788{ 805{
789 struct usbhsg_gpriv *gpriv = the_controller; 806 struct usbhsg_gpriv *gpriv;
790 struct usbhs_priv *priv; 807 struct usbhs_priv *priv;
791 struct device *dev = usbhsg_gpriv_to_dev(gpriv); 808 struct device *dev;
792
793 if (!gpriv)
794 return -ENODEV;
795 809
796 if (!driver || 810 if (!driver ||
797 !driver->unbind || 811 !driver->unbind)
798 driver != gpriv->driver)
799 return -EINVAL; 812 return -EINVAL;
800 813
814 /*
815 * find controller
816 */
817 usbhsg_for_each_controller(gpriv) {
818 if (gpriv->driver == driver)
819 goto find_matching_controller;
820 }
821 return -ENODEV;
822
823find_matching_controller:
824
801 dev = usbhsg_gpriv_to_dev(gpriv); 825 dev = usbhsg_gpriv_to_dev(gpriv);
802 priv = usbhsg_gpriv_to_priv(gpriv); 826 priv = usbhsg_gpriv_to_priv(gpriv);
803 827
@@ -919,7 +943,7 @@ int __devinit usbhs_mod_gadget_probe(struct usbhs_priv *priv)
919 } 943 }
920 } 944 }
921 945
922 the_controller = gpriv; 946 usbhsg_controller_register(gpriv);
923 947
924 ret = usb_add_gadget_udc(dev, &gpriv->gadget); 948 ret = usb_add_gadget_udc(dev, &gpriv->gadget);
925 if (ret) 949 if (ret)
@@ -943,6 +967,9 @@ void __devexit usbhs_mod_gadget_remove(struct usbhs_priv *priv)
943 struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); 967 struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv);
944 968
945 usb_del_gadget_udc(&gpriv->gadget); 969 usb_del_gadget_udc(&gpriv->gadget);
970
971 usbhsg_controller_unregister(gpriv);
972
946 kfree(gpriv->uep); 973 kfree(gpriv->uep);
947 kfree(gpriv); 974 kfree(gpriv);
948} 975}