From 8d52af6795c0480a20272159103976a893603fde Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 12 Dec 2017 13:27:06 +0200 Subject: [PATCH] mei: speed up the power down flow When mei driver is powering down due to suspend or shutdown it will iterate over the mei client bus and disconnect each client device attached in turn. The power down flow consist of the link rest, which causes all clients get disconnected at once, hence the individual disconnection can be omitted and significantly reduce power down flow. Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/bus.c | 10 ++++++++-- drivers/misc/mei/hw-me.c | 4 +++- drivers/misc/mei/hw-txe.c | 4 +++- drivers/misc/mei/init.c | 4 +++- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 1ac10cb..2a5146b 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -543,14 +543,20 @@ int mei_cldev_disable(struct mei_cl_device *cldev) mutex_lock(&bus->device_lock); if (!mei_cl_is_connected(cl)) { - dev_dbg(bus->dev, "Already disconnected"); + dev_dbg(bus->dev, "Already disconnected\n"); + err = 0; + goto out; + } + + if (bus->dev_state == MEI_DEV_POWER_DOWN) { + dev_dbg(bus->dev, "Device is powering down don't botther with disconnection\n"); err = 0; goto out; } err = mei_cl_disconnect(cl); if (err < 0) - dev_err(bus->dev, "Could not disconnect from the ME client"); + dev_err(bus->dev, "Could not disconnect from the ME client\n"); out: /* Flush queues and remove any pending read */ diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c index 10dcf4f..0b21f9e 100644 --- a/drivers/misc/mei/hw-me.c +++ b/drivers/misc/mei/hw-me.c @@ -1260,7 +1260,9 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id) if (rets == -ENODATA) break; - if (rets && dev->dev_state != MEI_DEV_RESETTING) { + if (rets && + (dev->dev_state != MEI_DEV_RESETTING || + dev->dev_state != MEI_DEV_POWER_DOWN)) { dev_err(dev->dev, "mei_irq_read_handler ret = %d.\n", rets); schedule_work(&dev->reset_work); diff --git a/drivers/misc/mei/hw-txe.c b/drivers/misc/mei/hw-txe.c index 24e4a4c..8419727 100644 --- a/drivers/misc/mei/hw-txe.c +++ b/drivers/misc/mei/hw-txe.c @@ -1127,7 +1127,9 @@ irqreturn_t mei_txe_irq_thread_handler(int irq, void *dev_id) if (test_and_clear_bit(TXE_INTR_OUT_DB_BIT, &hw->intr_cause)) { /* Read from TXE */ rets = mei_irq_read_handler(dev, &cmpl_list, &slots); - if (rets && dev->dev_state != MEI_DEV_RESETTING) { + if (rets && + (dev->dev_state != MEI_DEV_RESETTING || + dev->dev_state != MEI_DEV_POWER_DOWN)) { dev_err(dev->dev, "mei_irq_read_handler ret = %d.\n", rets); diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index d2f6914..c46f6e9 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -310,6 +310,9 @@ void mei_stop(struct mei_device *dev) { dev_dbg(dev->dev, "stopping the device.\n"); + mutex_lock(&dev->device_lock); + dev->dev_state = MEI_DEV_POWER_DOWN; + mutex_unlock(&dev->device_lock); mei_cl_bus_remove_devices(dev); mei_cancel_work(dev); @@ -319,7 +322,6 @@ void mei_stop(struct mei_device *dev) mutex_lock(&dev->device_lock); - dev->dev_state = MEI_DEV_POWER_DOWN; mei_reset(dev); /* move device to disabled state unconditionally */ dev->dev_state = MEI_DEV_DISABLED; -- 2.7.4