summaryrefslogtreecommitdiff
path: root/io-module/gpio.c
diff options
context:
space:
mode:
authorJohn Klug <john.klug@multitech.com>2021-10-29 10:45:43 -0500
committerJohn Klug <john.klug@multitech.com>2021-11-12 12:00:50 -0600
commitfdc6f30e9da19f19669ecfc6c66d02abf9057959 (patch)
tree1f30ba77204c5307aea4bf1ab4f73ff77495aa5c /io-module/gpio.c
parent0e772e1a11a545571232de6387699b73ac3278bf (diff)
downloadmts-io-fdc6f30e9da19f19669ecfc6c66d02abf9057959.tar.gz
mts-io-fdc6f30e9da19f19669ecfc6c66d02abf9057959.tar.bz2
mts-io-fdc6f30e9da19f19669ecfc6c66d02abf9057959.zip
MTCDT-0.2 with PCA9557 support
Diffstat (limited to 'io-module/gpio.c')
-rw-r--r--io-module/gpio.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/io-module/gpio.c b/io-module/gpio.c
index 0b45300..e754ed6 100644
--- a/io-module/gpio.c
+++ b/io-module/gpio.c
@@ -44,6 +44,14 @@ struct gpio_pin *gpio_pin_by_attr_name(const char *name) {
return NULL;
}
+/* Any gpio that could potentially get routed over an i2c bus
+ * as opposed to a memory write to a register must call
+ * "cansleep" versions of gpio functions. The purpose of the
+ * function is to remind kernel driver writers that any GPIO
+ * routed over i2c (or spi) cannot be accessed in an interrupt
+ * handler. Interrupt handlers should use the GPIO pins
+ * that are memory mapped. gpio_get_value and gpio_set_value
+ * cannot be used with the PCA 9557 or a dump will result. */
ssize_t mts_attr_show_gpio_pin(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -57,7 +65,7 @@ ssize_t mts_attr_show_gpio_pin(struct device *dev,
mutex_lock(&mts_io_mutex);
- value = gpio_get_value(pin->pin.gpio);
+ value = gpio_get_value_cansleep(pin->pin.gpio);
mutex_unlock(&mts_io_mutex);
@@ -92,7 +100,7 @@ static ssize_t mts_attr_store_gpio_pin(struct device *dev,
mutex_lock(&mts_io_mutex);
- gpio_set_value(pin->pin.gpio, value);
+ gpio_set_value_cansleep(pin->pin.gpio, value);
mutex_unlock(&mts_io_mutex);
@@ -105,11 +113,11 @@ static int reset_gpio_pin(struct gpio_pin *pin, unsigned int delay_ms, unsigned
return -ENODEV;
}
- gpio_set_value(pin->pin.gpio, value);
+ gpio_set_value_cansleep(pin->pin.gpio, value);
mdelay(delay_ms);
- gpio_set_value(pin->pin.gpio, !value);
+ gpio_set_value_cansleep(pin->pin.gpio, !value);
return 0;
}