aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2010-10-30 11:49:09 -0400
committerGrant Likely <grant.likely@secretlab.ca>2011-01-01 15:03:25 -0500
commita4f740cf33f7f6c164bbde3c0cdbcc77b0c4997c (patch)
tree62d061939000c65d91cf760a51509d388270f4c9
parent73930a85cf38d72851305fcf640c07b4c13aa405 (diff)
of/flattree: Add of_flat_dt_match() helper function
This patch adds of_flat_dt_match() which tests a node for compatibility with a list of values and converts the relevant powerpc platform code to use it. This approach simplifies the board support code a bit. Signed-off-by: Grant Likely <grant.likely@secretlab.ca> Reviewed-by: Stephen Neuendorffer <stephen.neuendorffer@xilinx.com>
-rw-r--r--arch/powerpc/platforms/40x/ppc40x_simple.c13
-rw-r--r--arch/powerpc/platforms/512x/mpc5121_generic.c13
-rw-r--r--arch/powerpc/platforms/52xx/lite5200.c16
-rw-r--r--arch/powerpc/platforms/52xx/media5200.c13
-rw-r--r--arch/powerpc/platforms/52xx/mpc5200_simple.c13
-rw-r--r--arch/powerpc/platforms/83xx/mpc830x_rdb.c13
-rw-r--r--arch/powerpc/platforms/83xx/mpc831x_rdb.c11
-rw-r--r--arch/powerpc/platforms/83xx/mpc837x_rdb.c15
-rw-r--r--arch/powerpc/platforms/85xx/tqm85xx.c20
-rw-r--r--drivers/of/fdt.c37
-rw-r--r--include/linux/of_fdt.h3
11 files changed, 89 insertions, 78 deletions
diff --git a/arch/powerpc/platforms/40x/ppc40x_simple.c b/arch/powerpc/platforms/40x/ppc40x_simple.c
index 546bbc229d19..2521d93ef136 100644
--- a/arch/powerpc/platforms/40x/ppc40x_simple.c
+++ b/arch/powerpc/platforms/40x/ppc40x_simple.c
@@ -50,7 +50,7 @@ machine_device_initcall(ppc40x_simple, ppc40x_device_probe);
50 * Again, if your board needs to do things differently then create a 50 * Again, if your board needs to do things differently then create a
51 * board.c file for it rather than adding it to this list. 51 * board.c file for it rather than adding it to this list.
52 */ 52 */
53static char *board[] __initdata = { 53static const char *board[] __initdata = {
54 "amcc,acadia", 54 "amcc,acadia",
55 "amcc,haleakala", 55 "amcc,haleakala",
56 "amcc,kilauea", 56 "amcc,kilauea",
@@ -60,14 +60,9 @@ static char *board[] __initdata = {
60 60
61static int __init ppc40x_probe(void) 61static int __init ppc40x_probe(void)
62{ 62{
63 unsigned long root = of_get_flat_dt_root(); 63 if (of_flat_dt_match(of_get_flat_dt_root(), board)) {
64 int i = 0; 64 ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC);
65 65 return 1;
66 for (i = 0; i < ARRAY_SIZE(board); i++) {
67 if (of_flat_dt_is_compatible(root, board[i])) {
68 ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC);
69 return 1;
70 }
71 } 66 }
72 67
73 return 0; 68 return 0;
diff --git a/arch/powerpc/platforms/512x/mpc5121_generic.c b/arch/powerpc/platforms/512x/mpc5121_generic.c
index e487eb06ec6b..926731f1ff01 100644
--- a/arch/powerpc/platforms/512x/mpc5121_generic.c
+++ b/arch/powerpc/platforms/512x/mpc5121_generic.c
@@ -26,7 +26,7 @@
26/* 26/*
27 * list of supported boards 27 * list of supported boards
28 */ 28 */
29static char *board[] __initdata = { 29static const char *board[] __initdata = {
30 "prt,prtlvt", 30 "prt,prtlvt",
31 NULL 31 NULL
32}; 32};
@@ -36,16 +36,7 @@ static char *board[] __initdata = {
36 */ 36 */
37static int __init mpc5121_generic_probe(void) 37static int __init mpc5121_generic_probe(void)
38{ 38{
39 unsigned long node = of_get_flat_dt_root(); 39 return of_flat_dt_match(of_get_flat_dt_root(), board);
40 int i = 0;
41
42 while (board[i]) {
43 if (of_flat_dt_is_compatible(node, board[i]))
44 break;
45 i++;
46 }
47
48 return board[i] != NULL;
49} 40}
50 41
51define_machine(mpc5121_generic) { 42define_machine(mpc5121_generic) {
diff --git a/arch/powerpc/platforms/52xx/lite5200.c b/arch/powerpc/platforms/52xx/lite5200.c
index de55bc0584b5..01ffa64d2aa7 100644
--- a/arch/powerpc/platforms/52xx/lite5200.c
+++ b/arch/powerpc/platforms/52xx/lite5200.c
@@ -172,20 +172,18 @@ static void __init lite5200_setup_arch(void)
172 mpc52xx_setup_pci(); 172 mpc52xx_setup_pci();
173} 173}
174 174
175static const char *board[] __initdata = {
176 "fsl,lite5200",
177 "fsl,lite5200b",
178 NULL,
179};
180
175/* 181/*
176 * Called very early, MMU is off, device-tree isn't unflattened 182 * Called very early, MMU is off, device-tree isn't unflattened
177 */ 183 */
178static int __init lite5200_probe(void) 184static int __init lite5200_probe(void)
179{ 185{
180 unsigned long node = of_get_flat_dt_root(); 186 return of_flat_dt_match(of_get_flat_dt_root(), board);
181 const char *model = of_get_flat_dt_prop(node, "model", NULL);
182
183 if (!of_flat_dt_is_compatible(node, "fsl,lite5200") &&
184 !of_flat_dt_is_compatible(node, "fsl,lite5200b"))
185 return 0;
186 pr_debug("%s board found\n", model ? model : "unknown");
187
188 return 1;
189} 187}
190 188
191define_machine(lite5200) { 189define_machine(lite5200) {
diff --git a/arch/powerpc/platforms/52xx/media5200.c b/arch/powerpc/platforms/52xx/media5200.c
index 0bac3a3dbecf..2c7780cb68e5 100644
--- a/arch/powerpc/platforms/52xx/media5200.c
+++ b/arch/powerpc/platforms/52xx/media5200.c
@@ -239,7 +239,7 @@ static void __init media5200_setup_arch(void)
239} 239}
240 240
241/* list of the supported boards */ 241/* list of the supported boards */
242static char *board[] __initdata = { 242static const char *board[] __initdata = {
243 "fsl,media5200", 243 "fsl,media5200",
244 NULL 244 NULL
245}; 245};
@@ -249,16 +249,7 @@ static char *board[] __initdata = {
249 */ 249 */
250static int __init media5200_probe(void) 250static int __init media5200_probe(void)
251{ 251{
252 unsigned long node = of_get_flat_dt_root(); 252 return of_flat_dt_match(of_get_flat_dt_root(), board);
253 int i = 0;
254
255 while (board[i]) {
256 if (of_flat_dt_is_compatible(node, board[i]))
257 break;
258 i++;
259 }
260
261 return (board[i] != NULL);
262} 253}
263 254
264define_machine(media5200_platform) { 255define_machine(media5200_platform) {
diff --git a/arch/powerpc/platforms/52xx/mpc5200_simple.c b/arch/powerpc/platforms/52xx/mpc5200_simple.c
index d45be5b5ad49..e36d6e232ae6 100644
--- a/arch/powerpc/platforms/52xx/mpc5200_simple.c
+++ b/arch/powerpc/platforms/52xx/mpc5200_simple.c
@@ -49,7 +49,7 @@ static void __init mpc5200_simple_setup_arch(void)
49} 49}
50 50
51/* list of the supported boards */ 51/* list of the supported boards */
52static char *board[] __initdata = { 52static const char *board[] __initdata = {
53 "intercontrol,digsy-mtc", 53 "intercontrol,digsy-mtc",
54 "manroland,mucmc52", 54 "manroland,mucmc52",
55 "manroland,uc101", 55 "manroland,uc101",
@@ -66,16 +66,7 @@ static char *board[] __initdata = {
66 */ 66 */
67static int __init mpc5200_simple_probe(void) 67static int __init mpc5200_simple_probe(void)
68{ 68{
69 unsigned long node = of_get_flat_dt_root(); 69 return of_flat_dt_match(of_get_flat_dt_root(), board);
70 int i = 0;
71
72 while (board[i]) {
73 if (of_flat_dt_is_compatible(node, board[i]))
74 break;
75 i++;
76 }
77
78 return (board[i] != NULL);
79} 70}
80 71
81define_machine(mpc5200_simple_platform) { 72define_machine(mpc5200_simple_platform) {
diff --git a/arch/powerpc/platforms/83xx/mpc830x_rdb.c b/arch/powerpc/platforms/83xx/mpc830x_rdb.c
index 846831d495b5..661d354e4ff2 100644
--- a/arch/powerpc/platforms/83xx/mpc830x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc830x_rdb.c
@@ -57,16 +57,19 @@ static void __init mpc830x_rdb_init_IRQ(void)
57 ipic_set_default_priority(); 57 ipic_set_default_priority();
58} 58}
59 59
60struct const char *board[] __initdata = {
61 "MPC8308RDB",
62 "fsl,mpc8308rdb",
63 "denx,mpc8308_p1m",
64 NULL
65}
66
60/* 67/*
61 * Called very early, MMU is off, device-tree isn't unflattened 68 * Called very early, MMU is off, device-tree isn't unflattened
62 */ 69 */
63static int __init mpc830x_rdb_probe(void) 70static int __init mpc830x_rdb_probe(void)
64{ 71{
65 unsigned long root = of_get_flat_dt_root(); 72 return of_flat_dt_match(of_get_flat_dt_root(), board);
66
67 return of_flat_dt_is_compatible(root, "MPC8308RDB") ||
68 of_flat_dt_is_compatible(root, "fsl,mpc8308rdb") ||
69 of_flat_dt_is_compatible(root, "denx,mpc8308_p1m");
70} 73}
71 74
72static struct of_device_id __initdata of_bus_ids[] = { 75static struct of_device_id __initdata of_bus_ids[] = {
diff --git a/arch/powerpc/platforms/83xx/mpc831x_rdb.c b/arch/powerpc/platforms/83xx/mpc831x_rdb.c
index ae525e4745d2..b54cd736a895 100644
--- a/arch/powerpc/platforms/83xx/mpc831x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc831x_rdb.c
@@ -60,15 +60,18 @@ static void __init mpc831x_rdb_init_IRQ(void)
60 ipic_set_default_priority(); 60 ipic_set_default_priority();
61} 61}
62 62
63struct const char *board[] __initdata = {
64 "MPC8313ERDB",
65 "fsl,mpc8315erdb",
66 NULL
67}
68
63/* 69/*
64 * Called very early, MMU is off, device-tree isn't unflattened 70 * Called very early, MMU is off, device-tree isn't unflattened
65 */ 71 */
66static int __init mpc831x_rdb_probe(void) 72static int __init mpc831x_rdb_probe(void)
67{ 73{
68 unsigned long root = of_get_flat_dt_root(); 74 return of_flat_dt_match(of_get_flat_dt_root(), board);
69
70 return of_flat_dt_is_compatible(root, "MPC8313ERDB") ||
71 of_flat_dt_is_compatible(root, "fsl,mpc8315erdb");
72} 75}
73 76
74static struct of_device_id __initdata of_bus_ids[] = { 77static struct of_device_id __initdata of_bus_ids[] = {
diff --git a/arch/powerpc/platforms/83xx/mpc837x_rdb.c b/arch/powerpc/platforms/83xx/mpc837x_rdb.c
index 910caa6b5810..7bafbf2ec0f9 100644
--- a/arch/powerpc/platforms/83xx/mpc837x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc837x_rdb.c
@@ -101,17 +101,20 @@ static void __init mpc837x_rdb_init_IRQ(void)
101 ipic_set_default_priority(); 101 ipic_set_default_priority();
102} 102}
103 103
104static const char *board[] __initdata = {
105 "fsl,mpc8377rdb",
106 "fsl,mpc8378rdb",
107 "fsl,mpc8379rdb",
108 "fsl,mpc8377wlan",
109 NULL
110};
111
104/* 112/*
105 * Called very early, MMU is off, device-tree isn't unflattened 113 * Called very early, MMU is off, device-tree isn't unflattened
106 */ 114 */
107static int __init mpc837x_rdb_probe(void) 115static int __init mpc837x_rdb_probe(void)
108{ 116{
109 unsigned long root = of_get_flat_dt_root(); 117 return of_flat_dt_match(of_get_flat_dt_root(), board);
110
111 return of_flat_dt_is_compatible(root, "fsl,mpc8377rdb") ||
112 of_flat_dt_is_compatible(root, "fsl,mpc8378rdb") ||
113 of_flat_dt_is_compatible(root, "fsl,mpc8379rdb") ||
114 of_flat_dt_is_compatible(root, "fsl,mpc8377wlan");
115} 118}
116 119
117define_machine(mpc837x_rdb) { 120define_machine(mpc837x_rdb) {
diff --git a/arch/powerpc/platforms/85xx/tqm85xx.c b/arch/powerpc/platforms/85xx/tqm85xx.c
index 8f29bbce5360..5e847d0b47c8 100644
--- a/arch/powerpc/platforms/85xx/tqm85xx.c
+++ b/arch/powerpc/platforms/85xx/tqm85xx.c
@@ -186,21 +186,21 @@ static int __init declare_of_platform_devices(void)
186} 186}
187machine_device_initcall(tqm85xx, declare_of_platform_devices); 187machine_device_initcall(tqm85xx, declare_of_platform_devices);
188 188
189static const char *board[] __initdata = {
190 "tqc,tqm8540",
191 "tqc,tqm8541",
192 "tqc,tqm8548",
193 "tqc,tqm8555",
194 "tqc,tqm8560",
195 NULL
196};
197
189/* 198/*
190 * Called very early, device-tree isn't unflattened 199 * Called very early, device-tree isn't unflattened
191 */ 200 */
192static int __init tqm85xx_probe(void) 201static int __init tqm85xx_probe(void)
193{ 202{
194 unsigned long root = of_get_flat_dt_root(); 203 return of_flat_dt_match(of_get_flat_dt_root(), board);
195
196 if ((of_flat_dt_is_compatible(root, "tqc,tqm8540")) ||
197 (of_flat_dt_is_compatible(root, "tqc,tqm8541")) ||
198 (of_flat_dt_is_compatible(root, "tqc,tqm8548")) ||
199 (of_flat_dt_is_compatible(root, "tqc,tqm8555")) ||
200 (of_flat_dt_is_compatible(root, "tqc,tqm8560")))
201 return 1;
202
203 return 0;
204} 204}
205 205
206define_machine(tqm85xx) { 206define_machine(tqm85xx) {
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 8a90ee42071a..c787c3d95c60 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -78,19 +78,23 @@ void *of_fdt_get_property(struct boot_param_header *blob,
78 * @blob: A device tree blob 78 * @blob: A device tree blob
79 * @node: node to test 79 * @node: node to test
80 * @compat: compatible string to compare with compatible list. 80 * @compat: compatible string to compare with compatible list.
81 *
82 * On match, returns a non-zero value with smaller values returned for more
83 * specific compatible values.
81 */ 84 */
82int of_fdt_is_compatible(struct boot_param_header *blob, 85int of_fdt_is_compatible(struct boot_param_header *blob,
83 unsigned long node, const char *compat) 86 unsigned long node, const char *compat)
84{ 87{
85 const char *cp; 88 const char *cp;
86 unsigned long cplen, l; 89 unsigned long cplen, l, score = 0;
87 90
88 cp = of_fdt_get_property(blob, node, "compatible", &cplen); 91 cp = of_fdt_get_property(blob, node, "compatible", &cplen);
89 if (cp == NULL) 92 if (cp == NULL)
90 return 0; 93 return 0;
91 while (cplen > 0) { 94 while (cplen > 0) {
95 score++;
92 if (of_compat_cmp(cp, compat, strlen(compat)) == 0) 96 if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
93 return 1; 97 return score;
94 l = strlen(cp) + 1; 98 l = strlen(cp) + 1;
95 cp += l; 99 cp += l;
96 cplen -= l; 100 cplen -= l;
@@ -99,6 +103,27 @@ int of_fdt_is_compatible(struct boot_param_header *blob,
99 return 0; 103 return 0;
100} 104}
101 105
106/**
107 * of_fdt_match - Return true if node matches a list of compatible values
108 */
109int of_fdt_match(struct boot_param_header *blob, unsigned long node,
110 const char **compat)
111{
112 unsigned int tmp, score = 0;
113
114 if (!compat)
115 return 0;
116
117 while (*compat) {
118 tmp = of_fdt_is_compatible(blob, node, *compat);
119 if (tmp && (score == 0 || (tmp < score)))
120 score = tmp;
121 compat++;
122 }
123
124 return score;
125}
126
102static void *unflatten_dt_alloc(unsigned long *mem, unsigned long size, 127static void *unflatten_dt_alloc(unsigned long *mem, unsigned long size,
103 unsigned long align) 128 unsigned long align)
104{ 129{
@@ -511,6 +536,14 @@ int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
511 return of_fdt_is_compatible(initial_boot_params, node, compat); 536 return of_fdt_is_compatible(initial_boot_params, node, compat);
512} 537}
513 538
539/**
540 * of_flat_dt_match - Return true if node matches a list of compatible values
541 */
542int __init of_flat_dt_match(unsigned long node, const char **compat)
543{
544 return of_fdt_match(initial_boot_params, node, compat);
545}
546
514#ifdef CONFIG_BLK_DEV_INITRD 547#ifdef CONFIG_BLK_DEV_INITRD
515/** 548/**
516 * early_init_dt_check_for_initrd - Decode initrd location from flat tree 549 * early_init_dt_check_for_initrd - Decode initrd location from flat tree
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
index 9ce5dfd2186a..ee96091f7d25 100644
--- a/include/linux/of_fdt.h
+++ b/include/linux/of_fdt.h
@@ -68,6 +68,8 @@ extern void *of_fdt_get_property(struct boot_param_header *blob,
68extern int of_fdt_is_compatible(struct boot_param_header *blob, 68extern int of_fdt_is_compatible(struct boot_param_header *blob,
69 unsigned long node, 69 unsigned long node,
70 const char *compat); 70 const char *compat);
71extern int of_fdt_match(struct boot_param_header *blob, unsigned long node,
72 const char **compat);
71extern void of_fdt_unflatten_tree(unsigned long *blob, 73extern void of_fdt_unflatten_tree(unsigned long *blob,
72 struct device_node **mynodes); 74 struct device_node **mynodes);
73 75
@@ -84,6 +86,7 @@ extern int of_scan_flat_dt(int (*it)(unsigned long node, const char *uname,
84extern void *of_get_flat_dt_prop(unsigned long node, const char *name, 86extern void *of_get_flat_dt_prop(unsigned long node, const char *name,
85 unsigned long *size); 87 unsigned long *size);
86extern int of_flat_dt_is_compatible(unsigned long node, const char *name); 88extern int of_flat_dt_is_compatible(unsigned long node, const char *name);
89extern int of_flat_dt_match(unsigned long node, const char **matches);
87extern unsigned long of_get_flat_dt_root(void); 90extern unsigned long of_get_flat_dt_root(void);
88 91
89extern int early_init_dt_scan_chosen(unsigned long node, const char *uname, 92extern int early_init_dt_scan_chosen(unsigned long node, const char *uname,