[PATCH v2] usb: phy: add R-Car USB phy driver

2012-09-05 Thread Kuninori Morimoto
This patch adds Renesas R-Car USB phy driver.
It supports R8A7779 chip at this point.

R-Car has some USB controllers, but has only one phy-initializer.
So, this driver is counting users.

Signed-off-by: Kuninori Morimoto kuninori.morimoto...@renesas.com
---
v1 - v2

- enable usb_phy_xxx()
- used subsys_initcall()

 drivers/usb/phy/Kconfig|   11 ++
 drivers/usb/phy/Makefile   |1 +
 drivers/usb/phy/rcar-phy.c |  241 
 3 files changed, 253 insertions(+)
 create mode 100644 drivers/usb/phy/rcar-phy.c

diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
index 2838adb..f55b6f6 100644
--- a/drivers/usb/phy/Kconfig
+++ b/drivers/usb/phy/Kconfig
@@ -23,3 +23,14 @@ config MV_U3D_PHY
help
  Enable this to support Marvell USB 3.0 phy controller for Marvell
  SoC.
+
+config USB_RCAR_PHY
+   tristate Renesas R-Car USB phy support
+   depends on (USB || USB_GADGET)  ARCH_R8A7779
+   help
+ Say Y here to add support for the Renesas R-Car USB phy driver.
+ This chip is typically used as USB phy for USB host, gadget.
+ This driver supports: R8A7779
+
+ To compile this driver as a module, choose M here: the
+ module will be called rcar-phy.
diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
index cf38f08..9af83f0 100644
--- a/drivers/usb/phy/Makefile
+++ b/drivers/usb/phy/Makefile
@@ -6,3 +6,4 @@ ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG
 
 obj-$(CONFIG_USB_ISP1301)  += isp1301.o
 obj-$(CONFIG_MV_U3D_PHY)   += mv_u3d_phy.o
+obj-$(CONFIG_USB_RCAR_PHY) += rcar-phy.o
diff --git a/drivers/usb/phy/rcar-phy.c b/drivers/usb/phy/rcar-phy.c
new file mode 100644
index 000..2169a1a
--- /dev/null
+++ b/drivers/usb/phy/rcar-phy.c
@@ -0,0 +1,241 @@
+/*
+ * Renesas R-Car USB phy driver
+ *
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ * Kuninori Morimoto kuninori.morimoto...@renesas.com
+ *
+ * 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/delay.h
+#include linux/io.h
+#include linux/usb/otg.h
+#include linux/platform_device.h
+#include linux/spinlock.h
+#include linux/module.h
+
+/* USBH common register */
+#define USBPCTRL0  0x0800
+#define USBPCTRL1  0x0804
+#define USBST  0x0808
+#define USBEH0 0x080C
+#define USBOH0 0x081C
+#define USBCTL00x0858
+#define EIIBC1 0x0094
+#define EIIBC2 0x009C
+
+#ifdef CONFIG_ARCH_SUPPORTS_BIG_ENDIAN
+# define PHY_ENDIAN BIG
+# define PHY_NO_SWAP 0x0003
+#else
+# define PHY_ENDIAN LITTLE
+# define PHY_NO_SWAP 0x
+#endif
+
+/* USBPCTRL1 */
+#define PHY_RST(1  2)
+#define PLL_ENB(1  1)
+#define PHY_ENB(1  0)
+
+/* USBST */
+#define ACT(1  31)
+#define PLL(1  30)
+
+struct rcar_usb_phy_priv {
+   struct usb_phy phy;
+   spinlock_t lock;
+
+   void __iomem *reg0;
+   void __iomem *reg1;
+   int counter;
+};
+
+#define usb_phy_to_priv(p) container_of(p, struct rcar_usb_phy_priv, phy)
+
+
+/*
+ * USB initial/install operation.
+ *
+ * This function setup USB phy.
+ * The used value and setting order came from
+ * [USB :: Initial setting] on datasheet.
+ */
+static int rcar_usb_phy_init(struct usb_phy *phy)
+{
+   struct rcar_usb_phy_priv *priv = usb_phy_to_priv(phy);
+   struct device *dev = phy-dev;
+   void __iomem *reg0 = priv-reg0;
+   void __iomem *reg1 = priv-reg1;
+   int i;
+   u32 val;
+   unsigned long flags;
+
+   /  spin lock /
+   spin_lock_irqsave(priv-lock, flags);
+   if (0 == priv-counter) {
+
+   /**
+* USB phy start-up
+**/
+
+   /* (1) USB-PHY standby release */
+   iowrite32(PHY_ENB, (reg0 + USBPCTRL1));
+
+   /* (2) start USB-PHY internal PLL */
+   iowrite32(PHY_ENB | PLL_ENB, (reg0 + USBPCTRL1));
+
+   /* (3) USB module status check */
+   for (i = 0; i  1024; i++) {
+   udelay(10);
+   val = ioread32(reg0 + USBST);
+   if ((ACT | PLL) == val)
+   goto usb_module_is_working;
+   }
+   dev_err(dev, USB phy not ready\n);
+   return -EIO;
+
+usb_module_is_working:
+   /* (4) USB-PHY reset clear */
+   iowrite32(PHY_ENB | PLL_ENB | PHY_RST, (reg0 + USBPCTRL1));
+
+   /* set platform specific port settings */
+   iowrite32(0x, (reg0 + USBPCTRL0));
+
+   /**
+* 

Re: [PATCH v2] usb: phy: add R-Car USB phy driver

2012-09-05 Thread Marc Kleine-Budde
On 09/05/2012 10:13 AM, Kuninori Morimoto wrote:
 This patch adds Renesas R-Car USB phy driver.
 It supports R8A7779 chip at this point.
 
 R-Car has some USB controllers, but has only one phy-initializer.
 So, this driver is counting users.
 
 Signed-off-by: Kuninori Morimoto kuninori.morimoto...@renesas.com
 ---
 v1 - v2
 
 - enable usb_phy_xxx()
 - used subsys_initcall()
 
  drivers/usb/phy/Kconfig|   11 ++
  drivers/usb/phy/Makefile   |1 +
  drivers/usb/phy/rcar-phy.c |  241 
 
  3 files changed, 253 insertions(+)
  create mode 100644 drivers/usb/phy/rcar-phy.c
 
 diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
 index 2838adb..f55b6f6 100644
 --- a/drivers/usb/phy/Kconfig
 +++ b/drivers/usb/phy/Kconfig
 @@ -23,3 +23,14 @@ config MV_U3D_PHY
   help
 Enable this to support Marvell USB 3.0 phy controller for Marvell
 SoC.
 +
 +config USB_RCAR_PHY
 + tristate Renesas R-Car USB phy support
 + depends on (USB || USB_GADGET)  ARCH_R8A7779
 + help
 +   Say Y here to add support for the Renesas R-Car USB phy driver.
 +   This chip is typically used as USB phy for USB host, gadget.
 +   This driver supports: R8A7779
 +
 +   To compile this driver as a module, choose M here: the
 +   module will be called rcar-phy.
 diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
 index cf38f08..9af83f0 100644
 --- a/drivers/usb/phy/Makefile
 +++ b/drivers/usb/phy/Makefile
 @@ -6,3 +6,4 @@ ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG
  
  obj-$(CONFIG_USB_ISP1301)+= isp1301.o
  obj-$(CONFIG_MV_U3D_PHY) += mv_u3d_phy.o
 +obj-$(CONFIG_USB_RCAR_PHY)   += rcar-phy.o
 diff --git a/drivers/usb/phy/rcar-phy.c b/drivers/usb/phy/rcar-phy.c
 new file mode 100644
 index 000..2169a1a
 --- /dev/null
 +++ b/drivers/usb/phy/rcar-phy.c
 @@ -0,0 +1,241 @@
 +/*
 + * Renesas R-Car USB phy driver
 + *
 + * Copyright (C) 2012 Renesas Solutions Corp.
 + * Kuninori Morimoto kuninori.morimoto...@renesas.com
 + *
 + * 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/delay.h
 +#include linux/io.h
 +#include linux/usb/otg.h
 +#include linux/platform_device.h
 +#include linux/spinlock.h
 +#include linux/module.h
 +
 +/* USBH common register */
 +#define USBPCTRL00x0800
 +#define USBPCTRL10x0804
 +#define USBST0x0808
 +#define USBEH0   0x080C
 +#define USBOH0   0x081C
 +#define USBCTL0  0x0858
 +#define EIIBC1   0x0094
 +#define EIIBC2   0x009C
 +
 +#ifdef CONFIG_ARCH_SUPPORTS_BIG_ENDIAN
 +# define PHY_ENDIAN BIG
 +# define PHY_NO_SWAP 0x0003
 +#else
 +# define PHY_ENDIAN LITTLE
 +# define PHY_NO_SWAP 0x
 +#endif
 +
 +/* USBPCTRL1 */
 +#define PHY_RST  (1  2)
 +#define PLL_ENB  (1  1)
 +#define PHY_ENB  (1  0)
 +
 +/* USBST */
 +#define ACT  (1  31)
 +#define PLL  (1  30)
 +
 +struct rcar_usb_phy_priv {
 + struct usb_phy phy;
 + spinlock_t lock;
 +
 + void __iomem *reg0;
 + void __iomem *reg1;
 + int counter;
 +};
 +
 +#define usb_phy_to_priv(p) container_of(p, struct rcar_usb_phy_priv, phy)
 +
 +
 +/*
 + * USB initial/install operation.
 + *
 + * This function setup USB phy.
 + * The used value and setting order came from
 + * [USB :: Initial setting] on datasheet.
 + */
 +static int rcar_usb_phy_init(struct usb_phy *phy)
 +{
 + struct rcar_usb_phy_priv *priv = usb_phy_to_priv(phy);
 + struct device *dev = phy-dev;
 + void __iomem *reg0 = priv-reg0;
 + void __iomem *reg1 = priv-reg1;
 + int i;
 + u32 val;
 + unsigned long flags;
 +
 + /  spin lock /
 + spin_lock_irqsave(priv-lock, flags);
 + if (0 == priv-counter) {
 +
 + /**
 +  * USB phy start-up
 +  **/

nitpick: unusual coding style

/*
 * This is the preferred
 * multi line style.
 */

 +
 + /* (1) USB-PHY standby release */
 + iowrite32(PHY_ENB, (reg0 + USBPCTRL1));
 +
 + /* (2) start USB-PHY internal PLL */
 + iowrite32(PHY_ENB | PLL_ENB, (reg0 + USBPCTRL1));
 +
 + /* (3) USB module status check */
 + for (i = 0; i  1024; i++) {
 + udelay(10);
 + val = ioread32(reg0 + USBST);
 + if ((ACT | PLL) == val)
 + goto usb_module_is_working;

Don't use goto, unless in error handling.

 + }
 + dev_err(dev, USB phy not ready\n);
 + return -EIO;

You return with the spin_lock held.

 +
 +usb_module_is_working:
 + /* (4) 

Re: [PATCH v2] usb: phy: add R-Car USB phy driver

2012-09-05 Thread ABRAHAM, KISHON VIJAY
Hi,

On Wed, Sep 5, 2012 at 2:01 PM, Marc Kleine-Budde m...@pengutronix.de wrote:
 On 09/05/2012 10:13 AM, Kuninori Morimoto wrote:
 This patch adds Renesas R-Car USB phy driver.
 It supports R8A7779 chip at this point.

 R-Car has some USB controllers, but has only one phy-initializer.
 So, this driver is counting users.

 Signed-off-by: Kuninori Morimoto kuninori.morimoto...@renesas.com
 ---
 v1 - v2

 - enable usb_phy_xxx()
 - used subsys_initcall()

  drivers/usb/phy/Kconfig|   11 ++
  drivers/usb/phy/Makefile   |1 +
  drivers/usb/phy/rcar-phy.c |  241 
 
  3 files changed, 253 insertions(+)
  create mode 100644 drivers/usb/phy/rcar-phy.c

 diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
 index 2838adb..f55b6f6 100644
 --- a/drivers/usb/phy/Kconfig
 +++ b/drivers/usb/phy/Kconfig
 @@ -23,3 +23,14 @@ config MV_U3D_PHY
   help
 Enable this to support Marvell USB 3.0 phy controller for Marvell
 SoC.
 +
 +config USB_RCAR_PHY
 + tristate Renesas R-Car USB phy support
 + depends on (USB || USB_GADGET)  ARCH_R8A7779
 + help
 +   Say Y here to add support for the Renesas R-Car USB phy driver.
 +   This chip is typically used as USB phy for USB host, gadget.
 +   This driver supports: R8A7779
 +
 +   To compile this driver as a module, choose M here: the
 +   module will be called rcar-phy.
 diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
 index cf38f08..9af83f0 100644
 --- a/drivers/usb/phy/Makefile
 +++ b/drivers/usb/phy/Makefile
 @@ -6,3 +6,4 @@ ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG

  obj-$(CONFIG_USB_ISP1301)+= isp1301.o
  obj-$(CONFIG_MV_U3D_PHY) += mv_u3d_phy.o
 +obj-$(CONFIG_USB_RCAR_PHY)   += rcar-phy.o
 diff --git a/drivers/usb/phy/rcar-phy.c b/drivers/usb/phy/rcar-phy.c
 new file mode 100644
 index 000..2169a1a
 --- /dev/null
 +++ b/drivers/usb/phy/rcar-phy.c
 @@ -0,0 +1,241 @@
 +/*
 + * Renesas R-Car USB phy driver
 + *
 + * Copyright (C) 2012 Renesas Solutions Corp.
 + * Kuninori Morimoto kuninori.morimoto...@renesas.com
 + *
 + * 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/delay.h
 +#include linux/io.h
 +#include linux/usb/otg.h
 +#include linux/platform_device.h
 +#include linux/spinlock.h
 +#include linux/module.h
 +
 +/* USBH common register */
 +#define USBPCTRL00x0800
 +#define USBPCTRL10x0804
 +#define USBST0x0808
 +#define USBEH0   0x080C
 +#define USBOH0   0x081C
 +#define USBCTL0  0x0858
 +#define EIIBC1   0x0094
 +#define EIIBC2   0x009C
 +
 +#ifdef CONFIG_ARCH_SUPPORTS_BIG_ENDIAN
 +# define PHY_ENDIAN BIG
 +# define PHY_NO_SWAP 0x0003
 +#else
 +# define PHY_ENDIAN LITTLE
 +# define PHY_NO_SWAP 0x
 +#endif
 +
 +/* USBPCTRL1 */
 +#define PHY_RST  (1  2)
 +#define PLL_ENB  (1  1)
 +#define PHY_ENB  (1  0)
 +
 +/* USBST */
 +#define ACT  (1  31)
 +#define PLL  (1  30)
 +
 +struct rcar_usb_phy_priv {
 + struct usb_phy phy;
 + spinlock_t lock;
 +
 + void __iomem *reg0;
 + void __iomem *reg1;
 + int counter;
 +};
 +
 +#define usb_phy_to_priv(p) container_of(p, struct rcar_usb_phy_priv, phy)
 +
 +
 +/*
 + * USB initial/install operation.
 + *
 + * This function setup USB phy.
 + * The used value and setting order came from
 + * [USB :: Initial setting] on datasheet.
 + */
 +static int rcar_usb_phy_init(struct usb_phy *phy)
 +{
 + struct rcar_usb_phy_priv *priv = usb_phy_to_priv(phy);
 + struct device *dev = phy-dev;
 + void __iomem *reg0 = priv-reg0;
 + void __iomem *reg1 = priv-reg1;
 + int i;
 + u32 val;
 + unsigned long flags;
 +
 + /  spin lock /

While at that, you can also remove the above comment and the *spin
unlocked* comment.


 + spin_lock_irqsave(priv-lock, flags);
 + if (0 == priv-counter) {
 +
 + /**
 +  * USB phy start-up
 +  **/

 nitpick: unusual coding style

 /*
  * This is the preferred
  * multi line style.
  */

 +
 + /* (1) USB-PHY standby release */
 + iowrite32(PHY_ENB, (reg0 + USBPCTRL1));
 +
 + /* (2) start USB-PHY internal PLL */
 + iowrite32(PHY_ENB | PLL_ENB, (reg0 + USBPCTRL1));
 +
 + /* (3) USB module status check */
 + for (i = 0; i  1024; i++) {
 + udelay(10);
 + val = ioread32(reg0 + USBST);
 + if ((ACT | PLL) == val)
 + goto usb_module_is_working;

 Don't use goto, unless in error handling.

 + }