From: Shiji Yang Date: Sat, 16 Mar 2024 00:39:16 +0000 (+0800) Subject: ath79: add MikroTik suffix to the local GPIO latch driver X-Git-Url: http://git.openwrt.org/?a=commitdiff_plain;h=e155e3bd093109744f77f884fa731e51fb2edb42;p=openwrt%2Fopenwrt.git ath79: add MikroTik suffix to the local GPIO latch driver The upcoming 6.6 kernel will introduce a new upstream generic "gpio-latch" driver. It will conflict with the downstream MikroTik GPIO latch driver. Let's rename it to avoid any potential issues. Signed-off-by: Shiji Yang --- diff --git a/target/linux/ath79/config-6.1 b/target/linux/ath79/config-6.1 index f2a6969aa1..87f520228f 100644 --- a/target/linux/ath79/config-6.1 +++ b/target/linux/ath79/config-6.1 @@ -81,7 +81,7 @@ CONFIG_GPIO_74X164=y CONFIG_GPIO_ATH79=y CONFIG_GPIO_CDEV=y CONFIG_GPIO_GENERIC=y -# CONFIG_GPIO_LATCH is not set +# CONFIG_GPIO_LATCH_MIKROTIK is not set # CONFIG_GPIO_RB91X_KEY is not set CONFIG_HARDWARE_WATCHPOINTS=y CONFIG_HAS_DMA=y diff --git a/target/linux/ath79/dts/ar9342_mikrotik_routerboard-911g.dtsi b/target/linux/ath79/dts/ar9342_mikrotik_routerboard-911g.dtsi index 5f9d8e42fb..0c98a6634e 100644 --- a/target/linux/ath79/dts/ar9342_mikrotik_routerboard-911g.dtsi +++ b/target/linux/ath79/dts/ar9342_mikrotik_routerboard-911g.dtsi @@ -22,7 +22,7 @@ }; gpio_latch: gpio_latch { - compatible = "gpio-latch"; + compatible = "gpio-latch-mikrotik"; gpio-controller; #gpio-cells = <2>; gpios = <&gpio 0 GPIO_ACTIVE_HIGH>, diff --git a/target/linux/ath79/files/drivers/gpio/gpio-latch-mikrotik.c b/target/linux/ath79/files/drivers/gpio/gpio-latch-mikrotik.c new file mode 100644 index 0000000000..8f53974e46 --- /dev/null +++ b/target/linux/ath79/files/drivers/gpio/gpio-latch-mikrotik.c @@ -0,0 +1,205 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * GPIO latch driver + * + * Copyright (C) 2014 Gabor Juhos + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define GPIO_LATCH_DRIVER_NAME "gpio-latch-mikrotik" +#define GPIO_LATCH_LINES 9 + +struct gpio_latch_chip { + struct gpio_chip gc; + struct mutex mutex; + struct mutex latch_mutex; + bool latch_enabled; + int le_gpio; + bool le_active_low; + struct gpio_desc *gpios[GPIO_LATCH_LINES]; +}; + +static inline struct gpio_latch_chip *to_gpio_latch_chip(struct gpio_chip *gc) +{ + return container_of(gc, struct gpio_latch_chip, gc); +} + +static void gpio_latch_lock(struct gpio_latch_chip *glc, bool enable) +{ + mutex_lock(&glc->mutex); + + if (enable) + glc->latch_enabled = true; + + if (glc->latch_enabled) + mutex_lock(&glc->latch_mutex); +} + +static void gpio_latch_unlock(struct gpio_latch_chip *glc, bool disable) +{ + if (glc->latch_enabled) + mutex_unlock(&glc->latch_mutex); + + if (disable) + glc->latch_enabled = true; + + mutex_unlock(&glc->mutex); +} + +static int +gpio_latch_get(struct gpio_chip *gc, unsigned offset) +{ + struct gpio_latch_chip *glc = to_gpio_latch_chip(gc); + int ret; + + gpio_latch_lock(glc, false); + ret = gpiod_get_raw_value_cansleep(glc->gpios[offset]); + gpio_latch_unlock(glc, false); + + return ret; +} + +static void +gpio_latch_set(struct gpio_chip *gc, unsigned offset, int value) +{ + struct gpio_latch_chip *glc = to_gpio_latch_chip(gc); + bool enable_latch = false; + bool disable_latch = false; + + if (offset == glc->le_gpio) { + enable_latch = value ^ glc->le_active_low; + disable_latch = !enable_latch; + } + + gpio_latch_lock(glc, enable_latch); + gpiod_set_raw_value_cansleep(glc->gpios[offset], value); + gpio_latch_unlock(glc, disable_latch); +} + +static int +gpio_latch_direction_output(struct gpio_chip *gc, unsigned offset, int value) +{ + struct gpio_latch_chip *glc = to_gpio_latch_chip(gc); + bool enable_latch = false; + bool disable_latch = false; + int ret; + + if (offset == glc->le_gpio) { + enable_latch = value ^ glc->le_active_low; + disable_latch = !enable_latch; + } + + gpio_latch_lock(glc, enable_latch); + ret = gpiod_direction_output_raw(glc->gpios[offset], value); + gpio_latch_unlock(glc, disable_latch); + + return ret; +} + +static int gpio_latch_probe(struct platform_device *pdev) +{ + struct gpio_latch_chip *glc; + struct gpio_chip *gc; + struct device *dev = &pdev->dev; + struct fwnode_handle *fwnode = dev->fwnode; + int i, n; + + glc = devm_kzalloc(dev, sizeof(*glc), GFP_KERNEL); + if (!glc) + return -ENOMEM; + + mutex_init(&glc->mutex); + mutex_init(&glc->latch_mutex); + + n = gpiod_count(dev, NULL); + if (n <= 0) { + dev_err(dev, "failed to get gpios: %d\n", n); + return n; + } else if (n != GPIO_LATCH_LINES) { + dev_err(dev, "expected %d gpios\n", GPIO_LATCH_LINES); + return -EINVAL; + } + + for (i = 0; i < n; i++) { + glc->gpios[i] = devm_gpiod_get_index_optional(dev, NULL, i, + GPIOD_OUT_LOW); + if (IS_ERR(glc->gpios[i])) { + if (PTR_ERR(glc->gpios[i]) != -EPROBE_DEFER) { + dev_err(dev, "failed to get gpio %d: %ld\n", i, + PTR_ERR(glc->gpios[i])); + } + return PTR_ERR(glc->gpios[i]); + } + } + + glc->le_gpio = 8; + glc->le_active_low = gpiod_is_active_low(glc->gpios[glc->le_gpio]); + + if (!glc->gpios[glc->le_gpio]) { + dev_err(dev, "missing required latch-enable gpio %d\n", + glc->le_gpio); + return -EINVAL; + } + + gc = &glc->gc; + gc->label = GPIO_LATCH_DRIVER_NAME; + gc->can_sleep = true; + gc->base = -1; + gc->ngpio = GPIO_LATCH_LINES; + gc->get = gpio_latch_get; + gc->set = gpio_latch_set; + gc->direction_output = gpio_latch_direction_output; + gc->fwnode = fwnode; + + platform_set_drvdata(pdev, glc); + + i = gpiochip_add(&glc->gc); + if (i) { + dev_err(dev, "gpiochip_add() failed: %d\n", i); + return i; + } + + return 0; +} + +static int gpio_latch_remove(struct platform_device *pdev) +{ + struct gpio_latch_chip *glc = platform_get_drvdata(pdev); + + gpiochip_remove(&glc->gc); + return 0; +} + +static const struct of_device_id gpio_latch_match[] = { + { .compatible = GPIO_LATCH_DRIVER_NAME }, + {}, +}; + +MODULE_DEVICE_TABLE(of, gpio_latch_match); + +static struct platform_driver gpio_latch_driver = { + .probe = gpio_latch_probe, + .remove = gpio_latch_remove, + .driver = { + .name = GPIO_LATCH_DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = gpio_latch_match, + }, +}; + +module_platform_driver(gpio_latch_driver); + +MODULE_DESCRIPTION("GPIO latch driver"); +MODULE_AUTHOR("Gabor Juhos "); +MODULE_AUTHOR("Denis Kalashnikov "); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" GPIO_LATCH_DRIVER_NAME); diff --git a/target/linux/ath79/files/drivers/gpio/gpio-latch.c b/target/linux/ath79/files/drivers/gpio/gpio-latch.c deleted file mode 100644 index 5518184caa..0000000000 --- a/target/linux/ath79/files/drivers/gpio/gpio-latch.c +++ /dev/null @@ -1,205 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * GPIO latch driver - * - * Copyright (C) 2014 Gabor Juhos - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define GPIO_LATCH_DRIVER_NAME "gpio-latch" -#define GPIO_LATCH_LINES 9 - -struct gpio_latch_chip { - struct gpio_chip gc; - struct mutex mutex; - struct mutex latch_mutex; - bool latch_enabled; - int le_gpio; - bool le_active_low; - struct gpio_desc *gpios[GPIO_LATCH_LINES]; -}; - -static inline struct gpio_latch_chip *to_gpio_latch_chip(struct gpio_chip *gc) -{ - return container_of(gc, struct gpio_latch_chip, gc); -} - -static void gpio_latch_lock(struct gpio_latch_chip *glc, bool enable) -{ - mutex_lock(&glc->mutex); - - if (enable) - glc->latch_enabled = true; - - if (glc->latch_enabled) - mutex_lock(&glc->latch_mutex); -} - -static void gpio_latch_unlock(struct gpio_latch_chip *glc, bool disable) -{ - if (glc->latch_enabled) - mutex_unlock(&glc->latch_mutex); - - if (disable) - glc->latch_enabled = true; - - mutex_unlock(&glc->mutex); -} - -static int -gpio_latch_get(struct gpio_chip *gc, unsigned offset) -{ - struct gpio_latch_chip *glc = to_gpio_latch_chip(gc); - int ret; - - gpio_latch_lock(glc, false); - ret = gpiod_get_raw_value_cansleep(glc->gpios[offset]); - gpio_latch_unlock(glc, false); - - return ret; -} - -static void -gpio_latch_set(struct gpio_chip *gc, unsigned offset, int value) -{ - struct gpio_latch_chip *glc = to_gpio_latch_chip(gc); - bool enable_latch = false; - bool disable_latch = false; - - if (offset == glc->le_gpio) { - enable_latch = value ^ glc->le_active_low; - disable_latch = !enable_latch; - } - - gpio_latch_lock(glc, enable_latch); - gpiod_set_raw_value_cansleep(glc->gpios[offset], value); - gpio_latch_unlock(glc, disable_latch); -} - -static int -gpio_latch_direction_output(struct gpio_chip *gc, unsigned offset, int value) -{ - struct gpio_latch_chip *glc = to_gpio_latch_chip(gc); - bool enable_latch = false; - bool disable_latch = false; - int ret; - - if (offset == glc->le_gpio) { - enable_latch = value ^ glc->le_active_low; - disable_latch = !enable_latch; - } - - gpio_latch_lock(glc, enable_latch); - ret = gpiod_direction_output_raw(glc->gpios[offset], value); - gpio_latch_unlock(glc, disable_latch); - - return ret; -} - -static int gpio_latch_probe(struct platform_device *pdev) -{ - struct gpio_latch_chip *glc; - struct gpio_chip *gc; - struct device *dev = &pdev->dev; - struct fwnode_handle *fwnode = dev->fwnode; - int i, n; - - glc = devm_kzalloc(dev, sizeof(*glc), GFP_KERNEL); - if (!glc) - return -ENOMEM; - - mutex_init(&glc->mutex); - mutex_init(&glc->latch_mutex); - - n = gpiod_count(dev, NULL); - if (n <= 0) { - dev_err(dev, "failed to get gpios: %d\n", n); - return n; - } else if (n != GPIO_LATCH_LINES) { - dev_err(dev, "expected %d gpios\n", GPIO_LATCH_LINES); - return -EINVAL; - } - - for (i = 0; i < n; i++) { - glc->gpios[i] = devm_gpiod_get_index_optional(dev, NULL, i, - GPIOD_OUT_LOW); - if (IS_ERR(glc->gpios[i])) { - if (PTR_ERR(glc->gpios[i]) != -EPROBE_DEFER) { - dev_err(dev, "failed to get gpio %d: %ld\n", i, - PTR_ERR(glc->gpios[i])); - } - return PTR_ERR(glc->gpios[i]); - } - } - - glc->le_gpio = 8; - glc->le_active_low = gpiod_is_active_low(glc->gpios[glc->le_gpio]); - - if (!glc->gpios[glc->le_gpio]) { - dev_err(dev, "missing required latch-enable gpio %d\n", - glc->le_gpio); - return -EINVAL; - } - - gc = &glc->gc; - gc->label = GPIO_LATCH_DRIVER_NAME; - gc->can_sleep = true; - gc->base = -1; - gc->ngpio = GPIO_LATCH_LINES; - gc->get = gpio_latch_get; - gc->set = gpio_latch_set; - gc->direction_output = gpio_latch_direction_output; - gc->fwnode = fwnode; - - platform_set_drvdata(pdev, glc); - - i = gpiochip_add(&glc->gc); - if (i) { - dev_err(dev, "gpiochip_add() failed: %d\n", i); - return i; - } - - return 0; -} - -static int gpio_latch_remove(struct platform_device *pdev) -{ - struct gpio_latch_chip *glc = platform_get_drvdata(pdev); - - gpiochip_remove(&glc->gc); - return 0; -} - -static const struct of_device_id gpio_latch_match[] = { - { .compatible = GPIO_LATCH_DRIVER_NAME }, - {}, -}; - -MODULE_DEVICE_TABLE(of, gpio_latch_match); - -static struct platform_driver gpio_latch_driver = { - .probe = gpio_latch_probe, - .remove = gpio_latch_remove, - .driver = { - .name = GPIO_LATCH_DRIVER_NAME, - .owner = THIS_MODULE, - .of_match_table = gpio_latch_match, - }, -}; - -module_platform_driver(gpio_latch_driver); - -MODULE_DESCRIPTION("GPIO latch driver"); -MODULE_AUTHOR("Gabor Juhos "); -MODULE_AUTHOR("Denis Kalashnikov "); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:" GPIO_LATCH_DRIVER_NAME); diff --git a/target/linux/ath79/mikrotik/config-default b/target/linux/ath79/mikrotik/config-default index a231188c83..3fe5cd4979 100644 --- a/target/linux/ath79/mikrotik/config-default +++ b/target/linux/ath79/mikrotik/config-default @@ -3,7 +3,7 @@ CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_HASH_INFO=y CONFIG_CRYPTO_LZO=y CONFIG_CRYPTO_ZSTD=y -CONFIG_GPIO_LATCH=y +CONFIG_GPIO_LATCH_MIKROTIK=y CONFIG_GPIO_RB4XX=y CONFIG_GPIO_RB91X_KEY=y CONFIG_GPIO_WATCHDOG=y diff --git a/target/linux/ath79/patches-6.1/911-mikrotik-rb91x.patch b/target/linux/ath79/patches-6.1/911-mikrotik-rb91x.patch index 768ab6fb49..677428fa65 100644 --- a/target/linux/ath79/patches-6.1/911-mikrotik-rb91x.patch +++ b/target/linux/ath79/patches-6.1/911-mikrotik-rb91x.patch @@ -33,7 +33,7 @@ Tested-by: Koen Vandeputte If unsure, say N. -+config GPIO_LATCH ++config GPIO_LATCH_MIKROTIK + tristate "MikroTik RouterBOARD GPIO latch support" + depends on ATH79 + help @@ -59,7 +59,7 @@ Tested-by: Koen Vandeputte obj-$(CONFIG_GPIO_IXP4XX) += gpio-ixp4xx.o obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o obj-$(CONFIG_GPIO_KEMPLD) += gpio-kempld.o -+obj-$(CONFIG_GPIO_LATCH) += gpio-latch.o ++obj-$(CONFIG_GPIO_LATCH_MIKROTIK) += gpio-latch-mikrotik.o obj-$(CONFIG_GPIO_LOGICVC) += gpio-logicvc.o obj-$(CONFIG_GPIO_LOONGSON1) += gpio-loongson1.o obj-$(CONFIG_GPIO_LOONGSON) += gpio-loongson.o