linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 0/3] phy: rcar-gen3-usb2: Add R-Car Gen3 USB2 PHY driver
@ 2015-10-13 10:22 Yoshihiro Shimoda
  2015-10-13 10:22 ` [PATCH v4 1/3] " Yoshihiro Shimoda
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Yoshihiro Shimoda @ 2015-10-13 10:22 UTC (permalink / raw)
  To: kishon, robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak
  Cc: linux-kernel, devicetree, linux-sh, Yoshihiro Shimoda

This patch is based on the latest linux-phy / next branch.
(commit id = 882fed73420e85c0b06447c036e3096862fc73ba)

In this v4 patch set, it has a new feature (ID/VBUS pin detection).
To ease review, I don't add this intp the patch 1/3. If I should add
it into the patch 1/3, please let me know!

 Changes from v3:
  - Shorten structure names to avoid new line if we add a long function name.
  - Add ID/VBUS pin detection for peripheral mode.

 Changes from v2:
  - Modify Kconfig to add "depends on OF" and "depends on ARCH_SHMOBILE".
  - Add more information in the dt document.
  - Change reg-names from "usb2" to "usb2_host".

 Changes from v1:
  - Revise some typos.
  - Remove using clk API to enable/disable the clocks.
    (In other words, this driver expects to enable/disable the clocks by
     Runtime PM API by the phy-core driver.)
  - Remove an unnecessary header file (asm/cmpxchg.h).

Yoshihiro Shimoda (3):
  phy: rcar-gen3-usb2: Add R-Car Gen3 USB2 PHY driver
  phy: rcar-gen3-usb2: change the mode to OTG on the combined channel
  phy: rcar-gen3-usb2: add runtime ID/VBUS pin detection

 .../devicetree/bindings/phy/rcar-gen3-phy-usb2.txt |  39 ++
 drivers/phy/Kconfig                                |   8 +
 drivers/phy/Makefile                               |   1 +
 drivers/phy/phy-rcar-gen3-usb2.c                   | 403 +++++++++++++++++++++
 4 files changed, 451 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt
 create mode 100644 drivers/phy/phy-rcar-gen3-usb2.c

-- 
1.9.1


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

* [PATCH v4 1/3] phy: rcar-gen3-usb2: Add R-Car Gen3 USB2 PHY driver
  2015-10-13 10:22 [PATCH v4 0/3] phy: rcar-gen3-usb2: Add R-Car Gen3 USB2 PHY driver Yoshihiro Shimoda
@ 2015-10-13 10:22 ` Yoshihiro Shimoda
  2015-10-17  1:43   ` Kishon Vijay Abraham I
  2015-10-13 10:22 ` [PATCH v4 2/3] phy: rcar-gen3-usb2: change the mode to OTG on the combined channel Yoshihiro Shimoda
  2015-10-13 10:22 ` [PATCH v4 3/3] phy: rcar-gen3-usb2: add runtime ID/VBUS pin detection Yoshihiro Shimoda
  2 siblings, 1 reply; 11+ messages in thread
From: Yoshihiro Shimoda @ 2015-10-13 10:22 UTC (permalink / raw)
  To: kishon, robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak
  Cc: linux-kernel, devicetree, linux-sh, Yoshihiro Shimoda

This patch adds support for R-Car generation 3 USB2 PHY driver.
This SoC has 3 EHCI/OHCI channels, and the channel 0 is shared
with the HSUSB (USB2.0 peripheral) device. And each channel has
independent registers about the PHYs.

So, the purpose of this driver is:
 1) initializes some registers of SoC specific to use the
    {ehci,ohci}-platform driver.

 2) detects id pin to select host or peripheral on the channel 0.

For now, this driver only supports 1) above.

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
 .../devicetree/bindings/phy/rcar-gen3-phy-usb2.txt |  37 ++++
 drivers/phy/Kconfig                                |   8 +
 drivers/phy/Makefile                               |   1 +
 drivers/phy/phy-rcar-gen3-usb2.c                   | 240 +++++++++++++++++++++
 4 files changed, 286 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt
 create mode 100644 drivers/phy/phy-rcar-gen3-usb2.c

diff --git a/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt
new file mode 100644
index 0000000..589f5c0
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt
@@ -0,0 +1,37 @@
+* Renesas R-Car generation 3 USB 2.0 PHY
+
+This file provides information on what the device node for the R-Car generation
+3 USB 2.0 PHY contains.
+
+Required properties:
+- compatible: "renesas,usb2-phy-r8a7795" if the device is a part of an R8A7795
+	      SoC.
+- reg: offset and length of the partial USB 2.0 Host register block.
+- reg-names: must be "usb2_host".
+- clocks: clock phandle and specifier pair(s).
+- #phy-cells: see phy-bindings.txt in the same directory, must be <0>.
+
+Optional properties:
+To use a USB channel where USB 2.0 Host and HSUSB (USB 2.0 Peripheral) are
+combined, the device tree node should set HSUSB properties to reg and reg-names
+properties. This is because HSUSB has registers to select USB 2.0 host or
+peripheral at that channel:
+- reg: offset and length of the partial HSUSB register block.
+- reg-names: must be "hsusb".
+
+Example (R-Car H3):
+
+	usb-phy@ee080200 {
+		compatible = "renesas,usb2-phy-r8a7795";
+		reg = <0 0xee080200 0 0x700>, <0 0xe6590100 0 0x100>;
+		reg-names = "usb2_host", "hsusb";
+		clocks = <&mstp7_clks R8A7795_CLK_EHCI0>,
+			 <&mstp7_clks R8A7795_CLK_HSUSB>;
+	};
+
+	usb-phy@ee0a0200 {
+		compatible = "renesas,usb2-phy-r8a7795";
+		reg = <0 0xee0a0200 0 0x6ff>;
+		reg-names = "usb2_host";
+		clocks = <&mstp7_clks R8A7795_CLK_EHCI0>;
+	};
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 7eb5859d..45c6131 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -118,6 +118,14 @@ config PHY_RCAR_GEN2
 	help
 	  Support for USB PHY found on Renesas R-Car generation 2 SoCs.
 
+config PHY_RCAR_GEN3_USB2
+	tristate "Renesas R-Car generation 3 USB 2.0 PHY driver"
+	depends on OF
+	depends on ARCH_SHMOBILE
+	depends on GENERIC_PHY
+	help
+	  Support for USB 2.0 PHY found on Renesas R-Car generation 3 SoCs.
+
 config OMAP_CONTROL_PHY
 	tristate "OMAP CONTROL PHY Driver"
 	depends on ARCH_OMAP2PLUS || COMPILE_TEST
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 075db1a..91d7a62 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_PHY_MVEBU_SATA)		+= phy-mvebu-sata.o
 obj-$(CONFIG_PHY_MIPHY28LP) 		+= phy-miphy28lp.o
 obj-$(CONFIG_PHY_MIPHY365X)		+= phy-miphy365x.o
 obj-$(CONFIG_PHY_RCAR_GEN2)		+= phy-rcar-gen2.o
+obj-$(CONFIG_PHY_RCAR_GEN3_USB2)	+= phy-rcar-gen3-usb2.o
 obj-$(CONFIG_OMAP_CONTROL_PHY)		+= phy-omap-control.o
 obj-$(CONFIG_OMAP_USB2)			+= phy-omap-usb2.o
 obj-$(CONFIG_TI_PIPE3)			+= phy-ti-pipe3.o
diff --git a/drivers/phy/phy-rcar-gen3-usb2.c b/drivers/phy/phy-rcar-gen3-usb2.c
new file mode 100644
index 0000000..d90dfcf
--- /dev/null
+++ b/drivers/phy/phy-rcar-gen3-usb2.c
@@ -0,0 +1,240 @@
+/*
+ * Renesas R-Car Gen3 for USB2.0 PHY driver
+ *
+ * Copyright (C) 2015 Renesas Electronics Corporation
+ *
+ * This is based on the phy-rcar-gen2 driver:
+ * Copyright (C) 2014 Renesas Solutions Corp.
+ * Copyright (C) 2014 Cogent Embedded, Inc.
+ *
+ * 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/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+
+/******* USB2.0 Host registers (original offset is +0x200) *******/
+#define USB2_INT_ENABLE		0x000
+#define USB2_USBCTR		0x00c
+#define USB2_SPD_RSM_TIMSET	0x10c
+#define USB2_OC_TIMSET		0x110
+
+/* INT_ENABLE */
+#define USB2_INT_ENABLE_USBH_INTB_EN	BIT(2)
+#define USB2_INT_ENABLE_USBH_INTA_EN	BIT(1)
+#define USB2_INT_ENABLE_INIT		(USB2_INT_ENABLE_USBH_INTB_EN | \
+					 USB2_INT_ENABLE_USBH_INTA_EN)
+
+/* USBCTR */
+#define USB2_USBCTR_DIRPD	BIT(2)
+#define USB2_USBCTR_PLL_RST	BIT(1)
+
+/* SPD_RSM_TIMSET */
+#define USB2_SPD_RSM_TIMSET_INIT	0x014e029b
+
+/* OC_TIMSET */
+#define USB2_OC_TIMSET_INIT		0x000209ab
+
+/******* HSUSB registers (original offset is +0x100) *******/
+#define HSUSB_LPSTS			0x02
+#define HSUSB_UGCTRL2			0x84
+
+/* Low Power Status register (LPSTS) */
+#define HSUSB_LPSTS_SUSPM		0x4000
+
+/* USB General control register 2 (UGCTRL2) */
+#define HSUSB_UGCTRL2_MASK		0x00000031 /* bit[31:6] should be 0 */
+#define HSUSB_UGCTRL2_USB0SEL		0x00000030
+#define HSUSB_UGCTRL2_USB0SEL_HOST	0x00000010
+#define HSUSB_UGCTRL2_USB0SEL_HS_USB	0x00000020
+#define HSUSB_UGCTRL2_USB0SEL_OTG	0x00000030
+
+struct rcar_gen3_data {
+	void __iomem *base;
+	struct clk *clk;
+};
+
+struct rcar_gen3_chan {
+	struct rcar_gen3_data usb2;
+	struct rcar_gen3_data hsusb;
+	struct phy *phy;
+	spinlock_t lock;
+};
+
+static int rcar_gen3_phy_usb2_init(struct phy *p)
+{
+	struct rcar_gen3_chan *channel = phy_get_drvdata(p);
+	unsigned long flags;
+	void __iomem *usb2_base = channel->usb2.base;
+	void __iomem *hsusb_base = channel->hsusb.base;
+	u32 tmp;
+
+	spin_lock_irqsave(&channel->lock, flags);
+
+	/* Initialize USB2 part */
+	writel(USB2_INT_ENABLE_INIT, usb2_base + USB2_INT_ENABLE);
+	writel(USB2_SPD_RSM_TIMSET_INIT, usb2_base + USB2_SPD_RSM_TIMSET);
+	writel(USB2_OC_TIMSET_INIT, usb2_base + USB2_OC_TIMSET);
+
+	/* Initialize HSUSB part */
+	if (hsusb_base) {
+		/* TODO: support "OTG" mode */
+		tmp = readl(hsusb_base + HSUSB_UGCTRL2);
+		tmp = (tmp & ~HSUSB_UGCTRL2_USB0SEL) |
+		      HSUSB_UGCTRL2_USB0SEL_HOST;
+		writel(tmp & HSUSB_UGCTRL2_MASK, hsusb_base + HSUSB_UGCTRL2);
+	}
+
+	spin_unlock_irqrestore(&channel->lock, flags);
+
+	return 0;
+}
+
+static int rcar_gen3_phy_usb2_exit(struct phy *p)
+{
+	struct rcar_gen3_chan *channel = phy_get_drvdata(p);
+
+	writel(0, channel->usb2.base + USB2_INT_ENABLE);
+
+	return 0;
+}
+
+static int rcar_gen3_phy_usb2_power_on(struct phy *p)
+{
+	struct rcar_gen3_chan *channel = phy_get_drvdata(p);
+	void __iomem *usb2_base = channel->usb2.base;
+	void __iomem *hsusb_base = channel->hsusb.base;
+	unsigned long flags;
+	u32 tmp;
+
+	spin_lock_irqsave(&channel->lock, flags);
+
+	tmp = readl(usb2_base + USB2_USBCTR);
+	tmp |= USB2_USBCTR_PLL_RST;
+	writel(tmp, usb2_base + USB2_USBCTR);
+	tmp &= ~USB2_USBCTR_PLL_RST;
+	writel(tmp, usb2_base + USB2_USBCTR);
+
+	/*
+	 * TODO: To reduce power consuming, this driver should set the SUSPM
+	 *	after the PHY detects ID pin as peripheral.
+	 */
+	if (hsusb_base) {
+		/* Power on HSUSB PHY */
+		tmp = readw(hsusb_base + HSUSB_LPSTS);
+		tmp |= HSUSB_LPSTS_SUSPM;
+		writew(tmp, hsusb_base + HSUSB_LPSTS);
+	}
+
+	spin_unlock_irqrestore(&channel->lock, flags);
+
+	return 0;
+}
+
+static int rcar_gen3_phy_usb2_power_off(struct phy *p)
+{
+	struct rcar_gen3_chan *channel = phy_get_drvdata(p);
+	void __iomem *hsusb_base = channel->hsusb.base;
+	unsigned long flags;
+	u32 tmp;
+
+	spin_lock_irqsave(&channel->lock, flags);
+
+	if (hsusb_base) {
+		/* Power off HSUSB PHY */
+		tmp = readw(hsusb_base + HSUSB_LPSTS);
+		tmp &= ~HSUSB_LPSTS_SUSPM;
+		writew(tmp, hsusb_base + HSUSB_LPSTS);
+	}
+
+	spin_unlock_irqrestore(&channel->lock, flags);
+
+	return 0;
+}
+
+static struct phy_ops rcar_gen3_phy_usb2_ops = {
+	.init		= rcar_gen3_phy_usb2_init,
+	.exit		= rcar_gen3_phy_usb2_exit,
+	.power_on	= rcar_gen3_phy_usb2_power_on,
+	.power_off	= rcar_gen3_phy_usb2_power_off,
+	.owner		= THIS_MODULE,
+};
+
+static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = {
+	{ .compatible = "renesas,usb2-phy-r8a7795" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, rcar_gen3_phy_usb2_match_table);
+
+static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct rcar_gen3_chan *channel;
+	struct phy_provider *provider;
+	struct resource *res;
+
+	if (!dev->of_node) {
+		dev_err(dev, "This driver needs device tree\n");
+		return -EINVAL;
+	}
+
+	channel = devm_kzalloc(dev, sizeof(*channel), GFP_KERNEL);
+	if (!channel)
+		return -ENOMEM;
+
+	spin_lock_init(&channel->lock);
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "usb2_host");
+	channel->usb2.base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(channel->usb2.base))
+		return PTR_ERR(channel->usb2.base);
+
+	/* "hsusb" memory resource is optional */
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hsusb");
+
+	/* To avoid error message by devm_ioremap_resource() */
+	if (res) {
+		channel->hsusb.base = devm_ioremap_resource(dev, res);
+		if (IS_ERR(channel->hsusb.base))
+			channel->hsusb.base = NULL;
+	}
+
+	/* devm_phy_create() will call pm_runtime_enable(dev); */
+	channel->phy = devm_phy_create(dev, NULL, &rcar_gen3_phy_usb2_ops);
+	if (IS_ERR(channel->phy)) {
+		dev_err(dev, "Failed to create USB2 PHY\n");
+		return PTR_ERR(channel->phy);
+	}
+
+	phy_set_drvdata(channel->phy, channel);
+
+	provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+	if (IS_ERR(provider)) {
+		dev_err(dev, "Failed to register PHY provider\n");
+		return PTR_ERR(provider);
+	}
+
+	dev_set_drvdata(dev, channel);
+
+	return 0;
+}
+
+static struct platform_driver rcar_gen3_phy_usb2_driver = {
+	.driver = {
+		.name		= "phy_rcar_gen3_usb2",
+		.of_match_table	= rcar_gen3_phy_usb2_match_table,
+	},
+	.probe	= rcar_gen3_phy_usb2_probe,
+};
+module_platform_driver(rcar_gen3_phy_usb2_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Renesas R-Car Gen3 USB 2.0 PHY");
+MODULE_AUTHOR("Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>");
-- 
1.9.1


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

* [PATCH v4 2/3] phy: rcar-gen3-usb2: change the mode to OTG on the combined channel
  2015-10-13 10:22 [PATCH v4 0/3] phy: rcar-gen3-usb2: Add R-Car Gen3 USB2 PHY driver Yoshihiro Shimoda
  2015-10-13 10:22 ` [PATCH v4 1/3] " Yoshihiro Shimoda
@ 2015-10-13 10:22 ` Yoshihiro Shimoda
  2015-10-17  1:48   ` Kishon Vijay Abraham I
  2015-10-13 10:22 ` [PATCH v4 3/3] phy: rcar-gen3-usb2: add runtime ID/VBUS pin detection Yoshihiro Shimoda
  2 siblings, 1 reply; 11+ messages in thread
From: Yoshihiro Shimoda @ 2015-10-13 10:22 UTC (permalink / raw)
  To: kishon, robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak
  Cc: linux-kernel, devicetree, linux-sh, Yoshihiro Shimoda

To use the channel 0 of R-Car gen3 as periperal mode, This patch changes
the mode to OTG instead of HOST. Then, this driver needs to set some
registers to enable host mode and detects ID pin and VBUS pin at
phy_init() timing.

For now, the channel 0 can be used as host mode only.

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
 drivers/phy/phy-rcar-gen3-usb2.c | 126 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 124 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/phy-rcar-gen3-usb2.c b/drivers/phy/phy-rcar-gen3-usb2.c
index d90dfcf..03d7079 100644
--- a/drivers/phy/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/phy-rcar-gen3-usb2.c
@@ -25,6 +25,10 @@
 #define USB2_USBCTR		0x00c
 #define USB2_SPD_RSM_TIMSET	0x10c
 #define USB2_OC_TIMSET		0x110
+#define USB2_COMMCTRL		0x600
+#define USB2_VBCTRL		0x60c
+#define USB2_LINECTRL1		0x610
+#define USB2_ADPCTRL		0x630
 
 /* INT_ENABLE */
 #define USB2_INT_ENABLE_USBH_INTB_EN	BIT(2)
@@ -42,6 +46,24 @@
 /* OC_TIMSET */
 #define USB2_OC_TIMSET_INIT		0x000209ab
 
+/* COMMCTRL */
+#define USB2_COMMCTRL_OTG_PERI		BIT(31)	/* 1 = Peripheral mode */
+
+/* VBCTRL */
+#define USB2_VBCTRL_DRVVBUSSEL		BIT(8)
+
+/* LINECTRL1 */
+#define USB2_LINECTRL1_DPRPD_EN		BIT(19)
+#define USB2_LINECTRL1_DP_RPD		BIT(18)
+#define USB2_LINECTRL1_DMRPD_EN		BIT(17)
+#define USB2_LINECTRL1_DM_RPD		BIT(16)
+
+/* ADPCTRL */
+#define USB2_ADPCTRL_OTGSESSVLD		BIT(20)
+#define USB2_ADPCTRL_IDDIG		BIT(19)
+#define USB2_ADPCTRL_IDPULLUP		BIT(5)	/* 1 = ID sampling is enabled */
+#define USB2_ADPCTRL_DRVVBUS		BIT(4)
+
 /******* HSUSB registers (original offset is +0x100) *******/
 #define HSUSB_LPSTS			0x02
 #define HSUSB_UGCTRL2			0x84
@@ -68,6 +90,104 @@ struct rcar_gen3_chan {
 	spinlock_t lock;
 };
 
+static void rcar_gen3_set_host_mode(struct rcar_gen3_chan *ch, int host)
+{
+	void __iomem *usb2_base = ch->usb2.base;
+	u32 tmp = readl(usb2_base + USB2_COMMCTRL);
+
+	dev_dbg(&ch->phy->dev, "%s: %08x, %d\n", __func__, tmp, host);
+	if (host)
+		tmp &= ~USB2_COMMCTRL_OTG_PERI;
+	else
+		tmp |= USB2_COMMCTRL_OTG_PERI;
+	writel(tmp, usb2_base + USB2_COMMCTRL);
+}
+
+static void rcar_gen3_set_linectrl(struct rcar_gen3_chan *ch, int dp, int dm)
+{
+	void __iomem *usb2_base = ch->usb2.base;
+	u32 tmp = readl(usb2_base + USB2_LINECTRL1);
+
+	dev_dbg(&ch->phy->dev, "%s: %08x, %d, %d\n", __func__, tmp, dp, dm);
+	tmp &= ~(USB2_LINECTRL1_DP_RPD | USB2_LINECTRL1_DM_RPD);
+	if (dp)
+		tmp |= USB2_LINECTRL1_DP_RPD;
+	if (dm)
+		tmp |= USB2_LINECTRL1_DM_RPD;
+	writel(tmp, usb2_base + USB2_LINECTRL1);
+}
+
+static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus)
+{
+	void __iomem *usb2_base = ch->usb2.base;
+	u32 tmp = readl(usb2_base + USB2_ADPCTRL);
+
+	dev_dbg(&ch->phy->dev, "%s: %08x, %d\n", __func__, tmp, vbus);
+	if (vbus)
+		tmp |= USB2_ADPCTRL_DRVVBUS;
+	else
+		tmp &= ~USB2_ADPCTRL_DRVVBUS;
+	writel(tmp, usb2_base + USB2_ADPCTRL);
+}
+
+static void rcar_gen3_init_for_host(struct rcar_gen3_chan *ch)
+{
+	rcar_gen3_set_linectrl(ch, 1, 1);
+	rcar_gen3_set_host_mode(ch, 1);
+	rcar_gen3_enable_vbus_ctrl(ch, 1);
+}
+
+static void rcar_gen3_init_for_peri(struct rcar_gen3_chan *ch)
+{
+	rcar_gen3_set_linectrl(ch, 0, 1);
+	rcar_gen3_set_host_mode(ch, 0);
+	rcar_gen3_enable_vbus_ctrl(ch, 0);
+}
+
+static bool rcar_gen3_check_vbus(struct rcar_gen3_chan *ch)
+{
+	return !!(readl(ch->usb2.base + USB2_ADPCTRL) &
+		  USB2_ADPCTRL_OTGSESSVLD);
+}
+
+static bool rcar_gen3_check_id(struct rcar_gen3_chan *ch)
+{
+	return !!(readl(ch->usb2.base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG);
+}
+
+static void rcar_gen3_device_recognition(struct rcar_gen3_chan *ch)
+{
+	bool is_host = true;
+
+	if (rcar_gen3_check_id(ch)) {
+		/* B-device? */
+		if (rcar_gen3_check_vbus(ch))
+			is_host = false;
+	}
+
+	if (is_host)
+		rcar_gen3_init_for_host(ch);
+	else
+		rcar_gen3_init_for_peri(ch);
+}
+
+static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch)
+{
+	void __iomem *usb2_base = ch->usb2.base;
+	u32 tmp;
+
+	tmp = readl(usb2_base + USB2_VBCTRL);
+	writel(tmp | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL);
+	tmp = readl(usb2_base + USB2_ADPCTRL);
+	writel(tmp | USB2_ADPCTRL_IDPULLUP, usb2_base + USB2_ADPCTRL);
+	tmp = readl(usb2_base + USB2_LINECTRL1);
+	rcar_gen3_set_linectrl(ch, 0, 0);
+	writel(tmp | USB2_LINECTRL1_DPRPD_EN | USB2_LINECTRL1_DMRPD_EN,
+	       usb2_base + USB2_LINECTRL1);
+
+	rcar_gen3_device_recognition(ch);
+}
+
 static int rcar_gen3_phy_usb2_init(struct phy *p)
 {
 	struct rcar_gen3_chan *channel = phy_get_drvdata(p);
@@ -85,11 +205,13 @@ static int rcar_gen3_phy_usb2_init(struct phy *p)
 
 	/* Initialize HSUSB part */
 	if (hsusb_base) {
-		/* TODO: support "OTG" mode */
 		tmp = readl(hsusb_base + HSUSB_UGCTRL2);
 		tmp = (tmp & ~HSUSB_UGCTRL2_USB0SEL) |
-		      HSUSB_UGCTRL2_USB0SEL_HOST;
+		      HSUSB_UGCTRL2_USB0SEL_OTG;
 		writel(tmp & HSUSB_UGCTRL2_MASK, hsusb_base + HSUSB_UGCTRL2);
+
+		/* Initialize otg part */
+		rcar_gen3_init_otg(channel);
 	}
 
 	spin_unlock_irqrestore(&channel->lock, flags);
-- 
1.9.1


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

* [PATCH v4 3/3] phy: rcar-gen3-usb2: add runtime ID/VBUS pin detection
  2015-10-13 10:22 [PATCH v4 0/3] phy: rcar-gen3-usb2: Add R-Car Gen3 USB2 PHY driver Yoshihiro Shimoda
  2015-10-13 10:22 ` [PATCH v4 1/3] " Yoshihiro Shimoda
  2015-10-13 10:22 ` [PATCH v4 2/3] phy: rcar-gen3-usb2: change the mode to OTG on the combined channel Yoshihiro Shimoda
@ 2015-10-13 10:22 ` Yoshihiro Shimoda
  2015-10-17  1:53   ` Kishon Vijay Abraham I
  2 siblings, 1 reply; 11+ messages in thread
From: Yoshihiro Shimoda @ 2015-10-13 10:22 UTC (permalink / raw)
  To: kishon, robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak
  Cc: linux-kernel, devicetree, linux-sh, Yoshihiro Shimoda

This patch adds support for runtime ID/VBUS pin detection if
the channel 0 of R-Car gen3 is used. So, we are able to use
the channel as both host and peripheral.

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
 .../devicetree/bindings/phy/rcar-gen3-phy-usb2.txt |  2 +
 drivers/phy/phy-rcar-gen3-usb2.c                   | 43 +++++++++++++++++++++-
 2 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt
index 589f5c0..b30a98a 100644
--- a/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt
+++ b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt
@@ -18,6 +18,7 @@ properties. This is because HSUSB has registers to select USB 2.0 host or
 peripheral at that channel:
 - reg: offset and length of the partial HSUSB register block.
 - reg-names: must be "hsusb".
+- interrupts: interrupt specifier for the PHY.
 
 Example (R-Car H3):
 
@@ -25,6 +26,7 @@ Example (R-Car H3):
 		compatible = "renesas,usb2-phy-r8a7795";
 		reg = <0 0xee080200 0 0x700>, <0 0xe6590100 0 0x100>;
 		reg-names = "usb2_host", "hsusb";
+		interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp7_clks R8A7795_CLK_EHCI0>,
 			 <&mstp7_clks R8A7795_CLK_HSUSB>;
 	};
diff --git a/drivers/phy/phy-rcar-gen3-usb2.c b/drivers/phy/phy-rcar-gen3-usb2.c
index 03d7079..40d0005 100644
--- a/drivers/phy/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/phy-rcar-gen3-usb2.c
@@ -12,6 +12,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/of.h>
@@ -26,14 +27,18 @@
 #define USB2_SPD_RSM_TIMSET	0x10c
 #define USB2_OC_TIMSET		0x110
 #define USB2_COMMCTRL		0x600
+#define USB2_OBINTSTA		0x604
+#define USB2_OBINTEN		0x608
 #define USB2_VBCTRL		0x60c
 #define USB2_LINECTRL1		0x610
 #define USB2_ADPCTRL		0x630
 
 /* INT_ENABLE */
+#define USB2_INT_ENABLE_UCOM_INTEN	BIT(3)
 #define USB2_INT_ENABLE_USBH_INTB_EN	BIT(2)
 #define USB2_INT_ENABLE_USBH_INTA_EN	BIT(1)
-#define USB2_INT_ENABLE_INIT		(USB2_INT_ENABLE_USBH_INTB_EN | \
+#define USB2_INT_ENABLE_INIT		(USB2_INT_ENABLE_UCOM_INTEN | \
+					 USB2_INT_ENABLE_USBH_INTB_EN | \
 					 USB2_INT_ENABLE_USBH_INTA_EN)
 
 /* USBCTR */
@@ -49,6 +54,12 @@
 /* COMMCTRL */
 #define USB2_COMMCTRL_OTG_PERI		BIT(31)	/* 1 = Peripheral mode */
 
+/* OBINTSTA and OBINTEN */
+#define USB2_OBINT_SESSVLDCHG		BIT(12)
+#define USB2_OBINT_IDDIGCHG		BIT(11)
+#define USB2_OBINT_BITS			(USB2_OBINT_SESSVLDCHG | \
+					 USB2_OBINT_IDDIGCHG)
+
 /* VBCTRL */
 #define USB2_VBCTRL_DRVVBUSSEL		BIT(8)
 
@@ -178,6 +189,9 @@ static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch)
 
 	tmp = readl(usb2_base + USB2_VBCTRL);
 	writel(tmp | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL);
+	writel(USB2_OBINT_BITS, usb2_base + USB2_OBINTSTA);
+	tmp = readl(usb2_base + USB2_OBINTEN);
+	writel(tmp | USB2_OBINT_BITS, usb2_base + USB2_OBINTEN);
 	tmp = readl(usb2_base + USB2_ADPCTRL);
 	writel(tmp | USB2_ADPCTRL_IDPULLUP, usb2_base + USB2_ADPCTRL);
 	tmp = readl(usb2_base + USB2_LINECTRL1);
@@ -289,6 +303,23 @@ static struct phy_ops rcar_gen3_phy_usb2_ops = {
 	.owner		= THIS_MODULE,
 };
 
+static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch)
+{
+	struct rcar_gen3_chan *ch = _ch;
+	void __iomem *usb2_base = ch->usb2.base;
+	u32 status = readl(usb2_base + USB2_OBINTSTA);
+	irqreturn_t ret = IRQ_NONE;
+
+	if (status & USB2_OBINT_BITS) {
+		dev_dbg(&ch->phy->dev, "%s: %08x\n", __func__, status);
+		writel(USB2_OBINT_BITS, usb2_base + USB2_OBINTSTA);
+		rcar_gen3_device_recognition(ch);
+		ret = IRQ_HANDLED;
+	}
+
+	return ret;
+}
+
 static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = {
 	{ .compatible = "renesas,usb2-phy-r8a7795" },
 	{ }
@@ -323,9 +354,19 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
 
 	/* To avoid error message by devm_ioremap_resource() */
 	if (res) {
+		int ret, irq;
+
 		channel->hsusb.base = devm_ioremap_resource(dev, res);
 		if (IS_ERR(channel->hsusb.base))
 			channel->hsusb.base = NULL;
+		/* call request_irq for OTG */
+		ret = irq = platform_get_irq(pdev, 0);
+		if (irq >= 0)
+			ret = devm_request_irq(dev, irq, rcar_gen3_phy_usb2_irq,
+					       IRQF_SHARED, dev_name(dev),
+					       channel);
+		if (ret < 0)
+			dev_err(dev, "No irq handler (%d)\n", ret);
 	}
 
 	/* devm_phy_create() will call pm_runtime_enable(dev); */
-- 
1.9.1


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

* Re: [PATCH v4 1/3] phy: rcar-gen3-usb2: Add R-Car Gen3 USB2 PHY driver
  2015-10-13 10:22 ` [PATCH v4 1/3] " Yoshihiro Shimoda
@ 2015-10-17  1:43   ` Kishon Vijay Abraham I
  2015-10-19  8:30     ` Yoshihiro Shimoda
  0 siblings, 1 reply; 11+ messages in thread
From: Kishon Vijay Abraham I @ 2015-10-17  1:43 UTC (permalink / raw)
  To: Yoshihiro Shimoda, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak
  Cc: linux-kernel, devicetree, linux-sh

Hi,

On Tuesday 13 October 2015 03:52 PM, Yoshihiro Shimoda wrote:
> This patch adds support for R-Car generation 3 USB2 PHY driver.
> This SoC has 3 EHCI/OHCI channels, and the channel 0 is shared
> with the HSUSB (USB2.0 peripheral) device. And each channel has
> independent registers about the PHYs.
> 
> So, the purpose of this driver is:
>  1) initializes some registers of SoC specific to use the
>     {ehci,ohci}-platform driver.
> 
>  2) detects id pin to select host or peripheral on the channel 0.
> 
> For now, this driver only supports 1) above.
> 
> Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> ---
>  .../devicetree/bindings/phy/rcar-gen3-phy-usb2.txt |  37 ++++
>  drivers/phy/Kconfig                                |   8 +
>  drivers/phy/Makefile                               |   1 +
>  drivers/phy/phy-rcar-gen3-usb2.c                   | 240 +++++++++++++++++++++
>  4 files changed, 286 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt
>  create mode 100644 drivers/phy/phy-rcar-gen3-usb2.c
> 
> diff --git a/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt
> new file mode 100644
> index 0000000..589f5c0
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt
> @@ -0,0 +1,37 @@
> +* Renesas R-Car generation 3 USB 2.0 PHY
> +
> +This file provides information on what the device node for the R-Car generation
> +3 USB 2.0 PHY contains.
> +
> +Required properties:
> +- compatible: "renesas,usb2-phy-r8a7795" if the device is a part of an R8A7795
> +	      SoC.
> +- reg: offset and length of the partial USB 2.0 Host register block.
> +- reg-names: must be "usb2_host".
> +- clocks: clock phandle and specifier pair(s).
> +- #phy-cells: see phy-bindings.txt in the same directory, must be <0>.
> +
> +Optional properties:
> +To use a USB channel where USB 2.0 Host and HSUSB (USB 2.0 Peripheral) are
> +combined, the device tree node should set HSUSB properties to reg and reg-names
> +properties. This is because HSUSB has registers to select USB 2.0 host or
> +peripheral at that channel:
> +- reg: offset and length of the partial HSUSB register block.
> +- reg-names: must be "hsusb".
> +
> +Example (R-Car H3):
> +
> +	usb-phy@ee080200 {
> +		compatible = "renesas,usb2-phy-r8a7795";
> +		reg = <0 0xee080200 0 0x700>, <0 0xe6590100 0 0x100>;
> +		reg-names = "usb2_host", "hsusb";
> +		clocks = <&mstp7_clks R8A7795_CLK_EHCI0>,
> +			 <&mstp7_clks R8A7795_CLK_HSUSB>;
> +	};
> +
> +	usb-phy@ee0a0200 {
> +		compatible = "renesas,usb2-phy-r8a7795";
> +		reg = <0 0xee0a0200 0 0x6ff>;
> +		reg-names = "usb2_host";
> +		clocks = <&mstp7_clks R8A7795_CLK_EHCI0>;
> +	};
> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
> index 7eb5859d..45c6131 100644
> --- a/drivers/phy/Kconfig
> +++ b/drivers/phy/Kconfig
> @@ -118,6 +118,14 @@ config PHY_RCAR_GEN2
>  	help
>  	  Support for USB PHY found on Renesas R-Car generation 2 SoCs.
>  
> +config PHY_RCAR_GEN3_USB2
> +	tristate "Renesas R-Car generation 3 USB 2.0 PHY driver"
> +	depends on OF
> +	depends on ARCH_SHMOBILE

The depends on can be moved to a single line.

> +	depends on GENERIC_PHY

all the PHY drivers inside drivers/phy directory use select PHY. Please
use select here.
> +	help
> +	  Support for USB 2.0 PHY found on Renesas R-Car generation 3 SoCs.
> +
>  config OMAP_CONTROL_PHY
>  	tristate "OMAP CONTROL PHY Driver"
>  	depends on ARCH_OMAP2PLUS || COMPILE_TEST
> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
> index 075db1a..91d7a62 100644
> --- a/drivers/phy/Makefile
> +++ b/drivers/phy/Makefile
> @@ -17,6 +17,7 @@ obj-$(CONFIG_PHY_MVEBU_SATA)		+= phy-mvebu-sata.o
>  obj-$(CONFIG_PHY_MIPHY28LP) 		+= phy-miphy28lp.o
>  obj-$(CONFIG_PHY_MIPHY365X)		+= phy-miphy365x.o
>  obj-$(CONFIG_PHY_RCAR_GEN2)		+= phy-rcar-gen2.o
> +obj-$(CONFIG_PHY_RCAR_GEN3_USB2)	+= phy-rcar-gen3-usb2.o
>  obj-$(CONFIG_OMAP_CONTROL_PHY)		+= phy-omap-control.o
>  obj-$(CONFIG_OMAP_USB2)			+= phy-omap-usb2.o
>  obj-$(CONFIG_TI_PIPE3)			+= phy-ti-pipe3.o
> diff --git a/drivers/phy/phy-rcar-gen3-usb2.c b/drivers/phy/phy-rcar-gen3-usb2.c
> new file mode 100644
> index 0000000..d90dfcf
> --- /dev/null
> +++ b/drivers/phy/phy-rcar-gen3-usb2.c

Add a MAINTAINER entry for this file if there is no one else.
> @@ -0,0 +1,240 @@
> +/*
> + * Renesas R-Car Gen3 for USB2.0 PHY driver
> + *
> + * Copyright (C) 2015 Renesas Electronics Corporation
> + *
> + * This is based on the phy-rcar-gen2 driver:
> + * Copyright (C) 2014 Renesas Solutions Corp.
> + * Copyright (C) 2014 Cogent Embedded, Inc.
> + *
> + * 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/io.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/spinlock.h>
> +
> +/******* USB2.0 Host registers (original offset is +0x200) *******/
> +#define USB2_INT_ENABLE		0x000
> +#define USB2_USBCTR		0x00c
> +#define USB2_SPD_RSM_TIMSET	0x10c
> +#define USB2_OC_TIMSET		0x110
> +
> +/* INT_ENABLE */
> +#define USB2_INT_ENABLE_USBH_INTB_EN	BIT(2)
> +#define USB2_INT_ENABLE_USBH_INTA_EN	BIT(1)
> +#define USB2_INT_ENABLE_INIT		(USB2_INT_ENABLE_USBH_INTB_EN | \
> +					 USB2_INT_ENABLE_USBH_INTA_EN)
> +
> +/* USBCTR */
> +#define USB2_USBCTR_DIRPD	BIT(2)
> +#define USB2_USBCTR_PLL_RST	BIT(1)
> +
> +/* SPD_RSM_TIMSET */
> +#define USB2_SPD_RSM_TIMSET_INIT	0x014e029b
> +
> +/* OC_TIMSET */
> +#define USB2_OC_TIMSET_INIT		0x000209ab
> +
> +/******* HSUSB registers (original offset is +0x100) *******/
> +#define HSUSB_LPSTS			0x02
> +#define HSUSB_UGCTRL2			0x84
> +
> +/* Low Power Status register (LPSTS) */
> +#define HSUSB_LPSTS_SUSPM		0x4000
> +
> +/* USB General control register 2 (UGCTRL2) */
> +#define HSUSB_UGCTRL2_MASK		0x00000031 /* bit[31:6] should be 0 */
> +#define HSUSB_UGCTRL2_USB0SEL		0x00000030
> +#define HSUSB_UGCTRL2_USB0SEL_HOST	0x00000010
> +#define HSUSB_UGCTRL2_USB0SEL_HS_USB	0x00000020
> +#define HSUSB_UGCTRL2_USB0SEL_OTG	0x00000030
> +
> +struct rcar_gen3_data {
> +	void __iomem *base;
> +	struct clk *clk;
> +};
> +
> +struct rcar_gen3_chan {
> +	struct rcar_gen3_data usb2;
> +	struct rcar_gen3_data hsusb;
> +	struct phy *phy;
> +	spinlock_t lock;

Why do you need a spinlock? It seems like a single PHY phy-provider? Is
it for future modifications?
> +};
> +
> +static int rcar_gen3_phy_usb2_init(struct phy *p)
> +{
> +	struct rcar_gen3_chan *channel = phy_get_drvdata(p);
> +	unsigned long flags;
> +	void __iomem *usb2_base = channel->usb2.base;
> +	void __iomem *hsusb_base = channel->hsusb.base;
> +	u32 tmp;
> +
> +	spin_lock_irqsave(&channel->lock, flags);
> +
> +	/* Initialize USB2 part */
> +	writel(USB2_INT_ENABLE_INIT, usb2_base + USB2_INT_ENABLE);
> +	writel(USB2_SPD_RSM_TIMSET_INIT, usb2_base + USB2_SPD_RSM_TIMSET);
> +	writel(USB2_OC_TIMSET_INIT, usb2_base + USB2_OC_TIMSET);
> +
> +	/* Initialize HSUSB part */
> +	if (hsusb_base) {
> +		/* TODO: support "OTG" mode */
> +		tmp = readl(hsusb_base + HSUSB_UGCTRL2);
> +		tmp = (tmp & ~HSUSB_UGCTRL2_USB0SEL) |
> +		      HSUSB_UGCTRL2_USB0SEL_HOST;
> +		writel(tmp & HSUSB_UGCTRL2_MASK, hsusb_base + HSUSB_UGCTRL2);
> +	}
> +
> +	spin_unlock_irqrestore(&channel->lock, flags);
> +
> +	return 0;
> +}
> +
> +static int rcar_gen3_phy_usb2_exit(struct phy *p)
> +{
> +	struct rcar_gen3_chan *channel = phy_get_drvdata(p);
> +
> +	writel(0, channel->usb2.base + USB2_INT_ENABLE);
> +
> +	return 0;
> +}
> +
> +static int rcar_gen3_phy_usb2_power_on(struct phy *p)
> +{
> +	struct rcar_gen3_chan *channel = phy_get_drvdata(p);
> +	void __iomem *usb2_base = channel->usb2.base;
> +	void __iomem *hsusb_base = channel->hsusb.base;
> +	unsigned long flags;
> +	u32 tmp;
> +
> +	spin_lock_irqsave(&channel->lock, flags);
> +
> +	tmp = readl(usb2_base + USB2_USBCTR);
> +	tmp |= USB2_USBCTR_PLL_RST;
> +	writel(tmp, usb2_base + USB2_USBCTR);
> +	tmp &= ~USB2_USBCTR_PLL_RST;
> +	writel(tmp, usb2_base + USB2_USBCTR);
> +
> +	/*
> +	 * TODO: To reduce power consuming, this driver should set the SUSPM
> +	 *	after the PHY detects ID pin as peripheral.
> +	 */
> +	if (hsusb_base) {
> +		/* Power on HSUSB PHY */
> +		tmp = readw(hsusb_base + HSUSB_LPSTS);
> +		tmp |= HSUSB_LPSTS_SUSPM;
> +		writew(tmp, hsusb_base + HSUSB_LPSTS);
> +	}
> +
> +	spin_unlock_irqrestore(&channel->lock, flags);
> +
> +	return 0;
> +}
> +
> +static int rcar_gen3_phy_usb2_power_off(struct phy *p)
> +{
> +	struct rcar_gen3_chan *channel = phy_get_drvdata(p);
> +	void __iomem *hsusb_base = channel->hsusb.base;
> +	unsigned long flags;
> +	u32 tmp;
> +
> +	spin_lock_irqsave(&channel->lock, flags);
> +
> +	if (hsusb_base) {
> +		/* Power off HSUSB PHY */
> +		tmp = readw(hsusb_base + HSUSB_LPSTS);
> +		tmp &= ~HSUSB_LPSTS_SUSPM;
> +		writew(tmp, hsusb_base + HSUSB_LPSTS);
> +	}
> +
> +	spin_unlock_irqrestore(&channel->lock, flags);
> +
> +	return 0;
> +}
> +
> +static struct phy_ops rcar_gen3_phy_usb2_ops = {
> +	.init		= rcar_gen3_phy_usb2_init,
> +	.exit		= rcar_gen3_phy_usb2_exit,
> +	.power_on	= rcar_gen3_phy_usb2_power_on,
> +	.power_off	= rcar_gen3_phy_usb2_power_off,
> +	.owner		= THIS_MODULE,
> +};
> +
> +static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = {
> +	{ .compatible = "renesas,usb2-phy-r8a7795" },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, rcar_gen3_phy_usb2_match_table);
> +
> +static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct rcar_gen3_chan *channel;
> +	struct phy_provider *provider;
> +	struct resource *res;
> +
> +	if (!dev->of_node) {
> +		dev_err(dev, "This driver needs device tree\n");
> +		return -EINVAL;
> +	}
> +
> +	channel = devm_kzalloc(dev, sizeof(*channel), GFP_KERNEL);
> +	if (!channel)
> +		return -ENOMEM;
> +
> +	spin_lock_init(&channel->lock);
> +
> +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "usb2_host");
> +	channel->usb2.base = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(channel->usb2.base))
> +		return PTR_ERR(channel->usb2.base);
> +
> +	/* "hsusb" memory resource is optional */
> +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hsusb");
> +
> +	/* To avoid error message by devm_ioremap_resource() */
> +	if (res) {
> +		channel->hsusb.base = devm_ioremap_resource(dev, res);
> +		if (IS_ERR(channel->hsusb.base))
> +			channel->hsusb.base = NULL;
> +	}
> +
> +	/* devm_phy_create() will call pm_runtime_enable(dev); */
> +	channel->phy = devm_phy_create(dev, NULL, &rcar_gen3_phy_usb2_ops);
> +	if (IS_ERR(channel->phy)) {
> +		dev_err(dev, "Failed to create USB2 PHY\n");
> +		return PTR_ERR(channel->phy);
> +	}
> +
> +	phy_set_drvdata(channel->phy, channel);
> +
> +	provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> +	if (IS_ERR(provider)) {
> +		dev_err(dev, "Failed to register PHY provider\n");
> +		return PTR_ERR(provider);
> +	}
> +
> +	dev_set_drvdata(dev, channel);

This looks unnecessary and if you remove that you can use return
PTR_ERR_OR_ZERO.

Thanks
Kishon

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

* Re: [PATCH v4 2/3] phy: rcar-gen3-usb2: change the mode to OTG on the combined channel
  2015-10-13 10:22 ` [PATCH v4 2/3] phy: rcar-gen3-usb2: change the mode to OTG on the combined channel Yoshihiro Shimoda
@ 2015-10-17  1:48   ` Kishon Vijay Abraham I
  2015-10-19  8:32     ` Yoshihiro Shimoda
  2015-10-19 11:50     ` Khiem Nguyen
  0 siblings, 2 replies; 11+ messages in thread
From: Kishon Vijay Abraham I @ 2015-10-17  1:48 UTC (permalink / raw)
  To: Yoshihiro Shimoda, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak
  Cc: linux-kernel, devicetree, linux-sh

Hi,

On Tuesday 13 October 2015 03:52 PM, Yoshihiro Shimoda wrote:
> To use the channel 0 of R-Car gen3 as periperal mode, This patch changes
> the mode to OTG instead of HOST. Then, this driver needs to set some
> registers to enable host mode and detects ID pin and VBUS pin at
> phy_init() timing.
> 
> For now, the channel 0 can be used as host mode only.
> 
> Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> ---
>  drivers/phy/phy-rcar-gen3-usb2.c | 126 ++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 124 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/phy/phy-rcar-gen3-usb2.c b/drivers/phy/phy-rcar-gen3-usb2.c
> index d90dfcf..03d7079 100644
> --- a/drivers/phy/phy-rcar-gen3-usb2.c
> +++ b/drivers/phy/phy-rcar-gen3-usb2.c
> @@ -25,6 +25,10 @@
>  #define USB2_USBCTR		0x00c
>  #define USB2_SPD_RSM_TIMSET	0x10c
>  #define USB2_OC_TIMSET		0x110
> +#define USB2_COMMCTRL		0x600
> +#define USB2_VBCTRL		0x60c
> +#define USB2_LINECTRL1		0x610
> +#define USB2_ADPCTRL		0x630
>  
>  /* INT_ENABLE */
>  #define USB2_INT_ENABLE_USBH_INTB_EN	BIT(2)
> @@ -42,6 +46,24 @@
>  /* OC_TIMSET */
>  #define USB2_OC_TIMSET_INIT		0x000209ab
>  
> +/* COMMCTRL */
> +#define USB2_COMMCTRL_OTG_PERI		BIT(31)	/* 1 = Peripheral mode */
> +
> +/* VBCTRL */
> +#define USB2_VBCTRL_DRVVBUSSEL		BIT(8)
> +
> +/* LINECTRL1 */
> +#define USB2_LINECTRL1_DPRPD_EN		BIT(19)
> +#define USB2_LINECTRL1_DP_RPD		BIT(18)
> +#define USB2_LINECTRL1_DMRPD_EN		BIT(17)
> +#define USB2_LINECTRL1_DM_RPD		BIT(16)
> +
> +/* ADPCTRL */
> +#define USB2_ADPCTRL_OTGSESSVLD		BIT(20)
> +#define USB2_ADPCTRL_IDDIG		BIT(19)
> +#define USB2_ADPCTRL_IDPULLUP		BIT(5)	/* 1 = ID sampling is enabled */
> +#define USB2_ADPCTRL_DRVVBUS		BIT(4)
> +
>  /******* HSUSB registers (original offset is +0x100) *******/
>  #define HSUSB_LPSTS			0x02
>  #define HSUSB_UGCTRL2			0x84
> @@ -68,6 +90,104 @@ struct rcar_gen3_chan {
>  	spinlock_t lock;
>  };
>  
> +static void rcar_gen3_set_host_mode(struct rcar_gen3_chan *ch, int host)
> +{
> +	void __iomem *usb2_base = ch->usb2.base;
> +	u32 tmp = readl(usb2_base + USB2_COMMCTRL);

It's your preference but I'd like to have something like val instead of tmp.
> +
> +	dev_dbg(&ch->phy->dev, "%s: %08x, %d\n", __func__, tmp, host);

This shoulod be dev_vdbg.
> +	if (host)
> +		tmp &= ~USB2_COMMCTRL_OTG_PERI;
> +	else
> +		tmp |= USB2_COMMCTRL_OTG_PERI;
> +	writel(tmp, usb2_base + USB2_COMMCTRL);
> +}
> +
> +static void rcar_gen3_set_linectrl(struct rcar_gen3_chan *ch, int dp, int dm)
> +{
> +	void __iomem *usb2_base = ch->usb2.base;
> +	u32 tmp = readl(usb2_base + USB2_LINECTRL1);
> +
> +	dev_dbg(&ch->phy->dev, "%s: %08x, %d, %d\n", __func__, tmp, dp, dm);

same here.
> +	tmp &= ~(USB2_LINECTRL1_DP_RPD | USB2_LINECTRL1_DM_RPD);
> +	if (dp)
> +		tmp |= USB2_LINECTRL1_DP_RPD;
> +	if (dm)
> +		tmp |= USB2_LINECTRL1_DM_RPD;
> +	writel(tmp, usb2_base + USB2_LINECTRL1);
> +}
> +
> +static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus)
> +{
> +	void __iomem *usb2_base = ch->usb2.base;
> +	u32 tmp = readl(usb2_base + USB2_ADPCTRL);
> +
> +	dev_dbg(&ch->phy->dev, "%s: %08x, %d\n", __func__, tmp, vbus);

here too.
> +	if (vbus)
> +		tmp |= USB2_ADPCTRL_DRVVBUS;
> +	else
> +		tmp &= ~USB2_ADPCTRL_DRVVBUS;
> +	writel(tmp, usb2_base + USB2_ADPCTRL);
> +}
> +
> +static void rcar_gen3_init_for_host(struct rcar_gen3_chan *ch)
> +{
> +	rcar_gen3_set_linectrl(ch, 1, 1);
> +	rcar_gen3_set_host_mode(ch, 1);
> +	rcar_gen3_enable_vbus_ctrl(ch, 1);
> +}
> +
> +static void rcar_gen3_init_for_peri(struct rcar_gen3_chan *ch)
> +{
> +	rcar_gen3_set_linectrl(ch, 0, 1);
> +	rcar_gen3_set_host_mode(ch, 0);
> +	rcar_gen3_enable_vbus_ctrl(ch, 0);
> +}
> +
> +static bool rcar_gen3_check_vbus(struct rcar_gen3_chan *ch)
> +{
> +	return !!(readl(ch->usb2.base + USB2_ADPCTRL) &
> +		  USB2_ADPCTRL_OTGSESSVLD);
> +}
> +
> +static bool rcar_gen3_check_id(struct rcar_gen3_chan *ch)
> +{
> +	return !!(readl(ch->usb2.base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG);
> +}
> +
> +static void rcar_gen3_device_recognition(struct rcar_gen3_chan *ch)
> +{
> +	bool is_host = true;
> +
> +	if (rcar_gen3_check_id(ch)) {
> +		/* B-device? */
> +		if (rcar_gen3_check_vbus(ch))

This can be rcar_gen3_check_id(ch) && rcar_gen3_check_vbus(ch) no?

Thanks
Kishon

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

* Re: [PATCH v4 3/3] phy: rcar-gen3-usb2: add runtime ID/VBUS pin detection
  2015-10-13 10:22 ` [PATCH v4 3/3] phy: rcar-gen3-usb2: add runtime ID/VBUS pin detection Yoshihiro Shimoda
@ 2015-10-17  1:53   ` Kishon Vijay Abraham I
  2015-10-19  8:35     ` Yoshihiro Shimoda
  0 siblings, 1 reply; 11+ messages in thread
From: Kishon Vijay Abraham I @ 2015-10-17  1:53 UTC (permalink / raw)
  To: Yoshihiro Shimoda, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak
  Cc: linux-kernel, devicetree, linux-sh

Hi,

On Tuesday 13 October 2015 03:52 PM, Yoshihiro Shimoda wrote:
> This patch adds support for runtime ID/VBUS pin detection if
> the channel 0 of R-Car gen3 is used. So, we are able to use
> the channel as both host and peripheral.
> 
> Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> ---
>  .../devicetree/bindings/phy/rcar-gen3-phy-usb2.txt |  2 +
>  drivers/phy/phy-rcar-gen3-usb2.c                   | 43 +++++++++++++++++++++-
>  2 files changed, 44 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt
> index 589f5c0..b30a98a 100644
> --- a/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt
> +++ b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt
> @@ -18,6 +18,7 @@ properties. This is because HSUSB has registers to select USB 2.0 host or
>  peripheral at that channel:
>  - reg: offset and length of the partial HSUSB register block.
>  - reg-names: must be "hsusb".
> +- interrupts: interrupt specifier for the PHY.
>  
>  Example (R-Car H3):
>  
> @@ -25,6 +26,7 @@ Example (R-Car H3):
>  		compatible = "renesas,usb2-phy-r8a7795";
>  		reg = <0 0xee080200 0 0x700>, <0 0xe6590100 0 0x100>;
>  		reg-names = "usb2_host", "hsusb";
> +		interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
>  		clocks = <&mstp7_clks R8A7795_CLK_EHCI0>,
>  			 <&mstp7_clks R8A7795_CLK_HSUSB>;
>  	};
> diff --git a/drivers/phy/phy-rcar-gen3-usb2.c b/drivers/phy/phy-rcar-gen3-usb2.c
> index 03d7079..40d0005 100644
> --- a/drivers/phy/phy-rcar-gen3-usb2.c
> +++ b/drivers/phy/phy-rcar-gen3-usb2.c
> @@ -12,6 +12,7 @@
>   * published by the Free Software Foundation.
>   */
>  
> +#include <linux/interrupt.h>
>  #include <linux/io.h>
>  #include <linux/module.h>
>  #include <linux/of.h>
> @@ -26,14 +27,18 @@
>  #define USB2_SPD_RSM_TIMSET	0x10c
>  #define USB2_OC_TIMSET		0x110
>  #define USB2_COMMCTRL		0x600
> +#define USB2_OBINTSTA		0x604
> +#define USB2_OBINTEN		0x608
>  #define USB2_VBCTRL		0x60c
>  #define USB2_LINECTRL1		0x610
>  #define USB2_ADPCTRL		0x630
>  
>  /* INT_ENABLE */
> +#define USB2_INT_ENABLE_UCOM_INTEN	BIT(3)
>  #define USB2_INT_ENABLE_USBH_INTB_EN	BIT(2)
>  #define USB2_INT_ENABLE_USBH_INTA_EN	BIT(1)
> -#define USB2_INT_ENABLE_INIT		(USB2_INT_ENABLE_USBH_INTB_EN | \
> +#define USB2_INT_ENABLE_INIT		(USB2_INT_ENABLE_UCOM_INTEN | \
> +					 USB2_INT_ENABLE_USBH_INTB_EN | \
>  					 USB2_INT_ENABLE_USBH_INTA_EN)
>  
>  /* USBCTR */
> @@ -49,6 +54,12 @@
>  /* COMMCTRL */
>  #define USB2_COMMCTRL_OTG_PERI		BIT(31)	/* 1 = Peripheral mode */
>  
> +/* OBINTSTA and OBINTEN */
> +#define USB2_OBINT_SESSVLDCHG		BIT(12)
> +#define USB2_OBINT_IDDIGCHG		BIT(11)
> +#define USB2_OBINT_BITS			(USB2_OBINT_SESSVLDCHG | \
> +					 USB2_OBINT_IDDIGCHG)
> +
>  /* VBCTRL */
>  #define USB2_VBCTRL_DRVVBUSSEL		BIT(8)
>  
> @@ -178,6 +189,9 @@ static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch)
>  
>  	tmp = readl(usb2_base + USB2_VBCTRL);
>  	writel(tmp | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL);
> +	writel(USB2_OBINT_BITS, usb2_base + USB2_OBINTSTA);
> +	tmp = readl(usb2_base + USB2_OBINTEN);
> +	writel(tmp | USB2_OBINT_BITS, usb2_base + USB2_OBINTEN);
>  	tmp = readl(usb2_base + USB2_ADPCTRL);
>  	writel(tmp | USB2_ADPCTRL_IDPULLUP, usb2_base + USB2_ADPCTRL);
>  	tmp = readl(usb2_base + USB2_LINECTRL1);
> @@ -289,6 +303,23 @@ static struct phy_ops rcar_gen3_phy_usb2_ops = {
>  	.owner		= THIS_MODULE,
>  };
>  
> +static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch)
> +{
> +	struct rcar_gen3_chan *ch = _ch;
> +	void __iomem *usb2_base = ch->usb2.base;
> +	u32 status = readl(usb2_base + USB2_OBINTSTA);
> +	irqreturn_t ret = IRQ_NONE;
> +
> +	if (status & USB2_OBINT_BITS) {
> +		dev_dbg(&ch->phy->dev, "%s: %08x\n", __func__, status);

This can be removed or use dev_vdbg.
> +		writel(USB2_OBINT_BITS, usb2_base + USB2_OBINTSTA);
> +		rcar_gen3_device_recognition(ch);
> +		ret = IRQ_HANDLED;
> +	}
> +
> +	return ret;
> +}
> +
>  static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = {
>  	{ .compatible = "renesas,usb2-phy-r8a7795" },
>  	{ }
> @@ -323,9 +354,19 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
>  
>  	/* To avoid error message by devm_ioremap_resource() */
>  	if (res) {
> +		int ret, irq;
> +
>  		channel->hsusb.base = devm_ioremap_resource(dev, res);
>  		if (IS_ERR(channel->hsusb.base))
>  			channel->hsusb.base = NULL;
> +		/* call request_irq for OTG */
> +		ret = irq = platform_get_irq(pdev, 0);
is irq optional property? even then you don't need 2 variables to handle
the same return value.

Thanks
Kishon

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

* RE: [PATCH v4 1/3] phy: rcar-gen3-usb2: Add R-Car Gen3 USB2 PHY driver
  2015-10-17  1:43   ` Kishon Vijay Abraham I
@ 2015-10-19  8:30     ` Yoshihiro Shimoda
  0 siblings, 0 replies; 11+ messages in thread
From: Yoshihiro Shimoda @ 2015-10-19  8:30 UTC (permalink / raw)
  To: Kishon Vijay Abraham I, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak
  Cc: linux-kernel, devicetree, linux-sh

Hi,

> Sent: Saturday, October 17, 2015 10:44 AM
> 
> Hi,
> 
> On Tuesday 13 October 2015 03:52 PM, Yoshihiro Shimoda wrote:
< snip >
> > diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
> > index 7eb5859d..45c6131 100644
> > --- a/drivers/phy/Kconfig
> > +++ b/drivers/phy/Kconfig
> > @@ -118,6 +118,14 @@ config PHY_RCAR_GEN2
> >  	help
> >  	  Support for USB PHY found on Renesas R-Car generation 2 SoCs.
> >
> > +config PHY_RCAR_GEN3_USB2
> > +	tristate "Renesas R-Car generation 3 USB 2.0 PHY driver"
> > +	depends on OF
> > +	depends on ARCH_SHMOBILE
> 
> The depends on can be moved to a single line.

Thank you for the review!
I will fix this.

> > +	depends on GENERIC_PHY
> 
> all the PHY drivers inside drivers/phy directory use select PHY. Please
> use select here.

Oops, I will fix it.

> > +	help
> > +	  Support for USB 2.0 PHY found on Renesas R-Car generation 3 SoCs.
> > +
> >  config OMAP_CONTROL_PHY
> >  	tristate "OMAP CONTROL PHY Driver"
> >  	depends on ARCH_OMAP2PLUS || COMPILE_TEST
< snip >
> > diff --git a/drivers/phy/phy-rcar-gen3-usb2.c b/drivers/phy/phy-rcar-gen3-usb2.c
> > new file mode 100644
> > index 0000000..d90dfcf
> > --- /dev/null
> > +++ b/drivers/phy/phy-rcar-gen3-usb2.c
> 
> Add a MAINTAINER entry for this file if there is no one else.

I got it. I will add a MAINTAINER entry.

> > @@ -0,0 +1,240 @@
> > +/*
> > + * Renesas R-Car Gen3 for USB2.0 PHY driver
> > + *
> > + * Copyright (C) 2015 Renesas Electronics Corporation
> > + *
> > + * This is based on the phy-rcar-gen2 driver:
> > + * Copyright (C) 2014 Renesas Solutions Corp.
> > + * Copyright (C) 2014 Cogent Embedded, Inc.
> > + *
> > + * 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/io.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/of_address.h>
> > +#include <linux/phy/phy.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/spinlock.h>
> > +
> > +/******* USB2.0 Host registers (original offset is +0x200) *******/
> > +#define USB2_INT_ENABLE		0x000
> > +#define USB2_USBCTR		0x00c
> > +#define USB2_SPD_RSM_TIMSET	0x10c
> > +#define USB2_OC_TIMSET		0x110
> > +
> > +/* INT_ENABLE */
> > +#define USB2_INT_ENABLE_USBH_INTB_EN	BIT(2)
> > +#define USB2_INT_ENABLE_USBH_INTA_EN	BIT(1)
> > +#define USB2_INT_ENABLE_INIT		(USB2_INT_ENABLE_USBH_INTB_EN | \
> > +					 USB2_INT_ENABLE_USBH_INTA_EN)
> > +
> > +/* USBCTR */
> > +#define USB2_USBCTR_DIRPD	BIT(2)
> > +#define USB2_USBCTR_PLL_RST	BIT(1)
> > +
> > +/* SPD_RSM_TIMSET */
> > +#define USB2_SPD_RSM_TIMSET_INIT	0x014e029b
> > +
> > +/* OC_TIMSET */
> > +#define USB2_OC_TIMSET_INIT		0x000209ab
> > +
> > +/******* HSUSB registers (original offset is +0x100) *******/
> > +#define HSUSB_LPSTS			0x02
> > +#define HSUSB_UGCTRL2			0x84
> > +
> > +/* Low Power Status register (LPSTS) */
> > +#define HSUSB_LPSTS_SUSPM		0x4000
> > +
> > +/* USB General control register 2 (UGCTRL2) */
> > +#define HSUSB_UGCTRL2_MASK		0x00000031 /* bit[31:6] should be 0 */
> > +#define HSUSB_UGCTRL2_USB0SEL		0x00000030
> > +#define HSUSB_UGCTRL2_USB0SEL_HOST	0x00000010
> > +#define HSUSB_UGCTRL2_USB0SEL_HS_USB	0x00000020
> > +#define HSUSB_UGCTRL2_USB0SEL_OTG	0x00000030
> > +
> > +struct rcar_gen3_data {
> > +	void __iomem *base;
> > +	struct clk *clk;
> > +};
> > +
> > +struct rcar_gen3_chan {
> > +	struct rcar_gen3_data usb2;
> > +	struct rcar_gen3_data hsusb;
> > +	struct phy *phy;
> > +	spinlock_t lock;
> 
> Why do you need a spinlock? It seems like a single PHY phy-provider? Is
> it for future modifications?

I used this spinlock to protect updating some registers from CPU(s).
I will remove it if it is not really needed.

> > +};
> > +
> > +static int rcar_gen3_phy_usb2_init(struct phy *p)
> > +{
> > +	struct rcar_gen3_chan *channel = phy_get_drvdata(p);
> > +	unsigned long flags;
> > +	void __iomem *usb2_base = channel->usb2.base;
> > +	void __iomem *hsusb_base = channel->hsusb.base;
> > +	u32 tmp;
> > +
> > +	spin_lock_irqsave(&channel->lock, flags);
> > +
> > +	/* Initialize USB2 part */
> > +	writel(USB2_INT_ENABLE_INIT, usb2_base + USB2_INT_ENABLE);
> > +	writel(USB2_SPD_RSM_TIMSET_INIT, usb2_base + USB2_SPD_RSM_TIMSET);
> > +	writel(USB2_OC_TIMSET_INIT, usb2_base + USB2_OC_TIMSET);
> > +
> > +	/* Initialize HSUSB part */
> > +	if (hsusb_base) {
> > +		/* TODO: support "OTG" mode */
> > +		tmp = readl(hsusb_base + HSUSB_UGCTRL2);
> > +		tmp = (tmp & ~HSUSB_UGCTRL2_USB0SEL) |
> > +		      HSUSB_UGCTRL2_USB0SEL_HOST;
> > +		writel(tmp & HSUSB_UGCTRL2_MASK, hsusb_base + HSUSB_UGCTRL2);
> > +	}
> > +
> > +	spin_unlock_irqrestore(&channel->lock, flags);
> > +
> > +	return 0;
> > +}
> > +
> > +static int rcar_gen3_phy_usb2_exit(struct phy *p)
> > +{
> > +	struct rcar_gen3_chan *channel = phy_get_drvdata(p);
> > +
> > +	writel(0, channel->usb2.base + USB2_INT_ENABLE);
> > +
> > +	return 0;
> > +}
> > +
> > +static int rcar_gen3_phy_usb2_power_on(struct phy *p)
> > +{
> > +	struct rcar_gen3_chan *channel = phy_get_drvdata(p);
> > +	void __iomem *usb2_base = channel->usb2.base;
> > +	void __iomem *hsusb_base = channel->hsusb.base;
> > +	unsigned long flags;
> > +	u32 tmp;
> > +
> > +	spin_lock_irqsave(&channel->lock, flags);
> > +
> > +	tmp = readl(usb2_base + USB2_USBCTR);
> > +	tmp |= USB2_USBCTR_PLL_RST;
> > +	writel(tmp, usb2_base + USB2_USBCTR);
> > +	tmp &= ~USB2_USBCTR_PLL_RST;
> > +	writel(tmp, usb2_base + USB2_USBCTR);
> > +
> > +	/*
> > +	 * TODO: To reduce power consuming, this driver should set the SUSPM
> > +	 *	after the PHY detects ID pin as peripheral.
> > +	 */
> > +	if (hsusb_base) {
> > +		/* Power on HSUSB PHY */
> > +		tmp = readw(hsusb_base + HSUSB_LPSTS);
> > +		tmp |= HSUSB_LPSTS_SUSPM;
> > +		writew(tmp, hsusb_base + HSUSB_LPSTS);
> > +	}
> > +
> > +	spin_unlock_irqrestore(&channel->lock, flags);
> > +
> > +	return 0;
> > +}
> > +
> > +static int rcar_gen3_phy_usb2_power_off(struct phy *p)
> > +{
> > +	struct rcar_gen3_chan *channel = phy_get_drvdata(p);
> > +	void __iomem *hsusb_base = channel->hsusb.base;
> > +	unsigned long flags;
> > +	u32 tmp;
> > +
> > +	spin_lock_irqsave(&channel->lock, flags);
> > +
> > +	if (hsusb_base) {
> > +		/* Power off HSUSB PHY */
> > +		tmp = readw(hsusb_base + HSUSB_LPSTS);
> > +		tmp &= ~HSUSB_LPSTS_SUSPM;
> > +		writew(tmp, hsusb_base + HSUSB_LPSTS);
> > +	}
> > +
> > +	spin_unlock_irqrestore(&channel->lock, flags);
> > +
> > +	return 0;
> > +}
> > +
> > +static struct phy_ops rcar_gen3_phy_usb2_ops = {
> > +	.init		= rcar_gen3_phy_usb2_init,
> > +	.exit		= rcar_gen3_phy_usb2_exit,
> > +	.power_on	= rcar_gen3_phy_usb2_power_on,
> > +	.power_off	= rcar_gen3_phy_usb2_power_off,
> > +	.owner		= THIS_MODULE,
> > +};
> > +
> > +static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = {
> > +	{ .compatible = "renesas,usb2-phy-r8a7795" },
> > +	{ }
> > +};
> > +MODULE_DEVICE_TABLE(of, rcar_gen3_phy_usb2_match_table);
> > +
> > +static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
> > +{
> > +	struct device *dev = &pdev->dev;
> > +	struct rcar_gen3_chan *channel;
> > +	struct phy_provider *provider;
> > +	struct resource *res;
> > +
> > +	if (!dev->of_node) {
> > +		dev_err(dev, "This driver needs device tree\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	channel = devm_kzalloc(dev, sizeof(*channel), GFP_KERNEL);
> > +	if (!channel)
> > +		return -ENOMEM;
> > +
> > +	spin_lock_init(&channel->lock);
> > +
> > +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "usb2_host");
> > +	channel->usb2.base = devm_ioremap_resource(dev, res);
> > +	if (IS_ERR(channel->usb2.base))
> > +		return PTR_ERR(channel->usb2.base);
> > +
> > +	/* "hsusb" memory resource is optional */
> > +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hsusb");
> > +
> > +	/* To avoid error message by devm_ioremap_resource() */
> > +	if (res) {
> > +		channel->hsusb.base = devm_ioremap_resource(dev, res);
> > +		if (IS_ERR(channel->hsusb.base))
> > +			channel->hsusb.base = NULL;
> > +	}
> > +
> > +	/* devm_phy_create() will call pm_runtime_enable(dev); */
> > +	channel->phy = devm_phy_create(dev, NULL, &rcar_gen3_phy_usb2_ops);
> > +	if (IS_ERR(channel->phy)) {
> > +		dev_err(dev, "Failed to create USB2 PHY\n");
> > +		return PTR_ERR(channel->phy);
> > +	}
> > +
> > +	phy_set_drvdata(channel->phy, channel);
> > +
> > +	provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> > +	if (IS_ERR(provider)) {
> > +		dev_err(dev, "Failed to register PHY provider\n");
> > +		return PTR_ERR(provider);
> > +	}
> > +
> > +	dev_set_drvdata(dev, channel);
> 
> This looks unnecessary and if you remove that you can use return
> PTR_ERR_OR_ZERO.

Thank you for the point. I will remove it.

Best regards,
Yoshihiro Shimoda

> Thanks
> Kishon

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

* RE: [PATCH v4 2/3] phy: rcar-gen3-usb2: change the mode to OTG on the combined channel
  2015-10-17  1:48   ` Kishon Vijay Abraham I
@ 2015-10-19  8:32     ` Yoshihiro Shimoda
  2015-10-19 11:50     ` Khiem Nguyen
  1 sibling, 0 replies; 11+ messages in thread
From: Yoshihiro Shimoda @ 2015-10-19  8:32 UTC (permalink / raw)
  To: Kishon Vijay Abraham I, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak
  Cc: linux-kernel, devicetree, linux-sh

Hi,

> Sent: Saturday, October 17, 2015 10:48 AM
> 
> Hi,
> 
> On Tuesday 13 October 2015 03:52 PM, Yoshihiro Shimoda wrote:
> > To use the channel 0 of R-Car gen3 as periperal mode, This patch changes
> > the mode to OTG instead of HOST. Then, this driver needs to set some
> > registers to enable host mode and detects ID pin and VBUS pin at
> > phy_init() timing.
> >
> > For now, the channel 0 can be used as host mode only.
> >
> > Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> > ---
> >  drivers/phy/phy-rcar-gen3-usb2.c | 126 ++++++++++++++++++++++++++++++++++++++-
> >  1 file changed, 124 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/phy/phy-rcar-gen3-usb2.c b/drivers/phy/phy-rcar-gen3-usb2.c
> > index d90dfcf..03d7079 100644
> > --- a/drivers/phy/phy-rcar-gen3-usb2.c
> > +++ b/drivers/phy/phy-rcar-gen3-usb2.c
> > @@ -25,6 +25,10 @@
> >  #define USB2_USBCTR		0x00c
> >  #define USB2_SPD_RSM_TIMSET	0x10c
> >  #define USB2_OC_TIMSET		0x110
> > +#define USB2_COMMCTRL		0x600
> > +#define USB2_VBCTRL		0x60c
> > +#define USB2_LINECTRL1		0x610
> > +#define USB2_ADPCTRL		0x630
> >
> >  /* INT_ENABLE */
> >  #define USB2_INT_ENABLE_USBH_INTB_EN	BIT(2)
> > @@ -42,6 +46,24 @@
> >  /* OC_TIMSET */
> >  #define USB2_OC_TIMSET_INIT		0x000209ab
> >
> > +/* COMMCTRL */
> > +#define USB2_COMMCTRL_OTG_PERI		BIT(31)	/* 1 = Peripheral mode */
> > +
> > +/* VBCTRL */
> > +#define USB2_VBCTRL_DRVVBUSSEL		BIT(8)
> > +
> > +/* LINECTRL1 */
> > +#define USB2_LINECTRL1_DPRPD_EN		BIT(19)
> > +#define USB2_LINECTRL1_DP_RPD		BIT(18)
> > +#define USB2_LINECTRL1_DMRPD_EN		BIT(17)
> > +#define USB2_LINECTRL1_DM_RPD		BIT(16)
> > +
> > +/* ADPCTRL */
> > +#define USB2_ADPCTRL_OTGSESSVLD		BIT(20)
> > +#define USB2_ADPCTRL_IDDIG		BIT(19)
> > +#define USB2_ADPCTRL_IDPULLUP		BIT(5)	/* 1 = ID sampling is enabled */
> > +#define USB2_ADPCTRL_DRVVBUS		BIT(4)
> > +
> >  /******* HSUSB registers (original offset is +0x100) *******/
> >  #define HSUSB_LPSTS			0x02
> >  #define HSUSB_UGCTRL2			0x84
> > @@ -68,6 +90,104 @@ struct rcar_gen3_chan {
> >  	spinlock_t lock;
> >  };
> >
> > +static void rcar_gen3_set_host_mode(struct rcar_gen3_chan *ch, int host)
> > +{
> > +	void __iomem *usb2_base = ch->usb2.base;
> > +	u32 tmp = readl(usb2_base + USB2_COMMCTRL);
> 
> It's your preference but I'd like to have something like val instead of tmp.

I got it. I will change the name.

> > +
> > +	dev_dbg(&ch->phy->dev, "%s: %08x, %d\n", __func__, tmp, host);
> 
> This shoulod be dev_vdbg.

I got it. I will fix it.

> > +	if (host)
> > +		tmp &= ~USB2_COMMCTRL_OTG_PERI;
> > +	else
> > +		tmp |= USB2_COMMCTRL_OTG_PERI;
> > +	writel(tmp, usb2_base + USB2_COMMCTRL);
> > +}
> > +
> > +static void rcar_gen3_set_linectrl(struct rcar_gen3_chan *ch, int dp, int dm)
> > +{
> > +	void __iomem *usb2_base = ch->usb2.base;
> > +	u32 tmp = readl(usb2_base + USB2_LINECTRL1);
> > +
> > +	dev_dbg(&ch->phy->dev, "%s: %08x, %d, %d\n", __func__, tmp, dp, dm);
> 
> same here.

I got it.

> > +	tmp &= ~(USB2_LINECTRL1_DP_RPD | USB2_LINECTRL1_DM_RPD);
> > +	if (dp)
> > +		tmp |= USB2_LINECTRL1_DP_RPD;
> > +	if (dm)
> > +		tmp |= USB2_LINECTRL1_DM_RPD;
> > +	writel(tmp, usb2_base + USB2_LINECTRL1);
> > +}
> > +
> > +static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus)
> > +{
> > +	void __iomem *usb2_base = ch->usb2.base;
> > +	u32 tmp = readl(usb2_base + USB2_ADPCTRL);
> > +
> > +	dev_dbg(&ch->phy->dev, "%s: %08x, %d\n", __func__, tmp, vbus);
> 
> here too.

I will fix it.

> > +	if (vbus)
> > +		tmp |= USB2_ADPCTRL_DRVVBUS;
> > +	else
> > +		tmp &= ~USB2_ADPCTRL_DRVVBUS;
> > +	writel(tmp, usb2_base + USB2_ADPCTRL);
> > +}
> > +
> > +static void rcar_gen3_init_for_host(struct rcar_gen3_chan *ch)
> > +{
> > +	rcar_gen3_set_linectrl(ch, 1, 1);
> > +	rcar_gen3_set_host_mode(ch, 1);
> > +	rcar_gen3_enable_vbus_ctrl(ch, 1);
> > +}
> > +
> > +static void rcar_gen3_init_for_peri(struct rcar_gen3_chan *ch)
> > +{
> > +	rcar_gen3_set_linectrl(ch, 0, 1);
> > +	rcar_gen3_set_host_mode(ch, 0);
> > +	rcar_gen3_enable_vbus_ctrl(ch, 0);
> > +}
> > +
> > +static bool rcar_gen3_check_vbus(struct rcar_gen3_chan *ch)
> > +{
> > +	return !!(readl(ch->usb2.base + USB2_ADPCTRL) &
> > +		  USB2_ADPCTRL_OTGSESSVLD);
> > +}
> > +
> > +static bool rcar_gen3_check_id(struct rcar_gen3_chan *ch)
> > +{
> > +	return !!(readl(ch->usb2.base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG);
> > +}
> > +
> > +static void rcar_gen3_device_recognition(struct rcar_gen3_chan *ch)
> > +{
> > +	bool is_host = true;
> > +
> > +	if (rcar_gen3_check_id(ch)) {
> > +		/* B-device? */
> > +		if (rcar_gen3_check_vbus(ch))
> 
> This can be rcar_gen3_check_id(ch) && rcar_gen3_check_vbus(ch) no?

Thank you for the point. I will change such a condition.

Best regards,
Yoshihiro Shimoda

> Thanks
> Kishon

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

* RE: [PATCH v4 3/3] phy: rcar-gen3-usb2: add runtime ID/VBUS pin detection
  2015-10-17  1:53   ` Kishon Vijay Abraham I
@ 2015-10-19  8:35     ` Yoshihiro Shimoda
  0 siblings, 0 replies; 11+ messages in thread
From: Yoshihiro Shimoda @ 2015-10-19  8:35 UTC (permalink / raw)
  To: Kishon Vijay Abraham I, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak
  Cc: linux-kernel, devicetree, linux-sh

Hi,

> Sent: Saturday, October 17, 2015 10:54 AM
> 
> Hi,
> 
> On Tuesday 13 October 2015 03:52 PM, Yoshihiro Shimoda wrote:
> > This patch adds support for runtime ID/VBUS pin detection if
> > the channel 0 of R-Car gen3 is used. So, we are able to use
> > the channel as both host and peripheral.
> >
> > Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> > ---
> >  .../devicetree/bindings/phy/rcar-gen3-phy-usb2.txt |  2 +
> >  drivers/phy/phy-rcar-gen3-usb2.c                   | 43 +++++++++++++++++++++-
> >  2 files changed, 44 insertions(+), 1 deletion(-)
> >
> > diff --git a/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt
> b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt
> > index 589f5c0..b30a98a 100644
> > --- a/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt
> > +++ b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt
> > @@ -18,6 +18,7 @@ properties. This is because HSUSB has registers to select USB 2.0 host or
> >  peripheral at that channel:
> >  - reg: offset and length of the partial HSUSB register block.
> >  - reg-names: must be "hsusb".
> > +- interrupts: interrupt specifier for the PHY.
> >
> >  Example (R-Car H3):
> >
> > @@ -25,6 +26,7 @@ Example (R-Car H3):
> >  		compatible = "renesas,usb2-phy-r8a7795";
> >  		reg = <0 0xee080200 0 0x700>, <0 0xe6590100 0 0x100>;
> >  		reg-names = "usb2_host", "hsusb";
> > +		interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
> >  		clocks = <&mstp7_clks R8A7795_CLK_EHCI0>,
> >  			 <&mstp7_clks R8A7795_CLK_HSUSB>;
> >  	};
> > diff --git a/drivers/phy/phy-rcar-gen3-usb2.c b/drivers/phy/phy-rcar-gen3-usb2.c
> > index 03d7079..40d0005 100644
> > --- a/drivers/phy/phy-rcar-gen3-usb2.c
> > +++ b/drivers/phy/phy-rcar-gen3-usb2.c
> > @@ -12,6 +12,7 @@
> >   * published by the Free Software Foundation.
> >   */
> >
> > +#include <linux/interrupt.h>
> >  #include <linux/io.h>
> >  #include <linux/module.h>
> >  #include <linux/of.h>
> > @@ -26,14 +27,18 @@
> >  #define USB2_SPD_RSM_TIMSET	0x10c
> >  #define USB2_OC_TIMSET		0x110
> >  #define USB2_COMMCTRL		0x600
> > +#define USB2_OBINTSTA		0x604
> > +#define USB2_OBINTEN		0x608
> >  #define USB2_VBCTRL		0x60c
> >  #define USB2_LINECTRL1		0x610
> >  #define USB2_ADPCTRL		0x630
> >
> >  /* INT_ENABLE */
> > +#define USB2_INT_ENABLE_UCOM_INTEN	BIT(3)
> >  #define USB2_INT_ENABLE_USBH_INTB_EN	BIT(2)
> >  #define USB2_INT_ENABLE_USBH_INTA_EN	BIT(1)
> > -#define USB2_INT_ENABLE_INIT		(USB2_INT_ENABLE_USBH_INTB_EN | \
> > +#define USB2_INT_ENABLE_INIT		(USB2_INT_ENABLE_UCOM_INTEN | \
> > +					 USB2_INT_ENABLE_USBH_INTB_EN | \
> >  					 USB2_INT_ENABLE_USBH_INTA_EN)
> >
> >  /* USBCTR */
> > @@ -49,6 +54,12 @@
> >  /* COMMCTRL */
> >  #define USB2_COMMCTRL_OTG_PERI		BIT(31)	/* 1 = Peripheral mode */
> >
> > +/* OBINTSTA and OBINTEN */
> > +#define USB2_OBINT_SESSVLDCHG		BIT(12)
> > +#define USB2_OBINT_IDDIGCHG		BIT(11)
> > +#define USB2_OBINT_BITS			(USB2_OBINT_SESSVLDCHG | \
> > +					 USB2_OBINT_IDDIGCHG)
> > +
> >  /* VBCTRL */
> >  #define USB2_VBCTRL_DRVVBUSSEL		BIT(8)
> >
> > @@ -178,6 +189,9 @@ static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch)
> >
> >  	tmp = readl(usb2_base + USB2_VBCTRL);
> >  	writel(tmp | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL);
> > +	writel(USB2_OBINT_BITS, usb2_base + USB2_OBINTSTA);
> > +	tmp = readl(usb2_base + USB2_OBINTEN);
> > +	writel(tmp | USB2_OBINT_BITS, usb2_base + USB2_OBINTEN);
> >  	tmp = readl(usb2_base + USB2_ADPCTRL);
> >  	writel(tmp | USB2_ADPCTRL_IDPULLUP, usb2_base + USB2_ADPCTRL);
> >  	tmp = readl(usb2_base + USB2_LINECTRL1);
> > @@ -289,6 +303,23 @@ static struct phy_ops rcar_gen3_phy_usb2_ops = {
> >  	.owner		= THIS_MODULE,
> >  };
> >
> > +static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch)
> > +{
> > +	struct rcar_gen3_chan *ch = _ch;
> > +	void __iomem *usb2_base = ch->usb2.base;
> > +	u32 status = readl(usb2_base + USB2_OBINTSTA);
> > +	irqreturn_t ret = IRQ_NONE;
> > +
> > +	if (status & USB2_OBINT_BITS) {
> > +		dev_dbg(&ch->phy->dev, "%s: %08x\n", __func__, status);
> 
> This can be removed or use dev_vdbg.

I got it. I will use dev_vdbg().

> > +		writel(USB2_OBINT_BITS, usb2_base + USB2_OBINTSTA);
> > +		rcar_gen3_device_recognition(ch);
> > +		ret = IRQ_HANDLED;
> > +	}
> > +
> > +	return ret;
> > +}
> > +
> >  static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = {
> >  	{ .compatible = "renesas,usb2-phy-r8a7795" },
> >  	{ }
> > @@ -323,9 +354,19 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
> >
> >  	/* To avoid error message by devm_ioremap_resource() */
> >  	if (res) {
> > +		int ret, irq;
> > +
> >  		channel->hsusb.base = devm_ioremap_resource(dev, res);
> >  		if (IS_ERR(channel->hsusb.base))
> >  			channel->hsusb.base = NULL;
> > +		/* call request_irq for OTG */
> > +		ret = irq = platform_get_irq(pdev, 0);
> is irq optional property? even then you don't need 2 variables to handle
> the same return value.

Yes, the irq is optional property.
Oops, thank you for the point. I will fix it.

> Thanks
> Kishon


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

* Re: [PATCH v4 2/3] phy: rcar-gen3-usb2: change the mode to OTG on the combined channel
  2015-10-17  1:48   ` Kishon Vijay Abraham I
  2015-10-19  8:32     ` Yoshihiro Shimoda
@ 2015-10-19 11:50     ` Khiem Nguyen
  1 sibling, 0 replies; 11+ messages in thread
From: Khiem Nguyen @ 2015-10-19 11:50 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: Yoshihiro Shimoda, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak, linux-kernel, devicetree, linux-sh,
	Toru Oishi

Hi Kishon,

On 10/17/2015 8:48 AM, Kishon Vijay Abraham I wrote:
> Hi,
>
> On Tuesday 13 October 2015 03:52 PM, Yoshihiro Shimoda wrote:
>> To use the channel 0 of R-Car gen3 as periperal mode, This patch changes
>> the mode to OTG instead of HOST. Then, this driver needs to set some
>> registers to enable host mode and detects ID pin and VBUS pin at
>> phy_init() timing.
>>
>> For now, the channel 0 can be used as host mode only.
>>
>> Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
>> ---
>>   drivers/phy/phy-rcar-gen3-usb2.c | 126 ++++++++++++++++++++++++++++++++++++++-
>>   1 file changed, 124 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/phy/phy-rcar-gen3-usb2.c b/drivers/phy/phy-rcar-gen3-usb2.c
>> index d90dfcf..03d7079 100644
>> --- a/drivers/phy/phy-rcar-gen3-usb2.c
>> +++ b/drivers/phy/phy-rcar-gen3-usb2.c

[ .... ] snip

>> +
>> +	dev_dbg(&ch->phy->dev, "%s: %08x, %d\n", __func__, tmp, host);
>
> This shoulod be dev_vdbg.

I guess using dev_dbg() is equivalent.

I searched in same directory (drivers/phy) and the number of drivers 
using dev_vdbg() are just few drivers. (in my search, only 3 drivers). 
Other drivers use dev_dbg().
The last driver using dev_dbg was from Jan 2015.
I also recognized that dev_vdbug was used mostly in USB drivers...

Is it your favorite way or is there any good point of using dev_vdbg() ?

>> +	if (host)
>> +		tmp &= ~USB2_COMMCTRL_OTG_PERI;
>> +	else
>> +		tmp |= USB2_COMMCTRL_OTG_PERI;
>> +	writel(tmp, usb2_base + USB2_COMMCTRL);
>> +}
>> +
>> +static void rcar_gen3_set_linectrl(struct rcar_gen3_chan *ch, int dp, int dm)
>> +{
>> +	void __iomem *usb2_base = ch->usb2.base;
>> +	u32 tmp = readl(usb2_base + USB2_LINECTRL1);
>> +
>> +	dev_dbg(&ch->phy->dev, "%s: %08x, %d, %d\n", __func__, tmp, dp, dm);
>
> same here.

[.....] snip
>
> Thanks
> Kishon
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sh" 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] 11+ messages in thread

end of thread, other threads:[~2015-10-19 11:50 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-13 10:22 [PATCH v4 0/3] phy: rcar-gen3-usb2: Add R-Car Gen3 USB2 PHY driver Yoshihiro Shimoda
2015-10-13 10:22 ` [PATCH v4 1/3] " Yoshihiro Shimoda
2015-10-17  1:43   ` Kishon Vijay Abraham I
2015-10-19  8:30     ` Yoshihiro Shimoda
2015-10-13 10:22 ` [PATCH v4 2/3] phy: rcar-gen3-usb2: change the mode to OTG on the combined channel Yoshihiro Shimoda
2015-10-17  1:48   ` Kishon Vijay Abraham I
2015-10-19  8:32     ` Yoshihiro Shimoda
2015-10-19 11:50     ` Khiem Nguyen
2015-10-13 10:22 ` [PATCH v4 3/3] phy: rcar-gen3-usb2: add runtime ID/VBUS pin detection Yoshihiro Shimoda
2015-10-17  1:53   ` Kishon Vijay Abraham I
2015-10-19  8:35     ` Yoshihiro Shimoda

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).