
Adding a UCLASS driver for USB based on driver-model, to facilitate binding mutiple host-controllers to their respective drivers, and thereby enable using mutiple controllers simultaneously on a platform.
Signed-off-by: Vivek Gautam gautam.vivek@samsung.com --- drivers/usb/host/Kconfig | 9 ++++ drivers/usb/host/Makefile | 3 ++ drivers/usb/host/usb-uclass.c | 107 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 119 insertions(+) create mode 100644 drivers/usb/host/usb-uclass.c
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 30d1457..fceacbb 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -3,6 +3,15 @@ # comment "USB Host Controller Drivers"
+config DM_USB + bool "USB Driver model support" + ---help--- + Driver model support for USB host controller drivers. + This will allow use of mutiple kinds of host controllers viz. OHCI, + EHCI, XHCI, etc simultaneously which was not possible till now. + Say 'y' if you have mutiple types of controllers on your boards + and would like to enable support for all of them. + config USB_XHCI_HCD bool "xHCI HCD (USB 3.0) support" ---help--- diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 66d6e9a..d54e2a7 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -5,6 +5,9 @@ # SPDX-License-Identifier: GPL-2.0+ #
+# usb driver-model +obj-$(CONFIG_DM_USB) += usb-uclass.o + # ohci obj-$(CONFIG_USB_OHCI_NEW) += ohci-hcd.o obj-$(CONFIG_USB_ATMEL) += ohci-at91.o diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c new file mode 100644 index 0000000..e7a97ec --- /dev/null +++ b/drivers/usb/host/usb-uclass.c @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2014 Samsung Electronics Co.Ltd + * + * Provides a smooth translation from usb_*() APIs from + * core usb drivers to controller drivers, enabling simultaneous + * use of different types of controller at once. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <linux/err.h> +#include <asm/io.h> +#include <usb.h> +//#include <linux/list.h> + +//DECLARE_GLOBAL_DATA_PTR; + +UCLASS_DRIVER(usb) = { + .name = "usb", + .id = UCLASS_USB, +}; + +int usb_lowlevel_init(int index, enum usb_init_type init, + void **controller, struct udevice *udev_usb) +{ + const struct usb_ops *ops; + + if (IS_ERR(udev_usb)) + return -EINVAL; + + ops = device_get_ops(udev_usb); + + if (!ops->lowlevel_init) + return -ENOSYS; + + return ops->lowlevel_init(index, init, controller); +} + +int usb_lowlevel_stop(int index, struct udevice *udev_usb) +{ + const struct usb_ops *ops; + + if (IS_ERR(udev_usb)) + return -EINVAL; + + ops = device_get_ops(udev_usb); + + if (!ops->lowlevel_stop) + return -ENOSYS; + + return ops->lowlevel_stop(index); +} + +int usb_submit_bulk_msg(struct usb_device *dev, unsigned long pipe, + void *buffer, int transfer_len, + struct udevice *udev_usb) +{ + const struct usb_ops *ops; + + if (IS_ERR(udev_usb)) + return -EINVAL; + + ops = device_get_ops(udev_usb); + + if (!ops->submit_bulk_msg) + return -ENOSYS; + + return ops->submit_bulk_msg(dev, pipe, buffer, transfer_len); +} + +int usb_submit_control_msg(struct usb_device *dev, unsigned long pipe, + void *buffer, int transfer_len, + struct devrequest *setup, struct udevice *udev_usb) +{ + const struct usb_ops *ops; + + if (IS_ERR(udev_usb)) + return -EINVAL; + + ops = device_get_ops(udev_usb); + + if (!ops->submit_ctrl_msg) + return -ENOSYS; + + return ops->submit_ctrl_msg(dev,pipe, buffer, transfer_len, setup); +} + +int usb_submit_int_msg(struct usb_device *dev, unsigned long pipe, + void *buffer, int transfer_len, + int interval, struct udevice *udev_usb) +{ + const struct usb_ops *ops; + + if (IS_ERR(udev_usb)) + return -EINVAL; + + ops = device_get_ops(udev_usb); + + if (!ops->submit_int_msg) + return -ENOSYS; + + return ops->submit_int_msg(dev, pipe, buffer, transfer_len, interval); +}