Commit 459773ae8dbbd480886d186181c6bc2e8556025f

Authored by Michael Hennerich
Committed by Linus Torvalds
1 parent ead6db0843

gpio: adp5588-gpio: support interrupt controller

Implement irq_chip functionality on ADP5588/5587 GPIO expanders.  Only
level sensitive interrupts are supported.  Interrupts provided by this
irq_chip must be requested using request_threaded_irq().

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 3 changed files with 278 additions and 21 deletions Side-by-side Diff

drivers/gpio/Kconfig
... ... @@ -272,6 +272,13 @@
272 272 To compile this driver as a module, choose M here: the module will be
273 273 called adp5588-gpio.
274 274  
  275 +config GPIO_ADP5588_IRQ
  276 + bool "Interrupt controller support for ADP5588"
  277 + depends on GPIO_ADP5588=y
  278 + help
  279 + Say yes here to enable the adp5588 to be used as an interrupt
  280 + controller. It requires the driver to be built in the kernel.
  281 +
275 282 comment "PCI GPIO expanders:"
276 283  
277 284 config GPIO_CS5535
drivers/gpio/adp5588-gpio.c
1 1 /*
2 2 * GPIO Chip driver for Analog Devices
3   - * ADP5588 I/O Expander and QWERTY Keypad Controller
  3 + * ADP5588/ADP5587 I/O Expander and QWERTY Keypad Controller
4 4 *
5   - * Copyright 2009 Analog Devices Inc.
  5 + * Copyright 2009-2010 Analog Devices Inc.
6 6 *
7 7 * Licensed under the GPL-2 or later.
8 8 */
9 9  
10 10  
11 11  
12 12  
13 13  
... ... @@ -13,21 +13,34 @@
13 13 #include <linux/init.h>
14 14 #include <linux/i2c.h>
15 15 #include <linux/gpio.h>
  16 +#include <linux/interrupt.h>
  17 +#include <linux/irq.h>
16 18  
17 19 #include <linux/i2c/adp5588.h>
18 20  
19   -#define DRV_NAME "adp5588-gpio"
20   -#define MAXGPIO 18
21   -#define ADP_BANK(offs) ((offs) >> 3)
22   -#define ADP_BIT(offs) (1u << ((offs) & 0x7))
  21 +#define DRV_NAME "adp5588-gpio"
23 22  
  23 +/*
  24 + * Early pre 4.0 Silicon required to delay readout by at least 25ms,
  25 + * since the Event Counter Register updated 25ms after the interrupt
  26 + * asserted.
  27 + */
  28 +#define WA_DELAYED_READOUT_REVID(rev) ((rev) < 4)
  29 +
24 30 struct adp5588_gpio {
25 31 struct i2c_client *client;
26 32 struct gpio_chip gpio_chip;
27 33 struct mutex lock; /* protect cached dir, dat_out */
  34 + /* protect serialized access to the interrupt controller bus */
  35 + struct mutex irq_lock;
28 36 unsigned gpio_start;
  37 + unsigned irq_base;
29 38 uint8_t dat_out[3];
30 39 uint8_t dir[3];
  40 + uint8_t int_lvl[3];
  41 + uint8_t int_en[3];
  42 + uint8_t irq_mask[3];
  43 + uint8_t irq_stat[3];
31 44 };
32 45  
33 46 static int adp5588_gpio_read(struct i2c_client *client, u8 reg)
... ... @@ -55,8 +68,8 @@
55 68 struct adp5588_gpio *dev =
56 69 container_of(chip, struct adp5588_gpio, gpio_chip);
57 70  
58   - return !!(adp5588_gpio_read(dev->client, GPIO_DAT_STAT1 + ADP_BANK(off))
59   - & ADP_BIT(off));
  71 + return !!(adp5588_gpio_read(dev->client,
  72 + GPIO_DAT_STAT1 + ADP5588_BANK(off)) & ADP5588_BIT(off));
60 73 }
61 74  
62 75 static void adp5588_gpio_set_value(struct gpio_chip *chip,
... ... @@ -66,8 +79,8 @@
66 79 struct adp5588_gpio *dev =
67 80 container_of(chip, struct adp5588_gpio, gpio_chip);
68 81  
69   - bank = ADP_BANK(off);
70   - bit = ADP_BIT(off);
  82 + bank = ADP5588_BANK(off);
  83 + bit = ADP5588_BIT(off);
71 84  
72 85 mutex_lock(&dev->lock);
73 86 if (val)
74 87  
... ... @@ -87,10 +100,10 @@
87 100 struct adp5588_gpio *dev =
88 101 container_of(chip, struct adp5588_gpio, gpio_chip);
89 102  
90   - bank = ADP_BANK(off);
  103 + bank = ADP5588_BANK(off);
91 104  
92 105 mutex_lock(&dev->lock);
93   - dev->dir[bank] &= ~ADP_BIT(off);
  106 + dev->dir[bank] &= ~ADP5588_BIT(off);
94 107 ret = adp5588_gpio_write(dev->client, GPIO_DIR1 + bank, dev->dir[bank]);
95 108 mutex_unlock(&dev->lock);
96 109  
... ... @@ -105,8 +118,8 @@
105 118 struct adp5588_gpio *dev =
106 119 container_of(chip, struct adp5588_gpio, gpio_chip);
107 120  
108   - bank = ADP_BANK(off);
109   - bit = ADP_BIT(off);
  121 + bank = ADP5588_BANK(off);
  122 + bit = ADP5588_BIT(off);
110 123  
111 124 mutex_lock(&dev->lock);
112 125 dev->dir[bank] |= bit;
... ... @@ -125,6 +138,213 @@
125 138 return ret;
126 139 }
127 140  
  141 +#ifdef CONFIG_GPIO_ADP5588_IRQ
  142 +static int adp5588_gpio_to_irq(struct gpio_chip *chip, unsigned off)
  143 +{
  144 + struct adp5588_gpio *dev =
  145 + container_of(chip, struct adp5588_gpio, gpio_chip);
  146 + return dev->irq_base + off;
  147 +}
  148 +
  149 +static void adp5588_irq_bus_lock(unsigned int irq)
  150 +{
  151 + struct adp5588_gpio *dev = get_irq_chip_data(irq);
  152 + mutex_lock(&dev->irq_lock);
  153 +}
  154 +
  155 + /*
  156 + * genirq core code can issue chip->mask/unmask from atomic context.
  157 + * This doesn't work for slow busses where an access needs to sleep.
  158 + * bus_sync_unlock() is therefore called outside the atomic context,
  159 + * syncs the current irq mask state with the slow external controller
  160 + * and unlocks the bus.
  161 + */
  162 +
  163 +static void adp5588_irq_bus_sync_unlock(unsigned int irq)
  164 +{
  165 + struct adp5588_gpio *dev = get_irq_chip_data(irq);
  166 + int i;
  167 +
  168 + for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++)
  169 + if (dev->int_en[i] ^ dev->irq_mask[i]) {
  170 + dev->int_en[i] = dev->irq_mask[i];
  171 + adp5588_gpio_write(dev->client, GPIO_INT_EN1 + i,
  172 + dev->int_en[i]);
  173 + }
  174 +
  175 + mutex_unlock(&dev->irq_lock);
  176 +}
  177 +
  178 +static void adp5588_irq_mask(unsigned int irq)
  179 +{
  180 + struct adp5588_gpio *dev = get_irq_chip_data(irq);
  181 + unsigned gpio = irq - dev->irq_base;
  182 +
  183 + dev->irq_mask[ADP5588_BANK(gpio)] &= ~ADP5588_BIT(gpio);
  184 +}
  185 +
  186 +static void adp5588_irq_unmask(unsigned int irq)
  187 +{
  188 + struct adp5588_gpio *dev = get_irq_chip_data(irq);
  189 + unsigned gpio = irq - dev->irq_base;
  190 +
  191 + dev->irq_mask[ADP5588_BANK(gpio)] |= ADP5588_BIT(gpio);
  192 +}
  193 +
  194 +static int adp5588_irq_set_type(unsigned int irq, unsigned int type)
  195 +{
  196 + struct adp5588_gpio *dev = get_irq_chip_data(irq);
  197 + uint16_t gpio = irq - dev->irq_base;
  198 + unsigned bank, bit;
  199 +
  200 + if ((type & IRQ_TYPE_EDGE_BOTH)) {
  201 + dev_err(&dev->client->dev, "irq %d: unsupported type %d\n",
  202 + irq, type);
  203 + return -EINVAL;
  204 + }
  205 +
  206 + bank = ADP5588_BANK(gpio);
  207 + bit = ADP5588_BIT(gpio);
  208 +
  209 + if (type & IRQ_TYPE_LEVEL_HIGH)
  210 + dev->int_lvl[bank] |= bit;
  211 + else if (type & IRQ_TYPE_LEVEL_LOW)
  212 + dev->int_lvl[bank] &= ~bit;
  213 + else
  214 + return -EINVAL;
  215 +
  216 + adp5588_gpio_direction_input(&dev->gpio_chip, gpio);
  217 + adp5588_gpio_write(dev->client, GPIO_INT_LVL1 + bank,
  218 + dev->int_lvl[bank]);
  219 +
  220 + return 0;
  221 +}
  222 +
  223 +static struct irq_chip adp5588_irq_chip = {
  224 + .name = "adp5588",
  225 + .mask = adp5588_irq_mask,
  226 + .unmask = adp5588_irq_unmask,
  227 + .bus_lock = adp5588_irq_bus_lock,
  228 + .bus_sync_unlock = adp5588_irq_bus_sync_unlock,
  229 + .set_type = adp5588_irq_set_type,
  230 +};
  231 +
  232 +static int adp5588_gpio_read_intstat(struct i2c_client *client, u8 *buf)
  233 +{
  234 + int ret = i2c_smbus_read_i2c_block_data(client, GPIO_INT_STAT1, 3, buf);
  235 +
  236 + if (ret < 0)
  237 + dev_err(&client->dev, "Read INT_STAT Error\n");
  238 +
  239 + return ret;
  240 +}
  241 +
  242 +static irqreturn_t adp5588_irq_handler(int irq, void *devid)
  243 +{
  244 + struct adp5588_gpio *dev = devid;
  245 + unsigned status, bank, bit, pending;
  246 + int ret;
  247 + status = adp5588_gpio_read(dev->client, INT_STAT);
  248 +
  249 + if (status & ADP5588_GPI_INT) {
  250 + ret = adp5588_gpio_read_intstat(dev->client, dev->irq_stat);
  251 + if (ret < 0)
  252 + memset(dev->irq_stat, 0, ARRAY_SIZE(dev->irq_stat));
  253 +
  254 + for (bank = 0; bank <= ADP5588_BANK(ADP5588_MAXGPIO);
  255 + bank++, bit = 0) {
  256 + pending = dev->irq_stat[bank] & dev->irq_mask[bank];
  257 +
  258 + while (pending) {
  259 + if (pending & (1 << bit)) {
  260 + handle_nested_irq(dev->irq_base +
  261 + (bank << 3) + bit);
  262 + pending &= ~(1 << bit);
  263 +
  264 + }
  265 + bit++;
  266 + }
  267 + }
  268 + }
  269 +
  270 + adp5588_gpio_write(dev->client, INT_STAT, status); /* Status is W1C */
  271 +
  272 + return IRQ_HANDLED;
  273 +}
  274 +
  275 +static int adp5588_irq_setup(struct adp5588_gpio *dev)
  276 +{
  277 + struct i2c_client *client = dev->client;
  278 + struct adp5588_gpio_platform_data *pdata = client->dev.platform_data;
  279 + unsigned gpio;
  280 + int ret;
  281 +
  282 + adp5588_gpio_write(client, CFG, ADP5588_AUTO_INC);
  283 + adp5588_gpio_write(client, INT_STAT, -1); /* status is W1C */
  284 + adp5588_gpio_read_intstat(client, dev->irq_stat); /* read to clear */
  285 +
  286 + dev->irq_base = pdata->irq_base;
  287 + mutex_init(&dev->irq_lock);
  288 +
  289 + for (gpio = 0; gpio < dev->gpio_chip.ngpio; gpio++) {
  290 + int irq = gpio + dev->irq_base;
  291 + set_irq_chip_data(irq, dev);
  292 + set_irq_chip_and_handler(irq, &adp5588_irq_chip,
  293 + handle_level_irq);
  294 + set_irq_nested_thread(irq, 1);
  295 +#ifdef CONFIG_ARM
  296 + /*
  297 + * ARM needs us to explicitly flag the IRQ as VALID,
  298 + * once we do so, it will also set the noprobe.
  299 + */
  300 + set_irq_flags(irq, IRQF_VALID);
  301 +#else
  302 + set_irq_noprobe(irq);
  303 +#endif
  304 + }
  305 +
  306 + ret = request_threaded_irq(client->irq,
  307 + NULL,
  308 + adp5588_irq_handler,
  309 + IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
  310 + dev_name(&client->dev), dev);
  311 + if (ret) {
  312 + dev_err(&client->dev, "failed to request irq %d\n",
  313 + client->irq);
  314 + goto out;
  315 + }
  316 +
  317 + dev->gpio_chip.to_irq = adp5588_gpio_to_irq;
  318 + adp5588_gpio_write(client, CFG,
  319 + ADP5588_AUTO_INC | ADP5588_INT_CFG | ADP5588_GPI_INT);
  320 +
  321 + return 0;
  322 +
  323 +out:
  324 + dev->irq_base = 0;
  325 + return ret;
  326 +}
  327 +
  328 +static void adp5588_irq_teardown(struct adp5588_gpio *dev)
  329 +{
  330 + if (dev->irq_base)
  331 + free_irq(dev->client->irq, dev);
  332 +}
  333 +
  334 +#else
  335 +static int adp5588_irq_setup(struct adp5588_gpio *dev)
  336 +{
  337 + struct i2c_client *client = dev->client;
  338 + dev_warn(&client->dev, "interrupt support not compiled in\n");
  339 +
  340 + return 0;
  341 +}
  342 +
  343 +static void adp5588_irq_teardown(struct adp5588_gpio *dev)
  344 +{
  345 +}
  346 +#endif /* CONFIG_GPIO_ADP5588_IRQ */
  347 +
128 348 static int __devinit adp5588_gpio_probe(struct i2c_client *client,
129 349 const struct i2c_device_id *id)
130 350 {
131 351  
132 352  
133 353  
134 354  
135 355  
136 356  
137 357  
... ... @@ -160,37 +380,46 @@
160 380 gc->can_sleep = 1;
161 381  
162 382 gc->base = pdata->gpio_start;
163   - gc->ngpio = MAXGPIO;
  383 + gc->ngpio = ADP5588_MAXGPIO;
164 384 gc->label = client->name;
165 385 gc->owner = THIS_MODULE;
166 386  
167 387 mutex_init(&dev->lock);
168 388  
169   -
170 389 ret = adp5588_gpio_read(dev->client, DEV_ID);
171 390 if (ret < 0)
172 391 goto err;
173 392  
174 393 revid = ret & ADP5588_DEVICE_ID_MASK;
175 394  
176   - for (i = 0, ret = 0; i <= ADP_BANK(MAXGPIO); i++) {
  395 + for (i = 0, ret = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) {
177 396 dev->dat_out[i] = adp5588_gpio_read(client, GPIO_DAT_OUT1 + i);
178 397 dev->dir[i] = adp5588_gpio_read(client, GPIO_DIR1 + i);
179 398 ret |= adp5588_gpio_write(client, KP_GPIO1 + i, 0);
180 399 ret |= adp5588_gpio_write(client, GPIO_PULL1 + i,
181 400 (pdata->pullup_dis_mask >> (8 * i)) & 0xFF);
182   -
  401 + ret |= adp5588_gpio_write(client, GPIO_INT_EN1 + i, 0);
183 402 if (ret)
184 403 goto err;
185 404 }
186 405  
  406 + if (pdata->irq_base) {
  407 + if (WA_DELAYED_READOUT_REVID(revid)) {
  408 + dev_warn(&client->dev, "GPIO int not supported\n");
  409 + } else {
  410 + ret = adp5588_irq_setup(dev);
  411 + if (ret)
  412 + goto err;
  413 + }
  414 + }
  415 +
187 416 ret = gpiochip_add(&dev->gpio_chip);
188 417 if (ret)
189   - goto err;
  418 + goto err_irq;
190 419  
191   - dev_info(&client->dev, "gpios %d..%d on a %s Rev. %d\n",
  420 + dev_info(&client->dev, "gpios %d..%d (IRQ Base %d) on a %s Rev. %d\n",
192 421 gc->base, gc->base + gc->ngpio - 1,
193   - client->name, revid);
  422 + pdata->irq_base, client->name, revid);
194 423  
195 424 if (pdata->setup) {
196 425 ret = pdata->setup(client, gc->base, gc->ngpio, pdata->context);
197 426  
... ... @@ -199,8 +428,11 @@
199 428 }
200 429  
201 430 i2c_set_clientdata(client, dev);
  431 +
202 432 return 0;
203 433  
  434 +err_irq:
  435 + adp5588_irq_teardown(dev);
204 436 err:
205 437 kfree(dev);
206 438 return ret;
... ... @@ -221,6 +453,9 @@
221 453 return ret;
222 454 }
223 455 }
  456 +
  457 + if (dev->irq_base)
  458 + free_irq(dev->client->irq, dev);
224 459  
225 460 ret = gpiochip_remove(&dev->gpio_chip);
226 461 if (ret) {
include/linux/i2c/adp5588.h
... ... @@ -74,6 +74,20 @@
74 74  
75 75 #define ADP5588_DEVICE_ID_MASK 0xF
76 76  
  77 + /* Configuration Register1 */
  78 +#define ADP5588_AUTO_INC (1 << 7)
  79 +#define ADP5588_GPIEM_CFG (1 << 6)
  80 +#define ADP5588_INT_CFG (1 << 4)
  81 +#define ADP5588_GPI_IEN (1 << 1)
  82 +
  83 +/* Interrupt Status Register */
  84 +#define ADP5588_GPI_INT (1 << 1)
  85 +#define ADP5588_KE_INT (1 << 0)
  86 +
  87 +#define ADP5588_MAXGPIO 18
  88 +#define ADP5588_BANK(offs) ((offs) >> 3)
  89 +#define ADP5588_BIT(offs) (1u << ((offs) & 0x7))
  90 +
77 91 /* Put one of these structures in i2c_board_info platform_data */
78 92  
79 93 #define ADP5588_KEYMAPSIZE 80
... ... @@ -128,6 +142,7 @@
128 142  
129 143 struct adp5588_gpio_platform_data {
130 144 unsigned gpio_start; /* GPIO Chip base # */
  145 + unsigned irq_base; /* interrupt base # */
131 146 unsigned pullup_dis_mask; /* Pull-Up Disable Mask */
132 147 int (*setup)(struct i2c_client *client,
133 148 int gpio, unsigned ngpio,