From: Joshua Henderson <joshua.henderson@microchip.com>
To: <linux-kernel@vger.kernel.org>, Ulf Hansson <ulf.hansson@linaro.org>
Cc: <linux-mips@linux-mips.org>, <ralf@linux-mips.org>,
Andrei Pistirica <andrei.pistirica@microchip.com>,
Jean Delvare <jdelvare@suse.de>,
Geert Uytterhoeven <geert@linux-m68k.org>,
Corneliu Doban <cdoban@broadcom.com>,
Haojian Zhuang <haojian.zhuang@gmail.com>,
Luis de Bethencourt <luisbg@osg.samsung.com>,
Weijun Yang <Weijun.Yang@csr.com>,
Lokesh Vutla <lokeshvutla@ti.com>,
Scott Branden <sbranden@broadcom.com>,
Vincent Yang <vincent.yang.fujitsu@gmail.com>,
Chaotian Jing <chaotian.jing@mediatek.com>,
"ludovic.desroches@atmel.com" <ludovic.desroches@atmel.com>,
Shawn Lin <shawn.lin@rock-chips.com>,
Stephen Boyd <sboyd@codeaurora.org>,
yangbo lu <yangbo.lu@freescale.com>,
Kevin Hao <haokexin@gmail.com>,
Ben Hutchings <ben@decadent.org.uk>,
Andy Green <andy.green@linaro.org>, <linux-mmc@vger.kernel.org>
Subject: Re: [PATCH v5 12/14] mmc: sdhci-pic32: Add PIC32 SDHCI host controller driver
Date: Tue, 26 Jan 2016 10:04:45 -0700 [thread overview]
Message-ID: <56A7A72D.6010007@microchip.com> (raw)
In-Reply-To: <1452734299-460-13-git-send-email-joshua.henderson@microchip.com>
Hi Ulf,
Ping! Need an ack for this or pull it upstream.
On 01/13/2016 06:15 PM, Joshua Henderson wrote:
> From: Andrei Pistirica <andrei.pistirica@microchip.com>
>
> This driver supports the SDHCI host controller found on a PIC32.
>
> Signed-off-by: Andrei Pistirica <andrei.pistirica@microchip.com>
> Signed-off-by: Joshua Henderson <joshua.henderson@microchip.com>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> ---
> Changes since v4: None
> Changes since v3: None
> Changes since v2:
> - Use 'sdhci_pltfm_*' instead of 'sdhci_*_host' and other cleanup
> Changes since v1:
> - Be consistent and use only "SDHCI" when referring to SD host
> controller
> - Remove unnecessary PIC32 sdhci_ops min clock function.
> - Drop usage of piomode and no-1-8-v DT properties
> - Formatting
> - Fix use of devm_iounmap
> - Address code comment
> ---
> drivers/mmc/host/Kconfig | 11 ++
> drivers/mmc/host/Makefile | 1 +
> drivers/mmc/host/sdhci-pic32.c | 257 ++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 269 insertions(+)
> create mode 100644 drivers/mmc/host/sdhci-pic32.c
>
> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> index 1dee533..c6a8916 100644
> --- a/drivers/mmc/host/Kconfig
> +++ b/drivers/mmc/host/Kconfig
> @@ -785,3 +785,14 @@ config MMC_MTK
> If you have a machine with a integrated SD/MMC card reader, say Y or M here.
> This is needed if support for any SD/SDIO/MMC devices is required.
> If unsure, say N.
> +
> +config MMC_SDHCI_MICROCHIP_PIC32
> + tristate "Microchip PIC32MZDA SDHCI support"
> + depends on MMC_SDHCI && PIC32MZDA && MMC_SDHCI_PLTFM
> + help
> + This selects the Secure Digital Host Controller Interface (SDHCI)
> + for PIC32MZDA platform.
> +
> + If you have a controller with this interface, say Y or M here.
> +
> + If unsure, say N.
> diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
> index 3595f83..af918d2 100644
> --- a/drivers/mmc/host/Makefile
> +++ b/drivers/mmc/host/Makefile
> @@ -75,6 +75,7 @@ obj-$(CONFIG_MMC_SDHCI_BCM2835) += sdhci-bcm2835.o
> obj-$(CONFIG_MMC_SDHCI_IPROC) += sdhci-iproc.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
>
> ifeq ($(CONFIG_CB710_DEBUG),y)
> CFLAGS-cb710-mmc += -DDEBUG
> diff --git a/drivers/mmc/host/sdhci-pic32.c b/drivers/mmc/host/sdhci-pic32.c
> new file mode 100644
> index 0000000..059df70
> --- /dev/null
> +++ b/drivers/mmc/host/sdhci-pic32.c
> @@ -0,0 +1,257 @@
> +/*
> + * Support of SDHCI platform devices for Microchip PIC32.
> + *
> + * Copyright (C) 2015 Microchip
> + * Andrei Pistirica, Paul Thacker
> + *
> + * Inspired by sdhci-pltfm.c
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/highmem.h>
> +#include <linux/module.h>
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm.h>
> +#include <linux/slab.h>
> +#include <linux/mmc/host.h>
> +#include <linux/io.h>
> +#include "sdhci.h"
> +#include "sdhci-pltfm.h"
> +#include <linux/platform_data/sdhci-pic32.h>
> +
> +#define SDH_SHARED_BUS_CTRL 0x000000E0
> +#define SDH_SHARED_BUS_NR_CLK_PINS_MASK 0x7
> +#define SDH_SHARED_BUS_NR_IRQ_PINS_MASK 0x30
> +#define SDH_SHARED_BUS_CLK_PINS 0x10
> +#define SDH_SHARED_BUS_IRQ_PINS 0x14
> +#define SDH_CAPS_SDH_SLOT_TYPE_MASK 0xC0000000
> +#define SDH_SLOT_TYPE_REMOVABLE 0x0
> +#define SDH_SLOT_TYPE_EMBEDDED 0x1
> +#define SDH_SLOT_TYPE_SHARED_BUS 0x2
> +#define SDHCI_CTRL_CDSSEL 0x80
> +#define SDHCI_CTRL_CDTLVL 0x40
> +
> +#define ADMA_FIFO_RD_THSHLD 512
> +#define ADMA_FIFO_WR_THSHLD 512
> +
> +struct pic32_sdhci_priv {
> + struct platform_device *pdev;
> + struct clk *sys_clk;
> + struct clk *base_clk;
> +};
> +
> +static unsigned int pic32_sdhci_get_max_clock(struct sdhci_host *host)
> +{
> + struct pic32_sdhci_priv *sdhci_pdata = sdhci_priv(host);
> +
> + return clk_get_rate(sdhci_pdata->base_clk);
> +}
> +
> +static void pic32_sdhci_set_bus_width(struct sdhci_host *host, int width)
> +{
> + u8 ctrl;
> +
> + ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
> + if (width == MMC_BUS_WIDTH_8) {
> + ctrl &= ~SDHCI_CTRL_4BITBUS;
> + if (host->version >= SDHCI_SPEC_300)
> + ctrl |= SDHCI_CTRL_8BITBUS;
> + } else {
> + if (host->version >= SDHCI_SPEC_300)
> + ctrl &= ~SDHCI_CTRL_8BITBUS;
> + if (width == MMC_BUS_WIDTH_4)
> + ctrl |= SDHCI_CTRL_4BITBUS;
> + else
> + ctrl &= ~SDHCI_CTRL_4BITBUS;
> + }
> +
> + /* CD select and test bits must be set for errata workaround. */
> + ctrl &= ~SDHCI_CTRL_CDTLVL;
> + ctrl |= SDHCI_CTRL_CDSSEL;
> + sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
> +}
> +
> +static unsigned int pic32_sdhci_get_ro(struct sdhci_host *host)
> +{
> + /*
> + * The SDHCI_WRITE_PROTECT bit is unstable on current hardware so we
> + * can't depend on its value in any way.
> + */
> + return 0;
> +}
> +
> +static const struct sdhci_ops pic32_sdhci_ops = {
> + .get_max_clock = pic32_sdhci_get_max_clock,
> + .set_clock = sdhci_set_clock,
> + .set_bus_width = pic32_sdhci_set_bus_width,
> + .reset = sdhci_reset,
> + .set_uhs_signaling = sdhci_set_uhs_signaling,
> + .get_ro = pic32_sdhci_get_ro,
> +};
> +
> +static struct sdhci_pltfm_data sdhci_pic32_pdata = {
> + .ops = &pic32_sdhci_ops,
> + .quirks = SDHCI_QUIRK_NO_HISPD_BIT,
> + .quirks2 = SDHCI_QUIRK2_NO_1_8_V,
> +};
> +
> +static void pic32_sdhci_shared_bus(struct platform_device *pdev)
> +{
> + struct sdhci_host *host = platform_get_drvdata(pdev);
> + u32 bus = readl(host->ioaddr + SDH_SHARED_BUS_CTRL);
> + u32 clk_pins = (bus & SDH_SHARED_BUS_NR_CLK_PINS_MASK) >> 0;
> + u32 irq_pins = (bus & SDH_SHARED_BUS_NR_IRQ_PINS_MASK) >> 4;
> +
> + /* select first clock */
> + if (clk_pins & 1)
> + bus |= (1 << SDH_SHARED_BUS_CLK_PINS);
> +
> + /* select first interrupt */
> + if (irq_pins & 1)
> + bus |= (1 << SDH_SHARED_BUS_IRQ_PINS);
> +
> + writel(bus, host->ioaddr + SDH_SHARED_BUS_CTRL);
> +}
> +
> +static int pic32_sdhci_probe_platform(struct platform_device *pdev,
> + struct pic32_sdhci_priv *pdata)
> +{
> + int ret = 0;
> + u32 caps_slot_type;
> + struct sdhci_host *host = platform_get_drvdata(pdev);
> +
> + /* Check card slot connected on shared bus. */
> + host->caps = readl(host->ioaddr + SDHCI_CAPABILITIES);
> + caps_slot_type = (host->caps & SDH_CAPS_SDH_SLOT_TYPE_MASK) >> 30;
> + if (caps_slot_type == SDH_SLOT_TYPE_SHARED_BUS)
> + pic32_sdhci_shared_bus(pdev);
> +
> + return ret;
> +}
> +
> +static int pic32_sdhci_probe(struct platform_device *pdev)
> +{
> + struct sdhci_host *host;
> + struct sdhci_pltfm_host *pltfm_host;
> + struct pic32_sdhci_priv *sdhci_pdata;
> + struct pic32_sdhci_platform_data *plat_data;
> + int ret;
> +
> + host = sdhci_pltfm_init(pdev, &sdhci_pic32_pdata,
> + sizeof(struct pic32_sdhci_priv));
> + if (IS_ERR(host)) {
> + ret = PTR_ERR(host);
> + goto err;
> + }
> +
> + pltfm_host = sdhci_priv(host);
> + sdhci_pdata = sdhci_pltfm_priv(pltfm_host);
> +
> + plat_data = pdev->dev.platform_data;
> + if (plat_data && plat_data->setup_dma) {
> + ret = plat_data->setup_dma(ADMA_FIFO_RD_THSHLD,
> + ADMA_FIFO_WR_THSHLD);
> + if (ret)
> + goto err_host;
> + }
> +
> + sdhci_pdata->sys_clk = devm_clk_get(&pdev->dev, "sys_clk");
> + if (IS_ERR(sdhci_pdata->sys_clk)) {
> + ret = PTR_ERR(sdhci_pdata->sys_clk);
> + dev_err(&pdev->dev, "Error getting clock\n");
> + goto err_host;
> + }
> +
> + ret = clk_prepare_enable(sdhci_pdata->sys_clk);
> + if (ret) {
> + dev_err(&pdev->dev, "Error enabling clock\n");
> + goto err_host;
> + }
> +
> + sdhci_pdata->base_clk = devm_clk_get(&pdev->dev, "base_clk");
> + if (IS_ERR(sdhci_pdata->base_clk)) {
> + ret = PTR_ERR(sdhci_pdata->base_clk);
> + dev_err(&pdev->dev, "Error getting clock\n");
> + goto err_sys_clk;
> + }
> +
> + ret = clk_prepare_enable(sdhci_pdata->base_clk);
> + if (ret) {
> + dev_err(&pdev->dev, "Error enabling clock\n");
> + goto err_base_clk;
> + }
> +
> + ret = mmc_of_parse(host->mmc);
> + if (ret)
> + goto err_base_clk;
> +
> + ret = pic32_sdhci_probe_platform(pdev, sdhci_pdata);
> + if (ret) {
> + dev_err(&pdev->dev, "failed to probe platform!\n");
> + goto err_base_clk;
> + }
> +
> + ret = sdhci_add_host(host);
> + if (ret) {
> + dev_err(&pdev->dev, "error adding host\n");
> + goto err_base_clk;
> + }
> +
> + dev_info(&pdev->dev, "Successfully added sdhci host\n");
> + return 0;
> +
> +err_base_clk:
> + clk_disable_unprepare(sdhci_pdata->base_clk);
> +err_sys_clk:
> + clk_disable_unprepare(sdhci_pdata->sys_clk);
> +err_host:
> + sdhci_pltfm_free(pdev);
> +err:
> + dev_err(&pdev->dev, "pic32-sdhci probe failed: %d\n", ret);
> + return ret;
> +}
> +
> +static int pic32_sdhci_remove(struct platform_device *pdev)
> +{
> + struct sdhci_host *host = platform_get_drvdata(pdev);
> + struct pic32_sdhci_priv *sdhci_pdata = sdhci_priv(host);
> + u32 scratch;
> +
> + scratch = readl(host->ioaddr + SDHCI_INT_STATUS);
> + sdhci_remove_host(host, scratch == (u32)~0);
> + clk_disable_unprepare(sdhci_pdata->base_clk);
> + clk_disable_unprepare(sdhci_pdata->sys_clk);
> + sdhci_pltfm_free(pdev);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id pic32_sdhci_id_table[] = {
> + { .compatible = "microchip,pic32mzda-sdhci" },
> + {}
> +};
> +MODULE_DEVICE_TABLE(of, pic32_sdhci_id_table);
> +
> +static struct platform_driver pic32_sdhci_driver = {
> + .driver = {
> + .name = "pic32-sdhci",
> + .owner = THIS_MODULE,
> + .of_match_table = of_match_ptr(pic32_sdhci_id_table),
> + },
> + .probe = pic32_sdhci_probe,
> + .remove = pic32_sdhci_remove,
> +};
> +
> +module_platform_driver(pic32_sdhci_driver);
> +
> +MODULE_DESCRIPTION("Microchip PIC32 SDHCI driver");
> +MODULE_AUTHOR("Pistirica Sorin Andrei & Sandeep Sheriker");
> +MODULE_LICENSE("GPL v2");
>
WARNING: multiple messages have this Message-ID (diff)
From: Joshua Henderson <joshua.henderson@microchip.com>
To: linux-kernel@vger.kernel.org, Ulf Hansson <ulf.hansson@linaro.org>
Cc: linux-mips@linux-mips.org, ralf@linux-mips.org,
Andrei Pistirica <andrei.pistirica@microchip.com>,
Jean Delvare <jdelvare@suse.de>,
Geert Uytterhoeven <geert@linux-m68k.org>,
Corneliu Doban <cdoban@broadcom.com>,
Haojian Zhuang <haojian.zhuang@gmail.com>,
Luis de Bethencourt <luisbg@osg.samsung.com>,
Weijun Yang <Weijun.Yang@csr.com>,
Lokesh Vutla <lokeshvutla@ti.com>,
Scott Branden <sbranden@broadcom.com>,
Vincent Yang <vincent.yang.fujitsu@gmail.com>,
Chaotian Jing <chaotian.jing@mediatek.com>,
"ludovic.desroches@atmel.com" <ludovic.desroches@atmel.com>,
Shawn Lin <shawn.lin@rock-chips.com>,
Stephen Boyd <sboyd@codeaurora.org>,
yangbo lu <yangbo.lu@freescale.com>,
Kevin Hao <haokexin@gmail.com>,
Ben Hutchings <ben@decadent.org.uk>,
Andy Green <andy.green@linaro.org>,
linux-mmc@vger.kernel.org
Subject: Re: [PATCH v5 12/14] mmc: sdhci-pic32: Add PIC32 SDHCI host controller driver
Date: Tue, 26 Jan 2016 10:04:45 -0700 [thread overview]
Message-ID: <56A7A72D.6010007@microchip.com> (raw)
Message-ID: <20160126170445.a0A39XkO_SQK9jvEYm1uE_CPLbGhOkw6PAtLPD4BXwk@z> (raw)
In-Reply-To: <1452734299-460-13-git-send-email-joshua.henderson@microchip.com>
Hi Ulf,
Ping! Need an ack for this or pull it upstream.
On 01/13/2016 06:15 PM, Joshua Henderson wrote:
> From: Andrei Pistirica <andrei.pistirica@microchip.com>
>
> This driver supports the SDHCI host controller found on a PIC32.
>
> Signed-off-by: Andrei Pistirica <andrei.pistirica@microchip.com>
> Signed-off-by: Joshua Henderson <joshua.henderson@microchip.com>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> ---
> Changes since v4: None
> Changes since v3: None
> Changes since v2:
> - Use 'sdhci_pltfm_*' instead of 'sdhci_*_host' and other cleanup
> Changes since v1:
> - Be consistent and use only "SDHCI" when referring to SD host
> controller
> - Remove unnecessary PIC32 sdhci_ops min clock function.
> - Drop usage of piomode and no-1-8-v DT properties
> - Formatting
> - Fix use of devm_iounmap
> - Address code comment
> ---
> drivers/mmc/host/Kconfig | 11 ++
> drivers/mmc/host/Makefile | 1 +
> drivers/mmc/host/sdhci-pic32.c | 257 ++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 269 insertions(+)
> create mode 100644 drivers/mmc/host/sdhci-pic32.c
>
> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> index 1dee533..c6a8916 100644
> --- a/drivers/mmc/host/Kconfig
> +++ b/drivers/mmc/host/Kconfig
> @@ -785,3 +785,14 @@ config MMC_MTK
> If you have a machine with a integrated SD/MMC card reader, say Y or M here.
> This is needed if support for any SD/SDIO/MMC devices is required.
> If unsure, say N.
> +
> +config MMC_SDHCI_MICROCHIP_PIC32
> + tristate "Microchip PIC32MZDA SDHCI support"
> + depends on MMC_SDHCI && PIC32MZDA && MMC_SDHCI_PLTFM
> + help
> + This selects the Secure Digital Host Controller Interface (SDHCI)
> + for PIC32MZDA platform.
> +
> + If you have a controller with this interface, say Y or M here.
> +
> + If unsure, say N.
> diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
> index 3595f83..af918d2 100644
> --- a/drivers/mmc/host/Makefile
> +++ b/drivers/mmc/host/Makefile
> @@ -75,6 +75,7 @@ obj-$(CONFIG_MMC_SDHCI_BCM2835) += sdhci-bcm2835.o
> obj-$(CONFIG_MMC_SDHCI_IPROC) += sdhci-iproc.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
>
> ifeq ($(CONFIG_CB710_DEBUG),y)
> CFLAGS-cb710-mmc += -DDEBUG
> diff --git a/drivers/mmc/host/sdhci-pic32.c b/drivers/mmc/host/sdhci-pic32.c
> new file mode 100644
> index 0000000..059df70
> --- /dev/null
> +++ b/drivers/mmc/host/sdhci-pic32.c
> @@ -0,0 +1,257 @@
> +/*
> + * Support of SDHCI platform devices for Microchip PIC32.
> + *
> + * Copyright (C) 2015 Microchip
> + * Andrei Pistirica, Paul Thacker
> + *
> + * Inspired by sdhci-pltfm.c
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/highmem.h>
> +#include <linux/module.h>
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm.h>
> +#include <linux/slab.h>
> +#include <linux/mmc/host.h>
> +#include <linux/io.h>
> +#include "sdhci.h"
> +#include "sdhci-pltfm.h"
> +#include <linux/platform_data/sdhci-pic32.h>
> +
> +#define SDH_SHARED_BUS_CTRL 0x000000E0
> +#define SDH_SHARED_BUS_NR_CLK_PINS_MASK 0x7
> +#define SDH_SHARED_BUS_NR_IRQ_PINS_MASK 0x30
> +#define SDH_SHARED_BUS_CLK_PINS 0x10
> +#define SDH_SHARED_BUS_IRQ_PINS 0x14
> +#define SDH_CAPS_SDH_SLOT_TYPE_MASK 0xC0000000
> +#define SDH_SLOT_TYPE_REMOVABLE 0x0
> +#define SDH_SLOT_TYPE_EMBEDDED 0x1
> +#define SDH_SLOT_TYPE_SHARED_BUS 0x2
> +#define SDHCI_CTRL_CDSSEL 0x80
> +#define SDHCI_CTRL_CDTLVL 0x40
> +
> +#define ADMA_FIFO_RD_THSHLD 512
> +#define ADMA_FIFO_WR_THSHLD 512
> +
> +struct pic32_sdhci_priv {
> + struct platform_device *pdev;
> + struct clk *sys_clk;
> + struct clk *base_clk;
> +};
> +
> +static unsigned int pic32_sdhci_get_max_clock(struct sdhci_host *host)
> +{
> + struct pic32_sdhci_priv *sdhci_pdata = sdhci_priv(host);
> +
> + return clk_get_rate(sdhci_pdata->base_clk);
> +}
> +
> +static void pic32_sdhci_set_bus_width(struct sdhci_host *host, int width)
> +{
> + u8 ctrl;
> +
> + ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
> + if (width == MMC_BUS_WIDTH_8) {
> + ctrl &= ~SDHCI_CTRL_4BITBUS;
> + if (host->version >= SDHCI_SPEC_300)
> + ctrl |= SDHCI_CTRL_8BITBUS;
> + } else {
> + if (host->version >= SDHCI_SPEC_300)
> + ctrl &= ~SDHCI_CTRL_8BITBUS;
> + if (width == MMC_BUS_WIDTH_4)
> + ctrl |= SDHCI_CTRL_4BITBUS;
> + else
> + ctrl &= ~SDHCI_CTRL_4BITBUS;
> + }
> +
> + /* CD select and test bits must be set for errata workaround. */
> + ctrl &= ~SDHCI_CTRL_CDTLVL;
> + ctrl |= SDHCI_CTRL_CDSSEL;
> + sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
> +}
> +
> +static unsigned int pic32_sdhci_get_ro(struct sdhci_host *host)
> +{
> + /*
> + * The SDHCI_WRITE_PROTECT bit is unstable on current hardware so we
> + * can't depend on its value in any way.
> + */
> + return 0;
> +}
> +
> +static const struct sdhci_ops pic32_sdhci_ops = {
> + .get_max_clock = pic32_sdhci_get_max_clock,
> + .set_clock = sdhci_set_clock,
> + .set_bus_width = pic32_sdhci_set_bus_width,
> + .reset = sdhci_reset,
> + .set_uhs_signaling = sdhci_set_uhs_signaling,
> + .get_ro = pic32_sdhci_get_ro,
> +};
> +
> +static struct sdhci_pltfm_data sdhci_pic32_pdata = {
> + .ops = &pic32_sdhci_ops,
> + .quirks = SDHCI_QUIRK_NO_HISPD_BIT,
> + .quirks2 = SDHCI_QUIRK2_NO_1_8_V,
> +};
> +
> +static void pic32_sdhci_shared_bus(struct platform_device *pdev)
> +{
> + struct sdhci_host *host = platform_get_drvdata(pdev);
> + u32 bus = readl(host->ioaddr + SDH_SHARED_BUS_CTRL);
> + u32 clk_pins = (bus & SDH_SHARED_BUS_NR_CLK_PINS_MASK) >> 0;
> + u32 irq_pins = (bus & SDH_SHARED_BUS_NR_IRQ_PINS_MASK) >> 4;
> +
> + /* select first clock */
> + if (clk_pins & 1)
> + bus |= (1 << SDH_SHARED_BUS_CLK_PINS);
> +
> + /* select first interrupt */
> + if (irq_pins & 1)
> + bus |= (1 << SDH_SHARED_BUS_IRQ_PINS);
> +
> + writel(bus, host->ioaddr + SDH_SHARED_BUS_CTRL);
> +}
> +
> +static int pic32_sdhci_probe_platform(struct platform_device *pdev,
> + struct pic32_sdhci_priv *pdata)
> +{
> + int ret = 0;
> + u32 caps_slot_type;
> + struct sdhci_host *host = platform_get_drvdata(pdev);
> +
> + /* Check card slot connected on shared bus. */
> + host->caps = readl(host->ioaddr + SDHCI_CAPABILITIES);
> + caps_slot_type = (host->caps & SDH_CAPS_SDH_SLOT_TYPE_MASK) >> 30;
> + if (caps_slot_type == SDH_SLOT_TYPE_SHARED_BUS)
> + pic32_sdhci_shared_bus(pdev);
> +
> + return ret;
> +}
> +
> +static int pic32_sdhci_probe(struct platform_device *pdev)
> +{
> + struct sdhci_host *host;
> + struct sdhci_pltfm_host *pltfm_host;
> + struct pic32_sdhci_priv *sdhci_pdata;
> + struct pic32_sdhci_platform_data *plat_data;
> + int ret;
> +
> + host = sdhci_pltfm_init(pdev, &sdhci_pic32_pdata,
> + sizeof(struct pic32_sdhci_priv));
> + if (IS_ERR(host)) {
> + ret = PTR_ERR(host);
> + goto err;
> + }
> +
> + pltfm_host = sdhci_priv(host);
> + sdhci_pdata = sdhci_pltfm_priv(pltfm_host);
> +
> + plat_data = pdev->dev.platform_data;
> + if (plat_data && plat_data->setup_dma) {
> + ret = plat_data->setup_dma(ADMA_FIFO_RD_THSHLD,
> + ADMA_FIFO_WR_THSHLD);
> + if (ret)
> + goto err_host;
> + }
> +
> + sdhci_pdata->sys_clk = devm_clk_get(&pdev->dev, "sys_clk");
> + if (IS_ERR(sdhci_pdata->sys_clk)) {
> + ret = PTR_ERR(sdhci_pdata->sys_clk);
> + dev_err(&pdev->dev, "Error getting clock\n");
> + goto err_host;
> + }
> +
> + ret = clk_prepare_enable(sdhci_pdata->sys_clk);
> + if (ret) {
> + dev_err(&pdev->dev, "Error enabling clock\n");
> + goto err_host;
> + }
> +
> + sdhci_pdata->base_clk = devm_clk_get(&pdev->dev, "base_clk");
> + if (IS_ERR(sdhci_pdata->base_clk)) {
> + ret = PTR_ERR(sdhci_pdata->base_clk);
> + dev_err(&pdev->dev, "Error getting clock\n");
> + goto err_sys_clk;
> + }
> +
> + ret = clk_prepare_enable(sdhci_pdata->base_clk);
> + if (ret) {
> + dev_err(&pdev->dev, "Error enabling clock\n");
> + goto err_base_clk;
> + }
> +
> + ret = mmc_of_parse(host->mmc);
> + if (ret)
> + goto err_base_clk;
> +
> + ret = pic32_sdhci_probe_platform(pdev, sdhci_pdata);
> + if (ret) {
> + dev_err(&pdev->dev, "failed to probe platform!\n");
> + goto err_base_clk;
> + }
> +
> + ret = sdhci_add_host(host);
> + if (ret) {
> + dev_err(&pdev->dev, "error adding host\n");
> + goto err_base_clk;
> + }
> +
> + dev_info(&pdev->dev, "Successfully added sdhci host\n");
> + return 0;
> +
> +err_base_clk:
> + clk_disable_unprepare(sdhci_pdata->base_clk);
> +err_sys_clk:
> + clk_disable_unprepare(sdhci_pdata->sys_clk);
> +err_host:
> + sdhci_pltfm_free(pdev);
> +err:
> + dev_err(&pdev->dev, "pic32-sdhci probe failed: %d\n", ret);
> + return ret;
> +}
> +
> +static int pic32_sdhci_remove(struct platform_device *pdev)
> +{
> + struct sdhci_host *host = platform_get_drvdata(pdev);
> + struct pic32_sdhci_priv *sdhci_pdata = sdhci_priv(host);
> + u32 scratch;
> +
> + scratch = readl(host->ioaddr + SDHCI_INT_STATUS);
> + sdhci_remove_host(host, scratch == (u32)~0);
> + clk_disable_unprepare(sdhci_pdata->base_clk);
> + clk_disable_unprepare(sdhci_pdata->sys_clk);
> + sdhci_pltfm_free(pdev);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id pic32_sdhci_id_table[] = {
> + { .compatible = "microchip,pic32mzda-sdhci" },
> + {}
> +};
> +MODULE_DEVICE_TABLE(of, pic32_sdhci_id_table);
> +
> +static struct platform_driver pic32_sdhci_driver = {
> + .driver = {
> + .name = "pic32-sdhci",
> + .owner = THIS_MODULE,
> + .of_match_table = of_match_ptr(pic32_sdhci_id_table),
> + },
> + .probe = pic32_sdhci_probe,
> + .remove = pic32_sdhci_remove,
> +};
> +
> +module_platform_driver(pic32_sdhci_driver);
> +
> +MODULE_DESCRIPTION("Microchip PIC32 SDHCI driver");
> +MODULE_AUTHOR("Pistirica Sorin Andrei & Sandeep Sheriker");
> +MODULE_LICENSE("GPL v2");
>
next prev parent reply other threads:[~2016-01-26 16:57 UTC|newest]
Thread overview: 66+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-01-14 1:15 [PATCH v5 00/14] Initial Microchip PIC32MZDA Support Joshua Henderson
2016-01-14 1:15 ` Joshua Henderson
2016-01-14 1:15 ` Joshua Henderson
2016-01-14 1:15 ` [PATCH v5 01/14] dt/bindings: Add bindings for PIC32 interrupt controller Joshua Henderson
2016-01-14 1:15 ` Joshua Henderson
2016-01-17 3:57 ` Rob Herring
2016-01-14 1:15 ` [PATCH v5 02/14] irqchip: irq-pic32-evic: Add support " Joshua Henderson
2016-01-14 1:15 ` Joshua Henderson
2016-01-14 8:10 ` Thomas Gleixner
2016-01-14 11:12 ` Ralf Baechle
2016-01-14 11:12 ` Ralf Baechle
2016-01-14 11:12 ` Ralf Baechle
2016-01-14 1:15 ` [PATCH v5 03/14] dt/bindings: Add PIC32 clock binding documentation Joshua Henderson
2016-01-14 1:15 ` Joshua Henderson
2016-01-14 1:15 ` [PATCH v5 04/14] clk: clk-pic32: Add PIC32 clock driver Joshua Henderson
2016-01-14 1:15 ` Joshua Henderson
2016-01-26 17:04 ` Joshua Henderson
2016-01-26 17:04 ` Joshua Henderson
2016-01-29 23:58 ` Stephen Boyd
2016-02-03 5:36 ` Purna Chandra Mandal
2016-02-03 5:36 ` Purna Chandra Mandal
2016-01-14 1:15 ` [PATCH v5 05/14] dt/bindings: Add bindings for PIC32/MZDA platforms Joshua Henderson
2016-01-14 1:15 ` Joshua Henderson
2016-01-14 1:15 ` [PATCH v5 06/14] MIPS: Add support for PIC32MZDA platform Joshua Henderson
2016-01-14 1:15 ` Joshua Henderson
2016-01-14 1:15 ` [PATCH v5 07/14] dt/bindings: Add bindings for PIC32 pin control and GPIO Joshua Henderson
2016-01-14 1:15 ` Joshua Henderson
2016-01-14 1:15 ` [PATCH v5 08/14] pinctrl: pinctrl-pic32: Add PIC32 pin control driver Joshua Henderson
2016-01-14 1:15 ` Joshua Henderson
2016-01-26 17:04 ` Joshua Henderson
2016-01-26 17:04 ` Joshua Henderson
2016-01-27 13:49 ` Linus Walleij
2016-01-28 0:33 ` Joshua Henderson
2016-01-14 1:15 ` [PATCH v5 09/14] dt/bindings: Add bindings for PIC32 UART driver Joshua Henderson
2016-01-14 1:15 ` Joshua Henderson
2016-01-14 1:15 ` [PATCH v5 10/14] serial: pic32_uart: Add " Joshua Henderson
2016-01-14 1:15 ` Joshua Henderson
2016-01-26 17:04 ` Joshua Henderson
2016-01-26 17:04 ` Joshua Henderson
[not found] ` <56A7A729.10008-UWL1GkI3JZL3oGB3hsPCZA@public.gmane.org>
2016-01-26 17:33 ` Greg Kroah-Hartman
2016-01-26 17:33 ` Greg Kroah-Hartman
[not found] ` <20160126173322.GA1664-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org>
2016-01-27 15:55 ` Joshua Henderson
2016-01-27 15:55 ` Joshua Henderson
2016-01-27 15:55 ` Joshua Henderson
[not found] ` <1452734299-460-11-git-send-email-joshua.henderson-UWL1GkI3JZL3oGB3hsPCZA@public.gmane.org>
2016-01-14 13:55 ` One Thousand Gnomes
2016-01-14 13:55 ` One Thousand Gnomes
2016-01-14 13:55 ` One Thousand Gnomes
2016-02-07 7:04 ` Greg Kroah-Hartman
2016-02-07 7:04 ` Greg Kroah-Hartman
2016-04-15 17:28 ` Sudeep Holla
2016-04-15 17:28 ` Sudeep Holla
2016-04-16 16:09 ` Greg Kroah-Hartman
2016-01-14 1:15 ` [PATCH v5 11/14] dt/bindings: Add bindings for PIC32 SDHCI host controller Joshua Henderson
2016-01-14 1:15 ` Joshua Henderson
2016-02-08 9:58 ` Ulf Hansson
2016-01-14 1:15 ` [PATCH v5 12/14] mmc: sdhci-pic32: Add PIC32 SDHCI host controller driver Joshua Henderson
2016-01-14 1:15 ` Joshua Henderson
2016-01-14 1:15 ` Joshua Henderson
2016-01-26 17:04 ` Joshua Henderson [this message]
2016-01-26 17:04 ` Joshua Henderson
2016-02-08 9:59 ` Ulf Hansson
2016-02-08 9:59 ` Ulf Hansson
2016-01-14 1:15 ` [PATCH v5 13/14] MIPS: dts: Add initial DTS for the PIC32MZDA Starter Kit Joshua Henderson
2016-01-14 1:15 ` Joshua Henderson
2016-01-14 1:15 ` [PATCH v5 14/14] MIPS: pic32mzda: Add initial PIC32MZDA Starter Kit defconfig Joshua Henderson
2016-01-14 1:15 ` Joshua Henderson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=56A7A72D.6010007@microchip.com \
--to=joshua.henderson@microchip.com \
--cc=Weijun.Yang@csr.com \
--cc=andrei.pistirica@microchip.com \
--cc=andy.green@linaro.org \
--cc=ben@decadent.org.uk \
--cc=cdoban@broadcom.com \
--cc=chaotian.jing@mediatek.com \
--cc=geert@linux-m68k.org \
--cc=haojian.zhuang@gmail.com \
--cc=haokexin@gmail.com \
--cc=jdelvare@suse.de \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mips@linux-mips.org \
--cc=linux-mmc@vger.kernel.org \
--cc=lokeshvutla@ti.com \
--cc=ludovic.desroches@atmel.com \
--cc=luisbg@osg.samsung.com \
--cc=ralf@linux-mips.org \
--cc=sboyd@codeaurora.org \
--cc=sbranden@broadcom.com \
--cc=shawn.lin@rock-chips.com \
--cc=ulf.hansson@linaro.org \
--cc=vincent.yang.fujitsu@gmail.com \
--cc=yangbo.lu@freescale.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.