diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/smc91x.c | 94 | ||||
-rw-r--r-- | drivers/net/smc91x.h | 76 |
2 files changed, 88 insertions, 82 deletions
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index f2051b209da..2040965d772 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c @@ -308,7 +308,7 @@ static void smc_reset(struct net_device *dev) * can't handle it then there will be no recovery except for * a hard reset or power cycle */ - if (nowait) + if (lp->cfg.flags & SMC91X_NOWAIT) cfg |= CONFIG_NO_WAIT; /* @@ -1939,8 +1939,11 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr, if (retval) goto err_out; -#ifdef SMC_USE_PXA_DMA - { +#ifdef CONFIG_ARCH_PXA +# ifdef SMC_USE_PXA_DMA + lp->cfg.flags |= SMC91X_USE_DMA; +# endif + if (lp->cfg.flags & SMC91X_USE_DMA) { int dma = pxa_request_dma(dev->name, DMA_PRIO_LOW, smc_pxa_dma_irq, NULL); if (dma >= 0) @@ -1980,7 +1983,7 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr, } err_out: -#ifdef SMC_USE_PXA_DMA +#ifdef CONFIG_ARCH_PXA if (retval && dev->dma != (unsigned char)-1) pxa_free_dma(dev->dma); #endif @@ -2050,9 +2053,11 @@ static int smc_enable_device(struct platform_device *pdev) return 0; } -static int smc_request_attrib(struct platform_device *pdev) +static int smc_request_attrib(struct platform_device *pdev, + struct net_device *ndev) { struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib"); + struct smc_local *lp = netdev_priv(ndev); if (!res) return 0; @@ -2063,9 +2068,11 @@ static int smc_request_attrib(struct platform_device *pdev) return 0; } -static void smc_release_attrib(struct platform_device *pdev) +static void smc_release_attrib(struct platform_device *pdev, + struct net_device *ndev) { struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib"); + struct smc_local *lp = netdev_priv(ndev); if (res) release_mem_region(res->start, ATTRIB_SIZE); @@ -2123,27 +2130,14 @@ static int smc_drv_probe(struct platform_device *pdev) struct net_device *ndev; struct resource *res, *ires; unsigned int __iomem *addr; + unsigned long irq_flags = SMC_IRQ_FLAGS; int ret; - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs"); - if (!res) - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - ret = -ENODEV; - goto out; - } - - - if (!request_mem_region(res->start, SMC_IO_EXTENT, CARDNAME)) { - ret = -EBUSY; - goto out; - } - ndev = alloc_etherdev(sizeof(struct smc_local)); if (!ndev) { printk("%s: could not allocate device.\n", CARDNAME); ret = -ENOMEM; - goto out_release_io; + goto out; } SET_NETDEV_DEV(ndev, &pdev->dev); @@ -2152,37 +2146,47 @@ static int smc_drv_probe(struct platform_device *pdev) */ lp = netdev_priv(ndev); - lp->cfg.irq_flags = SMC_IRQ_FLAGS; -#ifdef SMC_DYNAMIC_BUS_CONFIG - if (pd) + if (pd) { memcpy(&lp->cfg, pd, sizeof(lp->cfg)); - else { - lp->cfg.flags = SMC91X_USE_8BIT; - lp->cfg.flags |= SMC91X_USE_16BIT; - lp->cfg.flags |= SMC91X_USE_32BIT; + lp->io_shift = SMC91X_IO_SHIFT(lp->cfg.flags); + } else { + lp->cfg.flags |= (SMC_CAN_USE_8BIT) ? SMC91X_USE_8BIT : 0; + lp->cfg.flags |= (SMC_CAN_USE_16BIT) ? SMC91X_USE_16BIT : 0; + lp->cfg.flags |= (SMC_CAN_USE_32BIT) ? SMC91X_USE_32BIT : 0; + lp->cfg.flags |= (nowait) ? SMC91X_NOWAIT : 0; } - lp->cfg.flags &= ~(SMC_CAN_USE_8BIT ? 0 : SMC91X_USE_8BIT); - lp->cfg.flags &= ~(SMC_CAN_USE_16BIT ? 0 : SMC91X_USE_16BIT); - lp->cfg.flags &= ~(SMC_CAN_USE_32BIT ? 0 : SMC91X_USE_32BIT); -#endif - ndev->dma = (unsigned char)-1; + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs"); + if (!res) + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + ret = -ENODEV; + goto out_free_netdev; + } + + + if (!request_mem_region(res->start, SMC_IO_EXTENT, CARDNAME)) { + ret = -EBUSY; + goto out_free_netdev; + } + ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!ires) { ret = -ENODEV; - goto out_free_netdev; + goto out_release_io; } ndev->irq = ires->start; - if (SMC_IRQ_FLAGS == -1) - lp->cfg.irq_flags = ires->flags & IRQF_TRIGGER_MASK; - ret = smc_request_attrib(pdev); + if (ires->flags & IRQF_TRIGGER_MASK) + irq_flags = ires->flags & IRQF_TRIGGER_MASK; + + ret = smc_request_attrib(pdev, ndev); if (ret) - goto out_free_netdev; + goto out_release_io; #if defined(CONFIG_SA1100_ASSABET) NCR_0 |= NCR_ENET_OSC_EN; #endif @@ -2197,7 +2201,7 @@ static int smc_drv_probe(struct platform_device *pdev) goto out_release_attrib; } -#ifdef SMC_USE_PXA_DMA +#ifdef CONFIG_ARCH_PXA { struct smc_local *lp = netdev_priv(ndev); lp->device = &pdev->dev; @@ -2205,7 +2209,7 @@ static int smc_drv_probe(struct platform_device *pdev) } #endif - ret = smc_probe(ndev, addr, lp->cfg.irq_flags); + ret = smc_probe(ndev, addr, irq_flags); if (ret != 0) goto out_iounmap; @@ -2217,11 +2221,11 @@ static int smc_drv_probe(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); iounmap(addr); out_release_attrib: - smc_release_attrib(pdev); - out_free_netdev: - free_netdev(ndev); + smc_release_attrib(pdev, ndev); out_release_io: release_mem_region(res->start, SMC_IO_EXTENT); + out_free_netdev: + free_netdev(ndev); out: printk("%s: not found (%d).\n", CARDNAME, ret); @@ -2240,14 +2244,14 @@ static int smc_drv_remove(struct platform_device *pdev) free_irq(ndev->irq, ndev); -#ifdef SMC_USE_PXA_DMA +#ifdef CONFIG_ARCH_PXA if (ndev->dma != (unsigned char)-1) pxa_free_dma(ndev->dma); #endif iounmap(lp->base); smc_release_datacs(pdev,ndev); - smc_release_attrib(pdev); + smc_release_attrib(pdev,ndev); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs"); if (!res) diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index 8606818653f..22209b6f140 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h @@ -40,23 +40,46 @@ * Define your architecture specific bus configuration parameters here. */ -#if defined(CONFIG_ARCH_LUBBOCK) +#if defined(CONFIG_ARCH_LUBBOCK) ||\ + defined(CONFIG_MACH_MAINSTONE) ||\ + defined(CONFIG_MACH_ZYLONITE) ||\ + defined(CONFIG_MACH_LITTLETON) -/* We can only do 16-bit reads and writes in the static memory space. */ -#define SMC_CAN_USE_8BIT 0 +#include <asm/mach-types.h> + +/* Now the bus width is specified in the platform data + * pretend here to support all I/O access types + */ +#define SMC_CAN_USE_8BIT 1 #define SMC_CAN_USE_16BIT 1 -#define SMC_CAN_USE_32BIT 0 +#define SMC_CAN_USE_32BIT 1 #define SMC_NOWAIT 1 -/* The first two address lines aren't connected... */ -#define SMC_IO_SHIFT 2 +#define SMC_IO_SHIFT (lp->io_shift) +#define SMC_inb(a, r) readb((a) + (r)) #define SMC_inw(a, r) readw((a) + (r)) -#define SMC_outw(v, a, r) writew(v, (a) + (r)) +#define SMC_inl(a, r) readl((a) + (r)) +#define SMC_outb(v, a, r) writeb(v, (a) + (r)) +#define SMC_outl(v, a, r) writel(v, (a) + (r)) #define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) #define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) +#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) +#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) #define SMC_IRQ_FLAGS (-1) /* from resource */ +/* We actually can't write halfwords properly if not word aligned */ +static inline void SMC_outw(u16 val, void __iomem *ioaddr, int reg) +{ + if (machine_is_mainstone() && reg & 2) { + unsigned int v = val << 16; + v |= readl(ioaddr + (reg & ~2)) & 0xffff; + writel(v, ioaddr + (reg & ~2)); + } else { + writew(val, ioaddr + reg); + } +} + #elif defined(CONFIG_BLACKFIN) #define SMC_IRQ_FLAGS IRQF_TRIGGER_HIGH @@ -195,7 +218,6 @@ #define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) #elif defined(CONFIG_ARCH_INNOKOM) || \ - defined(CONFIG_MACH_MAINSTONE) || \ defined(CONFIG_ARCH_PXA_IDP) || \ defined(CONFIG_ARCH_RAMSES) || \ defined(CONFIG_ARCH_PCM027) @@ -229,22 +251,6 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg) } } -#elif defined(CONFIG_MACH_ZYLONITE) - -#define SMC_CAN_USE_8BIT 1 -#define SMC_CAN_USE_16BIT 1 -#define SMC_CAN_USE_32BIT 0 -#define SMC_IO_SHIFT 0 -#define SMC_NOWAIT 1 -#define SMC_USE_PXA_DMA 1 -#define SMC_inb(a, r) readb((a) + (r)) -#define SMC_inw(a, r) readw((a) + (r)) -#define SMC_insw(a, r, p, l) insw((a) + (r), p, l) -#define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l) -#define SMC_outb(v, a, r) writeb(v, (a) + (r)) -#define SMC_outw(v, a, r) writew(v, (a) + (r)) -#define SMC_IRQ_FLAGS (-1) /* from resource */ - #elif defined(CONFIG_ARCH_OMAP) /* We can only do 16-bit reads and writes in the static memory space. */ @@ -454,7 +460,6 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r, #define RPC_LSA_DEFAULT RPC_LED_100_10 #define RPC_LSB_DEFAULT RPC_LED_TX_RX -#define SMC_DYNAMIC_BUS_CONFIG #endif @@ -493,7 +498,7 @@ struct smc_local { spinlock_t lock; -#ifdef SMC_USE_PXA_DMA +#ifdef CONFIG_ARCH_PXA /* DMA needs the physical address of the chip */ u_long physaddr; struct device *device; @@ -501,20 +506,17 @@ struct smc_local { void __iomem *base; void __iomem *datacs; + /* the low address lines on some platforms aren't connected... */ + int io_shift; + struct smc91x_platdata cfg; }; -#ifdef SMC_DYNAMIC_BUS_CONFIG -#define SMC_8BIT(p) (((p)->cfg.flags & SMC91X_USE_8BIT) && SMC_CAN_USE_8BIT) -#define SMC_16BIT(p) (((p)->cfg.flags & SMC91X_USE_16BIT) && SMC_CAN_USE_16BIT) -#define SMC_32BIT(p) (((p)->cfg.flags & SMC91X_USE_32BIT) && SMC_CAN_USE_32BIT) -#else -#define SMC_8BIT(p) SMC_CAN_USE_8BIT -#define SMC_16BIT(p) SMC_CAN_USE_16BIT -#define SMC_32BIT(p) SMC_CAN_USE_32BIT -#endif +#define SMC_8BIT(p) ((p)->cfg.flags & SMC91X_USE_8BIT) +#define SMC_16BIT(p) ((p)->cfg.flags & SMC91X_USE_16BIT) +#define SMC_32BIT(p) ((p)->cfg.flags & SMC91X_USE_32BIT) -#ifdef SMC_USE_PXA_DMA +#ifdef CONFIG_ARCH_PXA /* * Let's use the DMA engine on the XScale PXA2xx for RX packets. This is * always happening in irq context so no need to worry about races. TX is @@ -608,7 +610,7 @@ smc_pxa_dma_irq(int dma, void *dummy) { DCSR(dma) = 0; } -#endif /* SMC_USE_PXA_DMA */ +#endif /* CONFIG_ARCH_PXA */ /* |