disable sstrip when using musl
[openwrt/openwrt.git] / target / linux / ubicom32 / files / arch / ubicom32 / kernel / devtree.c
1 /*
2 * arch/ubicom32/kernel/devtree.c
3 * Ubicom32 architecture device tree implementation.
4 *
5 * (C) Copyright 2009, Ubicom, Inc.
6 *
7 * This file is part of the Ubicom32 Linux Kernel Port.
8 *
9 * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10 * it and/or modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation, either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * The Ubicom32 Linux Kernel Port is distributed in the hope that it
15 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
16 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
17 * the GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with the Ubicom32 Linux Kernel Port. If not,
21 * see <http://www.gnu.org/licenses/>.
22 *
23 * Ubicom32 implementation derived from (with many thanks):
24 * arch/m68knommu
25 * arch/blackfin
26 * arch/parisc
27 */
28
29 #include <linux/module.h>
30 #include <linux/kernel.h>
31 #include <linux/string.h>
32 #include <linux/errno.h>
33 #include <asm/devtree.h>
34
35 /*
36 * The device tree.
37 */
38 struct devtree_node *devtree;
39
40 /*
41 * devtree_print()
42 * Print the device tree.
43 */
44 void devtree_print(void)
45 {
46 struct devtree_node *p = devtree;
47 printk(KERN_INFO "Device Tree:\n");
48 while (p) {
49 if (p->magic != DEVTREE_NODE_MAGIC) {
50 printk(KERN_EMERG
51 "device tree has improper node: %p\n", p);
52 return;
53 }
54 printk(KERN_INFO "\t%p: sendirq=%03d, recvirq=%03d, "
55 " name=%s\n", p, p->sendirq, p->recvirq, p->name);
56 p = p->next;
57 }
58 }
59 EXPORT_SYMBOL(devtree_print);
60
61 /*
62 * devtree_irq()
63 * Return the IRQ(s) associated with devtree node.
64 */
65 int devtree_irq(struct devtree_node *dn,
66 unsigned char *sendirq,
67 unsigned char *recvirq)
68 {
69 if (dn->magic != DEVTREE_NODE_MAGIC) {
70 printk(KERN_EMERG "improper node: %p\n", dn);
71 if (sendirq) {
72 *sendirq = DEVTREE_IRQ_NONE;
73 }
74 if (recvirq) {
75 *recvirq = DEVTREE_IRQ_NONE;
76 }
77 return -EFAULT;
78 }
79
80 /*
81 * Copy the devtree irq(s) to the output parameters.
82 */
83 if (sendirq) {
84 *sendirq = dn->sendirq;
85 }
86 if (recvirq) {
87 *recvirq = dn->recvirq;
88 }
89 return 0;
90 }
91 EXPORT_SYMBOL(devtree_irq);
92
93 /*
94 * devtree_find_next()
95 * Provide an iterator for walking the device tree.
96 */
97 struct devtree_node *devtree_find_next(struct devtree_node **cur)
98 {
99 struct devtree_node *p = *cur;
100 if (!p) {
101 *cur = devtree;
102 return devtree;
103 }
104 p = p->next;
105 *cur = p;
106 return p;
107 }
108
109 /*
110 * devtree_find_by_irq()
111 * Return the node associated with a given irq.
112 */
113 struct devtree_node *devtree_find_by_irq(uint8_t sendirq, uint8_t recvirq)
114 {
115 struct devtree_node *p = devtree;
116
117 if (sendirq == recvirq) {
118 printk(KERN_EMERG "identical request makes no sense sendirq = "
119 "%d, recvirq= %d\n", sendirq, recvirq);
120 return NULL;
121 }
122
123 while (p) {
124 if (p->magic != DEVTREE_NODE_MAGIC) {
125 printk(KERN_EMERG
126 "device tree has improper node: %p\n", p);
127 return NULL;
128 }
129
130 /*
131 * See if we can find a match on the IRQ(s) specified.
132 */
133 if ((sendirq == p->sendirq) && (recvirq == p->recvirq)) {
134 return p;
135 }
136
137 if ((sendirq == DEVTREE_IRQ_DONTCARE) &&
138 (p->recvirq == recvirq)) {
139 return p;
140 }
141
142 if ((recvirq == DEVTREE_IRQ_DONTCARE) &&
143 (p->sendirq == sendirq)) {
144 return p;
145 }
146
147 p = p->next;
148 }
149 return NULL;
150 }
151 EXPORT_SYMBOL(devtree_find_by_irq);
152
153 /*
154 * devtree_find_node()
155 * Find a node in the device tree by name.
156 */
157 struct devtree_node *devtree_find_node(const char *str)
158 {
159 struct devtree_node *p = devtree;
160 while (p) {
161 if (p->magic != DEVTREE_NODE_MAGIC) {
162 printk(KERN_EMERG
163 "device tree has improper node: %p\n", p);
164 return NULL;
165 }
166 if (strcmp(p->name, str) == 0) {
167 return p;
168 }
169 p = p->next;
170 }
171 return NULL;
172 }
173 EXPORT_SYMBOL(devtree_find_node);