Question about regmap_range_cfg and regmap_mmio

From: Lars MÃllendorf
Date: Wed Mar 04 2020 - 06:37:35 EST


Hi,

this mail is copied from internal issue written in markdown - I hope
this is still readable as mail.

I am referring to kernel sources v4.9.87 but I think all my assumptions
do still apply to current kernel versions.

[regmap.h](https://elixir.bootlin.com/linux/v4.9.87/source/include/linux/regmap.h#L334)
contains:

```c
/**
* Configuration for indirectly accessed or paged registers.
* Registers, mapped to this virtual range, are accessed in two steps:
* 1. page selector register update;
* 2. access through data window registers.
*
* @name: Descriptive name for diagnostics
*
* @range_min: Address of the lowest register address in virtual range.
* @range_max: Address of the highest register in virtual range.
*
* @page_sel_reg: Register with selector field.
* @page_sel_mask: Bit shift for selector value.
* @page_sel_shift: Bit mask for selector value.
*
* @window_start: Address of first (lowest) register in data window.
* @window_len: Number of registers in data window.
*/
struct regmap_range_cfg {
const char *name;

/* Registers of virtual address range */
unsigned int range_min;
unsigned int range_max;

/* Page selector for indirect addressing */
unsigned int selector_reg;
unsigned int selector_mask;
int selector_shift;

/* Data window (per each page) */
unsigned int window_start;
unsigned int window_len;
};
```

Unfortunately this seems not to work for MMIO devices.

In
[`__regmap_init()`](https://elixir.bootlin.com/linux/v4.9.87/source/drivers/base/regmap/regmap.c#L711)
[`_regmap_bus_reg_read()`](https://elixir.bootlin.com/linux/v4.9.87/source/drivers/base/regmap/regmap.c#L2330)
is assigned to
[`regmap.reg_read()`](https://elixir.bootlin.com/linux/v4.9.87/source/drivers/base/regmap/internal.h#L101)
if `!bus->read || !bus->write`, else
[`_regmap_bus_read()`](https://elixir.bootlin.com/linux/v4.9.87/source/drivers/base/regmap/regmap.c#L2338)
is assigned:

```c
if (!bus) {
map->reg_read = config->reg_read;
map->reg_write = config->reg_write;

map->defer_caching = false;
goto skip_format_initialization;
} else if (!bus->read || !bus->write) {
map->reg_read = _regmap_bus_reg_read;
map->reg_write = _regmap_bus_reg_write;

map->defer_caching = false;
goto skip_format_initialization;
} else {
map->reg_read = _regmap_bus_read;
map->reg_update_bits = bus->reg_update_bits;
}
```
[`_regmap_bus_reg_read()`](https://elixir.bootlin.com/linux/v4.9.87/source/drivers/base/regmap/regmap.c#L2330)
calls the `reg_read` function of the bus directly,
[`_regmap_bus_read()`](https://elixir.bootlin.com/linux/v4.9.87/source/drivers/base/regmap/regmap.c#L2338)
instead calls `_regmap_raw_read()`:

```c
static int _regmap_bus_reg_read(void *context, unsigned int reg,
unsigned int *val)
{
struct regmap *map = context;

return map->bus->reg_read(map->bus_context, reg, val);
}

static int _regmap_bus_read(void *context, unsigned int reg,
unsigned int *val)
{
int ret;
struct regmap *map = context;

if (!map->format.parse_val)
return -EINVAL;

ret = _regmap_raw_read(map, reg, map->work_buf, map->format.val_bytes);
if (ret == 0)
*val = map->format.parse_val(map->work_buf);

return ret;
}
```

[`_regmap_raw_read()`](https://elixir.bootlin.com/linux/v4.9.87/source/drivers/base/regmap/regmap.c#L2297)
in turn calls
[`_regmap_range_lookup()`](https://elixir.bootlin.com/linux/v4.9.87/source/drivers/base/regmap/regmap-mmio.c#L479)
and
[`_regmap_select_page()`](https://elixir.bootlin.com/linux/v4.9.87/source/drivers/base/regmap/regmap-mmio.c#L1283)
which do the paging.

-
[`regmap_mmio`](https://elixir.bootlin.com/linux/v4.9.87/source/drivers/base/regmap/regmap-mmio.c#L212)
does neither contain `.read` nor `.write`.
-
[`regmap_i2c`](https://elixir.bootlin.com/linux/v4.9.87/source/drivers/base/regmap/regmap-i2c.c#L204)
does contain both.

My assumption is that paging is not a common use case for Memory-mapped
I/O and thus has not been implemented for this case.

- Are my assumptions correct?
- If so, what would you recommend me to do:
- Continue using `regmap-mmio` and implement my custom paging
functions on top of that?
- Enhance the current `regmap-mmio` implementation so it does paging
and submit a patch?
- Write my own `better-regmap-mmio` implementation?

Thank you,
Lars

--

Lars MÃllendorf, B. Eng.


Tel.: +49 (0) 7641 93500-425
Fax: +49 (0) 7641 93500-999
E-Mail: lars.moellendorf@xxxxxxxxxx <mailto:lars.moellendorf@xxxxxxxxxx>
Website: www.plating.de <http://www.plating.de>

--------------------------------
plating electronic GmbH - Amtsgericht Freiburg - HRB Nr. 260 592 /
GeschÃftsfÃhrer Karl Rieder / RheinstraÃe 4 â 79350 Sexau â Tel.:+49 (0)
7641 â 93500-0

--------------------------------
Der Inhalt dieser E-Mail ist vertraulich und ausschlieÃlich fÃr den
bezeichneten Adressaten bestimmt. Wenn Sie nicht der vorgesehene
Adressat dieser E-Mail oder dessen Vertreter sein sollten, so beachten
Sie bitte, dass jede Form der Kenntnisnahme, VerÃffentlichung,
VervielfÃltigung oder Weitergabe des Inhalts dieser E-Mail unzulÃssig
ist. Wir bitten Sie, sich in diesem Fall mit dem Absender der E-Mail in
Verbindung zu setzen. Aussagen gegenÃber dem Adressaten unterliegen den
Regelungen des zugrundeliegenden Angebotes bzw. Auftrags, insbesondere
den Allgemeinen GeschÃftsbedingungen und der individuellen
Haftungsvereinbarung. Der Inhalt der E-Mail ist nur rechtsverbindlich,
wenn er unsererseits durch einen Brief oder ein Telefax entsprechend
bestaetigt wird.

The information contained in this email is confidential. It is intended
solely for the addressee. Access to this email by anyone else is
unauthorized. If you are not the intended recipient, any form of
disclosure, reproduction, distribution or any action taken or refrained
from in reliance on it, is prohibited and may be unlawful. Please notify
the sender immediately. All statements of opinion or advice directed via
this email to our clients are subject to the terms and conditions
expressed in the governing client engagement letter. The content of this
email is not legally binding unless confirmed by letter or fax.

Although plating electronic GmbH attempts to sweep e-mail and
attachments for viruses, it does not guarantee that either are
virus-free and accepts no liability for any damage sustained as a result
of viruses.