diff --git a/Documentation/devicetree/bindings/ata/brcm,sata-brcm.txt b/Documentation/devicetree/bindings/ata/brcm,sata-brcm.txt index 7713a413c6a7..b9ae4ce4a0a0 100644 --- a/Documentation/devicetree/bindings/ata/brcm,sata-brcm.txt +++ b/Documentation/devicetree/bindings/ata/brcm,sata-brcm.txt @@ -5,6 +5,7 @@ Each SATA controller should have its own node. Required properties: - compatible : should be one or more of + "brcm,bcm7216-ahci" "brcm,bcm7425-ahci" "brcm,bcm7445-ahci" "brcm,bcm-nsp-ahci" @@ -14,6 +15,12 @@ Required properties: - reg-names : "ahci" and "top-ctrl" - interrupts : interrupt mapping for SATA IRQ +Optional properties: + +- reset: for "brcm,bcm7216-ahci" must be a valid reset phandle + pointing to the RESCAL reset controller provider node. +- reset-names: for "brcm,bcm7216-ahci", must be "rescal". + Also see ahci-platform.txt. Example: diff --git a/drivers/ata/acard-ahci.c b/drivers/ata/acard-ahci.c index 46dc54d18f0b..2a04e8abd397 100644 --- a/drivers/ata/acard-ahci.c +++ b/drivers/ata/acard-ahci.c @@ -218,7 +218,6 @@ static enum ata_completion_errors acard_ahci_qc_prep(struct ata_queued_cmd *qc) void *cmd_tbl; u32 opts; const u32 cmd_fis_len = 5; /* five dwords */ - unsigned int n_elem; /* * Fill in command table information. First, the header, @@ -232,9 +231,8 @@ static enum ata_completion_errors acard_ahci_qc_prep(struct ata_queued_cmd *qc) memcpy(cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, qc->dev->cdb_len); } - n_elem = 0; if (qc->flags & ATA_QCFLAG_DMAMAP) - n_elem = acard_ahci_fill_sg(qc, cmd_tbl); + acard_ahci_fill_sg(qc, cmd_tbl); /* * Fill in command slot information. diff --git a/drivers/ata/ahci_brcm.c b/drivers/ata/ahci_brcm.c index 66a570d0da83..6853dbb4131d 100644 --- a/drivers/ata/ahci_brcm.c +++ b/drivers/ata/ahci_brcm.c @@ -73,6 +73,7 @@ enum brcm_ahci_version { BRCM_SATA_BCM7425 = 1, BRCM_SATA_BCM7445, BRCM_SATA_NSP, + BRCM_SATA_BCM7216, }; enum brcm_ahci_quirks { @@ -337,24 +338,39 @@ static const struct ata_port_info ahci_brcm_port_info = { .port_ops = &ahci_brcm_platform_ops, }; -#ifdef CONFIG_PM_SLEEP static int brcm_ahci_suspend(struct device *dev) { struct ata_host *host = dev_get_drvdata(dev); struct ahci_host_priv *hpriv = host->private_data; struct brcm_ahci_priv *priv = hpriv->plat_data; + int ret; brcm_sata_phys_disable(priv); - return ahci_platform_suspend(dev); + if (IS_ENABLED(CONFIG_PM_SLEEP)) + ret = ahci_platform_suspend(dev); + else + ret = 0; + + if (priv->version != BRCM_SATA_BCM7216) + reset_control_assert(priv->rcdev); + + return ret; } -static int brcm_ahci_resume(struct device *dev) +static int __maybe_unused brcm_ahci_resume(struct device *dev) { struct ata_host *host = dev_get_drvdata(dev); struct ahci_host_priv *hpriv = host->private_data; struct brcm_ahci_priv *priv = hpriv->plat_data; - int ret; + int ret = 0; + + if (priv->version == BRCM_SATA_BCM7216) + ret = reset_control_reset(priv->rcdev); + else + ret = reset_control_deassert(priv->rcdev); + if (ret) + return ret; /* Make sure clocks are turned on before re-configuration */ ret = ahci_platform_enable_clks(hpriv); @@ -393,7 +409,6 @@ out_disable_phys: ahci_platform_disable_clks(hpriv); return ret; } -#endif static struct scsi_host_template ahci_platform_sht = { AHCI_SHT(DRV_NAME), @@ -404,6 +419,7 @@ static const struct of_device_id ahci_of_match[] = { {.compatible = "brcm,bcm7445-ahci", .data = (void *)BRCM_SATA_BCM7445}, {.compatible = "brcm,bcm63138-ahci", .data = (void *)BRCM_SATA_BCM7445}, {.compatible = "brcm,bcm-nsp-ahci", .data = (void *)BRCM_SATA_NSP}, + {.compatible = "brcm,bcm7216-ahci", .data = (void *)BRCM_SATA_BCM7216}, {}, }; MODULE_DEVICE_TABLE(of, ahci_of_match); @@ -412,6 +428,7 @@ static int brcm_ahci_probe(struct platform_device *pdev) { const struct of_device_id *of_id; struct device *dev = &pdev->dev; + const char *reset_name = NULL; struct brcm_ahci_priv *priv; struct ahci_host_priv *hpriv; struct resource *res; @@ -433,16 +450,19 @@ static int brcm_ahci_probe(struct platform_device *pdev) if (IS_ERR(priv->top_ctrl)) return PTR_ERR(priv->top_ctrl); - /* Reset is optional depending on platform */ - priv->rcdev = devm_reset_control_get(&pdev->dev, "ahci"); - if (!IS_ERR_OR_NULL(priv->rcdev)) - reset_control_deassert(priv->rcdev); + /* Reset is optional depending on platform and named differently */ + if (priv->version == BRCM_SATA_BCM7216) + reset_name = "rescal"; + else + reset_name = "ahci"; + + priv->rcdev = devm_reset_control_get_optional(&pdev->dev, reset_name); + if (IS_ERR(priv->rcdev)) + return PTR_ERR(priv->rcdev); hpriv = ahci_platform_get_resources(pdev, 0); - if (IS_ERR(hpriv)) { - ret = PTR_ERR(hpriv); - goto out_reset; - } + if (IS_ERR(hpriv)) + return PTR_ERR(hpriv); hpriv->plat_data = priv; hpriv->flags = AHCI_HFLAG_WAKE_BEFORE_STOP | AHCI_HFLAG_NO_WRITE_TO_RO; @@ -459,6 +479,13 @@ static int brcm_ahci_probe(struct platform_device *pdev) break; } + if (priv->version == BRCM_SATA_BCM7216) + ret = reset_control_reset(priv->rcdev); + else + ret = reset_control_deassert(priv->rcdev); + if (ret) + return ret; + ret = ahci_platform_enable_clks(hpriv); if (ret) goto out_reset; @@ -500,7 +527,7 @@ out_disable_phys: out_disable_clks: ahci_platform_disable_clks(hpriv); out_reset: - if (!IS_ERR_OR_NULL(priv->rcdev)) + if (priv->version != BRCM_SATA_BCM7216) reset_control_assert(priv->rcdev); return ret; } @@ -521,11 +548,26 @@ static int brcm_ahci_remove(struct platform_device *pdev) return 0; } +static void brcm_ahci_shutdown(struct platform_device *pdev) +{ + int ret; + + /* All resources releasing happens via devres, but our device, unlike a + * proper remove is not disappearing, therefore using + * brcm_ahci_suspend() here which does explicit power management is + * appropriate. + */ + ret = brcm_ahci_suspend(&pdev->dev); + if (ret) + dev_err(&pdev->dev, "failed to shutdown\n"); +} + static SIMPLE_DEV_PM_OPS(ahci_brcm_pm_ops, brcm_ahci_suspend, brcm_ahci_resume); static struct platform_driver brcm_ahci_driver = { .probe = brcm_ahci_probe, .remove = brcm_ahci_remove, + .shutdown = brcm_ahci_shutdown, .driver = { .name = DRV_NAME, .of_match_table = ahci_of_match, diff --git a/drivers/ata/pata_macio.c b/drivers/ata/pata_macio.c index 1bfd0154dad5..e47a28271f5b 100644 --- a/drivers/ata/pata_macio.c +++ b/drivers/ata/pata_macio.c @@ -979,7 +979,7 @@ static void pata_macio_invariants(struct pata_macio_priv *priv) priv->aapl_bus_id = bidp ? *bidp : 0; /* Fixup missing Apple bus ID in case of media-bay */ - if (priv->mediabay && bidp == 0) + if (priv->mediabay && !bidp) priv->aapl_bus_id = 1; }