Commit 407a2c72 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull irq updates from Thomas Gleixner:
 "The irq departement delivers:

   - plug a potential race related to chained interrupt handlers

   - core updates which address the needs of the x86 irqdomain conversion

   - new irqchip callback to support affinity settings for VCPUs

   - the usual pile of updates to interrupt chip drivers

   - a few helper functions to allow further cleanups and
     simplifications

  I have a largish pile of coccinelle scripted/verified cleanups and
  simplifications pending on top of that, but I prefer to send that
  towards the end of the merge window when the arch/driver changes have
  hit your tree to avoid API change wreckage as far as possible"

* 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (34 commits)
  genirq: Remove bogus restriction in irq_move_mask_irq()
  irqchip: atmel-aic5: Add sama5d2 support
  irq: spear-shirq: Fix race in installing chained IRQ handler
  irq: irq-keystone: Fix race in installing chained IRQ handler
  gpio: gpio-tegra: Fix race in installing chained IRQ handler
  gpio: gpio-mxs: Fix race in installing chained IRQ handler
  gpio: gpio-mxc: Fix race in installing chained IRQ handler
  ARM: gemini: Fix race in installing GPIO chained IRQ handler
  GPU: ipu: Fix race in installing IPU chained IRQ handler
  ARM: sa1100: convert SA11x0 related code to use new chained handler helper
  irq: Add irq_set_chained_handler_and_data()
  irqchip: exynos-combiner: Save IRQ enable set on suspend
  genirq: Introduce helper function irq_data_get_affinity_mask()
  genirq: Introduce helper function irq_data_get_node()
  genirq: Introduce struct irq_common_data to host shared irq data
  genirq: Prevent crash in irq_move_irq()
  genirq: Enhance irq_data_to_desc() to support hierarchy irqdomain
  irqchip: gic: Simplify gic_configure_irq by using IRQCHIP_SET_TYPE_MASKED
  irqchip: renesas: intc-irqpin: Improve binding documentation
  genirq: Set IRQCHIP_SKIP_SET_WAKE for no_irq_chip
  ...
parents 3a95398f f0521865
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
Required properties: Required properties:
- compatible: Should be "atmel,<chip>-aic" - compatible: Should be "atmel,<chip>-aic"
<chip> can be "at91rm9200", "sama5d3" or "sama5d4" <chip> can be "at91rm9200", "sama5d2", "sama5d3" or "sama5d4"
- interrupt-controller: Identifies the node as an interrupt controller. - interrupt-controller: Identifies the node as an interrupt controller.
- interrupt-parent: For single AIC system, it is an empty property. - interrupt-parent: For single AIC system, it is an empty property.
- #interrupt-cells: The number of cells to define the interrupts. It should be 3. - #interrupt-cells: The number of cells to define the interrupts. It should be 3.
......
...@@ -13,9 +13,12 @@ Required properties: ...@@ -13,9 +13,12 @@ Required properties:
- reg: Base address and length of each register bank used by the external - reg: Base address and length of each register bank used by the external
IRQ pins driven by the interrupt controller hardware module. The base IRQ pins driven by the interrupt controller hardware module. The base
addresses, length and number of required register banks varies with soctype. addresses, length and number of required register banks varies with soctype.
- interrupt-controller: Identifies the node as an interrupt controller.
- #interrupt-cells: has to be <2>: an interrupt index and flags, as defined in - #interrupt-cells: has to be <2>: an interrupt index and flags, as defined in
interrupts.txt in this directory interrupts.txt in this directory.
- interrupts: Must contain a list of interrupt specifiers. For each interrupt
provided by this irqpin controller instance, there must be one entry,
referring to the corresponding parent interrupt.
Optional properties: Optional properties:
...@@ -25,3 +28,35 @@ Optional properties: ...@@ -25,3 +28,35 @@ Optional properties:
if different from the default 4 bits if different from the default 4 bits
- control-parent: disable and enable interrupts on the parent interrupt - control-parent: disable and enable interrupts on the parent interrupt
controller, needed for some broken implementations controller, needed for some broken implementations
- clocks: Must contain a reference to the functional clock. This property is
mandatory if the hardware implements a controllable functional clock for
the irqpin controller instance.
- power-domains: Must contain a reference to the power domain. This property is
mandatory if the irqpin controller instance is part of a controllable power
domain.
Example
-------
irqpin1: interrupt-controller@e6900004 {
compatible = "renesas,intc-irqpin-r8a7740",
"renesas,intc-irqpin";
#interrupt-cells = <2>;
interrupt-controller;
reg = <0xe6900004 4>,
<0xe6900014 4>,
<0xe6900024 1>,
<0xe6900044 1>,
<0xe6900064 1>;
interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH
0 149 IRQ_TYPE_LEVEL_HIGH
0 149 IRQ_TYPE_LEVEL_HIGH
0 149 IRQ_TYPE_LEVEL_HIGH
0 149 IRQ_TYPE_LEVEL_HIGH
0 149 IRQ_TYPE_LEVEL_HIGH
0 149 IRQ_TYPE_LEVEL_HIGH
0 149 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp2_clks R8A7740_CLK_INTCA>;
power-domains = <&pd_a4s>;
};
...@@ -501,8 +501,8 @@ static int sa1111_setup_irq(struct sa1111 *sachip, unsigned irq_base) ...@@ -501,8 +501,8 @@ static int sa1111_setup_irq(struct sa1111 *sachip, unsigned irq_base)
* Register SA1111 interrupt * Register SA1111 interrupt
*/ */
irq_set_irq_type(sachip->irq, IRQ_TYPE_EDGE_RISING); irq_set_irq_type(sachip->irq, IRQ_TYPE_EDGE_RISING);
irq_set_handler_data(sachip->irq, sachip); irq_set_chained_handler_and_data(sachip->irq, sa1111_irq_handler,
irq_set_chained_handler(sachip->irq, sa1111_irq_handler); sachip);
dev_info(sachip->dev, "Providing IRQ%u-%u\n", dev_info(sachip->dev, "Providing IRQ%u-%u\n",
sachip->irq_base, sachip->irq_base + SA1111_IRQ_NR - 1); sachip->irq_base, sachip->irq_base + SA1111_IRQ_NR - 1);
...@@ -836,8 +836,7 @@ static void __sa1111_remove(struct sa1111 *sachip) ...@@ -836,8 +836,7 @@ static void __sa1111_remove(struct sa1111 *sachip)
clk_unprepare(sachip->clk); clk_unprepare(sachip->clk);
if (sachip->irq != NO_IRQ) { if (sachip->irq != NO_IRQ) {
irq_set_chained_handler(sachip->irq, NULL); irq_set_chained_handler_and_data(sachip->irq, NULL, NULL);
irq_set_handler_data(sachip->irq, NULL);
irq_free_descs(sachip->irq_base, SA1111_IRQ_NR); irq_free_descs(sachip->irq_base, SA1111_IRQ_NR);
release_mem_region(sachip->phys + SA1111_INTC, 512); release_mem_region(sachip->phys + SA1111_INTC, 512);
......
...@@ -223,8 +223,8 @@ void __init gemini_gpio_init(void) ...@@ -223,8 +223,8 @@ void __init gemini_gpio_init(void)
set_irq_flags(j, IRQF_VALID); set_irq_flags(j, IRQF_VALID);
} }
irq_set_chained_handler(IRQ_GPIO(i), gpio_irq_handler); irq_set_chained_handler_and_data(IRQ_GPIO(i), gpio_irq_handler,
irq_set_handler_data(IRQ_GPIO(i), (void *)i); (void *)i);
} }
BUG_ON(gpiochip_add(&gemini_gpio_chip)); BUG_ON(gpiochip_add(&gemini_gpio_chip));
......
...@@ -327,8 +327,7 @@ static int neponset_probe(struct platform_device *dev) ...@@ -327,8 +327,7 @@ static int neponset_probe(struct platform_device *dev)
irq_set_chip(d->irq_base + NEP_IRQ_SA1111, &nochip); irq_set_chip(d->irq_base + NEP_IRQ_SA1111, &nochip);
irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING); irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING);
irq_set_handler_data(irq, d); irq_set_chained_handler_and_data(irq, neponset_irq_handler, d);
irq_set_chained_handler(irq, neponset_irq_handler);
/* /*
* We would set IRQ_GPIO25 to be a wake-up IRQ, but unfortunately * We would set IRQ_GPIO25 to be a wake-up IRQ, but unfortunately
......
...@@ -437,14 +437,13 @@ static int mxc_gpio_probe(struct platform_device *pdev) ...@@ -437,14 +437,13 @@ static int mxc_gpio_probe(struct platform_device *pdev)
irq_set_chained_handler(port->irq, mx2_gpio_irq_handler); irq_set_chained_handler(port->irq, mx2_gpio_irq_handler);
} else { } else {
/* setup one handler for each entry */ /* setup one handler for each entry */
irq_set_chained_handler(port->irq, mx3_gpio_irq_handler); irq_set_chained_handler_and_data(port->irq,
irq_set_handler_data(port->irq, port); mx3_gpio_irq_handler, port);
if (port->irq_high > 0) { if (port->irq_high > 0)
/* setup handler for GPIO 16 to 31 */ /* setup handler for GPIO 16 to 31 */
irq_set_chained_handler(port->irq_high, irq_set_chained_handler_and_data(port->irq_high,
mx3_gpio_irq_handler); mx3_gpio_irq_handler,
irq_set_handler_data(port->irq_high, port); port);
}
} }
err = bgpio_init(&port->bgc, &pdev->dev, 4, err = bgpio_init(&port->bgc, &pdev->dev, 4,
......
...@@ -320,8 +320,8 @@ static int mxs_gpio_probe(struct platform_device *pdev) ...@@ -320,8 +320,8 @@ static int mxs_gpio_probe(struct platform_device *pdev)
mxs_gpio_init_gc(port, irq_base); mxs_gpio_init_gc(port, irq_base);
/* setup one handler for each entry */ /* setup one handler for each entry */
irq_set_chained_handler(port->irq, mxs_gpio_irq_handler); irq_set_chained_handler_and_data(port->irq, mxs_gpio_irq_handler,
irq_set_handler_data(port->irq, port); port);
err = bgpio_init(&port->bgc, &pdev->dev, 4, err = bgpio_init(&port->bgc, &pdev->dev, 4,
port->base + PINCTRL_DIN(port), port->base + PINCTRL_DIN(port),
......
...@@ -515,8 +515,8 @@ static int tegra_gpio_probe(struct platform_device *pdev) ...@@ -515,8 +515,8 @@ static int tegra_gpio_probe(struct platform_device *pdev)
for (i = 0; i < tegra_gpio_bank_count; i++) { for (i = 0; i < tegra_gpio_bank_count; i++) {
bank = &tegra_gpio_banks[i]; bank = &tegra_gpio_banks[i];
irq_set_chained_handler(bank->irq, tegra_gpio_irq_handler); irq_set_chained_handler_and_data(bank->irq,
irq_set_handler_data(bank->irq, bank); tegra_gpio_irq_handler, bank);
for (j = 0; j < 4; j++) for (j = 0; j < 4; j++)
spin_lock_init(&bank->lvl_lock[j]); spin_lock_init(&bank->lvl_lock[j]);
......
...@@ -1119,10 +1119,9 @@ static int ipu_irq_init(struct ipu_soc *ipu) ...@@ -1119,10 +1119,9 @@ static int ipu_irq_init(struct ipu_soc *ipu)
ct->regs.mask = IPU_INT_CTRL(i / 32); ct->regs.mask = IPU_INT_CTRL(i / 32);
} }
irq_set_chained_handler(ipu->irq_sync, ipu_irq_handler); irq_set_chained_handler_and_data(ipu->irq_sync, ipu_irq_handler, ipu);
irq_set_handler_data(ipu->irq_sync, ipu); irq_set_chained_handler_and_data(ipu->irq_err, ipu_err_irq_handler,
irq_set_chained_handler(ipu->irq_err, ipu_err_irq_handler); ipu);
irq_set_handler_data(ipu->irq_err, ipu);
return 0; return 0;
} }
...@@ -1131,10 +1130,8 @@ static void ipu_irq_exit(struct ipu_soc *ipu) ...@@ -1131,10 +1130,8 @@ static void ipu_irq_exit(struct ipu_soc *ipu)
{ {
int i, irq; int i, irq;
irq_set_chained_handler(ipu->irq_err, NULL); irq_set_chained_handler_and_data(ipu->irq_err, NULL, NULL);
irq_set_handler_data(ipu->irq_err, NULL); irq_set_chained_handler_and_data(ipu->irq_sync, NULL, NULL);
irq_set_chained_handler(ipu->irq_sync, NULL);
irq_set_handler_data(ipu->irq_sync, NULL);
/* TODO: remove irq_domain_generic_chips */ /* TODO: remove irq_domain_generic_chips */
......
...@@ -30,6 +30,7 @@ config ARM_GIC_V3_ITS ...@@ -30,6 +30,7 @@ config ARM_GIC_V3_ITS
config ARM_NVIC config ARM_NVIC
bool bool
select IRQ_DOMAIN select IRQ_DOMAIN
select IRQ_DOMAIN_HIERARCHY
select GENERIC_IRQ_CHIP select GENERIC_IRQ_CHIP
config ARM_VIC config ARM_VIC
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/syscore_ops.h>
#include <linux/irqdomain.h> #include <linux/irqdomain.h>
#include <linux/irqchip/chained_irq.h> #include <linux/irqchip/chained_irq.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
...@@ -34,9 +35,14 @@ struct combiner_chip_data { ...@@ -34,9 +35,14 @@ struct combiner_chip_data {
unsigned int irq_mask; unsigned int irq_mask;
void __iomem *base; void __iomem *base;
unsigned int parent_irq; unsigned int parent_irq;
#ifdef CONFIG_PM
u32 pm_save;
#endif
}; };
static struct combiner_chip_data *combiner_data;
static struct irq_domain *combiner_irq_domain; static struct irq_domain *combiner_irq_domain;
static unsigned int max_nr = 20;
static inline void __iomem *combiner_base(struct irq_data *data) static inline void __iomem *combiner_base(struct irq_data *data)
{ {
...@@ -164,18 +170,16 @@ static int combiner_irq_domain_map(struct irq_domain *d, unsigned int irq, ...@@ -164,18 +170,16 @@ static int combiner_irq_domain_map(struct irq_domain *d, unsigned int irq,
return 0; return 0;
} }
static struct irq_domain_ops combiner_irq_domain_ops = { static const struct irq_domain_ops combiner_irq_domain_ops = {
.xlate = combiner_irq_domain_xlate, .xlate = combiner_irq_domain_xlate,
.map = combiner_irq_domain_map, .map = combiner_irq_domain_map,
}; };
static void __init combiner_init(void __iomem *combiner_base, static void __init combiner_init(void __iomem *combiner_base,
struct device_node *np, struct device_node *np)
unsigned int max_nr)
{ {
int i, irq; int i, irq;
unsigned int nr_irq; unsigned int nr_irq;
struct combiner_chip_data *combiner_data;
nr_irq = max_nr * IRQ_IN_COMBINER; nr_irq = max_nr * IRQ_IN_COMBINER;
...@@ -201,11 +205,59 @@ static void __init combiner_init(void __iomem *combiner_base, ...@@ -201,11 +205,59 @@ static void __init combiner_init(void __iomem *combiner_base,
} }
} }
#ifdef CONFIG_PM
/**
* combiner_suspend - save interrupt combiner state before suspend
*
* Save the interrupt enable set register for all combiner groups since
* the state is lost when the system enters into a sleep state.
*
*/
static int combiner_suspend(void)
{
int i;
for (i = 0; i < max_nr; i++)
combiner_data[i].pm_save =
__raw_readl(combiner_data[i].base + COMBINER_ENABLE_SET);
return 0;
}
/**
* combiner_resume - restore interrupt combiner state after resume
*
* Restore the interrupt enable set register for all combiner groups since
* the state is lost when the system enters into a sleep state on suspend.
*
*/
static void combiner_resume(void)
{
int i;
for (i = 0; i < max_nr; i++) {
__raw_writel(combiner_data[i].irq_mask,
combiner_data[i].base + COMBINER_ENABLE_CLEAR);
__raw_writel(combiner_data[i].pm_save,
combiner_data[i].base + COMBINER_ENABLE_SET);
}
}
#else
#define combiner_suspend NULL
#define combiner_resume NULL
#endif
static struct syscore_ops combiner_syscore_ops = {
.suspend = combiner_suspend,
.resume = combiner_resume,
};
static int __init combiner_of_init(struct device_node *np, static int __init combiner_of_init(struct device_node *np,
struct device_node *parent) struct device_node *parent)
{ {
void __iomem *combiner_base; void __iomem *combiner_base;
unsigned int max_nr = 20;
combiner_base = of_iomap(np, 0); combiner_base = of_iomap(np, 0);
if (!combiner_base) { if (!combiner_base) {
...@@ -219,7 +271,9 @@ static int __init combiner_of_init(struct device_node *np, ...@@ -219,7 +271,9 @@ static int __init combiner_of_init(struct device_node *np,
__func__, max_nr); __func__, max_nr);
} }
combiner_init(combiner_base, np, max_nr); combiner_init(combiner_base, np);
register_syscore_ops(&combiner_syscore_ops);
return 0; return 0;
} }
......
...@@ -409,7 +409,7 @@ static struct notifier_block mpic_cascaded_cpu_notifier = { ...@@ -409,7 +409,7 @@ static struct notifier_block mpic_cascaded_cpu_notifier = {
}; };
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
static struct irq_domain_ops armada_370_xp_mpic_irq_ops = { static const struct irq_domain_ops armada_370_xp_mpic_irq_ops = {
.map = armada_370_xp_mpic_irq_map, .map = armada_370_xp_mpic_irq_map,
.xlate = irq_domain_xlate_onecell, .xlate = irq_domain_xlate_onecell,
}; };
......
...@@ -339,6 +339,15 @@ static int __init aic5_of_init(struct device_node *node, ...@@ -339,6 +339,15 @@ static int __init aic5_of_init(struct device_node *node,
return 0; return 0;
} }
#define NR_SAMA5D2_IRQS 77
static int __init sama5d2_aic5_of_init(struct device_node *node,
struct device_node *parent)
{
return aic5_of_init(node, parent, NR_SAMA5D2_IRQS);
}
IRQCHIP_DECLARE(sama5d2_aic5, "atmel,sama5d2-aic", sama5d2_aic5_of_init);
#define NR_SAMA5D3_IRQS 48 #define NR_SAMA5D3_IRQS 48
static int __init sama5d3_aic5_of_init(struct device_node *node, static int __init sama5d3_aic5_of_init(struct device_node *node,
......
...@@ -135,7 +135,7 @@ static int armctrl_xlate(struct irq_domain *d, struct device_node *ctrlr, ...@@ -135,7 +135,7 @@ static int armctrl_xlate(struct irq_domain *d, struct device_node *ctrlr,
return 0; return 0;
} }
static struct irq_domain_ops armctrl_ops = { static const struct irq_domain_ops armctrl_ops = {
.xlate = armctrl_xlate .xlate = armctrl_xlate
}; };
......
...@@ -24,11 +24,8 @@ ...@@ -24,11 +24,8 @@
int gic_configure_irq(unsigned int irq, unsigned int type, int gic_configure_irq(unsigned int irq, unsigned int type,
void __iomem *base, void (*sync_access)(void)) void __iomem *base, void (*sync_access)(void))
{ {
u32 enablemask = 1 << (irq % 32);
u32 enableoff = (irq / 32) * 4;
u32 confmask = 0x2 << ((irq % 16) * 2); u32 confmask = 0x2 << ((irq % 16) * 2);
u32 confoff = (irq / 16) * 4; u32 confoff = (irq / 16) * 4;
bool enabled = false;
u32 val, oldval; u32 val, oldval;
int ret = 0; int ret = 0;
...@@ -42,17 +39,6 @@ int gic_configure_irq(unsigned int irq, unsigned int type, ...@@ -42,17 +39,6 @@ int gic_configure_irq(unsigned int irq, unsigned int type,
else if (type & IRQ_TYPE_EDGE_BOTH) else if (type & IRQ_TYPE_EDGE_BOTH)
val |= confmask; val |= confmask;
/*
* As recommended by the spec, disable the interrupt before changing
* the configuration
*/
if (readl_relaxed(base + GIC_DIST_ENABLE_SET + enableoff) & enablemask) {
writel_relaxed(enablemask, base + GIC_DIST_ENABLE_CLEAR + enableoff);
if (sync_access)
sync_access();
enabled = true;
}
/* /*
* Write back the new configuration, and possibly re-enable * Write back the new configuration, and possibly re-enable
* the interrupt. If we tried to write a new configuration and failed, * the interrupt. If we tried to write a new configuration and failed,
...@@ -62,9 +48,6 @@ int gic_configure_irq(unsigned int irq, unsigned int type, ...@@ -62,9 +48,6 @@ int gic_configure_irq(unsigned int irq, unsigned int type,
if (readl_relaxed(base + GIC_DIST_CONFIG + confoff) != val && val != oldval) if (readl_relaxed(base + GIC_DIST_CONFIG + confoff) != val && val != oldval)
ret = -EINVAL; ret = -EINVAL;
if (enabled)
writel_relaxed(enablemask, base + GIC_DIST_ENABLE_SET + enableoff);
if (sync_access) if (sync_access)
sync_access(); sync_access();
......
...@@ -658,6 +658,7 @@ static struct irq_chip gic_chip = { ...@@ -658,6 +658,7 @@ static struct irq_chip gic_chip = {
.irq_set_affinity = gic_set_affinity, .irq_set_affinity = gic_set_affinity,
.irq_get_irqchip_state = gic_irq_get_irqchip_state, .irq_get_irqchip_state = gic_irq_get_irqchip_state,
.irq_set_irqchip_state = gic_irq_set_irqchip_state, .irq_set_irqchip_state = gic_irq_set_irqchip_state,
.flags = IRQCHIP_SET_TYPE_MASKED,
}; };
#define GIC_ID_NR (1U << gic_data.rdists.id_bits) #define GIC_ID_NR (1U << gic_data.rdists.id_bits)
......
...@@ -324,6 +324,7 @@ static struct irq_chip gic_chip = { ...@@ -324,6 +324,7 @@ static struct irq_chip gic_chip = {
#endif #endif
.irq_get_irqchip_state = gic_irq_get_irqchip_state, .irq_get_irqchip_state = gic_irq_get_irqchip_state,
.irq_set_irqchip_state = gic_irq_set_irqchip_state, .irq_set_irqchip_state = gic_irq_set_irqchip_state,
.flags = IRQCHIP_SET_TYPE_MASKED,
}; };
void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq) void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
......
...@@ -202,6 +202,7 @@ static struct irq_chip hip04_irq_chip = { ...@@ -202,6 +202,7 @@ static struct irq_chip hip04_irq_chip = {
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
.irq_set_affinity = hip04_irq_set_affinity, .irq_set_affinity = hip04_irq_set_affinity,
#endif #endif
.flags = IRQCHIP_SET_TYPE_MASKED,
}; };
static u16 hip04_get_cpumask(struct hip04_irq_data *intc) static u16 hip04_get_cpumask(struct hip04_irq_data *intc)
......
...@@ -131,7 +131,7 @@ static int keystone_irq_map(struct irq_domain *h, unsigned int virq, ...@@ -131,7 +131,7 @@ static int keystone_irq_map(struct irq_domain *h, unsigned int virq,
return 0; return 0;
} }
static struct irq_domain_ops keystone_irq_ops = { static const struct irq_domain_ops keystone_irq_ops = {
.map = keystone_irq_map, .map = keystone_irq_map,
.xlate = irq_domain_xlate_onecell, .xlate = irq_domain_xlate_onecell,
}; };
...@@ -184,8 +184,7 @@ static int keystone_irq_probe(struct platform_device *pdev) ...@@ -184,8 +184,7 @@ static int keystone_irq_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, kirq); platform_set_drvdata(pdev, kirq);
irq_set_chained_handler(kirq->irq, keystone_irq_handler); irq_set_chained_handler_and_data(kirq->irq, keystone_irq_handler, kirq);
irq_set_handler_data(kirq->irq, kirq);
/* clear all source bits */ /* clear all source bits */
keystone_irq_writel(kirq, ~0x0); keystone_irq_writel(kirq, ~0x0);
......
...@@ -746,7 +746,7 @@ static int gic_irq_domain_xlate(struct irq_domain *d, struct device_node *ctrlr, ...@@ -746,7 +746,7 @@ static int gic_irq_domain_xlate(struct irq_domain *d, struct device_node *ctrlr,
return 0; return 0;
} }
static struct irq_domain_ops gic_irq_domain_ops = { static const struct irq_domain_ops gic_irq_domain_ops = {
.map = gic_irq_domain_map, .map = gic_irq_domain_map,
.xlate = gic_irq_domain_xlate, .xlate = gic_irq_domain_xlate,
}; };
......
...@@ -111,7 +111,7 @@ static int mtk_sysirq_domain_alloc(struct irq_domain *domain, unsigned int virq, ...@@ -111,7 +111,7 @@ static int mtk_sysirq_domain_alloc(struct irq_domain *domain, unsigned int virq,
return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &gic_data); return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &gic_data);
} }
static struct irq_domain_ops sysirq_domain_ops = { static const struct irq_domain_ops sysirq_domain_ops = {
.xlate = mtk_sysirq_domain_xlate, .xlate = mtk_sysirq_domain_xlate,
.alloc = mtk_sysirq_domain_alloc, .alloc = mtk_sysirq_domain_alloc,
.free = irq_domain_free_irqs_common, .free = irq_domain_free_irqs_common,
...@@ -144,7 +144,7 @@ static int __init mtk_sysirq_of_init(struct device_node *node, ...@@ -144,7 +144,7 @@ static int __init mtk_sysirq_of_init(struct device_node *node,
chip_data->intpol_base = ioremap(res.start, size); chip_data->intpol_base = ioremap(res.start, size);
if (!chip_data->intpol_base) { if (!chip_data->intpol_base) {
pr_err("mtk_sysirq: unable to map sysirq register\n"); pr_err("mtk_sysirq: unable to map sysirq register\n");
ret = PTR_ERR(chip_data->intpol_base); ret = -ENXIO;
goto out_free; goto out_free;
} }
......
...@@ -90,7 +90,7 @@ static int icoll_irq_domain_map(struct irq_domain *d, unsigned int virq, ...@@ -90,7 +90,7 @@ static int icoll_irq_domain_map(struct irq_domain *d, unsigned int virq,
return 0; return 0;
} }
static struct irq_domain_ops icoll_irq_domain_ops = { static const struct irq_domain_ops icoll_irq_domain_ops = {
.map = icoll_irq_domain_map, .map = icoll_irq_domain_map,
.xlate = irq_domain_xlate_onecell, .xlate = irq_domain_xlate_onecell,
}; };
......
...@@ -49,6 +49,31 @@ nvic_handle_irq(irq_hw_number_t hwirq, struct pt_regs *regs) ...@@ -49,6 +49,31 @@ nvic_handle_irq(irq_hw_number_t hwirq, struct pt_regs *regs)
handle_IRQ(irq, regs); handle_IRQ(irq, regs);
} }
static int nvic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
unsigned int nr_irqs, void *arg)
{
int i, ret;
irq_hw_number_t hwirq;
unsigned int type = IRQ_TYPE_NONE;
struct of_phandle_args *irq_data = arg;
ret = irq_domain_xlate_onecell(domain, irq_data->np, irq_data->args,
irq_data->args_count, &hwirq, &type);
if (ret)
return ret;
for (i = 0; i < nr_irqs; i++)
irq_map_generic_chip(domain, virq + i, hwirq + i);
return 0;
}
static const struct irq_domain_ops nvic_irq_domain_ops = {
.xlate = irq_domain_xlate_onecell,
.alloc = nvic_irq_domain_alloc,
.free = irq_domain_free_irqs_top,
};
static int __init nvic_of_init(struct device_node *node, static int __init nvic_of_init(struct device_node *node,
struct device_node *parent) struct device_node *parent)
{ {
...@@ -70,7 +95,8 @@ static int __init nvic_of_init(struct device_node *node, ...@@ -70,7 +95,8 @@ static int __init nvic_of_init(struct device_node *node,
irqs = NVIC_MAX_IRQ; irqs = NVIC_MAX_IRQ;
nvic_irq_domain = nvic_irq_domain =
irq_domain_add_linear(node, irqs, &irq_generic_chip_ops, NULL); irq_domain_add_linear(node, irqs, &nvic_irq_domain_ops, NULL);
if (!nvic_irq_domain) { if (!nvic_irq_domain) {
pr_warn("Failed to allocate irq domain\n"); pr_warn("Failed to allocate irq domain\n");
return -ENOMEM; return -ENOMEM;
......
...@@ -347,7 +347,7 @@ static int intc_irqpin_irq_domain_map(struct irq_domain *h, unsigned int virq, ...@@ -347,7 +347,7 @@ static int intc_irqpin_irq_domain_map(struct irq_domain *h, unsigned int virq,
return 0; return 0;
} }
static struct irq_domain_ops intc_irqpin_irq_domain_ops = { static const struct irq_domain_ops intc_irqpin_irq_domain_ops = {
.map = intc_irqpin_irq_domain_map, .map = intc_irqpin_irq_domain_map,
.xlate = irq_domain_xlate_twocell, .xlate = irq_domain_xlate_twocell,
}; };
......
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_data/irq-renesas-irqc.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#define IRQC_IRQ_MAX 32 /* maximum 32 interrupts per driver instance */ #define IRQC_IRQ_MAX 32 /* maximum 32 interrupts per driver instance */
...@@ -62,7 +61,6 @@ struct irqc_priv { ...@@ -62,7 +61,6 @@ struct irqc_priv {
void __iomem *iomem; void __iomem *iomem;
void __iomem *cpu_int_base; void __iomem *cpu_int_base;
struct irqc_irq irq[IRQC_IRQ_MAX]; struct irqc_irq irq[IRQC_IRQ_MAX];
struct renesas_irqc_config config;
unsigned int number_of_irqs; unsigned int number_of_irqs;
struct platform_device *pdev; struct platform_device *pdev;
struct irq_chip irq_chip; struct irq_chip irq_chip;
...@@ -168,14 +166,13 @@ static int irqc_irq_domain_map(struct irq_domain *h, unsigned int virq, ...@@ -168,14 +166,13 @@ static int irqc_irq_domain_map(struct irq_domain *h, unsigned int virq,
return 0; return 0;
} }
static struct irq_domain_ops irqc_irq_domain_ops = { static const struct irq_domain_ops irqc_irq_domain_ops = {
.map = irqc_irq_domain_map, .map = irqc_irq_domain_map,
.xlate = irq_domain_xlate_twocell, .xlate = irq_domain_xlate_twocell,
}; };
static int irqc_probe(struct platform_device *pdev) static int irqc_probe(struct platform_device *pdev)
{ {
struct renesas_irqc_config *pdata = pdev->dev.platform_data;
struct irqc_priv *p; struct irqc_priv *p;
struct resource *io; struct resource *io;
struct resource *irq; struct resource *irq;
...@@ -191,10 +188,6 @@ static int irqc_probe(struct platform_device *pdev) ...@@ -191,10 +188,6 @@ static int irqc_probe(struct platform_device *pdev)
goto err0; goto err0;
} }
/* deal with driver instance configuration */
if (pdata)
memcpy(&p->config, pdata, sizeof(*pdata));
p->pdev = pdev; p->pdev = pdev;
platform_set_drvdata(pdev, p); platform_set_drvdata(pdev, p);
...@@ -251,8 +244,7 @@ static int irqc_probe(struct platform_device *pdev) ...@@ -251,8 +244,7 @@ static int irqc_probe(struct platform_device *pdev)
irq_chip->flags = IRQCHIP_MASK_ON_SUSPEND; irq_chip->flags = IRQCHIP_MASK_ON_SUSPEND;
p->irq_domain = irq_domain_add_simple(pdev->dev.of_node, p->irq_domain = irq_domain_add_simple(pdev->dev.of_node,
p->number_of_irqs, p->number_of_irqs, 0,
p->config.irq_base,
&irqc_irq_domain_ops, p); &irqc_irq_domain_ops, p);
if (!p->irq_domain) { if (!p->irq_domain) {
ret = -ENXIO; ret = -ENXIO;
...@@ -272,13 +264,6 @@ static int irqc_probe(struct platform_device *pdev) ...@@ -272,13 +264,6 @@ static int irqc_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "driving %d irqs\n", p->number_of_irqs); dev_info(&pdev->dev, "driving %d irqs\n", p->number_of_irqs);
/* warn in case of mismatch if irq base is specified */
if (p->config.irq_base) {
if (p->config.irq_base != p->irq[0].domain_irq)
dev_warn(&pdev->dev, "irq base mismatch (%d/%d)\n",
p->config.irq_base, p->irq[0].domain_irq);
}
return 0; return 0;
err3: err3:
while (--k >= 0) while (--k >= 0)
......
...@@ -502,7 +502,7 @@ static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq, ...@@ -502,7 +502,7 @@ static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq,
return -EINVAL; return -EINVAL;
} }
static struct irq_domain_ops s3c24xx_irq_ops = { static const struct irq_domain_ops s3c24xx_irq_ops = {
.map = s3c24xx_irq_map, .map = s3c24xx_irq_map,
.xlate = irq_domain_xlate_twocell, .xlate = irq_domain_xlate_twocell,
}; };
...@@ -1228,7 +1228,7 @@ static int s3c24xx_irq_xlate_of(struct irq_domain *d, struct device_node *n, ...@@ -1228,7 +1228,7 @@ static int s3c24xx_irq_xlate_of(struct irq_domain *d, struct device_node *n,
return 0; return 0;
} }
static struct irq_domain_ops s3c24xx_irq_ops_of = { static const struct irq_domain_ops s3c24xx_irq_ops_of = {
.map = s3c24xx_irq_map_of, .map = s3c24xx_irq_map_of,
.xlate = s3c24xx_irq_xlate_of, .xlate = s3c24xx_irq_xlate_of,
}; };
......
...@@ -89,7 +89,7 @@ static int sun4i_irq_map(struct irq_domain *d, unsigned int virq, ...@@ -89,7 +89,7 @@ static int sun4i_irq_map(struct irq_domain *d, unsigned int virq,
return 0; return 0;
} }
static struct irq_domain_ops sun4i_irq_ops = { static const struct irq_domain_ops sun4i_irq_ops = {
.map = sun4i_irq_map, .map = sun4i_irq_map,
.xlate = irq_domain_xlate_onecell, .xlate = irq_domain_xlate_onecell,
}; };
......
...@@ -132,7 +132,7 @@ static int fpga_irqdomain_map(struct irq_domain *d, unsigned int irq, ...@@ -132,7 +132,7 @@ static int fpga_irqdomain_map(struct irq_domain *d, unsigned int irq,
return 0; return 0;
} }
static struct irq_domain_ops fpga_irqdomain_ops = { static const struct irq_domain_ops fpga_irqdomain_ops = {
.map = fpga_irqdomain_map, .map = fpga_irqdomain_map,
.xlate = irq_domain_xlate_onetwocell, .xlate = irq_domain_xlate_onetwocell,
}; };
......
...@@ -47,6 +47,7 @@ struct vf610_mscm_ir_chip_data { ...@@ -47,6 +47,7 @@ struct vf610_mscm_ir_chip_data {
void __iomem *mscm_ir_base; void __iomem *mscm_ir_base;
u16 cpu_mask; u16 cpu_mask;
u16 saved_irsprc[MSCM_IRSPRC_NUM]; u16 saved_irsprc[MSCM_IRSPRC_NUM];
bool is_nvic;
}; };
static struct vf610_mscm_ir_chip_data *mscm_ir_data; static struct vf610_mscm_ir_chip_data *mscm_ir_data;
...@@ -101,7 +102,7 @@ static void vf610_mscm_ir_enable(struct irq_data *data) ...@@ -101,7 +102,7 @@ static void vf610_mscm_ir_enable(struct irq_data *data)
writew_relaxed(chip_data->cpu_mask, writew_relaxed(chip_data->cpu_mask,
chip_data->mscm_ir_base + MSCM_IRSPRC(hwirq)); chip_data->mscm_ir_base + MSCM_IRSPRC(hwirq));
irq_chip_unmask_parent(data); irq_chip_enable_parent(data);
} }
static void vf610_mscm_ir_disable(struct irq_data *data) static void vf610_mscm_ir_disable(struct irq_data *data)
...@@ -111,7 +112,7 @@ static void vf610_mscm_ir_disable(struct irq_data *data) ...@@ -111,7 +112,7 @@ static void vf610_mscm_ir_disable(struct irq_data *data)
writew_relaxed(0x0, chip_data->mscm_ir_base + MSCM_IRSPRC(hwirq)); writew_relaxed(0x0, chip_data->mscm_ir_base + MSCM_IRSPRC(hwirq));
irq_chip_mask_parent(data); irq_chip_disable_parent(data);
} }
static struct irq_chip vf610_mscm_ir_irq_chip = { static struct irq_chip vf610_mscm_ir_irq_chip = {
...@@ -143,10 +144,17 @@ static int vf610_mscm_ir_domain_alloc(struct irq_domain *domain, unsigned int vi ...@@ -143,10 +144,17 @@ static int vf610_mscm_ir_domain_alloc(struct irq_domain *domain, unsigned int vi
domain->host_data); domain->host_data);
gic_data.np = domain->parent->of_node; gic_data.np = domain->parent->of_node;
gic_data.args_count = 3;
gic_data.args[0] = GIC_SPI; if (mscm_ir_data->is_nvic) {
gic_data.args[1] = irq_data->args[0]; gic_data.args_count = 1;
gic_data.args[2] = irq_data->args[1]; gic_data.args[0] = irq_data->args[0];
} else {
gic_data.args_count = 3;
gic_data.args[0] = GIC_SPI;
gic_data.args[1] = irq_data->args[0];
gic_data.args[2] = irq_data->args[1];
}
return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &gic_data); return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &gic_data);
} }
...@@ -174,10 +182,9 @@ static int __init vf610_mscm_ir_of_init(struct device_node *node, ...@@ -174,10 +182,9 @@ static int __init vf610_mscm_ir_of_init(struct device_node *node,
return -ENOMEM; return -ENOMEM;
mscm_ir_data->mscm_ir_base = of_io_request_and_map(node, 0, "mscm-ir"); mscm_ir_data->mscm_ir_base = of_io_request_and_map(node, 0, "mscm-ir");
if (IS_ERR(mscm_ir_data->mscm_ir_base)) {
if (!mscm_ir_data->mscm_ir_base) {
pr_err("vf610_mscm_ir: unable to map mscm register\n"); pr_err("vf610_mscm_ir: unable to map mscm register\n");
ret = -ENOMEM; ret = PTR_ERR(mscm_ir_data->mscm_ir_base);
goto out_free; goto out_free;
} }
...@@ -199,6 +206,9 @@ static int __init vf610_mscm_ir_of_init(struct device_node *node, ...@@ -199,6 +206,9 @@ static int __init vf610_mscm_ir_of_init(struct device_node *node,
goto out_unmap; goto out_unmap;
} }
if (of_device_is_compatible(domain->parent->of_node, "arm,armv7m-nvic"))
mscm_ir_data->is_nvic = true;
cpu_pm_register_notifier(&mscm_ir_notifier_block); cpu_pm_register_notifier(&mscm_ir_notifier_block);
return 0; return 0;
......
...@@ -256,7 +256,7 @@ static void __exception_irq_entry vic_handle_irq(struct pt_regs *regs) ...@@ -256,7 +256,7 @@ static void __exception_irq_entry vic_handle_irq(struct pt_regs *regs)
} while (handled); } while (handled);
} }
static struct irq_domain_ops vic_irqdomain_ops = { static const struct irq_domain_ops vic_irqdomain_ops = {
.map = vic_irqdomain_map, .map = vic_irqdomain_map,
.xlate = irq_domain_xlate_onetwocell, .xlate = irq_domain_xlate_onetwocell,
}; };
......
...@@ -173,7 +173,7 @@ static int vt8500_irq_map(struct irq_domain *h, unsigned int virq, ...@@ -173,7 +173,7 @@ static int vt8500_irq_map(struct irq_domain *h, unsigned int virq,
return 0; return 0;
} }
static struct irq_domain_ops vt8500_irq_domain_ops = { static const struct irq_domain_ops vt8500_irq_domain_ops = {
.map = vt8500_irq_map, .map = vt8500_irq_map,
.xlate = irq_domain_xlate_onecell, .xlate = irq_domain_xlate_onecell,
}; };
......
...@@ -207,8 +207,7 @@ static void __init spear_shirq_register(struct spear_shirq *shirq, ...@@ -207,8 +207,7 @@ static void __init spear_shirq_register(struct spear_shirq *shirq,
if (!shirq->irq_chip) if (!shirq->irq_chip)
return; return;
irq_set_chained_handler(parent_irq, shirq_handler); irq_set_chained_handler_and_data(parent_irq, shirq_handler, shirq);
irq_set_handler_data(parent_irq, shirq);
for (i = 0; i < shirq->nr_irqs; i++) { for (i = 0; i < shirq->nr_irqs; i++) {
irq_set_chip_and_handler(shirq->virq_base + i, irq_set_chip_and_handler(shirq->virq_base + i,
......
...@@ -566,8 +566,7 @@ static int ucb1x00_probe(struct mcp *mcp) ...@@ -566,8 +566,7 @@ static int ucb1x00_probe(struct mcp *mcp)
} }
irq_set_irq_type(ucb->irq, IRQ_TYPE_EDGE_RISING); irq_set_irq_type(ucb->irq, IRQ_TYPE_EDGE_RISING);
irq_set_handler_data(ucb->irq, ucb); irq_set_chained_handler_and_data(ucb->irq, ucb1x00_irq, ucb);
irq_set_chained_handler(ucb->irq, ucb1x00_irq);
if (pdata && pdata->gpio_base) { if (pdata && pdata->gpio_base) {
ucb->gpio.label = dev_name(&ucb->dev); ucb->gpio.label = dev_name(&ucb->dev);
......
...@@ -126,13 +126,21 @@ struct msi_desc; ...@@ -126,13 +126,21 @@ struct msi_desc;
struct irq_domain; struct irq_domain;
/** /**
* struct irq_data - per irq and irq chip data passed down to chip functions * struct irq_common_data - per irq data shared by all irqchips
* @state_use_accessors: status information for irq chip functions.
* Use accessor functions to deal with it
*/
struct irq_common_data {
unsigned int state_use_accessors;
};
/**
* struct irq_data - per irq chip data passed down to chip functions
* @mask: precomputed bitmask for accessing the chip registers * @mask: precomputed bitmask for accessing the chip registers
* @irq: interrupt number * @irq: interrupt number
* @hwirq: hardware interrupt number, local to the interrupt domain * @hwirq: hardware interrupt number, local to the interrupt domain
* @node: node index useful for balancing * @node: node index useful for balancing
* @state_use_accessors: status information for irq chip functions. * @common: point to data shared by all irqchips
* Use accessor functions to deal with it
* @chip: low level interrupt hardware access * @chip: low level interrupt hardware access
* @domain: Interrupt translation domain; responsible for mapping * @domain: Interrupt translation domain; responsible for mapping
* between hwirq number and linux irq number. * between hwirq number and linux irq number.
...@@ -153,7 +161,7 @@ struct irq_data { ...@@ -153,7 +161,7 @@ struct irq_data {
unsigned int irq; unsigned int irq;
unsigned long hwirq; unsigned long hwirq;
unsigned int node; unsigned int node;
unsigned int state_use_accessors; struct irq_common_data *common;
struct irq_chip *chip; struct irq_chip *chip;
struct irq_domain *domain; struct irq_domain *domain;
#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
...@@ -166,7 +174,7 @@ struct irq_data { ...@@ -166,7 +174,7 @@ struct irq_data {
}; };
/* /*
* Bit masks for irq_data.state * Bit masks for irq_common_data.state_use_accessors
* *
* IRQD_TRIGGER_MASK - Mask for the trigger type bits * IRQD_TRIGGER_MASK - Mask for the trigger type bits
* IRQD_SETAFFINITY_PENDING - Affinity setting is pending * IRQD_SETAFFINITY_PENDING - Affinity setting is pending
...@@ -198,34 +206,36 @@ enum { ...@@ -198,34 +206,36 @@ enum {
IRQD_WAKEUP_ARMED = (1 << 19), IRQD_WAKEUP_ARMED = (1 << 19),
}; };
#define __irqd_to_state(d) ((d)->common->state_use_accessors)
static inline bool irqd_is_setaffinity_pending(struct irq_data *d) static inline bool irqd_is_setaffinity_pending(struct irq_data *d)
{ {
return d->state_use_accessors & IRQD_SETAFFINITY_PENDING; return __irqd_to_state(d) & IRQD_SETAFFINITY_PENDING;
} }
static inline bool irqd_is_per_cpu(struct irq_data *d) static inline bool irqd_is_per_cpu(struct irq_data *d)
{ {
return d->state_use_accessors & IRQD_PER_CPU; return __irqd_to_state(d) & IRQD_PER_CPU;
} }
static inline bool irqd_can_balance(struct irq_data *d) static inline bool irqd_can_balance(struct irq_data *d)
{ {
return !(d->state_use_accessors & (IRQD_PER_CPU | IRQD_NO_BALANCING)); return !(__irqd_to_state(d) & (IRQD_PER_CPU | IRQD_NO_BALANCING));
} }
static inline bool irqd_affinity_was_set(struct irq_data *d) static inline bool irqd_affinity_was_set(struct irq_data *d)
{ {
return d->state_use_accessors & IRQD_AFFINITY_SET; return __irqd_to_state(d) & IRQD_AFFINITY_SET;
} }
static inline void irqd_mark_affinity_was_set(struct irq_data *d) static inline void irqd_mark_affinity_was_set(struct irq_data *d)
{ {
d->state_use_accessors |= IRQD_AFFINITY_SET; __irqd_to_state(d) |= IRQD_AFFINITY_SET;
} }
static inline u32 irqd_get_trigger_type(struct irq_data *d) static inline u32 irqd_get_trigger_type(struct irq_data *d)
{ {
return d->state_use_accessors & IRQD_TRIGGER_MASK; return __irqd_to_state(d) & IRQD_TRIGGER_MASK;
} }
/* /*
...@@ -233,43 +243,43 @@ static inline u32 irqd_get_trigger_type(struct irq_data *d) ...@@ -233,43 +243,43 @@ static inline u32 irqd_get_trigger_type(struct irq_data *d)
*/ */
static inline void irqd_set_trigger_type(struct irq_data *d, u32 type) static inline void irqd_set_trigger_type(struct irq_data *d, u32 type)
{ {
d->state_use_accessors &= ~IRQD_TRIGGER_MASK; __irqd_to_state(d) &= ~IRQD_TRIGGER_MASK;
d->state_use_accessors |= type & IRQD_TRIGGER_MASK; __irqd_to_state(d) |= type & IRQD_TRIGGER_MASK;
} }
static inline bool irqd_is_level_type(struct irq_data *d) static inline bool irqd_is_level_type(struct irq_data *d)
{ {
return d->state_use_accessors & IRQD_LEVEL; return __irqd_to_state(d) & IRQD_LEVEL;
} }
static inline bool irqd_is_wakeup_set(struct irq_data *d) static inline bool irqd_is_wakeup_set(struct irq_data *d)
{ {
return d->state_use_accessors & IRQD_WAKEUP_STATE; return __irqd_to_state(d) & IRQD_WAKEUP_STATE;
} }
static inline bool irqd_can_move_in_process_context(struct irq_data *d) static inline bool irqd_can_move_in_process_context(struct irq_data *d)
{ {
return d->state_use_accessors & IRQD_MOVE_PCNTXT; return __irqd_to_state(d) & IRQD_MOVE_PCNTXT;
} }
static inline bool irqd_irq_disabled(struct irq_data *d) static inline bool irqd_irq_disabled(struct irq_data *d)
{ {
return d->state_use_accessors & IRQD_IRQ_DISABLED; return __irqd_to_state(d) & IRQD_IRQ_DISABLED;
} }
static inline bool irqd_irq_masked(struct irq_data *d) static inline bool irqd_irq_masked(struct irq_data *d)
{ {
return d->state_use_accessors & IRQD_IRQ_MASKED; return __irqd_to_state(d) & IRQD_IRQ_MASKED;
} }
static inline bool irqd_irq_inprogress(struct irq_data *d) static inline bool irqd_irq_inprogress(struct irq_data *d)
{ {
return d->state_use_accessors & IRQD_IRQ_INPROGRESS; return __irqd_to_state(d) & IRQD_IRQ_INPROGRESS;
} }
static inline bool irqd_is_wakeup_armed(struct irq_data *d) static inline bool irqd_is_wakeup_armed(struct irq_data *d)
{ {
return d->state_use_accessors & IRQD_WAKEUP_ARMED; return __irqd_to_state(d) & IRQD_WAKEUP_ARMED;
} }
...@@ -280,12 +290,12 @@ static inline bool irqd_is_wakeup_armed(struct irq_data *d) ...@@ -280,12 +290,12 @@ static inline bool irqd_is_wakeup_armed(struct irq_data *d)
*/ */
static inline void irqd_set_chained_irq_inprogress(struct irq_data *d) static inline void irqd_set_chained_irq_inprogress(struct irq_data *d)
{ {
d->state_use_accessors |= IRQD_IRQ_INPROGRESS; __irqd_to_state(d) |= IRQD_IRQ_INPROGRESS;
} }
static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d) static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d)
{ {
d->state_use_accessors &= ~IRQD_IRQ_INPROGRESS; __irqd_to_state(d) &= ~IRQD_IRQ_INPROGRESS;
} }
static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d) static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
...@@ -462,6 +472,8 @@ extern void handle_nested_irq(unsigned int irq); ...@@ -462,6 +472,8 @@ extern void handle_nested_irq(unsigned int irq);
extern int irq_chip_compose_msi_msg(struct irq_data *data, struct msi_msg *msg); extern int irq_chip_compose_msi_msg(struct irq_data *data, struct msi_msg *msg);
#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
extern void irq_chip_enable_parent(struct irq_data *data);
extern void irq_chip_disable_parent(struct irq_data *data);
extern void irq_chip_ack_parent(struct irq_data *data); extern void irq_chip_ack_parent(struct irq_data *data);
extern int irq_chip_retrigger_hierarchy(struct irq_data *data); extern int irq_chip_retrigger_hierarchy(struct irq_data *data);
extern void irq_chip_mask_parent(struct irq_data *data); extern void irq_chip_mask_parent(struct irq_data *data);
...@@ -523,6 +535,15 @@ irq_set_chained_handler(unsigned int irq, irq_flow_handler_t handle) ...@@ -523,6 +535,15 @@ irq_set_chained_handler(unsigned int irq, irq_flow_handler_t handle)
__irq_set_handler(irq, handle, 1, NULL); __irq_set_handler(irq, handle, 1, NULL);
} }
/*
* Set a highlevel chained flow handler and its data for a given IRQ.
* (a chained handler is automatically enabled and set to
* IRQ_NOREQUEST, IRQ_NOPROBE, and IRQ_NOTHREAD)
*/
void
irq_set_chained_handler_and_data(unsigned int irq, irq_flow_handler_t handle,
void *data);
void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set); void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set);
static inline void irq_set_status_flags(unsigned int irq, unsigned long set) static inline void irq_set_status_flags(unsigned int irq, unsigned long set)
...@@ -630,6 +651,23 @@ static inline u32 irq_get_trigger_type(unsigned int irq) ...@@ -630,6 +651,23 @@ static inline u32 irq_get_trigger_type(unsigned int irq)
return d ? irqd_get_trigger_type(d) : 0; return d ? irqd_get_trigger_type(d) : 0;
} }
static inline int irq_data_get_node(struct irq_data *d)
{
return d->node;
}
static inline struct cpumask *irq_get_affinity_mask(int irq)
{
struct irq_data *d = irq_get_irq_data(irq);
return d ? d->affinity : NULL;
}
static inline struct cpumask *irq_data_get_affinity_mask(struct irq_data *d)
{
return d->affinity;
}
unsigned int arch_dynirq_lower_bound(unsigned int from); unsigned int arch_dynirq_lower_bound(unsigned int from);
int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node, int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
......
...@@ -17,7 +17,7 @@ struct pt_regs; ...@@ -17,7 +17,7 @@ struct pt_regs;
/** /**
* struct irq_desc - interrupt descriptor * struct irq_desc - interrupt descriptor
* @irq_data: per irq and chip data passed down to chip functions * @irq_common_data: per irq and chip data passed down to chip functions
* @kstat_irqs: irq stats per cpu * @kstat_irqs: irq stats per cpu
* @handle_irq: highlevel irq-events handler * @handle_irq: highlevel irq-events handler
* @preflow_handler: handler called before the flow handler (currently used by sparc) * @preflow_handler: handler called before the flow handler (currently used by sparc)
...@@ -47,6 +47,7 @@ struct pt_regs; ...@@ -47,6 +47,7 @@ struct pt_regs;
* @name: flow handler name for /proc/interrupts output * @name: flow handler name for /proc/interrupts output
*/ */
struct irq_desc { struct irq_desc {
struct irq_common_data irq_common_data;
struct irq_data irq_data; struct irq_data irq_data;
unsigned int __percpu *kstat_irqs; unsigned int __percpu *kstat_irqs;
irq_flow_handler_t handle_irq; irq_flow_handler_t handle_irq;
......
...@@ -258,6 +258,10 @@ int irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr, ...@@ -258,6 +258,10 @@ int irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr,
/* V2 interfaces to support hierarchy IRQ domains. */ /* V2 interfaces to support hierarchy IRQ domains. */
extern struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain, extern struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain,
unsigned int virq); unsigned int virq);
extern void irq_domain_set_info(struct irq_domain *domain, unsigned int virq,
irq_hw_number_t hwirq, struct irq_chip *chip,
void *chip_data, irq_flow_handler_t handler,
void *handler_data, const char *handler_name);
#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
extern struct irq_domain *irq_domain_add_hierarchy(struct irq_domain *parent, extern struct irq_domain *irq_domain_add_hierarchy(struct irq_domain *parent,
unsigned int flags, unsigned int size, unsigned int flags, unsigned int size,
...@@ -281,10 +285,6 @@ extern int irq_domain_set_hwirq_and_chip(struct irq_domain *domain, ...@@ -281,10 +285,6 @@ extern int irq_domain_set_hwirq_and_chip(struct irq_domain *domain,
irq_hw_number_t hwirq, irq_hw_number_t hwirq,
struct irq_chip *chip, struct irq_chip *chip,
void *chip_data); void *chip_data);
extern void irq_domain_set_info(struct irq_domain *domain, unsigned int virq,
irq_hw_number_t hwirq, struct irq_chip *chip,
void *chip_data, irq_flow_handler_t handler,
void *handler_data, const char *handler_name);
extern void irq_domain_reset_irq_data(struct irq_data *irq_data); extern void irq_domain_reset_irq_data(struct irq_data *irq_data);
extern void irq_domain_free_irqs_common(struct irq_domain *domain, extern void irq_domain_free_irqs_common(struct irq_domain *domain,
unsigned int virq, unsigned int virq,
......
/*
* Renesas IRQC Driver
*
* Copyright (C) 2013 Magnus Damm
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __IRQ_RENESAS_IRQC_H__
#define __IRQ_RENESAS_IRQC_H__
struct renesas_irqc_config {
unsigned int irq_base;
};
#endif /* __IRQ_RENESAS_IRQC_H__ */
...@@ -719,15 +719,9 @@ void handle_percpu_devid_irq(unsigned int irq, struct irq_desc *desc) ...@@ -719,15 +719,9 @@ void handle_percpu_devid_irq(unsigned int irq, struct irq_desc *desc)
} }
void void
__irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, __irq_do_set_handler(struct irq_desc *desc, irq_flow_handler_t handle,
const char *name) int is_chained, const char *name)
{ {
unsigned long flags;
struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, 0);
if (!desc)
return;
if (!handle) { if (!handle) {
handle = handle_bad_irq; handle = handle_bad_irq;
} else { } else {
...@@ -749,13 +743,13 @@ __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, ...@@ -749,13 +743,13 @@ __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
* right away. * right away.
*/ */
if (WARN_ON(is_chained)) if (WARN_ON(is_chained))
goto out; return;
/* Try the parent */ /* Try the parent */
irq_data = irq_data->parent_data; irq_data = irq_data->parent_data;
} }
#endif #endif
if (WARN_ON(!irq_data || irq_data->chip == &no_irq_chip)) if (WARN_ON(!irq_data || irq_data->chip == &no_irq_chip))
goto out; return;
} }
/* Uninstall? */ /* Uninstall? */
...@@ -774,11 +768,40 @@ __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, ...@@ -774,11 +768,40 @@ __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
irq_settings_set_nothread(desc); irq_settings_set_nothread(desc);
irq_startup(desc, true); irq_startup(desc, true);
} }
out: }
void
__irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
const char *name)
{
unsigned long flags;
struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, 0);
if (!desc)
return;
__irq_do_set_handler(desc, handle, is_chained, name);
irq_put_desc_busunlock(desc, flags); irq_put_desc_busunlock(desc, flags);
} }
EXPORT_SYMBOL_GPL(__irq_set_handler); EXPORT_SYMBOL_GPL(__irq_set_handler);
void
irq_set_chained_handler_and_data(unsigned int irq, irq_flow_handler_t handle,
void *data)
{
unsigned long flags;
struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, 0);
if (!desc)
return;
__irq_do_set_handler(desc, handle, 1, NULL);
desc->irq_data.handler_data = data;
irq_put_desc_busunlock(desc, flags);
}
EXPORT_SYMBOL_GPL(irq_set_chained_handler_and_data);
void void
irq_set_chip_and_handler_name(unsigned int irq, struct irq_chip *chip, irq_set_chip_and_handler_name(unsigned int irq, struct irq_chip *chip,
irq_flow_handler_t handle, const char *name) irq_flow_handler_t handle, const char *name)
...@@ -875,6 +898,34 @@ void irq_cpu_offline(void) ...@@ -875,6 +898,34 @@ void irq_cpu_offline(void)
} }
#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
/**
* irq_chip_enable_parent - Enable the parent interrupt (defaults to unmask if
* NULL)
* @data: Pointer to interrupt specific data
*/
void irq_chip_enable_parent(struct irq_data *data)
{
data = data->parent_data;
if (data->chip->irq_enable)
data->chip->irq_enable(data);
else
data->chip->irq_unmask(data);
}
/**
* irq_chip_disable_parent - Disable the parent interrupt (defaults to mask if
* NULL)
* @data: Pointer to interrupt specific data
*/
void irq_chip_disable_parent(struct irq_data *data)
{
data = data->parent_data;
if (data->chip->irq_disable)
data->chip->irq_disable(data);
else
data->chip->irq_mask(data);
}
/** /**
* irq_chip_ack_parent - Acknowledge the parent interrupt * irq_chip_ack_parent - Acknowledge the parent interrupt
* @data: Pointer to interrupt specific data * @data: Pointer to interrupt specific data
......
...@@ -104,7 +104,7 @@ int devm_request_any_context_irq(struct device *dev, unsigned int irq, ...@@ -104,7 +104,7 @@ int devm_request_any_context_irq(struct device *dev, unsigned int irq,
return -ENOMEM; return -ENOMEM;
rc = request_any_context_irq(irq, handler, irqflags, devname, dev_id); rc = request_any_context_irq(irq, handler, irqflags, devname, dev_id);
if (rc) { if (rc < 0) {
devres_free(dr); devres_free(dr);
return rc; return rc;
} }
...@@ -113,7 +113,7 @@ int devm_request_any_context_irq(struct device *dev, unsigned int irq, ...@@ -113,7 +113,7 @@ int devm_request_any_context_irq(struct device *dev, unsigned int irq,
dr->dev_id = dev_id; dr->dev_id = dev_id;
devres_add(dev, dr); devres_add(dev, dr);
return 0; return rc;
} }
EXPORT_SYMBOL(devm_request_any_context_irq); EXPORT_SYMBOL(devm_request_any_context_irq);
......
...@@ -42,6 +42,7 @@ struct irq_chip no_irq_chip = { ...@@ -42,6 +42,7 @@ struct irq_chip no_irq_chip = {
.irq_enable = noop, .irq_enable = noop,
.irq_disable = noop, .irq_disable = noop,
.irq_ack = ack_bad, .irq_ack = ack_bad,
.flags = IRQCHIP_SKIP_SET_WAKE,
}; };
/* /*
......
...@@ -360,7 +360,7 @@ static struct lock_class_key irq_nested_lock_class; ...@@ -360,7 +360,7 @@ static struct lock_class_key irq_nested_lock_class;
int irq_map_generic_chip(struct irq_domain *d, unsigned int virq, int irq_map_generic_chip(struct irq_domain *d, unsigned int virq,
irq_hw_number_t hw_irq) irq_hw_number_t hw_irq)
{ {
struct irq_data *data = irq_get_irq_data(virq); struct irq_data *data = irq_domain_get_irq_data(d, virq);
struct irq_domain_chip_generic *dgc = d->gc; struct irq_domain_chip_generic *dgc = d->gc;
struct irq_chip_generic *gc; struct irq_chip_generic *gc;
struct irq_chip_type *ct; struct irq_chip_type *ct;
...@@ -405,8 +405,7 @@ int irq_map_generic_chip(struct irq_domain *d, unsigned int virq, ...@@ -405,8 +405,7 @@ int irq_map_generic_chip(struct irq_domain *d, unsigned int virq,
else else
data->mask = 1 << idx; data->mask = 1 << idx;
irq_set_chip_and_handler(virq, chip, ct->handler); irq_domain_set_info(d, virq, hw_irq, chip, gc, ct->handler, NULL, NULL);
irq_set_chip_data(virq, gc);
irq_modify_status(virq, dgc->irq_flags_to_clear, dgc->irq_flags_to_set); irq_modify_status(virq, dgc->irq_flags_to_clear, dgc->irq_flags_to_set);
return 0; return 0;
} }
......
...@@ -168,27 +168,27 @@ irq_put_desc_unlock(struct irq_desc *desc, unsigned long flags) ...@@ -168,27 +168,27 @@ irq_put_desc_unlock(struct irq_desc *desc, unsigned long flags)
*/ */
static inline void irqd_set_move_pending(struct irq_data *d) static inline void irqd_set_move_pending(struct irq_data *d)
{ {
d->state_use_accessors |= IRQD_SETAFFINITY_PENDING; __irqd_to_state(d) |= IRQD_SETAFFINITY_PENDING;
} }
static inline void irqd_clr_move_pending(struct irq_data *d) static inline void irqd_clr_move_pending(struct irq_data *d)
{ {
d->state_use_accessors &= ~IRQD_SETAFFINITY_PENDING; __irqd_to_state(d) &= ~IRQD_SETAFFINITY_PENDING;
} }
static inline void irqd_clear(struct irq_data *d, unsigned int mask) static inline void irqd_clear(struct irq_data *d, unsigned int mask)
{ {
d->state_use_accessors &= ~mask; __irqd_to_state(d) &= ~mask;
} }
static inline void irqd_set(struct irq_data *d, unsigned int mask) static inline void irqd_set(struct irq_data *d, unsigned int mask)
{ {
d->state_use_accessors |= mask; __irqd_to_state(d) |= mask;
} }
static inline bool irqd_has_set(struct irq_data *d, unsigned int mask) static inline bool irqd_has_set(struct irq_data *d, unsigned int mask)
{ {
return d->state_use_accessors & mask; return __irqd_to_state(d) & mask;
} }
static inline void kstat_incr_irqs_this_cpu(unsigned int irq, struct irq_desc *desc) static inline void kstat_incr_irqs_this_cpu(unsigned int irq, struct irq_desc *desc)
...@@ -197,6 +197,11 @@ static inline void kstat_incr_irqs_this_cpu(unsigned int irq, struct irq_desc *d ...@@ -197,6 +197,11 @@ static inline void kstat_incr_irqs_this_cpu(unsigned int irq, struct irq_desc *d
__this_cpu_inc(kstat.irqs_sum); __this_cpu_inc(kstat.irqs_sum);
} }
static inline int irq_desc_get_node(struct irq_desc *desc)
{
return irq_data_get_node(&desc->irq_data);
}
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
bool irq_pm_check_wakeup(struct irq_desc *desc); bool irq_pm_check_wakeup(struct irq_desc *desc);
void irq_pm_install_action(struct irq_desc *desc, struct irqaction *action); void irq_pm_install_action(struct irq_desc *desc, struct irqaction *action);
......
...@@ -59,16 +59,10 @@ static void desc_smp_init(struct irq_desc *desc, int node) ...@@ -59,16 +59,10 @@ static void desc_smp_init(struct irq_desc *desc, int node)
#endif #endif
} }
static inline int desc_node(struct irq_desc *desc)
{
return desc->irq_data.node;
}
#else #else
static inline int static inline int
alloc_masks(struct irq_desc *desc, gfp_t gfp, int node) { return 0; } alloc_masks(struct irq_desc *desc, gfp_t gfp, int node) { return 0; }
static inline void desc_smp_init(struct irq_desc *desc, int node) { } static inline void desc_smp_init(struct irq_desc *desc, int node) { }
static inline int desc_node(struct irq_desc *desc) { return 0; }
#endif #endif
static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node, static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node,
...@@ -76,6 +70,7 @@ static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node, ...@@ -76,6 +70,7 @@ static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node,
{ {
int cpu; int cpu;
desc->irq_data.common = &desc->irq_common_data;
desc->irq_data.irq = irq; desc->irq_data.irq = irq;
desc->irq_data.chip = &no_irq_chip; desc->irq_data.chip = &no_irq_chip;
desc->irq_data.chip_data = NULL; desc->irq_data.chip_data = NULL;
...@@ -299,7 +294,7 @@ static void free_desc(unsigned int irq) ...@@ -299,7 +294,7 @@ static void free_desc(unsigned int irq)
unsigned long flags; unsigned long flags;
raw_spin_lock_irqsave(&desc->lock, flags); raw_spin_lock_irqsave(&desc->lock, flags);
desc_set_defaults(irq, desc, desc_node(desc), NULL); desc_set_defaults(irq, desc, irq_desc_get_node(desc), NULL);
raw_spin_unlock_irqrestore(&desc->lock, flags); raw_spin_unlock_irqrestore(&desc->lock, flags);
} }
...@@ -619,7 +614,7 @@ unsigned int kstat_irqs(unsigned int irq) ...@@ -619,7 +614,7 @@ unsigned int kstat_irqs(unsigned int irq)
{ {
struct irq_desc *desc = irq_to_desc(irq); struct irq_desc *desc = irq_to_desc(irq);
int cpu; int cpu;
int sum = 0; unsigned int sum = 0;
if (!desc || !desc->kstat_irqs) if (!desc || !desc->kstat_irqs)
return 0; return 0;
...@@ -639,7 +634,7 @@ unsigned int kstat_irqs(unsigned int irq) ...@@ -639,7 +634,7 @@ unsigned int kstat_irqs(unsigned int irq)
*/ */
unsigned int kstat_irqs_usr(unsigned int irq) unsigned int kstat_irqs_usr(unsigned int irq)
{ {
int sum; unsigned int sum;
irq_lock_sparse(); irq_lock_sparse();
sum = kstat_irqs(irq); sum = kstat_irqs(irq);
......
...@@ -830,10 +830,12 @@ static struct irq_data *irq_domain_insert_irq_data(struct irq_domain *domain, ...@@ -830,10 +830,12 @@ static struct irq_data *irq_domain_insert_irq_data(struct irq_domain *domain,
{ {
struct irq_data *irq_data; struct irq_data *irq_data;
irq_data = kzalloc_node(sizeof(*irq_data), GFP_KERNEL, child->node); irq_data = kzalloc_node(sizeof(*irq_data), GFP_KERNEL,
irq_data_get_node(child));
if (irq_data) { if (irq_data) {
child->parent_data = irq_data; child->parent_data = irq_data;
irq_data->irq = child->irq; irq_data->irq = child->irq;
irq_data->common = child->common;
irq_data->node = child->node; irq_data->node = child->node;
irq_data->domain = domain; irq_data->domain = domain;
} }
...@@ -1232,6 +1234,27 @@ struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain, ...@@ -1232,6 +1234,27 @@ struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain,
return (irq_data && irq_data->domain == domain) ? irq_data : NULL; return (irq_data && irq_data->domain == domain) ? irq_data : NULL;
} }
/**
* irq_domain_set_info - Set the complete data for a @virq in @domain
* @domain: Interrupt domain to match
* @virq: IRQ number
* @hwirq: The hardware interrupt number
* @chip: The associated interrupt chip
* @chip_data: The associated interrupt chip data
* @handler: The interrupt flow handler
* @handler_data: The interrupt flow handler data
* @handler_name: The interrupt handler name
*/
void irq_domain_set_info(struct irq_domain *domain, unsigned int virq,
irq_hw_number_t hwirq, struct irq_chip *chip,
void *chip_data, irq_flow_handler_t handler,
void *handler_data, const char *handler_name)
{
irq_set_chip_and_handler_name(virq, chip, handler, handler_name);
irq_set_chip_data(virq, chip_data);
irq_set_handler_data(virq, handler_data);
}
static void irq_domain_check_hierarchy(struct irq_domain *domain) static void irq_domain_check_hierarchy(struct irq_domain *domain)
{ {
} }
......
...@@ -363,7 +363,7 @@ static int ...@@ -363,7 +363,7 @@ static int
setup_affinity(unsigned int irq, struct irq_desc *desc, struct cpumask *mask) setup_affinity(unsigned int irq, struct irq_desc *desc, struct cpumask *mask)
{ {
struct cpumask *set = irq_default_affinity; struct cpumask *set = irq_default_affinity;
int node = desc->irq_data.node; int node = irq_desc_get_node(desc);
/* Excludes PER_CPU and NO_BALANCE interrupts */ /* Excludes PER_CPU and NO_BALANCE interrupts */
if (!irq_can_set_affinity(irq)) if (!irq_can_set_affinity(irq))
......
...@@ -12,16 +12,16 @@ void irq_move_masked_irq(struct irq_data *idata) ...@@ -12,16 +12,16 @@ void irq_move_masked_irq(struct irq_data *idata)
if (likely(!irqd_is_setaffinity_pending(&desc->irq_data))) if (likely(!irqd_is_setaffinity_pending(&desc->irq_data)))
return; return;
irqd_clr_move_pending(&desc->irq_data);
/* /*
* Paranoia: cpu-local interrupts shouldn't be calling in here anyway. * Paranoia: cpu-local interrupts shouldn't be calling in here anyway.
*/ */
if (!irqd_can_balance(&desc->irq_data)) { if (irqd_is_per_cpu(&desc->irq_data)) {
WARN_ON(1); WARN_ON(1);
return; return;
} }
irqd_clr_move_pending(&desc->irq_data);
if (unlikely(cpumask_empty(desc->pending_mask))) if (unlikely(cpumask_empty(desc->pending_mask)))
return; return;
......
...@@ -124,7 +124,7 @@ static void msi_domain_free(struct irq_domain *domain, unsigned int virq, ...@@ -124,7 +124,7 @@ static void msi_domain_free(struct irq_domain *domain, unsigned int virq,
irq_domain_free_irqs_top(domain, virq, nr_irqs); irq_domain_free_irqs_top(domain, virq, nr_irqs);
} }
static struct irq_domain_ops msi_domain_ops = { static const struct irq_domain_ops msi_domain_ops = {
.alloc = msi_domain_alloc, .alloc = msi_domain_alloc,
.free = msi_domain_free, .free = msi_domain_free,
.activate = msi_domain_activate, .activate = msi_domain_activate,
......
...@@ -123,6 +123,8 @@ void suspend_device_irqs(void) ...@@ -123,6 +123,8 @@ void suspend_device_irqs(void)
unsigned long flags; unsigned long flags;
bool sync; bool sync;
if (irq_settings_is_nested_thread(desc))
continue;
raw_spin_lock_irqsave(&desc->lock, flags); raw_spin_lock_irqsave(&desc->lock, flags);
sync = suspend_device_irq(desc, irq); sync = suspend_device_irq(desc, irq);
raw_spin_unlock_irqrestore(&desc->lock, flags); raw_spin_unlock_irqrestore(&desc->lock, flags);
...@@ -163,6 +165,8 @@ static void resume_irqs(bool want_early) ...@@ -163,6 +165,8 @@ static void resume_irqs(bool want_early)
if (!is_early && want_early) if (!is_early && want_early)
continue; continue;
if (irq_settings_is_nested_thread(desc))
continue;
raw_spin_lock_irqsave(&desc->lock, flags); raw_spin_lock_irqsave(&desc->lock, flags);
resume_irq(desc, irq); resume_irq(desc, irq);
......
...@@ -241,7 +241,7 @@ static int irq_node_proc_show(struct seq_file *m, void *v) ...@@ -241,7 +241,7 @@ static int irq_node_proc_show(struct seq_file *m, void *v)
{ {
struct irq_desc *desc = irq_to_desc((long) m->private); struct irq_desc *desc = irq_to_desc((long) m->private);
seq_printf(m, "%d\n", desc->irq_data.node); seq_printf(m, "%d\n", irq_desc_get_node(desc));
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment