예제 #1
0
static int __init olpc_init(void)
{
	unsigned char *romsig;

	/* The ioremap check is dangerous; limit what we run it on */
	if (!is_geode() || cs5535_has_vsa2())
		return 0;

	spin_lock_init(&ec_lock);

	romsig = ioremap(0xffffffc0, 16);
	if (!romsig)
		return 0;

	if (strncmp(romsig, "CL1   Q", 7))
		goto unmap;
	if (strncmp(romsig+6, romsig+13, 3)) {
		printk(KERN_INFO "OLPC BIOS signature looks invalid.  "
				"Assuming not OLPC\n");
		goto unmap;
	}

	printk(KERN_INFO "OLPC board with OpenFirmware %.16s\n", romsig);
	olpc_platform_info.flags |= OLPC_F_PRESENT;

	/* get the platform revision */
	platform_detect();

	/* 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 */
	if (!cs5535_has_vsa2())
		x86_init.pci.arch_init = pci_olpc_init;
#endif

	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);

unmap:
	iounmap(romsig);
	return 0;
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
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;
}