16
16
struct regmap_mmio_context {
17
17
void __iomem * regs ;
18
18
unsigned int val_bytes ;
19
+ bool big_endian ;
19
20
20
21
bool attached_clk ;
21
22
struct clk * clk ;
@@ -165,6 +166,83 @@ static int regmap_mmio_write(void *context, unsigned int reg, unsigned int val)
165
166
return 0 ;
166
167
}
167
168
169
+ static int regmap_mmio_noinc_write (void * context , unsigned int reg ,
170
+ const void * val , size_t val_count )
171
+ {
172
+ struct regmap_mmio_context * ctx = context ;
173
+ int ret = 0 ;
174
+ int i ;
175
+
176
+ if (!IS_ERR (ctx -> clk )) {
177
+ ret = clk_enable (ctx -> clk );
178
+ if (ret < 0 )
179
+ return ret ;
180
+ }
181
+
182
+ /*
183
+ * There are no native, assembly-optimized write single register
184
+ * operations for big endian, so fall back to emulation if this
185
+ * is needed. (Single bytes are fine, they are not affected by
186
+ * endianness.)
187
+ */
188
+ if (ctx -> big_endian && (ctx -> val_bytes > 1 )) {
189
+ switch (ctx -> val_bytes ) {
190
+ case 2 :
191
+ {
192
+ const u16 * valp = (const u16 * )val ;
193
+ for (i = 0 ; i < val_count ; i ++ )
194
+ writew (swab16 (valp [i ]), ctx -> regs + reg );
195
+ goto out_clk ;
196
+ }
197
+ case 4 :
198
+ {
199
+ const u32 * valp = (const u32 * )val ;
200
+ for (i = 0 ; i < val_count ; i ++ )
201
+ writel (swab32 (valp [i ]), ctx -> regs + reg );
202
+ goto out_clk ;
203
+ }
204
+ #ifdef CONFIG_64BIT
205
+ case 8 :
206
+ {
207
+ const u64 * valp = (const u64 * )val ;
208
+ for (i = 0 ; i < val_count ; i ++ )
209
+ writeq (swab64 (valp [i ]), ctx -> regs + reg );
210
+ goto out_clk ;
211
+ }
212
+ #endif
213
+ default :
214
+ ret = - EINVAL ;
215
+ goto out_clk ;
216
+ }
217
+ }
218
+
219
+ switch (ctx -> val_bytes ) {
220
+ case 1 :
221
+ writesb (ctx -> regs + reg , (const u8 * )val , val_count );
222
+ break ;
223
+ case 2 :
224
+ writesw (ctx -> regs + reg , (const u16 * )val , val_count );
225
+ break ;
226
+ case 4 :
227
+ writesl (ctx -> regs + reg , (const u32 * )val , val_count );
228
+ break ;
229
+ #ifdef CONFIG_64BIT
230
+ case 8 :
231
+ writesq (ctx -> regs + reg , (const u64 * )val , val_count );
232
+ break ;
233
+ #endif
234
+ default :
235
+ ret = - EINVAL ;
236
+ break ;
237
+ }
238
+
239
+ out_clk :
240
+ if (!IS_ERR (ctx -> clk ))
241
+ clk_disable (ctx -> clk );
242
+
243
+ return ret ;
244
+ }
245
+
168
246
static unsigned int regmap_mmio_read8 (struct regmap_mmio_context * ctx ,
169
247
unsigned int reg )
170
248
{
@@ -262,6 +340,87 @@ static int regmap_mmio_read(void *context, unsigned int reg, unsigned int *val)
262
340
return 0 ;
263
341
}
264
342
343
+ static int regmap_mmio_noinc_read (void * context , unsigned int reg ,
344
+ void * val , size_t val_count )
345
+ {
346
+ struct regmap_mmio_context * ctx = context ;
347
+ int ret = 0 ;
348
+ int i ;
349
+
350
+ if (!IS_ERR (ctx -> clk )) {
351
+ ret = clk_enable (ctx -> clk );
352
+ if (ret < 0 )
353
+ return ret ;
354
+ }
355
+
356
+ switch (ctx -> val_bytes ) {
357
+ case 1 :
358
+ readsb (ctx -> regs + reg , (u8 * )val , val_count );
359
+ break ;
360
+ case 2 :
361
+ readsw (ctx -> regs + reg , (u16 * )val , val_count );
362
+ break ;
363
+ case 4 :
364
+ readsl (ctx -> regs + reg , (u32 * )val , val_count );
365
+ break ;
366
+ #ifdef CONFIG_64BIT
367
+ case 8 :
368
+ readsq (ctx -> regs + reg , (u64 * )val , val_count );
369
+ break ;
370
+ #endif
371
+ default :
372
+ ret = - EINVAL ;
373
+ goto out_clk ;
374
+ }
375
+
376
+ /*
377
+ * There are no native, assembly-optimized write single register
378
+ * operations for big endian, so fall back to emulation if this
379
+ * is needed. (Single bytes are fine, they are not affected by
380
+ * endianness.)
381
+ */
382
+ if (ctx -> big_endian && (ctx -> val_bytes > 1 )) {
383
+ switch (ctx -> val_bytes ) {
384
+ case 2 :
385
+ {
386
+ u16 * valp = (u16 * )val ;
387
+ for (i = 0 ; i < val_count ; i ++ )
388
+ valp [i ] = swab16 (valp [i ]);
389
+ break ;
390
+ }
391
+ case 4 :
392
+ {
393
+ u32 * valp = (u32 * )val ;
394
+ for (i = 0 ; i < val_count ; i ++ )
395
+ valp [i ] = swab32 (valp [i ]);
396
+ break ;
397
+ }
398
+ #ifdef CONFIG_64BIT
399
+ case 8 :
400
+ {
401
+ u64 * valp = (u64 * )val ;
402
+ for (i = 0 ; i < val_count ; i ++ )
403
+ valp [i ] = swab64 (valp [i ]);
404
+ break ;
405
+ }
406
+ #endif
407
+ default :
408
+ ret = - EINVAL ;
409
+ break ;
410
+ }
411
+ }
412
+
413
+
414
+ out_clk :
415
+ if (!IS_ERR (ctx -> clk ))
416
+ clk_disable (ctx -> clk );
417
+
418
+ return ret ;
419
+
420
+ return 0 ;
421
+ }
422
+
423
+
265
424
static void regmap_mmio_free_context (void * context )
266
425
{
267
426
struct regmap_mmio_context * ctx = context ;
@@ -278,6 +437,8 @@ static const struct regmap_bus regmap_mmio = {
278
437
.fast_io = true,
279
438
.reg_write = regmap_mmio_write ,
280
439
.reg_read = regmap_mmio_read ,
440
+ .reg_noinc_write = regmap_mmio_noinc_write ,
441
+ .reg_noinc_read = regmap_mmio_noinc_read ,
281
442
.free_context = regmap_mmio_free_context ,
282
443
.val_format_endian_default = REGMAP_ENDIAN_LITTLE ,
283
444
};
@@ -368,6 +529,7 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev,
368
529
#ifdef __BIG_ENDIAN
369
530
case REGMAP_ENDIAN_NATIVE :
370
531
#endif
532
+ ctx -> big_endian = true;
371
533
switch (config -> val_bits ) {
372
534
case 8 :
373
535
if (config -> io_port ) {
0 commit comments