From a905b84fd1264d826b8e724839f52925a38f5926 Mon Sep 17 00:00:00 2001 From: "Vic (Chun-Ju) Yang" Date: Mon, 16 Dec 2013 16:09:20 +0800 Subject: mec1322: handle dummy GPIO gracefully When a GPIO signal is defined by GPIO_SIGNAL_NOT_IMPLEMENTED, it should still be able to call various GPIO methods on that GPIO signal. Since __builtin_clz dies when the value passed in is zero, we need to check this before calling __builtin_clz. BUG=chrome-os-partner:24107 TEST='sysjump RW' and the system doesn't crash BRANCH=None Change-Id: I5025a2f218d549316fe096c07bd3c7207fe9dbc2 Signed-off-by: Vic (Chun-Ju) Yang Reviewed-on: https://chromium-review.googlesource.com/180183 Reviewed-by: Randall Spangler --- chip/mec1322/gpio.c | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/chip/mec1322/gpio.c b/chip/mec1322/gpio.c index 6569985c67..9094401f61 100644 --- a/chip/mec1322/gpio.c +++ b/chip/mec1322/gpio.c @@ -46,8 +46,13 @@ void gpio_set_alternate_function(uint32_t port, uint32_t mask, int func) test_mockable int gpio_get_level(enum gpio_signal signal) { uint32_t mask = gpio_list[signal].mask; - int i = 31 - __builtin_clz(mask); - uint32_t val = MEC1322_GPIO_CTL(gpio_list[signal].port, i); + int i; + uint32_t val; + + if (mask == 0) + return 0; + i = 31 - __builtin_clz(mask); + val = MEC1322_GPIO_CTL(gpio_list[signal].port, i); if (val & (1 << 9)) /* Output */ return (val & (1 << 16)) ? 1 : 0; @@ -58,7 +63,12 @@ test_mockable int gpio_get_level(enum gpio_signal signal) void gpio_set_level(enum gpio_signal signal, int value) { uint32_t mask = gpio_list[signal].mask; - int i = 31 - __builtin_clz(mask); + int i; + + if (mask == 0) + return; + i = 31 - __builtin_clz(mask); + if (value) MEC1322_GPIO_CTL(gpio_list[signal].port, i) |= (1 << 16); else @@ -132,10 +142,15 @@ void gpio_set_flags_by_mask(uint32_t port, uint32_t mask, uint32_t flags) int gpio_enable_interrupt(enum gpio_signal signal) { - int i = 31 - __builtin_clz(gpio_list[signal].mask); - int port = gpio_list[signal].port; - int girq_id = int_map[port].girq_id; - int bit_id = (port - int_map[port].port_offset) * 8 + i; + int i, port, girq_id, bit_id; + + if (gpio_list[signal].mask == 0) + return EC_SUCCESS; + + i = 31 - __builtin_clz(gpio_list[signal].mask); + port = gpio_list[signal].port; + girq_id = int_map[port].girq_id; + bit_id = (port - int_map[port].port_offset) * 8 + i; MEC1322_INT_ENABLE(girq_id) |= (1 << bit_id); MEC1322_INT_BLK_EN |= (1 << girq_id); @@ -145,10 +160,15 @@ int gpio_enable_interrupt(enum gpio_signal signal) int gpio_disable_interrupt(enum gpio_signal signal) { - int i = 31 - __builtin_clz(gpio_list[signal].mask); - int port = gpio_list[signal].port; - int girq_id = int_map[port].girq_id; - int bit_id = (port - int_map[port].port_offset) * 8 + i; + int i, port, girq_id, bit_id; + + if (gpio_list[signal].mask == 0) + return EC_SUCCESS; + + i = 31 - __builtin_clz(gpio_list[signal].mask); + port = gpio_list[signal].port; + girq_id = int_map[port].girq_id; + bit_id = (port - int_map[port].port_offset) * 8 + i; MEC1322_INT_DISABLE(girq_id) |= (1 << bit_id); -- cgit v1.2.1