aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/smsc/smc91x.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/smsc/smc91x.c')
-rw-r--r--drivers/net/ethernet/smsc/smc91x.c78
1 files changed, 70 insertions, 8 deletions
diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c
index 5e94d00b96b3..6cc3cf6f17c8 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};
2190MODULE_DEVICE_TABLE(of, smc91x_match); 2191MODULE_DEVICE_TABLE(of, smc91x_match);
2192
2193/**
2194 * of_try_set_control_gpio - configure a gpio if it exists
2195 */
2196static 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/*
@@ -2207,9 +2243,10 @@ static int smc_drv_probe(struct platform_device *pdev)
2207 const struct of_device_id *match = NULL; 2243 const struct of_device_id *match = NULL;
2208 struct smc_local *lp; 2244 struct smc_local *lp;
2209 struct net_device *ndev; 2245 struct net_device *ndev;
2210 struct resource *res, *ires; 2246 struct resource *res;
2211 unsigned int __iomem *addr; 2247 unsigned int __iomem *addr;
2212 unsigned long irq_flags = SMC_IRQ_FLAGS; 2248 unsigned long irq_flags = SMC_IRQ_FLAGS;
2249 unsigned long irq_resflags;
2213 int ret; 2250 int ret;
2214 2251
2215 ndev = alloc_etherdev(sizeof(struct smc_local)); 2252 ndev = alloc_etherdev(sizeof(struct smc_local));
@@ -2237,6 +2274,28 @@ static int smc_drv_probe(struct platform_device *pdev)
2237 struct device_node *np = pdev->dev.of_node; 2274 struct device_node *np = pdev->dev.of_node;
2238 u32 val; 2275 u32 val;
2239 2276
2277 /* Optional pwrdwn GPIO configured? */
2278 ret = try_toggle_control_gpio(&pdev->dev, &lp->power_gpio,
2279 "power", 0, 0, 100);
2280 if (ret)
2281 return ret;
2282
2283 /*
2284 * Optional reset GPIO configured? Minimum 100 ns reset needed
2285 * according to LAN91C96 datasheet page 14.
2286 */
2287 ret = try_toggle_control_gpio(&pdev->dev, &lp->reset_gpio,
2288 "reset", 0, 0, 100);
2289 if (ret)
2290 return ret;
2291
2292 /*
2293 * Need to wait for optional EEPROM to load, max 750 us according
2294 * to LAN91C96 datasheet page 55.
2295 */
2296 if (lp->reset_gpio)
2297 usleep_range(750, 1000);
2298
2240 /* Combination of IO widths supported, default to 16-bit */ 2299 /* Combination of IO widths supported, default to 16-bit */
2241 if (!of_property_read_u32(np, "reg-io-width", &val)) { 2300 if (!of_property_read_u32(np, "reg-io-width", &val)) {
2242 if (val & 1) 2301 if (val & 1)
@@ -2279,16 +2338,19 @@ static int smc_drv_probe(struct platform_device *pdev)
2279 goto out_free_netdev; 2338 goto out_free_netdev;
2280 } 2339 }
2281 2340
2282 ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 2341 ndev->irq = platform_get_irq(pdev, 0);
2283 if (!ires) { 2342 if (ndev->irq <= 0) {
2284 ret = -ENODEV; 2343 ret = -ENODEV;
2285 goto out_release_io; 2344 goto out_release_io;
2286 } 2345 }
2287 2346 /*
2288 ndev->irq = ires->start; 2347 * If this platform does not specify any special irqflags, or if
2289 2348 * the resource supplies a trigger, override the irqflags with
2290 if (irq_flags == -1 || ires->flags & IRQF_TRIGGER_MASK) 2349 * the trigger flags from the resource.
2291 irq_flags = ires->flags & IRQF_TRIGGER_MASK; 2350 */
2351 irq_resflags = irqd_get_trigger_type(irq_get_irq_data(ndev->irq));
2352 if (irq_flags == -1 || irq_resflags & IRQF_TRIGGER_MASK)
2353 irq_flags = irq_resflags & IRQF_TRIGGER_MASK;
2292 2354
2293 ret = smc_request_attrib(pdev, ndev); 2355 ret = smc_request_attrib(pdev, ndev);
2294 if (ret) 2356 if (ret)