mmc: sdhci_f_sdh30: add ACPI support

The Fujitsu SDH30 SDHCI controller may be described as a SCX0002 ACPI
device on ACPI platforms incorporating the Socionext SynQuacer SoC.

Given that mmc_of_parse() has already been made ACPI/DT agnostic,
making the SDH30 driver ACPI capable is actually rather simple:
all we need to do is make the call to sdhci_get_of_property() [which
does not set any properties we care about] and the clock handling
dependent on whether we are dealing with a DT device, and exposing
the ACPI id via the platform_driver struct and the module metadata.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
This commit is contained in:
Ard Biesheuvel 2018-01-08 15:44:19 +00:00 committed by Ulf Hansson
parent 3602785b34
commit 90e1d8ccdb
2 changed files with 37 additions and 21 deletions

View File

@ -321,7 +321,7 @@ config MMC_SDHCI_BCM_KONA
config MMC_SDHCI_F_SDH30
tristate "SDHCI support for Fujitsu Semiconductor F_SDH30"
depends on MMC_SDHCI_PLTFM
depends on OF
depends on OF || ACPI
help
This selects the Secure Digital Host Controller Interface (SDHCI)
Needed by some Fujitsu SoC for MMC / SD / SDIO support.

View File

@ -10,9 +10,11 @@
* the Free Software Foundation, version 2 of the License.
*/
#include <linux/acpi.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/property.h>
#include <linux/clk.h>
@ -146,7 +148,6 @@ static int sdhci_f_sdh30_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, host);
sdhci_get_of_property(pdev);
host->hw_name = "f_sdh30";
host->ops = &sdhci_f_sdh30_ops;
host->irq = irq;
@ -158,26 +159,30 @@ static int sdhci_f_sdh30_probe(struct platform_device *pdev)
goto err;
}
priv->clk_iface = devm_clk_get(&pdev->dev, "iface");
if (IS_ERR(priv->clk_iface)) {
ret = PTR_ERR(priv->clk_iface);
goto err;
if (dev_of_node(dev)) {
sdhci_get_of_property(pdev);
priv->clk_iface = devm_clk_get(&pdev->dev, "iface");
if (IS_ERR(priv->clk_iface)) {
ret = PTR_ERR(priv->clk_iface);
goto err;
}
ret = clk_prepare_enable(priv->clk_iface);
if (ret)
goto err;
priv->clk = devm_clk_get(&pdev->dev, "core");
if (IS_ERR(priv->clk)) {
ret = PTR_ERR(priv->clk);
goto err_clk;
}
ret = clk_prepare_enable(priv->clk);
if (ret)
goto err_clk;
}
ret = clk_prepare_enable(priv->clk_iface);
if (ret)
goto err;
priv->clk = devm_clk_get(&pdev->dev, "core");
if (IS_ERR(priv->clk)) {
ret = PTR_ERR(priv->clk);
goto err_clk;
}
ret = clk_prepare_enable(priv->clk);
if (ret)
goto err_clk;
/* init vendor specific regs */
ctrl = sdhci_readw(host, F_SDH30_AHB_CONFIG);
ctrl |= F_SDH30_SIN | F_SDH30_AHB_INCR_16 | F_SDH30_AHB_INCR_8 |
@ -226,16 +231,27 @@ static int sdhci_f_sdh30_remove(struct platform_device *pdev)
return 0;
}
#ifdef CONFIG_OF
static const struct of_device_id f_sdh30_dt_ids[] = {
{ .compatible = "fujitsu,mb86s70-sdhci-3.0" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, f_sdh30_dt_ids);
#endif
#ifdef CONFIG_ACPI
static const struct acpi_device_id f_sdh30_acpi_ids[] = {
{ "SCX0002" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(acpi, f_sdh30_acpi_ids);
#endif
static struct platform_driver sdhci_f_sdh30_driver = {
.driver = {
.name = "f_sdh30",
.of_match_table = f_sdh30_dt_ids,
.of_match_table = of_match_ptr(f_sdh30_dt_ids),
.acpi_match_table = ACPI_PTR(f_sdh30_acpi_ids),
.pm = &sdhci_pltfm_pmops,
},
.probe = sdhci_f_sdh30_probe,