linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] bcm2836 (Raspberry Pi 2) interrupt controller updates for 4.5
@ 2015-12-26 21:47 Eric Anholt
  2015-12-26 21:47 ` [PATCH 1/4] irqchip: bcm2836: Fix initialization of the LOCAL_IRQ_CNT*IRQ timers Eric Anholt
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Eric Anholt @ 2015-12-26 21:47 UTC (permalink / raw)
  To: linux-arm-kernel

While the 2836 interrupt controller technically works, it would be
nice to merge these improvements to it, adding SMP booting, fixing the
timers, and fixing an apparently-spurious error message.

Patches 1, 2 were seen before in the full Pi 2 series I sent recently,
now with their summary prefixes fixed and a minor style cleanup to #2.
Patches 3, 4 are new, but trivial.

Andrea Merello (3):
  irqchip: bcm2836: Add SMP support for the 2836
  irqchip: bcm2836: tolerate IRQs while no flag is set in ISR
  irqchip: bcm2836: make code more readable

Eric Anholt (1):
  irqchip: bcm2836: Fix initialization of the LOCAL_IRQ_CNT*IRQ timers

 drivers/irqchip/irq-bcm2836.c | 55 +++++++++++++++++++++++++++++++++++++++----
 1 file changed, 51 insertions(+), 4 deletions(-)

-- 
2.6.2

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/4] irqchip: bcm2836: Fix initialization of the LOCAL_IRQ_CNT*IRQ timers
  2015-12-26 21:47 [PATCH 0/4] bcm2836 (Raspberry Pi 2) interrupt controller updates for 4.5 Eric Anholt
@ 2015-12-26 21:47 ` Eric Anholt
  2015-12-26 21:47 ` [PATCH 2/4] irqchip: bcm2836: Add SMP support for the 2836 Eric Anholt
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 7+ messages in thread
From: Eric Anholt @ 2015-12-26 21:47 UTC (permalink / raw)
  To: linux-arm-kernel

The irqchip's register area includes the the setup for the timer's
scaling factors, and for the platform we want a fixed configuration of
these registers.

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 drivers/irqchip/irq-bcm2836.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c
index f687082..6ec125e 100644
--- a/drivers/irqchip/irq-bcm2836.c
+++ b/drivers/irqchip/irq-bcm2836.c
@@ -21,6 +21,9 @@
 #include <linux/irqdomain.h>
 #include <asm/exception.h>
 
+#define LOCAL_CONTROL			0x000
+#define LOCAL_PRESCALER			0x008
+
 /*
  * The low 2 bits identify the CPU that the GPU IRQ goes to, and the
  * next 2 bits identify the CPU that the GPU FIQ goes to.
@@ -237,6 +240,27 @@ bcm2836_arm_irqchip_smp_init(void)
 #endif
 }
 
+/*
+ * The LOCAL_IRQ_CNT* timer firings are based off of the external
+ * oscillator with some scaling.  The firmware sets up CNTFRQ to
+ * report 19.2Mhz, but doesn't set up the scaling registers.
+ */
+static void bcm2835_init_local_timer_frequency(void)
+{
+	/*
+	 * Set the timer to source from the 19.2Mhz crystal clock (bit
+	 * 8 unset), and only increment by 1 instead of 2 (bit 9
+	 * unset).
+	 */
+	writel(0, intc.base + LOCAL_CONTROL);
+
+	/*
+	 * Set the timer prescaler to 1:1 (timer freq = input freq *
+	 * 2**31 / prescaler)
+	 */
+	writel(0x80000000, intc.base + LOCAL_PRESCALER);
+}
+
 static int __init bcm2836_arm_irqchip_l1_intc_of_init(struct device_node *node,
 						      struct device_node *parent)
 {
@@ -246,6 +270,8 @@ static int __init bcm2836_arm_irqchip_l1_intc_of_init(struct device_node *node,
 			node->full_name);
 	}
 
+	bcm2835_init_local_timer_frequency();
+
 	intc.domain = irq_domain_add_linear(node, LAST_IRQ + 1,
 					    &bcm2836_arm_irqchip_intc_ops,
 					    NULL);
-- 
2.6.2

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/4] irqchip: bcm2836: Add SMP support for the 2836
  2015-12-26 21:47 [PATCH 0/4] bcm2836 (Raspberry Pi 2) interrupt controller updates for 4.5 Eric Anholt
  2015-12-26 21:47 ` [PATCH 1/4] irqchip: bcm2836: Fix initialization of the LOCAL_IRQ_CNT*IRQ timers Eric Anholt
@ 2015-12-26 21:47 ` Eric Anholt
  2016-01-02 10:27   ` Russell King - ARM Linux
  2015-12-26 21:47 ` [PATCH 3/4] irqchip: bcm2836: tolerate IRQs while no flag is set in ISR Eric Anholt
  2015-12-26 21:47 ` [PATCH 4/4] irqchip: bcm2836: make code more readable Eric Anholt
  3 siblings, 1 reply; 7+ messages in thread
From: Eric Anholt @ 2015-12-26 21:47 UTC (permalink / raw)
  To: linux-arm-kernel

From: Andrea Merello <andrea.merello@gmail.com>

The firmware sets the secondaries spinning waiting for a non-NULL
value to show up in the last IPI mailbox.

The original SMP port from the downstream tree was done by Andrea, and
Eric cleaned it up/rewrote it a few times from there.

Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
---

v2: Merge into another CONFIG_SMP block.

 drivers/irqchip/irq-bcm2836.c | 25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c
index 6ec125e..59ac40c 100644
--- a/drivers/irqchip/irq-bcm2836.c
+++ b/drivers/irqchip/irq-bcm2836.c
@@ -53,14 +53,16 @@
 /* Same status bits as above, but for FIQ. */
 #define LOCAL_FIQ_PENDING0		0x070
 /*
- * Mailbox0 write-to-set bits.  There are 16 mailboxes, 4 per CPU, and
+ * Mailbox write-to-set bits.  There are 16 mailboxes, 4 per CPU, and
  * these bits are organized by mailbox number and then CPU number.  We
  * use mailbox 0 for IPIs.  The mailbox's interrupt is raised while
  * any bit is set.
  */
 #define LOCAL_MAILBOX0_SET0		0x080
-/* Mailbox0 write-to-clear bits. */
+#define LOCAL_MAILBOX3_SET0		0x08c
+/* Mailbox write-to-clear bits. */
 #define LOCAL_MAILBOX0_CLR0		0x0c0
+#define LOCAL_MAILBOX3_CLR0		0x0cc
 
 #define LOCAL_IRQ_CNTPSIRQ	0
 #define LOCAL_IRQ_CNTPNSIRQ	1
@@ -220,6 +222,24 @@ static struct notifier_block bcm2836_arm_irqchip_cpu_notifier = {
 	.notifier_call = bcm2836_arm_irqchip_cpu_notify,
 	.priority = 100,
 };
+
+int __init bcm2836_smp_boot_secondary(unsigned int cpu,
+				      struct task_struct *idle)
+{
+	unsigned long secondary_startup_phys =
+		(unsigned long)virt_to_phys((void *)secondary_startup);
+
+	dsb();
+	writel(secondary_startup_phys,
+	       intc.base + LOCAL_MAILBOX3_SET0 + 16 * cpu);
+
+	return 0;
+}
+
+static const struct smp_operations bcm2836_smp_ops __initconst = {
+	.smp_boot_secondary	= bcm2836_smp_boot_secondary,
+};
+
 #endif
 
 static const struct irq_domain_ops bcm2836_arm_irqchip_intc_ops = {
@@ -237,6 +257,7 @@ bcm2836_arm_irqchip_smp_init(void)
 	register_cpu_notifier(&bcm2836_arm_irqchip_cpu_notifier);
 
 	set_smp_cross_call(bcm2836_arm_irqchip_send_ipi);
+	smp_set_ops(&bcm2836_smp_ops);
 #endif
 }
 
-- 
2.6.2

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/4] irqchip: bcm2836: tolerate IRQs while no flag is set in ISR
  2015-12-26 21:47 [PATCH 0/4] bcm2836 (Raspberry Pi 2) interrupt controller updates for 4.5 Eric Anholt
  2015-12-26 21:47 ` [PATCH 1/4] irqchip: bcm2836: Fix initialization of the LOCAL_IRQ_CNT*IRQ timers Eric Anholt
  2015-12-26 21:47 ` [PATCH 2/4] irqchip: bcm2836: Add SMP support for the 2836 Eric Anholt
@ 2015-12-26 21:47 ` Eric Anholt
  2015-12-26 21:47 ` [PATCH 4/4] irqchip: bcm2836: make code more readable Eric Anholt
  3 siblings, 0 replies; 7+ messages in thread
From: Eric Anholt @ 2015-12-26 21:47 UTC (permalink / raw)
  To: linux-arm-kernel

From: Andrea Merello <andrea.merello@gmail.com>

On my RPi2 I got a lot of:
unexpected IRQ trap at vector 00

This happens because bcm2836_arm_irqchip_handle_irq() is sometimes
invoked even if the ISR is clear, and this case is not handled.

This patch explicitly handle this case, fixing the kernel complaints
about the bad IRQ lookup.

Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Eric Anholt <eric@anholt.net>
---
 drivers/irqchip/irq-bcm2836.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c
index 59ac40c..bb8f234 100644
--- a/drivers/irqchip/irq-bcm2836.c
+++ b/drivers/irqchip/irq-bcm2836.c
@@ -177,7 +177,7 @@ __exception_irq_entry bcm2836_arm_irqchip_handle_irq(struct pt_regs *regs)
 		writel(1 << ipi, mailbox0);
 		handle_IPI(ipi, regs);
 #endif
-	} else {
+	} else if (stat) {
 		u32 hwirq = ffs(stat) - 1;
 
 		handle_IRQ(irq_linear_revmap(intc.domain, hwirq), regs);
-- 
2.6.2

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 4/4] irqchip: bcm2836: make code more readable
  2015-12-26 21:47 [PATCH 0/4] bcm2836 (Raspberry Pi 2) interrupt controller updates for 4.5 Eric Anholt
                   ` (2 preceding siblings ...)
  2015-12-26 21:47 ` [PATCH 3/4] irqchip: bcm2836: tolerate IRQs while no flag is set in ISR Eric Anholt
@ 2015-12-26 21:47 ` Eric Anholt
  3 siblings, 0 replies; 7+ messages in thread
From: Eric Anholt @ 2015-12-26 21:47 UTC (permalink / raw)
  To: linux-arm-kernel

From: Andrea Merello <andrea.merello@gmail.com>

Avoid using hardcoded magics. We have a #define for this number.
No functional changes.

Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Eric Anholt <eric@anholt.net>
---
 drivers/irqchip/irq-bcm2836.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c
index bb8f234..963065a 100644
--- a/drivers/irqchip/irq-bcm2836.c
+++ b/drivers/irqchip/irq-bcm2836.c
@@ -167,7 +167,7 @@ __exception_irq_entry bcm2836_arm_irqchip_handle_irq(struct pt_regs *regs)
 	u32 stat;
 
 	stat = readl_relaxed(intc.base + LOCAL_IRQ_PENDING0 + 4 * cpu);
-	if (stat & 0x10) {
+	if (stat & BIT(LOCAL_IRQ_MAILBOX0)) {
 #ifdef CONFIG_SMP
 		void __iomem *mailbox0 = (intc.base +
 					  LOCAL_MAILBOX0_CLR0 + 16 * cpu);
-- 
2.6.2

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/4] irqchip: bcm2836: Add SMP support for the 2836
  2015-12-26 21:47 ` [PATCH 2/4] irqchip: bcm2836: Add SMP support for the 2836 Eric Anholt
@ 2016-01-02 10:27   ` Russell King - ARM Linux
  2016-01-02 16:05     ` Andrea Merello
  0 siblings, 1 reply; 7+ messages in thread
From: Russell King - ARM Linux @ 2016-01-02 10:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Dec 26, 2015 at 01:47:22PM -0800, Eric Anholt wrote:
> +int __init bcm2836_smp_boot_secondary(unsigned int cpu,
> +				      struct task_struct *idle)
> +{
> +	unsigned long secondary_startup_phys =
> +		(unsigned long)virt_to_phys((void *)secondary_startup);
> +
> +	dsb();
> +	writel(secondary_startup_phys,
> +	       intc.base + LOCAL_MAILBOX3_SET0 + 16 * cpu);

Please explain why you need this dsb() - I can't see a reason for it.
writel() has a barrier internally prior to writing the register, and
therefore I think the above dsb() is entirely redundant.

-- 
RMK's Patch system: http://www.arm.linux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 2/4] irqchip: bcm2836: Add SMP support for the 2836
  2016-01-02 10:27   ` Russell King - ARM Linux
@ 2016-01-02 16:05     ` Andrea Merello
  0 siblings, 0 replies; 7+ messages in thread
From: Andrea Merello @ 2016-01-02 16:05 UTC (permalink / raw)
  To: linux-arm-kernel

Agreed.
This probably comes from the downstream code, I think.. But I agree
it's actually redundant.

Thank you for pointing this out.

On Sat, Jan 2, 2016 at 11:27 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Sat, Dec 26, 2015 at 01:47:22PM -0800, Eric Anholt wrote:
>> +int __init bcm2836_smp_boot_secondary(unsigned int cpu,
>> +                                   struct task_struct *idle)
>> +{
>> +     unsigned long secondary_startup_phys =
>> +             (unsigned long)virt_to_phys((void *)secondary_startup);
>> +
>> +     dsb();
>> +     writel(secondary_startup_phys,
>> +            intc.base + LOCAL_MAILBOX3_SET0 + 16 * cpu);
>
> Please explain why you need this dsb() - I can't see a reason for it.
> writel() has a barrier internally prior to writing the register, and
> therefore I think the above dsb() is entirely redundant.
>
> --
> RMK's Patch system: http://www.arm.linux.org.uk/developer/patches/
> FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
> according to speedtest.net.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2016-01-02 16:05 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-12-26 21:47 [PATCH 0/4] bcm2836 (Raspberry Pi 2) interrupt controller updates for 4.5 Eric Anholt
2015-12-26 21:47 ` [PATCH 1/4] irqchip: bcm2836: Fix initialization of the LOCAL_IRQ_CNT*IRQ timers Eric Anholt
2015-12-26 21:47 ` [PATCH 2/4] irqchip: bcm2836: Add SMP support for the 2836 Eric Anholt
2016-01-02 10:27   ` Russell King - ARM Linux
2016-01-02 16:05     ` Andrea Merello
2015-12-26 21:47 ` [PATCH 3/4] irqchip: bcm2836: tolerate IRQs while no flag is set in ISR Eric Anholt
2015-12-26 21:47 ` [PATCH 4/4] irqchip: bcm2836: make code more readable Eric Anholt

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).