diff options
Diffstat (limited to 'drivers/sn/ioc3.c')
| -rw-r--r-- | drivers/sn/ioc3.c | 114 |
1 files changed, 53 insertions, 61 deletions
diff --git a/drivers/sn/ioc3.c b/drivers/sn/ioc3.c index aaa009f4a7b..fb7ea0d9a73 100644 --- a/drivers/sn/ioc3.c +++ b/drivers/sn/ioc3.c @@ -7,15 +7,16 @@ * Pat Gefre <pfg@sgi.com> - IOC3 serial port IRQ demuxer */ -#include <linux/config.h> #include <linux/errno.h> #include <linux/module.h> #include <linux/pci.h> +#include <linux/dma-mapping.h> #include <linux/interrupt.h> #include <linux/spinlock.h> #include <linux/delay.h> #include <linux/ioc3.h> #include <linux/rwsem.h> +#include <linux/slab.h> #define IOC3_PCI_SIZE 0x100000 @@ -25,7 +26,7 @@ static DECLARE_RWSEM(ioc3_devices_rwsem); static struct ioc3_submodule *ioc3_submodules[IOC3_MAX_SUBMODULES]; static struct ioc3_submodule *ioc3_ethernet; -static rwlock_t ioc3_submodules_lock = RW_LOCK_UNLOCKED; +static DEFINE_RWLOCK(ioc3_submodules_lock); /* NIC probing code */ @@ -38,10 +39,10 @@ static inline unsigned mcr_pack(unsigned pulse, unsigned sample) static int nic_wait(struct ioc3_driver_data *idd) { - volatile unsigned mcr; + unsigned mcr; do { - mcr = (volatile unsigned)idd->vma->mcr; + mcr = readl(&idd->vma->mcr); } while (!(mcr & 2)); return mcr & 1; @@ -53,7 +54,7 @@ static int nic_reset(struct ioc3_driver_data *idd) unsigned long flags; local_irq_save(flags); - idd->vma->mcr = mcr_pack(500, 65); + writel(mcr_pack(500, 65), &idd->vma->mcr); presence = nic_wait(idd); local_irq_restore(flags); @@ -62,13 +63,13 @@ static int nic_reset(struct ioc3_driver_data *idd) return presence; } -static inline int nic_read_bit(struct ioc3_driver_data *idd) +static int nic_read_bit(struct ioc3_driver_data *idd) { int result; unsigned long flags; local_irq_save(flags); - idd->vma->mcr = mcr_pack(6, 13); + writel(mcr_pack(6, 13), &idd->vma->mcr); result = nic_wait(idd); local_irq_restore(flags); @@ -77,12 +78,12 @@ static inline int nic_read_bit(struct ioc3_driver_data *idd) return result; } -static inline void nic_write_bit(struct ioc3_driver_data *idd, int bit) +static void nic_write_bit(struct ioc3_driver_data *idd, int bit) { if (bit) - idd->vma->mcr = mcr_pack(6, 110); + writel(mcr_pack(6, 110), &idd->vma->mcr); else - idd->vma->mcr = mcr_pack(80, 30); + writel(mcr_pack(80, 30), &idd->vma->mcr); nic_wait(idd); } @@ -337,7 +338,7 @@ static void probe_nic(struct ioc3_driver_data *idd) int save = 0, loops = 3; unsigned long first, addr; - idd->vma->gpcr_s = GPCR_MLAN_EN; + writel(GPCR_MLAN_EN, &idd->vma->gpcr_s); while(loops>0) { idd->nic_part[0] = 0; @@ -371,8 +372,7 @@ static void probe_nic(struct ioc3_driver_data *idd) /* Interrupts */ -static inline void -write_ireg(struct ioc3_driver_data *idd, uint32_t val, int which) +static void write_ireg(struct ioc3_driver_data *idd, uint32_t val, int which) { unsigned long flags; @@ -399,21 +399,21 @@ static inline uint32_t get_pending_intrs(struct ioc3_driver_data *idd) return intrs; } -static irqreturn_t ioc3_intr_io(int irq, void *arg, struct pt_regs *regs) +static irqreturn_t ioc3_intr_io(int irq, void *arg) { unsigned long flags; - struct ioc3_driver_data *idd = (struct ioc3_driver_data *)arg; + struct ioc3_driver_data *idd = arg; int handled = 1, id; unsigned int pending; read_lock_irqsave(&ioc3_submodules_lock, flags); - if(idd->dual_irq && idd->vma->eisr) { + if(idd->dual_irq && readb(&idd->vma->eisr)) { /* send Ethernet IRQ to the driver */ if(ioc3_ethernet && idd->active[ioc3_ethernet->id] && ioc3_ethernet->intr) { handled = handled && !ioc3_ethernet->intr(ioc3_ethernet, - idd, 0, regs); + idd, 0); } } pending = get_pending_intrs(idd); /* look at the IO IRQs */ @@ -425,8 +425,7 @@ static irqreturn_t ioc3_intr_io(int irq, void *arg, struct pt_regs *regs) write_ireg(idd, ioc3_submodules[id]->irq_mask, IOC3_W_IEC); if(!ioc3_submodules[id]->intr(ioc3_submodules[id], - idd, pending & ioc3_submodules[id]->irq_mask, - regs)) + idd, pending & ioc3_submodules[id]->irq_mask)) pending &= ~ioc3_submodules[id]->irq_mask; if (ioc3_submodules[id]->reset_mask) write_ireg(idd, ioc3_submodules[id]->irq_mask, @@ -443,7 +442,7 @@ static irqreturn_t ioc3_intr_io(int irq, void *arg, struct pt_regs *regs) return handled?IRQ_HANDLED:IRQ_NONE; } -static irqreturn_t ioc3_intr_eth(int irq, void *arg, struct pt_regs *regs) +static irqreturn_t ioc3_intr_eth(int irq, void *arg) { unsigned long flags; struct ioc3_driver_data *idd = (struct ioc3_driver_data *)arg; @@ -454,8 +453,7 @@ static irqreturn_t ioc3_intr_eth(int irq, void *arg, struct pt_regs *regs) read_lock_irqsave(&ioc3_submodules_lock, flags); if(ioc3_ethernet && idd->active[ioc3_ethernet->id] && ioc3_ethernet->intr) - handled = handled && !ioc3_ethernet->intr(ioc3_ethernet, idd, 0, - regs); + handled = handled && !ioc3_ethernet->intr(ioc3_ethernet, idd, 0); read_unlock_irqrestore(&ioc3_submodules_lock, flags); return handled?IRQ_HANDLED:IRQ_NONE; } @@ -564,7 +562,7 @@ void ioc3_unregister_submodule(struct ioc3_submodule *is) printk(KERN_WARNING "%s: IOC3 submodule %s remove failed " "for pci_dev %s.\n", - __FUNCTION__, module_name(is->owner), + __func__, module_name(is->owner), pci_name(idd->pdev)); idd->active[is->id] = 0; if(is->irq_mask) @@ -577,9 +575,8 @@ void ioc3_unregister_submodule(struct ioc3_submodule *is) * Device management * *********************/ -static char * -ioc3_class_names[]={"unknown", "IP27 BaseIO", "IP30 system", "MENET 1/2/3", - "MENET 4", "CADduo", "Altix Serial"}; +static char *ioc3_class_names[] = { "unknown", "IP27 BaseIO", "IP30 system", + "MENET 1/2/3", "MENET 4", "CADduo", "Altix Serial" }; static int ioc3_class(struct ioc3_driver_data *idd) { @@ -614,33 +611,32 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) if ((ret = pci_enable_device(pdev))) { printk(KERN_WARNING "%s: Failed to enable IOC3 device for pci_dev %s.\n", - __FUNCTION__, pci_name(pdev)); + __func__, pci_name(pdev)); goto out; } pci_set_master(pdev); #ifdef USE_64BIT_DMA - ret = pci_set_dma_mask(pdev, 0xffffffffffffffffULL); + ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); if (!ret) { - ret = pci_set_consistent_dma_mask(pdev, 0xffffffffffffffffULL); + ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); if (ret < 0) { printk(KERN_WARNING "%s: Unable to obtain 64 bit DMA " "for consistent allocations\n", - __FUNCTION__); + __func__); } } #endif /* Set up per-IOC3 data */ - idd = kmalloc(sizeof(struct ioc3_driver_data), GFP_KERNEL); + idd = kzalloc(sizeof(struct ioc3_driver_data), GFP_KERNEL); if (!idd) { printk(KERN_WARNING "%s: Failed to allocate IOC3 data for pci_dev %s.\n", - __FUNCTION__, pci_name(pdev)); + __func__, pci_name(pdev)); ret = -ENODEV; goto out_idd; } - memset(idd, 0, sizeof(struct ioc3_driver_data)); spin_lock_init(&idd->ir_lock); spin_lock_init(&idd->gpio_lock); idd->pdev = pdev; @@ -653,15 +649,15 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) printk(KERN_WARNING "%s: Unable to find IOC3 resource " "for pci_dev %s.\n", - __FUNCTION__, pci_name(pdev)); + __func__, pci_name(pdev)); ret = -ENODEV; goto out_pci; } - if (!request_region(idd->pma, IOC3_PCI_SIZE, "ioc3")) { + if (!request_mem_region(idd->pma, IOC3_PCI_SIZE, "ioc3")) { printk(KERN_WARNING "%s: Unable to request IOC3 region " "for pci_dev %s.\n", - __FUNCTION__, pci_name(pdev)); + __func__, pci_name(pdev)); ret = -ENODEV; goto out_pci; } @@ -670,7 +666,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) printk(KERN_WARNING "%s: Unable to remap IOC3 region " "for pci_dev %s.\n", - __FUNCTION__, pci_name(pdev)); + __func__, pci_name(pdev)); ret = -ENODEV; goto out_misc_region; } @@ -678,11 +674,11 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) /* Track PCI-device specific data */ pci_set_drvdata(pdev, idd); down_write(&ioc3_devices_rwsem); - list_add(&idd->list, &ioc3_devices); + list_add_tail(&idd->list, &ioc3_devices); idd->id = ioc3_counter++; up_write(&ioc3_devices_rwsem); - idd->gpdr_shadow = idd->vma->gpdr; + idd->gpdr_shadow = readl(&idd->vma->gpdr); /* Read IOC3 NIC contents */ probe_nic(idd); @@ -707,49 +703,47 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) writel(~0, &idd->vma->eisr); idd->dual_irq = 1; - if (!request_irq(pdev->irq, ioc3_intr_eth, SA_SHIRQ, + if (!request_irq(pdev->irq, ioc3_intr_eth, IRQF_SHARED, "ioc3-eth", (void *)idd)) { idd->irq_eth = pdev->irq; } else { printk(KERN_WARNING "%s : request_irq fails for IRQ 0x%x\n ", - __FUNCTION__, pdev->irq); + __func__, pdev->irq); } - if (!request_irq(pdev->irq+2, ioc3_intr_io, SA_SHIRQ, + if (!request_irq(pdev->irq+2, ioc3_intr_io, IRQF_SHARED, "ioc3-io", (void *)idd)) { idd->irq_io = pdev->irq+2; } else { printk(KERN_WARNING "%s : request_irq fails for IRQ 0x%x\n ", - __FUNCTION__, pdev->irq+2); + __func__, pdev->irq+2); } } else { - if (!request_irq(pdev->irq, ioc3_intr_io, SA_SHIRQ, + if (!request_irq(pdev->irq, ioc3_intr_io, IRQF_SHARED, "ioc3", (void *)idd)) { idd->irq_io = pdev->irq; } else { printk(KERN_WARNING "%s : request_irq fails for IRQ 0x%x\n ", - __FUNCTION__, pdev->irq); + __func__, pdev->irq); } } /* Add this IOC3 to all submodules */ - read_lock(&ioc3_submodules_lock); for(id=0;id<IOC3_MAX_SUBMODULES;id++) if(ioc3_submodules[id] && ioc3_submodules[id]->probe) { idd->active[id] = 1; idd->active[id] = !ioc3_submodules[id]->probe (ioc3_submodules[id], idd); } - read_unlock(&ioc3_submodules_lock); printk(KERN_INFO "IOC3 Master Driver loaded for %s\n", pci_name(pdev)); return 0; out_misc_region: - release_region(idd->pma, IOC3_PCI_SIZE); + release_mem_region(idd->pma, IOC3_PCI_SIZE); out_pci: kfree(idd); out_idd: @@ -767,7 +761,6 @@ static void ioc3_remove(struct pci_dev *pdev) idd = pci_get_drvdata(pdev); /* Remove this IOC3 from all submodules */ - read_lock(&ioc3_submodules_lock); for(id=0;id<IOC3_MAX_SUBMODULES;id++) if(idd->active[id]) { if(ioc3_submodules[id] && ioc3_submodules[id]->remove) @@ -776,12 +769,11 @@ static void ioc3_remove(struct pci_dev *pdev) printk(KERN_WARNING "%s: IOC3 submodule 0x%s remove failed " "for pci_dev %s.\n", - __FUNCTION__, + __func__, module_name(ioc3_submodules[id]->owner), pci_name(pdev)); idd->active[id] = 0; } - read_unlock(&ioc3_submodules_lock); /* Clear and disable all IRQs */ write_ireg(idd, ~0, IOC3_W_IEC); @@ -792,7 +784,7 @@ static void ioc3_remove(struct pci_dev *pdev) if(idd->dual_irq) free_irq(idd->irq_eth, (void *)idd); iounmap(idd->vma); - release_region(idd->pma, IOC3_PCI_SIZE); + release_mem_region(idd->pma, IOC3_PCI_SIZE); /* Disable IOC3 and relinquish */ pci_disable_device(pdev); @@ -823,15 +815,15 @@ MODULE_DEVICE_TABLE(pci, ioc3_id_table); *********************/ /* Module load */ -static int __devinit ioc3_init(void) +static int __init ioc3_init(void) { if (ia64_platform_is("sn2")) return pci_register_driver(&ioc3_driver); - return 0; + return -ENODEV; } /* Module unload */ -static void __devexit ioc3_exit(void) +static void __exit ioc3_exit(void) { pci_unregister_driver(&ioc3_driver); } @@ -843,9 +835,9 @@ MODULE_AUTHOR("Stanislaw Skowronek <skylark@linux-mips.org>"); MODULE_DESCRIPTION("PCI driver for SGI IOC3"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(ioc3_register_submodule); -EXPORT_SYMBOL(ioc3_unregister_submodule); -EXPORT_SYMBOL(ioc3_ack); -EXPORT_SYMBOL(ioc3_gpcr_set); -EXPORT_SYMBOL(ioc3_disable); -EXPORT_SYMBOL(ioc3_enable); +EXPORT_SYMBOL_GPL(ioc3_register_submodule); +EXPORT_SYMBOL_GPL(ioc3_unregister_submodule); +EXPORT_SYMBOL_GPL(ioc3_ack); +EXPORT_SYMBOL_GPL(ioc3_gpcr_set); +EXPORT_SYMBOL_GPL(ioc3_disable); +EXPORT_SYMBOL_GPL(ioc3_enable); |
