x86, olpc: Rework BIOS signature check

The XO-1.5 laptop is not currently detected as an OLPC machine because
it fails this XO-1-centric check.

Now that we have OLPC OFW support in the kernel, a more sensible
check is to see if we found OFW during boot and check the architecture
property.

Also remove a now-meaningless codepath, as we're always going to have
OFW support with OLPC.

Signed-off-by: Daniel Drake <dsd@laptop.org>
LKML-Reference: <20100923162846.D8D409D401B@zog.reactivated.net>
Cc: Andres Salomon <dilinger@queued.net>
Cc: Grant Likely <grant.likely@secretlab.ca>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
This commit is contained in:
Daniel Drake 2010-09-23 17:28:46 +01:00 committed by H. Peter Anvin
parent 76fb657017
commit 3e3c486012
4 changed files with 37 additions and 34 deletions

View File

@ -2061,6 +2061,7 @@ config SCx200HR_TIMER
config OLPC
bool "One Laptop Per Child support"
select GPIOLIB
select OLPC_OPENFIRMWARE
---help---
Add support for detecting the unique features of the OLPC
XO hardware.
@ -2068,7 +2069,7 @@ config OLPC
config OLPC_OPENFIRMWARE
bool "Support for OLPC's Open Firmware"
depends on !X86_64 && !X86_PAE
default y if OLPC
default n
help
This option adds support for the implementation of Open Firmware
that is used on the OLPC XO-1 Children's Machine.

View File

@ -21,10 +21,14 @@ extern void olpc_ofw_detect(void);
/* install OFW's pde permanently into the kernel's pgtable */
extern void setup_olpc_ofw_pgd(void);
/* check if OFW was detected during boot */
extern bool olpc_ofw_present(void);
#else /* !CONFIG_OLPC_OPENFIRMWARE */
static inline void olpc_ofw_detect(void) { }
static inline void setup_olpc_ofw_pgd(void) { }
static inline bool olpc_ofw_present(void) { return false; }
#endif /* !CONFIG_OLPC_OPENFIRMWARE */

View File

@ -183,8 +183,21 @@ err:
}
EXPORT_SYMBOL_GPL(olpc_ec_cmd);
#ifdef CONFIG_OLPC_OPENFIRMWARE
static void __init platform_detect(void)
static bool __init check_ofw_architecture(void)
{
size_t propsize;
char olpc_arch[5];
const void *args[] = { NULL, "architecture", olpc_arch, (void *)5 };
void *res[] = { &propsize };
if (olpc_ofw("getprop", args, res)) {
printk(KERN_ERR "ofw: getprop call failed!\n");
return false;
}
return propsize == 5 && strncmp("OLPC", olpc_arch, 5) == 0;
}
static u32 __init get_board_revision(void)
{
size_t propsize;
__be32 rev;
@ -193,46 +206,27 @@ static void __init platform_detect(void)
if (olpc_ofw("getprop", args, res) || propsize != 4) {
printk(KERN_ERR "ofw: getprop call failed!\n");
rev = cpu_to_be32(0);
return cpu_to_be32(0);
}
olpc_platform_info.boardrev = be32_to_cpu(rev);
return be32_to_cpu(rev);
}
#else
static void __init platform_detect(void)
static bool __init platform_detect(void)
{
/* stopgap until OFW support is added to the kernel */
olpc_platform_info.boardrev = olpc_board(0xc2);
if (!check_ofw_architecture())
return false;
olpc_platform_info.flags |= OLPC_F_PRESENT;
olpc_platform_info.boardrev = get_board_revision();
return true;
}
#endif
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())
if (!olpc_ofw_present() || !platform_detect())
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;
@ -254,8 +248,6 @@ static int __init olpc_init(void)
olpc_platform_info.boardrev >> 4,
olpc_platform_info.ecver);
unmap:
iounmap(romsig);
return 0;
}

View File

@ -74,6 +74,12 @@ int __olpc_ofw(const char *name, int nr_args, const void **args, int nr_res,
}
EXPORT_SYMBOL_GPL(__olpc_ofw);
bool olpc_ofw_present(void)
{
return olpc_ofw_cif != NULL;
}
EXPORT_SYMBOL_GPL(olpc_ofw_present);
/* OFW cif _should_ be above this address */
#define OFW_MIN 0xff000000