Skip to content

Commit e691d24

Browse files
committed
Merge branch 'x86-olpc-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'x86-olpc-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: x86, olpc: Speed up device tree creation during boot x86, olpc: Add OLPC device-tree support x86, of: Define irq functions to allow drivers/of/* to build on x86
2 parents 55065bc + b5318d3 commit e691d24

File tree

9 files changed

+220
-0
lines changed

9 files changed

+220
-0
lines changed

arch/x86/Kconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2076,11 +2076,17 @@ config OLPC_OPENFIRMWARE
20762076
bool "Support for OLPC's Open Firmware"
20772077
depends on !X86_64 && !X86_PAE
20782078
default n
2079+
select OF
20792080
help
20802081
This option adds support for the implementation of Open Firmware
20812082
that is used on the OLPC XO-1 Children's Machine.
20822083
If unsure, say N here.
20832084

2085+
config OLPC_OPENFIRMWARE_DT
2086+
bool
2087+
default y if OLPC_OPENFIRMWARE && PROC_DEVICETREE
2088+
select OF_PROMTREE
2089+
20842090
endif # X86_32
20852091

20862092
config AMD_NB

arch/x86/include/asm/irq.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
#include <asm/apicdef.h>
1111
#include <asm/irq_vectors.h>
1212

13+
/* Even though we don't support this, supply it to appease OF */
14+
static inline void irq_dispose_mapping(unsigned int virq) { }
15+
1316
static inline int irq_canonicalize(int irq)
1417
{
1518
return ((irq == 2) ? 9 : irq);

arch/x86/include/asm/olpc_ofw.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
#ifdef CONFIG_OLPC_OPENFIRMWARE
1010

11+
extern bool olpc_ofw_is_installed(void);
12+
1113
/* run an OFW command by calling into the firmware */
1214
#define olpc_ofw(name, args, res) \
1315
__olpc_ofw((name), ARRAY_SIZE(args), args, ARRAY_SIZE(res), res)
@@ -26,10 +28,17 @@ extern bool olpc_ofw_present(void);
2628

2729
#else /* !CONFIG_OLPC_OPENFIRMWARE */
2830

31+
static inline bool olpc_ofw_is_installed(void) { return false; }
2932
static inline void olpc_ofw_detect(void) { }
3033
static inline void setup_olpc_ofw_pgd(void) { }
3134
static inline bool olpc_ofw_present(void) { return false; }
3235

3336
#endif /* !CONFIG_OLPC_OPENFIRMWARE */
3437

38+
#ifdef CONFIG_OLPC_OPENFIRMWARE_DT
39+
extern void olpc_dt_build_devicetree(void);
40+
#else
41+
static inline void olpc_dt_build_devicetree(void) { }
42+
#endif /* CONFIG_OLPC_OPENFIRMWARE_DT */
43+
3544
#endif /* _ASM_X86_OLPC_OFW_H */

arch/x86/include/asm/prom.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/* dummy prom.h; here to make linux/of.h's #includes happy */

arch/x86/kernel/irq.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <linux/cpu.h>
55
#include <linux/interrupt.h>
66
#include <linux/kernel_stat.h>
7+
#include <linux/of.h>
78
#include <linux/seq_file.h>
89
#include <linux/smp.h>
910
#include <linux/ftrace.h>
@@ -275,6 +276,15 @@ void smp_x86_platform_ipi(struct pt_regs *regs)
275276

276277
EXPORT_SYMBOL_GPL(vector_used_by_percpu_irq);
277278

279+
#ifdef CONFIG_OF
280+
unsigned int irq_create_of_mapping(struct device_node *controller,
281+
const u32 *intspec, unsigned int intsize)
282+
{
283+
return intspec[0];
284+
}
285+
EXPORT_SYMBOL_GPL(irq_create_of_mapping);
286+
#endif
287+
278288
#ifdef CONFIG_HOTPLUG_CPU
279289
/* A cpu has been removed from cpu_online_mask. Reset irq affinities. */
280290
void fixup_irqs(void)

arch/x86/mm/init_32.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#include <asm/bugs.h>
4646
#include <asm/tlb.h>
4747
#include <asm/tlbflush.h>
48+
#include <asm/olpc_ofw.h>
4849
#include <asm/pgalloc.h>
4950
#include <asm/sections.h>
5051
#include <asm/paravirt.h>
@@ -715,6 +716,7 @@ void __init paging_init(void)
715716
/*
716717
* NOTE: at this point the bootmem allocator is fully available.
717718
*/
719+
olpc_dt_build_devicetree();
718720
sparse_init();
719721
zone_sizes_init();
720722
}

arch/x86/platform/olpc/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
obj-$(CONFIG_OLPC) += olpc.o
22
obj-$(CONFIG_OLPC_XO1) += olpc-xo1.o
33
obj-$(CONFIG_OLPC_OPENFIRMWARE) += olpc_ofw.o
4+
obj-$(CONFIG_OLPC_OPENFIRMWARE_DT) += olpc_dt.o

arch/x86/platform/olpc/olpc_dt.c

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
/*
2+
* OLPC-specific OFW device tree support code.
3+
*
4+
* Paul Mackerras August 1996.
5+
* Copyright (C) 1996-2005 Paul Mackerras.
6+
*
7+
* Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
8+
* {engebret|bergner}@us.ibm.com
9+
*
10+
* Adapted for sparc by David S. Miller [email protected]
11+
* Adapted for x86/OLPC by Andres Salomon <[email protected]>
12+
*
13+
* This program is free software; you can redistribute it and/or
14+
* modify it under the terms of the GNU General Public License
15+
* as published by the Free Software Foundation; either version
16+
* 2 of the License, or (at your option) any later version.
17+
*/
18+
19+
#include <linux/kernel.h>
20+
#include <linux/bootmem.h>
21+
#include <linux/of.h>
22+
#include <linux/of_pdt.h>
23+
#include <asm/olpc_ofw.h>
24+
25+
static phandle __init olpc_dt_getsibling(phandle node)
26+
{
27+
const void *args[] = { (void *)node };
28+
void *res[] = { &node };
29+
30+
if ((s32)node == -1)
31+
return 0;
32+
33+
if (olpc_ofw("peer", args, res) || (s32)node == -1)
34+
return 0;
35+
36+
return node;
37+
}
38+
39+
static phandle __init olpc_dt_getchild(phandle node)
40+
{
41+
const void *args[] = { (void *)node };
42+
void *res[] = { &node };
43+
44+
if ((s32)node == -1)
45+
return 0;
46+
47+
if (olpc_ofw("child", args, res) || (s32)node == -1) {
48+
pr_err("PROM: %s: fetching child failed!\n", __func__);
49+
return 0;
50+
}
51+
52+
return node;
53+
}
54+
55+
static int __init olpc_dt_getproplen(phandle node, const char *prop)
56+
{
57+
const void *args[] = { (void *)node, prop };
58+
int len;
59+
void *res[] = { &len };
60+
61+
if ((s32)node == -1)
62+
return -1;
63+
64+
if (olpc_ofw("getproplen", args, res)) {
65+
pr_err("PROM: %s: getproplen failed!\n", __func__);
66+
return -1;
67+
}
68+
69+
return len;
70+
}
71+
72+
static int __init olpc_dt_getproperty(phandle node, const char *prop,
73+
char *buf, int bufsize)
74+
{
75+
int plen;
76+
77+
plen = olpc_dt_getproplen(node, prop);
78+
if (plen > bufsize || plen < 1) {
79+
return -1;
80+
} else {
81+
const void *args[] = { (void *)node, prop, buf, (void *)plen };
82+
void *res[] = { &plen };
83+
84+
if (olpc_ofw("getprop", args, res)) {
85+
pr_err("PROM: %s: getprop failed!\n", __func__);
86+
return -1;
87+
}
88+
}
89+
90+
return plen;
91+
}
92+
93+
static int __init olpc_dt_nextprop(phandle node, char *prev, char *buf)
94+
{
95+
const void *args[] = { (void *)node, prev, buf };
96+
int success;
97+
void *res[] = { &success };
98+
99+
buf[0] = '\0';
100+
101+
if ((s32)node == -1)
102+
return -1;
103+
104+
if (olpc_ofw("nextprop", args, res) || success != 1)
105+
return -1;
106+
107+
return 0;
108+
}
109+
110+
static int __init olpc_dt_pkg2path(phandle node, char *buf,
111+
const int buflen, int *len)
112+
{
113+
const void *args[] = { (void *)node, buf, (void *)buflen };
114+
void *res[] = { len };
115+
116+
if ((s32)node == -1)
117+
return -1;
118+
119+
if (olpc_ofw("package-to-path", args, res) || *len < 1)
120+
return -1;
121+
122+
return 0;
123+
}
124+
125+
static unsigned int prom_early_allocated __initdata;
126+
127+
void * __init prom_early_alloc(unsigned long size)
128+
{
129+
static u8 *mem;
130+
static size_t free_mem;
131+
void *res;
132+
133+
if (free_mem < size) {
134+
const size_t chunk_size = max(PAGE_SIZE, size);
135+
136+
/*
137+
* To mimimize the number of allocations, grab at least
138+
* PAGE_SIZE of memory (that's an arbitrary choice that's
139+
* fast enough on the platforms we care about while minimizing
140+
* wasted bootmem) and hand off chunks of it to callers.
141+
*/
142+
res = alloc_bootmem(chunk_size);
143+
if (!res)
144+
return NULL;
145+
prom_early_allocated += chunk_size;
146+
memset(res, 0, chunk_size);
147+
free_mem = chunk_size;
148+
mem = res;
149+
}
150+
151+
/* allocate from the local cache */
152+
free_mem -= size;
153+
res = mem;
154+
mem += size;
155+
return res;
156+
}
157+
158+
static struct of_pdt_ops prom_olpc_ops __initdata = {
159+
.nextprop = olpc_dt_nextprop,
160+
.getproplen = olpc_dt_getproplen,
161+
.getproperty = olpc_dt_getproperty,
162+
.getchild = olpc_dt_getchild,
163+
.getsibling = olpc_dt_getsibling,
164+
.pkg2path = olpc_dt_pkg2path,
165+
};
166+
167+
void __init olpc_dt_build_devicetree(void)
168+
{
169+
phandle root;
170+
171+
if (!olpc_ofw_is_installed())
172+
return;
173+
174+
root = olpc_dt_getsibling(0);
175+
if (!root) {
176+
pr_err("PROM: unable to get root node from OFW!\n");
177+
return;
178+
}
179+
of_pdt_build_devicetree(root, &prom_olpc_ops);
180+
181+
pr_info("PROM DT: Built device tree with %u bytes of memory.\n",
182+
prom_early_allocated);
183+
}

arch/x86/platform/olpc/olpc_ofw.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,8 @@ void __init olpc_ofw_detect(void)
110110
(unsigned long)olpc_ofw_cif, (-start) >> 20);
111111
reserve_top_address(-start);
112112
}
113+
114+
bool __init olpc_ofw_is_installed(void)
115+
{
116+
return olpc_ofw_cif != NULL;
117+
}

0 commit comments

Comments
 (0)