mfd: pm8921: Drop irq_set_lockdep_class() code
[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
250static int pm8xxx_irq_set_wake(struct irq_data *d, unsigned int on)
251{
252 return 0;
253}
254
255static struct irq_chip pm8xxx_irq_chip = {
256 .name = "pm8xxx",
257 .irq_mask_ack = pm8xxx_irq_mask_ack,
258 .irq_unmask = pm8xxx_irq_unmask,
259 .irq_set_type = pm8xxx_irq_set_type,
260 .irq_set_wake = pm8xxx_irq_set_wake,
261 .flags = IRQCHIP_MASK_ON_SUSPEND,
262};
263
264/**
265 * pm8xxx_get_irq_stat - get the status of the irq line
266 * @chip: pointer to identify a pmic irq controller
267 * @irq: the irq number
268 *
269 * The pm8xxx gpio and mpp rely on the interrupt block to read
270 * the values on their pins. This function is to facilitate reading
271 * the status of a gpio or an mpp line. The caller has to convert the
272 * gpio number to irq number.
273 *
274 * RETURNS:
275 * an int indicating the value read on that line
276 */
277static int pm8xxx_get_irq_stat(struct pm_irq_chip *chip, int irq)
278{
279 int pmirq, rc;
e7b81fca 280 unsigned int block, bits, bit;
bc866fc7 281 unsigned long flags;
dc1a95cc 282 struct irq_data *irq_data = irq_get_irq_data(irq);
bc866fc7 283
dc1a95cc 284 pmirq = irq_data->hwirq;
bc866fc7
SB
285
286 block = pmirq / 8;
287 bit = pmirq % 8;
288
289 spin_lock_irqsave(&chip->pm_irq_lock, flags);
290
e7b81fca 291 rc = regmap_write(chip->regmap, SSBI_REG_ADDR_IRQ_BLK_SEL, block);
bc866fc7
SB
292 if (rc) {
293 pr_err("Failed Selecting block irq=%d pmirq=%d blk=%d rc=%d\n",
294 irq, pmirq, block, rc);
295 goto bail_out;
296 }
297
e7b81fca 298 rc = regmap_read(chip->regmap, SSBI_REG_ADDR_IRQ_RT_STATUS, &bits);
bc866fc7
SB
299 if (rc) {
300 pr_err("Failed Configuring irq=%d pmirq=%d blk=%d rc=%d\n",
301 irq, pmirq, block, rc);
302 goto bail_out;
303 }
304
305 rc = (bits & (1 << bit)) ? 1 : 0;
306
307bail_out:
308 spin_unlock_irqrestore(&chip->pm_irq_lock, flags);
309
310 return rc;
311}
312
dc1a95cc
SB
313static int pm8xxx_irq_domain_map(struct irq_domain *d, unsigned int irq,
314 irq_hw_number_t hwirq)
315{
316 struct pm_irq_chip *chip = d->host_data;
bc866fc7 317
dc1a95cc
SB
318 irq_set_chip_and_handler(irq, &pm8xxx_irq_chip, handle_level_irq);
319 irq_set_chip_data(irq, chip);
bc866fc7 320#ifdef CONFIG_ARM
dc1a95cc 321 set_irq_flags(irq, IRQF_VALID);
bc866fc7 322#else
dc1a95cc 323 irq_set_noprobe(irq);
bc866fc7 324#endif
bc866fc7
SB
325 return 0;
326}
327
dc1a95cc
SB
328static const struct irq_domain_ops pm8xxx_irq_domain_ops = {
329 .xlate = irq_domain_xlate_twocell,
330 .map = pm8xxx_irq_domain_map,
331};
332
cbdb53e1
AD
333static int pm8921_readb(const struct device *dev, u16 addr, u8 *val)
334{
335 const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev);
336 const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data;
337
ce44bf5b 338 return ssbi_read(pmic->dev->parent, addr, val, 1);
cbdb53e1
AD
339}
340
341static int pm8921_writeb(const struct device *dev, u16 addr, u8 val)
342{
343 const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev);
344 const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data;
345
ce44bf5b 346 return ssbi_write(pmic->dev->parent, addr, &val, 1);
cbdb53e1
AD
347}
348
349static int pm8921_read_buf(const struct device *dev, u16 addr, u8 *buf,
350 int cnt)
351{
352 const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev);
353 const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data;
354
ce44bf5b 355 return ssbi_read(pmic->dev->parent, addr, buf, cnt);
cbdb53e1
AD
356}
357
358static int pm8921_write_buf(const struct device *dev, u16 addr, u8 *buf,
359 int cnt)
360{
361 const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev);
362 const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data;
363
ce44bf5b 364 return ssbi_write(pmic->dev->parent, addr, buf, cnt);
cbdb53e1
AD
365}
366
c013f0a5
AD
367static int pm8921_read_irq_stat(const struct device *dev, int irq)
368{
369 const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev);
370 const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data;
371
372 return pm8xxx_get_irq_stat(pmic->irq_chip, irq);
373}
374
cbdb53e1
AD
375static struct pm8xxx_drvdata pm8921_drvdata = {
376 .pmic_readb = pm8921_readb,
377 .pmic_writeb = pm8921_writeb,
378 .pmic_read_buf = pm8921_read_buf,
379 .pmic_write_buf = pm8921_write_buf,
c013f0a5 380 .pmic_read_irq_stat = pm8921_read_irq_stat,
cbdb53e1
AD
381};
382
e7b81fca
SB
383static const struct regmap_config ssbi_regmap_config = {
384 .reg_bits = 16,
385 .val_bits = 8,
386 .max_register = 0x3ff,
387 .fast_io = true,
388 .reg_read = ssbi_reg_read,
389 .reg_write = ssbi_reg_write
390};
391
c5865a53
SB
392static const struct of_device_id pm8921_id_table[] = {
393 { .compatible = "qcom,pm8058", },
394 { .compatible = "qcom,pm8921", },
395 { }
396};
397MODULE_DEVICE_TABLE(of, pm8921_id_table);
398
f791be49 399static int pm8921_probe(struct platform_device *pdev)
cbdb53e1 400{
cbdb53e1 401 struct pm8921 *pmic;
e7b81fca 402 struct regmap *regmap;
cbdb53e1 403 int rc;
e7b81fca 404 unsigned int val;
dc1a95cc 405 unsigned int irq;
c013f0a5 406 u32 rev;
dc1a95cc
SB
407 struct pm_irq_chip *chip;
408 unsigned int nirqs = PM8921_NR_IRQS;
cbdb53e1 409
dc1a95cc
SB
410 irq = platform_get_irq(pdev, 0);
411 if (irq < 0)
412 return irq;
cbdb53e1 413
b2cdcfac 414 pmic = devm_kzalloc(&pdev->dev, sizeof(struct pm8921), GFP_KERNEL);
cbdb53e1
AD
415 if (!pmic) {
416 pr_err("Cannot alloc pm8921 struct\n");
417 return -ENOMEM;
418 }
419
e7b81fca
SB
420 regmap = devm_regmap_init(&pdev->dev, NULL, pdev->dev.parent,
421 &ssbi_regmap_config);
422 if (IS_ERR(regmap))
423 return PTR_ERR(regmap);
424
cbdb53e1 425 /* Read PMIC chip revision */
e7b81fca 426 rc = regmap_read(regmap, REG_HWREV, &val);
cbdb53e1
AD
427 if (rc) {
428 pr_err("Failed to read hw rev reg %d:rc=%d\n", REG_HWREV, rc);
b2cdcfac 429 return rc;
cbdb53e1
AD
430 }
431 pr_info("PMIC revision 1: %02X\n", val);
c013f0a5 432 rev = val;
cbdb53e1
AD
433
434 /* Read PMIC chip revision 2 */
e7b81fca 435 rc = regmap_read(regmap, REG_HWREV_2, &val);
cbdb53e1
AD
436 if (rc) {
437 pr_err("Failed to read hw rev 2 reg %d:rc=%d\n",
438 REG_HWREV_2, rc);
b2cdcfac 439 return rc;
cbdb53e1
AD
440 }
441 pr_info("PMIC revision 2: %02X\n", val);
c013f0a5 442 rev |= val << BITS_PER_BYTE;
cbdb53e1
AD
443
444 pmic->dev = &pdev->dev;
445 pm8921_drvdata.pm_chip_data = pmic;
446 platform_set_drvdata(pdev, &pm8921_drvdata);
447
dc1a95cc
SB
448 chip = devm_kzalloc(&pdev->dev, sizeof(*chip) +
449 sizeof(chip->config[0]) * nirqs,
450 GFP_KERNEL);
451 if (!chip)
452 return -ENOMEM;
453
454 pmic->irq_chip = chip;
455 chip->dev = &pdev->dev;
e7b81fca 456 chip->regmap = regmap;
dc1a95cc
SB
457 chip->num_irqs = nirqs;
458 chip->num_blocks = DIV_ROUND_UP(chip->num_irqs, 8);
459 chip->num_masters = DIV_ROUND_UP(chip->num_blocks, 8);
460 spin_lock_init(&chip->pm_irq_lock);
461
462 chip->irqdomain = irq_domain_add_linear(pdev->dev.of_node, nirqs,
463 &pm8xxx_irq_domain_ops,
464 chip);
465 if (!chip->irqdomain)
466 return -ENODEV;
467
468 irq_set_handler_data(irq, chip);
469 irq_set_chained_handler(irq, pm8xxx_irq_handler);
470 irq_set_irq_wake(irq, 1);
471
472 rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
c013f0a5 473 if (rc) {
dc1a95cc
SB
474 irq_set_chained_handler(irq, NULL);
475 irq_set_handler_data(irq, NULL);
476 irq_domain_remove(chip->irqdomain);
c013f0a5
AD
477 }
478
dc1a95cc
SB
479 return rc;
480}
c013f0a5 481
dc1a95cc
SB
482static int pm8921_remove_child(struct device *dev, void *unused)
483{
484 platform_device_unregister(to_platform_device(dev));
cbdb53e1 485 return 0;
cbdb53e1
AD
486}
487
4740f73f 488static int pm8921_remove(struct platform_device *pdev)
cbdb53e1 489{
dc1a95cc
SB
490 int irq = platform_get_irq(pdev, 0);
491 struct pm8921 *pmic = pm8921_drvdata.pm_chip_data;
492 struct pm_irq_chip *chip = pmic->irq_chip;
493
494 device_for_each_child(&pdev->dev, NULL, pm8921_remove_child);
495 irq_set_chained_handler(irq, NULL);
496 irq_set_handler_data(irq, NULL);
497 irq_domain_remove(chip->irqdomain);
cbdb53e1
AD
498
499 return 0;
500}
501
502static struct platform_driver pm8921_driver = {
503 .probe = pm8921_probe,
84449216 504 .remove = pm8921_remove,
cbdb53e1
AD
505 .driver = {
506 .name = "pm8921-core",
507 .owner = THIS_MODULE,
c5865a53 508 .of_match_table = pm8921_id_table,
cbdb53e1
AD
509 },
510};
511
512static int __init pm8921_init(void)
513{
514 return platform_driver_register(&pm8921_driver);
515}
516subsys_initcall(pm8921_init);
517
518static void __exit pm8921_exit(void)
519{
520 platform_driver_unregister(&pm8921_driver);
521}
522module_exit(pm8921_exit);
523
524MODULE_LICENSE("GPL v2");
525MODULE_DESCRIPTION("PMIC 8921 core driver");
526MODULE_VERSION("1.0");
527MODULE_ALIAS("platform:pm8921-core");
This page took 0.201845 seconds and 5 git commands to generate.