diff mbox series

[21/24] mpi3mr: add support of PM suspend and resume

Message ID 20201222101156.98308-22-kashyap.desai@broadcom.com
State Superseded
Headers show
Series Introducing mpi3mr driver | expand

Commit Message

Kashyap Desai Dec. 22, 2020, 10:11 a.m. UTC
Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>
Cc: sathya.prakash@broadcom.com
---
 drivers/scsi/mpi3mr/mpi3mr_os.c | 85 +++++++++++++++++++++++++++++++++
 1 file changed, 85 insertions(+)

Comments

Tomas Henzl Feb. 22, 2021, 3:32 p.m. UTC | #1
On 12/22/20 11:11 AM, Kashyap Desai wrote:
> Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>

> Cc: sathya.prakash@broadcom.com

> ---

>  drivers/scsi/mpi3mr/mpi3mr_os.c | 85 +++++++++++++++++++++++++++++++++

>  1 file changed, 85 insertions(+)

> 

> diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c

> index 1708aca1a5cd..ac47eed74705 100644

> --- a/drivers/scsi/mpi3mr/mpi3mr_os.c

> +++ b/drivers/scsi/mpi3mr/mpi3mr_os.c

...
> +/**

> + * mpi3mr_resume - PCI power management resume callback

> + * @pdev: PCI device instance

> + *

> + * Restore the power state to D0 and reinitialize the controller

> + * and resume I/O operations to the target devices

> + *

> + * Return: 0 on success, non-zero on failure

> + */

> +static int mpi3mr_resume(struct pci_dev *pdev)

> +{

> +	struct Scsi_Host *shost = pci_get_drvdata(pdev);

> +	struct mpi3mr_ioc *mrioc;

> +	pci_power_t device_state = pdev->current_state;

> +	int r;

> +

> +	mrioc = shost_priv(shost);

> +

> +	ioc_info(mrioc, "pdev=0x%p, slot=%s, previous operating state [D%d]\n",

> +	    pdev, pci_name(pdev), device_state);

> +	pci_set_power_state(pdev, PCI_D0);

> +	pci_enable_wake(pdev, PCI_D0, 0);

> +	pci_restore_state(pdev);

> +	mrioc->pdev = pdev;

> +	mrioc->cpu_count = num_online_cpus();

> +	r = mpi3mr_setup_resources(mrioc);

> +	if (r) {

> +		ioc_info(mrioc, "%s: Setup resoruces failed[%d]\n",


A typo 					here ^
> +		    __func__, r);

> +		return r;

> +	}
Kashyap Desai Feb. 25, 2021, 1:37 p.m. UTC | #2
> -----Original Message-----

> From: Tomas Henzl [mailto:thenzl@redhat.com]

> Sent: Monday, February 22, 2021 9:03 PM

> To: Kashyap Desai <kashyap.desai@broadcom.com>; linux-

> scsi@vger.kernel.org

> Cc: jejb@linux.ibm.com; martin.petersen@oracle.com;

> steve.hagan@broadcom.com; peter.rivera@broadcom.com; mpi3mr-

> linuxdrv.pdl@broadcom.com; sathya.prakash@broadcom.com

> Subject: Re: [PATCH 21/24] mpi3mr: add support of PM suspend and resume

>

> On 12/22/20 11:11 AM, Kashyap Desai wrote:

> > Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>

> > Cc: sathya.prakash@broadcom.com

> > ---

> >  drivers/scsi/mpi3mr/mpi3mr_os.c | 85

> > +++++++++++++++++++++++++++++++++

> >  1 file changed, 85 insertions(+)

> >

> > diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c

> > b/drivers/scsi/mpi3mr/mpi3mr_os.c index 1708aca1a5cd..ac47eed74705

> > 100644

> > --- a/drivers/scsi/mpi3mr/mpi3mr_os.c

> > +++ b/drivers/scsi/mpi3mr/mpi3mr_os.c

> ...

> > +/**

> > + * mpi3mr_resume - PCI power management resume callback

> > + * @pdev: PCI device instance

> > + *

> > + * Restore the power state to D0 and reinitialize the controller

> > + * and resume I/O operations to the target devices

> > + *

> > + * Return: 0 on success, non-zero on failure  */ static int

> > +mpi3mr_resume(struct pci_dev *pdev) {

> > +	struct Scsi_Host *shost = pci_get_drvdata(pdev);

> > +	struct mpi3mr_ioc *mrioc;

> > +	pci_power_t device_state = pdev->current_state;

> > +	int r;

> > +

> > +	mrioc = shost_priv(shost);

> > +

> > +	ioc_info(mrioc, "pdev=0x%p, slot=%s, previous operating state

> [D%d]\n",

> > +	    pdev, pci_name(pdev), device_state);

> > +	pci_set_power_state(pdev, PCI_D0);

> > +	pci_enable_wake(pdev, PCI_D0, 0);

> > +	pci_restore_state(pdev);

> > +	mrioc->pdev = pdev;

> > +	mrioc->cpu_count = num_online_cpus();

> > +	r = mpi3mr_setup_resources(mrioc);

> > +	if (r) {

> > +		ioc_info(mrioc, "%s: Setup resoruces failed[%d]\n",

>

> A typo 					here ^


Noted. I will fix it in V2. I will scan all the patch for such things one
more time.

Kashyap

> > +		    __func__, r);

> > +		return r;

> > +	}
Hannes Reinecke March 1, 2021, 7:18 a.m. UTC | #3
On 12/22/20 11:11 AM, Kashyap Desai wrote:
> Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>

> Cc: sathya.prakash@broadcom.com

> ---

>   drivers/scsi/mpi3mr/mpi3mr_os.c | 85 +++++++++++++++++++++++++++++++++

>   1 file changed, 85 insertions(+)

> 

> diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c

> index 1708aca1a5cd..ac47eed74705 100644

> --- a/drivers/scsi/mpi3mr/mpi3mr_os.c

> +++ b/drivers/scsi/mpi3mr/mpi3mr_os.c

> @@ -3480,6 +3480,87 @@ static void mpi3mr_shutdown(struct pci_dev *pdev)

>   

>   }

>   

> +#ifdef CONFIG_PM

> +/**

> + * mpi3mr_suspend - PCI power management suspend callback

> + * @pdev: PCI device instance

> + * @state: New power state

> + *

> + * Change the power state to the given value and cleanup the IOC

> + * by issuing MUR and shutdown notification

> + *

> + * Return: 0 always.

> + */

> +static int mpi3mr_suspend(struct pci_dev *pdev, pm_message_t state)

> +{

> +	struct Scsi_Host *shost = pci_get_drvdata(pdev);

> +	struct mpi3mr_ioc *mrioc;

> +	pci_power_t device_state;

> +

> +	if (!shost)

> +		return 0;

> +

> +	mrioc = shost_priv(shost);

> +	while (mrioc->reset_in_progress || mrioc->is_driver_loading)

> +		ssleep(1);

> +	mrioc->stop_drv_processing = 1;

> +	mpi3mr_cleanup_fwevt_list(mrioc);

> +	scsi_block_requests(shost);

> +	mpi3mr_stop_watchdog(mrioc);

> +	mpi3mr_cleanup_ioc(mrioc, 1);

> +

> +	device_state = pci_choose_state(pdev, state);

> +	ioc_info(mrioc, "pdev=0x%p, slot=%s, entering operating state [D%d]\n",

> +	    pdev, pci_name(pdev), device_state);

> +	pci_save_state(pdev);

> +	pci_set_power_state(pdev, device_state);

> +	mpi3mr_cleanup_resources(mrioc);

> +

> +	return 0;

> +}

> +

> +/**

> + * mpi3mr_resume - PCI power management resume callback

> + * @pdev: PCI device instance

> + *

> + * Restore the power state to D0 and reinitialize the controller

> + * and resume I/O operations to the target devices

> + *

> + * Return: 0 on success, non-zero on failure

> + */

> +static int mpi3mr_resume(struct pci_dev *pdev)

> +{

> +	struct Scsi_Host *shost = pci_get_drvdata(pdev);

> +	struct mpi3mr_ioc *mrioc;

> +	pci_power_t device_state = pdev->current_state;

> +	int r;

> +

> +	mrioc = shost_priv(shost);

> +

> +	ioc_info(mrioc, "pdev=0x%p, slot=%s, previous operating state [D%d]\n",

> +	    pdev, pci_name(pdev), device_state);

> +	pci_set_power_state(pdev, PCI_D0);

> +	pci_enable_wake(pdev, PCI_D0, 0);

> +	pci_restore_state(pdev);

> +	mrioc->pdev = pdev;

> +	mrioc->cpu_count = num_online_cpus();

> +	r = mpi3mr_setup_resources(mrioc);

> +	if (r) {

> +		ioc_info(mrioc, "%s: Setup resoruces failed[%d]\n",

> +		    __func__, r);

> +		return r;

> +	}

> +

> +	mrioc->stop_drv_processing = 0;

> +	mpi3mr_init_ioc(mrioc, 1);

> +	scsi_unblock_requests(shost);

> +	mpi3mr_start_watchdog(mrioc);

> +

> +	return 0;

> +}

> +#endif

> +

> +

>   static const struct pci_device_id mpi3mr_pci_id_table[] = {

>   	{

>   		PCI_DEVICE_SUB(PCI_VENDOR_ID_LSI_LOGIC, 0x00A5,

> @@ -3495,6 +3576,10 @@ static struct pci_driver mpi3mr_pci_driver = {

>   	.probe = mpi3mr_probe,

>   	.remove = mpi3mr_remove,

>   	.shutdown = mpi3mr_shutdown,

> +#ifdef CONFIG_PM

> +	.suspend = mpi3mr_suspend,

> +	.resume = mpi3mr_resume,

> +#endif

>   };

>   

>   static int __init mpi3mr_init(void)

> 

Reviewed-by: Hannes Reinecke <hare@suse.de>


Cheers,

Hannes
-- 
Dr. Hannes Reinecke                Kernel Storage Architect
hare@suse.de                              +49 911 74053 688
SUSE Software Solutions GmbH, Maxfeldstr. 5, 90409 Nürnberg
HRB 36809 (AG Nürnberg), Geschäftsführer: Felix Imendörffer
diff mbox series

Patch

diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c
index 1708aca1a5cd..ac47eed74705 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_os.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_os.c
@@ -3480,6 +3480,87 @@  static void mpi3mr_shutdown(struct pci_dev *pdev)
 
 }
 
+#ifdef CONFIG_PM
+/**
+ * mpi3mr_suspend - PCI power management suspend callback
+ * @pdev: PCI device instance
+ * @state: New power state
+ *
+ * Change the power state to the given value and cleanup the IOC
+ * by issuing MUR and shutdown notification
+ *
+ * Return: 0 always.
+ */
+static int mpi3mr_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	struct Scsi_Host *shost = pci_get_drvdata(pdev);
+	struct mpi3mr_ioc *mrioc;
+	pci_power_t device_state;
+
+	if (!shost)
+		return 0;
+
+	mrioc = shost_priv(shost);
+	while (mrioc->reset_in_progress || mrioc->is_driver_loading)
+		ssleep(1);
+	mrioc->stop_drv_processing = 1;
+	mpi3mr_cleanup_fwevt_list(mrioc);
+	scsi_block_requests(shost);
+	mpi3mr_stop_watchdog(mrioc);
+	mpi3mr_cleanup_ioc(mrioc, 1);
+
+	device_state = pci_choose_state(pdev, state);
+	ioc_info(mrioc, "pdev=0x%p, slot=%s, entering operating state [D%d]\n",
+	    pdev, pci_name(pdev), device_state);
+	pci_save_state(pdev);
+	pci_set_power_state(pdev, device_state);
+	mpi3mr_cleanup_resources(mrioc);
+
+	return 0;
+}
+
+/**
+ * mpi3mr_resume - PCI power management resume callback
+ * @pdev: PCI device instance
+ *
+ * Restore the power state to D0 and reinitialize the controller
+ * and resume I/O operations to the target devices
+ *
+ * Return: 0 on success, non-zero on failure
+ */
+static int mpi3mr_resume(struct pci_dev *pdev)
+{
+	struct Scsi_Host *shost = pci_get_drvdata(pdev);
+	struct mpi3mr_ioc *mrioc;
+	pci_power_t device_state = pdev->current_state;
+	int r;
+
+	mrioc = shost_priv(shost);
+
+	ioc_info(mrioc, "pdev=0x%p, slot=%s, previous operating state [D%d]\n",
+	    pdev, pci_name(pdev), device_state);
+	pci_set_power_state(pdev, PCI_D0);
+	pci_enable_wake(pdev, PCI_D0, 0);
+	pci_restore_state(pdev);
+	mrioc->pdev = pdev;
+	mrioc->cpu_count = num_online_cpus();
+	r = mpi3mr_setup_resources(mrioc);
+	if (r) {
+		ioc_info(mrioc, "%s: Setup resoruces failed[%d]\n",
+		    __func__, r);
+		return r;
+	}
+
+	mrioc->stop_drv_processing = 0;
+	mpi3mr_init_ioc(mrioc, 1);
+	scsi_unblock_requests(shost);
+	mpi3mr_start_watchdog(mrioc);
+
+	return 0;
+}
+#endif
+
+
 static const struct pci_device_id mpi3mr_pci_id_table[] = {
 	{
 		PCI_DEVICE_SUB(PCI_VENDOR_ID_LSI_LOGIC, 0x00A5,
@@ -3495,6 +3576,10 @@  static struct pci_driver mpi3mr_pci_driver = {
 	.probe = mpi3mr_probe,
 	.remove = mpi3mr_remove,
 	.shutdown = mpi3mr_shutdown,
+#ifdef CONFIG_PM
+	.suspend = mpi3mr_suspend,
+	.resume = mpi3mr_resume,
+#endif
 };
 
 static int __init mpi3mr_init(void)