drivers: gpio: mmio32: update gpio_mmio32 to behave like other divers

The current implementation requires SoCs/Boards to manualy instantiate
the preripherals and initilize them.

The change lets Zephyr rely on the device tree setup to instantiate &
initialize the relevant gpio peripheral.

Signed-off-by: Wilfried Chauveau <wilfried.chauveau@arm.com>
This commit is contained in:
Wilfried Chauveau 2024-11-28 15:34:39 +00:00 committed by Benjamin Cabé
commit c0139fad06
14 changed files with 83 additions and 184 deletions

View file

@ -156,7 +156,7 @@ i2c_shield1: i2c@20d000 {
};
gpio_led0: mps2_fpgaio@302000 {
compatible = "arm,mps2-fpgaio-gpio";
compatible = "arm,mmio32-gpio";
reg = <0x302000 0x4>;
gpio-controller;
@ -165,16 +165,17 @@ gpio_led0: mps2_fpgaio@302000 {
};
gpio_button: mps2_fpgaio@302008 {
compatible = "arm,mps2-fpgaio-gpio";
compatible = "arm,mmio32-gpio";
reg = <0x302008 0x4>;
gpio-controller;
#gpio-cells = <1>;
ngpios = <2>;
direction-input;
};
gpio_misc: mps2_fpgaio@30204c {
compatible = "arm,mps2-fpgaio-gpio";
compatible = "arm,mmio32-gpio";
reg = <0x30204c 0x4>;
gpio-controller;

View file

@ -15,7 +15,6 @@ supported:
testing:
default: true
ignore_tags:
- drivers
- bluetooth
- net
- timer

View file

@ -236,7 +236,7 @@
};
gpio_led0: mps2_fpgaio@40028000 {
compatible = "arm,mps2-fpgaio-gpio";
compatible = "arm,mmio32-gpio";
reg = <0x40028000 0x4>;
gpio-controller;
#gpio-cells = <1>;
@ -244,15 +244,16 @@
};
gpio_button: mps2_fpgaio@40028008 {
compatible = "arm,mps2-fpgaio-gpio";
compatible = "arm,mmio32-gpio";
reg = <0x40028008 0x4>;
gpio-controller;
#gpio-cells = <1>;
ngpios = <2>;
direction-input;
};
gpio_misc: mps2_fpgaio@4002804c {
compatible = "arm,mps2-fpgaio-gpio";
compatible = "arm,mmio32-gpio";
reg = <0x4002804c 0x4>;
gpio-controller;
#gpio-cells = <1>;

View file

@ -122,7 +122,7 @@ i2c_ddr4_eeprom: i2c@9208000 {
};
gpio_led0: mps3_fpgaio@9302000 {
compatible = "arm,mps3-fpgaio-gpio";
compatible = "arm,mmio32-gpio";
reg = <0x9302000 0x4>;
gpio-controller;
@ -131,16 +131,17 @@ gpio_led0: mps3_fpgaio@9302000 {
};
gpio_button: mps3_fpgaio@9302008 {
compatible = "arm,mps3-fpgaio-gpio";
compatible = "arm,mmio32-gpio";
reg = <0x9302008 0x4>;
gpio-controller;
#gpio-cells = <1>;
ngpios = <2>;
direction-input;
};
gpio_misc: mps3_fpgaio@930204c {
compatible = "arm,mps3-fpgaio-gpio";
compatible = "arm,mmio32-gpio";
reg = <0x930204c 0x4>;
gpio-controller;

View file

@ -17,7 +17,6 @@ supported:
- gpio
testing:
ignore_tags:
- drivers
- bluetooth
- net
- timer

View file

@ -26,12 +26,30 @@
* gpio_port_write.
*/
#include <zephyr/drivers/gpio/gpio_mmio32.h>
#define DT_DRV_COMPAT arm_mmio32_gpio
#include <zephyr/irq.h>
#include <errno.h>
static int gpio_mmio32_config(const struct device *dev,
gpio_pin_t pin, gpio_flags_t flags)
#include <zephyr/drivers/gpio/gpio_utils.h>
struct gpio_mmio32_config {
/* gpio_driver_config needs to be first */
struct gpio_driver_config common;
volatile uint32_t *reg;
uint32_t mask;
bool is_input;
};
struct gpio_mmio32_context {
/* gpio_driver_data needs to be first */
struct gpio_driver_data common;
const struct gpio_mmio32_config *config;
};
int gpio_mmio32_init(const struct device *dev);
static int gpio_mmio32_config(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags)
{
struct gpio_mmio32_context *context = dev->data;
const struct gpio_mmio32_config *config = context->config;
@ -40,13 +58,19 @@ static int gpio_mmio32_config(const struct device *dev,
return -EINVAL; /* Pin not in our validity mask */
}
if (flags & ~(GPIO_INPUT | GPIO_OUTPUT |
GPIO_OUTPUT_INIT_LOW | GPIO_OUTPUT_INIT_HIGH |
if (flags & ~(GPIO_INPUT | GPIO_OUTPUT | GPIO_OUTPUT_INIT_LOW | GPIO_OUTPUT_INIT_HIGH |
GPIO_ACTIVE_LOW)) {
/* We ignore direction and fake polarity, rest is unsupported */
return -ENOTSUP;
}
if (config->is_input && ((flags & GPIO_OUTPUT) != 0)) {
return -ENOTSUP;
}
if (!config->is_input && ((flags & GPIO_INPUT) != 0)) {
return -ENOTSUP;
}
if ((flags & GPIO_OUTPUT) != 0) {
unsigned int key;
volatile uint32_t *reg = config->reg;
@ -73,9 +97,7 @@ static int gpio_mmio32_port_get_raw(const struct device *dev, uint32_t *value)
return 0;
}
static int gpio_mmio32_port_set_masked_raw(const struct device *dev,
uint32_t mask,
uint32_t value)
static int gpio_mmio32_port_set_masked_raw(const struct device *dev, uint32_t mask, uint32_t value)
{
struct gpio_mmio32_context *context = dev->data;
const struct gpio_mmio32_config *config = context->config;
@ -93,8 +115,7 @@ static int gpio_mmio32_port_set_masked_raw(const struct device *dev,
return 0;
}
static int gpio_mmio32_port_set_bits_raw(const struct device *dev,
uint32_t mask)
static int gpio_mmio32_port_set_bits_raw(const struct device *dev, uint32_t mask)
{
struct gpio_mmio32_context *context = dev->data;
const struct gpio_mmio32_config *config = context->config;
@ -111,8 +132,7 @@ static int gpio_mmio32_port_set_bits_raw(const struct device *dev,
return 0;
}
static int gpio_mmio32_port_clear_bits_raw(const struct device *dev,
uint32_t mask)
static int gpio_mmio32_port_clear_bits_raw(const struct device *dev, uint32_t mask)
{
struct gpio_mmio32_context *context = dev->data;
const struct gpio_mmio32_config *config = context->config;
@ -129,8 +149,7 @@ static int gpio_mmio32_port_clear_bits_raw(const struct device *dev,
return 0;
}
static int gpio_mmio32_port_toggle_bits(const struct device *dev,
uint32_t mask)
static int gpio_mmio32_port_toggle_bits(const struct device *dev, uint32_t mask)
{
struct gpio_mmio32_context *context = dev->data;
const struct gpio_mmio32_config *config = context->config;
@ -147,8 +166,7 @@ static int gpio_mmio32_port_toggle_bits(const struct device *dev,
return 0;
}
int gpio_mmio_pin_interrupt_configure(const struct device *port,
gpio_pin_t pin,
int gpio_mmio32_pin_interrupt_configure(const struct device *port, gpio_pin_t pin,
enum gpio_int_mode, enum gpio_int_trig)
{
return -ENOTSUP;
@ -161,7 +179,7 @@ DEVICE_API(gpio, gpio_mmio32_api) = {
.port_set_bits_raw = gpio_mmio32_port_set_bits_raw,
.port_clear_bits_raw = gpio_mmio32_port_clear_bits_raw,
.port_toggle_bits = gpio_mmio32_port_toggle_bits,
.pin_interrupt_configure = gpio_mmio_pin_interrupt_configure,
.pin_interrupt_configure = gpio_mmio32_pin_interrupt_configure,
};
int gpio_mmio32_init(const struct device *dev)
@ -173,3 +191,22 @@ int gpio_mmio32_init(const struct device *dev)
return 0;
}
#define MMIO32_GPIO_DEVICE(n) \
static struct gpio_mmio32_context gpio_mmio32_##n##_ctx; \
\
static const struct gpio_mmio32_config gpio_mmio32_##n##_cfg = { \
.common = \
{ \
.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(n), \
}, \
.reg = (volatile uint32_t *)DT_INST_REG_ADDR(n), \
.mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(n), \
.is_input = DT_INST_PROP(n, direction_input), \
}; \
\
DEVICE_DT_INST_DEFINE(n, gpio_mmio32_init, NULL, &gpio_mmio32_##n##_ctx, \
&gpio_mmio32_##n##_cfg, PRE_KERNEL_1, \
CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &gpio_mmio32_api);
DT_INST_FOREACH_STATUS_OKAY(MMIO32_GPIO_DEVICE)

View file

@ -1,6 +1,6 @@
description: GPIO controller on ARM MPS2 FPGA
description: ARM MMIO32 GPIO
compatible: "arm,mps2-fpgaio-gpio"
compatible: "arm,mmio32-gpio"
include: [gpio-controller.yaml, base.yaml]
@ -14,5 +14,9 @@ properties:
"#gpio-cells":
const: 1
direction-input:
type: boolean
description: Marks this pin set as all input pins.
gpio-cells:
- pin

View file

@ -1,18 +0,0 @@
description: GPIO controller on ARM MPS3 FPGA
compatible: "arm,mps3-fpgaio-gpio"
include: [gpio-controller.yaml, base.yaml]
properties:
reg:
required: true
ngpios:
required: true
"#gpio-cells":
const: 1
gpio-cells:
- pin

View file

@ -1,79 +0,0 @@
/*
* Copyright (c) 2016 Linaro Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_DRIVERS_GPIO_GPIO_MMIO32_H_
#define ZEPHYR_INCLUDE_DRIVERS_GPIO_GPIO_MMIO32_H_
#include <zephyr/device.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/types.h>
#ifdef __cplusplus
extern "C" {
#endif
extern const struct gpio_driver_api gpio_mmio32_api;
struct gpio_mmio32_config {
/* gpio_driver_config needs to be first */
struct gpio_driver_config common;
volatile uint32_t *reg;
uint32_t mask;
};
struct gpio_mmio32_context {
/* gpio_driver_data needs to be first */
struct gpio_driver_data common;
const struct gpio_mmio32_config *config;
};
int gpio_mmio32_init(const struct device *dev);
#ifdef CONFIG_GPIO_MMIO32
/**
* Create a device object for accessing a simple 32-bit i/o register using the
* same APIs as GPIO drivers.
*
* @param node_id The devicetree node identifier.
* @param _address The address of the 32-bit i/o register the device will
* provide access to.
* @param _mask Mask of bits in the register that it is valid to access.
* E.g. 0xffffffffu to allow access to all of them.
*
*/
#define GPIO_MMIO32_INIT(node_id, _address, _mask) \
static struct gpio_mmio32_context _CONCAT(Z_DEVICE_DT_DEV_ID(node_id), _ctx); \
\
static const struct gpio_mmio32_config _CONCAT(Z_DEVICE_DT_DEV_ID(node_id), _cfg) = { \
.common = { \
.port_pin_mask = _mask, \
}, \
.reg = (volatile uint32_t *)_address, \
.mask = _mask, \
}; \
\
DEVICE_DT_DEFINE(node_id, \
&gpio_mmio32_init, \
NULL, \
&_CONCAT(Z_DEVICE_DT_DEV_ID(node_id), _ctx), \
&_CONCAT(Z_DEVICE_DT_DEV_ID(node_id), _cfg), \
PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \
&gpio_mmio32_api)
#else /* CONFIG_GPIO_MMIO32 */
/* Null definition for when support not configured into kernel */
#define GPIO_MMIO32_INIT(node_id, _address, _mask)
#endif
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_DRIVERS_GPIO_GPIO_MMIO32_H_ */

View file

@ -7,40 +7,24 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/drivers/gpio/gpio_mmio32.h>
#include <soc.h>
#include <zephyr/linker/linker-defs.h>
/* Setup GPIO drivers for accessing FPGAIO registers */
#define FPGAIO_NODE(n) DT_INST(n, arm_mps2_fpgaio_gpio)
#define FPGAIO_INIT(n) \
GPIO_MMIO32_INIT(FPGAIO_NODE(n), \
DT_REG_ADDR(FPGAIO_NODE(n)), \
BIT_MASK(DT_PROP(FPGAIO_NODE(n), ngpios)))
/* We expect there to be 3 arm,mps2-fpgaio-gpio devices:
* led0, button, and misc
*/
FPGAIO_INIT(0);
FPGAIO_INIT(1);
FPGAIO_INIT(2);
/* (Secure System Control) Base Address */
#define SSE_200_SYSTEM_CTRL_S_BASE (0x50021000UL)
#define SSE_200_SYSTEM_CTRL_INITSVTOR1 (SSE_200_SYSTEM_CTRL_S_BASE + 0x114)
#define SSE_200_SYSTEM_CTRL_CPU_WAIT (SSE_200_SYSTEM_CTRL_S_BASE + 0x118)
#define SSE_200_CPU_ID_UNIT_BASE (0x5001F000UL)
#define SSE_200_SYSTEM_CTRL_S_BASE (0x50021000UL)
#define SSE_200_SYSTEM_CTRL_INITSVTOR1 (SSE_200_SYSTEM_CTRL_S_BASE + 0x114)
#define SSE_200_SYSTEM_CTRL_CPU_WAIT (SSE_200_SYSTEM_CTRL_S_BASE + 0x118)
#define SSE_200_CPU_ID_UNIT_BASE (0x5001F000UL)
/* The base address that the application image will start at on the secondary
* (non-TrustZone) Cortex-M33 mcu.
*/
#define CPU1_FLASH_ADDRESS (0x38B000)
#define CPU1_FLASH_ADDRESS (0x38B000)
/* The memory map offset for the application image, which is used
* to determine the location of the reset vector at startup.
*/
#define CPU1_FLASH_OFFSET (0x10000000)
#define CPU1_FLASH_OFFSET (0x10000000)
/**
* @brief Wake up CPU 1 from another CPU, this is platform specific.
@ -49,9 +33,7 @@ void wakeup_cpu1(void)
{
/* Set the Initial Secure Reset Vector Register for CPU 1 */
*(uint32_t *)(SSE_200_SYSTEM_CTRL_INITSVTOR1) =
(uint32_t)_vector_start +
CPU1_FLASH_ADDRESS -
CPU1_FLASH_OFFSET;
(uint32_t)_vector_start + CPU1_FLASH_ADDRESS - CPU1_FLASH_OFFSET;
/* Set the CPU Boot wait control after reset */
*(uint32_t *)(SSE_200_SYSTEM_CTRL_CPU_WAIT) = 0;

View file

@ -1,10 +1,6 @@
# Copyright (c) 2021 Linaro Limited
# SPDX-License-Identifier: Apache-2.0
zephyr_sources(
soc.c
)
zephyr_include_directories(.)
set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "")

View file

@ -1,24 +0,0 @@
/*
* Copyright (c) 2021 Linaro Limited
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/drivers/gpio/gpio_mmio32.h>
#include <soc.h>
#include <zephyr/linker/linker-defs.h>
/* Setup GPIO drivers for accessing FPGAIO registers */
#define FPGAIO_NODE(n) DT_INST(n, arm_mps3_fpgaio_gpio)
#define FPGAIO_INIT(n) \
GPIO_MMIO32_INIT(FPGAIO_NODE(n), \
DT_REG_ADDR(FPGAIO_NODE(n)), \
BIT_MASK(DT_PROP(FPGAIO_NODE(n), ngpios)))
/* We expect there to be 3 arm,mps3-fpgaio-gpio devices:
* led0, button, and misc
*/
FPGAIO_INIT(0);
FPGAIO_INIT(1);
FPGAIO_INIT(2);

View file

@ -156,7 +156,7 @@ i2c_shield1: i2c@20d000 {
};
gpio_led0: mps2_fpgaio@302000 {
compatible = "arm,mps2-fpgaio-gpio";
compatible = "arm,mmio32-gpio";
reg = <0x302000 0x4>;
gpio-controller;
@ -165,16 +165,17 @@ gpio_led0: mps2_fpgaio@302000 {
};
gpio_button: mps2_fpgaio@302008 {
compatible = "arm,mps2-fpgaio-gpio";
compatible = "arm,mmio32-gpio";
reg = <0x302008 0x4>;
gpio-controller;
#gpio-cells = <1>;
ngpios = <2>;
direction-input;
};
gpio_misc: mps2_fpgaio@30204c {
compatible = "arm,mps2-fpgaio-gpio";
compatible = "arm,mmio32-gpio";
reg = <0x30204c 0x4>;
gpio-controller;

View file

@ -8,6 +8,5 @@ tests:
# Fix exclude when we can exclude just sim run
platform_exclude:
- mps2/an385
- mps2/an521/cpu0
- neorv32
filter: dt_enabled_alias_with_parent_compat("led0", "gpio-leds")