On Tue, 25 Jan 2005, Ian Campbell wrote:
> Sounds good. Are you happy for me to send the version below to Andrew
> and Jeff for inclusion? compiled on lubbock and neponset, compiled and
> tested on my platform.
>
> Cheers,
> Ian.
>
> Signed-off-by: Ian Campbell <[EMAIL PROTECTED]>
Signed-off-by: Nicolas Pitre <[EMAIL PROTECTED]>
>
> Index: 2.6/drivers/net/smc91x.c
> ===================================================================
> --- 2.6.orig/drivers/net/smc91x.c 2005-01-25 08:48:28.000000000 +0000
> +++ 2.6/drivers/net/smc91x.c 2005-01-25 15:56:00.405373349 +0000
> @@ -210,6 +210,10 @@
>
> spinlock_t lock;
>
> +#ifdef SMC_CAN_USE_DATACS
> + u32 *datacs;
> +#endif
> +
> #ifdef SMC_USE_PXA_DMA
> /* DMA needs the physical address of the chip */
> u_long physaddr;
> @@ -1998,16 +2002,21 @@
> return retval;
> }
>
> -static int smc_enable_device(unsigned long attrib_phys)
> +static int smc_enable_device(struct platform_device *pdev)
> {
> unsigned long flags;
> unsigned char ecor, ecsr;
> void *addr;
> + struct resource * res;
> +
> + res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> "smc91x-attrib");
> + if (!res)
> + return 0;
>
> /*
> * Map the attribute space. This is overkill, but clean.
> */
> - addr = ioremap(attrib_phys, ATTRIB_SIZE);
> + addr = ioremap(res->start, ATTRIB_SIZE);
> if (!addr)
> return -ENOMEM;
>
> @@ -2055,6 +2064,62 @@
> return 0;
> }
>
> +static int smc_request_attrib(struct platform_device *pdev)
> +{
> + struct resource * res = platform_get_resource_byname(pdev,
> IORESOURCE_MEM, "smc91x-attrib");
> +
> + if (!res)
> + return 0;
> +
> + if (!request_mem_region(res->start, ATTRIB_SIZE, CARDNAME))
> + return -EBUSY;
> +
> + return 0;
> +}
> +
> +static void smc_release_attrib(struct platform_device *pdev)
> +{
> + struct resource * res = platform_get_resource_byname(pdev,
> IORESOURCE_MEM, "smc91x-attrib");
> +
> + if (res)
> + release_mem_region(res->start, ATTRIB_SIZE);
> +}
> +
> +#ifdef SMC_CAN_USE_DATACS
> +static void smc_request_datacs(struct platform_device *pdev, struct
> net_device *ndev)
> +{
> + struct resource * res = platform_get_resource_byname(pdev,
> IORESOURCE_MEM, "smc91x-data32");
> + struct smc_local *lp = netdev_priv(ndev);
> +
> + if (!res)
> + return;
> +
> + if(!request_mem_region(res->start, SMC_DATA_EXTENT, CARDNAME)) {
> + printk(KERN_INFO "%s: failed to request datacs memory
> region.\n", CARDNAME);
> + return;
> + }
> +
> + lp->datacs = ioremap(res->start, SMC_DATA_EXTENT);
> +}
> +
> +static void smc_release_datacs(struct platform_device *pdev, struct
> net_device *ndev)
> +{
> + struct smc_local *lp = netdev_priv(ndev);
> + struct resource * res = platform_get_resource_byname(pdev,
> IORESOURCE_MEM, "smc91x-data32");
> +
> + if (lp->datacs)
> + iounmap(lp->datacs);
> +
> + lp->datacs = NULL;
> +
> + if (res)
> + release_mem_region(res->start, SMC_DATA_EXTENT);
> +}
> +#else
> +static void smc_request_datacs(struct platform_device *pdev, struct
> net_device *ndev) {}
> +static void smc_release_datacs(struct platform_device *pdev, struct
> net_device *ndev) {}
> +#endif
> +
> /*
> * smc_init(void)
> * Input parameters:
> @@ -2070,20 +2135,20 @@
> {
> struct platform_device *pdev = to_platform_device(dev);
> struct net_device *ndev;
> - struct resource *res, *ext = NULL;
> + struct resource *res;
> unsigned int *addr;
> int ret;
>
> - res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + 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;
> }
>
> - /*
> - * Request the regions.
> - */
> - if (!request_mem_region(res->start, SMC_IO_EXTENT, "smc91x")) {
> +
> + if (!request_mem_region(res->start, SMC_IO_EXTENT, CARDNAME)) {
> ret = -EBUSY;
> goto out;
> }
> @@ -2092,7 +2157,7 @@
> if (!ndev) {
> printk("%s: could not allocate device.\n", CARDNAME);
> ret = -ENOMEM;
> - goto release_1;
> + goto out_release_io;
> }
> SET_MODULE_OWNER(ndev);
> SET_NETDEV_DEV(ndev, dev);
> @@ -2100,42 +2165,26 @@
> ndev->dma = (unsigned char)-1;
> ndev->irq = platform_get_irq(pdev, 0);
>
> - ext = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> - if (ext) {
> - if (!request_mem_region(ext->start, ATTRIB_SIZE, ndev->name)) {
> - ret = -EBUSY;
> - goto release_1;
> - }
> -
> + ret = smc_request_attrib(pdev);
> + if (ret)
> + goto out_free_netdev;
> #if defined(CONFIG_SA1100_ASSABET)
> - NCR_0 |= NCR_ENET_OSC_EN;
> + NCR_0 |= NCR_ENET_OSC_EN;
> #endif
> -
> - ret = smc_enable_device(ext->start);
> - if (ret)
> - goto release_both;
> - }
> + ret = smc_enable_device(pdev);
> + if (ret)
> + goto out_release_attrib;
>
> addr = ioremap(res->start, SMC_IO_EXTENT);
> if (!addr) {
> ret = -ENOMEM;
> - goto release_both;
> + goto out_release_attrib;
> }
>
> dev_set_drvdata(dev, ndev);
> ret = smc_probe(ndev, (unsigned long)addr);
> - if (ret != 0) {
> - dev_set_drvdata(dev, NULL);
> - iounmap(addr);
> - release_both:
> - if (ext)
> - release_mem_region(ext->start, ATTRIB_SIZE);
> - free_netdev(ndev);
> - release_1:
> - release_mem_region(res->start, SMC_IO_EXTENT);
> - out:
> - printk("%s: not found (%d).\n", CARDNAME, ret);
> - }
> + if (ret != 0)
> + goto out_iounmap;
> #ifdef SMC_USE_PXA_DMA
> else {
> struct smc_local *lp = netdev_priv(ndev);
> @@ -2143,6 +2192,22 @@
> }
> #endif
>
> + smc_request_datacs(pdev, ndev);
> +
> + return 0;
> +
> + out_iounmap:
> + dev_set_drvdata(dev, NULL);
> + iounmap(addr);
> + out_release_attrib:
> + smc_release_attrib(pdev);
> + out_free_netdev:
> + free_netdev(ndev);
> + out_release_io:
> + release_mem_region(res->start, SMC_IO_EXTENT);
> + out:
> + printk("%s: not found (%d).\n", CARDNAME, ret);
> +
> return ret;
> }
>
> @@ -2163,10 +2228,13 @@
> pxa_free_dma(ndev->dma);
> #endif
> iounmap((void *)ndev->base_addr);
> - res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> - if (res)
> - release_mem_region(res->start, ATTRIB_SIZE);
> - res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +
> + smc_release_datacs(pdev,ndev);
> + smc_release_attrib(pdev);
> +
> + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs");
> + if (!res)
> + platform_get_resource(pdev, IORESOURCE_MEM, 0);
> release_mem_region(res->start, SMC_IO_EXTENT);
>
> free_netdev(ndev);
> @@ -2195,9 +2263,7 @@
>
> if (ndev && level == RESUME_ENABLE) {
> struct smc_local *lp = netdev_priv(ndev);
> -
> - if (pdev->num_resources == 3)
> - smc_enable_device(pdev->resource[2].start);
> + smc_enable_device(pdev);
> if (netif_running(ndev)) {
> smc_reset(ndev);
> smc_enable(ndev);
> Index: 2.6/drivers/net/smc91x.h
> ===================================================================
> --- 2.6.orig/drivers/net/smc91x.h 2005-01-04 14:11:08.000000000 +0000
> +++ 2.6/drivers/net/smc91x.h 2005-01-25 14:47:42.000000000 +0000
> @@ -362,7 +362,7 @@
> #define SMC_IO_SHIFT 0
> #endif
> #define SMC_IO_EXTENT (16 << SMC_IO_SHIFT)
> -
> +#define SMC_DATA_EXTENT (4)
>
> /*
> . Bank Select Register:
> @@ -883,7 +883,7 @@
> #endif
>
> #if SMC_CAN_USE_32BIT
> -#define SMC_PUSH_DATA(p, l) \
> +#define _SMC_PUSH_DATA(p, l) \
> do { \
> char *__ptr = (p); \
> int __len = (l); \
> @@ -898,7 +898,7 @@
> SMC_outw( *((u16 *)__ptr), ioaddr, DATA_REG ); \
> } \
> } while (0)
> -#define SMC_PULL_DATA(p, l) \
> +#define _SMC_PULL_DATA(p, l) \
> do { \
> char *__ptr = (p); \
> int __len = (l); \
> @@ -918,11 +918,11 @@
> SMC_insl( ioaddr, DATA_REG, __ptr, __len >> 2); \
> } while (0)
> #elif SMC_CAN_USE_16BIT
> -#define SMC_PUSH_DATA(p, l) SMC_outsw( ioaddr, DATA_REG, p, (l) >> 1 )
> -#define SMC_PULL_DATA(p, l) SMC_insw ( ioaddr, DATA_REG, p, (l) >> 1 )
> +#define _SMC_PUSH_DATA(p, l) SMC_outsw( ioaddr, DATA_REG, p, (l) >> 1 )
> +#define _SMC_PULL_DATA(p, l) SMC_insw ( ioaddr, DATA_REG, p, (l) >> 1 )
> #elif SMC_CAN_USE_8BIT
> -#define SMC_PUSH_DATA(p, l) SMC_outsb( ioaddr, DATA_REG, p, l )
> -#define SMC_PULL_DATA(p, l) SMC_insb ( ioaddr, DATA_REG, p, l )
> +#define _SMC_PUSH_DATA(p, l) SMC_outsb( ioaddr, DATA_REG, p, l )
> +#define _SMC_PULL_DATA(p, l) SMC_insb ( ioaddr, DATA_REG, p, l )
> #endif
>
> #if ! SMC_CAN_USE_16BIT
> @@ -941,6 +941,51 @@
> })
> #endif
>
> +#if SMC_CAN_USE_DATACS
> +#define SMC_PUSH_DATA(p, l) \
> + if ( lp->datacs ) { \
> + unsigned char *__ptr = (p); \
> + int __len = (l); \
> + if (__len >= 2 && (unsigned long)__ptr & 2) { \
> + __len -= 2; \
> + SMC_outw( *((u16 *)__ptr), ioaddr, DATA_REG ); \
> + __ptr += 2; \
> + } \
> + outsl(lp->datacs, __ptr, __len >> 2); \
> + if (__len & 2) { \
> + __ptr += (__len & ~3); \
> + SMC_outw( *((u16 *)__ptr), ioaddr, DATA_REG ); \
> + } \
> + } else { \
> + _SMC_PUSH_DATA(p, l); \
> + }
> +
> +#define SMC_PULL_DATA(p, l) \
> + if ( lp->datacs ) { \
> + unsigned char *__ptr = (p); \
> + int __len = (l); \
> + if ((unsigned long)__ptr & 2) { \
> + /* \
> + * We want 32bit alignment here. \
> + * Since some buses perform a full 32bit \
> + * fetch even for 16bit data we can't use \
> + * SMC_inw() here. Back both source (on chip \
> + * and destination) pointers of 2 bytes. \
> + */ \
> + __ptr -= 2; \
> + __len += 2; \
> + SMC_SET_PTR( 2|PTR_READ|PTR_RCV|PTR_AUTOINC ); \
> + } \
> + __len += 2; \
> + insl( lp->datacs, __ptr, __len >> 2); \
> + } else { \
> + _SMC_PULL_DATA(p, l); \
> + }
> +#else
> +#define SMC_PUSH_DATA(p, l) _SMC_PUSH_DATA(p, l)
> +#define SMC_PULL_DATA(p, l) _SMC_PULL_DATA(p, l)
> +#endif
> +
> #if !defined (SMC_INTERRUPT_PREAMBLE)
> # define SMC_INTERRUPT_PREAMBLE
> #endif
> Index: 2.6/arch/arm/mach-sa1100/neponset.c
> ===================================================================
> --- 2.6.orig/arch/arm/mach-sa1100/neponset.c 2005-01-04 14:10:53.000000000
> +0000
> +++ 2.6/arch/arm/mach-sa1100/neponset.c 2005-01-25 15:56:00.130447587
> +0000
> @@ -266,6 +266,7 @@
>
> static struct resource smc91x_resources[] = {
> [0] = {
> + .name = "smc91x-regs",
> .start = SA1100_CS3_PHYS,
> .end = SA1100_CS3_PHYS + 0x01ffffff,
> .flags = IORESOURCE_MEM,
> @@ -276,6 +277,7 @@
> .flags = IORESOURCE_IRQ,
> },
> [2] = {
> + .name = "smc91x-attrib",
> .start = SA1100_CS3_PHYS + 0x02000000,
> .end = SA1100_CS3_PHYS + 0x03ffffff,
> .flags = IORESOURCE_MEM,
> Index: 2.6/arch/arm/mach-pxa/lubbock.c
> ===================================================================
> --- 2.6.orig/arch/arm/mach-pxa/lubbock.c 2005-01-04 14:10:53.000000000
> +0000
> +++ 2.6/arch/arm/mach-pxa/lubbock.c 2005-01-25 15:56:00.048469724 +0000
> @@ -137,6 +137,7 @@
>
> static struct resource smc91x_resources[] = {
> [0] = {
> + .name = "smc91x-regs",
> .start = 0x0c000000,
> .end = 0x0c0fffff,
> .flags = IORESOURCE_MEM,
> @@ -147,6 +148,7 @@
> .flags = IORESOURCE_IRQ,
> },
> [2] = {
> + .name = "smc91x-attrib",
> .start = 0x0e000000,
> .end = 0x0e0fffff,
> .flags = IORESOURCE_MEM,
>
>
>
> --
> Ian Campbell, Senior Design Engineer
> Web: http://www.arcom.com
> Arcom, Clifton Road, Direct: +44 (0)1223 403 465
> Cambridge CB1 7EA, United Kingdom Phone: +44 (0)1223 411 200
>
>
> _____________________________________________________________________
> The message in this transmission is sent in confidence for the attention of
> the addressee only and should not be disclosed to any other party.
> Unauthorised recipients are requested to preserve this confidentiality.
> Please advise the sender if the addressee is not resident at the receiving
> end. Email to and from Arcom is automatically monitored for operational and
> lawful business reasons.
>
> This message has been virus scanned by MessageLabs.
>
Nicolas
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/