linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Kevin Cernekee <cernekee@gmail.com>
To: ralf@linux-mips.org
Cc: f.fainelli@gmail.com, jfraser@broadcom.com, dtor@chromium.org,
	tglx@linutronix.de, jason@lakedaemon.net, jogo@openwrt.org,
	arnd@arndb.de, computersforpeace@gmail.com,
	linux-mips@linux-mips.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: [PATCH V3 06/11] irqchip: bcm7120-l2: Change DT binding to allow non-contiguous IRQEN/IRQSTAT
Date: Sun, 23 Nov 2014 18:40:41 -0800	[thread overview]
Message-ID: <1416796846-28149-7-git-send-email-cernekee@gmail.com> (raw)
In-Reply-To: <1416796846-28149-1-git-send-email-cernekee@gmail.com>

To date, all supported controllers have had the IRQEN register at offset
0x00 and the IRQSTAT register at 0x04.  So in DT we would typically see
something like:

    reg = <0xf0406800 0x8>;

We still want to support this format, but we also need to support cases
where IRQEN and IRQSTAT aren't adjacent.  So, we will amend the driver to
accept an alternate format that looks like this:

    reg = <0xf0406800 0x4 0xf0406804 0x4>;

i.e. if the first resource_size() == 4, assume that the first resource
points to IRQEN and that the next resource points to IRQSTAT.  If the
first resource_size() == 8, retain the current behavior.

Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
---
 .../interrupt-controller/brcm,bcm7120-l2-intc.txt  |  5 +-
 drivers/irqchip/irq-bcm7120-l2.c                   | 76 +++++++++++++++++-----
 2 files changed, 63 insertions(+), 18 deletions(-)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7120-l2-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7120-l2-intc.txt
index bae1f2187226..e3b0cba9489a 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7120-l2-intc.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7120-l2-intc.txt
@@ -55,7 +55,10 @@ Required properties:
 - compatible: should be "brcm,bcm7120-l2-intc"
 - reg: specifies the base physical address and size of the registers;
   multiple pairs may be specified, with the first pair handling IRQ offsets
-  0..31 and the second pair handling 32..63
+  0..31 and the second pair handling 32..63. A register pair may be
+  specified as either <base 0x8>, where IRQEN lives at base+0x00 and
+  IRQSTAT lives at base+0x04, or <enreg 0x4 statreg 0x4>, where the
+  address of each register is listed independently.
 - interrupt-controller: identifies the node as an interrupt controller
 - #interrupt-cells: specifies the number of cells needed to encode an interrupt
   source, should be 1.
diff --git a/drivers/irqchip/irq-bcm7120-l2.c b/drivers/irqchip/irq-bcm7120-l2.c
index e8441ee7454c..576a92b34372 100644
--- a/drivers/irqchip/irq-bcm7120-l2.c
+++ b/drivers/irqchip/irq-bcm7120-l2.c
@@ -14,6 +14,7 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/kconfig.h>
+#include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
 #include <linux/of_irq.h>
@@ -22,6 +23,7 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/io.h>
+#include <linux/ioport.h>
 #include <linux/irqdomain.h>
 #include <linux/reboot.h>
 #include <linux/bitops.h>
@@ -29,12 +31,8 @@
 
 #include "irqchip.h"
 
-/* Register offset in the L2 interrupt controller */
-#define IRQEN		0x00
-#define IRQSTAT		0x04
-
 #define MAX_WORDS	4
-#define MAX_MAPPINGS	MAX_WORDS
+#define MAX_MAPPINGS	(MAX_WORDS * 2)
 #define IRQS_PER_WORD	32
 
 struct bcm7120_l2_intc_data {
@@ -128,6 +126,61 @@ static int bcm7120_l2_intc_init_one(struct device_node *dn,
 	return 0;
 }
 
+static int __init bcm7120_l2_intc_map_regs(struct device_node *dn,
+					   struct bcm7120_l2_intc_data *data)
+{
+	unsigned int idx, n_regs = 0, gc_idx = 0;
+	void __iomem *en_reg = NULL, *stat_reg = NULL;
+
+	for (idx = 0; n_regs < MAX_WORDS * 2; idx++) {
+		struct resource res;
+		resource_size_t sz;
+		void __iomem *map_base;
+
+		if (of_address_to_resource(dn, idx, &res))
+			break;
+		sz = resource_size(&res);
+		map_base = data->map_base[idx] = ioremap(res.start, sz);
+		if (!map_base)
+			return -EINVAL;
+
+		if (n_regs % 2 == 0) {
+			/* Accept either enable + status, or just enable:
+			 * reg = <0x10000024 0x8>;
+			 * reg = <0x10000024 0x4 0x1000002c 0x4>;
+			 */
+			en_reg = map_base;
+			if (sz == 8) {
+				stat_reg = map_base + 0x04;
+				n_regs += 2;
+			} else if (sz == 4) {
+				n_regs += 1;
+				continue;
+			} else {
+				return -EINVAL;
+			}
+		} else {
+			/* If the last register was enable, we're looking
+			 * for its corresponding status register
+			 */
+			if (sz == 4) {
+				stat_reg = map_base;
+				n_regs += 1;
+			} else {
+				return -EINVAL;
+			}
+		}
+
+		data->pair_base[gc_idx] = min(en_reg, stat_reg);
+		data->en_offset[gc_idx] = en_reg - data->pair_base[gc_idx];
+		data->stat_offset[gc_idx] = stat_reg - data->pair_base[gc_idx];
+		gc_idx++;
+	}
+
+	data->n_words = gc_idx;
+	return gc_idx ? 0 : -ENOENT;
+}
+
 int __init bcm7120_l2_intc_of_init(struct device_node *dn,
 					struct device_node *parent)
 {
@@ -144,18 +197,7 @@ int __init bcm7120_l2_intc_of_init(struct device_node *dn,
 	if (!data)
 		return -ENOMEM;
 
-	for (idx = 0; idx < MAX_WORDS; idx++) {
-		data->map_base[idx] = of_iomap(dn, idx);
-		if (!data->map_base[idx])
-			break;
-
-		data->pair_base[idx] = data->map_base[idx];
-		data->en_offset[idx] = IRQEN;
-		data->stat_offset[idx] = IRQSTAT;
-
-		data->n_words = idx + 1;
-	}
-	if (!data->n_words) {
+	if (bcm7120_l2_intc_map_regs(dn, data) < 0) {
 		pr_err("failed to remap intc L2 registers\n");
 		ret = -ENOMEM;
 		goto out_unmap;
-- 
2.1.1


  parent reply	other threads:[~2014-11-24  2:42 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-11-24  2:40 [PATCH V3 00/11] Multiplatform BMIPS kernel Kevin Cernekee
2014-11-24  2:40 ` [PATCH V3 01/11] irqchip: Update docs regarding irq_domain_add_tree() Kevin Cernekee
2014-11-24  2:40 ` [PATCH V3 02/11] irqchip: brcmstb-l2: don't clear wakeable interrupts at init time Kevin Cernekee
2014-11-24  2:40 ` [PATCH V3 03/11] irqchip: brcmstb-l2: fix error handling of irq_of_parse_and_map Kevin Cernekee
2014-11-24  2:40 ` [PATCH V3 04/11] irqchip: bcm7120-l2: " Kevin Cernekee
2014-11-24  2:40 ` [PATCH V3 05/11] irqchip: bcm7120-l2: Refactor driver for arbitrary IRQEN/IRQSTAT offsets Kevin Cernekee
2014-11-24  2:40 ` Kevin Cernekee [this message]
2014-11-24 14:31   ` [PATCH V3 06/11] irqchip: bcm7120-l2: Change DT binding to allow non-contiguous IRQEN/IRQSTAT Jonas Gorski
2014-11-26  5:18     ` Kevin Cernekee
2014-11-26  9:45       ` Jonas Gorski
2014-11-26 10:25         ` Jonas Gorski
2014-11-26 18:54           ` Kevin Cernekee
2014-11-26 20:13             ` Jonas Gorski
2014-11-26 21:06               ` Kevin Cernekee
2014-11-24  2:40 ` [PATCH V3 07/11] irqchip: Add new driver for BCM7038-style level 1 interrupt controllers Kevin Cernekee
2014-11-24  2:40 ` [PATCH V3 08/11] MIPS: Let __dt_register_buses accept a single bus type Kevin Cernekee
2014-11-24  2:40 ` [PATCH V3 09/11] MIPS: Fall back to the generic restart notifier Kevin Cernekee
2014-11-24  2:40 ` [PATCH V3 10/11] MIPS: Reorder MIPS_L1_CACHE_SHIFT priorities Kevin Cernekee
2014-11-24  2:40 ` [PATCH V3 11/11] MIPS: Add multiplatform BMIPS target Kevin Cernekee
2014-11-24 14:00   ` Arnd Bergmann
2014-11-24 18:34     ` Andrew Bresticker
2014-11-24 21:07     ` Kevin Cernekee
2014-11-24 21:39       ` Arnd Bergmann
2014-11-26 20:45         ` Kevin Cernekee
2014-11-26 21:28           ` Arnd Bergmann
2014-11-26 22:54             ` Kevin Cernekee
2014-11-24 19:29   ` Andrew Bresticker
2014-11-24 19:57     ` Kevin Cernekee
2014-11-24 13:34 ` [PATCH V3 00/11] Multiplatform BMIPS kernel Arnd Bergmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1416796846-28149-7-git-send-email-cernekee@gmail.com \
    --to=cernekee@gmail.com \
    --cc=arnd@arndb.de \
    --cc=computersforpeace@gmail.com \
    --cc=devicetree@vger.kernel.org \
    --cc=dtor@chromium.org \
    --cc=f.fainelli@gmail.com \
    --cc=jason@lakedaemon.net \
    --cc=jfraser@broadcom.com \
    --cc=jogo@openwrt.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mips@linux-mips.org \
    --cc=ralf@linux-mips.org \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).