aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/platform/olpc/olpc_dt.c64
1 files changed, 50 insertions, 14 deletions
diff --git a/arch/x86/platform/olpc/olpc_dt.c b/arch/x86/platform/olpc/olpc_dt.c
index 820236b511b3..0296c5b55e6f 100644
--- a/arch/x86/platform/olpc/olpc_dt.c
+++ b/arch/x86/platform/olpc/olpc_dt.c
@@ -220,10 +220,26 @@ static u32 __init olpc_dt_get_board_revision(void)
220 return be32_to_cpu(rev); 220 return be32_to_cpu(rev);
221} 221}
222 222
223int olpc_dt_compatible_match(phandle node, const char *compat)
224{
225 char buf[64], *p;
226 int plen, len;
227
228 plen = olpc_dt_getproperty(node, "compatible", buf, sizeof(buf));
229 if (plen <= 0)
230 return 0;
231
232 len = strlen(compat);
233 for (p = buf; p < buf + plen; p += strlen(p) + 1) {
234 if (strcmp(p, compat) == 0)
235 return 1;
236 }
237
238 return 0;
239}
240
223void __init olpc_dt_fixup(void) 241void __init olpc_dt_fixup(void)
224{ 242{
225 int r;
226 char buf[64];
227 phandle node; 243 phandle node;
228 u32 board_rev; 244 u32 board_rev;
229 245
@@ -231,22 +247,31 @@ void __init olpc_dt_fixup(void)
231 if (!node) 247 if (!node)
232 return; 248 return;
233 249
234 /*
235 * If the battery node has a compatible property, we are running a new
236 * enough firmware and don't have fixups to make.
237 */
238 r = olpc_dt_getproperty(node, "compatible", buf, sizeof(buf));
239 if (r > 0)
240 return;
241
242 pr_info("PROM DT: Old firmware detected, applying fixes\n");
243
244 board_rev = olpc_dt_get_board_revision(); 250 board_rev = olpc_dt_get_board_revision();
245 if (!board_rev) 251 if (!board_rev)
246 return; 252 return;
247 253
248 if (board_rev >= olpc_board_pre(0xd0)) { 254 if (board_rev >= olpc_board_pre(0xd0)) {
249 /* XO-1.5: add dcon device */ 255 /* XO-1.5 */
256
257 if (olpc_dt_compatible_match(node, "olpc,xo1.5-battery"))
258 return;
259
260 /* Add olpc,xo1.5-battery compatible marker to battery node */
261 olpc_dt_interpret("\" /battery@0\" find-device");
262 olpc_dt_interpret(" \" olpc,xo1.5-battery\" +compatible");
263 olpc_dt_interpret("device-end");
264
265 if (olpc_dt_compatible_match(node, "olpc,xo1-battery")) {
266 /*
267 * If we have a olpc,xo1-battery compatible, then we're
268 * running a new enough firmware that already has
269 * the dcon node.
270 */
271 return;
272 }
273
274 /* Add dcon device */
250 olpc_dt_interpret("\" /pci/display@1\" find-device"); 275 olpc_dt_interpret("\" /pci/display@1\" find-device");
251 olpc_dt_interpret(" new-device"); 276 olpc_dt_interpret(" new-device");
252 olpc_dt_interpret(" \" dcon\" device-name"); 277 olpc_dt_interpret(" \" dcon\" device-name");
@@ -254,7 +279,18 @@ void __init olpc_dt_fixup(void)
254 olpc_dt_interpret(" finish-device"); 279 olpc_dt_interpret(" finish-device");
255 olpc_dt_interpret("device-end"); 280 olpc_dt_interpret("device-end");
256 } else { 281 } else {
257 /* XO-1: add dcon device, mark RTC as olpc,xo1-rtc */ 282 /* XO-1 */
283
284 if (olpc_dt_compatible_match(node, "olpc,xo1-battery")) {
285 /*
286 * If we have a olpc,xo1-battery compatible, then we're
287 * running a new enough firmware that already has
288 * the dcon and RTC nodes.
289 */
290 return;
291 }
292
293 /* Add dcon device, mark RTC as olpc,xo1-rtc */
258 olpc_dt_interpret("\" /pci/display@1,1\" find-device"); 294 olpc_dt_interpret("\" /pci/display@1,1\" find-device");
259 olpc_dt_interpret(" new-device"); 295 olpc_dt_interpret(" new-device");
260 olpc_dt_interpret(" \" dcon\" device-name"); 296 olpc_dt_interpret(" \" dcon\" device-name");