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-
138126static 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
630619static 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