All of lore.kernel.org
 help / color / mirror / Atom feed
From: Florian Fainelli <f.fainelli@gmail.com>
To: linux-kernel@vger.kernel.org
Cc: Florian Fainelli <f.fainelli@gmail.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Jason Cooper <jason@lakedaemon.net>,
	Marc Zyngier <maz@kernel.org>, Rob Herring <robh+dt@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>,
	bcm-kernel-feedback-list@broadcom.com (maintainer:BROADCOM
	BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...),
	devicetree@vger.kernel.org (open list:OPEN FIRMWARE AND
	FLATTENED DEVICE TREE BINDINGS),
	linux-arm-kernel@lists.infradead.org (moderated list:BROADCOM
	BCM2835 ARM ARCHITECTURE)
Subject: [PATCH v3 5/5] irqchip/irq-bcm7038-l1: Support brcm,int-fwd-mask
Date: Thu, 24 Oct 2019 13:14:15 -0700	[thread overview]
Message-ID: <20191024201415.23454-6-f.fainelli@gmail.com> (raw)
In-Reply-To: <20191024201415.23454-1-f.fainelli@gmail.com>

On some specific chips like 7211 we need to leave some interrupts
untouched/forwarded to the VPU which is another agent in the system
making use of that interrupt controller hardware (goes to both ARM GIC
and VPU L1 interrupt controller). Make that possible by using the
existing brcm,int-fwd-mask property and take necessary actions to avoid
masking that interrupt as well as not allowing Linux to map them.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/irqchip/irq-bcm7038-l1.c | 30 ++++++++++++++++++++++++++----
 1 file changed, 26 insertions(+), 4 deletions(-)

diff --git a/drivers/irqchip/irq-bcm7038-l1.c b/drivers/irqchip/irq-bcm7038-l1.c
index 45879e59e58b..cbf01afcd2a6 100644
--- a/drivers/irqchip/irq-bcm7038-l1.c
+++ b/drivers/irqchip/irq-bcm7038-l1.c
@@ -44,6 +44,7 @@ struct bcm7038_l1_chip {
 	struct list_head	list;
 	u32			wake_mask[MAX_WORDS];
 #endif
+	u32			irq_fwd_mask[MAX_WORDS];
 	u8			affinity[MAX_WORDS * IRQS_PER_WORD];
 };
 
@@ -254,6 +255,7 @@ static int __init bcm7038_l1_init_one(struct device_node *dn,
 	resource_size_t sz;
 	struct bcm7038_l1_cpu *cpu;
 	unsigned int i, n_words, parent_irq;
+	int ret;
 
 	if (of_address_to_resource(dn, idx, &res))
 		return -EINVAL;
@@ -267,6 +269,14 @@ static int __init bcm7038_l1_init_one(struct device_node *dn,
 	else if (intc->n_words != n_words)
 		return -EINVAL;
 
+	ret = of_property_read_u32_array(dn , "brcm,int-fwd-mask",
+					 intc->irq_fwd_mask, n_words);
+	if (ret != 0 && ret != -EINVAL) {
+		/* property exists but has the wrong number of words */
+		pr_err("invalid brcm,int-fwd-mask property\n");
+		return -EINVAL;
+	}
+
 	cpu = intc->cpus[idx] = kzalloc(sizeof(*cpu) + n_words * sizeof(u32),
 					GFP_KERNEL);
 	if (!cpu)
@@ -277,8 +287,11 @@ static int __init bcm7038_l1_init_one(struct device_node *dn,
 		return -ENOMEM;
 
 	for (i = 0; i < n_words; i++) {
-		l1_writel(0xffffffff, cpu->map_base + reg_mask_set(intc, i));
-		cpu->mask_cache[i] = 0xffffffff;
+		l1_writel(~intc->irq_fwd_mask[i],
+			  cpu->map_base + reg_mask_set(intc, i));
+		l1_writel(intc->irq_fwd_mask[i],
+			  cpu->map_base + reg_mask_clr(intc, i));
+		cpu->mask_cache[i] = ~intc->irq_fwd_mask[i];
 	}
 
 	parent_irq = irq_of_parse_and_map(dn, idx);
@@ -311,15 +324,17 @@ static int bcm7038_l1_suspend(void)
 {
 	struct bcm7038_l1_chip *intc;
 	int boot_cpu, word;
+	u32 val;
 
 	/* Wakeup interrupt should only come from the boot cpu */
 	boot_cpu = cpu_logical_map(0);
 
 	list_for_each_entry(intc, &bcm7038_l1_intcs_list, list) {
 		for (word = 0; word < intc->n_words; word++) {
-			l1_writel(~intc->wake_mask[word],
+			val = intc->wake_mask[word] | intc->irq_fwd_mask[word];
+			l1_writel(~val,
 				intc->cpus[boot_cpu]->map_base + reg_mask_set(intc, word));
-			l1_writel(intc->wake_mask[word],
+			l1_writel(val,
 				intc->cpus[boot_cpu]->map_base + reg_mask_clr(intc, word));
 		}
 	}
@@ -383,6 +398,13 @@ static struct irq_chip bcm7038_l1_irq_chip = {
 static int bcm7038_l1_map(struct irq_domain *d, unsigned int virq,
 			  irq_hw_number_t hw_irq)
 {
+	struct bcm7038_l1_chip *intc = d->host_data;
+	u32 mask = BIT(hw_irq % IRQS_PER_WORD);
+	u32 word = hw_irq / IRQS_PER_WORD;
+
+	if (intc->irq_fwd_mask[word] & mask)
+		return -EPERM;
+
 	irq_set_chip_and_handler(virq, &bcm7038_l1_irq_chip, handle_level_irq);
 	irq_set_chip_data(virq, d->host_data);
 	irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(virq)));
-- 
2.17.1


WARNING: multiple messages have this Message-ID (diff)
From: Florian Fainelli <f.fainelli@gmail.com>
To: linux-kernel@vger.kernel.org
Cc: Mark Rutland <mark.rutland@arm.com>,
	"open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS"
	<devicetree@vger.kernel.org>,
	Florian Fainelli <f.fainelli@gmail.com>,
	Jason Cooper <jason@lakedaemon.net>,
	Marc Zyngier <maz@kernel.org>, Rob Herring <robh+dt@kernel.org>,
	"maintainer:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE..."
	<bcm-kernel-feedback-list@broadcom.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	"moderated list:BROADCOM BCM2835 ARM ARCHITECTURE"
	<linux-arm-kernel@lists.infradead.org>
Subject: [PATCH v3 5/5] irqchip/irq-bcm7038-l1: Support brcm,int-fwd-mask
Date: Thu, 24 Oct 2019 13:14:15 -0700	[thread overview]
Message-ID: <20191024201415.23454-6-f.fainelli@gmail.com> (raw)
In-Reply-To: <20191024201415.23454-1-f.fainelli@gmail.com>

On some specific chips like 7211 we need to leave some interrupts
untouched/forwarded to the VPU which is another agent in the system
making use of that interrupt controller hardware (goes to both ARM GIC
and VPU L1 interrupt controller). Make that possible by using the
existing brcm,int-fwd-mask property and take necessary actions to avoid
masking that interrupt as well as not allowing Linux to map them.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/irqchip/irq-bcm7038-l1.c | 30 ++++++++++++++++++++++++++----
 1 file changed, 26 insertions(+), 4 deletions(-)

diff --git a/drivers/irqchip/irq-bcm7038-l1.c b/drivers/irqchip/irq-bcm7038-l1.c
index 45879e59e58b..cbf01afcd2a6 100644
--- a/drivers/irqchip/irq-bcm7038-l1.c
+++ b/drivers/irqchip/irq-bcm7038-l1.c
@@ -44,6 +44,7 @@ struct bcm7038_l1_chip {
 	struct list_head	list;
 	u32			wake_mask[MAX_WORDS];
 #endif
+	u32			irq_fwd_mask[MAX_WORDS];
 	u8			affinity[MAX_WORDS * IRQS_PER_WORD];
 };
 
@@ -254,6 +255,7 @@ static int __init bcm7038_l1_init_one(struct device_node *dn,
 	resource_size_t sz;
 	struct bcm7038_l1_cpu *cpu;
 	unsigned int i, n_words, parent_irq;
+	int ret;
 
 	if (of_address_to_resource(dn, idx, &res))
 		return -EINVAL;
@@ -267,6 +269,14 @@ static int __init bcm7038_l1_init_one(struct device_node *dn,
 	else if (intc->n_words != n_words)
 		return -EINVAL;
 
+	ret = of_property_read_u32_array(dn , "brcm,int-fwd-mask",
+					 intc->irq_fwd_mask, n_words);
+	if (ret != 0 && ret != -EINVAL) {
+		/* property exists but has the wrong number of words */
+		pr_err("invalid brcm,int-fwd-mask property\n");
+		return -EINVAL;
+	}
+
 	cpu = intc->cpus[idx] = kzalloc(sizeof(*cpu) + n_words * sizeof(u32),
 					GFP_KERNEL);
 	if (!cpu)
@@ -277,8 +287,11 @@ static int __init bcm7038_l1_init_one(struct device_node *dn,
 		return -ENOMEM;
 
 	for (i = 0; i < n_words; i++) {
-		l1_writel(0xffffffff, cpu->map_base + reg_mask_set(intc, i));
-		cpu->mask_cache[i] = 0xffffffff;
+		l1_writel(~intc->irq_fwd_mask[i],
+			  cpu->map_base + reg_mask_set(intc, i));
+		l1_writel(intc->irq_fwd_mask[i],
+			  cpu->map_base + reg_mask_clr(intc, i));
+		cpu->mask_cache[i] = ~intc->irq_fwd_mask[i];
 	}
 
 	parent_irq = irq_of_parse_and_map(dn, idx);
@@ -311,15 +324,17 @@ static int bcm7038_l1_suspend(void)
 {
 	struct bcm7038_l1_chip *intc;
 	int boot_cpu, word;
+	u32 val;
 
 	/* Wakeup interrupt should only come from the boot cpu */
 	boot_cpu = cpu_logical_map(0);
 
 	list_for_each_entry(intc, &bcm7038_l1_intcs_list, list) {
 		for (word = 0; word < intc->n_words; word++) {
-			l1_writel(~intc->wake_mask[word],
+			val = intc->wake_mask[word] | intc->irq_fwd_mask[word];
+			l1_writel(~val,
 				intc->cpus[boot_cpu]->map_base + reg_mask_set(intc, word));
-			l1_writel(intc->wake_mask[word],
+			l1_writel(val,
 				intc->cpus[boot_cpu]->map_base + reg_mask_clr(intc, word));
 		}
 	}
@@ -383,6 +398,13 @@ static struct irq_chip bcm7038_l1_irq_chip = {
 static int bcm7038_l1_map(struct irq_domain *d, unsigned int virq,
 			  irq_hw_number_t hw_irq)
 {
+	struct bcm7038_l1_chip *intc = d->host_data;
+	u32 mask = BIT(hw_irq % IRQS_PER_WORD);
+	u32 word = hw_irq / IRQS_PER_WORD;
+
+	if (intc->irq_fwd_mask[word] & mask)
+		return -EPERM;
+
 	irq_set_chip_and_handler(virq, &bcm7038_l1_irq_chip, handle_level_irq);
 	irq_set_chip_data(virq, d->host_data);
 	irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(virq)));
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  parent reply	other threads:[~2019-10-24 20:14 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-24 20:14 [PATCH v3 0/5] irqchip/irq-bcm7038-l1 updates Florian Fainelli
2019-10-24 20:14 ` Florian Fainelli
2019-10-24 20:14 ` [PATCH v3 1/5] irqchip/irq-bcm7038-l1: Add PM support Florian Fainelli
2019-10-24 20:14   ` Florian Fainelli
2019-11-20 13:21   ` [tip: irq/core] " tip-bot2 for Justin Chen
2019-10-24 20:14 ` [PATCH v3 2/5] dt-bindings: Document brcm,irq-can-wake for brcm,bcm7038-l1-intc.txt Florian Fainelli
2019-10-24 20:14   ` [PATCH v3 2/5] dt-bindings: Document brcm, irq-can-wake for brcm, bcm7038-l1-intc.txt Florian Fainelli
2019-11-20 13:21   ` [tip: irq/core] " tip-bot2 for Florian Fainelli
2019-10-24 20:14 ` [PATCH v3 3/5] irqchip/irq-bcm7038-l1: Enable parent IRQ if necessary Florian Fainelli
2019-10-24 20:14   ` Florian Fainelli
2019-11-20 13:21   ` [tip: irq/core] " tip-bot2 for Florian Fainelli
2019-10-24 20:14 ` [PATCH v3 4/5] dt-bindings: Document brcm,int-fwd-mask property for bcm7038-l1-intc Florian Fainelli
2019-10-24 20:14   ` [PATCH v3 4/5] dt-bindings: Document brcm, int-fwd-mask " Florian Fainelli
2019-11-20 13:21   ` [tip: irq/core] " tip-bot2 for Florian Fainelli
2019-10-24 20:14 ` Florian Fainelli [this message]
2019-10-24 20:14   ` [PATCH v3 5/5] irqchip/irq-bcm7038-l1: Support brcm,int-fwd-mask Florian Fainelli
2019-11-20 13:21   ` [tip: irq/core] " tip-bot2 for Florian Fainelli
2019-11-11 10:52 ` [PATCH v3 0/5] irqchip/irq-bcm7038-l1 updates Marc Zyngier
2019-11-11 10:52   ` Marc Zyngier

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=20191024201415.23454-6-f.fainelli@gmail.com \
    --to=f.fainelli@gmail.com \
    --cc=bcm-kernel-feedback-list@broadcom.com \
    --cc=devicetree@vger.kernel.org \
    --cc=jason@lakedaemon.net \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=maz@kernel.org \
    --cc=robh+dt@kernel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.