提交 45bb1674 编写于 作者: D Daniel Drake 提交者: H. Peter Anvin

x86, olpc: Use device tree for platform identification

Make OLPC fully depend on device tree, and use it to identify the OLPC
platform details. Some nodes are exposed as platform devices where we
plan to use device tree for device probing.
Signed-off-by: NDaniel Drake <dsd@laptop.org>
Acked-by: NGrant Likely <grant.likely@secretlab.ca>
LKML-Reference: <20110313151017.C255F9D401E@zog.reactivated.net>
Signed-off-by: NH. Peter Anvin <hpa@linux.intel.com>
上级 25874a29
...@@ -2071,7 +2071,7 @@ config OLPC ...@@ -2071,7 +2071,7 @@ config OLPC
depends on !X86_PAE depends on !X86_PAE
select GPIOLIB select GPIOLIB
select OF select OF
select OF_PROMTREE if PROC_DEVICETREE select OF_PROMTREE
---help--- ---help---
Add support for detecting the unique features of the OLPC Add support for detecting the unique features of the OLPC
XO hardware. XO hardware.
......
...@@ -26,15 +26,12 @@ extern void setup_olpc_ofw_pgd(void); ...@@ -26,15 +26,12 @@ extern void setup_olpc_ofw_pgd(void);
/* check if OFW was detected during boot */ /* check if OFW was detected during boot */
extern bool olpc_ofw_present(void); extern bool olpc_ofw_present(void);
extern void olpc_dt_build_devicetree(void);
#else /* !CONFIG_OLPC */ #else /* !CONFIG_OLPC */
static inline void olpc_ofw_detect(void) { } static inline void olpc_ofw_detect(void) { }
static inline void setup_olpc_ofw_pgd(void) { } static inline void setup_olpc_ofw_pgd(void) { }
#endif /* !CONFIG_OLPC */
#ifdef CONFIG_OF_PROMTREE
extern void olpc_dt_build_devicetree(void);
#else
static inline void olpc_dt_build_devicetree(void) { } static inline void olpc_dt_build_devicetree(void) { }
#endif #endif /* !CONFIG_OLPC */
#endif /* _ASM_X86_OLPC_OFW_H */ #endif /* _ASM_X86_OLPC_OFW_H */
obj-$(CONFIG_OLPC) += olpc.o obj-$(CONFIG_OLPC) += olpc.o olpc_ofw.o olpc_dt.o
obj-$(CONFIG_OLPC_XO1) += olpc-xo1.o obj-$(CONFIG_OLPC_XO1) += olpc-xo1.o
obj-$(CONFIG_OLPC) += olpc_ofw.o
obj-$(CONFIG_OF_PROMTREE) += olpc_dt.o
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/of.h>
#include <asm/geode.h> #include <asm/geode.h>
#include <asm/setup.h> #include <asm/setup.h>
...@@ -187,41 +188,43 @@ int olpc_ec_cmd(unsigned char cmd, unsigned char *inbuf, size_t inlen, ...@@ -187,41 +188,43 @@ int olpc_ec_cmd(unsigned char cmd, unsigned char *inbuf, size_t inlen,
} }
EXPORT_SYMBOL_GPL(olpc_ec_cmd); EXPORT_SYMBOL_GPL(olpc_ec_cmd);
static bool __init check_ofw_architecture(void) static bool __init check_ofw_architecture(struct device_node *root)
{ {
size_t propsize; const char *olpc_arch;
char olpc_arch[5]; int propsize;
const void *args[] = { NULL, "architecture", olpc_arch, (void *)5 };
void *res[] = { &propsize };
if (olpc_ofw("getprop", args, res)) { olpc_arch = of_get_property(root, "architecture", &propsize);
printk(KERN_ERR "ofw: getprop call failed!\n");
return false;
}
return propsize == 5 && strncmp("OLPC", olpc_arch, 5) == 0; return propsize == 5 && strncmp("OLPC", olpc_arch, 5) == 0;
} }
static u32 __init get_board_revision(void) static u32 __init get_board_revision(struct device_node *root)
{ {
size_t propsize; int propsize;
__be32 rev; const __be32 *rev;
const void *args[] = { NULL, "board-revision-int", &rev, (void *)4 };
void *res[] = { &propsize }; rev = of_get_property(root, "board-revision-int", &propsize);
if (propsize != 4)
if (olpc_ofw("getprop", args, res) || propsize != 4) { return 0;
printk(KERN_ERR "ofw: getprop call failed!\n");
return cpu_to_be32(0); return be32_to_cpu(*rev);
}
return be32_to_cpu(rev);
} }
static bool __init platform_detect(void) static bool __init platform_detect(void)
{ {
if (!check_ofw_architecture()) struct device_node *root = of_find_node_by_path("/");
bool success;
if (!root)
return false; return false;
success = check_ofw_architecture(root);
if (success) {
olpc_platform_info.boardrev = get_board_revision(root);
olpc_platform_info.flags |= OLPC_F_PRESENT; olpc_platform_info.flags |= OLPC_F_PRESENT;
olpc_platform_info.boardrev = get_board_revision(); }
return true;
of_node_put(root);
return success;
} }
static int __init add_xo1_platform_devices(void) static int __init add_xo1_platform_devices(void)
......
...@@ -19,7 +19,9 @@ ...@@ -19,7 +19,9 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/bootmem.h> #include <linux/bootmem.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/of_pdt.h> #include <linux/of_pdt.h>
#include <asm/olpc.h>
#include <asm/olpc_ofw.h> #include <asm/olpc_ofw.h>
static phandle __init olpc_dt_getsibling(phandle node) static phandle __init olpc_dt_getsibling(phandle node)
...@@ -181,3 +183,20 @@ void __init olpc_dt_build_devicetree(void) ...@@ -181,3 +183,20 @@ void __init olpc_dt_build_devicetree(void)
pr_info("PROM DT: Built device tree with %u bytes of memory.\n", pr_info("PROM DT: Built device tree with %u bytes of memory.\n",
prom_early_allocated); prom_early_allocated);
} }
/* A list of DT node/bus matches that we want to expose as platform devices */
static struct of_device_id __initdata of_ids[] = {
{ .compatible = "olpc,xo1-battery" },
{ .compatible = "olpc,xo1-dcon" },
{ .compatible = "olpc,xo1-rtc" },
{},
};
static int __init olpc_create_platform_devices(void)
{
if (machine_is_olpc())
return of_platform_bus_probe(NULL, of_ids, NULL);
else
return 0;
}
device_initcall(olpc_create_platform_devices);
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册