Browse Source

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 <mail@birnbaum.immo>
pull/83247/head
Immo Birnbaum 10 months ago committed by Benjamin Cabé
parent
commit
fef27d8231
  1. 28
      drivers/gpio/gpio_xlnx_ps.c
  2. 6
      drivers/gpio/gpio_xlnx_ps.h
  3. 43
      drivers/gpio/gpio_xlnx_ps_bank.c
  4. 29
      drivers/gpio/gpio_xlnx_ps_bank.h

28
drivers/gpio/gpio_xlnx_ps.c

@ -20,6 +20,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); @@ -20,6 +20,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
#define DT_DRV_COMPAT xlnx_ps_gpio
#define DEV_CFG(_dev) ((const struct gpio_xlnx_ps_dev_cfg *)(_dev)->config)
#define DEV_DATA(_dev) ((struct gpio_xlnx_ps_dev_data *const)(_dev)->data)
/*
* An API is required for this driver, but as no pin access is provided at
* 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); @@ -41,7 +44,22 @@ static DEVICE_API(gpio, gpio_xlnx_ps_default_apis);
*/
static int gpio_xlnx_ps_init(const struct device *dev)
{
const struct gpio_xlnx_ps_dev_cfg *dev_conf = dev->config;
const struct gpio_xlnx_ps_dev_cfg *dev_conf = DEV_CFG(dev);
struct gpio_xlnx_ps_dev_data *dev_data = DEV_DATA(dev);
uint32_t bank;
/* Perform the actual memory map operation in the parent device */
DEVICE_MMIO_NAMED_MAP(dev, reg_base, K_MEM_CACHE_NONE);
dev_data->base = DEVICE_MMIO_NAMED_GET(dev, reg_base);
__ASSERT(dev_data->base != 0, "%s map register space failed", dev->name);
/* Propagate the virtual base address to the bank devices */
for (bank = 0; bank < dev_conf->num_banks; bank++) {
struct gpio_xlnx_ps_bank_dev_data *bank_data =
dev_conf->bank_devices[bank]->data;
__ASSERT(bank_data != NULL, "%s bank %u data unresolved", dev->name, bank);
bank_data->base = dev_data->base;
}
/* Initialize the device's interrupt */
dev_conf->config_func(dev);
@ -63,7 +81,7 @@ static int gpio_xlnx_ps_init(const struct device *dev) @@ -63,7 +81,7 @@ static int gpio_xlnx_ps_init(const struct device *dev)
*/
static void gpio_xlnx_ps_isr(const struct device *dev)
{
const struct gpio_xlnx_ps_dev_cfg *dev_conf = dev->config;
const struct gpio_xlnx_ps_dev_cfg *dev_conf = DEV_CFG(dev);
const struct gpio_driver_api *api;
struct gpio_xlnx_ps_bank_dev_data *bank_data;
@ -102,11 +120,13 @@ static const struct device *const gpio_xlnx_ps##idx##_banks[] = {\ @@ -102,11 +120,13 @@ static const struct device *const gpio_xlnx_ps##idx##_banks[] = {\
/* Device config & run-time data struct creation macros */
#define GPIO_XLNX_PS_DEV_DATA(idx)\
static struct gpio_xlnx_ps_dev_data gpio_xlnx_ps##idx##_data;
static struct gpio_xlnx_ps_dev_data gpio_xlnx_ps##idx##_data = {\
.base = 0x0,\
};
#define GPIO_XLNX_PS_DEV_CONFIG(idx)\
static const struct gpio_xlnx_ps_dev_cfg gpio_xlnx_ps##idx##_cfg = {\
.base_addr = DT_INST_REG_ADDR(idx),\
DEVICE_MMIO_NAMED_ROM_INIT(reg_base, DT_DRV_INST(idx)),\
.bank_devices = gpio_xlnx_ps##idx##_banks,\
.num_banks = ARRAY_SIZE(gpio_xlnx_ps##idx##_banks),\
.config_func = gpio_xlnx_ps##idx##_irq_config\

6
drivers/gpio/gpio_xlnx_ps.h

@ -23,6 +23,9 @@ typedef void (*gpio_xlnx_ps_config_irq_t)(const struct device *dev); @@ -23,6 +23,9 @@ typedef void (*gpio_xlnx_ps_config_irq_t)(const struct device *dev);
*/
struct gpio_xlnx_ps_dev_data {
struct gpio_driver_data common;
DEVICE_MMIO_NAMED_RAM(reg_base);
mem_addr_t base;
};
/**
@ -36,7 +39,8 @@ struct gpio_xlnx_ps_dev_data { @@ -36,7 +39,8 @@ struct gpio_xlnx_ps_dev_data {
struct gpio_xlnx_ps_dev_cfg {
struct gpio_driver_config common;
uint32_t base_addr;
DEVICE_MMIO_NAMED_ROM(reg_base);
const struct device *const *bank_devices;
uint32_t num_banks;
gpio_xlnx_ps_config_irq_t config_func;

43
drivers/gpio/gpio_xlnx_ps_bank.c

@ -21,6 +21,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); @@ -21,6 +21,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
#define DT_DRV_COMPAT xlnx_ps_gpio_bank
#define DEV_CFG(_dev) ((const struct gpio_xlnx_ps_bank_dev_cfg *)(_dev)->config)
#define DEV_DATA(_dev) ((struct gpio_xlnx_ps_bank_dev_data *const)(_dev)->data)
/**
* @brief GPIO bank pin configuration function
*
@ -47,7 +50,8 @@ static int gpio_xlnx_ps_pin_configure(const struct device *dev, @@ -47,7 +50,8 @@ static int gpio_xlnx_ps_pin_configure(const struct device *dev,
gpio_pin_t pin,
gpio_flags_t flags)
{
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = dev->config;
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev);
struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev);
uint32_t pin_mask = BIT(pin);
uint32_t bank_data;
uint32_t dirm_data;
@ -127,7 +131,8 @@ static int gpio_xlnx_ps_pin_configure(const struct device *dev, @@ -127,7 +131,8 @@ static int gpio_xlnx_ps_pin_configure(const struct device *dev,
static int gpio_xlnx_ps_bank_get(const struct device *dev,
gpio_port_value_t *value)
{
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = dev->config;
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev);
struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev);
*value = sys_read32(GPIO_XLNX_PS_BANK_DATA_REG);
return 0;
@ -159,7 +164,8 @@ static int gpio_xlnx_ps_bank_set_masked(const struct device *dev, @@ -159,7 +164,8 @@ static int gpio_xlnx_ps_bank_set_masked(const struct device *dev,
gpio_port_pins_t mask,
gpio_port_value_t value)
{
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = dev->config;
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev);
struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev);
uint32_t bank_data;
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, @@ -187,7 +193,8 @@ static int gpio_xlnx_ps_bank_set_masked(const struct device *dev,
static int gpio_xlnx_ps_bank_set_bits(const struct device *dev,
gpio_port_pins_t pins)
{
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = dev->config;
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev);
struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev);
uint32_t bank_data;
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, @@ -215,7 +222,8 @@ static int gpio_xlnx_ps_bank_set_bits(const struct device *dev,
static int gpio_xlnx_ps_bank_clear_bits(const struct device *dev,
gpio_port_pins_t pins)
{
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = dev->config;
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev);
struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev);
uint32_t bank_data;
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, @@ -243,7 +251,8 @@ static int gpio_xlnx_ps_bank_clear_bits(const struct device *dev,
static int gpio_xlnx_ps_bank_toggle_bits(const struct device *dev,
gpio_port_pins_t pins)
{
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = dev->config;
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev);
struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev);
uint32_t bank_data;
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, @@ -282,7 +291,8 @@ static int gpio_xlnx_ps_bank_pin_irq_configure(const struct device *dev,
enum gpio_int_mode mode,
enum gpio_int_trig trig)
{
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = dev->config;
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev);
struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev);
uint32_t pin_mask = BIT(pin);
uint32_t int_type_data;
uint32_t int_polarity_data;
@ -358,7 +368,8 @@ static int gpio_xlnx_ps_bank_pin_irq_configure(const struct device *dev, @@ -358,7 +368,8 @@ static int gpio_xlnx_ps_bank_pin_irq_configure(const struct device *dev,
*/
static uint32_t gpio_xlnx_ps_bank_get_int_status(const struct device *dev)
{
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = dev->config;
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev);
struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev);
uint32_t int_status;
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, @@ -387,7 +398,7 @@ static int gpio_xlnx_ps_bank_manage_callback(const struct device *dev,
struct gpio_callback *callback,
bool set)
{
struct gpio_xlnx_ps_bank_dev_data *dev_data = dev->data;
struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev);
return gpio_manage_callback(&dev_data->callbacks, callback, set);
}
@ -419,7 +430,14 @@ static DEVICE_API(gpio, gpio_xlnx_ps_bank_apis) = { @@ -419,7 +430,14 @@ static DEVICE_API(gpio, gpio_xlnx_ps_bank_apis) = {
*/
static int gpio_xlnx_ps_bank_init(const struct device *dev)
{
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = dev->config;
const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev);
struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev);
__ASSERT(dev_data->base != 0, "%s mapped base address missing", dev->name);
if (dev_data->base == 0) {
LOG_ERR("%s mapped base address missing", dev->name);
return -EIO;
}
sys_write32(~0x0, GPIO_XLNX_PS_BANK_INT_DIS_REG); /* Disable all interrupts */
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 = {\ @@ -436,10 +454,11 @@ static const struct gpio_xlnx_ps_bank_dev_cfg gpio_xlnx_ps_bank##idx##_cfg = {\
.common = {\
.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(idx),\
},\
.base_addr = DT_REG_ADDR(DT_PARENT(DT_INST(idx, DT_DRV_COMPAT))),\
.bank_index = idx,\
};\
static struct gpio_xlnx_ps_bank_dev_data gpio_xlnx_ps_bank##idx##_data;\
static struct gpio_xlnx_ps_bank_dev_data gpio_xlnx_ps_bank##idx##_data = {\
.base = 0,\
};\
DEVICE_DT_INST_DEFINE(idx, gpio_xlnx_ps_bank_init, NULL,\
&gpio_xlnx_ps_bank##idx##_data, &gpio_xlnx_ps_bank##idx##_cfg,\
PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY, &gpio_xlnx_ps_bank_apis);

29
drivers/gpio/gpio_xlnx_ps_bank.h

@ -14,31 +14,31 @@ @@ -14,31 +14,31 @@
* Register address calculation macros
* Register address offsets: comp. Zynq-7000 TRM, ug585, chap. B.19
*/
#define GPIO_XLNX_PS_BANK_MASK_DATA_LSW_REG (dev_conf->base_addr\
#define GPIO_XLNX_PS_BANK_MASK_DATA_LSW_REG (dev_data->base\
+ ((uint32_t)dev_conf->bank_index * 0x8))
#define GPIO_XLNX_PS_BANK_MASK_DATA_MSW_REG ((dev_conf->base_addr + 0x04)\
#define GPIO_XLNX_PS_BANK_MASK_DATA_MSW_REG ((dev_data->base + 0x04)\
+ ((uint32_t)dev_conf->bank_index * 0x8))
#define GPIO_XLNX_PS_BANK_DATA_REG ((dev_conf->base_addr + 0x40)\
#define GPIO_XLNX_PS_BANK_DATA_REG ((dev_data->base + 0x40)\
+ ((uint32_t)dev_conf->bank_index * 0x4))
#define GPIO_XLNX_PS_BANK_DATA_RO_REG ((dev_conf->base_addr + 0x60)\
#define GPIO_XLNX_PS_BANK_DATA_RO_REG ((dev_data->base + 0x60)\
+ ((uint32_t)dev_conf->bank_index * 0x4))
#define GPIO_XLNX_PS_BANK_DIRM_REG ((dev_conf->base_addr + 0x204)\
#define GPIO_XLNX_PS_BANK_DIRM_REG ((dev_data->base + 0x204)\
+ ((uint32_t)dev_conf->bank_index * 0x40))
#define GPIO_XLNX_PS_BANK_OEN_REG ((dev_conf->base_addr + 0x208)\
#define GPIO_XLNX_PS_BANK_OEN_REG ((dev_data->base + 0x208)\
+ ((uint32_t)dev_conf->bank_index * 0x40))
#define GPIO_XLNX_PS_BANK_INT_MASK_REG ((dev_conf->base_addr + 0x20C)\
#define GPIO_XLNX_PS_BANK_INT_MASK_REG ((dev_data->base + 0x20C)\
+ ((uint32_t)dev_conf->bank_index * 0x40))
#define GPIO_XLNX_PS_BANK_INT_EN_REG ((dev_conf->base_addr + 0x210)\
#define GPIO_XLNX_PS_BANK_INT_EN_REG ((dev_data->base + 0x210)\
+ ((uint32_t)dev_conf->bank_index * 0x40))
#define GPIO_XLNX_PS_BANK_INT_DIS_REG ((dev_conf->base_addr + 0x214)\
#define GPIO_XLNX_PS_BANK_INT_DIS_REG ((dev_data->base + 0x214)\
+ ((uint32_t)dev_conf->bank_index * 0x40))
#define GPIO_XLNX_PS_BANK_INT_STAT_REG ((dev_conf->base_addr + 0x218)\
#define GPIO_XLNX_PS_BANK_INT_STAT_REG ((dev_data->base + 0x218)\
+ ((uint32_t)dev_conf->bank_index * 0x40))
#define GPIO_XLNX_PS_BANK_INT_TYPE_REG ((dev_conf->base_addr + 0x21C)\
#define GPIO_XLNX_PS_BANK_INT_TYPE_REG ((dev_data->base + 0x21C)\
+ ((uint32_t)dev_conf->bank_index * 0x40))
#define GPIO_XLNX_PS_BANK_INT_POLARITY_REG ((dev_conf->base_addr + 0x220)\
#define GPIO_XLNX_PS_BANK_INT_POLARITY_REG ((dev_data->base + 0x220)\
+ ((uint32_t)dev_conf->bank_index * 0x40))
#define GPIO_XLNX_PS_BANK_INT_ANY_REG ((dev_conf->base_addr + 0x224)\
#define GPIO_XLNX_PS_BANK_INT_ANY_REG ((dev_data->base + 0x224)\
+ ((uint32_t)dev_conf->bank_index * 0x40))
/**
@ -51,6 +51,7 @@ @@ -51,6 +51,7 @@
*/
struct gpio_xlnx_ps_bank_dev_data {
struct gpio_driver_data common;
mem_addr_t base;
sys_slist_t callbacks;
};
@ -64,8 +65,6 @@ struct gpio_xlnx_ps_bank_dev_data { @@ -64,8 +65,6 @@ struct gpio_xlnx_ps_bank_dev_data {
*/
struct gpio_xlnx_ps_bank_dev_cfg {
struct gpio_driver_config common;
uint32_t base_addr;
uint8_t bank_index;
};

Loading…
Cancel
Save