Skip to content

Commit 77672e0

Browse files
committed
regmap: mmio: Extending to support IO ports
Merge series from Andy Shevchenko <[email protected]>: Currently regmap MMIO doesn't support IO ports, while being inconsistent in used IO accessors. Fix the latter and extend framework with the former.
2 parents 0600044 + 7e7ba58 commit 77672e0

File tree

2 files changed

+91
-52
lines changed

2 files changed

+91
-52
lines changed

drivers/base/regmap/regmap-mmio.c

Lines changed: 88 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
struct regmap_mmio_context {
1717
void __iomem *regs;
1818
unsigned int val_bytes;
19-
bool relaxed_mmio;
2019

2120
bool attached_clk;
2221
struct clk *clk;
@@ -33,9 +32,6 @@ static int regmap_mmio_regbits_check(size_t reg_bits)
3332
case 8:
3433
case 16:
3534
case 32:
36-
#ifdef CONFIG_64BIT
37-
case 64:
38-
#endif
3935
return 0;
4036
default:
4137
return -EINVAL;
@@ -57,11 +53,6 @@ static int regmap_mmio_get_min_stride(size_t val_bits)
5753
case 32:
5854
min_stride = 4;
5955
break;
60-
#ifdef CONFIG_64BIT
61-
case 64:
62-
min_stride = 8;
63-
break;
64-
#endif
6556
default:
6657
return -EINVAL;
6758
}
@@ -83,6 +74,12 @@ static void regmap_mmio_write8_relaxed(struct regmap_mmio_context *ctx,
8374
writeb_relaxed(val, ctx->regs + reg);
8475
}
8576

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+
8683
static void regmap_mmio_write16le(struct regmap_mmio_context *ctx,
8784
unsigned int reg,
8885
unsigned int val)
@@ -97,9 +94,21 @@ static void regmap_mmio_write16le_relaxed(struct regmap_mmio_context *ctx,
9794
writew_relaxed(val, ctx->regs + reg);
9895
}
9996

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+
100103
static void regmap_mmio_write16be(struct regmap_mmio_context *ctx,
101104
unsigned int reg,
102105
unsigned int val)
106+
{
107+
writew(swab16(val), ctx->regs + reg);
108+
}
109+
110+
static void regmap_mmio_iowrite16be(struct regmap_mmio_context *ctx,
111+
unsigned int reg, unsigned int val)
103112
{
104113
iowrite16be(val, ctx->regs + reg);
105114
}
@@ -118,28 +127,24 @@ static void regmap_mmio_write32le_relaxed(struct regmap_mmio_context *ctx,
118127
writel_relaxed(val, ctx->regs + reg);
119128
}
120129

121-
static void regmap_mmio_write32be(struct regmap_mmio_context *ctx,
122-
unsigned int reg,
123-
unsigned int val)
130+
static void regmap_mmio_iowrite32le(struct regmap_mmio_context *ctx,
131+
unsigned int reg, unsigned int val)
124132
{
125-
iowrite32be(val, ctx->regs + reg);
133+
iowrite32(val, ctx->regs + reg);
126134
}
127135

128-
#ifdef CONFIG_64BIT
129-
static void regmap_mmio_write64le(struct regmap_mmio_context *ctx,
136+
static void regmap_mmio_write32be(struct regmap_mmio_context *ctx,
130137
unsigned int reg,
131138
unsigned int val)
132139
{
133-
writeq(val, ctx->regs + reg);
140+
writel(swab32(val), ctx->regs + reg);
134141
}
135142

136-
static void regmap_mmio_write64le_relaxed(struct regmap_mmio_context *ctx,
137-
unsigned int reg,
138-
unsigned int val)
143+
static void regmap_mmio_iowrite32be(struct regmap_mmio_context *ctx,
144+
unsigned int reg, unsigned int val)
139145
{
140-
writeq_relaxed(val, ctx->regs + reg);
146+
iowrite32be(val, ctx->regs + reg);
141147
}
142-
#endif
143148

144149
static int regmap_mmio_write(void *context, unsigned int reg, unsigned int val)
145150
{
@@ -172,6 +177,12 @@ static unsigned int regmap_mmio_read8_relaxed(struct regmap_mmio_context *ctx,
172177
return readb_relaxed(ctx->regs + reg);
173178
}
174179

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+
175186
static unsigned int regmap_mmio_read16le(struct regmap_mmio_context *ctx,
176187
unsigned int reg)
177188
{
@@ -184,8 +195,20 @@ static unsigned int regmap_mmio_read16le_relaxed(struct regmap_mmio_context *ctx
184195
return readw_relaxed(ctx->regs + reg);
185196
}
186197

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+
187204
static unsigned int regmap_mmio_read16be(struct regmap_mmio_context *ctx,
188205
unsigned int reg)
206+
{
207+
return swab16(readw(ctx->regs + reg));
208+
}
209+
210+
static unsigned int regmap_mmio_ioread16be(struct regmap_mmio_context *ctx,
211+
unsigned int reg)
189212
{
190213
return ioread16be(ctx->regs + reg);
191214
}
@@ -202,25 +225,23 @@ static unsigned int regmap_mmio_read32le_relaxed(struct regmap_mmio_context *ctx
202225
return readl_relaxed(ctx->regs + reg);
203226
}
204227

205-
static unsigned int regmap_mmio_read32be(struct regmap_mmio_context *ctx,
206-
unsigned int reg)
228+
static unsigned int regmap_mmio_ioread32le(struct regmap_mmio_context *ctx,
229+
unsigned int reg)
207230
{
208-
return ioread32be(ctx->regs + reg);
231+
return ioread32(ctx->regs + reg);
209232
}
210233

211-
#ifdef CONFIG_64BIT
212-
static unsigned int regmap_mmio_read64le(struct regmap_mmio_context *ctx,
234+
static unsigned int regmap_mmio_read32be(struct regmap_mmio_context *ctx,
213235
unsigned int reg)
214236
{
215-
return readq(ctx->regs + reg);
237+
return swab32(readl(ctx->regs + reg));
216238
}
217239

218-
static unsigned int regmap_mmio_read64le_relaxed(struct regmap_mmio_context *ctx,
219-
unsigned int reg)
240+
static unsigned int regmap_mmio_ioread32be(struct regmap_mmio_context *ctx,
241+
unsigned int reg)
220242
{
221-
return readq_relaxed(ctx->regs + reg);
243+
return ioread32be(ctx->regs + reg);
222244
}
223-
#endif
224245

225246
static int regmap_mmio_read(void *context, unsigned int reg, unsigned int *val)
226247
{
@@ -284,13 +305,15 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev,
284305
if (config->reg_stride < min_stride)
285306
return ERR_PTR(-EINVAL);
286307

308+
if (config->use_relaxed_mmio && config->io_port)
309+
return ERR_PTR(-EINVAL);
310+
287311
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
288312
if (!ctx)
289313
return ERR_PTR(-ENOMEM);
290314

291315
ctx->regs = regs;
292316
ctx->val_bytes = config->val_bits / 8;
293-
ctx->relaxed_mmio = config->use_relaxed_mmio;
294317
ctx->clk = ERR_PTR(-ENODEV);
295318

296319
switch (regmap_get_val_endian(dev, &regmap_mmio, config)) {
@@ -301,7 +324,10 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev,
301324
#endif
302325
switch (config->val_bits) {
303326
case 8:
304-
if (ctx->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) {
305331
ctx->reg_read = regmap_mmio_read8_relaxed;
306332
ctx->reg_write = regmap_mmio_write8_relaxed;
307333
} else {
@@ -310,7 +336,10 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev,
310336
}
311337
break;
312338
case 16:
313-
if (ctx->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) {
314343
ctx->reg_read = regmap_mmio_read16le_relaxed;
315344
ctx->reg_write = regmap_mmio_write16le_relaxed;
316345
} else {
@@ -319,25 +348,17 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev,
319348
}
320349
break;
321350
case 32:
322-
if (ctx->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) {
323355
ctx->reg_read = regmap_mmio_read32le_relaxed;
324356
ctx->reg_write = regmap_mmio_write32le_relaxed;
325357
} else {
326358
ctx->reg_read = regmap_mmio_read32le;
327359
ctx->reg_write = regmap_mmio_write32le;
328360
}
329361
break;
330-
#ifdef CONFIG_64BIT
331-
case 64:
332-
if (ctx->relaxed_mmio) {
333-
ctx->reg_read = regmap_mmio_read64le_relaxed;
334-
ctx->reg_write = regmap_mmio_write64le_relaxed;
335-
} else {
336-
ctx->reg_read = regmap_mmio_read64le;
337-
ctx->reg_write = regmap_mmio_write64le;
338-
}
339-
break;
340-
#endif
341362
default:
342363
ret = -EINVAL;
343364
goto err_free;
@@ -349,16 +370,31 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev,
349370
#endif
350371
switch (config->val_bits) {
351372
case 8:
352-
ctx->reg_read = regmap_mmio_read8;
353-
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+
}
354380
break;
355381
case 16:
356-
ctx->reg_read = regmap_mmio_read16be;
357-
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+
}
358389
break;
359390
case 32:
360-
ctx->reg_read = regmap_mmio_read32be;
361-
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+
}
362398
break;
363399
default:
364400
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)