mfd: max14577: Fix IRQ handling after resume if this is not a wakeup source
[deliverable/linux.git] / drivers / mfd / pm8921-core.c
CommitLineData
cbdb53e1
AD
1/*
2 * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#define pr_fmt(fmt) "%s: " fmt, __func__
15
16#include <linux/kernel.h>
bc866fc7 17#include <linux/interrupt.h>
cced3548 18#include <linux/irqchip/chained_irq.h>
bc866fc7 19#include <linux/irq.h>
dc1a95cc 20#include <linux/irqdomain.h>
ef310f4b 21#include <linux/module.h>
cbdb53e1
AD
22#include <linux/platform_device.h>
23#include <linux/slab.h>
c013f0a5 24#include <linux/err.h>
ce44bf5b 25#include <linux/ssbi.h>
e7b81fca 26#include <linux/regmap.h>
dc1a95cc 27#include <linux/of_platform.h>
cbdb53e1 28#include <linux/mfd/core.h>
cbdb53e1 29#include <linux/mfd/pm8xxx/core.h>
bc866fc7
SB
30
31#define SSBI_REG_ADDR_IRQ_BASE 0x1BB
32
33#define SSBI_REG_ADDR_IRQ_ROOT (SSBI_REG_ADDR_IRQ_BASE + 0)
34#define SSBI_REG_ADDR_IRQ_M_STATUS1 (SSBI_REG_ADDR_IRQ_BASE + 1)
35#define SSBI_REG_ADDR_IRQ_M_STATUS2 (SSBI_REG_ADDR_IRQ_BASE + 2)
36#define SSBI_REG_ADDR_IRQ_M_STATUS3 (SSBI_REG_ADDR_IRQ_BASE + 3)
37#define SSBI_REG_ADDR_IRQ_M_STATUS4 (SSBI_REG_ADDR_IRQ_BASE + 4)
38#define SSBI_REG_ADDR_IRQ_BLK_SEL (SSBI_REG_ADDR_IRQ_BASE + 5)
39#define SSBI_REG_ADDR_IRQ_IT_STATUS (SSBI_REG_ADDR_IRQ_BASE + 6)
40#define SSBI_REG_ADDR_IRQ_CONFIG (SSBI_REG_ADDR_IRQ_BASE + 7)
41#define SSBI_REG_ADDR_IRQ_RT_STATUS (SSBI_REG_ADDR_IRQ_BASE + 8)
42
43#define PM_IRQF_LVL_SEL 0x01 /* level select */
44#define PM_IRQF_MASK_FE 0x02 /* mask falling edge */
45#define PM_IRQF_MASK_RE 0x04 /* mask rising edge */
46#define PM_IRQF_CLR 0x08 /* clear interrupt */
47#define PM_IRQF_BITS_MASK 0x70
48#define PM_IRQF_BITS_SHIFT 4
49#define PM_IRQF_WRITE 0x80
50
51#define PM_IRQF_MASK_ALL (PM_IRQF_MASK_FE | \
52 PM_IRQF_MASK_RE)
cbdb53e1
AD
53
54#define REG_HWREV 0x002 /* PMIC4 revision */
55#define REG_HWREV_2 0x0E8 /* PMIC4 revision 2 */
56
dc1a95cc
SB
57#define PM8921_NR_IRQS 256
58
bc866fc7
SB
59struct pm_irq_chip {
60 struct device *dev;
e7b81fca 61 struct regmap *regmap;
bc866fc7 62 spinlock_t pm_irq_lock;
dc1a95cc 63 struct irq_domain *irqdomain;
bc866fc7
SB
64 unsigned int num_irqs;
65 unsigned int num_blocks;
66 unsigned int num_masters;
67 u8 config[0];
68};
69
cbdb53e1
AD
70struct pm8921 {
71 struct device *dev;
c013f0a5 72 struct pm_irq_chip *irq_chip;
cbdb53e1
AD
73};
74
e7b81fca
SB
75static int pm8xxx_read_block_irq(struct pm_irq_chip *chip, unsigned int bp,
76 unsigned int *ip)
bc866fc7
SB
77{
78 int rc;
79
80 spin_lock(&chip->pm_irq_lock);
e7b81fca 81 rc = regmap_write(chip->regmap, SSBI_REG_ADDR_IRQ_BLK_SEL, bp);
bc866fc7
SB
82 if (rc) {
83 pr_err("Failed Selecting Block %d rc=%d\n", bp, rc);
84 goto bail;
85 }
86
e7b81fca 87 rc = regmap_read(chip->regmap, SSBI_REG_ADDR_IRQ_IT_STATUS, ip);
bc866fc7
SB
88 if (rc)
89 pr_err("Failed Reading Status rc=%d\n", rc);
90bail:
91 spin_unlock(&chip->pm_irq_lock);
92 return rc;
93}
94
e7b81fca
SB
95static int
96pm8xxx_config_irq(struct pm_irq_chip *chip, unsigned int bp, unsigned int cp)
bc866fc7
SB
97{
98 int rc;
99
100 spin_lock(&chip->pm_irq_lock);
e7b81fca 101 rc = regmap_write(chip->regmap, SSBI_REG_ADDR_IRQ_BLK_SEL, bp);
bc866fc7
SB
102 if (rc) {
103 pr_err("Failed Selecting Block %d rc=%d\n", bp, rc);
104 goto bail;
105 }
106
107 cp |= PM_IRQF_WRITE;
e7b81fca 108 rc = regmap_write(chip->regmap, SSBI_REG_ADDR_IRQ_CONFIG, cp);
bc866fc7
SB
109 if (rc)
110 pr_err("Failed Configuring IRQ rc=%d\n", rc);
111bail:
112 spin_unlock(&chip->pm_irq_lock);
113 return rc;
114}
115
116static int pm8xxx_irq_block_handler(struct pm_irq_chip *chip, int block)
117{
118 int pmirq, irq, i, ret = 0;
e7b81fca 119 unsigned int bits;
bc866fc7
SB
120
121 ret = pm8xxx_read_block_irq(chip, block, &bits);
122 if (ret) {
123 pr_err("Failed reading %d block ret=%d", block, ret);
124 return ret;
125 }
126 if (!bits) {
127 pr_err("block bit set in master but no irqs: %d", block);
128 return 0;
129 }
130
131 /* Check IRQ bits */
132 for (i = 0; i < 8; i++) {
133 if (bits & (1 << i)) {
134 pmirq = block * 8 + i;
dc1a95cc 135 irq = irq_find_mapping(chip->irqdomain, pmirq);
bc866fc7
SB
136 generic_handle_irq(irq);
137 }
138 }
139 return 0;
140}
141
142static int pm8xxx_irq_master_handler(struct pm_irq_chip *chip, int master)
143{
e7b81fca 144 unsigned int blockbits;
bc866fc7
SB
145 int block_number, i, ret = 0;
146
e7b81fca
SB
147 ret = regmap_read(chip->regmap, SSBI_REG_ADDR_IRQ_M_STATUS1 + master,
148 &blockbits);
bc866fc7
SB
149 if (ret) {
150 pr_err("Failed to read master %d ret=%d\n", master, ret);
151 return ret;
152 }
153 if (!blockbits) {
154 pr_err("master bit set in root but no blocks: %d", master);
155 return 0;
156 }
157
158 for (i = 0; i < 8; i++)
159 if (blockbits & (1 << i)) {
160 block_number = master * 8 + i; /* block # */
161 ret |= pm8xxx_irq_block_handler(chip, block_number);
162 }
163 return ret;
164}
165
166static void pm8xxx_irq_handler(unsigned int irq, struct irq_desc *desc)
167{
168 struct pm_irq_chip *chip = irq_desc_get_handler_data(desc);
169 struct irq_chip *irq_chip = irq_desc_get_chip(desc);
e7b81fca 170 unsigned int root;
bc866fc7
SB
171 int i, ret, masters = 0;
172
cced3548
SB
173 chained_irq_enter(irq_chip, desc);
174
e7b81fca 175 ret = regmap_read(chip->regmap, SSBI_REG_ADDR_IRQ_ROOT, &root);
bc866fc7
SB
176 if (ret) {
177 pr_err("Can't read root status ret=%d\n", ret);
178 return;
179 }
180
181 /* on pm8xxx series masters start from bit 1 of the root */
182 masters = root >> 1;
183
184 /* Read allowed masters for blocks. */
185 for (i = 0; i < chip->num_masters; i++)
186 if (masters & (1 << i))
187 pm8xxx_irq_master_handler(chip, i);
188
cced3548 189 chained_irq_exit(irq_chip, desc);
bc866fc7
SB
190}
191
192static void pm8xxx_irq_mask_ack(struct irq_data *d)
193{
194 struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
dc1a95cc
SB
195 unsigned int pmirq = irqd_to_hwirq(d);
196 int irq_bit;
bc866fc7
SB
197 u8 block, config;
198
199 block = pmirq / 8;
bc866fc7
SB
200 irq_bit = pmirq % 8;
201
202 config = chip->config[pmirq] | PM_IRQF_MASK_ALL | PM_IRQF_CLR;
203 pm8xxx_config_irq(chip, block, config);
204}
205
206static void pm8xxx_irq_unmask(struct irq_data *d)
207{
208 struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
dc1a95cc
SB
209 unsigned int pmirq = irqd_to_hwirq(d);
210 int irq_bit;
bc866fc7
SB
211 u8 block, config;
212
213 block = pmirq / 8;
bc866fc7
SB
214 irq_bit = pmirq % 8;
215
216 config = chip->config[pmirq];
217 pm8xxx_config_irq(chip, block, config);
218}
219
220static int pm8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)
221{
222 struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
dc1a95cc
SB
223 unsigned int pmirq = irqd_to_hwirq(d);
224 int irq_bit;
bc866fc7
SB
225 u8 block, config;
226
227 block = pmirq / 8;
bc866fc7
SB
228 irq_bit = pmirq % 8;
229
230 chip->config[pmirq] = (irq_bit << PM_IRQF_BITS_SHIFT)
231 | PM_IRQF_MASK_ALL;
232 if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
233 if (flow_type & IRQF_TRIGGER_RISING)
234 chip->config[pmirq] &= ~PM_IRQF_MASK_RE;
235 if (flow_type & IRQF_TRIGGER_FALLING)
236 chip->config[pmirq] &= ~PM_IRQF_MASK_FE;
237 } else {
238 chip->config[pmirq] |= PM_IRQF_LVL_SEL;
239
240 if (flow_type & IRQF_TRIGGER_HIGH)
241 chip->config[pmirq] &= ~PM_IRQF_MASK_RE;
242 else
243 chip->config[pmirq] &= ~PM_IRQF_MASK_FE;
244 }
245
246 config = chip->config[pmirq] | PM_IRQF_CLR;
247 return pm8xxx_config_irq(chip, block, config);
248}
249
bc866fc7
SB
250static struct irq_chip pm8xxx_irq_chip = {
251 .name = "pm8xxx",
252 .irq_mask_ack = pm8xxx_irq_mask_ack,
253 .irq_unmask = pm8xxx_irq_unmask,
254 .irq_set_type = pm8xxx_irq_set_type,
d2d24ad1 255 .flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE,
bc866fc7
SB
256};
257
258/**
259 * pm8xxx_get_irq_stat - get the status of the irq line
260 * @chip: pointer to identify a pmic irq controller
261 * @irq: the irq number
262 *
263 * The pm8xxx gpio and mpp rely on the interrupt block to read
264 * the values on their pins. This function is to facilitate reading
265 * the status of a gpio or an mpp line. The caller has to convert the
266 * gpio number to irq number.
267 *
268 * RETURNS:
269 * an int indicating the value read on that line
270 */
271static int pm8xxx_get_irq_stat(struct pm_irq_chip *chip, int irq)
272{
273 int pmirq, rc;
e7b81fca 274 unsigned int block, bits, bit;
bc866fc7 275 unsigned long flags;
dc1a95cc 276 struct irq_data *irq_data = irq_get_irq_data(irq);
bc866fc7 277
dc1a95cc 278 pmirq = irq_data->hwirq;
bc866fc7
SB
279
280 block = pmirq / 8;
281 bit = pmirq % 8;
282
283 spin_lock_irqsave(&chip->pm_irq_lock, flags);
284
e7b81fca 285 rc = regmap_write(chip->regmap, SSBI_REG_ADDR_IRQ_BLK_SEL, block);
bc866fc7
SB
286 if (rc) {
287 pr_err("Failed Selecting block irq=%d pmirq=%d blk=%d rc=%d\n",
288 irq, pmirq, block, rc);
289 goto bail_out;
290 }
291
e7b81fca 292 rc = regmap_read(chip->regmap, SSBI_REG_ADDR_IRQ_RT_STATUS, &bits);
bc866fc7
SB
293 if (rc) {
294 pr_err("Failed Configuring irq=%d pmirq=%d blk=%d rc=%d\n",
295 irq, pmirq, block, rc);
296 goto bail_out;
297 }
298
299 rc = (bits & (1 << bit)) ? 1 : 0;
300
301bail_out:
302 spin_unlock_irqrestore(&chip->pm_irq_lock, flags);
303
304 return rc;
305}
306
dc1a95cc
SB
307static int pm8xxx_irq_domain_map(struct irq_domain *d, unsigned int irq,
308 irq_hw_number_t hwirq)
309{
310 struct pm_irq_chip *chip = d->host_data;
bc866fc7 311
dc1a95cc
SB
312 irq_set_chip_and_handler(irq, &pm8xxx_irq_chip, handle_level_irq);
313 irq_set_chip_data(irq, chip);
bc866fc7 314#ifdef CONFIG_ARM
dc1a95cc 315 set_irq_flags(irq, IRQF_VALID);
bc866fc7 316#else
dc1a95cc 317 irq_set_noprobe(irq);
bc866fc7 318#endif
bc866fc7
SB
319 return 0;
320}
321
dc1a95cc
SB
322static const struct irq_domain_ops pm8xxx_irq_domain_ops = {
323 .xlate = irq_domain_xlate_twocell,
324 .map = pm8xxx_irq_domain_map,
325};
326
cbdb53e1
AD
327static int pm8921_readb(const struct device *dev, u16 addr, u8 *val)
328{
329 const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev);
330 const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data;
331
ce44bf5b 332 return ssbi_read(pmic->dev->parent, addr, val, 1);
cbdb53e1
AD
333}
334
335static int pm8921_writeb(const struct device *dev, u16 addr, u8 val)
336{
337 const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev);
338 const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data;
339
ce44bf5b 340 return ssbi_write(pmic->dev->parent, addr, &val, 1);
cbdb53e1
AD
341}
342
343static int pm8921_read_buf(const struct device *dev, u16 addr, u8 *buf,
344 int cnt)
345{
346 const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev);
347 const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data;
348
ce44bf5b 349 return ssbi_read(pmic->dev->parent, addr, buf, cnt);
cbdb53e1
AD
350}
351
352static int pm8921_write_buf(const struct device *dev, u16 addr, u8 *buf,
353 int cnt)
354{
355 const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev);
356 const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data;
357
ce44bf5b 358 return ssbi_write(pmic->dev->parent, addr, buf, cnt);
cbdb53e1
AD
359}
360
c013f0a5
AD
361static int pm8921_read_irq_stat(const struct device *dev, int irq)
362{
363 const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev);
364 const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data;
365
366 return pm8xxx_get_irq_stat(pmic->irq_chip, irq);
367}
368
cbdb53e1
AD
369static struct pm8xxx_drvdata pm8921_drvdata = {
370 .pmic_readb = pm8921_readb,
371 .pmic_writeb = pm8921_writeb,
372 .pmic_read_buf = pm8921_read_buf,
373 .pmic_write_buf = pm8921_write_buf,
c013f0a5 374 .pmic_read_irq_stat = pm8921_read_irq_stat,
cbdb53e1
AD
375};
376
e7b81fca
SB
377static const struct regmap_config ssbi_regmap_config = {
378 .reg_bits = 16,
379 .val_bits = 8,
380 .max_register = 0x3ff,
381 .fast_io = true,
382 .reg_read = ssbi_reg_read,
383 .reg_write = ssbi_reg_write
384};
385
c5865a53
SB
386static const struct of_device_id pm8921_id_table[] = {
387 { .compatible = "qcom,pm8058", },
388 { .compatible = "qcom,pm8921", },
389 { }
390};
391MODULE_DEVICE_TABLE(of, pm8921_id_table);
392
f791be49 393static int pm8921_probe(struct platform_device *pdev)
cbdb53e1 394{
cbdb53e1 395 struct pm8921 *pmic;
e7b81fca 396 struct regmap *regmap;
202f7680 397 int irq, rc;
e7b81fca 398 unsigned int val;
c013f0a5 399 u32 rev;
dc1a95cc
SB
400 struct pm_irq_chip *chip;
401 unsigned int nirqs = PM8921_NR_IRQS;
cbdb53e1 402
dc1a95cc
SB
403 irq = platform_get_irq(pdev, 0);
404 if (irq < 0)
405 return irq;
cbdb53e1 406
b2cdcfac 407 pmic = devm_kzalloc(&pdev->dev, sizeof(struct pm8921), GFP_KERNEL);
cbdb53e1
AD
408 if (!pmic) {
409 pr_err("Cannot alloc pm8921 struct\n");
410 return -ENOMEM;
411 }
412
e7b81fca
SB
413 regmap = devm_regmap_init(&pdev->dev, NULL, pdev->dev.parent,
414 &ssbi_regmap_config);
415 if (IS_ERR(regmap))
416 return PTR_ERR(regmap);
417
cbdb53e1 418 /* Read PMIC chip revision */
e7b81fca 419 rc = regmap_read(regmap, REG_HWREV, &val);
cbdb53e1
AD
420 if (rc) {
421 pr_err("Failed to read hw rev reg %d:rc=%d\n", REG_HWREV, rc);
b2cdcfac 422 return rc;
cbdb53e1
AD
423 }
424 pr_info("PMIC revision 1: %02X\n", val);
c013f0a5 425 rev = val;
cbdb53e1
AD
426
427 /* Read PMIC chip revision 2 */
e7b81fca 428 rc = regmap_read(regmap, REG_HWREV_2, &val);
cbdb53e1
AD
429 if (rc) {
430 pr_err("Failed to read hw rev 2 reg %d:rc=%d\n",
431 REG_HWREV_2, rc);
b2cdcfac 432 return rc;
cbdb53e1
AD
433 }
434 pr_info("PMIC revision 2: %02X\n", val);
c013f0a5 435 rev |= val << BITS_PER_BYTE;
cbdb53e1
AD
436
437 pmic->dev = &pdev->dev;
438 pm8921_drvdata.pm_chip_data = pmic;
439 platform_set_drvdata(pdev, &pm8921_drvdata);
440
dc1a95cc
SB
441 chip = devm_kzalloc(&pdev->dev, sizeof(*chip) +
442 sizeof(chip->config[0]) * nirqs,
443 GFP_KERNEL);
444 if (!chip)
445 return -ENOMEM;
446
447 pmic->irq_chip = chip;
448 chip->dev = &pdev->dev;
e7b81fca 449 chip->regmap = regmap;
dc1a95cc
SB
450 chip->num_irqs = nirqs;
451 chip->num_blocks = DIV_ROUND_UP(chip->num_irqs, 8);
452 chip->num_masters = DIV_ROUND_UP(chip->num_blocks, 8);
453 spin_lock_init(&chip->pm_irq_lock);
454
455 chip->irqdomain = irq_domain_add_linear(pdev->dev.of_node, nirqs,
456 &pm8xxx_irq_domain_ops,
457 chip);
458 if (!chip->irqdomain)
459 return -ENODEV;
460
461 irq_set_handler_data(irq, chip);
462 irq_set_chained_handler(irq, pm8xxx_irq_handler);
463 irq_set_irq_wake(irq, 1);
464
465 rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
c013f0a5 466 if (rc) {
dc1a95cc
SB
467 irq_set_chained_handler(irq, NULL);
468 irq_set_handler_data(irq, NULL);
469 irq_domain_remove(chip->irqdomain);
c013f0a5
AD
470 }
471
dc1a95cc
SB
472 return rc;
473}
c013f0a5 474
dc1a95cc
SB
475static int pm8921_remove_child(struct device *dev, void *unused)
476{
477 platform_device_unregister(to_platform_device(dev));
cbdb53e1 478 return 0;
cbdb53e1
AD
479}
480
4740f73f 481static int pm8921_remove(struct platform_device *pdev)
cbdb53e1 482{
dc1a95cc
SB
483 int irq = platform_get_irq(pdev, 0);
484 struct pm8921 *pmic = pm8921_drvdata.pm_chip_data;
485 struct pm_irq_chip *chip = pmic->irq_chip;
486
487 device_for_each_child(&pdev->dev, NULL, pm8921_remove_child);
488 irq_set_chained_handler(irq, NULL);
489 irq_set_handler_data(irq, NULL);
490 irq_domain_remove(chip->irqdomain);
cbdb53e1
AD
491
492 return 0;
493}
494
495static struct platform_driver pm8921_driver = {
496 .probe = pm8921_probe,
84449216 497 .remove = pm8921_remove,
cbdb53e1
AD
498 .driver = {
499 .name = "pm8921-core",
500 .owner = THIS_MODULE,
c5865a53 501 .of_match_table = pm8921_id_table,
cbdb53e1
AD
502 },
503};
504
505static int __init pm8921_init(void)
506{
507 return platform_driver_register(&pm8921_driver);
508}
509subsys_initcall(pm8921_init);
510
511static void __exit pm8921_exit(void)
512{
513 platform_driver_unregister(&pm8921_driver);
514}
515module_exit(pm8921_exit);
516
517MODULE_LICENSE("GPL v2");
518MODULE_DESCRIPTION("PMIC 8921 core driver");
519MODULE_VERSION("1.0");
520MODULE_ALIAS("platform:pm8921-core");
This page took 0.224067 seconds and 5 git commands to generate.