blob: 2602f8cf5b2539cafa72d382a3b887d8b9f01fcd [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 Bohan87436bd2012-04-03 14:45:03 -0700206 /*
207 * Count the total number of device_nodes so we know how much
208 * device_store to allocate.
209 */
Michael Bohan86622b32012-02-08 16:59:00 -0800210 for_each_child_of_node(container, node)
211 num_dev_node++;
212
213 rc = of_spmi_alloc_device_store(d_info, num_dev_node);
214 if (rc) {
215 dev_err(&ctrl->dev, "%s: unable to allocate"
216 " device resources\n", __func__);
217 return;
218 }
219
Michael Bohan86622b32012-02-08 16:59:00 -0800220 i = 0;
221 for_each_child_of_node(container, node) {
222 of_spmi_init_resource(&r_info, node);
223 of_spmi_sum_node_resources(&r_info, 1);
224 rc = of_spmi_allocate_node_resources(d_info, &r_info, i);
225 if (rc) {
226 dev_err(&ctrl->dev, "%s: unable to allocate"
227 " resources\n", __func__);
228 of_spmi_free_device_resources(d_info);
229 return;
230 }
Michael Bohan86622b32012-02-08 16:59:00 -0800231 of_spmi_populate_node_resources(d_info, &r_info, i);
232 i++;
233 }
234
235 rc = of_spmi_create_device(d_info, container);
236 if (rc) {
237 dev_err(&ctrl->dev, "%s: unable to create device for"
238 " node %s\n", __func__, container->full_name);
239 of_spmi_free_device_resources(d_info);
240 return;
241 }
242}
243
244/*
245 * Walks all children of a node containing the spmi-slave-container
246 * binding. This indicates that all spmi_devices created from this
247 * point all share the same slave_id.
248 */
Michael Bohan11926c92012-02-08 11:01:24 -0800249static void of_spmi_walk_slave_container(struct of_spmi_dev_info *d_info,
250 struct device_node *container)
Michael Bohan86e30dc2012-01-05 14:16:43 -0800251{
Michael Bohan11926c92012-02-08 11:01:24 -0800252 struct spmi_controller *ctrl = d_info->ctrl;
Michael Bohan86e30dc2012-01-05 14:16:43 -0800253 struct device_node *node;
Michael Bohan86e30dc2012-01-05 14:16:43 -0800254 int rc;
255
256 for_each_child_of_node(container, node) {
Michael Bohan11926c92012-02-08 11:01:24 -0800257 struct of_spmi_res_info r_info;
Michael Bohan86e30dc2012-01-05 14:16:43 -0800258
Michael Bohan86622b32012-02-08 16:59:00 -0800259 /**
260 * Check to see if this node contains children which
261 * should be all created as the same spmi_device.
262 */
263 if (of_get_property(node, "spmi-dev-container", NULL)) {
264 of_spmi_walk_dev_container(d_info, node);
265 continue;
266 }
Michael Bohan11926c92012-02-08 11:01:24 -0800267
Michael Bohan86622b32012-02-08 16:59:00 -0800268 rc = of_spmi_alloc_device_store(d_info, 1);
269 if (rc) {
270 dev_err(&ctrl->dev, "%s: unable to allocate"
271 " device resources\n", __func__);
272 goto slave_err;
273 }
274
275 of_spmi_init_resource(&r_info, node);
276 of_spmi_sum_node_resources(&r_info, 1);
277
278 rc = of_spmi_allocate_node_resources(d_info, &r_info, 0);
Michael Bohan86e30dc2012-01-05 14:16:43 -0800279 if (rc) {
280 dev_err(&ctrl->dev, "%s: unable to allocate"
281 " resources\n", __func__);
Michael Bohan86622b32012-02-08 16:59:00 -0800282 goto slave_err;
Michael Bohan86e30dc2012-01-05 14:16:43 -0800283 }
Michael Bohan86622b32012-02-08 16:59:00 -0800284
285 of_spmi_populate_node_resources(d_info, &r_info, 0);
286
Michael Bohan11926c92012-02-08 11:01:24 -0800287 rc = of_spmi_create_device(d_info, node);
Michael Bohan86e30dc2012-01-05 14:16:43 -0800288 if (rc) {
289 dev_err(&ctrl->dev, "%s: unable to create device for"
290 " node %s\n", __func__, node->full_name);
Michael Bohan86622b32012-02-08 16:59:00 -0800291 goto slave_err;
Michael Bohan86e30dc2012-01-05 14:16:43 -0800292 }
293 }
Michael Bohan86622b32012-02-08 16:59:00 -0800294 return;
295
296slave_err:
297 of_spmi_free_device_resources(d_info);
Michael Bohan86e30dc2012-01-05 14:16:43 -0800298}
299
300int of_spmi_register_devices(struct spmi_controller *ctrl)
301{
Michael Bohan86622b32012-02-08 16:59:00 -0800302 struct device_node *node = ctrl->dev.of_node;
Michael Bohan86e30dc2012-01-05 14:16:43 -0800303
304 /* Only register child devices if the ctrl has a node pointer set */
Michael Bohan86622b32012-02-08 16:59:00 -0800305 if (!node)
Michael Bohan86e30dc2012-01-05 14:16:43 -0800306 return -ENODEV;
307
Michael Bohan86622b32012-02-08 16:59:00 -0800308 if (of_get_property(node, "spmi-slave-container", NULL)) {
309 dev_err(&ctrl->dev, "%s: structural error: spmi-slave-container"
310 " is prohibited at the root level\n", __func__);
311 return -EINVAL;
312 } else if (of_get_property(node, "spmi-dev-container", NULL)) {
313 dev_err(&ctrl->dev, "%s: structural error: spmi-dev-container"
314 " is prohibited at the root level\n", __func__);
315 return -EINVAL;
316 }
317
318 /**
319 * Make best effort to launch as many nodes as possible. If there are
320 * syntax errors, we will simply ignore that subtree and keep going.
321 */
Michael Bohan86e30dc2012-01-05 14:16:43 -0800322 for_each_child_of_node(ctrl->dev.of_node, node) {
Michael Bohan11926c92012-02-08 11:01:24 -0800323 struct of_spmi_dev_info d_info = {};
Michael Bohan86e30dc2012-01-05 14:16:43 -0800324 const __be32 *slave_id;
Michael Bohan86622b32012-02-08 16:59:00 -0800325 int len, rc, have_dev_container = 0;
Michael Bohan86e30dc2012-01-05 14:16:43 -0800326
327 slave_id = of_get_property(node, "reg", &len);
328 if (!slave_id) {
Michael Bohan86622b32012-02-08 16:59:00 -0800329 dev_err(&ctrl->dev, "%s: invalid sid "
330 "on %s\n", __func__, node->full_name);
Michael Bohan86e30dc2012-01-05 14:16:43 -0800331 continue;
332 }
333
Michael Bohan11926c92012-02-08 11:01:24 -0800334 d_info.b_info.slave_id = be32_to_cpup(slave_id);
335 d_info.ctrl = ctrl;
Michael Bohan86e30dc2012-01-05 14:16:43 -0800336
Michael Bohan86622b32012-02-08 16:59:00 -0800337 if (of_get_property(node, "spmi-dev-container", NULL))
338 have_dev_container = 1;
Michael Bohan11926c92012-02-08 11:01:24 -0800339 if (of_get_property(node, "spmi-slave-container", NULL)) {
Michael Bohan86622b32012-02-08 16:59:00 -0800340 if (have_dev_container)
341 of_spmi_walk_dev_container(&d_info, node);
342 else
343 of_spmi_walk_slave_container(&d_info, node);
Michael Bohan86e30dc2012-01-05 14:16:43 -0800344 } else {
Michael Bohan11926c92012-02-08 11:01:24 -0800345 struct of_spmi_res_info r_info;
346
Michael Bohan86622b32012-02-08 16:59:00 -0800347 /**
348 * A dev container at the second level without a slave
349 * container is considered an error.
350 */
351 if (have_dev_container) {
352 dev_err(&ctrl->dev, "%s: structural error,"
353 " node %s has spmi-dev-container without"
354 " specifying spmi-slave-container\n",
355 __func__, node->full_name);
Michael Bohan86e30dc2012-01-05 14:16:43 -0800356 continue;
Michael Bohan86622b32012-02-08 16:59:00 -0800357 }
358
359 rc = of_spmi_alloc_device_store(&d_info, 1);
360 if (rc) {
361 dev_err(&ctrl->dev, "%s: unable to allocate"
362 " device resources\n", __func__);
363 continue;
364 }
365
366 of_spmi_init_resource(&r_info, node);
367 of_spmi_sum_node_resources(&r_info, 0);
368 rc = of_spmi_allocate_node_resources(&d_info,
369 &r_info, 0);
370 if (rc) {
371 dev_err(&ctrl->dev, "%s: unable to allocate"
372 " resources\n", __func__);
373 of_spmi_free_device_resources(&d_info);
374 continue;
375 }
376
377 of_spmi_populate_node_resources(&d_info, &r_info, 0);
378
379 rc = of_spmi_create_device(&d_info, node);
380 if (rc) {
381 dev_err(&ctrl->dev, "%s: unable to create"
382 " device\n", __func__);
383 of_spmi_free_device_resources(&d_info);
384 continue;
385 }
Michael Bohan86e30dc2012-01-05 14:16:43 -0800386 }
387 }
388
389 return 0;
390}
391EXPORT_SYMBOL(of_spmi_register_devices);
392
393MODULE_LICENSE("GPL");