diff --git a/drivers/gpio/gpio_xlnx_ps.c b/drivers/gpio/gpio_xlnx_ps.c index ed6488793f7..896916da1f4 100644 --- a/drivers/gpio/gpio_xlnx_ps.c +++ b/drivers/gpio/gpio_xlnx_ps.c @@ -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); */ 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) */ 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[] = {\ /* 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\ diff --git a/drivers/gpio/gpio_xlnx_ps.h b/drivers/gpio/gpio_xlnx_ps.h index e08b842bc0f..7dc48ffc9d2 100644 --- a/drivers/gpio/gpio_xlnx_ps.h +++ b/drivers/gpio/gpio_xlnx_ps.h @@ -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 { 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; diff --git a/drivers/gpio/gpio_xlnx_ps_bank.c b/drivers/gpio/gpio_xlnx_ps_bank.c index 046956782a6..c06479c8f53 100644 --- a/drivers/gpio/gpio_xlnx_ps_bank.c +++ b/drivers/gpio/gpio_xlnx_ps_bank.c @@ -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, 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, 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, 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, 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, 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, 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, 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, */ 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, 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) = { */ 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 = {\ .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); diff --git a/drivers/gpio/gpio_xlnx_ps_bank.h b/drivers/gpio/gpio_xlnx_ps_bank.h index ce2385fbb20..f2d34274ef3 100644 --- a/drivers/gpio/gpio_xlnx_ps_bank.h +++ b/drivers/gpio/gpio_xlnx_ps_bank.h @@ -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 @@ */ 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 { */ struct gpio_xlnx_ps_bank_dev_cfg { struct gpio_driver_config common; - - uint32_t base_addr; uint8_t bank_index; };