brcm2708: update against latest rpi-3.10.y branch
[openwrt/staging/rmilecki.git] / target / linux / brcm2708 / patches-3.10 / 0154-gpio-support-low-and-high-level-interrupts.patch
1 From c334aa8da6e17555823ebf05bdb429ff224e99b3 Mon Sep 17 00:00:00 2001
2 From: popcornmix <popcornmix@gmail.com>
3 Date: Thu, 9 Jan 2014 16:05:20 +0000
4 Subject: [PATCH 154/174] gpio: support low and high level interrupts
5
6 ---
7 arch/arm/mach-bcm2708/bcm2708_gpio.c | 52 +++++++++++++++++++++++++-----------
8 1 file changed, 37 insertions(+), 15 deletions(-)
9
10 --- a/arch/arm/mach-bcm2708/bcm2708_gpio.c
11 +++ b/arch/arm/mach-bcm2708/bcm2708_gpio.c
12 @@ -58,6 +58,8 @@ struct bcm2708_gpio {
13 struct gpio_chip gc;
14 unsigned long rising;
15 unsigned long falling;
16 + unsigned long high;
17 + unsigned long low;
18 };
19
20 static int bcm2708_set_function(struct gpio_chip *gc, unsigned offset,
21 @@ -145,20 +147,22 @@ static int bcm2708_gpio_irq_set_type(str
22 unsigned irq = d->irq;
23 struct bcm2708_gpio *gpio = irq_get_chip_data(irq);
24
25 - if (type & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
26 + gpio->rising &= ~(1 << __bcm2708_irq_to_gpio(irq));
27 + gpio->falling &= ~(1 << __bcm2708_irq_to_gpio(irq));
28 + gpio->high &= ~(1 << __bcm2708_irq_to_gpio(irq));
29 + gpio->low &= ~(1 << __bcm2708_irq_to_gpio(irq));
30 +
31 + if (type & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
32 return -EINVAL;
33
34 - if (type & IRQ_TYPE_EDGE_RISING) {
35 + if (type & IRQ_TYPE_EDGE_RISING)
36 gpio->rising |= (1 << __bcm2708_irq_to_gpio(irq));
37 - } else {
38 - gpio->rising &= ~(1 << __bcm2708_irq_to_gpio(irq));
39 - }
40 -
41 - if (type & IRQ_TYPE_EDGE_FALLING) {
42 + if (type & IRQ_TYPE_EDGE_FALLING)
43 gpio->falling |= (1 << __bcm2708_irq_to_gpio(irq));
44 - } else {
45 - gpio->falling &= ~(1 << __bcm2708_irq_to_gpio(irq));
46 - }
47 + if (type & IRQ_TYPE_LEVEL_HIGH)
48 + gpio->high |= (1 << __bcm2708_irq_to_gpio(irq));
49 + if (type & IRQ_TYPE_LEVEL_LOW)
50 + gpio->low |= (1 << __bcm2708_irq_to_gpio(irq));
51 return 0;
52 }
53
54 @@ -168,13 +172,17 @@ static void bcm2708_gpio_irq_mask(struct
55 struct bcm2708_gpio *gpio = irq_get_chip_data(irq);
56 unsigned gn = __bcm2708_irq_to_gpio(irq);
57 unsigned gb = gn / 32;
58 - unsigned long rising = readl(gpio->base + GPIOREN(gb));
59 + unsigned long rising = readl(gpio->base + GPIOREN(gb));
60 unsigned long falling = readl(gpio->base + GPIOFEN(gb));
61 + unsigned long high = readl(gpio->base + GPIOHEN(gb));
62 + unsigned long low = readl(gpio->base + GPIOLEN(gb));
63
64 gn = gn % 32;
65
66 - writel(rising & ~(1 << gn), gpio->base + GPIOREN(gb));
67 + writel(rising & ~(1 << gn), gpio->base + GPIOREN(gb));
68 writel(falling & ~(1 << gn), gpio->base + GPIOFEN(gb));
69 + writel(high & ~(1 << gn), gpio->base + GPIOHEN(gb));
70 + writel(low & ~(1 << gn), gpio->base + GPIOLEN(gb));
71 }
72
73 static void bcm2708_gpio_irq_unmask(struct irq_data *d)
74 @@ -183,24 +191,38 @@ static void bcm2708_gpio_irq_unmask(stru
75 struct bcm2708_gpio *gpio = irq_get_chip_data(irq);
76 unsigned gn = __bcm2708_irq_to_gpio(irq);
77 unsigned gb = gn / 32;
78 - unsigned long rising = readl(gpio->base + GPIOREN(gb));
79 + unsigned long rising = readl(gpio->base + GPIOREN(gb));
80 unsigned long falling = readl(gpio->base + GPIOFEN(gb));
81 + unsigned long high = readl(gpio->base + GPIOHEN(gb));
82 + unsigned long low = readl(gpio->base + GPIOLEN(gb));
83
84 gn = gn % 32;
85
86 writel(1 << gn, gpio->base + GPIOEDS(gb));
87
88 if (gpio->rising & (1 << gn)) {
89 - writel(rising | (1 << gn), gpio->base + GPIOREN(gb));
90 + writel(rising | (1 << gn), gpio->base + GPIOREN(gb));
91 } else {
92 writel(rising & ~(1 << gn), gpio->base + GPIOREN(gb));
93 }
94
95 if (gpio->falling & (1 << gn)) {
96 - writel(falling | (1 << gn), gpio->base + GPIOFEN(gb));
97 + writel(falling | (1 << gn), gpio->base + GPIOFEN(gb));
98 } else {
99 writel(falling & ~(1 << gn), gpio->base + GPIOFEN(gb));
100 }
101 +
102 + if (gpio->high & (1 << gn)) {
103 + writel(high | (1 << gn), gpio->base + GPIOHEN(gb));
104 + } else {
105 + writel(high & ~(1 << gn), gpio->base + GPIOHEN(gb));
106 + }
107 +
108 + if (gpio->low & (1 << gn)) {
109 + writel(low | (1 << gn), gpio->base + GPIOLEN(gb));
110 + } else {
111 + writel(low & ~(1 << gn), gpio->base + GPIOLEN(gb));
112 + }
113 }
114
115 static struct irq_chip bcm2708_irqchip = {