[U-Boot] [PATCH RFC 2/6] dm: usb: Make necessary changes in framework for driver model

Vivek Gautam gautam.vivek at samsung.com
Wed Feb 18 11:41:35 CET 2015


Add wrapper functions for usb layer operations for control, bulk,
interrupt transfers to accomodate support for driver model.

Signed-off-by: Vivek Gautam <gautam.vivek at samsung.com>
---
 common/usb.c           |   99 ++++++++++++++++++++++++++++++++++++++++++++----
 common/usb_hub.c       |    2 +-
 include/dm/uclass-id.h |    1 +
 include/usb.h          |   60 +++++++++++++++++++++++------
 4 files changed, 142 insertions(+), 20 deletions(-)

diff --git a/common/usb.c b/common/usb.c
index 849df27..407cc30 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -29,6 +29,7 @@
 #include <common.h>
 #include <command.h>
 #include <asm/processor.h>
+#include <dm/uclass.h>
 #include <linux/compiler.h>
 #include <linux/ctype.h>
 #include <asm/byteorder.h>
@@ -45,12 +46,83 @@ static struct usb_device usb_dev[USB_MAX_DEVICE];
 static int dev_index;
 static int asynch_allowed;
 
+static struct udevice *udev_usb;
+
 char usb_started; /* flag for the started/stopped USB status */
 
 #ifndef CONFIG_USB_MAX_CONTROLLER_COUNT
 #define CONFIG_USB_MAX_CONTROLLER_COUNT 1
 #endif
 
+#ifdef CONFIG_DM_USB
+/* Wrappers for Driver model */
+static inline int _usb_lowlevel_init(int index, enum usb_init_type init,
+							void **ctrl)
+{
+	return usb_lowlevel_init(index, USB_INIT_HOST, ctrl, udev_usb);
+}
+
+static inline int _usb_lowlevel_stop(int index)
+{
+	return usb_lowlevel_stop(index, udev_usb);
+}
+
+static inline int _usb_submit_control_msg(struct usb_device *dev,
+				unsigned long pipe, void *data,
+				int transfer_len, struct devrequest *setup)
+{
+	return usb_submit_control_msg(dev, pipe, data, transfer_len,
+					      setup, dev->udev_usb);
+}
+
+static inline int _usb_submit_bulk_msg(struct usb_device *dev,
+				unsigned int pipe, void *data, int transfer_len)
+{
+	return usb_submit_bulk_msg(dev, pipe, data, transfer_len,
+					   dev->udev_usb);
+}
+
+static inline int _usb_submit_int_msg(struct usb_device *dev,
+				unsigned long pipe, void *data,
+				int transfer_len, int interval)
+{
+	return usb_submit_int_msg(dev, pipe, data, transfer_len,
+					  interval, dev->udev_usb);
+}
+#else
+static inline int _usb_lowlevel_init(int index, enum usb_init_type init,
+							void **ctrl)
+{
+	return usb_lowlevel_init(index, USB_INIT_HOST, ctrl);
+}
+
+static inline int _usb_lowlevel_stop(int index)
+{
+	return usb_lowlevel_stop(index);
+}
+
+static inline int _usb_submit_control_msg(struct usb_device *dev,
+				unsigned long pipe, void *data,
+				int transfer_len, struct devrequest *setup)
+{
+	return usb_submit_control_msg(dev, pipe, data, transfer_len, setup);
+}
+
+static inline int _usb_submit_bulk_msg(struct usb_device *dev,
+				unsigned int pipe, void *data, int transfer_len)
+{
+	return usb_submit_bulk_msg(dev, pipe, data, transfer_len);
+}
+
+static inline int _usb_submit_int_msg(struct usb_device *dev,
+				unsigned long pipe, void *data,
+				int transfer_len, int interval)
+{
+	return usb_submit_int_msg(dev, pipe, data, transfer_len, interval);
+}
+#endif
+
+
 /***************************************************************************
  * Init USB Device
  */
@@ -74,9 +146,20 @@ int usb_init(void)
 
 	/* init low_level USB */
 	for (i = 0; i < CONFIG_USB_MAX_CONTROLLER_COUNT; i++) {
+#ifdef CONFIG_DM_USB
+		/* Get the udevice here for given index */
+		uclass_get_device(UCLASS_USB, i, &udev_usb);
+#else
+		udev_usb = -ERR_PTR(ENOSYS);
+#endif
+
+		/* Now this udev is a pointer to the particular controller
+		 * driver, which we can use now.
+		 */
+
 		/* init low_level USB */
 		printf("USB%d:   ", i);
-		ret = usb_lowlevel_init(i, USB_INIT_HOST, &ctrl);
+		ret = _usb_lowlevel_init(i, USB_INIT_HOST, &ctrl);
 		if (ret == -ENODEV) {	/* No such device. */
 			puts("Port not available.\n");
 			controllers_initialized++;
@@ -94,7 +177,7 @@ int usb_init(void)
 		controllers_initialized++;
 		start_index = dev_index;
 		printf("scanning bus %d for devices... ", i);
-		dev = usb_alloc_new_device(ctrl);
+		dev = usb_alloc_new_device(ctrl, udev_usb);
 		/*
 		 * device 0 is always present
 		 * (root hub, so let it analyze)
@@ -132,7 +215,7 @@ int usb_stop(void)
 		usb_hub_reset();
 
 		for (i = 0; i < CONFIG_USB_MAX_CONTROLLER_COUNT; i++) {
-			if (usb_lowlevel_stop(i))
+			if (_usb_lowlevel_stop(i))
 				printf("failed to stop USB controller %d\n", i);
 		}
 	}
@@ -165,7 +248,7 @@ int usb_disable_asynch(int disable)
 int usb_int_msg(struct usb_device *dev, unsigned long pipe,
 			void *buffer, int transfer_len, int interval)
 {
-	return usb_submit_int_msg(dev, pipe, buffer, transfer_len, interval);
+	return _usb_submit_int_msg(dev, pipe, buffer, transfer_len, interval);
 }
 
 /*
@@ -200,7 +283,7 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe,
 	      request, requesttype, value, index, size);
 	dev->status = USB_ST_NOT_PROC; /*not yet processed */
 
-	if (submit_control_msg(dev, pipe, data, size, setup_packet) < 0)
+	if (_usb_submit_control_msg(dev, pipe, data, size, setup_packet) < 0)
 		return -1;
 	if (timeout == 0)
 		return (int)size;
@@ -233,7 +316,7 @@ int usb_bulk_msg(struct usb_device *dev, unsigned int pipe,
 	if (len < 0)
 		return -1;
 	dev->status = USB_ST_NOT_PROC; /*not yet processed */
-	if (submit_bulk_msg(dev, pipe, data, len) < 0)
+	if (_usb_submit_bulk_msg(dev, pipe, data, len) < 0)
 		return -1;
 	while (timeout--) {
 		if (!((volatile unsigned long)dev->status & USB_ST_NOT_PROC))
@@ -830,7 +913,8 @@ struct usb_device *usb_get_dev_index(int index)
 /* returns a pointer of a new device structure or NULL, if
  * no device struct is available
  */
-struct usb_device *usb_alloc_new_device(void *controller)
+struct usb_device *usb_alloc_new_device(void *controller,
+					struct udevice *udev_usb)
 {
 	int i;
 	debug("New Device %d\n", dev_index);
@@ -845,6 +929,7 @@ struct usb_device *usb_alloc_new_device(void *controller)
 		usb_dev[dev_index].children[i] = NULL;
 	usb_dev[dev_index].parent = NULL;
 	usb_dev[dev_index].controller = controller;
+	usb_dev[dev_index].udev_usb = udev_usb;
 	dev_index++;
 	return &usb_dev[dev_index - 1];
 }
diff --git a/common/usb_hub.c b/common/usb_hub.c
index 66b4a72..0afe6ac 100644
--- a/common/usb_hub.c
+++ b/common/usb_hub.c
@@ -246,7 +246,7 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
 	mdelay(200);
 
 	/* Allocate a new device struct for it */
-	usb = usb_alloc_new_device(dev->controller);
+	usb = usb_alloc_new_device(dev->controller, dev->udev_usb);
 
 	switch (portstatus & USB_PORT_STAT_SPEED_MASK) {
 	case USB_PORT_STAT_SUPER_SPEED:
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index 91bb90d..4f91e87 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -34,6 +34,7 @@ enum uclass_id {
 	UCLASS_I2C_GENERIC,	/* Generic I2C device */
 	UCLASS_I2C_EEPROM,	/* I2C EEPROM device */
 	UCLASS_MOD_EXP,		/* RSA Mod Exp device */
+	UCLASS_USB,		/* USB host class */
 
 	UCLASS_COUNT,
 	UCLASS_INVALID = -1,
diff --git a/include/usb.h b/include/usb.h
index d1576b2..861f2fa 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -13,6 +13,7 @@
 #include <linux/usb/ch9.h>
 #include <asm/cache.h>
 #include <part.h>
+#include <dm.h>
 
 /*
  * The EHCI spec says that we must align to at least 32 bytes.  However,
@@ -130,6 +131,9 @@ struct usb_device {
 	void *controller;		/* hardware controller private data */
 	/* slot_id - for xHCI enabled devices */
 	unsigned int slot_id;
+
+	/* UClass device */
+	struct udevice *udev_usb;
 };
 
 struct int_queue;
@@ -158,20 +162,45 @@ enum usb_init_type {
 	defined(CONFIG_USB_MUSB_OMAP2PLUS) || defined(CONFIG_USB_MUSB_SUNXI) || \
 	defined(CONFIG_USB_XHCI) || defined(CONFIG_USB_DWC2)
 
+#ifdef CONFIG_DM_USB
+int usb_lowlevel_init(int index, enum usb_init_type init,
+			void **controller, struct udevice *udev_usb);
+int usb_lowlevel_stop(int index, struct udevice *udev_usb);
+
+int usb_submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
+			void *buffer, int transfer_len,
+			struct udevice *udev_usb);
+int usb_submit_control_msg(struct usb_device *dev, unsigned long pipe,
+			void *buffer, int transfer_len,
+			struct devrequest *setup, struct udevice *udev_usb);
+int usb_submit_int_msg(struct usb_device *dev, unsigned long pipe,
+			void *buffer, int transfer_len,
+			int interval, struct udevice *udev_usb);
+
+struct usb_ops {
+	int (*lowlevel_init)(int index, enum usb_init_type init,
+				void **controller);
+	int (*lowlevel_stop)(int index);
+	int (*submit_bulk_msg)(struct usb_device *dev, unsigned long pipe,
+				void *buffer, int transfer_len);
+	int (*submit_ctrl_msg)(struct usb_device *dev, unsigned long pipe,
+				void *buffer, int transfer_len,
+				struct devrequest *setup);
+	int (*submit_int_msg)(struct usb_device *dev, unsigned long pipe,
+				void *buffer, int transfer_len,
+				int interval);
+};
+#else
 int usb_lowlevel_init(int index, enum usb_init_type init, void **controller);
 int usb_lowlevel_stop(int index);
-#ifdef CONFIG_MUSB_HOST
-void usb_reset_root_port(void);
-#else
-#define usb_reset_root_port()
-#endif
-
-int submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
+int usb_submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
 			void *buffer, int transfer_len);
-int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
-			int transfer_len, struct devrequest *setup);
-int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
-			int transfer_len, int interval);
+int usb_submit_control_msg(struct usb_device *dev, unsigned long pipe,
+			   void *buffer, int transfer_len,
+			   struct devrequest *setup);
+int usb_submit_int_msg(struct usb_device *dev, unsigned long pipe,
+			void *buffer, int transfer_len, int interval);
+#endif
 
 #if defined CONFIG_USB_EHCI || defined CONFIG_MUSB_HOST
 struct int_queue *create_int_queue(struct usb_device *dev, unsigned long pipe,
@@ -180,6 +209,12 @@ int destroy_int_queue(struct usb_device *dev, struct int_queue *queue);
 void *poll_int_queue(struct usb_device *dev, struct int_queue *queue);
 #endif
 
+#ifdef CONFIG_MUSB_HOST
+void usb_reset_root_port(void);
+#else
+#define usb_reset_root_port()
+#endif
+
 /* Defines */
 #define USB_UHCI_VEND_ID	0x8086
 #define USB_UHCI_DEV_ID		0x7112
@@ -428,7 +463,8 @@ void usb_hub_reset(void);
 int hub_port_reset(struct usb_device *dev, int port,
 			  unsigned short *portstat);
 
-struct usb_device *usb_alloc_new_device(void *controller);
+struct usb_device *usb_alloc_new_device(void *controller,
+				struct udevice *udev_usb);
 
 int usb_new_device(struct usb_device *dev);
 void usb_free_device(void);
-- 
1.7.10.4



More information about the U-Boot mailing list