hisi_sas: add v2 hw ACPI support
authorJohn Garry <john.garry@huawei.com>
Tue, 31 May 2016 12:38:49 +0000 (20:38 +0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 13 Jul 2016 03:16:31 +0000 (23:16 -0400)
Add support in v2 hw driver for ACPI.

A check on whether an ACPI handle is available for the device is used to
decide on whether to use ACPI reset handler or syscon for hw reset.

Signed-off-by: John Garry <john.garry@huawei.com>
Signed-off-by: Wei Xu <xuwei5@hisilicon.com>
Reviewed-by: Zhangfei Gao <zhangfei.gao@linaro.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/hisi_sas/hisi_sas_v2_hw.c

index bd20c548876800c405c2862e7953eeb574aec48b..7d5edd1f4bbae7ec09930e2fc61ce4f9ec4a1bfe 100644 (file)
@@ -721,30 +721,41 @@ static int reset_hw_v2_hw(struct hisi_hba *hisi_hba)
                        return -EIO;
        }
 
-       /* reset and disable clock*/
-       regmap_write(hisi_hba->ctrl, hisi_hba->ctrl_reset_reg,
-                       reset_val);
-       regmap_write(hisi_hba->ctrl, hisi_hba->ctrl_clock_ena_reg + 4,
-                       reset_val);
-       msleep(1);
-       regmap_read(hisi_hba->ctrl, hisi_hba->ctrl_reset_sts_reg, &val);
-       if (reset_val != (val & reset_val)) {
-               dev_err(dev, "SAS reset fail.\n");
-               return -EIO;
-       }
+       if (ACPI_HANDLE(dev)) {
+               acpi_status s;
 
-       /* De-reset and enable clock*/
-       regmap_write(hisi_hba->ctrl, hisi_hba->ctrl_reset_reg + 4,
-                       reset_val);
-       regmap_write(hisi_hba->ctrl, hisi_hba->ctrl_clock_ena_reg,
-                       reset_val);
-       msleep(1);
-       regmap_read(hisi_hba->ctrl, hisi_hba->ctrl_reset_sts_reg,
-                       &val);
-       if (val & reset_val) {
-               dev_err(dev, "SAS de-reset fail.\n");
-               return -EIO;
-       }
+               s = acpi_evaluate_object(ACPI_HANDLE(dev), "_RST", NULL, NULL);
+               if (ACPI_FAILURE(s)) {
+                       dev_err(dev, "Reset failed\n");
+                       return -EIO;
+               }
+       } else if (hisi_hba->ctrl) {
+               /* reset and disable clock*/
+               regmap_write(hisi_hba->ctrl, hisi_hba->ctrl_reset_reg,
+                               reset_val);
+               regmap_write(hisi_hba->ctrl, hisi_hba->ctrl_clock_ena_reg + 4,
+                               reset_val);
+               msleep(1);
+               regmap_read(hisi_hba->ctrl, hisi_hba->ctrl_reset_sts_reg, &val);
+               if (reset_val != (val & reset_val)) {
+                       dev_err(dev, "SAS reset fail.\n");
+                       return -EIO;
+               }
+
+               /* De-reset and enable clock*/
+               regmap_write(hisi_hba->ctrl, hisi_hba->ctrl_reset_reg + 4,
+                               reset_val);
+               regmap_write(hisi_hba->ctrl, hisi_hba->ctrl_clock_ena_reg,
+                               reset_val);
+               msleep(1);
+               regmap_read(hisi_hba->ctrl, hisi_hba->ctrl_reset_sts_reg,
+                               &val);
+               if (val & reset_val) {
+                       dev_err(dev, "SAS de-reset fail.\n");
+                       return -EIO;
+               }
+       } else
+               dev_warn(dev, "no reset method\n");
 
        return 0;
 }
@@ -752,13 +763,12 @@ static int reset_hw_v2_hw(struct hisi_hba *hisi_hba)
 static void init_reg_v2_hw(struct hisi_hba *hisi_hba)
 {
        struct device *dev = &hisi_hba->pdev->dev;
-       struct device_node *np = dev->of_node;
        int i;
 
        /* Global registers init */
 
        /* Deal with am-max-transmissions quirk */
-       if (of_get_property(np, "hip06-sas-v2-quirk-amt", NULL)) {
+       if (device_property_present(dev, "hip06-sas-v2-quirk-amt")) {
                hisi_sas_write32(hisi_hba, AM_CFG_MAX_TRANS, 0x2020);
                hisi_sas_write32(hisi_hba, AM_CFG_SINGLE_PORT_MAX_TRANS,
                                 0x2020);
@@ -2260,12 +2270,20 @@ static const struct of_device_id sas_v2_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, sas_v2_of_match);
 
+static const struct acpi_device_id sas_v2_acpi_match[] = {
+       { "HISI0162", 0 },
+       { }
+};
+
+MODULE_DEVICE_TABLE(acpi, sas_v2_acpi_match);
+
 static struct platform_driver hisi_sas_v2_driver = {
        .probe = hisi_sas_v2_probe,
        .remove = hisi_sas_v2_remove,
        .driver = {
                .name = DRV_NAME,
                .of_match_table = sas_v2_of_match,
+               .acpi_match_table = ACPI_PTR(sas_v2_acpi_match),
        },
 };