blob: 234a5eb77db0ca6e2066fd79d12d295724eba098 [file] [log] [blame]
Duy Truong790f06d2013-02-13 16:38:12 -08001/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
Sagar Dharia7e42e7f2012-03-21 15:29:04 -06002 *
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/* OF helpers for SLIMbus */
14#include <linux/slimbus/slimbus.h>
15#include <linux/irq.h>
16#include <linux/slab.h>
17#include <linux/of.h>
18#include <linux/of_irq.h>
19#include <linux/of_slimbus.h>
20
21int of_register_slim_devices(struct slim_controller *ctrl)
22{
23 struct device_node *node;
24 struct slim_boardinfo *binfo = NULL;
Sagar Dhariaf1a10782013-06-04 14:55:35 -060025 struct slim_boardinfo *temp;
Sagar Dharia7e42e7f2012-03-21 15:29:04 -060026 int n = 0;
27 int ret = 0;
28
29 if (!ctrl->dev.of_node)
30 return -EINVAL;
31
32 for_each_child_of_node(ctrl->dev.of_node, node) {
33 struct property *prop;
34 struct slim_device *slim;
35 char *name;
36 prop = of_find_property(node, "elemental-addr", NULL);
37 if (!prop || prop->length != 6) {
38 dev_err(&ctrl->dev, "of_slim: invalid E-addr");
39 continue;
40 }
41 name = kzalloc(SLIMBUS_NAME_SIZE, GFP_KERNEL);
42 if (!name) {
43 dev_err(&ctrl->dev, "of_slim: out of memory");
44 ret = -ENOMEM;
45 goto of_slim_err;
46 }
47 if (of_modalias_node(node, name, SLIMBUS_NAME_SIZE) < 0) {
48 dev_err(&ctrl->dev, "of_slim: modalias failure on %s\n",
49 node->full_name);
50 kfree(name);
51 continue;
52 }
53 slim = kzalloc(sizeof(struct slim_device), GFP_KERNEL);
54 if (!slim) {
55 dev_err(&ctrl->dev, "of_slim: out of memory");
56 ret = -ENOMEM;
57 kfree(name);
58 goto of_slim_err;
59 }
60 memcpy(slim->e_addr, prop->value, 6);
61
Sagar Dhariaf1a10782013-06-04 14:55:35 -060062 temp = krealloc(binfo, (n + 1) * sizeof(struct slim_boardinfo),
Sagar Dharia7e42e7f2012-03-21 15:29:04 -060063 GFP_KERNEL);
Sagar Dhariaf1a10782013-06-04 14:55:35 -060064 if (!temp) {
Sagar Dharia7e42e7f2012-03-21 15:29:04 -060065 dev_err(&ctrl->dev, "out of memory");
66 kfree(name);
67 kfree(slim);
Sagar Dhariaf1a10782013-06-04 14:55:35 -060068 ret = -ENOMEM;
69 goto of_slim_err;
Sagar Dharia7e42e7f2012-03-21 15:29:04 -060070 }
Sagar Dhariaf1a10782013-06-04 14:55:35 -060071 binfo = temp;
Kiran Kandi1756d8c2012-07-31 19:30:52 -070072
73 slim->dev.of_node = of_node_get(node);
Sagar Dharia7e42e7f2012-03-21 15:29:04 -060074 slim->name = (const char *)name;
75 binfo[n].bus_num = ctrl->nr;
76 binfo[n].slim_slave = slim;
77 n++;
78 }
Sagar Dhariaf1a10782013-06-04 14:55:35 -060079 ret = slim_register_board_info(binfo, n);
80 if (!ret)
81 goto of_slim_ret;
Sagar Dharia7e42e7f2012-03-21 15:29:04 -060082of_slim_err:
Sagar Dhariaf1a10782013-06-04 14:55:35 -060083 while (n-- > 0) {
Sagar Dharia7e42e7f2012-03-21 15:29:04 -060084 kfree(binfo[n].slim_slave->name);
85 kfree(binfo[n].slim_slave);
86 }
Sagar Dhariaf1a10782013-06-04 14:55:35 -060087of_slim_ret:
Sagar Dharia7e42e7f2012-03-21 15:29:04 -060088 kfree(binfo);
89 return ret;
90}