diff options
Diffstat (limited to 'drivers/net/ethernet/smsc/smc91x.c')
-rw-r--r-- | drivers/net/ethernet/smsc/smc91x.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c index 5e94d00b96b3..2c62208077fe 100644 --- a/drivers/net/ethernet/smsc/smc91x.c +++ b/drivers/net/ethernet/smsc/smc91x.c | |||
@@ -81,6 +81,7 @@ static const char version[] = | |||
81 | #include <linux/workqueue.h> | 81 | #include <linux/workqueue.h> |
82 | #include <linux/of.h> | 82 | #include <linux/of.h> |
83 | #include <linux/of_device.h> | 83 | #include <linux/of_device.h> |
84 | #include <linux/of_gpio.h> | ||
84 | 85 | ||
85 | #include <linux/netdevice.h> | 86 | #include <linux/netdevice.h> |
86 | #include <linux/etherdevice.h> | 87 | #include <linux/etherdevice.h> |
@@ -2188,6 +2189,41 @@ static const struct of_device_id smc91x_match[] = { | |||
2188 | {}, | 2189 | {}, |
2189 | }; | 2190 | }; |
2190 | MODULE_DEVICE_TABLE(of, smc91x_match); | 2191 | MODULE_DEVICE_TABLE(of, smc91x_match); |
2192 | |||
2193 | /** | ||
2194 | * of_try_set_control_gpio - configure a gpio if it exists | ||
2195 | */ | ||
2196 | static int try_toggle_control_gpio(struct device *dev, | ||
2197 | struct gpio_desc **desc, | ||
2198 | const char *name, int index, | ||
2199 | int value, unsigned int nsdelay) | ||
2200 | { | ||
2201 | struct gpio_desc *gpio = *desc; | ||
2202 | int res; | ||
2203 | |||
2204 | gpio = devm_gpiod_get_index(dev, name, index); | ||
2205 | if (IS_ERR(gpio)) { | ||
2206 | if (PTR_ERR(gpio) == -ENOENT) { | ||
2207 | *desc = NULL; | ||
2208 | return 0; | ||
2209 | } | ||
2210 | |||
2211 | return PTR_ERR(gpio); | ||
2212 | } | ||
2213 | res = gpiod_direction_output(gpio, !value); | ||
2214 | if (res) { | ||
2215 | dev_err(dev, "unable to toggle gpio %s: %i\n", name, res); | ||
2216 | devm_gpiod_put(dev, gpio); | ||
2217 | gpio = NULL; | ||
2218 | return res; | ||
2219 | } | ||
2220 | if (nsdelay) | ||
2221 | usleep_range(nsdelay, 2 * nsdelay); | ||
2222 | gpiod_set_value_cansleep(gpio, value); | ||
2223 | *desc = gpio; | ||
2224 | |||
2225 | return 0; | ||
2226 | } | ||
2191 | #endif | 2227 | #endif |
2192 | 2228 | ||
2193 | /* | 2229 | /* |
@@ -2237,6 +2273,28 @@ static int smc_drv_probe(struct platform_device *pdev) | |||
2237 | struct device_node *np = pdev->dev.of_node; | 2273 | struct device_node *np = pdev->dev.of_node; |
2238 | u32 val; | 2274 | u32 val; |
2239 | 2275 | ||
2276 | /* Optional pwrdwn GPIO configured? */ | ||
2277 | ret = try_toggle_control_gpio(&pdev->dev, &lp->power_gpio, | ||
2278 | "power", 0, 0, 100); | ||
2279 | if (ret) | ||
2280 | return ret; | ||
2281 | |||
2282 | /* | ||
2283 | * Optional reset GPIO configured? Minimum 100 ns reset needed | ||
2284 | * according to LAN91C96 datasheet page 14. | ||
2285 | */ | ||
2286 | ret = try_toggle_control_gpio(&pdev->dev, &lp->reset_gpio, | ||
2287 | "reset", 0, 0, 100); | ||
2288 | if (ret) | ||
2289 | return ret; | ||
2290 | |||
2291 | /* | ||
2292 | * Need to wait for optional EEPROM to load, max 750 us according | ||
2293 | * to LAN91C96 datasheet page 55. | ||
2294 | */ | ||
2295 | if (lp->reset_gpio) | ||
2296 | usleep_range(750, 1000); | ||
2297 | |||
2240 | /* Combination of IO widths supported, default to 16-bit */ | 2298 | /* Combination of IO widths supported, default to 16-bit */ |
2241 | if (!of_property_read_u32(np, "reg-io-width", &val)) { | 2299 | if (!of_property_read_u32(np, "reg-io-width", &val)) { |
2242 | if (val & 1) | 2300 | if (val & 1) |