aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPramod Kumar <pramod.kumar@broadcom.com>2016-06-10 01:33:45 -0400
committerDavid S. Miller <davem@davemloft.net>2016-06-11 02:24:53 -0400
commitf20e6657a8758fe8d074889a6f1883674f01c7f2 (patch)
treea55ed4fb2fd0a3087905a230ffaab7d4d40d52e6
parentd46e416c11c88ef1deb5c7f19271806a5be597fe (diff)
mdio: mux: Enhanced MDIO mux framework for integrated multiplexers
An integrated multiplexer uses same address space for "muxed bus selection" and "generation of mdio transaction" hence its good to register parent bus from mux driver. Hence added a mechanism where mux driver could register a parent bus and pass it down to framework via mdio_mux_init api. Signed-off-by: Pramod Kumar <pramod.kumar@broadcom.com> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/phy/mdio-mux-gpio.c2
-rw-r--r--drivers/net/phy/mdio-mux-mmioreg.c2
-rw-r--r--drivers/net/phy/mdio-mux.c28
-rw-r--r--include/linux/mdio-mux.h4
4 files changed, 23 insertions, 13 deletions
diff --git a/drivers/net/phy/mdio-mux-gpio.c b/drivers/net/phy/mdio-mux-gpio.c
index 7ddb1ab70891..919949960a10 100644
--- a/drivers/net/phy/mdio-mux-gpio.c
+++ b/drivers/net/phy/mdio-mux-gpio.c
@@ -55,7 +55,7 @@ static int mdio_mux_gpio_probe(struct platform_device *pdev)
55 return PTR_ERR(s->gpios); 55 return PTR_ERR(s->gpios);
56 56
57 r = mdio_mux_init(&pdev->dev, 57 r = mdio_mux_init(&pdev->dev,
58 mdio_mux_gpio_switch_fn, &s->mux_handle, s); 58 mdio_mux_gpio_switch_fn, &s->mux_handle, s, NULL);
59 59
60 if (r != 0) { 60 if (r != 0) {
61 gpiod_put_array(s->gpios); 61 gpiod_put_array(s->gpios);
diff --git a/drivers/net/phy/mdio-mux-mmioreg.c b/drivers/net/phy/mdio-mux-mmioreg.c
index 7fde454fbc4f..d0bed52c8d16 100644
--- a/drivers/net/phy/mdio-mux-mmioreg.c
+++ b/drivers/net/phy/mdio-mux-mmioreg.c
@@ -126,7 +126,7 @@ static int mdio_mux_mmioreg_probe(struct platform_device *pdev)
126 } 126 }
127 127
128 ret = mdio_mux_init(&pdev->dev, mdio_mux_mmioreg_switch_fn, 128 ret = mdio_mux_init(&pdev->dev, mdio_mux_mmioreg_switch_fn,
129 &s->mux_handle, s); 129 &s->mux_handle, s, NULL);
130 if (ret) { 130 if (ret) {
131 dev_err(&pdev->dev, "failed to register mdio-mux bus %s\n", 131 dev_err(&pdev->dev, "failed to register mdio-mux bus %s\n",
132 np->full_name); 132 np->full_name);
diff --git a/drivers/net/phy/mdio-mux.c b/drivers/net/phy/mdio-mux.c
index 5c81d6faf304..dbd4ecc205dc 100644
--- a/drivers/net/phy/mdio-mux.c
+++ b/drivers/net/phy/mdio-mux.c
@@ -89,7 +89,8 @@ static int parent_count;
89int mdio_mux_init(struct device *dev, 89int mdio_mux_init(struct device *dev,
90 int (*switch_fn)(int cur, int desired, void *data), 90 int (*switch_fn)(int cur, int desired, void *data),
91 void **mux_handle, 91 void **mux_handle,
92 void *data) 92 void *data,
93 struct mii_bus *mux_bus)
93{ 94{
94 struct device_node *parent_bus_node; 95 struct device_node *parent_bus_node;
95 struct device_node *child_bus_node; 96 struct device_node *child_bus_node;
@@ -101,10 +102,21 @@ int mdio_mux_init(struct device *dev,
101 if (!dev->of_node) 102 if (!dev->of_node)
102 return -ENODEV; 103 return -ENODEV;
103 104
104 parent_bus_node = of_parse_phandle(dev->of_node, "mdio-parent-bus", 0); 105 if (!mux_bus) {
106 parent_bus_node = of_parse_phandle(dev->of_node,
107 "mdio-parent-bus", 0);
105 108
106 if (!parent_bus_node) 109 if (!parent_bus_node)
107 return -ENODEV; 110 return -ENODEV;
111
112 parent_bus = of_mdio_find_bus(parent_bus_node);
113 if (!parent_bus) {
114 ret_val = -EPROBE_DEFER;
115 goto err_parent_bus;
116 }
117 } else {
118 parent_bus = mux_bus;
119 }
108 120
109 pb = devm_kzalloc(dev, sizeof(*pb), GFP_KERNEL); 121 pb = devm_kzalloc(dev, sizeof(*pb), GFP_KERNEL);
110 if (pb == NULL) { 122 if (pb == NULL) {
@@ -112,11 +124,6 @@ int mdio_mux_init(struct device *dev,
112 goto err_parent_bus; 124 goto err_parent_bus;
113 } 125 }
114 126
115 parent_bus = of_mdio_find_bus(parent_bus_node);
116 if (parent_bus == NULL) {
117 ret_val = -EPROBE_DEFER;
118 goto err_parent_bus;
119 }
120 127
121 pb->switch_data = data; 128 pb->switch_data = data;
122 pb->switch_fn = switch_fn; 129 pb->switch_fn = switch_fn;
@@ -177,7 +184,8 @@ int mdio_mux_init(struct device *dev,
177 put_device(&pb->mii_bus->dev); 184 put_device(&pb->mii_bus->dev);
178 185
179err_parent_bus: 186err_parent_bus:
180 of_node_put(parent_bus_node); 187 if (!mux_bus)
188 of_node_put(parent_bus_node);
181 return ret_val; 189 return ret_val;
182} 190}
183EXPORT_SYMBOL_GPL(mdio_mux_init); 191EXPORT_SYMBOL_GPL(mdio_mux_init);
diff --git a/include/linux/mdio-mux.h b/include/linux/mdio-mux.h
index a243dbba8659..61f5b21b31c7 100644
--- a/include/linux/mdio-mux.h
+++ b/include/linux/mdio-mux.h
@@ -10,11 +10,13 @@
10#ifndef __LINUX_MDIO_MUX_H 10#ifndef __LINUX_MDIO_MUX_H
11#define __LINUX_MDIO_MUX_H 11#define __LINUX_MDIO_MUX_H
12#include <linux/device.h> 12#include <linux/device.h>
13#include <linux/phy.h>
13 14
14int mdio_mux_init(struct device *dev, 15int mdio_mux_init(struct device *dev,
15 int (*switch_fn) (int cur, int desired, void *data), 16 int (*switch_fn) (int cur, int desired, void *data),
16 void **mux_handle, 17 void **mux_handle,
17 void *data); 18 void *data,
19 struct mii_bus *mux_bus);
18 20
19void mdio_mux_uninit(void *mux_handle); 21void mdio_mux_uninit(void *mux_handle);
20 22