irqchip updates for v3.20
Subsystems (8)
Linus,
Please pull the latest irq-core-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-core-for-linus
# HEAD: 4fe7ffb7e17ca6ad9173b8de35f260c9c8fc2f79 genirq: Fix null pointer reference in irq_set_affinity_hint()
Various irqchip driver updates, plus a genirq core update that allows the initial spreading of irqs amonst CPUs without having to do it from user-space.
Thanks,
Ingo
------------------>
Baruch Siach (2):
irqchip: Devicetree: document Conexant Digicolor irq binding
irqchip: Conexant CX92755 interrupts controller driver
Jesse Brandeburg (2):
genirq: Set initial affinity in irq_set_affinity_hint()
genirq: Fix null pointer reference in irq_set_affinity_hint()
Liviu Dudau (1):
irqchip: gic: Allow interrupt level to be set for PPIs
Magnus Damm (1):
irqchip: renesas-intc-irqpin: r8a7779 IRLM setup support
Qais Yousef (1):
irqchip: mips-gic: Handle pending interrupts once in __gic_irq_dispatch()
Tony Lindgren (2):
irqchip: omap-intc: Fix support for dm814 and dm816
irqchip: omap-intc: Remove unused legacy interface for omap2
Yingjoe Chen (1):
irqchip: mtk-sysirq: Get irq number from register resource size
Documentation/devicetree/bindings/arm/gic.txt | 8 +- .../bindings/interrupt-controller/digicolor-ic.txt | 21 ++++ .../interrupt-controller/renesas,intc-irqpin.txt | 5 + .../interrupt-controller/ti,omap-intc-irq.txt | 28 +++++ drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-digicolor.c | 120 +++++++++++++++++++++ drivers/irqchip/irq-gic-common.c | 18 ++-- drivers/irqchip/irq-gic-common.h | 2 +- drivers/irqchip/irq-gic-v3.c | 8 +- drivers/irqchip/irq-gic.c | 9 +- drivers/irqchip/irq-hip04.c | 9 +- drivers/irqchip/irq-mips-gic.c | 44 ++++---- drivers/irqchip/irq-mtk-sysirq.c | 18 ++-- drivers/irqchip/irq-omap-intc.c | 22 +--- drivers/irqchip/irq-renesas-intc-irqpin.c | 50 +++++++-- include/linux/irqchip/irq-omap-intc.h | 2 - kernel/irq/manage.c | 3 + 17 files changed, 296 insertions(+), 72 deletions(-) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/digicolor-ic.txt create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ti,omap-intc-irq.txt create mode 100644 drivers/irqchip/irq-digicolor.c
Documentation/devicetree/bindings/arm/gic.txt +6 -2
@@ -32,12 +32,16 @@ have PPIs or SGIs. The 3rd cell is the flags, encoded as follows: bits[3:0] trigger type and level flags. 1 = low-to-high edge triggered - 2 = high-to-low edge triggered + 2 = high-to-low edge triggered (invalid for SPIs) 4 = active high level-sensitive - 8 = active low level-sensitive + 8 = active low level-sensitive (invalid for SPIs). bits[15:8] PPI interrupt cpu mask. Each bit corresponds to each of the 8 possible cpus attached to the GIC. A bit set to '1' indicated the interrupt is wired to that CPU. Only valid for PPI interrupts. + Also note that the configurability of PPI interrupts is IMPLEMENTATION + DEFINED and as such not guaranteed to be present (most SoC available + in 2014 seem to ignore the setting of this flag and use the hardware + default value). - reg : Specifies base physical address(s) and size of the GIC registers. The first region is the GIC distributor register base and size. The 2nd region is
Documentation/devicetree/bindings/interrupt-controller/digicolor-ic.txt new file +21 -0
@@ -0,0 +1,21 @@ +Conexant Digicolor Interrupt Controller + +Required properties: + +- compatible : should be "cnxt,cx92755-ic" +- reg : Specifies base physical address and size of the interrupt controller + registers (IC) area +- interrupt-controller : Identifies the node as an interrupt controller +- #interrupt-cells : Specifies the number of cells needed to encode an + interrupt source. The value shall be 1. +- syscon: A phandle to the syscon node describing UC registers + +Example: + + intc: interrupt-controller@f0000040 { + compatible = "cnxt,cx92755-ic"; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0xf0000040 0x40>; + syscon = <&uc_regs>; + };
Documentation/devicetree/bindings/interrupt-controller/renesas,intc-irqpin.txt +5 -0
@@ -9,6 +9,11 @@ DT bindings for the R-/SH-Mobile irqpin controller - "renesas,intc-irqpin-r8a7778" (R-Car M1A) - "renesas,intc-irqpin-r8a7779" (R-Car H1) - "renesas,intc-irqpin-sh73a0" (SH-Mobile AG5) + +- reg: Base address and length of each register bank used by the external + IRQ pins driven by the interrupt controller hardware module. The base + addresses, length and number of required register banks varies with soctype. + - #interrupt-cells: has to be <2>: an interrupt index and flags, as defined in interrupts.txt in this directory
Documentation/devicetree/bindings/interrupt-controller/ti,omap-intc-irq.txt new file +28 -0
@@ -0,0 +1,28 @@ +Omap2/3 intc controller + +On TI omap2 and 3 the intc interrupt controller can provide +96 or 128 IRQ signals to the ARM host depending on the SoC. + +Required Properties: +- compatible: should be one of + "ti,omap2-intc" + "ti,omap3-intc" + "ti,dm814-intc" + "ti,dm816-intc" + "ti,am33xx-intc" + +- interrupt-controller : Identifies the node as an interrupt controller +- #interrupt-cells : Specifies the number of cells needed to encode interrupt + source, should be 1 for intc +- interrupts: interrupt reference to primary interrupt controller + +Please refer to interrupts.txt in this directory for details of the common +Interrupt Controllers bindings used by client devices. + +Example: + intc: interrupt-controller@48200000 { + compatible = "ti,omap3-intc"; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0x48200000 0x1000>; + };
drivers/irqchip/Makefile +1 -0
@@ -42,3 +42,4 @@ obj-$(CONFIG_BRCMSTB_L2_IRQ) += irq-brcmstb-l2.o obj-$(CONFIG_KEYSTONE_IRQ) += irq-keystone.o obj-$(CONFIG_MIPS_GIC) += irq-mips-gic.o obj-$(CONFIG_ARCH_MEDIATEK) += irq-mtk-sysirq.o +obj-$(CONFIG_ARCH_DIGICOLOR) += irq-digicolor.o
drivers/irqchip/irq-digicolor.c new file +120 -0
120 lines not on this page · raw message
drivers/irqchip/irq-gic-common.c +12 -6
@@ -21,7 +21,7 @@#include "irq-gic-common.h" -void 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 )) {u32 enablemask =1 << (irq %32 );
@@ -29,16 +29,17 @@ void gic_configure_irq(unsigned int irq, unsigned int type,u32 confmask =0x2 << ((irq %16 ) *2 );u32 confoff = (irq /16 ) *4 ;bool enabled = false; -u32 val; +u32 val, oldval; +int ret =0 ;/* * Read current configuration register, and insert the config * for "irq", depending on "type". */ - val =readl_relaxed (base +GIC_DIST_CONFIG + confoff); -if (type ==IRQ_TYPE_LEVEL_HIGH ) + val = oldval =readl_relaxed (base +GIC_DIST_CONFIG + confoff); +if (type &IRQ_TYPE_LEVEL_MASK ) val &= ~confmask; -else if (type ==IRQ_TYPE_EDGE_RISING ) +else if (type &IRQ_TYPE_EDGE_BOTH ) val |= confmask;/*
@@ -54,15 +55,20 @@ void gic_configure_irq(unsigned int irq, unsigned int type,/* * Write back the new configuration, and possibly re-enable -* the interrupt. +* the interrupt. If we tried to write a new configuration and failed, +* return an error. */ writel_relaxed (val, base +GIC_DIST_CONFIG + confoff); +if (readl_relaxed (base +GIC_DIST_CONFIG + confoff) != val && val != oldval) + ret = -EINVAL ;if (enabled)writel_relaxed (enablemask, base +GIC_DIST_ENABLE_SET + enableoff);if (sync_access)sync_access (); + +return ret; } void __init gic_dist_config(void __iomem *base, int gic_irqs,
drivers/irqchip/irq-gic-common.h +1 -1
@@ -20,7 +20,7 @@#include <linux/of.h> #include <linux/irqdomain.h> -void 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 gic_dist_config (void __iomem *base,int gic_irqs,void (*sync_access)(void ));
drivers/irqchip/irq-gic-v3.c +4 -4
@@ -238,7 +238,9 @@ static int gic_set_type(struct irq_data *d, unsigned int type)if (irq <16 )return -EINVAL ; -if (type !=IRQ_TYPE_LEVEL_HIGH && type !=IRQ_TYPE_EDGE_RISING ) +/* SPIs have restrictions on the supported types */ +if (irq >=32 && type !=IRQ_TYPE_LEVEL_HIGH && + type !=IRQ_TYPE_EDGE_RISING )return -EINVAL ;if (gic_irq_in_rdist (d)) {
@@ -249,9 +251,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type) rwp_wait = gic_dist_wait_for_rwp; } -gic_configure_irq (irq, type, base, rwp_wait); - -return 0 ; +return gic_configure_irq (irq, type, base, rwp_wait); }static u64 gic_mpidr_to_affinity (u64 mpidr)
drivers/irqchip/irq-gic.c +6 -3
@@ -188,12 +188,15 @@ static int gic_set_type(struct irq_data *d, unsigned int type) {void __iomem *base =gic_dist_base (d);unsigned int gicirq =gic_irq (d); +int ret;/* Interrupt configuration for SGIs can't be changed */ if (gicirq <16 )return -EINVAL ; -if (type !=IRQ_TYPE_LEVEL_HIGH && type !=IRQ_TYPE_EDGE_RISING ) +/* SPIs have restrictions on the supported types */ +if (gicirq >=32 && type !=IRQ_TYPE_LEVEL_HIGH && + type !=IRQ_TYPE_EDGE_RISING )return -EINVAL ;raw_spin_lock (&irq_controller_lock);
@@ -201,11 +204,11 @@ static int gic_set_type(struct irq_data *d, unsigned int type)if (gic_arch_extn.irq_set_type) gic_arch_extn.irq_set_type (d, type); -gic_configure_irq (gicirq, type, base,NULL ); + ret =gic_configure_irq (gicirq, type, base,NULL );raw_spin_unlock (&irq_controller_lock); -return 0 ; +return ret; }static int gic_retrigger (struct irq_data *d)
drivers/irqchip/irq-hip04.c +6 -3
@@ -120,21 +120,24 @@ static int hip04_irq_set_type(struct irq_data *d, unsigned int type) {void __iomem *base =hip04_dist_base (d);unsigned int irq =hip04_irq (d); +int ret;/* Interrupt configuration for SGIs can't be changed */ if (irq <16 )return -EINVAL ; -if (type !=IRQ_TYPE_LEVEL_HIGH && type !=IRQ_TYPE_EDGE_RISING ) +/* SPIs have restrictions on the supported types */ +if (irq >=32 && type !=IRQ_TYPE_LEVEL_HIGH && + type !=IRQ_TYPE_EDGE_RISING )return -EINVAL ;raw_spin_lock (&irq_controller_lock); -gic_configure_irq (irq, type, base,NULL ); + ret =gic_configure_irq (irq, type, base,NULL );raw_spin_unlock (&irq_controller_lock); -return 0 ; +return ret; }#ifdef CONFIG_SMP
drivers/irqchip/irq-mips-gic.c +26 -18
77 lines not on this page · raw message
drivers/irqchip/irq-mtk-sysirq.c +11 -7
@@ -23,8 +23,6 @@#include "irqchip.h" -#define MT6577_SYS_INTPOL_NUM (224) -struct mtk_sysirq_chip_data {spinlock_t lock;void __iomem *intpol_base;
@@ -124,7 +122,8 @@ static int __init mtk_sysirq_of_init(struct device_node *node, {struct irq_domain *domain, *domain_parent;struct mtk_sysirq_chip_data *chip_data; -int ret =0 ; +int ret, size, intpol_num; +struct resource res; domain_parent =irq_find_host (parent);if (!domain_parent) {
@@ -132,19 +131,24 @@ static int __init mtk_sysirq_of_init(struct device_node *node,return -EINVAL ; } + ret =of_address_to_resource (node,0 , &res); +if (ret) +return ret; + chip_data =kzalloc (sizeof (*chip_data),GFP_KERNEL );if (!chip_data)return -ENOMEM ; - chip_data->intpol_base =of_io_request_and_map (node,0 ,"intpol" ); -if (IS_ERR (chip_data->intpol_base)) { + size =resource_size (&res); + intpol_num = size *8 ; + chip_data->intpol_base =ioremap (res.start, size); +if (!chip_data->intpol_base) {pr_err ("mtk_sysirq: unable to map sysirq register\n" ); ret =PTR_ERR (chip_data->intpol_base); goto out_free; } - domain =irq_domain_add_hierarchy (domain_parent,0 , -MT6577_SYS_INTPOL_NUM , node, + domain =irq_domain_add_hierarchy (domain_parent,0 , intpol_num, node, &sysirq_domain_ops, chip_data);if (!domain) { ret = -ENOMEM ;
drivers/irqchip/irq-omap-intc.c +5 -17
@@ -364,14 +364,6 @@ omap_intc_handle_irq(struct pt_regs *regs)omap_ack_irq (NULL ); } -void __init omap2_init_irq (void ) -{ - omap_nr_irqs =96 ; - omap_nr_pending =3 ; -omap_init_irq (OMAP24XX_IC_BASE ,NULL ); -set_handle_irq (omap_intc_handle_irq); -} -void __init omap3_init_irq (void ) { omap_nr_irqs =96 ;
@@ -380,14 +372,6 @@ void __init omap3_init_irq(void)set_handle_irq (omap_intc_handle_irq); } -void __init ti81xx_init_irq (void ) -{ - omap_nr_irqs =96 ; - omap_nr_pending =4 ; -omap_init_irq (OMAP34XX_IC_BASE ,NULL ); -set_handle_irq (omap_intc_handle_irq); -} -static int __init intc_of_init (struct device_node *node,struct device_node *parent) {
@@ -399,7 +383,9 @@ static int __init intc_of_init(struct device_node *node,if (WARN_ON (!node))return -ENODEV ; -if (of_device_is_compatible (node,"ti,am33xx-intc" )) { +if (of_device_is_compatible (node,"ti,dm814-intc" ) || +of_device_is_compatible (node,"ti,dm816-intc" ) || +of_device_is_compatible (node,"ti,am33xx-intc" )) { omap_nr_irqs =128 ; omap_nr_pending =4 ; }
@@ -415,4 +401,6 @@ static int __init intc_of_init(struct device_node *node,IRQCHIP_DECLARE (omap2_intc,"ti,omap2-intc" , intc_of_init);IRQCHIP_DECLARE (omap3_intc,"ti,omap3-intc" , intc_of_init); +IRQCHIP_DECLARE (dm814x_intc,"ti,dm814-intc" , intc_of_init); +IRQCHIP_DECLARE (dm816x_intc,"ti,dm816-intc" , intc_of_init);IRQCHIP_DECLARE (am33xx_intc,"ti,am33xx-intc" , intc_of_init);
drivers/irqchip/irq-renesas-intc-irqpin.c +41 -9
104 lines not on this page · raw message
include/linux/irqchip/irq-omap-intc.h +0 -2
@@ -18,9 +18,7 @@#ifndef __INCLUDE_LINUX_IRQCHIP_IRQ_OMAP_INTC_H#define __INCLUDE_LINUX_IRQCHIP_IRQ_OMAP_INTC_H -void omap2_init_irq (void );void omap3_init_irq (void ); -void ti81xx_init_irq (void );int omap_irq_pending (void );void omap_intc_save_context (void );
kernel/irq/manage.c +3 -0
@@ -243,6 +243,9 @@ int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m)return -EINVAL ; desc->affinity_hint = m;irq_put_desc_unlock (desc, flags); +/* set the initial affinity to prevent every interrupt being on CPU0 */ +if (m) +__irq_set_affinity (irq, m, false);return 0 ; }EXPORT_SYMBOL_GPL (irq_set_affinity_hint);