Skip to content

Commit

Permalink
[NET] smc91x: prepare for SMC_IO_SHIFT to be a platform configurable …
Browse files Browse the repository at this point in the history
…variable

Now one can use the following code

  #define SMC_IO_SHIFT	lp->io_shift

to make SMC_IO_SHIFT a variable. This, however, will slightly increase
the CPU overhead and have negative impact on the network performance.
The tradeoff is, this can be specified in the smc91x platform data so
that multiple boards support can be built in a single zImage.

Signed-off-by: Eric Miao <eric.miao@marvell.com>
Acked-by: Nicolas Pitre <nico@cam.org>
Acked-by: Jeff Garzik <jgarzik@pobox.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
  • Loading branch information
Eric Miao authored and Russell King committed Jul 12, 2008
1 parent c4f0e76 commit 1591988
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 26 deletions.
57 changes: 31 additions & 26 deletions drivers/net/smc91x.c
Original file line number Diff line number Diff line change
Expand Up @@ -2050,9 +2050,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;
Expand All @@ -2063,9 +2065,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);
Expand Down Expand Up @@ -2126,25 +2130,11 @@ static int smc_drv_probe(struct platform_device *pdev)
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);

Expand All @@ -2154,9 +2144,10 @@ static int smc_drv_probe(struct platform_device *pdev)

lp = netdev_priv(ndev);

if (pd)
if (pd) {
memcpy(&lp->cfg, pd, sizeof(lp->cfg));
else {
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;
Expand All @@ -2165,20 +2156,34 @@ static int smc_drv_probe(struct platform_device *pdev)

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 (ires->flags & IRQF_TRIGGER_MASK)
irq_flags = ires->flags & IRQF_TRIGGER_MASK;

ret = smc_request_attrib(pdev);
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
Expand Down Expand Up @@ -2213,11 +2218,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);

Expand All @@ -2243,7 +2248,7 @@ static int smc_drv_remove(struct platform_device *pdev)
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)
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/smc91x.h
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,9 @@ 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;
};

Expand Down
7 changes: 7 additions & 0 deletions include/linux/smc91x.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@

#define SMC91X_NOWAIT (1 << 3)

/* two bits for IO_SHIFT, let's hope later designs will keep this sane */
#define SMC91X_IO_SHIFT_0 (0 << 4)
#define SMC91X_IO_SHIFT_1 (1 << 4)
#define SMC91X_IO_SHIFT_2 (2 << 4)
#define SMC91X_IO_SHIFT_3 (3 << 4)
#define SMC91X_IO_SHIFT(x) (((x) >> 4) & 0x3)

struct smc91x_platdata {
unsigned long flags;
};
Expand Down

0 comments on commit 1591988

Please sign in to comment.