Merge branch 'for-2.6.26' of git://git.farnsworth.org/dale/linux-2.6-mv643xx_eth into upstream

authored by Jeff Garzik and committed by Jeff Garzik 54c852a2 7ab267d4

+148 -39
+2
arch/arm/mach-orion5x/common.c
··· 223 223 224 224 void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data) 225 225 { 226 + eth_data->shared = &orion5x_eth_shared; 226 227 orion5x_eth.dev.platform_data = eth_data; 228 + 227 229 platform_device_register(&orion5x_eth_shared); 228 230 platform_device_register(&orion5x_eth); 229 231 }
+4
arch/powerpc/platforms/chrp/pegasos_eth.c
··· 58 58 59 59 60 60 static struct mv643xx_eth_platform_data eth0_pd = { 61 + .shared = &mv643xx_eth_shared_device, 61 62 .port_number = 0, 63 + 62 64 .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH0, 63 65 .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE, 64 66 .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16, ··· 90 88 }; 91 89 92 90 static struct mv643xx_eth_platform_data eth1_pd = { 91 + .shared = &mv643xx_eth_shared_device, 93 92 .port_number = 1, 93 + 94 94 .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH1, 95 95 .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE, 96 96 .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16,
+2
arch/powerpc/sysdev/mv64x60_dev.c
··· 239 239 240 240 memset(&pdata, 0, sizeof(pdata)); 241 241 242 + pdata.shared = shared_pdev; 243 + 242 244 prop = of_get_property(np, "reg", NULL); 243 245 if (!prop) 244 246 return -ENODEV;
+3
arch/ppc/syslib/mv64x60.c
··· 341 341 }; 342 342 343 343 static struct mv643xx_eth_platform_data eth0_pd = { 344 + .shared = &mv64x60_eth_shared_device; 344 345 .port_number = 0, 345 346 }; 346 347 ··· 367 366 }; 368 367 369 368 static struct mv643xx_eth_platform_data eth1_pd = { 369 + .shared = &mv64x60_eth_shared_device; 370 370 .port_number = 1, 371 371 }; 372 372 ··· 393 391 }; 394 392 395 393 static struct mv643xx_eth_platform_data eth2_pd = { 394 + .shared = &mv64x60_eth_shared_device; 396 395 .port_number = 2, 397 396 }; 398 397
+123 -37
drivers/net/mv643xx_eth.c
··· 91 91 */ 92 92 #define PHY_ADDR_REG 0x0000 93 93 #define SMI_REG 0x0004 94 + #define WINDOW_BASE(i) (0x0200 + ((i) << 3)) 95 + #define WINDOW_SIZE(i) (0x0204 + ((i) << 3)) 96 + #define WINDOW_REMAP_HIGH(i) (0x0280 + ((i) << 2)) 97 + #define WINDOW_BAR_ENABLE 0x0290 98 + #define WINDOW_PROTECT(i) (0x0294 + ((i) << 4)) 94 99 95 100 /* 96 101 * Per-port registers. ··· 512 507 u32 late_collision; 513 508 }; 514 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 + u32 win_protect; 517 + 518 + unsigned int t_clk; 519 + }; 520 + 515 521 struct mv643xx_private { 522 + struct mv643xx_shared_private *shared; 516 523 int port_num; /* User Ethernet port number */ 524 + 525 + struct mv643xx_shared_private *shared_smi; 517 526 518 527 u32 rx_sram_addr; /* Base address of rx sram area */ 519 528 u32 rx_sram_size; /* Size of rx sram area */ ··· 633 614 static char mv643xx_driver_name[] = "mv643xx_eth"; 634 615 static char mv643xx_driver_version[] = "1.0"; 635 616 636 - static void __iomem *mv643xx_eth_base; 637 - 638 - /* used to protect SMI_REG, which is shared across ports */ 639 - static DEFINE_SPINLOCK(mv643xx_eth_phy_lock); 640 - 641 617 static inline u32 rdl(struct mv643xx_private *mp, int offset) 642 618 { 643 - return readl(mv643xx_eth_base + offset); 619 + return readl(mp->shared->eth_base + offset); 644 620 } 645 621 646 622 static inline void wrl(struct mv643xx_private *mp, int offset, u32 data) 647 623 { 648 - writel(data, mv643xx_eth_base + offset); 624 + writel(data, mp->shared->eth_base + offset); 649 625 } 650 626 651 627 /* ··· 1133 1119 * 1134 1120 * INPUT: 1135 1121 * struct mv643xx_private *mp Ethernet port 1136 - * unsigned int t_clk t_clk of the MV-643xx chip in HZ units 1137 1122 * unsigned int delay Delay in usec 1138 1123 * 1139 1124 * OUTPUT: ··· 1143 1130 * 1144 1131 */ 1145 1132 static unsigned int eth_port_set_rx_coal(struct mv643xx_private *mp, 1146 - unsigned int t_clk, unsigned int delay) 1133 + unsigned int delay) 1147 1134 { 1148 1135 unsigned int port_num = mp->port_num; 1149 - unsigned int coal = ((t_clk / 1000000) * delay) / 64; 1136 + unsigned int coal = ((mp->shared->t_clk / 1000000) * delay) / 64; 1150 1137 1151 1138 /* Set RX Coalescing mechanism */ 1152 1139 wrl(mp, SDMA_CONFIG_REG(port_num), ··· 1171 1158 * 1172 1159 * INPUT: 1173 1160 * struct mv643xx_private *mp Ethernet port 1174 - * unsigned int t_clk t_clk of the MV-643xx chip in HZ units 1175 1161 * unsigned int delay Delay in uSeconds 1176 1162 * 1177 1163 * OUTPUT: ··· 1181 1169 * 1182 1170 */ 1183 1171 static unsigned int eth_port_set_tx_coal(struct mv643xx_private *mp, 1184 - unsigned int t_clk, unsigned int delay) 1172 + unsigned int delay) 1185 1173 { 1186 - unsigned int coal = ((t_clk / 1000000) * delay) / 64; 1174 + unsigned int coal = ((mp->shared->t_clk / 1000000) * delay) / 64; 1187 1175 1188 1176 /* Set TX Coalescing mechanism */ 1189 1177 wrl(mp, TX_FIFO_URGENT_THRESHOLD_REG(mp->port_num), coal << 4); ··· 1425 1413 1426 1414 #ifdef MV643XX_COAL 1427 1415 mp->rx_int_coal = 1428 - eth_port_set_rx_coal(mp, 133000000, MV643XX_RX_COAL); 1416 + eth_port_set_rx_coal(mp, MV643XX_RX_COAL); 1429 1417 #endif 1430 1418 1431 1419 mp->tx_int_coal = 1432 - eth_port_set_tx_coal(mp, 133000000, MV643XX_TX_COAL); 1420 + eth_port_set_tx_coal(mp, MV643XX_TX_COAL); 1433 1421 1434 1422 /* Unmask phy and link status changes interrupts */ 1435 1423 wrl(mp, INTERRUPT_EXTEND_MASK_REG(port_num), ETH_INT_UNMASK_ALL_EXT); ··· 1839 1827 return -ENODEV; 1840 1828 } 1841 1829 1830 + if (pd->shared == NULL) { 1831 + printk(KERN_ERR "No mv643xx_eth_platform_data->shared\n"); 1832 + return -ENODEV; 1833 + } 1834 + 1842 1835 dev = alloc_etherdev(sizeof(struct mv643xx_private)); 1843 1836 if (!dev) 1844 1837 return -ENOMEM; ··· 1894 1877 1895 1878 spin_lock_init(&mp->lock); 1896 1879 1880 + mp->shared = platform_get_drvdata(pd->shared); 1897 1881 port_num = mp->port_num = pd->port_number; 1882 + 1883 + if (mp->shared->win_protect) 1884 + wrl(mp, WINDOW_PROTECT(port_num), mp->shared->win_protect); 1885 + 1886 + mp->shared_smi = mp->shared; 1887 + if (pd->shared_smi != NULL) 1888 + mp->shared_smi = platform_get_drvdata(pd->shared_smi); 1898 1889 1899 1890 /* set default config values */ 1900 1891 eth_port_uc_addr_get(mp, dev->dev_addr); ··· 2008 1983 return 0; 2009 1984 } 2010 1985 1986 + static void mv643xx_eth_conf_mbus_windows(struct mv643xx_shared_private *msp, 1987 + struct mbus_dram_target_info *dram) 1988 + { 1989 + void __iomem *base = msp->eth_base; 1990 + u32 win_enable; 1991 + u32 win_protect; 1992 + int i; 1993 + 1994 + for (i = 0; i < 6; i++) { 1995 + writel(0, base + WINDOW_BASE(i)); 1996 + writel(0, base + WINDOW_SIZE(i)); 1997 + if (i < 4) 1998 + writel(0, base + WINDOW_REMAP_HIGH(i)); 1999 + } 2000 + 2001 + win_enable = 0x3f; 2002 + win_protect = 0; 2003 + 2004 + for (i = 0; i < dram->num_cs; i++) { 2005 + struct mbus_dram_window *cs = dram->cs + i; 2006 + 2007 + writel((cs->base & 0xffff0000) | 2008 + (cs->mbus_attr << 8) | 2009 + dram->mbus_dram_target_id, base + WINDOW_BASE(i)); 2010 + writel((cs->size - 1) & 0xffff0000, base + WINDOW_SIZE(i)); 2011 + 2012 + win_enable &= ~(1 << i); 2013 + win_protect |= 3 << (2 * i); 2014 + } 2015 + 2016 + writel(win_enable, base + WINDOW_BAR_ENABLE); 2017 + msp->win_protect = win_protect; 2018 + } 2019 + 2011 2020 static int mv643xx_eth_shared_probe(struct platform_device *pdev) 2012 2021 { 2013 2022 static int mv643xx_version_printed = 0; 2023 + struct mv643xx_eth_shared_platform_data *pd = pdev->dev.platform_data; 2024 + struct mv643xx_shared_private *msp; 2014 2025 struct resource *res; 2026 + int ret; 2015 2027 2016 2028 if (!mv643xx_version_printed++) 2017 2029 printk(KERN_NOTICE "MV-643xx 10/100/1000 Ethernet Driver\n"); 2018 2030 2031 + ret = -EINVAL; 2019 2032 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 2020 2033 if (res == NULL) 2021 - return -ENODEV; 2034 + goto out; 2022 2035 2023 - mv643xx_eth_base = ioremap(res->start, res->end - res->start + 1); 2024 - if (mv643xx_eth_base == NULL) 2025 - return -ENOMEM; 2036 + ret = -ENOMEM; 2037 + msp = kmalloc(sizeof(*msp), GFP_KERNEL); 2038 + if (msp == NULL) 2039 + goto out; 2040 + memset(msp, 0, sizeof(*msp)); 2041 + 2042 + msp->eth_base = ioremap(res->start, res->end - res->start + 1); 2043 + if (msp->eth_base == NULL) 2044 + goto out_free; 2045 + 2046 + spin_lock_init(&msp->phy_lock); 2047 + msp->t_clk = (pd != NULL && pd->t_clk != 0) ? pd->t_clk : 133000000; 2048 + 2049 + platform_set_drvdata(pdev, msp); 2050 + 2051 + /* 2052 + * (Re-)program MBUS remapping windows if we are asked to. 2053 + */ 2054 + if (pd != NULL && pd->dram != NULL) 2055 + mv643xx_eth_conf_mbus_windows(msp, pd->dram); 2026 2056 2027 2057 return 0; 2028 2058 2059 + out_free: 2060 + kfree(msp); 2061 + out: 2062 + return ret; 2029 2063 } 2030 2064 2031 2065 static int mv643xx_eth_shared_remove(struct platform_device *pdev) 2032 2066 { 2033 - iounmap(mv643xx_eth_base); 2034 - mv643xx_eth_base = NULL; 2067 + struct mv643xx_shared_private *msp = platform_get_drvdata(pdev); 2068 + 2069 + iounmap(msp->eth_base); 2070 + kfree(msp); 2035 2071 2036 2072 return 0; 2037 2073 } ··· 2992 2906 static void eth_port_read_smi_reg(struct mv643xx_private *mp, 2993 2907 unsigned int phy_reg, unsigned int *value) 2994 2908 { 2909 + void __iomem *smi_reg = mp->shared_smi->eth_base + SMI_REG; 2995 2910 int phy_addr = ethernet_phy_get(mp); 2996 2911 unsigned long flags; 2997 2912 int i; 2998 2913 2999 2914 /* the SMI register is a shared resource */ 3000 - spin_lock_irqsave(&mv643xx_eth_phy_lock, flags); 2915 + spin_lock_irqsave(&mp->shared_smi->phy_lock, flags); 3001 2916 3002 2917 /* wait for the SMI register to become available */ 3003 - for (i = 0; rdl(mp, SMI_REG) & ETH_SMI_BUSY; i++) { 2918 + for (i = 0; readl(smi_reg) & ETH_SMI_BUSY; i++) { 3004 2919 if (i == PHY_WAIT_ITERATIONS) { 3005 2920 printk("%s: PHY busy timeout\n", mp->dev->name); 3006 2921 goto out; ··· 3009 2922 udelay(PHY_WAIT_MICRO_SECONDS); 3010 2923 } 3011 2924 3012 - wrl(mp, SMI_REG, 3013 - (phy_addr << 16) | (phy_reg << 21) | ETH_SMI_OPCODE_READ); 2925 + writel((phy_addr << 16) | (phy_reg << 21) | ETH_SMI_OPCODE_READ, 2926 + smi_reg); 3014 2927 3015 2928 /* now wait for the data to be valid */ 3016 - for (i = 0; !(rdl(mp, SMI_REG) & ETH_SMI_READ_VALID); i++) { 2929 + for (i = 0; !(readl(smi_reg) & ETH_SMI_READ_VALID); i++) { 3017 2930 if (i == PHY_WAIT_ITERATIONS) { 3018 2931 printk("%s: PHY read timeout\n", mp->dev->name); 3019 2932 goto out; ··· 3021 2934 udelay(PHY_WAIT_MICRO_SECONDS); 3022 2935 } 3023 2936 3024 - *value = rdl(mp, SMI_REG) & 0xffff; 2937 + *value = readl(smi_reg) & 0xffff; 3025 2938 out: 3026 - spin_unlock_irqrestore(&mv643xx_eth_phy_lock, flags); 2939 + spin_unlock_irqrestore(&mp->shared_smi->phy_lock, flags); 3027 2940 } 3028 2941 3029 2942 /* ··· 3049 2962 static void eth_port_write_smi_reg(struct mv643xx_private *mp, 3050 2963 unsigned int phy_reg, unsigned int value) 3051 2964 { 3052 - int phy_addr; 3053 - int i; 2965 + void __iomem *smi_reg = mp->shared_smi->eth_base + SMI_REG; 2966 + int phy_addr = ethernet_phy_get(mp); 3054 2967 unsigned long flags; 3055 - 3056 - phy_addr = ethernet_phy_get(mp); 2968 + int i; 3057 2969 3058 2970 /* the SMI register is a shared resource */ 3059 - spin_lock_irqsave(&mv643xx_eth_phy_lock, flags); 2971 + spin_lock_irqsave(&mp->shared_smi->phy_lock, flags); 3060 2972 3061 2973 /* wait for the SMI register to become available */ 3062 - for (i = 0; rdl(mp, SMI_REG) & ETH_SMI_BUSY; i++) { 2974 + for (i = 0; readl(smi_reg) & ETH_SMI_BUSY; i++) { 3063 2975 if (i == PHY_WAIT_ITERATIONS) { 3064 2976 printk("%s: PHY busy timeout\n", mp->dev->name); 3065 2977 goto out; ··· 3066 2980 udelay(PHY_WAIT_MICRO_SECONDS); 3067 2981 } 3068 2982 3069 - wrl(mp, SMI_REG, (phy_addr << 16) | (phy_reg << 21) | 3070 - ETH_SMI_OPCODE_WRITE | (value & 0xffff)); 2983 + writel((phy_addr << 16) | (phy_reg << 21) | 2984 + ETH_SMI_OPCODE_WRITE | (value & 0xffff), smi_reg); 3071 2985 out: 3072 - spin_unlock_irqrestore(&mv643xx_eth_phy_lock, flags); 2986 + spin_unlock_irqrestore(&mp->shared_smi->phy_lock, flags); 3073 2987 } 3074 2988 3075 2989 /*
+14 -2
include/linux/mv643xx_eth.h
··· 1 1 /* 2 2 * MV-643XX ethernet platform device data definition file. 3 3 */ 4 + 4 5 #ifndef __LINUX_MV643XX_ETH_H 5 6 #define __LINUX_MV643XX_ETH_H 6 7 7 - #define MV643XX_ETH_SHARED_NAME "mv643xx_eth_shared" 8 - #define MV643XX_ETH_NAME "mv643xx_eth" 8 + #include <linux/mbus.h> 9 + 10 + #define MV643XX_ETH_SHARED_NAME "mv643xx_eth" 11 + #define MV643XX_ETH_NAME "mv643xx_eth_port" 9 12 #define MV643XX_ETH_SHARED_REGS 0x2000 10 13 #define MV643XX_ETH_SHARED_REGS_SIZE 0x2000 11 14 #define MV643XX_ETH_BAR_4 0x2220 12 15 #define MV643XX_ETH_SIZE_REG_4 0x2224 13 16 #define MV643XX_ETH_BASE_ADDR_ENABLE_REG 0x2290 14 17 18 + struct mv643xx_eth_shared_platform_data { 19 + struct mbus_dram_target_info *dram; 20 + unsigned int t_clk; 21 + }; 22 + 15 23 struct mv643xx_eth_platform_data { 24 + struct platform_device *shared; 16 25 int port_number; 26 + 27 + struct platform_device *shared_smi; 28 + 17 29 u16 force_phy_addr; /* force override if phy_addr == 0 */ 18 30 u16 phy_addr; 19 31