blob: 61085c99eb659eba5cf405b6da756af161fe2bb6 [file] [log] [blame]
Michael Bohan86e30dc2012-01-05 14:16:43 -08001/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/spmi.h>
14#include <linux/irq.h>
15#include <linux/of.h>
16#include <linux/of_address.h>
17#include <linux/of_irq.h>
18#include <linux/of_spmi.h>
19#include <linux/slab.h>
20#include <linux/module.h>
Michael Bohan86622b32012-02-08 16:59:00 -080021#include <linux/types.h>
Michael Bohan86e30dc2012-01-05 14:16:43 -080022
Michael Bohan11926c92012-02-08 11:01:24 -080023struct of_spmi_dev_info {
24 struct spmi_controller *ctrl;
25 struct spmi_boardinfo b_info;
26};
27
28struct of_spmi_res_info {
29 struct device_node *node;
30 uint32_t num_reg;
31 uint32_t num_irq;
32};
33
Michael Bohan86622b32012-02-08 16:59:00 -080034/*
35 * Initialize r_info structure for safe usage
36 */
37static inline void of_spmi_init_resource(struct of_spmi_res_info *r_info,
38 struct device_node *node)
39{
40 r_info->node = node;
41 r_info->num_reg = 0;
42 r_info->num_irq = 0;
43}
44
45/*
46 * Allocate dev_node array for spmi_device
47 */
48static inline int of_spmi_alloc_device_store(struct of_spmi_dev_info *d_info,
49 uint32_t num_dev_node)
50{
51 d_info->b_info.num_dev_node = num_dev_node;
52 d_info->b_info.dev_node = kzalloc(sizeof(struct spmi_resource) *
53 num_dev_node, GFP_KERNEL);
54 if (!d_info->b_info.dev_node)
55 return -ENOMEM;
56
57 return 0;
58}
59
60/*
61 * Calculate the number of resources to allocate
62 *
63 * The caller is responsible for initializing the of_spmi_res_info structure.
64 */
65static void of_spmi_sum_node_resources(struct of_spmi_res_info *r_info,
66 bool has_reg)
Michael Bohan86e30dc2012-01-05 14:16:43 -080067{
Michael Bohan11926c92012-02-08 11:01:24 -080068 struct of_irq oirq;
Michael Bohan86e30dc2012-01-05 14:16:43 -080069 uint64_t size;
70 uint32_t flags;
Michael Bohan86622b32012-02-08 16:59:00 -080071 int i = 0;
Michael Bohan11926c92012-02-08 11:01:24 -080072
Michael Bohan86622b32012-02-08 16:59:00 -080073 while (of_irq_map_one(r_info->node, i, &oirq) == 0)
74 i++;
75
76 r_info->num_irq += i;
Michael Bohan11926c92012-02-08 11:01:24 -080077
78 if (!has_reg)
79 return;
80
81 /*
82 * We can't use of_address_to_resource here since it includes
83 * address translation; and address translation assumes that no
84 * parent buses have a size-cell of 0. But SPMI does have a
85 * size-cell of 0.
86 */
Michael Bohan86622b32012-02-08 16:59:00 -080087 i = 0;
88 while (of_get_address(r_info->node, i, &size, &flags) != NULL)
89 i++;
90
91 r_info->num_reg += i;
Michael Bohan11926c92012-02-08 11:01:24 -080092}
93
Michael Bohan86622b32012-02-08 16:59:00 -080094/*
95 * free spmi_resource for the spmi_device
Michael Bohan11926c92012-02-08 11:01:24 -080096 */
Michael Bohan86622b32012-02-08 16:59:00 -080097static void of_spmi_free_device_resources(struct of_spmi_dev_info *d_info)
98{
99 int i;
100
101 for (i = 0; i < d_info->b_info.num_dev_node; i++)
102 kfree(d_info->b_info.dev_node[i].resource);
103
104 kfree(d_info->b_info.dev_node);
105}
106
107/*
108 * Gather node resources and populate
109 */
110static void of_spmi_populate_node_resources(struct of_spmi_dev_info *d_info,
111 struct of_spmi_res_info *r_info,
112 int idx)
Michael Bohan11926c92012-02-08 11:01:24 -0800113
114{
115 uint32_t num_irq = r_info->num_irq, num_reg = r_info->num_reg;
116 int i;
Michael Bohan86e30dc2012-01-05 14:16:43 -0800117 struct resource *res;
118 const __be32 *addrp;
Michael Bohan11926c92012-02-08 11:01:24 -0800119 uint64_t size;
120 uint32_t flags;
Michael Bohan86e30dc2012-01-05 14:16:43 -0800121
Michael Bohan86622b32012-02-08 16:59:00 -0800122 res = d_info->b_info.dev_node[idx].resource;
123 d_info->b_info.dev_node[idx].of_node = r_info->node;
Michael Bohan86e30dc2012-01-05 14:16:43 -0800124
Michael Bohan86622b32012-02-08 16:59:00 -0800125 if ((num_irq || num_reg) && (res != NULL)) {
Michael Bohan86e30dc2012-01-05 14:16:43 -0800126 for (i = 0; i < num_reg; i++, res++) {
127 /* Addresses are always 16 bits */
Michael Bohan11926c92012-02-08 11:01:24 -0800128 addrp = of_get_address(r_info->node, i, &size, &flags);
Michael Bohan86e30dc2012-01-05 14:16:43 -0800129 BUG_ON(!addrp);
130 res->start = be32_to_cpup(addrp);
131 res->end = res->start + size - 1;
132 res->flags = flags;
133 }
Michael Bohan11926c92012-02-08 11:01:24 -0800134 WARN_ON(of_irq_to_resource_table(r_info->node, res, num_irq) !=
Michael Bohan86e30dc2012-01-05 14:16:43 -0800135 num_irq);
136 }
Michael Bohan86622b32012-02-08 16:59:00 -0800137}
138
139/*
140 * Allocate enough memory to handle the resources associated with the
141 * device_node. The number of device nodes included in this allocation
142 * depends on whether the spmi-dev-container flag is specified or not.
143 */
144static int of_spmi_allocate_node_resources(struct of_spmi_dev_info *d_info,
145 struct of_spmi_res_info *r_info,
146 uint32_t idx)
147{
148 uint32_t num_irq = r_info->num_irq, num_reg = r_info->num_reg;
149 struct resource *res = NULL;
150
151 if (num_irq || num_reg) {
152 res = kzalloc(sizeof(*res) * (num_irq + num_reg), GFP_KERNEL);
153 if (!res)
154 return -ENOMEM;
155 }
156 d_info->b_info.dev_node[idx].num_resources = num_reg + num_irq;
157 d_info->b_info.dev_node[idx].resource = res;
Michael Bohan86e30dc2012-01-05 14:16:43 -0800158
159 return 0;
160}
161
Michael Bohan86622b32012-02-08 16:59:00 -0800162/*
163 * create a single spmi_device
164 */
Michael Bohan11926c92012-02-08 11:01:24 -0800165static int of_spmi_create_device(struct of_spmi_dev_info *d_info,
166 struct device_node *node)
Michael Bohan86e30dc2012-01-05 14:16:43 -0800167{
Michael Bohan11926c92012-02-08 11:01:24 -0800168 struct spmi_controller *ctrl = d_info->ctrl;
169 struct spmi_boardinfo *b_info = &d_info->b_info;
Michael Bohan86e30dc2012-01-05 14:16:43 -0800170 void *result;
171 int rc;
172
Michael Bohan11926c92012-02-08 11:01:24 -0800173 rc = of_modalias_node(node, b_info->name, sizeof(b_info->name));
Michael Bohan86e30dc2012-01-05 14:16:43 -0800174 if (rc < 0) {
175 dev_err(&ctrl->dev, "of_spmi modalias failure on %s\n",
176 node->full_name);
177 return rc;
178 }
179
Michael Bohan11926c92012-02-08 11:01:24 -0800180 b_info->of_node = of_node_get(node);
181 result = spmi_new_device(ctrl, b_info);
Michael Bohan86e30dc2012-01-05 14:16:43 -0800182
183 if (result == NULL) {
184 dev_err(&ctrl->dev, "of_spmi: Failure registering %s\n",
185 node->full_name);
186 of_node_put(node);
187 return -ENODEV;
188 }
189
190 return 0;
191}
192
Michael Bohan86622b32012-02-08 16:59:00 -0800193/*
194 * Walks all children of a node containing the spmi-dev-container
195 * binding. This special type of spmi_device can include resources
196 * from more than one device node.
197 */
198static void of_spmi_walk_dev_container(struct of_spmi_dev_info *d_info,
199 struct device_node *container)
200{
201 struct of_spmi_res_info r_info = {};
202 struct spmi_controller *ctrl = d_info->ctrl;
203 struct device_node *node;
204 int rc, i, num_dev_node = 0;
205
Michael Bohan677dbbd2012-04-03 14:55:11 -0700206 if (!of_device_is_available(container))
207 return;
208
Michael Bohan87436bd2012-04-03 14:45:03 -0700209 /*
210 * Count the total number of device_nodes so we know how much
211 * device_store to allocate.
212 */
Michael Bohan677dbbd2012-04-03 14:55:11 -0700213 for_each_child_of_node(container, node) {
214 if (!of_device_is_available(node))
215 continue;
Michael Bohan86622b32012-02-08 16:59:00 -0800216 num_dev_node++;
Michael Bohan677dbbd2012-04-03 14:55:11 -0700217 }
Michael Bohan86622b32012-02-08 16:59:00 -0800218
219 rc = of_spmi_alloc_device_store(d_info, num_dev_node);
220 if (rc) {
221 dev_err(&ctrl->dev, "%s: unable to allocate"
222 " device resources\n", __func__);
223 return;
224 }
225
Michael Bohan86622b32012-02-08 16:59:00 -0800226 i = 0;
227 for_each_child_of_node(container, node) {
Michael Bohan677dbbd2012-04-03 14:55:11 -0700228 if (!of_device_is_available(node))
229 continue;
Michael Bohan86622b32012-02-08 16:59:00 -0800230 of_spmi_init_resource(&r_info, node);
231 of_spmi_sum_node_resources(&r_info, 1);
232 rc = of_spmi_allocate_node_resources(d_info, &r_info, i);
233 if (rc) {
234 dev_err(&ctrl->dev, "%s: unable to allocate"
235 " resources\n", __func__);
236 of_spmi_free_device_resources(d_info);
237 return;
238 }
Michael Bohan86622b32012-02-08 16:59:00 -0800239 of_spmi_populate_node_resources(d_info, &r_info, i);
240 i++;
241 }
242
243 rc = of_spmi_create_device(d_info, container);
244 if (rc) {
245 dev_err(&ctrl->dev, "%s: unable to create device for"
246 " node %s\n", __func__, container->full_name);
247 of_spmi_free_device_resources(d_info);
248 return;
249 }
250}
251
252/*
253 * Walks all children of a node containing the spmi-slave-container
254 * binding. This indicates that all spmi_devices created from this
255 * point all share the same slave_id.
256 */
Michael Bohan11926c92012-02-08 11:01:24 -0800257static void of_spmi_walk_slave_container(struct of_spmi_dev_info *d_info,
258 struct device_node *container)
Michael Bohan86e30dc2012-01-05 14:16:43 -0800259{
Michael Bohan11926c92012-02-08 11:01:24 -0800260 struct spmi_controller *ctrl = d_info->ctrl;
Michael Bohan86e30dc2012-01-05 14:16:43 -0800261 struct device_node *node;
Michael Bohan86e30dc2012-01-05 14:16:43 -0800262 int rc;
263
264 for_each_child_of_node(container, node) {
Michael Bohan11926c92012-02-08 11:01:24 -0800265 struct of_spmi_res_info r_info;
Michael Bohan86e30dc2012-01-05 14:16:43 -0800266
Michael Bohan677dbbd2012-04-03 14:55:11 -0700267 if (!of_device_is_available(node))
268 continue;
269
Michael Bohan86622b32012-02-08 16:59:00 -0800270 /**
271 * Check to see if this node contains children which
272 * should be all created as the same spmi_device.
273 */
274 if (of_get_property(node, "spmi-dev-container", NULL)) {
275 of_spmi_walk_dev_container(d_info, node);
276 continue;
277 }
Michael Bohan11926c92012-02-08 11:01:24 -0800278
Michael Bohan86622b32012-02-08 16:59:00 -0800279 rc = of_spmi_alloc_device_store(d_info, 1);
280 if (rc) {
281 dev_err(&ctrl->dev, "%s: unable to allocate"
282 " device resources\n", __func__);
283 goto slave_err;
284 }
285
286 of_spmi_init_resource(&r_info, node);
287 of_spmi_sum_node_resources(&r_info, 1);
288
289 rc = of_spmi_allocate_node_resources(d_info, &r_info, 0);
Michael Bohan86e30dc2012-01-05 14:16:43 -0800290 if (rc) {
291 dev_err(&ctrl->dev, "%s: unable to allocate"
292 " resources\n", __func__);
Michael Bohan86622b32012-02-08 16:59:00 -0800293 goto slave_err;
Michael Bohan86e30dc2012-01-05 14:16:43 -0800294 }
Michael Bohan86622b32012-02-08 16:59:00 -0800295
296 of_spmi_populate_node_resources(d_info, &r_info, 0);
297
Michael Bohan11926c92012-02-08 11:01:24 -0800298 rc = of_spmi_create_device(d_info, node);
Michael Bohan86e30dc2012-01-05 14:16:43 -0800299 if (rc) {
300 dev_err(&ctrl->dev, "%s: unable to create device for"
301 " node %s\n", __func__, node->full_name);
Michael Bohan86622b32012-02-08 16:59:00 -0800302 goto slave_err;
Michael Bohan86e30dc2012-01-05 14:16:43 -0800303 }
304 }
Michael Bohan86622b32012-02-08 16:59:00 -0800305 return;
306
307slave_err:
308 of_spmi_free_device_resources(d_info);
Michael Bohan86e30dc2012-01-05 14:16:43 -0800309}
310
311int of_spmi_register_devices(struct spmi_controller *ctrl)
312{
Michael Bohan86622b32012-02-08 16:59:00 -0800313 struct device_node *node = ctrl->dev.of_node;
Michael Bohan86e30dc2012-01-05 14:16:43 -0800314
315 /* Only register child devices if the ctrl has a node pointer set */
Michael Bohan86622b32012-02-08 16:59:00 -0800316 if (!node)
Michael Bohan86e30dc2012-01-05 14:16:43 -0800317 return -ENODEV;
318
Michael Bohan86622b32012-02-08 16:59:00 -0800319 if (of_get_property(node, "spmi-slave-container", NULL)) {
320 dev_err(&ctrl->dev, "%s: structural error: spmi-slave-container"
321 " is prohibited at the root level\n", __func__);
322 return -EINVAL;
323 } else if (of_get_property(node, "spmi-dev-container", NULL)) {
324 dev_err(&ctrl->dev, "%s: structural error: spmi-dev-container"
325 " is prohibited at the root level\n", __func__);
326 return -EINVAL;
327 }
328
329 /**
330 * Make best effort to launch as many nodes as possible. If there are
331 * syntax errors, we will simply ignore that subtree and keep going.
332 */
Michael Bohan86e30dc2012-01-05 14:16:43 -0800333 for_each_child_of_node(ctrl->dev.of_node, node) {
Michael Bohan11926c92012-02-08 11:01:24 -0800334 struct of_spmi_dev_info d_info = {};
Michael Bohan86e30dc2012-01-05 14:16:43 -0800335 const __be32 *slave_id;
Michael Bohan86622b32012-02-08 16:59:00 -0800336 int len, rc, have_dev_container = 0;
Michael Bohan86e30dc2012-01-05 14:16:43 -0800337
338 slave_id = of_get_property(node, "reg", &len);
339 if (!slave_id) {
Michael Bohan86622b32012-02-08 16:59:00 -0800340 dev_err(&ctrl->dev, "%s: invalid sid "
341 "on %s\n", __func__, node->full_name);
Michael Bohan86e30dc2012-01-05 14:16:43 -0800342 continue;
343 }
344
Michael Bohan11926c92012-02-08 11:01:24 -0800345 d_info.b_info.slave_id = be32_to_cpup(slave_id);
346 d_info.ctrl = ctrl;
Michael Bohan86e30dc2012-01-05 14:16:43 -0800347
Michael Bohan86622b32012-02-08 16:59:00 -0800348 if (of_get_property(node, "spmi-dev-container", NULL))
349 have_dev_container = 1;
Michael Bohan11926c92012-02-08 11:01:24 -0800350 if (of_get_property(node, "spmi-slave-container", NULL)) {
Michael Bohan86622b32012-02-08 16:59:00 -0800351 if (have_dev_container)
352 of_spmi_walk_dev_container(&d_info, node);
353 else
354 of_spmi_walk_slave_container(&d_info, node);
Michael Bohan86e30dc2012-01-05 14:16:43 -0800355 } else {
Michael Bohan11926c92012-02-08 11:01:24 -0800356 struct of_spmi_res_info r_info;
357
Michael Bohan86622b32012-02-08 16:59:00 -0800358 /**
359 * A dev container at the second level without a slave
360 * container is considered an error.
361 */
362 if (have_dev_container) {
363 dev_err(&ctrl->dev, "%s: structural error,"
364 " node %s has spmi-dev-container without"
365 " specifying spmi-slave-container\n",
366 __func__, node->full_name);
Michael Bohan86e30dc2012-01-05 14:16:43 -0800367 continue;
Michael Bohan86622b32012-02-08 16:59:00 -0800368 }
369
Michael Bohan677dbbd2012-04-03 14:55:11 -0700370 if (!of_device_is_available(node))
371 continue;
372
Michael Bohan86622b32012-02-08 16:59:00 -0800373 rc = of_spmi_alloc_device_store(&d_info, 1);
374 if (rc) {
375 dev_err(&ctrl->dev, "%s: unable to allocate"
376 " device resources\n", __func__);
377 continue;
378 }
379
380 of_spmi_init_resource(&r_info, node);
381 of_spmi_sum_node_resources(&r_info, 0);
382 rc = of_spmi_allocate_node_resources(&d_info,
383 &r_info, 0);
384 if (rc) {
385 dev_err(&ctrl->dev, "%s: unable to allocate"
386 " resources\n", __func__);
387 of_spmi_free_device_resources(&d_info);
388 continue;
389 }
390
391 of_spmi_populate_node_resources(&d_info, &r_info, 0);
392
393 rc = of_spmi_create_device(&d_info, node);
394 if (rc) {
395 dev_err(&ctrl->dev, "%s: unable to create"
396 " device\n", __func__);
397 of_spmi_free_device_resources(&d_info);
398 continue;
399 }
Michael Bohan86e30dc2012-01-05 14:16:43 -0800400 }
401 }
402
403 return 0;
404}
405EXPORT_SYMBOL(of_spmi_register_devices);
406
407MODULE_LICENSE("GPL");