Skip to content

Commit 59472e8

Browse files
xdarklightUlf Hansson
authored andcommitted
mmc: meson-mx-sdio: Switch to regmap for register access
Switch the driver over to use regmap to access the registers. This makes it consistent with the other Amlogic MMC drivers. No functional changes intended. Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
1 parent 989019c commit 59472e8

2 files changed

Lines changed: 64 additions & 62 deletions

File tree

drivers/mmc/host/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,7 @@ config MMC_MESON_MX_SDIO
504504
depends on ARCH_MESON || COMPILE_TEST
505505
depends on COMMON_CLK
506506
depends on OF_ADDRESS
507+
select REGMAP_MMIO
507508
help
508509
This selects support for the SD/MMC Host Controller on
509510
Amlogic Meson6, Meson8 and Meson8b SoCs.

drivers/mmc/host/meson-mx-sdio.c

Lines changed: 63 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <linux/ioport.h>
2020
#include <linux/platform_device.h>
2121
#include <linux/of_platform.h>
22+
#include <linux/regmap.h>
2223
#include <linux/timer.h>
2324
#include <linux/types.h>
2425

@@ -108,7 +109,7 @@ struct meson_mx_mmc_host {
108109
struct clk_fixed_factor fixed_factor;
109110
struct clk *fixed_factor_clk;
110111

111-
void __iomem *base;
112+
struct regmap *regmap;
112113
int irq;
113114
spinlock_t irq_lock;
114115

@@ -122,22 +123,10 @@ struct meson_mx_mmc_host {
122123
int error;
123124
};
124125

125-
static void meson_mx_mmc_mask_bits(struct mmc_host *mmc, char reg, u32 mask,
126-
u32 val)
127-
{
128-
struct meson_mx_mmc_host *host = mmc_priv(mmc);
129-
u32 regval;
130-
131-
regval = readl(host->base + reg);
132-
regval &= ~mask;
133-
regval |= (val & mask);
134-
135-
writel(regval, host->base + reg);
136-
}
137-
138126
static void meson_mx_mmc_soft_reset(struct meson_mx_mmc_host *host)
139127
{
140-
writel(MESON_MX_SDIO_IRQC_SOFT_RESET, host->base + MESON_MX_SDIO_IRQC);
128+
regmap_write(host->regmap, MESON_MX_SDIO_IRQC,
129+
MESON_MX_SDIO_IRQC_SOFT_RESET);
141130
udelay(2);
142131
}
143132

@@ -158,7 +147,7 @@ static void meson_mx_mmc_start_cmd(struct mmc_host *mmc,
158147
struct meson_mx_mmc_host *host = mmc_priv(mmc);
159148
unsigned int pack_size;
160149
unsigned long irqflags, timeout;
161-
u32 mult, send = 0, ext = 0;
150+
u32 send = 0, ext = 0;
162151

163152
host->cmd = cmd;
164153

@@ -215,25 +204,22 @@ static void meson_mx_mmc_start_cmd(struct mmc_host *mmc,
215204

216205
spin_lock_irqsave(&host->irq_lock, irqflags);
217206

218-
mult = readl(host->base + MESON_MX_SDIO_MULT);
219-
mult &= ~MESON_MX_SDIO_MULT_PORT_SEL_MASK;
220-
mult |= FIELD_PREP(MESON_MX_SDIO_MULT_PORT_SEL_MASK, host->slot_id);
221-
mult |= BIT(31);
222-
writel(mult, host->base + MESON_MX_SDIO_MULT);
207+
regmap_update_bits(host->regmap, MESON_MX_SDIO_MULT,
208+
MESON_MX_SDIO_MULT_PORT_SEL_MASK | BIT(31),
209+
FIELD_PREP(MESON_MX_SDIO_MULT_PORT_SEL_MASK,
210+
host->slot_id) | BIT(31));
223211

224212
/* enable the CMD done interrupt */
225-
meson_mx_mmc_mask_bits(mmc, MESON_MX_SDIO_IRQC,
226-
MESON_MX_SDIO_IRQC_ARC_CMD_INT_EN,
227-
MESON_MX_SDIO_IRQC_ARC_CMD_INT_EN);
213+
regmap_set_bits(host->regmap, MESON_MX_SDIO_IRQC,
214+
MESON_MX_SDIO_IRQC_ARC_CMD_INT_EN);
228215

229216
/* clear pending interrupts */
230-
meson_mx_mmc_mask_bits(mmc, MESON_MX_SDIO_IRQS,
231-
MESON_MX_SDIO_IRQS_CMD_INT,
232-
MESON_MX_SDIO_IRQS_CMD_INT);
217+
regmap_set_bits(host->regmap, MESON_MX_SDIO_IRQS,
218+
MESON_MX_SDIO_IRQS_CMD_INT);
233219

234-
writel(cmd->arg, host->base + MESON_MX_SDIO_ARGU);
235-
writel(ext, host->base + MESON_MX_SDIO_EXT);
236-
writel(send, host->base + MESON_MX_SDIO_SEND);
220+
regmap_write(host->regmap, MESON_MX_SDIO_ARGU, cmd->arg);
221+
regmap_write(host->regmap, MESON_MX_SDIO_EXT, ext);
222+
regmap_write(host->regmap, MESON_MX_SDIO_SEND, send);
237223

238224
spin_unlock_irqrestore(&host->irq_lock, irqflags);
239225

@@ -263,14 +249,13 @@ static void meson_mx_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
263249

264250
switch (ios->bus_width) {
265251
case MMC_BUS_WIDTH_1:
266-
meson_mx_mmc_mask_bits(mmc, MESON_MX_SDIO_CONF,
267-
MESON_MX_SDIO_CONF_BUS_WIDTH, 0);
252+
regmap_clear_bits(host->regmap, MESON_MX_SDIO_CONF,
253+
MESON_MX_SDIO_CONF_BUS_WIDTH);
268254
break;
269255

270256
case MMC_BUS_WIDTH_4:
271-
meson_mx_mmc_mask_bits(mmc, MESON_MX_SDIO_CONF,
272-
MESON_MX_SDIO_CONF_BUS_WIDTH,
273-
MESON_MX_SDIO_CONF_BUS_WIDTH);
257+
regmap_set_bits(host->regmap, MESON_MX_SDIO_CONF,
258+
MESON_MX_SDIO_CONF_BUS_WIDTH);
274259
break;
275260

276261
case MMC_BUS_WIDTH_8:
@@ -351,8 +336,8 @@ static void meson_mx_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
351336
host->mrq = mrq;
352337

353338
if (mrq->data)
354-
writel(sg_dma_address(mrq->data->sg),
355-
host->base + MESON_MX_SDIO_ADDR);
339+
regmap_write(host->regmap, MESON_MX_SDIO_ADDR,
340+
sg_dma_address(mrq->data->sg));
356341

357342
if (mrq->sbc)
358343
meson_mx_mmc_start_cmd(mmc, mrq->sbc);
@@ -364,24 +349,26 @@ static void meson_mx_mmc_read_response(struct mmc_host *mmc,
364349
struct mmc_command *cmd)
365350
{
366351
struct meson_mx_mmc_host *host = mmc_priv(mmc);
367-
u32 mult;
368-
int i, resp[4];
352+
unsigned int i, resp[4];
369353

370-
mult = readl(host->base + MESON_MX_SDIO_MULT);
371-
mult |= MESON_MX_SDIO_MULT_WR_RD_OUT_INDEX;
372-
mult &= ~MESON_MX_SDIO_MULT_RESP_READ_INDEX_MASK;
373-
mult |= FIELD_PREP(MESON_MX_SDIO_MULT_RESP_READ_INDEX_MASK, 0);
374-
writel(mult, host->base + MESON_MX_SDIO_MULT);
354+
regmap_update_bits(host->regmap, MESON_MX_SDIO_MULT,
355+
MESON_MX_SDIO_MULT_WR_RD_OUT_INDEX |
356+
MESON_MX_SDIO_MULT_RESP_READ_INDEX_MASK,
357+
MESON_MX_SDIO_MULT_WR_RD_OUT_INDEX |
358+
FIELD_PREP(MESON_MX_SDIO_MULT_RESP_READ_INDEX_MASK,
359+
0));
375360

376361
if (cmd->flags & MMC_RSP_136) {
377362
for (i = 0; i <= 3; i++)
378-
resp[3 - i] = readl(host->base + MESON_MX_SDIO_ARGU);
363+
regmap_read(host->regmap, MESON_MX_SDIO_ARGU,
364+
&resp[3 - i]);
365+
379366
cmd->resp[0] = (resp[0] << 8) | ((resp[1] >> 24) & 0xff);
380367
cmd->resp[1] = (resp[1] << 8) | ((resp[2] >> 24) & 0xff);
381368
cmd->resp[2] = (resp[2] << 8) | ((resp[3] >> 24) & 0xff);
382369
cmd->resp[3] = (resp[3] << 8);
383370
} else if (cmd->flags & MMC_RSP_PRESENT) {
384-
cmd->resp[0] = readl(host->base + MESON_MX_SDIO_ARGU);
371+
regmap_read(host->regmap, MESON_MX_SDIO_ARGU, &cmd->resp[0]);
385372
}
386373
}
387374

@@ -422,16 +409,16 @@ static irqreturn_t meson_mx_mmc_irq(int irq, void *data)
422409

423410
spin_lock(&host->irq_lock);
424411

425-
irqs = readl(host->base + MESON_MX_SDIO_IRQS);
426-
send = readl(host->base + MESON_MX_SDIO_SEND);
412+
regmap_read(host->regmap, MESON_MX_SDIO_IRQS, &irqs);
413+
regmap_read(host->regmap, MESON_MX_SDIO_SEND, &send);
427414

428415
if (irqs & MESON_MX_SDIO_IRQS_CMD_INT)
429416
ret = meson_mx_mmc_process_cmd_irq(host, irqs, send);
430417
else
431418
ret = IRQ_HANDLED;
432419

433420
/* finally ACK all pending interrupts */
434-
writel(irqs, host->base + MESON_MX_SDIO_IRQS);
421+
regmap_write(host->regmap, MESON_MX_SDIO_IRQS, irqs);
435422

436423
spin_unlock(&host->irq_lock);
437424

@@ -470,14 +457,13 @@ static void meson_mx_mmc_timeout(struct timer_list *t)
470457
struct meson_mx_mmc_host *host = timer_container_of(host, t,
471458
cmd_timeout);
472459
unsigned long irqflags;
473-
u32 irqc;
460+
u32 irqs, argu;
474461

475462
spin_lock_irqsave(&host->irq_lock, irqflags);
476463

477464
/* disable the CMD interrupt */
478-
irqc = readl(host->base + MESON_MX_SDIO_IRQC);
479-
irqc &= ~MESON_MX_SDIO_IRQC_ARC_CMD_INT_EN;
480-
writel(irqc, host->base + MESON_MX_SDIO_IRQC);
465+
regmap_clear_bits(host->regmap, MESON_MX_SDIO_IRQC,
466+
MESON_MX_SDIO_IRQC_ARC_CMD_INT_EN);
481467

482468
spin_unlock_irqrestore(&host->irq_lock, irqflags);
483469

@@ -488,10 +474,12 @@ static void meson_mx_mmc_timeout(struct timer_list *t)
488474
if (!host->cmd)
489475
return;
490476

477+
regmap_read(host->regmap, MESON_MX_SDIO_IRQS, &irqs);
478+
regmap_read(host->regmap, MESON_MX_SDIO_ARGU, &argu);
479+
491480
dev_dbg(mmc_dev(host->mmc),
492481
"Timeout on CMD%u (IRQS = 0x%08x, ARGU = 0x%08x)\n",
493-
host->cmd->opcode, readl(host->base + MESON_MX_SDIO_IRQS),
494-
readl(host->base + MESON_MX_SDIO_ARGU));
482+
host->cmd->opcode, irqs, argu);
495483

496484
host->cmd->error = -ETIMEDOUT;
497485

@@ -578,7 +566,8 @@ static int meson_mx_mmc_add_host(struct meson_mx_mmc_host *host)
578566
return 0;
579567
}
580568

581-
static int meson_mx_mmc_register_clks(struct meson_mx_mmc_host *host)
569+
static int meson_mx_mmc_register_clks(struct meson_mx_mmc_host *host,
570+
void __iomem *base)
582571
{
583572
struct clk_init_data init;
584573
const char *clk_div_parent, *clk_fixed_factor_parent;
@@ -613,7 +602,7 @@ static int meson_mx_mmc_register_clks(struct meson_mx_mmc_host *host)
613602
init.flags = CLK_SET_RATE_PARENT;
614603
init.parent_names = &clk_div_parent;
615604
init.num_parents = 1;
616-
host->cfg_div.reg = host->base + MESON_MX_SDIO_CONF;
605+
host->cfg_div.reg = base + MESON_MX_SDIO_CONF;
617606
host->cfg_div.shift = MESON_MX_SDIO_CONF_CMD_CLK_DIV_SHIFT;
618607
host->cfg_div.width = MESON_MX_SDIO_CONF_CMD_CLK_DIV_WIDTH;
619608
host->cfg_div.hw.init = &init;
@@ -629,12 +618,23 @@ static int meson_mx_mmc_register_clks(struct meson_mx_mmc_host *host)
629618

630619
static int meson_mx_mmc_probe(struct platform_device *pdev)
631620
{
621+
const struct regmap_config meson_mx_sdio_regmap_config = {
622+
.reg_bits = 8,
623+
.val_bits = 32,
624+
.reg_stride = 4,
625+
.max_register = MESON_MX_SDIO_EXT,
626+
};
632627
struct platform_device *slot_pdev;
633628
struct mmc_host *mmc;
634629
struct meson_mx_mmc_host *host;
630+
void __iomem *base;
635631
int ret, irq;
636632
u32 conf;
637633

634+
base = devm_platform_ioremap_resource(pdev, 0);
635+
if (IS_ERR(base))
636+
return PTR_ERR(base);
637+
638638
slot_pdev = meson_mx_mmc_slot_pdev(&pdev->dev);
639639
if (!slot_pdev)
640640
return -ENODEV;
@@ -656,9 +656,10 @@ static int meson_mx_mmc_probe(struct platform_device *pdev)
656656

657657
platform_set_drvdata(pdev, host);
658658

659-
host->base = devm_platform_ioremap_resource(pdev, 0);
660-
if (IS_ERR(host->base)) {
661-
ret = PTR_ERR(host->base);
659+
host->regmap = devm_regmap_init_mmio(&pdev->dev, base,
660+
&meson_mx_sdio_regmap_config);
661+
if (IS_ERR(host->regmap)) {
662+
ret = PTR_ERR(host->regmap);
662663
goto error_free_mmc;
663664
}
664665

@@ -687,7 +688,7 @@ static int meson_mx_mmc_probe(struct platform_device *pdev)
687688
goto error_free_mmc;
688689
}
689690

690-
ret = meson_mx_mmc_register_clks(host);
691+
ret = meson_mx_mmc_register_clks(host, base);
691692
if (ret)
692693
goto error_free_mmc;
693694

@@ -708,7 +709,7 @@ static int meson_mx_mmc_probe(struct platform_device *pdev)
708709
conf |= FIELD_PREP(MESON_MX_SDIO_CONF_M_ENDIAN_MASK, 0x3);
709710
conf |= FIELD_PREP(MESON_MX_SDIO_CONF_WRITE_NWR_MASK, 0x2);
710711
conf |= FIELD_PREP(MESON_MX_SDIO_CONF_WRITE_CRC_OK_STATUS_MASK, 0x2);
711-
writel(conf, host->base + MESON_MX_SDIO_CONF);
712+
regmap_write(host->regmap, MESON_MX_SDIO_CONF, conf);
712713

713714
meson_mx_mmc_soft_reset(host);
714715

0 commit comments

Comments
 (0)