diff options
Diffstat (limited to 'drivers/scsi/ibmvscsi')
-rw-r--r-- | drivers/scsi/ibmvscsi/ibmvfc.c | 28 | ||||
-rw-r--r-- | drivers/scsi/ibmvscsi/ibmvscsi.c | 20 | ||||
-rw-r--r-- | drivers/scsi/ibmvscsi/ibmvscsi.h | 1 | ||||
-rw-r--r-- | drivers/scsi/ibmvscsi/ibmvstgt.c | 1 | ||||
-rw-r--r-- | drivers/scsi/ibmvscsi/iseries_vscsi.c | 6 | ||||
-rw-r--r-- | drivers/scsi/ibmvscsi/rpa_vscsi.c | 14 |
6 files changed, 70 insertions, 0 deletions
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index 732f6d35b4a..c2eea711a5c 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -28,7 +28,9 @@ #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/kthread.h> +#include <linux/slab.h> #include <linux/of.h> +#include <linux/pm.h> #include <linux/stringify.h> #include <asm/firmware.h> #include <asm/irq.h> @@ -4736,6 +4738,27 @@ static int ibmvfc_remove(struct vio_dev *vdev) } /** + * ibmvfc_resume - Resume from suspend + * @dev: device struct + * + * We may have lost an interrupt across suspend/resume, so kick the + * interrupt handler + * + */ +static int ibmvfc_resume(struct device *dev) +{ + unsigned long flags; + struct ibmvfc_host *vhost = dev_get_drvdata(dev); + struct vio_dev *vdev = to_vio_dev(dev); + + spin_lock_irqsave(vhost->host->host_lock, flags); + vio_disable_interrupts(vdev); + tasklet_schedule(&vhost->tasklet); + spin_unlock_irqrestore(vhost->host->host_lock, flags); + return 0; +} + +/** * ibmvfc_get_desired_dma - Calculate DMA resources needed by the driver * @vdev: vio device struct * @@ -4755,6 +4778,10 @@ static struct vio_device_id ibmvfc_device_table[] __devinitdata = { }; MODULE_DEVICE_TABLE(vio, ibmvfc_device_table); +static struct dev_pm_ops ibmvfc_pm_ops = { + .resume = ibmvfc_resume +}; + static struct vio_driver ibmvfc_driver = { .id_table = ibmvfc_device_table, .probe = ibmvfc_probe, @@ -4763,6 +4790,7 @@ static struct vio_driver ibmvfc_driver = { .driver = { .name = IBMVFC_NAME, .owner = THIS_MODULE, + .pm = &ibmvfc_pm_ops, } }; diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index e3a18e0ef27..ff5ec5ac1fb 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -70,7 +70,9 @@ #include <linux/moduleparam.h> #include <linux/dma-mapping.h> #include <linux/delay.h> +#include <linux/slab.h> #include <linux/of.h> +#include <linux/pm.h> #include <asm/firmware.h> #include <asm/vio.h> #include <scsi/scsi.h> @@ -1991,6 +1993,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 +2015,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 +2027,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 76425303def..9cb7c6a773e 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/ibmvstgt.c b/drivers/scsi/ibmvscsi/ibmvstgt.c index d5eaf972710..e2056d517e9 100644 --- a/drivers/scsi/ibmvscsi/ibmvstgt.c +++ b/drivers/scsi/ibmvscsi/ibmvstgt.c @@ -23,6 +23,7 @@ */ #include <linux/interrupt.h> #include <linux/module.h> +#include <linux/slab.h> #include <scsi/scsi.h> #include <scsi/scsi_host.h> #include <scsi/scsi_transport_srp.h> diff --git a/drivers/scsi/ibmvscsi/iseries_vscsi.c b/drivers/scsi/ibmvscsi/iseries_vscsi.c index 0775fdee5fa..f4776451a75 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 462a8574dad..a864ccc0a34 100644 --- a/drivers/scsi/ibmvscsi/rpa_vscsi.c +++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c @@ -32,6 +32,7 @@ #include <asm/iommu.h> #include <asm/hvcall.h> #include <linux/dma-mapping.h> +#include <linux/gfp.h> #include <linux/interrupt.h> #include "ibmvscsi.h" @@ -334,10 +335,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, }; |