2014-11-19 15:28:28

by Heikki Krogerus

[permalink] [raw]
Subject: [PATCHv5 0/7] phy: simplified phy lookup

This set will in practice just separate the creation of a phy and
binding of it to the consumer. Mapping phys to consumers can be now
done with lookups similarly how clocks can be mapped in clkdev.c.

Vivek needs to handle the phys of dwc3 also in xhci driver on
Exynos5420 SoC, so I'm resending these now.

Changes since v4:
- Support for static lookups is dropped. The lookups can be now only
be created with phy_create_lookup()

Changes since v3:
- We can't rely on the order in which the phys are registered, so
using the name of the parent of the phy instance for matching
instead of the phy itself. The parent device is always the actual
physical device.
- Using PHY_LOOKUP macro in twl-common.c as suggested by Kishon.

Changes since v2:
- Calling ida_simple_remove in release function as pointed out by Greg


Heikki Krogerus (7):
phy: safer to_phy() macro
phy: improved lookup method
phy: twl4030: use the new lookup method
arm: omap3: twl: remove usb phy init data
phy: remove the old lookup method
base: platform: name the device already during allocation
usb: dwc3: host: convey the PHYs to xhci

Documentation/phy.txt | 60 ++++++--------------
arch/arm/mach-omap2/twl-common.c | 12 +---
drivers/base/platform.c | 69 +++++++++++++----------
drivers/phy/phy-bcm-kona-usb2.c | 2 +-
drivers/phy/phy-berlin-sata.c | 2 +-
drivers/phy/phy-core.c | 105 ++++++++++++++++++++++++-----------
drivers/phy/phy-exynos-dp-video.c | 2 +-
drivers/phy/phy-exynos-mipi-video.c | 2 +-
drivers/phy/phy-exynos5-usbdrd.c | 3 +-
drivers/phy/phy-exynos5250-sata.c | 2 +-
drivers/phy/phy-hix5hd2-sata.c | 2 +-
drivers/phy/phy-miphy365x.c | 2 +-
drivers/phy/phy-mvebu-sata.c | 2 +-
drivers/phy/phy-omap-usb2.c | 2 +-
drivers/phy/phy-qcom-apq8064-sata.c | 3 +-
drivers/phy/phy-qcom-ipq806x-sata.c | 3 +-
drivers/phy/phy-rcar-gen2.c | 2 +-
drivers/phy/phy-samsung-usb2.c | 3 +-
drivers/phy/phy-spear1310-miphy.c | 2 +-
drivers/phy/phy-spear1340-miphy.c | 2 +-
drivers/phy/phy-stih407-usb.c | 2 +-
drivers/phy/phy-stih41x-usb.c | 2 +-
drivers/phy/phy-sun4i-usb.c | 2 +-
drivers/phy/phy-ti-pipe3.c | 2 +-
drivers/phy/phy-twl4030-usb.c | 9 ++-
drivers/phy/phy-xgene.c | 2 +-
drivers/pinctrl/pinctrl-tegra-xusb.c | 4 +-
drivers/usb/dwc3/host.c | 22 ++++++--
include/linux/i2c/twl.h | 2 -
include/linux/phy/phy.h | 52 +++++++----------
30 files changed, 195 insertions(+), 186 deletions(-)

--
2.1.3


2014-11-19 15:28:32

by Heikki Krogerus

[permalink] [raw]
Subject: [PATCHv5 1/7] phy: safer to_phy() macro

This makes to_phy() macro work with other variable names
besides "dev".

Signed-off-by: Heikki Krogerus <[email protected]>
Tested-by: Vivek Gautam <[email protected]>
Acked-by: Felipe Balbi <[email protected]>
---
include/linux/phy/phy.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index 8cb6f81..9fda683 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -110,7 +110,7 @@ struct phy_init_data {
.port = _port, \
}

-#define to_phy(dev) (container_of((dev), struct phy, dev))
+#define to_phy(a) (container_of((a), struct phy, dev))

#define of_phy_provider_register(dev, xlate) \
__of_phy_provider_register((dev), THIS_MODULE, (xlate))
--
2.1.3

2014-11-19 15:28:35

by Heikki Krogerus

[permalink] [raw]
Subject: [PATCHv5 3/7] phy: twl4030: use the new lookup method

Creates the lookup separately. Hard coding the consumer as
it can't be anything else except musb.

Signed-off-by: Heikki Krogerus <[email protected]>
---
drivers/phy/phy-twl4030-usb.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c
index e2698d29..0d20fe0 100644
--- a/drivers/phy/phy-twl4030-usb.c
+++ b/drivers/phy/phy-twl4030-usb.c
@@ -644,7 +644,6 @@ static int twl4030_usb_probe(struct platform_device *pdev)
struct usb_otg *otg;
struct device_node *np = pdev->dev.of_node;
struct phy_provider *phy_provider;
- struct phy_init_data *init_data = NULL;

twl = devm_kzalloc(&pdev->dev, sizeof(*twl), GFP_KERNEL);
if (!twl)
@@ -655,7 +654,6 @@ static int twl4030_usb_probe(struct platform_device *pdev)
(enum twl4030_usb_mode *)&twl->usb_mode);
else if (pdata) {
twl->usb_mode = pdata->usb_mode;
- init_data = pdata->init_data;
} else {
dev_err(&pdev->dev, "twl4030 initialized without pdata\n");
return -EINVAL;
@@ -680,7 +678,7 @@ static int twl4030_usb_probe(struct platform_device *pdev)
otg->set_host = twl4030_set_host;
otg->set_peripheral = twl4030_set_peripheral;

- phy = devm_phy_create(twl->dev, NULL, &ops, init_data);
+ phy = devm_phy_create(twl->dev, NULL, &ops, NULL);
if (IS_ERR(phy)) {
dev_dbg(&pdev->dev, "Failed to create PHY\n");
return PTR_ERR(phy);
@@ -733,6 +731,11 @@ static int twl4030_usb_probe(struct platform_device *pdev)
return status;
}

+ if (pdata)
+ err = phy_create_lookup(phy, "usb", "musb-hdrc.0");
+ if (err)
+ return err;
+
pm_runtime_mark_last_busy(&pdev->dev);
pm_runtime_put_autosuspend(twl->dev);

--
2.1.3

2014-11-19 15:28:42

by Heikki Krogerus

[permalink] [raw]
Subject: [PATCHv5 5/7] phy: remove the old lookup method

The users of the old method are now converted to the new one.

Signed-off-by: Heikki Krogerus <[email protected]>
---
drivers/phy/phy-bcm-kona-usb2.c | 2 +-
drivers/phy/phy-berlin-sata.c | 2 +-
drivers/phy/phy-core.c | 49 +++---------------------------------
drivers/phy/phy-exynos-dp-video.c | 2 +-
drivers/phy/phy-exynos-mipi-video.c | 2 +-
drivers/phy/phy-exynos5-usbdrd.c | 3 +--
drivers/phy/phy-exynos5250-sata.c | 2 +-
drivers/phy/phy-hix5hd2-sata.c | 2 +-
drivers/phy/phy-miphy365x.c | 2 +-
drivers/phy/phy-mvebu-sata.c | 2 +-
drivers/phy/phy-omap-usb2.c | 2 +-
drivers/phy/phy-qcom-apq8064-sata.c | 3 +--
drivers/phy/phy-qcom-ipq806x-sata.c | 3 +--
drivers/phy/phy-rcar-gen2.c | 2 +-
drivers/phy/phy-samsung-usb2.c | 3 +--
drivers/phy/phy-spear1310-miphy.c | 2 +-
drivers/phy/phy-spear1340-miphy.c | 2 +-
drivers/phy/phy-stih407-usb.c | 2 +-
drivers/phy/phy-stih41x-usb.c | 2 +-
drivers/phy/phy-sun4i-usb.c | 2 +-
drivers/phy/phy-ti-pipe3.c | 2 +-
drivers/phy/phy-twl4030-usb.c | 2 +-
drivers/phy/phy-xgene.c | 2 +-
drivers/pinctrl/pinctrl-tegra-xusb.c | 4 +--
include/linux/phy/phy.h | 38 +++-------------------------
25 files changed, 32 insertions(+), 107 deletions(-)

diff --git a/drivers/phy/phy-bcm-kona-usb2.c b/drivers/phy/phy-bcm-kona-usb2.c
index c1e0ca3..ef2dc1a 100644
--- a/drivers/phy/phy-bcm-kona-usb2.c
+++ b/drivers/phy/phy-bcm-kona-usb2.c
@@ -117,7 +117,7 @@ static int bcm_kona_usb2_probe(struct platform_device *pdev)

platform_set_drvdata(pdev, phy);

- gphy = devm_phy_create(dev, NULL, &ops, NULL);
+ gphy = devm_phy_create(dev, NULL, &ops);
if (IS_ERR(gphy))
return PTR_ERR(gphy);

diff --git a/drivers/phy/phy-berlin-sata.c b/drivers/phy/phy-berlin-sata.c
index 69ced52..99bbf91 100644
--- a/drivers/phy/phy-berlin-sata.c
+++ b/drivers/phy/phy-berlin-sata.c
@@ -239,7 +239,7 @@ static int phy_berlin_sata_probe(struct platform_device *pdev)
if (!phy_desc)
return -ENOMEM;

- phy = devm_phy_create(dev, NULL, &phy_berlin_sata_ops, NULL);
+ phy = devm_phy_create(dev, NULL, &phy_berlin_sata_ops);
if (IS_ERR(phy)) {
dev_err(dev, "failed to create PHY %d\n", phy_id);
return PTR_ERR(phy);
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index 9c3f0dc..e7d93f2 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -55,36 +55,6 @@ static int devm_phy_match(struct device *dev, void *res, void *match_data)
return res == match_data;
}

-static struct phy *phy_lookup(struct device *device, const char *port)
-{
- unsigned int count;
- struct phy *phy;
- struct device *dev;
- struct phy_consumer *consumers;
- 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 (!phy->init_data)
- continue;
- count = phy->init_data->num_consumers;
- consumers = phy->init_data->consumers;
- while (count--) {
- if (!strcmp(consumers->dev_name, dev_name(device)) &&
- !strcmp(consumers->port, port)) {
- class_dev_iter_exit(&iter);
- return phy;
- }
- consumers++;
- }
- }
-
- class_dev_iter_exit(&iter);
- return ERR_PTR(-ENODEV);
-}
-
/**
* phy_create_lookup() - allocate and register PHY/device association
* @phy: the phy of the association
@@ -148,7 +118,6 @@ static struct phy *phy_find(struct device *dev, const char *con_id)
{
const char *dev_id = dev_name(dev);
struct phy_lookup *p, *pl = NULL;
- struct phy *phy;

mutex_lock(&phy_provider_mutex);
list_for_each_entry(p, &phys, node)
@@ -158,12 +127,7 @@ static struct phy *phy_find(struct device *dev, const char *con_id)
}
mutex_unlock(&phy_provider_mutex);

- phy = pl ? pl->phy : ERR_PTR(-ENODEV);
-
- /* fall-back to the old lookup method for now */
- if (IS_ERR(phy))
- phy = phy_lookup(dev, con_id);
- return phy;
+ return pl ? pl->phy : ERR_PTR(-ENODEV);
}

static struct phy_provider *of_phy_provider_lookup(struct device_node *node)
@@ -670,13 +634,11 @@ EXPORT_SYMBOL_GPL(devm_of_phy_get);
* @dev: device that is creating the new phy
* @node: device node of the phy
* @ops: function pointers for performing phy operations
- * @init_data: contains the list of PHY consumers or NULL
*
* Called to create a phy using phy framework.
*/
struct phy *phy_create(struct device *dev, struct device_node *node,
- const struct phy_ops *ops,
- struct phy_init_data *init_data)
+ const struct phy_ops *ops)
{
int ret;
int id;
@@ -714,7 +676,6 @@ struct phy *phy_create(struct device *dev, struct device_node *node,
phy->dev.of_node = node ?: dev->of_node;
phy->id = id;
phy->ops = ops;
- phy->init_data = init_data;

ret = dev_set_name(&phy->dev, "phy-%s.%d", dev_name(dev), id);
if (ret)
@@ -749,7 +710,6 @@ EXPORT_SYMBOL_GPL(phy_create);
* @dev: device that is creating the new phy
* @node: device node of the phy
* @ops: function pointers for performing phy operations
- * @init_data: contains the list of PHY consumers or NULL
*
* Creates a new PHY device adding it to the PHY class.
* While at that, it also associates the device with the phy using devres.
@@ -757,8 +717,7 @@ EXPORT_SYMBOL_GPL(phy_create);
* then, devres data is freed.
*/
struct phy *devm_phy_create(struct device *dev, struct device_node *node,
- const struct phy_ops *ops,
- struct phy_init_data *init_data)
+ const struct phy_ops *ops)
{
struct phy **ptr, *phy;

@@ -766,7 +725,7 @@ struct phy *devm_phy_create(struct device *dev, struct device_node *node,
if (!ptr)
return ERR_PTR(-ENOMEM);

- phy = phy_create(dev, node, ops, init_data);
+ phy = phy_create(dev, node, ops);
if (!IS_ERR(phy)) {
*ptr = phy;
devres_add(dev, ptr);
diff --git a/drivers/phy/phy-exynos-dp-video.c b/drivers/phy/phy-exynos-dp-video.c
index 84f49e5..f86cbe6 100644
--- a/drivers/phy/phy-exynos-dp-video.c
+++ b/drivers/phy/phy-exynos-dp-video.c
@@ -112,7 +112,7 @@ static int exynos_dp_video_phy_probe(struct platform_device *pdev)
match = of_match_node(exynos_dp_video_phy_of_match, dev->of_node);
state->drvdata = match->data;

- phy = devm_phy_create(dev, NULL, &exynos_dp_video_phy_ops, NULL);
+ phy = devm_phy_create(dev, NULL, &exynos_dp_video_phy_ops);
if (IS_ERR(phy)) {
dev_err(dev, "failed to create Display Port PHY\n");
return PTR_ERR(phy);
diff --git a/drivers/phy/phy-exynos-mipi-video.c b/drivers/phy/phy-exynos-mipi-video.c
index 6a9bef1..943e0f8 100644
--- a/drivers/phy/phy-exynos-mipi-video.c
+++ b/drivers/phy/phy-exynos-mipi-video.c
@@ -137,7 +137,7 @@ static int exynos_mipi_video_phy_probe(struct platform_device *pdev)

for (i = 0; i < EXYNOS_MIPI_PHYS_NUM; i++) {
struct phy *phy = devm_phy_create(dev, NULL,
- &exynos_mipi_video_phy_ops, NULL);
+ &exynos_mipi_video_phy_ops);
if (IS_ERR(phy)) {
dev_err(dev, "failed to create PHY %d\n", i);
return PTR_ERR(phy);
diff --git a/drivers/phy/phy-exynos5-usbdrd.c b/drivers/phy/phy-exynos5-usbdrd.c
index f756aca..b3ca3bc 100644
--- a/drivers/phy/phy-exynos5-usbdrd.c
+++ b/drivers/phy/phy-exynos5-usbdrd.c
@@ -637,8 +637,7 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev)

for (i = 0; i < EXYNOS5_DRDPHYS_NUM; i++) {
struct phy *phy = devm_phy_create(dev, NULL,
- &exynos5_usbdrd_phy_ops,
- NULL);
+ &exynos5_usbdrd_phy_ops);
if (IS_ERR(phy)) {
dev_err(dev, "Failed to create usbdrd_phy phy\n");
return PTR_ERR(phy);
diff --git a/drivers/phy/phy-exynos5250-sata.c b/drivers/phy/phy-exynos5250-sata.c
index 54cf4ae..bc858cc 100644
--- a/drivers/phy/phy-exynos5250-sata.c
+++ b/drivers/phy/phy-exynos5250-sata.c
@@ -210,7 +210,7 @@ static int exynos_sata_phy_probe(struct platform_device *pdev)
return ret;
}

- sata_phy->phy = devm_phy_create(dev, NULL, &exynos_sata_phy_ops, NULL);
+ sata_phy->phy = devm_phy_create(dev, NULL, &exynos_sata_phy_ops);
if (IS_ERR(sata_phy->phy)) {
clk_disable_unprepare(sata_phy->phyclk);
dev_err(dev, "failed to create PHY\n");
diff --git a/drivers/phy/phy-hix5hd2-sata.c b/drivers/phy/phy-hix5hd2-sata.c
index d5d9780..a80ff9d 100644
--- a/drivers/phy/phy-hix5hd2-sata.c
+++ b/drivers/phy/phy-hix5hd2-sata.c
@@ -156,7 +156,7 @@ static int hix5hd2_sata_phy_probe(struct platform_device *pdev)
if (IS_ERR(priv->peri_ctrl))
priv->peri_ctrl = NULL;

- phy = devm_phy_create(dev, NULL, &hix5hd2_sata_phy_ops, NULL);
+ phy = devm_phy_create(dev, NULL, &hix5hd2_sata_phy_ops);
if (IS_ERR(phy)) {
dev_err(dev, "failed to create PHY\n");
return PTR_ERR(phy);
diff --git a/drivers/phy/phy-miphy365x.c b/drivers/phy/phy-miphy365x.c
index 801afaf..239930e 100644
--- a/drivers/phy/phy-miphy365x.c
+++ b/drivers/phy/phy-miphy365x.c
@@ -593,7 +593,7 @@ static int miphy365x_probe(struct platform_device *pdev)

miphy_dev->phys[port] = miphy_phy;

- phy = devm_phy_create(&pdev->dev, child, &miphy365x_ops, NULL);
+ phy = devm_phy_create(&pdev->dev, child, &miphy365x_ops);
if (IS_ERR(phy)) {
dev_err(&pdev->dev, "failed to create PHY\n");
return PTR_ERR(phy);
diff --git a/drivers/phy/phy-mvebu-sata.c b/drivers/phy/phy-mvebu-sata.c
index d395558..03b94f9 100644
--- a/drivers/phy/phy-mvebu-sata.c
+++ b/drivers/phy/phy-mvebu-sata.c
@@ -101,7 +101,7 @@ static int phy_mvebu_sata_probe(struct platform_device *pdev)
if (IS_ERR(priv->clk))
return PTR_ERR(priv->clk);

- phy = devm_phy_create(&pdev->dev, NULL, &phy_mvebu_sata_ops, NULL);
+ phy = devm_phy_create(&pdev->dev, NULL, &phy_mvebu_sata_ops);
if (IS_ERR(phy))
return PTR_ERR(phy);

diff --git a/drivers/phy/phy-omap-usb2.c b/drivers/phy/phy-omap-usb2.c
index 08f2da2..4e489a8 100644
--- a/drivers/phy/phy-omap-usb2.c
+++ b/drivers/phy/phy-omap-usb2.c
@@ -256,7 +256,7 @@ static int omap_usb2_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, phy);
pm_runtime_enable(phy->dev);

- generic_phy = devm_phy_create(phy->dev, NULL, &ops, NULL);
+ generic_phy = devm_phy_create(phy->dev, NULL, &ops);
if (IS_ERR(generic_phy)) {
pm_runtime_disable(phy->dev);
return PTR_ERR(generic_phy);
diff --git a/drivers/phy/phy-qcom-apq8064-sata.c b/drivers/phy/phy-qcom-apq8064-sata.c
index 7b3ddfb..4b243f7 100644
--- a/drivers/phy/phy-qcom-apq8064-sata.c
+++ b/drivers/phy/phy-qcom-apq8064-sata.c
@@ -228,8 +228,7 @@ static int qcom_apq8064_sata_phy_probe(struct platform_device *pdev)
if (IS_ERR(phy->mmio))
return PTR_ERR(phy->mmio);

- generic_phy = devm_phy_create(dev, NULL, &qcom_apq8064_sata_phy_ops,
- NULL);
+ generic_phy = devm_phy_create(dev, NULL, &qcom_apq8064_sata_phy_ops);
if (IS_ERR(generic_phy)) {
dev_err(dev, "%s: failed to create phy\n", __func__);
return PTR_ERR(generic_phy);
diff --git a/drivers/phy/phy-qcom-ipq806x-sata.c b/drivers/phy/phy-qcom-ipq806x-sata.c
index 759b0bf..6f2fe26 100644
--- a/drivers/phy/phy-qcom-ipq806x-sata.c
+++ b/drivers/phy/phy-qcom-ipq806x-sata.c
@@ -150,8 +150,7 @@ static int qcom_ipq806x_sata_phy_probe(struct platform_device *pdev)
if (IS_ERR(phy->mmio))
return PTR_ERR(phy->mmio);

- generic_phy = devm_phy_create(dev, NULL, &qcom_ipq806x_sata_phy_ops,
- NULL);
+ generic_phy = devm_phy_create(dev, NULL, &qcom_ipq806x_sata_phy_ops);
if (IS_ERR(generic_phy)) {
dev_err(dev, "%s: failed to create phy\n", __func__);
return PTR_ERR(generic_phy);
diff --git a/drivers/phy/phy-rcar-gen2.c b/drivers/phy/phy-rcar-gen2.c
index 2793af1..778276a 100644
--- a/drivers/phy/phy-rcar-gen2.c
+++ b/drivers/phy/phy-rcar-gen2.c
@@ -304,7 +304,7 @@ static int rcar_gen2_phy_probe(struct platform_device *pdev)
phy->select_value = select_value[channel_num][n];

phy->phy = devm_phy_create(dev, NULL,
- &rcar_gen2_phy_ops, NULL);
+ &rcar_gen2_phy_ops);
if (IS_ERR(phy->phy)) {
dev_err(dev, "Failed to create PHY\n");
return PTR_ERR(phy->phy);
diff --git a/drivers/phy/phy-samsung-usb2.c b/drivers/phy/phy-samsung-usb2.c
index 908949d..4a12f66 100644
--- a/drivers/phy/phy-samsung-usb2.c
+++ b/drivers/phy/phy-samsung-usb2.c
@@ -202,8 +202,7 @@ static int samsung_usb2_phy_probe(struct platform_device *pdev)
struct samsung_usb2_phy_instance *p = &drv->instances[i];

dev_dbg(dev, "Creating phy \"%s\"\n", label);
- p->phy = devm_phy_create(dev, NULL, &samsung_usb2_phy_ops,
- NULL);
+ p->phy = devm_phy_create(dev, NULL, &samsung_usb2_phy_ops);
if (IS_ERR(p->phy)) {
dev_err(drv->dev, "Failed to create usb2_phy \"%s\"\n",
label);
diff --git a/drivers/phy/phy-spear1310-miphy.c b/drivers/phy/phy-spear1310-miphy.c
index 5f4c586..9f47fae 100644
--- a/drivers/phy/phy-spear1310-miphy.c
+++ b/drivers/phy/phy-spear1310-miphy.c
@@ -227,7 +227,7 @@ static int spear1310_miphy_probe(struct platform_device *pdev)
return -EINVAL;
}

- priv->phy = devm_phy_create(dev, NULL, &spear1310_miphy_ops, NULL);
+ priv->phy = devm_phy_create(dev, NULL, &spear1310_miphy_ops);
if (IS_ERR(priv->phy)) {
dev_err(dev, "failed to create SATA PCIe PHY\n");
return PTR_ERR(priv->phy);
diff --git a/drivers/phy/phy-spear1340-miphy.c b/drivers/phy/phy-spear1340-miphy.c
index 1ecd094..e42bc20 100644
--- a/drivers/phy/phy-spear1340-miphy.c
+++ b/drivers/phy/phy-spear1340-miphy.c
@@ -259,7 +259,7 @@ static int spear1340_miphy_probe(struct platform_device *pdev)
return PTR_ERR(priv->misc);
}

- priv->phy = devm_phy_create(dev, NULL, &spear1340_miphy_ops, NULL);
+ priv->phy = devm_phy_create(dev, NULL, &spear1340_miphy_ops);
if (IS_ERR(priv->phy)) {
dev_err(dev, "failed to create SATA PCIe PHY\n");
return PTR_ERR(priv->phy);
diff --git a/drivers/phy/phy-stih407-usb.c b/drivers/phy/phy-stih407-usb.c
index 42428d4..74f0fab 100644
--- a/drivers/phy/phy-stih407-usb.c
+++ b/drivers/phy/phy-stih407-usb.c
@@ -137,7 +137,7 @@ static int stih407_usb2_picophy_probe(struct platform_device *pdev)
}
phy_dev->param = res->start;

- phy = devm_phy_create(dev, NULL, &stih407_usb2_picophy_data, NULL);
+ phy = devm_phy_create(dev, NULL, &stih407_usb2_picophy_data);
if (IS_ERR(phy)) {
dev_err(dev, "failed to create Display Port PHY\n");
return PTR_ERR(phy);
diff --git a/drivers/phy/phy-stih41x-usb.c b/drivers/phy/phy-stih41x-usb.c
index 9f16cb8..4ab581e 100644
--- a/drivers/phy/phy-stih41x-usb.c
+++ b/drivers/phy/phy-stih41x-usb.c
@@ -148,7 +148,7 @@ static int stih41x_usb_phy_probe(struct platform_device *pdev)
return PTR_ERR(phy_dev->clk);
}

- phy = devm_phy_create(dev, NULL, &stih41x_usb_phy_ops, NULL);
+ phy = devm_phy_create(dev, NULL, &stih41x_usb_phy_ops);

if (IS_ERR(phy)) {
dev_err(dev, "failed to create phy\n");
diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c
index 0baf5ef..28df50d 100644
--- a/drivers/phy/phy-sun4i-usb.c
+++ b/drivers/phy/phy-sun4i-usb.c
@@ -295,7 +295,7 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
return PTR_ERR(phy->pmu);
}

- phy->phy = devm_phy_create(dev, NULL, &sun4i_usb_phy_ops, NULL);
+ phy->phy = devm_phy_create(dev, NULL, &sun4i_usb_phy_ops);
if (IS_ERR(phy->phy)) {
dev_err(dev, "failed to create PHY %d\n", i);
return PTR_ERR(phy->phy);
diff --git a/drivers/phy/phy-ti-pipe3.c b/drivers/phy/phy-ti-pipe3.c
index ab1e22d..c297b7a 100644
--- a/drivers/phy/phy-ti-pipe3.c
+++ b/drivers/phy/phy-ti-pipe3.c
@@ -399,7 +399,7 @@ static int ti_pipe3_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, phy);
pm_runtime_enable(phy->dev);

- generic_phy = devm_phy_create(phy->dev, NULL, &ops, NULL);
+ generic_phy = devm_phy_create(phy->dev, NULL, &ops);
if (IS_ERR(generic_phy))
return PTR_ERR(generic_phy);

diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c
index 0d20fe0..8e87f54 100644
--- a/drivers/phy/phy-twl4030-usb.c
+++ b/drivers/phy/phy-twl4030-usb.c
@@ -678,7 +678,7 @@ static int twl4030_usb_probe(struct platform_device *pdev)
otg->set_host = twl4030_set_host;
otg->set_peripheral = twl4030_set_peripheral;

- phy = devm_phy_create(twl->dev, NULL, &ops, NULL);
+ phy = devm_phy_create(twl->dev, NULL, &ops);
if (IS_ERR(phy)) {
dev_dbg(&pdev->dev, "Failed to create PHY\n");
return PTR_ERR(phy);
diff --git a/drivers/phy/phy-xgene.c b/drivers/phy/phy-xgene.c
index f8a51b1..29214a3 100644
--- a/drivers/phy/phy-xgene.c
+++ b/drivers/phy/phy-xgene.c
@@ -1707,7 +1707,7 @@ static int xgene_phy_probe(struct platform_device *pdev)
ctx->dev = &pdev->dev;
platform_set_drvdata(pdev, ctx);

- ctx->phy = devm_phy_create(ctx->dev, NULL, &xgene_phy_ops, NULL);
+ ctx->phy = devm_phy_create(ctx->dev, NULL, &xgene_phy_ops);
if (IS_ERR(ctx->phy)) {
dev_dbg(&pdev->dev, "Failed to create PHY\n");
rc = PTR_ERR(ctx->phy);
diff --git a/drivers/pinctrl/pinctrl-tegra-xusb.c b/drivers/pinctrl/pinctrl-tegra-xusb.c
index 080ec77..753d747 100644
--- a/drivers/pinctrl/pinctrl-tegra-xusb.c
+++ b/drivers/pinctrl/pinctrl-tegra-xusb.c
@@ -915,7 +915,7 @@ static int tegra_xusb_padctl_probe(struct platform_device *pdev)
goto reset;
}

- phy = devm_phy_create(&pdev->dev, NULL, &pcie_phy_ops, NULL);
+ phy = devm_phy_create(&pdev->dev, NULL, &pcie_phy_ops);
if (IS_ERR(phy)) {
err = PTR_ERR(phy);
goto unregister;
@@ -924,7 +924,7 @@ static int tegra_xusb_padctl_probe(struct platform_device *pdev)
padctl->phys[TEGRA_XUSB_PADCTL_PCIE] = phy;
phy_set_drvdata(phy, padctl);

- phy = devm_phy_create(&pdev->dev, NULL, &sata_phy_ops, NULL);
+ phy = devm_phy_create(&pdev->dev, NULL, &sata_phy_ops);
if (IS_ERR(phy)) {
err = PTR_ERR(phy);
goto unregister;
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index 849284e..a0197fa 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -61,7 +61,6 @@ struct phy {
struct device dev;
int id;
const struct phy_ops *ops;
- struct phy_init_data *init_data;
struct mutex mutex;
int init_count;
int power_count;
@@ -84,32 +83,6 @@ struct phy_provider {
struct of_phandle_args *args);
};

-/**
- * struct phy_consumer - represents the phy consumer
- * @dev_name: the device name of the controller that will use this PHY device
- * @port: name given to the consumer port
- */
-struct phy_consumer {
- const char *dev_name;
- const char *port;
-};
-
-/**
- * struct phy_init_data - contains the list of PHY consumers
- * @num_consumers: number of consumers for this PHY device
- * @consumers: list of PHY consumers
- */
-struct phy_init_data {
- unsigned int num_consumers;
- struct phy_consumer *consumers;
-};
-
-#define PHY_CONSUMER(_dev_name, _port) \
-{ \
- .dev_name = _dev_name, \
- .port = _port, \
-}
-
struct phy_lookup {
struct list_head node;
const char *dev_id;
@@ -166,10 +139,9 @@ struct phy *of_phy_get(struct device_node *np, const char *con_id);
struct phy *of_phy_simple_xlate(struct device *dev,
struct of_phandle_args *args);
struct phy *phy_create(struct device *dev, struct device_node *node,
- const struct phy_ops *ops,
- struct phy_init_data *init_data);
+ const struct phy_ops *ops);
struct phy *devm_phy_create(struct device *dev, struct device_node *node,
- const struct phy_ops *ops, struct phy_init_data *init_data);
+ const struct phy_ops *ops);
void phy_destroy(struct phy *phy);
void devm_phy_destroy(struct device *dev, struct phy *phy);
struct phy_provider *__of_phy_provider_register(struct device *dev,
@@ -310,16 +282,14 @@ static inline struct phy *of_phy_simple_xlate(struct device *dev,

static inline struct phy *phy_create(struct device *dev,
struct device_node *node,
- const struct phy_ops *ops,
- struct phy_init_data *init_data)
+ const struct phy_ops *ops)
{
return ERR_PTR(-ENOSYS);
}

static inline struct phy *devm_phy_create(struct device *dev,
struct device_node *node,
- const struct phy_ops *ops,
- struct phy_init_data *init_data)
+ const struct phy_ops *ops)
{
return ERR_PTR(-ENOSYS);
}
--
2.1.3

2014-11-19 15:28:38

by Heikki Krogerus

[permalink] [raw]
Subject: [PATCHv5 4/7] arm: omap3: twl: remove usb phy init data

The driver does no use it any more.

Signed-off-by: Heikki Krogerus <[email protected]>
---
arch/arm/mach-omap2/twl-common.c | 12 +-----------
include/linux/i2c/twl.h | 2 --
2 files changed, 1 insertion(+), 13 deletions(-)

diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c
index b0d54da..4457e73 100644
--- a/arch/arm/mach-omap2/twl-common.c
+++ b/arch/arm/mach-omap2/twl-common.c
@@ -91,18 +91,8 @@ void __init omap_pmic_late_init(void)
}

#if defined(CONFIG_ARCH_OMAP3)
-struct phy_consumer consumers[] = {
- PHY_CONSUMER("musb-hdrc.0", "usb"),
-};
-
-struct phy_init_data init_data = {
- .consumers = consumers,
- .num_consumers = ARRAY_SIZE(consumers),
-};
-
static struct twl4030_usb_data omap3_usb_pdata = {
- .usb_mode = T2_USB_MODE_ULPI,
- .init_data = &init_data,
+ .usb_mode = T2_USB_MODE_ULPI,
};

static int omap3_batt_table[] = {
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
index 8cfb50f..0bc03f1 100644
--- a/include/linux/i2c/twl.h
+++ b/include/linux/i2c/twl.h
@@ -26,7 +26,6 @@
#define __TWL_H_

#include <linux/types.h>
-#include <linux/phy/phy.h>
#include <linux/input/matrix_keypad.h>

/*
@@ -634,7 +633,6 @@ enum twl4030_usb_mode {
struct twl4030_usb_data {
enum twl4030_usb_mode usb_mode;
unsigned long features;
- struct phy_init_data *init_data;

int (*phy_init)(struct device *dev);
int (*phy_exit)(struct device *dev);
--
2.1.3

2014-11-19 15:28:46

by Heikki Krogerus

[permalink] [raw]
Subject: [PATCHv5 7/7] usb: dwc3: host: convey the PHYs to xhci

On some platforms a PHY may need to be handled also in the
host controller driver. Exynos5420 SoC requires some "PHY
tuning" based on the USB speed. This patch delivers dwc3's
PHYs to the xhci platform device when it's created.

Signed-off-by: Heikki Krogerus <[email protected]>
Tested-by: Vivek Gautam <[email protected]>
Acked-by: Felipe Balbi <[email protected]>
---
drivers/usb/dwc3/host.c | 22 ++++++++++++++++------
1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c
index dcb8ca0..12bfd3c 100644
--- a/drivers/usb/dwc3/host.c
+++ b/drivers/usb/dwc3/host.c
@@ -29,8 +29,7 @@ int dwc3_host_init(struct dwc3 *dwc)
xhci = platform_device_alloc("xhci-hcd", PLATFORM_DEVID_AUTO);
if (!xhci) {
dev_err(dwc->dev, "couldn't allocate xHCI device\n");
- ret = -ENOMEM;
- goto err0;
+ return -ENOMEM;
}

dma_set_coherent_mask(&xhci->dev, dwc->dev->coherent_dma_mask);
@@ -60,22 +59,33 @@ int dwc3_host_init(struct dwc3 *dwc)
goto err1;
}

+ phy_create_lookup(dwc->usb2_generic_phy, "usb2-phy",
+ dev_name(&xhci->dev));
+ phy_create_lookup(dwc->usb3_generic_phy, "usb3-phy",
+ dev_name(&xhci->dev));
+
ret = platform_device_add(xhci);
if (ret) {
dev_err(dwc->dev, "failed to register xHCI device\n");
- goto err1;
+ goto err2;
}

return 0;
-
+err2:
+ phy_remove_lookup(dwc->usb2_generic_phy, "usb2-phy",
+ dev_name(&xhci->dev));
+ phy_remove_lookup(dwc->usb3_generic_phy, "usb3-phy",
+ dev_name(&xhci->dev));
err1:
platform_device_put(xhci);
-
-err0:
return ret;
}

void dwc3_host_exit(struct dwc3 *dwc)
{
+ phy_remove_lookup(dwc->usb2_generic_phy, "usb2-phy",
+ dev_name(&dwc->xhci->dev));
+ phy_remove_lookup(dwc->usb3_generic_phy, "usb3-phy",
+ dev_name(&dwc->xhci->dev));
platform_device_unregister(dwc->xhci);
}
--
2.1.3

2014-11-19 15:29:33

by Heikki Krogerus

[permalink] [raw]
Subject: [PATCHv5 6/7] base: platform: name the device already during allocation

The device name is usually required when assigning resources
like clocks to platform devices. The problem is that the
device name is not know before platform_device_add is called
and that can be too late as the drivers may have already
requested the resources when the function returns. By naming
the device already in platform_device_alloc, the resources
can be assigned before platform_device_add is called.

This change allows different kinds of probe drivers to pass
forward their resources to the actual driver. The first
place where we need it is dwc3 controllers host glue code
(drivers/usb/dwc3/host.c) to pass the phy's to xhci.

Signed-off-by: Heikki Krogerus <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
---
drivers/base/platform.c | 69 +++++++++++++++++++++++++++++--------------------
1 file changed, 41 insertions(+), 28 deletions(-)

diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index cdb6c07..d2217f3 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -195,11 +195,41 @@ void platform_device_put(struct platform_device *pdev)
}
EXPORT_SYMBOL_GPL(platform_device_put);

+static int pdev_set_name(struct platform_device *pdev)
+{
+ int ret;
+
+ switch (pdev->id) {
+ default:
+ return dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id);
+ case PLATFORM_DEVID_NONE:
+ return dev_set_name(&pdev->dev, "%s", pdev->name);
+ case PLATFORM_DEVID_AUTO:
+ /*
+ * Automatically allocated device ID. We mark it as such so
+ * that we remember it must be freed, and we append a suffix
+ * to avoid namespace collision with explicit IDs.
+ */
+ ret = ida_simple_get(&platform_devid_ida, 0, 0, GFP_KERNEL);
+ if (ret < 0)
+ return ret;
+ pdev->id = ret;
+ pdev->id_auto = true;
+ return dev_set_name(&pdev->dev, "%s.%d.auto", pdev->name,
+ pdev->id);
+ }
+
+ return 0;
+}
+
static void platform_device_release(struct device *dev)
{
struct platform_object *pa = container_of(dev, struct platform_object,
pdev.dev);

+ if (pa->pdev.id_auto)
+ ida_simple_remove(&platform_devid_ida, pa->pdev.id);
+
of_device_node_put(&pa->pdev.dev);
kfree(pa->pdev.dev.platform_data);
kfree(pa->pdev.mfd_cell);
@@ -228,6 +258,10 @@ struct platform_device *platform_device_alloc(const char *name, int id)
device_initialize(&pa->pdev.dev);
pa->pdev.dev.release = platform_device_release;
arch_setup_pdev_archdata(&pa->pdev);
+ if (pdev_set_name(&pa->pdev)) {
+ kfree(pa);
+ return NULL;
+ }
}

return pa ? &pa->pdev : NULL;
@@ -308,28 +342,6 @@ int platform_device_add(struct platform_device *pdev)

pdev->dev.bus = &platform_bus_type;

- switch (pdev->id) {
- default:
- dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id);
- break;
- case PLATFORM_DEVID_NONE:
- dev_set_name(&pdev->dev, "%s", pdev->name);
- break;
- case PLATFORM_DEVID_AUTO:
- /*
- * Automatically allocated device ID. We mark it as such so
- * that we remember it must be freed, and we append a suffix
- * to avoid namespace collision with explicit IDs.
- */
- ret = ida_simple_get(&platform_devid_ida, 0, 0, GFP_KERNEL);
- if (ret < 0)
- goto err_out;
- pdev->id = ret;
- pdev->id_auto = true;
- dev_set_name(&pdev->dev, "%s.%d.auto", pdev->name, pdev->id);
- break;
- }
-
for (i = 0; i < pdev->num_resources; i++) {
struct resource *p, *r = &pdev->resource[i];

@@ -372,7 +384,6 @@ int platform_device_add(struct platform_device *pdev)
release_resource(r);
}

- err_out:
return ret;
}
EXPORT_SYMBOL_GPL(platform_device_add);
@@ -392,11 +403,6 @@ void platform_device_del(struct platform_device *pdev)
if (pdev) {
device_del(&pdev->dev);

- if (pdev->id_auto) {
- ida_simple_remove(&platform_devid_ida, pdev->id);
- pdev->id = PLATFORM_DEVID_AUTO;
- }
-
for (i = 0; i < pdev->num_resources; i++) {
struct resource *r = &pdev->resource[i];
unsigned long type = resource_type(r);
@@ -414,8 +420,15 @@ EXPORT_SYMBOL_GPL(platform_device_del);
*/
int platform_device_register(struct platform_device *pdev)
{
+ int ret;
+
device_initialize(&pdev->dev);
arch_setup_pdev_archdata(pdev);
+
+ ret = pdev_set_name(pdev);
+ if (ret)
+ return ret;
+
return platform_device_add(pdev);
}
EXPORT_SYMBOL_GPL(platform_device_register);
--
2.1.3

2014-11-19 15:31:00

by Heikki Krogerus

[permalink] [raw]
Subject: [PATCHv5 2/7] phy: improved lookup method

Separates registration of the phy and the lookup. The method
is copied from clkdev.c,

Signed-off-by: Heikki Krogerus <[email protected]>
---
Documentation/phy.txt | 60 ++++++++++-------------------------
drivers/phy/phy-core.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++-
include/linux/phy/phy.h | 16 ++++++++++
3 files changed, 115 insertions(+), 45 deletions(-)

diff --git a/Documentation/phy.txt b/Documentation/phy.txt
index c6594af..371361c 100644
--- a/Documentation/phy.txt
+++ b/Documentation/phy.txt
@@ -54,18 +54,14 @@ 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, struct device_node *node,
- const struct phy_ops *ops,
- struct phy_init_data *init_data);
+ const struct phy_ops *ops);
struct phy *devm_phy_create(struct device *dev, struct device_node *node,
- const struct phy_ops *ops,
- struct phy_init_data *init_data);
+ const struct phy_ops *ops);

The PHY drivers can use one of the above 2 APIs to create the PHY by passing
-the device pointer, phy ops and init_data.
+the device pointer and phy ops.
phy_ops is a set of function pointers for performing PHY operations such as
-init, exit, power_on and power_off. *init_data* is mandatory to get a reference
-to the PHY in the case of non-dt boot. See section *Board File Initialization*
-on how init_data should be used.
+init, exit, power_on and power_off.

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
@@ -137,42 +133,18 @@ 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. Board File Initialization
-
-Certain board file initialization is necessary in order to get a reference
-to the PHY in the case of non-dt boot.
-Say we have a single device that implements 3 PHYs that of USB, SATA and PCIe,
-then in the board file the following initialization should be done.
-
-struct phy_consumer consumers[] = {
- PHY_CONSUMER("dwc3.0", "usb"),
- PHY_CONSUMER("pcie.0", "pcie"),
- PHY_CONSUMER("sata.0", "sata"),
-};
-PHY_CONSUMER takes 2 parameters, first is the device name of the controller
-(PHY consumer) and second is the port name.
-
-struct phy_init_data init_data = {
- .consumers = consumers,
- .num_consumers = ARRAY_SIZE(consumers),
-};
-
-static const struct platform_device pipe3_phy_dev = {
- .name = "pipe3-phy",
- .id = -1,
- .dev = {
- .platform_data = {
- .init_data = &init_data,
- },
- },
-};
-
-then, while doing phy_create, the PHY driver should pass this init_data
- phy_create(dev, ops, pdata->init_data);
-
-and the controller driver (phy consumer) should pass the port name along with
-the device to get a reference to the PHY
- phy_get(dev, "pcie");
+8. PHY Mappings
+
+In order to get reference to a PHY without help from DeviceTree, the framework
+offers lookups which can be compared to clkdev that allow clk structures to be
+bound to devices. A lookup can be made be made during runtime when a handle to
+the struct phy already exists.
+
+The framework offers the following API for registering and unregistering the
+lookups.
+
+int phy_create_lookup(struct phy *phy, const char *con_id, const char *dev_id);
+void phy_remove_lookup(struct phy *phy, const char *con_id, const char *dev_id);

9. DeviceTree Binding

diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index ff5eec5..9c3f0dc 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -26,6 +26,7 @@
static struct class *phy_class;
static DEFINE_MUTEX(phy_provider_mutex);
static LIST_HEAD(phy_provider_list);
+static LIST_HEAD(phys);
static DEFINE_IDA(phy_ida);

static void devm_phy_release(struct device *dev, void *res)
@@ -84,6 +85,87 @@ static struct phy *phy_lookup(struct device *device, const char *port)
return ERR_PTR(-ENODEV);
}

+/**
+ * phy_create_lookup() - allocate and register PHY/device association
+ * @phy: the phy of the association
+ * @con_id: connection ID string on device
+ * @dev_id: the device of the association
+ *
+ * Creates and registers phy_lookup entry.
+ */
+int phy_create_lookup(struct phy *phy, const char *con_id, const char *dev_id)
+{
+ struct phy_lookup *pl;
+
+ if (!phy || !dev_id || !con_id)
+ return -EINVAL;
+
+ pl = kzalloc(sizeof(*pl), GFP_KERNEL);
+ if (!pl)
+ return -ENOMEM;
+
+ pl->dev_id = dev_id;
+ pl->con_id = con_id;
+ pl->phy = phy;
+
+ mutex_lock(&phy_provider_mutex);
+ list_add_tail(&pl->node, &phys);
+ mutex_unlock(&phy_provider_mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(phy_create_lookup);
+
+/**
+ * phy_remove_lookup() - find and remove PHY/device association
+ * @phy: the phy of the association
+ * @con_id: connection ID string on device
+ * @dev_id: the device of the association
+ *
+ * Finds and unregisters phy_lookup entry that was created with
+ * phy_create_lookup().
+ */
+void phy_remove_lookup(struct phy *phy, const char *con_id, const char *dev_id)
+{
+ struct phy_lookup *pl;
+
+ if (!phy || !dev_id || !con_id)
+ return;
+
+ mutex_lock(&phy_provider_mutex);
+ list_for_each_entry(pl, &phys, node)
+ if (pl->phy == phy && !strcmp(pl->dev_id, dev_id) &&
+ !strcmp(pl->con_id, con_id)) {
+ list_del(&pl->node);
+ kfree(pl);
+ break;
+ }
+ mutex_unlock(&phy_provider_mutex);
+}
+EXPORT_SYMBOL_GPL(phy_remove_lookup);
+
+static struct phy *phy_find(struct device *dev, const char *con_id)
+{
+ const char *dev_id = dev_name(dev);
+ struct phy_lookup *p, *pl = NULL;
+ struct phy *phy;
+
+ mutex_lock(&phy_provider_mutex);
+ list_for_each_entry(p, &phys, node)
+ if (!strcmp(p->dev_id, dev_id) && !strcmp(p->con_id, con_id)) {
+ pl = p;
+ break;
+ }
+ mutex_unlock(&phy_provider_mutex);
+
+ phy = pl ? pl->phy : ERR_PTR(-ENODEV);
+
+ /* fall-back to the old lookup method for now */
+ if (IS_ERR(phy))
+ phy = phy_lookup(dev, con_id);
+ return phy;
+}
+
static struct phy_provider *of_phy_provider_lookup(struct device_node *node)
{
struct phy_provider *phy_provider;
@@ -463,7 +545,7 @@ struct phy *phy_get(struct device *dev, const char *string)
string);
phy = _of_phy_get(dev->of_node, index);
} else {
- phy = phy_lookup(dev, string);
+ phy = phy_find(dev, string);
}
if (IS_ERR(phy))
return phy;
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index 9fda683..849284e 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -110,6 +110,13 @@ struct phy_init_data {
.port = _port, \
}

+struct phy_lookup {
+ struct list_head node;
+ const char *dev_id;
+ const char *con_id;
+ struct phy *phy;
+};
+
#define to_phy(a) (container_of((a), struct phy, dev))

#define of_phy_provider_register(dev, xlate) \
@@ -174,6 +181,8 @@ struct phy_provider *__devm_of_phy_provider_register(struct device *dev,
void of_phy_provider_unregister(struct phy_provider *phy_provider);
void devm_of_phy_provider_unregister(struct device *dev,
struct phy_provider *phy_provider);
+int phy_create_lookup(struct phy *phy, const char *con_id, const char *dev_id);
+void phy_remove_lookup(struct phy *phy, const char *con_id, const char *dev_id);
#else
static inline int phy_pm_runtime_get(struct phy *phy)
{
@@ -345,6 +354,13 @@ static inline void devm_of_phy_provider_unregister(struct device *dev,
struct phy_provider *phy_provider)
{
}
+static inline int
+phy_create_lookup(struct phy *phy, const char *con_id, const char *dev_id)
+{
+ return 0;
+}
+static inline void phy_remove_lookup(struct phy *phy, const char *con_id,
+ const char *dev_id) { }
#endif

#endif /* __DRIVERS_PHY_H */
--
2.1.3

2014-11-20 09:15:53

by Kishon Vijay Abraham I

[permalink] [raw]
Subject: Re: [PATCHv5 4/7] arm: omap3: twl: remove usb phy init data

Hi Tony,

On Wednesday 19 November 2014 08:58 PM, Heikki Krogerus wrote:
> The driver does no use it any more.
>
> Signed-off-by: Heikki Krogerus <[email protected]>

This version is slightly different from the one you gave your Acked-by.

So are you okay if I merge this with your Acked-by?

Thanks
Kishon
> ---
> arch/arm/mach-omap2/twl-common.c | 12 +-----------
> include/linux/i2c/twl.h | 2 --
> 2 files changed, 1 insertion(+), 13 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c
> index b0d54da..4457e73 100644
> --- a/arch/arm/mach-omap2/twl-common.c
> +++ b/arch/arm/mach-omap2/twl-common.c
> @@ -91,18 +91,8 @@ void __init omap_pmic_late_init(void)
> }
>
> #if defined(CONFIG_ARCH_OMAP3)
> -struct phy_consumer consumers[] = {
> - PHY_CONSUMER("musb-hdrc.0", "usb"),
> -};
> -
> -struct phy_init_data init_data = {
> - .consumers = consumers,
> - .num_consumers = ARRAY_SIZE(consumers),
> -};
> -
> static struct twl4030_usb_data omap3_usb_pdata = {
> - .usb_mode = T2_USB_MODE_ULPI,
> - .init_data = &init_data,
> + .usb_mode = T2_USB_MODE_ULPI,
> };
>
> static int omap3_batt_table[] = {
> diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
> index 8cfb50f..0bc03f1 100644
> --- a/include/linux/i2c/twl.h
> +++ b/include/linux/i2c/twl.h
> @@ -26,7 +26,6 @@
> #define __TWL_H_
>
> #include <linux/types.h>
> -#include <linux/phy/phy.h>
> #include <linux/input/matrix_keypad.h>
>
> /*
> @@ -634,7 +633,6 @@ enum twl4030_usb_mode {
> struct twl4030_usb_data {
> enum twl4030_usb_mode usb_mode;
> unsigned long features;
> - struct phy_init_data *init_data;
>
> int (*phy_init)(struct device *dev);
> int (*phy_exit)(struct device *dev);
>

2014-11-20 09:21:53

by Kishon Vijay Abraham I

[permalink] [raw]
Subject: Re: [PATCHv5 6/7] base: platform: name the device already during allocation

Hi Greg,

On Wednesday 19 November 2014 08:58 PM, Heikki Krogerus wrote:
> The device name is usually required when assigning resources
> like clocks to platform devices. The problem is that the
> device name is not know before platform_device_add is called
> and that can be too late as the drivers may have already
> requested the resources when the function returns. By naming
> the device already in platform_device_alloc, the resources
> can be assigned before platform_device_add is called.
>
> This change allows different kinds of probe drivers to pass
> forward their resources to the actual driver. The first
> place where we need it is dwc3 controllers host glue code
> (drivers/usb/dwc3/host.c) to pass the phy's to xhci.
>
> Signed-off-by: Heikki Krogerus <[email protected]>
> Cc: Greg Kroah-Hartman <[email protected]>

Are you fine with this change? Can it come via linux-phy tree?

Thanks
Kishon
> ---
> drivers/base/platform.c | 69 +++++++++++++++++++++++++++++--------------------
> 1 file changed, 41 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/base/platform.c b/drivers/base/platform.c
> index cdb6c07..d2217f3 100644
> --- a/drivers/base/platform.c
> +++ b/drivers/base/platform.c
> @@ -195,11 +195,41 @@ void platform_device_put(struct platform_device *pdev)
> }
> EXPORT_SYMBOL_GPL(platform_device_put);
>
> +static int pdev_set_name(struct platform_device *pdev)
> +{
> + int ret;
> +
> + switch (pdev->id) {
> + default:
> + return dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id);
> + case PLATFORM_DEVID_NONE:
> + return dev_set_name(&pdev->dev, "%s", pdev->name);
> + case PLATFORM_DEVID_AUTO:
> + /*
> + * Automatically allocated device ID. We mark it as such so
> + * that we remember it must be freed, and we append a suffix
> + * to avoid namespace collision with explicit IDs.
> + */
> + ret = ida_simple_get(&platform_devid_ida, 0, 0, GFP_KERNEL);
> + if (ret < 0)
> + return ret;
> + pdev->id = ret;
> + pdev->id_auto = true;
> + return dev_set_name(&pdev->dev, "%s.%d.auto", pdev->name,
> + pdev->id);
> + }
> +
> + return 0;
> +}
> +
> static void platform_device_release(struct device *dev)
> {
> struct platform_object *pa = container_of(dev, struct platform_object,
> pdev.dev);
>
> + if (pa->pdev.id_auto)
> + ida_simple_remove(&platform_devid_ida, pa->pdev.id);
> +
> of_device_node_put(&pa->pdev.dev);
> kfree(pa->pdev.dev.platform_data);
> kfree(pa->pdev.mfd_cell);
> @@ -228,6 +258,10 @@ struct platform_device *platform_device_alloc(const char *name, int id)
> device_initialize(&pa->pdev.dev);
> pa->pdev.dev.release = platform_device_release;
> arch_setup_pdev_archdata(&pa->pdev);
> + if (pdev_set_name(&pa->pdev)) {
> + kfree(pa);
> + return NULL;
> + }
> }
>
> return pa ? &pa->pdev : NULL;
> @@ -308,28 +342,6 @@ int platform_device_add(struct platform_device *pdev)
>
> pdev->dev.bus = &platform_bus_type;
>
> - switch (pdev->id) {
> - default:
> - dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id);
> - break;
> - case PLATFORM_DEVID_NONE:
> - dev_set_name(&pdev->dev, "%s", pdev->name);
> - break;
> - case PLATFORM_DEVID_AUTO:
> - /*
> - * Automatically allocated device ID. We mark it as such so
> - * that we remember it must be freed, and we append a suffix
> - * to avoid namespace collision with explicit IDs.
> - */
> - ret = ida_simple_get(&platform_devid_ida, 0, 0, GFP_KERNEL);
> - if (ret < 0)
> - goto err_out;
> - pdev->id = ret;
> - pdev->id_auto = true;
> - dev_set_name(&pdev->dev, "%s.%d.auto", pdev->name, pdev->id);
> - break;
> - }
> -
> for (i = 0; i < pdev->num_resources; i++) {
> struct resource *p, *r = &pdev->resource[i];
>
> @@ -372,7 +384,6 @@ int platform_device_add(struct platform_device *pdev)
> release_resource(r);
> }
>
> - err_out:
> return ret;
> }
> EXPORT_SYMBOL_GPL(platform_device_add);
> @@ -392,11 +403,6 @@ void platform_device_del(struct platform_device *pdev)
> if (pdev) {
> device_del(&pdev->dev);
>
> - if (pdev->id_auto) {
> - ida_simple_remove(&platform_devid_ida, pdev->id);
> - pdev->id = PLATFORM_DEVID_AUTO;
> - }
> -
> for (i = 0; i < pdev->num_resources; i++) {
> struct resource *r = &pdev->resource[i];
> unsigned long type = resource_type(r);
> @@ -414,8 +420,15 @@ EXPORT_SYMBOL_GPL(platform_device_del);
> */
> int platform_device_register(struct platform_device *pdev)
> {
> + int ret;
> +
> device_initialize(&pdev->dev);
> arch_setup_pdev_archdata(pdev);
> +
> + ret = pdev_set_name(pdev);
> + if (ret)
> + return ret;
> +
> return platform_device_add(pdev);
> }
> EXPORT_SYMBOL_GPL(platform_device_register);
>

2014-11-20 11:29:14

by Vivek Gautam

[permalink] [raw]
Subject: Re: [PATCHv5 0/7] phy: simplified phy lookup

Hi,


On Wed, Nov 19, 2014 at 8:58 PM, Heikki Krogerus
<[email protected]> wrote:
> This set will in practice just separate the creation of a phy and
> binding of it to the consumer. Mapping phys to consumers can be now
> done with lookups similarly how clocks can be mapped in clkdev.c.
>
> Vivek needs to handle the phys of dwc3 also in xhci driver on
> Exynos5420 SoC, so I'm resending these now.

This set of patches work fine for me.
Tested on usb-next with this series and my series for 5420 phy calibration:
[PATCH v7 0/2] Fine tune USB 3.0 PHY on exynos5420
https://lkml.org/lkml/2014/10/31/266

If you want here's my tested-by, again for entire series.

Tested-by: Vivek Gautam <[email protected]>

>
> Changes since v4:
> - Support for static lookups is dropped. The lookups can be now only
> be created with phy_create_lookup()
>
> Changes since v3:
> - We can't rely on the order in which the phys are registered, so
> using the name of the parent of the phy instance for matching
> instead of the phy itself. The parent device is always the actual
> physical device.
> - Using PHY_LOOKUP macro in twl-common.c as suggested by Kishon.
>
> Changes since v2:
> - Calling ida_simple_remove in release function as pointed out by Greg
>
>
> Heikki Krogerus (7):
> phy: safer to_phy() macro
> phy: improved lookup method
> phy: twl4030: use the new lookup method
> arm: omap3: twl: remove usb phy init data
> phy: remove the old lookup method
> base: platform: name the device already during allocation
> usb: dwc3: host: convey the PHYs to xhci
>
> Documentation/phy.txt | 60 ++++++--------------
> arch/arm/mach-omap2/twl-common.c | 12 +---
> drivers/base/platform.c | 69 +++++++++++++----------
> drivers/phy/phy-bcm-kona-usb2.c | 2 +-
> drivers/phy/phy-berlin-sata.c | 2 +-
> drivers/phy/phy-core.c | 105 ++++++++++++++++++++++++-----------
> drivers/phy/phy-exynos-dp-video.c | 2 +-
> drivers/phy/phy-exynos-mipi-video.c | 2 +-
> drivers/phy/phy-exynos5-usbdrd.c | 3 +-
> drivers/phy/phy-exynos5250-sata.c | 2 +-
> drivers/phy/phy-hix5hd2-sata.c | 2 +-
> drivers/phy/phy-miphy365x.c | 2 +-
> drivers/phy/phy-mvebu-sata.c | 2 +-
> drivers/phy/phy-omap-usb2.c | 2 +-
> drivers/phy/phy-qcom-apq8064-sata.c | 3 +-
> drivers/phy/phy-qcom-ipq806x-sata.c | 3 +-
> drivers/phy/phy-rcar-gen2.c | 2 +-
> drivers/phy/phy-samsung-usb2.c | 3 +-
> drivers/phy/phy-spear1310-miphy.c | 2 +-
> drivers/phy/phy-spear1340-miphy.c | 2 +-
> drivers/phy/phy-stih407-usb.c | 2 +-
> drivers/phy/phy-stih41x-usb.c | 2 +-
> drivers/phy/phy-sun4i-usb.c | 2 +-
> drivers/phy/phy-ti-pipe3.c | 2 +-
> drivers/phy/phy-twl4030-usb.c | 9 ++-
> drivers/phy/phy-xgene.c | 2 +-
> drivers/pinctrl/pinctrl-tegra-xusb.c | 4 +-
> drivers/usb/dwc3/host.c | 22 ++++++--
> include/linux/i2c/twl.h | 2 -
> include/linux/phy/phy.h | 52 +++++++----------
> 30 files changed, 195 insertions(+), 186 deletions(-)
>
> --
> 2.1.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html



--
Best Regards
Vivek Gautam
Samsung R&D Institute, Bangalore
India

2014-12-03 05:41:30

by Kishon Vijay Abraham I

[permalink] [raw]
Subject: Re: [PATCH] arm: omap3: twl: remove usb phy init data

Hi Greg,

On Monday 01 December 2014 02:14 PM, Kishon Vijay Abraham I wrote:
> From: Heikki Krogerus <[email protected]>
>
> The driver does no use it any more.
>
> Signed-off-by: Heikki Krogerus <[email protected]>
> Signed-off-by: Kishon Vijay Abraham I <[email protected]>

This patch is required to get rid of the error that Stephen Rothwell reported.

Thanks
Kishon
> ---
> While this patch was part of the original series sent by Heikki, I couldn't
> get Ack from Tony to be merged this in my tree and I failed to catch the
> build error during my testing :-(
>
> This patch should fix the error pointed out by Stephen Rothwell.
> arch/arm/mach-omap2/twl-common.c:94:21: error: array type has incomplete element type
> struct phy_consumer consumers[] = {
> ^
> arch/arm/mach-omap2/twl-common.c | 12 +-----------
> include/linux/i2c/twl.h | 2 --
> 2 files changed, 1 insertion(+), 13 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c
> index b0d54da..4457e73 100644
> --- a/arch/arm/mach-omap2/twl-common.c
> +++ b/arch/arm/mach-omap2/twl-common.c
> @@ -91,18 +91,8 @@ void __init omap_pmic_late_init(void)
> }
>
> #if defined(CONFIG_ARCH_OMAP3)
> -struct phy_consumer consumers[] = {
> - PHY_CONSUMER("musb-hdrc.0", "usb"),
> -};
> -
> -struct phy_init_data init_data = {
> - .consumers = consumers,
> - .num_consumers = ARRAY_SIZE(consumers),
> -};
> -
> static struct twl4030_usb_data omap3_usb_pdata = {
> - .usb_mode = T2_USB_MODE_ULPI,
> - .init_data = &init_data,
> + .usb_mode = T2_USB_MODE_ULPI,
> };
>
> static int omap3_batt_table[] = {
> diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
> index 8cfb50f..0bc03f1 100644
> --- a/include/linux/i2c/twl.h
> +++ b/include/linux/i2c/twl.h
> @@ -26,7 +26,6 @@
> #define __TWL_H_
>
> #include <linux/types.h>
> -#include <linux/phy/phy.h>
> #include <linux/input/matrix_keypad.h>
>
> /*
> @@ -634,7 +633,6 @@ enum twl4030_usb_mode {
> struct twl4030_usb_data {
> enum twl4030_usb_mode usb_mode;
> unsigned long features;
> - struct phy_init_data *init_data;
>
> int (*phy_init)(struct device *dev);
> int (*phy_exit)(struct device *dev);
>

2014-12-03 16:20:12

by Greg Kroah-Hartman

[permalink] [raw]
Subject: Re: [PATCH] arm: omap3: twl: remove usb phy init data

On Wed, Dec 03, 2014 at 11:11:09AM +0530, Kishon Vijay Abraham I wrote:
> Hi Greg,
>
> On Monday 01 December 2014 02:14 PM, Kishon Vijay Abraham I wrote:
> > From: Heikki Krogerus <[email protected]>
> >
> > The driver does no use it any more.
> >
> > Signed-off-by: Heikki Krogerus <[email protected]>
> > Signed-off-by: Kishon Vijay Abraham I <[email protected]>
>
> This patch is required to get rid of the error that Stephen Rothwell reported.

Then please resend it in a format that I can apply it in.

thanks,

greg k-h

2015-02-02 12:12:16

by Vivek Gautam

[permalink] [raw]
Subject: Re: [PATCHv5 6/7] base: platform: name the device already during allocation

Hi Kishon,


On Thu, Nov 20, 2014 at 2:51 PM, Kishon Vijay Abraham I <[email protected]> wrote:
> Hi Greg,
>
> On Wednesday 19 November 2014 08:58 PM, Heikki Krogerus wrote:
>> The device name is usually required when assigning resources
>> like clocks to platform devices. The problem is that the
>> device name is not know before platform_device_add is called
>> and that can be too late as the drivers may have already
>> requested the resources when the function returns. By naming
>> the device already in platform_device_alloc, the resources
>> can be assigned before platform_device_add is called.
>>
>> This change allows different kinds of probe drivers to pass
>> forward their resources to the actual driver. The first
>> place where we need it is dwc3 controllers host glue code
>> (drivers/usb/dwc3/host.c) to pass the phy's to xhci.
>>
>> Signed-off-by: Heikki Krogerus <[email protected]>
>> Cc: Greg Kroah-Hartman <[email protected]>
>
> Are you fine with this change? Can it come via linux-phy tree?
>
> Thanks
> Kishon

I think this patch missed getting into 3.19 or 20 now.
Is there some other tree where it got pulled in, coz i can't see it in
linux-next also ?

>> ---
>> drivers/base/platform.c | 69 +++++++++++++++++++++++++++++--------------------
>> 1 file changed, 41 insertions(+), 28 deletions(-)
>>
>> diff --git a/drivers/base/platform.c b/drivers/base/platform.c
>> index cdb6c07..d2217f3 100644
>> --- a/drivers/base/platform.c
>> +++ b/drivers/base/platform.c
>> @@ -195,11 +195,41 @@ void platform_device_put(struct platform_device *pdev)
>> }
>> EXPORT_SYMBOL_GPL(platform_device_put);
>>
>> +static int pdev_set_name(struct platform_device *pdev)
>> +{
>> + int ret;
>> +
>> + switch (pdev->id) {
>> + default:
>> + return dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id);
>> + case PLATFORM_DEVID_NONE:
>> + return dev_set_name(&pdev->dev, "%s", pdev->name);
>> + case PLATFORM_DEVID_AUTO:
>> + /*
>> + * Automatically allocated device ID. We mark it as such so
>> + * that we remember it must be freed, and we append a suffix
>> + * to avoid namespace collision with explicit IDs.
>> + */
>> + ret = ida_simple_get(&platform_devid_ida, 0, 0, GFP_KERNEL);
>> + if (ret < 0)
>> + return ret;
>> + pdev->id = ret;
>> + pdev->id_auto = true;
>> + return dev_set_name(&pdev->dev, "%s.%d.auto", pdev->name,
>> + pdev->id);
>> + }
>> +
>> + return 0;
>> +}
>> +
>> static void platform_device_release(struct device *dev)
>> {
>> struct platform_object *pa = container_of(dev, struct platform_object,
>> pdev.dev);
>>
>> + if (pa->pdev.id_auto)
>> + ida_simple_remove(&platform_devid_ida, pa->pdev.id);
>> +
>> of_device_node_put(&pa->pdev.dev);
>> kfree(pa->pdev.dev.platform_data);
>> kfree(pa->pdev.mfd_cell);
>> @@ -228,6 +258,10 @@ struct platform_device *platform_device_alloc(const char *name, int id)
>> device_initialize(&pa->pdev.dev);
>> pa->pdev.dev.release = platform_device_release;
>> arch_setup_pdev_archdata(&pa->pdev);
>> + if (pdev_set_name(&pa->pdev)) {
>> + kfree(pa);
>> + return NULL;
>> + }
>> }
>>
>> return pa ? &pa->pdev : NULL;
>> @@ -308,28 +342,6 @@ int platform_device_add(struct platform_device *pdev)
>>
>> pdev->dev.bus = &platform_bus_type;
>>
>> - switch (pdev->id) {
>> - default:
>> - dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id);
>> - break;
>> - case PLATFORM_DEVID_NONE:
>> - dev_set_name(&pdev->dev, "%s", pdev->name);
>> - break;
>> - case PLATFORM_DEVID_AUTO:
>> - /*
>> - * Automatically allocated device ID. We mark it as such so
>> - * that we remember it must be freed, and we append a suffix
>> - * to avoid namespace collision with explicit IDs.
>> - */
>> - ret = ida_simple_get(&platform_devid_ida, 0, 0, GFP_KERNEL);
>> - if (ret < 0)
>> - goto err_out;
>> - pdev->id = ret;
>> - pdev->id_auto = true;
>> - dev_set_name(&pdev->dev, "%s.%d.auto", pdev->name, pdev->id);
>> - break;
>> - }
>> -
>> for (i = 0; i < pdev->num_resources; i++) {
>> struct resource *p, *r = &pdev->resource[i];
>>
>> @@ -372,7 +384,6 @@ int platform_device_add(struct platform_device *pdev)
>> release_resource(r);
>> }
>>
>> - err_out:
>> return ret;
>> }
>> EXPORT_SYMBOL_GPL(platform_device_add);
>> @@ -392,11 +403,6 @@ void platform_device_del(struct platform_device *pdev)
>> if (pdev) {
>> device_del(&pdev->dev);
>>
>> - if (pdev->id_auto) {
>> - ida_simple_remove(&platform_devid_ida, pdev->id);
>> - pdev->id = PLATFORM_DEVID_AUTO;
>> - }
>> -
>> for (i = 0; i < pdev->num_resources; i++) {
>> struct resource *r = &pdev->resource[i];
>> unsigned long type = resource_type(r);
>> @@ -414,8 +420,15 @@ EXPORT_SYMBOL_GPL(platform_device_del);
>> */
>> int platform_device_register(struct platform_device *pdev)
>> {
>> + int ret;
>> +
>> device_initialize(&pdev->dev);
>> arch_setup_pdev_archdata(pdev);
>> +
>> + ret = pdev_set_name(pdev);
>> + if (ret)
>> + return ret;
>> +
>> return platform_device_add(pdev);
>> }
>> EXPORT_SYMBOL_GPL(platform_device_register);
>>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/



--
Best Regards
Vivek Gautam
Samsung R&D Institute, Bangalore
India