Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: mdio-gpio: Add support for active low gpio pins

Some systems using mdio-gpio may use active-low gpio pins
(eg with inverters or FETs connected to all or some of the
gpio pins).

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Guenter Roeck and committed by
David S. Miller
1d251481 78cdb079

+16 -6
+13 -6
drivers/net/phy/mdio-gpio.c
··· 33 33 struct mdio_gpio_info { 34 34 struct mdiobb_ctrl ctrl; 35 35 int mdc, mdio; 36 + int mdc_active_low, mdio_active_low; 36 37 }; 37 38 38 39 static void *mdio_gpio_of_get_data(struct platform_device *pdev) 39 40 { 40 41 struct device_node *np = pdev->dev.of_node; 41 42 struct mdio_gpio_platform_data *pdata; 43 + enum of_gpio_flags flags; 42 44 int ret; 43 45 44 46 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 45 47 if (!pdata) 46 48 return NULL; 47 49 48 - ret = of_get_gpio(np, 0); 50 + ret = of_get_gpio_flags(np, 0, &flags); 49 51 if (ret < 0) 50 52 return NULL; 51 53 52 54 pdata->mdc = ret; 55 + pdata->mdc_active_low = flags & OF_GPIO_ACTIVE_LOW; 53 56 54 - ret = of_get_gpio(np, 1); 57 + ret = of_get_gpio_flags(np, 1, &flags); 55 58 if (ret < 0) 56 59 return NULL; 57 60 pdata->mdio = ret; 61 + pdata->mdio_active_low = flags & OF_GPIO_ACTIVE_LOW; 58 62 59 63 return pdata; 60 64 } ··· 69 65 container_of(ctrl, struct mdio_gpio_info, ctrl); 70 66 71 67 if (dir) 72 - gpio_direction_output(bitbang->mdio, 1); 68 + gpio_direction_output(bitbang->mdio, 69 + 1 ^ bitbang->mdio_active_low); 73 70 else 74 71 gpio_direction_input(bitbang->mdio); 75 72 } ··· 80 75 struct mdio_gpio_info *bitbang = 81 76 container_of(ctrl, struct mdio_gpio_info, ctrl); 82 77 83 - return gpio_get_value(bitbang->mdio); 78 + return gpio_get_value(bitbang->mdio) ^ bitbang->mdio_active_low; 84 79 } 85 80 86 81 static void mdio_set(struct mdiobb_ctrl *ctrl, int what) ··· 88 83 struct mdio_gpio_info *bitbang = 89 84 container_of(ctrl, struct mdio_gpio_info, ctrl); 90 85 91 - gpio_set_value(bitbang->mdio, what); 86 + gpio_set_value(bitbang->mdio, what ^ bitbang->mdio_active_low); 92 87 } 93 88 94 89 static void mdc_set(struct mdiobb_ctrl *ctrl, int what) ··· 96 91 struct mdio_gpio_info *bitbang = 97 92 container_of(ctrl, struct mdio_gpio_info, ctrl); 98 93 99 - gpio_set_value(bitbang->mdc, what); 94 + gpio_set_value(bitbang->mdc, what ^ bitbang->mdc_active_low); 100 95 } 101 96 102 97 static struct mdiobb_ops mdio_gpio_ops = { ··· 122 117 bitbang->ctrl.ops = &mdio_gpio_ops; 123 118 bitbang->ctrl.reset = pdata->reset; 124 119 bitbang->mdc = pdata->mdc; 120 + bitbang->mdc_active_low = pdata->mdc_active_low; 125 121 bitbang->mdio = pdata->mdio; 122 + bitbang->mdio_active_low = pdata->mdio_active_low; 126 123 127 124 new_bus = alloc_mdio_bitbang(&bitbang->ctrl); 128 125 if (!new_bus)
+3
include/linux/mdio-gpio.h
··· 18 18 unsigned int mdc; 19 19 unsigned int mdio; 20 20 21 + bool mdc_active_low; 22 + bool mdio_active_low; 23 + 21 24 unsigned int phy_mask; 22 25 int irqs[PHY_MAX_ADDR]; 23 26 /* reset callback */