summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Short <keithshort@chromium.org>2021-09-17 13:05:19 -0600
committerCommit Bot <commit-bot@chromium.org>2021-09-18 00:07:46 +0000
commit2bfcf8da1d696783cf8a83bb2350d6931879c148 (patch)
tree4a56a4d27bc66188d2fdb3eb2cce53b89fe8d914
parentef1a31ced60aba0e1b54c8ae2c28e6c3fdd6f4c1 (diff)
downloadchrome-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>
-rw-r--r--zephyr/shim/src/gpio.c50
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);