aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2009-01-28 18:03:11 -0500
committerDavid S. Miller <davem@davemloft.net>2009-02-01 03:58:26 -0500
commitead731837d142b103eab9870105f50bc40b69255 (patch)
tree2c58dcfb60b042af8e73d58e8dbef9a351768c32 /drivers/net
parent196719ecec0c526de273dcb902f0be956a193232 (diff)
FEC: Turn FEC driver into platform device driver
This turns the fec driver into a platform device driver for new platforms. Old platforms are still supported through a FEC_LEGACY define till they are also ported. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Acked-by: Greg Ungerer <gerg@uclinux.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/fec.c249
1 files changed, 220 insertions, 29 deletions
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 7631062cd44d..ea23baaf0256 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -39,6 +39,7 @@
39#include <linux/io.h> 39#include <linux/io.h>
40#include <linux/irq.h> 40#include <linux/irq.h>
41#include <linux/clk.h> 41#include <linux/clk.h>
42#include <linux/platform_device.h>
42 43
43#include <asm/cacheflush.h> 44#include <asm/cacheflush.h>
44 45
@@ -49,12 +50,6 @@
49 50
50#include "fec.h" 51#include "fec.h"
51 52
52#if defined(CONFIG_FEC2)
53#define FEC_MAX_PORTS 2
54#else
55#define FEC_MAX_PORTS 1
56#endif
57
58#ifdef CONFIG_ARCH_MXC 53#ifdef CONFIG_ARCH_MXC
59#include <mach/hardware.h> 54#include <mach/hardware.h>
60#define FEC_ALIGNMENT 0xf 55#define FEC_ALIGNMENT 0xf
@@ -62,13 +57,22 @@
62#define FEC_ALIGNMENT 0x3 57#define FEC_ALIGNMENT 0x3
63#endif 58#endif
64 59
60#if defined CONFIG_M5272 || defined CONFIG_M527x || defined CONFIG_M523x \
61 || defined CONFIG_M528x || defined CONFIG_M532x || defined CONFIG_M520x
62#define FEC_LEGACY
63/*
64 * Define the fixed address of the FEC hardware.
65 */
65#if defined(CONFIG_M5272) 66#if defined(CONFIG_M5272)
66#define HAVE_mii_link_interrupt 67#define HAVE_mii_link_interrupt
67#endif 68#endif
68 69
69/* 70#if defined(CONFIG_FEC2)
70 * Define the fixed address of the FEC hardware. 71#define FEC_MAX_PORTS 2
71 */ 72#else
73#define FEC_MAX_PORTS 1
74#endif
75
72static unsigned int fec_hw[] = { 76static unsigned int fec_hw[] = {
73#if defined(CONFIG_M5272) 77#if defined(CONFIG_M5272)
74 (MCF_MBAR + 0x840), 78 (MCF_MBAR + 0x840),
@@ -106,6 +110,8 @@ static unsigned char fec_mac_default[] = {
106#define FEC_FLASHMAC 0 110#define FEC_FLASHMAC 0
107#endif 111#endif
108 112
113#endif /* FEC_LEGACY */
114
109/* Forward declarations of some structures to support different PHYs 115/* Forward declarations of some structures to support different PHYs
110*/ 116*/
111 117
@@ -189,6 +195,8 @@ struct fec_enet_private {
189 195
190 struct net_device *netdev; 196 struct net_device *netdev;
191 197
198 struct clk *clk;
199
192 /* The saved address of a sent-in-place packet/buffer, for skfree(). */ 200 /* The saved address of a sent-in-place packet/buffer, for skfree(). */
193 unsigned char *tx_bounce[TX_RING_SIZE]; 201 unsigned char *tx_bounce[TX_RING_SIZE];
194 struct sk_buff* tx_skbuff[TX_RING_SIZE]; 202 struct sk_buff* tx_skbuff[TX_RING_SIZE];
@@ -1919,7 +1927,9 @@ mii_discover_phy(uint mii_reg, struct net_device *dev)
1919 printk("FEC: No PHY device found.\n"); 1927 printk("FEC: No PHY device found.\n");
1920 /* Disable external MII interface */ 1928 /* Disable external MII interface */
1921 fecp->fec_mii_speed = fep->phy_speed = 0; 1929 fecp->fec_mii_speed = fep->phy_speed = 0;
1930#ifdef FREC_LEGACY
1922 fec_disable_phy_intr(); 1931 fec_disable_phy_intr();
1932#endif
1923 } 1933 }
1924} 1934}
1925 1935
@@ -2101,12 +2111,12 @@ fec_set_mac_address(struct net_device *dev)
2101 2111
2102} 2112}
2103 2113
2104/* Initialize the FEC Ethernet on 860T (or ColdFire 5272).
2105 */
2106 /* 2114 /*
2107 * XXX: We need to clean up on failure exits here. 2115 * XXX: We need to clean up on failure exits here.
2116 *
2117 * index is only used in legacy code
2108 */ 2118 */
2109int __init fec_enet_init(struct net_device *dev) 2119int __init fec_enet_init(struct net_device *dev, int index)
2110{ 2120{
2111 struct fec_enet_private *fep = netdev_priv(dev); 2121 struct fec_enet_private *fep = netdev_priv(dev);
2112 unsigned long mem_addr; 2122 unsigned long mem_addr;
@@ -2114,11 +2124,6 @@ int __init fec_enet_init(struct net_device *dev)
2114 cbd_t *cbd_base; 2124 cbd_t *cbd_base;
2115 volatile fec_t *fecp; 2125 volatile fec_t *fecp;
2116 int i, j; 2126 int i, j;
2117 static int index = 0;
2118
2119 /* Only allow us to be probed once. */
2120 if (index >= FEC_MAX_PORTS)
2121 return -ENXIO;
2122 2127
2123 /* Allocate memory for buffer descriptors. 2128 /* Allocate memory for buffer descriptors.
2124 */ 2129 */
@@ -2134,7 +2139,7 @@ int __init fec_enet_init(struct net_device *dev)
2134 2139
2135 /* Create an Ethernet device instance. 2140 /* Create an Ethernet device instance.
2136 */ 2141 */
2137 fecp = (volatile fec_t *) fec_hw[index]; 2142 fecp = (volatile fec_t *)dev->base_addr;
2138 2143
2139 fep->index = index; 2144 fep->index = index;
2140 fep->hwp = fecp; 2145 fep->hwp = fecp;
@@ -2145,16 +2150,24 @@ int __init fec_enet_init(struct net_device *dev)
2145 fecp->fec_ecntrl = 1; 2150 fecp->fec_ecntrl = 1;
2146 udelay(10); 2151 udelay(10);
2147 2152
2148 /* Set the Ethernet address. If using multiple Enets on the 8xx, 2153 /* Set the Ethernet address */
2149 * this needs some work to get unique addresses. 2154#ifdef FEC_LEGACY
2150 *
2151 * This is our default MAC address unless the user changes
2152 * it via eth_mac_addr (our dev->set_mac_addr handler).
2153 */
2154 fec_get_mac(dev); 2155 fec_get_mac(dev);
2156#else
2157 {
2158 unsigned long l;
2159 l = fecp->fec_addr_low;
2160 dev->dev_addr[0] = (unsigned char)((l & 0xFF000000) >> 24);
2161 dev->dev_addr[1] = (unsigned char)((l & 0x00FF0000) >> 16);
2162 dev->dev_addr[2] = (unsigned char)((l & 0x0000FF00) >> 8);
2163 dev->dev_addr[3] = (unsigned char)((l & 0x000000FF) >> 0);
2164 l = fecp->fec_addr_high;
2165 dev->dev_addr[4] = (unsigned char)((l & 0xFF000000) >> 24);
2166 dev->dev_addr[5] = (unsigned char)((l & 0x00FF0000) >> 16);
2167 }
2168#endif
2155 2169
2156 cbd_base = (cbd_t *)mem_addr; 2170 cbd_base = (cbd_t *)mem_addr;
2157 /* XXX: missing check for allocation failure */
2158 2171
2159 /* Set receive and transmit descriptor base. 2172 /* Set receive and transmit descriptor base.
2160 */ 2173 */
@@ -2222,10 +2235,12 @@ int __init fec_enet_init(struct net_device *dev)
2222 fecp->fec_x_des_start = (unsigned long)fep->bd_dma + sizeof(cbd_t) 2235 fecp->fec_x_des_start = (unsigned long)fep->bd_dma + sizeof(cbd_t)
2223 * RX_RING_SIZE; 2236 * RX_RING_SIZE;
2224 2237
2238#ifdef FEC_LEGACY
2225 /* Install our interrupt handlers. This varies depending on 2239 /* Install our interrupt handlers. This varies depending on
2226 * the architecture. 2240 * the architecture.
2227 */ 2241 */
2228 fec_request_intrs(dev); 2242 fec_request_intrs(dev);
2243#endif
2229 2244
2230 fecp->fec_grp_hash_table_high = 0; 2245 fecp->fec_grp_hash_table_high = 0;
2231 fecp->fec_grp_hash_table_low = 0; 2246 fecp->fec_grp_hash_table_low = 0;
@@ -2237,8 +2252,6 @@ int __init fec_enet_init(struct net_device *dev)
2237 fecp->fec_hash_table_low = 0; 2252 fecp->fec_hash_table_low = 0;
2238#endif 2253#endif
2239 2254
2240 dev->base_addr = (unsigned long)fecp;
2241
2242 /* The FEC Ethernet specific entries in the device structure. */ 2255 /* The FEC Ethernet specific entries in the device structure. */
2243 dev->open = fec_enet_open; 2256 dev->open = fec_enet_open;
2244 dev->hard_start_xmit = fec_enet_start_xmit; 2257 dev->hard_start_xmit = fec_enet_start_xmit;
@@ -2252,7 +2265,20 @@ int __init fec_enet_init(struct net_device *dev)
2252 mii_free = mii_cmds; 2265 mii_free = mii_cmds;
2253 2266
2254 /* setup MII interface */ 2267 /* setup MII interface */
2268#ifdef FEC_LEGACY
2255 fec_set_mii(dev, fep); 2269 fec_set_mii(dev, fep);
2270#else
2271 fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
2272 fecp->fec_x_cntrl = 0x00;
2273
2274 /*
2275 * Set MII speed to 2.5 MHz
2276 */
2277 fep->phy_speed = ((((clk_get_rate(fep->clk) / 2 + 4999999)
2278 / 2500000) / 2) & 0x3F) << 1;
2279 fecp->fec_mii_speed = fep->phy_speed;
2280 fec_restart(dev, 0);
2281#endif
2256 2282
2257 /* Clear and enable interrupts */ 2283 /* Clear and enable interrupts */
2258 fecp->fec_ievent = 0xffc00000; 2284 fecp->fec_ievent = 0xffc00000;
@@ -2265,7 +2291,6 @@ int __init fec_enet_init(struct net_device *dev)
2265 fep->phy_addr = 0; 2291 fep->phy_addr = 0;
2266 mii_queue(dev, mk_mii_read(MII_REG_PHYIR1), mii_discover_phy); 2292 mii_queue(dev, mk_mii_read(MII_REG_PHYIR1), mii_discover_phy);
2267 2293
2268 index++;
2269 return 0; 2294 return 0;
2270} 2295}
2271 2296
@@ -2417,6 +2442,7 @@ fec_stop(struct net_device *dev)
2417 fecp->fec_mii_speed = fep->phy_speed; 2442 fecp->fec_mii_speed = fep->phy_speed;
2418} 2443}
2419 2444
2445#ifdef FEC_LEGACY
2420static int __init fec_enet_module_init(void) 2446static int __init fec_enet_module_init(void)
2421{ 2447{
2422 struct net_device *dev; 2448 struct net_device *dev;
@@ -2428,7 +2454,8 @@ static int __init fec_enet_module_init(void)
2428 dev = alloc_etherdev(sizeof(struct fec_enet_private)); 2454 dev = alloc_etherdev(sizeof(struct fec_enet_private));
2429 if (!dev) 2455 if (!dev)
2430 return -ENOMEM; 2456 return -ENOMEM;
2431 err = fec_enet_init(dev); 2457 dev->base_addr = (unsigned long)fec_hw[i];
2458 err = fec_enet_init(dev, i);
2432 if (err) { 2459 if (err) {
2433 free_netdev(dev); 2460 free_netdev(dev);
2434 continue; 2461 continue;
@@ -2443,6 +2470,170 @@ static int __init fec_enet_module_init(void)
2443 } 2470 }
2444 return 0; 2471 return 0;
2445} 2472}
2473#else
2474
2475static int __devinit
2476fec_probe(struct platform_device *pdev)
2477{
2478 struct fec_enet_private *fep;
2479 struct net_device *ndev;
2480 int i, irq, ret = 0;
2481 struct resource *r;
2482
2483 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2484 if (!r)
2485 return -ENXIO;
2486
2487 r = request_mem_region(r->start, resource_size(r), pdev->name);
2488 if (!r)
2489 return -EBUSY;
2490
2491 /* Init network device */
2492 ndev = alloc_etherdev(sizeof(struct fec_enet_private));
2493 if (!ndev)
2494 return -ENOMEM;
2495
2496 SET_NETDEV_DEV(ndev, &pdev->dev);
2497
2498 /* setup board info structure */
2499 fep = netdev_priv(ndev);
2500 memset(fep, 0, sizeof(*fep));
2501
2502 ndev->base_addr = (unsigned long)ioremap(r->start, resource_size(r));
2503
2504 if (!ndev->base_addr) {
2505 ret = -ENOMEM;
2506 goto failed_ioremap;
2507 }
2508
2509 platform_set_drvdata(pdev, ndev);
2510
2511 /* This device has up to three irqs on some platforms */
2512 for (i = 0; i < 3; i++) {
2513 irq = platform_get_irq(pdev, i);
2514 if (i && irq < 0)
2515 break;
2516 ret = request_irq(irq, fec_enet_interrupt, IRQF_DISABLED, pdev->name, ndev);
2517 if (ret) {
2518 while (i >= 0) {
2519 irq = platform_get_irq(pdev, i);
2520 free_irq(irq, ndev);
2521 i--;
2522 }
2523 goto failed_irq;
2524 }
2525 }
2526
2527 fep->clk = clk_get(&pdev->dev, "fec_clk");
2528 if (IS_ERR(fep->clk)) {
2529 ret = PTR_ERR(fep->clk);
2530 goto failed_clk;
2531 }
2532 clk_enable(fep->clk);
2533
2534 ret = fec_enet_init(ndev, 0);
2535 if (ret)
2536 goto failed_init;
2537
2538 ret = register_netdev(ndev);
2539 if (ret)
2540 goto failed_register;
2541
2542 return 0;
2543
2544failed_register:
2545failed_init:
2546 clk_disable(fep->clk);
2547 clk_put(fep->clk);
2548failed_clk:
2549 for (i = 0; i < 3; i++) {
2550 irq = platform_get_irq(pdev, i);
2551 if (irq > 0)
2552 free_irq(irq, ndev);
2553 }
2554failed_irq:
2555 iounmap((void __iomem *)ndev->base_addr);
2556failed_ioremap:
2557 free_netdev(ndev);
2558
2559 return ret;
2560}
2561
2562static int __devexit
2563fec_drv_remove(struct platform_device *pdev)
2564{
2565 struct net_device *ndev = platform_get_drvdata(pdev);
2566 struct fec_enet_private *fep = netdev_priv(ndev);
2567
2568 platform_set_drvdata(pdev, NULL);
2569
2570 fec_stop(ndev);
2571 clk_disable(fep->clk);
2572 clk_put(fep->clk);
2573 iounmap((void __iomem *)ndev->base_addr);
2574 unregister_netdev(ndev);
2575 free_netdev(ndev);
2576 return 0;
2577}
2578
2579static int
2580fec_suspend(struct platform_device *dev, pm_message_t state)
2581{
2582 struct net_device *ndev = platform_get_drvdata(dev);
2583 struct fec_enet_private *fep;
2584
2585 if (ndev) {
2586 fep = netdev_priv(ndev);
2587 if (netif_running(ndev)) {
2588 netif_device_detach(ndev);
2589 fec_stop(ndev);
2590 }
2591 }
2592 return 0;
2593}
2594
2595static int
2596fec_resume(struct platform_device *dev)
2597{
2598 struct net_device *ndev = platform_get_drvdata(dev);
2599
2600 if (ndev) {
2601 if (netif_running(ndev)) {
2602 fec_enet_init(ndev, 0);
2603 netif_device_attach(ndev);
2604 }
2605 }
2606 return 0;
2607}
2608
2609static struct platform_driver fec_driver = {
2610 .driver = {
2611 .name = "fec",
2612 .owner = THIS_MODULE,
2613 },
2614 .probe = fec_probe,
2615 .remove = __devexit_p(fec_drv_remove),
2616 .suspend = fec_suspend,
2617 .resume = fec_resume,
2618};
2619
2620static int __init
2621fec_enet_module_init(void)
2622{
2623 printk(KERN_INFO "FEC Ethernet Driver\n");
2624
2625 return platform_driver_register(&fec_driver);
2626}
2627
2628static void __exit
2629fec_enet_cleanup(void)
2630{
2631 platform_driver_unregister(&fec_driver);
2632}
2633
2634module_exit(fec_enet_cleanup);
2635
2636#endif /* FEC_LEGACY */
2446 2637
2447module_init(fec_enet_module_init); 2638module_init(fec_enet_module_init);
2448 2639