Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1293956

[char-misc-next v2 7/7] watchdog: mei_wdt: re-register device on event

From Tomas Winkler <tomas.winkler@intel.com>
Newsgroups linux.kernel
Subject [char-misc-next v2 7/7] watchdog: mei_wdt: re-register device on event
Date 2015-12-17 16:00 +0100
Message-ID <qGIca-Ma-25@gated-at.bofh.it> (permalink)
References <qGIca-Ma-7@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


From: Alexander Usyskin <alexander.usyskin@intel.com>

For Intel SKL platform the ME device can inform the host via
asynchronous notification that the watchdog feature was activated
on the device. The activation doesn't require reboot.
In that case the driver registers the watchdog device with the kernel.
In the same manner the feature can be deactivated without reboot
in that case the watchdog device should be unregistered.

Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
V2: rework un/registration in runtime

 drivers/watchdog/mei_wdt.c | 45 ++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 42 insertions(+), 3 deletions(-)

diff --git a/drivers/watchdog/mei_wdt.c b/drivers/watchdog/mei_wdt.c
index 00d1b8e630b7..cd79920c473b 100644
--- a/drivers/watchdog/mei_wdt.c
+++ b/drivers/watchdog/mei_wdt.c
@@ -87,6 +87,7 @@ static const char *mei_wdt_state_str(enum mei_wdt_state state)
  * @state: watchdog internal state
  * @resp_required: ping required response
  * @response: ping response
+ * @unregister: unregister worker
  * @timeout: watchdog current timeout
  *
  * @dbgfs_dir: debugfs dir entry
@@ -101,6 +102,7 @@ struct mei_wdt {
 	enum mei_wdt_state state;
 	bool resp_required;
 	struct completion response;
+	struct work_struct unregister;
 	u16 timeout;
 
 #if IS_ENABLED(CONFIG_DEBUG_FS)
@@ -237,6 +239,13 @@ static void mei_wdt_unregister(struct mei_wdt *wdt)
 	mutex_unlock(&wdt->reg_lock);
 }
 
+static void mei_wdt_unregister_work(struct work_struct *work)
+{
+	struct mei_wdt *wdt = container_of(work, struct mei_wdt, unregister);
+
+	mei_wdt_unregister(wdt);
+}
+
 /**
  * mei_wdt_register - register with the watchdog subsystem
  *
@@ -350,8 +359,13 @@ static void mei_wdt_event_rx(struct mei_cl_device *cldev)
 		return;
 	}
 
-	if (wdt->state == MEI_WDT_RUNNING)
+	if (wdt->state == MEI_WDT_RUNNING) {
+		if (res.wdstate & MEI_WDT_WDSTATE_NOT_REQUIRED) {
+			wdt->state = MEI_WDT_NOT_REQUIRED;
+			schedule_work(&wdt->unregister);
+		}
 		goto out;
+	}
 
 	if (wdt->state == MEI_WDT_PROBE) {
 		if (res.wdstate & MEI_WDT_WDSTATE_NOT_REQUIRED) {
@@ -372,6 +386,21 @@ out:
 		complete(&wdt->response);
 }
 
+/*
+ * mei_wdt_notify_event - callback for event notification
+ *
+ * @cldev: bus device
+ */
+static void mei_wdt_notify_event(struct mei_cl_device *cldev)
+{
+	struct mei_wdt *wdt = mei_cldev_get_drvdata(cldev);
+
+	if (wdt->state != MEI_WDT_NOT_REQUIRED)
+		return;
+	wdt->state = MEI_WDT_IDLE;
+	mei_wdt_register(wdt);
+}
+
 /**
  * mei_wdt_event - callback for event receive
  *
@@ -384,6 +413,9 @@ static void mei_wdt_event(struct mei_cl_device *cldev,
 {
 	if (events & BIT(MEI_CL_EVENT_RX))
 		mei_wdt_event_rx(cldev);
+
+	if (events & BIT(MEI_CL_EVENT_NOTIF))
+		mei_wdt_notify_event(cldev);
 }
 
 /**
@@ -543,6 +575,7 @@ static int mei_wdt_probe(struct mei_cl_device *cldev,
 	wdt->resp_required = mei_cldev_ver(cldev) > 0x1;
 	mutex_init(&wdt->reg_lock);
 	wdt->is_registered = false;
+	INIT_WORK(&wdt->unregister, mei_wdt_unregister_work);
 	init_completion(&wdt->response);
 
 	mei_cldev_set_drvdata(cldev, wdt);
@@ -553,9 +586,13 @@ static int mei_wdt_probe(struct mei_cl_device *cldev,
 		goto err_out;
 	}
 
-	ret = mei_cldev_register_event_cb(wdt->cldev, BIT(MEI_CL_EVENT_RX),
+	ret = mei_cldev_register_event_cb(wdt->cldev,
+					  BIT(MEI_CL_EVENT_RX) |
+					  BIT(MEI_CL_EVENT_NOTIF),
 					  mei_wdt_event, NULL);
-	if (ret) {
+
+	/* on legacy devices notification is not supported */
+	if (ret && ret != -EOPNOTSUPP) {
 		dev_err(&cldev->dev, "Could not register event ret=%d\n", ret);
 		goto err_disable;
 	}
@@ -599,6 +636,8 @@ static int mei_wdt_remove(struct mei_cl_device *cldev)
 	if (!completion_done(&wdt->response))
 		complete(&wdt->response);
 
+	cancel_work_sync(&wdt->unregister);
+
 	mei_wdt_unregister(wdt);
 
 	kref_put(&wdt->refcnt, mei_wdt_release);
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Back to linux.kernel | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

[char-misc-next v2 0/7] mei: create proper iAMT watchdog driver Tomas Winkler <tomas.winkler@intel.com> - 2015-12-17 16:00 +0100
  [char-misc-next v2 2/7] mei: wd: drop the watchdog code from the core mei driver Tomas Winkler <tomas.winkler@intel.com> - 2015-12-17 16:00 +0100
  [char-misc-next v2 1/7] mei: drop nfc leftovers from the mei driver Tomas Winkler <tomas.winkler@intel.com> - 2015-12-17 16:00 +0100
  [char-misc-next v2 6/7] watchdog: mei_wdt: register wd device only if required Tomas Winkler <tomas.winkler@intel.com> - 2015-12-17 16:00 +0100
    Re: [char-misc-next v2 6/7] watchdog: mei_wdt: register wd device  only if required Guenter Roeck <linux@roeck-us.net> - 2015-12-18 18:00 +0100
      RE: [char-misc-next v2 6/7] watchdog: mei_wdt: register wd device  only if required "Winkler, Tomas" <tomas.winkler@intel.com> - 2015-12-20 13:30 +0100
        Re: [char-misc-next v2 6/7] watchdog: mei_wdt: register wd device  only if required Guenter Roeck <linux@roeck-us.net> - 2015-12-20 19:20 +0100
  [char-misc-next v2 7/7] watchdog: mei_wdt: re-register device on event Tomas Winkler <tomas.winkler@intel.com> - 2015-12-17 16:00 +0100
    Re: [char-misc-next v2 7/7] watchdog: mei_wdt: re-register device on  event Guenter Roeck <linux@roeck-us.net> - 2015-12-18 18:10 +0100
      Re: [char-misc-next v2 7/7] watchdog: mei_wdt: re-register device  on event One Thousand Gnomes <gnomes@lxorguk.ukuu.org.uk> - 2015-12-18 18:30 +0100
        Re: [char-misc-next v2 7/7] watchdog: mei_wdt: re-register device on  event Guenter Roeck <linux@roeck-us.net> - 2015-12-18 19:00 +0100
          Re: [char-misc-next v2 7/7] watchdog: mei_wdt: re-register device  on event One Thousand Gnomes <gnomes@lxorguk.ukuu.org.uk> - 2015-12-18 19:20 +0100
            RE: [char-misc-next v2 7/7] watchdog: mei_wdt: re-register device  on event "Winkler, Tomas" <tomas.winkler@intel.com> - 2015-12-20 14:00 +0100
  [char-misc-next v2 5/7] mei: bus: whitelist the watchdog client Tomas Winkler <tomas.winkler@intel.com> - 2015-12-17 16:00 +0100
  [char-misc-next v2 3/7] watchdog: mei_wdt: implement MEI iAMT watchdog driver Tomas Winkler <tomas.winkler@intel.com> - 2015-12-17 16:00 +0100
    Re: [char-misc-next v2 3/7] watchdog: mei_wdt: implement MEI iAMT  watchdog driver Guenter Roeck <linux@roeck-us.net> - 2015-12-18 17:40 +0100
  [char-misc-next 4/7] watchdog: mei_wdt: add status debugfs entry Tomas Winkler <tomas.winkler@intel.com> - 2015-12-17 16:00 +0100
    Re: [char-misc-next 4/7] watchdog: mei_wdt: add status debugfs entry Guenter Roeck <linux@roeck-us.net> - 2015-12-18 17:50 +0100
      RE: [char-misc-next 4/7] watchdog: mei_wdt: add status debugfs entry "Winkler, Tomas" <tomas.winkler@intel.com> - 2015-12-20 10:50 +0100
        Re: [char-misc-next 4/7] watchdog: mei_wdt: add status debugfs entry Guenter Roeck <linux@roeck-us.net> - 2015-12-20 11:50 +0100
          RE: [char-misc-next 4/7] watchdog: mei_wdt: add status debugfs entry "Winkler, Tomas" <tomas.winkler@intel.com> - 2015-12-20 13:00 +0100

csiph-web