PHY framework

Started by Kishon Vijay Abraham I on Jul 18, 2013 · 95 messages from 14 authors · Last reply Aug 20, 2013

Series

15 patches, 43 files

+1,774 −417

Subsystems (11)

Show 8 more

Maintainers (16)

Show 12 more
STALE4833d SUPERSEDED

Status: Superseded by v12 (posted 2013-09-27). [go to v12]

Revision v1 (4 revisions archived).

Revisions (4)
  1. v1 current
  2. v10 [diff against previous] re-posted go to this post
  3. v11 [diff against previous]
  4. v12 [diff against previous]

page 1 of 2 · open the first message on its own page

  1. [PATCH 01/15] drivers: phy: add generic PHY framework
    Revisions and related patches
    Revisions (4)
    1. v1 current
    2. v10 [diff against previous] re-posted go to this post
    3. v11 [diff against previous]
    4. v12 [diff against previous]
  2. [PATCH 03/15] usb: phy: twl4030: use the new generic PHY framework
    Revisions and related patches
    Revisions (4)
    1. v1 current
    2. v10 [diff against previous] re-posted go to this post
    3. v11 [diff against previous]
    4. v12 [diff against previous]
  3. [PATCH 04/15] ARM: OMAP: USB: Add phy binding information
    Revisions and related patches
    Revisions (4)
    1. v1 current
    2. v10 [diff against previous] re-posted go to this post
    3. v11 [diff against previous]
    4. v12 [diff against previous]
  4. [PATCH 05/15] ARM: dts: omap: update usb_otg_hs data
    Revisions and related patches
    Revisions (4)
    1. v1 current
    2. v10 [diff against previous] re-posted go to this post
    3. v11 [diff against previous]
    4. v12 [diff against previous]
  5. [PATCH 06/15] usb: musb: omap2430: use the new generic PHY framework
    Revisions and related patches
    Revisions (4)
    1. v1 current
    2. v10 [diff against previous] re-posted go to this post
    3. v11 [diff against previous]
    4. v12 [diff against previous]
  6. [PATCH 07/15] usb: phy: omap-usb2: remove *set_suspend* callback from omap-usb2
    Revisions and related patches
    Revisions (4)
    1. v1 current
    2. v10 [diff against previous] re-posted go to this post
    3. v11 [diff against previous]
    4. v12 [diff against previous]
  7. [PATCH 09/15] phy: Add driver for Exynos MIPI CSIS/DSIM DPHYs
    Related patches
  8. [PATCH 10/15] video: exynos_mipi_dsim: Use the generic PHY driver
    Related patches
  9. [PATCH 11/15] exynos4-is: Use the generic MIPI CSIS PHY driver
    Related patches
  10. [PATCH 12/15] ARM: Samsung: Remove the MIPI PHY setup code
    Related patches
  11. [PATCH 15/15] video: exynos_dp: Use the generic PHY driver
    Related patches
  12. [PATCH 14/15] video: exynos_dp: remove non-DT support for Exynos Display Port
    Related patches
  13. [PATCH 13/15] phy: Add driver for Exynos DP PHY
    Related patches
  14. [PATCH 08/15] usb: phy: twl4030-usb: remove *set_suspend* and *phy_init* ops
    Revisions and related patches
    Revisions (3)
    1. v1 current
    2. v10 [diff against previous] re-posted go to this post
    3. v11 [diff against previous]
  15. [PATCH 02/15] usb: phy: omap-usb2: use the new generic PHY framework
    Revisions and related patches
    Revisions (4)
    1. v1 current
    2. v10 [diff against previous] re-posted go to this post
    3. v11 [diff against previous]
    4. v12 [diff against previous]
Message details and related content
Added a generic PHY framework that provides a set of APIs for the PHY drivers
to create/destroy a PHY and APIs for the PHY users to obtain a reference to
the PHY with or without using phandle.

This framework will be of use only to devices that uses external PHY (PHY
functionality is not embedded within the controller).

The intention of creating this framework is to bring the phy drivers spread
all over the Linux kernel to drivers/phy to increase code re-use and to
increase code maintainability.

Comments to make PHY as bus wasn't done because PHY devices can be part of
other bus and making a same device attached to multiple bus leads to bad
design.

If the PHY driver has to send notification on connect/disconnect, the PHY
driver should make use of the extcon framework. Using this susbsystem
to use extcon framwork will have to be analysed.

Exynos MIPI CSIS/DSIM PHY and Displayport PHY have started using this
framework. Have included those patches also in this series.

twl4030-usb and omap-usb2 have also been adapted to this framework.

These patches are also available @
git://gitorious.org/linuxphy/linuxphy.git tags/phy-for-v3.12

Jingoo Han (3):
  phy: Add driver for Exynos DP PHY
  video: exynos_dp: remove non-DT support for Exynos Display Port
  video: exynos_dp: Use the generic PHY driver

Kishon Vijay Abraham I (8):
  drivers: phy: add generic PHY framework
  usb: phy: omap-usb2: use the new generic PHY framework
  usb: phy: twl4030: use the new generic PHY framework
  ARM: OMAP: USB: Add phy binding information
  ARM: dts: omap: update usb_otg_hs data
  usb: musb: omap2430: use the new generic PHY framework
  usb: phy: omap-usb2: remove *set_suspend* callback from omap-usb2

67 more lines

[PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
The PHY framework provides a set of APIs for the PHY drivers to
create/destroy a PHY and APIs for the PHY users to obtain a reference to the
PHY with or without using phandle. For dt-boot, the PHY drivers should
also register *PHY provider* with the framework.

PHY drivers should create the PHY by passing id and ops like init, exit,
power_on and power_off. This framework is also pm runtime enabled.

The documentation for the generic PHY framework is added in
Documentation/phy.txt and the documentation for dt binding can be found at
Documentation/devicetree/bindings/phy/phy-bindings.txt

Signed-off-by: Kishon Vijay Abraham I <redacted>
Acked-by: Felipe Balbi <redacted>
Tested-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 .../devicetree/bindings/phy/phy-bindings.txt       |   66 +++
 Documentation/phy.txt                              |  129 +++++
 MAINTAINERS                                        |    7 +
 drivers/Kconfig                                    |    2 +
 drivers/Makefile                                   |    2 +
 drivers/phy/Kconfig                                |   13 +
 drivers/phy/Makefile                               |    5 +
 drivers/phy/phy-core.c                             |  544 ++++++++++++++++++++
 include/linux/phy/phy.h                            |  344 +++++++++++++
 9 files changed, 1112 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/phy-bindings.txt
 create mode 100644 Documentation/phy.txt
 create mode 100644 drivers/phy/Kconfig
 create mode 100644 drivers/phy/Makefile
 create mode 100644 drivers/phy/phy-core.c
 create mode 100644 include/linux/phy/phy.h
diff --git a/Documentation/devicetree/bindings/phy/phy-bindings.txt b/Documentation/devicetree/bindings/phy/phy-bindings.txt
new file mode 100644
index 0000000..8ae844f
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/phy-bindings.txt
@@ -0,0 +1,66 @@
+This document explains only the device tree data binding. For general
+information about PHY subsystem refer to Documentation/phy.txt
+
+PHY device node
+=======+
+Required Properties:
+#phy-cells:	Number of cells in a PHY specifier;  The meaning of all those
+		cells is defined by the binding for the phy node. The PHY
+		provider can use the values in cells to find the appropriate
+		PHY.
+
+For example:
+
+phys: phy {
+    compatible = "xxx";
+    reg = <...>;
+    .
+    .
+    #phy-cells = <1>;
+    .
+    .
+};
+
+That node describes an IP block (PHY provider) that implements 2 different PHYs.
+In order to differentiate between these 2 PHYs, an additonal specifier should be
+given while trying to get a reference to it.
+
+PHY user node
+======+
+Required Properties:
+phys : the phandle for the PHY device (used by the PHY subsystem)
+phy-names : the names of the PHY corresponding to the PHYs present in the
+	    *phys* phandle
+
+Example 1:
+usb1: usb_otg_ss@xxx {
+    compatible = "xxx";
+    reg = <xxx>;
+    .
+    .
+    phys = <&usb2_phy>, <&usb3_phy>;
+    phy-names = "usb2phy", "usb3phy";
+    .
+    .
+};
+
+This node represents a controller that uses two PHYs, one for usb2 and one for
+usb3.
+
+Example 2:
+usb2: usb_otg_ss@xxx {
+    compatible = "xxx";
+    reg = <xxx>;
+    .
+    .
+    phys = <&phys 1>;
+    phy-names = "usbphy";
+    .
+    .
+};
+
+This node represents a controller that uses one of the PHYs of the PHY provider
+device defined previously. Note that the phy handle has an additional specifier
+"1" to differentiate between the two PHYs.
diff --git a/Documentation/phy.txt b/Documentation/phy.txt
new file mode 100644
index 0000000..05f8fda
--- /dev/null
+++ b/Documentation/phy.txt
@@ -0,0 +1,129 @@
+			    PHY SUBSYSTEM
+		  Kishon Vijay Abraham I <kishon@ti.com>
+
+This document explains the Generic PHY Framework along with the APIs provided,
+and how-to-use.
+
+1. Introduction
+
+*PHY* is the abbreviation for physical layer. It is used to connect a device
+to the physical medium e.g., the USB controller has a PHY to provide functions
+such as serialization, de-serialization, encoding, decoding and is responsible
+for obtaining the required data transmission rate. Note that some USB
+controllers have PHY functionality embedded into it and others use an external
+PHY. Other peripherals that use PHY include Wireless LAN, Ethernet,
+SATA etc.
+
+The intention of creating this framework is to bring the PHY drivers spread
+all over the Linux kernel to drivers/phy to increase code re-use and for
+better code maintainability.
+
+This framework will be of use only to devices that use external PHY (PHY
+functionality is not embedded within the controller).
+
+2. Registering/Unregistering the PHY provider
+
+PHY provider refers to an entity that implements one or more PHY instances.
+For the simple case where the PHY provider implements only a single instance of
+the PHY, the framework provides its own implementation of of_xlate in
+of_phy_simple_xlate. If the PHY provider implements multiple instances, it
+should provide its own implementation of of_xlate. of_xlate is used only for
+dt boot case.
+
+struct phy_provider *__of_phy_provider_register(struct device *dev,
+	struct module *owner, struct phy * (*of_xlate)(struct device *dev,
+	struct of_phandle_args *args));
+struct phy_provider *__devm_of_phy_provider_register(struct device *dev,
+	struct module *owner, struct phy * (*of_xlate)(struct device *dev,
+	struct of_phandle_args *args))
+
+__of_phy_provider_register and __devm_of_phy_provider_register can be used to
+register the phy_provider and it takes device, owner and of_xlate as
+arguments. For the dt boot case, all PHY providers should use one of the above
+2 APIs to register the PHY provider.
+
+void devm_of_phy_provider_unregister(struct device *dev,
+	struct phy_provider *phy_provider);
+void of_phy_provider_unregister(struct phy_provider *phy_provider);
+
+devm_of_phy_provider_unregister and of_phy_provider_unregister can be used to
+unregister the PHY.
+
+3. Creating the PHY
+
+The PHY driver should create the PHY in order for other peripheral controllers
+to make use of it. The PHY framework provides 2 APIs to create the PHY.
+
+struct phy *phy_create(struct device *dev, u8 id, const struct phy_ops *ops,
+	const char *label);
+extern struct phy *devm_phy_create(struct device *dev, u8 id,
+        const struct phy_ops *ops, const char *label);
+
+The PHY drivers can use one of the above 2 APIs to create the PHY by passing
+the device pointer, id, phy ops, label and a driver data.
+phy_ops is a set of function pointers for performing PHY operations such as
+init, exit, power_on and power_off. *label* is mandatory for non-dt boot case
+and it should be unique as well.
+
+Inorder to dereference the private data (in phy_ops), the phy provider driver
+can use phy_set_drvdata() after creating the PHY and use phy_get_drvdata() in
+phy_ops to get back the private data.
+
+4. Getting a reference to the PHY
+
+Before the controller can make use of the PHY, it has to get a reference to
+it. This framework provides the following APIs to get a reference to the PHY.
+
+struct phy *phy_get(struct device *dev, const char *string);
+struct phy *devm_phy_get(struct device *dev, const char *string);
+
+phy_get and devm_phy_get can be used to get the PHY. In the case of dt boot,
+the string arguments should contain the phy name as given in the dt data and
+in the case of non-dt boot, it should contain the label of the PHY.
+The only difference between the two APIs is that devm_phy_get associates the
+device with the PHY using devres on successful PHY get. On driver detach,
+release function is invoked on the the devres data and devres data is freed.
+
+5. Releasing a reference to the PHY
+
+When the controller no longer needs the PHY, it has to release the reference
+to the PHY it has obtained using the APIs mentioned in the above section. The
+PHY framework provides 2 APIs to release a reference to the PHY.
+
+void phy_put(struct phy *phy);
+void devm_phy_put(struct device *dev, struct phy *phy);
+
+Both these APIs are used to release a reference to the PHY and devm_phy_put
+destroys the devres associated with this PHY.
+
+6. Destroying the PHY
+
+When the driver that created the PHY is unloaded, it should destroy the PHY it
+created using one of the following 2 APIs.
+
+void phy_destroy(struct phy *phy);
+void devm_phy_destroy(struct device *dev, struct phy *phy);
+
+Both these APIs destroy the PHY and devm_phy_destroy destroys the devres
+associated with this PHY.
+
+7. PM Runtime
+
+This subsystem is pm runtime enabled. So while creating the PHY,
+pm_runtime_enable of the phy device created by this subsystem is called and
+while destroying the PHY, pm_runtime_disable is called. Note that the phy
+device created by this subsystem will be a child of the device that calls
+phy_create (PHY provider device).
+
+So pm_runtime_get_sync of the phy_device created by this subsystem will invoke
+pm_runtime_get_sync of PHY provider device because of parent-child relationship.
+It should also be noted that phy_power_on and phy_power_off performs
+phy_pm_runtime_get_sync and phy_pm_runtime_put respectively.
+There are exported APIs like phy_pm_runtime_get, phy_pm_runtime_get_sync,
+phy_pm_runtime_put, phy_pm_runtime_put_sync, phy_pm_runtime_allow and
+phy_pm_runtime_forbid for performing PM operations.
+
+8. DeviceTree Binding
+
+The documentation for PHY dt binding can be found @
+Documentation/devicetree/bindings/phy/phy-bindings.txt
diff --git a/MAINTAINERS b/MAINTAINERS
index bf61e04..dd03889 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3594,6 +3594,13 @@ S:	Maintained
 F:	include/asm-generic
 F:	include/uapi/asm-generic
 
+GENERIC PHY FRAMEWORK
+M:	Kishon Vijay Abraham I <kishon@ti.com>
+L:	linux-kernel@vger.kernel.org
+S:	Supported
+F:	drivers/phy/
+F:	include/linux/phy/
+
 GENERIC UIO DRIVER FOR PCI DEVICES
 M:	"Michael S. Tsirkin" <mst@redhat.com>
 L:	kvm@vger.kernel.org
diff --git a/drivers/Kconfig b/drivers/Kconfig
index aa43b91..8f45144 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -166,4 +166,6 @@ source "drivers/reset/Kconfig"
 
 source "drivers/fmc/Kconfig"
 
+source "drivers/phy/Kconfig"
+
 endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index ab93de8..687da89 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -8,6 +8,8 @@
 obj-y				+= irqchip/
 obj-y				+= bus/
 
+obj-$(CONFIG_GENERIC_PHY)	+= phy/
+
 # GPIO must come after pinctrl as gpios may need to mux pins etc
 obj-y				+= pinctrl/
 obj-y				+= gpio/
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
new file mode 100644
index 0000000..5f85909
--- /dev/null
+++ b/drivers/phy/Kconfig
@@ -0,0 +1,13 @@
+#
+# PHY
+#
+
+menuconfig GENERIC_PHY
+	tristate "PHY Subsystem"
+	help
+	  Generic PHY support.
+
+	  This framework is designed to provide a generic interface for PHY
+	  devices present in the kernel. This layer will have the generic
+	  API by which phy drivers can create PHY using the phy framework and
+	  phy users can obtain reference to the PHY.
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
new file mode 100644
index 0000000..9e9560f
--- /dev/null
+++ b/drivers/phy/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the phy drivers.
+#
+
+obj-$(CONFIG_GENERIC_PHY)	+= phy-core.o
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
new file mode 100644
index 0000000..6c75dc3
--- /dev/null
+++ b/drivers/phy/phy-core.c
@@ -0,0 +1,544 @@
+/*
+ * phy-core.c  --  Generic Phy framework.
+ *
+ * Copyright (C) 2013 Texas Instruments
+ *
+ * Author: Kishon Vijay Abraham I <kishon@ti.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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/export.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/phy/phy.h>
+#include <linux/pm_runtime.h>
+
+static struct class *phy_class;
+static DEFINE_MUTEX(phy_provider_mutex);
+static LIST_HEAD(phy_provider_list);
+
+static void devm_phy_release(struct device *dev, void *res)
+{
+	struct phy *phy = *(struct phy **)res;
+
+	phy_put(phy);
+}
+
+static void devm_phy_provider_release(struct device *dev, void *res)
+{
+	struct phy_provider *phy_provider = *(struct phy_provider **)res;
+
+	of_phy_provider_unregister(phy_provider);
+}
+
+static void devm_phy_consume(struct device *dev, void *res)
+{
+	struct phy *phy = *(struct phy **)res;
+
+	phy_destroy(phy);
+}
+
+static int devm_phy_match(struct device *dev, void *res, void *match_data)
+{
+	return res = match_data;
+}
+
+static struct phy *phy_lookup(const char *phy_name)
+{
+	struct phy *phy;
+	struct device *dev;
+	struct class_dev_iter iter;
+
+	class_dev_iter_init(&iter, phy_class, NULL, NULL);
+	while ((dev = class_dev_iter_next(&iter))) {
+		phy = to_phy(dev);
+		if (strcmp(phy->label, phy_name))
+			continue;
+
+		class_dev_iter_exit(&iter);
+		return phy;
+	}
+
+	class_dev_iter_exit(&iter);
+	return ERR_PTR(-ENODEV);
+}
+
+static struct phy_provider *of_phy_provider_lookup(struct device_node *node)
+{
+	struct phy_provider *phy_provider;
+
+	list_for_each_entry(phy_provider, &phy_provider_list, list) {
+		if (phy_provider->dev->of_node = node)
+			return phy_provider;
+	}
+
+	return ERR_PTR(-EPROBE_DEFER);
+}
+
+/**
+ * of_phy_get() - lookup and obtain a reference to a phy by phandle
+ * @dev: device that requests this phy
+ * @index: the index of the phy
+ *
+ * Returns the phy associated with the given phandle value,
+ * after getting a refcount to it or -ENODEV if there is no such phy or
+ * -EPROBE_DEFER if there is a phandle to the phy, but the device is
+ * not yet loaded. This function uses of_xlate call back function provided
+ * while registering the phy_provider to find the phy instance.
+ */
+static struct phy *of_phy_get(struct device *dev, int index)
+{
+	int ret;
+	struct phy_provider *phy_provider;
+	struct phy *phy = NULL;
+	struct of_phandle_args args;
+
+	ret = of_parse_phandle_with_args(dev->of_node, "phys", "#phy-cells",
+		index, &args);
+	if (ret) {
+		dev_dbg(dev, "failed to get phy in %s node\n",
+			dev->of_node->full_name);
+		return ERR_PTR(-ENODEV);
+	}
+
+	mutex_lock(&phy_provider_mutex);
+	phy_provider = of_phy_provider_lookup(args.np);
+	if (IS_ERR(phy_provider) || !try_module_get(phy_provider->owner)) {
+		phy = ERR_PTR(-EPROBE_DEFER);
+		goto err0;
+	}
+
+	phy = phy_provider->of_xlate(phy_provider->dev, &args);
+	module_put(phy_provider->owner);
+
+err0:
+	mutex_unlock(&phy_provider_mutex);
+	of_node_put(args.np);
+
+	return phy;
+}
+
+/**
+ * phy_put() - release the PHY
+ * @phy: the phy returned by phy_get()
+ *
+ * Releases a refcount the caller received from phy_get().
+ */
+void phy_put(struct phy *phy)
+{
+	if (IS_ERR(phy))
+		return;
+
+	module_put(phy->ops->owner);
+	put_device(&phy->dev);
+}
+EXPORT_SYMBOL_GPL(phy_put);
+
+/**
+ * devm_phy_put() - release the PHY
+ * @dev: device that wants to release this phy
+ * @phy: the phy returned by devm_phy_get()
+ *
+ * destroys the devres associated with this phy and invokes phy_put
+ * to release the phy.
+ */
+void devm_phy_put(struct device *dev, struct phy *phy)
+{
+	int r;
+
+	r = devres_destroy(dev, devm_phy_release, devm_phy_match, phy);
+	dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n");
+}
+EXPORT_SYMBOL_GPL(devm_phy_put);
+
+/**
+ * of_phy_simple_xlate() - returns the phy instance from phy provider
+ * @dev: the PHY provider device
+ * @args: of_phandle_args (not used here)
+ *
+ * Intended to be used by phy provider for the common case where #phy-cells is
+ * 0. For other cases where #phy-cells is greater than '0', the phy provider
+ * should provide a custom of_xlate function that reads the *args* and returns
+ * the appropriate phy.
+ */
+struct phy *of_phy_simple_xlate(struct device *dev, struct of_phandle_args
+	*args)
+{
+	struct phy *phy;
+	struct class_dev_iter iter;
+	struct device_node *node = dev->of_node;
+
+	class_dev_iter_init(&iter, phy_class, NULL, NULL);
+	while ((dev = class_dev_iter_next(&iter))) {
+		phy = to_phy(dev);
+		if (node != phy->dev.of_node)
+			continue;
+
+		class_dev_iter_exit(&iter);
+		return phy;
+	}
+
+	class_dev_iter_exit(&iter);
+	return ERR_PTR(-ENODEV);
+}
+EXPORT_SYMBOL_GPL(of_phy_simple_xlate);
+
+/**
+ * phy_get() - lookup and obtain a reference to a phy.
+ * @dev: device that requests this phy
+ * @string: the phy name as given in the dt data or phy device name
+ * for non-dt case
+ *
+ * Returns the phy driver, after getting a refcount to it; or
+ * -ENODEV if there is no such phy.  The caller is responsible for
+ * calling phy_put() to release that count.
+ */
+struct phy *phy_get(struct device *dev, const char *string)
+{
+	int index = 0;
+	struct phy *phy = NULL;
+
+	if (string = NULL) {
+		dev_WARN(dev, "missing string\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (dev->of_node) {
+		index = of_property_match_string(dev->of_node, "phy-names",
+			string);
+		phy = of_phy_get(dev, index);
+		if (IS_ERR(phy)) {
+			dev_WARN(dev, "unable to find phy\n");
+			return phy;
+		}
+	} else {
+		phy = phy_lookup(string);
+		if (IS_ERR(phy)) {
+			dev_WARN(dev, "unable to find phy\n");
+			return phy;
+		}
+	}
+
+	if (!try_module_get(phy->ops->owner))
+		return ERR_PTR(-EPROBE_DEFER);
+
+	get_device(&phy->dev);
+
+	return phy;
+}
+EXPORT_SYMBOL_GPL(phy_get);
+
+/**
+ * devm_phy_get() - lookup and obtain a reference to a phy.
+ * @dev: device that requests this phy
+ * @string: the phy name as given in the dt data or phy device name
+ * for non-dt case
+ *
+ * Gets the phy using phy_get(), and associates a device with it using
+ * devres. On driver detach, release function is invoked on the devres data,
+ * then, devres data is freed.
+ */
+struct phy *devm_phy_get(struct device *dev, const char *string)
+{
+	struct phy **ptr, *phy;
+
+	ptr = devres_alloc(devm_phy_release, sizeof(*ptr), GFP_KERNEL);
+	if (!ptr)
+		return ERR_PTR(-ENOMEM);
+
+	phy = phy_get(dev, string);
+	if (!IS_ERR(phy)) {
+		*ptr = phy;
+		devres_add(dev, ptr);
+	} else {
+		devres_free(ptr);
+	}
+
+	return phy;
+}
+EXPORT_SYMBOL_GPL(devm_phy_get);
+
+/**
+ * phy_create() - create a new phy
+ * @dev: device that is creating the new phy
+ * @id: id of the phy
+ * @ops: function pointers for performing phy operations
+ * @label: label given to the phy
+ *
+ * Called to create a phy using phy framework.
+ */
+struct phy *phy_create(struct device *dev, u8 id, const struct phy_ops *ops,
+	const char *label)
+{
+	int ret;
+	struct phy *phy;
+
+	if (!dev) {
+		dev_WARN(dev, "no device provided for PHY\n");
+		ret = -EINVAL;
+		goto err0;
+	}
+
+	phy = kzalloc(sizeof(*phy), GFP_KERNEL);
+	if (!phy) {
+		ret = -ENOMEM;
+		goto err0;
+	}
+
+	device_initialize(&phy->dev);
+	mutex_init(&phy->mutex);
+
+	phy->dev.class = phy_class;
+	phy->dev.parent = dev;
+	phy->dev.of_node = dev->of_node;
+	phy->id = id;
+	phy->ops = ops;
+	phy->label = kstrdup(label, GFP_KERNEL);
+
+	ret = dev_set_name(&phy->dev, "%s.%d", dev_name(dev), id);
+	if (ret)
+		goto err1;
+
+	ret = device_add(&phy->dev);
+	if (ret)
+		goto err1;
+
+	if (pm_runtime_enabled(dev)) {
+		pm_runtime_enable(&phy->dev);
+		pm_runtime_no_callbacks(&phy->dev);
+	}
+
+	return phy;
+
+err1:
+	put_device(&phy->dev);
+	kfree(phy->label);
+	kfree(phy);
+
+err0:
+	return ERR_PTR(ret);
+}
+EXPORT_SYMBOL_GPL(phy_create);
+
+/**
+ * devm_phy_create() - create a new phy
+ * @dev: device that is creating the new phy
+ * @id: id of the phy
+ * @ops: function pointers for performing phy operations
+ * @label: label given to the phy
+ *
+ * Creates a new PHY device adding it to the PHY class.
+ * While at that, it also associates the device with the phy using devres.
+ * On driver detach, release function is invoked on the devres data,
+ * then, devres data is freed.
+ */
+struct phy *devm_phy_create(struct device *dev, u8 id,
+	const struct phy_ops *ops, const char *label)
+{
+	struct phy **ptr, *phy;
+
+	ptr = devres_alloc(devm_phy_consume, sizeof(*ptr), GFP_KERNEL);
+	if (!ptr)
+		return ERR_PTR(-ENOMEM);
+
+	phy = phy_create(dev, id, ops, label);
+	if (!IS_ERR(phy)) {
+		*ptr = phy;
+		devres_add(dev, ptr);
+	} else {
+		devres_free(ptr);
+	}
+
+	return phy;
+}
+EXPORT_SYMBOL_GPL(devm_phy_create);
+
+/**
+ * phy_destroy() - destroy the phy
+ * @phy: the phy to be destroyed
+ *
+ * Called to destroy the phy.
+ */
+void phy_destroy(struct phy *phy)
+{
+	pm_runtime_disable(&phy->dev);
+	device_unregister(&phy->dev);
+}
+EXPORT_SYMBOL_GPL(phy_destroy);
+
+/**
+ * devm_phy_destroy() - destroy the PHY
+ * @dev: device that wants to release this phy
+ * @phy: the phy returned by devm_phy_get()
+ *
+ * destroys the devres associated with this phy and invokes phy_destroy
+ * to destroy the phy.
+ */
+void devm_phy_destroy(struct device *dev, struct phy *phy)
+{
+	int r;
+
+	r = devres_destroy(dev, devm_phy_consume, devm_phy_match, phy);
+	dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n");
+}
+EXPORT_SYMBOL_GPL(devm_phy_destroy);
+
+/**
+ * __of_phy_provider_register() - create/register phy provider with the framework
+ * @dev: struct device of the phy provider
+ * @owner: the module owner containing of_xlate
+ * @of_xlate: function pointer to obtain phy instance from phy provider
+ *
+ * Creates struct phy_provider from dev and of_xlate function pointer.
+ * This is used in the case of dt boot for finding the phy instance from
+ * phy provider.
+ */
+struct phy_provider *__of_phy_provider_register(struct device *dev,
+	struct module *owner, struct phy * (*of_xlate)(struct device *dev,
+	struct of_phandle_args *args))
+{
+	struct phy_provider *phy_provider;
+
+	phy_provider = kzalloc(sizeof(*phy_provider), GFP_KERNEL);
+	if (!phy_provider)
+		return ERR_PTR(-ENOMEM);
+
+	phy_provider->dev = dev;
+	phy_provider->owner = owner;
+	phy_provider->of_xlate = of_xlate;
+
+	mutex_lock(&phy_provider_mutex);
+	list_add_tail(&phy_provider->list, &phy_provider_list);
+	mutex_unlock(&phy_provider_mutex);
+
+	return phy_provider;
+}
+EXPORT_SYMBOL_GPL(__of_phy_provider_register);
+
+/**
+ * __devm_of_phy_provider_register() - create/register phy provider with the
+ * framework
+ * @dev: struct device of the phy provider
+ * @owner: the module owner containing of_xlate
+ * @of_xlate: function pointer to obtain phy instance from phy provider
+ *
+ * Creates struct phy_provider from dev and of_xlate function pointer.
+ * This is used in the case of dt boot for finding the phy instance from
+ * phy provider. While at that, it also associates the device with the
+ * phy provider using devres. On driver detach, release function is invoked
+ * on the devres data, then, devres data is freed.
+ */
+struct phy_provider *__devm_of_phy_provider_register(struct device *dev,
+	struct module *owner, struct phy * (*of_xlate)(struct device *dev,
+	struct of_phandle_args *args))
+{
+	struct phy_provider **ptr, *phy_provider;
+
+	ptr = devres_alloc(devm_phy_provider_release, sizeof(*ptr), GFP_KERNEL);
+	if (!ptr)
+		return ERR_PTR(-ENOMEM);
+
+	phy_provider = __of_phy_provider_register(dev, owner, of_xlate);
+	if (!IS_ERR(phy_provider)) {
+		*ptr = phy_provider;
+		devres_add(dev, ptr);
+	} else {
+		devres_free(ptr);
+	}
+
+	return phy_provider;
+}
+EXPORT_SYMBOL_GPL(__devm_of_phy_provider_register);
+
+/**
+ * of_phy_provider_unregister() - unregister phy provider from the framework
+ * @phy_provider: phy provider returned by of_phy_provider_register()
+ *
+ * Removes the phy_provider created using of_phy_provider_register().
+ */
+void of_phy_provider_unregister(struct phy_provider *phy_provider)
+{
+	if (IS_ERR(phy_provider))
+		return;
+
+	mutex_lock(&phy_provider_mutex);
+	list_del(&phy_provider->list);
+	kfree(phy_provider);
+	mutex_unlock(&phy_provider_mutex);
+}
+EXPORT_SYMBOL_GPL(of_phy_provider_unregister);
+
+/**
+ * devm_of_phy_provider_unregister() - remove phy provider from the framework
+ * @dev: struct device of the phy provider
+ *
+ * destroys the devres associated with this phy provider and invokes
+ * of_phy_provider_unregister to unregister the phy provider.
+ */
+void devm_of_phy_provider_unregister(struct device *dev,
+	struct phy_provider *phy_provider) {
+	int r;
+
+	r = devres_destroy(dev, devm_phy_provider_release, devm_phy_match,
+		phy_provider);
+	dev_WARN_ONCE(dev, r, "couldn't find PHY provider device resource\n");
+}
+EXPORT_SYMBOL_GPL(devm_of_phy_provider_unregister);
+
+/**
+ * phy_release() - release the phy
+ * @dev: the dev member within phy
+ *
+ * When the last reference to the device is removed, it is called
+ * from the embedded kobject as release method.
+ */
+static void phy_release(struct device *dev)
+{
+	struct phy *phy;
+
+	phy = to_phy(dev);
+	dev_vdbg(dev, "releasing '%s'\n", dev_name(dev));
+	kfree(phy->label);
+	kfree(phy);
+}
+
+static int __init phy_core_init(void)
+{
+	phy_class = class_create(THIS_MODULE, "phy");
+	if (IS_ERR(phy_class)) {
+		pr_err("failed to create phy class --> %ld\n",
+			PTR_ERR(phy_class));
+		return PTR_ERR(phy_class);
+	}
+
+	phy_class->dev_release = phy_release;
+
+	return 0;
+}
+module_init(phy_core_init);
+
+static void __exit phy_core_exit(void)
+{
+	class_destroy(phy_class);
+}
+module_exit(phy_core_exit);
+
+MODULE_DESCRIPTION("Generic PHY Framework");
+MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
new file mode 100644
index 0000000..9351a16
--- /dev/null
+++ b/include/linux/phy/phy.h
@@ -0,0 +1,344 @@
+/*
+ * phy.h -- generic phy header file
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.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.
+ *
+ * Author: Kishon Vijay Abraham I <kishon@ti.com>
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __DRIVERS_PHY_H
+#define __DRIVERS_PHY_H
+
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/device.h>
+#include <linux/pm_runtime.h>
+
+struct phy;
+
+/**
+ * struct phy_ops - set of function pointers for performing phy operations
+ * @init: operation to be performed for initializing phy
+ * @exit: operation to be performed while exiting
+ * @power_on: powering on the phy
+ * @power_off: powering off the phy
+ * @owner: the module owner containing the ops
+ */
+struct phy_ops {
+	int	(*init)(struct phy *phy);
+	int	(*exit)(struct phy *phy);
+	int	(*power_on)(struct phy *phy);
+	int	(*power_off)(struct phy *phy);
+	struct module *owner;
+};
+
+/**
+ * struct phy - represents the phy device
+ * @dev: phy device
+ * @id: id of the phy
+ * @ops: function pointers for performing phy operations
+ * @label: label given to the phy
+ * @mutex: mutex to protect phy_ops
+ * @init_count: used to protect when the PHY is used by multiple consumers
+ * @power_count: used to protect when the PHY is used by multiple consumers
+ */
+struct phy {
+	struct device		dev;
+	int			id;
+	const struct phy_ops	*ops;
+	const char		*label;
+	struct mutex		mutex;
+	int			init_count;
+	int			power_count;
+};
+
+/**
+ * struct phy_provider - represents the phy provider
+ * @dev: phy provider device
+ * @owner: the module owner having of_xlate
+ * @of_xlate: function pointer to obtain phy instance from phy pointer
+ * @list: to maintain a linked list of PHY providers
+ */
+struct phy_provider {
+	struct device		*dev;
+	struct module		*owner;
+	struct list_head	list;
+	struct phy * (*of_xlate)(struct device *dev,
+		struct of_phandle_args *args);
+};
+
+#define	to_phy(dev)	(container_of((dev), struct phy, dev))
+
+#define	of_phy_provider_register(dev, xlate)	\
+	__of_phy_provider_register((dev), THIS_MODULE, (xlate))
+
+#define	devm_of_phy_provider_register(dev, xlate)	\
+	__of_phy_provider_register((dev), THIS_MODULE, (xlate))
+
+static inline void phy_set_drvdata(struct phy *phy, void *data)
+{
+	dev_set_drvdata(&phy->dev, data);
+}
+
+static inline void *phy_get_drvdata(struct phy *phy)
+{
+	return dev_get_drvdata(&phy->dev);
+}
+
+#if IS_ENABLED(CONFIG_GENERIC_PHY)
+extern struct phy *phy_get(struct device *dev, const char *string);
+extern struct phy *devm_phy_get(struct device *dev, const char *string);
+extern void phy_put(struct phy *phy);
+extern void devm_phy_put(struct device *dev, struct phy *phy);
+extern struct phy *of_phy_simple_xlate(struct device *dev,
+	struct of_phandle_args *args);
+extern struct phy *phy_create(struct device *dev, u8 id,
+	const struct phy_ops *ops, const char *label);
+extern struct phy *devm_phy_create(struct device *dev, u8 id,
+	const struct phy_ops *ops, const char *label);
+extern void phy_destroy(struct phy *phy);
+extern void devm_phy_destroy(struct device *dev, struct phy *phy);
+extern struct phy_provider *__of_phy_provider_register(struct device *dev,
+	struct module *owner, struct phy * (*of_xlate)(struct device *dev,
+	struct of_phandle_args *args));
+extern struct phy_provider *__devm_of_phy_provider_register(struct device *dev,
+	struct module *owner, struct phy * (*of_xlate)(struct device *dev,
+	struct of_phandle_args *args));
+extern void of_phy_provider_unregister(struct phy_provider *phy_provider);
+extern void devm_of_phy_provider_unregister(struct device *dev,
+	struct phy_provider *phy_provider);
+#else
+static inline struct phy *phy_get(struct device *dev, const char *string)
+{
+	return ERR_PTR(-ENOSYS);
+}
+
+static inline struct phy *devm_phy_get(struct device *dev, const char *string)
+{
+	return ERR_PTR(-ENOSYS);
+}
+
+static inline void phy_put(struct phy *phy)
+{
+}
+
+static inline void devm_phy_put(struct device *dev, struct phy *phy)
+{
+}
+
+static inline struct phy *of_phy_simple_xlate(struct device *dev,
+	struct of_phandle_args *args)
+{
+	return ERR_PTR(-ENOSYS);
+}
+
+static inline struct phy *phy_create(struct device *dev, u8 id,
+	const struct phy_ops *ops, const char *label)
+{
+	return ERR_PTR(-ENOSYS);
+}
+
+static inline struct phy *devm_phy_create(struct device *dev, u8 id,
+	const struct phy_ops *ops, const char *label)
+{
+	return ERR_PTR(-ENOSYS);
+}
+
+static inline void phy_destroy(struct phy *phy)
+{
+}
+
+static inline void devm_phy_destroy(struct device *dev, struct phy *phy)
+{
+}
+
+static inline struct phy_provider *__of_phy_provider_register(
+	struct device *dev, struct module *owner, struct phy * (*of_xlate)(
+	struct device *dev, struct of_phandle_args *args))
+{
+	return ERR_PTR(-ENOSYS);
+}
+
+static inline struct phy_provider *__devm_of_phy_provider_register(struct device
+	*dev, struct module *owner, struct phy * (*of_xlate)(struct device *dev,
+	struct of_phandle_args *args))
+{
+	return ERR_PTR(-ENOSYS);
+}
+
+static inline void of_phy_provider_unregister(struct phy_provider *phy_provider)
+{
+}
+
+static inline void devm_of_phy_provider_unregister(struct device *dev,
+	struct phy_provider *phy_provider)
+{
+}
+#endif
+
+static inline int phy_pm_runtime_get(struct phy *phy)
+{
+	if (WARN(IS_ERR(phy), "Invalid PHY reference\n"))
+		return -EINVAL;
+
+	if (!pm_runtime_enabled(&phy->dev))
+		return -ENOTSUPP;
+
+	return pm_runtime_get(&phy->dev);
+}
+
+static inline int phy_pm_runtime_get_sync(struct phy *phy)
+{
+	if (WARN(IS_ERR(phy), "Invalid PHY reference\n"))
+		return -EINVAL;
+
+	if (!pm_runtime_enabled(&phy->dev))
+		return -ENOTSUPP;
+
+	return pm_runtime_get_sync(&phy->dev);
+}
+
+static inline int phy_pm_runtime_put(struct phy *phy)
+{
+	if (WARN(IS_ERR(phy), "Invalid PHY reference\n"))
+		return -EINVAL;
+
+	if (!pm_runtime_enabled(&phy->dev))
+		return -ENOTSUPP;
+
+	return pm_runtime_put(&phy->dev);
+}
+
+static inline int phy_pm_runtime_put_sync(struct phy *phy)
+{
+	if (WARN(IS_ERR(phy), "Invalid PHY reference\n"))
+		return -EINVAL;
+
+	if (!pm_runtime_enabled(&phy->dev))
+		return -ENOTSUPP;
+
+	return pm_runtime_put_sync(&phy->dev);
+}
+
+static inline void phy_pm_runtime_allow(struct phy *phy)
+{
+	if (WARN(IS_ERR(phy), "Invalid PHY reference\n"))
+		return;
+
+	if (!pm_runtime_enabled(&phy->dev))
+		return;
+
+	pm_runtime_allow(&phy->dev);
+}
+
+static inline void phy_pm_runtime_forbid(struct phy *phy)
+{
+	if (WARN(IS_ERR(phy), "Invalid PHY reference\n"))
+		return;
+
+	if (!pm_runtime_enabled(&phy->dev))
+		return;
+
+	pm_runtime_forbid(&phy->dev);
+}
+
+static inline int phy_init(struct phy *phy)
+{
+	int ret;
+
+	ret = phy_pm_runtime_get_sync(phy);
+	if (ret < 0 && ret != -ENOTSUPP)
+		return ret;
+
+	mutex_lock(&phy->mutex);
+	if (phy->init_count++ = 0 && phy->ops->init) {
+		ret = phy->ops->init(phy);
+		if (ret < 0) {
+			dev_err(&phy->dev, "phy init failed --> %d\n", ret);
+			goto out;
+		}
+	}
+
+out:
+	mutex_unlock(&phy->mutex);
+	phy_pm_runtime_put(phy);
+	return ret;
+}
+
+static inline int phy_exit(struct phy *phy)
+{
+	int ret;
+
+	ret = phy_pm_runtime_get_sync(phy);
+	if (ret < 0 && ret != -ENOTSUPP)
+		return ret;
+
+	mutex_lock(&phy->mutex);
+	if (--phy->init_count = 0 && phy->ops->exit) {
+		ret = phy->ops->exit(phy);
+		if (ret < 0) {
+			dev_err(&phy->dev, "phy exit failed --> %d\n", ret);
+			goto out;
+		}
+	}
+
+out:
+	mutex_unlock(&phy->mutex);
+	phy_pm_runtime_put(phy);
+	return ret;
+}
+
+static inline int phy_power_on(struct phy *phy)
+{
+	int ret = -ENOTSUPP;
+
+	ret = phy_pm_runtime_get_sync(phy);
+	if (ret < 0 && ret != -ENOTSUPP)
+		return ret;
+
+	mutex_lock(&phy->mutex);
+	if (phy->power_count++ = 0 && phy->ops->power_on) {
+		ret = phy->ops->power_on(phy);
+		if (ret < 0) {
+			dev_err(&phy->dev, "phy poweron failed --> %d\n", ret);
+			goto out;
+		}
+	}
+
+out:
+	mutex_unlock(&phy->mutex);
+
+	return ret;
+}
+
+static inline int phy_power_off(struct phy *phy)
+{
+	int ret = -ENOTSUPP;
+
+	mutex_lock(&phy->mutex);
+	if (--phy->power_count = 0 && phy->ops->power_off) {
+		ret =  phy->ops->power_off(phy);
+		if (ret < 0) {
+			dev_err(&phy->dev, "phy poweroff failed --> %d\n", ret);
+			goto out;
+		}
+	}
+
+out:
+	mutex_unlock(&phy->mutex);
+	phy_pm_runtime_put(phy);
+
+	return ret;
+}
+
+#endif /* __DRIVERS_PHY_H */
-- 
1.7.10.4

[PATCH 03/15] usb: phy: twl4030: use the new generic PHY framework

Message details and related content
Used the generic PHY framework API to create the PHY. For powering on
and powering off the PHY, power_on and power_off ops are used. Once the
MUSB OMAP glue is adapted to the new framework, the suspend and resume
ops of usb phy library will be removed.

However using the old usb phy library cannot be completely removed
because otg is intertwined with phy and moving to the new
framework completely will break otg. Once we have a separate otg state machine,
we can get rid of the usb phy library.

Signed-off-by: Kishon Vijay Abraham I <redacted>
Acked-by: Felipe Balbi <redacted>
Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 drivers/usb/phy/phy-twl4030-usb.c |   50 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 49 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/phy/phy-twl4030-usb.c b/drivers/usb/phy/phy-twl4030-usb.c
index 8f78d2d..9051756 100644
--- a/drivers/usb/phy/phy-twl4030-usb.c
+++ b/drivers/usb/phy/phy-twl4030-usb.c
@@ -33,6 +33,7 @@
 #include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/usb/otg.h>
+#include <linux/phy/phy.h>
 #include <linux/usb/musb-omap.h>
 #include <linux/usb/ulpi.h>
 #include <linux/i2c/twl.h>
@@ -431,6 +432,14 @@ static void twl4030_phy_suspend(struct twl4030_usb *twl, int controller_off)
 	dev_dbg(twl->dev, "%s\n", __func__);
 }
 
+static int twl4030_phy_power_off(struct phy *phy)
+{
+	struct twl4030_usb *twl = phy_get_drvdata(phy);
+
+	twl4030_phy_suspend(twl, 0);
+	return 0;
+}
+
 static void __twl4030_phy_resume(struct twl4030_usb *twl)
 {
 	twl4030_phy_power(twl, 1);
@@ -459,6 +468,14 @@ static void twl4030_phy_resume(struct twl4030_usb *twl)
 	}
 }
 
+static int twl4030_phy_power_on(struct phy *phy)
+{
+	struct twl4030_usb *twl = phy_get_drvdata(phy);
+
+	twl4030_phy_resume(twl);
+	return 0;
+}
+
 static int twl4030_usb_ldo_init(struct twl4030_usb *twl)
 {
 	/* Enable writing to power configuration registers */
@@ -602,13 +619,22 @@ static int twl4030_usb_phy_init(struct usb_phy *phy)
 	status = twl4030_usb_linkstat(twl);
 	twl->linkstat = status;
 
-	if (status = OMAP_MUSB_ID_GROUND || status = OMAP_MUSB_VBUS_VALID)
+	if (status = OMAP_MUSB_ID_GROUND || status = OMAP_MUSB_VBUS_VALID) {
 		omap_musb_mailbox(twl->linkstat);
+		twl4030_phy_resume(twl);
+	}
 
 	sysfs_notify(&twl->dev->kobj, NULL, "vbus");
 	return 0;
 }
 
+static int twl4030_phy_init(struct phy *phy)
+{
+	struct twl4030_usb *twl = phy_get_drvdata(phy);
+
+	return twl4030_usb_phy_init(&twl->phy);
+}
+
 static int twl4030_set_suspend(struct usb_phy *x, int suspend)
 {
 	struct twl4030_usb *twl = phy_to_twl(x);
@@ -646,13 +672,22 @@ static int twl4030_set_host(struct usb_otg *otg, struct usb_bus *host)
 	return 0;
 }
 
+static const struct phy_ops ops = {
+	.init		= twl4030_phy_init,
+	.power_on	= twl4030_phy_power_on,
+	.power_off	= twl4030_phy_power_off,
+	.owner		= THIS_MODULE,
+};
+
 static int twl4030_usb_probe(struct platform_device *pdev)
 {
 	struct twl4030_usb_data *pdata = pdev->dev.platform_data;
 	struct twl4030_usb	*twl;
+	struct phy		*phy;
 	int			status, err;
 	struct usb_otg		*otg;
 	struct device_node	*np = pdev->dev.of_node;
+	struct phy_provider	*phy_provider;
 
 	twl = devm_kzalloc(&pdev->dev, sizeof *twl, GFP_KERNEL);
 	if (!twl)
@@ -689,6 +724,19 @@ static int twl4030_usb_probe(struct platform_device *pdev)
 	otg->set_host		= twl4030_set_host;
 	otg->set_peripheral	= twl4030_set_peripheral;
 
+	phy_provider = devm_of_phy_provider_register(twl->dev,
+		of_phy_simple_xlate);
+	if (IS_ERR(phy_provider))
+		return PTR_ERR(phy_provider);
+
+	phy = devm_phy_create(twl->dev, 0, &ops, "twl4030");
+	if (IS_ERR(phy)) {
+		dev_dbg(&pdev->dev, "Failed to create PHY\n");
+		return PTR_ERR(phy);
+	}
+
+	phy_set_drvdata(phy, twl);
+
 	/* init spinlock for workqueue */
 	spin_lock_init(&twl->lock);
 
-- 
1.7.10.4

[PATCH 04/15] ARM: OMAP: USB: Add phy binding information

Message details and related content
In order for controllers to get PHY in case of non dt boot, the phy
binding information (phy device name) should be added in the platform
data of the controller.

Signed-off-by: Kishon Vijay Abraham I <redacted>
Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Acked-by: Felipe Balbi <redacted>
---
 arch/arm/mach-omap2/usb-musb.c |    3 +++
 include/linux/usb/musb.h       |    3 +++
 2 files changed, 6 insertions(+)
diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c
index 8c4de27..6aa7cbf 100644
--- a/arch/arm/mach-omap2/usb-musb.c
+++ b/arch/arm/mach-omap2/usb-musb.c
@@ -85,6 +85,9 @@ void __init usb_musb_init(struct omap_musb_board_data *musb_board_data)
 	musb_plat.mode = board_data->mode;
 	musb_plat.extvbus = board_data->extvbus;
 
+	if (cpu_is_omap34xx())
+		musb_plat.phy_label = "twl4030";
+
 	if (soc_is_am35xx()) {
 		oh_name = "am35x_otg_hs";
 		name = "musb-am35x";
diff --git a/include/linux/usb/musb.h b/include/linux/usb/musb.h
index 053c268..596f8c8 100644
--- a/include/linux/usb/musb.h
+++ b/include/linux/usb/musb.h
@@ -104,6 +104,9 @@ struct musb_hdrc_platform_data {
 	/* for clk_get() */
 	const char	*clock;
 
+	/* phy label */
+	const char	*phy_label;
+
 	/* (HOST or OTG) switch VBUS on/off */
 	int		(*set_vbus)(struct device *dev, int is_on);
 
-- 
1.7.10.4

[PATCH 05/15] ARM: dts: omap: update usb_otg_hs data

Message details and related content
Updated the usb_otg_hs dt data to include the *phy* and *phy-names*
binding in order for the driver to use the new generic PHY framework.
Also updated the Documentation to include the binding information.
The PHY binding information can be found at
Documentation/devicetree/bindings/phy/phy-bindings.txt

Signed-off-by: Kishon Vijay Abraham I <redacted>
Acked-by: Felipe Balbi <redacted>
Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 Documentation/devicetree/bindings/usb/omap-usb.txt |    5 +++++
 Documentation/devicetree/bindings/usb/usb-phy.txt  |    6 ++++++
 arch/arm/boot/dts/omap3-beagle-xm.dts              |    2 ++
 arch/arm/boot/dts/omap3-evm.dts                    |    2 ++
 arch/arm/boot/dts/omap3-overo.dtsi                 |    2 ++
 arch/arm/boot/dts/omap4.dtsi                       |    3 +++
 arch/arm/boot/dts/twl4030.dtsi                     |    1 +
 7 files changed, 21 insertions(+)
diff --git a/Documentation/devicetree/bindings/usb/omap-usb.txt b/Documentation/devicetree/bindings/usb/omap-usb.txt
index 57e71f6..825790d 100644
--- a/Documentation/devicetree/bindings/usb/omap-usb.txt
+++ b/Documentation/devicetree/bindings/usb/omap-usb.txt
@@ -19,6 +19,9 @@ OMAP MUSB GLUE
  - power : Should be "50". This signifies the controller can supply up to
    100mA when operating in host mode.
  - usb-phy : the phandle for the PHY device
+ - phys : the phandle for the PHY device (used by generic PHY framework)
+ - phy-names : the names of the PHY corresponding to the PHYs present in the
+   *phy* phandle.
 
 Optional properties:
  - ctrl-module : phandle of the control module this glue uses to write to
@@ -33,6 +36,8 @@ usb_otg_hs: usb_otg_hs@4a0ab000 {
 	num-eps = <16>;
 	ram-bits = <12>;
 	ctrl-module = <&omap_control_usb>;
+	phys = <&usb2_phy>;
+	phy-names = "usb2-phy";
 };
 
 Board specific device node entry
diff --git a/Documentation/devicetree/bindings/usb/usb-phy.txt b/Documentation/devicetree/bindings/usb/usb-phy.txt
index 61496f5..c0245c8 100644
--- a/Documentation/devicetree/bindings/usb/usb-phy.txt
+++ b/Documentation/devicetree/bindings/usb/usb-phy.txt
@@ -5,6 +5,8 @@ OMAP USB2 PHY
 Required properties:
  - compatible: Should be "ti,omap-usb2"
  - reg : Address and length of the register set for the device.
+ - #phy-cells: determine the number of cells that should be given in the
+   phandle while referencing this phy.
 
 Optional properties:
  - ctrl-module : phandle of the control module used by PHY driver to power on
@@ -16,6 +18,7 @@ usb2phy@4a0ad080 {
 	compatible = "ti,omap-usb2";
 	reg = <0x4a0ad080 0x58>;
 	ctrl-module = <&omap_control_usb>;
+	#phy-cells = <0>;
 };
 
 OMAP USB3 PHY
@@ -25,6 +28,8 @@ Required properties:
  - reg : Address and length of the register set for the device.
  - reg-names: The names of the register addresses corresponding to the registers
    filled in "reg".
+ - #phy-cells: determine the number of cells that should be given in the
+   phandle while referencing this phy.
 
 Optional properties:
  - ctrl-module : phandle of the control module used by PHY driver to power on
@@ -39,4 +44,5 @@ usb3phy@4a084400 {
 	      <0x4a084c00 0x40>;
 	reg-names = "phy_rx", "phy_tx", "pll_ctrl";
 	ctrl-module = <&omap_control_usb>;
+	#phy-cells = <0>;
 };
diff --git a/arch/arm/boot/dts/omap3-beagle-xm.dts b/arch/arm/boot/dts/omap3-beagle-xm.dts
index afdb164..533b2da 100644
--- a/arch/arm/boot/dts/omap3-beagle-xm.dts
+++ b/arch/arm/boot/dts/omap3-beagle-xm.dts
@@ -144,6 +144,8 @@
 &usb_otg_hs {
 	interface-type = <0>;
 	usb-phy = <&usb2_phy>;
+	phys = <&usb2_phy>;
+	phy-names = "usb2-phy";
 	mode = <3>;
 	power = <50>;
 };
diff --git a/arch/arm/boot/dts/omap3-evm.dts b/arch/arm/boot/dts/omap3-evm.dts
index 7d4329d..4134dd0 100644
--- a/arch/arm/boot/dts/omap3-evm.dts
+++ b/arch/arm/boot/dts/omap3-evm.dts
@@ -70,6 +70,8 @@
 &usb_otg_hs {
 	interface-type = <0>;
 	usb-phy = <&usb2_phy>;
+	phys = <&usb2_phy>;
+	phy-names = "usb2-phy";
 	mode = <3>;
 	power = <50>;
 };
diff --git a/arch/arm/boot/dts/omap3-overo.dtsi b/arch/arm/boot/dts/omap3-overo.dtsi
index 8f1abec..a461d2f 100644
--- a/arch/arm/boot/dts/omap3-overo.dtsi
+++ b/arch/arm/boot/dts/omap3-overo.dtsi
@@ -76,6 +76,8 @@
 &usb_otg_hs {
 	interface-type = <0>;
 	usb-phy = <&usb2_phy>;
+	phys = <&usb2_phy>;
+	phy-names = "usb2-phy";
 	mode = <3>;
 	power = <50>;
 };
diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi
index 22d9f2b..1e8e2fe 100644
--- a/arch/arm/boot/dts/omap4.dtsi
+++ b/arch/arm/boot/dts/omap4.dtsi
@@ -520,6 +520,7 @@
 				compatible = "ti,omap-usb2";
 				reg = <0x4a0ad080 0x58>;
 				ctrl-module = <&omap_control_usb>;
+				#phy-cells = <0>;
 			};
 		};
 
@@ -658,6 +659,8 @@
 			interrupt-names = "mc", "dma";
 			ti,hwmods = "usb_otg_hs";
 			usb-phy = <&usb2_phy>;
+			phys = <&usb2_phy>;
+			phy-names = "usb2-phy";
 			multipoint = <1>;
 			num-eps = <16>;
 			ram-bits = <12>;
diff --git a/arch/arm/boot/dts/twl4030.dtsi b/arch/arm/boot/dts/twl4030.dtsi
index b3034da..ce4cd6f 100644
--- a/arch/arm/boot/dts/twl4030.dtsi
+++ b/arch/arm/boot/dts/twl4030.dtsi
@@ -80,6 +80,7 @@
 		usb1v8-supply = <&vusb1v8>;
 		usb3v1-supply = <&vusb3v1>;
 		usb_mode = <1>;
+		#phy-cells = <0>;
 	};
 
 	twl_pwm: pwm {
-- 
1.7.10.4

[PATCH 06/15] usb: musb: omap2430: use the new generic PHY framework

Message details and related content
Use the generic PHY framework API to get the PHY. The usb_phy_set_resume
and usb_phy_set_suspend is replaced with power_on and
power_off to align with the new PHY framework.

musb->xceiv can't be removed as of now because musb core uses xceiv.state and
xceiv.otg. Once there is a separate state machine to handle otg, these can be
moved out of xceiv and then we can start using the generic PHY framework.

Signed-off-by: Kishon Vijay Abraham I <redacted>
Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Acked-by: Felipe Balbi <redacted>
---
 drivers/usb/musb/Kconfig     |    1 +
 drivers/usb/musb/musb_core.c |    1 +
 drivers/usb/musb/musb_core.h |    3 +++
 drivers/usb/musb/omap2430.c  |   26 ++++++++++++++++++++------
 4 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
index 797e3fd..01381ac 100644
--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -76,6 +76,7 @@ config USB_MUSB_TUSB6010
 config USB_MUSB_OMAP2PLUS
 	tristate "OMAP2430 and onwards"
 	depends on ARCH_OMAP2PLUS
+	depends on GENERIC_PHY
 
 config USB_MUSB_AM35X
 	tristate "AM35x"
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 29a24ce..cca12c0 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -1814,6 +1814,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
 	musb->min_power = plat->min_power;
 	musb->ops = plat->platform_ops;
 	musb->port_mode = plat->mode;
+	musb->phy_label = plat->phy_label;
 
 	/* The musb_platform_init() call:
 	 *   - adjusts musb->mregs
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index 7d341c3..8f017ab 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -46,6 +46,7 @@
 #include <linux/usb.h>
 #include <linux/usb/otg.h>
 #include <linux/usb/musb.h>
+#include <linux/phy/phy.h>
 
 struct musb;
 struct musb_hw_ep;
@@ -346,6 +347,7 @@ struct musb {
 	u16			int_tx;
 
 	struct usb_phy		*xceiv;
+	struct phy		*phy;
 
 	int nIrq;
 	unsigned		irq_wake:1;
@@ -424,6 +426,7 @@ struct musb {
 	unsigned                double_buffer_not_ok:1;
 
 	struct musb_hdrc_config	*config;
+	const char		*phy_label;
 
 #ifdef MUSB_CONFIG_PROC_FS
 	struct proc_dir_entry *proc_entry;
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
index 6708a3b..87dac0f 100644
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -348,11 +348,21 @@ static int omap2430_musb_init(struct musb *musb)
 	 * up through ULPI.  TWL4030-family PMICs include one,
 	 * which needs a driver, drivers aren't always needed.
 	 */
-	if (dev->parent->of_node)
+	if (dev->parent->of_node) {
+		musb->phy = devm_phy_get(dev->parent, "usb2-phy");
+
+		/* We can't totally remove musb->xceiv as of now because
+		 * musb core uses xceiv.state and xceiv.otg. Once we have
+		 * a separate state machine to handle otg, these can be moved
+		 * out of xceiv and then we can start using the generic PHY
+		 * framework
+		 */
 		musb->xceiv = devm_usb_get_phy_by_phandle(dev->parent,
 		    "usb-phy", 0);
-	else
+	} else {
 		musb->xceiv = devm_usb_get_phy_dev(dev, 0);
+		musb->phy = devm_phy_get(dev, musb->phy_label);
+	}
 
 	if (IS_ERR(musb->xceiv)) {
 		status = PTR_ERR(musb->xceiv);
@@ -364,6 +374,10 @@ static int omap2430_musb_init(struct musb *musb)
 		return -EPROBE_DEFER;
 	}
 
+	if (IS_ERR(musb->phy)) {
+		pr_err("HS USB OTG: no PHY configured\n");
+		return PTR_ERR(musb->phy);
+	}
 	musb->isr = omap2430_musb_interrupt;
 
 	status = pm_runtime_get_sync(dev);
@@ -397,7 +411,7 @@ static int omap2430_musb_init(struct musb *musb)
 	if (glue->status != OMAP_MUSB_UNKNOWN)
 		omap_musb_set_mailbox(glue);
 
-	usb_phy_init(musb->xceiv);
+	phy_init(musb->phy);
 
 	pm_runtime_put_noidle(musb->controller);
 	return 0;
@@ -460,6 +474,7 @@ static int omap2430_musb_exit(struct musb *musb)
 	del_timer_sync(&musb_idle_timer);
 
 	omap2430_low_level_exit(musb);
+	phy_exit(musb->phy);
 
 	return 0;
 }
@@ -633,7 +648,7 @@ static int omap2430_runtime_suspend(struct device *dev)
 				OTG_INTERFSEL);
 
 		omap2430_low_level_exit(musb);
-		usb_phy_set_suspend(musb->xceiv, 1);
+		phy_power_off(musb->phy);
 	}
 
 	return 0;
@@ -648,8 +663,7 @@ static int omap2430_runtime_resume(struct device *dev)
 		omap2430_low_level_init(musb);
 		musb_writel(musb->mregs, OTG_INTERFSEL,
 				musb->context.otg_interfsel);
-
-		usb_phy_set_suspend(musb->xceiv, 0);
+		phy_power_on(musb->phy);
 	}
 
 	return 0;
-- 
1.7.10.4

[PATCH 07/15] usb: phy: omap-usb2: remove *set_suspend* callback from omap-usb2

Message details and related content
Now that omap-usb2 is adapted to the new generic PHY framework,
*set_suspend* ops can be removed from omap-usb2 driver.

Signed-off-by: Kishon Vijay Abraham I <redacted>
Acked-by: Felipe Balbi <redacted>
Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 drivers/usb/phy/phy-omap-usb2.c |   25 -------------------------
 1 file changed, 25 deletions(-)
diff --git a/drivers/usb/phy/phy-omap-usb2.c b/drivers/usb/phy/phy-omap-usb2.c
index 751b30f..3f2b125 100644
--- a/drivers/usb/phy/phy-omap-usb2.c
+++ b/drivers/usb/phy/phy-omap-usb2.c
@@ -97,29 +97,6 @@ static int omap_usb_set_peripheral(struct usb_otg *otg,
 	return 0;
 }
 
-static int omap_usb2_suspend(struct usb_phy *x, int suspend)
-{
-	u32 ret;
-	struct omap_usb *phy = phy_to_omapusb(x);
-
-	if (suspend && !phy->is_suspended) {
-		omap_control_usb_phy_power(phy->control_dev, 0);
-		pm_runtime_put_sync(phy->dev);
-		phy->is_suspended = 1;
-	} else if (!suspend && phy->is_suspended) {
-		ret = pm_runtime_get_sync(phy->dev);
-		if (ret < 0) {
-			dev_err(phy->dev, "get_sync failed with err %d\n",
-									ret);
-			return ret;
-		}
-		omap_control_usb_phy_power(phy->control_dev, 1);
-		phy->is_suspended = 0;
-	}
-
-	return 0;
-}
-
 static int omap_usb_power_off(struct phy *x)
 {
 	struct omap_usb *phy = phy_get_drvdata(x);
@@ -167,7 +144,6 @@ static int omap_usb2_probe(struct platform_device *pdev)
 
 	phy->phy.dev		= phy->dev;
 	phy->phy.label		= "omap-usb2";
-	phy->phy.set_suspend	= omap_usb2_suspend;
 	phy->phy.otg		= otg;
 	phy->phy.type		= USB_PHY_TYPE_USB2;
 
@@ -182,7 +158,6 @@ static int omap_usb2_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	phy->is_suspended	= 1;
 	omap_control_usb_phy_power(phy->control_dev, 0);
 
 	otg->set_host		= omap_usb_set_host;
-- 
1.7.10.4

[PATCH 09/15] phy: Add driver for Exynos MIPI CSIS/DSIM DPHYs

Message details and related content
From: Sylwester Nawrocki <s.nawrocki@samsung.com>

Add a PHY provider driver for the Samsung S5P/Exynos SoC MIPI CSI-2
receiver and MIPI DSI transmitter DPHYs.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Acked-by: Felipe Balbi <redacted>
Signed-off-by: Kishon Vijay Abraham I <redacted>
---
 .../devicetree/bindings/phy/samsung-phy.txt        |   14 ++
 drivers/phy/Kconfig                                |    9 ++
 drivers/phy/Makefile                               |    3 +-
 drivers/phy/phy-exynos-mipi-video.c                |  169 ++++++++++++++++++++
 4 files changed, 194 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/phy/samsung-phy.txt
 create mode 100644 drivers/phy/phy-exynos-mipi-video.c
diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt
new file mode 100644
index 0000000..5ff208c
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt
@@ -0,0 +1,14 @@
+Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY
+-------------------------------------------------
+
+Required properties:
+- compatible : should be "samsung,s5pv210-mipi-video-phy";
+- reg : offset and length of the MIPI DPHY register set;
+- #phy-cells : from the generic phy bindings, must be 1;
+
+For "samsung,s5pv210-mipi-video-phy" compatible PHYs the second cell in
+the PHY specifier identifies the PHY and its meaning is as follows:
+  0 - MIPI CSIS 0,
+  1 - MIPI DSIM 0,
+  2 - MIPI CSIS 1,
+  3 - MIPI DSIM 1.
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 5f85909..6f446d0 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -11,3 +11,12 @@ menuconfig GENERIC_PHY
 	  devices present in the kernel. This layer will have the generic
 	  API by which phy drivers can create PHY using the phy framework and
 	  phy users can obtain reference to the PHY.
+
+if GENERIC_PHY
+
+config PHY_EXYNOS_MIPI_VIDEO
+	tristate "S5P/EXYNOS SoC series MIPI CSI-2/DSI PHY driver"
+	help
+	  Support for MIPI CSI-2 and MIPI DSI DPHY found on Samsung
+	  S5P and EXYNOS SoCs.
+endif
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 9e9560f..71d8841 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -2,4 +2,5 @@
 # Makefile for the phy drivers.
 #
 
-obj-$(CONFIG_GENERIC_PHY)	+= phy-core.o
+obj-$(CONFIG_GENERIC_PHY)		+= phy-core.o
+obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO)	+= phy-exynos-mipi-video.o
diff --git a/drivers/phy/phy-exynos-mipi-video.c b/drivers/phy/phy-exynos-mipi-video.c
new file mode 100644
index 0000000..7e7fcd7
--- /dev/null
+++ b/drivers/phy/phy-exynos-mipi-video.c
@@ -0,0 +1,169 @@
+/*
+ * Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY driver
+ *
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.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/io.h>
+#include <linux/kernel.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>
+
+/* MIPI_PHYn_CONTROL register offset: n = 0..1 */
+#define EXYNOS_MIPI_PHY_CONTROL(n)	((n) * 4)
+#define EXYNOS_MIPI_PHY_ENABLE		(1 << 0)
+#define EXYNOS_MIPI_PHY_SRESETN		(1 << 1)
+#define EXYNOS_MIPI_PHY_MRESETN		(1 << 2)
+#define EXYNOS_MIPI_PHY_RESET_MASK	(3 << 1)
+
+enum exynos_mipi_phy_id {
+	EXYNOS_MIPI_PHY_ID_CSIS0,
+	EXYNOS_MIPI_PHY_ID_DSIM0,
+	EXYNOS_MIPI_PHY_ID_CSIS1,
+	EXYNOS_MIPI_PHY_ID_DSIM1,
+	EXYNOS_MIPI_PHYS_NUM
+};
+
+#define IS_EXYNOS_MIPI_DSIM_PHY_ID(id) \
+	((id) = EXYNOS_MIPI_PHY_ID_DSIM0 || (id) = EXYNOS_MIPI_PHY_ID_DSIM0)
+
+struct exynos_mipi_video_phy {
+	spinlock_t slock;
+	struct phy *phys[EXYNOS_MIPI_PHYS_NUM];
+	void __iomem *regs;
+};
+
+static int __set_phy_state(struct exynos_mipi_video_phy *state,
+			enum exynos_mipi_phy_id id, unsigned int on)
+{
+	void __iomem *addr;
+	u32 reg, reset;
+
+	addr = state->regs + EXYNOS_MIPI_PHY_CONTROL(id / 2);
+
+	if (IS_EXYNOS_MIPI_DSIM_PHY_ID(id))
+		reset = EXYNOS_MIPI_PHY_MRESETN;
+	else
+		reset = EXYNOS_MIPI_PHY_SRESETN;
+
+	spin_lock(&state->slock);
+	reg = readl(addr);
+	if (on)
+		reg |= reset;
+	else
+		reg &= ~reset;
+	writel(reg, addr);
+
+	/* Clear ENABLE bit only if MRESETN, SRESETN bits are not set. */
+	if (on)
+		reg |= EXYNOS_MIPI_PHY_ENABLE;
+	else if (!(reg & EXYNOS_MIPI_PHY_RESET_MASK))
+		reg &= ~EXYNOS_MIPI_PHY_ENABLE;
+
+	writel(reg, addr);
+	spin_unlock(&state->slock);
+	return 0;
+}
+
+static int exynos_mipi_video_phy_power_on(struct phy *phy)
+{
+	struct exynos_mipi_video_phy *state = phy_get_drvdata(phy);
+	return __set_phy_state(state, phy->id, 1);
+}
+
+static int exynos_mipi_video_phy_power_off(struct phy *phy)
+{
+	struct exynos_mipi_video_phy *state = phy_get_drvdata(phy);
+	return __set_phy_state(state, phy->id, 0);
+}
+
+static struct phy *exynos_mipi_video_phy_xlate(struct device *dev,
+					struct of_phandle_args *args)
+{
+	struct exynos_mipi_video_phy *state = dev_get_drvdata(dev);
+
+	if (WARN_ON(args->args[0] > EXYNOS_MIPI_PHYS_NUM))
+		return ERR_PTR(-ENODEV);
+
+	return state->phys[args->args[0]];
+}
+
+static struct phy_ops exynos_mipi_video_phy_ops = {
+	.power_on	= exynos_mipi_video_phy_power_on,
+	.power_off	= exynos_mipi_video_phy_power_off,
+	.owner		= THIS_MODULE,
+};
+
+static int exynos_mipi_video_phy_probe(struct platform_device *pdev)
+{
+	struct exynos_mipi_video_phy *state;
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	struct phy_provider *phy_provider;
+	int i;
+
+	state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL);
+	if (!state)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	state->regs = devm_ioremap_resource(dev, res);
+	if (IS_ERR(state->regs))
+		return PTR_ERR(state->regs);
+
+	dev_set_drvdata(dev, state);
+	spin_lock_init(&state->slock);
+
+	phy_provider = devm_of_phy_provider_register(dev,
+					exynos_mipi_video_phy_xlate);
+	if (IS_ERR(phy_provider))
+		return PTR_ERR(phy_provider);
+
+	for (i = 0; i < EXYNOS_MIPI_PHYS_NUM; i++) {
+		char label[8];
+
+		snprintf(label, sizeof(label), "%s.%d",
+				IS_EXYNOS_MIPI_DSIM_PHY_ID(i) ?
+				"dsim" : "csis", i / 2);
+
+		state->phys[i] = devm_phy_create(dev, i,
+				&exynos_mipi_video_phy_ops, label);
+		if (IS_ERR(state->phys[i])) {
+			dev_err(dev, "failed to create PHY %s\n", label);
+			return PTR_ERR(state->phys[i]);
+		}
+		phy_set_drvdata(state->phys[i], state);
+	}
+
+	return 0;
+}
+
+static const struct of_device_id exynos_mipi_video_phy_of_match[] = {
+	{ .compatible = "samsung,s5pv210-mipi-video-phy" },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, exynos_mipi_video_phy_of_match);
+
+static struct platform_driver exynos_mipi_video_phy_driver = {
+	.probe	= exynos_mipi_video_phy_probe,
+	.driver = {
+		.of_match_table	= exynos_mipi_video_phy_of_match,
+		.name  = "exynos-mipi-video-phy",
+		.owner = THIS_MODULE,
+	}
+};
+module_platform_driver(exynos_mipi_video_phy_driver);
+
+MODULE_DESCRIPTION("Samsung S5P/EXYNOS SoC MIPI CSI-2/DSI PHY driver");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
-- 
1.7.10.4

[PATCH 10/15] video: exynos_mipi_dsim: Use the generic PHY driver

Message details and related content
From: Sylwester Nawrocki <s.nawrocki@samsung.com>

Use the generic PHY API instead of the platform callback to control
the MIPI DSIM DPHY. The 'phy_label' field is added to the platform
data structure to allow PHY lookup on non-dt platforms.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Acked-by: Felipe Balbi <redacted>
Acked-by: Donghwa Lee <redacted>
Signed-off-by: Kishon Vijay Abraham I <redacted>
---
 drivers/video/exynos/exynos_mipi_dsi.c |   19 ++++++++++---------
 include/video/exynos_mipi_dsim.h       |    6 ++++--
 2 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/drivers/video/exynos/exynos_mipi_dsi.c b/drivers/video/exynos/exynos_mipi_dsi.c
index 32e5406..248e444 100644
--- a/drivers/video/exynos/exynos_mipi_dsi.c
+++ b/drivers/video/exynos/exynos_mipi_dsi.c
@@ -30,6 +30,7 @@
 #include <linux/interrupt.h>
 #include <linux/kthread.h>
 #include <linux/notifier.h>
+#include <linux/phy/phy.h>
 #include <linux/regulator/consumer.h>
 #include <linux/pm_runtime.h>
 #include <linux/err.h>
@@ -156,8 +157,7 @@ static int exynos_mipi_dsi_blank_mode(struct mipi_dsim_device *dsim, int power)
 		exynos_mipi_regulator_enable(dsim);
 
 		/* enable MIPI-DSI PHY. */
-		if (dsim->pd->phy_enable)
-			dsim->pd->phy_enable(pdev, true);
+		phy_power_on(dsim->phy);
 
 		clk_enable(dsim->clock);
 
@@ -373,6 +373,10 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	dsim->phy = devm_phy_get(&pdev->dev, dsim_pd->phy_label);
+	if (IS_ERR(dsim->phy))
+		return PTR_ERR(dsim->phy);
+
 	dsim->clock = devm_clk_get(&pdev->dev, "dsim0");
 	if (IS_ERR(dsim->clock)) {
 		dev_err(&pdev->dev, "failed to get dsim clock source\n");
@@ -439,8 +443,7 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev)
 	exynos_mipi_regulator_enable(dsim);
 
 	/* enable MIPI-DSI PHY. */
-	if (dsim->pd->phy_enable)
-		dsim->pd->phy_enable(pdev, true);
+	phy_power_on(dsim->phy);
 
 	exynos_mipi_update_cfg(dsim);
 
@@ -504,9 +507,8 @@ static int exynos_mipi_dsi_suspend(struct device *dev)
 	if (client_drv && client_drv->suspend)
 		client_drv->suspend(client_dev);
 
-	/* enable MIPI-DSI PHY. */
-	if (dsim->pd->phy_enable)
-		dsim->pd->phy_enable(pdev, false);
+	/* disable MIPI-DSI PHY. */
+	phy_power_off(dsim->phy);
 
 	clk_disable(dsim->clock);
 
@@ -536,8 +538,7 @@ static int exynos_mipi_dsi_resume(struct device *dev)
 	exynos_mipi_regulator_enable(dsim);
 
 	/* enable MIPI-DSI PHY. */
-	if (dsim->pd->phy_enable)
-		dsim->pd->phy_enable(pdev, true);
+	phy_power_on(dsim->phy);
 
 	clk_enable(dsim->clock);
 
diff --git a/include/video/exynos_mipi_dsim.h b/include/video/exynos_mipi_dsim.h
index 89dc88a..0e7e43b 100644
--- a/include/video/exynos_mipi_dsim.h
+++ b/include/video/exynos_mipi_dsim.h
@@ -216,6 +216,7 @@ struct mipi_dsim_config {
  *	automatically.
  * @e_clk_src: select byte clock source.
  * @pd: pointer to MIPI-DSI driver platform data.
+ * @phy: pointer to the generic PHY
  */
 struct mipi_dsim_device {
 	struct device			*dev;
@@ -236,6 +237,7 @@ struct mipi_dsim_device {
 	bool				suspended;
 
 	struct mipi_dsim_platform_data	*pd;
+	struct phy			*phy;
 };
 
 /*
@@ -248,7 +250,7 @@ struct mipi_dsim_device {
  * @enabled: indicate whether mipi controller got enabled or not.
  * @lcd_panel_info: pointer for lcd panel specific structure.
  *	this structure specifies width, height, timing and polarity and so on.
- * @phy_enable: pointer to a callback controlling D-PHY enable/reset
+ * @phy_label: the generic PHY label
  */
 struct mipi_dsim_platform_data {
 	char				lcd_panel_name[PANEL_NAME_SIZE];
@@ -257,7 +259,7 @@ struct mipi_dsim_platform_data {
 	unsigned int			enabled;
 	void				*lcd_panel_info;
 
-	int (*phy_enable)(struct platform_device *pdev, bool on);
+	const char			*phy_label;
 };
 
 /*
-- 
1.7.10.4

[PATCH 11/15] exynos4-is: Use the generic MIPI CSIS PHY driver

Message details and related content
From: Sylwester Nawrocki <s.nawrocki@samsung.com>

Use the generic PHY API instead of the platform callback to control
the MIPI CSIS DPHY. The 'phy_label' field is added to the platform
data structure to allow PHY lookup on non-dt platforms

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Acked-by: Felipe Balbi <redacted>
Acked-by: Mauro Carvalho Chehab <redacted>
Signed-off-by: Kishon Vijay Abraham I <redacted>
---
 drivers/media/platform/exynos4-is/mipi-csis.c |   16 +++++++++++++---
 include/linux/platform_data/mipi-csis.h       |   11 ++---------
 2 files changed, 15 insertions(+), 12 deletions(-)
diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c
index 0914230..94028ce 100644
--- a/drivers/media/platform/exynos4-is/mipi-csis.c
+++ b/drivers/media/platform/exynos4-is/mipi-csis.c
@@ -20,6 +20,7 @@
 #include <linux/memory.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/phy/phy.h>
 #include <linux/platform_data/mipi-csis.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
@@ -180,6 +181,7 @@ struct csis_drvdata {
  * @sd: v4l2_subdev associated with CSIS device instance
  * @index: the hardware instance index
  * @pdev: CSIS platform device
+ * @phy: pointer to the CSIS generic PHY
  * @regs: mmaped I/O registers memory
  * @supplies: CSIS regulator supplies
  * @clock: CSIS clocks
@@ -203,6 +205,8 @@ struct csis_state {
 	struct v4l2_subdev sd;
 	u8 index;
 	struct platform_device *pdev;
+	struct phy *phy;
+	const char *phy_label;
 	void __iomem *regs;
 	struct regulator_bulk_data supplies[CSIS_NUM_SUPPLIES];
 	struct clk *clock[NUM_CSIS_CLOCKS];
@@ -742,6 +746,7 @@ static int s5pcsis_get_platform_data(struct platform_device *pdev,
 	state->index = max(0, pdev->id);
 	state->max_num_lanes = state->index ? CSIS1_MAX_LANES :
 					      CSIS0_MAX_LANES;
+	state->phy_label = pdata->phy_label;
 	return 0;
 }
 
@@ -779,8 +784,9 @@ static int s5pcsis_parse_dt(struct platform_device *pdev,
 					"samsung,csis-wclk");
 
 	state->num_lanes = endpoint.bus.mipi_csi2.num_data_lanes;
-
 	of_node_put(node);
+
+	state->phy_label = "csis";
 	return 0;
 }
 #else
@@ -829,6 +835,10 @@ static int s5pcsis_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
+	state->phy = devm_phy_get(dev, state->phy_label);
+	if (IS_ERR(state->phy))
+		return PTR_ERR(state->phy);
+
 	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	state->regs = devm_ioremap_resource(dev, mem_res);
 	if (IS_ERR(state->regs))
@@ -922,7 +932,7 @@ static int s5pcsis_pm_suspend(struct device *dev, bool runtime)
 	mutex_lock(&state->lock);
 	if (state->flags & ST_POWERED) {
 		s5pcsis_stop_stream(state);
-		ret = s5p_csis_phy_enable(state->index, false);
+		ret = phy_power_off(state->phy);
 		if (ret)
 			goto unlock;
 		ret = regulator_bulk_disable(CSIS_NUM_SUPPLIES,
@@ -958,7 +968,7 @@ static int s5pcsis_pm_resume(struct device *dev, bool runtime)
 					    state->supplies);
 		if (ret)
 			goto unlock;
-		ret = s5p_csis_phy_enable(state->index, true);
+		ret = phy_power_on(state->phy);
 		if (!ret) {
 			state->flags |= ST_POWERED;
 		} else {
diff --git a/include/linux/platform_data/mipi-csis.h b/include/linux/platform_data/mipi-csis.h
index bf34e17..9214317 100644
--- a/include/linux/platform_data/mipi-csis.h
+++ b/include/linux/platform_data/mipi-csis.h
@@ -17,21 +17,14 @@
  * @wclk_source: CSI wrapper clock selection: 0 - bus clock, 1 - ext. SCLK_CAM
  * @lanes:       number of data lanes used
  * @hs_settle:   HS-RX settle time
+ * @phy_label:	 the generic PHY label
  */
 struct s5p_platform_mipi_csis {
 	unsigned long clk_rate;
 	u8 wclk_source;
 	u8 lanes;
 	u8 hs_settle;
+	const char *phy_label;
 };
 
-/**
- * s5p_csis_phy_enable - global MIPI-CSI receiver D-PHY control
- * @id:     MIPI-CSIS harware instance index (0...1)
- * @on:     true to enable D-PHY and deassert its reset
- *          false to disable D-PHY
- * @return: 0 on success, or negative error code on failure
- */
-int s5p_csis_phy_enable(int id, bool on);
-
 #endif /* __PLAT_SAMSUNG_MIPI_CSIS_H_ */
-- 
1.7.10.4

[PATCH 12/15] ARM: Samsung: Remove the MIPI PHY setup code

Message details and related content
From: Sylwester Nawrocki <s.nawrocki@samsung.com>

Generic PHY drivers are used to handle the MIPI CSIS and MIPI DSIM
DPHYs so we can remove now unused code at arch/arm/plat-samsung.
In case there is any board file for S5PV210 platforms using MIPI
CSIS/DSIM (not any upstream currently) it should use the generic
PHY API to bind the PHYs to respective PHY consumer drivers and
a platform device for the PHY provider should be defined.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Acked-by: Felipe Balbi <redacted>
Acked-by: Kukjin Kim <redacted>
Signed-off-by: Kishon Vijay Abraham I <redacted>
---
 arch/arm/mach-exynos/include/mach/regs-pmu.h    |    5 --
 arch/arm/mach-s5pv210/include/mach/regs-clock.h |    4 --
 arch/arm/plat-samsung/Kconfig                   |    5 --
 arch/arm/plat-samsung/Makefile                  |    1 -
 arch/arm/plat-samsung/setup-mipiphy.c           |   60 -----------------------
 5 files changed, 75 deletions(-)
 delete mode 100644 arch/arm/plat-samsung/setup-mipiphy.c
diff --git a/arch/arm/mach-exynos/include/mach/regs-pmu.h b/arch/arm/mach-exynos/include/mach/regs-pmu.h
index 57344b7..2cdb63e 100644
--- a/arch/arm/mach-exynos/include/mach/regs-pmu.h
+++ b/arch/arm/mach-exynos/include/mach/regs-pmu.h
@@ -44,11 +44,6 @@
 #define S5P_DAC_PHY_CONTROL			S5P_PMUREG(0x070C)
 #define S5P_DAC_PHY_ENABLE			(1 << 0)
 
-#define S5P_MIPI_DPHY_CONTROL(n)		S5P_PMUREG(0x0710 + (n) * 4)
-#define S5P_MIPI_DPHY_ENABLE			(1 << 0)
-#define S5P_MIPI_DPHY_SRESETN			(1 << 1)
-#define S5P_MIPI_DPHY_MRESETN			(1 << 2)
-
 #define S5P_INFORM0				S5P_PMUREG(0x0800)
 #define S5P_INFORM1				S5P_PMUREG(0x0804)
 #define S5P_INFORM2				S5P_PMUREG(0x0808)
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-clock.h b/arch/arm/mach-s5pv210/include/mach/regs-clock.h
index 032de66..e345584 100644
--- a/arch/arm/mach-s5pv210/include/mach/regs-clock.h
+++ b/arch/arm/mach-s5pv210/include/mach/regs-clock.h
@@ -147,10 +147,6 @@
 #define S5P_HDMI_PHY_CONTROL	S5P_CLKREG(0xE804)
 #define S5P_USB_PHY_CONTROL	S5P_CLKREG(0xE80C)
 #define S5P_DAC_PHY_CONTROL	S5P_CLKREG(0xE810)
-#define S5P_MIPI_DPHY_CONTROL(x) S5P_CLKREG(0xE814)
-#define S5P_MIPI_DPHY_ENABLE	(1 << 0)
-#define S5P_MIPI_DPHY_SRESETN	(1 << 1)
-#define S5P_MIPI_DPHY_MRESETN	(1 << 2)
 
 #define S5P_INFORM0		S5P_CLKREG(0xF000)
 #define S5P_INFORM1		S5P_CLKREG(0xF004)
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index 3dc5cbe..db2d814 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -402,11 +402,6 @@ config S3C24XX_PWM
 	  Support for exporting the PWM timer blocks via the pwm device
 	  system
 
-config S5P_SETUP_MIPIPHY
-	bool
-	help
-	  Compile in common setup code for MIPI-CSIS and MIPI-DSIM devices
-
 config S3C_SETUP_CAMIF
 	bool
 	help
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index 98d07d8..98f1e31 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -41,7 +41,6 @@ obj-$(CONFIG_S5P_DEV_UART)	+= s5p-dev-uart.o
 obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT)	+= dev-backlight.o
 
 obj-$(CONFIG_S3C_SETUP_CAMIF)	+= setup-camif.o
-obj-$(CONFIG_S5P_SETUP_MIPIPHY)	+= setup-mipiphy.o
 
 # DMA support
 
diff --git a/arch/arm/plat-samsung/setup-mipiphy.c b/arch/arm/plat-samsung/setup-mipiphy.c
deleted file mode 100644
index 66df315..0000000
--- a/arch/arm/plat-samsung/setup-mipiphy.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2011 Samsung Electronics Co., Ltd.
- *
- * S5P - Helper functions for MIPI-CSIS and MIPI-DSIM D-PHY control
- *
- * 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/export.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/spinlock.h>
-#include <mach/regs-clock.h>
-
-static int __s5p_mipi_phy_control(int id, bool on, u32 reset)
-{
-	static DEFINE_SPINLOCK(lock);
-	void __iomem *addr;
-	unsigned long flags;
-	u32 cfg;
-
-	id = max(0, id);
-	if (id > 1)
-		return -EINVAL;
-
-	addr = S5P_MIPI_DPHY_CONTROL(id);
-
-	spin_lock_irqsave(&lock, flags);
-
-	cfg = __raw_readl(addr);
-	cfg = on ? (cfg | reset) : (cfg & ~reset);
-	__raw_writel(cfg, addr);
-
-	if (on) {
-		cfg |= S5P_MIPI_DPHY_ENABLE;
-	} else if (!(cfg & (S5P_MIPI_DPHY_SRESETN |
-			    S5P_MIPI_DPHY_MRESETN) & ~reset)) {
-		cfg &= ~S5P_MIPI_DPHY_ENABLE;
-	}
-
-	__raw_writel(cfg, addr);
-	spin_unlock_irqrestore(&lock, flags);
-
-	return 0;
-}
-
-int s5p_csis_phy_enable(int id, bool on)
-{
-	return __s5p_mipi_phy_control(id, on, S5P_MIPI_DPHY_SRESETN);
-}
-EXPORT_SYMBOL(s5p_csis_phy_enable);
-
-int s5p_dsim_phy_enable(struct platform_device *pdev, bool on)
-{
-	return __s5p_mipi_phy_control(pdev->id, on, S5P_MIPI_DPHY_MRESETN);
-}
-EXPORT_SYMBOL(s5p_dsim_phy_enable);
-- 
1.7.10.4

[PATCH 15/15] video: exynos_dp: Use the generic PHY driver

Message details and related content
From: Jingoo Han <redacted>

Use the generic PHY API to control the DP PHY.

Signed-off-by: Jingoo Han <redacted>
Reviewed-by: Tomasz Figa <redacted>
Signed-off-by: Kishon Vijay Abraham I <redacted>
---
 .../devicetree/bindings/video/exynos_dp.txt          |   18 +++++++++---------
 drivers/video/exynos/exynos_dp_core.c                |   16 ++++++++++++----
 drivers/video/exynos/exynos_dp_core.h                |    1 +
 3 files changed, 22 insertions(+), 13 deletions(-)
diff --git a/Documentation/devicetree/bindings/video/exynos_dp.txt b/Documentation/devicetree/bindings/video/exynos_dp.txt
index 84f10c1..2f56376 100644
--- a/Documentation/devicetree/bindings/video/exynos_dp.txt
+++ b/Documentation/devicetree/bindings/video/exynos_dp.txt
@@ -6,10 +6,10 @@ We use two nodes:
 	-dptx-phy node(defined inside dp-controller node)
 
 For the DP-PHY initialization, we use the dptx-phy node.
-Required properties for dptx-phy:
-	-reg:
+Required properties for dptx-phy: deprecated, use phys and phy-names
+	-reg: deprecated
 		Base address of DP PHY register.
-	-samsung,enable-mask:
+	-samsung,enable-mask: deprecated
 		The bit-mask used to enable/disable DP PHY.
 
 For the Panel initialization, we read data from dp-controller node.
@@ -25,6 +25,10 @@ Required properties for dp-controller:
 		from common clock binding: handle to dp clock.
 	-clock-names:
 		from common clock binding: Shall be "dp".
+	-phys:
+		from general PHY binding: the phandle for the PHY device.
+	-phy-names:
+		from general PHY binding: Should be "dp".
 	-interrupt-parent:
 		phandle to Interrupt combiner node.
 	-samsung,color-space:
@@ -67,12 +71,8 @@ SOC specific portion:
 		interrupt-parent = <&combiner>;
 		clocks = <&clock 342>;
 		clock-names = "dp";
-
-		dptx-phy {
-			reg = <0x10040720>;
-			samsung,enable-mask = <1>;
-		};
-
+		phys = <&dp_phy>;
+		phy-names = "dp";
 	};
 
 Board Specific portion:
diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
index 05fed7d..5e1a715 100644
--- a/drivers/video/exynos/exynos_dp_core.c
+++ b/drivers/video/exynos/exynos_dp_core.c
@@ -19,6 +19,7 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/of.h>
+#include <linux/phy/phy.h>
 
 #include "exynos_dp_core.h"
 
@@ -960,8 +961,11 @@ static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
 
 	dp_phy_node = of_find_node_by_name(dp_phy_node, "dptx-phy");
 	if (!dp_phy_node) {
-		dev_err(dp->dev, "could not find dptx-phy node\n");
-		return -ENODEV;
+		dp->phy = devm_phy_get(dp->dev, "dp");
+		if (IS_ERR(dp->phy))
+			return PTR_ERR(dp->phy);
+		else
+			return 0;
 	}
 
 	if (of_property_read_u32(dp_phy_node, "reg", &phy_base)) {
@@ -992,7 +996,9 @@ err:
 
 static void exynos_dp_phy_init(struct exynos_dp_device *dp)
 {
-	if (dp->phy_addr) {
+	if (dp->phy) {
+		phy_power_on(dp->phy);
+	} else if (dp->phy_addr) {
 		u32 reg;
 
 		reg = __raw_readl(dp->phy_addr);
@@ -1003,7 +1009,9 @@ static void exynos_dp_phy_init(struct exynos_dp_device *dp)
 
 static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
 {
-	if (dp->phy_addr) {
+	if (dp->phy) {
+		phy_power_off(dp->phy);
+	} else if (dp->phy_addr) {
 		u32 reg;
 
 		reg = __raw_readl(dp->phy_addr);
diff --git a/drivers/video/exynos/exynos_dp_core.h b/drivers/video/exynos/exynos_dp_core.h
index 56cfec8..607e36d 100644
--- a/drivers/video/exynos/exynos_dp_core.h
+++ b/drivers/video/exynos/exynos_dp_core.h
@@ -151,6 +151,7 @@ struct exynos_dp_device {
 	struct video_info	*video_info;
 	struct link_train	link_train;
 	struct work_struct	hotplug_work;
+	struct phy		*phy;
 };
 
 /* exynos_dp_reg.c */
-- 
1.7.10.4

[PATCH 14/15] video: exynos_dp: remove non-DT support for Exynos Display Port

Message details and related content
From: Jingoo Han <redacted>

Exynos Display Port can be used only for Exynos SoCs. In addition,
non-DT for EXYNOS SoCs is not supported from v3.11; thus, there is
no need to support non-DT for Exynos Display Port.

The 'include/video/exynos_dp.h' file has been used for non-DT
support and the content of file include/video/exynos_dp.h is moved
to drivers/video/exynos/exynos_dp_core.h. Thus, the 'exynos_dp.h'
file is removed. Also, 'struct exynos_dp_platdata' is removed,
because it is not used any more.

Signed-off-by: Jingoo Han <redacted>
Reviewed-by: Tomasz Figa <redacted>
Signed-off-by: Kishon Vijay Abraham I <redacted>
---
 drivers/video/exynos/Kconfig          |    2 +-
 drivers/video/exynos/exynos_dp_core.c |  116 +++++++----------------------
 drivers/video/exynos/exynos_dp_core.h |  109 +++++++++++++++++++++++++++
 drivers/video/exynos/exynos_dp_reg.c  |    2 -
 include/video/exynos_dp.h             |  131 ---------------------------------
 5 files changed, 135 insertions(+), 225 deletions(-)
 delete mode 100644 include/video/exynos_dp.h
diff --git a/drivers/video/exynos/Kconfig b/drivers/video/exynos/Kconfig
index 1b035b2..fab9019 100644
--- a/drivers/video/exynos/Kconfig
+++ b/drivers/video/exynos/Kconfig
@@ -29,7 +29,7 @@ config EXYNOS_LCD_S6E8AX0
 
 config EXYNOS_DP
 	bool "EXYNOS DP driver support"
-	depends on ARCH_EXYNOS
+	depends on OF && ARCH_EXYNOS
 	default n
 	help
 	  This enables support for DP device.
diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
index 12bbede..05fed7d 100644
--- a/drivers/video/exynos/exynos_dp_core.c
+++ b/drivers/video/exynos/exynos_dp_core.c
@@ -20,8 +20,6 @@
 #include <linux/delay.h>
 #include <linux/of.h>
 
-#include <video/exynos_dp.h>
-
 #include "exynos_dp_core.h"
 
 static int exynos_dp_init_dp(struct exynos_dp_device *dp)
@@ -894,26 +892,17 @@ static void exynos_dp_hotplug(struct work_struct *work)
 		dev_err(dp->dev, "unable to config video\n");
 }
 
-#ifdef CONFIG_OF
-static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
+static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev)
 {
 	struct device_node *dp_node = dev->of_node;
-	struct exynos_dp_platdata *pd;
 	struct video_info *dp_video_config;
 
-	pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
-	if (!pd) {
-		dev_err(dev, "memory allocation for pdata failed\n");
-		return ERR_PTR(-ENOMEM);
-	}
 	dp_video_config = devm_kzalloc(dev,
 				sizeof(*dp_video_config), GFP_KERNEL);
-
 	if (!dp_video_config) {
 		dev_err(dev, "memory allocation for video config failed\n");
 		return ERR_PTR(-ENOMEM);
 	}
-	pd->video_info = dp_video_config;
 
 	dp_video_config->h_sync_polarity  		of_property_read_bool(dp_node, "hsync-active-high");
@@ -960,7 +949,7 @@ static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
 		return ERR_PTR(-EINVAL);
 	}
 
-	return pd;
+	return dp_video_config;
 }
 
 static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
@@ -1003,48 +992,30 @@ err:
 
 static void exynos_dp_phy_init(struct exynos_dp_device *dp)
 {
-	u32 reg;
+	if (dp->phy_addr) {
+		u32 reg;
 
-	reg = __raw_readl(dp->phy_addr);
-	reg |= dp->enable_mask;
-	__raw_writel(reg, dp->phy_addr);
+		reg = __raw_readl(dp->phy_addr);
+		reg |= dp->enable_mask;
+		__raw_writel(reg, dp->phy_addr);
+	}
 }
 
 static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
 {
-	u32 reg;
-
-	reg = __raw_readl(dp->phy_addr);
-	reg &= ~(dp->enable_mask);
-	__raw_writel(reg, dp->phy_addr);
-}
-#else
-static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
-{
-	return NULL;
-}
-
-static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
-{
-	return -EINVAL;
-}
-
-static void exynos_dp_phy_init(struct exynos_dp_device *dp)
-{
-	return;
-}
+	if (dp->phy_addr) {
+		u32 reg;
 
-static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
-{
-	return;
+		reg = __raw_readl(dp->phy_addr);
+		reg &= ~(dp->enable_mask);
+		__raw_writel(reg, dp->phy_addr);
+	}
 }
-#endif /* CONFIG_OF */
 
 static int exynos_dp_probe(struct platform_device *pdev)
 {
 	struct resource *res;
 	struct exynos_dp_device *dp;
-	struct exynos_dp_platdata *pdata;
 
 	int ret = 0;
 
@@ -1057,21 +1028,13 @@ static int exynos_dp_probe(struct platform_device *pdev)
 
 	dp->dev = &pdev->dev;
 
-	if (pdev->dev.of_node) {
-		pdata = exynos_dp_dt_parse_pdata(&pdev->dev);
-		if (IS_ERR(pdata))
-			return PTR_ERR(pdata);
+	dp->video_info = exynos_dp_dt_parse_pdata(&pdev->dev);
+	if (IS_ERR(dp->video_info))
+		return PTR_ERR(dp->video_info);
 
-		ret = exynos_dp_dt_parse_phydata(dp);
-		if (ret)
-			return ret;
-	} else {
-		pdata = pdev->dev.platform_data;
-		if (!pdata) {
-			dev_err(&pdev->dev, "no platform data\n");
-			return -EINVAL;
-		}
-	}
+	ret = exynos_dp_dt_parse_phydata(dp);
+	if (ret)
+		return ret;
 
 	dp->clock = devm_clk_get(&pdev->dev, "dp");
 	if (IS_ERR(dp->clock)) {
@@ -1095,15 +1058,7 @@ static int exynos_dp_probe(struct platform_device *pdev)
 
 	INIT_WORK(&dp->hotplug_work, exynos_dp_hotplug);
 
-	dp->video_info = pdata->video_info;
-
-	if (pdev->dev.of_node) {
-		if (dp->phy_addr)
-			exynos_dp_phy_init(dp);
-	} else {
-		if (pdata->phy_init)
-			pdata->phy_init();
-	}
+	exynos_dp_phy_init(dp);
 
 	exynos_dp_init_dp(dp);
 
@@ -1121,18 +1076,11 @@ static int exynos_dp_probe(struct platform_device *pdev)
 
 static int exynos_dp_remove(struct platform_device *pdev)
 {
-	struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
 	struct exynos_dp_device *dp = platform_get_drvdata(pdev);
 
 	flush_work(&dp->hotplug_work);
 
-	if (pdev->dev.of_node) {
-		if (dp->phy_addr)
-			exynos_dp_phy_exit(dp);
-	} else {
-		if (pdata->phy_exit)
-			pdata->phy_exit();
-	}
+	exynos_dp_phy_exit(dp);
 
 	clk_disable_unprepare(dp->clock);
 
@@ -1143,20 +1091,13 @@ static int exynos_dp_remove(struct platform_device *pdev)
 #ifdef CONFIG_PM_SLEEP
 static int exynos_dp_suspend(struct device *dev)
 {
-	struct exynos_dp_platdata *pdata = dev->platform_data;
 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
 
 	disable_irq(dp->irq);
 
 	flush_work(&dp->hotplug_work);
 
-	if (dev->of_node) {
-		if (dp->phy_addr)
-			exynos_dp_phy_exit(dp);
-	} else {
-		if (pdata->phy_exit)
-			pdata->phy_exit();
-	}
+	exynos_dp_phy_exit(dp);
 
 	clk_disable_unprepare(dp->clock);
 
@@ -1165,16 +1106,9 @@ static int exynos_dp_suspend(struct device *dev)
 
 static int exynos_dp_resume(struct device *dev)
 {
-	struct exynos_dp_platdata *pdata = dev->platform_data;
 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
 
-	if (dev->of_node) {
-		if (dp->phy_addr)
-			exynos_dp_phy_init(dp);
-	} else {
-		if (pdata->phy_init)
-			pdata->phy_init();
-	}
+	exynos_dp_phy_init(dp);
 
 	clk_prepare_enable(dp->clock);
 
@@ -1203,7 +1137,7 @@ static struct platform_driver exynos_dp_driver = {
 		.name	= "exynos-dp",
 		.owner	= THIS_MODULE,
 		.pm	= &exynos_dp_pm_ops,
-		.of_match_table = of_match_ptr(exynos_dp_match),
+		.of_match_table = exynos_dp_match,
 	},
 };
 
diff --git a/drivers/video/exynos/exynos_dp_core.h b/drivers/video/exynos/exynos_dp_core.h
index 6c567bbf..56cfec8 100644
--- a/drivers/video/exynos/exynos_dp_core.h
+++ b/drivers/video/exynos/exynos_dp_core.h
@@ -13,6 +13,99 @@
 #ifndef _EXYNOS_DP_CORE_H
 #define _EXYNOS_DP_CORE_H
 
+#define DP_TIMEOUT_LOOP_COUNT 100
+#define MAX_CR_LOOP 5
+#define MAX_EQ_LOOP 5
+
+enum link_rate_type {
+	LINK_RATE_1_62GBPS = 0x06,
+	LINK_RATE_2_70GBPS = 0x0a
+};
+
+enum link_lane_count_type {
+	LANE_COUNT1 = 1,
+	LANE_COUNT2 = 2,
+	LANE_COUNT4 = 4
+};
+
+enum link_training_state {
+	START,
+	CLOCK_RECOVERY,
+	EQUALIZER_TRAINING,
+	FINISHED,
+	FAILED
+};
+
+enum voltage_swing_level {
+	VOLTAGE_LEVEL_0,
+	VOLTAGE_LEVEL_1,
+	VOLTAGE_LEVEL_2,
+	VOLTAGE_LEVEL_3,
+};
+
+enum pre_emphasis_level {
+	PRE_EMPHASIS_LEVEL_0,
+	PRE_EMPHASIS_LEVEL_1,
+	PRE_EMPHASIS_LEVEL_2,
+	PRE_EMPHASIS_LEVEL_3,
+};
+
+enum pattern_set {
+	PRBS7,
+	D10_2,
+	TRAINING_PTN1,
+	TRAINING_PTN2,
+	DP_NONE
+};
+
+enum color_space {
+	COLOR_RGB,
+	COLOR_YCBCR422,
+	COLOR_YCBCR444
+};
+
+enum color_depth {
+	COLOR_6,
+	COLOR_8,
+	COLOR_10,
+	COLOR_12
+};
+
+enum color_coefficient {
+	COLOR_YCBCR601,
+	COLOR_YCBCR709
+};
+
+enum dynamic_range {
+	VESA,
+	CEA
+};
+
+enum pll_status {
+	PLL_UNLOCKED,
+	PLL_LOCKED
+};
+
+enum clock_recovery_m_value_type {
+	CALCULATED_M,
+	REGISTER_M
+};
+
+enum video_timing_recognition_type {
+	VIDEO_TIMING_FROM_CAPTURE,
+	VIDEO_TIMING_FROM_REGISTER
+};
+
+enum analog_power_block {
+	AUX_BLOCK,
+	CH0_BLOCK,
+	CH1_BLOCK,
+	CH2_BLOCK,
+	CH3_BLOCK,
+	ANALOG_TOTAL,
+	POWER_ALL
+};
+
 enum dp_irq_type {
 	DP_IRQ_TYPE_HP_CABLE_IN,
 	DP_IRQ_TYPE_HP_CABLE_OUT,
@@ -20,6 +113,22 @@ enum dp_irq_type {
 	DP_IRQ_TYPE_UNKNOWN,
 };
 
+struct video_info {
+	char *name;
+
+	bool h_sync_polarity;
+	bool v_sync_polarity;
+	bool interlaced;
+
+	enum color_space color_space;
+	enum dynamic_range dynamic_range;
+	enum color_coefficient ycbcr_coeff;
+	enum color_depth color_depth;
+
+	enum link_rate_type link_rate;
+	enum link_lane_count_type lane_count;
+};
+
 struct link_train {
 	int eq_loop;
 	int cr_loop[4];
diff --git a/drivers/video/exynos/exynos_dp_reg.c b/drivers/video/exynos/exynos_dp_reg.c
index 29d9d03..b70da50 100644
--- a/drivers/video/exynos/exynos_dp_reg.c
+++ b/drivers/video/exynos/exynos_dp_reg.c
@@ -14,8 +14,6 @@
 #include <linux/io.h>
 #include <linux/delay.h>
 
-#include <video/exynos_dp.h>
-
 #include "exynos_dp_core.h"
 #include "exynos_dp_reg.h"
 
diff --git a/include/video/exynos_dp.h b/include/video/exynos_dp.h
deleted file mode 100644
index bd8cabd..0000000
--- a/include/video/exynos_dp.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Samsung SoC DP device support
- *
- * Copyright (C) 2012 Samsung Electronics Co., Ltd.
- * Author: Jingoo Han <jg1.han@samsung.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.
- */
-
-#ifndef _EXYNOS_DP_H
-#define _EXYNOS_DP_H
-
-#define DP_TIMEOUT_LOOP_COUNT 100
-#define MAX_CR_LOOP 5
-#define MAX_EQ_LOOP 5
-
-enum link_rate_type {
-	LINK_RATE_1_62GBPS = 0x06,
-	LINK_RATE_2_70GBPS = 0x0a
-};
-
-enum link_lane_count_type {
-	LANE_COUNT1 = 1,
-	LANE_COUNT2 = 2,
-	LANE_COUNT4 = 4
-};
-
-enum link_training_state {
-	START,
-	CLOCK_RECOVERY,
-	EQUALIZER_TRAINING,
-	FINISHED,
-	FAILED
-};
-
-enum voltage_swing_level {
-	VOLTAGE_LEVEL_0,
-	VOLTAGE_LEVEL_1,
-	VOLTAGE_LEVEL_2,
-	VOLTAGE_LEVEL_3,
-};
-
-enum pre_emphasis_level {
-	PRE_EMPHASIS_LEVEL_0,
-	PRE_EMPHASIS_LEVEL_1,
-	PRE_EMPHASIS_LEVEL_2,
-	PRE_EMPHASIS_LEVEL_3,
-};
-
-enum pattern_set {
-	PRBS7,
-	D10_2,
-	TRAINING_PTN1,
-	TRAINING_PTN2,
-	DP_NONE
-};
-
-enum color_space {
-	COLOR_RGB,
-	COLOR_YCBCR422,
-	COLOR_YCBCR444
-};
-
-enum color_depth {
-	COLOR_6,
-	COLOR_8,
-	COLOR_10,
-	COLOR_12
-};
-
-enum color_coefficient {
-	COLOR_YCBCR601,
-	COLOR_YCBCR709
-};
-
-enum dynamic_range {
-	VESA,
-	CEA
-};
-
-enum pll_status {
-	PLL_UNLOCKED,
-	PLL_LOCKED
-};
-
-enum clock_recovery_m_value_type {
-	CALCULATED_M,
-	REGISTER_M
-};
-
-enum video_timing_recognition_type {
-	VIDEO_TIMING_FROM_CAPTURE,
-	VIDEO_TIMING_FROM_REGISTER
-};
-
-enum analog_power_block {
-	AUX_BLOCK,
-	CH0_BLOCK,
-	CH1_BLOCK,
-	CH2_BLOCK,
-	CH3_BLOCK,
-	ANALOG_TOTAL,
-	POWER_ALL
-};
-
-struct video_info {
-	char *name;
-
-	bool h_sync_polarity;
-	bool v_sync_polarity;
-	bool interlaced;
-
-	enum color_space color_space;
-	enum dynamic_range dynamic_range;
-	enum color_coefficient ycbcr_coeff;
-	enum color_depth color_depth;
-
-	enum link_rate_type link_rate;
-	enum link_lane_count_type lane_count;
-};
-
-struct exynos_dp_platdata {
-	struct video_info *video_info;
-
-	void (*phy_init)(void);
-	void (*phy_exit)(void);
-};
-
-#endif /* _EXYNOS_DP_H */
-- 
1.7.10.4

[PATCH 13/15] phy: Add driver for Exynos DP PHY

Message details and related content
From: Jingoo Han <redacted>

Add a PHY provider driver for the Samsung Exynos SoC Display Port PHY.

Signed-off-by: Jingoo Han <redacted>
Reviewed-by: Tomasz Figa <redacted>
Cc: Sylwester Nawrocki <s.nawrocki@samsung.com>
Acked-by: Felipe Balbi <redacted>
Signed-off-by: Kishon Vijay Abraham I <redacted>
---
 .../devicetree/bindings/phy/samsung-phy.txt        |    8 ++
 drivers/phy/Kconfig                                |    6 ++
 drivers/phy/Makefile                               |    1 +
 drivers/phy/phy-exynos-dp-video.c                  |  111 ++++++++++++++++++++
 4 files changed, 126 insertions(+)
 create mode 100644 drivers/phy/phy-exynos-dp-video.c
diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt
index 5ff208c..c0fccaa 100644
--- a/Documentation/devicetree/bindings/phy/samsung-phy.txt
+++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt
@@ -12,3 +12,11 @@ the PHY specifier identifies the PHY and its meaning is as follows:
   1 - MIPI DSIM 0,
   2 - MIPI CSIS 1,
   3 - MIPI DSIM 1.
+
+Samsung EXYNOS SoC series Display Port PHY
+-------------------------------------------------
+
+Required properties:
+- compatible : should be "samsung,exynos5250-dp-video-phy";
+- reg : offset and length of the Display Port PHY register set;
+- #phy-cells : from the generic PHY bindings, must be 0;
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 6f446d0..ed0b1b8 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -19,4 +19,10 @@ config PHY_EXYNOS_MIPI_VIDEO
 	help
 	  Support for MIPI CSI-2 and MIPI DSI DPHY found on Samsung
 	  S5P and EXYNOS SoCs.
+
+config PHY_EXYNOS_DP_VIDEO
+	tristate "EXYNOS SoC series Display Port PHY driver"
+	depends on OF
+	help
+	  Support for Display Port PHY found on Samsung EXYNOS SoCs.
 endif
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 71d8841..0fd1340 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -4,3 +4,4 @@
 
 obj-$(CONFIG_GENERIC_PHY)		+= phy-core.o
 obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO)	+= phy-exynos-mipi-video.o
+obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO)	+= phy-exynos-dp-video.o
diff --git a/drivers/phy/phy-exynos-dp-video.c b/drivers/phy/phy-exynos-dp-video.c
new file mode 100644
index 0000000..3c8e247
--- /dev/null
+++ b/drivers/phy/phy-exynos-dp-video.c
@@ -0,0 +1,111 @@
+/*
+ * Samsung EXYNOS SoC series Display Port PHY driver
+ *
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ * Author: Jingoo Han <jg1.han@samsung.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/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+
+/* DPTX_PHY_CONTROL register */
+#define EXYNOS_DPTX_PHY_ENABLE		(1 << 0)
+
+struct exynos_dp_video_phy {
+	void __iomem *regs;
+};
+
+static int __set_phy_state(struct exynos_dp_video_phy *state, unsigned int on)
+{
+	u32 reg;
+
+	reg = readl(state->regs);
+	if (on)
+		reg |= EXYNOS_DPTX_PHY_ENABLE;
+	else
+		reg &= ~EXYNOS_DPTX_PHY_ENABLE;
+	writel(reg, state->regs);
+
+	return 0;
+}
+
+static int exynos_dp_video_phy_power_on(struct phy *phy)
+{
+	struct exynos_dp_video_phy *state = phy_get_drvdata(phy);
+
+	return __set_phy_state(state, 1);
+}
+
+static int exynos_dp_video_phy_power_off(struct phy *phy)
+{
+	struct exynos_dp_video_phy *state = phy_get_drvdata(phy);
+
+	return __set_phy_state(state, 0);
+}
+
+static struct phy_ops exynos_dp_video_phy_ops = {
+	.power_on	= exynos_dp_video_phy_power_on,
+	.power_off	= exynos_dp_video_phy_power_off,
+	.owner		= THIS_MODULE,
+};
+
+static int exynos_dp_video_phy_probe(struct platform_device *pdev)
+{
+	struct exynos_dp_video_phy *state;
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	struct phy_provider *phy_provider;
+	struct phy *phy;
+
+	state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL);
+	if (!state)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	state->regs = devm_ioremap_resource(dev, res);
+	if (IS_ERR(state->regs))
+		return PTR_ERR(state->regs);
+
+	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+	if (IS_ERR(phy_provider))
+		return PTR_ERR(phy_provider);
+
+	phy = devm_phy_create(dev, 0, &exynos_dp_video_phy_ops, NULL);
+	if (IS_ERR(phy)) {
+		dev_err(dev, "failed to create Display Port PHY\n");
+		return PTR_ERR(phy);
+	}
+	phy_set_drvdata(phy, state);
+
+	return 0;
+}
+
+static const struct of_device_id exynos_dp_video_phy_of_match[] = {
+	{ .compatible = "samsung,exynos5250-dp-video-phy" },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, exynos_dp_video_phy_of_match);
+
+static struct platform_driver exynos_dp_video_phy_driver = {
+	.probe	= exynos_dp_video_phy_probe,
+	.driver = {
+		.name	= "exynos-dp-video-phy",
+		.owner	= THIS_MODULE,
+		.of_match_table	= exynos_dp_video_phy_of_match,
+	}
+};
+module_platform_driver(exynos_dp_video_phy_driver);
+
+MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
+MODULE_DESCRIPTION("Samsung EXYNOS SoC DP PHY driver");
+MODULE_LICENSE("GPL v2");
-- 
1.7.10.4

[PATCH 08/15] usb: phy: twl4030-usb: remove *set_suspend* and *phy_init* ops

Message details and related content
Now that twl4030-usb is adapted to the new generic PHY framework,
*set_suspend* and *phy_init* ops can be removed from twl4030-usb driver.

Signed-off-by: Kishon Vijay Abraham I <redacted>
Acked-by: Felipe Balbi <redacted>
Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 drivers/usb/phy/phy-twl4030-usb.c |   57 +++++++++----------------------------
 1 file changed, 13 insertions(+), 44 deletions(-)
diff --git a/drivers/usb/phy/phy-twl4030-usb.c b/drivers/usb/phy/phy-twl4030-usb.c
index 9051756..44f8b1b 100644
--- a/drivers/usb/phy/phy-twl4030-usb.c
+++ b/drivers/usb/phy/phy-twl4030-usb.c
@@ -422,25 +422,20 @@ static void twl4030_phy_power(struct twl4030_usb *twl, int on)
 	}
 }
 
-static void twl4030_phy_suspend(struct twl4030_usb *twl, int controller_off)
+static int twl4030_phy_power_off(struct phy *phy)
 {
+	struct twl4030_usb *twl = phy_get_drvdata(phy);
+
 	if (twl->asleep)
-		return;
+		return 0;
 
 	twl4030_phy_power(twl, 0);
 	twl->asleep = 1;
 	dev_dbg(twl->dev, "%s\n", __func__);
-}
-
-static int twl4030_phy_power_off(struct phy *phy)
-{
-	struct twl4030_usb *twl = phy_get_drvdata(phy);
-
-	twl4030_phy_suspend(twl, 0);
 	return 0;
 }
 
-static void __twl4030_phy_resume(struct twl4030_usb *twl)
+static void __twl4030_phy_power_on(struct twl4030_usb *twl)
 {
 	twl4030_phy_power(twl, 1);
 	twl4030_i2c_access(twl, 1);
@@ -449,11 +444,13 @@ static void __twl4030_phy_resume(struct twl4030_usb *twl)
 		twl4030_i2c_access(twl, 0);
 }
 
-static void twl4030_phy_resume(struct twl4030_usb *twl)
+static int twl4030_phy_power_on(struct phy *phy)
 {
+	struct twl4030_usb *twl = phy_get_drvdata(phy);
+
 	if (!twl->asleep)
-		return;
-	__twl4030_phy_resume(twl);
+		return 0;
+	__twl4030_phy_power_on(twl);
 	twl->asleep = 0;
 	dev_dbg(twl->dev, "%s\n", __func__);
 
@@ -466,13 +463,6 @@ static void twl4030_phy_resume(struct twl4030_usb *twl)
 		cancel_delayed_work(&twl->id_workaround_work);
 		schedule_delayed_work(&twl->id_workaround_work, HZ);
 	}
-}
-
-static int twl4030_phy_power_on(struct phy *phy)
-{
-	struct twl4030_usb *twl = phy_get_drvdata(phy);
-
-	twl4030_phy_resume(twl);
 	return 0;
 }
 
@@ -604,9 +594,9 @@ static void twl4030_id_workaround_work(struct work_struct *work)
 	}
 }
 
-static int twl4030_usb_phy_init(struct usb_phy *phy)
+static int twl4030_phy_init(struct phy *phy)
 {
-	struct twl4030_usb *twl = phy_to_twl(phy);
+	struct twl4030_usb *twl = phy_get_drvdata(phy);
 	enum omap_musb_vbus_id_status status;
 
 	/*
@@ -621,32 +611,13 @@ static int twl4030_usb_phy_init(struct usb_phy *phy)
 
 	if (status = OMAP_MUSB_ID_GROUND || status = OMAP_MUSB_VBUS_VALID) {
 		omap_musb_mailbox(twl->linkstat);
-		twl4030_phy_resume(twl);
+		twl4030_phy_power_on(phy);
 	}
 
 	sysfs_notify(&twl->dev->kobj, NULL, "vbus");
 	return 0;
 }
 
-static int twl4030_phy_init(struct phy *phy)
-{
-	struct twl4030_usb *twl = phy_get_drvdata(phy);
-
-	return twl4030_usb_phy_init(&twl->phy);
-}
-
-static int twl4030_set_suspend(struct usb_phy *x, int suspend)
-{
-	struct twl4030_usb *twl = phy_to_twl(x);
-
-	if (suspend)
-		twl4030_phy_suspend(twl, 1);
-	else
-		twl4030_phy_resume(twl);
-
-	return 0;
-}
-
 static int twl4030_set_peripheral(struct usb_otg *otg,
 					struct usb_gadget *gadget)
 {
@@ -717,8 +688,6 @@ static int twl4030_usb_probe(struct platform_device *pdev)
 	twl->phy.label		= "twl4030";
 	twl->phy.otg		= otg;
 	twl->phy.type		= USB_PHY_TYPE_USB2;
-	twl->phy.set_suspend	= twl4030_set_suspend;
-	twl->phy.init		= twl4030_usb_phy_init;
 
 	otg->phy		= &twl->phy;
 	otg->set_host		= twl4030_set_host;
-- 
1.7.10.4

[PATCH 02/15] usb: phy: omap-usb2: use the new generic PHY framework

Message details and related content
Used the generic PHY framework API to create the PHY. Now the power off and
power on are done in omap_usb_power_off and omap_usb_power_on respectively.

However using the old USB PHY library cannot be completely removed
because OTG is intertwined with PHY and moving to the new framework
will break OTG. Once we have a separate OTG state machine, we
can get rid of the USB PHY library.

Signed-off-by: Kishon Vijay Abraham I <redacted>
Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Acked-by: Felipe Balbi <redacted>
---
 drivers/usb/phy/Kconfig         |    1 +
 drivers/usb/phy/phy-omap-usb2.c |   45 +++++++++++++++++++++++++++++++++++----
 2 files changed, 42 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
index 3622fff..cc55993 100644
--- a/drivers/usb/phy/Kconfig
+++ b/drivers/usb/phy/Kconfig
@@ -75,6 +75,7 @@ config OMAP_CONTROL_USB
 config OMAP_USB2
 	tristate "OMAP USB2 PHY Driver"
 	depends on ARCH_OMAP2PLUS
+	depends on GENERIC_PHY
 	select OMAP_CONTROL_USB
 	help
 	  Enable this to support the transceiver that is part of SOC. This
diff --git a/drivers/usb/phy/phy-omap-usb2.c b/drivers/usb/phy/phy-omap-usb2.c
index 844ab68..751b30f 100644
--- a/drivers/usb/phy/phy-omap-usb2.c
+++ b/drivers/usb/phy/phy-omap-usb2.c
@@ -28,6 +28,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/delay.h>
 #include <linux/usb/omap_control_usb.h>
+#include <linux/phy/phy.h>
 
 /**
  * omap_usb2_set_comparator - links the comparator present in the sytem with
@@ -119,10 +120,36 @@ static int omap_usb2_suspend(struct usb_phy *x, int suspend)
 	return 0;
 }
 
+static int omap_usb_power_off(struct phy *x)
+{
+	struct omap_usb *phy = phy_get_drvdata(x);
+
+	omap_control_usb_phy_power(phy->control_dev, 0);
+
+	return 0;
+}
+
+static int omap_usb_power_on(struct phy *x)
+{
+	struct omap_usb *phy = phy_get_drvdata(x);
+
+	omap_control_usb_phy_power(phy->control_dev, 1);
+
+	return 0;
+}
+
+static struct phy_ops ops = {
+	.power_on	= omap_usb_power_on,
+	.power_off	= omap_usb_power_off,
+	.owner		= THIS_MODULE,
+};
+
 static int omap_usb2_probe(struct platform_device *pdev)
 {
 	struct omap_usb			*phy;
+	struct phy			*generic_phy;
 	struct usb_otg			*otg;
+	struct phy_provider		*phy_provider;
 
 	phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
 	if (!phy) {
@@ -144,6 +171,11 @@ static int omap_usb2_probe(struct platform_device *pdev)
 	phy->phy.otg		= otg;
 	phy->phy.type		= USB_PHY_TYPE_USB2;
 
+	phy_provider = devm_of_phy_provider_register(phy->dev,
+			of_phy_simple_xlate);
+	if (IS_ERR(phy_provider))
+		return PTR_ERR(phy_provider);
+
 	phy->control_dev = omap_get_control_dev();
 	if (IS_ERR(phy->control_dev)) {
 		dev_dbg(&pdev->dev, "Failed to get control device\n");
@@ -159,6 +191,15 @@ static int omap_usb2_probe(struct platform_device *pdev)
 	otg->start_srp		= omap_usb_start_srp;
 	otg->phy		= &phy->phy;
 
+	platform_set_drvdata(pdev, phy);
+	pm_runtime_enable(phy->dev);
+
+	generic_phy = devm_phy_create(phy->dev, 0, &ops, "omap-usb2");
+	if (IS_ERR(generic_phy))
+		return PTR_ERR(generic_phy);
+
+	phy_set_drvdata(generic_phy, phy);
+
 	phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k");
 	if (IS_ERR(phy->wkupclk)) {
 		dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n");
@@ -174,10 +215,6 @@ static int omap_usb2_probe(struct platform_device *pdev)
 
 	usb_add_phy_dev(&phy->phy);
 
-	platform_set_drvdata(pdev, phy);
-
-	pm_runtime_enable(phy->dev);
-
 	return 0;
 }
 
-- 
1.7.10.4

Re: [PATCH 04/15] ARM: OMAP: USB: Add phy binding information

Message details and related content
* Kishon Vijay Abraham I [off-list ref] [130717 23:53]:
quoted hunk
In order for controllers to get PHY in case of non dt boot, the phy
binding information (phy device name) should be added in the platform
data of the controller.

Signed-off-by: Kishon Vijay Abraham I <redacted>
Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Acked-by: Felipe Balbi <redacted>
---
 arch/arm/mach-omap2/usb-musb.c |    3 +++
 include/linux/usb/musb.h       |    3 +++
 2 files changed, 6 insertions(+)
diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c
index 8c4de27..6aa7cbf 100644
--- a/arch/arm/mach-omap2/usb-musb.c
+++ b/arch/arm/mach-omap2/usb-musb.c
@@ -85,6 +85,9 @@ void __init usb_musb_init(struct omap_musb_board_data *musb_board_data)
 	musb_plat.mode = board_data->mode;
 	musb_plat.extvbus = board_data->extvbus;
 
+	if (cpu_is_omap34xx())
+		musb_plat.phy_label = "twl4030";
+
 	if (soc_is_am35xx()) {
 		oh_name = "am35x_otg_hs";
 		name = "musb-am35x";
I don't think there's a USB PHY on non-twl4030 chips, so this should
be OK:

Acked-by: Tony Lindgren <tony@atomide.com>

quoted hunk
diff --git a/include/linux/usb/musb.h b/include/linux/usb/musb.h
index 053c268..596f8c8 100644
--- a/include/linux/usb/musb.h
+++ b/include/linux/usb/musb.h
@@ -104,6 +104,9 @@ struct musb_hdrc_platform_data {
 	/* for clk_get() */
 	const char	*clock;
 
+	/* phy label */
+	const char	*phy_label;
+
 	/* (HOST or OTG) switch VBUS on/off */
 	int		(*set_vbus)(struct device *dev, int is_on);
 
-- 
1.7.10.4

Re: [PATCH 05/15] ARM: dts: omap: update usb_otg_hs data

Message details and related content
* Kishon Vijay Abraham I [off-list ref] [130717 23:53]:
Updated the usb_otg_hs dt data to include the *phy* and *phy-names*
binding in order for the driver to use the new generic PHY framework.
Also updated the Documentation to include the binding information.
The PHY binding information can be found at
Documentation/devicetree/bindings/phy/phy-bindings.txt

Signed-off-by: Kishon Vijay Abraham I <redacted>
Acked-by: Felipe Balbi <redacted>
Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
In general the .dts changes should be separate to avoid pointless
merge conflicts. But sounds like things will stop working for
USB unless we do it like this so:

Acked-by: Tony Lindgren <tony@atomide.com>

quoted hunk
---
 Documentation/devicetree/bindings/usb/omap-usb.txt |    5 +++++
 Documentation/devicetree/bindings/usb/usb-phy.txt  |    6 ++++++
 arch/arm/boot/dts/omap3-beagle-xm.dts              |    2 ++
 arch/arm/boot/dts/omap3-evm.dts                    |    2 ++
 arch/arm/boot/dts/omap3-overo.dtsi                 |    2 ++
 arch/arm/boot/dts/omap4.dtsi                       |    3 +++
 arch/arm/boot/dts/twl4030.dtsi                     |    1 +
 7 files changed, 21 insertions(+)
diff --git a/Documentation/devicetree/bindings/usb/omap-usb.txt b/Documentation/devicetree/bindings/usb/omap-usb.txt
index 57e71f6..825790d 100644
--- a/Documentation/devicetree/bindings/usb/omap-usb.txt
+++ b/Documentation/devicetree/bindings/usb/omap-usb.txt
@@ -19,6 +19,9 @@ OMAP MUSB GLUE
  - power : Should be "50". This signifies the controller can supply up to
    100mA when operating in host mode.
  - usb-phy : the phandle for the PHY device
+ - phys : the phandle for the PHY device (used by generic PHY framework)
+ - phy-names : the names of the PHY corresponding to the PHYs present in the
+   *phy* phandle.
 
 Optional properties:
  - ctrl-module : phandle of the control module this glue uses to write to
@@ -33,6 +36,8 @@ usb_otg_hs: usb_otg_hs@4a0ab000 {
 	num-eps = <16>;
 	ram-bits = <12>;
 	ctrl-module = <&omap_control_usb>;
+	phys = <&usb2_phy>;
+	phy-names = "usb2-phy";
 };
 
 Board specific device node entry
diff --git a/Documentation/devicetree/bindings/usb/usb-phy.txt b/Documentation/devicetree/bindings/usb/usb-phy.txt
index 61496f5..c0245c8 100644
--- a/Documentation/devicetree/bindings/usb/usb-phy.txt
+++ b/Documentation/devicetree/bindings/usb/usb-phy.txt
@@ -5,6 +5,8 @@ OMAP USB2 PHY
 Required properties:
  - compatible: Should be "ti,omap-usb2"

104 more quoted lines

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Thu, Jul 18, 2013 at 12:16:10PM +0530, Kishon Vijay Abraham I wrote:
quoted hunk
+struct phy_provider *__of_phy_provider_register(struct device *dev,
+	struct module *owner, struct phy * (*of_xlate)(struct device *dev,
+	struct of_phandle_args *args));
+struct phy_provider *__devm_of_phy_provider_register(struct device *dev,
+	struct module *owner, struct phy * (*of_xlate)(struct device *dev,
+	struct of_phandle_args *args))
+
+__of_phy_provider_register and __devm_of_phy_provider_register can be used to
+register the phy_provider and it takes device, owner and of_xlate as
+arguments. For the dt boot case, all PHY providers should use one of the above
+2 APIs to register the PHY provider.
Why do you have __ for the prefix of a public function?  Is that really
the way that OF handles this type of thing?
quoted hunk
--- /dev/null
+++ b/drivers/phy/Kconfig
@@ -0,0 +1,13 @@
+#
+# PHY
+#
+
+menuconfig GENERIC_PHY
+	tristate "PHY Subsystem"
+	help
+	  Generic PHY support.
+
+	  This framework is designed to provide a generic interface for PHY
+	  devices present in the kernel. This layer will have the generic
+	  API by which phy drivers can create PHY using the phy framework and
+	  phy users can obtain reference to the PHY.
Again, please reverse this.  The drivers that use it should select it,
not depend on it, which will then enable this option.  I will never know
if I need to enable it, and based on your follow-on patches, if I don't,
drivers that were working just fine, now disappeared from my build,
which isn't nice, and a pain to notice and fix up.
quoted hunk
+/**
+ * phy_create() - create a new phy
+ * @dev: device that is creating the new phy
+ * @id: id of the phy
+ * @ops: function pointers for performing phy operations
+ * @label: label given to the phy
+ *
+ * Called to create a phy using phy framework.
+ */
+struct phy *phy_create(struct device *dev, u8 id, const struct phy_ops *ops,
+	const char *label)
+{
+	int ret;
+	struct phy *phy;
+
+	if (!dev) {
+		dev_WARN(dev, "no device provided for PHY\n");
+		ret = -EINVAL;
+		goto err0;
+	}
+
+	phy = kzalloc(sizeof(*phy), GFP_KERNEL);
+	if (!phy) {
+		ret = -ENOMEM;
+		goto err0;
+	}
+
+	device_initialize(&phy->dev);
+	mutex_init(&phy->mutex);
+
+	phy->dev.class = phy_class;
+	phy->dev.parent = dev;
+	phy->dev.of_node = dev->of_node;
+	phy->id = id;
+	phy->ops = ops;
+	phy->label = kstrdup(label, GFP_KERNEL);
+
+	ret = dev_set_name(&phy->dev, "%s.%d", dev_name(dev), id);
Your naming is odd, no "phy" anywhere in it?  You rely on the sender to
never send a duplicate name.id pair?  Why not create your own ids based
on the number of phys in the system, like almost all other classes and
subsystems do?
quoted hunk
+static inline int phy_pm_runtime_get(struct phy *phy)
+{
+	if (WARN(IS_ERR(phy), "Invalid PHY reference\n"))
+		return -EINVAL;
Why would phy ever not be valid and a error pointer?  And why dump the
stack if that happens, that seems really extreme.
quoted hunk
+
+	if (!pm_runtime_enabled(&phy->dev))
+		return -ENOTSUPP;
+
+	return pm_runtime_get(&phy->dev);
+}
This, and the other inline functions in this .h file seem huge, why are
they inline and not in the .c file?  There's no speed issues, and it
should save space overall in the .c file.  Please move them.

quoted hunk
+static inline int phy_init(struct phy *phy)
+{
+	int ret;
+
+	ret = phy_pm_runtime_get_sync(phy);
+	if (ret < 0 && ret != -ENOTSUPP)
+		return ret;
+
+	mutex_lock(&phy->mutex);
+	if (phy->init_count++ = 0 && phy->ops->init) {
+		ret = phy->ops->init(phy);
+		if (ret < 0) {
+			dev_err(&phy->dev, "phy init failed --> %d\n", ret);
+			goto out;
+		}
+	}
+
+out:
+	mutex_unlock(&phy->mutex);
+	phy_pm_runtime_put(phy);
+	return ret;
+}
+
+static inline int phy_exit(struct phy *phy)
+{
+	int ret;
+
+	ret = phy_pm_runtime_get_sync(phy);
+	if (ret < 0 && ret != -ENOTSUPP)
+		return ret;
+
+	mutex_lock(&phy->mutex);
+	if (--phy->init_count = 0 && phy->ops->exit) {
+		ret = phy->ops->exit(phy);
+		if (ret < 0) {
+			dev_err(&phy->dev, "phy exit failed --> %d\n", ret);
+			goto out;
+		}
+	}
+

48 more quoted lines

Look at those 3 functions, they are all "real" and not an inline
function at all, please move them.

thanks,

greg k-h

Re: [PATCH 02/15] usb: phy: omap-usb2: use the new generic PHY framework

Message details and related content
On Thu, Jul 18, 2013 at 12:16:11PM +0530, Kishon Vijay Abraham I wrote:
quoted hunk
Used the generic PHY framework API to create the PHY. Now the power off and
power on are done in omap_usb_power_off and omap_usb_power_on respectively.

However using the old USB PHY library cannot be completely removed
because OTG is intertwined with PHY and moving to the new framework
will break OTG. Once we have a separate OTG state machine, we
can get rid of the USB PHY library.

Signed-off-by: Kishon Vijay Abraham I <redacted>
Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Acked-by: Felipe Balbi <redacted>
---
 drivers/usb/phy/Kconfig         |    1 +
 drivers/usb/phy/phy-omap-usb2.c |   45 +++++++++++++++++++++++++++++++++++----
 2 files changed, 42 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
index 3622fff..cc55993 100644
--- a/drivers/usb/phy/Kconfig
+++ b/drivers/usb/phy/Kconfig
@@ -75,6 +75,7 @@ config OMAP_CONTROL_USB
 config OMAP_USB2
 	tristate "OMAP USB2 PHY Driver"
 	depends on ARCH_OMAP2PLUS
+	depends on GENERIC_PHY
 	select OMAP_CONTROL_USB
 	help
 	  Enable this to support the transceiver that is part of SOC. This
diff --git a/drivers/usb/phy/phy-omap-usb2.c b/drivers/usb/phy/phy-omap-usb2.c
index 844ab68..751b30f 100644
--- a/drivers/usb/phy/phy-omap-usb2.c
+++ b/drivers/usb/phy/phy-omap-usb2.c
@@ -28,6 +28,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/delay.h>
 #include <linux/usb/omap_control_usb.h>
+#include <linux/phy/phy.h>
 
 /**
  * omap_usb2_set_comparator - links the comparator present in the sytem with

59 more quoted lines

So, if I have two of these controllers in my system, I can't create the
second phy because the name for it will be identical to the first?
That's why the phy core should handle the id, and not rely on the
drivers to set it, as they have no idea how many they have in the
system.

thanks,

greg k-h

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
Hi,

On Thursday 18 July 2013 12:50 PM, Greg KH wrote:
On Thu, Jul 18, 2013 at 12:16:10PM +0530, Kishon Vijay Abraham I wrote:
quoted
+struct phy_provider *__of_phy_provider_register(struct device *dev,
+	struct module *owner, struct phy * (*of_xlate)(struct device *dev,
+	struct of_phandle_args *args));
+struct phy_provider *__devm_of_phy_provider_register(struct device *dev,
+	struct module *owner, struct phy * (*of_xlate)(struct device *dev,
+	struct of_phandle_args *args))
+
+__of_phy_provider_register and __devm_of_phy_provider_register can be used to
+register the phy_provider and it takes device, owner and of_xlate as
+arguments. For the dt boot case, all PHY providers should use one of the above
+2 APIs to register the PHY provider.
Why do you have __ for the prefix of a public function?  Is that really
the way that OF handles this type of thing?
I have a macro of_phy_provider_register/devm_of_phy_provider_register that
calls these functions and should be used by the PHY drivers. Probably I should
make a mention of it in the Documentation.
quoted
--- /dev/null
+++ b/drivers/phy/Kconfig
@@ -0,0 +1,13 @@
+#
+# PHY
+#
+
+menuconfig GENERIC_PHY
+	tristate "PHY Subsystem"
+	help
+	  Generic PHY support.
+
+	  This framework is designed to provide a generic interface for PHY
+	  devices present in the kernel. This layer will have the generic
+	  API by which phy drivers can create PHY using the phy framework and
+	  phy users can obtain reference to the PHY.
Again, please reverse this.  The drivers that use it should select it,
not depend on it, which will then enable this option.  I will never know
if I need to enable it, and based on your follow-on patches, if I don't,
drivers that were working just fine, now disappeared from my build,
which isn't nice, and a pain to notice and fix up.
ok.
quoted
+/**
+ * phy_create() - create a new phy
+ * @dev: device that is creating the new phy
+ * @id: id of the phy
+ * @ops: function pointers for performing phy operations
+ * @label: label given to the phy
+ *
+ * Called to create a phy using phy framework.
+ */
+struct phy *phy_create(struct device *dev, u8 id, const struct phy_ops *ops,
+	const char *label)
+{
+	int ret;
+	struct phy *phy;
+
+	if (!dev) {
+		dev_WARN(dev, "no device provided for PHY\n");
+		ret = -EINVAL;
+		goto err0;
+	}
+
+	phy = kzalloc(sizeof(*phy), GFP_KERNEL);
+	if (!phy) {
+		ret = -ENOMEM;
+		goto err0;
+	}
+
+	device_initialize(&phy->dev);
+	mutex_init(&phy->mutex);
+
+	phy->dev.class = phy_class;
+	phy->dev.parent = dev;
+	phy->dev.of_node = dev->of_node;
+	phy->id = id;
+	phy->ops = ops;
+	phy->label = kstrdup(label, GFP_KERNEL);
+
+	ret = dev_set_name(&phy->dev, "%s.%d", dev_name(dev), id);

4 more quoted lines

hmm.. some PHY drivers use the id they provide to perform some of their
internal operation as in [1] (This is used only if a single PHY provider
implements multiple PHYS). Probably I'll add an option like PLATFORM_DEVID_AUTO
to give the PHY drivers an option to use auto id.

[1] ->
http://archive.arm.linux.org.uk/lurker/message/20130628.134308.4a8f7668.ca.html
quoted
+static inline int phy_pm_runtime_get(struct phy *phy)
+{
+	if (WARN(IS_ERR(phy), "Invalid PHY reference\n"))
+		return -EINVAL;
Why would phy ever not be valid and a error pointer?  And why dump the
stack if that happens, that seems really extreme.
hmm.. there might be cases where the same controller in one soc needs PHY
control and in some other soc does not need PHY control. In such cases, we
might get error pointer here.
I'll change WARN to dev_err.
quoted
+
+	if (!pm_runtime_enabled(&phy->dev))
+		return -ENOTSUPP;
+
+	return pm_runtime_get(&phy->dev);
+}
This, and the other inline functions in this .h file seem huge, why are
they inline and not in the .c file?  There's no speed issues, and it
should save space overall in the .c file.  Please move them.
ok
quoted
+static inline int phy_init(struct phy *phy)
+{
+	int ret;
+
+	ret = phy_pm_runtime_get_sync(phy);
+	if (ret < 0 && ret != -ENOTSUPP)
+		return ret;
+
+	mutex_lock(&phy->mutex);
+	if (phy->init_count++ = 0 && phy->ops->init) {
+		ret = phy->ops->init(phy);
+		if (ret < 0) {
+			dev_err(&phy->dev, "phy init failed --> %d\n", ret);
+			goto out;
+		}
+	}
+
+out:
+	mutex_unlock(&phy->mutex);
+	phy_pm_runtime_put(phy);
+	return ret;
+}
+
+static inline int phy_exit(struct phy *phy)
+{
+	int ret;
+
+	ret = phy_pm_runtime_get_sync(phy);
+	if (ret < 0 && ret != -ENOTSUPP)
+		return ret;
+
+	mutex_lock(&phy->mutex);
+	if (--phy->init_count = 0 && phy->ops->exit) {
+		ret = phy->ops->exit(phy);
+		if (ret < 0) {
+			dev_err(&phy->dev, "phy exit failed --> %d\n", ret);
+			goto out;
+		}

53 more quoted lines

Alright.

Thanks
Kishon

Re: [PATCH 02/15] usb: phy: omap-usb2: use the new generic PHY framework

Message details and related content
On Thursday 18 July 2013 12:51 PM, Greg KH wrote:
On Thu, Jul 18, 2013 at 12:16:11PM +0530, Kishon Vijay Abraham I wrote:
quoted
Used the generic PHY framework API to create the PHY. Now the power off and
power on are done in omap_usb_power_off and omap_usb_power_on respectively.

However using the old USB PHY library cannot be completely removed
because OTG is intertwined with PHY and moving to the new framework
will break OTG. Once we have a separate OTG state machine, we
can get rid of the USB PHY library.

Signed-off-by: Kishon Vijay Abraham I <redacted>
Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Acked-by: Felipe Balbi <redacted>
---
 drivers/usb/phy/Kconfig         |    1 +
 drivers/usb/phy/phy-omap-usb2.c |   45 +++++++++++++++++++++++++++++++++++----
 2 files changed, 42 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
index 3622fff..cc55993 100644
--- a/drivers/usb/phy/Kconfig
+++ b/drivers/usb/phy/Kconfig
@@ -75,6 +75,7 @@ config OMAP_CONTROL_USB
 config OMAP_USB2
 	tristate "OMAP USB2 PHY Driver"
 	depends on ARCH_OMAP2PLUS
+	depends on GENERIC_PHY
 	select OMAP_CONTROL_USB
 	help
 	  Enable this to support the transceiver that is part of SOC. This
diff --git a/drivers/usb/phy/phy-omap-usb2.c b/drivers/usb/phy/phy-omap-usb2.c
index 844ab68..751b30f 100644
--- a/drivers/usb/phy/phy-omap-usb2.c
+++ b/drivers/usb/phy/phy-omap-usb2.c
@@ -28,6 +28,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/delay.h>
 #include <linux/usb/omap_control_usb.h>
+#include <linux/phy/phy.h>
 
 /**

66 more quoted lines

hmm.. for such cases I'll have something like PLATFORM_DEVID_AUTO.

Thanks
Kishon

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Thu, Jul 18, 2013 at 02:29:52PM +0530, Kishon Vijay Abraham I wrote:
Hi,

On Thursday 18 July 2013 12:50 PM, Greg KH wrote:
quoted
On Thu, Jul 18, 2013 at 12:16:10PM +0530, Kishon Vijay Abraham I wrote:
quoted
+struct phy_provider *__of_phy_provider_register(struct device *dev,
+	struct module *owner, struct phy * (*of_xlate)(struct device *dev,
+	struct of_phandle_args *args));
+struct phy_provider *__devm_of_phy_provider_register(struct device *dev,
+	struct module *owner, struct phy * (*of_xlate)(struct device *dev,
+	struct of_phandle_args *args))
+
+__of_phy_provider_register and __devm_of_phy_provider_register can be used to
+register the phy_provider and it takes device, owner and of_xlate as
+arguments. For the dt boot case, all PHY providers should use one of the above
+2 APIs to register the PHY provider.
Why do you have __ for the prefix of a public function?  Is that really
the way that OF handles this type of thing?
I have a macro of_phy_provider_register/devm_of_phy_provider_register that
calls these functions and should be used by the PHY drivers. Probably I should
make a mention of it in the Documentation.
Yes, mention those as you never want to be calling __* functions
directly, right?
quoted
quoted
+	ret = dev_set_name(&phy->dev, "%s.%d", dev_name(dev), id);
Your naming is odd, no "phy" anywhere in it?  You rely on the sender to
never send a duplicate name.id pair?  Why not create your own ids based
on the number of phys in the system, like almost all other classes and
subsystems do?
hmm.. some PHY drivers use the id they provide to perform some of their
internal operation as in [1] (This is used only if a single PHY provider
implements multiple PHYS). Probably I'll add an option like PLATFORM_DEVID_AUTO
to give the PHY drivers an option to use auto id.

[1] ->
http://archive.arm.linux.org.uk/lurker/message/20130628.134308.4a8f7668.ca.html
No, who cares about the id?  No one outside of the phy core ever should,
because you pass back the only pointer that they really do care about,
if they need to do anything with the device.  Use that, and then you can
rip out all of the "search for a phy by a string" logic, as that's not
needed either.  Just stick to the pointer, it's easier, and safer that
way.
quoted
quoted
+static inline int phy_pm_runtime_get(struct phy *phy)
+{
+	if (WARN(IS_ERR(phy), "Invalid PHY reference\n"))
+		return -EINVAL;
Why would phy ever not be valid and a error pointer?  And why dump the
stack if that happens, that seems really extreme.
hmm.. there might be cases where the same controller in one soc needs PHY
control and in some other soc does not need PHY control. In such cases, we
might get error pointer here.
I'll change WARN to dev_err.
I still don't understand.  You have control over the code that calls
these functions, just ensure that they pass in a valid pointer, it's
that simple.  Or am I missing something?

thanks,

greg k-h

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
Hi,

On Thursday 18 July 2013 09:19 PM, Greg KH wrote:
On Thu, Jul 18, 2013 at 02:29:52PM +0530, Kishon Vijay Abraham I wrote:
quoted
Hi,

On Thursday 18 July 2013 12:50 PM, Greg KH wrote:
quoted
On Thu, Jul 18, 2013 at 12:16:10PM +0530, Kishon Vijay Abraham I wrote:
quoted
+struct phy_provider *__of_phy_provider_register(struct device *dev,
+	struct module *owner, struct phy * (*of_xlate)(struct device *dev,
+	struct of_phandle_args *args));
+struct phy_provider *__devm_of_phy_provider_register(struct device *dev,
+	struct module *owner, struct phy * (*of_xlate)(struct device *dev,
+	struct of_phandle_args *args))
+
+__of_phy_provider_register and __devm_of_phy_provider_register can be used to
+register the phy_provider and it takes device, owner and of_xlate as
+arguments. For the dt boot case, all PHY providers should use one of the above
+2 APIs to register the PHY provider.
Why do you have __ for the prefix of a public function?  Is that really
the way that OF handles this type of thing?
I have a macro of_phy_provider_register/devm_of_phy_provider_register that
calls these functions and should be used by the PHY drivers. Probably I should
make a mention of it in the Documentation.
Yes, mention those as you never want to be calling __* functions
directly, right?
correct.
quoted
quoted
quoted
+	ret = dev_set_name(&phy->dev, "%s.%d", dev_name(dev), id);
Your naming is odd, no "phy" anywhere in it?  You rely on the sender to
never send a duplicate name.id pair?  Why not create your own ids based
on the number of phys in the system, like almost all other classes and
subsystems do?
hmm.. some PHY drivers use the id they provide to perform some of their
internal operation as in [1] (This is used only if a single PHY provider
implements multiple PHYS). Probably I'll add an option like PLATFORM_DEVID_AUTO
to give the PHY drivers an option to use auto id.

[1] ->
http://archive.arm.linux.org.uk/lurker/message/20130628.134308.4a8f7668.ca.html
No, who cares about the id?  No one outside of the phy core ever should,
because you pass back the only pointer that they really do care about,
if they need to do anything with the device.  Use that, and then you can
hmm.. ok.
rip out all of the "search for a phy by a string" logic, as that's not
Actually this is needed for non-dt boot case. In the case of dt boot, we use a
phandle by which the controller can get a reference to the phy. But in the case
of non-dt boot, the controller can get a reference to the phy only by label.
needed either.  Just stick to the pointer, it's easier, and safer that
way.
quoted
quoted
quoted
+static inline int phy_pm_runtime_get(struct phy *phy)
+{
+	if (WARN(IS_ERR(phy), "Invalid PHY reference\n"))
+		return -EINVAL;
Why would phy ever not be valid and a error pointer?  And why dump the
stack if that happens, that seems really extreme.
hmm.. there might be cases where the same controller in one soc needs PHY
control and in some other soc does not need PHY control. In such cases, we
might get error pointer here.
I'll change WARN to dev_err.
I still don't understand.  You have control over the code that calls
these functions, just ensure that they pass in a valid pointer, it's
that simple.  Or am I missing something?
You are right. Valid pointer check can be done in controller code as well.

Thanks
Kishon

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Fri, Jul 19, 2013 at 11:07:10AM +0530, Kishon Vijay Abraham I wrote:
quoted
quoted
quoted
quoted
+	ret = dev_set_name(&phy->dev, "%s.%d", dev_name(dev), id);
Your naming is odd, no "phy" anywhere in it?  You rely on the sender to
never send a duplicate name.id pair?  Why not create your own ids based
on the number of phys in the system, like almost all other classes and
subsystems do?
hmm.. some PHY drivers use the id they provide to perform some of their
internal operation as in [1] (This is used only if a single PHY provider
implements multiple PHYS). Probably I'll add an option like PLATFORM_DEVID_AUTO
to give the PHY drivers an option to use auto id.

[1] ->
http://archive.arm.linux.org.uk/lurker/message/20130628.134308.4a8f7668.ca.html
No, who cares about the id?  No one outside of the phy core ever should,
because you pass back the only pointer that they really do care about,
if they need to do anything with the device.  Use that, and then you can
hmm.. ok.
quoted
rip out all of the "search for a phy by a string" logic, as that's not
Actually this is needed for non-dt boot case. In the case of dt boot, we use a
phandle by which the controller can get a reference to the phy. But in the case
of non-dt boot, the controller can get a reference to the phy only by label.
I don't understand.  They registered the phy, and got back a pointer to
it.  Why can't they save it in their local structure to use it again
later if needed?  They should never have to "ask" for the device, as the
device id might be unknown if there are multiple devices in the system.

Or am I missing something?

thanks,

greg k-h

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
Hi,

On Friday 19 July 2013 11:13 AM, Greg KH wrote:
On Fri, Jul 19, 2013 at 11:07:10AM +0530, Kishon Vijay Abraham I wrote:
quoted
quoted
quoted
quoted
quoted
+	ret = dev_set_name(&phy->dev, "%s.%d", dev_name(dev), id);
Your naming is odd, no "phy" anywhere in it?  You rely on the sender to
never send a duplicate name.id pair?  Why not create your own ids based
on the number of phys in the system, like almost all other classes and
subsystems do?
hmm.. some PHY drivers use the id they provide to perform some of their
internal operation as in [1] (This is used only if a single PHY provider
implements multiple PHYS). Probably I'll add an option like PLATFORM_DEVID_AUTO
to give the PHY drivers an option to use auto id.

[1] ->
http://archive.arm.linux.org.uk/lurker/message/20130628.134308.4a8f7668.ca.html
No, who cares about the id?  No one outside of the phy core ever should,
because you pass back the only pointer that they really do care about,
if they need to do anything with the device.  Use that, and then you can
hmm.. ok.
quoted
rip out all of the "search for a phy by a string" logic, as that's not
Actually this is needed for non-dt boot case. In the case of dt boot, we use a
phandle by which the controller can get a reference to the phy. But in the case
of non-dt boot, the controller can get a reference to the phy only by label.
I don't understand.  They registered the phy, and got back a pointer to
it.  Why can't they save it in their local structure to use it again
later if needed?  They should never have to "ask" for the device, as the
One is a *PHY provider* driver which is a driver for some PHY device. This will
use phy_create to create the phy.
The other is a *PHY consumer* driver which might be any controller driver (can
be USB/SATA/PCIE). The PHY consumer will use phy_get to get a reference to the
phy (by *phandle* in the case of dt boot and *label* in the case of non-dt boot).
device id might be unknown if there are multiple devices in the system.
I agree with you on the device id part. That need not be known to the PHY driver.

Thanks
Kishon

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Fri, Jul 19, 2013 at 11:25:44AM +0530, Kishon Vijay Abraham I wrote:
Hi,

On Friday 19 July 2013 11:13 AM, Greg KH wrote:
quoted
On Fri, Jul 19, 2013 at 11:07:10AM +0530, Kishon Vijay Abraham I wrote:
quoted
quoted
quoted
quoted
quoted
+	ret = dev_set_name(&phy->dev, "%s.%d", dev_name(dev), id);
Your naming is odd, no "phy" anywhere in it?  You rely on the sender to
never send a duplicate name.id pair?  Why not create your own ids based
on the number of phys in the system, like almost all other classes and
subsystems do?
hmm.. some PHY drivers use the id they provide to perform some of their
internal operation as in [1] (This is used only if a single PHY provider
implements multiple PHYS). Probably I'll add an option like PLATFORM_DEVID_AUTO
to give the PHY drivers an option to use auto id.

[1] ->
http://archive.arm.linux.org.uk/lurker/message/20130628.134308.4a8f7668.ca.html
No, who cares about the id?  No one outside of the phy core ever should,
because you pass back the only pointer that they really do care about,
if they need to do anything with the device.  Use that, and then you can
hmm.. ok.
quoted
rip out all of the "search for a phy by a string" logic, as that's not
Actually this is needed for non-dt boot case. In the case of dt boot, we use a
phandle by which the controller can get a reference to the phy. But in the case
of non-dt boot, the controller can get a reference to the phy only by label.
I don't understand.  They registered the phy, and got back a pointer to
it.  Why can't they save it in their local structure to use it again
later if needed?  They should never have to "ask" for the device, as the
One is a *PHY provider* driver which is a driver for some PHY device. This will
use phy_create to create the phy.
The other is a *PHY consumer* driver which might be any controller driver (can
be USB/SATA/PCIE). The PHY consumer will use phy_get to get a reference to the
phy (by *phandle* in the case of dt boot and *label* in the case of non-dt boot).

3 more quoted lines

How does a consumer know which "label" to use in a non-dt system if
there are multiple PHYs in the system?

Do you have any drivers that are non-dt using this yet?

greg k-h

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
Hi,

On Friday 19 July 2013 11:59 AM, Greg KH wrote:
On Fri, Jul 19, 2013 at 11:25:44AM +0530, Kishon Vijay Abraham I wrote:
quoted
Hi,

On Friday 19 July 2013 11:13 AM, Greg KH wrote:
quoted
On Fri, Jul 19, 2013 at 11:07:10AM +0530, Kishon Vijay Abraham I wrote:
quoted
quoted
quoted
quoted
quoted
+	ret = dev_set_name(&phy->dev, "%s.%d", dev_name(dev), id);
Your naming is odd, no "phy" anywhere in it?  You rely on the sender to
never send a duplicate name.id pair?  Why not create your own ids based
on the number of phys in the system, like almost all other classes and
subsystems do?
hmm.. some PHY drivers use the id they provide to perform some of their
internal operation as in [1] (This is used only if a single PHY provider
implements multiple PHYS). Probably I'll add an option like PLATFORM_DEVID_AUTO
to give the PHY drivers an option to use auto id.

[1] ->
http://archive.arm.linux.org.uk/lurker/message/20130628.134308.4a8f7668.ca.html
No, who cares about the id?  No one outside of the phy core ever should,
because you pass back the only pointer that they really do care about,
if they need to do anything with the device.  Use that, and then you can
hmm.. ok.
quoted
rip out all of the "search for a phy by a string" logic, as that's not
Actually this is needed for non-dt boot case. In the case of dt boot, we use a
phandle by which the controller can get a reference to the phy. But in the case
of non-dt boot, the controller can get a reference to the phy only by label.
I don't understand.  They registered the phy, and got back a pointer to
it.  Why can't they save it in their local structure to use it again
later if needed?  They should never have to "ask" for the device, as the
One is a *PHY provider* driver which is a driver for some PHY device. This will
use phy_create to create the phy.
The other is a *PHY consumer* driver which might be any controller driver (can
be USB/SATA/PCIE). The PHY consumer will use phy_get to get a reference to the

7 more quoted lines

That should be passed using platform data.
Do you have any drivers that are non-dt using this yet?
yes. tw4030 (used in OMAP3) supports non-dt.
[PATCH 04/15] ARM: OMAP: USB: Add phy binding information
[PATCH 06/15] usb: musb: omap2430: use the new generic PHY framework
of this patch series shows how it's used.

Thanks
Kishon

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On 07/19/2013 12:36 AM, Kishon Vijay Abraham I wrote:
Hi,

On Friday 19 July 2013 11:59 AM, Greg KH wrote:
quoted
On Fri, Jul 19, 2013 at 11:25:44AM +0530, Kishon Vijay Abraham I wrote:
quoted
Hi,

On Friday 19 July 2013 11:13 AM, Greg KH wrote:
quoted
On Fri, Jul 19, 2013 at 11:07:10AM +0530, Kishon Vijay Abraham I wrote:
quoted
quoted
quoted
quoted
quoted
+	ret = dev_set_name(&phy->dev, "%s.%d", dev_name(dev), id);
Your naming is odd, no "phy" anywhere in it?  You rely on the sender to
never send a duplicate name.id pair?  Why not create your own ids based
on the number of phys in the system, like almost all other classes and
subsystems do?
hmm.. some PHY drivers use the id they provide to perform some of their
internal operation as in [1] (This is used only if a single PHY provider
implements multiple PHYS). Probably I'll add an option like PLATFORM_DEVID_AUTO
to give the PHY drivers an option to use auto id.

[1] ->
http://archive.arm.linux.org.uk/lurker/message/20130628.134308.4a8f7668.ca.html
No, who cares about the id?  No one outside of the phy core ever should,
because you pass back the only pointer that they really do care about,
if they need to do anything with the device.  Use that, and then you can
hmm.. ok.
quoted
rip out all of the "search for a phy by a string" logic, as that's not
Actually this is needed for non-dt boot case. In the case of dt boot, we use a
phandle by which the controller can get a reference to the phy. But in the case
of non-dt boot, the controller can get a reference to the phy only by label.
I don't understand.  They registered the phy, and got back a pointer to
it.  Why can't they save it in their local structure to use it again
later if needed?  They should never have to "ask" for the device, as the
One is a *PHY provider* driver which is a driver for some PHY device. This will

12 more quoted lines

I don't think that's right. That's just like passing clock names in
platform data, which I believe is frowned upon.

Instead, why not take the approach that e.g. regulators have taken? Each
driver defines the names of the objects that it requires. There is a
table (registered by a board file) that has lookup key (device name,
regulator name), and the output is the regulator device (or global
regulator name).

This is almost the same way that DT works, except that in DT, the table
is represented as properties in the DT. The DT binding defines the names
of those properties, or the strings that must be in the foo-names
properties, just like a driver in non-DT Linux is going to define the
names it expects to be provided with.

That way, you don't need platform data to define the names.

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Fri, Jul 19, 2013 at 12:06:01PM +0530, Kishon Vijay Abraham I wrote:
Hi,

On Friday 19 July 2013 11:59 AM, Greg KH wrote:
quoted
On Fri, Jul 19, 2013 at 11:25:44AM +0530, Kishon Vijay Abraham I wrote:
quoted
Hi,

On Friday 19 July 2013 11:13 AM, Greg KH wrote:
quoted
On Fri, Jul 19, 2013 at 11:07:10AM +0530, Kishon Vijay Abraham I wrote:
quoted
quoted
quoted
quoted
quoted
+	ret = dev_set_name(&phy->dev, "%s.%d", dev_name(dev), id);
Your naming is odd, no "phy" anywhere in it?  You rely on the sender to
never send a duplicate name.id pair?  Why not create your own ids based
on the number of phys in the system, like almost all other classes and
subsystems do?
hmm.. some PHY drivers use the id they provide to perform some of their
internal operation as in [1] (This is used only if a single PHY provider
implements multiple PHYS). Probably I'll add an option like PLATFORM_DEVID_AUTO
to give the PHY drivers an option to use auto id.

[1] ->
http://archive.arm.linux.org.uk/lurker/message/20130628.134308.4a8f7668.ca.html
No, who cares about the id?  No one outside of the phy core ever should,
because you pass back the only pointer that they really do care about,
if they need to do anything with the device.  Use that, and then you can
hmm.. ok.
quoted
rip out all of the "search for a phy by a string" logic, as that's not
Actually this is needed for non-dt boot case. In the case of dt boot, we use a
phandle by which the controller can get a reference to the phy. But in the case
of non-dt boot, the controller can get a reference to the phy only by label.
I don't understand.  They registered the phy, and got back a pointer to
it.  Why can't they save it in their local structure to use it again
later if needed?  They should never have to "ask" for the device, as the
One is a *PHY provider* driver which is a driver for some PHY device. This will

12 more quoted lines

Ick, don't pass strings around, pass pointers.  If you have platform
data you can get to, then put the pointer there, don't use a "name".

thanks,

greg k-h

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
Hi,

On Friday 19 July 2013 09:24 PM, Stephen Warren wrote:
On 07/19/2013 12:36 AM, Kishon Vijay Abraham I wrote:
quoted
Hi,

On Friday 19 July 2013 11:59 AM, Greg KH wrote:
quoted
On Fri, Jul 19, 2013 at 11:25:44AM +0530, Kishon Vijay Abraham I wrote:
quoted
Hi,

On Friday 19 July 2013 11:13 AM, Greg KH wrote:
quoted
On Fri, Jul 19, 2013 at 11:07:10AM +0530, Kishon Vijay Abraham I wrote:
quoted
quoted
quoted
quoted
quoted
+	ret = dev_set_name(&phy->dev, "%s.%d", dev_name(dev), id);
Your naming is odd, no "phy" anywhere in it?  You rely on the sender to
never send a duplicate name.id pair?  Why not create your own ids based
on the number of phys in the system, like almost all other classes and
subsystems do?
hmm.. some PHY drivers use the id they provide to perform some of their
internal operation as in [1] (This is used only if a single PHY provider
implements multiple PHYS). Probably I'll add an option like PLATFORM_DEVID_AUTO
to give the PHY drivers an option to use auto id.

[1] ->
http://archive.arm.linux.org.uk/lurker/message/20130628.134308.4a8f7668.ca.html
No, who cares about the id?  No one outside of the phy core ever should,
because you pass back the only pointer that they really do care about,
if they need to do anything with the device.  Use that, and then you can
hmm.. ok.
quoted
rip out all of the "search for a phy by a string" logic, as that's not
Actually this is needed for non-dt boot case. In the case of dt boot, we use a
phandle by which the controller can get a reference to the phy. But in the case
of non-dt boot, the controller can get a reference to the phy only by label.
I don't understand.  They registered the phy, and got back a pointer to
it.  Why can't they save it in their local structure to use it again
later if needed?  They should never have to "ask" for the device, as the

20 more quoted lines

We were using a similar approach with USB PHY layer but things started 
breaking after the device names are created using PLATFORM_DEVID_AUTO. 
Now theres no way to reliably know the device names in advance.
Btw I had such device name binding in my v3 of this patch series [1] and 
had some discussion with Grant during that time [2].

[1] -> 
http://archive.arm.linux.org.uk/lurker/message/20130320.091200.721a6fb5.hu.html
[2] -> https://lkml.org/lkml/2013/4/22/26

Thanks
Kishon

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
Hi,

On Saturday 20 July 2013 05:20 AM, Greg KH wrote:
On Fri, Jul 19, 2013 at 12:06:01PM +0530, Kishon Vijay Abraham I wrote:
quoted
Hi,

On Friday 19 July 2013 11:59 AM, Greg KH wrote:
quoted
On Fri, Jul 19, 2013 at 11:25:44AM +0530, Kishon Vijay Abraham I wrote:
quoted
Hi,

On Friday 19 July 2013 11:13 AM, Greg KH wrote:
quoted
On Fri, Jul 19, 2013 at 11:07:10AM +0530, Kishon Vijay Abraham I wrote:
quoted
quoted
quoted
quoted
quoted
+	ret = dev_set_name(&phy->dev, "%s.%d", dev_name(dev), id);
Your naming is odd, no "phy" anywhere in it?  You rely on the sender to
never send a duplicate name.id pair?  Why not create your own ids based
on the number of phys in the system, like almost all other classes and
subsystems do?
hmm.. some PHY drivers use the id they provide to perform some of their
internal operation as in [1] (This is used only if a single PHY provider
implements multiple PHYS). Probably I'll add an option like PLATFORM_DEVID_AUTO
to give the PHY drivers an option to use auto id.

[1] ->
http://archive.arm.linux.org.uk/lurker/message/20130628.134308.4a8f7668.ca.html
No, who cares about the id?  No one outside of the phy core ever should,
because you pass back the only pointer that they really do care about,
if they need to do anything with the device.  Use that, and then you can
hmm.. ok.
quoted
rip out all of the "search for a phy by a string" logic, as that's not
Actually this is needed for non-dt boot case. In the case of dt boot, we use a
phandle by which the controller can get a reference to the phy. But in the case
of non-dt boot, the controller can get a reference to the phy only by label.
I don't understand.  They registered the phy, and got back a pointer to
it.  Why can't they save it in their local structure to use it again
later if needed?  They should never have to "ask" for the device, as the

16 more quoted lines

I don't think I understood you here :-s We wont have phy pointer when we 
create the device for the controller no?(it'll be done in board file). 
Probably I'm missing something.

Thanks
Kishon

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Sat, Jul 20, 2013 at 08:49:32AM +0530, Kishon Vijay Abraham I wrote:
Hi,

On Saturday 20 July 2013 05:20 AM, Greg KH wrote:
quoted
On Fri, Jul 19, 2013 at 12:06:01PM +0530, Kishon Vijay Abraham I wrote:
quoted
Hi,

On Friday 19 July 2013 11:59 AM, Greg KH wrote:
quoted
On Fri, Jul 19, 2013 at 11:25:44AM +0530, Kishon Vijay Abraham I wrote:
quoted
Hi,

On Friday 19 July 2013 11:13 AM, Greg KH wrote:
quoted
On Fri, Jul 19, 2013 at 11:07:10AM +0530, Kishon Vijay Abraham I wrote:
quoted
quoted
quoted
quoted
quoted
+	ret = dev_set_name(&phy->dev, "%s.%d", dev_name(dev), id);
Your naming is odd, no "phy" anywhere in it?  You rely on the sender to
never send a duplicate name.id pair?  Why not create your own ids based
on the number of phys in the system, like almost all other classes and
subsystems do?
hmm.. some PHY drivers use the id they provide to perform some of their
internal operation as in [1] (This is used only if a single PHY provider
implements multiple PHYS). Probably I'll add an option like PLATFORM_DEVID_AUTO
to give the PHY drivers an option to use auto id.

[1] ->
http://archive.arm.linux.org.uk/lurker/message/20130628.134308.4a8f7668.ca.html
No, who cares about the id?  No one outside of the phy core ever should,
because you pass back the only pointer that they really do care about,
if they need to do anything with the device.  Use that, and then you can
hmm.. ok.
quoted
rip out all of the "search for a phy by a string" logic, as that's not
Actually this is needed for non-dt boot case. In the case of dt boot, we use a
phandle by which the controller can get a reference to the phy. But in the case
of non-dt boot, the controller can get a reference to the phy only by label.
I don't understand.  They registered the phy, and got back a pointer to

23 more quoted lines

Why will you not have that pointer?  You can't rely on the "name" as the
device id will not match up, so you should be able to rely on the
pointer being in the structure that the board sets up, right?

Don't use names, especially as ids can, and will, change, that is going
to cause big problems.  Use pointers, this is C, we are supposed to be
doing that :)

thanks,

greg k-h

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Sat, 20 Jul 2013, Greg KH wrote:
quoted
quoted
quoted
That should be passed using platform data.
Ick, don't pass strings around, pass pointers.  If you have platform
data you can get to, then put the pointer there, don't use a "name".
I don't think I understood you here :-s We wont have phy pointer
when we create the device for the controller no?(it'll be done in
board file). Probably I'm missing something.
Why will you not have that pointer?  You can't rely on the "name" as the
device id will not match up, so you should be able to rely on the
pointer being in the structure that the board sets up, right?

Don't use names, especially as ids can, and will, change, that is going
to cause big problems.  Use pointers, this is C, we are supposed to be
doing that :)
Kishon, I think what Greg means is this:  The name you are using must
be stored somewhere in a data structure constructed by the board file,
right?  Or at least, associated with some data structure somehow.  
Otherwise the platform code wouldn't know which PHY hardware
corresponded to a particular name.

Greg's suggestion is that you store the address of that data structure 
in the platform data instead of storing the name string.  Have the 
consumer pass the data structure's address when it calls phy_create, 
instead of passing the name.  Then you don't have to worry about two 
PHYs accidentally ending up with the same name or any other similar 
problems.

Alan Stern

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Sat, Jul 20, 2013 at 10:32:26PM -0400, Alan Stern wrote:
On Sat, 20 Jul 2013, Greg KH wrote:
quoted
quoted
quoted
quoted
That should be passed using platform data.
Ick, don't pass strings around, pass pointers.  If you have platform
data you can get to, then put the pointer there, don't use a "name".
I don't think I understood you here :-s We wont have phy pointer
when we create the device for the controller no?(it'll be done in
board file). Probably I'm missing something.
Why will you not have that pointer?  You can't rely on the "name" as the
device id will not match up, so you should be able to rely on the
pointer being in the structure that the board sets up, right?

Don't use names, especially as ids can, and will, change, that is going
to cause big problems.  Use pointers, this is C, we are supposed to be
doing that :)
Kishon, I think what Greg means is this:  The name you are using must
be stored somewhere in a data structure constructed by the board file,
right?  Or at least, associated with some data structure somehow.  
Otherwise the platform code wouldn't know which PHY hardware
corresponded to a particular name.

Greg's suggestion is that you store the address of that data structure 
in the platform data instead of storing the name string.  Have the 
consumer pass the data structure's address when it calls phy_create, 
instead of passing the name.  Then you don't have to worry about two 
PHYs accidentally ending up with the same name or any other similar 
problems.
Close, but the issue is that whatever returns from phy_create() should
then be used, no need to call any "find" functions, as you can just use
the pointer that phy_create() returns.  Much like all other class api
functions in the kernel work.

thanks,

greg k-h

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Sat, Jul 20, 2013 at 07:59:10PM -0700, Greg KH wrote:
On Sat, Jul 20, 2013 at 10:32:26PM -0400, Alan Stern wrote:
quoted
On Sat, 20 Jul 2013, Greg KH wrote:
quoted
quoted
quoted
quoted
That should be passed using platform data.
Ick, don't pass strings around, pass pointers.  If you have platform
data you can get to, then put the pointer there, don't use a "name".
I don't think I understood you here :-s We wont have phy pointer
when we create the device for the controller no?(it'll be done in
board file). Probably I'm missing something.
Why will you not have that pointer?  You can't rely on the "name" as the
device id will not match up, so you should be able to rely on the
pointer being in the structure that the board sets up, right?

Don't use names, especially as ids can, and will, change, that is going
to cause big problems.  Use pointers, this is C, we are supposed to be
doing that :)
Kishon, I think what Greg means is this:  The name you are using must
be stored somewhere in a data structure constructed by the board file,
right?  Or at least, associated with some data structure somehow.  
Otherwise the platform code wouldn't know which PHY hardware
corresponded to a particular name.

Greg's suggestion is that you store the address of that data structure 
in the platform data instead of storing the name string.  Have the 
consumer pass the data structure's address when it calls phy_create, 
instead of passing the name.  Then you don't have to worry about two 
PHYs accidentally ending up with the same name or any other similar 
problems.
Close, but the issue is that whatever returns from phy_create() should
then be used, no need to call any "find" functions, as you can just use
the pointer that phy_create() returns.  Much like all other class api
functions in the kernel work.
I think the problem here is to connect two from the bus structure
completely independent devices. Several frameworks (ASoC, soc-camera)
had this problem and this wasn't solved until the advent of devicetrees
and their phandles.
phy_create might be called from the probe function of some i2c device
(the phy device) and the resulting pointer is then needed in some other
platform devices (the user of the phy) probe function.
The best solution we have right now is implemented in the clk framework
which uses a string matching of the device names in clk_get() (at least
in the non-dt case).

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
Hi,

On Saturday 20 of July 2013 19:59:10 Greg KH wrote:
On Sat, Jul 20, 2013 at 10:32:26PM -0400, Alan Stern wrote:
quoted
On Sat, 20 Jul 2013, Greg KH wrote:
quoted
quoted
quoted
quoted
That should be passed using platform data.
Ick, don't pass strings around, pass pointers.  If you have
platform
data you can get to, then put the pointer there, don't use a
"name".
I don't think I understood you here :-s We wont have phy pointer
when we create the device for the controller no?(it'll be done in
board file). Probably I'm missing something.
Why will you not have that pointer?  You can't rely on the "name" as
the device id will not match up, so you should be able to rely on
the pointer being in the structure that the board sets up, right?

Don't use names, especially as ids can, and will, change, that is
going
to cause big problems.  Use pointers, this is C, we are supposed to
be
doing that :)
Kishon, I think what Greg means is this:  The name you are using must
be stored somewhere in a data structure constructed by the board file,
right?  Or at least, associated with some data structure somehow.
Otherwise the platform code wouldn't know which PHY hardware
corresponded to a particular name.

Greg's suggestion is that you store the address of that data structure
in the platform data instead of storing the name string.  Have the
consumer pass the data structure's address when it calls phy_create,
instead of passing the name.  Then you don't have to worry about two
PHYs accidentally ending up with the same name or any other similar
problems.
Close, but the issue is that whatever returns from phy_create() should
then be used, no need to call any "find" functions, as you can just use
the pointer that phy_create() returns.  Much like all other class api
functions in the kernel work.
I think there is a confusion here about who registers the PHYs.

All platform code does is registering a platform/i2c/whatever device, 
which causes a driver (located in drivers/phy/) to be instantiated. Such 
drivers call phy_create(), usually in their probe() callbacks, so 
platform_code has no way (and should have no way, for the sake of 
layering) to get what phy_create() returns.

IMHO we need a lookup method for PHYs, just like for clocks, regulators, 
PWMs or even i2c busses because there are complex cases when passing just 
a name using platform data will not work. I would second what Stephen said 
[1] and define a structure doing things in a DT-like way.

Example;

[platform code]

static const struct phy_lookup my_phy_lookup[] = {
	PHY_LOOKUP("s3c-hsotg.0", "otg", "samsung-usbphy.1", "phy.2"),
	/* etc... */
};

static void my_machine_init(void)
{
	/* ... */
	phy_register_lookup(my_phy_lookup, ARRAY_SIZE(my_phy_lookup));
	/* ... */
}

/* Notice nothing stuffed in platform data. */

[provider code - samsung-usbphy driver]

static int samsung_usbphy_probe(...)
{
	/* ... */
		for (i = 0; i < PHY_COUNT; ++i) {
			usbphy->phy[i].name = "phy";
			usbphy->phy[i].id = i;

21 more lines

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
Hi,

On Sunday 21 July 2013 04:01 PM, Tomasz Figa wrote:
Hi,

On Saturday 20 of July 2013 19:59:10 Greg KH wrote:
quoted
On Sat, Jul 20, 2013 at 10:32:26PM -0400, Alan Stern wrote:
quoted
On Sat, 20 Jul 2013, Greg KH wrote:
quoted
quoted
quoted
quoted
That should be passed using platform data.
Ick, don't pass strings around, pass pointers.  If you have
platform
data you can get to, then put the pointer there, don't use a
"name".
I don't think I understood you here :-s We wont have phy pointer
when we create the device for the controller no?(it'll be done in
board file). Probably I'm missing something.
Why will you not have that pointer?  You can't rely on the "name" as
the device id will not match up, so you should be able to rely on
the pointer being in the structure that the board sets up, right?

Don't use names, especially as ids can, and will, change, that is
going
to cause big problems.  Use pointers, this is C, we are supposed to
be
doing that :)
Kishon, I think what Greg means is this:  The name you are using must
be stored somewhere in a data structure constructed by the board file,
right?  Or at least, associated with some data structure somehow.
Otherwise the platform code wouldn't know which PHY hardware
corresponded to a particular name.

Greg's suggestion is that you store the address of that data structure
in the platform data instead of storing the name string.  Have the
consumer pass the data structure's address when it calls phy_create,
instead of passing the name.  Then you don't have to worry about two
PHYs accidentally ending up with the same name or any other similar
problems.
Close, but the issue is that whatever returns from phy_create() should

11 more quoted lines

right.
IMHO we need a lookup method for PHYs, just like for clocks, regulators,
PWMs or even i2c busses because there are complex cases when passing just
a name using platform data will not work. I would second what Stephen said
[1] and define a structure doing things in a DT-like way.

Example;

[platform code]

static const struct phy_lookup my_phy_lookup[] = {
	PHY_LOOKUP("s3c-hsotg.0", "otg", "samsung-usbphy.1", "phy.2"),
The only problem here is that if *PLATFORM_DEVID_AUTO* is used while 
creating the device, the ids in the device name would change and 
PHY_LOOKUP wont be useful.

Thanks
Kishon

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Sunday 21 of July 2013 16:37:33 Kishon Vijay Abraham I wrote:
Hi,

On Sunday 21 July 2013 04:01 PM, Tomasz Figa wrote:
quoted
Hi,

On Saturday 20 of July 2013 19:59:10 Greg KH wrote:
quoted
On Sat, Jul 20, 2013 at 10:32:26PM -0400, Alan Stern wrote:
quoted
On Sat, 20 Jul 2013, Greg KH wrote:
quoted
quoted
quoted
quoted
That should be passed using platform data.
Ick, don't pass strings around, pass pointers.  If you have
platform
data you can get to, then put the pointer there, don't use a
"name".
I don't think I understood you here :-s We wont have phy pointer
when we create the device for the controller no?(it'll be done in
board file). Probably I'm missing something.
Why will you not have that pointer?  You can't rely on the "name"
as
the device id will not match up, so you should be able to rely on
the pointer being in the structure that the board sets up, right?

Don't use names, especially as ids can, and will, change, that is
going
to cause big problems.  Use pointers, this is C, we are supposed to
be
doing that :)
Kishon, I think what Greg means is this:  The name you are using
must
be stored somewhere in a data structure constructed by the board
file,
right?  Or at least, associated with some data structure somehow.
Otherwise the platform code wouldn't know which PHY hardware
corresponded to a particular name.

Greg's suggestion is that you store the address of that data
structure

40 more quoted lines

I don't think this is a problem. All the existing lookup methods already 
use ID to identify devices (see regulators, clkdev, PWMs, i2c, ...). You 
can simply add a requirement that the ID must be assigned manually, 
without using PLATFORM_DEVID_AUTO to use PHY lookup.

Best regards,
Tomasz

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Sun, Jul 21, 2013 at 01:12:07PM +0200, Tomasz Figa wrote:
On Sunday 21 of July 2013 16:37:33 Kishon Vijay Abraham I wrote:
quoted
Hi,

On Sunday 21 July 2013 04:01 PM, Tomasz Figa wrote:
quoted
Hi,

On Saturday 20 of July 2013 19:59:10 Greg KH wrote:
quoted
On Sat, Jul 20, 2013 at 10:32:26PM -0400, Alan Stern wrote:
quoted
On Sat, 20 Jul 2013, Greg KH wrote:
quoted
quoted
quoted
quoted
That should be passed using platform data.
Ick, don't pass strings around, pass pointers.  If you have
platform
data you can get to, then put the pointer there, don't use a
"name".
I don't think I understood you here :-s We wont have phy pointer
when we create the device for the controller no?(it'll be done in
board file). Probably I'm missing something.
Why will you not have that pointer?  You can't rely on the "name"
as
the device id will not match up, so you should be able to rely on
the pointer being in the structure that the board sets up, right?

Don't use names, especially as ids can, and will, change, that is
going
to cause big problems.  Use pointers, this is C, we are supposed to
be
doing that :)
Kishon, I think what Greg means is this:  The name you are using
must
be stored somewhere in a data structure constructed by the board
file,
right?  Or at least, associated with some data structure somehow.
Otherwise the platform code wouldn't know which PHY hardware
corresponded to a particular name.

Greg's suggestion is that you store the address of that data

21 more quoted lines

Why not put pointers in the platform data structure that can hold these
pointers?  I thought that is why we created those structures in the
first place.  If not, what are they there for?
quoted
quoted
IMHO we need a lookup method for PHYs, just like for clocks,
regulators, PWMs or even i2c busses because there are complex cases
when passing just a name using platform data will not work. I would
second what Stephen said [1] and define a structure doing things in a
DT-like way.

Example;

[platform code]

static const struct phy_lookup my_phy_lookup[] = {

	PHY_LOOKUP("s3c-hsotg.0", "otg", "samsung-usbphy.1", "phy.2"),
The only problem here is that if *PLATFORM_DEVID_AUTO* is used while
creating the device, the ids in the device name would change and
PHY_LOOKUP wont be useful.
I don't think this is a problem. All the existing lookup methods already 
use ID to identify devices (see regulators, clkdev, PWMs, i2c, ...). You 
can simply add a requirement that the ID must be assigned manually, 
without using PLATFORM_DEVID_AUTO to use PHY lookup.
And I'm saying that this idea, of using a specific name and id, is
frought with fragility and will break in the future in various ways when
devices get added to systems, making these strings constantly have to be
kept up to date with different board configurations.

People, NEVER, hardcode something like an id.  The fact that this
happens today with the clock code, doesn't make it right, it makes the
clock code wrong.  Others have already said that this is wrong there as
well, as systems change and dynamic ids get used more and more.

Let's not repeat the same mistakes of the past just because we refuse to
learn from them...

So again, the "find a phy by a string" functions should be removed, the
device id should be automatically created by the phy core just to make
things unique in sysfs, and no driver code should _ever_ be reliant on
the number that is being created, and the pointer to the phy structure
should be used everywhere instead.

With those types of changes, I will consider merging this subsystem, but
without them, sorry, I will not.

thanks,

greg k-h

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Sun, Jul 21, 2013 at 12:22:48PM +0200, Sascha Hauer wrote:
On Sat, Jul 20, 2013 at 07:59:10PM -0700, Greg KH wrote:
quoted
On Sat, Jul 20, 2013 at 10:32:26PM -0400, Alan Stern wrote:
quoted
On Sat, 20 Jul 2013, Greg KH wrote:
quoted
quoted
quoted
quoted
That should be passed using platform data.
Ick, don't pass strings around, pass pointers.  If you have platform
data you can get to, then put the pointer there, don't use a "name".
I don't think I understood you here :-s We wont have phy pointer
when we create the device for the controller no?(it'll be done in
board file). Probably I'm missing something.
Why will you not have that pointer?  You can't rely on the "name" as the
device id will not match up, so you should be able to rely on the
pointer being in the structure that the board sets up, right?

Don't use names, especially as ids can, and will, change, that is going
to cause big problems.  Use pointers, this is C, we are supposed to be
doing that :)
Kishon, I think what Greg means is this:  The name you are using must
be stored somewhere in a data structure constructed by the board file,
right?  Or at least, associated with some data structure somehow.  
Otherwise the platform code wouldn't know which PHY hardware
corresponded to a particular name.

Greg's suggestion is that you store the address of that data structure 
in the platform data instead of storing the name string.  Have the 
consumer pass the data structure's address when it calls phy_create, 
instead of passing the name.  Then you don't have to worry about two 
PHYs accidentally ending up with the same name or any other similar 
problems.
Close, but the issue is that whatever returns from phy_create() should
then be used, no need to call any "find" functions, as you can just use
the pointer that phy_create() returns.  Much like all other class api
functions in the kernel work.
I think the problem here is to connect two from the bus structure

9 more quoted lines

I would argue that clocks are wrong here as well, as others have already
pointed out.

What's wrong with the platform_data structure, why can't that be used
for this?

Or, if not, we can always add pointers to the platform device structure,
or even the main 'struct device' as well, that's what it is there for.

thanks,

greg k-h

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On 07/21/2013 05:48 PM, Greg KH wrote:
On Sun, Jul 21, 2013 at 12:22:48PM +0200, Sascha Hauer wrote:
quoted
On Sat, Jul 20, 2013 at 07:59:10PM -0700, Greg KH wrote:
quoted
On Sat, Jul 20, 2013 at 10:32:26PM -0400, Alan Stern wrote:
quoted
On Sat, 20 Jul 2013, Greg KH wrote:
quoted
quoted
quoted
quoted
That should be passed using platform data.
Ick, don't pass strings around, pass pointers.  If you have platform
data you can get to, then put the pointer there, don't use a "name".
I don't think I understood you here :-s We wont have phy pointer
when we create the device for the controller no?(it'll be done in
board file). Probably I'm missing something.
Why will you not have that pointer?  You can't rely on the "name" as the
device id will not match up, so you should be able to rely on the
pointer being in the structure that the board sets up, right?

Don't use names, especially as ids can, and will, change, that is going
to cause big problems.  Use pointers, this is C, we are supposed to be
doing that :)
Kishon, I think what Greg means is this:  The name you are using must
be stored somewhere in a data structure constructed by the board file,
right?  Or at least, associated with some data structure somehow.
Otherwise the platform code wouldn't know which PHY hardware
corresponded to a particular name.

Greg's suggestion is that you store the address of that data structure
in the platform data instead of storing the name string.  Have the
consumer pass the data structure's address when it calls phy_create,
instead of passing the name.  Then you don't have to worry about two
PHYs accidentally ending up with the same name or any other similar
problems.
Close, but the issue is that whatever returns from phy_create() should
then be used, no need to call any "find" functions, as you can just use
the pointer that phy_create() returns.  Much like all other class api
functions in the kernel work.

16 more quoted lines

At the point the platform data of some driver is initialized, e.g. in
board setup code the PHY pointer is not known, since the PHY supplier
driver has not initialized yet.  Even though we wanted to pass pointer
to a PHY through some notifier call, it would have been not clear
which PHY user driver should match on such notifier.  A single PHY
supplier driver can create M PHY objects and this needs to be mapped
to N PHY user drivers.  This mapping needs to be defined somewhere by
the system integrator.  It works well with device tree, but except that
there seems to be no other reliable infrastructure in the kernel to
define links/dependencies between devices, since device identifiers are
not known in advance in all cases.

What Tomasz proposed seems currently most reasonable to me for non-dt.
Or, if not, we can always add pointers to the platform device structure,
or even the main 'struct device' as well, that's what it is there for.
Still we would need to solve a problem which platform device structure
gets which PHY pointer.

--
Regards,
Sylwester

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Sun, 21 Jul 2013, Sylwester Nawrocki wrote:
quoted
What's wrong with the platform_data structure, why can't that be used
for this?
At the point the platform data of some driver is initialized, e.g. in
board setup code the PHY pointer is not known, since the PHY supplier
driver has not initialized yet.  Even though we wanted to pass pointer
to a PHY through some notifier call, it would have been not clear
which PHY user driver should match on such notifier.  A single PHY
supplier driver can create M PHY objects and this needs to be mapped
to N PHY user drivers.  This mapping needs to be defined somewhere by
the system integrator.  It works well with device tree, but except that
there seems to be no other reliable infrastructure in the kernel to
define links/dependencies between devices, since device identifiers are
not known in advance in all cases.

What Tomasz proposed seems currently most reasonable to me for non-dt.
quoted
Or, if not, we can always add pointers to the platform device structure,
or even the main 'struct device' as well, that's what it is there for.
Still we would need to solve a problem which platform device structure
gets which PHY pointer.
Can you explain the issues in more detail?  I don't fully understand 
the situation.

Here's what I think I know:

	The PHY and the controller it is attached to are both physical
	devices.

	The connection between them is hardwired by the system
	manufacturer and cannot be changed by software.

	PHYs are generally described by fixed system-specific board
	files or by Device Tree information.  Are they ever discovered
	dynamically?

	Is the same true for the controllers attached to the PHYs?
	If not -- if both a PHY and a controller are discovered 
	dynamically -- how does the kernel know whether they are 
	connected to each other?

	The kernel needs to know which controller is attached to which
	PHY.  Currently this information is represented by name or ID
	strings embedded in platform data.

	The PHY's driver (the supplier) uses the platform data to 
	construct a platform_device structure that represents the PHY.  
	Until this is done, the controller's driver (the client) cannot 
	use the PHY.

	Since there is no parent-child relation between the PHY and the 
	controller, there is no guarantee that the PHY's driver will be
	ready when the controller's driver wants to use it.  A deferred
	probe may be needed.

	The issue (or one of the issues) in this discussion is that 
	Greg does not like the idea of using names or IDs to associate
	PHYs with controllers, because they are too prone to
	duplications or other errors.  Pointers are more reliable.

11 more lines

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
Hi,

On Monday 22 July 2013 12:52 AM, Alan Stern wrote:
On Sun, 21 Jul 2013, Sylwester Nawrocki wrote:
quoted
quoted
What's wrong with the platform_data structure, why can't that be used
for this?
At the point the platform data of some driver is initialized, e.g. in
board setup code the PHY pointer is not known, since the PHY supplier
driver has not initialized yet.  Even though we wanted to pass pointer
to a PHY through some notifier call, it would have been not clear
which PHY user driver should match on such notifier.  A single PHY
supplier driver can create M PHY objects and this needs to be mapped
to N PHY user drivers.  This mapping needs to be defined somewhere by
the system integrator.  It works well with device tree, but except that
there seems to be no other reliable infrastructure in the kernel to
define links/dependencies between devices, since device identifiers are
not known in advance in all cases.

What Tomasz proposed seems currently most reasonable to me for non-dt.
quoted
Or, if not, we can always add pointers to the platform device structure,
or even the main 'struct device' as well, that's what it is there for.
Still we would need to solve a problem which platform device structure
gets which PHY pointer.
Can you explain the issues in more detail?  I don't fully understand 
the situation.

Here's what I think I know:

	The PHY and the controller it is attached to are both physical
	devices.

	The connection between them is hardwired by the system
	manufacturer and cannot be changed by software.

	PHYs are generally described by fixed system-specific board
	files or by Device Tree information.  Are they ever discovered
	dynamically?
No. They are created just like any other platform devices are created.
	Is the same true for the controllers attached to the PHYs?
	If not -- if both a PHY and a controller are discovered 
	dynamically -- how does the kernel know whether they are 
	connected to each other?
No differences here. Both PHY and controller will have dt information or hwmod
data using which platform devices will be created.
	The kernel needs to know which controller is attached to which
	PHY.  Currently this information is represented by name or ID
	strings embedded in platform data.
right. It's embedded in the platform data of the controller.
	The PHY's driver (the supplier) uses the platform data to 
	construct a platform_device structure that represents the PHY.  
Currently the driver assigns static labels (corresponding to the label used in
the platform data of the controller).
	Until this is done, the controller's driver (the client) cannot 
	use the PHY.
right.
	Since there is no parent-child relation between the PHY and the 
	controller, there is no guarantee that the PHY's driver will be
	ready when the controller's driver wants to use it.  A deferred
	probe may be needed.
right.
	The issue (or one of the issues) in this discussion is that 
	Greg does not like the idea of using names or IDs to associate
	PHYs with controllers, because they are too prone to
	duplications or other errors.  Pointers are more reliable.

	But pointers to what?  Since the only data known to be 
	available to both the PHY driver and controller driver is the
	platform data, the obvious answer is a pointer to platform data
	(either for the PHY or for the controller, or maybe both).
hmm.. it's not going to be simple though as the platform device for the PHY and
controller can be created in entirely different places. e.g., in some cases the
PHY device is a child of some mfd core device (the device will be created in
drivers/mfd) and the controller driver (usually) is created in board file. I
guess then we have to come up with something to share a pointer in two
different files.
Probably some of the details above are wrong; please indicate where I
have gone astray.  Also, I'm not clear about the role played by various 
APIs.  For example, where does phy_create() fit into this picture?
phy_create is the API by which the PHY's driver (the supplier) hook into the
PHY framework. It's like the controller driver will always interact with the
PHY driver through the PHY framework.

Thanks
Kishon

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Mon, 22 Jul 2013, Kishon Vijay Abraham I wrote:
quoted
	The PHY and the controller it is attached to are both physical
	devices.

	The connection between them is hardwired by the system
	manufacturer and cannot be changed by software.

	PHYs are generally described by fixed system-specific board
	files or by Device Tree information.  Are they ever discovered
	dynamically?
No. They are created just like any other platform devices are created.
Okay.  Are PHYs _always_ platform devices?
quoted
	Is the same true for the controllers attached to the PHYs?
	If not -- if both a PHY and a controller are discovered 
	dynamically -- how does the kernel know whether they are 
	connected to each other?
No differences here. Both PHY and controller will have dt information or hwmod
data using which platform devices will be created.
quoted
	The kernel needs to know which controller is attached to which
	PHY.  Currently this information is represented by name or ID
	strings embedded in platform data.
right. It's embedded in the platform data of the controller.
It must also be embedded in the PHY's platform data somehow.  
Otherwise, how would the kernel know which PHY to use?
quoted
	The PHY's driver (the supplier) uses the platform data to 
	construct a platform_device structure that represents the PHY.  
Currently the driver assigns static labels (corresponding to the label used in
the platform data of the controller).
quoted
	Until this is done, the controller's driver (the client) cannot 
	use the PHY.
right.
quoted
	Since there is no parent-child relation between the PHY and the 
	controller, there is no guarantee that the PHY's driver will be
	ready when the controller's driver wants to use it.  A deferred
	probe may be needed.
right.
quoted
	The issue (or one of the issues) in this discussion is that 
	Greg does not like the idea of using names or IDs to associate
	PHYs with controllers, because they are too prone to
	duplications or other errors.  Pointers are more reliable.

	But pointers to what?  Since the only data known to be 
	available to both the PHY driver and controller driver is the
	platform data, the obvious answer is a pointer to platform data
	(either for the PHY or for the controller, or maybe both).
hmm.. it's not going to be simple though as the platform device for the PHY and
controller can be created in entirely different places. e.g., in some cases the
PHY device is a child of some mfd core device (the device will be created in
drivers/mfd) and the controller driver (usually) is created in board file. I
guess then we have to come up with something to share a pointer in two
different files.
The ability for two different source files to share a pointer to a data 
item defined in a third source file has been around since long before 
the C language was invented.  :-)

In this case, it doesn't matter where the platform_device structures 
are created or where the driver source code is.  Let's take a simple 
example.  Suppose the system design includes a PHY named "foo".  Then 
the board file could contain:

struct phy_info { ... } phy_foo;
EXPORT_SYMBOL_GPL(phy_foo);

and a header file would contain:

extern struct phy_info phy_foo;

The PHY supplier could then call phy_create(&phy_foo), and the PHY 
client could call phy_find(&phy_foo).  Or something like that; make up 
your own structure tags and function names.

It's still possible to have conflicts, but now two PHYs with the same 
name (or a misspelled name somewhere) will cause an error at link time.
quoted
Probably some of the details above are wrong; please indicate where I
have gone astray.  Also, I'm not clear about the role played by various 
APIs.  For example, where does phy_create() fit into this picture?
phy_create is the API by which the PHY's driver (the supplier) hook into the
PHY framework. It's like the controller driver will always interact with the
PHY driver through the PHY framework.
Alan Stern

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Mon, Jul 22, 2013 at 12:55:18PM +0530, Kishon Vijay Abraham I wrote:
quoted
	The issue (or one of the issues) in this discussion is that 
	Greg does not like the idea of using names or IDs to associate
	PHYs with controllers, because they are too prone to
	duplications or other errors.  Pointers are more reliable.

	But pointers to what?  Since the only data known to be 
	available to both the PHY driver and controller driver is the
	platform data, the obvious answer is a pointer to platform data
	(either for the PHY or for the controller, or maybe both).
hmm.. it's not going to be simple though as the platform device for the PHY and
controller can be created in entirely different places. e.g., in some cases the
PHY device is a child of some mfd core device (the device will be created in
drivers/mfd) and the controller driver (usually) is created in board file. I
guess then we have to come up with something to share a pointer in two
different files.
What's wrong with using the platform_data structure that is unique to
all boards (see include/platform_data/ for examples)?  Isn't that what
this structure is there for?

greg k-h

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
Hi,

On Monday 22 July 2013 08:34 PM, Greg KH wrote:
On Mon, Jul 22, 2013 at 12:55:18PM +0530, Kishon Vijay Abraham I wrote:
quoted
quoted
	The issue (or one of the issues) in this discussion is that 
	Greg does not like the idea of using names or IDs to associate
	PHYs with controllers, because they are too prone to
	duplications or other errors.  Pointers are more reliable.

	But pointers to what?  Since the only data known to be 
	available to both the PHY driver and controller driver is the
	platform data, the obvious answer is a pointer to platform data
	(either for the PHY or for the controller, or maybe both).
hmm.. it's not going to be simple though as the platform device for the PHY and
controller can be created in entirely different places. e.g., in some cases the
PHY device is a child of some mfd core device (the device will be created in
drivers/mfd) and the controller driver (usually) is created in board file. I
guess then we have to come up with something to share a pointer in two
different files.
What's wrong with using the platform_data structure that is unique to
all boards (see include/platform_data/ for examples)?  Isn't that what
this structure is there for?
Alright. I got some ideas from Alan Stern. I'll use it with platform_data and
repost the series.

Thanks
Kishon

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
Hi,

On Monday 22 July 2013 08:14 PM, Alan Stern wrote:
On Mon, 22 Jul 2013, Kishon Vijay Abraham I wrote:
quoted
quoted
	The PHY and the controller it is attached to are both physical
	devices.

	The connection between them is hardwired by the system
	manufacturer and cannot be changed by software.

	PHYs are generally described by fixed system-specific board
	files or by Device Tree information.  Are they ever discovered
	dynamically?
No. They are created just like any other platform devices are created.
Okay.  Are PHYs _always_ platform devices?
Not always. It can be any other device also.
quoted
quoted
	Is the same true for the controllers attached to the PHYs?
	If not -- if both a PHY and a controller are discovered 
	dynamically -- how does the kernel know whether they are 
	connected to each other?
No differences here. Both PHY and controller will have dt information or hwmod
data using which platform devices will be created.
quoted
	The kernel needs to know which controller is attached to which
	PHY.  Currently this information is represented by name or ID
	strings embedded in platform data.
right. It's embedded in the platform data of the controller.
It must also be embedded in the PHY's platform data somehow.  
Otherwise, how would the kernel know which PHY to use?
quoted
quoted
	The PHY's driver (the supplier) uses the platform data to 
	construct a platform_device structure that represents the PHY.  
Currently the driver assigns static labels (corresponding to the label used in
the platform data of the controller).
quoted
	Until this is done, the controller's driver (the client) cannot 
	use the PHY.
right.
quoted
	Since there is no parent-child relation between the PHY and the 
	controller, there is no guarantee that the PHY's driver will be
	ready when the controller's driver wants to use it.  A deferred
	probe may be needed.
right.
quoted
	The issue (or one of the issues) in this discussion is that 
	Greg does not like the idea of using names or IDs to associate
	PHYs with controllers, because they are too prone to
	duplications or other errors.  Pointers are more reliable.

31 more quoted lines

Alright. Thanks for the hint :-)

Thanks
Kishon

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
Hi Alan,

On Monday 22 of July 2013 10:44:39 Alan Stern wrote:
On Mon, 22 Jul 2013, Kishon Vijay Abraham I wrote:
quoted
quoted
	The PHY and the controller it is attached to are both physical
	devices.
	
	The connection between them is hardwired by the system
	manufacturer and cannot be changed by software.
	
	PHYs are generally described by fixed system-specific board
	files or by Device Tree information.  Are they ever discovered
	dynamically?
No. They are created just like any other platform devices are created.
Okay.  Are PHYs _always_ platform devices?
They can be i2c, spi or any other device types as well.
quoted
quoted
	Is the same true for the controllers attached to the PHYs?
	If not -- if both a PHY and a controller are discovered
	dynamically -- how does the kernel know whether they are
	connected to each other?
No differences here. Both PHY and controller will have dt information
or hwmod data using which platform devices will be created.
quoted
	The kernel needs to know which controller is attached to which
	PHY.  Currently this information is represented by name or ID
	strings embedded in platform data.
right. It's embedded in the platform data of the controller.
It must also be embedded in the PHY's platform data somehow.
Otherwise, how would the kernel know which PHY to use?
By using a PHY lookup as Stephen and I suggested in our previous replies. 
Without any extra data in platform data. (I have even posted a code 
example.)
quoted
quoted
	The PHY's driver (the supplier) uses the platform data to
	construct a platform_device structure that represents the PHY.
Currently the driver assigns static labels (corresponding to the label
used in the platform data of the controller).
quoted
	Until this is done, the controller's driver (the client) cannot
	use the PHY.
right.
quoted
	Since there is no parent-child relation between the PHY and the
	controller, there is no guarantee that the PHY's driver will be
	ready when the controller's driver wants to use it.  A deferred
	probe may be needed.
right.
quoted
	The issue (or one of the issues) in this discussion is that
	Greg does not like the idea of using names or IDs to associate
	PHYs with controllers, because they are too prone to
	duplications or other errors.  Pointers are more reliable.
	
	But pointers to what?  Since the only data known to be
	available to both the PHY driver and controller driver is the
	platform data, the obvious answer is a pointer to platform data
	(either for the PHY or for the controller, or maybe both).
hmm.. it's not going to be simple though as the platform device for
the PHY and controller can be created in entirely different places.
e.g., in some cases the PHY device is a child of some mfd core device
(the device will be created in drivers/mfd) and the controller driver
(usually) is created in board file. I guess then we have to come up
with something to share a pointer in two different files.
The ability for two different source files to share a pointer to a data
item defined in a third source file has been around since long before
the C language was invented.  :-)

In this case, it doesn't matter where the platform_device structures

17 more quoted lines

This is incorrect, sorry. First of all it's a layering violation - you 
export random driver-specific symbols from one driver to another. Then 
imagine 4 SoCs - A, B, C, D. There are two PHY types PHY1 and PHY2 and 
there are two types of consumer drivers (e.g. USB host controllers). Now 
consider following mapping:

SoC	PHY	consumer
A	PHY1	HOST1
B	PHY1	HOST2
C	PHY2	HOST1
D	PHY2	HOST2

So we have to be able to use any of the PHYs with any of the host drivers. 
This means you would have to export symbol with the same name from both 
PHY drivers, which obviously would not work in this case, because having 
both drivers enabled (in a multiplatform aware configuration) would lead 
to linking conflict.

Best regards,
Tomasz

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
[Fixed address of devicetree mailing list and added more people on CC.]

For reference, full thread can be found under following link:
http://thread.gmane.org/gmane.linux.ports.arm.kernel/252813

Best regards,
Tomasz

On Tuesday 23 of July 2013 09:29:32 Tomasz Figa wrote:
Hi Alan,

On Monday 22 of July 2013 10:44:39 Alan Stern wrote:
quoted
On Mon, 22 Jul 2013, Kishon Vijay Abraham I wrote:
quoted
quoted
	The PHY and the controller it is attached to are both 
physical
quoted
quoted
quoted
	devices.
	
	The connection between them is hardwired by the system
	manufacturer and cannot be changed by software.
	
	PHYs are generally described by fixed system-specific 
board
quoted
quoted
quoted
	files or by Device Tree information.  Are they ever 
discovered
quoted
quoted
quoted
	dynamically?
No. They are created just like any other platform devices are
created.
Okay.  Are PHYs _always_ platform devices?
They can be i2c, spi or any other device types as well.
quoted
quoted
quoted
	Is the same true for the controllers attached to the PHYs?
	If not -- if both a PHY and a controller are discovered
	dynamically -- how does the kernel know whether they are
	connected to each other?
No differences here. Both PHY and controller will have dt
information
or hwmod data using which platform devices will be created.
quoted
	The kernel needs to know which controller is attached to 
which
quoted
quoted
quoted
	PHY.  Currently this information is represented by name or 
ID
quoted
quoted
quoted
	strings embedded in platform data.
right. It's embedded in the platform data of the controller.
It must also be embedded in the PHY's platform data somehow.
Otherwise, how would the kernel know which PHY to use?
By using a PHY lookup as Stephen and I suggested in our previous
replies. Without any extra data in platform data. (I have even posted a
code example.)
quoted
quoted
quoted
	The PHY's driver (the supplier) uses the platform data to
	construct a platform_device structure that represents the 
PHY.
quoted
quoted
Currently the driver assigns static labels (corresponding to the
label
used in the platform data of the controller).
quoted
	Until this is done, the controller's driver (the client) 
cannot
quoted
quoted
quoted
	use the PHY.
right.
quoted
	Since there is no parent-child relation between the PHY 
and the
quoted
quoted
quoted
	controller, there is no guarantee that the PHY's driver 
will be
quoted
quoted
quoted
	ready when the controller's driver wants to use it.  A 
deferred
quoted
quoted
quoted
	probe may be needed.
right.
quoted
	The issue (or one of the issues) in this discussion is 
that
quoted
quoted
quoted
	Greg does not like the idea of using names or IDs to 
associate
quoted
quoted
quoted
	PHYs with controllers, because they are too prone to
	duplications or other errors.  Pointers are more reliable.
	
	But pointers to what?  Since the only data known to be
	available to both the PHY driver and controller driver is 
the
quoted
quoted
quoted
	platform data, the obvious answer is a pointer to platform 
data
quoted
quoted
quoted
	(either for the PHY or for the controller, or maybe both).
hmm.. it's not going to be simple though as the platform device for
the PHY and controller can be created in entirely different places.
e.g., in some cases the PHY device is a child of some mfd core
device
(the device will be created in drivers/mfd) and the controller
driver
(usually) is created in board file. I guess then we have to come up
with something to share a pointer in two different files.
The ability for two different source files to share a pointer to a
data
item defined in a third source file has been around since long before
the C language was invented.  :-)

In this case, it doesn't matter where the platform_device structures
are created or where the driver source code is.  Let's take a simple
example.  Suppose the system design includes a PHY named "foo".  Then
the board file could contain:

struct phy_info { ... } phy_foo;
EXPORT_SYMBOL_GPL(phy_foo);

and a header file would contain:

extern struct phy_info phy_foo;

The PHY supplier could then call phy_create(&phy_foo), and the PHY
client could call phy_find(&phy_foo).  Or something like that; make up
your own structure tags and function names.

It's still possible to have conflicts, but now two PHYs with the same
name (or a misspelled name somewhere) will cause an error at link
time.
This is incorrect, sorry. First of all it's a layering violation - you
export random driver-specific symbols from one driver to another. Then
imagine 4 SoCs - A, B, C, D. There are two PHY types PHY1 and PHY2 and
there are two types of consumer drivers (e.g. USB host controllers). Now

16 more quoted lines

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Tue, 23 Jul 2013, Tomasz Figa wrote:
On Tuesday 23 of July 2013 09:29:32 Tomasz Figa wrote:
quoted
Hi Alan,
Thanks for helping to clarify the issues here.
quoted
quoted
Okay.  Are PHYs _always_ platform devices?
They can be i2c, spi or any other device types as well.
In those other cases, presumably there is no platform data associated
with the PHY since it isn't a platform device.  Then how does the
kernel know which controller is attached to the PHY?  Is this spelled
out in platform data associated with the PHY's i2c/spi/whatever parent?
quoted
quoted
quoted
quoted
	PHY.  Currently this information is represented by name or 
ID
quoted
quoted
quoted
quoted
	strings embedded in platform data.
right. It's embedded in the platform data of the controller.
It must also be embedded in the PHY's platform data somehow.
Otherwise, how would the kernel know which PHY to use?
By using a PHY lookup as Stephen and I suggested in our previous
replies. Without any extra data in platform data. (I have even posted a
code example.)
I don't understand, because I don't know what "a PHY lookup" does.
quoted
quoted
In this case, it doesn't matter where the platform_device structures
are created or where the driver source code is.  Let's take a simple
example.  Suppose the system design includes a PHY named "foo".  Then
the board file could contain:

struct phy_info { ... } phy_foo;
EXPORT_SYMBOL_GPL(phy_foo);

and a header file would contain:

extern struct phy_info phy_foo;

The PHY supplier could then call phy_create(&phy_foo), and the PHY
client could call phy_find(&phy_foo).  Or something like that; make up
your own structure tags and function names.

It's still possible to have conflicts, but now two PHYs with the same
name (or a misspelled name somewhere) will cause an error at link
time.
This is incorrect, sorry. First of all it's a layering violation - you
export random driver-specific symbols from one driver to another. Then
No, that's not what I said.  Neither the PHY driver nor the controller
driver exports anything to the other.  Instead, both drivers use data
exported by the board file.
quoted
imagine 4 SoCs - A, B, C, D. There are two PHY types PHY1 and PHY2 and
there are two types of consumer drivers (e.g. USB host controllers). Now
consider following mapping:

SoC	PHY	consumer
A	PHY1	HOST1
B	PHY1	HOST2
C	PHY2	HOST1
D	PHY2	HOST2

So we have to be able to use any of the PHYs with any of the host
drivers. This means you would have to export symbol with the same name
from both PHY drivers, which obviously would not work in this case,
because having both drivers enabled (in a multiplatform aware
configuration) would lead to linking conflict.
You're right; the scheme was too simple.  Instead, the board file must
export two types of data structures, one for PHYs and one for
controllers.  Like this:

struct phy_info {
	/* Info for the controller attached to this PHY */
	struct controller_info	*hinfo;
};

struct controller_info {
	/* Info for the PHY which this controller is attached to */
	struct phy_info		*pinfo;
};

The board file for SoC A would contain:

struct phy_info phy1 = {&host1);
EXPORT_SYMBOL(phy1);
struct controller_info host1 = {&phy1};
EXPORT_SYMBOL(host1);

The board file for SoC B would contain:

struct phy_info phy1 = {&host2);
EXPORT_SYMBOL(phy1);
struct controller_info host2 = {&phy1};
EXPORT_SYMBOL(host2);

And so on.  This explicitly gives the connection between PHYs and
controllers.  The PHY providers would use &phy1 or &phy2, and the PHY
consumers would use &host1 or &host2.

Alan Stern

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Tuesday 23 of July 2013 10:37:05 Alan Stern wrote:
On Tue, 23 Jul 2013, Tomasz Figa wrote:
quoted
On Tuesday 23 of July 2013 09:29:32 Tomasz Figa wrote:
quoted
Hi Alan,
Thanks for helping to clarify the issues here.
quoted
quoted
quoted
Okay.  Are PHYs _always_ platform devices?
They can be i2c, spi or any other device types as well.
In those other cases, presumably there is no platform data associated
with the PHY since it isn't a platform device.  Then how does the
kernel know which controller is attached to the PHY?  Is this spelled
out in platform data associated with the PHY's i2c/spi/whatever parent?
quoted
quoted
quoted
quoted
quoted
	PHY.  Currently this information is represented by name or
ID
quoted
quoted
quoted
quoted
	strings embedded in platform data.
right. It's embedded in the platform data of the controller.
It must also be embedded in the PHY's platform data somehow.
Otherwise, how would the kernel know which PHY to use?
By using a PHY lookup as Stephen and I suggested in our previous
replies. Without any extra data in platform data. (I have even posted
a
code example.)
I don't understand, because I don't know what "a PHY lookup" does.
I have provided a code example in [1]. Feel free to ask questions about 
those code snippets.

[1] http://thread.gmane.org/gmane.linux.ports.arm.kernel/252813/focus 889
quoted
quoted
quoted
In this case, it doesn't matter where the platform_device
structures
are created or where the driver source code is.  Let's take a
simple
example.  Suppose the system design includes a PHY named "foo". 
Then
the board file could contain:

struct phy_info { ... } phy_foo;
EXPORT_SYMBOL_GPL(phy_foo);

and a header file would contain:

extern struct phy_info phy_foo;

The PHY supplier could then call phy_create(&phy_foo), and the PHY
client could call phy_find(&phy_foo).  Or something like that; make
up
your own structure tags and function names.

It's still possible to have conflicts, but now two PHYs with the
same
name (or a misspelled name somewhere) will cause an error at link
time.
This is incorrect, sorry. First of all it's a layering violation -
you
export random driver-specific symbols from one driver to another.
Then
No, that's not what I said.  Neither the PHY driver nor the controller
driver exports anything to the other.  Instead, both drivers use data
exported by the board file.
It's still a random, driver-specific global symbol exported from board file 
to drivers.
quoted
quoted
imagine 4 SoCs - A, B, C, D. There are two PHY types PHY1 and PHY2
and
there are two types of consumer drivers (e.g. USB host controllers).
Now
consider following mapping:

SoC	PHY	consumer
A	PHY1	HOST1
B	PHY1	HOST2
C	PHY2	HOST1
D	PHY2	HOST2

So we have to be able to use any of the PHYs with any of the host
drivers. This means you would have to export symbol with the same
name
from both PHY drivers, which obviously would not work in this case,
because having both drivers enabled (in a multiplatform aware
configuration) would lead to linking conflict.
You're right; the scheme was too simple.  Instead, the board file must
export two types of data structures, one for PHYs and one for
controllers.  Like this:

struct phy_info {
	/* Info for the controller attached to this PHY */
	struct controller_info	*hinfo;
};

struct controller_info {
	/* Info for the PHY which this controller is attached to */
	struct phy_info		*pinfo;
};

The board file for SoC A would contain:

struct phy_info phy1 = {&host1);
EXPORT_SYMBOL(phy1);
struct controller_info host1 = {&phy1};
EXPORT_SYMBOL(host1);

10 more quoted lines

This could work assuming that only one SoC and one board is supported in 
single kernel image. However it's not the case.

We've used to support multiple boards since a long time already and now for 
selected platforms we even support multiplatform, i.e. multiple SoCs in 
single zImage. Such solution will not work.

Best regards,
Tomasz

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
Hi,

On Tuesday 23 July 2013 08:07 PM, Alan Stern wrote:
On Tue, 23 Jul 2013, Tomasz Figa wrote:
quoted
On Tuesday 23 of July 2013 09:29:32 Tomasz Figa wrote:
quoted
Hi Alan,
Thanks for helping to clarify the issues here.
quoted
quoted
quoted
Okay.  Are PHYs _always_ platform devices?
They can be i2c, spi or any other device types as well.
In those other cases, presumably there is no platform data associated
with the PHY since it isn't a platform device.  Then how does the
kernel know which controller is attached to the PHY?  Is this spelled
out in platform data associated with the PHY's i2c/spi/whatever parent?
Yes. I think we could use i2c_board_info for passing platform data.
quoted
quoted
quoted
quoted
quoted
	PHY.  Currently this information is represented by name or 
ID
quoted
quoted
quoted
quoted
	strings embedded in platform data.
right. It's embedded in the platform data of the controller.
It must also be embedded in the PHY's platform data somehow.
Otherwise, how would the kernel know which PHY to use?
By using a PHY lookup as Stephen and I suggested in our previous
replies. Without any extra data in platform data. (I have even posted a
code example.)
I don't understand, because I don't know what "a PHY lookup" does.
It is how the PHY framework finds a PHY, when the controller (say USB)requests
a PHY from the PHY framework.
quoted
quoted
quoted
In this case, it doesn't matter where the platform_device structures
are created or where the driver source code is.  Let's take a simple
example.  Suppose the system design includes a PHY named "foo".  Then
the board file could contain:

struct phy_info { ... } phy_foo;
EXPORT_SYMBOL_GPL(phy_foo);

and a header file would contain:

extern struct phy_info phy_foo;

The PHY supplier could then call phy_create(&phy_foo), and the PHY
client could call phy_find(&phy_foo).  Or something like that; make up
your own structure tags and function names.

It's still possible to have conflicts, but now two PHYs with the same
name (or a misspelled name somewhere) will cause an error at link
time.
This is incorrect, sorry. First of all it's a layering violation - you
export random driver-specific symbols from one driver to another. Then
No, that's not what I said.  Neither the PHY driver nor the controller
driver exports anything to the other.  Instead, both drivers use data
exported by the board file.
I think instead we can use the same data while creating the platform data of
the controller and the PHY.
The PHY driver while creating the PHY (using PHY framework) will also pass the
*data* it actually got from the platform data to the framework.
The PHY user driver (USB), while requesting for the PHY (from the PHY
framework) will pass the *data* it got from its platform data.
The PHY framework can do a comparison of the *data* pointers it has and return
the appropriate PHY to the controller.
quoted
quoted
imagine 4 SoCs - A, B, C, D. There are two PHY types PHY1 and PHY2 and
there are two types of consumer drivers (e.g. USB host controllers). Now
consider following mapping:

SoC	PHY	consumer
A	PHY1	HOST1
B	PHY1	HOST2
C	PHY2	HOST1
D	PHY2	HOST2

So we have to be able to use any of the PHYs with any of the host
drivers. This means you would have to export symbol with the same name
from both PHY drivers, which obviously would not work in this case,
because having both drivers enabled (in a multiplatform aware
configuration) would lead to linking conflict.
You're right; the scheme was too simple.  Instead, the board file must
export two types of data structures, one for PHYs and one for
controllers.  Like this:

struct phy_info {
	/* Info for the controller attached to this PHY */
	struct controller_info	*hinfo;
};

struct controller_info {
	/* Info for the PHY which this controller is attached to */
	struct phy_info		*pinfo;
};

The board file for SoC A would contain:

struct phy_info phy1 = {&host1);
EXPORT_SYMBOL(phy1);
struct controller_info host1 = {&phy1};
EXPORT_SYMBOL(host1);

The board file for SoC B would contain:

4 more quoted lines

I meant something like this
struct phy_info {
	const char *name;
};

struct phy_platform_data {
	.
	.
	struct phy_info *info;
};

struct usb_controller_platform_data {
	.
	.
	struct phy_info *info;
};

struct phy_info phy_info;

While creating the phy device
	struct phy_platform_data phy_data;
	phy_data.info = &info;
	platform_device_add_data(pdev, &phy_data, sizeof(*phy_data))
	platform_device_add();

While creating the controller device
	struct usb_controller_platform_data controller_data;
	controller_data.info = &info;
	platform_device_add_data(pdev, &controller_data, sizeof(*controller_data))
	platform_device_add();

Then modify PHY framework API phy create
	phy_create((struct device *dev, const struct phy_ops *ops,
        void *priv)  {//API changed to take void pointer instead of label
		. //existing implementation
		.
		phy->priv = priv;
	}

24 more lines

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Tue, Jul 23, 2013 at 08:48:24PM +0530, Kishon Vijay Abraham I wrote:
Hi,

On Tuesday 23 July 2013 08:07 PM, Alan Stern wrote:
quoted
On Tue, 23 Jul 2013, Tomasz Figa wrote:
quoted
On Tuesday 23 of July 2013 09:29:32 Tomasz Figa wrote:
quoted
Hi Alan,
Thanks for helping to clarify the issues here.
quoted
quoted
quoted
Okay.  Are PHYs _always_ platform devices?
They can be i2c, spi or any other device types as well.
In those other cases, presumably there is no platform data associated
with the PHY since it isn't a platform device.  Then how does the
kernel know which controller is attached to the PHY?  Is this spelled
out in platform data associated with the PHY's i2c/spi/whatever parent?
Yes. I think we could use i2c_board_info for passing platform data.
quoted
quoted
quoted
quoted
quoted
quoted
	PHY.  Currently this information is represented by name or 
ID
quoted
quoted
quoted
quoted
	strings embedded in platform data.
right. It's embedded in the platform data of the controller.
It must also be embedded in the PHY's platform data somehow.
Otherwise, how would the kernel know which PHY to use?
By using a PHY lookup as Stephen and I suggested in our previous
replies. Without any extra data in platform data. (I have even posted a
code example.)
I don't understand, because I don't know what "a PHY lookup" does.
It is how the PHY framework finds a PHY, when the controller (say USB)requests
a PHY from the PHY framework.
quoted
quoted
quoted
quoted
In this case, it doesn't matter where the platform_device structures

139 more quoted lines

Ick, no.  Why can't you just pass the pointer to the phy itself?  If you
had a "priv" pointer to search from, then you could have just passed the
original phy pointer in the first place, right?

The issue is that a string "name" is not going to scale at all, as it
requires hard-coded information that will change over time (as the
existing clock interface is already showing.)

Please just pass the real "phy" pointer around, that's what it is there
for.  Your "board binding" logic/code should be able to handle this, as
it somehow was going to do the same thing with a "name".

thanks,

greg k-h

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
Hi Greg,

On Tuesday 23 July 2013 09:48 PM, Greg KH wrote:
On Tue, Jul 23, 2013 at 08:48:24PM +0530, Kishon Vijay Abraham I wrote:
quoted
Hi,

On Tuesday 23 July 2013 08:07 PM, Alan Stern wrote:
quoted
On Tue, 23 Jul 2013, Tomasz Figa wrote:
quoted
On Tuesday 23 of July 2013 09:29:32 Tomasz Figa wrote:
quoted
Hi Alan,
Thanks for helping to clarify the issues here.
quoted
quoted
quoted
Okay.  Are PHYs _always_ platform devices?
They can be i2c, spi or any other device types as well.
In those other cases, presumably there is no platform data associated
with the PHY since it isn't a platform device.  Then how does the
kernel know which controller is attached to the PHY?  Is this spelled
out in platform data associated with the PHY's i2c/spi/whatever parent?
.
.
<snip>
.
.
quoted
	static struct phy *phy_lookup(void *priv) {
		.
		.
		if (phy->priv=priv) //instead of string comparison, we'll use pointer
			return phy;
	}

PHY driver should be like
	phy_create((dev, ops, pdata->info);

The controller driver would do
	phy_get(dev, NULL, pdata->info);

Now the PHY framework will check for a match of *priv* pointer and return the PHY.

I think this should be possible?
Ick, no.  Why can't you just pass the pointer to the phy itself?  If you
had a "priv" pointer to search from, then you could have just passed the
original phy pointer in the first place, right?

The issue is that a string "name" is not going to scale at all, as it
requires hard-coded information that will change over time (as the
existing clock interface is already showing.)

Please just pass the real "phy" pointer around, that's what it is there
for.  Your "board binding" logic/code should be able to handle this, as
it somehow was going to do the same thing with a "name".
The problem is the board file won't have the *phy* pointer. *phy* pointer is
created at a much later time when the phy driver is probed.

Thanks
Kishon

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Tue, Jul 23, 2013 at 09:58:34PM +0530, Kishon Vijay Abraham I wrote:
Hi Greg,

On Tuesday 23 July 2013 09:48 PM, Greg KH wrote:
quoted
On Tue, Jul 23, 2013 at 08:48:24PM +0530, Kishon Vijay Abraham I wrote:
quoted
Hi,

On Tuesday 23 July 2013 08:07 PM, Alan Stern wrote:
quoted
On Tue, 23 Jul 2013, Tomasz Figa wrote:
quoted
On Tuesday 23 of July 2013 09:29:32 Tomasz Figa wrote:
quoted
Hi Alan,
Thanks for helping to clarify the issues here.
quoted
quoted
quoted
Okay.  Are PHYs _always_ platform devices?
They can be i2c, spi or any other device types as well.
In those other cases, presumably there is no platform data associated
with the PHY since it isn't a platform device.  Then how does the
kernel know which controller is attached to the PHY?  Is this spelled
out in platform data associated with the PHY's i2c/spi/whatever parent?
.
.
<snip>
.
.
quoted
quoted
	static struct phy *phy_lookup(void *priv) {
		.
		.
		if (phy->priv=priv) //instead of string comparison, we'll use pointer
			return phy;
	}

PHY driver should be like
	phy_create((dev, ops, pdata->info);

The controller driver would do
	phy_get(dev, NULL, pdata->info);

19 more quoted lines

Ok, then save it then, as no one could have used it before then, right?

All I don't want to see is any "get by name/void *" functions in the
api, as that way is fragile and will break, as people have already
shown.

Just pass the real pointer around.  If that is somehow a problem, then
something larger is a problem with how board devices are tied together :)

thanks,

greg k-h

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Tuesday 23 of July 2013 09:18:46 Greg KH wrote:
On Tue, Jul 23, 2013 at 08:48:24PM +0530, Kishon Vijay Abraham I wrote:
quoted
Hi,

On Tuesday 23 July 2013 08:07 PM, Alan Stern wrote:
quoted
On Tue, 23 Jul 2013, Tomasz Figa wrote:
quoted
On Tuesday 23 of July 2013 09:29:32 Tomasz Figa wrote:
quoted
Hi Alan,
Thanks for helping to clarify the issues here.
quoted
quoted
quoted
Okay.  Are PHYs _always_ platform devices?
They can be i2c, spi or any other device types as well.
In those other cases, presumably there is no platform data associated
with the PHY since it isn't a platform device.  Then how does the
kernel know which controller is attached to the PHY?  Is this spelled
out in platform data associated with the PHY's i2c/spi/whatever
parent?
Yes. I think we could use i2c_board_info for passing platform data.
quoted
quoted
quoted
quoted
quoted
quoted
	PHY.  Currently this information is represented by name or
ID
quoted
quoted
quoted
quoted
	strings embedded in platform data.
right. It's embedded in the platform data of the controller.
It must also be embedded in the PHY's platform data somehow.
Otherwise, how would the kernel know which PHY to use?
By using a PHY lookup as Stephen and I suggested in our previous
replies. Without any extra data in platform data. (I have even
posted a
code example.)
I don't understand, because I don't know what "a PHY lookup" does.

187 more quoted lines

IMHO it would be better if you provided some code example, but let's try to 
check if I understood you correctly.

8><------------------------------------------------------------------------

[Board file]

static struct phy my_phy;

static struct platform_device phy_pdev = {
	/* ... */
	.platform_data = &my_phy;
	/* ... */
};

static struct platform_device phy_pdev = {
	/* ... */
	.platform_data = &my_phy;
	/* ... */
};

[Provider driver]

struct phy *phy = pdev->dev.platform_data;

ret = phy_create(phy);

[Consumer driver]

struct phy *phy = pdev->dev.platform_data;

ret = phy_get(&pdev->dev, phy);

------------------------------------------------------------------------><8

Is this what you mean?
The issue is that a string "name" is not going to scale at all, as it
requires hard-coded information that will change over time (as the
existing clock interface is already showing.)
I fully agree that a simple, single string will not scale even in some, not 
so uncommon cases, but there is already a lot of existing lookup solutions 
over the kernel and so there is no point in introducing another one.
Please just pass the real "phy" pointer around, that's what it is there
for.  Your "board binding" logic/code should be able to handle this, as
it somehow was going to do the same thing with a "name".
It's technically correct, but quality of this solution isn't really nice, 
because it's a layering violation (at least if I understood what you mean). 
This is because you need to have full definition of struct phy in board file 
and a structure that is used as private data in PHY core comes from 
platform code.

Best regards,
Tomasz

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Tue, Jul 23, 2013 at 06:50:29PM +0200, Tomasz Figa wrote:
quoted
Ick, no.  Why can't you just pass the pointer to the phy itself?  If you
had a "priv" pointer to search from, then you could have just passed the
original phy pointer in the first place, right?
IMHO it would be better if you provided some code example, but let's try to 
check if I understood you correctly.
It's not my code that I want to have added, so I don't have to write
examples, I just get to complain about the existing stuff :)
8><------------------------------------------------------------------------

[Board file]

static struct phy my_phy;

static struct platform_device phy_pdev = {
	/* ... */
	.platform_data = &my_phy;
	/* ... */
};

static struct platform_device phy_pdev = {
	/* ... */
	.platform_data = &my_phy;
	/* ... */
};

[Provider driver]

struct phy *phy = pdev->dev.platform_data;

ret = phy_create(phy);

[Consumer driver]

struct phy *phy = pdev->dev.platform_data;

ret = phy_get(&pdev->dev, phy);

------------------------------------------------------------------------><8

Is this what you mean?
No.  Well, kind of.  What's wrong with using the platform data structure
unique to the board to have the pointer?

For example (just randomly picking one), the ata-pxa driver would change
include/linux/platform_data/ata-pxa.h to have a phy pointer in it:

struct phy;

struct  pata_pxa_pdata {
	/* PXA DMA DREQ<0:2> pin */
	uint32_t	dma_dreq;
	/* Register shift */
	uint32_t	reg_shift;
	/* IRQ flags */
	uint32_t	irq_flags;
	/* PHY */
	struct phy	*phy;
};

Then, when you create the platform, set the phy* pointer with a call to
phy_create().  Then you can use that pointer wherever that plaform data
is available (i.e. whereever platform_data is at).
quoted
The issue is that a string "name" is not going to scale at all, as it
requires hard-coded information that will change over time (as the
existing clock interface is already showing.)
I fully agree that a simple, single string will not scale even in some, not 
so uncommon cases, but there is already a lot of existing lookup solutions 
over the kernel and so there is no point in introducing another one.
I'm trying to get _rid_ of lookup "solutions" and just use a real
pointer, as you should.  I'll go tackle those other ones after this one
is taken care of, to show how the others should be handled as well.
quoted
Please just pass the real "phy" pointer around, that's what it is there
for.  Your "board binding" logic/code should be able to handle this, as
it somehow was going to do the same thing with a "name".
It's technically correct, but quality of this solution isn't really nice, 
because it's a layering violation (at least if I understood what you mean). 
This is because you need to have full definition of struct phy in board file 
and a structure that is used as private data in PHY core comes from 
platform code.
No, just a pointer, you don't need the "full" structure until you get to
some .c code that actually manipulates the phy itself, for all other
places, you are just dealing with a pointer and a structure you never
reference.

Does that make more sense?

thanks,

greg k-h

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Tue, Jul 23, 2013 at 10:37:05AM -0400, Alan Stern wrote:
On Tue, 23 Jul 2013, Tomasz Figa wrote:
quoted
quoted
quoted
Okay.  Are PHYs _always_ platform devices?
quoted
quoted
They can be i2c, spi or any other device types as well.
In those other cases, presumably there is no platform data associated
with the PHY since it isn't a platform device.  Then how does the
kernel know which controller is attached to the PHY?  Is this spelled
out in platform data associated with the PHY's i2c/spi/whatever parent?
Platform data is nothing to do with the platform bus - it's board
specific data (ie, data for the platform) and can be done with any
device.

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Tue, Jul 23, 2013 at 10:37:11AM -0700, Greg KH wrote:
On Tue, Jul 23, 2013 at 06:50:29PM +0200, Tomasz Figa wrote:
quoted
I fully agree that a simple, single string will not scale even in some, not 
so uncommon cases, but there is already a lot of existing lookup solutions 
over the kernel and so there is no point in introducing another one.
I'm trying to get _rid_ of lookup "solutions" and just use a real
pointer, as you should.  I'll go tackle those other ones after this one
is taken care of, to show how the others should be handled as well.
What are the problems you are seeing with doing things with lookups?
Having to write platform data for everything gets old fast and the code
duplication is pretty tedious...

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Tuesday 23 of July 2013 10:37:11 Greg KH wrote:
On Tue, Jul 23, 2013 at 06:50:29PM +0200, Tomasz Figa wrote:
quoted
quoted
Ick, no.  Why can't you just pass the pointer to the phy itself?  If
you
had a "priv" pointer to search from, then you could have just passed
the
original phy pointer in the first place, right?
IMHO it would be better if you provided some code example, but let's
try to check if I understood you correctly.
It's not my code that I want to have added, so I don't have to write
examples, I just get to complain about the existing stuff :)
Still, I think that some small code snippets illustrating the idea are 
really helpful.
quoted
8><--------------------------------------------------------------------
----

[Board file]

static struct phy my_phy;

static struct platform_device phy_pdev = {

	/* ... */
	.platform_data = &my_phy;
	/* ... */

};

static struct platform_device phy_pdev = {

	/* ... */
	.platform_data = &my_phy;
	/* ... */

};

[Provider driver]

struct phy *phy = pdev->dev.platform_data;

ret = phy_create(phy);

[Consumer driver]

struct phy *phy = pdev->dev.platform_data;

ret = phy_get(&pdev->dev, phy);

-----------------------------------------------------------------------
-><8

Is this what you mean?

22 more quoted lines

Hmm? So, do you suggest to call phy_create() from board file? What phy_ops 
struct and other hardware parameters would it take?
quoted
quoted
The issue is that a string "name" is not going to scale at all, as it
requires hard-coded information that will change over time (as the
existing clock interface is already showing.)
I fully agree that a simple, single string will not scale even in some,
not so uncommon cases, but there is already a lot of existing lookup
solutions over the kernel and so there is no point in introducing
another one.
I'm trying to get _rid_ of lookup "solutions" and just use a real
pointer, as you should.  I'll go tackle those other ones after this one
is taken care of, to show how the others should be handled as well.
There was a reason for introducing lookup solutions. The reason was that in 
board file there is no way to get a pointer to something that is going to be 
created much later in time. We don't do time travel ;-).
quoted
quoted
Please just pass the real "phy" pointer around, that's what it is
there
for.  Your "board binding" logic/code should be able to handle this,
as
it somehow was going to do the same thing with a "name".
It's technically correct, but quality of this solution isn't really
nice, because it's a layering violation (at least if I understood what
you mean). This is because you need to have full definition of struct
phy in board file and a structure that is used as private data in PHY
core comes from platform code.
No, just a pointer, you don't need the "full" structure until you get to
some .c code that actually manipulates the phy itself, for all other
places, you are just dealing with a pointer and a structure you never
reference.

Does that make more sense?
Well, to the point that I think I now understood your suggestion. 
Unfortunately the suggestion alone isn't really something that can be done, 
considering how driver core and generic frameworks work.

Best regards,
Tomasz

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Tue, Jul 23, 2013 at 06:44:56PM +0100, Mark Brown wrote:
On Tue, Jul 23, 2013 at 10:37:11AM -0700, Greg KH wrote:
quoted
On Tue, Jul 23, 2013 at 06:50:29PM +0200, Tomasz Figa wrote:
quoted
quoted
I fully agree that a simple, single string will not scale even in some, not 
so uncommon cases, but there is already a lot of existing lookup solutions 
over the kernel and so there is no point in introducing another one.
quoted
I'm trying to get _rid_ of lookup "solutions" and just use a real
pointer, as you should.  I'll go tackle those other ones after this one
is taken care of, to show how the others should be handled as well.
What are the problems you are seeing with doing things with lookups?
You don't "know" the id of the device you are looking up, due to
multiple devices being in the system (dynamic ids, look back earlier in
this thread for details about that.)
Having to write platform data for everything gets old fast and the code
duplication is pretty tedious...
Adding a single pointer is "tedious"?  Where is the "name" that you are
going to lookup going to come from?  That code doesn't write itself...

thanks,

greg k-h

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Tue, Jul 23, 2013 at 07:48:11PM +0200, Tomasz Figa wrote:
On Tuesday 23 of July 2013 10:37:11 Greg KH wrote:
quoted
On Tue, Jul 23, 2013 at 06:50:29PM +0200, Tomasz Figa wrote:
quoted
quoted
Ick, no.  Why can't you just pass the pointer to the phy itself?  If
you
had a "priv" pointer to search from, then you could have just passed
the
original phy pointer in the first place, right?
IMHO it would be better if you provided some code example, but let's
try to check if I understood you correctly.
It's not my code that I want to have added, so I don't have to write
examples, I just get to complain about the existing stuff :)
Still, I think that some small code snippets illustrating the idea are 
really helpful.
quoted
quoted
8><--------------------------------------------------------------------
----

[Board file]

static struct phy my_phy;

static struct platform_device phy_pdev = {

	/* ... */
	.platform_data = &my_phy;
	/* ... */

};

static struct platform_device phy_pdev = {

	/* ... */
	.platform_data = &my_phy;
	/* ... */

};

81 more quoted lines

Ok, given that I seem to be totally confused as to exactly how the
board-specific frameworks work, I'll take your word for it.

But again, I will not accept "lookup by name" type solutions, when the
"name" is dynamic and will change.  Because you are using a "name", you
can deal with a pointer, putting it _somewhere_ in your board-specific
data structures, as you are going to need to store it anyway (hint, you
had to get that "name" from somewhere, right?)

And maybe the way that these "generic frameworks" are created is wrong,
given that you don't feel that a generic pointer can be passed to the
needed devices.  That seems like a huge problem, one that has already
been pointed out is causing issues with other subsystems.

So maybe they need to be fixed?

thanks,

greg k-h

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Tue, Jul 23, 2013 at 11:01:10AM -0700, Greg KH wrote:
On Tue, Jul 23, 2013 at 06:44:56PM +0100, Mark Brown wrote:
quoted
What are the problems you are seeing with doing things with lookups?
You don't "know" the id of the device you are looking up, due to
multiple devices being in the system (dynamic ids, look back earlier in
this thread for details about that.)
I got copied in very late so don't have most of the thread I'm afraid, 
I did try looking at web archives but didn't see a clear problem
statement.  In any case this is why the APIs doing lookups do the
lookups in the context of the requesting device - devices ask for
whatever name they use locally.
quoted
Having to write platform data for everything gets old fast and the code
duplication is pretty tedious...
Adding a single pointer is "tedious"?  Where is the "name" that you are
going to lookup going to come from?  That code doesn't write itself...
It's adding platform data in the first place that gets tedious - and of
course there's also DT and ACPI to worry about, it's not just a case of
platform data and then you're done.  Pushing the lookup into library
code means that drivers don't have to worry about any of this stuff.

For most of the APIs doing this there is a clear and unambiguous name in
the hardware that can be used (and for hardware process reasons is
unlikely to get changed).  The major exception to this is the clock API
since it is relatively rare to have clear, segregated IP level
information for IPs baked into larger chips.  The other APIs tend to be
establishing chip to chip links.

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Tue, 23 Jul 2013, Tomasz Figa wrote:
IMHO it would be better if you provided some code example, but let's try to 
check if I understood you correctly.

8><------------------------------------------------------------------------

[Board file]

static struct phy my_phy;

static struct platform_device phy_pdev = {
	/* ... */
	.platform_data = &my_phy;
	/* ... */
};

static struct platform_device phy_pdev = {
This should be controller_pdev, not phy_pdev, yes?
	/* ... */
	.platform_data = &my_phy;
	/* ... */
};

[Provider driver]

struct phy *phy = pdev->dev.platform_data;

ret = phy_create(phy);

[Consumer driver]

struct phy *phy = pdev->dev.platform_data;

ret = phy_get(&pdev->dev, phy);
Or even just phy_get(&pdev->dev), because phy_get() could be smart 
enough to to set phy = dev->platform_data.
------------------------------------------------------------------------><8

Is this what you mean?
That's what I was going to suggest too.  The struct phy is defined in
the board file, which already knows about all the PHYs that exist in
the system.  (Or perhaps it is allocated dynamically, so that when many
board files are present in the same kernel, only the entries listed in
the board file for the current system get created.)  Then the
structure's address is stored in the platform data and made available
to both the provider and the consumer.

Even though the struct phy is defined (or allocated) in the board file,
its contents don't get filled in until the PHY driver provides the
details.
It's technically correct, but quality of this solution isn't really nice, 
because it's a layering violation (at least if I understood what you mean). 
This is because you need to have full definition of struct phy in board file 
and a structure that is used as private data in PHY core comes from 
platform code.
You don't have to have a full definition in the board file.  Just a 
partial definition -- most of the contents can be filled in later, when 
the PHY driver is ready to store the private data.

It's not a layering violation for one region of the kernel to store 
private data in a structure defined by another part of the kernel.  
This happens all the time (e.g., dev_set_drvdata).

Alan Stern

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Tue, Jul 23, 2013 at 08:31:05PM +0100, Mark Brown wrote:
quoted
You don't "know" the id of the device you are looking up, due to
multiple devices being in the system (dynamic ids, look back earlier in
this thread for details about that.)
I got copied in very late so don't have most of the thread I'm afraid, 
I did try looking at web archives but didn't see a clear problem
statement.  In any case this is why the APIs doing lookups do the
lookups in the context of the requesting device - devices ask for
whatever name they use locally.
What do you mean by "locally"?

The problem with the api was that the phy core wanted a id and a name to
create a phy, and then later other code was doing a "lookup" based on
the name and id (mushed together), because it "knew" that this device
was the one it wanted.

Just like the clock api, which, for multiple devices, has proven to
cause problems.  I don't want to see us accept an api that we know has
issues in it now, I'd rather us fix it up properly.

Subsystems should be able to create ids how ever they want to, and not
rely on the code calling them to specify the names of the devices that
way, otherwise the api is just too fragile.

I think, that if you create a device, then just carry around the pointer
to that device (in this case a phy) and pass it to whatever other code
needs it.  No need to do lookups on "known names" or anything else, just
normal pointers, with no problems for multiple devices, busses, or
naming issues.
quoted
quoted
Having to write platform data for everything gets old fast and the code
duplication is pretty tedious...
quoted
Adding a single pointer is "tedious"?  Where is the "name" that you are
going to lookup going to come from?  That code doesn't write itself...
It's adding platform data in the first place that gets tedious - and of
course there's also DT and ACPI to worry about, it's not just a case of
platform data and then you're done.  Pushing the lookup into library
code means that drivers don't have to worry about any of this stuff.
I agree, so just pass around the pointer to the phy and all is good.  No
need to worry about DT or ACPI or anything else.
For most of the APIs doing this there is a clear and unambiguous name in
the hardware that can be used (and for hardware process reasons is
unlikely to get changed).  The major exception to this is the clock API
since it is relatively rare to have clear, segregated IP level
information for IPs baked into larger chips.  The other APIs tend to be
establishing chip to chip links.
The clock api is having problems with multiple "names" due to dynamic
devices from what I was told.  I want to prevent the PHY interface from
having that same issue.

thanks,

greg k-h

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Tuesday 23 of July 2013 12:44:23 Greg KH wrote:
On Tue, Jul 23, 2013 at 08:31:05PM +0100, Mark Brown wrote:
quoted
quoted
You don't "know" the id of the device you are looking up, due to
multiple devices being in the system (dynamic ids, look back earlier
in
this thread for details about that.)
I got copied in very late so don't have most of the thread I'm afraid,
I did try looking at web archives but didn't see a clear problem
statement.  In any case this is why the APIs doing lookups do the
lookups in the context of the requesting device - devices ask for
whatever name they use locally.
What do you mean by "locally"?

The problem with the api was that the phy core wanted a id and a name to
create a phy, and then later other code was doing a "lookup" based on
the name and id (mushed together), because it "knew" that this device
was the one it wanted.

Just like the clock api, which, for multiple devices, has proven to
cause problems.  I don't want to see us accept an api that we know has
issues in it now, I'd rather us fix it up properly.

Subsystems should be able to create ids how ever they want to, and not
rely on the code calling them to specify the names of the devices that
way, otherwise the api is just too fragile.

I think, that if you create a device, then just carry around the pointer
to that device (in this case a phy) and pass it to whatever other code
needs it.  No need to do lookups on "known names" or anything else,
just normal pointers, with no problems for multiple devices, busses, or
naming issues.
PHY object is not a device, it is something that a device driver creates 
(one or more instances of) when it is being probed. You don't have a clean 
way to export this PHY object to other driver, other than keeping this PHY 
on a list inside PHY core with some well-known ID (e.g. device name + 
consumer port name/index, like in regulator core) and then to use this 
well-known ID inside consumer driver as a lookup key passed to phy_get();

Actually I think for PHY case, exactly the same way as used for regulators 
might be completely fine:

1. Each PHY would have some kind of platform, non-unique name, that is 
just used to print some messages (like the platform/board name of a 
regulator).
2. Each PHY would have an array of consumers. Consumer specifier would 
consist of consumer device name and consumer port name - just like in 
regulator subsystem.
3. PHY driver receives an array of, let's say, phy_init_data inside its 
platform data that it would use to register its PHYs.
4. Consumer drivers would have constant consumer port names and wouldn't 
receive any information about PHYs from platform code.

Code example:

[Board file]

static const struct phy_consumer_data usb_20_phy0_consumers[] = {
	{
		.devname = "foo-ehci",
		.port = "usbphy",
	},
};

static const struct phy_consumer_data usb_20_phy1_consumers[] = {
	{
		.devname = "foo-otg",
		.port = "otgphy",
	},
};

55 more lines

quoted
quoted
quoted
Having to write platform data for everything gets old fast and the
code
duplication is pretty tedious...
Adding a single pointer is "tedious"?  Where is the "name" that you
are
going to lookup going to come from?  That code doesn't write
itself...
It's adding platform data in the first place that gets tedious - and
of
course there's also DT and ACPI to worry about, it's not just a case
of
platform data and then you're done.  Pushing the lookup into library
code means that drivers don't have to worry about any of this stuff.
I agree, so just pass around the pointer to the phy and all is good.  No
need to worry about DT or ACPI or anything else.
With Device Tree we don't have board files anymore. How would you pass any 
pointers between provider and consumer drivers in this case?
quoted
For most of the APIs doing this there is a clear and unambiguous name
in the hardware that can be used (and for hardware process reasons is
unlikely to get changed).  The major exception to this is the clock
API since it is relatively rare to have clear, segregated IP level
information for IPs baked into larger chips.  The other APIs tend to
be establishing chip to chip links.
The clock api is having problems with multiple "names" due to dynamic
devices from what I was told.  I want to prevent the PHY interface from
having that same issue.
Yes, the clock API has a problem related to the clock namespace being 
global for all registered clock controllers. This is not a problem with 
lookup in general, but with wrong lookup key chosen.

Best regards,
Tomasz

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Tuesday 23 of July 2013 15:36:00 Alan Stern wrote:
On Tue, 23 Jul 2013, Tomasz Figa wrote:
quoted
IMHO it would be better if you provided some code example, but let's
try to check if I understood you correctly.

8><-------------------------------------------------------------------
-----

[Board file]

static struct phy my_phy;

static struct platform_device phy_pdev = {

	/* ... */
	.platform_data = &my_phy;
	/* ... */

};

static struct platform_device phy_pdev = {
This should be controller_pdev, not phy_pdev, yes?
Right. A copy-pasto.
quoted
	/* ... */
	.platform_data = &my_phy;
	/* ... */

};

[Provider driver]

struct phy *phy = pdev->dev.platform_data;

ret = phy_create(phy);

[Consumer driver]

struct phy *phy = pdev->dev.platform_data;

ret = phy_get(&pdev->dev, phy);
Or even just phy_get(&pdev->dev), because phy_get() could be smart
enough to to set phy = dev->platform_data.
Unless you need more than one PHY in this driver...
quoted
----------------------------------------------------------------------
--><8

Is this what you mean?
That's what I was going to suggest too.  The struct phy is defined in
the board file, which already knows about all the PHYs that exist in
the system.  (Or perhaps it is allocated dynamically, so that when many
board files are present in the same kernel, only the entries listed in
the board file for the current system get created.) 
Well, such dynamic allocation is a must. We don't accept non-multiplatform 
aware code anymore, not even saying about multiboard.
Then the
structure's address is stored in the platform data and made available
to both the provider and the consumer.
Yes, technically this can work. You would still have to perform some kind 
of synchronization to make sure that the PHY bound to this structure is 
actually present. This is again technically doable (e.g. a list of 
registered struct phys inside PHY core).
Even though the struct phy is defined (or allocated) in the board file,
its contents don't get filled in until the PHY driver provides the
details.
You can't assure this. Board file is free to do whatever it wants with 
this struct. A clean solution would prevent this.
quoted
It's technically correct, but quality of this solution isn't really
nice, because it's a layering violation (at least if I understood
what you mean). This is because you need to have full definition of
struct phy in board file and a structure that is used as private data
in PHY core comes from platform code.
You don't have to have a full definition in the board file.  Just a
partial definition -- most of the contents can be filled in later, when
the PHY driver is ready to store the private data.

It's not a layering violation for one region of the kernel to store
private data in a structure defined by another part of the kernel.
This happens all the time (e.g., dev_set_drvdata).
Not really. The phy struct is something that _is_ private data of PHY 
subsystem, not something that can store private data of PHY subsystem 
(sure it can store private data of particular PHY driver, but that's 
another story) and only PHY subsystem should have access to its contents.

By the way, we need to consider other cases here as well, for example it 
would be nice to have a single phy_get() function that works for both non-
DT and DT cases to make the consumer driver not have to worry whether it's 
being probed from DT or not.

I'd suggest simply reusing the lookup method of regulator framework, just 
as I suggested here:

http://thread.gmane.org/gmane.linux.ports.arm.kernel/252813/focus1661

Best regards,
Tomasz

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Tuesday 23 of July 2013 11:04:14 Greg KH wrote:
On Tue, Jul 23, 2013 at 07:48:11PM +0200, Tomasz Figa wrote:
quoted
On Tuesday 23 of July 2013 10:37:11 Greg KH wrote:
quoted
On Tue, Jul 23, 2013 at 06:50:29PM +0200, Tomasz Figa wrote:
quoted
quoted
Ick, no.  Why can't you just pass the pointer to the phy itself?
 If
you
had a "priv" pointer to search from, then you could have just
passed
the
original phy pointer in the first place, right?
IMHO it would be better if you provided some code example, but
let's
try to check if I understood you correctly.
It's not my code that I want to have added, so I don't have to write
examples, I just get to complain about the existing stuff :)
Still, I think that some small code snippets illustrating the idea are
really helpful.
quoted
quoted
8><---------------------------------------------------------------
-----
----

[Board file]

static struct phy my_phy;

static struct platform_device phy_pdev = {

	/* ... */
	.platform_data = &my_phy;
	/* ... */

};

static struct platform_device phy_pdev = {

	/* ... */

108 more quoted lines

Well, they are working in a way that keeps separation of layers, making 
things clean. Platform code should not (well, there might exist some in 
tree hacks, but this should not be propagated) used to exchange data 
between drivers, but rather to specify board specific parameters for 
generic drivers. If drivers need to cooperate, there must be a dedicated 
interface for this, like the PHY framework Kishon is introducing here.

Sure, with platform code you can do a lot of hacky things, for example you 
can simply provide PHY callbacks inside platform_data, like it was being 
done historically, but that's just ugly.

Anyway, board files should now be rather considered a historical thing. We 
are moving towards full DT-based description on ARM systems and so board 
files and related things, like name-based lookups, statically registered 
platform devices and so one are going away. Device Tree handles such 
provider-consumer links automatically using specifiers with phandles and 
lookup by node + provider-specific specifier args, so all the problems 
with binding things together just go away.
But again, I will not accept "lookup by name" type solutions, when the
"name" is dynamic and will change.  Because you are using a "name", you
can deal with a pointer, putting it _somewhere_ in your board-specific
data structures, as you are going to need to store it anyway (hint, you
had to get that "name" from somewhere, right?)
Yes. This kind of artificial names passed to both provider and consumer 
isn't really a good way of lookup. This is just an example of bad lookup 
key, though. IMHO for a good example of lookup you should see regulator 
framework.
And maybe the way that these "generic frameworks" are created is wrong,
given that you don't feel that a generic pointer can be passed to the
needed devices.  That seems like a huge problem, one that has already
been pointed out is causing issues with other subsystems.
What problem are you talking about here? AFAIK frameworks using correctly 
designed lookup do work fine for most, if not all, people. See the 
regulator framework.
So maybe they need to be fixed?
I don't really think anything is broken here, so there is nothing to fix.

Best regards,
Tomasz

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Tue, Jul 23, 2013 at 10:07:52PM +0200, Tomasz Figa wrote:
On Tuesday 23 of July 2013 12:44:23 Greg KH wrote:
quoted
On Tue, Jul 23, 2013 at 08:31:05PM +0100, Mark Brown wrote:
quoted
quoted
You don't "know" the id of the device you are looking up, due to
multiple devices being in the system (dynamic ids, look back earlier
in
this thread for details about that.)
I got copied in very late so don't have most of the thread I'm afraid,
I did try looking at web archives but didn't see a clear problem
statement.  In any case this is why the APIs doing lookups do the
lookups in the context of the requesting device - devices ask for
whatever name they use locally.
What do you mean by "locally"?

The problem with the api was that the phy core wanted a id and a name to
create a phy, and then later other code was doing a "lookup" based on
the name and id (mushed together), because it "knew" that this device
was the one it wanted.

Just like the clock api, which, for multiple devices, has proven to
cause problems.  I don't want to see us accept an api that we know has
issues in it now, I'd rather us fix it up properly.

Subsystems should be able to create ids how ever they want to, and not
rely on the code calling them to specify the names of the devices that
way, otherwise the api is just too fragile.

I think, that if you create a device, then just carry around the pointer
to that device (in this case a phy) and pass it to whatever other code
needs it.  No need to do lookups on "known names" or anything else,
just normal pointers, with no problems for multiple devices, busses, or
naming issues.
PHY object is not a device, it is something that a device driver creates 
(one or more instances of) when it is being probed.
But you created a 'struct device' for it, so I think of it as a "device"
be it "virtual" or "real" :)
You don't have a clean way to export this PHY object to other driver,
other than keeping this PHY on a list inside PHY core with some
well-known ID (e.g. device name + consumer port name/index, like in
regulator core) and then to use this well-known ID inside consumer
driver as a lookup key passed to phy_get();

Actually I think for PHY case, exactly the same way as used for
regulators might be completely fine:

1. Each PHY would have some kind of platform, non-unique name, that is 
just used to print some messages (like the platform/board name of a 
regulator).
2. Each PHY would have an array of consumers. Consumer specifier would 
consist of consumer device name and consumer port name - just like in 
regulator subsystem.
3. PHY driver receives an array of, let's say, phy_init_data inside its 
platform data that it would use to register its PHYs.
4. Consumer drivers would have constant consumer port names and wouldn't 
receive any information about PHYs from platform code.

Code example:

[Board file]

static const struct phy_consumer_data usb_20_phy0_consumers[] = {
	{
		.devname = "foo-ehci",
		.port = "usbphy",
	},
};

static const struct phy_consumer_data usb_20_phy1_consumers[] = {
	{
		.devname = "foo-otg",
		.port = "otgphy",
	},
};

static const struct phy_init_data my_phys[] = {
	{

52 more quoted lines

That's not so bad, as long as you let the phy core use whatever name it
wants for the device when it registers it with sysfs.  Use the name you
are requesting as a "tag" or some such "hint" as to what the phy can be
looked up by.

Good luck handling duplicate "tags" :)

thanks,

greg k-h

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Tue, 23 Jul 2013, Tomasz Figa wrote:
quoted
That's what I was going to suggest too.  The struct phy is defined in
the board file, which already knows about all the PHYs that exist in
the system.  (Or perhaps it is allocated dynamically, so that when many
board files are present in the same kernel, only the entries listed in
the board file for the current system get created.) 
Well, such dynamic allocation is a must. We don't accept non-multiplatform 
aware code anymore, not even saying about multiboard.
quoted
Then the
structure's address is stored in the platform data and made available
to both the provider and the consumer.
Yes, technically this can work. You would still have to perform some kind 
of synchronization to make sure that the PHY bound to this structure is 
actually present. This is again technically doable (e.g. a list of 
registered struct phys inside PHY core).
The synchronization takes place inside phy_get.  If phy_create hasn't
been called for this structure by the time phy_get runs, phy_get will 
return an error.
quoted
Even though the struct phy is defined (or allocated) in the board file,
its contents don't get filled in until the PHY driver provides the
details.
You can't assure this. Board file is free to do whatever it wants with 
this struct. A clean solution would prevent this.
I'm not sure what you mean here.  Of course I can't prevent a board 
file from messing up a data structure.  I can't prevent it from causing 
memory access violations either; in fact, I can't prevent any bugs in 
other people's code.

Besides, why do you say the board file is free to do whatever it wants 
with the struct phy?  Currently the struct phy is created by the PHY 
provider and the PHY core, right?  It's not even mentioned in the board 
file.
quoted
quoted
It's technically correct, but quality of this solution isn't really
nice, because it's a layering violation (at least if I understood
what you mean). This is because you need to have full definition of
struct phy in board file and a structure that is used as private data
in PHY core comes from platform code.
You don't have to have a full definition in the board file.  Just a
partial definition -- most of the contents can be filled in later, when
the PHY driver is ready to store the private data.

It's not a layering violation for one region of the kernel to store
private data in a structure defined by another part of the kernel.
This happens all the time (e.g., dev_set_drvdata).
Not really. The phy struct is something that _is_ private data of PHY 
subsystem, not something that can store private data of PHY subsystem 
(sure it can store private data of particular PHY driver, but that's 
another story) and only PHY subsystem should have access to its contents.
If you want to keep the phy struct completely separate from the board
file, there's an easy way to do it.  Let's say the board file knows
about N different PHYs in the system.  Then you define an array of N
pointers to phys:

struct phy *(phy_address[N]);

In the platform data for both PHY j and its controller, store
&phy_address[j].  The PHY provider passes this cookie to phy_create:

	cookie = pdev->dev.platform_data;
	ret = phy_create(phy, cookie);

and phy_create simply stores: *cookie = phy.  The PHY consumer does
much the same the same thing:

	cookie = pdev->dev.platform_data;
	phy = phy_get(cookie);

phy_get returns *cookie if it isn't NULL, or an ERR_PTR otherwise.
By the way, we need to consider other cases here as well, for example it 
would be nice to have a single phy_get() function that works for both non-
DT and DT cases to make the consumer driver not have to worry whether it's 
being probed from DT or not.
You ought to be able to adapt this scheme to work with DT.  Maybe by 
having multiple "phy_address" arrays.

Alan Stern

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Tuesday 23 of July 2013 16:53:55 Alan Stern wrote:
On Tue, 23 Jul 2013, Tomasz Figa wrote:
quoted
quoted
That's what I was going to suggest too.  The struct phy is defined
in
the board file, which already knows about all the PHYs that exist in
the system.  (Or perhaps it is allocated dynamically, so that when
many
board files are present in the same kernel, only the entries listed
in
the board file for the current system get created.)
Well, such dynamic allocation is a must. We don't accept
non-multiplatform aware code anymore, not even saying about
multiboard.
quoted
Then the
structure's address is stored in the platform data and made
available
to both the provider and the consumer.
Yes, technically this can work. You would still have to perform some
kind of synchronization to make sure that the PHY bound to this
structure is actually present. This is again technically doable (e.g.
a list of registered struct phys inside PHY core).
The synchronization takes place inside phy_get.  If phy_create hasn't
been called for this structure by the time phy_get runs, phy_get will
return an error.
Yes, this is the solution that I had in mind when saying that this is 
doable.
quoted
quoted
Even though the struct phy is defined (or allocated) in the board
file,
its contents don't get filled in until the PHY driver provides the
details.
You can't assure this. Board file is free to do whatever it wants with
this struct. A clean solution would prevent this.
I'm not sure what you mean here.  Of course I can't prevent a board
file from messing up a data structure.  I can't prevent it from causing
memory access violations either; in fact, I can't prevent any bugs in
other people's code.

Besides, why do you say the board file is free to do whatever it wants
with the struct phy?  Currently the struct phy is created by the PHY
provider and the PHY core, right?  It's not even mentioned in the board
file.
I mean, if you have a struct type of which full declaration is available 
for some code, this code can access any memeber of it without any hacks, 
which is not something that we want to have in board files. The phy struct 
should be opaque for them.
quoted
quoted
quoted
It's technically correct, but quality of this solution isn't
really
nice, because it's a layering violation (at least if I understood
what you mean). This is because you need to have full definition
of
struct phy in board file and a structure that is used as private
data
in PHY core comes from platform code.
You don't have to have a full definition in the board file.  Just a
partial definition -- most of the contents can be filled in later,
when
the PHY driver is ready to store the private data.

It's not a layering violation for one region of the kernel to store
private data in a structure defined by another part of the kernel.
This happens all the time (e.g., dev_set_drvdata).
Not really. The phy struct is something that _is_ private data of PHY
subsystem, not something that can store private data of PHY subsystem
(sure it can store private data of particular PHY driver, but that's
another story) and only PHY subsystem should have access to its
contents.
If you want to keep the phy struct completely separate from the board
file, there's an easy way to do it.  Let's say the board file knows
about N different PHYs in the system.  Then you define an array of N
pointers to phys:

struct phy *(phy_address[N]);

In the platform data for both PHY j and its controller, store
&phy_address[j].  The PHY provider passes this cookie to phy_create:

	cookie = pdev->dev.platform_data;
	ret = phy_create(phy, cookie);

and phy_create simply stores: *cookie = phy.  The PHY consumer does
much the same the same thing:

	cookie = pdev->dev.platform_data;

3 more quoted lines

OK, this can work. Again, just technically, because it's rather ugly.
quoted
By the way, we need to consider other cases here as well, for example
it would be nice to have a single phy_get() function that works for
both non- DT and DT cases to make the consumer driver not have to
worry whether it's being probed from DT or not.
You ought to be able to adapt this scheme to work with DT.  Maybe by
having multiple "phy_address" arrays.
Where would you want to have those phy_address arrays stored? There are no 
board files when booting with DT. Not even saying that you don't need to 
use any hacky schemes like this when you have DT that nicely specifies 
relations between devices.

Anyway, board file should not be considered as a method to exchange data 
between drivers. It should be used only to pass data from it to drivers, 
not the other way. Ideally all data in a board file should be marked as 
const and __init and dropped after system initialization.

Best regards,
Tomasz

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Tuesday 23 of July 2013 13:50:07 Greg KH wrote:
On Tue, Jul 23, 2013 at 10:07:52PM +0200, Tomasz Figa wrote:
quoted
On Tuesday 23 of July 2013 12:44:23 Greg KH wrote:
quoted
On Tue, Jul 23, 2013 at 08:31:05PM +0100, Mark Brown wrote:
quoted
quoted
You don't "know" the id of the device you are looking up, due to
multiple devices being in the system (dynamic ids, look back
earlier
in
this thread for details about that.)
I got copied in very late so don't have most of the thread I'm
afraid,
I did try looking at web archives but didn't see a clear problem
statement.  In any case this is why the APIs doing lookups do the
lookups in the context of the requesting device - devices ask for
whatever name they use locally.
What do you mean by "locally"?

The problem with the api was that the phy core wanted a id and a
name to create a phy, and then later other code was doing a
"lookup" based on the name and id (mushed together), because it
"knew" that this device was the one it wanted.

Just like the clock api, which, for multiple devices, has proven to
cause problems.  I don't want to see us accept an api that we know
has
issues in it now, I'd rather us fix it up properly.

Subsystems should be able to create ids how ever they want to, and
not
rely on the code calling them to specify the names of the devices
that
way, otherwise the api is just too fragile.

I think, that if you create a device, then just carry around the
pointer to that device (in this case a phy) and pass it to whatever
other code needs it.  No need to do lookups on "known names" or
anything else, just normal pointers, with no problems for multiple
devices, busses, or naming issues.

5 more quoted lines

Keep in mind that those virtual devices are created by PHY driver bound to 
a real device and one real device can have multiple virtual devices behind 
it.
quoted
You don't have a clean way to export this PHY object to other driver,
other than keeping this PHY on a list inside PHY core with some
well-known ID (e.g. device name + consumer port name/index, like in
regulator core) and then to use this well-known ID inside consumer
driver as a lookup key passed to phy_get();

Actually I think for PHY case, exactly the same way as used for
regulators might be completely fine:

1. Each PHY would have some kind of platform, non-unique name, that is
just used to print some messages (like the platform/board name of a
regulator).
2. Each PHY would have an array of consumers. Consumer specifier would
consist of consumer device name and consumer port name - just like in
regulator subsystem.
3. PHY driver receives an array of, let's say, phy_init_data inside
its
platform data that it would use to register its PHYs.
4. Consumer drivers would have constant consumer port names and
wouldn't receive any information about PHYs from platform code.

Code example:

[Board file]

static const struct phy_consumer_data usb_20_phy0_consumers[] = {

	{
	
		.devname = "foo-ehci",
		.port = "usbphy",
	
	},

};

static const struct phy_consumer_data usb_20_phy1_consumers[] = {

	{
	

82 more quoted lines

Yes, in regulator core consumer names are completely separated from this. 
Regulator core simply assigns a sequential integer ID to each regulator 
and registers /sys/class/regulator/regulator.ID for each regulator.
Use the name you
are requesting as a "tag" or some such "hint" as to what the phy can be
looked up by.

Good luck handling duplicate "tags" :)
The tag alone is not a key. Lookup key consists of two components, 
consumer device name and consumer tag. What kind of duplicate tags can be 
a problem here?

Best regards,
Tomasz

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Tue, 23 Jul 2013, Tomasz Figa wrote:
quoted
If you want to keep the phy struct completely separate from the board
file, there's an easy way to do it.  Let's say the board file knows
about N different PHYs in the system.  Then you define an array of N
pointers to phys:

struct phy *(phy_address[N]);

In the platform data for both PHY j and its controller, store
&phy_address[j].  The PHY provider passes this cookie to phy_create:

	cookie = pdev->dev.platform_data;
	ret = phy_create(phy, cookie);

and phy_create simply stores: *cookie = phy.  The PHY consumer does
much the same the same thing:

	cookie = pdev->dev.platform_data;
	phy = phy_get(cookie);

phy_get returns *cookie if it isn't NULL, or an ERR_PTR otherwise.
OK, this can work. Again, just technically, because it's rather ugly.
There's no reason the phy_address things have to be arrays.  A separate
individual pointer for each PHY would work just as well.
Where would you want to have those phy_address arrays stored? There are no 
board files when booting with DT. Not even saying that you don't need to 
use any hacky schemes like this when you have DT that nicely specifies 
relations between devices.
If everybody agrees DT has a nice scheme for specifying relations
between devices, why not use that same scheme in the PHY core?
Anyway, board file should not be considered as a method to exchange data 
between drivers. It should be used only to pass data from it to drivers, 
not the other way. Ideally all data in a board file should be marked as 
const and __init and dropped after system initialization.
The phy_address things don't have to be defined or allocated in the 
board file; they could be set up along with the platform data.

In any case, this was simply meant to be a suggestion to show that it 
is relatively easy to do what you need without using name or ID 
strings.

Alan Stern

Re: [PATCH 01/15] drivers: phy: add generic PHY framework

Message details and related content
On Tue, Jul 23, 2013 at 11:05:48PM +0200, Tomasz Figa wrote:
quoted
That's not so bad, as long as you let the phy core use whatever name it
wants for the device when it registers it with sysfs.
Yes, in regulator core consumer names are completely separated from this. 
Regulator core simply assigns a sequential integer ID to each regulator 
and registers /sys/class/regulator/regulator.ID for each regulator.
Yes, that's fine.
quoted
Use the name you
are requesting as a "tag" or some such "hint" as to what the phy can be
looked up by.

Good luck handling duplicate "tags" :)
The tag alone is not a key. Lookup key consists of two components, 
consumer device name and consumer tag. What kind of duplicate tags can be 
a problem here?
Ok, I didn't realize it looked at both parts, that makes sense, thanks.

greg k-h
Keyboard shortcuts
hback out one level
jnext message in thread / next series-diff position
kprevious message in thread / previous series-diff position
ldrill in
Escclose help / fold thread tree
?toggle this help