aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/pinctrl-sunxi.h
diff options
context:
space:
mode:
authorMaxime Ripard <maxime.ripard@free-electrons.com>2013-06-08 06:05:44 -0400
committerLinus Walleij <linus.walleij@linaro.org>2013-06-16 05:57:31 -0400
commit60242db1a7292cc63ae390f12ec9d62e9e2f6935 (patch)
treee563fde69b9b305469d92fbce919ff3c96adfa73 /drivers/pinctrl/pinctrl-sunxi.h
parent814d4f2e153dfb337ee894d1f23863e623add4ab (diff)
pinctrl: sunxi: Add external interrupts support
The port controller IP found in the Allwinner A10 and A13 can use few of the pins it manage as an interrupt source, called external interrupts in the datasheet. The number of these external interrupts are SoCs specific, but the current upper limit is 32. In order to work, the external interrupts' pins have to be muxed to a specific function to generate an interrupt. This patch adds the irqchip and the needed logic to use the PIO controller as an interrupt controller. Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/pinctrl-sunxi.h')
-rw-r--r--drivers/pinctrl/pinctrl-sunxi.h68
1 files changed, 68 insertions, 0 deletions
diff --git a/drivers/pinctrl/pinctrl-sunxi.h b/drivers/pinctrl/pinctrl-sunxi.h
index e921621059ce..d68047d8f699 100644
--- a/drivers/pinctrl/pinctrl-sunxi.h
+++ b/drivers/pinctrl/pinctrl-sunxi.h
@@ -344,9 +344,31 @@
344#define PULL_PINS_BITS 2 344#define PULL_PINS_BITS 2
345#define PULL_PINS_MASK 0x03 345#define PULL_PINS_MASK 0x03
346 346
347#define SUNXI_IRQ_NUMBER 32
348
349#define IRQ_CFG_REG 0x200
350#define IRQ_CFG_IRQ_PER_REG 8
351#define IRQ_CFG_IRQ_BITS 4
352#define IRQ_CFG_IRQ_MASK ((1 << IRQ_CFG_IRQ_BITS) - 1)
353#define IRQ_CTRL_REG 0x210
354#define IRQ_CTRL_IRQ_PER_REG 32
355#define IRQ_CTRL_IRQ_BITS 1
356#define IRQ_CTRL_IRQ_MASK ((1 << IRQ_CTRL_IRQ_BITS) - 1)
357#define IRQ_STATUS_REG 0x214
358#define IRQ_STATUS_IRQ_PER_REG 32
359#define IRQ_STATUS_IRQ_BITS 1
360#define IRQ_STATUS_IRQ_MASK ((1 << IRQ_STATUS_IRQ_BITS) - 1)
361
362#define IRQ_EDGE_RISING 0x00
363#define IRQ_EDGE_FALLING 0x01
364#define IRQ_LEVEL_HIGH 0x02
365#define IRQ_LEVEL_LOW 0x03
366#define IRQ_EDGE_BOTH 0x04
367
347struct sunxi_desc_function { 368struct sunxi_desc_function {
348 const char *name; 369 const char *name;
349 u8 muxval; 370 u8 muxval;
371 u8 irqnum;
350}; 372};
351 373
352struct sunxi_desc_pin { 374struct sunxi_desc_pin {
@@ -378,10 +400,13 @@ struct sunxi_pinctrl {
378 struct gpio_chip *chip; 400 struct gpio_chip *chip;
379 struct sunxi_pinctrl_desc *desc; 401 struct sunxi_pinctrl_desc *desc;
380 struct device *dev; 402 struct device *dev;
403 struct irq_domain *domain;
381 struct sunxi_pinctrl_function *functions; 404 struct sunxi_pinctrl_function *functions;
382 unsigned nfunctions; 405 unsigned nfunctions;
383 struct sunxi_pinctrl_group *groups; 406 struct sunxi_pinctrl_group *groups;
384 unsigned ngroups; 407 unsigned ngroups;
408 int irq;
409 int irq_array[SUNXI_IRQ_NUMBER];
385 struct pinctrl_dev *pctl_dev; 410 struct pinctrl_dev *pctl_dev;
386}; 411};
387 412
@@ -398,6 +423,13 @@ struct sunxi_pinctrl {
398 .muxval = _val, \ 423 .muxval = _val, \
399 } 424 }
400 425
426#define SUNXI_FUNCTION_IRQ(_val, _irq) \
427 { \
428 .name = "irq", \
429 .muxval = _val, \
430 .irqnum = _irq, \
431 }
432
401/* 433/*
402 * The sunXi PIO registers are organized as is: 434 * The sunXi PIO registers are organized as is:
403 * 0x00 - 0x0c Muxing values. 435 * 0x00 - 0x0c Muxing values.
@@ -475,4 +507,40 @@ static inline u32 sunxi_pull_offset(u16 pin)
475 return pin_num * PULL_PINS_BITS; 507 return pin_num * PULL_PINS_BITS;
476} 508}
477 509
510static inline u32 sunxi_irq_cfg_reg(u16 irq)
511{
512 u8 reg = irq / IRQ_CFG_IRQ_PER_REG;
513 return reg + IRQ_CFG_REG;
514}
515
516static inline u32 sunxi_irq_cfg_offset(u16 irq)
517{
518 u32 irq_num = irq % IRQ_CFG_IRQ_PER_REG;
519 return irq_num * IRQ_CFG_IRQ_BITS;
520}
521
522static inline u32 sunxi_irq_ctrl_reg(u16 irq)
523{
524 u8 reg = irq / IRQ_CTRL_IRQ_PER_REG;
525 return reg + IRQ_CTRL_REG;
526}
527
528static inline u32 sunxi_irq_ctrl_offset(u16 irq)
529{
530 u32 irq_num = irq % IRQ_CTRL_IRQ_PER_REG;
531 return irq_num * IRQ_CTRL_IRQ_BITS;
532}
533
534static inline u32 sunxi_irq_status_reg(u16 irq)
535{
536 u8 reg = irq / IRQ_STATUS_IRQ_PER_REG;
537 return reg + IRQ_STATUS_REG;
538}
539
540static inline u32 sunxi_irq_status_offset(u16 irq)
541{
542 u32 irq_num = irq % IRQ_STATUS_IRQ_PER_REG;
543 return irq_num * IRQ_STATUS_IRQ_BITS;
544}
545
478#endif /* __PINCTRL_SUNXI_H */ 546#endif /* __PINCTRL_SUNXI_H */