mirror of
https://github.com/torvalds/linux.git
synced 2024-12-16 08:02:17 +00:00
Merge branch 'features/cs89x0' of git://git.pengutronix.de/git/imx/linux-2.6 into next/drivers
* 'features/cs89x0' of git://git.pengutronix.de/git/imx/linux-2.6: CS89x0 : add CS89x0 platform device to the iMX31ADS board CS89x0 : remove QQ2440 board support from the CS89x0 driver CS89x0 : add CS89x0 platform device to the iMX21ADS board CS89x0 : add platform driver support
This commit is contained in:
commit
afde962608
@ -78,6 +78,8 @@ CONFIG_MISC_DEVICES=y
|
||||
CONFIG_EEPROM_AT24=y
|
||||
CONFIG_EEPROM_AT25=y
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_CS89x0=y
|
||||
CONFIG_CS89x0_PLATFORM=y
|
||||
CONFIG_DM9000=y
|
||||
CONFIG_SMC91X=y
|
||||
CONFIG_SMC911X=y
|
||||
|
@ -26,7 +26,6 @@ CONFIG_MACH_ARMADILLO5X0=y
|
||||
CONFIG_MACH_KZM_ARM11_01=y
|
||||
CONFIG_MACH_PCM043=y
|
||||
CONFIG_MACH_MX35_3DS=y
|
||||
CONFIG_MACH_EUKREA_CPUIMX35=y
|
||||
CONFIG_MACH_VPR200=y
|
||||
CONFIG_MACH_IMX51_DT=y
|
||||
CONFIG_MACH_MX51_3DS=y
|
||||
@ -82,8 +81,9 @@ CONFIG_PATA_IMX=y
|
||||
CONFIG_NETDEVICES=y
|
||||
# CONFIG_NET_VENDOR_BROADCOM is not set
|
||||
# CONFIG_NET_VENDOR_CHELSIO is not set
|
||||
CONFIG_CS89x0=y
|
||||
CONFIG_CS89x0_PLATFORM=y
|
||||
# CONFIG_NET_VENDOR_FARADAY is not set
|
||||
CONFIG_FEC=y
|
||||
# CONFIG_NET_VENDOR_INTEL is not set
|
||||
# CONFIG_NET_VENDOR_MARVELL is not set
|
||||
# CONFIG_NET_VENDOR_MICREL is not set
|
||||
|
@ -37,8 +37,8 @@
|
||||
#define MX21ADS_REG_ADDR(offset) (void __force __iomem *) \
|
||||
(MX21ADS_MMIO_BASE_ADDR + (offset))
|
||||
|
||||
#define MX21ADS_CS8900A_MMIO_SIZE 0x200000
|
||||
#define MX21ADS_CS8900A_IRQ IRQ_GPIOE(11)
|
||||
#define MX21ADS_CS8900A_IOBASE_REG MX21ADS_REG_ADDR(0x000000)
|
||||
#define MX21ADS_ST16C255_IOBASE_REG MX21ADS_REG_ADDR(0x200000)
|
||||
#define MX21ADS_VERSION_REG MX21ADS_REG_ADDR(0x400000)
|
||||
#define MX21ADS_IO_REG MX21ADS_REG_ADDR(0x800000)
|
||||
@ -159,6 +159,18 @@ static struct platform_device mx21ads_nor_mtd_device = {
|
||||
.resource = &mx21ads_flash_resource,
|
||||
};
|
||||
|
||||
static const struct resource mx21ads_cs8900_resources[] __initconst = {
|
||||
DEFINE_RES_MEM(MX21_CS1_BASE_ADDR, MX21ADS_CS8900A_MMIO_SIZE),
|
||||
DEFINE_RES_IRQ(MX21ADS_CS8900A_IRQ),
|
||||
};
|
||||
|
||||
static const struct platform_device_info mx21ads_cs8900_devinfo __initconst = {
|
||||
.name = "cs89x0",
|
||||
.id = 0,
|
||||
.res = mx21ads_cs8900_resources,
|
||||
.num_res = ARRAY_SIZE(mx21ads_cs8900_resources),
|
||||
};
|
||||
|
||||
static const struct imxuart_platform_data uart_pdata_rts __initconst = {
|
||||
.flags = IMXUART_HAVE_RTSCTS,
|
||||
};
|
||||
@ -292,6 +304,8 @@ static void __init mx21ads_board_init(void)
|
||||
imx21_add_mxc_nand(&mx21ads_nand_board_info);
|
||||
|
||||
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
|
||||
platform_device_register_full(
|
||||
(struct platform_device_info *)&mx21ads_cs8900_devinfo);
|
||||
}
|
||||
|
||||
static void __init mx21ads_timer_init(void)
|
||||
|
@ -28,7 +28,6 @@
|
||||
#include <asm/memory.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <mach/common.h>
|
||||
#include <mach/board-mx31ads.h>
|
||||
#include <mach/iomux-mx3.h>
|
||||
|
||||
#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
|
||||
@ -39,6 +38,9 @@
|
||||
|
||||
#include "devices-imx31.h"
|
||||
|
||||
/* Base address of PBC controller */
|
||||
#define PBC_BASE_ADDRESS MX31_CS4_BASE_ADDR_VIRT
|
||||
|
||||
/* PBC Board interrupt status register */
|
||||
#define PBC_INTSTATUS 0x000016
|
||||
|
||||
@ -62,6 +64,7 @@
|
||||
#define PBC_INTMASK_CLEAR_REG (PBC_INTMASK_CLEAR + PBC_BASE_ADDRESS)
|
||||
#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX31_PIN_GPIO1_4)
|
||||
|
||||
#define MXC_EXP_IO_BASE MXC_BOARD_IRQ_START
|
||||
#define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_EXP_IO_BASE)
|
||||
|
||||
#define EXPIO_INT_XUART_INTA (MXC_EXP_IO_BASE + 10)
|
||||
@ -69,6 +72,10 @@
|
||||
|
||||
#define MXC_MAX_EXP_IO_LINES 16
|
||||
|
||||
/* CS8900 */
|
||||
#define EXPIO_INT_ENET_INT (MXC_EXP_IO_BASE + 8)
|
||||
#define CS4_CS8900_MMIO_START 0x20000
|
||||
|
||||
/*
|
||||
* The serial port definition structure.
|
||||
*/
|
||||
@ -101,11 +108,29 @@ static struct platform_device serial_device = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct resource mx31ads_cs8900_resources[] __initconst = {
|
||||
DEFINE_RES_MEM(MX31_CS4_BASE_ADDR + CS4_CS8900_MMIO_START, SZ_64K),
|
||||
DEFINE_RES_IRQ(EXPIO_INT_ENET_INT),
|
||||
};
|
||||
|
||||
static const struct platform_device_info mx31ads_cs8900_devinfo __initconst = {
|
||||
.name = "cs89x0",
|
||||
.id = 0,
|
||||
.res = mx31ads_cs8900_resources,
|
||||
.num_res = ARRAY_SIZE(mx31ads_cs8900_resources),
|
||||
};
|
||||
|
||||
static int __init mxc_init_extuart(void)
|
||||
{
|
||||
return platform_device_register(&serial_device);
|
||||
}
|
||||
|
||||
static void __init mxc_init_ext_ethernet(void)
|
||||
{
|
||||
platform_device_register_full(
|
||||
(struct platform_device_info *)&mx31ads_cs8900_devinfo);
|
||||
}
|
||||
|
||||
static const struct imxuart_platform_data uart_pdata __initconst = {
|
||||
.flags = IMXUART_HAVE_RTSCTS,
|
||||
};
|
||||
@ -492,12 +517,15 @@ static void __init mxc_init_audio(void)
|
||||
mxc_iomux_setup_multiple_pins(ssi_pins, ARRAY_SIZE(ssi_pins), "ssi");
|
||||
}
|
||||
|
||||
/* static mappings */
|
||||
/*
|
||||
* Static mappings, starting from the CS4 start address up to the start address
|
||||
* of the CS8900.
|
||||
*/
|
||||
static struct map_desc mx31ads_io_desc[] __initdata = {
|
||||
{
|
||||
.virtual = MX31_CS4_BASE_ADDR_VIRT,
|
||||
.pfn = __phys_to_pfn(MX31_CS4_BASE_ADDR),
|
||||
.length = MX31_CS4_SIZE / 2,
|
||||
.length = CS4_CS8900_MMIO_START,
|
||||
.type = MT_DEVICE
|
||||
},
|
||||
};
|
||||
@ -522,6 +550,7 @@ static void __init mx31ads_init(void)
|
||||
mxc_init_imx_uart();
|
||||
mxc_init_i2c();
|
||||
mxc_init_audio();
|
||||
mxc_init_ext_ethernet();
|
||||
}
|
||||
|
||||
static void __init mx31ads_timer_init(void)
|
||||
|
@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __ASM_ARCH_MXC_BOARD_MX31ADS_H__
|
||||
#define __ASM_ARCH_MXC_BOARD_MX31ADS_H__
|
||||
|
||||
#include <mach/hardware.h>
|
||||
|
||||
/*
|
||||
* These symbols are used by drivers/net/cs89x0.c.
|
||||
* This is ugly as hell, but we have to provide them until
|
||||
* someone fixed the driver.
|
||||
*/
|
||||
|
||||
/* Base address of PBC controller */
|
||||
#define PBC_BASE_ADDRESS MX31_CS4_BASE_ADDR_VIRT
|
||||
/* Offsets for the PBC Controller register */
|
||||
|
||||
/* Ethernet Controller IO base address */
|
||||
#define PBC_CS8900A_IOBASE 0x020000
|
||||
|
||||
#define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START)
|
||||
|
||||
#define EXPIO_INT_ENET_INT (MXC_EXP_IO_BASE + 8)
|
||||
|
||||
#endif /* __ASM_ARCH_MXC_BOARD_MX31ADS_H__ */
|
@ -190,8 +190,10 @@ static struct devprobe2 isa_probes[] __initdata = {
|
||||
{seeq8005_probe, 0},
|
||||
#endif
|
||||
#ifdef CONFIG_CS89x0
|
||||
#ifndef CONFIG_CS89x0_PLATFORM
|
||||
{cs89x0_probe, 0},
|
||||
#endif
|
||||
#endif
|
||||
#ifdef CONFIG_AT1700
|
||||
{at1700_probe, 0},
|
||||
#endif
|
||||
|
@ -5,8 +5,7 @@
|
||||
config NET_VENDOR_CIRRUS
|
||||
bool "Cirrus devices"
|
||||
default y
|
||||
depends on ISA || EISA || MACH_IXDP2351 || ARCH_IXDP2X01 \
|
||||
|| MACH_MX31ADS || MACH_QQ2440 || (ARM && ARCH_EP93XX) || MAC
|
||||
depends on ISA || EISA || ARM || MAC
|
||||
---help---
|
||||
If you have a network (Ethernet) card belonging to this class, say Y
|
||||
and read the Ethernet-HOWTO, available from
|
||||
@ -21,8 +20,7 @@ if NET_VENDOR_CIRRUS
|
||||
|
||||
config CS89x0
|
||||
tristate "CS89x0 support"
|
||||
depends on (ISA || EISA || MACH_IXDP2351 \
|
||||
|| ARCH_IXDP2X01 || MACH_MX31ADS || MACH_QQ2440)
|
||||
depends on ISA || EISA || ARM
|
||||
---help---
|
||||
Support for CS89x0 chipset based Ethernet cards. If you have a
|
||||
network (Ethernet) card of this type, say Y and read the
|
||||
@ -33,10 +31,15 @@ config CS89x0
|
||||
To compile this driver as a module, choose M here. The module
|
||||
will be called cs89x0.
|
||||
|
||||
config CS89x0_NONISA_IRQ
|
||||
def_bool y
|
||||
depends on CS89x0 != n
|
||||
depends on MACH_IXDP2351 || ARCH_IXDP2X01 || MACH_MX31ADS || MACH_QQ2440
|
||||
config CS89x0_PLATFORM
|
||||
bool "CS89x0 platform driver support"
|
||||
depends on CS89x0
|
||||
help
|
||||
Say Y to compile the cs89x0 driver as a platform driver. This
|
||||
makes this driver suitable for use on certain evaluation boards
|
||||
such as the iMX21ADS.
|
||||
|
||||
If you are unsure, say N.
|
||||
|
||||
config EP93XX_ETH
|
||||
tristate "EP93xx Ethernet support"
|
||||
|
@ -100,9 +100,6 @@
|
||||
|
||||
*/
|
||||
|
||||
/* Always include 'config.h' first in case the user wants to turn on
|
||||
or override something. */
|
||||
#include <linux/module.h>
|
||||
|
||||
/*
|
||||
* Set this to zero to disable DMA code
|
||||
@ -131,9 +128,12 @@
|
||||
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/printk.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/fcntl.h>
|
||||
@ -151,6 +151,7 @@
|
||||
#include <asm/system.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <linux/atomic.h>
|
||||
#if ALLOW_DMA
|
||||
#include <asm/dma.h>
|
||||
#endif
|
||||
@ -174,26 +175,20 @@ static char version[] __initdata =
|
||||
them to system IRQ numbers. This mapping is card specific and is set to
|
||||
the configuration of the Cirrus Eval board for this chip. */
|
||||
#if defined(CONFIG_MACH_IXDP2351)
|
||||
#define CS89x0_NONISA_IRQ
|
||||
static unsigned int netcard_portlist[] __used __initdata = {IXDP2351_VIRT_CS8900_BASE, 0};
|
||||
static unsigned int cs8900_irq_map[] = {IRQ_IXDP2351_CS8900, 0, 0, 0};
|
||||
#elif defined(CONFIG_ARCH_IXDP2X01)
|
||||
#define CS89x0_NONISA_IRQ
|
||||
static unsigned int netcard_portlist[] __used __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0};
|
||||
static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0};
|
||||
#elif defined(CONFIG_MACH_QQ2440)
|
||||
#include <mach/qq2440.h>
|
||||
static unsigned int netcard_portlist[] __used __initdata = { QQ2440_CS8900_VIRT_BASE + 0x300, 0 };
|
||||
static unsigned int cs8900_irq_map[] = { QQ2440_CS8900_IRQ, 0, 0, 0 };
|
||||
#elif defined(CONFIG_MACH_MX31ADS)
|
||||
#include <mach/board-mx31ads.h>
|
||||
static unsigned int netcard_portlist[] __used __initdata = {
|
||||
PBC_BASE_ADDRESS + PBC_CS8900A_IOBASE + 0x300, 0
|
||||
};
|
||||
static unsigned cs8900_irq_map[] = {EXPIO_INT_ENET_INT, 0, 0, 0};
|
||||
#else
|
||||
#ifndef CONFIG_CS89x0_PLATFORM
|
||||
static unsigned int netcard_portlist[] __used __initdata =
|
||||
{ 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};
|
||||
static unsigned int cs8900_irq_map[] = {10,11,12,5};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if DEBUGGING
|
||||
static unsigned int net_debug = DEBUGGING;
|
||||
@ -236,11 +231,16 @@ struct net_local {
|
||||
unsigned char *end_dma_buff; /* points to the end of the buffer */
|
||||
unsigned char *rx_dma_ptr; /* points to the next packet */
|
||||
#endif
|
||||
#ifdef CONFIG_CS89x0_PLATFORM
|
||||
void __iomem *virt_addr;/* Virtual address for accessing the CS89x0. */
|
||||
unsigned long phys_addr;/* Physical address for accessing the CS89x0. */
|
||||
unsigned long size; /* Length of CS89x0 memory region. */
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Index to functions, as function prototypes. */
|
||||
|
||||
static int cs89x0_probe1(struct net_device *dev, int ioaddr, int modular);
|
||||
static int cs89x0_probe1(struct net_device *dev, unsigned long ioaddr, int modular);
|
||||
static int net_open(struct net_device *dev);
|
||||
static netdev_tx_t net_send_packet(struct sk_buff *skb, struct net_device *dev);
|
||||
static irqreturn_t net_interrupt(int irq, void *dev_id);
|
||||
@ -294,6 +294,7 @@ static int __init media_fn(char *str)
|
||||
__setup("cs89x0_media=", media_fn);
|
||||
|
||||
|
||||
#ifndef CONFIG_CS89x0_PLATFORM
|
||||
/* Check for a network adaptor of this type, and return '0' iff one exists.
|
||||
If dev->base_addr == 0, probe all likely locations.
|
||||
If dev->base_addr == 1, always return failure.
|
||||
@ -343,6 +344,7 @@ out:
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MACH_IXDP2351)
|
||||
static u16
|
||||
@ -504,7 +506,7 @@ static const struct net_device_ops net_ops = {
|
||||
*/
|
||||
|
||||
static int __init
|
||||
cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
|
||||
cs89x0_probe1(struct net_device *dev, unsigned long ioaddr, int modular)
|
||||
{
|
||||
struct net_local *lp = netdev_priv(dev);
|
||||
static unsigned version_printed;
|
||||
@ -529,15 +531,12 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
|
||||
lp->force = g_cs89x0_media__force;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MACH_QQ2440)
|
||||
lp->force |= FORCE_RJ45 | FORCE_FULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Grab the region so we can find another board if autoIRQ fails. */
|
||||
/* WTF is going on here? */
|
||||
if (!request_region(ioaddr & ~3, NETCARD_IO_EXTENT, DRV_NAME)) {
|
||||
printk(KERN_ERR "%s: request_region(0x%x, 0x%x) failed\n",
|
||||
printk(KERN_ERR "%s: request_region(0x%lx, 0x%x) failed\n",
|
||||
DRV_NAME, ioaddr, NETCARD_IO_EXTENT);
|
||||
retval = -EBUSY;
|
||||
goto out1;
|
||||
@ -549,7 +548,7 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
|
||||
will skip the test for the ADD_PORT. */
|
||||
if (ioaddr & 1) {
|
||||
if (net_debug > 1)
|
||||
printk(KERN_INFO "%s: odd ioaddr 0x%x\n", dev->name, ioaddr);
|
||||
printk(KERN_INFO "%s: odd ioaddr 0x%lx\n", dev->name, ioaddr);
|
||||
if ((ioaddr & 2) != 2)
|
||||
if ((readword(ioaddr & ~3, ADD_PORT) & ADD_MASK) != ADD_SIG) {
|
||||
printk(KERN_ERR "%s: bad signature 0x%x\n",
|
||||
@ -560,13 +559,13 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
|
||||
}
|
||||
|
||||
ioaddr &= ~3;
|
||||
printk(KERN_DEBUG "PP_addr at %x[%x]: 0x%x\n",
|
||||
printk(KERN_DEBUG "PP_addr at %lx[%x]: 0x%x\n",
|
||||
ioaddr, ADD_PORT, readword(ioaddr, ADD_PORT));
|
||||
writeword(ioaddr, ADD_PORT, PP_ChipID);
|
||||
|
||||
tmp = readword(ioaddr, DATA_PORT);
|
||||
if (tmp != CHIP_EISA_ID_SIG) {
|
||||
printk(KERN_DEBUG "%s: incorrect signature at %x[%x]: 0x%x!="
|
||||
printk(KERN_DEBUG "%s: incorrect signature at %lx[%x]: 0x%x!="
|
||||
CHIP_EISA_ID_SIG_STR "\n",
|
||||
dev->name, ioaddr, DATA_PORT, tmp);
|
||||
retval = -ENODEV;
|
||||
@ -736,8 +735,9 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
|
||||
dev->irq = i;
|
||||
} else {
|
||||
i = lp->isa_config & INT_NO_MASK;
|
||||
#ifndef CONFIG_CS89x0_PLATFORM
|
||||
if (lp->chip_type == CS8900) {
|
||||
#ifdef CONFIG_CS89x0_NONISA_IRQ
|
||||
#ifdef CS89x0_NONISA_IRQ
|
||||
i = cs8900_irq_map[0];
|
||||
#else
|
||||
/* Translate the IRQ using the IRQ mapping table. */
|
||||
@ -758,6 +758,7 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
if (!dev->irq)
|
||||
dev->irq = i;
|
||||
}
|
||||
@ -1168,6 +1169,7 @@ write_irq(struct net_device *dev, int chip_type, int irq)
|
||||
int i;
|
||||
|
||||
if (chip_type == CS8900) {
|
||||
#ifndef CONFIG_CS89x0_PLATFORM
|
||||
/* Search the mapping table for the corresponding IRQ pin. */
|
||||
for (i = 0; i != ARRAY_SIZE(cs8900_irq_map); i++)
|
||||
if (cs8900_irq_map[i] == irq)
|
||||
@ -1175,6 +1177,10 @@ write_irq(struct net_device *dev, int chip_type, int irq)
|
||||
/* Not found */
|
||||
if (i == ARRAY_SIZE(cs8900_irq_map))
|
||||
i = 3;
|
||||
#else
|
||||
/* INTRQ0 pin is used for interrupt generation. */
|
||||
i = 0;
|
||||
#endif
|
||||
writereg(dev, PP_CS8900_ISAINT, i);
|
||||
} else {
|
||||
writereg(dev, PP_CS8920_ISAINT, irq);
|
||||
@ -1228,7 +1234,7 @@ net_open(struct net_device *dev)
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifndef CONFIG_CS89x0_NONISA_IRQ
|
||||
#if !defined(CS89x0_NONISA_IRQ) && !defined(CONFIG_CS89x0_PLATFORM)
|
||||
if (((1 << dev->irq) & lp->irq_map) == 0) {
|
||||
printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n",
|
||||
dev->name, dev->irq, lp->irq_map);
|
||||
@ -1746,7 +1752,7 @@ static int set_mac_address(struct net_device *dev, void *p)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef MODULE
|
||||
#if defined(MODULE) && !defined(CONFIG_CS89x0_PLATFORM)
|
||||
|
||||
static struct net_device *dev_cs89x0;
|
||||
|
||||
@ -1900,7 +1906,97 @@ cleanup_module(void)
|
||||
release_region(dev_cs89x0->base_addr, NETCARD_IO_EXTENT);
|
||||
free_netdev(dev_cs89x0);
|
||||
}
|
||||
#endif /* MODULE */
|
||||
#endif /* MODULE && !CONFIG_CS89x0_PLATFORM */
|
||||
|
||||
#ifdef CONFIG_CS89x0_PLATFORM
|
||||
static int __init cs89x0_platform_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
|
||||
struct net_local *lp;
|
||||
struct resource *mem_res;
|
||||
int err;
|
||||
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
|
||||
lp = netdev_priv(dev);
|
||||
|
||||
mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
dev->irq = platform_get_irq(pdev, 0);
|
||||
if (mem_res == NULL || dev->irq <= 0) {
|
||||
dev_warn(&dev->dev, "memory/interrupt resource missing.\n");
|
||||
err = -ENXIO;
|
||||
goto free;
|
||||
}
|
||||
|
||||
lp->phys_addr = mem_res->start;
|
||||
lp->size = resource_size(mem_res);
|
||||
if (!request_mem_region(lp->phys_addr, lp->size, DRV_NAME)) {
|
||||
dev_warn(&dev->dev, "request_mem_region() failed.\n");
|
||||
err = -EBUSY;
|
||||
goto free;
|
||||
}
|
||||
|
||||
lp->virt_addr = ioremap(lp->phys_addr, lp->size);
|
||||
if (!lp->virt_addr) {
|
||||
dev_warn(&dev->dev, "ioremap() failed.\n");
|
||||
err = -ENOMEM;
|
||||
goto release;
|
||||
}
|
||||
|
||||
err = cs89x0_probe1(dev, (unsigned long)lp->virt_addr, 0);
|
||||
if (err) {
|
||||
dev_warn(&dev->dev, "no cs8900 or cs8920 detected.\n");
|
||||
goto unmap;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, dev);
|
||||
return 0;
|
||||
|
||||
unmap:
|
||||
iounmap(lp->virt_addr);
|
||||
release:
|
||||
release_mem_region(lp->phys_addr, lp->size);
|
||||
free:
|
||||
free_netdev(dev);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int cs89x0_platform_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct net_device *dev = platform_get_drvdata(pdev);
|
||||
struct net_local *lp = netdev_priv(dev);
|
||||
|
||||
unregister_netdev(dev);
|
||||
iounmap(lp->virt_addr);
|
||||
release_mem_region(lp->phys_addr, lp->size);
|
||||
free_netdev(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver cs89x0_driver = {
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.remove = cs89x0_platform_remove,
|
||||
};
|
||||
|
||||
static int __init cs89x0_init(void)
|
||||
{
|
||||
return platform_driver_probe(&cs89x0_driver, cs89x0_platform_probe);
|
||||
}
|
||||
|
||||
module_init(cs89x0_init);
|
||||
|
||||
static void __exit cs89x0_cleanup(void)
|
||||
{
|
||||
platform_driver_unregister(&cs89x0_driver);
|
||||
}
|
||||
|
||||
module_exit(cs89x0_cleanup);
|
||||
|
||||
#endif /* CONFIG_CS89x0_PLATFORM */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
|
Loading…
Reference in New Issue
Block a user