diff options
author | Lennert Buytenhek <buytenh@wantstofly.org> | 2008-04-23 19:27:02 -0400 |
---|---|---|
committer | Dale Farnsworth <dale@farnsworth.org> | 2008-04-29 00:17:07 -0400 |
commit | fa3959f457109cc7d082b86ea6daae927982815b (patch) | |
tree | 0e1f7aae6f3340d915f61e1489615972c629621d /drivers/net/mv643xx_eth.c | |
parent | e31a94ed371c70855eb30b77c490d6d85dd4da26 (diff) |
mv643xx_eth: get rid of static variables, allow multiple instances
Move mv643xx_eth's static state (ethernet register block base address
and MII management interface spinlock) into a struct hanging off the
shared platform device. This is necessary to support chips that
contain multiple mv643xx_eth silicon blocks.
Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
Acked-by: Nicolas Pitre <nico@marvell.com>
Signed-off-by: Dale Farnsworth <dale@farnsworth.org>
Diffstat (limited to 'drivers/net/mv643xx_eth.c')
-rw-r--r-- | drivers/net/mv643xx_eth.c | 62 |
1 files changed, 45 insertions, 17 deletions
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 381b36e5f64c..eebf0d288e36 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c | |||
@@ -507,7 +507,15 @@ struct mv643xx_mib_counters { | |||
507 | u32 late_collision; | 507 | u32 late_collision; |
508 | }; | 508 | }; |
509 | 509 | ||
510 | struct mv643xx_shared_private { | ||
511 | void __iomem *eth_base; | ||
512 | |||
513 | /* used to protect SMI_REG, which is shared across ports */ | ||
514 | spinlock_t phy_lock; | ||
515 | }; | ||
516 | |||
510 | struct mv643xx_private { | 517 | struct mv643xx_private { |
518 | struct mv643xx_shared_private *shared; | ||
511 | int port_num; /* User Ethernet port number */ | 519 | int port_num; /* User Ethernet port number */ |
512 | 520 | ||
513 | u32 rx_sram_addr; /* Base address of rx sram area */ | 521 | u32 rx_sram_addr; /* Base address of rx sram area */ |
@@ -614,19 +622,14 @@ static const struct ethtool_ops mv643xx_ethtool_ops; | |||
614 | static char mv643xx_driver_name[] = "mv643xx_eth"; | 622 | static char mv643xx_driver_name[] = "mv643xx_eth"; |
615 | static char mv643xx_driver_version[] = "1.0"; | 623 | static char mv643xx_driver_version[] = "1.0"; |
616 | 624 | ||
617 | static void __iomem *mv643xx_eth_base; | ||
618 | |||
619 | /* used to protect SMI_REG, which is shared across ports */ | ||
620 | static DEFINE_SPINLOCK(mv643xx_eth_phy_lock); | ||
621 | |||
622 | static inline u32 rdl(struct mv643xx_private *mp, int offset) | 625 | static inline u32 rdl(struct mv643xx_private *mp, int offset) |
623 | { | 626 | { |
624 | return readl(mv643xx_eth_base + offset); | 627 | return readl(mp->shared->eth_base + offset); |
625 | } | 628 | } |
626 | 629 | ||
627 | static inline void wrl(struct mv643xx_private *mp, int offset, u32 data) | 630 | static inline void wrl(struct mv643xx_private *mp, int offset, u32 data) |
628 | { | 631 | { |
629 | writel(data, mv643xx_eth_base + offset); | 632 | writel(data, mp->shared->eth_base + offset); |
630 | } | 633 | } |
631 | 634 | ||
632 | /* | 635 | /* |
@@ -1827,6 +1830,11 @@ static int mv643xx_eth_probe(struct platform_device *pdev) | |||
1827 | return -ENODEV; | 1830 | return -ENODEV; |
1828 | } | 1831 | } |
1829 | 1832 | ||
1833 | if (pd->shared == NULL) { | ||
1834 | printk(KERN_ERR "No mv643xx_eth_platform_data->shared\n"); | ||
1835 | return -ENODEV; | ||
1836 | } | ||
1837 | |||
1830 | dev = alloc_etherdev(sizeof(struct mv643xx_private)); | 1838 | dev = alloc_etherdev(sizeof(struct mv643xx_private)); |
1831 | if (!dev) | 1839 | if (!dev) |
1832 | return -ENOMEM; | 1840 | return -ENOMEM; |
@@ -1877,6 +1885,7 @@ static int mv643xx_eth_probe(struct platform_device *pdev) | |||
1877 | 1885 | ||
1878 | spin_lock_init(&mp->lock); | 1886 | spin_lock_init(&mp->lock); |
1879 | 1887 | ||
1888 | mp->shared = platform_get_drvdata(pd->shared); | ||
1880 | port_num = mp->port_num = pd->port_number; | 1889 | port_num = mp->port_num = pd->port_number; |
1881 | 1890 | ||
1882 | /* set default config values */ | 1891 | /* set default config values */ |
@@ -1986,27 +1995,46 @@ static int mv643xx_eth_remove(struct platform_device *pdev) | |||
1986 | static int mv643xx_eth_shared_probe(struct platform_device *pdev) | 1995 | static int mv643xx_eth_shared_probe(struct platform_device *pdev) |
1987 | { | 1996 | { |
1988 | static int mv643xx_version_printed = 0; | 1997 | static int mv643xx_version_printed = 0; |
1998 | struct mv643xx_shared_private *msp; | ||
1989 | struct resource *res; | 1999 | struct resource *res; |
2000 | int ret; | ||
1990 | 2001 | ||
1991 | if (!mv643xx_version_printed++) | 2002 | if (!mv643xx_version_printed++) |
1992 | printk(KERN_NOTICE "MV-643xx 10/100/1000 Ethernet Driver\n"); | 2003 | printk(KERN_NOTICE "MV-643xx 10/100/1000 Ethernet Driver\n"); |
1993 | 2004 | ||
2005 | ret = -EINVAL; | ||
1994 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2006 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1995 | if (res == NULL) | 2007 | if (res == NULL) |
1996 | return -ENODEV; | 2008 | goto out; |
1997 | 2009 | ||
1998 | mv643xx_eth_base = ioremap(res->start, res->end - res->start + 1); | 2010 | ret = -ENOMEM; |
1999 | if (mv643xx_eth_base == NULL) | 2011 | msp = kmalloc(sizeof(*msp), GFP_KERNEL); |
2000 | return -ENOMEM; | 2012 | if (msp == NULL) |
2013 | goto out; | ||
2014 | memset(msp, 0, sizeof(*msp)); | ||
2015 | |||
2016 | msp->eth_base = ioremap(res->start, res->end - res->start + 1); | ||
2017 | if (msp->eth_base == NULL) | ||
2018 | goto out_free; | ||
2019 | |||
2020 | spin_lock_init(&msp->phy_lock); | ||
2021 | |||
2022 | platform_set_drvdata(pdev, msp); | ||
2001 | 2023 | ||
2002 | return 0; | 2024 | return 0; |
2003 | 2025 | ||
2026 | out_free: | ||
2027 | kfree(msp); | ||
2028 | out: | ||
2029 | return ret; | ||
2004 | } | 2030 | } |
2005 | 2031 | ||
2006 | static int mv643xx_eth_shared_remove(struct platform_device *pdev) | 2032 | static int mv643xx_eth_shared_remove(struct platform_device *pdev) |
2007 | { | 2033 | { |
2008 | iounmap(mv643xx_eth_base); | 2034 | struct mv643xx_shared_private *msp = platform_get_drvdata(pdev); |
2009 | mv643xx_eth_base = NULL; | 2035 | |
2036 | iounmap(msp->eth_base); | ||
2037 | kfree(msp); | ||
2010 | 2038 | ||
2011 | return 0; | 2039 | return 0; |
2012 | } | 2040 | } |
@@ -2911,7 +2939,7 @@ static void eth_port_read_smi_reg(struct mv643xx_private *mp, | |||
2911 | int i; | 2939 | int i; |
2912 | 2940 | ||
2913 | /* the SMI register is a shared resource */ | 2941 | /* the SMI register is a shared resource */ |
2914 | spin_lock_irqsave(&mv643xx_eth_phy_lock, flags); | 2942 | spin_lock_irqsave(&mp->shared->phy_lock, flags); |
2915 | 2943 | ||
2916 | /* wait for the SMI register to become available */ | 2944 | /* wait for the SMI register to become available */ |
2917 | for (i = 0; rdl(mp, SMI_REG) & ETH_SMI_BUSY; i++) { | 2945 | for (i = 0; rdl(mp, SMI_REG) & ETH_SMI_BUSY; i++) { |
@@ -2936,7 +2964,7 @@ static void eth_port_read_smi_reg(struct mv643xx_private *mp, | |||
2936 | 2964 | ||
2937 | *value = rdl(mp, SMI_REG) & 0xffff; | 2965 | *value = rdl(mp, SMI_REG) & 0xffff; |
2938 | out: | 2966 | out: |
2939 | spin_unlock_irqrestore(&mv643xx_eth_phy_lock, flags); | 2967 | spin_unlock_irqrestore(&mp->shared->phy_lock, flags); |
2940 | } | 2968 | } |
2941 | 2969 | ||
2942 | /* | 2970 | /* |
@@ -2969,7 +2997,7 @@ static void eth_port_write_smi_reg(struct mv643xx_private *mp, | |||
2969 | phy_addr = ethernet_phy_get(mp); | 2997 | phy_addr = ethernet_phy_get(mp); |
2970 | 2998 | ||
2971 | /* the SMI register is a shared resource */ | 2999 | /* the SMI register is a shared resource */ |
2972 | spin_lock_irqsave(&mv643xx_eth_phy_lock, flags); | 3000 | spin_lock_irqsave(&mp->shared->phy_lock, flags); |
2973 | 3001 | ||
2974 | /* wait for the SMI register to become available */ | 3002 | /* wait for the SMI register to become available */ |
2975 | for (i = 0; rdl(mp, SMI_REG) & ETH_SMI_BUSY; i++) { | 3003 | for (i = 0; rdl(mp, SMI_REG) & ETH_SMI_BUSY; i++) { |
@@ -2983,7 +3011,7 @@ static void eth_port_write_smi_reg(struct mv643xx_private *mp, | |||
2983 | wrl(mp, SMI_REG, (phy_addr << 16) | (phy_reg << 21) | | 3011 | wrl(mp, SMI_REG, (phy_addr << 16) | (phy_reg << 21) | |
2984 | ETH_SMI_OPCODE_WRITE | (value & 0xffff)); | 3012 | ETH_SMI_OPCODE_WRITE | (value & 0xffff)); |
2985 | out: | 3013 | out: |
2986 | spin_unlock_irqrestore(&mv643xx_eth_phy_lock, flags); | 3014 | spin_unlock_irqrestore(&mp->shared->phy_lock, flags); |
2987 | } | 3015 | } |
2988 | 3016 | ||
2989 | /* | 3017 | /* |