All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v2 0/80] dm: Add USB support
@ 2015-03-25 18:21 Simon Glass
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 01/80] linker_lists: Add a function to access a linker list entry Simon Glass
                   ` (80 more replies)
  0 siblings, 81 replies; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:21 UTC (permalink / raw)
  To: u-boot

This series adds driver model support to USB. The intent is to permit the
various subsystems (OHCI, EHCI, XHCI) to co-exist and allow any number of USB
ports of different types.

With the RFC series, only USB controllers had a real driver model device.
USB devices (including the hub in the controller) were not modelled as driver
model devices.

While this was expedient, and produced much fewer patches, it is not a
long-term solution. Also, since then, driver model Ethernet support (which
USB can use) has been merged to u-boot-dm/next. It seems better to bite the
bullet and do a full conversion.

Unfortunately this results in a very large series. It includes:

- USB uclass
- USB hub uclass
- Adjustments to make USB keyboard, Ethernet and storage continue to work
- Sandbox USB emulation support
- Sandbox USB emulations for flash and hub devices
- A reasonable set of tests
- EHCI and XHCI support (not OHCI)
- Conversion of Tegra and Exynos drivers to driver model
- Adjustments to make the 'usb' command operate as expected
- README describing how USB works with driver model

Both EHCI and XHCI needed a little bit of refactoring before they are
converted to driver model - e.g. removal of weak fuctions and splitting up
the init code.

This series includes patches to remove the non-driver-model code for Exynos
and Tegra, to be applied once everything is stable. For now it is convenient
to be able to compare the two options.

This series does not change how USB is started up. The 'usb start' command
scans the buses as before, and takes just as long. Once it has started you
can use 'dm tree' to see the tree structure of the USB bus, although 'usb
tree' provides a better view. It is unclear how we could implement lazy init
for USB given the long time it takes to probe the bus.

A README is provided to describe how USB works under driver model.

This series is available at u-boot-dm/usb-working.

Changes in v2:
- Rewrite and expand series to support driver model fully

Simon Glass (80):
  linker_lists: Add a function to access a linker list entry
  sandbox: Fix comment for os_open()
  dm: test: bus: Use a local variable to simplify code
  dm: exynos: snow: Move the keyboard to I2C
  dm: core: Support allocating driver-private data for DMA
  dm: core: Convert driver_bind() to use const
  dm: core: Rename driver data function to dev_get_driver_data()
  dm: core: Mark device as active before calling uclass probe() methods
  dm: core: Add device children and sibling functions
  dm: gpio: Add an implementation for gpio_get_number()
  dm: usb: Add a uclass for USB controllers
  dm: usb: Adjust usb command to prepare for driver model
  dm: usb: Adjust usb_alloc_new_device() to return an error
  dm: usb: Convert 'usb' command to support driver model
  dm: usb: Drop the legacy USB init sequence
  dm: usb: Refactor port resets
  dm: usb: Move descriptor setup code into its own function
  dm: usb: Split out more code from usb_new_device()
  dm: usb: Complete the splitting up of usb_new_device()
  dm: usb: Convert core usb.c file to support driver model
  dm: usb: Split hub detection into its own function
  dm: usb: Add driver model support for hubs
  dm: usb: Move USB storage definitions to usb_defs.h
  dm: usb: Fix type problems in usb_stor_get_info()
  dm: usb: Simply device finding code in usb_storage
  dm: usb: Adjust usb_storage to work with sandbox
  dm: usb: Move storage device scanning into its own function
  dm: usb: Convert usb_storage to driver model
  dm: usb: Move all the EHCI weak functions together and declare them
  dm: usb: Pass EHCI controller pointer to ehci_get_port_speed()
  dm: usb: Allow ECHI to hold private data for the controller
  dm: usb: tegra: Store the controller type explicitly
  dm: usb: Pass EHCI controller pointer to ehci_powerup_fixup()
  dm: usb: tegra: Drop use of global controller variable
  dm: usb: Pass EHCI controller pointer to ehci_set_usbmode()
  dm: usb: Pass EHCI controller pointer to ehci_get_portsc_register()
  dm: usb: ehci: Use a function to find the controller from struct
    udevice
  dm: usb: Refactor EHCI init
  dm: usb: Drop the EHCI weak functions
  dm: usb: Change ehci_reset() to use a pointer
  dm: usb: Add driver model support to EHCI
  dm: usb: Allow USB drivers to be declared and auto-probed
  dm: usb: Bind generic USB devices when there is no driver
  dm: usb: Allow setting up a USB controller as a device/gadget
  dm: usb: Split out the keyboard probe into its own function
  dm: usb: Support driver model with USB keyboards
  dm: usb: tegra: Add vbus GPIOs for nyan
  dm: usb: Move struct usb_string to a common place
  dm: usb: sandbox: Add a uclass for USB device emulation
  dm: usb: sandbox: Reset emulation devices in usb stop()
  dm: usb: sandbox: Add an emulator for USB flash devices
  dm: usb: sandbox: Add an emulator for USB hub emulation
  dm: usb: sandbox: Add a driver for sandbox
  dm: usb: dts: sandbox: Add some sample USB devices to sandbox
  dm: usb: Add support for USB ethernet devices with driver model
  dm: usb: exynos: Add driver model support to exynos EHCI
  dm: usb: tegra: Remove the port_addr_clear_csc variable
  dm: usb: tegra: Tidy up error handling and a static function
  dm: usb: tegra: Move most of init/uninit into a function
  dm: usb: tegra: Add driver model support to tegra EHCI
  dm: usb: xhci: Use a function to get xhci_ctrl
  dm: usb: xhci: Use explicit parameters for xhci_alloc_virt_device()
  dm: usb: xhci: Use explicit parameters for
    xhci_setup_addressable_virt_dev()
  dm: usb: xhci: Factor out common init/uninit
  dm: usb: Support driver model in XHCI
  dm: usb: Rename the XHCI HCD to U-Boot
  dm: usb: exynos: Adjust XHCI driver to support driver model
  dm: usb: exynos: Use driver model for USB
  dm: usb: exynos: Enable both USB ports on snow
  dm: usb: exynos: Enable both EHCI and XHCI on snow
  dm: usb: tegra: Move to driver model for USB
  dm: usb: Add a generic descriptor struct
  dm: usb: Tidy up pipe value decoding
  dm: usb: sandbox: Enable USB
  dm: test: Correct printf() output nit in 'dm uclass'
  dm: test: Allow 'dm test' to select a particular test to run
  dm: usb: Add tests for the USB uclass
  dm: usb: tegra: Drop legacy USB code
  dm: usb: exynos: Drop legacy USB code
  dm: usb: Add a README for driver model

 Makefile                                |   1 +
 arch/arm/cpu/armv7/exynos/Kconfig       |   3 +
 arch/arm/dts/exynos5250-snow.dts        |   5 +-
 arch/arm/dts/tegra124-nyan-big.dts      |   2 +
 arch/arm/mach-tegra/Kconfig             |   3 +
 arch/sandbox/dts/sandbox.dts            |  40 ++
 board/genesi/mx51_efikamx/efikamx-usb.c |   4 +-
 board/nvidia/common/board.c             |   1 -
 common/cmd_usb.c                        | 198 ++++++++--
 common/usb.c                            | 277 ++++++++------
 common/usb_hub.c                        | 194 ++++++++--
 common/usb_kbd.c                        | 119 ++++--
 common/usb_storage.c                    | 249 ++++++------
 configs/sandbox_defconfig               |   4 +
 doc/driver-model/usb-info.txt           | 415 ++++++++++++++++++++
 drivers/core/device-remove.c            |   4 +-
 drivers/core/device.c                   |  66 +++-
 drivers/core/lists.c                    |   2 +-
 drivers/gpio/gpio-uclass.c              |  12 +
 drivers/i2c/s3c24x0_i2c.c               |   2 +-
 drivers/i2c/tegra_i2c.c                 |   6 +-
 drivers/usb/Kconfig                     |  16 +
 drivers/usb/emul/Kconfig                |   8 +
 drivers/usb/emul/Makefile               |  10 +
 drivers/usb/emul/sandbox_flash.c        | 423 +++++++++++++++++++++
 drivers/usb/emul/sandbox_hub.c          | 303 +++++++++++++++
 drivers/usb/emul/usb-emul-uclass.c      | 263 +++++++++++++
 drivers/usb/eth/usb_ether.c             |  52 ++-
 drivers/usb/gadget/ci_udc.c             |   4 +
 drivers/usb/host/Makefile               |   5 +
 drivers/usb/host/ehci-exynos.c          | 127 +++----
 drivers/usb/host/ehci-faraday.c         | 112 +++---
 drivers/usb/host/ehci-hcd.c             | 379 ++++++++++++++-----
 drivers/usb/host/ehci-mx5.c             |  12 +
 drivers/usb/host/ehci-tegra.c           | 288 +++++++-------
 drivers/usb/host/ehci.h                 |  47 +++
 drivers/usb/host/usb-sandbox.c          | 117 ++++++
 drivers/usb/host/usb-uclass.c           | 645 ++++++++++++++++++++++++++++++++
 drivers/usb/host/xhci-exynos5.c         | 106 +++---
 drivers/usb/host/xhci-mem.c             |  24 +-
 drivers/usb/host/xhci-ring.c            |   8 +-
 drivers/usb/host/xhci.c                 | 312 ++++++++++++---
 drivers/usb/host/xhci.h                 |  31 +-
 drivers/usb/musb-new/musb_uboot.c       |   4 +-
 include/configs/sandbox.h               |   2 +
 include/configs/snow.h                  |   2 +
 include/dm/device-internal.h            |   2 +-
 include/dm/device.h                     |  51 ++-
 include/dm/test.h                       |   7 +-
 include/dm/uclass-id.h                  |   5 +
 include/fdtdec.h                        |   5 -
 include/linker_lists.h                  |  10 +
 include/linux/usb/ch9.h                 |  18 +
 include/linux/usb/gadget.h              |  13 -
 include/os.h                            |   2 +-
 include/usb.h                           | 494 +++++++++++++++++++++++-
 include/usb_defs.h                      |  68 +++-
 lib/fdtdec.c                            |   5 -
 test/dm/Makefile                        |   1 +
 test/dm/bus.c                           |  16 +-
 test/dm/cmd_dm.c                        |  13 +-
 test/dm/test-dm.sh                      |   3 +
 test/dm/test-main.c                     |   7 +-
 test/dm/test-uclass.c                   |   3 +-
 test/dm/test.dts                        |  41 ++
 test/dm/usb.c                           |  50 +++
 66 files changed, 4807 insertions(+), 914 deletions(-)
 create mode 100644 doc/driver-model/usb-info.txt
 create mode 100644 drivers/usb/emul/Kconfig
 create mode 100644 drivers/usb/emul/Makefile
 create mode 100644 drivers/usb/emul/sandbox_flash.c
 create mode 100644 drivers/usb/emul/sandbox_hub.c
 create mode 100644 drivers/usb/emul/usb-emul-uclass.c
 create mode 100644 drivers/usb/host/usb-sandbox.c
 create mode 100644 drivers/usb/host/usb-uclass.c
 create mode 100644 test/dm/usb.c

-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 01/80] linker_lists: Add a function to access a linker list entry
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
@ 2015-03-25 18:21 ` Simon Glass
  2015-04-07 18:39   ` Simon Glass
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 02/80] sandbox: Fix comment for os_open() Simon Glass
                   ` (79 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:21 UTC (permalink / raw)
  To: u-boot

Once declared, you cannot access a linker_list entry since you do not have
a symbol name for it. Add llsym() macro to provide this. This avoids
searching for the symbol at run-time based on name.

An example usage is to declare a driver with U_BOOT_DRIVER(), then obtain
a pointer to that driver later.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 include/linker_lists.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/include/linker_lists.h b/include/linker_lists.h
index 940c871..b22d169 100644
--- a/include/linker_lists.h
+++ b/include/linker_lists.h
@@ -103,6 +103,16 @@
  */
 
 /**
+ * ll_sym() - Access a linker-generated array entry
+ * @_type:	Data type of the entry
+ * @_name:	Name of the entry
+ * @_list:	name of the list. Should contain only characters allowed
+ *		in a C variable name!
+ */
+#define llsym(_type, _name, _list) \
+		((_type *)&_u_boot_list_2_##_list##_2_##_name)
+
+/**
  * ll_entry_declare() - Declare linker-generated array entry
  * @_type:	Data type of the entry
  * @_name:	Name of the entry
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 02/80] sandbox: Fix comment for os_open()
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 01/80] linker_lists: Add a function to access a linker list entry Simon Glass
@ 2015-03-25 18:21 ` Simon Glass
  2015-04-07 18:39   ` Simon Glass
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 03/80] dm: test: bus: Use a local variable to simplify code Simon Glass
                   ` (78 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:21 UTC (permalink / raw)
  To: u-boot

This has the wrong #define in the function comment. Fix it.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 include/os.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/os.h b/include/os.h
index e3645e0..a758f09 100644
--- a/include/os.h
+++ b/include/os.h
@@ -64,7 +64,7 @@ off_t os_lseek(int fd, off_t offset, int whence);
  * Access to the OS open() system call
  *
  * \param pathname	Pathname of file to open
- * \param flags		Flags, like O_RDONLY, O_RDWR
+ * \param flags		Flags, like OS_O_RDONLY, OS_O_RDWR
  * \return file descriptor, or -1 on error
  */
 int os_open(const char *pathname, int flags);
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 03/80] dm: test: bus: Use a local variable to simplify code
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 01/80] linker_lists: Add a function to access a linker list entry Simon Glass
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 02/80] sandbox: Fix comment for os_open() Simon Glass
@ 2015-03-25 18:21 ` Simon Glass
  2015-04-07 18:39   ` Simon Glass
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 04/80] dm: exynos: snow: Move the keyboard to I2C Simon Glass
                   ` (77 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:21 UTC (permalink / raw)
  To: u-boot

Adjust this test to avoid repeating the same code too often.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 test/dm/bus.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/test/dm/bus.c b/test/dm/bus.c
index faffe6a..116a52d 100644
--- a/test/dm/bus.c
+++ b/test/dm/bus.c
@@ -273,20 +273,22 @@ DM_TEST(dm_test_bus_parent_data, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
 /* As above but the size is controlled by the uclass */
 static int dm_test_bus_parent_data_uclass(struct dm_test_state *dms)
 {
+	struct driver *drv;
 	struct udevice *bus;
 	int size;
 	int ret;
 
 	/* Set the driver size to 0 so that the uclass size is used */
 	ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus));
-	size = bus->driver->per_child_auto_alloc_size;
+	drv = (struct driver *)bus->driver;
+	size = drv->per_child_auto_alloc_size;
 	bus->uclass->uc_drv->per_child_auto_alloc_size = size;
-	bus->driver->per_child_auto_alloc_size = 0;
+	drv->per_child_auto_alloc_size = 0;
 	ret = test_bus_parent_data(dms);
 	if (ret)
 		return ret;
 	bus->uclass->uc_drv->per_child_auto_alloc_size = 0;
-	bus->driver->per_child_auto_alloc_size = size;
+	drv->per_child_auto_alloc_size = size;
 
 	return 0;
 }
@@ -414,19 +416,21 @@ DM_TEST(dm_test_bus_parent_platdata, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
 static int dm_test_bus_parent_platdata_uclass(struct dm_test_state *dms)
 {
 	struct udevice *bus;
+	struct driver *drv;
 	int size;
 	int ret;
 
 	/* Set the driver size to 0 so that the uclass size is used */
 	ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus));
-	size = bus->driver->per_child_platdata_auto_alloc_size;
+	drv = (struct driver *)bus->driver;
+	size = drv->per_child_platdata_auto_alloc_size;
 	bus->uclass->uc_drv->per_child_platdata_auto_alloc_size = size;
-	bus->driver->per_child_platdata_auto_alloc_size = 0;
+	drv->per_child_platdata_auto_alloc_size = 0;
 	ret = test_bus_parent_platdata(dms);
 	if (ret)
 		return ret;
 	bus->uclass->uc_drv->per_child_platdata_auto_alloc_size = 0;
-	bus->driver->per_child_platdata_auto_alloc_size = size;
+	drv->per_child_platdata_auto_alloc_size = size;
 
 	return 0;
 }
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 04/80] dm: exynos: snow: Move the keyboard to I2C
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (2 preceding siblings ...)
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 03/80] dm: test: bus: Use a local variable to simplify code Simon Glass
@ 2015-03-25 18:21 ` Simon Glass
  2015-04-07 18:39   ` Simon Glass
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 05/80] dm: core: Support allocating driver-private data for DMA Simon Glass
                   ` (76 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:21 UTC (permalink / raw)
  To: u-boot

The snow keyboard on shipping devices is actually on I2C not SPI. Move the
label to indicate this.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 arch/arm/dts/exynos5250-snow.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/dts/exynos5250-snow.dts b/arch/arm/dts/exynos5250-snow.dts
index 7d8be69..d6777ee 100644
--- a/arch/arm/dts/exynos5250-snow.dts
+++ b/arch/arm/dts/exynos5250-snow.dts
@@ -40,7 +40,7 @@
 	};
 
 	i2c4: i2c at 12ca0000 {
-		cros-ec at 1e {
+		cros_ec: cros-ec at 1e {
 			reg = <0x1e>;
 			compatible = "google,cros-ec";
 			i2c-max-frequency = <100000>;
@@ -65,7 +65,7 @@
 	spi at 131b0000 {
 		spi-max-frequency = <1000000>;
 		spi-deactivate-delay = <100>;
-		cros_ec: cros-ec at 0 {
+		cros-ec at 0 {
 			reg = <0>;
 			compatible = "google,cros-ec";
 			spi-max-frequency = <5000000>;
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 05/80] dm: core: Support allocating driver-private data for DMA
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (3 preceding siblings ...)
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 04/80] dm: exynos: snow: Move the keyboard to I2C Simon Glass
@ 2015-03-25 18:21 ` Simon Glass
  2015-04-07 18:39   ` Simon Glass
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 06/80] dm: core: Convert driver_bind() to use const Simon Glass
                   ` (75 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:21 UTC (permalink / raw)
  To: u-boot

Some driver want to put DMA buffers in their private data. Add a flag
to tell driver model to align driver-private data to a cache boundary so
that DMA will work correctly in this case.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/core/device.c | 19 +++++++++++++++++--
 include/dm/device.h   |  3 +++
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/core/device.c b/drivers/core/device.c
index 7483405..1ca5d1c 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -164,6 +164,21 @@ int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
 			   -1, devp);
 }
 
+static void *alloc_priv(int size, uint flags)
+{
+	void *priv;
+
+	if (flags & DM_FLAG_ALLOC_PRIV_DMA) {
+		priv = memalign(ARCH_DMA_MINALIGN, size);
+		if (priv)
+			memset(priv, '\0', size);
+	} else {
+		priv = calloc(1, size);
+	}
+
+	return priv;
+}
+
 int device_probe_child(struct udevice *dev, void *parent_priv)
 {
 	struct driver *drv;
@@ -182,7 +197,7 @@ int device_probe_child(struct udevice *dev, void *parent_priv)
 
 	/* Allocate private data if requested */
 	if (drv->priv_auto_alloc_size) {
-		dev->priv = calloc(1, drv->priv_auto_alloc_size);
+		dev->priv = alloc_priv(drv->priv_auto_alloc_size, drv->flags);
 		if (!dev->priv) {
 			ret = -ENOMEM;
 			goto fail;
@@ -206,7 +221,7 @@ int device_probe_child(struct udevice *dev, void *parent_priv)
 					per_child_auto_alloc_size;
 		}
 		if (size) {
-			dev->parent_priv = calloc(1, size);
+			dev->parent_priv = alloc_priv(size, drv->flags);
 			if (!dev->parent_priv) {
 				ret = -ENOMEM;
 				goto fail;
diff --git a/include/dm/device.h b/include/dm/device.h
index 6980954..f27b34b 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -30,6 +30,9 @@ struct driver_info;
 /* DM is responsible for allocating and freeing parent_platdata */
 #define DM_FLAG_ALLOC_PARENT_PDATA	(1 << 3)
 
+/* Allocate driver private data on a DMA boundary */
+#define DM_FLAG_ALLOC_PRIV_DMA	(1 << 4)
+
 /**
  * struct udevice - An instance of a driver
  *
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 06/80] dm: core: Convert driver_bind() to use const
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (4 preceding siblings ...)
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 05/80] dm: core: Support allocating driver-private data for DMA Simon Glass
@ 2015-03-25 18:21 ` Simon Glass
  2015-04-07 18:39   ` Simon Glass
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 07/80] dm: core: Rename driver data function to dev_get_driver_data() Simon Glass
                   ` (74 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:21 UTC (permalink / raw)
  To: u-boot

The driver is not modified by driver model, so update driver_bind() to
recognise that.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/core/device-remove.c | 4 ++--
 drivers/core/device.c        | 7 ++++---
 include/dm/device-internal.h | 2 +-
 include/dm/device.h          | 2 +-
 4 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/core/device-remove.c b/drivers/core/device-remove.c
index 3a5f48d..7fee1c0 100644
--- a/drivers/core/device-remove.c
+++ b/drivers/core/device-remove.c
@@ -66,7 +66,7 @@ static int device_chld_remove(struct udevice *dev)
 
 int device_unbind(struct udevice *dev)
 {
-	struct driver *drv;
+	const struct driver *drv;
 	int ret;
 
 	if (!dev)
@@ -139,7 +139,7 @@ void device_free(struct udevice *dev)
 
 int device_remove(struct udevice *dev)
 {
-	struct driver *drv;
+	const struct driver *drv;
 	int ret;
 
 	if (!dev)
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 1ca5d1c..f1a03d9 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -24,8 +24,9 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-int device_bind(struct udevice *parent, struct driver *drv, const char *name,
-		void *platdata, int of_offset, struct udevice **devp)
+int device_bind(struct udevice *parent, const struct driver *drv,
+		const char *name, void *platdata, int of_offset,
+		struct udevice **devp)
 {
 	struct udevice *dev;
 	struct uclass *uc;
@@ -181,7 +182,7 @@ static void *alloc_priv(int size, uint flags)
 
 int device_probe_child(struct udevice *dev, void *parent_priv)
 {
-	struct driver *drv;
+	const struct driver *drv;
 	int size = 0;
 	int ret;
 	int seq;
diff --git a/include/dm/device-internal.h b/include/dm/device-internal.h
index e2418fe..687462b 100644
--- a/include/dm/device-internal.h
+++ b/include/dm/device-internal.h
@@ -34,7 +34,7 @@ struct udevice;
  * @devp: Returns a pointer to the bound device
  * @return 0 if OK, -ve on error
  */
-int device_bind(struct udevice *parent, struct driver *drv,
+int device_bind(struct udevice *parent, const struct driver *drv,
 		const char *name, void *platdata, int of_offset,
 		struct udevice **devp);
 
diff --git a/include/dm/device.h b/include/dm/device.h
index f27b34b..fafecce 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -70,7 +70,7 @@ struct driver_info;
  * when the device is probed and will be unique within the device's uclass.
  */
 struct udevice {
-	struct driver *driver;
+	const struct driver *driver;
 	const char *name;
 	void *platdata;
 	void *parent_platdata;
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 07/80] dm: core: Rename driver data function to dev_get_driver_data()
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (5 preceding siblings ...)
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 06/80] dm: core: Convert driver_bind() to use const Simon Glass
@ 2015-03-25 18:21 ` Simon Glass
  2015-04-07 18:40   ` Simon Glass
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 08/80] dm: core: Mark device as active before calling uclass probe() methods Simon Glass
                   ` (73 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:21 UTC (permalink / raw)
  To: u-boot

The existing get_get_of_data() function provides access to both the driver's
compatible string and its driver data. However only the latter is actually
useful. Update the interface to reflect this and fix up existing users.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/core/device.c     |  4 ++--
 drivers/core/lists.c      |  2 +-
 drivers/i2c/s3c24x0_i2c.c |  2 +-
 drivers/i2c/tegra_i2c.c   |  6 +++---
 include/dm/device.h       | 16 +++++++++++-----
 5 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/drivers/core/device.c b/drivers/core/device.c
index f1a03d9..4fba118 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -467,9 +467,9 @@ struct udevice *dev_get_parent(struct udevice *child)
 	return child->parent;
 }
 
-ulong dev_get_of_data(struct udevice *dev)
+ulong dev_get_driver_data(struct udevice *dev)
 {
-	return dev->of_id->data;
+	return dev->driver_data;
 }
 
 enum uclass_id device_get_uclass_id(struct udevice *dev)
diff --git a/drivers/core/lists.c b/drivers/core/lists.c
index ff115c4..647e390 100644
--- a/drivers/core/lists.c
+++ b/drivers/core/lists.c
@@ -168,7 +168,7 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
 			dm_warn("Error binding driver '%s'\n", entry->name);
 			return ret;
 		} else {
-			dev->of_id = id;
+			dev->driver_data = id->data;
 			found = true;
 			if (devp)
 				*devp = dev;
diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c
index b4ee33f..27ff587 100644
--- a/drivers/i2c/s3c24x0_i2c.c
+++ b/drivers/i2c/s3c24x0_i2c.c
@@ -1348,7 +1348,7 @@ static int s3c_i2c_ofdata_to_platdata(struct udevice *dev)
 	struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
 	int node, flags;
 
-	i2c_bus->is_highspeed = dev->of_id->data;
+	i2c_bus->is_highspeed = dev_get_driver_data(dev);
 	node = dev->of_offset;
 
 	if (i2c_bus->is_highspeed) {
diff --git a/drivers/i2c/tegra_i2c.c b/drivers/i2c/tegra_i2c.c
index f414287..fc95646 100644
--- a/drivers/i2c/tegra_i2c.c
+++ b/drivers/i2c/tegra_i2c.c
@@ -338,7 +338,7 @@ static int tegra_i2c_probe(struct udevice *dev)
 	bool is_dvc;
 
 	i2c_bus->id = dev->seq;
-	i2c_bus->type = dev_get_of_data(dev);
+	i2c_bus->type = dev_get_driver_data(dev);
 	i2c_bus->regs = (struct i2c_ctlr *)fdtdec_get_addr(blob, node, "reg");
 
 	/*
@@ -360,7 +360,7 @@ static int tegra_i2c_probe(struct udevice *dev)
 	if (i2c_bus->periph_id == -1)
 		return -EINVAL;
 
-	is_dvc = dev_get_of_data(dev) == TYPE_DVC;
+	is_dvc = dev_get_driver_data(dev) == TYPE_DVC;
 	if (is_dvc) {
 		i2c_bus->control =
 			&((struct dvc_ctlr *)i2c_bus->regs)->control;
@@ -469,7 +469,7 @@ int tegra_i2c_get_dvc_bus(struct udevice **busp)
 	for (uclass_first_device(UCLASS_I2C, &bus);
 	     bus;
 	     uclass_next_device(&bus)) {
-		if (dev_get_of_data(bus) == TYPE_DVC) {
+		if (dev_get_driver_data(bus) == TYPE_DVC) {
 			*busp = bus;
 			return 0;
 		}
diff --git a/include/dm/device.h b/include/dm/device.h
index fafecce..ec22885 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -55,7 +55,8 @@ struct driver_info;
  * @platdata: Configuration data for this device
  * @parent_platdata: The parent bus's configuration data for this device
  * @of_offset: Device tree node offset for this device (- for none)
- * @of_id: Pointer to the udevice_id structure which created the device
+ * @driver_data: Driver data word for the entry that matched this device with
+ *		its driver
  * @parent: Parent of this device, or NULL for the top level device
  * @priv: Private data for this device
  * @uclass: Pointer to uclass for this device
@@ -75,7 +76,7 @@ struct udevice {
 	void *platdata;
 	void *parent_platdata;
 	int of_offset;
-	const struct udevice_id *of_id;
+	ulong driver_data;
 	struct udevice *parent;
 	void *priv;
 	struct uclass *uclass;
@@ -251,13 +252,18 @@ struct udevice *dev_get_parent(struct udevice *child);
 void *dev_get_uclass_priv(struct udevice *dev);
 
 /**
- * dev_get_of_data() - get the device tree data used to bind a device
+ * dev_get_driver_data() - get the driver data used to bind a device
  *
  * When a device is bound using a device tree node, it matches a
  * particular compatible string as in struct udevice_id. This function
- * returns the associated data value for that compatible string
+ * returns the associated data value for that compatible string. This is
+ * the 'data' field in struct udevice_id.
+ *
+ * For USB devices, this is the driver_info field in struct usb_device_id.
+ *
+ * @dev:	Device to check
  */
-ulong dev_get_of_data(struct udevice *dev);
+ulong dev_get_driver_data(struct udevice *dev);
 
 /*
  * device_get_uclass_id() - return the uclass ID of a device
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 08/80] dm: core: Mark device as active before calling uclass probe() methods
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (6 preceding siblings ...)
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 07/80] dm: core: Rename driver data function to dev_get_driver_data() Simon Glass
@ 2015-03-25 18:21 ` Simon Glass
  2015-04-07 18:40   ` Simon Glass
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 09/80] dm: core: Add device children and sibling functions Simon Glass
                   ` (72 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:21 UTC (permalink / raw)
  To: u-boot

The uclass pre-probe functions may end up calling back into the device in
some circumstances. This can fail if recursion takes place. Adjust the
ordering so that we mark the device as active early, then retract this
later if needed.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/core/device.c | 8 +++++---
 test/dm/test-uclass.c | 3 ++-
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/core/device.c b/drivers/core/device.c
index 4fba118..b7ed21c 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -243,6 +243,8 @@ int device_probe_child(struct udevice *dev, void *parent_priv)
 	}
 	dev->seq = seq;
 
+	dev->flags |= DM_FLAG_ACTIVATED;
+
 	ret = uclass_pre_probe_device(dev);
 	if (ret)
 		goto fail;
@@ -269,10 +271,8 @@ int device_probe_child(struct udevice *dev, void *parent_priv)
 	}
 
 	ret = uclass_post_probe_device(dev);
-	if (ret) {
-		dev->flags &= ~DM_FLAG_ACTIVATED;
+	if (ret)
 		goto fail_uclass;
-	}
 
 	return 0;
 fail_uclass:
@@ -281,6 +281,8 @@ fail_uclass:
 			__func__, dev->name);
 	}
 fail:
+	dev->flags &= ~DM_FLAG_ACTIVATED;
+
 	dev->seq = -1;
 	device_free(dev);
 
diff --git a/test/dm/test-uclass.c b/test/dm/test-uclass.c
index be91657..7cb37f7 100644
--- a/test/dm/test-uclass.c
+++ b/test/dm/test-uclass.c
@@ -31,6 +31,7 @@ int test_ping(struct udevice *dev, int pingval, int *pingret)
 static int test_post_bind(struct udevice *dev)
 {
 	dm_testdrv_op_count[DM_TEST_OP_POST_BIND]++;
+	ut_assert(!device_active(dev));
 
 	return 0;
 }
@@ -48,7 +49,7 @@ static int test_pre_probe(struct udevice *dev)
 
 	dm_testdrv_op_count[DM_TEST_OP_PRE_PROBE]++;
 	ut_assert(priv);
-	ut_assert(!device_active(dev));
+	ut_assert(device_active(dev));
 
 	return 0;
 }
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 09/80] dm: core: Add device children and sibling functions
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (7 preceding siblings ...)
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 08/80] dm: core: Mark device as active before calling uclass probe() methods Simon Glass
@ 2015-03-25 18:21 ` Simon Glass
  2015-04-07 18:40   ` Simon Glass
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 10/80] dm: gpio: Add an implementation for gpio_get_number() Simon Glass
                   ` (71 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:21 UTC (permalink / raw)
  To: u-boot

Add some utility functions to check for children and for the last sibling in
a device's parent.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/core/device.c | 28 ++++++++++++++++++++++++++++
 include/dm/device.h   | 30 ++++++++++++++++++++++++++++++
 2 files changed, 58 insertions(+)

diff --git a/drivers/core/device.c b/drivers/core/device.c
index b7ed21c..ccaa99c 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -490,3 +490,31 @@ fdt_addr_t dev_get_addr(struct udevice *dev)
 	return FDT_ADDR_T_NONE;
 }
 #endif
+
+bool device_has_children(struct udevice *dev)
+{
+	return !list_empty(&dev->child_head);
+}
+
+bool device_has_active_children(struct udevice *dev)
+{
+	struct udevice *child;
+
+	for (device_find_first_child(dev, &child);
+	     child;
+	     device_find_next_child(&child)) {
+		if (device_active(child))
+			return true;
+	}
+
+	return false;
+}
+
+bool device_is_last_sibling(struct udevice *dev)
+{
+	struct udevice *parent = dev->parent;
+
+	if (!parent)
+		return false;
+	return list_is_last(&dev->sibling_node, &parent->child_head);
+}
diff --git a/include/dm/device.h b/include/dm/device.h
index ec22885..c11342c 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -380,4 +380,34 @@ int device_find_next_child(struct udevice **devp);
  */
 fdt_addr_t dev_get_addr(struct udevice *dev);
 
+/**
+ * device_has_children() - check if a device has any children
+ *
+ * @dev:	Device to check
+ * @return true if the device has one or more children
+ */
+bool device_has_children(struct udevice *dev);
+
+/**
+ * device_has_active_children() - check if a device has any active children
+ *
+ * @dev:	Device to check
+ * @return true if the device has one or more children and at least one of
+ * them is active (probed).
+ */
+bool device_has_active_children(struct udevice *dev);
+
+/**
+ * device_is_last_sibling() - check if a device is the last sibling
+ *
+ * This function can be useful for display purposes, when special action needs
+ * to be taken when displaying the last sibling. This can happen when a tree
+ * view of devices is being displayed.
+ *
+ * @dev:	Device to check
+ * @return true if there are no more siblings after this one - i.e. is it
+ * last in the list.
+ */
+bool device_is_last_sibling(struct udevice *dev);
+
 #endif
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 10/80] dm: gpio: Add an implementation for gpio_get_number()
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (8 preceding siblings ...)
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 09/80] dm: core: Add device children and sibling functions Simon Glass
@ 2015-03-25 18:21 ` Simon Glass
  2015-04-07 18:40   ` Simon Glass
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 11/80] dm: usb: Add a uclass for USB controllers Simon Glass
                   ` (70 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:21 UTC (permalink / raw)
  To: u-boot

This has a prototype but no implementation. It returns the global GPIO number
given a gpio_desc. It is useful for debugging in some cases.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/gpio/gpio-uclass.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index b6e1058..380366f 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -689,6 +689,18 @@ static int gpio_renumber(struct udevice *removed_dev)
 	return 0;
 }
 
+int gpio_get_number(struct gpio_desc *desc)
+{
+	struct udevice *dev = desc->dev;
+	struct gpio_dev_priv *uc_priv;
+
+	if (!dev)
+		return -1;
+	uc_priv = dev->uclass_priv;
+
+	return uc_priv->gpio_base + desc->offset;
+}
+
 static int gpio_post_probe(struct udevice *dev)
 {
 	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 11/80] dm: usb: Add a uclass for USB controllers
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (9 preceding siblings ...)
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 10/80] dm: gpio: Add an implementation for gpio_get_number() Simon Glass
@ 2015-03-25 18:21 ` Simon Glass
  2015-04-07 18:40   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 12/80] dm: usb: Adjust usb command to prepare for driver model Simon Glass
                   ` (69 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:21 UTC (permalink / raw)
  To: u-boot

Add a uclass that can represent a USB controller. For now we do not create
devices for things attached to the controller. This will be added later.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/Kconfig               |  14 ++
 drivers/usb/host/Makefile         |   4 +
 drivers/usb/host/usb-uclass.c     | 392 ++++++++++++++++++++++++++++++++++++++
 drivers/usb/musb-new/musb_uboot.c |   4 +-
 include/dm/uclass-id.h            |   1 +
 include/usb.h                     | 285 ++++++++++++++++++++++++++-
 6 files changed, 694 insertions(+), 6 deletions(-)
 create mode 100644 drivers/usb/host/usb-uclass.c

diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index b4a9442..a4414ef 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -35,6 +35,20 @@ config USB
 
 if USB
 
+config DM_USB
+	bool "Enable driver model for USB"
+	depends on USB && DM
+	help
+	  Enable driver model for USB. The USB interface is then implemented
+	  by the USB uclass. Multiple USB controllers of different types
+	  (XHCI, EHCI) can be attached and used. The 'usb' command works as
+	  normal. OCHI is not supported at present.
+
+	  Much of the code is shared but with this option enabled the USB
+	  uclass takes care of device enumeration. USB devices can be
+	  declared with the USB_DEVICE() macro and will be automatically
+	  probed when found on the bus.
+
 source "drivers/usb/host/Kconfig"
 
 config USB_STORAGE
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index eb6f34b..9419295 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -5,6 +5,10 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
+ifdef CONFIG_DM_USB
+obj-$(CONFIG_CMD_USB) += usb-uclass.o
+endif
+
 # 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..22dcd14
--- /dev/null
+++ b/drivers/usb/host/usb-uclass.c
@@ -0,0 +1,392 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <usb.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <dm/root.h>
+#include <dm/uclass-internal.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+extern bool usb_started; /* flag for the started/stopped USB status */
+static bool asynch_allowed;
+
+int usb_disable_asynch(int disable)
+{
+	int old_value = asynch_allowed;
+
+	asynch_allowed = !disable;
+	return old_value;
+}
+
+int submit_int_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
+		   int length, int interval)
+{
+	struct udevice *bus = udev->controller_dev;
+	struct dm_usb_ops *ops = usb_get_ops(bus);
+
+	if (!ops->interrupt)
+		return -ENOSYS;
+
+	return ops->interrupt(bus, udev, pipe, buffer, length, interval);
+}
+
+int submit_control_msg(struct usb_device *udev, unsigned long pipe,
+		       void *buffer, int length, struct devrequest *setup)
+{
+	struct udevice *bus = udev->controller_dev;
+	struct dm_usb_ops *ops = usb_get_ops(bus);
+
+	if (!ops->control)
+		return -ENOSYS;
+
+	return ops->control(bus, udev, pipe, buffer, length, setup);
+}
+
+int submit_bulk_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
+		    int length)
+{
+	struct udevice *bus = udev->controller_dev;
+	struct dm_usb_ops *ops = usb_get_ops(bus);
+
+	if (!ops->bulk)
+		return -ENOSYS;
+
+	return ops->bulk(bus, udev, pipe, buffer, length);
+}
+
+int usb_alloc_device(struct usb_device *udev)
+{
+	struct udevice *bus = udev->controller_dev;
+	struct dm_usb_ops *ops = usb_get_ops(bus);
+
+	/* This is only requird by some controllers - current XHCI */
+	if (!ops->alloc_device)
+		return 0;
+
+	return ops->alloc_device(bus, udev);
+}
+
+int usb_stop(void)
+{
+	struct udevice *bus;
+	struct uclass *uc;
+	int err = 0, ret;
+
+	/* De-activate any devices that have been activated */
+	ret = uclass_get(UCLASS_USB, &uc);
+	if (ret)
+		return ret;
+	uclass_foreach_dev(bus, uc) {
+		ret = device_remove(bus);
+		if (ret && !err)
+			err = ret;
+	}
+
+	usb_stor_reset();
+	usb_hub_reset();
+	usb_started = 0;
+
+	return err;
+}
+
+static int usb_scan_bus(struct udevice *bus, bool recurse)
+{
+	struct usb_bus_priv *priv;
+	struct udevice *dev;
+	int ret;
+
+	priv = dev_get_uclass_priv(bus);
+
+	assert(recurse);	/* TODO: Support non-recusive */
+
+	ret = usb_scan_device(bus, 0, USB_SPEED_FULL, &dev);
+	if (ret)
+		return ret;
+
+	return priv->next_addr;
+}
+
+int usb_init(void)
+{
+	int controllers_initialized = 0;
+	struct udevice *bus;
+	struct uclass *uc;
+	int count = 0;
+	int ret;
+
+	asynch_allowed = 1;
+	usb_hub_reset();
+
+	ret = uclass_get(UCLASS_USB, &uc);
+	if (ret)
+		return ret;
+
+	uclass_foreach_dev(bus, uc) {
+		/* init low_level USB */
+		count++;
+		printf("USB");
+		printf("%d:   ", bus->seq);
+		ret = device_probe(bus);
+		if (ret == -ENODEV) {	/* No such device. */
+			puts("Port not available.\n");
+			controllers_initialized++;
+			continue;
+		}
+
+		if (ret) {		/* Other error. */
+			printf("probe failed, error %d\n", ret);
+			continue;
+		}
+		/*
+		 * lowlevel init is OK, now scan the bus for devices
+		 * i.e. search HUBs and configure them
+		 */
+		controllers_initialized++;
+		printf("scanning bus %d for devices... ", bus->seq);
+		debug("\n");
+		ret = usb_scan_bus(bus, true);
+		if (ret < 0)
+			printf("failed, error %d\n", ret);
+		else if (!ret)
+			printf("No USB Device found\n");
+		else
+			printf("%d USB Device(s) found\n", ret);
+		usb_started = true;
+	}
+
+	debug("scan end\n");
+	/* if we were not able to find@least one working bus, bail out */
+	if (!count)
+		printf("No controllers found\n");
+	else if (controllers_initialized == 0)
+		printf("USB error: all controllers failed lowlevel init\n");
+
+	return usb_started ? 0 : -1;
+}
+
+int usb_reset_root_port(void)
+{
+	return -ENOSYS;
+}
+
+static struct usb_device *find_child_devnum(struct udevice *parent, int devnum)
+{
+	struct usb_device *udev;
+	struct udevice *dev;
+
+	if (!device_active(parent))
+		return NULL;
+	udev = dev_get_parentdata(parent);
+	if (udev->devnum == devnum)
+		return udev;
+
+	for (device_find_first_child(parent, &dev);
+	     dev;
+	     device_find_next_child(&dev)) {
+		udev = find_child_devnum(dev, devnum);
+		if (udev)
+			return udev;
+	}
+
+	return NULL;
+}
+
+struct usb_device *usb_get_dev_index(struct udevice *bus, int index)
+{
+	struct udevice *hub;
+	int devnum = index + 1; /* Addresses are allocated from 1 on USB */
+
+	device_find_first_child(bus, &hub);
+	if (device_get_uclass_id(hub) == UCLASS_USB_HUB)
+		return find_child_devnum(hub, devnum);
+
+	return NULL;
+}
+
+int usb_post_bind(struct udevice *dev)
+{
+	/* Scan the bus for devices */
+	return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
+}
+
+int usb_port_reset(struct usb_device *parent, int portnr)
+{
+	unsigned short portstatus;
+	int ret;
+
+	debug("%s: start\n", __func__);
+
+	if (parent) {
+		/* reset the port for the second time */
+		assert(portnr > 0);
+		debug("%s: reset %d\n", __func__, portnr - 1);
+		ret = legacy_hub_port_reset(parent, portnr - 1, &portstatus);
+		if (ret < 0) {
+			printf("\n     Couldn't reset port %i\n", portnr);
+			return ret;
+		}
+	} else {
+		debug("%s: reset root\n", __func__);
+		usb_reset_root_port();
+	}
+
+	return 0;
+}
+
+int usb_legacy_port_reset(struct usb_device *parent, int portnr)
+{
+	return usb_port_reset(parent, portnr);
+}
+
+int usb_scan_device(struct udevice *parent, int port,
+		    enum usb_device_speed speed, struct udevice **devp)
+{
+	struct udevice *dev;
+	bool created = false;
+	struct usb_dev_platdata *plat;
+	struct usb_bus_priv *priv;
+	struct usb_device *parent_udev;
+	int ret;
+	ALLOC_CACHE_ALIGN_BUFFER(struct usb_device, udev, 1);
+	struct usb_interface_descriptor *iface = &udev->config.if_desc[0].desc;
+
+	*devp = NULL;
+	memset(udev, '\0', sizeof(*udev));
+	ret = usb_get_bus(parent, &udev->controller_dev);
+	if (ret)
+		return ret;
+	priv = dev_get_uclass_priv(udev->controller_dev);
+
+	/*
+	 * Somewhat nasty, this. We create a local device and use the normal
+	 * USB stack to read its descriptor. Then we know what type of device
+	 * to create for real.
+	 *
+	 * udev->dev is set to the parent, since we don't have a real device
+	 * yet. The USB stack should not access udev.dev anyway, except perhaps
+	 * to find the controller, and the controller will either be @parent,
+	 * or some parent of @parent.
+	 *
+	 * Another option might be to create the device as a generic USB
+	 * device, then morph it into the correct one when we know what it
+	 * should be. This means that a generic USB device would morph into
+	 * a network controller, or a USB flash stick, for example. However,
+	 * we don't support such morphing and it isn't clear that it would
+	 * be easy to do.
+	 *
+	 * Yet another option is to split out the USB stack parts of udev
+	 * into something like a 'struct urb' (as Linux does) which can exist
+	 * independently of any device. This feels cleaner, but calls for quite
+	 * a big change to the USB stack.
+	 *
+	 * For now, the approach is to set up an empty udev, read its
+	 * descriptor and assign it an address, then bind a real device and
+	 * stash the resulting information into the device's parent
+	 * platform data. Then when we probe it, usb_child_pre_probe() is called
+	 * and it will pull the information out of the stash.
+	 */
+	udev->dev = parent;
+	udev->speed = speed;
+	udev->devnum = priv->next_addr + 1;
+	udev->portnr = port;
+	debug("Calling usb_setup_device(), portnr=%d\n", udev->portnr);
+	parent_udev = device_get_uclass_id(parent) == UCLASS_USB_HUB ?
+		dev_get_parentdata(parent) : NULL;
+	ret = usb_setup_device(udev, priv->desc_before_addr, parent_udev, port);
+	debug("read_descriptor for '%s': ret=%d\n", parent->name, ret);
+	if (ret)
+		return ret;
+	ret = usb_find_child(parent, &udev->descriptor, iface, &dev);
+	debug("** usb_find_child returns %d\n", ret);
+
+	/* TODO: Find a suitable driver and create the device */
+	return -ENOENT;
+}
+
+int usb_child_post_bind(struct udevice *dev)
+{
+	struct usb_dev_platdata *plat = dev_get_parent_platdata(dev);
+	const void *blob = gd->fdt_blob;
+	int val;
+
+	if (dev->of_offset == -1)
+		return 0;
+
+	/* We only support matching a few things */
+	val = fdtdec_get_int(blob, dev->of_offset, "usb,device-class", -1);
+	if (val != -1) {
+		plat->id.match_flags |= USB_DEVICE_ID_MATCH_DEV_CLASS;
+		plat->id.bDeviceClass = val;
+	}
+	val = fdtdec_get_int(blob, dev->of_offset, "usb,interface-class", -1);
+	if (val != -1) {
+		plat->id.match_flags |= USB_DEVICE_ID_MATCH_INT_CLASS;
+		plat->id.bInterfaceClass = val;
+	}
+
+	return 0;
+}
+
+int usb_get_bus(struct udevice *dev, struct udevice **busp)
+{
+	struct udevice *bus;
+
+	*busp = NULL;
+	for (bus = dev; bus && device_get_uclass_id(bus) != UCLASS_USB; )
+		bus = bus->parent;
+	if (!bus) {
+		/* By design this cannot happen */
+		assert(bus);
+		debug("USB HUB '%s' does not have a controller\n", dev->name);
+		return -EXDEV;
+	}
+	*busp = bus;
+
+	return 0;
+}
+
+int usb_child_pre_probe(struct udevice *dev)
+{
+	struct udevice *bus;
+	struct usb_device *udev = dev_get_parentdata(dev);
+	struct usb_dev_platdata *plat = dev_get_parent_platdata(dev);
+	int ret;
+
+	ret = usb_get_bus(dev, &bus);
+	if (ret)
+		return ret;
+	udev->controller_dev = bus;
+	udev->dev = dev;
+	udev->devnum = plat->devnum;
+	udev->slot_id = plat->slot_id;
+	udev->portnr = plat->portnr;
+	udev->speed = plat->speed;
+	debug("** device '%s': getting slot_id=%d\n", dev->name, plat->slot_id);
+
+	ret = usb_select_config(udev);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+UCLASS_DRIVER(usb) = {
+	.id		= UCLASS_USB,
+	.name		= "usb",
+	.flags		= DM_UC_FLAG_SEQ_ALIAS,
+	.post_bind	= usb_post_bind,
+	.per_child_auto_alloc_size = sizeof(struct usb_device),
+	.per_device_auto_alloc_size = sizeof(struct usb_bus_priv),
+	.child_post_bind = usb_child_post_bind,
+	.child_pre_probe = usb_child_pre_probe,
+	.per_child_platdata_auto_alloc_size = sizeof(struct usb_dev_platdata),
+};
diff --git a/drivers/usb/musb-new/musb_uboot.c b/drivers/usb/musb-new/musb_uboot.c
index 6e58ddf..f42db59 100644
--- a/drivers/usb/musb-new/musb_uboot.c
+++ b/drivers/usb/musb-new/musb_uboot.c
@@ -177,7 +177,7 @@ void *poll_int_queue(struct usb_device *dev, struct int_queue *queue)
 	return NULL; /* URB still pending */
 }
 
-void usb_reset_root_port(void)
+int usb_reset_root_port(void)
 {
 	void *mbase = host->mregs;
 	u8 power;
@@ -194,6 +194,8 @@ void usb_reset_root_port(void)
 			(musb_readb(mbase, MUSB_DEVCTL) & MUSB_DEVCTL_FSDEV) ?
 			USB_SPEED_FULL : USB_SPEED_LOW;
 	mdelay((host_speed == USB_SPEED_LOW) ? 200 : 50);
+
+	return 0;
 }
 
 int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index 84a6955..cb6d2e5 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -39,6 +39,7 @@ enum uclass_id {
 	UCLASS_PCI_GENERIC,	/* Generic PCI bus device */
 	UCLASS_PCH,		/* x86 platform controller hub */
 	UCLASS_ETH,		/* Ethernet device */
+	UCLASS_USB,		/* USB bus */
 
 	UCLASS_COUNT,
 	UCLASS_INVALID = -1,
diff --git a/include/usb.h b/include/usb.h
index a8fee0b..0e1c16a 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -2,6 +2,9 @@
  * (C) Copyright 2001
  * Denis Peter, MPL AG Switzerland
  *
+ * Adapted for U-Boot driver model
+ * (C) Copyright 2015 Google, Inc
+ *
  * SPDX-License-Identifier:	GPL-2.0+
  * Note: Part of this code has been derived from linux
  *
@@ -9,6 +12,7 @@
 #ifndef _USB_H_
 #define _USB_H_
 
+#include <fdtdec.h>
 #include <usb_defs.h>
 #include <linux/usb/ch9.h>
 #include <asm/cache.h>
@@ -85,6 +89,19 @@ enum {
 	PACKET_SIZE_64  = 3,
 };
 
+/**
+ * struct usb_device - information about a USB device
+ *
+ * With driver model both UCLASS_USB (the USB controllers) and UCLASS_USB_HUB
+ * (the hubs) have this as parent data. Hubs are children of controllers or
+ * other hubs and there is always a single root hub for each controller.
+ * Therefore struct usb_device can always be accessed with
+ * dev_get_parentdata(dev), where dev is a USB device.
+ *
+ * Pointers exist for obtaining both the device (could be any uclass) and
+ * controller (UCLASS_USB) from this structure. The controller does not have
+ * a struct usb_device since it is not a device.
+ */
 struct usb_device {
 	int	devnum;			/* Device number on USB bus */
 	int	speed;			/* full/low/high */
@@ -123,13 +140,19 @@ struct usb_device {
 	unsigned long int_pending;	/* 1 bit per ep, used by int_queue */
 	int act_len;			/* transfered bytes */
 	int maxchild;			/* Number of ports if hub */
-	int portnr;
+	int portnr;			/* Port number, 1=first */
+#ifndef CONFIG_DM_USB
+	/* parent hub, or NULL if this is the root hub */
 	struct usb_device *parent;
 	struct usb_device *children[USB_MAXCHILDREN];
-
 	void *controller;		/* hardware controller private data */
+#endif
 	/* slot_id - for xHCI enabled devices */
 	unsigned int slot_id;
+#ifdef CONFIG_DM_USB
+	struct udevice *dev;		/* Pointer to associated device */
+	struct udevice *controller_dev;	/* Pointer to associated controller */
+#endif
 };
 
 struct int_queue;
@@ -160,8 +183,9 @@ enum usb_init_type {
 
 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);
+
+#if defined(CONFIG_MUSB_HOST) || defined(CONFIG_DM_USB)
+int usb_reset_root_port(void);
 #else
 #define usb_reset_root_port()
 #endif
@@ -245,7 +269,6 @@ int usb_stop(void); /* stop the USB Controller */
 int usb_set_protocol(struct usb_device *dev, int ifnum, int protocol);
 int usb_set_idle(struct usb_device *dev, int ifnum, int duration,
 			int report_id);
-struct usb_device *usb_get_dev_index(int index);
 int usb_control_msg(struct usb_device *dev, unsigned int pipe,
 			unsigned char request, unsigned char requesttype,
 			unsigned short value, unsigned short index,
@@ -423,6 +446,258 @@ struct usb_hub_device {
 	struct usb_hub_descriptor desc;
 };
 
+#ifdef CONFIG_DM_USB
+/**
+ * struct usb_platdata - Platform data about a USB controller
+ *
+ * Given a USB controller (UCLASS_USB) dev this is dev_get_platdata(dev)
+ */
+struct usb_platdata {
+	enum usb_init_type init_type;
+};
+
+/**
+ * struct usb_dev_platdata - Platform data about a USB device
+ *
+ * Given a USB device dev this structure is dev_get_parent_platdata(dev).
+ * This is used by sandbox to provide emulation data also.
+ *
+ * @id:		ID used to match this device
+ * @speed:	Stores the speed associated with a USB device
+ * @devnum:	Device address on the USB bus
+ * @slot_id:	USB3 slot ID, which is separate from the device address
+ * @portnr:	Port number of this device on its parent hub, numbered from 1
+ *		(0 mean this device is the root hub)
+ * @strings:	List of descriptor strings (for sandbox emulation purposes)
+ * @desc_list:	List of descriptors (for sandbox emulation purposes)
+ */
+struct usb_dev_platdata {
+	struct usb_device_id id;
+	enum usb_device_speed speed;
+	int devnum;
+	int slot_id;
+	int portnr;	/* Hub port number, 1..n */
+#ifdef CONFIG_SANDBOX
+	struct usb_string *strings;
+	/* NULL-terminated list of descriptor pointers */
+	struct usb_generic_descriptor **desc_list;
+#endif
+	int configno;
+};
+
+/**
+ * struct usb_bus_priv - information about the USB controller
+ *
+ * Given a USB controller (UCLASS_USB) 'dev', this is
+ * dev_get_uclass_priv(dev).
+ *
+ * @next_addr:	Next device address to allocate minus 1. Incremented by 1
+ *		each time a new device address is set, so this holds the
+ *		number of devices on the bus
+ * @desc_before_addr:	true if we can read a device descriptor before it
+ *		has been assigned an address. For XHCI this is not possible
+ *		so this will be false.
+ */
+struct usb_bus_priv {
+	int next_addr;
+	bool desc_before_addr;
+};
+
+/**
+ * struct dm_usb_ops - USB controller operations
+ *
+ * This defines the operations supoorted on a USB controller. Common
+ * arguments are:
+ *
+ * @bus:	USB bus (i.e. controller), which is in UCLASS_USB.
+ * @udev:	USB device parent data. Controllers are not expected to need
+ *		this, since the device address on the bus is encoded in @pipe.
+ *		It is used for sandbox, and can be handy for debugging and
+ *		logging.
+ * @pipe:	An assortment of bitfields which provide address and packet
+ *		type information. See create_pipe() above for encoding
+ *		details
+ * @buffer:	A buffer to use for sending/receiving. This should be
+ *		DMA-aligned.
+ * @length:	Buffer length in bytes
+ */
+struct dm_usb_ops {
+	/**
+	 * control() - Send a control message
+	 *
+	 * Most parameters are as above.
+	 *
+	 * @setup: Additional setup information required by the message
+	 */
+	int (*control)(struct udevice *bus, struct usb_device *udev,
+		       unsigned long pipe, void *buffer, int length,
+		       struct devrequest *setup);
+	/**
+	 * bulk() - Send a bulk message
+	 *
+	 * Parameters are as above.
+	 */
+	int (*bulk)(struct udevice *bus, struct usb_device *udev,
+		    unsigned long pipe, void *buffer, int length);
+	/**
+	 * interrupt() - Send an interrupt message
+	 *
+	 * Most parameters are as above.
+	 *
+	 * @interval: Interrupt interval
+	 */
+	int (*interrupt)(struct udevice *bus, struct usb_device *udev,
+			 unsigned long pipe, void *buffer, int length,
+			 int interval);
+	/**
+	 * alloc_device() - Allocate a new device context (XHCI)
+	 *
+	 * Before sending packets to a new device on an XHCI bus, a device
+	 * context must be created. If this method is not NULL it will be
+	 * called before the device is enumerated (even before its descriptor
+	 * is read). This should be NULL for EHCI, which does not need this.
+	 */
+	int (*alloc_device)(struct udevice *bus, struct usb_device *udev);
+};
+
+#define usb_get_ops(dev)	((struct dm_usb_ops *)(dev)->driver->ops)
+#define usb_get_emul_ops(dev)	((struct dm_usb_ops *)(dev)->driver->ops)
+
+#ifdef CONFIG_MUSB_HOST
+int usb_reset_root_port(void);
+#endif
+
+/**
+ * usb_get_dev_index() - look up a device index number
+ *
+ * Look up devices using their index number (starting at 0). This works since
+ * in U-Boot device addresses are allocated starting at 1 with no gaps.
+ *
+ * TODO(sjg at chromium.org): Remove this function when usb_ether.c is modified
+ * to work better with driver model.
+ *
+ * @bus:	USB bus to check
+ * @index:	Index number of device to find (0=first). This is just the
+ *		device address less 1.
+ */
+struct usb_device *usb_get_dev_index(struct udevice *bus, int index);
+
+/**
+ * usb_legacy_port_reset() - Legacy function to reset a hub port
+ *
+ * @hub:	Hub device
+ * @portnr:	Port number (1=first)
+ */
+int usb_legacy_port_reset(struct usb_device *hub, int portnr);
+
+/**
+ * usb_setup_device() - set up a device ready for use
+ *
+ * @dev:	USB device pointer. This need not be a real device - it is
+ *		common for it to just be a local variable with its ->dev
+ *		member (i.e. @dev->dev) set to the parent device
+ * @do_read:	true to read the device descriptor before an address is set
+ *		(should be false for XHCI buses, true otherwise)
+ * @parent:	Parent device (either UCLASS_USB or UCLASS_USB_HUB)
+ * @portnr:	Port number on hub (1=first) or 0 for none
+ * @return 0 if OK, -ve on error */
+int usb_setup_device(struct usb_device *dev, bool do_read,
+		     struct usb_device *parent, int portnr);
+
+/**
+ * usb_hub_scan() - Scan a hub and find its devices
+ *
+ * @hub:	Hub device to scan
+ */
+int usb_hub_scan(struct udevice *hub);
+
+/**
+ * usb_scan_device() - Scan a device on a bus
+ *
+ * Scan a device on a bus. It has already been detected and is ready to
+ * be enumerated. This may be either the root hub (@parent is a bus) or a
+ * normal device (@parent is a hub)
+ *
+ * @parent:	Parent device
+ * @port:	Hub port number (numbered from 1)
+ * @speed:	USB speed to use for this device
+ * @devp:	Returns pointer to device if all is well
+ * @return 0 if OK, -ve on error
+ */
+int usb_scan_device(struct udevice *parent, int port,
+		    enum usb_device_speed speed, struct udevice **devp);
+
+/**
+ * usb_get_bus() - Find the bus for a device
+ *
+ * Search up through parents to find the bus this device is connected to. This
+ * will be a device with uclass UCLASS_USB.
+ *
+ * @dev:	Device to check
+ * @busp:	Returns bus, or NULL if not found
+ * @return 0 if OK, -EXDEV is somehow this bus does not have a controller (this
+ *	indicates a critical error in the USB stack
+ */
+int usb_get_bus(struct udevice *dev, struct udevice **busp);
+
+/**
+ * usb_select_config() - Set up a device ready for use
+ *
+ * This function assumes that the device already has an address and a driver
+ * bound, and is ready to be set up.
+ *
+ * This re-reads the device and configuration descriptors and sets the
+ * configuration
+ *
+ * @dev:	Device to set up
+ */
+int usb_select_config(struct usb_device *dev);
+
+/**
+ * usb_child_pre_probe() - Pre-probe function for USB devices
+ *
+ * This is called on all children of hubs and USB controllers (i.e. UCLASS_USB
+ * and UCLASS_USB_HUB) when a new device is about to be probed. It sets up the
+ * device from the saved platform data and calls usb_select_config() to
+ * finish set up.
+ *
+ * Once this is done, the device's normal driver can take over, knowing the
+ * device is accessible on the USB bus.
+ *
+ * This function is for use only by the internal USB stack.
+ *
+ * @dev:	Device to set up
+ */
+int usb_child_pre_probe(struct udevice *dev);
+
+struct ehci_ctrl;
+
+/**
+ * usb_setup_ehci_gadget() - Set up a USB device as a gadget
+ *
+ * TODO(sjg at chromium.org): Tidy this up when USB gadgets can use driver model
+ *
+ * This provides a way to tell a controller to start up as a USB device
+ * instead of as a host. It is untested.
+ */
+int usb_setup_ehci_gadget(struct ehci_ctrl **ctlrp);
+
+/**
+ * usb_stor_reset() - Prepare to scan USB storage devices
+ *
+ * Empty the list of USB storage devices in preparation for scanning them.
+ * This must be called before a USB scan.
+ */
+void usb_stor_reset(void);
+
+#else /* !CONFIG_DM_USB */
+
+struct usb_device *usb_get_dev_index(int index);
+
+#endif
+
+bool usb_device_has_child_on_port(struct usb_device *parent, int port);
+
 int usb_hub_probe(struct usb_device *dev, int ifnum);
 void usb_hub_reset(void);
 int hub_port_reset(struct usb_device *dev, int port,
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 12/80] dm: usb: Adjust usb command to prepare for driver model
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (10 preceding siblings ...)
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 11/80] dm: usb: Add a uclass for USB controllers Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:40   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 13/80] dm: usb: Adjust usb_alloc_new_device() to return an error Simon Glass
                   ` (68 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

Use 'udev' instead of 'dev' in a few places, reserving 'dev' for driver
model's struct udevice. Also adjust the code in a few minor ways to make
it easier to plumb in driver model.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 common/cmd_usb.c | 51 +++++++++++++++++++++++++--------------------------
 1 file changed, 25 insertions(+), 26 deletions(-)

diff --git a/common/cmd_usb.c b/common/cmd_usb.c
index 27813f0..085802b 100644
--- a/common/cmd_usb.c
+++ b/common/cmd_usb.c
@@ -254,15 +254,15 @@ static void usb_display_config(struct usb_device *dev)
 
 static struct usb_device *usb_find_device(int devnum)
 {
-	struct usb_device *dev;
+	struct usb_device *udev;
 	int d;
 
 	for (d = 0; d < USB_MAX_DEVICE; d++) {
-		dev = usb_get_dev_index(d);
-		if (dev == NULL)
+		udev = usb_get_dev_index(d);
+		if (udev == NULL)
 			return NULL;
-		if (dev->devnum == devnum)
-			return dev;
+		if (udev->devnum == devnum)
+			return udev;
 	}
 
 	return NULL;
@@ -305,8 +305,8 @@ static void usb_show_tree_graph(struct usb_device *dev, char *pre)
 			has_child = 1;
 	}
 	/* check if we are the last one */
-	last_child = 1;
-	if (dev->parent != NULL) {
+	last_child = (dev->parent != NULL);
+	if (last_child) {
 		for (i = 0; i < dev->parent->maxchild; i++) {
 			/* search for children */
 			if (dev->parent->children[i] == dev) {
@@ -324,7 +324,7 @@ static void usb_show_tree_graph(struct usb_device *dev, char *pre)
 		} /* for all children of the parent */
 		printf("\b+-");
 		/* correct last child */
-		if (last_child)
+		if (last_child && index)
 			pre[index-1] = ' ';
 	} /* if not root hub */
 	else
@@ -355,7 +355,7 @@ static void usb_show_tree(struct usb_device *dev)
 {
 	char preamble[32];
 
-	memset(preamble, 0, 32);
+	memset(preamble, '\0', sizeof(preamble));
 	usb_show_tree_graph(dev, &preamble[0]);
 }
 
@@ -466,9 +466,8 @@ static void do_usb_start(void)
  */
 static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-
+	struct usb_device *udev = NULL;
 	int i;
-	struct usb_device *dev = NULL;
 	extern char usb_started;
 #ifdef CONFIG_USB_STORAGE
 	block_dev_desc_t *stor_dev;
@@ -509,11 +508,11 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	if (strncmp(argv[1], "tree", 4) == 0) {
 		puts("USB device tree:\n");
 		for (i = 0; i < USB_MAX_DEVICE; i++) {
-			dev = usb_get_dev_index(i);
-			if (dev == NULL)
+			udev = usb_get_dev_index(i);
+			if (udev == NULL)
 				break;
-			if (dev->parent == NULL)
-				usb_show_tree(dev);
+			if (udev->parent == NULL)
+				usb_show_tree(udev);
 		}
 		return 0;
 	}
@@ -521,23 +520,23 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 		int d;
 		if (argc == 2) {
 			for (d = 0; d < USB_MAX_DEVICE; d++) {
-				dev = usb_get_dev_index(d);
-				if (dev == NULL)
+				udev = usb_get_dev_index(d);
+				if (udev == NULL)
 					break;
-				usb_display_desc(dev);
-				usb_display_config(dev);
+				usb_display_desc(udev);
+				usb_display_config(udev);
 			}
 			return 0;
 		} else {
 			i = simple_strtoul(argv[2], NULL, 10);
 			printf("config for device %d\n", i);
-			dev = usb_find_device(i);
-			if (dev == NULL) {
+			udev = usb_find_device(i);
+			if (udev == NULL) {
 				printf("*** No device available ***\n");
 				return 0;
 			} else {
-				usb_display_desc(dev);
-				usb_display_config(dev);
+				usb_display_desc(udev);
+				usb_display_config(udev);
 			}
 		}
 		return 0;
@@ -546,13 +545,13 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 		if (argc < 5)
 			return CMD_RET_USAGE;
 		i = simple_strtoul(argv[2], NULL, 10);
-		dev = usb_find_device(i);
-		if (dev == NULL) {
+		udev = usb_find_device(i);
+		if (udev == NULL) {
 			printf("Device %d does not exist.\n", i);
 			return 1;
 		}
 		i = simple_strtoul(argv[3], NULL, 10);
-		return usb_test(dev, i, argv[4]);
+		return usb_test(udev, i, argv[4]);
 	}
 #ifdef CONFIG_USB_STORAGE
 	if (strncmp(argv[1], "stor", 4) == 0)
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 13/80] dm: usb: Adjust usb_alloc_new_device() to return an error
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (11 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 12/80] dm: usb: Adjust usb command to prepare for driver model Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:40   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 14/80] dm: usb: Convert 'usb' command to support driver model Simon Glass
                   ` (67 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

This function returns NULL on error at present. Adjust it so that we can
return a real error, as is needed with driver model. Also improve the
error handling in its caller, usb_hub_port_connect_change(), and adjust
the code order to prepare for driver model.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 common/usb.c     | 17 ++++++++---------
 common/usb_hub.c | 41 ++++++++++++++++++++++++++---------------
 include/usb.h    | 20 ++++++++++++++++++--
 3 files changed, 52 insertions(+), 26 deletions(-)

diff --git a/common/usb.c b/common/usb.c
index 32e15cd..f87c6a5 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -94,12 +94,12 @@ int usb_init(void)
 		controllers_initialized++;
 		start_index = dev_index;
 		printf("scanning bus %d for devices... ", i);
-		dev = usb_alloc_new_device(ctrl);
+		ret = usb_alloc_new_device(ctrl, &dev);
 		/*
 		 * device 0 is always present
 		 * (root hub, so let it analyze)
 		 */
-		if (dev)
+		if (!ret)
 			usb_new_device(dev);
 
 		if (start_index == dev_index)
@@ -827,16 +827,13 @@ struct usb_device *usb_get_dev_index(int index)
 		return &usb_dev[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)
+int usb_alloc_new_device(struct udevice *controller, struct usb_device **devp)
 {
 	int i;
 	debug("New Device %d\n", dev_index);
 	if (dev_index == USB_MAX_DEVICE) {
 		printf("ERROR, too many USB Devices, max=%d\n", USB_MAX_DEVICE);
-		return NULL;
+		return -ENOSPC;
 	}
 	/* default Address is 0, real addresses start with 1 */
 	usb_dev[dev_index].devnum = dev_index + 1;
@@ -846,7 +843,9 @@ struct usb_device *usb_alloc_new_device(void *controller)
 	usb_dev[dev_index].parent = NULL;
 	usb_dev[dev_index].controller = controller;
 	dev_index++;
-	return &usb_dev[dev_index - 1];
+	*devp = &usb_dev[dev_index - 1];
+
+	return 0;
 }
 
 /*
@@ -854,7 +853,7 @@ struct usb_device *usb_alloc_new_device(void *controller)
  * Called in error cases where configuring a newly attached
  * device fails for some reason.
  */
-void usb_free_device(void)
+void usb_free_device(struct udevice *controller)
 {
 	dev_index--;
 	debug("Freeing device node: %d\n", dev_index);
diff --git a/common/usb_hub.c b/common/usb_hub.c
index 66b4a72..7199e25 100644
--- a/common/usb_hub.c
+++ b/common/usb_hub.c
@@ -24,6 +24,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <errno.h>
 #include <asm/processor.h>
 #include <asm/unaligned.h>
 #include <linux/ctype.h>
@@ -206,16 +207,18 @@ int hub_port_reset(struct usb_device *dev, int port,
 }
 
 
-void usb_hub_port_connect_change(struct usb_device *dev, int port)
+int usb_hub_port_connect_change(struct usb_device *dev, int port)
 {
 	struct usb_device *usb;
 	ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
 	unsigned short portstatus;
+	int ret, speed;
 
 	/* Check status */
-	if (usb_get_port_status(dev, port + 1, portsts) < 0) {
+	ret = usb_get_port_status(dev, port + 1, portsts);
+	if (ret < 0) {
 		debug("get_port_status failed\n");
-		return;
+		return ret;
 	}
 
 	portstatus = le16_to_cpu(portsts->wPortStatus);
@@ -233,47 +236,55 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
 		debug("usb_disconnect(&hub->children[port]);\n");
 		/* Return now if nothing is connected */
 		if (!(portstatus & USB_PORT_STAT_CONNECTION))
-			return;
+			return -ENOTCONN;
 	}
 	mdelay(200);
 
 	/* Reset the port */
-	if (hub_port_reset(dev, port, &portstatus) < 0) {
+	ret = hub_port_reset(dev, port, &portstatus);
+	if (ret < 0) {
 		printf("cannot reset port %i!?\n", port + 1);
-		return;
+		return ret;
 	}
 
 	mdelay(200);
 
-	/* Allocate a new device struct for it */
-	usb = usb_alloc_new_device(dev->controller);
-
 	switch (portstatus & USB_PORT_STAT_SPEED_MASK) {
 	case USB_PORT_STAT_SUPER_SPEED:
-		usb->speed = USB_SPEED_SUPER;
+		speed = USB_SPEED_SUPER;
 		break;
 	case USB_PORT_STAT_HIGH_SPEED:
-		usb->speed = USB_SPEED_HIGH;
+		speed = USB_SPEED_HIGH;
 		break;
 	case USB_PORT_STAT_LOW_SPEED:
-		usb->speed = USB_SPEED_LOW;
+		speed = USB_SPEED_LOW;
 		break;
 	default:
-		usb->speed = USB_SPEED_FULL;
+		speed = USB_SPEED_FULL;
 		break;
 	}
 
+	ret = usb_alloc_new_device(dev->controller, &usb);
+	if (ret) {
+		printf("cannot create new device: ret=%d", ret);
+		return ret;
+	}
+
 	dev->children[port] = usb;
+	usb->speed = speed;
 	usb->parent = dev;
 	usb->portnr = port + 1;
 	/* Run it through the hoops (find a driver, etc) */
-	if (usb_new_device(usb)) {
+	ret = usb_new_device(usb);
+	if (ret < 0) {
 		/* Woops, disable the port */
-		usb_free_device();
+		usb_free_device(dev->controller);
 		dev->children[port] = NULL;
 		debug("hub: disabling port %d\n", port + 1);
 		usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_ENABLE);
 	}
+
+	return ret;
 }
 
 
diff --git a/include/usb.h b/include/usb.h
index 0e1c16a..11ff5ab 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -703,10 +703,26 @@ 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);
+/**
+ * usb_alloc_new_device() - Allocate a new device
+ *
+ * @devp: returns a pointer of a new device structure. With driver model this
+ *		is a device pointer, but with legacy USB this pointer is
+ *		driver-specific.
+ * @return 0 if OK, -ENOSPC if we have found out of room for new devices
+ */
+int usb_alloc_new_device(struct udevice *controller, struct usb_device **devp);
+
+/**
+ * usb_free_device() - Free a partially-inited device
+ *
+ * This is an internal function. It is used to reverse the action of
+ * usb_alloc_new_device() when we hit a problem during init.
+ */
+void usb_free_device(struct udevice *controller);
 
 int usb_new_device(struct usb_device *dev);
-void usb_free_device(void);
+
 int usb_alloc_device(struct usb_device *dev);
 
 #endif /*_USB_H_ */
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 14/80] dm: usb: Convert 'usb' command to support driver model
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (12 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 13/80] dm: usb: Adjust usb_alloc_new_device() to return an error Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:40   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 15/80] dm: usb: Drop the legacy USB init sequence Simon Glass
                   ` (66 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

Adjust this command to work with the new driver model uclass. It needs to
iterate through multiple independent controllers to find hubs, and work
through their children recursively in a different way. Otherwise the
functionality is much the same.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 common/cmd_usb.c | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 145 insertions(+), 2 deletions(-)

diff --git a/common/cmd_usb.c b/common/cmd_usb.c
index 085802b..eab55cd 100644
--- a/common/cmd_usb.c
+++ b/common/cmd_usb.c
@@ -2,6 +2,9 @@
  * (C) Copyright 2001
  * Denis Peter, MPL AG Switzerland
  *
+ * Adapted for U-Boot driver model
+ * (C) Copyright 2015 Google, Inc
+ *
  * Most of this source has been derived from the Linux USB
  * project.
  *
@@ -10,6 +13,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <dm.h>
 #include <asm/byteorder.h>
 #include <asm/unaligned.h>
 #include <part.h>
@@ -252,8 +256,46 @@ static void usb_display_config(struct usb_device *dev)
 	printf("\n");
 }
 
+/*
+ * With driver model this isn't right since we can have multiple controllers
+ * and the device numbering starts at 1 on each bus.
+ * TODO(sjg at chromium.org): Add a way to specify the controller/bus.
+ */
 static struct usb_device *usb_find_device(int devnum)
 {
+#ifdef CONFIG_DM_USB
+	struct usb_device *udev;
+	struct udevice *hub;
+	struct uclass *uc;
+	int ret;
+
+	/* Device addresses start at 1 */
+	devnum++;
+	ret = uclass_get(UCLASS_USB_HUB, &uc);
+	if (ret)
+		return NULL;
+
+	uclass_foreach_dev(hub, uc) {
+		struct udevice *dev;
+
+		if (!device_active(hub))
+			continue;
+		udev = dev_get_parentdata(hub);
+		if (udev->devnum == devnum)
+			return udev;
+
+		for (device_find_first_child(hub, &dev);
+		     dev;
+		     device_find_next_child(&dev)) {
+			if (!device_active(hub))
+				continue;
+
+			udev = dev_get_parentdata(dev);
+			if (udev->devnum == devnum)
+				return udev;
+		}
+	}
+#else
 	struct usb_device *udev;
 	int d;
 
@@ -264,6 +306,7 @@ static struct usb_device *usb_find_device(int devnum)
 		if (udev->devnum == devnum)
 			return udev;
 	}
+#endif
 
 	return NULL;
 }
@@ -293,20 +336,31 @@ static inline char *portspeed(int speed)
 /* shows the device tree recursively */
 static void usb_show_tree_graph(struct usb_device *dev, char *pre)
 {
-	int i, index;
+	int index;
 	int has_child, last_child;
 
 	index = strlen(pre);
 	printf(" %s", pre);
+#ifdef CONFIG_DM_USB
+	has_child = device_has_active_children(dev->dev);
+#else
 	/* check if the device has connected children */
+	int i;
+
 	has_child = 0;
 	for (i = 0; i < dev->maxchild; i++) {
 		if (dev->children[i] != NULL)
 			has_child = 1;
 	}
+#endif
 	/* check if we are the last one */
+#ifdef CONFIG_DM_USB
+	last_child = device_is_last_sibling(dev->dev);
+#else
 	last_child = (dev->parent != NULL);
+#endif
 	if (last_child) {
+#ifndef CONFIG_DM_USB
 		for (i = 0; i < dev->parent->maxchild; i++) {
 			/* search for children */
 			if (dev->parent->children[i] == dev) {
@@ -322,6 +376,7 @@ static void usb_show_tree_graph(struct usb_device *dev, char *pre)
 				} /* while */
 			} /* device found */
 		} /* for all children of the parent */
+#endif
 		printf("\b+-");
 		/* correct last child */
 		if (last_child && index)
@@ -340,6 +395,26 @@ static void usb_show_tree_graph(struct usb_device *dev, char *pre)
 	if (strlen(dev->mf) || strlen(dev->prod) || strlen(dev->serial))
 		printf(" %s  %s %s %s\n", pre, dev->mf, dev->prod, dev->serial);
 	printf(" %s\n", pre);
+#ifdef CONFIG_DM_USB
+	struct udevice *child;
+
+	for (device_find_first_child(dev->dev, &child);
+	     child;
+	     device_find_next_child(&child)) {
+		struct usb_device *udev;
+
+		if (!device_active(child))
+			continue;
+
+		udev = dev_get_parentdata(child);
+
+		/* Ignore emulators, we only want real devices */
+		if (device_get_uclass_id(child) != UCLASS_USB_EMUL) {
+			usb_show_tree_graph(udev, pre);
+			pre[index] = 0;
+		}
+	}
+#else
 	if (dev->maxchild > 0) {
 		for (i = 0; i < dev->maxchild; i++) {
 			if (dev->children[i] != NULL) {
@@ -348,6 +423,7 @@ static void usb_show_tree_graph(struct usb_device *dev, char *pre)
 			}
 		}
 	}
+#endif
 }
 
 /* main routine for the tree command */
@@ -448,10 +524,13 @@ static void do_usb_start(void)
 	if (usb_init() < 0)
 		return;
 
+	/* Driver model will probe the devices as they are found */
+#ifndef CONFIG_DM_USB
 #ifdef CONFIG_USB_STORAGE
 	/* try to recognize storage devices immediately */
 	usb_stor_curr_dev = usb_stor_scan(1);
 #endif
+#endif
 #ifdef CONFIG_USB_HOST_ETHER
 	/* try to recognize ethernet devices immediately */
 	usb_ether_curr_dev = usb_host_eth_scan(1);
@@ -461,6 +540,43 @@ static void do_usb_start(void)
 #endif
 }
 
+#ifdef CONFIG_DM_USB
+static void show_info(struct udevice *dev)
+{
+	struct udevice *child;
+	struct usb_device *udev;
+
+	udev = dev_get_parentdata(dev);
+	usb_display_desc(udev);
+	usb_display_config(udev);
+	for (device_find_first_child(dev, &child);
+	     child;
+	     device_find_next_child(&child)) {
+		if (device_active(child))
+			show_info(child);
+	}
+}
+
+static int usb_device_info(void)
+{
+	struct udevice *bus;
+
+	for (uclass_first_device(UCLASS_USB, &bus);
+	     bus;
+	     uclass_next_device(&bus)) {
+		struct udevice *hub;
+
+		device_find_first_child(bus, &hub);
+		if (device_get_uclass_id(hub) == UCLASS_USB_HUB &&
+		    device_active(hub)) {
+			show_info(hub);
+		}
+	}
+
+	return 0;
+}
+#endif
+
 /******************************************************************************
  * usb command intepreter
  */
@@ -507,6 +623,23 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	}
 	if (strncmp(argv[1], "tree", 4) == 0) {
 		puts("USB device tree:\n");
+#ifdef CONFIG_DM_USB
+		struct udevice *bus;
+
+		for (uclass_first_device(UCLASS_USB, &bus);
+		     bus;
+		     uclass_next_device(&bus)) {
+			struct usb_device *udev;
+			struct udevice *hub;
+
+			device_find_first_child(bus, &hub);
+			if (device_get_uclass_id(hub) == UCLASS_USB_HUB &&
+			    device_active(hub)) {
+				udev = dev_get_parentdata(hub);
+				usb_show_tree(udev);
+			}
+		}
+#else
 		for (i = 0; i < USB_MAX_DEVICE; i++) {
 			udev = usb_get_dev_index(i);
 			if (udev == NULL)
@@ -514,11 +647,15 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 			if (udev->parent == NULL)
 				usb_show_tree(udev);
 		}
+#endif
 		return 0;
 	}
 	if (strncmp(argv[1], "inf", 3) == 0) {
-		int d;
 		if (argc == 2) {
+#ifdef CONFIG_DM_USB
+			usb_device_info();
+#else
+			int d;
 			for (d = 0; d < USB_MAX_DEVICE; d++) {
 				udev = usb_get_dev_index(d);
 				if (udev == NULL)
@@ -526,8 +663,14 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 				usb_display_desc(udev);
 				usb_display_config(udev);
 			}
+#endif
 			return 0;
 		} else {
+			/*
+			 * With driver model this isn't right since we can
+			 * have multiple controllers and the device numbering
+			 * starts@1 on each bus.
+			 */
 			i = simple_strtoul(argv[2], NULL, 10);
 			printf("config for device %d\n", i);
 			udev = usb_find_device(i);
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 15/80] dm: usb: Drop the legacy USB init sequence
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (13 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 14/80] dm: usb: Convert 'usb' command to support driver model Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-03-26 18:22   ` Marek Vasut
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 16/80] dm: usb: Refactor port resets Simon Glass
                   ` (65 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

This CONFIG is not used anywhere in U-Boot, so drop it.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 common/usb.c | 26 ++++----------------------
 1 file changed, 4 insertions(+), 22 deletions(-)

diff --git a/common/usb.c b/common/usb.c
index f87c6a5..330e6a2 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -899,26 +899,8 @@ int usb_new_device(struct usb_device *dev)
 	addr = dev->devnum;
 	dev->devnum = 0;
 
-#ifdef CONFIG_LEGACY_USB_INIT_SEQ
-	/* this is the old and known way of initializing devices, it is
-	 * different than what Windows and Linux are doing. Windows and Linux
-	 * both retrieve 64 bytes while reading the device descriptor
-	 * Several USB stick devices report ERR: CTL_TIMEOUT, caused by an
-	 * invalid header while reading 8 bytes as device descriptor. */
-	dev->descriptor.bMaxPacketSize0 = 8;	    /* Start off at 8 bytes  */
-	dev->maxpacketsize = PACKET_SIZE_8;
-	dev->epmaxpacketin[0] = 8;
-	dev->epmaxpacketout[0] = 8;
-
-	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, tmpbuf, 8);
-	if (err < 8) {
-		printf("\n      USB device not responding, " \
-		       "giving up (status=%lX)\n", dev->status);
-		return 1;
-	}
-	memcpy(&dev->descriptor, tmpbuf, 8);
-#else
-	/* This is a Windows scheme of initialization sequence, with double
+	/*
+	 * This is a Windows scheme of initialization sequence, with double
 	 * reset of the device (Linux uses the same sequence)
 	 * Some equipment is said to work only with such init sequence; this
 	 * patch is based on the work by Alan Stern:
@@ -929,7 +911,8 @@ int usb_new_device(struct usb_device *dev)
 	struct usb_device *parent = dev->parent;
 	unsigned short portstatus;
 
-	/* send 64-byte GET-DEVICE-DESCRIPTOR request.  Since the descriptor is
+	/*
+	 * send 64-byte GET-DEVICE-DESCRIPTOR request.  Since the descriptor is
 	 * only 18 bytes long, this will terminate with a short packet.  But if
 	 * the maxpacket size is 8 or 16 the device may be waiting to transmit
 	 * some more, or keeps on retransmitting the 8 byte header. */
@@ -972,7 +955,6 @@ int usb_new_device(struct usb_device *dev)
 	} else {
 		usb_reset_root_port();
 	}
-#endif
 
 	dev->epmaxpacketin[0] = dev->descriptor.bMaxPacketSize0;
 	dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0;
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 16/80] dm: usb: Refactor port resets
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (14 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 15/80] dm: usb: Drop the legacy USB init sequence Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:41   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 17/80] dm: usb: Move descriptor setup code into its own function Simon Glass
                   ` (64 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

Move the port reset code into its own function. Rename usb_hub_reset() to
indicate that is is now a legacy function.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 common/usb.c     | 40 ++++++++++++++++++++++++++--------------
 common/usb_hub.c |  4 ++--
 include/usb.h    | 18 +++++++++++++++++-
 3 files changed, 45 insertions(+), 17 deletions(-)

diff --git a/common/usb.c b/common/usb.c
index 330e6a2..4ab2213 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -871,6 +871,26 @@ __weak int usb_alloc_device(struct usb_device *udev)
 {
 	return 0;
 }
+
+int usb_legacy_port_reset(struct usb_device *hub, int portnr)
+{
+	if (hub) {
+		unsigned short portstatus;
+		int err;
+
+		/* reset the port for the second time */
+		err = legacy_hub_port_reset(hub, portnr - 1, &portstatus);
+		if (err < 0) {
+			printf("\n     Couldn't reset port %i\n", portnr);
+			return err;
+		}
+	} else {
+		usb_reset_root_port();
+	}
+
+	return 0;
+}
+
 /*
  * By the time we get here, the device has gotten a new device ID
  * and is in the default state. We need to identify the thing and
@@ -907,9 +927,6 @@ int usb_new_device(struct usb_device *dev)
 	 * http://sourceforge.net/mailarchive/forum.php?
 	 * thread_id=5729457&forum_id=5398
 	 */
-	__maybe_unused struct usb_device_descriptor *desc;
-	struct usb_device *parent = dev->parent;
-	unsigned short portstatus;
 
 	/*
 	 * send 64-byte GET-DEVICE-DESCRIPTOR request.  Since the descriptor is
@@ -917,7 +934,6 @@ int usb_new_device(struct usb_device *dev)
 	 * the maxpacket size is 8 or 16 the device may be waiting to transmit
 	 * some more, or keeps on retransmitting the 8 byte header. */
 
-	desc = (struct usb_device_descriptor *)tmpbuf;
 	dev->descriptor.bMaxPacketSize0 = 64;	    /* Start off at 64 bytes  */
 	/* Default to 64 byte max packet size */
 	dev->maxpacketsize = PACKET_SIZE_64;
@@ -931,6 +947,9 @@ int usb_new_device(struct usb_device *dev)
 	 * of that is done for XHCI unlike EHCI.
 	 */
 #ifndef CONFIG_USB_XHCI
+	struct usb_device_descriptor *desc;
+
+	desc = (struct usb_device_descriptor *)tmpbuf;
 	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, 64);
 	if (err < 0) {
 		debug("usb_new_device: usb_get_descriptor() failed\n");
@@ -945,16 +964,9 @@ int usb_new_device(struct usb_device *dev)
 	dev->descriptor.bDeviceClass = desc->bDeviceClass;
 #endif
 
-	if (parent) {
-		/* reset the port for the second time */
-		err = hub_port_reset(dev->parent, dev->portnr - 1, &portstatus);
-		if (err < 0) {
-			printf("\n     Couldn't reset port %i\n", dev->portnr);
-			return 1;
-		}
-	} else {
-		usb_reset_root_port();
-	}
+	err = usb_legacy_port_reset(dev->parent, dev->portnr);
+	if (err)
+		return err;
 
 	dev->epmaxpacketin[0] = dev->descriptor.bMaxPacketSize0;
 	dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0;
diff --git a/common/usb_hub.c b/common/usb_hub.c
index 7199e25..49fa5a6 100644
--- a/common/usb_hub.c
+++ b/common/usb_hub.c
@@ -141,7 +141,7 @@ static inline char *portspeed(int portstatus)
 	return speed_str;
 }
 
-int hub_port_reset(struct usb_device *dev, int port,
+int legacy_hub_port_reset(struct usb_device *dev, int port,
 			unsigned short *portstat)
 {
 	int tries;
@@ -241,7 +241,7 @@ int usb_hub_port_connect_change(struct usb_device *dev, int port)
 	mdelay(200);
 
 	/* Reset the port */
-	ret = hub_port_reset(dev, port, &portstatus);
+	ret = legacy_hub_port_reset(dev, port, &portstatus);
 	if (ret < 0) {
 		printf("cannot reset port %i!?\n", port + 1);
 		return ret;
diff --git a/include/usb.h b/include/usb.h
index 11ff5ab..badb287 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -700,9 +700,25 @@ bool usb_device_has_child_on_port(struct usb_device *parent, int port);
 
 int usb_hub_probe(struct usb_device *dev, int ifnum);
 void usb_hub_reset(void);
-int hub_port_reset(struct usb_device *dev, int port,
+
+/**
+ * legacy_hub_port_reset() - reset a port given its usb_device pointer
+ *
+ * Reset a hub port and see if a device is present on that port, providing
+ * sufficient time for it to show itself. The port status is returned.
+ *
+ * With driver model this moves to hub_port_reset() and is passed a struct
+ * udevice.
+ *
+ * @dev:	USB device to reset
+ * @port:	Port number to reset (note ports are numbered from 0 here)
+ * @portstat:	Returns port status
+ */
+int legacy_hub_port_reset(struct usb_device *dev, int port,
 			  unsigned short *portstat);
 
+int hub_port_reset(struct udevice *dev, int port, unsigned short *portstat);
+
 /**
  * usb_alloc_new_device() - Allocate a new device
  *
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 17/80] dm: usb: Move descriptor setup code into its own function
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (15 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 16/80] dm: usb: Refactor port resets Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:41   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 18/80] dm: usb: Split out more code from usb_new_device() Simon Glass
                   ` (63 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

usb_new_device() is far too long and does far too much. As a first step, move
the code that does initial setup and reads a descriptor into its own function
called usb_setup_descriptor().

For XHCI the init order is different - we set up the device but don't
actually read the descriptor until after we set an address. Support this
option as a parameter to usb_setup_descriptor().

Avoid changing this torturous code more than necessary to make it easy to
review.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 common/usb.c | 117 ++++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 67 insertions(+), 50 deletions(-)

diff --git a/common/usb.c b/common/usb.c
index 4ab2213..d0debbc 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -891,35 +891,12 @@ int usb_legacy_port_reset(struct usb_device *hub, int portnr)
 	return 0;
 }
 
-/*
- * By the time we get here, the device has gotten a new device ID
- * and is in the default state. We need to identify the thing and
- * get the ball rolling..
- *
- * Returns 0 for success, != 0 for error.
- */
-int usb_new_device(struct usb_device *dev)
+static int usb_setup_descriptor(struct usb_device *dev, bool do_read)
 {
-	int addr, err;
-	int tmp;
+	__maybe_unused struct usb_device_descriptor *desc;
 	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
 
 	/*
-	 * Allocate usb 3.0 device context.
-	 * USB 3.0 (xHCI) protocol tries to allocate device slot
-	 * and related data structures first. This call does that.
-	 * Refer to sec 4.3.2 in xHCI spec rev1.0
-	 */
-	if (usb_alloc_device(dev)) {
-		printf("Cannot allocate device context to get SLOT_ID\n");
-		return -1;
-	}
-
-	/* We still haven't set the Address yet */
-	addr = dev->devnum;
-	dev->devnum = 0;
-
-	/*
 	 * This is a Windows scheme of initialization sequence, with double
 	 * reset of the device (Linux uses the same sequence)
 	 * Some equipment is said to work only with such init sequence; this
@@ -934,40 +911,31 @@ int usb_new_device(struct usb_device *dev)
 	 * the maxpacket size is 8 or 16 the device may be waiting to transmit
 	 * some more, or keeps on retransmitting the 8 byte header. */
 
+	desc = (struct usb_device_descriptor *)tmpbuf;
 	dev->descriptor.bMaxPacketSize0 = 64;	    /* Start off at 64 bytes  */
 	/* Default to 64 byte max packet size */
 	dev->maxpacketsize = PACKET_SIZE_64;
 	dev->epmaxpacketin[0] = 64;
 	dev->epmaxpacketout[0] = 64;
 
-	/*
-	 * XHCI needs to issue a Address device command to setup
-	 * proper device context structures, before it can interact
-	 * with the device. So a get_descriptor will fail before any
-	 * of that is done for XHCI unlike EHCI.
-	 */
-#ifndef CONFIG_USB_XHCI
-	struct usb_device_descriptor *desc;
+	if (do_read) {
+		int err;
 
-	desc = (struct usb_device_descriptor *)tmpbuf;
-	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, 64);
-	if (err < 0) {
-		debug("usb_new_device: usb_get_descriptor() failed\n");
-		return 1;
+		err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, 64);
+		if (err < sizeof(dev->descriptor)) {
+			if (err < 0) {
+				printf("unable to get device descriptor (error=%d)\n",
+				       err);
+				return err;
+			} else {
+				printf("USB device descriptor short read (expected %i, got %i)\n",
+				       (int)sizeof(dev->descriptor), err);
+				return -EIO;
+			}
+		}
+		memcpy(&dev->descriptor, tmpbuf, sizeof(dev->descriptor));
 	}
 
-	dev->descriptor.bMaxPacketSize0 = desc->bMaxPacketSize0;
-	/*
-	 * Fetch the device class, driver can use this info
-	 * to differentiate between HUB and DEVICE.
-	 */
-	dev->descriptor.bDeviceClass = desc->bDeviceClass;
-#endif
-
-	err = usb_legacy_port_reset(dev->parent, dev->portnr);
-	if (err)
-		return err;
-
 	dev->epmaxpacketin[0] = dev->descriptor.bMaxPacketSize0;
 	dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0;
 	switch (dev->descriptor.bMaxPacketSize0) {
@@ -984,6 +952,55 @@ int usb_new_device(struct usb_device *dev)
 		dev->maxpacketsize = PACKET_SIZE_64;
 		break;
 	}
+
+	return 0;
+}
+
+/*
+ * By the time we get here, the device has gotten a new device ID
+ * and is in the default state. We need to identify the thing and
+ * get the ball rolling..
+ *
+ * Returns 0 for success, != 0 for error.
+ */
+int usb_new_device(struct usb_device *dev)
+{
+	bool do_read = true;
+	int addr, err;
+	int tmp;
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
+
+	/*
+	 * Allocate usb 3.0 device context.
+	 * USB 3.0 (xHCI) protocol tries to allocate device slot
+	 * and related data structures first. This call does that.
+	 * Refer to sec 4.3.2 in xHCI spec rev1.0
+	 */
+	if (usb_alloc_device(dev)) {
+		printf("Cannot allocate device context to get SLOT_ID\n");
+		return -1;
+	}
+
+	/* We still haven't set the Address yet */
+	addr = dev->devnum;
+	dev->devnum = 0;
+
+	/*
+	 * XHCI needs to issue a Address device command to setup
+	 * proper device context structures, before it can interact
+	 * with the device. So a get_descriptor will fail before any
+	 * of that is done for XHCI unlike EHCI.
+	 */
+#ifndef CONFIG_USB_XHCI
+	do_read = false;
+#endif
+	err = usb_setup_descriptor(dev, do_read);
+	if (err)
+		return err;
+	err = usb_legacy_port_reset(dev->parent, dev->portnr);
+	if (err)
+		return err;
+
 	dev->devnum = addr;
 
 	err = usb_set_address(dev); /* set address */
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 18/80] dm: usb: Split out more code from usb_new_device()
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (16 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 17/80] dm: usb: Move descriptor setup code into its own function Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:41   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 19/80] dm: usb: Complete the splitting up of usb_new_device() Simon Glass
                   ` (62 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

Move the code that sets up the device with a new address into its own
function, usb_prepare_device().

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 common/usb.c | 72 +++++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 42 insertions(+), 30 deletions(-)

diff --git a/common/usb.c b/common/usb.c
index d0debbc..c3f805d 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -956,19 +956,10 @@ static int usb_setup_descriptor(struct usb_device *dev, bool do_read)
 	return 0;
 }
 
-/*
- * By the time we get here, the device has gotten a new device ID
- * and is in the default state. We need to identify the thing and
- * get the ball rolling..
- *
- * Returns 0 for success, != 0 for error.
- */
-int usb_new_device(struct usb_device *dev)
+static int usb_prepare_device(struct usb_device *dev, int addr, bool do_read,
+			      struct usb_device *parent, int portnr)
 {
-	bool do_read = true;
-	int addr, err;
-	int tmp;
-	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
+	int err;
 
 	/*
 	 * Allocate usb 3.0 device context.
@@ -976,28 +967,15 @@ int usb_new_device(struct usb_device *dev)
 	 * and related data structures first. This call does that.
 	 * Refer to sec 4.3.2 in xHCI spec rev1.0
 	 */
-	if (usb_alloc_device(dev)) {
+	err = usb_alloc_device(dev);
+	if (err) {
 		printf("Cannot allocate device context to get SLOT_ID\n");
-		return -1;
+		return err;
 	}
-
-	/* We still haven't set the Address yet */
-	addr = dev->devnum;
-	dev->devnum = 0;
-
-	/*
-	 * XHCI needs to issue a Address device command to setup
-	 * proper device context structures, before it can interact
-	 * with the device. So a get_descriptor will fail before any
-	 * of that is done for XHCI unlike EHCI.
-	 */
-#ifndef CONFIG_USB_XHCI
-	do_read = false;
-#endif
 	err = usb_setup_descriptor(dev, do_read);
 	if (err)
 		return err;
-	err = usb_legacy_port_reset(dev->parent, dev->portnr);
+	err = usb_legacy_port_reset(parent, portnr);
 	if (err)
 		return err;
 
@@ -1008,11 +986,45 @@ int usb_new_device(struct usb_device *dev)
 	if (err < 0) {
 		printf("\n      USB device not accepting new address " \
 			"(error=%lX)\n", dev->status);
-		return 1;
+		return err;
 	}
 
 	mdelay(10);	/* Let the SET_ADDRESS settle */
 
+	return 0;
+}
+
+/*
+ * By the time we get here, the device has gotten a new device ID
+ * and is in the default state. We need to identify the thing and
+ * get the ball rolling..
+ *
+ * Returns 0 for success, != 0 for error.
+ */
+int usb_new_device(struct usb_device *dev)
+{
+	bool do_read = true;
+	int addr, err;
+	int tmp, ret;
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
+
+	/* We still haven't set the Address yet */
+	addr = dev->devnum;
+	dev->devnum = 0;
+
+	/*
+	 * XHCI needs to issue a Address device command to setup
+	 * proper device context structures, before it can interact
+	 * with the device. So a get_descriptor will fail before any
+	 * of that is done for XHCI unlike EHCI.
+	 */
+#ifndef CONFIG_USB_XHCI
+	do_read = false;
+#endif
+	ret = usb_prepare_device(dev, addr, do_read, dev->parent, dev->portnr);
+	if (ret)
+		return ret;
+
 	tmp = sizeof(dev->descriptor);
 
 	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 19/80] dm: usb: Complete the splitting up of usb_new_device()
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (17 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 18/80] dm: usb: Split out more code from usb_new_device() Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:41   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 20/80] dm: usb: Convert core usb.c file to support driver model Simon Glass
                   ` (61 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

This function now calls usb_setup_device() to set up the device and
usb_hub_probe() to check if it is a hub. The XHCI special case is now a
parameter to usb_setup_device(). The latter will be used by the USB uclass
when it is added, since it does not rely on any CONFIGs or legacy data
structures.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 common/usb.c | 114 +++++++++++++++++++++++++++++++++++------------------------
 1 file changed, 68 insertions(+), 46 deletions(-)

diff --git a/common/usb.c b/common/usb.c
index c3f805d..5e14d7c 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -994,71 +994,40 @@ static int usb_prepare_device(struct usb_device *dev, int addr, bool do_read,
 	return 0;
 }
 
-/*
- * By the time we get here, the device has gotten a new device ID
- * and is in the default state. We need to identify the thing and
- * get the ball rolling..
- *
- * Returns 0 for success, != 0 for error.
- */
-int usb_new_device(struct usb_device *dev)
+static int usb_select_config(struct usb_device *dev)
 {
-	bool do_read = true;
-	int addr, err;
-	int tmp, ret;
 	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
+	int err;
 
-	/* We still haven't set the Address yet */
-	addr = dev->devnum;
-	dev->devnum = 0;
-
-	/*
-	 * XHCI needs to issue a Address device command to setup
-	 * proper device context structures, before it can interact
-	 * with the device. So a get_descriptor will fail before any
-	 * of that is done for XHCI unlike EHCI.
-	 */
-#ifndef CONFIG_USB_XHCI
-	do_read = false;
-#endif
-	ret = usb_prepare_device(dev, addr, do_read, dev->parent, dev->portnr);
-	if (ret)
-		return ret;
-
-	tmp = sizeof(dev->descriptor);
+	err = usb_setup_descriptor(dev, true);
+	if (err)
+		return err;
 
-	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
-				 tmpbuf, sizeof(dev->descriptor));
-	if (err < tmp) {
-		if (err < 0)
-			printf("unable to get device descriptor (error=%d)\n",
-			       err);
-		else
-			printf("USB device descriptor short read " \
-				"(expected %i, got %i)\n", tmp, err);
-		return 1;
-	}
-	memcpy(&dev->descriptor, tmpbuf, sizeof(dev->descriptor));
 	/* correct le values */
 	le16_to_cpus(&dev->descriptor.bcdUSB);
 	le16_to_cpus(&dev->descriptor.idVendor);
 	le16_to_cpus(&dev->descriptor.idProduct);
 	le16_to_cpus(&dev->descriptor.bcdDevice);
+
 	/* only support for one config for now */
 	err = usb_get_configuration_no(dev, tmpbuf, 0);
 	if (err < 0) {
 		printf("usb_new_device: Cannot read configuration, " \
 		       "skipping device %04x:%04x\n",
 		       dev->descriptor.idVendor, dev->descriptor.idProduct);
-		return -1;
+		return -err;
 	}
 	usb_parse_config(dev, tmpbuf, 0);
 	usb_set_maxpacket(dev);
-	/* we set the default configuration here */
+	/*
+	 * we set the default configuration here
+	 * This seems premature. If the driver wants a different configuration
+	 * it will need to select itself.
+	 */
 	if (usb_set_configuration(dev, dev->config.desc.bConfigurationValue)) {
 		printf("failed to set default configuration " \
 			"len %d, status %lX\n", dev->act_len, dev->status);
-		return -1;
+		return -err;
 	}
 	debug("new device strings: Mfr=%d, Product=%d, SerialNumber=%d\n",
 	      dev->descriptor.iManufacturer, dev->descriptor.iProduct,
@@ -1078,11 +1047,64 @@ int usb_new_device(struct usb_device *dev)
 	debug("Manufacturer %s\n", dev->mf);
 	debug("Product      %s\n", dev->prod);
 	debug("SerialNumber %s\n", dev->serial);
-	/* now prode if the device is a hub */
-	usb_hub_probe(dev, 0);
+
 	return 0;
 }
 
+static int usb_setup_device(struct usb_device *dev, bool do_read,
+			    struct usb_device *parent, int portnr)
+{
+	int addr;
+	int ret;
+
+	/* We still haven't set the Address yet */
+	addr = dev->devnum;
+	dev->devnum = 0;
+
+	ret = usb_prepare_device(dev, addr, do_read, parent, portnr);
+	if (ret)
+		return ret;
+	ret = usb_select_config(dev);
+
+	return ret;
+}
+
+/*
+ * By the time we get here, the device has gotten a new device ID
+ * and is in the default state. We need to identify the thing and
+ * get the ball rolling..
+ *
+ * Returns 0 for success, != 0 for error.
+ */
+int usb_new_device(struct usb_device *dev)
+{
+	bool do_read = true;
+	int count;
+	int err;
+
+	/*
+	 * XHCI needs to issue a Address device command to setup
+	 * proper device context structures, before it can interact
+	 * with the device. So a get_descriptor will fail before any
+	 * of that is done for XHCI unlike EHCI.
+	 */
+#ifndef CONFIG_USB_XHCI
+	do_read = false;
+#endif
+	err = usb_setup_device(dev, do_read, dev->parent, dev->portnr);
+	if (err)
+		return err;
+
+	count = 1;
+	/* now prode if the device is a hub */
+	err = usb_hub_probe(dev, 0);
+	if (err < 0)
+		return err;
+	count += err;
+
+	return count;
+}
+
 __weak
 int board_usb_init(int index, enum usb_init_type init)
 {
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 20/80] dm: usb: Convert core usb.c file to support driver model
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (18 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 19/80] dm: usb: Complete the splitting up of usb_new_device() Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:41   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 21/80] dm: usb: Split hub detection into its own function Simon Glass
                   ` (60 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

Add the required #ifdefs and remove unwanted data structures so that the
USB uclass will be able to use this file.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 common/usb.c | 31 +++++++++++++++++++++++++------
 1 file changed, 25 insertions(+), 6 deletions(-)

diff --git a/common/usb.c b/common/usb.c
index 5e14d7c..06c1c43 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -28,6 +28,7 @@
  */
 #include <common.h>
 #include <command.h>
+#include <dm.h>
 #include <asm/processor.h>
 #include <linux/compiler.h>
 #include <linux/ctype.h>
@@ -41,12 +42,13 @@
 
 #define USB_BUFSIZ	512
 
-static struct usb_device usb_dev[USB_MAX_DEVICE];
-static int dev_index;
 static int asynch_allowed;
-
 char usb_started; /* flag for the started/stopped USB status */
 
+#ifndef CONFIG_DM_USB
+static struct usb_device usb_dev[USB_MAX_DEVICE];
+static int dev_index;
+
 #ifndef CONFIG_USB_MAX_CONTROLLER_COUNT
 #define CONFIG_USB_MAX_CONTROLLER_COUNT 1
 #endif
@@ -152,6 +154,7 @@ int usb_disable_asynch(int disable)
 	asynch_allowed = !disable;
 	return old_value;
 }
+#endif /* !CONFIG_DM_USB */
 
 
 /*-------------------------------------------------------------------
@@ -815,6 +818,7 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
  * the USB device are static allocated [USB_MAX_DEVICE].
  */
 
+#ifndef CONFIG_DM_USB
 
 /* returns a pointer to the device with the index [index].
  * if the device is not assigned (dev->devnum==-1) returns NULL
@@ -871,7 +875,9 @@ __weak int usb_alloc_device(struct usb_device *udev)
 {
 	return 0;
 }
+#endif /* !CONFIG_DM_USB */
 
+#ifndef CONFIG_DM_USB
 int usb_legacy_port_reset(struct usb_device *hub, int portnr)
 {
 	if (hub) {
@@ -890,6 +896,7 @@ int usb_legacy_port_reset(struct usb_device *hub, int portnr)
 
 	return 0;
 }
+#endif
 
 static int usb_setup_descriptor(struct usb_device *dev, bool do_read)
 {
@@ -994,7 +1001,7 @@ static int usb_prepare_device(struct usb_device *dev, int addr, bool do_read,
 	return 0;
 }
 
-static int usb_select_config(struct usb_device *dev)
+int usb_select_config(struct usb_device *dev)
 {
 	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
 	int err;
@@ -1051,8 +1058,8 @@ static int usb_select_config(struct usb_device *dev)
 	return 0;
 }
 
-static int usb_setup_device(struct usb_device *dev, bool do_read,
-			    struct usb_device *parent, int portnr)
+int usb_setup_device(struct usb_device *dev, bool do_read,
+		     struct usb_device *parent, int portnr)
 {
 	int addr;
 	int ret;
@@ -1069,6 +1076,7 @@ static int usb_setup_device(struct usb_device *dev, bool do_read,
 	return ret;
 }
 
+#ifndef CONFIG_DM_USB
 /*
  * By the time we get here, the device has gotten a new device ID
  * and is in the default state. We need to identify the thing and
@@ -1104,10 +1112,21 @@ int usb_new_device(struct usb_device *dev)
 
 	return count;
 }
+#endif
 
 __weak
 int board_usb_init(int index, enum usb_init_type init)
 {
 	return 0;
 }
+
+bool usb_device_has_child_on_port(struct usb_device *parent, int port)
+{
+#ifdef CONFIG_DM_USB
+	return false;
+#else
+	return parent->children[port] != NULL;
+#endif
+}
+
 /* EOF */
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 21/80] dm: usb: Split hub detection into its own function
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (19 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 20/80] dm: usb: Convert core usb.c file to support driver model Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:41   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 22/80] dm: usb: Add driver model support for hubs Simon Glass
                   ` (59 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

Split out the hub detection logic so it can be used by driver model. Also
adjust the code to return errors correctly.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 common/usb_hub.c | 57 ++++++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 41 insertions(+), 16 deletions(-)

diff --git a/common/usb_hub.c b/common/usb_hub.c
index 49fa5a6..cc22f4b 100644
--- a/common/usb_hub.c
+++ b/common/usb_hub.c
@@ -297,27 +297,30 @@ static int usb_hub_configure(struct usb_device *dev)
 	struct usb_hub_descriptor *descriptor;
 	struct usb_hub_device *hub;
 	__maybe_unused struct usb_hub_status *hubsts;
+	int ret;
 
 	/* "allocate" Hub device */
 	hub = usb_hub_allocate();
 	if (hub == NULL)
-		return -1;
+		return -ENOMEM;
 	hub->pusb_dev = dev;
 	/* Get the the hub descriptor */
-	if (usb_get_hub_descriptor(dev, buffer, 4) < 0) {
+	ret = usb_get_hub_descriptor(dev, buffer, 4);
+	if (ret < 0) {
 		debug("usb_hub_configure: failed to get hub " \
 		      "descriptor, giving up %lX\n", dev->status);
-		return -1;
+		return ret;
 	}
 	descriptor = (struct usb_hub_descriptor *)buffer;
 
 	length = min_t(int, descriptor->bLength,
 		       sizeof(struct usb_hub_descriptor));
 
-	if (usb_get_hub_descriptor(dev, buffer, length) < 0) {
+	ret = usb_get_hub_descriptor(dev, buffer, length);
+	if (ret < 0) {
 		debug("usb_hub_configure: failed to get hub " \
 		      "descriptor 2nd giving up %lX\n", dev->status);
-		return -1;
+		return ret;
 	}
 	memcpy((unsigned char *)&hub->desc, buffer, length);
 	/* adjust 16bit values */
@@ -385,13 +388,14 @@ static int usb_hub_configure(struct usb_device *dev)
 	if (sizeof(struct usb_hub_status) > USB_BUFSIZ) {
 		debug("usb_hub_configure: failed to get Status - " \
 		      "too long: %d\n", descriptor->bLength);
-		return -1;
+		return -EFBIG;
 	}
 
-	if (usb_get_hub_status(dev, buffer) < 0) {
+	ret = usb_get_hub_status(dev, buffer);
+	if (ret < 0) {
 		debug("usb_hub_configure: failed to get Status %lX\n",
 		      dev->status);
-		return -1;
+		return ret;
 	}
 
 #ifdef DEBUG
@@ -423,6 +427,7 @@ static int usb_hub_configure(struct usb_device *dev)
 		int ret;
 		ulong start = get_timer(0);
 
+		debug("\n\nScanning port %d\n", i + 1);
 		/*
 		 * Wait for (whichever finishes first)
 		 *  - A maximum of 10 seconds
@@ -503,33 +508,53 @@ static int usb_hub_configure(struct usb_device *dev)
 	return 0;
 }
 
-int usb_hub_probe(struct usb_device *dev, int ifnum)
+static int usb_hub_check(struct usb_device *dev, int ifnum)
 {
 	struct usb_interface *iface;
-	struct usb_endpoint_descriptor *ep;
-	int ret;
+	struct usb_endpoint_descriptor *ep = NULL;
 
 	iface = &dev->config.if_desc[ifnum];
 	/* Is it a hub? */
 	if (iface->desc.bInterfaceClass != USB_CLASS_HUB)
-		return 0;
+		goto err;
 	/* Some hubs have a subclass of 1, which AFAICT according to the */
 	/*  specs is not defined, but it works */
 	if ((iface->desc.bInterfaceSubClass != 0) &&
 	    (iface->desc.bInterfaceSubClass != 1))
-		return 0;
+		goto err;
 	/* Multiple endpoints? What kind of mutant ninja-hub is this? */
 	if (iface->desc.bNumEndpoints != 1)
-		return 0;
+		goto err;
 	ep = &iface->ep_desc[0];
 	/* Output endpoint? Curiousier and curiousier.. */
 	if (!(ep->bEndpointAddress & USB_DIR_IN))
-		return 0;
+		goto err;
 	/* If it's not an interrupt endpoint, we'd better punt! */
 	if ((ep->bmAttributes & 3) != 3)
-		return 0;
+		goto err;
 	/* We found a hub */
 	debug("USB hub found\n");
+	return 0;
+
+err:
+	debug("USB hub not found: bInterfaceClass=%d, bInterfaceSubClass=%d, bNumEndpoints=%d\n",
+	      iface->desc.bInterfaceClass, iface->desc.bInterfaceSubClass,
+	      iface->desc.bNumEndpoints);
+	if (ep) {
+		debug("   bEndpointAddress=%#x, bmAttributes=%d",
+		      ep->bEndpointAddress, ep->bmAttributes);
+	}
+
+	return -ENOENT;
+}
+
+int usb_hub_probe(struct usb_device *dev, int ifnum)
+{
+	int ret;
+
+	ret = usb_hub_check(dev, ifnum);
+	if (ret)
+		return 0;
 	ret = usb_hub_configure(dev);
 	return ret;
 }
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 22/80] dm: usb: Add driver model support for hubs
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (20 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 21/80] dm: usb: Split hub detection into its own function Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:41   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 23/80] dm: usb: Move USB storage definitions to usb_defs.h Simon Glass
                   ` (58 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

Adjust the existing hub code to support driver model, and add a USB driver
for hubs.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 common/usb_hub.c       | 94 +++++++++++++++++++++++++++++++++++++++++++++++---
 include/dm/uclass-id.h |  1 +
 2 files changed, 91 insertions(+), 4 deletions(-)

diff --git a/common/usb_hub.c b/common/usb_hub.c
index cc22f4b..6933015 100644
--- a/common/usb_hub.c
+++ b/common/usb_hub.c
@@ -24,12 +24,16 @@
 
 #include <common.h>
 #include <command.h>
+#include <dm.h>
 #include <errno.h>
 #include <asm/processor.h>
 #include <asm/unaligned.h>
 #include <linux/ctype.h>
 #include <asm/byteorder.h>
 #include <asm/unaligned.h>
+#include <dm/root.h>
+
+DECLARE_GLOBAL_DATA_PTR;
 
 #include <usb.h>
 #ifdef CONFIG_4xx
@@ -38,6 +42,7 @@
 
 #define USB_BUFSIZ	512
 
+/* TODO(sjg at chromium.org): Remove this when CONFIG_DM_USB is defined */
 static struct usb_hub_device hub_dev[USB_MAX_HUB];
 static int usb_hub_index;
 
@@ -148,7 +153,12 @@ int legacy_hub_port_reset(struct usb_device *dev, int port,
 	ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
 	unsigned short portstatus, portchange;
 
-	debug("hub_port_reset: resetting port %d...\n", port);
+#ifdef CONFIG_DM_USB
+	debug("%s: resetting '%s' port %d...\n", __func__, dev->dev->name,
+	      port + 1);
+#else
+	debug("%s: resetting port %d...\n", __func__, port + 1);
+#endif
 	for (tries = 0; tries < MAX_TRIES; tries++) {
 
 		usb_set_port_feature(dev, port + 1, USB_PORT_FEAT_RESET);
@@ -206,10 +216,17 @@ int legacy_hub_port_reset(struct usb_device *dev, int port,
 	return 0;
 }
 
+#ifdef CONFIG_DM_USB
+int hub_port_reset(struct udevice *dev, int port, unsigned short *portstat)
+{
+	struct usb_device *udev = dev_get_parentdata(dev);
+
+	return legacy_hub_port_reset(udev, port, portstat);
+}
+#endif
 
 int usb_hub_port_connect_change(struct usb_device *dev, int port)
 {
-	struct usb_device *usb;
 	ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
 	unsigned short portstatus;
 	int ret, speed;
@@ -232,7 +249,8 @@ int usb_hub_port_connect_change(struct usb_device *dev, int port)
 
 	/* Disconnect any existing devices under this port */
 	if (((!(portstatus & USB_PORT_STAT_CONNECTION)) &&
-	     (!(portstatus & USB_PORT_STAT_ENABLE))) || (dev->children[port])) {
+	     (!(portstatus & USB_PORT_STAT_ENABLE))) ||
+	    usb_device_has_child_on_port(dev, port)) {
 		debug("usb_disconnect(&hub->children[port]);\n");
 		/* Return now if nothing is connected */
 		if (!(portstatus & USB_PORT_STAT_CONNECTION))
@@ -264,6 +282,13 @@ int usb_hub_port_connect_change(struct usb_device *dev, int port)
 		break;
 	}
 
+#ifdef CONFIG_DM_USB
+	struct udevice *child;
+
+	ret = usb_scan_device(dev->dev, port + 1, speed, &child);
+#else
+	struct usb_device *usb;
+
 	ret = usb_alloc_new_device(dev->controller, &usb);
 	if (ret) {
 		printf("cannot create new device: ret=%d", ret);
@@ -280,6 +305,9 @@ int usb_hub_port_connect_change(struct usb_device *dev, int port)
 		/* Woops, disable the port */
 		usb_free_device(dev->controller);
 		dev->children[port] = NULL;
+	}
+#endif
+	if (ret < 0) {
 		debug("hub: disabling port %d\n", port + 1);
 		usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_ENABLE);
 	}
@@ -427,7 +455,11 @@ static int usb_hub_configure(struct usb_device *dev)
 		int ret;
 		ulong start = get_timer(0);
 
+#ifdef CONFIG_DM_USB
+		debug("\n\nScanning '%s' port %d\n", dev->dev->name, i + 1);
+#else
 		debug("\n\nScanning port %d\n", i + 1);
+#endif
 		/*
 		 * Wait for (whichever finishes first)
 		 *  - A maximum of 10 seconds
@@ -477,7 +509,7 @@ static int usb_hub_configure(struct usb_device *dev)
 			 * them again. Works at least with mouse driver */
 			if (!(portstatus & USB_PORT_STAT_ENABLE) &&
 			     (portstatus & USB_PORT_STAT_CONNECTION) &&
-			     ((dev->children[i]))) {
+			     usb_device_has_child_on_port(dev, i)) {
 				debug("already running port %i "  \
 				      "disabled by hub (EMI?), " \
 				      "re-enabling...\n", i + 1);
@@ -558,3 +590,57 @@ int usb_hub_probe(struct usb_device *dev, int ifnum)
 	ret = usb_hub_configure(dev);
 	return ret;
 }
+
+#ifdef CONFIG_DM_USB
+int usb_hub_scan(struct udevice *hub)
+{
+	struct usb_device *udev = dev_get_parentdata(hub);
+
+	return usb_hub_configure(udev);
+}
+
+static int usb_hub_post_bind(struct udevice *dev)
+{
+	/* Scan the bus for devices */
+	return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
+}
+
+static int usb_hub_post_probe(struct udevice *dev)
+{
+	debug("%s\n", __func__);
+	return usb_hub_scan(dev);
+}
+
+static const struct udevice_id usb_hub_ids[] = {
+	{ .compatible = "usb-hub" },
+	{ }
+};
+
+U_BOOT_DRIVER(usb_generic_hub) = {
+	.name	= "usb_hub",
+	.id	= UCLASS_USB_HUB,
+	.of_match = usb_hub_ids,
+	.flags	= DM_FLAG_ALLOC_PRIV_DMA,
+};
+
+UCLASS_DRIVER(usb_hub) = {
+	.id		= UCLASS_USB_HUB,
+	.name		= "usb_hub",
+	.post_bind	= usb_hub_post_bind,
+	.post_probe	= usb_hub_post_probe,
+	.child_pre_probe	= usb_child_pre_probe,
+	.per_child_auto_alloc_size = sizeof(struct usb_device),
+	.per_child_platdata_auto_alloc_size = sizeof(struct usb_dev_platdata),
+};
+
+static const struct usb_device_id hub_id_table[] = {
+	{
+		.match_flags = USB_DEVICE_ID_MATCH_DEV_CLASS,
+		.bDeviceClass = USB_CLASS_HUB
+	},
+	{ }	/* Terminating entry */
+};
+
+USB_DEVICE(usb_generic_hub, hub_id_table);
+
+#endif
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index cb6d2e5..acec938 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -40,6 +40,7 @@ enum uclass_id {
 	UCLASS_PCH,		/* x86 platform controller hub */
 	UCLASS_ETH,		/* Ethernet device */
 	UCLASS_USB,		/* USB bus */
+	UCLASS_USB_HUB,		/* USB hub */
 
 	UCLASS_COUNT,
 	UCLASS_INVALID = -1,
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 23/80] dm: usb: Move USB storage definitions to usb_defs.h
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (21 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 22/80] dm: usb: Add driver model support for hubs Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:42   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 24/80] dm: usb: Fix type problems in usb_stor_get_info() Simon Glass
                   ` (57 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

These are better off in a header file so they can be used by other code (e.g.
the sandbox USB storage emulator).

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 common/usb_storage.c | 45 ++-------------------------------------------
 include/usb_defs.h   | 42 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+), 43 deletions(-)

diff --git a/common/usb_storage.c b/common/usb_storage.c
index 1411737..590408a 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -56,49 +56,8 @@ static const unsigned char us_direction[256/8] = {
 #define US_DIRECTION(x) ((us_direction[x>>3] >> (x & 7)) & 1)
 
 static ccb usb_ccb __attribute__((aligned(ARCH_DMA_MINALIGN)));
-
-/*
- * CBI style
- */
-
-#define US_CBI_ADSC		0
-
-/*
- * BULK only
- */
-#define US_BBB_RESET		0xff
-#define US_BBB_GET_MAX_LUN	0xfe
-
-/* Command Block Wrapper */
-typedef struct {
-	__u32		dCBWSignature;
-#	define CBWSIGNATURE	0x43425355
-	__u32		dCBWTag;
-	__u32		dCBWDataTransferLength;
-	__u8		bCBWFlags;
-#	define CBWFLAGS_OUT	0x00
-#	define CBWFLAGS_IN	0x80
-	__u8		bCBWLUN;
-	__u8		bCDBLength;
-#	define CBWCDBLENGTH	16
-	__u8		CBWCDB[CBWCDBLENGTH];
-} umass_bbb_cbw_t;
-#define UMASS_BBB_CBW_SIZE	31
 static __u32 CBWTag;
 
-/* Command Status Wrapper */
-typedef struct {
-	__u32		dCSWSignature;
-#	define CSWSIGNATURE	0x53425355
-	__u32		dCSWTag;
-	__u32		dCSWDataResidue;
-	__u8		bCSWStatus;
-#	define CSWSTATUS_GOOD	0x0
-#	define CSWSTATUS_FAILED 0x1
-#	define CSWSTATUS_PHASE	0x2
-} umass_bbb_csw_t;
-#define UMASS_BBB_CSW_SIZE	13
-
 #define USB_MAX_STOR_DEV 5
 static int usb_max_devs; /* number of highest available usb device */
 
@@ -483,7 +442,7 @@ static int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
 	int actlen;
 	int dir_in;
 	unsigned int pipe;
-	ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_cbw_t, cbw, 1);
+	ALLOC_CACHE_ALIGN_BUFFER(struct umass_bbb_cbw, cbw, 1);
 
 	dir_in = US_DIRECTION(srb->cmd[0]);
 
@@ -658,7 +617,7 @@ static int usb_stor_BBB_transport(ccb *srb, struct us_data *us)
 	int dir_in;
 	int actlen, data_actlen;
 	unsigned int pipe, pipein, pipeout;
-	ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_csw_t, csw, 1);
+	ALLOC_CACHE_ALIGN_BUFFER(struct umass_bbb_csw, csw, 1);
 #ifdef BBB_XPORT_TRACE
 	unsigned char *ptr;
 	int index;
diff --git a/include/usb_defs.h b/include/usb_defs.h
index 236a5ec..d7f7465 100644
--- a/include/usb_defs.h
+++ b/include/usb_defs.h
@@ -286,4 +286,46 @@
 #define HUB_CHANGE_LOCAL_POWER	0x0001
 #define HUB_CHANGE_OVERCURRENT	0x0002
 
+/*
+ * CBI style
+ */
+
+#define US_CBI_ADSC		0
+
+/* Command Block Wrapper */
+struct umass_bbb_cbw {
+	__u32		dCBWSignature;
+#	define CBWSIGNATURE	0x43425355
+	__u32		dCBWTag;
+	__u32		dCBWDataTransferLength;
+	__u8		bCBWFlags;
+#	define CBWFLAGS_OUT	0x00
+#	define CBWFLAGS_IN	0x80
+#	define CBWFLAGS_SBZ	0x7f
+	__u8		bCBWLUN;
+	__u8		bCDBLength;
+#	define CBWCDBLENGTH	16
+	__u8		CBWCDB[CBWCDBLENGTH];
+};
+#define UMASS_BBB_CBW_SIZE	31
+
+/* Command Status Wrapper */
+struct umass_bbb_csw {
+	__u32		dCSWSignature;
+#	define CSWSIGNATURE	0x53425355
+	__u32		dCSWTag;
+	__u32		dCSWDataResidue;
+	__u8		bCSWStatus;
+#	define CSWSTATUS_GOOD	0x0
+#	define CSWSTATUS_FAILED 0x1
+#	define CSWSTATUS_PHASE	0x2
+};
+#define UMASS_BBB_CSW_SIZE	13
+
+/*
+ * BULK only
+ */
+#define US_BBB_RESET		0xff
+#define US_BBB_GET_MAX_LUN	0xfe
+
 #endif /*_USB_DEFS_H_ */
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 24/80] dm: usb: Fix type problems in usb_stor_get_info()
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (22 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 23/80] dm: usb: Move USB storage definitions to usb_defs.h Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:42   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 25/80] dm: usb: Simply device finding code in usb_storage Simon Glass
                   ` (56 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

This function assumes that unsigned long is 32-bits wide, but it is not
on 64-bit machines. Use the correct type, and add a few debug() lines also.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 common/usb_storage.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/common/usb_storage.c b/common/usb_storage.c
index 590408a..80ed14a 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -1178,6 +1178,7 @@ int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,
 			iface->desc.bInterfaceClass != USB_CLASS_MASS_STORAGE ||
 			iface->desc.bInterfaceSubClass < US_SC_MIN ||
 			iface->desc.bInterfaceSubClass > US_SC_MAX) {
+		debug("Not mass storage\n");
 		/* if it's not a mass storage, we go no further */
 		return 0;
 	}
@@ -1293,9 +1294,9 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
 		      block_dev_desc_t *dev_desc)
 {
 	unsigned char perq, modi;
-	ALLOC_CACHE_ALIGN_BUFFER(unsigned long, cap, 2);
+	ALLOC_CACHE_ALIGN_BUFFER(uint32_t, cap, 2);
 	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, usb_stor_buf, 36);
-	unsigned long *capacity, *blksz;
+	uint32_t *capacity, *blksz;
 	ccb *pccb = &usb_ccb;
 
 	pccb->pdata = usb_stor_buf;
@@ -1304,8 +1305,10 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
 	pccb->lun = dev_desc->lun;
 	debug(" address %d\n", dev_desc->target);
 
-	if (usb_inquiry(pccb, ss))
+	if (usb_inquiry(pccb, ss)) {
+		debug("%s: usb_inquiry() failed\n", __func__);
 		return -1;
+	}
 
 	perq = usb_stor_buf[0];
 	modi = usb_stor_buf[1];
@@ -1315,6 +1318,7 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
 	 * they would not respond to test_unit_ready .
 	 */
 	if (((perq & 0x1f) == 0x1f) || ((perq & 0x1f) == 0x0d)) {
+		debug("%s: unknown/unsupported device\n", __func__);
 		return 0;
 	}
 	if ((modi&0x80) == 0x80) {
@@ -1352,19 +1356,19 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
 		cap[1] = 0x200;
 	}
 	ss->flags &= ~USB_READY;
-	debug("Read Capacity returns: 0x%lx, 0x%lx\n", cap[0], cap[1]);
+	debug("Read Capacity returns: 0x%x, 0x%x\n", cap[0], cap[1]);
 #if 0
 	if (cap[0] > (0x200000 * 10)) /* greater than 10 GByte */
 		cap[0] >>= 16;
 #endif
-	cap[0] = cpu_to_be32(cap[0]);
-	cap[1] = cpu_to_be32(cap[1]);
+	cap[0] = be32_to_cpu(cap[0]);
+	cap[1] = be32_to_cpu(cap[1]);
 
 	/* this assumes bigendian! */
 	cap[0] += 1;
 	capacity = &cap[0];
 	blksz = &cap[1];
-	debug("Capacity = 0x%lx, blocksz = 0x%lx\n", *capacity, *blksz);
+	debug("Capacity = 0x%x, blocksz = 0x%x\n", *capacity, *blksz);
 	dev_desc->lba = *capacity;
 	dev_desc->blksz = *blksz;
 	dev_desc->log2blksz = LOG2(dev_desc->blksz);
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 25/80] dm: usb: Simply device finding code in usb_storage
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (23 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 24/80] dm: usb: Fix type problems in usb_stor_get_info() Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:42   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 26/80] dm: usb: Adjust usb_storage to work with sandbox Simon Glass
                   ` (55 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

The for() loop is not needed since the value is immediately accessible.
Use this instead to simplify the code.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 common/usb_storage.c | 30 +++++++++++-------------------
 1 file changed, 11 insertions(+), 19 deletions(-)

diff --git a/common/usb_storage.c b/common/usb_storage.c
index 80ed14a..64d01ea 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -1005,7 +1005,7 @@ unsigned long usb_stor_read(int device, lbaint_t blknr,
 	unsigned short smallblks;
 	struct usb_device *dev;
 	struct us_data *ss;
-	int retry, i;
+	int retry;
 	ccb *srb = &usb_ccb;
 
 	if (blkcnt == 0)
@@ -1013,14 +1013,11 @@ unsigned long usb_stor_read(int device, lbaint_t blknr,
 
 	device &= 0xff;
 	/* Setup  device */
-	debug("\nusb_read: dev %d \n", device);
-	dev = NULL;
-	for (i = 0; i < USB_MAX_DEVICE; i++) {
-		dev = usb_get_dev_index(i);
-		if (dev == NULL)
-			return 0;
-		if (dev->devnum == usb_dev_desc[device].target)
-			break;
+	debug("\nusb_read: dev %d\n", device);
+	dev = usb_dev_desc[device].priv;
+	if (!dev) {
+		debug("%s: No device\n", __func__);
+		return 0;
 	}
 	ss = (struct us_data *)dev->privptr;
 
@@ -1078,7 +1075,7 @@ unsigned long usb_stor_write(int device, lbaint_t blknr,
 	unsigned short smallblks;
 	struct usb_device *dev;
 	struct us_data *ss;
-	int retry, i;
+	int retry;
 	ccb *srb = &usb_ccb;
 
 	if (blkcnt == 0)
@@ -1086,15 +1083,10 @@ unsigned long usb_stor_write(int device, lbaint_t blknr,
 
 	device &= 0xff;
 	/* Setup  device */
-	debug("\nusb_write: dev %d \n", device);
-	dev = NULL;
-	for (i = 0; i < USB_MAX_DEVICE; i++) {
-		dev = usb_get_dev_index(i);
-		if (dev == NULL)
-			return 0;
-		if (dev->devnum == usb_dev_desc[device].target)
-			break;
-	}
+	debug("\nusb_write: dev %d\n", device);
+	dev = usb_dev_desc[device].priv;
+	if (!dev)
+		return 0;
 	ss = (struct us_data *)dev->privptr;
 
 	usb_disable_asynch(1); /* asynch transfer not allowed */
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 26/80] dm: usb: Adjust usb_storage to work with sandbox
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (24 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 25/80] dm: usb: Simply device finding code in usb_storage Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:42   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 27/80] dm: usb: Move storage device scanning into its own function Simon Glass
                   ` (54 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

With a few tweaks we can compile this code with sandbox and enable testing
of the USB storage layer.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 common/usb_storage.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/common/usb_storage.c b/common/usb_storage.c
index 64d01ea..acea5ae 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -34,6 +34,7 @@
 #include <common.h>
 #include <command.h>
 #include <inttypes.h>
+#include <mapmem.h>
 #include <asm/byteorder.h>
 #include <asm/processor.h>
 
@@ -295,8 +296,9 @@ static int us_one_transfer(struct us_data *us, int pipe, char *buf, int length)
 		/* set up the transfer loop */
 		do {
 			/* transfer the data */
-			debug("Bulk xfer 0x%x(%d) try #%d\n",
-			      (unsigned int)buf, this_xfer, 11 - maxtry);
+			debug("Bulk xfer 0x%lx(%d) try #%d\n",
+			      (ulong)map_to_sysmem(buf), this_xfer,
+			      11 - maxtry);
 			result = usb_bulk_msg(us->pusb_dev, pipe, buf,
 					      this_xfer, &partial,
 					      USB_CNTL_TIMEOUT * 5);
@@ -562,7 +564,7 @@ static int usb_stor_CBI_get_status(ccb *srb, struct us_data *us)
 			(void *) &us->ip_data, us->irqmaxp, us->irqinterval);
 	timeout = 1000;
 	while (timeout--) {
-		if ((volatile int *) us->ip_wanted == NULL)
+		if (*(volatile int *)&us->ip_wanted == 0)
 			break;
 		mdelay(10);
 	}
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 27/80] dm: usb: Move storage device scanning into its own function
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (25 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 26/80] dm: usb: Adjust usb_storage to work with sandbox Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:43   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 28/80] dm: usb: Convert usb_storage to driver model Simon Glass
                   ` (53 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

The usb_stor_scan() function is quite long, so split out the code that scans
each device into its own function. Also, rather than setting up the block
device list once at the start, set it up as each device is scanned. This
makes it possible to use this code from driver model.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 common/usb_storage.c | 97 ++++++++++++++++++++++++++++++++--------------------
 1 file changed, 59 insertions(+), 38 deletions(-)

diff --git a/common/usb_storage.c b/common/usb_storage.c
index acea5ae..67494b7 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -33,6 +33,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <errno.h>
 #include <inttypes.h>
 #include <mapmem.h>
 #include <asm/byteorder.h>
@@ -168,6 +169,60 @@ static unsigned int usb_get_max_lun(struct us_data *us)
 	return (len > 0) ? *result : 0;
 }
 
+static int usb_stor_probe_device(struct usb_device *dev)
+{
+	if (dev == NULL)
+		return -ENOENT; /* no more devices available */
+
+	debug("\n\nProbing for storage\n");
+	if (usb_storage_probe(dev, 0, &usb_stor[usb_max_devs])) {
+		/* OK, it's a storage device.  Iterate over its LUNs
+			* and populate `usb_dev_desc'.
+			*/
+		int lun, max_lun, start = usb_max_devs;
+
+		max_lun = usb_get_max_lun(&usb_stor[usb_max_devs]);
+		for (lun = 0;
+			lun <= max_lun && usb_max_devs < USB_MAX_STOR_DEV;
+			lun++) {
+			struct block_dev_desc *blkdev;
+
+			blkdev = &usb_dev_desc[usb_max_devs];
+			memset(blkdev, '\0', sizeof(block_dev_desc_t));
+			blkdev->if_type = IF_TYPE_USB;
+			blkdev->dev = usb_max_devs;
+			blkdev->part_type = PART_TYPE_UNKNOWN;
+			blkdev->target = 0xff;
+			blkdev->type = DEV_TYPE_UNKNOWN;
+			blkdev->block_read = usb_stor_read;
+			blkdev->block_write = usb_stor_write;
+			blkdev->lun = lun;
+			blkdev->priv = dev;
+
+			if (usb_stor_get_info(dev, &usb_stor[start],
+					      &usb_dev_desc[usb_max_devs]) ==
+					      1) {
+				usb_max_devs++;
+				debug("%s: Found device %p\n", __func__, dev);
+			}
+		}
+	}
+
+	/* if storage device */
+	if (usb_max_devs == USB_MAX_STOR_DEV) {
+		printf("max USB Storage Device reached: %d stopping\n",
+		       usb_max_devs);
+		return -ENOSPC;
+	}
+
+	return 0;
+}
+
+void usb_stor_reset(void)
+{
+	usb_max_devs = 0;
+}
+
 /*******************************************************************************
  * scan the usb and reports device info
  * to the user if mode = 1
@@ -176,54 +231,20 @@ static unsigned int usb_get_max_lun(struct us_data *us)
 int usb_stor_scan(int mode)
 {
 	unsigned char i;
-	struct usb_device *dev;
 
 	if (mode == 1)
 		printf("       scanning usb for storage devices... ");
 
 	usb_disable_asynch(1); /* asynch transfer not allowed */
 
-	for (i = 0; i < USB_MAX_STOR_DEV; i++) {
-		memset(&usb_dev_desc[i], 0, sizeof(block_dev_desc_t));
-		usb_dev_desc[i].if_type = IF_TYPE_USB;
-		usb_dev_desc[i].dev = i;
-		usb_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
-		usb_dev_desc[i].target = 0xff;
-		usb_dev_desc[i].type = DEV_TYPE_UNKNOWN;
-		usb_dev_desc[i].block_read = usb_stor_read;
-		usb_dev_desc[i].block_write = usb_stor_write;
-	}
-
-	usb_max_devs = 0;
+	usb_stor_reset();
 	for (i = 0; i < USB_MAX_DEVICE; i++) {
+		struct usb_device *dev;
+
 		dev = usb_get_dev_index(i); /* get device */
 		debug("i=%d\n", i);
-		if (dev == NULL)
-			break; /* no more devices available */
-
-		if (usb_storage_probe(dev, 0, &usb_stor[usb_max_devs])) {
-			/* OK, it's a storage device.  Iterate over its LUNs
-			 * and populate `usb_dev_desc'.
-			 */
-			int lun, max_lun, start = usb_max_devs;
-
-			max_lun = usb_get_max_lun(&usb_stor[usb_max_devs]);
-			for (lun = 0;
-			     lun <= max_lun && usb_max_devs < USB_MAX_STOR_DEV;
-			     lun++) {
-				usb_dev_desc[usb_max_devs].lun = lun;
-				if (usb_stor_get_info(dev, &usb_stor[start],
-				    &usb_dev_desc[usb_max_devs]) == 1) {
-					usb_max_devs++;
-				}
-			}
-		}
-		/* if storage device */
-		if (usb_max_devs == USB_MAX_STOR_DEV) {
-			printf("max USB Storage Device reached: %d stopping\n",
-				usb_max_devs);
+		if (usb_stor_probe_device(dev))
 			break;
-		}
 	} /* for */
 
 	usb_disable_asynch(0); /* asynch transfer allowed */
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 28/80] dm: usb: Convert usb_storage to driver model
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (26 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 27/80] dm: usb: Move storage device scanning into its own function Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:43   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 29/80] dm: usb: Move all the EHCI weak functions together and declare them Simon Glass
                   ` (52 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

Add support for scanning USB storage devices with driver model. This mostly
involves adding a USB device ID for storage devices.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 common/usb_storage.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 49 insertions(+), 2 deletions(-)

diff --git a/common/usb_storage.c b/common/usb_storage.c
index 67494b7..8b8962e 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -9,6 +9,8 @@
  *
  * Adapted for U-Boot:
  *   (C) Copyright 2001 Denis Peter, MPL AG Switzerland
+ * Driver model conversion:
+ *   (C) Copyright 2015 Google, Inc
  *
  * For BBB support (C) Copyright 2003
  * Gary Jennejohn, DENX Software Engineering <garyj@denx.de>
@@ -33,11 +35,13 @@
 
 #include <common.h>
 #include <command.h>
+#include <dm.h>
 #include <errno.h>
 #include <inttypes.h>
 #include <mapmem.h>
 #include <asm/byteorder.h>
 #include <asm/processor.h>
+#include <dm/device-internal.h>
 
 #include <part.h>
 #include <usb.h>
@@ -106,7 +110,6 @@ struct us_data {
 
 static struct us_data usb_stor[USB_MAX_STOR_DEV];
 
-
 #define USB_STOR_TRANSPORT_GOOD	   0
 #define USB_STOR_TRANSPORT_FAILED -1
 #define USB_STOR_TRANSPORT_ERROR  -2
@@ -119,7 +122,6 @@ unsigned long usb_stor_read(int device, lbaint_t blknr,
 			    lbaint_t blkcnt, void *buffer);
 unsigned long usb_stor_write(int device, lbaint_t blknr,
 			     lbaint_t blkcnt, const void *buffer);
-struct usb_device * usb_get_dev_index(int index);
 void uhci_show_temp_int_td(void);
 
 #ifdef CONFIG_PARTITIONS
@@ -223,6 +225,7 @@ void usb_stor_reset(void)
 	usb_max_devs = 0;
 }
 
+#ifndef CONFIG_DM_USB
 /*******************************************************************************
  * scan the usb and reports device info
  * to the user if mode = 1
@@ -253,6 +256,7 @@ int usb_stor_scan(int mode)
 		return 0;
 	return -1;
 }
+#endif
 
 static int usb_stor_irq(struct usb_device *dev)
 {
@@ -1396,3 +1400,46 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
 	debug("partype: %d\n", dev_desc->part_type);
 	return 1;
 }
+
+#ifdef CONFIG_DM_USB
+
+static int usb_mass_storage_probe(struct udevice *dev)
+{
+	struct usb_device *udev = dev_get_parentdata(dev);
+	int ret;
+
+	usb_disable_asynch(1); /* asynch transfer not allowed */
+	ret = usb_stor_probe_device(udev);
+	usb_disable_asynch(0); /* asynch transfer allowed */
+
+	return ret;
+}
+
+static const struct udevice_id usb_mass_storage_ids[] = {
+	{ .compatible = "usb-mass-storage" },
+	{ }
+};
+
+U_BOOT_DRIVER(usb_mass_storage) = {
+	.name	= "usb_mass_storage",
+	.id	= UCLASS_MASS_STORAGE,
+	.of_match = usb_mass_storage_ids,
+	.probe = usb_mass_storage_probe,
+};
+
+UCLASS_DRIVER(usb_mass_storage) = {
+	.id		= UCLASS_MASS_STORAGE,
+	.name		= "usb_mass_storage",
+};
+
+static const struct usb_device_id mass_storage_id_table[] = {
+	{
+		.match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
+		.bInterfaceClass = USB_CLASS_MASS_STORAGE
+	},
+	{ }		/* Terminating entry */
+};
+
+USB_DEVICE(usb_mass_storage, mass_storage_id_table);
+
+#endif
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 29/80] dm: usb: Move all the EHCI weak functions together and declare them
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (27 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 28/80] dm: usb: Convert usb_storage to driver model Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:43   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 30/80] dm: usb: Pass EHCI controller pointer to ehci_get_port_speed() Simon Glass
                   ` (51 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

Put these at the top of the file so they are in one place. Also add function
prototypes to the header file to avoid call site mismatches.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/host/ehci-hcd.c | 22 +++++++++++-----------
 drivers/usb/host/ehci.h     |  6 ++++++
 2 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index f1fb190..10a0671 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -143,6 +143,17 @@ __weak void ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg)
 	mdelay(50);
 }
 
+__weak uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port)
+{
+	if (port < 0 || port >= CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
+		/* Printing the message would cause a scan failure! */
+		debug("The request port(%u) is not configured\n", port);
+		return NULL;
+	}
+
+	return (uint32_t *)&hcor->or_portsc[port];
+}
+
 static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int usec)
 {
 	uint32_t result;
@@ -649,17 +660,6 @@ fail:
 	return -1;
 }
 
-__weak uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port)
-{
-	if (port < 0 || port >= CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
-		/* Printing the message would cause a scan failure! */
-		debug("The request port(%u) is not configured\n", port);
-		return NULL;
-	}
-
-	return (uint32_t *)&hcor->or_portsc[port];
-}
-
 int
 ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 		 int length, struct devrequest *req)
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 79aecd4..3e5427a 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -250,6 +250,12 @@ struct ehci_ctrl {
 	int ntds;
 };
 
+/* Weak functions that drivers can override */
+int ehci_get_port_speed(struct ehci_hcor *hcor, uint32_t reg);
+void ehci_set_usbmode(int index);
+void ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg);
+uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port);
+
 /* Low level init functions */
 int ehci_hcd_init(int index, enum usb_init_type init,
 		struct ehci_hccr **hccr, struct ehci_hcor **hcor);
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 30/80] dm: usb: Pass EHCI controller pointer to ehci_get_port_speed()
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (28 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 29/80] dm: usb: Move all the EHCI weak functions together and declare them Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:43   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 31/80] dm: usb: Allow ECHI to hold private data for the controller Simon Glass
                   ` (50 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

Adjust this function so that it is passed an EHCI controller pointer so that
implementations can look up their controller.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/host/ehci-faraday.c | 5 +++--
 drivers/usb/host/ehci-hcd.c     | 4 ++--
 drivers/usb/host/ehci-tegra.c   | 5 +++--
 drivers/usb/host/ehci.h         | 2 +-
 4 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/host/ehci-faraday.c b/drivers/usb/host/ehci-faraday.c
index 3b761bc..e386813 100644
--- a/drivers/usb/host/ehci-faraday.c
+++ b/drivers/usb/host/ehci-faraday.c
@@ -101,11 +101,12 @@ void ehci_set_usbmode(int index)
  * This ehci_get_port_speed() overrides the weak function
  * in "ehci-hcd.c".
  */
-int ehci_get_port_speed(struct ehci_hcor *hcor, uint32_t reg)
+int ehci_get_port_speed(struct ehci_ctrl *ctrl, uint32_t reg)
 {
 	int spd, ret = PORTSC_PSPD_HS;
-	union ehci_faraday_regs *regs = (void __iomem *)((ulong)hcor - 0x10);
+	union ehci_faraday_regs *regs;
 
+	ret = (void __iomem *)((ulong)ctrl->hcor - 0x10);
 	if (ehci_is_fotg2xx(regs))
 		spd = OTGCSR_SPD(readl(&regs->otg.otgcsr));
 	else
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 10a0671..fed3942 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -119,7 +119,7 @@ static struct descriptor {
 #define ehci_is_TDI()	(0)
 #endif
 
-__weak int ehci_get_port_speed(struct ehci_hcor *hcor, uint32_t reg)
+__weak int ehci_get_port_speed(struct ehci_ctrl *ctrl, uint32_t reg)
 {
 	return PORTSC_PSPD(reg);
 }
@@ -781,7 +781,7 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 			tmpbuf[1] |= USB_PORT_STAT_POWER >> 8;
 
 		if (ehci_is_TDI()) {
-			switch (ehci_get_port_speed(ctrl->hcor, reg)) {
+			switch (ehci_get_port_speed(ctrl, reg)) {
 			case PORTSC_PSPD_FS:
 				break;
 			case PORTSC_PSPD_LS:
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index b5ad1e3..0831fe9 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -225,13 +225,14 @@ void ehci_set_usbmode(int index)
  * This ehci_get_port_speed overrides the weak function ehci_get_port_speed
  * in "ehci-hcd.c".
  */
-int ehci_get_port_speed(struct ehci_hcor *hcor, uint32_t reg)
+int ehci_get_port_speed(struct ehci_ctrl *ctrl, uint32_t reg)
 {
 	uint32_t tmp;
 	uint32_t *reg_ptr;
 
 	if (controller->has_hostpc) {
-		reg_ptr = (uint32_t *)((u8 *)&hcor->or_usbcmd + HOSTPC1_DEVLC);
+		reg_ptr = (uint32_t *)((u8 *)&ctrl->hcor->or_usbcmd +
+				HOSTPC1_DEVLC);
 		tmp = ehci_readl(reg_ptr);
 		return HOSTPC1_PSPD(tmp);
 	} else
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 3e5427a..ec4d6b0 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -251,7 +251,7 @@ struct ehci_ctrl {
 };
 
 /* Weak functions that drivers can override */
-int ehci_get_port_speed(struct ehci_hcor *hcor, uint32_t reg);
+int ehci_get_port_speed(struct ehci_ctrl *ctrl, uint32_t reg);
 void ehci_set_usbmode(int index);
 void ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg);
 uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port);
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 31/80] dm: usb: Allow ECHI to hold private data for the controller
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (29 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 30/80] dm: usb: Pass EHCI controller pointer to ehci_get_port_speed() Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:43   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 32/80] dm: usb: tegra: Store the controller type explicitly Simon Glass
                   ` (49 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

Add a private data pointer that clients of EHCI can use to access their
private information. This establishes a link between struct ehci_ctrl and
its associated controller data structure.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/host/ehci-hcd.c | 10 ++++++++++
 drivers/usb/host/ehci.h     | 21 +++++++++++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index fed3942..d85308f 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -930,6 +930,16 @@ unknown:
 	return -1;
 }
 
+void ehci_set_controller_priv(int index, void *priv)
+{
+	ehcic[index].priv = priv;
+}
+
+void *ehci_get_controller_priv(int index)
+{
+	return ehcic[index].priv;
+}
+
 int usb_lowlevel_stop(int index)
 {
 	ehci_shutdown(&ehcic[index]);
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index ec4d6b0..d538bb6 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -248,6 +248,7 @@ struct ehci_ctrl {
 	uint32_t *periodic_list;
 	int periodic_schedules;
 	int ntds;
+	void *priv;	/* client's private data */
 };
 
 /* Weak functions that drivers can override */
@@ -256,6 +257,26 @@ void ehci_set_usbmode(int index);
 void ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg);
 uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port);
 
+/**
+ * ehci_set_controller_priv() - Set up private data for the controller
+ *
+ * This function can be called in ehci_hcd_init() to tell the EHCI layer
+ * about the controller's private data pointer. Then in the above functions
+ * this can be accessed given the struct ehci_ctrl pointer.
+ *
+ * @index:	Controller number to set
+ * @priv:	Controller pointer
+ */
+void ehci_set_controller_priv(int index, void *priv);
+
+/**
+ * ehci_get_controller_priv() - Get controller private data
+ *
+ * @index	Controller number to get
+ * @return controller pointer for this index
+ */
+void *ehci_get_controller_priv(int index);
+
 /* Low level init functions */
 int ehci_hcd_init(int index, enum usb_init_type init,
 		struct ehci_hccr **hccr, struct ehci_hcor **hcor);
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 32/80] dm: usb: tegra: Store the controller type explicitly
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (30 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 31/80] dm: usb: Allow ECHI to hold private data for the controller Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:43   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 33/80] dm: usb: Pass EHCI controller pointer to ehci_powerup_fixup() Simon Glass
                   ` (48 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

At present the tegra driver uses a separate pointer to know which controller
type is in use. This works because only one controller type is used at a
time.

With driver model we want to make the controller state hermetic in the sense
that it is not necessary to look elsewhere to know the controller type. This
will permit a controller to implement the EHCI weak functions without
reference to global data structures.

To achieve this, define an enum for the controller type and store it with
the information on each EHCI controller.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/host/ehci-tegra.c | 30 ++++++++++++++++++++++++------
 1 file changed, 24 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 0831fe9..9a73e60 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -61,6 +61,14 @@ enum dr_mode {
 	DR_MODE_OTG,		/* supports both */
 };
 
+enum usb_ctlr_type {
+	USB_CTLR_T20,
+	USB_CTLR_T30,
+	USB_CTLR_T114,
+
+	USB_CTRL_COUNT,
+};
+
 /* Information about a USB port */
 struct fdt_usb {
 	struct usb_ctlr *reg;	/* address of registers in physical memory */
@@ -69,6 +77,7 @@ struct fdt_usb {
 	unsigned enabled:1;	/* 1 to enable, 0 to disable */
 	unsigned has_legacy_mode:1; /* 1 if this port has legacy mode */
 	unsigned initialized:1; /* has this port already been initialized? */
+	enum usb_ctlr_type type;
 	enum usb_init_type init_type;
 	enum dr_mode dr_mode;	/* dual role mode */
 	enum periph_id periph_id;/* peripheral id */
@@ -162,7 +171,7 @@ struct fdt_usb_controller {
 	const unsigned *pll_parameter;
 };
 
-static struct fdt_usb_controller fdt_usb_controllers[] = {
+static struct fdt_usb_controller fdt_usb_controllers[USB_CTRL_COUNT] = {
 	{
 		.compat		= COMPAT_NVIDIA_TEGRA20_USB,
 		.has_hostpc	= 0,
@@ -284,7 +293,7 @@ void usbf_reset_controller(struct fdt_usb *config, struct usb_ctlr *usbctlr)
 		setbits_le32(&usbctlr->susp_ctrl, UTMIP_PHY_ENB);
 }
 
-static const unsigned *get_pll_timing(void)
+static const unsigned *get_pll_timing(struct fdt_usb_controller *controller)
 {
 	const unsigned *timing;
 
@@ -331,6 +340,7 @@ static void init_phy_mux(struct fdt_usb *config, uint pts,
 static int init_utmi_usb_controller(struct fdt_usb *config,
 				    enum usb_init_type init)
 {
+	struct fdt_usb_controller *controller;
 	u32 b_sess_valid_mask, val;
 	int loop_count;
 	const unsigned *timing;
@@ -363,11 +373,14 @@ static int init_utmi_usb_controller(struct fdt_usb *config,
 			VBUS_SENSE_CTL_MASK,
 			VBUS_SENSE_CTL_A_SESS_VLD << VBUS_SENSE_CTL_SHIFT);
 
+	controller = &fdt_usb_controllers[config->type];
+	debug("controller=%p, type=%d\n", controller, config->type);
+
 	/*
 	 * PLL Delay CONFIGURATION settings. The following parameters control
 	 * the bring up of the plls.
 	 */
-	timing = get_pll_timing();
+	timing = get_pll_timing(controller);
 
 	if (!controller->has_hostpc) {
 		val = readl(&usbctlr->utmip_misc_cfg1);
@@ -702,10 +715,12 @@ static int fdt_decode_usb(const void *blob, int node, struct fdt_usb *config)
  * @blob:	fdt blob
  * @node_list:	list of nodes to process (any <=0 are ignored)
  * @count:	number of nodes to process
+ * @id:		controller type (enum usb_ctlr_type)
  *
  * Return:	0 - ok, -1 - error
  */
-static int process_usb_nodes(const void *blob, int node_list[], int count)
+static int process_usb_nodes(const void *blob, int node_list[], int count,
+			     enum usb_ctlr_type id)
 {
 	struct fdt_usb config;
 	int node, i;
@@ -729,9 +744,11 @@ static int process_usb_nodes(const void *blob, int node_list[], int count)
 			return -1;
 		}
 		if (!clk_done) {
-			config_clock(get_pll_timing());
+			config_clock(get_pll_timing(
+					&fdt_usb_controllers[id]));
 			clk_done = 1;
 		}
+		config.type = id;
 		config.initialized = 0;
 
 		/* add new USB port to the list of available ports */
@@ -753,7 +770,7 @@ int usb_process_devicetree(const void *blob)
 		count = fdtdec_find_aliases_for_id(blob, "usb",
 			controller->compat, node_list, USB_PORTS_MAX);
 		if (count) {
-			err = process_usb_nodes(blob, node_list, count);
+			err = process_usb_nodes(blob, node_list, count, i);
 			if (err)
 				printf("%s: Error processing USB node!\n",
 				       __func__);
@@ -786,6 +803,7 @@ int ehci_hcd_init(int index, enum usb_init_type init,
 		return -1;
 
 	config = &port[index];
+	ehci_set_controller_priv(index, config);
 
 	switch (init) {
 	case USB_INIT_HOST:
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 33/80] dm: usb: Pass EHCI controller pointer to ehci_powerup_fixup()
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (31 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 32/80] dm: usb: tegra: Store the controller type explicitly Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:43   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 34/80] dm: usb: tegra: Drop use of global controller variable Simon Glass
                   ` (47 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

Adjust this function so that it is passed an EHCI controller pointer so that
implementations can look up their controller.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 board/genesi/mx51_efikamx/efikamx-usb.c | 3 ++-
 drivers/usb/host/ehci-hcd.c             | 5 +++--
 drivers/usb/host/ehci-tegra.c           | 3 ++-
 drivers/usb/host/ehci.h                 | 3 ++-
 4 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/board/genesi/mx51_efikamx/efikamx-usb.c b/board/genesi/mx51_efikamx/efikamx-usb.c
index 0b43101..0c0b8d3 100644
--- a/board/genesi/mx51_efikamx/efikamx-usb.c
+++ b/board/genesi/mx51_efikamx/efikamx-usb.c
@@ -173,7 +173,8 @@ int board_ehci_hcd_init(int port)
 	return 0;
 }
 
-void ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg)
+void ehci_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg,
+			uint32_t *reg)
 {
 	uint32_t port = OTG_BASE_ADDR + (0x200 * CONFIG_MXC_USB_PORT);
 	struct usb_ehci *ehci = (struct usb_ehci *)port;
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index d85308f..e9f58e3 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -138,7 +138,8 @@ __weak void ehci_set_usbmode(int index)
 	ehci_writel(reg_ptr, tmp);
 }
 
-__weak void ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg)
+__weak void ehci_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg,
+			       uint32_t *reg)
 {
 	mdelay(50);
 }
@@ -843,7 +844,7 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 				 * usb 2.0 specification say 50 ms resets on
 				 * root
 				 */
-				ehci_powerup_fixup(status_reg, &reg);
+				ehci_powerup_fixup(ctrl, status_reg, &reg);
 
 				ehci_writel(status_reg, reg & ~EHCI_PS_PR);
 				/*
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 9a73e60..5d746f2 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -198,7 +198,8 @@ static struct fdt_usb_controller *controller;
  * This ehci_powerup_fixup overrides the weak function ehci_powerup_fixup
  * in "ehci-hcd.c".
  */
-void ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg)
+void ehci_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg,
+			uint32_t *reg)
 {
 	mdelay(50);
 	/* This is to avoid PORT_ENABLE bit to be cleared in "ehci-hcd.c". */
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index d538bb6..a00c7e7 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -254,7 +254,8 @@ struct ehci_ctrl {
 /* Weak functions that drivers can override */
 int ehci_get_port_speed(struct ehci_ctrl *ctrl, uint32_t reg);
 void ehci_set_usbmode(int index);
-void ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg);
+void ehci_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg,
+			uint32_t *reg);
 uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port);
 
 /**
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 34/80] dm: usb: tegra: Drop use of global controller variable
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (32 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 33/80] dm: usb: Pass EHCI controller pointer to ehci_powerup_fixup() Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:44   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 35/80] dm: usb: Pass EHCI controller pointer to ehci_set_usbmode() Simon Glass
                   ` (46 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

We don't need this anymore, so adjust the code to avoid using it.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/host/ehci-tegra.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 5d746f2..5060dd1 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -189,8 +189,6 @@ static struct fdt_usb_controller fdt_usb_controllers[USB_CTRL_COUNT] = {
 	},
 };
 
-static struct fdt_usb_controller *controller;
-
 /*
  * A known hardware issue where Connect Status Change bit of PORTSC register
  * of USB1 controller will be set after Port Reset.
@@ -201,6 +199,10 @@ static struct fdt_usb_controller *controller;
 void ehci_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg,
 			uint32_t *reg)
 {
+	struct fdt_usb *config = ctrl->priv;
+	struct fdt_usb_controller *controller;
+
+	controller = &fdt_usb_controllers[config->type];
 	mdelay(50);
 	/* This is to avoid PORT_ENABLE bit to be cleared in "ehci-hcd.c". */
 	if (controller->has_hostpc)
@@ -237,9 +239,12 @@ void ehci_set_usbmode(int index)
  */
 int ehci_get_port_speed(struct ehci_ctrl *ctrl, uint32_t reg)
 {
+	struct fdt_usb *config = ctrl->priv;
+	struct fdt_usb_controller *controller;
 	uint32_t tmp;
 	uint32_t *reg_ptr;
 
+	controller = &fdt_usb_controllers[config->type];
 	if (controller->has_hostpc) {
 		reg_ptr = (uint32_t *)((u8 *)&ctrl->hcor->or_usbcmd +
 				HOSTPC1_DEVLC);
@@ -766,10 +771,9 @@ int usb_process_devicetree(const void *blob)
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(fdt_usb_controllers); i++) {
-		controller = &fdt_usb_controllers[i];
-
 		count = fdtdec_find_aliases_for_id(blob, "usb",
-			controller->compat, node_list, USB_PORTS_MAX);
+			fdt_usb_controllers[i].compat, node_list,
+			USB_PORTS_MAX);
 		if (count) {
 			err = process_usb_nodes(blob, node_list, count, i);
 			if (err)
@@ -778,8 +782,6 @@ int usb_process_devicetree(const void *blob)
 			return err;
 		}
 	}
-	if (i == ARRAY_SIZE(fdt_usb_controllers))
-		controller = NULL;
 
 	return err;
 }
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 35/80] dm: usb: Pass EHCI controller pointer to ehci_set_usbmode()
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (33 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 34/80] dm: usb: tegra: Drop use of global controller variable Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:44   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 36/80] dm: usb: Pass EHCI controller pointer to ehci_get_portsc_register() Simon Glass
                   ` (45 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

Adjust this function so that it is passed an EHCI controller pointer so that
implementations can look up their controller. This makes the weak functions
use a consistent API.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/host/ehci-faraday.c | 2 +-
 drivers/usb/host/ehci-hcd.c     | 6 +++---
 drivers/usb/host/ehci-tegra.c   | 5 ++---
 drivers/usb/host/ehci.h         | 2 +-
 4 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/host/ehci-faraday.c b/drivers/usb/host/ehci-faraday.c
index e386813..c64672b 100644
--- a/drivers/usb/host/ehci-faraday.c
+++ b/drivers/usb/host/ehci-faraday.c
@@ -92,7 +92,7 @@ int ehci_hcd_stop(int index)
  * This ehci_set_usbmode() overrides the weak function
  * in "ehci-hcd.c".
  */
-void ehci_set_usbmode(int index)
+void ehci_set_usbmode(struct ehci_ctrl *ctrl)
 {
 	/* nothing needs to be done */
 }
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index e9f58e3..196e23a 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -124,12 +124,12 @@ __weak int ehci_get_port_speed(struct ehci_ctrl *ctrl, uint32_t reg)
 	return PORTSC_PSPD(reg);
 }
 
-__weak void ehci_set_usbmode(int index)
+__weak void ehci_set_usbmode(struct ehci_ctrl *ctrl)
 {
 	uint32_t tmp;
 	uint32_t *reg_ptr;
 
-	reg_ptr = (uint32_t *)((u8 *)&ehcic[index].hcor->or_usbcmd + USBMODE);
+	reg_ptr = (uint32_t *)((u8 *)&ctrl->hcor->or_usbcmd + USBMODE);
 	tmp = ehci_readl(reg_ptr);
 	tmp |= USBMODE_CM_HC;
 #if defined(CONFIG_EHCI_MMIO_BIG_ENDIAN)
@@ -187,7 +187,7 @@ static int ehci_reset(int index)
 	}
 
 	if (ehci_is_TDI())
-		ehci_set_usbmode(index);
+		ehci_set_usbmode(&ehcic[index]);
 
 #ifdef CONFIG_USB_EHCI_TXFIFO_THRESH
 	cmd = ehci_readl(&ehcic[index].hcor->or_txfilltuning);
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 5060dd1..6054b2b 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -219,13 +219,12 @@ void ehci_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg,
  * This ehci_set_usbmode overrides the weak function ehci_set_usbmode
  * in "ehci-hcd.c".
  */
-void ehci_set_usbmode(int index)
+void ehci_set_usbmode(struct ehci_ctrl *ctrl)
 {
-	struct fdt_usb *config;
+	struct fdt_usb *config = ctrl->priv;
 	struct usb_ctlr *usbctlr;
 	uint32_t tmp;
 
-	config = &port[index];
 	usbctlr = config->reg;
 
 	tmp = ehci_readl(&usbctlr->usb_mode);
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index a00c7e7..164b3cb 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -253,7 +253,7 @@ struct ehci_ctrl {
 
 /* Weak functions that drivers can override */
 int ehci_get_port_speed(struct ehci_ctrl *ctrl, uint32_t reg);
-void ehci_set_usbmode(int index);
+void ehci_set_usbmode(struct ehci_ctrl *ctrl);
 void ehci_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg,
 			uint32_t *reg);
 uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port);
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 36/80] dm: usb: Pass EHCI controller pointer to ehci_get_portsc_register()
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (34 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 35/80] dm: usb: Pass EHCI controller pointer to ehci_set_usbmode() Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:44   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 37/80] dm: usb: ehci: Use a function to find the controller from struct udevice Simon Glass
                   ` (44 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

Adjust this function so that it is passed an EHCI controller pointer so that
implementations can look up their controller. This makes the weak functions
use a consistent API.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/host/ehci-faraday.c | 4 ++--
 drivers/usb/host/ehci-hcd.c     | 6 +++---
 drivers/usb/host/ehci.h         | 2 +-
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/host/ehci-faraday.c b/drivers/usb/host/ehci-faraday.c
index c64672b..b865fea 100644
--- a/drivers/usb/host/ehci-faraday.c
+++ b/drivers/usb/host/ehci-faraday.c
@@ -134,7 +134,7 @@ int ehci_get_port_speed(struct ehci_ctrl *ctrl, uint32_t reg)
  * This ehci_get_portsc_register() overrides the weak function
  * in "ehci-hcd.c".
  */
-uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port)
+uint32_t *ehci_get_portsc_register(struct ehci_ctrl *ctrl, int port)
 {
 	/* Faraday EHCI has one and only one portsc register */
 	if (port) {
@@ -144,5 +144,5 @@ uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port)
 	}
 
 	/* Faraday EHCI PORTSC register offset is 0x20 from hcor */
-	return (uint32_t *)((uint8_t *)hcor + 0x20);
+	return (uint32_t *)((uint8_t *)ctrl->hcor + 0x20);
 }
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 196e23a..4b0074e 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -144,7 +144,7 @@ __weak void ehci_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg,
 	mdelay(50);
 }
 
-__weak uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port)
+__weak uint32_t *ehci_get_portsc_register(struct ehci_ctrl *ctrl, int port)
 {
 	if (port < 0 || port >= CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
 		/* Printing the message would cause a scan failure! */
@@ -152,7 +152,7 @@ __weak uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port)
 		return NULL;
 	}
 
-	return (uint32_t *)&hcor->or_portsc[port];
+	return (uint32_t *)&ctrl->hcor->or_portsc[port];
 }
 
 static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int usec)
@@ -687,7 +687,7 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 	case USB_REQ_GET_STATUS | ((USB_RT_PORT | USB_DIR_IN) << 8):
 	case USB_REQ_SET_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
 	case USB_REQ_CLEAR_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
-		status_reg = ehci_get_portsc_register(ctrl->hcor, port - 1);
+		status_reg = ehci_get_portsc_register(ctrl, port - 1);
 		if (!status_reg)
 			return -1;
 		break;
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 164b3cb..0fd59bc 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -256,7 +256,7 @@ int ehci_get_port_speed(struct ehci_ctrl *ctrl, uint32_t reg);
 void ehci_set_usbmode(struct ehci_ctrl *ctrl);
 void ehci_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg,
 			uint32_t *reg);
-uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port);
+uint32_t *ehci_get_portsc_register(struct ehci_ctrl *ctrl, int port);
 
 /**
  * ehci_set_controller_priv() - Set up private data for the controller
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 37/80] dm: usb: ehci: Use a function to find the controller from struct udevice
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (35 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 36/80] dm: usb: Pass EHCI controller pointer to ehci_get_portsc_register() Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:44   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 38/80] dm: usb: Refactor EHCI init Simon Glass
                   ` (43 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

With driver model we want to remove the controller pointer in struct udevice
and use driver model data structures instead. To prepare for this, move
access to this field to a function which can provide a different
implementation for driver model.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/host/ehci-hcd.c | 54 +++++++++++++++++++++++++++++++--------------
 1 file changed, 37 insertions(+), 17 deletions(-)

diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 4b0074e..d01e17e 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -119,6 +119,11 @@ static struct descriptor {
 #define ehci_is_TDI()	(0)
 #endif
 
+static struct ehci_ctrl *ehci_get_ctrl(struct usb_device *udev)
+{
+	return udev->controller;
+}
+
 __weak int ehci_get_port_speed(struct ehci_ctrl *ctrl, uint32_t reg)
 {
 	return PORTSC_PSPD(reg);
@@ -315,7 +320,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 	uint32_t cmd;
 	int timeout;
 	int ret = 0;
-	struct ehci_ctrl *ctrl = dev->controller;
+	struct ehci_ctrl *ctrl = ehci_get_ctrl(dev);
 
 	debug("dev=%p, pipe=%lx, buffer=%p, length=%d, req=%p\n", dev, pipe,
 	      buffer, length, req);
@@ -661,9 +666,8 @@ fail:
 	return -1;
 }
 
-int
-ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
-		 int length, struct devrequest *req)
+static int ehci_submit_root(struct usb_device *dev, unsigned long pipe,
+			    void *buffer, int length, struct devrequest *req)
 {
 	uint8_t tmpbuf[4];
 	u16 typeReq;
@@ -672,7 +676,7 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 	uint32_t reg;
 	uint32_t *status_reg;
 	int port = le16_to_cpu(req->index) & 0xff;
-	struct ehci_ctrl *ctrl = dev->controller;
+	struct ehci_ctrl *ctrl = ehci_get_ctrl(dev);
 
 	srclen = 0;
 
@@ -1075,9 +1079,8 @@ done:
 	return 0;
 }
 
-int
-submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
-		int length)
+static int _ehci_submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
+				 void *buffer, int length)
 {
 
 	if (usb_pipetype(pipe) != PIPE_BULK) {
@@ -1087,11 +1090,11 @@ submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 	return ehci_submit_async(dev, pipe, buffer, length, NULL);
 }
 
-int
-submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
-		   int length, struct devrequest *setup)
+static int _ehci_submit_control_msg(struct usb_device *dev, unsigned long pipe,
+				    void *buffer, int length,
+				    struct devrequest *setup)
 {
-	struct ehci_ctrl *ctrl = dev->controller;
+	struct ehci_ctrl *ctrl = ehci_get_ctrl(dev);
 
 	if (usb_pipetype(pipe) != PIPE_CONTROL) {
 		debug("non-control pipe (type=%lu)", usb_pipetype(pipe));
@@ -1161,7 +1164,7 @@ struct int_queue *
 create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize,
 		 int elementsize, void *buffer, int interval)
 {
-	struct ehci_ctrl *ctrl = dev->controller;
+	struct ehci_ctrl *ctrl = ehci_get_ctrl(dev);
 	struct int_queue *result = NULL;
 	int i;
 
@@ -1353,7 +1356,7 @@ void *poll_int_queue(struct usb_device *dev, struct int_queue *queue)
 int
 destroy_int_queue(struct usb_device *dev, struct int_queue *queue)
 {
-	struct ehci_ctrl *ctrl = dev->controller;
+	struct ehci_ctrl *ctrl = ehci_get_ctrl(dev);
 	int result = -1;
 	unsigned long timeout;
 
@@ -1397,9 +1400,8 @@ out:
 	return result;
 }
 
-int
-submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
-	       int length, int interval)
+static int _ehci_submit_int_msg(struct usb_device *dev, unsigned long pipe,
+				void *buffer, int length, int interval)
 {
 	void *backbuffer;
 	struct int_queue *queue;
@@ -1434,3 +1436,21 @@ submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 	/* everything worked out fine */
 	return result;
 }
+
+int submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
+			    void *buffer, int length)
+{
+	return _ehci_submit_bulk_msg(dev, pipe, buffer, length);
+}
+
+int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+		   int length, struct devrequest *setup)
+{
+	return _ehci_submit_control_msg(dev, pipe, buffer, length, setup);
+}
+
+int submit_int_msg(struct usb_device *dev, unsigned long pipe,
+		   void *buffer, int length, int interval)
+{
+	return _ehci_submit_int_msg(dev, pipe, buffer, length, interval);
+}
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 38/80] dm: usb: Refactor EHCI init
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (36 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 37/80] dm: usb: ehci: Use a function to find the controller from struct udevice Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:44   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 39/80] dm: usb: Drop the EHCI weak functions Simon Glass
                   ` (42 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

Move the bulk of the code in usb_lowlevel_init() into a separate function
which will also be used by driver model. Keep the CONFIG options out of
this function by providing a tweak flag for Faraday. We need to avoid using
CONFIG options in driver model code where possible, since it makes it
impossible to use multiple controllers in that code where they have
different options.

The CONFIG_EHCI_HCD_INIT_AFTER_RESET option is also kept out of the
common init function. With driver model the controller will be able to
perform this extra init itself after registering with the EHCI layer.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/host/ehci-hcd.c | 117 +++++++++++++++++++++++++-------------------
 drivers/usb/host/ehci.h     |   6 +++
 2 files changed, 72 insertions(+), 51 deletions(-)

diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index d01e17e..3fa6fe2 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -945,41 +945,19 @@ void *ehci_get_controller_priv(int index)
 	return ehcic[index].priv;
 }
 
-int usb_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)
+static int ehci_common_init(struct ehci_ctrl *ctrl, uint tweaks)
 {
-	uint32_t reg;
-	uint32_t cmd;
 	struct QH *qh_list;
 	struct QH *periodic;
+	uint32_t reg;
+	uint32_t cmd;
 	int i;
-	int rc;
-
-	rc = ehci_hcd_init(index, init, &ehcic[index].hccr, &ehcic[index].hcor);
-	if (rc)
-		return rc;
-	if (init == USB_INIT_DEVICE)
-		goto done;
-
-	/* EHCI spec section 4.1 */
-	if (ehci_reset(index))
-		return -1;
 
-#if defined(CONFIG_EHCI_HCD_INIT_AFTER_RESET)
-	rc = ehci_hcd_init(index, init, &ehcic[index].hccr, &ehcic[index].hcor);
-	if (rc)
-		return rc;
-#endif
 	/* Set the high address word (aka segment) for 64-bit controller */
-	if (ehci_readl(&ehcic[index].hccr->cr_hccparams) & 1)
-		ehci_writel(&ehcic[index].hcor->or_ctrldssegment, 0);
+	if (ehci_readl(&ctrl->hccr->cr_hccparams) & 1)
+		ehci_writel(&ctrl->hcor->or_ctrldssegment, 0);
 
-	qh_list = &ehcic[index].qh_list;
+	qh_list = &ctrl->qh_list;
 
 	/* Set head of reclaim list */
 	memset(qh_list, 0, sizeof(*qh_list));
@@ -995,14 +973,14 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
 			   ALIGN_END_ADDR(struct QH, qh_list, 1));
 
 	/* Set async. queue head pointer. */
-	ehci_writel(&ehcic[index].hcor->or_asynclistaddr, (uint32_t)qh_list);
+	ehci_writel(&ctrl->hcor->or_asynclistaddr, (uint32_t)qh_list);
 
 	/*
 	 * Set up periodic list
 	 * Step 1: Parent QH for all periodic transfers.
 	 */
-	ehcic[index].periodic_schedules = 0;
-	periodic = &ehcic[index].periodic_queue;
+	ctrl->periodic_schedules = 0;
+	periodic = &ctrl->periodic_queue;
 	memset(periodic, 0, sizeof(*periodic));
 	periodic->qh_link = cpu_to_hc32(QH_LINK_TERMINATE);
 	periodic->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
@@ -1020,25 +998,25 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
 	 *         Split Transactions will be spread across microframes using
 	 *         S-mask and C-mask.
 	 */
-	if (ehcic[index].periodic_list == NULL)
-		ehcic[index].periodic_list = memalign(4096, 1024 * 4);
+	if (ctrl->periodic_list == NULL)
+		ctrl->periodic_list = memalign(4096, 1024 * 4);
 
-	if (!ehcic[index].periodic_list)
+	if (!ctrl->periodic_list)
 		return -ENOMEM;
 	for (i = 0; i < 1024; i++) {
-		ehcic[index].periodic_list[i] = cpu_to_hc32((uint32_t)periodic
+		ctrl->periodic_list[i] = cpu_to_hc32((uint32_t)periodic
 						| QH_LINK_TYPE_QH);
 	}
 
-	flush_dcache_range((uint32_t)ehcic[index].periodic_list,
-			   ALIGN_END_ADDR(uint32_t, ehcic[index].periodic_list,
+	flush_dcache_range((uint32_t)ctrl->periodic_list,
+			   ALIGN_END_ADDR(uint32_t, ctrl->periodic_list,
 					  1024));
 
 	/* Set periodic list base address */
-	ehci_writel(&ehcic[index].hcor->or_periodiclistbase,
-		(uint32_t)ehcic[index].periodic_list);
+	ehci_writel(&ctrl->hcor->or_periodiclistbase,
+		    (uint32_t)ctrl->periodic_list);
 
-	reg = ehci_readl(&ehcic[index].hccr->cr_hcsparams);
+	reg = ehci_readl(&ctrl->hccr->cr_hcsparams);
 	descriptor.hub.bNbrPorts = HCS_N_PORTS(reg);
 	debug("Register %x NbrPorts %d\n", reg, descriptor.hub.bNbrPorts);
 	/* Port Indicators */
@@ -1051,29 +1029,66 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
 				| 0x01, &descriptor.hub.wHubCharacteristics);
 
 	/* Start the host controller. */
-	cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
+	cmd = ehci_readl(&ctrl->hcor->or_usbcmd);
 	/*
 	 * Philips, Intel, and maybe others need CMD_RUN before the
 	 * root hub will detect new devices (why?); NEC doesn't
 	 */
 	cmd &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET);
 	cmd |= CMD_RUN;
-	ehci_writel(&ehcic[index].hcor->or_usbcmd, cmd);
+	ehci_writel(&ctrl->hcor->or_usbcmd, cmd);
 
-#ifndef CONFIG_USB_EHCI_FARADAY
-	/* take control over the ports */
-	cmd = ehci_readl(&ehcic[index].hcor->or_configflag);
-	cmd |= FLAG_CF;
-	ehci_writel(&ehcic[index].hcor->or_configflag, cmd);
-#endif
+	if (!(tweaks & EHCI_TWEAK_NO_INIT_CF)) {
+		/* take control over the ports */
+		cmd = ehci_readl(&ctrl->hcor->or_configflag);
+		cmd |= FLAG_CF;
+		ehci_writel(&ctrl->hcor->or_configflag, cmd);
+	}
 
 	/* unblock posted write */
-	cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
+	cmd = ehci_readl(&ctrl->hcor->or_usbcmd);
 	mdelay(5);
-	reg = HC_VERSION(ehci_readl(&ehcic[index].hccr->cr_capbase));
+	reg = HC_VERSION(ehci_readl(&ctrl->hccr->cr_capbase));
 	printf("USB EHCI %x.%02x\n", reg >> 8, reg & 0xff);
 
-	ehcic[index].rootdev = 0;
+	return 0;
+}
+
+int usb_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)
+{
+	struct ehci_ctrl *ctrl = &ehcic[index];
+	uint tweaks = 0;
+	int rc;
+
+	rc = ehci_hcd_init(index, init, &ctrl->hccr, &ctrl->hcor);
+	if (rc)
+		return rc;
+	if (init == USB_INIT_DEVICE)
+		goto done;
+
+	/* EHCI spec section 4.1 */
+	if (ehci_reset(index))
+		return -1;
+
+#if defined(CONFIG_EHCI_HCD_INIT_AFTER_RESET)
+	rc = ehci_hcd_init(index, init, &ctrl->hccr, &ctrl->hcor);
+	if (rc)
+		return rc;
+#endif
+#ifdef CONFIG_USB_EHCI_FARADAY
+	tweaks |= EHCI_TWEAK_NO_INIT_CF;
+#endif
+	rc = ehci_common_init(ctrl, tweaks);
+	if (rc)
+		return rc;
+
+	ctrl->rootdev = 0;
 done:
 	*controller = &ehcic[index];
 	return 0;
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 0fd59bc..2ca111a 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -238,6 +238,12 @@ struct QH {
 	};
 };
 
+/* Tweak flags for EHCI, used to control operation */
+enum {
+	/* don't use or_configflag in init */
+	EHCI_TWEAK_NO_INIT_CF		= 1 << 0,
+};
+
 struct ehci_ctrl {
 	struct ehci_hccr *hccr;	/* R/O registers, not need for volatile */
 	struct ehci_hcor *hcor;
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 39/80] dm: usb: Drop the EHCI weak functions
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (37 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 38/80] dm: usb: Refactor EHCI init Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:44   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 40/80] dm: usb: Change ehci_reset() to use a pointer Simon Glass
                   ` (41 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

These are a pain with driver model because we might have different EHCI
drivers which want to implement them differently. Now that they use
consistent function signatures, we can in good conscience move them to
a struct.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 board/genesi/mx51_efikamx/efikamx-usb.c |   5 +-
 drivers/usb/host/ehci-faraday.c         | 113 +++++++++++++++-----------------
 drivers/usb/host/ehci-hcd.c             |  49 +++++++++++---
 drivers/usb/host/ehci-mx5.c             |  12 ++++
 drivers/usb/host/ehci-tegra.c           |  26 ++++----
 drivers/usb/host/ehci.h                 |  27 +++++---
 6 files changed, 136 insertions(+), 96 deletions(-)

diff --git a/board/genesi/mx51_efikamx/efikamx-usb.c b/board/genesi/mx51_efikamx/efikamx-usb.c
index 0c0b8d3..9dfd249 100644
--- a/board/genesi/mx51_efikamx/efikamx-usb.c
+++ b/board/genesi/mx51_efikamx/efikamx-usb.c
@@ -173,8 +173,9 @@ int board_ehci_hcd_init(int port)
 	return 0;
 }
 
-void ehci_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg,
-			uint32_t *reg)
+/* This overrides a weak function */
+void mx5_ehci_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg,
+			   uint32_t *reg)
 {
 	uint32_t port = OTG_BASE_ADDR + (0x200 * CONFIG_MXC_USB_PORT);
 	struct usb_ehci *ehci = (struct usb_ehci *)port;
diff --git a/drivers/usb/host/ehci-faraday.c b/drivers/usb/host/ehci-faraday.c
index b865fea..821222c 100644
--- a/drivers/usb/host/ehci-faraday.c
+++ b/drivers/usb/host/ehci-faraday.c
@@ -29,6 +29,59 @@ static inline int ehci_is_fotg2xx(union ehci_faraday_regs *regs)
 	return !readl(&regs->usb.easstr);
 }
 
+void faraday_ehci_set_usbmode(struct ehci_ctrl *ctrl)
+{
+	/* nothing needs to be done */
+}
+
+int faraday_ehci_get_port_speed(struct ehci_ctrl *ctrl, uint32_t reg)
+{
+	int spd, ret = PORTSC_PSPD_HS;
+	union ehci_faraday_regs *regs;
+
+	ret = (void __iomem *)((ulong)ctrl->hcor - 0x10);
+	if (ehci_is_fotg2xx(regs))
+		spd = OTGCSR_SPD(readl(&regs->otg.otgcsr));
+	else
+		spd = BMCSR_SPD(readl(&regs->usb.bmcsr));
+
+	switch (spd) {
+	case 0:    /* full speed */
+		ret = PORTSC_PSPD_FS;
+		break;
+	case 1:    /* low  speed */
+		ret = PORTSC_PSPD_LS;
+		break;
+	case 2:    /* high speed */
+		ret = PORTSC_PSPD_HS;
+		break;
+	default:
+		printf("ehci-faraday: invalid device speed\n");
+		break;
+	}
+
+	return ret;
+}
+
+uint32_t *faraday_ehci_get_portsc_register(struct ehci_ctrl *ctrl, int port)
+{
+	/* Faraday EHCI has one and only one portsc register */
+	if (port) {
+		/* Printing the message would cause a scan failure! */
+		debug("The request port(%d) is not configured\n", port);
+		return NULL;
+	}
+
+	/* Faraday EHCI PORTSC register offset is 0x20 from hcor */
+	return (uint32_t *)((uint8_t *)ctrl->hcor + 0x20);
+}
+
+static const struct ehci_ops faraday_ehci_ops = {
+	.set_usb_mode		= faraday_ehci_set_usbmode,
+	.get_port_speed		= faraday_ehci_get_port_speed,
+	.get_portsc_register	= faraday_ehci_get_portsc_register,
+};
+
 /*
  * Create the appropriate control structures to manage
  * a new EHCI host controller.
@@ -43,6 +96,7 @@ int ehci_hcd_init(int index, enum usb_init_type init,
 
 	if (index < 0 || index >= ARRAY_SIZE(base_list))
 		return -1;
+	ehci_set_controller_priv(index, NULL, &faraday_ehci_ops);
 	regs = (void __iomem *)base_list[index];
 	hccr = (struct ehci_hccr *)&regs->usb.hccr;
 	hcor = (struct ehci_hcor *)&regs->usb.hcor;
@@ -87,62 +141,3 @@ int ehci_hcd_stop(int index)
 {
 	return 0;
 }
-
-/*
- * This ehci_set_usbmode() overrides the weak function
- * in "ehci-hcd.c".
- */
-void ehci_set_usbmode(struct ehci_ctrl *ctrl)
-{
-	/* nothing needs to be done */
-}
-
-/*
- * This ehci_get_port_speed() overrides the weak function
- * in "ehci-hcd.c".
- */
-int ehci_get_port_speed(struct ehci_ctrl *ctrl, uint32_t reg)
-{
-	int spd, ret = PORTSC_PSPD_HS;
-	union ehci_faraday_regs *regs;
-
-	ret = (void __iomem *)((ulong)ctrl->hcor - 0x10);
-	if (ehci_is_fotg2xx(regs))
-		spd = OTGCSR_SPD(readl(&regs->otg.otgcsr));
-	else
-		spd = BMCSR_SPD(readl(&regs->usb.bmcsr));
-
-	switch (spd) {
-	case 0:    /* full speed */
-		ret = PORTSC_PSPD_FS;
-		break;
-	case 1:    /* low  speed */
-		ret = PORTSC_PSPD_LS;
-		break;
-	case 2:    /* high speed */
-		ret = PORTSC_PSPD_HS;
-		break;
-	default:
-		printf("ehci-faraday: invalid device speed\n");
-		break;
-	}
-
-	return ret;
-}
-
-/*
- * This ehci_get_portsc_register() overrides the weak function
- * in "ehci-hcd.c".
- */
-uint32_t *ehci_get_portsc_register(struct ehci_ctrl *ctrl, int port)
-{
-	/* Faraday EHCI has one and only one portsc register */
-	if (port) {
-		/* Printing the message would cause a scan failure! */
-		debug("The request port(%d) is not configured\n", port);
-		return NULL;
-	}
-
-	/* Faraday EHCI PORTSC register offset is 0x20 from hcor */
-	return (uint32_t *)((uint8_t *)ctrl->hcor + 0x20);
-}
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 3fa6fe2..82f7318 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -124,12 +124,12 @@ static struct ehci_ctrl *ehci_get_ctrl(struct usb_device *udev)
 	return udev->controller;
 }
 
-__weak int ehci_get_port_speed(struct ehci_ctrl *ctrl, uint32_t reg)
+static int ehci_get_port_speed(struct ehci_ctrl *ctrl, uint32_t reg)
 {
 	return PORTSC_PSPD(reg);
 }
 
-__weak void ehci_set_usbmode(struct ehci_ctrl *ctrl)
+static void ehci_set_usbmode(struct ehci_ctrl *ctrl)
 {
 	uint32_t tmp;
 	uint32_t *reg_ptr;
@@ -143,13 +143,13 @@ __weak void ehci_set_usbmode(struct ehci_ctrl *ctrl)
 	ehci_writel(reg_ptr, tmp);
 }
 
-__weak void ehci_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg,
+static void ehci_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg,
 			       uint32_t *reg)
 {
 	mdelay(50);
 }
 
-__weak uint32_t *ehci_get_portsc_register(struct ehci_ctrl *ctrl, int port)
+static uint32_t *ehci_get_portsc_register(struct ehci_ctrl *ctrl, int port)
 {
 	if (port < 0 || port >= CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
 		/* Printing the message would cause a scan failure! */
@@ -178,6 +178,7 @@ static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int usec)
 
 static int ehci_reset(int index)
 {
+	struct ehci_ctrl *ctrl = &ehcic[index];
 	uint32_t cmd;
 	int ret = 0;
 
@@ -192,7 +193,7 @@ static int ehci_reset(int index)
 	}
 
 	if (ehci_is_TDI())
-		ehci_set_usbmode(&ehcic[index]);
+		ctrl->ops.set_usb_mode(&ehcic[index]);
 
 #ifdef CONFIG_USB_EHCI_TXFIFO_THRESH
 	cmd = ehci_readl(&ehcic[index].hcor->or_txfilltuning);
@@ -691,7 +692,7 @@ static int ehci_submit_root(struct usb_device *dev, unsigned long pipe,
 	case USB_REQ_GET_STATUS | ((USB_RT_PORT | USB_DIR_IN) << 8):
 	case USB_REQ_SET_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
 	case USB_REQ_CLEAR_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
-		status_reg = ehci_get_portsc_register(ctrl, port - 1);
+		status_reg = ctrl->ops.get_portsc_register(ctrl, port - 1);
 		if (!status_reg)
 			return -1;
 		break;
@@ -786,7 +787,7 @@ static int ehci_submit_root(struct usb_device *dev, unsigned long pipe,
 			tmpbuf[1] |= USB_PORT_STAT_POWER >> 8;
 
 		if (ehci_is_TDI()) {
-			switch (ehci_get_port_speed(ctrl, reg)) {
+			switch (ctrl->ops.get_port_speed(ctrl, reg)) {
 			case PORTSC_PSPD_FS:
 				break;
 			case PORTSC_PSPD_LS:
@@ -848,7 +849,7 @@ static int ehci_submit_root(struct usb_device *dev, unsigned long pipe,
 				 * usb 2.0 specification say 50 ms resets on
 				 * root
 				 */
-				ehci_powerup_fixup(ctrl, status_reg, &reg);
+				ctrl->ops.powerup_fixup(ctrl, status_reg, &reg);
 
 				ehci_writel(status_reg, reg & ~EHCI_PS_PR);
 				/*
@@ -935,9 +936,37 @@ unknown:
 	return -1;
 }
 
-void ehci_set_controller_priv(int index, void *priv)
+const struct ehci_ops default_ehci_ops = {
+	.set_usb_mode		= ehci_set_usbmode,
+	.get_port_speed		= ehci_get_port_speed,
+	.powerup_fixup		= ehci_powerup_fixup,
+	.get_portsc_register	= ehci_get_portsc_register,
+};
+
+static void ehci_setup_ops(struct ehci_ctrl *ctrl, const struct ehci_ops *ops)
+{
+	if (!ops) {
+		ctrl->ops = default_ehci_ops;
+	} else {
+		ctrl->ops = *ops;
+		if (!ctrl->ops.set_usb_mode)
+			ctrl->ops.set_usb_mode = ehci_set_usbmode;
+		if (!ctrl->ops.get_port_speed)
+			ctrl->ops.get_port_speed = ehci_get_port_speed;
+		if (!ctrl->ops.powerup_fixup)
+			ctrl->ops.powerup_fixup = ehci_powerup_fixup;
+		if (!ctrl->ops.get_portsc_register)
+			ctrl->ops.get_portsc_register =
+					ehci_get_portsc_register;
+	}
+}
+
+void ehci_set_controller_priv(int index, void *priv, const struct ehci_ops *ops)
 {
-	ehcic[index].priv = priv;
+	struct ehci_ctrl *ctrl = &ehcic[index];
+
+	ctrl->priv = priv;
+	ehci_setup_ops(ctrl, ops);
 }
 
 void *ehci_get_controller_priv(int index)
diff --git a/drivers/usb/host/ehci-mx5.c b/drivers/usb/host/ehci-mx5.c
index 7566c61..d319962 100644
--- a/drivers/usb/host/ehci-mx5.c
+++ b/drivers/usb/host/ehci-mx5.c
@@ -218,11 +218,23 @@ void __weak board_ehci_hcd_postinit(struct usb_ehci *ehci, int port)
 {
 }
 
+__weak void mx5_ehci_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg,
+				   uint32_t *reg)
+{
+	mdelay(50);
+}
+
+static const struct ehci_ops mx5_ehci_ops = {
+	.powerup_fixup		= mx5_ehci_powerup_fixup,
+};
+
 int ehci_hcd_init(int index, enum usb_init_type init,
 		struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 {
 	struct usb_ehci *ehci;
 
+	/* The only user for this is efikamx-usb */
+	ehci_set_controller_priv(index, NULL, &mx5_ehci_ops);
 	set_usboh3_clk();
 	enable_usboh3_clk(true);
 	set_usb_phy_clk();
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 6054b2b..38333c7 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -193,11 +193,9 @@ static struct fdt_usb_controller fdt_usb_controllers[USB_CTRL_COUNT] = {
  * A known hardware issue where Connect Status Change bit of PORTSC register
  * of USB1 controller will be set after Port Reset.
  * We have to clear it in order for later device enumeration to proceed.
- * This ehci_powerup_fixup overrides the weak function ehci_powerup_fixup
- * in "ehci-hcd.c".
  */
-void ehci_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg,
-			uint32_t *reg)
+static void tegra_ehci_powerup_fixup(struct ehci_ctrl *ctrl,
+				     uint32_t *status_reg, uint32_t *reg)
 {
 	struct fdt_usb *config = ctrl->priv;
 	struct fdt_usb_controller *controller;
@@ -215,11 +213,7 @@ void ehci_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg,
 		*reg |= EHCI_PS_CSC;
 }
 
-/*
- * This ehci_set_usbmode overrides the weak function ehci_set_usbmode
- * in "ehci-hcd.c".
- */
-void ehci_set_usbmode(struct ehci_ctrl *ctrl)
+static void tegra_ehci_set_usbmode(struct ehci_ctrl *ctrl)
 {
 	struct fdt_usb *config = ctrl->priv;
 	struct usb_ctlr *usbctlr;
@@ -232,11 +226,7 @@ void ehci_set_usbmode(struct ehci_ctrl *ctrl)
 	ehci_writel(&usbctlr->usb_mode, tmp);
 }
 
-/*
- * This ehci_get_port_speed overrides the weak function ehci_get_port_speed
- * in "ehci-hcd.c".
- */
-int ehci_get_port_speed(struct ehci_ctrl *ctrl, uint32_t reg)
+static int tegra_ehci_get_port_speed(struct ehci_ctrl *ctrl, uint32_t reg)
 {
 	struct fdt_usb *config = ctrl->priv;
 	struct fdt_usb_controller *controller;
@@ -714,6 +704,12 @@ static int fdt_decode_usb(const void *blob, int node, struct fdt_usb *config)
 	return 0;
 }
 
+static const struct ehci_ops tegra_ehci_ops = {
+	.set_usb_mode		= tegra_ehci_set_usbmode,
+	.get_port_speed		= tegra_ehci_get_port_speed,
+	.powerup_fixup		= tegra_ehci_powerup_fixup,
+};
+
 /*
  * process_usb_nodes() - Process a list of USB nodes, adding them to our list
  *			of USB ports.
@@ -805,7 +801,7 @@ int ehci_hcd_init(int index, enum usb_init_type init,
 		return -1;
 
 	config = &port[index];
-	ehci_set_controller_priv(index, config);
+	ehci_set_controller_priv(index, config, &tegra_ehci_ops);
 
 	switch (init) {
 	case USB_INIT_HOST:
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 2ca111a..cc23e1f 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -244,6 +244,16 @@ enum {
 	EHCI_TWEAK_NO_INIT_CF		= 1 << 0,
 };
 
+struct ehci_ctrl;
+
+struct ehci_ops {
+	void (*set_usb_mode)(struct ehci_ctrl *ctrl);
+	int (*get_port_speed)(struct ehci_ctrl *ctrl, uint32_t reg);
+	void (*powerup_fixup)(struct ehci_ctrl *ctrl, uint32_t *status_reg,
+			      uint32_t *reg);
+	uint32_t *(*get_portsc_register)(struct ehci_ctrl *ctrl, int port);
+};
+
 struct ehci_ctrl {
 	struct ehci_hccr *hccr;	/* R/O registers, not need for volatile */
 	struct ehci_hcor *hcor;
@@ -254,27 +264,24 @@ struct ehci_ctrl {
 	uint32_t *periodic_list;
 	int periodic_schedules;
 	int ntds;
+	struct ehci_ops ops;
 	void *priv;	/* client's private data */
 };
 
-/* Weak functions that drivers can override */
-int ehci_get_port_speed(struct ehci_ctrl *ctrl, uint32_t reg);
-void ehci_set_usbmode(struct ehci_ctrl *ctrl);
-void ehci_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg,
-			uint32_t *reg);
-uint32_t *ehci_get_portsc_register(struct ehci_ctrl *ctrl, int port);
-
 /**
- * ehci_set_controller_priv() - Set up private data for the controller
+ * ehci_set_controller_info() - Set up private data for the controller
  *
  * This function can be called in ehci_hcd_init() to tell the EHCI layer
  * about the controller's private data pointer. Then in the above functions
- * this can be accessed given the struct ehci_ctrl pointer.
+ * this can be accessed given the struct ehci_ctrl pointer. Also special
+ * EHCI operation methods can be provided if required
  *
  * @index:	Controller number to set
  * @priv:	Controller pointer
+ * @ops:	Controller operations, or NULL to use default
  */
-void ehci_set_controller_priv(int index, void *priv);
+void ehci_set_controller_priv(int index, void *priv,
+			      const struct ehci_ops *ops);
 
 /**
  * ehci_get_controller_priv() - Get controller private data
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 40/80] dm: usb: Change ehci_reset() to use a pointer
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (38 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 39/80] dm: usb: Drop the EHCI weak functions Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:44   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 41/80] dm: usb: Add driver model support to EHCI Simon Glass
                   ` (40 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

The index cannot be used with driver model, and isn't needed anyway. Change
the parameter to a pointer.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/host/ehci-hcd.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 82f7318..86082a9 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -176,16 +176,15 @@ static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int usec)
 	return -1;
 }
 
-static int ehci_reset(int index)
+static int ehci_reset(struct ehci_ctrl *ctrl)
 {
-	struct ehci_ctrl *ctrl = &ehcic[index];
 	uint32_t cmd;
 	int ret = 0;
 
-	cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
+	cmd = ehci_readl(&ctrl->hcor->or_usbcmd);
 	cmd = (cmd & ~CMD_RUN) | CMD_RESET;
-	ehci_writel(&ehcic[index].hcor->or_usbcmd, cmd);
-	ret = handshake((uint32_t *)&ehcic[index].hcor->or_usbcmd,
+	ehci_writel(&ctrl->hcor->or_usbcmd, cmd);
+	ret = handshake((uint32_t *)&ctrl->hcor->or_usbcmd,
 			CMD_RESET, 0, 250 * 1000);
 	if (ret < 0) {
 		printf("EHCI fail to reset\n");
@@ -193,13 +192,13 @@ static int ehci_reset(int index)
 	}
 
 	if (ehci_is_TDI())
-		ctrl->ops.set_usb_mode(&ehcic[index]);
+		ctrl->ops.set_usb_mode(ctrl);
 
 #ifdef CONFIG_USB_EHCI_TXFIFO_THRESH
-	cmd = ehci_readl(&ehcic[index].hcor->or_txfilltuning);
+	cmd = ehci_readl(&ctrl->hcor->or_txfilltuning);
 	cmd &= ~TXFIFO_THRESH_MASK;
 	cmd |= TXFIFO_THRESH(CONFIG_USB_EHCI_TXFIFO_THRESH);
-	ehci_writel(&ehcic[index].hcor->or_txfilltuning, cmd);
+	ehci_writel(&ctrl->hcor->or_txfilltuning, cmd);
 #endif
 out:
 	return ret;
@@ -1102,7 +1101,7 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
 		goto done;
 
 	/* EHCI spec section 4.1 */
-	if (ehci_reset(index))
+	if (ehci_reset(ctrl))
 		return -1;
 
 #if defined(CONFIG_EHCI_HCD_INIT_AFTER_RESET)
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 41/80] dm: usb: Add driver model support to EHCI
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (39 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 40/80] dm: usb: Change ehci_reset() to use a pointer Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:44   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 42/80] dm: usb: Allow USB drivers to be declared and auto-probed Simon Glass
                   ` (39 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

Add a way for EHCI controller drivers to support driver model. Drivers can
call ehci_register() to register themselves in their probe() methods.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/host/ehci-hcd.c | 125 ++++++++++++++++++++++++++++++++++++++++++--
 drivers/usb/host/ehci.h     |   6 +++
 2 files changed, 127 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 86082a9..227aa83 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -21,6 +21,7 @@
  * MA 02111-1307 USA
  */
 #include <common.h>
+#include <dm.h>
 #include <errno.h>
 #include <asm/byteorder.h>
 #include <asm/unaligned.h>
@@ -42,7 +43,9 @@
  */
 #define HCHALT_TIMEOUT (8 * 1000)
 
+#ifndef CONFIG_DM_USB
 static struct ehci_ctrl ehcic[CONFIG_USB_MAX_CONTROLLER_COUNT];
+#endif
 
 #define ALIGN_END_ADDR(type, ptr, size)			\
 	((uint32_t)(ptr) + roundup((size) * sizeof(type), USB_DMA_MINALIGN))
@@ -121,7 +124,18 @@ static struct descriptor {
 
 static struct ehci_ctrl *ehci_get_ctrl(struct usb_device *udev)
 {
+#ifdef CONFIG_DM_USB
+	struct udevice *dev;
+
+	/* Find the USB controller */
+	for (dev = udev->dev;
+	     device_get_uclass_id(dev) != UCLASS_USB;
+	     dev = dev->parent)
+		;
+	return dev_get_priv(dev);
+#else
 	return udev->controller;
+#endif
 }
 
 static int ehci_get_port_speed(struct ehci_ctrl *ctrl, uint32_t reg)
@@ -281,12 +295,13 @@ static inline u8 ehci_encode_speed(enum usb_device_speed speed)
 	return QH_FULL_SPEED;
 }
 
-static void ehci_update_endpt2_dev_n_port(struct usb_device *dev,
+static void ehci_update_endpt2_dev_n_port(struct usb_device *udev,
 					  struct QH *qh)
 {
 	struct usb_device *ttdev;
+	int parent_devnum;
 
-	if (dev->speed != USB_SPEED_LOW && dev->speed != USB_SPEED_FULL)
+	if (udev->speed != USB_SPEED_LOW && udev->speed != USB_SPEED_FULL)
 		return;
 
 	/*
@@ -294,14 +309,35 @@ static void ehci_update_endpt2_dev_n_port(struct usb_device *dev,
 	 * the tt, so of the first upstream usb-2 hub, there may be usb-1 hubs
 	 * in the tree before that one!
 	 */
-	ttdev = dev;
+#ifdef CONFIG_DM_USB
+	struct udevice *parent;
+
+	for (ttdev = udev; ; ) {
+		struct udevice *dev = ttdev->dev;
+
+		if (dev->parent &&
+		    device_get_uclass_id(dev->parent) == UCLASS_USB_HUB)
+			parent = dev->parent;
+		else
+			parent = NULL;
+		if (!parent)
+			return;
+		ttdev = dev_get_parentdata(parent);
+		if (!ttdev->speed != USB_SPEED_HIGH)
+			break;
+	}
+	parent_devnum = ttdev->devnum;
+#else
+	ttdev = udev;
 	while (ttdev->parent && ttdev->parent->speed != USB_SPEED_HIGH)
 		ttdev = ttdev->parent;
 	if (!ttdev->parent)
 		return;
+	parent_devnum = ttdev->parent->devnum;
+#endif
 
 	qh->qh_endpt2 |= cpu_to_hc32(QH_ENDPT2_PORTNUM(ttdev->portnr) |
-				     QH_ENDPT2_HUBADDR(ttdev->parent->devnum));
+				     QH_ENDPT2_HUBADDR(parent_devnum));
 }
 
 static int
@@ -960,6 +996,7 @@ static void ehci_setup_ops(struct ehci_ctrl *ctrl, const struct ehci_ops *ops)
 	}
 }
 
+#ifndef CONFIG_DM_USB
 void ehci_set_controller_priv(int index, void *priv, const struct ehci_ops *ops)
 {
 	struct ehci_ctrl *ctrl = &ehcic[index];
@@ -972,6 +1009,7 @@ void *ehci_get_controller_priv(int index)
 {
 	return ehcic[index].priv;
 }
+#endif
 
 static int ehci_common_init(struct ehci_ctrl *ctrl, uint tweaks)
 {
@@ -1082,6 +1120,7 @@ static int ehci_common_init(struct ehci_ctrl *ctrl, uint tweaks)
 	return 0;
 }
 
+#ifndef CONFIG_DM_USB
 int usb_lowlevel_stop(int index)
 {
 	ehci_shutdown(&ehcic[index]);
@@ -1121,6 +1160,7 @@ done:
 	*controller = &ehcic[index];
 	return 0;
 }
+#endif
 
 static int _ehci_submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
 				 void *buffer, int length)
@@ -1480,6 +1520,7 @@ static int _ehci_submit_int_msg(struct usb_device *dev, unsigned long pipe,
 	return result;
 }
 
+#ifndef CONFIG_DM_USB
 int submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
 			    void *buffer, int length)
 {
@@ -1497,3 +1538,79 @@ int submit_int_msg(struct usb_device *dev, unsigned long pipe,
 {
 	return _ehci_submit_int_msg(dev, pipe, buffer, length, interval);
 }
+#endif
+
+#ifdef CONFIG_DM_USB
+static int ehci_submit_control_msg(struct udevice *dev, struct usb_device *udev,
+				   unsigned long pipe, void *buffer, int length,
+				   struct devrequest *setup)
+{
+	debug("%s: dev='%s', udev=%p, udev->dev='%s', portnr=%d\n", __func__,
+	      dev->name, udev, udev->dev->name, udev->portnr);
+
+	return _ehci_submit_control_msg(udev, pipe, buffer, length, setup);
+}
+
+static int ehci_submit_bulk_msg(struct udevice *dev, struct usb_device *udev,
+				unsigned long pipe, void *buffer, int length)
+{
+	debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev);
+	return _ehci_submit_bulk_msg(udev, pipe, buffer, length);
+}
+
+static int ehci_submit_int_msg(struct udevice *dev, struct usb_device *udev,
+			       unsigned long pipe, void *buffer, int length,
+			       int interval)
+{
+	debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev);
+	return _ehci_submit_int_msg(udev, pipe, buffer, length, interval);
+}
+
+int ehci_register(struct udevice *dev, struct ehci_hccr *hccr,
+		  struct ehci_hcor *hcor, const struct ehci_ops *ops,
+		  uint tweaks, enum usb_init_type init)
+{
+	struct ehci_ctrl *ctrl = dev_get_priv(dev);
+	int ret;
+
+	debug("%s: dev='%s', ctrl=%p, hccr=%p, hcor=%p, init=%d\n", __func__,
+	      dev->name, ctrl, hccr, hcor, init);
+
+	ehci_setup_ops(ctrl, ops);
+	ctrl->hccr = hccr;
+	ctrl->hcor = hcor;
+	ctrl->priv = ctrl;
+
+	if (init == USB_INIT_DEVICE)
+		goto done;
+	ret = ehci_reset(ctrl);
+	if (ret)
+		goto err;
+
+	ret = ehci_common_init(ctrl, tweaks);
+	if (ret)
+		goto err;
+done:
+	return 0;
+err:
+	free(ctrl);
+	debug("%s: failed, ret=%d\n", __func__, ret);
+	return ret;
+}
+
+int ehci_deregister(struct udevice *dev)
+{
+	struct ehci_ctrl *ctrl = dev_get_priv(dev);
+
+	ehci_shutdown(ctrl);
+
+	return 0;
+}
+
+struct dm_usb_ops ehci_usb_ops = {
+	.control = ehci_submit_control_msg,
+	.bulk = ehci_submit_bulk_msg,
+	.interrupt = ehci_submit_int_msg,
+};
+
+#endif
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index cc23e1f..774282d 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -296,4 +296,10 @@ int ehci_hcd_init(int index, enum usb_init_type init,
 		struct ehci_hccr **hccr, struct ehci_hcor **hcor);
 int ehci_hcd_stop(int index);
 
+int ehci_register(struct udevice *dev, struct ehci_hccr *hccr,
+		  struct ehci_hcor *hcor, const struct ehci_ops *ops,
+		  uint tweaks, enum usb_init_type init);
+int ehci_deregister(struct udevice *dev);
+extern struct dm_usb_ops ehci_usb_ops;
+
 #endif /* USB_EHCI_H */
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 42/80] dm: usb: Allow USB drivers to be declared and auto-probed
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (40 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 41/80] dm: usb: Add driver model support to EHCI Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:45   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 43/80] dm: usb: Bind generic USB devices when there is no driver Simon Glass
                   ` (38 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

USB devices in U-Boot are currently probed only after all devices have
been enumerated. Each type of device is probed by custom code, e.g.:

- USB storage
- Keyboard
- Ethernet

With driver model this approach doesn't work very well. We could build
a picture of the bus and then go back and add the devices later, but
this means that the data structures are incomplete for quite a while.
It also does not follow the model of being able to bind a device when we
discover it.

We would prefer to have devices automatically be bound as the device is
enumerated. This allows us to attach drivers to particular USB classes
or product/vendor IDs. This is the method used by Linux.

Add the required #defines from Linux, a way of declaring a USB driver and
the logic to locate the correct driver given the USB device's descriptors.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/host/usb-uclass.c | 206 +++++++++++++++++++++++++++++++++++++++++-
 include/usb.h                 | 107 ++++++++++++++++++++++
 2 files changed, 311 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c
index 22dcd14..a86e905 100644
--- a/drivers/usb/host/usb-uclass.c
+++ b/drivers/usb/host/usb-uclass.c
@@ -2,6 +2,8 @@
  * (C) Copyright 2015 Google, Inc
  * Written by Simon Glass <sjg@chromium.org>
  *
+ * usb_match_device() modified from Linux kernel v4.0.
+ *
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
@@ -247,6 +249,179 @@ int usb_legacy_port_reset(struct usb_device *parent, int portnr)
 	return usb_port_reset(parent, portnr);
 }
 
+/* returns 0 if no match, 1 if match */
+int usb_match_device(const struct usb_device_descriptor *desc,
+		     const struct usb_device_id *id)
+{
+	if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
+	    id->idVendor != le16_to_cpu(desc->idVendor))
+		return 0;
+
+	if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&
+	    id->idProduct != le16_to_cpu(desc->idProduct))
+		return 0;
+
+	/* No need to test id->bcdDevice_lo != 0, since 0 is never
+	   greater than any unsigned number. */
+	if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) &&
+	    (id->bcdDevice_lo > le16_to_cpu(desc->bcdDevice)))
+		return 0;
+
+	if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) &&
+	    (id->bcdDevice_hi < le16_to_cpu(desc->bcdDevice)))
+		return 0;
+
+	if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) &&
+	    (id->bDeviceClass != desc->bDeviceClass))
+		return 0;
+
+	if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) &&
+	    (id->bDeviceSubClass != desc->bDeviceSubClass))
+		return 0;
+
+	if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) &&
+	    (id->bDeviceProtocol != desc->bDeviceProtocol))
+		return 0;
+
+	return 1;
+}
+
+/* returns 0 if no match, 1 if match */
+int usb_match_one_id_intf(const struct usb_device_descriptor *desc,
+			  const struct usb_interface_descriptor *int_desc,
+			  const struct usb_device_id *id)
+{
+	/* The interface class, subclass, protocol and number should never be
+	 * checked for a match if the device class is Vendor Specific,
+	 * unless the match record specifies the Vendor ID. */
+	if (desc->bDeviceClass == USB_CLASS_VENDOR_SPEC &&
+	    !(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
+	    (id->match_flags & (USB_DEVICE_ID_MATCH_INT_CLASS |
+				USB_DEVICE_ID_MATCH_INT_SUBCLASS |
+				USB_DEVICE_ID_MATCH_INT_PROTOCOL |
+				USB_DEVICE_ID_MATCH_INT_NUMBER)))
+		return 0;
+
+	if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&
+	    (id->bInterfaceClass != int_desc->bInterfaceClass))
+		return 0;
+
+	if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) &&
+	    (id->bInterfaceSubClass != int_desc->bInterfaceSubClass))
+		return 0;
+
+	if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) &&
+	    (id->bInterfaceProtocol != int_desc->bInterfaceProtocol))
+		return 0;
+
+	if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_NUMBER) &&
+	    (id->bInterfaceNumber != int_desc->bInterfaceNumber))
+		return 0;
+
+	return 1;
+}
+
+/* returns 0 if no match, 1 if match */
+int usb_match_one_id(struct usb_device_descriptor *desc,
+		     struct usb_interface_descriptor *int_desc,
+		     const struct usb_device_id *id)
+{
+	if (!usb_match_device(desc, id))
+		return 0;
+
+	return usb_match_one_id_intf(desc, int_desc, id);
+}
+
+/**
+ * usb_find_and_bind_driver() - Find and bind the right USB driver
+ *
+ * This only looks at certain fields in the descriptor.
+ */
+static int usb_find_and_bind_driver(struct udevice *parent,
+				    struct usb_device_descriptor *desc,
+				    struct usb_interface_descriptor *iface,
+				    int bus_seq, int devnum,
+				    struct udevice **devp)
+{
+	struct usb_driver_entry *start, *entry;
+	int n_ents;
+	int ret;
+	char name[30], *str;
+
+	*devp = NULL;
+	debug("%s: Searching for driver\n", __func__);
+	start = ll_entry_start(struct usb_driver_entry, usb_driver_entry);
+	n_ents = ll_entry_count(struct usb_driver_entry, usb_driver_entry);
+	for (entry = start; entry != start + n_ents; entry++) {
+		const struct usb_device_id *id;
+		struct udevice *dev;
+		const struct driver *drv;
+		struct usb_dev_platdata *plat;
+
+		for (id = entry->match; id->match_flags; id++) {
+			if (!usb_match_one_id(desc, iface, id))
+				continue;
+
+			drv = entry->driver;
+			/*
+			 * We could pass the descriptor to the driver as
+			 * platdata (instead of NULL) and allow its bind()
+			 * method to return -ENOENT if it doesn't support this
+			 * device. That way we could continue the search to
+			 * find another driver. For now this doesn't seem
+			 * necesssary, so just bind the first match.
+			 */
+			ret = device_bind(parent, drv, drv->name, NULL, -1,
+					  &dev);
+			if (ret)
+				goto error;
+			debug("%s: Match found: %s\n", __func__, drv->name);
+			dev->driver_data = id->driver_info;
+			plat = dev_get_parent_platdata(dev);
+			plat->id = *id;
+			*devp = dev;
+			return 0;
+		}
+	}
+
+	ret = -ENOENT;
+error:
+	debug("%s: No match found: %d\n", __func__, ret);
+	return ret;
+}
+
+/**
+ * usb_find_child() - Find an existing device which matches our needs
+ *
+ *
+ */
+static int usb_find_child(struct udevice *parent,
+			  struct usb_device_descriptor *desc,
+			  struct usb_interface_descriptor *iface,
+			  struct udevice **devp)
+{
+	struct udevice *dev;
+
+	*devp = NULL;
+	for (device_find_first_child(parent, &dev);
+	     dev;
+	     device_find_next_child(&dev)) {
+		struct usb_dev_platdata *plat = dev_get_parent_platdata(dev);
+
+		/* If this device is already in use, skip it */
+		if (device_active(dev))
+			continue;
+		debug("   %s: name='%s', plat=%d, desc=%d\n", __func__,
+		      dev->name, plat->id.bDeviceClass, desc->bDeviceClass);
+		if (usb_match_one_id(desc, iface, &plat->id)) {
+			*devp = dev;
+			return 0;
+		}
+	}
+
+	return -ENOENT;
+}
+
 int usb_scan_device(struct udevice *parent, int port,
 		    enum usb_device_speed speed, struct udevice **devp)
 {
@@ -307,9 +482,36 @@ int usb_scan_device(struct udevice *parent, int port,
 		return ret;
 	ret = usb_find_child(parent, &udev->descriptor, iface, &dev);
 	debug("** usb_find_child returns %d\n", ret);
+	if (ret) {
+		if (ret != -ENOENT)
+			return ret;
+		ret = usb_find_and_bind_driver(parent, &udev->descriptor, iface,
+					       udev->controller_dev->seq,
+					       udev->devnum, &dev);
+		if (ret)
+			return ret;
+		created = true;
+	}
+	plat = dev_get_parent_platdata(dev);
+	debug("%s: Probing '%s', plat=%p\n", __func__, dev->name, plat);
+	plat->devnum = udev->devnum;
+	plat->speed = udev->speed;
+	plat->slot_id = udev->slot_id;
+	plat->portnr = port;
+	debug("** device '%s': stashing slot_id=%d\n", dev->name,
+	      plat->slot_id);
+	priv->next_addr++;
+	ret = device_probe(dev);
+	if (ret) {
+		debug("%s: Device '%s' probe failed\n", __func__, dev->name);
+		priv->next_addr--;
+		if (created)
+			device_unbind(dev);
+		return ret;
+	}
+	*devp = dev;
 
-	/* TODO: Find a suitable driver and create the device */
-	return -ENOENT;
+	return 0;
 }
 
 int usb_child_post_bind(struct udevice *dev)
diff --git a/include/usb.h b/include/usb.h
index badb287..799b0c3 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -412,6 +412,113 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate);
 				((usb_pipeendpoint(pipe) * 2) - \
 				 (usb_pipein(pipe) ? 0 : 1))
 
+/**
+ * struct usb_device_id - identifies USB devices for probing and hotplugging
+ * @match_flags: Bit mask controlling which of the other fields are used to
+ *	match against new devices. Any field except for driver_info may be
+ *	used, although some only make sense in conjunction with other fields.
+ *	This is usually set by a USB_DEVICE_*() macro, which sets all
+ *	other fields in this structure except for driver_info.
+ * @idVendor: USB vendor ID for a device; numbers are assigned
+ *	by the USB forum to its members.
+ * @idProduct: Vendor-assigned product ID.
+ * @bcdDevice_lo: Low end of range of vendor-assigned product version numbers.
+ *	This is also used to identify individual product versions, for
+ *	a range consisting of a single device.
+ * @bcdDevice_hi: High end of version number range.  The range of product
+ *	versions is inclusive.
+ * @bDeviceClass: Class of device; numbers are assigned
+ *	by the USB forum.  Products may choose to implement classes,
+ *	or be vendor-specific.  Device classes specify behavior of all
+ *	the interfaces on a device.
+ * @bDeviceSubClass: Subclass of device; associated with bDeviceClass.
+ * @bDeviceProtocol: Protocol of device; associated with bDeviceClass.
+ * @bInterfaceClass: Class of interface; numbers are assigned
+ *	by the USB forum.  Products may choose to implement classes,
+ *	or be vendor-specific.  Interface classes specify behavior only
+ *	of a given interface; other interfaces may support other classes.
+ * @bInterfaceSubClass: Subclass of interface; associated with bInterfaceClass.
+ * @bInterfaceProtocol: Protocol of interface; associated with bInterfaceClass.
+ * @bInterfaceNumber: Number of interface; composite devices may use
+ *	fixed interface numbers to differentiate between vendor-specific
+ *	interfaces.
+ * @driver_info: Holds information used by the driver.  Usually it holds
+ *	a pointer to a descriptor understood by the driver, or perhaps
+ *	device flags.
+ *
+ * In most cases, drivers will create a table of device IDs by using
+ * USB_DEVICE(), or similar macros designed for that purpose.
+ * They will then export it to userspace using MODULE_DEVICE_TABLE(),
+ * and provide it to the USB core through their usb_driver structure.
+ *
+ * See the usb_match_id() function for information about how matches are
+ * performed.  Briefly, you will normally use one of several macros to help
+ * construct these entries.  Each entry you provide will either identify
+ * one or more specific products, or will identify a class of products
+ * which have agreed to behave the same.  You should put the more specific
+ * matches towards the beginning of your table, so that driver_info can
+ * record quirks of specific products.
+ */
+struct usb_device_id {
+	/* which fields to match against? */
+	u16 match_flags;
+
+	/* Used for product specific matches; range is inclusive */
+	u16 idVendor;
+	u16 idProduct;
+	u16 bcdDevice_lo;
+	u16 bcdDevice_hi;
+
+	/* Used for device class matches */
+	u8 bDeviceClass;
+	u8 bDeviceSubClass;
+	u8 bDeviceProtocol;
+
+	/* Used for interface class matches */
+	u8 bInterfaceClass;
+	u8 bInterfaceSubClass;
+	u8 bInterfaceProtocol;
+
+	/* Used for vendor-specific interface matches */
+	u8 bInterfaceNumber;
+
+	/* not matched against */
+	ulong driver_info;
+};
+
+/* Some useful macros to use to create struct usb_device_id */
+#define USB_DEVICE_ID_MATCH_VENDOR		0x0001
+#define USB_DEVICE_ID_MATCH_PRODUCT		0x0002
+#define USB_DEVICE_ID_MATCH_DEV_LO		0x0004
+#define USB_DEVICE_ID_MATCH_DEV_HI		0x0008
+#define USB_DEVICE_ID_MATCH_DEV_CLASS		0x0010
+#define USB_DEVICE_ID_MATCH_DEV_SUBCLASS	0x0020
+#define USB_DEVICE_ID_MATCH_DEV_PROTOCOL	0x0040
+#define USB_DEVICE_ID_MATCH_INT_CLASS		0x0080
+#define USB_DEVICE_ID_MATCH_INT_SUBCLASS	0x0100
+#define USB_DEVICE_ID_MATCH_INT_PROTOCOL	0x0200
+#define USB_DEVICE_ID_MATCH_INT_NUMBER		0x0400
+
+/* Match anything, indicates this is a valid entry even if everything is 0 */
+#define USB_DEVICE_ID_MATCH_NONE		0x0800
+#define USB_DEVICE_ID_MATCH_ALL			0x07ff
+
+/**
+ * struct usb_driver_entry - Matches a driver to its usb_device_ids
+ * @compatible: Compatible string
+ * @data: Data for this compatible string
+ */
+struct usb_driver_entry {
+	struct driver *driver;
+	const struct usb_device_id *match;
+};
+
+#define USB_DEVICE(__name, __match)					\
+	ll_entry_declare(struct usb_driver_entry, __name, usb_driver_entry) = {\
+		.driver = llsym(struct driver, __name, driver), \
+		.match = __match, \
+		}
+
 /*************************************************************************
  * Hub Stuff
  */
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 43/80] dm: usb: Bind generic USB devices when there is no driver
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (41 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 42/80] dm: usb: Allow USB drivers to be declared and auto-probed Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:45   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 44/80] dm: usb: Allow setting up a USB controller as a device/gadget Simon Glass
                   ` (37 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

At present USB devices with no driver model driver cannot be seen in the
device list, and we fail to set them up correctly. This means they cannot
be used.

While having real drivers that support driver model for all USB devices
is the eventual goal, we are not there yet.

As a stop-gap, add a generic USB driver which is bound when we do not have
a real driver. This allows the device to be set up and shown on the bus.
It also allows ad-hoc code (such as usb_ether) to find these devices and
set them up.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/host/usb-uclass.c | 18 +++++++++++++++++-
 include/dm/uclass-id.h        |  1 +
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c
index a86e905..fa5f14e 100644
--- a/drivers/usb/host/usb-uclass.c
+++ b/drivers/usb/host/usb-uclass.c
@@ -384,7 +384,13 @@ static int usb_find_and_bind_driver(struct udevice *parent,
 		}
 	}
 
-	ret = -ENOENT;
+	/* Bind a generic driver so that the device can be used */
+	snprintf(name, sizeof(name), "generic_bus_%x_dev_%x", bus_seq, devnum);
+	str = strdup(name);
+	if (!str)
+		return -ENOMEM;
+	ret = device_bind_driver(parent, "usb_dev_generic_drv", str, devp);
+
 error:
 	debug("%s: No match found: %d\n", __func__, ret);
 	return ret;
@@ -592,3 +598,13 @@ UCLASS_DRIVER(usb) = {
 	.child_pre_probe = usb_child_pre_probe,
 	.per_child_platdata_auto_alloc_size = sizeof(struct usb_dev_platdata),
 };
+
+UCLASS_DRIVER(usb_dev_generic) = {
+	.id		= UCLASS_USB_DEV_GENERIC,
+	.name		= "usb_dev_generic",
+};
+
+U_BOOT_DRIVER(usb_dev_generic_drv) = {
+	.id		= UCLASS_USB_DEV_GENERIC,
+	.name		= "usb_dev_generic_drv",
+};
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index acec938..42a6f1f 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -41,6 +41,7 @@ enum uclass_id {
 	UCLASS_ETH,		/* Ethernet device */
 	UCLASS_USB,		/* USB bus */
 	UCLASS_USB_HUB,		/* USB hub */
+	UCLASS_USB_DEV_GENERIC,	/* USB generic device */
 
 	UCLASS_COUNT,
 	UCLASS_INVALID = -1,
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 44/80] dm: usb: Allow setting up a USB controller as a device/gadget
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (42 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 43/80] dm: usb: Bind generic USB devices when there is no driver Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:45   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 45/80] dm: usb: Split out the keyboard probe into its own function Simon Glass
                   ` (36 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

Some controllers support OTG (on-the-go) where they can operate as either
host or device. The gadget layer in U-Boot supports this.

While this layer does not interact with driver model, we can provide a
function which sets up the controller in the correct way. This way the code
at least builds (although it likely will not work).

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/gadget/ci_udc.c   |  4 ++++
 drivers/usb/host/usb-uclass.c | 24 ++++++++++++++++++++++++
 2 files changed, 28 insertions(+)

diff --git a/drivers/usb/gadget/ci_udc.c b/drivers/usb/gadget/ci_udc.c
index b0ef35e..0afc987 100644
--- a/drivers/usb/gadget/ci_udc.c
+++ b/drivers/usb/gadget/ci_udc.c
@@ -883,7 +883,11 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
 	if (driver->speed != USB_SPEED_FULL && driver->speed != USB_SPEED_HIGH)
 		return -EINVAL;
 
+#ifdef CONFIG_DM_USB
+	ret = usb_setup_ehci_gadget(&controller.ctrl);
+#else
 	ret = usb_lowlevel_init(0, USB_INIT_DEVICE, (void **)&controller.ctrl);
+#endif
 	if (ret)
 		return ret;
 
diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c
index fa5f14e..29ef5d9 100644
--- a/drivers/usb/host/usb-uclass.c
+++ b/drivers/usb/host/usb-uclass.c
@@ -249,6 +249,30 @@ int usb_legacy_port_reset(struct usb_device *parent, int portnr)
 	return usb_port_reset(parent, portnr);
 }
 
+int usb_setup_ehci_gadget(struct ehci_ctrl **ctlrp)
+{
+	struct usb_platdata *plat;
+	struct udevice *dev;
+	int ret;
+
+	/* Find the old device and remove it */
+	ret = uclass_find_device_by_seq(UCLASS_USB, 0, true, &dev);
+	if (ret)
+		return ret;
+	ret = device_remove(dev);
+	if (ret)
+		return ret;
+
+	plat = dev_get_platdata(dev);
+	plat->init_type = USB_INIT_DEVICE;
+	ret = device_probe(dev);
+	if (ret)
+		return ret;
+	*ctlrp = dev_get_priv(dev);
+
+	return 0;
+}
+
 /* returns 0 if no match, 1 if match */
 int usb_match_device(const struct usb_device_descriptor *desc,
 		     const struct usb_device_id *id)
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 45/80] dm: usb: Split out the keyboard probe into its own function
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (43 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 44/80] dm: usb: Allow setting up a USB controller as a device/gadget Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:45   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 46/80] dm: usb: Support driver model with USB keyboards Simon Glass
                   ` (35 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

Before adding driver model support, split out code from this over-long
function.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 common/usb_kbd.c | 89 ++++++++++++++++++++++++++++++++------------------------
 1 file changed, 51 insertions(+), 38 deletions(-)

diff --git a/common/usb_kbd.c b/common/usb_kbd.c
index ecc3085..e02529f 100644
--- a/common/usb_kbd.c
+++ b/common/usb_kbd.c
@@ -471,59 +471,72 @@ static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum)
 	return 1;
 }
 
+static int probe_usb_keyboard(struct usb_device *dev)
+{
+	char *stdinname;
+	struct stdio_dev usb_kbd_dev;
+	int error;
+
+	/* Try probing the keyboard */
+	if (usb_kbd_probe(dev, 0) != 1)
+		return -ENOENT;
+
+	/* Register the keyboard */
+	debug("USB KBD: register.\n");
+	memset(&usb_kbd_dev, 0, sizeof(struct stdio_dev));
+	strcpy(usb_kbd_dev.name, DEVNAME);
+	usb_kbd_dev.flags =  DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
+	usb_kbd_dev.getc = usb_kbd_getc;
+	usb_kbd_dev.tstc = usb_kbd_testc;
+	usb_kbd_dev.priv = (void *)dev;
+	error = stdio_register(&usb_kbd_dev);
+	if (error)
+		return error;
+
+	stdinname = getenv("stdin");
+#ifdef CONFIG_CONSOLE_MUX
+	error = iomux_doenv(stdin, stdinname);
+	if (error)
+		return error;
+#else
+	/* Check if this is the standard input device. */
+	if (strcmp(stdinname, DEVNAME))
+		return 1;
+
+	/* Reassign the console */
+	if (overwrite_console())
+		return 1;
+
+	error = console_assign(stdin, DEVNAME);
+	if (error)
+		return error;
+#endif
+
+	return 0;
+}
+
 /* Search for keyboard and register it if found. */
 int drv_usb_kbd_init(void)
 {
-	struct stdio_dev usb_kbd_dev;
-	struct usb_device *dev;
-	char *stdinname = getenv("stdin");
 	int error, i;
 
-	/* Scan all USB Devices */
+	debug("%s: Probing for keyboard\n", __func__);/* Scan all USB Devices */
 	for (i = 0; i < USB_MAX_DEVICE; i++) {
+		struct usb_device *dev;
+
 		/* Get USB device. */
 		dev = usb_get_dev_index(i);
 		if (!dev)
-			return -1;
+			break;
 
 		if (dev->devnum == -1)
 			continue;
 
-		/* Try probing the keyboard */
-		if (usb_kbd_probe(dev, 0) != 1)
-			continue;
-
-		/* Register the keyboard */
-		debug("USB KBD: register.\n");
-		memset(&usb_kbd_dev, 0, sizeof(struct stdio_dev));
-		strcpy(usb_kbd_dev.name, DEVNAME);
-		usb_kbd_dev.flags =  DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
-		usb_kbd_dev.getc = usb_kbd_getc;
-		usb_kbd_dev.tstc = usb_kbd_testc;
-		usb_kbd_dev.priv = (void *)dev;
-		error = stdio_register(&usb_kbd_dev);
-		if (error)
-			return error;
-
-#ifdef CONFIG_CONSOLE_MUX
-		error = iomux_doenv(stdin, stdinname);
-		if (error)
-			return error;
-#else
-		/* Check if this is the standard input device. */
-		if (strcmp(stdinname, DEVNAME))
-			return 1;
-
-		/* Reassign the console */
-		if (overwrite_console())
+		error = probe_usb_keyboard(dev);
+		if (!error)
 			return 1;
-
-		error = console_assign(stdin, DEVNAME);
-		if (error)
+		if (error && error != -ENOENT)
 			return error;
-#endif
-
-		return 1;
 	}
 
 	/* No USB Keyboard found */
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 46/80] dm: usb: Support driver model with USB keyboards
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (44 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 45/80] dm: usb: Split out the keyboard probe into its own function Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 18:45   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 47/80] dm: usb: tegra: Add vbus GPIOs for nyan Simon Glass
                   ` (34 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

Allow USB keyboards to work with driver model. The main difference is that
we can have multiple buses (each with its own device numbering) and each
bus must be scanned.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 common/usb_kbd.c | 34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/common/usb_kbd.c b/common/usb_kbd.c
index e02529f..24a1a56 100644
--- a/common/usb_kbd.c
+++ b/common/usb_kbd.c
@@ -8,6 +8,7 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 #include <common.h>
+#include <dm.h>
 #include <errno.h>
 #include <malloc.h>
 #include <stdio_dev.h>
@@ -520,7 +521,37 @@ int drv_usb_kbd_init(void)
 {
 	int error, i;
 
-	debug("%s: Probing for keyboard\n", __func__);/* Scan all USB Devices */
+	debug("%s: Probing for keyboard\n", __func__);
+#ifdef CONFIG_DM_USB
+	/*
+	 * TODO: We should add USB_DEVICE() declarations to each USB ethernet
+	 * driver and then most of this file can be removed.
+	 */
+	struct udevice *bus;
+	struct uclass *uc;
+	int ret;
+
+	ret = uclass_get(UCLASS_USB, &uc);
+	if (ret)
+		return ret;
+	uclass_foreach_dev(bus, uc) {
+		for (i = 0; i < USB_MAX_DEVICE; i++) {
+			struct usb_device *dev;
+
+			dev = usb_get_dev_index(bus, i); /* get device */
+			debug("i=%d, %p\n", i, dev);
+			if (!dev)
+				break; /* no more devices available */
+
+			error = probe_usb_keyboard(dev);
+			if (!error)
+				return 1;
+			if (error && error != -ENOENT)
+				return error;
+		} /* for */
+	}
+#else
+	/* Scan all USB Devices */
 	for (i = 0; i < USB_MAX_DEVICE; i++) {
 		struct usb_device *dev;
 
@@ -538,6 +569,7 @@ int drv_usb_kbd_init(void)
 		if (error && error != -ENOENT)
 			return error;
 	}
+#endif
 
 	/* No USB Keyboard found */
 	return -1;
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 47/80] dm: usb: tegra: Add vbus GPIOs for nyan
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (45 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 46/80] dm: usb: Support driver model with USB keyboards Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 19:09   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 48/80] dm: usb: Move struct usb_string to a common place Simon Glass
                   ` (33 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

These are needed to enable the USB bus (although not sufficient since it
still does not work).

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 arch/arm/dts/tegra124-nyan-big.dts | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/dts/tegra124-nyan-big.dts b/arch/arm/dts/tegra124-nyan-big.dts
index c1f35a0..9367193 100644
--- a/arch/arm/dts/tegra124-nyan-big.dts
+++ b/arch/arm/dts/tegra124-nyan-big.dts
@@ -230,6 +230,7 @@
 
 	usb at 7d000000 { /* Rear external USB port. */
 		status = "okay";
+		nvidia,vbus-gpio = <&gpio TEGRA_GPIO(N, 4) GPIO_ACTIVE_HIGH>;
 	};
 
 	usb-phy at 7d000000 {
@@ -246,6 +247,7 @@
 
 	usb at 7d008000 { /* Left external USB port. */
 		status = "okay";
+		nvidia,vbus-gpio = <&gpio TEGRA_GPIO(N, 5) GPIO_ACTIVE_HIGH>;
 	};
 
 	usb-phy at 7d008000 {
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 48/80] dm: usb: Move struct usb_string to a common place
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (46 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 47/80] dm: usb: tegra: Add vbus GPIOs for nyan Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 19:09   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 49/80] dm: usb: sandbox: Add a uclass for USB device emulation Simon Glass
                   ` (32 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

This is needed for sandbox USB device emulation, so move it to a place
where it can be found by things other than gadgets.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 include/linux/usb/ch9.h    | 13 +++++++++++++
 include/linux/usb/gadget.h | 13 -------------
 2 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h
index bd48704..10675b4 100644
--- a/include/linux/usb/ch9.h
+++ b/include/linux/usb/ch9.h
@@ -1002,4 +1002,17 @@ struct usb_set_sel_req {
  */
 #define USB_SELF_POWER_VBUS_MAX_DRAW		100
 
+/**
+ * struct usb_string - wraps a C string and its USB id
+ * @id:the (nonzero) ID for this string
+ * @s:the string, in UTF-8 encoding
+ *
+ * If you're using usb_gadget_get_string(), use this to wrap a string
+ * together with its ID.
+ */
+struct usb_string {
+	u8 id;
+	const char *s;
+};
+
 #endif /* __LINUX_USB_CH9_H */
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 9bccd45..bd409bc 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -806,19 +806,6 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver);
 /* utility to simplify dealing with string descriptors */
 
 /**
- * struct usb_string - wraps a C string and its USB id
- * @id:the (nonzero) ID for this string
- * @s:the string, in UTF-8 encoding
- *
- * If you're using usb_gadget_get_string(), use this to wrap a string
- * together with its ID.
- */
-struct usb_string {
-	u8			id;
-	const char		*s;
-};
-
-/**
  * struct usb_gadget_strings - a set of USB strings in a given language
  * @language:identifies the strings' language (0x0409 for en-us)
  * @strings:array of strings with their ids
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 49/80] dm: usb: sandbox: Add a uclass for USB device emulation
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (47 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 48/80] dm: usb: Move struct usb_string to a common place Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 19:09   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 50/80] dm: usb: sandbox: Reset emulation devices in usb stop() Simon Glass
                   ` (31 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

With sandbox we want to be able to emulate USB devices so that we can test
the USB stack. Add a uclass to support this. It implements the same
operations as a normal USB device driver, but in this case passes them on
to an emulation driver.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 Makefile                           |   1 +
 drivers/usb/Kconfig                |   2 +
 drivers/usb/emul/Kconfig           |   8 ++
 drivers/usb/emul/Makefile          |   8 ++
 drivers/usb/emul/usb-emul-uclass.c | 263 +++++++++++++++++++++++++++++++++++++
 include/dm/uclass-id.h             |   1 +
 include/usb.h                      |  64 ++++++++-
 7 files changed, 346 insertions(+), 1 deletion(-)
 create mode 100644 drivers/usb/emul/Kconfig
 create mode 100644 drivers/usb/emul/Makefile
 create mode 100644 drivers/usb/emul/usb-emul-uclass.c

diff --git a/Makefile b/Makefile
index 1b3ebe7..c389869 100644
--- a/Makefile
+++ b/Makefile
@@ -637,6 +637,7 @@ libs-y += drivers/spi/
 libs-$(CONFIG_FMAN_ENET) += drivers/net/fm/
 libs-$(CONFIG_SYS_FSL_DDR) += drivers/ddr/fsl/
 libs-y += drivers/serial/
+libs-y += drivers/usb/emul/
 libs-y += drivers/usb/eth/
 libs-y += drivers/usb/gadget/
 libs-y += drivers/usb/host/
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index a4414ef..637ef3d 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -51,6 +51,8 @@ config DM_USB
 
 source "drivers/usb/host/Kconfig"
 
+source "drivers/usb/emul/Kconfig"
+
 config USB_STORAGE
 	bool "USB Mass Storage support"
 	---help---
diff --git a/drivers/usb/emul/Kconfig b/drivers/usb/emul/Kconfig
new file mode 100644
index 0000000..ae1ab23
--- /dev/null
+++ b/drivers/usb/emul/Kconfig
@@ -0,0 +1,8 @@
+config USB_EMUL
+	bool "Support for USB device emulation"
+	depends on DM_USB && SANDBOX
+	help
+	  Since sandbox does not have access to a real USB bus, it is possible
+	  to use device emulators instead. This allows testing of the USB
+	  stack on sandbox without needing a real device, or any host machine
+	  USB resources.
diff --git a/drivers/usb/emul/Makefile b/drivers/usb/emul/Makefile
new file mode 100644
index 0000000..f75bbd8
--- /dev/null
+++ b/drivers/usb/emul/Makefile
@@ -0,0 +1,8 @@
+#
+# (C) Copyright 2015 Google, Inc
+# Written by Simon Glass <sjg@chromium.org>
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-$(CONFIG_USB_EMUL) += usb-emul-uclass.o
diff --git a/drivers/usb/emul/usb-emul-uclass.c b/drivers/usb/emul/usb-emul-uclass.c
new file mode 100644
index 0000000..205f2c5
--- /dev/null
+++ b/drivers/usb/emul/usb-emul-uclass.c
@@ -0,0 +1,263 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <usb.h>
+#include <dm/root.h>
+#include <dm/device-internal.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int copy_to_unicode(char *buff, int length, const char *str)
+{
+	int ptr;
+	int i;
+
+	if (length < 2)
+		return 0;
+	buff[1] = USB_DT_STRING;
+	for (ptr = 2, i = 0; ptr + 1 < length && *str; i++, ptr += 2) {
+		buff[ptr] = str[i];
+		buff[ptr + 1] = 0;
+	}
+	buff[0] = ptr;
+
+	return ptr;
+}
+
+static int usb_emul_get_string(struct usb_string *strings, int index,
+			       char *buff, int length)
+{
+	if (index == 0) {
+		char *desc = buff;
+
+		desc[0] = 4;
+		desc[1] = USB_DT_STRING;
+		desc[2] = 0x09;
+		desc[3] = 0x14;
+		return 4;
+	} else if (strings) {
+		struct usb_string *ptr;
+
+		for (ptr = strings; ptr->s; ptr++) {
+			if (ptr->id == index)
+				return copy_to_unicode(buff, length, ptr->s);
+		}
+	}
+
+	return -EINVAL;
+}
+
+static struct usb_generic_descriptor **find_descriptor(
+		struct usb_generic_descriptor **ptr, int type, int index)
+{
+	debug("%s: type=%x, index=%d\n", __func__, type, index);
+	for (; *ptr; ptr++) {
+		if ((*ptr)->bDescriptorType != type)
+			continue;
+		switch (type) {
+		case USB_DT_CONFIG: {
+			struct usb_config_descriptor *cdesc;
+
+			cdesc = (struct usb_config_descriptor *)*ptr;
+			if (cdesc && cdesc->bConfigurationValue == index)
+				return ptr;
+			break;
+		}
+		default:
+			return ptr;
+		}
+	}
+	debug("%s: config ptr=%p\n", __func__, *ptr);
+
+	return ptr;
+}
+
+static int usb_emul_get_descriptor(struct usb_dev_platdata *plat, int value,
+				   void *buffer, int length)
+{
+	struct usb_generic_descriptor **ptr;
+	int type = value >> 8;
+	int index = value & 0xff;
+	int upto, todo;
+
+	debug("%s: type=%d, index=%d, plat=%p\n", __func__, type, index, plat);
+	if (type == USB_DT_STRING) {
+		return usb_emul_get_string(plat->strings, index, buffer,
+					   length);
+	}
+
+	ptr = find_descriptor((struct usb_generic_descriptor **)plat->desc_list,
+			      type, index);
+	if (!ptr) {
+		debug("%s: Could not find descriptor type %d, index %d\n",
+		      __func__, type, index);
+		return -ENOENT;
+	}
+	for (upto = 0; *ptr && upto < length; ptr++, upto += todo) {
+		todo = min(length - upto, (int)(*ptr)->bLength);
+
+		memcpy(buffer + upto, *ptr, todo);
+	}
+
+	return upto ? upto : length ? -EIO : 0;
+}
+
+int usb_emul_find(struct udevice *bus, ulong pipe, struct udevice **emulp)
+{
+	int devnum = usb_pipedevice(pipe);
+	struct udevice *dev;
+	struct uclass *uc;
+	int ret;
+
+	*emulp = NULL;
+	ret = uclass_get(UCLASS_USB_EMUL, &uc);
+	if (ret)
+		return ret;
+	uclass_foreach_dev(dev, uc) {
+		struct usb_dev_platdata *udev = dev_get_parent_platdata(dev);
+
+		if (udev->devnum == devnum) {
+			debug("%s: Found emulator '%s', addr %d\n", __func__,
+			      dev->name, udev->devnum);
+			*emulp = dev;
+			return 0;
+		}
+	}
+
+	debug("%s: No emulator found, addr %d\n", __func__, devnum);
+	return -ENOENT;
+}
+
+int usb_emul_control(struct udevice *emul, struct usb_device *udev,
+		     unsigned long pipe, void *buffer, int length,
+		     struct devrequest *setup)
+{
+	struct dm_usb_ops *ops = usb_get_emul_ops(emul);
+	struct usb_dev_platdata *plat;
+	int ret;
+
+	/* We permit getting the descriptor before we are probed */
+	plat = dev_get_parent_platdata(emul);
+	if (!ops->control)
+		return -ENOSYS;
+	debug("%s: dev=%s\n", __func__, emul->name);
+	if (pipe == usb_rcvctrlpipe(udev, 0)) {
+		switch (setup->request) {
+		case USB_REQ_GET_DESCRIPTOR: {
+			return usb_emul_get_descriptor(plat, setup->value,
+						       buffer, length);
+		}
+		default:
+			ret = device_probe(emul);
+			if (ret)
+				return ret;
+			return ops->control(emul, udev, pipe, buffer, length,
+					    setup);
+		}
+	} else if (pipe == usb_snddefctrl(udev)) {
+		switch (setup->request) {
+		case USB_REQ_SET_ADDRESS:
+			debug("   ** set address %s %d\n", emul->name,
+			      setup->value);
+			plat->devnum = setup->value;
+			return 0;
+		default:
+			debug("requestsend =%x\n", setup->request);
+			break;
+		}
+	} else if (pipe == usb_sndctrlpipe(udev, 0)) {
+		switch (setup->request) {
+		case USB_REQ_SET_CONFIGURATION:
+			plat->configno = setup->value;
+			return 0;
+		default:
+			ret = device_probe(emul);
+			if (ret)
+				return ret;
+			return ops->control(emul, udev, pipe, buffer, length,
+					    setup);
+		}
+	}
+	debug("pipe=%lx\n", pipe);
+
+	return -EIO;
+}
+
+int usb_emul_bulk(struct udevice *emul, struct usb_device *udev,
+		  unsigned long pipe, void *buffer, int length)
+{
+	struct dm_usb_ops *ops = usb_get_emul_ops(emul);
+	int ret;
+
+	/* We permit getting the descriptor before we are probed */
+	if (!ops->bulk)
+		return -ENOSYS;
+	debug("%s: dev=%s\n", __func__, emul->name);
+	ret = device_probe(emul);
+	if (ret)
+		return ret;
+	return ops->bulk(emul, udev, pipe, buffer, length);
+}
+
+int usb_emul_setup_device(struct udevice *dev, int maxpacketsize,
+			  struct usb_string *strings, void **desc_list)
+{
+	struct usb_dev_platdata *plat = dev_get_parent_platdata(dev);
+	struct usb_generic_descriptor **ptr;
+	struct usb_config_descriptor *cdesc;
+	int upto;
+
+	plat->strings = strings;
+	plat->desc_list = (struct usb_generic_descriptor **)desc_list;
+
+	/* Fill in wTotalLength for each configuration descriptor */
+	ptr = plat->desc_list;
+	for (cdesc = NULL, upto = 0; *ptr; upto += (*ptr)->bLength, ptr++) {
+		debug("   - upto=%d, type=%d\n", upto, (*ptr)->bDescriptorType);
+		if ((*ptr)->bDescriptorType == USB_DT_CONFIG) {
+			if (cdesc) {
+				cdesc->wTotalLength = upto;
+				debug("%s: config %d length %d\n", __func__,
+				      cdesc->bConfigurationValue,
+				      cdesc->bLength);
+			}
+			cdesc = (struct usb_config_descriptor *)*ptr;
+			upto = 0;
+		}
+	}
+	if (cdesc) {
+		cdesc->wTotalLength = upto;
+		debug("%s: config %d length %d\n", __func__,
+		      cdesc->bConfigurationValue, cdesc->wTotalLength);
+	}
+
+	return 0;
+}
+
+int usb_emul_post_bind(struct udevice *dev)
+{
+	/* Scan the bus for devices */
+	return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
+}
+
+void usb_emul_reset(struct udevice *dev)
+{
+	struct usb_dev_platdata *plat = dev_get_parent_platdata(dev);
+
+	plat->devnum = 0;
+	plat->configno = 0;
+}
+
+UCLASS_DRIVER(usb_emul) = {
+	.id		= UCLASS_USB_EMUL,
+	.name		= "usb_emul",
+	.post_bind	= usb_emul_post_bind,
+	.per_child_auto_alloc_size = sizeof(struct usb_device),
+	.per_child_platdata_auto_alloc_size = sizeof(struct usb_dev_platdata),
+};
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index 42a6f1f..2d0a145 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -21,6 +21,7 @@ enum uclass_id {
 	UCLASS_SPI_EMUL,	/* sandbox SPI device emulator */
 	UCLASS_I2C_EMUL,	/* sandbox I2C device emulator */
 	UCLASS_PCI_EMUL,	/* sandbox PCI device emulator */
+	UCLASS_USB_EMUL,	/* sandbox USB bus device emulator */
 	UCLASS_SIMPLE_BUS,
 
 	/* U-Boot uclasses start here */
diff --git a/include/usb.h b/include/usb.h
index 799b0c3..b449074 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -179,7 +179,8 @@ enum usb_init_type {
 	defined(CONFIG_USB_BLACKFIN) || defined(CONFIG_USB_AM35X) || \
 	defined(CONFIG_USB_MUSB_DSPS) || defined(CONFIG_USB_MUSB_AM35X) || \
 	defined(CONFIG_USB_MUSB_OMAP2PLUS) || defined(CONFIG_USB_MUSB_SUNXI) || \
-	defined(CONFIG_USB_XHCI) || defined(CONFIG_USB_DWC2)
+	defined(CONFIG_USB_XHCI) || defined(CONFIG_USB_DWC2) || \
+	defined(CONFIG_USB_EMUL)
 
 int usb_lowlevel_init(int index, enum usb_init_type init, void **controller);
 int usb_lowlevel_stop(int index);
@@ -848,4 +849,65 @@ int usb_new_device(struct usb_device *dev);
 
 int usb_alloc_device(struct usb_device *dev);
 
+/**
+ * usb_emul_setup_device() - Set up a new USB device emulation
+ *
+ * This is normally called when a new emulation device is bound. It tells
+ * the USB emulation uclass about the features of the emulator.
+ *
+ * @dev:		Emulation device
+ * @maxpacketsize:	Maximum packet size (e.g. PACKET_SIZE_64)
+ * @strings:		List of USB string descriptors, terminated by a NULL
+ *			entry
+ * @desc_list:		List of points or USB descriptors, terminated by NULL.
+ *			The first entry must be struct usb_device_descriptor,
+ *			and others follow on after that.
+ * @return 0 if OK, -ve on error
+ */
+int usb_emul_setup_device(struct udevice *dev, int maxpacketsize,
+			  struct usb_string *strings, void **desc_list);
+
+/**
+ * usb_emul_control() - Send a control packet to an emulator
+ *
+ * @emul:	Emulator device
+ * @udev:	USB device (which the emulator is causing to appear)
+ * See struct dm_usb_ops for details on other parameters
+ * @return 0 if OK, -ve on error
+ */
+int usb_emul_control(struct udevice *emul, struct usb_device *udev,
+		     unsigned long pipe, void *buffer, int length,
+		     struct devrequest *setup);
+
+/**
+ * usb_emul_bulk() - Send a bulk packet to an emulator
+ *
+ * @emul:	Emulator device
+ * @udev:	USB device (which the emulator is causing to appear)
+ * See struct dm_usb_ops for details on other parameters
+ * @return 0 if OK, -ve on error
+ */
+int usb_emul_bulk(struct udevice *emul, struct usb_device *udev,
+		  unsigned long pipe, void *buffer, int length);
+
+/**
+ * usb_emul_find() - Find an emulator for a particular device
+ *
+ * Check @pipe to find a device number on bus @bus and return it.
+ *
+ * @bus:	USB bus (controller)
+ * @pipe:	Describes pipe being used, and includes the device number
+ * @emulp:	Returns pointer to emulator, or NULL if not found
+ * @return 0 if found, -ve on error
+ */
+int usb_emul_find(struct udevice *bus, ulong pipe, struct udevice **emulp);
+
+/**
+ * usb_emul_reset() - Reset all emulators ready for use
+ *
+ * Clear out any address information in the emulators and make then ready for
+ * a new USB scan
+ */
+void usb_emul_reset(struct udevice *dev);
+
 #endif /*_USB_H_ */
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 50/80] dm: usb: sandbox: Reset emulation devices in usb stop()
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (48 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 49/80] dm: usb: sandbox: Add a uclass for USB device emulation Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 19:10   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 51/80] dm: usb: sandbox: Add an emulator for USB flash devices Simon Glass
                   ` (30 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

These devices must have their addresses removed ready for the next USB
bus enumeration. Add this logic to usb_stop().

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/host/usb-uclass.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c
index 29ef5d9..714bc0e 100644
--- a/drivers/usb/host/usb-uclass.c
+++ b/drivers/usb/host/usb-uclass.c
@@ -93,6 +93,17 @@ int usb_stop(void)
 			err = ret;
 	}
 
+#ifdef CONFIG_SANDBOX
+	struct udevice *dev;
+
+	/* Reset all enulation devices */
+	ret = uclass_get(UCLASS_USB_EMUL, &uc);
+	if (ret)
+		return ret;
+
+	uclass_foreach_dev(dev, uc)
+		usb_emul_reset(dev);
+#endif
 	usb_stor_reset();
 	usb_hub_reset();
 	usb_started = 0;
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 51/80] dm: usb: sandbox: Add an emulator for USB flash devices
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (49 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 50/80] dm: usb: sandbox: Reset emulation devices in usb stop() Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 19:10   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 52/80] dm: usb: sandbox: Add an emulator for USB hub emulation Simon Glass
                   ` (29 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

This emulator supports USB enumeration and allows a local file to be provided
as the contents of the emulated flash stick. U-Boot can then use the file as
it would a normal device, with all access passing through the usb_stor layer
and the USB stack.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/emul/Makefile        |   1 +
 drivers/usb/emul/sandbox_flash.c | 423 +++++++++++++++++++++++++++++++++++++++
 include/dm/uclass-id.h           |   1 +
 3 files changed, 425 insertions(+)
 create mode 100644 drivers/usb/emul/sandbox_flash.c

diff --git a/drivers/usb/emul/Makefile b/drivers/usb/emul/Makefile
index f75bbd8..1d5acce 100644
--- a/drivers/usb/emul/Makefile
+++ b/drivers/usb/emul/Makefile
@@ -5,4 +5,5 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
+obj-$(CONFIG_USB_EMUL) += sandbox_flash.o
 obj-$(CONFIG_USB_EMUL) += usb-emul-uclass.o
diff --git a/drivers/usb/emul/sandbox_flash.c b/drivers/usb/emul/sandbox_flash.c
new file mode 100644
index 0000000..6e0808d
--- /dev/null
+++ b/drivers/usb/emul/sandbox_flash.c
@@ -0,0 +1,423 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <os.h>
+#include <scsi.h>
+#include <usb.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * This driver emulates a flash stick using the UFI command specification and
+ * the BBB (bulk/bulk/bulk) protocol. It supports only a single logical unit
+ * number (LUN 0).
+ */
+
+enum {
+	SANDBOX_FLASH_EP_OUT		= 1,	/* endpoints */
+	SANDBOX_FLASH_EP_IN		= 2,
+	SANDBOX_FLASH_BLOCK_LEN		= 512,
+};
+
+enum cmd_phase {
+	PHASE_START,
+	PHASE_DATA,
+	PHASE_STATUS,
+};
+
+/**
+ * struct sandbox_flash_priv - private state for this driver
+ *
+ * @error:	true if there is an error condition
+ * @alloc_len:	Allocation length from the last incoming command
+ * @transfer_len: Transfer length from CBW header
+ * @read_len:	Number of blocks of data left in the current read command
+ * @tag:	Tag value from last command
+ * @fd:		File descriptor of backing file
+ * @file_size:	Size of file in bytes
+ * @status_buff:	Data buffer for outgoing status
+ * @buff_used:	Number of bytes ready to transfer back to host
+ * @buff:	Data buffer for outgoing data
+ */
+struct sandbox_flash_priv {
+	bool error;
+	int alloc_len;
+	int transfer_len;
+	int read_len;
+	enum cmd_phase phase;
+	u32 tag;
+	int fd;
+	loff_t file_size;
+	struct umass_bbb_csw status;
+	int buff_used;
+	u8 buff[512];
+};
+
+struct sandbox_flash_plat {
+	const char *pathname;
+};
+
+struct scsi_inquiry_resp {
+	u8 type;
+	u8 flags;
+	u8 version;
+	u8 data_format;
+	u8 additional_len;
+	u8 spare[3];
+	char vendor[8];
+	char product[16];
+	char revision[4];
+};
+
+struct scsi_read_capacity_resp {
+	u32 last_block_addr;
+	u32 block_len;
+};
+
+struct __packed scsi_read10_req {
+	u8 cmd;
+	u8 lun_flags;
+	u32 lba;
+	u8 spare;
+	u16 transfer_len;
+	u8 spare2[3];
+};
+
+enum {
+	STRINGID_MANUFACTURER = 1,
+	STRINGID_PRODUCT,
+	STRINGID_SERIAL,
+
+	STRINGID_COUNT,
+};
+
+static struct usb_string flash_strings[] = {
+	{STRINGID_MANUFACTURER,	"sandbox"},
+	{STRINGID_PRODUCT,	"flash"},
+	{STRINGID_SERIAL,	"2345"},
+	{},
+};
+
+static struct usb_device_descriptor flash_device_desc = {
+	.bLength =		sizeof(flash_device_desc),
+	.bDescriptorType =	USB_DT_DEVICE,
+
+	.bcdUSB =		__constant_cpu_to_le16(0x0200),
+
+	.bDeviceClass =		0,
+	.bDeviceSubClass =	0,
+	.bDeviceProtocol =	0,
+
+	.idVendor =		__constant_cpu_to_le16(0x1234),
+	.idProduct =		__constant_cpu_to_le16(0x5678),
+	.iManufacturer =	STRINGID_MANUFACTURER,
+	.iProduct =		STRINGID_PRODUCT,
+	.iSerialNumber =	STRINGID_SERIAL,
+	.bNumConfigurations =	1,
+};
+
+static struct usb_config_descriptor flash_config0 = {
+	.bLength		= sizeof(flash_config0),
+	.bDescriptorType	= USB_DT_CONFIG,
+
+	/* wTotalLength is set up by usb-emul-uclass */
+	.bNumInterfaces		= 1,
+	.bConfigurationValue	= 0,
+	.iConfiguration		= 0,
+	.bmAttributes		= 1 << 7,
+	.bMaxPower		= 50,
+};
+
+static struct usb_interface_descriptor flash_interface0 = {
+	.bLength		= sizeof(flash_interface0),
+	.bDescriptorType	= USB_DT_INTERFACE,
+
+	.bInterfaceNumber	= 0,
+	.bAlternateSetting	= 0,
+	.bNumEndpoints		= 2,
+	.bInterfaceClass	= USB_CLASS_MASS_STORAGE,
+	.bInterfaceSubClass	= US_SC_UFI,
+	.bInterfaceProtocol	= US_PR_BULK,
+	.iInterface		= 0,
+};
+
+static struct usb_endpoint_descriptor flash_endpoint0_out = {
+	.bLength		= USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType	= USB_DT_ENDPOINT,
+
+	.bEndpointAddress	= SANDBOX_FLASH_EP_OUT,
+	.bmAttributes		= USB_ENDPOINT_XFER_BULK,
+	.wMaxPacketSize		= __constant_cpu_to_le16(1024),
+	.bInterval		= 0,
+};
+
+static struct usb_endpoint_descriptor flash_endpoint1_in = {
+	.bLength		= USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType	= USB_DT_ENDPOINT,
+
+	.bEndpointAddress	= SANDBOX_FLASH_EP_IN | USB_ENDPOINT_DIR_MASK,
+	.bmAttributes		= USB_ENDPOINT_XFER_BULK,
+	.wMaxPacketSize		= __constant_cpu_to_le16(1024),
+	.bInterval		= 0,
+};
+
+static void *flash_desc_list[] = {
+	&flash_device_desc,
+	&flash_config0,
+	&flash_interface0,
+	&flash_endpoint0_out,
+	&flash_endpoint1_in,
+	NULL,
+};
+
+static int sandbox_flash_control(struct udevice *dev, struct usb_device *udev,
+				 unsigned long pipe, void *buff, int len,
+				 struct devrequest *setup)
+{
+	struct sandbox_flash_priv *priv = dev_get_priv(dev);
+
+	if (pipe == usb_rcvctrlpipe(udev, 0)) {
+		switch (setup->request) {
+		case US_BBB_RESET:
+			priv->error = false;
+			return 0;
+		case US_BBB_GET_MAX_LUN:
+			*(char *)buff = '\0';
+			return 1;
+		default:
+			debug("request=%x\n", setup->request);
+			break;
+		}
+	}
+	debug("pipe=%lx\n", pipe);
+
+	return -EIO;
+}
+
+static void setup_fail_response(struct sandbox_flash_priv *priv)
+{
+	struct umass_bbb_csw *csw = &priv->status;
+
+	csw->dCSWSignature = CSWSIGNATURE;
+	csw->dCSWTag = priv->tag;
+	csw->dCSWDataResidue = 0;
+	csw->bCSWStatus = CSWSTATUS_FAILED;
+	priv->buff_used = 0;
+}
+
+/**
+ * setup_response() - set up a response to send back to the host
+ *
+ * @priv:	Sandbox flash private data
+ * @resp:	Response to send, or NULL if none
+ * @size:	Size of response
+ */
+static void setup_response(struct sandbox_flash_priv *priv, void *resp,
+			   int size)
+{
+	struct umass_bbb_csw *csw = &priv->status;
+
+	csw->dCSWSignature = CSWSIGNATURE;
+	csw->dCSWTag = priv->tag;
+	csw->dCSWDataResidue = 0;
+	csw->bCSWStatus = CSWSTATUS_GOOD;
+
+	assert(!resp || resp == priv->buff);
+	priv->buff_used = size;
+}
+
+static void handle_read(struct sandbox_flash_priv *priv, ulong lba,
+			ulong transfer_len)
+{
+	debug("%s: lba=%lx, transfer_len=%lx\n", __func__, lba, transfer_len);
+	if (priv->fd != -1) {
+		os_lseek(priv->fd, lba * SANDBOX_FLASH_BLOCK_LEN, OS_SEEK_SET);
+		priv->read_len = transfer_len;
+		setup_response(priv, priv->buff,
+			       transfer_len * SANDBOX_FLASH_BLOCK_LEN);
+	} else {
+		setup_fail_response(priv);
+	}
+}
+
+static int handle_ufi_command(struct sandbox_flash_priv *priv, const void *buff,
+			      int len)
+{
+	const struct SCSI_cmd_block *req = buff;
+
+	switch (*req->cmd) {
+	case SCSI_INQUIRY: {
+		struct scsi_inquiry_resp *resp = (void *)priv->buff;
+
+		priv->alloc_len = req->cmd[4];
+		memset(resp, '\0', sizeof(*resp));
+		resp->data_format = 1;
+		resp->additional_len = 0x1f;
+		strncpy(resp->vendor,
+			flash_strings[STRINGID_MANUFACTURER -  1].s,
+			sizeof(resp->vendor));
+		strncpy(resp->product, flash_strings[STRINGID_PRODUCT - 1].s,
+			sizeof(resp->product));
+		strncpy(resp->revision, "1.0", sizeof(resp->revision));
+		setup_response(priv, resp, sizeof(*resp));
+		break;
+	}
+	case SCSI_TST_U_RDY:
+		setup_response(priv, NULL, 0);
+		break;
+	case SCSI_RD_CAPAC: {
+		struct scsi_read_capacity_resp *resp = (void *)priv->buff;
+		uint blocks;
+
+		if (priv->file_size)
+			blocks = priv->file_size / SANDBOX_FLASH_BLOCK_LEN - 1;
+		else
+			blocks = 0;
+		resp->last_block_addr = cpu_to_be32(blocks);
+		resp->block_len = cpu_to_be32(SANDBOX_FLASH_BLOCK_LEN);
+		setup_response(priv, resp, sizeof(*resp));
+		break;
+	}
+	case SCSI_READ10: {
+		struct scsi_read10_req *req = (void *)buff;
+
+		handle_read(priv, be32_to_cpu(req->lba),
+			    be16_to_cpu(req->transfer_len));
+		break;
+	}
+	default:
+		debug("Command not supported: %x\n", req->cmd[0]);
+		return -EPROTONOSUPPORT;
+	}
+
+	priv->phase = priv->transfer_len ? PHASE_DATA : PHASE_STATUS;
+	return 0;
+}
+
+static int sandbox_flash_bulk(struct udevice *dev, struct usb_device *udev,
+			      unsigned long pipe, void *buff, int len)
+{
+	struct sandbox_flash_priv *priv = dev_get_priv(dev);
+	int ep = usb_pipeendpoint(pipe);
+	struct umass_bbb_cbw *cbw = buff;
+
+	debug("%s: dev=%s, pipe=%lx, ep=%x, len=%x, phase=%d\n", __func__,
+	      dev->name, pipe, ep, len, priv->phase);
+	switch (ep) {
+	case SANDBOX_FLASH_EP_OUT:
+		switch (priv->phase) {
+		case PHASE_START:
+			priv->alloc_len = 0;
+			priv->read_len = 0;
+			if (priv->error || len != UMASS_BBB_CBW_SIZE ||
+			    cbw->dCBWSignature != CBWSIGNATURE)
+				goto err;
+			if ((cbw->bCBWFlags & CBWFLAGS_SBZ) ||
+			    cbw->bCBWLUN != 0)
+				goto err;
+			if (cbw->bCDBLength < 1 || cbw->bCDBLength >= 0x10)
+				goto err;
+			priv->transfer_len = cbw->dCBWDataTransferLength;
+			priv->tag = cbw->dCBWTag;
+			return handle_ufi_command(priv, cbw->CBWCDB,
+						  cbw->bCDBLength);
+		case PHASE_DATA:
+			debug("data out\n");
+			break;
+		default:
+			break;
+		}
+	case SANDBOX_FLASH_EP_IN:
+		switch (priv->phase) {
+		case PHASE_DATA:
+			debug("data in, len=%x, alloc_len=%x, priv->read_len=%x\n",
+			      len, priv->alloc_len, priv->read_len);
+			if (priv->read_len) {
+				ulong bytes_read;
+
+				bytes_read = os_read(priv->fd, buff, len);
+				if (bytes_read != len)
+					return -EIO;
+				priv->read_len -= len / SANDBOX_FLASH_BLOCK_LEN;
+				if (!priv->read_len)
+					priv->phase = PHASE_STATUS;
+			} else {
+				if (priv->alloc_len && len > priv->alloc_len)
+					len = priv->alloc_len;
+				memcpy(buff, priv->buff, len);
+				priv->phase = PHASE_STATUS;
+			}
+			return len;
+		case PHASE_STATUS:
+			debug("status in, len=%x\n", len);
+			if (len > sizeof(priv->status))
+				len = sizeof(priv->status);
+			memcpy(buff, &priv->status, len);
+			priv->phase = PHASE_START;
+			return len;
+		default:
+			break;
+		}
+	}
+err:
+	priv->error = true;
+	debug("%s: Detected transfer error\n", __func__);
+	return 0;
+}
+
+static int sandbox_flash_ofdata_to_platdata(struct udevice *dev)
+{
+	struct sandbox_flash_plat *plat = dev_get_platdata(dev);
+	const void *blob = gd->fdt_blob;
+
+	plat->pathname = fdt_getprop(blob, dev->of_offset, "sandbox,filepath",
+				     NULL);
+
+	return 0;
+}
+
+static int sandbox_flash_bind(struct udevice *dev)
+{
+	return usb_emul_setup_device(dev, PACKET_SIZE_64, flash_strings,
+				     flash_desc_list);
+}
+
+static int sandbox_flash_probe(struct udevice *dev)
+{
+	struct sandbox_flash_plat *plat = dev_get_platdata(dev);
+	struct sandbox_flash_priv *priv = dev_get_priv(dev);
+
+	priv->fd = os_open(plat->pathname, OS_O_RDONLY);
+	if (priv->fd != -1)
+		return os_get_filesize(plat->pathname, &priv->file_size);
+
+	return 0;
+}
+
+static const struct dm_usb_ops sandbox_usb_flash_ops = {
+	.control	= sandbox_flash_control,
+	.bulk		= sandbox_flash_bulk,
+};
+
+static const struct udevice_id sandbox_usb_flash_ids[] = {
+	{ .compatible = "sandbox,usb-flash" },
+	{ }
+};
+
+U_BOOT_DRIVER(usb_sandbox_flash) = {
+	.name	= "usb_sandbox_flash",
+	.id	= UCLASS_USB_EMUL,
+	.of_match = sandbox_usb_flash_ids,
+	.bind	= sandbox_flash_bind,
+	.probe	= sandbox_flash_probe,
+	.ofdata_to_platdata = sandbox_flash_ofdata_to_platdata,
+	.ops	= &sandbox_usb_flash_ops,
+	.priv_auto_alloc_size = sizeof(struct sandbox_flash_priv),
+	.platdata_auto_alloc_size = sizeof(struct sandbox_flash_plat),
+};
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index 2d0a145..8ebe9fa 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -43,6 +43,7 @@ enum uclass_id {
 	UCLASS_USB,		/* USB bus */
 	UCLASS_USB_HUB,		/* USB hub */
 	UCLASS_USB_DEV_GENERIC,	/* USB generic device */
+	UCLASS_MASS_STORAGE,	/* Mass storage device */
 
 	UCLASS_COUNT,
 	UCLASS_INVALID = -1,
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 52/80] dm: usb: sandbox: Add an emulator for USB hub emulation
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (50 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 51/80] dm: usb: sandbox: Add an emulator for USB flash devices Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 19:10   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 53/80] dm: usb: sandbox: Add a driver for sandbox Simon Glass
                   ` (28 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

All USB controllers need a root hub. Add a sandbox emulation for this so
that we can add USB devices to sandbox.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/emul/Makefile      |   1 +
 drivers/usb/emul/sandbox_hub.c | 303 +++++++++++++++++++++++++++++++++++++++++
 include/usb_defs.h             |   3 +
 3 files changed, 307 insertions(+)
 create mode 100644 drivers/usb/emul/sandbox_hub.c

diff --git a/drivers/usb/emul/Makefile b/drivers/usb/emul/Makefile
index 1d5acce..8fd83d5 100644
--- a/drivers/usb/emul/Makefile
+++ b/drivers/usb/emul/Makefile
@@ -6,4 +6,5 @@
 #
 
 obj-$(CONFIG_USB_EMUL) += sandbox_flash.o
+obj-$(CONFIG_USB_EMUL) += sandbox_hub.o
 obj-$(CONFIG_USB_EMUL) += usb-emul-uclass.o
diff --git a/drivers/usb/emul/sandbox_hub.c b/drivers/usb/emul/sandbox_hub.c
new file mode 100644
index 0000000..280c708
--- /dev/null
+++ b/drivers/usb/emul/sandbox_hub.c
@@ -0,0 +1,303 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <usb.h>
+#include <dm/device-internal.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* We only support up to 8 */
+#define SANDBOX_NUM_PORTS	2
+
+struct sandbox_hub_platdata {
+	struct usb_dev_platdata plat;
+	int port;	/* Port number (numbered from 0) */
+};
+
+enum {
+	STRING_MANUFACTURER = 1,
+	STRING_PRODUCT,
+	STRING_SERIAL,
+
+	STRING_count,
+};
+
+static struct usb_string hub_strings[] = {
+	{STRING_MANUFACTURER,	"sandbox"},
+	{STRING_PRODUCT,	"hub"},
+	{STRING_SERIAL,		"2345"},
+};
+
+static struct usb_device_descriptor hub_device_desc = {
+	.bLength =		sizeof(hub_device_desc),
+	.bDescriptorType =	USB_DT_DEVICE,
+
+	.bcdUSB =		__constant_cpu_to_le16(0x0200),
+
+	.bDeviceClass =		USB_CLASS_HUB,
+	.bDeviceSubClass =	0,
+	.bDeviceProtocol =	0,
+
+	.idVendor =		__constant_cpu_to_le16(0x1234),
+	.idProduct =		__constant_cpu_to_le16(0x5678),
+	.iManufacturer =	STRING_MANUFACTURER,
+	.iProduct =		STRING_PRODUCT,
+	.iSerialNumber =	STRING_SERIAL,
+	.bNumConfigurations =	1,
+};
+
+static struct usb_config_descriptor hub_config1 = {
+	.bLength		= sizeof(hub_config1),
+	.bDescriptorType	= USB_DT_CONFIG,
+
+	/* wTotalLength is set up by usb-emul-uclass */
+	.bNumInterfaces		= 1,
+	.bConfigurationValue	= 0,
+	.iConfiguration		= 0,
+	.bmAttributes		= 1 << 7,
+	.bMaxPower		= 50,
+};
+
+static struct usb_interface_descriptor hub_interface0 = {
+	.bLength		= sizeof(hub_interface0),
+	.bDescriptorType	= USB_DT_INTERFACE,
+
+	.bInterfaceNumber	= 0,
+	.bAlternateSetting	= 0,
+	.bNumEndpoints		= 1,
+	.bInterfaceClass	= USB_CLASS_HUB,
+	.bInterfaceSubClass	= 0,
+	.bInterfaceProtocol	= US_PR_CB,
+	.iInterface		= 0,
+};
+
+static struct usb_endpoint_descriptor hub_endpoint0_in = {
+	.bLength		= USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType	= USB_DT_ENDPOINT,
+
+	.bEndpointAddress	= 1 | USB_DIR_IN,
+	.bmAttributes		= USB_ENDPOINT_XFER_INT,
+	.wMaxPacketSize		= __constant_cpu_to_le16(1024),
+	.bInterval		= 0,
+};
+
+static struct usb_hub_descriptor hub_desc = {
+	.bLength		= sizeof(hub_desc),
+	.bDescriptorType	= USB_DT_HUB,
+	.bNbrPorts		= SANDBOX_NUM_PORTS,
+	.wHubCharacteristics	= __constant_cpu_to_le16(1 << 0 | 1 << 3 |
+								1 << 7),
+	.bPwrOn2PwrGood		= 2,
+	.bHubContrCurrent	= 5,
+	.DeviceRemovable	= {0, 0xff}, /* all ports removeable */
+#if SANDBOX_NUM_PORTS > 8
+#error "This code sets up an incorrect mask"
+#endif
+};
+
+static void *hub_desc_list[] = {
+	&hub_device_desc,
+	&hub_config1,
+	&hub_interface0,
+	&hub_endpoint0_in,
+	&hub_desc,
+	NULL,
+};
+
+struct sandbox_hub_priv {
+	int status[SANDBOX_NUM_PORTS];
+	int change[SANDBOX_NUM_PORTS];
+};
+
+static struct udevice *hub_find_device(struct udevice *hub, int port)
+{
+	struct udevice *dev;
+
+	for (device_find_first_child(hub, &dev);
+	     dev;
+	     device_find_next_child(&dev)) {
+		struct sandbox_hub_platdata *plat;
+
+		plat = dev_get_parent_platdata(dev);
+		if (plat->port == port)
+			return dev;
+	}
+
+	return NULL;
+}
+
+static int clrset_post_state(struct udevice *hub, int port, int clear, int set)
+{
+	struct sandbox_hub_priv *priv = dev_get_priv(hub);
+	int *status = &priv->status[port];
+	int *change = &priv->change[port];
+	int ret = 0;
+
+	if ((clear | set) & USB_PORT_STAT_POWER) {
+		struct udevice *dev = hub_find_device(hub, port);
+
+		if (dev) {
+			if (set & USB_PORT_STAT_POWER) {
+				ret = device_probe(dev);
+				debug("%s: %s: power on, probed, ret=%d\n",
+				      __func__, dev->name, ret);
+				if (!ret) {
+					set |= USB_PORT_STAT_CONNECTION |
+						USB_PORT_STAT_ENABLE;
+				}
+
+			} else if (clear & USB_PORT_STAT_POWER) {
+				debug("%s: %s: power off, removed, ret=%d\n",
+				      __func__, dev->name, ret);
+				ret = device_remove(dev);
+				clear |= USB_PORT_STAT_CONNECTION;
+			}
+		}
+	}
+	*change |= *status & clear;
+	*change |= ~*status & set;
+	*change &= 0x1f;
+	*status = (*status & ~clear) | set;
+
+	return ret;
+}
+
+static int sandbox_hub_submit_control_msg(struct udevice *bus,
+					  struct usb_device *udev,
+					  unsigned long pipe,
+					  void *buffer, int length,
+					  struct devrequest *setup)
+{
+	struct sandbox_hub_priv *priv = dev_get_priv(bus);
+	int ret = 0;
+
+	if (pipe == usb_rcvctrlpipe(udev, 0)) {
+		switch (setup->requesttype) {
+		case USB_RT_HUB | USB_DIR_IN:
+			switch (setup->request) {
+			case USB_REQ_GET_STATUS: {
+				struct usb_hub_status *hubsts = buffer;
+
+				hubsts->wHubStatus = 0;
+				hubsts->wHubChange = 0;
+				udev->status = 0;
+				udev->act_len = sizeof(*hubsts);
+				return 0;
+			}
+			default:
+				debug("%s: rx ctl requesttype=%x, request=%x\n",
+				      __func__, setup->requesttype,
+				      setup->request);
+				break;
+			}
+		case USB_RT_PORT | USB_DIR_IN:
+			switch (setup->request) {
+			case USB_REQ_GET_STATUS: {
+				struct usb_port_status *portsts = buffer;
+				int port;
+
+				port = (setup->index & USB_HUB_PORT_MASK) - 1;
+				portsts->wPortStatus = priv->status[port];
+				portsts->wPortChange = priv->change[port];
+				udev->status = 0;
+				udev->act_len = sizeof(*portsts);
+				return 0;
+			}
+			}
+		default:
+			debug("%s: rx ctl requesttype=%x, request=%x\n",
+			      __func__, setup->requesttype, setup->request);
+			break;
+		}
+	} else if (pipe == usb_sndctrlpipe(udev, 0)) {
+		switch (setup->requesttype) {
+		case USB_RT_PORT:
+			switch (setup->request) {
+			case USB_REQ_SET_FEATURE: {
+				int port;
+
+				port = (setup->index & USB_HUB_PORT_MASK) - 1;
+				debug("set feature port=%x, feature=%x\n",
+				      port, setup->value);
+				if (setup->value < USB_PORT_FEAT_C_CONNECTION) {
+					ret = clrset_post_state(bus, port, 0,
+							1 << setup->value);
+				} else {
+					debug("  ** Invalid feature\n");
+				}
+				return ret;
+			}
+			case USB_REQ_CLEAR_FEATURE: {
+				int port;
+
+				port = (setup->index & USB_HUB_PORT_MASK) - 1;
+				debug("clear feature port=%x, feature=%x\n",
+				      port, setup->value);
+				if (setup->value < USB_PORT_FEAT_C_CONNECTION) {
+					ret = clrset_post_state(bus, port,
+							1 << setup->value, 0);
+				} else {
+					priv->change[port] &= 1 <<
+						(setup->value - 16);
+				}
+				udev->status = 0;
+				return 0;
+			}
+			default:
+				debug("%s: tx ctl requesttype=%x, request=%x\n",
+				      __func__, setup->requesttype,
+				      setup->request);
+				break;
+			}
+		default:
+			debug("%s: tx ctl requesttype=%x, request=%x\n",
+			      __func__, setup->requesttype, setup->request);
+			break;
+		}
+	}
+	debug("pipe=%lx\n", pipe);
+
+	return -EIO;
+}
+
+static int sandbox_hub_bind(struct udevice *dev)
+{
+	return usb_emul_setup_device(dev, PACKET_SIZE_64, hub_strings,
+				     hub_desc_list);
+}
+
+static int sandbox_child_post_bind(struct udevice *dev)
+{
+	struct sandbox_hub_platdata *plat = dev_get_parent_platdata(dev);
+
+	plat->port = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg", -1);
+
+	return 0;
+}
+
+static const struct dm_usb_ops sandbox_usb_hub_ops = {
+	.control	= sandbox_hub_submit_control_msg,
+};
+
+static const struct udevice_id sandbox_usb_hub_ids[] = {
+	{ .compatible = "sandbox,usb-hub" },
+	{ }
+};
+
+U_BOOT_DRIVER(usb_sandbox_hub) = {
+	.name	= "usb_sandbox_hub",
+	.id	= UCLASS_USB_EMUL,
+	.of_match = sandbox_usb_hub_ids,
+	.bind	= sandbox_hub_bind,
+	.ops	= &sandbox_usb_hub_ops,
+	.priv_auto_alloc_size = sizeof(struct sandbox_hub_priv),
+	.per_child_platdata_auto_alloc_size =
+			sizeof(struct sandbox_hub_platdata),
+	.child_post_bind = sandbox_child_post_bind,
+};
diff --git a/include/usb_defs.h b/include/usb_defs.h
index d7f7465..27ddc47 100644
--- a/include/usb_defs.h
+++ b/include/usb_defs.h
@@ -286,6 +286,9 @@
 #define HUB_CHANGE_LOCAL_POWER	0x0001
 #define HUB_CHANGE_OVERCURRENT	0x0002
 
+/* Mask for wIndex in get/set port feature */
+#define USB_HUB_PORT_MASK	0xf
+
 /*
  * CBI style
  */
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 53/80] dm: usb: sandbox: Add a driver for sandbox
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (51 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 52/80] dm: usb: sandbox: Add an emulator for USB hub emulation Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 19:10   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 54/80] dm: usb: dts: sandbox: Add some sample USB devices to sandbox Simon Glass
                   ` (27 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

This driver supports using emulation devices to provide a USB bus within
sandbox.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/host/Makefile      |   1 +
 drivers/usb/host/usb-sandbox.c | 117 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 118 insertions(+)
 create mode 100644 drivers/usb/host/usb-sandbox.c

diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 9419295..7658f87 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -7,6 +7,7 @@
 
 ifdef CONFIG_DM_USB
 obj-$(CONFIG_CMD_USB) += usb-uclass.o
+obj-$(CONFIG_SANDBOX) += usb-sandbox.o
 endif
 
 # ohci
diff --git a/drivers/usb/host/usb-sandbox.c b/drivers/usb/host/usb-sandbox.c
new file mode 100644
index 0000000..c5f9822
--- /dev/null
+++ b/drivers/usb/host/usb-sandbox.c
@@ -0,0 +1,117 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <usb.h>
+#include <dm/root.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static void usbmon_trace(struct udevice *bus, ulong pipe,
+			 struct devrequest *setup, struct udevice *emul)
+{
+	static const char types[] = "ZICB";
+	int type;
+
+	type = (pipe & USB_PIPE_TYPE_MASK) >> USB_PIPE_TYPE_SHIFT;
+	debug("0 0 S %c%c:%d:%03ld:%ld", types[type],
+	      pipe & USB_DIR_IN ? 'i' : 'o',
+	      bus->seq,
+	      (pipe & USB_PIPE_DEV_MASK) >> USB_PIPE_DEV_SHIFT,
+	      (pipe & USB_PIPE_EP_MASK) >> USB_PIPE_EP_SHIFT);
+	if (setup) {
+		debug(" s %02x %02x %04x %04x %04x", setup->requesttype,
+		      setup->request, setup->value, setup->index,
+		      setup->length);
+	}
+	debug(" %s", emul ? emul->name : "(no emul found)");
+
+	debug("\n");
+}
+
+static int sandbox_submit_control(struct udevice *bus,
+				      struct usb_device *udev,
+				      unsigned long pipe,
+				      void *buffer, int length,
+				      struct devrequest *setup)
+{
+	struct udevice *emul;
+	int ret;
+
+	/* Just use child of dev as emulator? */
+	debug("%s: bus=%s\n", __func__, bus->name);
+	ret = usb_emul_find(bus, pipe, &emul);
+	usbmon_trace(bus, pipe, setup, emul);
+	if (ret)
+		return ret;
+	ret = usb_emul_control(emul, udev, pipe, buffer, length, setup);
+	if (ret < 0) {
+		debug("ret=%d\n", ret);
+		udev->status = ret;
+		udev->act_len = 0;
+	} else {
+		udev->status = 0;
+		udev->act_len = ret;
+	}
+
+	return ret;
+}
+
+static int sandbox_submit_bulk(struct udevice *bus, struct usb_device *udev,
+			       unsigned long pipe, void *buffer, int length)
+{
+	struct udevice *emul;
+	int ret;
+
+	/* Just use child of dev as emulator? */
+	debug("%s: bus=%s\n", __func__, bus->name);
+	ret = usb_emul_find(bus, pipe, &emul);
+	usbmon_trace(bus, pipe, NULL, emul);
+	if (ret)
+		return ret;
+	ret = usb_emul_bulk(emul, udev, pipe, buffer, length);
+	if (ret < 0) {
+		debug("ret=%d\n", ret);
+		udev->status = ret;
+		udev->act_len = 0;
+	} else {
+		udev->status = 0;
+		udev->act_len = ret;
+	}
+
+	return ret;
+}
+
+static int sandbox_alloc_device(struct udevice *dev, struct usb_device *udev)
+{
+	return 0;
+}
+
+static int sandbox_usb_probe(struct udevice *dev)
+{
+	return 0;
+}
+
+static const struct dm_usb_ops sandbox_usb_ops = {
+	.control	= sandbox_submit_control,
+	.bulk		= sandbox_submit_bulk,
+	.alloc_device	= sandbox_alloc_device,
+};
+
+static const struct udevice_id sandbox_usb_ids[] = {
+	{ .compatible = "sandbox,usb" },
+	{ }
+};
+
+U_BOOT_DRIVER(usb_sandbox) = {
+	.name	= "usb_sandbox",
+	.id	= UCLASS_USB,
+	.of_match = sandbox_usb_ids,
+	.probe = sandbox_usb_probe,
+	.ops	= &sandbox_usb_ops,
+};
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 54/80] dm: usb: dts: sandbox: Add some sample USB devices to sandbox
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (52 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 53/80] dm: usb: sandbox: Add a driver for sandbox Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 19:10   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 55/80] dm: usb: Add support for USB ethernet devices with driver model Simon Glass
                   ` (26 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

These allow basic testing of the USB functionality within sandbox.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 arch/sandbox/dts/sandbox.dts | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts
index 7d050d9..03b540c 100644
--- a/arch/sandbox/dts/sandbox.dts
+++ b/arch/sandbox/dts/sandbox.dts
@@ -1,5 +1,7 @@
 /dts-v1/;
 
+#define USB_CLASS_HUB			9
+
 / {
 	#address-cells = <1>;
 	#size-cells = <1>;
@@ -219,4 +221,42 @@
 		reg = <0x90000000 0x1000>;
 		host-raw-interface = "lo";
 	};
+
+	usb at 0 {
+		compatible = "sandbox,usb";
+		status = "disabled";
+		hub {
+			compatible = "sandbox,usb-hub";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			flash-stick {
+				reg = <0>;
+				compatible = "sandbox,usb-flash";
+			};
+		};
+	};
+
+	usb at 1 {
+		compatible = "sandbox,usb";
+		hub {
+			compatible = "usb-hub";
+			usb,device-class = <USB_CLASS_HUB>;
+			hub-emul {
+				compatible = "sandbox,usb-hub";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				flash-stick {
+					reg = <0>;
+					compatible = "sandbox,usb-flash";
+					sandbox,filepath = "flash.bin";
+				};
+			};
+		};
+	};
+
+	usb at 2 {
+		compatible = "sandbox,usb";
+		status = "disabled";
+	};
+
 };
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 55/80] dm: usb: Add support for USB ethernet devices with driver model
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (53 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 54/80] dm: usb: dts: sandbox: Add some sample USB devices to sandbox Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 19:10   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 56/80] dm: usb: exynos: Add driver model support to exynos EHCI Simon Glass
                   ` (25 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

Add support for scanning USB etghernet devices with driver model. This mostly
involves scanning all buses since device numbering is not unique across
buses.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/eth/usb_ether.c | 52 ++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 44 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/eth/usb_ether.c b/drivers/usb/eth/usb_ether.c
index 7cb96e3..c72b7e4 100644
--- a/drivers/usb/eth/usb_ether.c
+++ b/drivers/usb/eth/usb_ether.c
@@ -5,7 +5,9 @@
  */
 
 #include <common.h>
+#include <dm.h>
 #include <usb.h>
+#include <dm/device-internal.h>
 
 #include "usb_ether.h"
 
@@ -118,8 +120,6 @@ static void probe_valid_drivers(struct usb_device *dev)
 int usb_host_eth_scan(int mode)
 {
 	int i, old_async;
-	struct usb_device *dev;
-
 
 	if (mode == 1)
 		printf("       scanning usb for ethernet devices... ");
@@ -138,23 +138,59 @@ int usb_host_eth_scan(int mode)
 	}
 
 	usb_max_eth_dev = 0;
+#ifdef CONFIG_DM_USB
+	/*
+	 * TODO: We should add USB_DEVICE() declarations to each USB ethernet
+	 * driver and then most of this file can be removed.
+	 */
+	struct udevice *bus;
+	struct uclass *uc;
+	int ret;
+
+	ret = uclass_get(UCLASS_USB, &uc);
+	if (ret)
+		return ret;
+	uclass_foreach_dev(bus, uc) {
+		for (i = 0; i < USB_MAX_DEVICE; i++) {
+			struct usb_device *dev;
+
+			dev = usb_get_dev_index(bus, i); /* get device */
+			debug("i=%d, %s\n", i, dev ? dev->dev->name : "(done)");
+			if (!dev)
+				break; /* no more devices available */
+
+			/*
+			 * find valid usb_ether driver for this device,
+			 * if any
+			 */
+			probe_valid_drivers(dev);
+
+			/* check limit */
+			if (usb_max_eth_dev == USB_MAX_ETH_DEV)
+				break;
+		} /* for */
+	}
+#else
 	for (i = 0; i < USB_MAX_DEVICE; i++) {
+		struct usb_device *dev;
+
 		dev = usb_get_dev_index(i); /* get device */
 		debug("i=%d\n", i);
-		if (dev == NULL)
+		if (!dev)
 			break; /* no more devices available */
 
 		/* find valid usb_ether driver for this device, if any */
 		probe_valid_drivers(dev);
 
 		/* check limit */
-		if (usb_max_eth_dev == USB_MAX_ETH_DEV) {
-			printf("max USB Ethernet Device reached: %d stopping\n",
-				usb_max_eth_dev);
+		if (usb_max_eth_dev == USB_MAX_ETH_DEV)
 			break;
-		}
 	} /* for */
-
+#endif
+	if (usb_max_eth_dev == USB_MAX_ETH_DEV) {
+		printf("max USB Ethernet Device reached: %d stopping\n",
+		       usb_max_eth_dev);
+	}
 	usb_disable_asynch(old_async); /* restore asynch value */
 	printf("%d Ethernet Device(s) found\n", usb_max_eth_dev);
 	if (usb_max_eth_dev > 0)
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 56/80] dm: usb: exynos: Add driver model support to exynos EHCI
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (54 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 55/80] dm: usb: Add support for USB ethernet devices with driver model Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 19:10   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 57/80] dm: usb: tegra: Remove the port_addr_clear_csc variable Simon Glass
                   ` (24 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

Update this driver with driver model support for USB.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/host/ehci-exynos.c | 112 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 111 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c
index f3c077d..86cf631 100644
--- a/drivers/usb/host/ehci-exynos.c
+++ b/drivers/usb/host/ehci-exynos.c
@@ -8,6 +8,7 @@
  */
 
 #include <common.h>
+#include <dm.h>
 #include <fdtdec.h>
 #include <libfdt.h>
 #include <malloc.h>
@@ -24,19 +25,73 @@
 /* Declare global data pointer */
 DECLARE_GLOBAL_DATA_PTR;
 
+#ifdef CONFIG_DM_USB
+struct exynos_ehci_platdata {
+	struct usb_platdata usb_plat;
+	fdt_addr_t hcd_base;
+	fdt_addr_t phy_base;
+	struct gpio_desc vbus_gpio;
+};
+#endif
+
 /**
  * Contains pointers to register base addresses
  * for the usb controller.
  */
 struct exynos_ehci {
+	struct ehci_ctrl ctrl;
 	struct exynos_usb_phy *usb;
 	struct ehci_hccr *hcd;
+#ifndef CONFIG_DM_USB
 	struct gpio_desc vbus_gpio;
+#endif
 };
 
+#ifndef CONFIG_DM_USB
 static struct exynos_ehci exynos;
+#endif
 
-#ifdef CONFIG_OF_CONTROL
+#ifdef CONFIG_DM_USB
+static int ehci_usb_ofdata_to_platdata(struct udevice *dev)
+{
+	struct exynos_ehci_platdata *plat = dev_get_platdata(dev);
+	const void *blob = gd->fdt_blob;
+	unsigned int node;
+	int depth;
+
+	/*
+	 * Get the base address for XHCI controller from the device node
+	 */
+	plat->hcd_base = dev_get_addr(dev);
+	if (plat->hcd_base == FDT_ADDR_T_NONE) {
+		debug("Can't get the XHCI register base address\n");
+		return -ENXIO;
+	}
+
+	depth = 0;
+	node = fdtdec_next_compatible_subnode(blob, dev->of_offset,
+				COMPAT_SAMSUNG_EXYNOS_USB_PHY, &depth);
+	if (node <= 0) {
+		debug("XHCI: Can't get device node for usb3-phy controller\n");
+		return -ENODEV;
+	}
+
+	/*
+	 * Get the base address for usbphy from the device node
+	 */
+	plat->phy_base = fdtdec_get_addr(blob, node, "reg");
+	if (plat->phy_base == FDT_ADDR_T_NONE) {
+		debug("Can't get the usbphy register address\n");
+		return -ENXIO;
+	}
+
+	/* Vbus gpio */
+	gpio_request_by_name(dev, "samsung,vbus-gpio", 0,
+			     &plat->vbus_gpio, GPIOD_IS_OUT);
+
+	return 0;
+}
+#else
 static int exynos_usb_parse_dt(const void *blob, struct exynos_ehci *exynos)
 {
 	fdt_addr_t addr;
@@ -215,6 +270,7 @@ static void reset_usb_phy(struct exynos_usb_phy *usb)
 	set_usbhost_phy_ctrl(POWER_USB_HOST_PHY_CTRL_DISABLE);
 }
 
+#ifndef CONFIG_DM_USB
 /*
  * EHCI-initialization
  * Create the appropriate control structures to manage
@@ -268,3 +324,57 @@ int ehci_hcd_stop(int index)
 
 	return 0;
 }
+#endif
+
+#ifdef CONFIG_DM_USB
+static int ehci_usb_probe(struct udevice *dev)
+{
+	struct exynos_ehci_platdata *plat = dev_get_platdata(dev);
+	struct exynos_ehci *ctx = dev_get_priv(dev);
+	struct ehci_hcor *hcor;
+
+	ctx->hcd = (struct ehci_hccr *)plat->hcd_base;
+	ctx->usb = (struct exynos_usb_phy *)plat->phy_base;
+	hcor = (struct ehci_hcor *)((uint32_t)ctx->hcd +
+			HC_LENGTH(ehci_readl(&ctx->hcd->cr_capbase)));
+
+	/* setup the Vbus gpio here */
+	if (dm_gpio_is_valid(&plat->vbus_gpio))
+		dm_gpio_set_value(&plat->vbus_gpio, 1);
+
+	setup_usb_phy(ctx->usb);
+
+	return ehci_register(dev, ctx->hcd, hcor, NULL, 0, USB_INIT_HOST);
+}
+
+static int ehci_usb_remove(struct udevice *dev)
+{
+	struct exynos_ehci *ctx = dev_get_priv(dev);
+	int ret;
+
+	ret = ehci_deregister(dev);
+	if (ret)
+		return ret;
+	reset_usb_phy(ctx->usb);
+
+	return 0;
+}
+
+static const struct udevice_id ehci_usb_ids[] = {
+	{ .compatible = "samsung,exynos-ehci" },
+	{ }
+};
+
+U_BOOT_DRIVER(usb_ehci) = {
+	.name	= "ehci_exynos",
+	.id	= UCLASS_USB,
+	.of_match = ehci_usb_ids,
+	.ofdata_to_platdata = ehci_usb_ofdata_to_platdata,
+	.probe = ehci_usb_probe,
+	.remove = ehci_usb_remove,
+	.ops	= &ehci_usb_ops,
+	.priv_auto_alloc_size = sizeof(struct exynos_ehci),
+	.platdata_auto_alloc_size = sizeof(struct exynos_ehci_platdata),
+	.flags	= DM_FLAG_ALLOC_PRIV_DMA,
+};
+#endif
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 57/80] dm: usb: tegra: Remove the port_addr_clear_csc variable
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (55 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 56/80] dm: usb: exynos: Add driver model support to exynos EHCI Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-03-26  3:38   ` Jim Lin
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 58/80] dm: usb: tegra: Tidy up error handling and a static function Simon Glass
                   ` (23 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

This variable is a bit of a hack. We can obtain the same information from
the normal device config. This will fit better with driver model, where
global variables are best avoided.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/host/ehci-tegra.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 38333c7..464f55d 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -87,8 +87,6 @@ struct fdt_usb {
 
 static struct fdt_usb port[USB_PORTS_MAX];	/* List of valid USB ports */
 static unsigned port_count;			/* Number of available ports */
-/* Port that needs to clear CSC after Port Reset */
-static u32 port_addr_clear_csc;
 
 /*
  * This table has USB timing parameters for each Oscillator frequency we
@@ -206,7 +204,7 @@ static void tegra_ehci_powerup_fixup(struct ehci_ctrl *ctrl,
 	if (controller->has_hostpc)
 		*reg |= EHCI_PS_PE;
 
-	if (((u32)status_reg & TEGRA_USB_ADDR_MASK) != port_addr_clear_csc)
+	if (!config->has_legacy_mode)
 		return;
 	/* For EHCI_PS_CSC to be cleared in ehci_hcd.c */
 	if (ehci_readl(status_reg) & EHCI_PS_CSC)
@@ -683,8 +681,6 @@ static int fdt_decode_usb(const void *blob, int node, struct fdt_usb *config)
 	config->enabled = fdtdec_get_is_enabled(blob, node);
 	config->has_legacy_mode = fdtdec_get_bool(blob, node,
 						  "nvidia,has-legacy-mode");
-	if (config->has_legacy_mode)
-		port_addr_clear_csc = (u32) config->reg;
 	config->periph_id = clock_decode_periph_id(blob, node);
 	if (config->periph_id == PERIPH_ID_NONE) {
 		debug("%s: Missing/invalid peripheral ID\n", __func__);
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 58/80] dm: usb: tegra: Tidy up error handling and a static function
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (56 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 57/80] dm: usb: tegra: Remove the port_addr_clear_csc variable Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 19:10   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 59/80] dm: usb: tegra: Move most of init/uninit into a function Simon Glass
                   ` (22 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

Try to return useful error numbers where possible. Also avoid swallowing
an error number when it is returned by a called function.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/host/ehci-tegra.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 464f55d..04653e4 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -266,7 +266,8 @@ static void set_up_vbus(struct fdt_usb *config, enum usb_init_type init)
 	}
 }
 
-void usbf_reset_controller(struct fdt_usb *config, struct usb_ctlr *usbctlr)
+static void usbf_reset_controller(struct fdt_usb *config,
+				  struct usb_ctlr *usbctlr)
 {
 	/* Reset the USB controller with 2us delay */
 	reset_periph(config->periph_id, 2);
@@ -524,7 +525,7 @@ static int init_utmi_usb_controller(struct fdt_usb *config,
 		udelay(1);
 	}
 	if (!loop_count)
-		return -1;
+		return -ETIMEDOUT;
 
 	/* Disable ICUSB FS/LS transceiver */
 	clrbits_le32(&usbctlr->icusb_ctrl, IC_ENB1);
@@ -567,6 +568,7 @@ static int init_ulpi_usb_controller(struct fdt_usb *config,
 	int loop_count;
 	struct ulpi_viewport ulpi_vp;
 	struct usb_ctlr *usbctlr = config->reg;
+	int ret;
 
 	/* set up ULPI reference clock on pllp_out4 */
 	clock_enable(PERIPH_ID_DEV2_OUT);
@@ -612,9 +614,10 @@ static int init_ulpi_usb_controller(struct fdt_usb *config,
 	ulpi_vp.port_num = 0;
 	ulpi_vp.viewport_addr = (u32)&usbctlr->ulpi_viewport;
 
-	if (ulpi_init(&ulpi_vp)) {
+	ret = ulpi_init(&ulpi_vp);
+	if (ret) {
 		printf("Tegra ULPI viewport init failed\n");
-		return -1;
+		return ret;
 	}
 
 	ulpi_set_vbus(&ulpi_vp, 1, 1);
@@ -631,7 +634,7 @@ static int init_ulpi_usb_controller(struct fdt_usb *config,
 		udelay(1);
 	}
 	if (!loop_count)
-		return -1;
+		return -ETIMEDOUT;
 	clrbits_le32(&usbctlr->susp_ctrl, USB_SUSP_CLR);
 
 	return 0;
@@ -642,7 +645,7 @@ static int init_ulpi_usb_controller(struct fdt_usb *config,
 {
 	printf("No code to set up ULPI controller, please enable"
 			"CONFIG_USB_ULPI and CONFIG_USB_ULPI_VIEWPORT");
-	return -1;
+	return -ENOSYS;
 }
 #endif
 
@@ -669,7 +672,7 @@ static int fdt_decode_usb(const void *blob, int node, struct fdt_usb *config)
 		else {
 			debug("%s: Cannot decode dr_mode '%s'\n", __func__,
 			      mode);
-			return -FDT_ERR_NOTFOUND;
+			return -EINVAL;
 		}
 	} else {
 		config->dr_mode = DR_MODE_HOST;
@@ -684,7 +687,7 @@ static int fdt_decode_usb(const void *blob, int node, struct fdt_usb *config)
 	config->periph_id = clock_decode_periph_id(blob, node);
 	if (config->periph_id == PERIPH_ID_NONE) {
 		debug("%s: Missing/invalid peripheral ID\n", __func__);
-		return -FDT_ERR_NOTFOUND;
+		return -EINVAL;
 	}
 	gpio_request_by_name_nodev(blob, node, "nvidia,vbus-gpio", 0,
 				   &config->vbus_gpio, GPIOD_IS_OUT);
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 59/80] dm: usb: tegra: Move most of init/uninit into a function
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (57 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 58/80] dm: usb: tegra: Tidy up error handling and a static function Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 19:10   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 60/80] dm: usb: tegra: Add driver model support to tegra EHCI Simon Glass
                   ` (21 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

We want to use mostly the same init and uninit code for driver model, so move
the common part into two functions.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/host/ehci-tegra.c | 143 ++++++++++++++++++++++++------------------
 1 file changed, 81 insertions(+), 62 deletions(-)

diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 04653e4..940a583 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -703,6 +703,82 @@ static int fdt_decode_usb(const void *blob, int node, struct fdt_usb *config)
 	return 0;
 }
 
+int usb_common_init(struct fdt_usb *config, enum usb_init_type init)
+{
+	int ret = 0;
+
+	switch (init) {
+	case USB_INIT_HOST:
+		switch (config->dr_mode) {
+		case DR_MODE_HOST:
+		case DR_MODE_OTG:
+			break;
+		default:
+			printf("tegrausb: Invalid dr_mode %d for host mode\n",
+			       config->dr_mode);
+			return -1;
+		}
+		break;
+	case USB_INIT_DEVICE:
+		if (config->periph_id != PERIPH_ID_USBD) {
+			printf("tegrausb: Device mode only supported on first USB controller\n");
+			return -1;
+		}
+		if (!config->utmi) {
+			printf("tegrausb: Device mode only supported with UTMI PHY\n");
+			return -1;
+		}
+		switch (config->dr_mode) {
+		case DR_MODE_DEVICE:
+		case DR_MODE_OTG:
+			break;
+		default:
+			printf("tegrausb: Invalid dr_mode %d for device mode\n",
+			       config->dr_mode);
+			return -1;
+		}
+		break;
+	default:
+		printf("tegrausb: Unknown USB_INIT_* %d\n", init);
+		return -1;
+	}
+
+#ifndef CONFIG_DM_USB
+	/* skip init, if the port is already initialized */
+	if (config->initialized && config->init_type == init)
+		return 0;
+#endif
+
+	debug("%d, %d\n", config->utmi, config->ulpi);
+	if (config->utmi)
+		ret = init_utmi_usb_controller(config, init);
+	else if (config->ulpi)
+		ret = init_ulpi_usb_controller(config, init);
+	if (ret)
+		return ret;
+
+	set_up_vbus(config, init);
+
+	config->init_type = init;
+
+	return 0;
+}
+
+void usb_common_uninit(struct fdt_usb *priv)
+{
+	struct usb_ctlr *usbctlr;
+
+	usbctlr = priv->reg;
+
+	/* Stop controller */
+	writel(0, &usbctlr->usb_cmd);
+	udelay(1000);
+
+	/* Initiate controller reset */
+	writel(2, &usbctlr->usb_cmd);
+	udelay(1000);
+}
+
 static const struct ehci_ops tegra_ehci_ops = {
 	.set_usb_mode		= tegra_ehci_set_usbmode,
 	.get_port_speed		= tegra_ehci_get_port_speed,
@@ -795,6 +871,7 @@ int ehci_hcd_init(int index, enum usb_init_type init,
 {
 	struct fdt_usb *config;
 	struct usb_ctlr *usbctlr;
+	int ret;
 
 	if (index >= port_count)
 		return -1;
@@ -802,62 +879,14 @@ int ehci_hcd_init(int index, enum usb_init_type init,
 	config = &port[index];
 	ehci_set_controller_priv(index, config, &tegra_ehci_ops);
 
-	switch (init) {
-	case USB_INIT_HOST:
-		switch (config->dr_mode) {
-		case DR_MODE_HOST:
-		case DR_MODE_OTG:
-			break;
-		default:
-			printf("tegrausb: Invalid dr_mode %d for host mode\n",
-			       config->dr_mode);
-			return -1;
-		}
-		break;
-	case USB_INIT_DEVICE:
-		if (config->periph_id != PERIPH_ID_USBD) {
-			printf("tegrausb: Device mode only supported on first USB controller\n");
-			return -1;
-		}
-		if (!config->utmi) {
-			printf("tegrausb: Device mode only supported with UTMI PHY\n");
-			return -1;
-		}
-		switch (config->dr_mode) {
-		case DR_MODE_DEVICE:
-		case DR_MODE_OTG:
-			break;
-		default:
-			printf("tegrausb: Invalid dr_mode %d for device mode\n",
-			       config->dr_mode);
-			return -1;
-		}
-		break;
-	default:
-		printf("tegrausb: Unknown USB_INIT_* %d\n", init);
-		return -1;
-	}
-
-	/* skip init, if the port is already initialized */
-	if (config->initialized && config->init_type == init)
-		goto success;
-
-	if (config->utmi && init_utmi_usb_controller(config, init)) {
-		printf("tegrausb: Cannot init port %d\n", index);
-		return -1;
-	}
-
-	if (config->ulpi && init_ulpi_usb_controller(config, init)) {
+	ret = usb_common_init(config, init);
+	if (ret) {
 		printf("tegrausb: Cannot init port %d\n", index);
-		return -1;
+		return ret;
 	}
 
-	set_up_vbus(config, init);
-
 	config->initialized = 1;
-	config->init_type = init;
 
-success:
 	usbctlr = config->reg;
 	*hccr = (struct ehci_hccr *)&usbctlr->cap_length;
 	*hcor = (struct ehci_hcor *)&usbctlr->usb_cmd;
@@ -870,17 +899,7 @@ success:
  */
 int ehci_hcd_stop(int index)
 {
-	struct usb_ctlr *usbctlr;
-
-	usbctlr = port[index].reg;
-
-	/* Stop controller */
-	writel(0, &usbctlr->usb_cmd);
-	udelay(1000);
-
-	/* Initiate controller reset */
-	writel(2, &usbctlr->usb_cmd);
-	udelay(1000);
+	usb_common_uninit(&port[index]);
 
 	port[index].initialized = 0;
 
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 60/80] dm: usb: tegra: Add driver model support to tegra EHCI
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (58 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 59/80] dm: usb: tegra: Move most of init/uninit into a function Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 19:10   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 61/80] dm: usb: xhci: Use a function to get xhci_ctrl Simon Glass
                   ` (20 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

Update this driver with driver model support for USB.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/host/ehci-tegra.c | 83 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 83 insertions(+)

diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 940a583..66e5649 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -7,6 +7,7 @@
  */
 
 #include <common.h>
+#include <dm.h>
 #include <asm/errno.h>
 #include <asm/io.h>
 #include <asm-generic/gpio.h>
@@ -20,6 +21,8 @@
 
 #include "ehci.h"
 
+DECLARE_GLOBAL_DATA_PTR;
+
 #define USB1_ADDR_MASK	0xFFFF0000
 
 #define HOSTPC1_DEVLC	0x84
@@ -32,9 +35,11 @@
 	#endif
 #endif
 
+#ifndef CONFIG_DM_USB
 enum {
 	USB_PORTS_MAX	= 3,		/* Maximum ports we allow */
 };
+#endif
 
 /* Parameters we need for USB */
 enum {
@@ -71,12 +76,15 @@ enum usb_ctlr_type {
 
 /* Information about a USB port */
 struct fdt_usb {
+	struct ehci_ctrl ehci;
 	struct usb_ctlr *reg;	/* address of registers in physical memory */
 	unsigned utmi:1;	/* 1 if port has external tranceiver, else 0 */
 	unsigned ulpi:1;	/* 1 if port has external ULPI transceiver */
 	unsigned enabled:1;	/* 1 to enable, 0 to disable */
 	unsigned has_legacy_mode:1; /* 1 if this port has legacy mode */
+#ifndef CONFIG_DM_USB
 	unsigned initialized:1; /* has this port already been initialized? */
+#endif
 	enum usb_ctlr_type type;
 	enum usb_init_type init_type;
 	enum dr_mode dr_mode;	/* dual role mode */
@@ -85,8 +93,10 @@ struct fdt_usb {
 	struct gpio_desc phy_reset_gpio; /* GPIO to reset ULPI phy */
 };
 
+#ifndef CONFIG_DM_USB
 static struct fdt_usb port[USB_PORTS_MAX];	/* List of valid USB ports */
 static unsigned port_count;			/* Number of available ports */
+#endif
 
 /*
  * This table has USB timing parameters for each Oscillator frequency we
@@ -163,6 +173,7 @@ static const u8 utmip_elastic_limit = 16;
 static const u8 utmip_hs_sync_start_delay = 9;
 
 struct fdt_usb_controller {
+	/* TODO(sjg at chromium.org): Remove when we only use driver model */
 	int compat;
 	/* flag to determine whether controller supports hostpc register */
 	u32 has_hostpc:1;
@@ -785,6 +796,7 @@ static const struct ehci_ops tegra_ehci_ops = {
 	.powerup_fixup		= tegra_ehci_powerup_fixup,
 };
 
+#ifndef CONFIG_DM_USB
 /*
  * process_usb_nodes() - Process a list of USB nodes, adding them to our list
  *			of USB ports.
@@ -905,3 +917,74 @@ int ehci_hcd_stop(int index)
 
 	return 0;
 }
+#endif /* !CONFIG_DM_USB */
+
+#ifdef CONFIG_DM_USB
+static int ehci_usb_ofdata_to_platdata(struct udevice *dev)
+{
+	struct fdt_usb *priv = dev_get_priv(dev);
+	int ret;
+
+	ret = fdt_decode_usb(gd->fdt_blob, dev->of_offset, priv);
+	if (ret)
+		return ret;
+
+	priv->type = dev_get_driver_data(dev);
+
+	return 0;
+}
+
+static int ehci_usb_probe(struct udevice *dev)
+{
+	struct usb_platdata *plat = dev_get_platdata(dev);
+	struct fdt_usb *priv = dev_get_priv(dev);
+	struct ehci_hccr *hccr;
+	struct ehci_hcor *hcor;
+	static bool clk_done;
+	int ret;
+
+	ret = usb_common_init(priv, plat->init_type);
+	if (ret)
+		return ret;
+	hccr = (struct ehci_hccr *)&priv->reg->cap_length;
+	hcor = (struct ehci_hcor *)&priv->reg->usb_cmd;
+	if (!clk_done) {
+		config_clock(get_pll_timing(&fdt_usb_controllers[priv->type]));
+		clk_done = true;
+	}
+
+	return ehci_register(dev, hccr, hcor, &tegra_ehci_ops, 0,
+			     plat->init_type);
+}
+
+static int ehci_usb_remove(struct udevice *dev)
+{
+	int ret;
+
+	ret = ehci_deregister(dev);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static const struct udevice_id ehci_usb_ids[] = {
+	{ .compatible = "nvidia,tegra20-ehci", .data = USB_CTLR_T20 },
+	{ .compatible = "nvidia,tegra30-ehci", .data = USB_CTLR_T30 },
+	{ .compatible = "nvidia,tegra114-ehci", .data = USB_CTLR_T114 },
+	{ }
+};
+
+U_BOOT_DRIVER(usb_ehci) = {
+	.name	= "ehci_tegra",
+	.id	= UCLASS_USB,
+	.of_match = ehci_usb_ids,
+	.ofdata_to_platdata = ehci_usb_ofdata_to_platdata,
+	.probe = ehci_usb_probe,
+	.remove = ehci_usb_remove,
+	.ops	= &ehci_usb_ops,
+	.platdata_auto_alloc_size = sizeof(struct usb_platdata),
+	.priv_auto_alloc_size = sizeof(struct fdt_usb),
+	.flags	= DM_FLAG_ALLOC_PRIV_DMA,
+};
+#endif
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 61/80] dm: usb: xhci: Use a function to get xhci_ctrl
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (59 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 60/80] dm: usb: tegra: Add driver model support to tegra EHCI Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 19:11   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 62/80] dm: usb: xhci: Use explicit parameters for xhci_alloc_virt_device() Simon Glass
                   ` (19 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

Rather than getting this directly from struct usb_device, call a function
to obtain it. This will make it possible for driver model to provide it
another way.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/host/xhci-ring.c |  8 ++++----
 drivers/usb/host/xhci.c      | 19 ++++++++++++-------
 drivers/usb/host/xhci.h      |  2 ++
 3 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index b5aade9..246b697 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -353,7 +353,7 @@ static void giveback_first_trb(struct usb_device *udev, int ep_index,
 				int start_cycle,
 				struct xhci_generic_trb *start_trb)
 {
-	struct xhci_ctrl *ctrl = udev->controller;
+	struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
 
 	/*
 	 * Pass all the TRBs to the hardware at once and make sure this write
@@ -477,7 +477,7 @@ union xhci_trb *xhci_wait_for_event(struct xhci_ctrl *ctrl, trb_type expected)
  */
 static void abort_td(struct usb_device *udev, int ep_index)
 {
-	struct xhci_ctrl *ctrl = udev->controller;
+	struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
 	struct xhci_ring *ring =  ctrl->devs[udev->slot_id]->eps[ep_index].ring;
 	union xhci_trb *event;
 	u32 field;
@@ -554,7 +554,7 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe,
 	int start_cycle;
 	u32 field = 0;
 	u32 length_field = 0;
-	struct xhci_ctrl *ctrl = udev->controller;
+	struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
 	int slot_id = udev->slot_id;
 	int ep_index;
 	struct xhci_virt_device *virt_dev;
@@ -748,7 +748,7 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe,
 	u32 length_field;
 	u64 buf_64 = 0;
 	struct xhci_generic_trb *start_trb;
-	struct xhci_ctrl *ctrl = udev->controller;
+	struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
 	int slot_id = udev->slot_id;
 	int ep_index;
 	u32 trb_fields[4];
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 87f2972..ab39878 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -110,6 +110,11 @@ static struct descriptor {
 
 static struct xhci_ctrl xhcic[CONFIG_USB_MAX_CONTROLLER_COUNT];
 
+struct xhci_ctrl *xhci_get_ctrl(struct usb_device *udev)
+{
+	return udev->controller;
+}
+
 /**
  * Waits for as per specified amount of time
  * for the "result" to match with "done"
@@ -250,7 +255,7 @@ static int xhci_configure_endpoints(struct usb_device *udev, bool ctx_change)
 {
 	struct xhci_container_ctx *in_ctx;
 	struct xhci_virt_device *virt_dev;
-	struct xhci_ctrl *ctrl = udev->controller;
+	struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
 	union xhci_trb *event;
 
 	virt_dev = ctrl->devs[udev->slot_id];
@@ -298,7 +303,7 @@ static int xhci_set_configuration(struct usb_device *udev)
 	int ep_index;
 	unsigned int dir;
 	unsigned int ep_type;
-	struct xhci_ctrl *ctrl = udev->controller;
+	struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
 	int num_of_ep;
 	int ep_flag = 0;
 	u64 trb_64 = 0;
@@ -382,7 +387,7 @@ static int xhci_set_configuration(struct usb_device *udev)
 static int xhci_address_device(struct usb_device *udev)
 {
 	int ret = 0;
-	struct xhci_ctrl *ctrl = udev->controller;
+	struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
 	struct xhci_slot_ctx *slot_ctx;
 	struct xhci_input_control_ctx *ctrl_ctx;
 	struct xhci_virt_device *virt_dev;
@@ -463,8 +468,8 @@ static int xhci_address_device(struct usb_device *udev)
  */
 int usb_alloc_device(struct usb_device *udev)
 {
+	struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
 	union xhci_trb *event;
-	struct xhci_ctrl *ctrl = udev->controller;
 	int ret;
 
 	/*
@@ -510,7 +515,7 @@ int usb_alloc_device(struct usb_device *udev)
  */
 int xhci_check_maxpacket(struct usb_device *udev)
 {
-	struct xhci_ctrl *ctrl = udev->controller;
+	struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
 	unsigned int slot_id = udev->slot_id;
 	int ep_index = 0;	/* control endpoint */
 	struct xhci_container_ctx *in_ctx;
@@ -640,7 +645,7 @@ static int xhci_submit_root(struct usb_device *udev, unsigned long pipe,
 	int len, srclen;
 	uint32_t reg;
 	volatile uint32_t *status_reg;
-	struct xhci_ctrl *ctrl = udev->controller;
+	struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
 	struct xhci_hcor *hcor = ctrl->hcor;
 
 	if ((req->requesttype & USB_RT_PORT) &&
@@ -904,7 +909,7 @@ int
 submit_control_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
 					int length, struct devrequest *setup)
 {
-	struct xhci_ctrl *ctrl = udev->controller;
+	struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
 	int ret = 0;
 
 	if (usb_pipetype(pipe) != PIPE_CONTROL) {
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 6685ed2..6e76872 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1250,4 +1250,6 @@ int xhci_alloc_virt_device(struct usb_device *udev);
 int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr *hccr,
 		  struct xhci_hcor *hcor);
 
+struct xhci_ctrl *xhci_get_ctrl(struct usb_device *udev);
+
 #endif /* HOST_XHCI_H_ */
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 62/80] dm: usb: xhci: Use explicit parameters for xhci_alloc_virt_device()
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (60 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 61/80] dm: usb: xhci: Use a function to get xhci_ctrl Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 19:11   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 63/80] dm: usb: xhci: Use explicit parameters for xhci_setup_addressable_virt_dev() Simon Glass
                   ` (18 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

This function should not be delving into struct usb_device. Pass in the
parameters it needs directly.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/host/xhci-mem.c | 4 +---
 drivers/usb/host/xhci.c     | 2 +-
 drivers/usb/host/xhci.h     | 2 +-
 3 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 89908e8..4644ffa 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -352,12 +352,10 @@ static struct xhci_container_ctx
  * @param udev	pointer to USB deivce structure
  * @return 0 on success else -1 on failure
  */
-int xhci_alloc_virt_device(struct usb_device *udev)
+int xhci_alloc_virt_device(struct xhci_ctrl *ctrl, unsigned int slot_id)
 {
 	u64 byte_64 = 0;
-	unsigned int slot_id = udev->slot_id;
 	struct xhci_virt_device *virt_dev;
-	struct xhci_ctrl *ctrl = udev->controller;
 
 	/* Slot ID 0 is reserved */
 	if (ctrl->devs[slot_id]) {
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index ab39878..de006f7 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -491,7 +491,7 @@ int usb_alloc_device(struct usb_device *udev)
 
 	xhci_acknowledge_event(ctrl);
 
-	ret = xhci_alloc_virt_device(udev);
+	ret = xhci_alloc_virt_device(ctrl, udev->slot_id);
 	if (ret < 0) {
 		/*
 		 * TODO: Unsuccessful Address Device command shall leave
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 6e76872..00faa81 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1246,7 +1246,7 @@ void xhci_flush_cache(uint32_t addr, u32 type_len);
 void xhci_inval_cache(uint32_t addr, u32 type_len);
 void xhci_cleanup(struct xhci_ctrl *ctrl);
 struct xhci_ring *xhci_ring_alloc(unsigned int num_segs, bool link_trbs);
-int xhci_alloc_virt_device(struct usb_device *udev);
+int xhci_alloc_virt_device(struct xhci_ctrl *ctrl, unsigned int slot_id);
 int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr *hccr,
 		  struct xhci_hcor *hcor);
 
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 63/80] dm: usb: xhci: Use explicit parameters for xhci_setup_addressable_virt_dev()
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (61 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 62/80] dm: usb: xhci: Use explicit parameters for xhci_alloc_virt_device() Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 19:11   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 64/80] dm: usb: xhci: Factor out common init/uninit Simon Glass
                   ` (17 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

This function should not be delving into struct usb_device. Pass in the
parameters it needs directly.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/host/xhci-mem.c | 19 +++++++------------
 drivers/usb/host/xhci.c     | 29 ++++++++++++++++++++++-------
 drivers/usb/host/xhci.h     |  3 ++-
 3 files changed, 31 insertions(+), 20 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 4644ffa..1b55534 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -625,17 +625,16 @@ void xhci_slot_copy(struct xhci_ctrl *ctrl, struct xhci_container_ctx *in_ctx,
  * @param udev pointer to the Device Data Structure
  * @return returns negative value on failure else 0 on success
  */
-void xhci_setup_addressable_virt_dev(struct usb_device *udev)
+void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl, int slot_id,
+				     int speed, int hop_portnr)
 {
-	struct usb_device *hop = udev;
 	struct xhci_virt_device *virt_dev;
 	struct xhci_ep_ctx *ep0_ctx;
 	struct xhci_slot_ctx *slot_ctx;
 	u32 port_num = 0;
 	u64 trb_64 = 0;
-	struct xhci_ctrl *ctrl = udev->controller;
 
-	virt_dev = ctrl->devs[udev->slot_id];
+	virt_dev = ctrl->devs[slot_id];
 
 	BUG_ON(!virt_dev);
 
@@ -646,7 +645,7 @@ void xhci_setup_addressable_virt_dev(struct usb_device *udev)
 	/* Only the control endpoint is valid - one endpoint context */
 	slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(1) | 0);
 
-	switch (udev->speed) {
+	switch (speed) {
 	case USB_SPEED_SUPER:
 		slot_ctx->dev_info |= cpu_to_le32(SLOT_SPEED_SS);
 		break;
@@ -664,11 +663,7 @@ void xhci_setup_addressable_virt_dev(struct usb_device *udev)
 		BUG();
 	}
 
-	/* Extract the root hub port number */
-	if (hop->parent)
-		while (hop->parent->parent)
-			hop = hop->parent;
-	port_num = hop->portnr;
+	port_num = hop_portnr;
 	debug("port_num = %d\n", port_num);
 
 	slot_ctx->dev_info2 |=
@@ -678,9 +673,9 @@ void xhci_setup_addressable_virt_dev(struct usb_device *udev)
 	/* Step 4 - ring already allocated */
 	/* Step 5 */
 	ep0_ctx->ep_info2 = cpu_to_le32(CTRL_EP << EP_TYPE_SHIFT);
-	debug("SPEED = %d\n", udev->speed);
+	debug("SPEED = %d\n", speed);
 
-	switch (udev->speed) {
+	switch (speed) {
 	case USB_SPEED_SUPER:
 		ep0_ctx->ep_info2 |= cpu_to_le32(((512 & MAX_PACKET_MASK) <<
 					MAX_PACKET_SHIFT));
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index de006f7..774c3e6 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -384,7 +384,7 @@ static int xhci_set_configuration(struct usb_device *udev)
  * @param udev pointer to the Device Data Structure
  * @return 0 if successful else error code on failure
  */
-static int xhci_address_device(struct usb_device *udev)
+static int xhci_address_device(struct usb_device *udev, int root_portnr)
 {
 	int ret = 0;
 	struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
@@ -400,8 +400,9 @@ static int xhci_address_device(struct usb_device *udev)
 	 * This is the first Set Address since device plug-in
 	 * so setting up the slot context.
 	 */
-	debug("Setting up addressable devices\n");
-	xhci_setup_addressable_virt_dev(udev);
+	debug("Setting up addressable devices %p\n", ctrl->dcbaa);
+	xhci_setup_addressable_virt_dev(ctrl, udev->slot_id, udev->speed,
+					root_portnr);
 
 	ctrl_ctx = xhci_get_input_control_ctx(virt_dev->in_ctx);
 	ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG | EP0_FLAG);
@@ -903,11 +904,12 @@ submit_bulk_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
  * @param buffer	buffer to be read/written based on the request
  * @param length	length of the buffer
  * @param setup		Request type
+ * @param root_portnr	Root port number that this device is on
  * @return returns 0 if successful else -1 on failure
  */
-int
-submit_control_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
-					int length, struct devrequest *setup)
+static int _xhci_submit_control_msg(struct usb_device *udev, unsigned long pipe,
+				    void *buffer, int length,
+				    struct devrequest *setup, int root_portnr)
 {
 	struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
 	int ret = 0;
@@ -921,7 +923,7 @@ submit_control_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
 		return xhci_submit_root(udev, pipe, buffer, setup);
 
 	if (setup->request == USB_REQ_SET_ADDRESS)
-		return xhci_address_device(udev);
+		return xhci_address_device(udev, root_portnr);
 
 	if (setup->request == USB_REQ_SET_CONFIGURATION) {
 		ret = xhci_set_configuration(udev);
@@ -1007,6 +1009,19 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
 	return 0;
 }
 
+int submit_control_msg(struct usb_device *udev, unsigned long pipe,
+		       void *buffer, int length, struct devrequest *setup)
+{
+	struct usb_device *hop = udev;
+
+	if (hop->parent)
+		while (hop->parent->parent)
+			hop = hop->parent;
+
+	return _xhci_submit_control_msg(udev, pipe, buffer, length, setup,
+					hop->portnr);
+}
+
 /**
  * Stops the XHCI host controller
  * and cleans up all the related data structures
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 00faa81..916a5a4 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1232,7 +1232,8 @@ void xhci_endpoint_copy(struct xhci_ctrl *ctrl,
 void xhci_slot_copy(struct xhci_ctrl *ctrl,
 		    struct xhci_container_ctx *in_ctx,
 		    struct xhci_container_ctx *out_ctx);
-void xhci_setup_addressable_virt_dev(struct usb_device *udev);
+void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl, int slot_id,
+				     int speed, int hop_portnr);
 void xhci_queue_command(struct xhci_ctrl *ctrl, u8 *ptr,
 			u32 slot_id, u32 ep_index, trb_type cmd);
 void xhci_acknowledge_event(struct xhci_ctrl *ctrl);
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 64/80] dm: usb: xhci: Factor out common init/uninit
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (62 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 63/80] dm: usb: xhci: Use explicit parameters for xhci_setup_addressable_virt_dev() Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 19:11   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 65/80] dm: usb: Support driver model in XHCI Simon Glass
                   ` (16 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

Since driver model will want to use most of the same code for XHCI init
and uninit, put it in a separate function.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/host/xhci.c | 85 ++++++++++++++++++++++++++++++-------------------
 1 file changed, 52 insertions(+), 33 deletions(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 774c3e6..4d94618 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -936,33 +936,16 @@ static int _xhci_submit_control_msg(struct usb_device *udev, unsigned long pipe,
 	return xhci_ctrl_tx(udev, pipe, setup, length, buffer);
 }
 
-/**
- * Intialises the XHCI host controller
- * and allocates the necessary data structures
- *
- * @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)
+static int xhci_lowlevel_init(struct xhci_ctrl *ctrl)
 {
+	struct xhci_hccr *hccr;
+	struct xhci_hcor *hcor;
 	uint32_t val;
 	uint32_t val2;
 	uint32_t reg;
-	struct xhci_hccr *hccr;
-	struct xhci_hcor *hcor;
-	struct xhci_ctrl *ctrl;
-
-	if (xhci_hcd_init(index, &hccr, (struct xhci_hcor **)&hcor) != 0)
-		return -ENODEV;
-
-	if (xhci_reset(hcor) != 0)
-		return -ENODEV;
-
-	ctrl = &xhcic[index];
-
-	ctrl->hccr = hccr;
-	ctrl->hcor = hcor;
 
+	hccr = ctrl->hccr;
+	hcor = ctrl->hcor;
 	/*
 	 * Program the Number of Device Slots Enabled field in the CONFIG
 	 * register with the max value of slots the HC can handle.
@@ -1004,7 +987,20 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
 	reg = HC_VERSION(xhci_readl(&hccr->cr_capbase));
 	printf("USB XHCI %x.%02x\n", reg >> 8, reg & 0xff);
 
-	*controller = &xhcic[index];
+	return 0;
+}
+
+static int xhci_lowlevel_stop(struct xhci_ctrl *ctrl)
+{
+	u32 temp;
+
+	xhci_reset(ctrl->hcor);
+
+	debug("// Disabling event ring interrupts\n");
+	temp = xhci_readl(&ctrl->hcor->or_usbsts);
+	xhci_writel(&ctrl->hcor->or_usbsts, temp & ~STS_EINT);
+	temp = xhci_readl(&ctrl->ir_set->irq_pending);
+	xhci_writel(&ctrl->ir_set->irq_pending, ER_IRQ_DISABLE(temp));
 
 	return 0;
 }
@@ -1023,6 +1019,38 @@ int submit_control_msg(struct usb_device *udev, unsigned long pipe,
 }
 
 /**
+ * Intialises the XHCI host controller
+ * and allocates the necessary data structures
+ *
+ * @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)
+{
+	struct xhci_hccr *hccr;
+	struct xhci_hcor *hcor;
+	struct xhci_ctrl *ctrl;
+	int ret;
+
+	if (xhci_hcd_init(index, &hccr, (struct xhci_hcor **)&hcor) != 0)
+		return -ENODEV;
+
+	if (xhci_reset(hcor) != 0)
+		return -ENODEV;
+
+	ctrl = &xhcic[index];
+
+	ctrl->hccr = hccr;
+	ctrl->hcor = hcor;
+
+	ret = xhci_lowlevel_init(ctrl);
+
+	*controller = &xhcic[index];
+
+	return ret;
+}
+
+/**
  * Stops the XHCI host controller
  * and cleans up all the related data structures
  *
@@ -1032,18 +1060,9 @@ int submit_control_msg(struct usb_device *udev, unsigned long pipe,
 int usb_lowlevel_stop(int index)
 {
 	struct xhci_ctrl *ctrl = (xhcic + index);
-	u32 temp;
-
-	xhci_reset(ctrl->hcor);
-
-	debug("// Disabling event ring interrupts\n");
-	temp = xhci_readl(&ctrl->hcor->or_usbsts);
-	xhci_writel(&ctrl->hcor->or_usbsts, temp & ~STS_EINT);
-	temp = xhci_readl(&ctrl->ir_set->irq_pending);
-	xhci_writel(&ctrl->ir_set->irq_pending, ER_IRQ_DISABLE(temp));
 
+	xhci_lowlevel_stop(ctrl);
 	xhci_hcd_stop(index);
-
 	xhci_cleanup(ctrl);
 
 	return 0;
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 65/80] dm: usb: Support driver model in XHCI
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (63 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 64/80] dm: usb: xhci: Factor out common init/uninit Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 19:11   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 66/80] dm: usb: Rename the XHCI HCD to U-Boot Simon Glass
                   ` (15 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

Add driver model support in the XHCI support code so that it can be used by
XHCI USB drivers.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/host/xhci-mem.c |   1 +
 drivers/usb/host/xhci.c     | 179 ++++++++++++++++++++++++++++++++++++++++++--
 drivers/usb/host/xhci.h     |  24 ++++++
 3 files changed, 197 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 1b55534..79cb17e 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -15,6 +15,7 @@
  */
 
 #include <common.h>
+#include <dm.h>
 #include <asm/byteorder.h>
 #include <usb.h>
 #include <malloc.h>
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 4d94618..6d9d4a6 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -21,6 +21,7 @@
  */
 
 #include <common.h>
+#include <dm.h>
 #include <asm/byteorder.h>
 #include <usb.h>
 #include <malloc.h>
@@ -108,11 +109,24 @@ static struct descriptor {
 	},
 };
 
+#ifndef CONFIG_DM_USB
 static struct xhci_ctrl xhcic[CONFIG_USB_MAX_CONTROLLER_COUNT];
+#endif
 
 struct xhci_ctrl *xhci_get_ctrl(struct usb_device *udev)
 {
+#ifdef CONFIG_DM_USB
+	struct udevice *dev;
+
+	/* Find the USB controller */
+	for (dev = udev->dev;
+	     device_get_uclass_id(dev) != UCLASS_USB;
+	     dev = dev->parent)
+		;
+	return dev_get_priv(dev);
+#else
 	return udev->controller;
+#endif
 }
 
 /**
@@ -467,7 +481,7 @@ static int xhci_address_device(struct usb_device *udev, int root_portnr)
  * @param udev	pointer to the Device Data Structure
  * @return Returns 0 on succes else return error code on failure
  */
-int usb_alloc_device(struct usb_device *udev)
+int _xhci_alloc_device(struct usb_device *udev)
 {
 	struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
 	union xhci_trb *event;
@@ -505,6 +519,13 @@ int usb_alloc_device(struct usb_device *udev)
 	return 0;
 }
 
+#ifndef CONFIG_DM_USB
+int usb_alloc_device(struct usb_device *udev)
+{
+	return _xhci_alloc_device(udev);
+}
+#endif
+
 /*
  * Full speed devices may have a max packet size greater than 8 bytes, but the
  * USB core doesn't know that until it reads the first 8 bytes of the
@@ -864,9 +885,8 @@ unknown:
  * @param interval	interval of the interrupt
  * @return 0
  */
-int
-submit_int_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
-						int length, int interval)
+static int _xhci_submit_int_msg(struct usb_device *udev, unsigned long pipe,
+				void *buffer, int length, int interval)
 {
 	/*
 	 * TODO: Not addressing any interrupt type transfer requests
@@ -884,9 +904,8 @@ submit_int_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
  * @param length	length of the buffer
  * @return returns 0 if successful else -1 on failure
  */
-int
-submit_bulk_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
-								int length)
+static int _xhci_submit_bulk_msg(struct usb_device *udev, unsigned long pipe,
+				 void *buffer, int length)
 {
 	if (usb_pipetype(pipe) != PIPE_BULK) {
 		printf("non-bulk pipe (type=%lu)", usb_pipetype(pipe));
@@ -1005,6 +1024,7 @@ static int xhci_lowlevel_stop(struct xhci_ctrl *ctrl)
 	return 0;
 }
 
+#ifndef CONFIG_DM_USB
 int submit_control_msg(struct usb_device *udev, unsigned long pipe,
 		       void *buffer, int length, struct devrequest *setup)
 {
@@ -1018,6 +1038,18 @@ int submit_control_msg(struct usb_device *udev, unsigned long pipe,
 					hop->portnr);
 }
 
+int submit_bulk_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
+		    int length)
+{
+	return _xhci_submit_bulk_msg(udev, pipe, buffer, length);
+}
+
+int submit_int_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
+		   int length, int interval)
+{
+	return _xhci_submit_int_msg(udev, pipe, buffer, length, interval);
+}
+
 /**
  * Intialises the XHCI host controller
  * and allocates the necessary data structures
@@ -1067,3 +1099,136 @@ int usb_lowlevel_stop(int index)
 
 	return 0;
 }
+#endif /* CONFIG_DM_USB */
+
+#ifdef CONFIG_DM_USB
+/*
+static struct usb_device *get_usb_device(struct udevice *dev)
+{
+	struct usb_device *udev;
+
+	if (device_get_uclass_id(dev) == UCLASS_USB)
+		udev = dev_get_uclass_priv(dev);
+	else
+		udev = dev_get_parentdata(dev);
+
+	return udev;
+}
+*/
+static bool is_root_hub(struct udevice *dev)
+{
+	if (device_get_uclass_id(dev->parent) != UCLASS_USB_HUB)
+		return true;
+
+	return false;
+}
+
+static int xhci_submit_control_msg(struct udevice *dev, struct usb_device *udev,
+				   unsigned long pipe, void *buffer, int length,
+				   struct devrequest *setup)
+{
+	struct usb_device *uhop;
+	struct udevice *hub;
+	int root_portnr = 0;
+
+	debug("%s: dev='%s', udev=%p, udev->dev='%s', portnr=%d\n", __func__,
+	      dev->name, udev, udev->dev->name, udev->portnr);
+	hub = udev->dev;
+	if (device_get_uclass_id(hub) == UCLASS_USB_HUB) {
+		/* Figure out our port number on the root hub */
+		if (is_root_hub(hub)) {
+			root_portnr = udev->portnr;
+		} else {
+			while (!is_root_hub(hub->parent))
+				hub = hub->parent;
+			uhop = dev_get_parentdata(hub);
+			root_portnr = uhop->portnr;
+		}
+	}
+/*
+	struct usb_device *hop = udev;
+
+	if (hop->parent)
+		while (hop->parent->parent)
+			hop = hop->parent;
+*/
+	return _xhci_submit_control_msg(udev, pipe, buffer, length, setup,
+					root_portnr);
+}
+
+static int xhci_submit_bulk_msg(struct udevice *dev, struct usb_device *udev,
+				unsigned long pipe, void *buffer, int length)
+{
+	debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev);
+	return _xhci_submit_bulk_msg(udev, pipe, buffer, length);
+}
+
+static int xhci_submit_int_msg(struct udevice *dev, struct usb_device *udev,
+			       unsigned long pipe, void *buffer, int length,
+			       int interval)
+{
+	debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev);
+	return _xhci_submit_int_msg(udev, pipe, buffer, length, interval);
+}
+
+static int xhci_alloc_device(struct udevice *dev, struct usb_device *udev)
+{
+	debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev);
+	return _xhci_alloc_device(udev);
+}
+
+int xhci_register(struct udevice *dev, struct xhci_hccr *hccr,
+		  struct xhci_hcor *hcor)
+{
+	struct xhci_ctrl *ctrl = dev_get_priv(dev);
+	struct usb_bus_priv *priv = dev_get_uclass_priv(dev);
+	int ret;
+
+	debug("%s: dev='%s', ctrl=%p, hccr=%p, hcor=%p\n", __func__, dev->name,
+	      ctrl, hccr, hcor);
+
+	ctrl->dev = dev;
+
+	/*
+	 * XHCI needs to issue a Address device command to setup
+	 * proper device context structures, before it can interact
+	 * with the device. So a get_descriptor will fail before any
+	 * of that is done for XHCI unlike EHCI.
+	 */
+	priv->desc_before_addr = false;
+
+	ret = xhci_reset(hcor);
+	if (ret)
+		goto err;
+
+	ctrl->hccr = hccr;
+	ctrl->hcor = hcor;
+	ret = xhci_lowlevel_init(ctrl);
+	if (ret)
+		goto err;
+
+	return 0;
+err:
+	free(ctrl);
+	debug("%s: failed, ret=%d\n", __func__, ret);
+	return ret;
+}
+
+int xhci_deregister(struct udevice *dev)
+{
+	struct xhci_ctrl *ctrl = dev_get_priv(dev);
+
+	xhci_lowlevel_stop(ctrl);
+	xhci_cleanup(ctrl);
+
+	return 0;
+}
+
+struct dm_usb_ops xhci_usb_ops = {
+	.control = xhci_submit_control_msg,
+	.bulk = xhci_submit_bulk_msg,
+	.interrupt = xhci_submit_int_msg,
+	.alloc_device = xhci_alloc_device,
+};
+
+#endif
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 916a5a4..7f7cb75 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1200,6 +1200,9 @@ void xhci_hcd_stop(int index);
 #define XHCI_STS_CNR		(1 << 11)
 
 struct xhci_ctrl {
+#ifdef CONFIG_DM_USB
+	struct udevice *dev;
+#endif
 	struct xhci_hccr *hccr;	/* R/O registers, not need for volatile */
 	struct xhci_hcor *hcor;
 	struct xhci_doorbell_array *dba;
@@ -1251,6 +1254,27 @@ int xhci_alloc_virt_device(struct xhci_ctrl *ctrl, unsigned int slot_id);
 int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr *hccr,
 		  struct xhci_hcor *hcor);
 
+/**
+ * xhci_deregister() - Unregister an XHCI controller
+ *
+ * @dev:	Controller device
+ * @return 0 if registered, -ve on error
+ */
+int xhci_deregister(struct udevice *dev);
+
+/**
+ * xhci_register() - Register a new XHCI controller
+ *
+ * @dev:	Controller device
+ * @hccr:	Host controller control registers
+ * @hcor:	Not sure what this means
+ * @return 0 if registered, -ve on error
+ */
+int xhci_register(struct udevice *dev, struct xhci_hccr *hccr,
+		  struct xhci_hcor *hcor);
+
+extern struct dm_usb_ops xhci_usb_ops;
+
 struct xhci_ctrl *xhci_get_ctrl(struct usb_device *udev);
 
 #endif /* HOST_XHCI_H_ */
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 66/80] dm: usb: Rename the XHCI HCD to U-Boot
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (64 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 65/80] dm: usb: Support driver model in XHCI Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 19:11   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 67/80] dm: usb: exynos: Adjust XHCI driver to support driver model Simon Glass
                   ` (14 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

This should be "U-Boot", not "u-boot".

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/host/xhci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 6d9d4a6..7396c2d 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -704,7 +704,7 @@ static int xhci_submit_root(struct usb_device *udev, unsigned long pipe,
 				srclen = 4;
 				break;
 			case 1:	/* Vendor String  */
-				srcptr = "\16\3u\0-\0b\0o\0o\0t\0";
+				srcptr = "\16\3U\0-\0B\0o\0o\0t\0";
 				srclen = 14;
 				break;
 			case 2:	/* Product Name */
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 67/80] dm: usb: exynos: Adjust XHCI driver to support driver model
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (65 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 66/80] dm: usb: Rename the XHCI HCD to U-Boot Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 19:11   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 68/80] dm: usb: exynos: Use driver model for USB Simon Glass
                   ` (13 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

Support driver model in the exynos XHCI driver.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/host/xhci-exynos5.c | 120 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 119 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-exynos5.c b/drivers/usb/host/xhci-exynos5.c
index 3f86fdc..23c7ecc 100644
--- a/drivers/usb/host/xhci-exynos5.c
+++ b/drivers/usb/host/xhci-exynos5.c
@@ -14,6 +14,7 @@
  */
 
 #include <common.h>
+#include <dm.h>
 #include <fdtdec.h>
 #include <libfdt.h>
 #include <malloc.h>
@@ -32,20 +33,76 @@
 /* Declare global data pointer */
 DECLARE_GLOBAL_DATA_PTR;
 
+#ifdef CONFIG_DM_USB
+struct exynos_xhci_platdata {
+	fdt_addr_t hcd_base;
+	fdt_addr_t phy_base;
+	struct gpio_desc vbus_gpio;
+};
+#endif
+
 /**
  * Contains pointers to register base addresses
  * for the usb controller.
  */
 struct exynos_xhci {
+#ifdef CONFIG_DM_USB
+	struct usb_platdata usb_plat;
+#endif
+	struct xhci_ctrl ctrl;
 	struct exynos_usb3_phy *usb3_phy;
 	struct xhci_hccr *hcd;
 	struct dwc3 *dwc3_reg;
+#ifndef CONFIG_DM_USB
 	struct gpio_desc vbus_gpio;
+#endif
 };
 
+#ifndef CONFIG_DM_USB
 static struct exynos_xhci exynos;
+#endif
 
-#ifdef CONFIG_OF_CONTROL
+#ifdef CONFIG_DM_USB
+static int xhci_usb_ofdata_to_platdata(struct udevice *dev)
+{
+	struct exynos_xhci_platdata *plat = dev_get_platdata(dev);
+	const void *blob = gd->fdt_blob;
+	unsigned int node;
+	int depth;
+
+	/*
+	 * Get the base address for XHCI controller from the device node
+	 */
+	plat->hcd_base = fdtdec_get_addr(blob, dev->of_offset, "reg");
+	if (plat->hcd_base == FDT_ADDR_T_NONE) {
+		debug("Can't get the XHCI register base address\n");
+		return -ENXIO;
+	}
+
+	depth = 0;
+	node = fdtdec_next_compatible_subnode(blob, dev->of_offset,
+				COMPAT_SAMSUNG_EXYNOS5_USB3_PHY, &depth);
+	if (node <= 0) {
+		debug("XHCI: Can't get device node for usb3-phy controller\n");
+		return -ENODEV;
+	}
+
+	/*
+	 * Get the base address for usbphy from the device node
+	 */
+	plat->phy_base = fdtdec_get_addr(blob, node, "reg");
+	if (plat->phy_base == FDT_ADDR_T_NONE) {
+		debug("Can't get the usbphy register address\n");
+		return -ENXIO;
+	}
+
+	/* Vbus gpio */
+	gpio_request_by_name(dev, "samsung,vbus-gpio", 0,
+			     &plat->vbus_gpio, GPIOD_IS_OUT);
+
+	return 0;
+}
+#else
 static int exynos_usb3_parse_dt(const void *blob, struct exynos_xhci *exynos)
 {
 	fdt_addr_t addr;
@@ -283,6 +340,7 @@ static void exynos_xhci_core_exit(struct exynos_xhci *exynos)
 	exynos5_usb3_phy_exit(exynos->usb3_phy);
 }
 
+#ifndef CONFIG_DM_USB
 int xhci_hcd_init(int index, struct xhci_hccr **hccr, struct xhci_hcor **hcor)
 {
 	struct exynos_xhci *ctx = &exynos;
@@ -326,3 +384,63 @@ void xhci_hcd_stop(int index)
 
 	exynos_xhci_core_exit(ctx);
 }
+#endif
+
+#ifdef CONFIG_DM_USB
+static int xhci_usb_probe(struct udevice *dev)
+{
+	struct exynos_xhci_platdata *plat = dev_get_platdata(dev);
+	struct exynos_xhci *ctx = dev_get_priv(dev);
+	struct xhci_hcor *hcor;
+	int ret;
+
+	ctx->hcd = (struct xhci_hccr *)plat->hcd_base;
+	ctx->usb3_phy = (struct exynos_usb3_phy *)plat->phy_base;
+	ctx->dwc3_reg = (struct dwc3 *)((char *)(ctx->hcd) + DWC3_REG_OFFSET);
+	hcor = (struct xhci_hcor *)((uint32_t)ctx->hcd +
+			HC_LENGTH(xhci_readl(&ctx->hcd->cr_capbase)));
+
+	/* setup the Vbus gpio here */
+	if (dm_gpio_is_valid(&plat->vbus_gpio))
+		dm_gpio_set_value(&plat->vbus_gpio, 1);
+
+	ret = exynos_xhci_core_init(ctx);
+	if (ret) {
+		puts("XHCI: failed to initialize controller\n");
+		return -EINVAL;
+	}
+
+	return xhci_register(dev, ctx->hcd, hcor);
+}
+
+static int xhci_usb_remove(struct udevice *dev)
+{
+	struct exynos_xhci *ctx = dev_get_priv(dev);
+	int ret;
+
+	ret = xhci_deregister(dev);
+	if (ret)
+		return ret;
+	exynos_xhci_core_exit(ctx);
+
+	return 0;
+}
+
+static const struct udevice_id xhci_usb_ids[] = {
+	{ .compatible = "samsung,exynos5250-xhci" },
+	{ }
+};
+
+U_BOOT_DRIVER(usb_xhci) = {
+	.name	= "xhci_exynos",
+	.id	= UCLASS_USB,
+	.of_match = xhci_usb_ids,
+	.ofdata_to_platdata = xhci_usb_ofdata_to_platdata,
+	.probe = xhci_usb_probe,
+	.remove = xhci_usb_remove,
+	.ops	= &xhci_usb_ops,
+	.platdata_auto_alloc_size = sizeof(struct exynos_xhci_platdata),
+	.priv_auto_alloc_size = sizeof(struct exynos_xhci),
+	.flags	= DM_FLAG_ALLOC_PRIV_DMA,
+};
+#endif
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 68/80] dm: usb: exynos: Use driver model for USB
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (66 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 67/80] dm: usb: exynos: Adjust XHCI driver to support driver model Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 19:11   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 69/80] dm: usb: exynos: Enable both USB ports on snow Simon Glass
                   ` (12 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

Convert Exynos boards over to use driver model for USB. This does not remove
any unnecessary code so far.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 arch/arm/cpu/armv7/exynos/Kconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/cpu/armv7/exynos/Kconfig b/arch/arm/cpu/armv7/exynos/Kconfig
index eb86a7f..b042fba 100644
--- a/arch/arm/cpu/armv7/exynos/Kconfig
+++ b/arch/arm/cpu/armv7/exynos/Kconfig
@@ -86,6 +86,9 @@ config SYS_MALLOC_F
 config SYS_MALLOC_F_LEN
 	default 0x400
 
+config DM_USB
+	default y
+
 source "board/samsung/smdkv310/Kconfig"
 source "board/samsung/trats/Kconfig"
 source "board/samsung/universal_c210/Kconfig"
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 69/80] dm: usb: exynos: Enable both USB ports on snow
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (67 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 68/80] dm: usb: exynos: Use driver model for USB Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 19:11   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 70/80] dm: usb: exynos: Enable both EHCI and XHCI " Simon Glass
                   ` (11 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

Switch snow over to use both EHCI and XHCI at the same time.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 include/configs/snow.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/configs/snow.h b/include/configs/snow.h
index fe802f2..e024955 100644
--- a/include/configs/snow.h
+++ b/include/configs/snow.h
@@ -26,7 +26,9 @@
 #define CONFIG_ARCH_EARLY_INIT_R
 
 #define CONFIG_USB_XHCI
+#define CONFIG_USB_EHCI
 #define CONFIG_USB_XHCI_EXYNOS
+#define CONFIG_USB_EHCI_EXYNOS
 
 #define CONFIG_SYS_PROMPT		"snow # "
 #define CONFIG_IDENT_STRING		" for snow"
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 70/80] dm: usb: exynos: Enable both EHCI and XHCI on snow
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (68 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 69/80] dm: usb: exynos: Enable both USB ports on snow Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 19:11   ` Simon Glass
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 71/80] dm: usb: tegra: Move to driver model for USB Simon Glass
                   ` (10 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

Since we can support both controllers now, enable this in the device tree.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 arch/arm/dts/exynos5250-snow.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/dts/exynos5250-snow.dts b/arch/arm/dts/exynos5250-snow.dts
index d6777ee..668961a 100644
--- a/arch/arm/dts/exynos5250-snow.dts
+++ b/arch/arm/dts/exynos5250-snow.dts
@@ -133,6 +133,7 @@
 
 	ehci at 12110000 {
 		samsung,vbus-gpio = <&gpx1 1 GPIO_ACTIVE_HIGH>;
+		status = "okay";
 	};
 
 	xhci at 12000000 {
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 71/80] dm: usb: tegra: Move to driver model for USB
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (69 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 70/80] dm: usb: exynos: Enable both EHCI and XHCI " Simon Glass
@ 2015-03-25 18:22 ` Simon Glass
  2015-04-07 19:11   ` Simon Glass
  2015-03-25 18:23 ` [U-Boot] [PATCH v2 72/80] dm: usb: Add a generic descriptor struct Simon Glass
                   ` (9 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:22 UTC (permalink / raw)
  To: u-boot

Move Tegra boards over to driver model for USB EHCI. There are a few things
that are no-longer needed (e.g. in fdtdec.h) but these will be cleaned up
in a later patch to be applied one we are confident this change is fully
tested.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 arch/arm/mach-tegra/Kconfig | 3 +++
 board/nvidia/common/board.c | 2 ++
 2 files changed, 5 insertions(+)

diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index fccfd79..3625035 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -47,6 +47,9 @@ config DM_I2C
 config DM_GPIO
 	default y
 
+config DM_USB
+	default y
+
 source "arch/arm/mach-tegra/tegra20/Kconfig"
 source "arch/arm/mach-tegra/tegra30/Kconfig"
 source "arch/arm/mach-tegra/tegra114/Kconfig"
diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c
index 018dddb..a97035c 100644
--- a/board/nvidia/common/board.c
+++ b/board/nvidia/common/board.c
@@ -128,8 +128,10 @@ int board_init(void)
 
 #ifdef CONFIG_USB_EHCI_TEGRA
 	pin_mux_usb();
+#ifndef CONFIG_DM_USB
 	usb_process_devicetree(gd->fdt_blob);
 #endif
+#endif
 
 #ifdef CONFIG_LCD
 	tegra_lcd_check_next_stage(gd->fdt_blob, 0);
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 72/80] dm: usb: Add a generic descriptor struct
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (70 preceding siblings ...)
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 71/80] dm: usb: tegra: Move to driver model for USB Simon Glass
@ 2015-03-25 18:23 ` Simon Glass
  2015-04-07 19:11   ` Simon Glass
  2015-03-25 18:23 ` [U-Boot] [PATCH v2 73/80] dm: usb: Tidy up pipe value decoding Simon Glass
                   ` (8 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:23 UTC (permalink / raw)
  To: u-boot

This is useful for creating lists of descriptors, and is better than using
void * for this purpose.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 include/linux/usb/ch9.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h
index 10675b4..822fca0 100644
--- a/include/linux/usb/ch9.h
+++ b/include/linux/usb/ch9.h
@@ -379,6 +379,11 @@ struct usb_endpoint_descriptor {
 #define USB_DT_ENDPOINT_SIZE		7
 #define USB_DT_ENDPOINT_AUDIO_SIZE	9	/* Audio extension */
 
+/* Used to access common fields */
+struct usb_generic_descriptor {
+	__u8  bLength;
+	__u8  bDescriptorType;
+};
 
 /*
  * Endpoints
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 73/80] dm: usb: Tidy up pipe value decoding
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (71 preceding siblings ...)
  2015-03-25 18:23 ` [U-Boot] [PATCH v2 72/80] dm: usb: Add a generic descriptor struct Simon Glass
@ 2015-03-25 18:23 ` Simon Glass
  2015-04-07 19:12   ` Simon Glass
  2015-03-25 18:23 ` [U-Boot] [PATCH v2 74/80] dm: usb: sandbox: Enable USB Simon Glass
                   ` (7 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:23 UTC (permalink / raw)
  To: u-boot

Add a few more shifts/masks to make it easier to decode a pipe value (rather
than just building it). We need this for USB device emulation.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 include/usb_defs.h | 23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/include/usb_defs.h b/include/usb_defs.h
index 27ddc47..8214ba9 100644
--- a/include/usb_defs.h
+++ b/include/usb_defs.h
@@ -165,12 +165,14 @@
 #define USB_TEST_MODE_FORCE_ENABLE  0x05
 
 
-/* "pipe" definitions */
-
-#define PIPE_ISOCHRONOUS    0
-#define PIPE_INTERRUPT      1
-#define PIPE_CONTROL        2
-#define PIPE_BULK           3
+/*
+ * "pipe" definitions, use unsigned so we can compare reliably, since this
+ * value is shifted up to bits 30/31.
+ */
+#define PIPE_ISOCHRONOUS    0U
+#define PIPE_INTERRUPT      1U
+#define PIPE_CONTROL        2U
+#define PIPE_BULK           3U
 #define PIPE_DEVEP_MASK     0x0007ff00
 
 #define USB_ISOCHRONOUS    0
@@ -178,6 +180,15 @@
 #define USB_CONTROL        2
 #define USB_BULK           3
 
+#define USB_PIPE_TYPE_SHIFT	30
+#define USB_PIPE_TYPE_MASK	(3 << USB_PIPE_TYPE_SHIFT)
+
+#define USB_PIPE_DEV_SHIFT	8
+#define USB_PIPE_DEV_MASK	(0x7f << USB_PIPE_DEV_SHIFT)
+
+#define USB_PIPE_EP_SHIFT	15
+#define USB_PIPE_EP_MASK	(0xf << USB_PIPE_EP_SHIFT)
+
 /* USB-status codes: */
 #define USB_ST_ACTIVE           0x1		/* TD is active */
 #define USB_ST_STALLED          0x2		/* TD is stalled */
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 74/80] dm: usb: sandbox: Enable USB
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (72 preceding siblings ...)
  2015-03-25 18:23 ` [U-Boot] [PATCH v2 73/80] dm: usb: Tidy up pipe value decoding Simon Glass
@ 2015-03-25 18:23 ` Simon Glass
  2015-04-07 19:12   ` Simon Glass
  2015-03-25 18:23 ` [U-Boot] [PATCH v2 75/80] dm: test: Correct printf() output nit in 'dm uclass' Simon Glass
                   ` (6 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:23 UTC (permalink / raw)
  To: u-boot

Enable USB emulation and associated features so that USB can be used in
sandbox.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 configs/sandbox_defconfig | 4 ++++
 include/configs/sandbox.h | 2 ++
 2 files changed, 6 insertions(+)

diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index e23b959..3f4812c 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -15,3 +15,7 @@ CONFIG_CMD_CROS_EC=y
 CONFIG_PCI=y
 CONFIG_DM_PCI=y
 CONFIG_PCI_SANDBOX=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_EMUL=y
+CONFIG_USB_STORAGE=y
diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h
index 558ea2c..95cfce6 100644
--- a/include/configs/sandbox.h
+++ b/include/configs/sandbox.h
@@ -60,6 +60,7 @@
 #define CONFIG_CMD_GPT
 #define CONFIG_PARTITION_UUIDS
 #define CONFIG_EFI_PARTITION
+#define CONFIG_DOS_PARTITION
 
 /*
  * Size of malloc() pool, before and after relocation
@@ -200,5 +201,6 @@
 #define CONFIG_TPM_TIS_SANDBOX
 
 #define CONFIG_CMD_LZMADEC
+#define CONFIG_CMD_USB
 
 #endif
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 75/80] dm: test: Correct printf() output nit in 'dm uclass'
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (73 preceding siblings ...)
  2015-03-25 18:23 ` [U-Boot] [PATCH v2 74/80] dm: usb: sandbox: Enable USB Simon Glass
@ 2015-03-25 18:23 ` Simon Glass
  2015-04-07 19:12   ` Simon Glass
  2015-03-25 18:23 ` [U-Boot] [PATCH v2 76/80] dm: test: Allow 'dm test' to select a particular test to run Simon Glass
                   ` (5 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:23 UTC (permalink / raw)
  To: u-boot

Neither the hyphen nor the equals sign is needed.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 test/dm/cmd_dm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/dm/cmd_dm.c b/test/dm/cmd_dm.c
index 8d531fd..62e065c 100644
--- a/test/dm/cmd_dm.c
+++ b/test/dm/cmd_dm.c
@@ -79,7 +79,7 @@ static void dm_display_line(struct udevice *dev)
 	       dev->flags & DM_FLAG_ACTIVATED ? '*' : ' ',
 	       dev->name, (ulong)map_to_sysmem(dev));
 	if (dev->seq != -1 || dev->req_seq != -1)
-		printf(", seq-%d, (req=%d)", dev->seq, dev->req_seq);
+		printf(", seq %d, (req %d)", dev->seq, dev->req_seq);
 	puts("\n");
 }
 
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 76/80] dm: test: Allow 'dm test' to select a particular test to run
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (74 preceding siblings ...)
  2015-03-25 18:23 ` [U-Boot] [PATCH v2 75/80] dm: test: Correct printf() output nit in 'dm uclass' Simon Glass
@ 2015-03-25 18:23 ` Simon Glass
  2015-04-07 19:12   ` Simon Glass
  2015-03-25 18:23 ` [U-Boot] [PATCH v2 77/80] dm: usb: Add tests for the USB uclass Simon Glass
                   ` (4 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:23 UTC (permalink / raw)
  To: u-boot

As well as running all tests, it is useful to be able to run a selected test.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 include/dm/test.h   |  7 ++++---
 test/dm/cmd_dm.c    | 11 ++++++++---
 test/dm/test-main.c |  7 +++++--
 3 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/include/dm/test.h b/include/dm/test.h
index b310e5f..9c4b8d3 100644
--- a/include/dm/test.h
+++ b/include/dm/test.h
@@ -205,12 +205,13 @@ void dm_leak_check_start(struct dm_test_state *dms);
 
 
 /**
- * dm_test_main() - Run all the tests
+ * dm_test_main() - Run all or one of the tests
  *
- * This runs all available driver model tests
+ * This runs all available driver model tests, or a selected one
  *
+ * @test_name:	Name of test to run, or NULL for all
  * @return 0 if OK, -ve on error
  */
-int dm_test_main(void);
+int dm_test_main(const char *test_name);
 
 #endif
diff --git a/test/dm/cmd_dm.c b/test/dm/cmd_dm.c
index 62e065c..2f527e9 100644
--- a/test/dm/cmd_dm.c
+++ b/test/dm/cmd_dm.c
@@ -113,7 +113,12 @@ static int do_dm_dump_uclass(cmd_tbl_t *cmdtp, int flag, int argc,
 static int do_dm_test(cmd_tbl_t *cmdtp, int flag, int argc,
 			  char * const argv[])
 {
-	return dm_test_main();
+	const char *test_name = NULL;
+
+	if (argc > 0)
+		test_name = argv[0];
+
+	return dm_test_main(test_name);
 }
 #define TEST_HELP "\ndm test         Run tests"
 #else
@@ -133,7 +138,7 @@ static int do_dm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	cmd_tbl_t *test_cmd;
 	int ret;
 
-	if (argc != 2)
+	if (argc < 2)
 		return CMD_RET_USAGE;
 	test_cmd = find_cmd_tbl(argv[1], test_commands,
 				ARRAY_SIZE(test_commands));
@@ -148,7 +153,7 @@ static int do_dm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 }
 
 U_BOOT_CMD(
-	dm,	2,	1,	do_dm,
+	dm,	3,	1,	do_dm,
 	"Driver model low level access",
 	"tree         Dump driver model tree ('*' = activated)\n"
 	"dm uclass        Dump list of instances for each uclass"
diff --git a/test/dm/test-main.c b/test/dm/test-main.c
index 90ca810..a47bb37 100644
--- a/test/dm/test-main.c
+++ b/test/dm/test-main.c
@@ -65,7 +65,7 @@ static int dm_test_destroy(struct dm_test_state *dms)
 	return 0;
 }
 
-int dm_test_main(void)
+int dm_test_main(const char *test_name)
 {
 	struct dm_test *tests = ll_entry_start(struct dm_test, dm_test);
 	const int n_ents = ll_entry_count(struct dm_test, dm_test);
@@ -83,9 +83,12 @@ int dm_test_main(void)
 		ut_assert(gd->fdt_blob);
 	}
 
-	printf("Running %d driver model tests\n", n_ents);
+	if (!test_name)
+		printf("Running %d driver model tests\n", n_ents);
 
 	for (test = tests; test < tests + n_ents; test++) {
+		if (test_name && strcmp(test_name, test->name))
+			continue;
 		printf("Test: %s\n", test->name);
 		ut_assertok(dm_test_init(dms));
 
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 77/80] dm: usb: Add tests for the USB uclass
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (75 preceding siblings ...)
  2015-03-25 18:23 ` [U-Boot] [PATCH v2 76/80] dm: test: Allow 'dm test' to select a particular test to run Simon Glass
@ 2015-03-25 18:23 ` Simon Glass
  2015-04-07 19:12   ` Simon Glass
  2015-04-21  5:24   ` Joe Hershberger
  2015-03-25 18:23 ` [U-Boot] [PATCH v2 78/80] dm: usb: tegra: Drop legacy USB code Simon Glass
                   ` (3 subsequent siblings)
  80 siblings, 2 replies; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:23 UTC (permalink / raw)
  To: u-boot

This adds a simple test for probing and a functional test using the flash
stick emulator, which tests a large chunk of the USB stack.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 test/dm/Makefile   |  1 +
 test/dm/test-dm.sh |  3 +++
 test/dm/test.dts   | 41 +++++++++++++++++++++++++++++++++++++++++
 test/dm/usb.c      | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 95 insertions(+)
 create mode 100644 test/dm/usb.c

diff --git a/test/dm/Makefile b/test/dm/Makefile
index a2e2d23..fd9e29f 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -23,4 +23,5 @@ obj-$(CONFIG_DM_I2C) += i2c.o
 obj-$(CONFIG_DM_PCI) += pci.o
 obj-$(CONFIG_DM_SPI_FLASH) += sf.o
 obj-$(CONFIG_DM_SPI) += spi.o
+obj-$(CONFIG_DM_USB) += usb.o
 endif
diff --git a/test/dm/test-dm.sh b/test/dm/test-dm.sh
index 8ebc392..6158f68 100755
--- a/test/dm/test-dm.sh
+++ b/test/dm/test-dm.sh
@@ -10,5 +10,8 @@ dtc -I dts -O dtb test/dm/test.dts -o test/dm/test.dtb
 make O=sandbox sandbox_config || die "Cannot configure U-Boot"
 make O=sandbox -s -j${NUM_CPUS} || die "Cannot build U-Boot"
 dd if=/dev/zero of=spi.bin bs=1M count=2
+echo -n "this is a test" > testflash.bin
+dd if=/dev/zero bs=1M count=4 >>testflash.bin
 ./sandbox/u-boot -d test/dm/test.dtb -c "dm test"
 rm spi.bin
+rm testflash.bin
diff --git a/test/dm/test.dts b/test/dm/test.dts
index 0ab0916..d0c40be 100644
--- a/test/dm/test.dts
+++ b/test/dm/test.dts
@@ -20,6 +20,9 @@
 		testfdt8 = "/a-test";
 		eth0 = "/eth at 10002000";
 		eth5 = &eth_5;
+		usb0 = &usb_0;
+		usb1 = &usb_1;
+		usb2 = &usb_2;
 	};
 
 	uart0: serial {
@@ -186,4 +189,42 @@
 		fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x22>;
 	};
 
+	usb_0: usb at 0 {
+		compatible = "sandbox,usb";
+		status = "disabled";
+		hub {
+			compatible = "sandbox,usb-hub";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			flash-stick {
+				reg = <0>;
+				compatible = "sandbox,usb-flash";
+			};
+		};
+	};
+
+	usb_1: usb at 1 {
+		compatible = "sandbox,usb";
+		hub {
+			compatible = "usb-hub";
+			usb,device-class = <9>;
+			hub-emul {
+				compatible = "sandbox,usb-hub";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				flash-stick {
+					reg = <0>;
+					compatible = "sandbox,usb-flash";
+					sandbox,filepath = "testflash.bin";
+				};
+
+			};
+		};
+	};
+
+	usb_2: usb at 2 {
+		compatible = "sandbox,usb";
+		status = "disabled";
+	};
+
 };
diff --git a/test/dm/usb.c b/test/dm/usb.c
new file mode 100644
index 0000000..6ea86d7
--- /dev/null
+++ b/test/dm/usb.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <usb.h>
+#include <asm/io.h>
+#include <dm/test.h>
+#include <dm/ut.h>
+
+/* Test that sandbox USB works correctly */
+static int dm_test_usb_base(struct dm_test_state *dms)
+{
+	struct udevice *bus;
+
+	ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_USB, 0, &bus));
+	ut_assertok(uclass_get_device(UCLASS_USB, 0, &bus));
+	ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_USB, 2, &bus));
+
+	return 0;
+}
+DM_TEST(dm_test_usb_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/*
+ * Test that we can use the flash stick. This is more of a functional test. It
+ * covers scanning the bug, setting up a hub and a flash stick and reading
+ * data from the flash stick.
+ */
+static int dm_test_usb_flash(struct dm_test_state *dms)
+{
+	struct udevice *dev;
+	block_dev_desc_t *dev_desc;
+	char cmp[1024];
+
+	ut_assertok(usb_init());
+	ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
+	ut_assertok(get_device("usb", "0", &dev_desc));
+
+	/* Read a few blocks and look for the string we expect */
+	ut_asserteq(512, dev_desc->blksz);
+	memset(cmp, '\0', sizeof(cmp));
+	ut_asserteq(2, dev_desc->block_read(dev_desc->dev, 0, 2, cmp));
+	ut_assertok(strcmp(cmp, "this is a test"));
+
+	return 0;
+}
+DM_TEST(dm_test_usb_flash, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 78/80] dm: usb: tegra: Drop legacy USB code
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (76 preceding siblings ...)
  2015-03-25 18:23 ` [U-Boot] [PATCH v2 77/80] dm: usb: Add tests for the USB uclass Simon Glass
@ 2015-03-25 18:23 ` Simon Glass
  2015-06-11 20:19   ` Simon Glass
  2015-03-25 18:23 ` [U-Boot] [PATCH v2 79/80] dm: usb: exynos: " Simon Glass
                   ` (2 subsequent siblings)
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:23 UTC (permalink / raw)
  To: u-boot

Drop the code that doesn't use driver model for USB.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 board/nvidia/common/board.c   |   3 -
 drivers/usb/host/ehci-tegra.c | 150 ------------------------------------------
 include/fdtdec.h              |   3 -
 lib/fdtdec.c                  |   3 -
 4 files changed, 159 deletions(-)

diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c
index a97035c..91bc03b 100644
--- a/board/nvidia/common/board.c
+++ b/board/nvidia/common/board.c
@@ -128,9 +128,6 @@ int board_init(void)
 
 #ifdef CONFIG_USB_EHCI_TEGRA
 	pin_mux_usb();
-#ifndef CONFIG_DM_USB
-	usb_process_devicetree(gd->fdt_blob);
-#endif
 #endif
 
 #ifdef CONFIG_LCD
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 66e5649..bfa53ed 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -35,12 +35,6 @@ DECLARE_GLOBAL_DATA_PTR;
 	#endif
 #endif
 
-#ifndef CONFIG_DM_USB
-enum {
-	USB_PORTS_MAX	= 3,		/* Maximum ports we allow */
-};
-#endif
-
 /* Parameters we need for USB */
 enum {
 	PARAM_DIVN,                     /* PLL FEEDBACK DIVIDer */
@@ -82,9 +76,6 @@ struct fdt_usb {
 	unsigned ulpi:1;	/* 1 if port has external ULPI transceiver */
 	unsigned enabled:1;	/* 1 to enable, 0 to disable */
 	unsigned has_legacy_mode:1; /* 1 if this port has legacy mode */
-#ifndef CONFIG_DM_USB
-	unsigned initialized:1; /* has this port already been initialized? */
-#endif
 	enum usb_ctlr_type type;
 	enum usb_init_type init_type;
 	enum dr_mode dr_mode;	/* dual role mode */
@@ -93,11 +84,6 @@ struct fdt_usb {
 	struct gpio_desc phy_reset_gpio; /* GPIO to reset ULPI phy */
 };
 
-#ifndef CONFIG_DM_USB
-static struct fdt_usb port[USB_PORTS_MAX];	/* List of valid USB ports */
-static unsigned port_count;			/* Number of available ports */
-#endif
-
 /*
  * This table has USB timing parameters for each Oscillator frequency we
  * support. There are four sets of values:
@@ -173,8 +159,6 @@ static const u8 utmip_elastic_limit = 16;
 static const u8 utmip_hs_sync_start_delay = 9;
 
 struct fdt_usb_controller {
-	/* TODO(sjg at chromium.org): Remove when we only use driver model */
-	int compat;
 	/* flag to determine whether controller supports hostpc register */
 	u32 has_hostpc:1;
 	const unsigned *pll_parameter;
@@ -182,17 +166,14 @@ struct fdt_usb_controller {
 
 static struct fdt_usb_controller fdt_usb_controllers[USB_CTRL_COUNT] = {
 	{
-		.compat		= COMPAT_NVIDIA_TEGRA20_USB,
 		.has_hostpc	= 0,
 		.pll_parameter	= (const unsigned *)T20_usb_pll,
 	},
 	{
-		.compat		= COMPAT_NVIDIA_TEGRA30_USB,
 		.has_hostpc	= 1,
 		.pll_parameter	= (const unsigned *)T30_usb_pll,
 	},
 	{
-		.compat		= COMPAT_NVIDIA_TEGRA114_USB,
 		.has_hostpc	= 1,
 		.pll_parameter	= (const unsigned *)T114_usb_pll,
 	},
@@ -754,12 +735,6 @@ int usb_common_init(struct fdt_usb *config, enum usb_init_type init)
 		return -1;
 	}
 
-#ifndef CONFIG_DM_USB
-	/* skip init, if the port is already initialized */
-	if (config->initialized && config->init_type == init)
-		return 0;
-#endif
-
 	debug("%d, %d\n", config->utmi, config->ulpi);
 	if (config->utmi)
 		ret = init_utmi_usb_controller(config, init);
@@ -796,130 +771,6 @@ static const struct ehci_ops tegra_ehci_ops = {
 	.powerup_fixup		= tegra_ehci_powerup_fixup,
 };
 
-#ifndef CONFIG_DM_USB
-/*
- * process_usb_nodes() - Process a list of USB nodes, adding them to our list
- *			of USB ports.
- * @blob:	fdt blob
- * @node_list:	list of nodes to process (any <=0 are ignored)
- * @count:	number of nodes to process
- * @id:		controller type (enum usb_ctlr_type)
- *
- * Return:	0 - ok, -1 - error
- */
-static int process_usb_nodes(const void *blob, int node_list[], int count,
-			     enum usb_ctlr_type id)
-{
-	struct fdt_usb config;
-	int node, i;
-	int clk_done = 0;
-
-	port_count = 0;
-	for (i = 0; i < count; i++) {
-		if (port_count == USB_PORTS_MAX) {
-			printf("tegrausb: Cannot register more than %d ports\n",
-				USB_PORTS_MAX);
-			return -1;
-		}
-
-		debug("USB %d: ", i);
-		node = node_list[i];
-		if (!node)
-			continue;
-		if (fdt_decode_usb(blob, node, &config)) {
-			debug("Cannot decode USB node %s\n",
-			      fdt_get_name(blob, node, NULL));
-			return -1;
-		}
-		if (!clk_done) {
-			config_clock(get_pll_timing(
-					&fdt_usb_controllers[id]));
-			clk_done = 1;
-		}
-		config.type = id;
-		config.initialized = 0;
-
-		/* add new USB port to the list of available ports */
-		port[port_count++] = config;
-	}
-
-	return 0;
-}
-
-int usb_process_devicetree(const void *blob)
-{
-	int node_list[USB_PORTS_MAX];
-	int count, err = 0;
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(fdt_usb_controllers); i++) {
-		count = fdtdec_find_aliases_for_id(blob, "usb",
-			fdt_usb_controllers[i].compat, node_list,
-			USB_PORTS_MAX);
-		if (count) {
-			err = process_usb_nodes(blob, node_list, count, i);
-			if (err)
-				printf("%s: Error processing USB node!\n",
-				       __func__);
-			return err;
-		}
-	}
-
-	return err;
-}
-
-/**
- * Start up the given port number (ports are numbered from 0 on each board).
- * This returns values for the appropriate hccr and hcor addresses to use for
- * USB EHCI operations.
- *
- * @param index	port number to start
- * @param hccr		returns start address of EHCI HCCR registers
- * @param hcor		returns start address of EHCI HCOR registers
- * @return 0 if ok, -1 on error (generally invalid port number)
- */
-int ehci_hcd_init(int index, enum usb_init_type init,
-		struct ehci_hccr **hccr, struct ehci_hcor **hcor)
-{
-	struct fdt_usb *config;
-	struct usb_ctlr *usbctlr;
-	int ret;
-
-	if (index >= port_count)
-		return -1;
-
-	config = &port[index];
-	ehci_set_controller_priv(index, config, &tegra_ehci_ops);
-
-	ret = usb_common_init(config, init);
-	if (ret) {
-		printf("tegrausb: Cannot init port %d\n", index);
-		return ret;
-	}
-
-	config->initialized = 1;
-
-	usbctlr = config->reg;
-	*hccr = (struct ehci_hccr *)&usbctlr->cap_length;
-	*hcor = (struct ehci_hcor *)&usbctlr->usb_cmd;
-
-	return 0;
-}
-
-/*
- * Bring down the specified USB controller
- */
-int ehci_hcd_stop(int index)
-{
-	usb_common_uninit(&port[index]);
-
-	port[index].initialized = 0;
-
-	return 0;
-}
-#endif /* !CONFIG_DM_USB */
-
-#ifdef CONFIG_DM_USB
 static int ehci_usb_ofdata_to_platdata(struct udevice *dev)
 {
 	struct fdt_usb *priv = dev_get_priv(dev);
@@ -987,4 +838,3 @@ U_BOOT_DRIVER(usb_ehci) = {
 	.priv_auto_alloc_size = sizeof(struct fdt_usb),
 	.flags	= DM_FLAG_ALLOC_PRIV_DMA,
 };
-#endif
diff --git a/include/fdtdec.h b/include/fdtdec.h
index 063a980..c24fed2 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -112,9 +112,6 @@ static inline fdt_size_t fdt_resource_size(const struct fdt_resource *res)
  */
 enum fdt_compat_id {
 	COMPAT_UNKNOWN,
-	COMPAT_NVIDIA_TEGRA20_USB,	/* Tegra20 USB port */
-	COMPAT_NVIDIA_TEGRA30_USB,	/* Tegra30 USB port */
-	COMPAT_NVIDIA_TEGRA114_USB,	/* Tegra114 USB port */
 	COMPAT_NVIDIA_TEGRA20_EMC,	/* Tegra20 memory controller */
 	COMPAT_NVIDIA_TEGRA20_EMC_TABLE, /* Tegra20 memory timing table */
 	COMPAT_NVIDIA_TEGRA20_KBC,	/* Tegra20 Keyboard */
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 9fcc1bb..d3e725b 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -21,9 +21,6 @@ DECLARE_GLOBAL_DATA_PTR;
 #define COMPAT(id, name) name
 static const char * const compat_names[COMPAT_COUNT] = {
 	COMPAT(UNKNOWN, "<none>"),
-	COMPAT(NVIDIA_TEGRA20_USB, "nvidia,tegra20-ehci"),
-	COMPAT(NVIDIA_TEGRA30_USB, "nvidia,tegra30-ehci"),
-	COMPAT(NVIDIA_TEGRA114_USB, "nvidia,tegra114-ehci"),
 	COMPAT(NVIDIA_TEGRA20_EMC, "nvidia,tegra20-emc"),
 	COMPAT(NVIDIA_TEGRA20_EMC_TABLE, "nvidia,tegra20-emc-table"),
 	COMPAT(NVIDIA_TEGRA20_KBC, "nvidia,tegra20-kbc"),
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 79/80] dm: usb: exynos: Drop legacy USB code
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (77 preceding siblings ...)
  2015-03-25 18:23 ` [U-Boot] [PATCH v2 78/80] dm: usb: tegra: Drop legacy USB code Simon Glass
@ 2015-03-25 18:23 ` Simon Glass
  2015-05-06 21:44   ` Simon Glass
  2015-03-25 18:23 ` [U-Boot] [PATCH v2 80/80] dm: usb: Add a README for driver model Simon Glass
  2015-03-26 19:40 ` [U-Boot] [PATCH v2 0/80] dm: Add USB support Marek Vasut
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:23 UTC (permalink / raw)
  To: u-boot

Drop the code that doesn't use driver model for USB.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/usb/host/ehci-exynos.c  | 117 ----------------------------------------
 drivers/usb/host/xhci-exynos5.c | 108 -------------------------------------
 include/fdtdec.h                |   2 -
 lib/fdtdec.c                    |   2 -
 4 files changed, 229 deletions(-)

diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c
index 86cf631..18e9251 100644
--- a/drivers/usb/host/ehci-exynos.c
+++ b/drivers/usb/host/ehci-exynos.c
@@ -25,14 +25,12 @@
 /* Declare global data pointer */
 DECLARE_GLOBAL_DATA_PTR;
 
-#ifdef CONFIG_DM_USB
 struct exynos_ehci_platdata {
 	struct usb_platdata usb_plat;
 	fdt_addr_t hcd_base;
 	fdt_addr_t phy_base;
 	struct gpio_desc vbus_gpio;
 };
-#endif
 
 /**
  * Contains pointers to register base addresses
@@ -42,16 +40,8 @@ struct exynos_ehci {
 	struct ehci_ctrl ctrl;
 	struct exynos_usb_phy *usb;
 	struct ehci_hccr *hcd;
-#ifndef CONFIG_DM_USB
-	struct gpio_desc vbus_gpio;
-#endif
 };
 
-#ifndef CONFIG_DM_USB
-static struct exynos_ehci exynos;
-#endif
-
-#ifdef CONFIG_DM_USB
 static int ehci_usb_ofdata_to_platdata(struct udevice *dev)
 {
 	struct exynos_ehci_platdata *plat = dev_get_platdata(dev);
@@ -91,55 +81,6 @@ static int ehci_usb_ofdata_to_platdata(struct udevice *dev)
 
 	return 0;
 }
-#else
-static int exynos_usb_parse_dt(const void *blob, struct exynos_ehci *exynos)
-{
-	fdt_addr_t addr;
-	unsigned int node;
-	int depth;
-
-	node = fdtdec_next_compatible(blob, 0, COMPAT_SAMSUNG_EXYNOS_EHCI);
-	if (node <= 0) {
-		debug("EHCI: Can't get device node for ehci\n");
-		return -ENODEV;
-	}
-
-	/*
-	 * Get the base address for EHCI controller from the device node
-	 */
-	addr = fdtdec_get_addr(blob, node, "reg");
-	if (addr == FDT_ADDR_T_NONE) {
-		debug("Can't get the EHCI register address\n");
-		return -ENXIO;
-	}
-
-	exynos->hcd = (struct ehci_hccr *)addr;
-
-	/* Vbus gpio */
-	gpio_request_by_name_nodev(blob, node, "samsung,vbus-gpio", 0,
-				   &exynos->vbus_gpio, GPIOD_IS_OUT);
-
-	depth = 0;
-	node = fdtdec_next_compatible_subnode(blob, node,
-					COMPAT_SAMSUNG_EXYNOS_USB_PHY, &depth);
-	if (node <= 0) {
-		debug("EHCI: Can't get device node for usb-phy controller\n");
-		return -ENODEV;
-	}
-
-	/*
-	 * Get the base address for usbphy from the device node
-	 */
-	exynos->usb = (struct exynos_usb_phy *)fdtdec_get_addr(blob, node,
-								"reg");
-	if (exynos->usb == NULL) {
-		debug("Can't get the usbphy register address\n");
-		return -ENXIO;
-	}
-
-	return 0;
-}
-#endif
 
 static void exynos5_setup_usb_phy(struct exynos_usb_phy *usb)
 {
@@ -270,63 +211,6 @@ static void reset_usb_phy(struct exynos_usb_phy *usb)
 	set_usbhost_phy_ctrl(POWER_USB_HOST_PHY_CTRL_DISABLE);
 }
 
-#ifndef CONFIG_DM_USB
-/*
- * EHCI-initialization
- * Create the appropriate control structures to manage
- * a new EHCI host controller.
- */
-int ehci_hcd_init(int index, enum usb_init_type init,
-		struct ehci_hccr **hccr, struct ehci_hcor **hcor)
-{
-	struct exynos_ehci *ctx = &exynos;
-
-#ifdef CONFIG_OF_CONTROL
-	if (exynos_usb_parse_dt(gd->fdt_blob, ctx)) {
-		debug("Unable to parse device tree for ehci-exynos\n");
-		return -ENODEV;
-	}
-#else
-	ctx->usb = (struct exynos_usb_phy *)samsung_get_base_usb_phy();
-	ctx->hcd = (struct ehci_hccr *)samsung_get_base_usb_ehci();
-#endif
-
-#ifdef CONFIG_OF_CONTROL
-	/* setup the Vbus gpio here */
-	if (dm_gpio_is_valid(&ctx->vbus_gpio))
-		dm_gpio_set_value(&ctx->vbus_gpio, 1);
-#endif
-
-	setup_usb_phy(ctx->usb);
-
-	board_usb_init(index, init);
-
-	*hccr = ctx->hcd;
-	*hcor = (struct ehci_hcor *)((uint32_t) *hccr
-				+ HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
-
-	debug("Exynos5-ehci: init hccr %x and hcor %x hc_length %d\n",
-		(uint32_t)*hccr, (uint32_t)*hcor,
-		(uint32_t)HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
-
-	return 0;
-}
-
-/*
- * Destroy the appropriate control structures corresponding
- * the EHCI host controller.
- */
-int ehci_hcd_stop(int index)
-{
-	struct exynos_ehci *ctx = &exynos;
-
-	reset_usb_phy(ctx->usb);
-
-	return 0;
-}
-#endif
-
-#ifdef CONFIG_DM_USB
 static int ehci_usb_probe(struct udevice *dev)
 {
 	struct exynos_ehci_platdata *plat = dev_get_platdata(dev);
@@ -377,4 +261,3 @@ U_BOOT_DRIVER(usb_ehci) = {
 	.platdata_auto_alloc_size = sizeof(struct exynos_ehci_platdata),
 	.flags	= DM_FLAG_ALLOC_PRIV_DMA,
 };
-#endif
diff --git a/drivers/usb/host/xhci-exynos5.c b/drivers/usb/host/xhci-exynos5.c
index 23c7ecc..a27a796 100644
--- a/drivers/usb/host/xhci-exynos5.c
+++ b/drivers/usb/host/xhci-exynos5.c
@@ -33,36 +33,24 @@
 /* Declare global data pointer */
 DECLARE_GLOBAL_DATA_PTR;
 
-#ifdef CONFIG_DM_USB
 struct exynos_xhci_platdata {
 	fdt_addr_t hcd_base;
 	fdt_addr_t phy_base;
 	struct gpio_desc vbus_gpio;
 };
-#endif
 
 /**
  * Contains pointers to register base addresses
  * for the usb controller.
  */
 struct exynos_xhci {
-#ifdef CONFIG_DM_USB
 	struct usb_platdata usb_plat;
-#endif
 	struct xhci_ctrl ctrl;
 	struct exynos_usb3_phy *usb3_phy;
 	struct xhci_hccr *hcd;
 	struct dwc3 *dwc3_reg;
-#ifndef CONFIG_DM_USB
-	struct gpio_desc vbus_gpio;
-#endif
 };
 
-#ifndef CONFIG_DM_USB
-static struct exynos_xhci exynos;
-#endif
-
-#ifdef CONFIG_DM_USB
 static int xhci_usb_ofdata_to_platdata(struct udevice *dev)
 {
 	struct exynos_xhci_platdata *plat = dev_get_platdata(dev);
@@ -102,54 +90,6 @@ static int xhci_usb_ofdata_to_platdata(struct udevice *dev)
 
 	return 0;
 }
-#else
-static int exynos_usb3_parse_dt(const void *blob, struct exynos_xhci *exynos)
-{
-	fdt_addr_t addr;
-	unsigned int node;
-	int depth;
-
-	node = fdtdec_next_compatible(blob, 0, COMPAT_SAMSUNG_EXYNOS5_XHCI);
-	if (node <= 0) {
-		debug("XHCI: Can't get device node for xhci\n");
-		return -ENODEV;
-	}
-
-	/*
-	 * Get the base address for XHCI controller from the device node
-	 */
-	addr = fdtdec_get_addr(blob, node, "reg");
-	if (addr == FDT_ADDR_T_NONE) {
-		debug("Can't get the XHCI register base address\n");
-		return -ENXIO;
-	}
-	exynos->hcd = (struct xhci_hccr *)addr;
-
-	/* Vbus gpio */
-	gpio_request_by_name_nodev(blob, node, "samsung,vbus-gpio", 0,
-				   &exynos->vbus_gpio, GPIOD_IS_OUT);
-
-	depth = 0;
-	node = fdtdec_next_compatible_subnode(blob, node,
-				COMPAT_SAMSUNG_EXYNOS5_USB3_PHY, &depth);
-	if (node <= 0) {
-		debug("XHCI: Can't get device node for usb3-phy controller\n");
-		return -ENODEV;
-	}
-
-	/*
-	 * Get the base address for usbphy from the device node
-	 */
-	exynos->usb3_phy = (struct exynos_usb3_phy *)fdtdec_get_addr(blob, node,
-								"reg");
-	if (exynos->usb3_phy == NULL) {
-		debug("Can't get the usbphy register address\n");
-		return -ENXIO;
-	}
-
-	return 0;
-}
-#endif
 
 static void exynos5_usb3_phy_init(struct exynos_usb3_phy *phy)
 {
@@ -340,53 +280,6 @@ static void exynos_xhci_core_exit(struct exynos_xhci *exynos)
 	exynos5_usb3_phy_exit(exynos->usb3_phy);
 }
 
-#ifndef CONFIG_DM_USB
-int xhci_hcd_init(int index, struct xhci_hccr **hccr, struct xhci_hcor **hcor)
-{
-	struct exynos_xhci *ctx = &exynos;
-	int ret;
-
-#ifdef CONFIG_OF_CONTROL
-	exynos_usb3_parse_dt(gd->fdt_blob, ctx);
-#else
-	ctx->usb3_phy = (struct exynos_usb3_phy *)samsung_get_base_usb3_phy();
-	ctx->hcd = (struct xhci_hccr *)samsung_get_base_usb_xhci();
-#endif
-
-	ctx->dwc3_reg = (struct dwc3 *)((char *)(ctx->hcd) + DWC3_REG_OFFSET);
-
-#ifdef CONFIG_OF_CONTROL
-	/* setup the Vbus gpio here */
-	if (dm_gpio_is_valid(&ctx->vbus_gpio))
-		dm_gpio_set_value(&ctx->vbus_gpio, 1);
-#endif
-
-	ret = exynos_xhci_core_init(ctx);
-	if (ret) {
-		puts("XHCI: failed to initialize controller\n");
-		return -EINVAL;
-	}
-
-	*hccr = (ctx->hcd);
-	*hcor = (struct xhci_hcor *)((uint32_t) *hccr
-				+ HC_LENGTH(xhci_readl(&(*hccr)->cr_capbase)));
-
-	debug("Exynos5-xhci: init hccr %x and hcor %x hc_length %d\n",
-		(uint32_t)*hccr, (uint32_t)*hcor,
-		(uint32_t)HC_LENGTH(xhci_readl(&(*hccr)->cr_capbase)));
-
-	return 0;
-}
-
-void xhci_hcd_stop(int index)
-{
-	struct exynos_xhci *ctx = &exynos;
-
-	exynos_xhci_core_exit(ctx);
-}
-#endif
-
-#ifdef CONFIG_DM_USB
 static int xhci_usb_probe(struct udevice *dev)
 {
 	struct exynos_xhci_platdata *plat = dev_get_platdata(dev);
@@ -443,4 +336,3 @@ U_BOOT_DRIVER(usb_xhci) = {
 	.priv_auto_alloc_size = sizeof(struct exynos_xhci),
 	.flags	= DM_FLAG_ALLOC_PRIV_DMA,
 };
-#endif
diff --git a/include/fdtdec.h b/include/fdtdec.h
index c24fed2..b9d63ad 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -133,8 +133,6 @@ enum fdt_compat_id {
 	COMPAT_WOLFSON_WM8994_CODEC,	/* Wolfson WM8994 Sound Codec */
 	COMPAT_GOOGLE_CROS_EC,		/* Google CROS_EC Protocol */
 	COMPAT_GOOGLE_CROS_EC_KEYB,	/* Google CROS_EC Keyboard */
-	COMPAT_SAMSUNG_EXYNOS_EHCI,	/* Exynos EHCI controller */
-	COMPAT_SAMSUNG_EXYNOS5_XHCI,	/* Exynos5 XHCI controller */
 	COMPAT_SAMSUNG_EXYNOS_USB_PHY,	/* Exynos phy controller for usb2.0 */
 	COMPAT_SAMSUNG_EXYNOS5_USB3_PHY,/* Exynos phy controller for usb3.0 */
 	COMPAT_SAMSUNG_EXYNOS_TMU,	/* Exynos TMU */
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index d3e725b..94460d0 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -41,8 +41,6 @@ static const char * const compat_names[COMPAT_COUNT] = {
 	COMPAT(WOLFSON_WM8994_CODEC, "wolfson,wm8994-codec"),
 	COMPAT(GOOGLE_CROS_EC, "google,cros-ec"),
 	COMPAT(GOOGLE_CROS_EC_KEYB, "google,cros-ec-keyb"),
-	COMPAT(SAMSUNG_EXYNOS_EHCI, "samsung,exynos-ehci"),
-	COMPAT(SAMSUNG_EXYNOS5_XHCI, "samsung,exynos5250-xhci"),
 	COMPAT(SAMSUNG_EXYNOS_USB_PHY, "samsung,exynos-usb-phy"),
 	COMPAT(SAMSUNG_EXYNOS5_USB3_PHY, "samsung,exynos5250-usb3-phy"),
 	COMPAT(SAMSUNG_EXYNOS_TMU, "samsung,exynos-tmu"),
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 80/80] dm: usb: Add a README for driver model
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (78 preceding siblings ...)
  2015-03-25 18:23 ` [U-Boot] [PATCH v2 79/80] dm: usb: exynos: " Simon Glass
@ 2015-03-25 18:23 ` Simon Glass
  2015-04-07  3:24   ` Jim Lin
  2015-03-26 19:40 ` [U-Boot] [PATCH v2 0/80] dm: Add USB support Marek Vasut
  80 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-03-25 18:23 UTC (permalink / raw)
  To: u-boot

Add some documentation describing how USB is implemented with USB. This
might make things easier for people to understand.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2:
- Rewrite and expand series to support driver model fully

 doc/driver-model/usb-info.txt | 415 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 415 insertions(+)
 create mode 100644 doc/driver-model/usb-info.txt

diff --git a/doc/driver-model/usb-info.txt b/doc/driver-model/usb-info.txt
new file mode 100644
index 0000000..3762b6c
--- /dev/null
+++ b/doc/driver-model/usb-info.txt
@@ -0,0 +1,415 @@
+How USB works with driver model
+===============================
+
+Introduction
+------------
+
+Driver model USB support makes use of existing features but changes how
+drivers are found. This document provides some information intended to help
+understand how things work with USB in U-Boot when driver model is enabled.
+
+
+Enabling driver model for USB
+-----------------------------
+
+A new CONFIG_DM_USB option is provided to enable driver model for USB. This
+causes the USB uclass to be included, and drops the equivalent code in
+usb.c. In particular the usb_init() function is then implemented by the
+uclass.
+
+
+Support for ECHI and XCHI
+-------------------------
+
+So far OHCI is not supported. Both EHCI and XHCI drivers should be declared
+as drivers in the USB uclass. For example:
+
+static const struct udevice_id ehci_usb_ids[] = {
+	{ .compatible = "nvidia,tegra20-ehci", .data = USB_CTLR_T20 },
+	{ .compatible = "nvidia,tegra30-ehci", .data = USB_CTLR_T30 },
+	{ .compatible = "nvidia,tegra114-ehci", .data = USB_CTLR_T114 },
+	{ }
+};
+
+U_BOOT_DRIVER(usb_ehci) = {
+	.name	= "ehci_tegra",
+	.id	= UCLASS_USB,
+	.of_match = ehci_usb_ids,
+	.ofdata_to_platdata = ehci_usb_ofdata_to_platdata,
+	.probe = tegra_ehci_usb_probe,
+	.remove = tegra_ehci_usb_remove,
+	.ops	= &ehci_usb_ops,
+	.platdata_auto_alloc_size = sizeof(struct usb_platdata),
+	.priv_auto_alloc_size = sizeof(struct fdt_usb),
+	.flags	= DM_FLAG_ALLOC_PRIV_DMA,
+};
+
+Here ehci_usb_ids is used to list the controllers that the driver supports.
+Each has its own data value. Controllers must be in the UCLASS_USB uclass.
+
+The ofdata_to_platdata() method allows the controller driver to grab any
+necessary settings from the device tree.
+
+The ops here are ehci_usb_ops. All EHCI drivers will use these same ops in
+most cases, since they are all ECHI-compatible. For ECHI there are also some
+special operations that can be overriden when calling ehci_register().
+
+The driver can use priv_auto_alloc_size to set the size of its private data.
+This can hold run-time information needed by the driver for operation. It
+exists when the device is probed (not when it is bound) and is removed when
+the driver is removed.
+
+Note that usb_platdata is currently only used to deal with setting up a bus
+in USB device mode (OTG operation). It can be omitted if that is not
+supported.
+
+The driver's probe() method should do the basic controller init and then
+call ehci_register() to register itself as an EHCI device. It should call
+ehci_deregister() in the remove() method. Registering a new EHCI device
+does not by itself cause the bus to be scanned.
+
+The old ehci_hcd_init() function is no-longer used. Nor is it necessary to
+set up the USB controllers from board init code. When 'usb start' is used,
+each controller will be probed and its bus scanned.
+
+XHCI works in a similar way.
+
+
+Data structures
+---------------
+
+The following primary data structures are in use:
+
+- struct usb_device
+	This holds information about a device on the bus. All devices have
+	this structure, even the root hub. The controller itself does not
+	have this structure. You can access it for a device 'dev' with
+	dev_get_parentdata(dev). It matches the old structure except that the
+	parent and child information is not present (since driver model
+	handles that). Once the device is set up, you can find the device
+	descriptor and current configuration descriptor in this structure.
+
+- struct usb_platdata
+	This holds platform data for a controller. So far this is only used
+	as a work-around for controllers which can act as USB devices in OTG
+	mode, since the gadget framework does not use driver model.
+
+- struct usb_dev_platdata
+	This holds platform data for a device. You can access it for a
+	device 'dev' with dev_get_parent_platdata(dev). It holds the device
+	address and speed - anything that can be determined before the device
+	driver is actually set up. When probing the bus this structure is
+	used to provide essential information to the device driver.
+
+- struct usb_bus_priv
+	This is private information for each controller, maintained by the
+	controller uclass. It is mostly used to keep track of the next
+	device address to use.
+
+Of these, only struct usb_device was used prior to driver model.
+
+
+USB buses
+---------
+
+Given a controller, you know the bus - it is the one attached to the
+controller. Each controller handles exactly one bus. Every controller has a
+root hub attached to it. This hub, which is itself a USB device, can provide
+one or more 'ports' to which additional devices can be attached. It is
+possible to power up a hub and find out which of its ports have devices
+attached.
+
+Devices are given addresses starting at 1. The root hub is always address 1,
+and from there the devices are numbered in sequence. The USB uclass takes
+care of this numbering automatically during enumeration.
+
+USB devices are enumerated by finding a device on a particular hub, and
+setting its address to the next available address. The USB bus stretches out
+in a tree structure, potentially with multiple hubs each with several ports
+and perhaps other hubs. Some hubs will have their own power since otherwise
+the 5V 500mA power supplied by the controller will not be sufficient to run
+very many devices.
+
+Enumeration in U-Boot takes a long time since devices are probed one at a
+time, and each is given sufficient time to wake up and announce itself. The
+timeouts are set for the slowest device.
+
+Up to 127 devices can be on each bus. USB has four bus speeds: low
+(1.5Mbps), full (12Mbps), high (480Mbps) which is only available with USB2
+and newer (EHCI), and super (5Gbps) which is only available with USB3 and
+newer (XHCI). If you connect a super-speed device to a high-speed hub, you
+will only get high-speed.
+
+
+USB operations
+--------------
+
+As before driver model, messages can be sent using submit_bulk_msg() and the
+like. These are now implemented by the USB uclass and route through the
+controller drivers. Note that messages are not sent to the driver of the
+device itself - i.e. they don't pass down the stack to the controller.
+U-Boot simply finds the controller to which the device is attached, and sends
+the message there with an appropriate 'pipe' value so it can be addressed
+properly. Having said that, the USB device which should receive the message
+is passed in to the driver methods, for use by sandbox. This design decision
+is open for review and the code impact of changing it is small since the
+methods are typically implemented by the EHCI and XHCI stacks.
+
+Controller drivers (in UCLASS_USB) themselves provide methods for sending
+each message type. For XHCI an additional alloc_device() method is provided
+since XHCI needs to allocate a device context before it can even read the
+device's descriptor.
+
+These methods use a 'pipe' which is a collection of bit fields used to
+describe the type of message, direction of transfer and the intended
+recipient (device number).
+
+
+USB Devices
+-----------
+
+USB devices are found using a simple algorithm which works through the
+available hubs in a depth-first search. Devices can be in any uclass, but
+are attached to a parent hub (or controller in the case of the root hub) and
+so have parent data attached to them (this is struct usb_device).
+
+By the time the device's probe() method is called, it is enumerated and is
+ready to talk to the host.
+
+The enumeration process needs to work out which driver to attach to each USB
+device. It does this by examining the device class, interface class, vendor
+ID, product ID, etc. See struct usb_driver_entry for how drivers are matched
+with USB devices - you can use the USB_DEVICE() macro to declare a USB
+driver. For example, usb_storage.c defines a USB_DEVICE() to handle storage
+devices, and it will be used for all USB devices which match.
+
+
+
+Technical details on enumeration flow
+-------------------------------------
+
+It is useful to understand precisely how a USB bus is enumerating to avoid
+confusion when dealing with USB devices.
+
+Device initialisation happens roughly like this:
+
+- At some point the 'usb start' command is run
+- This calls usb_init() which works through each controller in turn
+- The controller is probed(). This does no enumeration.
+- Then usb_scan_bus() is called. This calls usb_scan_device() to scan the
+(only) device that is attached to the controller - a root hub
+- usb_scan_device() sets up a fake struct usb_device and calls
+usb_setup_device(), passing the port number to be scanned, in this case port
+0
+- usb_setup_device() first calls usb_prepare_device() to set the device
+address, then usb_select_config() to select the first configuration
+- at this point the device is enumerated but we do not have a real struct
+udevice for it. But we do have the descriptor in struct usb_device so we can
+use this to figure out what driver to use
+- back in usb_scan_device(), we call usb_find_child() to try to find an
+existing device which matches the one we just found on the bus. This can
+happen if the device is mentioned in the device tree, or if we previously
+scanned the bus and so the device was created before
+- if usb_find_child() does not find an existing device, we call
+usb_find_and_bind_driver() which tries to bind one
+- usb_find_and_bind_driver() searches all available USB drivers (declared
+with USB_DEVICE()). If it finds a match it binds that driver to create a new
+device.
+- If it does not, it binds a generic driver. A generic driver is good enough
+to allow access to the device (sending it packets, etc.) but all
+functionality will need to be implemented outside the driver model.
+- in any case, when usb_find_child() and/or usb_find_and_bind_driver() are
+done, we have a device with the correct uclass. At this point we want to
+probe the device
+- first we store basic information about the new device (address, port,
+speed) in its parent platform data. We cannot store it its private data
+since that will not exist until the device is probed.
+- then we call device_probe() which probes the device
+- the first probe step is actually the USB controller's (or USB hubs's)
+child_pre_probe() method. This gets called before anything else and is
+intended to set up a child device ready to be used with its parent bus. For
+USB this calls usb_child_pre_probe() which grabs the information that was
+stored in the parent platform data and stores it in the parent private data
+(which is struct usb_device, a real one this time). It then calls
+usb_select_config() again to make sure that everything about the device is
+set up
+- note that we have called usb_select_config() twice. This is inefficient
+but the alternative is to store additional information in the platform data.
+The time taken is minimal and this way is simpler
+- at this point the device is set up and ready for use so far as the USB
+subsystem is concerned
+- the device's probe() method is then called. It can send messages and do
+whatever else it wants to make the device work.
+
+Note that the first device is always a root hub, and this must be scanned to
+find any devices. The above steps will have created a hub (UCLASS_USB_HUB),
+given it address 1 and set the configuration.
+
+For hubs, the hub uclass has a post_probe() method. This means that after
+any hub is probed, the uclass gets to do some processing. In this case
+usb_hub_post_probe() is called, and the following steps take place:
+
+- usb_hub_post_probe() calls usb_hub_scan() to scan the hub, which in turn
+calls usb_hub_configure()
+- hub power is enabled
+- we loop through each port on the hub, performing the same steps for each
+- first, check if there is a device present. This happens in
+usb_hub_port_connect_change(). If so, then usb_scan_device() is called to
+scan the device, passing the appropriate port number.
+- you will recognise usb_scan_device() from the steps above. It sets up the
+device ready for use. If it is a hub, it will scan that hub before it
+continues here (recursively, depth-first)
+- once all hub ports are scanned in this way, the hub is ready for use and
+all of its downstream devices also
+- additional controllers are scanned in the same way
+
+The above method has some nice properties:
+
+- the bus enumeration happens by virtue of driver model's natural device flow
+- most logic is in the USB controller and hub uclasses; the actual device
+drivers do not need to know they are on a USB bus, at least so far as
+enumeration goes
+- hub scanning happens automatically after a hub is probed
+
+
+Hubs
+----
+
+USB hubs are scanned as in the section above. While hubs have their own
+uclass, they share some common elements with controllers:
+
+- they both attach private data to their children (struct usb_device,
+accessible for a child with dev_get_parentdata(child))
+- they both use usb_child_pre_probe() to set up their children as proper USB
+devices
+
+
+Example - Mass Storage
+----------------------
+
+As an example of a USB device driver, see usb_storage.c. It uses its own
+uclass and declares itself as follows:
+
+U_BOOT_DRIVER(usb_mass_storage) = {
+	.name	= "usb_mass_storage",
+	.id	= UCLASS_MASS_STORAGE,
+	.of_match = usb_mass_storage_ids,
+	.probe = usb_mass_storage_probe,
+};
+
+static const struct usb_device_id mass_storage_id_table[] = {
+    { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
+      .bInterfaceClass = USB_CLASS_MASS_STORAGE},
+    { }						/* Terminating entry */
+};
+
+USB_DEVICE(usb_mass_storage, mass_storage_id_table);
+
+The USB_DEVICE() macro attaches the given table of matching information to
+the given driver. Note that the driver is declared in U_BOOT_DRIVER() as
+'usb_mass_storage' and this must match the first parameter of USB_DEVICE.
+
+When usb_find_and_bind_driver() is called on a USB device with the
+bInterfaceClass value of USB_CLASS_MASS_STORAGE, it will automatically find
+this driver and use it.
+
+
+Counter-example: USB Ethernet
+-----------------------------
+
+As an example of the old way of doing things, see usb_ether.c. When the bus
+is scanned, all Ethernet devices will be created as generic USB devices (in
+uclass UCLASS_USB_DEV_GENERIC). Then, when the scan is completed,
+usb_host_eth_scan() will be called. This looks through all the devices on
+each bus and manually figures out which are Ethernet devices in the ways of
+yore.
+
+In fact, usb_ether should be moved to driver model. Each USB Ethernet driver
+(e.g drivers/usb/eth/asix.c) should include a USB_DEVICE() declaration, so
+that it will be found as part of normal USB enumeration. Then, instead of a
+generic USB driver, a real (driver-model-aware) driver will be used. Since
+Ethernet now supports driver model, this should be fairly easy to achieve,
+and then usb_ether.c and the usb_host_eth_scan() will melt away.
+
+
+Sandbox
+-------
+
+All driver model uclasses must have tests and USB is no exception. To
+achieve this, a sandbox USB controller is provided. This can make use of
+emulation drivers which pretend to be USB devices. Emulations are provided
+for a hub and a flash stick. These are enough to create a pretend USB bus
+(defined by the sandbox device tree sandbox.dts) which can be scanned and
+used.
+
+Tests in test/dm/usb.c make use of this feature. It allows much of the USB
+stack to be tested without real hardware being needed.
+
+Here is an example device tree fragment:
+
+	usb at 1 {
+		compatible = "sandbox,usb";
+		hub {
+			compatible = "usb-hub";
+			usb,device-class = <USB_CLASS_HUB>;
+			hub-emul {
+				compatible = "sandbox,usb-hub";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				flash-stick {
+					reg = <0>;
+					compatible = "sandbox,usb-flash";
+					sandbox,filepath = "flash.bin";
+				};
+			};
+		};
+	};
+
+This defines a single controller, containing a root hub (which is required).
+The hub is emulated by a hub emulator, and the emulated hub has a single
+flash stick to emulate on one of its ports.
+
+When 'usb start' is used, the following 'dm tree' output will be available:
+
+ usb         [ + ]    `-- usb at 1
+ usb_hub     [ + ]        `-- hub
+ usb_emul    [ + ]            |-- hub-emul
+ usb_emul    [ + ]            |   `-- flash-stick
+ usb_mass_st [ + ]            `-- usb_mass_storage
+
+
+This may look a confusing. Most of it mirrors the device tree, but the
+'usb_mass_storage' device is not in the device tree. This is created by
+usb_find_and_bind_driver() based on the USB_DRIVER in usb_storage.c. While
+'flash-stick' is the emulation device, 'usb_mass_storage' is the real U-Boot
+USB device driver that talks to it.
+
+
+Future work
+-----------
+
+It is pretty uncommon to have a large USB bus with lots of hubs on an
+embedded system. In fact anything other than a root hub is uncommon. Still
+it would be possible to speed up enumeration in two ways:
+
+- breadth-first search would allow devices to be reset and probed in
+parallel to some extent
+- enumeration could be lazy, in the sense that we could enumerate just the
+root hub at first, then only progress to the next 'level' when a device is
+used that we cannot find. This could be made easier if the devices were
+statically declared in the device tree (which is acceptable for production
+boards where the same, known, things are on each bus).
+
+But in common cases the current algorithm is sufficient.
+
+Other things that need doing:
+- Convert usb_ether to use driver model as described above
+- Test that keyboards work (and convert to driver model)
+- Move the USB gadget framework to driver model
+- Implement OHCI in driver model
+- Implement USB PHYs in driver model
+- Work out a clever way to provide lazy init for USB devices
+
+--
+Simon Glass <sjg@chromium.org>
+23-Mar-15
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 57/80] dm: usb: tegra: Remove the port_addr_clear_csc variable
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 57/80] dm: usb: tegra: Remove the port_addr_clear_csc variable Simon Glass
@ 2015-03-26  3:38   ` Jim Lin
  2015-03-26  9:01     ` Jim Lin
  0 siblings, 1 reply; 178+ messages in thread
From: Jim Lin @ 2015-03-26  3:38 UTC (permalink / raw)
  To: u-boot


> -----Original Message-----
> From: U-Boot [mailto:u-boot-bounces at lists.denx.de] On Behalf Of Simon Glass
> Sent: Thursday, March 26, 2015 2:23 AM
> To: U-Boot Mailing List
> Cc: Marek Vasut; Stephen Warren; Vivek Gautam; Tom Warren
> Subject: [U-Boot] [PATCH v2 57/80] dm: usb: tegra: Remove the port_addr_clear_csc variable
> 
> This variable is a bit of a hack. We can obtain the same information from the normal device config. This will fit better with driver model, where global variables > are best avoided.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
> 
> Changes in v2: None
> 
>  drivers/usb/host/ehci-tegra.c | 6 +-----
>  1 file changed, 1 insertion(+), 5 deletions(-)
> 
> diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 38333c7..464f55d 100644
> --- a/drivers/usb/host/ehci-tegra.c
> +++ b/drivers/usb/host/ehci-tegra.c
> @@ -87,8 +87,6 @@ struct fdt_usb {
>  
>  static struct fdt_usb port[USB_PORTS_MAX];	/* List of valid USB ports */
>  static unsigned port_count;			/* Number of available ports */
> -/* Port that needs to clear CSC after Port Reset */ -static u32 port_addr_clear_csc;
>  
>  /*
>   * This table has USB timing parameters for each Oscillator frequency we @@ -206,7 +204,7 @@ static void tegra_ehci_powerup_fixup(struct ehci_ctrl *ctrl,
  	if (controller->has_hostpc)
>  		*reg |= EHCI_PS_PE;
>  
> -	if (((u32)status_reg & TEGRA_USB_ADDR_MASK) != port_addr_clear_csc)
> +	if (!config->has_legacy_mode)
>  		return;
How do we get config (config->has_legacy_mode) for in this function?
If you read ehci_set_usbmode, "config"  comes from
"config = &port[index];".
Or "config" is an input argument like set_up_vbus(struct fdt_usb *config, ...)
But for ehci_powerup_fixup, I don't see a way for us to get "config".

>  	/* For EHCI_PS_CSC to be cleared in ehci_hcd.c */
--nvpublic

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 57/80] dm: usb: tegra: Remove the port_addr_clear_csc variable
  2015-03-26  3:38   ` Jim Lin
@ 2015-03-26  9:01     ` Jim Lin
  2015-04-07 19:10       ` Simon Glass
  0 siblings, 1 reply; 178+ messages in thread
From: Jim Lin @ 2015-03-26  9:01 UTC (permalink / raw)
  To: u-boot

Please ignore my question because it is answered by [PATCH v2 34/80].

On 03/26/2015 11:38 AM, Jim Lin wrote:
>> -----Original Message-----
>> From: U-Boot [mailto:u-boot-bounces at lists.denx.de] On Behalf Of Simon Glass
>> Sent: Thursday, March 26, 2015 2:23 AM
>> To: U-Boot Mailing List
>> Cc: Marek Vasut; Stephen Warren; Vivek Gautam; Tom Warren
>> Subject: [U-Boot] [PATCH v2 57/80] dm: usb: tegra: Remove the port_addr_clear_csc variable
>>
>> This variable is a bit of a hack. We can obtain the same information from the normal device config. This will fit better with driver model, where global variables > are best avoided.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>>
>> Changes in v2: None
>>
>>   drivers/usb/host/ehci-tegra.c | 6 +-----
>>   1 file changed, 1 insertion(+), 5 deletions(-)
>>
>> diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 38333c7..464f55d 100644
>> --- a/drivers/usb/host/ehci-tegra.c
>> +++ b/drivers/usb/host/ehci-tegra.c
>> @@ -87,8 +87,6 @@ struct fdt_usb {
>>   
>>   static struct fdt_usb port[USB_PORTS_MAX];	/* List of valid USB ports */
>>   static unsigned port_count;			/* Number of available ports */
>> -/* Port that needs to clear CSC after Port Reset */ -static u32 port_addr_clear_csc;
>>   
>>   /*
>>    * This table has USB timing parameters for each Oscillator frequency we @@ -206,7 +204,7 @@ static void tegra_ehci_powerup_fixup(struct ehci_ctrl *ctrl,
>    	if (controller->has_hostpc)
>>   		*reg |= EHCI_PS_PE;
>>   
>> -	if (((u32)status_reg & TEGRA_USB_ADDR_MASK) != port_addr_clear_csc)
>> +	if (!config->has_legacy_mode)
>>   		return;
> How do we get config (config->has_legacy_mode) for in this function?
> If you read ehci_set_usbmode, "config"  comes from
> "config = &port[index];".
> Or "config" is an input argument like set_up_vbus(struct fdt_usb *config, ...)
> But for ehci_powerup_fixup, I don't see a way for us to get "config".
>
>>   	/* For EHCI_PS_CSC to be cleared in ehci_hcd.c */
> --nvpublic
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 15/80] dm: usb: Drop the legacy USB init sequence
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 15/80] dm: usb: Drop the legacy USB init sequence Simon Glass
@ 2015-03-26 18:22   ` Marek Vasut
  2015-04-07 18:41     ` Simon Glass
  0 siblings, 1 reply; 178+ messages in thread
From: Marek Vasut @ 2015-03-26 18:22 UTC (permalink / raw)
  To: u-boot

On Wednesday, March 25, 2015 at 07:22:03 PM, Simon Glass wrote:
> This CONFIG is not used anywhere in U-Boot, so drop it.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>

Acked-by: Marek Vasut <marex@denx.de>

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 0/80] dm: Add USB support
  2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
                   ` (79 preceding siblings ...)
  2015-03-25 18:23 ` [U-Boot] [PATCH v2 80/80] dm: usb: Add a README for driver model Simon Glass
@ 2015-03-26 19:40 ` Marek Vasut
  2015-04-05 23:38   ` Simon Glass
  80 siblings, 1 reply; 178+ messages in thread
From: Marek Vasut @ 2015-03-26 19:40 UTC (permalink / raw)
  To: u-boot

On Wednesday, March 25, 2015 at 07:21:48 PM, Simon Glass wrote:
> This series adds driver model support to USB. The intent is to permit the
> various subsystems (OHCI, EHCI, XHCI) to co-exist and allow any number of
> USB ports of different types.
> 
> With the RFC series, only USB controllers had a real driver model device.
> USB devices (including the hub in the controller) were not modelled as
> driver model devices.
> 
> While this was expedient, and produced much fewer patches, it is not a
> long-term solution. Also, since then, driver model Ethernet support (which
> USB can use) has been merged to u-boot-dm/next. It seems better to bite the
> bullet and do a full conversion.

Whew.

Reviewed-by: Marek Vasut <marex@denx.de>

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 0/80] dm: Add USB support
  2015-03-26 19:40 ` [U-Boot] [PATCH v2 0/80] dm: Add USB support Marek Vasut
@ 2015-04-05 23:38   ` Simon Glass
  2015-04-06 13:13     ` Marek Vasut
  0 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-04-05 23:38 UTC (permalink / raw)
  To: u-boot

Hi Marek,

On 26 March 2015 at 13:40, Marek Vasut <marex@denx.de> wrote:
> On Wednesday, March 25, 2015 at 07:21:48 PM, Simon Glass wrote:
>> This series adds driver model support to USB. The intent is to permit the
>> various subsystems (OHCI, EHCI, XHCI) to co-exist and allow any number of
>> USB ports of different types.
>>
>> With the RFC series, only USB controllers had a real driver model device.
>> USB devices (including the hub in the controller) were not modelled as
>> driver model devices.
>>
>> While this was expedient, and produced much fewer patches, it is not a
>> long-term solution. Also, since then, driver model Ethernet support (which
>> USB can use) has been merged to u-boot-dm/next. It seems better to bite the
>> bullet and do a full conversion.
>
> Whew.
>
> Reviewed-by: Marek Vasut <marex@denx.de>

Thanks very much for working through these!

Unless there are other comments I plan to apply this to u-boot-dm/next
in the next few days. I expect it will need some tweaking as boards
are moved over too.

Regards,
Simon

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 0/80] dm: Add USB support
  2015-04-05 23:38   ` Simon Glass
@ 2015-04-06 13:13     ` Marek Vasut
  2015-04-06 22:38       ` Simon Glass
  0 siblings, 1 reply; 178+ messages in thread
From: Marek Vasut @ 2015-04-06 13:13 UTC (permalink / raw)
  To: u-boot

On Monday, April 06, 2015 at 01:38:13 AM, Simon Glass wrote:
> Hi Marek,

Hi Simon,

> On 26 March 2015 at 13:40, Marek Vasut <marex@denx.de> wrote:
> > On Wednesday, March 25, 2015 at 07:21:48 PM, Simon Glass wrote:
> >> This series adds driver model support to USB. The intent is to permit
> >> the various subsystems (OHCI, EHCI, XHCI) to co-exist and allow any
> >> number of USB ports of different types.
> >> 
> >> With the RFC series, only USB controllers had a real driver model
> >> device. USB devices (including the hub in the controller) were not
> >> modelled as driver model devices.
> >> 
> >> While this was expedient, and produced much fewer patches, it is not a
> >> long-term solution. Also, since then, driver model Ethernet support
> >> (which USB can use) has been merged to u-boot-dm/next. It seems better
> >> to bite the bullet and do a full conversion.
> > 
> > Whew.
> > 
> > Reviewed-by: Marek Vasut <marex@denx.de>
> 
> Thanks very much for working through these!
> 
> Unless there are other comments I plan to apply this to u-boot-dm/next
> in the next few days. I expect it will need some tweaking as boards
> are moved over too.

Please apply, I'm really looking forward to this.

Thank you very much for putting all the effort into this !

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 0/80] dm: Add USB support
  2015-04-06 13:13     ` Marek Vasut
@ 2015-04-06 22:38       ` Simon Glass
  2015-04-07 13:52         ` Marek Vasut
  0 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-04-06 22:38 UTC (permalink / raw)
  To: u-boot

Hi Marek,

On 6 April 2015 at 07:13, Marek Vasut <marex@denx.de> wrote:
> On Monday, April 06, 2015 at 01:38:13 AM, Simon Glass wrote:
>> Hi Marek,
>
> Hi Simon,
>
>> On 26 March 2015 at 13:40, Marek Vasut <marex@denx.de> wrote:
>> > On Wednesday, March 25, 2015 at 07:21:48 PM, Simon Glass wrote:
>> >> This series adds driver model support to USB. The intent is to permit
>> >> the various subsystems (OHCI, EHCI, XHCI) to co-exist and allow any
>> >> number of USB ports of different types.
>> >>
>> >> With the RFC series, only USB controllers had a real driver model
>> >> device. USB devices (including the hub in the controller) were not
>> >> modelled as driver model devices.
>> >>
>> >> While this was expedient, and produced much fewer patches, it is not a
>> >> long-term solution. Also, since then, driver model Ethernet support
>> >> (which USB can use) has been merged to u-boot-dm/next. It seems better
>> >> to bite the bullet and do a full conversion.
>> >
>> > Whew.
>> >
>> > Reviewed-by: Marek Vasut <marex@denx.de>
>>
>> Thanks very much for working through these!
>>
>> Unless there are other comments I plan to apply this to u-boot-dm/next
>> in the next few days. I expect it will need some tweaking as boards
>> are moved over too.
>
> Please apply, I'm really looking forward to this.
>
> Thank you very much for putting all the effort into this !

OK, I'll apply to u-boot-dm/next, do a bit more testing, and apply. It
will be great to get this moved over.

Regards,
Simon

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 80/80] dm: usb: Add a README for driver model
  2015-03-25 18:23 ` [U-Boot] [PATCH v2 80/80] dm: usb: Add a README for driver model Simon Glass
@ 2015-04-07  3:24   ` Jim Lin
  2015-04-08  1:40     ` Simon Glass
  0 siblings, 1 reply; 178+ messages in thread
From: Jim Lin @ 2015-04-07  3:24 UTC (permalink / raw)
  To: u-boot

There are some typos. Please correct them, thanks.

On 03/26/2015 02:23 AM, Simon Glass wrote:
> Add some documentation describing how USB is implemented with USB. This
> might make things easier for people to understand.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2:
> - Rewrite and expand series to support driver model fully
>
>   doc/driver-model/usb-info.txt | 415 ++++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 415 insertions(+)
>   create mode 100644 doc/driver-model/usb-info.txt
>
> diff --git a/doc/driver-model/usb-info.txt b/doc/driver-model/usb-info.txt
> new file mode 100644
> index 0000000..3762b6c
> --- /dev/null
> +++ b/doc/driver-model/usb-info.txt
> @@ -0,0 +1,415 @@
> +How USB works with driver model
> +===============================
> +
> +Introduction
> +------------
> +
> +Driver model USB support makes use of existing features but changes how
> +drivers are found. This document provides some information intended to help
> +understand how things work with USB in U-Boot when driver model is enabled.
> +
> +
> +Enabling driver model for USB
> +-----------------------------
> +
> +A new CONFIG_DM_USB option is provided to enable driver model for USB. This
> +causes the USB uclass to be included, and drops the equivalent code in
> +usb.c. In particular the usb_init() function is then implemented by the
> +uclass.
> +
> +
> +Support for ECHI and XCHI
EHCI
XHCI

> +-------------------------
> +
> +So far OHCI is not supported. Both EHCI and XHCI drivers should be declared
> +as drivers in the USB uclass. For example:
> +
> +static const struct udevice_id ehci_usb_ids[] = {
> +	{ .compatible = "nvidia,tegra20-ehci", .data = USB_CTLR_T20 },
> +	{ .compatible = "nvidia,tegra30-ehci", .data = USB_CTLR_T30 },
> +	{ .compatible = "nvidia,tegra114-ehci", .data = USB_CTLR_T114 },
> +	{ }
> +};
> +
> +U_BOOT_DRIVER(usb_ehci) = {
> +	.name	= "ehci_tegra",
> +	.id	= UCLASS_USB,
> +	.of_match = ehci_usb_ids,
> +	.ofdata_to_platdata = ehci_usb_ofdata_to_platdata,
> +	.probe = tegra_ehci_usb_probe,
> +	.remove = tegra_ehci_usb_remove,
> +	.ops	= &ehci_usb_ops,
> +	.platdata_auto_alloc_size = sizeof(struct usb_platdata),
> +	.priv_auto_alloc_size = sizeof(struct fdt_usb),
> +	.flags	= DM_FLAG_ALLOC_PRIV_DMA,
> +};
> +
> +Here ehci_usb_ids is used to list the controllers that the driver supports.
> +Each has its own data value. Controllers must be in the UCLASS_USB uclass.
> +
> +The ofdata_to_platdata() method allows the controller driver to grab any
> +necessary settings from the device tree.
> +
> +The ops here are ehci_usb_ops. All EHCI drivers will use these same ops in
> +most cases, since they are all ECHI-compatible. For ECHI there are also some
EHCI-compatible
For EHCI
> +special operations that can be overriden when calling ehci_register().
overridden

> +This defines a single controller, containing a root hub (which is required).
> +The hub is emulated by a hub emulator, and the emulated hub has a single
> +flash stick to emulate on one of its ports.
> +
> +When 'usb start' is used, the following 'dm tree' output will be available:
> +
> + usb         [ + ]    `-- usb at 1
> + usb_hub     [ + ]        `-- hub
> + usb_emul    [ + ]            |-- hub-emul
> + usb_emul    [ + ]            |   `-- flash-stick
> + usb_mass_st [ + ]            `-- usb_mass_storage
> +
> +
> +This may look a confusing. Most of it mirrors the device tree, but the
may look confusing
--nvpublic

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 0/80] dm: Add USB support
  2015-04-06 22:38       ` Simon Glass
@ 2015-04-07 13:52         ` Marek Vasut
  0 siblings, 0 replies; 178+ messages in thread
From: Marek Vasut @ 2015-04-07 13:52 UTC (permalink / raw)
  To: u-boot

On Tuesday, April 07, 2015 at 12:38:58 AM, Simon Glass wrote:
> Hi Marek,

Hi Simon,

> On 6 April 2015 at 07:13, Marek Vasut <marex@denx.de> wrote:
> > On Monday, April 06, 2015 at 01:38:13 AM, Simon Glass wrote:
> >> Hi Marek,
> > 
> > Hi Simon,
> > 
> >> On 26 March 2015 at 13:40, Marek Vasut <marex@denx.de> wrote:
> >> > On Wednesday, March 25, 2015 at 07:21:48 PM, Simon Glass wrote:
> >> >> This series adds driver model support to USB. The intent is to permit
> >> >> the various subsystems (OHCI, EHCI, XHCI) to co-exist and allow any
> >> >> number of USB ports of different types.
> >> >> 
> >> >> With the RFC series, only USB controllers had a real driver model
> >> >> device. USB devices (including the hub in the controller) were not
> >> >> modelled as driver model devices.
> >> >> 
> >> >> While this was expedient, and produced much fewer patches, it is not
> >> >> a long-term solution. Also, since then, driver model Ethernet
> >> >> support (which USB can use) has been merged to u-boot-dm/next. It
> >> >> seems better to bite the bullet and do a full conversion.
> >> > 
> >> > Whew.
> >> > 
> >> > Reviewed-by: Marek Vasut <marex@denx.de>
> >> 
> >> Thanks very much for working through these!
> >> 
> >> Unless there are other comments I plan to apply this to u-boot-dm/next
> >> in the next few days. I expect it will need some tweaking as boards
> >> are moved over too.
> > 
> > Please apply, I'm really looking forward to this.
> > 
> > Thank you very much for putting all the effort into this !
> 
> OK, I'll apply to u-boot-dm/next, do a bit more testing, and apply. It
> will be great to get this moved over.

Thank you!

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 01/80] linker_lists: Add a function to access a linker list entry
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 01/80] linker_lists: Add a function to access a linker list entry Simon Glass
@ 2015-04-07 18:39   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:39 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:21, Simon Glass <sjg@chromium.org> wrote:
> Once declared, you cannot access a linker_list entry since you do not have
> a symbol name for it. Add llsym() macro to provide this. This avoids
> searching for the symbol at run-time based on name.
>
> An example usage is to declare a driver with U_BOOT_DRIVER(), then obtain
> a pointer to that driver later.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  include/linker_lists.h | 10 ++++++++++
>  1 file changed, 10 insertions(+)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 02/80] sandbox: Fix comment for os_open()
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 02/80] sandbox: Fix comment for os_open() Simon Glass
@ 2015-04-07 18:39   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:39 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:21, Simon Glass <sjg@chromium.org> wrote:
> This has the wrong #define in the function comment. Fix it.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  include/os.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 03/80] dm: test: bus: Use a local variable to simplify code
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 03/80] dm: test: bus: Use a local variable to simplify code Simon Glass
@ 2015-04-07 18:39   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:39 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:21, Simon Glass <sjg@chromium.org> wrote:
> Adjust this test to avoid repeating the same code too often.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  test/dm/bus.c | 16 ++++++++++------
>  1 file changed, 10 insertions(+), 6 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 04/80] dm: exynos: snow: Move the keyboard to I2C
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 04/80] dm: exynos: snow: Move the keyboard to I2C Simon Glass
@ 2015-04-07 18:39   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:39 UTC (permalink / raw)
  To: u-boot

Hi,

On 25 March 2015 at 12:21, Simon Glass <sjg@chromium.org> wrote:
> The snow keyboard on shipping devices is actually on I2C not SPI. Move the
> label to indicate this.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  arch/arm/dts/exynos5250-snow.dts | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

This patch is not needed now, so I'm dropping it. Commit  c9b53f8d
solved this problem.

Regards,
Simon

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 05/80] dm: core: Support allocating driver-private data for DMA
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 05/80] dm: core: Support allocating driver-private data for DMA Simon Glass
@ 2015-04-07 18:39   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:39 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:21, Simon Glass <sjg@chromium.org> wrote:
> Some driver want to put DMA buffers in their private data. Add a flag
> to tell driver model to align driver-private data to a cache boundary so
> that DMA will work correctly in this case.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/core/device.c | 19 +++++++++++++++++--
>  include/dm/device.h   |  3 +++
>  2 files changed, 20 insertions(+), 2 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 06/80] dm: core: Convert driver_bind() to use const
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 06/80] dm: core: Convert driver_bind() to use const Simon Glass
@ 2015-04-07 18:39   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:39 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:21, Simon Glass <sjg@chromium.org> wrote:
> The driver is not modified by driver model, so update driver_bind() to
> recognise that.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/core/device-remove.c | 4 ++--
>  drivers/core/device.c        | 7 ++++---
>  include/dm/device-internal.h | 2 +-
>  include/dm/device.h          | 2 +-
>  4 files changed, 8 insertions(+), 7 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 07/80] dm: core: Rename driver data function to dev_get_driver_data()
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 07/80] dm: core: Rename driver data function to dev_get_driver_data() Simon Glass
@ 2015-04-07 18:40   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:40 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:21, Simon Glass <sjg@chromium.org> wrote:
> The existing get_get_of_data() function provides access to both the driver's
> compatible string and its driver data. However only the latter is actually
> useful. Update the interface to reflect this and fix up existing users.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/core/device.c     |  4 ++--
>  drivers/core/lists.c      |  2 +-
>  drivers/i2c/s3c24x0_i2c.c |  2 +-
>  drivers/i2c/tegra_i2c.c   |  6 +++---
>  include/dm/device.h       | 16 +++++++++++-----
>  5 files changed, 18 insertions(+), 12 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 08/80] dm: core: Mark device as active before calling uclass probe() methods
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 08/80] dm: core: Mark device as active before calling uclass probe() methods Simon Glass
@ 2015-04-07 18:40   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:40 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:21, Simon Glass <sjg@chromium.org> wrote:
> The uclass pre-probe functions may end up calling back into the device in
> some circumstances. This can fail if recursion takes place. Adjust the
> ordering so that we mark the device as active early, then retract this
> later if needed.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/core/device.c | 8 +++++---
>  test/dm/test-uclass.c | 3 ++-
>  2 files changed, 7 insertions(+), 4 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 09/80] dm: core: Add device children and sibling functions
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 09/80] dm: core: Add device children and sibling functions Simon Glass
@ 2015-04-07 18:40   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:40 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:21, Simon Glass <sjg@chromium.org> wrote:
> Add some utility functions to check for children and for the last sibling in
> a device's parent.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/core/device.c | 28 ++++++++++++++++++++++++++++
>  include/dm/device.h   | 30 ++++++++++++++++++++++++++++++
>  2 files changed, 58 insertions(+)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 10/80] dm: gpio: Add an implementation for gpio_get_number()
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 10/80] dm: gpio: Add an implementation for gpio_get_number() Simon Glass
@ 2015-04-07 18:40   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:40 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:21, Simon Glass <sjg@chromium.org> wrote:
> This has a prototype but no implementation. It returns the global GPIO number
> given a gpio_desc. It is useful for debugging in some cases.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/gpio/gpio-uclass.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 11/80] dm: usb: Add a uclass for USB controllers
  2015-03-25 18:21 ` [U-Boot] [PATCH v2 11/80] dm: usb: Add a uclass for USB controllers Simon Glass
@ 2015-04-07 18:40   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:40 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:21, Simon Glass <sjg@chromium.org> wrote:
> Add a uclass that can represent a USB controller. For now we do not create
> devices for things attached to the controller. This will be added later.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/usb/Kconfig               |  14 ++
>  drivers/usb/host/Makefile         |   4 +
>  drivers/usb/host/usb-uclass.c     | 392 ++++++++++++++++++++++++++++++++++++++
>  drivers/usb/musb-new/musb_uboot.c |   4 +-
>  include/dm/uclass-id.h            |   1 +
>  include/usb.h                     | 285 ++++++++++++++++++++++++++-
>  6 files changed, 694 insertions(+), 6 deletions(-)
>  create mode 100644 drivers/usb/host/usb-uclass.c

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 12/80] dm: usb: Adjust usb command to prepare for driver model
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 12/80] dm: usb: Adjust usb command to prepare for driver model Simon Glass
@ 2015-04-07 18:40   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:40 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> Use 'udev' instead of 'dev' in a few places, reserving 'dev' for driver
> model's struct udevice. Also adjust the code in a few minor ways to make
> it easier to plumb in driver model.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  common/cmd_usb.c | 51 +++++++++++++++++++++++++--------------------------
>  1 file changed, 25 insertions(+), 26 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 13/80] dm: usb: Adjust usb_alloc_new_device() to return an error
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 13/80] dm: usb: Adjust usb_alloc_new_device() to return an error Simon Glass
@ 2015-04-07 18:40   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:40 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> This function returns NULL on error at present. Adjust it so that we can
> return a real error, as is needed with driver model. Also improve the
> error handling in its caller, usb_hub_port_connect_change(), and adjust
> the code order to prepare for driver model.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  common/usb.c     | 17 ++++++++---------
>  common/usb_hub.c | 41 ++++++++++++++++++++++++++---------------
>  include/usb.h    | 20 ++++++++++++++++++--
>  3 files changed, 52 insertions(+), 26 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 14/80] dm: usb: Convert 'usb' command to support driver model
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 14/80] dm: usb: Convert 'usb' command to support driver model Simon Glass
@ 2015-04-07 18:40   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:40 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> Adjust this command to work with the new driver model uclass. It needs to
> iterate through multiple independent controllers to find hubs, and work
> through their children recursively in a different way. Otherwise the
> functionality is much the same.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  common/cmd_usb.c | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 145 insertions(+), 2 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 15/80] dm: usb: Drop the legacy USB init sequence
  2015-03-26 18:22   ` Marek Vasut
@ 2015-04-07 18:41     ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:41 UTC (permalink / raw)
  To: u-boot

On 26 March 2015 at 12:22, Marek Vasut <marex@denx.de> wrote:
> On Wednesday, March 25, 2015 at 07:22:03 PM, Simon Glass wrote:
>> This CONFIG is not used anywhere in U-Boot, so drop it.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>
> Acked-by: Marek Vasut <marex@denx.de>

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 16/80] dm: usb: Refactor port resets
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 16/80] dm: usb: Refactor port resets Simon Glass
@ 2015-04-07 18:41   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:41 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> Move the port reset code into its own function. Rename usb_hub_reset() to
> indicate that is is now a legacy function.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  common/usb.c     | 40 ++++++++++++++++++++++++++--------------
>  common/usb_hub.c |  4 ++--
>  include/usb.h    | 18 +++++++++++++++++-
>  3 files changed, 45 insertions(+), 17 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 17/80] dm: usb: Move descriptor setup code into its own function
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 17/80] dm: usb: Move descriptor setup code into its own function Simon Glass
@ 2015-04-07 18:41   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:41 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> usb_new_device() is far too long and does far too much. As a first step, move
> the code that does initial setup and reads a descriptor into its own function
> called usb_setup_descriptor().
>
> For XHCI the init order is different - we set up the device but don't
> actually read the descriptor until after we set an address. Support this
> option as a parameter to usb_setup_descriptor().
>
> Avoid changing this torturous code more than necessary to make it easy to
> review.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  common/usb.c | 117 ++++++++++++++++++++++++++++++++++-------------------------
>  1 file changed, 67 insertions(+), 50 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 18/80] dm: usb: Split out more code from usb_new_device()
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 18/80] dm: usb: Split out more code from usb_new_device() Simon Glass
@ 2015-04-07 18:41   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:41 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> Move the code that sets up the device with a new address into its own
> function, usb_prepare_device().
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  common/usb.c | 72 +++++++++++++++++++++++++++++++++++-------------------------
>  1 file changed, 42 insertions(+), 30 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 19/80] dm: usb: Complete the splitting up of usb_new_device()
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 19/80] dm: usb: Complete the splitting up of usb_new_device() Simon Glass
@ 2015-04-07 18:41   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:41 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> This function now calls usb_setup_device() to set up the device and
> usb_hub_probe() to check if it is a hub. The XHCI special case is now a
> parameter to usb_setup_device(). The latter will be used by the USB uclass
> when it is added, since it does not rely on any CONFIGs or legacy data
> structures.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  common/usb.c | 114 +++++++++++++++++++++++++++++++++++------------------------
>  1 file changed, 68 insertions(+), 46 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 20/80] dm: usb: Convert core usb.c file to support driver model
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 20/80] dm: usb: Convert core usb.c file to support driver model Simon Glass
@ 2015-04-07 18:41   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:41 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> Add the required #ifdefs and remove unwanted data structures so that the
> USB uclass will be able to use this file.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  common/usb.c | 31 +++++++++++++++++++++++++------
>  1 file changed, 25 insertions(+), 6 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 21/80] dm: usb: Split hub detection into its own function
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 21/80] dm: usb: Split hub detection into its own function Simon Glass
@ 2015-04-07 18:41   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:41 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> Split out the hub detection logic so it can be used by driver model. Also
> adjust the code to return errors correctly.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  common/usb_hub.c | 57 ++++++++++++++++++++++++++++++++++++++++----------------
>  1 file changed, 41 insertions(+), 16 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 22/80] dm: usb: Add driver model support for hubs
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 22/80] dm: usb: Add driver model support for hubs Simon Glass
@ 2015-04-07 18:41   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:41 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> Adjust the existing hub code to support driver model, and add a USB driver
> for hubs.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  common/usb_hub.c       | 94 +++++++++++++++++++++++++++++++++++++++++++++++---
>  include/dm/uclass-id.h |  1 +
>  2 files changed, 91 insertions(+), 4 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 23/80] dm: usb: Move USB storage definitions to usb_defs.h
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 23/80] dm: usb: Move USB storage definitions to usb_defs.h Simon Glass
@ 2015-04-07 18:42   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:42 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> These are better off in a header file so they can be used by other code (e.g.
> the sandbox USB storage emulator).
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  common/usb_storage.c | 45 ++-------------------------------------------
>  include/usb_defs.h   | 42 ++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 44 insertions(+), 43 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 24/80] dm: usb: Fix type problems in usb_stor_get_info()
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 24/80] dm: usb: Fix type problems in usb_stor_get_info() Simon Glass
@ 2015-04-07 18:42   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:42 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> This function assumes that unsigned long is 32-bits wide, but it is not
> on 64-bit machines. Use the correct type, and add a few debug() lines also.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  common/usb_storage.c | 18 +++++++++++-------
>  1 file changed, 11 insertions(+), 7 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 25/80] dm: usb: Simply device finding code in usb_storage
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 25/80] dm: usb: Simply device finding code in usb_storage Simon Glass
@ 2015-04-07 18:42   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:42 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> The for() loop is not needed since the value is immediately accessible.
> Use this instead to simplify the code.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  common/usb_storage.c | 30 +++++++++++-------------------
>  1 file changed, 11 insertions(+), 19 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 26/80] dm: usb: Adjust usb_storage to work with sandbox
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 26/80] dm: usb: Adjust usb_storage to work with sandbox Simon Glass
@ 2015-04-07 18:42   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:42 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> With a few tweaks we can compile this code with sandbox and enable testing
> of the USB storage layer.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  common/usb_storage.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 27/80] dm: usb: Move storage device scanning into its own function
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 27/80] dm: usb: Move storage device scanning into its own function Simon Glass
@ 2015-04-07 18:43   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:43 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> The usb_stor_scan() function is quite long, so split out the code that scans
> each device into its own function. Also, rather than setting up the block
> device list once at the start, set it up as each device is scanned. This
> makes it possible to use this code from driver model.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  common/usb_storage.c | 97 ++++++++++++++++++++++++++++++++--------------------
>  1 file changed, 59 insertions(+), 38 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 28/80] dm: usb: Convert usb_storage to driver model
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 28/80] dm: usb: Convert usb_storage to driver model Simon Glass
@ 2015-04-07 18:43   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:43 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> Add support for scanning USB storage devices with driver model. This mostly
> involves adding a USB device ID for storage devices.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  common/usb_storage.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 49 insertions(+), 2 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 29/80] dm: usb: Move all the EHCI weak functions together and declare them
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 29/80] dm: usb: Move all the EHCI weak functions together and declare them Simon Glass
@ 2015-04-07 18:43   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:43 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> Put these at the top of the file so they are in one place. Also add function
> prototypes to the header file to avoid call site mismatches.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/usb/host/ehci-hcd.c | 22 +++++++++++-----------
>  drivers/usb/host/ehci.h     |  6 ++++++
>  2 files changed, 17 insertions(+), 11 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 30/80] dm: usb: Pass EHCI controller pointer to ehci_get_port_speed()
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 30/80] dm: usb: Pass EHCI controller pointer to ehci_get_port_speed() Simon Glass
@ 2015-04-07 18:43   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:43 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> Adjust this function so that it is passed an EHCI controller pointer so that
> implementations can look up their controller.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/usb/host/ehci-faraday.c | 5 +++--
>  drivers/usb/host/ehci-hcd.c     | 4 ++--
>  drivers/usb/host/ehci-tegra.c   | 5 +++--
>  drivers/usb/host/ehci.h         | 2 +-
>  4 files changed, 9 insertions(+), 7 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 31/80] dm: usb: Allow ECHI to hold private data for the controller
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 31/80] dm: usb: Allow ECHI to hold private data for the controller Simon Glass
@ 2015-04-07 18:43   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:43 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> Add a private data pointer that clients of EHCI can use to access their
> private information. This establishes a link between struct ehci_ctrl and
> its associated controller data structure.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/usb/host/ehci-hcd.c | 10 ++++++++++
>  drivers/usb/host/ehci.h     | 21 +++++++++++++++++++++
>  2 files changed, 31 insertions(+)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 32/80] dm: usb: tegra: Store the controller type explicitly
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 32/80] dm: usb: tegra: Store the controller type explicitly Simon Glass
@ 2015-04-07 18:43   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:43 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> At present the tegra driver uses a separate pointer to know which controller
> type is in use. This works because only one controller type is used at a
> time.
>
> With driver model we want to make the controller state hermetic in the sense
> that it is not necessary to look elsewhere to know the controller type. This
> will permit a controller to implement the EHCI weak functions without
> reference to global data structures.
>
> To achieve this, define an enum for the controller type and store it with
> the information on each EHCI controller.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/usb/host/ehci-tegra.c | 30 ++++++++++++++++++++++++------
>  1 file changed, 24 insertions(+), 6 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 33/80] dm: usb: Pass EHCI controller pointer to ehci_powerup_fixup()
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 33/80] dm: usb: Pass EHCI controller pointer to ehci_powerup_fixup() Simon Glass
@ 2015-04-07 18:43   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:43 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> Adjust this function so that it is passed an EHCI controller pointer so that
> implementations can look up their controller.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  board/genesi/mx51_efikamx/efikamx-usb.c | 3 ++-
>  drivers/usb/host/ehci-hcd.c             | 5 +++--
>  drivers/usb/host/ehci-tegra.c           | 3 ++-
>  drivers/usb/host/ehci.h                 | 3 ++-
>  4 files changed, 9 insertions(+), 5 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 34/80] dm: usb: tegra: Drop use of global controller variable
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 34/80] dm: usb: tegra: Drop use of global controller variable Simon Glass
@ 2015-04-07 18:44   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:44 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> We don't need this anymore, so adjust the code to avoid using it.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/usb/host/ehci-tegra.c | 16 +++++++++-------
>  1 file changed, 9 insertions(+), 7 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 35/80] dm: usb: Pass EHCI controller pointer to ehci_set_usbmode()
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 35/80] dm: usb: Pass EHCI controller pointer to ehci_set_usbmode() Simon Glass
@ 2015-04-07 18:44   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:44 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> Adjust this function so that it is passed an EHCI controller pointer so that
> implementations can look up their controller. This makes the weak functions
> use a consistent API.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/usb/host/ehci-faraday.c | 2 +-
>  drivers/usb/host/ehci-hcd.c     | 6 +++---
>  drivers/usb/host/ehci-tegra.c   | 5 ++---
>  drivers/usb/host/ehci.h         | 2 +-
>  4 files changed, 7 insertions(+), 8 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 36/80] dm: usb: Pass EHCI controller pointer to ehci_get_portsc_register()
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 36/80] dm: usb: Pass EHCI controller pointer to ehci_get_portsc_register() Simon Glass
@ 2015-04-07 18:44   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:44 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> Adjust this function so that it is passed an EHCI controller pointer so that
> implementations can look up their controller. This makes the weak functions
> use a consistent API.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/usb/host/ehci-faraday.c | 4 ++--
>  drivers/usb/host/ehci-hcd.c     | 6 +++---
>  drivers/usb/host/ehci.h         | 2 +-
>  3 files changed, 6 insertions(+), 6 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 37/80] dm: usb: ehci: Use a function to find the controller from struct udevice
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 37/80] dm: usb: ehci: Use a function to find the controller from struct udevice Simon Glass
@ 2015-04-07 18:44   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:44 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> With driver model we want to remove the controller pointer in struct udevice
> and use driver model data structures instead. To prepare for this, move
> access to this field to a function which can provide a different
> implementation for driver model.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/usb/host/ehci-hcd.c | 54 +++++++++++++++++++++++++++++++--------------
>  1 file changed, 37 insertions(+), 17 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 38/80] dm: usb: Refactor EHCI init
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 38/80] dm: usb: Refactor EHCI init Simon Glass
@ 2015-04-07 18:44   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:44 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> Move the bulk of the code in usb_lowlevel_init() into a separate function
> which will also be used by driver model. Keep the CONFIG options out of
> this function by providing a tweak flag for Faraday. We need to avoid using
> CONFIG options in driver model code where possible, since it makes it
> impossible to use multiple controllers in that code where they have
> different options.
>
> The CONFIG_EHCI_HCD_INIT_AFTER_RESET option is also kept out of the
> common init function. With driver model the controller will be able to
> perform this extra init itself after registering with the EHCI layer.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/usb/host/ehci-hcd.c | 117 +++++++++++++++++++++++++-------------------
>  drivers/usb/host/ehci.h     |   6 +++
>  2 files changed, 72 insertions(+), 51 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 39/80] dm: usb: Drop the EHCI weak functions
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 39/80] dm: usb: Drop the EHCI weak functions Simon Glass
@ 2015-04-07 18:44   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:44 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> These are a pain with driver model because we might have different EHCI
> drivers which want to implement them differently. Now that they use
> consistent function signatures, we can in good conscience move them to
> a struct.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  board/genesi/mx51_efikamx/efikamx-usb.c |   5 +-
>  drivers/usb/host/ehci-faraday.c         | 113 +++++++++++++++-----------------
>  drivers/usb/host/ehci-hcd.c             |  49 +++++++++++---
>  drivers/usb/host/ehci-mx5.c             |  12 ++++
>  drivers/usb/host/ehci-tegra.c           |  26 ++++----
>  drivers/usb/host/ehci.h                 |  27 +++++---
>  6 files changed, 136 insertions(+), 96 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 40/80] dm: usb: Change ehci_reset() to use a pointer
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 40/80] dm: usb: Change ehci_reset() to use a pointer Simon Glass
@ 2015-04-07 18:44   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:44 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> The index cannot be used with driver model, and isn't needed anyway. Change
> the parameter to a pointer.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/usb/host/ehci-hcd.c | 17 ++++++++---------
>  1 file changed, 8 insertions(+), 9 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 41/80] dm: usb: Add driver model support to EHCI
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 41/80] dm: usb: Add driver model support to EHCI Simon Glass
@ 2015-04-07 18:44   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:44 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> Add a way for EHCI controller drivers to support driver model. Drivers can
> call ehci_register() to register themselves in their probe() methods.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/usb/host/ehci-hcd.c | 125 ++++++++++++++++++++++++++++++++++++++++++--
>  drivers/usb/host/ehci.h     |   6 +++
>  2 files changed, 127 insertions(+), 4 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 42/80] dm: usb: Allow USB drivers to be declared and auto-probed
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 42/80] dm: usb: Allow USB drivers to be declared and auto-probed Simon Glass
@ 2015-04-07 18:45   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:45 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> USB devices in U-Boot are currently probed only after all devices have
> been enumerated. Each type of device is probed by custom code, e.g.:
>
> - USB storage
> - Keyboard
> - Ethernet
>
> With driver model this approach doesn't work very well. We could build
> a picture of the bus and then go back and add the devices later, but
> this means that the data structures are incomplete for quite a while.
> It also does not follow the model of being able to bind a device when we
> discover it.
>
> We would prefer to have devices automatically be bound as the device is
> enumerated. This allows us to attach drivers to particular USB classes
> or product/vendor IDs. This is the method used by Linux.
>
> Add the required #defines from Linux, a way of declaring a USB driver and
> the logic to locate the correct driver given the USB device's descriptors.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/usb/host/usb-uclass.c | 206 +++++++++++++++++++++++++++++++++++++++++-
>  include/usb.h                 | 107 ++++++++++++++++++++++
>  2 files changed, 311 insertions(+), 2 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 43/80] dm: usb: Bind generic USB devices when there is no driver
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 43/80] dm: usb: Bind generic USB devices when there is no driver Simon Glass
@ 2015-04-07 18:45   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:45 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> At present USB devices with no driver model driver cannot be seen in the
> device list, and we fail to set them up correctly. This means they cannot
> be used.
>
> While having real drivers that support driver model for all USB devices
> is the eventual goal, we are not there yet.
>
> As a stop-gap, add a generic USB driver which is bound when we do not have
> a real driver. This allows the device to be set up and shown on the bus.
> It also allows ad-hoc code (such as usb_ether) to find these devices and
> set them up.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/usb/host/usb-uclass.c | 18 +++++++++++++++++-
>  include/dm/uclass-id.h        |  1 +
>  2 files changed, 18 insertions(+), 1 deletion(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 44/80] dm: usb: Allow setting up a USB controller as a device/gadget
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 44/80] dm: usb: Allow setting up a USB controller as a device/gadget Simon Glass
@ 2015-04-07 18:45   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:45 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> Some controllers support OTG (on-the-go) where they can operate as either
> host or device. The gadget layer in U-Boot supports this.
>
> While this layer does not interact with driver model, we can provide a
> function which sets up the controller in the correct way. This way the code
> at least builds (although it likely will not work).
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/usb/gadget/ci_udc.c   |  4 ++++
>  drivers/usb/host/usb-uclass.c | 24 ++++++++++++++++++++++++
>  2 files changed, 28 insertions(+)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 45/80] dm: usb: Split out the keyboard probe into its own function
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 45/80] dm: usb: Split out the keyboard probe into its own function Simon Glass
@ 2015-04-07 18:45   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:45 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> Before adding driver model support, split out code from this over-long
> function.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  common/usb_kbd.c | 89 ++++++++++++++++++++++++++++++++------------------------
>  1 file changed, 51 insertions(+), 38 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 46/80] dm: usb: Support driver model with USB keyboards
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 46/80] dm: usb: Support driver model with USB keyboards Simon Glass
@ 2015-04-07 18:45   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 18:45 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> Allow USB keyboards to work with driver model. The main difference is that
> we can have multiple buses (each with its own device numbering) and each
> bus must be scanned.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  common/usb_kbd.c | 34 +++++++++++++++++++++++++++++++++-
>  1 file changed, 33 insertions(+), 1 deletion(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 47/80] dm: usb: tegra: Add vbus GPIOs for nyan
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 47/80] dm: usb: tegra: Add vbus GPIOs for nyan Simon Glass
@ 2015-04-07 19:09   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 19:09 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> These are needed to enable the USB bus (although not sufficient since it
> still does not work).
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  arch/arm/dts/tegra124-nyan-big.dts | 2 ++
>  1 file changed, 2 insertions(+)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 48/80] dm: usb: Move struct usb_string to a common place
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 48/80] dm: usb: Move struct usb_string to a common place Simon Glass
@ 2015-04-07 19:09   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 19:09 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> This is needed for sandbox USB device emulation, so move it to a place
> where it can be found by things other than gadgets.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  include/linux/usb/ch9.h    | 13 +++++++++++++
>  include/linux/usb/gadget.h | 13 -------------
>  2 files changed, 13 insertions(+), 13 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 49/80] dm: usb: sandbox: Add a uclass for USB device emulation
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 49/80] dm: usb: sandbox: Add a uclass for USB device emulation Simon Glass
@ 2015-04-07 19:09   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 19:09 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> With sandbox we want to be able to emulate USB devices so that we can test
> the USB stack. Add a uclass to support this. It implements the same
> operations as a normal USB device driver, but in this case passes them on
> to an emulation driver.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  Makefile                           |   1 +
>  drivers/usb/Kconfig                |   2 +
>  drivers/usb/emul/Kconfig           |   8 ++
>  drivers/usb/emul/Makefile          |   8 ++
>  drivers/usb/emul/usb-emul-uclass.c | 263 +++++++++++++++++++++++++++++++++++++
>  include/dm/uclass-id.h             |   1 +
>  include/usb.h                      |  64 ++++++++-
>  7 files changed, 346 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/usb/emul/Kconfig
>  create mode 100644 drivers/usb/emul/Makefile
>  create mode 100644 drivers/usb/emul/usb-emul-uclass.c

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 50/80] dm: usb: sandbox: Reset emulation devices in usb stop()
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 50/80] dm: usb: sandbox: Reset emulation devices in usb stop() Simon Glass
@ 2015-04-07 19:10   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 19:10 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> These devices must have their addresses removed ready for the next USB
> bus enumeration. Add this logic to usb_stop().
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/usb/host/usb-uclass.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 51/80] dm: usb: sandbox: Add an emulator for USB flash devices
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 51/80] dm: usb: sandbox: Add an emulator for USB flash devices Simon Glass
@ 2015-04-07 19:10   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 19:10 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> This emulator supports USB enumeration and allows a local file to be provided
> as the contents of the emulated flash stick. U-Boot can then use the file as
> it would a normal device, with all access passing through the usb_stor layer
> and the USB stack.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/usb/emul/Makefile        |   1 +
>  drivers/usb/emul/sandbox_flash.c | 423 +++++++++++++++++++++++++++++++++++++++
>  include/dm/uclass-id.h           |   1 +
>  3 files changed, 425 insertions(+)
>  create mode 100644 drivers/usb/emul/sandbox_flash.c

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 52/80] dm: usb: sandbox: Add an emulator for USB hub emulation
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 52/80] dm: usb: sandbox: Add an emulator for USB hub emulation Simon Glass
@ 2015-04-07 19:10   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 19:10 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> All USB controllers need a root hub. Add a sandbox emulation for this so
> that we can add USB devices to sandbox.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/usb/emul/Makefile      |   1 +
>  drivers/usb/emul/sandbox_hub.c | 303 +++++++++++++++++++++++++++++++++++++++++
>  include/usb_defs.h             |   3 +
>  3 files changed, 307 insertions(+)
>  create mode 100644 drivers/usb/emul/sandbox_hub.c

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 53/80] dm: usb: sandbox: Add a driver for sandbox
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 53/80] dm: usb: sandbox: Add a driver for sandbox Simon Glass
@ 2015-04-07 19:10   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 19:10 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> This driver supports using emulation devices to provide a USB bus within
> sandbox.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/usb/host/Makefile      |   1 +
>  drivers/usb/host/usb-sandbox.c | 117 +++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 118 insertions(+)
>  create mode 100644 drivers/usb/host/usb-sandbox.c

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 54/80] dm: usb: dts: sandbox: Add some sample USB devices to sandbox
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 54/80] dm: usb: dts: sandbox: Add some sample USB devices to sandbox Simon Glass
@ 2015-04-07 19:10   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 19:10 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> These allow basic testing of the USB functionality within sandbox.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  arch/sandbox/dts/sandbox.dts | 40 ++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 40 insertions(+)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 55/80] dm: usb: Add support for USB ethernet devices with driver model
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 55/80] dm: usb: Add support for USB ethernet devices with driver model Simon Glass
@ 2015-04-07 19:10   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 19:10 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> Add support for scanning USB etghernet devices with driver model. This mostly
> involves scanning all buses since device numbering is not unique across
> buses.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/usb/eth/usb_ether.c | 52 ++++++++++++++++++++++++++++++++++++++-------
>  1 file changed, 44 insertions(+), 8 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 56/80] dm: usb: exynos: Add driver model support to exynos EHCI
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 56/80] dm: usb: exynos: Add driver model support to exynos EHCI Simon Glass
@ 2015-04-07 19:10   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 19:10 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> Update this driver with driver model support for USB.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/usb/host/ehci-exynos.c | 112 ++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 111 insertions(+), 1 deletion(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 57/80] dm: usb: tegra: Remove the port_addr_clear_csc variable
  2015-03-26  9:01     ` Jim Lin
@ 2015-04-07 19:10       ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 19:10 UTC (permalink / raw)
  To: u-boot

On 26 March 2015 at 03:01, Jim Lin <jilin@nvidia.com> wrote:
> Please ignore my question because it is answered by [PATCH v2 34/80].
>
>
> On 03/26/2015 11:38 AM, Jim Lin wrote:
>>>
>>> -----Original Message-----
>>> From: U-Boot [mailto:u-boot-bounces at lists.denx.de] On Behalf Of Simon
>>> Glass
>>> Sent: Thursday, March 26, 2015 2:23 AM
>>> To: U-Boot Mailing List
>>> Cc: Marek Vasut; Stephen Warren; Vivek Gautam; Tom Warren
>>> Subject: [U-Boot] [PATCH v2 57/80] dm: usb: tegra: Remove the
>>> port_addr_clear_csc variable
>>>
>>> This variable is a bit of a hack. We can obtain the same information from
>>> the normal device config. This will fit better with driver model, where
>>> global variables > are best avoided.
>>>
>>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>> ---
>>>
>>> Changes in v2: None
>>>
>>>   drivers/usb/host/ehci-tegra.c | 6 +-----
>>>   1 file changed, 1 insertion(+), 5 deletions(-)
>>>
>>> diff --git a/drivers/usb/host/ehci-tegra.c
>>> b/drivers/usb/host/ehci-tegra.c index 38333c7..464f55d 100644
>>> --- a/drivers/usb/host/ehci-tegra.c
>>> +++ b/drivers/usb/host/ehci-tegra.c
>>> @@ -87,8 +87,6 @@ struct fdt_usb {
>>>     static struct fdt_usb port[USB_PORTS_MAX];  /* List of valid USB
>>> ports */
>>>   static unsigned port_count;                   /* Number of available
>>> ports */
>>> -/* Port that needs to clear CSC after Port Reset */ -static u32
>>> port_addr_clear_csc;
>>>     /*
>>>    * This table has USB timing parameters for each Oscillator frequency
>>> we @@ -206,7 +204,7 @@ static void tegra_ehci_powerup_fixup(struct ehci_ctrl
>>> *ctrl,
>>
>>         if (controller->has_hostpc)
>>>
>>>                 *reg |= EHCI_PS_PE;
>>>   -     if (((u32)status_reg & TEGRA_USB_ADDR_MASK) !=
>>> port_addr_clear_csc)
>>> +       if (!config->has_legacy_mode)
>>>                 return;
>>
>> How do we get config (config->has_legacy_mode) for in this function?
>> If you read ehci_set_usbmode, "config"  comes from
>> "config = &port[index];".
>> Or "config" is an input argument like set_up_vbus(struct fdt_usb *config,
>> ...)
>> But for ehci_powerup_fixup, I don't see a way for us to get "config".
>>
>>>         /* For EHCI_PS_CSC to be cleared in ehci_hcd.c */
>>
>> --nvpublic
>> _______________________________________________
>> U-Boot mailing list
>> U-Boot at lists.denx.de
>> http://lists.denx.de/mailman/listinfo/u-boot
>
>

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 58/80] dm: usb: tegra: Tidy up error handling and a static function
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 58/80] dm: usb: tegra: Tidy up error handling and a static function Simon Glass
@ 2015-04-07 19:10   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 19:10 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> Try to return useful error numbers where possible. Also avoid swallowing
> an error number when it is returned by a called function.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/usb/host/ehci-tegra.c | 19 +++++++++++--------
>  1 file changed, 11 insertions(+), 8 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 59/80] dm: usb: tegra: Move most of init/uninit into a function
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 59/80] dm: usb: tegra: Move most of init/uninit into a function Simon Glass
@ 2015-04-07 19:10   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 19:10 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> We want to use mostly the same init and uninit code for driver model, so move
> the common part into two functions.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/usb/host/ehci-tegra.c | 143 ++++++++++++++++++++++++------------------
>  1 file changed, 81 insertions(+), 62 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 60/80] dm: usb: tegra: Add driver model support to tegra EHCI
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 60/80] dm: usb: tegra: Add driver model support to tegra EHCI Simon Glass
@ 2015-04-07 19:10   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 19:10 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> Update this driver with driver model support for USB.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/usb/host/ehci-tegra.c | 83 +++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 83 insertions(+)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 61/80] dm: usb: xhci: Use a function to get xhci_ctrl
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 61/80] dm: usb: xhci: Use a function to get xhci_ctrl Simon Glass
@ 2015-04-07 19:11   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 19:11 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> Rather than getting this directly from struct usb_device, call a function
> to obtain it. This will make it possible for driver model to provide it
> another way.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/usb/host/xhci-ring.c |  8 ++++----
>  drivers/usb/host/xhci.c      | 19 ++++++++++++-------
>  drivers/usb/host/xhci.h      |  2 ++
>  3 files changed, 18 insertions(+), 11 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 62/80] dm: usb: xhci: Use explicit parameters for xhci_alloc_virt_device()
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 62/80] dm: usb: xhci: Use explicit parameters for xhci_alloc_virt_device() Simon Glass
@ 2015-04-07 19:11   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 19:11 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> This function should not be delving into struct usb_device. Pass in the
> parameters it needs directly.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/usb/host/xhci-mem.c | 4 +---
>  drivers/usb/host/xhci.c     | 2 +-
>  drivers/usb/host/xhci.h     | 2 +-
>  3 files changed, 3 insertions(+), 5 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 63/80] dm: usb: xhci: Use explicit parameters for xhci_setup_addressable_virt_dev()
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 63/80] dm: usb: xhci: Use explicit parameters for xhci_setup_addressable_virt_dev() Simon Glass
@ 2015-04-07 19:11   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 19:11 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> This function should not be delving into struct usb_device. Pass in the
> parameters it needs directly.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/usb/host/xhci-mem.c | 19 +++++++------------
>  drivers/usb/host/xhci.c     | 29 ++++++++++++++++++++++-------
>  drivers/usb/host/xhci.h     |  3 ++-
>  3 files changed, 31 insertions(+), 20 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 64/80] dm: usb: xhci: Factor out common init/uninit
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 64/80] dm: usb: xhci: Factor out common init/uninit Simon Glass
@ 2015-04-07 19:11   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 19:11 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> Since driver model will want to use most of the same code for XHCI init
> and uninit, put it in a separate function.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/usb/host/xhci.c | 85 ++++++++++++++++++++++++++++++-------------------
>  1 file changed, 52 insertions(+), 33 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 65/80] dm: usb: Support driver model in XHCI
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 65/80] dm: usb: Support driver model in XHCI Simon Glass
@ 2015-04-07 19:11   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 19:11 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> Add driver model support in the XHCI support code so that it can be used by
> XHCI USB drivers.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/usb/host/xhci-mem.c |   1 +
>  drivers/usb/host/xhci.c     | 179 ++++++++++++++++++++++++++++++++++++++++++--
>  drivers/usb/host/xhci.h     |  24 ++++++
>  3 files changed, 197 insertions(+), 7 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 66/80] dm: usb: Rename the XHCI HCD to U-Boot
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 66/80] dm: usb: Rename the XHCI HCD to U-Boot Simon Glass
@ 2015-04-07 19:11   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 19:11 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> This should be "U-Boot", not "u-boot".
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/usb/host/xhci.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 67/80] dm: usb: exynos: Adjust XHCI driver to support driver model
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 67/80] dm: usb: exynos: Adjust XHCI driver to support driver model Simon Glass
@ 2015-04-07 19:11   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 19:11 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> Support driver model in the exynos XHCI driver.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/usb/host/xhci-exynos5.c | 120 +++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 119 insertions(+), 1 deletion(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 68/80] dm: usb: exynos: Use driver model for USB
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 68/80] dm: usb: exynos: Use driver model for USB Simon Glass
@ 2015-04-07 19:11   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 19:11 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> Convert Exynos boards over to use driver model for USB. This does not remove
> any unnecessary code so far.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  arch/arm/cpu/armv7/exynos/Kconfig | 3 +++
>  1 file changed, 3 insertions(+)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 69/80] dm: usb: exynos: Enable both USB ports on snow
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 69/80] dm: usb: exynos: Enable both USB ports on snow Simon Glass
@ 2015-04-07 19:11   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 19:11 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> Switch snow over to use both EHCI and XHCI at the same time.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  include/configs/snow.h | 2 ++
>  1 file changed, 2 insertions(+)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 70/80] dm: usb: exynos: Enable both EHCI and XHCI on snow
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 70/80] dm: usb: exynos: Enable both EHCI and XHCI " Simon Glass
@ 2015-04-07 19:11   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 19:11 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> Since we can support both controllers now, enable this in the device tree.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  arch/arm/dts/exynos5250-snow.dts | 1 +
>  1 file changed, 1 insertion(+)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 71/80] dm: usb: tegra: Move to driver model for USB
  2015-03-25 18:22 ` [U-Boot] [PATCH v2 71/80] dm: usb: tegra: Move to driver model for USB Simon Glass
@ 2015-04-07 19:11   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 19:11 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:22, Simon Glass <sjg@chromium.org> wrote:
> Move Tegra boards over to driver model for USB EHCI. There are a few things
> that are no-longer needed (e.g. in fdtdec.h) but these will be cleaned up
> in a later patch to be applied one we are confident this change is fully
> tested.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  arch/arm/mach-tegra/Kconfig | 3 +++
>  board/nvidia/common/board.c | 2 ++
>  2 files changed, 5 insertions(+)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 72/80] dm: usb: Add a generic descriptor struct
  2015-03-25 18:23 ` [U-Boot] [PATCH v2 72/80] dm: usb: Add a generic descriptor struct Simon Glass
@ 2015-04-07 19:11   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 19:11 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:23, Simon Glass <sjg@chromium.org> wrote:
> This is useful for creating lists of descriptors, and is better than using
> void * for this purpose.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  include/linux/usb/ch9.h | 5 +++++
>  1 file changed, 5 insertions(+)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 73/80] dm: usb: Tidy up pipe value decoding
  2015-03-25 18:23 ` [U-Boot] [PATCH v2 73/80] dm: usb: Tidy up pipe value decoding Simon Glass
@ 2015-04-07 19:12   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 19:12 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:23, Simon Glass <sjg@chromium.org> wrote:
> Add a few more shifts/masks to make it easier to decode a pipe value (rather
> than just building it). We need this for USB device emulation.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  include/usb_defs.h | 23 +++++++++++++++++------
>  1 file changed, 17 insertions(+), 6 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 74/80] dm: usb: sandbox: Enable USB
  2015-03-25 18:23 ` [U-Boot] [PATCH v2 74/80] dm: usb: sandbox: Enable USB Simon Glass
@ 2015-04-07 19:12   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 19:12 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:23, Simon Glass <sjg@chromium.org> wrote:
> Enable USB emulation and associated features so that USB can be used in
> sandbox.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  configs/sandbox_defconfig | 4 ++++
>  include/configs/sandbox.h | 2 ++
>  2 files changed, 6 insertions(+)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 75/80] dm: test: Correct printf() output nit in 'dm uclass'
  2015-03-25 18:23 ` [U-Boot] [PATCH v2 75/80] dm: test: Correct printf() output nit in 'dm uclass' Simon Glass
@ 2015-04-07 19:12   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 19:12 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:23, Simon Glass <sjg@chromium.org> wrote:
> Neither the hyphen nor the equals sign is needed.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  test/dm/cmd_dm.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 76/80] dm: test: Allow 'dm test' to select a particular test to run
  2015-03-25 18:23 ` [U-Boot] [PATCH v2 76/80] dm: test: Allow 'dm test' to select a particular test to run Simon Glass
@ 2015-04-07 19:12   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 19:12 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:23, Simon Glass <sjg@chromium.org> wrote:
> As well as running all tests, it is useful to be able to run a selected test.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  include/dm/test.h   |  7 ++++---
>  test/dm/cmd_dm.c    | 11 ++++++++---
>  test/dm/test-main.c |  7 +++++--
>  3 files changed, 17 insertions(+), 8 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 77/80] dm: usb: Add tests for the USB uclass
  2015-03-25 18:23 ` [U-Boot] [PATCH v2 77/80] dm: usb: Add tests for the USB uclass Simon Glass
@ 2015-04-07 19:12   ` Simon Glass
  2015-04-21  5:24   ` Joe Hershberger
  1 sibling, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-07 19:12 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:23, Simon Glass <sjg@chromium.org> wrote:
> This adds a simple test for probing and a functional test using the flash
> stick emulator, which tests a large chunk of the USB stack.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  test/dm/Makefile   |  1 +
>  test/dm/test-dm.sh |  3 +++
>  test/dm/test.dts   | 41 +++++++++++++++++++++++++++++++++++++++++
>  test/dm/usb.c      | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 95 insertions(+)
>  create mode 100644 test/dm/usb.c

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 80/80] dm: usb: Add a README for driver model
  2015-04-07  3:24   ` Jim Lin
@ 2015-04-08  1:40     ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-08  1:40 UTC (permalink / raw)
  To: u-boot

Hi Jim,

On 6 April 2015 at 21:24, Jim Lin <jilin@nvidia.com> wrote:
> There are some typos. Please correct them, thanks.
>
>
> On 03/26/2015 02:23 AM, Simon Glass wrote:
>>
>> Add some documentation describing how USB is implemented with USB. This
>> might make things easier for people to understand.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>>
>> Changes in v2:
>> - Rewrite and expand series to support driver model fully
>>
>>   doc/driver-model/usb-info.txt | 415
>> ++++++++++++++++++++++++++++++++++++++++++
>>   1 file changed, 415 insertions(+)
>>   create mode 100644 doc/driver-model/usb-info.txt
>>
>> diff --git a/doc/driver-model/usb-info.txt b/doc/driver-model/usb-info.txt
>> new file mode 100644
>> index 0000000..3762b6c
>> --- /dev/null
>> +++ b/doc/driver-model/usb-info.txt
>> @@ -0,0 +1,415 @@
>> +How USB works with driver model
>> +===============================
>> +
>> +Introduction
>> +------------
>> +
>> +Driver model USB support makes use of existing features but changes how
>> +drivers are found. This document provides some information intended to
>> help
>> +understand how things work with USB in U-Boot when driver model is
>> enabled.
>> +
>> +
>> +Enabling driver model for USB
>> +-----------------------------
>> +
>> +A new CONFIG_DM_USB option is provided to enable driver model for USB.
>> This
>> +causes the USB uclass to be included, and drops the equivalent code in
>> +usb.c. In particular the usb_init() function is then implemented by the
>> +uclass.
>> +
>> +
>> +Support for ECHI and XCHI
>
> EHCI
> XHCI
>
>
>> +-------------------------
>> +
>> +So far OHCI is not supported. Both EHCI and XHCI drivers should be
>> declared
>> +as drivers in the USB uclass. For example:
>> +
>> +static const struct udevice_id ehci_usb_ids[] = {
>> +       { .compatible = "nvidia,tegra20-ehci", .data = USB_CTLR_T20 },
>> +       { .compatible = "nvidia,tegra30-ehci", .data = USB_CTLR_T30 },
>> +       { .compatible = "nvidia,tegra114-ehci", .data = USB_CTLR_T114 },
>> +       { }
>> +};
>> +
>> +U_BOOT_DRIVER(usb_ehci) = {
>> +       .name   = "ehci_tegra",
>> +       .id     = UCLASS_USB,
>> +       .of_match = ehci_usb_ids,
>> +       .ofdata_to_platdata = ehci_usb_ofdata_to_platdata,
>> +       .probe = tegra_ehci_usb_probe,
>> +       .remove = tegra_ehci_usb_remove,
>> +       .ops    = &ehci_usb_ops,
>> +       .platdata_auto_alloc_size = sizeof(struct usb_platdata),
>> +       .priv_auto_alloc_size = sizeof(struct fdt_usb),
>> +       .flags  = DM_FLAG_ALLOC_PRIV_DMA,
>> +};
>> +
>> +Here ehci_usb_ids is used to list the controllers that the driver
>> supports.
>> +Each has its own data value. Controllers must be in the UCLASS_USB
>> uclass.
>> +
>> +The ofdata_to_platdata() method allows the controller driver to grab any
>> +necessary settings from the device tree.
>> +
>> +The ops here are ehci_usb_ops. All EHCI drivers will use these same ops
>> in
>> +most cases, since they are all ECHI-compatible. For ECHI there are also
>> some
>
> EHCI-compatible
> For EHCI
>>
>> +special operations that can be overriden when calling ehci_register().
>
> overridden
>
>> +This defines a single controller, containing a root hub (which is
>> required).
>> +The hub is emulated by a hub emulator, and the emulated hub has a single
>> +flash stick to emulate on one of its ports.
>> +
>> +When 'usb start' is used, the following 'dm tree' output will be
>> available:
>> +
>> + usb         [ + ]    `-- usb at 1
>> + usb_hub     [ + ]        `-- hub
>> + usb_emul    [ + ]            |-- hub-emul
>> + usb_emul    [ + ]            |   `-- flash-stick
>> + usb_mass_st [ + ]            `-- usb_mass_storage
>> +
>> +
>> +This may look a confusing. Most of it mirrors the device tree, but the
>
> may look confusing
> --nvpublic

Thanks for the corrections, I fixed these.

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 77/80] dm: usb: Add tests for the USB uclass
  2015-03-25 18:23 ` [U-Boot] [PATCH v2 77/80] dm: usb: Add tests for the USB uclass Simon Glass
  2015-04-07 19:12   ` Simon Glass
@ 2015-04-21  5:24   ` Joe Hershberger
  2015-04-21 13:14     ` Simon Glass
  1 sibling, 1 reply; 178+ messages in thread
From: Joe Hershberger @ 2015-04-21  5:24 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Wed, Mar 25, 2015 at 1:23 PM, Simon Glass <sjg@chromium.org> wrote:
> This adds a simple test for probing and a functional test using the flash
> stick emulator, which tests a large chunk of the USB stack.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>

I'm seeing a seg fault when running the dm tests and bisected it to this patch.

I'm not sure why it's related, but it appears to seg fault on a GPIO test...


U-Boot 2015.04-00280-ge00cb22-dirty (Apr 21 2015 - 00:02:01)

DRAM:  128 MiB
Using default environment

In:    serial
Out:   lcd
Err:   lcd
Net:   eth0: eth at 10002000, eth5: eth at 10003000, eth1: eth at 10004000
Running 53 driver model tests
Test: dm_test_autobind
Test: dm_test_autoprobe
Test: dm_test_bus_child_post_bind
Test: dm_test_bus_child_post_bind_uclass
Test: dm_test_bus_child_pre_probe_uclass
Test: dm_test_bus_children
Device 'c-test at 0': seq 0 is in use by 'd-test'
Device 'c-test at 1': seq 1 is in use by 'f-test'
Test: dm_test_bus_children_funcs
Test: dm_test_bus_children_iterators
Test: dm_test_bus_parent_data
Test: dm_test_bus_parent_data_uclass
Test: dm_test_bus_parent_ops
Test: dm_test_bus_parent_platdata
Test: dm_test_bus_parent_platdata_uclass
Test: dm_test_children
Test: dm_test_device_get_uclass_id
Test: dm_test_eth
Using eth at 10002000 device
Using eth at 10003000 device
Using eth at 10004000 device
Test: dm_test_eth_alias
Using eth at 10002000 device
Using eth at 10004000 device
Using eth at 10002000 device
Using eth at 10003000 device
Test: dm_test_eth_prime
Using eth at 10003000 device
Using eth at 10002000 device
Test: dm_test_eth_rotate

Error: eth at 10004000 address not set.

Error: eth at 10004000 address not set.
Using eth at 10002000 device

Error: eth at 10004000 address not set.

Error: eth at 10004000 address not set.
Using eth at 10004000 device
Test: dm_test_fdt
Test: dm_test_fdt_offset
Test: dm_test_fdt_pre_reloc
Test: dm_test_fdt_uclass_seq
Test: dm_test_gpio
extra-gpios: get_value: error: gpio b5 not reserved
Test: dm_test_gpio_anon
Test: dm_test_gpio_copy
Test: dm_test_gpio_leak
extra-gpios: get_value: error: gpio b5 not reserved

Program received signal SIGSEGV, Segmentation fault.
0x000009ec in ?? ()
(gdb) bt
#0  0x000009ec in ?? ()
#1  0x0806a0aa in uclass_destroy (uc=0xb5abd228) at
/home/joe/u-boot/drivers/core/uclass.c:109
#2  0x080a29e1 in dm_leak_check_end (dms=0x8106870) at
/home/joe/u-boot/test/dm/core.c:89
#3  0x080a46a6 in dm_test_gpio_leak (dms=0x8106870) at
/home/joe/u-boot/test/dm/gpio.c:173
#4  0x080a0ed2 in dm_test_main (test_name=0x0) at
/home/joe/u-boot/test/dm/test-main.c:103
#5  0x0809e9fb in do_dm (cmdtp=0x80c0250, flag=0, argc=135022648,
argv=0xb5abbd40) at /home/joe/u-boot/test/dm/cmd_dm.c:150
#6  0x08065d6b in cmd_process (flag=0, argc=2, argv=0xb5abbd40,
repeatable=0x80c5fc4, ticks=0x0) at
/home/joe/u-boot/common/command.c:493
#7  0x0804d6fb in run_list_real (pi=0xb5abbc88) at
/home/joe/u-boot/common/cli_hush.c:1656
#8  0x0804dce4 in parse_stream_outer (inp=0xbffff0e8, flag=2) at
/home/joe/u-boot/common/cli_hush.c:2003
#9  0x0804df1d in parse_string_outer (s=0xbffff513 "dm test", flag=2)
at /home/joe/u-boot/common/cli_hush.c:3248
#10 0x0804a855 in sandbox_main_loop_init () at
/home/joe/u-boot/arch/sandbox/cpu/start.c:85
#11 0x0804e65b in run_main_loop () at /home/joe/u-boot/common/board_r.c:682
#12 0x0808f082 in initcall_run_list (init_sequence=0x80c1f68) at
/home/joe/u-boot/lib/initcall.c:27
#13 0x0804e798 in board_init_r (new_gd=0xb5ab9f14, dest_addr=0) at
/home/joe/u-boot/common/board_r.c:916
#14 0x0804a810 in main (argc=Cannot access memory at address 0x0
) at /home/joe/u-boot/arch/sandbox/cpu/start.c:276
(gdb) f 1
#1  0x0806a0aa in uclass_destroy (uc=0xb5abd228) at
/home/joe/u-boot/drivers/core/uclass.c:109
109                     ret = device_unbind(dev);
(gdb) l -
99      int uclass_destroy(struct uclass *uc)
100     {
101             struct uclass_driver *uc_drv;
102             struct udevice *dev, *tmp;
103             int ret;
104
105             list_for_each_entry_safe(dev, tmp, &uc->dev_head, uclass_node) {
106                     ret = device_remove(dev);
107                     if (ret)
108                             return ret;
(gdb) l
109                     ret = device_unbind(dev);
110                     if (ret)
111                             return ret;
112             }
113
114             uc_drv = uc->uc_drv;
115             if (uc_drv->destroy)
116                     uc_drv->destroy(uc);
117             list_del(&uc->sibling_node);
118             if (uc_drv->priv_auto_alloc_size)
(gdb)


Thoughts?
-Joe

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 77/80] dm: usb: Add tests for the USB uclass
  2015-04-21  5:24   ` Joe Hershberger
@ 2015-04-21 13:14     ` Simon Glass
  2015-04-21 16:05       ` Joe Hershberger
  0 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-04-21 13:14 UTC (permalink / raw)
  To: u-boot

Hi Joe,

On 20 April 2015 at 23:24, Joe Hershberger <joe.hershberger@gmail.com> wrote:
> Hi Simon,
>
> On Wed, Mar 25, 2015 at 1:23 PM, Simon Glass <sjg@chromium.org> wrote:
>> This adds a simple test for probing and a functional test using the flash
>> stick emulator, which tests a large chunk of the USB stack.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>
> I'm seeing a seg fault when running the dm tests and bisected it to this patch.
>
> I'm not sure why it's related, but it appears to seg fault on a GPIO test...
>
>
> U-Boot 2015.04-00280-ge00cb22-dirty (Apr 21 2015 - 00:02:01)
>
> DRAM:  128 MiB
> Using default environment
>
> In:    serial
> Out:   lcd
> Err:   lcd
> Net:   eth0: eth at 10002000, eth5: eth at 10003000, eth1: eth at 10004000
> Running 53 driver model tests
> Test: dm_test_autobind
> Test: dm_test_autoprobe
> Test: dm_test_bus_child_post_bind
> Test: dm_test_bus_child_post_bind_uclass
> Test: dm_test_bus_child_pre_probe_uclass
> Test: dm_test_bus_children
> Device 'c-test at 0': seq 0 is in use by 'd-test'
> Device 'c-test at 1': seq 1 is in use by 'f-test'
> Test: dm_test_bus_children_funcs
> Test: dm_test_bus_children_iterators
> Test: dm_test_bus_parent_data
> Test: dm_test_bus_parent_data_uclass
> Test: dm_test_bus_parent_ops
> Test: dm_test_bus_parent_platdata
> Test: dm_test_bus_parent_platdata_uclass
> Test: dm_test_children
> Test: dm_test_device_get_uclass_id
> Test: dm_test_eth
> Using eth at 10002000 device
> Using eth at 10003000 device
> Using eth at 10004000 device
> Test: dm_test_eth_alias
> Using eth at 10002000 device
> Using eth at 10004000 device
> Using eth at 10002000 device
> Using eth at 10003000 device
> Test: dm_test_eth_prime
> Using eth at 10003000 device
> Using eth at 10002000 device
> Test: dm_test_eth_rotate
>
> Error: eth at 10004000 address not set.
>
> Error: eth at 10004000 address not set.
> Using eth at 10002000 device
>
> Error: eth at 10004000 address not set.
>
> Error: eth at 10004000 address not set.
> Using eth at 10004000 device
> Test: dm_test_fdt
> Test: dm_test_fdt_offset
> Test: dm_test_fdt_pre_reloc
> Test: dm_test_fdt_uclass_seq
> Test: dm_test_gpio
> extra-gpios: get_value: error: gpio b5 not reserved
> Test: dm_test_gpio_anon
> Test: dm_test_gpio_copy
> Test: dm_test_gpio_leak
> extra-gpios: get_value: error: gpio b5 not reserved
>
> Program received signal SIGSEGV, Segmentation fault.
> 0x000009ec in ?? ()
> (gdb) bt
> #0  0x000009ec in ?? ()
> #1  0x0806a0aa in uclass_destroy (uc=0xb5abd228) at
> /home/joe/u-boot/drivers/core/uclass.c:109
> #2  0x080a29e1 in dm_leak_check_end (dms=0x8106870) at
> /home/joe/u-boot/test/dm/core.c:89
> #3  0x080a46a6 in dm_test_gpio_leak (dms=0x8106870) at
> /home/joe/u-boot/test/dm/gpio.c:173
> #4  0x080a0ed2 in dm_test_main (test_name=0x0) at
> /home/joe/u-boot/test/dm/test-main.c:103
> #5  0x0809e9fb in do_dm (cmdtp=0x80c0250, flag=0, argc=135022648,
> argv=0xb5abbd40) at /home/joe/u-boot/test/dm/cmd_dm.c:150
> #6  0x08065d6b in cmd_process (flag=0, argc=2, argv=0xb5abbd40,
> repeatable=0x80c5fc4, ticks=0x0) at
> /home/joe/u-boot/common/command.c:493
> #7  0x0804d6fb in run_list_real (pi=0xb5abbc88) at
> /home/joe/u-boot/common/cli_hush.c:1656
> #8  0x0804dce4 in parse_stream_outer (inp=0xbffff0e8, flag=2) at
> /home/joe/u-boot/common/cli_hush.c:2003
> #9  0x0804df1d in parse_string_outer (s=0xbffff513 "dm test", flag=2)
> at /home/joe/u-boot/common/cli_hush.c:3248
> #10 0x0804a855 in sandbox_main_loop_init () at
> /home/joe/u-boot/arch/sandbox/cpu/start.c:85
> #11 0x0804e65b in run_main_loop () at /home/joe/u-boot/common/board_r.c:682
> #12 0x0808f082 in initcall_run_list (init_sequence=0x80c1f68) at
> /home/joe/u-boot/lib/initcall.c:27
> #13 0x0804e798 in board_init_r (new_gd=0xb5ab9f14, dest_addr=0) at
> /home/joe/u-boot/common/board_r.c:916
> #14 0x0804a810 in main (argc=Cannot access memory at address 0x0
> ) at /home/joe/u-boot/arch/sandbox/cpu/start.c:276
> (gdb) f 1
> #1  0x0806a0aa in uclass_destroy (uc=0xb5abd228) at
> /home/joe/u-boot/drivers/core/uclass.c:109
> 109                     ret = device_unbind(dev);
> (gdb) l -
> 99      int uclass_destroy(struct uclass *uc)
> 100     {
> 101             struct uclass_driver *uc_drv;
> 102             struct udevice *dev, *tmp;
> 103             int ret;
> 104
> 105             list_for_each_entry_safe(dev, tmp, &uc->dev_head, uclass_node) {
> 106                     ret = device_remove(dev);
> 107                     if (ret)
> 108                             return ret;
> (gdb) l
> 109                     ret = device_unbind(dev);
> 110                     if (ret)
> 111                             return ret;
> 112             }
> 113
> 114             uc_drv = uc->uc_drv;
> 115             if (uc_drv->destroy)
> 116                     uc_drv->destroy(uc);
> 117             list_del(&uc->sibling_node);
> 118             if (uc_drv->priv_auto_alloc_size)
> (gdb)
>
>
> Thoughts?

Yes it is broken. I sent a series to fix this recent ('dm: core: Fix
up test failures') starting with this patch:

http://patchwork.ozlabs.org/patch/462556/

If you are able to test it that would be good.

Regards,
Simon

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 77/80] dm: usb: Add tests for the USB uclass
  2015-04-21 13:14     ` Simon Glass
@ 2015-04-21 16:05       ` Joe Hershberger
  2015-04-21 16:19         ` Simon Glass
  0 siblings, 1 reply; 178+ messages in thread
From: Joe Hershberger @ 2015-04-21 16:05 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Tue, Apr 21, 2015 at 8:14 AM, Simon Glass <sjg@chromium.org> wrote:
> Hi Joe,
>
> On 20 April 2015 at 23:24, Joe Hershberger <joe.hershberger@gmail.com> wrote:
>> Hi Simon,
>>
>> On Wed, Mar 25, 2015 at 1:23 PM, Simon Glass <sjg@chromium.org> wrote:
>>> This adds a simple test for probing and a functional test using the flash
>>> stick emulator, which tests a large chunk of the USB stack.
>>>
>>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>
>> I'm seeing a seg fault when running the dm tests and bisected it to this patch.
>>
>> I'm not sure why it's related, but it appears to seg fault on a GPIO test...

<--snip-->

>> Thoughts?
>
> Yes it is broken. I sent a series to fix this recent ('dm: core: Fix
> up test failures') starting with this patch:
>
> http://patchwork.ozlabs.org/patch/462556/
>
> If you are able to test it that would be good.

I tested the series, but I still have a USB test failure...

"""
Test: dm_test_usb_flash
USB-1:   scanning bus 1 for devices... 2 USB Device(s) found
/home/joe/u-boot/test/dm/usb.c:45, dm_test_usb_flash(): 2 ==
dev_desc->block_read(dev_desc->dev, 0, 2, cmp): Expected 2, got 0
"""

Have you seen that one?

Thanks,
-Joe

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 77/80] dm: usb: Add tests for the USB uclass
  2015-04-21 16:05       ` Joe Hershberger
@ 2015-04-21 16:19         ` Simon Glass
  2015-04-21 16:57           ` Joe Hershberger
  0 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-04-21 16:19 UTC (permalink / raw)
  To: u-boot

Hi Joe,

On 21 April 2015 at 10:05, Joe Hershberger <joe.hershberger@gmail.com> wrote:
>
> Hi Simon,
>
> On Tue, Apr 21, 2015 at 8:14 AM, Simon Glass <sjg@chromium.org> wrote:
> > Hi Joe,
> >
> > On 20 April 2015 at 23:24, Joe Hershberger <joe.hershberger@gmail.com> wrote:
> >> Hi Simon,
> >>
> >> On Wed, Mar 25, 2015 at 1:23 PM, Simon Glass <sjg@chromium.org> wrote:
> >>> This adds a simple test for probing and a functional test using the flash
> >>> stick emulator, which tests a large chunk of the USB stack.
> >>>
> >>> Signed-off-by: Simon Glass <sjg@chromium.org>
> >>
> >> I'm seeing a seg fault when running the dm tests and bisected it to this patch.
> >>
> >> I'm not sure why it's related, but it appears to seg fault on a GPIO test...
>
> <--snip-->
>
> >> Thoughts?
> >
> > Yes it is broken. I sent a series to fix this recent ('dm: core: Fix
> > up test failures') starting with this patch:
> >
> > http://patchwork.ozlabs.org/patch/462556/
> >
> > If you are able to test it that would be good.
>
> I tested the series, but I still have a USB test failure...
>
> """
> Test: dm_test_usb_flash
> USB-1:   scanning bus 1 for devices... 2 USB Device(s) found
> /home/joe/u-boot/test/dm/usb.c:45, dm_test_usb_flash(): 2 ==
> dev_desc->block_read(dev_desc->dev, 0, 2, cmp): Expected 2, got 0
> """
>
> Have you seen that one?

No I don't see that. It is saying that it was not able to read 2
512-byte blocks from the testflash.bin file. It should be created by
the test script. I just tried it again.

BTW I'd like to get a sandbox network device that works in a purely
emulated way (i.e. without any reference to real hardware). Then we
could use it for ping tests, etc. and they would run instantly. At
present the network tests are quite slow. What do you think?

Regards,
Simon

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 77/80] dm: usb: Add tests for the USB uclass
  2015-04-21 16:19         ` Simon Glass
@ 2015-04-21 16:57           ` Joe Hershberger
  2015-04-21 17:00             ` Simon Glass
  0 siblings, 1 reply; 178+ messages in thread
From: Joe Hershberger @ 2015-04-21 16:57 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Tue, Apr 21, 2015 at 11:19 AM, Simon Glass <sjg@chromium.org> wrote:
> Hi Joe,
>
> On 21 April 2015 at 10:05, Joe Hershberger <joe.hershberger@gmail.com> wrote:
>>
>> Hi Simon,
>>
>> On Tue, Apr 21, 2015 at 8:14 AM, Simon Glass <sjg@chromium.org> wrote:
>> > Hi Joe,
>> >
>> > On 20 April 2015 at 23:24, Joe Hershberger <joe.hershberger@gmail.com> wrote:
>> >> Hi Simon,
>> >>
>> >> On Wed, Mar 25, 2015 at 1:23 PM, Simon Glass <sjg@chromium.org> wrote:
>> >>> This adds a simple test for probing and a functional test using the flash
>> >>> stick emulator, which tests a large chunk of the USB stack.
>> >>>
>> >>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> >>
>> >> I'm seeing a seg fault when running the dm tests and bisected it to this patch.
>> >>
>> >> I'm not sure why it's related, but it appears to seg fault on a GPIO test...
>>
>> <--snip-->
>>
>> >> Thoughts?
>> >
>> > Yes it is broken. I sent a series to fix this recent ('dm: core: Fix
>> > up test failures') starting with this patch:
>> >
>> > http://patchwork.ozlabs.org/patch/462556/
>> >
>> > If you are able to test it that would be good.
>>
>> I tested the series, but I still have a USB test failure...
>>
>> """
>> Test: dm_test_usb_flash
>> USB-1:   scanning bus 1 for devices... 2 USB Device(s) found
>> /home/joe/u-boot/test/dm/usb.c:45, dm_test_usb_flash(): 2 ==
>> dev_desc->block_read(dev_desc->dev, 0, 2, cmp): Expected 2, got 0
>> """
>>
>> Have you seen that one?
>
> No I don't see that. It is saying that it was not able to read 2
> 512-byte blocks from the testflash.bin file. It should be created by
> the test script. I just tried it again.

That makes sense... I wasn't creating that file. D'oh!  Working for me now too.

> BTW I'd like to get a sandbox network device that works in a purely
> emulated way (i.e. without any reference to real hardware). Then we
> could use it for ping tests, etc. and they would run instantly. At
> present the network tests are quite slow. What do you think?

The tests are all using fully emulated Ethernet... the issue is that
the ping test ensures that on timeout an error is returned. Even
though it is an emulated MAC, the timeout in the network stack is
still there.

I'll work on a patch that adds a way to change the ping timeout to
make this faster.

Cheers,
-Joe

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 77/80] dm: usb: Add tests for the USB uclass
  2015-04-21 16:57           ` Joe Hershberger
@ 2015-04-21 17:00             ` Simon Glass
  2015-04-21 20:10               ` Joe Hershberger
  0 siblings, 1 reply; 178+ messages in thread
From: Simon Glass @ 2015-04-21 17:00 UTC (permalink / raw)
  To: u-boot

Hi Joe,

On 21 April 2015 at 10:57, Joe Hershberger <joe.hershberger@gmail.com> wrote:
> Hi Simon,
>
> On Tue, Apr 21, 2015 at 11:19 AM, Simon Glass <sjg@chromium.org> wrote:
>> Hi Joe,
>>
>> On 21 April 2015 at 10:05, Joe Hershberger <joe.hershberger@gmail.com> wrote:
>>>
>>> Hi Simon,
>>>
>>> On Tue, Apr 21, 2015 at 8:14 AM, Simon Glass <sjg@chromium.org> wrote:
>>> > Hi Joe,
>>> >
>>> > On 20 April 2015 at 23:24, Joe Hershberger <joe.hershberger@gmail.com> wrote:
>>> >> Hi Simon,
>>> >>
>>> >> On Wed, Mar 25, 2015 at 1:23 PM, Simon Glass <sjg@chromium.org> wrote:
>>> >>> This adds a simple test for probing and a functional test using the flash
>>> >>> stick emulator, which tests a large chunk of the USB stack.
>>> >>>
>>> >>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>> >>
>>> >> I'm seeing a seg fault when running the dm tests and bisected it to this patch.
>>> >>
>>> >> I'm not sure why it's related, but it appears to seg fault on a GPIO test...
>>>
>>> <--snip-->
>>>
>>> >> Thoughts?
>>> >
>>> > Yes it is broken. I sent a series to fix this recent ('dm: core: Fix
>>> > up test failures') starting with this patch:
>>> >
>>> > http://patchwork.ozlabs.org/patch/462556/
>>> >
>>> > If you are able to test it that would be good.
>>>
>>> I tested the series, but I still have a USB test failure...
>>>
>>> """
>>> Test: dm_test_usb_flash
>>> USB-1:   scanning bus 1 for devices... 2 USB Device(s) found
>>> /home/joe/u-boot/test/dm/usb.c:45, dm_test_usb_flash(): 2 ==
>>> dev_desc->block_read(dev_desc->dev, 0, 2, cmp): Expected 2, got 0
>>> """
>>>
>>> Have you seen that one?
>>
>> No I don't see that. It is saying that it was not able to read 2
>> 512-byte blocks from the testflash.bin file. It should be created by
>> the test script. I just tried it again.
>
> That makes sense... I wasn't creating that file. D'oh!  Working for me now too.
>
>> BTW I'd like to get a sandbox network device that works in a purely
>> emulated way (i.e. without any reference to real hardware). Then we
>> could use it for ping tests, etc. and they would run instantly. At
>> present the network tests are quite slow. What do you think?
>
> The tests are all using fully emulated Ethernet... the issue is that
> the ping test ensures that on timeout an error is returned. Even
> though it is an emulated MAC, the timeout in the network stack is
> still there.
>
> I'll work on a patch that adds a way to change the ping timeout to
> make this faster.

OK thanks for explaining this. Rather than changing the ping timeout,
can you look at changing the time? With sandbox it should be possible
to adjust the time so that timeouts appear to happen instantly. The
arch/sandbox/include/test.h file has some test functions used by
various parts of the stack.

Regards,
Simon

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 77/80] dm: usb: Add tests for the USB uclass
  2015-04-21 17:00             ` Simon Glass
@ 2015-04-21 20:10               ` Joe Hershberger
  2015-04-21 20:14                 ` Simon Glass
  0 siblings, 1 reply; 178+ messages in thread
From: Joe Hershberger @ 2015-04-21 20:10 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Tue, Apr 21, 2015 at 12:00 PM, Simon Glass <sjg@chromium.org> wrote:
> Hi Joe,
>
> On 21 April 2015 at 10:57, Joe Hershberger <joe.hershberger@gmail.com> wrote:
>> Hi Simon,
>>
>> On Tue, Apr 21, 2015 at 11:19 AM, Simon Glass <sjg@chromium.org> wrote:
>>> Hi Joe,
>>>
>>> On 21 April 2015 at 10:05, Joe Hershberger <joe.hershberger@gmail.com> wrote:
>>>>
>>>> Hi Simon,
>>>>
>>>> On Tue, Apr 21, 2015 at 8:14 AM, Simon Glass <sjg@chromium.org> wrote:
>>>> > Hi Joe,
>>>> >
>>>> > On 20 April 2015 at 23:24, Joe Hershberger <joe.hershberger@gmail.com> wrote:
>>>> >> Hi Simon,
>>>> >>
>>>> >> On Wed, Mar 25, 2015 at 1:23 PM, Simon Glass <sjg@chromium.org> wrote:
>>>> >>> This adds a simple test for probing and a functional test using the flash
>>>> >>> stick emulator, which tests a large chunk of the USB stack.
>>>> >>>
>>>> >>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>>> >>
>>>> >> I'm seeing a seg fault when running the dm tests and bisected it to this patch.
>>>> >>
>>>> >> I'm not sure why it's related, but it appears to seg fault on a GPIO test...
>>>>
>>>> <--snip-->
>>>>
>>>> >> Thoughts?
>>>> >
>>>> > Yes it is broken. I sent a series to fix this recent ('dm: core: Fix
>>>> > up test failures') starting with this patch:
>>>> >
>>>> > http://patchwork.ozlabs.org/patch/462556/
>>>> >
>>>> > If you are able to test it that would be good.
>>>>
>>>> I tested the series, but I still have a USB test failure...
>>>>
>>>> """
>>>> Test: dm_test_usb_flash
>>>> USB-1:   scanning bus 1 for devices... 2 USB Device(s) found
>>>> /home/joe/u-boot/test/dm/usb.c:45, dm_test_usb_flash(): 2 ==
>>>> dev_desc->block_read(dev_desc->dev, 0, 2, cmp): Expected 2, got 0
>>>> """
>>>>
>>>> Have you seen that one?
>>>
>>> No I don't see that. It is saying that it was not able to read 2
>>> 512-byte blocks from the testflash.bin file. It should be created by
>>> the test script. I just tried it again.
>>
>> That makes sense... I wasn't creating that file. D'oh!  Working for me now too.
>>
>>> BTW I'd like to get a sandbox network device that works in a purely
>>> emulated way (i.e. without any reference to real hardware). Then we
>>> could use it for ping tests, etc. and they would run instantly. At
>>> present the network tests are quite slow. What do you think?
>>
>> The tests are all using fully emulated Ethernet... the issue is that
>> the ping test ensures that on timeout an error is returned. Even
>> though it is an emulated MAC, the timeout in the network stack is
>> still there.
>>
>> I'll work on a patch that adds a way to change the ping timeout to
>> make this faster.
>
> OK thanks for explaining this. Rather than changing the ping timeout,
> can you look at changing the time? With sandbox it should be possible
> to adjust the time so that timeouts appear to happen instantly. The
> arch/sandbox/include/test.h file has some test functions used by
> various parts of the stack.

I posted a series that handles the issue as you recommended and called
it "test: Speed up test timeouts by advancing time".

I now notice that the only test that takes any time is the USB Flash test.

"""
Test: dm_test_usb_flash
USB-1:   scanning bus 1 for devices... 2 USB Device(s) found
"""

It takes about 3 seconds.  Is that a timeout too?

Thanks,
-Joe

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 77/80] dm: usb: Add tests for the USB uclass
  2015-04-21 20:10               ` Joe Hershberger
@ 2015-04-21 20:14                 ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-04-21 20:14 UTC (permalink / raw)
  To: u-boot

Hi Joe,

On 21 April 2015 at 14:10, Joe Hershberger <joe.hershberger@gmail.com> wrote:
> Hi Simon,
>
> On Tue, Apr 21, 2015 at 12:00 PM, Simon Glass <sjg@chromium.org> wrote:
>> Hi Joe,
>>
>> On 21 April 2015 at 10:57, Joe Hershberger <joe.hershberger@gmail.com> wrote:
>>> Hi Simon,
>>>
>>> On Tue, Apr 21, 2015 at 11:19 AM, Simon Glass <sjg@chromium.org> wrote:
>>>> Hi Joe,
>>>>
>>>> On 21 April 2015 at 10:05, Joe Hershberger <joe.hershberger@gmail.com> wrote:
>>>>>
>>>>> Hi Simon,
>>>>>
>>>>> On Tue, Apr 21, 2015 at 8:14 AM, Simon Glass <sjg@chromium.org> wrote:
>>>>> > Hi Joe,
>>>>> >
>>>>> > On 20 April 2015 at 23:24, Joe Hershberger <joe.hershberger@gmail.com> wrote:
>>>>> >> Hi Simon,
>>>>> >>
>>>>> >> On Wed, Mar 25, 2015 at 1:23 PM, Simon Glass <sjg@chromium.org> wrote:
>>>>> >>> This adds a simple test for probing and a functional test using the flash
>>>>> >>> stick emulator, which tests a large chunk of the USB stack.
>>>>> >>>
>>>>> >>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>>>> >>
>>>>> >> I'm seeing a seg fault when running the dm tests and bisected it to this patch.
>>>>> >>
>>>>> >> I'm not sure why it's related, but it appears to seg fault on a GPIO test...
>>>>>
>>>>> <--snip-->
>>>>>
>>>>> >> Thoughts?
>>>>> >
>>>>> > Yes it is broken. I sent a series to fix this recent ('dm: core: Fix
>>>>> > up test failures') starting with this patch:
>>>>> >
>>>>> > http://patchwork.ozlabs.org/patch/462556/
>>>>> >
>>>>> > If you are able to test it that would be good.
>>>>>
>>>>> I tested the series, but I still have a USB test failure...
>>>>>
>>>>> """
>>>>> Test: dm_test_usb_flash
>>>>> USB-1:   scanning bus 1 for devices... 2 USB Device(s) found
>>>>> /home/joe/u-boot/test/dm/usb.c:45, dm_test_usb_flash(): 2 ==
>>>>> dev_desc->block_read(dev_desc->dev, 0, 2, cmp): Expected 2, got 0
>>>>> """
>>>>>
>>>>> Have you seen that one?
>>>>
>>>> No I don't see that. It is saying that it was not able to read 2
>>>> 512-byte blocks from the testflash.bin file. It should be created by
>>>> the test script. I just tried it again.
>>>
>>> That makes sense... I wasn't creating that file. D'oh!  Working for me now too.
>>>
>>>> BTW I'd like to get a sandbox network device that works in a purely
>>>> emulated way (i.e. without any reference to real hardware). Then we
>>>> could use it for ping tests, etc. and they would run instantly. At
>>>> present the network tests are quite slow. What do you think?
>>>
>>> The tests are all using fully emulated Ethernet... the issue is that
>>> the ping test ensures that on timeout an error is returned. Even
>>> though it is an emulated MAC, the timeout in the network stack is
>>> still there.
>>>
>>> I'll work on a patch that adds a way to change the ping timeout to
>>> make this faster.
>>
>> OK thanks for explaining this. Rather than changing the ping timeout,
>> can you look at changing the time? With sandbox it should be possible
>> to adjust the time so that timeouts appear to happen instantly. The
>> arch/sandbox/include/test.h file has some test functions used by
>> various parts of the stack.
>
> I posted a series that handles the issue as you recommended and called
> it "test: Speed up test timeouts by advancing time".

I see it. This is great, thank you!

>
> I now notice that the only test that takes any time is the USB Flash test.
>
> """
> Test: dm_test_usb_flash
> USB-1:   scanning bus 1 for devices... 2 USB Device(s) found
> """
>
> It takes about 3 seconds.  Is that a timeout too?

Yes. I'll take a look at how you have advanced time - we should do
this for USB too.

Regards,
Simon

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 79/80] dm: usb: exynos: Drop legacy USB code
  2015-03-25 18:23 ` [U-Boot] [PATCH v2 79/80] dm: usb: exynos: " Simon Glass
@ 2015-05-06 21:44   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-05-06 21:44 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:23, Simon Glass <sjg@chromium.org> wrote:
> Drop the code that doesn't use driver model for USB.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/usb/host/ehci-exynos.c  | 117 ----------------------------------------
>  drivers/usb/host/xhci-exynos5.c | 108 -------------------------------------
>  include/fdtdec.h                |   2 -
>  lib/fdtdec.c                    |   2 -
>  4 files changed, 229 deletions(-)

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [U-Boot] [PATCH v2 78/80] dm: usb: tegra: Drop legacy USB code
  2015-03-25 18:23 ` [U-Boot] [PATCH v2 78/80] dm: usb: tegra: Drop legacy USB code Simon Glass
@ 2015-06-11 20:19   ` Simon Glass
  0 siblings, 0 replies; 178+ messages in thread
From: Simon Glass @ 2015-06-11 20:19 UTC (permalink / raw)
  To: u-boot

On 25 March 2015 at 12:23, Simon Glass <sjg@chromium.org> wrote:
> Drop the code that doesn't use driver model for USB.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  board/nvidia/common/board.c   |   3 -
>  drivers/usb/host/ehci-tegra.c | 150 ------------------------------------------
>  include/fdtdec.h              |   3 -
>  lib/fdtdec.c                  |   3 -
>  4 files changed, 159 deletions(-)

Applied to u-boot-dm.

^ permalink raw reply	[flat|nested] 178+ messages in thread

end of thread, other threads:[~2015-06-11 20:19 UTC | newest]

Thread overview: 178+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-25 18:21 [U-Boot] [PATCH v2 0/80] dm: Add USB support Simon Glass
2015-03-25 18:21 ` [U-Boot] [PATCH v2 01/80] linker_lists: Add a function to access a linker list entry Simon Glass
2015-04-07 18:39   ` Simon Glass
2015-03-25 18:21 ` [U-Boot] [PATCH v2 02/80] sandbox: Fix comment for os_open() Simon Glass
2015-04-07 18:39   ` Simon Glass
2015-03-25 18:21 ` [U-Boot] [PATCH v2 03/80] dm: test: bus: Use a local variable to simplify code Simon Glass
2015-04-07 18:39   ` Simon Glass
2015-03-25 18:21 ` [U-Boot] [PATCH v2 04/80] dm: exynos: snow: Move the keyboard to I2C Simon Glass
2015-04-07 18:39   ` Simon Glass
2015-03-25 18:21 ` [U-Boot] [PATCH v2 05/80] dm: core: Support allocating driver-private data for DMA Simon Glass
2015-04-07 18:39   ` Simon Glass
2015-03-25 18:21 ` [U-Boot] [PATCH v2 06/80] dm: core: Convert driver_bind() to use const Simon Glass
2015-04-07 18:39   ` Simon Glass
2015-03-25 18:21 ` [U-Boot] [PATCH v2 07/80] dm: core: Rename driver data function to dev_get_driver_data() Simon Glass
2015-04-07 18:40   ` Simon Glass
2015-03-25 18:21 ` [U-Boot] [PATCH v2 08/80] dm: core: Mark device as active before calling uclass probe() methods Simon Glass
2015-04-07 18:40   ` Simon Glass
2015-03-25 18:21 ` [U-Boot] [PATCH v2 09/80] dm: core: Add device children and sibling functions Simon Glass
2015-04-07 18:40   ` Simon Glass
2015-03-25 18:21 ` [U-Boot] [PATCH v2 10/80] dm: gpio: Add an implementation for gpio_get_number() Simon Glass
2015-04-07 18:40   ` Simon Glass
2015-03-25 18:21 ` [U-Boot] [PATCH v2 11/80] dm: usb: Add a uclass for USB controllers Simon Glass
2015-04-07 18:40   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 12/80] dm: usb: Adjust usb command to prepare for driver model Simon Glass
2015-04-07 18:40   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 13/80] dm: usb: Adjust usb_alloc_new_device() to return an error Simon Glass
2015-04-07 18:40   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 14/80] dm: usb: Convert 'usb' command to support driver model Simon Glass
2015-04-07 18:40   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 15/80] dm: usb: Drop the legacy USB init sequence Simon Glass
2015-03-26 18:22   ` Marek Vasut
2015-04-07 18:41     ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 16/80] dm: usb: Refactor port resets Simon Glass
2015-04-07 18:41   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 17/80] dm: usb: Move descriptor setup code into its own function Simon Glass
2015-04-07 18:41   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 18/80] dm: usb: Split out more code from usb_new_device() Simon Glass
2015-04-07 18:41   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 19/80] dm: usb: Complete the splitting up of usb_new_device() Simon Glass
2015-04-07 18:41   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 20/80] dm: usb: Convert core usb.c file to support driver model Simon Glass
2015-04-07 18:41   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 21/80] dm: usb: Split hub detection into its own function Simon Glass
2015-04-07 18:41   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 22/80] dm: usb: Add driver model support for hubs Simon Glass
2015-04-07 18:41   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 23/80] dm: usb: Move USB storage definitions to usb_defs.h Simon Glass
2015-04-07 18:42   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 24/80] dm: usb: Fix type problems in usb_stor_get_info() Simon Glass
2015-04-07 18:42   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 25/80] dm: usb: Simply device finding code in usb_storage Simon Glass
2015-04-07 18:42   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 26/80] dm: usb: Adjust usb_storage to work with sandbox Simon Glass
2015-04-07 18:42   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 27/80] dm: usb: Move storage device scanning into its own function Simon Glass
2015-04-07 18:43   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 28/80] dm: usb: Convert usb_storage to driver model Simon Glass
2015-04-07 18:43   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 29/80] dm: usb: Move all the EHCI weak functions together and declare them Simon Glass
2015-04-07 18:43   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 30/80] dm: usb: Pass EHCI controller pointer to ehci_get_port_speed() Simon Glass
2015-04-07 18:43   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 31/80] dm: usb: Allow ECHI to hold private data for the controller Simon Glass
2015-04-07 18:43   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 32/80] dm: usb: tegra: Store the controller type explicitly Simon Glass
2015-04-07 18:43   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 33/80] dm: usb: Pass EHCI controller pointer to ehci_powerup_fixup() Simon Glass
2015-04-07 18:43   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 34/80] dm: usb: tegra: Drop use of global controller variable Simon Glass
2015-04-07 18:44   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 35/80] dm: usb: Pass EHCI controller pointer to ehci_set_usbmode() Simon Glass
2015-04-07 18:44   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 36/80] dm: usb: Pass EHCI controller pointer to ehci_get_portsc_register() Simon Glass
2015-04-07 18:44   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 37/80] dm: usb: ehci: Use a function to find the controller from struct udevice Simon Glass
2015-04-07 18:44   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 38/80] dm: usb: Refactor EHCI init Simon Glass
2015-04-07 18:44   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 39/80] dm: usb: Drop the EHCI weak functions Simon Glass
2015-04-07 18:44   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 40/80] dm: usb: Change ehci_reset() to use a pointer Simon Glass
2015-04-07 18:44   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 41/80] dm: usb: Add driver model support to EHCI Simon Glass
2015-04-07 18:44   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 42/80] dm: usb: Allow USB drivers to be declared and auto-probed Simon Glass
2015-04-07 18:45   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 43/80] dm: usb: Bind generic USB devices when there is no driver Simon Glass
2015-04-07 18:45   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 44/80] dm: usb: Allow setting up a USB controller as a device/gadget Simon Glass
2015-04-07 18:45   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 45/80] dm: usb: Split out the keyboard probe into its own function Simon Glass
2015-04-07 18:45   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 46/80] dm: usb: Support driver model with USB keyboards Simon Glass
2015-04-07 18:45   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 47/80] dm: usb: tegra: Add vbus GPIOs for nyan Simon Glass
2015-04-07 19:09   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 48/80] dm: usb: Move struct usb_string to a common place Simon Glass
2015-04-07 19:09   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 49/80] dm: usb: sandbox: Add a uclass for USB device emulation Simon Glass
2015-04-07 19:09   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 50/80] dm: usb: sandbox: Reset emulation devices in usb stop() Simon Glass
2015-04-07 19:10   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 51/80] dm: usb: sandbox: Add an emulator for USB flash devices Simon Glass
2015-04-07 19:10   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 52/80] dm: usb: sandbox: Add an emulator for USB hub emulation Simon Glass
2015-04-07 19:10   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 53/80] dm: usb: sandbox: Add a driver for sandbox Simon Glass
2015-04-07 19:10   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 54/80] dm: usb: dts: sandbox: Add some sample USB devices to sandbox Simon Glass
2015-04-07 19:10   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 55/80] dm: usb: Add support for USB ethernet devices with driver model Simon Glass
2015-04-07 19:10   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 56/80] dm: usb: exynos: Add driver model support to exynos EHCI Simon Glass
2015-04-07 19:10   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 57/80] dm: usb: tegra: Remove the port_addr_clear_csc variable Simon Glass
2015-03-26  3:38   ` Jim Lin
2015-03-26  9:01     ` Jim Lin
2015-04-07 19:10       ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 58/80] dm: usb: tegra: Tidy up error handling and a static function Simon Glass
2015-04-07 19:10   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 59/80] dm: usb: tegra: Move most of init/uninit into a function Simon Glass
2015-04-07 19:10   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 60/80] dm: usb: tegra: Add driver model support to tegra EHCI Simon Glass
2015-04-07 19:10   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 61/80] dm: usb: xhci: Use a function to get xhci_ctrl Simon Glass
2015-04-07 19:11   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 62/80] dm: usb: xhci: Use explicit parameters for xhci_alloc_virt_device() Simon Glass
2015-04-07 19:11   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 63/80] dm: usb: xhci: Use explicit parameters for xhci_setup_addressable_virt_dev() Simon Glass
2015-04-07 19:11   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 64/80] dm: usb: xhci: Factor out common init/uninit Simon Glass
2015-04-07 19:11   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 65/80] dm: usb: Support driver model in XHCI Simon Glass
2015-04-07 19:11   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 66/80] dm: usb: Rename the XHCI HCD to U-Boot Simon Glass
2015-04-07 19:11   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 67/80] dm: usb: exynos: Adjust XHCI driver to support driver model Simon Glass
2015-04-07 19:11   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 68/80] dm: usb: exynos: Use driver model for USB Simon Glass
2015-04-07 19:11   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 69/80] dm: usb: exynos: Enable both USB ports on snow Simon Glass
2015-04-07 19:11   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 70/80] dm: usb: exynos: Enable both EHCI and XHCI " Simon Glass
2015-04-07 19:11   ` Simon Glass
2015-03-25 18:22 ` [U-Boot] [PATCH v2 71/80] dm: usb: tegra: Move to driver model for USB Simon Glass
2015-04-07 19:11   ` Simon Glass
2015-03-25 18:23 ` [U-Boot] [PATCH v2 72/80] dm: usb: Add a generic descriptor struct Simon Glass
2015-04-07 19:11   ` Simon Glass
2015-03-25 18:23 ` [U-Boot] [PATCH v2 73/80] dm: usb: Tidy up pipe value decoding Simon Glass
2015-04-07 19:12   ` Simon Glass
2015-03-25 18:23 ` [U-Boot] [PATCH v2 74/80] dm: usb: sandbox: Enable USB Simon Glass
2015-04-07 19:12   ` Simon Glass
2015-03-25 18:23 ` [U-Boot] [PATCH v2 75/80] dm: test: Correct printf() output nit in 'dm uclass' Simon Glass
2015-04-07 19:12   ` Simon Glass
2015-03-25 18:23 ` [U-Boot] [PATCH v2 76/80] dm: test: Allow 'dm test' to select a particular test to run Simon Glass
2015-04-07 19:12   ` Simon Glass
2015-03-25 18:23 ` [U-Boot] [PATCH v2 77/80] dm: usb: Add tests for the USB uclass Simon Glass
2015-04-07 19:12   ` Simon Glass
2015-04-21  5:24   ` Joe Hershberger
2015-04-21 13:14     ` Simon Glass
2015-04-21 16:05       ` Joe Hershberger
2015-04-21 16:19         ` Simon Glass
2015-04-21 16:57           ` Joe Hershberger
2015-04-21 17:00             ` Simon Glass
2015-04-21 20:10               ` Joe Hershberger
2015-04-21 20:14                 ` Simon Glass
2015-03-25 18:23 ` [U-Boot] [PATCH v2 78/80] dm: usb: tegra: Drop legacy USB code Simon Glass
2015-06-11 20:19   ` Simon Glass
2015-03-25 18:23 ` [U-Boot] [PATCH v2 79/80] dm: usb: exynos: " Simon Glass
2015-05-06 21:44   ` Simon Glass
2015-03-25 18:23 ` [U-Boot] [PATCH v2 80/80] dm: usb: Add a README for driver model Simon Glass
2015-04-07  3:24   ` Jim Lin
2015-04-08  1:40     ` Simon Glass
2015-03-26 19:40 ` [U-Boot] [PATCH v2 0/80] dm: Add USB support Marek Vasut
2015-04-05 23:38   ` Simon Glass
2015-04-06 13:13     ` Marek Vasut
2015-04-06 22:38       ` Simon Glass
2015-04-07 13:52         ` Marek Vasut

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.