X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fparisc%2Fiosapic.c;h=6fb3f7979f21b89043bb3cc90d16240d110c590d;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=91df0bf181ddf7b6d3e9d889af3e7d2714b1ba22;hpb=f7f1b0f1e2fbadeab12d24236000e778aa9b1ead;p=linux-2.6.git diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c index 91df0bf18..6fb3f7979 100644 --- a/drivers/parisc/iosapic.c +++ b/drivers/parisc/iosapic.c @@ -50,12 +50,12 @@ ** ** PA Firmware ** ----------- -** PA-RISC platforms have two fundementally different types of firmware. +** PA-RISC platforms have two fundamentally different types of firmware. ** For PCI devices, "Legacy" PDC initializes the "INTERRUPT_LINE" register ** and BARs similar to a traditional PC BIOS. ** The newer "PAT" firmware supports PDC calls which return tables. -** PAT firmware only initializes PCI Console and Boot interface. -** With these tables, the OS can progam all other PCI devices. +** PAT firmware only initializes the PCI Console and Boot interface. +** With these tables, the OS can program all other PCI devices. ** ** One such PAT PDC call returns the "Interrupt Routing Table" (IRT). ** The IRT maps each PCI slot's INTA-D "output" line to an I/O SAPIC @@ -146,7 +146,7 @@ #include #endif -#include +#include #include "./iosapic_private.h" #define MODULE_NAME "iosapic" @@ -215,7 +215,7 @@ static inline void iosapic_write(void __iomem *iosapic, unsigned int reg, u32 va #define IOSAPIC_IRDT_ID_EID_SHIFT 0x10 -static spinlock_t iosapic_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(iosapic_lock); static inline void iosapic_eoi(void __iomem *addr, unsigned int data) { @@ -244,7 +244,7 @@ static struct irt_entry *iosapic_alloc_irt(int num_entries) * 4-byte alignment on 32-bit kernels */ a = (unsigned long)kmalloc(sizeof(struct irt_entry) * num_entries + 8, GFP_KERNEL); - a = (a + 7) & ~7; + a = (a + 7UL) & ~7UL; return (struct irt_entry *)a; } @@ -619,7 +619,7 @@ iosapic_set_irt_data( struct vector_info *vi, u32 *dp0, u32 *dp1) static struct vector_info *iosapic_get_vector(unsigned int irq) { - return irq_desc[irq].handler_data; + return irq_desc[irq].chip_data; } static void iosapic_disable_irq(unsigned int irq) @@ -692,6 +692,7 @@ static void iosapic_end_irq(unsigned int irq) DBG(KERN_DEBUG "end_irq(%d): eoi(%p, 0x%x)\n", irq, vi->eoi_addr, vi->eoi_data); iosapic_eoi(vi->eoi_addr, vi->eoi_data); + cpu_end_irq(irq); } static unsigned int iosapic_startup_irq(unsigned int irq) @@ -700,15 +701,39 @@ static unsigned int iosapic_startup_irq(unsigned int irq) return 0; } +#ifdef CONFIG_SMP +static void iosapic_set_affinity_irq(unsigned int irq, cpumask_t dest) +{ + struct vector_info *vi = iosapic_get_vector(irq); + u32 d0, d1, dummy_d0; + unsigned long flags; + + if (cpu_check_affinity(irq, &dest)) + return; + + vi->txn_addr = txn_affinity_addr(irq, first_cpu(dest)); + + spin_lock_irqsave(&iosapic_lock, flags); + /* d1 contains the destination CPU, so only want to set that + * entry */ + iosapic_rd_irt_entry(vi, &d0, &d1); + iosapic_set_irt_data(vi, &dummy_d0, &d1); + iosapic_wr_irt_entry(vi, d0, d1); + spin_unlock_irqrestore(&iosapic_lock, flags); +} +#endif + static struct hw_interrupt_type iosapic_interrupt_type = { .typename = "IO-SAPIC-level", .startup = iosapic_startup_irq, .shutdown = iosapic_disable_irq, .enable = iosapic_enable_irq, .disable = iosapic_disable_irq, - .ack = no_ack_irq, + .ack = cpu_ack_irq, .end = iosapic_end_irq, -// .set_affinity = iosapic_set_affinity_irq, +#ifdef CONFIG_SMP + .set_affinity = iosapic_set_affinity_irq, +#endif }; int iosapic_fixup_irq(void *isi_obj, struct pci_dev *pcidev) @@ -849,28 +874,24 @@ void *iosapic_register(unsigned long hpa) return NULL; } - isi = (struct iosapic_info *)kmalloc(sizeof(struct iosapic_info), GFP_KERNEL); + isi = kzalloc(sizeof(struct iosapic_info), GFP_KERNEL); if (!isi) { BUG(); return NULL; } - memset(isi, 0, sizeof(struct iosapic_info)); - - isi->addr = ioremap(hpa, 4096); + isi->addr = ioremap_nocache(hpa, 4096); isi->isi_hpa = hpa; isi->isi_version = iosapic_rd_version(isi); isi->isi_num_vectors = IOSAPIC_IRDT_MAX_ENTRY(isi->isi_version) + 1; vip = isi->isi_vector = (struct vector_info *) - kmalloc(sizeof(struct vector_info) * isi->isi_num_vectors, GFP_KERNEL); + kzalloc(sizeof(struct vector_info) * isi->isi_num_vectors, GFP_KERNEL); if (vip == NULL) { kfree(isi); return NULL; } - memset(vip, 0, sizeof(struct vector_info) * isi->isi_num_vectors); - for (cnt=0; cnt < isi->isi_num_vectors; cnt++, vip++) { vip->irqline = (unsigned char) cnt; vip->iosapic = isi;