hisi_sas: Scan device tree
authorJohn Garry <john.garry@huawei.com>
Tue, 17 Nov 2015 16:50:32 +0000 (00:50 +0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Thu, 26 Nov 2015 03:12:52 +0000 (22:12 -0500)
Scan the device tree for all properties. Also do this:

- do ioremap for SAS registers
- allocate memory for interrupt names

Signed-off-by: John Garry <john.garry@huawei.com>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/hisi_sas/hisi_sas.h
drivers/scsi/hisi_sas/hisi_sas_main.c

index 6f57fd16e9375a9991053800e65aefec8f67c36a..87f4b61028ebf3f2a34ff32b162a98ea79ae5a6a 100644 (file)
@@ -28,6 +28,8 @@
 #define HISI_SAS_MAX_DEVICES HISI_SAS_MAX_ITCT_ENTRIES
 #define HISI_SAS_COMMAND_ENTRIES 8192
 
+#define HISI_SAS_NAME_LEN 32
+
 struct hisi_sas_phy {
        struct asd_sas_phy      sas_phy;
 };
@@ -44,6 +46,11 @@ struct hisi_hba {
        struct sas_ha_struct *p;
 
        struct platform_device *pdev;
+       void __iomem *regs;
+       struct regmap *ctrl;
+       u32 ctrl_reset_reg;
+       u32 ctrl_reset_sts_reg;
+       u32 ctrl_clock_ena_reg;
        u8 sas_addr[SAS_ADDR_SIZE];
 
        int n_phy;
@@ -53,6 +60,9 @@ struct hisi_hba {
        struct Scsi_Host *shost;
        struct hisi_sas_phy phy[HISI_SAS_MAX_PHYS];
        struct hisi_sas_port port[HISI_SAS_MAX_PHYS];
+
+       int     queue_count;
+       char    *int_names;
        const struct hisi_sas_hw *hw;   /* Low level hw interface */
 };
 
index 4fd000e565c26a7e9cd56701c0a0a20d3ada1ecc..4fc5a6c6d0ce5517e24b00d63d7c30e181950b89 100644 (file)
@@ -39,9 +39,13 @@ static struct sas_domain_function_template hisi_sas_transport_ops = {
 static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev,
                                              const struct hisi_sas_hw *hw)
 {
+       struct resource *res;
        struct Scsi_Host *shost;
        struct hisi_hba *hisi_hba;
        struct device *dev = &pdev->dev;
+       struct device_node *np = pdev->dev.of_node;
+       struct property *sas_addr_prop;
+       int num;
 
        shost = scsi_host_alloc(&hisi_sas_sht, sizeof(*hisi_hba));
        if (!shost)
@@ -53,6 +57,46 @@ static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev,
        hisi_hba->shost = shost;
        SHOST_TO_SAS_HA(shost) = &hisi_hba->sha;
 
+       sas_addr_prop = of_find_property(np, "sas-addr", NULL);
+       if (!sas_addr_prop || (sas_addr_prop->length != SAS_ADDR_SIZE))
+               goto err_out;
+       memcpy(hisi_hba->sas_addr, sas_addr_prop->value, SAS_ADDR_SIZE);
+
+       if (of_property_read_u32(np, "ctrl-reset-reg",
+                                &hisi_hba->ctrl_reset_reg))
+               goto err_out;
+
+       if (of_property_read_u32(np, "ctrl-reset-sts-reg",
+                                &hisi_hba->ctrl_reset_sts_reg))
+               goto err_out;
+
+       if (of_property_read_u32(np, "ctrl-clock-ena-reg",
+                                &hisi_hba->ctrl_clock_ena_reg))
+               goto err_out;
+
+       if (of_property_read_u32(np, "phy-count", &hisi_hba->n_phy))
+               goto err_out;
+
+       if (of_property_read_u32(np, "queue-count", &hisi_hba->queue_count))
+               goto err_out;
+
+       num = of_irq_count(np);
+       hisi_hba->int_names = devm_kcalloc(dev, num,
+                                          HISI_SAS_NAME_LEN,
+                                          GFP_KERNEL);
+       if (!hisi_hba->int_names)
+               goto err_out;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       hisi_hba->regs = devm_ioremap_resource(dev, res);
+       if (IS_ERR(hisi_hba->regs))
+               goto err_out;
+
+       hisi_hba->ctrl = syscon_regmap_lookup_by_phandle(
+                               np, "hisilicon,sas-syscon");
+       if (IS_ERR(hisi_hba->ctrl))
+               goto err_out;
+
        return shost;
 err_out:
        dev_err(dev, "shost alloc failed\n");
@@ -79,7 +123,6 @@ int hisi_sas_probe(struct platform_device *pdev,
        sha = SHOST_TO_SAS_HA(shost);
        hisi_hba = shost_priv(shost);
        platform_set_drvdata(pdev, sha);
-       hisi_hba->n_phy = HISI_SAS_MAX_PHYS;
        phy_nr = port_nr = hisi_hba->n_phy;
 
        arr_phy = devm_kcalloc(dev, phy_nr, sizeof(void *), GFP_KERNEL);