From a2cc220a9a9227b2c5c9b39f57340bce64f040fd Mon Sep 17 00:00:00 2001 From: Rajan Vaja Date: Fri, 24 Apr 2020 13:58:07 -0700 Subject: firmware: xilinx: Add sysfs and API to set boot health status Add sysfs interface to set boot health status from user space. Add API used by this interface to communicate with firmware. If PMUFW is compiled with CHECK_HEALTHY_BOOT, it will check the healthy bit on FPD WDT expiration. If healthy bit is set by a user application running in Linux, PMUFW will do APU only restart. If healthy bit is not set during FPD WDT expiration, PMUFW will do system restart. Signed-off-by: Rajan Vaja Signed-off-by: Michal Simek Signed-off-by: Tejas Patel Signed-off-by: Jolly Shah Link: https://lore.kernel.org/r/1587761887-4279-26-git-send-email-jolly.shah@xilinx.com Signed-off-by: Greg Kroah-Hartman --- drivers/firmware/xilinx/zynqmp.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'drivers/firmware/xilinx') diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c index 8d3661877670..bfaf29a58eac 100644 --- a/drivers/firmware/xilinx/zynqmp.c +++ b/drivers/firmware/xilinx/zynqmp.c @@ -683,6 +683,21 @@ int zynqmp_pm_read_pggs(u32 index, u32 *value) } EXPORT_SYMBOL_GPL(zynqmp_pm_read_pggs); +/** + * zynqmp_pm_set_boot_health_status() - PM API for setting healthy boot status + * @value Status value to be written + * + * This function sets healthy bit value to indicate boot health status + * to firmware. + * + * @return Returns status, either success or error+reason + */ +int zynqmp_pm_set_boot_health_status(u32 value) +{ + return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_SET_BOOT_HEALTH_STATUS, + value, 0, NULL); +} + /** * zynqmp_pm_reset_assert - Request setting of reset (1 - assert, 0 - release) * @reset: Reset to be configured @@ -984,6 +999,29 @@ static ssize_t shutdown_scope_store(struct device *device, static DEVICE_ATTR_RW(shutdown_scope); +static ssize_t health_status_store(struct device *device, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + unsigned int value; + + ret = kstrtouint(buf, 10, &value); + if (ret) + return ret; + + ret = zynqmp_pm_set_boot_health_status(value); + if (ret) { + dev_err(device, "unable to set healthy bit value to %u\n", + value); + return ret; + } + + return count; +} + +static DEVICE_ATTR_WO(health_status); + static ssize_t ggs_show(struct device *device, struct device_attribute *attr, char *buf, @@ -1143,6 +1181,7 @@ static struct attribute *zynqmp_firmware_attrs[] = { &dev_attr_pggs2.attr, &dev_attr_pggs3.attr, &dev_attr_shutdown_scope.attr, + &dev_attr_health_status.attr, NULL, }; -- cgit 1.4.1