linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: sudeep.holla@arm.com (Sudeep Holla)
To: linux-arm-kernel@lists.infradead.org
Subject: [Linaro-acpi] [PATCH v4 1/3] PSCI: Add initial support for PSCIv0.2 functions
Date: Mon, 31 Mar 2014 17:52:50 +0100	[thread overview]
Message-ID: <53399D62.5060704@arm.com> (raw)
In-Reply-To: <1396278179-28181-2-git-send-email-ashwin.chaugule@linaro.org>

Hi Ashwin,

On 31/03/14 16:02, Ashwin Chaugule wrote:
> The PSCIv0.2 spec defines standard values of function IDs
> and introduces a few new functions. Detect version of PSCI
> and appropriately select the right PSCI functions.
> 
> Signed-off-by: Ashwin Chaugule <ashwin.chaugule@linaro.org>
> ---
>  arch/arm/include/asm/psci.h |   7 +-
>  arch/arm/kernel/psci.c      | 155 ++++++++++++++++++++++++++++++++++--------
>  arch/arm64/kernel/psci.c    | 160 +++++++++++++++++++++++++++++++++++---------
>  include/uapi/linux/psci.h   |  61 +++++++++++++++++
>  4 files changed, 323 insertions(+), 60 deletions(-)
>  create mode 100644 include/uapi/linux/psci.h
> 
> diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h
> index c4ae171..b93e34a 100644
> --- a/arch/arm/include/asm/psci.h
> +++ b/arch/arm/include/asm/psci.h
> @@ -29,16 +29,19 @@ struct psci_operations {
>         int (*cpu_off)(struct psci_power_state state);
>         int (*cpu_on)(unsigned long cpuid, unsigned long entry_point);
>         int (*migrate)(unsigned long cpuid);
> +       int (*affinity_info)(unsigned long target_affinity,
> +                       unsigned long lowest_affinity_level);
> +       int (*migrate_info_type)(void);
>  };
> 
>  extern struct psci_operations psci_ops;
>  extern struct smp_operations psci_smp_ops;
> 
>  #ifdef CONFIG_ARM_PSCI
> -void psci_init(void);
> +int psci_init(void);
>  bool psci_smp_available(void);
>  #else
> -static inline void psci_init(void) { }
> +static inline int psci_init(void) { }
>  static inline bool psci_smp_available(void) { return false; }
>  #endif
> 
> diff --git a/arch/arm/kernel/psci.c b/arch/arm/kernel/psci.c
> index 4693188..46b23b6 100644
> --- a/arch/arm/kernel/psci.c
> +++ b/arch/arm/kernel/psci.c
> @@ -17,6 +17,7 @@
> 
>  #include <linux/init.h>
>  #include <linux/of.h>
> +#include <uapi/linux/psci.h>
> 
>  #include <asm/compiler.h>
>  #include <asm/errno.h>
> @@ -27,22 +28,20 @@
>  struct psci_operations psci_ops;
> 
>  static int (*invoke_psci_fn)(u32, u32, u32, u32);
> +typedef int (*psci_initcall_t)(const struct device_node *);
> 
>  enum psci_function {
>         PSCI_FN_CPU_SUSPEND,
>         PSCI_FN_CPU_ON,
>         PSCI_FN_CPU_OFF,
>         PSCI_FN_MIGRATE,
> +       PSCI_FN_AFFINITY_INFO,
> +       PSCI_FN_MIGRATE_INFO_TYPE,
>         PSCI_FN_MAX,
>  };
> 
>  static u32 psci_function_id[PSCI_FN_MAX];
> 
> -#define PSCI_RET_SUCCESS               0
> -#define PSCI_RET_EOPNOTSUPP            -1
> -#define PSCI_RET_EINVAL                        -2
> -#define PSCI_RET_EPERM                 -3
> -
>  static int psci_to_linux_errno(int errno)
>  {
>         switch (errno) {
> @@ -59,13 +58,6 @@ static int psci_to_linux_errno(int errno)
>         return -EINVAL;
>  }
> 
> -#define PSCI_POWER_STATE_ID_MASK       0xffff
> -#define PSCI_POWER_STATE_ID_SHIFT      0
> -#define PSCI_POWER_STATE_TYPE_MASK     0x1
> -#define PSCI_POWER_STATE_TYPE_SHIFT    16
> -#define PSCI_POWER_STATE_AFFL_MASK     0x3
> -#define PSCI_POWER_STATE_AFFL_SHIFT    24
> -
>  static u32 psci_power_state_pack(struct psci_power_state state)
>  {
>         return  ((state.id & PSCI_POWER_STATE_ID_MASK)
> @@ -110,6 +102,14 @@ static noinline int __invoke_psci_fn_smc(u32 function_id, u32 arg0, u32 arg1,
>         return function_id;
>  }
> 
> +static int psci_get_version(void)
> +{
> +       int err;
> +
> +       err = invoke_psci_fn(PSCI_ID_VERSION, 0, 0, 0);
> +       return err;
> +}
> +
>  static int psci_cpu_suspend(struct psci_power_state state,
>                             unsigned long entry_point)
>  {
> @@ -153,26 +153,36 @@ static int psci_migrate(unsigned long cpuid)
>         return psci_to_linux_errno(err);
>  }
> 
> -static const struct of_device_id psci_of_match[] __initconst = {
> -       { .compatible = "arm,psci",     },
> -       {},
> -};
> +static int psci_affinity_info(unsigned long target_affinity,
> +               unsigned long lowest_affinity_level)
> +{
> +       int err;
> +       u32 fn;
> 
> -void __init psci_init(void)
> +       fn = psci_function_id[PSCI_FN_AFFINITY_INFO];
> +       err = invoke_psci_fn(fn, target_affinity, lowest_affinity_level, 0);
> +       return err;
> +}
> +
> +static int psci_migrate_info_type(void)
>  {
> -       struct device_node *np;
> -       const char *method;
> -       u32 id;
> +       int err;
> +       u32 fn;
> 
> -       np = of_find_matching_node(NULL, psci_of_match);
> -       if (!np)
> -               return;
> +       fn = psci_function_id[PSCI_FN_MIGRATE_INFO_TYPE];
> +       err = invoke_psci_fn(fn, 0, 0, 0);
> +       return err;
> +}
> 
> -       pr_info("probing function IDs from device-tree\n");
> +static int get_set_conduit_method(struct device_node *np)
> +{
> +       const char *method;
> +
> +       pr_info("probing for conduit method from DT.\n");
> 
>         if (of_property_read_string(np, "method", &method)) {
> -               pr_warning("missing \"method\" property\n");
> -               goto out_put_node;
> +               pr_warn("missing \"method\" property\n");
> +               return -ENXIO;
>         }
> 
>         if (!strcmp("hvc", method)) {
> @@ -180,10 +190,79 @@ void __init psci_init(void)
>         } else if (!strcmp("smc", method)) {
>                 invoke_psci_fn = __invoke_psci_fn_smc;
>         } else {
> -               pr_warning("invalid \"method\" property: %s\n", method);
> +               pr_warn("invalid \"method\" property: %s\n", method);
> +               return -EINVAL;
> +       }
> +       return 0;
> +}
> +
> +/*
> + * PSCI Function IDs for v0.2+ are well defined so use
> + * standard values.
> + */
> +static int psci_0_2_init(struct device_node *np)
> +{
> +       int err, ver;
> +
> +       err = get_set_conduit_method(np);
> +
> +       if (err)
>                 goto out_put_node;
> +
> +       ver = psci_get_version();
> +
> +       if (ver == PSCI_RET_EOPNOTSUPP) {
> +               pr_info("PSCI_ID_VERSION Function not supported in firmware.\n");

IMO you should stop here as the implementation conforming to the specification
must return a minor version number of 2 and major version number of 0. You
can't proceed, assume ids and use them.

Regards,
Sudeep

  reply	other threads:[~2014-03-31 16:52 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-03-31 15:02 [PATCH v4 0/3] PSCI v0.2 support and DT bindings Ashwin Chaugule
2014-03-31 15:02 ` [PATCH v4 1/3] PSCI: Add initial support for PSCIv0.2 functions Ashwin Chaugule
2014-03-31 16:52   ` Sudeep Holla [this message]
2014-03-31 17:09     ` [Linaro-acpi] " Ashwin Chaugule
2014-03-31 17:25       ` Ashwin Chaugule
2014-03-31 18:25         ` Sudeep Holla
2014-03-31 15:02 ` [PATCH v4 2/3] Documentation: devicetree: Add new binding for PSCIv0.2 Ashwin Chaugule
2014-03-31 15:02 ` [PATCH v4 3/3] ARM: Check if a CPU has gone offline Ashwin Chaugule

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=53399D62.5060704@arm.com \
    --to=sudeep.holla@arm.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 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).