From: robherring2@gmail.com (Rob Herring)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v3] [RFC] arm: use PSCI if available
Date: Wed, 27 Mar 2013 09:55:12 -0500 [thread overview]
Message-ID: <51530850.6070405@gmail.com> (raw)
In-Reply-To: <1364388639-11210-1-git-send-email-stefano.stabellini@eu.citrix.com>
On 03/27/2013 07:50 AM, Stefano Stabellini wrote:
> Check for the presence of PSCI before setting smp_ops, use PSCI if it is
> available.
>
> This is useful because at least when running on Xen it's possible to have a
> PSCI node for example on a Versatile Express or an Exynos5 machine. In these
> cases the PSCI SMP calls should be the ones to be called.
I have a similar patch in my tree. I thought I had sent it out, but
looks like I didn't. I didn't make smp_ops default to this or change
mach-virt, so we should go with yours.
[...]
> @@ -36,7 +38,11 @@ enum psci_function {
> PSCI_FN_MAX,
> };
>
> -static u32 psci_function_id[PSCI_FN_MAX];
> +struct psci_function_desc {
> + enum psci_function func;
> + bool valid;
Why can't you use a NULL function ptr or a 0 psci_function_id to
indicate not valid?
> +};
> +static struct psci_function_desc psci_function_id[PSCI_FN_MAX];
>
> #define PSCI_RET_SUCCESS 0
> #define PSCI_RET_EOPNOTSUPP -1
> @@ -116,7 +122,10 @@ static int psci_cpu_suspend(struct psci_power_state state,
> int err;
> u32 fn, power_state;
>
> - fn = psci_function_id[PSCI_FN_CPU_SUSPEND];
> + if (!psci_function_id[PSCI_FN_CPU_SUSPEND].valid)
> + return -ENOSYS;
> +
> + fn = psci_function_id[PSCI_FN_CPU_SUSPEND].func;
> power_state = psci_power_state_pack(state);
> err = invoke_psci_fn(fn, power_state, entry_point, 0);
> return psci_to_linux_errno(err);
> @@ -127,7 +136,10 @@ static int psci_cpu_off(struct psci_power_state state)
> int err;
> u32 fn, power_state;
>
> - fn = psci_function_id[PSCI_FN_CPU_OFF];
> + if (!psci_function_id[PSCI_FN_CPU_OFF].valid)
> + return -ENOSYS;
> +
> + fn = psci_function_id[PSCI_FN_CPU_OFF].func;
> power_state = psci_power_state_pack(state);
> err = invoke_psci_fn(fn, power_state, 0, 0);
> return psci_to_linux_errno(err);
> @@ -138,7 +150,10 @@ static int psci_cpu_on(unsigned long cpuid, unsigned long entry_point)
> int err;
> u32 fn;
>
> - fn = psci_function_id[PSCI_FN_CPU_ON];
> + if (!psci_function_id[PSCI_FN_CPU_ON].valid)
> + return -ENOSYS;
> +
> + fn = psci_function_id[PSCI_FN_CPU_ON].func;
> err = invoke_psci_fn(fn, cpuid, entry_point, 0);
> return psci_to_linux_errno(err);
> }
> @@ -148,25 +163,64 @@ static int psci_migrate(unsigned long cpuid)
> int err;
> u32 fn;
>
> - fn = psci_function_id[PSCI_FN_MIGRATE];
> + if (!psci_function_id[PSCI_FN_MIGRATE].valid)
> + return -ENOSYS;
> +
> + fn = psci_function_id[PSCI_FN_MIGRATE].func;
> err = invoke_psci_fn(fn, cpuid, 0, 0);
> return psci_to_linux_errno(err);
> }
>
> +struct psci_operations psci_ops = {
> + .cpu_suspend = psci_cpu_suspend,
> + .cpu_off = psci_cpu_off,
> + .cpu_on = psci_cpu_on,
> + .migrate = psci_migrate,
> +};
> +
> +#ifdef CONFIG_SMP
> +static void __init psci_smp_init_cpus(void)
> +{
> +}
> +
> +static void __init psci_smp_prepare_cpus(unsigned int max_cpus)
> +{
> +}
You can leave these 2 functions as NULL.
> +
> +static int __cpuinit psci_boot_secondary(unsigned int cpu,
> + struct task_struct *idle)
> +{
> + return psci_cpu_on(cpu_logical_map(cpu), __pa(secondary_startup));
> +}
> +
> +static void __cpuinit psci_secondary_init(unsigned int cpu)
> +{
> + gic_secondary_init(0);
> +}
> +
> +struct smp_operations __initdata psci_smp_ops = {
> + .smp_init_cpus = psci_smp_init_cpus,
> + .smp_prepare_cpus = psci_smp_prepare_cpus,
> + .smp_secondary_init = psci_secondary_init,
> + .smp_boot_secondary = psci_boot_secondary,
You should also include hotplug. Here's what I had:
#ifdef CONFIG_HOTPLUG_CPU
void __ref psci_cpu_die(unsigned int cpu)
{
const struct psci_power_state ps = {
.type = PSCI_POWER_STATE_TYPE_POWER_DOWN,
};
if (psci_ops.cpu_off)
psci_ops.cpu_off(ps);
/* We should never return */
panic("psci: cpu %d failed to shutdown\n", cpu);
}
#else
#define psci_cpu_die NULL
#endif
WARNING: multiple messages have this Message-ID (diff)
From: Rob Herring <robherring2@gmail.com>
To: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: xen-devel@lists.xensource.com, linux@arm.linux.org.uk,
arnd@arndb.de, marc.zyngier@arm.com, nico@linaro.org,
will.deacon@arm.com, linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH v3] [RFC] arm: use PSCI if available
Date: Wed, 27 Mar 2013 09:55:12 -0500 [thread overview]
Message-ID: <51530850.6070405@gmail.com> (raw)
In-Reply-To: <1364388639-11210-1-git-send-email-stefano.stabellini@eu.citrix.com>
On 03/27/2013 07:50 AM, Stefano Stabellini wrote:
> Check for the presence of PSCI before setting smp_ops, use PSCI if it is
> available.
>
> This is useful because at least when running on Xen it's possible to have a
> PSCI node for example on a Versatile Express or an Exynos5 machine. In these
> cases the PSCI SMP calls should be the ones to be called.
I have a similar patch in my tree. I thought I had sent it out, but
looks like I didn't. I didn't make smp_ops default to this or change
mach-virt, so we should go with yours.
[...]
> @@ -36,7 +38,11 @@ enum psci_function {
> PSCI_FN_MAX,
> };
>
> -static u32 psci_function_id[PSCI_FN_MAX];
> +struct psci_function_desc {
> + enum psci_function func;
> + bool valid;
Why can't you use a NULL function ptr or a 0 psci_function_id to
indicate not valid?
> +};
> +static struct psci_function_desc psci_function_id[PSCI_FN_MAX];
>
> #define PSCI_RET_SUCCESS 0
> #define PSCI_RET_EOPNOTSUPP -1
> @@ -116,7 +122,10 @@ static int psci_cpu_suspend(struct psci_power_state state,
> int err;
> u32 fn, power_state;
>
> - fn = psci_function_id[PSCI_FN_CPU_SUSPEND];
> + if (!psci_function_id[PSCI_FN_CPU_SUSPEND].valid)
> + return -ENOSYS;
> +
> + fn = psci_function_id[PSCI_FN_CPU_SUSPEND].func;
> power_state = psci_power_state_pack(state);
> err = invoke_psci_fn(fn, power_state, entry_point, 0);
> return psci_to_linux_errno(err);
> @@ -127,7 +136,10 @@ static int psci_cpu_off(struct psci_power_state state)
> int err;
> u32 fn, power_state;
>
> - fn = psci_function_id[PSCI_FN_CPU_OFF];
> + if (!psci_function_id[PSCI_FN_CPU_OFF].valid)
> + return -ENOSYS;
> +
> + fn = psci_function_id[PSCI_FN_CPU_OFF].func;
> power_state = psci_power_state_pack(state);
> err = invoke_psci_fn(fn, power_state, 0, 0);
> return psci_to_linux_errno(err);
> @@ -138,7 +150,10 @@ static int psci_cpu_on(unsigned long cpuid, unsigned long entry_point)
> int err;
> u32 fn;
>
> - fn = psci_function_id[PSCI_FN_CPU_ON];
> + if (!psci_function_id[PSCI_FN_CPU_ON].valid)
> + return -ENOSYS;
> +
> + fn = psci_function_id[PSCI_FN_CPU_ON].func;
> err = invoke_psci_fn(fn, cpuid, entry_point, 0);
> return psci_to_linux_errno(err);
> }
> @@ -148,25 +163,64 @@ static int psci_migrate(unsigned long cpuid)
> int err;
> u32 fn;
>
> - fn = psci_function_id[PSCI_FN_MIGRATE];
> + if (!psci_function_id[PSCI_FN_MIGRATE].valid)
> + return -ENOSYS;
> +
> + fn = psci_function_id[PSCI_FN_MIGRATE].func;
> err = invoke_psci_fn(fn, cpuid, 0, 0);
> return psci_to_linux_errno(err);
> }
>
> +struct psci_operations psci_ops = {
> + .cpu_suspend = psci_cpu_suspend,
> + .cpu_off = psci_cpu_off,
> + .cpu_on = psci_cpu_on,
> + .migrate = psci_migrate,
> +};
> +
> +#ifdef CONFIG_SMP
> +static void __init psci_smp_init_cpus(void)
> +{
> +}
> +
> +static void __init psci_smp_prepare_cpus(unsigned int max_cpus)
> +{
> +}
You can leave these 2 functions as NULL.
> +
> +static int __cpuinit psci_boot_secondary(unsigned int cpu,
> + struct task_struct *idle)
> +{
> + return psci_cpu_on(cpu_logical_map(cpu), __pa(secondary_startup));
> +}
> +
> +static void __cpuinit psci_secondary_init(unsigned int cpu)
> +{
> + gic_secondary_init(0);
> +}
> +
> +struct smp_operations __initdata psci_smp_ops = {
> + .smp_init_cpus = psci_smp_init_cpus,
> + .smp_prepare_cpus = psci_smp_prepare_cpus,
> + .smp_secondary_init = psci_secondary_init,
> + .smp_boot_secondary = psci_boot_secondary,
You should also include hotplug. Here's what I had:
#ifdef CONFIG_HOTPLUG_CPU
void __ref psci_cpu_die(unsigned int cpu)
{
const struct psci_power_state ps = {
.type = PSCI_POWER_STATE_TYPE_POWER_DOWN,
};
if (psci_ops.cpu_off)
psci_ops.cpu_off(ps);
/* We should never return */
panic("psci: cpu %d failed to shutdown\n", cpu);
}
#else
#define psci_cpu_die NULL
#endif
next prev parent reply other threads:[~2013-03-27 14:55 UTC|newest]
Thread overview: 65+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-03-27 12:50 [PATCH v3] [RFC] arm: use PSCI if available Stefano Stabellini
2013-03-27 12:50 ` Stefano Stabellini
2013-03-27 12:50 ` Stefano Stabellini
2013-03-27 13:35 ` Marc Zyngier
2013-03-27 13:35 ` Marc Zyngier
2013-03-27 16:20 ` Rob Herring
2013-03-27 16:20 ` Rob Herring
2013-03-27 13:38 ` Will Deacon
2013-03-27 13:38 ` Will Deacon
2013-03-27 16:23 ` Stefano Stabellini
2013-03-27 16:23 ` Stefano Stabellini
2013-03-27 16:35 ` Rob Herring
2013-03-27 16:35 ` Rob Herring
2013-03-27 17:10 ` Stefano Stabellini
2013-03-27 17:10 ` Stefano Stabellini
2013-03-27 17:24 ` Nicolas Pitre
2013-03-27 17:24 ` Nicolas Pitre
2013-03-27 18:22 ` Stefano Stabellini
2013-03-27 18:22 ` Stefano Stabellini
2013-03-27 17:45 ` Rob Herring
2013-03-27 17:45 ` Rob Herring
2013-03-27 18:03 ` Arnd Bergmann
2013-03-27 18:03 ` Arnd Bergmann
2013-03-27 18:14 ` Stefano Stabellini
2013-03-27 18:14 ` Stefano Stabellini
2013-03-27 17:23 ` Will Deacon
2013-03-27 17:23 ` Will Deacon
2013-03-28 12:48 ` Stefano Stabellini
2013-03-28 12:48 ` Stefano Stabellini
2013-03-28 14:51 ` Nicolas Pitre
2013-03-28 14:51 ` Nicolas Pitre
2013-03-28 15:04 ` Rob Herring
2013-03-28 15:04 ` Rob Herring
2013-03-28 15:36 ` Stefano Stabellini
2013-03-28 15:36 ` Stefano Stabellini
2013-03-28 15:39 ` Nicolas Pitre
2013-03-28 15:39 ` Nicolas Pitre
2013-03-28 16:00 ` Will Deacon
2013-03-28 16:00 ` Will Deacon
2013-03-28 16:06 ` Nicolas Pitre
2013-03-28 16:06 ` Nicolas Pitre
2013-03-28 16:20 ` Stefano Stabellini
2013-03-28 16:20 ` Stefano Stabellini
2013-03-28 18:38 ` Rob Herring
2013-03-28 18:38 ` Rob Herring
2013-03-29 13:22 ` Stefano Stabellini
2013-03-29 13:22 ` Stefano Stabellini
2013-03-29 13:54 ` Rob Herring
2013-03-29 13:54 ` Rob Herring
2013-03-29 14:47 ` Stefano Stabellini
2013-03-29 14:47 ` Stefano Stabellini
2013-03-27 16:33 ` Rob Herring
2013-03-27 16:33 ` Rob Herring
2013-03-27 17:05 ` Will Deacon
2013-03-27 17:05 ` Will Deacon
2013-03-27 17:50 ` Arnd Bergmann
2013-03-27 17:50 ` Arnd Bergmann
2013-03-27 18:12 ` Will Deacon
2013-03-27 18:12 ` Will Deacon
2013-03-27 19:10 ` Rob Herring
2013-03-27 19:10 ` Rob Herring
2013-03-27 19:14 ` Arnd Bergmann
2013-03-27 19:14 ` Arnd Bergmann
2013-03-27 14:55 ` Rob Herring [this message]
2013-03-27 14:55 ` Rob Herring
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=51530850.6070405@gmail.com \
--to=robherring2@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.