Skip to content

Commit

Permalink
mfd: Add support for irq over gpio pin to stmpe
Browse files Browse the repository at this point in the history
On many boards, stmpe is present as an separate device (not as part of SoC).
Here gpio lines are mostly used for getting interrupts. This patch adds in
support to handle irq over gpio pin.

Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
  • Loading branch information
Viresh Kumar authored and Samuel Ortiz committed Jan 8, 2012
1 parent 42ab84f commit 73de16d
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 7 deletions.
36 changes: 29 additions & 7 deletions drivers/mfd/stmpe.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
*/

#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
Expand Down Expand Up @@ -877,19 +878,21 @@ static int __devinit stmpe_devices_init(struct stmpe *stmpe)
static int stmpe_suspend(struct device *dev)
{
struct i2c_client *i2c = to_i2c_client(dev);
struct stmpe *stmpe = i2c_get_clientdata(i2c);

if (device_may_wakeup(&i2c->dev))
enable_irq_wake(i2c->irq);
enable_irq_wake(stmpe->irq);

return 0;
}

static int stmpe_resume(struct device *dev)
{
struct i2c_client *i2c = to_i2c_client(dev);
struct stmpe *stmpe = i2c_get_clientdata(i2c);

if (device_may_wakeup(&i2c->dev))
disable_irq_wake(i2c->irq);
disable_irq_wake(stmpe->irq);

return 0;
}
Expand Down Expand Up @@ -925,15 +928,28 @@ static int __devinit stmpe_probe(struct i2c_client *i2c,

i2c_set_clientdata(i2c, stmpe);

if (pdata->irq_over_gpio) {
ret = gpio_request_one(pdata->irq_gpio, GPIOF_DIR_IN, "stmpe");
if (ret) {
dev_err(stmpe->dev, "failed to request IRQ GPIO: %d\n",
ret);
goto out_free;
}

stmpe->irq = gpio_to_irq(pdata->irq_gpio);
} else {
stmpe->irq = i2c->irq;
}

ret = stmpe_chip_init(stmpe);
if (ret)
goto out_free;
goto free_gpio;

ret = stmpe_irq_init(stmpe);
if (ret)
goto out_free;
goto free_gpio;

ret = request_threaded_irq(stmpe->i2c->irq, NULL, stmpe_irq,
ret = request_threaded_irq(stmpe->irq, NULL, stmpe_irq,
pdata->irq_trigger | IRQF_ONESHOT,
"stmpe", stmpe);
if (ret) {
Expand All @@ -951,9 +967,12 @@ static int __devinit stmpe_probe(struct i2c_client *i2c,

out_removedevs:
mfd_remove_devices(stmpe->dev);
free_irq(stmpe->i2c->irq, stmpe);
free_irq(stmpe->irq, stmpe);
out_removeirq:
stmpe_irq_remove(stmpe);
free_gpio:
if (pdata->irq_over_gpio)
gpio_free(pdata->irq_gpio);
out_free:
kfree(stmpe);
return ret;
Expand All @@ -965,9 +984,12 @@ static int __devexit stmpe_remove(struct i2c_client *client)

mfd_remove_devices(stmpe->dev);

free_irq(stmpe->i2c->irq, stmpe);
free_irq(stmpe->irq, stmpe);
stmpe_irq_remove(stmpe);

if (stmpe->pdata->irq_over_gpio)
gpio_free(stmpe->pdata->irq_gpio);

kfree(stmpe);

return 0;
Expand Down
7 changes: 7 additions & 0 deletions include/linux/mfd/stmpe.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ struct stmpe_variant_info;
* @variant: the detected STMPE model number
* @regs: list of addresses of registers which are at different addresses on
* different variants. Indexed by one of STMPE_IDX_*.
* @irq: irq number for stmpe
* @irq_base: starting IRQ number for internal IRQs
* @num_gpios: number of gpios, differs for variants
* @ier: cache of IER registers for bus_lock
Expand All @@ -76,6 +77,7 @@ struct stmpe {
struct stmpe_variant_info *variant;
const u8 *regs;

int irq;
int irq_base;
int num_gpios;
u8 ier[2];
Expand Down Expand Up @@ -183,6 +185,9 @@ struct stmpe_ts_platform_data {
* @autosleep_timeout: inactivity timeout in milliseconds for autosleep
* @irq_base: base IRQ number. %STMPE_NR_IRQS irqs will be used, or
* %STMPE_NR_INTERNAL_IRQS if the GPIO driver is not used.
* @irq_over_gpio: true if gpio is used to get irq
* @irq_gpio: gpio number over which irq will be requested (significant only if
* irq_over_gpio is true)
* @gpio: GPIO-specific platform data
* @keypad: keypad-specific platform data
* @ts: touchscreen-specific platform data
Expand All @@ -194,6 +199,8 @@ struct stmpe_platform_data {
unsigned int irq_trigger;
bool irq_invert_polarity;
bool autosleep;
bool irq_over_gpio;
int irq_gpio;
int autosleep_timeout;

struct stmpe_gpio_platform_data *gpio;
Expand Down

0 comments on commit 73de16d

Please sign in to comment.