[PATCH linux dev-4.10] drivers/hwmon/occ: Switch to non-blocking for occ reads
Eddie James
eajames at linux.vnet.ibm.com
Tue Sep 19 07:12:21 AEST 2017
From: Eddie James <eajames at us.ibm.com>
It's possible for the sbefifo ops to hang entirely if the system goes
down (checkstop, etc), meaning that the occ and occ-hwmon drivers may
hang during remove().
Signed-off-by: Eddie James <eajames at us.ibm.com>
---
drivers/hwmon/occ/p9_sbe.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/occ/p9_sbe.c b/drivers/hwmon/occ/p9_sbe.c
index 2d50a94..a6aa4d2 100644
--- a/drivers/hwmon/occ/p9_sbe.c
+++ b/drivers/hwmon/occ/p9_sbe.c
@@ -16,7 +16,10 @@
#include <linux/sched.h>
#include <linux/workqueue.h>
+#define OCC_CMD_INCOMPLETE_MS 10
+
struct p9_sbe_occ {
+ bool cancel;
struct occ occ;
struct device *sbe;
};
@@ -34,7 +37,7 @@ static int p9_sbe_occ_send_cmd(struct occ *occ, u8 *cmd)
start = jiffies;
retry:
- client = occ_drv_open(p9_sbe_occ->sbe, 0);
+ client = occ_drv_open(p9_sbe_occ->sbe, O_NONBLOCK);
if (!client) {
rc = -ENODEV;
goto assign;
@@ -44,9 +47,14 @@ static int p9_sbe_occ_send_cmd(struct occ *occ, u8 *cmd)
if (rc < 0)
goto err;
- rc = occ_drv_read(client, (char *)resp, sizeof(*resp));
- if (rc < 0)
- goto err;
+ do {
+ rc = occ_drv_read(client, (char *)resp, sizeof(*resp));
+ if (rc != -EAGAIN)
+ break;
+
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(msecs_to_jiffies(OCC_CMD_INCOMPLETE_MS));
+ } while (!p9_sbe_occ->cancel);
occ_drv_release(client);
@@ -164,6 +172,9 @@ static int p9_sbe_occ_probe(struct platform_device *pdev)
static int p9_sbe_occ_remove(struct platform_device *pdev)
{
struct occ *occ = platform_get_drvdata(pdev);
+ struct p9_sbe_occ *p9_sbe_occ = to_p9_sbe_occ(occ);
+
+ p9_sbe_occ->cancel = true;
occ_remove_status_attrs(occ);
--
1.8.3.1
More information about the openbmc
mailing list