diff options
Diffstat (limited to 'drivers/atm/fore200e.c')
| -rw-r--r-- | drivers/atm/fore200e.c | 518 |
1 files changed, 241 insertions, 277 deletions
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index 73338d231db..d4725fc0395 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c @@ -44,11 +44,12 @@ #include <asm/dma.h> #include <asm/byteorder.h> #include <asm/uaccess.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #ifdef CONFIG_SBUS +#include <linux/of.h> +#include <linux/of_device.h> #include <asm/idprom.h> -#include <asm/sbus.h> #include <asm/openprom.h> #include <asm/oplib.h> #include <asm/pgtable.h> @@ -91,7 +92,7 @@ #define FORE200E_INDEX(virt_addr, type, index) (&((type *)(virt_addr))[ index ]) -#define FORE200E_NEXT_ENTRY(index, modulo) (index = ++(index) % (modulo)) +#define FORE200E_NEXT_ENTRY(index, modulo) (index = ((index) + 1) % (modulo)) #if 1 #define ASSERT(expr) if (!(expr)) { \ @@ -526,8 +527,7 @@ fore200e_pca_reset(struct fore200e* fore200e) } -static int __devinit -fore200e_pca_map(struct fore200e* fore200e) +static int fore200e_pca_map(struct fore200e* fore200e) { DPRINTK(2, "device %s being mapped in memory\n", fore200e->name); @@ -560,8 +560,7 @@ fore200e_pca_unmap(struct fore200e* fore200e) } -static int __devinit -fore200e_pca_configure(struct fore200e* fore200e) +static int fore200e_pca_configure(struct fore200e *fore200e) { struct pci_dev* pci_dev = (struct pci_dev*)fore200e->bus_dev; u8 master_ctrl, latency; @@ -661,249 +660,191 @@ fore200e_pca_proc_read(struct fore200e* fore200e, char *page) #ifdef CONFIG_SBUS -static u32 -fore200e_sba_read(volatile u32 __iomem *addr) +static u32 fore200e_sba_read(volatile u32 __iomem *addr) { return sbus_readl(addr); } - -static void -fore200e_sba_write(u32 val, volatile u32 __iomem *addr) +static void fore200e_sba_write(u32 val, volatile u32 __iomem *addr) { sbus_writel(val, addr); } - -static u32 -fore200e_sba_dma_map(struct fore200e* fore200e, void* virt_addr, int size, int direction) +static u32 fore200e_sba_dma_map(struct fore200e *fore200e, void* virt_addr, int size, int direction) { - u32 dma_addr = sbus_map_single((struct sbus_dev*)fore200e->bus_dev, virt_addr, size, direction); + struct platform_device *op = fore200e->bus_dev; + u32 dma_addr; - DPRINTK(3, "SBUS DVMA mapping: virt_addr = 0x%p, size = %d, direction = %d --> dma_addr = 0x%08x\n", - virt_addr, size, direction, dma_addr); + dma_addr = dma_map_single(&op->dev, virt_addr, size, direction); + + DPRINTK(3, "SBUS DVMA mapping: virt_addr = 0x%p, size = %d, direction = %d --> dma_addr = 0x%08x\n", + virt_addr, size, direction, dma_addr); - return dma_addr; + return dma_addr; } - -static void -fore200e_sba_dma_unmap(struct fore200e* fore200e, u32 dma_addr, int size, int direction) +static void fore200e_sba_dma_unmap(struct fore200e *fore200e, u32 dma_addr, int size, int direction) { - DPRINTK(3, "SBUS DVMA unmapping: dma_addr = 0x%08x, size = %d, direction = %d,\n", - dma_addr, size, direction); + struct platform_device *op = fore200e->bus_dev; - sbus_unmap_single((struct sbus_dev*)fore200e->bus_dev, dma_addr, size, direction); -} + DPRINTK(3, "SBUS DVMA unmapping: dma_addr = 0x%08x, size = %d, direction = %d,\n", + dma_addr, size, direction); + dma_unmap_single(&op->dev, dma_addr, size, direction); +} -static void -fore200e_sba_dma_sync_for_cpu(struct fore200e* fore200e, u32 dma_addr, int size, int direction) +static void fore200e_sba_dma_sync_for_cpu(struct fore200e *fore200e, u32 dma_addr, int size, int direction) { - DPRINTK(3, "SBUS DVMA sync: dma_addr = 0x%08x, size = %d, direction = %d\n", dma_addr, size, direction); + struct platform_device *op = fore200e->bus_dev; + + DPRINTK(3, "SBUS DVMA sync: dma_addr = 0x%08x, size = %d, direction = %d\n", dma_addr, size, direction); - sbus_dma_sync_single_for_cpu((struct sbus_dev*)fore200e->bus_dev, dma_addr, size, direction); + dma_sync_single_for_cpu(&op->dev, dma_addr, size, direction); } -static void -fore200e_sba_dma_sync_for_device(struct fore200e* fore200e, u32 dma_addr, int size, int direction) +static void fore200e_sba_dma_sync_for_device(struct fore200e *fore200e, u32 dma_addr, int size, int direction) { - DPRINTK(3, "SBUS DVMA sync: dma_addr = 0x%08x, size = %d, direction = %d\n", dma_addr, size, direction); - - sbus_dma_sync_single_for_device((struct sbus_dev*)fore200e->bus_dev, dma_addr, size, direction); -} + struct platform_device *op = fore200e->bus_dev; + DPRINTK(3, "SBUS DVMA sync: dma_addr = 0x%08x, size = %d, direction = %d\n", dma_addr, size, direction); -/* allocate a DVMA consistent chunk of memory intended to act as a communication mechanism - (to hold descriptors, status, queues, etc.) shared by the driver and the adapter */ + dma_sync_single_for_device(&op->dev, dma_addr, size, direction); +} -static int -fore200e_sba_dma_chunk_alloc(struct fore200e* fore200e, struct chunk* chunk, - int size, int nbr, int alignment) +/* Allocate a DVMA consistent chunk of memory intended to act as a communication mechanism + * (to hold descriptors, status, queues, etc.) shared by the driver and the adapter. + */ +static int fore200e_sba_dma_chunk_alloc(struct fore200e *fore200e, struct chunk *chunk, + int size, int nbr, int alignment) { - chunk->alloc_size = chunk->align_size = size * nbr; + struct platform_device *op = fore200e->bus_dev; - /* returned chunks are page-aligned */ - chunk->alloc_addr = sbus_alloc_consistent((struct sbus_dev*)fore200e->bus_dev, - chunk->alloc_size, - &chunk->dma_addr); + chunk->alloc_size = chunk->align_size = size * nbr; - if ((chunk->alloc_addr == NULL) || (chunk->dma_addr == 0)) - return -ENOMEM; + /* returned chunks are page-aligned */ + chunk->alloc_addr = dma_alloc_coherent(&op->dev, chunk->alloc_size, + &chunk->dma_addr, GFP_ATOMIC); - chunk->align_addr = chunk->alloc_addr; + if ((chunk->alloc_addr == NULL) || (chunk->dma_addr == 0)) + return -ENOMEM; + + chunk->align_addr = chunk->alloc_addr; - return 0; + return 0; } - /* free a DVMA consistent chunk of memory */ - -static void -fore200e_sba_dma_chunk_free(struct fore200e* fore200e, struct chunk* chunk) +static void fore200e_sba_dma_chunk_free(struct fore200e *fore200e, struct chunk *chunk) { - sbus_free_consistent((struct sbus_dev*)fore200e->bus_dev, - chunk->alloc_size, - chunk->alloc_addr, - chunk->dma_addr); -} + struct platform_device *op = fore200e->bus_dev; + dma_free_coherent(&op->dev, chunk->alloc_size, + chunk->alloc_addr, chunk->dma_addr); +} -static void -fore200e_sba_irq_enable(struct fore200e* fore200e) +static void fore200e_sba_irq_enable(struct fore200e *fore200e) { - u32 hcr = fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_STICKY; - fore200e->bus->write(hcr | SBA200E_HCR_INTR_ENA, fore200e->regs.sba.hcr); + u32 hcr = fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_STICKY; + fore200e->bus->write(hcr | SBA200E_HCR_INTR_ENA, fore200e->regs.sba.hcr); } - -static int -fore200e_sba_irq_check(struct fore200e* fore200e) +static int fore200e_sba_irq_check(struct fore200e *fore200e) { - return fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_INTR_REQ; + return fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_INTR_REQ; } - -static void -fore200e_sba_irq_ack(struct fore200e* fore200e) +static void fore200e_sba_irq_ack(struct fore200e *fore200e) { - u32 hcr = fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_STICKY; - fore200e->bus->write(hcr | SBA200E_HCR_INTR_CLR, fore200e->regs.sba.hcr); + u32 hcr = fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_STICKY; + fore200e->bus->write(hcr | SBA200E_HCR_INTR_CLR, fore200e->regs.sba.hcr); } - -static void -fore200e_sba_reset(struct fore200e* fore200e) +static void fore200e_sba_reset(struct fore200e *fore200e) { - fore200e->bus->write(SBA200E_HCR_RESET, fore200e->regs.sba.hcr); - fore200e_spin(10); - fore200e->bus->write(0, fore200e->regs.sba.hcr); + fore200e->bus->write(SBA200E_HCR_RESET, fore200e->regs.sba.hcr); + fore200e_spin(10); + fore200e->bus->write(0, fore200e->regs.sba.hcr); } - -static int __init -fore200e_sba_map(struct fore200e* fore200e) +static int __init fore200e_sba_map(struct fore200e *fore200e) { - struct sbus_dev* sbus_dev = (struct sbus_dev*)fore200e->bus_dev; - unsigned int bursts; + struct platform_device *op = fore200e->bus_dev; + unsigned int bursts; - /* gain access to the SBA specific registers */ - fore200e->regs.sba.hcr = sbus_ioremap(&sbus_dev->resource[0], 0, SBA200E_HCR_LENGTH, "SBA HCR"); - fore200e->regs.sba.bsr = sbus_ioremap(&sbus_dev->resource[1], 0, SBA200E_BSR_LENGTH, "SBA BSR"); - fore200e->regs.sba.isr = sbus_ioremap(&sbus_dev->resource[2], 0, SBA200E_ISR_LENGTH, "SBA ISR"); - fore200e->virt_base = sbus_ioremap(&sbus_dev->resource[3], 0, SBA200E_RAM_LENGTH, "SBA RAM"); + /* gain access to the SBA specific registers */ + fore200e->regs.sba.hcr = of_ioremap(&op->resource[0], 0, SBA200E_HCR_LENGTH, "SBA HCR"); + fore200e->regs.sba.bsr = of_ioremap(&op->resource[1], 0, SBA200E_BSR_LENGTH, "SBA BSR"); + fore200e->regs.sba.isr = of_ioremap(&op->resource[2], 0, SBA200E_ISR_LENGTH, "SBA ISR"); + fore200e->virt_base = of_ioremap(&op->resource[3], 0, SBA200E_RAM_LENGTH, "SBA RAM"); - if (fore200e->virt_base == NULL) { - printk(FORE200E "unable to map RAM of device %s\n", fore200e->name); - return -EFAULT; - } + if (!fore200e->virt_base) { + printk(FORE200E "unable to map RAM of device %s\n", fore200e->name); + return -EFAULT; + } - DPRINTK(1, "device %s mapped to 0x%p\n", fore200e->name, fore200e->virt_base); + DPRINTK(1, "device %s mapped to 0x%p\n", fore200e->name, fore200e->virt_base); - fore200e->bus->write(0x02, fore200e->regs.sba.isr); /* XXX hardwired interrupt level */ + fore200e->bus->write(0x02, fore200e->regs.sba.isr); /* XXX hardwired interrupt level */ - /* get the supported DVMA burst sizes */ - bursts = prom_getintdefault(sbus_dev->bus->prom_node, "burst-sizes", 0x00); + /* get the supported DVMA burst sizes */ + bursts = of_getintprop_default(op->dev.of_node->parent, "burst-sizes", 0x00); - if (sbus_can_dma_64bit(sbus_dev)) - sbus_set_sbus64(sbus_dev, bursts); + if (sbus_can_dma_64bit()) + sbus_set_sbus64(&op->dev, bursts); - fore200e->state = FORE200E_STATE_MAP; - return 0; + fore200e->state = FORE200E_STATE_MAP; + return 0; } - -static void -fore200e_sba_unmap(struct fore200e* fore200e) +static void fore200e_sba_unmap(struct fore200e *fore200e) { - sbus_iounmap(fore200e->regs.sba.hcr, SBA200E_HCR_LENGTH); - sbus_iounmap(fore200e->regs.sba.bsr, SBA200E_BSR_LENGTH); - sbus_iounmap(fore200e->regs.sba.isr, SBA200E_ISR_LENGTH); - sbus_iounmap(fore200e->virt_base, SBA200E_RAM_LENGTH); -} + struct platform_device *op = fore200e->bus_dev; + of_iounmap(&op->resource[0], fore200e->regs.sba.hcr, SBA200E_HCR_LENGTH); + of_iounmap(&op->resource[1], fore200e->regs.sba.bsr, SBA200E_BSR_LENGTH); + of_iounmap(&op->resource[2], fore200e->regs.sba.isr, SBA200E_ISR_LENGTH); + of_iounmap(&op->resource[3], fore200e->virt_base, SBA200E_RAM_LENGTH); +} -static int __init -fore200e_sba_configure(struct fore200e* fore200e) +static int __init fore200e_sba_configure(struct fore200e *fore200e) { - fore200e->state = FORE200E_STATE_CONFIGURE; - return 0; + fore200e->state = FORE200E_STATE_CONFIGURE; + return 0; } - -static struct fore200e* __init -fore200e_sba_detect(const struct fore200e_bus* bus, int index) +static int __init fore200e_sba_prom_read(struct fore200e *fore200e, struct prom_data *prom) { - struct fore200e* fore200e; - struct sbus_bus* sbus_bus; - struct sbus_dev* sbus_dev = NULL; - - unsigned int count = 0; - - for_each_sbus (sbus_bus) { - for_each_sbusdev (sbus_dev, sbus_bus) { - if (strcmp(sbus_dev->prom_name, SBA200E_PROM_NAME) == 0) { - if (count >= index) - goto found; - count++; - } - } - } - return NULL; - - found: - if (sbus_dev->num_registers != 4) { - printk(FORE200E "this %s device has %d instead of 4 registers\n", - bus->model_name, sbus_dev->num_registers); - return NULL; - } - - fore200e = kzalloc(sizeof(struct fore200e), GFP_KERNEL); - if (fore200e == NULL) - return NULL; + struct platform_device *op = fore200e->bus_dev; + const u8 *prop; + int len; - fore200e->bus = bus; - fore200e->bus_dev = sbus_dev; - fore200e->irq = sbus_dev->irqs[ 0 ]; + prop = of_get_property(op->dev.of_node, "madaddrlo2", &len); + if (!prop) + return -ENODEV; + memcpy(&prom->mac_addr[4], prop, 4); - fore200e->phys_base = (unsigned long)sbus_dev; + prop = of_get_property(op->dev.of_node, "madaddrhi4", &len); + if (!prop) + return -ENODEV; + memcpy(&prom->mac_addr[2], prop, 4); - sprintf(fore200e->name, "%s-%d", bus->model_name, index - 1); + prom->serial_number = of_getintprop_default(op->dev.of_node, + "serialnumber", 0); + prom->hw_revision = of_getintprop_default(op->dev.of_node, + "promversion", 0); - return fore200e; + return 0; } - -static int __init -fore200e_sba_prom_read(struct fore200e* fore200e, struct prom_data* prom) +static int fore200e_sba_proc_read(struct fore200e *fore200e, char *page) { - struct sbus_dev* sbus_dev = (struct sbus_dev*) fore200e->bus_dev; - int len; - - len = prom_getproperty(sbus_dev->prom_node, "macaddrlo2", &prom->mac_addr[ 4 ], 4); - if (len < 0) - return -EBUSY; - - len = prom_getproperty(sbus_dev->prom_node, "macaddrhi4", &prom->mac_addr[ 2 ], 4); - if (len < 0) - return -EBUSY; - - prom_getproperty(sbus_dev->prom_node, "serialnumber", - (char*)&prom->serial_number, sizeof(prom->serial_number)); - - prom_getproperty(sbus_dev->prom_node, "promversion", - (char*)&prom->hw_revision, sizeof(prom->hw_revision)); - - return 0; -} + struct platform_device *op = fore200e->bus_dev; + const struct linux_prom_registers *regs; + regs = of_get_property(op->dev.of_node, "reg", NULL); -static int -fore200e_sba_proc_read(struct fore200e* fore200e, char *page) -{ - struct sbus_dev* sbus_dev = (struct sbus_dev*)fore200e->bus_dev; - - return sprintf(page, " SBUS slot/device:\t\t%d/'%s'\n", sbus_dev->slot, sbus_dev->prom_name); + return sprintf(page, " SBUS slot/device:\t\t%d/'%s'\n", + (regs ? regs->which_io : 0), op->dev.of_node->name); } #endif /* CONFIG_SBUS */ @@ -1854,7 +1795,7 @@ fore200e_getsockopt(struct atm_vcc* vcc, int level, int optname, void __user *op static int -fore200e_setsockopt(struct atm_vcc* vcc, int level, int optname, void __user *optval, int optlen) +fore200e_setsockopt(struct atm_vcc* vcc, int level, int optname, void __user *optval, unsigned int optlen) { /* struct fore200e* fore200e = FORE200E_DEV(vcc->dev); */ @@ -2085,8 +2026,7 @@ fore200e_change_qos(struct atm_vcc* vcc,struct atm_qos* qos, int flags) } -static int __devinit -fore200e_irq_request(struct fore200e* fore200e) +static int fore200e_irq_request(struct fore200e *fore200e) { if (request_irq(fore200e->irq, fore200e_interrupt, IRQF_SHARED, fore200e->name, fore200e->atm_dev) < 0) { @@ -2108,8 +2048,7 @@ fore200e_irq_request(struct fore200e* fore200e) } -static int __devinit -fore200e_get_esi(struct fore200e* fore200e) +static int fore200e_get_esi(struct fore200e *fore200e) { struct prom_data* prom = kzalloc(sizeof(struct prom_data), GFP_KERNEL | GFP_DMA); int ok, i; @@ -2123,12 +2062,10 @@ fore200e_get_esi(struct fore200e* fore200e) return -EBUSY; } - printk(FORE200E "device %s, rev. %c, S/N: %d, ESI: %02x:%02x:%02x:%02x:%02x:%02x\n", + printk(FORE200E "device %s, rev. %c, S/N: %d, ESI: %pM\n", fore200e->name, (prom->hw_revision & 0xFF) + '@', /* probably meaningless with SBA boards */ - prom->serial_number & 0xFFFF, - prom->mac_addr[ 2 ], prom->mac_addr[ 3 ], prom->mac_addr[ 4 ], - prom->mac_addr[ 5 ], prom->mac_addr[ 6 ], prom->mac_addr[ 7 ]); + prom->serial_number & 0xFFFF, &prom->mac_addr[2]); for (i = 0; i < ESI_LEN; i++) { fore200e->esi[ i ] = fore200e->atm_dev->esi[ i ] = prom->mac_addr[ i + 2 ]; @@ -2140,8 +2077,7 @@ fore200e_get_esi(struct fore200e* fore200e) } -static int __devinit -fore200e_alloc_rx_buf(struct fore200e* fore200e) +static int fore200e_alloc_rx_buf(struct fore200e *fore200e) { int scheme, magn, nbr, size, i; @@ -2205,8 +2141,7 @@ fore200e_alloc_rx_buf(struct fore200e* fore200e) } -static int __devinit -fore200e_init_bs_queue(struct fore200e* fore200e) +static int fore200e_init_bs_queue(struct fore200e *fore200e) { int scheme, magn, i; @@ -2268,8 +2203,7 @@ fore200e_init_bs_queue(struct fore200e* fore200e) } -static int __devinit -fore200e_init_rx_queue(struct fore200e* fore200e) +static int fore200e_init_rx_queue(struct fore200e *fore200e) { struct host_rxq* rxq = &fore200e->host_rxq; struct cp_rxq_entry __iomem * cp_entry; @@ -2328,8 +2262,7 @@ fore200e_init_rx_queue(struct fore200e* fore200e) } -static int __devinit -fore200e_init_tx_queue(struct fore200e* fore200e) +static int fore200e_init_tx_queue(struct fore200e *fore200e) { struct host_txq* txq = &fore200e->host_txq; struct cp_txq_entry __iomem * cp_entry; @@ -2391,8 +2324,7 @@ fore200e_init_tx_queue(struct fore200e* fore200e) } -static int __devinit -fore200e_init_cmd_queue(struct fore200e* fore200e) +static int fore200e_init_cmd_queue(struct fore200e *fore200e) { struct host_cmdq* cmdq = &fore200e->host_cmdq; struct cp_cmdq_entry __iomem * cp_entry; @@ -2433,10 +2365,10 @@ fore200e_init_cmd_queue(struct fore200e* fore200e) } -static void __devinit -fore200e_param_bs_queue(struct fore200e* fore200e, - enum buffer_scheme scheme, enum buffer_magn magn, - int queue_length, int pool_size, int supply_blksize) +static void fore200e_param_bs_queue(struct fore200e *fore200e, + enum buffer_scheme scheme, + enum buffer_magn magn, int queue_length, + int pool_size, int supply_blksize) { struct bs_spec __iomem * bs_spec = &fore200e->cp_queues->init.bs_spec[ scheme ][ magn ]; @@ -2447,8 +2379,7 @@ fore200e_param_bs_queue(struct fore200e* fore200e, } -static int __devinit -fore200e_initialize(struct fore200e* fore200e) +static int fore200e_initialize(struct fore200e *fore200e) { struct cp_queues __iomem * cpq; int ok, scheme, magn; @@ -2499,8 +2430,7 @@ fore200e_initialize(struct fore200e* fore200e) } -static void __devinit -fore200e_monitor_putc(struct fore200e* fore200e, char c) +static void fore200e_monitor_putc(struct fore200e *fore200e, char c) { struct cp_monitor __iomem * monitor = fore200e->cp_monitor; @@ -2511,8 +2441,7 @@ fore200e_monitor_putc(struct fore200e* fore200e, char c) } -static int __devinit -fore200e_monitor_getc(struct fore200e* fore200e) +static int fore200e_monitor_getc(struct fore200e *fore200e) { struct cp_monitor __iomem * monitor = fore200e->cp_monitor; unsigned long timeout = jiffies + msecs_to_jiffies(50); @@ -2536,8 +2465,7 @@ fore200e_monitor_getc(struct fore200e* fore200e) } -static void __devinit -fore200e_monitor_puts(struct fore200e* fore200e, char* str) +static void fore200e_monitor_puts(struct fore200e *fore200e, char *str) { while (*str) { @@ -2556,8 +2484,7 @@ fore200e_monitor_puts(struct fore200e* fore200e, char* str) #define FW_EXT "_ecd.bin2" #endif -static int __devinit -fore200e_load_and_start_fw(struct fore200e* fore200e) +static int fore200e_load_and_start_fw(struct fore200e *fore200e) { const struct firmware *firmware; struct device *device; @@ -2572,14 +2499,14 @@ fore200e_load_and_start_fw(struct fore200e* fore200e) device = &((struct pci_dev *) fore200e->bus_dev)->dev; #ifdef CONFIG_SBUS else if (strcmp(fore200e->bus->model_name, "SBA-200E") == 0) - device = &((struct sbus_dev *) fore200e->bus_dev)->ofdev.dev; + device = &((struct platform_device *) fore200e->bus_dev)->dev; #endif else return err; sprintf(buf, "%s%s", fore200e->bus->proc_name, FW_EXT); - if (request_firmware(&firmware, buf, device) == 1) { - printk(FORE200E "missing %s firmware image\n", fore200e->bus->model_name); + if ((err = request_firmware(&firmware, buf, device)) < 0) { + printk(FORE200E "problem loading firmware image %s\n", fore200e->bus->model_name); return err; } @@ -2625,15 +2552,14 @@ release: } -static int __devinit -fore200e_register(struct fore200e* fore200e) +static int fore200e_register(struct fore200e *fore200e, struct device *parent) { struct atm_dev* atm_dev; DPRINTK(2, "device %s being registered\n", fore200e->name); - atm_dev = atm_dev_register(fore200e->bus->proc_name, &fore200e_ops, -1, - NULL); + atm_dev = atm_dev_register(fore200e->bus->proc_name, parent, &fore200e_ops, + -1, NULL); if (atm_dev == NULL) { printk(FORE200E "unable to register device %s\n", fore200e->name); return -ENODEV; @@ -2652,10 +2578,9 @@ fore200e_register(struct fore200e* fore200e) } -static int __devinit -fore200e_init(struct fore200e* fore200e) +static int fore200e_init(struct fore200e *fore200e, struct device *parent) { - if (fore200e_register(fore200e) < 0) + if (fore200e_register(fore200e, parent) < 0) return -ENODEV; if (fore200e->bus->configure(fore200e) < 0) @@ -2701,9 +2626,78 @@ fore200e_init(struct fore200e* fore200e) return 0; } +#ifdef CONFIG_SBUS +static const struct of_device_id fore200e_sba_match[]; +static int fore200e_sba_probe(struct platform_device *op) +{ + const struct of_device_id *match; + const struct fore200e_bus *bus; + struct fore200e *fore200e; + static int index = 0; + int err; + + match = of_match_device(fore200e_sba_match, &op->dev); + if (!match) + return -EINVAL; + bus = match->data; + + fore200e = kzalloc(sizeof(struct fore200e), GFP_KERNEL); + if (!fore200e) + return -ENOMEM; + + fore200e->bus = bus; + fore200e->bus_dev = op; + fore200e->irq = op->archdata.irqs[0]; + fore200e->phys_base = op->resource[0].start; + + sprintf(fore200e->name, "%s-%d", bus->model_name, index); + + err = fore200e_init(fore200e, &op->dev); + if (err < 0) { + fore200e_shutdown(fore200e); + kfree(fore200e); + return err; + } + + index++; + dev_set_drvdata(&op->dev, fore200e); + + return 0; +} + +static int fore200e_sba_remove(struct platform_device *op) +{ + struct fore200e *fore200e = dev_get_drvdata(&op->dev); + + fore200e_shutdown(fore200e); + kfree(fore200e); + + return 0; +} + +static const struct of_device_id fore200e_sba_match[] = { + { + .name = SBA200E_PROM_NAME, + .data = (void *) &fore200e_bus[1], + }, + {}, +}; +MODULE_DEVICE_TABLE(of, fore200e_sba_match); + +static struct platform_driver fore200e_sba_driver = { + .driver = { + .name = "fore_200e", + .owner = THIS_MODULE, + .of_match_table = fore200e_sba_match, + }, + .probe = fore200e_sba_probe, + .remove = fore200e_sba_remove, +}; +#endif + #ifdef CONFIG_PCI -static int __devinit -fore200e_pca_detect(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent) +static int fore200e_pca_detect(struct pci_dev *pci_dev, + const struct pci_device_id *pci_ent) { const struct fore200e_bus* bus = (struct fore200e_bus*) pci_ent->driver_data; struct fore200e* fore200e; @@ -2736,7 +2730,7 @@ fore200e_pca_detect(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent sprintf(fore200e->name, "%s-%d", bus->model_name, index); - err = fore200e_init(fore200e); + err = fore200e_init(fore200e, &pci_dev->dev); if (err < 0) { fore200e_shutdown(fore200e); goto out_free; @@ -2756,7 +2750,7 @@ out_disable: } -static void __devexit fore200e_pca_remove_one(struct pci_dev *pci_dev) +static void fore200e_pca_remove_one(struct pci_dev *pci_dev) { struct fore200e *fore200e; @@ -2779,72 +2773,45 @@ MODULE_DEVICE_TABLE(pci, fore200e_pca_tbl); static struct pci_driver fore200e_pca_driver = { .name = "fore_200e", .probe = fore200e_pca_detect, - .remove = __devexit_p(fore200e_pca_remove_one), + .remove = fore200e_pca_remove_one, .id_table = fore200e_pca_tbl, }; #endif - -static int __init -fore200e_module_init(void) +static int __init fore200e_module_init(void) { - const struct fore200e_bus* bus; - struct fore200e* fore200e; - int index; - - printk(FORE200E "FORE Systems 200E-series ATM driver - version " FORE200E_VERSION "\n"); + int err = 0; - /* for each configured bus interface */ - for (bus = fore200e_bus; bus->model_name; bus++) { + printk(FORE200E "FORE Systems 200E-series ATM driver - version " FORE200E_VERSION "\n"); - /* detect all boards present on that bus */ - for (index = 0; bus->detect && (fore200e = bus->detect(bus, index)); index++) { - - printk(FORE200E "device %s found at 0x%lx, IRQ %s\n", - fore200e->bus->model_name, - fore200e->phys_base, fore200e_irq_itoa(fore200e->irq)); - - sprintf(fore200e->name, "%s-%d", bus->model_name, index); - - if (fore200e_init(fore200e) < 0) { - - fore200e_shutdown(fore200e); - break; - } - - list_add(&fore200e->entry, &fore200e_boards); - } - } +#ifdef CONFIG_SBUS + err = platform_driver_register(&fore200e_sba_driver); + if (err) + return err; +#endif #ifdef CONFIG_PCI - if (!pci_register_driver(&fore200e_pca_driver)) - return 0; + err = pci_register_driver(&fore200e_pca_driver); #endif - if (!list_empty(&fore200e_boards)) - return 0; +#ifdef CONFIG_SBUS + if (err) + platform_driver_unregister(&fore200e_sba_driver); +#endif - return -ENODEV; + return err; } - -static void __exit -fore200e_module_cleanup(void) +static void __exit fore200e_module_cleanup(void) { - struct fore200e *fore200e, *next; - #ifdef CONFIG_PCI - pci_unregister_driver(&fore200e_pca_driver); + pci_unregister_driver(&fore200e_pca_driver); +#endif +#ifdef CONFIG_SBUS + platform_driver_unregister(&fore200e_sba_driver); #endif - - list_for_each_entry_safe(fore200e, next, &fore200e_boards, entry) { - fore200e_shutdown(fore200e); - kfree(fore200e); - } - DPRINTK(1, "module being removed\n"); } - static int fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page) { @@ -2871,13 +2838,12 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page) " interrupt line:\t\t%s\n" " physical base address:\t0x%p\n" " virtual base address:\t0x%p\n" - " factory address (ESI):\t%02x:%02x:%02x:%02x:%02x:%02x\n" + " factory address (ESI):\t%pM\n" " board serial number:\t\t%d\n\n", fore200e_irq_itoa(fore200e->irq), (void*)fore200e->phys_base, fore200e->virt_base, - fore200e->esi[0], fore200e->esi[1], fore200e->esi[2], - fore200e->esi[3], fore200e->esi[4], fore200e->esi[5], + fore200e->esi, fore200e->esi[4] * 256 + fore200e->esi[5]); return len; @@ -2932,8 +2898,8 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page) u32 media_index = FORE200E_MEDIA_INDEX(fore200e->bus->read(&fore200e->cp_queues->media_type)); u32 oc3_index; - if ((media_index < 0) || (media_index > 4)) - media_index = 5; + if (media_index > 4) + media_index = 5; switch (fore200e->loop_mode) { case ATM_LM_NONE: oc3_index = 0; @@ -3163,7 +3129,6 @@ static const struct fore200e_bus fore200e_bus[] = { fore200e_pca_dma_sync_for_device, fore200e_pca_dma_chunk_alloc, fore200e_pca_dma_chunk_free, - NULL, fore200e_pca_configure, fore200e_pca_map, fore200e_pca_reset, @@ -3185,7 +3150,6 @@ static const struct fore200e_bus fore200e_bus[] = { fore200e_sba_dma_sync_for_device, fore200e_sba_dma_chunk_alloc, fore200e_sba_dma_chunk_free, - fore200e_sba_detect, fore200e_sba_configure, fore200e_sba_map, fore200e_sba_reset, |
