Re: [RFC PATH 1/3] phy: add USB ULPI abstraction layer

2013-12-02 Thread Kishon Vijay Abraham I
Hi,

On Thursday 28 November 2013 09:29 PM, Heikki Krogerus wrote:
 ULPI PHY is an USB2 PHY that is accessed from the USB
 controller. ULPI PHYs allow discovery based on vendor and
 product ids which allows binding the PHY to a driver.
 
 For USB controllers that are enumerated from buses such as
 PCI, that do not provide any information about the PHY, ULPI
 abstraction layer allows runtime detection. This makes it
 possible to take advantage of vendor specific functions of
 the PHYs with product specific drivers without the need for
 platform or device specific quirks.
 
 Signed-off-by: Heikki Krogerus heikki.kroge...@linux.intel.com
 ---
  drivers/phy/Kconfig   |   2 +
  drivers/phy/Makefile  |   1 +
  drivers/phy/ulpi/Kconfig  |  11 ++
  drivers/phy/ulpi/Makefile |   1 +
  drivers/phy/ulpi/ulpi.c   | 273 
 ++
  include/linux/phy/ulpi.h  | 105 ++
  6 files changed, 393 insertions(+)
  create mode 100644 drivers/phy/ulpi/Kconfig
  create mode 100644 drivers/phy/ulpi/Makefile
  create mode 100644 drivers/phy/ulpi/ulpi.c
  create mode 100644 include/linux/phy/ulpi.h
 
 diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
 index a344f3d..6c03824 100644
 --- a/drivers/phy/Kconfig
 +++ b/drivers/phy/Kconfig
 @@ -51,4 +51,6 @@ config PHY_EXYNOS_DP_VIDEO
   help
 Support for Display Port PHY found on Samsung EXYNOS SoCs.
  
 +source drivers/phy/ulpi/Kconfig
 +
  endmenu
 diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
 index d0caae9..d6af605 100644
 --- a/drivers/phy/Makefile
 +++ b/drivers/phy/Makefile
 @@ -7,3 +7,4 @@ obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO) += phy-exynos-dp-video.o
  obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO)  += phy-exynos-mipi-video.o
  obj-$(CONFIG_OMAP_USB2)  += phy-omap-usb2.o
  obj-$(CONFIG_TWL4030_USB)+= phy-twl4030-usb.o
 +obj-$(CONFIG_ULPI_PHY)   += ulpi/
 diff --git a/drivers/phy/ulpi/Kconfig b/drivers/phy/ulpi/Kconfig
 new file mode 100644
 index 000..3211aaa
 --- /dev/null
 +++ b/drivers/phy/ulpi/Kconfig
 @@ -0,0 +1,11 @@
 +
 +config ULPI_PHY
 + tristate USB ULPI PHY interface support
 + depends on USB || USB_GADGET
 + select GENERIC_PHY
 + help
 +   Say yes if you have ULPI PHY attached to your USB controller. If no
 +   vendor modules are selected, the driver will act as NOP PHY driver.
 +
 +   If unsure, say Y.
 +
 diff --git a/drivers/phy/ulpi/Makefile b/drivers/phy/ulpi/Makefile
 new file mode 100644
 index 000..7ed0895
 --- /dev/null
 +++ b/drivers/phy/ulpi/Makefile
 @@ -0,0 +1 @@
 +obj-$(CONFIG_ULPI_PHY)   += ulpi.o
 diff --git a/drivers/phy/ulpi/ulpi.c b/drivers/phy/ulpi/ulpi.c
 new file mode 100644
 index 000..7aa2f5d
 --- /dev/null
 +++ b/drivers/phy/ulpi/ulpi.c
 @@ -0,0 +1,273 @@
 +/**
 + * ulpi.c - USB ULPI PHY abstraction module
 + *
 + * Copyright (C) 2013 Intel Corporation
 + *
 + * Author: Heikki Krogerus heikki.kroge...@linux.intel.com
 + *
 + * This program is free software; you can redistribute  it and/or modify it
 + * under  the terms of  the GNU General  Public License as published by the
 + * Free Software Foundation;  either version 2 of the  License, or (at your
 + * option) any later version.
 + */
 +
 +#include linux/phy/ulpi.h
 +#include linux/phy/phy.h
 +#include linux/module.h
 +#include linux/slab.h
 +
 +/* 
 -- */
 +
 +static struct phy_consumer phy_consumer[] = {
 + { .port = ULPI_PORT_NAME, },

We had to introduce the entire phy_consumer stuff to support legacy pdata. Not
sure if it is a good idea to use it here.
 +};
 +
 +static struct phy_init_data phy_data = {
 + .num_consumers = 1,
 + .consumers = phy_consumer,
 +};
 +
 +static int ulpi_power_on(struct phy *phy)
 +{
 + struct ulpi_dev *ulpi = phy_get_drvdata(phy);
 + struct ulpi_driver *drv = to_ulpi_driver(ulpi-dev.driver);
 +
 + if (drv  drv-phy_ops  drv-phy_ops-power_on)
 + return drv-phy_ops-power_on(phy);
 +
 + return 0;
 +}
 +
 +static int ulpi_power_off(struct phy *phy)
 +{
 + struct ulpi_dev *ulpi = phy_get_drvdata(phy);
 + struct ulpi_driver *drv = to_ulpi_driver(ulpi-dev.driver);
 +
 + if (drv  drv-phy_ops  drv-phy_ops-power_off)
 + return drv-phy_ops-power_off(phy);
 +
 + return 0;
 +}
 +
 +static struct phy_ops phy_ops = {
 + .owner = THIS_MODULE,
 + .power_on = ulpi_power_on,
 + .power_off = ulpi_power_off,
 +};
 +
 +/* 
 -- */
 +
 +static int ulpi_match(struct device *dev, struct device_driver *driver)
 +{
 + struct ulpi_driver *drv = to_ulpi_driver(driver);
 + struct ulpi_dev *ulpi = to_ulpi_dev(dev);
 + const struct ulpi_device_id *id;
 +
 + for (id = drv-id_table; id-vendor; id++)
 + if (id-vendor == ulpi-id.vendor 
 + id-product 

Re: [RFC PATH 1/3] phy: add USB ULPI abstraction layer

2013-12-02 Thread Heikki Krogerus
Hi,

On Mon, Dec 02, 2013 at 04:20:51PM +0530, Kishon Vijay Abraham I wrote:
 Hi,
 
 On Thursday 28 November 2013 09:29 PM, Heikki Krogerus wrote:
  ULPI PHY is an USB2 PHY that is accessed from the USB
  controller. ULPI PHYs allow discovery based on vendor and
  product ids which allows binding the PHY to a driver.
  
  For USB controllers that are enumerated from buses such as
  PCI, that do not provide any information about the PHY, ULPI
  abstraction layer allows runtime detection. This makes it
  possible to take advantage of vendor specific functions of
  the PHYs with product specific drivers without the need for
  platform or device specific quirks.
  
  Signed-off-by: Heikki Krogerus heikki.kroge...@linux.intel.com
  ---
   drivers/phy/Kconfig   |   2 +
   drivers/phy/Makefile  |   1 +
   drivers/phy/ulpi/Kconfig  |  11 ++
   drivers/phy/ulpi/Makefile |   1 +
   drivers/phy/ulpi/ulpi.c   | 273 
  ++
   include/linux/phy/ulpi.h  | 105 ++
   6 files changed, 393 insertions(+)
   create mode 100644 drivers/phy/ulpi/Kconfig
   create mode 100644 drivers/phy/ulpi/Makefile
   create mode 100644 drivers/phy/ulpi/ulpi.c
   create mode 100644 include/linux/phy/ulpi.h
  
  diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
  index a344f3d..6c03824 100644
  --- a/drivers/phy/Kconfig
  +++ b/drivers/phy/Kconfig
  @@ -51,4 +51,6 @@ config PHY_EXYNOS_DP_VIDEO
  help
Support for Display Port PHY found on Samsung EXYNOS SoCs.
   
  +source drivers/phy/ulpi/Kconfig
  +
   endmenu
  diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
  index d0caae9..d6af605 100644
  --- a/drivers/phy/Makefile
  +++ b/drivers/phy/Makefile
  @@ -7,3 +7,4 @@ obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO)   += phy-exynos-dp-video.o
   obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO)+= phy-exynos-mipi-video.o
   obj-$(CONFIG_OMAP_USB2)+= phy-omap-usb2.o
   obj-$(CONFIG_TWL4030_USB)  += phy-twl4030-usb.o
  +obj-$(CONFIG_ULPI_PHY) += ulpi/
  diff --git a/drivers/phy/ulpi/Kconfig b/drivers/phy/ulpi/Kconfig
  new file mode 100644
  index 000..3211aaa
  --- /dev/null
  +++ b/drivers/phy/ulpi/Kconfig
  @@ -0,0 +1,11 @@
  +
  +config ULPI_PHY
  +   tristate USB ULPI PHY interface support
  +   depends on USB || USB_GADGET
  +   select GENERIC_PHY
  +   help
  + Say yes if you have ULPI PHY attached to your USB controller. If no
  + vendor modules are selected, the driver will act as NOP PHY driver.
  +
  + If unsure, say Y.
  +
  diff --git a/drivers/phy/ulpi/Makefile b/drivers/phy/ulpi/Makefile
  new file mode 100644
  index 000..7ed0895
  --- /dev/null
  +++ b/drivers/phy/ulpi/Makefile
  @@ -0,0 +1 @@
  +obj-$(CONFIG_ULPI_PHY) += ulpi.o
  diff --git a/drivers/phy/ulpi/ulpi.c b/drivers/phy/ulpi/ulpi.c
  new file mode 100644
  index 000..7aa2f5d
  --- /dev/null
  +++ b/drivers/phy/ulpi/ulpi.c
  @@ -0,0 +1,273 @@
  +/**
  + * ulpi.c - USB ULPI PHY abstraction module
  + *
  + * Copyright (C) 2013 Intel Corporation
  + *
  + * Author: Heikki Krogerus heikki.kroge...@linux.intel.com
  + *
  + * This program is free software; you can redistribute  it and/or modify it
  + * under  the terms of  the GNU General  Public License as published by the
  + * Free Software Foundation;  either version 2 of the  License, or (at your
  + * option) any later version.
  + */
  +
  +#include linux/phy/ulpi.h
  +#include linux/phy/phy.h
  +#include linux/module.h
  +#include linux/slab.h
  +
  +/* 
  -- 
  */
  +
  +static struct phy_consumer phy_consumer[] = {
  +   { .port = ULPI_PORT_NAME, },
 
 We had to introduce the entire phy_consumer stuff to support legacy pdata. Not
 sure if it is a good idea to use it here.

Well, maybe we can improve it at least a bit. I don't see how it's
possible to get rid of the device name matching, but at least the port
name dependency could be replaced with possibility to use index
instead. Check how they made the gpiod lookup to work in gpiolib.

Let's get back to this one.

  +};
  +
  +static struct phy_init_data phy_data = {
  +   .num_consumers = 1,
  +   .consumers = phy_consumer,
  +};
  +
  +static int ulpi_power_on(struct phy *phy)
  +{
  +   struct ulpi_dev *ulpi = phy_get_drvdata(phy);
  +   struct ulpi_driver *drv = to_ulpi_driver(ulpi-dev.driver);
  +
  +   if (drv  drv-phy_ops  drv-phy_ops-power_on)
  +   return drv-phy_ops-power_on(phy);
  +
  +   return 0;
  +}
  +
  +static int ulpi_power_off(struct phy *phy)
  +{
  +   struct ulpi_dev *ulpi = phy_get_drvdata(phy);
  +   struct ulpi_driver *drv = to_ulpi_driver(ulpi-dev.driver);
  +
  +   if (drv  drv-phy_ops  drv-phy_ops-power_off)
  +   return drv-phy_ops-power_off(phy);
  +
  +   return 0;
  +}
  +
  +static struct phy_ops phy_ops = {
  +   .owner = THIS_MODULE,
  +   .power_on = ulpi_power_on,
  +   .power_off = 

[RFC PATH 1/3] phy: add USB ULPI abstraction layer

2013-11-28 Thread Heikki Krogerus
ULPI PHY is an USB2 PHY that is accessed from the USB
controller. ULPI PHYs allow discovery based on vendor and
product ids which allows binding the PHY to a driver.

For USB controllers that are enumerated from buses such as
PCI, that do not provide any information about the PHY, ULPI
abstraction layer allows runtime detection. This makes it
possible to take advantage of vendor specific functions of
the PHYs with product specific drivers without the need for
platform or device specific quirks.

Signed-off-by: Heikki Krogerus heikki.kroge...@linux.intel.com
---
 drivers/phy/Kconfig   |   2 +
 drivers/phy/Makefile  |   1 +
 drivers/phy/ulpi/Kconfig  |  11 ++
 drivers/phy/ulpi/Makefile |   1 +
 drivers/phy/ulpi/ulpi.c   | 273 ++
 include/linux/phy/ulpi.h  | 105 ++
 6 files changed, 393 insertions(+)
 create mode 100644 drivers/phy/ulpi/Kconfig
 create mode 100644 drivers/phy/ulpi/Makefile
 create mode 100644 drivers/phy/ulpi/ulpi.c
 create mode 100644 include/linux/phy/ulpi.h

diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index a344f3d..6c03824 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -51,4 +51,6 @@ config PHY_EXYNOS_DP_VIDEO
help
  Support for Display Port PHY found on Samsung EXYNOS SoCs.
 
+source drivers/phy/ulpi/Kconfig
+
 endmenu
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index d0caae9..d6af605 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -7,3 +7,4 @@ obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO)   += phy-exynos-dp-video.o
 obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO)+= phy-exynos-mipi-video.o
 obj-$(CONFIG_OMAP_USB2)+= phy-omap-usb2.o
 obj-$(CONFIG_TWL4030_USB)  += phy-twl4030-usb.o
+obj-$(CONFIG_ULPI_PHY) += ulpi/
diff --git a/drivers/phy/ulpi/Kconfig b/drivers/phy/ulpi/Kconfig
new file mode 100644
index 000..3211aaa
--- /dev/null
+++ b/drivers/phy/ulpi/Kconfig
@@ -0,0 +1,11 @@
+
+config ULPI_PHY
+   tristate USB ULPI PHY interface support
+   depends on USB || USB_GADGET
+   select GENERIC_PHY
+   help
+ Say yes if you have ULPI PHY attached to your USB controller. If no
+ vendor modules are selected, the driver will act as NOP PHY driver.
+
+ If unsure, say Y.
+
diff --git a/drivers/phy/ulpi/Makefile b/drivers/phy/ulpi/Makefile
new file mode 100644
index 000..7ed0895
--- /dev/null
+++ b/drivers/phy/ulpi/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_ULPI_PHY) += ulpi.o
diff --git a/drivers/phy/ulpi/ulpi.c b/drivers/phy/ulpi/ulpi.c
new file mode 100644
index 000..7aa2f5d
--- /dev/null
+++ b/drivers/phy/ulpi/ulpi.c
@@ -0,0 +1,273 @@
+/**
+ * ulpi.c - USB ULPI PHY abstraction module
+ *
+ * Copyright (C) 2013 Intel Corporation
+ *
+ * Author: Heikki Krogerus heikki.kroge...@linux.intel.com
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include linux/phy/ulpi.h
+#include linux/phy/phy.h
+#include linux/module.h
+#include linux/slab.h
+
+/* -- 
*/
+
+static struct phy_consumer phy_consumer[] = {
+   { .port = ULPI_PORT_NAME, },
+};
+
+static struct phy_init_data phy_data = {
+   .num_consumers = 1,
+   .consumers = phy_consumer,
+};
+
+static int ulpi_power_on(struct phy *phy)
+{
+   struct ulpi_dev *ulpi = phy_get_drvdata(phy);
+   struct ulpi_driver *drv = to_ulpi_driver(ulpi-dev.driver);
+
+   if (drv  drv-phy_ops  drv-phy_ops-power_on)
+   return drv-phy_ops-power_on(phy);
+
+   return 0;
+}
+
+static int ulpi_power_off(struct phy *phy)
+{
+   struct ulpi_dev *ulpi = phy_get_drvdata(phy);
+   struct ulpi_driver *drv = to_ulpi_driver(ulpi-dev.driver);
+
+   if (drv  drv-phy_ops  drv-phy_ops-power_off)
+   return drv-phy_ops-power_off(phy);
+
+   return 0;
+}
+
+static struct phy_ops phy_ops = {
+   .owner = THIS_MODULE,
+   .power_on = ulpi_power_on,
+   .power_off = ulpi_power_off,
+};
+
+/* -- 
*/
+
+static int ulpi_match(struct device *dev, struct device_driver *driver)
+{
+   struct ulpi_driver *drv = to_ulpi_driver(driver);
+   struct ulpi_dev *ulpi = to_ulpi_dev(dev);
+   const struct ulpi_device_id *id;
+
+   for (id = drv-id_table; id-vendor; id++)
+   if (id-vendor == ulpi-id.vendor 
+   id-product == ulpi-id.product)
+   return 1;
+
+   return 0;
+}
+
+static int ulpi_probe(struct device *dev)
+{
+   struct ulpi_driver *drv = to_ulpi_driver(dev-driver);
+
+   return drv-probe(to_ulpi_dev(dev));
+}
+
+static int ulpi_remove(struct device