Re: [PATCH 3/3] HID: i2c-hid: Add support for ACPI GPIO interrupts

2015-02-25 Thread Mika Westerberg
On Tue, Feb 24, 2015 at 10:27:05PM +0100, Antonio Ospite wrote:
> On Mon, 23 Feb 2015 15:52:45 +0200
> Mika Westerberg  wrote:
> 
> > The HID over I2C specification allows to have the interrupt for a HID
> > device to be GPIO instead of directly connected to the IO-APIC.
> > 
> > Add support for this so that when the driver does not find proper interrupt
> > number from the I2C client structure we check if it has ACPI GpioInt()
> > resource listed in _CRS. If it is found we convert it to an interrupt
> > number and use it instead.
> > 
> > Signed-off-by: Mika Westerberg 
> > ---
> >  drivers/hid/i2c-hid/i2c-hid.c | 68 
> > +++
> >  1 file changed, 50 insertions(+), 18 deletions(-)
> > 
> > diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c
> > index 404ccde49acd..c6cad72f6296 100644
> > --- a/drivers/hid/i2c-hid/i2c-hid.c
> > +++ b/drivers/hid/i2c-hid/i2c-hid.c
> > @@ -37,6 +37,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  
> >  #include 
> >  
> > @@ -144,6 +145,8 @@ struct i2c_hid {
> > unsigned long   flags;  /* device flags */
> >  
> > wait_queue_head_t   wait;   /* For waiting the interrupt */
> > +   struct gpio_desc*desc;
> 
> Just curious: can't the gpio_desc be local in the probe function?
> I take that the gpio descriptor needs to be alive even after the irq
> number has been derived from it in order for the gpio chip to remember
> that the gpio has been requested by someone. Is that correct?

That's right and we need to release it in remove() as well.

Someone should convert this driver to use devm_* APIs...
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/3] HID: i2c-hid: Add support for ACPI GPIO interrupts

2015-02-25 Thread Mika Westerberg
On Tue, Feb 24, 2015 at 10:27:05PM +0100, Antonio Ospite wrote:
 On Mon, 23 Feb 2015 15:52:45 +0200
 Mika Westerberg mika.westerb...@linux.intel.com wrote:
 
  The HID over I2C specification allows to have the interrupt for a HID
  device to be GPIO instead of directly connected to the IO-APIC.
  
  Add support for this so that when the driver does not find proper interrupt
  number from the I2C client structure we check if it has ACPI GpioInt()
  resource listed in _CRS. If it is found we convert it to an interrupt
  number and use it instead.
  
  Signed-off-by: Mika Westerberg mika.westerb...@linux.intel.com
  ---
   drivers/hid/i2c-hid/i2c-hid.c | 68 
  +++
   1 file changed, 50 insertions(+), 18 deletions(-)
  
  diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c
  index 404ccde49acd..c6cad72f6296 100644
  --- a/drivers/hid/i2c-hid/i2c-hid.c
  +++ b/drivers/hid/i2c-hid/i2c-hid.c
  @@ -37,6 +37,7 @@
   #include linux/mutex.h
   #include linux/acpi.h
   #include linux/of.h
  +#include linux/gpio/consumer.h
   
   #include linux/i2c/i2c-hid.h
   
  @@ -144,6 +145,8 @@ struct i2c_hid {
  unsigned long   flags;  /* device flags */
   
  wait_queue_head_t   wait;   /* For waiting the interrupt */
  +   struct gpio_desc*desc;
 
 Just curious: can't the gpio_desc be local in the probe function?
 I take that the gpio descriptor needs to be alive even after the irq
 number has been derived from it in order for the gpio chip to remember
 that the gpio has been requested by someone. Is that correct?

That's right and we need to release it in remove() as well.

Someone should convert this driver to use devm_* APIs...
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/3] HID: i2c-hid: Add support for ACPI GPIO interrupts

2015-02-24 Thread Antonio Ospite
On Mon, 23 Feb 2015 15:52:45 +0200
Mika Westerberg  wrote:

> The HID over I2C specification allows to have the interrupt for a HID
> device to be GPIO instead of directly connected to the IO-APIC.
> 
> Add support for this so that when the driver does not find proper interrupt
> number from the I2C client structure we check if it has ACPI GpioInt()
> resource listed in _CRS. If it is found we convert it to an interrupt
> number and use it instead.
> 
> Signed-off-by: Mika Westerberg 
> ---
>  drivers/hid/i2c-hid/i2c-hid.c | 68 
> +++
>  1 file changed, 50 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c
> index 404ccde49acd..c6cad72f6296 100644
> --- a/drivers/hid/i2c-hid/i2c-hid.c
> +++ b/drivers/hid/i2c-hid/i2c-hid.c
> @@ -37,6 +37,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include 
>  
> @@ -144,6 +145,8 @@ struct i2c_hid {
>   unsigned long   flags;  /* device flags */
>  
>   wait_queue_head_t   wait;   /* For waiting the interrupt */
> + struct gpio_desc*desc;

Just curious: can't the gpio_desc be local in the probe function?
I take that the gpio descriptor needs to be alive even after the irq
number has been derived from it in order for the gpio chip to remember
that the gpio has been requested by someone. Is that correct?

Thanks,
   Antonio

[...]

-- 
Antonio Ospite
http://ao2.it

A: Because it messes up the order in which people normally read text.
   See http://en.wikipedia.org/wiki/Posting_style
Q: Why is top-posting such a bad thing?
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/3] HID: i2c-hid: Add support for ACPI GPIO interrupts

2015-02-24 Thread Jiri Kosina
On Mon, 23 Feb 2015, Mika Westerberg wrote:

> The HID over I2C specification allows to have the interrupt for a HID
> device to be GPIO instead of directly connected to the IO-APIC.
> 
> Add support for this so that when the driver does not find proper interrupt
> number from the I2C client structure we check if it has ACPI GpioInt()
> resource listed in _CRS. If it is found we convert it to an interrupt
> number and use it instead.
> 
> Signed-off-by: Mika Westerberg 

Applied, thanks.

-- 
Jiri Kosina
SUSE Labs
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/3] HID: i2c-hid: Add support for ACPI GPIO interrupts

2015-02-24 Thread Antonio Ospite
On Mon, 23 Feb 2015 15:52:45 +0200
Mika Westerberg mika.westerb...@linux.intel.com wrote:

 The HID over I2C specification allows to have the interrupt for a HID
 device to be GPIO instead of directly connected to the IO-APIC.
 
 Add support for this so that when the driver does not find proper interrupt
 number from the I2C client structure we check if it has ACPI GpioInt()
 resource listed in _CRS. If it is found we convert it to an interrupt
 number and use it instead.
 
 Signed-off-by: Mika Westerberg mika.westerb...@linux.intel.com
 ---
  drivers/hid/i2c-hid/i2c-hid.c | 68 
 +++
  1 file changed, 50 insertions(+), 18 deletions(-)
 
 diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c
 index 404ccde49acd..c6cad72f6296 100644
 --- a/drivers/hid/i2c-hid/i2c-hid.c
 +++ b/drivers/hid/i2c-hid/i2c-hid.c
 @@ -37,6 +37,7 @@
  #include linux/mutex.h
  #include linux/acpi.h
  #include linux/of.h
 +#include linux/gpio/consumer.h
  
  #include linux/i2c/i2c-hid.h
  
 @@ -144,6 +145,8 @@ struct i2c_hid {
   unsigned long   flags;  /* device flags */
  
   wait_queue_head_t   wait;   /* For waiting the interrupt */
 + struct gpio_desc*desc;

Just curious: can't the gpio_desc be local in the probe function?
I take that the gpio descriptor needs to be alive even after the irq
number has been derived from it in order for the gpio chip to remember
that the gpio has been requested by someone. Is that correct?

Thanks,
   Antonio

[...]

-- 
Antonio Ospite
http://ao2.it

A: Because it messes up the order in which people normally read text.
   See http://en.wikipedia.org/wiki/Posting_style
Q: Why is top-posting such a bad thing?
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/3] HID: i2c-hid: Add support for ACPI GPIO interrupts

2015-02-24 Thread Jiri Kosina
On Mon, 23 Feb 2015, Mika Westerberg wrote:

 The HID over I2C specification allows to have the interrupt for a HID
 device to be GPIO instead of directly connected to the IO-APIC.
 
 Add support for this so that when the driver does not find proper interrupt
 number from the I2C client structure we check if it has ACPI GpioInt()
 resource listed in _CRS. If it is found we convert it to an interrupt
 number and use it instead.
 
 Signed-off-by: Mika Westerberg mika.westerb...@linux.intel.com

Applied, thanks.

-- 
Jiri Kosina
SUSE Labs
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/3] HID: i2c-hid: Add support for ACPI GPIO interrupts

2015-02-23 Thread Mika Westerberg
On Mon, Feb 23, 2015 at 10:35:02AM -0500, Benjamin Tissoires wrote:
> On Feb 23 2015 or thereabouts, Mika Westerberg wrote:
> > The HID over I2C specification allows to have the interrupt for a HID
> > device to be GPIO instead of directly connected to the IO-APIC.
> > 
> > Add support for this so that when the driver does not find proper interrupt
> > number from the I2C client structure we check if it has ACPI GpioInt()
> > resource listed in _CRS. If it is found we convert it to an interrupt
> > number and use it instead.
> > 
> > Signed-off-by: Mika Westerberg 
> > ---
> 
> I know this has been already discussed, so don't take this as a request
> for a change. I however hoped that the acpi subsystem would provide the
> irq directly in the i2c client without having to deal with it in
> i2c_hid. For me, declaring the GPIO as an interrupt means that the irq
> should be created in the first place. However, if we also have access to
> the gpio, that means that we can read the value of it, which is better in
> our case. So I am fine with all the solutions - as long as it works :)

I understand your point.

It would be nice to do it that way but it is not so simple.

For example if we have some button array that has several GpioInts
listed, we convert the first to an interrupt but the driver needs to
handle all the rest itself (taking the one converted interrupt into
account).

Another problem that I can think of is to determine who is responsible
in releasing the GPIO and at which point. We cannot just use devm_* APIs
because no driver has been probed yet.

Also if the driver needs to use the interrupt as GPIO for reading its
value we would first need to release it (because it has been requested
by the core code), then re-request it, read the value and then somehow
release it back so that the core code can release it...

That's why I think it is better to let drivers handle these themselves
as they like.

Of course if someone has good idea how to do this properly in the core
code, I'm all ears.

> I don't know enough of the use of gpios in acpi to properly review the
> code. So I'll just add my:
> Acked-by: Benjamin Tissoires 

Thanks :-)
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/3] HID: i2c-hid: Add support for ACPI GPIO interrupts

2015-02-23 Thread Benjamin Tissoires
On Feb 23 2015 or thereabouts, Mika Westerberg wrote:
> The HID over I2C specification allows to have the interrupt for a HID
> device to be GPIO instead of directly connected to the IO-APIC.
> 
> Add support for this so that when the driver does not find proper interrupt
> number from the I2C client structure we check if it has ACPI GpioInt()
> resource listed in _CRS. If it is found we convert it to an interrupt
> number and use it instead.
> 
> Signed-off-by: Mika Westerberg 
> ---

I know this has been already discussed, so don't take this as a request
for a change. I however hoped that the acpi subsystem would provide the
irq directly in the i2c client without having to deal with it in
i2c_hid. For me, declaring the GPIO as an interrupt means that the irq
should be created in the first place. However, if we also have access to
the gpio, that means that we can read the value of it, which is better in
our case. So I am fine with all the solutions - as long as it works :)

I don't know enough of the use of gpios in acpi to properly review the
code. So I'll just add my:
Acked-by: Benjamin Tissoires 

Cheers,
Benjamin

>  drivers/hid/i2c-hid/i2c-hid.c | 68 
> +++
>  1 file changed, 50 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c
> index 404ccde49acd..c6cad72f6296 100644
> --- a/drivers/hid/i2c-hid/i2c-hid.c
> +++ b/drivers/hid/i2c-hid/i2c-hid.c
> @@ -37,6 +37,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include 
>  
> @@ -144,6 +145,8 @@ struct i2c_hid {
>   unsigned long   flags;  /* device flags */
>  
>   wait_queue_head_t   wait;   /* For waiting the interrupt */
> + struct gpio_desc*desc;
> + int irq;
>  
>   struct i2c_hid_platform_data pdata;
>  };
> @@ -790,16 +793,16 @@ static int i2c_hid_init_irq(struct i2c_client *client)
>   struct i2c_hid *ihid = i2c_get_clientdata(client);
>   int ret;
>  
> - dev_dbg(>dev, "Requesting IRQ: %d\n", client->irq);
> + dev_dbg(>dev, "Requesting IRQ: %d\n", ihid->irq);
>  
> - ret = request_threaded_irq(client->irq, NULL, i2c_hid_irq,
> + ret = request_threaded_irq(ihid->irq, NULL, i2c_hid_irq,
>   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
>   client->name, ihid);
>   if (ret < 0) {
>   dev_warn(>dev,
>   "Could not register for %s interrupt, irq = %d,"
>   " ret = %d\n",
> - client->name, client->irq, ret);
> + client->name, ihid->irq, ret);
>  
>   return ret;
>   }
> @@ -846,6 +849,14 @@ static int i2c_hid_fetch_hid_descriptor(struct i2c_hid 
> *ihid)
>  }
>  
>  #ifdef CONFIG_ACPI
> +
> +/* Default GPIO mapping */
> +static const struct acpi_gpio_params i2c_hid_irq_gpio = { 0, 0, true };
> +static const struct acpi_gpio_mapping i2c_hid_acpi_gpios[] = {
> + { "gpios", _hid_irq_gpio, 1 },
> + { },
> +};
> +
>  static int i2c_hid_acpi_pdata(struct i2c_client *client,
>   struct i2c_hid_platform_data *pdata)
>  {
> @@ -871,7 +882,7 @@ static int i2c_hid_acpi_pdata(struct i2c_client *client,
>   pdata->hid_descriptor_address = obj->integer.value;
>   ACPI_FREE(obj);
>  
> - return 0;
> + return acpi_dev_add_driver_gpios(adev, i2c_hid_acpi_gpios);
>  }
>  
>  static const struct acpi_device_id i2c_hid_acpi_match[] = {
> @@ -935,12 +946,6 @@ static int i2c_hid_probe(struct i2c_client *client,
>  
>   dbg_hid("HID probe called for i2c 0x%02x\n", client->addr);
>  
> - if (!client->irq) {
> - dev_err(>dev,
> - "HID over i2c has not been provided an Int IRQ\n");
> - return -EINVAL;
> - }
> -
>   ihid = kzalloc(sizeof(struct i2c_hid), GFP_KERNEL);
>   if (!ihid)
>   return -ENOMEM;
> @@ -960,6 +965,23 @@ static int i2c_hid_probe(struct i2c_client *client,
>   ihid->pdata = *platform_data;
>   }
>  
> + if (client->irq > 0) {
> + ihid->irq = client->irq;
> + } else if (ACPI_COMPANION(>dev)) {
> + ihid->desc = gpiod_get(>dev, NULL, GPIOD_IN);
> + if (IS_ERR(ihid->desc)) {
> + dev_err(>dev, "Failed to get GPIO interrupt\n");
> + return PTR_ERR(ihid->desc);
> + }
> +
> + ihid->irq = gpiod_to_irq(ihid->desc);
> + if (ihid->irq < 0) {
> + gpiod_put(ihid->desc);
> + dev_err(>dev, "Failed to convert GPIO to 
> IRQ\n");
> + return ihid->irq;
> + }
> + }
> +
>   i2c_set_clientdata(client, ihid);
>  
>   ihid->client = client;
> @@ -1022,13 +1044,16 @@ err_mem_free:
>   hid_destroy_device(hid);
>  
>  err_irq:
> - free_irq(client->irq, ihid);
> + free_irq(ihid->irq, ihid);
>  
>  

[PATCH 3/3] HID: i2c-hid: Add support for ACPI GPIO interrupts

2015-02-23 Thread Mika Westerberg
The HID over I2C specification allows to have the interrupt for a HID
device to be GPIO instead of directly connected to the IO-APIC.

Add support for this so that when the driver does not find proper interrupt
number from the I2C client structure we check if it has ACPI GpioInt()
resource listed in _CRS. If it is found we convert it to an interrupt
number and use it instead.

Signed-off-by: Mika Westerberg 
---
 drivers/hid/i2c-hid/i2c-hid.c | 68 +++
 1 file changed, 50 insertions(+), 18 deletions(-)

diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c
index 404ccde49acd..c6cad72f6296 100644
--- a/drivers/hid/i2c-hid/i2c-hid.c
+++ b/drivers/hid/i2c-hid/i2c-hid.c
@@ -37,6 +37,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -144,6 +145,8 @@ struct i2c_hid {
unsigned long   flags;  /* device flags */
 
wait_queue_head_t   wait;   /* For waiting the interrupt */
+   struct gpio_desc*desc;
+   int irq;
 
struct i2c_hid_platform_data pdata;
 };
@@ -790,16 +793,16 @@ static int i2c_hid_init_irq(struct i2c_client *client)
struct i2c_hid *ihid = i2c_get_clientdata(client);
int ret;
 
-   dev_dbg(>dev, "Requesting IRQ: %d\n", client->irq);
+   dev_dbg(>dev, "Requesting IRQ: %d\n", ihid->irq);
 
-   ret = request_threaded_irq(client->irq, NULL, i2c_hid_irq,
+   ret = request_threaded_irq(ihid->irq, NULL, i2c_hid_irq,
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
client->name, ihid);
if (ret < 0) {
dev_warn(>dev,
"Could not register for %s interrupt, irq = %d,"
" ret = %d\n",
-   client->name, client->irq, ret);
+   client->name, ihid->irq, ret);
 
return ret;
}
@@ -846,6 +849,14 @@ static int i2c_hid_fetch_hid_descriptor(struct i2c_hid 
*ihid)
 }
 
 #ifdef CONFIG_ACPI
+
+/* Default GPIO mapping */
+static const struct acpi_gpio_params i2c_hid_irq_gpio = { 0, 0, true };
+static const struct acpi_gpio_mapping i2c_hid_acpi_gpios[] = {
+   { "gpios", _hid_irq_gpio, 1 },
+   { },
+};
+
 static int i2c_hid_acpi_pdata(struct i2c_client *client,
struct i2c_hid_platform_data *pdata)
 {
@@ -871,7 +882,7 @@ static int i2c_hid_acpi_pdata(struct i2c_client *client,
pdata->hid_descriptor_address = obj->integer.value;
ACPI_FREE(obj);
 
-   return 0;
+   return acpi_dev_add_driver_gpios(adev, i2c_hid_acpi_gpios);
 }
 
 static const struct acpi_device_id i2c_hid_acpi_match[] = {
@@ -935,12 +946,6 @@ static int i2c_hid_probe(struct i2c_client *client,
 
dbg_hid("HID probe called for i2c 0x%02x\n", client->addr);
 
-   if (!client->irq) {
-   dev_err(>dev,
-   "HID over i2c has not been provided an Int IRQ\n");
-   return -EINVAL;
-   }
-
ihid = kzalloc(sizeof(struct i2c_hid), GFP_KERNEL);
if (!ihid)
return -ENOMEM;
@@ -960,6 +965,23 @@ static int i2c_hid_probe(struct i2c_client *client,
ihid->pdata = *platform_data;
}
 
+   if (client->irq > 0) {
+   ihid->irq = client->irq;
+   } else if (ACPI_COMPANION(>dev)) {
+   ihid->desc = gpiod_get(>dev, NULL, GPIOD_IN);
+   if (IS_ERR(ihid->desc)) {
+   dev_err(>dev, "Failed to get GPIO interrupt\n");
+   return PTR_ERR(ihid->desc);
+   }
+
+   ihid->irq = gpiod_to_irq(ihid->desc);
+   if (ihid->irq < 0) {
+   gpiod_put(ihid->desc);
+   dev_err(>dev, "Failed to convert GPIO to 
IRQ\n");
+   return ihid->irq;
+   }
+   }
+
i2c_set_clientdata(client, ihid);
 
ihid->client = client;
@@ -1022,13 +1044,16 @@ err_mem_free:
hid_destroy_device(hid);
 
 err_irq:
-   free_irq(client->irq, ihid);
+   free_irq(ihid->irq, ihid);
 
 err_pm:
pm_runtime_put_noidle(>dev);
pm_runtime_disable(>dev);
 
 err:
+   if (ihid->desc)
+   gpiod_put(ihid->desc);
+
i2c_hid_free_buffers(ihid);
kfree(ihid);
return ret;
@@ -1047,13 +1072,18 @@ static int i2c_hid_remove(struct i2c_client *client)
hid = ihid->hid;
hid_destroy_device(hid);
 
-   free_irq(client->irq, ihid);
+   free_irq(ihid->irq, ihid);
 
if (ihid->bufsize)
i2c_hid_free_buffers(ihid);
 
+   if (ihid->desc)
+   gpiod_put(ihid->desc);
+
kfree(ihid);
 
+   acpi_dev_remove_driver_gpios(ACPI_COMPANION(>dev));
+
return 0;
 }
 
@@ -1065,9 +1095,9 @@ static int i2c_hid_suspend(struct device *dev)
struct hid_device *hid = ihid->hid;
int ret = 0;
 
-   

[PATCH 3/3] HID: i2c-hid: Add support for ACPI GPIO interrupts

2015-02-23 Thread Mika Westerberg
The HID over I2C specification allows to have the interrupt for a HID
device to be GPIO instead of directly connected to the IO-APIC.

Add support for this so that when the driver does not find proper interrupt
number from the I2C client structure we check if it has ACPI GpioInt()
resource listed in _CRS. If it is found we convert it to an interrupt
number and use it instead.

Signed-off-by: Mika Westerberg mika.westerb...@linux.intel.com
---
 drivers/hid/i2c-hid/i2c-hid.c | 68 +++
 1 file changed, 50 insertions(+), 18 deletions(-)

diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c
index 404ccde49acd..c6cad72f6296 100644
--- a/drivers/hid/i2c-hid/i2c-hid.c
+++ b/drivers/hid/i2c-hid/i2c-hid.c
@@ -37,6 +37,7 @@
 #include linux/mutex.h
 #include linux/acpi.h
 #include linux/of.h
+#include linux/gpio/consumer.h
 
 #include linux/i2c/i2c-hid.h
 
@@ -144,6 +145,8 @@ struct i2c_hid {
unsigned long   flags;  /* device flags */
 
wait_queue_head_t   wait;   /* For waiting the interrupt */
+   struct gpio_desc*desc;
+   int irq;
 
struct i2c_hid_platform_data pdata;
 };
@@ -790,16 +793,16 @@ static int i2c_hid_init_irq(struct i2c_client *client)
struct i2c_hid *ihid = i2c_get_clientdata(client);
int ret;
 
-   dev_dbg(client-dev, Requesting IRQ: %d\n, client-irq);
+   dev_dbg(client-dev, Requesting IRQ: %d\n, ihid-irq);
 
-   ret = request_threaded_irq(client-irq, NULL, i2c_hid_irq,
+   ret = request_threaded_irq(ihid-irq, NULL, i2c_hid_irq,
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
client-name, ihid);
if (ret  0) {
dev_warn(client-dev,
Could not register for %s interrupt, irq = %d,
 ret = %d\n,
-   client-name, client-irq, ret);
+   client-name, ihid-irq, ret);
 
return ret;
}
@@ -846,6 +849,14 @@ static int i2c_hid_fetch_hid_descriptor(struct i2c_hid 
*ihid)
 }
 
 #ifdef CONFIG_ACPI
+
+/* Default GPIO mapping */
+static const struct acpi_gpio_params i2c_hid_irq_gpio = { 0, 0, true };
+static const struct acpi_gpio_mapping i2c_hid_acpi_gpios[] = {
+   { gpios, i2c_hid_irq_gpio, 1 },
+   { },
+};
+
 static int i2c_hid_acpi_pdata(struct i2c_client *client,
struct i2c_hid_platform_data *pdata)
 {
@@ -871,7 +882,7 @@ static int i2c_hid_acpi_pdata(struct i2c_client *client,
pdata-hid_descriptor_address = obj-integer.value;
ACPI_FREE(obj);
 
-   return 0;
+   return acpi_dev_add_driver_gpios(adev, i2c_hid_acpi_gpios);
 }
 
 static const struct acpi_device_id i2c_hid_acpi_match[] = {
@@ -935,12 +946,6 @@ static int i2c_hid_probe(struct i2c_client *client,
 
dbg_hid(HID probe called for i2c 0x%02x\n, client-addr);
 
-   if (!client-irq) {
-   dev_err(client-dev,
-   HID over i2c has not been provided an Int IRQ\n);
-   return -EINVAL;
-   }
-
ihid = kzalloc(sizeof(struct i2c_hid), GFP_KERNEL);
if (!ihid)
return -ENOMEM;
@@ -960,6 +965,23 @@ static int i2c_hid_probe(struct i2c_client *client,
ihid-pdata = *platform_data;
}
 
+   if (client-irq  0) {
+   ihid-irq = client-irq;
+   } else if (ACPI_COMPANION(client-dev)) {
+   ihid-desc = gpiod_get(client-dev, NULL, GPIOD_IN);
+   if (IS_ERR(ihid-desc)) {
+   dev_err(client-dev, Failed to get GPIO interrupt\n);
+   return PTR_ERR(ihid-desc);
+   }
+
+   ihid-irq = gpiod_to_irq(ihid-desc);
+   if (ihid-irq  0) {
+   gpiod_put(ihid-desc);
+   dev_err(client-dev, Failed to convert GPIO to 
IRQ\n);
+   return ihid-irq;
+   }
+   }
+
i2c_set_clientdata(client, ihid);
 
ihid-client = client;
@@ -1022,13 +1044,16 @@ err_mem_free:
hid_destroy_device(hid);
 
 err_irq:
-   free_irq(client-irq, ihid);
+   free_irq(ihid-irq, ihid);
 
 err_pm:
pm_runtime_put_noidle(client-dev);
pm_runtime_disable(client-dev);
 
 err:
+   if (ihid-desc)
+   gpiod_put(ihid-desc);
+
i2c_hid_free_buffers(ihid);
kfree(ihid);
return ret;
@@ -1047,13 +1072,18 @@ static int i2c_hid_remove(struct i2c_client *client)
hid = ihid-hid;
hid_destroy_device(hid);
 
-   free_irq(client-irq, ihid);
+   free_irq(ihid-irq, ihid);
 
if (ihid-bufsize)
i2c_hid_free_buffers(ihid);
 
+   if (ihid-desc)
+   gpiod_put(ihid-desc);
+
kfree(ihid);
 
+   acpi_dev_remove_driver_gpios(ACPI_COMPANION(client-dev));
+
return 0;
 }
 
@@ -1065,9 +1095,9 @@ static int 

Re: [PATCH 3/3] HID: i2c-hid: Add support for ACPI GPIO interrupts

2015-02-23 Thread Benjamin Tissoires
On Feb 23 2015 or thereabouts, Mika Westerberg wrote:
 The HID over I2C specification allows to have the interrupt for a HID
 device to be GPIO instead of directly connected to the IO-APIC.
 
 Add support for this so that when the driver does not find proper interrupt
 number from the I2C client structure we check if it has ACPI GpioInt()
 resource listed in _CRS. If it is found we convert it to an interrupt
 number and use it instead.
 
 Signed-off-by: Mika Westerberg mika.westerb...@linux.intel.com
 ---

I know this has been already discussed, so don't take this as a request
for a change. I however hoped that the acpi subsystem would provide the
irq directly in the i2c client without having to deal with it in
i2c_hid. For me, declaring the GPIO as an interrupt means that the irq
should be created in the first place. However, if we also have access to
the gpio, that means that we can read the value of it, which is better in
our case. So I am fine with all the solutions - as long as it works :)

I don't know enough of the use of gpios in acpi to properly review the
code. So I'll just add my:
Acked-by: Benjamin Tissoires benjamin.tissoi...@redhat.com

Cheers,
Benjamin

  drivers/hid/i2c-hid/i2c-hid.c | 68 
 +++
  1 file changed, 50 insertions(+), 18 deletions(-)
 
 diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c
 index 404ccde49acd..c6cad72f6296 100644
 --- a/drivers/hid/i2c-hid/i2c-hid.c
 +++ b/drivers/hid/i2c-hid/i2c-hid.c
 @@ -37,6 +37,7 @@
  #include linux/mutex.h
  #include linux/acpi.h
  #include linux/of.h
 +#include linux/gpio/consumer.h
  
  #include linux/i2c/i2c-hid.h
  
 @@ -144,6 +145,8 @@ struct i2c_hid {
   unsigned long   flags;  /* device flags */
  
   wait_queue_head_t   wait;   /* For waiting the interrupt */
 + struct gpio_desc*desc;
 + int irq;
  
   struct i2c_hid_platform_data pdata;
  };
 @@ -790,16 +793,16 @@ static int i2c_hid_init_irq(struct i2c_client *client)
   struct i2c_hid *ihid = i2c_get_clientdata(client);
   int ret;
  
 - dev_dbg(client-dev, Requesting IRQ: %d\n, client-irq);
 + dev_dbg(client-dev, Requesting IRQ: %d\n, ihid-irq);
  
 - ret = request_threaded_irq(client-irq, NULL, i2c_hid_irq,
 + ret = request_threaded_irq(ihid-irq, NULL, i2c_hid_irq,
   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
   client-name, ihid);
   if (ret  0) {
   dev_warn(client-dev,
   Could not register for %s interrupt, irq = %d,
ret = %d\n,
 - client-name, client-irq, ret);
 + client-name, ihid-irq, ret);
  
   return ret;
   }
 @@ -846,6 +849,14 @@ static int i2c_hid_fetch_hid_descriptor(struct i2c_hid 
 *ihid)
  }
  
  #ifdef CONFIG_ACPI
 +
 +/* Default GPIO mapping */
 +static const struct acpi_gpio_params i2c_hid_irq_gpio = { 0, 0, true };
 +static const struct acpi_gpio_mapping i2c_hid_acpi_gpios[] = {
 + { gpios, i2c_hid_irq_gpio, 1 },
 + { },
 +};
 +
  static int i2c_hid_acpi_pdata(struct i2c_client *client,
   struct i2c_hid_platform_data *pdata)
  {
 @@ -871,7 +882,7 @@ static int i2c_hid_acpi_pdata(struct i2c_client *client,
   pdata-hid_descriptor_address = obj-integer.value;
   ACPI_FREE(obj);
  
 - return 0;
 + return acpi_dev_add_driver_gpios(adev, i2c_hid_acpi_gpios);
  }
  
  static const struct acpi_device_id i2c_hid_acpi_match[] = {
 @@ -935,12 +946,6 @@ static int i2c_hid_probe(struct i2c_client *client,
  
   dbg_hid(HID probe called for i2c 0x%02x\n, client-addr);
  
 - if (!client-irq) {
 - dev_err(client-dev,
 - HID over i2c has not been provided an Int IRQ\n);
 - return -EINVAL;
 - }
 -
   ihid = kzalloc(sizeof(struct i2c_hid), GFP_KERNEL);
   if (!ihid)
   return -ENOMEM;
 @@ -960,6 +965,23 @@ static int i2c_hid_probe(struct i2c_client *client,
   ihid-pdata = *platform_data;
   }
  
 + if (client-irq  0) {
 + ihid-irq = client-irq;
 + } else if (ACPI_COMPANION(client-dev)) {
 + ihid-desc = gpiod_get(client-dev, NULL, GPIOD_IN);
 + if (IS_ERR(ihid-desc)) {
 + dev_err(client-dev, Failed to get GPIO interrupt\n);
 + return PTR_ERR(ihid-desc);
 + }
 +
 + ihid-irq = gpiod_to_irq(ihid-desc);
 + if (ihid-irq  0) {
 + gpiod_put(ihid-desc);
 + dev_err(client-dev, Failed to convert GPIO to 
 IRQ\n);
 + return ihid-irq;
 + }
 + }
 +
   i2c_set_clientdata(client, ihid);
  
   ihid-client = client;
 @@ -1022,13 +1044,16 @@ err_mem_free:
   hid_destroy_device(hid);
  
  err_irq:
 - free_irq(client-irq, ihid);
 + free_irq(ihid-irq, 

Re: [PATCH 3/3] HID: i2c-hid: Add support for ACPI GPIO interrupts

2015-02-23 Thread Mika Westerberg
On Mon, Feb 23, 2015 at 10:35:02AM -0500, Benjamin Tissoires wrote:
 On Feb 23 2015 or thereabouts, Mika Westerberg wrote:
  The HID over I2C specification allows to have the interrupt for a HID
  device to be GPIO instead of directly connected to the IO-APIC.
  
  Add support for this so that when the driver does not find proper interrupt
  number from the I2C client structure we check if it has ACPI GpioInt()
  resource listed in _CRS. If it is found we convert it to an interrupt
  number and use it instead.
  
  Signed-off-by: Mika Westerberg mika.westerb...@linux.intel.com
  ---
 
 I know this has been already discussed, so don't take this as a request
 for a change. I however hoped that the acpi subsystem would provide the
 irq directly in the i2c client without having to deal with it in
 i2c_hid. For me, declaring the GPIO as an interrupt means that the irq
 should be created in the first place. However, if we also have access to
 the gpio, that means that we can read the value of it, which is better in
 our case. So I am fine with all the solutions - as long as it works :)

I understand your point.

It would be nice to do it that way but it is not so simple.

For example if we have some button array that has several GpioInts
listed, we convert the first to an interrupt but the driver needs to
handle all the rest itself (taking the one converted interrupt into
account).

Another problem that I can think of is to determine who is responsible
in releasing the GPIO and at which point. We cannot just use devm_* APIs
because no driver has been probed yet.

Also if the driver needs to use the interrupt as GPIO for reading its
value we would first need to release it (because it has been requested
by the core code), then re-request it, read the value and then somehow
release it back so that the core code can release it...

That's why I think it is better to let drivers handle these themselves
as they like.

Of course if someone has good idea how to do this properly in the core
code, I'm all ears.

 I don't know enough of the use of gpios in acpi to properly review the
 code. So I'll just add my:
 Acked-by: Benjamin Tissoires benjamin.tissoi...@redhat.com

Thanks :-)
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/