diff options
-rw-r--r-- | drivers/scsi/ibmvscsi/ibmvscsi.c | 19 | ||||
-rw-r--r-- | drivers/scsi/ibmvscsi/ibmvscsi.h | 1 | ||||
-rw-r--r-- | drivers/scsi/ibmvscsi/iseries_vscsi.c | 6 | ||||
-rw-r--r-- | drivers/scsi/ibmvscsi/rpa_vscsi.c | 13 |
4 files changed, 39 insertions, 0 deletions
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index e3a18e0..dc1bcbe 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -71,6 +71,7 @@ #include <linux/dma-mapping.h> #include <linux/delay.h> #include <linux/of.h> +#include <linux/pm.h> #include <asm/firmware.h> #include <asm/vio.h> #include <scsi/scsi.h> @@ -1991,6 +1992,19 @@ static int ibmvscsi_remove(struct vio_dev *vdev) } /** + * ibmvscsi_resume: Resume from suspend + * @dev: device struct + * + * We may have lost an interrupt across suspend/resume, so kick the + * interrupt handler + */ +static int ibmvscsi_resume(struct device *dev) +{ + struct ibmvscsi_host_data *hostdata = dev_get_drvdata(dev); + return ibmvscsi_ops->resume(hostdata); +} + +/** * ibmvscsi_device_table: Used by vio.c to match devices in the device tree we * support. */ @@ -2000,6 +2014,10 @@ static struct vio_device_id ibmvscsi_device_table[] __devinitdata = { }; MODULE_DEVICE_TABLE(vio, ibmvscsi_device_table); +static struct dev_pm_ops ibmvscsi_pm_ops = { + .resume = ibmvscsi_resume +}; + static struct vio_driver ibmvscsi_driver = { .id_table = ibmvscsi_device_table, .probe = ibmvscsi_probe, @@ -2008,6 +2026,7 @@ static struct vio_driver ibmvscsi_driver = { .driver = { .name = "ibmvscsi", .owner = THIS_MODULE, + .pm = &ibmvscsi_pm_ops, } }; diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.h b/drivers/scsi/ibmvscsi/ibmvscsi.h index 7642530..9cb7c6a 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.h +++ b/drivers/scsi/ibmvscsi/ibmvscsi.h @@ -120,6 +120,7 @@ struct ibmvscsi_ops { struct ibmvscsi_host_data *hostdata); int (*send_crq)(struct ibmvscsi_host_data *hostdata, u64 word1, u64 word2); + int (*resume) (struct ibmvscsi_host_data *hostdata); }; extern struct ibmvscsi_ops iseriesvscsi_ops; diff --git a/drivers/scsi/ibmvscsi/iseries_vscsi.c b/drivers/scsi/ibmvscsi/iseries_vscsi.c index 0775fde..f477645 100644 --- a/drivers/scsi/ibmvscsi/iseries_vscsi.c +++ b/drivers/scsi/ibmvscsi/iseries_vscsi.c @@ -158,10 +158,16 @@ static int iseriesvscsi_send_crq(struct ibmvscsi_host_data *hostdata, 0); } +static int iseriesvscsi_resume(struct ibmvscsi_host_data *hostdata) +{ + return 0; +} + struct ibmvscsi_ops iseriesvscsi_ops = { .init_crq_queue = iseriesvscsi_init_crq_queue, .release_crq_queue = iseriesvscsi_release_crq_queue, .reset_crq_queue = iseriesvscsi_reset_crq_queue, .reenable_crq_queue = iseriesvscsi_reenable_crq_queue, .send_crq = iseriesvscsi_send_crq, + .resume = iseriesvscsi_resume, }; diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c index 462a857..63a30cb 100644 --- a/drivers/scsi/ibmvscsi/rpa_vscsi.c +++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c @@ -334,10 +334,23 @@ static int rpavscsi_reenable_crq_queue(struct crq_queue *queue, return rc; } +/** + * rpavscsi_resume: - resume after suspend + * @hostdata: ibmvscsi_host_data of host + * + */ +static int rpavscsi_resume(struct ibmvscsi_host_data *hostdata) +{ + vio_disable_interrupts(to_vio_dev(hostdata->dev)); + tasklet_schedule(&hostdata->srp_task); + return 0; +} + struct ibmvscsi_ops rpavscsi_ops = { .init_crq_queue = rpavscsi_init_crq_queue, .release_crq_queue = rpavscsi_release_crq_queue, .reset_crq_queue = rpavscsi_reset_crq_queue, .reenable_crq_queue = rpavscsi_reenable_crq_queue, .send_crq = rpavscsi_send_crq, + .resume = rpavscsi_resume, }; |