[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