Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

pinctrl: st: Add software edge trigger interrupt support

ST pin controller does not have hardware support for detecting edge
triggered interrupts, It only has level triggering support.
This patch attempts to fake up edge triggers from hw level trigger
support in software. With this facility now the gpios can be easily used
for keypads, otherwise it would be difficult for drivers like keypads to
work with level trigger interrupts.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

authored by

Srinivas Kandagatla and committed by
Linus Walleij
155795b9 727b0f71

+114 -2
+114 -2
drivers/pinctrl/pinctrl-st.c
··· 271 271 struct st_pinconf *pin_conf; 272 272 }; 273 273 274 + /* 275 + * Edge triggers are not supported at hardware level, it is supported by 276 + * software by exploiting the level trigger support in hardware. 277 + * Software uses a virtual register (EDGE_CONF) for edge trigger configuration 278 + * of each gpio pin in a GPIO bank. 279 + * 280 + * Each bank has a 32 bit EDGE_CONF register which is divided in to 8 parts of 281 + * 4-bits. Each 4-bit space is allocated for each pin in a gpio bank. 282 + * 283 + * bit allocation per pin is: 284 + * Bits: [0 - 3] | [4 - 7] [8 - 11] ... ... ... ... [ 28 - 31] 285 + * -------------------------------------------------------- 286 + * | pin-0 | pin-2 | pin-3 | ... ... ... ... | pin -7 | 287 + * -------------------------------------------------------- 288 + * 289 + * A pin can have one of following the values in its edge configuration field. 290 + * 291 + * ------- ---------------------------- 292 + * [0-3] - Description 293 + * ------- ---------------------------- 294 + * 0000 - No edge IRQ. 295 + * 0001 - Falling edge IRQ. 296 + * 0010 - Rising edge IRQ. 297 + * 0011 - Rising and Falling edge IRQ. 298 + * ------- ---------------------------- 299 + */ 300 + 301 + #define ST_IRQ_EDGE_CONF_BITS_PER_PIN 4 302 + #define ST_IRQ_EDGE_MASK 0xf 303 + #define ST_IRQ_EDGE_FALLING BIT(0) 304 + #define ST_IRQ_EDGE_RISING BIT(1) 305 + #define ST_IRQ_EDGE_BOTH (BIT(0) | BIT(1)) 306 + 307 + #define ST_IRQ_RISING_EDGE_CONF(pin) \ 308 + (ST_IRQ_EDGE_RISING << (pin * ST_IRQ_EDGE_CONF_BITS_PER_PIN)) 309 + 310 + #define ST_IRQ_FALLING_EDGE_CONF(pin) \ 311 + (ST_IRQ_EDGE_FALLING << (pin * ST_IRQ_EDGE_CONF_BITS_PER_PIN)) 312 + 313 + #define ST_IRQ_BOTH_EDGE_CONF(pin) \ 314 + (ST_IRQ_EDGE_BOTH << (pin * ST_IRQ_EDGE_CONF_BITS_PER_PIN)) 315 + 316 + #define ST_IRQ_EDGE_CONF(conf, pin) \ 317 + (conf >> (pin * ST_IRQ_EDGE_CONF_BITS_PER_PIN) & ST_IRQ_EDGE_MASK) 318 + 274 319 struct st_gpio_bank { 275 320 struct gpio_chip gpio_chip; 276 321 struct pinctrl_gpio_range range; 277 322 void __iomem *base; 278 323 struct st_pio_control pc; 279 324 struct irq_domain *domain; 325 + unsigned long irq_edge_conf; 326 + spinlock_t lock; 280 327 }; 281 328 282 329 struct st_pinctrl { ··· 1309 1262 unsigned long flags; 1310 1263 int comp, pin = d->hwirq; 1311 1264 u32 val; 1265 + u32 pin_edge_conf = 0; 1312 1266 1313 1267 switch (type) { 1314 1268 case IRQ_TYPE_LEVEL_HIGH: 1315 1269 comp = 0; 1316 1270 break; 1271 + case IRQ_TYPE_EDGE_FALLING: 1272 + comp = 0; 1273 + pin_edge_conf = ST_IRQ_FALLING_EDGE_CONF(pin); 1274 + break; 1317 1275 case IRQ_TYPE_LEVEL_LOW: 1318 1276 comp = 1; 1277 + break; 1278 + case IRQ_TYPE_EDGE_RISING: 1279 + comp = 1; 1280 + pin_edge_conf = ST_IRQ_RISING_EDGE_CONF(pin); 1281 + break; 1282 + case IRQ_TYPE_EDGE_BOTH: 1283 + comp = st_gpio_get(&bank->gpio_chip, pin); 1284 + pin_edge_conf = ST_IRQ_BOTH_EDGE_CONF(pin); 1319 1285 break; 1320 1286 default: 1321 1287 return -EINVAL; 1322 1288 } 1289 + 1290 + spin_lock_irqsave(&bank->lock, flags); 1291 + bank->irq_edge_conf &= ~(ST_IRQ_EDGE_MASK << ( 1292 + pin * ST_IRQ_EDGE_CONF_BITS_PER_PIN)); 1293 + bank->irq_edge_conf |= pin_edge_conf; 1294 + spin_unlock_irqrestore(&bank->lock, flags); 1323 1295 1324 1296 val = readl(bank->base + REG_PIO_PCOMP); 1325 1297 val &= ~BIT(pin); ··· 1348 1282 return 0; 1349 1283 } 1350 1284 1285 + /* 1286 + * As edge triggers are not supported at hardware level, it is supported by 1287 + * software by exploiting the level trigger support in hardware. 1288 + * 1289 + * Steps for detection raising edge interrupt in software. 1290 + * 1291 + * Step 1: CONFIGURE pin to detect level LOW interrupts. 1292 + * 1293 + * Step 2: DETECT level LOW interrupt and in irqmux/gpio bank interrupt handler, 1294 + * if the value of pin is low, then CONFIGURE pin for level HIGH interrupt. 1295 + * IGNORE calling the actual interrupt handler for the pin at this stage. 1296 + * 1297 + * Step 3: DETECT level HIGH interrupt and in irqmux/gpio-bank interrupt handler 1298 + * if the value of pin is HIGH, CONFIGURE pin for level LOW interrupt and then 1299 + * DISPATCH the interrupt to the interrupt handler of the pin. 1300 + * 1301 + * step-1 ________ __________ 1302 + * | | step - 3 1303 + * | | 1304 + * step -2 |_____| 1305 + * 1306 + * falling edge is also detected int the same way. 1307 + * 1308 + */ 1351 1309 static void __gpio_irq_handler(struct st_gpio_bank *bank) 1352 1310 { 1353 1311 unsigned long port_in, port_mask, port_comp, active_irqs; 1354 - int n; 1312 + unsigned long bank_edge_mask, flags; 1313 + int n, val, ecfg; 1314 + 1315 + spin_lock_irqsave(&bank->lock, flags); 1316 + bank_edge_mask = bank->irq_edge_conf; 1317 + spin_unlock_irqrestore(&bank->lock, flags); 1355 1318 1356 1319 for (;;) { 1357 1320 port_in = readl(bank->base + REG_PIO_PIN); ··· 1393 1298 break; 1394 1299 1395 1300 for_each_set_bit(n, &active_irqs, BITS_PER_LONG) { 1301 + /* check if we are detecting fake edges ... */ 1302 + ecfg = ST_IRQ_EDGE_CONF(bank_edge_mask, n); 1303 + 1304 + if (ecfg) { 1305 + /* edge detection. */ 1306 + val = st_gpio_get(&bank->gpio_chip, n); 1307 + 1308 + writel(BIT(n), 1309 + val ? bank->base + REG_PIO_SET_PCOMP : 1310 + bank->base + REG_PIO_CLR_PCOMP); 1311 + 1312 + if (ecfg != ST_IRQ_EDGE_BOTH && 1313 + !((ecfg & ST_IRQ_EDGE_FALLING) ^ val)) 1314 + continue; 1315 + } 1316 + 1396 1317 generic_handle_irq(irq_find_mapping(bank->domain, n)); 1397 1318 } 1398 1319 } ··· 1470 1359 struct st_gpio_bank *bank = h->host_data; 1471 1360 1472 1361 irq_set_chip(virq, &st_gpio_irqchip); 1473 - irq_set_handler(virq, handle_level_irq); 1362 + irq_set_handler(virq, handle_simple_irq); 1474 1363 set_irq_flags(virq, IRQF_VALID); 1475 1364 irq_set_chip_data(virq, bank); 1476 1365 ··· 1503 1392 bank->gpio_chip.base = bank_num * ST_GPIO_PINS_PER_BANK; 1504 1393 bank->gpio_chip.ngpio = ST_GPIO_PINS_PER_BANK; 1505 1394 bank->gpio_chip.of_node = np; 1395 + spin_lock_init(&bank->lock); 1506 1396 1507 1397 of_property_read_string(np, "st,bank-name", &range->name); 1508 1398 bank->gpio_chip.label = range->name;