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:
parent
eb4c8fc319
commit
c0139fad06
14 changed files with 83 additions and 184 deletions
|
@ -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;
|
||||
|
|
|
@ -15,7 +15,6 @@ supported:
|
|||
testing:
|
||||
default: true
|
||||
ignore_tags:
|
||||
- drivers
|
||||
- bluetooth
|
||||
- net
|
||||
- timer
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -17,7 +17,6 @@ supported:
|
|||
- gpio
|
||||
testing:
|
||||
ignore_tags:
|
||||
- drivers
|
||||
- bluetooth
|
||||
- net
|
||||
- timer
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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_ */
|
|
@ -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;
|
||||
|
|
|
@ -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 "")
|
||||
|
|
|
@ -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);
|
|
@ -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;
|
||||
|
|
|
@ -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")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue