Skip to contentSkip to conversation

irq/core changes for v3.11

GIT PULL Ingo Molnar 1 participant 1 message Jul 1, 2013

Subsystems (14)
lore
Share & tools
lore
#0 lore raw

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: d2e08473f2488d53a71c2f53455f934ec6c44c53 softirq: Use _RET_IP_

The main changes:

- generic-irqchip driver additions, cleanups and fixes

- 3 new irqchip drivers: ARMv7-M NVIC, TB10x and Marvell Orion SoCs

- irq_get_trigger_type() simplification and cross-arch cleanup

- various cleanups, simplifications

- documentation updates

Thanks,

Ingo

------------------>
Andreas Fenkart (1):
genirq: Add kerneldoc for irq_disable.

Ben Hutchings (1):
genirq: Fix can_request_irq() for IRQs without an action

Christian Ruppert (1):

      irqchip: Add TB10x interrupt controller driver

Davidlohr Bueso (1):
softirq: Use _RET_IP_

Fabio Estevam (1):
genirq: generic-chip: Export some irq_gc_ functions

Gerlando Falauto (3):
genirq: Generic chip: Remove the local cur_regs() function
genirq: Generic chip: Add support for per chip type mask cache
genirq: Generic chip: Handle separate mask registers

Grant Likely (1):
genirq: irqchip: Add mask to block out invalid irqs

Ivo Sieben (1):
genirq: Set irq thread to RT priority on creation

James Hogan (1):
genirq: Irqchip: document gcflags arg of irq_alloc_domain_generic_chips

Javier Martinez Canillas (7):
genirq: Add irq_get_trigger_type() to get IRQ flags
gpio: mvebu: Use irq_get_trigger_type() to get IRQ flags
mfd: twl4030-irq: Use irq_get_trigger_type() to get IRQ flags
mfd: stmpe: use irq_get_trigger_type() to get IRQ flags
arm: orion: Use irq_get_trigger_type() to get IRQ flags
MIPS: octeon: Use irq_get_trigger_type() to get IRQ flags
irqdomain: Use irq_get_trigger_type() to get IRQ flags

Sachin Kamat (1):
irqchip: exynos-combiner: Staticize combiner_init

Sebastian Hesselbarth (1):
irqchip: Add support for Marvell Orion SoCs

Thomas Gleixner (5):
genirq: Generic chip: Cache per irq bit mask
genirq: irqchip: Add a mask calculation function
genirq: Generic chip: Split out code into separate functions
genirq: Generic chip: Add linear irq domain support
genirq: Add the generic chip to the genirq docbook

Uwe Kleine-König (1):
irqchip: Add support for ARMv7-M NVIC

 Documentation/DocBook/genericirq.tmpl              |  13 +
 .../interrupt-controller/abilis,tb10x-ictl.txt     |  38 +++
 .../interrupt-controller/marvell,orion-intc.txt    |  48 ++++
 arch/arm/plat-orion/gpio.c                         |   2 +-
 arch/mips/cavium-octeon/octeon-irq.c               |   2 +-
 drivers/gpio/gpio-mvebu.c                          |   2 +-
 drivers/irqchip/Kconfig                            |  15 +
 drivers/irqchip/Makefile                           |   3 +
 drivers/irqchip/exynos-combiner.c                  |   8 +-
 drivers/irqchip/irq-nvic.c                         | 117 ++++++++
 drivers/irqchip/irq-orion.c                        | 192 +++++++++++++
 drivers/irqchip/irq-tb10x.c                        | 195 +++++++++++++
 drivers/mfd/stmpe.c                                |   3 +-
 drivers/mfd/twl4030-irq.c                          |   5 +-
 include/linux/irq.h                                |  53 +++-
 include/linux/irqdomain.h                          |  12 +
 kernel/irq/chip.c                                  |  13 +
 kernel/irq/generic-chip.c                          | 314 ++++++++++++++++++---
 kernel/irq/irqdomain.c                             |   8 +-
 kernel/irq/manage.c                                |  17 +-
 kernel/softirq.c                                   |  10 +-
 21 files changed, 988 insertions(+), 82 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/abilis,tb10x-ictl.txt
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/marvell,orion-intc.txt
 create mode 100644 drivers/irqchip/irq-nvic.c
 create mode 100644 drivers/irqchip/irq-orion.c
 create mode 100644 drivers/irqchip/irq-tb10x.c
Documentation/DocBook/genericirq.tmpl +13 -0
index b342234..d16d21b 100644
@@ -464,6 +464,19 @@ if (desc->irq_data.chip->irq_eoi)
 	protected via desc->lock, by the generic layer.
      </para>
   </chapter>
+
+  <chapter id="genericchip">
+     <title>Generic interrupt chip</title>
+     <para>
+       To avoid copies of identical implementations of irq chips the
+       core provides a configurable generic interrupt chip
+       implementation. Developers should check carefuly whether the
+       generic chip fits their needs before implementing the same
+       functionality slightly different themself.
+     </para>
+!Ekernel/irq/generic-chip.c
+  </chapter>
+
   <chapter id="structs">
      <title>Structures</title>
      <para>
Documentation/devicetree/bindings/interrupt-controller/abilis,tb10x-ictl.txt new file +38 -0
new file mode 100644
index 0000000..9d52d5a
@@ -0,0 +1,38 @@
+TB10x Top Level Interrupt Controller
+====================================
+
+The Abilis TB10x SOC contains a custom interrupt controller. It performs
+one-to-one mapping of external interrupt sources to CPU interrupts and
+provides support for reconfigurable trigger modes.
+
+Required properties
+-------------------
+
+- compatible: Should be "abilis,tb10x-ictl"
+- reg: specifies physical base address and size of register range.
+- interrupt-congroller: Identifies the node as an interrupt controller.
+- #interrupt cells: Specifies the number of cells used to encode an interrupt
+  source connected to this controller. The value shall be 2.
+- interrupt-parent: Specifies the parent interrupt controller.
+- interrupts: Specifies the list of interrupt lines which are handled by
+  the interrupt controller in the parent controller's notation. Interrupts
+  are mapped one-to-one to parent interrupts.
+
+Example
+-------
+
+intc: interrupt-controller {	/* Parent interrupt controller */
+	interrupt-controller;
+	#interrupt-cells = <1>;	/* For example below */
+	/* ... */
+};
+
+tb10x_ictl: pic@2000 {		/* TB10x interrupt controller */
+	compatible = "abilis,tb10x-ictl";
+	reg = <0x2000 0x20>;
+	interrupt-controller;
+	#interrupt-cells = <2>;
+	interrupt-parent = <&intc>;
+	interrupts = <5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
+			20 21 22 23 24 25 26 27 28 29 30 31>;
+};
Documentation/devicetree/bindings/interrupt-controller/marvell,orion-intc.txt new file +48 -0

48 lines not on this page · raw message

arch/arm/plat-orion/gpio.c +1 -1
index 249fe63..6816192 100644
@@ -426,7 +426,7 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 		if (!(cause & (1 << i)))
 			continue;
 
-		type = irqd_get_trigger_type(irq_get_irq_data(irq));
+		type = irq_get_trigger_type(irq);
 		if ((type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
 			/* Swap polarity (race with GPIO line) */
 			u32 polarity;
arch/mips/cavium-octeon/octeon-irq.c +1 -1
index a22f06a..7181def 100644
@@ -607,7 +607,7 @@ static void octeon_irq_ciu_gpio_ack(struct irq_data *data)
 
 static void octeon_irq_handle_gpio(unsigned int irq, struct irq_desc *desc)
 {
-	if (irqd_get_trigger_type(irq_desc_get_irq_data(desc)) & IRQ_TYPE_EDGE_BOTH)
+	if (irq_get_trigger_type(irq) & IRQ_TYPE_EDGE_BOTH)
 		handle_edge_irq(irq, desc);
 	else
 		handle_level_irq(irq, desc);
drivers/gpio/gpio-mvebu.c +1 -1
index 3a4816a..80ad35e 100644
@@ -457,7 +457,7 @@ static void mvebu_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 		if (!(cause & (1 << i)))
 			continue;
 
-		type = irqd_get_trigger_type(irq_get_irq_data(irq));
+		type = irq_get_trigger_type(irq);
 		if ((type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
 			/* Swap polarity (race with GPIO line) */
 			u32 polarity;
drivers/irqchip/Kconfig +15 -0
index 4a33351..1fea003 100644
@@ -10,6 +10,11 @@ config ARM_GIC
 config GIC_NON_BANKED
 	bool
 
+config ARM_NVIC
+	bool
+	select IRQ_DOMAIN
+	select GENERIC_IRQ_CHIP
+
 config ARM_VIC
 	bool
 	select IRQ_DOMAIN
@@ -25,6 +30,11 @@ config ARM_VIC_NR
 	  The maximum number of VICs available in the system, for
 	  power management.
 
+config ORION_IRQCHIP
+	bool
+	select IRQ_DOMAIN
+	select MULTI_IRQ_HANDLER
+
 config RENESAS_INTC_IRQPIN
 	bool
 	select IRQ_DOMAIN
@@ -33,6 +43,11 @@ config RENESAS_IRQC
 	bool
 	select IRQ_DOMAIN
 
+config TB10X_IRQC
+	bool
+	select IRQ_DOMAIN
+	select GENERIC_IRQ_CHIP
+
 config VERSATILE_FPGA_IRQ
 	bool
 	select IRQ_DOMAIN
drivers/irqchip/Makefile +3 -0
index cda4cb5..2065ef6 100644
@@ -7,12 +7,15 @@ obj-$(CONFIG_ARCH_MXS)			+= irq-mxs.o
 obj-$(CONFIG_ARCH_S3C24XX)		+= irq-s3c24xx.o
 obj-$(CONFIG_METAG)			+= irq-metag-ext.o
 obj-$(CONFIG_METAG_PERFCOUNTER_IRQS)	+= irq-metag.o
+obj-$(CONFIG_ORION_IRQCHIP)		+= irq-orion.o
 obj-$(CONFIG_ARCH_SUNXI)		+= irq-sun4i.o
 obj-$(CONFIG_ARCH_SPEAR3XX)		+= spear-shirq.o
 obj-$(CONFIG_ARM_GIC)			+= irq-gic.o
+obj-$(CONFIG_ARM_NVIC)			+= irq-nvic.o
 obj-$(CONFIG_ARM_VIC)			+= irq-vic.o
 obj-$(CONFIG_SIRF_IRQ)			+= irq-sirfsoc.o
 obj-$(CONFIG_RENESAS_INTC_IRQPIN)	+= irq-renesas-intc-irqpin.o
 obj-$(CONFIG_RENESAS_IRQC)		+= irq-renesas-irqc.o
 obj-$(CONFIG_VERSATILE_FPGA_IRQ)	+= irq-versatile-fpga.o
 obj-$(CONFIG_ARCH_VT8500)		+= irq-vt8500.o
+obj-$(CONFIG_TB10X_IRQC)		+= irq-tb10x.o
drivers/irqchip/exynos-combiner.c +4 -4
index a9d2b2f..4c68265 100644
@@ -204,10 +204,10 @@ static unsigned int combiner_lookup_irq(int group)
 	return 0;
 }
 
-void __init combiner_init(void __iomem *combiner_base,
-			  struct device_node *np,
-			  unsigned int max_nr,
-			  int irq_base)
+static void __init combiner_init(void __iomem *combiner_base,
+				 struct device_node *np,
+				 unsigned int max_nr,
+				 int irq_base)
 {
 	int i, irq;
 	unsigned int nr_irq;
drivers/irqchip/irq-nvic.c new file +117 -0

117 lines not on this page · raw message

drivers/irqchip/irq-orion.c new file +192 -0

192 lines not on this page · raw message

drivers/irqchip/irq-tb10x.c new file +195 -0

195 lines not on this page · raw message

drivers/mfd/stmpe.c +1 -2
index bbccd51..5d5e6f9 100644
@@ -1208,8 +1208,7 @@ int stmpe_probe(struct stmpe_client_info *ci, int partnum)
 		}
 		stmpe->variant = stmpe_noirq_variant_info[stmpe->partnum];
 	} else if (pdata->irq_trigger == IRQF_TRIGGER_NONE) {
-		pdata->irq_trigger =
-			irqd_get_trigger_type(irq_get_irq_data(stmpe->irq));
+		pdata->irq_trigger = irq_get_trigger_type(stmpe->irq);
 	}
 
 	ret = stmpe_chip_init(stmpe);
drivers/mfd/twl4030-irq.c +1 -4
index a5f9888..9d2d1ba 100644
@@ -537,16 +537,13 @@ static void twl4030_sih_bus_sync_unlock(struct irq_data *data)
 		/* Modify only the bits we know must change */
 		while (edge_change) {
 			int		i = fls(edge_change) - 1;
-			struct irq_data	*idata;
 			int		byte = i >> 2;
 			int		off = (i & 0x3) * 2;
 			unsigned int	type;
 
-			idata = irq_get_irq_data(i + agent->irq_base);
-
 			bytes[byte] &= ~(0x03 << off);
 
-			type = irqd_get_trigger_type(idata);
+			type = irq_get_trigger_type(i + agent->irq_base);
 			if (type & IRQ_TYPE_EDGE_RISING)
 				bytes[byte] |= BIT(off + 1);
 			if (type & IRQ_TYPE_EDGE_FALLING)
include/linux/irq.h +52 -1

129 lines not on this page · raw message

include/linux/irqdomain.h +12 -0
index 0d5b17b..ba2c708 100644
@@ -66,6 +66,10 @@ struct irq_domain_ops {
 		     unsigned long *out_hwirq, unsigned int *out_type);
 };
 
+extern struct irq_domain_ops irq_generic_chip_ops;
+
+struct irq_domain_chip_generic;
+
 /**
  * struct irq_domain - Hardware interrupt number translation object
  * @link: Element in global irq_domain list.
@@ -109,8 +113,16 @@ struct irq_domain {
 
 	/* Optional device node pointer */
 	struct device_node *of_node;
+	/* Optional pointer to generic interrupt chips */
+	struct irq_domain_chip_generic *gc;
 };
 
+#define IRQ_DOMAIN_MAP_LEGACY 0 /* driver allocated fixed range of irqs.
+				 * ie. legacy 8259, gets irqs 1..15 */
+#define IRQ_DOMAIN_MAP_NOMAP 1 /* no fast reverse mapping */
+#define IRQ_DOMAIN_MAP_LINEAR 2 /* linear map of interrupts */
+#define IRQ_DOMAIN_MAP_TREE 3 /* radix tree */
+
 #ifdef CONFIG_IRQ_DOMAIN
 struct irq_domain *irq_domain_add_simple(struct device_node *of_node,
 					 unsigned int size,
kernel/irq/chip.c +13 -0
index cbd97ce..a3bb14f 100644
@@ -213,6 +213,19 @@ void irq_enable(struct irq_desc *desc)
 	irq_state_clr_masked(desc);
 }
 
+/**
+ * irq_disable - Mark interupt disabled
+ * @desc:	irq descriptor which should be disabled
+ *
+ * If the chip does not implement the irq_disable callback, we
+ * use a lazy disable approach. That means we mark the interrupt
+ * disabled, but leave the hardware unmasked. That's an
+ * optimization because we avoid the hardware access for the
+ * common case where no interrupt happens after we marked it
+ * disabled. If an interrupt happens, then the interrupt flow
+ * handler masks the line at the hardware level and marks it
+ * pending.
+ */
 void irq_disable(struct irq_desc *desc)
 {
 	irq_state_set_disabled(desc);
kernel/irq/generic-chip.c +267 -47

484 lines not on this page · raw message

kernel/irq/irqdomain.c +1 -7
index 5a83dde..489921e 100644
@@ -16,12 +16,6 @@
 #include <linux/smp.h>
 #include <linux/fs.h>
 
-#define IRQ_DOMAIN_MAP_LEGACY 0 /* driver allocated fixed range of irqs.
-				 * ie. legacy 8259, gets irqs 1..15 */
-#define IRQ_DOMAIN_MAP_NOMAP 1 /* no fast reverse mapping */
-#define IRQ_DOMAIN_MAP_LINEAR 2 /* linear map of interrupts */
-#define IRQ_DOMAIN_MAP_TREE 3 /* radix tree */
-
 static LIST_HEAD(irq_domain_list);
 static DEFINE_MUTEX(irq_domain_mutex);
 
@@ -693,7 +687,7 @@ unsigned int irq_create_of_mapping(struct device_node *controller,
 
 	/* Set type if specified and different than the current one */
 	if (type != IRQ_TYPE_NONE &&
-	    type != (irqd_get_trigger_type(irq_get_irq_data(virq))))
+	    type != irq_get_trigger_type(virq))
 		irq_set_irq_type(virq, type);
 	return virq;
 }
kernel/irq/manage.c +9 -8
index fa17855..514bcfd 100644
@@ -555,9 +555,9 @@ int can_request_irq(unsigned int irq, unsigned long irqflags)
 		return 0;
 
 	if (irq_settings_can_request(desc)) {
-		if (desc->action)
-			if (irqflags & desc->action->flags & IRQF_SHARED)
-				canrequest =1;
+		if (!desc->action ||
+		    irqflags & desc->action->flags & IRQF_SHARED)
+			canrequest = 1;
 	}
 	irq_put_desc_unlock(desc, flags);
 	return canrequest;
@@ -840,9 +840,6 @@ static void irq_thread_dtor(struct callback_head *unused)
 static int irq_thread(void *data)
 {
 	struct callback_head on_exit_work;
-	static const struct sched_param param = {
-		.sched_priority = MAX_USER_RT_PRIO/2,
-	};
 	struct irqaction *action = data;
 	struct irq_desc *desc = irq_to_desc(action->irq);
 	irqreturn_t (*handler_fn)(struct irq_desc *desc,
@@ -854,8 +851,6 @@ static int irq_thread(void *data)
 	else
 		handler_fn = irq_thread_fn;
 
-	sched_setscheduler(current, SCHED_FIFO, &param);
-
 	init_task_work(&on_exit_work, irq_thread_dtor);
 	task_work_add(current, &on_exit_work, false);
 
@@ -950,6 +945,9 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
 	 */
 	if (new->thread_fn && !nested) {
 		struct task_struct *t;
+		static const struct sched_param param = {
+			.sched_priority = MAX_USER_RT_PRIO/2,
+		};
 
 		t = kthread_create(irq_thread, new, "irq/%d-%s", irq,
 				   new->name);
@@ -957,6 +955,9 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
 			ret = PTR_ERR(t);
 			goto out_mput;
 		}
+
+		sched_setscheduler(t, SCHED_FIFO, &param);
+
 		/*
 		 * We keep the reference to the task struct even if
 		 * the thread dies to avoid that the interrupt code
kernel/softirq.c +4 -6
index b5197dc..a5f8836 100644
@@ -127,8 +127,7 @@ static inline void __local_bh_disable(unsigned long ip, unsigned int cnt)
 
 void local_bh_disable(void)
 {
-	__local_bh_disable((unsigned long)__builtin_return_address(0),
-				SOFTIRQ_DISABLE_OFFSET);
+	__local_bh_disable(_RET_IP_, SOFTIRQ_DISABLE_OFFSET);
 }
 
 EXPORT_SYMBOL(local_bh_disable);
@@ -139,7 +138,7 @@ static void __local_bh_enable(unsigned int cnt)
 	WARN_ON_ONCE(!irqs_disabled());
 
 	if (softirq_count() == cnt)
-		trace_softirqs_on((unsigned long)__builtin_return_address(0));
+		trace_softirqs_on(_RET_IP_);
 	sub_preempt_count(cnt);
 }
 
@@ -184,7 +183,7 @@ static inline void _local_bh_enable_ip(unsigned long ip)
 
 void local_bh_enable(void)
 {
-	_local_bh_enable_ip((unsigned long)__builtin_return_address(0));
+	_local_bh_enable_ip(_RET_IP_);
 }
 EXPORT_SYMBOL(local_bh_enable);
 
@@ -223,8 +222,7 @@ asmlinkage void __do_softirq(void)
 	pending = local_softirq_pending();
 	account_irq_enter_time(current);
 
-	__local_bh_disable((unsigned long)__builtin_return_address(0),
-				SOFTIRQ_OFFSET);
+	__local_bh_disable(_RET_IP_, SOFTIRQ_OFFSET);
 	lockdep_softirq_enter();
 
 	cpu = smp_processor_id();