aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Vasut <marek.vasut@gmail.com>2018-09-18 08:23:40 -0400
committerSimon Horman <horms+renesas@verge.net.au>2018-09-19 05:11:46 -0400
commit6d14d4d313d09dabdb06b4a9f4e5fe4305051e9b (patch)
tree13d45c09227e338e766ed50c6e661d3b95df11ed
parentabf3bf537d298db18ad929ceb71c0353d6794f42 (diff)
ARM: shmobile: Rework the PMIC IRQ line quirk
Rather than hard-coding the quirk topology, which stopped scaling, parse the information from DT. The code looks for all compatible PMICs -- da9063 and da9210 -- and checks if their IRQ line is tied to the same pin. If so, the code sends a matching sequence to the PMIC to deassert the IRQ. Signed-off-by: Marek Vasut <marek.vasut+renesas@gmail.com> Acked-by: Wolfram Sang <wsa+renesas@sang-engineering.com> Tested-by: Geert Uytterhoeven <geert+renesas@glider.be> (on Koelsch) Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
-rw-r--r--arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c139
1 files changed, 110 insertions, 29 deletions
diff --git a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
index 21ebc7678ffd..8e50daa99151 100644
--- a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
+++ b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
@@ -23,11 +23,12 @@
23#include <linux/i2c.h> 23#include <linux/i2c.h>
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/io.h> 25#include <linux/io.h>
26#include <linux/list.h>
26#include <linux/notifier.h> 27#include <linux/notifier.h>
27#include <linux/of.h> 28#include <linux/of.h>
29#include <linux/of_irq.h>
28#include <linux/mfd/da9063/registers.h> 30#include <linux/mfd/da9063/registers.h>
29 31
30
31#define IRQC_BASE 0xe61c0000 32#define IRQC_BASE 0xe61c0000
32#define IRQC_MONITOR 0x104 /* IRQn Signal Level Monitor Register */ 33#define IRQC_MONITOR 0x104 /* IRQn Signal Level Monitor Register */
33 34
@@ -36,34 +37,45 @@
36/* start of DA9210 System Control and Event Registers */ 37/* start of DA9210 System Control and Event Registers */
37#define DA9210_REG_MASK_A 0x54 38#define DA9210_REG_MASK_A 0x54
38 39
40struct regulator_quirk {
41 struct list_head list;
42 const struct of_device_id *id;
43 struct of_phandle_args irq_args;
44 struct i2c_msg i2c_msg;
45 bool shared; /* IRQ line is shared */
46};
47
48static LIST_HEAD(quirk_list);
39static void __iomem *irqc; 49static void __iomem *irqc;
40 50
41/* first byte sets the memory pointer, following are consecutive reg values */ 51/* first byte sets the memory pointer, following are consecutive reg values */
42static u8 da9063_irq_clr[] = { DA9063_REG_IRQ_MASK_A, 0xff, 0xff, 0xff, 0xff }; 52static u8 da9063_irq_clr[] = { DA9063_REG_IRQ_MASK_A, 0xff, 0xff, 0xff, 0xff };
43static u8 da9210_irq_clr[] = { DA9210_REG_MASK_A, 0xff, 0xff }; 53static u8 da9210_irq_clr[] = { DA9210_REG_MASK_A, 0xff, 0xff };
44 54
45static struct i2c_msg da9xxx_msgs[3] = { 55static struct i2c_msg da9063_msg = {
46 { 56 .len = ARRAY_SIZE(da9063_irq_clr),
47 .addr = 0x58, 57 .buf = da9063_irq_clr,
48 .len = ARRAY_SIZE(da9063_irq_clr), 58};
49 .buf = da9063_irq_clr, 59
50 }, { 60static struct i2c_msg da9210_msg = {
51 .addr = 0x68, 61 .len = ARRAY_SIZE(da9210_irq_clr),
52 .len = ARRAY_SIZE(da9210_irq_clr), 62 .buf = da9210_irq_clr,
53 .buf = da9210_irq_clr, 63};
54 }, { 64
55 .addr = 0x70, 65static const struct of_device_id rcar_gen2_quirk_match[] = {
56 .len = ARRAY_SIZE(da9210_irq_clr), 66 { .compatible = "dlg,da9063", .data = &da9063_msg },
57 .buf = da9210_irq_clr, 67 { .compatible = "dlg,da9210", .data = &da9210_msg },
58 }, 68 {},
59}; 69};
60 70
61static int regulator_quirk_notify(struct notifier_block *nb, 71static int regulator_quirk_notify(struct notifier_block *nb,
62 unsigned long action, void *data) 72 unsigned long action, void *data)
63{ 73{
74 struct regulator_quirk *pos, *tmp;
64 struct device *dev = data; 75 struct device *dev = data;
65 struct i2c_client *client; 76 struct i2c_client *client;
66 static bool done; 77 static bool done;
78 int ret;
67 u32 mon; 79 u32 mon;
68 80
69 if (done) 81 if (done)
@@ -80,17 +92,20 @@ static int regulator_quirk_notify(struct notifier_block *nb,
80 client = to_i2c_client(dev); 92 client = to_i2c_client(dev);
81 dev_dbg(dev, "Detected %s\n", client->name); 93 dev_dbg(dev, "Detected %s\n", client->name);
82 94
83 if ((client->addr == 0x58 && !strcmp(client->name, "da9063")) || 95 /*
84 (client->addr == 0x68 && !strcmp(client->name, "da9210")) || 96 * Send message to all PMICs that share an IRQ line to deassert it.
85 (client->addr == 0x70 && !strcmp(client->name, "da9210"))) { 97 *
86 int ret, len; 98 * WARNING: This works only if all the PMICs are on the same I2C bus.
99 */
100 list_for_each_entry(pos, &quirk_list, list) {
101 if (!pos->shared)
102 continue;
87 103
88 /* There are two DA9210 on Stout, one on the other boards. */ 104 dev_info(&client->dev, "clearing %s@0x%02x interrupts\n",
89 len = of_machine_is_compatible("renesas,stout") ? 3 : 2; 105 pos->id->compatible, pos->i2c_msg.addr);
90 106
91 dev_info(&client->dev, "clearing da9063/da9210 interrupts\n"); 107 ret = i2c_transfer(client->adapter, &pos->i2c_msg, 1);
92 ret = i2c_transfer(client->adapter, da9xxx_msgs, len); 108 if (ret != 1)
93 if (ret != len)
94 dev_err(&client->dev, "i2c error %d\n", ret); 109 dev_err(&client->dev, "i2c error %d\n", ret);
95 } 110 }
96 111
@@ -103,6 +118,11 @@ static int regulator_quirk_notify(struct notifier_block *nb,
103remove: 118remove:
104 dev_info(dev, "IRQ2 is not asserted, removing quirk\n"); 119 dev_info(dev, "IRQ2 is not asserted, removing quirk\n");
105 120
121 list_for_each_entry_safe(pos, tmp, &quirk_list, list) {
122 list_del(&pos->list);
123 kfree(pos);
124 }
125
106 done = true; 126 done = true;
107 iounmap(irqc); 127 iounmap(irqc);
108 return 0; 128 return 0;
@@ -114,7 +134,12 @@ static struct notifier_block regulator_quirk_nb = {
114 134
115static int __init rcar_gen2_regulator_quirk(void) 135static int __init rcar_gen2_regulator_quirk(void)
116{ 136{
117 u32 mon; 137 struct regulator_quirk *quirk, *pos, *tmp;
138 struct of_phandle_args *argsa, *argsb;
139 const struct of_device_id *id;
140 struct device_node *np;
141 u32 mon, addr;
142 int ret;
118 143
119 if (!of_machine_is_compatible("renesas,koelsch") && 144 if (!of_machine_is_compatible("renesas,koelsch") &&
120 !of_machine_is_compatible("renesas,lager") && 145 !of_machine_is_compatible("renesas,lager") &&
@@ -122,22 +147,78 @@ static int __init rcar_gen2_regulator_quirk(void)
122 !of_machine_is_compatible("renesas,gose")) 147 !of_machine_is_compatible("renesas,gose"))
123 return -ENODEV; 148 return -ENODEV;
124 149
150 for_each_matching_node_and_match(np, rcar_gen2_quirk_match, &id) {
151 if (!of_device_is_available(np))
152 break;
153
154 ret = of_property_read_u32(np, "reg", &addr);
155 if (ret) /* Skip invalid entry and continue */
156 continue;
157
158 quirk = kzalloc(sizeof(*quirk), GFP_KERNEL);
159 if (!quirk) {
160 ret = -ENOMEM;
161 goto err_mem;
162 }
163
164 argsa = &quirk->irq_args;
165 memcpy(&quirk->i2c_msg, id->data, sizeof(quirk->i2c_msg));
166
167 quirk->id = id;
168 quirk->i2c_msg.addr = addr;
169
170 ret = of_irq_parse_one(np, 0, argsa);
171 if (ret) { /* Skip invalid entry and continue */
172 kfree(quirk);
173 continue;
174 }
175
176 list_for_each_entry(pos, &quirk_list, list) {
177 argsb = &pos->irq_args;
178
179 if (argsa->args_count != argsb->args_count)
180 continue;
181
182 ret = memcmp(argsa->args, argsb->args,
183 argsa->args_count *
184 sizeof(argsa->args[0]));
185 if (!ret) {
186 pos->shared = true;
187 quirk->shared = true;
188 }
189 }
190
191 list_add_tail(&quirk->list, &quirk_list);
192 }
193
125 irqc = ioremap(IRQC_BASE, PAGE_SIZE); 194 irqc = ioremap(IRQC_BASE, PAGE_SIZE);
126 if (!irqc) 195 if (!irqc) {
127 return -ENOMEM; 196 ret = -ENOMEM;
197 goto err_mem;
198 }
128 199
129 mon = ioread32(irqc + IRQC_MONITOR); 200 mon = ioread32(irqc + IRQC_MONITOR);
130 if (mon & REGULATOR_IRQ_MASK) { 201 if (mon & REGULATOR_IRQ_MASK) {
131 pr_debug("%s: IRQ2 is not asserted, not installing quirk\n", 202 pr_debug("%s: IRQ2 is not asserted, not installing quirk\n",
132 __func__); 203 __func__);
133 iounmap(irqc); 204 ret = 0;
134 return 0; 205 goto err_free;
135 } 206 }
136 207
137 pr_info("IRQ2 is asserted, installing da9063/da9210 regulator quirk\n"); 208 pr_info("IRQ2 is asserted, installing da9063/da9210 regulator quirk\n");
138 209
139 bus_register_notifier(&i2c_bus_type, &regulator_quirk_nb); 210 bus_register_notifier(&i2c_bus_type, &regulator_quirk_nb);
140 return 0; 211 return 0;
212
213err_free:
214 iounmap(irqc);
215err_mem:
216 list_for_each_entry_safe(pos, tmp, &quirk_list, list) {
217 list_del(&pos->list);
218 kfree(pos);
219 }
220
221 return ret;
141} 222}
142 223
143arch_initcall(rcar_gen2_regulator_quirk); 224arch_initcall(rcar_gen2_regulator_quirk);