From: marex@denx.de (Marek Vasut)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 04/10 RESEND] mmc: spi: Pull out parts shared between MMC and SPI
Date: Fri, 6 Jul 2012 08:17:23 +0200 [thread overview]
Message-ID: <1341555449-17507-4-git-send-email-marex@denx.de> (raw)
In-Reply-To: <1341555449-17507-1-git-send-email-marex@denx.de>
Abstract out the common part of private data shared between MMC
and SPI. These shall later allow to use common clock configuration
function.
Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Chris Ball <cjb@laptop.org>
Cc: Detlev Zundel <dzu@denx.de>
CC: Dong Aisheng <b29396@freescale.com>
Cc: Fabio Estevam <fabio.estevam@freescale.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Linux ARM kernel <linux-arm-kernel@lists.infradead.org>
Cc: Rob Herring <rob.herring@calxeda.com>
CC: Shawn Guo <shawn.guo@linaro.org>
Cc: Stefano Babic <sbabic@denx.de>
Cc: Wolfgang Denk <wd@denx.de>
---
drivers/mmc/host/mxs-mmc.c | 107 ++++++++++++++++++++++++-------------------
include/linux/spi/mxs-spi.h | 8 ++++
2 files changed, 67 insertions(+), 48 deletions(-)
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
index f9509e8..1ea1cba 100644
--- a/drivers/mmc/host/mxs-mmc.c
+++ b/drivers/mmc/host/mxs-mmc.c
@@ -62,23 +62,20 @@
#define MXS_MMC_DETECT_TIMEOUT (HZ/2)
struct mxs_mmc_host {
+ struct mxs_ssp ssp;
+
struct mmc_host *mmc;
struct mmc_request *mrq;
struct mmc_command *cmd;
struct mmc_data *data;
- void __iomem *base;
int dma_channel;
- struct clk *clk;
- unsigned int clk_rate;
-
struct dma_chan *dmach;
struct mxs_dma_data dma_data;
unsigned int dma_dir;
enum dma_transfer_direction slave_dirn;
u32 ssp_pio_words[SSP_PIO_NUM];
- enum mxs_ssp_id devid;
unsigned char bus_width;
spinlock_t lock;
int sdio_irq_en;
@@ -105,16 +102,18 @@ static int mxs_mmc_get_ro(struct mmc_host *mmc)
static int mxs_mmc_get_cd(struct mmc_host *mmc)
{
struct mxs_mmc_host *host = mmc_priv(mmc);
+ struct mxs_ssp *ssp = &host->ssp;
- return !(readl(host->base + HW_SSP_STATUS(host)) &
+ return !(readl(ssp->base + HW_SSP_STATUS(ssp)) &
BM_SSP_STATUS_CARD_DETECT);
}
static void mxs_mmc_reset(struct mxs_mmc_host *host)
{
+ struct mxs_ssp *ssp = &host->ssp;
u32 ctrl0, ctrl1;
- stmp_reset_block(host->base);
+ stmp_reset_block(ssp->base);
ctrl0 = BM_SSP_CTRL0_IGNORE_CRC;
ctrl1 = BF_SSP(0x3, CTRL1_SSP_MODE) |
@@ -130,15 +129,15 @@ static void mxs_mmc_reset(struct mxs_mmc_host *host)
writel(BF_SSP(0xffff, TIMING_TIMEOUT) |
BF_SSP(2, TIMING_CLOCK_DIVIDE) |
BF_SSP(0, TIMING_CLOCK_RATE),
- host->base + HW_SSP_TIMING(host));
+ ssp->base + HW_SSP_TIMING(ssp));
if (host->sdio_irq_en) {
ctrl0 |= BM_SSP_CTRL0_SDIO_IRQ_CHECK;
ctrl1 |= BM_SSP_CTRL1_SDIO_IRQ_EN;
}
- writel(ctrl0, host->base + HW_SSP_CTRL0);
- writel(ctrl1, host->base + HW_SSP_CTRL1(host));
+ writel(ctrl0, ssp->base + HW_SSP_CTRL0);
+ writel(ctrl1, ssp->base + HW_SSP_CTRL1(ssp));
}
static void mxs_mmc_start_cmd(struct mxs_mmc_host *host,
@@ -149,15 +148,16 @@ static void mxs_mmc_request_done(struct mxs_mmc_host *host)
struct mmc_command *cmd = host->cmd;
struct mmc_data *data = host->data;
struct mmc_request *mrq = host->mrq;
+ struct mxs_ssp *ssp = &host->ssp;
if (mmc_resp_type(cmd) & MMC_RSP_PRESENT) {
if (mmc_resp_type(cmd) & MMC_RSP_136) {
- cmd->resp[3] = readl(host->base + HW_SSP_SDRESP0(host));
- cmd->resp[2] = readl(host->base + HW_SSP_SDRESP1(host));
- cmd->resp[1] = readl(host->base + HW_SSP_SDRESP2(host));
- cmd->resp[0] = readl(host->base + HW_SSP_SDRESP3(host));
+ cmd->resp[3] = readl(ssp->base + HW_SSP_SDRESP0(ssp));
+ cmd->resp[2] = readl(ssp->base + HW_SSP_SDRESP1(ssp));
+ cmd->resp[1] = readl(ssp->base + HW_SSP_SDRESP2(ssp));
+ cmd->resp[0] = readl(ssp->base + HW_SSP_SDRESP3(ssp));
} else {
- cmd->resp[0] = readl(host->base + HW_SSP_SDRESP0(host));
+ cmd->resp[0] = readl(ssp->base + HW_SSP_SDRESP0(ssp));
}
}
@@ -196,13 +196,14 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id)
struct mxs_mmc_host *host = dev_id;
struct mmc_command *cmd = host->cmd;
struct mmc_data *data = host->data;
+ struct mxs_ssp *ssp = &host->ssp;
u32 stat;
spin_lock(&host->lock);
- stat = readl(host->base + HW_SSP_CTRL1(host));
+ stat = readl(ssp->base + HW_SSP_CTRL1(ssp));
writel(stat & MXS_MMC_IRQ_BITS,
- host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_CLR);
+ ssp->base + HW_SSP_CTRL1(ssp) + STMP_OFFSET_REG_CLR);
if ((stat & BM_SSP_CTRL1_SDIO_IRQ) && (stat & BM_SSP_CTRL1_SDIO_IRQ_EN))
mmc_signal_sdio_irq(host->mmc);
@@ -366,6 +367,8 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
unsigned int data_size = 0, log2_blksz;
unsigned int blocks = data->blocks;
+ struct mxs_ssp *ssp = &host->ssp;
+
u32 ignore_crc, get_resp, long_resp, read;
u32 ctrl0, cmd0, cmd1, val;
@@ -408,15 +411,15 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
blocks = 1;
/* xfer count, block size and count need to be set differently */
- if (ssp_is_old(host)) {
+ if (ssp_is_old(ssp)) {
ctrl0 |= BF_SSP(data_size, CTRL0_XFER_COUNT);
cmd0 |= BF_SSP(log2_blksz, CMD0_BLOCK_SIZE) |
BF_SSP(blocks - 1, CMD0_BLOCK_COUNT);
} else {
- writel(data_size, host->base + HW_SSP_XFER_SIZE);
+ writel(data_size, ssp->base + HW_SSP_XFER_SIZE);
writel(BF_SSP(log2_blksz, BLOCK_SIZE_BLOCK_SIZE) |
BF_SSP(blocks - 1, BLOCK_SIZE_BLOCK_COUNT),
- host->base + HW_SSP_BLOCK_SIZE);
+ ssp->base + HW_SSP_BLOCK_SIZE);
}
if ((cmd->opcode == MMC_STOP_TRANSMISSION) ||
@@ -431,11 +434,11 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
}
/* set the timeout count */
- timeout = mxs_ns_to_ssp_ticks(host->clk_rate, data->timeout_ns);
- val = readl(host->base + HW_SSP_TIMING(host));
+ timeout = mxs_ns_to_ssp_ticks(ssp->clk_rate, data->timeout_ns);
+ val = readl(ssp->base + HW_SSP_TIMING(ssp));
val &= ~(BM_SSP_TIMING_TIMEOUT);
val |= BF_SSP(timeout, TIMING_TIMEOUT);
- writel(val, host->base + HW_SSP_TIMING(host));
+ writel(val, ssp->base + HW_SSP_TIMING(ssp));
/* pio */
host->ssp_pio_words[0] = ctrl0;
@@ -500,11 +503,12 @@ static void mxs_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
static void mxs_mmc_set_clk_rate(struct mxs_mmc_host *host, unsigned int rate)
{
+ struct mxs_ssp *ssp = &host->ssp;
unsigned int ssp_clk, ssp_sck;
u32 clock_divide, clock_rate;
u32 val;
- ssp_clk = clk_get_rate(host->clk);
+ ssp_clk = clk_get_rate(ssp->clk);
for (clock_divide = 2; clock_divide <= 254; clock_divide += 2) {
clock_rate = DIV_ROUND_UP(ssp_clk, rate * clock_divide);
@@ -521,13 +525,13 @@ static void mxs_mmc_set_clk_rate(struct mxs_mmc_host *host, unsigned int rate)
ssp_sck = ssp_clk / clock_divide / (1 + clock_rate);
- val = readl(host->base + HW_SSP_TIMING(host));
+ val = readl(ssp->base + HW_SSP_TIMING(ssp));
val &= ~(BM_SSP_TIMING_CLOCK_DIVIDE | BM_SSP_TIMING_CLOCK_RATE);
val |= BF_SSP(clock_divide, TIMING_CLOCK_DIVIDE);
val |= BF_SSP(clock_rate, TIMING_CLOCK_RATE);
- writel(val, host->base + HW_SSP_TIMING(host));
+ writel(val, ssp->base + HW_SSP_TIMING(ssp));
- host->clk_rate = ssp_sck;
+ ssp->clk_rate = ssp_sck;
dev_dbg(mmc_dev(host->mmc),
"%s: clock_divide %d, clock_rate %d, ssp_clk %d, rate_actual %d, rate_requested %d\n",
@@ -552,6 +556,7 @@ static void mxs_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
{
struct mxs_mmc_host *host = mmc_priv(mmc);
+ struct mxs_ssp *ssp = &host->ssp;
unsigned long flags;
spin_lock_irqsave(&host->lock, flags);
@@ -560,19 +565,19 @@ static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
if (enable) {
writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
- host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
+ ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
- host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_SET);
+ ssp->base + HW_SSP_CTRL1(ssp) + STMP_OFFSET_REG_SET);
- if (readl(host->base + HW_SSP_STATUS(host)) &
+ if (readl(ssp->base + HW_SSP_STATUS(ssp)) &
BM_SSP_STATUS_SDIO_IRQ)
mmc_signal_sdio_irq(host->mmc);
} else {
writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
- host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);
+ ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);
writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
- host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_CLR);
+ ssp->base + HW_SSP_CTRL1(ssp) + STMP_OFFSET_REG_CLR);
}
spin_unlock_irqrestore(&host->lock, flags);
@@ -635,6 +640,7 @@ static int mxs_mmc_probe(struct platform_device *pdev)
dma_cap_mask_t mask;
struct regulator *reg_vmmc;
enum of_gpio_flags flags;
+ struct mxs_ssp *ssp;
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
@@ -648,14 +654,16 @@ static int mxs_mmc_probe(struct platform_device *pdev)
return -ENOMEM;
host = mmc_priv(mmc);
- host->base = devm_request_and_ioremap(&pdev->dev, iores);
- if (!host->base) {
+ ssp = &host->ssp;
+ ssp->dev = &pdev->dev;
+ ssp->base = devm_request_and_ioremap(&pdev->dev, iores);
+ if (!ssp->base) {
ret = -EADDRNOTAVAIL;
goto out_mmc_free;
}
if (np) {
- host->devid = (enum mxs_ssp_id) of_id->data;
+ ssp->devid = (enum mxs_ssp_id) of_id->data;
/*
* TODO: This is a temporary solution and should be changed
* to use generic DMA binding later when the helpers get in.
@@ -668,7 +676,7 @@ static int mxs_mmc_probe(struct platform_device *pdev)
goto out_mmc_free;
}
} else {
- host->devid = pdev->id_entry->driver_data;
+ ssp->devid = pdev->id_entry->driver_data;
host->dma_channel = dmares->start;
}
@@ -691,12 +699,12 @@ static int mxs_mmc_probe(struct platform_device *pdev)
goto out_mmc_free;
}
- host->clk = clk_get(&pdev->dev, NULL);
- if (IS_ERR(host->clk)) {
- ret = PTR_ERR(host->clk);
+ ssp->clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(ssp->clk)) {
+ ret = PTR_ERR(ssp->clk);
goto out_mmc_free;
}
- clk_prepare_enable(host->clk);
+ clk_prepare_enable(ssp->clk);
mxs_mmc_reset(host);
@@ -741,8 +749,8 @@ static int mxs_mmc_probe(struct platform_device *pdev)
mmc->max_segs = 52;
mmc->max_blk_size = 1 << 0xf;
- mmc->max_blk_count = (ssp_is_old(host)) ? 0xff : 0xffffff;
- mmc->max_req_size = (ssp_is_old(host)) ? 0xffff : 0xffffffff;
+ mmc->max_blk_count = (ssp_is_old(ssp)) ? 0xff : 0xffffff;
+ mmc->max_req_size = (ssp_is_old(ssp)) ? 0xffff : 0xffffffff;
mmc->max_seg_size = dma_get_max_seg_size(host->dmach->device->dev);
platform_set_drvdata(pdev, mmc);
@@ -766,8 +774,8 @@ out_free_dma:
if (host->dmach)
dma_release_channel(host->dmach);
out_clk_put:
- clk_disable_unprepare(host->clk);
- clk_put(host->clk);
+ clk_disable_unprepare(ssp->clk);
+ clk_put(ssp->clk);
out_mmc_free:
mmc_free_host(mmc);
return ret;
@@ -777,6 +785,7 @@ static int mxs_mmc_remove(struct platform_device *pdev)
{
struct mmc_host *mmc = platform_get_drvdata(pdev);
struct mxs_mmc_host *host = mmc_priv(mmc);
+ struct mxs_ssp *ssp = &host->ssp;
mmc_remove_host(mmc);
@@ -785,8 +794,8 @@ static int mxs_mmc_remove(struct platform_device *pdev)
if (host->dmach)
dma_release_channel(host->dmach);
- clk_disable_unprepare(host->clk);
- clk_put(host->clk);
+ clk_disable_unprepare(ssp->clk);
+ clk_put(ssp->clk);
mmc_free_host(mmc);
@@ -798,11 +807,12 @@ static int mxs_mmc_suspend(struct device *dev)
{
struct mmc_host *mmc = dev_get_drvdata(dev);
struct mxs_mmc_host *host = mmc_priv(mmc);
+ struct mxs_ssp *ssp = &host->ssp;
int ret = 0;
ret = mmc_suspend_host(mmc);
- clk_disable_unprepare(host->clk);
+ clk_disable_unprepare(ssp->clk);
return ret;
}
@@ -811,9 +821,10 @@ static int mxs_mmc_resume(struct device *dev)
{
struct mmc_host *mmc = dev_get_drvdata(dev);
struct mxs_mmc_host *host = mmc_priv(mmc);
+ struct mxs_ssp *ssp = &host->ssp;
int ret = 0;
- clk_prepare_enable(host->clk);
+ clk_prepare_enable(ssp->clk);
ret = mmc_resume_host(mmc);
diff --git a/include/linux/spi/mxs-spi.h b/include/linux/spi/mxs-spi.h
index b0a0335..0cb2767 100644
--- a/include/linux/spi/mxs-spi.h
+++ b/include/linux/spi/mxs-spi.h
@@ -128,4 +128,12 @@ enum mxs_ssp_id {
IMX28_SSP,
};
+struct mxs_ssp {
+ struct device *dev;
+ void __iomem *base;
+ struct clk *clk;
+ unsigned int clk_rate;
+ enum mxs_ssp_id devid;
+};
+
#endif /* __LINUX_SPI_MXS_SPI_H__ */
--
1.7.10
next prev parent reply other threads:[~2012-07-06 6:17 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-07-06 6:17 [PATCH 01/10 RESEND] mmc: spi: Move SSP register definitions into separate file Marek Vasut
2012-07-06 6:17 ` [PATCH 02/10 RESEND] mmc: spi: Rename IMX2[38]_MMC to IMX2[38]_SSP Marek Vasut
2012-07-06 6:17 ` [PATCH 03/10 RESEND] mmc: spi: Add necessary bits into mxs-spi.h Marek Vasut
2012-07-06 6:17 ` Marek Vasut [this message]
2012-07-16 7:57 ` [PATCH 04/10 RESEND] mmc: spi: Pull out parts shared between MMC and SPI Attila Kinali
2012-07-16 10:59 ` Marek Vasut
2012-07-16 11:32 ` Attila Kinali
2012-07-06 6:17 ` [PATCH 05/10 RESEND] mmc: spi: Pull out the SSP clock configuration function Marek Vasut
2012-07-06 6:17 ` [PATCH 06/10 V2] spi: Add SPI driver for mx233/mx28 Marek Vasut
2012-07-31 20:53 ` [06/10,V2] " Guenter Roeck
2012-08-01 2:31 ` Marek Vasut
2012-08-01 3:34 ` Guenter Roeck
2012-08-01 3:53 ` Shawn Guo
2012-08-01 3:35 ` Guenter Roeck
2012-08-01 4:50 ` Shawn Guo
2012-08-01 5:00 ` Marek Vasut
2012-08-01 5:29 ` Guenter Roeck
2012-08-01 5:46 ` Shubhrajyoti Datta
2012-08-01 6:36 ` Guenter Roeck
2012-08-01 6:41 ` Marek Vasut
2012-08-01 5:58 ` Shawn Guo
2012-08-01 5:42 ` Guenter Roeck
2012-08-01 6:28 ` Shawn Guo
2012-08-01 6:10 ` Marek Vasut
2012-08-01 6:39 ` Guenter Roeck
2012-08-01 6:45 ` Marek Vasut
2012-08-01 6:56 ` Guenter Roeck
2012-08-01 7:50 ` Shawn Guo
2012-08-01 14:58 ` Guenter Roeck
2012-08-01 7:40 ` Shawn Guo
2012-08-01 7:38 ` Lothar Waßmann
2012-08-01 8:20 ` Shawn Guo
2012-08-01 7:47 ` Shawn Guo
2012-08-01 6:33 ` Guenter Roeck
2012-08-01 6:40 ` Marek Vasut
2012-08-01 4:48 ` Marek Vasut
2012-08-01 3:48 ` Shawn Guo
2012-07-06 6:17 ` [PATCH 07/10 RESEND] mmc: spi: Pull out common DMA parts from MXS MMC Marek Vasut
2012-07-06 6:17 ` [PATCH 08/10 V2] spi: Add DMA support into SPI driver Marek Vasut
2012-08-01 6:29 ` Marek Vasut
2012-07-06 6:17 ` [PATCH 09/10] spi: Add SSP/SPI device tree documentation Marek Vasut
2012-07-06 6:17 ` [PATCH 10/10] ARM: mx28: Add SPI pinmux into imx28.dtsi Marek Vasut
2012-07-09 16:53 ` [PATCH 01/10 RESEND] mmc: spi: Move SSP register definitions into separate file Marek Vasut
-- strict thread matches above, loose matches on Subject: below --
2012-07-23 20:40 [PATCH 00/10 V2] MXS SPI driver Marek Vasut
2012-07-23 20:40 ` [PATCH 04/10 RESEND] mmc: spi: Pull out parts shared between MMC and SPI Marek Vasut
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=1341555449-17507-4-git-send-email-marex@denx.de \
--to=marex@denx.de \
--cc=linux-arm-kernel@lists.infradead.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).