aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/hisi_sas/hisi_sas_main.c
diff options
context:
space:
mode:
authorJohn Garry <john.garry@huawei.com>2017-06-14 23:33:18 +0800
committerMartin K. Petersen <martin.petersen@oracle.com>2017-06-19 21:31:25 -0400
commit0fa24c19d844945b6edf981ff425c93f20085f10 (patch)
treea2510e31aedf7c1f3f0141c38b9bc7f5c5bf06d9 /drivers/scsi/hisi_sas/hisi_sas_main.c
parentscsi: hisi_sas: add pci_dev in hisi_hba struct (diff)
downloadlinux-dev-0fa24c19d844945b6edf981ff425c93f20085f10.tar.xz
linux-dev-0fa24c19d844945b6edf981ff425c93f20085f10.zip
scsi: hisi_sas: create hisi_sas_get_fw_info()
Move the functionality to retrieve the fw info into a dedicated device type-agnostic function, hisi_sas_get_fw_info(). The reasoning is that this function will be required for future pci-based platforms. Also add some debug logs for failure. Signed-off-by: John Garry <john.garry@huawei.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/hisi_sas/hisi_sas_main.c')
-rw-r--r--drivers/scsi/hisi_sas/hisi_sas_main.c107
1 files changed, 70 insertions, 37 deletions
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
index 139df4509a41..8a2af906e1ad 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -1729,66 +1729,99 @@ static void hisi_sas_rst_work_handler(struct work_struct *work)
hisi_sas_controller_reset(hisi_hba);
}
-static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev,
- const struct hisi_sas_hw *hw)
+int hisi_sas_get_fw_info(struct hisi_hba *hisi_hba)
{
- 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 device *dev = hisi_hba->dev;
+ struct platform_device *pdev = hisi_hba->platform_dev;
+ struct device_node *np = pdev ? pdev->dev.of_node : NULL;
struct clk *refclk;
- shost = scsi_host_alloc(&hisi_sas_sht, sizeof(*hisi_hba));
- if (!shost) {
- dev_err(dev, "scsi host alloc failed\n");
- return NULL;
- }
- hisi_hba = shost_priv(shost);
-
- INIT_WORK(&hisi_hba->rst_work, hisi_sas_rst_work_handler);
- hisi_hba->hw = hw;
- hisi_hba->platform_dev = pdev;
- hisi_hba->dev = dev;
- hisi_hba->shost = shost;
- SHOST_TO_SAS_HA(shost) = &hisi_hba->sha;
-
- init_timer(&hisi_hba->timer);
-
if (device_property_read_u8_array(dev, "sas-addr", hisi_hba->sas_addr,
- SAS_ADDR_SIZE))
- goto err_out;
+ SAS_ADDR_SIZE)) {
+ dev_err(dev, "could not get property sas-addr\n");
+ return -ENOENT;
+ }
if (np) {
+ /*
+ * These properties are only required for platform device-based
+ * controller with DT firmware.
+ */
hisi_hba->ctrl = syscon_regmap_lookup_by_phandle(np,
"hisilicon,sas-syscon");
- if (IS_ERR(hisi_hba->ctrl))
- goto err_out;
+ if (IS_ERR(hisi_hba->ctrl)) {
+ dev_err(dev, "could not get syscon\n");
+ return -ENOENT;
+ }
if (device_property_read_u32(dev, "ctrl-reset-reg",
- &hisi_hba->ctrl_reset_reg))
- goto err_out;
+ &hisi_hba->ctrl_reset_reg)) {
+ dev_err(dev,
+ "could not get property ctrl-reset-reg\n");
+ return -ENOENT;
+ }
if (device_property_read_u32(dev, "ctrl-reset-sts-reg",
- &hisi_hba->ctrl_reset_sts_reg))
- goto err_out;
+ &hisi_hba->ctrl_reset_sts_reg)) {
+ dev_err(dev,
+ "could not get property ctrl-reset-sts-reg\n");
+ return -ENOENT;
+ }
if (device_property_read_u32(dev, "ctrl-clock-ena-reg",
- &hisi_hba->ctrl_clock_ena_reg))
- goto err_out;
+ &hisi_hba->ctrl_clock_ena_reg)) {
+ dev_err(dev,
+ "could not get property ctrl-clock-ena-reg\n");
+ return -ENOENT;
+ }
}
- refclk = devm_clk_get(&pdev->dev, NULL);
+ refclk = devm_clk_get(dev, NULL);
if (IS_ERR(refclk))
dev_dbg(dev, "no ref clk property\n");
else
hisi_hba->refclk_frequency_mhz = clk_get_rate(refclk) / 1000000;
- if (device_property_read_u32(dev, "phy-count", &hisi_hba->n_phy))
- goto err_out;
+ if (device_property_read_u32(dev, "phy-count", &hisi_hba->n_phy)) {
+ dev_err(dev, "could not get property phy-count\n");
+ return -ENOENT;
+ }
if (device_property_read_u32(dev, "queue-count",
- &hisi_hba->queue_count))
+ &hisi_hba->queue_count)) {
+ dev_err(dev, "could not get property queue-count\n");
+ return -ENOENT;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(hisi_sas_get_fw_info);
+
+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;
+
+ shost = scsi_host_alloc(&hisi_sas_sht, sizeof(*hisi_hba));
+ if (!shost) {
+ dev_err(dev, "scsi host alloc failed\n");
+ return NULL;
+ }
+ hisi_hba = shost_priv(shost);
+
+ INIT_WORK(&hisi_hba->rst_work, hisi_sas_rst_work_handler);
+ hisi_hba->hw = hw;
+ hisi_hba->dev = dev;
+ hisi_hba->platform_dev = pdev;
+ hisi_hba->shost = shost;
+ SHOST_TO_SAS_HA(shost) = &hisi_hba->sha;
+
+ init_timer(&hisi_hba->timer);
+
+ if (hisi_sas_get_fw_info(hisi_hba) < 0)
goto err_out;
if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)) &&