diff options
Diffstat (limited to 'drivers/gpio/gpio-brcmstb.c')
-rw-r--r-- | drivers/gpio/gpio-brcmstb.c | 422 |
1 files changed, 323 insertions, 99 deletions
diff --git a/drivers/gpio/gpio-brcmstb.c b/drivers/gpio/gpio-brcmstb.c index dd0308cc8bb0..545d43a587b7 100644 --- a/drivers/gpio/gpio-brcmstb.c +++ b/drivers/gpio/gpio-brcmstb.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2015 Broadcom Corporation | 2 | * Copyright (C) 2015-2017 Broadcom |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or | 4 | * This program is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU General Public License as | 5 | * modify it under the terms of the GNU General Public License as |
@@ -19,17 +19,30 @@ | |||
19 | #include <linux/irqdomain.h> | 19 | #include <linux/irqdomain.h> |
20 | #include <linux/irqchip/chained_irq.h> | 20 | #include <linux/irqchip/chained_irq.h> |
21 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
22 | #include <linux/reboot.h> | 22 | #include <linux/bitops.h> |
23 | 23 | ||
24 | #define GIO_BANK_SIZE 0x20 | 24 | enum gio_reg_index { |
25 | #define GIO_ODEN(bank) (((bank) * GIO_BANK_SIZE) + 0x00) | 25 | GIO_REG_ODEN = 0, |
26 | #define GIO_DATA(bank) (((bank) * GIO_BANK_SIZE) + 0x04) | 26 | GIO_REG_DATA, |
27 | #define GIO_IODIR(bank) (((bank) * GIO_BANK_SIZE) + 0x08) | 27 | GIO_REG_IODIR, |
28 | #define GIO_EC(bank) (((bank) * GIO_BANK_SIZE) + 0x0c) | 28 | GIO_REG_EC, |
29 | #define GIO_EI(bank) (((bank) * GIO_BANK_SIZE) + 0x10) | 29 | GIO_REG_EI, |
30 | #define GIO_MASK(bank) (((bank) * GIO_BANK_SIZE) + 0x14) | 30 | GIO_REG_MASK, |
31 | #define GIO_LEVEL(bank) (((bank) * GIO_BANK_SIZE) + 0x18) | 31 | GIO_REG_LEVEL, |
32 | #define GIO_STAT(bank) (((bank) * GIO_BANK_SIZE) + 0x1c) | 32 | GIO_REG_STAT, |
33 | NUMBER_OF_GIO_REGISTERS | ||
34 | }; | ||
35 | |||
36 | #define GIO_BANK_SIZE (NUMBER_OF_GIO_REGISTERS * sizeof(u32)) | ||
37 | #define GIO_BANK_OFF(bank, off) (((bank) * GIO_BANK_SIZE) + (off * sizeof(u32))) | ||
38 | #define GIO_ODEN(bank) GIO_BANK_OFF(bank, GIO_REG_ODEN) | ||
39 | #define GIO_DATA(bank) GIO_BANK_OFF(bank, GIO_REG_DATA) | ||
40 | #define GIO_IODIR(bank) GIO_BANK_OFF(bank, GIO_REG_IODIR) | ||
41 | #define GIO_EC(bank) GIO_BANK_OFF(bank, GIO_REG_EC) | ||
42 | #define GIO_EI(bank) GIO_BANK_OFF(bank, GIO_REG_EI) | ||
43 | #define GIO_MASK(bank) GIO_BANK_OFF(bank, GIO_REG_MASK) | ||
44 | #define GIO_LEVEL(bank) GIO_BANK_OFF(bank, GIO_REG_LEVEL) | ||
45 | #define GIO_STAT(bank) GIO_BANK_OFF(bank, GIO_REG_STAT) | ||
33 | 46 | ||
34 | struct brcmstb_gpio_bank { | 47 | struct brcmstb_gpio_bank { |
35 | struct list_head node; | 48 | struct list_head node; |
@@ -37,21 +50,23 @@ struct brcmstb_gpio_bank { | |||
37 | struct gpio_chip gc; | 50 | struct gpio_chip gc; |
38 | struct brcmstb_gpio_priv *parent_priv; | 51 | struct brcmstb_gpio_priv *parent_priv; |
39 | u32 width; | 52 | u32 width; |
40 | struct irq_chip irq_chip; | 53 | u32 wake_active; |
54 | u32 saved_regs[GIO_REG_STAT]; /* Don't save and restore GIO_REG_STAT */ | ||
41 | }; | 55 | }; |
42 | 56 | ||
43 | struct brcmstb_gpio_priv { | 57 | struct brcmstb_gpio_priv { |
44 | struct list_head bank_list; | 58 | struct list_head bank_list; |
45 | void __iomem *reg_base; | 59 | void __iomem *reg_base; |
46 | struct platform_device *pdev; | 60 | struct platform_device *pdev; |
61 | struct irq_domain *irq_domain; | ||
62 | struct irq_chip irq_chip; | ||
47 | int parent_irq; | 63 | int parent_irq; |
48 | int gpio_base; | 64 | int gpio_base; |
49 | bool can_wake; | 65 | int num_gpios; |
50 | int parent_wake_irq; | 66 | int parent_wake_irq; |
51 | struct notifier_block reboot_notifier; | ||
52 | }; | 67 | }; |
53 | 68 | ||
54 | #define MAX_GPIO_PER_BANK 32 | 69 | #define MAX_GPIO_PER_BANK 32 |
55 | #define GPIO_BANK(gpio) ((gpio) >> 5) | 70 | #define GPIO_BANK(gpio) ((gpio) >> 5) |
56 | /* assumes MAX_GPIO_PER_BANK is a multiple of 2 */ | 71 | /* assumes MAX_GPIO_PER_BANK is a multiple of 2 */ |
57 | #define GPIO_BIT(gpio) ((gpio) & (MAX_GPIO_PER_BANK - 1)) | 72 | #define GPIO_BIT(gpio) ((gpio) & (MAX_GPIO_PER_BANK - 1)) |
@@ -63,12 +78,40 @@ brcmstb_gpio_gc_to_priv(struct gpio_chip *gc) | |||
63 | return bank->parent_priv; | 78 | return bank->parent_priv; |
64 | } | 79 | } |
65 | 80 | ||
81 | static unsigned long | ||
82 | __brcmstb_gpio_get_active_irqs(struct brcmstb_gpio_bank *bank) | ||
83 | { | ||
84 | void __iomem *reg_base = bank->parent_priv->reg_base; | ||
85 | |||
86 | return bank->gc.read_reg(reg_base + GIO_STAT(bank->id)) & | ||
87 | bank->gc.read_reg(reg_base + GIO_MASK(bank->id)); | ||
88 | } | ||
89 | |||
90 | static unsigned long | ||
91 | brcmstb_gpio_get_active_irqs(struct brcmstb_gpio_bank *bank) | ||
92 | { | ||
93 | unsigned long status; | ||
94 | unsigned long flags; | ||
95 | |||
96 | spin_lock_irqsave(&bank->gc.bgpio_lock, flags); | ||
97 | status = __brcmstb_gpio_get_active_irqs(bank); | ||
98 | spin_unlock_irqrestore(&bank->gc.bgpio_lock, flags); | ||
99 | |||
100 | return status; | ||
101 | } | ||
102 | |||
103 | static int brcmstb_gpio_hwirq_to_offset(irq_hw_number_t hwirq, | ||
104 | struct brcmstb_gpio_bank *bank) | ||
105 | { | ||
106 | return hwirq - (bank->gc.base - bank->parent_priv->gpio_base); | ||
107 | } | ||
108 | |||
66 | static void brcmstb_gpio_set_imask(struct brcmstb_gpio_bank *bank, | 109 | static void brcmstb_gpio_set_imask(struct brcmstb_gpio_bank *bank, |
67 | unsigned int offset, bool enable) | 110 | unsigned int hwirq, bool enable) |
68 | { | 111 | { |
69 | struct gpio_chip *gc = &bank->gc; | 112 | struct gpio_chip *gc = &bank->gc; |
70 | struct brcmstb_gpio_priv *priv = bank->parent_priv; | 113 | struct brcmstb_gpio_priv *priv = bank->parent_priv; |
71 | u32 mask = gc->pin2mask(gc, offset); | 114 | u32 mask = BIT(brcmstb_gpio_hwirq_to_offset(hwirq, bank)); |
72 | u32 imask; | 115 | u32 imask; |
73 | unsigned long flags; | 116 | unsigned long flags; |
74 | 117 | ||
@@ -82,6 +125,17 @@ static void brcmstb_gpio_set_imask(struct brcmstb_gpio_bank *bank, | |||
82 | spin_unlock_irqrestore(&gc->bgpio_lock, flags); | 125 | spin_unlock_irqrestore(&gc->bgpio_lock, flags); |
83 | } | 126 | } |
84 | 127 | ||
128 | static int brcmstb_gpio_to_irq(struct gpio_chip *gc, unsigned offset) | ||
129 | { | ||
130 | struct brcmstb_gpio_priv *priv = brcmstb_gpio_gc_to_priv(gc); | ||
131 | /* gc_offset is relative to this gpio_chip; want real offset */ | ||
132 | int hwirq = offset + (gc->base - priv->gpio_base); | ||
133 | |||
134 | if (hwirq >= priv->num_gpios) | ||
135 | return -ENXIO; | ||
136 | return irq_create_mapping(priv->irq_domain, hwirq); | ||
137 | } | ||
138 | |||
85 | /* -------------------- IRQ chip functions -------------------- */ | 139 | /* -------------------- IRQ chip functions -------------------- */ |
86 | 140 | ||
87 | static void brcmstb_gpio_irq_mask(struct irq_data *d) | 141 | static void brcmstb_gpio_irq_mask(struct irq_data *d) |
@@ -100,12 +154,22 @@ static void brcmstb_gpio_irq_unmask(struct irq_data *d) | |||
100 | brcmstb_gpio_set_imask(bank, d->hwirq, true); | 154 | brcmstb_gpio_set_imask(bank, d->hwirq, true); |
101 | } | 155 | } |
102 | 156 | ||
157 | static void brcmstb_gpio_irq_ack(struct irq_data *d) | ||
158 | { | ||
159 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | ||
160 | struct brcmstb_gpio_bank *bank = gpiochip_get_data(gc); | ||
161 | struct brcmstb_gpio_priv *priv = bank->parent_priv; | ||
162 | u32 mask = BIT(brcmstb_gpio_hwirq_to_offset(d->hwirq, bank)); | ||
163 | |||
164 | gc->write_reg(priv->reg_base + GIO_STAT(bank->id), mask); | ||
165 | } | ||
166 | |||
103 | static int brcmstb_gpio_irq_set_type(struct irq_data *d, unsigned int type) | 167 | static int brcmstb_gpio_irq_set_type(struct irq_data *d, unsigned int type) |
104 | { | 168 | { |
105 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | 169 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
106 | struct brcmstb_gpio_bank *bank = gpiochip_get_data(gc); | 170 | struct brcmstb_gpio_bank *bank = gpiochip_get_data(gc); |
107 | struct brcmstb_gpio_priv *priv = bank->parent_priv; | 171 | struct brcmstb_gpio_priv *priv = bank->parent_priv; |
108 | u32 mask = BIT(d->hwirq); | 172 | u32 mask = BIT(brcmstb_gpio_hwirq_to_offset(d->hwirq, bank)); |
109 | u32 edge_insensitive, iedge_insensitive; | 173 | u32 edge_insensitive, iedge_insensitive; |
110 | u32 edge_config, iedge_config; | 174 | u32 edge_config, iedge_config; |
111 | u32 level, ilevel; | 175 | u32 level, ilevel; |
@@ -113,13 +177,13 @@ static int brcmstb_gpio_irq_set_type(struct irq_data *d, unsigned int type) | |||
113 | 177 | ||
114 | switch (type) { | 178 | switch (type) { |
115 | case IRQ_TYPE_LEVEL_LOW: | 179 | case IRQ_TYPE_LEVEL_LOW: |
116 | level = 0; | 180 | level = mask; |
117 | edge_config = 0; | 181 | edge_config = 0; |
118 | edge_insensitive = 0; | 182 | edge_insensitive = 0; |
119 | break; | 183 | break; |
120 | case IRQ_TYPE_LEVEL_HIGH: | 184 | case IRQ_TYPE_LEVEL_HIGH: |
121 | level = mask; | 185 | level = mask; |
122 | edge_config = 0; | 186 | edge_config = mask; |
123 | edge_insensitive = 0; | 187 | edge_insensitive = 0; |
124 | break; | 188 | break; |
125 | case IRQ_TYPE_EDGE_FALLING: | 189 | case IRQ_TYPE_EDGE_FALLING: |
@@ -166,11 +230,6 @@ static int brcmstb_gpio_priv_set_wake(struct brcmstb_gpio_priv *priv, | |||
166 | { | 230 | { |
167 | int ret = 0; | 231 | int ret = 0; |
168 | 232 | ||
169 | /* | ||
170 | * Only enable wake IRQ once for however many hwirqs can wake | ||
171 | * since they all use the same wake IRQ. Mask will be set | ||
172 | * up appropriately thanks to IRQCHIP_MASK_ON_SUSPEND flag. | ||
173 | */ | ||
174 | if (enable) | 233 | if (enable) |
175 | ret = enable_irq_wake(priv->parent_wake_irq); | 234 | ret = enable_irq_wake(priv->parent_wake_irq); |
176 | else | 235 | else |
@@ -184,7 +243,18 @@ static int brcmstb_gpio_priv_set_wake(struct brcmstb_gpio_priv *priv, | |||
184 | static int brcmstb_gpio_irq_set_wake(struct irq_data *d, unsigned int enable) | 243 | static int brcmstb_gpio_irq_set_wake(struct irq_data *d, unsigned int enable) |
185 | { | 244 | { |
186 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | 245 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
187 | struct brcmstb_gpio_priv *priv = brcmstb_gpio_gc_to_priv(gc); | 246 | struct brcmstb_gpio_bank *bank = gpiochip_get_data(gc); |
247 | struct brcmstb_gpio_priv *priv = bank->parent_priv; | ||
248 | u32 mask = BIT(brcmstb_gpio_hwirq_to_offset(d->hwirq, bank)); | ||
249 | |||
250 | /* | ||
251 | * Do not do anything specific for now, suspend/resume callbacks will | ||
252 | * configure the interrupt mask appropriately | ||
253 | */ | ||
254 | if (enable) | ||
255 | bank->wake_active |= mask; | ||
256 | else | ||
257 | bank->wake_active &= ~mask; | ||
188 | 258 | ||
189 | return brcmstb_gpio_priv_set_wake(priv, enable); | 259 | return brcmstb_gpio_priv_set_wake(priv, enable); |
190 | } | 260 | } |
@@ -195,43 +265,36 @@ static irqreturn_t brcmstb_gpio_wake_irq_handler(int irq, void *data) | |||
195 | 265 | ||
196 | if (!priv || irq != priv->parent_wake_irq) | 266 | if (!priv || irq != priv->parent_wake_irq) |
197 | return IRQ_NONE; | 267 | return IRQ_NONE; |
198 | pm_wakeup_event(&priv->pdev->dev, 0); | 268 | |
269 | /* Nothing to do */ | ||
199 | return IRQ_HANDLED; | 270 | return IRQ_HANDLED; |
200 | } | 271 | } |
201 | 272 | ||
202 | static void brcmstb_gpio_irq_bank_handler(struct brcmstb_gpio_bank *bank) | 273 | static void brcmstb_gpio_irq_bank_handler(struct brcmstb_gpio_bank *bank) |
203 | { | 274 | { |
204 | struct brcmstb_gpio_priv *priv = bank->parent_priv; | 275 | struct brcmstb_gpio_priv *priv = bank->parent_priv; |
205 | struct irq_domain *irq_domain = bank->gc.irqdomain; | 276 | struct irq_domain *domain = priv->irq_domain; |
206 | void __iomem *reg_base = priv->reg_base; | 277 | int hwbase = bank->gc.base - priv->gpio_base; |
207 | unsigned long status; | 278 | unsigned long status; |
208 | unsigned long flags; | ||
209 | 279 | ||
210 | spin_lock_irqsave(&bank->gc.bgpio_lock, flags); | 280 | while ((status = brcmstb_gpio_get_active_irqs(bank))) { |
211 | while ((status = bank->gc.read_reg(reg_base + GIO_STAT(bank->id)) & | 281 | unsigned int irq, offset; |
212 | bank->gc.read_reg(reg_base + GIO_MASK(bank->id)))) { | 282 | |
213 | int bit; | 283 | for_each_set_bit(offset, &status, 32) { |
214 | 284 | if (offset >= bank->width) | |
215 | for_each_set_bit(bit, &status, 32) { | ||
216 | u32 stat = bank->gc.read_reg(reg_base + | ||
217 | GIO_STAT(bank->id)); | ||
218 | if (bit >= bank->width) | ||
219 | dev_warn(&priv->pdev->dev, | 285 | dev_warn(&priv->pdev->dev, |
220 | "IRQ for invalid GPIO (bank=%d, offset=%d)\n", | 286 | "IRQ for invalid GPIO (bank=%d, offset=%d)\n", |
221 | bank->id, bit); | 287 | bank->id, offset); |
222 | bank->gc.write_reg(reg_base + GIO_STAT(bank->id), | 288 | irq = irq_linear_revmap(domain, hwbase + offset); |
223 | stat | BIT(bit)); | 289 | generic_handle_irq(irq); |
224 | generic_handle_irq(irq_find_mapping(irq_domain, bit)); | ||
225 | } | 290 | } |
226 | } | 291 | } |
227 | spin_unlock_irqrestore(&bank->gc.bgpio_lock, flags); | ||
228 | } | 292 | } |
229 | 293 | ||
230 | /* Each UPG GIO block has one IRQ for all banks */ | 294 | /* Each UPG GIO block has one IRQ for all banks */ |
231 | static void brcmstb_gpio_irq_handler(struct irq_desc *desc) | 295 | static void brcmstb_gpio_irq_handler(struct irq_desc *desc) |
232 | { | 296 | { |
233 | struct gpio_chip *gc = irq_desc_get_handler_data(desc); | 297 | struct brcmstb_gpio_priv *priv = irq_desc_get_handler_data(desc); |
234 | struct brcmstb_gpio_priv *priv = brcmstb_gpio_gc_to_priv(gc); | ||
235 | struct irq_chip *chip = irq_desc_get_chip(desc); | 298 | struct irq_chip *chip = irq_desc_get_chip(desc); |
236 | struct brcmstb_gpio_bank *bank; | 299 | struct brcmstb_gpio_bank *bank; |
237 | 300 | ||
@@ -244,19 +307,63 @@ static void brcmstb_gpio_irq_handler(struct irq_desc *desc) | |||
244 | chained_irq_exit(chip, desc); | 307 | chained_irq_exit(chip, desc); |
245 | } | 308 | } |
246 | 309 | ||
247 | static int brcmstb_gpio_reboot(struct notifier_block *nb, | 310 | static struct brcmstb_gpio_bank *brcmstb_gpio_hwirq_to_bank( |
248 | unsigned long action, void *data) | 311 | struct brcmstb_gpio_priv *priv, irq_hw_number_t hwirq) |
249 | { | 312 | { |
250 | struct brcmstb_gpio_priv *priv = | 313 | struct brcmstb_gpio_bank *bank; |
251 | container_of(nb, struct brcmstb_gpio_priv, reboot_notifier); | 314 | int i = 0; |
252 | 315 | ||
253 | /* Enable GPIO for S5 cold boot */ | 316 | /* banks are in descending order */ |
254 | if (action == SYS_POWER_OFF) | 317 | list_for_each_entry_reverse(bank, &priv->bank_list, node) { |
255 | brcmstb_gpio_priv_set_wake(priv, 1); | 318 | i += bank->gc.ngpio; |
319 | if (hwirq < i) | ||
320 | return bank; | ||
321 | } | ||
322 | return NULL; | ||
323 | } | ||
324 | |||
325 | /* | ||
326 | * This lock class tells lockdep that GPIO irqs are in a different | ||
327 | * category than their parents, so it won't report false recursion. | ||
328 | */ | ||
329 | static struct lock_class_key brcmstb_gpio_irq_lock_class; | ||
256 | 330 | ||
257 | return NOTIFY_DONE; | 331 | |
332 | static int brcmstb_gpio_irq_map(struct irq_domain *d, unsigned int irq, | ||
333 | irq_hw_number_t hwirq) | ||
334 | { | ||
335 | struct brcmstb_gpio_priv *priv = d->host_data; | ||
336 | struct brcmstb_gpio_bank *bank = | ||
337 | brcmstb_gpio_hwirq_to_bank(priv, hwirq); | ||
338 | struct platform_device *pdev = priv->pdev; | ||
339 | int ret; | ||
340 | |||
341 | if (!bank) | ||
342 | return -EINVAL; | ||
343 | |||
344 | dev_dbg(&pdev->dev, "Mapping irq %d for gpio line %d (bank %d)\n", | ||
345 | irq, (int)hwirq, bank->id); | ||
346 | ret = irq_set_chip_data(irq, &bank->gc); | ||
347 | if (ret < 0) | ||
348 | return ret; | ||
349 | irq_set_lockdep_class(irq, &brcmstb_gpio_irq_lock_class); | ||
350 | irq_set_chip_and_handler(irq, &priv->irq_chip, handle_level_irq); | ||
351 | irq_set_noprobe(irq); | ||
352 | return 0; | ||
258 | } | 353 | } |
259 | 354 | ||
355 | static void brcmstb_gpio_irq_unmap(struct irq_domain *d, unsigned int irq) | ||
356 | { | ||
357 | irq_set_chip_and_handler(irq, NULL, NULL); | ||
358 | irq_set_chip_data(irq, NULL); | ||
359 | } | ||
360 | |||
361 | static const struct irq_domain_ops brcmstb_gpio_irq_domain_ops = { | ||
362 | .map = brcmstb_gpio_irq_map, | ||
363 | .unmap = brcmstb_gpio_irq_unmap, | ||
364 | .xlate = irq_domain_xlate_twocell, | ||
365 | }; | ||
366 | |||
260 | /* Make sure that the number of banks matches up between properties */ | 367 | /* Make sure that the number of banks matches up between properties */ |
261 | static int brcmstb_gpio_sanity_check_banks(struct device *dev, | 368 | static int brcmstb_gpio_sanity_check_banks(struct device *dev, |
262 | struct device_node *np, struct resource *res) | 369 | struct device_node *np, struct resource *res) |
@@ -278,13 +385,25 @@ static int brcmstb_gpio_remove(struct platform_device *pdev) | |||
278 | { | 385 | { |
279 | struct brcmstb_gpio_priv *priv = platform_get_drvdata(pdev); | 386 | struct brcmstb_gpio_priv *priv = platform_get_drvdata(pdev); |
280 | struct brcmstb_gpio_bank *bank; | 387 | struct brcmstb_gpio_bank *bank; |
281 | int ret = 0; | 388 | int offset, ret = 0, virq; |
282 | 389 | ||
283 | if (!priv) { | 390 | if (!priv) { |
284 | dev_err(&pdev->dev, "called %s without drvdata!\n", __func__); | 391 | dev_err(&pdev->dev, "called %s without drvdata!\n", __func__); |
285 | return -EFAULT; | 392 | return -EFAULT; |
286 | } | 393 | } |
287 | 394 | ||
395 | if (priv->parent_irq > 0) | ||
396 | irq_set_chained_handler_and_data(priv->parent_irq, NULL, NULL); | ||
397 | |||
398 | /* Remove all IRQ mappings and delete the domain */ | ||
399 | if (priv->irq_domain) { | ||
400 | for (offset = 0; offset < priv->num_gpios; offset++) { | ||
401 | virq = irq_find_mapping(priv->irq_domain, offset); | ||
402 | irq_dispose_mapping(virq); | ||
403 | } | ||
404 | irq_domain_remove(priv->irq_domain); | ||
405 | } | ||
406 | |||
288 | /* | 407 | /* |
289 | * You can lose return values below, but we report all errors, and it's | 408 | * You can lose return values below, but we report all errors, and it's |
290 | * more important to actually perform all of the steps. | 409 | * more important to actually perform all of the steps. |
@@ -292,12 +411,6 @@ static int brcmstb_gpio_remove(struct platform_device *pdev) | |||
292 | list_for_each_entry(bank, &priv->bank_list, node) | 411 | list_for_each_entry(bank, &priv->bank_list, node) |
293 | gpiochip_remove(&bank->gc); | 412 | gpiochip_remove(&bank->gc); |
294 | 413 | ||
295 | if (priv->reboot_notifier.notifier_call) { | ||
296 | ret = unregister_reboot_notifier(&priv->reboot_notifier); | ||
297 | if (ret) | ||
298 | dev_err(&pdev->dev, | ||
299 | "failed to unregister reboot notifier\n"); | ||
300 | } | ||
301 | return ret; | 414 | return ret; |
302 | } | 415 | } |
303 | 416 | ||
@@ -332,66 +445,163 @@ static int brcmstb_gpio_of_xlate(struct gpio_chip *gc, | |||
332 | return offset; | 445 | return offset; |
333 | } | 446 | } |
334 | 447 | ||
335 | /* Before calling, must have bank->parent_irq set and gpiochip registered */ | 448 | /* priv->parent_irq and priv->num_gpios must be set before calling */ |
336 | static int brcmstb_gpio_irq_setup(struct platform_device *pdev, | 449 | static int brcmstb_gpio_irq_setup(struct platform_device *pdev, |
337 | struct brcmstb_gpio_bank *bank) | 450 | struct brcmstb_gpio_priv *priv) |
338 | { | 451 | { |
339 | struct brcmstb_gpio_priv *priv = bank->parent_priv; | ||
340 | struct device *dev = &pdev->dev; | 452 | struct device *dev = &pdev->dev; |
341 | struct device_node *np = dev->of_node; | 453 | struct device_node *np = dev->of_node; |
342 | int err; | 454 | int err; |
343 | 455 | ||
344 | bank->irq_chip.name = dev_name(dev); | 456 | priv->irq_domain = |
345 | bank->irq_chip.irq_mask = brcmstb_gpio_irq_mask; | 457 | irq_domain_add_linear(np, priv->num_gpios, |
346 | bank->irq_chip.irq_unmask = brcmstb_gpio_irq_unmask; | 458 | &brcmstb_gpio_irq_domain_ops, |
347 | bank->irq_chip.irq_set_type = brcmstb_gpio_irq_set_type; | 459 | priv); |
348 | 460 | if (!priv->irq_domain) { | |
349 | /* Ensures that all non-wakeup IRQs are disabled at suspend */ | 461 | dev_err(dev, "Couldn't allocate IRQ domain\n"); |
350 | bank->irq_chip.flags = IRQCHIP_MASK_ON_SUSPEND; | 462 | return -ENXIO; |
463 | } | ||
351 | 464 | ||
352 | if (IS_ENABLED(CONFIG_PM_SLEEP) && !priv->can_wake && | 465 | if (of_property_read_bool(np, "wakeup-source")) { |
353 | of_property_read_bool(np, "wakeup-source")) { | ||
354 | priv->parent_wake_irq = platform_get_irq(pdev, 1); | 466 | priv->parent_wake_irq = platform_get_irq(pdev, 1); |
355 | if (priv->parent_wake_irq < 0) { | 467 | if (priv->parent_wake_irq < 0) { |
468 | priv->parent_wake_irq = 0; | ||
356 | dev_warn(dev, | 469 | dev_warn(dev, |
357 | "Couldn't get wake IRQ - GPIOs will not be able to wake from sleep"); | 470 | "Couldn't get wake IRQ - GPIOs will not be able to wake from sleep"); |
358 | } else { | 471 | } else { |
359 | /* | 472 | /* |
360 | * Set wakeup capability before requesting wakeup | 473 | * Set wakeup capability so we can process boot-time |
361 | * interrupt, so we can process boot-time "wakeups" | 474 | * "wakeups" (e.g., from S5 cold boot) |
362 | * (e.g., from S5 cold boot) | ||
363 | */ | 475 | */ |
364 | device_set_wakeup_capable(dev, true); | 476 | device_set_wakeup_capable(dev, true); |
365 | device_wakeup_enable(dev); | 477 | device_wakeup_enable(dev); |
366 | err = devm_request_irq(dev, priv->parent_wake_irq, | 478 | err = devm_request_irq(dev, priv->parent_wake_irq, |
367 | brcmstb_gpio_wake_irq_handler, 0, | 479 | brcmstb_gpio_wake_irq_handler, |
368 | "brcmstb-gpio-wake", priv); | 480 | IRQF_SHARED, |
481 | "brcmstb-gpio-wake", priv); | ||
369 | 482 | ||
370 | if (err < 0) { | 483 | if (err < 0) { |
371 | dev_err(dev, "Couldn't request wake IRQ"); | 484 | dev_err(dev, "Couldn't request wake IRQ"); |
372 | return err; | 485 | goto out_free_domain; |
373 | } | 486 | } |
374 | |||
375 | priv->reboot_notifier.notifier_call = | ||
376 | brcmstb_gpio_reboot; | ||
377 | register_reboot_notifier(&priv->reboot_notifier); | ||
378 | priv->can_wake = true; | ||
379 | } | 487 | } |
380 | } | 488 | } |
381 | 489 | ||
382 | if (priv->can_wake) | 490 | priv->irq_chip.name = dev_name(dev); |
383 | bank->irq_chip.irq_set_wake = brcmstb_gpio_irq_set_wake; | 491 | priv->irq_chip.irq_disable = brcmstb_gpio_irq_mask; |
492 | priv->irq_chip.irq_mask = brcmstb_gpio_irq_mask; | ||
493 | priv->irq_chip.irq_unmask = brcmstb_gpio_irq_unmask; | ||
494 | priv->irq_chip.irq_ack = brcmstb_gpio_irq_ack; | ||
495 | priv->irq_chip.irq_set_type = brcmstb_gpio_irq_set_type; | ||
496 | |||
497 | if (priv->parent_wake_irq) | ||
498 | priv->irq_chip.irq_set_wake = brcmstb_gpio_irq_set_wake; | ||
499 | |||
500 | irq_set_chained_handler_and_data(priv->parent_irq, | ||
501 | brcmstb_gpio_irq_handler, priv); | ||
502 | irq_set_status_flags(priv->parent_irq, IRQ_DISABLE_UNLAZY); | ||
503 | |||
504 | return 0; | ||
505 | |||
506 | out_free_domain: | ||
507 | irq_domain_remove(priv->irq_domain); | ||
508 | |||
509 | return err; | ||
510 | } | ||
511 | |||
512 | static void brcmstb_gpio_bank_save(struct brcmstb_gpio_priv *priv, | ||
513 | struct brcmstb_gpio_bank *bank) | ||
514 | { | ||
515 | struct gpio_chip *gc = &bank->gc; | ||
516 | unsigned int i; | ||
517 | |||
518 | for (i = 0; i < GIO_REG_STAT; i++) | ||
519 | bank->saved_regs[i] = gc->read_reg(priv->reg_base + | ||
520 | GIO_BANK_OFF(bank->id, i)); | ||
521 | } | ||
522 | |||
523 | static void brcmstb_gpio_quiesce(struct device *dev, bool save) | ||
524 | { | ||
525 | struct brcmstb_gpio_priv *priv = dev_get_drvdata(dev); | ||
526 | struct brcmstb_gpio_bank *bank; | ||
527 | struct gpio_chip *gc; | ||
528 | u32 imask; | ||
529 | |||
530 | /* disable non-wake interrupt */ | ||
531 | if (priv->parent_irq >= 0) | ||
532 | disable_irq(priv->parent_irq); | ||
533 | |||
534 | list_for_each_entry(bank, &priv->bank_list, node) { | ||
535 | gc = &bank->gc; | ||
536 | |||
537 | if (save) | ||
538 | brcmstb_gpio_bank_save(priv, bank); | ||
539 | |||
540 | /* Unmask GPIOs which have been flagged as wake-up sources */ | ||
541 | if (priv->parent_wake_irq) | ||
542 | imask = bank->wake_active; | ||
543 | else | ||
544 | imask = 0; | ||
545 | gc->write_reg(priv->reg_base + GIO_MASK(bank->id), | ||
546 | imask); | ||
547 | } | ||
548 | } | ||
549 | |||
550 | static void brcmstb_gpio_shutdown(struct platform_device *pdev) | ||
551 | { | ||
552 | /* Enable GPIO for S5 cold boot */ | ||
553 | brcmstb_gpio_quiesce(&pdev->dev, false); | ||
554 | } | ||
555 | |||
556 | #ifdef CONFIG_PM_SLEEP | ||
557 | static void brcmstb_gpio_bank_restore(struct brcmstb_gpio_priv *priv, | ||
558 | struct brcmstb_gpio_bank *bank) | ||
559 | { | ||
560 | struct gpio_chip *gc = &bank->gc; | ||
561 | unsigned int i; | ||
562 | |||
563 | for (i = 0; i < GIO_REG_STAT; i++) | ||
564 | gc->write_reg(priv->reg_base + GIO_BANK_OFF(bank->id, i), | ||
565 | bank->saved_regs[i]); | ||
566 | } | ||
567 | |||
568 | static int brcmstb_gpio_suspend(struct device *dev) | ||
569 | { | ||
570 | brcmstb_gpio_quiesce(dev, true); | ||
571 | return 0; | ||
572 | } | ||
573 | |||
574 | static int brcmstb_gpio_resume(struct device *dev) | ||
575 | { | ||
576 | struct brcmstb_gpio_priv *priv = dev_get_drvdata(dev); | ||
577 | struct brcmstb_gpio_bank *bank; | ||
578 | bool need_wakeup_event = false; | ||
579 | |||
580 | list_for_each_entry(bank, &priv->bank_list, node) { | ||
581 | need_wakeup_event |= !!__brcmstb_gpio_get_active_irqs(bank); | ||
582 | brcmstb_gpio_bank_restore(priv, bank); | ||
583 | } | ||
584 | |||
585 | if (priv->parent_wake_irq && need_wakeup_event) | ||
586 | pm_wakeup_event(dev, 0); | ||
384 | 587 | ||
385 | err = gpiochip_irqchip_add(&bank->gc, &bank->irq_chip, 0, | 588 | /* enable non-wake interrupt */ |
386 | handle_simple_irq, IRQ_TYPE_NONE); | 589 | if (priv->parent_irq >= 0) |
387 | if (err) | 590 | enable_irq(priv->parent_irq); |
388 | return err; | ||
389 | gpiochip_set_chained_irqchip(&bank->gc, &bank->irq_chip, | ||
390 | priv->parent_irq, brcmstb_gpio_irq_handler); | ||
391 | 591 | ||
392 | return 0; | 592 | return 0; |
393 | } | 593 | } |
394 | 594 | ||
595 | #else | ||
596 | #define brcmstb_gpio_suspend NULL | ||
597 | #define brcmstb_gpio_resume NULL | ||
598 | #endif /* CONFIG_PM_SLEEP */ | ||
599 | |||
600 | static const struct dev_pm_ops brcmstb_gpio_pm_ops = { | ||
601 | .suspend_noirq = brcmstb_gpio_suspend, | ||
602 | .resume_noirq = brcmstb_gpio_resume, | ||
603 | }; | ||
604 | |||
395 | static int brcmstb_gpio_probe(struct platform_device *pdev) | 605 | static int brcmstb_gpio_probe(struct platform_device *pdev) |
396 | { | 606 | { |
397 | struct device *dev = &pdev->dev; | 607 | struct device *dev = &pdev->dev; |
@@ -406,6 +616,7 @@ static int brcmstb_gpio_probe(struct platform_device *pdev) | |||
406 | int err; | 616 | int err; |
407 | static int gpio_base; | 617 | static int gpio_base; |
408 | unsigned long flags = 0; | 618 | unsigned long flags = 0; |
619 | bool need_wakeup_event = false; | ||
409 | 620 | ||
410 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | 621 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); |
411 | if (!priv) | 622 | if (!priv) |
@@ -485,16 +696,23 @@ static int brcmstb_gpio_probe(struct platform_device *pdev) | |||
485 | gc->of_node = np; | 696 | gc->of_node = np; |
486 | gc->owner = THIS_MODULE; | 697 | gc->owner = THIS_MODULE; |
487 | gc->label = devm_kasprintf(dev, GFP_KERNEL, "%pOF", dev->of_node); | 698 | gc->label = devm_kasprintf(dev, GFP_KERNEL, "%pOF", dev->of_node); |
699 | if (!gc->label) { | ||
700 | err = -ENOMEM; | ||
701 | goto fail; | ||
702 | } | ||
488 | gc->base = gpio_base; | 703 | gc->base = gpio_base; |
489 | gc->of_gpio_n_cells = 2; | 704 | gc->of_gpio_n_cells = 2; |
490 | gc->of_xlate = brcmstb_gpio_of_xlate; | 705 | gc->of_xlate = brcmstb_gpio_of_xlate; |
491 | /* not all ngpio lines are valid, will use bank width later */ | 706 | /* not all ngpio lines are valid, will use bank width later */ |
492 | gc->ngpio = MAX_GPIO_PER_BANK; | 707 | gc->ngpio = MAX_GPIO_PER_BANK; |
708 | if (priv->parent_irq > 0) | ||
709 | gc->to_irq = brcmstb_gpio_to_irq; | ||
493 | 710 | ||
494 | /* | 711 | /* |
495 | * Mask all interrupts by default, since wakeup interrupts may | 712 | * Mask all interrupts by default, since wakeup interrupts may |
496 | * be retained from S5 cold boot | 713 | * be retained from S5 cold boot |
497 | */ | 714 | */ |
715 | need_wakeup_event |= !!__brcmstb_gpio_get_active_irqs(bank); | ||
498 | gc->write_reg(reg_base + GIO_MASK(bank->id), 0); | 716 | gc->write_reg(reg_base + GIO_MASK(bank->id), 0); |
499 | 717 | ||
500 | err = gpiochip_add_data(gc, bank); | 718 | err = gpiochip_add_data(gc, bank); |
@@ -505,12 +723,6 @@ static int brcmstb_gpio_probe(struct platform_device *pdev) | |||
505 | } | 723 | } |
506 | gpio_base += gc->ngpio; | 724 | gpio_base += gc->ngpio; |
507 | 725 | ||
508 | if (priv->parent_irq > 0) { | ||
509 | err = brcmstb_gpio_irq_setup(pdev, bank); | ||
510 | if (err) | ||
511 | goto fail; | ||
512 | } | ||
513 | |||
514 | dev_dbg(dev, "bank=%d, base=%d, ngpio=%d, width=%d\n", bank->id, | 726 | dev_dbg(dev, "bank=%d, base=%d, ngpio=%d, width=%d\n", bank->id, |
515 | gc->base, gc->ngpio, bank->width); | 727 | gc->base, gc->ngpio, bank->width); |
516 | 728 | ||
@@ -520,9 +732,19 @@ static int brcmstb_gpio_probe(struct platform_device *pdev) | |||
520 | num_banks++; | 732 | num_banks++; |
521 | } | 733 | } |
522 | 734 | ||
735 | priv->num_gpios = gpio_base - priv->gpio_base; | ||
736 | if (priv->parent_irq > 0) { | ||
737 | err = brcmstb_gpio_irq_setup(pdev, priv); | ||
738 | if (err) | ||
739 | goto fail; | ||
740 | } | ||
741 | |||
523 | dev_info(dev, "Registered %d banks (GPIO(s): %d-%d)\n", | 742 | dev_info(dev, "Registered %d banks (GPIO(s): %d-%d)\n", |
524 | num_banks, priv->gpio_base, gpio_base - 1); | 743 | num_banks, priv->gpio_base, gpio_base - 1); |
525 | 744 | ||
745 | if (priv->parent_wake_irq && need_wakeup_event) | ||
746 | pm_wakeup_event(dev, 0); | ||
747 | |||
526 | return 0; | 748 | return 0; |
527 | 749 | ||
528 | fail: | 750 | fail: |
@@ -541,9 +763,11 @@ static struct platform_driver brcmstb_gpio_driver = { | |||
541 | .driver = { | 763 | .driver = { |
542 | .name = "brcmstb-gpio", | 764 | .name = "brcmstb-gpio", |
543 | .of_match_table = brcmstb_gpio_of_match, | 765 | .of_match_table = brcmstb_gpio_of_match, |
766 | .pm = &brcmstb_gpio_pm_ops, | ||
544 | }, | 767 | }, |
545 | .probe = brcmstb_gpio_probe, | 768 | .probe = brcmstb_gpio_probe, |
546 | .remove = brcmstb_gpio_remove, | 769 | .remove = brcmstb_gpio_remove, |
770 | .shutdown = brcmstb_gpio_shutdown, | ||
547 | }; | 771 | }; |
548 | module_platform_driver(brcmstb_gpio_driver); | 772 | module_platform_driver(brcmstb_gpio_driver); |
549 | 773 | ||