Signed-off-by: Xiang Chen <chenxiang66@xxxxxxxxxxxxx>
Reviewed-by: John Garry <john.garry@xxxxxxxxxx>
---
drivers/scsi/libsas/sas_event.c | 24 +++++++++++++++++++++---
1 file changed, 21 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/libsas/sas_event.c
b/drivers/scsi/libsas/sas_event.c
index 626ef96b9348..3613b9b315bc 100644
--- a/drivers/scsi/libsas/sas_event.c
+++ b/drivers/scsi/libsas/sas_event.c
@@ -50,8 +50,10 @@ void sas_queue_deferred_work(struct sas_ha_struct
*ha)
list_for_each_entry_safe(sw, _sw, &ha->defer_q, drain_node) {
list_del_init(&sw->drain_node);
ret = sas_queue_work(ha, sw);
- if (ret != 1)
+ if (ret != 1) {
+ pm_runtime_put(ha->dev);
sas_free_event(to_asd_sas_event(&sw->work));
+ }
}
spin_unlock_irq(&ha->lock);
}
@@ -126,16 +128,22 @@ void sas_enable_revalidation(struct
sas_ha_struct *ha)
static void sas_port_event_worker(struct work_struct *work)
{
struct asd_sas_event *ev = to_asd_sas_event(work);
+ struct asd_sas_phy *phy = ev->phy;
+ struct sas_ha_struct *ha = phy->ha;
sas_port_event_fns[ev->event](work);
+ pm_runtime_put(ha->dev);
sas_free_event(ev);
}
static void sas_phy_event_worker(struct work_struct *work)
{
struct asd_sas_event *ev = to_asd_sas_event(work);
+ struct asd_sas_phy *phy = ev->phy;
+ struct sas_ha_struct *ha = phy->ha;
sas_phy_event_fns[ev->event](work);
+ pm_runtime_put(ha->dev);
sas_free_event(ev);
}
@@ -170,14 +178,19 @@ int sas_notify_port_event(struct asd_sas_phy
*phy, enum port_event event,
if (!ev)
return -ENOMEM;
+ /* Call pm_runtime_put() with pairs in sas_port_event_worker() */
+ pm_runtime_get_noresume(ha->dev);
+
INIT_SAS_EVENT(ev, sas_port_event_worker, phy, event);
if (sas_defer_event(phy, ev))
return 0;
ret = sas_queue_event(event, &ev->work, ha);
- if (ret != 1)
+ if (ret != 1) {
+ pm_runtime_put(ha->dev);
sas_free_event(ev);
+ }
return ret;
}
@@ -196,14 +209,19 @@ int sas_notify_phy_event(struct asd_sas_phy
*phy, enum phy_event event,
if (!ev)
return -ENOMEM;
+ /* Call pm_runtime_put() with pairs in sas_phy_event_worker() */
+ pm_runtime_get_noresume(ha->dev);
+
INIT_SAS_EVENT(ev, sas_phy_event_worker, phy, event);
if (sas_defer_event(phy, ev))
return 0;
ret = sas_queue_event(event, &ev->work, ha);
- if (ret != 1)
+ if (ret != 1) {
+ pm_runtime_put(ha->dev);
sas_free_event(ev);
+ }
return ret;
}