Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

usb: renesas_usbhs: support multi driver

Some SuperH/board has multi USBHS on it.
This patch supports multi register for renesas_usbhs

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Kuninori Morimoto and committed by
Greg Kroah-Hartman
3b872188 4ef85e0f

+41 -14
+41 -14
drivers/usb/renesas_usbhs/mod_gadget.c
··· 44 44 struct usbhsg_gpriv { 45 45 struct usb_gadget gadget; 46 46 struct usbhs_mod mod; 47 + struct list_head link; 47 48 48 49 struct usbhsg_uep *uep; 49 50 int uep_size; ··· 113 112 #define usbhsg_status_set(gp, b) (gp->status |= b) 114 113 #define usbhsg_status_clr(gp, b) (gp->status &= ~b) 115 114 #define usbhsg_status_has(gp, b) (gp->status & b) 115 + 116 + /* controller */ 117 + LIST_HEAD(the_controller_link); 118 + 119 + #define usbhsg_for_each_controller(gpriv)\ 120 + list_for_each_entry(gpriv, &the_controller_link, link) 121 + #define usbhsg_controller_register(gpriv)\ 122 + list_add_tail(&(gpriv)->link, &the_controller_link) 123 + #define usbhsg_controller_unregister(gpriv)\ 124 + list_del_init(&(gpriv)->link) 116 125 117 126 /* 118 127 * queue push/pop ··· 743 732 * linux usb function 744 733 * 745 734 */ 746 - struct usbhsg_gpriv *the_controller; 747 735 static int usbhsg_gadget_start(struct usb_gadget_driver *driver, 748 736 int (*bind)(struct usb_gadget *)) 749 737 { 750 - struct usbhsg_gpriv *gpriv = the_controller; 738 + struct usbhsg_gpriv *gpriv; 751 739 struct usbhs_priv *priv; 752 740 struct device *dev; 753 741 int ret; ··· 756 746 !driver->setup || 757 747 driver->speed != USB_SPEED_HIGH) 758 748 return -EINVAL; 759 - if (!gpriv) 760 - return -ENODEV; 761 - if (gpriv->driver) 762 - return -EBUSY; 749 + 750 + /* 751 + * find unused controller 752 + */ 753 + usbhsg_for_each_controller(gpriv) { 754 + if (!gpriv->driver) 755 + goto find_unused_controller; 756 + } 757 + return -ENODEV; 758 + 759 + find_unused_controller: 763 760 764 761 dev = usbhsg_gpriv_to_dev(gpriv); 765 762 priv = usbhsg_gpriv_to_priv(gpriv); ··· 803 786 804 787 static int usbhsg_gadget_stop(struct usb_gadget_driver *driver) 805 788 { 806 - struct usbhsg_gpriv *gpriv = the_controller; 789 + struct usbhsg_gpriv *gpriv; 807 790 struct usbhs_priv *priv; 808 - struct device *dev = usbhsg_gpriv_to_dev(gpriv); 809 - 810 - if (!gpriv) 811 - return -ENODEV; 791 + struct device *dev; 812 792 813 793 if (!driver || 814 - !driver->unbind || 815 - driver != gpriv->driver) 794 + !driver->unbind) 816 795 return -EINVAL; 796 + 797 + /* 798 + * find controller 799 + */ 800 + usbhsg_for_each_controller(gpriv) { 801 + if (gpriv->driver == driver) 802 + goto find_matching_controller; 803 + } 804 + return -ENODEV; 805 + 806 + find_matching_controller: 817 807 818 808 dev = usbhsg_gpriv_to_dev(gpriv); 819 809 priv = usbhsg_gpriv_to_priv(gpriv); ··· 943 919 } 944 920 } 945 921 946 - the_controller = gpriv; 922 + usbhsg_controller_register(gpriv); 947 923 948 924 ret = usb_add_gadget_udc(dev, &gpriv->gadget); 949 925 if (ret) ··· 967 943 struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); 968 944 969 945 usb_del_gadget_udc(&gpriv->gadget); 946 + 947 + usbhsg_controller_unregister(gpriv); 948 + 970 949 kfree(gpriv->uep); 971 950 kfree(gpriv); 972 951 }