| From b0868a9b4606304a0a70e8f60e53a313776ef74f Mon Sep 17 00:00:00 2001 |
| From: Tomer Maimon <tmaimon77@gmail.com> |
| Date: Mon, 2 Oct 2023 23:06:10 +0300 |
| Subject: [PATCH] mmc: sdhci-npcm: Add NPCM SDHCI driver |
| |
| Add Nuvoton NPCM BMC sdhci-pltfm controller driver. |
| |
| Signed-off-by: Tomer Maimon <tmaimon77@gmail.com> |
| Acked-by: Adrian Hunter <adrian.hunter@intel.com> |
| Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> |
| Link: https://lore.kernel.org/r/20231002200610.129799-3-tmaimon77@gmail.com |
| Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> |
| (cherry picked from commit 0ebebb21c48408bfa96a6fb18aa1a5bb543e2312) |
| Patch Tracking Bug: b/310037171 |
| Upstream-Status: Accepted |
| Justification: Required for nuvoton BMCs |
| --- |
| drivers/mmc/host/Kconfig | 8 +++ |
| drivers/mmc/host/Makefile | 1 + |
| drivers/mmc/host/sdhci-npcm.c | 94 +++++++++++++++++++++++++++++++++++ |
| 3 files changed, 103 insertions(+) |
| create mode 100644 drivers/mmc/host/sdhci-npcm.c |
| |
| diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig |
| index 554e67103c1a..3999d4fddc73 100644 |
| --- a/drivers/mmc/host/Kconfig |
| +++ b/drivers/mmc/host/Kconfig |
| @@ -429,6 +429,14 @@ config MMC_SDHCI_IPROC |
| |
| If unsure, say N. |
| |
| +config MMC_SDHCI_NPCM |
| + tristate "Secure Digital Host Controller Interface support for NPCM" |
| + depends on ARCH_NPCM || COMPILE_TEST |
| + depends on MMC_SDHCI_PLTFM |
| + help |
| + This provides support for the SD/eMMC controller found in |
| + NPCM BMC family SoCs. |
| + |
| config MMC_MESON_GX |
| tristate "Amlogic S905/GX*/AXG SD/MMC Host Controller support" |
| depends on ARCH_MESON|| COMPILE_TEST |
| diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile |
| index a693fa3d3f1c..d0be4465f3ec 100644 |
| --- a/drivers/mmc/host/Makefile |
| +++ b/drivers/mmc/host/Makefile |
| @@ -89,6 +89,7 @@ obj-$(CONFIG_MMC_SDHCI_OF_DWCMSHC) += sdhci-of-dwcmshc.o |
| obj-$(CONFIG_MMC_SDHCI_OF_SPARX5) += sdhci-of-sparx5.o |
| obj-$(CONFIG_MMC_SDHCI_BCM_KONA) += sdhci-bcm-kona.o |
| obj-$(CONFIG_MMC_SDHCI_IPROC) += sdhci-iproc.o |
| +obj-$(CONFIG_MMC_SDHCI_NPCM) += sdhci-npcm.o |
| obj-$(CONFIG_MMC_SDHCI_MSM) += sdhci-msm.o |
| obj-$(CONFIG_MMC_SDHCI_ST) += sdhci-st.o |
| obj-$(CONFIG_MMC_SDHCI_MICROCHIP_PIC32) += sdhci-pic32.o |
| diff --git a/drivers/mmc/host/sdhci-npcm.c b/drivers/mmc/host/sdhci-npcm.c |
| new file mode 100644 |
| index 000000000000..5bf9d18f364e |
| --- /dev/null |
| +++ b/drivers/mmc/host/sdhci-npcm.c |
| @@ -0,0 +1,94 @@ |
| +// SPDX-License-Identifier: GPL-2.0+ |
| +/* |
| + * NPCM SDHC MMC host controller driver. |
| + * |
| + * Copyright (c) 2023 Nuvoton Technology corporation. |
| + */ |
| + |
| +#include <linux/clk.h> |
| +#include <linux/err.h> |
| +#include <linux/io.h> |
| +#include <linux/mmc/host.h> |
| +#include <linux/mmc/mmc.h> |
| +#include <linux/mod_devicetable.h> |
| +#include <linux/module.h> |
| +#include <linux/of.h> |
| + |
| +#include "sdhci-pltfm.h" |
| + |
| +static const struct sdhci_pltfm_data npcm7xx_sdhci_pdata = { |
| + .quirks = SDHCI_QUIRK_DELAY_AFTER_POWER, |
| + .quirks2 = SDHCI_QUIRK2_STOP_WITH_TC | |
| + SDHCI_QUIRK2_NO_1_8_V, |
| +}; |
| + |
| +static const struct sdhci_pltfm_data npcm8xx_sdhci_pdata = { |
| + .quirks = SDHCI_QUIRK_DELAY_AFTER_POWER, |
| + .quirks2 = SDHCI_QUIRK2_STOP_WITH_TC, |
| +}; |
| + |
| +static int npcm_sdhci_probe(struct platform_device *pdev) |
| +{ |
| + const struct sdhci_pltfm_data *data; |
| + struct sdhci_pltfm_host *pltfm_host; |
| + struct device *dev = &pdev->dev; |
| + struct sdhci_host *host; |
| + u32 caps; |
| + int ret; |
| + |
| + data = of_device_get_match_data(dev); |
| + if (!data) |
| + return -EINVAL; |
| + |
| + host = sdhci_pltfm_init(pdev, data, 0); |
| + if (IS_ERR(host)) |
| + return PTR_ERR(host); |
| + |
| + pltfm_host = sdhci_priv(host); |
| + |
| + pltfm_host->clk = devm_clk_get_optional_enabled(dev, NULL); |
| + if (IS_ERR(pltfm_host->clk)) { |
| + ret = PTR_ERR(pltfm_host->clk); |
| + goto err_sdhci; |
| + } |
| + |
| + caps = sdhci_readl(host, SDHCI_CAPABILITIES); |
| + if (caps & SDHCI_CAN_DO_8BIT) |
| + host->mmc->caps |= MMC_CAP_8_BIT_DATA; |
| + |
| + ret = mmc_of_parse(host->mmc); |
| + if (ret) |
| + goto err_sdhci; |
| + |
| + ret = sdhci_add_host(host); |
| + if (ret) |
| + goto err_sdhci; |
| + |
| + return 0; |
| + |
| +err_sdhci: |
| + sdhci_pltfm_free(pdev); |
| + return ret; |
| +} |
| + |
| +static const struct of_device_id npcm_sdhci_of_match[] = { |
| + { .compatible = "nuvoton,npcm750-sdhci", .data = &npcm7xx_sdhci_pdata }, |
| + { .compatible = "nuvoton,npcm845-sdhci", .data = &npcm8xx_sdhci_pdata }, |
| + { } |
| +}; |
| +MODULE_DEVICE_TABLE(of, npcm_sdhci_of_match); |
| + |
| +static struct platform_driver npcm_sdhci_driver = { |
| + .driver = { |
| + .name = "npcm-sdhci", |
| + .of_match_table = npcm_sdhci_of_match, |
| + .pm = &sdhci_pltfm_pmops, |
| + }, |
| + .probe = npcm_sdhci_probe, |
| + .remove_new = sdhci_pltfm_remove, |
| +}; |
| +module_platform_driver(npcm_sdhci_driver); |
| + |
| +MODULE_DESCRIPTION("NPCM Secure Digital Host Controller Interface driver"); |
| +MODULE_AUTHOR("Tomer Maimon <tomer.maimon@nuvoton.com>"); |
| +MODULE_LICENSE("GPL"); |
| -- |
| 2.42.0.869.gea05f2083d-goog |
| |