All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/21] Support qcom's HSIC USB and rewrite USB2 HS phy support
@ 2016-06-26  7:28 ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb
  Cc: linux-arm-kernel, linux-kernel, linux-arm-msm, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Greg Kroah-Hartman, Heikki Krogerus, Peter Chen, Ivan T. Ivanov,
	devicetree, Rob Herring, Kishon Vijay Abraham I

The state of USB ChipIdea support on Qualcomm's platforms is not great.
The DT description of these devices requires up to three different nodes
for what amounts to be the same hardware block, when there should really
only be one. Furthermore, the "phy" driver that is in mainline (phy-msm-usb.c)
duplicates the OTG state machine and touches the ci controller wrapper
registers when it should really be focused on the phy and the ULPI accesses
needed to get the phy working. There's also a slimmed down phy driver for
the msm8916 platform, but really the phy hardware is the same as other MSMs,
so we have two drivers doing pretty much the same thing. This leads to a
situtaion where we have the chipidea core driver, the "phy" driver, and
sometimes the ehci-msm.c driver operating the same device all at the same
time with very little coordination. This just isn't very safe and is
confusing from a driver perspective when trying to figure out who does what.
Finally, there isn't any HSIC support on platforms like apq8074 so we
should add that.

This patch series updates the ChipIdea driver and the MSM wrapper
(ci_hdrc_msm.c) to properly handle the PHY and wrapper bits at the right
times in the right places. To get there, we update the ChipIdea core to
have support for the ULPI phy bus introduced by Heikki. Along the way
we fix bugs with the extcon handling for peripheral and OTG mode controllers
and move the parts of phy-usb-msm.c that are touching the CI controller
wrapper into the wrapper driver (ci_hdrc_msm.c). Finally we add support
for the HSIC phy based on the ULPI bus and rewrite the HS phy driver
(phy-usb-msm.c) as a standard ULPI phy driver.

Once this series is accepted, we should be able to delete the phy-usb-msm.c
phy-qcom-8x16-usb.c, and ehci-msm.c drivers from the tree and use the ULPI
based phy driver (which also lives in drivers/phy/ instead of drivers/usb/phy/)
and the chipidea host core instead.

I've also sent seperate patches for other minor pieces to make this
all work. The full tree can be found here[3], hacks and all to get
things working. I've tested this on the db410c, apq8074 dragonboard,
and ifc6410 with configfs gadgets and otg cables.

TODO:
 * DMA fails on arm64 so we need something like [1] to make it work.

 * The HSIC phy on the apq8074 dragonboard is connected to a usb4604
   device which requires the i2c driver to probe and send an i2c
   sequence before the HSIC controller enumerates or HSIC doesn't work.
   Right now I have a hack to force the controller to probe defer
   once so that usb4604 probes first. This needs a more proper solution
   like having the DT describe a linkage between the controller and
   the usb device so we can enforce probe ordering.
 
 * OTG support requires a working VBUS supply on apq8074 dragonboard
   and that requires changes to the smbb_charger driver to support
   the OTG OVP switch as a regulator[2]. This series needs revival.

 * Sleeping while atomic problems exist when trying to do phy operations
   underneath some spinlocks in the ci core. I have a patch to remove a
   spinlock, but that needs more thought if it's correct. At the least
   it's necessary though because of how we need to initialize the HSIC
   phy after the reset bit is toggled in USBCMD.

[1] https://lkml.org/lkml/2016/2/22/7
[2] http://lkml.kernel.org/g/1449621618-11900-1-git-send-email-tim.bird@sonymobile.com
[3] https://git.linaro.org/people/stephen.boyd/linux.git/shortlog/refs/heads/usb-hsic-8074

Stephen Boyd (21):
  of: device: Support loading a module with OF based modalias
  usb: ulpi: Support device discovery via DT
  usb: ulpi: Avoid reading/writing in device creation with OF devices
  usb: chipidea: Only read/write OTGSC from one place
  usb: chipidea: Handle extcon events properly
  usb: chipidea: Initialize and reinitialize phy later
  usb: chipidea: Notify of reset when switching into host mode
  usb: chipidea: Kick OTG state machine for AVVIS with vbus extcon
  usb: chipidea: Add support for ULPI PHY bus
  usb: chipidea: msm: Rely on core to override AHBBURST
  usb: chipidea: msm: Use hw_write_id_reg() instead of writel directly
  usb: chipidea: msm: Keep device runtime enabled
  usb: chipidea: msm: Allow core to get usb phy
  usb: chipidea: msm: Add proper clk and reset support
  usb: chipidea: msm: Mux over secondary phy at the right time
  usb: chipidea: msm: Restore wrapper settings after reset
  usb: chipidea: msm: Make platform data driver local instead of global
  usb: chipidea: msm: Add reset controller for PHY POR bit
  usb: chipidea: msm: Be silent on probe defer errors
  phy: Add support for Qualcomm's USB HSIC phy
  phy: Add support for Qualcomm's USB HS phy

 .../devicetree/bindings/phy/qcom,usb-hs-phy.txt    |  71 ++++++
 .../devicetree/bindings/phy/qcom,usb-hsic-phy.txt  |  60 +++++
 Documentation/devicetree/bindings/usb/ulpi.txt     |  20 ++
 drivers/of/device.c                                |  50 ++++
 drivers/phy/Kconfig                                |  15 ++
 drivers/phy/Makefile                               |   2 +
 drivers/phy/phy-qcom-usb-hs.c                      | 283 +++++++++++++++++++++
 drivers/phy/phy-qcom-usb-hsic.c                    | 161 ++++++++++++
 drivers/usb/chipidea/Kconfig                       |   7 +
 drivers/usb/chipidea/Makefile                      |   1 +
 drivers/usb/chipidea/ci.h                          |  23 +-
 drivers/usb/chipidea/ci_hdrc_msm.c                 | 264 ++++++++++++++++---
 drivers/usb/chipidea/core.c                        |  85 +++----
 drivers/usb/chipidea/host.c                        |   6 +-
 drivers/usb/chipidea/otg.c                         |  81 +++++-
 drivers/usb/chipidea/otg_fsm.c                     |  17 ++
 drivers/usb/chipidea/udc.c                         |   2 +
 drivers/usb/chipidea/ulpi.c                        | 113 ++++++++
 drivers/usb/common/ulpi.c                          |  92 +++++--
 include/linux/of_device.h                          |   6 +
 include/linux/usb/chipidea.h                       |   2 +
 21 files changed, 1238 insertions(+), 123 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/phy/qcom,usb-hs-phy.txt
 create mode 100644 Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt
 create mode 100644 Documentation/devicetree/bindings/usb/ulpi.txt
 create mode 100644 drivers/phy/phy-qcom-usb-hs.c
 create mode 100644 drivers/phy/phy-qcom-usb-hsic.c
 create mode 100644 drivers/usb/chipidea/ulpi.c

-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 00/21] Support qcom's HSIC USB and rewrite USB2 HS phy support
@ 2016-06-26  7:28 ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-arm-kernel

The state of USB ChipIdea support on Qualcomm's platforms is not great.
The DT description of these devices requires up to three different nodes
for what amounts to be the same hardware block, when there should really
only be one. Furthermore, the "phy" driver that is in mainline (phy-msm-usb.c)
duplicates the OTG state machine and touches the ci controller wrapper
registers when it should really be focused on the phy and the ULPI accesses
needed to get the phy working. There's also a slimmed down phy driver for
the msm8916 platform, but really the phy hardware is the same as other MSMs,
so we have two drivers doing pretty much the same thing. This leads to a
situtaion where we have the chipidea core driver, the "phy" driver, and
sometimes the ehci-msm.c driver operating the same device all at the same
time with very little coordination. This just isn't very safe and is
confusing from a driver perspective when trying to figure out who does what.
Finally, there isn't any HSIC support on platforms like apq8074 so we
should add that.

This patch series updates the ChipIdea driver and the MSM wrapper
(ci_hdrc_msm.c) to properly handle the PHY and wrapper bits at the right
times in the right places. To get there, we update the ChipIdea core to
have support for the ULPI phy bus introduced by Heikki. Along the way
we fix bugs with the extcon handling for peripheral and OTG mode controllers
and move the parts of phy-usb-msm.c that are touching the CI controller
wrapper into the wrapper driver (ci_hdrc_msm.c). Finally we add support
for the HSIC phy based on the ULPI bus and rewrite the HS phy driver
(phy-usb-msm.c) as a standard ULPI phy driver.

Once this series is accepted, we should be able to delete the phy-usb-msm.c
phy-qcom-8x16-usb.c, and ehci-msm.c drivers from the tree and use the ULPI
based phy driver (which also lives in drivers/phy/ instead of drivers/usb/phy/)
and the chipidea host core instead.

I've also sent seperate patches for other minor pieces to make this
all work. The full tree can be found here[3], hacks and all to get
things working. I've tested this on the db410c, apq8074 dragonboard,
and ifc6410 with configfs gadgets and otg cables.

TODO:
 * DMA fails on arm64 so we need something like [1] to make it work.

 * The HSIC phy on the apq8074 dragonboard is connected to a usb4604
   device which requires the i2c driver to probe and send an i2c
   sequence before the HSIC controller enumerates or HSIC doesn't work.
   Right now I have a hack to force the controller to probe defer
   once so that usb4604 probes first. This needs a more proper solution
   like having the DT describe a linkage between the controller and
   the usb device so we can enforce probe ordering.
 
 * OTG support requires a working VBUS supply on apq8074 dragonboard
   and that requires changes to the smbb_charger driver to support
   the OTG OVP switch as a regulator[2]. This series needs revival.

 * Sleeping while atomic problems exist when trying to do phy operations
   underneath some spinlocks in the ci core. I have a patch to remove a
   spinlock, but that needs more thought if it's correct. At the least
   it's necessary though because of how we need to initialize the HSIC
   phy after the reset bit is toggled in USBCMD.

[1] https://lkml.org/lkml/2016/2/22/7
[2] http://lkml.kernel.org/g/1449621618-11900-1-git-send-email-tim.bird at sonymobile.com
[3] https://git.linaro.org/people/stephen.boyd/linux.git/shortlog/refs/heads/usb-hsic-8074

Stephen Boyd (21):
  of: device: Support loading a module with OF based modalias
  usb: ulpi: Support device discovery via DT
  usb: ulpi: Avoid reading/writing in device creation with OF devices
  usb: chipidea: Only read/write OTGSC from one place
  usb: chipidea: Handle extcon events properly
  usb: chipidea: Initialize and reinitialize phy later
  usb: chipidea: Notify of reset when switching into host mode
  usb: chipidea: Kick OTG state machine for AVVIS with vbus extcon
  usb: chipidea: Add support for ULPI PHY bus
  usb: chipidea: msm: Rely on core to override AHBBURST
  usb: chipidea: msm: Use hw_write_id_reg() instead of writel directly
  usb: chipidea: msm: Keep device runtime enabled
  usb: chipidea: msm: Allow core to get usb phy
  usb: chipidea: msm: Add proper clk and reset support
  usb: chipidea: msm: Mux over secondary phy at the right time
  usb: chipidea: msm: Restore wrapper settings after reset
  usb: chipidea: msm: Make platform data driver local instead of global
  usb: chipidea: msm: Add reset controller for PHY POR bit
  usb: chipidea: msm: Be silent on probe defer errors
  phy: Add support for Qualcomm's USB HSIC phy
  phy: Add support for Qualcomm's USB HS phy

 .../devicetree/bindings/phy/qcom,usb-hs-phy.txt    |  71 ++++++
 .../devicetree/bindings/phy/qcom,usb-hsic-phy.txt  |  60 +++++
 Documentation/devicetree/bindings/usb/ulpi.txt     |  20 ++
 drivers/of/device.c                                |  50 ++++
 drivers/phy/Kconfig                                |  15 ++
 drivers/phy/Makefile                               |   2 +
 drivers/phy/phy-qcom-usb-hs.c                      | 283 +++++++++++++++++++++
 drivers/phy/phy-qcom-usb-hsic.c                    | 161 ++++++++++++
 drivers/usb/chipidea/Kconfig                       |   7 +
 drivers/usb/chipidea/Makefile                      |   1 +
 drivers/usb/chipidea/ci.h                          |  23 +-
 drivers/usb/chipidea/ci_hdrc_msm.c                 | 264 ++++++++++++++++---
 drivers/usb/chipidea/core.c                        |  85 +++----
 drivers/usb/chipidea/host.c                        |   6 +-
 drivers/usb/chipidea/otg.c                         |  81 +++++-
 drivers/usb/chipidea/otg_fsm.c                     |  17 ++
 drivers/usb/chipidea/udc.c                         |   2 +
 drivers/usb/chipidea/ulpi.c                        | 113 ++++++++
 drivers/usb/common/ulpi.c                          |  92 +++++--
 include/linux/of_device.h                          |   6 +
 include/linux/usb/chipidea.h                       |   2 +
 21 files changed, 1238 insertions(+), 123 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/phy/qcom,usb-hs-phy.txt
 create mode 100644 Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt
 create mode 100644 Documentation/devicetree/bindings/usb/ulpi.txt
 create mode 100644 drivers/phy/phy-qcom-usb-hs.c
 create mode 100644 drivers/phy/phy-qcom-usb-hsic.c
 create mode 100644 drivers/usb/chipidea/ulpi.c

-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 01/21] of: device: Support loading a module with OF based modalias
  2016-06-26  7:28 ` Stephen Boyd
  (?)
@ 2016-06-26  7:28   ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb
  Cc: Felipe Balbi, Arnd Bergmann, Neil Armstrong, linux-arm-msm,
	linux-kernel, Bjorn Andersson, devicetree, Rob Herring,
	Andy Gross, linux-arm-kernel

In the case of ULPI devices, we want to be able to load the
driver before registering the device so that we don't get stuck
in a loop waiting for the phy module to appear and failing usb
controller probe. Currently we request the ulpi module via the
ulpi ids, but in the DT case we might need to request it with the
OF based modalias instead. Add a common function that allows
anyone to request a module with the OF based modalias.

Cc: Rob Herring <robh+dt@kernel.org>
Cc: <devicetree@vger.kernel.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/of/device.c       | 50 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/of_device.h |  6 ++++++
 2 files changed, 56 insertions(+)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index fd5cfad7c403..f275e5beb736 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -226,6 +226,56 @@ ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len)
 	return tsize;
 }
 
+static ssize_t of_device_modalias_size(struct device *dev)
+{
+	const char *compat;
+	int cplen, i;
+	ssize_t csize;
+
+	if ((!dev) || (!dev->of_node))
+		return -ENODEV;
+
+	/* Name & Type */
+	csize = 5 + strlen(dev->of_node->name) + strlen(dev->of_node->type);
+
+	/* Get compatible property if any */
+	compat = of_get_property(dev->of_node, "compatible", &cplen);
+	if (!compat)
+		return csize;
+
+	/* Find true end (we tolerate multiple \0 at the end */
+	for (i = (cplen - 1); i >= 0 && !compat[i]; i--)
+		cplen--;
+	if (!cplen)
+		return csize;
+	cplen++;
+
+	/* Check space (need cplen+1 chars including final \0) */
+	return csize + cplen;
+}
+
+int of_device_request_module(struct device *dev)
+{
+	char *str;
+	ssize_t size;
+	int ret;
+
+	size = of_device_modalias_size(dev);
+	if (size < 0)
+		return size;
+
+	str = kmalloc(size + 1, GFP_KERNEL);
+	if (!str)
+		return -ENOMEM;
+
+	of_device_get_modalias(dev, str, size);
+	str[size] = '\0';
+	ret = request_module(str);
+	kfree(str);
+
+	return ret;
+}
+
 /**
  * of_device_uevent - Display OF related uevent information
  */
diff --git a/include/linux/of_device.h b/include/linux/of_device.h
index cc7dd687a89d..e9afbcc8de12 100644
--- a/include/linux/of_device.h
+++ b/include/linux/of_device.h
@@ -37,6 +37,7 @@ extern const void *of_device_get_match_data(const struct device *dev);
 
 extern ssize_t of_device_get_modalias(struct device *dev,
 					char *str, ssize_t len);
+extern int of_device_request_module(struct device *dev);
 
 extern void of_device_uevent(struct device *dev, struct kobj_uevent_env *env);
 extern int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env);
@@ -78,6 +79,11 @@ static inline int of_device_get_modalias(struct device *dev,
 	return -ENODEV;
 }
 
+static inline int of_device_request_module(struct device *dev)
+{
+	return -ENODEV;
+}
+
 static inline int of_device_uevent_modalias(struct device *dev,
 				   struct kobj_uevent_env *env)
 {
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 01/21] of: device: Support loading a module with OF based modalias
@ 2016-06-26  7:28   ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb
  Cc: linux-arm-kernel, linux-kernel, linux-arm-msm, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Rob Herring, devicetree

In the case of ULPI devices, we want to be able to load the
driver before registering the device so that we don't get stuck
in a loop waiting for the phy module to appear and failing usb
controller probe. Currently we request the ulpi module via the
ulpi ids, but in the DT case we might need to request it with the
OF based modalias instead. Add a common function that allows
anyone to request a module with the OF based modalias.

Cc: Rob Herring <robh+dt@kernel.org>
Cc: <devicetree@vger.kernel.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/of/device.c       | 50 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/of_device.h |  6 ++++++
 2 files changed, 56 insertions(+)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index fd5cfad7c403..f275e5beb736 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -226,6 +226,56 @@ ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len)
 	return tsize;
 }
 
+static ssize_t of_device_modalias_size(struct device *dev)
+{
+	const char *compat;
+	int cplen, i;
+	ssize_t csize;
+
+	if ((!dev) || (!dev->of_node))
+		return -ENODEV;
+
+	/* Name & Type */
+	csize = 5 + strlen(dev->of_node->name) + strlen(dev->of_node->type);
+
+	/* Get compatible property if any */
+	compat = of_get_property(dev->of_node, "compatible", &cplen);
+	if (!compat)
+		return csize;
+
+	/* Find true end (we tolerate multiple \0 at the end */
+	for (i = (cplen - 1); i >= 0 && !compat[i]; i--)
+		cplen--;
+	if (!cplen)
+		return csize;
+	cplen++;
+
+	/* Check space (need cplen+1 chars including final \0) */
+	return csize + cplen;
+}
+
+int of_device_request_module(struct device *dev)
+{
+	char *str;
+	ssize_t size;
+	int ret;
+
+	size = of_device_modalias_size(dev);
+	if (size < 0)
+		return size;
+
+	str = kmalloc(size + 1, GFP_KERNEL);
+	if (!str)
+		return -ENOMEM;
+
+	of_device_get_modalias(dev, str, size);
+	str[size] = '\0';
+	ret = request_module(str);
+	kfree(str);
+
+	return ret;
+}
+
 /**
  * of_device_uevent - Display OF related uevent information
  */
diff --git a/include/linux/of_device.h b/include/linux/of_device.h
index cc7dd687a89d..e9afbcc8de12 100644
--- a/include/linux/of_device.h
+++ b/include/linux/of_device.h
@@ -37,6 +37,7 @@ extern const void *of_device_get_match_data(const struct device *dev);
 
 extern ssize_t of_device_get_modalias(struct device *dev,
 					char *str, ssize_t len);
+extern int of_device_request_module(struct device *dev);
 
 extern void of_device_uevent(struct device *dev, struct kobj_uevent_env *env);
 extern int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env);
@@ -78,6 +79,11 @@ static inline int of_device_get_modalias(struct device *dev,
 	return -ENODEV;
 }
 
+static inline int of_device_request_module(struct device *dev)
+{
+	return -ENODEV;
+}
+
 static inline int of_device_uevent_modalias(struct device *dev,
 				   struct kobj_uevent_env *env)
 {
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 01/21] of: device: Support loading a module with OF based modalias
@ 2016-06-26  7:28   ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-arm-kernel

In the case of ULPI devices, we want to be able to load the
driver before registering the device so that we don't get stuck
in a loop waiting for the phy module to appear and failing usb
controller probe. Currently we request the ulpi module via the
ulpi ids, but in the DT case we might need to request it with the
OF based modalias instead. Add a common function that allows
anyone to request a module with the OF based modalias.

Cc: Rob Herring <robh+dt@kernel.org>
Cc: <devicetree@vger.kernel.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/of/device.c       | 50 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/of_device.h |  6 ++++++
 2 files changed, 56 insertions(+)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index fd5cfad7c403..f275e5beb736 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -226,6 +226,56 @@ ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len)
 	return tsize;
 }
 
+static ssize_t of_device_modalias_size(struct device *dev)
+{
+	const char *compat;
+	int cplen, i;
+	ssize_t csize;
+
+	if ((!dev) || (!dev->of_node))
+		return -ENODEV;
+
+	/* Name & Type */
+	csize = 5 + strlen(dev->of_node->name) + strlen(dev->of_node->type);
+
+	/* Get compatible property if any */
+	compat = of_get_property(dev->of_node, "compatible", &cplen);
+	if (!compat)
+		return csize;
+
+	/* Find true end (we tolerate multiple \0 at the end */
+	for (i = (cplen - 1); i >= 0 && !compat[i]; i--)
+		cplen--;
+	if (!cplen)
+		return csize;
+	cplen++;
+
+	/* Check space (need cplen+1 chars including final \0) */
+	return csize + cplen;
+}
+
+int of_device_request_module(struct device *dev)
+{
+	char *str;
+	ssize_t size;
+	int ret;
+
+	size = of_device_modalias_size(dev);
+	if (size < 0)
+		return size;
+
+	str = kmalloc(size + 1, GFP_KERNEL);
+	if (!str)
+		return -ENOMEM;
+
+	of_device_get_modalias(dev, str, size);
+	str[size] = '\0';
+	ret = request_module(str);
+	kfree(str);
+
+	return ret;
+}
+
 /**
  * of_device_uevent - Display OF related uevent information
  */
diff --git a/include/linux/of_device.h b/include/linux/of_device.h
index cc7dd687a89d..e9afbcc8de12 100644
--- a/include/linux/of_device.h
+++ b/include/linux/of_device.h
@@ -37,6 +37,7 @@ extern const void *of_device_get_match_data(const struct device *dev);
 
 extern ssize_t of_device_get_modalias(struct device *dev,
 					char *str, ssize_t len);
+extern int of_device_request_module(struct device *dev);
 
 extern void of_device_uevent(struct device *dev, struct kobj_uevent_env *env);
 extern int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env);
@@ -78,6 +79,11 @@ static inline int of_device_get_modalias(struct device *dev,
 	return -ENODEV;
 }
 
+static inline int of_device_request_module(struct device *dev)
+{
+	return -ENODEV;
+}
+
 static inline int of_device_uevent_modalias(struct device *dev,
 				   struct kobj_uevent_env *env)
 {
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 02/21] usb: ulpi: Support device discovery via DT
  2016-06-26  7:28 ` Stephen Boyd
  (?)
@ 2016-06-26  7:28     ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Greg Kroah-Hartman, Heikki Krogerus,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring

The qcom HSIC ulpi phy doesn't have any bits set in the vendor or
product id ulpi registers. This makes it impossible to make a
ulpi driver match against the id registers. Add support to
discover the ulpi phys via DT to help alleviate this problem.
We'll look for a ulpi bus node underneath the device registering
the ulpi viewport (or the parent of that device to support
chipidea's device layout) and then match up the phy node
underneath that with the ulpi device that's created.

The side benefit of this is that we can use standard DT
properties in the phy node like clks, regulators, gpios, etc.
because we don't have firmware like ACPI to turn these things on
for us. And we can use the DT phy binding to point our phy
consumer to the phy provider.

Cc: Greg Kroah-Hartman <gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org>
Cc: Heikki Krogerus <heikki.krogerus-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Cc: <devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>
Cc: Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Stephen Boyd <stephen.boyd-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 Documentation/devicetree/bindings/usb/ulpi.txt | 20 +++++++++
 drivers/usb/common/ulpi.c                      | 56 +++++++++++++++++++++++++-
 2 files changed, 74 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/usb/ulpi.txt

diff --git a/Documentation/devicetree/bindings/usb/ulpi.txt b/Documentation/devicetree/bindings/usb/ulpi.txt
new file mode 100644
index 000000000000..ca179dc4bd50
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/ulpi.txt
@@ -0,0 +1,20 @@
+ULPI bus binding
+----------------
+
+Phys that are behind a ULPI connection can be described with the following
+binding. The host controller shall have a "ulpi" named node as a child, and
+that node shall have one enabled node underneath it representing the ulpi
+device on the bus.
+
+EXAMPLE
+-------
+
+usb {
+	compatible = "vendor,usb-controller";
+
+	ulpi {
+		phy {
+			compatible = "vendor,phy";
+		};
+	};
+};
diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c
index 01c0c0477a9e..980af672bfe3 100644
--- a/drivers/usb/common/ulpi.c
+++ b/drivers/usb/common/ulpi.c
@@ -16,6 +16,9 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/acpi.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/clk/clk-conf.h>
 
 /* -------------------------------------------------------------------------- */
 
@@ -39,7 +42,10 @@ static int ulpi_match(struct device *dev, struct device_driver *driver)
 	struct ulpi *ulpi = to_ulpi_dev(dev);
 	const struct ulpi_device_id *id;
 
-	for (id = drv->id_table; id->vendor; id++)
+	if (of_driver_match_device(dev, driver))
+		return 1;
+
+	for (id = drv->id_table; id && id->vendor; id++)
 		if (id->vendor == ulpi->id.vendor &&
 		    id->product == ulpi->id.product)
 			return 1;
@@ -50,6 +56,11 @@ static int ulpi_match(struct device *dev, struct device_driver *driver)
 static int ulpi_uevent(struct device *dev, struct kobj_uevent_env *env)
 {
 	struct ulpi *ulpi = to_ulpi_dev(dev);
+	int ret;
+
+	ret = of_device_uevent_modalias(dev, env);
+	if (ret != -ENODEV)
+		return ret;
 
 	if (add_uevent_var(env, "MODALIAS=ulpi:v%04xp%04x",
 			   ulpi->id.vendor, ulpi->id.product))
@@ -60,6 +71,11 @@ static int ulpi_uevent(struct device *dev, struct kobj_uevent_env *env)
 static int ulpi_probe(struct device *dev)
 {
 	struct ulpi_driver *drv = to_ulpi_driver(dev->driver);
+	int ret;
+
+	ret = of_clk_set_defaults(dev->of_node, false);
+	if (ret < 0)
+		return ret;
 
 	return drv->probe(to_ulpi_dev(dev));
 }
@@ -87,8 +103,13 @@ static struct bus_type ulpi_bus = {
 static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
 			     char *buf)
 {
+	int len;
 	struct ulpi *ulpi = to_ulpi_dev(dev);
 
+	len = of_device_get_modalias(dev, buf, PAGE_SIZE - 1);
+	if (len != -ENODEV)
+		return len;
+
 	return sprintf(buf, "ulpi:v%04xp%04x\n",
 		       ulpi->id.vendor, ulpi->id.product);
 }
@@ -152,6 +173,28 @@ EXPORT_SYMBOL_GPL(ulpi_unregister_driver);
 
 /* -------------------------------------------------------------------------- */
 
+static int ulpi_of_register(struct ulpi *ulpi)
+{
+	struct device_node *np = NULL, *child;
+
+	/* Find a ulpi bus underneath the parent or the parent of the parent */
+	if (ulpi->dev.parent->of_node)
+		np = of_find_node_by_name(ulpi->dev.parent->of_node, "ulpi");
+	else if (ulpi->dev.parent->parent &&
+		 ulpi->dev.parent->parent->of_node)
+		np = of_find_node_by_name(ulpi->dev.parent->parent->of_node, "ulpi");
+	if (!np)
+		return 0;
+
+	child = of_get_next_available_child(np, NULL);
+	if (!child)
+		return -EINVAL;
+
+	ulpi->dev.of_node = child;
+
+	return 0;
+}
+
 static int ulpi_register(struct device *dev, struct ulpi *ulpi)
 {
 	int ret;
@@ -181,7 +224,15 @@ static int ulpi_register(struct device *dev, struct ulpi *ulpi)
 
 	ACPI_COMPANION_SET(&ulpi->dev, ACPI_COMPANION(dev));
 
-	request_module("ulpi:v%04xp%04x", ulpi->id.vendor, ulpi->id.product);
+	if (IS_ENABLED(CONFIG_OF)) {
+		ret = ulpi_of_register(ulpi);
+		if (ret)
+			return ret;
+	}
+
+	if (of_device_request_module(&ulpi->dev))
+		request_module("ulpi:v%04xp%04x", ulpi->id.vendor,
+			       ulpi->id.product);
 
 	ret = device_register(&ulpi->dev);
 	if (ret)
@@ -232,6 +283,7 @@ EXPORT_SYMBOL_GPL(ulpi_register_interface);
  */
 void ulpi_unregister_interface(struct ulpi *ulpi)
 {
+	of_node_put(ulpi->dev.of_node);
 	device_unregister(&ulpi->dev);
 }
 EXPORT_SYMBOL_GPL(ulpi_unregister_interface);
-- 
2.9.0.rc2.8.ga28705d

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 02/21] usb: ulpi: Support device discovery via DT
@ 2016-06-26  7:28     ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb
  Cc: linux-arm-kernel, linux-kernel, linux-arm-msm, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Greg Kroah-Hartman, Heikki Krogerus, devicetree, Rob Herring

The qcom HSIC ulpi phy doesn't have any bits set in the vendor or
product id ulpi registers. This makes it impossible to make a
ulpi driver match against the id registers. Add support to
discover the ulpi phys via DT to help alleviate this problem.
We'll look for a ulpi bus node underneath the device registering
the ulpi viewport (or the parent of that device to support
chipidea's device layout) and then match up the phy node
underneath that with the ulpi device that's created.

The side benefit of this is that we can use standard DT
properties in the phy node like clks, regulators, gpios, etc.
because we don't have firmware like ACPI to turn these things on
for us. And we can use the DT phy binding to point our phy
consumer to the phy provider.

Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Cc: <devicetree@vger.kernel.org>
Cc: Rob Herring <robh+dt@kernel.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 Documentation/devicetree/bindings/usb/ulpi.txt | 20 +++++++++
 drivers/usb/common/ulpi.c                      | 56 +++++++++++++++++++++++++-
 2 files changed, 74 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/usb/ulpi.txt

diff --git a/Documentation/devicetree/bindings/usb/ulpi.txt b/Documentation/devicetree/bindings/usb/ulpi.txt
new file mode 100644
index 000000000000..ca179dc4bd50
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/ulpi.txt
@@ -0,0 +1,20 @@
+ULPI bus binding
+----------------
+
+Phys that are behind a ULPI connection can be described with the following
+binding. The host controller shall have a "ulpi" named node as a child, and
+that node shall have one enabled node underneath it representing the ulpi
+device on the bus.
+
+EXAMPLE
+-------
+
+usb {
+	compatible = "vendor,usb-controller";
+
+	ulpi {
+		phy {
+			compatible = "vendor,phy";
+		};
+	};
+};
diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c
index 01c0c0477a9e..980af672bfe3 100644
--- a/drivers/usb/common/ulpi.c
+++ b/drivers/usb/common/ulpi.c
@@ -16,6 +16,9 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/acpi.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/clk/clk-conf.h>
 
 /* -------------------------------------------------------------------------- */
 
@@ -39,7 +42,10 @@ static int ulpi_match(struct device *dev, struct device_driver *driver)
 	struct ulpi *ulpi = to_ulpi_dev(dev);
 	const struct ulpi_device_id *id;
 
-	for (id = drv->id_table; id->vendor; id++)
+	if (of_driver_match_device(dev, driver))
+		return 1;
+
+	for (id = drv->id_table; id && id->vendor; id++)
 		if (id->vendor == ulpi->id.vendor &&
 		    id->product == ulpi->id.product)
 			return 1;
@@ -50,6 +56,11 @@ static int ulpi_match(struct device *dev, struct device_driver *driver)
 static int ulpi_uevent(struct device *dev, struct kobj_uevent_env *env)
 {
 	struct ulpi *ulpi = to_ulpi_dev(dev);
+	int ret;
+
+	ret = of_device_uevent_modalias(dev, env);
+	if (ret != -ENODEV)
+		return ret;
 
 	if (add_uevent_var(env, "MODALIAS=ulpi:v%04xp%04x",
 			   ulpi->id.vendor, ulpi->id.product))
@@ -60,6 +71,11 @@ static int ulpi_uevent(struct device *dev, struct kobj_uevent_env *env)
 static int ulpi_probe(struct device *dev)
 {
 	struct ulpi_driver *drv = to_ulpi_driver(dev->driver);
+	int ret;
+
+	ret = of_clk_set_defaults(dev->of_node, false);
+	if (ret < 0)
+		return ret;
 
 	return drv->probe(to_ulpi_dev(dev));
 }
@@ -87,8 +103,13 @@ static struct bus_type ulpi_bus = {
 static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
 			     char *buf)
 {
+	int len;
 	struct ulpi *ulpi = to_ulpi_dev(dev);
 
+	len = of_device_get_modalias(dev, buf, PAGE_SIZE - 1);
+	if (len != -ENODEV)
+		return len;
+
 	return sprintf(buf, "ulpi:v%04xp%04x\n",
 		       ulpi->id.vendor, ulpi->id.product);
 }
@@ -152,6 +173,28 @@ EXPORT_SYMBOL_GPL(ulpi_unregister_driver);
 
 /* -------------------------------------------------------------------------- */
 
+static int ulpi_of_register(struct ulpi *ulpi)
+{
+	struct device_node *np = NULL, *child;
+
+	/* Find a ulpi bus underneath the parent or the parent of the parent */
+	if (ulpi->dev.parent->of_node)
+		np = of_find_node_by_name(ulpi->dev.parent->of_node, "ulpi");
+	else if (ulpi->dev.parent->parent &&
+		 ulpi->dev.parent->parent->of_node)
+		np = of_find_node_by_name(ulpi->dev.parent->parent->of_node, "ulpi");
+	if (!np)
+		return 0;
+
+	child = of_get_next_available_child(np, NULL);
+	if (!child)
+		return -EINVAL;
+
+	ulpi->dev.of_node = child;
+
+	return 0;
+}
+
 static int ulpi_register(struct device *dev, struct ulpi *ulpi)
 {
 	int ret;
@@ -181,7 +224,15 @@ static int ulpi_register(struct device *dev, struct ulpi *ulpi)
 
 	ACPI_COMPANION_SET(&ulpi->dev, ACPI_COMPANION(dev));
 
-	request_module("ulpi:v%04xp%04x", ulpi->id.vendor, ulpi->id.product);
+	if (IS_ENABLED(CONFIG_OF)) {
+		ret = ulpi_of_register(ulpi);
+		if (ret)
+			return ret;
+	}
+
+	if (of_device_request_module(&ulpi->dev))
+		request_module("ulpi:v%04xp%04x", ulpi->id.vendor,
+			       ulpi->id.product);
 
 	ret = device_register(&ulpi->dev);
 	if (ret)
@@ -232,6 +283,7 @@ EXPORT_SYMBOL_GPL(ulpi_register_interface);
  */
 void ulpi_unregister_interface(struct ulpi *ulpi)
 {
+	of_node_put(ulpi->dev.of_node);
 	device_unregister(&ulpi->dev);
 }
 EXPORT_SYMBOL_GPL(ulpi_unregister_interface);
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 02/21] usb: ulpi: Support device discovery via DT
@ 2016-06-26  7:28     ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-arm-kernel

The qcom HSIC ulpi phy doesn't have any bits set in the vendor or
product id ulpi registers. This makes it impossible to make a
ulpi driver match against the id registers. Add support to
discover the ulpi phys via DT to help alleviate this problem.
We'll look for a ulpi bus node underneath the device registering
the ulpi viewport (or the parent of that device to support
chipidea's device layout) and then match up the phy node
underneath that with the ulpi device that's created.

The side benefit of this is that we can use standard DT
properties in the phy node like clks, regulators, gpios, etc.
because we don't have firmware like ACPI to turn these things on
for us. And we can use the DT phy binding to point our phy
consumer to the phy provider.

Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Cc: <devicetree@vger.kernel.org>
Cc: Rob Herring <robh+dt@kernel.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 Documentation/devicetree/bindings/usb/ulpi.txt | 20 +++++++++
 drivers/usb/common/ulpi.c                      | 56 +++++++++++++++++++++++++-
 2 files changed, 74 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/usb/ulpi.txt

diff --git a/Documentation/devicetree/bindings/usb/ulpi.txt b/Documentation/devicetree/bindings/usb/ulpi.txt
new file mode 100644
index 000000000000..ca179dc4bd50
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/ulpi.txt
@@ -0,0 +1,20 @@
+ULPI bus binding
+----------------
+
+Phys that are behind a ULPI connection can be described with the following
+binding. The host controller shall have a "ulpi" named node as a child, and
+that node shall have one enabled node underneath it representing the ulpi
+device on the bus.
+
+EXAMPLE
+-------
+
+usb {
+	compatible = "vendor,usb-controller";
+
+	ulpi {
+		phy {
+			compatible = "vendor,phy";
+		};
+	};
+};
diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c
index 01c0c0477a9e..980af672bfe3 100644
--- a/drivers/usb/common/ulpi.c
+++ b/drivers/usb/common/ulpi.c
@@ -16,6 +16,9 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/acpi.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/clk/clk-conf.h>
 
 /* -------------------------------------------------------------------------- */
 
@@ -39,7 +42,10 @@ static int ulpi_match(struct device *dev, struct device_driver *driver)
 	struct ulpi *ulpi = to_ulpi_dev(dev);
 	const struct ulpi_device_id *id;
 
-	for (id = drv->id_table; id->vendor; id++)
+	if (of_driver_match_device(dev, driver))
+		return 1;
+
+	for (id = drv->id_table; id && id->vendor; id++)
 		if (id->vendor == ulpi->id.vendor &&
 		    id->product == ulpi->id.product)
 			return 1;
@@ -50,6 +56,11 @@ static int ulpi_match(struct device *dev, struct device_driver *driver)
 static int ulpi_uevent(struct device *dev, struct kobj_uevent_env *env)
 {
 	struct ulpi *ulpi = to_ulpi_dev(dev);
+	int ret;
+
+	ret = of_device_uevent_modalias(dev, env);
+	if (ret != -ENODEV)
+		return ret;
 
 	if (add_uevent_var(env, "MODALIAS=ulpi:v%04xp%04x",
 			   ulpi->id.vendor, ulpi->id.product))
@@ -60,6 +71,11 @@ static int ulpi_uevent(struct device *dev, struct kobj_uevent_env *env)
 static int ulpi_probe(struct device *dev)
 {
 	struct ulpi_driver *drv = to_ulpi_driver(dev->driver);
+	int ret;
+
+	ret = of_clk_set_defaults(dev->of_node, false);
+	if (ret < 0)
+		return ret;
 
 	return drv->probe(to_ulpi_dev(dev));
 }
@@ -87,8 +103,13 @@ static struct bus_type ulpi_bus = {
 static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
 			     char *buf)
 {
+	int len;
 	struct ulpi *ulpi = to_ulpi_dev(dev);
 
+	len = of_device_get_modalias(dev, buf, PAGE_SIZE - 1);
+	if (len != -ENODEV)
+		return len;
+
 	return sprintf(buf, "ulpi:v%04xp%04x\n",
 		       ulpi->id.vendor, ulpi->id.product);
 }
@@ -152,6 +173,28 @@ EXPORT_SYMBOL_GPL(ulpi_unregister_driver);
 
 /* -------------------------------------------------------------------------- */
 
+static int ulpi_of_register(struct ulpi *ulpi)
+{
+	struct device_node *np = NULL, *child;
+
+	/* Find a ulpi bus underneath the parent or the parent of the parent */
+	if (ulpi->dev.parent->of_node)
+		np = of_find_node_by_name(ulpi->dev.parent->of_node, "ulpi");
+	else if (ulpi->dev.parent->parent &&
+		 ulpi->dev.parent->parent->of_node)
+		np = of_find_node_by_name(ulpi->dev.parent->parent->of_node, "ulpi");
+	if (!np)
+		return 0;
+
+	child = of_get_next_available_child(np, NULL);
+	if (!child)
+		return -EINVAL;
+
+	ulpi->dev.of_node = child;
+
+	return 0;
+}
+
 static int ulpi_register(struct device *dev, struct ulpi *ulpi)
 {
 	int ret;
@@ -181,7 +224,15 @@ static int ulpi_register(struct device *dev, struct ulpi *ulpi)
 
 	ACPI_COMPANION_SET(&ulpi->dev, ACPI_COMPANION(dev));
 
-	request_module("ulpi:v%04xp%04x", ulpi->id.vendor, ulpi->id.product);
+	if (IS_ENABLED(CONFIG_OF)) {
+		ret = ulpi_of_register(ulpi);
+		if (ret)
+			return ret;
+	}
+
+	if (of_device_request_module(&ulpi->dev))
+		request_module("ulpi:v%04xp%04x", ulpi->id.vendor,
+			       ulpi->id.product);
 
 	ret = device_register(&ulpi->dev);
 	if (ret)
@@ -232,6 +283,7 @@ EXPORT_SYMBOL_GPL(ulpi_register_interface);
  */
 void ulpi_unregister_interface(struct ulpi *ulpi)
 {
+	of_node_put(ulpi->dev.of_node);
 	device_unregister(&ulpi->dev);
 }
 EXPORT_SYMBOL_GPL(ulpi_unregister_interface);
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 03/21] usb: ulpi: Avoid reading/writing in device creation with OF devices
  2016-06-26  7:28 ` Stephen Boyd
  (?)
@ 2016-06-26  7:28     ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Greg Kroah-Hartman, Heikki Krogerus

ULPI devices are matched up against ULPI drivers by reading the
vendor id and product id registers in the ULPI address space.
Before we try to read those registers we'll do a scratch write to
test the interface. Unfortunately, this doesn't work well if the
ULPI device is not powered at the time of device creation. In
that case, the scratch register writes fail and product and
vendor ids can't be read.

If the ULPI spec had some way to describe generic power
requirements for the scratch, product, and vendor registers we
could but power sequencing into the ULPI bus layer and power up
the device before touching the hardware. Unfortunately this
doesn't exist. Furthermore, the power information is device
specific, so it varies from device to device and is not standard.

Let's punt on doing the reads/writes here when we're using DT
backed ULPI devices. This avoids any problems where we need to
power on the device but haven't figured out which device it is
yet to know what sort of regulators, clks, etc. that need to be
turned on for it to work.

Cc: Greg Kroah-Hartman <gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org>
Cc: Heikki Krogerus <heikki.krogerus-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Signed-off-by: Stephen Boyd <stephen.boyd-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 drivers/usb/common/ulpi.c | 40 +++++++++++++++++++++-------------------
 1 file changed, 21 insertions(+), 19 deletions(-)

diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c
index 980af672bfe3..a6b2a150b176 100644
--- a/drivers/usb/common/ulpi.c
+++ b/drivers/usb/common/ulpi.c
@@ -197,25 +197,7 @@ static int ulpi_of_register(struct ulpi *ulpi)
 
 static int ulpi_register(struct device *dev, struct ulpi *ulpi)
 {
-	int ret;
-
-	/* Test the interface */
-	ret = ulpi_write(ulpi, ULPI_SCRATCH, 0xaa);
-	if (ret < 0)
-		return ret;
-
-	ret = ulpi_read(ulpi, ULPI_SCRATCH);
-	if (ret < 0)
-		return ret;
-
-	if (ret != 0xaa)
-		return -ENODEV;
-
-	ulpi->id.vendor = ulpi_read(ulpi, ULPI_VENDOR_ID_LOW);
-	ulpi->id.vendor |= ulpi_read(ulpi, ULPI_VENDOR_ID_HIGH) << 8;
-
-	ulpi->id.product = ulpi_read(ulpi, ULPI_PRODUCT_ID_LOW);
-	ulpi->id.product |= ulpi_read(ulpi, ULPI_PRODUCT_ID_HIGH) << 8;
+	int ret = -ENODEV;
 
 	ulpi->dev.parent = dev;
 	ulpi->dev.bus = &ulpi_bus;
@@ -230,6 +212,26 @@ static int ulpi_register(struct device *dev, struct ulpi *ulpi)
 			return ret;
 	}
 
+	if (ret) {
+		/* Test the interface */
+		ret = ulpi_write(ulpi, ULPI_SCRATCH, 0xaa);
+		if (ret < 0)
+			return ret;
+
+		ret = ulpi_read(ulpi, ULPI_SCRATCH);
+		if (ret < 0)
+			return ret;
+
+		if (ret != 0xaa)
+			return -ENODEV;
+
+		ulpi->id.vendor = ulpi_read(ulpi, ULPI_VENDOR_ID_LOW);
+		ulpi->id.vendor |= ulpi_read(ulpi, ULPI_VENDOR_ID_HIGH) << 8;
+
+		ulpi->id.product = ulpi_read(ulpi, ULPI_PRODUCT_ID_LOW);
+		ulpi->id.product |= ulpi_read(ulpi, ULPI_PRODUCT_ID_HIGH) << 8;
+	}
+
 	if (of_device_request_module(&ulpi->dev))
 		request_module("ulpi:v%04xp%04x", ulpi->id.vendor,
 			       ulpi->id.product);
-- 
2.9.0.rc2.8.ga28705d

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 03/21] usb: ulpi: Avoid reading/writing in device creation with OF devices
@ 2016-06-26  7:28     ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb
  Cc: linux-arm-kernel, linux-kernel, linux-arm-msm, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Greg Kroah-Hartman, Heikki Krogerus

ULPI devices are matched up against ULPI drivers by reading the
vendor id and product id registers in the ULPI address space.
Before we try to read those registers we'll do a scratch write to
test the interface. Unfortunately, this doesn't work well if the
ULPI device is not powered at the time of device creation. In
that case, the scratch register writes fail and product and
vendor ids can't be read.

If the ULPI spec had some way to describe generic power
requirements for the scratch, product, and vendor registers we
could but power sequencing into the ULPI bus layer and power up
the device before touching the hardware. Unfortunately this
doesn't exist. Furthermore, the power information is device
specific, so it varies from device to device and is not standard.

Let's punt on doing the reads/writes here when we're using DT
backed ULPI devices. This avoids any problems where we need to
power on the device but haven't figured out which device it is
yet to know what sort of regulators, clks, etc. that need to be
turned on for it to work.

Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/common/ulpi.c | 40 +++++++++++++++++++++-------------------
 1 file changed, 21 insertions(+), 19 deletions(-)

diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c
index 980af672bfe3..a6b2a150b176 100644
--- a/drivers/usb/common/ulpi.c
+++ b/drivers/usb/common/ulpi.c
@@ -197,25 +197,7 @@ static int ulpi_of_register(struct ulpi *ulpi)
 
 static int ulpi_register(struct device *dev, struct ulpi *ulpi)
 {
-	int ret;
-
-	/* Test the interface */
-	ret = ulpi_write(ulpi, ULPI_SCRATCH, 0xaa);
-	if (ret < 0)
-		return ret;
-
-	ret = ulpi_read(ulpi, ULPI_SCRATCH);
-	if (ret < 0)
-		return ret;
-
-	if (ret != 0xaa)
-		return -ENODEV;
-
-	ulpi->id.vendor = ulpi_read(ulpi, ULPI_VENDOR_ID_LOW);
-	ulpi->id.vendor |= ulpi_read(ulpi, ULPI_VENDOR_ID_HIGH) << 8;
-
-	ulpi->id.product = ulpi_read(ulpi, ULPI_PRODUCT_ID_LOW);
-	ulpi->id.product |= ulpi_read(ulpi, ULPI_PRODUCT_ID_HIGH) << 8;
+	int ret = -ENODEV;
 
 	ulpi->dev.parent = dev;
 	ulpi->dev.bus = &ulpi_bus;
@@ -230,6 +212,26 @@ static int ulpi_register(struct device *dev, struct ulpi *ulpi)
 			return ret;
 	}
 
+	if (ret) {
+		/* Test the interface */
+		ret = ulpi_write(ulpi, ULPI_SCRATCH, 0xaa);
+		if (ret < 0)
+			return ret;
+
+		ret = ulpi_read(ulpi, ULPI_SCRATCH);
+		if (ret < 0)
+			return ret;
+
+		if (ret != 0xaa)
+			return -ENODEV;
+
+		ulpi->id.vendor = ulpi_read(ulpi, ULPI_VENDOR_ID_LOW);
+		ulpi->id.vendor |= ulpi_read(ulpi, ULPI_VENDOR_ID_HIGH) << 8;
+
+		ulpi->id.product = ulpi_read(ulpi, ULPI_PRODUCT_ID_LOW);
+		ulpi->id.product |= ulpi_read(ulpi, ULPI_PRODUCT_ID_HIGH) << 8;
+	}
+
 	if (of_device_request_module(&ulpi->dev))
 		request_module("ulpi:v%04xp%04x", ulpi->id.vendor,
 			       ulpi->id.product);
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 03/21] usb: ulpi: Avoid reading/writing in device creation with OF devices
@ 2016-06-26  7:28     ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-arm-kernel

ULPI devices are matched up against ULPI drivers by reading the
vendor id and product id registers in the ULPI address space.
Before we try to read those registers we'll do a scratch write to
test the interface. Unfortunately, this doesn't work well if the
ULPI device is not powered at the time of device creation. In
that case, the scratch register writes fail and product and
vendor ids can't be read.

If the ULPI spec had some way to describe generic power
requirements for the scratch, product, and vendor registers we
could but power sequencing into the ULPI bus layer and power up
the device before touching the hardware. Unfortunately this
doesn't exist. Furthermore, the power information is device
specific, so it varies from device to device and is not standard.

Let's punt on doing the reads/writes here when we're using DT
backed ULPI devices. This avoids any problems where we need to
power on the device but haven't figured out which device it is
yet to know what sort of regulators, clks, etc. that need to be
turned on for it to work.

Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/common/ulpi.c | 40 +++++++++++++++++++++-------------------
 1 file changed, 21 insertions(+), 19 deletions(-)

diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c
index 980af672bfe3..a6b2a150b176 100644
--- a/drivers/usb/common/ulpi.c
+++ b/drivers/usb/common/ulpi.c
@@ -197,25 +197,7 @@ static int ulpi_of_register(struct ulpi *ulpi)
 
 static int ulpi_register(struct device *dev, struct ulpi *ulpi)
 {
-	int ret;
-
-	/* Test the interface */
-	ret = ulpi_write(ulpi, ULPI_SCRATCH, 0xaa);
-	if (ret < 0)
-		return ret;
-
-	ret = ulpi_read(ulpi, ULPI_SCRATCH);
-	if (ret < 0)
-		return ret;
-
-	if (ret != 0xaa)
-		return -ENODEV;
-
-	ulpi->id.vendor = ulpi_read(ulpi, ULPI_VENDOR_ID_LOW);
-	ulpi->id.vendor |= ulpi_read(ulpi, ULPI_VENDOR_ID_HIGH) << 8;
-
-	ulpi->id.product = ulpi_read(ulpi, ULPI_PRODUCT_ID_LOW);
-	ulpi->id.product |= ulpi_read(ulpi, ULPI_PRODUCT_ID_HIGH) << 8;
+	int ret = -ENODEV;
 
 	ulpi->dev.parent = dev;
 	ulpi->dev.bus = &ulpi_bus;
@@ -230,6 +212,26 @@ static int ulpi_register(struct device *dev, struct ulpi *ulpi)
 			return ret;
 	}
 
+	if (ret) {
+		/* Test the interface */
+		ret = ulpi_write(ulpi, ULPI_SCRATCH, 0xaa);
+		if (ret < 0)
+			return ret;
+
+		ret = ulpi_read(ulpi, ULPI_SCRATCH);
+		if (ret < 0)
+			return ret;
+
+		if (ret != 0xaa)
+			return -ENODEV;
+
+		ulpi->id.vendor = ulpi_read(ulpi, ULPI_VENDOR_ID_LOW);
+		ulpi->id.vendor |= ulpi_read(ulpi, ULPI_VENDOR_ID_HIGH) << 8;
+
+		ulpi->id.product = ulpi_read(ulpi, ULPI_PRODUCT_ID_LOW);
+		ulpi->id.product |= ulpi_read(ulpi, ULPI_PRODUCT_ID_HIGH) << 8;
+	}
+
 	if (of_device_request_module(&ulpi->dev))
 		request_module("ulpi:v%04xp%04x", ulpi->id.vendor,
 			       ulpi->id.product);
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 04/21] usb: chipidea: Only read/write OTGSC from one place
  2016-06-26  7:28 ` Stephen Boyd
  (?)
@ 2016-06-26  7:28   ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb
  Cc: Felipe Balbi, Arnd Bergmann, Neil Armstrong, linux-arm-msm,
	linux-kernel, Bjorn Andersson, Peter Chen, Greg Kroah-Hartman,
	Andy Gross, Ivan T. Ivanov, linux-arm-kernel

With the id and vbus detection done via extcon we need to make
sure we poll the status of OTGSC properly by considering what the
extcon is saying, and not just what the register is saying. Let's
move this hw_wait_reg() function to the only place it's used and
simplify it for polling the OTGSC register. Then we can make
certain we only use the hw_read_otgsc() API to read OTGSC, which
will make sure we properly handle extcon events.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Ivan T. Ivanov" <iivanov.xz@gmail.com>
Fixes: 3ecb3e09b042 ("usb: chipidea: Use extcon framework for VBUS and ID detect")
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/core.c | 32 --------------------------------
 drivers/usb/chipidea/otg.c  | 35 +++++++++++++++++++++++++++++++----
 2 files changed, 31 insertions(+), 36 deletions(-)

diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 69426e644d17..01390e02ee53 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -516,38 +516,6 @@ int hw_device_reset(struct ci_hdrc *ci)
 	return 0;
 }
 
-/**
- * hw_wait_reg: wait the register value
- *
- * Sometimes, it needs to wait register value before going on.
- * Eg, when switch to device mode, the vbus value should be lower
- * than OTGSC_BSV before connects to host.
- *
- * @ci: the controller
- * @reg: register index
- * @mask: mast bit
- * @value: the bit value to wait
- * @timeout_ms: timeout in millisecond
- *
- * This function returns an error code if timeout
- */
-int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
-				u32 value, unsigned int timeout_ms)
-{
-	unsigned long elapse = jiffies + msecs_to_jiffies(timeout_ms);
-
-	while (hw_read(ci, reg, mask) != value) {
-		if (time_after(jiffies, elapse)) {
-			dev_err(ci->dev, "timeout waiting for %08x in %d\n",
-					mask, reg);
-			return -ETIMEDOUT;
-		}
-		msleep(20);
-	}
-
-	return 0;
-}
-
 static irqreturn_t ci_irq(int irq, void *data)
 {
 	struct ci_hdrc *ci = data;
diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
index 03b6743461d1..763a8332b009 100644
--- a/drivers/usb/chipidea/otg.c
+++ b/drivers/usb/chipidea/otg.c
@@ -104,7 +104,32 @@ void ci_handle_vbus_change(struct ci_hdrc *ci)
 		usb_gadget_vbus_disconnect(&ci->gadget);
 }
 
-#define CI_VBUS_STABLE_TIMEOUT_MS 5000
+/**
+ * Sometimes, it needs to wait register value before going on.
+ * Eg, when switch to device mode, the vbus value should be lower
+ * than OTGSC_BSV before connects to host.
+ *
+ * @ci: the controller
+ *
+ * This function returns an error code if timeout
+ */
+static int hw_wait_otgsc_bsv(struct ci_hdrc *ci)
+{
+	unsigned long elapse = jiffies + msecs_to_jiffies(5000);
+	u32 mask = OTGSC_BSV;
+
+	while (!hw_read_otgsc(ci, mask)) {
+		if (time_after(jiffies, elapse)) {
+			dev_err(ci->dev, "timeout waiting for %08x in OTGSC\n",
+					mask);
+			return -ETIMEDOUT;
+		}
+		msleep(20);
+	}
+
+	return 0;
+}
+
 static void ci_handle_id_switch(struct ci_hdrc *ci)
 {
 	enum ci_role role = ci_otg_role(ci);
@@ -116,9 +141,11 @@ static void ci_handle_id_switch(struct ci_hdrc *ci)
 		ci_role_stop(ci);
 
 		if (role == CI_ROLE_GADGET)
-			/* wait vbus lower than OTGSC_BSV */
-			hw_wait_reg(ci, OP_OTGSC, OTGSC_BSV, 0,
-					CI_VBUS_STABLE_TIMEOUT_MS);
+			/*
+			 * wait vbus lower than OTGSC_BSV before connecting
+			 * to host
+			 */
+			hw_wait_otgsc_bsv(ci);
 
 		ci_role_start(ci, role);
 	}
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 04/21] usb: chipidea: Only read/write OTGSC from one place
@ 2016-06-26  7:28   ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb
  Cc: linux-arm-kernel, linux-kernel, linux-arm-msm, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Peter Chen, Greg Kroah-Hartman, Ivan T. Ivanov

With the id and vbus detection done via extcon we need to make
sure we poll the status of OTGSC properly by considering what the
extcon is saying, and not just what the register is saying. Let's
move this hw_wait_reg() function to the only place it's used and
simplify it for polling the OTGSC register. Then we can make
certain we only use the hw_read_otgsc() API to read OTGSC, which
will make sure we properly handle extcon events.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Ivan T. Ivanov" <iivanov.xz@gmail.com>
Fixes: 3ecb3e09b042 ("usb: chipidea: Use extcon framework for VBUS and ID detect")
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/core.c | 32 --------------------------------
 drivers/usb/chipidea/otg.c  | 35 +++++++++++++++++++++++++++++++----
 2 files changed, 31 insertions(+), 36 deletions(-)

diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 69426e644d17..01390e02ee53 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -516,38 +516,6 @@ int hw_device_reset(struct ci_hdrc *ci)
 	return 0;
 }
 
-/**
- * hw_wait_reg: wait the register value
- *
- * Sometimes, it needs to wait register value before going on.
- * Eg, when switch to device mode, the vbus value should be lower
- * than OTGSC_BSV before connects to host.
- *
- * @ci: the controller
- * @reg: register index
- * @mask: mast bit
- * @value: the bit value to wait
- * @timeout_ms: timeout in millisecond
- *
- * This function returns an error code if timeout
- */
-int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
-				u32 value, unsigned int timeout_ms)
-{
-	unsigned long elapse = jiffies + msecs_to_jiffies(timeout_ms);
-
-	while (hw_read(ci, reg, mask) != value) {
-		if (time_after(jiffies, elapse)) {
-			dev_err(ci->dev, "timeout waiting for %08x in %d\n",
-					mask, reg);
-			return -ETIMEDOUT;
-		}
-		msleep(20);
-	}
-
-	return 0;
-}
-
 static irqreturn_t ci_irq(int irq, void *data)
 {
 	struct ci_hdrc *ci = data;
diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
index 03b6743461d1..763a8332b009 100644
--- a/drivers/usb/chipidea/otg.c
+++ b/drivers/usb/chipidea/otg.c
@@ -104,7 +104,32 @@ void ci_handle_vbus_change(struct ci_hdrc *ci)
 		usb_gadget_vbus_disconnect(&ci->gadget);
 }
 
-#define CI_VBUS_STABLE_TIMEOUT_MS 5000
+/**
+ * Sometimes, it needs to wait register value before going on.
+ * Eg, when switch to device mode, the vbus value should be lower
+ * than OTGSC_BSV before connects to host.
+ *
+ * @ci: the controller
+ *
+ * This function returns an error code if timeout
+ */
+static int hw_wait_otgsc_bsv(struct ci_hdrc *ci)
+{
+	unsigned long elapse = jiffies + msecs_to_jiffies(5000);
+	u32 mask = OTGSC_BSV;
+
+	while (!hw_read_otgsc(ci, mask)) {
+		if (time_after(jiffies, elapse)) {
+			dev_err(ci->dev, "timeout waiting for %08x in OTGSC\n",
+					mask);
+			return -ETIMEDOUT;
+		}
+		msleep(20);
+	}
+
+	return 0;
+}
+
 static void ci_handle_id_switch(struct ci_hdrc *ci)
 {
 	enum ci_role role = ci_otg_role(ci);
@@ -116,9 +141,11 @@ static void ci_handle_id_switch(struct ci_hdrc *ci)
 		ci_role_stop(ci);
 
 		if (role == CI_ROLE_GADGET)
-			/* wait vbus lower than OTGSC_BSV */
-			hw_wait_reg(ci, OP_OTGSC, OTGSC_BSV, 0,
-					CI_VBUS_STABLE_TIMEOUT_MS);
+			/*
+			 * wait vbus lower than OTGSC_BSV before connecting
+			 * to host
+			 */
+			hw_wait_otgsc_bsv(ci);
 
 		ci_role_start(ci, role);
 	}
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 04/21] usb: chipidea: Only read/write OTGSC from one place
@ 2016-06-26  7:28   ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-arm-kernel

With the id and vbus detection done via extcon we need to make
sure we poll the status of OTGSC properly by considering what the
extcon is saying, and not just what the register is saying. Let's
move this hw_wait_reg() function to the only place it's used and
simplify it for polling the OTGSC register. Then we can make
certain we only use the hw_read_otgsc() API to read OTGSC, which
will make sure we properly handle extcon events.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Ivan T. Ivanov" <iivanov.xz@gmail.com>
Fixes: 3ecb3e09b042 ("usb: chipidea: Use extcon framework for VBUS and ID detect")
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/core.c | 32 --------------------------------
 drivers/usb/chipidea/otg.c  | 35 +++++++++++++++++++++++++++++++----
 2 files changed, 31 insertions(+), 36 deletions(-)

diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 69426e644d17..01390e02ee53 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -516,38 +516,6 @@ int hw_device_reset(struct ci_hdrc *ci)
 	return 0;
 }
 
-/**
- * hw_wait_reg: wait the register value
- *
- * Sometimes, it needs to wait register value before going on.
- * Eg, when switch to device mode, the vbus value should be lower
- * than OTGSC_BSV before connects to host.
- *
- * @ci: the controller
- * @reg: register index
- * @mask: mast bit
- * @value: the bit value to wait
- * @timeout_ms: timeout in millisecond
- *
- * This function returns an error code if timeout
- */
-int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
-				u32 value, unsigned int timeout_ms)
-{
-	unsigned long elapse = jiffies + msecs_to_jiffies(timeout_ms);
-
-	while (hw_read(ci, reg, mask) != value) {
-		if (time_after(jiffies, elapse)) {
-			dev_err(ci->dev, "timeout waiting for %08x in %d\n",
-					mask, reg);
-			return -ETIMEDOUT;
-		}
-		msleep(20);
-	}
-
-	return 0;
-}
-
 static irqreturn_t ci_irq(int irq, void *data)
 {
 	struct ci_hdrc *ci = data;
diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
index 03b6743461d1..763a8332b009 100644
--- a/drivers/usb/chipidea/otg.c
+++ b/drivers/usb/chipidea/otg.c
@@ -104,7 +104,32 @@ void ci_handle_vbus_change(struct ci_hdrc *ci)
 		usb_gadget_vbus_disconnect(&ci->gadget);
 }
 
-#define CI_VBUS_STABLE_TIMEOUT_MS 5000
+/**
+ * Sometimes, it needs to wait register value before going on.
+ * Eg, when switch to device mode, the vbus value should be lower
+ * than OTGSC_BSV before connects to host.
+ *
+ * @ci: the controller
+ *
+ * This function returns an error code if timeout
+ */
+static int hw_wait_otgsc_bsv(struct ci_hdrc *ci)
+{
+	unsigned long elapse = jiffies + msecs_to_jiffies(5000);
+	u32 mask = OTGSC_BSV;
+
+	while (!hw_read_otgsc(ci, mask)) {
+		if (time_after(jiffies, elapse)) {
+			dev_err(ci->dev, "timeout waiting for %08x in OTGSC\n",
+					mask);
+			return -ETIMEDOUT;
+		}
+		msleep(20);
+	}
+
+	return 0;
+}
+
 static void ci_handle_id_switch(struct ci_hdrc *ci)
 {
 	enum ci_role role = ci_otg_role(ci);
@@ -116,9 +141,11 @@ static void ci_handle_id_switch(struct ci_hdrc *ci)
 		ci_role_stop(ci);
 
 		if (role == CI_ROLE_GADGET)
-			/* wait vbus lower than OTGSC_BSV */
-			hw_wait_reg(ci, OP_OTGSC, OTGSC_BSV, 0,
-					CI_VBUS_STABLE_TIMEOUT_MS);
+			/*
+			 * wait vbus lower than OTGSC_BSV before connecting
+			 * to host
+			 */
+			hw_wait_otgsc_bsv(ci);
 
 		ci_role_start(ci, role);
 	}
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 05/21] usb: chipidea: Handle extcon events properly
  2016-06-26  7:28 ` Stephen Boyd
  (?)
@ 2016-06-26  7:28   ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb
  Cc: Felipe Balbi, Arnd Bergmann, Neil Armstrong, linux-arm-msm,
	linux-kernel, Bjorn Andersson, Peter Chen, Greg Kroah-Hartman,
	Andy Gross, Ivan T. Ivanov, linux-arm-kernel

We're currently emulating the vbus and id interrupts in the OTGSC
read API, but we also need to make sure that if we're handling
the events with extcon that we don't enable the interrupts for
those events in the hardware. Therefore, properly emulate this
register if we're using extcon, but don't enable the interrupts.
This allows me to get my cable connect/disconnect working
properly without getting spurious interrupts on my device that
uses an extcon for these two events.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Ivan T. Ivanov" <iivanov.xz@gmail.com>
Fixes: 3ecb3e09b042 ("usb: chipidea: Use extcon framework for VBUS and ID detect")
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/otg.c   | 46 +++++++++++++++++++++++++++++++++++++++-----
 include/linux/usb/chipidea.h |  2 ++
 2 files changed, 43 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
index 763a8332b009..b6a88bea4cac 100644
--- a/drivers/usb/chipidea/otg.c
+++ b/drivers/usb/chipidea/otg.c
@@ -44,12 +44,15 @@ u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask)
 		else
 			val &= ~OTGSC_BSVIS;
 
-		cable->changed = false;
-
 		if (cable->state)
 			val |= OTGSC_BSV;
 		else
 			val &= ~OTGSC_BSV;
+
+		if (cable->enabled)
+			val |= OTGSC_BSVIE;
+		else
+			val &= ~OTGSC_BSVIE;
 	}
 
 	cable = &ci->platdata->id_extcon;
@@ -59,15 +62,18 @@ u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask)
 		else
 			val &= ~OTGSC_IDIS;
 
-		cable->changed = false;
-
 		if (cable->state)
 			val |= OTGSC_ID;
 		else
 			val &= ~OTGSC_ID;
+
+		if (cable->enabled)
+			val |= OTGSC_IDIE;
+		else
+			val &= ~OTGSC_IDIE;
 	}
 
-	return val;
+	return val & mask;
 }
 
 /**
@@ -77,6 +83,36 @@ u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask)
  */
 void hw_write_otgsc(struct ci_hdrc *ci, u32 mask, u32 data)
 {
+	struct ci_hdrc_cable *cable;
+
+	cable = &ci->platdata->vbus_extcon;
+	if (!IS_ERR(cable->edev)) {
+		if (data & mask & OTGSC_BSVIS)
+			cable->changed = false;
+
+		/* Don't enable vbus interrupt if using external notifier */
+		if (data & mask & OTGSC_BSVIE) {
+			cable->enabled = true;
+			data &= ~OTGSC_BSVIE;
+		} else if (mask & OTGSC_BSVIE) {
+			cable->enabled = false;
+		}
+	}
+
+	cable = &ci->platdata->id_extcon;
+	if (!IS_ERR(cable->edev)) {
+		if (data & mask & OTGSC_IDIS)
+			cable->changed = false;
+
+		/* Don't enable id interrupt if using external notifier */
+		if (data & mask & OTGSC_IDIE) {
+			cable->enabled = true;
+			data &= ~OTGSC_IDIE;
+		} else if (mask & OTGSC_IDIE) {
+			cable->enabled = false;
+		}
+	}
+
 	hw_write(ci, OP_OTGSC, mask | OTGSC_INT_STATUS_BITS, data);
 }
 
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index 5dd75fa47dd8..f9be467d6695 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -14,6 +14,7 @@ struct ci_hdrc;
  * struct ci_hdrc_cable - structure for external connector cable state tracking
  * @state: current state of the line
  * @changed: set to true when extcon event happen
+ * @enabled: set to true if we've enabled the vbus or id interrupt
  * @edev: device which generate events
  * @ci: driver state of the chipidea device
  * @nb: hold event notification callback
@@ -22,6 +23,7 @@ struct ci_hdrc;
 struct ci_hdrc_cable {
 	bool				state;
 	bool				changed;
+	bool				enabled;
 	struct extcon_dev		*edev;
 	struct ci_hdrc			*ci;
 	struct notifier_block		nb;
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 05/21] usb: chipidea: Handle extcon events properly
@ 2016-06-26  7:28   ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb
  Cc: linux-arm-kernel, linux-kernel, linux-arm-msm, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Peter Chen, Greg Kroah-Hartman, Ivan T. Ivanov

We're currently emulating the vbus and id interrupts in the OTGSC
read API, but we also need to make sure that if we're handling
the events with extcon that we don't enable the interrupts for
those events in the hardware. Therefore, properly emulate this
register if we're using extcon, but don't enable the interrupts.
This allows me to get my cable connect/disconnect working
properly without getting spurious interrupts on my device that
uses an extcon for these two events.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Ivan T. Ivanov" <iivanov.xz@gmail.com>
Fixes: 3ecb3e09b042 ("usb: chipidea: Use extcon framework for VBUS and ID detect")
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/otg.c   | 46 +++++++++++++++++++++++++++++++++++++++-----
 include/linux/usb/chipidea.h |  2 ++
 2 files changed, 43 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
index 763a8332b009..b6a88bea4cac 100644
--- a/drivers/usb/chipidea/otg.c
+++ b/drivers/usb/chipidea/otg.c
@@ -44,12 +44,15 @@ u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask)
 		else
 			val &= ~OTGSC_BSVIS;
 
-		cable->changed = false;
-
 		if (cable->state)
 			val |= OTGSC_BSV;
 		else
 			val &= ~OTGSC_BSV;
+
+		if (cable->enabled)
+			val |= OTGSC_BSVIE;
+		else
+			val &= ~OTGSC_BSVIE;
 	}
 
 	cable = &ci->platdata->id_extcon;
@@ -59,15 +62,18 @@ u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask)
 		else
 			val &= ~OTGSC_IDIS;
 
-		cable->changed = false;
-
 		if (cable->state)
 			val |= OTGSC_ID;
 		else
 			val &= ~OTGSC_ID;
+
+		if (cable->enabled)
+			val |= OTGSC_IDIE;
+		else
+			val &= ~OTGSC_IDIE;
 	}
 
-	return val;
+	return val & mask;
 }
 
 /**
@@ -77,6 +83,36 @@ u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask)
  */
 void hw_write_otgsc(struct ci_hdrc *ci, u32 mask, u32 data)
 {
+	struct ci_hdrc_cable *cable;
+
+	cable = &ci->platdata->vbus_extcon;
+	if (!IS_ERR(cable->edev)) {
+		if (data & mask & OTGSC_BSVIS)
+			cable->changed = false;
+
+		/* Don't enable vbus interrupt if using external notifier */
+		if (data & mask & OTGSC_BSVIE) {
+			cable->enabled = true;
+			data &= ~OTGSC_BSVIE;
+		} else if (mask & OTGSC_BSVIE) {
+			cable->enabled = false;
+		}
+	}
+
+	cable = &ci->platdata->id_extcon;
+	if (!IS_ERR(cable->edev)) {
+		if (data & mask & OTGSC_IDIS)
+			cable->changed = false;
+
+		/* Don't enable id interrupt if using external notifier */
+		if (data & mask & OTGSC_IDIE) {
+			cable->enabled = true;
+			data &= ~OTGSC_IDIE;
+		} else if (mask & OTGSC_IDIE) {
+			cable->enabled = false;
+		}
+	}
+
 	hw_write(ci, OP_OTGSC, mask | OTGSC_INT_STATUS_BITS, data);
 }
 
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index 5dd75fa47dd8..f9be467d6695 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -14,6 +14,7 @@ struct ci_hdrc;
  * struct ci_hdrc_cable - structure for external connector cable state tracking
  * @state: current state of the line
  * @changed: set to true when extcon event happen
+ * @enabled: set to true if we've enabled the vbus or id interrupt
  * @edev: device which generate events
  * @ci: driver state of the chipidea device
  * @nb: hold event notification callback
@@ -22,6 +23,7 @@ struct ci_hdrc;
 struct ci_hdrc_cable {
 	bool				state;
 	bool				changed;
+	bool				enabled;
 	struct extcon_dev		*edev;
 	struct ci_hdrc			*ci;
 	struct notifier_block		nb;
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 05/21] usb: chipidea: Handle extcon events properly
@ 2016-06-26  7:28   ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-arm-kernel

We're currently emulating the vbus and id interrupts in the OTGSC
read API, but we also need to make sure that if we're handling
the events with extcon that we don't enable the interrupts for
those events in the hardware. Therefore, properly emulate this
register if we're using extcon, but don't enable the interrupts.
This allows me to get my cable connect/disconnect working
properly without getting spurious interrupts on my device that
uses an extcon for these two events.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Ivan T. Ivanov" <iivanov.xz@gmail.com>
Fixes: 3ecb3e09b042 ("usb: chipidea: Use extcon framework for VBUS and ID detect")
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/otg.c   | 46 +++++++++++++++++++++++++++++++++++++++-----
 include/linux/usb/chipidea.h |  2 ++
 2 files changed, 43 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
index 763a8332b009..b6a88bea4cac 100644
--- a/drivers/usb/chipidea/otg.c
+++ b/drivers/usb/chipidea/otg.c
@@ -44,12 +44,15 @@ u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask)
 		else
 			val &= ~OTGSC_BSVIS;
 
-		cable->changed = false;
-
 		if (cable->state)
 			val |= OTGSC_BSV;
 		else
 			val &= ~OTGSC_BSV;
+
+		if (cable->enabled)
+			val |= OTGSC_BSVIE;
+		else
+			val &= ~OTGSC_BSVIE;
 	}
 
 	cable = &ci->platdata->id_extcon;
@@ -59,15 +62,18 @@ u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask)
 		else
 			val &= ~OTGSC_IDIS;
 
-		cable->changed = false;
-
 		if (cable->state)
 			val |= OTGSC_ID;
 		else
 			val &= ~OTGSC_ID;
+
+		if (cable->enabled)
+			val |= OTGSC_IDIE;
+		else
+			val &= ~OTGSC_IDIE;
 	}
 
-	return val;
+	return val & mask;
 }
 
 /**
@@ -77,6 +83,36 @@ u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask)
  */
 void hw_write_otgsc(struct ci_hdrc *ci, u32 mask, u32 data)
 {
+	struct ci_hdrc_cable *cable;
+
+	cable = &ci->platdata->vbus_extcon;
+	if (!IS_ERR(cable->edev)) {
+		if (data & mask & OTGSC_BSVIS)
+			cable->changed = false;
+
+		/* Don't enable vbus interrupt if using external notifier */
+		if (data & mask & OTGSC_BSVIE) {
+			cable->enabled = true;
+			data &= ~OTGSC_BSVIE;
+		} else if (mask & OTGSC_BSVIE) {
+			cable->enabled = false;
+		}
+	}
+
+	cable = &ci->platdata->id_extcon;
+	if (!IS_ERR(cable->edev)) {
+		if (data & mask & OTGSC_IDIS)
+			cable->changed = false;
+
+		/* Don't enable id interrupt if using external notifier */
+		if (data & mask & OTGSC_IDIE) {
+			cable->enabled = true;
+			data &= ~OTGSC_IDIE;
+		} else if (mask & OTGSC_IDIE) {
+			cable->enabled = false;
+		}
+	}
+
 	hw_write(ci, OP_OTGSC, mask | OTGSC_INT_STATUS_BITS, data);
 }
 
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index 5dd75fa47dd8..f9be467d6695 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -14,6 +14,7 @@ struct ci_hdrc;
  * struct ci_hdrc_cable - structure for external connector cable state tracking
  * @state: current state of the line
  * @changed: set to true when extcon event happen
+ * @enabled: set to true if we've enabled the vbus or id interrupt
  * @edev: device which generate events
  * @ci: driver state of the chipidea device
  * @nb: hold event notification callback
@@ -22,6 +23,7 @@ struct ci_hdrc;
 struct ci_hdrc_cable {
 	bool				state;
 	bool				changed;
+	bool				enabled;
 	struct extcon_dev		*edev;
 	struct ci_hdrc			*ci;
 	struct notifier_block		nb;
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 06/21] usb: chipidea: Initialize and reinitialize phy later
  2016-06-26  7:28 ` Stephen Boyd
@ 2016-06-26  7:28   ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb
  Cc: linux-arm-kernel, linux-kernel, linux-arm-msm, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Peter Chen, Greg Kroah-Hartman

The ULPI phy on qcom platforms needs to be initialized and
powered on after a USB reset and before we toggle the run/stop
bit. Otherwise, the phy locks up and doesn't work properly. Move
the phy initialization to a later point, and shut it down outside
of driver remove so that the phy state is properly managed across
role switches.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/ci.h   |  3 ++-
 drivers/usb/chipidea/core.c | 23 ++++++++++-------------
 drivers/usb/chipidea/host.c |  5 ++---
 drivers/usb/chipidea/udc.c  |  2 ++
 4 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index cd414559040f..f87805235caa 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -431,7 +431,8 @@ u8 hw_port_test_get(struct ci_hdrc *ci);
 int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
 				u32 value, unsigned int timeout_ms);
 
-void ci_platform_configure(struct ci_hdrc *ci);
+void ci_usb_phy_exit(struct ci_hdrc *ci);
+int ci_platform_configure(struct ci_hdrc *ci);
 
 int dbg_create_files(struct ci_hdrc *ci);
 
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 01390e02ee53..a01611c7f815 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -359,7 +359,7 @@ static int _ci_usb_phy_init(struct ci_hdrc *ci)
  * interfaces
  * @ci: the controller
  */
-static void ci_usb_phy_exit(struct ci_hdrc *ci)
+void ci_usb_phy_exit(struct ci_hdrc *ci)
 {
 	if (ci->phy) {
 		phy_power_off(ci->phy);
@@ -412,9 +412,14 @@ static int ci_usb_phy_init(struct ci_hdrc *ci)
  * @ci: the controller
  *
  */
-void ci_platform_configure(struct ci_hdrc *ci)
+int ci_platform_configure(struct ci_hdrc *ci)
 {
 	bool is_device_mode, is_host_mode;
+	int ret;
+
+	ret = ci_usb_phy_init(ci);
+	if (ret)
+		return ret;
 
 	is_device_mode = hw_read(ci, OP_USBMODE, USBMODE_CM) == USBMODE_CM_DC;
 	is_host_mode = hw_read(ci, OP_USBMODE, USBMODE_CM) == USBMODE_CM_HC;
@@ -453,6 +458,8 @@ void ci_platform_configure(struct ci_hdrc *ci)
 			hw_write(ci, OP_BURSTSIZE, RX_BURST_MASK,
 				ci->platdata->rx_burst_size);
 	}
+
+	return 0;
 }
 
 /**
@@ -511,9 +518,7 @@ int hw_device_reset(struct ci_hdrc *ci)
 		return -ENODEV;
 	}
 
-	ci_platform_configure(ci);
-
-	return 0;
+	return ci_platform_configure(ci);
 }
 
 static irqreturn_t ci_irq(int irq, void *data)
@@ -917,12 +922,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 			ci->usb_phy = NULL;
 	}
 
-	ret = ci_usb_phy_init(ci);
-	if (ret) {
-		dev_err(dev, "unable to init phy: %d\n", ret);
-		return ret;
-	}
-
 	ci->hw_bank.phys = res->start;
 
 	ci->irq = platform_get_irq(pdev, 0);
@@ -1025,7 +1024,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 stop:
 	ci_role_destroy(ci);
 deinit_phy:
-	ci_usb_phy_exit(ci);
 
 	return ret;
 }
@@ -1044,7 +1042,6 @@ static int ci_hdrc_remove(struct platform_device *pdev)
 	ci_extcon_unregister(ci);
 	ci_role_destroy(ci);
 	ci_hdrc_enter_lpm(ci, true);
-	ci_usb_phy_exit(ci);
 
 	return 0;
 }
diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
index 053bac9d983c..523c155daea8 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -87,9 +87,7 @@ static int ehci_ci_reset(struct usb_hcd *hcd)
 	if (ret)
 		return ret;
 
-	ci_platform_configure(ci);
-
-	return ret;
+	return ci_platform_configure(ci);
 }
 
 static const struct ehci_driver_overrides ehci_ci_overrides = {
@@ -186,6 +184,7 @@ static void host_stop(struct ci_hdrc *ci)
 	if (hcd) {
 		usb_remove_hcd(hcd);
 		usb_put_hcd(hcd);
+		ci_usb_phy_exit(ci);
 		if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci) &&
 			(ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON))
 				regulator_disable(ci->platdata->reg_vbus);
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 065f5d97aa67..8f44e2d1e0c0 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1534,6 +1534,7 @@ static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active)
 			if (ci->driver)
 				ci->driver->disconnect(&ci->gadget);
 			hw_device_state(ci, 0);
+			ci_usb_phy_exit(ci);
 			if (ci->platdata->notify_event)
 				ci->platdata->notify_event(ci,
 				CI_HDRC_CONTROLLER_STOPPED_EVENT);
@@ -1794,6 +1795,7 @@ static int ci_udc_stop(struct usb_gadget *gadget)
 			ci->platdata->notify_event(ci,
 			CI_HDRC_CONTROLLER_STOPPED_EVENT);
 		spin_unlock_irqrestore(&ci->lock, flags);
+		ci_usb_phy_exit(ci);
 		_gadget_stop_activity(&ci->gadget);
 		spin_lock_irqsave(&ci->lock, flags);
 		pm_runtime_put(&ci->gadget.dev);
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 06/21] usb: chipidea: Initialize and reinitialize phy later
@ 2016-06-26  7:28   ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-arm-kernel

The ULPI phy on qcom platforms needs to be initialized and
powered on after a USB reset and before we toggle the run/stop
bit. Otherwise, the phy locks up and doesn't work properly. Move
the phy initialization to a later point, and shut it down outside
of driver remove so that the phy state is properly managed across
role switches.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/ci.h   |  3 ++-
 drivers/usb/chipidea/core.c | 23 ++++++++++-------------
 drivers/usb/chipidea/host.c |  5 ++---
 drivers/usb/chipidea/udc.c  |  2 ++
 4 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index cd414559040f..f87805235caa 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -431,7 +431,8 @@ u8 hw_port_test_get(struct ci_hdrc *ci);
 int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
 				u32 value, unsigned int timeout_ms);
 
-void ci_platform_configure(struct ci_hdrc *ci);
+void ci_usb_phy_exit(struct ci_hdrc *ci);
+int ci_platform_configure(struct ci_hdrc *ci);
 
 int dbg_create_files(struct ci_hdrc *ci);
 
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 01390e02ee53..a01611c7f815 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -359,7 +359,7 @@ static int _ci_usb_phy_init(struct ci_hdrc *ci)
  * interfaces
  * @ci: the controller
  */
-static void ci_usb_phy_exit(struct ci_hdrc *ci)
+void ci_usb_phy_exit(struct ci_hdrc *ci)
 {
 	if (ci->phy) {
 		phy_power_off(ci->phy);
@@ -412,9 +412,14 @@ static int ci_usb_phy_init(struct ci_hdrc *ci)
  * @ci: the controller
  *
  */
-void ci_platform_configure(struct ci_hdrc *ci)
+int ci_platform_configure(struct ci_hdrc *ci)
 {
 	bool is_device_mode, is_host_mode;
+	int ret;
+
+	ret = ci_usb_phy_init(ci);
+	if (ret)
+		return ret;
 
 	is_device_mode = hw_read(ci, OP_USBMODE, USBMODE_CM) == USBMODE_CM_DC;
 	is_host_mode = hw_read(ci, OP_USBMODE, USBMODE_CM) == USBMODE_CM_HC;
@@ -453,6 +458,8 @@ void ci_platform_configure(struct ci_hdrc *ci)
 			hw_write(ci, OP_BURSTSIZE, RX_BURST_MASK,
 				ci->platdata->rx_burst_size);
 	}
+
+	return 0;
 }
 
 /**
@@ -511,9 +518,7 @@ int hw_device_reset(struct ci_hdrc *ci)
 		return -ENODEV;
 	}
 
-	ci_platform_configure(ci);
-
-	return 0;
+	return ci_platform_configure(ci);
 }
 
 static irqreturn_t ci_irq(int irq, void *data)
@@ -917,12 +922,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 			ci->usb_phy = NULL;
 	}
 
-	ret = ci_usb_phy_init(ci);
-	if (ret) {
-		dev_err(dev, "unable to init phy: %d\n", ret);
-		return ret;
-	}
-
 	ci->hw_bank.phys = res->start;
 
 	ci->irq = platform_get_irq(pdev, 0);
@@ -1025,7 +1024,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 stop:
 	ci_role_destroy(ci);
 deinit_phy:
-	ci_usb_phy_exit(ci);
 
 	return ret;
 }
@@ -1044,7 +1042,6 @@ static int ci_hdrc_remove(struct platform_device *pdev)
 	ci_extcon_unregister(ci);
 	ci_role_destroy(ci);
 	ci_hdrc_enter_lpm(ci, true);
-	ci_usb_phy_exit(ci);
 
 	return 0;
 }
diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
index 053bac9d983c..523c155daea8 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -87,9 +87,7 @@ static int ehci_ci_reset(struct usb_hcd *hcd)
 	if (ret)
 		return ret;
 
-	ci_platform_configure(ci);
-
-	return ret;
+	return ci_platform_configure(ci);
 }
 
 static const struct ehci_driver_overrides ehci_ci_overrides = {
@@ -186,6 +184,7 @@ static void host_stop(struct ci_hdrc *ci)
 	if (hcd) {
 		usb_remove_hcd(hcd);
 		usb_put_hcd(hcd);
+		ci_usb_phy_exit(ci);
 		if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci) &&
 			(ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON))
 				regulator_disable(ci->platdata->reg_vbus);
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 065f5d97aa67..8f44e2d1e0c0 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1534,6 +1534,7 @@ static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active)
 			if (ci->driver)
 				ci->driver->disconnect(&ci->gadget);
 			hw_device_state(ci, 0);
+			ci_usb_phy_exit(ci);
 			if (ci->platdata->notify_event)
 				ci->platdata->notify_event(ci,
 				CI_HDRC_CONTROLLER_STOPPED_EVENT);
@@ -1794,6 +1795,7 @@ static int ci_udc_stop(struct usb_gadget *gadget)
 			ci->platdata->notify_event(ci,
 			CI_HDRC_CONTROLLER_STOPPED_EVENT);
 		spin_unlock_irqrestore(&ci->lock, flags);
+		ci_usb_phy_exit(ci);
 		_gadget_stop_activity(&ci->gadget);
 		spin_lock_irqsave(&ci->lock, flags);
 		pm_runtime_put(&ci->gadget.dev);
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 07/21] usb: chipidea: Notify of reset when switching into host mode
  2016-06-26  7:28 ` Stephen Boyd
  (?)
@ 2016-06-26  7:28   ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb
  Cc: Felipe Balbi, Arnd Bergmann, Neil Armstrong, linux-arm-msm,
	linux-kernel, Bjorn Andersson, Peter Chen, Greg Kroah-Hartman,
	Andy Gross, linux-arm-kernel

The chipidea/udc.c file sends a CI_HDRC_CONTROLLER_RESET_EVENT to
the wrapper drivers when it calls hw_device_reset(), but that
function is not called from chipidea/host.c. The intent of this
event is to allow the wrapper driver to do any wrapper specific
things after the reset bit has been set in the usb command
register. Therefore, add this event hook in the host role after
we toggle that bit.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/host.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
index 523c155daea8..3344d3256a60 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -87,6 +87,9 @@ static int ehci_ci_reset(struct usb_hcd *hcd)
 	if (ret)
 		return ret;
 
+	if (ci->platdata->notify_event)
+		ci->platdata->notify_event(ci, CI_HDRC_CONTROLLER_RESET_EVENT);
+
 	return ci_platform_configure(ci);
 }
 
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 07/21] usb: chipidea: Notify of reset when switching into host mode
@ 2016-06-26  7:28   ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb
  Cc: linux-arm-kernel, linux-kernel, linux-arm-msm, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Peter Chen, Greg Kroah-Hartman

The chipidea/udc.c file sends a CI_HDRC_CONTROLLER_RESET_EVENT to
the wrapper drivers when it calls hw_device_reset(), but that
function is not called from chipidea/host.c. The intent of this
event is to allow the wrapper driver to do any wrapper specific
things after the reset bit has been set in the usb command
register. Therefore, add this event hook in the host role after
we toggle that bit.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/host.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
index 523c155daea8..3344d3256a60 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -87,6 +87,9 @@ static int ehci_ci_reset(struct usb_hcd *hcd)
 	if (ret)
 		return ret;
 
+	if (ci->platdata->notify_event)
+		ci->platdata->notify_event(ci, CI_HDRC_CONTROLLER_RESET_EVENT);
+
 	return ci_platform_configure(ci);
 }
 
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 07/21] usb: chipidea: Notify of reset when switching into host mode
@ 2016-06-26  7:28   ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-arm-kernel

The chipidea/udc.c file sends a CI_HDRC_CONTROLLER_RESET_EVENT to
the wrapper drivers when it calls hw_device_reset(), but that
function is not called from chipidea/host.c. The intent of this
event is to allow the wrapper driver to do any wrapper specific
things after the reset bit has been set in the usb command
register. Therefore, add this event hook in the host role after
we toggle that bit.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/host.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
index 523c155daea8..3344d3256a60 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -87,6 +87,9 @@ static int ehci_ci_reset(struct usb_hcd *hcd)
 	if (ret)
 		return ret;
 
+	if (ci->platdata->notify_event)
+		ci->platdata->notify_event(ci, CI_HDRC_CONTROLLER_RESET_EVENT);
+
 	return ci_platform_configure(ci);
 }
 
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 08/21] usb: chipidea: Kick OTG state machine for AVVIS with vbus extcon
  2016-06-26  7:28 ` Stephen Boyd
@ 2016-06-26  7:28   ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb
  Cc: linux-arm-kernel, linux-kernel, linux-arm-msm, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Peter Chen, Greg Kroah-Hartman

Force the OTG state machine to go forward when we're using an
extcon for vbus detection. In this case, the controller may never
raise an interrupt for AVVIS, so we need to simulate the event by
toggling the appropriate OTG fsm bits and kicking the state
machine again.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/otg_fsm.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c
index de8e22ec3902..aab076fc4d82 100644
--- a/drivers/usb/chipidea/otg_fsm.c
+++ b/drivers/usb/chipidea/otg_fsm.c
@@ -475,6 +475,14 @@ static void ci_otg_drv_vbus(struct otg_fsm *fsm, int on)
 				return;
 			}
 		}
+		/*
+		 * Force state machine forward if we use extcon
+		 * to detect vbus state (i.e. simulate AVVIS event)
+		 */
+		if (!IS_ERR(ci->platdata->vbus_extcon.edev)) {
+			fsm->a_vbus_vld = 1;
+			ci_otg_queue_work(ci);
+		}
 		/* Disable data pulse irq */
 		hw_write_otgsc(ci, OTGSC_DPIE, 0);
 
@@ -486,6 +494,15 @@ static void ci_otg_drv_vbus(struct otg_fsm *fsm, int on)
 
 		fsm->a_bus_drop = 1;
 		fsm->a_bus_req = 0;
+		/*
+		 * Force state machine forward if we use extcon
+		 * to detect vbus state (i.e. simulate AVVIS event)
+		 */
+		if (!IS_ERR(ci->platdata->vbus_extcon.edev)) {
+			fsm->a_vbus_vld = 0;
+			fsm->b_conn = 0;
+			ci_otg_queue_work(ci);
+		}
 	}
 }
 
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 08/21] usb: chipidea: Kick OTG state machine for AVVIS with vbus extcon
@ 2016-06-26  7:28   ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-arm-kernel

Force the OTG state machine to go forward when we're using an
extcon for vbus detection. In this case, the controller may never
raise an interrupt for AVVIS, so we need to simulate the event by
toggling the appropriate OTG fsm bits and kicking the state
machine again.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/otg_fsm.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c
index de8e22ec3902..aab076fc4d82 100644
--- a/drivers/usb/chipidea/otg_fsm.c
+++ b/drivers/usb/chipidea/otg_fsm.c
@@ -475,6 +475,14 @@ static void ci_otg_drv_vbus(struct otg_fsm *fsm, int on)
 				return;
 			}
 		}
+		/*
+		 * Force state machine forward if we use extcon
+		 * to detect vbus state (i.e. simulate AVVIS event)
+		 */
+		if (!IS_ERR(ci->platdata->vbus_extcon.edev)) {
+			fsm->a_vbus_vld = 1;
+			ci_otg_queue_work(ci);
+		}
 		/* Disable data pulse irq */
 		hw_write_otgsc(ci, OTGSC_DPIE, 0);
 
@@ -486,6 +494,15 @@ static void ci_otg_drv_vbus(struct otg_fsm *fsm, int on)
 
 		fsm->a_bus_drop = 1;
 		fsm->a_bus_req = 0;
+		/*
+		 * Force state machine forward if we use extcon
+		 * to detect vbus state (i.e. simulate AVVIS event)
+		 */
+		if (!IS_ERR(ci->platdata->vbus_extcon.edev)) {
+			fsm->a_vbus_vld = 0;
+			fsm->b_conn = 0;
+			ci_otg_queue_work(ci);
+		}
 	}
 }
 
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 09/21] usb: chipidea: Add support for ULPI PHY bus
  2016-06-26  7:28 ` Stephen Boyd
@ 2016-06-26  7:28   ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb
  Cc: linux-arm-kernel, linux-kernel, linux-arm-msm, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Peter Chen, Greg Kroah-Hartman, Heikki Krogerus

Some phys for the chipidea controller are controlled via the ULPI
viewport. Add support for the ULPI bus so that these sorts of
phys can be probed and read/written automatically without having
to duplicate the viewport logic in each phy driver.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/Kconfig  |   7 +++
 drivers/usb/chipidea/Makefile |   1 +
 drivers/usb/chipidea/ci.h     |  20 ++++++++
 drivers/usb/chipidea/core.c   |  30 ++++++++---
 drivers/usb/chipidea/ulpi.c   | 113 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 165 insertions(+), 6 deletions(-)
 create mode 100644 drivers/usb/chipidea/ulpi.c

diff --git a/drivers/usb/chipidea/Kconfig b/drivers/usb/chipidea/Kconfig
index 3644a3500b70..4f8c342a8865 100644
--- a/drivers/usb/chipidea/Kconfig
+++ b/drivers/usb/chipidea/Kconfig
@@ -37,4 +37,11 @@ config USB_CHIPIDEA_HOST
 	  Say Y here to enable host controller functionality of the
 	  ChipIdea driver.
 
+config USB_CHIPIDEA_ULPI
+	bool "ChipIdea ULPI PHY support"
+	depends on USB_ULPI_BUS=y || USB_ULPI_BUS=USB_CHIPIDEA
+	help
+	  Say Y here if you have a ULPI PHY attached to your ChipIdea
+	  controller.
+
 endif
diff --git a/drivers/usb/chipidea/Makefile b/drivers/usb/chipidea/Makefile
index 518e445476c3..39fca5715ed3 100644
--- a/drivers/usb/chipidea/Makefile
+++ b/drivers/usb/chipidea/Makefile
@@ -4,6 +4,7 @@ ci_hdrc-y				:= core.o otg.o debug.o
 ci_hdrc-$(CONFIG_USB_CHIPIDEA_UDC)	+= udc.o
 ci_hdrc-$(CONFIG_USB_CHIPIDEA_HOST)	+= host.o
 ci_hdrc-$(CONFIG_USB_OTG_FSM)		+= otg_fsm.o
+ci_hdrc-$(CONFIG_USB_CHIPIDEA_ULPI)	+= ulpi.o
 
 # Glue/Bridge layers go here
 
diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index f87805235caa..14aa20525547 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -18,6 +18,8 @@
 #include <linux/usb.h>
 #include <linux/usb/gadget.h>
 #include <linux/usb/otg-fsm.h>
+#include <linux/usb/otg.h>
+#include <linux/ulpi/interface.h>
 
 /******************************************************************************
  * DEFINE
@@ -52,6 +54,7 @@ enum ci_hw_regs {
 	OP_ENDPTLISTADDR,
 	OP_TTCTRL,
 	OP_BURSTSIZE,
+	OP_ULPI_VIEWPORT,
 	OP_PORTSC,
 	OP_DEVLC,
 	OP_OTGSC,
@@ -187,6 +190,7 @@ struct hw_bank {
  * @test_mode: the selected test mode
  * @platdata: platform specific information supplied by parent device
  * @vbus_active: is VBUS active
+ * @ulpi: pointer to ULPI device, if any
  * @phy: pointer to PHY, if any
  * @usb_phy: pointer to USB PHY, if any and if using the USB PHY framework
  * @hcd: pointer to usb_hcd for ehci host driver
@@ -236,6 +240,10 @@ struct ci_hdrc {
 
 	struct ci_hdrc_platform_data	*platdata;
 	int				vbus_active;
+#ifdef CONFIG_USB_CHIPIDEA_ULPI
+	struct ulpi			*ulpi;
+	struct ulpi_ops 		ulpi_ops;
+#endif
 	struct phy			*phy;
 	/* old usb_phy interface */
 	struct usb_phy			*usb_phy;
@@ -418,6 +426,17 @@ static inline bool ci_otg_is_fsm_mode(struct ci_hdrc *ci)
 #endif
 }
 
+#if IS_ENABLED(CONFIG_USB_CHIPIDEA_ULPI)
+int ci_ulpi_init(struct ci_hdrc *ci);
+void ci_ulpi_exit(struct ci_hdrc *ci);
+int ci_ulpi_resume(struct ci_hdrc *ci);
+#else
+static inline int ci_ulpi_init(struct ci_hdrc *ci) { return 0; }
+static inline void ci_ulpi_exit(struct ci_hdrc *ci) { }
+static inline int ci_ulpi_resume(struct ci_hdrc *ci) { return 0; }
+#endif
+
+
 u32 hw_read_intr_enable(struct ci_hdrc *ci);
 
 u32 hw_read_intr_status(struct ci_hdrc *ci);
@@ -432,6 +451,7 @@ int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
 				u32 value, unsigned int timeout_ms);
 
 void ci_usb_phy_exit(struct ci_hdrc *ci);
+void hw_phymode_configure(struct ci_hdrc *ci);
 int ci_platform_configure(struct ci_hdrc *ci);
 
 int dbg_create_files(struct ci_hdrc *ci);
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index a01611c7f815..ea84fc0a03a6 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -86,6 +86,7 @@ static const u8 ci_regs_nolpm[] = {
 	[OP_ENDPTLISTADDR]	= 0x18U,
 	[OP_TTCTRL]		= 0x1CU,
 	[OP_BURSTSIZE]		= 0x20U,
+	[OP_ULPI_VIEWPORT]	= 0x30U,
 	[OP_PORTSC]		= 0x44U,
 	[OP_DEVLC]		= 0x84U,
 	[OP_OTGSC]		= 0x64U,
@@ -110,6 +111,7 @@ static const u8 ci_regs_lpm[] = {
 	[OP_ENDPTLISTADDR]	= 0x18U,
 	[OP_TTCTRL]		= 0x1CU,
 	[OP_BURSTSIZE]		= 0x20U,
+	[OP_ULPI_VIEWPORT]	= 0x30U,
 	[OP_PORTSC]		= 0x44U,
 	[OP_DEVLC]		= 0x84U,
 	[OP_OTGSC]		= 0xC4U,
@@ -285,7 +287,7 @@ static int hw_device_init(struct ci_hdrc *ci, void __iomem *base)
 	return 0;
 }
 
-static void hw_phymode_configure(struct ci_hdrc *ci)
+void hw_phymode_configure(struct ci_hdrc *ci)
 {
 	u32 portsc, lpm, sts = 0;
 
@@ -893,6 +895,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 		CI_HDRC_IMX28_WRITE_FIX);
 	ci->supports_runtime_pm = !!(ci->platdata->flags &
 		CI_HDRC_SUPPORTS_RUNTIME_PM);
+	platform_set_drvdata(pdev, ci);
 
 	ret = hw_device_init(ci, base);
 	if (ret < 0) {
@@ -900,6 +903,10 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
+	ret = ci_ulpi_init(ci);
+	if (ret)
+		return ret;
+
 	if (ci->platdata->phy) {
 		ci->phy = ci->platdata->phy;
 	} else if (ci->platdata->usb_phy) {
@@ -910,11 +917,15 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 
 		/* if both generic PHY and USB PHY layers aren't enabled */
 		if (PTR_ERR(ci->phy) == -ENOSYS &&
-				PTR_ERR(ci->usb_phy) == -ENXIO)
-			return -ENXIO;
+				PTR_ERR(ci->usb_phy) == -ENXIO) {
+			ret = -ENXIO;
+			goto deinit_phy;
+		}
 
-		if (IS_ERR(ci->phy) && IS_ERR(ci->usb_phy))
-			return -EPROBE_DEFER;
+		if (IS_ERR(ci->phy) && IS_ERR(ci->usb_phy)) {
+			ret = -EPROBE_DEFER;
+			goto deinit_phy;
+		}
 
 		if (IS_ERR(ci->phy))
 			ci->phy = NULL;
@@ -993,7 +1004,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 		}
 	}
 
-	platform_set_drvdata(pdev, ci);
 	ret = devm_request_irq(dev, ci->irq, ci_irq, IRQF_SHARED,
 			ci->platdata->name, ci);
 	if (ret)
@@ -1024,6 +1034,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 stop:
 	ci_role_destroy(ci);
 deinit_phy:
+	ci_ulpi_exit(ci);
 
 	return ret;
 }
@@ -1042,6 +1053,7 @@ static int ci_hdrc_remove(struct platform_device *pdev)
 	ci_extcon_unregister(ci);
 	ci_role_destroy(ci);
 	ci_hdrc_enter_lpm(ci, true);
+	ci_ulpi_exit(ci);
 
 	return 0;
 }
@@ -1089,6 +1101,7 @@ static void ci_controller_suspend(struct ci_hdrc *ci)
 static int ci_controller_resume(struct device *dev)
 {
 	struct ci_hdrc *ci = dev_get_drvdata(dev);
+	int ret;
 
 	dev_dbg(dev, "at %s\n", __func__);
 
@@ -1098,6 +1111,11 @@ static int ci_controller_resume(struct device *dev)
 	}
 
 	ci_hdrc_enter_lpm(ci, false);
+
+	ret = ci_ulpi_resume(ci);
+	if (ret)
+		return ret;
+
 	if (ci->usb_phy) {
 		usb_phy_set_suspend(ci->usb_phy, 0);
 		usb_phy_set_wakeup(ci->usb_phy, false);
diff --git a/drivers/usb/chipidea/ulpi.c b/drivers/usb/chipidea/ulpi.c
new file mode 100644
index 000000000000..3962255ff687
--- /dev/null
+++ b/drivers/usb/chipidea/ulpi.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2016 Linaro Ltd.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/device.h>
+#include <linux/usb/chipidea.h>
+#include <linux/ulpi/interface.h>
+
+#include "ci.h"
+
+#define ULPI_WAKEUP		BIT(31)
+#define ULPI_RUN		BIT(30)
+#define ULPI_WRITE		BIT(29)
+#define ULPI_SYNC_STATE		BIT(27)
+#define ULPI_ADDR(n)		((n) << 16)
+#define ULPI_DATA(n)		(n)
+
+static int ci_ulpi_wait(struct ci_hdrc *ci, u32 mask)
+{
+	unsigned long usec = 10000;
+
+	while (usec--) {
+		if (!hw_read(ci, OP_ULPI_VIEWPORT, mask))
+			return 0;
+
+		udelay(1);
+	}
+
+	return -ETIMEDOUT;
+}
+
+static int ci_ulpi_read(struct ulpi_ops *ops, u8 addr)
+{
+	struct ci_hdrc *ci = dev_get_drvdata(ops->dev);
+	int ret;
+
+	hw_write(ci, OP_ULPI_VIEWPORT, 0xffffffff, ULPI_WRITE | ULPI_WAKEUP);
+	ret = ci_ulpi_wait(ci, ULPI_WAKEUP);
+	if (ret)
+		return ret;
+
+	hw_write(ci, OP_ULPI_VIEWPORT, 0xffffffff, ULPI_RUN | ULPI_ADDR(addr));
+	ret = ci_ulpi_wait(ci, ULPI_RUN);
+	if (ret)
+		return ret;
+
+	return hw_read(ci, OP_ULPI_VIEWPORT, GENMASK(15, 8)) >> 8;
+}
+
+static int ci_ulpi_write(struct ulpi_ops *ops, u8 addr, u8 val)
+{
+	struct ci_hdrc *ci = dev_get_drvdata(ops->dev);
+	int ret;
+
+	hw_write(ci, OP_ULPI_VIEWPORT, 0xffffffff, ULPI_WRITE | ULPI_WAKEUP);
+	ret = ci_ulpi_wait(ci, ULPI_WAKEUP);
+	if (ret)
+		return ret;
+
+	hw_write(ci, OP_ULPI_VIEWPORT, 0xffffffff,
+		 ULPI_RUN | ULPI_WRITE | ULPI_ADDR(addr) | val);
+	return ci_ulpi_wait(ci, ULPI_RUN);
+}
+
+int ci_ulpi_init(struct ci_hdrc *ci)
+{
+	if (ci->platdata->phy_mode != USBPHY_INTERFACE_MODE_ULPI)
+		return 0;
+
+	/*
+	 * Set PORTSC correctly so we can read/write ULPI registers for
+	 * identification purposes
+	 */
+	hw_phymode_configure(ci);
+
+	ci->ulpi_ops.read = ci_ulpi_read;
+	ci->ulpi_ops.write = ci_ulpi_write;
+	ci->ulpi = ulpi_register_interface(ci->dev, &ci->ulpi_ops);
+	if (IS_ERR(ci->ulpi))
+		dev_err(ci->dev, "failed to register ULPI interface");
+
+	return PTR_ERR_OR_ZERO(ci->ulpi);
+}
+
+void ci_ulpi_exit(struct ci_hdrc *ci)
+{
+	if (ci->ulpi) {
+		ulpi_unregister_interface(ci->ulpi);
+		ci->ulpi = NULL;
+	}
+}
+
+int ci_ulpi_resume(struct ci_hdrc *ci)
+{
+	int cnt = 100000;
+
+	while (cnt-- > 0) {
+		if (hw_read(ci, OP_ULPI_VIEWPORT, ULPI_SYNC_STATE))
+			return 0;
+		udelay(1);
+	}
+
+	return -ETIMEDOUT;
+}
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 09/21] usb: chipidea: Add support for ULPI PHY bus
@ 2016-06-26  7:28   ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-arm-kernel

Some phys for the chipidea controller are controlled via the ULPI
viewport. Add support for the ULPI bus so that these sorts of
phys can be probed and read/written automatically without having
to duplicate the viewport logic in each phy driver.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/Kconfig  |   7 +++
 drivers/usb/chipidea/Makefile |   1 +
 drivers/usb/chipidea/ci.h     |  20 ++++++++
 drivers/usb/chipidea/core.c   |  30 ++++++++---
 drivers/usb/chipidea/ulpi.c   | 113 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 165 insertions(+), 6 deletions(-)
 create mode 100644 drivers/usb/chipidea/ulpi.c

diff --git a/drivers/usb/chipidea/Kconfig b/drivers/usb/chipidea/Kconfig
index 3644a3500b70..4f8c342a8865 100644
--- a/drivers/usb/chipidea/Kconfig
+++ b/drivers/usb/chipidea/Kconfig
@@ -37,4 +37,11 @@ config USB_CHIPIDEA_HOST
 	  Say Y here to enable host controller functionality of the
 	  ChipIdea driver.
 
+config USB_CHIPIDEA_ULPI
+	bool "ChipIdea ULPI PHY support"
+	depends on USB_ULPI_BUS=y || USB_ULPI_BUS=USB_CHIPIDEA
+	help
+	  Say Y here if you have a ULPI PHY attached to your ChipIdea
+	  controller.
+
 endif
diff --git a/drivers/usb/chipidea/Makefile b/drivers/usb/chipidea/Makefile
index 518e445476c3..39fca5715ed3 100644
--- a/drivers/usb/chipidea/Makefile
+++ b/drivers/usb/chipidea/Makefile
@@ -4,6 +4,7 @@ ci_hdrc-y				:= core.o otg.o debug.o
 ci_hdrc-$(CONFIG_USB_CHIPIDEA_UDC)	+= udc.o
 ci_hdrc-$(CONFIG_USB_CHIPIDEA_HOST)	+= host.o
 ci_hdrc-$(CONFIG_USB_OTG_FSM)		+= otg_fsm.o
+ci_hdrc-$(CONFIG_USB_CHIPIDEA_ULPI)	+= ulpi.o
 
 # Glue/Bridge layers go here
 
diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index f87805235caa..14aa20525547 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -18,6 +18,8 @@
 #include <linux/usb.h>
 #include <linux/usb/gadget.h>
 #include <linux/usb/otg-fsm.h>
+#include <linux/usb/otg.h>
+#include <linux/ulpi/interface.h>
 
 /******************************************************************************
  * DEFINE
@@ -52,6 +54,7 @@ enum ci_hw_regs {
 	OP_ENDPTLISTADDR,
 	OP_TTCTRL,
 	OP_BURSTSIZE,
+	OP_ULPI_VIEWPORT,
 	OP_PORTSC,
 	OP_DEVLC,
 	OP_OTGSC,
@@ -187,6 +190,7 @@ struct hw_bank {
  * @test_mode: the selected test mode
  * @platdata: platform specific information supplied by parent device
  * @vbus_active: is VBUS active
+ * @ulpi: pointer to ULPI device, if any
  * @phy: pointer to PHY, if any
  * @usb_phy: pointer to USB PHY, if any and if using the USB PHY framework
  * @hcd: pointer to usb_hcd for ehci host driver
@@ -236,6 +240,10 @@ struct ci_hdrc {
 
 	struct ci_hdrc_platform_data	*platdata;
 	int				vbus_active;
+#ifdef CONFIG_USB_CHIPIDEA_ULPI
+	struct ulpi			*ulpi;
+	struct ulpi_ops 		ulpi_ops;
+#endif
 	struct phy			*phy;
 	/* old usb_phy interface */
 	struct usb_phy			*usb_phy;
@@ -418,6 +426,17 @@ static inline bool ci_otg_is_fsm_mode(struct ci_hdrc *ci)
 #endif
 }
 
+#if IS_ENABLED(CONFIG_USB_CHIPIDEA_ULPI)
+int ci_ulpi_init(struct ci_hdrc *ci);
+void ci_ulpi_exit(struct ci_hdrc *ci);
+int ci_ulpi_resume(struct ci_hdrc *ci);
+#else
+static inline int ci_ulpi_init(struct ci_hdrc *ci) { return 0; }
+static inline void ci_ulpi_exit(struct ci_hdrc *ci) { }
+static inline int ci_ulpi_resume(struct ci_hdrc *ci) { return 0; }
+#endif
+
+
 u32 hw_read_intr_enable(struct ci_hdrc *ci);
 
 u32 hw_read_intr_status(struct ci_hdrc *ci);
@@ -432,6 +451,7 @@ int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
 				u32 value, unsigned int timeout_ms);
 
 void ci_usb_phy_exit(struct ci_hdrc *ci);
+void hw_phymode_configure(struct ci_hdrc *ci);
 int ci_platform_configure(struct ci_hdrc *ci);
 
 int dbg_create_files(struct ci_hdrc *ci);
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index a01611c7f815..ea84fc0a03a6 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -86,6 +86,7 @@ static const u8 ci_regs_nolpm[] = {
 	[OP_ENDPTLISTADDR]	= 0x18U,
 	[OP_TTCTRL]		= 0x1CU,
 	[OP_BURSTSIZE]		= 0x20U,
+	[OP_ULPI_VIEWPORT]	= 0x30U,
 	[OP_PORTSC]		= 0x44U,
 	[OP_DEVLC]		= 0x84U,
 	[OP_OTGSC]		= 0x64U,
@@ -110,6 +111,7 @@ static const u8 ci_regs_lpm[] = {
 	[OP_ENDPTLISTADDR]	= 0x18U,
 	[OP_TTCTRL]		= 0x1CU,
 	[OP_BURSTSIZE]		= 0x20U,
+	[OP_ULPI_VIEWPORT]	= 0x30U,
 	[OP_PORTSC]		= 0x44U,
 	[OP_DEVLC]		= 0x84U,
 	[OP_OTGSC]		= 0xC4U,
@@ -285,7 +287,7 @@ static int hw_device_init(struct ci_hdrc *ci, void __iomem *base)
 	return 0;
 }
 
-static void hw_phymode_configure(struct ci_hdrc *ci)
+void hw_phymode_configure(struct ci_hdrc *ci)
 {
 	u32 portsc, lpm, sts = 0;
 
@@ -893,6 +895,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 		CI_HDRC_IMX28_WRITE_FIX);
 	ci->supports_runtime_pm = !!(ci->platdata->flags &
 		CI_HDRC_SUPPORTS_RUNTIME_PM);
+	platform_set_drvdata(pdev, ci);
 
 	ret = hw_device_init(ci, base);
 	if (ret < 0) {
@@ -900,6 +903,10 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
+	ret = ci_ulpi_init(ci);
+	if (ret)
+		return ret;
+
 	if (ci->platdata->phy) {
 		ci->phy = ci->platdata->phy;
 	} else if (ci->platdata->usb_phy) {
@@ -910,11 +917,15 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 
 		/* if both generic PHY and USB PHY layers aren't enabled */
 		if (PTR_ERR(ci->phy) == -ENOSYS &&
-				PTR_ERR(ci->usb_phy) == -ENXIO)
-			return -ENXIO;
+				PTR_ERR(ci->usb_phy) == -ENXIO) {
+			ret = -ENXIO;
+			goto deinit_phy;
+		}
 
-		if (IS_ERR(ci->phy) && IS_ERR(ci->usb_phy))
-			return -EPROBE_DEFER;
+		if (IS_ERR(ci->phy) && IS_ERR(ci->usb_phy)) {
+			ret = -EPROBE_DEFER;
+			goto deinit_phy;
+		}
 
 		if (IS_ERR(ci->phy))
 			ci->phy = NULL;
@@ -993,7 +1004,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 		}
 	}
 
-	platform_set_drvdata(pdev, ci);
 	ret = devm_request_irq(dev, ci->irq, ci_irq, IRQF_SHARED,
 			ci->platdata->name, ci);
 	if (ret)
@@ -1024,6 +1034,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 stop:
 	ci_role_destroy(ci);
 deinit_phy:
+	ci_ulpi_exit(ci);
 
 	return ret;
 }
@@ -1042,6 +1053,7 @@ static int ci_hdrc_remove(struct platform_device *pdev)
 	ci_extcon_unregister(ci);
 	ci_role_destroy(ci);
 	ci_hdrc_enter_lpm(ci, true);
+	ci_ulpi_exit(ci);
 
 	return 0;
 }
@@ -1089,6 +1101,7 @@ static void ci_controller_suspend(struct ci_hdrc *ci)
 static int ci_controller_resume(struct device *dev)
 {
 	struct ci_hdrc *ci = dev_get_drvdata(dev);
+	int ret;
 
 	dev_dbg(dev, "at %s\n", __func__);
 
@@ -1098,6 +1111,11 @@ static int ci_controller_resume(struct device *dev)
 	}
 
 	ci_hdrc_enter_lpm(ci, false);
+
+	ret = ci_ulpi_resume(ci);
+	if (ret)
+		return ret;
+
 	if (ci->usb_phy) {
 		usb_phy_set_suspend(ci->usb_phy, 0);
 		usb_phy_set_wakeup(ci->usb_phy, false);
diff --git a/drivers/usb/chipidea/ulpi.c b/drivers/usb/chipidea/ulpi.c
new file mode 100644
index 000000000000..3962255ff687
--- /dev/null
+++ b/drivers/usb/chipidea/ulpi.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2016 Linaro Ltd.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/device.h>
+#include <linux/usb/chipidea.h>
+#include <linux/ulpi/interface.h>
+
+#include "ci.h"
+
+#define ULPI_WAKEUP		BIT(31)
+#define ULPI_RUN		BIT(30)
+#define ULPI_WRITE		BIT(29)
+#define ULPI_SYNC_STATE		BIT(27)
+#define ULPI_ADDR(n)		((n) << 16)
+#define ULPI_DATA(n)		(n)
+
+static int ci_ulpi_wait(struct ci_hdrc *ci, u32 mask)
+{
+	unsigned long usec = 10000;
+
+	while (usec--) {
+		if (!hw_read(ci, OP_ULPI_VIEWPORT, mask))
+			return 0;
+
+		udelay(1);
+	}
+
+	return -ETIMEDOUT;
+}
+
+static int ci_ulpi_read(struct ulpi_ops *ops, u8 addr)
+{
+	struct ci_hdrc *ci = dev_get_drvdata(ops->dev);
+	int ret;
+
+	hw_write(ci, OP_ULPI_VIEWPORT, 0xffffffff, ULPI_WRITE | ULPI_WAKEUP);
+	ret = ci_ulpi_wait(ci, ULPI_WAKEUP);
+	if (ret)
+		return ret;
+
+	hw_write(ci, OP_ULPI_VIEWPORT, 0xffffffff, ULPI_RUN | ULPI_ADDR(addr));
+	ret = ci_ulpi_wait(ci, ULPI_RUN);
+	if (ret)
+		return ret;
+
+	return hw_read(ci, OP_ULPI_VIEWPORT, GENMASK(15, 8)) >> 8;
+}
+
+static int ci_ulpi_write(struct ulpi_ops *ops, u8 addr, u8 val)
+{
+	struct ci_hdrc *ci = dev_get_drvdata(ops->dev);
+	int ret;
+
+	hw_write(ci, OP_ULPI_VIEWPORT, 0xffffffff, ULPI_WRITE | ULPI_WAKEUP);
+	ret = ci_ulpi_wait(ci, ULPI_WAKEUP);
+	if (ret)
+		return ret;
+
+	hw_write(ci, OP_ULPI_VIEWPORT, 0xffffffff,
+		 ULPI_RUN | ULPI_WRITE | ULPI_ADDR(addr) | val);
+	return ci_ulpi_wait(ci, ULPI_RUN);
+}
+
+int ci_ulpi_init(struct ci_hdrc *ci)
+{
+	if (ci->platdata->phy_mode != USBPHY_INTERFACE_MODE_ULPI)
+		return 0;
+
+	/*
+	 * Set PORTSC correctly so we can read/write ULPI registers for
+	 * identification purposes
+	 */
+	hw_phymode_configure(ci);
+
+	ci->ulpi_ops.read = ci_ulpi_read;
+	ci->ulpi_ops.write = ci_ulpi_write;
+	ci->ulpi = ulpi_register_interface(ci->dev, &ci->ulpi_ops);
+	if (IS_ERR(ci->ulpi))
+		dev_err(ci->dev, "failed to register ULPI interface");
+
+	return PTR_ERR_OR_ZERO(ci->ulpi);
+}
+
+void ci_ulpi_exit(struct ci_hdrc *ci)
+{
+	if (ci->ulpi) {
+		ulpi_unregister_interface(ci->ulpi);
+		ci->ulpi = NULL;
+	}
+}
+
+int ci_ulpi_resume(struct ci_hdrc *ci)
+{
+	int cnt = 100000;
+
+	while (cnt-- > 0) {
+		if (hw_read(ci, OP_ULPI_VIEWPORT, ULPI_SYNC_STATE))
+			return 0;
+		udelay(1);
+	}
+
+	return -ETIMEDOUT;
+}
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 10/21] usb: chipidea: msm: Rely on core to override AHBBURST
  2016-06-26  7:28 ` Stephen Boyd
@ 2016-06-26  7:28   ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb
  Cc: linux-arm-kernel, linux-kernel, linux-arm-msm, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Peter Chen, Greg Kroah-Hartman

The core framework already handles setting this parameter with a
platform quirk. Add the appropriate flag so that we always set
AHBBURST to 0. Technically DT should be doing this, but we always
do it for msm chipidea devices so setting the flag in the driver
works just as well.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/ci_hdrc_msm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
index 3889809fd0c4..37591a4b1346 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -24,7 +24,6 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
 	switch (event) {
 	case CI_HDRC_CONTROLLER_RESET_EVENT:
 		dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
-		writel(0, USB_AHBBURST);
 		/* use AHB transactor, allow posted data writes */
 		writel(0x8, USB_AHBMODE);
 		usb_phy_init(ci->usb_phy);
@@ -47,7 +46,8 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
 	.name			= "ci_hdrc_msm",
 	.capoffset		= DEF_CAPOFFSET,
 	.flags			= CI_HDRC_REGS_SHARED |
-				  CI_HDRC_DISABLE_STREAMING,
+				  CI_HDRC_DISABLE_STREAMING |
+				  CI_HDRC_OVERRIDE_AHB_BURST,
 
 	.notify_event		= ci_hdrc_msm_notify_event,
 };
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 10/21] usb: chipidea: msm: Rely on core to override AHBBURST
@ 2016-06-26  7:28   ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-arm-kernel

The core framework already handles setting this parameter with a
platform quirk. Add the appropriate flag so that we always set
AHBBURST to 0. Technically DT should be doing this, but we always
do it for msm chipidea devices so setting the flag in the driver
works just as well.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/ci_hdrc_msm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
index 3889809fd0c4..37591a4b1346 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -24,7 +24,6 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
 	switch (event) {
 	case CI_HDRC_CONTROLLER_RESET_EVENT:
 		dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
-		writel(0, USB_AHBBURST);
 		/* use AHB transactor, allow posted data writes */
 		writel(0x8, USB_AHBMODE);
 		usb_phy_init(ci->usb_phy);
@@ -47,7 +46,8 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
 	.name			= "ci_hdrc_msm",
 	.capoffset		= DEF_CAPOFFSET,
 	.flags			= CI_HDRC_REGS_SHARED |
-				  CI_HDRC_DISABLE_STREAMING,
+				  CI_HDRC_DISABLE_STREAMING |
+				  CI_HDRC_OVERRIDE_AHB_BURST,
 
 	.notify_event		= ci_hdrc_msm_notify_event,
 };
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 11/21] usb: chipidea: msm: Use hw_write_id_reg() instead of writel directly
  2016-06-26  7:28 ` Stephen Boyd
@ 2016-06-26  7:28   ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb
  Cc: linux-arm-kernel, linux-kernel, linux-arm-msm, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Peter Chen, Greg Kroah-Hartman

The MSM_USB_BASE macro trick is not very clear, and we're using
it for only one register write so let's just move to using
hw_write_id_reg() and passing the ci pointer instead. That
clearly shows what offset we're using and avoids needing to
include the msm_hsusb_hw.h file when we're going to delete that
file soon.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/ci_hdrc_msm.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
index 37591a4b1346..520c85e701ef 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -8,14 +8,12 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
-#include <linux/usb/msm_hsusb_hw.h>
-#include <linux/usb/ulpi.h>
 #include <linux/usb/gadget.h>
 #include <linux/usb/chipidea.h>
 
 #include "ci.h"
 
-#define MSM_USB_BASE	(ci->hw_bank.abs)
+#define HS_PHY_AHB_MODE			0x0098
 
 static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
 {
@@ -25,7 +23,7 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
 	case CI_HDRC_CONTROLLER_RESET_EVENT:
 		dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
 		/* use AHB transactor, allow posted data writes */
-		writel(0x8, USB_AHBMODE);
+		hw_write_id_reg(ci, HS_PHY_AHB_MODE, 0xffffffff, 0x8);
 		usb_phy_init(ci->usb_phy);
 		break;
 	case CI_HDRC_CONTROLLER_STOPPED_EVENT:
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 11/21] usb: chipidea: msm: Use hw_write_id_reg() instead of writel directly
@ 2016-06-26  7:28   ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-arm-kernel

The MSM_USB_BASE macro trick is not very clear, and we're using
it for only one register write so let's just move to using
hw_write_id_reg() and passing the ci pointer instead. That
clearly shows what offset we're using and avoids needing to
include the msm_hsusb_hw.h file when we're going to delete that
file soon.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/ci_hdrc_msm.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
index 37591a4b1346..520c85e701ef 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -8,14 +8,12 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
-#include <linux/usb/msm_hsusb_hw.h>
-#include <linux/usb/ulpi.h>
 #include <linux/usb/gadget.h>
 #include <linux/usb/chipidea.h>
 
 #include "ci.h"
 
-#define MSM_USB_BASE	(ci->hw_bank.abs)
+#define HS_PHY_AHB_MODE			0x0098
 
 static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
 {
@@ -25,7 +23,7 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
 	case CI_HDRC_CONTROLLER_RESET_EVENT:
 		dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
 		/* use AHB transactor, allow posted data writes */
-		writel(0x8, USB_AHBMODE);
+		hw_write_id_reg(ci, HS_PHY_AHB_MODE, 0xffffffff, 0x8);
 		usb_phy_init(ci->usb_phy);
 		break;
 	case CI_HDRC_CONTROLLER_STOPPED_EVENT:
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 12/21] usb: chipidea: msm: Keep device runtime enabled
  2016-06-26  7:28 ` Stephen Boyd
@ 2016-06-26  7:28   ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb
  Cc: linux-arm-kernel, linux-kernel, linux-arm-msm, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Peter Chen, Greg Kroah-Hartman

Sometimes the usb wrapper device is part of a power domain that
needs to stay on as long as the device is active. Let's get and
put the device in driver probe/remove so that we keep the power
domain powered as long as the device is attached. We can fine
tune this later to handle wakeup interrupts, etc. for finer grain
power management later, but this is necessary to make sure we can
keep accessing the device right now.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/ci_hdrc_msm.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
index 520c85e701ef..430856ef1be3 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -80,6 +80,7 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
 
 	pm_runtime_no_callbacks(&pdev->dev);
 	pm_runtime_enable(&pdev->dev);
+	pm_runtime_get(&pdev->dev);
 
 	return 0;
 }
@@ -88,6 +89,7 @@ static int ci_hdrc_msm_remove(struct platform_device *pdev)
 {
 	struct platform_device *plat_ci = platform_get_drvdata(pdev);
 
+	pm_runtime_put(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 	ci_hdrc_remove_device(plat_ci);
 
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 12/21] usb: chipidea: msm: Keep device runtime enabled
@ 2016-06-26  7:28   ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-arm-kernel

Sometimes the usb wrapper device is part of a power domain that
needs to stay on as long as the device is active. Let's get and
put the device in driver probe/remove so that we keep the power
domain powered as long as the device is attached. We can fine
tune this later to handle wakeup interrupts, etc. for finer grain
power management later, but this is necessary to make sure we can
keep accessing the device right now.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/ci_hdrc_msm.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
index 520c85e701ef..430856ef1be3 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -80,6 +80,7 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
 
 	pm_runtime_no_callbacks(&pdev->dev);
 	pm_runtime_enable(&pdev->dev);
+	pm_runtime_get(&pdev->dev);
 
 	return 0;
 }
@@ -88,6 +89,7 @@ static int ci_hdrc_msm_remove(struct platform_device *pdev)
 {
 	struct platform_device *plat_ci = platform_get_drvdata(pdev);
 
+	pm_runtime_put(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 	ci_hdrc_remove_device(plat_ci);
 
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 13/21] usb: chipidea: msm: Allow core to get usb phy
  2016-06-26  7:28 ` Stephen Boyd
@ 2016-06-26  7:28   ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb
  Cc: linux-arm-kernel, linux-kernel, linux-arm-msm, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Peter Chen, Greg Kroah-Hartman

The chipidea core gets the usb phy and initializes the phy at the
right point now so we don't need to get the phy in this driver.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/ci_hdrc_msm.c | 21 ---------------------
 1 file changed, 21 deletions(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
index 430856ef1be3..07cccd24a87f 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -24,15 +24,6 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
 		dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
 		/* use AHB transactor, allow posted data writes */
 		hw_write_id_reg(ci, HS_PHY_AHB_MODE, 0xffffffff, 0x8);
-		usb_phy_init(ci->usb_phy);
-		break;
-	case CI_HDRC_CONTROLLER_STOPPED_EVENT:
-		dev_dbg(dev, "CI_HDRC_CONTROLLER_STOPPED_EVENT received\n");
-		/*
-		 * Put the phy in non-driving mode. Otherwise host
-		 * may not detect soft-disconnection.
-		 */
-		usb_phy_notify_disconnect(ci->usb_phy, USB_SPEED_UNKNOWN);
 		break;
 	default:
 		dev_dbg(dev, "unknown ci_hdrc event\n");
@@ -53,21 +44,9 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
 static int ci_hdrc_msm_probe(struct platform_device *pdev)
 {
 	struct platform_device *plat_ci;
-	struct usb_phy *phy;
 
 	dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
 
-	/*
-	 * OTG(PHY) driver takes care of PHY initialization, clock management,
-	 * powering up VBUS, mapping of registers address space and power
-	 * management.
-	 */
-	phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0);
-	if (IS_ERR(phy))
-		return PTR_ERR(phy);
-
-	ci_hdrc_msm_platdata.usb_phy = phy;
-
 	plat_ci = ci_hdrc_add_device(&pdev->dev,
 				pdev->resource, pdev->num_resources,
 				&ci_hdrc_msm_platdata);
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 13/21] usb: chipidea: msm: Allow core to get usb phy
@ 2016-06-26  7:28   ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-arm-kernel

The chipidea core gets the usb phy and initializes the phy at the
right point now so we don't need to get the phy in this driver.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/ci_hdrc_msm.c | 21 ---------------------
 1 file changed, 21 deletions(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
index 430856ef1be3..07cccd24a87f 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -24,15 +24,6 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
 		dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
 		/* use AHB transactor, allow posted data writes */
 		hw_write_id_reg(ci, HS_PHY_AHB_MODE, 0xffffffff, 0x8);
-		usb_phy_init(ci->usb_phy);
-		break;
-	case CI_HDRC_CONTROLLER_STOPPED_EVENT:
-		dev_dbg(dev, "CI_HDRC_CONTROLLER_STOPPED_EVENT received\n");
-		/*
-		 * Put the phy in non-driving mode. Otherwise host
-		 * may not detect soft-disconnection.
-		 */
-		usb_phy_notify_disconnect(ci->usb_phy, USB_SPEED_UNKNOWN);
 		break;
 	default:
 		dev_dbg(dev, "unknown ci_hdrc event\n");
@@ -53,21 +44,9 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
 static int ci_hdrc_msm_probe(struct platform_device *pdev)
 {
 	struct platform_device *plat_ci;
-	struct usb_phy *phy;
 
 	dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
 
-	/*
-	 * OTG(PHY) driver takes care of PHY initialization, clock management,
-	 * powering up VBUS, mapping of registers address space and power
-	 * management.
-	 */
-	phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0);
-	if (IS_ERR(phy))
-		return PTR_ERR(phy);
-
-	ci_hdrc_msm_platdata.usb_phy = phy;
-
 	plat_ci = ci_hdrc_add_device(&pdev->dev,
 				pdev->resource, pdev->num_resources,
 				&ci_hdrc_msm_platdata);
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 14/21] usb: chipidea: msm: Add proper clk and reset support
  2016-06-26  7:28 ` Stephen Boyd
  (?)
@ 2016-06-26  7:28     ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Peter Chen, Greg Kroah-Hartman

The msm chipidea controller uses two main clks, an AHB clk to
read/write the MMIO registers and a core clk called the system
clk that drives the controller itself. Add support for these clks
as they're required in all designs.

Also add support for an optional third clk that we need to turn
on to read/write the ULPI phy registers. Some ULPI phys drive
this clk themselves and so it isn't necessary to turn on to probe
a ULPI device, but the HSIC phy doesn't provide one itself, so we
must turn it on here.

Cc: Peter Chen <peter.chen-3arQi8VN3Tc@public.gmane.org>
Cc: Greg Kroah-Hartman <gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org>
Signed-off-by: Stephen Boyd <stephen.boyd-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 drivers/usb/chipidea/ci_hdrc_msm.c | 58 +++++++++++++++++++++++++++++++++++---
 1 file changed, 54 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
index 07cccd24a87f..40249b0e3e93 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -10,11 +10,19 @@
 #include <linux/pm_runtime.h>
 #include <linux/usb/gadget.h>
 #include <linux/usb/chipidea.h>
+#include <linux/clk.h>
+#include <linux/reset.h>
 
 #include "ci.h"
 
 #define HS_PHY_AHB_MODE			0x0098
 
+struct ci_hdrc_msm {
+	struct platform_device *ci;
+	struct clk *core_clk;
+	struct clk *iface_clk;
+};
+
 static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
 {
 	struct device *dev = ci->gadget.dev.parent;
@@ -43,34 +51,76 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
 
 static int ci_hdrc_msm_probe(struct platform_device *pdev)
 {
+	struct ci_hdrc_msm *ci;
 	struct platform_device *plat_ci;
+	struct clk *clk;
+	struct reset_control *reset;
+	int ret;
 
 	dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
 
+	ci = devm_kzalloc(&pdev->dev, sizeof(*ci), GFP_KERNEL);
+	if (!ci)
+		return -ENOMEM;
+	platform_set_drvdata(pdev, ci);
+
+	reset = devm_reset_control_get(&pdev->dev, "core");
+	if (IS_ERR(reset))
+		return PTR_ERR(reset);
+
+	ci->core_clk = clk = devm_clk_get(&pdev->dev, "core");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	ci->iface_clk = clk = devm_clk_get(&pdev->dev, "iface");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	reset_control_assert(reset);
+	usleep_range(10000, 12000);
+	reset_control_deassert(reset);
+
+	ret = clk_prepare_enable(ci->core_clk);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(ci->iface_clk);
+	if (ret)
+		goto err_iface;
+
 	plat_ci = ci_hdrc_add_device(&pdev->dev,
 				pdev->resource, pdev->num_resources,
 				&ci_hdrc_msm_platdata);
 	if (IS_ERR(plat_ci)) {
 		dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
-		return PTR_ERR(plat_ci);
+		ret = PTR_ERR(plat_ci);
+		goto err_mux;
 	}
 
-	platform_set_drvdata(pdev, plat_ci);
+	ci->ci = plat_ci;
 
 	pm_runtime_no_callbacks(&pdev->dev);
 	pm_runtime_enable(&pdev->dev);
 	pm_runtime_get(&pdev->dev);
 
 	return 0;
+
+err_mux:
+	clk_disable_unprepare(ci->iface_clk);
+err_iface:
+	clk_disable_unprepare(ci->core_clk);
+	return ret;
 }
 
 static int ci_hdrc_msm_remove(struct platform_device *pdev)
 {
-	struct platform_device *plat_ci = platform_get_drvdata(pdev);
+	struct ci_hdrc_msm *ci = platform_get_drvdata(pdev);
 
 	pm_runtime_put(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
-	ci_hdrc_remove_device(plat_ci);
+	ci_hdrc_remove_device(ci->ci);
+	clk_disable_unprepare(ci->iface_clk);
+	clk_disable_unprepare(ci->core_clk);
 
 	return 0;
 }
-- 
2.9.0.rc2.8.ga28705d

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 14/21] usb: chipidea: msm: Add proper clk and reset support
@ 2016-06-26  7:28     ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb
  Cc: linux-arm-kernel, linux-kernel, linux-arm-msm, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Peter Chen, Greg Kroah-Hartman

The msm chipidea controller uses two main clks, an AHB clk to
read/write the MMIO registers and a core clk called the system
clk that drives the controller itself. Add support for these clks
as they're required in all designs.

Also add support for an optional third clk that we need to turn
on to read/write the ULPI phy registers. Some ULPI phys drive
this clk themselves and so it isn't necessary to turn on to probe
a ULPI device, but the HSIC phy doesn't provide one itself, so we
must turn it on here.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/ci_hdrc_msm.c | 58 +++++++++++++++++++++++++++++++++++---
 1 file changed, 54 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
index 07cccd24a87f..40249b0e3e93 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -10,11 +10,19 @@
 #include <linux/pm_runtime.h>
 #include <linux/usb/gadget.h>
 #include <linux/usb/chipidea.h>
+#include <linux/clk.h>
+#include <linux/reset.h>
 
 #include "ci.h"
 
 #define HS_PHY_AHB_MODE			0x0098
 
+struct ci_hdrc_msm {
+	struct platform_device *ci;
+	struct clk *core_clk;
+	struct clk *iface_clk;
+};
+
 static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
 {
 	struct device *dev = ci->gadget.dev.parent;
@@ -43,34 +51,76 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
 
 static int ci_hdrc_msm_probe(struct platform_device *pdev)
 {
+	struct ci_hdrc_msm *ci;
 	struct platform_device *plat_ci;
+	struct clk *clk;
+	struct reset_control *reset;
+	int ret;
 
 	dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
 
+	ci = devm_kzalloc(&pdev->dev, sizeof(*ci), GFP_KERNEL);
+	if (!ci)
+		return -ENOMEM;
+	platform_set_drvdata(pdev, ci);
+
+	reset = devm_reset_control_get(&pdev->dev, "core");
+	if (IS_ERR(reset))
+		return PTR_ERR(reset);
+
+	ci->core_clk = clk = devm_clk_get(&pdev->dev, "core");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	ci->iface_clk = clk = devm_clk_get(&pdev->dev, "iface");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	reset_control_assert(reset);
+	usleep_range(10000, 12000);
+	reset_control_deassert(reset);
+
+	ret = clk_prepare_enable(ci->core_clk);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(ci->iface_clk);
+	if (ret)
+		goto err_iface;
+
 	plat_ci = ci_hdrc_add_device(&pdev->dev,
 				pdev->resource, pdev->num_resources,
 				&ci_hdrc_msm_platdata);
 	if (IS_ERR(plat_ci)) {
 		dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
-		return PTR_ERR(plat_ci);
+		ret = PTR_ERR(plat_ci);
+		goto err_mux;
 	}
 
-	platform_set_drvdata(pdev, plat_ci);
+	ci->ci = plat_ci;
 
 	pm_runtime_no_callbacks(&pdev->dev);
 	pm_runtime_enable(&pdev->dev);
 	pm_runtime_get(&pdev->dev);
 
 	return 0;
+
+err_mux:
+	clk_disable_unprepare(ci->iface_clk);
+err_iface:
+	clk_disable_unprepare(ci->core_clk);
+	return ret;
 }
 
 static int ci_hdrc_msm_remove(struct platform_device *pdev)
 {
-	struct platform_device *plat_ci = platform_get_drvdata(pdev);
+	struct ci_hdrc_msm *ci = platform_get_drvdata(pdev);
 
 	pm_runtime_put(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
-	ci_hdrc_remove_device(plat_ci);
+	ci_hdrc_remove_device(ci->ci);
+	clk_disable_unprepare(ci->iface_clk);
+	clk_disable_unprepare(ci->core_clk);
 
 	return 0;
 }
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 14/21] usb: chipidea: msm: Add proper clk and reset support
@ 2016-06-26  7:28     ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-arm-kernel

The msm chipidea controller uses two main clks, an AHB clk to
read/write the MMIO registers and a core clk called the system
clk that drives the controller itself. Add support for these clks
as they're required in all designs.

Also add support for an optional third clk that we need to turn
on to read/write the ULPI phy registers. Some ULPI phys drive
this clk themselves and so it isn't necessary to turn on to probe
a ULPI device, but the HSIC phy doesn't provide one itself, so we
must turn it on here.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/ci_hdrc_msm.c | 58 +++++++++++++++++++++++++++++++++++---
 1 file changed, 54 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
index 07cccd24a87f..40249b0e3e93 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -10,11 +10,19 @@
 #include <linux/pm_runtime.h>
 #include <linux/usb/gadget.h>
 #include <linux/usb/chipidea.h>
+#include <linux/clk.h>
+#include <linux/reset.h>
 
 #include "ci.h"
 
 #define HS_PHY_AHB_MODE			0x0098
 
+struct ci_hdrc_msm {
+	struct platform_device *ci;
+	struct clk *core_clk;
+	struct clk *iface_clk;
+};
+
 static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
 {
 	struct device *dev = ci->gadget.dev.parent;
@@ -43,34 +51,76 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
 
 static int ci_hdrc_msm_probe(struct platform_device *pdev)
 {
+	struct ci_hdrc_msm *ci;
 	struct platform_device *plat_ci;
+	struct clk *clk;
+	struct reset_control *reset;
+	int ret;
 
 	dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
 
+	ci = devm_kzalloc(&pdev->dev, sizeof(*ci), GFP_KERNEL);
+	if (!ci)
+		return -ENOMEM;
+	platform_set_drvdata(pdev, ci);
+
+	reset = devm_reset_control_get(&pdev->dev, "core");
+	if (IS_ERR(reset))
+		return PTR_ERR(reset);
+
+	ci->core_clk = clk = devm_clk_get(&pdev->dev, "core");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	ci->iface_clk = clk = devm_clk_get(&pdev->dev, "iface");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	reset_control_assert(reset);
+	usleep_range(10000, 12000);
+	reset_control_deassert(reset);
+
+	ret = clk_prepare_enable(ci->core_clk);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(ci->iface_clk);
+	if (ret)
+		goto err_iface;
+
 	plat_ci = ci_hdrc_add_device(&pdev->dev,
 				pdev->resource, pdev->num_resources,
 				&ci_hdrc_msm_platdata);
 	if (IS_ERR(plat_ci)) {
 		dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
-		return PTR_ERR(plat_ci);
+		ret = PTR_ERR(plat_ci);
+		goto err_mux;
 	}
 
-	platform_set_drvdata(pdev, plat_ci);
+	ci->ci = plat_ci;
 
 	pm_runtime_no_callbacks(&pdev->dev);
 	pm_runtime_enable(&pdev->dev);
 	pm_runtime_get(&pdev->dev);
 
 	return 0;
+
+err_mux:
+	clk_disable_unprepare(ci->iface_clk);
+err_iface:
+	clk_disable_unprepare(ci->core_clk);
+	return ret;
 }
 
 static int ci_hdrc_msm_remove(struct platform_device *pdev)
 {
-	struct platform_device *plat_ci = platform_get_drvdata(pdev);
+	struct ci_hdrc_msm *ci = platform_get_drvdata(pdev);
 
 	pm_runtime_put(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
-	ci_hdrc_remove_device(plat_ci);
+	ci_hdrc_remove_device(ci->ci);
+	clk_disable_unprepare(ci->iface_clk);
+	clk_disable_unprepare(ci->core_clk);
 
 	return 0;
 }
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 15/21] usb: chipidea: msm: Mux over secondary phy at the right time
  2016-06-26  7:28 ` Stephen Boyd
  (?)
@ 2016-06-26  7:28   ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb
  Cc: Felipe Balbi, Arnd Bergmann, Neil Armstrong, linux-arm-msm,
	linux-kernel, Bjorn Andersson, Peter Chen, Greg Kroah-Hartman,
	Andy Gross, linux-arm-kernel

We need to pick the correct phy at runtime based on how the SoC
has been wired onto the board. If the secondary phy is used, take
it out of reset and mux over to it by writing into the TCSR
register. Make sure to do this on reset too, because this
register is reset to the default value (primary phy) after the
RESET bit is set in USBCMD.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/ci_hdrc_msm.c | 78 +++++++++++++++++++++++++++++++++++---
 1 file changed, 73 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
index 40249b0e3e93..df0f8b31db4f 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -8,30 +8,40 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
-#include <linux/usb/gadget.h>
 #include <linux/usb/chipidea.h>
 #include <linux/clk.h>
 #include <linux/reset.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <linux/io.h>
 
 #include "ci.h"
 
 #define HS_PHY_AHB_MODE			0x0098
+#define HS_PHY_SEC_CTRL			0x0278
+# define HS_PHY_DIG_CLAMP_N		BIT(16)
 
 struct ci_hdrc_msm {
 	struct platform_device *ci;
 	struct clk *core_clk;
 	struct clk *iface_clk;
+	bool secondary_phy;
+	void __iomem *base;
 };
 
 static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
 {
-	struct device *dev = ci->gadget.dev.parent;
+	struct device *dev = ci->dev->parent;
+	struct ci_hdrc_msm *msm_ci = dev_get_drvdata(dev);
 
 	switch (event) {
 	case CI_HDRC_CONTROLLER_RESET_EVENT:
 		dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
 		/* use AHB transactor, allow posted data writes */
 		hw_write_id_reg(ci, HS_PHY_AHB_MODE, 0xffffffff, 0x8);
+		if (msm_ci->secondary_phy)
+			hw_write_id_reg(ci, HS_PHY_SEC_CTRL, HS_PHY_DIG_CLAMP_N,
+					HS_PHY_DIG_CLAMP_N);
 		break;
 	default:
 		dev_dbg(dev, "unknown ci_hdrc event\n");
@@ -49,12 +59,58 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
 	.notify_event		= ci_hdrc_msm_notify_event,
 };
 
+static int ci_hdrc_msm_mux_phy(struct ci_hdrc_msm *ci,
+			       struct platform_device *pdev)
+{
+	struct regmap *regmap;
+	struct device_node *syscon;
+	struct device *dev = &pdev->dev;
+	u32 off, val;
+	int ret;
+
+	syscon = of_parse_phandle(dev->of_node, "phy-select", 0);
+	if (!syscon)
+		return 0;
+
+	regmap = syscon_node_to_regmap(syscon);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	ret = of_property_read_u32_index(dev->of_node, "phy-select", 1, &off);
+	if (ret < 0) {
+		dev_err(dev, "no offset in syscon\n");
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32_index(dev->of_node, "phy-select", 2, &val);
+	if (ret < 0) {
+		dev_err(dev, "no value in syscon\n");
+		return -EINVAL;
+	}
+
+	ret = regmap_write(regmap, off, val);
+	if (ret)
+		return ret;
+
+	ci->secondary_phy = !!val;
+	if (ci->secondary_phy) {
+		val = readl_relaxed(ci->base + HS_PHY_SEC_CTRL);
+		val |= HS_PHY_DIG_CLAMP_N;
+		writel_relaxed(val, ci->base + HS_PHY_SEC_CTRL);
+	}
+
+	return 0;
+}
+
 static int ci_hdrc_msm_probe(struct platform_device *pdev)
 {
 	struct ci_hdrc_msm *ci;
 	struct platform_device *plat_ci;
 	struct clk *clk;
 	struct reset_control *reset;
+	struct resource *res;
+	void __iomem *base;
+	resource_size_t size;
 	int ret;
 
 	dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
@@ -76,6 +132,15 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
 	if (IS_ERR(clk))
 		return PTR_ERR(clk);
 
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
+	size = resource_size(res);
+	ci->base = base = devm_ioremap(&pdev->dev, res->start, size);
+	if (!base)
+		return -ENOMEM;
+
 	reset_control_assert(reset);
 	usleep_range(10000, 12000);
 	reset_control_deassert(reset);
@@ -88,9 +153,12 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_iface;
 
-	plat_ci = ci_hdrc_add_device(&pdev->dev,
-				pdev->resource, pdev->num_resources,
-				&ci_hdrc_msm_platdata);
+	ret = ci_hdrc_msm_mux_phy(ci, pdev);
+	if (ret)
+		goto err_mux;
+
+	plat_ci = ci_hdrc_add_device(&pdev->dev, pdev->resource,
+				     pdev->num_resources, &ci_hdrc_msm_platdata);
 	if (IS_ERR(plat_ci)) {
 		dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
 		ret = PTR_ERR(plat_ci);
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 15/21] usb: chipidea: msm: Mux over secondary phy at the right time
@ 2016-06-26  7:28   ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb
  Cc: linux-arm-kernel, linux-kernel, linux-arm-msm, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Peter Chen, Greg Kroah-Hartman

We need to pick the correct phy at runtime based on how the SoC
has been wired onto the board. If the secondary phy is used, take
it out of reset and mux over to it by writing into the TCSR
register. Make sure to do this on reset too, because this
register is reset to the default value (primary phy) after the
RESET bit is set in USBCMD.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/ci_hdrc_msm.c | 78 +++++++++++++++++++++++++++++++++++---
 1 file changed, 73 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
index 40249b0e3e93..df0f8b31db4f 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -8,30 +8,40 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
-#include <linux/usb/gadget.h>
 #include <linux/usb/chipidea.h>
 #include <linux/clk.h>
 #include <linux/reset.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <linux/io.h>
 
 #include "ci.h"
 
 #define HS_PHY_AHB_MODE			0x0098
+#define HS_PHY_SEC_CTRL			0x0278
+# define HS_PHY_DIG_CLAMP_N		BIT(16)
 
 struct ci_hdrc_msm {
 	struct platform_device *ci;
 	struct clk *core_clk;
 	struct clk *iface_clk;
+	bool secondary_phy;
+	void __iomem *base;
 };
 
 static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
 {
-	struct device *dev = ci->gadget.dev.parent;
+	struct device *dev = ci->dev->parent;
+	struct ci_hdrc_msm *msm_ci = dev_get_drvdata(dev);
 
 	switch (event) {
 	case CI_HDRC_CONTROLLER_RESET_EVENT:
 		dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
 		/* use AHB transactor, allow posted data writes */
 		hw_write_id_reg(ci, HS_PHY_AHB_MODE, 0xffffffff, 0x8);
+		if (msm_ci->secondary_phy)
+			hw_write_id_reg(ci, HS_PHY_SEC_CTRL, HS_PHY_DIG_CLAMP_N,
+					HS_PHY_DIG_CLAMP_N);
 		break;
 	default:
 		dev_dbg(dev, "unknown ci_hdrc event\n");
@@ -49,12 +59,58 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
 	.notify_event		= ci_hdrc_msm_notify_event,
 };
 
+static int ci_hdrc_msm_mux_phy(struct ci_hdrc_msm *ci,
+			       struct platform_device *pdev)
+{
+	struct regmap *regmap;
+	struct device_node *syscon;
+	struct device *dev = &pdev->dev;
+	u32 off, val;
+	int ret;
+
+	syscon = of_parse_phandle(dev->of_node, "phy-select", 0);
+	if (!syscon)
+		return 0;
+
+	regmap = syscon_node_to_regmap(syscon);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	ret = of_property_read_u32_index(dev->of_node, "phy-select", 1, &off);
+	if (ret < 0) {
+		dev_err(dev, "no offset in syscon\n");
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32_index(dev->of_node, "phy-select", 2, &val);
+	if (ret < 0) {
+		dev_err(dev, "no value in syscon\n");
+		return -EINVAL;
+	}
+
+	ret = regmap_write(regmap, off, val);
+	if (ret)
+		return ret;
+
+	ci->secondary_phy = !!val;
+	if (ci->secondary_phy) {
+		val = readl_relaxed(ci->base + HS_PHY_SEC_CTRL);
+		val |= HS_PHY_DIG_CLAMP_N;
+		writel_relaxed(val, ci->base + HS_PHY_SEC_CTRL);
+	}
+
+	return 0;
+}
+
 static int ci_hdrc_msm_probe(struct platform_device *pdev)
 {
 	struct ci_hdrc_msm *ci;
 	struct platform_device *plat_ci;
 	struct clk *clk;
 	struct reset_control *reset;
+	struct resource *res;
+	void __iomem *base;
+	resource_size_t size;
 	int ret;
 
 	dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
@@ -76,6 +132,15 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
 	if (IS_ERR(clk))
 		return PTR_ERR(clk);
 
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
+	size = resource_size(res);
+	ci->base = base = devm_ioremap(&pdev->dev, res->start, size);
+	if (!base)
+		return -ENOMEM;
+
 	reset_control_assert(reset);
 	usleep_range(10000, 12000);
 	reset_control_deassert(reset);
@@ -88,9 +153,12 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_iface;
 
-	plat_ci = ci_hdrc_add_device(&pdev->dev,
-				pdev->resource, pdev->num_resources,
-				&ci_hdrc_msm_platdata);
+	ret = ci_hdrc_msm_mux_phy(ci, pdev);
+	if (ret)
+		goto err_mux;
+
+	plat_ci = ci_hdrc_add_device(&pdev->dev, pdev->resource,
+				     pdev->num_resources, &ci_hdrc_msm_platdata);
 	if (IS_ERR(plat_ci)) {
 		dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
 		ret = PTR_ERR(plat_ci);
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 15/21] usb: chipidea: msm: Mux over secondary phy at the right time
@ 2016-06-26  7:28   ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-arm-kernel

We need to pick the correct phy at runtime based on how the SoC
has been wired onto the board. If the secondary phy is used, take
it out of reset and mux over to it by writing into the TCSR
register. Make sure to do this on reset too, because this
register is reset to the default value (primary phy) after the
RESET bit is set in USBCMD.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/ci_hdrc_msm.c | 78 +++++++++++++++++++++++++++++++++++---
 1 file changed, 73 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
index 40249b0e3e93..df0f8b31db4f 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -8,30 +8,40 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
-#include <linux/usb/gadget.h>
 #include <linux/usb/chipidea.h>
 #include <linux/clk.h>
 #include <linux/reset.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <linux/io.h>
 
 #include "ci.h"
 
 #define HS_PHY_AHB_MODE			0x0098
+#define HS_PHY_SEC_CTRL			0x0278
+# define HS_PHY_DIG_CLAMP_N		BIT(16)
 
 struct ci_hdrc_msm {
 	struct platform_device *ci;
 	struct clk *core_clk;
 	struct clk *iface_clk;
+	bool secondary_phy;
+	void __iomem *base;
 };
 
 static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
 {
-	struct device *dev = ci->gadget.dev.parent;
+	struct device *dev = ci->dev->parent;
+	struct ci_hdrc_msm *msm_ci = dev_get_drvdata(dev);
 
 	switch (event) {
 	case CI_HDRC_CONTROLLER_RESET_EVENT:
 		dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
 		/* use AHB transactor, allow posted data writes */
 		hw_write_id_reg(ci, HS_PHY_AHB_MODE, 0xffffffff, 0x8);
+		if (msm_ci->secondary_phy)
+			hw_write_id_reg(ci, HS_PHY_SEC_CTRL, HS_PHY_DIG_CLAMP_N,
+					HS_PHY_DIG_CLAMP_N);
 		break;
 	default:
 		dev_dbg(dev, "unknown ci_hdrc event\n");
@@ -49,12 +59,58 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
 	.notify_event		= ci_hdrc_msm_notify_event,
 };
 
+static int ci_hdrc_msm_mux_phy(struct ci_hdrc_msm *ci,
+			       struct platform_device *pdev)
+{
+	struct regmap *regmap;
+	struct device_node *syscon;
+	struct device *dev = &pdev->dev;
+	u32 off, val;
+	int ret;
+
+	syscon = of_parse_phandle(dev->of_node, "phy-select", 0);
+	if (!syscon)
+		return 0;
+
+	regmap = syscon_node_to_regmap(syscon);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	ret = of_property_read_u32_index(dev->of_node, "phy-select", 1, &off);
+	if (ret < 0) {
+		dev_err(dev, "no offset in syscon\n");
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32_index(dev->of_node, "phy-select", 2, &val);
+	if (ret < 0) {
+		dev_err(dev, "no value in syscon\n");
+		return -EINVAL;
+	}
+
+	ret = regmap_write(regmap, off, val);
+	if (ret)
+		return ret;
+
+	ci->secondary_phy = !!val;
+	if (ci->secondary_phy) {
+		val = readl_relaxed(ci->base + HS_PHY_SEC_CTRL);
+		val |= HS_PHY_DIG_CLAMP_N;
+		writel_relaxed(val, ci->base + HS_PHY_SEC_CTRL);
+	}
+
+	return 0;
+}
+
 static int ci_hdrc_msm_probe(struct platform_device *pdev)
 {
 	struct ci_hdrc_msm *ci;
 	struct platform_device *plat_ci;
 	struct clk *clk;
 	struct reset_control *reset;
+	struct resource *res;
+	void __iomem *base;
+	resource_size_t size;
 	int ret;
 
 	dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
@@ -76,6 +132,15 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
 	if (IS_ERR(clk))
 		return PTR_ERR(clk);
 
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
+	size = resource_size(res);
+	ci->base = base = devm_ioremap(&pdev->dev, res->start, size);
+	if (!base)
+		return -ENOMEM;
+
 	reset_control_assert(reset);
 	usleep_range(10000, 12000);
 	reset_control_deassert(reset);
@@ -88,9 +153,12 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_iface;
 
-	plat_ci = ci_hdrc_add_device(&pdev->dev,
-				pdev->resource, pdev->num_resources,
-				&ci_hdrc_msm_platdata);
+	ret = ci_hdrc_msm_mux_phy(ci, pdev);
+	if (ret)
+		goto err_mux;
+
+	plat_ci = ci_hdrc_add_device(&pdev->dev, pdev->resource,
+				     pdev->num_resources, &ci_hdrc_msm_platdata);
 	if (IS_ERR(plat_ci)) {
 		dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
 		ret = PTR_ERR(plat_ci);
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 16/21] usb: chipidea: msm: Restore wrapper settings after reset
  2016-06-26  7:28 ` Stephen Boyd
  (?)
@ 2016-06-26  7:28   ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb
  Cc: Felipe Balbi, Arnd Bergmann, Neil Armstrong, linux-arm-msm,
	linux-kernel, Bjorn Andersson, Peter Chen, Greg Kroah-Hartman,
	Andy Gross, linux-arm-kernel

When the RESET bit is set in the USBCMD register it resets quite
a few of the wrapper's registers to their reset state. This
includes the GENCONFIG and GENCONFIG2 registers. Currently this
is done by the usb phy and ehci-msm drivers writing into the
controller wrapper's MMIO address space. Let's consolidate the
register writes into the wrapper driver instead so that we
clearly split the wrapper from the phys.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/ci_hdrc_msm.c | 46 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
index df0f8b31db4f..cc6f9b0df9d5 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -14,6 +14,8 @@
 #include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
 #include <linux/io.h>
+#include <linux/extcon.h>
+#include <linux/of.h>
 
 #include "ci.h"
 
@@ -21,11 +23,22 @@
 #define HS_PHY_SEC_CTRL			0x0278
 # define HS_PHY_DIG_CLAMP_N		BIT(16)
 
+#define HS_PHY_GENCONFIG		0x009c
+# define HS_PHY_TXFIFO_IDLE_FORCE_DIS	BIT(4)
+
+#define HS_PHY_GENCONFIG_2		0x00a0
+# define HS_PHY_SESS_VLD_CTRL_EN	BIT(7)
+# define HS_PHY_ULPI_TX_PKT_EN_CLR_FIX	BIT(19)
+
+#define HSPHY_SESS_VLD_CTRL		BIT(25)
+
 struct ci_hdrc_msm {
 	struct platform_device *ci;
 	struct clk *core_clk;
 	struct clk *iface_clk;
+	struct extcon_dev *vbus_edev;
 	bool secondary_phy;
+	bool hsic;
 	void __iomem *base;
 };
 
@@ -39,9 +52,26 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
 		dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
 		/* use AHB transactor, allow posted data writes */
 		hw_write_id_reg(ci, HS_PHY_AHB_MODE, 0xffffffff, 0x8);
+		/* workaround for rx buffer collision issue */
+		hw_write_id_reg(ci, HS_PHY_GENCONFIG,
+				HS_PHY_TXFIFO_IDLE_FORCE_DIS, 0);
+
 		if (msm_ci->secondary_phy)
 			hw_write_id_reg(ci, HS_PHY_SEC_CTRL, HS_PHY_DIG_CLAMP_N,
 					HS_PHY_DIG_CLAMP_N);
+
+		if (!msm_ci->hsic)
+			hw_write_id_reg(ci, HS_PHY_GENCONFIG_2,
+					HS_PHY_ULPI_TX_PKT_EN_CLR_FIX, 0);
+
+		if (msm_ci->vbus_edev) {
+			hw_write_id_reg(ci, HS_PHY_GENCONFIG_2,
+					HS_PHY_SESS_VLD_CTRL_EN,
+					HS_PHY_SESS_VLD_CTRL_EN);
+			hw_write(ci, OP_USBCMD, HSPHY_SESS_VLD_CTRL,
+				 HSPHY_SESS_VLD_CTRL);
+
+		}
 		break;
 	default:
 		dev_dbg(dev, "unknown ci_hdrc event\n");
@@ -112,6 +142,7 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
 	void __iomem *base;
 	resource_size_t size;
 	int ret;
+	struct device_node *ulpi_node, *phy_node;
 
 	dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
 
@@ -141,6 +172,13 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
 	if (!base)
 		return -ENOMEM;
 
+	ci->vbus_edev = extcon_get_edev_by_phandle(&pdev->dev, 0);
+	if (IS_ERR(ci->vbus_edev)) {
+		if (PTR_ERR(ci->vbus_edev) != -ENODEV)
+			return PTR_ERR(ci->vbus_edev);
+		ci->vbus_edev = NULL;
+	}
+
 	reset_control_assert(reset);
 	usleep_range(10000, 12000);
 	reset_control_deassert(reset);
@@ -157,6 +195,14 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_mux;
 
+	ulpi_node = of_find_node_by_name(pdev->dev.of_node, "ulpi");
+	if (ulpi_node) {
+		phy_node = of_get_next_available_child(ulpi_node, NULL);
+		ci->hsic = of_device_is_compatible(phy_node, "qcom,usb-hsic-phy");
+		of_node_put(phy_node);
+	}
+	of_node_put(ulpi_node);
+
 	plat_ci = ci_hdrc_add_device(&pdev->dev, pdev->resource,
 				     pdev->num_resources, &ci_hdrc_msm_platdata);
 	if (IS_ERR(plat_ci)) {
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 16/21] usb: chipidea: msm: Restore wrapper settings after reset
@ 2016-06-26  7:28   ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb
  Cc: linux-arm-kernel, linux-kernel, linux-arm-msm, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Peter Chen, Greg Kroah-Hartman

When the RESET bit is set in the USBCMD register it resets quite
a few of the wrapper's registers to their reset state. This
includes the GENCONFIG and GENCONFIG2 registers. Currently this
is done by the usb phy and ehci-msm drivers writing into the
controller wrapper's MMIO address space. Let's consolidate the
register writes into the wrapper driver instead so that we
clearly split the wrapper from the phys.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/ci_hdrc_msm.c | 46 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
index df0f8b31db4f..cc6f9b0df9d5 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -14,6 +14,8 @@
 #include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
 #include <linux/io.h>
+#include <linux/extcon.h>
+#include <linux/of.h>
 
 #include "ci.h"
 
@@ -21,11 +23,22 @@
 #define HS_PHY_SEC_CTRL			0x0278
 # define HS_PHY_DIG_CLAMP_N		BIT(16)
 
+#define HS_PHY_GENCONFIG		0x009c
+# define HS_PHY_TXFIFO_IDLE_FORCE_DIS	BIT(4)
+
+#define HS_PHY_GENCONFIG_2		0x00a0
+# define HS_PHY_SESS_VLD_CTRL_EN	BIT(7)
+# define HS_PHY_ULPI_TX_PKT_EN_CLR_FIX	BIT(19)
+
+#define HSPHY_SESS_VLD_CTRL		BIT(25)
+
 struct ci_hdrc_msm {
 	struct platform_device *ci;
 	struct clk *core_clk;
 	struct clk *iface_clk;
+	struct extcon_dev *vbus_edev;
 	bool secondary_phy;
+	bool hsic;
 	void __iomem *base;
 };
 
@@ -39,9 +52,26 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
 		dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
 		/* use AHB transactor, allow posted data writes */
 		hw_write_id_reg(ci, HS_PHY_AHB_MODE, 0xffffffff, 0x8);
+		/* workaround for rx buffer collision issue */
+		hw_write_id_reg(ci, HS_PHY_GENCONFIG,
+				HS_PHY_TXFIFO_IDLE_FORCE_DIS, 0);
+
 		if (msm_ci->secondary_phy)
 			hw_write_id_reg(ci, HS_PHY_SEC_CTRL, HS_PHY_DIG_CLAMP_N,
 					HS_PHY_DIG_CLAMP_N);
+
+		if (!msm_ci->hsic)
+			hw_write_id_reg(ci, HS_PHY_GENCONFIG_2,
+					HS_PHY_ULPI_TX_PKT_EN_CLR_FIX, 0);
+
+		if (msm_ci->vbus_edev) {
+			hw_write_id_reg(ci, HS_PHY_GENCONFIG_2,
+					HS_PHY_SESS_VLD_CTRL_EN,
+					HS_PHY_SESS_VLD_CTRL_EN);
+			hw_write(ci, OP_USBCMD, HSPHY_SESS_VLD_CTRL,
+				 HSPHY_SESS_VLD_CTRL);
+
+		}
 		break;
 	default:
 		dev_dbg(dev, "unknown ci_hdrc event\n");
@@ -112,6 +142,7 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
 	void __iomem *base;
 	resource_size_t size;
 	int ret;
+	struct device_node *ulpi_node, *phy_node;
 
 	dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
 
@@ -141,6 +172,13 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
 	if (!base)
 		return -ENOMEM;
 
+	ci->vbus_edev = extcon_get_edev_by_phandle(&pdev->dev, 0);
+	if (IS_ERR(ci->vbus_edev)) {
+		if (PTR_ERR(ci->vbus_edev) != -ENODEV)
+			return PTR_ERR(ci->vbus_edev);
+		ci->vbus_edev = NULL;
+	}
+
 	reset_control_assert(reset);
 	usleep_range(10000, 12000);
 	reset_control_deassert(reset);
@@ -157,6 +195,14 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_mux;
 
+	ulpi_node = of_find_node_by_name(pdev->dev.of_node, "ulpi");
+	if (ulpi_node) {
+		phy_node = of_get_next_available_child(ulpi_node, NULL);
+		ci->hsic = of_device_is_compatible(phy_node, "qcom,usb-hsic-phy");
+		of_node_put(phy_node);
+	}
+	of_node_put(ulpi_node);
+
 	plat_ci = ci_hdrc_add_device(&pdev->dev, pdev->resource,
 				     pdev->num_resources, &ci_hdrc_msm_platdata);
 	if (IS_ERR(plat_ci)) {
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 16/21] usb: chipidea: msm: Restore wrapper settings after reset
@ 2016-06-26  7:28   ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-arm-kernel

When the RESET bit is set in the USBCMD register it resets quite
a few of the wrapper's registers to their reset state. This
includes the GENCONFIG and GENCONFIG2 registers. Currently this
is done by the usb phy and ehci-msm drivers writing into the
controller wrapper's MMIO address space. Let's consolidate the
register writes into the wrapper driver instead so that we
clearly split the wrapper from the phys.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/ci_hdrc_msm.c | 46 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
index df0f8b31db4f..cc6f9b0df9d5 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -14,6 +14,8 @@
 #include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
 #include <linux/io.h>
+#include <linux/extcon.h>
+#include <linux/of.h>
 
 #include "ci.h"
 
@@ -21,11 +23,22 @@
 #define HS_PHY_SEC_CTRL			0x0278
 # define HS_PHY_DIG_CLAMP_N		BIT(16)
 
+#define HS_PHY_GENCONFIG		0x009c
+# define HS_PHY_TXFIFO_IDLE_FORCE_DIS	BIT(4)
+
+#define HS_PHY_GENCONFIG_2		0x00a0
+# define HS_PHY_SESS_VLD_CTRL_EN	BIT(7)
+# define HS_PHY_ULPI_TX_PKT_EN_CLR_FIX	BIT(19)
+
+#define HSPHY_SESS_VLD_CTRL		BIT(25)
+
 struct ci_hdrc_msm {
 	struct platform_device *ci;
 	struct clk *core_clk;
 	struct clk *iface_clk;
+	struct extcon_dev *vbus_edev;
 	bool secondary_phy;
+	bool hsic;
 	void __iomem *base;
 };
 
@@ -39,9 +52,26 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
 		dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
 		/* use AHB transactor, allow posted data writes */
 		hw_write_id_reg(ci, HS_PHY_AHB_MODE, 0xffffffff, 0x8);
+		/* workaround for rx buffer collision issue */
+		hw_write_id_reg(ci, HS_PHY_GENCONFIG,
+				HS_PHY_TXFIFO_IDLE_FORCE_DIS, 0);
+
 		if (msm_ci->secondary_phy)
 			hw_write_id_reg(ci, HS_PHY_SEC_CTRL, HS_PHY_DIG_CLAMP_N,
 					HS_PHY_DIG_CLAMP_N);
+
+		if (!msm_ci->hsic)
+			hw_write_id_reg(ci, HS_PHY_GENCONFIG_2,
+					HS_PHY_ULPI_TX_PKT_EN_CLR_FIX, 0);
+
+		if (msm_ci->vbus_edev) {
+			hw_write_id_reg(ci, HS_PHY_GENCONFIG_2,
+					HS_PHY_SESS_VLD_CTRL_EN,
+					HS_PHY_SESS_VLD_CTRL_EN);
+			hw_write(ci, OP_USBCMD, HSPHY_SESS_VLD_CTRL,
+				 HSPHY_SESS_VLD_CTRL);
+
+		}
 		break;
 	default:
 		dev_dbg(dev, "unknown ci_hdrc event\n");
@@ -112,6 +142,7 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
 	void __iomem *base;
 	resource_size_t size;
 	int ret;
+	struct device_node *ulpi_node, *phy_node;
 
 	dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
 
@@ -141,6 +172,13 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
 	if (!base)
 		return -ENOMEM;
 
+	ci->vbus_edev = extcon_get_edev_by_phandle(&pdev->dev, 0);
+	if (IS_ERR(ci->vbus_edev)) {
+		if (PTR_ERR(ci->vbus_edev) != -ENODEV)
+			return PTR_ERR(ci->vbus_edev);
+		ci->vbus_edev = NULL;
+	}
+
 	reset_control_assert(reset);
 	usleep_range(10000, 12000);
 	reset_control_deassert(reset);
@@ -157,6 +195,14 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_mux;
 
+	ulpi_node = of_find_node_by_name(pdev->dev.of_node, "ulpi");
+	if (ulpi_node) {
+		phy_node = of_get_next_available_child(ulpi_node, NULL);
+		ci->hsic = of_device_is_compatible(phy_node, "qcom,usb-hsic-phy");
+		of_node_put(phy_node);
+	}
+	of_node_put(ulpi_node);
+
 	plat_ci = ci_hdrc_add_device(&pdev->dev, pdev->resource,
 				     pdev->num_resources, &ci_hdrc_msm_platdata);
 	if (IS_ERR(plat_ci)) {
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 17/21] usb: chipidea: msm: Make platform data driver local instead of global
  2016-06-26  7:28 ` Stephen Boyd
  (?)
@ 2016-06-26  7:28   ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb
  Cc: Felipe Balbi, Arnd Bergmann, Neil Armstrong, linux-arm-msm,
	linux-kernel, Bjorn Andersson, Peter Chen, Greg Kroah-Hartman,
	Andy Gross, linux-arm-kernel

If two devices are probed with this same driver, they'll share
the same platform data structure, while the chipidea core layer
writes and modifies it. This can lead to interesting results
especially if one device is an OTG type chipidea controller and
another is a host. Let's create a copy of this structure per each
device instance so that odd things don't happen.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/ci_hdrc_msm.c | 19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
index cc6f9b0df9d5..fb4340f02c16 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -37,6 +37,7 @@ struct ci_hdrc_msm {
 	struct clk *core_clk;
 	struct clk *iface_clk;
 	struct extcon_dev *vbus_edev;
+	struct ci_hdrc_platform_data pdata;
 	bool secondary_phy;
 	bool hsic;
 	void __iomem *base;
@@ -79,16 +80,6 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
 	}
 }
 
-static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
-	.name			= "ci_hdrc_msm",
-	.capoffset		= DEF_CAPOFFSET,
-	.flags			= CI_HDRC_REGS_SHARED |
-				  CI_HDRC_DISABLE_STREAMING |
-				  CI_HDRC_OVERRIDE_AHB_BURST,
-
-	.notify_event		= ci_hdrc_msm_notify_event,
-};
-
 static int ci_hdrc_msm_mux_phy(struct ci_hdrc_msm *ci,
 			       struct platform_device *pdev)
 {
@@ -151,6 +142,12 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	platform_set_drvdata(pdev, ci);
 
+	ci->pdata.name = "ci_hdrc_msm";
+	ci->pdata.capoffset = DEF_CAPOFFSET;
+	ci->pdata.flags	= CI_HDRC_REGS_SHARED | CI_HDRC_DISABLE_STREAMING |
+			  CI_HDRC_OVERRIDE_AHB_BURST;
+	ci->pdata.notify_event = ci_hdrc_msm_notify_event;
+
 	reset = devm_reset_control_get(&pdev->dev, "core");
 	if (IS_ERR(reset))
 		return PTR_ERR(reset);
@@ -204,7 +201,7 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
 	of_node_put(ulpi_node);
 
 	plat_ci = ci_hdrc_add_device(&pdev->dev, pdev->resource,
-				     pdev->num_resources, &ci_hdrc_msm_platdata);
+				     pdev->num_resources, &ci->pdata);
 	if (IS_ERR(plat_ci)) {
 		dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
 		ret = PTR_ERR(plat_ci);
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 17/21] usb: chipidea: msm: Make platform data driver local instead of global
@ 2016-06-26  7:28   ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb
  Cc: linux-arm-kernel, linux-kernel, linux-arm-msm, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Peter Chen, Greg Kroah-Hartman

If two devices are probed with this same driver, they'll share
the same platform data structure, while the chipidea core layer
writes and modifies it. This can lead to interesting results
especially if one device is an OTG type chipidea controller and
another is a host. Let's create a copy of this structure per each
device instance so that odd things don't happen.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/ci_hdrc_msm.c | 19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
index cc6f9b0df9d5..fb4340f02c16 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -37,6 +37,7 @@ struct ci_hdrc_msm {
 	struct clk *core_clk;
 	struct clk *iface_clk;
 	struct extcon_dev *vbus_edev;
+	struct ci_hdrc_platform_data pdata;
 	bool secondary_phy;
 	bool hsic;
 	void __iomem *base;
@@ -79,16 +80,6 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
 	}
 }
 
-static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
-	.name			= "ci_hdrc_msm",
-	.capoffset		= DEF_CAPOFFSET,
-	.flags			= CI_HDRC_REGS_SHARED |
-				  CI_HDRC_DISABLE_STREAMING |
-				  CI_HDRC_OVERRIDE_AHB_BURST,
-
-	.notify_event		= ci_hdrc_msm_notify_event,
-};
-
 static int ci_hdrc_msm_mux_phy(struct ci_hdrc_msm *ci,
 			       struct platform_device *pdev)
 {
@@ -151,6 +142,12 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	platform_set_drvdata(pdev, ci);
 
+	ci->pdata.name = "ci_hdrc_msm";
+	ci->pdata.capoffset = DEF_CAPOFFSET;
+	ci->pdata.flags	= CI_HDRC_REGS_SHARED | CI_HDRC_DISABLE_STREAMING |
+			  CI_HDRC_OVERRIDE_AHB_BURST;
+	ci->pdata.notify_event = ci_hdrc_msm_notify_event;
+
 	reset = devm_reset_control_get(&pdev->dev, "core");
 	if (IS_ERR(reset))
 		return PTR_ERR(reset);
@@ -204,7 +201,7 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
 	of_node_put(ulpi_node);
 
 	plat_ci = ci_hdrc_add_device(&pdev->dev, pdev->resource,
-				     pdev->num_resources, &ci_hdrc_msm_platdata);
+				     pdev->num_resources, &ci->pdata);
 	if (IS_ERR(plat_ci)) {
 		dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
 		ret = PTR_ERR(plat_ci);
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 17/21] usb: chipidea: msm: Make platform data driver local instead of global
@ 2016-06-26  7:28   ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-arm-kernel

If two devices are probed with this same driver, they'll share
the same platform data structure, while the chipidea core layer
writes and modifies it. This can lead to interesting results
especially if one device is an OTG type chipidea controller and
another is a host. Let's create a copy of this structure per each
device instance so that odd things don't happen.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/ci_hdrc_msm.c | 19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
index cc6f9b0df9d5..fb4340f02c16 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -37,6 +37,7 @@ struct ci_hdrc_msm {
 	struct clk *core_clk;
 	struct clk *iface_clk;
 	struct extcon_dev *vbus_edev;
+	struct ci_hdrc_platform_data pdata;
 	bool secondary_phy;
 	bool hsic;
 	void __iomem *base;
@@ -79,16 +80,6 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
 	}
 }
 
-static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
-	.name			= "ci_hdrc_msm",
-	.capoffset		= DEF_CAPOFFSET,
-	.flags			= CI_HDRC_REGS_SHARED |
-				  CI_HDRC_DISABLE_STREAMING |
-				  CI_HDRC_OVERRIDE_AHB_BURST,
-
-	.notify_event		= ci_hdrc_msm_notify_event,
-};
-
 static int ci_hdrc_msm_mux_phy(struct ci_hdrc_msm *ci,
 			       struct platform_device *pdev)
 {
@@ -151,6 +142,12 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	platform_set_drvdata(pdev, ci);
 
+	ci->pdata.name = "ci_hdrc_msm";
+	ci->pdata.capoffset = DEF_CAPOFFSET;
+	ci->pdata.flags	= CI_HDRC_REGS_SHARED | CI_HDRC_DISABLE_STREAMING |
+			  CI_HDRC_OVERRIDE_AHB_BURST;
+	ci->pdata.notify_event = ci_hdrc_msm_notify_event;
+
 	reset = devm_reset_control_get(&pdev->dev, "core");
 	if (IS_ERR(reset))
 		return PTR_ERR(reset);
@@ -204,7 +201,7 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
 	of_node_put(ulpi_node);
 
 	plat_ci = ci_hdrc_add_device(&pdev->dev, pdev->resource,
-				     pdev->num_resources, &ci_hdrc_msm_platdata);
+				     pdev->num_resources, &ci->pdata);
 	if (IS_ERR(plat_ci)) {
 		dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
 		ret = PTR_ERR(plat_ci);
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 18/21] usb: chipidea: msm: Add reset controller for PHY POR bit
  2016-06-26  7:28 ` Stephen Boyd
@ 2016-06-26  7:28   ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb
  Cc: linux-arm-kernel, linux-kernel, linux-arm-msm, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Peter Chen, Greg Kroah-Hartman

The MSM chipidea wrapper has two bits that are used to reset the
first or second phy. Add support for these bits via the reset
controller framework, so that phy drivers can reset their
hardware at the right time during initialization.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/ci_hdrc_msm.c | 43 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 42 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
index fb4340f02c16..7d191928e55b 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -14,14 +14,17 @@
 #include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
 #include <linux/io.h>
+#include <linux/reset-controller.h>
 #include <linux/extcon.h>
 #include <linux/of.h>
 
 #include "ci.h"
 
 #define HS_PHY_AHB_MODE			0x0098
+#define HS_PHY_CTRL			0x0240
 #define HS_PHY_SEC_CTRL			0x0278
 # define HS_PHY_DIG_CLAMP_N		BIT(16)
+# define HS_PHY_POR_ASSERT		BIT(0)
 
 #define HS_PHY_GENCONFIG		0x009c
 # define HS_PHY_TXFIFO_IDLE_FORCE_DIS	BIT(4)
@@ -38,11 +41,38 @@ struct ci_hdrc_msm {
 	struct clk *iface_clk;
 	struct extcon_dev *vbus_edev;
 	struct ci_hdrc_platform_data pdata;
+	struct reset_controller_dev rcdev;
 	bool secondary_phy;
 	bool hsic;
 	void __iomem *base;
 };
 
+static int
+ci_hdrc_msm_por_reset(struct reset_controller_dev *r, unsigned long id)
+{
+	struct ci_hdrc_msm *ci_msm = container_of(r, struct ci_hdrc_msm, rcdev);
+	void __iomem *addr = ci_msm->base;
+	u32 val;
+
+	if (id)
+		addr += HS_PHY_SEC_CTRL;
+	else
+		addr += HS_PHY_CTRL;
+
+	val = readl_relaxed(addr);
+	val |= HS_PHY_POR_ASSERT;
+	writel_relaxed(val, addr);
+	udelay(12);
+	val &= ~HS_PHY_POR_ASSERT;
+	writel(val, addr);
+
+	return 0;
+}
+
+static const struct reset_control_ops ci_hdrc_msm_reset_ops = {
+	.reset = ci_hdrc_msm_por_reset,
+};
+
 static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
 {
 	struct device *dev = ci->dev->parent;
@@ -176,13 +206,21 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
 		ci->vbus_edev = NULL;
 	}
 
+	ci->rcdev.owner = THIS_MODULE;
+	ci->rcdev.ops = &ci_hdrc_msm_reset_ops;
+	ci->rcdev.of_node = pdev->dev.of_node;
+	ci->rcdev.nr_resets = 2;
+	ret = reset_controller_register(&ci->rcdev);
+	if (ret)
+		return ret;
+
 	reset_control_assert(reset);
 	usleep_range(10000, 12000);
 	reset_control_deassert(reset);
 
 	ret = clk_prepare_enable(ci->core_clk);
 	if (ret)
-		return ret;
+		goto err_core;
 
 	ret = clk_prepare_enable(ci->iface_clk);
 	if (ret)
@@ -220,6 +258,8 @@ err_mux:
 	clk_disable_unprepare(ci->iface_clk);
 err_iface:
 	clk_disable_unprepare(ci->core_clk);
+err_core:
+	reset_controller_unregister(&ci->rcdev);
 	return ret;
 }
 
@@ -232,6 +272,7 @@ static int ci_hdrc_msm_remove(struct platform_device *pdev)
 	ci_hdrc_remove_device(ci->ci);
 	clk_disable_unprepare(ci->iface_clk);
 	clk_disable_unprepare(ci->core_clk);
+	reset_controller_unregister(&ci->rcdev);
 
 	return 0;
 }
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 18/21] usb: chipidea: msm: Add reset controller for PHY POR bit
@ 2016-06-26  7:28   ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-arm-kernel

The MSM chipidea wrapper has two bits that are used to reset the
first or second phy. Add support for these bits via the reset
controller framework, so that phy drivers can reset their
hardware at the right time during initialization.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/ci_hdrc_msm.c | 43 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 42 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
index fb4340f02c16..7d191928e55b 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -14,14 +14,17 @@
 #include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
 #include <linux/io.h>
+#include <linux/reset-controller.h>
 #include <linux/extcon.h>
 #include <linux/of.h>
 
 #include "ci.h"
 
 #define HS_PHY_AHB_MODE			0x0098
+#define HS_PHY_CTRL			0x0240
 #define HS_PHY_SEC_CTRL			0x0278
 # define HS_PHY_DIG_CLAMP_N		BIT(16)
+# define HS_PHY_POR_ASSERT		BIT(0)
 
 #define HS_PHY_GENCONFIG		0x009c
 # define HS_PHY_TXFIFO_IDLE_FORCE_DIS	BIT(4)
@@ -38,11 +41,38 @@ struct ci_hdrc_msm {
 	struct clk *iface_clk;
 	struct extcon_dev *vbus_edev;
 	struct ci_hdrc_platform_data pdata;
+	struct reset_controller_dev rcdev;
 	bool secondary_phy;
 	bool hsic;
 	void __iomem *base;
 };
 
+static int
+ci_hdrc_msm_por_reset(struct reset_controller_dev *r, unsigned long id)
+{
+	struct ci_hdrc_msm *ci_msm = container_of(r, struct ci_hdrc_msm, rcdev);
+	void __iomem *addr = ci_msm->base;
+	u32 val;
+
+	if (id)
+		addr += HS_PHY_SEC_CTRL;
+	else
+		addr += HS_PHY_CTRL;
+
+	val = readl_relaxed(addr);
+	val |= HS_PHY_POR_ASSERT;
+	writel_relaxed(val, addr);
+	udelay(12);
+	val &= ~HS_PHY_POR_ASSERT;
+	writel(val, addr);
+
+	return 0;
+}
+
+static const struct reset_control_ops ci_hdrc_msm_reset_ops = {
+	.reset = ci_hdrc_msm_por_reset,
+};
+
 static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
 {
 	struct device *dev = ci->dev->parent;
@@ -176,13 +206,21 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
 		ci->vbus_edev = NULL;
 	}
 
+	ci->rcdev.owner = THIS_MODULE;
+	ci->rcdev.ops = &ci_hdrc_msm_reset_ops;
+	ci->rcdev.of_node = pdev->dev.of_node;
+	ci->rcdev.nr_resets = 2;
+	ret = reset_controller_register(&ci->rcdev);
+	if (ret)
+		return ret;
+
 	reset_control_assert(reset);
 	usleep_range(10000, 12000);
 	reset_control_deassert(reset);
 
 	ret = clk_prepare_enable(ci->core_clk);
 	if (ret)
-		return ret;
+		goto err_core;
 
 	ret = clk_prepare_enable(ci->iface_clk);
 	if (ret)
@@ -220,6 +258,8 @@ err_mux:
 	clk_disable_unprepare(ci->iface_clk);
 err_iface:
 	clk_disable_unprepare(ci->core_clk);
+err_core:
+	reset_controller_unregister(&ci->rcdev);
 	return ret;
 }
 
@@ -232,6 +272,7 @@ static int ci_hdrc_msm_remove(struct platform_device *pdev)
 	ci_hdrc_remove_device(ci->ci);
 	clk_disable_unprepare(ci->iface_clk);
 	clk_disable_unprepare(ci->core_clk);
+	reset_controller_unregister(&ci->rcdev);
 
 	return 0;
 }
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 19/21] usb: chipidea: msm: Be silent on probe defer errors
  2016-06-26  7:28 ` Stephen Boyd
@ 2016-06-26  7:28   ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb
  Cc: linux-arm-kernel, linux-kernel, linux-arm-msm, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Peter Chen, Greg Kroah-Hartman

If something fails in ci_hdrc_add_device() due to probe defer, we
shouldn't print an error message. Be silent in this case as we'll
try probe again later.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/ci_hdrc_msm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
index 7d191928e55b..2ed9a181f4b6 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -241,7 +241,8 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
 	plat_ci = ci_hdrc_add_device(&pdev->dev, pdev->resource,
 				     pdev->num_resources, &ci->pdata);
 	if (IS_ERR(plat_ci)) {
-		dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
+		if (PTR_ERR(plat_ci) != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
 		ret = PTR_ERR(plat_ci);
 		goto err_mux;
 	}
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 19/21] usb: chipidea: msm: Be silent on probe defer errors
@ 2016-06-26  7:28   ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-arm-kernel

If something fails in ci_hdrc_add_device() due to probe defer, we
shouldn't print an error message. Be silent in this case as we'll
try probe again later.

Cc: Peter Chen <peter.chen@nxp.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 drivers/usb/chipidea/ci_hdrc_msm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
index 7d191928e55b..2ed9a181f4b6 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -241,7 +241,8 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
 	plat_ci = ci_hdrc_add_device(&pdev->dev, pdev->resource,
 				     pdev->num_resources, &ci->pdata);
 	if (IS_ERR(plat_ci)) {
-		dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
+		if (PTR_ERR(plat_ci) != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
 		ret = PTR_ERR(plat_ci);
 		goto err_mux;
 	}
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 20/21] phy: Add support for Qualcomm's USB HSIC phy
  2016-06-26  7:28 ` Stephen Boyd
  (?)
@ 2016-06-26  7:28     ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Kishon Vijay Abraham I, devicetree-u79uwXL29TY76Z2rM5mHXA

The HSIC USB controller on qcom SoCs has an integrated all
digital phy controlled via the ULPI viewport.

Cc: Kishon Vijay Abraham I <kishon-l0cyMroinI0@public.gmane.org>
Cc: <devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>
Signed-off-by: Stephen Boyd <stephen.boyd-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 .../devicetree/bindings/phy/qcom,usb-hsic-phy.txt  |  60 ++++++++
 drivers/phy/Kconfig                                |   7 +
 drivers/phy/Makefile                               |   1 +
 drivers/phy/phy-qcom-usb-hsic.c                    | 161 +++++++++++++++++++++
 4 files changed, 229 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt
 create mode 100644 drivers/phy/phy-qcom-usb-hsic.c

diff --git a/Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt b/Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt
new file mode 100644
index 000000000000..6b1c6aad2962
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt
@@ -0,0 +1,60 @@
+Qualcomm's USB HSIC PHY
+
+PROPERTIES
+
+- compatible:
+    Usage: required
+    Value type: <string>
+    Definition: Should contain "qcom,usb-hsic-phy"
+
+- #phy-cells:
+    Usage: required
+    Value type: <u32>
+    Definition: Should contain 0
+
+- clocks:
+    Usage: required
+    Value type: <prop-encoded-array>
+    Definition: Should contain clock specifier for phy, calibration and
+                optionally a calibration sleep clock
+
+- clock-names:
+    Usage: required
+    Value type: <stringlist>
+    Definition: Should contain "phy, "cal" and optionally "cal_sleep"
+
+- pinctrl-names:
+    Usage: required
+    Value type: <stringlist>
+    Definition: Should contain "init" and "default" in that order
+
+- pinctrl-0:
+    Usage: required
+    Value type: <prop-encoded-array>
+    Definition: List of pinctrl settings to apply to keep HSIC pins in a glitch
+                free state
+
+- pinctrl-1:
+    Usage: required
+    Value type: <prop-encoded-array>
+    Definition: List of pinctrl settings to apply to mux out the HSIC pins
+
+EXAMPLE
+
+usb-controller {
+	ulpi {
+		phy {
+			compatible = "qcom,usb-hsic-phy";
+			#phy-cells = <0>;
+			pinctrl-names = "init", "default";
+			pinctrl-0 = <&hsic_sleep>;
+			pinctrl-1 = <&hsic_default>;
+			clocks = <&gcc GCC_USB_HSIC_CLK>,
+				 <&gcc GCC_USB_HSIC_IO_CAL_CLK>,
+				 <&gcc GCC_USB_HSIC_IO_CAL_SLEEP_CLK>;
+			clock-names = "phy", "cal", "cal_sleep";
+			assigned-clocks = <&gcc GCC_USB_HSIC_IO_CAL_CLK>;
+			assigned-clock-rates = <960000>;
+		};
+	};
+};
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index b869b98835f4..a2866949dc97 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -406,6 +406,13 @@ config PHY_QCOM_UFS
 	help
 	  Support for UFS PHY on QCOM chipsets.
 
+config PHY_QCOM_USB_HSIC
+	tristate "Qualcomm USB HSIC ULPI PHY module"
+	depends on USB_ULPI_BUS
+	select GENERIC_PHY
+	help
+	  Support for the USB HSIC ULPI compliant PHY on QCOM chipsets.
+
 config PHY_TUSB1210
 	tristate "TI TUSB1210 ULPI PHY module"
 	depends on USB_ULPI_BUS
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 9c3e73ccabc4..982e84a290ec 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_PHY_STIH41X_USB)		+= phy-stih41x-usb.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs-qmp-20nm.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs-qmp-14nm.o
+obj-$(CONFIG_PHY_QCOM_USB_HSIC) 	+= phy-qcom-usb-hsic.o
 obj-$(CONFIG_PHY_TUSB1210)		+= phy-tusb1210.o
 obj-$(CONFIG_PHY_BRCM_SATA)		+= phy-brcm-sata.o
 obj-$(CONFIG_PHY_PISTACHIO_USB)		+= phy-pistachio-usb.o
diff --git a/drivers/phy/phy-qcom-usb-hsic.c b/drivers/phy/phy-qcom-usb-hsic.c
new file mode 100644
index 000000000000..a81b2f8bfe37
--- /dev/null
+++ b/drivers/phy/phy-qcom-usb-hsic.c
@@ -0,0 +1,161 @@
+/**
+ * Copyright (C) 2016 Linaro Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/ulpi/driver.h>
+#include <linux/ulpi/regs.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/pinctrl/pinctrl-state.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+
+#include "ulpi_phy.h"
+
+#define ULPI_HSIC_CFG		0x30
+#define ULPI_HSIC_IO_CAL	0x33
+
+struct qcom_usb_hsic_phy {
+	struct ulpi *ulpi;
+	struct phy *phy;
+	struct pinctrl *pctl;
+	struct clk *phy_clk;
+	struct clk *cal_clk;
+	struct clk *cal_sleep_clk;
+};
+
+static int qcom_usb_hsic_phy_power_on(struct phy *phy)
+{
+	struct qcom_usb_hsic_phy *uphy = phy_get_drvdata(phy);
+	struct ulpi *ulpi = uphy->ulpi;
+	struct pinctrl_state *pins_default;
+	int ret;
+
+	ret = clk_prepare_enable(uphy->phy_clk);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(uphy->cal_clk);
+	if (ret)
+		goto err_cal;
+
+	ret = clk_prepare_enable(uphy->cal_sleep_clk);
+	if (ret)
+		goto err_sleep;
+
+	/* Set periodic calibration interval to ~2.048sec in HSIC_IO_CAL_REG */
+	ret = ulpi_write(ulpi, ULPI_HSIC_IO_CAL, 0xff);
+	if (ret)
+		goto err_ulpi;
+
+	/* Enable periodic IO calibration in HSIC_CFG register */
+	ret = ulpi_write(ulpi, ULPI_HSIC_CFG, 0xa8);
+	if (ret)
+		goto err_ulpi;
+
+	/* Configure pins for HSIC functionality */
+	pins_default = pinctrl_lookup_state(uphy->pctl, PINCTRL_STATE_DEFAULT);
+	if (IS_ERR(pins_default))
+		return PTR_ERR(pins_default);
+
+	ret = pinctrl_select_state(uphy->pctl, pins_default);
+	if (ret)
+		goto err_ulpi;
+
+	 /* Enable HSIC mode in HSIC_CFG register */
+	ret = ulpi_write(ulpi, ULPI_SET(ULPI_HSIC_CFG), 0x01);
+	if (ret)
+		goto err_ulpi;
+
+	/* Disable auto-resume */
+	ret = ulpi_write(ulpi, ULPI_CLR(ULPI_IFC_CTRL),
+			 ULPI_IFC_CTRL_AUTORESUME);
+	if (ret)
+		goto err_ulpi;
+
+	return ret;
+err_ulpi:
+	clk_disable_unprepare(uphy->cal_sleep_clk);
+err_sleep:
+	clk_disable_unprepare(uphy->cal_clk);
+err_cal:
+	clk_disable_unprepare(uphy->phy_clk);
+	return ret;
+}
+
+static int qcom_usb_hsic_phy_power_off(struct phy *phy)
+{
+	struct qcom_usb_hsic_phy *uphy = phy_get_drvdata(phy);
+
+	clk_disable_unprepare(uphy->cal_sleep_clk);
+	clk_disable_unprepare(uphy->cal_clk);
+	clk_disable_unprepare(uphy->phy_clk);
+
+	return 0;
+}
+
+static const struct phy_ops qcom_usb_hsic_phy_ops = {
+	.power_on = qcom_usb_hsic_phy_power_on,
+	.power_off = qcom_usb_hsic_phy_power_off,
+	.owner = THIS_MODULE,
+};
+
+static int qcom_usb_hsic_phy_probe(struct ulpi *ulpi)
+{
+	struct qcom_usb_hsic_phy *uphy;
+	struct phy_provider *p;
+	struct clk *clk;
+
+	uphy = devm_kzalloc(&ulpi->dev, sizeof(*uphy), GFP_KERNEL);
+	if (!uphy)
+		return -ENOMEM;
+	ulpi_set_drvdata(ulpi, uphy);
+
+	uphy->ulpi = ulpi;
+	uphy->pctl = devm_pinctrl_get(&ulpi->dev);
+	if (IS_ERR(uphy->pctl))
+		return PTR_ERR(uphy->pctl);
+
+	uphy->phy_clk = clk = devm_clk_get(&ulpi->dev, "phy");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	uphy->cal_clk = clk = devm_clk_get(&ulpi->dev, "cal");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	uphy->cal_sleep_clk = clk = devm_clk_get(&ulpi->dev, "cal_sleep");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	uphy->phy = devm_phy_create(&ulpi->dev, ulpi->dev.of_node,
+				    &qcom_usb_hsic_phy_ops);
+	if (IS_ERR(uphy->phy))
+		return PTR_ERR(uphy->phy);
+	phy_set_drvdata(uphy->phy, uphy);
+
+	p = devm_of_phy_provider_register(&ulpi->dev, of_phy_simple_xlate);
+	return PTR_ERR_OR_ZERO(p);
+}
+
+
+static const struct of_device_id qcom_usb_hsic_phy_match[] = {
+	{ .compatible = "qcom,usb-hsic-phy", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, qcom_usb_hsic_phy_match);
+
+static struct ulpi_driver qcom_usb_hsic_phy_driver = {
+	.probe = qcom_usb_hsic_phy_probe,
+	.driver = {
+		.name = "qcom_usb_hsic_phy",
+		.of_match_table = qcom_usb_hsic_phy_match
+	},
+};
+module_ulpi_driver(qcom_usb_hsic_phy_driver);
+
+MODULE_DESCRIPTION("Qualcomm USB HSIC phy");
+MODULE_LICENSE("GPL v2");
-- 
2.9.0.rc2.8.ga28705d

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 20/21] phy: Add support for Qualcomm's USB HSIC phy
@ 2016-06-26  7:28     ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb
  Cc: linux-arm-kernel, linux-kernel, linux-arm-msm, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Kishon Vijay Abraham I, devicetree

The HSIC USB controller on qcom SoCs has an integrated all
digital phy controlled via the ULPI viewport.

Cc: Kishon Vijay Abraham I <kishon@ti.com>
Cc: <devicetree@vger.kernel.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 .../devicetree/bindings/phy/qcom,usb-hsic-phy.txt  |  60 ++++++++
 drivers/phy/Kconfig                                |   7 +
 drivers/phy/Makefile                               |   1 +
 drivers/phy/phy-qcom-usb-hsic.c                    | 161 +++++++++++++++++++++
 4 files changed, 229 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt
 create mode 100644 drivers/phy/phy-qcom-usb-hsic.c

diff --git a/Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt b/Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt
new file mode 100644
index 000000000000..6b1c6aad2962
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt
@@ -0,0 +1,60 @@
+Qualcomm's USB HSIC PHY
+
+PROPERTIES
+
+- compatible:
+    Usage: required
+    Value type: <string>
+    Definition: Should contain "qcom,usb-hsic-phy"
+
+- #phy-cells:
+    Usage: required
+    Value type: <u32>
+    Definition: Should contain 0
+
+- clocks:
+    Usage: required
+    Value type: <prop-encoded-array>
+    Definition: Should contain clock specifier for phy, calibration and
+                optionally a calibration sleep clock
+
+- clock-names:
+    Usage: required
+    Value type: <stringlist>
+    Definition: Should contain "phy, "cal" and optionally "cal_sleep"
+
+- pinctrl-names:
+    Usage: required
+    Value type: <stringlist>
+    Definition: Should contain "init" and "default" in that order
+
+- pinctrl-0:
+    Usage: required
+    Value type: <prop-encoded-array>
+    Definition: List of pinctrl settings to apply to keep HSIC pins in a glitch
+                free state
+
+- pinctrl-1:
+    Usage: required
+    Value type: <prop-encoded-array>
+    Definition: List of pinctrl settings to apply to mux out the HSIC pins
+
+EXAMPLE
+
+usb-controller {
+	ulpi {
+		phy {
+			compatible = "qcom,usb-hsic-phy";
+			#phy-cells = <0>;
+			pinctrl-names = "init", "default";
+			pinctrl-0 = <&hsic_sleep>;
+			pinctrl-1 = <&hsic_default>;
+			clocks = <&gcc GCC_USB_HSIC_CLK>,
+				 <&gcc GCC_USB_HSIC_IO_CAL_CLK>,
+				 <&gcc GCC_USB_HSIC_IO_CAL_SLEEP_CLK>;
+			clock-names = "phy", "cal", "cal_sleep";
+			assigned-clocks = <&gcc GCC_USB_HSIC_IO_CAL_CLK>;
+			assigned-clock-rates = <960000>;
+		};
+	};
+};
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index b869b98835f4..a2866949dc97 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -406,6 +406,13 @@ config PHY_QCOM_UFS
 	help
 	  Support for UFS PHY on QCOM chipsets.
 
+config PHY_QCOM_USB_HSIC
+	tristate "Qualcomm USB HSIC ULPI PHY module"
+	depends on USB_ULPI_BUS
+	select GENERIC_PHY
+	help
+	  Support for the USB HSIC ULPI compliant PHY on QCOM chipsets.
+
 config PHY_TUSB1210
 	tristate "TI TUSB1210 ULPI PHY module"
 	depends on USB_ULPI_BUS
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 9c3e73ccabc4..982e84a290ec 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_PHY_STIH41X_USB)		+= phy-stih41x-usb.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs-qmp-20nm.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs-qmp-14nm.o
+obj-$(CONFIG_PHY_QCOM_USB_HSIC) 	+= phy-qcom-usb-hsic.o
 obj-$(CONFIG_PHY_TUSB1210)		+= phy-tusb1210.o
 obj-$(CONFIG_PHY_BRCM_SATA)		+= phy-brcm-sata.o
 obj-$(CONFIG_PHY_PISTACHIO_USB)		+= phy-pistachio-usb.o
diff --git a/drivers/phy/phy-qcom-usb-hsic.c b/drivers/phy/phy-qcom-usb-hsic.c
new file mode 100644
index 000000000000..a81b2f8bfe37
--- /dev/null
+++ b/drivers/phy/phy-qcom-usb-hsic.c
@@ -0,0 +1,161 @@
+/**
+ * Copyright (C) 2016 Linaro Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/ulpi/driver.h>
+#include <linux/ulpi/regs.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/pinctrl/pinctrl-state.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+
+#include "ulpi_phy.h"
+
+#define ULPI_HSIC_CFG		0x30
+#define ULPI_HSIC_IO_CAL	0x33
+
+struct qcom_usb_hsic_phy {
+	struct ulpi *ulpi;
+	struct phy *phy;
+	struct pinctrl *pctl;
+	struct clk *phy_clk;
+	struct clk *cal_clk;
+	struct clk *cal_sleep_clk;
+};
+
+static int qcom_usb_hsic_phy_power_on(struct phy *phy)
+{
+	struct qcom_usb_hsic_phy *uphy = phy_get_drvdata(phy);
+	struct ulpi *ulpi = uphy->ulpi;
+	struct pinctrl_state *pins_default;
+	int ret;
+
+	ret = clk_prepare_enable(uphy->phy_clk);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(uphy->cal_clk);
+	if (ret)
+		goto err_cal;
+
+	ret = clk_prepare_enable(uphy->cal_sleep_clk);
+	if (ret)
+		goto err_sleep;
+
+	/* Set periodic calibration interval to ~2.048sec in HSIC_IO_CAL_REG */
+	ret = ulpi_write(ulpi, ULPI_HSIC_IO_CAL, 0xff);
+	if (ret)
+		goto err_ulpi;
+
+	/* Enable periodic IO calibration in HSIC_CFG register */
+	ret = ulpi_write(ulpi, ULPI_HSIC_CFG, 0xa8);
+	if (ret)
+		goto err_ulpi;
+
+	/* Configure pins for HSIC functionality */
+	pins_default = pinctrl_lookup_state(uphy->pctl, PINCTRL_STATE_DEFAULT);
+	if (IS_ERR(pins_default))
+		return PTR_ERR(pins_default);
+
+	ret = pinctrl_select_state(uphy->pctl, pins_default);
+	if (ret)
+		goto err_ulpi;
+
+	 /* Enable HSIC mode in HSIC_CFG register */
+	ret = ulpi_write(ulpi, ULPI_SET(ULPI_HSIC_CFG), 0x01);
+	if (ret)
+		goto err_ulpi;
+
+	/* Disable auto-resume */
+	ret = ulpi_write(ulpi, ULPI_CLR(ULPI_IFC_CTRL),
+			 ULPI_IFC_CTRL_AUTORESUME);
+	if (ret)
+		goto err_ulpi;
+
+	return ret;
+err_ulpi:
+	clk_disable_unprepare(uphy->cal_sleep_clk);
+err_sleep:
+	clk_disable_unprepare(uphy->cal_clk);
+err_cal:
+	clk_disable_unprepare(uphy->phy_clk);
+	return ret;
+}
+
+static int qcom_usb_hsic_phy_power_off(struct phy *phy)
+{
+	struct qcom_usb_hsic_phy *uphy = phy_get_drvdata(phy);
+
+	clk_disable_unprepare(uphy->cal_sleep_clk);
+	clk_disable_unprepare(uphy->cal_clk);
+	clk_disable_unprepare(uphy->phy_clk);
+
+	return 0;
+}
+
+static const struct phy_ops qcom_usb_hsic_phy_ops = {
+	.power_on = qcom_usb_hsic_phy_power_on,
+	.power_off = qcom_usb_hsic_phy_power_off,
+	.owner = THIS_MODULE,
+};
+
+static int qcom_usb_hsic_phy_probe(struct ulpi *ulpi)
+{
+	struct qcom_usb_hsic_phy *uphy;
+	struct phy_provider *p;
+	struct clk *clk;
+
+	uphy = devm_kzalloc(&ulpi->dev, sizeof(*uphy), GFP_KERNEL);
+	if (!uphy)
+		return -ENOMEM;
+	ulpi_set_drvdata(ulpi, uphy);
+
+	uphy->ulpi = ulpi;
+	uphy->pctl = devm_pinctrl_get(&ulpi->dev);
+	if (IS_ERR(uphy->pctl))
+		return PTR_ERR(uphy->pctl);
+
+	uphy->phy_clk = clk = devm_clk_get(&ulpi->dev, "phy");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	uphy->cal_clk = clk = devm_clk_get(&ulpi->dev, "cal");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	uphy->cal_sleep_clk = clk = devm_clk_get(&ulpi->dev, "cal_sleep");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	uphy->phy = devm_phy_create(&ulpi->dev, ulpi->dev.of_node,
+				    &qcom_usb_hsic_phy_ops);
+	if (IS_ERR(uphy->phy))
+		return PTR_ERR(uphy->phy);
+	phy_set_drvdata(uphy->phy, uphy);
+
+	p = devm_of_phy_provider_register(&ulpi->dev, of_phy_simple_xlate);
+	return PTR_ERR_OR_ZERO(p);
+}
+
+
+static const struct of_device_id qcom_usb_hsic_phy_match[] = {
+	{ .compatible = "qcom,usb-hsic-phy", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, qcom_usb_hsic_phy_match);
+
+static struct ulpi_driver qcom_usb_hsic_phy_driver = {
+	.probe = qcom_usb_hsic_phy_probe,
+	.driver = {
+		.name = "qcom_usb_hsic_phy",
+		.of_match_table = qcom_usb_hsic_phy_match
+	},
+};
+module_ulpi_driver(qcom_usb_hsic_phy_driver);
+
+MODULE_DESCRIPTION("Qualcomm USB HSIC phy");
+MODULE_LICENSE("GPL v2");
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 20/21] phy: Add support for Qualcomm's USB HSIC phy
@ 2016-06-26  7:28     ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-arm-kernel

The HSIC USB controller on qcom SoCs has an integrated all
digital phy controlled via the ULPI viewport.

Cc: Kishon Vijay Abraham I <kishon@ti.com>
Cc: <devicetree@vger.kernel.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 .../devicetree/bindings/phy/qcom,usb-hsic-phy.txt  |  60 ++++++++
 drivers/phy/Kconfig                                |   7 +
 drivers/phy/Makefile                               |   1 +
 drivers/phy/phy-qcom-usb-hsic.c                    | 161 +++++++++++++++++++++
 4 files changed, 229 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt
 create mode 100644 drivers/phy/phy-qcom-usb-hsic.c

diff --git a/Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt b/Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt
new file mode 100644
index 000000000000..6b1c6aad2962
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt
@@ -0,0 +1,60 @@
+Qualcomm's USB HSIC PHY
+
+PROPERTIES
+
+- compatible:
+    Usage: required
+    Value type: <string>
+    Definition: Should contain "qcom,usb-hsic-phy"
+
+- #phy-cells:
+    Usage: required
+    Value type: <u32>
+    Definition: Should contain 0
+
+- clocks:
+    Usage: required
+    Value type: <prop-encoded-array>
+    Definition: Should contain clock specifier for phy, calibration and
+                optionally a calibration sleep clock
+
+- clock-names:
+    Usage: required
+    Value type: <stringlist>
+    Definition: Should contain "phy, "cal" and optionally "cal_sleep"
+
+- pinctrl-names:
+    Usage: required
+    Value type: <stringlist>
+    Definition: Should contain "init" and "default" in that order
+
+- pinctrl-0:
+    Usage: required
+    Value type: <prop-encoded-array>
+    Definition: List of pinctrl settings to apply to keep HSIC pins in a glitch
+                free state
+
+- pinctrl-1:
+    Usage: required
+    Value type: <prop-encoded-array>
+    Definition: List of pinctrl settings to apply to mux out the HSIC pins
+
+EXAMPLE
+
+usb-controller {
+	ulpi {
+		phy {
+			compatible = "qcom,usb-hsic-phy";
+			#phy-cells = <0>;
+			pinctrl-names = "init", "default";
+			pinctrl-0 = <&hsic_sleep>;
+			pinctrl-1 = <&hsic_default>;
+			clocks = <&gcc GCC_USB_HSIC_CLK>,
+				 <&gcc GCC_USB_HSIC_IO_CAL_CLK>,
+				 <&gcc GCC_USB_HSIC_IO_CAL_SLEEP_CLK>;
+			clock-names = "phy", "cal", "cal_sleep";
+			assigned-clocks = <&gcc GCC_USB_HSIC_IO_CAL_CLK>;
+			assigned-clock-rates = <960000>;
+		};
+	};
+};
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index b869b98835f4..a2866949dc97 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -406,6 +406,13 @@ config PHY_QCOM_UFS
 	help
 	  Support for UFS PHY on QCOM chipsets.
 
+config PHY_QCOM_USB_HSIC
+	tristate "Qualcomm USB HSIC ULPI PHY module"
+	depends on USB_ULPI_BUS
+	select GENERIC_PHY
+	help
+	  Support for the USB HSIC ULPI compliant PHY on QCOM chipsets.
+
 config PHY_TUSB1210
 	tristate "TI TUSB1210 ULPI PHY module"
 	depends on USB_ULPI_BUS
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 9c3e73ccabc4..982e84a290ec 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_PHY_STIH41X_USB)		+= phy-stih41x-usb.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs-qmp-20nm.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs-qmp-14nm.o
+obj-$(CONFIG_PHY_QCOM_USB_HSIC) 	+= phy-qcom-usb-hsic.o
 obj-$(CONFIG_PHY_TUSB1210)		+= phy-tusb1210.o
 obj-$(CONFIG_PHY_BRCM_SATA)		+= phy-brcm-sata.o
 obj-$(CONFIG_PHY_PISTACHIO_USB)		+= phy-pistachio-usb.o
diff --git a/drivers/phy/phy-qcom-usb-hsic.c b/drivers/phy/phy-qcom-usb-hsic.c
new file mode 100644
index 000000000000..a81b2f8bfe37
--- /dev/null
+++ b/drivers/phy/phy-qcom-usb-hsic.c
@@ -0,0 +1,161 @@
+/**
+ * Copyright (C) 2016 Linaro Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/ulpi/driver.h>
+#include <linux/ulpi/regs.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/pinctrl/pinctrl-state.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+
+#include "ulpi_phy.h"
+
+#define ULPI_HSIC_CFG		0x30
+#define ULPI_HSIC_IO_CAL	0x33
+
+struct qcom_usb_hsic_phy {
+	struct ulpi *ulpi;
+	struct phy *phy;
+	struct pinctrl *pctl;
+	struct clk *phy_clk;
+	struct clk *cal_clk;
+	struct clk *cal_sleep_clk;
+};
+
+static int qcom_usb_hsic_phy_power_on(struct phy *phy)
+{
+	struct qcom_usb_hsic_phy *uphy = phy_get_drvdata(phy);
+	struct ulpi *ulpi = uphy->ulpi;
+	struct pinctrl_state *pins_default;
+	int ret;
+
+	ret = clk_prepare_enable(uphy->phy_clk);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(uphy->cal_clk);
+	if (ret)
+		goto err_cal;
+
+	ret = clk_prepare_enable(uphy->cal_sleep_clk);
+	if (ret)
+		goto err_sleep;
+
+	/* Set periodic calibration interval to ~2.048sec in HSIC_IO_CAL_REG */
+	ret = ulpi_write(ulpi, ULPI_HSIC_IO_CAL, 0xff);
+	if (ret)
+		goto err_ulpi;
+
+	/* Enable periodic IO calibration in HSIC_CFG register */
+	ret = ulpi_write(ulpi, ULPI_HSIC_CFG, 0xa8);
+	if (ret)
+		goto err_ulpi;
+
+	/* Configure pins for HSIC functionality */
+	pins_default = pinctrl_lookup_state(uphy->pctl, PINCTRL_STATE_DEFAULT);
+	if (IS_ERR(pins_default))
+		return PTR_ERR(pins_default);
+
+	ret = pinctrl_select_state(uphy->pctl, pins_default);
+	if (ret)
+		goto err_ulpi;
+
+	 /* Enable HSIC mode in HSIC_CFG register */
+	ret = ulpi_write(ulpi, ULPI_SET(ULPI_HSIC_CFG), 0x01);
+	if (ret)
+		goto err_ulpi;
+
+	/* Disable auto-resume */
+	ret = ulpi_write(ulpi, ULPI_CLR(ULPI_IFC_CTRL),
+			 ULPI_IFC_CTRL_AUTORESUME);
+	if (ret)
+		goto err_ulpi;
+
+	return ret;
+err_ulpi:
+	clk_disable_unprepare(uphy->cal_sleep_clk);
+err_sleep:
+	clk_disable_unprepare(uphy->cal_clk);
+err_cal:
+	clk_disable_unprepare(uphy->phy_clk);
+	return ret;
+}
+
+static int qcom_usb_hsic_phy_power_off(struct phy *phy)
+{
+	struct qcom_usb_hsic_phy *uphy = phy_get_drvdata(phy);
+
+	clk_disable_unprepare(uphy->cal_sleep_clk);
+	clk_disable_unprepare(uphy->cal_clk);
+	clk_disable_unprepare(uphy->phy_clk);
+
+	return 0;
+}
+
+static const struct phy_ops qcom_usb_hsic_phy_ops = {
+	.power_on = qcom_usb_hsic_phy_power_on,
+	.power_off = qcom_usb_hsic_phy_power_off,
+	.owner = THIS_MODULE,
+};
+
+static int qcom_usb_hsic_phy_probe(struct ulpi *ulpi)
+{
+	struct qcom_usb_hsic_phy *uphy;
+	struct phy_provider *p;
+	struct clk *clk;
+
+	uphy = devm_kzalloc(&ulpi->dev, sizeof(*uphy), GFP_KERNEL);
+	if (!uphy)
+		return -ENOMEM;
+	ulpi_set_drvdata(ulpi, uphy);
+
+	uphy->ulpi = ulpi;
+	uphy->pctl = devm_pinctrl_get(&ulpi->dev);
+	if (IS_ERR(uphy->pctl))
+		return PTR_ERR(uphy->pctl);
+
+	uphy->phy_clk = clk = devm_clk_get(&ulpi->dev, "phy");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	uphy->cal_clk = clk = devm_clk_get(&ulpi->dev, "cal");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	uphy->cal_sleep_clk = clk = devm_clk_get(&ulpi->dev, "cal_sleep");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	uphy->phy = devm_phy_create(&ulpi->dev, ulpi->dev.of_node,
+				    &qcom_usb_hsic_phy_ops);
+	if (IS_ERR(uphy->phy))
+		return PTR_ERR(uphy->phy);
+	phy_set_drvdata(uphy->phy, uphy);
+
+	p = devm_of_phy_provider_register(&ulpi->dev, of_phy_simple_xlate);
+	return PTR_ERR_OR_ZERO(p);
+}
+
+
+static const struct of_device_id qcom_usb_hsic_phy_match[] = {
+	{ .compatible = "qcom,usb-hsic-phy", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, qcom_usb_hsic_phy_match);
+
+static struct ulpi_driver qcom_usb_hsic_phy_driver = {
+	.probe = qcom_usb_hsic_phy_probe,
+	.driver = {
+		.name = "qcom_usb_hsic_phy",
+		.of_match_table = qcom_usb_hsic_phy_match
+	},
+};
+module_ulpi_driver(qcom_usb_hsic_phy_driver);
+
+MODULE_DESCRIPTION("Qualcomm USB HSIC phy");
+MODULE_LICENSE("GPL v2");
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 21/21] phy: Add support for Qualcomm's USB HS phy
  2016-06-26  7:28 ` Stephen Boyd
  (?)
@ 2016-06-26  7:28     ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Kishon Vijay Abraham I, devicetree-u79uwXL29TY76Z2rM5mHXA

The high-speed phy on qcom SoCs is controlled via the ULPI
viewport.

Cc: Kishon Vijay Abraham I <kishon-l0cyMroinI0@public.gmane.org>
Cc: <devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>
Signed-off-by: Stephen Boyd <stephen.boyd-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 .../devicetree/bindings/phy/qcom,usb-hs-phy.txt    |  71 ++++++
 drivers/phy/Kconfig                                |   8 +
 drivers/phy/Makefile                               |   1 +
 drivers/phy/phy-qcom-usb-hs.c                      | 283 +++++++++++++++++++++
 4 files changed, 363 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/qcom,usb-hs-phy.txt
 create mode 100644 drivers/phy/phy-qcom-usb-hs.c

diff --git a/Documentation/devicetree/bindings/phy/qcom,usb-hs-phy.txt b/Documentation/devicetree/bindings/phy/qcom,usb-hs-phy.txt
new file mode 100644
index 000000000000..2bd22c53cee0
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/qcom,usb-hs-phy.txt
@@ -0,0 +1,71 @@
+Qualcomm's USB HS PHY
+
+PROPERTIES
+
+- compatible:
+    Usage: required
+    Value type: <string>
+    Definition: Should contain "qcom,usb-hs-phy"
+
+- #phy-cells:
+    Usage: required
+    Value type: <u32>
+    Definition: Should contain 0
+
+- clocks:
+    Usage: required
+    Value type: <prop-encoded-array>
+    Definition: Should contain clock specifier for the reference and sleep
+                clocks
+
+- clock-names:
+    Usage: required
+    Value type: <stringlist>
+    Definition: Should contain "ref" and "sleep" for the reference and sleep
+                clocks respectively
+
+- resets:
+    Usage: required
+    Value type: <prop-encoded-array>
+    Definition: Should contain the phy and POR resets
+
+- reset-names:
+    Usage: required
+    Value type: <stringlist>
+    Definition: Should contain "phy" and "por" for the phy and POR resets
+                respectively
+
+- v3p3-supply:
+    Usage: required
+    Value type: <phandle>
+    Definition: Should contain a reference to the 3.3V supply
+
+- v1p8-supply:
+    Usage: required
+    Value type: <phandle>
+    Definition: Should contain a reference to the 1.8V supply
+
+- qcom,init-seq:
+    Usage: optional
+    Value type: <u8 array>
+    Definition: Should contain a sequence of ULPI register and address pairs to
+                program into the ULPI_EXT_VENDOR_SPECIFIC area. This is related
+                to Device Mode Eye Diagram test.
+
+EXAMPLE
+
+otg: usb-controller {
+	ulpi {
+		phy {
+			compatible = "qcom,usb-hs-phy";
+			#phy-cells = <0>;
+			clocks = <&xo_board>, <&gcc GCC_USB2A_PHY_SLEEP_CLK>;
+			clock-names = "ref", "sleep";
+			resets = <&gcc GCC_USB2A_PHY_BCR>, <&otg 0>;
+			reset-names = "phy", "por";
+			v3p3-supply = <&pm8941_l24>;
+			v1p8-supply = <&pm8941_l6>;
+			qcom,init-seq = /bits/ 8 <0x81 0x63>;
+		};
+	};
+};
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index a2866949dc97..cfb3ded0896d 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -406,6 +406,14 @@ config PHY_QCOM_UFS
 	help
 	  Support for UFS PHY on QCOM chipsets.
 
+config PHY_QCOM_USB_HS
+	tristate "Qualcomm USB HS PHY module"
+	depends on USB_ULPI_BUS
+	select GENERIC_PHY
+	help
+	  Support for the USB high-speed ULPI compliant phy on Qualcomm
+	  chipsets.
+
 config PHY_QCOM_USB_HSIC
 	tristate "Qualcomm USB HSIC ULPI PHY module"
 	depends on USB_ULPI_BUS
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 982e84a290ec..21435fc0b656 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_PHY_STIH41X_USB)		+= phy-stih41x-usb.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs-qmp-20nm.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs-qmp-14nm.o
+obj-$(CONFIG_PHY_QCOM_USB_HS) 		+= phy-qcom-usb-hs.o
 obj-$(CONFIG_PHY_QCOM_USB_HSIC) 	+= phy-qcom-usb-hsic.o
 obj-$(CONFIG_PHY_TUSB1210)		+= phy-tusb1210.o
 obj-$(CONFIG_PHY_BRCM_SATA)		+= phy-brcm-sata.o
diff --git a/drivers/phy/phy-qcom-usb-hs.c b/drivers/phy/phy-qcom-usb-hs.c
new file mode 100644
index 000000000000..8be83100ecd9
--- /dev/null
+++ b/drivers/phy/phy-qcom-usb-hs.c
@@ -0,0 +1,283 @@
+/**
+ * Copyright (C) 2016 Linaro Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/ulpi/driver.h>
+#include <linux/ulpi/regs.h>
+#include <linux/clk.h>
+#include <linux/regulator/consumer.h>
+#include <linux/of_device.h>
+#include <linux/reset.h>
+#include <linux/extcon.h>
+#include <linux/notifier.h>
+#include <linux/usb/of.h>
+
+#include "ulpi_phy.h"
+
+#define ULPI_PWR_CLK_MNG_REG		0x88
+# define ULPI_PWR_OTG_COMP_DISABLE	BIT(0)
+
+#define ULPI_MISC_A			0x96
+# define ULPI_MISC_A_VBUSVLDEXTSEL	BIT(1)
+# define ULPI_MISC_A_VBUSVLDEXT		BIT(0)
+
+
+struct ulpi_seq {
+	u8 addr;
+	u8 val;
+};
+
+struct qcom_usb_hs_phy {
+	struct ulpi *ulpi;
+	struct phy *phy;
+	struct clk *ref_clk;
+	struct clk *sleep_clk;
+	struct regulator *v1p8;
+	struct regulator *v3p3;
+	struct reset_control *reset;
+	struct ulpi_seq *init_seq;
+	struct notifier_block vbus_notify;
+	struct extcon_dev *vbus_edev;
+	struct extcon_dev *id_edev;
+	enum usb_dr_mode dr_mode;
+};
+
+static int
+qcom_usb_hs_phy_vbus_notifier(struct notifier_block *nb, unsigned long event,
+			      void *ptr)
+{
+	struct qcom_usb_hs_phy *uphy;
+	int is_host;
+	u8 addr;
+
+	uphy = container_of(nb, struct qcom_usb_hs_phy, vbus_notify);
+	is_host = extcon_get_cable_state_(uphy->id_edev, EXTCON_USB_HOST);
+	if (is_host < 0)
+		is_host = 0; /* No id event means always a peripheral */
+
+	if (event && !is_host)
+		addr = ULPI_SET(ULPI_MISC_A);
+	else
+		addr = ULPI_CLR(ULPI_MISC_A);
+
+	return ulpi_write(uphy->ulpi, addr,
+			  ULPI_MISC_A_VBUSVLDEXTSEL | ULPI_MISC_A_VBUSVLDEXT);
+}
+
+static int qcom_usb_hs_phy_power_on(struct phy *phy)
+{
+	struct qcom_usb_hs_phy *uphy = phy_get_drvdata(phy);
+	struct ulpi *ulpi = uphy->ulpi;
+	const struct ulpi_seq *seq;
+	int ret, state;
+
+	ret = clk_prepare_enable(uphy->ref_clk);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(uphy->sleep_clk);
+	if (ret)
+		goto err_sleep;
+
+	ret = regulator_set_voltage(uphy->v1p8, 1800000, 1800000);
+	if (ret)
+		goto err_1p8;
+	ret = regulator_set_load(uphy->v1p8, 50000);
+	if (ret < 0)
+		goto err_1p8;
+
+	ret = regulator_enable(uphy->v1p8);
+	if (ret)
+		goto err_1p8;
+
+	ret = regulator_set_voltage_triplet(uphy->v3p3, 3050000, 3300000,
+					    3300000);
+	if (ret)
+		goto err_3p3;
+
+	ret = regulator_set_load(uphy->v3p3, 50000);
+	if (ret < 0)
+		goto err_3p3;
+
+	ret = regulator_enable(uphy->v3p3);
+	if (ret)
+		goto err_3p3;
+
+	for (seq = uphy->init_seq; seq->addr; seq++) {
+		ret = ulpi_write(ulpi, seq->addr, seq->val);
+		if (ret)
+			goto err_ulpi;
+	}
+
+	if (uphy->reset) {
+		ret = reset_control_reset(uphy->reset);
+		if (ret)
+			goto err_ulpi;
+	}
+
+	if (uphy->vbus_edev) {
+		ulpi_write(ulpi, ULPI_SET(ULPI_PWR_CLK_MNG_REG),
+			   ULPI_PWR_OTG_COMP_DISABLE);
+		state = extcon_get_cable_state_(uphy->vbus_edev, EXTCON_USB);
+		/* setup initial state */
+		qcom_usb_hs_phy_vbus_notifier(&uphy->vbus_notify, state,
+					      uphy->vbus_edev);
+	} else {
+		u8 val;
+
+		switch (uphy->dr_mode) {
+		case USB_DR_MODE_OTG:
+			val = ULPI_INT_IDGRD;
+		case USB_DR_MODE_PERIPHERAL:
+			val |= ULPI_INT_SESS_VALID;
+			break;
+		default:
+			val = 0;
+		}
+
+		ret = ulpi_write(ulpi, ULPI_USB_INT_EN_RISE, val);
+		if (ret)
+			goto err_ulpi;
+		ret = ulpi_write(ulpi, ULPI_USB_INT_EN_FALL, val);
+		if (ret)
+			goto err_ulpi;
+	}
+
+	return 0;
+err_ulpi:
+	regulator_disable(uphy->v3p3);
+err_3p3:
+	regulator_disable(uphy->v1p8);
+err_1p8:
+	clk_disable_unprepare(uphy->sleep_clk);
+err_sleep:
+	clk_disable_unprepare(uphy->ref_clk);
+	return ret;
+}
+
+static int qcom_usb_hs_phy_power_off(struct phy *phy)
+{
+	struct qcom_usb_hs_phy *uphy = phy_get_drvdata(phy);
+
+	regulator_disable(uphy->v3p3);
+	regulator_disable(uphy->v1p8);
+	clk_disable_unprepare(uphy->sleep_clk);
+	clk_disable_unprepare(uphy->ref_clk);
+
+	return 0;
+}
+
+static const struct phy_ops qcom_usb_hs_phy_ops = {
+	.power_on = qcom_usb_hs_phy_power_on,
+	.power_off = qcom_usb_hs_phy_power_off,
+	.owner = THIS_MODULE,
+};
+
+static int qcom_usb_hs_phy_probe(struct ulpi *ulpi)
+{
+	struct qcom_usb_hs_phy *uphy;
+	struct phy_provider *p;
+	struct clk *clk;
+	struct regulator *reg;
+	struct reset_control *reset;
+	int size;
+	int ret;
+
+	uphy = devm_kzalloc(&ulpi->dev, sizeof(*uphy), GFP_KERNEL);
+	if (!uphy)
+		return -ENOMEM;
+	ulpi_set_drvdata(ulpi, uphy);
+	uphy->ulpi = ulpi;
+	uphy->dr_mode = of_usb_get_dr_mode_by_phy(ulpi->dev.of_node);
+
+	size = of_property_count_u8_elems(ulpi->dev.of_node, "qcom,init-seq");
+	if (size < 0)
+		size = 0;
+	uphy->init_seq = devm_kmalloc_array(&ulpi->dev, (size / 2) + 1,
+					   sizeof(*uphy->init_seq), GFP_KERNEL);
+	if (!uphy->init_seq)
+		return -ENOMEM;
+	ret = of_property_read_u8_array(ulpi->dev.of_node, "qcom,init-seq",
+					(u8 *)uphy->init_seq, size);
+	if (ret && size)
+		return ret;
+	/* NUL terminate */
+	uphy->init_seq[size / 2].addr = uphy->init_seq[size / 2].val = 0;
+
+	uphy->ref_clk = clk = devm_clk_get(&ulpi->dev, "ref");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	uphy->sleep_clk = clk = devm_clk_get(&ulpi->dev, "sleep");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	uphy->v1p8 = reg = devm_regulator_get(&ulpi->dev, "v1p8");
+	if (IS_ERR(reg))
+		return PTR_ERR(reg);
+
+	uphy->v3p3 = reg = devm_regulator_get(&ulpi->dev, "v3p3");
+	if (IS_ERR(reg))
+		return PTR_ERR(reg);
+
+	uphy->reset = reset = devm_reset_control_get(&ulpi->dev, "por");
+	if (IS_ERR(reset)) {
+		if (PTR_ERR(reset) == -EPROBE_DEFER)
+			return PTR_ERR(reset);
+		uphy->reset = NULL;
+	}
+
+	uphy->phy = devm_phy_create(&ulpi->dev, ulpi->dev.of_node,
+				    &qcom_usb_hs_phy_ops);
+	if (IS_ERR(uphy->phy))
+		return PTR_ERR(uphy->phy);
+
+	uphy->vbus_edev = extcon_get_edev_by_phandle(&ulpi->dev, 0);
+	if (IS_ERR(uphy->vbus_edev)) {
+		if (PTR_ERR(uphy->vbus_edev) != -ENODEV)
+			return PTR_ERR(uphy->vbus_edev);
+		uphy->vbus_edev = NULL;
+	}
+
+	uphy->id_edev = extcon_get_edev_by_phandle(&ulpi->dev, 1);
+	if (IS_ERR(uphy->id_edev)) {
+		if (PTR_ERR(uphy->id_edev) != -ENODEV)
+			return PTR_ERR(uphy->id_edev);
+		uphy->id_edev = NULL;
+	}
+
+	if (uphy->vbus_edev) {
+		uphy->vbus_notify.notifier_call = qcom_usb_hs_phy_vbus_notifier;
+		ret = extcon_register_notifier(uphy->vbus_edev, EXTCON_USB,
+						&uphy->vbus_notify);
+		if (ret)
+			return ret;
+	}
+
+	phy_set_drvdata(uphy->phy, uphy);
+
+	p = devm_of_phy_provider_register(&ulpi->dev, of_phy_simple_xlate);
+	return PTR_ERR_OR_ZERO(p);
+}
+
+static const struct of_device_id qcom_usb_hs_phy_match[] = {
+	{ .compatible = "qcom,usb-hs-phy", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, qcom_usb_hs_phy_match);
+
+static struct ulpi_driver qcom_usb_hs_phy_driver = {
+	.probe = qcom_usb_hs_phy_probe,
+	.driver = {
+		.name = "qcom_usb_hs_phy",
+		.of_match_table = qcom_usb_hs_phy_match
+	},
+};
+module_ulpi_driver(qcom_usb_hs_phy_driver);
+
+MODULE_DESCRIPTION("Qualcomm USB HS phy");
+MODULE_LICENSE("GPL v2");
-- 
2.9.0.rc2.8.ga28705d

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 21/21] phy: Add support for Qualcomm's USB HS phy
@ 2016-06-26  7:28     ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-usb
  Cc: linux-arm-kernel, linux-kernel, linux-arm-msm, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Kishon Vijay Abraham I, devicetree

The high-speed phy on qcom SoCs is controlled via the ULPI
viewport.

Cc: Kishon Vijay Abraham I <kishon@ti.com>
Cc: <devicetree@vger.kernel.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 .../devicetree/bindings/phy/qcom,usb-hs-phy.txt    |  71 ++++++
 drivers/phy/Kconfig                                |   8 +
 drivers/phy/Makefile                               |   1 +
 drivers/phy/phy-qcom-usb-hs.c                      | 283 +++++++++++++++++++++
 4 files changed, 363 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/qcom,usb-hs-phy.txt
 create mode 100644 drivers/phy/phy-qcom-usb-hs.c

diff --git a/Documentation/devicetree/bindings/phy/qcom,usb-hs-phy.txt b/Documentation/devicetree/bindings/phy/qcom,usb-hs-phy.txt
new file mode 100644
index 000000000000..2bd22c53cee0
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/qcom,usb-hs-phy.txt
@@ -0,0 +1,71 @@
+Qualcomm's USB HS PHY
+
+PROPERTIES
+
+- compatible:
+    Usage: required
+    Value type: <string>
+    Definition: Should contain "qcom,usb-hs-phy"
+
+- #phy-cells:
+    Usage: required
+    Value type: <u32>
+    Definition: Should contain 0
+
+- clocks:
+    Usage: required
+    Value type: <prop-encoded-array>
+    Definition: Should contain clock specifier for the reference and sleep
+                clocks
+
+- clock-names:
+    Usage: required
+    Value type: <stringlist>
+    Definition: Should contain "ref" and "sleep" for the reference and sleep
+                clocks respectively
+
+- resets:
+    Usage: required
+    Value type: <prop-encoded-array>
+    Definition: Should contain the phy and POR resets
+
+- reset-names:
+    Usage: required
+    Value type: <stringlist>
+    Definition: Should contain "phy" and "por" for the phy and POR resets
+                respectively
+
+- v3p3-supply:
+    Usage: required
+    Value type: <phandle>
+    Definition: Should contain a reference to the 3.3V supply
+
+- v1p8-supply:
+    Usage: required
+    Value type: <phandle>
+    Definition: Should contain a reference to the 1.8V supply
+
+- qcom,init-seq:
+    Usage: optional
+    Value type: <u8 array>
+    Definition: Should contain a sequence of ULPI register and address pairs to
+                program into the ULPI_EXT_VENDOR_SPECIFIC area. This is related
+                to Device Mode Eye Diagram test.
+
+EXAMPLE
+
+otg: usb-controller {
+	ulpi {
+		phy {
+			compatible = "qcom,usb-hs-phy";
+			#phy-cells = <0>;
+			clocks = <&xo_board>, <&gcc GCC_USB2A_PHY_SLEEP_CLK>;
+			clock-names = "ref", "sleep";
+			resets = <&gcc GCC_USB2A_PHY_BCR>, <&otg 0>;
+			reset-names = "phy", "por";
+			v3p3-supply = <&pm8941_l24>;
+			v1p8-supply = <&pm8941_l6>;
+			qcom,init-seq = /bits/ 8 <0x81 0x63>;
+		};
+	};
+};
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index a2866949dc97..cfb3ded0896d 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -406,6 +406,14 @@ config PHY_QCOM_UFS
 	help
 	  Support for UFS PHY on QCOM chipsets.
 
+config PHY_QCOM_USB_HS
+	tristate "Qualcomm USB HS PHY module"
+	depends on USB_ULPI_BUS
+	select GENERIC_PHY
+	help
+	  Support for the USB high-speed ULPI compliant phy on Qualcomm
+	  chipsets.
+
 config PHY_QCOM_USB_HSIC
 	tristate "Qualcomm USB HSIC ULPI PHY module"
 	depends on USB_ULPI_BUS
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 982e84a290ec..21435fc0b656 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_PHY_STIH41X_USB)		+= phy-stih41x-usb.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs-qmp-20nm.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs-qmp-14nm.o
+obj-$(CONFIG_PHY_QCOM_USB_HS) 		+= phy-qcom-usb-hs.o
 obj-$(CONFIG_PHY_QCOM_USB_HSIC) 	+= phy-qcom-usb-hsic.o
 obj-$(CONFIG_PHY_TUSB1210)		+= phy-tusb1210.o
 obj-$(CONFIG_PHY_BRCM_SATA)		+= phy-brcm-sata.o
diff --git a/drivers/phy/phy-qcom-usb-hs.c b/drivers/phy/phy-qcom-usb-hs.c
new file mode 100644
index 000000000000..8be83100ecd9
--- /dev/null
+++ b/drivers/phy/phy-qcom-usb-hs.c
@@ -0,0 +1,283 @@
+/**
+ * Copyright (C) 2016 Linaro Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/ulpi/driver.h>
+#include <linux/ulpi/regs.h>
+#include <linux/clk.h>
+#include <linux/regulator/consumer.h>
+#include <linux/of_device.h>
+#include <linux/reset.h>
+#include <linux/extcon.h>
+#include <linux/notifier.h>
+#include <linux/usb/of.h>
+
+#include "ulpi_phy.h"
+
+#define ULPI_PWR_CLK_MNG_REG		0x88
+# define ULPI_PWR_OTG_COMP_DISABLE	BIT(0)
+
+#define ULPI_MISC_A			0x96
+# define ULPI_MISC_A_VBUSVLDEXTSEL	BIT(1)
+# define ULPI_MISC_A_VBUSVLDEXT		BIT(0)
+
+
+struct ulpi_seq {
+	u8 addr;
+	u8 val;
+};
+
+struct qcom_usb_hs_phy {
+	struct ulpi *ulpi;
+	struct phy *phy;
+	struct clk *ref_clk;
+	struct clk *sleep_clk;
+	struct regulator *v1p8;
+	struct regulator *v3p3;
+	struct reset_control *reset;
+	struct ulpi_seq *init_seq;
+	struct notifier_block vbus_notify;
+	struct extcon_dev *vbus_edev;
+	struct extcon_dev *id_edev;
+	enum usb_dr_mode dr_mode;
+};
+
+static int
+qcom_usb_hs_phy_vbus_notifier(struct notifier_block *nb, unsigned long event,
+			      void *ptr)
+{
+	struct qcom_usb_hs_phy *uphy;
+	int is_host;
+	u8 addr;
+
+	uphy = container_of(nb, struct qcom_usb_hs_phy, vbus_notify);
+	is_host = extcon_get_cable_state_(uphy->id_edev, EXTCON_USB_HOST);
+	if (is_host < 0)
+		is_host = 0; /* No id event means always a peripheral */
+
+	if (event && !is_host)
+		addr = ULPI_SET(ULPI_MISC_A);
+	else
+		addr = ULPI_CLR(ULPI_MISC_A);
+
+	return ulpi_write(uphy->ulpi, addr,
+			  ULPI_MISC_A_VBUSVLDEXTSEL | ULPI_MISC_A_VBUSVLDEXT);
+}
+
+static int qcom_usb_hs_phy_power_on(struct phy *phy)
+{
+	struct qcom_usb_hs_phy *uphy = phy_get_drvdata(phy);
+	struct ulpi *ulpi = uphy->ulpi;
+	const struct ulpi_seq *seq;
+	int ret, state;
+
+	ret = clk_prepare_enable(uphy->ref_clk);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(uphy->sleep_clk);
+	if (ret)
+		goto err_sleep;
+
+	ret = regulator_set_voltage(uphy->v1p8, 1800000, 1800000);
+	if (ret)
+		goto err_1p8;
+	ret = regulator_set_load(uphy->v1p8, 50000);
+	if (ret < 0)
+		goto err_1p8;
+
+	ret = regulator_enable(uphy->v1p8);
+	if (ret)
+		goto err_1p8;
+
+	ret = regulator_set_voltage_triplet(uphy->v3p3, 3050000, 3300000,
+					    3300000);
+	if (ret)
+		goto err_3p3;
+
+	ret = regulator_set_load(uphy->v3p3, 50000);
+	if (ret < 0)
+		goto err_3p3;
+
+	ret = regulator_enable(uphy->v3p3);
+	if (ret)
+		goto err_3p3;
+
+	for (seq = uphy->init_seq; seq->addr; seq++) {
+		ret = ulpi_write(ulpi, seq->addr, seq->val);
+		if (ret)
+			goto err_ulpi;
+	}
+
+	if (uphy->reset) {
+		ret = reset_control_reset(uphy->reset);
+		if (ret)
+			goto err_ulpi;
+	}
+
+	if (uphy->vbus_edev) {
+		ulpi_write(ulpi, ULPI_SET(ULPI_PWR_CLK_MNG_REG),
+			   ULPI_PWR_OTG_COMP_DISABLE);
+		state = extcon_get_cable_state_(uphy->vbus_edev, EXTCON_USB);
+		/* setup initial state */
+		qcom_usb_hs_phy_vbus_notifier(&uphy->vbus_notify, state,
+					      uphy->vbus_edev);
+	} else {
+		u8 val;
+
+		switch (uphy->dr_mode) {
+		case USB_DR_MODE_OTG:
+			val = ULPI_INT_IDGRD;
+		case USB_DR_MODE_PERIPHERAL:
+			val |= ULPI_INT_SESS_VALID;
+			break;
+		default:
+			val = 0;
+		}
+
+		ret = ulpi_write(ulpi, ULPI_USB_INT_EN_RISE, val);
+		if (ret)
+			goto err_ulpi;
+		ret = ulpi_write(ulpi, ULPI_USB_INT_EN_FALL, val);
+		if (ret)
+			goto err_ulpi;
+	}
+
+	return 0;
+err_ulpi:
+	regulator_disable(uphy->v3p3);
+err_3p3:
+	regulator_disable(uphy->v1p8);
+err_1p8:
+	clk_disable_unprepare(uphy->sleep_clk);
+err_sleep:
+	clk_disable_unprepare(uphy->ref_clk);
+	return ret;
+}
+
+static int qcom_usb_hs_phy_power_off(struct phy *phy)
+{
+	struct qcom_usb_hs_phy *uphy = phy_get_drvdata(phy);
+
+	regulator_disable(uphy->v3p3);
+	regulator_disable(uphy->v1p8);
+	clk_disable_unprepare(uphy->sleep_clk);
+	clk_disable_unprepare(uphy->ref_clk);
+
+	return 0;
+}
+
+static const struct phy_ops qcom_usb_hs_phy_ops = {
+	.power_on = qcom_usb_hs_phy_power_on,
+	.power_off = qcom_usb_hs_phy_power_off,
+	.owner = THIS_MODULE,
+};
+
+static int qcom_usb_hs_phy_probe(struct ulpi *ulpi)
+{
+	struct qcom_usb_hs_phy *uphy;
+	struct phy_provider *p;
+	struct clk *clk;
+	struct regulator *reg;
+	struct reset_control *reset;
+	int size;
+	int ret;
+
+	uphy = devm_kzalloc(&ulpi->dev, sizeof(*uphy), GFP_KERNEL);
+	if (!uphy)
+		return -ENOMEM;
+	ulpi_set_drvdata(ulpi, uphy);
+	uphy->ulpi = ulpi;
+	uphy->dr_mode = of_usb_get_dr_mode_by_phy(ulpi->dev.of_node);
+
+	size = of_property_count_u8_elems(ulpi->dev.of_node, "qcom,init-seq");
+	if (size < 0)
+		size = 0;
+	uphy->init_seq = devm_kmalloc_array(&ulpi->dev, (size / 2) + 1,
+					   sizeof(*uphy->init_seq), GFP_KERNEL);
+	if (!uphy->init_seq)
+		return -ENOMEM;
+	ret = of_property_read_u8_array(ulpi->dev.of_node, "qcom,init-seq",
+					(u8 *)uphy->init_seq, size);
+	if (ret && size)
+		return ret;
+	/* NUL terminate */
+	uphy->init_seq[size / 2].addr = uphy->init_seq[size / 2].val = 0;
+
+	uphy->ref_clk = clk = devm_clk_get(&ulpi->dev, "ref");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	uphy->sleep_clk = clk = devm_clk_get(&ulpi->dev, "sleep");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	uphy->v1p8 = reg = devm_regulator_get(&ulpi->dev, "v1p8");
+	if (IS_ERR(reg))
+		return PTR_ERR(reg);
+
+	uphy->v3p3 = reg = devm_regulator_get(&ulpi->dev, "v3p3");
+	if (IS_ERR(reg))
+		return PTR_ERR(reg);
+
+	uphy->reset = reset = devm_reset_control_get(&ulpi->dev, "por");
+	if (IS_ERR(reset)) {
+		if (PTR_ERR(reset) == -EPROBE_DEFER)
+			return PTR_ERR(reset);
+		uphy->reset = NULL;
+	}
+
+	uphy->phy = devm_phy_create(&ulpi->dev, ulpi->dev.of_node,
+				    &qcom_usb_hs_phy_ops);
+	if (IS_ERR(uphy->phy))
+		return PTR_ERR(uphy->phy);
+
+	uphy->vbus_edev = extcon_get_edev_by_phandle(&ulpi->dev, 0);
+	if (IS_ERR(uphy->vbus_edev)) {
+		if (PTR_ERR(uphy->vbus_edev) != -ENODEV)
+			return PTR_ERR(uphy->vbus_edev);
+		uphy->vbus_edev = NULL;
+	}
+
+	uphy->id_edev = extcon_get_edev_by_phandle(&ulpi->dev, 1);
+	if (IS_ERR(uphy->id_edev)) {
+		if (PTR_ERR(uphy->id_edev) != -ENODEV)
+			return PTR_ERR(uphy->id_edev);
+		uphy->id_edev = NULL;
+	}
+
+	if (uphy->vbus_edev) {
+		uphy->vbus_notify.notifier_call = qcom_usb_hs_phy_vbus_notifier;
+		ret = extcon_register_notifier(uphy->vbus_edev, EXTCON_USB,
+						&uphy->vbus_notify);
+		if (ret)
+			return ret;
+	}
+
+	phy_set_drvdata(uphy->phy, uphy);
+
+	p = devm_of_phy_provider_register(&ulpi->dev, of_phy_simple_xlate);
+	return PTR_ERR_OR_ZERO(p);
+}
+
+static const struct of_device_id qcom_usb_hs_phy_match[] = {
+	{ .compatible = "qcom,usb-hs-phy", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, qcom_usb_hs_phy_match);
+
+static struct ulpi_driver qcom_usb_hs_phy_driver = {
+	.probe = qcom_usb_hs_phy_probe,
+	.driver = {
+		.name = "qcom_usb_hs_phy",
+		.of_match_table = qcom_usb_hs_phy_match
+	},
+};
+module_ulpi_driver(qcom_usb_hs_phy_driver);
+
+MODULE_DESCRIPTION("Qualcomm USB HS phy");
+MODULE_LICENSE("GPL v2");
-- 
2.9.0.rc2.8.ga28705d

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

* [PATCH 21/21] phy: Add support for Qualcomm's USB HS phy
@ 2016-06-26  7:28     ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-26  7:28 UTC (permalink / raw)
  To: linux-arm-kernel

The high-speed phy on qcom SoCs is controlled via the ULPI
viewport.

Cc: Kishon Vijay Abraham I <kishon@ti.com>
Cc: <devicetree@vger.kernel.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
---
 .../devicetree/bindings/phy/qcom,usb-hs-phy.txt    |  71 ++++++
 drivers/phy/Kconfig                                |   8 +
 drivers/phy/Makefile                               |   1 +
 drivers/phy/phy-qcom-usb-hs.c                      | 283 +++++++++++++++++++++
 4 files changed, 363 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/qcom,usb-hs-phy.txt
 create mode 100644 drivers/phy/phy-qcom-usb-hs.c

diff --git a/Documentation/devicetree/bindings/phy/qcom,usb-hs-phy.txt b/Documentation/devicetree/bindings/phy/qcom,usb-hs-phy.txt
new file mode 100644
index 000000000000..2bd22c53cee0
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/qcom,usb-hs-phy.txt
@@ -0,0 +1,71 @@
+Qualcomm's USB HS PHY
+
+PROPERTIES
+
+- compatible:
+    Usage: required
+    Value type: <string>
+    Definition: Should contain "qcom,usb-hs-phy"
+
+- #phy-cells:
+    Usage: required
+    Value type: <u32>
+    Definition: Should contain 0
+
+- clocks:
+    Usage: required
+    Value type: <prop-encoded-array>
+    Definition: Should contain clock specifier for the reference and sleep
+                clocks
+
+- clock-names:
+    Usage: required
+    Value type: <stringlist>
+    Definition: Should contain "ref" and "sleep" for the reference and sleep
+                clocks respectively
+
+- resets:
+    Usage: required
+    Value type: <prop-encoded-array>
+    Definition: Should contain the phy and POR resets
+
+- reset-names:
+    Usage: required
+    Value type: <stringlist>
+    Definition: Should contain "phy" and "por" for the phy and POR resets
+                respectively
+
+- v3p3-supply:
+    Usage: required
+    Value type: <phandle>
+    Definition: Should contain a reference to the 3.3V supply
+
+- v1p8-supply:
+    Usage: required
+    Value type: <phandle>
+    Definition: Should contain a reference to the 1.8V supply
+
+- qcom,init-seq:
+    Usage: optional
+    Value type: <u8 array>
+    Definition: Should contain a sequence of ULPI register and address pairs to
+                program into the ULPI_EXT_VENDOR_SPECIFIC area. This is related
+                to Device Mode Eye Diagram test.
+
+EXAMPLE
+
+otg: usb-controller {
+	ulpi {
+		phy {
+			compatible = "qcom,usb-hs-phy";
+			#phy-cells = <0>;
+			clocks = <&xo_board>, <&gcc GCC_USB2A_PHY_SLEEP_CLK>;
+			clock-names = "ref", "sleep";
+			resets = <&gcc GCC_USB2A_PHY_BCR>, <&otg 0>;
+			reset-names = "phy", "por";
+			v3p3-supply = <&pm8941_l24>;
+			v1p8-supply = <&pm8941_l6>;
+			qcom,init-seq = /bits/ 8 <0x81 0x63>;
+		};
+	};
+};
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index a2866949dc97..cfb3ded0896d 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -406,6 +406,14 @@ config PHY_QCOM_UFS
 	help
 	  Support for UFS PHY on QCOM chipsets.
 
+config PHY_QCOM_USB_HS
+	tristate "Qualcomm USB HS PHY module"
+	depends on USB_ULPI_BUS
+	select GENERIC_PHY
+	help
+	  Support for the USB high-speed ULPI compliant phy on Qualcomm
+	  chipsets.
+
 config PHY_QCOM_USB_HSIC
 	tristate "Qualcomm USB HSIC ULPI PHY module"
 	depends on USB_ULPI_BUS
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 982e84a290ec..21435fc0b656 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_PHY_STIH41X_USB)		+= phy-stih41x-usb.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs-qmp-20nm.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs-qmp-14nm.o
+obj-$(CONFIG_PHY_QCOM_USB_HS) 		+= phy-qcom-usb-hs.o
 obj-$(CONFIG_PHY_QCOM_USB_HSIC) 	+= phy-qcom-usb-hsic.o
 obj-$(CONFIG_PHY_TUSB1210)		+= phy-tusb1210.o
 obj-$(CONFIG_PHY_BRCM_SATA)		+= phy-brcm-sata.o
diff --git a/drivers/phy/phy-qcom-usb-hs.c b/drivers/phy/phy-qcom-usb-hs.c
new file mode 100644
index 000000000000..8be83100ecd9
--- /dev/null
+++ b/drivers/phy/phy-qcom-usb-hs.c
@@ -0,0 +1,283 @@
+/**
+ * Copyright (C) 2016 Linaro Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/ulpi/driver.h>
+#include <linux/ulpi/regs.h>
+#include <linux/clk.h>
+#include <linux/regulator/consumer.h>
+#include <linux/of_device.h>
+#include <linux/reset.h>
+#include <linux/extcon.h>
+#include <linux/notifier.h>
+#include <linux/usb/of.h>
+
+#include "ulpi_phy.h"
+
+#define ULPI_PWR_CLK_MNG_REG		0x88
+# define ULPI_PWR_OTG_COMP_DISABLE	BIT(0)
+
+#define ULPI_MISC_A			0x96
+# define ULPI_MISC_A_VBUSVLDEXTSEL	BIT(1)
+# define ULPI_MISC_A_VBUSVLDEXT		BIT(0)
+
+
+struct ulpi_seq {
+	u8 addr;
+	u8 val;
+};
+
+struct qcom_usb_hs_phy {
+	struct ulpi *ulpi;
+	struct phy *phy;
+	struct clk *ref_clk;
+	struct clk *sleep_clk;
+	struct regulator *v1p8;
+	struct regulator *v3p3;
+	struct reset_control *reset;
+	struct ulpi_seq *init_seq;
+	struct notifier_block vbus_notify;
+	struct extcon_dev *vbus_edev;
+	struct extcon_dev *id_edev;
+	enum usb_dr_mode dr_mode;
+};
+
+static int
+qcom_usb_hs_phy_vbus_notifier(struct notifier_block *nb, unsigned long event,
+			      void *ptr)
+{
+	struct qcom_usb_hs_phy *uphy;
+	int is_host;
+	u8 addr;
+
+	uphy = container_of(nb, struct qcom_usb_hs_phy, vbus_notify);
+	is_host = extcon_get_cable_state_(uphy->id_edev, EXTCON_USB_HOST);
+	if (is_host < 0)
+		is_host = 0; /* No id event means always a peripheral */
+
+	if (event && !is_host)
+		addr = ULPI_SET(ULPI_MISC_A);
+	else
+		addr = ULPI_CLR(ULPI_MISC_A);
+
+	return ulpi_write(uphy->ulpi, addr,
+			  ULPI_MISC_A_VBUSVLDEXTSEL | ULPI_MISC_A_VBUSVLDEXT);
+}
+
+static int qcom_usb_hs_phy_power_on(struct phy *phy)
+{
+	struct qcom_usb_hs_phy *uphy = phy_get_drvdata(phy);
+	struct ulpi *ulpi = uphy->ulpi;
+	const struct ulpi_seq *seq;
+	int ret, state;
+
+	ret = clk_prepare_enable(uphy->ref_clk);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(uphy->sleep_clk);
+	if (ret)
+		goto err_sleep;
+
+	ret = regulator_set_voltage(uphy->v1p8, 1800000, 1800000);
+	if (ret)
+		goto err_1p8;
+	ret = regulator_set_load(uphy->v1p8, 50000);
+	if (ret < 0)
+		goto err_1p8;
+
+	ret = regulator_enable(uphy->v1p8);
+	if (ret)
+		goto err_1p8;
+
+	ret = regulator_set_voltage_triplet(uphy->v3p3, 3050000, 3300000,
+					    3300000);
+	if (ret)
+		goto err_3p3;
+
+	ret = regulator_set_load(uphy->v3p3, 50000);
+	if (ret < 0)
+		goto err_3p3;
+
+	ret = regulator_enable(uphy->v3p3);
+	if (ret)
+		goto err_3p3;
+
+	for (seq = uphy->init_seq; seq->addr; seq++) {
+		ret = ulpi_write(ulpi, seq->addr, seq->val);
+		if (ret)
+			goto err_ulpi;
+	}
+
+	if (uphy->reset) {
+		ret = reset_control_reset(uphy->reset);
+		if (ret)
+			goto err_ulpi;
+	}
+
+	if (uphy->vbus_edev) {
+		ulpi_write(ulpi, ULPI_SET(ULPI_PWR_CLK_MNG_REG),
+			   ULPI_PWR_OTG_COMP_DISABLE);
+		state = extcon_get_cable_state_(uphy->vbus_edev, EXTCON_USB);
+		/* setup initial state */
+		qcom_usb_hs_phy_vbus_notifier(&uphy->vbus_notify, state,
+					      uphy->vbus_edev);
+	} else {
+		u8 val;
+
+		switch (uphy->dr_mode) {
+		case USB_DR_MODE_OTG:
+			val = ULPI_INT_IDGRD;
+		case USB_DR_MODE_PERIPHERAL:
+			val |= ULPI_INT_SESS_VALID;
+			break;
+		default:
+			val = 0;
+		}
+
+		ret = ulpi_write(ulpi, ULPI_USB_INT_EN_RISE, val);
+		if (ret)
+			goto err_ulpi;
+		ret = ulpi_write(ulpi, ULPI_USB_INT_EN_FALL, val);
+		if (ret)
+			goto err_ulpi;
+	}
+
+	return 0;
+err_ulpi:
+	regulator_disable(uphy->v3p3);
+err_3p3:
+	regulator_disable(uphy->v1p8);
+err_1p8:
+	clk_disable_unprepare(uphy->sleep_clk);
+err_sleep:
+	clk_disable_unprepare(uphy->ref_clk);
+	return ret;
+}
+
+static int qcom_usb_hs_phy_power_off(struct phy *phy)
+{
+	struct qcom_usb_hs_phy *uphy = phy_get_drvdata(phy);
+
+	regulator_disable(uphy->v3p3);
+	regulator_disable(uphy->v1p8);
+	clk_disable_unprepare(uphy->sleep_clk);
+	clk_disable_unprepare(uphy->ref_clk);
+
+	return 0;
+}
+
+static const struct phy_ops qcom_usb_hs_phy_ops = {
+	.power_on = qcom_usb_hs_phy_power_on,
+	.power_off = qcom_usb_hs_phy_power_off,
+	.owner = THIS_MODULE,
+};
+
+static int qcom_usb_hs_phy_probe(struct ulpi *ulpi)
+{
+	struct qcom_usb_hs_phy *uphy;
+	struct phy_provider *p;
+	struct clk *clk;
+	struct regulator *reg;
+	struct reset_control *reset;
+	int size;
+	int ret;
+
+	uphy = devm_kzalloc(&ulpi->dev, sizeof(*uphy), GFP_KERNEL);
+	if (!uphy)
+		return -ENOMEM;
+	ulpi_set_drvdata(ulpi, uphy);
+	uphy->ulpi = ulpi;
+	uphy->dr_mode = of_usb_get_dr_mode_by_phy(ulpi->dev.of_node);
+
+	size = of_property_count_u8_elems(ulpi->dev.of_node, "qcom,init-seq");
+	if (size < 0)
+		size = 0;
+	uphy->init_seq = devm_kmalloc_array(&ulpi->dev, (size / 2) + 1,
+					   sizeof(*uphy->init_seq), GFP_KERNEL);
+	if (!uphy->init_seq)
+		return -ENOMEM;
+	ret = of_property_read_u8_array(ulpi->dev.of_node, "qcom,init-seq",
+					(u8 *)uphy->init_seq, size);
+	if (ret && size)
+		return ret;
+	/* NUL terminate */
+	uphy->init_seq[size / 2].addr = uphy->init_seq[size / 2].val = 0;
+
+	uphy->ref_clk = clk = devm_clk_get(&ulpi->dev, "ref");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	uphy->sleep_clk = clk = devm_clk_get(&ulpi->dev, "sleep");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	uphy->v1p8 = reg = devm_regulator_get(&ulpi->dev, "v1p8");
+	if (IS_ERR(reg))
+		return PTR_ERR(reg);
+
+	uphy->v3p3 = reg = devm_regulator_get(&ulpi->dev, "v3p3");
+	if (IS_ERR(reg))
+		return PTR_ERR(reg);
+
+	uphy->reset = reset = devm_reset_control_get(&ulpi->dev, "por");
+	if (IS_ERR(reset)) {
+		if (PTR_ERR(reset) == -EPROBE_DEFER)
+			return PTR_ERR(reset);
+		uphy->reset = NULL;
+	}
+
+	uphy->phy = devm_phy_create(&ulpi->dev, ulpi->dev.of_node,
+				    &qcom_usb_hs_phy_ops);
+	if (IS_ERR(uphy->phy))
+		return PTR_ERR(uphy->phy);
+
+	uphy->vbus_edev = extcon_get_edev_by_phandle(&ulpi->dev, 0);
+	if (IS_ERR(uphy->vbus_edev)) {
+		if (PTR_ERR(uphy->vbus_edev) != -ENODEV)
+			return PTR_ERR(uphy->vbus_edev);
+		uphy->vbus_edev = NULL;
+	}
+
+	uphy->id_edev = extcon_get_edev_by_phandle(&ulpi->dev, 1);
+	if (IS_ERR(uphy->id_edev)) {
+		if (PTR_ERR(uphy->id_edev) != -ENODEV)
+			return PTR_ERR(uphy->id_edev);
+		uphy->id_edev = NULL;
+	}
+
+	if (uphy->vbus_edev) {
+		uphy->vbus_notify.notifier_call = qcom_usb_hs_phy_vbus_notifier;
+		ret = extcon_register_notifier(uphy->vbus_edev, EXTCON_USB,
+						&uphy->vbus_notify);
+		if (ret)
+			return ret;
+	}
+
+	phy_set_drvdata(uphy->phy, uphy);
+
+	p = devm_of_phy_provider_register(&ulpi->dev, of_phy_simple_xlate);
+	return PTR_ERR_OR_ZERO(p);
+}
+
+static const struct of_device_id qcom_usb_hs_phy_match[] = {
+	{ .compatible = "qcom,usb-hs-phy", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, qcom_usb_hs_phy_match);
+
+static struct ulpi_driver qcom_usb_hs_phy_driver = {
+	.probe = qcom_usb_hs_phy_probe,
+	.driver = {
+		.name = "qcom_usb_hs_phy",
+		.of_match_table = qcom_usb_hs_phy_match
+	},
+};
+module_ulpi_driver(qcom_usb_hs_phy_driver);
+
+MODULE_DESCRIPTION("Qualcomm USB HS phy");
+MODULE_LICENSE("GPL v2");
-- 
2.9.0.rc2.8.ga28705d

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

* Re: [PATCH 18/21] usb: chipidea: msm: Add reset controller for PHY POR bit
  2016-06-26  7:28   ` Stephen Boyd
@ 2016-06-27  3:41     ` kbuild test robot
  -1 siblings, 0 replies; 214+ messages in thread
From: kbuild test robot @ 2016-06-27  3:41 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: kbuild-all, linux-usb, linux-arm-kernel, linux-kernel,
	linux-arm-msm, Andy Gross, Bjorn Andersson, Neil Armstrong,
	Arnd Bergmann, Felipe Balbi, Peter Chen, Greg Kroah-Hartman

[-- Attachment #1: Type: text/plain, Size: 969 bytes --]

Hi,

[auto build test ERROR on peter.chen-usb/ci-for-usb-next]
[also build test ERROR on v4.7-rc5 next-20160624]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Stephen-Boyd/Support-qcom-s-HSIC-USB-and-rewrite-USB2-HS-phy-support/20160627-102637
base:   https://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb ci-for-usb-next
config: x86_64-acpi-redef (attached as .config)
compiler: gcc-6 (Debian 6.1.1-1) 6.1.1 20160430
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   drivers/built-in.o: In function `ci_hdrc_msm_remove':
>> ci_hdrc_msm.c:(.text+0x4fffd2): undefined reference to `reset_controller_unregister'

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 28294 bytes --]

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

* [PATCH 18/21] usb: chipidea: msm: Add reset controller for PHY POR bit
@ 2016-06-27  3:41     ` kbuild test robot
  0 siblings, 0 replies; 214+ messages in thread
From: kbuild test robot @ 2016-06-27  3:41 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

[auto build test ERROR on peter.chen-usb/ci-for-usb-next]
[also build test ERROR on v4.7-rc5 next-20160624]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Stephen-Boyd/Support-qcom-s-HSIC-USB-and-rewrite-USB2-HS-phy-support/20160627-102637
base:   https://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb ci-for-usb-next
config: x86_64-acpi-redef (attached as .config)
compiler: gcc-6 (Debian 6.1.1-1) 6.1.1 20160430
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   drivers/built-in.o: In function `ci_hdrc_msm_remove':
>> ci_hdrc_msm.c:(.text+0x4fffd2): undefined reference to `reset_controller_unregister'

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/octet-stream
Size: 28294 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160627/ad1e2216/attachment-0001.obj>

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

* Re: [PATCH 02/21] usb: ulpi: Support device discovery via DT
  2016-06-26  7:28     ` Stephen Boyd
  (?)
@ 2016-06-27  4:21         ` kbuild test robot
  -1 siblings, 0 replies; 214+ messages in thread
From: kbuild test robot @ 2016-06-27  4:21 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: kbuild-all-JC7UmRfGjtg, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Greg Kroah-Hartman, Heikki Krogerus,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring

[-- Attachment #1: Type: text/plain, Size: 1066 bytes --]

Hi,

[auto build test ERROR on peter.chen-usb/ci-for-usb-next]
[also build test ERROR on v4.7-rc5 next-20160624]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Stephen-Boyd/Support-qcom-s-HSIC-USB-and-rewrite-USB2-HS-phy-support/20160627-102637
base:   https://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb ci-for-usb-next
config: x86_64-randconfig-h0-06270614 (attached as .config)
compiler: gcc-6 (Debian 6.1.1-1) 6.1.1 20160430
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

>> ERROR: "of_device_request_module" [drivers/usb/common/ulpi.ko] undefined!
>> ERROR: "of_device_get_modalias" [drivers/usb/common/ulpi.ko] undefined!
>> ERROR: "of_device_uevent_modalias" [drivers/usb/common/ulpi.ko] undefined!

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 22307 bytes --]

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

* Re: [PATCH 02/21] usb: ulpi: Support device discovery via DT
@ 2016-06-27  4:21         ` kbuild test robot
  0 siblings, 0 replies; 214+ messages in thread
From: kbuild test robot @ 2016-06-27  4:21 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: kbuild-all, linux-usb, linux-arm-kernel, linux-kernel,
	linux-arm-msm, Andy Gross, Bjorn Andersson, Neil Armstrong,
	Arnd Bergmann, Felipe Balbi, Greg Kroah-Hartman, Heikki Krogerus,
	devicetree, Rob Herring

[-- Attachment #1: Type: text/plain, Size: 1066 bytes --]

Hi,

[auto build test ERROR on peter.chen-usb/ci-for-usb-next]
[also build test ERROR on v4.7-rc5 next-20160624]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Stephen-Boyd/Support-qcom-s-HSIC-USB-and-rewrite-USB2-HS-phy-support/20160627-102637
base:   https://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb ci-for-usb-next
config: x86_64-randconfig-h0-06270614 (attached as .config)
compiler: gcc-6 (Debian 6.1.1-1) 6.1.1 20160430
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

>> ERROR: "of_device_request_module" [drivers/usb/common/ulpi.ko] undefined!
>> ERROR: "of_device_get_modalias" [drivers/usb/common/ulpi.ko] undefined!
>> ERROR: "of_device_uevent_modalias" [drivers/usb/common/ulpi.ko] undefined!

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 22307 bytes --]

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

* [PATCH 02/21] usb: ulpi: Support device discovery via DT
@ 2016-06-27  4:21         ` kbuild test robot
  0 siblings, 0 replies; 214+ messages in thread
From: kbuild test robot @ 2016-06-27  4:21 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

[auto build test ERROR on peter.chen-usb/ci-for-usb-next]
[also build test ERROR on v4.7-rc5 next-20160624]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Stephen-Boyd/Support-qcom-s-HSIC-USB-and-rewrite-USB2-HS-phy-support/20160627-102637
base:   https://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb ci-for-usb-next
config: x86_64-randconfig-h0-06270614 (attached as .config)
compiler: gcc-6 (Debian 6.1.1-1) 6.1.1 20160430
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

>> ERROR: "of_device_request_module" [drivers/usb/common/ulpi.ko] undefined!
>> ERROR: "of_device_get_modalias" [drivers/usb/common/ulpi.ko] undefined!
>> ERROR: "of_device_uevent_modalias" [drivers/usb/common/ulpi.ko] undefined!

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/octet-stream
Size: 22307 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160627/cb33d152/attachment-0001.obj>

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

* Re: [PATCH 18/21] usb: chipidea: msm: Add reset controller for PHY POR bit
  2016-06-26  7:28   ` Stephen Boyd
@ 2016-06-27  4:51     ` kbuild test robot
  -1 siblings, 0 replies; 214+ messages in thread
From: kbuild test robot @ 2016-06-27  4:51 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: kbuild-all, linux-usb, linux-arm-kernel, linux-kernel,
	linux-arm-msm, Andy Gross, Bjorn Andersson, Neil Armstrong,
	Arnd Bergmann, Felipe Balbi, Peter Chen, Greg Kroah-Hartman

[-- Attachment #1: Type: text/plain, Size: 1497 bytes --]

Hi,

[auto build test ERROR on peter.chen-usb/ci-for-usb-next]
[also build test ERROR on v4.7-rc5 next-20160624]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Stephen-Boyd/Support-qcom-s-HSIC-USB-and-rewrite-USB2-HS-phy-support/20160627-102637
base:   https://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb ci-for-usb-next
config: arm-multi_v5_defconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 5.3.1-8) 5.3.1 20160205
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=arm 

All errors (new ones prefixed by >>):

   drivers/built-in.o: In function `ci_hdrc_msm_remove':
>> drivers/usb/chipidea/ci_hdrc_msm.c:275: undefined reference to `reset_controller_unregister'

vim +275 drivers/usb/chipidea/ci_hdrc_msm.c

   269	
   270		pm_runtime_put(&pdev->dev);
   271		pm_runtime_disable(&pdev->dev);
   272		ci_hdrc_remove_device(ci->ci);
   273		clk_disable_unprepare(ci->iface_clk);
   274		clk_disable_unprepare(ci->core_clk);
 > 275		reset_controller_unregister(&ci->rcdev);
   276	
   277		return 0;
   278	}

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 23385 bytes --]

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

* [PATCH 18/21] usb: chipidea: msm: Add reset controller for PHY POR bit
@ 2016-06-27  4:51     ` kbuild test robot
  0 siblings, 0 replies; 214+ messages in thread
From: kbuild test robot @ 2016-06-27  4:51 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

[auto build test ERROR on peter.chen-usb/ci-for-usb-next]
[also build test ERROR on v4.7-rc5 next-20160624]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Stephen-Boyd/Support-qcom-s-HSIC-USB-and-rewrite-USB2-HS-phy-support/20160627-102637
base:   https://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb ci-for-usb-next
config: arm-multi_v5_defconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 5.3.1-8) 5.3.1 20160205
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=arm 

All errors (new ones prefixed by >>):

   drivers/built-in.o: In function `ci_hdrc_msm_remove':
>> drivers/usb/chipidea/ci_hdrc_msm.c:275: undefined reference to `reset_controller_unregister'

vim +275 drivers/usb/chipidea/ci_hdrc_msm.c

   269	
   270		pm_runtime_put(&pdev->dev);
   271		pm_runtime_disable(&pdev->dev);
   272		ci_hdrc_remove_device(ci->ci);
   273		clk_disable_unprepare(ci->iface_clk);
   274		clk_disable_unprepare(ci->core_clk);
 > 275		reset_controller_unregister(&ci->rcdev);
   276	
   277		return 0;
   278	}

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/octet-stream
Size: 23385 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160627/6d6296a1/attachment-0001.obj>

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

* Re: [PATCH 18/21] usb: chipidea: msm: Add reset controller for PHY POR bit
  2016-06-26  7:28   ` Stephen Boyd
@ 2016-06-27  7:50     ` kbuild test robot
  -1 siblings, 0 replies; 214+ messages in thread
From: kbuild test robot @ 2016-06-27  7:50 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: kbuild-all, linux-usb, linux-arm-kernel, linux-kernel,
	linux-arm-msm, Andy Gross, Bjorn Andersson, Neil Armstrong,
	Arnd Bergmann, Felipe Balbi, Peter Chen, Greg Kroah-Hartman

[-- Attachment #1: Type: text/plain, Size: 925 bytes --]

Hi,

[auto build test ERROR on peter.chen-usb/ci-for-usb-next]
[also build test ERROR on v4.7-rc5 next-20160624]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Stephen-Boyd/Support-qcom-s-HSIC-USB-and-rewrite-USB2-HS-phy-support/20160627-102637
base:   https://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb ci-for-usb-next
config: x86_64-randconfig-s5-06271251 (attached as .config)
compiler: gcc-6 (Debian 6.1.1-1) 6.1.1 20160430
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

>> ERROR: "reset_controller_unregister" [drivers/usb/chipidea/ci_hdrc_msm.ko] undefined!

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 21055 bytes --]

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

* [PATCH 18/21] usb: chipidea: msm: Add reset controller for PHY POR bit
@ 2016-06-27  7:50     ` kbuild test robot
  0 siblings, 0 replies; 214+ messages in thread
From: kbuild test robot @ 2016-06-27  7:50 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

[auto build test ERROR on peter.chen-usb/ci-for-usb-next]
[also build test ERROR on v4.7-rc5 next-20160624]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Stephen-Boyd/Support-qcom-s-HSIC-USB-and-rewrite-USB2-HS-phy-support/20160627-102637
base:   https://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb ci-for-usb-next
config: x86_64-randconfig-s5-06271251 (attached as .config)
compiler: gcc-6 (Debian 6.1.1-1) 6.1.1 20160430
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

>> ERROR: "reset_controller_unregister" [drivers/usb/chipidea/ci_hdrc_msm.ko] undefined!

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/octet-stream
Size: 21055 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160627/41fd2cc4/attachment-0001.obj>

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

* RE: [PATCH 04/21] usb: chipidea: Only read/write OTGSC from one place
  2016-06-26  7:28   ` Stephen Boyd
  (?)
@ 2016-06-27  8:04     ` Jun Li
  -1 siblings, 0 replies; 214+ messages in thread
From: Jun Li @ 2016-06-27  8:04 UTC (permalink / raw)
  To: Stephen Boyd, linux-usb
  Cc: linux-arm-kernel, linux-kernel, linux-arm-msm, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Peter Chen, Greg Kroah-Hartman, Ivan T. Ivanov

Hi

> -----Original Message-----
> From: linux-usb-owner@vger.kernel.org [mailto:linux-usb-
> owner@vger.kernel.org] On Behalf Of Stephen Boyd
> Sent: Sunday, June 26, 2016 3:28 PM
> To: linux-usb@vger.kernel.org
> Cc: linux-arm-kernel@lists.infradead.org; linux-kernel@vger.kernel.org;
> linux-arm-msm@vger.kernel.org; Andy Gross <andy.gross@linaro.org>; Bjorn
> Andersson <bjorn.andersson@linaro.org>; Neil Armstrong
> <narmstrong@baylibre.com>; Arnd Bergmann <arnd@arndb.de>; Felipe Balbi
> <balbi@kernel.org>; Peter Chen <peter.chen@nxp.com>; Greg Kroah-Hartman
> <gregkh@linuxfoundation.org>; Ivan T. Ivanov <iivanov.xz@gmail.com>
> Subject: [PATCH 04/21] usb: chipidea: Only read/write OTGSC from one place
> 
> With the id and vbus detection done via extcon we need to make sure we
> poll the status of OTGSC properly by considering what the extcon is saying,
> and not just what the register is saying. Let's move this hw_wait_reg()
> function to the only place it's used and simplify it for polling the OTGSC
> register. Then we can make certain we only use the hw_read_otgsc() API to
> read OTGSC, which will make sure we properly handle extcon events.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: "Ivan T. Ivanov" <iivanov.xz@gmail.com>
> Fixes: 3ecb3e09b042 ("usb: chipidea: Use extcon framework for VBUS and ID
> detect")
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/core.c | 32 --------------------------------
> drivers/usb/chipidea/otg.c  | 35 +++++++++++++++++++++++++++++++----
>  2 files changed, 31 insertions(+), 36 deletions(-)
> 
> diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
> index 69426e644d17..01390e02ee53 100644
> --- a/drivers/usb/chipidea/core.c
> +++ b/drivers/usb/chipidea/core.c
> @@ -516,38 +516,6 @@ int hw_device_reset(struct ci_hdrc *ci)
>  	return 0;
>  }
> 
> -/**
> - * hw_wait_reg: wait the register value
> - *
> - * Sometimes, it needs to wait register value before going on.
> - * Eg, when switch to device mode, the vbus value should be lower
> - * than OTGSC_BSV before connects to host.
> - *
> - * @ci: the controller
> - * @reg: register index
> - * @mask: mast bit
> - * @value: the bit value to wait
> - * @timeout_ms: timeout in millisecond
> - *
> - * This function returns an error code if timeout
> - */
> -int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
> -				u32 value, unsigned int timeout_ms)
> -{
> -	unsigned long elapse = jiffies + msecs_to_jiffies(timeout_ms);
> -
> -	while (hw_read(ci, reg, mask) != value) {
> -		if (time_after(jiffies, elapse)) {
> -			dev_err(ci->dev, "timeout waiting for %08x in %d\n",
> -					mask, reg);
> -			return -ETIMEDOUT;
> -		}
> -		msleep(20);
> -	}
> -
> -	return 0;
> -}
> -
>  static irqreturn_t ci_irq(int irq, void *data)  {
>  	struct ci_hdrc *ci = data;
> diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c index
> 03b6743461d1..763a8332b009 100644
> --- a/drivers/usb/chipidea/otg.c
> +++ b/drivers/usb/chipidea/otg.c
> @@ -104,7 +104,32 @@ void ci_handle_vbus_change(struct ci_hdrc *ci)
>  		usb_gadget_vbus_disconnect(&ci->gadget);
>  }
> 
> -#define CI_VBUS_STABLE_TIMEOUT_MS 5000
> +/**
> + * Sometimes, it needs to wait register value before going on.
> + * Eg, when switch to device mode, the vbus value should be lower
> + * than OTGSC_BSV before connects to host.

This should be updated since this API is dedicated for BSV now.

> + *
> + * @ci: the controller
> + *
> + * This function returns an error code if timeout  */ static int
> +hw_wait_otgsc_bsv(struct ci_hdrc *ci) {
> +	unsigned long elapse = jiffies + msecs_to_jiffies(5000);
> +	u32 mask = OTGSC_BSV;
> +
> +	while (!hw_read_otgsc(ci, mask)) {

Reverse logic, should be:
while (hw_read_otgsc(ci, mask)) {

Li Jun

> +		if (time_after(jiffies, elapse)) {
> +			dev_err(ci->dev, "timeout waiting for %08x in OTGSC\n",
> +					mask);
> +			return -ETIMEDOUT;
> +		}
> +		msleep(20);
> +	}
> +
> +	return 0;
> +}
> +
>  static void ci_handle_id_switch(struct ci_hdrc *ci)  {
>  	enum ci_role role = ci_otg_role(ci);
> @@ -116,9 +141,11 @@ static void ci_handle_id_switch(struct ci_hdrc *ci)
>  		ci_role_stop(ci);
> 
>  		if (role == CI_ROLE_GADGET)
> -			/* wait vbus lower than OTGSC_BSV */
> -			hw_wait_reg(ci, OP_OTGSC, OTGSC_BSV, 0,
> -					CI_VBUS_STABLE_TIMEOUT_MS);
> +			/*
> +			 * wait vbus lower than OTGSC_BSV before connecting
> +			 * to host
> +			 */
> +			hw_wait_otgsc_bsv(ci);
> 
>  		ci_role_start(ci, role);
>  	}
> --
> 2.9.0.rc2.8.ga28705d
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo@vger.kernel.org More majordomo info at
> http://vger.kernel.org/majordomo-info.html

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

* RE: [PATCH 04/21] usb: chipidea: Only read/write OTGSC from one place
@ 2016-06-27  8:04     ` Jun Li
  0 siblings, 0 replies; 214+ messages in thread
From: Jun Li @ 2016-06-27  8:04 UTC (permalink / raw)
  To: Stephen Boyd, linux-usb
  Cc: linux-arm-kernel, linux-kernel, linux-arm-msm, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Peter Chen, Greg Kroah-Hartman, Ivan T. Ivanov

Hi

> -----Original Message-----
> From: linux-usb-owner@vger.kernel.org [mailto:linux-usb-
> owner@vger.kernel.org] On Behalf Of Stephen Boyd
> Sent: Sunday, June 26, 2016 3:28 PM
> To: linux-usb@vger.kernel.org
> Cc: linux-arm-kernel@lists.infradead.org; linux-kernel@vger.kernel.org;
> linux-arm-msm@vger.kernel.org; Andy Gross <andy.gross@linaro.org>; Bjorn
> Andersson <bjorn.andersson@linaro.org>; Neil Armstrong
> <narmstrong@baylibre.com>; Arnd Bergmann <arnd@arndb.de>; Felipe Balbi
> <balbi@kernel.org>; Peter Chen <peter.chen@nxp.com>; Greg Kroah-Hartman
> <gregkh@linuxfoundation.org>; Ivan T. Ivanov <iivanov.xz@gmail.com>
> Subject: [PATCH 04/21] usb: chipidea: Only read/write OTGSC from one place
> 
> With the id and vbus detection done via extcon we need to make sure we
> poll the status of OTGSC properly by considering what the extcon is saying,
> and not just what the register is saying. Let's move this hw_wait_reg()
> function to the only place it's used and simplify it for polling the OTGSC
> register. Then we can make certain we only use the hw_read_otgsc() API to
> read OTGSC, which will make sure we properly handle extcon events.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: "Ivan T. Ivanov" <iivanov.xz@gmail.com>
> Fixes: 3ecb3e09b042 ("usb: chipidea: Use extcon framework for VBUS and ID
> detect")
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/core.c | 32 --------------------------------
> drivers/usb/chipidea/otg.c  | 35 +++++++++++++++++++++++++++++++----
>  2 files changed, 31 insertions(+), 36 deletions(-)
> 
> diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
> index 69426e644d17..01390e02ee53 100644
> --- a/drivers/usb/chipidea/core.c
> +++ b/drivers/usb/chipidea/core.c
> @@ -516,38 +516,6 @@ int hw_device_reset(struct ci_hdrc *ci)
>  	return 0;
>  }
> 
> -/**
> - * hw_wait_reg: wait the register value
> - *
> - * Sometimes, it needs to wait register value before going on.
> - * Eg, when switch to device mode, the vbus value should be lower
> - * than OTGSC_BSV before connects to host.
> - *
> - * @ci: the controller
> - * @reg: register index
> - * @mask: mast bit
> - * @value: the bit value to wait
> - * @timeout_ms: timeout in millisecond
> - *
> - * This function returns an error code if timeout
> - */
> -int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
> -				u32 value, unsigned int timeout_ms)
> -{
> -	unsigned long elapse = jiffies + msecs_to_jiffies(timeout_ms);
> -
> -	while (hw_read(ci, reg, mask) != value) {
> -		if (time_after(jiffies, elapse)) {
> -			dev_err(ci->dev, "timeout waiting for %08x in %d\n",
> -					mask, reg);
> -			return -ETIMEDOUT;
> -		}
> -		msleep(20);
> -	}
> -
> -	return 0;
> -}
> -
>  static irqreturn_t ci_irq(int irq, void *data)  {
>  	struct ci_hdrc *ci = data;
> diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c index
> 03b6743461d1..763a8332b009 100644
> --- a/drivers/usb/chipidea/otg.c
> +++ b/drivers/usb/chipidea/otg.c
> @@ -104,7 +104,32 @@ void ci_handle_vbus_change(struct ci_hdrc *ci)
>  		usb_gadget_vbus_disconnect(&ci->gadget);
>  }
> 
> -#define CI_VBUS_STABLE_TIMEOUT_MS 5000
> +/**
> + * Sometimes, it needs to wait register value before going on.
> + * Eg, when switch to device mode, the vbus value should be lower
> + * than OTGSC_BSV before connects to host.

This should be updated since this API is dedicated for BSV now.

> + *
> + * @ci: the controller
> + *
> + * This function returns an error code if timeout  */ static int
> +hw_wait_otgsc_bsv(struct ci_hdrc *ci) {
> +	unsigned long elapse = jiffies + msecs_to_jiffies(5000);
> +	u32 mask = OTGSC_BSV;
> +
> +	while (!hw_read_otgsc(ci, mask)) {

Reverse logic, should be:
while (hw_read_otgsc(ci, mask)) {

Li Jun

> +		if (time_after(jiffies, elapse)) {
> +			dev_err(ci->dev, "timeout waiting for %08x in OTGSC\n",
> +					mask);
> +			return -ETIMEDOUT;
> +		}
> +		msleep(20);
> +	}
> +
> +	return 0;
> +}
> +
>  static void ci_handle_id_switch(struct ci_hdrc *ci)  {
>  	enum ci_role role = ci_otg_role(ci);
> @@ -116,9 +141,11 @@ static void ci_handle_id_switch(struct ci_hdrc *ci)
>  		ci_role_stop(ci);
> 
>  		if (role == CI_ROLE_GADGET)
> -			/* wait vbus lower than OTGSC_BSV */
> -			hw_wait_reg(ci, OP_OTGSC, OTGSC_BSV, 0,
> -					CI_VBUS_STABLE_TIMEOUT_MS);
> +			/*
> +			 * wait vbus lower than OTGSC_BSV before connecting
> +			 * to host
> +			 */
> +			hw_wait_otgsc_bsv(ci);
> 
>  		ci_role_start(ci, role);
>  	}
> --
> 2.9.0.rc2.8.ga28705d
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo@vger.kernel.org More majordomo info at
> http://vger.kernel.org/majordomo-info.html

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

* [PATCH 04/21] usb: chipidea: Only read/write OTGSC from one place
@ 2016-06-27  8:04     ` Jun Li
  0 siblings, 0 replies; 214+ messages in thread
From: Jun Li @ 2016-06-27  8:04 UTC (permalink / raw)
  To: linux-arm-kernel

Hi

> -----Original Message-----
> From: linux-usb-owner at vger.kernel.org [mailto:linux-usb-
> owner at vger.kernel.org] On Behalf Of Stephen Boyd
> Sent: Sunday, June 26, 2016 3:28 PM
> To: linux-usb at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org;
> linux-arm-msm at vger.kernel.org; Andy Gross <andy.gross@linaro.org>; Bjorn
> Andersson <bjorn.andersson@linaro.org>; Neil Armstrong
> <narmstrong@baylibre.com>; Arnd Bergmann <arnd@arndb.de>; Felipe Balbi
> <balbi@kernel.org>; Peter Chen <peter.chen@nxp.com>; Greg Kroah-Hartman
> <gregkh@linuxfoundation.org>; Ivan T. Ivanov <iivanov.xz@gmail.com>
> Subject: [PATCH 04/21] usb: chipidea: Only read/write OTGSC from one place
> 
> With the id and vbus detection done via extcon we need to make sure we
> poll the status of OTGSC properly by considering what the extcon is saying,
> and not just what the register is saying. Let's move this hw_wait_reg()
> function to the only place it's used and simplify it for polling the OTGSC
> register. Then we can make certain we only use the hw_read_otgsc() API to
> read OTGSC, which will make sure we properly handle extcon events.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: "Ivan T. Ivanov" <iivanov.xz@gmail.com>
> Fixes: 3ecb3e09b042 ("usb: chipidea: Use extcon framework for VBUS and ID
> detect")
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/core.c | 32 --------------------------------
> drivers/usb/chipidea/otg.c  | 35 +++++++++++++++++++++++++++++++----
>  2 files changed, 31 insertions(+), 36 deletions(-)
> 
> diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
> index 69426e644d17..01390e02ee53 100644
> --- a/drivers/usb/chipidea/core.c
> +++ b/drivers/usb/chipidea/core.c
> @@ -516,38 +516,6 @@ int hw_device_reset(struct ci_hdrc *ci)
>  	return 0;
>  }
> 
> -/**
> - * hw_wait_reg: wait the register value
> - *
> - * Sometimes, it needs to wait register value before going on.
> - * Eg, when switch to device mode, the vbus value should be lower
> - * than OTGSC_BSV before connects to host.
> - *
> - * @ci: the controller
> - * @reg: register index
> - * @mask: mast bit
> - * @value: the bit value to wait
> - * @timeout_ms: timeout in millisecond
> - *
> - * This function returns an error code if timeout
> - */
> -int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
> -				u32 value, unsigned int timeout_ms)
> -{
> -	unsigned long elapse = jiffies + msecs_to_jiffies(timeout_ms);
> -
> -	while (hw_read(ci, reg, mask) != value) {
> -		if (time_after(jiffies, elapse)) {
> -			dev_err(ci->dev, "timeout waiting for %08x in %d\n",
> -					mask, reg);
> -			return -ETIMEDOUT;
> -		}
> -		msleep(20);
> -	}
> -
> -	return 0;
> -}
> -
>  static irqreturn_t ci_irq(int irq, void *data)  {
>  	struct ci_hdrc *ci = data;
> diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c index
> 03b6743461d1..763a8332b009 100644
> --- a/drivers/usb/chipidea/otg.c
> +++ b/drivers/usb/chipidea/otg.c
> @@ -104,7 +104,32 @@ void ci_handle_vbus_change(struct ci_hdrc *ci)
>  		usb_gadget_vbus_disconnect(&ci->gadget);
>  }
> 
> -#define CI_VBUS_STABLE_TIMEOUT_MS 5000
> +/**
> + * Sometimes, it needs to wait register value before going on.
> + * Eg, when switch to device mode, the vbus value should be lower
> + * than OTGSC_BSV before connects to host.

This should be updated since this API is dedicated for BSV now.

> + *
> + * @ci: the controller
> + *
> + * This function returns an error code if timeout  */ static int
> +hw_wait_otgsc_bsv(struct ci_hdrc *ci) {
> +	unsigned long elapse = jiffies + msecs_to_jiffies(5000);
> +	u32 mask = OTGSC_BSV;
> +
> +	while (!hw_read_otgsc(ci, mask)) {

Reverse logic, should be:
while (hw_read_otgsc(ci, mask)) {

Li Jun

> +		if (time_after(jiffies, elapse)) {
> +			dev_err(ci->dev, "timeout waiting for %08x in OTGSC\n",
> +					mask);
> +			return -ETIMEDOUT;
> +		}
> +		msleep(20);
> +	}
> +
> +	return 0;
> +}
> +
>  static void ci_handle_id_switch(struct ci_hdrc *ci)  {
>  	enum ci_role role = ci_otg_role(ci);
> @@ -116,9 +141,11 @@ static void ci_handle_id_switch(struct ci_hdrc *ci)
>  		ci_role_stop(ci);
> 
>  		if (role == CI_ROLE_GADGET)
> -			/* wait vbus lower than OTGSC_BSV */
> -			hw_wait_reg(ci, OP_OTGSC, OTGSC_BSV, 0,
> -					CI_VBUS_STABLE_TIMEOUT_MS);
> +			/*
> +			 * wait vbus lower than OTGSC_BSV before connecting
> +			 * to host
> +			 */
> +			hw_wait_otgsc_bsv(ci);
> 
>  		ci_role_start(ci, role);
>  	}
> --
> 2.9.0.rc2.8.ga28705d
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo at vger.kernel.org More majordomo info at
> http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 02/21] usb: ulpi: Support device discovery via DT
  2016-06-26  7:28     ` Stephen Boyd
@ 2016-06-27 14:34       ` Heikki Krogerus
  -1 siblings, 0 replies; 214+ messages in thread
From: Heikki Krogerus @ 2016-06-27 14:34 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, linux-arm-kernel, linux-kernel, linux-arm-msm,
	Andy Gross, Bjorn Andersson, Neil Armstrong, Arnd Bergmann,
	Felipe Balbi, Greg Kroah-Hartman, devicetree, Rob Herring

Hi,

I'm fine with most of the patch, except..

On Sun, Jun 26, 2016 at 12:28:19AM -0700, Stephen Boyd wrote:
> @@ -39,7 +42,10 @@ static int ulpi_match(struct device *dev, struct device_driver *driver)
>  	struct ulpi *ulpi = to_ulpi_dev(dev);
>  	const struct ulpi_device_id *id;
>  
> -	for (id = drv->id_table; id->vendor; id++)
> +	if (of_driver_match_device(dev, driver))
> +		return 1;

I don't like this part. We should match separately like that only
if the bus does not support native enumeration, and of course ULPI
with its vendor and product IDs does. There really should always be
IDs to match with here. So exceptions have to be solved before we
attempt matching.

Since we also have to support platforms where the PHY is initially
powered off and reading the IDs from the registers is not possible
because of that, I think we should consider getting the product and
vendor IDs optionally from device properties. Something like this:


diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c
index 01c0c04..6228a85 100644
--- a/drivers/usb/common/ulpi.c
+++ b/drivers/usb/common/ulpi.c
@@ -152,7 +152,7 @@ EXPORT_SYMBOL_GPL(ulpi_unregister_driver);
 
 /* -------------------------------------------------------------------------- */
 
-static int ulpi_register(struct device *dev, struct ulpi *ulpi)
+static int ulpi_read_id(struct ulpi *ulpi)
 {
        int ret;
 
@@ -174,6 +174,21 @@ static int ulpi_register(struct device *dev, struct ulpi *ulpi)
        ulpi->id.product = ulpi_read(ulpi, ULPI_PRODUCT_ID_LOW);
        ulpi->id.product |= ulpi_read(ulpi, ULPI_PRODUCT_ID_HIGH) << 8;
 
+       return 0;
+}
+
+static int ulpi_register(struct device *dev, struct ulpi *ulpi)
+{
+       int ret;
+
+       ret = device_property_read_u16(dev, "ulpi-vendor", &ulpi->id.vendor);
+       ret |= device_property_read_u16(dev, "ulpi-product", &ulpi->id.product);
+       if (ret) {
+               ret = ulpi_read_id(ulpi);
+               if (ret)
+                       return ret;
+       }
+
        ulpi->dev.parent = dev;
        ulpi->dev.bus = &ulpi_bus;
        ulpi->dev.type = &ulpi_dev_type;


That should cover both cases. You would just have to create the IDs
yourself in this case.


Thanks,

-- 
heikki

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

* [PATCH 02/21] usb: ulpi: Support device discovery via DT
@ 2016-06-27 14:34       ` Heikki Krogerus
  0 siblings, 0 replies; 214+ messages in thread
From: Heikki Krogerus @ 2016-06-27 14:34 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

I'm fine with most of the patch, except..

On Sun, Jun 26, 2016 at 12:28:19AM -0700, Stephen Boyd wrote:
> @@ -39,7 +42,10 @@ static int ulpi_match(struct device *dev, struct device_driver *driver)
>  	struct ulpi *ulpi = to_ulpi_dev(dev);
>  	const struct ulpi_device_id *id;
>  
> -	for (id = drv->id_table; id->vendor; id++)
> +	if (of_driver_match_device(dev, driver))
> +		return 1;

I don't like this part. We should match separately like that only
if the bus does not support native enumeration, and of course ULPI
with its vendor and product IDs does. There really should always be
IDs to match with here. So exceptions have to be solved before we
attempt matching.

Since we also have to support platforms where the PHY is initially
powered off and reading the IDs from the registers is not possible
because of that, I think we should consider getting the product and
vendor IDs optionally from device properties. Something like this:


diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c
index 01c0c04..6228a85 100644
--- a/drivers/usb/common/ulpi.c
+++ b/drivers/usb/common/ulpi.c
@@ -152,7 +152,7 @@ EXPORT_SYMBOL_GPL(ulpi_unregister_driver);
 
 /* -------------------------------------------------------------------------- */
 
-static int ulpi_register(struct device *dev, struct ulpi *ulpi)
+static int ulpi_read_id(struct ulpi *ulpi)
 {
        int ret;
 
@@ -174,6 +174,21 @@ static int ulpi_register(struct device *dev, struct ulpi *ulpi)
        ulpi->id.product = ulpi_read(ulpi, ULPI_PRODUCT_ID_LOW);
        ulpi->id.product |= ulpi_read(ulpi, ULPI_PRODUCT_ID_HIGH) << 8;
 
+       return 0;
+}
+
+static int ulpi_register(struct device *dev, struct ulpi *ulpi)
+{
+       int ret;
+
+       ret = device_property_read_u16(dev, "ulpi-vendor", &ulpi->id.vendor);
+       ret |= device_property_read_u16(dev, "ulpi-product", &ulpi->id.product);
+       if (ret) {
+               ret = ulpi_read_id(ulpi);
+               if (ret)
+                       return ret;
+       }
+
        ulpi->dev.parent = dev;
        ulpi->dev.bus = &ulpi_bus;
        ulpi->dev.type = &ulpi_dev_type;


That should cover both cases. You would just have to create the IDs
yourself in this case.


Thanks,

-- 
heikki

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

* RE: [PATCH 04/21] usb: chipidea: Only read/write OTGSC from one place
  2016-06-27  8:04     ` Jun Li
  (?)
@ 2016-06-27 19:07         ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-27 19:07 UTC (permalink / raw)
  To: Jun Li, linux-usb-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Peter Chen, Greg Kroah-Hartman, Ivan T. Ivanov

Quoting Jun Li (2016-06-27 01:04:39)
> > diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c index
> > 03b6743461d1..763a8332b009 100644
> > --- a/drivers/usb/chipidea/otg.c
> > +++ b/drivers/usb/chipidea/otg.c
> > @@ -104,7 +104,32 @@ void ci_handle_vbus_change(struct ci_hdrc *ci)
> >               usb_gadget_vbus_disconnect(&ci->gadget);
> >  }
> > 
> > -#define CI_VBUS_STABLE_TIMEOUT_MS 5000
> > +/**
> > + * Sometimes, it needs to wait register value before going on.
> > + * Eg, when switch to device mode, the vbus value should be lower
> > + * than OTGSC_BSV before connects to host.
> 
> This should be updated since this API is dedicated for BSV now.

Ok I've updated it to say:

  When we switch to device mode, the vbus value should be lower
  than OTGSC_BSV before connecting to host.

> 
> > + *
> > + * @ci: the controller
> > + *
> > + * This function returns an error code if timeout  */ static int
> > +hw_wait_otgsc_bsv(struct ci_hdrc *ci) {
> > +     unsigned long elapse = jiffies + msecs_to_jiffies(5000);
> > +     u32 mask = OTGSC_BSV;
> > +
> > +     while (!hw_read_otgsc(ci, mask)) {
> 
> Reverse logic, should be:
> while (hw_read_otgsc(ci, mask)) {
> 

Good catch! Thanks.
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* RE: [PATCH 04/21] usb: chipidea: Only read/write OTGSC from one place
@ 2016-06-27 19:07         ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-27 19:07 UTC (permalink / raw)
  To: Jun Li, linux-usb
  Cc: linux-arm-kernel, linux-kernel, linux-arm-msm, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Peter Chen, Greg Kroah-Hartman, Ivan T. Ivanov

Quoting Jun Li (2016-06-27 01:04:39)
> > diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c index
> > 03b6743461d1..763a8332b009 100644
> > --- a/drivers/usb/chipidea/otg.c
> > +++ b/drivers/usb/chipidea/otg.c
> > @@ -104,7 +104,32 @@ void ci_handle_vbus_change(struct ci_hdrc *ci)
> >               usb_gadget_vbus_disconnect(&ci->gadget);
> >  }
> > 
> > -#define CI_VBUS_STABLE_TIMEOUT_MS 5000
> > +/**
> > + * Sometimes, it needs to wait register value before going on.
> > + * Eg, when switch to device mode, the vbus value should be lower
> > + * than OTGSC_BSV before connects to host.
> 
> This should be updated since this API is dedicated for BSV now.

Ok I've updated it to say:

  When we switch to device mode, the vbus value should be lower
  than OTGSC_BSV before connecting to host.

> 
> > + *
> > + * @ci: the controller
> > + *
> > + * This function returns an error code if timeout  */ static int
> > +hw_wait_otgsc_bsv(struct ci_hdrc *ci) {
> > +     unsigned long elapse = jiffies + msecs_to_jiffies(5000);
> > +     u32 mask = OTGSC_BSV;
> > +
> > +     while (!hw_read_otgsc(ci, mask)) {
> 
> Reverse logic, should be:
> while (hw_read_otgsc(ci, mask)) {
> 

Good catch! Thanks.

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

* [PATCH 04/21] usb: chipidea: Only read/write OTGSC from one place
@ 2016-06-27 19:07         ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-27 19:07 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Jun Li (2016-06-27 01:04:39)
> > diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c index
> > 03b6743461d1..763a8332b009 100644
> > --- a/drivers/usb/chipidea/otg.c
> > +++ b/drivers/usb/chipidea/otg.c
> > @@ -104,7 +104,32 @@ void ci_handle_vbus_change(struct ci_hdrc *ci)
> >               usb_gadget_vbus_disconnect(&ci->gadget);
> >  }
> > 
> > -#define CI_VBUS_STABLE_TIMEOUT_MS 5000
> > +/**
> > + * Sometimes, it needs to wait register value before going on.
> > + * Eg, when switch to device mode, the vbus value should be lower
> > + * than OTGSC_BSV before connects to host.
> 
> This should be updated since this API is dedicated for BSV now.

Ok I've updated it to say:

  When we switch to device mode, the vbus value should be lower
  than OTGSC_BSV before connecting to host.

> 
> > + *
> > + * @ci: the controller
> > + *
> > + * This function returns an error code if timeout  */ static int
> > +hw_wait_otgsc_bsv(struct ci_hdrc *ci) {
> > +     unsigned long elapse = jiffies + msecs_to_jiffies(5000);
> > +     u32 mask = OTGSC_BSV;
> > +
> > +     while (!hw_read_otgsc(ci, mask)) {
> 
> Reverse logic, should be:
> while (hw_read_otgsc(ci, mask)) {
> 

Good catch! Thanks.

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

* Re: [PATCH 02/21] usb: ulpi: Support device discovery via DT
  2016-06-27 14:34       ` Heikki Krogerus
@ 2016-06-27 22:10         ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-27 22:10 UTC (permalink / raw)
  To: Heikki Krogerus
  Cc: Felipe Balbi, Arnd Bergmann, Neil Armstrong, linux-arm-msm,
	linux-usb, linux-kernel, Bjorn Andersson, devicetree,
	Rob Herring, Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

Quoting Heikki Krogerus (2016-06-27 07:34:22)
> Hi,
> 
> I'm fine with most of the patch, except..
> 
> On Sun, Jun 26, 2016 at 12:28:19AM -0700, Stephen Boyd wrote:
> > @@ -39,7 +42,10 @@ static int ulpi_match(struct device *dev, struct device_driver *driver)
> >       struct ulpi *ulpi = to_ulpi_dev(dev);
> >       const struct ulpi_device_id *id;
> >  
> > -     for (id = drv->id_table; id->vendor; id++)
> > +     if (of_driver_match_device(dev, driver))
> > +             return 1;
> 
> I don't like this part. We should match separately like that only
> if the bus does not support native enumeration, and of course ULPI
> with its vendor and product IDs does. There really should always be
> IDs to match with here. So exceptions have to be solved before we
> attempt matching.
> 
> Since we also have to support platforms where the PHY is initially
> powered off and reading the IDs from the registers is not possible
> because of that, I think we should consider getting the product and
> vendor IDs optionally from device properties. Something like this:

Ok, I'm a little worried about conflating the powered off problem with
this product/vendor ID missing problem. But if you're ok with that I'll
combine the two patches into one using your approach below.

> 
> 
> diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c
> index 01c0c04..6228a85 100644
> --- a/drivers/usb/common/ulpi.c
> +++ b/drivers/usb/common/ulpi.c
> @@ -152,7 +152,7 @@ EXPORT_SYMBOL_GPL(ulpi_unregister_driver);
>  
>  /* -------------------------------------------------------------------------- */
>  
> -static int ulpi_register(struct device *dev, struct ulpi *ulpi)
> +static int ulpi_read_id(struct ulpi *ulpi)
>  {
>         int ret;
>  
> @@ -174,6 +174,21 @@ static int ulpi_register(struct device *dev, struct ulpi *ulpi)
>         ulpi->id.product = ulpi_read(ulpi, ULPI_PRODUCT_ID_LOW);
>         ulpi->id.product |= ulpi_read(ulpi, ULPI_PRODUCT_ID_HIGH) << 8;
>  
> +       return 0;
> +}
> +
> +static int ulpi_register(struct device *dev, struct ulpi *ulpi)
> +{
> +       int ret;
> +
> +       ret = device_property_read_u16(dev, "ulpi-vendor", &ulpi->id.vendor);
> +       ret |= device_property_read_u16(dev, "ulpi-product", &ulpi->id.product);
> +       if (ret) {
> +               ret = ulpi_read_id(ulpi);
> +               if (ret)
> +                       return ret;
> +       }
> +
>         ulpi->dev.parent = dev;
>         ulpi->dev.bus = &ulpi_bus;
>         ulpi->dev.type = &ulpi_dev_type;
> 
> 
> That should cover both cases. You would just have to create the IDs
> yourself in this case.
> 

Right, I would have to make up some IDs in this case. I suppose I can
use the qcom vendor ID 0x05c6 and then product ids 0 and 1 for HS phy
and HSIC phy? That doesn't make me feel great because it's all made up,
but I guess there's no other option. I hope they don't decide to start
populating these ids in the future though and then we may have
conflicting product ids. If that happens I suppose we can do a
workaround based on compatible strings in the DT node. Fun!

Nice side effect of all that is I can drop requesting the module by DT
aliases and things become simpler. I'll try this out.

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

* [PATCH 02/21] usb: ulpi: Support device discovery via DT
@ 2016-06-27 22:10         ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-27 22:10 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Heikki Krogerus (2016-06-27 07:34:22)
> Hi,
> 
> I'm fine with most of the patch, except..
> 
> On Sun, Jun 26, 2016 at 12:28:19AM -0700, Stephen Boyd wrote:
> > @@ -39,7 +42,10 @@ static int ulpi_match(struct device *dev, struct device_driver *driver)
> >       struct ulpi *ulpi = to_ulpi_dev(dev);
> >       const struct ulpi_device_id *id;
> >  
> > -     for (id = drv->id_table; id->vendor; id++)
> > +     if (of_driver_match_device(dev, driver))
> > +             return 1;
> 
> I don't like this part. We should match separately like that only
> if the bus does not support native enumeration, and of course ULPI
> with its vendor and product IDs does. There really should always be
> IDs to match with here. So exceptions have to be solved before we
> attempt matching.
> 
> Since we also have to support platforms where the PHY is initially
> powered off and reading the IDs from the registers is not possible
> because of that, I think we should consider getting the product and
> vendor IDs optionally from device properties. Something like this:

Ok, I'm a little worried about conflating the powered off problem with
this product/vendor ID missing problem. But if you're ok with that I'll
combine the two patches into one using your approach below.

> 
> 
> diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c
> index 01c0c04..6228a85 100644
> --- a/drivers/usb/common/ulpi.c
> +++ b/drivers/usb/common/ulpi.c
> @@ -152,7 +152,7 @@ EXPORT_SYMBOL_GPL(ulpi_unregister_driver);
>  
>  /* -------------------------------------------------------------------------- */
>  
> -static int ulpi_register(struct device *dev, struct ulpi *ulpi)
> +static int ulpi_read_id(struct ulpi *ulpi)
>  {
>         int ret;
>  
> @@ -174,6 +174,21 @@ static int ulpi_register(struct device *dev, struct ulpi *ulpi)
>         ulpi->id.product = ulpi_read(ulpi, ULPI_PRODUCT_ID_LOW);
>         ulpi->id.product |= ulpi_read(ulpi, ULPI_PRODUCT_ID_HIGH) << 8;
>  
> +       return 0;
> +}
> +
> +static int ulpi_register(struct device *dev, struct ulpi *ulpi)
> +{
> +       int ret;
> +
> +       ret = device_property_read_u16(dev, "ulpi-vendor", &ulpi->id.vendor);
> +       ret |= device_property_read_u16(dev, "ulpi-product", &ulpi->id.product);
> +       if (ret) {
> +               ret = ulpi_read_id(ulpi);
> +               if (ret)
> +                       return ret;
> +       }
> +
>         ulpi->dev.parent = dev;
>         ulpi->dev.bus = &ulpi_bus;
>         ulpi->dev.type = &ulpi_dev_type;
> 
> 
> That should cover both cases. You would just have to create the IDs
> yourself in this case.
> 

Right, I would have to make up some IDs in this case. I suppose I can
use the qcom vendor ID 0x05c6 and then product ids 0 and 1 for HS phy
and HSIC phy? That doesn't make me feel great because it's all made up,
but I guess there's no other option. I hope they don't decide to start
populating these ids in the future though and then we may have
conflicting product ids. If that happens I suppose we can do a
workaround based on compatible strings in the DT node. Fun!

Nice side effect of all that is I can drop requesting the module by DT
aliases and things become simpler. I'll try this out.

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

* Re: [PATCH 18/21] usb: chipidea: msm: Add reset controller for PHY POR bit
  2016-06-27  7:50     ` kbuild test robot
@ 2016-06-28  1:27       ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-28  1:27 UTC (permalink / raw)
  To: kbuild test robot
  Cc: Felipe Balbi, Arnd Bergmann, Neil Armstrong, linux-arm-msm,
	linux-usb, linux-kernel, Bjorn Andersson, Peter Chen, kbuild-all,
	Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

Quoting kbuild test robot (2016-06-27 00:50:24)
> Hi,
> 
> [auto build test ERROR on peter.chen-usb/ci-for-usb-next]
> [also build test ERROR on v4.7-rc5 next-20160624]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
> 
> url:    https://github.com/0day-ci/linux/commits/Stephen-Boyd/Support-qcom-s-HSIC-USB-and-rewrite-USB2-HS-phy-support/20160627-102637
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb ci-for-usb-next
> config: x86_64-randconfig-s5-06271251 (attached as .config)
> compiler: gcc-6 (Debian 6.1.1-1) 6.1.1 20160430
> reproduce:
>         # save the attached .config to linux build tree
>         make ARCH=x86_64 
> 
> All errors (new ones prefixed by >>):
> 
> >> ERROR: "reset_controller_unregister" [drivers/usb/chipidea/ci_hdrc_msm.ko] undefined!

Hmm. If I try to fix this by selecting RESET_CONTROLLER from the
chipidea Kconfig I get the following recursive Kconfig warning

drivers/usb/Kconfig:39:error: recursive dependency detected!
drivers/usb/Kconfig:39: symbol USB is selected by MOUSE_APPLETOUCH
drivers/input/mouse/Kconfig:187:        symbol MOUSE_APPLETOUCH depends on INPUT
drivers/input/Kconfig:8:        symbol INPUT is selected by VT
drivers/tty/Kconfig:12: symbol VT is selected by FB_STI
drivers/video/fbdev/Kconfig:674:        symbol FB_STI depends on FB
drivers/video/fbdev/Kconfig:5:  symbol FB is selected by DRM_KMS_FB_HELPER
drivers/gpu/drm/Kconfig:42:     symbol DRM_KMS_FB_HELPER is selected by DRM_KMS_CMA_HELPER
drivers/gpu/drm/Kconfig:98:     symbol DRM_KMS_CMA_HELPER is selected by DRM_IMX
drivers/gpu/drm/imx/Kconfig:1:  symbol DRM_IMX depends on IMX_IPUV3_CORE
drivers/gpu/ipu-v3/Kconfig:1:   symbol IMX_IPUV3_CORE depends on RESET_CONTROLLER
drivers/reset/Kconfig:4:        symbol RESET_CONTROLLER is selected by USB_CHIPIDEA
drivers/usb/chipidea/Kconfig:1: symbol USB_CHIPIDEA depends on USB_EHCI_HCD
drivers/usb/host/Kconfig:84:    symbol USB_EHCI_HCD depends on USB

Is the proper fix here to have IMX_IPUV3 select RESET_CONTROLLER instead
of depend on it? Doing that leads to another case where rockchip needs
to be changed from a depends on to a select, and then tegra is the same
way. Arnd, any ideas?

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

* [PATCH 18/21] usb: chipidea: msm: Add reset controller for PHY POR bit
@ 2016-06-28  1:27       ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-28  1:27 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting kbuild test robot (2016-06-27 00:50:24)
> Hi,
> 
> [auto build test ERROR on peter.chen-usb/ci-for-usb-next]
> [also build test ERROR on v4.7-rc5 next-20160624]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
> 
> url:    https://github.com/0day-ci/linux/commits/Stephen-Boyd/Support-qcom-s-HSIC-USB-and-rewrite-USB2-HS-phy-support/20160627-102637
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb ci-for-usb-next
> config: x86_64-randconfig-s5-06271251 (attached as .config)
> compiler: gcc-6 (Debian 6.1.1-1) 6.1.1 20160430
> reproduce:
>         # save the attached .config to linux build tree
>         make ARCH=x86_64 
> 
> All errors (new ones prefixed by >>):
> 
> >> ERROR: "reset_controller_unregister" [drivers/usb/chipidea/ci_hdrc_msm.ko] undefined!

Hmm. If I try to fix this by selecting RESET_CONTROLLER from the
chipidea Kconfig I get the following recursive Kconfig warning

drivers/usb/Kconfig:39:error: recursive dependency detected!
drivers/usb/Kconfig:39: symbol USB is selected by MOUSE_APPLETOUCH
drivers/input/mouse/Kconfig:187:        symbol MOUSE_APPLETOUCH depends on INPUT
drivers/input/Kconfig:8:        symbol INPUT is selected by VT
drivers/tty/Kconfig:12: symbol VT is selected by FB_STI
drivers/video/fbdev/Kconfig:674:        symbol FB_STI depends on FB
drivers/video/fbdev/Kconfig:5:  symbol FB is selected by DRM_KMS_FB_HELPER
drivers/gpu/drm/Kconfig:42:     symbol DRM_KMS_FB_HELPER is selected by DRM_KMS_CMA_HELPER
drivers/gpu/drm/Kconfig:98:     symbol DRM_KMS_CMA_HELPER is selected by DRM_IMX
drivers/gpu/drm/imx/Kconfig:1:  symbol DRM_IMX depends on IMX_IPUV3_CORE
drivers/gpu/ipu-v3/Kconfig:1:   symbol IMX_IPUV3_CORE depends on RESET_CONTROLLER
drivers/reset/Kconfig:4:        symbol RESET_CONTROLLER is selected by USB_CHIPIDEA
drivers/usb/chipidea/Kconfig:1: symbol USB_CHIPIDEA depends on USB_EHCI_HCD
drivers/usb/host/Kconfig:84:    symbol USB_EHCI_HCD depends on USB

Is the proper fix here to have IMX_IPUV3 select RESET_CONTROLLER instead
of depend on it? Doing that leads to another case where rockchip needs
to be changed from a depends on to a select, and then tegra is the same
way. Arnd, any ideas?

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

* Re: [PATCH 00/21] Support qcom's HSIC USB and rewrite USB2 HS phy support
  2016-06-26  7:28 ` Stephen Boyd
  (?)
@ 2016-06-28  3:09     ` John Stultz
  -1 siblings, 0 replies; 214+ messages in thread
From: John Stultz @ 2016-06-28  3:09 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA, Felipe Balbi, Heikki Krogerus,
	Arnd Bergmann, Neil Armstrong,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA, lkml, Bjorn Andersson,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Peter Chen,
	Greg Kroah-Hartman, Andy Gross, Ivan T. Ivanov,
	Kishon Vijay Abraham I,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Sun, Jun 26, 2016 at 12:28 AM, Stephen Boyd <stephen.boyd-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
> The state of USB ChipIdea support on Qualcomm's platforms is not great.
> The DT description of these devices requires up to three different nodes
> for what amounts to be the same hardware block, when there should really
> only be one. Furthermore, the "phy" driver that is in mainline (phy-msm-usb.c)
> duplicates the OTG state machine and touches the ci controller wrapper
> registers when it should really be focused on the phy and the ULPI accesses
> needed to get the phy working. There's also a slimmed down phy driver for
> the msm8916 platform, but really the phy hardware is the same as other MSMs,
> so we have two drivers doing pretty much the same thing. This leads to a
> situtaion where we have the chipidea core driver, the "phy" driver, and
> sometimes the ehci-msm.c driver operating the same device all at the same
> time with very little coordination. This just isn't very safe and is
> confusing from a driver perspective when trying to figure out who does what.
> Finally, there isn't any HSIC support on platforms like apq8074 so we
> should add that.
>
> This patch series updates the ChipIdea driver and the MSM wrapper
> (ci_hdrc_msm.c) to properly handle the PHY and wrapper bits at the right
> times in the right places. To get there, we update the ChipIdea core to
> have support for the ULPI phy bus introduced by Heikki. Along the way
> we fix bugs with the extcon handling for peripheral and OTG mode controllers
> and move the parts of phy-usb-msm.c that are touching the CI controller
> wrapper into the wrapper driver (ci_hdrc_msm.c). Finally we add support
> for the HSIC phy based on the ULPI bus and rewrite the HS phy driver
> (phy-usb-msm.c) as a standard ULPI phy driver.
>
> Once this series is accepted, we should be able to delete the phy-usb-msm.c
> phy-qcom-8x16-usb.c, and ehci-msm.c drivers from the tree and use the ULPI
> based phy driver (which also lives in drivers/phy/ instead of drivers/usb/phy/)
> and the chipidea host core instead.
>
> I've also sent seperate patches for other minor pieces to make this
> all work. The full tree can be found here[3], hacks and all to get
> things working. I've tested this on the db410c, apq8074 dragonboard,
> and ifc6410 with configfs gadgets and otg cables.
...
> [3] https://git.linaro.org/people/stephen.boyd/linux.git/shortlog/refs/heads/usb-hsic-8074

Very excited to see this moving upstream!

Just a heads up, trying to build with this branch gives me:

drivers/usb/Kconfig:39:error: recursive dependency detected!
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/usb/Kconfig:39: symbol USB is selected by MOUSE_APPLETOUCH
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/input/mouse/Kconfig:187:        symbol MOUSE_APPLETOUCH depends on INPUT
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/input/Kconfig:8:        symbol INPUT is selected by VT
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/tty/Kconfig:12: symbol VT is selected by FB_STI
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/video/fbdev/Kconfig:674:        symbol FB_STI depends on FB
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/video/fbdev/Kconfig:5:  symbol FB is selected by DRM_KMS_FB_HELPER
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/gpu/drm/Kconfig:42:     symbol DRM_KMS_FB_HELPER is selected
by DRM_KMS_CMA_HELPER
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/gpu/drm/Kconfig:98:     symbol DRM_KMS_CMA_HELPER is selected by DRM_IMX
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/gpu/drm/imx/Kconfig:1:  symbol DRM_IMX depends on IMX_IPUV3_CORE
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/gpu/ipu-v3/Kconfig:1:   symbol IMX_IPUV3_CORE depends on
RESET_CONTROLLER
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/reset/Kconfig:4:        symbol RESET_CONTROLLER is selected by
USB_CHIPIDEA
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/usb/chipidea/Kconfig:1: symbol USB_CHIPIDEA depends on USB_EHCI_HCD
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/usb/host/Kconfig:84:    symbol USB_EHCI_HCD depends on USB
drivers/usb/chipidea/otg.c: In function ‘hw_write_otgsc’:
drivers/usb/chipidea/otg.c:120:2: warning: format ‘%x’ expects
argument of type ‘unsigned int’, but argument 3 has type ‘long
unsigned int’ [-Wformat]
drivers/usb/chipidea/otg.c:120:2: warning: format ‘%x’ expects
argument of type ‘unsigned int’, but argument 4 has type ‘long
unsigned int’ [-Wformat]

I haven't yet been able to test with this, as I need some other fixes
it seems too to deal with some of the iommu changes in my flo-WIP tree
(it can't find of_dma_configure), but will let you know how things
work once I have all that sorted.

thanks
-john
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 00/21] Support qcom's HSIC USB and rewrite USB2 HS phy support
@ 2016-06-28  3:09     ` John Stultz
  0 siblings, 0 replies; 214+ messages in thread
From: John Stultz @ 2016-06-28  3:09 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, Felipe Balbi, Heikki Krogerus, Arnd Bergmann,
	Neil Armstrong, linux-arm-msm, lkml, Bjorn Andersson, devicetree,
	Rob Herring, Peter Chen, Greg Kroah-Hartman, Andy Gross,
	Ivan T. Ivanov, Kishon Vijay Abraham I, linux-arm-kernel

On Sun, Jun 26, 2016 at 12:28 AM, Stephen Boyd <stephen.boyd@linaro.org> wrote:
> The state of USB ChipIdea support on Qualcomm's platforms is not great.
> The DT description of these devices requires up to three different nodes
> for what amounts to be the same hardware block, when there should really
> only be one. Furthermore, the "phy" driver that is in mainline (phy-msm-usb.c)
> duplicates the OTG state machine and touches the ci controller wrapper
> registers when it should really be focused on the phy and the ULPI accesses
> needed to get the phy working. There's also a slimmed down phy driver for
> the msm8916 platform, but really the phy hardware is the same as other MSMs,
> so we have two drivers doing pretty much the same thing. This leads to a
> situtaion where we have the chipidea core driver, the "phy" driver, and
> sometimes the ehci-msm.c driver operating the same device all at the same
> time with very little coordination. This just isn't very safe and is
> confusing from a driver perspective when trying to figure out who does what.
> Finally, there isn't any HSIC support on platforms like apq8074 so we
> should add that.
>
> This patch series updates the ChipIdea driver and the MSM wrapper
> (ci_hdrc_msm.c) to properly handle the PHY and wrapper bits at the right
> times in the right places. To get there, we update the ChipIdea core to
> have support for the ULPI phy bus introduced by Heikki. Along the way
> we fix bugs with the extcon handling for peripheral and OTG mode controllers
> and move the parts of phy-usb-msm.c that are touching the CI controller
> wrapper into the wrapper driver (ci_hdrc_msm.c). Finally we add support
> for the HSIC phy based on the ULPI bus and rewrite the HS phy driver
> (phy-usb-msm.c) as a standard ULPI phy driver.
>
> Once this series is accepted, we should be able to delete the phy-usb-msm.c
> phy-qcom-8x16-usb.c, and ehci-msm.c drivers from the tree and use the ULPI
> based phy driver (which also lives in drivers/phy/ instead of drivers/usb/phy/)
> and the chipidea host core instead.
>
> I've also sent seperate patches for other minor pieces to make this
> all work. The full tree can be found here[3], hacks and all to get
> things working. I've tested this on the db410c, apq8074 dragonboard,
> and ifc6410 with configfs gadgets and otg cables.
...
> [3] https://git.linaro.org/people/stephen.boyd/linux.git/shortlog/refs/heads/usb-hsic-8074

Very excited to see this moving upstream!

Just a heads up, trying to build with this branch gives me:

drivers/usb/Kconfig:39:error: recursive dependency detected!
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/usb/Kconfig:39: symbol USB is selected by MOUSE_APPLETOUCH
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/input/mouse/Kconfig:187:        symbol MOUSE_APPLETOUCH depends on INPUT
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/input/Kconfig:8:        symbol INPUT is selected by VT
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/tty/Kconfig:12: symbol VT is selected by FB_STI
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/video/fbdev/Kconfig:674:        symbol FB_STI depends on FB
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/video/fbdev/Kconfig:5:  symbol FB is selected by DRM_KMS_FB_HELPER
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/gpu/drm/Kconfig:42:     symbol DRM_KMS_FB_HELPER is selected
by DRM_KMS_CMA_HELPER
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/gpu/drm/Kconfig:98:     symbol DRM_KMS_CMA_HELPER is selected by DRM_IMX
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/gpu/drm/imx/Kconfig:1:  symbol DRM_IMX depends on IMX_IPUV3_CORE
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/gpu/ipu-v3/Kconfig:1:   symbol IMX_IPUV3_CORE depends on
RESET_CONTROLLER
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/reset/Kconfig:4:        symbol RESET_CONTROLLER is selected by
USB_CHIPIDEA
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/usb/chipidea/Kconfig:1: symbol USB_CHIPIDEA depends on USB_EHCI_HCD
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/usb/host/Kconfig:84:    symbol USB_EHCI_HCD depends on USB
drivers/usb/chipidea/otg.c: In function ‘hw_write_otgsc’:
drivers/usb/chipidea/otg.c:120:2: warning: format ‘%x’ expects
argument of type ‘unsigned int’, but argument 3 has type ‘long
unsigned int’ [-Wformat]
drivers/usb/chipidea/otg.c:120:2: warning: format ‘%x’ expects
argument of type ‘unsigned int’, but argument 4 has type ‘long
unsigned int’ [-Wformat]

I haven't yet been able to test with this, as I need some other fixes
it seems too to deal with some of the iommu changes in my flo-WIP tree
(it can't find of_dma_configure), but will let you know how things
work once I have all that sorted.

thanks
-john

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

* [PATCH 00/21] Support qcom's HSIC USB and rewrite USB2 HS phy support
@ 2016-06-28  3:09     ` John Stultz
  0 siblings, 0 replies; 214+ messages in thread
From: John Stultz @ 2016-06-28  3:09 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Jun 26, 2016 at 12:28 AM, Stephen Boyd <stephen.boyd@linaro.org> wrote:
> The state of USB ChipIdea support on Qualcomm's platforms is not great.
> The DT description of these devices requires up to three different nodes
> for what amounts to be the same hardware block, when there should really
> only be one. Furthermore, the "phy" driver that is in mainline (phy-msm-usb.c)
> duplicates the OTG state machine and touches the ci controller wrapper
> registers when it should really be focused on the phy and the ULPI accesses
> needed to get the phy working. There's also a slimmed down phy driver for
> the msm8916 platform, but really the phy hardware is the same as other MSMs,
> so we have two drivers doing pretty much the same thing. This leads to a
> situtaion where we have the chipidea core driver, the "phy" driver, and
> sometimes the ehci-msm.c driver operating the same device all at the same
> time with very little coordination. This just isn't very safe and is
> confusing from a driver perspective when trying to figure out who does what.
> Finally, there isn't any HSIC support on platforms like apq8074 so we
> should add that.
>
> This patch series updates the ChipIdea driver and the MSM wrapper
> (ci_hdrc_msm.c) to properly handle the PHY and wrapper bits at the right
> times in the right places. To get there, we update the ChipIdea core to
> have support for the ULPI phy bus introduced by Heikki. Along the way
> we fix bugs with the extcon handling for peripheral and OTG mode controllers
> and move the parts of phy-usb-msm.c that are touching the CI controller
> wrapper into the wrapper driver (ci_hdrc_msm.c). Finally we add support
> for the HSIC phy based on the ULPI bus and rewrite the HS phy driver
> (phy-usb-msm.c) as a standard ULPI phy driver.
>
> Once this series is accepted, we should be able to delete the phy-usb-msm.c
> phy-qcom-8x16-usb.c, and ehci-msm.c drivers from the tree and use the ULPI
> based phy driver (which also lives in drivers/phy/ instead of drivers/usb/phy/)
> and the chipidea host core instead.
>
> I've also sent seperate patches for other minor pieces to make this
> all work. The full tree can be found here[3], hacks and all to get
> things working. I've tested this on the db410c, apq8074 dragonboard,
> and ifc6410 with configfs gadgets and otg cables.
...
> [3] https://git.linaro.org/people/stephen.boyd/linux.git/shortlog/refs/heads/usb-hsic-8074

Very excited to see this moving upstream!

Just a heads up, trying to build with this branch gives me:

drivers/usb/Kconfig:39:error: recursive dependency detected!
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/usb/Kconfig:39: symbol USB is selected by MOUSE_APPLETOUCH
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/input/mouse/Kconfig:187:        symbol MOUSE_APPLETOUCH depends on INPUT
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/input/Kconfig:8:        symbol INPUT is selected by VT
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/tty/Kconfig:12: symbol VT is selected by FB_STI
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/video/fbdev/Kconfig:674:        symbol FB_STI depends on FB
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/video/fbdev/Kconfig:5:  symbol FB is selected by DRM_KMS_FB_HELPER
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/gpu/drm/Kconfig:42:     symbol DRM_KMS_FB_HELPER is selected
by DRM_KMS_CMA_HELPER
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/gpu/drm/Kconfig:98:     symbol DRM_KMS_CMA_HELPER is selected by DRM_IMX
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/gpu/drm/imx/Kconfig:1:  symbol DRM_IMX depends on IMX_IPUV3_CORE
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/gpu/ipu-v3/Kconfig:1:   symbol IMX_IPUV3_CORE depends on
RESET_CONTROLLER
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/reset/Kconfig:4:        symbol RESET_CONTROLLER is selected by
USB_CHIPIDEA
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/usb/chipidea/Kconfig:1: symbol USB_CHIPIDEA depends on USB_EHCI_HCD
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
drivers/usb/host/Kconfig:84:    symbol USB_EHCI_HCD depends on USB
drivers/usb/chipidea/otg.c: In function ?hw_write_otgsc?:
drivers/usb/chipidea/otg.c:120:2: warning: format ?%x? expects
argument of type ?unsigned int?, but argument 3 has type ?long
unsigned int? [-Wformat]
drivers/usb/chipidea/otg.c:120:2: warning: format ?%x? expects
argument of type ?unsigned int?, but argument 4 has type ?long
unsigned int? [-Wformat]

I haven't yet been able to test with this, as I need some other fixes
it seems too to deal with some of the iommu changes in my flo-WIP tree
(it can't find of_dma_configure), but will let you know how things
work once I have all that sorted.

thanks
-john

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

* Re: [PATCH 01/21] of: device: Support loading a module with OF based modalias
  2016-06-26  7:28   ` Stephen Boyd
@ 2016-06-28  4:17     ` Bjorn Andersson
  -1 siblings, 0 replies; 214+ messages in thread
From: Bjorn Andersson @ 2016-06-28  4:17 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, linux-arm-kernel, linux-kernel, linux-arm-msm,
	Andy Gross, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Rob Herring, devicetree

On Sun 26 Jun 00:28 PDT 2016, Stephen Boyd wrote:

> In the case of ULPI devices, we want to be able to load the
> driver before registering the device so that we don't get stuck
> in a loop waiting for the phy module to appear and failing usb
> controller probe. Currently we request the ulpi module via the
> ulpi ids, but in the DT case we might need to request it with the
> OF based modalias instead. Add a common function that allows
> anyone to request a module with the OF based modalias.
> 
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: <devicetree@vger.kernel.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/of/device.c       | 50 +++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/of_device.h |  6 ++++++
>  2 files changed, 56 insertions(+)
> 
> diff --git a/drivers/of/device.c b/drivers/of/device.c
> index fd5cfad7c403..f275e5beb736 100644
> --- a/drivers/of/device.c
> +++ b/drivers/of/device.c
> @@ -226,6 +226,56 @@ ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len)
>  	return tsize;
>  }
>  
> +static ssize_t of_device_modalias_size(struct device *dev)
> +{
> +	const char *compat;
> +	int cplen, i;
> +	ssize_t csize;
> +
> +	if ((!dev) || (!dev->of_node))
> +		return -ENODEV;
> +
> +	/* Name & Type */
> +	csize = 5 + strlen(dev->of_node->name) + strlen(dev->of_node->type);

It would be clearer if you replaced 5 with strlen("of:NT"), but...

> +
> +	/* Get compatible property if any */
> +	compat = of_get_property(dev->of_node, "compatible", &cplen);
> +	if (!compat)
> +		return csize;
> +
> +	/* Find true end (we tolerate multiple \0 at the end */
> +	for (i = (cplen - 1); i >= 0 && !compat[i]; i--)
> +		cplen--;
> +	if (!cplen)
> +		return csize;
> +	cplen++;
> +
> +	/* Check space (need cplen+1 chars including final \0) */
> +	return csize + cplen;
> +}

...if I understand of_device_get_modalias() correctly you should be able
to replace this function with:

  size = of_device_get_modalias(dev, NULL, 0);

snprintf() will not write to NULL, csize will be larger than 0 so tsize
will be returned before it will memcpy() to the buffer.

> +
> +int of_device_request_module(struct device *dev)
> +{
> +	char *str;
> +	ssize_t size;
> +	int ret;
> +
> +	size = of_device_modalias_size(dev);
> +	if (size < 0)
> +		return size;
> +
> +	str = kmalloc(size + 1, GFP_KERNEL);
> +	if (!str)
> +		return -ENOMEM;
> +
> +	of_device_get_modalias(dev, str, size);
> +	str[size] = '\0';
> +	ret = request_module(str);
> +	kfree(str);
> +
> +	return ret;
> +}
> +

Regards,
Bjorn

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

* [PATCH 01/21] of: device: Support loading a module with OF based modalias
@ 2016-06-28  4:17     ` Bjorn Andersson
  0 siblings, 0 replies; 214+ messages in thread
From: Bjorn Andersson @ 2016-06-28  4:17 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun 26 Jun 00:28 PDT 2016, Stephen Boyd wrote:

> In the case of ULPI devices, we want to be able to load the
> driver before registering the device so that we don't get stuck
> in a loop waiting for the phy module to appear and failing usb
> controller probe. Currently we request the ulpi module via the
> ulpi ids, but in the DT case we might need to request it with the
> OF based modalias instead. Add a common function that allows
> anyone to request a module with the OF based modalias.
> 
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: <devicetree@vger.kernel.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/of/device.c       | 50 +++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/of_device.h |  6 ++++++
>  2 files changed, 56 insertions(+)
> 
> diff --git a/drivers/of/device.c b/drivers/of/device.c
> index fd5cfad7c403..f275e5beb736 100644
> --- a/drivers/of/device.c
> +++ b/drivers/of/device.c
> @@ -226,6 +226,56 @@ ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len)
>  	return tsize;
>  }
>  
> +static ssize_t of_device_modalias_size(struct device *dev)
> +{
> +	const char *compat;
> +	int cplen, i;
> +	ssize_t csize;
> +
> +	if ((!dev) || (!dev->of_node))
> +		return -ENODEV;
> +
> +	/* Name & Type */
> +	csize = 5 + strlen(dev->of_node->name) + strlen(dev->of_node->type);

It would be clearer if you replaced 5 with strlen("of:NT"), but...

> +
> +	/* Get compatible property if any */
> +	compat = of_get_property(dev->of_node, "compatible", &cplen);
> +	if (!compat)
> +		return csize;
> +
> +	/* Find true end (we tolerate multiple \0 at the end */
> +	for (i = (cplen - 1); i >= 0 && !compat[i]; i--)
> +		cplen--;
> +	if (!cplen)
> +		return csize;
> +	cplen++;
> +
> +	/* Check space (need cplen+1 chars including final \0) */
> +	return csize + cplen;
> +}

...if I understand of_device_get_modalias() correctly you should be able
to replace this function with:

  size = of_device_get_modalias(dev, NULL, 0);

snprintf() will not write to NULL, csize will be larger than 0 so tsize
will be returned before it will memcpy() to the buffer.

> +
> +int of_device_request_module(struct device *dev)
> +{
> +	char *str;
> +	ssize_t size;
> +	int ret;
> +
> +	size = of_device_modalias_size(dev);
> +	if (size < 0)
> +		return size;
> +
> +	str = kmalloc(size + 1, GFP_KERNEL);
> +	if (!str)
> +		return -ENOMEM;
> +
> +	of_device_get_modalias(dev, str, size);
> +	str[size] = '\0';
> +	ret = request_module(str);
> +	kfree(str);
> +
> +	return ret;
> +}
> +

Regards,
Bjorn

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

* Re: [PATCH 01/21] of: device: Support loading a module with OF based modalias
  2016-06-28  4:17     ` Bjorn Andersson
  (?)
@ 2016-06-28  4:39     ` Rob Herring
  -1 siblings, 0 replies; 214+ messages in thread
From: Rob Herring @ 2016-06-28  4:39 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: Stephen Boyd, Linux USB List, linux-arm-kernel, linux-kernel,
	linux-arm-msm, Andy Gross, Neil Armstrong, Arnd Bergmann,
	Felipe Balbi, devicetree

On Mon, Jun 27, 2016 at 11:17 PM, Bjorn Andersson <bjorn.andersson@linaro.org> wrote:
> On Sun 26 Jun 00:28 PDT 2016, Stephen Boyd wrote:
>
>> In the case of ULPI devices, we want to be able to load the
>> driver before registering the device so that we don't get stuck
>> in a loop waiting for the phy module to appear and failing usb
>> controller probe. Currently we request the ulpi module via the
>> ulpi ids, but in the DT case we might need to request it with the
>> OF based modalias instead. Add a common function that allows
>> anyone to request a module with the OF based modalias.
>>
>> Cc: Rob Herring <robh+dt@kernel.org>
>> Cc: <devicetree@vger.kernel.org>
>> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
>> ---
>>  drivers/of/device.c       | 50 +++++++++++++++++++++++++++++++++++++++++++++++
>>  include/linux/of_device.h |  6 ++++++
>>  2 files changed, 56 insertions(+)
>>
>> diff --git a/drivers/of/device.c b/drivers/of/device.c
>> index fd5cfad7c403..f275e5beb736 100644
>> --- a/drivers/of/device.c
>> +++ b/drivers/of/device.c
>> @@ -226,6 +226,56 @@ ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len)
>>       return tsize;
>>  }
>>
>> +static ssize_t of_device_modalias_size(struct device *dev)
>> +{
>> +     const char *compat;
>> +     int cplen, i;
>> +     ssize_t csize;
>> +
>> +     if ((!dev) || (!dev->of_node))
>> +             return -ENODEV;
>> +
>> +     /* Name & Type */
>> +     csize = 5 + strlen(dev->of_node->name) + strlen(dev->of_node->type);
>
> It would be clearer if you replaced 5 with strlen("of:NT"), but...

Is the compiler smart enough to replace that with a constant 5? At least a comment of where 5 comes from as I was wondering.

>> +
>> +     /* Get compatible property if any */
>> +     compat = of_get_property(dev->of_node, "compatible", &cplen);
>> +     if (!compat)
>> +             return csize;
>> +
>> +     /* Find true end (we tolerate multiple \0 at the end */
>> +     for (i = (cplen - 1); i >= 0 && !compat[i]; i--)
>> +             cplen--;
>> +     if (!cplen)
>> +             return csize;
>> +     cplen++;
>> +
>> +     /* Check space (need cplen+1 chars including final \0) */
>> +     return csize + cplen;
>> +}
>
> ...if I understand of_device_get_modalias() correctly you should be able
> to replace this function with:
>
>   size = of_device_get_modalias(dev, NULL, 0);
>
> snprintf() will not write to NULL, csize will be larger than 0 so tsize
> will be returned before it will memcpy() to the buffer.
>
>> +
>> +int of_device_request_module(struct device *dev)
>> +{
>> +     char *str;
>> +     ssize_t size;
>> +     int ret;
>> +
>> +     size = of_device_modalias_size(dev);
>> +     if (size < 0)
>> +             return size;
>> +
>> +     str = kmalloc(size + 1, GFP_KERNEL);
>> +     if (!str)
>> +             return -ENOMEM;
>> +
>> +     of_device_get_modalias(dev, str, size);
>> +     str[size] = '\0';
>> +     ret = request_module(str);
>> +     kfree(str);
>> +
>> +     return ret;
>> +}
>> +
>
> Regards,
> Bjorn

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

* Re: [PATCH 15/21] usb: chipidea: msm: Mux over secondary phy at the right time
  2016-06-26  7:28   ` Stephen Boyd
  (?)
@ 2016-06-28  4:51       ` Bjorn Andersson
  -1 siblings, 0 replies; 214+ messages in thread
From: Bjorn Andersson @ 2016-06-28  4:51 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA, Andy Gross, Neil Armstrong,
	Arnd Bergmann, Felipe Balbi, Peter Chen, Greg Kroah-Hartman

On Sun 26 Jun 00:28 PDT 2016, Stephen Boyd wrote:

> We need to pick the correct phy at runtime based on how the SoC
> has been wired onto the board. If the secondary phy is used, take
> it out of reset and mux over to it by writing into the TCSR
> register. Make sure to do this on reset too, because this
> register is reset to the default value (primary phy) after the
> RESET bit is set in USBCMD.
> 
> Cc: Peter Chen <peter.chen-3arQi8VN3Tc@public.gmane.org>
> Cc: Greg Kroah-Hartman <gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org>
> Signed-off-by: Stephen Boyd <stephen.boyd-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> ---
>  drivers/usb/chipidea/ci_hdrc_msm.c | 78 +++++++++++++++++++++++++++++++++++---
>  1 file changed, 73 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
[..]
>  
> +static int ci_hdrc_msm_mux_phy(struct ci_hdrc_msm *ci,
> +			       struct platform_device *pdev)
> +{
> +	struct regmap *regmap;
> +	struct device_node *syscon;
> +	struct device *dev = &pdev->dev;
> +	u32 off, val;
> +	int ret;
> +
> +	syscon = of_parse_phandle(dev->of_node, "phy-select", 0);
> +	if (!syscon)
> +		return 0;
> +
> +	regmap = syscon_node_to_regmap(syscon);
> +	if (IS_ERR(regmap))
> +		return PTR_ERR(regmap);
> +
> +	ret = of_property_read_u32_index(dev->of_node, "phy-select", 1, &off);
> +	if (ret < 0) {
> +		dev_err(dev, "no offset in syscon\n");
> +		return -EINVAL;
> +	}
> +
> +	ret = of_property_read_u32_index(dev->of_node, "phy-select", 2, &val);
> +	if (ret < 0) {
> +		dev_err(dev, "no value in syscon\n");
> +		return -EINVAL;
> +	}
> +
> +	ret = regmap_write(regmap, off, val);

I recently found out (thanks to a comment from Srinivas) that you can
drop the last two error checks by using
of_parse_phandle_with_fixed_args() as in:

  struct of_phandle_args args;

  ret = of_parse_phandle_with_fixed_args(dev->of_node, "phy-select", 2, 0, &args);
  if (ret < 0)
	...

  regmap = syscon_node_to_regmap(args.np);
  of_node_put(args.np);
  if (IS_ERR(regmap))
	...

  ret = regmap_write(regmap, args.args[0], args.args[1]);

> +	if (ret)
> +		return ret;
> +
> +	ci->secondary_phy = !!val;
> +	if (ci->secondary_phy) {
> +		val = readl_relaxed(ci->base + HS_PHY_SEC_CTRL);
> +		val |= HS_PHY_DIG_CLAMP_N;
> +		writel_relaxed(val, ci->base + HS_PHY_SEC_CTRL);
> +	}
> +
> +	return 0;
> +}
> +
>  static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  {
>  	struct ci_hdrc_msm *ci;
>  	struct platform_device *plat_ci;
>  	struct clk *clk;
>  	struct reset_control *reset;
> +	struct resource *res;
> +	void __iomem *base;

Doesn't look like you need "base".

> +	resource_size_t size;
>  	int ret;
>  
>  	dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
> @@ -76,6 +132,15 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  	if (IS_ERR(clk))
>  		return PTR_ERR(clk);
>  
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!res)
> +		return -ENODEV;
> +
> +	size = resource_size(res);
> +	ci->base = base = devm_ioremap(&pdev->dev, res->start, size);
> +	if (!base)
> +		return -ENOMEM;

Replace these two snippets with:

  res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  ci->base = devm_ioremap_resource(&pdev->dev, res);
  if (IS_ERR(ci->base))
	return PTR_ERR(ci->base);

> +
>  	reset_control_assert(reset);
>  	usleep_range(10000, 12000);
>  	reset_control_deassert(reset);

Regards,
Bjorn
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 15/21] usb: chipidea: msm: Mux over secondary phy at the right time
@ 2016-06-28  4:51       ` Bjorn Andersson
  0 siblings, 0 replies; 214+ messages in thread
From: Bjorn Andersson @ 2016-06-28  4:51 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, linux-arm-kernel, linux-kernel, linux-arm-msm,
	Andy Gross, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Peter Chen, Greg Kroah-Hartman

On Sun 26 Jun 00:28 PDT 2016, Stephen Boyd wrote:

> We need to pick the correct phy at runtime based on how the SoC
> has been wired onto the board. If the secondary phy is used, take
> it out of reset and mux over to it by writing into the TCSR
> register. Make sure to do this on reset too, because this
> register is reset to the default value (primary phy) after the
> RESET bit is set in USBCMD.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/ci_hdrc_msm.c | 78 +++++++++++++++++++++++++++++++++++---
>  1 file changed, 73 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
[..]
>  
> +static int ci_hdrc_msm_mux_phy(struct ci_hdrc_msm *ci,
> +			       struct platform_device *pdev)
> +{
> +	struct regmap *regmap;
> +	struct device_node *syscon;
> +	struct device *dev = &pdev->dev;
> +	u32 off, val;
> +	int ret;
> +
> +	syscon = of_parse_phandle(dev->of_node, "phy-select", 0);
> +	if (!syscon)
> +		return 0;
> +
> +	regmap = syscon_node_to_regmap(syscon);
> +	if (IS_ERR(regmap))
> +		return PTR_ERR(regmap);
> +
> +	ret = of_property_read_u32_index(dev->of_node, "phy-select", 1, &off);
> +	if (ret < 0) {
> +		dev_err(dev, "no offset in syscon\n");
> +		return -EINVAL;
> +	}
> +
> +	ret = of_property_read_u32_index(dev->of_node, "phy-select", 2, &val);
> +	if (ret < 0) {
> +		dev_err(dev, "no value in syscon\n");
> +		return -EINVAL;
> +	}
> +
> +	ret = regmap_write(regmap, off, val);

I recently found out (thanks to a comment from Srinivas) that you can
drop the last two error checks by using
of_parse_phandle_with_fixed_args() as in:

  struct of_phandle_args args;

  ret = of_parse_phandle_with_fixed_args(dev->of_node, "phy-select", 2, 0, &args);
  if (ret < 0)
	...

  regmap = syscon_node_to_regmap(args.np);
  of_node_put(args.np);
  if (IS_ERR(regmap))
	...

  ret = regmap_write(regmap, args.args[0], args.args[1]);

> +	if (ret)
> +		return ret;
> +
> +	ci->secondary_phy = !!val;
> +	if (ci->secondary_phy) {
> +		val = readl_relaxed(ci->base + HS_PHY_SEC_CTRL);
> +		val |= HS_PHY_DIG_CLAMP_N;
> +		writel_relaxed(val, ci->base + HS_PHY_SEC_CTRL);
> +	}
> +
> +	return 0;
> +}
> +
>  static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  {
>  	struct ci_hdrc_msm *ci;
>  	struct platform_device *plat_ci;
>  	struct clk *clk;
>  	struct reset_control *reset;
> +	struct resource *res;
> +	void __iomem *base;

Doesn't look like you need "base".

> +	resource_size_t size;
>  	int ret;
>  
>  	dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
> @@ -76,6 +132,15 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  	if (IS_ERR(clk))
>  		return PTR_ERR(clk);
>  
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!res)
> +		return -ENODEV;
> +
> +	size = resource_size(res);
> +	ci->base = base = devm_ioremap(&pdev->dev, res->start, size);
> +	if (!base)
> +		return -ENOMEM;

Replace these two snippets with:

  res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  ci->base = devm_ioremap_resource(&pdev->dev, res);
  if (IS_ERR(ci->base))
	return PTR_ERR(ci->base);

> +
>  	reset_control_assert(reset);
>  	usleep_range(10000, 12000);
>  	reset_control_deassert(reset);

Regards,
Bjorn

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

* [PATCH 15/21] usb: chipidea: msm: Mux over secondary phy at the right time
@ 2016-06-28  4:51       ` Bjorn Andersson
  0 siblings, 0 replies; 214+ messages in thread
From: Bjorn Andersson @ 2016-06-28  4:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun 26 Jun 00:28 PDT 2016, Stephen Boyd wrote:

> We need to pick the correct phy at runtime based on how the SoC
> has been wired onto the board. If the secondary phy is used, take
> it out of reset and mux over to it by writing into the TCSR
> register. Make sure to do this on reset too, because this
> register is reset to the default value (primary phy) after the
> RESET bit is set in USBCMD.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/ci_hdrc_msm.c | 78 +++++++++++++++++++++++++++++++++++---
>  1 file changed, 73 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
[..]
>  
> +static int ci_hdrc_msm_mux_phy(struct ci_hdrc_msm *ci,
> +			       struct platform_device *pdev)
> +{
> +	struct regmap *regmap;
> +	struct device_node *syscon;
> +	struct device *dev = &pdev->dev;
> +	u32 off, val;
> +	int ret;
> +
> +	syscon = of_parse_phandle(dev->of_node, "phy-select", 0);
> +	if (!syscon)
> +		return 0;
> +
> +	regmap = syscon_node_to_regmap(syscon);
> +	if (IS_ERR(regmap))
> +		return PTR_ERR(regmap);
> +
> +	ret = of_property_read_u32_index(dev->of_node, "phy-select", 1, &off);
> +	if (ret < 0) {
> +		dev_err(dev, "no offset in syscon\n");
> +		return -EINVAL;
> +	}
> +
> +	ret = of_property_read_u32_index(dev->of_node, "phy-select", 2, &val);
> +	if (ret < 0) {
> +		dev_err(dev, "no value in syscon\n");
> +		return -EINVAL;
> +	}
> +
> +	ret = regmap_write(regmap, off, val);

I recently found out (thanks to a comment from Srinivas) that you can
drop the last two error checks by using
of_parse_phandle_with_fixed_args() as in:

  struct of_phandle_args args;

  ret = of_parse_phandle_with_fixed_args(dev->of_node, "phy-select", 2, 0, &args);
  if (ret < 0)
	...

  regmap = syscon_node_to_regmap(args.np);
  of_node_put(args.np);
  if (IS_ERR(regmap))
	...

  ret = regmap_write(regmap, args.args[0], args.args[1]);

> +	if (ret)
> +		return ret;
> +
> +	ci->secondary_phy = !!val;
> +	if (ci->secondary_phy) {
> +		val = readl_relaxed(ci->base + HS_PHY_SEC_CTRL);
> +		val |= HS_PHY_DIG_CLAMP_N;
> +		writel_relaxed(val, ci->base + HS_PHY_SEC_CTRL);
> +	}
> +
> +	return 0;
> +}
> +
>  static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  {
>  	struct ci_hdrc_msm *ci;
>  	struct platform_device *plat_ci;
>  	struct clk *clk;
>  	struct reset_control *reset;
> +	struct resource *res;
> +	void __iomem *base;

Doesn't look like you need "base".

> +	resource_size_t size;
>  	int ret;
>  
>  	dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
> @@ -76,6 +132,15 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  	if (IS_ERR(clk))
>  		return PTR_ERR(clk);
>  
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!res)
> +		return -ENODEV;
> +
> +	size = resource_size(res);
> +	ci->base = base = devm_ioremap(&pdev->dev, res->start, size);
> +	if (!base)
> +		return -ENOMEM;

Replace these two snippets with:

  res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  ci->base = devm_ioremap_resource(&pdev->dev, res);
  if (IS_ERR(ci->base))
	return PTR_ERR(ci->base);

> +
>  	reset_control_assert(reset);
>  	usleep_range(10000, 12000);
>  	reset_control_deassert(reset);

Regards,
Bjorn

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

* Re: [PATCH 00/21] Support qcom's HSIC USB and rewrite USB2 HS phy support
  2016-06-28  3:09     ` John Stultz
@ 2016-06-28  8:34       ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-28  8:34 UTC (permalink / raw)
  To: John Stultz
  Cc: Felipe Balbi, Heikki Krogerus, Arnd Bergmann, Neil Armstrong,
	linux-arm-msm, linux-usb, lkml, Bjorn Andersson, devicetree,
	Rob Herring, Peter Chen, Greg Kroah-Hartman, Andy Gross,
	Ivan T. Ivanov, Kishon Vijay Abraham I, linux-arm-kernel

Quoting John Stultz (2016-06-27 20:09:30)
> 
> Just a heads up, trying to build with this branch gives me:
> 
> drivers/usb/Kconfig:39:error: recursive dependency detected!
> For a resolution refer to Documentation/kbuild/kconfig-language.txt
> subsection "Kconfig recursive dependency limitations"
> drivers/usb/Kconfig:39: symbol USB is selected by MOUSE_APPLETOUCH
> For a resolution refer to Documentation/kbuild/kconfig-language.txt
> subsection "Kconfig recursive dependency limitations"
> drivers/input/mouse/Kconfig:187:        symbol MOUSE_APPLETOUCH depends on INPUT
> For a resolution refer to Documentation/kbuild/kconfig-language.txt
> subsection "Kconfig recursive dependency limitations"
> drivers/input/Kconfig:8:        symbol INPUT is selected by VT
> For a resolution refer to Documentation/kbuild/kconfig-language.txt
> subsection "Kconfig recursive dependency limitations"
> drivers/tty/Kconfig:12: symbol VT is selected by FB_STI
> For a resolution refer to Documentation/kbuild/kconfig-language.txt
> subsection "Kconfig recursive dependency limitations"
> drivers/video/fbdev/Kconfig:674:        symbol FB_STI depends on FB
> For a resolution refer to Documentation/kbuild/kconfig-language.txt
> subsection "Kconfig recursive dependency limitations"
> drivers/video/fbdev/Kconfig:5:  symbol FB is selected by DRM_KMS_FB_HELPER
> For a resolution refer to Documentation/kbuild/kconfig-language.txt
> subsection "Kconfig recursive dependency limitations"
> drivers/gpu/drm/Kconfig:42:     symbol DRM_KMS_FB_HELPER is selected
> by DRM_KMS_CMA_HELPER
> For a resolution refer to Documentation/kbuild/kconfig-language.txt
> subsection "Kconfig recursive dependency limitations"
> drivers/gpu/drm/Kconfig:98:     symbol DRM_KMS_CMA_HELPER is selected by DRM_IMX
> For a resolution refer to Documentation/kbuild/kconfig-language.txt
> subsection "Kconfig recursive dependency limitations"
> drivers/gpu/drm/imx/Kconfig:1:  symbol DRM_IMX depends on IMX_IPUV3_CORE
> For a resolution refer to Documentation/kbuild/kconfig-language.txt
> subsection "Kconfig recursive dependency limitations"
> drivers/gpu/ipu-v3/Kconfig:1:   symbol IMX_IPUV3_CORE depends on
> RESET_CONTROLLER
> For a resolution refer to Documentation/kbuild/kconfig-language.txt
> subsection "Kconfig recursive dependency limitations"
> drivers/reset/Kconfig:4:        symbol RESET_CONTROLLER is selected by
> USB_CHIPIDEA
> For a resolution refer to Documentation/kbuild/kconfig-language.txt
> subsection "Kconfig recursive dependency limitations"
> drivers/usb/chipidea/Kconfig:1: symbol USB_CHIPIDEA depends on USB_EHCI_HCD
> For a resolution refer to Documentation/kbuild/kconfig-language.txt
> subsection "Kconfig recursive dependency limitations"
> drivers/usb/host/Kconfig:84:    symbol USB_EHCI_HCD depends on USB

Yeah, sorry I've updated the branch today with fixes reported by kbuild
robot. This problem starts to happen once I start selecting
RESET_CONTROLLER from the chipidea Kconfig symbol. I've layered another
patch on top to fix the build errors I'm seeing, although I'm not sure
it's a great solution.

> drivers/usb/chipidea/otg.c: In function ‘hw_write_otgsc’:
> drivers/usb/chipidea/otg.c:120:2: warning: format ‘%x’ expects
> argument of type ‘unsigned int’, but argument 3 has type ‘long
> unsigned int’ [-Wformat]
> drivers/usb/chipidea/otg.c:120:2: warning: format ‘%x’ expects
> argument of type ‘unsigned int’, but argument 4 has type ‘long
> unsigned int’ [-Wformat]

These are debug print warnings. Nothing to see here...

> 
> I haven't yet been able to test with this, as I need some other fixes
> it seems too to deal with some of the iommu changes in my flo-WIP tree
> (it can't find of_dma_configure), but will let you know how things
> work once I have all that sorted.

Cool, thanks for testing.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 00/21] Support qcom's HSIC USB and rewrite USB2 HS phy support
@ 2016-06-28  8:34       ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-28  8:34 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting John Stultz (2016-06-27 20:09:30)
> 
> Just a heads up, trying to build with this branch gives me:
> 
> drivers/usb/Kconfig:39:error: recursive dependency detected!
> For a resolution refer to Documentation/kbuild/kconfig-language.txt
> subsection "Kconfig recursive dependency limitations"
> drivers/usb/Kconfig:39: symbol USB is selected by MOUSE_APPLETOUCH
> For a resolution refer to Documentation/kbuild/kconfig-language.txt
> subsection "Kconfig recursive dependency limitations"
> drivers/input/mouse/Kconfig:187:        symbol MOUSE_APPLETOUCH depends on INPUT
> For a resolution refer to Documentation/kbuild/kconfig-language.txt
> subsection "Kconfig recursive dependency limitations"
> drivers/input/Kconfig:8:        symbol INPUT is selected by VT
> For a resolution refer to Documentation/kbuild/kconfig-language.txt
> subsection "Kconfig recursive dependency limitations"
> drivers/tty/Kconfig:12: symbol VT is selected by FB_STI
> For a resolution refer to Documentation/kbuild/kconfig-language.txt
> subsection "Kconfig recursive dependency limitations"
> drivers/video/fbdev/Kconfig:674:        symbol FB_STI depends on FB
> For a resolution refer to Documentation/kbuild/kconfig-language.txt
> subsection "Kconfig recursive dependency limitations"
> drivers/video/fbdev/Kconfig:5:  symbol FB is selected by DRM_KMS_FB_HELPER
> For a resolution refer to Documentation/kbuild/kconfig-language.txt
> subsection "Kconfig recursive dependency limitations"
> drivers/gpu/drm/Kconfig:42:     symbol DRM_KMS_FB_HELPER is selected
> by DRM_KMS_CMA_HELPER
> For a resolution refer to Documentation/kbuild/kconfig-language.txt
> subsection "Kconfig recursive dependency limitations"
> drivers/gpu/drm/Kconfig:98:     symbol DRM_KMS_CMA_HELPER is selected by DRM_IMX
> For a resolution refer to Documentation/kbuild/kconfig-language.txt
> subsection "Kconfig recursive dependency limitations"
> drivers/gpu/drm/imx/Kconfig:1:  symbol DRM_IMX depends on IMX_IPUV3_CORE
> For a resolution refer to Documentation/kbuild/kconfig-language.txt
> subsection "Kconfig recursive dependency limitations"
> drivers/gpu/ipu-v3/Kconfig:1:   symbol IMX_IPUV3_CORE depends on
> RESET_CONTROLLER
> For a resolution refer to Documentation/kbuild/kconfig-language.txt
> subsection "Kconfig recursive dependency limitations"
> drivers/reset/Kconfig:4:        symbol RESET_CONTROLLER is selected by
> USB_CHIPIDEA
> For a resolution refer to Documentation/kbuild/kconfig-language.txt
> subsection "Kconfig recursive dependency limitations"
> drivers/usb/chipidea/Kconfig:1: symbol USB_CHIPIDEA depends on USB_EHCI_HCD
> For a resolution refer to Documentation/kbuild/kconfig-language.txt
> subsection "Kconfig recursive dependency limitations"
> drivers/usb/host/Kconfig:84:    symbol USB_EHCI_HCD depends on USB

Yeah, sorry I've updated the branch today with fixes reported by kbuild
robot. This problem starts to happen once I start selecting
RESET_CONTROLLER from the chipidea Kconfig symbol. I've layered another
patch on top to fix the build errors I'm seeing, although I'm not sure
it's a great solution.

> drivers/usb/chipidea/otg.c: In function ?hw_write_otgsc?:
> drivers/usb/chipidea/otg.c:120:2: warning: format ?%x? expects
> argument of type ?unsigned int?, but argument 3 has type ?long
> unsigned int? [-Wformat]
> drivers/usb/chipidea/otg.c:120:2: warning: format ?%x? expects
> argument of type ?unsigned int?, but argument 4 has type ?long
> unsigned int? [-Wformat]

These are debug print warnings. Nothing to see here...

> 
> I haven't yet been able to test with this, as I need some other fixes
> it seems too to deal with some of the iommu changes in my flo-WIP tree
> (it can't find of_dma_configure), but will let you know how things
> work once I have all that sorted.

Cool, thanks for testing.

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

* Re: [PATCH 15/21] usb: chipidea: msm: Mux over secondary phy at the right time
  2016-06-28  4:51       ` Bjorn Andersson
@ 2016-06-28  8:39         ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-28  8:39 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: Felipe Balbi, Arnd Bergmann, Neil Armstrong, linux-arm-msm,
	linux-usb, linux-kernel, Peter Chen, Greg Kroah-Hartman,
	Andy Gross, linux-arm-kernel

Quoting Bjorn Andersson (2016-06-27 21:51:37)
> On Sun 26 Jun 00:28 PDT 2016, Stephen Boyd wrote:
> > +static int ci_hdrc_msm_mux_phy(struct ci_hdrc_msm *ci,
> > +                            struct platform_device *pdev)
> > +{
> > +     struct regmap *regmap;
> > +     struct device_node *syscon;
> > +     struct device *dev = &pdev->dev;
> > +     u32 off, val;
> > +     int ret;
> > +
> > +     syscon = of_parse_phandle(dev->of_node, "phy-select", 0);
> > +     if (!syscon)
> > +             return 0;
> > +
> > +     regmap = syscon_node_to_regmap(syscon);
> > +     if (IS_ERR(regmap))
> > +             return PTR_ERR(regmap);
> > +
> > +     ret = of_property_read_u32_index(dev->of_node, "phy-select", 1, &off);
> > +     if (ret < 0) {
> > +             dev_err(dev, "no offset in syscon\n");
> > +             return -EINVAL;
> > +     }
> > +
> > +     ret = of_property_read_u32_index(dev->of_node, "phy-select", 2, &val);
> > +     if (ret < 0) {
> > +             dev_err(dev, "no value in syscon\n");
> > +             return -EINVAL;
> > +     }
> > +
> > +     ret = regmap_write(regmap, off, val);
> 
> I recently found out (thanks to a comment from Srinivas) that you can
> drop the last two error checks by using
> of_parse_phandle_with_fixed_args() as in:
> 
>   struct of_phandle_args args;
> 
>   ret = of_parse_phandle_with_fixed_args(dev->of_node, "phy-select", 2, 0, &args);
>   if (ret < 0)
>         ...
> 
>   regmap = syscon_node_to_regmap(args.np);
>   of_node_put(args.np);
>   if (IS_ERR(regmap))
>         ...
> 
>   ret = regmap_write(regmap, args.args[0], args.args[1]);

Awesome, thanks. I'll fold this in.

> > +     resource_size_t size;
> >       int ret;
> >  
> >       dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
> > @@ -76,6 +132,15 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
> >       if (IS_ERR(clk))
> >               return PTR_ERR(clk);
> >  
> > +     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +     if (!res)
> > +             return -ENODEV;
> > +
> > +     size = resource_size(res);
> > +     ci->base = base = devm_ioremap(&pdev->dev, res->start, size);
> > +     if (!base)
> > +             return -ENOMEM;
> 
> Replace these two snippets with:
> 
>   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>   ci->base = devm_ioremap_resource(&pdev->dev, res);
>   if (IS_ERR(ci->base))
>         return PTR_ERR(ci->base);

Unfortunately I can't do that. I'm mapping the base here without
ioremap_resource() because the ci core is mapping it with
devm_ioremap_resource() and that doesn't allow two callers to map the
same address space. If the ci core was a library and not written as a
sub device driver this could be made to work assuming there was some API
to setup the mapping and then another API to do the rest of the ci core
probe.

Or I can add another event like SETUP that would allow me to mux the phy
over early during the ci device probe. I would still need to get a
handle on the registers for the extcon handler though, so that would
need a think.

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

* [PATCH 15/21] usb: chipidea: msm: Mux over secondary phy at the right time
@ 2016-06-28  8:39         ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-28  8:39 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Bjorn Andersson (2016-06-27 21:51:37)
> On Sun 26 Jun 00:28 PDT 2016, Stephen Boyd wrote:
> > +static int ci_hdrc_msm_mux_phy(struct ci_hdrc_msm *ci,
> > +                            struct platform_device *pdev)
> > +{
> > +     struct regmap *regmap;
> > +     struct device_node *syscon;
> > +     struct device *dev = &pdev->dev;
> > +     u32 off, val;
> > +     int ret;
> > +
> > +     syscon = of_parse_phandle(dev->of_node, "phy-select", 0);
> > +     if (!syscon)
> > +             return 0;
> > +
> > +     regmap = syscon_node_to_regmap(syscon);
> > +     if (IS_ERR(regmap))
> > +             return PTR_ERR(regmap);
> > +
> > +     ret = of_property_read_u32_index(dev->of_node, "phy-select", 1, &off);
> > +     if (ret < 0) {
> > +             dev_err(dev, "no offset in syscon\n");
> > +             return -EINVAL;
> > +     }
> > +
> > +     ret = of_property_read_u32_index(dev->of_node, "phy-select", 2, &val);
> > +     if (ret < 0) {
> > +             dev_err(dev, "no value in syscon\n");
> > +             return -EINVAL;
> > +     }
> > +
> > +     ret = regmap_write(regmap, off, val);
> 
> I recently found out (thanks to a comment from Srinivas) that you can
> drop the last two error checks by using
> of_parse_phandle_with_fixed_args() as in:
> 
>   struct of_phandle_args args;
> 
>   ret = of_parse_phandle_with_fixed_args(dev->of_node, "phy-select", 2, 0, &args);
>   if (ret < 0)
>         ...
> 
>   regmap = syscon_node_to_regmap(args.np);
>   of_node_put(args.np);
>   if (IS_ERR(regmap))
>         ...
> 
>   ret = regmap_write(regmap, args.args[0], args.args[1]);

Awesome, thanks. I'll fold this in.

> > +     resource_size_t size;
> >       int ret;
> >  
> >       dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
> > @@ -76,6 +132,15 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
> >       if (IS_ERR(clk))
> >               return PTR_ERR(clk);
> >  
> > +     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +     if (!res)
> > +             return -ENODEV;
> > +
> > +     size = resource_size(res);
> > +     ci->base = base = devm_ioremap(&pdev->dev, res->start, size);
> > +     if (!base)
> > +             return -ENOMEM;
> 
> Replace these two snippets with:
> 
>   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>   ci->base = devm_ioremap_resource(&pdev->dev, res);
>   if (IS_ERR(ci->base))
>         return PTR_ERR(ci->base);

Unfortunately I can't do that. I'm mapping the base here without
ioremap_resource() because the ci core is mapping it with
devm_ioremap_resource() and that doesn't allow two callers to map the
same address space. If the ci core was a library and not written as a
sub device driver this could be made to work assuming there was some API
to setup the mapping and then another API to do the rest of the ci core
probe.

Or I can add another event like SETUP that would allow me to mux the phy
over early during the ci device probe. I would still need to get a
handle on the registers for the extcon handler though, so that would
need a think.

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

* Re: [PATCH 20/21] phy: Add support for Qualcomm's USB HSIC phy
  2016-06-26  7:28     ` Stephen Boyd
@ 2016-06-28  8:49       ` Neil Armstrong
  -1 siblings, 0 replies; 214+ messages in thread
From: Neil Armstrong @ 2016-06-28  8:49 UTC (permalink / raw)
  To: Stephen Boyd, linux-usb
  Cc: linux-arm-kernel, linux-kernel, linux-arm-msm, Andy Gross,
	Bjorn Andersson, Arnd Bergmann, Felipe Balbi,
	Kishon Vijay Abraham I, devicetree

On 06/26/2016 09:28 AM, Stephen Boyd wrote:
> The HSIC USB controller on qcom SoCs has an integrated all
> digital phy controlled via the ULPI viewport.
> 
> Cc: Kishon Vijay Abraham I <kishon@ti.com>
> Cc: <devicetree@vger.kernel.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  .../devicetree/bindings/phy/qcom,usb-hsic-phy.txt  |  60 ++++++++
>  drivers/phy/Kconfig                                |   7 +
>  drivers/phy/Makefile                               |   1 +
>  drivers/phy/phy-qcom-usb-hsic.c                    | 161 +++++++++++++++++++++
>  4 files changed, 229 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt
>  create mode 100644 drivers/phy/phy-qcom-usb-hsic.c
> 
> diff --git a/Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt b/Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt
> new file mode 100644
> index 000000000000..6b1c6aad2962
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt
> @@ -0,0 +1,60 @@
> +Qualcomm's USB HSIC PHY
> +
> +PROPERTIES
> +
> +- compatible:
> +    Usage: required
> +    Value type: <string>
> +    Definition: Should contain "qcom,usb-hsic-phy"
> +
> +- #phy-cells:
> +    Usage: required
> +    Value type: <u32>
> +    Definition: Should contain 0
> +
> +- clocks:
> +    Usage: required
> +    Value type: <prop-encoded-array>
> +    Definition: Should contain clock specifier for phy, calibration and
> +                optionally a calibration sleep clock
> +
> +- clock-names:
> +    Usage: required
> +    Value type: <stringlist>
> +    Definition: Should contain "phy, "cal" and optionally "cal_sleep"
> +

[...]

> +
> +static int qcom_usb_hsic_phy_power_on(struct phy *phy)
> +{
> +	struct qcom_usb_hsic_phy *uphy = phy_get_drvdata(phy);
> +	struct ulpi *ulpi = uphy->ulpi;
> +	struct pinctrl_state *pins_default;
> +	int ret;
> +
> +	ret = clk_prepare_enable(uphy->phy_clk);
> +	if (ret)
> +		return ret;
> +
> +	ret = clk_prepare_enable(uphy->cal_clk);
> +	if (ret)
> +		goto err_cal;
> +
> +	ret = clk_prepare_enable(uphy->cal_sleep_clk);
> +	if (ret)
> +		goto err_sleep;
> +

[...]

> +
> +	return ret;
> +err_ulpi:
> +	clk_disable_unprepare(uphy->cal_sleep_clk);
> +err_sleep:
> +	clk_disable_unprepare(uphy->cal_clk);
> +err_cal:
> +	clk_disable_unprepare(uphy->phy_clk);
> +	return ret;
> +}
> +
> +static int qcom_usb_hsic_phy_power_off(struct phy *phy)
> +{
> +	struct qcom_usb_hsic_phy *uphy = phy_get_drvdata(phy);
> +
> +	clk_disable_unprepare(uphy->cal_sleep_clk);
> +	clk_disable_unprepare(uphy->cal_clk);
> +	clk_disable_unprepare(uphy->phy_clk);

[...]

> +static int qcom_usb_hsic_phy_probe(struct ulpi *ulpi)
> +{
> +	struct qcom_usb_hsic_phy *uphy;
> +	struct phy_provider *p;
> +	struct clk *clk;
> +
> +	uphy = devm_kzalloc(&ulpi->dev, sizeof(*uphy), GFP_KERNEL);
> +	if (!uphy)
> +		return -ENOMEM;
> +	ulpi_set_drvdata(ulpi, uphy);
> +
> +	uphy->ulpi = ulpi;
> +	uphy->pctl = devm_pinctrl_get(&ulpi->dev);
> +	if (IS_ERR(uphy->pctl))
> +		return PTR_ERR(uphy->pctl);
> +
> +	uphy->phy_clk = clk = devm_clk_get(&ulpi->dev, "phy");
> +	if (IS_ERR(clk))
> +		return PTR_ERR(clk);
> +
> +	uphy->cal_clk = clk = devm_clk_get(&ulpi->dev, "cal");
> +	if (IS_ERR(clk))
> +		return PTR_ERR(clk);
> +
> +	uphy->cal_sleep_clk = clk = devm_clk_get(&ulpi->dev, "cal_sleep");
> +	if (IS_ERR(clk))
> +		return PTR_ERR(clk);

Hi Stephen,

In the bindings the cal_sleep is marked optional, and I think should be since AFAIK
it's not present on MDM9615 for example.

Also MDM9615 HSIC requires "core", "alt-core", "phy", "cal" and "iface" clocks.
I assume "core" can be attributed to the main chipidea node, but I think "alt-core" and "iface" should be also optionnal.

Finally, it misses an optional reset line AFAIK mandatory on MDM9615.

Neil

> +
> +	uphy->phy = devm_phy_create(&ulpi->dev, ulpi->dev.of_node,
> +				    &qcom_usb_hsic_phy_ops);
> +	if (IS_ERR(uphy->phy))
> +		return PTR_ERR(uphy->phy);
> +	phy_set_drvdata(uphy->phy, uphy);
> +
> +	p = devm_of_phy_provider_register(&ulpi->dev, of_phy_simple_xlate);
> +	return PTR_ERR_OR_ZERO(p);
> +}
> +
> +
> +static const struct of_device_id qcom_usb_hsic_phy_match[] = {
> +	{ .compatible = "qcom,usb-hsic-phy", },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, qcom_usb_hsic_phy_match);
> +
> +static struct ulpi_driver qcom_usb_hsic_phy_driver = {
> +	.probe = qcom_usb_hsic_phy_probe,
> +	.driver = {
> +		.name = "qcom_usb_hsic_phy",
> +		.of_match_table = qcom_usb_hsic_phy_match
> +	},
> +};
> +module_ulpi_driver(qcom_usb_hsic_phy_driver);
> +
> +MODULE_DESCRIPTION("Qualcomm USB HSIC phy");
> +MODULE_LICENSE("GPL v2");
> 

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

* [PATCH 20/21] phy: Add support for Qualcomm's USB HSIC phy
@ 2016-06-28  8:49       ` Neil Armstrong
  0 siblings, 0 replies; 214+ messages in thread
From: Neil Armstrong @ 2016-06-28  8:49 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/26/2016 09:28 AM, Stephen Boyd wrote:
> The HSIC USB controller on qcom SoCs has an integrated all
> digital phy controlled via the ULPI viewport.
> 
> Cc: Kishon Vijay Abraham I <kishon@ti.com>
> Cc: <devicetree@vger.kernel.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  .../devicetree/bindings/phy/qcom,usb-hsic-phy.txt  |  60 ++++++++
>  drivers/phy/Kconfig                                |   7 +
>  drivers/phy/Makefile                               |   1 +
>  drivers/phy/phy-qcom-usb-hsic.c                    | 161 +++++++++++++++++++++
>  4 files changed, 229 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt
>  create mode 100644 drivers/phy/phy-qcom-usb-hsic.c
> 
> diff --git a/Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt b/Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt
> new file mode 100644
> index 000000000000..6b1c6aad2962
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/qcom,usb-hsic-phy.txt
> @@ -0,0 +1,60 @@
> +Qualcomm's USB HSIC PHY
> +
> +PROPERTIES
> +
> +- compatible:
> +    Usage: required
> +    Value type: <string>
> +    Definition: Should contain "qcom,usb-hsic-phy"
> +
> +- #phy-cells:
> +    Usage: required
> +    Value type: <u32>
> +    Definition: Should contain 0
> +
> +- clocks:
> +    Usage: required
> +    Value type: <prop-encoded-array>
> +    Definition: Should contain clock specifier for phy, calibration and
> +                optionally a calibration sleep clock
> +
> +- clock-names:
> +    Usage: required
> +    Value type: <stringlist>
> +    Definition: Should contain "phy, "cal" and optionally "cal_sleep"
> +

[...]

> +
> +static int qcom_usb_hsic_phy_power_on(struct phy *phy)
> +{
> +	struct qcom_usb_hsic_phy *uphy = phy_get_drvdata(phy);
> +	struct ulpi *ulpi = uphy->ulpi;
> +	struct pinctrl_state *pins_default;
> +	int ret;
> +
> +	ret = clk_prepare_enable(uphy->phy_clk);
> +	if (ret)
> +		return ret;
> +
> +	ret = clk_prepare_enable(uphy->cal_clk);
> +	if (ret)
> +		goto err_cal;
> +
> +	ret = clk_prepare_enable(uphy->cal_sleep_clk);
> +	if (ret)
> +		goto err_sleep;
> +

[...]

> +
> +	return ret;
> +err_ulpi:
> +	clk_disable_unprepare(uphy->cal_sleep_clk);
> +err_sleep:
> +	clk_disable_unprepare(uphy->cal_clk);
> +err_cal:
> +	clk_disable_unprepare(uphy->phy_clk);
> +	return ret;
> +}
> +
> +static int qcom_usb_hsic_phy_power_off(struct phy *phy)
> +{
> +	struct qcom_usb_hsic_phy *uphy = phy_get_drvdata(phy);
> +
> +	clk_disable_unprepare(uphy->cal_sleep_clk);
> +	clk_disable_unprepare(uphy->cal_clk);
> +	clk_disable_unprepare(uphy->phy_clk);

[...]

> +static int qcom_usb_hsic_phy_probe(struct ulpi *ulpi)
> +{
> +	struct qcom_usb_hsic_phy *uphy;
> +	struct phy_provider *p;
> +	struct clk *clk;
> +
> +	uphy = devm_kzalloc(&ulpi->dev, sizeof(*uphy), GFP_KERNEL);
> +	if (!uphy)
> +		return -ENOMEM;
> +	ulpi_set_drvdata(ulpi, uphy);
> +
> +	uphy->ulpi = ulpi;
> +	uphy->pctl = devm_pinctrl_get(&ulpi->dev);
> +	if (IS_ERR(uphy->pctl))
> +		return PTR_ERR(uphy->pctl);
> +
> +	uphy->phy_clk = clk = devm_clk_get(&ulpi->dev, "phy");
> +	if (IS_ERR(clk))
> +		return PTR_ERR(clk);
> +
> +	uphy->cal_clk = clk = devm_clk_get(&ulpi->dev, "cal");
> +	if (IS_ERR(clk))
> +		return PTR_ERR(clk);
> +
> +	uphy->cal_sleep_clk = clk = devm_clk_get(&ulpi->dev, "cal_sleep");
> +	if (IS_ERR(clk))
> +		return PTR_ERR(clk);

Hi Stephen,

In the bindings the cal_sleep is marked optional, and I think should be since AFAIK
it's not present on MDM9615 for example.

Also MDM9615 HSIC requires "core", "alt-core", "phy", "cal" and "iface" clocks.
I assume "core" can be attributed to the main chipidea node, but I think "alt-core" and "iface" should be also optionnal.

Finally, it misses an optional reset line AFAIK mandatory on MDM9615.

Neil

> +
> +	uphy->phy = devm_phy_create(&ulpi->dev, ulpi->dev.of_node,
> +				    &qcom_usb_hsic_phy_ops);
> +	if (IS_ERR(uphy->phy))
> +		return PTR_ERR(uphy->phy);
> +	phy_set_drvdata(uphy->phy, uphy);
> +
> +	p = devm_of_phy_provider_register(&ulpi->dev, of_phy_simple_xlate);
> +	return PTR_ERR_OR_ZERO(p);
> +}
> +
> +
> +static const struct of_device_id qcom_usb_hsic_phy_match[] = {
> +	{ .compatible = "qcom,usb-hsic-phy", },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, qcom_usb_hsic_phy_match);
> +
> +static struct ulpi_driver qcom_usb_hsic_phy_driver = {
> +	.probe = qcom_usb_hsic_phy_probe,
> +	.driver = {
> +		.name = "qcom_usb_hsic_phy",
> +		.of_match_table = qcom_usb_hsic_phy_match
> +	},
> +};
> +module_ulpi_driver(qcom_usb_hsic_phy_driver);
> +
> +MODULE_DESCRIPTION("Qualcomm USB HSIC phy");
> +MODULE_LICENSE("GPL v2");
> 

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

* Re: [PATCH 04/21] usb: chipidea: Only read/write OTGSC from one place
  2016-06-27 19:07         ` Stephen Boyd
  (?)
@ 2016-06-28  9:36           ` Peter Chen
  -1 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-28  9:36 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Jun Li, linux-usb, linux-arm-kernel, linux-kernel, linux-arm-msm,
	Andy Gross, Bjorn Andersson, Neil Armstrong, Arnd Bergmann,
	Felipe Balbi, Peter Chen, Greg Kroah-Hartman, Ivan T. Ivanov

On Mon, Jun 27, 2016 at 12:07:54PM -0700, Stephen Boyd wrote:
> Quoting Jun Li (2016-06-27 01:04:39)
> > > diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c index
> > > 03b6743461d1..763a8332b009 100644
> > > --- a/drivers/usb/chipidea/otg.c
> > > +++ b/drivers/usb/chipidea/otg.c
> > > @@ -104,7 +104,32 @@ void ci_handle_vbus_change(struct ci_hdrc *ci)
> > >               usb_gadget_vbus_disconnect(&ci->gadget);
> > >  }
> > > 
> > > -#define CI_VBUS_STABLE_TIMEOUT_MS 5000
> > > +/**
> > > + * Sometimes, it needs to wait register value before going on.
> > > + * Eg, when switch to device mode, the vbus value should be lower
> > > + * than OTGSC_BSV before connects to host.
> > 
> > This should be updated since this API is dedicated for BSV now.
> 
> Ok I've updated it to say:
> 
>   When we switch to device mode, the vbus value should be lower
>   than OTGSC_BSV before connecting to host.
> 
> > 
> > > + *
> > > + * @ci: the controller
> > > + *
> > > + * This function returns an error code if timeout  */ static int
> > > +hw_wait_otgsc_bsv(struct ci_hdrc *ci) {
> > > +     unsigned long elapse = jiffies + msecs_to_jiffies(5000);
> > > +     u32 mask = OTGSC_BSV;
> > > +
> > > +     while (!hw_read_otgsc(ci, mask)) {
> > 
> > Reverse logic, should be:
> > while (hw_read_otgsc(ci, mask)) {
> > 
> 
> Good catch! Thanks.

Besides above, please delete the declaration at ci.h.

-- 

Best Regards,
Peter Chen

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

* Re: [PATCH 04/21] usb: chipidea: Only read/write OTGSC from one place
@ 2016-06-28  9:36           ` Peter Chen
  0 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-28  9:36 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Jun Li, linux-usb, linux-arm-kernel, linux-kernel, linux-arm-msm,
	Andy Gross, Bjorn Andersson, Neil Armstrong, Arnd Bergmann,
	Felipe Balbi, Peter Chen, Greg Kroah-Hartman, Ivan T. Ivanov

On Mon, Jun 27, 2016 at 12:07:54PM -0700, Stephen Boyd wrote:
> Quoting Jun Li (2016-06-27 01:04:39)
> > > diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c index
> > > 03b6743461d1..763a8332b009 100644
> > > --- a/drivers/usb/chipidea/otg.c
> > > +++ b/drivers/usb/chipidea/otg.c
> > > @@ -104,7 +104,32 @@ void ci_handle_vbus_change(struct ci_hdrc *ci)
> > >               usb_gadget_vbus_disconnect(&ci->gadget);
> > >  }
> > > 
> > > -#define CI_VBUS_STABLE_TIMEOUT_MS 5000
> > > +/**
> > > + * Sometimes, it needs to wait register value before going on.
> > > + * Eg, when switch to device mode, the vbus value should be lower
> > > + * than OTGSC_BSV before connects to host.
> > 
> > This should be updated since this API is dedicated for BSV now.
> 
> Ok I've updated it to say:
> 
>   When we switch to device mode, the vbus value should be lower
>   than OTGSC_BSV before connecting to host.
> 
> > 
> > > + *
> > > + * @ci: the controller
> > > + *
> > > + * This function returns an error code if timeout  */ static int
> > > +hw_wait_otgsc_bsv(struct ci_hdrc *ci) {
> > > +     unsigned long elapse = jiffies + msecs_to_jiffies(5000);
> > > +     u32 mask = OTGSC_BSV;
> > > +
> > > +     while (!hw_read_otgsc(ci, mask)) {
> > 
> > Reverse logic, should be:
> > while (hw_read_otgsc(ci, mask)) {
> > 
> 
> Good catch! Thanks.

Besides above, please delete the declaration at ci.h.

-- 

Best Regards,
Peter Chen

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

* [PATCH 04/21] usb: chipidea: Only read/write OTGSC from one place
@ 2016-06-28  9:36           ` Peter Chen
  0 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-28  9:36 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jun 27, 2016 at 12:07:54PM -0700, Stephen Boyd wrote:
> Quoting Jun Li (2016-06-27 01:04:39)
> > > diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c index
> > > 03b6743461d1..763a8332b009 100644
> > > --- a/drivers/usb/chipidea/otg.c
> > > +++ b/drivers/usb/chipidea/otg.c
> > > @@ -104,7 +104,32 @@ void ci_handle_vbus_change(struct ci_hdrc *ci)
> > >               usb_gadget_vbus_disconnect(&ci->gadget);
> > >  }
> > > 
> > > -#define CI_VBUS_STABLE_TIMEOUT_MS 5000
> > > +/**
> > > + * Sometimes, it needs to wait register value before going on.
> > > + * Eg, when switch to device mode, the vbus value should be lower
> > > + * than OTGSC_BSV before connects to host.
> > 
> > This should be updated since this API is dedicated for BSV now.
> 
> Ok I've updated it to say:
> 
>   When we switch to device mode, the vbus value should be lower
>   than OTGSC_BSV before connecting to host.
> 
> > 
> > > + *
> > > + * @ci: the controller
> > > + *
> > > + * This function returns an error code if timeout  */ static int
> > > +hw_wait_otgsc_bsv(struct ci_hdrc *ci) {
> > > +     unsigned long elapse = jiffies + msecs_to_jiffies(5000);
> > > +     u32 mask = OTGSC_BSV;
> > > +
> > > +     while (!hw_read_otgsc(ci, mask)) {
> > 
> > Reverse logic, should be:
> > while (hw_read_otgsc(ci, mask)) {
> > 
> 
> Good catch! Thanks.

Besides above, please delete the declaration at ci.h.

-- 

Best Regards,
Peter Chen

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

* Re: [PATCH 05/21] usb: chipidea: Handle extcon events properly
  2016-06-26  7:28   ` Stephen Boyd
@ 2016-06-28 10:01     ` Peter Chen
  -1 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-28 10:01 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, Felipe Balbi, Arnd Bergmann, Neil Armstrong,
	linux-arm-msm, linux-kernel, Bjorn Andersson, Peter Chen,
	Greg Kroah-Hartman, Andy Gross, Ivan T. Ivanov, linux-arm-kernel

On Sun, Jun 26, 2016 at 12:28:22AM -0700, Stephen Boyd wrote:
> We're currently emulating the vbus and id interrupts in the OTGSC
> read API, but we also need to make sure that if we're handling
> the events with extcon that we don't enable the interrupts for
> those events in the hardware. Therefore, properly emulate this
> register if we're using extcon, but don't enable the interrupts.
> This allows me to get my cable connect/disconnect working
> properly without getting spurious interrupts on my device that
> uses an extcon for these two events.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: "Ivan T. Ivanov" <iivanov.xz@gmail.com>
> Fixes: 3ecb3e09b042 ("usb: chipidea: Use extcon framework for VBUS and ID detect")
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/otg.c   | 46 +++++++++++++++++++++++++++++++++++++++-----
>  include/linux/usb/chipidea.h |  2 ++
>  2 files changed, 43 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
> index 763a8332b009..b6a88bea4cac 100644
> --- a/drivers/usb/chipidea/otg.c
> +++ b/drivers/usb/chipidea/otg.c
> @@ -44,12 +44,15 @@ u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask)
>  		else
>  			val &= ~OTGSC_BSVIS;
>  
> -		cable->changed = false;
> -
>  		if (cable->state)
>  			val |= OTGSC_BSV;
>  		else
>  			val &= ~OTGSC_BSV;
> +
> +		if (cable->enabled)
> +			val |= OTGSC_BSVIE;
> +		else
> +			val &= ~OTGSC_BSVIE;
>  	}
>  
>  	cable = &ci->platdata->id_extcon;
> @@ -59,15 +62,18 @@ u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask)
>  		else
>  			val &= ~OTGSC_IDIS;
>  
> -		cable->changed = false;
> -
>  		if (cable->state)
>  			val |= OTGSC_ID;
>  		else
>  			val &= ~OTGSC_ID;
> +
> +		if (cable->enabled)
> +			val |= OTGSC_IDIE;
> +		else
> +			val &= ~OTGSC_IDIE;
>  	}
>  
> -	return val;
> +	return val & mask;
>  }
>  
>  /**
> @@ -77,6 +83,36 @@ u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask)
>   */
>  void hw_write_otgsc(struct ci_hdrc *ci, u32 mask, u32 data)
>  {
> +	struct ci_hdrc_cable *cable;
> +
> +	cable = &ci->platdata->vbus_extcon;
> +	if (!IS_ERR(cable->edev)) {
> +		if (data & mask & OTGSC_BSVIS)
> +			cable->changed = false;
> +
> +		/* Don't enable vbus interrupt if using external notifier */
> +		if (data & mask & OTGSC_BSVIE) {
> +			cable->enabled = true;
> +			data &= ~OTGSC_BSVIE;
> +		} else if (mask & OTGSC_BSVIE) {
> +			cable->enabled = false;
> +		}
> +	}
> +
> +	cable = &ci->platdata->id_extcon;
> +	if (!IS_ERR(cable->edev)) {
> +		if (data & mask & OTGSC_IDIS)
> +			cable->changed = false;
> +
> +		/* Don't enable id interrupt if using external notifier */
> +		if (data & mask & OTGSC_IDIE) {
> +			cable->enabled = true;
> +			data &= ~OTGSC_IDIE;
> +		} else if (mask & OTGSC_IDIE) {
> +			cable->enabled = false;
> +		}
> +	}
> +
>  	hw_write(ci, OP_OTGSC, mask | OTGSC_INT_STATUS_BITS, data);
>  }
>  
> diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
> index 5dd75fa47dd8..f9be467d6695 100644
> --- a/include/linux/usb/chipidea.h
> +++ b/include/linux/usb/chipidea.h
> @@ -14,6 +14,7 @@ struct ci_hdrc;
>   * struct ci_hdrc_cable - structure for external connector cable state tracking
>   * @state: current state of the line
>   * @changed: set to true when extcon event happen
> + * @enabled: set to true if we've enabled the vbus or id interrupt
>   * @edev: device which generate events
>   * @ci: driver state of the chipidea device
>   * @nb: hold event notification callback
> @@ -22,6 +23,7 @@ struct ci_hdrc;
>  struct ci_hdrc_cable {
>  	bool				state;
>  	bool				changed;
> +	bool				enabled;
>  	struct extcon_dev		*edev;
>  	struct ci_hdrc			*ci;
>  	struct notifier_block		nb;
> -- 

Acked-by: Peter Chen <peter.chen@nxp.com>

-- 

Best Regards,
Peter Chen

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

* [PATCH 05/21] usb: chipidea: Handle extcon events properly
@ 2016-06-28 10:01     ` Peter Chen
  0 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-28 10:01 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Jun 26, 2016 at 12:28:22AM -0700, Stephen Boyd wrote:
> We're currently emulating the vbus and id interrupts in the OTGSC
> read API, but we also need to make sure that if we're handling
> the events with extcon that we don't enable the interrupts for
> those events in the hardware. Therefore, properly emulate this
> register if we're using extcon, but don't enable the interrupts.
> This allows me to get my cable connect/disconnect working
> properly without getting spurious interrupts on my device that
> uses an extcon for these two events.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: "Ivan T. Ivanov" <iivanov.xz@gmail.com>
> Fixes: 3ecb3e09b042 ("usb: chipidea: Use extcon framework for VBUS and ID detect")
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/otg.c   | 46 +++++++++++++++++++++++++++++++++++++++-----
>  include/linux/usb/chipidea.h |  2 ++
>  2 files changed, 43 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
> index 763a8332b009..b6a88bea4cac 100644
> --- a/drivers/usb/chipidea/otg.c
> +++ b/drivers/usb/chipidea/otg.c
> @@ -44,12 +44,15 @@ u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask)
>  		else
>  			val &= ~OTGSC_BSVIS;
>  
> -		cable->changed = false;
> -
>  		if (cable->state)
>  			val |= OTGSC_BSV;
>  		else
>  			val &= ~OTGSC_BSV;
> +
> +		if (cable->enabled)
> +			val |= OTGSC_BSVIE;
> +		else
> +			val &= ~OTGSC_BSVIE;
>  	}
>  
>  	cable = &ci->platdata->id_extcon;
> @@ -59,15 +62,18 @@ u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask)
>  		else
>  			val &= ~OTGSC_IDIS;
>  
> -		cable->changed = false;
> -
>  		if (cable->state)
>  			val |= OTGSC_ID;
>  		else
>  			val &= ~OTGSC_ID;
> +
> +		if (cable->enabled)
> +			val |= OTGSC_IDIE;
> +		else
> +			val &= ~OTGSC_IDIE;
>  	}
>  
> -	return val;
> +	return val & mask;
>  }
>  
>  /**
> @@ -77,6 +83,36 @@ u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask)
>   */
>  void hw_write_otgsc(struct ci_hdrc *ci, u32 mask, u32 data)
>  {
> +	struct ci_hdrc_cable *cable;
> +
> +	cable = &ci->platdata->vbus_extcon;
> +	if (!IS_ERR(cable->edev)) {
> +		if (data & mask & OTGSC_BSVIS)
> +			cable->changed = false;
> +
> +		/* Don't enable vbus interrupt if using external notifier */
> +		if (data & mask & OTGSC_BSVIE) {
> +			cable->enabled = true;
> +			data &= ~OTGSC_BSVIE;
> +		} else if (mask & OTGSC_BSVIE) {
> +			cable->enabled = false;
> +		}
> +	}
> +
> +	cable = &ci->platdata->id_extcon;
> +	if (!IS_ERR(cable->edev)) {
> +		if (data & mask & OTGSC_IDIS)
> +			cable->changed = false;
> +
> +		/* Don't enable id interrupt if using external notifier */
> +		if (data & mask & OTGSC_IDIE) {
> +			cable->enabled = true;
> +			data &= ~OTGSC_IDIE;
> +		} else if (mask & OTGSC_IDIE) {
> +			cable->enabled = false;
> +		}
> +	}
> +
>  	hw_write(ci, OP_OTGSC, mask | OTGSC_INT_STATUS_BITS, data);
>  }
>  
> diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
> index 5dd75fa47dd8..f9be467d6695 100644
> --- a/include/linux/usb/chipidea.h
> +++ b/include/linux/usb/chipidea.h
> @@ -14,6 +14,7 @@ struct ci_hdrc;
>   * struct ci_hdrc_cable - structure for external connector cable state tracking
>   * @state: current state of the line
>   * @changed: set to true when extcon event happen
> + * @enabled: set to true if we've enabled the vbus or id interrupt
>   * @edev: device which generate events
>   * @ci: driver state of the chipidea device
>   * @nb: hold event notification callback
> @@ -22,6 +23,7 @@ struct ci_hdrc;
>  struct ci_hdrc_cable {
>  	bool				state;
>  	bool				changed;
> +	bool				enabled;
>  	struct extcon_dev		*edev;
>  	struct ci_hdrc			*ci;
>  	struct notifier_block		nb;
> -- 

Acked-by: Peter Chen <peter.chen@nxp.com>

-- 

Best Regards,
Peter Chen

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

* Re: [PATCH 02/21] usb: ulpi: Support device discovery via DT
  2016-06-27 22:10         ` Stephen Boyd
@ 2016-06-28 11:42           ` Heikki Krogerus
  -1 siblings, 0 replies; 214+ messages in thread
From: Heikki Krogerus @ 2016-06-28 11:42 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Felipe Balbi, Arnd Bergmann, Neil Armstrong, linux-arm-msm,
	linux-usb, linux-kernel, Bjorn Andersson, devicetree,
	Rob Herring, Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

On Mon, Jun 27, 2016 at 03:10:40PM -0700, Stephen Boyd wrote:
> Quoting Heikki Krogerus (2016-06-27 07:34:22)
> > Hi,
> > 
> > I'm fine with most of the patch, except..
> > 
> > On Sun, Jun 26, 2016 at 12:28:19AM -0700, Stephen Boyd wrote:
> > > @@ -39,7 +42,10 @@ static int ulpi_match(struct device *dev, struct device_driver *driver)
> > >       struct ulpi *ulpi = to_ulpi_dev(dev);
> > >       const struct ulpi_device_id *id;
> > >  
> > > -     for (id = drv->id_table; id->vendor; id++)
> > > +     if (of_driver_match_device(dev, driver))
> > > +             return 1;
> > 
> > I don't like this part. We should match separately like that only
> > if the bus does not support native enumeration, and of course ULPI
> > with its vendor and product IDs does. There really should always be
> > IDs to match with here. So exceptions have to be solved before we
> > attempt matching.
> > 
> > Since we also have to support platforms where the PHY is initially
> > powered off and reading the IDs from the registers is not possible
> > because of that, I think we should consider getting the product and
> > vendor IDs optionally from device properties. Something like this:
> 
> Ok, I'm a little worried about conflating the powered off problem with
> this product/vendor ID missing problem. But if you're ok with that I'll
> combine the two patches into one using your approach below.
> 
> > 
> > 
> > diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c
> > index 01c0c04..6228a85 100644
> > --- a/drivers/usb/common/ulpi.c
> > +++ b/drivers/usb/common/ulpi.c
> > @@ -152,7 +152,7 @@ EXPORT_SYMBOL_GPL(ulpi_unregister_driver);
> >  
> >  /* -------------------------------------------------------------------------- */
> >  
> > -static int ulpi_register(struct device *dev, struct ulpi *ulpi)
> > +static int ulpi_read_id(struct ulpi *ulpi)
> >  {
> >         int ret;
> >  
> > @@ -174,6 +174,21 @@ static int ulpi_register(struct device *dev, struct ulpi *ulpi)
> >         ulpi->id.product = ulpi_read(ulpi, ULPI_PRODUCT_ID_LOW);
> >         ulpi->id.product |= ulpi_read(ulpi, ULPI_PRODUCT_ID_HIGH) << 8;
> >  
> > +       return 0;
> > +}
> > +
> > +static int ulpi_register(struct device *dev, struct ulpi *ulpi)
> > +{
> > +       int ret;
> > +
> > +       ret = device_property_read_u16(dev, "ulpi-vendor", &ulpi->id.vendor);
> > +       ret |= device_property_read_u16(dev, "ulpi-product", &ulpi->id.product);
> > +       if (ret) {
> > +               ret = ulpi_read_id(ulpi);
> > +               if (ret)
> > +                       return ret;
> > +       }
> > +
> >         ulpi->dev.parent = dev;
> >         ulpi->dev.bus = &ulpi_bus;
> >         ulpi->dev.type = &ulpi_dev_type;
> > 
> > 
> > That should cover both cases. You would just have to create the IDs
> > yourself in this case.
> > 
> 
> Right, I would have to make up some IDs in this case. I suppose I can
> use the qcom vendor ID 0x05c6 and then product ids 0 and 1 for HS phy
> and HSIC phy? That doesn't make me feel great because it's all made up,
> but I guess there's no other option. I hope they don't decide to start
> populating these ids in the future though and then we may have
> conflicting product ids. If that happens I suppose we can do a
> workaround based on compatible strings in the DT node. Fun!
> 
> Nice side effect of all that is I can drop requesting the module by DT
> aliases and things become simpler. I'll try this out.

I was hoping that we could manage with product id 0 as an exception (I
failed to consider that you have multiple PHYs to deal with). I don't
think we can just come up with product id > 0.

I guess we should have the of_driver_match_device() call after all.
Let's just call it conditionally, only in cases where there is no
product ID, to make me feel a bit more better. I don't want to make it
too easy to use.

The properties for the vendor and product ID are still something that
we need to introduce in any case. We have the powered off problem on
all kinds of platforms, and not all of them use DT. Please feel free
to incorporate the diff into the patch you had for the powered off
case if you are OK with it. So I think in your case you would just
need to addthe correct ulpi-vendor id 0x05c6 and ulpi-product id 0 to
the chipidea device node, and I think this would work.

Sorry about the hassle.


Thanks,

-- 
heikki

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

* [PATCH 02/21] usb: ulpi: Support device discovery via DT
@ 2016-06-28 11:42           ` Heikki Krogerus
  0 siblings, 0 replies; 214+ messages in thread
From: Heikki Krogerus @ 2016-06-28 11:42 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jun 27, 2016 at 03:10:40PM -0700, Stephen Boyd wrote:
> Quoting Heikki Krogerus (2016-06-27 07:34:22)
> > Hi,
> > 
> > I'm fine with most of the patch, except..
> > 
> > On Sun, Jun 26, 2016 at 12:28:19AM -0700, Stephen Boyd wrote:
> > > @@ -39,7 +42,10 @@ static int ulpi_match(struct device *dev, struct device_driver *driver)
> > >       struct ulpi *ulpi = to_ulpi_dev(dev);
> > >       const struct ulpi_device_id *id;
> > >  
> > > -     for (id = drv->id_table; id->vendor; id++)
> > > +     if (of_driver_match_device(dev, driver))
> > > +             return 1;
> > 
> > I don't like this part. We should match separately like that only
> > if the bus does not support native enumeration, and of course ULPI
> > with its vendor and product IDs does. There really should always be
> > IDs to match with here. So exceptions have to be solved before we
> > attempt matching.
> > 
> > Since we also have to support platforms where the PHY is initially
> > powered off and reading the IDs from the registers is not possible
> > because of that, I think we should consider getting the product and
> > vendor IDs optionally from device properties. Something like this:
> 
> Ok, I'm a little worried about conflating the powered off problem with
> this product/vendor ID missing problem. But if you're ok with that I'll
> combine the two patches into one using your approach below.
> 
> > 
> > 
> > diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c
> > index 01c0c04..6228a85 100644
> > --- a/drivers/usb/common/ulpi.c
> > +++ b/drivers/usb/common/ulpi.c
> > @@ -152,7 +152,7 @@ EXPORT_SYMBOL_GPL(ulpi_unregister_driver);
> >  
> >  /* -------------------------------------------------------------------------- */
> >  
> > -static int ulpi_register(struct device *dev, struct ulpi *ulpi)
> > +static int ulpi_read_id(struct ulpi *ulpi)
> >  {
> >         int ret;
> >  
> > @@ -174,6 +174,21 @@ static int ulpi_register(struct device *dev, struct ulpi *ulpi)
> >         ulpi->id.product = ulpi_read(ulpi, ULPI_PRODUCT_ID_LOW);
> >         ulpi->id.product |= ulpi_read(ulpi, ULPI_PRODUCT_ID_HIGH) << 8;
> >  
> > +       return 0;
> > +}
> > +
> > +static int ulpi_register(struct device *dev, struct ulpi *ulpi)
> > +{
> > +       int ret;
> > +
> > +       ret = device_property_read_u16(dev, "ulpi-vendor", &ulpi->id.vendor);
> > +       ret |= device_property_read_u16(dev, "ulpi-product", &ulpi->id.product);
> > +       if (ret) {
> > +               ret = ulpi_read_id(ulpi);
> > +               if (ret)
> > +                       return ret;
> > +       }
> > +
> >         ulpi->dev.parent = dev;
> >         ulpi->dev.bus = &ulpi_bus;
> >         ulpi->dev.type = &ulpi_dev_type;
> > 
> > 
> > That should cover both cases. You would just have to create the IDs
> > yourself in this case.
> > 
> 
> Right, I would have to make up some IDs in this case. I suppose I can
> use the qcom vendor ID 0x05c6 and then product ids 0 and 1 for HS phy
> and HSIC phy? That doesn't make me feel great because it's all made up,
> but I guess there's no other option. I hope they don't decide to start
> populating these ids in the future though and then we may have
> conflicting product ids. If that happens I suppose we can do a
> workaround based on compatible strings in the DT node. Fun!
> 
> Nice side effect of all that is I can drop requesting the module by DT
> aliases and things become simpler. I'll try this out.

I was hoping that we could manage with product id 0 as an exception (I
failed to consider that you have multiple PHYs to deal with). I don't
think we can just come up with product id > 0.

I guess we should have the of_driver_match_device() call after all.
Let's just call it conditionally, only in cases where there is no
product ID, to make me feel a bit more better. I don't want to make it
too easy to use.

The properties for the vendor and product ID are still something that
we need to introduce in any case. We have the powered off problem on
all kinds of platforms, and not all of them use DT. Please feel free
to incorporate the diff into the patch you had for the powered off
case if you are OK with it. So I think in your case you would just
need to addthe correct ulpi-vendor id 0x05c6 and ulpi-product id 0 to
the chipidea device node, and I think this would work.

Sorry about the hassle.


Thanks,

-- 
heikki

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

* Re: [PATCH 02/21] usb: ulpi: Support device discovery via DT
  2016-06-28 11:42           ` Heikki Krogerus
@ 2016-06-28 18:27             ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-28 18:27 UTC (permalink / raw)
  To: Heikki Krogerus
  Cc: Felipe Balbi, Arnd Bergmann, Neil Armstrong, linux-arm-msm,
	linux-usb, linux-kernel, Bjorn Andersson, devicetree,
	Rob Herring, Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

Quoting Heikki Krogerus (2016-06-28 04:42:05)
> On Mon, Jun 27, 2016 at 03:10:40PM -0700, Stephen Boyd wrote:
> > 
> > Right, I would have to make up some IDs in this case. I suppose I can
> > use the qcom vendor ID 0x05c6 and then product ids 0 and 1 for HS phy
> > and HSIC phy? That doesn't make me feel great because it's all made up,
> > but I guess there's no other option. I hope they don't decide to start
> > populating these ids in the future though and then we may have
> > conflicting product ids. If that happens I suppose we can do a
> > workaround based on compatible strings in the DT node. Fun!
> > 
> > Nice side effect of all that is I can drop requesting the module by DT
> > aliases and things become simpler. I'll try this out.
> 
> I was hoping that we could manage with product id 0 as an exception (I
> failed to consider that you have multiple PHYs to deal with). I don't
> think we can just come up with product id > 0.
> 
> I guess we should have the of_driver_match_device() call after all.
> Let's just call it conditionally, only in cases where there is no
> product ID, to make me feel a bit more better. I don't want to make it
> too easy to use.
> 
> The properties for the vendor and product ID are still something that
> we need to introduce in any case. We have the powered off problem on
> all kinds of platforms, and not all of them use DT. Please feel free
> to incorporate the diff into the patch you had for the powered off
> case if you are OK with it. So I think in your case you would just
> need to addthe correct ulpi-vendor id 0x05c6 and ulpi-product id 0 to
> the chipidea device node, and I think this would work.
> 

Hmm ok. I'll have to bring back all the module loading and uevent stuff
based on DT compatible strings then. We'll have the same product id on
HSIC and HS phys, but that isn't a big deal.

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

* [PATCH 02/21] usb: ulpi: Support device discovery via DT
@ 2016-06-28 18:27             ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-28 18:27 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Heikki Krogerus (2016-06-28 04:42:05)
> On Mon, Jun 27, 2016 at 03:10:40PM -0700, Stephen Boyd wrote:
> > 
> > Right, I would have to make up some IDs in this case. I suppose I can
> > use the qcom vendor ID 0x05c6 and then product ids 0 and 1 for HS phy
> > and HSIC phy? That doesn't make me feel great because it's all made up,
> > but I guess there's no other option. I hope they don't decide to start
> > populating these ids in the future though and then we may have
> > conflicting product ids. If that happens I suppose we can do a
> > workaround based on compatible strings in the DT node. Fun!
> > 
> > Nice side effect of all that is I can drop requesting the module by DT
> > aliases and things become simpler. I'll try this out.
> 
> I was hoping that we could manage with product id 0 as an exception (I
> failed to consider that you have multiple PHYs to deal with). I don't
> think we can just come up with product id > 0.
> 
> I guess we should have the of_driver_match_device() call after all.
> Let's just call it conditionally, only in cases where there is no
> product ID, to make me feel a bit more better. I don't want to make it
> too easy to use.
> 
> The properties for the vendor and product ID are still something that
> we need to introduce in any case. We have the powered off problem on
> all kinds of platforms, and not all of them use DT. Please feel free
> to incorporate the diff into the patch you had for the powered off
> case if you are OK with it. So I think in your case you would just
> need to addthe correct ulpi-vendor id 0x05c6 and ulpi-product id 0 to
> the chipidea device node, and I think this would work.
> 

Hmm ok. I'll have to bring back all the module loading and uevent stuff
based on DT compatible strings then. We'll have the same product id on
HSIC and HS phys, but that isn't a big deal.

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

* Re: [PATCH 02/21] usb: ulpi: Support device discovery via DT
  2016-06-26  7:28     ` Stephen Boyd
@ 2016-06-28 20:56       ` Rob Herring
  -1 siblings, 0 replies; 214+ messages in thread
From: Rob Herring @ 2016-06-28 20:56 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, linux-arm-kernel, linux-kernel, linux-arm-msm,
	Andy Gross, Bjorn Andersson, Neil Armstrong, Arnd Bergmann,
	Felipe Balbi, Greg Kroah-Hartman, Heikki Krogerus, devicetree

On Sun, Jun 26, 2016 at 12:28:19AM -0700, Stephen Boyd wrote:
> The qcom HSIC ulpi phy doesn't have any bits set in the vendor or
> product id ulpi registers. This makes it impossible to make a
> ulpi driver match against the id registers. Add support to
> discover the ulpi phys via DT to help alleviate this problem.
> We'll look for a ulpi bus node underneath the device registering
> the ulpi viewport (or the parent of that device to support
> chipidea's device layout) and then match up the phy node
> underneath that with the ulpi device that's created.
> 
> The side benefit of this is that we can use standard DT
> properties in the phy node like clks, regulators, gpios, etc.
> because we don't have firmware like ACPI to turn these things on
> for us. And we can use the DT phy binding to point our phy
> consumer to the phy provider.
> 
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> Cc: <devicetree@vger.kernel.org>
> Cc: Rob Herring <robh+dt@kernel.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  Documentation/devicetree/bindings/usb/ulpi.txt | 20 +++++++++
>  drivers/usb/common/ulpi.c                      | 56 +++++++++++++++++++++++++-
>  2 files changed, 74 insertions(+), 2 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/usb/ulpi.txt
> 
> diff --git a/Documentation/devicetree/bindings/usb/ulpi.txt b/Documentation/devicetree/bindings/usb/ulpi.txt
> new file mode 100644
> index 000000000000..ca179dc4bd50
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/usb/ulpi.txt
> @@ -0,0 +1,20 @@
> +ULPI bus binding
> +----------------
> +
> +Phys that are behind a ULPI connection can be described with the following
> +binding. The host controller shall have a "ulpi" named node as a child, and
> +that node shall have one enabled node underneath it representing the ulpi
> +device on the bus.

This needs to co-exist with the USB bus binding which has the controller 
ports for the child nodes. Maybe use the phy binding?

> +
> +EXAMPLE
> +-------
> +
> +usb {
> +	compatible = "vendor,usb-controller";
> +
> +	ulpi {
> +		phy {
> +			compatible = "vendor,phy";
> +		};
> +	};
> +};

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

* [PATCH 02/21] usb: ulpi: Support device discovery via DT
@ 2016-06-28 20:56       ` Rob Herring
  0 siblings, 0 replies; 214+ messages in thread
From: Rob Herring @ 2016-06-28 20:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Jun 26, 2016 at 12:28:19AM -0700, Stephen Boyd wrote:
> The qcom HSIC ulpi phy doesn't have any bits set in the vendor or
> product id ulpi registers. This makes it impossible to make a
> ulpi driver match against the id registers. Add support to
> discover the ulpi phys via DT to help alleviate this problem.
> We'll look for a ulpi bus node underneath the device registering
> the ulpi viewport (or the parent of that device to support
> chipidea's device layout) and then match up the phy node
> underneath that with the ulpi device that's created.
> 
> The side benefit of this is that we can use standard DT
> properties in the phy node like clks, regulators, gpios, etc.
> because we don't have firmware like ACPI to turn these things on
> for us. And we can use the DT phy binding to point our phy
> consumer to the phy provider.
> 
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> Cc: <devicetree@vger.kernel.org>
> Cc: Rob Herring <robh+dt@kernel.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  Documentation/devicetree/bindings/usb/ulpi.txt | 20 +++++++++
>  drivers/usb/common/ulpi.c                      | 56 +++++++++++++++++++++++++-
>  2 files changed, 74 insertions(+), 2 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/usb/ulpi.txt
> 
> diff --git a/Documentation/devicetree/bindings/usb/ulpi.txt b/Documentation/devicetree/bindings/usb/ulpi.txt
> new file mode 100644
> index 000000000000..ca179dc4bd50
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/usb/ulpi.txt
> @@ -0,0 +1,20 @@
> +ULPI bus binding
> +----------------
> +
> +Phys that are behind a ULPI connection can be described with the following
> +binding. The host controller shall have a "ulpi" named node as a child, and
> +that node shall have one enabled node underneath it representing the ulpi
> +device on the bus.

This needs to co-exist with the USB bus binding which has the controller 
ports for the child nodes. Maybe use the phy binding?

> +
> +EXAMPLE
> +-------
> +
> +usb {
> +	compatible = "vendor,usb-controller";
> +
> +	ulpi {
> +		phy {
> +			compatible = "vendor,phy";
> +		};
> +	};
> +};

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

* Re: [PATCH 20/21] phy: Add support for Qualcomm's USB HSIC phy
  2016-06-28  8:49       ` Neil Armstrong
  (?)
@ 2016-06-28 21:58         ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-28 21:58 UTC (permalink / raw)
  To: Neil Armstrong, linux-usb
  Cc: Felipe Balbi, Arnd Bergmann, devicetree, linux-arm-msm,
	linux-kernel, Bjorn Andersson, Andy Gross,
	Kishon Vijay Abraham I, linux-arm-kernel

Quoting Neil Armstrong (2016-06-28 01:49:37)
> On 06/26/2016 09:28 AM, Stephen Boyd wrote:
> > +     uphy->cal_sleep_clk = clk = devm_clk_get(&ulpi->dev, "cal_sleep");
> > +     if (IS_ERR(clk))
> > +             return PTR_ERR(clk);
> 
> Hi Stephen,
> 
> In the bindings the cal_sleep is marked optional, and I think should be since AFAIK
> it's not present on MDM9615 for example.

The cal_sleep clk is just the sleep clk then (should be a board clk in
DT). Sometimes there's a gate in GCC to allow us to turn it off, other
times there isn't. Either way, it's always wired there so I'll update
the binding to say it isn't optional.

> 
> Also MDM9615 HSIC requires "core", "alt-core", "phy", "cal" and "iface" clocks.
> I assume "core" can be attributed to the main chipidea node, but I think "alt-core" and "iface" should be also optionnal.

Looking at the downstream sources I see this:

        "core_clk"     -> usb_hsic_sys_clk
        "iface_clk"    -> usb_hsic_p_clk
        "alt_core_clk" -> usb_hsic_xcvr_clk

        "cal_clk"      -> usb_hsic_hsio_cal_clk
        "phy_clk"      -> usb_hsic_clk

"core_clk" would be the core clk in ci_hdrc_msm. "iface_clk" would be
the iface clk in ci_hdrc_msm. "cal_clk" would be the cal clk in the hsic
phy and "phy_clk" would be the phy clk in the hsic phy.

That leaves alt_core_clk which seems to be a clock that needs to be on
during the reset assert/deassert and possibly for LPM and USB1.1 FS
modes. Sometimes it's referred to as the "housekeeping" clk. Due to the
way resets are done on msm8974 and later SoCs it looks like this clk was
removed. I can make this an optional clk in the ci_hdrc_msm driver, or
we can have two versions of the ci_hdrc_msm compatible string, one for a
device that has the housekeeping clk and one for the device that
doesn't.

> 
> Finally, it misses an optional reset line AFAIK mandatory on MDM9615.
> 

>From what I can tell downstream, all those clks point to the same bit 0
of HSIC_RESET register? So there isn't any phy reset, just the chipidea
controller wrapper reset bit, which should go into the wrapper node?

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

* Re: [PATCH 20/21] phy: Add support for Qualcomm's USB HSIC phy
@ 2016-06-28 21:58         ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-28 21:58 UTC (permalink / raw)
  To: Neil Armstrong, linux-usb
  Cc: linux-arm-kernel, linux-kernel, linux-arm-msm, Andy Gross,
	Bjorn Andersson, Arnd Bergmann, Felipe Balbi,
	Kishon Vijay Abraham I, devicetree

Quoting Neil Armstrong (2016-06-28 01:49:37)
> On 06/26/2016 09:28 AM, Stephen Boyd wrote:
> > +     uphy->cal_sleep_clk = clk = devm_clk_get(&ulpi->dev, "cal_sleep");
> > +     if (IS_ERR(clk))
> > +             return PTR_ERR(clk);
> 
> Hi Stephen,
> 
> In the bindings the cal_sleep is marked optional, and I think should be since AFAIK
> it's not present on MDM9615 for example.

The cal_sleep clk is just the sleep clk then (should be a board clk in
DT). Sometimes there's a gate in GCC to allow us to turn it off, other
times there isn't. Either way, it's always wired there so I'll update
the binding to say it isn't optional.

> 
> Also MDM9615 HSIC requires "core", "alt-core", "phy", "cal" and "iface" clocks.
> I assume "core" can be attributed to the main chipidea node, but I think "alt-core" and "iface" should be also optionnal.

Looking at the downstream sources I see this:

        "core_clk"     -> usb_hsic_sys_clk
        "iface_clk"    -> usb_hsic_p_clk
        "alt_core_clk" -> usb_hsic_xcvr_clk

        "cal_clk"      -> usb_hsic_hsio_cal_clk
        "phy_clk"      -> usb_hsic_clk

"core_clk" would be the core clk in ci_hdrc_msm. "iface_clk" would be
the iface clk in ci_hdrc_msm. "cal_clk" would be the cal clk in the hsic
phy and "phy_clk" would be the phy clk in the hsic phy.

That leaves alt_core_clk which seems to be a clock that needs to be on
during the reset assert/deassert and possibly for LPM and USB1.1 FS
modes. Sometimes it's referred to as the "housekeeping" clk. Due to the
way resets are done on msm8974 and later SoCs it looks like this clk was
removed. I can make this an optional clk in the ci_hdrc_msm driver, or
we can have two versions of the ci_hdrc_msm compatible string, one for a
device that has the housekeeping clk and one for the device that
doesn't.

> 
> Finally, it misses an optional reset line AFAIK mandatory on MDM9615.
> 

>From what I can tell downstream, all those clks point to the same bit 0
of HSIC_RESET register? So there isn't any phy reset, just the chipidea
controller wrapper reset bit, which should go into the wrapper node?

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

* [PATCH 20/21] phy: Add support for Qualcomm's USB HSIC phy
@ 2016-06-28 21:58         ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-28 21:58 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Neil Armstrong (2016-06-28 01:49:37)
> On 06/26/2016 09:28 AM, Stephen Boyd wrote:
> > +     uphy->cal_sleep_clk = clk = devm_clk_get(&ulpi->dev, "cal_sleep");
> > +     if (IS_ERR(clk))
> > +             return PTR_ERR(clk);
> 
> Hi Stephen,
> 
> In the bindings the cal_sleep is marked optional, and I think should be since AFAIK
> it's not present on MDM9615 for example.

The cal_sleep clk is just the sleep clk then (should be a board clk in
DT). Sometimes there's a gate in GCC to allow us to turn it off, other
times there isn't. Either way, it's always wired there so I'll update
the binding to say it isn't optional.

> 
> Also MDM9615 HSIC requires "core", "alt-core", "phy", "cal" and "iface" clocks.
> I assume "core" can be attributed to the main chipidea node, but I think "alt-core" and "iface" should be also optionnal.

Looking at the downstream sources I see this:

        "core_clk"     -> usb_hsic_sys_clk
        "iface_clk"    -> usb_hsic_p_clk
        "alt_core_clk" -> usb_hsic_xcvr_clk

        "cal_clk"      -> usb_hsic_hsio_cal_clk
        "phy_clk"      -> usb_hsic_clk

"core_clk" would be the core clk in ci_hdrc_msm. "iface_clk" would be
the iface clk in ci_hdrc_msm. "cal_clk" would be the cal clk in the hsic
phy and "phy_clk" would be the phy clk in the hsic phy.

That leaves alt_core_clk which seems to be a clock that needs to be on
during the reset assert/deassert and possibly for LPM and USB1.1 FS
modes. Sometimes it's referred to as the "housekeeping" clk. Due to the
way resets are done on msm8974 and later SoCs it looks like this clk was
removed. I can make this an optional clk in the ci_hdrc_msm driver, or
we can have two versions of the ci_hdrc_msm compatible string, one for a
device that has the housekeeping clk and one for the device that
doesn't.

> 
> Finally, it misses an optional reset line AFAIK mandatory on MDM9615.
> 

>From what I can tell downstream, all those clks point to the same bit 0
of HSIC_RESET register? So there isn't any phy reset, just the chipidea
controller wrapper reset bit, which should go into the wrapper node?

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

* Re: [PATCH 02/21] usb: ulpi: Support device discovery via DT
  2016-06-28 20:56       ` Rob Herring
@ 2016-06-28 22:09         ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-28 22:09 UTC (permalink / raw)
  To: Rob Herring
  Cc: Felipe Balbi, Heikki Krogerus, Arnd Bergmann, Neil Armstrong,
	linux-arm-msm, linux-usb, linux-kernel, Bjorn Andersson,
	devicetree, Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

Quoting Rob Herring (2016-06-28 13:56:42)
> On Sun, Jun 26, 2016 at 12:28:19AM -0700, Stephen Boyd wrote:
> > The qcom HSIC ulpi phy doesn't have any bits set in the vendor or
> > product id ulpi registers. This makes it impossible to make a
> > ulpi driver match against the id registers. Add support to
> > discover the ulpi phys via DT to help alleviate this problem.
> > We'll look for a ulpi bus node underneath the device registering
> > the ulpi viewport (or the parent of that device to support
> > chipidea's device layout) and then match up the phy node
> > underneath that with the ulpi device that's created.
> > 
> > The side benefit of this is that we can use standard DT
> > properties in the phy node like clks, regulators, gpios, etc.
> > because we don't have firmware like ACPI to turn these things on
> > for us. And we can use the DT phy binding to point our phy
> > consumer to the phy provider.
> > 
> > Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> > Cc: <devicetree@vger.kernel.org>
> > Cc: Rob Herring <robh+dt@kernel.org>
> > Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> > ---
> >  Documentation/devicetree/bindings/usb/ulpi.txt | 20 +++++++++
> >  drivers/usb/common/ulpi.c                      | 56 +++++++++++++++++++++++++-
> >  2 files changed, 74 insertions(+), 2 deletions(-)
> >  create mode 100644 Documentation/devicetree/bindings/usb/ulpi.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/usb/ulpi.txt b/Documentation/devicetree/bindings/usb/ulpi.txt
> > new file mode 100644
> > index 000000000000..ca179dc4bd50
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/usb/ulpi.txt
> > @@ -0,0 +1,20 @@
> > +ULPI bus binding
> > +----------------
> > +
> > +Phys that are behind a ULPI connection can be described with the following
> > +binding. The host controller shall have a "ulpi" named node as a child, and
> > +that node shall have one enabled node underneath it representing the ulpi
> > +device on the bus.
> 
> This needs to co-exist with the USB bus binding which has the controller 
> ports for the child nodes. Maybe use the phy binding?

Which binding is that? bindings/usb/usb-device.txt? This ulpi binding is
to describe phys that are accessed through the ulpi "viewport" in the
usb controller. So controller ports don't come into the picture here.

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

* [PATCH 02/21] usb: ulpi: Support device discovery via DT
@ 2016-06-28 22:09         ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-28 22:09 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Rob Herring (2016-06-28 13:56:42)
> On Sun, Jun 26, 2016 at 12:28:19AM -0700, Stephen Boyd wrote:
> > The qcom HSIC ulpi phy doesn't have any bits set in the vendor or
> > product id ulpi registers. This makes it impossible to make a
> > ulpi driver match against the id registers. Add support to
> > discover the ulpi phys via DT to help alleviate this problem.
> > We'll look for a ulpi bus node underneath the device registering
> > the ulpi viewport (or the parent of that device to support
> > chipidea's device layout) and then match up the phy node
> > underneath that with the ulpi device that's created.
> > 
> > The side benefit of this is that we can use standard DT
> > properties in the phy node like clks, regulators, gpios, etc.
> > because we don't have firmware like ACPI to turn these things on
> > for us. And we can use the DT phy binding to point our phy
> > consumer to the phy provider.
> > 
> > Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> > Cc: <devicetree@vger.kernel.org>
> > Cc: Rob Herring <robh+dt@kernel.org>
> > Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> > ---
> >  Documentation/devicetree/bindings/usb/ulpi.txt | 20 +++++++++
> >  drivers/usb/common/ulpi.c                      | 56 +++++++++++++++++++++++++-
> >  2 files changed, 74 insertions(+), 2 deletions(-)
> >  create mode 100644 Documentation/devicetree/bindings/usb/ulpi.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/usb/ulpi.txt b/Documentation/devicetree/bindings/usb/ulpi.txt
> > new file mode 100644
> > index 000000000000..ca179dc4bd50
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/usb/ulpi.txt
> > @@ -0,0 +1,20 @@
> > +ULPI bus binding
> > +----------------
> > +
> > +Phys that are behind a ULPI connection can be described with the following
> > +binding. The host controller shall have a "ulpi" named node as a child, and
> > +that node shall have one enabled node underneath it representing the ulpi
> > +device on the bus.
> 
> This needs to co-exist with the USB bus binding which has the controller 
> ports for the child nodes. Maybe use the phy binding?

Which binding is that? bindings/usb/usb-device.txt? This ulpi binding is
to describe phys that are accessed through the ulpi "viewport" in the
usb controller. So controller ports don't come into the picture here.

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

* Re: [PATCH 04/21] usb: chipidea: Only read/write OTGSC from one place
  2016-06-28  9:36           ` Peter Chen
@ 2016-06-28 22:10             ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-28 22:10 UTC (permalink / raw)
  To: Peter Chen
  Cc: Felipe Balbi, Arnd Bergmann, Neil Armstrong, linux-arm-msm,
	linux-usb, linux-kernel, Bjorn Andersson, Peter Chen,
	Greg Kroah-Hartman, Andy Gross, Ivan T. Ivanov, linux-arm-kernel,
	Jun Li

Quoting Peter Chen (2016-06-28 02:36:06)
> On Mon, Jun 27, 2016 at 12:07:54PM -0700, Stephen Boyd wrote:
> > 
> > Good catch! Thanks.
> 
> Besides above, please delete the declaration at ci.h.
> 

Done. Thanks.

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

* [PATCH 04/21] usb: chipidea: Only read/write OTGSC from one place
@ 2016-06-28 22:10             ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-28 22:10 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Peter Chen (2016-06-28 02:36:06)
> On Mon, Jun 27, 2016 at 12:07:54PM -0700, Stephen Boyd wrote:
> > 
> > Good catch! Thanks.
> 
> Besides above, please delete the declaration at ci.h.
> 

Done. Thanks.

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

* Re: [PATCH 02/21] usb: ulpi: Support device discovery via DT
  2016-06-28 11:42           ` Heikki Krogerus
@ 2016-06-29  1:53             ` Peter Chen
  -1 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-29  1:53 UTC (permalink / raw)
  To: Heikki Krogerus
  Cc: Stephen Boyd, Felipe Balbi, Arnd Bergmann, Neil Armstrong,
	linux-arm-msm, linux-usb, linux-kernel, Bjorn Andersson,
	devicetree, Rob Herring, Greg Kroah-Hartman, Andy Gross,
	linux-arm-kernel

On Tue, Jun 28, 2016 at 02:42:05PM +0300, Heikki Krogerus wrote:
> On Mon, Jun 27, 2016 at 03:10:40PM -0700, Stephen Boyd wrote:
> > Quoting Heikki Krogerus (2016-06-27 07:34:22)
> > > Hi,
> > > 
> > > I'm fine with most of the patch, except..
> > > 
> > > On Sun, Jun 26, 2016 at 12:28:19AM -0700, Stephen Boyd wrote:
> > > > @@ -39,7 +42,10 @@ static int ulpi_match(struct device *dev, struct device_driver *driver)
> > > >       struct ulpi *ulpi = to_ulpi_dev(dev);
> > > >       const struct ulpi_device_id *id;
> > > >  
> > > > -     for (id = drv->id_table; id->vendor; id++)
> > > > +     if (of_driver_match_device(dev, driver))
> > > > +             return 1;
> > > 
> > > I don't like this part. We should match separately like that only
> > > if the bus does not support native enumeration, and of course ULPI
> > > with its vendor and product IDs does. There really should always be
> > > IDs to match with here. So exceptions have to be solved before we
> > > attempt matching.
> > > 
> > > Since we also have to support platforms where the PHY is initially
> > > powered off and reading the IDs from the registers is not possible
> > > because of that, I think we should consider getting the product and
> > > vendor IDs optionally from device properties. Something like this:
> > 
> > Ok, I'm a little worried about conflating the powered off problem with
> > this product/vendor ID missing problem. But if you're ok with that I'll
> > combine the two patches into one using your approach below.
> > 
> > > 
> > > 
> > > diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c
> > > index 01c0c04..6228a85 100644
> > > --- a/drivers/usb/common/ulpi.c
> > > +++ b/drivers/usb/common/ulpi.c
> > > @@ -152,7 +152,7 @@ EXPORT_SYMBOL_GPL(ulpi_unregister_driver);
> > >  
> > >  /* -------------------------------------------------------------------------- */
> > >  
> > > -static int ulpi_register(struct device *dev, struct ulpi *ulpi)
> > > +static int ulpi_read_id(struct ulpi *ulpi)
> > >  {
> > >         int ret;
> > >  
> > > @@ -174,6 +174,21 @@ static int ulpi_register(struct device *dev, struct ulpi *ulpi)
> > >         ulpi->id.product = ulpi_read(ulpi, ULPI_PRODUCT_ID_LOW);
> > >         ulpi->id.product |= ulpi_read(ulpi, ULPI_PRODUCT_ID_HIGH) << 8;
> > >  
> > > +       return 0;
> > > +}
> > > +
> > > +static int ulpi_register(struct device *dev, struct ulpi *ulpi)
> > > +{
> > > +       int ret;
> > > +
> > > +       ret = device_property_read_u16(dev, "ulpi-vendor", &ulpi->id.vendor);
> > > +       ret |= device_property_read_u16(dev, "ulpi-product", &ulpi->id.product);
> > > +       if (ret) {
> > > +               ret = ulpi_read_id(ulpi);
> > > +               if (ret)
> > > +                       return ret;
> > > +       }
> > > +
> > >         ulpi->dev.parent = dev;
> > >         ulpi->dev.bus = &ulpi_bus;
> > >         ulpi->dev.type = &ulpi_dev_type;
> > > 
> > > 
> > > That should cover both cases. You would just have to create the IDs
> > > yourself in this case.
> > > 
> > 
> > Right, I would have to make up some IDs in this case. I suppose I can
> > use the qcom vendor ID 0x05c6 and then product ids 0 and 1 for HS phy
> > and HSIC phy? That doesn't make me feel great because it's all made up,
> > but I guess there's no other option. I hope they don't decide to start
> > populating these ids in the future though and then we may have
> > conflicting product ids. If that happens I suppose we can do a
> > workaround based on compatible strings in the DT node. Fun!
> > 
> > Nice side effect of all that is I can drop requesting the module by DT
> > aliases and things become simpler. I'll try this out.
> 
> I was hoping that we could manage with product id 0 as an exception (I
> failed to consider that you have multiple PHYs to deal with). I don't
> think we can just come up with product id > 0.
> 
> I guess we should have the of_driver_match_device() call after all.
> Let's just call it conditionally, only in cases where there is no
> product ID, to make me feel a bit more better. I don't want to make it
> too easy to use.
> 
> The properties for the vendor and product ID are still something that
> we need to introduce in any case. We have the powered off problem on
> all kinds of platforms, and not all of them use DT.

I am thinking power sequence framework, how power sequence elements
(eg, clock, reset-gpios) can get for non-DT platform? Does ACPI does power
sequence for x86 platforms?

-- 

Best Regards,
Peter Chen

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

* [PATCH 02/21] usb: ulpi: Support device discovery via DT
@ 2016-06-29  1:53             ` Peter Chen
  0 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-29  1:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jun 28, 2016 at 02:42:05PM +0300, Heikki Krogerus wrote:
> On Mon, Jun 27, 2016 at 03:10:40PM -0700, Stephen Boyd wrote:
> > Quoting Heikki Krogerus (2016-06-27 07:34:22)
> > > Hi,
> > > 
> > > I'm fine with most of the patch, except..
> > > 
> > > On Sun, Jun 26, 2016 at 12:28:19AM -0700, Stephen Boyd wrote:
> > > > @@ -39,7 +42,10 @@ static int ulpi_match(struct device *dev, struct device_driver *driver)
> > > >       struct ulpi *ulpi = to_ulpi_dev(dev);
> > > >       const struct ulpi_device_id *id;
> > > >  
> > > > -     for (id = drv->id_table; id->vendor; id++)
> > > > +     if (of_driver_match_device(dev, driver))
> > > > +             return 1;
> > > 
> > > I don't like this part. We should match separately like that only
> > > if the bus does not support native enumeration, and of course ULPI
> > > with its vendor and product IDs does. There really should always be
> > > IDs to match with here. So exceptions have to be solved before we
> > > attempt matching.
> > > 
> > > Since we also have to support platforms where the PHY is initially
> > > powered off and reading the IDs from the registers is not possible
> > > because of that, I think we should consider getting the product and
> > > vendor IDs optionally from device properties. Something like this:
> > 
> > Ok, I'm a little worried about conflating the powered off problem with
> > this product/vendor ID missing problem. But if you're ok with that I'll
> > combine the two patches into one using your approach below.
> > 
> > > 
> > > 
> > > diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c
> > > index 01c0c04..6228a85 100644
> > > --- a/drivers/usb/common/ulpi.c
> > > +++ b/drivers/usb/common/ulpi.c
> > > @@ -152,7 +152,7 @@ EXPORT_SYMBOL_GPL(ulpi_unregister_driver);
> > >  
> > >  /* -------------------------------------------------------------------------- */
> > >  
> > > -static int ulpi_register(struct device *dev, struct ulpi *ulpi)
> > > +static int ulpi_read_id(struct ulpi *ulpi)
> > >  {
> > >         int ret;
> > >  
> > > @@ -174,6 +174,21 @@ static int ulpi_register(struct device *dev, struct ulpi *ulpi)
> > >         ulpi->id.product = ulpi_read(ulpi, ULPI_PRODUCT_ID_LOW);
> > >         ulpi->id.product |= ulpi_read(ulpi, ULPI_PRODUCT_ID_HIGH) << 8;
> > >  
> > > +       return 0;
> > > +}
> > > +
> > > +static int ulpi_register(struct device *dev, struct ulpi *ulpi)
> > > +{
> > > +       int ret;
> > > +
> > > +       ret = device_property_read_u16(dev, "ulpi-vendor", &ulpi->id.vendor);
> > > +       ret |= device_property_read_u16(dev, "ulpi-product", &ulpi->id.product);
> > > +       if (ret) {
> > > +               ret = ulpi_read_id(ulpi);
> > > +               if (ret)
> > > +                       return ret;
> > > +       }
> > > +
> > >         ulpi->dev.parent = dev;
> > >         ulpi->dev.bus = &ulpi_bus;
> > >         ulpi->dev.type = &ulpi_dev_type;
> > > 
> > > 
> > > That should cover both cases. You would just have to create the IDs
> > > yourself in this case.
> > > 
> > 
> > Right, I would have to make up some IDs in this case. I suppose I can
> > use the qcom vendor ID 0x05c6 and then product ids 0 and 1 for HS phy
> > and HSIC phy? That doesn't make me feel great because it's all made up,
> > but I guess there's no other option. I hope they don't decide to start
> > populating these ids in the future though and then we may have
> > conflicting product ids. If that happens I suppose we can do a
> > workaround based on compatible strings in the DT node. Fun!
> > 
> > Nice side effect of all that is I can drop requesting the module by DT
> > aliases and things become simpler. I'll try this out.
> 
> I was hoping that we could manage with product id 0 as an exception (I
> failed to consider that you have multiple PHYs to deal with). I don't
> think we can just come up with product id > 0.
> 
> I guess we should have the of_driver_match_device() call after all.
> Let's just call it conditionally, only in cases where there is no
> product ID, to make me feel a bit more better. I don't want to make it
> too easy to use.
> 
> The properties for the vendor and product ID are still something that
> we need to introduce in any case. We have the powered off problem on
> all kinds of platforms, and not all of them use DT.

I am thinking power sequence framework, how power sequence elements
(eg, clock, reset-gpios) can get for non-DT platform? Does ACPI does power
sequence for x86 platforms?

-- 

Best Regards,
Peter Chen

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

* Re: [PATCH 06/21] usb: chipidea: Initialize and reinitialize phy later
  2016-06-26  7:28   ` Stephen Boyd
@ 2016-06-29  2:30     ` Peter Chen
  -1 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-29  2:30 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, Felipe Balbi, Arnd Bergmann, Neil Armstrong,
	linux-arm-msm, linux-kernel, Bjorn Andersson, Peter Chen,
	Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

On Sun, Jun 26, 2016 at 12:28:23AM -0700, Stephen Boyd wrote:
> The ULPI phy on qcom platforms needs to be initialized and
> powered on after a USB reset and before we toggle the run/stop
> bit. Otherwise, the phy locks up and doesn't work properly.

This requirement is so strange, try to see if any other initialization
sequences.
     
Since this driver is multi-platforms, I can't accept this change for
common, if you had to do that, would you please move your changes to
msm glue layer using CI_HDRC_CONTROLLER_RESET_EVENT and
CI_HDRC_CONTROLLER_STOPPED_EVENT? Besides, you need to add one flag
at ci_hdrc_platform_data.flags for your case to avoid normal
initialization.

Peter

> Move
> the phy initialization to a later point, and shut it down outside
> of driver remove so that the phy state is properly managed across
> role switches.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/ci.h   |  3 ++-
>  drivers/usb/chipidea/core.c | 23 ++++++++++-------------
>  drivers/usb/chipidea/host.c |  5 ++---
>  drivers/usb/chipidea/udc.c  |  2 ++
>  4 files changed, 16 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
> index cd414559040f..f87805235caa 100644
> --- a/drivers/usb/chipidea/ci.h
> +++ b/drivers/usb/chipidea/ci.h
> @@ -431,7 +431,8 @@ u8 hw_port_test_get(struct ci_hdrc *ci);
>  int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
>  				u32 value, unsigned int timeout_ms);
>  
> -void ci_platform_configure(struct ci_hdrc *ci);
> +void ci_usb_phy_exit(struct ci_hdrc *ci);
> +int ci_platform_configure(struct ci_hdrc *ci);
>  
>  int dbg_create_files(struct ci_hdrc *ci);
>  
> diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
> index 01390e02ee53..a01611c7f815 100644
> --- a/drivers/usb/chipidea/core.c
> +++ b/drivers/usb/chipidea/core.c
> @@ -359,7 +359,7 @@ static int _ci_usb_phy_init(struct ci_hdrc *ci)
>   * interfaces
>   * @ci: the controller
>   */
> -static void ci_usb_phy_exit(struct ci_hdrc *ci)
> +void ci_usb_phy_exit(struct ci_hdrc *ci)
>  {
>  	if (ci->phy) {
>  		phy_power_off(ci->phy);
> @@ -412,9 +412,14 @@ static int ci_usb_phy_init(struct ci_hdrc *ci)
>   * @ci: the controller
>   *
>   */
> -void ci_platform_configure(struct ci_hdrc *ci)
> +int ci_platform_configure(struct ci_hdrc *ci)
>  {
>  	bool is_device_mode, is_host_mode;
> +	int ret;
> +
> +	ret = ci_usb_phy_init(ci);
> +	if (ret)
> +		return ret;
>  
>  	is_device_mode = hw_read(ci, OP_USBMODE, USBMODE_CM) == USBMODE_CM_DC;
>  	is_host_mode = hw_read(ci, OP_USBMODE, USBMODE_CM) == USBMODE_CM_HC;
> @@ -453,6 +458,8 @@ void ci_platform_configure(struct ci_hdrc *ci)
>  			hw_write(ci, OP_BURSTSIZE, RX_BURST_MASK,
>  				ci->platdata->rx_burst_size);
>  	}
> +
> +	return 0;
>  }
>  
>  /**
> @@ -511,9 +518,7 @@ int hw_device_reset(struct ci_hdrc *ci)
>  		return -ENODEV;
>  	}
>  
> -	ci_platform_configure(ci);
> -
> -	return 0;
> +	return ci_platform_configure(ci);
>  }
>  
>  static irqreturn_t ci_irq(int irq, void *data)
> @@ -917,12 +922,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
>  			ci->usb_phy = NULL;
>  	}
>  
> -	ret = ci_usb_phy_init(ci);
> -	if (ret) {
> -		dev_err(dev, "unable to init phy: %d\n", ret);
> -		return ret;
> -	}
> -
>  	ci->hw_bank.phys = res->start;
>  
>  	ci->irq = platform_get_irq(pdev, 0);
> @@ -1025,7 +1024,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
>  stop:
>  	ci_role_destroy(ci);
>  deinit_phy:
> -	ci_usb_phy_exit(ci);
>  
>  	return ret;
>  }
> @@ -1044,7 +1042,6 @@ static int ci_hdrc_remove(struct platform_device *pdev)
>  	ci_extcon_unregister(ci);
>  	ci_role_destroy(ci);
>  	ci_hdrc_enter_lpm(ci, true);
> -	ci_usb_phy_exit(ci);
>  
>  	return 0;
>  }
> diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
> index 053bac9d983c..523c155daea8 100644
> --- a/drivers/usb/chipidea/host.c
> +++ b/drivers/usb/chipidea/host.c
> @@ -87,9 +87,7 @@ static int ehci_ci_reset(struct usb_hcd *hcd)
>  	if (ret)
>  		return ret;
>  
> -	ci_platform_configure(ci);
> -
> -	return ret;
> +	return ci_platform_configure(ci);
>  }
>  
>  static const struct ehci_driver_overrides ehci_ci_overrides = {
> @@ -186,6 +184,7 @@ static void host_stop(struct ci_hdrc *ci)
>  	if (hcd) {
>  		usb_remove_hcd(hcd);
>  		usb_put_hcd(hcd);
> +		ci_usb_phy_exit(ci);
>  		if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci) &&
>  			(ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON))
>  				regulator_disable(ci->platdata->reg_vbus);
> diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
> index 065f5d97aa67..8f44e2d1e0c0 100644
> --- a/drivers/usb/chipidea/udc.c
> +++ b/drivers/usb/chipidea/udc.c
> @@ -1534,6 +1534,7 @@ static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active)
>  			if (ci->driver)
>  				ci->driver->disconnect(&ci->gadget);
>  			hw_device_state(ci, 0);
> +			ci_usb_phy_exit(ci);
>  			if (ci->platdata->notify_event)
>  				ci->platdata->notify_event(ci,
>  				CI_HDRC_CONTROLLER_STOPPED_EVENT);
> @@ -1794,6 +1795,7 @@ static int ci_udc_stop(struct usb_gadget *gadget)
>  			ci->platdata->notify_event(ci,
>  			CI_HDRC_CONTROLLER_STOPPED_EVENT);
>  		spin_unlock_irqrestore(&ci->lock, flags);
> +		ci_usb_phy_exit(ci);
>  		_gadget_stop_activity(&ci->gadget);
>  		spin_lock_irqsave(&ci->lock, flags);
>  		pm_runtime_put(&ci->gadget.dev);
> -- 
> 2.9.0.rc2.8.ga28705d
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 

Best Regards,
Peter Chen

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

* [PATCH 06/21] usb: chipidea: Initialize and reinitialize phy later
@ 2016-06-29  2:30     ` Peter Chen
  0 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-29  2:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Jun 26, 2016 at 12:28:23AM -0700, Stephen Boyd wrote:
> The ULPI phy on qcom platforms needs to be initialized and
> powered on after a USB reset and before we toggle the run/stop
> bit. Otherwise, the phy locks up and doesn't work properly.

This requirement is so strange, try to see if any other initialization
sequences.
     
Since this driver is multi-platforms, I can't accept this change for
common, if you had to do that, would you please move your changes to
msm glue layer using CI_HDRC_CONTROLLER_RESET_EVENT and
CI_HDRC_CONTROLLER_STOPPED_EVENT? Besides, you need to add one flag
at ci_hdrc_platform_data.flags for your case to avoid normal
initialization.

Peter

> Move
> the phy initialization to a later point, and shut it down outside
> of driver remove so that the phy state is properly managed across
> role switches.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/ci.h   |  3 ++-
>  drivers/usb/chipidea/core.c | 23 ++++++++++-------------
>  drivers/usb/chipidea/host.c |  5 ++---
>  drivers/usb/chipidea/udc.c  |  2 ++
>  4 files changed, 16 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
> index cd414559040f..f87805235caa 100644
> --- a/drivers/usb/chipidea/ci.h
> +++ b/drivers/usb/chipidea/ci.h
> @@ -431,7 +431,8 @@ u8 hw_port_test_get(struct ci_hdrc *ci);
>  int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
>  				u32 value, unsigned int timeout_ms);
>  
> -void ci_platform_configure(struct ci_hdrc *ci);
> +void ci_usb_phy_exit(struct ci_hdrc *ci);
> +int ci_platform_configure(struct ci_hdrc *ci);
>  
>  int dbg_create_files(struct ci_hdrc *ci);
>  
> diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
> index 01390e02ee53..a01611c7f815 100644
> --- a/drivers/usb/chipidea/core.c
> +++ b/drivers/usb/chipidea/core.c
> @@ -359,7 +359,7 @@ static int _ci_usb_phy_init(struct ci_hdrc *ci)
>   * interfaces
>   * @ci: the controller
>   */
> -static void ci_usb_phy_exit(struct ci_hdrc *ci)
> +void ci_usb_phy_exit(struct ci_hdrc *ci)
>  {
>  	if (ci->phy) {
>  		phy_power_off(ci->phy);
> @@ -412,9 +412,14 @@ static int ci_usb_phy_init(struct ci_hdrc *ci)
>   * @ci: the controller
>   *
>   */
> -void ci_platform_configure(struct ci_hdrc *ci)
> +int ci_platform_configure(struct ci_hdrc *ci)
>  {
>  	bool is_device_mode, is_host_mode;
> +	int ret;
> +
> +	ret = ci_usb_phy_init(ci);
> +	if (ret)
> +		return ret;
>  
>  	is_device_mode = hw_read(ci, OP_USBMODE, USBMODE_CM) == USBMODE_CM_DC;
>  	is_host_mode = hw_read(ci, OP_USBMODE, USBMODE_CM) == USBMODE_CM_HC;
> @@ -453,6 +458,8 @@ void ci_platform_configure(struct ci_hdrc *ci)
>  			hw_write(ci, OP_BURSTSIZE, RX_BURST_MASK,
>  				ci->platdata->rx_burst_size);
>  	}
> +
> +	return 0;
>  }
>  
>  /**
> @@ -511,9 +518,7 @@ int hw_device_reset(struct ci_hdrc *ci)
>  		return -ENODEV;
>  	}
>  
> -	ci_platform_configure(ci);
> -
> -	return 0;
> +	return ci_platform_configure(ci);
>  }
>  
>  static irqreturn_t ci_irq(int irq, void *data)
> @@ -917,12 +922,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
>  			ci->usb_phy = NULL;
>  	}
>  
> -	ret = ci_usb_phy_init(ci);
> -	if (ret) {
> -		dev_err(dev, "unable to init phy: %d\n", ret);
> -		return ret;
> -	}
> -
>  	ci->hw_bank.phys = res->start;
>  
>  	ci->irq = platform_get_irq(pdev, 0);
> @@ -1025,7 +1024,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
>  stop:
>  	ci_role_destroy(ci);
>  deinit_phy:
> -	ci_usb_phy_exit(ci);
>  
>  	return ret;
>  }
> @@ -1044,7 +1042,6 @@ static int ci_hdrc_remove(struct platform_device *pdev)
>  	ci_extcon_unregister(ci);
>  	ci_role_destroy(ci);
>  	ci_hdrc_enter_lpm(ci, true);
> -	ci_usb_phy_exit(ci);
>  
>  	return 0;
>  }
> diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
> index 053bac9d983c..523c155daea8 100644
> --- a/drivers/usb/chipidea/host.c
> +++ b/drivers/usb/chipidea/host.c
> @@ -87,9 +87,7 @@ static int ehci_ci_reset(struct usb_hcd *hcd)
>  	if (ret)
>  		return ret;
>  
> -	ci_platform_configure(ci);
> -
> -	return ret;
> +	return ci_platform_configure(ci);
>  }
>  
>  static const struct ehci_driver_overrides ehci_ci_overrides = {
> @@ -186,6 +184,7 @@ static void host_stop(struct ci_hdrc *ci)
>  	if (hcd) {
>  		usb_remove_hcd(hcd);
>  		usb_put_hcd(hcd);
> +		ci_usb_phy_exit(ci);
>  		if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci) &&
>  			(ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON))
>  				regulator_disable(ci->platdata->reg_vbus);
> diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
> index 065f5d97aa67..8f44e2d1e0c0 100644
> --- a/drivers/usb/chipidea/udc.c
> +++ b/drivers/usb/chipidea/udc.c
> @@ -1534,6 +1534,7 @@ static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active)
>  			if (ci->driver)
>  				ci->driver->disconnect(&ci->gadget);
>  			hw_device_state(ci, 0);
> +			ci_usb_phy_exit(ci);
>  			if (ci->platdata->notify_event)
>  				ci->platdata->notify_event(ci,
>  				CI_HDRC_CONTROLLER_STOPPED_EVENT);
> @@ -1794,6 +1795,7 @@ static int ci_udc_stop(struct usb_gadget *gadget)
>  			ci->platdata->notify_event(ci,
>  			CI_HDRC_CONTROLLER_STOPPED_EVENT);
>  		spin_unlock_irqrestore(&ci->lock, flags);
> +		ci_usb_phy_exit(ci);
>  		_gadget_stop_activity(&ci->gadget);
>  		spin_lock_irqsave(&ci->lock, flags);
>  		pm_runtime_put(&ci->gadget.dev);
> -- 
> 2.9.0.rc2.8.ga28705d
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 

Best Regards,
Peter Chen

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

* Re: [PATCH 08/21] usb: chipidea: Kick OTG state machine for AVVIS with vbus extcon
  2016-06-26  7:28   ` Stephen Boyd
  (?)
@ 2016-06-29  3:09       ` Peter Chen
  -1 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-29  3:09 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA, Andy Gross,
	Bjorn Andersson, Neil Armstrong, Arnd Bergmann, Felipe Balbi,
	Peter Chen, Greg Kroah-Hartman

On Sun, Jun 26, 2016 at 12:28:25AM -0700, Stephen Boyd wrote:
> Force the OTG state machine to go forward when we're using an
> extcon for vbus detection. In this case, the controller may never
> raise an interrupt for AVVIS, so we need to simulate the event by
> toggling the appropriate OTG fsm bits and kicking the state
> machine again.
> 

Well, I think you may misunderstand the OTG FSM and dual-role.
>From my and Felipe's point, there are seldom users for USB FSM,
there are only OTG FSM spec and related OTG certification.

The OTG FSM needs related SoC support, the vbus will be off at
several states, and the SRP should be supported by SoC.

By default, the dts needs below properties for disabling it if you
choose otg fsm support at kernel configuration.

&usbotg1 {
	vbus-supply = <&reg_usb_otg1_vbus>;
	srp-disable;
	hnp-disable;
	adp-disable;
	status = "okay";
};

See Documentation/devicetree/bindings/usb/generic.txt.

Peter

> Cc: Peter Chen <peter.chen-3arQi8VN3Tc@public.gmane.org>
> Cc: Greg Kroah-Hartman <gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org>
> Signed-off-by: Stephen Boyd <stephen.boyd-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> ---
>  drivers/usb/chipidea/otg_fsm.c | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
> 
> diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c
> index de8e22ec3902..aab076fc4d82 100644
> --- a/drivers/usb/chipidea/otg_fsm.c
> +++ b/drivers/usb/chipidea/otg_fsm.c
> @@ -475,6 +475,14 @@ static void ci_otg_drv_vbus(struct otg_fsm *fsm, int on)
>  				return;
>  			}
>  		}
> +		/*
> +		 * Force state machine forward if we use extcon
> +		 * to detect vbus state (i.e. simulate AVVIS event)
> +		 */
> +		if (!IS_ERR(ci->platdata->vbus_extcon.edev)) {
> +			fsm->a_vbus_vld = 1;
> +			ci_otg_queue_work(ci);
> +		}
>  		/* Disable data pulse irq */
>  		hw_write_otgsc(ci, OTGSC_DPIE, 0);
>  
> @@ -486,6 +494,15 @@ static void ci_otg_drv_vbus(struct otg_fsm *fsm, int on)
>  
>  		fsm->a_bus_drop = 1;
>  		fsm->a_bus_req = 0;
> +		/*
> +		 * Force state machine forward if we use extcon
> +		 * to detect vbus state (i.e. simulate AVVIS event)
> +		 */
> +		if (!IS_ERR(ci->platdata->vbus_extcon.edev)) {
> +			fsm->a_vbus_vld = 0;
> +			fsm->b_conn = 0;
> +			ci_otg_queue_work(ci);
> +		}
>  	}
>  }
>  
> -- 
> 2.9.0.rc2.8.ga28705d
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 

Best Regards,
Peter Chen
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 08/21] usb: chipidea: Kick OTG state machine for AVVIS with vbus extcon
@ 2016-06-29  3:09       ` Peter Chen
  0 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-29  3:09 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, linux-arm-kernel, linux-kernel, linux-arm-msm,
	Andy Gross, Bjorn Andersson, Neil Armstrong, Arnd Bergmann,
	Felipe Balbi, Peter Chen, Greg Kroah-Hartman

On Sun, Jun 26, 2016 at 12:28:25AM -0700, Stephen Boyd wrote:
> Force the OTG state machine to go forward when we're using an
> extcon for vbus detection. In this case, the controller may never
> raise an interrupt for AVVIS, so we need to simulate the event by
> toggling the appropriate OTG fsm bits and kicking the state
> machine again.
> 

Well, I think you may misunderstand the OTG FSM and dual-role.
>From my and Felipe's point, there are seldom users for USB FSM,
there are only OTG FSM spec and related OTG certification.

The OTG FSM needs related SoC support, the vbus will be off at
several states, and the SRP should be supported by SoC.

By default, the dts needs below properties for disabling it if you
choose otg fsm support at kernel configuration.

&usbotg1 {
	vbus-supply = <&reg_usb_otg1_vbus>;
	srp-disable;
	hnp-disable;
	adp-disable;
	status = "okay";
};

See Documentation/devicetree/bindings/usb/generic.txt.

Peter

> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/otg_fsm.c | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
> 
> diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c
> index de8e22ec3902..aab076fc4d82 100644
> --- a/drivers/usb/chipidea/otg_fsm.c
> +++ b/drivers/usb/chipidea/otg_fsm.c
> @@ -475,6 +475,14 @@ static void ci_otg_drv_vbus(struct otg_fsm *fsm, int on)
>  				return;
>  			}
>  		}
> +		/*
> +		 * Force state machine forward if we use extcon
> +		 * to detect vbus state (i.e. simulate AVVIS event)
> +		 */
> +		if (!IS_ERR(ci->platdata->vbus_extcon.edev)) {
> +			fsm->a_vbus_vld = 1;
> +			ci_otg_queue_work(ci);
> +		}
>  		/* Disable data pulse irq */
>  		hw_write_otgsc(ci, OTGSC_DPIE, 0);
>  
> @@ -486,6 +494,15 @@ static void ci_otg_drv_vbus(struct otg_fsm *fsm, int on)
>  
>  		fsm->a_bus_drop = 1;
>  		fsm->a_bus_req = 0;
> +		/*
> +		 * Force state machine forward if we use extcon
> +		 * to detect vbus state (i.e. simulate AVVIS event)
> +		 */
> +		if (!IS_ERR(ci->platdata->vbus_extcon.edev)) {
> +			fsm->a_vbus_vld = 0;
> +			fsm->b_conn = 0;
> +			ci_otg_queue_work(ci);
> +		}
>  	}
>  }
>  
> -- 
> 2.9.0.rc2.8.ga28705d
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 

Best Regards,
Peter Chen

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

* [PATCH 08/21] usb: chipidea: Kick OTG state machine for AVVIS with vbus extcon
@ 2016-06-29  3:09       ` Peter Chen
  0 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-29  3:09 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Jun 26, 2016 at 12:28:25AM -0700, Stephen Boyd wrote:
> Force the OTG state machine to go forward when we're using an
> extcon for vbus detection. In this case, the controller may never
> raise an interrupt for AVVIS, so we need to simulate the event by
> toggling the appropriate OTG fsm bits and kicking the state
> machine again.
> 

Well, I think you may misunderstand the OTG FSM and dual-role.
>From my and Felipe's point, there are seldom users for USB FSM,
there are only OTG FSM spec and related OTG certification.

The OTG FSM needs related SoC support, the vbus will be off at
several states, and the SRP should be supported by SoC.

By default, the dts needs below properties for disabling it if you
choose otg fsm support at kernel configuration.

&usbotg1 {
	vbus-supply = <&reg_usb_otg1_vbus>;
	srp-disable;
	hnp-disable;
	adp-disable;
	status = "okay";
};

See Documentation/devicetree/bindings/usb/generic.txt.

Peter

> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/otg_fsm.c | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
> 
> diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c
> index de8e22ec3902..aab076fc4d82 100644
> --- a/drivers/usb/chipidea/otg_fsm.c
> +++ b/drivers/usb/chipidea/otg_fsm.c
> @@ -475,6 +475,14 @@ static void ci_otg_drv_vbus(struct otg_fsm *fsm, int on)
>  				return;
>  			}
>  		}
> +		/*
> +		 * Force state machine forward if we use extcon
> +		 * to detect vbus state (i.e. simulate AVVIS event)
> +		 */
> +		if (!IS_ERR(ci->platdata->vbus_extcon.edev)) {
> +			fsm->a_vbus_vld = 1;
> +			ci_otg_queue_work(ci);
> +		}
>  		/* Disable data pulse irq */
>  		hw_write_otgsc(ci, OTGSC_DPIE, 0);
>  
> @@ -486,6 +494,15 @@ static void ci_otg_drv_vbus(struct otg_fsm *fsm, int on)
>  
>  		fsm->a_bus_drop = 1;
>  		fsm->a_bus_req = 0;
> +		/*
> +		 * Force state machine forward if we use extcon
> +		 * to detect vbus state (i.e. simulate AVVIS event)
> +		 */
> +		if (!IS_ERR(ci->platdata->vbus_extcon.edev)) {
> +			fsm->a_vbus_vld = 0;
> +			fsm->b_conn = 0;
> +			ci_otg_queue_work(ci);
> +		}
>  	}
>  }
>  
> -- 
> 2.9.0.rc2.8.ga28705d
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 

Best Regards,
Peter Chen

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

* Re: [PATCH 09/21] usb: chipidea: Add support for ULPI PHY bus
  2016-06-26  7:28   ` Stephen Boyd
@ 2016-06-29  6:26     ` Peter Chen
  -1 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-29  6:26 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, linux-arm-kernel, linux-kernel, linux-arm-msm,
	Andy Gross, Bjorn Andersson, Neil Armstrong, Arnd Bergmann,
	Felipe Balbi, Peter Chen, Greg Kroah-Hartman, Heikki Krogerus

On Sun, Jun 26, 2016 at 12:28:26AM -0700, Stephen Boyd wrote:
> Some phys for the chipidea controller are controlled via the ULPI
> viewport. Add support for the ULPI bus so that these sorts of
> phys can be probed and read/written automatically without having
> to duplicate the viewport logic in each phy driver.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/Kconfig  |   7 +++
>  drivers/usb/chipidea/Makefile |   1 +
>  drivers/usb/chipidea/ci.h     |  20 ++++++++
>  drivers/usb/chipidea/core.c   |  30 ++++++++---
>  drivers/usb/chipidea/ulpi.c   | 113 ++++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 165 insertions(+), 6 deletions(-)
>  create mode 100644 drivers/usb/chipidea/ulpi.c
> 
> diff --git a/drivers/usb/chipidea/Kconfig b/drivers/usb/chipidea/Kconfig
> index 3644a3500b70..4f8c342a8865 100644
> --- a/drivers/usb/chipidea/Kconfig
> +++ b/drivers/usb/chipidea/Kconfig
> @@ -37,4 +37,11 @@ config USB_CHIPIDEA_HOST
>  	  Say Y here to enable host controller functionality of the
>  	  ChipIdea driver.
>  
> +config USB_CHIPIDEA_ULPI
> +	bool "ChipIdea ULPI PHY support"
> +	depends on USB_ULPI_BUS=y || USB_ULPI_BUS=USB_CHIPIDEA
> +	help
> +	  Say Y here if you have a ULPI PHY attached to your ChipIdea
> +	  controller.
> +
>  endif
> diff --git a/drivers/usb/chipidea/Makefile b/drivers/usb/chipidea/Makefile
> index 518e445476c3..39fca5715ed3 100644
> --- a/drivers/usb/chipidea/Makefile
> +++ b/drivers/usb/chipidea/Makefile
> @@ -4,6 +4,7 @@ ci_hdrc-y				:= core.o otg.o debug.o
>  ci_hdrc-$(CONFIG_USB_CHIPIDEA_UDC)	+= udc.o
>  ci_hdrc-$(CONFIG_USB_CHIPIDEA_HOST)	+= host.o
>  ci_hdrc-$(CONFIG_USB_OTG_FSM)		+= otg_fsm.o
> +ci_hdrc-$(CONFIG_USB_CHIPIDEA_ULPI)	+= ulpi.o
>  
>  # Glue/Bridge layers go here
>  
> diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
> index f87805235caa..14aa20525547 100644
> --- a/drivers/usb/chipidea/ci.h
> +++ b/drivers/usb/chipidea/ci.h
> @@ -18,6 +18,8 @@
>  #include <linux/usb.h>
>  #include <linux/usb/gadget.h>
>  #include <linux/usb/otg-fsm.h>
> +#include <linux/usb/otg.h>
> +#include <linux/ulpi/interface.h>
>  
>  /******************************************************************************
>   * DEFINE
> @@ -52,6 +54,7 @@ enum ci_hw_regs {
>  	OP_ENDPTLISTADDR,
>  	OP_TTCTRL,
>  	OP_BURSTSIZE,
> +	OP_ULPI_VIEWPORT,
>  	OP_PORTSC,
>  	OP_DEVLC,
>  	OP_OTGSC,
> @@ -187,6 +190,7 @@ struct hw_bank {
>   * @test_mode: the selected test mode
>   * @platdata: platform specific information supplied by parent device
>   * @vbus_active: is VBUS active
> + * @ulpi: pointer to ULPI device, if any

One more kernel-doc

>   * @phy: pointer to PHY, if any
>   * @usb_phy: pointer to USB PHY, if any and if using the USB PHY framework
>   * @hcd: pointer to usb_hcd for ehci host driver
> @@ -236,6 +240,10 @@ struct ci_hdrc {
>  
>  	struct ci_hdrc_platform_data	*platdata;
>  	int				vbus_active;
> +#ifdef CONFIG_USB_CHIPIDEA_ULPI
> +	struct ulpi			*ulpi;
> +	struct ulpi_ops 		ulpi_ops;
> +#endif
>  	struct phy			*phy;
>  	/* old usb_phy interface */
>  	struct usb_phy			*usb_phy;
> @@ -418,6 +426,17 @@ static inline bool ci_otg_is_fsm_mode(struct ci_hdrc *ci)
>  #endif
>  }
>  

Others are ok, but I can't accept you change current PHY initialization
at your previous patch, so you may need to refine this patch a little.

-- 

Best Regards,
Peter Chen

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

* [PATCH 09/21] usb: chipidea: Add support for ULPI PHY bus
@ 2016-06-29  6:26     ` Peter Chen
  0 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-29  6:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Jun 26, 2016 at 12:28:26AM -0700, Stephen Boyd wrote:
> Some phys for the chipidea controller are controlled via the ULPI
> viewport. Add support for the ULPI bus so that these sorts of
> phys can be probed and read/written automatically without having
> to duplicate the viewport logic in each phy driver.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/Kconfig  |   7 +++
>  drivers/usb/chipidea/Makefile |   1 +
>  drivers/usb/chipidea/ci.h     |  20 ++++++++
>  drivers/usb/chipidea/core.c   |  30 ++++++++---
>  drivers/usb/chipidea/ulpi.c   | 113 ++++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 165 insertions(+), 6 deletions(-)
>  create mode 100644 drivers/usb/chipidea/ulpi.c
> 
> diff --git a/drivers/usb/chipidea/Kconfig b/drivers/usb/chipidea/Kconfig
> index 3644a3500b70..4f8c342a8865 100644
> --- a/drivers/usb/chipidea/Kconfig
> +++ b/drivers/usb/chipidea/Kconfig
> @@ -37,4 +37,11 @@ config USB_CHIPIDEA_HOST
>  	  Say Y here to enable host controller functionality of the
>  	  ChipIdea driver.
>  
> +config USB_CHIPIDEA_ULPI
> +	bool "ChipIdea ULPI PHY support"
> +	depends on USB_ULPI_BUS=y || USB_ULPI_BUS=USB_CHIPIDEA
> +	help
> +	  Say Y here if you have a ULPI PHY attached to your ChipIdea
> +	  controller.
> +
>  endif
> diff --git a/drivers/usb/chipidea/Makefile b/drivers/usb/chipidea/Makefile
> index 518e445476c3..39fca5715ed3 100644
> --- a/drivers/usb/chipidea/Makefile
> +++ b/drivers/usb/chipidea/Makefile
> @@ -4,6 +4,7 @@ ci_hdrc-y				:= core.o otg.o debug.o
>  ci_hdrc-$(CONFIG_USB_CHIPIDEA_UDC)	+= udc.o
>  ci_hdrc-$(CONFIG_USB_CHIPIDEA_HOST)	+= host.o
>  ci_hdrc-$(CONFIG_USB_OTG_FSM)		+= otg_fsm.o
> +ci_hdrc-$(CONFIG_USB_CHIPIDEA_ULPI)	+= ulpi.o
>  
>  # Glue/Bridge layers go here
>  
> diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
> index f87805235caa..14aa20525547 100644
> --- a/drivers/usb/chipidea/ci.h
> +++ b/drivers/usb/chipidea/ci.h
> @@ -18,6 +18,8 @@
>  #include <linux/usb.h>
>  #include <linux/usb/gadget.h>
>  #include <linux/usb/otg-fsm.h>
> +#include <linux/usb/otg.h>
> +#include <linux/ulpi/interface.h>
>  
>  /******************************************************************************
>   * DEFINE
> @@ -52,6 +54,7 @@ enum ci_hw_regs {
>  	OP_ENDPTLISTADDR,
>  	OP_TTCTRL,
>  	OP_BURSTSIZE,
> +	OP_ULPI_VIEWPORT,
>  	OP_PORTSC,
>  	OP_DEVLC,
>  	OP_OTGSC,
> @@ -187,6 +190,7 @@ struct hw_bank {
>   * @test_mode: the selected test mode
>   * @platdata: platform specific information supplied by parent device
>   * @vbus_active: is VBUS active
> + * @ulpi: pointer to ULPI device, if any

One more kernel-doc

>   * @phy: pointer to PHY, if any
>   * @usb_phy: pointer to USB PHY, if any and if using the USB PHY framework
>   * @hcd: pointer to usb_hcd for ehci host driver
> @@ -236,6 +240,10 @@ struct ci_hdrc {
>  
>  	struct ci_hdrc_platform_data	*platdata;
>  	int				vbus_active;
> +#ifdef CONFIG_USB_CHIPIDEA_ULPI
> +	struct ulpi			*ulpi;
> +	struct ulpi_ops 		ulpi_ops;
> +#endif
>  	struct phy			*phy;
>  	/* old usb_phy interface */
>  	struct usb_phy			*usb_phy;
> @@ -418,6 +426,17 @@ static inline bool ci_otg_is_fsm_mode(struct ci_hdrc *ci)
>  #endif
>  }
>  

Others are ok, but I can't accept you change current PHY initialization
at your previous patch, so you may need to refine this patch a little.

-- 

Best Regards,
Peter Chen

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

* Re: [PATCH 10/21] usb: chipidea: msm: Rely on core to override AHBBURST
  2016-06-26  7:28   ` Stephen Boyd
@ 2016-06-29  6:32     ` Peter Chen
  -1 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-29  6:32 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, linux-arm-kernel, linux-kernel, linux-arm-msm,
	Andy Gross, Bjorn Andersson, Neil Armstrong, Arnd Bergmann,
	Felipe Balbi, Peter Chen, Greg Kroah-Hartman

On Sun, Jun 26, 2016 at 12:28:27AM -0700, Stephen Boyd wrote:
> The core framework already handles setting this parameter with a
> platform quirk. Add the appropriate flag so that we always set
> AHBBURST to 0. Technically DT should be doing this, but we always
> do it for msm chipidea devices so setting the flag in the driver
> works just as well.

You still need to set AHB burst value at dts, this flag is just for
override, see below:

ahb-burst-config = <0x0>;

> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/ci_hdrc_msm.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> index 3889809fd0c4..37591a4b1346 100644
> --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> @@ -24,7 +24,6 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
>  	switch (event) {
>  	case CI_HDRC_CONTROLLER_RESET_EVENT:
>  		dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
> -		writel(0, USB_AHBBURST);
>  		/* use AHB transactor, allow posted data writes */
>  		writel(0x8, USB_AHBMODE);
>  		usb_phy_init(ci->usb_phy);
> @@ -47,7 +46,8 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
>  	.name			= "ci_hdrc_msm",
>  	.capoffset		= DEF_CAPOFFSET,
>  	.flags			= CI_HDRC_REGS_SHARED |
> -				  CI_HDRC_DISABLE_STREAMING,
> +				  CI_HDRC_DISABLE_STREAMING |
> +				  CI_HDRC_OVERRIDE_AHB_BURST,
>  
>  	.notify_event		= ci_hdrc_msm_notify_event,
>  };
> -- 
> 2.9.0.rc2.8.ga28705d
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 

Best Regards,
Peter Chen

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

* [PATCH 10/21] usb: chipidea: msm: Rely on core to override AHBBURST
@ 2016-06-29  6:32     ` Peter Chen
  0 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-29  6:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Jun 26, 2016 at 12:28:27AM -0700, Stephen Boyd wrote:
> The core framework already handles setting this parameter with a
> platform quirk. Add the appropriate flag so that we always set
> AHBBURST to 0. Technically DT should be doing this, but we always
> do it for msm chipidea devices so setting the flag in the driver
> works just as well.

You still need to set AHB burst value at dts, this flag is just for
override, see below:

ahb-burst-config = <0x0>;

> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/ci_hdrc_msm.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> index 3889809fd0c4..37591a4b1346 100644
> --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> @@ -24,7 +24,6 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
>  	switch (event) {
>  	case CI_HDRC_CONTROLLER_RESET_EVENT:
>  		dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
> -		writel(0, USB_AHBBURST);
>  		/* use AHB transactor, allow posted data writes */
>  		writel(0x8, USB_AHBMODE);
>  		usb_phy_init(ci->usb_phy);
> @@ -47,7 +46,8 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
>  	.name			= "ci_hdrc_msm",
>  	.capoffset		= DEF_CAPOFFSET,
>  	.flags			= CI_HDRC_REGS_SHARED |
> -				  CI_HDRC_DISABLE_STREAMING,
> +				  CI_HDRC_DISABLE_STREAMING |
> +				  CI_HDRC_OVERRIDE_AHB_BURST,
>  
>  	.notify_event		= ci_hdrc_msm_notify_event,
>  };
> -- 
> 2.9.0.rc2.8.ga28705d
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 

Best Regards,
Peter Chen

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

* Re: [PATCH 11/21] usb: chipidea: msm: Use hw_write_id_reg() instead of writel directly
  2016-06-26  7:28   ` Stephen Boyd
@ 2016-06-29  6:37     ` Peter Chen
  -1 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-29  6:37 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, Felipe Balbi, Arnd Bergmann, Neil Armstrong,
	linux-arm-msm, linux-kernel, Bjorn Andersson, Peter Chen,
	Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

On Sun, Jun 26, 2016 at 12:28:28AM -0700, Stephen Boyd wrote:
> The MSM_USB_BASE macro trick is not very clear, and we're using
> it for only one register write so let's just move to using
> hw_write_id_reg() and passing the ci pointer instead. That
> clearly shows what offset we're using and avoids needing to
> include the msm_hsusb_hw.h file when we're going to delete that
> file soon.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/ci_hdrc_msm.c | 6 ++----
>  1 file changed, 2 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> index 37591a4b1346..520c85e701ef 100644
> --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> @@ -8,14 +8,12 @@
>  #include <linux/module.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_runtime.h>
> -#include <linux/usb/msm_hsusb_hw.h>
> -#include <linux/usb/ulpi.h>
>  #include <linux/usb/gadget.h>
>  #include <linux/usb/chipidea.h>
>  
>  #include "ci.h"
>  
> -#define MSM_USB_BASE	(ci->hw_bank.abs)
> +#define HS_PHY_AHB_MODE			0x0098
>  
>  static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
>  {
> @@ -25,7 +23,7 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
>  	case CI_HDRC_CONTROLLER_RESET_EVENT:
>  		dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
>  		/* use AHB transactor, allow posted data writes */
> -		writel(0x8, USB_AHBMODE);
> +		hw_write_id_reg(ci, HS_PHY_AHB_MODE, 0xffffffff, 0x8);
>  		usb_phy_init(ci->usb_phy);
>  		break;
>  	case CI_HDRC_CONTROLLER_STOPPED_EVENT:
> -- 

Acked-by: Peter Chen <peter.chen@nxp.com>

-- 

Best Regards,
Peter Chen

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

* [PATCH 11/21] usb: chipidea: msm: Use hw_write_id_reg() instead of writel directly
@ 2016-06-29  6:37     ` Peter Chen
  0 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-29  6:37 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Jun 26, 2016 at 12:28:28AM -0700, Stephen Boyd wrote:
> The MSM_USB_BASE macro trick is not very clear, and we're using
> it for only one register write so let's just move to using
> hw_write_id_reg() and passing the ci pointer instead. That
> clearly shows what offset we're using and avoids needing to
> include the msm_hsusb_hw.h file when we're going to delete that
> file soon.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/ci_hdrc_msm.c | 6 ++----
>  1 file changed, 2 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> index 37591a4b1346..520c85e701ef 100644
> --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> @@ -8,14 +8,12 @@
>  #include <linux/module.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_runtime.h>
> -#include <linux/usb/msm_hsusb_hw.h>
> -#include <linux/usb/ulpi.h>
>  #include <linux/usb/gadget.h>
>  #include <linux/usb/chipidea.h>
>  
>  #include "ci.h"
>  
> -#define MSM_USB_BASE	(ci->hw_bank.abs)
> +#define HS_PHY_AHB_MODE			0x0098
>  
>  static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
>  {
> @@ -25,7 +23,7 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
>  	case CI_HDRC_CONTROLLER_RESET_EVENT:
>  		dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
>  		/* use AHB transactor, allow posted data writes */
> -		writel(0x8, USB_AHBMODE);
> +		hw_write_id_reg(ci, HS_PHY_AHB_MODE, 0xffffffff, 0x8);
>  		usb_phy_init(ci->usb_phy);
>  		break;
>  	case CI_HDRC_CONTROLLER_STOPPED_EVENT:
> -- 

Acked-by: Peter Chen <peter.chen@nxp.com>

-- 

Best Regards,
Peter Chen

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

* Re: [PATCH 12/21] usb: chipidea: msm: Keep device runtime enabled
  2016-06-26  7:28   ` Stephen Boyd
@ 2016-06-29  6:46     ` Peter Chen
  -1 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-29  6:46 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, linux-arm-kernel, linux-kernel, linux-arm-msm,
	Andy Gross, Bjorn Andersson, Neil Armstrong, Arnd Bergmann,
	Felipe Balbi, Peter Chen, Greg Kroah-Hartman

On Sun, Jun 26, 2016 at 12:28:29AM -0700, Stephen Boyd wrote:
> Sometimes the usb wrapper device is part of a power domain that
> needs to stay on as long as the device is active. Let's get and
> put the device in driver probe/remove so that we keep the power
> domain powered as long as the device is attached. We can fine
> tune this later to handle wakeup interrupts, etc. for finer grain
> power management later, but this is necessary to make sure we can
> keep accessing the device right now.

Since some of the controllers work abnormal if we enables runtime
pm unconditionally, so I use one system flag CI_HDRC_SUPPORTS_RUNTIME_PM
for it. I can't understand why you can't access device without enable
parent's runtime pm, the controller will not enter runtime suspend
without that flag.

Peter
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/ci_hdrc_msm.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> index 520c85e701ef..430856ef1be3 100644
> --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> @@ -80,6 +80,7 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  
>  	pm_runtime_no_callbacks(&pdev->dev);
>  	pm_runtime_enable(&pdev->dev);
> +	pm_runtime_get(&pdev->dev);
>  
>  	return 0;
>  }
> @@ -88,6 +89,7 @@ static int ci_hdrc_msm_remove(struct platform_device *pdev)
>  {
>  	struct platform_device *plat_ci = platform_get_drvdata(pdev);
>  
> +	pm_runtime_put(&pdev->dev);
>  	pm_runtime_disable(&pdev->dev);
>  	ci_hdrc_remove_device(plat_ci);
>  
> -- 
> 2.9.0.rc2.8.ga28705d
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 

Best Regards,
Peter Chen

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

* [PATCH 12/21] usb: chipidea: msm: Keep device runtime enabled
@ 2016-06-29  6:46     ` Peter Chen
  0 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-29  6:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Jun 26, 2016 at 12:28:29AM -0700, Stephen Boyd wrote:
> Sometimes the usb wrapper device is part of a power domain that
> needs to stay on as long as the device is active. Let's get and
> put the device in driver probe/remove so that we keep the power
> domain powered as long as the device is attached. We can fine
> tune this later to handle wakeup interrupts, etc. for finer grain
> power management later, but this is necessary to make sure we can
> keep accessing the device right now.

Since some of the controllers work abnormal if we enables runtime
pm unconditionally, so I use one system flag CI_HDRC_SUPPORTS_RUNTIME_PM
for it. I can't understand why you can't access device without enable
parent's runtime pm, the controller will not enter runtime suspend
without that flag.

Peter
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/ci_hdrc_msm.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> index 520c85e701ef..430856ef1be3 100644
> --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> @@ -80,6 +80,7 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  
>  	pm_runtime_no_callbacks(&pdev->dev);
>  	pm_runtime_enable(&pdev->dev);
> +	pm_runtime_get(&pdev->dev);
>  
>  	return 0;
>  }
> @@ -88,6 +89,7 @@ static int ci_hdrc_msm_remove(struct platform_device *pdev)
>  {
>  	struct platform_device *plat_ci = platform_get_drvdata(pdev);
>  
> +	pm_runtime_put(&pdev->dev);
>  	pm_runtime_disable(&pdev->dev);
>  	ci_hdrc_remove_device(plat_ci);
>  
> -- 
> 2.9.0.rc2.8.ga28705d
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 

Best Regards,
Peter Chen

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

* Re: [PATCH 13/21] usb: chipidea: msm: Allow core to get usb phy
  2016-06-26  7:28   ` Stephen Boyd
@ 2016-06-29  6:48     ` Peter Chen
  -1 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-29  6:48 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, linux-arm-kernel, linux-kernel, linux-arm-msm,
	Andy Gross, Bjorn Andersson, Neil Armstrong, Arnd Bergmann,
	Felipe Balbi, Peter Chen, Greg Kroah-Hartman

On Sun, Jun 26, 2016 at 12:28:30AM -0700, Stephen Boyd wrote:
> The chipidea core gets the usb phy and initializes the phy at the
> right point now so we don't need to get the phy in this driver.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/ci_hdrc_msm.c | 21 ---------------------
>  1 file changed, 21 deletions(-)
> 
> diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> index 430856ef1be3..07cccd24a87f 100644
> --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> @@ -24,15 +24,6 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
>  		dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
>  		/* use AHB transactor, allow posted data writes */
>  		hw_write_id_reg(ci, HS_PHY_AHB_MODE, 0xffffffff, 0x8);
> -		usb_phy_init(ci->usb_phy);
> -		break;
> -	case CI_HDRC_CONTROLLER_STOPPED_EVENT:
> -		dev_dbg(dev, "CI_HDRC_CONTROLLER_STOPPED_EVENT received\n");
> -		/*
> -		 * Put the phy in non-driving mode. Otherwise host
> -		 * may not detect soft-disconnection.
> -		 */
> -		usb_phy_notify_disconnect(ci->usb_phy, USB_SPEED_UNKNOWN);
>  		break;
>  	default:
>  		dev_dbg(dev, "unknown ci_hdrc event\n");
> @@ -53,21 +44,9 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
>  static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  {
>  	struct platform_device *plat_ci;
> -	struct usb_phy *phy;
>  
>  	dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
>  
> -	/*
> -	 * OTG(PHY) driver takes care of PHY initialization, clock management,
> -	 * powering up VBUS, mapping of registers address space and power
> -	 * management.
> -	 */
> -	phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0);
> -	if (IS_ERR(phy))
> -		return PTR_ERR(phy);
> -
> -	ci_hdrc_msm_platdata.usb_phy = phy;
> -
>  	plat_ci = ci_hdrc_add_device(&pdev->dev,
>  				pdev->resource, pdev->num_resources,
>  				&ci_hdrc_msm_platdata);
> -- 

Acked-by: Peter Chen <peter.chen@nxp.com>

-- 

Best Regards,
Peter Chen

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

* [PATCH 13/21] usb: chipidea: msm: Allow core to get usb phy
@ 2016-06-29  6:48     ` Peter Chen
  0 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-29  6:48 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Jun 26, 2016 at 12:28:30AM -0700, Stephen Boyd wrote:
> The chipidea core gets the usb phy and initializes the phy at the
> right point now so we don't need to get the phy in this driver.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/ci_hdrc_msm.c | 21 ---------------------
>  1 file changed, 21 deletions(-)
> 
> diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> index 430856ef1be3..07cccd24a87f 100644
> --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> @@ -24,15 +24,6 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
>  		dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
>  		/* use AHB transactor, allow posted data writes */
>  		hw_write_id_reg(ci, HS_PHY_AHB_MODE, 0xffffffff, 0x8);
> -		usb_phy_init(ci->usb_phy);
> -		break;
> -	case CI_HDRC_CONTROLLER_STOPPED_EVENT:
> -		dev_dbg(dev, "CI_HDRC_CONTROLLER_STOPPED_EVENT received\n");
> -		/*
> -		 * Put the phy in non-driving mode. Otherwise host
> -		 * may not detect soft-disconnection.
> -		 */
> -		usb_phy_notify_disconnect(ci->usb_phy, USB_SPEED_UNKNOWN);
>  		break;
>  	default:
>  		dev_dbg(dev, "unknown ci_hdrc event\n");
> @@ -53,21 +44,9 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
>  static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  {
>  	struct platform_device *plat_ci;
> -	struct usb_phy *phy;
>  
>  	dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
>  
> -	/*
> -	 * OTG(PHY) driver takes care of PHY initialization, clock management,
> -	 * powering up VBUS, mapping of registers address space and power
> -	 * management.
> -	 */
> -	phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0);
> -	if (IS_ERR(phy))
> -		return PTR_ERR(phy);
> -
> -	ci_hdrc_msm_platdata.usb_phy = phy;
> -
>  	plat_ci = ci_hdrc_add_device(&pdev->dev,
>  				pdev->resource, pdev->num_resources,
>  				&ci_hdrc_msm_platdata);
> -- 

Acked-by: Peter Chen <peter.chen@nxp.com>

-- 

Best Regards,
Peter Chen

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

* Re: [PATCH 14/21] usb: chipidea: msm: Add proper clk and reset support
  2016-06-26  7:28     ` Stephen Boyd
@ 2016-06-29  7:02       ` Peter Chen
  -1 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-29  7:02 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, linux-arm-kernel, linux-kernel, linux-arm-msm,
	Andy Gross, Bjorn Andersson, Neil Armstrong, Arnd Bergmann,
	Felipe Balbi, Peter Chen, Greg Kroah-Hartman

On Sun, Jun 26, 2016 at 12:28:31AM -0700, Stephen Boyd wrote:
> The msm chipidea controller uses two main clks, an AHB clk to
> read/write the MMIO registers and a core clk called the system
> clk that drives the controller itself. Add support for these clks
> as they're required in all designs.
> 
> Also add support for an optional third clk that we need to turn
> on to read/write the ULPI phy registers. Some ULPI phys drive
> this clk themselves and so it isn't necessary to turn on to probe
> a ULPI device, but the HSIC phy doesn't provide one itself, so we
> must turn it on here.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/ci_hdrc_msm.c | 58 +++++++++++++++++++++++++++++++++++---
>  1 file changed, 54 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> index 07cccd24a87f..40249b0e3e93 100644
> --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> @@ -10,11 +10,19 @@
>  #include <linux/pm_runtime.h>
>  #include <linux/usb/gadget.h>
>  #include <linux/usb/chipidea.h>
> +#include <linux/clk.h>
> +#include <linux/reset.h>
>  
>  #include "ci.h"
>  
>  #define HS_PHY_AHB_MODE			0x0098
>  
> +struct ci_hdrc_msm {
> +	struct platform_device *ci;
> +	struct clk *core_clk;
> +	struct clk *iface_clk;
> +};
> +
>  static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
>  {
>  	struct device *dev = ci->gadget.dev.parent;
> @@ -43,34 +51,76 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
>  
>  static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  {
> +	struct ci_hdrc_msm *ci;
>  	struct platform_device *plat_ci;
> +	struct clk *clk;
> +	struct reset_control *reset;
> +	int ret;
>  
>  	dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
>  
> +	ci = devm_kzalloc(&pdev->dev, sizeof(*ci), GFP_KERNEL);
> +	if (!ci)
> +		return -ENOMEM;
> +	platform_set_drvdata(pdev, ci);
> +
> +	reset = devm_reset_control_get(&pdev->dev, "core");
> +	if (IS_ERR(reset))
> +		return PTR_ERR(reset);
> +
> +	ci->core_clk = clk = devm_clk_get(&pdev->dev, "core");
> +	if (IS_ERR(clk))
> +		return PTR_ERR(clk);
> +
> +	ci->iface_clk = clk = devm_clk_get(&pdev->dev, "iface");
> +	if (IS_ERR(clk))
> +		return PTR_ERR(clk);

You say it has three clocks in commit log, why it is only two in the code?
> +
> +	reset_control_assert(reset);
> +	usleep_range(10000, 12000);
> +	reset_control_deassert(reset);
> +
> +	ret = clk_prepare_enable(ci->core_clk);
> +	if (ret)
> +		return ret;
> +
> +	ret = clk_prepare_enable(ci->iface_clk);
> +	if (ret)
> +		goto err_iface;
> +
>  	plat_ci = ci_hdrc_add_device(&pdev->dev,
>  				pdev->resource, pdev->num_resources,
>  				&ci_hdrc_msm_platdata);
ci->plat_ci(or ci) = ...

Delete the local variable plat_ci

>  	if (IS_ERR(plat_ci)) {
>  		dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
> -		return PTR_ERR(plat_ci);
> +		ret = PTR_ERR(plat_ci);
> +		goto err_mux;
>  	}
>  
> -	platform_set_drvdata(pdev, plat_ci);
> +	ci->ci = plat_ci;

[...]


-- 

Best Regards,
Peter Chen

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

* [PATCH 14/21] usb: chipidea: msm: Add proper clk and reset support
@ 2016-06-29  7:02       ` Peter Chen
  0 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-29  7:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Jun 26, 2016 at 12:28:31AM -0700, Stephen Boyd wrote:
> The msm chipidea controller uses two main clks, an AHB clk to
> read/write the MMIO registers and a core clk called the system
> clk that drives the controller itself. Add support for these clks
> as they're required in all designs.
> 
> Also add support for an optional third clk that we need to turn
> on to read/write the ULPI phy registers. Some ULPI phys drive
> this clk themselves and so it isn't necessary to turn on to probe
> a ULPI device, but the HSIC phy doesn't provide one itself, so we
> must turn it on here.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/ci_hdrc_msm.c | 58 +++++++++++++++++++++++++++++++++++---
>  1 file changed, 54 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> index 07cccd24a87f..40249b0e3e93 100644
> --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> @@ -10,11 +10,19 @@
>  #include <linux/pm_runtime.h>
>  #include <linux/usb/gadget.h>
>  #include <linux/usb/chipidea.h>
> +#include <linux/clk.h>
> +#include <linux/reset.h>
>  
>  #include "ci.h"
>  
>  #define HS_PHY_AHB_MODE			0x0098
>  
> +struct ci_hdrc_msm {
> +	struct platform_device *ci;
> +	struct clk *core_clk;
> +	struct clk *iface_clk;
> +};
> +
>  static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
>  {
>  	struct device *dev = ci->gadget.dev.parent;
> @@ -43,34 +51,76 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
>  
>  static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  {
> +	struct ci_hdrc_msm *ci;
>  	struct platform_device *plat_ci;
> +	struct clk *clk;
> +	struct reset_control *reset;
> +	int ret;
>  
>  	dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
>  
> +	ci = devm_kzalloc(&pdev->dev, sizeof(*ci), GFP_KERNEL);
> +	if (!ci)
> +		return -ENOMEM;
> +	platform_set_drvdata(pdev, ci);
> +
> +	reset = devm_reset_control_get(&pdev->dev, "core");
> +	if (IS_ERR(reset))
> +		return PTR_ERR(reset);
> +
> +	ci->core_clk = clk = devm_clk_get(&pdev->dev, "core");
> +	if (IS_ERR(clk))
> +		return PTR_ERR(clk);
> +
> +	ci->iface_clk = clk = devm_clk_get(&pdev->dev, "iface");
> +	if (IS_ERR(clk))
> +		return PTR_ERR(clk);

You say it has three clocks in commit log, why it is only two in the code?
> +
> +	reset_control_assert(reset);
> +	usleep_range(10000, 12000);
> +	reset_control_deassert(reset);
> +
> +	ret = clk_prepare_enable(ci->core_clk);
> +	if (ret)
> +		return ret;
> +
> +	ret = clk_prepare_enable(ci->iface_clk);
> +	if (ret)
> +		goto err_iface;
> +
>  	plat_ci = ci_hdrc_add_device(&pdev->dev,
>  				pdev->resource, pdev->num_resources,
>  				&ci_hdrc_msm_platdata);
ci->plat_ci(or ci) = ...

Delete the local variable plat_ci

>  	if (IS_ERR(plat_ci)) {
>  		dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
> -		return PTR_ERR(plat_ci);
> +		ret = PTR_ERR(plat_ci);
> +		goto err_mux;
>  	}
>  
> -	platform_set_drvdata(pdev, plat_ci);
> +	ci->ci = plat_ci;

[...]


-- 

Best Regards,
Peter Chen

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

* Re: [PATCH 15/21] usb: chipidea: msm: Mux over secondary phy at the right time
  2016-06-26  7:28   ` Stephen Boyd
@ 2016-06-29  8:08     ` Peter Chen
  -1 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-29  8:08 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, Felipe Balbi, Arnd Bergmann, Neil Armstrong,
	linux-arm-msm, linux-kernel, Bjorn Andersson, Peter Chen,
	Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

On Sun, Jun 26, 2016 at 12:28:32AM -0700, Stephen Boyd wrote:
> We need to pick the correct phy at runtime based on how the SoC
> has been wired onto the board. If the secondary phy is used, take
> it out of reset and mux over to it by writing into the TCSR
> register. Make sure to do this on reset too, because this
> register is reset to the default value (primary phy) after the
> RESET bit is set in USBCMD.
> 

I am curious when you need the secondary phy?

> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/ci_hdrc_msm.c | 78 +++++++++++++++++++++++++++++++++++---
>  1 file changed, 73 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> index 40249b0e3e93..df0f8b31db4f 100644
> --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> @@ -8,30 +8,40 @@
>  #include <linux/module.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_runtime.h>
> -#include <linux/usb/gadget.h>
>  #include <linux/usb/chipidea.h>
>  #include <linux/clk.h>
>  #include <linux/reset.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/regmap.h>
> +#include <linux/io.h>
>  
>  #include "ci.h"
>  
>  #define HS_PHY_AHB_MODE			0x0098
> +#define HS_PHY_SEC_CTRL			0x0278
> +# define HS_PHY_DIG_CLAMP_N		BIT(16)
>  

One space at the beginning, and keep alignment.

>  struct ci_hdrc_msm {
>  	struct platform_device *ci;
>  	struct clk *core_clk;
>  	struct clk *iface_clk;
> +	bool secondary_phy;
> +	void __iomem *base;
>  };
>  
>  static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
>  {
> -	struct device *dev = ci->gadget.dev.parent;
> +	struct device *dev = ci->dev->parent;
> +	struct ci_hdrc_msm *msm_ci = dev_get_drvdata(dev);
>  
>  	switch (event) {
>  	case CI_HDRC_CONTROLLER_RESET_EVENT:
>  		dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
>  		/* use AHB transactor, allow posted data writes */
>  		hw_write_id_reg(ci, HS_PHY_AHB_MODE, 0xffffffff, 0x8);
> +		if (msm_ci->secondary_phy)
> +			hw_write_id_reg(ci, HS_PHY_SEC_CTRL, HS_PHY_DIG_CLAMP_N,
> +					HS_PHY_DIG_CLAMP_N);
>  		break;
>  	default:
>  		dev_dbg(dev, "unknown ci_hdrc event\n");
> @@ -49,12 +59,58 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
>  	.notify_event		= ci_hdrc_msm_notify_event,
>  };
>  
> +static int ci_hdrc_msm_mux_phy(struct ci_hdrc_msm *ci,
> +			       struct platform_device *pdev)
> +{
> +	struct regmap *regmap;
> +	struct device_node *syscon;
> +	struct device *dev = &pdev->dev;
> +	u32 off, val;
> +	int ret;
> +
> +	syscon = of_parse_phandle(dev->of_node, "phy-select", 0);
> +	if (!syscon)
> +		return 0;
> +
> +	regmap = syscon_node_to_regmap(syscon);
> +	if (IS_ERR(regmap))
> +		return PTR_ERR(regmap);
> +
> +	ret = of_property_read_u32_index(dev->of_node, "phy-select", 1, &off);
> +	if (ret < 0) {
> +		dev_err(dev, "no offset in syscon\n");
> +		return -EINVAL;
> +	}
> +
> +	ret = of_property_read_u32_index(dev->of_node, "phy-select", 2, &val);
> +	if (ret < 0) {
> +		dev_err(dev, "no value in syscon\n");
> +		return -EINVAL;
> +	}
> +
> +	ret = regmap_write(regmap, off, val);
> +	if (ret)
> +		return ret;
> +
> +	ci->secondary_phy = !!val;
> +	if (ci->secondary_phy) {
> +		val = readl_relaxed(ci->base + HS_PHY_SEC_CTRL);
> +		val |= HS_PHY_DIG_CLAMP_N;
> +		writel_relaxed(val, ci->base + HS_PHY_SEC_CTRL);
> +	}
> +
> +	return 0;
> +}
> +
>  static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  {
>  	struct ci_hdrc_msm *ci;
>  	struct platform_device *plat_ci;
>  	struct clk *clk;
>  	struct reset_control *reset;
> +	struct resource *res;
> +	void __iomem *base;
> +	resource_size_t size;
>  	int ret;
>  
>  	dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
> @@ -76,6 +132,15 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  	if (IS_ERR(clk))
>  		return PTR_ERR(clk);
>  
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!res)
> +		return -ENODEV;
> +
> +	size = resource_size(res);
> +	ci->base = base = devm_ioremap(&pdev->dev, res->start, size);
> +	if (!base)
> +		return -ENOMEM;
> +

The core will do the ioremap too, you can't remap io address two times.
The offset larger than 0x200 is vendor specific, you can map it as
the second io region.


>  	reset_control_assert(reset);
>  	usleep_range(10000, 12000);
>  	reset_control_deassert(reset);
> @@ -88,9 +153,12 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  	if (ret)
>  		goto err_iface;
>  
> -	plat_ci = ci_hdrc_add_device(&pdev->dev,
> -				pdev->resource, pdev->num_resources,
> -				&ci_hdrc_msm_platdata);
> +	ret = ci_hdrc_msm_mux_phy(ci, pdev);
> +	if (ret)
> +		goto err_mux;
> +
> +	plat_ci = ci_hdrc_add_device(&pdev->dev, pdev->resource,
> +				     pdev->num_resources, &ci_hdrc_msm_platdata);
>  	if (IS_ERR(plat_ci)) {
>  		dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
>  		ret = PTR_ERR(plat_ci);
> -- 
> 2.9.0.rc2.8.ga28705d
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 

Best Regards,
Peter Chen

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

* [PATCH 15/21] usb: chipidea: msm: Mux over secondary phy at the right time
@ 2016-06-29  8:08     ` Peter Chen
  0 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-29  8:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Jun 26, 2016 at 12:28:32AM -0700, Stephen Boyd wrote:
> We need to pick the correct phy at runtime based on how the SoC
> has been wired onto the board. If the secondary phy is used, take
> it out of reset and mux over to it by writing into the TCSR
> register. Make sure to do this on reset too, because this
> register is reset to the default value (primary phy) after the
> RESET bit is set in USBCMD.
> 

I am curious when you need the secondary phy?

> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/ci_hdrc_msm.c | 78 +++++++++++++++++++++++++++++++++++---
>  1 file changed, 73 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> index 40249b0e3e93..df0f8b31db4f 100644
> --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> @@ -8,30 +8,40 @@
>  #include <linux/module.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_runtime.h>
> -#include <linux/usb/gadget.h>
>  #include <linux/usb/chipidea.h>
>  #include <linux/clk.h>
>  #include <linux/reset.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/regmap.h>
> +#include <linux/io.h>
>  
>  #include "ci.h"
>  
>  #define HS_PHY_AHB_MODE			0x0098
> +#define HS_PHY_SEC_CTRL			0x0278
> +# define HS_PHY_DIG_CLAMP_N		BIT(16)
>  

One space at the beginning, and keep alignment.

>  struct ci_hdrc_msm {
>  	struct platform_device *ci;
>  	struct clk *core_clk;
>  	struct clk *iface_clk;
> +	bool secondary_phy;
> +	void __iomem *base;
>  };
>  
>  static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
>  {
> -	struct device *dev = ci->gadget.dev.parent;
> +	struct device *dev = ci->dev->parent;
> +	struct ci_hdrc_msm *msm_ci = dev_get_drvdata(dev);
>  
>  	switch (event) {
>  	case CI_HDRC_CONTROLLER_RESET_EVENT:
>  		dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
>  		/* use AHB transactor, allow posted data writes */
>  		hw_write_id_reg(ci, HS_PHY_AHB_MODE, 0xffffffff, 0x8);
> +		if (msm_ci->secondary_phy)
> +			hw_write_id_reg(ci, HS_PHY_SEC_CTRL, HS_PHY_DIG_CLAMP_N,
> +					HS_PHY_DIG_CLAMP_N);
>  		break;
>  	default:
>  		dev_dbg(dev, "unknown ci_hdrc event\n");
> @@ -49,12 +59,58 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
>  	.notify_event		= ci_hdrc_msm_notify_event,
>  };
>  
> +static int ci_hdrc_msm_mux_phy(struct ci_hdrc_msm *ci,
> +			       struct platform_device *pdev)
> +{
> +	struct regmap *regmap;
> +	struct device_node *syscon;
> +	struct device *dev = &pdev->dev;
> +	u32 off, val;
> +	int ret;
> +
> +	syscon = of_parse_phandle(dev->of_node, "phy-select", 0);
> +	if (!syscon)
> +		return 0;
> +
> +	regmap = syscon_node_to_regmap(syscon);
> +	if (IS_ERR(regmap))
> +		return PTR_ERR(regmap);
> +
> +	ret = of_property_read_u32_index(dev->of_node, "phy-select", 1, &off);
> +	if (ret < 0) {
> +		dev_err(dev, "no offset in syscon\n");
> +		return -EINVAL;
> +	}
> +
> +	ret = of_property_read_u32_index(dev->of_node, "phy-select", 2, &val);
> +	if (ret < 0) {
> +		dev_err(dev, "no value in syscon\n");
> +		return -EINVAL;
> +	}
> +
> +	ret = regmap_write(regmap, off, val);
> +	if (ret)
> +		return ret;
> +
> +	ci->secondary_phy = !!val;
> +	if (ci->secondary_phy) {
> +		val = readl_relaxed(ci->base + HS_PHY_SEC_CTRL);
> +		val |= HS_PHY_DIG_CLAMP_N;
> +		writel_relaxed(val, ci->base + HS_PHY_SEC_CTRL);
> +	}
> +
> +	return 0;
> +}
> +
>  static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  {
>  	struct ci_hdrc_msm *ci;
>  	struct platform_device *plat_ci;
>  	struct clk *clk;
>  	struct reset_control *reset;
> +	struct resource *res;
> +	void __iomem *base;
> +	resource_size_t size;
>  	int ret;
>  
>  	dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
> @@ -76,6 +132,15 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  	if (IS_ERR(clk))
>  		return PTR_ERR(clk);
>  
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!res)
> +		return -ENODEV;
> +
> +	size = resource_size(res);
> +	ci->base = base = devm_ioremap(&pdev->dev, res->start, size);
> +	if (!base)
> +		return -ENOMEM;
> +

The core will do the ioremap too, you can't remap io address two times.
The offset larger than 0x200 is vendor specific, you can map it as
the second io region.


>  	reset_control_assert(reset);
>  	usleep_range(10000, 12000);
>  	reset_control_deassert(reset);
> @@ -88,9 +153,12 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  	if (ret)
>  		goto err_iface;
>  
> -	plat_ci = ci_hdrc_add_device(&pdev->dev,
> -				pdev->resource, pdev->num_resources,
> -				&ci_hdrc_msm_platdata);
> +	ret = ci_hdrc_msm_mux_phy(ci, pdev);
> +	if (ret)
> +		goto err_mux;
> +
> +	plat_ci = ci_hdrc_add_device(&pdev->dev, pdev->resource,
> +				     pdev->num_resources, &ci_hdrc_msm_platdata);
>  	if (IS_ERR(plat_ci)) {
>  		dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
>  		ret = PTR_ERR(plat_ci);
> -- 
> 2.9.0.rc2.8.ga28705d
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 

Best Regards,
Peter Chen

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

* Re: [PATCH 16/21] usb: chipidea: msm: Restore wrapper settings after reset
  2016-06-26  7:28   ` Stephen Boyd
@ 2016-06-29  8:26     ` Peter Chen
  -1 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-29  8:26 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, Felipe Balbi, Arnd Bergmann, Neil Armstrong,
	linux-arm-msm, linux-kernel, Bjorn Andersson, Peter Chen,
	Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

On Sun, Jun 26, 2016 at 12:28:33AM -0700, Stephen Boyd wrote:
> When the RESET bit is set in the USBCMD register it resets quite
> a few of the wrapper's registers to their reset state. This
> includes the GENCONFIG and GENCONFIG2 registers. Currently this
> is done by the usb phy and ehci-msm drivers writing into the
> controller wrapper's MMIO address space. Let's consolidate the
> register writes into the wrapper driver instead so that we
> clearly split the wrapper from the phys.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/ci_hdrc_msm.c | 46 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 46 insertions(+)
> 
> diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> index df0f8b31db4f..cc6f9b0df9d5 100644
> --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> @@ -14,6 +14,8 @@
>  #include <linux/mfd/syscon.h>
>  #include <linux/regmap.h>
>  #include <linux/io.h>
> +#include <linux/extcon.h>
> +#include <linux/of.h>
>  
>  #include "ci.h"
>  
> @@ -21,11 +23,22 @@
>  #define HS_PHY_SEC_CTRL			0x0278
>  # define HS_PHY_DIG_CLAMP_N		BIT(16)
>  
> +#define HS_PHY_GENCONFIG		0x009c
> +# define HS_PHY_TXFIFO_IDLE_FORCE_DIS	BIT(4)
> +
> +#define HS_PHY_GENCONFIG_2		0x00a0
> +# define HS_PHY_SESS_VLD_CTRL_EN	BIT(7)
> +# define HS_PHY_ULPI_TX_PKT_EN_CLR_FIX	BIT(19)
> +
> +#define HSPHY_SESS_VLD_CTRL		BIT(25)
> +

Keep alignment please.

>  struct ci_hdrc_msm {
>  	struct platform_device *ci;
>  	struct clk *core_clk;
>  	struct clk *iface_clk;
> +	struct extcon_dev *vbus_edev;
>  	bool secondary_phy;
> +	bool hsic;
>  	void __iomem *base;
>  };
>  
> @@ -39,9 +52,26 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
>  		dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
>  		/* use AHB transactor, allow posted data writes */
>  		hw_write_id_reg(ci, HS_PHY_AHB_MODE, 0xffffffff, 0x8);
> +		/* workaround for rx buffer collision issue */
> +		hw_write_id_reg(ci, HS_PHY_GENCONFIG,
> +				HS_PHY_TXFIFO_IDLE_FORCE_DIS, 0);
> +
>  		if (msm_ci->secondary_phy)
>  			hw_write_id_reg(ci, HS_PHY_SEC_CTRL, HS_PHY_DIG_CLAMP_N,
>  					HS_PHY_DIG_CLAMP_N);
> +
> +		if (!msm_ci->hsic)
> +			hw_write_id_reg(ci, HS_PHY_GENCONFIG_2,
> +					HS_PHY_ULPI_TX_PKT_EN_CLR_FIX, 0);
> +
> +		if (msm_ci->vbus_edev) {
> +			hw_write_id_reg(ci, HS_PHY_GENCONFIG_2,
> +					HS_PHY_SESS_VLD_CTRL_EN,
> +					HS_PHY_SESS_VLD_CTRL_EN);
> +			hw_write(ci, OP_USBCMD, HSPHY_SESS_VLD_CTRL,
> +				 HSPHY_SESS_VLD_CTRL);
> +
> +		}
>  		break;
>  	default:
>  		dev_dbg(dev, "unknown ci_hdrc event\n");
> @@ -112,6 +142,7 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  	void __iomem *base;
>  	resource_size_t size;
>  	int ret;
> +	struct device_node *ulpi_node, *phy_node;
>  
>  	dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
>  
> @@ -141,6 +172,13 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  	if (!base)
>  		return -ENOMEM;
>  
> +	ci->vbus_edev = extcon_get_edev_by_phandle(&pdev->dev, 0);
> +	if (IS_ERR(ci->vbus_edev)) {
> +		if (PTR_ERR(ci->vbus_edev) != -ENODEV)
> +			return PTR_ERR(ci->vbus_edev);
> +		ci->vbus_edev = NULL;
> +	}
> +

Why not using ci->platdata->vbus_extcon directly?

>  	reset_control_assert(reset);
>  	usleep_range(10000, 12000);
>  	reset_control_deassert(reset);
> @@ -157,6 +195,14 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  	if (ret)
>  		goto err_mux;
>  
> +	ulpi_node = of_find_node_by_name(pdev->dev.of_node, "ulpi");
> +	if (ulpi_node) {
> +		phy_node = of_get_next_available_child(ulpi_node, NULL);
> +		ci->hsic = of_device_is_compatible(phy_node, "qcom,usb-hsic-phy");
> +		of_node_put(phy_node);
> +	}
> +	of_node_put(ulpi_node);
> +

Just confirm with you that ci->platdata->phy_mode is not enough?

>  	plat_ci = ci_hdrc_add_device(&pdev->dev, pdev->resource,
>  				     pdev->num_resources, &ci_hdrc_msm_platdata);
>  	if (IS_ERR(plat_ci)) {
> -- 
> 2.9.0.rc2.8.ga28705d
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 

Best Regards,
Peter Chen

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

* [PATCH 16/21] usb: chipidea: msm: Restore wrapper settings after reset
@ 2016-06-29  8:26     ` Peter Chen
  0 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-29  8:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Jun 26, 2016 at 12:28:33AM -0700, Stephen Boyd wrote:
> When the RESET bit is set in the USBCMD register it resets quite
> a few of the wrapper's registers to their reset state. This
> includes the GENCONFIG and GENCONFIG2 registers. Currently this
> is done by the usb phy and ehci-msm drivers writing into the
> controller wrapper's MMIO address space. Let's consolidate the
> register writes into the wrapper driver instead so that we
> clearly split the wrapper from the phys.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/ci_hdrc_msm.c | 46 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 46 insertions(+)
> 
> diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> index df0f8b31db4f..cc6f9b0df9d5 100644
> --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> @@ -14,6 +14,8 @@
>  #include <linux/mfd/syscon.h>
>  #include <linux/regmap.h>
>  #include <linux/io.h>
> +#include <linux/extcon.h>
> +#include <linux/of.h>
>  
>  #include "ci.h"
>  
> @@ -21,11 +23,22 @@
>  #define HS_PHY_SEC_CTRL			0x0278
>  # define HS_PHY_DIG_CLAMP_N		BIT(16)
>  
> +#define HS_PHY_GENCONFIG		0x009c
> +# define HS_PHY_TXFIFO_IDLE_FORCE_DIS	BIT(4)
> +
> +#define HS_PHY_GENCONFIG_2		0x00a0
> +# define HS_PHY_SESS_VLD_CTRL_EN	BIT(7)
> +# define HS_PHY_ULPI_TX_PKT_EN_CLR_FIX	BIT(19)
> +
> +#define HSPHY_SESS_VLD_CTRL		BIT(25)
> +

Keep alignment please.

>  struct ci_hdrc_msm {
>  	struct platform_device *ci;
>  	struct clk *core_clk;
>  	struct clk *iface_clk;
> +	struct extcon_dev *vbus_edev;
>  	bool secondary_phy;
> +	bool hsic;
>  	void __iomem *base;
>  };
>  
> @@ -39,9 +52,26 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
>  		dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
>  		/* use AHB transactor, allow posted data writes */
>  		hw_write_id_reg(ci, HS_PHY_AHB_MODE, 0xffffffff, 0x8);
> +		/* workaround for rx buffer collision issue */
> +		hw_write_id_reg(ci, HS_PHY_GENCONFIG,
> +				HS_PHY_TXFIFO_IDLE_FORCE_DIS, 0);
> +
>  		if (msm_ci->secondary_phy)
>  			hw_write_id_reg(ci, HS_PHY_SEC_CTRL, HS_PHY_DIG_CLAMP_N,
>  					HS_PHY_DIG_CLAMP_N);
> +
> +		if (!msm_ci->hsic)
> +			hw_write_id_reg(ci, HS_PHY_GENCONFIG_2,
> +					HS_PHY_ULPI_TX_PKT_EN_CLR_FIX, 0);
> +
> +		if (msm_ci->vbus_edev) {
> +			hw_write_id_reg(ci, HS_PHY_GENCONFIG_2,
> +					HS_PHY_SESS_VLD_CTRL_EN,
> +					HS_PHY_SESS_VLD_CTRL_EN);
> +			hw_write(ci, OP_USBCMD, HSPHY_SESS_VLD_CTRL,
> +				 HSPHY_SESS_VLD_CTRL);
> +
> +		}
>  		break;
>  	default:
>  		dev_dbg(dev, "unknown ci_hdrc event\n");
> @@ -112,6 +142,7 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  	void __iomem *base;
>  	resource_size_t size;
>  	int ret;
> +	struct device_node *ulpi_node, *phy_node;
>  
>  	dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
>  
> @@ -141,6 +172,13 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  	if (!base)
>  		return -ENOMEM;
>  
> +	ci->vbus_edev = extcon_get_edev_by_phandle(&pdev->dev, 0);
> +	if (IS_ERR(ci->vbus_edev)) {
> +		if (PTR_ERR(ci->vbus_edev) != -ENODEV)
> +			return PTR_ERR(ci->vbus_edev);
> +		ci->vbus_edev = NULL;
> +	}
> +

Why not using ci->platdata->vbus_extcon directly?

>  	reset_control_assert(reset);
>  	usleep_range(10000, 12000);
>  	reset_control_deassert(reset);
> @@ -157,6 +195,14 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  	if (ret)
>  		goto err_mux;
>  
> +	ulpi_node = of_find_node_by_name(pdev->dev.of_node, "ulpi");
> +	if (ulpi_node) {
> +		phy_node = of_get_next_available_child(ulpi_node, NULL);
> +		ci->hsic = of_device_is_compatible(phy_node, "qcom,usb-hsic-phy");
> +		of_node_put(phy_node);
> +	}
> +	of_node_put(ulpi_node);
> +

Just confirm with you that ci->platdata->phy_mode is not enough?

>  	plat_ci = ci_hdrc_add_device(&pdev->dev, pdev->resource,
>  				     pdev->num_resources, &ci_hdrc_msm_platdata);
>  	if (IS_ERR(plat_ci)) {
> -- 
> 2.9.0.rc2.8.ga28705d
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 

Best Regards,
Peter Chen

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

* Re: [PATCH 20/21] phy: Add support for Qualcomm's USB HSIC phy
  2016-06-28 21:58         ` Stephen Boyd
  (?)
@ 2016-06-29  9:16           ` Neil Armstrong
  -1 siblings, 0 replies; 214+ messages in thread
From: Neil Armstrong @ 2016-06-29  9:16 UTC (permalink / raw)
  To: Stephen Boyd, linux-usb-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA, Andy Gross,
	Bjorn Andersson, Arnd Bergmann, Felipe Balbi,
	Kishon Vijay Abraham I, devicetree-u79uwXL29TY76Z2rM5mHXA

On 06/28/2016 11:58 PM, Stephen Boyd wrote:
> Quoting Neil Armstrong (2016-06-28 01:49:37)
>> On 06/26/2016 09:28 AM, Stephen Boyd wrote:
>>> +     uphy->cal_sleep_clk = clk = devm_clk_get(&ulpi->dev, "cal_sleep");
>>> +     if (IS_ERR(clk))
>>> +             return PTR_ERR(clk);
>>
>> Hi Stephen,
>>
>> In the bindings the cal_sleep is marked optional, and I think should be since AFAIK
>> it's not present on MDM9615 for example.
> 
> The cal_sleep clk is just the sleep clk then (should be a board clk in
> DT). Sometimes there's a gate in GCC to allow us to turn it off, other
> times there isn't. Either way, it's always wired there so I'll update
> the binding to say it isn't optional.

Sorry I don't understand !
What should I do if GCC does not provide a gate here ? And looking at the driver, it could be optional.

> 
>>
>> Also MDM9615 HSIC requires "core", "alt-core", "phy", "cal" and "iface" clocks.
>> I assume "core" can be attributed to the main chipidea node, but I think "alt-core" and "iface" should be also optionnal.
> 
> Looking at the downstream sources I see this:
> 
>         "core_clk"     -> usb_hsic_sys_clk
>         "iface_clk"    -> usb_hsic_p_clk
>         "alt_core_clk" -> usb_hsic_xcvr_clk
> 
>         "cal_clk"      -> usb_hsic_hsio_cal_clk
>         "phy_clk"      -> usb_hsic_clk
> 
> "core_clk" would be the core clk in ci_hdrc_msm. "iface_clk" would be
> the iface clk in ci_hdrc_msm. "cal_clk" would be the cal clk in the hsic
> phy and "phy_clk" would be the phy clk in the hsic phy.
> 
> That leaves alt_core_clk which seems to be a clock that needs to be on
> during the reset assert/deassert and possibly for LPM and USB1.1 FS
> modes. Sometimes it's referred to as the "housekeeping" clk. Due to the
> way resets are done on msm8974 and later SoCs it looks like this clk was
> removed. I can make this an optional clk in the ci_hdrc_msm driver, or
> we can have two versions of the ci_hdrc_msm compatible string, one for a
> device that has the housekeeping clk and one for the device that
> doesn't.

Having it optional would be the best solution I think.

> 
>>
>> Finally, it misses an optional reset line AFAIK mandatory on MDM9615.
>>
> 
> From what I can tell downstream, all those clks point to the same bit 0
> of HSIC_RESET register? So there isn't any phy reset, just the chipidea
> controller wrapper reset bit, which should go into the wrapper node?

Ok, makes sense.

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 20/21] phy: Add support for Qualcomm's USB HSIC phy
@ 2016-06-29  9:16           ` Neil Armstrong
  0 siblings, 0 replies; 214+ messages in thread
From: Neil Armstrong @ 2016-06-29  9:16 UTC (permalink / raw)
  To: Stephen Boyd, linux-usb
  Cc: linux-arm-kernel, linux-kernel, linux-arm-msm, Andy Gross,
	Bjorn Andersson, Arnd Bergmann, Felipe Balbi,
	Kishon Vijay Abraham I, devicetree

On 06/28/2016 11:58 PM, Stephen Boyd wrote:
> Quoting Neil Armstrong (2016-06-28 01:49:37)
>> On 06/26/2016 09:28 AM, Stephen Boyd wrote:
>>> +     uphy->cal_sleep_clk = clk = devm_clk_get(&ulpi->dev, "cal_sleep");
>>> +     if (IS_ERR(clk))
>>> +             return PTR_ERR(clk);
>>
>> Hi Stephen,
>>
>> In the bindings the cal_sleep is marked optional, and I think should be since AFAIK
>> it's not present on MDM9615 for example.
> 
> The cal_sleep clk is just the sleep clk then (should be a board clk in
> DT). Sometimes there's a gate in GCC to allow us to turn it off, other
> times there isn't. Either way, it's always wired there so I'll update
> the binding to say it isn't optional.

Sorry I don't understand !
What should I do if GCC does not provide a gate here ? And looking at the driver, it could be optional.

> 
>>
>> Also MDM9615 HSIC requires "core", "alt-core", "phy", "cal" and "iface" clocks.
>> I assume "core" can be attributed to the main chipidea node, but I think "alt-core" and "iface" should be also optionnal.
> 
> Looking at the downstream sources I see this:
> 
>         "core_clk"     -> usb_hsic_sys_clk
>         "iface_clk"    -> usb_hsic_p_clk
>         "alt_core_clk" -> usb_hsic_xcvr_clk
> 
>         "cal_clk"      -> usb_hsic_hsio_cal_clk
>         "phy_clk"      -> usb_hsic_clk
> 
> "core_clk" would be the core clk in ci_hdrc_msm. "iface_clk" would be
> the iface clk in ci_hdrc_msm. "cal_clk" would be the cal clk in the hsic
> phy and "phy_clk" would be the phy clk in the hsic phy.
> 
> That leaves alt_core_clk which seems to be a clock that needs to be on
> during the reset assert/deassert and possibly for LPM and USB1.1 FS
> modes. Sometimes it's referred to as the "housekeeping" clk. Due to the
> way resets are done on msm8974 and later SoCs it looks like this clk was
> removed. I can make this an optional clk in the ci_hdrc_msm driver, or
> we can have two versions of the ci_hdrc_msm compatible string, one for a
> device that has the housekeeping clk and one for the device that
> doesn't.

Having it optional would be the best solution I think.

> 
>>
>> Finally, it misses an optional reset line AFAIK mandatory on MDM9615.
>>
> 
> From what I can tell downstream, all those clks point to the same bit 0
> of HSIC_RESET register? So there isn't any phy reset, just the chipidea
> controller wrapper reset bit, which should go into the wrapper node?

Ok, makes sense.

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

* [PATCH 20/21] phy: Add support for Qualcomm's USB HSIC phy
@ 2016-06-29  9:16           ` Neil Armstrong
  0 siblings, 0 replies; 214+ messages in thread
From: Neil Armstrong @ 2016-06-29  9:16 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/28/2016 11:58 PM, Stephen Boyd wrote:
> Quoting Neil Armstrong (2016-06-28 01:49:37)
>> On 06/26/2016 09:28 AM, Stephen Boyd wrote:
>>> +     uphy->cal_sleep_clk = clk = devm_clk_get(&ulpi->dev, "cal_sleep");
>>> +     if (IS_ERR(clk))
>>> +             return PTR_ERR(clk);
>>
>> Hi Stephen,
>>
>> In the bindings the cal_sleep is marked optional, and I think should be since AFAIK
>> it's not present on MDM9615 for example.
> 
> The cal_sleep clk is just the sleep clk then (should be a board clk in
> DT). Sometimes there's a gate in GCC to allow us to turn it off, other
> times there isn't. Either way, it's always wired there so I'll update
> the binding to say it isn't optional.

Sorry I don't understand !
What should I do if GCC does not provide a gate here ? And looking at the driver, it could be optional.

> 
>>
>> Also MDM9615 HSIC requires "core", "alt-core", "phy", "cal" and "iface" clocks.
>> I assume "core" can be attributed to the main chipidea node, but I think "alt-core" and "iface" should be also optionnal.
> 
> Looking at the downstream sources I see this:
> 
>         "core_clk"     -> usb_hsic_sys_clk
>         "iface_clk"    -> usb_hsic_p_clk
>         "alt_core_clk" -> usb_hsic_xcvr_clk
> 
>         "cal_clk"      -> usb_hsic_hsio_cal_clk
>         "phy_clk"      -> usb_hsic_clk
> 
> "core_clk" would be the core clk in ci_hdrc_msm. "iface_clk" would be
> the iface clk in ci_hdrc_msm. "cal_clk" would be the cal clk in the hsic
> phy and "phy_clk" would be the phy clk in the hsic phy.
> 
> That leaves alt_core_clk which seems to be a clock that needs to be on
> during the reset assert/deassert and possibly for LPM and USB1.1 FS
> modes. Sometimes it's referred to as the "housekeeping" clk. Due to the
> way resets are done on msm8974 and later SoCs it looks like this clk was
> removed. I can make this an optional clk in the ci_hdrc_msm driver, or
> we can have two versions of the ci_hdrc_msm compatible string, one for a
> device that has the housekeeping clk and one for the device that
> doesn't.

Having it optional would be the best solution I think.

> 
>>
>> Finally, it misses an optional reset line AFAIK mandatory on MDM9615.
>>
> 
> From what I can tell downstream, all those clks point to the same bit 0
> of HSIC_RESET register? So there isn't any phy reset, just the chipidea
> controller wrapper reset bit, which should go into the wrapper node?

Ok, makes sense.

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

* Re: [PATCH 17/21] usb: chipidea: msm: Make platform data driver local instead of global
  2016-06-26  7:28   ` Stephen Boyd
@ 2016-06-29 11:29     ` Peter Chen
  -1 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-29 11:29 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, linux-arm-kernel, linux-kernel, linux-arm-msm,
	Andy Gross, Bjorn Andersson, Neil Armstrong, Arnd Bergmann,
	Felipe Balbi, Peter Chen, Greg Kroah-Hartman

On Sun, Jun 26, 2016 at 12:28:34AM -0700, Stephen Boyd wrote:
> If two devices are probed with this same driver, they'll share
> the same platform data structure, while the chipidea core layer
> writes and modifies it. This can lead to interesting results
> especially if one device is an OTG type chipidea controller and
> another is a host. Let's create a copy of this structure per each
> device instance so that odd things don't happen.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/ci_hdrc_msm.c | 19 ++++++++-----------
>  1 file changed, 8 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> index cc6f9b0df9d5..fb4340f02c16 100644
> --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> @@ -37,6 +37,7 @@ struct ci_hdrc_msm {
>  	struct clk *core_clk;
>  	struct clk *iface_clk;
>  	struct extcon_dev *vbus_edev;
> +	struct ci_hdrc_platform_data pdata;
>  	bool secondary_phy;
>  	bool hsic;
>  	void __iomem *base;
> @@ -79,16 +80,6 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
>  	}
>  }
>  
> -static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
> -	.name			= "ci_hdrc_msm",
> -	.capoffset		= DEF_CAPOFFSET,
> -	.flags			= CI_HDRC_REGS_SHARED |
> -				  CI_HDRC_DISABLE_STREAMING |
> -				  CI_HDRC_OVERRIDE_AHB_BURST,
> -
> -	.notify_event		= ci_hdrc_msm_notify_event,
> -};
> -
>  static int ci_hdrc_msm_mux_phy(struct ci_hdrc_msm *ci,
>  			       struct platform_device *pdev)
>  {
> @@ -151,6 +142,12 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  		return -ENOMEM;
>  	platform_set_drvdata(pdev, ci);
>  
> +	ci->pdata.name = "ci_hdrc_msm";
> +	ci->pdata.capoffset = DEF_CAPOFFSET;
> +	ci->pdata.flags	= CI_HDRC_REGS_SHARED | CI_HDRC_DISABLE_STREAMING |
> +			  CI_HDRC_OVERRIDE_AHB_BURST;
> +	ci->pdata.notify_event = ci_hdrc_msm_notify_event;
> +
>  	reset = devm_reset_control_get(&pdev->dev, "core");
>  	if (IS_ERR(reset))
>  		return PTR_ERR(reset);
> @@ -204,7 +201,7 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  	of_node_put(ulpi_node);
>  
>  	plat_ci = ci_hdrc_add_device(&pdev->dev, pdev->resource,
> -				     pdev->num_resources, &ci_hdrc_msm_platdata);
> +				     pdev->num_resources, &ci->pdata);
>  	if (IS_ERR(plat_ci)) {
>  		dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
>  		ret = PTR_ERR(plat_ci);

You can do something like ci_hdrc_usb2.c, it looks simpler. 

-- 

Best Regards,
Peter Chen

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

* [PATCH 17/21] usb: chipidea: msm: Make platform data driver local instead of global
@ 2016-06-29 11:29     ` Peter Chen
  0 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-29 11:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Jun 26, 2016 at 12:28:34AM -0700, Stephen Boyd wrote:
> If two devices are probed with this same driver, they'll share
> the same platform data structure, while the chipidea core layer
> writes and modifies it. This can lead to interesting results
> especially if one device is an OTG type chipidea controller and
> another is a host. Let's create a copy of this structure per each
> device instance so that odd things don't happen.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/ci_hdrc_msm.c | 19 ++++++++-----------
>  1 file changed, 8 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> index cc6f9b0df9d5..fb4340f02c16 100644
> --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> @@ -37,6 +37,7 @@ struct ci_hdrc_msm {
>  	struct clk *core_clk;
>  	struct clk *iface_clk;
>  	struct extcon_dev *vbus_edev;
> +	struct ci_hdrc_platform_data pdata;
>  	bool secondary_phy;
>  	bool hsic;
>  	void __iomem *base;
> @@ -79,16 +80,6 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
>  	}
>  }
>  
> -static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
> -	.name			= "ci_hdrc_msm",
> -	.capoffset		= DEF_CAPOFFSET,
> -	.flags			= CI_HDRC_REGS_SHARED |
> -				  CI_HDRC_DISABLE_STREAMING |
> -				  CI_HDRC_OVERRIDE_AHB_BURST,
> -
> -	.notify_event		= ci_hdrc_msm_notify_event,
> -};
> -
>  static int ci_hdrc_msm_mux_phy(struct ci_hdrc_msm *ci,
>  			       struct platform_device *pdev)
>  {
> @@ -151,6 +142,12 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  		return -ENOMEM;
>  	platform_set_drvdata(pdev, ci);
>  
> +	ci->pdata.name = "ci_hdrc_msm";
> +	ci->pdata.capoffset = DEF_CAPOFFSET;
> +	ci->pdata.flags	= CI_HDRC_REGS_SHARED | CI_HDRC_DISABLE_STREAMING |
> +			  CI_HDRC_OVERRIDE_AHB_BURST;
> +	ci->pdata.notify_event = ci_hdrc_msm_notify_event;
> +
>  	reset = devm_reset_control_get(&pdev->dev, "core");
>  	if (IS_ERR(reset))
>  		return PTR_ERR(reset);
> @@ -204,7 +201,7 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  	of_node_put(ulpi_node);
>  
>  	plat_ci = ci_hdrc_add_device(&pdev->dev, pdev->resource,
> -				     pdev->num_resources, &ci_hdrc_msm_platdata);
> +				     pdev->num_resources, &ci->pdata);
>  	if (IS_ERR(plat_ci)) {
>  		dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
>  		ret = PTR_ERR(plat_ci);

You can do something like ci_hdrc_usb2.c, it looks simpler. 

-- 

Best Regards,
Peter Chen

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

* Re: [PATCH 13/21] usb: chipidea: msm: Allow core to get usb phy
  2016-06-29  6:48     ` Peter Chen
@ 2016-06-29 11:34       ` Peter Chen
  -1 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-29 11:34 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, linux-arm-kernel, linux-kernel, linux-arm-msm,
	Andy Gross, Bjorn Andersson, Neil Armstrong, Arnd Bergmann,
	Felipe Balbi, Peter Chen, Greg Kroah-Hartman

On Wed, Jun 29, 2016 at 02:48:11PM +0800, Peter Chen wrote:
> On Sun, Jun 26, 2016 at 12:28:30AM -0700, Stephen Boyd wrote:
> > The chipidea core gets the usb phy and initializes the phy at the
> > right point now so we don't need to get the phy in this driver.
> > 
> > Cc: Peter Chen <peter.chen@nxp.com>
> > Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> > ---
> >  drivers/usb/chipidea/ci_hdrc_msm.c | 21 ---------------------
> >  1 file changed, 21 deletions(-)
> > 
> > diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> > index 430856ef1be3..07cccd24a87f 100644
> > --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> > +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> > @@ -24,15 +24,6 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
> >  		dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
> >  		/* use AHB transactor, allow posted data writes */
> >  		hw_write_id_reg(ci, HS_PHY_AHB_MODE, 0xffffffff, 0x8);
> > -		usb_phy_init(ci->usb_phy);
> > -		break;
> > -	case CI_HDRC_CONTROLLER_STOPPED_EVENT:
> > -		dev_dbg(dev, "CI_HDRC_CONTROLLER_STOPPED_EVENT received\n");
> > -		/*
> > -		 * Put the phy in non-driving mode. Otherwise host
> > -		 * may not detect soft-disconnection.
> > -		 */
> > -		usb_phy_notify_disconnect(ci->usb_phy, USB_SPEED_UNKNOWN);
> >  		break;
> >  	default:
> >  		dev_dbg(dev, "unknown ci_hdrc event\n");
> > @@ -53,21 +44,9 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
> >  static int ci_hdrc_msm_probe(struct platform_device *pdev)
> >  {
> >  	struct platform_device *plat_ci;
> > -	struct usb_phy *phy;
> >  
> >  	dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
> >  
> > -	/*
> > -	 * OTG(PHY) driver takes care of PHY initialization, clock management,
> > -	 * powering up VBUS, mapping of registers address space and power
> > -	 * management.
> > -	 */
> > -	phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0);
> > -	if (IS_ERR(phy))
> > -		return PTR_ERR(phy);
> > -
> > -	ci_hdrc_msm_platdata.usb_phy = phy;
> > -
> >  	plat_ci = ci_hdrc_add_device(&pdev->dev,
> >  				pdev->resource, pdev->num_resources,
> >  				&ci_hdrc_msm_platdata);
> > -- 
> 

Wait, how about the UTMI PHY? You don't have a platform which needs
to get PHY through the phandle?

-- 

Best Regards,
Peter Chen

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

* [PATCH 13/21] usb: chipidea: msm: Allow core to get usb phy
@ 2016-06-29 11:34       ` Peter Chen
  0 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-29 11:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jun 29, 2016 at 02:48:11PM +0800, Peter Chen wrote:
> On Sun, Jun 26, 2016 at 12:28:30AM -0700, Stephen Boyd wrote:
> > The chipidea core gets the usb phy and initializes the phy at the
> > right point now so we don't need to get the phy in this driver.
> > 
> > Cc: Peter Chen <peter.chen@nxp.com>
> > Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> > ---
> >  drivers/usb/chipidea/ci_hdrc_msm.c | 21 ---------------------
> >  1 file changed, 21 deletions(-)
> > 
> > diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> > index 430856ef1be3..07cccd24a87f 100644
> > --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> > +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> > @@ -24,15 +24,6 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
> >  		dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
> >  		/* use AHB transactor, allow posted data writes */
> >  		hw_write_id_reg(ci, HS_PHY_AHB_MODE, 0xffffffff, 0x8);
> > -		usb_phy_init(ci->usb_phy);
> > -		break;
> > -	case CI_HDRC_CONTROLLER_STOPPED_EVENT:
> > -		dev_dbg(dev, "CI_HDRC_CONTROLLER_STOPPED_EVENT received\n");
> > -		/*
> > -		 * Put the phy in non-driving mode. Otherwise host
> > -		 * may not detect soft-disconnection.
> > -		 */
> > -		usb_phy_notify_disconnect(ci->usb_phy, USB_SPEED_UNKNOWN);
> >  		break;
> >  	default:
> >  		dev_dbg(dev, "unknown ci_hdrc event\n");
> > @@ -53,21 +44,9 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
> >  static int ci_hdrc_msm_probe(struct platform_device *pdev)
> >  {
> >  	struct platform_device *plat_ci;
> > -	struct usb_phy *phy;
> >  
> >  	dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
> >  
> > -	/*
> > -	 * OTG(PHY) driver takes care of PHY initialization, clock management,
> > -	 * powering up VBUS, mapping of registers address space and power
> > -	 * management.
> > -	 */
> > -	phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0);
> > -	if (IS_ERR(phy))
> > -		return PTR_ERR(phy);
> > -
> > -	ci_hdrc_msm_platdata.usb_phy = phy;
> > -
> >  	plat_ci = ci_hdrc_add_device(&pdev->dev,
> >  				pdev->resource, pdev->num_resources,
> >  				&ci_hdrc_msm_platdata);
> > -- 
> 

Wait, how about the UTMI PHY? You don't have a platform which needs
to get PHY through the phandle?

-- 

Best Regards,
Peter Chen

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

* Re: [PATCH 18/21] usb: chipidea: msm: Add reset controller for PHY POR bit
  2016-06-26  7:28   ` Stephen Boyd
@ 2016-06-29 11:45     ` Peter Chen
  -1 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-29 11:45 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, linux-arm-kernel, linux-kernel, linux-arm-msm,
	Andy Gross, Bjorn Andersson, Neil Armstrong, Arnd Bergmann,
	Felipe Balbi, Peter Chen, Greg Kroah-Hartman

On Sun, Jun 26, 2016 at 12:28:35AM -0700, Stephen Boyd wrote:
> The MSM chipidea wrapper has two bits that are used to reset the
> first or second phy. Add support for these bits via the reset
> controller framework, so that phy drivers can reset their
> hardware at the right time during initialization.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/ci_hdrc_msm.c | 43 +++++++++++++++++++++++++++++++++++++-
>  1 file changed, 42 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> index fb4340f02c16..7d191928e55b 100644
> --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> @@ -14,14 +14,17 @@
>  #include <linux/mfd/syscon.h>
>  #include <linux/regmap.h>
>  #include <linux/io.h>
> +#include <linux/reset-controller.h>
>  #include <linux/extcon.h>
>  #include <linux/of.h>
>  
>  #include "ci.h"
>  
>  #define HS_PHY_AHB_MODE			0x0098
> +#define HS_PHY_CTRL			0x0240
>  #define HS_PHY_SEC_CTRL			0x0278
>  # define HS_PHY_DIG_CLAMP_N		BIT(16)
> +# define HS_PHY_POR_ASSERT		BIT(0)
>  
>  #define HS_PHY_GENCONFIG		0x009c
>  # define HS_PHY_TXFIFO_IDLE_FORCE_DIS	BIT(4)
> @@ -38,11 +41,38 @@ struct ci_hdrc_msm {
>  	struct clk *iface_clk;
>  	struct extcon_dev *vbus_edev;
>  	struct ci_hdrc_platform_data pdata;
> +	struct reset_controller_dev rcdev;
>  	bool secondary_phy;
>  	bool hsic;
>  	void __iomem *base;
>  };
>  
> +static int
> +ci_hdrc_msm_por_reset(struct reset_controller_dev *r, unsigned long id)
> +{
> +	struct ci_hdrc_msm *ci_msm = container_of(r, struct ci_hdrc_msm, rcdev);
> +	void __iomem *addr = ci_msm->base;

Like I mentioned at previous email, you can use vendor base for
0x200.

> +	u32 val;
> +
> +	if (id)
> +		addr += HS_PHY_SEC_CTRL;
> +	else
> +		addr += HS_PHY_CTRL;
> +
> +	val = readl_relaxed(addr);
> +	val |= HS_PHY_POR_ASSERT;
> +	writel_relaxed(val, addr);
> +	udelay(12);
> +	val &= ~HS_PHY_POR_ASSERT;
> +	writel(val, addr);
> +
> +	return 0;
> +}
> +
> +static const struct reset_control_ops ci_hdrc_msm_reset_ops = {
> +	.reset = ci_hdrc_msm_por_reset,
> +};
> +
>  static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
>  {
>  	struct device *dev = ci->dev->parent;
> @@ -176,13 +206,21 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  		ci->vbus_edev = NULL;
>  	}
>  
> +	ci->rcdev.owner = THIS_MODULE;
> +	ci->rcdev.ops = &ci_hdrc_msm_reset_ops;
> +	ci->rcdev.of_node = pdev->dev.of_node;
> +	ci->rcdev.nr_resets = 2;
> +	ret = reset_controller_register(&ci->rcdev);
> +	if (ret)
> +		return ret;
> +
>  	reset_control_assert(reset);
>  	usleep_range(10000, 12000);
>  	reset_control_deassert(reset);
>  
>  	ret = clk_prepare_enable(ci->core_clk);
>  	if (ret)
> -		return ret;
> +		goto err_core;
>  
>  	ret = clk_prepare_enable(ci->iface_clk);
>  	if (ret)
> @@ -220,6 +258,8 @@ err_mux:
>  	clk_disable_unprepare(ci->iface_clk);
>  err_iface:
>  	clk_disable_unprepare(ci->core_clk);
> +err_core:
> +	reset_controller_unregister(&ci->rcdev);
>  	return ret;
>  }
>  
> @@ -232,6 +272,7 @@ static int ci_hdrc_msm_remove(struct platform_device *pdev)
>  	ci_hdrc_remove_device(ci->ci);
>  	clk_disable_unprepare(ci->iface_clk);
>  	clk_disable_unprepare(ci->core_clk);
> +	reset_controller_unregister(&ci->rcdev);
>  
>  	return 0;
>  }
> -- 
> 2.9.0.rc2.8.ga28705d
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 

Best Regards,
Peter Chen

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

* [PATCH 18/21] usb: chipidea: msm: Add reset controller for PHY POR bit
@ 2016-06-29 11:45     ` Peter Chen
  0 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-29 11:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Jun 26, 2016 at 12:28:35AM -0700, Stephen Boyd wrote:
> The MSM chipidea wrapper has two bits that are used to reset the
> first or second phy. Add support for these bits via the reset
> controller framework, so that phy drivers can reset their
> hardware at the right time during initialization.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/ci_hdrc_msm.c | 43 +++++++++++++++++++++++++++++++++++++-
>  1 file changed, 42 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> index fb4340f02c16..7d191928e55b 100644
> --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> @@ -14,14 +14,17 @@
>  #include <linux/mfd/syscon.h>
>  #include <linux/regmap.h>
>  #include <linux/io.h>
> +#include <linux/reset-controller.h>
>  #include <linux/extcon.h>
>  #include <linux/of.h>
>  
>  #include "ci.h"
>  
>  #define HS_PHY_AHB_MODE			0x0098
> +#define HS_PHY_CTRL			0x0240
>  #define HS_PHY_SEC_CTRL			0x0278
>  # define HS_PHY_DIG_CLAMP_N		BIT(16)
> +# define HS_PHY_POR_ASSERT		BIT(0)
>  
>  #define HS_PHY_GENCONFIG		0x009c
>  # define HS_PHY_TXFIFO_IDLE_FORCE_DIS	BIT(4)
> @@ -38,11 +41,38 @@ struct ci_hdrc_msm {
>  	struct clk *iface_clk;
>  	struct extcon_dev *vbus_edev;
>  	struct ci_hdrc_platform_data pdata;
> +	struct reset_controller_dev rcdev;
>  	bool secondary_phy;
>  	bool hsic;
>  	void __iomem *base;
>  };
>  
> +static int
> +ci_hdrc_msm_por_reset(struct reset_controller_dev *r, unsigned long id)
> +{
> +	struct ci_hdrc_msm *ci_msm = container_of(r, struct ci_hdrc_msm, rcdev);
> +	void __iomem *addr = ci_msm->base;

Like I mentioned at previous email, you can use vendor base for
0x200.

> +	u32 val;
> +
> +	if (id)
> +		addr += HS_PHY_SEC_CTRL;
> +	else
> +		addr += HS_PHY_CTRL;
> +
> +	val = readl_relaxed(addr);
> +	val |= HS_PHY_POR_ASSERT;
> +	writel_relaxed(val, addr);
> +	udelay(12);
> +	val &= ~HS_PHY_POR_ASSERT;
> +	writel(val, addr);
> +
> +	return 0;
> +}
> +
> +static const struct reset_control_ops ci_hdrc_msm_reset_ops = {
> +	.reset = ci_hdrc_msm_por_reset,
> +};
> +
>  static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
>  {
>  	struct device *dev = ci->dev->parent;
> @@ -176,13 +206,21 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  		ci->vbus_edev = NULL;
>  	}
>  
> +	ci->rcdev.owner = THIS_MODULE;
> +	ci->rcdev.ops = &ci_hdrc_msm_reset_ops;
> +	ci->rcdev.of_node = pdev->dev.of_node;
> +	ci->rcdev.nr_resets = 2;
> +	ret = reset_controller_register(&ci->rcdev);
> +	if (ret)
> +		return ret;
> +
>  	reset_control_assert(reset);
>  	usleep_range(10000, 12000);
>  	reset_control_deassert(reset);
>  
>  	ret = clk_prepare_enable(ci->core_clk);
>  	if (ret)
> -		return ret;
> +		goto err_core;
>  
>  	ret = clk_prepare_enable(ci->iface_clk);
>  	if (ret)
> @@ -220,6 +258,8 @@ err_mux:
>  	clk_disable_unprepare(ci->iface_clk);
>  err_iface:
>  	clk_disable_unprepare(ci->core_clk);
> +err_core:
> +	reset_controller_unregister(&ci->rcdev);
>  	return ret;
>  }
>  
> @@ -232,6 +272,7 @@ static int ci_hdrc_msm_remove(struct platform_device *pdev)
>  	ci_hdrc_remove_device(ci->ci);
>  	clk_disable_unprepare(ci->iface_clk);
>  	clk_disable_unprepare(ci->core_clk);
> +	reset_controller_unregister(&ci->rcdev);
>  
>  	return 0;
>  }
> -- 
> 2.9.0.rc2.8.ga28705d
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 

Best Regards,
Peter Chen

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

* Re: [PATCH 20/21] phy: Add support for Qualcomm's USB HSIC phy
  2016-06-29  9:16           ` Neil Armstrong
  (?)
@ 2016-06-29 18:54               ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-29 18:54 UTC (permalink / raw)
  To: Neil Armstrong, linux-usb-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA, Andy Gross,
	Bjorn Andersson, Arnd Bergmann, Felipe Balbi,
	Kishon Vijay Abraham I, devicetree-u79uwXL29TY76Z2rM5mHXA

Quoting Neil Armstrong (2016-06-29 02:16:51)
> On 06/28/2016 11:58 PM, Stephen Boyd wrote:
> > Quoting Neil Armstrong (2016-06-28 01:49:37)
> >> On 06/26/2016 09:28 AM, Stephen Boyd wrote:
> >>> +     uphy->cal_sleep_clk = clk = devm_clk_get(&ulpi->dev, "cal_sleep");
> >>> +     if (IS_ERR(clk))
> >>> +             return PTR_ERR(clk);
> >>
> >> Hi Stephen,
> >>
> >> In the bindings the cal_sleep is marked optional, and I think should be since AFAIK
> >> it's not present on MDM9615 for example.
> > 
> > The cal_sleep clk is just the sleep clk then (should be a board clk in
> > DT). Sometimes there's a gate in GCC to allow us to turn it off, other
> > times there isn't. Either way, it's always wired there so I'll update
> > the binding to say it isn't optional.
> 
> Sorry I don't understand !
> What should I do if GCC does not provide a gate here ? And looking at the driver, it could be optional.

You should set the property to point to &sleep_clk which should be under
the "clocks" node at the root of the OF tree. For example, see the
sleep_clk node in arch/arm/boot/dts/qcom-apq8064.dtsi.
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 20/21] phy: Add support for Qualcomm's USB HSIC phy
@ 2016-06-29 18:54               ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-29 18:54 UTC (permalink / raw)
  To: Neil Armstrong, linux-usb
  Cc: linux-arm-kernel, linux-kernel, linux-arm-msm, Andy Gross,
	Bjorn Andersson, Arnd Bergmann, Felipe Balbi,
	Kishon Vijay Abraham I, devicetree

Quoting Neil Armstrong (2016-06-29 02:16:51)
> On 06/28/2016 11:58 PM, Stephen Boyd wrote:
> > Quoting Neil Armstrong (2016-06-28 01:49:37)
> >> On 06/26/2016 09:28 AM, Stephen Boyd wrote:
> >>> +     uphy->cal_sleep_clk = clk = devm_clk_get(&ulpi->dev, "cal_sleep");
> >>> +     if (IS_ERR(clk))
> >>> +             return PTR_ERR(clk);
> >>
> >> Hi Stephen,
> >>
> >> In the bindings the cal_sleep is marked optional, and I think should be since AFAIK
> >> it's not present on MDM9615 for example.
> > 
> > The cal_sleep clk is just the sleep clk then (should be a board clk in
> > DT). Sometimes there's a gate in GCC to allow us to turn it off, other
> > times there isn't. Either way, it's always wired there so I'll update
> > the binding to say it isn't optional.
> 
> Sorry I don't understand !
> What should I do if GCC does not provide a gate here ? And looking at the driver, it could be optional.

You should set the property to point to &sleep_clk which should be under
the "clocks" node at the root of the OF tree. For example, see the
sleep_clk node in arch/arm/boot/dts/qcom-apq8064.dtsi.

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

* [PATCH 20/21] phy: Add support for Qualcomm's USB HSIC phy
@ 2016-06-29 18:54               ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-29 18:54 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Neil Armstrong (2016-06-29 02:16:51)
> On 06/28/2016 11:58 PM, Stephen Boyd wrote:
> > Quoting Neil Armstrong (2016-06-28 01:49:37)
> >> On 06/26/2016 09:28 AM, Stephen Boyd wrote:
> >>> +     uphy->cal_sleep_clk = clk = devm_clk_get(&ulpi->dev, "cal_sleep");
> >>> +     if (IS_ERR(clk))
> >>> +             return PTR_ERR(clk);
> >>
> >> Hi Stephen,
> >>
> >> In the bindings the cal_sleep is marked optional, and I think should be since AFAIK
> >> it's not present on MDM9615 for example.
> > 
> > The cal_sleep clk is just the sleep clk then (should be a board clk in
> > DT). Sometimes there's a gate in GCC to allow us to turn it off, other
> > times there isn't. Either way, it's always wired there so I'll update
> > the binding to say it isn't optional.
> 
> Sorry I don't understand !
> What should I do if GCC does not provide a gate here ? And looking at the driver, it could be optional.

You should set the property to point to &sleep_clk which should be under
the "clocks" node at the root of the OF tree. For example, see the
sleep_clk node in arch/arm/boot/dts/qcom-apq8064.dtsi.

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

* Re: [PATCH 10/21] usb: chipidea: msm: Rely on core to override AHBBURST
  2016-06-29  6:32     ` Peter Chen
@ 2016-06-29 18:59       ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-29 18:59 UTC (permalink / raw)
  To: Peter Chen
  Cc: Felipe Balbi, Arnd Bergmann, Neil Armstrong, linux-arm-msm,
	linux-usb, linux-kernel, Bjorn Andersson, Peter Chen,
	Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

Quoting Peter Chen (2016-06-28 23:32:11)
> On Sun, Jun 26, 2016 at 12:28:27AM -0700, Stephen Boyd wrote:
> > The core framework already handles setting this parameter with a
> > platform quirk. Add the appropriate flag so that we always set
> > AHBBURST to 0. Technically DT should be doing this, but we always
> > do it for msm chipidea devices so setting the flag in the driver
> > works just as well.
> 
> You still need to set AHB burst value at dts, this flag is just for
> override, see below:
> 
> ahb-burst-config = <0x0>;

Right, I have added that to dts now, but the CI_HDRC_OVERRIDE_AHB_BURST
flag allows us to specify it from the platdata structure in the
ci_hdrc_msm.c file. As the value is zero for msm type controllers, I
left it out of the static definition of platdata because all the
non-initialized members of that structure are going to be zero anyway. I
can explicitly set it to zero to make it more clear if you like.

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

* [PATCH 10/21] usb: chipidea: msm: Rely on core to override AHBBURST
@ 2016-06-29 18:59       ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-29 18:59 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Peter Chen (2016-06-28 23:32:11)
> On Sun, Jun 26, 2016 at 12:28:27AM -0700, Stephen Boyd wrote:
> > The core framework already handles setting this parameter with a
> > platform quirk. Add the appropriate flag so that we always set
> > AHBBURST to 0. Technically DT should be doing this, but we always
> > do it for msm chipidea devices so setting the flag in the driver
> > works just as well.
> 
> You still need to set AHB burst value at dts, this flag is just for
> override, see below:
> 
> ahb-burst-config = <0x0>;

Right, I have added that to dts now, but the CI_HDRC_OVERRIDE_AHB_BURST
flag allows us to specify it from the platdata structure in the
ci_hdrc_msm.c file. As the value is zero for msm type controllers, I
left it out of the static definition of platdata because all the
non-initialized members of that structure are going to be zero anyway. I
can explicitly set it to zero to make it more clear if you like.

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

* Re: [PATCH 16/21] usb: chipidea: msm: Restore wrapper settings after reset
  2016-06-29  8:26     ` Peter Chen
@ 2016-06-29 19:13       ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-29 19:13 UTC (permalink / raw)
  To: Peter Chen
  Cc: Felipe Balbi, Arnd Bergmann, Neil Armstrong, linux-arm-msm,
	linux-usb, linux-kernel, Bjorn Andersson, Peter Chen,
	Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

Quoting Peter Chen (2016-06-29 01:26:48)
> On Sun, Jun 26, 2016 at 12:28:33AM -0700, Stephen Boyd wrote:
> > When the RESET bit is set in the USBCMD register it resets quite
> > @@ -21,11 +23,22 @@
> >  #define HS_PHY_SEC_CTRL                      0x0278
> >  # define HS_PHY_DIG_CLAMP_N          BIT(16)
> >  
> > +#define HS_PHY_GENCONFIG             0x009c
> > +# define HS_PHY_TXFIFO_IDLE_FORCE_DIS        BIT(4)
> > +
> > +#define HS_PHY_GENCONFIG_2           0x00a0
> > +# define HS_PHY_SESS_VLD_CTRL_EN     BIT(7)
> > +# define HS_PHY_ULPI_TX_PKT_EN_CLR_FIX       BIT(19)
> > +
> > +#define HSPHY_SESS_VLD_CTRL          BIT(25)
> > +
> 
> Keep alignment please.

I take it this means it should look like:

#define HS_PHY_GENCONFIG
#define HS_PHY_TXFIFO_IDLE_FORCE_DIS

?

> > @@ -141,6 +172,13 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
> >       if (!base)
> >               return -ENOMEM;
> >  
> > +     ci->vbus_edev = extcon_get_edev_by_phandle(&pdev->dev, 0);
> > +     if (IS_ERR(ci->vbus_edev)) {
> > +             if (PTR_ERR(ci->vbus_edev) != -ENODEV)
> > +                     return PTR_ERR(ci->vbus_edev);
> > +             ci->vbus_edev = NULL;
> > +     }
> > +
> 
> Why not using ci->platdata->vbus_extcon directly?

Because ci->platdata->vbus_extcon is assigned after the child platform
driver probes, and we have no idea when that will happen from the
ci_hdrc_msm driver probe. If we try after ci_hdrc_add_device() we'll
race with the driver probe and only get the pointer sometimes.

> 
> >       reset_control_assert(reset);
> >       usleep_range(10000, 12000);
> >       reset_control_deassert(reset);
> > @@ -157,6 +195,14 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
> >       if (ret)
> >               goto err_mux;
> >  
> > +     ulpi_node = of_find_node_by_name(pdev->dev.of_node, "ulpi");
> > +     if (ulpi_node) {
> > +             phy_node = of_get_next_available_child(ulpi_node, NULL);
> > +             ci->hsic = of_device_is_compatible(phy_node, "qcom,usb-hsic-phy");
> > +             of_node_put(phy_node);
> > +     }
> > +     of_node_put(ulpi_node);
> > +
> 
> Just confirm with you that ci->platdata->phy_mode is not enough?

Right. The phy_mode is never set to HSIC. It's always ULPI.

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

* [PATCH 16/21] usb: chipidea: msm: Restore wrapper settings after reset
@ 2016-06-29 19:13       ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-29 19:13 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Peter Chen (2016-06-29 01:26:48)
> On Sun, Jun 26, 2016 at 12:28:33AM -0700, Stephen Boyd wrote:
> > When the RESET bit is set in the USBCMD register it resets quite
> > @@ -21,11 +23,22 @@
> >  #define HS_PHY_SEC_CTRL                      0x0278
> >  # define HS_PHY_DIG_CLAMP_N          BIT(16)
> >  
> > +#define HS_PHY_GENCONFIG             0x009c
> > +# define HS_PHY_TXFIFO_IDLE_FORCE_DIS        BIT(4)
> > +
> > +#define HS_PHY_GENCONFIG_2           0x00a0
> > +# define HS_PHY_SESS_VLD_CTRL_EN     BIT(7)
> > +# define HS_PHY_ULPI_TX_PKT_EN_CLR_FIX       BIT(19)
> > +
> > +#define HSPHY_SESS_VLD_CTRL          BIT(25)
> > +
> 
> Keep alignment please.

I take it this means it should look like:

#define HS_PHY_GENCONFIG
#define HS_PHY_TXFIFO_IDLE_FORCE_DIS

?

> > @@ -141,6 +172,13 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
> >       if (!base)
> >               return -ENOMEM;
> >  
> > +     ci->vbus_edev = extcon_get_edev_by_phandle(&pdev->dev, 0);
> > +     if (IS_ERR(ci->vbus_edev)) {
> > +             if (PTR_ERR(ci->vbus_edev) != -ENODEV)
> > +                     return PTR_ERR(ci->vbus_edev);
> > +             ci->vbus_edev = NULL;
> > +     }
> > +
> 
> Why not using ci->platdata->vbus_extcon directly?

Because ci->platdata->vbus_extcon is assigned after the child platform
driver probes, and we have no idea when that will happen from the
ci_hdrc_msm driver probe. If we try after ci_hdrc_add_device() we'll
race with the driver probe and only get the pointer sometimes.

> 
> >       reset_control_assert(reset);
> >       usleep_range(10000, 12000);
> >       reset_control_deassert(reset);
> > @@ -157,6 +195,14 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
> >       if (ret)
> >               goto err_mux;
> >  
> > +     ulpi_node = of_find_node_by_name(pdev->dev.of_node, "ulpi");
> > +     if (ulpi_node) {
> > +             phy_node = of_get_next_available_child(ulpi_node, NULL);
> > +             ci->hsic = of_device_is_compatible(phy_node, "qcom,usb-hsic-phy");
> > +             of_node_put(phy_node);
> > +     }
> > +     of_node_put(ulpi_node);
> > +
> 
> Just confirm with you that ci->platdata->phy_mode is not enough?

Right. The phy_mode is never set to HSIC. It's always ULPI.

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

* Re: [PATCH 17/21] usb: chipidea: msm: Make platform data driver local instead of global
  2016-06-29 11:29     ` Peter Chen
@ 2016-06-29 19:17       ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-29 19:17 UTC (permalink / raw)
  To: Peter Chen
  Cc: Felipe Balbi, Arnd Bergmann, Neil Armstrong, linux-arm-msm,
	linux-usb, linux-kernel, Bjorn Andersson, Peter Chen,
	Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

Quoting Peter Chen (2016-06-29 04:29:25)
> On Sun, Jun 26, 2016 at 12:28:34AM -0700, Stephen Boyd wrote:
> > @@ -204,7 +201,7 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
> >       of_node_put(ulpi_node);
> >  
> >       plat_ci = ci_hdrc_add_device(&pdev->dev, pdev->resource,
> > -                                  pdev->num_resources, &ci_hdrc_msm_platdata);
> > +                                  pdev->num_resources, &ci->pdata);
> >       if (IS_ERR(plat_ci)) {
> >               dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
> >               ret = PTR_ERR(plat_ci);
> 
> You can do something like ci_hdrc_usb2.c, it looks simpler. 
> 

Do what exactly? I'd rather not do a structure copy because that wastes
some memory for a structure that is just a template. We add some more
code here to assign values directly, but that is smaller size wise than
the large platdata structure that only has a few values set in it.

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

* [PATCH 17/21] usb: chipidea: msm: Make platform data driver local instead of global
@ 2016-06-29 19:17       ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-29 19:17 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Peter Chen (2016-06-29 04:29:25)
> On Sun, Jun 26, 2016 at 12:28:34AM -0700, Stephen Boyd wrote:
> > @@ -204,7 +201,7 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
> >       of_node_put(ulpi_node);
> >  
> >       plat_ci = ci_hdrc_add_device(&pdev->dev, pdev->resource,
> > -                                  pdev->num_resources, &ci_hdrc_msm_platdata);
> > +                                  pdev->num_resources, &ci->pdata);
> >       if (IS_ERR(plat_ci)) {
> >               dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
> >               ret = PTR_ERR(plat_ci);
> 
> You can do something like ci_hdrc_usb2.c, it looks simpler. 
> 

Do what exactly? I'd rather not do a structure copy because that wastes
some memory for a structure that is just a template. We add some more
code here to assign values directly, but that is smaller size wise than
the large platdata structure that only has a few values set in it.

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

* Re: [PATCH 15/21] usb: chipidea: msm: Mux over secondary phy at the right time
  2016-06-29  8:08     ` Peter Chen
@ 2016-06-29 19:28       ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-29 19:28 UTC (permalink / raw)
  To: Peter Chen
  Cc: Felipe Balbi, Arnd Bergmann, Neil Armstrong, linux-arm-msm,
	linux-usb, linux-kernel, Bjorn Andersson, Peter Chen,
	Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

Quoting Peter Chen (2016-06-29 01:08:52)
> On Sun, Jun 26, 2016 at 12:28:32AM -0700, Stephen Boyd wrote:
> > We need to pick the correct phy at runtime based on how the SoC
> > has been wired onto the board. If the secondary phy is used, take
> > it out of reset and mux over to it by writing into the TCSR
> > register. Make sure to do this on reset too, because this
> > register is reset to the default value (primary phy) after the
> > RESET bit is set in USBCMD.
> > 
> 
> I am curious when you need the secondary phy?
> 
> > Cc: Peter Chen <peter.chen@nxp.com>
> > Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> > ---
> >  drivers/usb/chipidea/ci_hdrc_msm.c | 78 +++++++++++++++++++++++++++++++++++---
> >  1 file changed, 73 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> > index 40249b0e3e93..df0f8b31db4f 100644
> > --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> > +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> > @@ -8,30 +8,40 @@
> >  #include <linux/module.h>
> >  #include <linux/platform_device.h>
> >  #include <linux/pm_runtime.h>
> > -#include <linux/usb/gadget.h>
> >  #include <linux/usb/chipidea.h>
> >  #include <linux/clk.h>
> >  #include <linux/reset.h>
> > +#include <linux/mfd/syscon.h>
> > +#include <linux/regmap.h>
> > +#include <linux/io.h>
> >  
> >  #include "ci.h"
> >  
> >  #define HS_PHY_AHB_MODE                      0x0098
> > +#define HS_PHY_SEC_CTRL                      0x0278
> > +# define HS_PHY_DIG_CLAMP_N          BIT(16)
> >  
> 
> One space at the beginning, and keep alignment.
> 
> >  struct ci_hdrc_msm {
> >       struct platform_device *ci;
> >       struct clk *core_clk;
> >       struct clk *iface_clk;
> > +     bool secondary_phy;
> > +     void __iomem *base;
> >  };
> >  
> >  static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
> >  {
> > -     struct device *dev = ci->gadget.dev.parent;
> > +     struct device *dev = ci->dev->parent;
> > +     struct ci_hdrc_msm *msm_ci = dev_get_drvdata(dev);
> >  
> >       switch (event) {
> >       case CI_HDRC_CONTROLLER_RESET_EVENT:
> >               dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
> >               /* use AHB transactor, allow posted data writes */
> >               hw_write_id_reg(ci, HS_PHY_AHB_MODE, 0xffffffff, 0x8);
> > +             if (msm_ci->secondary_phy)
> > +                     hw_write_id_reg(ci, HS_PHY_SEC_CTRL, HS_PHY_DIG_CLAMP_N,
> > +                                     HS_PHY_DIG_CLAMP_N);
> >               break;
> >       default:
> >               dev_dbg(dev, "unknown ci_hdrc event\n");
> > @@ -49,12 +59,58 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
> >       .notify_event           = ci_hdrc_msm_notify_event,
> >  };
> >  
> > +static int ci_hdrc_msm_mux_phy(struct ci_hdrc_msm *ci,
> > +                            struct platform_device *pdev)
> > +{
> > +     struct regmap *regmap;
> > +     struct device_node *syscon;
> > +     struct device *dev = &pdev->dev;
> > +     u32 off, val;
> > +     int ret;
> > +
> > +     syscon = of_parse_phandle(dev->of_node, "phy-select", 0);
> > +     if (!syscon)
> > +             return 0;
> > +
> > +     regmap = syscon_node_to_regmap(syscon);
> > +     if (IS_ERR(regmap))
> > +             return PTR_ERR(regmap);
> > +
> > +     ret = of_property_read_u32_index(dev->of_node, "phy-select", 1, &off);
> > +     if (ret < 0) {
> > +             dev_err(dev, "no offset in syscon\n");
> > +             return -EINVAL;
> > +     }
> > +
> > +     ret = of_property_read_u32_index(dev->of_node, "phy-select", 2, &val);
> > +     if (ret < 0) {
> > +             dev_err(dev, "no value in syscon\n");
> > +             return -EINVAL;
> > +     }
> > +
> > +     ret = regmap_write(regmap, off, val);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ci->secondary_phy = !!val;
> > +     if (ci->secondary_phy) {
> > +             val = readl_relaxed(ci->base + HS_PHY_SEC_CTRL);
> > +             val |= HS_PHY_DIG_CLAMP_N;
> > +             writel_relaxed(val, ci->base + HS_PHY_SEC_CTRL);
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> >  static int ci_hdrc_msm_probe(struct platform_device *pdev)
> >  {
> >       struct ci_hdrc_msm *ci;
> >       struct platform_device *plat_ci;
> >       struct clk *clk;
> >       struct reset_control *reset;
> > +     struct resource *res;
> > +     void __iomem *base;
> > +     resource_size_t size;
> >       int ret;
> >  
> >       dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
> > @@ -76,6 +132,15 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
> >       if (IS_ERR(clk))
> >               return PTR_ERR(clk);
> >  
> > +     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +     if (!res)
> > +             return -ENODEV;
> > +
> > +     size = resource_size(res);
> > +     ci->base = base = devm_ioremap(&pdev->dev, res->start, size);
> > +     if (!base)
> > +             return -ENOMEM;
> > +
> 
> The core will do the ioremap too, you can't remap io address two times.

You can ioremap an address twice, but it's not a great solution. On ARM,
at least, we detect the double mapping and return the same virtual
address the second time.

> The offset larger than 0x200 is vendor specific, you can map it as
> the second io region.

Ok. That would mean we need to adjust the binding then to have to reg
properties? Or we can limit the size of the resource in the core and the
size of the resource here can be bumped up by 0x200. So DT still says
one resource for the entire ci address space but we don't map anything
more than what we use. Something like this?

---8<----
diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
index 4c70fa6fdc34..1121cf3e3fdc 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -190,8 +190,9 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
 	if (!res)
 		return -ENODEV;
 
-	size = resource_size(res);
-	ci->base = base = devm_ioremap(&pdev->dev, res->start, size);
+	res->start += 0x200;
+	res->end -= 0x200;
+	ci->base = base = devm_ioremap_resource(&pdev->dev, res);
 	if (!base)
 		return -ENOMEM;
 
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 298029a9ffce..8f5782913b11 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -887,6 +887,8 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 	}
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (resource_size(res) > 0x200)
+		res->end = res->start + 0x200;
 	base = devm_ioremap_resource(dev, res);
 	if (IS_ERR(base))
 		return PTR_ERR(base);

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

* [PATCH 15/21] usb: chipidea: msm: Mux over secondary phy at the right time
@ 2016-06-29 19:28       ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-29 19:28 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Peter Chen (2016-06-29 01:08:52)
> On Sun, Jun 26, 2016 at 12:28:32AM -0700, Stephen Boyd wrote:
> > We need to pick the correct phy at runtime based on how the SoC
> > has been wired onto the board. If the secondary phy is used, take
> > it out of reset and mux over to it by writing into the TCSR
> > register. Make sure to do this on reset too, because this
> > register is reset to the default value (primary phy) after the
> > RESET bit is set in USBCMD.
> > 
> 
> I am curious when you need the secondary phy?
> 
> > Cc: Peter Chen <peter.chen@nxp.com>
> > Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> > ---
> >  drivers/usb/chipidea/ci_hdrc_msm.c | 78 +++++++++++++++++++++++++++++++++++---
> >  1 file changed, 73 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> > index 40249b0e3e93..df0f8b31db4f 100644
> > --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> > +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> > @@ -8,30 +8,40 @@
> >  #include <linux/module.h>
> >  #include <linux/platform_device.h>
> >  #include <linux/pm_runtime.h>
> > -#include <linux/usb/gadget.h>
> >  #include <linux/usb/chipidea.h>
> >  #include <linux/clk.h>
> >  #include <linux/reset.h>
> > +#include <linux/mfd/syscon.h>
> > +#include <linux/regmap.h>
> > +#include <linux/io.h>
> >  
> >  #include "ci.h"
> >  
> >  #define HS_PHY_AHB_MODE                      0x0098
> > +#define HS_PHY_SEC_CTRL                      0x0278
> > +# define HS_PHY_DIG_CLAMP_N          BIT(16)
> >  
> 
> One space at the beginning, and keep alignment.
> 
> >  struct ci_hdrc_msm {
> >       struct platform_device *ci;
> >       struct clk *core_clk;
> >       struct clk *iface_clk;
> > +     bool secondary_phy;
> > +     void __iomem *base;
> >  };
> >  
> >  static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
> >  {
> > -     struct device *dev = ci->gadget.dev.parent;
> > +     struct device *dev = ci->dev->parent;
> > +     struct ci_hdrc_msm *msm_ci = dev_get_drvdata(dev);
> >  
> >       switch (event) {
> >       case CI_HDRC_CONTROLLER_RESET_EVENT:
> >               dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
> >               /* use AHB transactor, allow posted data writes */
> >               hw_write_id_reg(ci, HS_PHY_AHB_MODE, 0xffffffff, 0x8);
> > +             if (msm_ci->secondary_phy)
> > +                     hw_write_id_reg(ci, HS_PHY_SEC_CTRL, HS_PHY_DIG_CLAMP_N,
> > +                                     HS_PHY_DIG_CLAMP_N);
> >               break;
> >       default:
> >               dev_dbg(dev, "unknown ci_hdrc event\n");
> > @@ -49,12 +59,58 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
> >       .notify_event           = ci_hdrc_msm_notify_event,
> >  };
> >  
> > +static int ci_hdrc_msm_mux_phy(struct ci_hdrc_msm *ci,
> > +                            struct platform_device *pdev)
> > +{
> > +     struct regmap *regmap;
> > +     struct device_node *syscon;
> > +     struct device *dev = &pdev->dev;
> > +     u32 off, val;
> > +     int ret;
> > +
> > +     syscon = of_parse_phandle(dev->of_node, "phy-select", 0);
> > +     if (!syscon)
> > +             return 0;
> > +
> > +     regmap = syscon_node_to_regmap(syscon);
> > +     if (IS_ERR(regmap))
> > +             return PTR_ERR(regmap);
> > +
> > +     ret = of_property_read_u32_index(dev->of_node, "phy-select", 1, &off);
> > +     if (ret < 0) {
> > +             dev_err(dev, "no offset in syscon\n");
> > +             return -EINVAL;
> > +     }
> > +
> > +     ret = of_property_read_u32_index(dev->of_node, "phy-select", 2, &val);
> > +     if (ret < 0) {
> > +             dev_err(dev, "no value in syscon\n");
> > +             return -EINVAL;
> > +     }
> > +
> > +     ret = regmap_write(regmap, off, val);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ci->secondary_phy = !!val;
> > +     if (ci->secondary_phy) {
> > +             val = readl_relaxed(ci->base + HS_PHY_SEC_CTRL);
> > +             val |= HS_PHY_DIG_CLAMP_N;
> > +             writel_relaxed(val, ci->base + HS_PHY_SEC_CTRL);
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> >  static int ci_hdrc_msm_probe(struct platform_device *pdev)
> >  {
> >       struct ci_hdrc_msm *ci;
> >       struct platform_device *plat_ci;
> >       struct clk *clk;
> >       struct reset_control *reset;
> > +     struct resource *res;
> > +     void __iomem *base;
> > +     resource_size_t size;
> >       int ret;
> >  
> >       dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
> > @@ -76,6 +132,15 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
> >       if (IS_ERR(clk))
> >               return PTR_ERR(clk);
> >  
> > +     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +     if (!res)
> > +             return -ENODEV;
> > +
> > +     size = resource_size(res);
> > +     ci->base = base = devm_ioremap(&pdev->dev, res->start, size);
> > +     if (!base)
> > +             return -ENOMEM;
> > +
> 
> The core will do the ioremap too, you can't remap io address two times.

You can ioremap an address twice, but it's not a great solution. On ARM,
at least, we detect the double mapping and return the same virtual
address the second time.

> The offset larger than 0x200 is vendor specific, you can map it as
> the second io region.

Ok. That would mean we need to adjust the binding then to have to reg
properties? Or we can limit the size of the resource in the core and the
size of the resource here can be bumped up by 0x200. So DT still says
one resource for the entire ci address space but we don't map anything
more than what we use. Something like this?

---8<----
diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
index 4c70fa6fdc34..1121cf3e3fdc 100644
--- a/drivers/usb/chipidea/ci_hdrc_msm.c
+++ b/drivers/usb/chipidea/ci_hdrc_msm.c
@@ -190,8 +190,9 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
 	if (!res)
 		return -ENODEV;
 
-	size = resource_size(res);
-	ci->base = base = devm_ioremap(&pdev->dev, res->start, size);
+	res->start += 0x200;
+	res->end -= 0x200;
+	ci->base = base = devm_ioremap_resource(&pdev->dev, res);
 	if (!base)
 		return -ENOMEM;
 
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 298029a9ffce..8f5782913b11 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -887,6 +887,8 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 	}
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (resource_size(res) > 0x200)
+		res->end = res->start + 0x200;
 	base = devm_ioremap_resource(dev, res);
 	if (IS_ERR(base))
 		return PTR_ERR(base);

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

* Re: [PATCH 13/21] usb: chipidea: msm: Allow core to get usb phy
  2016-06-29 11:34       ` Peter Chen
@ 2016-06-29 19:31         ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-29 19:31 UTC (permalink / raw)
  To: Peter Chen
  Cc: Felipe Balbi, Arnd Bergmann, Neil Armstrong, linux-arm-msm,
	linux-usb, linux-kernel, Bjorn Andersson, Peter Chen,
	Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

Quoting Peter Chen (2016-06-29 04:34:11)
> On Wed, Jun 29, 2016 at 02:48:11PM +0800, Peter Chen wrote:
> > On Sun, Jun 26, 2016 at 12:28:30AM -0700, Stephen Boyd wrote:
> > > @@ -53,21 +44,9 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
> > >  static int ci_hdrc_msm_probe(struct platform_device *pdev)
> > >  {
> > >     struct platform_device *plat_ci;
> > > -   struct usb_phy *phy;
> > >  
> > >     dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
> > >  
> > > -   /*
> > > -    * OTG(PHY) driver takes care of PHY initialization, clock management,
> > > -    * powering up VBUS, mapping of registers address space and power
> > > -    * management.
> > > -    */
> > > -   phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0);
> > > -   if (IS_ERR(phy))
> > > -           return PTR_ERR(phy);
> > > -
> > > -   ci_hdrc_msm_platdata.usb_phy = phy;
> > > -
> > >     plat_ci = ci_hdrc_add_device(&pdev->dev,
> > >                             pdev->resource, pdev->num_resources,
> > >                             &ci_hdrc_msm_platdata);
> > > -- 
> > 
> 
> Wait, how about the UTMI PHY? You don't have a platform which needs
> to get PHY through the phandle?

Sorry I don't understand the question. What is the UTMI PHY? We need to
get the phy through phandles. The only boards that are using ci_hdrc_msm
are DT enabled boards.

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

* [PATCH 13/21] usb: chipidea: msm: Allow core to get usb phy
@ 2016-06-29 19:31         ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-29 19:31 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Peter Chen (2016-06-29 04:34:11)
> On Wed, Jun 29, 2016 at 02:48:11PM +0800, Peter Chen wrote:
> > On Sun, Jun 26, 2016 at 12:28:30AM -0700, Stephen Boyd wrote:
> > > @@ -53,21 +44,9 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
> > >  static int ci_hdrc_msm_probe(struct platform_device *pdev)
> > >  {
> > >     struct platform_device *plat_ci;
> > > -   struct usb_phy *phy;
> > >  
> > >     dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
> > >  
> > > -   /*
> > > -    * OTG(PHY) driver takes care of PHY initialization, clock management,
> > > -    * powering up VBUS, mapping of registers address space and power
> > > -    * management.
> > > -    */
> > > -   phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0);
> > > -   if (IS_ERR(phy))
> > > -           return PTR_ERR(phy);
> > > -
> > > -   ci_hdrc_msm_platdata.usb_phy = phy;
> > > -
> > >     plat_ci = ci_hdrc_add_device(&pdev->dev,
> > >                             pdev->resource, pdev->num_resources,
> > >                             &ci_hdrc_msm_platdata);
> > > -- 
> > 
> 
> Wait, how about the UTMI PHY? You don't have a platform which needs
> to get PHY through the phandle?

Sorry I don't understand the question. What is the UTMI PHY? We need to
get the phy through phandles. The only boards that are using ci_hdrc_msm
are DT enabled boards.

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

* Re: [PATCH 12/21] usb: chipidea: msm: Keep device runtime enabled
  2016-06-29  6:46     ` Peter Chen
@ 2016-06-30  0:43       ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-30  0:43 UTC (permalink / raw)
  To: Peter Chen
  Cc: Felipe Balbi, Arnd Bergmann, Neil Armstrong, linux-arm-msm,
	linux-pm, linux-usb, linux-kernel, Bjorn Andersson, Peter Chen,
	Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

Quoting Peter Chen (2016-06-28 23:46:00)
> On Sun, Jun 26, 2016 at 12:28:29AM -0700, Stephen Boyd wrote:
> > Sometimes the usb wrapper device is part of a power domain that
> > needs to stay on as long as the device is active. Let's get and
> > put the device in driver probe/remove so that we keep the power
> > domain powered as long as the device is attached. We can fine
> > tune this later to handle wakeup interrupts, etc. for finer grain
> > power management later, but this is necessary to make sure we can
> > keep accessing the device right now.
> 
> Since some of the controllers work abnormal if we enables runtime
> pm unconditionally, so I use one system flag CI_HDRC_SUPPORTS_RUNTIME_PM
> for it. I can't understand why you can't access device without enable
> parent's runtime pm, the controller will not enter runtime suspend
> without that flag.

Correct, the child device of ci_hdrc_msm will be able to do runtime PM
and keep the parent enabled if the CI_HDRC_SUPPORTS_RUNTIME_PM flag is
set. But even if that flag isn't set, the ci_hdrc_msm driver is calling
pm_runtime_enable() on the same device that it would be called on if the
CI_HDRC_SUPPORTS_RUNTIME_PM flag was set. That allows runtime PM
transition of child devices such as the usb ports (usb1-port1 for
example) to propagate up all the way to the ci_hdrc_msm device and
disable any attached power domains.

Why don't we call runtime PM functions on the ci->dev for all cases of
ci->supports_runtime_pm? It seems like the glue drivers should be
managing their own device power states and the ci->dev should be managed
by core.c code.

Another solution would be to remove the call to pm_runtime_enable() from
ci_hdrc_msm. That would make sure we don't call the power domain code
when the device changes runtime PM states and rely on the fact that
power domains are turned on during device driver probe.

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

* [PATCH 12/21] usb: chipidea: msm: Keep device runtime enabled
@ 2016-06-30  0:43       ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-30  0:43 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Peter Chen (2016-06-28 23:46:00)
> On Sun, Jun 26, 2016 at 12:28:29AM -0700, Stephen Boyd wrote:
> > Sometimes the usb wrapper device is part of a power domain that
> > needs to stay on as long as the device is active. Let's get and
> > put the device in driver probe/remove so that we keep the power
> > domain powered as long as the device is attached. We can fine
> > tune this later to handle wakeup interrupts, etc. for finer grain
> > power management later, but this is necessary to make sure we can
> > keep accessing the device right now.
> 
> Since some of the controllers work abnormal if we enables runtime
> pm unconditionally, so I use one system flag CI_HDRC_SUPPORTS_RUNTIME_PM
> for it. I can't understand why you can't access device without enable
> parent's runtime pm, the controller will not enter runtime suspend
> without that flag.

Correct, the child device of ci_hdrc_msm will be able to do runtime PM
and keep the parent enabled if the CI_HDRC_SUPPORTS_RUNTIME_PM flag is
set. But even if that flag isn't set, the ci_hdrc_msm driver is calling
pm_runtime_enable() on the same device that it would be called on if the
CI_HDRC_SUPPORTS_RUNTIME_PM flag was set. That allows runtime PM
transition of child devices such as the usb ports (usb1-port1 for
example) to propagate up all the way to the ci_hdrc_msm device and
disable any attached power domains.

Why don't we call runtime PM functions on the ci->dev for all cases of
ci->supports_runtime_pm? It seems like the glue drivers should be
managing their own device power states and the ci->dev should be managed
by core.c code.

Another solution would be to remove the call to pm_runtime_enable() from
ci_hdrc_msm. That would make sure we don't call the power domain code
when the device changes runtime PM states and rely on the fact that
power domains are turned on during device driver probe.

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

* Re: [PATCH 19/21] usb: chipidea: msm: Be silent on probe defer errors
  2016-06-26  7:28   ` Stephen Boyd
  (?)
@ 2016-06-30  1:06     ` Peter Chen
  -1 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-30  1:06 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Felipe Balbi, Arnd Bergmann, Neil Armstrong, linux-arm-msm,
	linux-usb, linux-kernel, Bjorn Andersson, Peter Chen,
	Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

On Sun, Jun 26, 2016 at 12:28:36AM -0700, Stephen Boyd wrote:
> If something fails in ci_hdrc_add_device() due to probe defer, we
> shouldn't print an error message. Be silent in this case as we'll
> try probe again later.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/ci_hdrc_msm.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> index 7d191928e55b..2ed9a181f4b6 100644
> --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> @@ -241,7 +241,8 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  	plat_ci = ci_hdrc_add_device(&pdev->dev, pdev->resource,
>  				     pdev->num_resources, &ci->pdata);
>  	if (IS_ERR(plat_ci)) {
> -		dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
> +		if (PTR_ERR(plat_ci) != -EPROBE_DEFER)
> +			dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
>  		ret = PTR_ERR(plat_ci);
>  		goto err_mux;
>  	}

Why not let ret equals to PTR_ERR(plat_ci) first, and using ret to
compare?

-- 

Best Regards,
Peter Chen

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

* Re: [PATCH 19/21] usb: chipidea: msm: Be silent on probe defer errors
@ 2016-06-30  1:06     ` Peter Chen
  0 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-30  1:06 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, linux-arm-kernel, linux-kernel, linux-arm-msm,
	Andy Gross, Bjorn Andersson, Neil Armstrong, Arnd Bergmann,
	Felipe Balbi, Peter Chen, Greg Kroah-Hartman

On Sun, Jun 26, 2016 at 12:28:36AM -0700, Stephen Boyd wrote:
> If something fails in ci_hdrc_add_device() due to probe defer, we
> shouldn't print an error message. Be silent in this case as we'll
> try probe again later.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/ci_hdrc_msm.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> index 7d191928e55b..2ed9a181f4b6 100644
> --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> @@ -241,7 +241,8 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  	plat_ci = ci_hdrc_add_device(&pdev->dev, pdev->resource,
>  				     pdev->num_resources, &ci->pdata);
>  	if (IS_ERR(plat_ci)) {
> -		dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
> +		if (PTR_ERR(plat_ci) != -EPROBE_DEFER)
> +			dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
>  		ret = PTR_ERR(plat_ci);
>  		goto err_mux;
>  	}

Why not let ret equals to PTR_ERR(plat_ci) first, and using ret to
compare?

-- 

Best Regards,
Peter Chen

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

* [PATCH 19/21] usb: chipidea: msm: Be silent on probe defer errors
@ 2016-06-30  1:06     ` Peter Chen
  0 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-30  1:06 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Jun 26, 2016 at 12:28:36AM -0700, Stephen Boyd wrote:
> If something fails in ci_hdrc_add_device() due to probe defer, we
> shouldn't print an error message. Be silent in this case as we'll
> try probe again later.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/ci_hdrc_msm.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> index 7d191928e55b..2ed9a181f4b6 100644
> --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> @@ -241,7 +241,8 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  	plat_ci = ci_hdrc_add_device(&pdev->dev, pdev->resource,
>  				     pdev->num_resources, &ci->pdata);
>  	if (IS_ERR(plat_ci)) {
> -		dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
> +		if (PTR_ERR(plat_ci) != -EPROBE_DEFER)
> +			dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
>  		ret = PTR_ERR(plat_ci);
>  		goto err_mux;
>  	}

Why not let ret equals to PTR_ERR(plat_ci) first, and using ret to
compare?

-- 

Best Regards,
Peter Chen

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

* Re: [PATCH 10/21] usb: chipidea: msm: Rely on core to override AHBBURST
  2016-06-29 18:59       ` Stephen Boyd
  (?)
@ 2016-06-30  1:18         ` Peter Chen
  -1 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-30  1:18 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Felipe Balbi, Arnd Bergmann, Neil Armstrong, linux-arm-msm,
	linux-usb, linux-kernel, Bjorn Andersson, Peter Chen,
	Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

On Wed, Jun 29, 2016 at 11:59:21AM -0700, Stephen Boyd wrote:
> Quoting Peter Chen (2016-06-28 23:32:11)
> > On Sun, Jun 26, 2016 at 12:28:27AM -0700, Stephen Boyd wrote:
> > > The core framework already handles setting this parameter with a
> > > platform quirk. Add the appropriate flag so that we always set
> > > AHBBURST to 0. Technically DT should be doing this, but we always
> > > do it for msm chipidea devices so setting the flag in the driver
> > > works just as well.
> > 
> > You still need to set AHB burst value at dts, this flag is just for
> > override, see below:
> > 
> > ahb-burst-config = <0x0>;
> 
> Right, I have added that to dts now, but the CI_HDRC_OVERRIDE_AHB_BURST
> flag allows us to specify it from the platdata structure in the
> ci_hdrc_msm.c file. As the value is zero for msm type controllers, I
> left it out of the static definition of platdata because all the
> non-initialized members of that structure are going to be zero anyway. I
> can explicitly set it to zero to make it more clear if you like.

I suggest setting it explicitly at dts, at current code, it is set
as zero explicitly too:)

-- 

Best Regards,
Peter Chen

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

* Re: [PATCH 10/21] usb: chipidea: msm: Rely on core to override AHBBURST
@ 2016-06-30  1:18         ` Peter Chen
  0 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-30  1:18 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, linux-arm-kernel, linux-kernel, linux-arm-msm,
	Andy Gross, Bjorn Andersson, Neil Armstrong, Arnd Bergmann,
	Felipe Balbi, Peter Chen, Greg Kroah-Hartman

On Wed, Jun 29, 2016 at 11:59:21AM -0700, Stephen Boyd wrote:
> Quoting Peter Chen (2016-06-28 23:32:11)
> > On Sun, Jun 26, 2016 at 12:28:27AM -0700, Stephen Boyd wrote:
> > > The core framework already handles setting this parameter with a
> > > platform quirk. Add the appropriate flag so that we always set
> > > AHBBURST to 0. Technically DT should be doing this, but we always
> > > do it for msm chipidea devices so setting the flag in the driver
> > > works just as well.
> > 
> > You still need to set AHB burst value at dts, this flag is just for
> > override, see below:
> > 
> > ahb-burst-config = <0x0>;
> 
> Right, I have added that to dts now, but the CI_HDRC_OVERRIDE_AHB_BURST
> flag allows us to specify it from the platdata structure in the
> ci_hdrc_msm.c file. As the value is zero for msm type controllers, I
> left it out of the static definition of platdata because all the
> non-initialized members of that structure are going to be zero anyway. I
> can explicitly set it to zero to make it more clear if you like.

I suggest setting it explicitly at dts, at current code, it is set
as zero explicitly too:)

-- 

Best Regards,
Peter Chen

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

* [PATCH 10/21] usb: chipidea: msm: Rely on core to override AHBBURST
@ 2016-06-30  1:18         ` Peter Chen
  0 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-30  1:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jun 29, 2016 at 11:59:21AM -0700, Stephen Boyd wrote:
> Quoting Peter Chen (2016-06-28 23:32:11)
> > On Sun, Jun 26, 2016 at 12:28:27AM -0700, Stephen Boyd wrote:
> > > The core framework already handles setting this parameter with a
> > > platform quirk. Add the appropriate flag so that we always set
> > > AHBBURST to 0. Technically DT should be doing this, but we always
> > > do it for msm chipidea devices so setting the flag in the driver
> > > works just as well.
> > 
> > You still need to set AHB burst value at dts, this flag is just for
> > override, see below:
> > 
> > ahb-burst-config = <0x0>;
> 
> Right, I have added that to dts now, but the CI_HDRC_OVERRIDE_AHB_BURST
> flag allows us to specify it from the platdata structure in the
> ci_hdrc_msm.c file. As the value is zero for msm type controllers, I
> left it out of the static definition of platdata because all the
> non-initialized members of that structure are going to be zero anyway. I
> can explicitly set it to zero to make it more clear if you like.

I suggest setting it explicitly at dts, at current code, it is set
as zero explicitly too:)

-- 

Best Regards,
Peter Chen

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

* Re: [PATCH 08/21] usb: chipidea: Kick OTG state machine for AVVIS with vbus extcon
  2016-06-29  3:09       ` Peter Chen
@ 2016-06-30  1:19         ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-30  1:19 UTC (permalink / raw)
  To: Peter Chen
  Cc: Felipe Balbi, Arnd Bergmann, Neil Armstrong, linux-arm-msm,
	linux-usb, linux-kernel, Bjorn Andersson, Peter Chen,
	Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

Quoting Peter Chen (2016-06-28 20:09:13)
> On Sun, Jun 26, 2016 at 12:28:25AM -0700, Stephen Boyd wrote:
> > Force the OTG state machine to go forward when we're using an
> > extcon for vbus detection. In this case, the controller may never
> > raise an interrupt for AVVIS, so we need to simulate the event by
> > toggling the appropriate OTG fsm bits and kicking the state
> > machine again.
> > 
> 
> Well, I think you may misunderstand the OTG FSM and dual-role.
> From my and Felipe's point, there are seldom users for USB FSM,
> there are only OTG FSM spec and related OTG certification.

Probably yes.

> 
> The OTG FSM needs related SoC support, the vbus will be off at
> several states, and the SRP should be supported by SoC.
> 
> By default, the dts needs below properties for disabling it if you
> choose otg fsm support at kernel configuration.
> 
> &usbotg1 {
>         vbus-supply = <&reg_usb_otg1_vbus>;
>         srp-disable;
>         hnp-disable;
>         adp-disable;
>         status = "okay";
> };
> 
> See Documentation/devicetree/bindings/usb/generic.txt.

Does this mean we should be setting all those properties if we're using
an extcon for vbus and id? I have noticed that vbus is powered off after
some time when no device is connected and we're in A_HOST state because
the timeout for a B device connection happens.

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

* [PATCH 08/21] usb: chipidea: Kick OTG state machine for AVVIS with vbus extcon
@ 2016-06-30  1:19         ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-30  1:19 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Peter Chen (2016-06-28 20:09:13)
> On Sun, Jun 26, 2016 at 12:28:25AM -0700, Stephen Boyd wrote:
> > Force the OTG state machine to go forward when we're using an
> > extcon for vbus detection. In this case, the controller may never
> > raise an interrupt for AVVIS, so we need to simulate the event by
> > toggling the appropriate OTG fsm bits and kicking the state
> > machine again.
> > 
> 
> Well, I think you may misunderstand the OTG FSM and dual-role.
> From my and Felipe's point, there are seldom users for USB FSM,
> there are only OTG FSM spec and related OTG certification.

Probably yes.

> 
> The OTG FSM needs related SoC support, the vbus will be off at
> several states, and the SRP should be supported by SoC.
> 
> By default, the dts needs below properties for disabling it if you
> choose otg fsm support at kernel configuration.
> 
> &usbotg1 {
>         vbus-supply = <&reg_usb_otg1_vbus>;
>         srp-disable;
>         hnp-disable;
>         adp-disable;
>         status = "okay";
> };
> 
> See Documentation/devicetree/bindings/usb/generic.txt.

Does this mean we should be setting all those properties if we're using
an extcon for vbus and id? I have noticed that vbus is powered off after
some time when no device is connected and we're in A_HOST state because
the timeout for a B device connection happens.

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

* Re: [PATCH 06/21] usb: chipidea: Initialize and reinitialize phy later
  2016-06-30  1:23       ` Stephen Boyd
@ 2016-06-30  1:22         ` Peter Chen
  -1 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-30  1:22 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, Felipe Balbi, Arnd Bergmann, Neil Armstrong,
	linux-arm-msm, linux-kernel, Bjorn Andersson, Peter Chen,
	Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

On Wed, Jun 29, 2016 at 06:23:50PM -0700, Stephen Boyd wrote:
> Quoting Peter Chen (2016-06-28 19:30:52)
> > On Sun, Jun 26, 2016 at 12:28:23AM -0700, Stephen Boyd wrote:
> > > The ULPI phy on qcom platforms needs to be initialized and
> > > powered on after a USB reset and before we toggle the run/stop
> > > bit. Otherwise, the phy locks up and doesn't work properly.
> > 
> > This requirement is so strange, try to see if any other initialization
> > sequences.
> 
> I think the problem is that the reset bit also resets the phy because
> the phy is part of the same clock domain as the controller. Just a guess
> though.
> 
> >      
> > Since this driver is multi-platforms, I can't accept this change for
> > common, if you had to do that, would you please move your changes to
> > msm glue layer using CI_HDRC_CONTROLLER_RESET_EVENT and
> > CI_HDRC_CONTROLLER_STOPPED_EVENT? Besides, you need to add one flag
> > at ci_hdrc_platform_data.flags for your case to avoid normal
> > initialization.
> 
> Ok, let me see if I can make this work properly in the glue layer. I
> take it that you want me to add a flag for this specific case so that we
> don't do any phy control in the core and leave it up to the glue layer
> to handle, like CI_HDRC_DISABLE_PHY_CONTROL or something?

Yes

-- 

Best Regards,
Peter Chen

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

* [PATCH 06/21] usb: chipidea: Initialize and reinitialize phy later
@ 2016-06-30  1:22         ` Peter Chen
  0 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-30  1:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jun 29, 2016 at 06:23:50PM -0700, Stephen Boyd wrote:
> Quoting Peter Chen (2016-06-28 19:30:52)
> > On Sun, Jun 26, 2016 at 12:28:23AM -0700, Stephen Boyd wrote:
> > > The ULPI phy on qcom platforms needs to be initialized and
> > > powered on after a USB reset and before we toggle the run/stop
> > > bit. Otherwise, the phy locks up and doesn't work properly.
> > 
> > This requirement is so strange, try to see if any other initialization
> > sequences.
> 
> I think the problem is that the reset bit also resets the phy because
> the phy is part of the same clock domain as the controller. Just a guess
> though.
> 
> >      
> > Since this driver is multi-platforms, I can't accept this change for
> > common, if you had to do that, would you please move your changes to
> > msm glue layer using CI_HDRC_CONTROLLER_RESET_EVENT and
> > CI_HDRC_CONTROLLER_STOPPED_EVENT? Besides, you need to add one flag
> > at ci_hdrc_platform_data.flags for your case to avoid normal
> > initialization.
> 
> Ok, let me see if I can make this work properly in the glue layer. I
> take it that you want me to add a flag for this specific case so that we
> don't do any phy control in the core and leave it up to the glue layer
> to handle, like CI_HDRC_DISABLE_PHY_CONTROL or something?

Yes

-- 

Best Regards,
Peter Chen

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

* Re: [PATCH 06/21] usb: chipidea: Initialize and reinitialize phy later
  2016-06-29  2:30     ` Peter Chen
@ 2016-06-30  1:23       ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-30  1:23 UTC (permalink / raw)
  To: Peter Chen
  Cc: Felipe Balbi, Arnd Bergmann, Neil Armstrong, linux-arm-msm,
	linux-usb, linux-kernel, Bjorn Andersson, Peter Chen,
	Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

Quoting Peter Chen (2016-06-28 19:30:52)
> On Sun, Jun 26, 2016 at 12:28:23AM -0700, Stephen Boyd wrote:
> > The ULPI phy on qcom platforms needs to be initialized and
> > powered on after a USB reset and before we toggle the run/stop
> > bit. Otherwise, the phy locks up and doesn't work properly.
> 
> This requirement is so strange, try to see if any other initialization
> sequences.

I think the problem is that the reset bit also resets the phy because
the phy is part of the same clock domain as the controller. Just a guess
though.

>      
> Since this driver is multi-platforms, I can't accept this change for
> common, if you had to do that, would you please move your changes to
> msm glue layer using CI_HDRC_CONTROLLER_RESET_EVENT and
> CI_HDRC_CONTROLLER_STOPPED_EVENT? Besides, you need to add one flag
> at ci_hdrc_platform_data.flags for your case to avoid normal
> initialization.

Ok, let me see if I can make this work properly in the glue layer. I
take it that you want me to add a flag for this specific case so that we
don't do any phy control in the core and leave it up to the glue layer
to handle, like CI_HDRC_DISABLE_PHY_CONTROL or something?

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

* [PATCH 06/21] usb: chipidea: Initialize and reinitialize phy later
@ 2016-06-30  1:23       ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-30  1:23 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Peter Chen (2016-06-28 19:30:52)
> On Sun, Jun 26, 2016 at 12:28:23AM -0700, Stephen Boyd wrote:
> > The ULPI phy on qcom platforms needs to be initialized and
> > powered on after a USB reset and before we toggle the run/stop
> > bit. Otherwise, the phy locks up and doesn't work properly.
> 
> This requirement is so strange, try to see if any other initialization
> sequences.

I think the problem is that the reset bit also resets the phy because
the phy is part of the same clock domain as the controller. Just a guess
though.

>      
> Since this driver is multi-platforms, I can't accept this change for
> common, if you had to do that, would you please move your changes to
> msm glue layer using CI_HDRC_CONTROLLER_RESET_EVENT and
> CI_HDRC_CONTROLLER_STOPPED_EVENT? Besides, you need to add one flag
> at ci_hdrc_platform_data.flags for your case to avoid normal
> initialization.

Ok, let me see if I can make this work properly in the glue layer. I
take it that you want me to add a flag for this specific case so that we
don't do any phy control in the core and leave it up to the glue layer
to handle, like CI_HDRC_DISABLE_PHY_CONTROL or something?

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

* Re: [PATCH 19/21] usb: chipidea: msm: Be silent on probe defer errors
  2016-06-30  1:06     ` Peter Chen
@ 2016-06-30  1:26       ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-30  1:26 UTC (permalink / raw)
  To: Peter Chen
  Cc: Felipe Balbi, Arnd Bergmann, Neil Armstrong, linux-arm-msm,
	linux-usb, linux-kernel, Bjorn Andersson, Peter Chen,
	Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

Quoting Peter Chen (2016-06-29 18:06:28)
> On Sun, Jun 26, 2016 at 12:28:36AM -0700, Stephen Boyd wrote:
> > ---
> >  drivers/usb/chipidea/ci_hdrc_msm.c | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> > index 7d191928e55b..2ed9a181f4b6 100644
> > --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> > +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> > @@ -241,7 +241,8 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
> >       plat_ci = ci_hdrc_add_device(&pdev->dev, pdev->resource,
> >                                    pdev->num_resources, &ci->pdata);
> >       if (IS_ERR(plat_ci)) {
> > -             dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
> > +             if (PTR_ERR(plat_ci) != -EPROBE_DEFER)
> > +                     dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
> >               ret = PTR_ERR(plat_ci);
> >               goto err_mux;
> >       }
> 
> Why not let ret equals to PTR_ERR(plat_ci) first, and using ret to
> compare?

Sure. I've fixed it up.

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

* [PATCH 19/21] usb: chipidea: msm: Be silent on probe defer errors
@ 2016-06-30  1:26       ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-30  1:26 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Peter Chen (2016-06-29 18:06:28)
> On Sun, Jun 26, 2016 at 12:28:36AM -0700, Stephen Boyd wrote:
> > ---
> >  drivers/usb/chipidea/ci_hdrc_msm.c | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> > index 7d191928e55b..2ed9a181f4b6 100644
> > --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> > +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> > @@ -241,7 +241,8 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
> >       plat_ci = ci_hdrc_add_device(&pdev->dev, pdev->resource,
> >                                    pdev->num_resources, &ci->pdata);
> >       if (IS_ERR(plat_ci)) {
> > -             dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
> > +             if (PTR_ERR(plat_ci) != -EPROBE_DEFER)
> > +                     dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
> >               ret = PTR_ERR(plat_ci);
> >               goto err_mux;
> >       }
> 
> Why not let ret equals to PTR_ERR(plat_ci) first, and using ret to
> compare?

Sure. I've fixed it up.

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

* Re: [PATCH 08/21] usb: chipidea: Kick OTG state machine for AVVIS with vbus extcon
  2016-06-30  1:19         ` Stephen Boyd
  (?)
@ 2016-06-30  1:26           ` Peter Chen
  -1 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-30  1:26 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Felipe Balbi, Arnd Bergmann, Neil Armstrong, linux-arm-msm,
	linux-usb, linux-kernel, Bjorn Andersson, Peter Chen,
	Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

On Wed, Jun 29, 2016 at 06:19:59PM -0700, Stephen Boyd wrote:
> Quoting Peter Chen (2016-06-28 20:09:13)
> > On Sun, Jun 26, 2016 at 12:28:25AM -0700, Stephen Boyd wrote:
> > > Force the OTG state machine to go forward when we're using an
> > > extcon for vbus detection. In this case, the controller may never
> > > raise an interrupt for AVVIS, so we need to simulate the event by
> > > toggling the appropriate OTG fsm bits and kicking the state
> > > machine again.
> > > 
> > 
> > Well, I think you may misunderstand the OTG FSM and dual-role.
> > From my and Felipe's point, there are seldom users for USB FSM,
> > there are only OTG FSM spec and related OTG certification.
> 
> Probably yes.
> 
> > 
> > The OTG FSM needs related SoC support, the vbus will be off at
> > several states, and the SRP should be supported by SoC.
> > 
> > By default, the dts needs below properties for disabling it if you
> > choose otg fsm support at kernel configuration.
> > 
> > &usbotg1 {
> >         vbus-supply = <&reg_usb_otg1_vbus>;
> >         srp-disable;
> >         hnp-disable;
> >         adp-disable;
> >         status = "okay";
> > };
> > 
> > See Documentation/devicetree/bindings/usb/generic.txt.
> 
> Does this mean we should be setting all those properties if we're using
> an extcon for vbus and id?

It is not related to how we know vbus and id. If your controller is
otg-capable, and you don't want to enable OTG FSM (just want dual-role),
you should set them at dts since the zImage is multi-platforms, the
CONFIG_USB_OTG and CONFIG_USB_OTG_FSM may be chosen.

> I have noticed that vbus is powered off after
> some time when no device is connected and we're in A_HOST state because
> the timeout for a B device connection happens.

I think it is not you want, but it is OTG compliance.

-- 

Best Regards,
Peter Chen

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

* Re: [PATCH 08/21] usb: chipidea: Kick OTG state machine for AVVIS with vbus extcon
@ 2016-06-30  1:26           ` Peter Chen
  0 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-30  1:26 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, linux-arm-kernel, linux-kernel, linux-arm-msm,
	Andy Gross, Bjorn Andersson, Neil Armstrong, Arnd Bergmann,
	Felipe Balbi, Peter Chen, Greg Kroah-Hartman

On Wed, Jun 29, 2016 at 06:19:59PM -0700, Stephen Boyd wrote:
> Quoting Peter Chen (2016-06-28 20:09:13)
> > On Sun, Jun 26, 2016 at 12:28:25AM -0700, Stephen Boyd wrote:
> > > Force the OTG state machine to go forward when we're using an
> > > extcon for vbus detection. In this case, the controller may never
> > > raise an interrupt for AVVIS, so we need to simulate the event by
> > > toggling the appropriate OTG fsm bits and kicking the state
> > > machine again.
> > > 
> > 
> > Well, I think you may misunderstand the OTG FSM and dual-role.
> > From my and Felipe's point, there are seldom users for USB FSM,
> > there are only OTG FSM spec and related OTG certification.
> 
> Probably yes.
> 
> > 
> > The OTG FSM needs related SoC support, the vbus will be off at
> > several states, and the SRP should be supported by SoC.
> > 
> > By default, the dts needs below properties for disabling it if you
> > choose otg fsm support at kernel configuration.
> > 
> > &usbotg1 {
> >         vbus-supply = <&reg_usb_otg1_vbus>;
> >         srp-disable;
> >         hnp-disable;
> >         adp-disable;
> >         status = "okay";
> > };
> > 
> > See Documentation/devicetree/bindings/usb/generic.txt.
> 
> Does this mean we should be setting all those properties if we're using
> an extcon for vbus and id?

It is not related to how we know vbus and id. If your controller is
otg-capable, and you don't want to enable OTG FSM (just want dual-role),
you should set them at dts since the zImage is multi-platforms, the
CONFIG_USB_OTG and CONFIG_USB_OTG_FSM may be chosen.

> I have noticed that vbus is powered off after
> some time when no device is connected and we're in A_HOST state because
> the timeout for a B device connection happens.

I think it is not you want, but it is OTG compliance.

-- 

Best Regards,
Peter Chen

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

* [PATCH 08/21] usb: chipidea: Kick OTG state machine for AVVIS with vbus extcon
@ 2016-06-30  1:26           ` Peter Chen
  0 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-30  1:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jun 29, 2016 at 06:19:59PM -0700, Stephen Boyd wrote:
> Quoting Peter Chen (2016-06-28 20:09:13)
> > On Sun, Jun 26, 2016 at 12:28:25AM -0700, Stephen Boyd wrote:
> > > Force the OTG state machine to go forward when we're using an
> > > extcon for vbus detection. In this case, the controller may never
> > > raise an interrupt for AVVIS, so we need to simulate the event by
> > > toggling the appropriate OTG fsm bits and kicking the state
> > > machine again.
> > > 
> > 
> > Well, I think you may misunderstand the OTG FSM and dual-role.
> > From my and Felipe's point, there are seldom users for USB FSM,
> > there are only OTG FSM spec and related OTG certification.
> 
> Probably yes.
> 
> > 
> > The OTG FSM needs related SoC support, the vbus will be off at
> > several states, and the SRP should be supported by SoC.
> > 
> > By default, the dts needs below properties for disabling it if you
> > choose otg fsm support at kernel configuration.
> > 
> > &usbotg1 {
> >         vbus-supply = <&reg_usb_otg1_vbus>;
> >         srp-disable;
> >         hnp-disable;
> >         adp-disable;
> >         status = "okay";
> > };
> > 
> > See Documentation/devicetree/bindings/usb/generic.txt.
> 
> Does this mean we should be setting all those properties if we're using
> an extcon for vbus and id?

It is not related to how we know vbus and id. If your controller is
otg-capable, and you don't want to enable OTG FSM (just want dual-role),
you should set them at dts since the zImage is multi-platforms, the
CONFIG_USB_OTG and CONFIG_USB_OTG_FSM may be chosen.

> I have noticed that vbus is powered off after
> some time when no device is connected and we're in A_HOST state because
> the timeout for a B device connection happens.

I think it is not you want, but it is OTG compliance.

-- 

Best Regards,
Peter Chen

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

* Re: [PATCH 09/21] usb: chipidea: Add support for ULPI PHY bus
  2016-06-29  6:26     ` Peter Chen
@ 2016-06-30  1:29       ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-30  1:29 UTC (permalink / raw)
  To: Peter Chen
  Cc: Felipe Balbi, Heikki Krogerus, Arnd Bergmann, Neil Armstrong,
	linux-arm-msm, linux-usb, linux-kernel, Bjorn Andersson,
	Peter Chen, Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

Quoting Peter Chen (2016-06-28 23:26:00)
> On Sun, Jun 26, 2016 at 12:28:26AM -0700, Stephen Boyd wrote:
> > @@ -187,6 +190,7 @@ struct hw_bank {
> >   * @test_mode: the selected test mode
> >   * @platdata: platform specific information supplied by parent device
> >   * @vbus_active: is VBUS active
> > + * @ulpi: pointer to ULPI device, if any
> 
> One more kernel-doc

Done.

> 
> >   * @phy: pointer to PHY, if any
> >   * @usb_phy: pointer to USB PHY, if any and if using the USB PHY framework
> >   * @hcd: pointer to usb_hcd for ehci host driver
> > @@ -236,6 +240,10 @@ struct ci_hdrc {
> >  
> >       struct ci_hdrc_platform_data    *platdata;
> >       int                             vbus_active;
> > +#ifdef CONFIG_USB_CHIPIDEA_ULPI
> > +     struct ulpi                     *ulpi;
> > +     struct ulpi_ops                 ulpi_ops;
> > +#endif
> >       struct phy                      *phy;
> >       /* old usb_phy interface */
> >       struct usb_phy                  *usb_phy;
> > @@ -418,6 +426,17 @@ static inline bool ci_otg_is_fsm_mode(struct ci_hdrc *ci)
> >  #endif
> >  }
> >  
> 
> Others are ok, but I can't accept you change current PHY initialization
> at your previous patch, so you may need to refine this patch a little.
> 

Ok. No problem.

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

* [PATCH 09/21] usb: chipidea: Add support for ULPI PHY bus
@ 2016-06-30  1:29       ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-30  1:29 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Peter Chen (2016-06-28 23:26:00)
> On Sun, Jun 26, 2016 at 12:28:26AM -0700, Stephen Boyd wrote:
> > @@ -187,6 +190,7 @@ struct hw_bank {
> >   * @test_mode: the selected test mode
> >   * @platdata: platform specific information supplied by parent device
> >   * @vbus_active: is VBUS active
> > + * @ulpi: pointer to ULPI device, if any
> 
> One more kernel-doc

Done.

> 
> >   * @phy: pointer to PHY, if any
> >   * @usb_phy: pointer to USB PHY, if any and if using the USB PHY framework
> >   * @hcd: pointer to usb_hcd for ehci host driver
> > @@ -236,6 +240,10 @@ struct ci_hdrc {
> >  
> >       struct ci_hdrc_platform_data    *platdata;
> >       int                             vbus_active;
> > +#ifdef CONFIG_USB_CHIPIDEA_ULPI
> > +     struct ulpi                     *ulpi;
> > +     struct ulpi_ops                 ulpi_ops;
> > +#endif
> >       struct phy                      *phy;
> >       /* old usb_phy interface */
> >       struct usb_phy                  *usb_phy;
> > @@ -418,6 +426,17 @@ static inline bool ci_otg_is_fsm_mode(struct ci_hdrc *ci)
> >  #endif
> >  }
> >  
> 
> Others are ok, but I can't accept you change current PHY initialization
> at your previous patch, so you may need to refine this patch a little.
> 

Ok. No problem.

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

* Re: [PATCH 15/21] usb: chipidea: msm: Mux over secondary phy at the right time
  2016-06-29  8:08     ` Peter Chen
@ 2016-06-30  1:35       ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-30  1:35 UTC (permalink / raw)
  To: Peter Chen
  Cc: Felipe Balbi, Arnd Bergmann, Neil Armstrong, linux-arm-msm,
	linux-usb, linux-kernel, Bjorn Andersson, Peter Chen,
	Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

Quoting Peter Chen (2016-06-29 01:08:52)
> On Sun, Jun 26, 2016 at 12:28:32AM -0700, Stephen Boyd wrote:
> > We need to pick the correct phy at runtime based on how the SoC
> > has been wired onto the board. If the secondary phy is used, take
> > it out of reset and mux over to it by writing into the TCSR
> > register. Make sure to do this on reset too, because this
> > register is reset to the default value (primary phy) after the
> > RESET bit is set in USBCMD.
> > 
> 
> I am curious when you need the secondary phy?

The msm8974 SoC has two phys that sit behind a mux. The primary phy is
typically used by the dwc3 instance for usb3, but it can also be used by
the chipidea controller if this mux is set to zero instead of one. It's
a board designer decision to use either the primary phy or the secondary
phy for the chipidea controller, but dwc3 can only use the primary phy
as it's the only HS phy it's connected to. I suppose if there's a board
out there that doesn't want to use the dwc3 instance because they don't
want USB3 they can use the primary phy for the chipidea instance and
keep the secondary phy powered off.

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

* [PATCH 15/21] usb: chipidea: msm: Mux over secondary phy at the right time
@ 2016-06-30  1:35       ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-30  1:35 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Peter Chen (2016-06-29 01:08:52)
> On Sun, Jun 26, 2016 at 12:28:32AM -0700, Stephen Boyd wrote:
> > We need to pick the correct phy at runtime based on how the SoC
> > has been wired onto the board. If the secondary phy is used, take
> > it out of reset and mux over to it by writing into the TCSR
> > register. Make sure to do this on reset too, because this
> > register is reset to the default value (primary phy) after the
> > RESET bit is set in USBCMD.
> > 
> 
> I am curious when you need the secondary phy?

The msm8974 SoC has two phys that sit behind a mux. The primary phy is
typically used by the dwc3 instance for usb3, but it can also be used by
the chipidea controller if this mux is set to zero instead of one. It's
a board designer decision to use either the primary phy or the secondary
phy for the chipidea controller, but dwc3 can only use the primary phy
as it's the only HS phy it's connected to. I suppose if there's a board
out there that doesn't want to use the dwc3 instance because they don't
want USB3 they can use the primary phy for the chipidea instance and
keep the secondary phy powered off.

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

* Re: [PATCH 12/21] usb: chipidea: msm: Keep device runtime enabled
  2016-06-30  0:43       ` Stephen Boyd
@ 2016-06-30  1:39         ` Peter Chen
  -1 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-30  1:39 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, linux-arm-kernel, linux-kernel, linux-arm-msm,
	Andy Gross, Bjorn Andersson, Neil Armstrong, Arnd Bergmann,
	Felipe Balbi, Peter Chen, Greg Kroah-Hartman, linux-pm

On Wed, Jun 29, 2016 at 05:43:30PM -0700, Stephen Boyd wrote:
> Quoting Peter Chen (2016-06-28 23:46:00)
> > On Sun, Jun 26, 2016 at 12:28:29AM -0700, Stephen Boyd wrote:
> > > Sometimes the usb wrapper device is part of a power domain that
> > > needs to stay on as long as the device is active. Let's get and
> > > put the device in driver probe/remove so that we keep the power
> > > domain powered as long as the device is attached. We can fine
> > > tune this later to handle wakeup interrupts, etc. for finer grain
> > > power management later, but this is necessary to make sure we can
> > > keep accessing the device right now.
> > 
> > Since some of the controllers work abnormal if we enables runtime
> > pm unconditionally, so I use one system flag CI_HDRC_SUPPORTS_RUNTIME_PM
> > for it. I can't understand why you can't access device without enable
> > parent's runtime pm, the controller will not enter runtime suspend
> > without that flag.
> 
> Correct, the child device of ci_hdrc_msm will be able to do runtime PM
> and keep the parent enabled if the CI_HDRC_SUPPORTS_RUNTIME_PM flag is
> set. But even if that flag isn't set, the ci_hdrc_msm driver is calling
> pm_runtime_enable() on the same device that it would be called on if the
> CI_HDRC_SUPPORTS_RUNTIME_PM flag was set. That allows runtime PM
> transition of child devices such as the usb ports (usb1-port1 for
> example) to propagate up all the way to the ci_hdrc_msm device and
> disable any attached power domains.

Sorry, I can't get you.

If the chipidea core's runtime is disabled, the port under the
controller will not be in runtime suspended, only the bus will
be in suspended due to USB core enables runtime PM by default.

> 
> Why don't we call runtime PM functions on the ci->dev for all cases of
> ci->supports_runtime_pm? It seems like the glue drivers should be
> managing their own device power states and the ci->dev should be managed
> by core.c code.
> 

This is current design. Chipidea core manages portsc.phcd and PHY's PM
(through PHY's API), and glue layer manages its own clocks on the system
bus for register visit (and data transfer if necessary).

-- 

Best Regards,
Peter Chen

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

* [PATCH 12/21] usb: chipidea: msm: Keep device runtime enabled
@ 2016-06-30  1:39         ` Peter Chen
  0 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-30  1:39 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jun 29, 2016 at 05:43:30PM -0700, Stephen Boyd wrote:
> Quoting Peter Chen (2016-06-28 23:46:00)
> > On Sun, Jun 26, 2016 at 12:28:29AM -0700, Stephen Boyd wrote:
> > > Sometimes the usb wrapper device is part of a power domain that
> > > needs to stay on as long as the device is active. Let's get and
> > > put the device in driver probe/remove so that we keep the power
> > > domain powered as long as the device is attached. We can fine
> > > tune this later to handle wakeup interrupts, etc. for finer grain
> > > power management later, but this is necessary to make sure we can
> > > keep accessing the device right now.
> > 
> > Since some of the controllers work abnormal if we enables runtime
> > pm unconditionally, so I use one system flag CI_HDRC_SUPPORTS_RUNTIME_PM
> > for it. I can't understand why you can't access device without enable
> > parent's runtime pm, the controller will not enter runtime suspend
> > without that flag.
> 
> Correct, the child device of ci_hdrc_msm will be able to do runtime PM
> and keep the parent enabled if the CI_HDRC_SUPPORTS_RUNTIME_PM flag is
> set. But even if that flag isn't set, the ci_hdrc_msm driver is calling
> pm_runtime_enable() on the same device that it would be called on if the
> CI_HDRC_SUPPORTS_RUNTIME_PM flag was set. That allows runtime PM
> transition of child devices such as the usb ports (usb1-port1 for
> example) to propagate up all the way to the ci_hdrc_msm device and
> disable any attached power domains.

Sorry, I can't get you.

If the chipidea core's runtime is disabled, the port under the
controller will not be in runtime suspended, only the bus will
be in suspended due to USB core enables runtime PM by default.

> 
> Why don't we call runtime PM functions on the ci->dev for all cases of
> ci->supports_runtime_pm? It seems like the glue drivers should be
> managing their own device power states and the ci->dev should be managed
> by core.c code.
> 

This is current design. Chipidea core manages portsc.phcd and PHY's PM
(through PHY's API), and glue layer manages its own clocks on the system
bus for register visit (and data transfer if necessary).

-- 

Best Regards,
Peter Chen

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

* Re: [PATCH 10/21] usb: chipidea: msm: Rely on core to override AHBBURST
  2016-06-30  1:18         ` Peter Chen
@ 2016-06-30  1:41           ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-30  1:41 UTC (permalink / raw)
  To: Peter Chen
  Cc: Felipe Balbi, Arnd Bergmann, Neil Armstrong, linux-arm-msm,
	linux-usb, linux-kernel, Bjorn Andersson, Peter Chen,
	Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

Quoting Peter Chen (2016-06-29 18:18:27)
> On Wed, Jun 29, 2016 at 11:59:21AM -0700, Stephen Boyd wrote:
> > Quoting Peter Chen (2016-06-28 23:32:11)
> > > On Sun, Jun 26, 2016 at 12:28:27AM -0700, Stephen Boyd wrote:
> > > > The core framework already handles setting this parameter with a
> > > > platform quirk. Add the appropriate flag so that we always set
> > > > AHBBURST to 0. Technically DT should be doing this, but we always
> > > > do it for msm chipidea devices so setting the flag in the driver
> > > > works just as well.
> > > 
> > > You still need to set AHB burst value at dts, this flag is just for
> > > override, see below:
> > > 
> > > ahb-burst-config = <0x0>;
> > 
> > Right, I have added that to dts now, but the CI_HDRC_OVERRIDE_AHB_BURST
> > flag allows us to specify it from the platdata structure in the
> > ci_hdrc_msm.c file. As the value is zero for msm type controllers, I
> > left it out of the static definition of platdata because all the
> > non-initialized members of that structure are going to be zero anyway. I
> > can explicitly set it to zero to make it more clear if you like.
> 
> I suggest setting it explicitly at dts, at current code, it is set
> as zero explicitly too:)
> 

Yes I'm making sure to always set it in dts as well. Should we drop this
patch and require dts to always have it set if needed? I was setting it
in the driver in case we had some older dts lying around, but I suppose
this is changing significantly enough where the qcom,ci_hdrc_msm binding
needs to be redone anyway. I'd still like to remove writing the value in
the reset callback though.

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

* [PATCH 10/21] usb: chipidea: msm: Rely on core to override AHBBURST
@ 2016-06-30  1:41           ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-30  1:41 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Peter Chen (2016-06-29 18:18:27)
> On Wed, Jun 29, 2016 at 11:59:21AM -0700, Stephen Boyd wrote:
> > Quoting Peter Chen (2016-06-28 23:32:11)
> > > On Sun, Jun 26, 2016 at 12:28:27AM -0700, Stephen Boyd wrote:
> > > > The core framework already handles setting this parameter with a
> > > > platform quirk. Add the appropriate flag so that we always set
> > > > AHBBURST to 0. Technically DT should be doing this, but we always
> > > > do it for msm chipidea devices so setting the flag in the driver
> > > > works just as well.
> > > 
> > > You still need to set AHB burst value at dts, this flag is just for
> > > override, see below:
> > > 
> > > ahb-burst-config = <0x0>;
> > 
> > Right, I have added that to dts now, but the CI_HDRC_OVERRIDE_AHB_BURST
> > flag allows us to specify it from the platdata structure in the
> > ci_hdrc_msm.c file. As the value is zero for msm type controllers, I
> > left it out of the static definition of platdata because all the
> > non-initialized members of that structure are going to be zero anyway. I
> > can explicitly set it to zero to make it more clear if you like.
> 
> I suggest setting it explicitly at dts, at current code, it is set
> as zero explicitly too:)
> 

Yes I'm making sure to always set it in dts as well. Should we drop this
patch and require dts to always have it set if needed? I was setting it
in the driver in case we had some older dts lying around, but I suppose
this is changing significantly enough where the qcom,ci_hdrc_msm binding
needs to be redone anyway. I'd still like to remove writing the value in
the reset callback though.

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

* Re: [PATCH 13/21] usb: chipidea: msm: Allow core to get usb phy
  2016-06-29 19:31         ` Stephen Boyd
  (?)
@ 2016-06-30  1:43           ` Peter Chen
  -1 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-30  1:43 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Felipe Balbi, Arnd Bergmann, Neil Armstrong, linux-arm-msm,
	linux-usb, linux-kernel, Bjorn Andersson, Peter Chen,
	Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

On Wed, Jun 29, 2016 at 12:31:18PM -0700, Stephen Boyd wrote:
> Quoting Peter Chen (2016-06-29 04:34:11)
> > On Wed, Jun 29, 2016 at 02:48:11PM +0800, Peter Chen wrote:
> > > On Sun, Jun 26, 2016 at 12:28:30AM -0700, Stephen Boyd wrote:
> > > > @@ -53,21 +44,9 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
> > > >  static int ci_hdrc_msm_probe(struct platform_device *pdev)
> > > >  {
> > > >     struct platform_device *plat_ci;
> > > > -   struct usb_phy *phy;
> > > >  
> > > >     dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
> > > >  
> > > > -   /*
> > > > -    * OTG(PHY) driver takes care of PHY initialization, clock management,
> > > > -    * powering up VBUS, mapping of registers address space and power
> > > > -    * management.
> > > > -    */
> > > > -   phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0);
> > > > -   if (IS_ERR(phy))
> > > > -           return PTR_ERR(phy);
> > > > -
> > > > -   ci_hdrc_msm_platdata.usb_phy = phy;
> > > > -
> > > >     plat_ci = ci_hdrc_add_device(&pdev->dev,
> > > >                             pdev->resource, pdev->num_resources,
> > > >                             &ci_hdrc_msm_platdata);
> > > > -- 
> > > 
> > 
> > Wait, how about the UTMI PHY? You don't have a platform which needs
> > to get PHY through the phandle?
> 
> Sorry I don't understand the question. What is the UTMI PHY? We need to
> get the phy through phandles. The only boards that are using ci_hdrc_msm
> are DT enabled boards.

UTMI PHY is the PHY inside the SoC, I just want to confirm all your PHYs
are at ulpi bus, if they are, you can do that, else, you may need above
way to get the PHY through PHY node.

-- 

Best Regards,
Peter Chen

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

* Re: [PATCH 13/21] usb: chipidea: msm: Allow core to get usb phy
@ 2016-06-30  1:43           ` Peter Chen
  0 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-30  1:43 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, linux-arm-kernel, linux-kernel, linux-arm-msm,
	Andy Gross, Bjorn Andersson, Neil Armstrong, Arnd Bergmann,
	Felipe Balbi, Peter Chen, Greg Kroah-Hartman

On Wed, Jun 29, 2016 at 12:31:18PM -0700, Stephen Boyd wrote:
> Quoting Peter Chen (2016-06-29 04:34:11)
> > On Wed, Jun 29, 2016 at 02:48:11PM +0800, Peter Chen wrote:
> > > On Sun, Jun 26, 2016 at 12:28:30AM -0700, Stephen Boyd wrote:
> > > > @@ -53,21 +44,9 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
> > > >  static int ci_hdrc_msm_probe(struct platform_device *pdev)
> > > >  {
> > > >     struct platform_device *plat_ci;
> > > > -   struct usb_phy *phy;
> > > >  
> > > >     dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
> > > >  
> > > > -   /*
> > > > -    * OTG(PHY) driver takes care of PHY initialization, clock management,
> > > > -    * powering up VBUS, mapping of registers address space and power
> > > > -    * management.
> > > > -    */
> > > > -   phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0);
> > > > -   if (IS_ERR(phy))
> > > > -           return PTR_ERR(phy);
> > > > -
> > > > -   ci_hdrc_msm_platdata.usb_phy = phy;
> > > > -
> > > >     plat_ci = ci_hdrc_add_device(&pdev->dev,
> > > >                             pdev->resource, pdev->num_resources,
> > > >                             &ci_hdrc_msm_platdata);
> > > > -- 
> > > 
> > 
> > Wait, how about the UTMI PHY? You don't have a platform which needs
> > to get PHY through the phandle?
> 
> Sorry I don't understand the question. What is the UTMI PHY? We need to
> get the phy through phandles. The only boards that are using ci_hdrc_msm
> are DT enabled boards.

UTMI PHY is the PHY inside the SoC, I just want to confirm all your PHYs
are at ulpi bus, if they are, you can do that, else, you may need above
way to get the PHY through PHY node.

-- 

Best Regards,
Peter Chen

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

* [PATCH 13/21] usb: chipidea: msm: Allow core to get usb phy
@ 2016-06-30  1:43           ` Peter Chen
  0 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-30  1:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jun 29, 2016 at 12:31:18PM -0700, Stephen Boyd wrote:
> Quoting Peter Chen (2016-06-29 04:34:11)
> > On Wed, Jun 29, 2016 at 02:48:11PM +0800, Peter Chen wrote:
> > > On Sun, Jun 26, 2016 at 12:28:30AM -0700, Stephen Boyd wrote:
> > > > @@ -53,21 +44,9 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
> > > >  static int ci_hdrc_msm_probe(struct platform_device *pdev)
> > > >  {
> > > >     struct platform_device *plat_ci;
> > > > -   struct usb_phy *phy;
> > > >  
> > > >     dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
> > > >  
> > > > -   /*
> > > > -    * OTG(PHY) driver takes care of PHY initialization, clock management,
> > > > -    * powering up VBUS, mapping of registers address space and power
> > > > -    * management.
> > > > -    */
> > > > -   phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0);
> > > > -   if (IS_ERR(phy))
> > > > -           return PTR_ERR(phy);
> > > > -
> > > > -   ci_hdrc_msm_platdata.usb_phy = phy;
> > > > -
> > > >     plat_ci = ci_hdrc_add_device(&pdev->dev,
> > > >                             pdev->resource, pdev->num_resources,
> > > >                             &ci_hdrc_msm_platdata);
> > > > -- 
> > > 
> > 
> > Wait, how about the UTMI PHY? You don't have a platform which needs
> > to get PHY through the phandle?
> 
> Sorry I don't understand the question. What is the UTMI PHY? We need to
> get the phy through phandles. The only boards that are using ci_hdrc_msm
> are DT enabled boards.

UTMI PHY is the PHY inside the SoC, I just want to confirm all your PHYs
are at ulpi bus, if they are, you can do that, else, you may need above
way to get the PHY through PHY node.

-- 

Best Regards,
Peter Chen

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

* RE: [PATCH 08/21] usb: chipidea: Kick OTG state machine for AVVIS with vbus extcon
  2016-06-30  1:26           ` Peter Chen
  (?)
@ 2016-06-30  1:50             ` Jun Li
  -1 siblings, 0 replies; 214+ messages in thread
From: Jun Li @ 2016-06-30  1:50 UTC (permalink / raw)
  To: Peter Chen, Stephen Boyd
  Cc: Felipe Balbi, Arnd Bergmann, Neil Armstrong, linux-arm-msm,
	linux-usb, linux-kernel, Bjorn Andersson, Peter Chen,
	Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

Hi Stephen,

> -----Original Message-----
> From: linux-usb-owner@vger.kernel.org [mailto:linux-usb-
> owner@vger.kernel.org] On Behalf Of Peter Chen
> Sent: Thursday, June 30, 2016 9:27 AM
> To: Stephen Boyd <stephen.boyd@linaro.org>
> Cc: linux-usb@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> linux-kernel@vger.kernel.org; linux-arm-msm@vger.kernel.org; Andy Gross
> <andy.gross@linaro.org>; Bjorn Andersson <bjorn.andersson@linaro.org>;
> Neil Armstrong <narmstrong@baylibre.com>; Arnd Bergmann <arnd@arndb.de>;
> Felipe Balbi <balbi@kernel.org>; Peter Chen <peter.chen@nxp.com>; Greg
> Kroah-Hartman <gregkh@linuxfoundation.org>
> Subject: Re: [PATCH 08/21] usb: chipidea: Kick OTG state machine for AVVIS
> with vbus extcon
> 
> On Wed, Jun 29, 2016 at 06:19:59PM -0700, Stephen Boyd wrote:
> > Quoting Peter Chen (2016-06-28 20:09:13)
> > > On Sun, Jun 26, 2016 at 12:28:25AM -0700, Stephen Boyd wrote:
> > > > Force the OTG state machine to go forward when we're using an
> > > > extcon for vbus detection. In this case, the controller may never
> > > > raise an interrupt for AVVIS, so we need to simulate the event by
> > > > toggling the appropriate OTG fsm bits and kicking the state
> > > > machine again.
> > > >
> > >
> > > Well, I think you may misunderstand the OTG FSM and dual-role.
> > > From my and Felipe's point, there are seldom users for USB FSM,
> > > there are only OTG FSM spec and related OTG certification.
> >
> > Probably yes.
> >
> > >
> > > The OTG FSM needs related SoC support, the vbus will be off at
> > > several states, and the SRP should be supported by SoC.
> > >
> > > By default, the dts needs below properties for disabling it if you
> > > choose otg fsm support at kernel configuration.
> > >
> > > &usbotg1 {
> > >         vbus-supply = <&reg_usb_otg1_vbus>;
> > >         srp-disable;
> > >         hnp-disable;
> > >         adp-disable;
> > >         status = "okay";
> > > };
> > >
> > > See Documentation/devicetree/bindings/usb/generic.txt.
> >
> > Does this mean we should be setting all those properties if we're
> > using an extcon for vbus and id?
> 
> It is not related to how we know vbus and id. If your controller is otg-
> capable, and you don't want to enable OTG FSM (just want dual-role), you
> should set them at dts since the zImage is multi-platforms, the
> CONFIG_USB_OTG and CONFIG_USB_OTG_FSM may be chosen.
> 
> > I have noticed that vbus is powered off after some time when no device
> > is connected and we're in A_HOST state because the timeout for a B
> > device connection happens.
> 
> I think it is not you want, but it is OTG compliance.

For simple, if you don't want OTG(i.e HNP&SRP) at all, just needs
dual role, you may disable CONFIG_USB_OTG and CONFIG_USB_OTG_FSM
in your menuconfig, then you don't need touch all those properties.

Li Jun

> 
> --
> 
> Best Regards,
> Peter Chen
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo@vger.kernel.org More majordomo info at
> http://vger.kernel.org/majordomo-info.html

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

* RE: [PATCH 08/21] usb: chipidea: Kick OTG state machine for AVVIS with vbus extcon
@ 2016-06-30  1:50             ` Jun Li
  0 siblings, 0 replies; 214+ messages in thread
From: Jun Li @ 2016-06-30  1:50 UTC (permalink / raw)
  To: Peter Chen, Stephen Boyd
  Cc: linux-usb, linux-arm-kernel, linux-kernel, linux-arm-msm,
	Andy Gross, Bjorn Andersson, Neil Armstrong, Arnd Bergmann,
	Felipe Balbi, Peter Chen, Greg Kroah-Hartman

Hi Stephen,

> -----Original Message-----
> From: linux-usb-owner@vger.kernel.org [mailto:linux-usb-
> owner@vger.kernel.org] On Behalf Of Peter Chen
> Sent: Thursday, June 30, 2016 9:27 AM
> To: Stephen Boyd <stephen.boyd@linaro.org>
> Cc: linux-usb@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> linux-kernel@vger.kernel.org; linux-arm-msm@vger.kernel.org; Andy Gross
> <andy.gross@linaro.org>; Bjorn Andersson <bjorn.andersson@linaro.org>;
> Neil Armstrong <narmstrong@baylibre.com>; Arnd Bergmann <arnd@arndb.de>;
> Felipe Balbi <balbi@kernel.org>; Peter Chen <peter.chen@nxp.com>; Greg
> Kroah-Hartman <gregkh@linuxfoundation.org>
> Subject: Re: [PATCH 08/21] usb: chipidea: Kick OTG state machine for AVVIS
> with vbus extcon
> 
> On Wed, Jun 29, 2016 at 06:19:59PM -0700, Stephen Boyd wrote:
> > Quoting Peter Chen (2016-06-28 20:09:13)
> > > On Sun, Jun 26, 2016 at 12:28:25AM -0700, Stephen Boyd wrote:
> > > > Force the OTG state machine to go forward when we're using an
> > > > extcon for vbus detection. In this case, the controller may never
> > > > raise an interrupt for AVVIS, so we need to simulate the event by
> > > > toggling the appropriate OTG fsm bits and kicking the state
> > > > machine again.
> > > >
> > >
> > > Well, I think you may misunderstand the OTG FSM and dual-role.
> > > From my and Felipe's point, there are seldom users for USB FSM,
> > > there are only OTG FSM spec and related OTG certification.
> >
> > Probably yes.
> >
> > >
> > > The OTG FSM needs related SoC support, the vbus will be off at
> > > several states, and the SRP should be supported by SoC.
> > >
> > > By default, the dts needs below properties for disabling it if you
> > > choose otg fsm support at kernel configuration.
> > >
> > > &usbotg1 {
> > >         vbus-supply = <&reg_usb_otg1_vbus>;
> > >         srp-disable;
> > >         hnp-disable;
> > >         adp-disable;
> > >         status = "okay";
> > > };
> > >
> > > See Documentation/devicetree/bindings/usb/generic.txt.
> >
> > Does this mean we should be setting all those properties if we're
> > using an extcon for vbus and id?
> 
> It is not related to how we know vbus and id. If your controller is otg-
> capable, and you don't want to enable OTG FSM (just want dual-role), you
> should set them at dts since the zImage is multi-platforms, the
> CONFIG_USB_OTG and CONFIG_USB_OTG_FSM may be chosen.
> 
> > I have noticed that vbus is powered off after some time when no device
> > is connected and we're in A_HOST state because the timeout for a B
> > device connection happens.
> 
> I think it is not you want, but it is OTG compliance.

For simple, if you don't want OTG(i.e HNP&SRP) at all, just needs
dual role, you may disable CONFIG_USB_OTG and CONFIG_USB_OTG_FSM
in your menuconfig, then you don't need touch all those properties.

Li Jun

> 
> --
> 
> Best Regards,
> Peter Chen
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo@vger.kernel.org More majordomo info at
> http://vger.kernel.org/majordomo-info.html

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

* [PATCH 08/21] usb: chipidea: Kick OTG state machine for AVVIS with vbus extcon
@ 2016-06-30  1:50             ` Jun Li
  0 siblings, 0 replies; 214+ messages in thread
From: Jun Li @ 2016-06-30  1:50 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Stephen,

> -----Original Message-----
> From: linux-usb-owner at vger.kernel.org [mailto:linux-usb-
> owner at vger.kernel.org] On Behalf Of Peter Chen
> Sent: Thursday, June 30, 2016 9:27 AM
> To: Stephen Boyd <stephen.boyd@linaro.org>
> Cc: linux-usb at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> linux-kernel at vger.kernel.org; linux-arm-msm at vger.kernel.org; Andy Gross
> <andy.gross@linaro.org>; Bjorn Andersson <bjorn.andersson@linaro.org>;
> Neil Armstrong <narmstrong@baylibre.com>; Arnd Bergmann <arnd@arndb.de>;
> Felipe Balbi <balbi@kernel.org>; Peter Chen <peter.chen@nxp.com>; Greg
> Kroah-Hartman <gregkh@linuxfoundation.org>
> Subject: Re: [PATCH 08/21] usb: chipidea: Kick OTG state machine for AVVIS
> with vbus extcon
> 
> On Wed, Jun 29, 2016 at 06:19:59PM -0700, Stephen Boyd wrote:
> > Quoting Peter Chen (2016-06-28 20:09:13)
> > > On Sun, Jun 26, 2016 at 12:28:25AM -0700, Stephen Boyd wrote:
> > > > Force the OTG state machine to go forward when we're using an
> > > > extcon for vbus detection. In this case, the controller may never
> > > > raise an interrupt for AVVIS, so we need to simulate the event by
> > > > toggling the appropriate OTG fsm bits and kicking the state
> > > > machine again.
> > > >
> > >
> > > Well, I think you may misunderstand the OTG FSM and dual-role.
> > > From my and Felipe's point, there are seldom users for USB FSM,
> > > there are only OTG FSM spec and related OTG certification.
> >
> > Probably yes.
> >
> > >
> > > The OTG FSM needs related SoC support, the vbus will be off at
> > > several states, and the SRP should be supported by SoC.
> > >
> > > By default, the dts needs below properties for disabling it if you
> > > choose otg fsm support at kernel configuration.
> > >
> > > &usbotg1 {
> > >         vbus-supply = <&reg_usb_otg1_vbus>;
> > >         srp-disable;
> > >         hnp-disable;
> > >         adp-disable;
> > >         status = "okay";
> > > };
> > >
> > > See Documentation/devicetree/bindings/usb/generic.txt.
> >
> > Does this mean we should be setting all those properties if we're
> > using an extcon for vbus and id?
> 
> It is not related to how we know vbus and id. If your controller is otg-
> capable, and you don't want to enable OTG FSM (just want dual-role), you
> should set them at dts since the zImage is multi-platforms, the
> CONFIG_USB_OTG and CONFIG_USB_OTG_FSM may be chosen.
> 
> > I have noticed that vbus is powered off after some time when no device
> > is connected and we're in A_HOST state because the timeout for a B
> > device connection happens.
> 
> I think it is not you want, but it is OTG compliance.

For simple, if you don't want OTG(i.e HNP&SRP) at all, just needs
dual role, you may disable CONFIG_USB_OTG and CONFIG_USB_OTG_FSM
in your menuconfig, then you don't need touch all those properties.

Li Jun

> 
> --
> 
> Best Regards,
> Peter Chen
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo at vger.kernel.org More majordomo info at
> http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 15/21] usb: chipidea: msm: Mux over secondary phy at the right time
  2016-06-29 19:28       ` Stephen Boyd
@ 2016-06-30  1:52         ` Peter Chen
  -1 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-30  1:52 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, Felipe Balbi, Arnd Bergmann, Neil Armstrong,
	linux-arm-msm, linux-kernel, Bjorn Andersson, Peter Chen,
	Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

On Wed, Jun 29, 2016 at 12:28:58PM -0700, Stephen Boyd wrote:
> Quoting Peter Chen (2016-06-29 01:08:52)
> > On Sun, Jun 26, 2016 at 12:28:32AM -0700, Stephen Boyd wrote:
> > > We need to pick the correct phy at runtime based on how the SoC
> > > has been wired onto the board. If the secondary phy is used, take
> > > it out of reset and mux over to it by writing into the TCSR
> > > register. Make sure to do this on reset too, because this
> > > register is reset to the default value (primary phy) after the
> > > RESET bit is set in USBCMD.
> > > 
> > 
> > I am curious when you need the secondary phy?
> > 
> > > Cc: Peter Chen <peter.chen@nxp.com>
> > > Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > > Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> > > ---
> > >  drivers/usb/chipidea/ci_hdrc_msm.c | 78 +++++++++++++++++++++++++++++++++++---
> > >  1 file changed, 73 insertions(+), 5 deletions(-)
> > > 
> > > diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> > > index 40249b0e3e93..df0f8b31db4f 100644
> > > --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> > > +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> > > @@ -8,30 +8,40 @@
> > >  #include <linux/module.h>
> > >  #include <linux/platform_device.h>
> > >  #include <linux/pm_runtime.h>
> > > -#include <linux/usb/gadget.h>
> > >  #include <linux/usb/chipidea.h>
> > >  #include <linux/clk.h>
> > >  #include <linux/reset.h>
> > > +#include <linux/mfd/syscon.h>
> > > +#include <linux/regmap.h>
> > > +#include <linux/io.h>
> > >  
> > >  #include "ci.h"
> > >  
> > >  #define HS_PHY_AHB_MODE                      0x0098
> > > +#define HS_PHY_SEC_CTRL                      0x0278
> > > +# define HS_PHY_DIG_CLAMP_N          BIT(16)
> > >  
> > 
> > One space at the beginning, and keep alignment.
> > 
> > >  struct ci_hdrc_msm {
> > >       struct platform_device *ci;
> > >       struct clk *core_clk;
> > >       struct clk *iface_clk;
> > > +     bool secondary_phy;
> > > +     void __iomem *base;
> > >  };
> > >  
> > >  static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
> > >  {
> > > -     struct device *dev = ci->gadget.dev.parent;
> > > +     struct device *dev = ci->dev->parent;
> > > +     struct ci_hdrc_msm *msm_ci = dev_get_drvdata(dev);
> > >  
> > >       switch (event) {
> > >       case CI_HDRC_CONTROLLER_RESET_EVENT:
> > >               dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
> > >               /* use AHB transactor, allow posted data writes */
> > >               hw_write_id_reg(ci, HS_PHY_AHB_MODE, 0xffffffff, 0x8);
> > > +             if (msm_ci->secondary_phy)
> > > +                     hw_write_id_reg(ci, HS_PHY_SEC_CTRL, HS_PHY_DIG_CLAMP_N,
> > > +                                     HS_PHY_DIG_CLAMP_N);
> > >               break;
> > >       default:
> > >               dev_dbg(dev, "unknown ci_hdrc event\n");
> > > @@ -49,12 +59,58 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
> > >       .notify_event           = ci_hdrc_msm_notify_event,
> > >  };
> > >  
> > > +static int ci_hdrc_msm_mux_phy(struct ci_hdrc_msm *ci,
> > > +                            struct platform_device *pdev)
> > > +{
> > > +     struct regmap *regmap;
> > > +     struct device_node *syscon;
> > > +     struct device *dev = &pdev->dev;
> > > +     u32 off, val;
> > > +     int ret;
> > > +
> > > +     syscon = of_parse_phandle(dev->of_node, "phy-select", 0);
> > > +     if (!syscon)
> > > +             return 0;
> > > +
> > > +     regmap = syscon_node_to_regmap(syscon);
> > > +     if (IS_ERR(regmap))
> > > +             return PTR_ERR(regmap);
> > > +
> > > +     ret = of_property_read_u32_index(dev->of_node, "phy-select", 1, &off);
> > > +     if (ret < 0) {
> > > +             dev_err(dev, "no offset in syscon\n");
> > > +             return -EINVAL;
> > > +     }
> > > +
> > > +     ret = of_property_read_u32_index(dev->of_node, "phy-select", 2, &val);
> > > +     if (ret < 0) {
> > > +             dev_err(dev, "no value in syscon\n");
> > > +             return -EINVAL;
> > > +     }
> > > +
> > > +     ret = regmap_write(regmap, off, val);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     ci->secondary_phy = !!val;
> > > +     if (ci->secondary_phy) {
> > > +             val = readl_relaxed(ci->base + HS_PHY_SEC_CTRL);
> > > +             val |= HS_PHY_DIG_CLAMP_N;
> > > +             writel_relaxed(val, ci->base + HS_PHY_SEC_CTRL);
> > > +     }
> > > +
> > > +     return 0;
> > > +}
> > > +
> > >  static int ci_hdrc_msm_probe(struct platform_device *pdev)
> > >  {
> > >       struct ci_hdrc_msm *ci;
> > >       struct platform_device *plat_ci;
> > >       struct clk *clk;
> > >       struct reset_control *reset;
> > > +     struct resource *res;
> > > +     void __iomem *base;
> > > +     resource_size_t size;
> > >       int ret;
> > >  
> > >       dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
> > > @@ -76,6 +132,15 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
> > >       if (IS_ERR(clk))
> > >               return PTR_ERR(clk);
> > >  
> > > +     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > > +     if (!res)
> > > +             return -ENODEV;
> > > +
> > > +     size = resource_size(res);
> > > +     ci->base = base = devm_ioremap(&pdev->dev, res->start, size);
> > > +     if (!base)
> > > +             return -ENOMEM;
> > > +
> > 
> > The core will do the ioremap too, you can't remap io address two times.
> 
> You can ioremap an address twice, but it's not a great solution. On ARM,
> at least, we detect the double mapping and return the same virtual
> address the second time.
> 
> > The offset larger than 0x200 is vendor specific, you can map it as
> > the second io region.
> 
> Ok. That would mean we need to adjust the binding then to have to reg
> properties?

Just using two regs at dts, the second one is dedicated for glue layer.

> Or we can limit the size of the resource in the core and the
> size of the resource here can be bumped up by 0x200. So DT still says
> one resource for the entire ci address space but we don't map anything
> more than what we use. Something like this?
> 
> ---8<----
> diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> index 4c70fa6fdc34..1121cf3e3fdc 100644
> --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> @@ -190,8 +190,9 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  	if (!res)
>  		return -ENODEV;
>  
> -	size = resource_size(res);
> -	ci->base = base = devm_ioremap(&pdev->dev, res->start, size);
> +	res->start += 0x200;
> +	res->end -= 0x200;
> +	ci->base = base = devm_ioremap_resource(&pdev->dev, res);
>  	if (!base)
>  		return -ENOMEM;
>  
> diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
> index 298029a9ffce..8f5782913b11 100644
> --- a/drivers/usb/chipidea/core.c
> +++ b/drivers/usb/chipidea/core.c
> @@ -887,6 +887,8 @@ static int ci_hdrc_probe(struct platform_device *pdev)
>  	}
>  
>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (resource_size(res) > 0x200)
> +		res->end = res->start + 0x200;
>  	base = devm_ioremap_resource(dev, res);
>  	if (IS_ERR(base))
>  		return PTR_ERR(base);
> 

No, don't do it. Keep the core unchanging, and map the second regs at
glue layer.

-- 

Best Regards,
Peter Chen

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

* [PATCH 15/21] usb: chipidea: msm: Mux over secondary phy at the right time
@ 2016-06-30  1:52         ` Peter Chen
  0 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-30  1:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jun 29, 2016 at 12:28:58PM -0700, Stephen Boyd wrote:
> Quoting Peter Chen (2016-06-29 01:08:52)
> > On Sun, Jun 26, 2016 at 12:28:32AM -0700, Stephen Boyd wrote:
> > > We need to pick the correct phy at runtime based on how the SoC
> > > has been wired onto the board. If the secondary phy is used, take
> > > it out of reset and mux over to it by writing into the TCSR
> > > register. Make sure to do this on reset too, because this
> > > register is reset to the default value (primary phy) after the
> > > RESET bit is set in USBCMD.
> > > 
> > 
> > I am curious when you need the secondary phy?
> > 
> > > Cc: Peter Chen <peter.chen@nxp.com>
> > > Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > > Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> > > ---
> > >  drivers/usb/chipidea/ci_hdrc_msm.c | 78 +++++++++++++++++++++++++++++++++++---
> > >  1 file changed, 73 insertions(+), 5 deletions(-)
> > > 
> > > diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> > > index 40249b0e3e93..df0f8b31db4f 100644
> > > --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> > > +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> > > @@ -8,30 +8,40 @@
> > >  #include <linux/module.h>
> > >  #include <linux/platform_device.h>
> > >  #include <linux/pm_runtime.h>
> > > -#include <linux/usb/gadget.h>
> > >  #include <linux/usb/chipidea.h>
> > >  #include <linux/clk.h>
> > >  #include <linux/reset.h>
> > > +#include <linux/mfd/syscon.h>
> > > +#include <linux/regmap.h>
> > > +#include <linux/io.h>
> > >  
> > >  #include "ci.h"
> > >  
> > >  #define HS_PHY_AHB_MODE                      0x0098
> > > +#define HS_PHY_SEC_CTRL                      0x0278
> > > +# define HS_PHY_DIG_CLAMP_N          BIT(16)
> > >  
> > 
> > One space at the beginning, and keep alignment.
> > 
> > >  struct ci_hdrc_msm {
> > >       struct platform_device *ci;
> > >       struct clk *core_clk;
> > >       struct clk *iface_clk;
> > > +     bool secondary_phy;
> > > +     void __iomem *base;
> > >  };
> > >  
> > >  static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
> > >  {
> > > -     struct device *dev = ci->gadget.dev.parent;
> > > +     struct device *dev = ci->dev->parent;
> > > +     struct ci_hdrc_msm *msm_ci = dev_get_drvdata(dev);
> > >  
> > >       switch (event) {
> > >       case CI_HDRC_CONTROLLER_RESET_EVENT:
> > >               dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
> > >               /* use AHB transactor, allow posted data writes */
> > >               hw_write_id_reg(ci, HS_PHY_AHB_MODE, 0xffffffff, 0x8);
> > > +             if (msm_ci->secondary_phy)
> > > +                     hw_write_id_reg(ci, HS_PHY_SEC_CTRL, HS_PHY_DIG_CLAMP_N,
> > > +                                     HS_PHY_DIG_CLAMP_N);
> > >               break;
> > >       default:
> > >               dev_dbg(dev, "unknown ci_hdrc event\n");
> > > @@ -49,12 +59,58 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
> > >       .notify_event           = ci_hdrc_msm_notify_event,
> > >  };
> > >  
> > > +static int ci_hdrc_msm_mux_phy(struct ci_hdrc_msm *ci,
> > > +                            struct platform_device *pdev)
> > > +{
> > > +     struct regmap *regmap;
> > > +     struct device_node *syscon;
> > > +     struct device *dev = &pdev->dev;
> > > +     u32 off, val;
> > > +     int ret;
> > > +
> > > +     syscon = of_parse_phandle(dev->of_node, "phy-select", 0);
> > > +     if (!syscon)
> > > +             return 0;
> > > +
> > > +     regmap = syscon_node_to_regmap(syscon);
> > > +     if (IS_ERR(regmap))
> > > +             return PTR_ERR(regmap);
> > > +
> > > +     ret = of_property_read_u32_index(dev->of_node, "phy-select", 1, &off);
> > > +     if (ret < 0) {
> > > +             dev_err(dev, "no offset in syscon\n");
> > > +             return -EINVAL;
> > > +     }
> > > +
> > > +     ret = of_property_read_u32_index(dev->of_node, "phy-select", 2, &val);
> > > +     if (ret < 0) {
> > > +             dev_err(dev, "no value in syscon\n");
> > > +             return -EINVAL;
> > > +     }
> > > +
> > > +     ret = regmap_write(regmap, off, val);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     ci->secondary_phy = !!val;
> > > +     if (ci->secondary_phy) {
> > > +             val = readl_relaxed(ci->base + HS_PHY_SEC_CTRL);
> > > +             val |= HS_PHY_DIG_CLAMP_N;
> > > +             writel_relaxed(val, ci->base + HS_PHY_SEC_CTRL);
> > > +     }
> > > +
> > > +     return 0;
> > > +}
> > > +
> > >  static int ci_hdrc_msm_probe(struct platform_device *pdev)
> > >  {
> > >       struct ci_hdrc_msm *ci;
> > >       struct platform_device *plat_ci;
> > >       struct clk *clk;
> > >       struct reset_control *reset;
> > > +     struct resource *res;
> > > +     void __iomem *base;
> > > +     resource_size_t size;
> > >       int ret;
> > >  
> > >       dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
> > > @@ -76,6 +132,15 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
> > >       if (IS_ERR(clk))
> > >               return PTR_ERR(clk);
> > >  
> > > +     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > > +     if (!res)
> > > +             return -ENODEV;
> > > +
> > > +     size = resource_size(res);
> > > +     ci->base = base = devm_ioremap(&pdev->dev, res->start, size);
> > > +     if (!base)
> > > +             return -ENOMEM;
> > > +
> > 
> > The core will do the ioremap too, you can't remap io address two times.
> 
> You can ioremap an address twice, but it's not a great solution. On ARM,
> at least, we detect the double mapping and return the same virtual
> address the second time.
> 
> > The offset larger than 0x200 is vendor specific, you can map it as
> > the second io region.
> 
> Ok. That would mean we need to adjust the binding then to have to reg
> properties?

Just using two regs at dts, the second one is dedicated for glue layer.

> Or we can limit the size of the resource in the core and the
> size of the resource here can be bumped up by 0x200. So DT still says
> one resource for the entire ci address space but we don't map anything
> more than what we use. Something like this?
> 
> ---8<----
> diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c
> index 4c70fa6fdc34..1121cf3e3fdc 100644
> --- a/drivers/usb/chipidea/ci_hdrc_msm.c
> +++ b/drivers/usb/chipidea/ci_hdrc_msm.c
> @@ -190,8 +190,9 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
>  	if (!res)
>  		return -ENODEV;
>  
> -	size = resource_size(res);
> -	ci->base = base = devm_ioremap(&pdev->dev, res->start, size);
> +	res->start += 0x200;
> +	res->end -= 0x200;
> +	ci->base = base = devm_ioremap_resource(&pdev->dev, res);
>  	if (!base)
>  		return -ENOMEM;
>  
> diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
> index 298029a9ffce..8f5782913b11 100644
> --- a/drivers/usb/chipidea/core.c
> +++ b/drivers/usb/chipidea/core.c
> @@ -887,6 +887,8 @@ static int ci_hdrc_probe(struct platform_device *pdev)
>  	}
>  
>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (resource_size(res) > 0x200)
> +		res->end = res->start + 0x200;
>  	base = devm_ioremap_resource(dev, res);
>  	if (IS_ERR(base))
>  		return PTR_ERR(base);
> 

No, don't do it. Keep the core unchanging, and map the second regs at
glue layer.

-- 

Best Regards,
Peter Chen

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

* Re: [PATCH 16/21] usb: chipidea: msm: Restore wrapper settings after reset
  2016-06-29 19:13       ` Stephen Boyd
@ 2016-06-30  8:54         ` Peter Chen
  -1 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-30  8:54 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, Felipe Balbi, Arnd Bergmann, Neil Armstrong,
	linux-arm-msm, linux-kernel, Bjorn Andersson, Peter Chen,
	Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

On Wed, Jun 29, 2016 at 12:13:45PM -0700, Stephen Boyd wrote:
> Quoting Peter Chen (2016-06-29 01:26:48)
> > On Sun, Jun 26, 2016 at 12:28:33AM -0700, Stephen Boyd wrote:
> > > When the RESET bit is set in the USBCMD register it resets quite
> > > @@ -21,11 +23,22 @@
> > >  #define HS_PHY_SEC_CTRL                      0x0278
> > >  # define HS_PHY_DIG_CLAMP_N          BIT(16)
> > >  
> > > +#define HS_PHY_GENCONFIG             0x009c
> > > +# define HS_PHY_TXFIFO_IDLE_FORCE_DIS        BIT(4)
> > > +
> > > +#define HS_PHY_GENCONFIG_2           0x00a0
> > > +# define HS_PHY_SESS_VLD_CTRL_EN     BIT(7)
> > > +# define HS_PHY_ULPI_TX_PKT_EN_CLR_FIX       BIT(19)
> > > +
> > > +#define HSPHY_SESS_VLD_CTRL          BIT(25)
> > > +
> > 
> > Keep alignment please.
> 
> I take it this means it should look like:
> 
> #define HS_PHY_GENCONFIG
> #define HS_PHY_TXFIFO_IDLE_FORCE_DIS
> 
> ?
> 

Yes

> > > @@ -141,6 +172,13 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
> > >       if (!base)
> > >               return -ENOMEM;
> > >  
> > > +     ci->vbus_edev = extcon_get_edev_by_phandle(&pdev->dev, 0);
> > > +     if (IS_ERR(ci->vbus_edev)) {
> > > +             if (PTR_ERR(ci->vbus_edev) != -ENODEV)
> > > +                     return PTR_ERR(ci->vbus_edev);
> > > +             ci->vbus_edev = NULL;
> > > +     }
> > > +
> > 
> > Why not using ci->platdata->vbus_extcon directly?
> 
> Because ci->platdata->vbus_extcon is assigned after the child platform
> driver probes, and we have no idea when that will happen from the
> ci_hdrc_msm driver probe. If we try after ci_hdrc_add_device() we'll
> race with the driver probe and only get the pointer sometimes.

ci->platdata->vbus_extcon->edev is assigned at ci_get_platdata which is
called before ci core device is created.

> 
> > 
> > >       reset_control_assert(reset);
> > >       usleep_range(10000, 12000);
> > >       reset_control_deassert(reset);
> > > @@ -157,6 +195,14 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
> > >       if (ret)
> > >               goto err_mux;
> > >  
> > > +     ulpi_node = of_find_node_by_name(pdev->dev.of_node, "ulpi");
> > > +     if (ulpi_node) {
> > > +             phy_node = of_get_next_available_child(ulpi_node, NULL);
> > > +             ci->hsic = of_device_is_compatible(phy_node, "qcom,usb-hsic-phy");
> > > +             of_node_put(phy_node);
> > > +     }
> > > +     of_node_put(ulpi_node);
> > > +
> > 
> > Just confirm with you that ci->platdata->phy_mode is not enough?
> 
> Right. The phy_mode is never set to HSIC. It's always ULPI.

Ok

-- 

Best Regards,
Peter Chen

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

* [PATCH 16/21] usb: chipidea: msm: Restore wrapper settings after reset
@ 2016-06-30  8:54         ` Peter Chen
  0 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-30  8:54 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jun 29, 2016 at 12:13:45PM -0700, Stephen Boyd wrote:
> Quoting Peter Chen (2016-06-29 01:26:48)
> > On Sun, Jun 26, 2016 at 12:28:33AM -0700, Stephen Boyd wrote:
> > > When the RESET bit is set in the USBCMD register it resets quite
> > > @@ -21,11 +23,22 @@
> > >  #define HS_PHY_SEC_CTRL                      0x0278
> > >  # define HS_PHY_DIG_CLAMP_N          BIT(16)
> > >  
> > > +#define HS_PHY_GENCONFIG             0x009c
> > > +# define HS_PHY_TXFIFO_IDLE_FORCE_DIS        BIT(4)
> > > +
> > > +#define HS_PHY_GENCONFIG_2           0x00a0
> > > +# define HS_PHY_SESS_VLD_CTRL_EN     BIT(7)
> > > +# define HS_PHY_ULPI_TX_PKT_EN_CLR_FIX       BIT(19)
> > > +
> > > +#define HSPHY_SESS_VLD_CTRL          BIT(25)
> > > +
> > 
> > Keep alignment please.
> 
> I take it this means it should look like:
> 
> #define HS_PHY_GENCONFIG
> #define HS_PHY_TXFIFO_IDLE_FORCE_DIS
> 
> ?
> 

Yes

> > > @@ -141,6 +172,13 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
> > >       if (!base)
> > >               return -ENOMEM;
> > >  
> > > +     ci->vbus_edev = extcon_get_edev_by_phandle(&pdev->dev, 0);
> > > +     if (IS_ERR(ci->vbus_edev)) {
> > > +             if (PTR_ERR(ci->vbus_edev) != -ENODEV)
> > > +                     return PTR_ERR(ci->vbus_edev);
> > > +             ci->vbus_edev = NULL;
> > > +     }
> > > +
> > 
> > Why not using ci->platdata->vbus_extcon directly?
> 
> Because ci->platdata->vbus_extcon is assigned after the child platform
> driver probes, and we have no idea when that will happen from the
> ci_hdrc_msm driver probe. If we try after ci_hdrc_add_device() we'll
> race with the driver probe and only get the pointer sometimes.

ci->platdata->vbus_extcon->edev is assigned at ci_get_platdata which is
called before ci core device is created.

> 
> > 
> > >       reset_control_assert(reset);
> > >       usleep_range(10000, 12000);
> > >       reset_control_deassert(reset);
> > > @@ -157,6 +195,14 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
> > >       if (ret)
> > >               goto err_mux;
> > >  
> > > +     ulpi_node = of_find_node_by_name(pdev->dev.of_node, "ulpi");
> > > +     if (ulpi_node) {
> > > +             phy_node = of_get_next_available_child(ulpi_node, NULL);
> > > +             ci->hsic = of_device_is_compatible(phy_node, "qcom,usb-hsic-phy");
> > > +             of_node_put(phy_node);
> > > +     }
> > > +     of_node_put(ulpi_node);
> > > +
> > 
> > Just confirm with you that ci->platdata->phy_mode is not enough?
> 
> Right. The phy_mode is never set to HSIC. It's always ULPI.

Ok

-- 

Best Regards,
Peter Chen

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

* Re: [PATCH 17/21] usb: chipidea: msm: Make platform data driver local instead of global
  2016-06-29 19:17       ` Stephen Boyd
@ 2016-06-30  9:08         ` Peter Chen
  -1 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-30  9:08 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, linux-arm-kernel, linux-kernel, linux-arm-msm,
	Andy Gross, Bjorn Andersson, Neil Armstrong, Arnd Bergmann,
	Felipe Balbi, Peter Chen, Greg Kroah-Hartman

On Wed, Jun 29, 2016 at 12:17:12PM -0700, Stephen Boyd wrote:
> Quoting Peter Chen (2016-06-29 04:29:25)
> > On Sun, Jun 26, 2016 at 12:28:34AM -0700, Stephen Boyd wrote:
> > > @@ -204,7 +201,7 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
> > >       of_node_put(ulpi_node);
> > >  
> > >       plat_ci = ci_hdrc_add_device(&pdev->dev, pdev->resource,
> > > -                                  pdev->num_resources, &ci_hdrc_msm_platdata);
> > > +                                  pdev->num_resources, &ci->pdata);
> > >       if (IS_ERR(plat_ci)) {
> > >               dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
> > >               ret = PTR_ERR(plat_ci);
> > 
> > You can do something like ci_hdrc_usb2.c, it looks simpler. 
> > 
> 
> Do what exactly? I'd rather not do a structure copy because that wastes
> some memory for a structure that is just a template. We add some more
> code here to assign values directly, but that is smaller size wise than
> the large platdata structure that only has a few values set in it.

But you add one struct ci_hdrc_platform_data pdata entry at struct
ci_hdrc_msm which needs to allocate the memory too. Anyway, it is not a 
big problem.

Acked-by: Peter Chen <peter.chen@nxp.com>

-- 

Best Regards,
Peter Chen

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

* [PATCH 17/21] usb: chipidea: msm: Make platform data driver local instead of global
@ 2016-06-30  9:08         ` Peter Chen
  0 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-06-30  9:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jun 29, 2016 at 12:17:12PM -0700, Stephen Boyd wrote:
> Quoting Peter Chen (2016-06-29 04:29:25)
> > On Sun, Jun 26, 2016 at 12:28:34AM -0700, Stephen Boyd wrote:
> > > @@ -204,7 +201,7 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
> > >       of_node_put(ulpi_node);
> > >  
> > >       plat_ci = ci_hdrc_add_device(&pdev->dev, pdev->resource,
> > > -                                  pdev->num_resources, &ci_hdrc_msm_platdata);
> > > +                                  pdev->num_resources, &ci->pdata);
> > >       if (IS_ERR(plat_ci)) {
> > >               dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
> > >               ret = PTR_ERR(plat_ci);
> > 
> > You can do something like ci_hdrc_usb2.c, it looks simpler. 
> > 
> 
> Do what exactly? I'd rather not do a structure copy because that wastes
> some memory for a structure that is just a template. We add some more
> code here to assign values directly, but that is smaller size wise than
> the large platdata structure that only has a few values set in it.

But you add one struct ci_hdrc_platform_data pdata entry at struct
ci_hdrc_msm which needs to allocate the memory too. Anyway, it is not a 
big problem.

Acked-by: Peter Chen <peter.chen@nxp.com>

-- 

Best Regards,
Peter Chen

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

* Re: [PATCH 16/21] usb: chipidea: msm: Restore wrapper settings after reset
  2016-06-30  8:54         ` Peter Chen
  (?)
@ 2016-06-30 16:24           ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-30 16:24 UTC (permalink / raw)
  To: Peter Chen
  Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA, Felipe Balbi, Arnd Bergmann,
	Neil Armstrong, linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	Linux Kernel Mailing List, Bjorn Andersson, Peter Chen,
	Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

On 30 June 2016 at 01:54, Peter Chen <hzpeterchen-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> On Wed, Jun 29, 2016 at 12:13:45PM -0700, Stephen Boyd wrote:
>> Quoting Peter Chen (2016-06-29 01:26:48
>> > Why not using ci->platdata->vbus_extcon directly?
>>
>> Because ci->platdata->vbus_extcon is assigned after the child platform
>> driver probes, and we have no idea when that will happen from the
>> ci_hdrc_msm driver probe. If we try after ci_hdrc_add_device() we'll
>> race with the driver probe and only get the pointer sometimes.
>
> ci->platdata->vbus_extcon->edev is assigned at ci_get_platdata which is
> called before ci core device is created.
>

Ok.
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 16/21] usb: chipidea: msm: Restore wrapper settings after reset
@ 2016-06-30 16:24           ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-30 16:24 UTC (permalink / raw)
  To: Peter Chen
  Cc: linux-usb, Felipe Balbi, Arnd Bergmann, Neil Armstrong,
	linux-arm-msm, Linux Kernel Mailing List, Bjorn Andersson,
	Peter Chen, Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

On 30 June 2016 at 01:54, Peter Chen <hzpeterchen@gmail.com> wrote:
> On Wed, Jun 29, 2016 at 12:13:45PM -0700, Stephen Boyd wrote:
>> Quoting Peter Chen (2016-06-29 01:26:48
>> > Why not using ci->platdata->vbus_extcon directly?
>>
>> Because ci->platdata->vbus_extcon is assigned after the child platform
>> driver probes, and we have no idea when that will happen from the
>> ci_hdrc_msm driver probe. If we try after ci_hdrc_add_device() we'll
>> race with the driver probe and only get the pointer sometimes.
>
> ci->platdata->vbus_extcon->edev is assigned at ci_get_platdata which is
> called before ci core device is created.
>

Ok.

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

* [PATCH 16/21] usb: chipidea: msm: Restore wrapper settings after reset
@ 2016-06-30 16:24           ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-30 16:24 UTC (permalink / raw)
  To: linux-arm-kernel

On 30 June 2016 at 01:54, Peter Chen <hzpeterchen@gmail.com> wrote:
> On Wed, Jun 29, 2016 at 12:13:45PM -0700, Stephen Boyd wrote:
>> Quoting Peter Chen (2016-06-29 01:26:48
>> > Why not using ci->platdata->vbus_extcon directly?
>>
>> Because ci->platdata->vbus_extcon is assigned after the child platform
>> driver probes, and we have no idea when that will happen from the
>> ci_hdrc_msm driver probe. If we try after ci_hdrc_add_device() we'll
>> race with the driver probe and only get the pointer sometimes.
>
> ci->platdata->vbus_extcon->edev is assigned at ci_get_platdata which is
> called before ci core device is created.
>

Ok.

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

* Re: [PATCH 12/21] usb: chipidea: msm: Keep device runtime enabled
  2016-06-30  1:39         ` Peter Chen
@ 2016-06-30 20:30           ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-30 20:30 UTC (permalink / raw)
  To: Peter Chen
  Cc: Felipe Balbi, Arnd Bergmann, Neil Armstrong, linux-arm-msm,
	linux-pm, linux-usb, linux-kernel, Bjorn Andersson, Peter Chen,
	Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

Quoting Peter Chen (2016-06-29 18:39:01)
> On Wed, Jun 29, 2016 at 05:43:30PM -0700, Stephen Boyd wrote:
> > Quoting Peter Chen (2016-06-28 23:46:00)
> > > On Sun, Jun 26, 2016 at 12:28:29AM -0700, Stephen Boyd wrote:
> > > > Sometimes the usb wrapper device is part of a power domain that
> > > > needs to stay on as long as the device is active. Let's get and
> > > > put the device in driver probe/remove so that we keep the power
> > > > domain powered as long as the device is attached. We can fine
> > > > tune this later to handle wakeup interrupts, etc. for finer grain
> > > > power management later, but this is necessary to make sure we can
> > > > keep accessing the device right now.
> > > 
> > > Since some of the controllers work abnormal if we enables runtime
> > > pm unconditionally, so I use one system flag CI_HDRC_SUPPORTS_RUNTIME_PM
> > > for it. I can't understand why you can't access device without enable
> > > parent's runtime pm, the controller will not enter runtime suspend
> > > without that flag.
> > 
> > Correct, the child device of ci_hdrc_msm will be able to do runtime PM
> > and keep the parent enabled if the CI_HDRC_SUPPORTS_RUNTIME_PM flag is
> > set. But even if that flag isn't set, the ci_hdrc_msm driver is calling
> > pm_runtime_enable() on the same device that it would be called on if the
> > CI_HDRC_SUPPORTS_RUNTIME_PM flag was set. That allows runtime PM
> > transition of child devices such as the usb ports (usb1-port1 for
> > example) to propagate up all the way to the ci_hdrc_msm device and
> > disable any attached power domains.
> 
> Sorry, I can't get you.
> 
> If the chipidea core's runtime is disabled, the port under the
> controller will not be in runtime suspended, only the bus will
> be in suspended due to USB core enables runtime PM by default.

Hmm sorry, I was confused too.

>From what I can tell, if I don't call pm_runtime_set_active() on the
glue device, it will runtime suspend once I call pm_runtime_enable() on
it (which we do in ci_hdrc_mms_probe()). When we runtime suspend the
glue device, we turn off the power domain associated with it too. The
runtime pm enabled state of the core device doesn't seem to matter
either way here. So perhaps I should be calling pm_runtime_set_active()
before pm_runtime_enable() there instead of doing the get/put? It isn't
clear to me when we should be calling pm_runtime_get() vs.
pm_runtime_set_active() though.

> 
> > 
> > Why don't we call runtime PM functions on the ci->dev for all cases of
> > ci->supports_runtime_pm? It seems like the glue drivers should be
> > managing their own device power states and the ci->dev should be managed
> > by core.c code.
> > 
> 
> This is current design. Chipidea core manages portsc.phcd and PHY's PM
> (through PHY's API), and glue layer manages its own clocks on the system
> bus for register visit (and data transfer if necessary).
> 

Sorry, I mean this code in core.c

	pm_runtime_set_active(&pdev->dev);
	pm_runtime_enable(&pdev->dev);
       	pm_runtime_set_autosuspend_delay(&pdev->dev, 2000);
       	pm_runtime_mark_last_busy(ci->dev);
       	pm_runtime_use_autosuspend(&pdev->dev);

which confused me. I thought pdev->dev was the glue device, but it's the
same as ci->dev, the core device. I get it now, but I'd like to change
all the calls there to use ci->dev to be clearer.

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

* [PATCH 12/21] usb: chipidea: msm: Keep device runtime enabled
@ 2016-06-30 20:30           ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-06-30 20:30 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Peter Chen (2016-06-29 18:39:01)
> On Wed, Jun 29, 2016 at 05:43:30PM -0700, Stephen Boyd wrote:
> > Quoting Peter Chen (2016-06-28 23:46:00)
> > > On Sun, Jun 26, 2016 at 12:28:29AM -0700, Stephen Boyd wrote:
> > > > Sometimes the usb wrapper device is part of a power domain that
> > > > needs to stay on as long as the device is active. Let's get and
> > > > put the device in driver probe/remove so that we keep the power
> > > > domain powered as long as the device is attached. We can fine
> > > > tune this later to handle wakeup interrupts, etc. for finer grain
> > > > power management later, but this is necessary to make sure we can
> > > > keep accessing the device right now.
> > > 
> > > Since some of the controllers work abnormal if we enables runtime
> > > pm unconditionally, so I use one system flag CI_HDRC_SUPPORTS_RUNTIME_PM
> > > for it. I can't understand why you can't access device without enable
> > > parent's runtime pm, the controller will not enter runtime suspend
> > > without that flag.
> > 
> > Correct, the child device of ci_hdrc_msm will be able to do runtime PM
> > and keep the parent enabled if the CI_HDRC_SUPPORTS_RUNTIME_PM flag is
> > set. But even if that flag isn't set, the ci_hdrc_msm driver is calling
> > pm_runtime_enable() on the same device that it would be called on if the
> > CI_HDRC_SUPPORTS_RUNTIME_PM flag was set. That allows runtime PM
> > transition of child devices such as the usb ports (usb1-port1 for
> > example) to propagate up all the way to the ci_hdrc_msm device and
> > disable any attached power domains.
> 
> Sorry, I can't get you.
> 
> If the chipidea core's runtime is disabled, the port under the
> controller will not be in runtime suspended, only the bus will
> be in suspended due to USB core enables runtime PM by default.

Hmm sorry, I was confused too.

>From what I can tell, if I don't call pm_runtime_set_active() on the
glue device, it will runtime suspend once I call pm_runtime_enable() on
it (which we do in ci_hdrc_mms_probe()). When we runtime suspend the
glue device, we turn off the power domain associated with it too. The
runtime pm enabled state of the core device doesn't seem to matter
either way here. So perhaps I should be calling pm_runtime_set_active()
before pm_runtime_enable() there instead of doing the get/put? It isn't
clear to me when we should be calling pm_runtime_get() vs.
pm_runtime_set_active() though.

> 
> > 
> > Why don't we call runtime PM functions on the ci->dev for all cases of
> > ci->supports_runtime_pm? It seems like the glue drivers should be
> > managing their own device power states and the ci->dev should be managed
> > by core.c code.
> > 
> 
> This is current design. Chipidea core manages portsc.phcd and PHY's PM
> (through PHY's API), and glue layer manages its own clocks on the system
> bus for register visit (and data transfer if necessary).
> 

Sorry, I mean this code in core.c

	pm_runtime_set_active(&pdev->dev);
	pm_runtime_enable(&pdev->dev);
       	pm_runtime_set_autosuspend_delay(&pdev->dev, 2000);
       	pm_runtime_mark_last_busy(ci->dev);
       	pm_runtime_use_autosuspend(&pdev->dev);

which confused me. I thought pdev->dev was the glue device, but it's the
same as ci->dev, the core device. I get it now, but I'd like to change
all the calls there to use ci->dev to be clearer.

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

* Re: [PATCH 02/21] usb: ulpi: Support device discovery via DT
  2016-06-28 22:09         ` Stephen Boyd
  (?)
@ 2016-07-01  0:59           ` Rob Herring
  -1 siblings, 0 replies; 214+ messages in thread
From: Rob Herring @ 2016-07-01  0:59 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Felipe Balbi, Heikki Krogerus, Arnd Bergmann, Neil Armstrong,
	linux-arm-msm, linux-usb, linux-kernel, Bjorn Andersson,
	devicetree, Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

On Tue, Jun 28, 2016 at 03:09:21PM -0700, Stephen Boyd wrote:
> Quoting Rob Herring (2016-06-28 13:56:42)
> > On Sun, Jun 26, 2016 at 12:28:19AM -0700, Stephen Boyd wrote:
> > > The qcom HSIC ulpi phy doesn't have any bits set in the vendor or
> > > product id ulpi registers. This makes it impossible to make a
> > > ulpi driver match against the id registers. Add support to
> > > discover the ulpi phys via DT to help alleviate this problem.
> > > We'll look for a ulpi bus node underneath the device registering
> > > the ulpi viewport (or the parent of that device to support
> > > chipidea's device layout) and then match up the phy node
> > > underneath that with the ulpi device that's created.
> > > 
> > > The side benefit of this is that we can use standard DT
> > > properties in the phy node like clks, regulators, gpios, etc.
> > > because we don't have firmware like ACPI to turn these things on
> > > for us. And we can use the DT phy binding to point our phy
> > > consumer to the phy provider.
> > > 
> > > Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > > Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> > > Cc: <devicetree@vger.kernel.org>
> > > Cc: Rob Herring <robh+dt@kernel.org>
> > > Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> > > ---
> > >  Documentation/devicetree/bindings/usb/ulpi.txt | 20 +++++++++
> > >  drivers/usb/common/ulpi.c                      | 56 +++++++++++++++++++++++++-
> > >  2 files changed, 74 insertions(+), 2 deletions(-)
> > >  create mode 100644 Documentation/devicetree/bindings/usb/ulpi.txt
> > > 
> > > diff --git a/Documentation/devicetree/bindings/usb/ulpi.txt b/Documentation/devicetree/bindings/usb/ulpi.txt
> > > new file mode 100644
> > > index 000000000000..ca179dc4bd50
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/usb/ulpi.txt
> > > @@ -0,0 +1,20 @@
> > > +ULPI bus binding
> > > +----------------
> > > +
> > > +Phys that are behind a ULPI connection can be described with the following
> > > +binding. The host controller shall have a "ulpi" named node as a child, and
> > > +that node shall have one enabled node underneath it representing the ulpi
> > > +device on the bus.
> > 
> > This needs to co-exist with the USB bus binding which has the controller 
> > ports for the child nodes. Maybe use the phy binding?
> 
> Which binding is that? bindings/usb/usb-device.txt? 

Yes.

> This ulpi binding is
> to describe phys that are accessed through the ulpi "viewport" in the
> usb controller. So controller ports don't come into the picture here.

You just need to confirm that there's no collision with child nodes like 
it assumes all children are ports.

Rob

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

* Re: [PATCH 02/21] usb: ulpi: Support device discovery via DT
@ 2016-07-01  0:59           ` Rob Herring
  0 siblings, 0 replies; 214+ messages in thread
From: Rob Herring @ 2016-07-01  0:59 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, linux-arm-kernel, linux-kernel, linux-arm-msm,
	Andy Gross, Bjorn Andersson, Neil Armstrong, Arnd Bergmann,
	Felipe Balbi, Greg Kroah-Hartman, Heikki Krogerus, devicetree

On Tue, Jun 28, 2016 at 03:09:21PM -0700, Stephen Boyd wrote:
> Quoting Rob Herring (2016-06-28 13:56:42)
> > On Sun, Jun 26, 2016 at 12:28:19AM -0700, Stephen Boyd wrote:
> > > The qcom HSIC ulpi phy doesn't have any bits set in the vendor or
> > > product id ulpi registers. This makes it impossible to make a
> > > ulpi driver match against the id registers. Add support to
> > > discover the ulpi phys via DT to help alleviate this problem.
> > > We'll look for a ulpi bus node underneath the device registering
> > > the ulpi viewport (or the parent of that device to support
> > > chipidea's device layout) and then match up the phy node
> > > underneath that with the ulpi device that's created.
> > > 
> > > The side benefit of this is that we can use standard DT
> > > properties in the phy node like clks, regulators, gpios, etc.
> > > because we don't have firmware like ACPI to turn these things on
> > > for us. And we can use the DT phy binding to point our phy
> > > consumer to the phy provider.
> > > 
> > > Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > > Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> > > Cc: <devicetree@vger.kernel.org>
> > > Cc: Rob Herring <robh+dt@kernel.org>
> > > Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> > > ---
> > >  Documentation/devicetree/bindings/usb/ulpi.txt | 20 +++++++++
> > >  drivers/usb/common/ulpi.c                      | 56 +++++++++++++++++++++++++-
> > >  2 files changed, 74 insertions(+), 2 deletions(-)
> > >  create mode 100644 Documentation/devicetree/bindings/usb/ulpi.txt
> > > 
> > > diff --git a/Documentation/devicetree/bindings/usb/ulpi.txt b/Documentation/devicetree/bindings/usb/ulpi.txt
> > > new file mode 100644
> > > index 000000000000..ca179dc4bd50
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/usb/ulpi.txt
> > > @@ -0,0 +1,20 @@
> > > +ULPI bus binding
> > > +----------------
> > > +
> > > +Phys that are behind a ULPI connection can be described with the following
> > > +binding. The host controller shall have a "ulpi" named node as a child, and
> > > +that node shall have one enabled node underneath it representing the ulpi
> > > +device on the bus.
> > 
> > This needs to co-exist with the USB bus binding which has the controller 
> > ports for the child nodes. Maybe use the phy binding?
> 
> Which binding is that? bindings/usb/usb-device.txt? 

Yes.

> This ulpi binding is
> to describe phys that are accessed through the ulpi "viewport" in the
> usb controller. So controller ports don't come into the picture here.

You just need to confirm that there's no collision with child nodes like 
it assumes all children are ports.

Rob

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

* [PATCH 02/21] usb: ulpi: Support device discovery via DT
@ 2016-07-01  0:59           ` Rob Herring
  0 siblings, 0 replies; 214+ messages in thread
From: Rob Herring @ 2016-07-01  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jun 28, 2016 at 03:09:21PM -0700, Stephen Boyd wrote:
> Quoting Rob Herring (2016-06-28 13:56:42)
> > On Sun, Jun 26, 2016 at 12:28:19AM -0700, Stephen Boyd wrote:
> > > The qcom HSIC ulpi phy doesn't have any bits set in the vendor or
> > > product id ulpi registers. This makes it impossible to make a
> > > ulpi driver match against the id registers. Add support to
> > > discover the ulpi phys via DT to help alleviate this problem.
> > > We'll look for a ulpi bus node underneath the device registering
> > > the ulpi viewport (or the parent of that device to support
> > > chipidea's device layout) and then match up the phy node
> > > underneath that with the ulpi device that's created.
> > > 
> > > The side benefit of this is that we can use standard DT
> > > properties in the phy node like clks, regulators, gpios, etc.
> > > because we don't have firmware like ACPI to turn these things on
> > > for us. And we can use the DT phy binding to point our phy
> > > consumer to the phy provider.
> > > 
> > > Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > > Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> > > Cc: <devicetree@vger.kernel.org>
> > > Cc: Rob Herring <robh+dt@kernel.org>
> > > Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> > > ---
> > >  Documentation/devicetree/bindings/usb/ulpi.txt | 20 +++++++++
> > >  drivers/usb/common/ulpi.c                      | 56 +++++++++++++++++++++++++-
> > >  2 files changed, 74 insertions(+), 2 deletions(-)
> > >  create mode 100644 Documentation/devicetree/bindings/usb/ulpi.txt
> > > 
> > > diff --git a/Documentation/devicetree/bindings/usb/ulpi.txt b/Documentation/devicetree/bindings/usb/ulpi.txt
> > > new file mode 100644
> > > index 000000000000..ca179dc4bd50
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/usb/ulpi.txt
> > > @@ -0,0 +1,20 @@
> > > +ULPI bus binding
> > > +----------------
> > > +
> > > +Phys that are behind a ULPI connection can be described with the following
> > > +binding. The host controller shall have a "ulpi" named node as a child, and
> > > +that node shall have one enabled node underneath it representing the ulpi
> > > +device on the bus.
> > 
> > This needs to co-exist with the USB bus binding which has the controller 
> > ports for the child nodes. Maybe use the phy binding?
> 
> Which binding is that? bindings/usb/usb-device.txt? 

Yes.

> This ulpi binding is
> to describe phys that are accessed through the ulpi "viewport" in the
> usb controller. So controller ports don't come into the picture here.

You just need to confirm that there's no collision with child nodes like 
it assumes all children are ports.

Rob

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

* Re: [PATCH 12/21] usb: chipidea: msm: Keep device runtime enabled
  2016-06-30 20:30           ` Stephen Boyd
@ 2016-07-01  3:20             ` Peter Chen
  -1 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-07-01  3:20 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, linux-arm-kernel, linux-kernel, linux-arm-msm,
	Andy Gross, Bjorn Andersson, Neil Armstrong, Arnd Bergmann,
	Felipe Balbi, Peter Chen, Greg Kroah-Hartman, linux-pm

On Thu, Jun 30, 2016 at 01:30:54PM -0700, Stephen Boyd wrote:
> Quoting Peter Chen (2016-06-29 18:39:01)
> > On Wed, Jun 29, 2016 at 05:43:30PM -0700, Stephen Boyd wrote:
> > > Quoting Peter Chen (2016-06-28 23:46:00)
> > > > On Sun, Jun 26, 2016 at 12:28:29AM -0700, Stephen Boyd wrote:
> > > > > Sometimes the usb wrapper device is part of a power domain that
> > > > > needs to stay on as long as the device is active. Let's get and
> > > > > put the device in driver probe/remove so that we keep the power
> > > > > domain powered as long as the device is attached. We can fine
> > > > > tune this later to handle wakeup interrupts, etc. for finer grain
> > > > > power management later, but this is necessary to make sure we can
> > > > > keep accessing the device right now.
> > > > 
> > > > Since some of the controllers work abnormal if we enables runtime
> > > > pm unconditionally, so I use one system flag CI_HDRC_SUPPORTS_RUNTIME_PM
> > > > for it. I can't understand why you can't access device without enable
> > > > parent's runtime pm, the controller will not enter runtime suspend
> > > > without that flag.
> > > 
> > > Correct, the child device of ci_hdrc_msm will be able to do runtime PM
> > > and keep the parent enabled if the CI_HDRC_SUPPORTS_RUNTIME_PM flag is
> > > set. But even if that flag isn't set, the ci_hdrc_msm driver is calling
> > > pm_runtime_enable() on the same device that it would be called on if the
> > > CI_HDRC_SUPPORTS_RUNTIME_PM flag was set. That allows runtime PM
> > > transition of child devices such as the usb ports (usb1-port1 for
> > > example) to propagate up all the way to the ci_hdrc_msm device and
> > > disable any attached power domains.
> > 
> > Sorry, I can't get you.
> > 
> > If the chipidea core's runtime is disabled, the port under the
> > controller will not be in runtime suspended, only the bus will
> > be in suspended due to USB core enables runtime PM by default.
> 
> Hmm sorry, I was confused too.
> 
> From what I can tell, if I don't call pm_runtime_set_active() on the
> glue device, it will runtime suspend once I call pm_runtime_enable() on
> it (which we do in ci_hdrc_mms_probe()). When we runtime suspend the
> glue device, we turn off the power domain associated with it too. The
> runtime pm enabled state of the core device doesn't seem to matter
> either way here. So perhaps I should be calling pm_runtime_set_active()
> before pm_runtime_enable() there instead of doing the get/put? It isn't
> clear to me when we should be calling pm_runtime_get() vs.
> pm_runtime_set_active() though.
> 
> > 
> > > 
> > > Why don't we call runtime PM functions on the ci->dev for all cases of
> > > ci->supports_runtime_pm? It seems like the glue drivers should be
> > > managing their own device power states and the ci->dev should be managed
> > > by core.c code.
> > > 
> > 
> > This is current design. Chipidea core manages portsc.phcd and PHY's PM
> > (through PHY's API), and glue layer manages its own clocks on the system
> > bus for register visit (and data transfer if necessary).
> > 
> 
> Sorry, I mean this code in core.c
> 
> 	pm_runtime_set_active(&pdev->dev);
> 	pm_runtime_enable(&pdev->dev);
>        	pm_runtime_set_autosuspend_delay(&pdev->dev, 2000);
>        	pm_runtime_mark_last_busy(ci->dev);
>        	pm_runtime_use_autosuspend(&pdev->dev);
> 
> which confused me. I thought pdev->dev was the glue device, but it's the
> same as ci->dev, the core device. I get it now, but I'd like to change
> all the calls there to use ci->dev to be clearer.

Yes, please do it.

Glue device is the parent for core device, and at core.c, only ci_hdrc_add_device and
ci_get_platdata will touch glue device.

-- 

Best Regards,
Peter Chen

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

* [PATCH 12/21] usb: chipidea: msm: Keep device runtime enabled
@ 2016-07-01  3:20             ` Peter Chen
  0 siblings, 0 replies; 214+ messages in thread
From: Peter Chen @ 2016-07-01  3:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jun 30, 2016 at 01:30:54PM -0700, Stephen Boyd wrote:
> Quoting Peter Chen (2016-06-29 18:39:01)
> > On Wed, Jun 29, 2016 at 05:43:30PM -0700, Stephen Boyd wrote:
> > > Quoting Peter Chen (2016-06-28 23:46:00)
> > > > On Sun, Jun 26, 2016 at 12:28:29AM -0700, Stephen Boyd wrote:
> > > > > Sometimes the usb wrapper device is part of a power domain that
> > > > > needs to stay on as long as the device is active. Let's get and
> > > > > put the device in driver probe/remove so that we keep the power
> > > > > domain powered as long as the device is attached. We can fine
> > > > > tune this later to handle wakeup interrupts, etc. for finer grain
> > > > > power management later, but this is necessary to make sure we can
> > > > > keep accessing the device right now.
> > > > 
> > > > Since some of the controllers work abnormal if we enables runtime
> > > > pm unconditionally, so I use one system flag CI_HDRC_SUPPORTS_RUNTIME_PM
> > > > for it. I can't understand why you can't access device without enable
> > > > parent's runtime pm, the controller will not enter runtime suspend
> > > > without that flag.
> > > 
> > > Correct, the child device of ci_hdrc_msm will be able to do runtime PM
> > > and keep the parent enabled if the CI_HDRC_SUPPORTS_RUNTIME_PM flag is
> > > set. But even if that flag isn't set, the ci_hdrc_msm driver is calling
> > > pm_runtime_enable() on the same device that it would be called on if the
> > > CI_HDRC_SUPPORTS_RUNTIME_PM flag was set. That allows runtime PM
> > > transition of child devices such as the usb ports (usb1-port1 for
> > > example) to propagate up all the way to the ci_hdrc_msm device and
> > > disable any attached power domains.
> > 
> > Sorry, I can't get you.
> > 
> > If the chipidea core's runtime is disabled, the port under the
> > controller will not be in runtime suspended, only the bus will
> > be in suspended due to USB core enables runtime PM by default.
> 
> Hmm sorry, I was confused too.
> 
> From what I can tell, if I don't call pm_runtime_set_active() on the
> glue device, it will runtime suspend once I call pm_runtime_enable() on
> it (which we do in ci_hdrc_mms_probe()). When we runtime suspend the
> glue device, we turn off the power domain associated with it too. The
> runtime pm enabled state of the core device doesn't seem to matter
> either way here. So perhaps I should be calling pm_runtime_set_active()
> before pm_runtime_enable() there instead of doing the get/put? It isn't
> clear to me when we should be calling pm_runtime_get() vs.
> pm_runtime_set_active() though.
> 
> > 
> > > 
> > > Why don't we call runtime PM functions on the ci->dev for all cases of
> > > ci->supports_runtime_pm? It seems like the glue drivers should be
> > > managing their own device power states and the ci->dev should be managed
> > > by core.c code.
> > > 
> > 
> > This is current design. Chipidea core manages portsc.phcd and PHY's PM
> > (through PHY's API), and glue layer manages its own clocks on the system
> > bus for register visit (and data transfer if necessary).
> > 
> 
> Sorry, I mean this code in core.c
> 
> 	pm_runtime_set_active(&pdev->dev);
> 	pm_runtime_enable(&pdev->dev);
>        	pm_runtime_set_autosuspend_delay(&pdev->dev, 2000);
>        	pm_runtime_mark_last_busy(ci->dev);
>        	pm_runtime_use_autosuspend(&pdev->dev);
> 
> which confused me. I thought pdev->dev was the glue device, but it's the
> same as ci->dev, the core device. I get it now, but I'd like to change
> all the calls there to use ci->dev to be clearer.

Yes, please do it.

Glue device is the parent for core device, and at core.c, only ci_hdrc_add_device and
ci_get_platdata will touch glue device.

-- 

Best Regards,
Peter Chen

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

* Re: [PATCH 00/21] Support qcom's HSIC USB and rewrite USB2 HS phy support
  2016-06-28  8:34       ` Stephen Boyd
  (?)
@ 2016-07-02  6:03         ` John Stultz
  -1 siblings, 0 replies; 214+ messages in thread
From: John Stultz @ 2016-07-02  6:03 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, Felipe Balbi, Heikki Krogerus, Arnd Bergmann,
	Neil Armstrong, linux-arm-msm, lkml, Bjorn Andersson, devicetree,
	Rob Herring, Peter Chen, Greg Kroah-Hartman, Andy Gross,
	Ivan T. Ivanov, Kishon Vijay Abraham I, linux-arm-kernel

On Tue, Jun 28, 2016 at 1:34 AM, Stephen Boyd <stephen.boyd@linaro.org> wrote:
> Quoting John Stultz (2016-06-27 20:09:30)
>>
>> I haven't yet been able to test with this, as I need some other fixes
>> it seems too to deal with some of the iommu changes in my flo-WIP tree
>> (it can't find of_dma_configure), but will let you know how things
>> work once I have all that sorted.
>
> Cool, thanks for testing.

So after working out some merge issues w/ my flo-WIP branch for the
nexus7, I was still having trouble, so I backed out to just your
(updated) branch.

But even there, I'm not able to get the usb gadget up. I see:

[    1.869717] msm_hsusb 12500000.usb: failed to get phandle in
/soc/usb@12500000 node
[    1.882347] 12500000.usb supply vbus not found, using dummy regulator

So I'm not sure if the dts changes were quite right. I've got all the
ULPI configs enabled. Any ideas?

thanks
-john

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

* Re: [PATCH 00/21] Support qcom's HSIC USB and rewrite USB2 HS phy support
@ 2016-07-02  6:03         ` John Stultz
  0 siblings, 0 replies; 214+ messages in thread
From: John Stultz @ 2016-07-02  6:03 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, Felipe Balbi, Heikki Krogerus, Arnd Bergmann,
	Neil Armstrong, linux-arm-msm, lkml, Bjorn Andersson, devicetree,
	Rob Herring, Peter Chen, Greg Kroah-Hartman, Andy Gross,
	Ivan T. Ivanov, Kishon Vijay Abraham I, linux-arm-kernel

On Tue, Jun 28, 2016 at 1:34 AM, Stephen Boyd <stephen.boyd@linaro.org> wrote:
> Quoting John Stultz (2016-06-27 20:09:30)
>>
>> I haven't yet been able to test with this, as I need some other fixes
>> it seems too to deal with some of the iommu changes in my flo-WIP tree
>> (it can't find of_dma_configure), but will let you know how things
>> work once I have all that sorted.
>
> Cool, thanks for testing.

So after working out some merge issues w/ my flo-WIP branch for the
nexus7, I was still having trouble, so I backed out to just your
(updated) branch.

But even there, I'm not able to get the usb gadget up. I see:

[    1.869717] msm_hsusb 12500000.usb: failed to get phandle in
/soc/usb@12500000 node
[    1.882347] 12500000.usb supply vbus not found, using dummy regulator

So I'm not sure if the dts changes were quite right. I've got all the
ULPI configs enabled. Any ideas?

thanks
-john

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

* [PATCH 00/21] Support qcom's HSIC USB and rewrite USB2 HS phy support
@ 2016-07-02  6:03         ` John Stultz
  0 siblings, 0 replies; 214+ messages in thread
From: John Stultz @ 2016-07-02  6:03 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jun 28, 2016 at 1:34 AM, Stephen Boyd <stephen.boyd@linaro.org> wrote:
> Quoting John Stultz (2016-06-27 20:09:30)
>>
>> I haven't yet been able to test with this, as I need some other fixes
>> it seems too to deal with some of the iommu changes in my flo-WIP tree
>> (it can't find of_dma_configure), but will let you know how things
>> work once I have all that sorted.
>
> Cool, thanks for testing.

So after working out some merge issues w/ my flo-WIP branch for the
nexus7, I was still having trouble, so I backed out to just your
(updated) branch.

But even there, I'm not able to get the usb gadget up. I see:

[    1.869717] msm_hsusb 12500000.usb: failed to get phandle in
/soc/usb at 12500000 node
[    1.882347] 12500000.usb supply vbus not found, using dummy regulator

So I'm not sure if the dts changes were quite right. I've got all the
ULPI configs enabled. Any ideas?

thanks
-john

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

* Re: [PATCH 00/21] Support qcom's HSIC USB and rewrite USB2 HS phy support
  2016-07-02  6:03         ` John Stultz
@ 2016-07-05 19:22           ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-07-05 19:22 UTC (permalink / raw)
  To: John Stultz
  Cc: Felipe Balbi, Heikki Krogerus, Arnd Bergmann, Neil Armstrong,
	linux-arm-msm, linux-usb, lkml, Bjorn Andersson, devicetree,
	Rob Herring, Peter Chen, Greg Kroah-Hartman, Andy Gross,
	Ivan T. Ivanov, Kishon Vijay Abraham I, linux-arm-kernel

Quoting John Stultz (2016-07-01 23:03:38)
> On Tue, Jun 28, 2016 at 1:34 AM, Stephen Boyd <stephen.boyd@linaro.org> wrote:
> > Quoting John Stultz (2016-06-27 20:09:30)
> >>
> >> I haven't yet been able to test with this, as I need some other fixes
> >> it seems too to deal with some of the iommu changes in my flo-WIP tree
> >> (it can't find of_dma_configure), but will let you know how things
> >> work once I have all that sorted.
> >
> > Cool, thanks for testing.
> 
> So after working out some merge issues w/ my flo-WIP branch for the
> nexus7, I was still having trouble, so I backed out to just your
> (updated) branch.
> 
> But even there, I'm not able to get the usb gadget up. I see:

I can get the gadget working on the ifc6410 device I have. I'm using
this script to test things:

modprobe libcomposite
mkdir config
mount none config -t configfs
mkdir config/usb_gadget/g1
mkdir config/usb_gadget/g1/strings/0x409
echo 012345678 > config/usb_gadget/g1/strings/0x409/serialnumber
echo "manufacturer" > config/usb_gadget/g1/strings/0x409/manufacturer
echo "db8074" > config/usb_gadget/g1/strings/0x409/product
echo 0x1d6b > config/usb_gadget/g1/idVendor
echo 0x0104 > config/usb_gadget/g1/idProduct
mkdir config/usb_gadget/g1/functions/acm.GS0
mkdir config/usb_gadget/g1/functions/acm.GS1
mkdir config/usb_gadget/g1/functions/ecm.usb0
mkdir config/usb_gadget/g1/configs/c.1
mkdir config/usb_gadget/g1/configs/c.1/strings/0x409/
echo "CDC 2xACM+ECM" >
config/usb_gadget/g1/configs/c.1/strings/0x409/configuration
ln -s config/usb_gadget/g1/functions/acm.GS0
config/usb_gadget/g1/configs/c.1
ln -s config/usb_gadget/g1/functions/acm.GS1
config/usb_gadget/g1/configs/c.1
ln -s config/usb_gadget/g1/functions/ecm.usb0
config/usb_gadget/g1/configs/c.1
echo $(ls /sys/class/udc/) > config/usb_gadget/g1/UDC

> 
> [    1.869717] msm_hsusb 12500000.usb: failed to get phandle in
> /soc/usb@12500000 node

This is sort of ok (I've seen it before with the HSIC controller on
8074). The extcon is optional and so the error message should be
silenced. I sent a patch to move it to debug level.

I don't see an extcon in mainline for apq8064, but I think it may be
needed. At the least, I see that we're using a PMIC interrupt in the
msm-3.4 kernel for the ID pin and the charger is notifying of vbus
events similar to how smbb is doing it for apq8074.

> [    1.882347] 12500000.usb supply vbus not found, using dummy regulator

This is not great. We don't have a regulator specified on apq8064 so we
can't turn on vbus and really support host mode. This seems to already
be the case on mainline though, so it's not like we're any worse here.
To properly support this we need a regulator driver. I suppose if the
RPM supports it we can just use that, but if it doesn't support this
regulator then we need to port over the SSBI regulator driver to do
native regulator control. So far I haven't been able to test host mode
on apq8064 because of this.

> 
> So I'm not sure if the dts changes were quite right. I've got all the
> ULPI configs enabled. Any ideas?
> 

The phy and controller are both probing? If they're not failing to probe
then it's probably the phy that isn't working properly. Does gadget work
without my patches on nexus7?

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

* [PATCH 00/21] Support qcom's HSIC USB and rewrite USB2 HS phy support
@ 2016-07-05 19:22           ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-07-05 19:22 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting John Stultz (2016-07-01 23:03:38)
> On Tue, Jun 28, 2016 at 1:34 AM, Stephen Boyd <stephen.boyd@linaro.org> wrote:
> > Quoting John Stultz (2016-06-27 20:09:30)
> >>
> >> I haven't yet been able to test with this, as I need some other fixes
> >> it seems too to deal with some of the iommu changes in my flo-WIP tree
> >> (it can't find of_dma_configure), but will let you know how things
> >> work once I have all that sorted.
> >
> > Cool, thanks for testing.
> 
> So after working out some merge issues w/ my flo-WIP branch for the
> nexus7, I was still having trouble, so I backed out to just your
> (updated) branch.
> 
> But even there, I'm not able to get the usb gadget up. I see:

I can get the gadget working on the ifc6410 device I have. I'm using
this script to test things:

modprobe libcomposite
mkdir config
mount none config -t configfs
mkdir config/usb_gadget/g1
mkdir config/usb_gadget/g1/strings/0x409
echo 012345678 > config/usb_gadget/g1/strings/0x409/serialnumber
echo "manufacturer" > config/usb_gadget/g1/strings/0x409/manufacturer
echo "db8074" > config/usb_gadget/g1/strings/0x409/product
echo 0x1d6b > config/usb_gadget/g1/idVendor
echo 0x0104 > config/usb_gadget/g1/idProduct
mkdir config/usb_gadget/g1/functions/acm.GS0
mkdir config/usb_gadget/g1/functions/acm.GS1
mkdir config/usb_gadget/g1/functions/ecm.usb0
mkdir config/usb_gadget/g1/configs/c.1
mkdir config/usb_gadget/g1/configs/c.1/strings/0x409/
echo "CDC 2xACM+ECM" >
config/usb_gadget/g1/configs/c.1/strings/0x409/configuration
ln -s config/usb_gadget/g1/functions/acm.GS0
config/usb_gadget/g1/configs/c.1
ln -s config/usb_gadget/g1/functions/acm.GS1
config/usb_gadget/g1/configs/c.1
ln -s config/usb_gadget/g1/functions/ecm.usb0
config/usb_gadget/g1/configs/c.1
echo $(ls /sys/class/udc/) > config/usb_gadget/g1/UDC

> 
> [    1.869717] msm_hsusb 12500000.usb: failed to get phandle in
> /soc/usb at 12500000 node

This is sort of ok (I've seen it before with the HSIC controller on
8074). The extcon is optional and so the error message should be
silenced. I sent a patch to move it to debug level.

I don't see an extcon in mainline for apq8064, but I think it may be
needed. At the least, I see that we're using a PMIC interrupt in the
msm-3.4 kernel for the ID pin and the charger is notifying of vbus
events similar to how smbb is doing it for apq8074.

> [    1.882347] 12500000.usb supply vbus not found, using dummy regulator

This is not great. We don't have a regulator specified on apq8064 so we
can't turn on vbus and really support host mode. This seems to already
be the case on mainline though, so it's not like we're any worse here.
To properly support this we need a regulator driver. I suppose if the
RPM supports it we can just use that, but if it doesn't support this
regulator then we need to port over the SSBI regulator driver to do
native regulator control. So far I haven't been able to test host mode
on apq8064 because of this.

> 
> So I'm not sure if the dts changes were quite right. I've got all the
> ULPI configs enabled. Any ideas?
> 

The phy and controller are both probing? If they're not failing to probe
then it's probably the phy that isn't working properly. Does gadget work
without my patches on nexus7?

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

* Re: [PATCH 00/21] Support qcom's HSIC USB and rewrite USB2 HS phy support
  2016-07-05 19:22           ` Stephen Boyd
  (?)
@ 2016-07-05 19:33             ` John Stultz
  -1 siblings, 0 replies; 214+ messages in thread
From: John Stultz @ 2016-07-05 19:33 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, Felipe Balbi, Heikki Krogerus, Arnd Bergmann,
	Neil Armstrong, linux-arm-msm, lkml, Bjorn Andersson, devicetree,
	Rob Herring, Peter Chen, Greg Kroah-Hartman, Andy Gross,
	Ivan T. Ivanov, Kishon Vijay Abraham I, linux-arm-kernel

On Tue, Jul 5, 2016 at 12:22 PM, Stephen Boyd <stephen.boyd@linaro.org> wrote:
> Quoting John Stultz (2016-07-01 23:03:38)
>> On Tue, Jun 28, 2016 at 1:34 AM, Stephen Boyd <stephen.boyd@linaro.org> wrote:
>> > Quoting John Stultz (2016-06-27 20:09:30)
>> >>
>> >> I haven't yet been able to test with this, as I need some other fixes
>> >> it seems too to deal with some of the iommu changes in my flo-WIP tree
>> >> (it can't find of_dma_configure), but will let you know how things
>> >> work once I have all that sorted.
>> >
>> > Cool, thanks for testing.
>>
>> So after working out some merge issues w/ my flo-WIP branch for the
>> nexus7, I was still having trouble, so I backed out to just your
>> (updated) branch.
>>
>> But even there, I'm not able to get the usb gadget up. I see:
>
> I can get the gadget working on the ifc6410 device I have. I'm using
> this script to test things:
>
> modprobe libcomposite
> mkdir config
> mount none config -t configfs
> mkdir config/usb_gadget/g1
> mkdir config/usb_gadget/g1/strings/0x409
> echo 012345678 > config/usb_gadget/g1/strings/0x409/serialnumber
> echo "manufacturer" > config/usb_gadget/g1/strings/0x409/manufacturer
> echo "db8074" > config/usb_gadget/g1/strings/0x409/product
> echo 0x1d6b > config/usb_gadget/g1/idVendor
> echo 0x0104 > config/usb_gadget/g1/idProduct
> mkdir config/usb_gadget/g1/functions/acm.GS0
> mkdir config/usb_gadget/g1/functions/acm.GS1
> mkdir config/usb_gadget/g1/functions/ecm.usb0
> mkdir config/usb_gadget/g1/configs/c.1
> mkdir config/usb_gadget/g1/configs/c.1/strings/0x409/
> echo "CDC 2xACM+ECM" >
> config/usb_gadget/g1/configs/c.1/strings/0x409/configuration
> ln -s config/usb_gadget/g1/functions/acm.GS0
> config/usb_gadget/g1/configs/c.1
> ln -s config/usb_gadget/g1/functions/acm.GS1
> config/usb_gadget/g1/configs/c.1
> ln -s config/usb_gadget/g1/functions/ecm.usb0
> config/usb_gadget/g1/configs/c.1
> echo $(ls /sys/class/udc/) > config/usb_gadget/g1/UDC
>
>>
>> [    1.869717] msm_hsusb 12500000.usb: failed to get phandle in
>> /soc/usb@12500000 node
>
> This is sort of ok (I've seen it before with the HSIC controller on
> 8074). The extcon is optional and so the error message should be
> silenced. I sent a patch to move it to debug level.
>
> I don't see an extcon in mainline for apq8064, but I think it may be
> needed. At the least, I see that we're using a PMIC interrupt in the
> msm-3.4 kernel for the ID pin and the charger is notifying of vbus
> events similar to how smbb is doing it for apq8074.
>
>> [    1.882347] 12500000.usb supply vbus not found, using dummy regulator
>
> This is not great. We don't have a regulator specified on apq8064 so we
> can't turn on vbus and really support host mode. This seems to already
> be the case on mainline though, so it's not like we're any worse here.
> To properly support this we need a regulator driver. I suppose if the
> RPM supports it we can just use that, but if it doesn't support this
> regulator then we need to port over the SSBI regulator driver to do
> native regulator control. So far I haven't been able to test host mode
> on apq8064 because of this.
>
>>
>> So I'm not sure if the dts changes were quite right. I've got all the
>> ULPI configs enabled. Any ideas?
>>
>
> The phy and controller are both probing? If they're not failing to probe
> then it's probably the phy that isn't working properly. Does gadget work
> without my patches on nexus7?

Without your patch, I need one dts tweak on nexus7 (which I sent out
on friday[1]) to get the default direction set to OTG or gadget. But
yea, it works with that against mainline.

I'll dig in some more on your suggestions above and let you know if I
figure it out.

thanks
-john

[1]: http://www.spinics.net/lists/devicetree/msg134274.html

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

* Re: [PATCH 00/21] Support qcom's HSIC USB and rewrite USB2 HS phy support
@ 2016-07-05 19:33             ` John Stultz
  0 siblings, 0 replies; 214+ messages in thread
From: John Stultz @ 2016-07-05 19:33 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, Felipe Balbi, Heikki Krogerus, Arnd Bergmann,
	Neil Armstrong, linux-arm-msm, lkml, Bjorn Andersson, devicetree,
	Rob Herring, Peter Chen, Greg Kroah-Hartman, Andy Gross,
	Ivan T. Ivanov, Kishon Vijay Abraham I, linux-arm-kernel

On Tue, Jul 5, 2016 at 12:22 PM, Stephen Boyd <stephen.boyd@linaro.org> wrote:
> Quoting John Stultz (2016-07-01 23:03:38)
>> On Tue, Jun 28, 2016 at 1:34 AM, Stephen Boyd <stephen.boyd@linaro.org> wrote:
>> > Quoting John Stultz (2016-06-27 20:09:30)
>> >>
>> >> I haven't yet been able to test with this, as I need some other fixes
>> >> it seems too to deal with some of the iommu changes in my flo-WIP tree
>> >> (it can't find of_dma_configure), but will let you know how things
>> >> work once I have all that sorted.
>> >
>> > Cool, thanks for testing.
>>
>> So after working out some merge issues w/ my flo-WIP branch for the
>> nexus7, I was still having trouble, so I backed out to just your
>> (updated) branch.
>>
>> But even there, I'm not able to get the usb gadget up. I see:
>
> I can get the gadget working on the ifc6410 device I have. I'm using
> this script to test things:
>
> modprobe libcomposite
> mkdir config
> mount none config -t configfs
> mkdir config/usb_gadget/g1
> mkdir config/usb_gadget/g1/strings/0x409
> echo 012345678 > config/usb_gadget/g1/strings/0x409/serialnumber
> echo "manufacturer" > config/usb_gadget/g1/strings/0x409/manufacturer
> echo "db8074" > config/usb_gadget/g1/strings/0x409/product
> echo 0x1d6b > config/usb_gadget/g1/idVendor
> echo 0x0104 > config/usb_gadget/g1/idProduct
> mkdir config/usb_gadget/g1/functions/acm.GS0
> mkdir config/usb_gadget/g1/functions/acm.GS1
> mkdir config/usb_gadget/g1/functions/ecm.usb0
> mkdir config/usb_gadget/g1/configs/c.1
> mkdir config/usb_gadget/g1/configs/c.1/strings/0x409/
> echo "CDC 2xACM+ECM" >
> config/usb_gadget/g1/configs/c.1/strings/0x409/configuration
> ln -s config/usb_gadget/g1/functions/acm.GS0
> config/usb_gadget/g1/configs/c.1
> ln -s config/usb_gadget/g1/functions/acm.GS1
> config/usb_gadget/g1/configs/c.1
> ln -s config/usb_gadget/g1/functions/ecm.usb0
> config/usb_gadget/g1/configs/c.1
> echo $(ls /sys/class/udc/) > config/usb_gadget/g1/UDC
>
>>
>> [    1.869717] msm_hsusb 12500000.usb: failed to get phandle in
>> /soc/usb@12500000 node
>
> This is sort of ok (I've seen it before with the HSIC controller on
> 8074). The extcon is optional and so the error message should be
> silenced. I sent a patch to move it to debug level.
>
> I don't see an extcon in mainline for apq8064, but I think it may be
> needed. At the least, I see that we're using a PMIC interrupt in the
> msm-3.4 kernel for the ID pin and the charger is notifying of vbus
> events similar to how smbb is doing it for apq8074.
>
>> [    1.882347] 12500000.usb supply vbus not found, using dummy regulator
>
> This is not great. We don't have a regulator specified on apq8064 so we
> can't turn on vbus and really support host mode. This seems to already
> be the case on mainline though, so it's not like we're any worse here.
> To properly support this we need a regulator driver. I suppose if the
> RPM supports it we can just use that, but if it doesn't support this
> regulator then we need to port over the SSBI regulator driver to do
> native regulator control. So far I haven't been able to test host mode
> on apq8064 because of this.
>
>>
>> So I'm not sure if the dts changes were quite right. I've got all the
>> ULPI configs enabled. Any ideas?
>>
>
> The phy and controller are both probing? If they're not failing to probe
> then it's probably the phy that isn't working properly. Does gadget work
> without my patches on nexus7?

Without your patch, I need one dts tweak on nexus7 (which I sent out
on friday[1]) to get the default direction set to OTG or gadget. But
yea, it works with that against mainline.

I'll dig in some more on your suggestions above and let you know if I
figure it out.

thanks
-john

[1]: http://www.spinics.net/lists/devicetree/msg134274.html

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

* [PATCH 00/21] Support qcom's HSIC USB and rewrite USB2 HS phy support
@ 2016-07-05 19:33             ` John Stultz
  0 siblings, 0 replies; 214+ messages in thread
From: John Stultz @ 2016-07-05 19:33 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 5, 2016 at 12:22 PM, Stephen Boyd <stephen.boyd@linaro.org> wrote:
> Quoting John Stultz (2016-07-01 23:03:38)
>> On Tue, Jun 28, 2016 at 1:34 AM, Stephen Boyd <stephen.boyd@linaro.org> wrote:
>> > Quoting John Stultz (2016-06-27 20:09:30)
>> >>
>> >> I haven't yet been able to test with this, as I need some other fixes
>> >> it seems too to deal with some of the iommu changes in my flo-WIP tree
>> >> (it can't find of_dma_configure), but will let you know how things
>> >> work once I have all that sorted.
>> >
>> > Cool, thanks for testing.
>>
>> So after working out some merge issues w/ my flo-WIP branch for the
>> nexus7, I was still having trouble, so I backed out to just your
>> (updated) branch.
>>
>> But even there, I'm not able to get the usb gadget up. I see:
>
> I can get the gadget working on the ifc6410 device I have. I'm using
> this script to test things:
>
> modprobe libcomposite
> mkdir config
> mount none config -t configfs
> mkdir config/usb_gadget/g1
> mkdir config/usb_gadget/g1/strings/0x409
> echo 012345678 > config/usb_gadget/g1/strings/0x409/serialnumber
> echo "manufacturer" > config/usb_gadget/g1/strings/0x409/manufacturer
> echo "db8074" > config/usb_gadget/g1/strings/0x409/product
> echo 0x1d6b > config/usb_gadget/g1/idVendor
> echo 0x0104 > config/usb_gadget/g1/idProduct
> mkdir config/usb_gadget/g1/functions/acm.GS0
> mkdir config/usb_gadget/g1/functions/acm.GS1
> mkdir config/usb_gadget/g1/functions/ecm.usb0
> mkdir config/usb_gadget/g1/configs/c.1
> mkdir config/usb_gadget/g1/configs/c.1/strings/0x409/
> echo "CDC 2xACM+ECM" >
> config/usb_gadget/g1/configs/c.1/strings/0x409/configuration
> ln -s config/usb_gadget/g1/functions/acm.GS0
> config/usb_gadget/g1/configs/c.1
> ln -s config/usb_gadget/g1/functions/acm.GS1
> config/usb_gadget/g1/configs/c.1
> ln -s config/usb_gadget/g1/functions/ecm.usb0
> config/usb_gadget/g1/configs/c.1
> echo $(ls /sys/class/udc/) > config/usb_gadget/g1/UDC
>
>>
>> [    1.869717] msm_hsusb 12500000.usb: failed to get phandle in
>> /soc/usb at 12500000 node
>
> This is sort of ok (I've seen it before with the HSIC controller on
> 8074). The extcon is optional and so the error message should be
> silenced. I sent a patch to move it to debug level.
>
> I don't see an extcon in mainline for apq8064, but I think it may be
> needed. At the least, I see that we're using a PMIC interrupt in the
> msm-3.4 kernel for the ID pin and the charger is notifying of vbus
> events similar to how smbb is doing it for apq8074.
>
>> [    1.882347] 12500000.usb supply vbus not found, using dummy regulator
>
> This is not great. We don't have a regulator specified on apq8064 so we
> can't turn on vbus and really support host mode. This seems to already
> be the case on mainline though, so it's not like we're any worse here.
> To properly support this we need a regulator driver. I suppose if the
> RPM supports it we can just use that, but if it doesn't support this
> regulator then we need to port over the SSBI regulator driver to do
> native regulator control. So far I haven't been able to test host mode
> on apq8064 because of this.
>
>>
>> So I'm not sure if the dts changes were quite right. I've got all the
>> ULPI configs enabled. Any ideas?
>>
>
> The phy and controller are both probing? If they're not failing to probe
> then it's probably the phy that isn't working properly. Does gadget work
> without my patches on nexus7?

Without your patch, I need one dts tweak on nexus7 (which I sent out
on friday[1]) to get the default direction set to OTG or gadget. But
yea, it works with that against mainline.

I'll dig in some more on your suggestions above and let you know if I
figure it out.

thanks
-john

[1]: http://www.spinics.net/lists/devicetree/msg134274.html

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

* Re: [PATCH 02/21] usb: ulpi: Support device discovery via DT
  2016-07-01  0:59           ` Rob Herring
@ 2016-07-06  6:16             ` Stephen Boyd
  -1 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-07-06  6:16 UTC (permalink / raw)
  To: Rob Herring
  Cc: Felipe Balbi, Heikki Krogerus, Arnd Bergmann, Neil Armstrong,
	linux-arm-msm, linux-usb, linux-kernel, Bjorn Andersson,
	devicetree, Greg Kroah-Hartman, Andy Gross, linux-arm-kernel

Quoting Rob Herring (2016-06-30 17:59:15)
> On Tue, Jun 28, 2016 at 03:09:21PM -0700, Stephen Boyd wrote:
> > Quoting Rob Herring (2016-06-28 13:56:42)
> > > On Sun, Jun 26, 2016 at 12:28:19AM -0700, Stephen Boyd wrote:
> > > > The qcom HSIC ulpi phy doesn't have any bits set in the vendor or
> > > > product id ulpi registers. This makes it impossible to make a
> > > > ulpi driver match against the id registers. Add support to
> > > > discover the ulpi phys via DT to help alleviate this problem.
> > > > We'll look for a ulpi bus node underneath the device registering
> > > > the ulpi viewport (or the parent of that device to support
> > > > chipidea's device layout) and then match up the phy node
> > > > underneath that with the ulpi device that's created.
> > > > 
> > > > The side benefit of this is that we can use standard DT
> > > > properties in the phy node like clks, regulators, gpios, etc.
> > > > because we don't have firmware like ACPI to turn these things on
> > > > for us. And we can use the DT phy binding to point our phy
> > > > consumer to the phy provider.
> > > > 
> > > > Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > > > Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> > > > Cc: <devicetree@vger.kernel.org>
> > > > Cc: Rob Herring <robh+dt@kernel.org>
> > > > Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> > > > ---
> > > >  Documentation/devicetree/bindings/usb/ulpi.txt | 20 +++++++++
> > > >  drivers/usb/common/ulpi.c                      | 56 +++++++++++++++++++++++++-
> > > >  2 files changed, 74 insertions(+), 2 deletions(-)
> > > >  create mode 100644 Documentation/devicetree/bindings/usb/ulpi.txt
> > > > 
> > > > diff --git a/Documentation/devicetree/bindings/usb/ulpi.txt b/Documentation/devicetree/bindings/usb/ulpi.txt
> > > > new file mode 100644
> > > > index 000000000000..ca179dc4bd50
> > > > --- /dev/null
> > > > +++ b/Documentation/devicetree/bindings/usb/ulpi.txt
> > > > @@ -0,0 +1,20 @@
> > > > +ULPI bus binding
> > > > +----------------
> > > > +
> > > > +Phys that are behind a ULPI connection can be described with the following
> > > > +binding. The host controller shall have a "ulpi" named node as a child, and
> > > > +that node shall have one enabled node underneath it representing the ulpi
> > > > +device on the bus.
> > > 
> > > This needs to co-exist with the USB bus binding which has the controller 
> > > ports for the child nodes. Maybe use the phy binding?
> > 
> > Which binding is that? bindings/usb/usb-device.txt? 
> 
> Yes.
> 
> > This ulpi binding is
> > to describe phys that are accessed through the ulpi "viewport" in the
> > usb controller. So controller ports don't come into the picture here.
> 
> You just need to confirm that there's no collision with child nodes like 
> it assumes all children are ports.
> 

Ok. It will work with the way usb_of_get_child_node() is written but it
doesn't seem like great DT design if we want to support usb-device
binding and ulpi bus at the same time, because we treat the controller
node as the usb bus.

&usb1 { 
        status = "okay";

        #address-cells = <1>;
        #size-cells = <0>;
	phys = <&uphy>;
	phy-names = "usb-phy";

        hub: genesys@1 {
                compatible = "usb5e3,608";
                reg = <1>;
        };

	ulpi {
		uphy: phy {
			compatible = "phy";
		};
	};
}

In this example, the ulpi bus doesn't have a reg property because it
isn't a port.

Perhaps we can move the usb ports to a subnode like 'usb' so that we can
have two logical busses underneath the controller, one for usb and one
for ulpi? We would need backwards compatibility code that looks for a
ports directly underneath the usb controller node when #address-cells
and #size-cells are present, otherwise it should fall down into a
'usb' subnode.

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

* [PATCH 02/21] usb: ulpi: Support device discovery via DT
@ 2016-07-06  6:16             ` Stephen Boyd
  0 siblings, 0 replies; 214+ messages in thread
From: Stephen Boyd @ 2016-07-06  6:16 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Rob Herring (2016-06-30 17:59:15)
> On Tue, Jun 28, 2016 at 03:09:21PM -0700, Stephen Boyd wrote:
> > Quoting Rob Herring (2016-06-28 13:56:42)
> > > On Sun, Jun 26, 2016 at 12:28:19AM -0700, Stephen Boyd wrote:
> > > > The qcom HSIC ulpi phy doesn't have any bits set in the vendor or
> > > > product id ulpi registers. This makes it impossible to make a
> > > > ulpi driver match against the id registers. Add support to
> > > > discover the ulpi phys via DT to help alleviate this problem.
> > > > We'll look for a ulpi bus node underneath the device registering
> > > > the ulpi viewport (or the parent of that device to support
> > > > chipidea's device layout) and then match up the phy node
> > > > underneath that with the ulpi device that's created.
> > > > 
> > > > The side benefit of this is that we can use standard DT
> > > > properties in the phy node like clks, regulators, gpios, etc.
> > > > because we don't have firmware like ACPI to turn these things on
> > > > for us. And we can use the DT phy binding to point our phy
> > > > consumer to the phy provider.
> > > > 
> > > > Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > > > Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> > > > Cc: <devicetree@vger.kernel.org>
> > > > Cc: Rob Herring <robh+dt@kernel.org>
> > > > Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> > > > ---
> > > >  Documentation/devicetree/bindings/usb/ulpi.txt | 20 +++++++++
> > > >  drivers/usb/common/ulpi.c                      | 56 +++++++++++++++++++++++++-
> > > >  2 files changed, 74 insertions(+), 2 deletions(-)
> > > >  create mode 100644 Documentation/devicetree/bindings/usb/ulpi.txt
> > > > 
> > > > diff --git a/Documentation/devicetree/bindings/usb/ulpi.txt b/Documentation/devicetree/bindings/usb/ulpi.txt
> > > > new file mode 100644
> > > > index 000000000000..ca179dc4bd50
> > > > --- /dev/null
> > > > +++ b/Documentation/devicetree/bindings/usb/ulpi.txt
> > > > @@ -0,0 +1,20 @@
> > > > +ULPI bus binding
> > > > +----------------
> > > > +
> > > > +Phys that are behind a ULPI connection can be described with the following
> > > > +binding. The host controller shall have a "ulpi" named node as a child, and
> > > > +that node shall have one enabled node underneath it representing the ulpi
> > > > +device on the bus.
> > > 
> > > This needs to co-exist with the USB bus binding which has the controller 
> > > ports for the child nodes. Maybe use the phy binding?
> > 
> > Which binding is that? bindings/usb/usb-device.txt? 
> 
> Yes.
> 
> > This ulpi binding is
> > to describe phys that are accessed through the ulpi "viewport" in the
> > usb controller. So controller ports don't come into the picture here.
> 
> You just need to confirm that there's no collision with child nodes like 
> it assumes all children are ports.
> 

Ok. It will work with the way usb_of_get_child_node() is written but it
doesn't seem like great DT design if we want to support usb-device
binding and ulpi bus at the same time, because we treat the controller
node as the usb bus.

&usb1 { 
        status = "okay";

        #address-cells = <1>;
        #size-cells = <0>;
	phys = <&uphy>;
	phy-names = "usb-phy";

        hub: genesys at 1 {
                compatible = "usb5e3,608";
                reg = <1>;
        };

	ulpi {
		uphy: phy {
			compatible = "phy";
		};
	};
}

In this example, the ulpi bus doesn't have a reg property because it
isn't a port.

Perhaps we can move the usb ports to a subnode like 'usb' so that we can
have two logical busses underneath the controller, one for usb and one
for ulpi? We would need backwards compatibility code that looks for a
ports directly underneath the usb controller node when #address-cells
and #size-cells are present, otherwise it should fall down into a
'usb' subnode.

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

end of thread, other threads:[~2016-07-06  6:16 UTC | newest]

Thread overview: 214+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-26  7:28 [PATCH 00/21] Support qcom's HSIC USB and rewrite USB2 HS phy support Stephen Boyd
2016-06-26  7:28 ` Stephen Boyd
2016-06-26  7:28 ` [PATCH 01/21] of: device: Support loading a module with OF based modalias Stephen Boyd
2016-06-26  7:28   ` Stephen Boyd
2016-06-26  7:28   ` Stephen Boyd
2016-06-28  4:17   ` Bjorn Andersson
2016-06-28  4:17     ` Bjorn Andersson
2016-06-28  4:39     ` Rob Herring
     [not found] ` <20160626072838.28082-1-stephen.boyd-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2016-06-26  7:28   ` [PATCH 02/21] usb: ulpi: Support device discovery via DT Stephen Boyd
2016-06-26  7:28     ` Stephen Boyd
2016-06-26  7:28     ` Stephen Boyd
     [not found]     ` <20160626072838.28082-3-stephen.boyd-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2016-06-27  4:21       ` kbuild test robot
2016-06-27  4:21         ` kbuild test robot
2016-06-27  4:21         ` kbuild test robot
2016-06-27 14:34     ` Heikki Krogerus
2016-06-27 14:34       ` Heikki Krogerus
2016-06-27 22:10       ` Stephen Boyd
2016-06-27 22:10         ` Stephen Boyd
2016-06-28 11:42         ` Heikki Krogerus
2016-06-28 11:42           ` Heikki Krogerus
2016-06-28 18:27           ` Stephen Boyd
2016-06-28 18:27             ` Stephen Boyd
2016-06-29  1:53           ` Peter Chen
2016-06-29  1:53             ` Peter Chen
2016-06-28 20:56     ` Rob Herring
2016-06-28 20:56       ` Rob Herring
2016-06-28 22:09       ` Stephen Boyd
2016-06-28 22:09         ` Stephen Boyd
2016-07-01  0:59         ` Rob Herring
2016-07-01  0:59           ` Rob Herring
2016-07-01  0:59           ` Rob Herring
2016-07-06  6:16           ` Stephen Boyd
2016-07-06  6:16             ` Stephen Boyd
2016-06-26  7:28   ` [PATCH 03/21] usb: ulpi: Avoid reading/writing in device creation with OF devices Stephen Boyd
2016-06-26  7:28     ` Stephen Boyd
2016-06-26  7:28     ` Stephen Boyd
2016-06-26  7:28   ` [PATCH 14/21] usb: chipidea: msm: Add proper clk and reset support Stephen Boyd
2016-06-26  7:28     ` Stephen Boyd
2016-06-26  7:28     ` Stephen Boyd
2016-06-29  7:02     ` Peter Chen
2016-06-29  7:02       ` Peter Chen
2016-06-26  7:28   ` [PATCH 20/21] phy: Add support for Qualcomm's USB HSIC phy Stephen Boyd
2016-06-26  7:28     ` Stephen Boyd
2016-06-26  7:28     ` Stephen Boyd
2016-06-28  8:49     ` Neil Armstrong
2016-06-28  8:49       ` Neil Armstrong
2016-06-28 21:58       ` Stephen Boyd
2016-06-28 21:58         ` Stephen Boyd
2016-06-28 21:58         ` Stephen Boyd
2016-06-29  9:16         ` Neil Armstrong
2016-06-29  9:16           ` Neil Armstrong
2016-06-29  9:16           ` Neil Armstrong
     [not found]           ` <57739203.9000601-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
2016-06-29 18:54             ` Stephen Boyd
2016-06-29 18:54               ` Stephen Boyd
2016-06-29 18:54               ` Stephen Boyd
2016-06-26  7:28   ` [PATCH 21/21] phy: Add support for Qualcomm's USB HS phy Stephen Boyd
2016-06-26  7:28     ` Stephen Boyd
2016-06-26  7:28     ` Stephen Boyd
2016-06-28  3:09   ` [PATCH 00/21] Support qcom's HSIC USB and rewrite USB2 HS phy support John Stultz
2016-06-28  3:09     ` John Stultz
2016-06-28  3:09     ` John Stultz
2016-06-28  8:34     `