aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/phy/mdio-mux-gpio.c37
1 files changed, 13 insertions, 24 deletions
diff --git a/drivers/net/phy/mdio-mux-gpio.c b/drivers/net/phy/mdio-mux-gpio.c
index 096695163491..1eaf81efde24 100644
--- a/drivers/net/phy/mdio-mux-gpio.c
+++ b/drivers/net/phy/mdio-mux-gpio.c
@@ -14,13 +14,13 @@
14#include <linux/mdio-mux.h> 14#include <linux/mdio-mux.h>
15#include <linux/of_gpio.h> 15#include <linux/of_gpio.h>
16 16
17#define DRV_VERSION "1.0" 17#define DRV_VERSION "1.1"
18#define DRV_DESCRIPTION "GPIO controlled MDIO bus multiplexer driver" 18#define DRV_DESCRIPTION "GPIO controlled MDIO bus multiplexer driver"
19 19
20#define MDIO_MUX_GPIO_MAX_BITS 8 20#define MDIO_MUX_GPIO_MAX_BITS 8
21 21
22struct mdio_mux_gpio_state { 22struct mdio_mux_gpio_state {
23 int gpio[MDIO_MUX_GPIO_MAX_BITS]; 23 struct gpio_desc *gpio[MDIO_MUX_GPIO_MAX_BITS];
24 unsigned int num_gpios; 24 unsigned int num_gpios;
25 void *mux_handle; 25 void *mux_handle;
26}; 26};
@@ -28,29 +28,23 @@ struct mdio_mux_gpio_state {
28static int mdio_mux_gpio_switch_fn(int current_child, int desired_child, 28static int mdio_mux_gpio_switch_fn(int current_child, int desired_child,
29 void *data) 29 void *data)
30{ 30{
31 int change; 31 int values[MDIO_MUX_GPIO_MAX_BITS];
32 unsigned int n; 32 unsigned int n;
33 struct mdio_mux_gpio_state *s = data; 33 struct mdio_mux_gpio_state *s = data;
34 34
35 if (current_child == desired_child) 35 if (current_child == desired_child)
36 return 0; 36 return 0;
37 37
38 change = current_child == -1 ? -1 : current_child ^ desired_child;
39
40 for (n = 0; n < s->num_gpios; n++) { 38 for (n = 0; n < s->num_gpios; n++) {
41 if (change & 1) 39 values[n] = (desired_child >> n) & 1;
42 gpio_set_value_cansleep(s->gpio[n],
43 (desired_child & 1) != 0);
44 change >>= 1;
45 desired_child >>= 1;
46 } 40 }
41 gpiod_set_array_cansleep(s->num_gpios, s->gpio, values);
47 42
48 return 0; 43 return 0;
49} 44}
50 45
51static int mdio_mux_gpio_probe(struct platform_device *pdev) 46static int mdio_mux_gpio_probe(struct platform_device *pdev)
52{ 47{
53 enum of_gpio_flags f;
54 struct mdio_mux_gpio_state *s; 48 struct mdio_mux_gpio_state *s;
55 int num_gpios; 49 int num_gpios;
56 unsigned int n; 50 unsigned int n;
@@ -70,22 +64,14 @@ static int mdio_mux_gpio_probe(struct platform_device *pdev)
70 s->num_gpios = num_gpios; 64 s->num_gpios = num_gpios;
71 65
72 for (n = 0; n < num_gpios; ) { 66 for (n = 0; n < num_gpios; ) {
73 int gpio = of_get_gpio_flags(pdev->dev.of_node, n, &f); 67 struct gpio_desc *gpio = gpiod_get_index(&pdev->dev, NULL, n,
74 if (gpio < 0) { 68 GPIOD_OUT_LOW);
75 r = (gpio == -ENODEV) ? -EPROBE_DEFER : gpio; 69 if (IS_ERR(gpio)) {
70 r = PTR_ERR(gpio);
76 goto err; 71 goto err;
77 } 72 }
78 s->gpio[n] = gpio; 73 s->gpio[n] = gpio;
79
80 n++; 74 n++;
81
82 r = gpio_request(gpio, "mdio_mux_gpio");
83 if (r)
84 goto err;
85
86 r = gpio_direction_output(gpio, 0);
87 if (r)
88 goto err;
89 } 75 }
90 76
91 r = mdio_mux_init(&pdev->dev, 77 r = mdio_mux_init(&pdev->dev,
@@ -98,15 +84,18 @@ static int mdio_mux_gpio_probe(struct platform_device *pdev)
98err: 84err:
99 while (n) { 85 while (n) {
100 n--; 86 n--;
101 gpio_free(s->gpio[n]); 87 gpiod_put(s->gpio[n]);
102 } 88 }
103 return r; 89 return r;
104} 90}
105 91
106static int mdio_mux_gpio_remove(struct platform_device *pdev) 92static int mdio_mux_gpio_remove(struct platform_device *pdev)
107{ 93{
94 unsigned int n;
108 struct mdio_mux_gpio_state *s = dev_get_platdata(&pdev->dev); 95 struct mdio_mux_gpio_state *s = dev_get_platdata(&pdev->dev);
109 mdio_mux_uninit(s->mux_handle); 96 mdio_mux_uninit(s->mux_handle);
97 for (n = 0; n < s->num_gpios; n++)
98 gpiod_put(s->gpio[n]);
110 return 0; 99 return 0;
111} 100}
112 101