All of lore.kernel.org
 help / color / mirror / Atom feed
From: f.fainelli@gmail.com (Florian Fainelli)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] irq-bcm2836: Move SMP boot to the irqchip code.
Date: Mon, 27 Jul 2015 11:46:25 -0700	[thread overview]
Message-ID: <55B67C81.1010900@gmail.com> (raw)
In-Reply-To: <1438022532-14576-1-git-send-email-eric@anholt.net>

On 27/07/15 11:42, Eric Anholt wrote:
> Signed-off-by: Eric Anholt <eric@anholt.net>
> ---
> 
> Thomas: The problem with delaying IPI unmasking until secondary boot
> is that it means we need the secondary boot process to integrate with
> the irqchip code, which seems unusual given the dearth of includes I
> could find between arch/arm/mach-* SMP boot code and drivers/irqchip/
> to get function prototypes.  However, since the irqchip is most of
> this register space already, it might make sense to just have the SMP
> boot live in drivers/irqchip/.  Here's a patch that would do that,
> that could be squashed into my change.

I do not think this patch is going to work, there are CPU notifiers that
allows you to listen for events (CPU_ONLINE, CPU_DEAD...) as to when
(re)configuration of an interrupt controller can become necessary in
other areas of the kernel.

drivers/irqchip/irq-gic*.c contains code that deals with this for instance.

> 
>  drivers/irqchip/irq-bcm2836.c | 57 +++++++++++++++++++++++++++++++++++++------
>  1 file changed, 50 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c
> index 87340b0..5f2a40e 100644
> --- a/drivers/irqchip/irq-bcm2836.c
> +++ b/drivers/irqchip/irq-bcm2836.c
> @@ -49,14 +49,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
> +#define LOCAL_MAILBOX3_SET0		0x08c
>  /* Mailbox0 write-to-clear bits. */
>  #define LOCAL_MAILBOX0_CLR0		0x0c0
> +#define LOCAL_MAILBOX3_CLR0		0x0cc
>  
>  #define LOCAL_IRQ_CNTPSIRQ	0
>  #define LOCAL_IRQ_CNTPNSIRQ	1
> @@ -195,6 +197,46 @@ static void bcm2836_arm_irqchip_send_ipi(const struct cpumask *mask,
>  		writel(1 << ipi, mailbox0_base + 16 * cpu);
>  	}
>  }
> +
> +/* Requests boot of a secondary CPU.
> + *
> + * The Raspberry Pi firmware has already started up the CPU and set it
> + * spinning in a loop in low memory waiting for a value in mailbox 3
> + * indicating what OS code it should jump to.
> + */
> +int __init bcm2836_smp_boot_secondary(unsigned int cpu, struct task_struct *idle)
> +{
> +	int timeout = 20;
> +	void __iomem *mailbox3_set_base = intc.base + LOCAL_MAILBOX3_SET0;
> +	void __iomem *mailbox3_clr_base = intc.base + LOCAL_MAILBOX3_CLR0;
> +	unsigned long secondary_startup_phys =
> +		(unsigned long) virt_to_phys((void *)secondary_startup);
> +
> +	/* Unmask IPIs to the target cpu. */
> +	bcm2836_arm_irqchip_unmask_per_cpu_irq(LOCAL_MAILBOX_INT_CONTROL0, 0,
> +					       cpu);
> +
> +	dsb();
> +
> +	writel(secondary_startup_phys, mailbox3_set_base + 16 * cpu);
> +
> +	while (true) {
> +		int val = readl(mailbox3_clr_base + 16 * cpu);
> +
> +		if (val == 0)
> +			return 0;
> +		if (timeout-- == 0)
> +			return -ETIMEDOUT;
> +		cpu_relax();
> +	}
> +
> +	return 0;
> +}
> +
> +static struct smp_operations bcm2836_smp_ops __initdata = {
> +	.smp_boot_secondary	= bcm2836_smp_boot_secondary,
> +};
> +
>  #endif
>  
>  static const struct irq_domain_ops bcm2836_arm_irqchip_intc_ops = {
> @@ -205,14 +247,15 @@ static void
>  bcm2836_arm_irqchip_smp_init(void)
>  {
>  #ifdef CONFIG_SMP
> -	int i;
> +	/* Unmask IPIs to the boot CPU. Other CPUs will be unmasked as
> +	 * they're brought up.
> +	 */
> +	bcm2836_arm_irqchip_unmask_per_cpu_irq(LOCAL_MAILBOX_INT_CONTROL0, 0,
> +					       smp_processor_id());
>  
> -	/* unmask IPIs */
> -	for_each_possible_cpu(i) {
> -		bcm2836_arm_irqchip_unmask_per_cpu_irq(
> -			LOCAL_MAILBOX_INT_CONTROL0, 0, i);
> -	}
>  	set_smp_cross_call(bcm2836_arm_irqchip_send_ipi);
> +
> +	smp_set_ops(&bcm2836_smp_ops);
>  #endif
>  }
>  
> 


-- 
Florian

WARNING: multiple messages have this Message-ID (diff)
From: Florian Fainelli <f.fainelli@gmail.com>
To: Eric Anholt <eric@anholt.net>, linux-arm-kernel@lists.infradead.org
Cc: devicetree@vger.kernel.org, Jason Cooper <jason@lakedaemon.net>,
	Stephen Warren <swarren@wwwdotorg.org>,
	Lee Jones <lee@kernel.org>,
	linux-kernel@vger.kernel.org,
	linux-rpi-kernel@lists.infradead.org,
	Thomas Gleixner <tglx@linutronix.de>
Subject: Re: [PATCH] irq-bcm2836: Move SMP boot to the irqchip code.
Date: Mon, 27 Jul 2015 11:46:25 -0700	[thread overview]
Message-ID: <55B67C81.1010900@gmail.com> (raw)
In-Reply-To: <1438022532-14576-1-git-send-email-eric@anholt.net>

On 27/07/15 11:42, Eric Anholt wrote:
> Signed-off-by: Eric Anholt <eric@anholt.net>
> ---
> 
> Thomas: The problem with delaying IPI unmasking until secondary boot
> is that it means we need the secondary boot process to integrate with
> the irqchip code, which seems unusual given the dearth of includes I
> could find between arch/arm/mach-* SMP boot code and drivers/irqchip/
> to get function prototypes.  However, since the irqchip is most of
> this register space already, it might make sense to just have the SMP
> boot live in drivers/irqchip/.  Here's a patch that would do that,
> that could be squashed into my change.

I do not think this patch is going to work, there are CPU notifiers that
allows you to listen for events (CPU_ONLINE, CPU_DEAD...) as to when
(re)configuration of an interrupt controller can become necessary in
other areas of the kernel.

drivers/irqchip/irq-gic*.c contains code that deals with this for instance.

> 
>  drivers/irqchip/irq-bcm2836.c | 57 +++++++++++++++++++++++++++++++++++++------
>  1 file changed, 50 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c
> index 87340b0..5f2a40e 100644
> --- a/drivers/irqchip/irq-bcm2836.c
> +++ b/drivers/irqchip/irq-bcm2836.c
> @@ -49,14 +49,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
> +#define LOCAL_MAILBOX3_SET0		0x08c
>  /* Mailbox0 write-to-clear bits. */
>  #define LOCAL_MAILBOX0_CLR0		0x0c0
> +#define LOCAL_MAILBOX3_CLR0		0x0cc
>  
>  #define LOCAL_IRQ_CNTPSIRQ	0
>  #define LOCAL_IRQ_CNTPNSIRQ	1
> @@ -195,6 +197,46 @@ static void bcm2836_arm_irqchip_send_ipi(const struct cpumask *mask,
>  		writel(1 << ipi, mailbox0_base + 16 * cpu);
>  	}
>  }
> +
> +/* Requests boot of a secondary CPU.
> + *
> + * The Raspberry Pi firmware has already started up the CPU and set it
> + * spinning in a loop in low memory waiting for a value in mailbox 3
> + * indicating what OS code it should jump to.
> + */
> +int __init bcm2836_smp_boot_secondary(unsigned int cpu, struct task_struct *idle)
> +{
> +	int timeout = 20;
> +	void __iomem *mailbox3_set_base = intc.base + LOCAL_MAILBOX3_SET0;
> +	void __iomem *mailbox3_clr_base = intc.base + LOCAL_MAILBOX3_CLR0;
> +	unsigned long secondary_startup_phys =
> +		(unsigned long) virt_to_phys((void *)secondary_startup);
> +
> +	/* Unmask IPIs to the target cpu. */
> +	bcm2836_arm_irqchip_unmask_per_cpu_irq(LOCAL_MAILBOX_INT_CONTROL0, 0,
> +					       cpu);
> +
> +	dsb();
> +
> +	writel(secondary_startup_phys, mailbox3_set_base + 16 * cpu);
> +
> +	while (true) {
> +		int val = readl(mailbox3_clr_base + 16 * cpu);
> +
> +		if (val == 0)
> +			return 0;
> +		if (timeout-- == 0)
> +			return -ETIMEDOUT;
> +		cpu_relax();
> +	}
> +
> +	return 0;
> +}
> +
> +static struct smp_operations bcm2836_smp_ops __initdata = {
> +	.smp_boot_secondary	= bcm2836_smp_boot_secondary,
> +};
> +
>  #endif
>  
>  static const struct irq_domain_ops bcm2836_arm_irqchip_intc_ops = {
> @@ -205,14 +247,15 @@ static void
>  bcm2836_arm_irqchip_smp_init(void)
>  {
>  #ifdef CONFIG_SMP
> -	int i;
> +	/* Unmask IPIs to the boot CPU. Other CPUs will be unmasked as
> +	 * they're brought up.
> +	 */
> +	bcm2836_arm_irqchip_unmask_per_cpu_irq(LOCAL_MAILBOX_INT_CONTROL0, 0,
> +					       smp_processor_id());
>  
> -	/* unmask IPIs */
> -	for_each_possible_cpu(i) {
> -		bcm2836_arm_irqchip_unmask_per_cpu_irq(
> -			LOCAL_MAILBOX_INT_CONTROL0, 0, i);
> -	}
>  	set_smp_cross_call(bcm2836_arm_irqchip_send_ipi);
> +
> +	smp_set_ops(&bcm2836_smp_ops);
>  #endif
>  }
>  
> 


-- 
Florian

  reply	other threads:[~2015-07-27 18:46 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-07-14  1:35 Raspberry Pi 2 interrupt controller support (v2) Second round Eric Anholt
2015-07-14  1:35 ` Eric Anholt
2015-07-14  1:35 ` Eric Anholt
2015-07-14  1:35 ` [PATCH v2 1/4] irqchip: bcm2835: Refactor handle_IRQ() calls out of MAKE_HWIRQ Eric Anholt
2015-07-14  1:35   ` Eric Anholt
2015-07-14  1:35 ` [PATCH v2 2/4] irqchip: bcm2835: If a parent interrupt is registered, chain from it Eric Anholt
2015-07-14  1:35   ` Eric Anholt
2015-07-22  2:08   ` Stephen Warren
2015-07-22  2:08     ` Stephen Warren
2015-07-22  2:08     ` Stephen Warren
2015-07-22 18:17     ` Eric Anholt
2015-07-22 18:17       ` Eric Anholt
2015-07-24  4:13       ` Stephen Warren
2015-07-24  4:13         ` Stephen Warren
2015-07-24  4:13         ` Stephen Warren
2015-07-14  1:35 ` [PATCH v2 3/4] irqchip: Add documentation for the bcm2836 interrupt controller Eric Anholt
2015-07-14  1:35   ` Eric Anholt
2015-07-14  1:35   ` Eric Anholt
2015-07-14  1:35 ` [PATCH v2 4/4] irqchip: Add bcm2836 interrupt controller for Raspberry Pi 2 Eric Anholt
2015-07-14  1:35   ` Eric Anholt
2015-07-22  2:09   ` Stephen Warren
2015-07-22  2:09     ` Stephen Warren
2015-07-22  2:09     ` Stephen Warren
2015-07-22 18:02     ` Eric Anholt
2015-07-22 18:02       ` Eric Anholt
2015-07-22 18:02       ` Eric Anholt
2015-07-26  9:52   ` Thomas Gleixner
2015-07-26  9:52     ` Thomas Gleixner
2015-07-26  9:52     ` Thomas Gleixner
2015-07-27 18:42     ` [PATCH] irq-bcm2836: Move SMP boot to the irqchip code Eric Anholt
2015-07-27 18:42       ` Eric Anholt
2015-07-27 18:46       ` Florian Fainelli [this message]
2015-07-27 18:46         ` Florian Fainelli
2015-07-27 20:09         ` [PATCH] irqchip: bcm2836: Use a CPU notifier enable IPIs Eric Anholt
2015-07-27 20:09           ` Eric Anholt
2015-08-02 10:22           ` Thomas Gleixner
2015-08-02 10:22             ` Thomas Gleixner
2015-08-02 10:22             ` Thomas Gleixner
2015-08-03 23:23             ` Eric Anholt
2015-08-03 23:23               ` Eric Anholt
2015-08-03 23:23               ` Eric Anholt
2015-08-04  7:14               ` Thomas Gleixner
2015-08-04  7:14                 ` Thomas Gleixner
2015-08-04  7:14                 ` Thomas Gleixner

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=55B67C81.1010900@gmail.com \
    --to=f.fainelli@gmail.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    /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.