diff options
author | Keith Short <keithshort@chromium.org> | 2021-09-17 13:05:19 -0600 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-09-18 00:07:46 +0000 |
commit | 2bfcf8da1d696783cf8a83bb2350d6931879c148 (patch) | |
tree | 4a56a4d27bc66188d2fdb3eb2cce53b89fe8d914 /zephyr/shim/src | |
parent | ef1a31ced60aba0e1b54c8ae2c28e6c3fdd6f4c1 (diff) | |
download | chrome-ec-2bfcf8da1d696783cf8a83bb2350d6931879c148.tar.gz |
zephyr: Restructure GPIO interrupt table to save RAM
Restructure the GPIO interrupt table to separate the constant data from
the data that needs to be updated at runtime.
On Herobrine, this saves 180 byts flash and 240 bytes RAM.
BUG=b:199328071
BRANCH=none
TEST=zmake testall
TEST=Boot zephyr on herobrine
Signed-off-by: Keith Short <keithshort@chromium.org>
Change-Id: I096aec5b00fd7dc661db326a278ab44a0a1286da
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3169563
Commit-Queue: Yuval Peress <peress@google.com>
Reviewed-by: Yuval Peress <peress@google.com>
Diffstat (limited to 'zephyr/shim/src')
-rw-r--r-- | zephyr/shim/src/gpio.c | 50 |
1 files changed, 38 insertions, 12 deletions
diff --git a/zephyr/shim/src/gpio.c b/zephyr/shim/src/gpio.c index 01faf87fda..2bae272361 100644 --- a/zephyr/shim/src/gpio.c +++ b/zephyr/shim/src/gpio.c @@ -60,12 +60,10 @@ static struct gpio_data data[] = { #endif }; -/* Maps platform/ec gpio callbacks to zephyr gpio callbacks */ +/* Maps platform/ec gpio callback information */ struct gpio_signal_callback { /* The platform/ec gpio_signal */ const enum gpio_signal signal; - /* Zephyr callback */ - struct gpio_callback callback; /* IRQ handler from platform/ec code */ void (*const irq_handler)(enum gpio_signal signal); /* Interrupt-related gpio flags */ @@ -104,31 +102,59 @@ EC_CROS_GPIO_INTERRUPTS #endif #undef GPIO_INT +/* + * Create unique enum values for each GPIO_INT entry, which also sets + * the ZEPHYR_GPIO_INT_COUNT value. + */ +#define ZEPHYR_GPIO_INT_ID(sig) INT_##sig +#define GPIO_INT(sig, f, cb) ZEPHYR_GPIO_INT_ID(sig), +enum zephyr_gpio_int_id { +#ifdef EC_CROS_GPIO_INTERRUPTS + EC_CROS_GPIO_INTERRUPTS +#endif + ZEPHYR_GPIO_INT_COUNT, +}; +#undef GPIO_INT + +/* Create prototypes for each GPIO IRQ handler */ #define GPIO_INT(sig, f, cb) void cb(enum gpio_signal signal); #ifdef EC_CROS_GPIO_INTERRUPTS EC_CROS_GPIO_INTERRUPTS #endif #undef GPIO_INT +/* + * The Zephyr gpio_callback data needs to be updated at runtime, so allocate + * into uninitialized data (BSS). The constant data pulled from + * EC_CROS_GPIO_INTERRUPTS is stored separately in the gpio_interrupts[] array. + */ +static struct gpio_callback zephyr_gpio_callbacks[ZEPHYR_GPIO_INT_COUNT]; + +#define ZEPHYR_GPIO_CALLBACK_TO_INDEX(cb) \ + (int)(((int)(cb) - (int)&zephyr_gpio_callbacks) / \ + sizeof(struct gpio_callback)) + #define GPIO_INT(sig, f, cb) \ { \ .signal = sig, \ .flags = f, \ .irq_handler = cb, \ }, -struct gpio_signal_callback gpio_interrupts[] = { +const static struct gpio_signal_callback + gpio_interrupts[ZEPHYR_GPIO_INT_COUNT] = { #ifdef EC_CROS_GPIO_INTERRUPTS - EC_CROS_GPIO_INTERRUPTS + EC_CROS_GPIO_INTERRUPTS #endif #undef GPIO_INT -}; + }; /* The single zephyr gpio handler that routes to appropriate platform/ec cb */ static void gpio_handler_shim(const struct device *port, struct gpio_callback *cb, gpio_port_pins_t pins) { + int callback_index = ZEPHYR_GPIO_CALLBACK_TO_INDEX(cb); const struct gpio_signal_callback *const gpio = - CONTAINER_OF(cb, struct gpio_signal_callback, callback); + &gpio_interrupts[callback_index]; /* Call the platform/ec gpio interrupt handler */ gpio->irq_handler(gpio->signal); @@ -143,7 +169,7 @@ static void gpio_handler_shim(const struct device *port, * Return: A pointer to the corresponding entry in gpio_interrupts, or * NULL if one does not exist. */ -static struct gpio_signal_callback * +const static struct gpio_signal_callback * get_interrupt_from_signal(enum gpio_signal signal) { if (!gpio_is_implemented(signal)) @@ -320,10 +346,10 @@ static int init_gpios(const struct device *unused) if (signal == GPIO_UNIMPLEMENTED) continue; - gpio_init_callback(&gpio_interrupts[i].callback, - gpio_handler_shim, BIT(configs[signal].pin)); + gpio_init_callback(&zephyr_gpio_callbacks[i], gpio_handler_shim, + BIT(configs[signal].pin)); rv = gpio_add_callback(data[signal].dev, - &gpio_interrupts[i].callback); + &zephyr_gpio_callbacks[i]); if (rv < 0) { LOG_ERR("Callback reg failed %s (%d)", @@ -352,7 +378,7 @@ SYS_INIT(init_gpios, POST_KERNEL, CONFIG_PLATFORM_EC_GPIO_INIT_PRIORITY); int gpio_enable_interrupt(enum gpio_signal signal) { int rv; - struct gpio_signal_callback *interrupt; + const struct gpio_signal_callback *interrupt; interrupt = get_interrupt_from_signal(signal); |