All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vivek Gautam <gautam.vivek@samsung.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 2/2] RFC: usb: host: Introduce host translational layer
Date: Tue, 24 Jun 2014 19:40:22 +0530	[thread overview]
Message-ID: <1403619022-15662-3-git-send-email-gautam.vivek@samsung.com> (raw)
In-Reply-To: <1403619022-15662-1-git-send-email-gautam.vivek@samsung.com>

Introduce a wrapper layer to translate submit_**_msg() APIs
as well as usb_lowlevel_**() APIs so as to enable using
mutiple controller types viz. OHCI/EHCI/XHCI.

This is still WIP, with support for APIs translation for
EHCI and XHCI only.

Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
---
 common/usb.c                  |    8 ++--
 drivers/usb/host/Makefile     |    2 +
 drivers/usb/host/ehci-hcd.c   |   15 +++---
 drivers/usb/host/host_trans.c |  102 +++++++++++++++++++++++++++++++++++++++++
 drivers/usb/host/host_trans.h |   42 +++++++++++++++++
 drivers/usb/host/xhci.c       |   11 +++--
 include/usb.h                 |   15 +++---
 7 files changed, 174 insertions(+), 21 deletions(-)
 create mode 100644 drivers/usb/host/host_trans.c
 create mode 100644 drivers/usb/host/host_trans.h

diff --git a/common/usb.c b/common/usb.c
index 5dd09aa..ae483d0 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -58,6 +58,7 @@ char usb_started; /* flag for the started/stopped USB status */
 int usb_init(void)
 {
 	void *ctrl;
+	int ctrl_type;
 	struct usb_device *dev;
 	int i, start_index = 0;
 
@@ -75,7 +76,7 @@ int usb_init(void)
 	for (i = 0; i < CONFIG_USB_MAX_CONTROLLER_COUNT; i++) {
 		/* init low_level USB */
 		printf("USB%d:   ", i);
-		if (usb_lowlevel_init(i, USB_INIT_HOST, &ctrl)) {
+		if (usb_lowlevel_init(i, USB_INIT_HOST, &ctrl, &ctrl_type)) {
 			puts("lowlevel init failed\n");
 			continue;
 		}
@@ -86,6 +87,7 @@ int usb_init(void)
 		start_index = dev_index;
 		printf("scanning bus %d for devices... ", i);
 		dev = usb_alloc_new_device(ctrl);
+		dev->ctrl_type = ctrl_type;
 		/*
 		 * device 0 is always present
 		 * (root hub, so let it analyze)
@@ -193,7 +195,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;
@@ -226,7 +228,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))
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 7211c6a..9c6eb84 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -43,3 +43,5 @@ obj-$(CONFIG_USB_EHCI_ZYNQ) += ehci-zynq.o
 obj-$(CONFIG_USB_XHCI) += xhci.o xhci-mem.o xhci-ring.o
 obj-$(CONFIG_USB_XHCI_EXYNOS) += xhci-exynos5.o
 obj-$(CONFIG_USB_XHCI_OMAP) += xhci-omap.o
+
+obj-$(CONFIG_USB_HOST_TRANS) += host_trans.o
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index eaf5913..460c509 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -31,6 +31,7 @@
 #include <linux/compiler.h>
 
 #include "ehci.h"
+#include "host_trans.h"
 
 #ifndef CONFIG_USB_MAX_CONTROLLER_COUNT
 #define CONFIG_USB_MAX_CONTROLLER_COUNT 1
@@ -917,13 +918,13 @@ unknown:
 	return -1;
 }
 
-int usb_lowlevel_stop(int index)
+int ehci_lowlevel_stop(int index)
 {
 	ehci_shutdown(&ehcic[index]);
 	return ehci_hcd_stop(index);
 }
 
-int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
+int ehci_lowlevel_init(int index, enum usb_init_type init, void **controller)
 {
 	uint32_t reg;
 	uint32_t cmd;
@@ -1052,8 +1053,8 @@ done:
 }
 
 int
-submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
-		int length)
+ehci_submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
+			void *buffer, int length)
 {
 
 	if (usb_pipetype(pipe) != PIPE_BULK) {
@@ -1064,8 +1065,8 @@ submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 }
 
 int
-submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
-		   int length, struct devrequest *setup)
+ehci_submit_control_msg(struct usb_device *dev, unsigned long pipe,
+			void *buffer, int length, struct devrequest *setup)
 {
 	struct ehci_ctrl *ctrl = dev->controller;
 
@@ -1348,7 +1349,7 @@ out:
 }
 
 int
-submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+ehci_submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 	       int length, int interval)
 {
 	void *backbuffer;
diff --git a/drivers/usb/host/host_trans.c b/drivers/usb/host/host_trans.c
new file mode 100644
index 0000000..701faa2
--- /dev/null
+++ b/drivers/usb/host/host_trans.c
@@ -0,0 +1,102 @@
+/*
+ * USB HOST Controller translation layer
+ *
+ * Provides a smooth translation from usb_*() APIs from
+ * core usb drivers to controller drivers, enabling simultaneous
+ * use of different types of controller at once.
+ *
+ * Copyright (C) 2014 Samsung Electronics Co.Ltd
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include "host_trans.h"
+
+static int ehci_count;
+static int xhci_count;
+
+int usb_lowlevel_init(int index, enum usb_init_type init, void **controller,
+			int *ctrl_type)
+{
+	if (index >= CONFIG_USB_MAX_CONTROLLER_COUNT)
+		return 0;
+
+	/* first enumerate available EHCI controllers */
+	if (ehci_count < CONFIG_USB_MAX_EHCI_COUNT) {
+		if (ehci_lowlevel_init) {
+			ehci_count++;
+			*ctrl_type = USB_HOST_EHCI;
+			/* init max number of ehci controllers */
+			return ehci_lowlevel_init(ehci_count, init, controller);
+		}
+	}
+
+	if (xhci_count < CONFIG_USB_MAX_XHCI_COUNT) {
+		if (xhci_lowlevel_init) {
+			xhci_count++;
+			*ctrl_type = USB_HOST_XHCI;
+			/* init max number of xhci controllers */
+			return xhci_lowlevel_init(index, init, controller);
+		}
+	}
+
+	return -1;
+}
+
+int usb_lowlevel_stop(int index)
+{
+	if (index >= CONFIG_USB_MAX_CONTROLLER_COUNT)
+		return 0;
+
+	ehci_count = xhci_count = 0;
+
+	if (ehci_count < CONFIG_USB_MAX_EHCI_COUNT) {
+		if (ehci_lowlevel_init) {
+			ehci_count++;
+			return ehci_lowlevel_stop(index);
+		}
+	}
+
+	if (xhci_count < CONFIG_USB_MAX_XHCI_COUNT) {
+		if (xhci_lowlevel_init) {
+			xhci_count++;
+			return xhci_lowlevel_stop(index);
+		}
+	}
+
+	return -1;
+}
+
+int usb_submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
+			void *buffer, int transfer_len)
+{
+	if (dev->ctrl_type == USB_HOST_EHCI)
+		return ehci_submit_bulk_msg(dev, pipe, buffer, transfer_len);
+
+	if (dev->ctrl_type == USB_HOST_XHCI)
+		return xhci_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)
+{
+	if (dev->ctrl_type == USB_HOST_EHCI)
+		return ehci_submit_control_msg(dev, pipe, buffer,
+						transfer_len, setup);
+
+	if (dev->ctrl_type == USB_HOST_EHCI)
+		return xhci_submit_control_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)
+{
+	if (dev->ctrl_type == USB_HOST_EHCI)
+		return ehci_submit_int_msg(dev, pipe, buffer,
+						transfer_len, interval);
+
+	if (dev->ctrl_type == USB_HOST_XHCI)
+		return xhci_submit_int_msg(dev, pipe, buffer,
+						transfer_len, interval);
+}
diff --git a/drivers/usb/host/host_trans.h b/drivers/usb/host/host_trans.h
new file mode 100644
index 0000000..90bcc92
--- /dev/null
+++ b/drivers/usb/host/host_trans.h
@@ -0,0 +1,42 @@
+
+#ifndef _HOST_TRANS_H_
+#define _HOST_TRANS_H_
+
+#include <common.h>
+#include <usb.h>
+#include <linux/compat.h>
+
+#ifndef CONFIG_USB_MAX_EHCI_COUNT
+#define CONFIG_USB_MAX_EHCI_COUNT 1
+#endif
+
+#ifndef CONFIG_USB_MAX_XHCI_COUNT
+#define CONFIG_USB_MAX_XHCI_COUNT 1
+#endif
+
+enum usb_ctrl_type {
+	USB_HOST_OHCI,
+	USB_HOST_UHCI,
+	USB_HOST_EHCI,
+	USB_HOST_XHCI,
+};
+
+int ehci_submit_int_msg(struct usb_device *dev, unsigned long pipe,
+			void *buffer, int length, int interval);
+int ehci_submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
+			 void *buffer, int length);
+int ehci_submit_control_msg(struct usb_device *dev, unsigned long pipe,
+			    void *buffer, int length, struct devrequest *setup);
+int ehci_lowlevel_init(int index, enum usb_init_type init, void **controller);
+int ehci_lowlevel_stop(int index);
+
+int xhci_submit_int_msg(struct usb_device *udev, unsigned long pipe,
+			void *buffer, int length, int interval);
+int xhci_submit_bulk_msg(struct usb_device *udev, unsigned long pipe,
+			 void *buffer, int length);
+int xhci_submit_control_msg(struct usb_device *udev, unsigned long pipe,
+			    void *buffer, int length, struct devrequest *setup);
+int xhci_lowlevel_init(int index, enum usb_init_type init, void **controller);
+int xhci_lowlevel_stop(int index);
+
+#endif /* _HOST_TRANS_H_ */
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index d1c2e5c..2e7e3f0 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -29,6 +29,7 @@
 #include <asm/unaligned.h>
 #include <asm-generic/errno.h>
 #include "xhci.h"
+#include "host_trans.h"
 
 #ifndef CONFIG_USB_MAX_CONTROLLER_COUNT
 #define CONFIG_USB_MAX_CONTROLLER_COUNT 1
@@ -859,7 +860,7 @@ unknown:
  * @return 0
  */
 int
-submit_int_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
+xhci_submit_int_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
 						int length, int interval)
 {
 	/*
@@ -879,7 +880,7 @@ submit_int_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
  * @return returns 0 if successful else -1 on failure
  */
 int
-submit_bulk_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
+xhci_submit_bulk_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
 								int length)
 {
 	if (usb_pipetype(pipe) != PIPE_BULK) {
@@ -901,7 +902,7 @@ submit_bulk_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
  * @return returns 0 if successful else -1 on failure
  */
 int
-submit_control_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
+xhci_submit_control_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
 					int length, struct devrequest *setup)
 {
 	struct xhci_ctrl *ctrl = udev->controller;
@@ -936,7 +937,7 @@ submit_control_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
  * @param index	index to the host controller data structure
  * @return pointer to the intialised controller
  */
-int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
+int xhci_lowlevel_init(int index, enum usb_init_type init, void **controller)
 {
 	uint32_t val;
 	uint32_t val2;
@@ -1009,7 +1010,7 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
  * @param index	index to the host controller data structure
  * @return none
  */
-int usb_lowlevel_stop(int index)
+int xhci_lowlevel_stop(int index)
 {
 	struct xhci_ctrl *ctrl = (xhcic + index);
 	u32 temp;
diff --git a/include/usb.h b/include/usb.h
index 30fc890..212a34d 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -125,6 +125,7 @@ struct usb_device {
 	struct usb_device *children[USB_MAXCHILDREN];
 
 	void *controller;		/* hardware controller private data */
+	int ctrl_type;			/* controller type - OHCI/EHCI/XHCI */
 	/* slot_id - for xHCI enabled devices */
 	unsigned int slot_id;
 };
@@ -152,15 +153,17 @@ enum usb_init_type {
 	defined(CONFIG_USB_MUSB_DSPS) || defined(CONFIG_USB_MUSB_AM35X) || \
 	defined(CONFIG_USB_MUSB_OMAP2PLUS) || defined(CONFIG_USB_XHCI)
 
-int usb_lowlevel_init(int index, enum usb_init_type init, void **controller);
+int usb_lowlevel_init(int index, enum usb_init_type init, void **controller,
+			int *ctrl_type);
 int usb_lowlevel_stop(int index);
 
-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);
 
 /* Defines */
 #define USB_UHCI_VEND_ID	0x8086
-- 
1.7.10.4

  parent reply	other threads:[~2014-06-24 14:10 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-06-24 14:10 [U-Boot] [PATCH RFC 0/2] usb: host: Add a wrapper layer for mutiple host support Vivek Gautam
2014-06-24 14:10 ` [U-Boot] [PATCH 1/2] usb: Rename usb_submit_int_msg() API to usb_int_msg() Vivek Gautam
2014-06-24 14:10 ` Vivek Gautam [this message]
2014-06-24 14:26 ` [U-Boot] [PATCH RFC 0/2] usb: host: Add a wrapper layer for mutiple host support Marek Vasut
2014-06-25  5:11   ` Vivek Gautam
2014-06-25  6:08     ` Marek Vasut
2014-06-25  6:27       ` Simon Glass
2014-06-25  8:33         ` Marek Vasut
2014-06-26  2:30           ` Simon Glass
2014-06-26  4:34             ` Vivek Gautam
2014-06-26  4:46               ` Vivek Gautam
2014-06-26  9:21                 ` Marek Vasut
2014-07-07 22:46                   ` Simon Glass

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1403619022-15662-3-git-send-email-gautam.vivek@samsung.com \
    --to=gautam.vivek@samsung.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.