aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/smsc911x.c
diff options
context:
space:
mode:
authorShawn Guo <shawn.guo@linaro.org>2011-07-30 04:26:00 -0400
committerDavid S. Miller <davem@davemloft.net>2011-08-01 21:01:33 -0400
commit79f88ee9836d482891ba41b1a553e2baacf31b02 (patch)
tree216f52c4d2e6e11c90cf05d71a79bb1fea39117b /drivers/net/smsc911x.c
parentebdcc94b4b03212a1f715c39526c9b9578bba0b0 (diff)
net/smsc911x: add device tree probe support
It adds device tree probe support for smsc911x driver. Signed-off-by: Shawn Guo <shawn.guo@linaro.org> Cc: Grant Likely <grant.likely@secretlab.ca> Cc: Steve Glendinning <steve.glendinning@smsc.com> Cc: David S. Miller <davem@davemloft.net> Reviewed-by: Grant Likely <grant.likely@secretlab.ca> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/smsc911x.c')
-rw-r--r--drivers/net/smsc911x.c85
1 files changed, 74 insertions, 11 deletions
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index b9016a30cdc5..75c08a55582c 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -53,6 +53,10 @@
53#include <linux/phy.h> 53#include <linux/phy.h>
54#include <linux/smsc911x.h> 54#include <linux/smsc911x.h>
55#include <linux/device.h> 55#include <linux/device.h>
56#include <linux/of.h>
57#include <linux/of_device.h>
58#include <linux/of_gpio.h>
59#include <linux/of_net.h>
56#include "smsc911x.h" 60#include "smsc911x.h"
57 61
58#define SMSC_CHIPNAME "smsc911x" 62#define SMSC_CHIPNAME "smsc911x"
@@ -2095,8 +2099,58 @@ static const struct smsc911x_ops shifted_smsc911x_ops = {
2095 .tx_writefifo = smsc911x_tx_writefifo_shift, 2099 .tx_writefifo = smsc911x_tx_writefifo_shift,
2096}; 2100};
2097 2101
2102#ifdef CONFIG_OF
2103static int __devinit smsc911x_probe_config_dt(
2104 struct smsc911x_platform_config *config,
2105 struct device_node *np)
2106{
2107 const char *mac;
2108 u32 width = 0;
2109
2110 if (!np)
2111 return -ENODEV;
2112
2113 config->phy_interface = of_get_phy_mode(np);
2114
2115 mac = of_get_mac_address(np);
2116 if (mac)
2117 memcpy(config->mac, mac, ETH_ALEN);
2118
2119 of_property_read_u32(np, "reg-shift", &config->shift);
2120
2121 of_property_read_u32(np, "reg-io-width", &width);
2122 if (width == 4)
2123 config->flags |= SMSC911X_USE_32BIT;
2124
2125 if (of_get_property(np, "smsc,irq-active-high", NULL))
2126 config->irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH;
2127
2128 if (of_get_property(np, "smsc,irq-push-pull", NULL))
2129 config->irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL;
2130
2131 if (of_get_property(np, "smsc,force-internal-phy", NULL))
2132 config->flags |= SMSC911X_FORCE_INTERNAL_PHY;
2133
2134 if (of_get_property(np, "smsc,force-external-phy", NULL))
2135 config->flags |= SMSC911X_FORCE_EXTERNAL_PHY;
2136
2137 if (of_get_property(np, "smsc,save-mac-address", NULL))
2138 config->flags |= SMSC911X_SAVE_MAC_ADDRESS;
2139
2140 return 0;
2141}
2142#else
2143static inline int smsc911x_probe_config_dt(
2144 struct smsc911x_platform_config *config,
2145 struct device_node *np)
2146{
2147 return -ENODEV;
2148}
2149#endif /* CONFIG_OF */
2150
2098static int __devinit smsc911x_drv_probe(struct platform_device *pdev) 2151static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
2099{ 2152{
2153 struct device_node *np = pdev->dev.of_node;
2100 struct net_device *dev; 2154 struct net_device *dev;
2101 struct smsc911x_data *pdata; 2155 struct smsc911x_data *pdata;
2102 struct smsc911x_platform_config *config = pdev->dev.platform_data; 2156 struct smsc911x_platform_config *config = pdev->dev.platform_data;
@@ -2107,13 +2161,6 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
2107 2161
2108 pr_info("Driver version %s\n", SMSC_DRV_VERSION); 2162 pr_info("Driver version %s\n", SMSC_DRV_VERSION);
2109 2163
2110 /* platform data specifies irq & dynamic bus configuration */
2111 if (!pdev->dev.platform_data) {
2112 pr_warn("platform_data not provided\n");
2113 retval = -ENODEV;
2114 goto out_0;
2115 }
2116
2117 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, 2164 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
2118 "smsc911x-memory"); 2165 "smsc911x-memory");
2119 if (!res) 2166 if (!res)
@@ -2152,9 +2199,6 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
2152 irq_flags = irq_res->flags & IRQF_TRIGGER_MASK; 2199 irq_flags = irq_res->flags & IRQF_TRIGGER_MASK;
2153 pdata->ioaddr = ioremap_nocache(res->start, res_size); 2200 pdata->ioaddr = ioremap_nocache(res->start, res_size);
2154 2201
2155 /* copy config parameters across to pdata */
2156 memcpy(&pdata->config, config, sizeof(pdata->config));
2157
2158 pdata->dev = dev; 2202 pdata->dev = dev;
2159 pdata->msg_enable = ((1 << debug) - 1); 2203 pdata->msg_enable = ((1 << debug) - 1);
2160 2204
@@ -2164,10 +2208,22 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
2164 goto out_free_netdev_2; 2208 goto out_free_netdev_2;
2165 } 2209 }
2166 2210
2211 retval = smsc911x_probe_config_dt(&pdata->config, np);
2212 if (retval && config) {
2213 /* copy config parameters across to pdata */
2214 memcpy(&pdata->config, config, sizeof(pdata->config));
2215 retval = 0;
2216 }
2217
2218 if (retval) {
2219 SMSC_WARN(pdata, probe, "Error smsc911x config not found");
2220 goto out_unmap_io_3;
2221 }
2222
2167 /* assume standard, non-shifted, access to HW registers */ 2223 /* assume standard, non-shifted, access to HW registers */
2168 pdata->ops = &standard_smsc911x_ops; 2224 pdata->ops = &standard_smsc911x_ops;
2169 /* apply the right access if shifting is needed */ 2225 /* apply the right access if shifting is needed */
2170 if (config->shift) 2226 if (pdata->config.shift)
2171 pdata->ops = &shifted_smsc911x_ops; 2227 pdata->ops = &shifted_smsc911x_ops;
2172 2228
2173 retval = smsc911x_init(dev); 2229 retval = smsc911x_init(dev);
@@ -2314,6 +2370,12 @@ static const struct dev_pm_ops smsc911x_pm_ops = {
2314#define SMSC911X_PM_OPS NULL 2370#define SMSC911X_PM_OPS NULL
2315#endif 2371#endif
2316 2372
2373static const struct of_device_id smsc911x_dt_ids[] = {
2374 { .compatible = "smsc,lan9115", },
2375 { /* sentinel */ }
2376};
2377MODULE_DEVICE_TABLE(of, smsc911x_dt_ids);
2378
2317static struct platform_driver smsc911x_driver = { 2379static struct platform_driver smsc911x_driver = {
2318 .probe = smsc911x_drv_probe, 2380 .probe = smsc911x_drv_probe,
2319 .remove = __devexit_p(smsc911x_drv_remove), 2381 .remove = __devexit_p(smsc911x_drv_remove),
@@ -2321,6 +2383,7 @@ static struct platform_driver smsc911x_driver = {
2321 .name = SMSC_CHIPNAME, 2383 .name = SMSC_CHIPNAME,
2322 .owner = THIS_MODULE, 2384 .owner = THIS_MODULE,
2323 .pm = SMSC911X_PM_OPS, 2385 .pm = SMSC911X_PM_OPS,
2386 .of_match_table = smsc911x_dt_ids,
2324 }, 2387 },
2325}; 2388};
2326 2389