Skip to content

Commit 93ce557

Browse files
andy-shevbroonie
authored andcommitted
regmap: mmio: Introduce IO accessors that can talk to IO port
Some users may use regmap MMIO for IO ports, and this can be done by assigning ioreadXX()/iowriteXX() and their Big Endian counterparts to the regmap context. Add IO port support with a corresponding flag added. While doing that, make sure that user won't select relaxed MMIO access along with IO port because the latter have no relaxed variants. Signed-off-by: Andy Shevchenko <[email protected]> Acked-by: William Breathitt Gray <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 159dfab commit 93ce557

File tree

2 files changed

+99
-9
lines changed

2 files changed

+99
-9
lines changed

drivers/base/regmap/regmap-mmio.c

Lines changed: 96 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@ static void regmap_mmio_write8_relaxed(struct regmap_mmio_context *ctx,
7474
writeb_relaxed(val, ctx->regs + reg);
7575
}
7676

77+
static void regmap_mmio_iowrite8(struct regmap_mmio_context *ctx,
78+
unsigned int reg, unsigned int val)
79+
{
80+
iowrite8(val, ctx->regs + reg);
81+
}
82+
7783
static void regmap_mmio_write16le(struct regmap_mmio_context *ctx,
7884
unsigned int reg,
7985
unsigned int val)
@@ -88,13 +94,25 @@ static void regmap_mmio_write16le_relaxed(struct regmap_mmio_context *ctx,
8894
writew_relaxed(val, ctx->regs + reg);
8995
}
9096

97+
static void regmap_mmio_iowrite16le(struct regmap_mmio_context *ctx,
98+
unsigned int reg, unsigned int val)
99+
{
100+
iowrite16(val, ctx->regs + reg);
101+
}
102+
91103
static void regmap_mmio_write16be(struct regmap_mmio_context *ctx,
92104
unsigned int reg,
93105
unsigned int val)
94106
{
95107
iowrite16be(val, ctx->regs + reg);
96108
}
97109

110+
static void regmap_mmio_iowrite16be(struct regmap_mmio_context *ctx,
111+
unsigned int reg, unsigned int val)
112+
{
113+
iowrite16be(val, ctx->regs + reg);
114+
}
115+
98116
static void regmap_mmio_write32le(struct regmap_mmio_context *ctx,
99117
unsigned int reg,
100118
unsigned int val)
@@ -109,13 +127,25 @@ static void regmap_mmio_write32le_relaxed(struct regmap_mmio_context *ctx,
109127
writel_relaxed(val, ctx->regs + reg);
110128
}
111129

130+
static void regmap_mmio_iowrite32le(struct regmap_mmio_context *ctx,
131+
unsigned int reg, unsigned int val)
132+
{
133+
iowrite32(val, ctx->regs + reg);
134+
}
135+
112136
static void regmap_mmio_write32be(struct regmap_mmio_context *ctx,
113137
unsigned int reg,
114138
unsigned int val)
115139
{
116140
iowrite32be(val, ctx->regs + reg);
117141
}
118142

143+
static void regmap_mmio_iowrite32be(struct regmap_mmio_context *ctx,
144+
unsigned int reg, unsigned int val)
145+
{
146+
iowrite32be(val, ctx->regs + reg);
147+
}
148+
119149
static int regmap_mmio_write(void *context, unsigned int reg, unsigned int val)
120150
{
121151
struct regmap_mmio_context *ctx = context;
@@ -147,6 +177,12 @@ static unsigned int regmap_mmio_read8_relaxed(struct regmap_mmio_context *ctx,
147177
return readb_relaxed(ctx->regs + reg);
148178
}
149179

180+
static unsigned int regmap_mmio_ioread8(struct regmap_mmio_context *ctx,
181+
unsigned int reg)
182+
{
183+
return ioread8(ctx->regs + reg);
184+
}
185+
150186
static unsigned int regmap_mmio_read16le(struct regmap_mmio_context *ctx,
151187
unsigned int reg)
152188
{
@@ -159,12 +195,24 @@ static unsigned int regmap_mmio_read16le_relaxed(struct regmap_mmio_context *ctx
159195
return readw_relaxed(ctx->regs + reg);
160196
}
161197

198+
static unsigned int regmap_mmio_ioread16le(struct regmap_mmio_context *ctx,
199+
unsigned int reg)
200+
{
201+
return ioread16(ctx->regs + reg);
202+
}
203+
162204
static unsigned int regmap_mmio_read16be(struct regmap_mmio_context *ctx,
163205
unsigned int reg)
164206
{
165207
return ioread16be(ctx->regs + reg);
166208
}
167209

210+
static unsigned int regmap_mmio_ioread16be(struct regmap_mmio_context *ctx,
211+
unsigned int reg)
212+
{
213+
return ioread16be(ctx->regs + reg);
214+
}
215+
168216
static unsigned int regmap_mmio_read32le(struct regmap_mmio_context *ctx,
169217
unsigned int reg)
170218
{
@@ -177,12 +225,24 @@ static unsigned int regmap_mmio_read32le_relaxed(struct regmap_mmio_context *ctx
177225
return readl_relaxed(ctx->regs + reg);
178226
}
179227

228+
static unsigned int regmap_mmio_ioread32le(struct regmap_mmio_context *ctx,
229+
unsigned int reg)
230+
{
231+
return ioread32(ctx->regs + reg);
232+
}
233+
180234
static unsigned int regmap_mmio_read32be(struct regmap_mmio_context *ctx,
181235
unsigned int reg)
182236
{
183237
return ioread32be(ctx->regs + reg);
184238
}
185239

240+
static unsigned int regmap_mmio_ioread32be(struct regmap_mmio_context *ctx,
241+
unsigned int reg)
242+
{
243+
return ioread32be(ctx->regs + reg);
244+
}
245+
186246
static int regmap_mmio_read(void *context, unsigned int reg, unsigned int *val)
187247
{
188248
struct regmap_mmio_context *ctx = context;
@@ -245,6 +305,9 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev,
245305
if (config->reg_stride < min_stride)
246306
return ERR_PTR(-EINVAL);
247307

308+
if (config->use_relaxed_mmio && config->io_port)
309+
return ERR_PTR(-EINVAL);
310+
248311
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
249312
if (!ctx)
250313
return ERR_PTR(-ENOMEM);
@@ -261,7 +324,10 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev,
261324
#endif
262325
switch (config->val_bits) {
263326
case 8:
264-
if (config->use_relaxed_mmio) {
327+
if (config->io_port) {
328+
ctx->reg_read = regmap_mmio_ioread8;
329+
ctx->reg_write = regmap_mmio_iowrite8;
330+
} else if (config->use_relaxed_mmio) {
265331
ctx->reg_read = regmap_mmio_read8_relaxed;
266332
ctx->reg_write = regmap_mmio_write8_relaxed;
267333
} else {
@@ -270,7 +336,10 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev,
270336
}
271337
break;
272338
case 16:
273-
if (config->use_relaxed_mmio) {
339+
if (config->io_port) {
340+
ctx->reg_read = regmap_mmio_ioread16le;
341+
ctx->reg_write = regmap_mmio_iowrite16le;
342+
} else if (config->use_relaxed_mmio) {
274343
ctx->reg_read = regmap_mmio_read16le_relaxed;
275344
ctx->reg_write = regmap_mmio_write16le_relaxed;
276345
} else {
@@ -279,7 +348,10 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev,
279348
}
280349
break;
281350
case 32:
282-
if (config->use_relaxed_mmio) {
351+
if (config->io_port) {
352+
ctx->reg_read = regmap_mmio_ioread32le;
353+
ctx->reg_write = regmap_mmio_iowrite32le;
354+
} else if (config->use_relaxed_mmio) {
283355
ctx->reg_read = regmap_mmio_read32le_relaxed;
284356
ctx->reg_write = regmap_mmio_write32le_relaxed;
285357
} else {
@@ -298,16 +370,31 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev,
298370
#endif
299371
switch (config->val_bits) {
300372
case 8:
301-
ctx->reg_read = regmap_mmio_read8;
302-
ctx->reg_write = regmap_mmio_write8;
373+
if (config->io_port) {
374+
ctx->reg_read = regmap_mmio_ioread8;
375+
ctx->reg_write = regmap_mmio_iowrite8;
376+
} else {
377+
ctx->reg_read = regmap_mmio_read8;
378+
ctx->reg_write = regmap_mmio_write8;
379+
}
303380
break;
304381
case 16:
305-
ctx->reg_read = regmap_mmio_read16be;
306-
ctx->reg_write = regmap_mmio_write16be;
382+
if (config->io_port) {
383+
ctx->reg_read = regmap_mmio_ioread16be;
384+
ctx->reg_write = regmap_mmio_iowrite16be;
385+
} else {
386+
ctx->reg_read = regmap_mmio_read16be;
387+
ctx->reg_write = regmap_mmio_write16be;
388+
}
307389
break;
308390
case 32:
309-
ctx->reg_read = regmap_mmio_read32be;
310-
ctx->reg_write = regmap_mmio_write32be;
391+
if (config->io_port) {
392+
ctx->reg_read = regmap_mmio_ioread32be;
393+
ctx->reg_write = regmap_mmio_iowrite32be;
394+
} else {
395+
ctx->reg_read = regmap_mmio_read32be;
396+
ctx->reg_write = regmap_mmio_write32be;
397+
}
311398
break;
312399
default:
313400
ret = -EINVAL;

include/linux/regmap.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,8 @@ typedef void (*regmap_unlock)(void *);
311311
* This field is a duplicate of a similar file in
312312
* 'struct regmap_bus' and serves exact same purpose.
313313
* Use it only for "no-bus" cases.
314+
* @io_port: Support IO port accessors. Makes sense only when MMIO vs. IO port
315+
* access can be distinguished.
314316
* @max_register: Optional, specifies the maximum valid register address.
315317
* @wr_table: Optional, points to a struct regmap_access_table specifying
316318
* valid ranges for write access.
@@ -399,6 +401,7 @@ struct regmap_config {
399401
size_t max_raw_write;
400402

401403
bool fast_io;
404+
bool io_port;
402405

403406
unsigned int max_register;
404407
const struct regmap_access_table *wr_table;

0 commit comments

Comments
 (0)