Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

scsi: smartpqi: Fix hibernate and suspend

Restructure the hibernate/suspend code to allow workarounds for the
controller boot differences.

Newer controllers have subtle differences in the way that they boot up.

Link: https://lore.kernel.org/r/164375214859.440833.14683009064111314948.stgit@brunhilda.pdev.net
Reviewed-by: Mike McGowen <mike.mcgowen@microchip.com>
Reviewed-by: Scott Benesh <scott.benesh@microchip.com>
Reviewed-by: Scott Teel <scott.teel@microchip.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microchip.com>
Signed-off-by: Don Brace <don.brace@microchip.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Kevin Barnett and committed by
Martin K. Petersen
c66e078a 5e693586

+82 -36
+82 -36
drivers/scsi/smartpqi/smartpqi_init.c
··· 8955 8955 { 8956 8956 if (pci_dev->subsystem_vendor == PCI_VENDOR_ID_ADAPTEC2 && pci_dev->subsystem_device == 0x1304) 8957 8957 return RESTART; 8958 + 8958 8959 return SUSPEND; 8959 8960 } 8960 8961 8961 - static __maybe_unused int pqi_suspend(struct pci_dev *pci_dev, pm_message_t state) 8962 + static int pqi_suspend_or_freeze(struct device *dev, bool suspend) 8962 8963 { 8964 + struct pci_dev *pci_dev; 8963 8965 struct pqi_ctrl_info *ctrl_info; 8964 - enum bmic_flush_cache_shutdown_event shutdown_event; 8965 8966 8966 - shutdown_event = pqi_get_flush_cache_shutdown_event(pci_dev); 8967 + pci_dev = to_pci_dev(dev); 8967 8968 ctrl_info = pci_get_drvdata(pci_dev); 8968 8969 8969 8970 pqi_wait_until_ofa_finished(ctrl_info); ··· 8974 8973 pqi_ctrl_block_device_reset(ctrl_info); 8975 8974 pqi_ctrl_block_requests(ctrl_info); 8976 8975 pqi_ctrl_wait_until_quiesced(ctrl_info); 8977 - pqi_flush_cache(ctrl_info, shutdown_event); 8976 + 8977 + if (suspend) { 8978 + enum bmic_flush_cache_shutdown_event shutdown_event; 8979 + 8980 + shutdown_event = pqi_get_flush_cache_shutdown_event(pci_dev); 8981 + pqi_flush_cache(ctrl_info, shutdown_event); 8982 + } 8983 + 8978 8984 pqi_stop_heartbeat_timer(ctrl_info); 8979 - 8980 8985 pqi_crash_if_pending_command(ctrl_info); 8981 - 8982 - if (state.event == PM_EVENT_FREEZE) 8983 - return 0; 8984 - 8985 - pci_save_state(pci_dev); 8986 - pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state)); 8986 + pqi_free_irqs(ctrl_info); 8987 8987 8988 8988 ctrl_info->controller_online = false; 8989 8989 ctrl_info->pqi_mode_enabled = false; ··· 8992 8990 return 0; 8993 8991 } 8994 8992 8995 - static __maybe_unused int pqi_resume(struct pci_dev *pci_dev) 8993 + static __maybe_unused int pqi_suspend(struct device *dev) 8994 + { 8995 + return pqi_suspend_or_freeze(dev, true); 8996 + } 8997 + 8998 + static int pqi_resume_or_restore(struct device *dev) 8996 8999 { 8997 9000 int rc; 9001 + struct pci_dev *pci_dev; 8998 9002 struct pqi_ctrl_info *ctrl_info; 8999 9003 9004 + pci_dev = to_pci_dev(dev); 9000 9005 ctrl_info = pci_get_drvdata(pci_dev); 9001 9006 9002 - if (pci_dev->current_state != PCI_D0) { 9003 - ctrl_info->max_hw_queue_index = 0; 9004 - pqi_free_interrupts(ctrl_info); 9005 - pqi_change_irq_mode(ctrl_info, IRQ_MODE_INTX); 9006 - rc = request_irq(pci_irq_vector(pci_dev, 0), pqi_irq_handler, 9007 - IRQF_SHARED, DRIVER_NAME_SHORT, 9008 - &ctrl_info->queue_groups[0]); 9009 - if (rc) { 9010 - dev_err(&ctrl_info->pci_dev->dev, 9011 - "irq %u init failed with error %d\n", 9012 - pci_dev->irq, rc); 9013 - return rc; 9014 - } 9015 - pqi_ctrl_unblock_device_reset(ctrl_info); 9016 - pqi_ctrl_unblock_requests(ctrl_info); 9017 - pqi_scsi_unblock_requests(ctrl_info); 9018 - pqi_ctrl_unblock_scan(ctrl_info); 9019 - return 0; 9020 - } 9021 - 9022 - pci_set_power_state(pci_dev, PCI_D0); 9023 - pci_restore_state(pci_dev); 9007 + rc = pqi_request_irqs(ctrl_info); 9008 + if (rc) 9009 + return rc; 9024 9010 9025 9011 pqi_ctrl_unblock_device_reset(ctrl_info); 9026 9012 pqi_ctrl_unblock_requests(ctrl_info); 9027 9013 pqi_scsi_unblock_requests(ctrl_info); 9028 9014 pqi_ctrl_unblock_scan(ctrl_info); 9029 9015 9016 + ssleep(PQI_POST_RESET_DELAY_SECS); 9017 + 9030 9018 return pqi_ctrl_init_resume(ctrl_info); 9031 9019 } 9020 + 9021 + static int pqi_freeze(struct device *dev) 9022 + { 9023 + return pqi_suspend_or_freeze(dev, false); 9024 + } 9025 + 9026 + static int pqi_thaw(struct device *dev) 9027 + { 9028 + int rc; 9029 + struct pci_dev *pci_dev; 9030 + struct pqi_ctrl_info *ctrl_info; 9031 + 9032 + pci_dev = to_pci_dev(dev); 9033 + ctrl_info = pci_get_drvdata(pci_dev); 9034 + 9035 + rc = pqi_request_irqs(ctrl_info); 9036 + if (rc) 9037 + return rc; 9038 + 9039 + ctrl_info->controller_online = true; 9040 + ctrl_info->pqi_mode_enabled = true; 9041 + 9042 + pqi_ctrl_unblock_device_reset(ctrl_info); 9043 + pqi_ctrl_unblock_requests(ctrl_info); 9044 + pqi_scsi_unblock_requests(ctrl_info); 9045 + pqi_ctrl_unblock_scan(ctrl_info); 9046 + 9047 + return 0; 9048 + } 9049 + 9050 + static int pqi_poweroff(struct device *dev) 9051 + { 9052 + struct pci_dev *pci_dev; 9053 + struct pqi_ctrl_info *ctrl_info; 9054 + enum bmic_flush_cache_shutdown_event shutdown_event; 9055 + 9056 + pci_dev = to_pci_dev(dev); 9057 + ctrl_info = pci_get_drvdata(pci_dev); 9058 + 9059 + shutdown_event = pqi_get_flush_cache_shutdown_event(pci_dev); 9060 + pqi_flush_cache(ctrl_info, shutdown_event); 9061 + 9062 + return 0; 9063 + } 9064 + 9065 + static const struct dev_pm_ops pqi_pm_ops = { 9066 + .suspend = pqi_suspend, 9067 + .resume = pqi_resume_or_restore, 9068 + .freeze = pqi_freeze, 9069 + .thaw = pqi_thaw, 9070 + .poweroff = pqi_poweroff, 9071 + .restore = pqi_resume_or_restore, 9072 + }; 9032 9073 9033 9074 /* Define the PCI IDs for the controllers that we support. */ 9034 9075 static const struct pci_device_id pqi_pci_id_table[] = { ··· 9739 9694 .remove = pqi_pci_remove, 9740 9695 .shutdown = pqi_shutdown, 9741 9696 #if defined(CONFIG_PM) 9742 - .suspend = pqi_suspend, 9743 - .resume = pqi_resume, 9697 + .driver = { 9698 + .pm = &pqi_pm_ops 9699 + }, 9744 9700 #endif 9745 9701 }; 9746 9702