In case some transactions to the Serial Power Controller (SPC) are lost owing to multiple operations handled at once by the M3 controller the OS needs to rely on a configuration API that can time out so that failures do not result in an unusable system.
This patch adds a timeout API to the vexpress config programming interface, and refactors the existing read/write functions so that they can be reused seamlessly on top of the newly defined API. Cc: Samuel Ortiz <sa...@linux.intel.com> Cc: Achin Gupta <achin.gu...@arm.com> Cc: Sudeep KarkadaNagesha <sudeep.karkadanage...@arm.com> Cc: Pawel Moll <pawel.m...@arm.com> Cc: Nicolas Pitre <nicolas.pi...@linaro.org> Cc: Amit Kucheria <amit.kuche...@linaro.org> Cc: Jon Medhurst <t...@linaro.org> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com> --- drivers/mfd/vexpress-config.c | 26 +++++++--- include/linux/vexpress.h | 23 ++++++-- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/drivers/mfd/vexpress-config.c b/drivers/mfd/vexpress-config.c index 1af2b0e..6f4aa5a 100644 --- a/drivers/mfd/vexpress-config.c +++ b/drivers/mfd/vexpress-config.c @@ -266,8 +266,18 @@ int vexpress_config_wait(struct vexpress_config_trans *trans) } EXPORT_SYMBOL(vexpress_config_wait); -int vexpress_config_read(struct vexpress_config_func *func, int offset, - u32 *data) +int vexpress_config_wait_timeout(struct vexpress_config_trans *trans, + long jiffies) +{ + int ret; + ret = wait_for_completion_timeout(&trans->completion, jiffies); + + return ret ? trans->status : -ETIMEDOUT; +} +EXPORT_SYMBOL(vexpress_config_wait_timeout); + +int vexpress_config_read_timeout(struct vexpress_config_func *func, int offset, + u32 *data, long jiffies) { struct vexpress_config_trans trans = { .func = func, @@ -279,14 +289,14 @@ int vexpress_config_read(struct vexpress_config_func *func, int offset, int status = vexpress_config_schedule(&trans); if (status == VEXPRESS_CONFIG_STATUS_WAIT) - status = vexpress_config_wait(&trans); + status = vexpress_config_wait_timeout(&trans, jiffies); return status; } -EXPORT_SYMBOL(vexpress_config_read); +EXPORT_SYMBOL(vexpress_config_read_timeout); -int vexpress_config_write(struct vexpress_config_func *func, int offset, - u32 data) +int vexpress_config_write_timeout(struct vexpress_config_func *func, + int offset, u32 data, long jiffies) { struct vexpress_config_trans trans = { .func = func, @@ -298,8 +308,8 @@ int vexpress_config_write(struct vexpress_config_func *func, int offset, int status = vexpress_config_schedule(&trans); if (status == VEXPRESS_CONFIG_STATUS_WAIT) - status = vexpress_config_wait(&trans); + status = vexpress_config_wait_timeout(&trans, jiffies); return status; } -EXPORT_SYMBOL(vexpress_config_write); +EXPORT_SYMBOL(vexpress_config_write_timeout); diff --git a/include/linux/vexpress.h b/include/linux/vexpress.h index 50368e0..e5015d8 100644 --- a/include/linux/vexpress.h +++ b/include/linux/vexpress.h @@ -15,6 +15,7 @@ #define _LINUX_VEXPRESS_H #include <linux/device.h> +#include <linux/sched.h> #define VEXPRESS_SITE_MB 0 #define VEXPRESS_SITE_DB1 1 @@ -102,10 +103,24 @@ struct vexpress_config_func *__vexpress_config_func_get( void vexpress_config_func_put(struct vexpress_config_func *func); /* Both may sleep! */ -int vexpress_config_read(struct vexpress_config_func *func, int offset, - u32 *data); -int vexpress_config_write(struct vexpress_config_func *func, int offset, - u32 data); +int vexpress_config_read_timeout(struct vexpress_config_func *func, int offset, + u32 *data, long jiffies); +int vexpress_config_write_timeout(struct vexpress_config_func *func, + int offset, u32 data, long jiffies); + +static inline int vexpress_config_read(struct vexpress_config_func *func, + int offset, u32 *data) +{ + return vexpress_config_read_timeout(func, offset, data, + MAX_SCHEDULE_TIMEOUT); +} + +static inline int vexpress_config_write(struct vexpress_config_func *func, + int offset, u32 data) +{ + return vexpress_config_write_timeout(func, offset, data, + MAX_SCHEDULE_TIMEOUT); +} /* Platform control */ -- 1.8.2.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/