Root/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 */
38struct devtree_node *devtree;
39
40/*
41 * devtree_print()
42 * Print the device tree.
43 */
44void 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}
59EXPORT_SYMBOL(devtree_print);
60
61/*
62 * devtree_irq()
63 * Return the IRQ(s) associated with devtree node.
64 */
65int 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}
91EXPORT_SYMBOL(devtree_irq);
92
93/*
94 * devtree_find_next()
95 * Provide an iterator for walking the device tree.
96 */
97struct 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 */
113struct 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}
151EXPORT_SYMBOL(devtree_find_by_irq);
152
153/*
154 * devtree_find_node()
155 * Find a node in the device tree by name.
156 */
157struct 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}
173EXPORT_SYMBOL(devtree_find_node);
174

Archive Download this file



interactive