Messages in this thread |  | | Subject | Re: [PATCH 4/5] firmware: xilinx: Add sysfs to set shutdown scope | From | Michal Simek <> | Date | Wed, 18 Dec 2019 15:25:55 +0100 |
| |
On 05. 12. 19 0:29, Jolly Shah wrote: > From: Rajan Vaja <rajan.vaja@xilinx.com> > > The Linux shutdown functionality implemented via PSCI system_off does > not include an option to set a scope, i.e. which parts of the system to > shut down. > > This patch creates sysfs that allows to set the shutdown scope for the > next shutdown request. When the next shutdown is performed, the platform > specific portion of PSCI-system_off can use the chosen shutdown scope. > > Signed-off-by: Stefan Krsmanovic <stefan.krsmanovic@aggios.com> > Signed-off-by: Michal Simek <michal.simek@xilinx.com> > Signed-off-by: Rajan Vaja <rajan.vaja@xilinx.com> > Signed-off-by: Jolly Shah <jolly.shah@xilinx.com> > --- > Documentation/ABI/stable/sysfs-firmware-zynqmp | 32 ++++++ > drivers/firmware/xilinx/zynqmp.c | 141 +++++++++++++++++++++++++ > include/linux/firmware/xlnx-zynqmp.h | 12 +++ > 3 files changed, 185 insertions(+) > > diff --git a/Documentation/ABI/stable/sysfs-firmware-zynqmp b/Documentation/ABI/stable/sysfs-firmware-zynqmp > index 0a75812..13e4fd2 100644 > --- a/Documentation/ABI/stable/sysfs-firmware-zynqmp > +++ b/Documentation/ABI/stable/sysfs-firmware-zynqmp > @@ -48,3 +48,35 @@ Description: > # echo 0xFFFFFFFF 0x1234ABCD > /sys/firmware/zynqmp/pggs0 > > Users: Xilinx > + > +What: /sys/firmware/zynqmp/shutdown_scope > +Date: February 2018 > +KernelVersion: 4.15.6
ditto.
> +Contact: "Jolly Shah" <jollys@xilinx.com> > +Description: > + This sysfs interface allows to set the shutdown scope for the > + next shutdown request. When the next shutdown is performed, the > + platform specific portion of PSCI-system_off can use the chosen > + shutdown scope. > + > + Following are available shutdown scopes(subtypes): > + > + subsystem: Only the APU along with all of its peripherals > + not used by other processing units will be > + shut down. This may result in the FPD power > + domain being shut down provided that no other > + processing unit uses FPD peripherals or DRAM. > + ps_only: The complete PS will be shut down, including the > + RPU, PMU, etc. Only the PL domain (FPGA) > + remains untouched. > + system: The complete system/device is shut down. > + > + Usage: > + # cat /sys/firmware/zynqmp/shutdown_scope > + # echo <scope> > /sys/firmware/zynqmp/shutdown_scope > + > + Example: > + # cat /sys/firmware/zynqmp/shutdown_scope > + # echo "subsystem" > /sys/firmware/zynqmp/shutdown_scope > + > +Users: Xilinx > diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c > index 8dcf5a4..b23bda4 100644 > --- a/drivers/firmware/xilinx/zynqmp.c > +++ b/drivers/firmware/xilinx/zynqmp.c > @@ -746,6 +746,146 @@ const struct zynqmp_eemi_ops *zynqmp_pm_get_eemi_ops(void) > EXPORT_SYMBOL_GPL(zynqmp_pm_get_eemi_ops); > > /** > + * struct zynqmp_pm_shutdown_scope - Struct for shutdown scope > + * @subtype: Shutdown subtype > + * @name: Matching string for scope argument > + * > + * This struct encapsulates mapping between shutdown scope ID and string. > + */ > +struct zynqmp_pm_shutdown_scope { > + const enum zynqmp_pm_shutdown_subtype subtype; > + const char *name; > +}; > + > +static struct zynqmp_pm_shutdown_scope shutdown_scopes[] = { > + [ZYNQMP_PM_SHUTDOWN_SUBTYPE_SUBSYSTEM] = { > + .subtype = ZYNQMP_PM_SHUTDOWN_SUBTYPE_SUBSYSTEM, > + .name = "subsystem", > + }, > + [ZYNQMP_PM_SHUTDOWN_SUBTYPE_PS_ONLY] = { > + .subtype = ZYNQMP_PM_SHUTDOWN_SUBTYPE_PS_ONLY, > + .name = "ps_only", > + }, > + [ZYNQMP_PM_SHUTDOWN_SUBTYPE_SYSTEM] = { > + .subtype = ZYNQMP_PM_SHUTDOWN_SUBTYPE_SYSTEM, > + .name = "system", > + }, > +}; > + > +static struct zynqmp_pm_shutdown_scope *selected_scope = > + &shutdown_scopes[ZYNQMP_PM_SHUTDOWN_SUBTYPE_SYSTEM]; > + > +/** > + * zynqmp_pm_is_shutdown_scope_valid - Check if shutdown scope string is valid > + * @scope_string: Shutdown scope string > + * > + * Return: Return pointer to matching shutdown scope struct from > + * array of available options in system if string is valid, > + * otherwise returns NULL. > + */ > +static struct zynqmp_pm_shutdown_scope* > + zynqmp_pm_is_shutdown_scope_valid(const char *scope_string) > +{ > + int count; > + > + for (count = 0; count < ARRAY_SIZE(shutdown_scopes); count++) > + if (sysfs_streq(scope_string, shutdown_scopes[count].name)) > + return &shutdown_scopes[count]; > + > + return NULL; > +} > + > +/** > + * shutdown_scope_show - Show shutdown_scope sysfs attribute > + * @kobj: Kobject structure > + * @attr: Kobject attribute structure > + * @buf: Requested available shutdown_scope attributes string > + * > + * User-space interface for viewing the available scope options for system > + * shutdown. Scope option for next shutdown call is marked with []. > + * > + * Usage: cat /sys/firmware/zynqmp/shutdown_scope > + * > + * Return: Number of bytes printed into the buffer. > + */ > +static ssize_t shutdown_scope_show(struct kobject *kobj, > + struct kobj_attribute *attr, > + char *buf) > +{ > + int i; > + > + for (i = 0; i < ARRAY_SIZE(shutdown_scopes); i++) { > + if (&shutdown_scopes[i] == selected_scope) { > + strcat(buf, "["); > + strcat(buf, shutdown_scopes[i].name); > + strcat(buf, "]"); > + } else { > + strcat(buf, shutdown_scopes[i].name); > + } > + strcat(buf, " "); > + } > + strcat(buf, "\n"); > + > + return strlen(buf); > +} > + > +/** > + * shutdown_scope_store - Store shutdown_scope sysfs attribute > + * @kobj: Kobject structure > + * @attr: Kobject attribute structure > + * @buf: User entered shutdown_scope attribute string > + * @count: Buffer size > + * > + * User-space interface for setting the scope for the next system shutdown. > + * Usage: echo <scope> > /sys/firmware/zynqmp/shutdown_scope > + * > + * The Linux shutdown functionality implemented via PSCI system_off does not > + * include an option to set a scope, i.e. which parts of the system to shut > + * down. > + * > + * This API function allows to set the shutdown scope for the next shutdown > + * request by passing it to the ATF running in EL3. When the next shutdown > + * is performed, the platform specific portion of PSCI-system_off can use > + * the chosen shutdown scope. > + * > + * subsystem: Only the APU along with all of its peripherals not used by other > + * processing units will be shut down. This may result in the FPD > + * power domain being shut down provided that no other processing > + * unit uses FPD peripherals or DRAM. > + * ps_only: The complete PS will be shut down, including the RPU, PMU, etc. > + * Only the PL domain (FPGA) remains untouched. > + * system: The complete system/device is shut down. > + * > + * Return: count argument if request succeeds, the corresponding error > + * code otherwise > + */ > +static ssize_t shutdown_scope_store(struct kobject *kobj, > + struct kobj_attribute *attr, > + const char *buf, size_t count) > +{ > + int ret; > + struct zynqmp_pm_shutdown_scope *scope; > + > + scope = zynqmp_pm_is_shutdown_scope_valid(buf); > + if (!scope) > + return -EINVAL; > + > + ret = zynqmp_pm_system_shutdown(ZYNQMP_PM_SHUTDOWN_TYPE_SETSCOPE_ONLY, > + scope->subtype); > + if (ret) { > + pr_err("unable to set shutdown scope %s\n", buf); > + return ret; > + } > + > + selected_scope = scope; > + > + return count; > +} > + > +static struct kobj_attribute zynqmp_attr_shutdown_scope = > + __ATTR_RW(shutdown_scope);
the same as was in 1/5.
> + > +/** > * config_reg_store - Write config_reg sysfs attribute > * @kobj: Kobject structure > * @attr: Kobject attribute structure > @@ -870,6 +1010,7 @@ static struct kobj_attribute zynqmp_attr_config_reg = > __ATTR_RW(config_reg); > > static struct attribute *attrs[] = { > + &zynqmp_attr_shutdown_scope.attr, > &zynqmp_attr_config_reg.attr, > NULL, > }; > diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h > index b96ea5d..54061de 100644 > --- a/include/linux/firmware/xlnx-zynqmp.h > +++ b/include/linux/firmware/xlnx-zynqmp.h > @@ -277,6 +277,18 @@ enum pm_register_access_id { > CONFIG_REG_READ, > }; > > +enum zynqmp_pm_shutdown_type { > + ZYNQMP_PM_SHUTDOWN_TYPE_SHUTDOWN, > + ZYNQMP_PM_SHUTDOWN_TYPE_RESET, > + ZYNQMP_PM_SHUTDOWN_TYPE_SETSCOPE_ONLY, > +}; > + > +enum zynqmp_pm_shutdown_subtype { > + ZYNQMP_PM_SHUTDOWN_SUBTYPE_SUBSYSTEM, > + ZYNQMP_PM_SHUTDOWN_SUBTYPE_PS_ONLY, > + ZYNQMP_PM_SHUTDOWN_SUBTYPE_SYSTEM, > +}; > + > /** > * struct zynqmp_pm_query_data - PM query data > * @qid: query ID >
M
|  |