Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c216fdeb authored by Tomas Winkler's avatar Tomas Winkler Committed by Greg Kroah-Hartman
Browse files

mei: wd: decouple and revamp watchdog state machine



Before ME watchdog was exported through standard watchdog interface
it was closed and started together with the mei device.

The major issue is that closing ME watchdog disabled also MEI device,
to fix this the watchdog state machine has to be independent from MEI
state machine.

Signed-off-by: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 248ffdf7
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -330,7 +330,6 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)

	dev->me_clients_num = 0;
	dev->rd_msg_hdr = 0;
	dev->stop = false;
	dev->wd_pending = false;

	/* update the state of the registers after reset */
+1 −1
Original line number Diff line number Diff line
@@ -56,7 +56,7 @@ int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *cl);


int mei_wd_send(struct mei_device *dev);
int mei_wd_stop(struct mei_device *dev, bool preserve);
int mei_wd_stop(struct mei_device *dev);
int mei_wd_host_init(struct mei_device *dev);
/*
 * mei_watchdog_register  - Registering watchdog interface
+3 −6
Original line number Diff line number Diff line
@@ -1224,10 +1224,9 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list,
		}
	}

	if (dev->stop && !dev->wd_pending) {
		dev->wd_stopped = true;
	if (dev->wd_state == MEI_WD_STOPPING) {
		dev->wd_state = MEI_WD_IDLE;
		wake_up_interruptible(&dev->wait_stop_wd);
		return 0;
	}

	if (dev->extra_write_index) {
@@ -1250,14 +1249,12 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list,

			dev->wd_pending = false;

			if (dev->wd_timeout)
			if (dev->wd_state == MEI_WD_RUNNING)
				*slots -= mei_data2slots(MEI_WD_START_MSG_SIZE);
			else
				*slots -= mei_data2slots(MEI_WD_STOP_MSG_SIZE);
		}
	}
	if (dev->stop)
		return -ENODEV;

	/* complete control write list CB */
	dev_dbg(&dev->pdev->dev, "complete control write list cb.\n");
+7 −2
Original line number Diff line number Diff line
@@ -1060,7 +1060,9 @@ static void __devexit mei_remove(struct pci_dev *pdev)

	mutex_lock(&dev->device_lock);

	mei_wd_stop(dev, false);
	cancel_delayed_work(&dev->timer_work);

	mei_wd_stop(dev);

	mei_device = NULL;

@@ -1115,8 +1117,11 @@ static int mei_pci_suspend(struct device *device)
	if (!dev)
		return -ENODEV;
	mutex_lock(&dev->device_lock);

	cancel_delayed_work(&dev->timer_work);

	/* Stop watchdog if exists */
	err = mei_wd_stop(dev, true);
	err = mei_wd_stop(dev);
	/* Set new mei state */
	if (dev->dev_state == MEI_DEV_ENABLED ||
	    dev->dev_state == MEI_DEV_RECOVERING_FROM_RESET) {
+10 −4
Original line number Diff line number Diff line
@@ -33,6 +33,8 @@
#define MEI_WD_MIN_TIMEOUT       120  /* seconds */
#define MEI_WD_MAX_TIMEOUT     65535  /* seconds */

#define MEI_WD_STOP_TIMEOUT      10 /* msecs */

#define MEI_WD_STATE_INDEPENDENCE_MSG_SENT       (1 << 0)

#define MEI_RD_MSG_BUF_SIZE           (128 * sizeof(u32))
@@ -120,6 +122,12 @@ enum mei_file_transaction_states {
	MEI_READ_COMPLETE
};

enum mei_wd_states {
	MEI_WD_IDLE,
	MEI_WD_RUNNING,
	MEI_WD_STOPPING,
};

/* MEI CB */
enum mei_cb_major_types {
	MEI_READ = 0,
@@ -228,7 +236,6 @@ struct mei_device {
	enum mei_dev_state dev_state;
	enum mei_init_clients_states init_clients_state;
	u16 init_clients_timer;
	bool stop;
	bool need_reset;

	u32 extra_write_index;
@@ -248,11 +255,10 @@ struct mei_device {
	bool mei_host_buffer_is_empty;

	struct mei_cl wd_cl;
	enum mei_wd_states wd_state;
	bool wd_interface_reg;
	bool wd_pending;
	bool wd_stopped;
	bool wd_bypass;	/* if false, don't refresh watchdog ME client */
	u16 wd_timeout;	/* seconds ((wd_data[1] << 8) + wd_data[0]) */
	u16 wd_timeout;
	unsigned char wd_data[MEI_WD_START_MSG_SIZE];


Loading