Re: [PATCH 05/15] Input: synaptics-rmi4 - remove gpio handling and polling

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

 



On Wed, Feb 05, 2014 at 12:08:35AM +0100, Christopher Heiny wrote:
> On 01/23/2014 04:00 PM, Courtney Cavin wrote:
> > Since all the configuration needed for an irq can be provided in other
> > ways, remove all gpio->irq functionality. This cleans up the code quite
> > a bit.
>
> In certain diagnostic modes, we need to be able to release the IRQ so
> the GPIO can be monitored from userspace.  This patch removes that
> capability.
>

Polling a GPIO from userspace is poor design regardless of the use-case, if
you ask me.  It certainly doesn't motivate the extra gpio<->IRQ code.

> > This also gets rid of polling functionality, as this should be done
> > elsewhere if absolutely needed.
>
> As mentioned in previous patch discussions, the polling functionality is
> quite useful during new system integration, so we need to retain that.
> If you have a proposal for where else it could be done, we'd certainly
> entertain a patch that implements that.

Do you actually have systems that have these hooked up to GPIOs without
IRQ support?

Regardless, if this is the case, implementing a GPIO polling IRQ chip
should be possible, if extremely ugly.

Linus may have some comments in this area, though.  Linus?

>
>                                         Thanks,
>                                                 Chris
>
> >
> > Cc: Christopher Heiny <cheiny@xxxxxxxxxxxxx>
> > Cc: Dmitry Torokhov <dmitry.torokhov@xxxxxxxxx>
> > Signed-off-by: Courtney Cavin <courtney.cavin@xxxxxxxxxxxxxx>
> > ---
> >   drivers/input/rmi4/rmi_driver.c | 143 +++++-----------------------------------
> >   drivers/input/rmi4/rmi_driver.h |   7 --
> >   drivers/input/rmi4/rmi_i2c.c    |  24 +------
> >   include/linux/rmi.h             |  31 +--------
> >   4 files changed, 20 insertions(+), 185 deletions(-)
> >
> > diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
> > index 5fb582c..780742f 100644
> > --- a/drivers/input/rmi4/rmi_driver.c
> > +++ b/drivers/input/rmi4/rmi_driver.c
> > @@ -20,7 +20,6 @@
> >   #include <linux/delay.h>
> >   #include <linux/device.h>
> >   #include <linux/fs.h>
> > -#include <linux/gpio.h>
> >   #include <linux/kconfig.h>
> >   #include <linux/list.h>
> >   #include <linux/module.h>
> > @@ -50,74 +49,17 @@ static irqreturn_t rmi_irq_thread(int irq, void *p)
> >       struct rmi_transport_dev *xport = p;
> >       struct rmi_device *rmi_dev = xport->rmi_dev;
> >       struct rmi_driver *driver = rmi_dev->driver;
> > -     struct rmi_device_platform_data *pdata = xport->dev->platform_data;
> >       struct rmi_driver_data *data;
> >
> >       data = dev_get_drvdata(&rmi_dev->dev);
> > -
> > -     if (IRQ_DEBUG(data))
> > -             dev_dbg(xport->dev, "ATTN gpio, value: %d.\n",
> > -                             gpio_get_value(pdata->attn_gpio));
> > -
> > -     if (gpio_get_value(pdata->attn_gpio) == pdata->attn_polarity) {
> > -             data->attn_count++;
> > -             if (driver && driver->irq_handler && rmi_dev)
> > -                     driver->irq_handler(rmi_dev, irq);
> > -     }
> > +     if (driver && driver->irq_handler && rmi_dev)
> > +             driver->irq_handler(rmi_dev, irq);
> >
> >       return IRQ_HANDLED;
> >   }
> >
> >   static int process_interrupt_requests(struct rmi_device *rmi_dev);
> >
> > -static void rmi_poll_work(struct work_struct *work)
> > -{
> > -     struct rmi_driver_data *data =
> > -                     container_of(work, struct rmi_driver_data, poll_work);
> > -     struct rmi_device *rmi_dev = data->rmi_dev;
> > -
> > -     process_interrupt_requests(rmi_dev);
> > -}
> > -
> > -/*
> > - * This is the timer function for polling - it simply has to schedule work
> > - * and restart the timer.
> > - */
> > -static enum hrtimer_restart rmi_poll_timer(struct hrtimer *timer)
> > -{
> > -     struct rmi_driver_data *data =
> > -                     container_of(timer, struct rmi_driver_data, poll_timer);
> > -
> > -     if (!data->enabled)
> > -             return HRTIMER_NORESTART;
> > -     if (!work_pending(&data->poll_work))
> > -             schedule_work(&data->poll_work);
> > -     hrtimer_start(&data->poll_timer, data->poll_interval, HRTIMER_MODE_REL);
> > -     return HRTIMER_NORESTART;
> > -}
> > -
> > -static int enable_polling(struct rmi_device *rmi_dev)
> > -{
> > -     struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
> > -
> > -     dev_dbg(&rmi_dev->dev, "Polling enabled.\n");
> > -     INIT_WORK(&data->poll_work, rmi_poll_work);
> > -     hrtimer_init(&data->poll_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
> > -     data->poll_timer.function = rmi_poll_timer;
> > -     hrtimer_start(&data->poll_timer, data->poll_interval, HRTIMER_MODE_REL);
> > -
> > -     return 0;
> > -}
> > -
> > -static void disable_polling(struct rmi_device *rmi_dev)
> > -{
> > -     struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
> > -
> > -     dev_dbg(&rmi_dev->dev, "Polling disabled.\n");
> > -     hrtimer_cancel(&data->poll_timer);
> > -     cancel_work_sync(&data->poll_work);
> > -}
> > -
> >   static void disable_sensor(struct rmi_device *rmi_dev)
> >   {
> >       struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
> > @@ -125,9 +67,6 @@ static void disable_sensor(struct rmi_device *rmi_dev)
> >       if (!data->enabled)
> >               return;
> >
> > -     if (!data->irq)
> > -             disable_polling(rmi_dev);
> > -
> >       if (rmi_dev->xport->ops->disable_device)
> >               rmi_dev->xport->ops->disable_device(rmi_dev->xport);
> >
> > @@ -155,20 +94,14 @@ static int enable_sensor(struct rmi_device *rmi_dev)
> >       }
> >
> >       xport = rmi_dev->xport;
> > -     if (data->irq) {
> > -             retval = request_threaded_irq(data->irq,
> > -                             xport->hard_irq ? xport->hard_irq : NULL,
> > -                             xport->irq_thread ?
> > -                                     xport->irq_thread : rmi_irq_thread,
> > -                             data->irq_flags,
> > -                             dev_name(&rmi_dev->dev), xport);
> > -             if (retval)
> > -                     return retval;
> > -     } else {
> > -             retval = enable_polling(rmi_dev);
> > -             if (retval < 0)
> > -                     return retval;
> > -     }
> > +     retval = request_threaded_irq(data->irq,
> > +                     xport->hard_irq ? xport->hard_irq : NULL,
> > +                     xport->irq_thread ?
> > +                             xport->irq_thread : rmi_irq_thread,
> > +                     IRQF_ONESHOT,
> > +                     dev_name(&rmi_dev->dev), xport);
> > +     if (retval)
> > +             return retval;
> >
> >       data->enabled = true;
> >
> > @@ -751,16 +684,9 @@ static SIMPLE_DEV_PM_OPS(rmi_driver_pm, rmi_driver_suspend, rmi_driver_resume);
> >   static int rmi_driver_remove(struct device *dev)
> >   {
> >       struct rmi_device *rmi_dev = to_rmi_device(dev);
> > -     const struct rmi_device_platform_data *pdata =
> > -                                     to_rmi_platform_data(rmi_dev);
> > -     const struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
> > -
> >       disable_sensor(rmi_dev);
> >       rmi_free_function_list(rmi_dev);
> >
> > -     if (data->gpio_held)
> > -             gpio_free(pdata->attn_gpio);
> > -
> >       return 0;
> >   }
> >
> > @@ -895,51 +821,12 @@ static int rmi_driver_probe(struct device *dev)
> >               mutex_init(&data->suspend_mutex);
> >       }
> >
> > -     if (gpio_is_valid(pdata->attn_gpio)) {
> > -             static const char GPIO_LABEL[] = "attn";
> > -             unsigned long gpio_flags = GPIOF_DIR_IN;
> > -
> > -             data->irq = gpio_to_irq(pdata->attn_gpio);
> > -             if (pdata->level_triggered) {
> > -                     data->irq_flags = IRQF_ONESHOT |
> > -                             ((pdata->attn_polarity == RMI_ATTN_ACTIVE_HIGH)
> > -                             ? IRQF_TRIGGER_HIGH : IRQF_TRIGGER_LOW);
> > -             } else {
> > -                     data->irq_flags =
> > -                             (pdata->attn_polarity == RMI_ATTN_ACTIVE_HIGH)
> > -                             ? IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING;
> > -             }
> > +     data->irq = pdata->irq;
> > +     if (data->irq < 0) {
> > +             dev_err(dev, "Failed to get attn IRQ.\n");
> > +             retval = data->irq;
> > +             goto err_free_data;
> >
> > -             if (IS_ENABLED(CONFIG_RMI4_DEV))
> > -                     gpio_flags |= GPIOF_EXPORT;
> > -
> > -             retval = gpio_request_one(pdata->attn_gpio, gpio_flags,
> > -                                       GPIO_LABEL);
> > -             if (retval) {
> > -                     dev_warn(dev, "WARNING: Failed to request ATTN gpio %d, code=%d.\n",
> > -                              pdata->attn_gpio, retval);
> > -                     retval = 0;
> > -             } else {
> > -                     dev_info(dev, "Obtained ATTN gpio %d.\n",
> > -                                     pdata->attn_gpio);
> > -                     data->gpio_held = true;
> > -                     if (IS_ENABLED(CONFIG_RMI4_DEV)) {
> > -                             retval = gpio_export_link(dev,
> > -                                             GPIO_LABEL, pdata->attn_gpio);
> > -                             if (retval) {
> > -                                     dev_warn(dev,
> > -                                             "WARNING: Failed to symlink ATTN gpio!\n");
> > -                                     retval = 0;
> > -                             } else {
> > -                                     dev_info(dev, "Exported ATTN gpio %d.",
> > -                                             pdata->attn_gpio);
> > -                             }
> > -                     }
> > -             }
> > -     } else {
> > -             data->poll_interval = ktime_set(0,
> > -                     (pdata->poll_interval_ms ? pdata->poll_interval_ms :
> > -                     DEFAULT_POLL_INTERVAL_MS) * 1000 * 1000);
> >       }
> >
> >       if (data->f01_container->dev.driver) {
> > diff --git a/drivers/input/rmi4/rmi_driver.h b/drivers/input/rmi4/rmi_driver.h
> > index 4f44a54..aef5521 100644
> > --- a/drivers/input/rmi4/rmi_driver.h
> > +++ b/drivers/input/rmi4/rmi_driver.h
> > @@ -39,9 +39,7 @@ struct rmi_driver_data {
> >
> >       u32 attn_count;
> >       u32 irq_debug;  /* Should be bool, but debugfs wants u32 */
> > -     bool gpio_held;
> >       int irq;
> > -     int irq_flags;
> >       int num_of_irq_regs;
> >       int irq_count;
> >       unsigned long *irq_status;
> > @@ -50,11 +48,6 @@ struct rmi_driver_data {
> >       bool irq_stored;
> >       struct mutex irq_mutex;
> >
> > -     /* Following are used when polling. */
> > -     struct hrtimer poll_timer;
> > -     struct work_struct poll_work;
> > -     ktime_t poll_interval;
> > -
> >       struct mutex pdt_mutex;
> >       u8 pdt_props;
> >       u8 bsr;
> > diff --git a/drivers/input/rmi4/rmi_i2c.c b/drivers/input/rmi4/rmi_i2c.c
> > index 910f05c..aebf974 100644
> > --- a/drivers/input/rmi4/rmi_i2c.c
> > +++ b/drivers/input/rmi4/rmi_i2c.c
> > @@ -196,8 +196,7 @@ static int rmi_i2c_probe(struct i2c_client *client,
> >               return -EINVAL;
> >       }
> >
> > -     dev_dbg(&client->dev, "Probing %#02x (GPIO %d).\n",
> > -             client->addr, pdata->attn_gpio);
> > +     dev_dbg(&client->dev, "Probing %#02x.\n", client->addr);
> >
> >       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
> >               dev_err(&client->dev,
> > @@ -205,15 +204,6 @@ static int rmi_i2c_probe(struct i2c_client *client,
> >               return -ENODEV;
> >       }
> >
> > -     if (pdata->gpio_config) {
> > -             retval = pdata->gpio_config(pdata->gpio_data, true);
> > -             if (retval < 0) {
> > -                     dev_err(&client->dev, "Failed to configure GPIOs, code: %d.\n",
> > -                             retval);
> > -                     return retval;
> > -             }
> > -     }
> > -
> >       rmi_i2c = devm_kzalloc(&client->dev, sizeof(struct rmi_i2c_xport),
> >                               GFP_KERNEL);
> >       if (!rmi_i2c)
> > @@ -240,7 +230,7 @@ static int rmi_i2c_probe(struct i2c_client *client,
> >       if (retval) {
> >               dev_err(&client->dev, "Failed to register transport driver at 0x%.2X.\n",
> >                       client->addr);
> > -             goto err_gpio;
> > +             goto err;
> >       }
> >
> >       i2c_set_clientdata(client, rmi_i2c);
> > @@ -249,24 +239,16 @@ static int rmi_i2c_probe(struct i2c_client *client,
> >                       client->addr);
> >       return 0;
> >
> > -err_gpio:
> > -     if (pdata->gpio_config)
> > -             pdata->gpio_config(pdata->gpio_data, false);
> > -
> > +err:
> >       return retval;
> >   }
> >
> >   static int rmi_i2c_remove(struct i2c_client *client)
> >   {
> > -     const struct rmi_device_platform_data *pdata =
> > -                             dev_get_platdata(&client->dev);
> >       struct rmi_i2c_xport *rmi_i2c = i2c_get_clientdata(client);
> >
> >       rmi_unregister_transport_device(&rmi_i2c->xport);
> >
> > -     if (pdata->gpio_config)
> > -             pdata->gpio_config(pdata->gpio_data, false);
> > -
> >       return 0;
> >   }
> >
> > diff --git a/include/linux/rmi.h b/include/linux/rmi.h
> > index 65b59b5..326e741 100644
> > --- a/include/linux/rmi.h
> > +++ b/include/linux/rmi.h
> > @@ -23,11 +23,6 @@
> >   #include <linux/wait.h>
> >   #include <linux/debugfs.h>
> >
> > -enum rmi_attn_polarity {
> > -     RMI_ATTN_ACTIVE_LOW = 0,
> > -     RMI_ATTN_ACTIVE_HIGH = 1
> > -};
> > -
> >   /**
> >    * struct rmi_f11_axis_alignment - target axis alignment
> >    * @swap_axes: set to TRUE if desired to swap x- and y-axis
> > @@ -194,25 +189,10 @@ struct rmi_device_platform_data_spi {
> >   /**
> >    * struct rmi_device_platform_data - system specific configuration info.
> >    *
> > + * @irq - attention IRQ
> >    * @firmware_name - if specified will override default firmware name,
> >    * for reflashing.
> >    *
> > - * @attn_gpio - the index of a GPIO that will be used to provide the ATTN
> > - * interrupt from the touch sensor.
> > - * @attn_polarity - indicates whether ATTN is active high or low.
> > - * @level_triggered - by default, the driver uses edge triggered interrupts.
> > - * However, this can cause problems with suspend/resume on some platforms.  In
> > - * that case, set this to 1 to use level triggered interrupts.
> > - * @gpio_config - a routine that will be called when the driver is loaded to
> > - * perform any platform specific GPIO configuration, and when it is unloaded
> > - * for GPIO de-configuration.  This is typically used to configure the ATTN
> > - * GPIO and the I2C or SPI pins, if necessary.
> > - * @gpio_data - platform specific data to be passed to the GPIO configuration
> > - * function.
> > - *
> > - * @poll_interval_ms - the time in milliseconds between reads of the interrupt
> > - * status register.  This is ignored if attn_gpio is non-zero.
> > - *
> >    * @reset_delay_ms - after issuing a reset command to the touch sensor, the
> >    * driver waits a few milliseconds to give the firmware a chance to
> >    * to re-initialize.  You can override the default wait period here.
> > @@ -245,14 +225,7 @@ struct rmi_device_platform_data_spi {
> >    * functions.
> >    */
> >   struct rmi_device_platform_data {
> > -     int attn_gpio;
> > -     enum rmi_attn_polarity attn_polarity;
> > -     bool level_triggered;
> > -     void *gpio_data;
> > -     int (*gpio_config)(void *gpio_data, bool configure);
> > -
> > -     int poll_interval_ms;
> > -
> > +     int irq;
> >       int reset_delay_ms;
> >
> >       struct rmi_device_platform_data_spi spi_data;
> >
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux