diff options
Diffstat (limited to 'drivers')
59 files changed, 330 insertions, 367 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c index dafae6d2f7ac..18e2a89aa138 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -662,6 +662,9 @@ void device_initialize(struct device *dev) INIT_LIST_HEAD(&dev->devres_head); device_pm_init(dev); set_dev_node(dev, -1); +#ifdef CONFIG_GENERIC_MSI_IRQ + INIT_LIST_HEAD(&dev->msi_list); +#endif } EXPORT_SYMBOL_GPL(device_initialize); diff --git a/drivers/irqchip/exynos-combiner.c b/drivers/irqchip/exynos-combiner.c index 5c82e3bdafdf..e9c6f2a5b52d 100644 --- a/drivers/irqchip/exynos-combiner.c +++ b/drivers/irqchip/exynos-combiner.c @@ -15,13 +15,12 @@ #include <linux/slab.h> #include <linux/syscore_ops.h> #include <linux/irqdomain.h> +#include <linux/irqchip.h> #include <linux/irqchip/chained_irq.h> #include <linux/interrupt.h> #include <linux/of_address.h> #include <linux/of_irq.h> -#include "irqchip.h" - #define COMBINER_ENABLE_SET 0x0 #define COMBINER_ENABLE_CLEAR 0x4 #define COMBINER_INT_STATUS 0xC @@ -66,10 +65,12 @@ static void combiner_unmask_irq(struct irq_data *data) __raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_SET); } -static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) +static void combiner_handle_cascade_irq(unsigned int __irq, + struct irq_desc *desc) { - struct combiner_chip_data *chip_data = irq_get_handler_data(irq); - struct irq_chip *chip = irq_get_chip(irq); + struct combiner_chip_data *chip_data = irq_desc_get_handler_data(desc); + struct irq_chip *chip = irq_desc_get_chip(desc); + unsigned int irq = irq_desc_get_irq(desc); unsigned int cascade_irq, combiner_irq; unsigned long status; @@ -122,9 +123,8 @@ static struct irq_chip combiner_chip = { static void __init combiner_cascade_irq(struct combiner_chip_data *combiner_data, unsigned int irq) { - if (irq_set_handler_data(irq, combiner_data) != 0) - BUG(); - irq_set_chained_handler(irq, combiner_handle_cascade_irq); + irq_set_chained_handler_and_data(irq, combiner_handle_cascade_irq, + combiner_data); } static void __init combiner_init_one(struct combiner_chip_data *combiner_data, @@ -185,14 +185,14 @@ static void __init combiner_init(void __iomem *combiner_base, combiner_data = kcalloc(max_nr, sizeof (*combiner_data), GFP_KERNEL); if (!combiner_data) { - pr_warning("%s: could not allocate combiner data\n", __func__); + pr_warn("%s: could not allocate combiner data\n", __func__); return; } combiner_irq_domain = irq_domain_add_linear(np, nr_irq, &combiner_irq_domain_ops, combiner_data); if (WARN_ON(!combiner_irq_domain)) { - pr_warning("%s: irq domain init failed\n", __func__); + pr_warn("%s: irq domain init failed\n", __func__); return; } diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c index 0d3b0fe2f175..39b72da0c143 100644 --- a/drivers/irqchip/irq-armada-370-xp.c +++ b/drivers/irqchip/irq-armada-370-xp.c @@ -18,6 +18,7 @@ #include <linux/init.h> #include <linux/irq.h> #include <linux/interrupt.h> +#include <linux/irqchip.h> #include <linux/irqchip/chained_irq.h> #include <linux/cpu.h> #include <linux/io.h> @@ -33,8 +34,6 @@ #include <asm/smp_plat.h> #include <asm/mach/irq.h> -#include "irqchip.h" - /* Interrupt Controller Registers Map */ #define ARMADA_370_XP_INT_SET_MASK_OFFS (0x48) #define ARMADA_370_XP_INT_CLEAR_MASK_OFFS (0x4C) @@ -451,7 +450,7 @@ static void armada_370_xp_handle_msi_irq(struct pt_regs *r, bool b) {} static void armada_370_xp_mpic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) { - struct irq_chip *chip = irq_get_chip(irq); + struct irq_chip *chip = irq_desc_get_chip(desc); unsigned long irqmap, irqn, irqsrc, cpuid; unsigned int cascade_irq; diff --git a/drivers/irqchip/irq-atmel-aic.c b/drivers/irqchip/irq-atmel-aic.c index dae3604b32a9..8a0c7f288198 100644 --- a/drivers/irqchip/irq-atmel-aic.c +++ b/drivers/irqchip/irq-atmel-aic.c @@ -19,6 +19,7 @@ #include <linux/bitmap.h> #include <linux/types.h> #include <linux/irq.h> +#include <linux/irqchip.h> #include <linux/of.h> #include <linux/of_address.h> #include <linux/of_irq.h> @@ -31,7 +32,6 @@ #include <asm/mach/irq.h> #include "irq-atmel-aic-common.h" -#include "irqchip.h" /* Number of irq lines managed by AIC */ #define NR_AIC_IRQS 32 @@ -225,7 +225,7 @@ static void __init at91sam9g45_aic_irq_fixup(struct device_node *root) aic_common_rtt_irq_fixup(root); } -static const struct of_device_id __initdata aic_irq_fixups[] = { +static const struct of_device_id aic_irq_fixups[] __initconst = { { .compatible = "atmel,at91rm9200", .data = at91rm9200_aic_irq_fixup }, { .compatible = "atmel,at91sam9g45", .data = at91sam9g45_aic_irq_fixup }, { .compatible = "atmel,at91sam9n12", .data = at91rm9200_aic_irq_fixup }, diff --git a/drivers/irqchip/irq-atmel-aic5.c b/drivers/irqchip/irq-atmel-aic5.c index 459bf4429d36..9da9942ac83c 100644 --- a/drivers/irqchip/irq-atmel-aic5.c +++ b/drivers/irqchip/irq-atmel-aic5.c @@ -19,6 +19,7 @@ #include <linux/bitmap.h> #include <linux/types.h> #include <linux/irq.h> +#include <linux/irqchip.h> #include <linux/of.h> #include <linux/of_address.h> #include <linux/of_irq.h> @@ -31,7 +32,6 @@ #include <asm/mach/irq.h> #include "irq-atmel-aic-common.h" -#include "irqchip.h" /* Number of irq lines managed by AIC */ #define NR_AIC5_IRQS 128 @@ -290,7 +290,7 @@ static void __init sama5d3_aic_irq_fixup(struct device_node *root) aic_common_rtc_irq_fixup(root); } -static const struct of_device_id __initdata aic5_irq_fixups[] = { +static const struct of_device_id aic5_irq_fixups[] __initconst = { { .compatible = "atmel,sama5d3", .data = sama5d3_aic_irq_fixup }, { .compatible = "atmel,sama5d4", .data = sama5d3_aic_irq_fixup }, { /* sentinel */ }, diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c index e68c3b60a681..ca35171e8afc 100644 --- a/drivers/irqchip/irq-bcm2835.c +++ b/drivers/irqchip/irq-bcm2835.c @@ -48,13 +48,12 @@ #include <linux/slab.h> #include <linux/of_address.h> #include <linux/of_irq.h> +#include <linux/irqchip.h> #include <linux/irqdomain.h> #include <asm/exception.h> #include <asm/mach/irq.h> -#include "irqchip.h" - /* Put the bank and irq (32 bits) into the hwirq */ #define MAKE_HWIRQ(b, n) ((b << 5) | (n)) #define HWIRQ_BANK(i) (i >> 5) @@ -76,10 +75,10 @@ #define NR_BANKS 3 #define IRQS_PER_BANK 32 -static int reg_pending[] __initconst = { 0x00, 0x04, 0x08 }; -static int reg_enable[] __initconst = { 0x18, 0x10, 0x14 }; -static int reg_disable[] __initconst = { 0x24, 0x1c, 0x20 }; -static int bank_irqs[] __initconst = { 8, 32, 32 }; +static const int reg_pending[] __initconst = { 0x00, 0x04, 0x08 }; +static const int reg_enable[] __initconst = { 0x18, 0x10, 0x14 }; +static const int reg_disable[] __initconst = { 0x24, 0x1c, 0x20 }; +static const int bank_irqs[] __initconst = { 8, 32, 32 }; static const int shortcuts[] = { 7, 9, 10, 18, 19, /* Bank 1 */ diff --git a/drivers/irqchip/irq-bcm7038-l1.c b/drivers/irqchip/irq-bcm7038-l1.c index d3b8c8be15f6..409bdc6366c2 100644 --- a/drivers/irqchip/irq-bcm7038-l1.c +++ b/drivers/irqchip/irq-bcm7038-l1.c @@ -29,10 +29,9 @@ #include <linux/slab.h> #include <linux/smp.h> #include <linux/types.h> +#include <linux/irqchip.h> #include <linux/irqchip/chained_irq.h> -#include "irqchip.h" - #define IRQS_PER_WORD 32 #define REG_BYTES_PER_IRQ_WORD (sizeof(u32) * 4) #define MAX_WORDS 8 @@ -257,8 +256,8 @@ static int __init bcm7038_l1_init_one(struct device_node *dn, pr_err("failed to map parent interrupt %d\n", parent_irq); return -EINVAL; } - irq_set_handler_data(parent_irq, intc); - irq_set_chained_handler(parent_irq, bcm7038_l1_irq_handle); + irq_set_chained_handler_and_data(parent_irq, bcm7038_l1_irq_handle, + intc); return 0; } diff --git a/drivers/irqchip/irq-bcm7120-l2.c b/drivers/irqchip/irq-bcm7120-l2.c index 3ba5cc780fcb..d3f976913a6f 100644 --- a/drivers/irqchip/irq-bcm7120-l2.c +++ b/drivers/irqchip/irq-bcm7120-l2.c @@ -26,10 +26,9 @@ #include <linux/irqdomain.h> #include <linux/reboot.h> #include <linux/bitops.h> +#include <linux/irqchip.h> #include <linux/irqchip/chained_irq.h> -#include "irqchip.h" - /* Register offset in the L2 interrupt controller */ #define IRQEN 0x00 #define IRQSTAT 0x04 @@ -38,6 +37,11 @@ #define MAX_MAPPINGS (MAX_WORDS * 2) #define IRQS_PER_WORD 32 +struct bcm7120_l1_intc_data { + struct bcm7120_l2_intc_data *b; + u32 irq_map_mask[MAX_WORDS]; +}; + struct bcm7120_l2_intc_data { unsigned int n_words; void __iomem *map_base[MAX_MAPPINGS]; @@ -47,14 +51,15 @@ struct bcm7120_l2_intc_data { struct irq_domain *domain; bool can_wake; u32 irq_fwd_mask[MAX_WORDS]; - u32 irq_map_mask[MAX_WORDS]; + struct bcm7120_l1_intc_data *l1_data; int num_parent_irqs; const __be32 *map_mask_prop; }; static void bcm7120_l2_intc_irq_handle(unsigned int irq, struct irq_desc *desc) { - struct bcm7120_l2_intc_data *b = irq_desc_get_handler_data(desc); + struct bcm7120_l1_intc_data *data = irq_desc_get_handler_data(desc); + struct bcm7120_l2_intc_data *b = data->b; struct irq_chip *chip = irq_desc_get_chip(desc); unsigned int idx; @@ -69,7 +74,8 @@ static void bcm7120_l2_intc_irq_handle(unsigned int irq, struct irq_desc *desc) irq_gc_lock(gc); pending = irq_reg_readl(gc, b->stat_offset[idx]) & - gc->mask_cache; + gc->mask_cache & + data->irq_map_mask[idx]; irq_gc_unlock(gc); for_each_set_bit(hwirq, &pending, IRQS_PER_WORD) { @@ -81,11 +87,10 @@ static void bcm7120_l2_intc_irq_handle(unsigned int irq, struct irq_desc *desc) chained_irq_exit(chip, desc); } -static void bcm7120_l2_intc_suspend(struct irq_data *d) +static void bcm7120_l2_intc_suspend(struct irq_chip_generic *gc) { - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); - struct irq_chip_type *ct = irq_data_get_chip_type(d); struct bcm7120_l2_intc_data *b = gc->private; + struct irq_chip_type *ct = gc->chip_types; irq_gc_lock(gc); if (b->can_wake) @@ -94,10 +99,9 @@ static void bcm7120_l2_intc_suspend(struct irq_data *d) irq_gc_unlock(gc); } -static void bcm7120_l2_intc_resume(struct irq_data *d) +static void bcm7120_l2_intc_resume(struct irq_chip_generic *gc) { - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); - struct irq_chip_type *ct = irq_data_get_chip_type(d); + struct irq_chip_type *ct = gc->chip_types; /* Restore the saved mask */ irq_gc_lock(gc); @@ -107,8 +111,9 @@ static void bcm7120_l2_intc_resume(struct irq_data *d) static int bcm7120_l2_intc_init_one(struct device_node *dn, struct bcm7120_l2_intc_data *data, - int irq) + int irq, u32 *valid_mask) { + struct bcm7120_l1_intc_data *l1_data = &data->l1_data[irq]; int parent_irq; unsigned int idx; @@ -120,20 +125,28 @@ static int bcm7120_l2_intc_init_one(struct device_node *dn, /* For multiple parent IRQs with multiple words, this looks like: * <irq0_w0 irq0_w1 irq1_w0 irq1_w1 ...> + * + * We need to associate a given parent interrupt with its corresponding + * map_mask in order to mask the status register with it because we + * have the same handler being called for multiple parent interrupts. + * + * This is typically something needed on BCM7xxx (STB chips). */ for (idx = 0; idx < data->n_words; idx++) { if (data->map_mask_prop) { - data->irq_map_mask[idx] |= + l1_data->irq_map_mask[idx] |= be32_to_cpup(data->map_mask_prop + irq * data->n_words + idx); } else { - data->irq_map_mask[idx] = 0xffffffff; + l1_data->irq_map_mask[idx] = 0xffffffff; } + valid_mask[idx] |= l1_data->irq_map_mask[idx]; } - irq_set_handler_data(parent_irq, data); - irq_set_chained_handler(parent_irq, bcm7120_l2_intc_irq_handle); + l1_data->b = data; + irq_set_chained_handler_and_data(parent_irq, + bcm7120_l2_intc_irq_handle, l1_data); return 0; } @@ -214,6 +227,7 @@ int __init bcm7120_l2_intc_probe(struct device_node *dn, struct irq_chip_type *ct; int ret = 0; unsigned int idx, irq, flags; + u32 valid_mask[MAX_WORDS] = { }; data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) @@ -226,9 +240,16 @@ int __init bcm7120_l2_intc_probe(struct device_node *dn, goto out_unmap; } + data->l1_data = kcalloc(data->num_parent_irqs, sizeof(*data->l1_data), + GFP_KERNEL); + if (!data->l1_data) { + ret = -ENOMEM; + goto out_free_l1_data; + } + ret = iomap_regs_fn(dn, data); if (ret < 0) - goto out_unmap; + goto out_free_l1_data; for (idx = 0; idx < data->n_words; idx++) { __raw_writel(data->irq_fwd_mask[idx], @@ -237,16 +258,16 @@ int __init bcm7120_l2_intc_probe(struct device_node *dn, } for (irq = 0; irq < data->num_parent_irqs; irq++) { - ret = bcm7120_l2_intc_init_one(dn, data, irq); + ret = bcm7120_l2_intc_init_one(dn, data, irq, valid_mask); if (ret) - goto out_unmap; + goto out_free_l1_data; } data->domain = irq_domain_add_linear(dn, IRQS_PER_WORD * data->n_words, &irq_generic_chip_ops, NULL); if (!data->domain) { ret = -ENOMEM; - goto out_unmap; + goto out_free_l1_data; } /* MIPS chips strapped for BE will automagically configure the @@ -270,7 +291,7 @@ int __init bcm7120_l2_intc_probe(struct device_node *dn, irq = idx * IRQS_PER_WORD; gc = irq_get_domain_generic_chip(data->domain, irq); - gc->unused = 0xffffffff & ~data->irq_map_mask[idx]; + gc->unused = 0xffffffff & ~valid_mask[idx]; gc->private = data; ct = gc->chip_types; @@ -280,8 +301,15 @@ int __init bcm7120_l2_intc_probe(struct device_node *dn, ct->chip.irq_mask = irq_gc_mask_clr_bit; ct->chip.irq_unmask = irq_gc_mask_set_bit; ct->chip.irq_ack = irq_gc_noop; - ct->chip.irq_suspend = bcm7120_l2_intc_suspend; - ct->chip.irq_resume = bcm7120_l2_intc_resume; + gc->suspend = bcm7120_l2_intc_suspend; + gc->resume = bcm7120_l2_intc_resume; + + /* + * Initialize mask-cache, in case we need it for + * saving/restoring fwd mask even w/o any child interrupts + * installed + */ + gc->mask_cache = irq_reg_readl(gc, ct->regs.mask); if (data->can_wake) { /* This IRQ chip can wake the system, set all @@ -300,6 +328,8 @@ int __init bcm7120_l2_intc_probe(struct device_node *dn, out_free_domain: irq_domain_remove(data->domain); +out_free_l1_data: + kfree(data->l1_data); out_unmap: for (idx = 0; idx < MAX_MAPPINGS; idx++) { if (data->map_base[idx]) diff --git a/drivers/irqchip/irq-brcmstb-l2.c b/drivers/irqchip/irq-brcmstb-l2.c index d6bcc6be0777..aedda06191eb 100644 --- a/drivers/irqchip/irq-brcmstb-l2.c +++ b/drivers/irqchip/irq-brcmstb-l2.c @@ -32,8 +32,6 @@ #include <linux/irqchip.h> #include <linux/irqchip/chained_irq.h> -#include "irqchip.h" - /* Register offsets in the L2 interrupt controller */ #define CPU_STATUS 0x00 #define CPU_SET 0x04 @@ -51,11 +49,13 @@ struct brcmstb_l2_intc_data { u32 saved_mask; /* for suspend/resume */ }; -static void brcmstb_l2_intc_irq_handle(unsigned int irq, struct irq_desc *desc) +static void brcmstb_l2_intc_irq_handle(unsigned int __irq, + struct irq_desc *desc) { struct brcmstb_l2_intc_data *b = irq_desc_get_handler_data(desc); struct irq_chip_generic *gc = irq_get_domain_generic_chip(b->domain, 0); struct irq_chip *chip = irq_desc_get_chip(desc); + unsigned int irq = irq_desc_get_irq(desc); u32 status; chained_irq_enter(chip, desc); @@ -172,8 +172,8 @@ int __init brcmstb_l2_intc_of_init(struct device_node *np, } /* Set the IRQ chaining logic */ - irq_set_handler_data(data->parent_irq, data); - irq_set_chained_handler(data->parent_irq, brcmstb_l2_intc_irq_handle); + irq_set_chained_handler_and_data(data->parent_irq, + brcmstb_l2_intc_irq_handle, data); gc = irq_get_domain_generic_chip(data->domain, 0); gc->reg_base = data->base; diff --git a/drivers/irqchip/irq-clps711x.c b/drivers/irqchip/irq-clps711x.c index 33127f131d78..2dd929eed9e0 100644 --- a/drivers/irqchip/irq-clps711x.c +++ b/drivers/irqchip/irq-clps711x.c @@ -11,6 +11,7 @@ #include <linux/io.h> #include <linux/irq.h> +#include <linux/irqchip.h> #include <linux/irqdomain.h> #include <linux/of_address.h> #include <linux/of_irq.h> @@ -19,8 +20,6 @@ #include <asm/exception.h> #include <asm/mach/irq.h> -#include "irqchip.h" - #define CLPS711X_INTSR1 (0x0240) #define CLPS711X_INTMR1 (0x0280) #define CLPS711X_BLEOI (0x0600) diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c index 692fe2bc8197..1240c4deda75 100644 --- a/drivers/irqchip/irq-crossbar.c +++ b/drivers/irqchip/irq-crossbar.c @@ -11,13 +11,12 @@ */ #include <linux/err.h> #include <linux/io.h> +#include <linux/irqchip.h> #include <linux/irqdomain.h> #include <linux/of_address.h> #include <linux/of_irq.h> #include <linux/slab.h> -#include "irqchip.h" - #define IRQ_FREE -1 #define IRQ_RESERVED -2 #define IRQ_SKIP -3 diff --git a/drivers/irqchip/irq-digicolor.c b/drivers/irqchip/irq-digicolor.c index 3cbc658afe27..dad85e74c37c 100644 --- a/drivers/irqchip/irq-digicolor.c +++ b/drivers/irqchip/irq-digicolor.c @@ -12,6 +12,7 @@ #include <linux/io.h> #include <linux/irq.h> +#include <linux/irqchip.h> #include <linux/of.h> #include <linux/of_address.h> #include <linux/of_irq.h> @@ -20,8 +21,6 @@ #include <asm/exception.h> -#include "irqchip.h" - #define UC_IRQ_CONTROL 0x04 #define IC_FLAG_CLEAR_LO 0x00 diff --git a/drivers/irqchip/irq-dw-apb-ictl.c b/drivers/irqchip/irq-dw-apb-ictl.c index 53bb7326a60a..efd95d9955e7 100644 --- a/drivers/irqchip/irq-dw-apb-ictl.c +++ b/drivers/irqchip/irq-dw-apb-ictl.c @@ -13,36 +13,36 @@ #include <linux/io.h> #include <linux/irq.h> +#include <linux/irqchip.h> #include <linux/irqchip/chained_irq.h> #include <linux/of_address.h> #include <linux/of_irq.h> -#include "irqchip.h" - #define APB_INT_ENABLE_L 0x00 #define APB_INT_ENABLE_H 0x04 #define APB_INT_MASK_L 0x08 #define APB_INT_MASK_H 0x0c #define APB_INT_FINALSTATUS_L 0x30 #define APB_INT_FINALSTATUS_H 0x34 +#define APB_INT_BASE_OFFSET 0x04 static void dw_apb_ictl_handler(unsigned int irq, struct irq_desc *desc) { - struct irq_chip *chip = irq_get_chip(irq); - struct irq_chip_generic *gc = irq_get_handler_data(irq); - struct irq_domain *d = gc->private; - u32 stat; + struct irq_domain *d = irq_desc_get_handler_data(desc); + struct irq_chip *chip = irq_desc_get_chip(desc); int n; chained_irq_enter(chip, desc); - for (n = 0; n < gc->num_ct; n++) { - stat = readl_relaxed(gc->reg_base + - APB_INT_FINALSTATUS_L + 4 * n); + for (n = 0; n < d->revmap_size; n += 32) { + struct irq_chip_generic *gc = irq_get_domain_generic_chip(d, n); + u32 stat = readl_relaxed(gc->reg_base + APB_INT_FINALSTATUS_L); + while (stat) { u32 hwirq = ffs(stat) - 1; - generic_handle_irq(irq_find_mapping(d, - gc->irq_base + hwirq + 32 * n)); + u32 virq = irq_find_mapping(d, gc->irq_base + hwirq); + + generic_handle_irq(virq); stat &= ~(1 << hwirq); } } @@ -73,7 +73,7 @@ static int __init dw_apb_ictl_init(struct device_node *np, struct irq_domain *domain; struct irq_chip_generic *gc; void __iomem *iobase; - int ret, nrirqs, irq; + int ret, nrirqs, irq, i; u32 reg; /* Map the parent interrupt for the chained handler */ @@ -128,35 +128,25 @@ static int __init dw_apb_ictl_init(struct device_node *np, goto err_unmap; } - ret = irq_alloc_domain_generic_chips(domain, 32, (nrirqs > 32) ? 2 : 1, - np->name, handle_level_irq, clr, 0, - IRQ_GC_MASK_CACHE_PER_TYPE | + ret = irq_alloc_domain_generic_chips(domain, 32, 1, np->name, + handle_level_irq, clr, 0, IRQ_GC_INIT_MASK_CACHE); if (ret) { pr_err("%s: unable to alloc irq domain gc\n", np->full_name); goto err_unmap; } - gc = irq_get_domain_generic_chip(domain, 0); - gc->private = domain; - gc->reg_base = iobase; - - gc->chip_types[0].regs.mask = APB_INT_MASK_L; - gc->chip_types[0].regs.enable = APB_INT_ENABLE_L; - gc->chip_types[0].chip.irq_mask = irq_gc_mask_set_bit; - gc->chip_types[0].chip.irq_unmask = irq_gc_mask_clr_bit; - gc->chip_types[0].chip.irq_resume = dw_apb_ictl_resume; - - if (nrirqs > 32) { - gc->chip_types[1].regs.mask = APB_INT_MASK_H; - gc->chip_types[1].regs.enable = APB_INT_ENABLE_H; - gc->chip_types[1].chip.irq_mask = irq_gc_mask_set_bit; - gc->chip_types[1].chip.irq_unmask = irq_gc_mask_clr_bit; - gc->chip_types[1].chip.irq_resume = dw_apb_ictl_resume; + for (i = 0; i < DIV_ROUND_UP(nrirqs, 32); i++) { + gc = irq_get_domain_generic_chip(domain, i * 32); + gc->reg_base = iobase + i * APB_INT_BASE_OFFSET; + gc->chip_types[0].regs.mask = APB_INT_MASK_L; + gc->chip_types[0].regs.enable = APB_INT_ENABLE_L; + gc->chip_types[0].chip.irq_mask = irq_gc_mask_set_bit; + gc->chip_types[0].chip.irq_unmask = irq_gc_mask_clr_bit; + gc->chip_types[0].chip.irq_resume = dw_apb_ictl_resume; } - irq_set_handler_data(irq, gc); - irq_set_chained_handler(irq, dw_apb_ictl_handler); + irq_set_chained_handler_and_data(irq, dw_apb_ictl_handler, domain); return 0; diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index c00e2db351ba..1df956afb937 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -30,14 +30,13 @@ #include <linux/percpu.h> #include <linux/slab.h> +#include <linux/irqchip.h> #include <linux/irqchip/arm-gic-v3.h> #include <asm/cacheflush.h> #include <asm/cputype.h> #include <asm/exception.h> -#include "irqchip.h" - #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING (1 << 0) #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0) diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index c52f7ba205b4..e406bc5f13e4 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -25,6 +25,7 @@ #include <linux/percpu.h> #include <linux/slab.h> +#include <linux/irqchip.h> #include <linux/irqchip/arm-gic-v3.h> #include <asm/cputype.h> @@ -32,7 +33,6 @@ #include <asm/smp_plat.h> #include "irq-gic-common.h" -#include "irqchip.h" struct redist_region { void __iomem *redist_base; diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 4dd88264dff5..29c544d0aaa9 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -38,6 +38,7 @@ #include <linux/interrupt.h> #include <linux/percpu.h> #include <linux/slab.h> +#include <linux/irqchip.h> #include <linux/irqchip/chained_irq.h> #include <linux/irqchip/arm-gic.h> #include <linux/irqchip/arm-gic-acpi.h> @@ -48,7 +49,6 @@ #include <asm/smp_plat.h> #include "irq-gic-common.h" -#include "irqchip.h" union gic_base { void __iomem *common_base; @@ -288,8 +288,8 @@ static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) { - struct gic_chip_data *chip_data = irq_get_handler_data(irq); - struct irq_chip *chip = irq_get_chip(irq); + struct gic_chip_data *chip_data = irq_desc_get_handler_data(desc); + struct irq_chip *chip = irq_desc_get_chip(desc); unsigned int cascade_irq, gic_irq; unsigned long status; @@ -324,16 +324,17 @@ static struct irq_chip gic_chip = { #endif .irq_get_irqchip_state = gic_irq_get_irqchip_state, .irq_set_irqchip_state = gic_irq_set_irqchip_state, - .flags = IRQCHIP_SET_TYPE_MASKED, + .flags = IRQCHIP_SET_TYPE_MASKED | + IRQCHIP_SKIP_SET_WAKE | + IRQCHIP_MASK_ON_SUSPEND, }; void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq) { if (gic_nr >= MAX_GIC_NR) BUG(); - if (irq_set_handler_data(irq, &gic_data[gic_nr]) != 0) - BUG(); - irq_set_chained_handler(irq, gic_handle_cascade_irq); + irq_set_chained_handler_and_data(irq, gic_handle_cascade_irq, + &gic_data[gic_nr]); } static u8 gic_get_cpumask(struct gic_chip_data *gic) @@ -880,11 +881,6 @@ static const struct irq_domain_ops gic_irq_domain_ops = { .xlate = gic_irq_domain_xlate, }; -void gic_set_irqchip_flags(unsigned long flags) -{ - gic_chip.flags |= flags; -} - void __init gic_init_bases(unsigned int gic_nr, int irq_start, void __iomem *dist_base, void __iomem *cpu_base, u32 percpu_offset, struct device_node *node) diff --git a/drivers/irqchip/irq-hip04.c b/drivers/irqchip/irq-hip04.c index 0cae45d10695..a0128c7c98dd 100644 --- a/drivers/irqchip/irq-hip04.c +++ b/drivers/irqchip/irq-hip04.c @@ -41,6 +41,7 @@ #include <linux/irqdomain.h> #include <linux/interrupt.h> #include <linux/slab.h> +#include <linux/irqchip.h> #include <linux/irqchip/arm-gic.h> #include <asm/irq.h> @@ -48,7 +49,6 @@ #include <asm/smp_plat.h> #include "irq-gic-common.h" -#include "irqchip.h" #define HIP04_MAX_IRQS 510 @@ -202,7 +202,9 @@ static struct irq_chip hip04_irq_chip = { #ifdef CONFIG_SMP .irq_set_affinity = hip04_irq_set_affinity, #endif - .flags = IRQCHIP_SET_TYPE_MASKED, + .flags = IRQCHIP_SET_TYPE_MASKED | + IRQCHIP_SKIP_SET_WAKE | + IRQCHIP_MASK_ON_SUSPEND, }; static u16 hip04_get_cpumask(struct hip04_irq_data *intc) diff --git a/drivers/irqchip/irq-imgpdc.c b/drivers/irqchip/irq-imgpdc.c index 8071c2eb0248..841604b81004 100644 --- a/drivers/irqchip/irq-imgpdc.c +++ b/drivers/irqchip/irq-imgpdc.c @@ -218,8 +218,9 @@ static int pdc_irq_set_wake(struct irq_data *data, unsigned int on) return 0; } -static void pdc_intc_perip_isr(unsigned int irq, struct irq_desc *desc) +static void pdc_intc_perip_isr(unsigned int __irq, struct irq_desc *desc) { + unsigned int irq = irq_desc_get_irq(desc); struct pdc_intc_priv *priv; unsigned int i, irq_no; @@ -451,13 +452,13 @@ static int pdc_intc_probe(struct platform_device *pdev) /* Setup chained handlers for the peripheral IRQs */ for (i = 0; i < priv->nr_perips; ++i) { irq = priv->perip_irqs[i]; - irq_set_handler_data(irq, priv); - irq_set_chained_handler(irq, pdc_intc_perip_isr); + irq_set_chained_handler_and_data(irq, pdc_intc_perip_isr, + priv); } /* Setup chained handler for the syswake IRQ */ - irq_set_handler_data(priv->syswake_irq, priv); - irq_set_chained_handler(priv->syswake_irq, pdc_intc_syswake_isr); + irq_set_chained_handler_and_data(priv->syswake_irq, + pdc_intc_syswake_isr, priv); dev_info(&pdev->dev, "PDC IRQ controller initialised (%u perip IRQs, %u syswake IRQs)\n", diff --git a/drivers/irqchip/irq-ingenic.c b/drivers/irqchip/irq-ingenic.c index 005de3f932ae..fc5953dea509 100644 --- a/drivers/irqchip/irq-ingenic.c +++ b/drivers/irqchip/irq-ingenic.c @@ -18,6 +18,7 @@ #include <linux/types.h> #include <linux/interrupt.h> #include <linux/ioport.h> +#include <linux/irqchip.h> #include <linux/irqchip/ingenic.h> #include <linux/of_address.h> #include <linux/of_irq.h> @@ -28,8 +29,6 @@ #include <asm/io.h> #include <asm/mach-jz4740/irq.h> -#include "irqchip.h" - struct ingenic_intc_data { void __iomem *base; unsigned num_chips; diff --git a/drivers/irqchip/irq-keystone.c b/drivers/irqchip/irq-keystone.c index 81e3cf5b9a1f..c1517267b5db 100644 --- a/drivers/irqchip/irq-keystone.c +++ b/drivers/irqchip/irq-keystone.c @@ -20,13 +20,12 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/irqdomain.h> +#include <linux/irqchip.h> #include <linux/irqchip/chained_irq.h> #include <linux/of.h> #include <linux/of_platform.h> #include <linux/mfd/syscon.h> #include <linux/regmap.h> -#include "irqchip.h" - /* The source ID bits start from 4 to 31 (total 28 bits)*/ #define BIT_OFS 4 @@ -84,8 +83,9 @@ static void keystone_irq_ack(struct irq_data *d) /* nothing to do here */ } -static void keystone_irq_handler(unsigned irq, struct irq_desc *desc) +static void keystone_irq_handler(unsigned __irq, struct irq_desc *desc) { + unsigned int irq = irq_desc_get_irq(desc); struct keystone_irq_device *kirq = irq_desc_get_handler_data(desc); unsigned long pending; int src, virq; diff --git a/drivers/irqchip/irq-metag-ext.c b/drivers/irqchip/irq-metag-ext.c index 2cb474ad8809..5f4c52928d16 100644 --- a/drivers/irqchip/irq-metag-ext.c +++ b/drivers/irqchip/irq-metag-ext.c @@ -404,7 +404,6 @@ static int meta_intc_irq_set_type(struct irq_data *data, unsigned int flow_type) #ifdef CONFIG_METAG_SUSPEND_MEM struct meta_intc_priv *priv = &meta_intc_priv; #endif - unsigned int irq = data->irq; irq_hw_number_t hw = data->hwirq; unsigned int bit = 1 << meta_intc_offset(hw); void __iomem *level_addr = meta_intc_level_addr(hw); @@ -413,11 +412,11 @@ static int meta_intc_irq_set_type(struct irq_data *data, unsigned int flow_type) /* update the chip/handler */ if (flow_type & IRQ_TYPE_LEVEL_MASK) - __irq_set_chip_handler_name_locked(irq, &meta_intc_level_chip, - handle_level_irq, NULL); + irq_set_chip_handler_name_locked(data, &meta_intc_level_chip, + handle_level_irq, NULL); else - __irq_set_chip_handler_name_locked(irq, &meta_intc_edge_chip, - handle_edge_irq, NULL); + irq_set_chip_handler_name_locked(data, &meta_intc_edge_chip, + handle_edge_irq, NULL); /* and clear/set the bit in HWLEVELEXT */ __global_lock2(flags); diff --git a/drivers/irqchip/irq-metag.c b/drivers/irqchip/irq-metag.c index c16c186d97d3..3d23ce3edb5c 100644 --- a/drivers/irqchip/irq-metag.c +++ b/drivers/irqchip/irq-metag.c @@ -286,8 +286,7 @@ static void metag_internal_irq_init_cpu(struct metag_internal_irq_priv *priv, int irq = tbisig_map(signum); /* Register the multiplexed IRQ handler */ - irq_set_handler_data(irq, priv); - irq_set_chained_handler(irq, metag_internal_irq_demux); + irq_set_chained_handler_and_data(irq, metag_internal_irq_demux, priv); irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW); } diff --git a/drivers/irqchip/irq-mips-cpu.c b/drivers/irqchip/irq-mips-cpu.c index a43c41988009..8c504f562e9d 100644 --- a/drivers/irqchip/irq-mips-cpu.c +++ b/drivers/irqchip/irq-mips-cpu.c @@ -31,6 +31,7 @@ #include <linux/interrupt.h> #include <linux/kernel.h> #include <linux/irq.h> +#include <linux/irqchip.h> #include <linux/irqdomain.h> #include <asm/irq_cpu.h> @@ -38,8 +39,6 @@ #include <asm/mipsmtregs.h> #include <asm/setup.h> -#include "irqchip.h" - static inline void unmask_mips_irq(struct irq_data *d) { set_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE)); diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index b7d54d428b5e..2d36eca76bef 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -11,6 +11,7 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/irq.h> +#include <linux/irqchip.h> #include <linux/irqchip/mips-gic.h> #include <linux/of_address.h> #include <linux/sched.h> @@ -22,8 +23,6 @@ #include <dt-bindings/interrupt-controller/mips-gic.h> -#include "irqchip.h" - unsigned int gic_present; struct gic_pcpu_mask { @@ -358,15 +357,12 @@ static int gic_set_type(struct irq_data *d, unsigned int type) break; } - if (is_edge) { - __irq_set_chip_handler_name_locked(d->irq, - &gic_edge_irq_controller, - handle_edge_irq, NULL); - } else { - __irq_set_chip_handler_name_locked(d->irq, - &gic_level_irq_controller, - handle_level_irq, NULL); - } + if (is_edge) + irq_set_chip_handler_name_locked(d, &gic_edge_irq_controller, + handle_edge_irq, NULL); + else + irq_set_chip_handler_name_locked(d, &gic_level_irq_controller, + handle_level_irq, NULL); spin_unlock_irqrestore(&gic_lock, flags); return 0; @@ -396,7 +392,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask, clear_bit(irq, pcpu_masks[i].pcpu_mask); set_bit(irq, pcpu_masks[cpumask_first(&tmp)].pcpu_mask); - cpumask_copy(d->affinity, cpumask); + cpumask_copy(irq_data_get_affinity_mask(d), cpumask); spin_unlock_irqrestore(&gic_lock, flags); return IRQ_SET_MASK_OK_NOCOPY; diff --git a/drivers/irqchip/irq-mmp.c b/drivers/irqchip/irq-mmp.c index c0da57bdb89d..781ed6e71dbb 100644 --- a/drivers/irqchip/irq-mmp.c +++ b/drivers/irqchip/irq-mmp.c @@ -15,6 +15,7 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/irq.h> +#include <linux/irqchip.h> #include <linux/irqdomain.h> #include <linux/io.h> #include <linux/ioport.h> @@ -24,8 +25,6 @@ #include <asm/exception.h> #include <asm/hardirq.h> -#include "irqchip.h" - #define MAX_ICU_NR 16 #define PJ1_INT_SEL 0x10c @@ -130,8 +129,9 @@ struct irq_chip icu_irq_chip = { .irq_unmask = icu_unmask_irq, }; -static void icu_mux_irq_demux(unsigned int irq, struct irq_desc *desc) +static void icu_mux_irq_demux(unsigned int __irq, struct irq_desc *desc) { + unsigned int irq = irq_desc_get_irq(desc); struct irq_domain *domain; struct icu_chip_data *data; int i; diff --git a/drivers/irqchip/irq-moxart.c b/drivers/irqchip/irq-moxart.c index 00b3cc908f76..a24b06a1718b 100644 --- a/drivers/irqchip/irq-moxart.c +++ b/drivers/irqchip/irq-moxart.c @@ -12,6 +12,7 @@ #include <linux/io.h> #include <linux/irq.h> +#include <linux/irqchip.h> #include <linux/of.h> #include <linux/of_address.h> #include <linux/of_irq.h> @@ -19,8 +20,6 @@ #include <asm/exception.h> -#include "irqchip.h" - #define IRQ_SOURCE_REG 0 #define IRQ_MASK_REG 0x04 #define IRQ_CLEAR_REG 0x08 diff --git a/drivers/irqchip/irq-mtk-sysirq.c b/drivers/irqchip/irq-mtk-sysirq.c index 15c13039bba2..c8753da4c156 100644 --- a/drivers/irqchip/irq-mtk-sysirq.c +++ b/drivers/irqchip/irq-mtk-sysirq.c @@ -13,6 +13,7 @@ */ #include <linux/irq.h> +#include <linux/irqchip.h> #include <linux/irqdomain.h> #include <linux/of.h> #include <linux/of_irq.h> @@ -21,8 +22,6 @@ #include <linux/slab.h> #include <linux/spinlock.h> -#include "irqchip.h" - struct mtk_sysirq_chip_data { spinlock_t lock; void __iomem *intpol_base; diff --git a/drivers/irqchip/irq-mxs.c b/drivers/irqchip/irq-mxs.c index 04bf97b289cf..1faf812f3dc8 100644 --- a/drivers/irqchip/irq-mxs.c +++ b/drivers/irqchip/irq-mxs.c @@ -19,6 +19,7 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/irq.h> +#include <linux/irqchip.h> #include <linux/irqdomain.h> #include <linux/io.h> #include <linux/of.h> @@ -27,8 +28,6 @@ #include <linux/stmp_device.h> #include <asm/exception.h> -#include "irqchip.h" - #define HW_ICOLL_VECTOR 0x0000 #define HW_ICOLL_LEVELACK 0x0010 #define HW_ICOLL_CTRL 0x0020 diff --git a/drivers/irqchip/irq-nvic.c b/drivers/irqchip/irq-nvic.c index 5fac9100f6cb..a878b8d03868 100644 --- a/drivers/irqchip/irq-nvic.c +++ b/drivers/irqchip/irq-nvic.c @@ -21,13 +21,12 @@ #include <linux/of.h> #include <linux/of_address.h> #include <linux/irq.h> +#include <linux/irqchip.h> #include <linux/irqdomain.h> #include <asm/v7m.h> #include <asm/exception.h> -#include "irqchip.h" - #define NVIC_ISER 0x000 #define NVIC_ICER 0x080 #define NVIC_IPR 0x300 diff --git a/drivers/irqchip/irq-omap-intc.c b/drivers/irqchip/irq-omap-intc.c index a569c6dbd1d1..8587d0f8d8c0 100644 --- a/drivers/irqchip/irq-omap-intc.c +++ b/drivers/irqchip/irq-omap-intc.c @@ -17,13 +17,12 @@ #include <linux/io.h> #include <asm/exception.h> +#include <linux/irqchip.h> #include <linux/irqdomain.h> #include <linux/of.h> #include <linux/of_address.h> #include <linux/of_irq.h> -#include "irqchip.h" - /* Define these here for now until we drop all board-files */ #define OMAP24XX_IC_BASE 0x480fe000 #define OMAP34XX_IC_BASE 0x48200000 @@ -331,37 +330,12 @@ static int __init omap_init_irq(u32 base, struct device_node *node) static asmlinkage void __exception_irq_entry omap_intc_handle_irq(struct pt_regs *regs) { - u32 irqnr = 0; - int handled_irq = 0; - int i; - - do { - for (i = 0; i < omap_nr_pending; i++) { - irqnr = intc_readl(INTC_PENDING_IRQ0 + (0x20 * i)); - if (irqnr) - goto out; - } - -out: - if (!irqnr) - break; + u32 irqnr; - irqnr = intc_readl(INTC_SIR); - irqnr &= ACTIVEIRQ_MASK; - - if (irqnr) { - handle_domain_irq(domain, irqnr, regs); - handled_irq = 1; - } - } while (irqnr); - - /* - * If an irq is masked or deasserted while active, we will - * keep ending up here with no irq handled. So remove it from - * the INTC with an ack. - */ - if (!handled_irq) - omap_ack_irq(NULL); + irqnr = intc_readl(INTC_SIR); + irqnr &= ACTIVEIRQ_MASK; + WARN_ONCE(!irqnr, "Spurious IRQ ?\n"); + handle_domain_irq(domain, irqnr, regs); } void __init omap3_init_irq(void) diff --git a/drivers/irqchip/irq-or1k-pic.c b/drivers/irqchip/irq-or1k-pic.c index e93d079fe069..6a9a3e79218b 100644 --- a/drivers/irqchip/irq-or1k-pic.c +++ b/drivers/irqchip/irq-or1k-pic.c @@ -9,12 +9,11 @@ */ #include <linux/irq.h> +#include <linux/irqchip.h> #include <linux/of.h> #include <linux/of_irq.h> #include <linux/of_address.h> -#include "irqchip.h" - /* OR1K PIC implementation */ struct or1k_pic_dev { diff --git a/drivers/irqchip/irq-orion.c b/drivers/irqchip/irq-orion.c index ad0c0f6f1d65..5ea999a724b5 100644 --- a/drivers/irqchip/irq-orion.c +++ b/drivers/irqchip/irq-orion.c @@ -10,14 +10,13 @@ #include <linux/io.h> #include <linux/irq.h> +#include <linux/irqchip.h> #include <linux/of.h> #include <linux/of_address.h> #include <linux/of_irq.h> #include <asm/exception.h> #include <asm/mach/irq.h> -#include "irqchip.h" - /* * Orion SoC main interrupt controller */ @@ -109,7 +108,7 @@ IRQCHIP_DECLARE(orion_intc, "marvell,orion-intc", orion_irq_init); static void orion_bridge_irq_handler(unsigned int irq, struct irq_desc *desc) { - struct irq_domain *d = irq_get_handler_data(irq); + struct irq_domain *d = irq_desc_get_handler_data(desc); struct irq_chip_generic *gc = irq_get_domain_generic_chip(d, 0); u32 stat = readl_relaxed(gc->reg_base + ORION_BRIDGE_IRQ_CAUSE) & @@ -198,8 +197,8 @@ static int __init orion_bridge_irq_init(struct device_node *np, writel(0, gc->reg_base + ORION_BRIDGE_IRQ_MASK); writel(0, gc->reg_base + ORION_BRIDGE_IRQ_CAUSE); - irq_set_handler_data(irq, domain); - irq_set_chained_handler(irq, orion_bridge_irq_handler); + irq_set_chained_handler_and_data(irq, orion_bridge_irq_handler, + domain); return 0; } diff --git a/drivers/irqchip/irq-renesas-h8300h.c b/drivers/irqchip/irq-renesas-h8300h.c index 1870e6bd3dd9..6fd30d5ee14d 100644 --- a/drivers/irqchip/irq-renesas-h8300h.c +++ b/drivers/irqchip/irq-renesas-h8300h.c @@ -11,8 +11,6 @@ #include <linux/of_irq.h> #include <asm/io.h> -#include "irqchip.h" - static const char ipr_bit[] = { 7, 6, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3, diff --git a/drivers/irqchip/irq-renesas-h8s.c b/drivers/irqchip/irq-renesas-h8s.c index 64425f4de7d9..8098ead1eb22 100644 --- a/drivers/irqchip/irq-renesas-h8s.c +++ b/drivers/irqchip/irq-renesas-h8s.c @@ -5,10 +5,10 @@ */ #include <linux/irq.h> +#include <linux/irqchip.h> #include <linux/of_address.h> #include <linux/of_irq.h> #include <asm/io.h> -#include "irqchip.h" static void *intc_baseaddr; #define IPRA ((unsigned long)intc_baseaddr) diff --git a/drivers/irqchip/irq-renesas-irqc.c b/drivers/irqchip/irq-renesas-irqc.c index 778bd076aeea..2aa3add711a6 100644 --- a/drivers/irqchip/irq-renesas-irqc.c +++ b/drivers/irqchip/irq-renesas-irqc.c @@ -53,7 +53,6 @@ struct irqc_irq { int hw_irq; int requested_irq; - int domain_irq; struct irqc_priv *p; }; @@ -70,8 +69,8 @@ struct irqc_priv { static void irqc_dbg(struct irqc_irq *i, char *str) { - dev_dbg(&i->p->pdev->dev, "%s (%d:%d:%d)\n", - str, i->requested_irq, i->hw_irq, i->domain_irq); + dev_dbg(&i->p->pdev->dev, "%s (%d:%d)\n", + str, i->requested_irq, i->hw_irq); } static void irqc_irq_enable(struct irq_data *d) @@ -145,7 +144,7 @@ static irqreturn_t irqc_irq_handler(int irq, void *dev_id) if (ioread32(p->iomem + DETECT_STATUS) & bit) { iowrite32(bit, p->iomem + DETECT_STATUS); irqc_dbg(i, "demux2"); - generic_handle_irq(i->domain_irq); + generic_handle_irq(irq_find_mapping(p->irq_domain, i->hw_irq)); return IRQ_HANDLED; } return IRQ_NONE; @@ -156,13 +155,9 @@ static int irqc_irq_domain_map(struct irq_domain *h, unsigned int virq, { struct irqc_priv *p = h->host_data; - p->irq[hw].domain_irq = virq; - p->irq[hw].hw_irq = hw; - irqc_dbg(&p->irq[hw], "map"); irq_set_chip_data(virq, h->host_data); irq_set_chip_and_handler(virq, &p->irq_chip, handle_level_irq); - set_irq_flags(virq, IRQF_VALID); /* kill me now */ return 0; } @@ -215,6 +210,7 @@ static int irqc_probe(struct platform_device *pdev) break; p->irq[k].p = p; + p->irq[k].hw_irq = k; p->irq[k].requested_irq = irq->start; } @@ -243,8 +239,8 @@ static int irqc_probe(struct platform_device *pdev) irq_chip->irq_set_wake = irqc_irq_set_wake; irq_chip->flags = IRQCHIP_MASK_ON_SUSPEND; - p->irq_domain = irq_domain_add_simple(pdev->dev.of_node, - p->number_of_irqs, 0, + p->irq_domain = irq_domain_add_linear(pdev->dev.of_node, + p->number_of_irqs, &irqc_irq_domain_ops, p); if (!p->irq_domain) { ret = -ENXIO; diff --git a/drivers/irqchip/irq-s3c24xx.c b/drivers/irqchip/irq-s3c24xx.c index e96717f45ea1..506d9f20ca51 100644 --- a/drivers/irqchip/irq-s3c24xx.c +++ b/drivers/irqchip/irq-s3c24xx.c @@ -25,6 +25,7 @@ #include <linux/ioport.h> #include <linux/device.h> #include <linux/irqdomain.h> +#include <linux/irqchip.h> #include <linux/irqchip/chained_irq.h> #include <linux/of.h> #include <linux/of_irq.h> @@ -40,8 +41,6 @@ #include <plat/regs-irqtype.h> #include <plat/pm.h> -#include "irqchip.h" - #define S3C_IRQTYPE_NONE 0 #define S3C_IRQTYPE_EINT 1 #define S3C_IRQTYPE_EDGE 2 @@ -299,16 +298,14 @@ static struct irq_chip s3c_irq_eint0t4 = { .irq_set_type = s3c_irqext0_type, }; -static void s3c_irq_demux(unsigned int irq, struct irq_desc *desc) +static void s3c_irq_demux(unsigned int __irq, struct irq_desc *desc) { struct irq_chip *chip = irq_desc_get_chip(desc); struct s3c_irq_data *irq_data = irq_desc_get_chip_data(desc); struct s3c_irq_intc *intc = irq_data->intc; struct s3c_irq_intc *sub_intc = irq_data->sub_intc; - unsigned long src; - unsigned long msk; - unsigned int n; - unsigned int offset; + unsigned int n, offset, irq; + unsigned long src, msk; /* we're using individual domains for the non-dt case * and one big domain for the dt case where the subintc diff --git a/drivers/irqchip/irq-sirfsoc.c b/drivers/irqchip/irq-sirfsoc.c index a469355df352..10cb21b9ba3d 100644 --- a/drivers/irqchip/irq-sirfsoc.c +++ b/drivers/irqchip/irq-sirfsoc.c @@ -11,40 +11,44 @@ #include <linux/irq.h> #include <linux/of.h> #include <linux/of_address.h> +#include <linux/irqchip.h> #include <linux/irqdomain.h> #include <linux/syscore_ops.h> #include <asm/mach/irq.h> #include <asm/exception.h> -#include "irqchip.h" -#define SIRFSOC_INT_RISC_MASK0 0x0018 -#define SIRFSOC_INT_RISC_MASK1 0x001C -#define SIRFSOC_INT_RISC_LEVEL0 0x0020 -#define SIRFSOC_INT_RISC_LEVEL1 0x0024 +#define SIRFSOC_INT_RISC_MASK0 0x0018 +#define SIRFSOC_INT_RISC_MASK1 0x001C +#define SIRFSOC_INT_RISC_LEVEL0 0x0020 +#define SIRFSOC_INT_RISC_LEVEL1 0x0024 #define SIRFSOC_INIT_IRQ_ID 0x0038 +#define SIRFSOC_INT_BASE_OFFSET 0x0004 #define SIRFSOC_NUM_IRQS 64 +#define SIRFSOC_NUM_BANKS (SIRFSOC_NUM_IRQS / 32) static struct irq_domain *sirfsoc_irqdomain; -static __init void -sirfsoc_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num) +static __init void sirfsoc_alloc_gc(void __iomem *base) { - struct irq_chip_generic *gc; - struct irq_chip_type *ct; - int ret; unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; unsigned int set = IRQ_LEVEL; - - ret = irq_alloc_domain_generic_chips(sirfsoc_irqdomain, num, 1, "irq_sirfsoc", - handle_level_irq, clr, set, IRQ_GC_INIT_MASK_CACHE); - - gc = irq_get_domain_generic_chip(sirfsoc_irqdomain, irq_start); - gc->reg_base = base; - ct = gc->chip_types; - ct->chip.irq_mask = irq_gc_mask_clr_bit; - ct->chip.irq_unmask = irq_gc_mask_set_bit; - ct->regs.mask = SIRFSOC_INT_RISC_MASK0; + struct irq_chip_generic *gc; + struct irq_chip_type *ct; + int i; + + irq_alloc_domain_generic_chips(sirfsoc_irqdomain, 32, 1, "irq_sirfsoc", + handle_level_irq, clr, set, + IRQ_GC_INIT_MASK_CACHE); + + for (i = 0; i < SIRFSOC_NUM_BANKS; i++) { + gc = irq_get_domain_generic_chip(sirfsoc_irqdomain, i * 32); + gc->reg_base = base + i * SIRFSOC_INT_BASE_OFFSET; + ct = gc->chip_types; + ct->chip.irq_mask = irq_gc_mask_clr_bit; + ct->chip.irq_unmask = irq_gc_mask_set_bit; + ct->regs.mask = SIRFSOC_INT_RISC_MASK0; + } } static void __exception_irq_entry sirfsoc_handle_irq(struct pt_regs *regs) @@ -64,10 +68,8 @@ static int __init sirfsoc_irq_init(struct device_node *np, panic("unable to map intc cpu registers\n"); sirfsoc_irqdomain = irq_domain_add_linear(np, SIRFSOC_NUM_IRQS, - &irq_generic_chip_ops, base); - - sirfsoc_alloc_gc(base, 0, 32); - sirfsoc_alloc_gc(base + 4, 32, SIRFSOC_NUM_IRQS - 32); + &irq_generic_chip_ops, base); + sirfsoc_alloc_gc(base); writel_relaxed(0, base + SIRFSOC_INT_RISC_LEVEL0); writel_relaxed(0, base + SIRFSOC_INT_RISC_LEVEL1); diff --git a/drivers/irqchip/irq-sun4i.c b/drivers/irqchip/irq-sun4i.c index 83d6aa6464ee..4ad3e7c69aa7 100644 --- a/drivers/irqchip/irq-sun4i.c +++ b/drivers/irqchip/irq-sun4i.c @@ -16,6 +16,7 @@ #include <linux/io.h> #include <linux/irq.h> +#include <linux/irqchip.h> #include <linux/of.h> #include <linux/of_address.h> #include <linux/of_irq.h> @@ -23,8 +24,6 @@ #include <asm/exception.h> #include <asm/mach/irq.h> -#include "irqchip.h" - #define SUN4I_IRQ_VECTOR_REG 0x00 #define SUN4I_IRQ_PROTECTION_REG 0x08 #define SUN4I_IRQ_NMI_CTRL_REG 0x0c diff --git a/drivers/irqchip/irq-sunxi-nmi.c b/drivers/irqchip/irq-sunxi-nmi.c index 6b2b582433bd..772a82cacbf7 100644 --- a/drivers/irqchip/irq-sunxi-nmi.c +++ b/drivers/irqchip/irq-sunxi-nmi.c @@ -17,8 +17,8 @@ #include <linux/of_irq.h> #include <linux/of_address.h> #include <linux/of_platform.h> +#include <linux/irqchip.h> #include <linux/irqchip/chained_irq.h> -#include "irqchip.h" #define SUNXI_NMI_SRC_TYPE_MASK 0x00000003 @@ -61,7 +61,7 @@ static inline u32 sunxi_sc_nmi_read(struct irq_chip_generic *gc, u32 off) static void sunxi_sc_nmi_handle_irq(unsigned int irq, struct irq_desc *desc) { struct irq_domain *domain = irq_desc_get_handler_data(desc); - struct irq_chip *chip = irq_get_chip(irq); + struct irq_chip *chip = irq_desc_get_chip(desc); unsigned int virq = irq_find_mapping(domain, 0); chained_irq_enter(chip, desc); @@ -182,8 +182,7 @@ static int __init sunxi_sc_nmi_irq_init(struct device_node *node, sunxi_sc_nmi_write(gc, reg_offs->enable, 0); sunxi_sc_nmi_write(gc, reg_offs->pend, 0x1); - irq_set_handler_data(irq, domain); - irq_set_chained_handler(irq, sunxi_sc_nmi_handle_irq); + irq_set_chained_handler_and_data(irq, sunxi_sc_nmi_handle_irq, domain); return 0; diff --git a/drivers/irqchip/irq-tb10x.c b/drivers/irqchip/irq-tb10x.c index accc20036a3c..331829661366 100644 --- a/drivers/irqchip/irq-tb10x.c +++ b/drivers/irqchip/irq-tb10x.c @@ -22,13 +22,13 @@ #include <linux/interrupt.h> #include <linux/irqdomain.h> #include <linux/irq.h> +#include <linux/irqchip.h> #include <linux/of_irq.h> #include <linux/of_address.h> #include <linux/of_platform.h> #include <linux/io.h> #include <linux/slab.h> #include <linux/bitops.h> -#include "irqchip.h" #define AB_IRQCTL_INT_ENABLE 0x00 #define AB_IRQCTL_INT_STATUS 0x04 @@ -97,9 +97,10 @@ static int tb10x_irq_set_type(struct irq_data *data, unsigned int flow_type) return IRQ_SET_MASK_OK; } -static void tb10x_irq_cascade(unsigned int irq, struct irq_desc *desc) +static void tb10x_irq_cascade(unsigned int __irq, struct irq_desc *desc) { struct irq_domain *domain = irq_desc_get_handler_data(desc); + unsigned int irq = irq_desc_get_irq(desc); generic_handle_irq(irq_find_mapping(domain, irq)); } @@ -173,8 +174,8 @@ static int __init of_tb10x_init_irq(struct device_node *ictl, for (i = 0; i < nrirqs; i++) { unsigned int irq = irq_of_parse_and_map(ictl, i); - irq_set_handler_data(irq, domain); - irq_set_chained_handler(irq, tb10x_irq_cascade); + irq_set_chained_handler_and_data(irq, tb10x_irq_cascade, + domain); } ab_irqctl_writereg(gc, AB_IRQCTL_INT_ENABLE, 0); diff --git a/drivers/irqchip/irq-tegra.c b/drivers/irqchip/irq-tegra.c index f67bbd80433e..2fd89eb88f3a 100644 --- a/drivers/irqchip/irq-tegra.c +++ b/drivers/irqchip/irq-tegra.c @@ -24,6 +24,7 @@ #include <linux/io.h> #include <linux/irq.h> +#include <linux/irqchip.h> #include <linux/irqdomain.h> #include <linux/of_address.h> #include <linux/slab.h> @@ -31,8 +32,6 @@ #include <dt-bindings/interrupt-controller/arm-gic.h> -#include "irqchip.h" - #define ICTLR_CPU_IEP_VFIQ 0x08 #define ICTLR_CPU_IEP_FIR 0x14 #define ICTLR_CPU_IEP_FIR_SET 0x18 diff --git a/drivers/irqchip/irq-versatile-fpga.c b/drivers/irqchip/irq-versatile-fpga.c index 888111b76ea0..16123f688768 100644 --- a/drivers/irqchip/irq-versatile-fpga.c +++ b/drivers/irqchip/irq-versatile-fpga.c @@ -4,6 +4,7 @@ #include <linux/bitops.h> #include <linux/irq.h> #include <linux/io.h> +#include <linux/irqchip.h> #include <linux/irqchip/versatile-fpga.h> #include <linux/irqdomain.h> #include <linux/module.h> @@ -14,8 +15,6 @@ #include <asm/exception.h> #include <asm/mach/irq.h> -#include "irqchip.h" - #define IRQ_STATUS 0x00 #define IRQ_RAW_STATUS 0x04 #define IRQ_ENABLE_SET 0x08 @@ -66,9 +65,10 @@ static void fpga_irq_unmask(struct irq_data *d) writel(mask, f->base + IRQ_ENABLE_SET); } -static void fpga_irq_handle(unsigned int irq, struct irq_desc *desc) +static void fpga_irq_handle(unsigned int __irq, struct irq_desc *desc) { struct fpga_irq_data *f = irq_desc_get_handler_data(desc); + unsigned int irq = irq_desc_get_irq(desc); u32 status = readl(f->base + IRQ_STATUS); if (status == 0) { @@ -156,8 +156,8 @@ void __init fpga_irq_init(void __iomem *base, const char *name, int irq_start, f->valid = valid; if (parent_irq != -1) { - irq_set_handler_data(parent_irq, f); - irq_set_chained_handler(parent_irq, fpga_irq_handle); + irq_set_chained_handler_and_data(parent_irq, fpga_irq_handle, + f); } /* This will also allocate irq descriptors */ diff --git a/drivers/irqchip/irq-vf610-mscm-ir.c b/drivers/irqchip/irq-vf610-mscm-ir.c index f5c01cbcc73a..2c2255886401 100644 --- a/drivers/irqchip/irq-vf610-mscm-ir.c +++ b/drivers/irqchip/irq-vf610-mscm-ir.c @@ -26,6 +26,7 @@ #include <linux/cpu_pm.h> #include <linux/io.h> #include <linux/irq.h> +#include <linux/irqchip.h> #include <linux/irqdomain.h> #include <linux/mfd/syscon.h> #include <dt-bindings/interrupt-controller/arm-gic.h> @@ -34,8 +35,6 @@ #include <linux/slab.h> #include <linux/regmap.h> -#include "irqchip.h" - #define MSCM_CPxNUM 0x4 #define MSCM_IRSPRC(n) (0x80 + 2 * (n)) diff --git a/drivers/irqchip/irq-vic.c b/drivers/irqchip/irq-vic.c index d4ce331ea4a0..03846dff4212 100644 --- a/drivers/irqchip/irq-vic.c +++ b/drivers/irqchip/irq-vic.c @@ -24,6 +24,7 @@ #include <linux/list.h> #include <linux/io.h> #include <linux/irq.h> +#include <linux/irqchip.h> #include <linux/irqchip/chained_irq.h> #include <linux/irqdomain.h> #include <linux/of.h> @@ -37,8 +38,6 @@ #include <asm/exception.h> #include <asm/irq.h> -#include "irqchip.h" - #define VIC_IRQ_STATUS 0x00 #define VIC_FIQ_STATUS 0x04 #define VIC_INT_SELECT 0x0c /* 1 = FIQ, 0 = IRQ */ @@ -297,8 +296,8 @@ static void __init vic_register(void __iomem *base, unsigned int parent_irq, vic_id++; if (parent_irq) { - irq_set_handler_data(parent_irq, v); - irq_set_chained_handler(parent_irq, vic_handle_irq_cascaded); + irq_set_chained_handler_and_data(parent_irq, + vic_handle_irq_cascaded, v); } v->domain = irq_domain_add_simple(node, fls(valid_sources), irq, diff --git a/drivers/irqchip/irq-vt8500.c b/drivers/irqchip/irq-vt8500.c index 0b297009b856..8371d9978d31 100644 --- a/drivers/irqchip/irq-vt8500.c +++ b/drivers/irqchip/irq-vt8500.c @@ -27,6 +27,7 @@ #include <linux/slab.h> #include <linux/io.h> #include <linux/irq.h> +#include <linux/irqchip.h> #include <linux/irqdomain.h> #include <linux/interrupt.h> #include <linux/bitops.h> @@ -39,8 +40,6 @@ #include <asm/exception.h> #include <asm/mach/irq.h> -#include "irqchip.h" - #define VT8500_ICPC_IRQ 0x20 #define VT8500_ICPC_FIQ 0x24 #define VT8500_ICDC 0x40 /* Destination Control 64*u32 */ @@ -127,15 +126,15 @@ static int vt8500_irq_set_type(struct irq_data *d, unsigned int flow_type) return -EINVAL; case IRQF_TRIGGER_HIGH: dctr |= VT8500_TRIGGER_HIGH; - __irq_set_handler_locked(d->irq, handle_level_irq); + irq_set_handler_locked(d, handle_level_irq); break; case IRQF_TRIGGER_FALLING: dctr |= VT8500_TRIGGER_FALLING; - __irq_set_handler_locked(d->irq, handle_edge_irq); + irq_set_handler_locked(d, handle_edge_irq); break; case IRQF_TRIGGER_RISING: dctr |= VT8500_TRIGGER_RISING; - __irq_set_handler_locked(d->irq, handle_edge_irq); + irq_set_handler_locked(d, handle_edge_irq); break; } writeb(dctr, base + VT8500_ICDC + d->hwirq); diff --git a/drivers/irqchip/irq-xtensa-mx.c b/drivers/irqchip/irq-xtensa-mx.c index e1c2f9632893..bb3ac5fe5846 100644 --- a/drivers/irqchip/irq-xtensa-mx.c +++ b/drivers/irqchip/irq-xtensa-mx.c @@ -11,12 +11,11 @@ #include <linux/interrupt.h> #include <linux/irqdomain.h> #include <linux/irq.h> +#include <linux/irqchip.h> #include <linux/of.h> #include <asm/mxregs.h> -#include "irqchip.h" - #define HW_IRQ_IPI_COUNT 2 #define HW_IRQ_MX_BASE 2 #define HW_IRQ_EXTERN_BASE 3 diff --git a/drivers/irqchip/irq-xtensa-pic.c b/drivers/irqchip/irq-xtensa-pic.c index 7d71126d1ce5..472ae1770964 100644 --- a/drivers/irqchip/irq-xtensa-pic.c +++ b/drivers/irqchip/irq-xtensa-pic.c @@ -15,10 +15,9 @@ #include <linux/interrupt.h> #include <linux/irqdomain.h> #include <linux/irq.h> +#include <linux/irqchip.h> #include <linux/of.h> -#include "irqchip.h" - unsigned int cached_irq_mask; /* diff --git a/drivers/irqchip/irq-zevio.c b/drivers/irqchip/irq-zevio.c index e4ef74ed454a..4c48fa88a03d 100644 --- a/drivers/irqchip/irq-zevio.c +++ b/drivers/irqchip/irq-zevio.c @@ -11,6 +11,7 @@ #include <linux/io.h> #include <linux/irq.h> +#include <linux/irqchip.h> #include <linux/of.h> #include <linux/of_address.h> #include <linux/of_irq.h> @@ -18,8 +19,6 @@ #include <asm/mach/irq.h> #include <asm/exception.h> -#include "irqchip.h" - #define IO_STATUS 0x000 #define IO_RAW_STATUS 0x004 #define IO_ENABLE 0x008 diff --git a/drivers/irqchip/spear-shirq.c b/drivers/irqchip/spear-shirq.c index acb721b31bcf..4cbd9c5dc1e6 100644 --- a/drivers/irqchip/spear-shirq.c +++ b/drivers/irqchip/spear-shirq.c @@ -18,14 +18,13 @@ #include <linux/interrupt.h> #include <linux/io.h> #include <linux/irq.h> +#include <linux/irqchip.h> #include <linux/irqdomain.h> #include <linux/of.h> #include <linux/of_address.h> #include <linux/of_irq.h> #include <linux/spinlock.h> -#include "irqchip.h" - /* * struct spear_shirq: shared irq structure * @@ -183,9 +182,9 @@ static struct spear_shirq *spear320_shirq_blocks[] = { &spear320_shirq_intrcomm_ras, }; -static void shirq_handler(unsigned irq, struct irq_desc *desc) +static void shirq_handler(unsigned __irq, struct irq_desc *desc) { - struct spear_shirq *shirq = irq_get_handler_data(irq); + struct spear_shirq *shirq = irq_desc_get_handler_data(desc); u32 pend; pend = readl(shirq->base + shirq->status_reg) & shirq->mask; diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c index f34892e0edb4..6f3abc2c7316 100644 --- a/drivers/pci/host/pci-keystone-dw.c +++ b/drivers/pci/host/pci-keystone-dw.c @@ -104,14 +104,13 @@ static void ks_dw_pcie_msi_irq_ack(struct irq_data *d) { u32 offset, reg_offset, bit_pos; struct keystone_pcie *ks_pcie; - unsigned int irq = d->irq; struct msi_desc *msi; struct pcie_port *pp; - msi = irq_get_msi_desc(irq); - pp = sys_to_pcie(msi->dev->bus->sysdata); + msi = irq_data_get_msi_desc(d); + pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi)); ks_pcie = to_keystone_pcie(pp); - offset = irq - irq_linear_revmap(pp->irq_domain, 0); + offset = d->irq - irq_linear_revmap(pp->irq_domain, 0); update_reg_offset_bit_pos(offset, ®_offset, &bit_pos); writel(BIT(bit_pos), @@ -142,15 +141,14 @@ void ks_dw_pcie_msi_clear_irq(struct pcie_port *pp, int irq) static void ks_dw_pcie_msi_irq_mask(struct irq_data *d) { struct keystone_pcie *ks_pcie; - unsigned int irq = d->irq; struct msi_desc *msi; struct pcie_port *pp; u32 offset; - msi = irq_get_msi_desc(irq); - pp = sys_to_pcie(msi->dev->bus->sysdata); + msi = irq_data_get_msi_desc(d); + pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi)); ks_pcie = to_keystone_pcie(pp); - offset = irq - irq_linear_revmap(pp->irq_domain, 0); + offset = d->irq - irq_linear_revmap(pp->irq_domain, 0); /* Mask the end point if PVM implemented */ if (IS_ENABLED(CONFIG_PCI_MSI)) { @@ -164,15 +162,14 @@ static void ks_dw_pcie_msi_irq_mask(struct irq_data *d) static void ks_dw_pcie_msi_irq_unmask(struct irq_data *d) { struct keystone_pcie *ks_pcie; - unsigned int irq = d->irq; struct msi_desc *msi; struct pcie_port *pp; u32 offset; - msi = irq_get_msi_desc(irq); - pp = sys_to_pcie(msi->dev->bus->sysdata); + msi = irq_data_get_msi_desc(d); + pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi)); ks_pcie = to_keystone_pcie(pp); - offset = irq - irq_linear_revmap(pp->irq_domain, 0); + offset = d->irq - irq_linear_revmap(pp->irq_domain, 0); /* Mask the end point if PVM implemented */ if (IS_ENABLED(CONFIG_PCI_MSI)) { diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-keystone.c index 734da589cdfb..81253e70b1c5 100644 --- a/drivers/pci/host/pci-keystone.c +++ b/drivers/pci/host/pci-keystone.c @@ -110,8 +110,9 @@ static int ks_pcie_establish_link(struct keystone_pcie *ks_pcie) return -EINVAL; } -static void ks_pcie_msi_irq_handler(unsigned int irq, struct irq_desc *desc) +static void ks_pcie_msi_irq_handler(unsigned int __irq, struct irq_desc *desc) { + unsigned int irq = irq_desc_get_irq(desc); struct keystone_pcie *ks_pcie = irq_desc_get_handler_data(desc); u32 offset = irq - ks_pcie->msi_host_irqs[0]; struct pcie_port *pp = &ks_pcie->pp; @@ -137,8 +138,10 @@ static void ks_pcie_msi_irq_handler(unsigned int irq, struct irq_desc *desc) * Traverse through pending legacy interrupts and invoke handler for each. Also * takes care of interrupt controller level mask/ack operation. */ -static void ks_pcie_legacy_irq_handler(unsigned int irq, struct irq_desc *desc) +static void ks_pcie_legacy_irq_handler(unsigned int __irq, + struct irq_desc *desc) { + unsigned int irq = irq_desc_get_irq(desc); struct keystone_pcie *ks_pcie = irq_desc_get_handler_data(desc); struct pcie_port *pp = &ks_pcie->pp; u32 irq_offset = irq - ks_pcie->legacy_host_irqs[0]; @@ -212,9 +215,9 @@ static void ks_pcie_setup_interrupts(struct keystone_pcie *ks_pcie) /* Legacy IRQ */ for (i = 0; i < ks_pcie->num_legacy_host_irqs; i++) { - irq_set_handler_data(ks_pcie->legacy_host_irqs[i], ks_pcie); - irq_set_chained_handler(ks_pcie->legacy_host_irqs[i], - ks_pcie_legacy_irq_handler); + irq_set_chained_handler_and_data(ks_pcie->legacy_host_irqs[i], + ks_pcie_legacy_irq_handler, + ks_pcie); } ks_dw_pcie_enable_legacy_irqs(ks_pcie); diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c index 69486be7181e..aae6dcb528c1 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c @@ -255,7 +255,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq) static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos) { int irq, pos0, i; - struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata); + struct pcie_port *pp = sys_to_pcie(msi_desc_to_pci_sysdata(desc)); pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS, order_base_2(no_irqs)); @@ -326,8 +326,8 @@ static int dw_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev, static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq) { struct irq_data *data = irq_get_irq_data(irq); - struct msi_desc *msi = irq_data_get_msi(data); - struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata); + struct msi_desc *msi = irq_data_get_msi_desc(data); + struct pcie_port *pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi)); clear_irq_range(pp, irq, 1, data->hwirq); } diff --git a/drivers/pci/host/pcie-xilinx.c b/drivers/pci/host/pcie-xilinx.c index f1a06a091ccb..64454f416639 100644 --- a/drivers/pci/host/pcie-xilinx.c +++ b/drivers/pci/host/pcie-xilinx.c @@ -227,18 +227,16 @@ static struct pci_ops xilinx_pcie_ops = { */ static void xilinx_pcie_destroy_msi(unsigned int irq) { - struct irq_desc *desc; struct msi_desc *msi; struct xilinx_pcie_port *port; - desc = irq_to_desc(irq); - msi = irq_desc_get_msi_desc(desc); - port = sys_to_pcie(msi->dev->bus->sysdata); - - if (!test_bit(irq, msi_irq_in_use)) + if (!test_bit(irq, msi_irq_in_use)) { + msi = irq_get_msi_desc(irq); + port = sys_to_pcie(msi_desc_to_pci_sys_data(msi)); dev_err(port->dev, "Trying to free unused MSI#%d\n", irq); - else + } else { clear_bit(irq, msi_irq_in_use); + } } /** diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index f66be868ad21..cd4c78c193de 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -131,7 +131,7 @@ int __weak arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) if (type == PCI_CAP_ID_MSI && nvec > 1) return 1; - list_for_each_entry(entry, &dev->msi_list, list) { + for_each_pci_msi_entry(entry, dev) { ret = arch_setup_msi_irq(dev, entry); if (ret < 0) return ret; @@ -151,7 +151,7 @@ void default_teardown_msi_irqs(struct pci_dev *dev) int i; struct msi_desc *entry; - list_for_each_entry(entry, &dev->msi_list, list) + for_each_pci_msi_entry(entry, dev) if (entry->irq) for (i = 0; i < entry->nvec_used; i++) arch_teardown_msi_irq(entry->irq + i); @@ -168,7 +168,7 @@ static void default_restore_msi_irq(struct pci_dev *dev, int irq) entry = NULL; if (dev->msix_enabled) { - list_for_each_entry(entry, &dev->msi_list, list) { + for_each_pci_msi_entry(entry, dev) { if (irq == entry->irq) break; } @@ -208,7 +208,8 @@ u32 __pci_msi_desc_mask_irq(struct msi_desc *desc, u32 mask, u32 flag) mask_bits &= ~mask; mask_bits |= flag; - pci_write_config_dword(desc->dev, desc->mask_pos, mask_bits); + pci_write_config_dword(msi_desc_to_pci_dev(desc), desc->mask_pos, + mask_bits); return mask_bits; } @@ -249,7 +250,7 @@ static void msix_mask_irq(struct msi_desc *desc, u32 flag) static void msi_set_mask_bit(struct irq_data *data, u32 flag) { - struct msi_desc *desc = irq_data_get_msi(data); + struct msi_desc *desc = irq_data_get_msi_desc(data); if (desc->msi_attrib.is_msix) { msix_mask_irq(desc, flag); @@ -282,13 +283,15 @@ void default_restore_msi_irqs(struct pci_dev *dev) { struct msi_desc *entry; - list_for_each_entry(entry, &dev->msi_list, list) + for_each_pci_msi_entry(entry, dev) default_restore_msi_irq(dev, entry->irq); } void __pci_read_msi_msg(struct msi_desc *entry, struct msi_msg *msg) { - BUG_ON(entry->dev->current_state != PCI_D0); + struct pci_dev *dev = msi_desc_to_pci_dev(entry); + + BUG_ON(dev->current_state != PCI_D0); if (entry->msi_attrib.is_msix) { void __iomem *base = entry->mask_base + @@ -298,7 +301,6 @@ void __pci_read_msi_msg(struct msi_desc *entry, struct msi_msg *msg) msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR); msg->data = readl(base + PCI_MSIX_ENTRY_DATA); } else { - struct pci_dev *dev = entry->dev; int pos = dev->msi_cap; u16 data; @@ -318,7 +320,9 @@ void __pci_read_msi_msg(struct msi_desc *entry, struct msi_msg *msg) void __pci_write_msi_msg(struct msi_desc *entry, struct msi_msg *msg) { - if (entry->dev->current_state != PCI_D0) { + struct pci_dev *dev = msi_desc_to_pci_dev(entry); + + if (dev->current_state != PCI_D0) { /* Don't touch the hardware now */ } else if (entry->msi_attrib.is_msix) { void __iomem *base; @@ -329,7 +333,6 @@ void __pci_write_msi_msg(struct msi_desc *entry, struct msi_msg *msg) writel(msg->address_hi, base + PCI_MSIX_ENTRY_UPPER_ADDR); writel(msg->data, base + PCI_MSIX_ENTRY_DATA); } else { - struct pci_dev *dev = entry->dev; int pos = dev->msi_cap; u16 msgctl; @@ -363,21 +366,22 @@ EXPORT_SYMBOL_GPL(pci_write_msi_msg); static void free_msi_irqs(struct pci_dev *dev) { + struct list_head *msi_list = dev_to_msi_list(&dev->dev); struct msi_desc *entry, *tmp; struct attribute **msi_attrs; struct device_attribute *dev_attr; int i, count = 0; - list_for_each_entry(entry, &dev->msi_list, list) + for_each_pci_msi_entry(entry, dev) if (entry->irq) for (i = 0; i < entry->nvec_used; i++) BUG_ON(irq_has_action(entry->irq + i)); pci_msi_teardown_msi_irqs(dev); - list_for_each_entry_safe(entry, tmp, &dev->msi_list, list) { + list_for_each_entry_safe(entry, tmp, msi_list, list) { if (entry->msi_attrib.is_msix) { - if (list_is_last(&entry->list, &dev->msi_list)) + if (list_is_last(&entry->list, msi_list)) iounmap(entry->mask_base); } @@ -402,18 +406,6 @@ static void free_msi_irqs(struct pci_dev *dev) } } -static struct msi_desc *alloc_msi_entry(struct pci_dev *dev) -{ - struct msi_desc *desc = kzalloc(sizeof(*desc), GFP_KERNEL); - if (!desc) - return NULL; - - INIT_LIST_HEAD(&desc->list); - desc->dev = dev; - - return desc; -} - static void pci_intx_for_msi(struct pci_dev *dev, int enable) { if (!(dev->dev_flags & PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG)) @@ -448,7 +440,7 @@ static void __pci_restore_msix_state(struct pci_dev *dev) if (!dev->msix_enabled) return; - BUG_ON(list_empty(&dev->msi_list)); + BUG_ON(list_empty(dev_to_msi_list(&dev->dev))); /* route the table */ pci_intx_for_msi(dev, 0); @@ -456,7 +448,7 @@ static void __pci_restore_msix_state(struct pci_dev *dev) PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL); arch_restore_msi_irqs(dev); - list_for_each_entry(entry, &dev->msi_list, list) + for_each_pci_msi_entry(entry, dev) msix_mask_irq(entry, entry->masked); pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_MASKALL, 0); @@ -501,7 +493,7 @@ static int populate_msi_sysfs(struct pci_dev *pdev) int count = 0; /* Determine how many msi entries we have */ - list_for_each_entry(entry, &pdev->msi_list, list) + for_each_pci_msi_entry(entry, pdev) ++num_msi; if (!num_msi) return 0; @@ -510,7 +502,7 @@ static int populate_msi_sysfs(struct pci_dev *pdev) msi_attrs = kzalloc(sizeof(void *) * (num_msi + 1), GFP_KERNEL); if (!msi_attrs) return -ENOMEM; - list_for_each_entry(entry, &pdev->msi_list, list) { + for_each_pci_msi_entry(entry, pdev) { msi_dev_attr = kzalloc(sizeof(*msi_dev_attr), GFP_KERNEL); if (!msi_dev_attr) goto error_attrs; @@ -568,7 +560,7 @@ static struct msi_desc *msi_setup_entry(struct pci_dev *dev, int nvec) struct msi_desc *entry; /* MSI Entry Initialization */ - entry = alloc_msi_entry(dev); + entry = alloc_msi_entry(&dev->dev); if (!entry) return NULL; @@ -599,7 +591,7 @@ static int msi_verify_entries(struct pci_dev *dev) { struct msi_desc *entry; - list_for_each_entry(entry, &dev->msi_list, list) { + for_each_pci_msi_entry(entry, dev) { if (!dev->no_64bit_msi || !entry->msg.address_hi) continue; dev_err(&dev->dev, "Device has broken 64-bit MSI but arch" @@ -636,7 +628,7 @@ static int msi_capability_init(struct pci_dev *dev, int nvec) mask = msi_mask(entry->msi_attrib.multi_cap); msi_mask_irq(entry, mask, mask); - list_add_tail(&entry->list, &dev->msi_list); + list_add_tail(&entry->list, dev_to_msi_list(&dev->dev)); /* Configure MSI capability structure */ ret = pci_msi_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSI); @@ -696,7 +688,7 @@ static int msix_setup_entries(struct pci_dev *dev, void __iomem *base, int i; for (i = 0; i < nvec; i++) { - entry = alloc_msi_entry(dev); + entry = alloc_msi_entry(&dev->dev); if (!entry) { if (!i) iounmap(base); @@ -713,7 +705,7 @@ static int msix_setup_entries(struct pci_dev *dev, void __iomem *base, entry->mask_base = base; entry->nvec_used = 1; - list_add_tail(&entry->list, &dev->msi_list); + list_add_tail(&entry->list, dev_to_msi_list(&dev->dev)); } return 0; @@ -725,7 +717,7 @@ static void msix_program_entries(struct pci_dev *dev, struct msi_desc *entry; int i = 0; - list_for_each_entry(entry, &dev->msi_list, list) { + for_each_pci_msi_entry(entry, dev) { int offset = entries[i].entry * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_VECTOR_CTRL; @@ -806,7 +798,7 @@ out_avail: struct msi_desc *entry; int avail = 0; - list_for_each_entry(entry, &dev->msi_list, list) { + for_each_pci_msi_entry(entry, dev) { if (entry->irq != 0) avail++; } @@ -895,8 +887,8 @@ void pci_msi_shutdown(struct pci_dev *dev) if (!pci_msi_enable || !dev || !dev->msi_enabled) return; - BUG_ON(list_empty(&dev->msi_list)); - desc = list_first_entry(&dev->msi_list, struct msi_desc, list); + BUG_ON(list_empty(dev_to_msi_list(&dev->dev))); + desc = first_pci_msi_entry(dev); pci_msi_set_enable(dev, 0); pci_intx_for_msi(dev, 1); @@ -1001,7 +993,7 @@ void pci_msix_shutdown(struct pci_dev *dev) return; /* Return the device with MSI-X masked as initial states */ - list_for_each_entry(entry, &dev->msi_list, list) { + for_each_pci_msi_entry(entry, dev) { /* Keep cached states to be restored */ __pci_msix_desc_mask_irq(entry, 1); } @@ -1040,7 +1032,6 @@ EXPORT_SYMBOL(pci_msi_enabled); void pci_msi_init_pci_dev(struct pci_dev *dev) { - INIT_LIST_HEAD(&dev->msi_list); } /** @@ -1137,6 +1128,19 @@ int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, } EXPORT_SYMBOL(pci_enable_msix_range); +struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc) +{ + return to_pci_dev(desc->dev); +} + +void *msi_desc_to_pci_sysdata(struct msi_desc *desc) +{ + struct pci_dev *dev = msi_desc_to_pci_dev(desc); + + return dev->bus->sysdata; +} +EXPORT_SYMBOL_GPL(msi_desc_to_pci_sysdata); + #ifdef CONFIG_PCI_MSI_IRQ_DOMAIN /** * pci_msi_domain_write_msg - Helper to write MSI message to PCI config space @@ -1145,7 +1149,7 @@ EXPORT_SYMBOL(pci_enable_msix_range); */ void pci_msi_domain_write_msg(struct irq_data *irq_data, struct msi_msg *msg) { - struct msi_desc *desc = irq_data->msi_desc; + struct msi_desc *desc = irq_data_get_msi_desc(irq_data); /* * For MSI-X desc->irq is always equal to irq_data->irq. For diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c index 8b7a900cd28b..c777b97207d5 100644 --- a/drivers/pci/xen-pcifront.c +++ b/drivers/pci/xen-pcifront.c @@ -265,7 +265,7 @@ static int pci_frontend_enable_msix(struct pci_dev *dev, } i = 0; - list_for_each_entry(entry, &dev->msi_list, list) { + for_each_pci_msi_entry(entry, dev) { op.msix_entries[i].entry = entry->msi_attrib.entry_nr; /* Vector is useless at this point. */ op.msix_entries[i].vector = -1; diff --git a/drivers/sh/intc/chip.c b/drivers/sh/intc/chip.c index 46427b48e2f1..358df7510186 100644 --- a/drivers/sh/intc/chip.c +++ b/drivers/sh/intc/chip.c @@ -22,7 +22,7 @@ void _intc_enable(struct irq_data *data, unsigned long handle) for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_E(handle)); cpu++) { #ifdef CONFIG_SMP - if (!cpumask_test_cpu(cpu, data->affinity)) + if (!cpumask_test_cpu(cpu, irq_data_get_affinity_mask(data))) continue; #endif addr = INTC_REG(d, _INTC_ADDR_E(handle), cpu); @@ -50,7 +50,7 @@ static void intc_disable(struct irq_data *data) for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_D(handle)); cpu++) { #ifdef CONFIG_SMP - if (!cpumask_test_cpu(cpu, data->affinity)) + if (!cpumask_test_cpu(cpu, irq_data_get_affinity_mask(data))) continue; #endif addr = INTC_REG(d, _INTC_ADDR_D(handle), cpu); @@ -72,7 +72,7 @@ static int intc_set_affinity(struct irq_data *data, if (!cpumask_intersects(cpumask, cpu_online_mask)) return -1; - cpumask_copy(data->affinity, cpumask); + cpumask_copy(irq_data_get_affinity_mask(data), cpumask); return IRQ_SET_MASK_OK_NOCOPY; } diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c index 156b790072b4..043419dcee92 100644 --- a/drivers/sh/intc/core.c +++ b/drivers/sh/intc/core.c @@ -67,7 +67,7 @@ void intc_set_prio_level(unsigned int irq, unsigned int level) static void intc_redirect_irq(unsigned int irq, struct irq_desc *desc) { - generic_handle_irq((unsigned int)irq_get_handler_data(irq)); + generic_handle_irq((unsigned int)irq_desc_get_handler_data(desc)); } static void __init intc_register_irq(struct intc_desc *desc, diff --git a/drivers/sh/intc/virq.c b/drivers/sh/intc/virq.c index f5f1b821241a..bafc51c6f0ba 100644 --- a/drivers/sh/intc/virq.c +++ b/drivers/sh/intc/virq.c @@ -83,12 +83,11 @@ EXPORT_SYMBOL_GPL(intc_irq_lookup); static int add_virq_to_pirq(unsigned int irq, unsigned int virq) { - struct intc_virq_list **last, *entry; - struct irq_data *data = irq_get_irq_data(irq); + struct intc_virq_list *entry; + struct intc_virq_list **last = NULL; /* scan for duplicates */ - last = (struct intc_virq_list **)&data->handler_data; - for_each_virq(entry, data->handler_data) { + for_each_virq(entry, irq_get_handler_data(irq)) { if (entry->irq == virq) return 0; last = &entry->next; @@ -102,14 +101,18 @@ static int add_virq_to_pirq(unsigned int irq, unsigned int virq) entry->irq = virq; - *last = entry; + if (last) + *last = entry; + else + irq_set_handler_data(irq, entry); return 0; } -static void intc_virq_handler(unsigned int irq, struct irq_desc *desc) +static void intc_virq_handler(unsigned int __irq, struct irq_desc *desc) { - struct irq_data *data = irq_get_irq_data(irq); + unsigned int irq = irq_desc_get_irq(desc); + struct irq_data *data = irq_desc_get_irq_data(desc); struct irq_chip *chip = irq_data_get_irq_chip(data); struct intc_virq_list *entry, *vlist = irq_data_get_irq_handler_data(data); struct intc_desc_int *d = get_intc_desc(irq); @@ -118,12 +121,14 @@ static void intc_virq_handler(unsigned int irq, struct irq_desc *desc) for_each_virq(entry, vlist) { unsigned long addr, handle; + struct irq_desc *vdesc = irq_to_desc(entry->irq); - handle = (unsigned long)irq_get_handler_data(entry->irq); - addr = INTC_REG(d, _INTC_ADDR_E(handle), 0); - - if (intc_reg_fns[_INTC_FN(handle)](addr, handle, 0)) - generic_handle_irq(entry->irq); + if (vdesc) { + handle = (unsigned long)irq_desc_get_handler_data(vdesc); + addr = INTC_REG(d, _INTC_ADDR_E(handle), 0); + if (intc_reg_fns[_INTC_FN(handle)](addr, handle, 0)) + generic_handle_irq_desc(entry->irq, vdesc); + } } chip->irq_unmask(data); diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c index d7119db49cfe..483948459765 100644 --- a/drivers/spmi/spmi-pmic-arb.c +++ b/drivers/spmi/spmi-pmic-arb.c @@ -453,8 +453,8 @@ static void periph_interrupt(struct spmi_pmic_arb_dev *pa, u8 apid) static void pmic_arb_chained_irq(unsigned int irq, struct irq_desc *desc) { - struct spmi_pmic_arb_dev *pa = irq_get_handler_data(irq); - struct irq_chip *chip = irq_get_chip(irq); + struct spmi_pmic_arb_dev *pa = irq_desc_get_handler_data(desc); + struct irq_chip *chip = irq_desc_get_chip(desc); void __iomem *intr = pa->intr; int first = pa->min_apid >> 5; int last = pa->max_apid >> 5; @@ -928,8 +928,7 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) goto err_put_ctrl; } - irq_set_handler_data(pa->irq, pa); - irq_set_chained_handler(pa->irq, pmic_arb_chained_irq); + irq_set_chained_handler_and_data(pa->irq, pmic_arb_chained_irq, pa); err = spmi_controller_add(ctrl); if (err) @@ -938,8 +937,7 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) return 0; err_domain_remove: - irq_set_chained_handler(pa->irq, NULL); - irq_set_handler_data(pa->irq, NULL); + irq_set_chained_handler_and_data(pa->irq, NULL, NULL); irq_domain_remove(pa->domain); err_put_ctrl: spmi_controller_put(ctrl); @@ -951,8 +949,7 @@ static int spmi_pmic_arb_remove(struct platform_device *pdev) struct spmi_controller *ctrl = platform_get_drvdata(pdev); struct spmi_pmic_arb_dev *pa = spmi_controller_get_drvdata(ctrl); spmi_controller_remove(ctrl); - irq_set_chained_handler(pa->irq, NULL); - irq_set_handler_data(pa->irq, NULL); + irq_set_chained_handler_and_data(pa->irq, NULL, NULL); irq_domain_remove(pa->domain); spmi_controller_put(ctrl); return 0; |