All of lore.kernel.org
 help / color / mirror / Atom feed
From: santosh.shilimkar@ti.com (Santosh Shilimkar)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 02/16] ARM: b.L: introduce the CPU/cluster power API
Date: Sat, 12 Jan 2013 00:11:24 +0530	[thread overview]
Message-ID: <50F05CD4.8050905@ti.com> (raw)
In-Reply-To: <alpine.LFD.2.02.1301111312180.6300@xanadu.home>

On Saturday 12 January 2013 12:03 AM, Nicolas Pitre wrote:
> On Fri, 11 Jan 2013, Santosh Shilimkar wrote:
>
>> On Thursday 10 January 2013 05:50 AM, Nicolas Pitre wrote:
>>> This is the basic API used to handle the powering up/down of individual
>>> CPUs in a big.LITTLE system.  The platform specific backend implementation
>>> has the responsibility to also handle the cluster level power as well when
>>> the first/last CPU in a cluster is brought up/down.
>>>
>>> Signed-off-by: Nicolas Pitre <nico@linaro.org>
>>> ---
>>>    arch/arm/common/bL_entry.c      | 88
>>> +++++++++++++++++++++++++++++++++++++++
>>>    arch/arm/include/asm/bL_entry.h | 92
>>> +++++++++++++++++++++++++++++++++++++++++
>>>    2 files changed, 180 insertions(+)
>>>
>>> diff --git a/arch/arm/common/bL_entry.c b/arch/arm/common/bL_entry.c
>>> index 80fff49417..41de0622de 100644
>>> --- a/arch/arm/common/bL_entry.c
>>> +++ b/arch/arm/common/bL_entry.c
>>> @@ -11,11 +11,13 @@
>>>
>>>    #include <linux/kernel.h>
>>>    #include <linux/init.h>
>>> +#include <linux/irqflags.h>
>>>
>>>    #include <asm/bL_entry.h>
>>>    #include <asm/barrier.h>
>>>    #include <asm/proc-fns.h>
>>>    #include <asm/cacheflush.h>
>>> +#include <asm/idmap.h>
>>>
>>>    extern volatile unsigned long
>>> bL_entry_vectors[BL_NR_CLUSTERS][BL_CPUS_PER_CLUSTER];
>>>
>>> @@ -28,3 +30,89 @@ void bL_set_entry_vector(unsigned cpu, unsigned cluster,
>>> void *ptr)
>>>    	outer_clean_range(__pa(&bL_entry_vectors[cluster][cpu]),
>>>    			  __pa(&bL_entry_vectors[cluster][cpu + 1]));
>>>    }
>>> +
>>> +static const struct bL_platform_power_ops *platform_ops;
>>> +
>>> +int __init bL_platform_power_register(const struct bL_platform_power_ops
>>> *ops)
>>> +{
>>> +	if (platform_ops)
>>> +		return -EBUSY;
>>> +	platform_ops = ops;
>>> +	return 0;
>>> +}
>>> +
>>> +int bL_cpu_power_up(unsigned int cpu, unsigned int cluster)
>>> +{
>>> +	if (!platform_ops)
>>> +		return -EUNATCH;
>>> +	might_sleep();
>>> +	return platform_ops->power_up(cpu, cluster);
>>> +}
>>> +
>>> +typedef void (*phys_reset_t)(unsigned long);
>>> +
>>> +void bL_cpu_power_down(void)
>>> +{
>>> +	phys_reset_t phys_reset;
>>> +
>>> +	BUG_ON(!platform_ops);
>>> +	BUG_ON(!irqs_disabled());
>>> +
>>> +	/*
>>> +	 * Do this before calling into the power_down method,
>>> +	 * as it might not always be safe to do afterwards.
>>> +	 */
>>> +	setup_mm_for_reboot();
>>> +
>>> +	platform_ops->power_down();
>>> +
>>> +	/*
>>> +	 * It is possible for a power_up request to happen concurrently
>>> +	 * with a power_down request for the same CPU. In this case the
>>> +	 * power_down method might not be able to actually enter a
>>> +	 * powered down state with the WFI instruction if the power_up
>>> +	 * method has removed the required reset condition.  The
>>> +	 * power_down method is then allowed to return. We must perform
>>> +	 * a re-entry in the kernel as if the power_up method just had
>>> +	 * deasserted reset on the CPU.
>>> +	 *
>>> +	 * To simplify race issues, the platform specific implementation
>>> +	 * must accommodate for the possibility of unordered calls to
>>> +	 * power_down and power_up with a usage count. Therefore, if a
>>> +	 * call to power_up is issued for a CPU that is not down, then
>>> +	 * the next call to power_down must not attempt a full shutdown
>>> +	 * but only do the minimum (normally disabling L1 cache and CPU
>>> +	 * coherency) and return just as if a concurrent power_up request
>>> +	 * had happened as described above.
>>> +	 */
>>> +
>>> +	phys_reset = (phys_reset_t)(unsigned long)virt_to_phys(cpu_reset);
>>> +	phys_reset(virt_to_phys(bL_entry_point));
>>> +
>>> +	/* should never get here */
>>> +	BUG();
>>> +}
>>> +
>>> +void bL_cpu_suspend(u64 expected_residency)
>>> +{
>>> +	phys_reset_t phys_reset;
>>> +
>>> +	BUG_ON(!platform_ops);
>>> +	BUG_ON(!irqs_disabled());
>>> +
>>> +	/* Very similar to bL_cpu_power_down() */
>>> +	setup_mm_for_reboot();
>>> +	platform_ops->suspend(expected_residency);
>>> +	phys_reset = (phys_reset_t)(unsigned long)virt_to_phys(cpu_reset);
>>> +	phys_reset(virt_to_phys(bL_entry_point));
>>> +	BUG();
>>>
>> I might be missing all the rationales behind not having a recovery for
>> CPUs entering suspend if they actualy come here because of some events.
>> This is pretty much possible in many scenario's and hence letting CPU
>> cpu come out of suspend should be possible. May be switcher code don't
>> have such requirement but it appeared bit off to me.
>
> There are two things to consider here:
>
> 1) The CPU is suspended.  CPU state is lost. Next interrupt to wake up
>     the CPU will make it restart from the reset vector and re-entry in
>     the kernel will happen via bL_entry_point to deal with the various
>     cluster issues, to eventually resume kernel code via cpu_resume.
>     Obviously, the machine specific backend code would have set the
>     bL_entry_point address in its machine specific reset vector in
>     advance.
This is the successful case and in that case you will anyway not hit the
BUG.
>
> 2) An interrupt comes along before the CPU is effectively suspended, say
>     right before the backend code executes a WFI to shut the CPU down.
>     The CPU and possibly cluster state was already set for being powered
>     off.  We cannot simply return at this point as caches are off, the
>     CPU is not coherent with the rest of the system anymore, etc.  So if
>     the platform specific backend ever returns, say because the final WFI
>     exited, then we have to go through the same arbitration process to
>     restore the CPU and cluster state as if that was a hard reset.  Hence
>     the cpu_reset call to loop back into bL_entry_point.
>
This is the one I was thinking. Enabling C bit and SMP bit should be
enough for CPU to get back to right state since the CPU has not lost
the context all the registers including SP is intact and CPU should
be able to resume.

> In either cases, we simply cannot ever return from bL_cpu_suspend()
> directly.  Of course, the caller is expected to have used
> bL_set_entry_vector() beforehand, most probably with cpu_resume as
> argument.
>
The above might get complicated if when above situation happens on
last CPU where even CCI gets disabled and then adding the rever code
for all of that may not be worth. You approach is much safer.
Thanks for explaining it further.

Regards,
Santosh

  reply	other threads:[~2013-01-11 18:41 UTC|newest]

Thread overview: 140+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-01-10  0:20 [PATCH 00/16] big.LITTLE low-level CPU and cluster power management Nicolas Pitre
2013-01-10  0:20 ` [PATCH 01/16] ARM: b.L: secondary kernel entry code Nicolas Pitre
2013-01-10  7:12   ` Stephen Boyd
2013-01-10 15:30     ` Nicolas Pitre
2013-01-10 15:34   ` Catalin Marinas
2013-01-10 16:47     ` Nicolas Pitre
2013-01-11 11:45       ` Catalin Marinas
2013-01-11 12:05         ` Lorenzo Pieralisi
2013-01-11 12:19         ` Dave Martin
2013-01-10 23:05   ` Will Deacon
2013-01-11  1:26     ` Nicolas Pitre
2013-01-11 10:55       ` Will Deacon
2013-01-11 11:35         ` Dave Martin
2013-01-11 17:16   ` Santosh Shilimkar
2013-01-11 18:10     ` Nicolas Pitre
2013-01-11 18:30       ` Santosh Shilimkar
2013-03-07  7:37   ` Pavel Machek
2013-03-07  8:57     ` Nicolas Pitre
2013-01-10  0:20 ` [PATCH 02/16] ARM: b.L: introduce the CPU/cluster power API Nicolas Pitre
2013-01-10 23:08   ` Will Deacon
2013-01-11  2:30     ` Nicolas Pitre
2013-01-11 10:58       ` Will Deacon
2013-01-11 11:29       ` Dave Martin
2013-01-11 17:26   ` Santosh Shilimkar
2013-01-11 18:33     ` Nicolas Pitre
2013-01-11 18:41       ` Santosh Shilimkar [this message]
2013-01-11 19:54         ` Nicolas Pitre
2013-01-10  0:20 ` [PATCH 03/16] ARM: b.L: introduce helpers for platform coherency exit/setup Nicolas Pitre
2013-01-10 12:01   ` Dave Martin
2013-01-10 19:04     ` Nicolas Pitre
2013-01-11 11:30       ` Dave Martin
2013-01-10 16:53   ` Catalin Marinas
2013-01-10 17:59     ` Nicolas Pitre
2013-01-10 21:50       ` Catalin Marinas
2013-01-10 22:31         ` Nicolas Pitre
2013-01-11 10:36           ` Dave Martin
2013-01-10 22:32     ` Nicolas Pitre
2013-01-10 23:13   ` Will Deacon
2013-01-11  1:50     ` Nicolas Pitre
2013-01-11 11:09       ` Dave Martin
2013-01-11 17:46   ` Santosh Shilimkar
2013-01-11 18:07     ` Dave Martin
2013-01-11 18:34       ` Santosh Shilimkar
2013-01-14 17:08   ` Dave Martin
2013-01-14 17:15     ` Catalin Marinas
2013-01-14 18:10       ` Dave Martin
2013-01-14 21:34         ` Catalin Marinas
2013-01-10  0:20 ` [PATCH 04/16] ARM: b.L: Add baremetal voting mutexes Nicolas Pitre
2013-01-10 23:18   ` Will Deacon
2013-01-11  3:15     ` Nicolas Pitre
2013-01-11 11:03       ` Will Deacon
2013-01-11 16:57       ` Dave Martin
2013-01-10  0:20 ` [PATCH 05/16] ARM: bL_head: vlock-based first man election Nicolas Pitre
2013-01-10  0:20 ` [PATCH 06/16] ARM: b.L: generic SMP secondary bringup and hotplug support Nicolas Pitre
2013-01-11 18:02   ` Santosh Shilimkar
2013-01-14 18:05     ` Achin Gupta
2013-01-15  6:32       ` Santosh Shilimkar
2013-01-15 11:18         ` Achin Gupta
2013-01-15 11:26           ` Santosh Shilimkar
2013-01-15 18:53           ` Dave Martin
2013-01-14 16:35   ` Will Deacon
2013-01-14 16:51     ` Nicolas Pitre
2013-01-15 19:09       ` Dave Martin
2013-01-10  0:20 ` [PATCH 07/16] ARM: bL_platsmp.c: close the kernel entry gate before hot-unplugging a CPU Nicolas Pitre
2013-01-14 16:37   ` Will Deacon
2013-01-14 16:53     ` Nicolas Pitre
2013-01-14 17:00       ` Will Deacon
2013-01-14 17:11         ` Catalin Marinas
2013-01-14 17:15         ` Nicolas Pitre
2013-01-14 17:23           ` Will Deacon
2013-01-14 18:26           ` Russell King - ARM Linux
2013-01-14 18:49             ` Nicolas Pitre
2013-01-15 18:40             ` Dave Martin
2013-01-16 16:06               ` Catalin Marinas
2013-01-10  0:20 ` [PATCH 08/16] ARM: bL_platsmp.c: make sure the GIC interface of a dying CPU is disabled Nicolas Pitre
2013-01-11 18:07   ` Santosh Shilimkar
2013-01-11 19:07     ` Nicolas Pitre
2013-01-12  6:50       ` Santosh Shilimkar
2013-01-12 16:47         ` Nicolas Pitre
2013-01-13  4:37           ` Santosh Shilimkar
2013-01-14 17:53           ` Lorenzo Pieralisi
2013-01-14 16:39   ` Will Deacon
2013-01-14 16:54     ` Nicolas Pitre
2013-01-14 17:02       ` Will Deacon
2013-01-14 17:18         ` Nicolas Pitre
2013-01-14 17:24           ` Will Deacon
2013-01-14 17:56             ` Lorenzo Pieralisi
2013-01-10  0:20 ` [PATCH 09/16] ARM: vexpress: Select the correct SMP operations at run-time Nicolas Pitre
2013-01-10  0:20 ` [PATCH 10/16] ARM: vexpress: introduce DCSCB support Nicolas Pitre
2013-01-11 18:12   ` Santosh Shilimkar
2013-01-11 19:13     ` Nicolas Pitre
2013-01-12  6:52       ` Santosh Shilimkar
2013-01-10  0:20 ` [PATCH 11/16] ARM: vexpress/dcscb: add CPU use counts to the power up/down API implementation Nicolas Pitre
2013-01-10  0:20 ` [PATCH 12/16] ARM: vexpress/dcscb: do not hardcode number of CPUs per cluster Nicolas Pitre
2013-01-10  0:20 ` [PATCH 13/16] drivers: misc: add ARM CCI support Nicolas Pitre
2013-01-11 18:20   ` Santosh Shilimkar
2013-01-11 19:22     ` Nicolas Pitre
2013-01-12  6:53       ` Santosh Shilimkar
2013-01-15 18:34       ` Dave Martin
2013-01-10  0:20 ` [PATCH 14/16] ARM: TC2: ensure powerdown-time data is flushed from cache Nicolas Pitre
2013-01-10 18:50   ` Dave Martin
2013-01-10 19:13     ` Nicolas Pitre
2013-01-11 11:38       ` Dave Martin
2013-01-10  0:20 ` [PATCH 15/16] ARM: vexpress/dcscb: handle platform coherency exit/setup and CCI Nicolas Pitre
2013-01-10 12:05   ` Dave Martin
2013-01-11 18:27   ` Santosh Shilimkar
2013-01-11 19:28     ` Nicolas Pitre
2013-01-12  7:21       ` Santosh Shilimkar
2013-01-14 12:25         ` Lorenzo Pieralisi
2013-01-15  6:23           ` Santosh Shilimkar
2013-01-15 18:20             ` Dave Martin
2013-01-16  6:33               ` Santosh Shilimkar
2013-01-16 10:03                 ` Lorenzo Pieralisi
2013-01-16 10:12                   ` Santosh Shilimkar
2013-01-10  0:20 ` [PATCH 16/16] ARM: vexpress/dcscb: probe via device tree Nicolas Pitre
2013-01-10  0:46 ` [PATCH 00/16] big.LITTLE low-level CPU and cluster power management Rob Herring
2013-01-10  5:04   ` Nicolas Pitre
2013-01-10 23:01 ` Will Deacon
     [not found] ` <1357777251-13541-1-git-send-email-nicolas.pitre-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2013-01-14  9:56   ` Joseph Lo
2013-01-14  9:56     ` Joseph Lo
     [not found]     ` <1358157392.19304.243.camel-yx3yKKdKkHfc7b1ADBJPm0n48jw8i0AO@public.gmane.org>
2013-01-14 14:05       ` Nicolas Pitre
2013-01-14 14:05         ` Nicolas Pitre
     [not found]         ` <alpine.LFD.2.02.1301140849020.6300-QuJgVwGFrdf/9pzu0YdTqQ@public.gmane.org>
2013-01-15  2:44           ` Joseph Lo
2013-01-15  2:44             ` Joseph Lo
     [not found]             ` <1358217848.8513.14.camel-yx3yKKdKkHfc7b1ADBJPm0n48jw8i0AO@public.gmane.org>
2013-01-15 16:44               ` Nicolas Pitre
2013-01-15 16:44                 ` Nicolas Pitre
2013-01-16 16:02                 ` Catalin Marinas
2013-01-16 16:02                   ` Catalin Marinas
     [not found]                   ` <20130116160242.GB31318-5wv7dgnIgG8@public.gmane.org>
2013-01-16 21:18                     ` Nicolas Pitre
2013-01-16 21:18                       ` Nicolas Pitre
     [not found]                       ` <alpine.LFD.2.02.1301161614390.6300-QuJgVwGFrdf/9pzu0YdTqQ@public.gmane.org>
2013-01-17 17:55                         ` Catalin Marinas
2013-01-17 17:55                           ` Catalin Marinas
2013-01-15 18:31           ` Dave Martin
2013-01-15 18:31             ` Dave Martin
2013-03-07  8:27 ` Pavel Machek
2013-03-07  9:12   ` Nicolas Pitre
2013-03-07  9:40     ` Pavel Machek
2013-03-07  9:56       ` Nicolas Pitre
2013-03-07 14:51         ` Pavel Machek
2013-03-07 15:42           ` Nicolas Pitre

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=50F05CD4.8050905@ti.com \
    --to=santosh.shilimkar@ti.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.