Input: ams_delta_serio: use IRQ resource
authorJanusz Krzysztofik <jmkrzyszt@gmail.com>
Thu, 21 Jun 2018 22:41:27 +0000 (00:41 +0200)
committerTony Lindgren <tony@atomide.com>
Tue, 3 Jul 2018 06:05:14 +0000 (23:05 -0700)
The driver still obtains IRQ number from a hardcoded GPIO.  Use IRQ
resource instead.

For this to work on Amstrad Delta, add the IRQ resource to
ams-delta-serio platform device structure.  Obtain the IRQ number
assigned to "keybrd_clk" GPIO pin from FIQ initialization routine.

As a benefit, the driver no longer needs to include
<mach/board-ams-delta.h>.

Signed-off-by: Janusz Krzysztofik <jmkrzyszt@gmail.com>
Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
arch/arm/mach-omap1/ams-delta-fiq.c
arch/arm/mach-omap1/ams-delta-fiq.h
arch/arm/mach-omap1/board-ams-delta.c
drivers/input/serio/ams_delta_serio.c

index e729350..82ca424 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/module.h>
 #include <linux/io.h>
 #include <linux/platform_data/ams-delta-fiq.h>
+#include <linux/platform_device.h>
 
 #include <mach/board-ams-delta.h>
 
@@ -84,7 +85,8 @@ static irqreturn_t deferred_fiq(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-void __init ams_delta_init_fiq(struct gpio_chip *chip)
+void __init ams_delta_init_fiq(struct gpio_chip *chip,
+                              struct platform_device *serio)
 {
        struct gpio_desc *gpiod, *data = NULL, *clk = NULL;
        void *fiqhandler_start;
@@ -201,6 +203,22 @@ void __init ams_delta_init_fiq(struct gpio_chip *chip)
        val = omap_readl(OMAP_IH1_BASE + offset) | 1;
        omap_writel(val, OMAP_IH1_BASE + offset);
 
+       /* Initialize serio device IRQ resource */
+       serio->resource[0].start = gpiod_to_irq(clk);
+       serio->resource[0].end = serio->resource[0].start;
+
+       /*
+        * Since FIQ handler performs handling of GPIO registers for
+        * "keybrd_clk" IRQ pin, ams_delta_serio driver used to set
+        * handle_simple_irq() as active IRQ handler for that pin to avoid
+        * bad interaction with gpio-omap driver.  This is no longer needed
+        * as handle_simple_irq() is now the default handler for OMAP GPIO
+        * edge interrupts.
+        * This comment replaces the obsolete code which has been removed
+        * from the ams_delta_serio driver and stands here only as a reminder
+        * of that dependency on gpio-omap driver behavior.
+        */
+
        return;
 
 out_gpio:
index 3f691d6..fd76df3 100644 (file)
@@ -35,7 +35,8 @@
 #ifndef __ASSEMBLER__
 extern unsigned char qwerty_fiqin_start, qwerty_fiqin_end;
 
-extern void __init ams_delta_init_fiq(struct gpio_chip *chip);
+extern void __init ams_delta_init_fiq(struct gpio_chip *chip,
+                                     struct platform_device *pdev);
 #endif
 
 #endif
index 902c24c..f453b08 100644 (file)
@@ -521,9 +521,24 @@ static struct platform_device cx20442_codec_device = {
        .id     = -1,
 };
 
+static struct resource ams_delta_serio_resources[] = {
+       {
+               .flags  = IORESOURCE_IRQ,
+               /*
+                * Initialize IRQ resource with invalid IRQ number.
+                * It will be replaced with dynamically allocated GPIO IRQ
+                * obtained from GPIO chip as soon as the chip is available.
+                */
+               .start  = -EINVAL,
+               .end    = -EINVAL,
+       },
+};
+
 static struct platform_device ams_delta_serio_device = {
        .name           = "ams-delta-serio",
        .id             = PLATFORM_DEVID_NONE,
+       .num_resources  = ARRAY_SIZE(ams_delta_serio_resources),
+       .resource       = ams_delta_serio_resources,
 };
 
 static struct regulator_consumer_supply keybrd_pwr_consumers[] = {
@@ -632,7 +647,7 @@ static void __init omap_gpio_deps_init(void)
                return;
        }
 
-       ams_delta_init_fiq(chip);
+       ams_delta_init_fiq(chip, &ams_delta_serio_device);
 }
 
 static void __init ams_delta_init(void)
index 2602f7c..c1f8226 100644 (file)
@@ -20,7 +20,6 @@
  * However, when used with the E3 mailboard that producecs non-standard
  * scancodes, a custom key table must be prepared and loaded from userspace.
  */
-#include <linux/gpio.h>
 #include <linux/irq.h>
 #include <linux/platform_data/ams-delta-fiq.h>
 #include <linux/platform_device.h>
@@ -29,8 +28,6 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 
-#include <mach/board-ams-delta.h>
-
 #define DRIVER_NAME    "ams-delta-serio"
 
 MODULE_AUTHOR("Matt Callow");
@@ -113,7 +110,7 @@ static int ams_delta_serio_init(struct platform_device *pdev)
 {
        struct ams_delta_serio *priv;
        struct serio *serio;
-       int err;
+       int irq, err;
 
        priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
        if (!priv)
@@ -139,26 +136,20 @@ static int ams_delta_serio_init(struct platform_device *pdev)
                return err;
        }
 
-       err = request_irq(gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK),
-                       ams_delta_serio_interrupt, IRQ_TYPE_EDGE_RISING,
-                       DRIVER_NAME, priv);
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0)
+               return -ENXIO;
+
+       err = devm_request_irq(&pdev->dev, irq, ams_delta_serio_interrupt,
+                              IRQ_TYPE_EDGE_RISING, DRIVER_NAME, priv);
        if (err < 0) {
                dev_err(&pdev->dev, "IRQ request failed (%d)\n", err);
                return err;
        }
-       /*
-        * Since GPIO register handling for keyboard clock pin is performed
-        * at FIQ level, switch back from edge to simple interrupt handler
-        * to avoid bad interaction.
-        */
-       irq_set_handler(gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK),
-                       handle_simple_irq);
 
        serio = kzalloc(sizeof(*serio), GFP_KERNEL);
-       if (!serio) {
-               err = -ENOMEM;
-               goto irq;
-       }
+       if (!serio)
+               return -ENOMEM;
 
        priv->serio = serio;
 
@@ -177,10 +168,6 @@ static int ams_delta_serio_init(struct platform_device *pdev)
        dev_info(&serio->dev, "%s\n", serio->name);
 
        return 0;
-
-irq:
-       free_irq(gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK), priv);
-       return err;
 }
 
 static int ams_delta_serio_exit(struct platform_device *pdev)
@@ -188,7 +175,6 @@ static int ams_delta_serio_exit(struct platform_device *pdev)
        struct ams_delta_serio *priv = platform_get_drvdata(pdev);
 
        serio_unregister_port(priv->serio);
-       free_irq(gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK), 0);
 
        return 0;
 }