/* * Returns true if the compile and runtime configurations allow for EC events * to wake the system. */ bool olpc_ec_wakeup_available(void) { if (!machine_is_olpc()) return false; /* * XO-1 EC wakeups are available when olpc-xo1-sci driver is * compiled in */ #ifdef CONFIG_OLPC_XO1_SCI if (olpc_platform_info.boardrev < olpc_board_pre(0xd0)) /* XO-1 */ return true; #endif /* * XO-1.5 EC wakeups are available when olpc-xo15-sci driver is * compiled in */ #ifdef CONFIG_OLPC_XO15_SCI if (olpc_platform_info.boardrev >= olpc_board_pre(0xd0)) /* XO-1.5 */ return true; #endif return false; }
static int __init olpc_init(void) { int r = 0; if (!olpc_ofw_present() || !platform_detect()) return 0; spin_lock_init(&ec_lock); /* assume B1 and above models always have a DCON */ if (olpc_board_at_least(olpc_board(0xb1))) olpc_platform_info.flags |= OLPC_F_DCON; /* get the EC revision */ olpc_ec_cmd(EC_FIRMWARE_REV, NULL, 0, (unsigned char *) &olpc_platform_info.ecver, 1); #ifdef CONFIG_PCI_OLPC /* If the VSA exists let it emulate PCI, if not emulate in kernel. * XO-1 only. */ if (olpc_platform_info.boardrev < olpc_board_pre(0xd0) && !cs5535_has_vsa2()) x86_init.pci.arch_init = pci_olpc_init; #endif /* EC version 0x5f adds support for wide SCI mask */ if (olpc_platform_info.ecver >= 0x5f) olpc_platform_info.flags |= OLPC_F_EC_WIDE_SCI; printk(KERN_INFO "OLPC board revision %s%X (EC=%x)\n", ((olpc_platform_info.boardrev & 0xf) < 8) ? "pre" : "", olpc_platform_info.boardrev >> 4, olpc_platform_info.ecver); if (olpc_platform_info.boardrev < olpc_board_pre(0xd0)) { /* XO-1 */ r = add_xo1_platform_devices(); if (r) return r; } register_syscore_ops(&olpc_syscore_ops); setup_debugfs(); return 0; }
void __init olpc_dt_fixup(void) { int r; char buf[64]; phandle node; u32 board_rev; node = olpc_dt_finddevice("/battery@0"); if (!node) return; /* */ r = olpc_dt_getproperty(node, "compatible", buf, sizeof(buf)); if (r > 0) return; pr_info("PROM DT: Old firmware detected, applying fixes\n"); /* */ olpc_dt_interpret("\" /battery@0\" find-device" " \" olpc,xo1-battery\" +compatible" " device-end"); board_rev = olpc_dt_get_board_revision(); if (!board_rev) return; if (board_rev >= olpc_board_pre(0xd0)) { /* */ olpc_dt_interpret("\" /pci/display@1\" find-device" " new-device" " \" dcon\" device-name \" olpc,xo1-dcon\" +compatible" " finish-device device-end"); } else { /* */ olpc_dt_interpret("\" /pci/display@1,1\" find-device" " new-device" " \" dcon\" device-name \" olpc,xo1-dcon\" +compatible" " finish-device device-end" " \" /rtc\" find-device" " \" olpc,xo1-rtc\" +compatible" " device-end"); } }
void __init olpc_dt_fixup(void) { int r; char buf[64]; phandle node; u32 board_rev; node = olpc_dt_finddevice("/battery@0"); if (!node) return; /* * If the battery node has a compatible property, we are running a new * enough firmware and don't have fixups to make. */ r = olpc_dt_getproperty(node, "compatible", buf, sizeof(buf)); if (r > 0) return; pr_info("PROM DT: Old firmware detected, applying fixes\n"); /* Add olpc,xo1-battery compatible marker to battery node */ olpc_dt_interpret("\" /battery@0\" find-device" " \" olpc,xo1-battery\" +compatible" " device-end"); board_rev = olpc_dt_get_board_revision(); if (!board_rev) return; if (board_rev >= olpc_board_pre(0xd0)) { /* XO-1.5: add dcon device */ olpc_dt_interpret("\" /pci/display@1\" find-device" " new-device" " \" dcon\" device-name \" olpc,xo1-dcon\" +compatible" " finish-device device-end"); } else { /* XO-1: add dcon device, mark RTC as olpc,xo1-rtc */ olpc_dt_interpret("\" /pci/display@1,1\" find-device" " new-device" " \" dcon\" device-name \" olpc,xo1-dcon\" +compatible" " finish-device device-end" " \" /rtc\" find-device" " \" olpc,xo1-rtc\" +compatible" " device-end"); } }
static int __init olpc_bat_init(void) { int ret = 0; uint8_t status; if (!olpc_platform_info.ecver) return -ENXIO; /* * We've seen a number of EC protocol changes; this driver requires * the latest EC protocol, supported by 0x44 and above. */ if (olpc_platform_info.ecver < 0x44) { printk(KERN_NOTICE "OLPC EC version 0x%02x too old for " "battery driver.\n", olpc_platform_info.ecver); return -ENXIO; } ret = olpc_ec_cmd(EC_BAT_STATUS, NULL, 0, &status, 1); if (ret) return ret; /* Ignore the status. It doesn't actually matter */ bat_pdev = platform_device_register_simple("olpc-battery", 0, NULL, 0); if (IS_ERR(bat_pdev)) return PTR_ERR(bat_pdev); ret = power_supply_register(&bat_pdev->dev, &olpc_ac); if (ret) goto ac_failed; olpc_bat.name = bat_pdev->name; if (olpc_board_at_least(olpc_board_pre(0xd0))) { /* XO-1.5 */ olpc_bat.properties = olpc_xo15_bat_props; olpc_bat.num_properties = ARRAY_SIZE(olpc_xo15_bat_props); } else { /* XO-1 */ olpc_bat.properties = olpc_xo1_bat_props; olpc_bat.num_properties = ARRAY_SIZE(olpc_xo1_bat_props); } ret = power_supply_register(&bat_pdev->dev, &olpc_bat); if (ret) goto battery_failed; ret = device_create_bin_file(olpc_bat.dev, &olpc_bat_eeprom); if (ret) goto eeprom_failed; ret = device_create_file(olpc_bat.dev, &olpc_bat_error); if (ret) goto error_failed; goto success; error_failed: device_remove_bin_file(olpc_bat.dev, &olpc_bat_eeprom); eeprom_failed: power_supply_unregister(&olpc_bat); battery_failed: power_supply_unregister(&olpc_ac); ac_failed: platform_device_unregister(bat_pdev); success: return ret; }
static int olpc_battery_probe(struct platform_device *pdev) { int ret; uint8_t status; /* * We've seen a number of EC protocol changes; this driver requires * the latest EC protocol, supported by 0x44 and above. */ if (olpc_platform_info.ecver < 0x44) { printk(KERN_NOTICE "OLPC EC version 0x%02x too old for " "battery driver.\n", olpc_platform_info.ecver); return -ENXIO; } ret = olpc_ec_cmd(EC_BAT_STATUS, NULL, 0, &status, 1); if (ret) return ret; /* Ignore the status. It doesn't actually matter */ olpc_ac = power_supply_register(&pdev->dev, &olpc_ac_desc, NULL); if (IS_ERR(olpc_ac)) return PTR_ERR(olpc_ac); if (olpc_board_at_least(olpc_board_pre(0xd0))) { /* XO-1.5 */ olpc_bat_desc.properties = olpc_xo15_bat_props; olpc_bat_desc.num_properties = ARRAY_SIZE(olpc_xo15_bat_props); } else { /* XO-1 */ olpc_bat_desc.properties = olpc_xo1_bat_props; olpc_bat_desc.num_properties = ARRAY_SIZE(olpc_xo1_bat_props); } olpc_bat = power_supply_register(&pdev->dev, &olpc_bat_desc, NULL); if (IS_ERR(olpc_bat)) { ret = PTR_ERR(olpc_bat); goto battery_failed; } ret = device_create_bin_file(&olpc_bat->dev, &olpc_bat_eeprom); if (ret) goto eeprom_failed; ret = device_create_file(&olpc_bat->dev, &olpc_bat_error); if (ret) goto error_failed; if (olpc_ec_wakeup_available()) { device_set_wakeup_capable(&olpc_ac->dev, true); device_set_wakeup_capable(&olpc_bat->dev, true); } return 0; error_failed: device_remove_bin_file(&olpc_bat->dev, &olpc_bat_eeprom); eeprom_failed: power_supply_unregister(olpc_bat); battery_failed: power_supply_unregister(olpc_ac); return ret; }