Date   

[PATCH 4.4.y-cip 38/83] mmc: tmio: document mandatory and optional callbacks

Biju Das <biju.das@...>
 

From: Simon Horman <horms+renesas@...>

commit 2f87365f832bbc26e32f23588aaeb40abe15ff0d upstream.

Signed-off-by: Simon Horman <horms+renesas@...>
Acked-by: Wolfram Sang <wsa+renesas@...>
Tested-by: Wolfram Sang <wsa+renesas@...>
Signed-off-by: Ulf Hansson <ulf.hansson@...>
Signed-off-by: Biju Das <biju.das@...>
---
drivers/mmc/host/tmio_mmc.h | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index c4131d9..d3d24e1 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -154,8 +154,10 @@ struct tmio_mmc_host {
bool native_hotplug;
bool sdio_irq_enabled;

- int (*write16_hook)(struct tmio_mmc_host *host, int addr);
+ /* Mandatory callback */
int (*clk_enable)(struct tmio_mmc_host *host);
+
+ /* Optional callbacks */
unsigned int (*clk_update)(struct tmio_mmc_host *host,
unsigned int new_clock);
void (*clk_disable)(struct tmio_mmc_host *host);
@@ -164,6 +166,7 @@ struct tmio_mmc_host {
int (*card_busy)(struct mmc_host *mmc);
int (*start_signal_voltage_switch)(struct mmc_host *mmc,
struct mmc_ios *ios);
+ int (*write16_hook)(struct tmio_mmc_host *host, int addr);
};

struct tmio_mmc_host *tmio_mmc_host_alloc(struct platform_device *pdev);
--
2.7.4


[PATCH 4.4.y-cip 37/83] mmc: tmio: enhance illegal sequence handling

Biju Das <biju.das@...>
 

From: Ai Kyuse <ai.kyuse.uw@...>

commit 96e0b2ba00ee5dacb12bed6585145ce784ec9153 upstream.

An illegal sequence command error may occur if there is a stopbit or
cmd_index error as well as a CRC error. The correct course of action
is to re-enable IRQs

An illegal sequence data error may occur if there is a CRC or stopbit
error, or underrun. In this case set data->error correctly.

This is in preparation for enabling tuning support which relies on
differentiating between illegal sequence and other errors.

Signed-off-by: Ai Kyuse <ai.kyuse.uw@...>
[simon: broken out of a larger patch]
Signed-off-by: Simon Horman <horms+renesas@...>
Acked-by: Wolfram Sang <wsa+renesas@...>
Tested-by: Wolfram Sang <wsa+renesas@...>
Signed-off-by: Ulf Hansson <ulf.hansson@...>

Signed-off-by: Biju Das <biju.das@...>
---
drivers/mmc/host/tmio_mmc_pio.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index 4d9e17a..c255af8 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -552,7 +552,7 @@ void tmio_mmc_do_data_irq(struct tmio_mmc_host *host)
schedule_work(&host->done);
}

-static void tmio_mmc_data_irq(struct tmio_mmc_host *host)
+static void tmio_mmc_data_irq(struct tmio_mmc_host *host, unsigned int stat)
{
struct mmc_data *data;
spin_lock(&host->lock);
@@ -561,6 +561,9 @@ static void tmio_mmc_data_irq(struct tmio_mmc_host *host)
if (!data)
goto out;

+ if (stat & TMIO_STAT_CRCFAIL || stat & TMIO_STAT_STOPBIT_ERR ||
+ stat & TMIO_STAT_TXUNDERRUN)
+ data->error = -EILSEQ;
if (host->chan_tx && (data->flags & MMC_DATA_WRITE) && !host->force_pio) {
u32 status = sd_ctrl_read16_and_16_as_32(host, CTL_STATUS);
bool done = false;
@@ -609,8 +612,6 @@ static void tmio_mmc_cmd_irq(struct tmio_mmc_host *host,
goto out;
}

- host->cmd = NULL;
-
/* This controller is sicker than the PXA one. Not only do we need to
* drop the top 8 bits of the first response word, we also need to
* modify the order of the response for short response command types.
@@ -630,14 +631,16 @@ static void tmio_mmc_cmd_irq(struct tmio_mmc_host *host,

if (stat & TMIO_STAT_CMDTIMEOUT)
cmd->error = -ETIMEDOUT;
- else if (stat & TMIO_STAT_CRCFAIL && cmd->flags & MMC_RSP_CRC)
+ else if ((stat & TMIO_STAT_CRCFAIL && cmd->flags & MMC_RSP_CRC) ||
+ stat & TMIO_STAT_STOPBIT_ERR ||
+ stat & TMIO_STAT_CMD_IDX_ERR)
cmd->error = -EILSEQ;

/* If there is data to handle we enable data IRQs here, and
* we will ultimatley finish the request in the data_end handler.
* If theres no data or we encountered an error, finish now.
*/
- if (host->data && !cmd->error) {
+ if (host->data && (!cmd->error || cmd->error == -EILSEQ)) {
if (host->data->flags & MMC_DATA_READ) {
if (host->force_pio || !host->chan_rx)
tmio_mmc_enable_mmc_irqs(host, TMIO_MASK_READOP);
@@ -698,7 +701,7 @@ static bool __tmio_mmc_sdcard_irq(struct tmio_mmc_host *host,
/* Data transfer completion */
if (ireg & TMIO_STAT_DATAEND) {
tmio_mmc_ack_mmc_irqs(host, TMIO_STAT_DATAEND);
- tmio_mmc_data_irq(host);
+ tmio_mmc_data_irq(host, status);
return true;
}

--
2.7.4


[PATCH 4.4.y-cip 36/83] mmc: sh_mobile_sdhi: add ocr_mask option

Biju Das <biju.das@...>
 

From: Chris Brandt <chris.brandt@...>

commit f19417f38264f9a2f7b4627aa4060133c237b211 upstream.

In moving platforms from board files to DT, there still needs to be a way
to set the ocr_mask setting for the tmio driver during probe. Without this
setting, the probe will fail because the supported voltages are not known.

This patch will also traditional platform registration platforms to
migrate to DT.

Signed-off-by: Chris Brandt <chris.brandt@...>
Reviewed-by: Wolfram Sang <wsa+renesas@...>
Signed-off-by: Ulf Hansson <ulf.hansson@...>
Signed-off-by: Biju Das <biju.das@...>
---
drivers/mmc/host/sh_mobile_sdhi.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index 3d186cc..9124246 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -49,6 +49,7 @@

struct sh_mobile_sdhi_of_data {
unsigned long tmio_flags;
+ u32 tmio_ocr_mask;
unsigned long capabilities;
unsigned long capabilities2;
enum dma_slave_buswidth dma_buswidth;
@@ -370,6 +371,7 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev)
const struct sh_mobile_sdhi_of_data *of_data = of_id->data;

mmc_data->flags |= of_data->tmio_flags;
+ mmc_data->ocr_mask = of_data->tmio_ocr_mask;
mmc_data->capabilities |= of_data->capabilities;
mmc_data->capabilities2 |= of_data->capabilities2;
mmc_data->dma_rx_offset = of_data->dma_rx_offset;
--
2.7.4


[PATCH 4.4.y-cip 35/83] mmc: add define for R1 response without CRC

Biju Das <biju.das@...>
 

From: Wolfram Sang <wsa+renesas@...>

commit 51b50c961676428cd356d6fa494a2e9f53dc77bf upstream.

The core uses it for polling. Give drivers a proper define handle this
case like for other response types.

Signed-off-by: Wolfram Sang <wsa+renesas@...>
Signed-off-by: Ulf Hansson <ulf.hansson@...>
Signed-off-by: Biju Das <biju.das@...>
---
include/linux/mmc/core.h | 3 +++
1 file changed, 3 insertions(+)

diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
index 37967b6..6c2e285 100644
--- a/include/linux/mmc/core.h
+++ b/include/linux/mmc/core.h
@@ -55,6 +55,9 @@ struct mmc_command {
#define MMC_RSP_R6 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
#define MMC_RSP_R7 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)

+/* Can be used by core to poll after switch to MMC HS mode */
+#define MMC_RSP_R1_NO_CRC (MMC_RSP_PRESENT|MMC_RSP_OPCODE)
+
#define mmc_resp_type(cmd) ((cmd)->flags & (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC|MMC_RSP_BUSY|MMC_RSP_OPCODE))

/*
--
2.7.4


[PATCH 4.4.y-cip 34/83] mmc: tmio-mmc: add support for 32bit data port

Biju Das <biju.das@...>
 

From: Chris Brandt <chris.brandt@...>

commit 8185e51f358a8dd4801b67e8c66f03eb9eeaba75 upstream.

For the r7s72100 SOC, the DATA_PORT register was changed to 32-bits wide.
Therefore a new flag has been created that will allow 32-bit reads/writes
to the DATA_PORT register instead of 16-bit (because 16-bits accesses are
not supported).

Signed-off-by: Chris Brandt <chris.brandt@...>
Reviewed-by: Wolfram Sang <wsa+renesas@...>
Signed-off-by: Ulf Hansson <ulf.hansson@...>
Signed-off-by: Biju Das <biju.das@...>
---
drivers/mmc/host/tmio_mmc.h | 12 ++++++++++++
drivers/mmc/host/tmio_mmc_pio.c | 30 ++++++++++++++++++++++++++++++
include/linux/mfd/tmio.h | 5 +++++
3 files changed, 47 insertions(+)

diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index eafd92d..c4131d9 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -245,6 +245,12 @@ static inline u32 sd_ctrl_read16_and_16_as_32(struct tmio_mmc_host *host, int ad
readw(host->ctl + ((addr + 2) << host->bus_shift)) << 16;
}

+static inline void sd_ctrl_read32_rep(struct tmio_mmc_host *host, int addr,
+ u32 *buf, int count)
+{
+ readsl(host->ctl + (addr << host->bus_shift), buf, count);
+}
+
static inline void sd_ctrl_write16(struct tmio_mmc_host *host, int addr, u16 val)
{
/* If there is a hook and it returns non-zero then there
@@ -267,4 +273,10 @@ static inline void sd_ctrl_write32_as_16_and_16(struct tmio_mmc_host *host, int
writew(val >> 16, host->ctl + ((addr + 2) << host->bus_shift));
}

+static inline void sd_ctrl_write32_rep(struct tmio_mmc_host *host, int addr,
+ const u32 *buf, int count)
+{
+ writesl(host->ctl + (addr << host->bus_shift), buf, count);
+}
+
#endif
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index c927916..4d9e17a 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -393,6 +393,36 @@ static void tmio_mmc_transfer_data(struct tmio_mmc_host *host,
/*
* Transfer the data
*/
+ if (host->pdata->flags & TMIO_MMC_32BIT_DATA_PORT) {
+ u8 data[4] = { };
+
+ if (is_read)
+ sd_ctrl_read32_rep(host, CTL_SD_DATA_PORT, (u32 *)buf,
+ count >> 2);
+ else
+ sd_ctrl_write32_rep(host, CTL_SD_DATA_PORT, (u32 *)buf,
+ count >> 2);
+
+ /* if count was multiple of 4 */
+ if (!(count & 0x3))
+ return;
+
+ buf8 = (u8 *)(buf + (count >> 2));
+ count %= 4;
+
+ if (is_read) {
+ sd_ctrl_read32_rep(host, CTL_SD_DATA_PORT,
+ (u32 *)data, 1);
+ memcpy(buf8, data, count);
+ } else {
+ memcpy(data, buf8, count);
+ sd_ctrl_write32_rep(host, CTL_SD_DATA_PORT,
+ (u32 *)data, 1);
+ }
+
+ return;
+ }
+
if (is_read)
sd_ctrl_read16_rep(host, CTL_SD_DATA_PORT, buf, count >> 1);
else
diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h
index 7a26286..fba44ab 100644
--- a/include/linux/mfd/tmio.h
+++ b/include/linux/mfd/tmio.h
@@ -100,6 +100,11 @@
#define TMIO_MMC_SDIO_STATUS_QUIRK (1 << 8)

/*
+ * Some controllers have a 32-bit wide data port register
+ */
+#define TMIO_MMC_32BIT_DATA_PORT (1 << 9)
+
+/*
* Some controllers allows to set SDx actual clock
*/
#define TMIO_MMC_CLK_ACTUAL (1 << 10)
--
2.7.4


[PATCH 4.4.y-cip 33/83] mmc: tmio: add eMMC support

Biju Das <biju.das@...>
 

From: Wolfram Sang <wsa+renesas@...>

commit 0bc0b6e86524526c92a9409faea79d53db8e7e6e upstream.

We need to add R1 without CRC support, refactor the bus width routine a
little and extend a quirk check. To support "non-removable;" we need a
workaround which will be hopefully removed when reworking PM soon.

Signed-off-by: Wolfram Sang <wsa+renesas@...>
Signed-off-by: Ulf Hansson <ulf.hansson@...>
Signed-off-by: Biju Das <biju.das@...>
---
drivers/mmc/host/tmio_mmc.h | 3 +++
drivers/mmc/host/tmio_mmc_pio.c | 38 ++++++++++++++++++++++++++------------
2 files changed, 29 insertions(+), 12 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index addbc71..eafd92d 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -79,6 +79,9 @@
#define CLK_CTL_DIV_MASK 0xff
#define CLK_CTL_SCLKEN BIT(8)

+#define CARD_OPT_WIDTH8 BIT(13)
+#define CARD_OPT_WIDTH BIT(15)
+
#define TMIO_BBS 512 /* Boot block size */

/* Definitions for values the CTRL_SDIO_STATUS register can take. */
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index d499ed2..c927916 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -336,7 +336,9 @@ static int tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command

switch (mmc_resp_type(cmd)) {
case MMC_RSP_NONE: c |= RESP_NONE; break;
- case MMC_RSP_R1: c |= RESP_R1; break;
+ case MMC_RSP_R1:
+ case MMC_RSP_R1_NO_CRC:
+ c |= RESP_R1; break;
case MMC_RSP_R1B: c |= RESP_R1B; break;
case MMC_RSP_R2: c |= RESP_R2; break;
case MMC_RSP_R3: c |= RESP_R3; break;
@@ -733,12 +735,13 @@ static int tmio_mmc_start_data(struct tmio_mmc_host *host,
pr_debug("setup data transfer: blocksize %08x nr_blocks %d\n",
data->blksz, data->blocks);

- /* Some hardware cannot perform 2 byte requests in 4 bit mode */
- if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4) {
+ /* Some hardware cannot perform 2 byte requests in 4/8 bit mode */
+ if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4 ||
+ host->mmc->ios.bus_width == MMC_BUS_WIDTH_8) {
int blksz_2bytes = pdata->flags & TMIO_MMC_BLKSZ_2BYTES;

if (data->blksz < 2 || (data->blksz < 4 && !blksz_2bytes)) {
- pr_err("%s: %d byte block unsupported in 4 bit mode\n",
+ pr_err("%s: %d byte block unsupported in 4/8 bit mode\n",
mmc_hostname(host->mmc), data->blksz);
return -EINVAL;
}
@@ -860,14 +863,16 @@ static void tmio_mmc_power_off(struct tmio_mmc_host *host)
static void tmio_mmc_set_bus_width(struct tmio_mmc_host *host,
unsigned char bus_width)
{
- switch (bus_width) {
- case MMC_BUS_WIDTH_1:
- sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x80e0);
- break;
- case MMC_BUS_WIDTH_4:
- sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x00e0);
- break;
- }
+ u16 reg = sd_ctrl_read16(host, CTL_SD_MEM_CARD_OPT)
+ & ~(CARD_OPT_WIDTH | CARD_OPT_WIDTH8);
+
+ /* reg now applies to MMC_BUS_WIDTH_4 */
+ if (bus_width == MMC_BUS_WIDTH_1)
+ reg |= CARD_OPT_WIDTH;
+ else if (bus_width == MMC_BUS_WIDTH_8)
+ reg |= CARD_OPT_WIDTH8;
+
+ sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, reg);
}

/* Set MMC clock / power.
@@ -1085,6 +1090,15 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host,
mmc->caps & MMC_CAP_NONREMOVABLE ||
mmc->slot.cd_irq >= 0);

+ /*
+ * On Gen2+, eMMC with NONREMOVABLE currently fails because native
+ * hotplug gets disabled. It seems RuntimePM related yet we need further
+ * research. Since we are planning a PM overhaul anyway, let's enforce
+ * for now the device being active by enabling native hotplug always.
+ */
+ if (pdata->flags & TMIO_MMC_MIN_RCAR2)
+ _host->native_hotplug = true;
+
if (tmio_mmc_clk_enable(_host) < 0) {
mmc->f_max = pdata->hclk;
mmc->f_min = mmc->f_max / 512;
--
2.7.4


[PATCH 4.4.y-cip 32/83] mmc: host: sh_mobile_sdhi: don't populate unneeded functions

Biju Das <biju.das@...>
 

From: Wolfram Sang <wsa+renesas@...>

commit ff026099d775c74548839f1d627eb0b2bec0b857 upstream.

Populating card_busy caused a side-effect on a chip variant we don't
have documentation for (r8a73a4). So, enable it and voltage switching
only on devices known to support those features.

Signed-off-by: Wolfram Sang <wsa+renesas@...>
Tested-by: Geert Uytterhoeven <geert+renesas@...>
Signed-off-by: Ulf Hansson <ulf.hansson@...>
Fixes: 452e5eef6d31 ("mmc: tmio: Add UHS-I mode support")
Signed-off-by: Biju Das <biju.das@...>
---
drivers/mmc/host/sh_mobile_sdhi.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index 343aa1a..3d186cc 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -383,8 +383,14 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev)
host->clk_update = sh_mobile_sdhi_clk_update;
host->clk_disable = sh_mobile_sdhi_clk_disable;
host->multi_io_quirk = sh_mobile_sdhi_multi_io_quirk;
- host->card_busy = sh_mobile_sdhi_card_busy;
- host->start_signal_voltage_switch = sh_mobile_sdhi_start_signal_voltage_switch;
+
+ /* SDR speeds are only available on Gen2+ */
+ if (mmc_data->flags & TMIO_MMC_MIN_RCAR2) {
+ /* card_busy caused issues on r8a73a4 (pre-Gen2) CD-less SDHI */
+ host->card_busy = sh_mobile_sdhi_card_busy;
+ host->start_signal_voltage_switch =
+ sh_mobile_sdhi_start_signal_voltage_switch;
+ }

/* Orginally registers were 16 bit apart, could be 32 or 64 nowadays */
if (!host->bus_shift && resource_size(res) > 0x100) /* old way to determine the shift */
--
2.7.4


[PATCH 4.4.y-cip 31/83] mmc: host: sh_mobile_sdhi: move card_busy from tmio to sdhi

Biju Das <biju.das@...>
 

From: Wolfram Sang <wsa+renesas@...>

commit 6a4679f312357ac7c74c0e1b996efdd1d0a612fa upstream.

card_busy is only used/tested on SDHI for R-Car Gen2 and later.
Move it to the SDHI driver, so we can then activate it conditionally
depending on the SDHI type.

Signed-off-by: Wolfram Sang <wsa+renesas@...>
Tested-by: Geert Uytterhoeven <geert+renesas@...>
Signed-off-by: Ulf Hansson <ulf.hansson@...>
Signed-off-by: Biju Das <biju.das@...>
---
drivers/mmc/host/sh_mobile_sdhi.c | 8 ++++++++
drivers/mmc/host/tmio_mmc.h | 1 +
drivers/mmc/host/tmio_mmc_pio.c | 9 +--------
3 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index 62b6605..343aa1a 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -217,6 +217,13 @@ static void sh_mobile_sdhi_clk_disable(struct tmio_mmc_host *host)
clk_disable_unprepare(priv->clk);
}

+static int sh_mobile_sdhi_card_busy(struct mmc_host *mmc)
+{
+ struct tmio_mmc_host *host = mmc_priv(mmc);
+
+ return !(sd_ctrl_read16_and_16_as_32(host, CTL_STATUS) & TMIO_STAT_DAT0);
+}
+
static int sh_mobile_sdhi_start_signal_voltage_switch(struct mmc_host *mmc,
struct mmc_ios *ios)
{
@@ -376,6 +383,7 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev)
host->clk_update = sh_mobile_sdhi_clk_update;
host->clk_disable = sh_mobile_sdhi_clk_disable;
host->multi_io_quirk = sh_mobile_sdhi_multi_io_quirk;
+ host->card_busy = sh_mobile_sdhi_card_busy;
host->start_signal_voltage_switch = sh_mobile_sdhi_start_signal_voltage_switch;

/* Orginally registers were 16 bit apart, could be 32 or 64 nowadays */
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index 1aac2ad..addbc71 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -158,6 +158,7 @@ struct tmio_mmc_host {
void (*clk_disable)(struct tmio_mmc_host *host);
int (*multi_io_quirk)(struct mmc_card *card,
unsigned int direction, int blk_size);
+ int (*card_busy)(struct mmc_host *mmc);
int (*start_signal_voltage_switch)(struct mmc_host *mmc,
struct mmc_ios *ios);
};
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index b14672d..d499ed2 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -963,20 +963,12 @@ static int tmio_multi_io_quirk(struct mmc_card *card,
return blk_size;
}

-static int tmio_mmc_card_busy(struct mmc_host *mmc)
-{
- struct tmio_mmc_host *host = mmc_priv(mmc);
-
- return !(sd_ctrl_read16_and_16_as_32(host, CTL_STATUS) & TMIO_STAT_DAT0);
-}
-
static struct mmc_host_ops tmio_mmc_ops = {
.request = tmio_mmc_request,
.set_ios = tmio_mmc_set_ios,
.get_ro = tmio_mmc_get_ro,
.get_cd = mmc_gpio_get_cd,
.enable_sdio_irq = tmio_mmc_enable_sdio_irq,
- .card_busy = tmio_mmc_card_busy,
.multi_io_quirk = tmio_multi_io_quirk,
};

@@ -1075,6 +1067,7 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host,
goto host_free;
}

+ tmio_mmc_ops.card_busy = _host->card_busy;
tmio_mmc_ops.start_signal_voltage_switch = _host->start_signal_voltage_switch;
mmc->ops = &tmio_mmc_ops;

--
2.7.4


[PATCH 4.4.y-cip 30/83] mmc: sh_mobile_sdhi: properly document R-Car versions

Biju Das <biju.das@...>
 

From: Wolfram Sang <wsa+renesas@...>

commit a2a16c77a1a2c951b5930c3182e2737cb13e1a53 upstream.

Replace hardcoded values with meaningful names and document what we
know.

Signed-off-by: Wolfram Sang <wsa+renesas@...>
Reviewed-by: Simon Horman <horms+renesas@...>
Signed-off-by: Ulf Hansson <ulf.hansson@...>
Signed-off-by: Biju Das <biju.das@...>
---
drivers/mmc/host/sh_mobile_sdhi.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index 814391b..62b6605 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -39,6 +39,12 @@

#define EXT_ACC 0xe4

+#define SDHI_VER_GEN2_SDR50 0x490c
+/* very old datasheets said 0x490c for SDR104, too. They are wrong! */
+#define SDHI_VER_GEN2_SDR104 0xcb0d
+#define SDHI_VER_GEN3_SD 0xcc10
+#define SDHI_VER_GEN3_SDMMC 0xcd10
+
#define host_to_priv(host) container_of((host)->pdata, struct sh_mobile_sdhi, mmc_data)

struct sh_mobile_sdhi_of_data {
@@ -113,14 +119,14 @@ static void sh_mobile_sdhi_sdbuf_width(struct tmio_mmc_host *host, int width)
* sh_mobile_sdhi_of_data :: dma_buswidth
*/
switch (sd_ctrl_read16(host, CTL_VERSION)) {
- case 0x490C:
+ case SDHI_VER_GEN2_SDR50:
val = (width == 32) ? 0x0001 : 0x0000;
break;
- case 0xCB0D:
+ case SDHI_VER_GEN2_SDR104:
val = (width == 32) ? 0x0000 : 0x0001;
break;
- case 0xCC10: /* Gen3, SD only */
- case 0xCD10: /* Gen3, SD + MMC */
+ case SDHI_VER_GEN3_SD:
+ case SDHI_VER_GEN3_SDMMC:
if (width == 64)
val = 0x0000;
else if (width == 32)
--
2.7.4


[PATCH 4.4.y-cip 29/83] mmc: sh_mobile_sdhi: check return value when changing clk

Biju Das <biju.das@...>
 

From: Wolfram Sang <wsa+renesas@...>

commit f3f44d512cafef7e3d2cb140f642786dd6ec8818 upstream.

And return the old clock rate if something went wrong.

Signed-off-by: Wolfram Sang <wsa+renesas@...>
Tested-by: Geert Uytterhoeven <geert+renesas@...>
Signed-off-by: Ulf Hansson <ulf.hansson@...>
Signed-off-by: Biju Das <biju.das@...>
---
drivers/mmc/host/sh_mobile_sdhi.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index d5e4000..814391b 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -170,7 +170,7 @@ static unsigned int sh_mobile_sdhi_clk_update(struct tmio_mmc_host *host,
{
struct sh_mobile_sdhi *priv = host_to_priv(host);
unsigned int freq, diff, best_freq = 0, diff_min = ~0;
- int i;
+ int i, ret;

/* tested only on RCar Gen2+ currently; may work for others */
if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2))
@@ -199,9 +199,9 @@ static unsigned int sh_mobile_sdhi_clk_update(struct tmio_mmc_host *host,
}
}

- clk_set_rate(priv->clk, best_freq);
+ ret = clk_set_rate(priv->clk, best_freq);

- return best_freq;
+ return ret == 0 ? best_freq : clk_get_rate(priv->clk);
}

static void sh_mobile_sdhi_clk_disable(struct tmio_mmc_host *host)
--
2.7.4


[PATCH 4.4.y-cip 28/83] mmc: sh_mobile_sdhi: only change the clock on RCar Gen2+

Biju Das <biju.das@...>
 

From: Wolfram Sang <wsa+renesas@...>

commit 8fc009986471729533fb1246c7ea9395635dac26 upstream.

We had a regression on r8a7740 where the SDHI clock was a generic
peripheral clock, so changing its rate was not desired. This should be
fixed in the clock driver. However, it also shows that the new clock
calculation should only be used on tested systems. Add a check for that.

Signed-off-by: Wolfram Sang <wsa+renesas@...>
Tested-by: Geert Uytterhoeven <geert+renesas@...>
Signed-off-by: Ulf Hansson <ulf.hansson@...>
Signed-off-by: Biju Das <biju.das@...>
---
drivers/mmc/host/sh_mobile_sdhi.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index efa4fca..d5e4000 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -172,6 +172,10 @@ static unsigned int sh_mobile_sdhi_clk_update(struct tmio_mmc_host *host,
unsigned int freq, diff, best_freq = 0, diff_min = ~0;
int i;

+ /* tested only on RCar Gen2+ currently; may work for others */
+ if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2))
+ return clk_get_rate(priv->clk);
+
/*
* We want the bus clock to be as close as possible to, but no
* greater than, new_clock. As we can divide by 1 << i for
--
2.7.4


[PATCH 4.4.y-cip 27/83] mmc: sh_mobile_sdhi: make clk_update function more compact

Biju Das <biju.das@...>
 

From: Wolfram Sang <wsa+renesas@...>

commit 3072ba8cd95bd0e7fbe9a3a1c9b61fb190257855 upstream.

Save a few lines, the codebase is large enough.

Signed-off-by: Wolfram Sang <wsa+renesas@...>
Tested-by: Geert Uytterhoeven <geert+renesas@...>
Signed-off-by: Ulf Hansson <ulf.hansson@...>
Signed-off-by: Biju Das <biju.das@...>
---
drivers/mmc/host/sh_mobile_sdhi.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index f7317cf..efa4fca 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -169,12 +169,9 @@ static unsigned int sh_mobile_sdhi_clk_update(struct tmio_mmc_host *host,
unsigned int new_clock)
{
struct sh_mobile_sdhi *priv = host_to_priv(host);
- unsigned int freq, best_freq, diff_min, diff;
+ unsigned int freq, diff, best_freq = 0, diff_min = ~0;
int i;

- diff_min = ~0;
- best_freq = 0;
-
/*
* We want the bus clock to be as close as possible to, but no
* greater than, new_clock. As we can divide by 1 << i for
--
2.7.4


[PATCH 4.4.y-cip 26/83] mmc: tmio/sdhi: introduce flag for RCar 2+ specific features

Biju Das <biju.das@...>
 

From: Wolfram Sang <wsa+renesas@...>

commit 3d376fb2ea907f0c1bbccf87125456439feb4ed4 upstream.

RCar Gen2 and later implementations of TMIO/SDHI have their own set of
features and additions. FAST_CLK_CHG is just one of them and I see a few
others being added soon. Some may work on older chipsets but this needs
to be tested case by case. Instead of adding a bunch of flags for each
feature, add a global RCar2+ one for now. We can still break out
features if the need arises.

Signed-off-by: Wolfram Sang <wsa+renesas@...>
Tested-by: Geert Uytterhoeven <geert+renesas@...>
Signed-off-by: Ulf Hansson <ulf.hansson@...>
Signed-off-by: Biju Das <biju.das@...>
---
drivers/mmc/host/sh_mobile_sdhi.c | 4 ++--
drivers/mmc/host/tmio_mmc_pio.c | 6 +++---
include/linux/mfd/tmio.h | 4 ++--
3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index 7bb2900..f7317cf 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -64,7 +64,7 @@ static const struct sh_mobile_sdhi_of_data of_rcar_gen1_compatible = {

static const struct sh_mobile_sdhi_of_data of_rcar_gen2_compatible = {
.tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_WRPROTECT_DISABLE |
- TMIO_MMC_CLK_ACTUAL | TMIO_MMC_FAST_CLK_CHG,
+ TMIO_MMC_CLK_ACTUAL | TMIO_MMC_MIN_RCAR2,
.capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ,
.dma_buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES,
.dma_rx_offset = 0x2000,
@@ -72,7 +72,7 @@ static const struct sh_mobile_sdhi_of_data of_rcar_gen2_compatible = {

static const struct sh_mobile_sdhi_of_data of_rcar_gen3_compatible = {
.tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_WRPROTECT_DISABLE |
- TMIO_MMC_CLK_ACTUAL | TMIO_MMC_FAST_CLK_CHG,
+ TMIO_MMC_CLK_ACTUAL | TMIO_MMC_MIN_RCAR2,
.capabilities = MMC_CAP_SD_HIGHSPEED,
.bus_shift = 2,
};
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index dbad002..b14672d 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -157,7 +157,7 @@ static void tmio_mmc_clk_start(struct tmio_mmc_host *host)
{
sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN |
sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
- msleep(host->pdata->flags & TMIO_MMC_FAST_CLK_CHG ? 1 : 10);
+ msleep(host->pdata->flags & TMIO_MMC_MIN_RCAR2 ? 1 : 10);

if (host->pdata->flags & TMIO_MMC_HAVE_HIGH_REG) {
sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0100);
@@ -174,7 +174,7 @@ static void tmio_mmc_clk_stop(struct tmio_mmc_host *host)

sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN &
sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
- msleep(host->pdata->flags & TMIO_MMC_FAST_CLK_CHG ? 5 : 10);
+ msleep(host->pdata->flags & TMIO_MMC_MIN_RCAR2 ? 5 : 10);
}

static void tmio_mmc_set_clock(struct tmio_mmc_host *host,
@@ -205,7 +205,7 @@ static void tmio_mmc_set_clock(struct tmio_mmc_host *host,
sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN &
sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & CLK_CTL_DIV_MASK);
- if (!(host->pdata->flags & TMIO_MMC_FAST_CLK_CHG))
+ if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2))
msleep(10);

tmio_mmc_clk_start(host);
diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h
index 05d58ee..7a26286 100644
--- a/include/linux/mfd/tmio.h
+++ b/include/linux/mfd/tmio.h
@@ -66,8 +66,8 @@
*/
#define TMIO_MMC_SDIO_IRQ (1 << 2)

-/* Some controllers don't need to wait 10ms for clock changes */
-#define TMIO_MMC_FAST_CLK_CHG (1 << 3)
+/* Some features are only available or tested on RCar Gen2 or later */
+#define TMIO_MMC_MIN_RCAR2 (1 << 3)

/*
* Some controllers require waiting for the SD bus to become
--
2.7.4


[PATCH 4.4.y-cip 25/83] mmc: tmio: document CTL_STATUS handling

Biju Das <biju.das@...>
 

From: Wolfram Sang <wsa+renesas@...>

commit 184adf202bca05ca34380cb53b349307aede7ef3 upstream.

Now that reading CTL_STATUS is consistent, we can remove CTL_STATUS2 and
document how this is handled internally.

Reviewed-by: Simon Horman <horms+renesas@...>
Signed-off-by: Wolfram Sang <wsa+renesas@...>
Signed-off-by: Ulf Hansson <ulf.hansson@...>
Signed-off-by: Biju Das <biju.das@...>
---
drivers/mmc/host/tmio_mmc.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index 8dd5ea4..1aac2ad 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -30,8 +30,9 @@
#define CTL_STOP_INTERNAL_ACTION 0x08
#define CTL_XFER_BLK_COUNT 0xa
#define CTL_RESPONSE 0x0c
+/* driver merges STATUS and following STATUS2 */
#define CTL_STATUS 0x1c
-#define CTL_STATUS2 0x1e
+/* driver merges IRQ_MASK and following IRQ_MASK2 */
#define CTL_IRQ_MASK 0x20
#define CTL_SD_CARD_CLK_CTL 0x24
#define CTL_SD_XFER_LEN 0x26
--
2.7.4


[PATCH 4.4.y-cip 24/83] mmc: tmio/sdhi: distinguish between SCLKDIVEN and ILL_FUNC

Biju Das <biju.das@...>
 

From: Wolfram Sang <wsa+renesas@...>

commit a21553c9e0c236ae241d9f4333aafae24ae19dfc upstream.

This bit has a different meaning in SDHI and original TMIO. Document
that and use the proper naming.

Reviewed-by: Simon Horman <horms+renesas@...>
Signed-off-by: Wolfram Sang <wsa+renesas@...>
Signed-off-by: Ulf Hansson <ulf.hansson@...>
Signed-off-by: Biju Das <biju.das@...>
---
drivers/mmc/host/sh_mobile_sdhi.c | 3 ++-
drivers/mmc/host/tmio_mmc.h | 3 ++-
drivers/mmc/host/tmio_mmc_pio.c | 2 +-
3 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index ea78c77..7bb2900 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -252,7 +252,8 @@ static int sh_mobile_sdhi_wait_idle(struct tmio_mmc_host *host)
{
int timeout = 1000;

- while (--timeout && !(sd_ctrl_read16(host, CTL_STATUS2) & (1 << 13)))
+ while (--timeout && !(sd_ctrl_read16_and_16_as_32(host, CTL_STATUS)
+ & TMIO_STAT_SCLKDIVEN))
udelay(1);

if (!timeout) {
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index 55f251f..8dd5ea4 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -70,7 +70,8 @@
#define TMIO_STAT_DAT0 BIT(23) /* only known on R-Car so far */
#define TMIO_STAT_RXRDY BIT(24)
#define TMIO_STAT_TXRQ BIT(25)
-#define TMIO_STAT_ILL_FUNC BIT(29)
+#define TMIO_STAT_ILL_FUNC BIT(29) /* only when !TMIO_MMC_HAS_IDLE_WAIT */
+#define TMIO_STAT_SCLKDIVEN BIT(29) /* only when TMIO_MMC_HAS_IDLE_WAIT */
#define TMIO_STAT_CMD_BUSY BIT(30)
#define TMIO_STAT_ILL_ACCESS BIT(31)

diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index 3a9620f..dbad002 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -542,7 +542,7 @@ static void tmio_mmc_data_irq(struct tmio_mmc_host *host)
* waiting for one more interrupt fixes the problem.
*/
if (host->pdata->flags & TMIO_MMC_HAS_IDLE_WAIT) {
- if (status & TMIO_STAT_ILL_FUNC)
+ if (status & TMIO_STAT_SCLKDIVEN)
done = true;
} else {
if (!(status & TMIO_STAT_CMD_BUSY))
--
2.7.4


[PATCH 4.4.y-cip 23/83] mmc: tmio: use CTL_STATUS consistently

Biju Das <biju.das@...>
 

From: Wolfram Sang <wsa+renesas@...>

commit 83e95351d49f60d6cf37706bf94529116d03e648 upstream.

To prevent confusion, use the virtual u32 CTL_STATUS in card_busy() the
same way as in other parts of this driver.

Reviewed-by: Simon Horman <horms+renesas@...>
Signed-off-by: Wolfram Sang <wsa+renesas@...>
Signed-off-by: Ulf Hansson <ulf.hansson@...>
Signed-off-by: Biju Das <biju.das@...>
---
drivers/mmc/host/tmio_mmc.h | 3 +--
drivers/mmc/host/tmio_mmc_pio.c | 2 +-
2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index 74945c1a..55f251f 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -67,14 +67,13 @@
#define TMIO_STAT_RXOVERFLOW BIT(20)
#define TMIO_STAT_TXUNDERRUN BIT(21)
#define TMIO_STAT_CMDTIMEOUT BIT(22)
+#define TMIO_STAT_DAT0 BIT(23) /* only known on R-Car so far */
#define TMIO_STAT_RXRDY BIT(24)
#define TMIO_STAT_TXRQ BIT(25)
#define TMIO_STAT_ILL_FUNC BIT(29)
#define TMIO_STAT_CMD_BUSY BIT(30)
#define TMIO_STAT_ILL_ACCESS BIT(31)

-#define TMIO_STATUS2_DAT0 BIT(7)
-
#define CLK_CTL_DIV_MASK 0xff
#define CLK_CTL_SCLKEN BIT(8)

diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index fcc6879..3a9620f 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -967,7 +967,7 @@ static int tmio_mmc_card_busy(struct mmc_host *mmc)
{
struct tmio_mmc_host *host = mmc_priv(mmc);

- return !(sd_ctrl_read16_and_16_as_32(host, CTL_STATUS2) & TMIO_STATUS2_DAT0);
+ return !(sd_ctrl_read16_and_16_as_32(host, CTL_STATUS) & TMIO_STAT_DAT0);
}

static struct mmc_host_ops tmio_mmc_ops = {
--
2.7.4


[PATCH 4.4.y-cip 22/83] mmc: tmio: use BIT() within defines

Biju Das <biju.das@...>
 

From: Wolfram Sang <wsa+renesas@...>

commit 2cafc5cb4fcbe648d0d16ec5039ee292d85d7bfa upstream.

BIT() makes it easier to match the bits to the datasheet. This is
especially important here, since some variants have different names in
their datasheets (like with Renesas R-Car).

Reviewed-by: Simon Horman <horms+renesas@...>
Signed-off-by: Wolfram Sang <wsa+renesas@...>
Signed-off-by: Ulf Hansson <ulf.hansson@...>
Signed-off-by: Biju Das <biju.das@...>
---
drivers/mmc/host/tmio_mmc.h | 44 +++++++++++++++++++++++---------------------
1 file changed, 23 insertions(+), 21 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index e75e5ca..74945c1a 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -49,27 +49,29 @@
#define CTL_RESET_SDIO 0x1e0

/* Definitions for values the CTRL_STATUS register can take. */
-#define TMIO_STAT_CMDRESPEND 0x00000001
-#define TMIO_STAT_DATAEND 0x00000004
-#define TMIO_STAT_CARD_REMOVE 0x00000008
-#define TMIO_STAT_CARD_INSERT 0x00000010
-#define TMIO_STAT_SIGSTATE 0x00000020
-#define TMIO_STAT_WRPROTECT 0x00000080
-#define TMIO_STAT_CARD_REMOVE_A 0x00000100
-#define TMIO_STAT_CARD_INSERT_A 0x00000200
-#define TMIO_STAT_SIGSTATE_A 0x00000400
-#define TMIO_STAT_CMD_IDX_ERR 0x00010000
-#define TMIO_STAT_CRCFAIL 0x00020000
-#define TMIO_STAT_STOPBIT_ERR 0x00040000
-#define TMIO_STAT_DATATIMEOUT 0x00080000
-#define TMIO_STAT_RXOVERFLOW 0x00100000
-#define TMIO_STAT_TXUNDERRUN 0x00200000
-#define TMIO_STAT_CMDTIMEOUT 0x00400000
-#define TMIO_STAT_RXRDY 0x01000000
-#define TMIO_STAT_TXRQ 0x02000000
-#define TMIO_STAT_ILL_FUNC 0x20000000
-#define TMIO_STAT_CMD_BUSY 0x40000000
-#define TMIO_STAT_ILL_ACCESS 0x80000000
+#define TMIO_STAT_CMDRESPEND BIT(0)
+#define TMIO_STAT_DATAEND BIT(2)
+#define TMIO_STAT_CARD_REMOVE BIT(3)
+#define TMIO_STAT_CARD_INSERT BIT(4)
+#define TMIO_STAT_SIGSTATE BIT(5)
+#define TMIO_STAT_WRPROTECT BIT(7)
+#define TMIO_STAT_CARD_REMOVE_A BIT(8)
+#define TMIO_STAT_CARD_INSERT_A BIT(9)
+#define TMIO_STAT_SIGSTATE_A BIT(10)
+
+/* These belong technically to CTRL_STATUS2, but the driver merges them */
+#define TMIO_STAT_CMD_IDX_ERR BIT(16)
+#define TMIO_STAT_CRCFAIL BIT(17)
+#define TMIO_STAT_STOPBIT_ERR BIT(18)
+#define TMIO_STAT_DATATIMEOUT BIT(19)
+#define TMIO_STAT_RXOVERFLOW BIT(20)
+#define TMIO_STAT_TXUNDERRUN BIT(21)
+#define TMIO_STAT_CMDTIMEOUT BIT(22)
+#define TMIO_STAT_RXRDY BIT(24)
+#define TMIO_STAT_TXRQ BIT(25)
+#define TMIO_STAT_ILL_FUNC BIT(29)
+#define TMIO_STAT_CMD_BUSY BIT(30)
+#define TMIO_STAT_ILL_ACCESS BIT(31)

#define TMIO_STATUS2_DAT0 BIT(7)

--
2.7.4


[PATCH 4.4.y-cip 21/83] mmc: tmio: give read32/write32 functions more descriptive names

Biju Das <biju.das@...>
 

From: Wolfram Sang <wsa+renesas@...>

commit 2c54506b769d0633aac8f0511ef23f76bedeec9e upstream.

Looking at the backlogs, I am not the only one who missed that the above
functions do not read u32 from one register, but create a virtual u32
from reading to adjacent u16 registers (which depending on 'bus_shift'
can be up to 8 byte apart). Because this driver supports old hardware
for which we don't have documentation, I first wrongly assumed there was
a variant which had a few u32 registers. Let's give the functions more
descriptive names to make it more obvious what is happening.

Reviewed-by: Simon Horman <horms+renesas@...>
Signed-off-by: Wolfram Sang <wsa+renesas@...>
Signed-off-by: Ulf Hansson <ulf.hansson@...>
Signed-off-by: Biju Das <biju.das@...>
---
drivers/mmc/host/tmio_mmc.h | 5 ++---
drivers/mmc/host/tmio_mmc_pio.c | 22 +++++++++++-----------
2 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index 439fdad..e75e5ca 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -232,7 +232,7 @@ static inline void sd_ctrl_read16_rep(struct tmio_mmc_host *host, int addr,
readsw(host->ctl + (addr << host->bus_shift), buf, count);
}

-static inline u32 sd_ctrl_read32(struct tmio_mmc_host *host, int addr)
+static inline u32 sd_ctrl_read16_and_16_as_32(struct tmio_mmc_host *host, int addr)
{
return readw(host->ctl + (addr << host->bus_shift)) |
readw(host->ctl + ((addr + 2) << host->bus_shift)) << 16;
@@ -254,11 +254,10 @@ static inline void sd_ctrl_write16_rep(struct tmio_mmc_host *host, int addr,
writesw(host->ctl + (addr << host->bus_shift), buf, count);
}

-static inline void sd_ctrl_write32(struct tmio_mmc_host *host, int addr, u32 val)
+static inline void sd_ctrl_write32_as_16_and_16(struct tmio_mmc_host *host, int addr, u32 val)
{
writew(val, host->ctl + (addr << host->bus_shift));
writew(val >> 16, host->ctl + ((addr + 2) << host->bus_shift));
}

-
#endif
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index 78fd343..fcc6879 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -55,18 +55,18 @@
void tmio_mmc_enable_mmc_irqs(struct tmio_mmc_host *host, u32 i)
{
host->sdcard_irq_mask &= ~(i & TMIO_MASK_IRQ);
- sd_ctrl_write32(host, CTL_IRQ_MASK, host->sdcard_irq_mask);
+ sd_ctrl_write32_as_16_and_16(host, CTL_IRQ_MASK, host->sdcard_irq_mask);
}

void tmio_mmc_disable_mmc_irqs(struct tmio_mmc_host *host, u32 i)
{
host->sdcard_irq_mask |= (i & TMIO_MASK_IRQ);
- sd_ctrl_write32(host, CTL_IRQ_MASK, host->sdcard_irq_mask);
+ sd_ctrl_write32_as_16_and_16(host, CTL_IRQ_MASK, host->sdcard_irq_mask);
}

static void tmio_mmc_ack_mmc_irqs(struct tmio_mmc_host *host, u32 i)
{
- sd_ctrl_write32(host, CTL_STATUS, ~i);
+ sd_ctrl_write32_as_16_and_16(host, CTL_STATUS, ~i);
}

static void tmio_mmc_init_sg(struct tmio_mmc_host *host, struct mmc_data *data)
@@ -375,7 +375,7 @@ static int tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command
tmio_mmc_enable_mmc_irqs(host, irq_mask);

/* Fire off the command */
- sd_ctrl_write32(host, CTL_ARG_REG, cmd->arg);
+ sd_ctrl_write32_as_16_and_16(host, CTL_ARG_REG, cmd->arg);
sd_ctrl_write16(host, CTL_SD_CMD, c);

return 0;
@@ -530,7 +530,7 @@ static void tmio_mmc_data_irq(struct tmio_mmc_host *host)
goto out;

if (host->chan_tx && (data->flags & MMC_DATA_WRITE) && !host->force_pio) {
- u32 status = sd_ctrl_read32(host, CTL_STATUS);
+ u32 status = sd_ctrl_read16_and_16_as_32(host, CTL_STATUS);
bool done = false;

/*
@@ -585,7 +585,7 @@ static void tmio_mmc_cmd_irq(struct tmio_mmc_host *host,
*/

for (i = 3, addr = CTL_RESPONSE ; i >= 0 ; i--, addr += 4)
- cmd->resp[i] = sd_ctrl_read32(host, addr);
+ cmd->resp[i] = sd_ctrl_read16_and_16_as_32(host, addr);

if (cmd->flags & MMC_RSP_136) {
cmd->resp[0] = (cmd->resp[0] << 8) | (cmd->resp[1] >> 24);
@@ -704,14 +704,14 @@ irqreturn_t tmio_mmc_irq(int irq, void *devid)
struct tmio_mmc_host *host = devid;
unsigned int ireg, status;

- status = sd_ctrl_read32(host, CTL_STATUS);
+ status = sd_ctrl_read16_and_16_as_32(host, CTL_STATUS);
ireg = status & TMIO_MASK_IRQ & ~host->sdcard_irq_mask;

pr_debug_status(status);
pr_debug_status(ireg);

/* Clear the status except the interrupt status */
- sd_ctrl_write32(host, CTL_STATUS, TMIO_MASK_IRQ);
+ sd_ctrl_write32_as_16_and_16(host, CTL_STATUS, TMIO_MASK_IRQ);

if (__tmio_mmc_card_detect_irq(host, ireg, status))
return IRQ_HANDLED;
@@ -947,7 +947,7 @@ static int tmio_mmc_get_ro(struct mmc_host *mmc)
return ret;

ret = !((pdata->flags & TMIO_MMC_WRPROTECT_DISABLE) ||
- (sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT));
+ (sd_ctrl_read16_and_16_as_32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT));

return ret;
}
@@ -967,7 +967,7 @@ static int tmio_mmc_card_busy(struct mmc_host *mmc)
{
struct tmio_mmc_host *host = mmc_priv(mmc);

- return !(sd_ctrl_read32(host, CTL_STATUS2) & TMIO_STATUS2_DAT0);
+ return !(sd_ctrl_read16_and_16_as_32(host, CTL_STATUS2) & TMIO_STATUS2_DAT0);
}

static struct mmc_host_ops tmio_mmc_ops = {
@@ -1116,7 +1116,7 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host,
tmio_mmc_clk_stop(_host);
tmio_mmc_reset(_host);

- _host->sdcard_irq_mask = sd_ctrl_read32(_host, CTL_IRQ_MASK);
+ _host->sdcard_irq_mask = sd_ctrl_read16_and_16_as_32(_host, CTL_IRQ_MASK);
tmio_mmc_disable_mmc_irqs(_host, TMIO_MASK_ALL);

/* Unmask the IRQs we want to know about */
--
2.7.4


[PATCH 4.4.y-cip 20/83] mmc: tmio: merge distributed include files

Biju Das <biju.das@...>
 

From: Wolfram Sang <wsa+renesas@...>

commit ac86045ee9cd89774030ff1c21c7ff35f1c1eeaa upstream.

There is no reason to have a public and private header file. Merge them
into a private one, so looking up symbols is less confusing.

Signed-off-by: Wolfram Sang <wsa+renesas@...>
Acked-by: Arnd Bergmann <arnd@...>
Signed-off-by: Ulf Hansson <ulf.hansson@...>
Signed-off-by: Biju Das <biju.das@...>
---
drivers/mmc/host/tmio_mmc.h | 56 ++++++++++++++++++++++++++++++-
drivers/mmc/host/tmio_mmc_dma.c | 1 -
drivers/mmc/host/tmio_mmc_pio.c | 1 -
include/linux/mmc/tmio.h | 73 -----------------------------------------
4 files changed, 55 insertions(+), 76 deletions(-)
delete mode 100644 include/linux/mmc/tmio.h

diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index 032188b..439fdad 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -1,6 +1,8 @@
/*
* linux/drivers/mmc/host/tmio_mmc.h
*
+ * Copyright (C) 2016 Sang Engineering, Wolfram Sang
+ * Copyright (C) 2015-16 Renesas Electronics Corporation
* Copyright (C) 2007 Ian Molton
* Copyright (C) 2004 Ian Molton
*
@@ -18,12 +20,64 @@

#include <linux/dmaengine.h>
#include <linux/highmem.h>
-#include <linux/mmc/tmio.h>
#include <linux/mutex.h>
#include <linux/pagemap.h>
#include <linux/scatterlist.h>
#include <linux/spinlock.h>

+#define CTL_SD_CMD 0x00
+#define CTL_ARG_REG 0x04
+#define CTL_STOP_INTERNAL_ACTION 0x08
+#define CTL_XFER_BLK_COUNT 0xa
+#define CTL_RESPONSE 0x0c
+#define CTL_STATUS 0x1c
+#define CTL_STATUS2 0x1e
+#define CTL_IRQ_MASK 0x20
+#define CTL_SD_CARD_CLK_CTL 0x24
+#define CTL_SD_XFER_LEN 0x26
+#define CTL_SD_MEM_CARD_OPT 0x28
+#define CTL_SD_ERROR_DETAIL_STATUS 0x2c
+#define CTL_SD_DATA_PORT 0x30
+#define CTL_TRANSACTION_CTL 0x34
+#define CTL_SDIO_STATUS 0x36
+#define CTL_SDIO_IRQ_MASK 0x38
+#define CTL_DMA_ENABLE 0xd8
+#define CTL_RESET_SD 0xe0
+#define CTL_VERSION 0xe2
+#define CTL_SDIO_REGS 0x100
+#define CTL_CLK_AND_WAIT_CTL 0x138
+#define CTL_RESET_SDIO 0x1e0
+
+/* Definitions for values the CTRL_STATUS register can take. */
+#define TMIO_STAT_CMDRESPEND 0x00000001
+#define TMIO_STAT_DATAEND 0x00000004
+#define TMIO_STAT_CARD_REMOVE 0x00000008
+#define TMIO_STAT_CARD_INSERT 0x00000010
+#define TMIO_STAT_SIGSTATE 0x00000020
+#define TMIO_STAT_WRPROTECT 0x00000080
+#define TMIO_STAT_CARD_REMOVE_A 0x00000100
+#define TMIO_STAT_CARD_INSERT_A 0x00000200
+#define TMIO_STAT_SIGSTATE_A 0x00000400
+#define TMIO_STAT_CMD_IDX_ERR 0x00010000
+#define TMIO_STAT_CRCFAIL 0x00020000
+#define TMIO_STAT_STOPBIT_ERR 0x00040000
+#define TMIO_STAT_DATATIMEOUT 0x00080000
+#define TMIO_STAT_RXOVERFLOW 0x00100000
+#define TMIO_STAT_TXUNDERRUN 0x00200000
+#define TMIO_STAT_CMDTIMEOUT 0x00400000
+#define TMIO_STAT_RXRDY 0x01000000
+#define TMIO_STAT_TXRQ 0x02000000
+#define TMIO_STAT_ILL_FUNC 0x20000000
+#define TMIO_STAT_CMD_BUSY 0x40000000
+#define TMIO_STAT_ILL_ACCESS 0x80000000
+
+#define TMIO_STATUS2_DAT0 BIT(7)
+
+#define CLK_CTL_DIV_MASK 0xff
+#define CLK_CTL_SCLKEN BIT(8)
+
+#define TMIO_BBS 512 /* Boot block size */
+
/* Definitions for values the CTRL_SDIO_STATUS register can take. */
#define TMIO_SDIO_STAT_IOIRQ 0x0001
#define TMIO_SDIO_STAT_EXPUB52 0x4000
diff --git a/drivers/mmc/host/tmio_mmc_dma.c b/drivers/mmc/host/tmio_mmc_dma.c
index 6754358..d157368 100644
--- a/drivers/mmc/host/tmio_mmc_dma.c
+++ b/drivers/mmc/host/tmio_mmc_dma.c
@@ -15,7 +15,6 @@
#include <linux/dmaengine.h>
#include <linux/mfd/tmio.h>
#include <linux/mmc/host.h>
-#include <linux/mmc/tmio.h>
#include <linux/pagemap.h>
#include <linux/scatterlist.h>

diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index f4f509c..78fd343 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -39,7 +39,6 @@
#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h>
#include <linux/mmc/slot-gpio.h>
-#include <linux/mmc/tmio.h>
#include <linux/module.h>
#include <linux/pagemap.h>
#include <linux/platform_device.h>
diff --git a/include/linux/mmc/tmio.h b/include/linux/mmc/tmio.h
deleted file mode 100644
index b2f28e9..0000000
--- a/include/linux/mmc/tmio.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * include/linux/mmc/tmio.h
- *
- * Copyright (C) 2016 Sang Engineering, Wolfram Sang
- * Copyright (C) 2015-16 Renesas Electronics Corporation
- * Copyright (C) 2007 Ian Molton
- * Copyright (C) 2004 Ian Molton
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Driver for the MMC / SD / SDIO cell found in:
- *
- * TC6393XB TC6391XB TC6387XB T7L66XB ASIC3
- */
-#ifndef LINUX_MMC_TMIO_H
-#define LINUX_MMC_TMIO_H
-
-#define CTL_SD_CMD 0x00
-#define CTL_ARG_REG 0x04
-#define CTL_STOP_INTERNAL_ACTION 0x08
-#define CTL_XFER_BLK_COUNT 0xa
-#define CTL_RESPONSE 0x0c
-#define CTL_STATUS 0x1c
-#define CTL_STATUS2 0x1e
-#define CTL_IRQ_MASK 0x20
-#define CTL_SD_CARD_CLK_CTL 0x24
-#define CTL_SD_XFER_LEN 0x26
-#define CTL_SD_MEM_CARD_OPT 0x28
-#define CTL_SD_ERROR_DETAIL_STATUS 0x2c
-#define CTL_SD_DATA_PORT 0x30
-#define CTL_TRANSACTION_CTL 0x34
-#define CTL_SDIO_STATUS 0x36
-#define CTL_SDIO_IRQ_MASK 0x38
-#define CTL_DMA_ENABLE 0xd8
-#define CTL_RESET_SD 0xe0
-#define CTL_VERSION 0xe2
-#define CTL_SDIO_REGS 0x100
-#define CTL_CLK_AND_WAIT_CTL 0x138
-#define CTL_RESET_SDIO 0x1e0
-
-/* Definitions for values the CTRL_STATUS register can take. */
-#define TMIO_STAT_CMDRESPEND 0x00000001
-#define TMIO_STAT_DATAEND 0x00000004
-#define TMIO_STAT_CARD_REMOVE 0x00000008
-#define TMIO_STAT_CARD_INSERT 0x00000010
-#define TMIO_STAT_SIGSTATE 0x00000020
-#define TMIO_STAT_WRPROTECT 0x00000080
-#define TMIO_STAT_CARD_REMOVE_A 0x00000100
-#define TMIO_STAT_CARD_INSERT_A 0x00000200
-#define TMIO_STAT_SIGSTATE_A 0x00000400
-#define TMIO_STAT_CMD_IDX_ERR 0x00010000
-#define TMIO_STAT_CRCFAIL 0x00020000
-#define TMIO_STAT_STOPBIT_ERR 0x00040000
-#define TMIO_STAT_DATATIMEOUT 0x00080000
-#define TMIO_STAT_RXOVERFLOW 0x00100000
-#define TMIO_STAT_TXUNDERRUN 0x00200000
-#define TMIO_STAT_CMDTIMEOUT 0x00400000
-#define TMIO_STAT_RXRDY 0x01000000
-#define TMIO_STAT_TXRQ 0x02000000
-#define TMIO_STAT_ILL_FUNC 0x20000000
-#define TMIO_STAT_CMD_BUSY 0x40000000
-#define TMIO_STAT_ILL_ACCESS 0x80000000
-
-#define TMIO_STATUS2_DAT0 BIT(7)
-
-#define CLK_CTL_DIV_MASK 0xff
-#define CLK_CTL_SCLKEN BIT(8)
-
-#define TMIO_BBS 512 /* Boot block size */
-
-#endif /* LINUX_MMC_TMIO_H */
--
2.7.4


[PATCH 4.4.y-cip 19/83] mmc: tmio: simplify irq handler

Biju Das <biju.das@...>
 

From: Wolfram Sang <wsa+renesas@...>

commit 958401266e5812619b04765bef23712a72badd55 upstream.

Having just one irq handler again, let's include the 'card_status'
function in the main handler which is way more readable. Drop a useless
debug output while here. It should be a dev_dbg in case we ever need it
again.

Signed-off-by: Wolfram Sang <wsa+renesas@...>
Acked-by: Arnd Bergmann <arnd@...>
Signed-off-by: Ulf Hansson <ulf.hansson@...>
Signed-off-by: Biju Das <biju.das@...>
---
drivers/mmc/host/tmio_mmc_pio.c | 23 ++++++++---------------
1 file changed, 8 insertions(+), 15 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index 1e050a4..f4f509c 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -626,19 +626,6 @@ out:
spin_unlock(&host->lock);
}

-static void tmio_mmc_card_irq_status(struct tmio_mmc_host *host,
- int *ireg, int *status)
-{
- *status = sd_ctrl_read32(host, CTL_STATUS);
- *ireg = *status & TMIO_MASK_IRQ & ~host->sdcard_irq_mask;
-
- pr_debug_status(*status);
- pr_debug_status(*ireg);
-
- /* Clear the status except the interrupt status */
- sd_ctrl_write32(host, CTL_STATUS, TMIO_MASK_IRQ);
-}
-
static bool __tmio_mmc_card_detect_irq(struct tmio_mmc_host *host,
int ireg, int status)
{
@@ -718,9 +705,15 @@ irqreturn_t tmio_mmc_irq(int irq, void *devid)
struct tmio_mmc_host *host = devid;
unsigned int ireg, status;

- pr_debug("MMC IRQ begin\n");
+ status = sd_ctrl_read32(host, CTL_STATUS);
+ ireg = status & TMIO_MASK_IRQ & ~host->sdcard_irq_mask;
+
+ pr_debug_status(status);
+ pr_debug_status(ireg);
+
+ /* Clear the status except the interrupt status */
+ sd_ctrl_write32(host, CTL_STATUS, TMIO_MASK_IRQ);

- tmio_mmc_card_irq_status(host, &ireg, &status);
if (__tmio_mmc_card_detect_irq(host, ireg, status))
return IRQ_HANDLED;
if (__tmio_mmc_sdcard_irq(host, ireg, status))
--
2.7.4

6501 - 6520 of 10122