diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-02-26 02:38:37 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-02-26 02:38:37 +0300 |
commit | 6ebdc661b608671e9ca572af8bb42d58108cc008 (patch) | |
tree | e99caacb964a27caeae699160fa5eddcb14526e9 /drivers | |
parent | d7930c9ef9cc67044f5ddaac54d06ca22645a012 (diff) | |
parent | df0edeb59eb559be0bee53452fda2f5cc0ae133f (diff) | |
download | linux-6ebdc661b608671e9ca572af8bb42d58108cc008.tar.xz |
Merge branch 'next-devicetree' of git://git.secretlab.ca/git/linux-2.6
* 'next-devicetree' of git://git.secretlab.ca/git/linux-2.6: (41 commits)
of: remove undefined request_OF_resource & release_OF_resource
of/sparc: Remove sparc-local declaration of allnodes and devtree_lock
of: move definition of of_chosen into common code.
of: remove unused extern reference to devtree_lock
of: put default string compare and #a/s-cell values into common header
of/flattree: Don't assume HAVE_LMB
of: protect linux/of.h with CONFIG_OF
proc_devtree: fix THIS_MODULE without module.h
of: Remove old and misplaced function declarations
of/flattree: Make the kernel accept ePAPR style phandle information
of/flattree: endian-convert members of boot_param_header
of: assume big-endian properties, adding conversions where necessary
of: use __be32 for cell value accessors
of/flattree: use OF_ROOT_NODE_{SIZE,ADDR}_CELLS DEFAULT for fdt parsing
of/flattree: use callback to setup initrd from /chosen
proc_devtree: include linux/of.h
of: make set_node_proc_entry private to proc_devtree.c
of: include linux/proc_fs.h
of/flattree: merge early_init_dt_scan_memory() common code
of: add 'of_' prefix to machine_is_compatible()
...
Diffstat (limited to 'drivers')
30 files changed, 1009 insertions, 103 deletions
diff --git a/drivers/char/hvc_beat.c b/drivers/char/hvc_beat.c index 6913fc33270c..5fe4631e2a61 100644 --- a/drivers/char/hvc_beat.c +++ b/drivers/char/hvc_beat.c @@ -99,7 +99,7 @@ static int hvc_beat_config(char *p) static int __init hvc_beat_console_init(void) { - if (hvc_beat_useit && machine_is_compatible("Beat")) { + if (hvc_beat_useit && of_machine_is_compatible("Beat")) { hvc_instantiate(0, 0, &hvc_beat_get_put_ops); } return 0; diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index e7b19440102e..22d476160d52 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -1279,47 +1279,47 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) rdev->mode_info.connector_table = radeon_connector_table; if (rdev->mode_info.connector_table == CT_NONE) { #ifdef CONFIG_PPC_PMAC - if (machine_is_compatible("PowerBook3,3")) { + if (of_machine_is_compatible("PowerBook3,3")) { /* powerbook with VGA */ rdev->mode_info.connector_table = CT_POWERBOOK_VGA; - } else if (machine_is_compatible("PowerBook3,4") || - machine_is_compatible("PowerBook3,5")) { + } else if (of_machine_is_compatible("PowerBook3,4") || + of_machine_is_compatible("PowerBook3,5")) { /* powerbook with internal tmds */ rdev->mode_info.connector_table = CT_POWERBOOK_INTERNAL; - } else if (machine_is_compatible("PowerBook5,1") || - machine_is_compatible("PowerBook5,2") || - machine_is_compatible("PowerBook5,3") || - machine_is_compatible("PowerBook5,4") || - machine_is_compatible("PowerBook5,5")) { + } else if (of_machine_is_compatible("PowerBook5,1") || + of_machine_is_compatible("PowerBook5,2") || + of_machine_is_compatible("PowerBook5,3") || + of_machine_is_compatible("PowerBook5,4") || + of_machine_is_compatible("PowerBook5,5")) { /* powerbook with external single link tmds (sil164) */ rdev->mode_info.connector_table = CT_POWERBOOK_EXTERNAL; - } else if (machine_is_compatible("PowerBook5,6")) { + } else if (of_machine_is_compatible("PowerBook5,6")) { /* powerbook with external dual or single link tmds */ rdev->mode_info.connector_table = CT_POWERBOOK_EXTERNAL; - } else if (machine_is_compatible("PowerBook5,7") || - machine_is_compatible("PowerBook5,8") || - machine_is_compatible("PowerBook5,9")) { + } else if (of_machine_is_compatible("PowerBook5,7") || + of_machine_is_compatible("PowerBook5,8") || + of_machine_is_compatible("PowerBook5,9")) { /* PowerBook6,2 ? */ /* powerbook with external dual link tmds (sil1178?) */ rdev->mode_info.connector_table = CT_POWERBOOK_EXTERNAL; - } else if (machine_is_compatible("PowerBook4,1") || - machine_is_compatible("PowerBook4,2") || - machine_is_compatible("PowerBook4,3") || - machine_is_compatible("PowerBook6,3") || - machine_is_compatible("PowerBook6,5") || - machine_is_compatible("PowerBook6,7")) { + } else if (of_machine_is_compatible("PowerBook4,1") || + of_machine_is_compatible("PowerBook4,2") || + of_machine_is_compatible("PowerBook4,3") || + of_machine_is_compatible("PowerBook6,3") || + of_machine_is_compatible("PowerBook6,5") || + of_machine_is_compatible("PowerBook6,7")) { /* ibook */ rdev->mode_info.connector_table = CT_IBOOK; - } else if (machine_is_compatible("PowerMac4,4")) { + } else if (of_machine_is_compatible("PowerMac4,4")) { /* emac */ rdev->mode_info.connector_table = CT_EMAC; - } else if (machine_is_compatible("PowerMac10,1")) { + } else if (of_machine_is_compatible("PowerMac10,1")) { /* mini with internal tmds */ rdev->mode_info.connector_table = CT_MINI_INTERNAL; - } else if (machine_is_compatible("PowerMac10,2")) { + } else if (of_machine_is_compatible("PowerMac10,2")) { /* mini with external tmds */ rdev->mode_info.connector_table = CT_MINI_EXTERNAL; - } else if (machine_is_compatible("PowerMac12,1")) { + } else if (of_machine_is_compatible("PowerMac12,1")) { /* PowerMac8,1 ? */ /* imac g5 isight */ rdev->mode_info.connector_table = CT_IMAC_G5_ISIGHT; diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c index 23741cec45e3..d840a109f833 100644 --- a/drivers/macintosh/adb.c +++ b/drivers/macintosh/adb.c @@ -322,8 +322,8 @@ static int __init adb_init(void) adb_controller = NULL; } else { #ifdef CONFIG_PPC - if (machine_is_compatible("AAPL,PowerBook1998") || - machine_is_compatible("PowerBook1,1")) + if (of_machine_is_compatible("AAPL,PowerBook1998") || + of_machine_is_compatible("PowerBook1,1")) sleepy_trackpad = 1; #endif /* CONFIG_PPC */ diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index 454bc501df3c..5738d8bf2d97 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c @@ -1899,7 +1899,7 @@ static int create_control_loops(void) */ if (rackmac) cpu_pid_type = CPU_PID_TYPE_RACKMAC; - else if (machine_is_compatible("PowerMac7,3") + else if (of_machine_is_compatible("PowerMac7,3") && (cpu_count > 1) && fcu_fans[CPUA_PUMP_RPM_INDEX].id != FCU_FAN_ABSENT_ID && fcu_fans[CPUB_PUMP_RPM_INDEX].id != FCU_FAN_ABSENT_ID) { @@ -2234,10 +2234,10 @@ static int __init therm_pm72_init(void) { struct device_node *np; - rackmac = machine_is_compatible("RackMac3,1"); + rackmac = of_machine_is_compatible("RackMac3,1"); - if (!machine_is_compatible("PowerMac7,2") && - !machine_is_compatible("PowerMac7,3") && + if (!of_machine_is_compatible("PowerMac7,2") && + !of_machine_is_compatible("PowerMac7,3") && !rackmac) return -ENODEV; diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c index ba48fd76396e..7fb8b4da35a7 100644 --- a/drivers/macintosh/therm_windtunnel.c +++ b/drivers/macintosh/therm_windtunnel.c @@ -490,7 +490,7 @@ g4fan_init( void ) info = of_get_property(np, "thermal-info", NULL); of_node_put(np); - if( !info || !machine_is_compatible("PowerMac3,6") ) + if( !info || !of_machine_is_compatible("PowerMac3,6") ) return -ENODEV; if( info->id != 3 ) { diff --git a/drivers/macintosh/via-pmu-backlight.c b/drivers/macintosh/via-pmu-backlight.c index a348bb0791d3..4f3c4479c16a 100644 --- a/drivers/macintosh/via-pmu-backlight.c +++ b/drivers/macintosh/via-pmu-backlight.c @@ -150,13 +150,13 @@ void __init pmu_backlight_init() /* Special case for the old PowerBook since I can't test on it */ autosave = - machine_is_compatible("AAPL,3400/2400") || - machine_is_compatible("AAPL,3500"); + of_machine_is_compatible("AAPL,3400/2400") || + of_machine_is_compatible("AAPL,3500"); if (!autosave && !pmac_has_backlight_type("pmu") && - !machine_is_compatible("AAPL,PowerBook1998") && - !machine_is_compatible("PowerBook1,1")) + !of_machine_is_compatible("AAPL,PowerBook1998") && + !of_machine_is_compatible("PowerBook1,1")) return; snprintf(name, sizeof(name), "pmubl"); diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index db379c381432..42764849eb78 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -463,8 +463,8 @@ static int __init via_pmu_dev_init(void) #endif #ifdef CONFIG_PPC32 - if (machine_is_compatible("AAPL,3400/2400") || - machine_is_compatible("AAPL,3500")) { + if (of_machine_is_compatible("AAPL,3400/2400") || + of_machine_is_compatible("AAPL,3500")) { int mb = pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_MODEL, 0); pmu_battery_count = 1; @@ -472,8 +472,8 @@ static int __init via_pmu_dev_init(void) pmu_batteries[0].flags |= PMU_BATT_TYPE_COMET; else pmu_batteries[0].flags |= PMU_BATT_TYPE_HOOPER; - } else if (machine_is_compatible("AAPL,PowerBook1998") || - machine_is_compatible("PowerBook1,1")) { + } else if (of_machine_is_compatible("AAPL,PowerBook1998") || + of_machine_is_compatible("PowerBook1,1")) { pmu_battery_count = 2; pmu_batteries[0].flags |= PMU_BATT_TYPE_SMART; pmu_batteries[1].flags |= PMU_BATT_TYPE_SMART; diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c index 075b4d99e354..437f55c5d18d 100644 --- a/drivers/macintosh/windfarm_core.c +++ b/drivers/macintosh/windfarm_core.c @@ -468,9 +468,9 @@ static int __init windfarm_core_init(void) DBG("wf: core loaded\n"); /* Don't register on old machines that use therm_pm72 for now */ - if (machine_is_compatible("PowerMac7,2") || - machine_is_compatible("PowerMac7,3") || - machine_is_compatible("RackMac3,1")) + if (of_machine_is_compatible("PowerMac7,2") || + of_machine_is_compatible("PowerMac7,3") || + of_machine_is_compatible("RackMac3,1")) return -ENODEV; platform_device_register(&wf_platform_device); return 0; diff --git a/drivers/macintosh/windfarm_cpufreq_clamp.c b/drivers/macintosh/windfarm_cpufreq_clamp.c index 900aade06198..1a77a7c97d0e 100644 --- a/drivers/macintosh/windfarm_cpufreq_clamp.c +++ b/drivers/macintosh/windfarm_cpufreq_clamp.c @@ -76,9 +76,9 @@ static int __init wf_cpufreq_clamp_init(void) struct wf_control *clamp; /* Don't register on old machines that use therm_pm72 for now */ - if (machine_is_compatible("PowerMac7,2") || - machine_is_compatible("PowerMac7,3") || - machine_is_compatible("RackMac3,1")) + if (of_machine_is_compatible("PowerMac7,2") || + of_machine_is_compatible("PowerMac7,3") || + of_machine_is_compatible("RackMac3,1")) return -ENODEV; clamp = kmalloc(sizeof(struct wf_control), GFP_KERNEL); diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c index ed6426a10773..d8257d35afde 100644 --- a/drivers/macintosh/windfarm_lm75_sensor.c +++ b/drivers/macintosh/windfarm_lm75_sensor.c @@ -239,9 +239,9 @@ static struct i2c_driver wf_lm75_driver = { static int __init wf_lm75_sensor_init(void) { /* Don't register on old machines that use therm_pm72 for now */ - if (machine_is_compatible("PowerMac7,2") || - machine_is_compatible("PowerMac7,3") || - machine_is_compatible("RackMac3,1")) + if (of_machine_is_compatible("PowerMac7,2") || + of_machine_is_compatible("PowerMac7,3") || + of_machine_is_compatible("RackMac3,1")) return -ENODEV; return i2c_add_driver(&wf_lm75_driver); } diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c index a67b349319e9..b486eb929fde 100644 --- a/drivers/macintosh/windfarm_max6690_sensor.c +++ b/drivers/macintosh/windfarm_max6690_sensor.c @@ -188,9 +188,9 @@ static struct i2c_driver wf_max6690_driver = { static int __init wf_max6690_sensor_init(void) { /* Don't register on old machines that use therm_pm72 for now */ - if (machine_is_compatible("PowerMac7,2") || - machine_is_compatible("PowerMac7,3") || - machine_is_compatible("RackMac3,1")) + if (of_machine_is_compatible("PowerMac7,2") || + of_machine_is_compatible("PowerMac7,3") || + of_machine_is_compatible("RackMac3,1")) return -ENODEV; return i2c_add_driver(&wf_max6690_driver); } diff --git a/drivers/macintosh/windfarm_pm112.c b/drivers/macintosh/windfarm_pm112.c index 73d695dc9e50..e0ee80700cde 100644 --- a/drivers/macintosh/windfarm_pm112.c +++ b/drivers/macintosh/windfarm_pm112.c @@ -676,7 +676,7 @@ static int __init wf_pm112_init(void) { struct device_node *cpu; - if (!machine_is_compatible("PowerMac11,2")) + if (!of_machine_is_compatible("PowerMac11,2")) return -ENODEV; /* Count the number of CPU cores */ diff --git a/drivers/macintosh/windfarm_pm121.c b/drivers/macintosh/windfarm_pm121.c index 66ec4fb115bb..947d4afa25ca 100644 --- a/drivers/macintosh/windfarm_pm121.c +++ b/drivers/macintosh/windfarm_pm121.c @@ -1008,7 +1008,7 @@ static int __init pm121_init(void) { int rc = -ENODEV; - if (machine_is_compatible("PowerMac12,1")) + if (of_machine_is_compatible("PowerMac12,1")) rc = pm121_init_pm(); if (rc == 0) { diff --git a/drivers/macintosh/windfarm_pm81.c b/drivers/macintosh/windfarm_pm81.c index abbe206474f5..565d5b2adc95 100644 --- a/drivers/macintosh/windfarm_pm81.c +++ b/drivers/macintosh/windfarm_pm81.c @@ -779,8 +779,8 @@ static int __init wf_smu_init(void) { int rc = -ENODEV; - if (machine_is_compatible("PowerMac8,1") || - machine_is_compatible("PowerMac8,2")) + if (of_machine_is_compatible("PowerMac8,1") || + of_machine_is_compatible("PowerMac8,2")) rc = wf_init_pm(); if (rc == 0) { diff --git a/drivers/macintosh/windfarm_pm91.c b/drivers/macintosh/windfarm_pm91.c index 764c525b2117..bea99168ff35 100644 --- a/drivers/macintosh/windfarm_pm91.c +++ b/drivers/macintosh/windfarm_pm91.c @@ -711,7 +711,7 @@ static int __init wf_smu_init(void) { int rc = -ENODEV; - if (machine_is_compatible("PowerMac9,1")) + if (of_machine_is_compatible("PowerMac9,1")) rc = wf_init_pm(); if (rc == 0) { diff --git a/drivers/macintosh/windfarm_smu_sensors.c b/drivers/macintosh/windfarm_smu_sensors.c index 9c567b93f417..3c193504bb80 100644 --- a/drivers/macintosh/windfarm_smu_sensors.c +++ b/drivers/macintosh/windfarm_smu_sensors.c @@ -363,9 +363,9 @@ smu_cpu_power_create(struct wf_sensor *volts, struct wf_sensor *amps) * I yet have to figure out what's up with 8,2 and will have to * adjust for later, unless we can 100% trust the SDB partition... */ - if ((machine_is_compatible("PowerMac8,1") || - machine_is_compatible("PowerMac8,2") || - machine_is_compatible("PowerMac9,1")) && + if ((of_machine_is_compatible("PowerMac8,1") || + of_machine_is_compatible("PowerMac8,2") || + of_machine_is_compatible("PowerMac9,1")) && cpuvcp_version >= 2) { pow->quadratic = 1; DBG("windfarm: CPU Power using quadratic transform\n"); diff --git a/drivers/net/mace.c b/drivers/net/mace.c index d9fbad386389..43aea91e3369 100644 --- a/drivers/net/mace.c +++ b/drivers/net/mace.c @@ -206,7 +206,7 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i mp->port_aaui = port_aaui; else { /* Apple Network Server uses the AAUI port */ - if (machine_is_compatible("AAPL,ShinerESB")) + if (of_machine_is_compatible("AAPL,ShinerESB")) mp->port_aaui = 1; else { #ifdef CONFIG_MACE_AAUI_PORT diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index d2fa27c5c1b2..7cecc8fea9bd 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -1,3 +1,11 @@ +config OF_FLATTREE + bool + depends on OF + +config OF_DYNAMIC + def_bool y + depends on OF && PPC_OF + config OF_DEVICE def_bool y depends on OF && (SPARC || PPC_OF || MICROBLAZE) diff --git a/drivers/of/Makefile b/drivers/of/Makefile index bdfb5f5d4b06..f232cc98ce00 100644 --- a/drivers/of/Makefile +++ b/drivers/of/Makefile @@ -1,4 +1,5 @@ obj-y = base.o +obj-$(CONFIG_OF_FLATTREE) += fdt.o obj-$(CONFIG_OF_DEVICE) += device.o platform.o obj-$(CONFIG_OF_GPIO) += gpio.o obj-$(CONFIG_OF_I2C) += of_i2c.o diff --git a/drivers/of/base.c b/drivers/of/base.c index e6627b2320f1..cb96888d1427 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -20,8 +20,10 @@ #include <linux/module.h> #include <linux/of.h> #include <linux/spinlock.h> +#include <linux/proc_fs.h> struct device_node *allnodes; +struct device_node *of_chosen; /* use when traversing tree through the allnext, child, sibling, * or parent members of struct device_node. @@ -37,7 +39,7 @@ int of_n_addr_cells(struct device_node *np) np = np->parent; ip = of_get_property(np, "#address-cells", NULL); if (ip) - return *ip; + return be32_to_cpup(ip); } while (np->parent); /* No #address-cells property for the root node */ return OF_ROOT_NODE_ADDR_CELLS_DEFAULT; @@ -53,13 +55,88 @@ int of_n_size_cells(struct device_node *np) np = np->parent; ip = of_get_property(np, "#size-cells", NULL); if (ip) - return *ip; + return be32_to_cpup(ip); } while (np->parent); /* No #size-cells property for the root node */ return OF_ROOT_NODE_SIZE_CELLS_DEFAULT; } EXPORT_SYMBOL(of_n_size_cells); +#if !defined(CONFIG_SPARC) /* SPARC doesn't do ref counting (yet) */ +/** + * of_node_get - Increment refcount of a node + * @node: Node to inc refcount, NULL is supported to + * simplify writing of callers + * + * Returns node. + */ +struct device_node *of_node_get(struct device_node *node) +{ + if (node) + kref_get(&node->kref); + return node; +} +EXPORT_SYMBOL(of_node_get); + +static inline struct device_node *kref_to_device_node(struct kref *kref) +{ + return container_of(kref, struct device_node, kref); +} + +/** + * of_node_release - release a dynamically allocated node + * @kref: kref element of the node to be released + * + * In of_node_put() this function is passed to kref_put() + * as the destructor. + */ +static void of_node_release(struct kref *kref) +{ + struct device_node *node = kref_to_device_node(kref); + struct property *prop = node->properties; + + /* We should never be releasing nodes that haven't been detached. */ + if (!of_node_check_flag(node, OF_DETACHED)) { + pr_err("ERROR: Bad of_node_put() on %s\n", node->full_name); + dump_stack(); + kref_init(&node->kref); + return; + } + + if (!of_node_check_flag(node, OF_DYNAMIC)) + return; + + while (prop) { + struct property *next = prop->next; + kfree(prop->name); + kfree(prop->value); + kfree(prop); + prop = next; + + if (!prop) { + prop = node->deadprops; + node->deadprops = NULL; + } + } + kfree(node->full_name); + kfree(node->data); + kfree(node); +} + +/** + * of_node_put - Decrement refcount of a node + * @node: Node to dec refcount, NULL is supported to + * simplify writing of callers + * + */ +void of_node_put(struct device_node *node) +{ + if (node) + kref_put(&node->kref, of_node_release); +} +EXPORT_SYMBOL(of_node_put); +#endif /* !CONFIG_SPARC */ + struct property *of_find_property(const struct device_node *np, const char *name, int *lenp) @@ -144,6 +221,27 @@ int of_device_is_compatible(const struct device_node *device, EXPORT_SYMBOL(of_device_is_compatible); /** + * of_machine_is_compatible - Test root of device tree for a given compatible value + * @compat: compatible string to look for in root node's compatible property. + * + * Returns true if the root node has the given value in its + * compatible property. + */ +int of_machine_is_compatible(const char *compat) +{ + struct device_node *root; + int rc = 0; + + root = of_find_node_by_path("/"); + if (root) { + rc = of_device_is_compatible(root, compat); + of_node_put(root); + } + return rc; +} +EXPORT_SYMBOL(of_machine_is_compatible); + +/** * of_device_is_available - check if a device is available for use * * @device: Node to check for availability @@ -519,6 +617,27 @@ int of_modalias_node(struct device_node *node, char *modalias, int len) EXPORT_SYMBOL_GPL(of_modalias_node); /** + * of_find_node_by_phandle - Find a node given a phandle + * @handle: phandle of the node to find + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_find_node_by_phandle(phandle handle) +{ + struct device_node *np; + + read_lock(&devtree_lock); + for (np = allnodes; np; np = np->allnext) + if (np->phandle == handle) + break; + of_node_get(np); + read_unlock(&devtree_lock); + return np; +} +EXPORT_SYMBOL(of_find_node_by_phandle); + +/** * of_parse_phandle - Resolve a phandle property to a device_node pointer * @np: Pointer to device node holding phandle property * @phandle_name: Name of property holding a phandle value @@ -578,8 +697,8 @@ int of_parse_phandles_with_args(struct device_node *np, const char *list_name, const void **out_args) { int ret = -EINVAL; - const u32 *list; - const u32 *list_end; + const __be32 *list; + const __be32 *list_end; int size; int cur_index = 0; struct device_node *node = NULL; @@ -593,7 +712,7 @@ int of_parse_phandles_with_args(struct device_node *np, const char *list_name, list_end = list + size / sizeof(*list); while (list < list_end) { - const u32 *cells; + const __be32 *cells; const phandle *phandle; phandle = list++; @@ -617,7 +736,7 @@ int of_parse_phandles_with_args(struct device_node *np, const char *list_name, goto err1; } - list += *cells; + list += be32_to_cpup(cells); if (list > list_end) { pr_debug("%s: insufficient arguments length\n", np->full_name); @@ -658,3 +777,190 @@ err0: return ret; } EXPORT_SYMBOL(of_parse_phandles_with_args); + +/** + * prom_add_property - Add a property to a node + */ +int prom_add_property(struct device_node *np, struct property *prop) +{ + struct property **next; + unsigned long flags; + + prop->next = NULL; + write_lock_irqsave(&devtree_lock, flags); + next = &np->properties; + while (*next) { + if (strcmp(prop->name, (*next)->name) == 0) { + /* duplicate ! don't insert it */ + write_unlock_irqrestore(&devtree_lock, flags); + return -1; + } + next = &(*next)->next; + } + *next = prop; + write_unlock_irqrestore(&devtree_lock, flags); + +#ifdef CONFIG_PROC_DEVICETREE + /* try to add to proc as well if it was initialized */ + if (np->pde) + proc_device_tree_add_prop(np->pde, prop); +#endif /* CONFIG_PROC_DEVICETREE */ + + return 0; +} + +/** + * prom_remove_property - Remove a property from a node. + * + * Note that we don't actually remove it, since we have given out + * who-knows-how-many pointers to the data using get-property. + * Instead we just move the property to the "dead properties" + * list, so it won't be found any more. + */ +int prom_remove_property(struct device_node *np, struct property *prop) +{ + struct property **next; + unsigned long flags; + int found = 0; + + write_lock_irqsave(&devtree_lock, flags); + next = &np->properties; + while (*next) { + if (*next == prop) { + /* found the node */ + *next = prop->next; + prop->next = np->deadprops; + np->deadprops = prop; + found = 1; + break; + } + next = &(*next)->next; + } + write_unlock_irqrestore(&devtree_lock, flags); + + if (!found) + return -ENODEV; + +#ifdef CONFIG_PROC_DEVICETREE + /* try to remove the proc node as well */ + if (np->pde) + proc_device_tree_remove_prop(np->pde, prop); +#endif /* CONFIG_PROC_DEVICETREE */ + + return 0; +} + +/* + * prom_update_property - Update a property in a node. + * + * Note that we don't actually remove it, since we have given out + * who-knows-how-many pointers to the data using get-property. + * Instead we just move the property to the "dead properties" list, + * and add the new property to the property list + */ +int prom_update_property(struct device_node *np, + struct property *newprop, + struct property *oldprop) +{ + struct property **next; + unsigned long flags; + int found = 0; + + write_lock_irqsave(&devtree_lock, flags); + next = &np->properties; + while (*next) { + if (*next == oldprop) { + /* found the node */ + newprop->next = oldprop->next; + *next = newprop; + oldprop->next = np->deadprops; + np->deadprops = oldprop; + found = 1; + break; + } + next = &(*next)->next; + } + write_unlock_irqrestore(&devtree_lock, flags); + + if (!found) + return -ENODEV; + +#ifdef CONFIG_PROC_DEVICETREE + /* try to add to proc as well if it was initialized */ + if (np->pde) + proc_device_tree_update_prop(np->pde, newprop, oldprop); +#endif /* CONFIG_PROC_DEVICETREE */ + + return 0; +} + +#if defined(CONFIG_OF_DYNAMIC) +/* + * Support for dynamic device trees. + * + * On some platforms, the device tree can be manipulated at runtime. + * The routines in this section support adding, removing and changing + * device tree nodes. + */ + +/** + * of_attach_node - Plug a device node into the tree and global list. + */ +void of_attach_node(struct device_node *np) +{ + unsigned long flags; + + write_lock_irqsave(&devtree_lock, flags); + np->sibling = np->parent->child; + np->allnext = allnodes; + np->parent->child = np; + allnodes = np; + write_unlock_irqrestore(&devtree_lock, flags); +} + +/** + * of_detach_node - "Unplug" a node from the device tree. + * + * The caller must hold a reference to the node. The memory associated with + * the node is not freed until its refcount goes to zero. + */ +void of_detach_node(struct device_node *np) +{ + struct device_node *parent; + unsigned long flags; + + write_lock_irqsave(&devtree_lock, flags); + + parent = np->parent; + if (!parent) + goto out_unlock; + + if (allnodes == np) + allnodes = np->allnext; + else { + struct device_node *prev; + for (prev = allnodes; + prev->allnext != np; + prev = prev->allnext) + ; + prev->allnext = np->allnext; + } + + if (parent->child == np) + parent->child = np->sibling; + else { + struct device_node *prevsib; + for (prevsib = np->parent->child; + prevsib->sibling != np; + prevsib = prevsib->sibling) + ; + prevsib->sibling = np->sibling; + } + + of_node_set_flag(np, OF_DETACHED); + +out_unlock: + write_unlock_irqrestore(&devtree_lock, flags); +} +#endif /* defined(CONFIG_OF_DYNAMIC) */ + diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c new file mode 100644 index 000000000000..406757a9d7ea --- /dev/null +++ b/drivers/of/fdt.c @@ -0,0 +1,590 @@ +/* + * Functions for working with the Flattened Device Tree data format + * + * Copyright 2009 Benjamin Herrenschmidt, IBM Corp + * benh@kernel.crashing.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/initrd.h> +#include <linux/of.h> +#include <linux/of_fdt.h> +#include <linux/string.h> +#include <linux/errno.h> + +#ifdef CONFIG_PPC +#include <asm/machdep.h> +#endif /* CONFIG_PPC */ + +#include <asm/page.h> + +int __initdata dt_root_addr_cells; +int __initdata dt_root_size_cells; + +struct boot_param_header *initial_boot_params; + +char *find_flat_dt_string(u32 offset) +{ + return ((char *)initial_boot_params) + + be32_to_cpu(initial_boot_params->off_dt_strings) + offset; +} + +/** + * of_scan_flat_dt - scan flattened tree blob and call callback on each. + * @it: callback function + * @data: context data pointer + * + * This function is used to scan the flattened device-tree, it is + * used to extract the memory information at boot before we can + * unflatten the tree + */ +int __init of_scan_flat_dt(int (*it)(unsigned long node, + const char *uname, int depth, + void *data), + void *data) +{ + unsigned long p = ((unsigned long)initial_boot_params) + + be32_to_cpu(initial_boot_params->off_dt_struct); + int rc = 0; + int depth = -1; + + do { + u32 tag = be32_to_cpup((__be32 *)p); + char *pathp; + + p += 4; + if (tag == OF_DT_END_NODE) { + depth--; + continue; + } + if (tag == OF_DT_NOP) + continue; + if (tag == OF_DT_END) + break; + if (tag == OF_DT_PROP) { + u32 sz = be32_to_cpup((__be32 *)p); + p += 8; + if (be32_to_cpu(initial_boot_params->version) < 0x10) + p = _ALIGN(p, sz >= 8 ? 8 : 4); + p += sz; + p = _ALIGN(p, 4); + continue; + } + if (tag != OF_DT_BEGIN_NODE) { + pr_err("Invalid tag %x in flat device tree!\n", tag); + return -EINVAL; + } + depth++; + pathp = (char *)p; + p = _ALIGN(p + strlen(pathp) + 1, 4); + if ((*pathp) == '/') { + char *lp, *np; + for (lp = NULL, np = pathp; *np; np++) + if ((*np) == '/') + lp = np+1; + if (lp != NULL) + pathp = lp; + } + rc = it(p, pathp, depth, data); + if (rc != 0) + break; + } while (1); + + return rc; +} + +/** + * of_get_flat_dt_root - find the root node in the flat blob + */ +unsigned long __init of_get_flat_dt_root(void) +{ + unsigned long p = ((unsigned long)initial_boot_params) + + be32_to_cpu(initial_boot_params->off_dt_struct); + + while (be32_to_cpup((__be32 *)p) == OF_DT_NOP) + p += 4; + BUG_ON(be32_to_cpup((__be32 *)p) != OF_DT_BEGIN_NODE); + p += 4; + return _ALIGN(p + strlen((char *)p) + 1, 4); +} + +/** + * of_get_flat_dt_prop - Given a node in the flat blob, return the property ptr + * + * This function can be used within scan_flattened_dt callback to get + * access to properties + */ +void *__init of_get_flat_dt_prop(unsigned long node, const char *name, + unsigned long *size) +{ + unsigned long p = node; + + do { + u32 tag = be32_to_cpup((__be32 *)p); + u32 sz, noff; + const char *nstr; + + p += 4; + if (tag == OF_DT_NOP) + continue; + if (tag != OF_DT_PROP) + return NULL; + + sz = be32_to_cpup((__be32 *)p); + noff = be32_to_cpup((__be32 *)(p + 4)); + p += 8; + if (be32_to_cpu(initial_boot_params->version) < 0x10) + p = _ALIGN(p, sz >= 8 ? 8 : 4); + + nstr = find_flat_dt_string(noff); + if (nstr == NULL) { + pr_warning("Can't find property index name !\n"); + return NULL; + } + if (strcmp(name, nstr) == 0) { + if (size) + *size = sz; + return (void *)p; + } + p += sz; + p = _ALIGN(p, 4); + } while (1); +} + +/** + * of_flat_dt_is_compatible - Return true if given node has compat in compatible list + * @node: node to test + * @compat: compatible string to compare with compatible list. + */ +int __init of_flat_dt_is_compatible(unsigned long node, const char *compat) +{ + const char *cp; + unsigned long cplen, l; + + cp = of_get_flat_dt_prop(node, "compatible", &cplen); + if (cp == NULL) + return 0; + while (cplen > 0) { + if (strncasecmp(cp, compat, strlen(compat)) == 0) + return 1; + l = strlen(cp) + 1; + cp += l; + cplen -= l; + } + + return 0; +} + +static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size, + unsigned long align) +{ + void *res; + + *mem = _ALIGN(*mem, align); + res = (void *)*mem; + *mem += size; + + return res; +} + +/** + * unflatten_dt_node - Alloc and populate a device_node from the flat tree + * @p: pointer to node in flat tree + * @dad: Parent struct device_node + * @allnextpp: pointer to ->allnext from last allocated device_node + * @fpsize: Size of the node path up at the current depth. + */ +unsigned long __init unflatten_dt_node(unsigned long mem, + unsigned long *p, + struct device_node *dad, + struct device_node ***allnextpp, + unsigned long fpsize) +{ + struct device_node *np; + struct property *pp, **prev_pp = NULL; + char *pathp; + u32 tag; + unsigned int l, allocl; + int has_name = 0; + int new_format = 0; + + tag = be32_to_cpup((__be32 *)(*p)); + if (tag != OF_DT_BEGIN_NODE) { + pr_err("Weird tag at start of node: %x\n", tag); + return mem; + } + *p += 4; + pathp = (char *)*p; + l = allocl = strlen(pathp) + 1; + *p = _ALIGN(*p + l, 4); + + /* version 0x10 has a more compact unit name here instead of the full + * path. we accumulate the full path size using "fpsize", we'll rebuild + * it later. We detect this because the first character of the name is + * not '/'. + */ + if ((*pathp) != '/') { + new_format = 1; + if (fpsize == 0) { + /* root node: special case. fpsize accounts for path + * plus terminating zero. root node only has '/', so + * fpsize should be 2, but we want to avoid the first + * level nodes to have two '/' so we use fpsize 1 here + */ + fpsize = 1; + allocl = 2; + } else { + /* account for '/' and path size minus terminal 0 + * already in 'l' + */ + fpsize += l; + allocl = fpsize; + } + } + + np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl, + __alignof__(struct device_node)); + if (allnextpp) { + memset(np, 0, sizeof(*np)); + np->full_name = ((char *)np) + sizeof(struct device_node); + if (new_format) { + char *fn = np->full_name; + /* rebuild full path for new format */ + if (dad && dad->parent) { + strcpy(fn, dad->full_name); +#ifdef DEBUG + if ((strlen(fn) + l + 1) != allocl) { + pr_debug("%s: p: %d, l: %d, a: %d\n", + pathp, (int)strlen(fn), + l, allocl); + } +#endif + fn += strlen(fn); + } + *(fn++) = '/'; + memcpy(fn, pathp, l); + } else + memcpy(np->full_name, pathp, l); + prev_pp = &np->properties; + **allnextpp = np; + *allnextpp = &np->allnext; + if (dad != NULL) { + np->parent = dad; + /* we temporarily use the next field as `last_child'*/ + if (dad->next == NULL) + dad->child = np; + else + dad->next->sibling = np; + dad->next = np; + } + kref_init(&np->kref); + } + while (1) { + u32 sz, noff; + char *pname; + + tag = be32_to_cpup((__be32 *)(*p)); + if (tag == OF_DT_NOP) { + *p += 4; + continue; + } + if (tag != OF_DT_PROP) + break; + *p += 4; + sz = be32_to_cpup((__be32 *)(*p)); + noff = be32_to_cpup((__be32 *)((*p) + 4)); + *p += 8; + if (be32_to_cpu(initial_boot_params->version) < 0x10) + *p = _ALIGN(*p, sz >= 8 ? 8 : 4); + + pname = find_flat_dt_string(noff); + if (pname == NULL) { + pr_info("Can't find property name in list !\n"); + break; + } + if (strcmp(pname, "name") == 0) + has_name = 1; + l = strlen(pname) + 1; + pp = unflatten_dt_alloc(&mem, sizeof(struct property), + __alignof__(struct property)); + if (allnextpp) { + /* We accept flattened tree phandles either in + * ePAPR-style "phandle" properties, or the + * legacy "linux,phandle" properties. If both + * appear and have different values, things + * will get weird. Don't do that. */ + if ((strcmp(pname, "phandle") == 0) || + (strcmp(pname, "linux,phandle") == 0)) { + if (np->phandle == 0) + np->phandle = *((u32 *)*p); + } + /* And we process the "ibm,phandle" property + * used in pSeries dynamic device tree + * stuff */ + if (strcmp(pname, "ibm,phandle") == 0) + np->phandle = *((u32 *)*p); + pp->name = pname; + pp->length = sz; + pp->value = (void *)*p; + *prev_pp = pp; + prev_pp = &pp->next; + } + *p = _ALIGN((*p) + sz, 4); + } + /* with version 0x10 we may not have the name property, recreate + * it here from the unit name if absent + */ + if (!has_name) { + char *p1 = pathp, *ps = pathp, *pa = NULL; + int sz; + + while (*p1) { + if ((*p1) == '@') + pa = p1; + if ((*p1) == '/') + ps = p1 + 1; + p1++; + } + if (pa < ps) + pa = p1; + sz = (pa - ps) + 1; + pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz, + __alignof__(struct property)); + if (allnextpp) { + pp->name = "name"; + pp->length = sz; + pp->value = pp + 1; + *prev_pp = pp; + prev_pp = &pp->next; + memcpy(pp->value, ps, sz - 1); + ((char *)pp->value)[sz - 1] = 0; + pr_debug("fixed up name for %s -> %s\n", pathp, + (char *)pp->value); + } + } + if (allnextpp) { + *prev_pp = NULL; + np->name = of_get_property(np, "name", NULL); + np->type = of_get_property(np, "device_type", NULL); + + if (!np->name) + np->name = "<NULL>"; + if (!np->type) + np->type = "<NULL>"; + } + while (tag == OF_DT_BEGIN_NODE) { + mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize); + tag = be32_to_cpup((__be32 *)(*p)); + } + if (tag != OF_DT_END_NODE) { + pr_err("Weird tag at end of node: %x\n", tag); + return mem; + } + *p += 4; + return mem; +} + +#ifdef CONFIG_BLK_DEV_INITRD +/** + * early_init_dt_check_for_initrd - Decode initrd location from flat tree + * @node: reference to node containing initrd location ('chosen') + */ +void __init early_init_dt_check_for_initrd(unsigned long node) +{ + unsigned long start, end, len; + __be32 *prop; + + pr_debug("Looking for initrd properties... "); + + prop = of_get_flat_dt_prop(node, "linux,initrd-start", &len); + if (!prop) + return; + start = of_read_ulong(prop, len/4); + + prop = of_get_flat_dt_prop(node, "linux,initrd-end", &len); + if (!prop) + return; + end = of_read_ulong(prop, len/4); + + early_init_dt_setup_initrd_arch(start, end); + pr_debug("initrd_start=0x%lx initrd_end=0x%lx\n", start, end); +} +#else +inline void early_init_dt_check_for_initrd(unsigned long node) +{ +} +#endif /* CONFIG_BLK_DEV_INITRD */ + +/** + * early_init_dt_scan_root - fetch the top level address and size cells + */ +int __init early_init_dt_scan_root(unsigned long node, const char *uname, + int depth, void *data) +{ + __be32 *prop; + + if (depth != 0) + return 0; + + dt_root_size_cells = OF_ROOT_NODE_SIZE_CELLS_DEFAULT; + dt_root_addr_cells = OF_ROOT_NODE_ADDR_CELLS_DEFAULT; + + prop = of_get_flat_dt_prop(node, "#size-cells", NULL); + if (prop) + dt_root_size_cells = be32_to_cpup(prop); + pr_debug("dt_root_size_cells = %x\n", dt_root_size_cells); + + prop = of_get_flat_dt_prop(node, "#address-cells", NULL); + if (prop) + dt_root_addr_cells = be32_to_cpup(prop); + pr_debug("dt_root_addr_cells = %x\n", dt_root_addr_cells); + + /* break now */ + return 1; +} + +u64 __init dt_mem_next_cell(int s, __be32 **cellp) +{ + __be32 *p = *cellp; + + *cellp = p + s; + return of_read_number(p, s); +} + +/** + * early_init_dt_scan_memory - Look for an parse memory nodes + */ +int __init early_init_dt_scan_memory(unsigned long node, const char *uname, + int depth, void *data) +{ + char *type = of_get_flat_dt_prop(node, "device_type", NULL); + __be32 *reg, *endp; + unsigned long l; + + /* We are scanning "memory" nodes only */ + if (type == NULL) { + /* + * The longtrail doesn't have a device_type on the + * /memory node, so look for the node called /memory@0. + */ + if (depth != 1 || strcmp(uname, "memory@0") != 0) + return 0; + } else if (strcmp(type, "memory") != 0) + return 0; + + reg = of_get_flat_dt_prop(node, "linux,usable-memory", &l); + if (reg == NULL) + reg = of_get_flat_dt_prop(node, "reg", &l); + if (reg == NULL) + return 0; + + endp = reg + (l / sizeof(__be32)); + + pr_debug("memory scan node %s, reg size %ld, data: %x %x %x %x,\n", + uname, l, reg[0], reg[1], reg[2], reg[3]); + + while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) { + u64 base, size; + + base = dt_mem_next_cell(dt_root_addr_cells, ®); + size = dt_mem_next_cell(dt_root_size_cells, ®); + + if (size == 0) + continue; + pr_debug(" - %llx , %llx\n", (unsigned long long)base, + (unsigned long long)size); + + early_init_dt_add_memory_arch(base, size); + } + + return 0; +} + +int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, + int depth, void *data) +{ + unsigned long l; + char *p; + + pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname); + + if (depth != 1 || + (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0)) + return 0; + + early_init_dt_check_for_initrd(node); + + /* Retreive command line */ + p = of_get_flat_dt_prop(node, "bootargs", &l); + if (p != NULL && l > 0) + strlcpy(cmd_line, p, min((int)l, COMMAND_LINE_SIZE)); + +#ifdef CONFIG_CMDLINE +#ifndef CONFIG_CMDLINE_FORCE + if (p == NULL || l == 0 || (l == 1 && (*p) == 0)) +#endif + strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE); +#endif /* CONFIG_CMDLINE */ + + early_init_dt_scan_chosen_arch(node); + + pr_debug("Command line is: %s\n", cmd_line); + + /* break now */ + return 1; +} + +/** + * unflatten_device_tree - create tree of device_nodes from flat blob + * + * unflattens the device-tree passed by the firmware, creating the + * tree of struct device_node. It also fills the "name" and "type" + * pointers of the nodes so the normal device-tree walking functions + * can be used. + */ +void __init unflatten_device_tree(void) +{ + unsigned long start, mem, size; + struct device_node **allnextp = &allnodes; + + pr_debug(" -> unflatten_device_tree()\n"); + + /* First pass, scan for size */ + start = ((unsigned long)initial_boot_params) + + be32_to_cpu(initial_boot_params->off_dt_struct); + size = unflatten_dt_node(0, &start, NULL, NULL, 0); + size = (size | 3) + 1; + + pr_debug(" size is %lx, allocating...\n", size); + + /* Allocate memory for the expanded device tree */ + mem = early_init_dt_alloc_memory_arch(size + 4, + __alignof__(struct device_node)); + mem = (unsigned long) __va(mem); + + ((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef); + + pr_debug(" unflattening %lx...\n", mem); + + /* Second pass, do actual unflattening */ + start = ((unsigned long)initial_boot_params) + + be32_to_cpu(initial_boot_params->off_dt_struct); + unflatten_dt_node(mem, &start, NULL, &allnextp, 0); + if (be32_to_cpup((__be32 *)start) != OF_DT_END) + pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start)); + if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef) + pr_warning("End of tree marker overwritten: %08x\n", + be32_to_cpu(((__be32 *)mem)[size / 4])); + *allnextp = NULL; + + /* Get pointer to OF "/chosen" node for use everywhere */ + of_chosen = of_find_node_by_path("/chosen"); + if (of_chosen == NULL) + of_chosen = of_find_node_by_path("/chosen@0"); + + pr_debug(" <- unflatten_device_tree()\n"); +} diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c index 6eea601a9204..24c3606217f8 100644 --- a/drivers/of/gpio.c +++ b/drivers/of/gpio.c @@ -36,7 +36,7 @@ int of_get_gpio_flags(struct device_node *np, int index, struct of_gpio_chip *of_gc = NULL; int size; const void *gpio_spec; - const u32 *gpio_cells; + const __be32 *gpio_cells; ret = of_parse_phandles_with_args(np, "gpios", "#gpio-cells", index, &gc, &gpio_spec); @@ -55,7 +55,7 @@ int of_get_gpio_flags(struct device_node *np, int index, gpio_cells = of_get_property(gc, "#gpio-cells", &size); if (!gpio_cells || size != sizeof(*gpio_cells) || - *gpio_cells != of_gc->gpio_cells) { + be32_to_cpup(gpio_cells) != of_gc->gpio_cells) { pr_debug("%s: wrong #gpio-cells for %s\n", np->full_name, gc->full_name); ret = -EINVAL; @@ -127,7 +127,8 @@ EXPORT_SYMBOL(of_gpio_count); int of_gpio_simple_xlate(struct of_gpio_chip *of_gc, struct device_node *np, const void *gpio_spec, enum of_gpio_flags *flags) { - const u32 *gpio = gpio_spec; + const __be32 *gpio = gpio_spec; + const u32 n = be32_to_cpup(gpio); /* * We're discouraging gpio_cells < 2, since that way you'll have to @@ -140,13 +141,13 @@ int of_gpio_simple_xlate(struct of_gpio_chip *of_gc, struct device_node *np, return -EINVAL; } - if (*gpio > of_gc->gc.ngpio) + if (n > of_gc->gc.ngpio) return -EINVAL; if (flags) - *flags = gpio[1]; + *flags = be32_to_cpu(gpio[1]); - return *gpio; + return n; } EXPORT_SYMBOL(of_gpio_simple_xlate); diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c index fa65a2b2ae2e..a3a708e590d0 100644 --- a/drivers/of/of_i2c.c +++ b/drivers/of/of_i2c.c @@ -25,7 +25,7 @@ void of_register_i2c_devices(struct i2c_adapter *adap, for_each_child_of_node(adap_node, node) { struct i2c_board_info info = {}; struct dev_archdata dev_ad = {}; - const u32 *addr; + const __be32 *addr; int len; if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) @@ -40,7 +40,7 @@ void of_register_i2c_devices(struct i2c_adapter *adap, info.irq = irq_of_parse_and_map(node, 0); - info.addr = *addr; + info.addr = be32_to_cpup(addr); dev_archdata_set_node(&dev_ad, node); info.archdata = &dev_ad; diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index 4b22ba568b19..18ecae4a4375 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c @@ -51,7 +51,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) /* Loop over the child nodes and register a phy_device for each one */ for_each_child_of_node(np, child) { - const u32 *addr; + const __be32 *addr; int len; /* A PHY must have a reg property in the range [0-31] */ @@ -68,7 +68,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) mdio->irq[*addr] = PHY_POLL; } - phy = get_phy_device(mdio, *addr); + phy = get_phy_device(mdio, be32_to_cpup(addr)); if (!phy) { dev_err(&mdio->dev, "error probing PHY at address %i\n", *addr); @@ -160,7 +160,7 @@ struct phy_device *of_phy_connect_fixed_link(struct net_device *dev, struct device_node *net_np; char bus_id[MII_BUS_ID_SIZE + 3]; struct phy_device *phy; - const u32 *phy_id; + const __be32 *phy_id; int sz; if (!dev->dev.parent) @@ -174,7 +174,7 @@ struct phy_device *of_phy_connect_fixed_link(struct net_device *dev, if (!phy_id || sz < sizeof(*phy_id)) return NULL; - sprintf(bus_id, PHY_ID_FMT, "0", phy_id[0]); + sprintf(bus_id, PHY_ID_FMT, "0", be32_to_cpu(phy_id[0])); phy = phy_connect(dev, bus_id, hndlr, 0, iface); return IS_ERR(phy) ? NULL : phy; diff --git a/drivers/of/of_spi.c b/drivers/of/of_spi.c index bed0ed6dcdc1..f65f48b98448 100644 --- a/drivers/of/of_spi.c +++ b/drivers/of/of_spi.c @@ -23,7 +23,7 @@ void of_register_spi_devices(struct spi_master *master, struct device_node *np) { struct spi_device *spi; struct device_node *nc; - const u32 *prop; + const __be32 *prop; int rc; int len; @@ -54,7 +54,7 @@ void of_register_spi_devices(struct spi_master *master, struct device_node *np) spi_dev_put(spi); continue; } - spi->chip_select = *prop; + spi->chip_select = be32_to_cpup(prop); /* Mode (clock phase/polarity/etc.) */ if (of_find_property(nc, "spi-cpha", NULL)) @@ -72,7 +72,7 @@ void of_register_spi_devices(struct spi_master *master, struct device_node *np) spi_dev_put(spi); continue; } - spi->max_speed_hz = *prop; + spi->max_speed_hz = be32_to_cpup(prop); /* IRQ */ spi->irq = irq_of_parse_and_map(nc, 0); diff --git a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c index 75ac19b1192f..fc2f676e984d 100644 --- a/drivers/sbus/char/openprom.c +++ b/drivers/sbus/char/openprom.c @@ -233,7 +233,7 @@ static int opromnext(void __user *argp, unsigned int cmd, struct device_node *dp ph = 0; if (dp) - ph = dp->node; + ph = dp->phandle; data->current_node = dp; *((int *) op->oprom_array) = ph; @@ -256,7 +256,7 @@ static int oprompci2node(void __user *argp, struct device_node *dp, struct openp dp = pci_device_to_OF_node(pdev); data->current_node = dp; - *((int *)op->oprom_array) = dp->node; + *((int *)op->oprom_array) = dp->phandle; op->oprom_size = sizeof(int); err = copyout(argp, op, bufsize + sizeof(int)); @@ -273,7 +273,7 @@ static int oprompath2node(void __user *argp, struct device_node *dp, struct open dp = of_find_node_by_path(op->oprom_array); if (dp) - ph = dp->node; + ph = dp->phandle; data->current_node = dp; *((int *)op->oprom_array) = ph; op->oprom_size = sizeof(int); @@ -540,7 +540,7 @@ static int opiocgetnext(unsigned int cmd, void __user *argp) } } if (dp) - nd = dp->node; + nd = dp->phandle; if (copy_to_user(argp, &nd, sizeof(phandle))) return -EFAULT; @@ -570,7 +570,7 @@ static int openprom_bsd_ioctl(struct inode * inode, struct file * file, case OPIOCGETOPTNODE: BUILD_BUG_ON(sizeof(phandle) != sizeof(int)); - if (copy_to_user(argp, &options_node->node, sizeof(phandle))) + if (copy_to_user(argp, &options_node->phandle, sizeof(phandle))) return -EFAULT; return 0; diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c index 683e66f18e8c..3e2ae4807ae2 100644 --- a/drivers/serial/pmac_zilog.c +++ b/drivers/serial/pmac_zilog.c @@ -2031,9 +2031,9 @@ static int __init pmz_console_setup(struct console *co, char *options) /* * XServe's default to 57600 bps */ - if (machine_is_compatible("RackMac1,1") - || machine_is_compatible("RackMac1,2") - || machine_is_compatible("MacRISC4")) + if (of_machine_is_compatible("RackMac1,1") + || of_machine_is_compatible("RackMac1,2") + || of_machine_is_compatible("MacRISC4")) baud = 57600; /* diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c index e4e4d433b007..9ee67d6da710 100644 --- a/drivers/video/aty/aty128fb.c +++ b/drivers/video/aty/aty128fb.c @@ -1931,22 +1931,22 @@ static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_i * PowerMac2,2 summer 2000 iMacs * PowerMac4,1 january 2001 iMacs "flower power" */ - if (machine_is_compatible("PowerMac2,1") || - machine_is_compatible("PowerMac2,2") || - machine_is_compatible("PowerMac4,1")) + if (of_machine_is_compatible("PowerMac2,1") || + of_machine_is_compatible("PowerMac2,2") || + of_machine_is_compatible("PowerMac4,1")) default_vmode = VMODE_1024_768_75; /* iBook SE */ - if (machine_is_compatible("PowerBook2,2")) + if (of_machine_is_compatible("PowerBook2,2")) default_vmode = VMODE_800_600_60; /* PowerBook Firewire (Pismo), iBook Dual USB */ - if (machine_is_compatible("PowerBook3,1") || - machine_is_compatible("PowerBook4,1")) + if (of_machine_is_compatible("PowerBook3,1") || + of_machine_is_compatible("PowerBook4,1")) default_vmode = VMODE_1024_768_60; /* PowerBook Titanium */ - if (machine_is_compatible("PowerBook3,2")) + if (of_machine_is_compatible("PowerBook3,2")) default_vmode = VMODE_1152_768_60; if (default_cmode > 16) diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index 1ddeb4c34763..e45ab8db2ddc 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c @@ -2439,7 +2439,7 @@ static int __devinit aty_init(struct fb_info *info) * The Apple iBook1 uses non-standard memory frequencies. * We detect it and set the frequency manually. */ - if (machine_is_compatible("PowerBook2,1")) { + if (of_machine_is_compatible("PowerBook2,1")) { par->pll_limits.mclk = 70; par->pll_limits.xclk = 53; } @@ -2659,7 +2659,7 @@ static int __devinit aty_init(struct fb_info *info) FBINFO_HWACCEL_YPAN; #ifdef CONFIG_PMAC_BACKLIGHT - if (M64_HAS(G3_PB_1_1) && machine_is_compatible("PowerBook1,1")) { + if (M64_HAS(G3_PB_1_1) && of_machine_is_compatible("PowerBook1,1")) { /* * these bits let the 101 powerbook * wake up from sleep -- paulus @@ -2690,9 +2690,9 @@ static int __devinit aty_init(struct fb_info *info) if (M64_HAS(G3_PB_1024x768)) /* G3 PowerBook with 1024x768 LCD */ default_vmode = VMODE_1024_768_60; - else if (machine_is_compatible("iMac")) + else if (of_machine_is_compatible("iMac")) default_vmode = VMODE_1024_768_75; - else if (machine_is_compatible("PowerBook2,1")) + else if (of_machine_is_compatible("PowerBook2,1")) /* iBook with 800x600 LCD */ default_vmode = VMODE_800_600_60; else @@ -3104,7 +3104,7 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev, } dp = pci_device_to_OF_node(pdev); - if (node == dp->node) { + if (node == dp->phandle) { struct fb_var_screeninfo *var = &default_var; unsigned int N, P, Q, M, T, R; u32 v_total, h_total; diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/aty/radeon_backlight.c index 1a056adb61c8..fa1198c4ccc5 100644 --- a/drivers/video/aty/radeon_backlight.c +++ b/drivers/video/aty/radeon_backlight.c @@ -175,9 +175,9 @@ void radeonfb_bl_init(struct radeonfb_info *rinfo) #ifdef CONFIG_PMAC_BACKLIGHT pdata->negative = pdata->negative || - machine_is_compatible("PowerBook4,3") || - machine_is_compatible("PowerBook6,3") || - machine_is_compatible("PowerBook6,5"); + of_machine_is_compatible("PowerBook4,3") || + of_machine_is_compatible("PowerBook6,3") || + of_machine_is_compatible("PowerBook6,5"); #endif rinfo->info->bl_dev = bd; |