Commit 65ff4aef authored by Xiang Chen's avatar Xiang Chen Committed by Martin K. Petersen
Browse files

scsi: hisi_sas: Add controller runtime PM support for v3 hw

parent 6c459ea1
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <linux/of_address.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/timer.h>
@@ -32,6 +33,7 @@
#define HISI_SAS_MAX_DEVICES HISI_SAS_MAX_ITCT_ENTRIES
#define HISI_SAS_RESET_BIT	0
#define HISI_SAS_REJECT_CMD_BIT	1
#define HISI_SAS_PM_BIT		2
#define HISI_SAS_MAX_COMMANDS (HISI_SAS_QUEUE_SLOTS)
#define HISI_SAS_RESERVED_IPTT  96
#define HISI_SAS_UNRESERVED_IPTT \
+54 −2
Original line number Diff line number Diff line
@@ -3314,6 +3314,17 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)

	scsi_scan_host(shost);

	/*
	 * For the situation that there are ATA disks connected with SAS
	 * controller, it additionally creates ata_port which will affect the
	 * child_count of hisi_hba->dev. Even if suspended all the disks,
	 * ata_port is still and the child_count of hisi_hba->dev is not 0.
	 * So use pm_suspend_ignore_children() to ignore the effect to
	 * hisi_hba->dev.
	 */
	pm_suspend_ignore_children(dev, true);
	pm_runtime_put_noidle(&pdev->dev);

	return 0;

err_out_register_ha:
@@ -3353,6 +3364,7 @@ static void hisi_sas_v3_remove(struct pci_dev *pdev)
	struct hisi_hba *hisi_hba = sha->lldd_ha;
	struct Scsi_Host *shost = sha->core.shost;

	pm_runtime_get_noresume(dev);
	if (timer_pending(&hisi_hba->timer))
		del_timer(&hisi_hba->timer);

@@ -3407,7 +3419,7 @@ enum {
	hip08,
};

static int suspend_v3_hw(struct device *device)
static int _suspend_v3_hw(struct device *device)
{
	struct pci_dev *pdev = to_pci_dev(device);
	struct sas_ha_struct *sha = pci_get_drvdata(pdev);
@@ -3453,7 +3465,7 @@ static int suspend_v3_hw(struct device *device)
	return 0;
}

static int resume_v3_hw(struct device *device)
static int _resume_v3_hw(struct device *device)
{
	struct pci_dev *pdev = to_pci_dev(device);
	struct sas_ha_struct *sha = pci_get_drvdata(pdev);
@@ -3492,6 +3504,34 @@ static int resume_v3_hw(struct device *device)
	return 0;
}

static int suspend_v3_hw(struct device *device)
{
	struct pci_dev *pdev = to_pci_dev(device);
	struct sas_ha_struct *sha = pci_get_drvdata(pdev);
	struct hisi_hba *hisi_hba = sha->lldd_ha;
	int rc;

	set_bit(HISI_SAS_PM_BIT, &hisi_hba->flags);

	rc = _suspend_v3_hw(device);
	if (rc)
		clear_bit(HISI_SAS_PM_BIT, &hisi_hba->flags);

	return rc;
}

static int resume_v3_hw(struct device *device)
{
	struct pci_dev *pdev = to_pci_dev(device);
	struct sas_ha_struct *sha = pci_get_drvdata(pdev);
	struct hisi_hba *hisi_hba = sha->lldd_ha;
	int rc = _resume_v3_hw(device);

	clear_bit(HISI_SAS_PM_BIT, &hisi_hba->flags);

	return rc;
}

static const struct pci_device_id sas_v3_pci_table[] = {
	{ PCI_VDEVICE(HUAWEI, 0xa230), hip08 },
	{}
@@ -3503,8 +3543,20 @@ static const struct pci_error_handlers hisi_sas_err_handler = {
	.reset_done	= hisi_sas_reset_done_v3_hw,
};

static int runtime_suspend_v3_hw(struct device *dev)
{
	return suspend_v3_hw(dev);
}

static int runtime_resume_v3_hw(struct device *dev)
{
	return resume_v3_hw(dev);
}

static const struct dev_pm_ops hisi_sas_v3_pm_ops = {
	SET_SYSTEM_SLEEP_PM_OPS(suspend_v3_hw, resume_v3_hw)
	SET_RUNTIME_PM_OPS(runtime_suspend_v3_hw,
			   runtime_resume_v3_hw, NULL)
};

static struct pci_driver sas_v3_pci_driver = {