Skip to content

Commit fef27d8

Browse files
ibirnbaumkartben
authored andcommitted
drivers: gpio: xlnx_ps: switch driver over to DEVICE_MMIO mapping
Set up a named device MMIO memory mapping in the GPIO controller's parent device, map the virtual memory in the init function of the parent device. Once the controller's register space has been successfully mapped, propagate the mapped virtual address to all child (= GPIO bank) devices. While it is possible to add a named mapping to every single GPIO bank device and initialize it in the respective bank device's init function, this would result in multiple virtual address mappings all pointing to the same 4k of physical memory. I assume that, although all those mappings having the same attri- butes, such a setup is at least discouraged. Signed-off-by: Immo Birnbaum <[email protected]>
1 parent f98868e commit fef27d8

File tree

4 files changed

+74
-32
lines changed

4 files changed

+74
-32
lines changed

drivers/gpio/gpio_xlnx_ps.c

+24-4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
2020

2121
#define DT_DRV_COMPAT xlnx_ps_gpio
2222

23+
#define DEV_CFG(_dev) ((const struct gpio_xlnx_ps_dev_cfg *)(_dev)->config)
24+
#define DEV_DATA(_dev) ((struct gpio_xlnx_ps_dev_data *const)(_dev)->data)
25+
2326
/*
2427
* An API is required for this driver, but as no pin access is provided at
2528
* this level, use the default API contents provided by the driver subsystem.
@@ -41,7 +44,22 @@ static DEVICE_API(gpio, gpio_xlnx_ps_default_apis);
4144
*/
4245
static int gpio_xlnx_ps_init(const struct device *dev)
4346
{
44-
const struct gpio_xlnx_ps_dev_cfg *dev_conf = dev->config;
47+
const struct gpio_xlnx_ps_dev_cfg *dev_conf = DEV_CFG(dev);
48+
struct gpio_xlnx_ps_dev_data *dev_data = DEV_DATA(dev);
49+
uint32_t bank;
50+
51+
/* Perform the actual memory map operation in the parent device */
52+
DEVICE_MMIO_NAMED_MAP(dev, reg_base, K_MEM_CACHE_NONE);
53+
dev_data->base = DEVICE_MMIO_NAMED_GET(dev, reg_base);
54+
__ASSERT(dev_data->base != 0, "%s map register space failed", dev->name);
55+
56+
/* Propagate the virtual base address to the bank devices */
57+
for (bank = 0; bank < dev_conf->num_banks; bank++) {
58+
struct gpio_xlnx_ps_bank_dev_data *bank_data =
59+
dev_conf->bank_devices[bank]->data;
60+
__ASSERT(bank_data != NULL, "%s bank %u data unresolved", dev->name, bank);
61+
bank_data->base = dev_data->base;
62+
}
4563

4664
/* Initialize the device's interrupt */
4765
dev_conf->config_func(dev);
@@ -63,7 +81,7 @@ static int gpio_xlnx_ps_init(const struct device *dev)
6381
*/
6482
static void gpio_xlnx_ps_isr(const struct device *dev)
6583
{
66-
const struct gpio_xlnx_ps_dev_cfg *dev_conf = dev->config;
84+
const struct gpio_xlnx_ps_dev_cfg *dev_conf = DEV_CFG(dev);
6785

6886
const struct gpio_driver_api *api;
6987
struct gpio_xlnx_ps_bank_dev_data *bank_data;
@@ -102,11 +120,13 @@ static const struct device *const gpio_xlnx_ps##idx##_banks[] = {\
102120

103121
/* Device config & run-time data struct creation macros */
104122
#define GPIO_XLNX_PS_DEV_DATA(idx)\
105-
static struct gpio_xlnx_ps_dev_data gpio_xlnx_ps##idx##_data;
123+
static struct gpio_xlnx_ps_dev_data gpio_xlnx_ps##idx##_data = {\
124+
.base = 0x0,\
125+
};
106126

107127
#define GPIO_XLNX_PS_DEV_CONFIG(idx)\
108128
static const struct gpio_xlnx_ps_dev_cfg gpio_xlnx_ps##idx##_cfg = {\
109-
.base_addr = DT_INST_REG_ADDR(idx),\
129+
DEVICE_MMIO_NAMED_ROM_INIT(reg_base, DT_DRV_INST(idx)),\
110130
.bank_devices = gpio_xlnx_ps##idx##_banks,\
111131
.num_banks = ARRAY_SIZE(gpio_xlnx_ps##idx##_banks),\
112132
.config_func = gpio_xlnx_ps##idx##_irq_config\

drivers/gpio/gpio_xlnx_ps.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ typedef void (*gpio_xlnx_ps_config_irq_t)(const struct device *dev);
2323
*/
2424
struct gpio_xlnx_ps_dev_data {
2525
struct gpio_driver_data common;
26+
27+
DEVICE_MMIO_NAMED_RAM(reg_base);
28+
mem_addr_t base;
2629
};
2730

2831
/**
@@ -36,7 +39,8 @@ struct gpio_xlnx_ps_dev_data {
3639
struct gpio_xlnx_ps_dev_cfg {
3740
struct gpio_driver_config common;
3841

39-
uint32_t base_addr;
42+
DEVICE_MMIO_NAMED_ROM(reg_base);
43+
4044
const struct device *const *bank_devices;
4145
uint32_t num_banks;
4246
gpio_xlnx_ps_config_irq_t config_func;

drivers/gpio/gpio_xlnx_ps_bank.c

+31-12
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
2121

2222
#define DT_DRV_COMPAT xlnx_ps_gpio_bank
2323

24+
#define DEV_CFG(_dev) ((const struct gpio_xlnx_ps_bank_dev_cfg *)(_dev)->config)
25+
#define DEV_DATA(_dev) ((struct gpio_xlnx_ps_bank_dev_data *const)(_dev)->data)
26+
2427
/**
2528
* @brief GPIO bank pin configuration function
2629
*
@@ -47,7 +50,8 @@ static int gpio_xlnx_ps_pin_configure(const struct device *dev,
4750
gpio_pin_t pin,
4851
gpio_flags_t flags)
4952
{
50-
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = dev->config;
53+
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev);
54+
struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev);
5155
uint32_t pin_mask = BIT(pin);
5256
uint32_t bank_data;
5357
uint32_t dirm_data;
@@ -127,7 +131,8 @@ static int gpio_xlnx_ps_pin_configure(const struct device *dev,
127131
static int gpio_xlnx_ps_bank_get(const struct device *dev,
128132
gpio_port_value_t *value)
129133
{
130-
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = dev->config;
134+
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev);
135+
struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev);
131136

132137
*value = sys_read32(GPIO_XLNX_PS_BANK_DATA_REG);
133138
return 0;
@@ -159,7 +164,8 @@ static int gpio_xlnx_ps_bank_set_masked(const struct device *dev,
159164
gpio_port_pins_t mask,
160165
gpio_port_value_t value)
161166
{
162-
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = dev->config;
167+
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev);
168+
struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev);
163169
uint32_t bank_data;
164170

165171
bank_data = sys_read32(GPIO_XLNX_PS_BANK_DATA_REG);
@@ -187,7 +193,8 @@ static int gpio_xlnx_ps_bank_set_masked(const struct device *dev,
187193
static int gpio_xlnx_ps_bank_set_bits(const struct device *dev,
188194
gpio_port_pins_t pins)
189195
{
190-
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = dev->config;
196+
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev);
197+
struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev);
191198
uint32_t bank_data;
192199

193200
bank_data = sys_read32(GPIO_XLNX_PS_BANK_DATA_REG);
@@ -215,7 +222,8 @@ static int gpio_xlnx_ps_bank_set_bits(const struct device *dev,
215222
static int gpio_xlnx_ps_bank_clear_bits(const struct device *dev,
216223
gpio_port_pins_t pins)
217224
{
218-
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = dev->config;
225+
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev);
226+
struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev);
219227
uint32_t bank_data;
220228

221229
bank_data = sys_read32(GPIO_XLNX_PS_BANK_DATA_REG);
@@ -243,7 +251,8 @@ static int gpio_xlnx_ps_bank_clear_bits(const struct device *dev,
243251
static int gpio_xlnx_ps_bank_toggle_bits(const struct device *dev,
244252
gpio_port_pins_t pins)
245253
{
246-
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = dev->config;
254+
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev);
255+
struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev);
247256
uint32_t bank_data;
248257

249258
bank_data = sys_read32(GPIO_XLNX_PS_BANK_DATA_REG);
@@ -282,7 +291,8 @@ static int gpio_xlnx_ps_bank_pin_irq_configure(const struct device *dev,
282291
enum gpio_int_mode mode,
283292
enum gpio_int_trig trig)
284293
{
285-
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = dev->config;
294+
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev);
295+
struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev);
286296
uint32_t pin_mask = BIT(pin);
287297
uint32_t int_type_data;
288298
uint32_t int_polarity_data;
@@ -358,7 +368,8 @@ static int gpio_xlnx_ps_bank_pin_irq_configure(const struct device *dev,
358368
*/
359369
static uint32_t gpio_xlnx_ps_bank_get_int_status(const struct device *dev)
360370
{
361-
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = dev->config;
371+
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev);
372+
struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev);
362373
uint32_t int_status;
363374

364375
int_status = sys_read32(GPIO_XLNX_PS_BANK_INT_STAT_REG);
@@ -387,7 +398,7 @@ static int gpio_xlnx_ps_bank_manage_callback(const struct device *dev,
387398
struct gpio_callback *callback,
388399
bool set)
389400
{
390-
struct gpio_xlnx_ps_bank_dev_data *dev_data = dev->data;
401+
struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev);
391402

392403
return gpio_manage_callback(&dev_data->callbacks, callback, set);
393404
}
@@ -419,7 +430,14 @@ static DEVICE_API(gpio, gpio_xlnx_ps_bank_apis) = {
419430
*/
420431
static int gpio_xlnx_ps_bank_init(const struct device *dev)
421432
{
422-
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = dev->config;
433+
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev);
434+
struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev);
435+
436+
__ASSERT(dev_data->base != 0, "%s mapped base address missing", dev->name);
437+
if (dev_data->base == 0) {
438+
LOG_ERR("%s mapped base address missing", dev->name);
439+
return -EIO;
440+
}
423441

424442
sys_write32(~0x0, GPIO_XLNX_PS_BANK_INT_DIS_REG); /* Disable all interrupts */
425443
sys_write32(~0x0, GPIO_XLNX_PS_BANK_INT_STAT_REG); /* Clear all interrupts */
@@ -436,10 +454,11 @@ static const struct gpio_xlnx_ps_bank_dev_cfg gpio_xlnx_ps_bank##idx##_cfg = {\
436454
.common = {\
437455
.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(idx),\
438456
},\
439-
.base_addr = DT_REG_ADDR(DT_PARENT(DT_INST(idx, DT_DRV_COMPAT))),\
440457
.bank_index = idx,\
441458
};\
442-
static struct gpio_xlnx_ps_bank_dev_data gpio_xlnx_ps_bank##idx##_data;\
459+
static struct gpio_xlnx_ps_bank_dev_data gpio_xlnx_ps_bank##idx##_data = {\
460+
.base = 0,\
461+
};\
443462
DEVICE_DT_INST_DEFINE(idx, gpio_xlnx_ps_bank_init, NULL,\
444463
&gpio_xlnx_ps_bank##idx##_data, &gpio_xlnx_ps_bank##idx##_cfg,\
445464
PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY, &gpio_xlnx_ps_bank_apis);

drivers/gpio/gpio_xlnx_ps_bank.h

+14-15
Original file line numberDiff line numberDiff line change
@@ -14,31 +14,31 @@
1414
* Register address calculation macros
1515
* Register address offsets: comp. Zynq-7000 TRM, ug585, chap. B.19
1616
*/
17-
#define GPIO_XLNX_PS_BANK_MASK_DATA_LSW_REG (dev_conf->base_addr\
17+
#define GPIO_XLNX_PS_BANK_MASK_DATA_LSW_REG (dev_data->base\
1818
+ ((uint32_t)dev_conf->bank_index * 0x8))
19-
#define GPIO_XLNX_PS_BANK_MASK_DATA_MSW_REG ((dev_conf->base_addr + 0x04)\
19+
#define GPIO_XLNX_PS_BANK_MASK_DATA_MSW_REG ((dev_data->base + 0x04)\
2020
+ ((uint32_t)dev_conf->bank_index * 0x8))
21-
#define GPIO_XLNX_PS_BANK_DATA_REG ((dev_conf->base_addr + 0x40)\
21+
#define GPIO_XLNX_PS_BANK_DATA_REG ((dev_data->base + 0x40)\
2222
+ ((uint32_t)dev_conf->bank_index * 0x4))
23-
#define GPIO_XLNX_PS_BANK_DATA_RO_REG ((dev_conf->base_addr + 0x60)\
23+
#define GPIO_XLNX_PS_BANK_DATA_RO_REG ((dev_data->base + 0x60)\
2424
+ ((uint32_t)dev_conf->bank_index * 0x4))
25-
#define GPIO_XLNX_PS_BANK_DIRM_REG ((dev_conf->base_addr + 0x204)\
25+
#define GPIO_XLNX_PS_BANK_DIRM_REG ((dev_data->base + 0x204)\
2626
+ ((uint32_t)dev_conf->bank_index * 0x40))
27-
#define GPIO_XLNX_PS_BANK_OEN_REG ((dev_conf->base_addr + 0x208)\
27+
#define GPIO_XLNX_PS_BANK_OEN_REG ((dev_data->base + 0x208)\
2828
+ ((uint32_t)dev_conf->bank_index * 0x40))
29-
#define GPIO_XLNX_PS_BANK_INT_MASK_REG ((dev_conf->base_addr + 0x20C)\
29+
#define GPIO_XLNX_PS_BANK_INT_MASK_REG ((dev_data->base + 0x20C)\
3030
+ ((uint32_t)dev_conf->bank_index * 0x40))
31-
#define GPIO_XLNX_PS_BANK_INT_EN_REG ((dev_conf->base_addr + 0x210)\
31+
#define GPIO_XLNX_PS_BANK_INT_EN_REG ((dev_data->base + 0x210)\
3232
+ ((uint32_t)dev_conf->bank_index * 0x40))
33-
#define GPIO_XLNX_PS_BANK_INT_DIS_REG ((dev_conf->base_addr + 0x214)\
33+
#define GPIO_XLNX_PS_BANK_INT_DIS_REG ((dev_data->base + 0x214)\
3434
+ ((uint32_t)dev_conf->bank_index * 0x40))
35-
#define GPIO_XLNX_PS_BANK_INT_STAT_REG ((dev_conf->base_addr + 0x218)\
35+
#define GPIO_XLNX_PS_BANK_INT_STAT_REG ((dev_data->base + 0x218)\
3636
+ ((uint32_t)dev_conf->bank_index * 0x40))
37-
#define GPIO_XLNX_PS_BANK_INT_TYPE_REG ((dev_conf->base_addr + 0x21C)\
37+
#define GPIO_XLNX_PS_BANK_INT_TYPE_REG ((dev_data->base + 0x21C)\
3838
+ ((uint32_t)dev_conf->bank_index * 0x40))
39-
#define GPIO_XLNX_PS_BANK_INT_POLARITY_REG ((dev_conf->base_addr + 0x220)\
39+
#define GPIO_XLNX_PS_BANK_INT_POLARITY_REG ((dev_data->base + 0x220)\
4040
+ ((uint32_t)dev_conf->bank_index * 0x40))
41-
#define GPIO_XLNX_PS_BANK_INT_ANY_REG ((dev_conf->base_addr + 0x224)\
41+
#define GPIO_XLNX_PS_BANK_INT_ANY_REG ((dev_data->base + 0x224)\
4242
+ ((uint32_t)dev_conf->bank_index * 0x40))
4343

4444
/**
@@ -51,6 +51,7 @@
5151
*/
5252
struct gpio_xlnx_ps_bank_dev_data {
5353
struct gpio_driver_data common;
54+
mem_addr_t base;
5455
sys_slist_t callbacks;
5556
};
5657

@@ -64,8 +65,6 @@ struct gpio_xlnx_ps_bank_dev_data {
6465
*/
6566
struct gpio_xlnx_ps_bank_dev_cfg {
6667
struct gpio_driver_config common;
67-
68-
uint32_t base_addr;
6968
uint8_t bank_index;
7069
};
7170

0 commit comments

Comments
 (0)