summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0041-Enable-passthrough-based-gpio-character-device.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0041-Enable-passthrough-based-gpio-character-device.patch')
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0041-Enable-passthrough-based-gpio-character-device.patch287
1 files changed, 0 insertions, 287 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0041-Enable-passthrough-based-gpio-character-device.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0041-Enable-passthrough-based-gpio-character-device.patch
deleted file mode 100644
index 7a4b090ec..000000000
--- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0041-Enable-passthrough-based-gpio-character-device.patch
+++ /dev/null
@@ -1,287 +0,0 @@
-From 554bc7a7c7aa6e0c0ec49a24063102e17954d06c Mon Sep 17 00:00:00 2001
-From: Kuiying Wang <kuiying.wang@intel.com>
-Date: Thu, 31 Jan 2019 17:47:39 +0800
-Subject: [PATCH] Enable passthrough based gpio character device.
-
-Signed-off-by: Kuiying Wang <kuiying.wang@intel.com>
----
- drivers/gpio/gpio-aspeed.c | 47 ++++++++++++++++++++++++++++--
- drivers/gpio/gpiolib.c | 51 +++++++++++++++++++++++++++++++--
- drivers/gpio/gpiolib.h | 1 +
- include/linux/gpio/consumer.h | 9 ++++++
- include/linux/pinctrl/pinconf-generic.h | 2 ++
- include/uapi/linux/gpio.h | 1 +
- 6 files changed, 106 insertions(+), 5 deletions(-)
-
-diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c
-index 854bce4fb9e7..5f1bce3a9274 100644
---- a/drivers/gpio/gpio-aspeed.c
-+++ b/drivers/gpio/gpio-aspeed.c
-@@ -17,9 +17,11 @@
- #include <linux/init.h>
- #include <linux/io.h>
- #include <linux/kernel.h>
-+#include <linux/mfd/syscon.h>
- #include <linux/module.h>
- #include <linux/pinctrl/consumer.h>
- #include <linux/platform_device.h>
-+#include <linux/regmap.h>
- #include <linux/spinlock.h>
- #include <linux/string.h>
-
-@@ -58,6 +60,7 @@ struct aspeed_gpio {
- struct gpio_chip chip;
- spinlock_t lock;
- void __iomem *base;
-+ struct regmap *scu;
- int irq;
- const struct aspeed_gpio_config *config;
-
-@@ -91,6 +94,13 @@ struct aspeed_gpio_bank {
- * and thus can be used to read back what was last written
- * reliably.
- */
-+#define SCU8C 0x8C /* Multi-function Pin Control #4 */
-+#define PASS_THROUGH1 32
-+#define PASS_THROUGH2 34
-+#define PASS_THROUGH2_MASK 0x2000
-+#define PASS_THROUGH1_MASK 0x1000
-+#define PASS_THROUGH2_ON 0x2000
-+#define PASS_THROUGH1_ON 0x1000
-
- static const int debounce_timers[4] = { 0x00, 0x50, 0x54, 0x58 };
-
-@@ -988,12 +998,38 @@ static int set_debounce(struct gpio_chip *chip, unsigned int offset,
- return disable_debounce(chip, offset);
- }
-
-+static int aspeed_gpio_pass_through(struct gpio_chip *chip, unsigned int offset,
-+ unsigned long param)
-+{
-+ struct aspeed_gpio *gpio = gpiochip_get_data(chip);
-+ u32 value;
-+
-+ if (!gpio->scu)
-+ return -ENOTSUPP;
-+ if (param == PIN_CONFIG_PASS_THROUGH_ENABLE){
-+ if (offset == PASS_THROUGH2){
-+ regmap_update_bits(gpio->scu, SCU8C, PASS_THROUGH2_MASK, PASS_THROUGH2_ON);
-+ } else if (offset == PASS_THROUGH1){
-+ regmap_update_bits(gpio->scu, SCU8C, PASS_THROUGH1_MASK, PASS_THROUGH1_ON);
-+ }
-+ } else if (param == PIN_CONFIG_PASS_THROUGH_DISABLE){
-+ if (offset == PASS_THROUGH2){
-+ regmap_update_bits(gpio->scu, SCU8C, PASS_THROUGH2_MASK, ~(PASS_THROUGH2_ON));
-+ } else if (offset == PASS_THROUGH1){
-+ regmap_update_bits(gpio->scu, SCU8C, PASS_THROUGH1_MASK, ~(PASS_THROUGH1_ON));
-+ }
-+ } else {
-+ return -ENOTSUPP;
-+ }
-+
-+ return 0;
-+}
-+
- static int aspeed_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
- unsigned long config)
- {
- unsigned long param = pinconf_to_config_param(config);
- u32 arg = pinconf_to_config_argument(config);
--
- if (param == PIN_CONFIG_INPUT_DEBOUNCE)
- return set_debounce(chip, offset, arg);
- else if (param == PIN_CONFIG_BIAS_DISABLE ||
-@@ -1006,6 +1042,9 @@ static int aspeed_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
- return -ENOTSUPP;
- else if (param == PIN_CONFIG_PERSIST_STATE)
- return aspeed_gpio_reset_tolerance(chip, offset, arg);
-+ else if (param == PIN_CONFIG_PASS_THROUGH_ENABLE ||
-+ param == PIN_CONFIG_PASS_THROUGH_DISABLE)
-+ return aspeed_gpio_pass_through(chip, offset, param);
-
- return -ENOTSUPP;
- }
-@@ -1167,7 +1206,11 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev)
- gpio->base = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(gpio->base))
- return PTR_ERR(gpio->base);
--
-+ gpio->scu = syscon_regmap_lookup_by_compatible("aspeed,ast2500-scu");
-+ if (IS_ERR(gpio->scu)) {
-+ dev_err(&pdev->dev, "Failed to find SCU regmap\n");
-+ gpio->scu = NULL;
-+ }
- spin_lock_init(&gpio->lock);
-
- gpio_id = of_match_node(aspeed_gpio_of_table, pdev->dev.of_node);
-diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
-index d1adfdf50fb3..4f9fdd25c6d7 100644
---- a/drivers/gpio/gpiolib.c
-+++ b/drivers/gpio/gpiolib.c
-@@ -428,6 +428,7 @@ struct linehandle_state {
- GPIOHANDLE_REQUEST_OUTPUT | \
- GPIOHANDLE_REQUEST_ACTIVE_LOW | \
- GPIOHANDLE_REQUEST_OPEN_DRAIN | \
-+ GPIOHANDLE_REQUEST_PASS_THROUGH | \
- GPIOHANDLE_REQUEST_OPEN_SOURCE)
-
- static long linehandle_ioctl(struct file *filep, unsigned int cmd,
-@@ -530,7 +531,6 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip)
- return -EINVAL;
-
- lflags = handlereq.flags;
--
- /* Return an error if an unknown flag is set */
- if (lflags & ~GPIOHANDLE_REQUEST_VALID_FLAGS)
- return -EINVAL;
-@@ -590,6 +590,8 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip)
- set_bit(FLAG_OPEN_DRAIN, &desc->flags);
- if (lflags & GPIOHANDLE_REQUEST_OPEN_SOURCE)
- set_bit(FLAG_OPEN_SOURCE, &desc->flags);
-+ if (lflags & GPIOHANDLE_REQUEST_PASS_THROUGH)
-+ set_bit(FLAG_PASS_THROUGH, &desc->flags);
-
- ret = gpiod_set_transitory(desc, false);
- if (ret < 0)
-@@ -609,6 +611,11 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip)
- ret = gpiod_direction_input(desc);
- if (ret)
- goto out_free_descs;
-+ } else if (lflags & GPIOHANDLE_REQUEST_PASS_THROUGH) {
-+ int val = !!handlereq.default_values[i];
-+ ret = gpiod_direction_pass_through(desc, val);
-+ if (ret)
-+ goto out_free_descs;
- }
- dev_dbg(&gdev->dev, "registered chardev handle for line %d\n",
- offset);
-@@ -1027,7 +1034,6 @@ static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
- struct gpio_device *gdev = filp->private_data;
- struct gpio_chip *chip = gdev->chip;
- void __user *ip = (void __user *)arg;
--
- /* We fail any subsequent ioctl():s when the chip is gone */
- if (!chip)
- return -ENODEV;
-@@ -1035,7 +1041,6 @@ static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
- /* Fill in the struct and pass to userspace */
- if (cmd == GPIO_GET_CHIPINFO_IOCTL) {
- struct gpiochip_info chipinfo;
--
- memset(&chipinfo, 0, sizeof(chipinfo));
-
- strncpy(chipinfo.name, dev_name(&gdev->dev),
-@@ -2709,6 +2714,46 @@ int gpiod_direction_output(struct gpio_desc *desc, int value)
- EXPORT_SYMBOL_GPL(gpiod_direction_output);
-
- /**
-+ * gpiod_direction_pass_through - set the GPIO direction to pass-through
-+ * @desc: GPIO to set to pass-through
-+ *
-+ * Set the direction of the passed GPIO to passthrough.
-+ *
-+ * Return 0 in case of success, else an error code.
-+ */
-+int gpiod_direction_pass_through(struct gpio_desc *desc, int val)
-+{
-+ struct gpio_chip *gc;
-+
-+ VALIDATE_DESC(desc);
-+ /* GPIOs used for IRQs shall not be set as pass-through */
-+ if (test_bit(FLAG_USED_AS_IRQ, &desc->flags)) {
-+ gpiod_err(desc,
-+ "%s: tried to set a GPIO tied to an IRQ as pass-through\n",
-+ __func__);
-+ return -EIO;
-+ }
-+ gc = desc->gdev->chip;
-+ val = !!val;
-+ if (test_bit(FLAG_PASS_THROUGH, &desc->flags)) {
-+ if (val)
-+ gpio_set_config(gc, gpio_chip_hwgpio(desc),
-+ PIN_CONFIG_PASS_THROUGH_ENABLE);
-+ else
-+ gpio_set_config(gc, gpio_chip_hwgpio(desc),
-+ PIN_CONFIG_PASS_THROUGH_DISABLE);
-+ } else {
-+ gpiod_err(desc,
-+ "%s: desc->flags is not set to FLAG_PASS_THROUGH\n",
-+ __func__);
-+ return -EIO;
-+ }
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(gpiod_direction_pass_through);
-+
-+/**
- * gpiod_set_debounce - sets @debounce time for a GPIO
- * @desc: descriptor of the GPIO for which to set debounce time
- * @debounce: debounce time in microseconds
-diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
-index bc57f0dc5953..a821a04fc04b 100644
---- a/drivers/gpio/gpiolib.h
-+++ b/drivers/gpio/gpiolib.h
-@@ -212,6 +212,7 @@ struct gpio_desc {
- #define FLAG_IS_OUT 1
- #define FLAG_EXPORT 2 /* protected by sysfs_lock */
- #define FLAG_SYSFS 3 /* exported via /sys/class/gpio/control */
-+#define FLAG_PASS_THROUGH 4 /*Gpio is passthrough type*/
- #define FLAG_ACTIVE_LOW 6 /* value has active low */
- #define FLAG_OPEN_DRAIN 7 /* Gpio is open drain type */
- #define FLAG_OPEN_SOURCE 8 /* Gpio is open source type */
-diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h
-index 9ddcf50a3c59..f9775be5a46a 100644
---- a/include/linux/gpio/consumer.h
-+++ b/include/linux/gpio/consumer.h
-@@ -110,6 +110,7 @@ void devm_gpiod_put_array(struct device *dev, struct gpio_descs *descs);
- int gpiod_get_direction(struct gpio_desc *desc);
- int gpiod_direction_input(struct gpio_desc *desc);
- int gpiod_direction_output(struct gpio_desc *desc, int value);
-+int gpiod_direction_pass_through(struct gpio_desc *desc, int val);
- int gpiod_direction_output_raw(struct gpio_desc *desc, int value);
-
- /* Value get/set from non-sleeping context */
-@@ -348,6 +349,14 @@ static inline int gpiod_direction_output(struct gpio_desc *desc, int value)
- WARN_ON(1);
- return -ENOSYS;
- }
-+
-+static inline int gpiod_direction_pass_through(struct gpio_desc *desc, int val)
-+{
-+ /* GPIO can never have been requested */
-+ WARN_ON(1);
-+ return -ENOSYS;
-+}
-+
- static inline int gpiod_direction_output_raw(struct gpio_desc *desc, int value)
- {
- /* GPIO can never have been requested */
-diff --git a/include/linux/pinctrl/pinconf-generic.h b/include/linux/pinctrl/pinconf-generic.h
-index 6c0680641108..59f0cbabb685 100644
---- a/include/linux/pinctrl/pinconf-generic.h
-+++ b/include/linux/pinctrl/pinconf-generic.h
-@@ -124,6 +124,8 @@ enum pin_config_param {
- PIN_CONFIG_SLEW_RATE,
- PIN_CONFIG_SKEW_DELAY,
- PIN_CONFIG_PERSIST_STATE,
-+ PIN_CONFIG_PASS_THROUGH_ENABLE,
-+ PIN_CONFIG_PASS_THROUGH_DISABLE,
- PIN_CONFIG_END = 0x7F,
- PIN_CONFIG_MAX = 0xFF,
- };
-diff --git a/include/uapi/linux/gpio.h b/include/uapi/linux/gpio.h
-index 4ebfe0ac6c5b..99864572b7d9 100644
---- a/include/uapi/linux/gpio.h
-+++ b/include/uapi/linux/gpio.h
-@@ -62,6 +62,7 @@ struct gpioline_info {
- #define GPIOHANDLE_REQUEST_ACTIVE_LOW (1UL << 2)
- #define GPIOHANDLE_REQUEST_OPEN_DRAIN (1UL << 3)
- #define GPIOHANDLE_REQUEST_OPEN_SOURCE (1UL << 4)
-+#define GPIOHANDLE_REQUEST_PASS_THROUGH (1UL << 5)
-
- /**
- * struct gpiohandle_request - Information about a GPIO handle request
---
-2.7.4
-