]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
MIPS/input: Move RB532 button to GPIO descriptors
authorLinus Walleij <linusw@kernel.org>
Sat, 28 Mar 2026 15:55:47 +0000 (16:55 +0100)
committerThomas Bogendoerfer <tsbogend@alpha.franken.de>
Mon, 13 Apr 2026 13:41:56 +0000 (15:41 +0200)
Convert the Mikrotik RouterBoard RB532 to use GPIO descriptors
by defining a software node for the GPIO chip, then register
the button platform device with full info passing the GPIO
as a device property.

This can be used as a base to move more of the RB532 devices
over to passing GPIOs using device properties.

Use the GPIO_ACTIVE_LOW flag and drop the inversion in the
rb532_button_pressed() function.

Signed-off-by: Linus Walleij <linusw@kernel.org>
Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
arch/mips/rb532/devices.c
drivers/input/misc/rb532_button.c

index 4f027efbf27b05377ddac306ff16714b8764915b..3f56d9feb73a50113e5d73fcd5515f6836521e79 100644 (file)
 #include <linux/mtd/mtd.h>
 #include <linux/gpio.h>
 #include <linux/gpio/machine.h>
+#include <linux/gpio/property.h>
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
+#include <linux/property.h>
 #include <linux/serial_8250.h>
 
 #include <asm/bootinfo.h>
@@ -38,6 +40,10 @@ extern unsigned int idt_cpu_freq;
 
 static struct mpmc_device dev3;
 
+static const struct software_node rb532_gpio0_node = {
+       .name = "gpio0",
+};
+
 void set_latch_u5(unsigned char or_mask, unsigned char nand_mask)
 {
        unsigned long flags;
@@ -189,11 +195,6 @@ static struct platform_device rb532_led = {
        .id = -1,
 };
 
-static struct platform_device rb532_button = {
-       .name   = "rb532-button",
-       .id     = -1,
-};
-
 static struct resource rb532_wdt_res[] = {
        {
                .name = "rb532_wdt_res",
@@ -236,11 +237,23 @@ static struct platform_device *rb532_devs[] = {
        &nand_slot0,
        &cf_slot0,
        &rb532_led,
-       &rb532_button,
        &rb532_uart,
        &rb532_wdt
 };
 
+static const struct property_entry rb532_button_properties[] = {
+       PROPERTY_ENTRY_GPIO("button-gpios", &rb532_gpio0_node,
+                           GPIO_BTN_S1, GPIO_ACTIVE_LOW),
+       { }
+};
+
+static const struct platform_device_info rb532_button_info  __initconst = {
+       .name           = "rb532-button",
+       .id             = PLATFORM_DEVID_NONE,
+       .properties     = rb532_button_properties,
+};
+
+
 /* NAND definitions */
 #define NAND_CHIP_DELAY 25
 
@@ -267,6 +280,9 @@ static void __init rb532_nand_setup(void)
 
 static int __init plat_setup_devices(void)
 {
+       struct platform_device *pd;
+       int ret;
+
        /* Look for the CF card reader */
        if (!readl(IDT434_REG_BASE + DEV1MASK))
                rb532_devs[2] = NULL;   /* disable cf_slot0 at index 2 */
@@ -295,7 +311,24 @@ static int __init plat_setup_devices(void)
        rb532_uart_res[0].uartclk = idt_cpu_freq;
 
        gpiod_add_lookup_table(&cf_slot0_gpio_table);
-       return platform_add_devices(rb532_devs, ARRAY_SIZE(rb532_devs));
+       ret = platform_add_devices(rb532_devs, ARRAY_SIZE(rb532_devs));
+       if (ret)
+               return ret;
+
+       /*
+        * Stack devices using full info and properties here, after we
+        * register the node for the GPIO chip.
+        */
+       software_node_register(&rb532_gpio0_node);
+
+       pd = platform_device_register_full(&rb532_button_info);
+       ret = PTR_ERR_OR_ZERO(pd);
+       if (ret) {
+               pr_err("failed to create RB532 button device: %d\n", ret);
+               return ret;
+       }
+
+       return 0;
 }
 
 #ifdef CONFIG_NET
index 190a80e1e2c16eace4a690665c2f35af5e6d388a..40173bf7a23504a5a8813e1d1b6eccf974d85de9 100644 (file)
@@ -8,7 +8,7 @@
 #include <linux/input.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 
 #include <asm/mach-rc32434/gpio.h>
 #include <asm/mach-rc32434/rb.h>
 #define RB532_BTN_RATE 100 /* msec */
 #define RB532_BTN_KSYM BTN_0
 
+/**
+ * struct rb532_button - RB532 button information
+ * @gpio: GPIO connected to the button
+ */
+struct rb532_button {
+       struct gpio_desc        *gpio;
+};
+
 /* The S1 button state is provided by GPIO pin 1. But as this
  * pin is also used for uart input as alternate function, the
  * operational modes must be switched first:
  * The GPIO value occurs to be inverted, so pin high means
  * button is not pressed.
  */
-static bool rb532_button_pressed(void)
+static bool rb532_button_pressed(struct rb532_button *button)
 {
        int val;
 
        set_latch_u5(0, LO_FOFF);
-       gpio_direction_input(GPIO_BTN_S1);
+       gpiod_direction_input(button->gpio);
 
-       val = gpio_get_value(GPIO_BTN_S1);
+       val = gpiod_get_value(button->gpio);
 
        rb532_gpio_set_func(GPIO_BTN_S1);
        set_latch_u5(LO_FOFF, 0);
 
-       return !val;
+       return val;
 }
 
 static void rb532_button_poll(struct input_dev *input)
 {
-       input_report_key(input, RB532_BTN_KSYM, rb532_button_pressed());
+       struct rb532_button *button = input_get_drvdata(input);
+
+       input_report_key(input, RB532_BTN_KSYM, rb532_button_pressed(button));
        input_sync(input);
 }
 
 static int rb532_button_probe(struct platform_device *pdev)
 {
+       struct rb532_button *button;
        struct input_dev *input;
        int error;
 
+       button = devm_kzalloc(&pdev->dev, sizeof(*button), GFP_KERNEL);
+       if (!button)
+               return -ENOMEM;
+
+       button->gpio = devm_gpiod_get(&pdev->dev, "button", GPIOD_IN);
+       if (IS_ERR(button->gpio))
+               return dev_err_probe(&pdev->dev, PTR_ERR(button->gpio),
+                                    "error getting button GPIO\n");
+
        input = devm_input_allocate_device(&pdev->dev);
        if (!input)
                return -ENOMEM;
+       input_set_drvdata(input, button);
 
        input->name = "rb532 button";
        input->phys = "rb532/button0";
@@ -77,6 +98,8 @@ static int rb532_button_probe(struct platform_device *pdev)
        if (error)
                return error;
 
+       platform_set_drvdata(pdev, button);
+
        return 0;
 }