RE: [PATCH] iio-trig-gpio:Remove redundant gpio_request

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hennerich, Michael wrote on 2010-03-08:
> Jonathan Cameron wrote on 2010-03-08:
>> On 03/08/10 11:38, Hennerich, Michael wrote:
>>> Hi Jonathan,
>>> Jonathan Cameron wrote on 2010-03-08:
>>>> Hi Michael,
>>>>
>>>> I'm wondering about this one.  Are you sure all platforms have the
>>>> correct gpio setup when doing the request_irq? (those that need it
>>>> obviously, basically the question is whether all platforms default to
>>>> having gpio's as inputs).
>>>>
>>>> If the do there is certainly a lot of redundant code about based on a
>>>> quick bit of grepping. (loads of it in arm/mach-pxa for starters). In
>>>> that particular case all gpio's are configured as inputs, but I'm not
>>>> sure other platforms are so well behaved.
>>>>
>>>>
>>>> Unless I'm completely wrong that means we have run into a rather
>>>> general issue.
>>>
>>> By no means - you have to first configure a GPIO_IRQ as GPIO-Input and
>>> then as IRQ. irq_type takes care of it. In your case you gave the
>>> IRQF_TRIGGER_RISING flag with request_irq(). In case such a
>>> IRQF_TRIGGER_XXX flag is present the common IRQ infrastructure will
>>> call the associated irq_chips irq_type() function. This function is
>>> supposed to take care for all of it.(GPIO input, setting the level,
>>> edge and polarity)
>>>
>>> As an alternative you can request_irq() without the
>>> IRQF_TRIGGER_XXX
>> flags and use set_irq_type() anytime later, or even in advance.
>> Ah fair enough. Thanks for cleaning that up for me.
>>
>> Acked-by: Jonathan Cameron <jic23@xxxxxxxxx>
>>
>> Please send it on to Greg KH
>
> Shall I change the driver to loop on while(irq_res != NULL)?
> And get the irqflags from the platform data struct resource?

What do you think about this one?

Example Platform Data:

#if defined(CONFIG_IIO_GPIO_TRIGGER) || \
        defined(CONFIG_IIO_GPIO_TRIGGER_MODULE)

static struct resource iio_gpio_trigger_resources[] = {
        [0] = {
                .start  = IRQ_PF5,
                .end    = IRQ_PF5,
                .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
        },
        [1] = {
                .start  = IRQ_PF2,
                .end    = IRQ_PF3,
                .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
        },
};

static struct platform_device iio_gpio_trigger = {
        .name = "iio_gpio_trigger",
        .num_resources = ARRAY_SIZE(iio_gpio_trigger_resources),
        .resource = iio_gpio_trigger_resources,
};
#endif

This way allows you to specify different GPIO Edge/Polarity behavior as well as GPIO-IRQ sequences.
Patch below is an top of my previous one.
I wonder I we should change all references to gpio completely (replace with irq), since this driver can also be used with any other system IRQ as well.


===================================================================
--- drivers/staging/iio/trigger/iio-trig-gpio.c (revision 8415)
+++ drivers/staging/iio/trigger/iio-trig-gpio.c (working copy)
@@ -57,64 +57,73 @@
        .attrs = iio_gpio_trigger_attrs,
 };

-static int iio_gpio_trigger_probe(struct platform_device *dev)
+static int iio_gpio_trigger_probe(struct platform_device *pdev)
 {
-       int *pdata = dev->dev.platform_data;
+       int *pdata = pdev->dev.platform_data;
        struct iio_gpio_trigger_info *trig_info;
        struct iio_trigger *trig, *trig2;
-       int i, irq, ret = 0;
-       if (!pdata) {
-               printk(KERN_ERR "No IIO gpio trigger platform data found\n");
-               goto error_ret;
-       }
-       for (i = 0;; i++) {
-               if (!gpio_is_valid(pdata[i]))
+       unsigned long irqflags;
+       struct resource *irq_res;
+       int irq, ret = 0, irq_res_cnt = 0;
+       unsigned gpio;
+
+       do {
+               irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, irq_res_cnt);
+
+               if (irq_res == NULL) {
+                       if (irq_res_cnt == 0)
+                               dev_err(&pdev->dev, "No GPIO IRQs specified");
                        break;
-               trig = iio_allocate_trigger();
-               if (!trig) {
-                       ret = -ENOMEM;
-                       goto error_free_completed_registrations;
                }
+               irqflags = irq_res->flags & IRQF_TRIGGER_MASK;

-               trig_info = kzalloc(sizeof(*trig_info), GFP_KERNEL);
-               if (!trig_info) {
-                       ret = -ENOMEM;
-                       goto error_put_trigger;
-               }
-               trig->control_attrs = &iio_gpio_trigger_attr_group;
-               trig->private_data = trig_info;
-               trig_info->gpio = pdata[i];
-               trig->owner = THIS_MODULE;
-               trig->name = kmalloc(IIO_TRIGGER_NAME_LENGTH, GFP_KERNEL);
-               if (!trig->name) {
-                       ret = -ENOMEM;
-                       goto error_free_trig_info;
-               }
-               snprintf((char *)trig->name,
-                        IIO_TRIGGER_NAME_LENGTH,
-                        "gpiotrig%d",
-                        pdata[i]);
+               for (irq = irq_res->start; irq <= irq_res->end; irq++) {
+                       gpio = irq_to_gpio(irq);
+                       if (!gpio_is_valid(gpio))
+                               break;
+                       trig = iio_allocate_trigger();
+                       if (!trig) {
+                               ret = -ENOMEM;
+                               goto error_free_completed_registrations;
+                       }

-               irq = gpio_to_irq(trig_info->gpio);
-               if (irq < 0) {
-                       ret = irq;
-                       goto error_free_name;
+                       trig_info = kzalloc(sizeof(*trig_info), GFP_KERNEL);
+                       if (!trig_info) {
+                               ret = -ENOMEM;
+                               goto error_put_trigger;
+                       }
+                       trig->control_attrs = &iio_gpio_trigger_attr_group;
+                       trig->private_data = trig_info;
+                       trig_info->gpio = gpio;
+                       trig->owner = THIS_MODULE;
+                       trig->name = kmalloc(IIO_TRIGGER_NAME_LENGTH, GFP_KERNEL);
+                       if (!trig->name) {
+                               ret = -ENOMEM;
+                               goto error_free_trig_info;
+                       }
+                       snprintf((char *)trig->name,
+                                IIO_TRIGGER_NAME_LENGTH,
+                                "gpiotrig%d",
+                                gpio);
+
+                       ret = request_irq(irq, iio_gpio_trigger_poll,
+                                         irqflags,
+                                         trig->name,
+                                         trig);
+                       if (ret)
+                               goto error_free_name;
+
+                       ret = iio_trigger_register(trig);
+                       if (ret)
+                               goto error_release_irq;
+
+                       list_add_tail(&trig->alloc_list, &iio_gpio_trigger_list);
                }

-               ret = request_irq(irq, iio_gpio_trigger_poll,
-                                 IRQF_TRIGGER_RISING,
-                                 trig->name,
-                                 trig);
-               if (ret)
-                       goto error_free_name;
+               irq_res_cnt++;
+       } while (irq_res != NULL);

-               ret = iio_trigger_register(trig);
-               if (ret)
-                       goto error_release_irq;

-               list_add_tail(&trig->alloc_list, &iio_gpio_trigger_list);
-
-       }
        return 0;

 /* First clean up the partly allocated trigger */
@@ -143,7 +152,7 @@
        return ret;
 }

-static int iio_gpio_trigger_remove(struct platform_device *dev)
+static int iio_gpio_trigger_remove(struct platform_device *pdev)
 {
        struct iio_trigger *trig, *trig2;
        struct iio_gpio_trigger_info *trig_info;
--
To unsubscribe from this list: send the line "unsubscribe linux-iio" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux