From a04e78b8579272c37c42a9badb6dae71f38fe4a9 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 29 Sep 2010 15:52:12 +1000 Subject: of: GPIO: Fix OF probing on little-endian systems DTB is always big-endian that's why is necessary to convert it. Signed-off-by: Michal Simek Signed-off-by: Grant Likely diff --git a/drivers/gpio/xilinx_gpio.c b/drivers/gpio/xilinx_gpio.c index 7096909..846fbd5 100644 --- a/drivers/gpio/xilinx_gpio.c +++ b/drivers/gpio/xilinx_gpio.c @@ -171,13 +171,13 @@ static int __devinit xgpio_of_probe(struct device_node *np) /* Update GPIO state shadow register with default value */ tree_info = of_get_property(np, "xlnx,dout-default", NULL); if (tree_info) - chip->gpio_state = *tree_info; + chip->gpio_state = be32_to_cpup(tree_info); /* Update GPIO direction shadow register with default value */ chip->gpio_dir = 0xFFFFFFFF; /* By default, all pins are inputs */ tree_info = of_get_property(np, "xlnx,tri-default", NULL); if (tree_info) - chip->gpio_dir = *tree_info; + chip->gpio_dir = be32_to_cpup(tree_info); /* Check device node and parent device node for device width */ chip->mmchip.gc.ngpio = 32; /* By default assume full GPIO controller */ @@ -186,7 +186,7 @@ static int __devinit xgpio_of_probe(struct device_node *np) tree_info = of_get_property(np->parent, "xlnx,gpio-width", NULL); if (tree_info) - chip->mmchip.gc.ngpio = *tree_info; + chip->mmchip.gc.ngpio = be32_to_cpup(tree_info); spin_lock_init(&chip->gpio_lock); -- cgit v0.10.2 From 2548558445b43c1f18a61c0bd3629f92dffa612e Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 29 Sep 2010 15:52:13 +1000 Subject: of: MTD: Fix OF probing on little-endian systems Convert big-endian DTB to little-endian if necessary. Signed-off-by: Michal Simek Signed-off-by: Grant Likely diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index fe63f6b..ec3edf6 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c @@ -294,7 +294,7 @@ static int __devinit of_flash_probe(struct platform_device *dev, info->list[i].map.name = dev_name(&dev->dev); info->list[i].map.phys = res.start; info->list[i].map.size = res_size; - info->list[i].map.bankwidth = *width; + info->list[i].map.bankwidth = be32_to_cpup(width); err = -ENOMEM; info->list[i].map.virt = ioremap(info->list[i].map.phys, diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c index 8bf7dc6..7bd171e 100644 --- a/drivers/mtd/ofpart.c +++ b/drivers/mtd/ofpart.c @@ -53,8 +53,8 @@ int __devinit of_mtd_parse_partitions(struct device *dev, continue; } - (*pparts)[i].offset = reg[0]; - (*pparts)[i].size = reg[1]; + (*pparts)[i].offset = be32_to_cpu(reg[0]); + (*pparts)[i].size = be32_to_cpu(reg[1]); partname = of_get_property(pp, "label", &len); if (!partname) -- cgit v0.10.2 From f14362d1fe81cece6f1d78483e5bbfcf8cc497bf Mon Sep 17 00:00:00 2001 From: Ian Munsie Date: Fri, 1 Oct 2010 17:06:07 +1000 Subject: powerpc, of_serial: Endianness issues setting up the serial ports The speed and clock of the serial ports is retrieved from the device tree in both the PowerPC legacy serial code and the Open Firmware serial driver, therefore they need to handle the fact that the device tree is always big endian, while the CPU may not be. Also fix other device tree references in the legacy serial code. Signed-off-by: Ian Munsie Signed-off-by: Grant Likely diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c index c1fd0f9..c834757 100644 --- a/arch/powerpc/kernel/legacy_serial.c +++ b/arch/powerpc/kernel/legacy_serial.c @@ -52,14 +52,14 @@ static int __init add_legacy_port(struct device_node *np, int want_index, phys_addr_t taddr, unsigned long irq, upf_t flags, int irq_check_parent) { - const u32 *clk, *spd; + const __be32 *clk, *spd; u32 clock = BASE_BAUD * 16; int index; /* get clock freq. if present */ clk = of_get_property(np, "clock-frequency", NULL); if (clk && *clk) - clock = *clk; + clock = be32_to_cpup(clk); /* get default speed if present */ spd = of_get_property(np, "current-speed", NULL); @@ -109,7 +109,7 @@ static int __init add_legacy_port(struct device_node *np, int want_index, legacy_serial_infos[index].taddr = taddr; legacy_serial_infos[index].np = of_node_get(np); legacy_serial_infos[index].clock = clock; - legacy_serial_infos[index].speed = spd ? *spd : 0; + legacy_serial_infos[index].speed = spd ? be32_to_cpup(spd) : 0; legacy_serial_infos[index].irq_check_parent = irq_check_parent; printk(KERN_DEBUG "Found legacy serial port %d for %s\n", @@ -168,7 +168,7 @@ static int __init add_legacy_soc_port(struct device_node *np, static int __init add_legacy_isa_port(struct device_node *np, struct device_node *isa_brg) { - const u32 *reg; + const __be32 *reg; const char *typep; int index = -1; u64 taddr; @@ -181,7 +181,7 @@ static int __init add_legacy_isa_port(struct device_node *np, return -1; /* Verify it's an IO port, we don't support anything else */ - if (!(reg[0] & 0x00000001)) + if (!(be32_to_cpu(reg[0]) & 0x00000001)) return -1; /* Now look for an "ibm,aix-loc" property that gives us ordering @@ -202,7 +202,7 @@ static int __init add_legacy_isa_port(struct device_node *np, taddr = 0; /* Add port, irq will be dealt with later */ - return add_legacy_port(np, index, UPIO_PORT, reg[1], taddr, + return add_legacy_port(np, index, UPIO_PORT, be32_to_cpu(reg[1]), taddr, NO_IRQ, UPF_BOOT_AUTOCONF, 0); } @@ -251,9 +251,9 @@ static int __init add_legacy_pci_port(struct device_node *np, * we get to their "reg" property */ if (np != pci_dev) { - const u32 *reg = of_get_property(np, "reg", NULL); - if (reg && (*reg < 4)) - index = lindex = *reg; + const __be32 *reg = of_get_property(np, "reg", NULL); + if (reg && (be32_to_cpup(reg) < 4)) + index = lindex = be32_to_cpup(reg); } /* Local index means it's the Nth port in the PCI chip. Unfortunately @@ -507,7 +507,7 @@ static int __init check_legacy_serial_console(void) struct device_node *prom_stdout = NULL; int i, speed = 0, offset = 0; const char *name; - const u32 *spd; + const __be32 *spd; DBG(" -> check_legacy_serial_console()\n"); @@ -547,7 +547,7 @@ static int __init check_legacy_serial_console(void) } spd = of_get_property(prom_stdout, "current-speed", NULL); if (spd) - speed = *spd; + speed = be32_to_cpup(spd); if (strcmp(name, "serial") != 0) goto not_found; diff --git a/drivers/serial/of_serial.c b/drivers/serial/of_serial.c index 2af8fd1..17849dc 100644 --- a/drivers/serial/of_serial.c +++ b/drivers/serial/of_serial.c @@ -31,8 +31,8 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev, { struct resource resource; struct device_node *np = ofdev->dev.of_node; - const unsigned int *clk, *spd; - const u32 *prop; + const __be32 *clk, *spd; + const __be32 *prop; int ret, prop_size; memset(port, 0, sizeof *port); @@ -55,23 +55,23 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev, /* Check for shifted address mapping */ prop = of_get_property(np, "reg-offset", &prop_size); if (prop && (prop_size == sizeof(u32))) - port->mapbase += *prop; + port->mapbase += be32_to_cpup(prop); /* Check for registers offset within the devices address range */ prop = of_get_property(np, "reg-shift", &prop_size); if (prop && (prop_size == sizeof(u32))) - port->regshift = *prop; + port->regshift = be32_to_cpup(prop); port->irq = irq_of_parse_and_map(np, 0); port->iotype = UPIO_MEM; port->type = type; - port->uartclk = *clk; + port->uartclk = be32_to_cpup(clk); port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_FIXED_PORT | UPF_FIXED_TYPE; port->dev = &ofdev->dev; /* If current-speed was set, then try not to change it. */ if (spd) - port->custom_divisor = *clk / (16 * (*spd)); + port->custom_divisor = be32_to_cpup(clk) / (16 * (be32_to_cpup(spd))); return 0; } -- cgit v0.10.2 From 4e13efc99106723960a27e55f560028bced5076d Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Fri, 8 Oct 2010 11:34:24 -0700 Subject: sparc: stop exporting openprom.h header It's unknown why openprom.h was being exported; there doesn't seem to be any reason for it currently, and it creates headaches with userspace being able to potentially use the structures in there. So, don't export it anymore. Signed-off-by: Andres Salomon Acked-by: David S. Miller Signed-off-by: Grant Likely diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild index deeb0fb..3c93f08 100644 --- a/arch/sparc/include/asm/Kbuild +++ b/arch/sparc/include/asm/Kbuild @@ -7,7 +7,6 @@ header-y += display7seg.h header-y += envctrl.h header-y += fbio.h header-y += jsflash.h -header-y += openprom.h header-y += openpromio.h header-y += perfctr.h header-y += psrcompat.h -- cgit v0.10.2 From 8d1255627d4ce9cb4b9d0a1c44b6c18d92e84a99 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Fri, 8 Oct 2010 14:18:11 -0700 Subject: of/sparc: convert various prom_* functions to use phandle Rather than passing around ints everywhere, use the phandle type where appropriate for the various functions that talk to the PROM. Signed-off-by: Andres Salomon Acked-by: David S. Miller Signed-off-by: Grant Likely diff --git a/arch/sparc/include/asm/floppy_32.h b/arch/sparc/include/asm/floppy_32.h index c792830..86666f7 100644 --- a/arch/sparc/include/asm/floppy_32.h +++ b/arch/sparc/include/asm/floppy_32.h @@ -304,7 +304,8 @@ static struct linux_prom_registers fd_regs[2]; static int sun_floppy_init(void) { char state[128]; - int tnode, fd_node, num_regs; + phandle tnode, fd_node; + int num_regs; struct resource r; use_virtual_dma = 1; diff --git a/arch/sparc/include/asm/openprom.h b/arch/sparc/include/asm/openprom.h index 963e1a4..81cd434 100644 --- a/arch/sparc/include/asm/openprom.h +++ b/arch/sparc/include/asm/openprom.h @@ -11,6 +11,8 @@ #define LINUX_OPPROM_MAGIC 0x10010407 #ifndef __ASSEMBLY__ +#include + /* V0 prom device operations. */ struct linux_dev_v0_funcs { int (*v0_devopen)(char *device_str); @@ -26,7 +28,7 @@ struct linux_dev_v0_funcs { /* V2 and later prom device operations. */ struct linux_dev_v2_funcs { - int (*v2_inst2pkg)(int d); /* Convert ihandle to phandle */ + phandle (*v2_inst2pkg)(int d); /* Convert ihandle to phandle */ char * (*v2_dumb_mem_alloc)(char *va, unsigned sz); void (*v2_dumb_mem_free)(char *va, unsigned sz); @@ -168,12 +170,12 @@ struct linux_romvec { /* Routines for traversing the prom device tree. */ struct linux_nodeops { - int (*no_nextnode)(int node); - int (*no_child)(int node); - int (*no_proplen)(int node, const char *name); - int (*no_getprop)(int node, const char *name, char *val); - int (*no_setprop)(int node, const char *name, char *val, int len); - char * (*no_nextprop)(int node, char *name); + phandle (*no_nextnode)(phandle node); + phandle (*no_child)(phandle node); + int (*no_proplen)(phandle node, const char *name); + int (*no_getprop)(phandle node, const char *name, char *val); + int (*no_setprop)(phandle node, const char *name, char *val, int len); + char * (*no_nextprop)(phandle node, char *name); }; /* More fun PROM structures for device probing. */ diff --git a/arch/sparc/include/asm/oplib_32.h b/arch/sparc/include/asm/oplib_32.h index 33e31ce..51296a6 100644 --- a/arch/sparc/include/asm/oplib_32.h +++ b/arch/sparc/include/asm/oplib_32.h @@ -30,7 +30,7 @@ extern unsigned int prom_rev, prom_prev; /* Root node of the prom device tree, this stays constant after * initialization is complete. */ -extern int prom_root_node; +extern phandle prom_root_node; /* Pointer to prom structure containing the device tree traversal * and usage utility functions. Only prom-lib should use these, @@ -178,68 +178,68 @@ extern void prom_putsegment(int context, unsigned long virt_addr, /* PROM device tree traversal functions... */ /* Get the child node of the given node, or zero if no child exists. */ -extern int prom_getchild(int parent_node); +extern phandle prom_getchild(phandle parent_node); /* Get the next sibling node of the given node, or zero if no further * siblings exist. */ -extern int prom_getsibling(int node); +extern phandle prom_getsibling(phandle node); /* Get the length, at the passed node, of the given property type. * Returns -1 on error (ie. no such property at this node). */ -extern int prom_getproplen(int thisnode, const char *property); +extern int prom_getproplen(phandle thisnode, const char *property); /* Fetch the requested property using the given buffer. Returns * the number of bytes the prom put into your buffer or -1 on error. */ -extern int __must_check prom_getproperty(int thisnode, const char *property, +extern int __must_check prom_getproperty(phandle thisnode, const char *property, char *prop_buffer, int propbuf_size); /* Acquire an integer property. */ -extern int prom_getint(int node, char *property); +extern int prom_getint(phandle node, char *property); /* Acquire an integer property, with a default value. */ -extern int prom_getintdefault(int node, char *property, int defval); +extern int prom_getintdefault(phandle node, char *property, int defval); /* Acquire a boolean property, 0=FALSE 1=TRUE. */ -extern int prom_getbool(int node, char *prop); +extern int prom_getbool(phandle node, char *prop); /* Acquire a string property, null string on error. */ -extern void prom_getstring(int node, char *prop, char *buf, int bufsize); +extern void prom_getstring(phandle node, char *prop, char *buf, int bufsize); /* Does the passed node have the given "name"? YES=1 NO=0 */ -extern int prom_nodematch(int thisnode, char *name); +extern int prom_nodematch(phandle thisnode, char *name); /* Search all siblings starting at the passed node for "name" matching * the given string. Returns the node on success, zero on failure. */ -extern int prom_searchsiblings(int node_start, char *name); +extern phandle prom_searchsiblings(phandle node_start, char *name); /* Return the first property type, as a string, for the given node. * Returns a null string on error. */ -extern char *prom_firstprop(int node, char *buffer); +extern char *prom_firstprop(phandle node, char *buffer); /* Returns the next property after the passed property for the given * node. Returns null string on failure. */ -extern char *prom_nextprop(int node, char *prev_property, char *buffer); +extern char *prom_nextprop(phandle node, char *prev_property, char *buffer); /* Returns phandle of the path specified */ -extern int prom_finddevice(char *name); +extern phandle prom_finddevice(char *name); /* Returns 1 if the specified node has given property. */ -extern int prom_node_has_property(int node, char *property); +extern int prom_node_has_property(phandle node, char *property); /* Set the indicated property at the given node with the passed value. * Returns the number of bytes of your value that the prom took. */ -extern int prom_setprop(int node, const char *prop_name, char *prop_value, +extern int prom_setprop(phandle node, const char *prop_name, char *prop_value, int value_size); -extern int prom_pathtoinode(char *path); -extern int prom_inst2pkg(int); +extern phandle prom_pathtoinode(char *path); +extern phandle prom_inst2pkg(int); /* Dorking with Bus ranges... */ @@ -247,13 +247,13 @@ extern int prom_inst2pkg(int); extern void prom_apply_obio_ranges(struct linux_prom_registers *obioregs, int nregs); /* Apply ranges of any prom node (and optionally parent node as well) to registers. */ -extern void prom_apply_generic_ranges(int node, int parent, +extern void prom_apply_generic_ranges(phandle node, phandle parent, struct linux_prom_registers *sbusregs, int nregs); /* CPU probing helpers. */ -int cpu_find_by_instance(int instance, int *prom_node, int *mid); -int cpu_find_by_mid(int mid, int *prom_node); -int cpu_get_hwmid(int prom_node); +int cpu_find_by_instance(int instance, phandle *prom_node, int *mid); +int cpu_find_by_mid(int mid, phandle *prom_node); +int cpu_get_hwmid(phandle prom_node); extern spinlock_t prom_lock; diff --git a/arch/sparc/include/asm/oplib_64.h b/arch/sparc/include/asm/oplib_64.h index 3e0b2d6..c9cc078 100644 --- a/arch/sparc/include/asm/oplib_64.h +++ b/arch/sparc/include/asm/oplib_64.h @@ -16,7 +16,7 @@ extern char prom_version[]; /* Root node of the prom device tree, this stays constant after * initialization is complete. */ -extern int prom_root_node; +extern phandle prom_root_node; /* PROM stdin and stdout */ extern int prom_stdin, prom_stdout; @@ -24,7 +24,7 @@ extern int prom_stdin, prom_stdout; /* /chosen node of the prom device tree, this stays constant after * initialization is complete. */ -extern int prom_chosen_node; +extern phandle prom_chosen_node; /* Helper values and strings in arch/sparc64/kernel/head.S */ extern const char prom_peer_name[]; @@ -218,68 +218,69 @@ extern void prom_unmap(unsigned long size, unsigned long vaddr); /* PROM device tree traversal functions... */ /* Get the child node of the given node, or zero if no child exists. */ -extern int prom_getchild(int parent_node); +extern phandle prom_getchild(phandle parent_node); /* Get the next sibling node of the given node, or zero if no further * siblings exist. */ -extern int prom_getsibling(int node); +extern phandle prom_getsibling(phandle node); /* Get the length, at the passed node, of the given property type. * Returns -1 on error (ie. no such property at this node). */ -extern int prom_getproplen(int thisnode, const char *property); +extern int prom_getproplen(phandle thisnode, const char *property); /* Fetch the requested property using the given buffer. Returns * the number of bytes the prom put into your buffer or -1 on error. */ -extern int prom_getproperty(int thisnode, const char *property, +extern int prom_getproperty(phandle thisnode, const char *property, char *prop_buffer, int propbuf_size); /* Acquire an integer property. */ -extern int prom_getint(int node, const char *property); +extern int prom_getint(phandle node, const char *property); /* Acquire an integer property, with a default value. */ -extern int prom_getintdefault(int node, const char *property, int defval); +extern int prom_getintdefault(phandle node, const char *property, int defval); /* Acquire a boolean property, 0=FALSE 1=TRUE. */ -extern int prom_getbool(int node, const char *prop); +extern int prom_getbool(phandle node, const char *prop); /* Acquire a string property, null string on error. */ -extern void prom_getstring(int node, const char *prop, char *buf, int bufsize); +extern void prom_getstring(phandle node, const char *prop, char *buf, + int bufsize); /* Does the passed node have the given "name"? YES=1 NO=0 */ -extern int prom_nodematch(int thisnode, const char *name); +extern int prom_nodematch(phandle thisnode, const char *name); /* Search all siblings starting at the passed node for "name" matching * the given string. Returns the node on success, zero on failure. */ -extern int prom_searchsiblings(int node_start, const char *name); +extern phandle prom_searchsiblings(phandle node_start, const char *name); /* Return the first property type, as a string, for the given node. * Returns a null string on error. Buffer should be at least 32B long. */ -extern char *prom_firstprop(int node, char *buffer); +extern char *prom_firstprop(phandle node, char *buffer); /* Returns the next property after the passed property for the given * node. Returns null string on failure. Buffer should be at least 32B long. */ -extern char *prom_nextprop(int node, const char *prev_property, char *buffer); +extern char *prom_nextprop(phandle node, const char *prev_property, char *buf); /* Returns 1 if the specified node has given property. */ -extern int prom_node_has_property(int node, const char *property); +extern int prom_node_has_property(phandle node, const char *property); /* Returns phandle of the path specified */ -extern int prom_finddevice(const char *name); +extern phandle prom_finddevice(const char *name); /* Set the indicated property at the given node with the passed value. * Returns the number of bytes of your value that the prom took. */ -extern int prom_setprop(int node, const char *prop_name, char *prop_value, +extern int prom_setprop(phandle node, const char *prop_name, char *prop_value, int value_size); -extern int prom_pathtoinode(const char *path); -extern int prom_inst2pkg(int); +extern phandle prom_pathtoinode(const char *path); +extern phandle prom_inst2pkg(int); extern int prom_service_exists(const char *service_name); extern void prom_sun4v_guest_soft_state(void); diff --git a/arch/sparc/kernel/auxio_32.c b/arch/sparc/kernel/auxio_32.c index ee8d214..35f4883 100644 --- a/arch/sparc/kernel/auxio_32.c +++ b/arch/sparc/kernel/auxio_32.c @@ -23,7 +23,7 @@ static DEFINE_SPINLOCK(auxio_lock); void __init auxio_probe(void) { - int node, auxio_nd; + phandle node, auxio_nd; struct linux_prom_registers auxregs[1]; struct resource r; @@ -113,7 +113,7 @@ volatile unsigned char * auxio_power_register = NULL; void __init auxio_power_probe(void) { struct linux_prom_registers regs; - int node; + phandle node; struct resource r; /* Attempt to find the sun4m power control node. */ diff --git a/arch/sparc/kernel/btext.c b/arch/sparc/kernel/btext.c index 8cc2d56..89aa4eb 100644 --- a/arch/sparc/kernel/btext.c +++ b/arch/sparc/kernel/btext.c @@ -40,7 +40,7 @@ static unsigned char *dispDeviceBase __force_data; static unsigned char vga_font[cmapsz]; -static int __init btext_initialize(unsigned int node) +static int __init btext_initialize(phandle node) { unsigned int width, height, depth, pitch; unsigned long address = 0; @@ -309,7 +309,7 @@ static struct console btext_console = { int __init btext_find_display(void) { - unsigned int node; + phandle node; char type[32]; int ret; diff --git a/arch/sparc/kernel/devices.c b/arch/sparc/kernel/devices.c index 62dc7a0..d2eddd6 100644 --- a/arch/sparc/kernel/devices.c +++ b/arch/sparc/kernel/devices.c @@ -31,9 +31,9 @@ static char *cpu_mid_prop(void) return "mid"; } -static int check_cpu_node(int nd, int *cur_inst, - int (*compare)(int, int, void *), void *compare_arg, - int *prom_node, int *mid) +static int check_cpu_node(phandle nd, int *cur_inst, + int (*compare)(phandle, int, void *), void *compare_arg, + phandle *prom_node, int *mid) { if (!compare(nd, *cur_inst, compare_arg)) { if (prom_node) @@ -51,8 +51,8 @@ static int check_cpu_node(int nd, int *cur_inst, return -ENODEV; } -static int __cpu_find_by(int (*compare)(int, int, void *), void *compare_arg, - int *prom_node, int *mid) +static int __cpu_find_by(int (*compare)(phandle, int, void *), + void *compare_arg, phandle *prom_node, int *mid) { struct device_node *dp; int cur_inst; @@ -71,7 +71,7 @@ static int __cpu_find_by(int (*compare)(int, int, void *), void *compare_arg, return -ENODEV; } -static int cpu_instance_compare(int nd, int instance, void *_arg) +static int cpu_instance_compare(phandle nd, int instance, void *_arg) { int desired_instance = (int) _arg; @@ -80,13 +80,13 @@ static int cpu_instance_compare(int nd, int instance, void *_arg) return -ENODEV; } -int cpu_find_by_instance(int instance, int *prom_node, int *mid) +int cpu_find_by_instance(int instance, phandle *prom_node, int *mid) { return __cpu_find_by(cpu_instance_compare, (void *)instance, prom_node, mid); } -static int cpu_mid_compare(int nd, int instance, void *_arg) +static int cpu_mid_compare(phandle nd, int instance, void *_arg) { int desired_mid = (int) _arg; int this_mid; @@ -98,7 +98,7 @@ static int cpu_mid_compare(int nd, int instance, void *_arg) return -ENODEV; } -int cpu_find_by_mid(int mid, int *prom_node) +int cpu_find_by_mid(int mid, phandle *prom_node) { return __cpu_find_by(cpu_mid_compare, (void *)mid, prom_node, NULL); @@ -108,7 +108,7 @@ int cpu_find_by_mid(int mid, int *prom_node) * address (0-3). This gives us the true hardware mid, which might have * some other bits set. On 4d hardware and software mids are the same. */ -int cpu_get_hwmid(int prom_node) +int cpu_get_hwmid(phandle prom_node) { return prom_getintdefault(prom_node, cpu_mid_prop(), -ENODEV); } @@ -119,7 +119,8 @@ void __init device_scan(void) #ifndef CONFIG_SMP { - int err, cpu_node; + phandle cpu_node; + int err; err = cpu_find_by_instance(0, &cpu_node, NULL); if (err) { /* Probably a sun4e, Sun is trying to trick us ;-) */ diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index d36a8d3..aeaa09a 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c @@ -284,7 +284,7 @@ int __init pcic_probe(void) struct linux_prom_registers regs[PROMREG_MAX]; struct linux_pbm_info* pbm; char namebuf[64]; - int node; + phandle node; int err; if (pcic0_up) { @@ -440,7 +440,7 @@ static int __devinit pdev_to_pnode(struct linux_pbm_info *pbm, { struct linux_prom_pci_registers regs[PROMREG_MAX]; int err; - int node = prom_getchild(pbm->prom_node); + phandle node = prom_getchild(pbm->prom_node); while(node) { err = prom_getproperty(node, "reg", diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c index 5f72de6..29bafe0 100644 --- a/arch/sparc/kernel/setup_64.c +++ b/arch/sparc/kernel/setup_64.c @@ -315,7 +315,7 @@ void __init setup_arch(char **cmdline_p) #ifdef CONFIG_IP_PNP if (!ic_set_manually) { - int chosen = prom_finddevice ("/chosen"); + phandle chosen = prom_finddevice("/chosen"); u32 cl, sv, gw; cl = prom_getintdefault (chosen, "client-ip", 0); diff --git a/arch/sparc/kernel/starfire.c b/arch/sparc/kernel/starfire.c index 060d0f3..a4446c0 100644 --- a/arch/sparc/kernel/starfire.c +++ b/arch/sparc/kernel/starfire.c @@ -23,7 +23,7 @@ int this_is_starfire = 0; void check_if_starfire(void) { - int ssnode = prom_finddevice("/ssp-serial"); + phandle ssnode = prom_finddevice("/ssp-serial"); if (ssnode != 0 && ssnode != -1) this_is_starfire = 1; } diff --git a/arch/sparc/kernel/tadpole.c b/arch/sparc/kernel/tadpole.c index f476a5f..9aba8bd 100644 --- a/arch/sparc/kernel/tadpole.c +++ b/arch/sparc/kernel/tadpole.c @@ -100,7 +100,7 @@ static void swift_clockstop(void) void __init clock_stop_probe(void) { - unsigned int node, clk_nd; + phandle node, clk_nd; char name[20]; prom_getstring(prom_root_node, "name", name, sizeof(name)); diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index f043451..9b020d6 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c @@ -88,7 +88,7 @@ static void __init read_obp_memory(const char *property, struct linux_prom64_registers *regs, int *num_ents) { - int node = prom_finddevice("/memory"); + phandle node = prom_finddevice("/memory"); int prop_size = prom_getproplen(node, property); int ents, ret, i; diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index b0b43aa..92319aa 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c @@ -1262,7 +1262,8 @@ extern unsigned long bootmem_init(unsigned long *pages_avail); void __init srmmu_paging_init(void) { - int i, cpunode; + int i; + phandle cpunode; char node_str[128]; pgd_t *pgd; pmd_t *pmd; @@ -1398,7 +1399,8 @@ static void __init srmmu_is_bad(void) static void __init init_vac_layout(void) { - int nd, cache_lines; + phandle nd; + int cache_lines; char node_str[128]; #ifdef CONFIG_SMP int cpu = 0; @@ -2082,7 +2084,7 @@ static void __init get_srmmu_type(void) /* Next check for Fujitsu Swift. */ if(psr_typ == 0 && psr_vers == 4) { - int cpunode; + phandle cpunode; char node_str[128]; /* Look if it is not a TurboSparc emulating Swift... */ diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c index 4289f90..ddd0d86 100644 --- a/arch/sparc/mm/sun4c.c +++ b/arch/sparc/mm/sun4c.c @@ -420,7 +420,7 @@ volatile unsigned long __iomem *sun4c_memerr_reg = NULL; void __init sun4c_probe_memerr_reg(void) { - int node; + phandle node; struct linux_prom_registers regs[1]; node = prom_getchild(prom_root_node); diff --git a/arch/sparc/prom/init_32.c b/arch/sparc/prom/init_32.c index ccb36c7..d342dba 100644 --- a/arch/sparc/prom/init_32.c +++ b/arch/sparc/prom/init_32.c @@ -20,7 +20,7 @@ enum prom_major_version prom_vers; unsigned int prom_rev, prom_prev; /* The root node of the prom device tree. */ -int prom_root_node; +phandle prom_root_node; EXPORT_SYMBOL(prom_root_node); /* Pointer to the device tree operations structure. */ diff --git a/arch/sparc/prom/init_64.c b/arch/sparc/prom/init_64.c index 7b00f89..3ff911e 100644 --- a/arch/sparc/prom/init_64.c +++ b/arch/sparc/prom/init_64.c @@ -19,7 +19,7 @@ char prom_version[80]; /* The root node of the prom device tree. */ int prom_stdin, prom_stdout; -int prom_chosen_node; +phandle prom_chosen_node; /* You must call prom_init() before you attempt to use any of the * routines in the prom library. It returns 0 on success, 1 on @@ -30,7 +30,7 @@ extern void prom_cif_init(void *, void *); void __init prom_init(void *cif_handler, void *cif_stack) { - int node; + phandle node; prom_cif_init(cif_handler, cif_stack); diff --git a/arch/sparc/prom/memory.c b/arch/sparc/prom/memory.c index fac7899..3f263a6 100644 --- a/arch/sparc/prom/memory.c +++ b/arch/sparc/prom/memory.c @@ -31,7 +31,8 @@ static int __init prom_meminit_v0(void) static int __init prom_meminit_v2(void) { struct linux_prom_registers reg[64]; - int node, size, num_ents, i; + phandle node; + int size, num_ents, i; node = prom_searchsiblings(prom_getchild(prom_root_node), "memory"); size = prom_getproperty(node, "available", (char *) reg, sizeof(reg)); diff --git a/arch/sparc/prom/misc_64.c b/arch/sparc/prom/misc_64.c index 6cb1581..d24bc44 100644 --- a/arch/sparc/prom/misc_64.c +++ b/arch/sparc/prom/misc_64.c @@ -183,7 +183,8 @@ unsigned char prom_get_idprom(char *idbuf, int num_bytes) int prom_get_mmu_ihandle(void) { - int node, ret; + phandle node; + int ret; if (prom_mmu_ihandle_cache != 0) return prom_mmu_ihandle_cache; @@ -201,7 +202,8 @@ int prom_get_mmu_ihandle(void) static int prom_get_memory_ihandle(void) { static int memory_ihandle_cache; - int node, ret; + phandle node; + int ret; if (memory_ihandle_cache != 0) return memory_ihandle_cache; diff --git a/arch/sparc/prom/ranges.c b/arch/sparc/prom/ranges.c index aeff43e..541fc82 100644 --- a/arch/sparc/prom/ranges.c +++ b/arch/sparc/prom/ranges.c @@ -68,7 +68,7 @@ EXPORT_SYMBOL(prom_apply_obio_ranges); void __init prom_ranges_init(void) { - int node, obio_node; + phandle node, obio_node; int success; num_obio_ranges = 0; @@ -89,8 +89,8 @@ void __init prom_ranges_init(void) prom_printf("PROMLIB: obio_ranges %d\n", num_obio_ranges); } -void -prom_apply_generic_ranges (int node, int parent, struct linux_prom_registers *regs, int nregs) +void prom_apply_generic_ranges(phandle node, phandle parent, + struct linux_prom_registers *regs, int nregs) { int success; int num_ranges; diff --git a/arch/sparc/prom/tree_32.c b/arch/sparc/prom/tree_32.c index b21592f..63e08e1 100644 --- a/arch/sparc/prom/tree_32.c +++ b/arch/sparc/prom/tree_32.c @@ -20,10 +20,10 @@ extern void restore_current(void); static char promlib_buf[128]; /* Internal version of prom_getchild that does not alter return values. */ -int __prom_getchild(int node) +phandle __prom_getchild(phandle node) { unsigned long flags; - int cnode; + phandle cnode; spin_lock_irqsave(&prom_lock, flags); cnode = prom_nodeops->no_child(node); @@ -36,9 +36,9 @@ int __prom_getchild(int node) /* Return the child of node 'node' or zero if no this node has no * direct descendent. */ -int prom_getchild(int node) +phandle prom_getchild(phandle node) { - int cnode; + phandle cnode; if (node == -1) return 0; @@ -52,10 +52,10 @@ int prom_getchild(int node) EXPORT_SYMBOL(prom_getchild); /* Internal version of prom_getsibling that does not alter return values. */ -int __prom_getsibling(int node) +phandle __prom_getsibling(phandle node) { unsigned long flags; - int cnode; + phandle cnode; spin_lock_irqsave(&prom_lock, flags); cnode = prom_nodeops->no_nextnode(node); @@ -68,9 +68,9 @@ int __prom_getsibling(int node) /* Return the next sibling of node 'node' or zero if no more siblings * at this level of depth in the tree. */ -int prom_getsibling(int node) +phandle prom_getsibling(phandle node) { - int sibnode; + phandle sibnode; if (node == -1) return 0; @@ -86,7 +86,7 @@ EXPORT_SYMBOL(prom_getsibling); /* Return the length in bytes of property 'prop' at node 'node'. * Return -1 on error. */ -int prom_getproplen(int node, const char *prop) +int prom_getproplen(phandle node, const char *prop) { int ret; unsigned long flags; @@ -106,7 +106,7 @@ EXPORT_SYMBOL(prom_getproplen); * 'buffer' which has a size of 'bufsize'. If the acquisition * was successful the length will be returned, else -1 is returned. */ -int prom_getproperty(int node, const char *prop, char *buffer, int bufsize) +int prom_getproperty(phandle node, const char *prop, char *buffer, int bufsize) { int plen, ret; unsigned long flags; @@ -126,7 +126,7 @@ EXPORT_SYMBOL(prom_getproperty); /* Acquire an integer property and return its value. Returns -1 * on failure. */ -int prom_getint(int node, char *prop) +int prom_getint(phandle node, char *prop) { static int intprop; @@ -140,7 +140,7 @@ EXPORT_SYMBOL(prom_getint); /* Acquire an integer property, upon error return the passed default * integer. */ -int prom_getintdefault(int node, char *property, int deflt) +int prom_getintdefault(phandle node, char *property, int deflt) { int retval; @@ -152,7 +152,7 @@ int prom_getintdefault(int node, char *property, int deflt) EXPORT_SYMBOL(prom_getintdefault); /* Acquire a boolean property, 1=TRUE 0=FALSE. */ -int prom_getbool(int node, char *prop) +int prom_getbool(phandle node, char *prop) { int retval; @@ -166,7 +166,7 @@ EXPORT_SYMBOL(prom_getbool); * string on error. The char pointer is the user supplied string * buffer. */ -void prom_getstring(int node, char *prop, char *user_buf, int ubuf_size) +void prom_getstring(phandle node, char *prop, char *user_buf, int ubuf_size) { int len; @@ -180,7 +180,7 @@ EXPORT_SYMBOL(prom_getstring); /* Does the device at node 'node' have name 'name'? * YES = 1 NO = 0 */ -int prom_nodematch(int node, char *name) +int prom_nodematch(phandle node, char *name) { int error; @@ -194,10 +194,11 @@ int prom_nodematch(int node, char *name) /* Search siblings at 'node_start' for a node with name * 'nodename'. Return node if successful, zero if not. */ -int prom_searchsiblings(int node_start, char *nodename) +phandle prom_searchsiblings(phandle node_start, char *nodename) { - int thisnode, error; + phandle thisnode; + int error; for(thisnode = node_start; thisnode; thisnode=prom_getsibling(thisnode)) { @@ -213,7 +214,7 @@ int prom_searchsiblings(int node_start, char *nodename) EXPORT_SYMBOL(prom_searchsiblings); /* Interal version of nextprop that does not alter return values. */ -char * __prom_nextprop(int node, char * oprop) +char *__prom_nextprop(phandle node, char * oprop) { unsigned long flags; char *prop; @@ -228,7 +229,7 @@ char * __prom_nextprop(int node, char * oprop) /* Return the first property name for node 'node'. */ /* buffer is unused argument, but as v9 uses it, we need to have the same interface */ -char * prom_firstprop(int node, char *bufer) +char *prom_firstprop(phandle node, char *bufer) { if (node == 0 || node == -1) return ""; @@ -241,7 +242,7 @@ EXPORT_SYMBOL(prom_firstprop); * at node 'node' . Returns empty string if no more * property types for this node. */ -char * prom_nextprop(int node, char *oprop, char *buffer) +char *prom_nextprop(phandle node, char *oprop, char *buffer) { if (node == 0 || node == -1) return ""; @@ -250,11 +251,11 @@ char * prom_nextprop(int node, char *oprop, char *buffer) } EXPORT_SYMBOL(prom_nextprop); -int prom_finddevice(char *name) +phandle prom_finddevice(char *name) { char nbuf[128]; char *s = name, *d; - int node = prom_root_node, node2; + phandle node = prom_root_node, node2; unsigned int which_io, phys_addr; struct linux_prom_registers reg[PROMREG_MAX]; @@ -298,7 +299,7 @@ int prom_finddevice(char *name) } EXPORT_SYMBOL(prom_finddevice); -int prom_node_has_property(int node, char *prop) +int prom_node_has_property(phandle node, char *prop) { char *current_property = ""; @@ -314,7 +315,7 @@ EXPORT_SYMBOL(prom_node_has_property); /* Set property 'pname' at node 'node' to value 'value' which has a length * of 'size' bytes. Return the number of bytes the prom accepted. */ -int prom_setprop(int node, const char *pname, char *value, int size) +int prom_setprop(phandle node, const char *pname, char *value, int size) { unsigned long flags; int ret; @@ -329,9 +330,9 @@ int prom_setprop(int node, const char *pname, char *value, int size) } EXPORT_SYMBOL(prom_setprop); -int prom_inst2pkg(int inst) +phandle prom_inst2pkg(int inst) { - int node; + phandle node; unsigned long flags; spin_lock_irqsave(&prom_lock, flags); @@ -345,9 +346,10 @@ int prom_inst2pkg(int inst) /* Return 'node' assigned to a particular prom 'path' * FIXME: Should work for v0 as well */ -int prom_pathtoinode(char *path) +phandle prom_pathtoinode(char *path) { - int node, inst; + phandle node; + int inst; inst = prom_devopen (path); if (inst == -1) return 0; diff --git a/arch/sparc/prom/tree_64.c b/arch/sparc/prom/tree_64.c index 9d3f913..691be68 100644 --- a/arch/sparc/prom/tree_64.c +++ b/arch/sparc/prom/tree_64.c @@ -16,7 +16,7 @@ #include #include -static int prom_node_to_node(const char *type, int node) +static phandle prom_node_to_node(const char *type, phandle node) { unsigned long args[5]; @@ -28,20 +28,20 @@ static int prom_node_to_node(const char *type, int node) p1275_cmd_direct(args); - return (int) args[4]; + return (phandle) args[4]; } /* Return the child of node 'node' or zero if no this node has no * direct descendent. */ -inline int __prom_getchild(int node) +inline phandle __prom_getchild(phandle node) { return prom_node_to_node("child", node); } -inline int prom_getchild(int node) +inline phandle prom_getchild(phandle node) { - int cnode; + phandle cnode; if (node == -1) return 0; @@ -52,9 +52,9 @@ inline int prom_getchild(int node) } EXPORT_SYMBOL(prom_getchild); -inline int prom_getparent(int node) +inline phandle prom_getparent(phandle node) { - int cnode; + phandle cnode; if (node == -1) return 0; @@ -67,14 +67,14 @@ inline int prom_getparent(int node) /* Return the next sibling of node 'node' or zero if no more siblings * at this level of depth in the tree. */ -inline int __prom_getsibling(int node) +inline phandle __prom_getsibling(phandle node) { return prom_node_to_node(prom_peer_name, node); } -inline int prom_getsibling(int node) +inline phandle prom_getsibling(phandle node) { - int sibnode; + phandle sibnode; if (node == -1) return 0; @@ -89,7 +89,7 @@ EXPORT_SYMBOL(prom_getsibling); /* Return the length in bytes of property 'prop' at node 'node'. * Return -1 on error. */ -inline int prom_getproplen(int node, const char *prop) +inline int prom_getproplen(phandle node, const char *prop) { unsigned long args[6]; @@ -113,7 +113,7 @@ EXPORT_SYMBOL(prom_getproplen); * 'buffer' which has a size of 'bufsize'. If the acquisition * was successful the length will be returned, else -1 is returned. */ -inline int prom_getproperty(int node, const char *prop, +inline int prom_getproperty(phandle node, const char *prop, char *buffer, int bufsize) { unsigned long args[8]; @@ -141,7 +141,7 @@ EXPORT_SYMBOL(prom_getproperty); /* Acquire an integer property and return its value. Returns -1 * on failure. */ -inline int prom_getint(int node, const char *prop) +inline int prom_getint(phandle node, const char *prop) { int intprop; @@ -156,7 +156,7 @@ EXPORT_SYMBOL(prom_getint); * integer. */ -int prom_getintdefault(int node, const char *property, int deflt) +int prom_getintdefault(phandle node, const char *property, int deflt) { int retval; @@ -169,7 +169,7 @@ int prom_getintdefault(int node, const char *property, int deflt) EXPORT_SYMBOL(prom_getintdefault); /* Acquire a boolean property, 1=TRUE 0=FALSE. */ -int prom_getbool(int node, const char *prop) +int prom_getbool(phandle node, const char *prop) { int retval; @@ -184,7 +184,8 @@ EXPORT_SYMBOL(prom_getbool); * string on error. The char pointer is the user supplied string * buffer. */ -void prom_getstring(int node, const char *prop, char *user_buf, int ubuf_size) +void prom_getstring(phandle node, const char *prop, char *user_buf, + int ubuf_size) { int len; @@ -198,7 +199,7 @@ EXPORT_SYMBOL(prom_getstring); /* Does the device at node 'node' have name 'name'? * YES = 1 NO = 0 */ -int prom_nodematch(int node, const char *name) +int prom_nodematch(phandle node, const char *name) { char namebuf[128]; prom_getproperty(node, "name", namebuf, sizeof(namebuf)); @@ -210,10 +211,10 @@ int prom_nodematch(int node, const char *name) /* Search siblings at 'node_start' for a node with name * 'nodename'. Return node if successful, zero if not. */ -int prom_searchsiblings(int node_start, const char *nodename) +phandle prom_searchsiblings(phandle node_start, const char *nodename) { - - int thisnode, error; + phandle thisnode; + int error; char promlib_buf[128]; for(thisnode = node_start; thisnode; @@ -234,7 +235,7 @@ static const char *prom_nextprop_name = "nextprop"; /* Return the first property type for node 'node'. * buffer should be at least 32B in length */ -inline char *prom_firstprop(int node, char *buffer) +inline char *prom_firstprop(phandle node, char *buffer) { unsigned long args[7]; @@ -260,7 +261,7 @@ EXPORT_SYMBOL(prom_firstprop); * at node 'node' . Returns NULL string if no more * property types for this node. */ -inline char *prom_nextprop(int node, const char *oprop, char *buffer) +inline char *prom_nextprop(phandle node, const char *oprop, char *buffer) { unsigned long args[7]; char buf[32]; @@ -288,8 +289,7 @@ inline char *prom_nextprop(int node, const char *oprop, char *buffer) } EXPORT_SYMBOL(prom_nextprop); -int -prom_finddevice(const char *name) +phandle prom_finddevice(const char *name) { unsigned long args[5]; @@ -307,7 +307,7 @@ prom_finddevice(const char *name) } EXPORT_SYMBOL(prom_finddevice); -int prom_node_has_property(int node, const char *prop) +int prom_node_has_property(phandle node, const char *prop) { char buf [32]; @@ -325,7 +325,7 @@ EXPORT_SYMBOL(prom_node_has_property); * of 'size' bytes. Return the number of bytes the prom accepted. */ int -prom_setprop(int node, const char *pname, char *value, int size) +prom_setprop(phandle node, const char *pname, char *value, int size) { unsigned long args[8]; @@ -355,10 +355,10 @@ prom_setprop(int node, const char *pname, char *value, int size) } EXPORT_SYMBOL(prom_setprop); -inline int prom_inst2pkg(int inst) +inline phandle prom_inst2pkg(int inst) { unsigned long args[5]; - int node; + phandle node; args[0] = (unsigned long) "instance-to-package"; args[1] = 1; @@ -377,10 +377,10 @@ inline int prom_inst2pkg(int inst) /* Return 'node' assigned to a particular prom 'path' * FIXME: Should work for v0 as well */ -int -prom_pathtoinode(const char *path) +phandle prom_pathtoinode(const char *path) { - int node, inst; + phandle node; + int inst; inst = prom_devopen (path); if (inst == 0) diff --git a/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c index 4942050..5139371 100644 --- a/drivers/sbus/char/jsflash.c +++ b/drivers/sbus/char/jsflash.c @@ -459,7 +459,7 @@ static int jsflash_init(void) { int rc; struct jsflash *jsf; - int node; + phandle node; char banner[128]; struct linux_prom_registers reg0; diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index f8d69ad..5bf9123 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c @@ -2970,7 +2970,8 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev, struct atyfb_par *par = info->par; struct device_node *dp; char prop[128]; - int node, len, i, j, ret; + phandle node; + int len, i, j, ret; u32 mem, chip_id; /* -- cgit v0.10.2 From 9bdf6bab4ecfb6a8ca50c0c46f2365ef6c3e35b7 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Mon, 30 Aug 2010 03:57:28 +0000 Subject: sparc: break out some PROM device-tree building code out into drivers/of Transitioning into making this useful for architectures other than sparc. This is a verbatim copy of all functions/variables that've been moved. Signed-off-by: Andres Salomon Acked-by: David S. Miller Signed-off-by: Grant Likely diff --git a/arch/sparc/kernel/prom_common.c b/arch/sparc/kernel/prom_common.c index 1f830da..7b454f6 100644 --- a/arch/sparc/kernel/prom_common.c +++ b/arch/sparc/kernel/prom_common.c @@ -26,8 +26,6 @@ #include "prom.h" -void (*prom_build_more)(struct device_node *dp, struct device_node ***nextp); - struct device_node *of_console_device; EXPORT_SYMBOL(of_console_device); @@ -119,192 +117,6 @@ int of_find_in_proplist(const char *list, const char *match, int len) } EXPORT_SYMBOL(of_find_in_proplist); -unsigned int prom_unique_id; - -static struct property * __init build_one_prop(phandle node, char *prev, - char *special_name, - void *special_val, - int special_len) -{ - static struct property *tmp = NULL; - struct property *p; - const char *name; - - if (tmp) { - p = tmp; - memset(p, 0, sizeof(*p) + 32); - tmp = NULL; - } else { - p = prom_early_alloc(sizeof(struct property) + 32); - p->unique_id = prom_unique_id++; - } - - p->name = (char *) (p + 1); - if (special_name) { - strcpy(p->name, special_name); - p->length = special_len; - p->value = prom_early_alloc(special_len); - memcpy(p->value, special_val, special_len); - } else { - if (prev == NULL) { - name = prom_firstprop(node, p->name); - } else { - name = prom_nextprop(node, prev, p->name); - } - - if (!name || strlen(name) == 0) { - tmp = p; - return NULL; - } -#ifdef CONFIG_SPARC32 - strcpy(p->name, name); -#endif - p->length = prom_getproplen(node, p->name); - if (p->length <= 0) { - p->length = 0; - } else { - int len; - - p->value = prom_early_alloc(p->length + 1); - len = prom_getproperty(node, p->name, p->value, - p->length); - if (len <= 0) - p->length = 0; - ((unsigned char *)p->value)[p->length] = '\0'; - } - } - return p; -} - -static struct property * __init build_prop_list(phandle node) -{ - struct property *head, *tail; - - head = tail = build_one_prop(node, NULL, - ".node", &node, sizeof(node)); - - tail->next = build_one_prop(node, NULL, NULL, NULL, 0); - tail = tail->next; - while(tail) { - tail->next = build_one_prop(node, tail->name, - NULL, NULL, 0); - tail = tail->next; - } - - return head; -} - -static char * __init get_one_property(phandle node, const char *name) -{ - char *buf = ""; - int len; - - len = prom_getproplen(node, name); - if (len > 0) { - buf = prom_early_alloc(len); - len = prom_getproperty(node, name, buf, len); - } - - return buf; -} - -static struct device_node * __init prom_create_node(phandle node, - struct device_node *parent) -{ - struct device_node *dp; - - if (!node) - return NULL; - - dp = prom_early_alloc(sizeof(*dp)); - dp->unique_id = prom_unique_id++; - dp->parent = parent; - - kref_init(&dp->kref); - - dp->name = get_one_property(node, "name"); - dp->type = get_one_property(node, "device_type"); - dp->phandle = node; - - dp->properties = build_prop_list(node); - - irq_trans_init(dp); - - return dp; -} - -char * __init build_full_name(struct device_node *dp) -{ - int len, ourlen, plen; - char *n; - - plen = strlen(dp->parent->full_name); - ourlen = strlen(dp->path_component_name); - len = ourlen + plen + 2; - - n = prom_early_alloc(len); - strcpy(n, dp->parent->full_name); - if (!of_node_is_root(dp->parent)) { - strcpy(n + plen, "/"); - plen++; - } - strcpy(n + plen, dp->path_component_name); - - return n; -} - -static struct device_node * __init prom_build_tree(struct device_node *parent, - phandle node, - struct device_node ***nextp) -{ - struct device_node *ret = NULL, *prev_sibling = NULL; - struct device_node *dp; - - while (1) { - dp = prom_create_node(node, parent); - if (!dp) - break; - - if (prev_sibling) - prev_sibling->sibling = dp; - - if (!ret) - ret = dp; - prev_sibling = dp; - - *(*nextp) = dp; - *nextp = &dp->allnext; - - dp->path_component_name = build_path_component(dp); - dp->full_name = build_full_name(dp); - - dp->child = prom_build_tree(dp, prom_getchild(node), nextp); - - if (prom_build_more) - prom_build_more(dp, nextp); - - node = prom_getsibling(node); - } - - return ret; -} - unsigned int prom_early_allocated __initdata; -void __init prom_build_devicetree(void) -{ - struct device_node **nextp; - - allnodes = prom_create_node(prom_root_node, NULL); - allnodes->path_component_name = ""; - allnodes->full_name = "/"; - - nextp = &allnodes->allnext; - allnodes->child = prom_build_tree(allnodes, - prom_getchild(allnodes->phandle), - &nextp); - of_console_init(); - - printk("PROM: Built device tree with %u bytes of memory.\n", - prom_early_allocated); -} +#include "../../../drivers/of/pdt.c" diff --git a/drivers/of/pdt.c b/drivers/of/pdt.c new file mode 100644 index 0000000..c3c2d70 --- /dev/null +++ b/drivers/of/pdt.c @@ -0,0 +1,215 @@ +/* prom_common.c: OF device tree support common code. + * + * Paul Mackerras August 1996. + * Copyright (C) 1996-2005 Paul Mackerras. + * + * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner. + * {engebret|bergner}@us.ibm.com + * + * Adapted for sparc by David S. Miller davem@davemloft.net + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void (*prom_build_more)(struct device_node *dp, struct device_node ***nextp); + +unsigned int prom_unique_id; + +static struct property * __init build_one_prop(phandle node, char *prev, + char *special_name, + void *special_val, + int special_len) +{ + static struct property *tmp = NULL; + struct property *p; + const char *name; + + if (tmp) { + p = tmp; + memset(p, 0, sizeof(*p) + 32); + tmp = NULL; + } else { + p = prom_early_alloc(sizeof(struct property) + 32); + p->unique_id = prom_unique_id++; + } + + p->name = (char *) (p + 1); + if (special_name) { + strcpy(p->name, special_name); + p->length = special_len; + p->value = prom_early_alloc(special_len); + memcpy(p->value, special_val, special_len); + } else { + if (prev == NULL) { + name = prom_firstprop(node, p->name); + } else { + name = prom_nextprop(node, prev, p->name); + } + + if (!name || strlen(name) == 0) { + tmp = p; + return NULL; + } +#ifdef CONFIG_SPARC32 + strcpy(p->name, name); +#endif + p->length = prom_getproplen(node, p->name); + if (p->length <= 0) { + p->length = 0; + } else { + int len; + + p->value = prom_early_alloc(p->length + 1); + len = prom_getproperty(node, p->name, p->value, + p->length); + if (len <= 0) + p->length = 0; + ((unsigned char *)p->value)[p->length] = '\0'; + } + } + return p; +} + +static struct property * __init build_prop_list(phandle node) +{ + struct property *head, *tail; + + head = tail = build_one_prop(node, NULL, + ".node", &node, sizeof(node)); + + tail->next = build_one_prop(node, NULL, NULL, NULL, 0); + tail = tail->next; + while(tail) { + tail->next = build_one_prop(node, tail->name, + NULL, NULL, 0); + tail = tail->next; + } + + return head; +} + +static char * __init get_one_property(phandle node, const char *name) +{ + char *buf = ""; + int len; + + len = prom_getproplen(node, name); + if (len > 0) { + buf = prom_early_alloc(len); + len = prom_getproperty(node, name, buf, len); + } + + return buf; +} + +static struct device_node * __init prom_create_node(phandle node, + struct device_node *parent) +{ + struct device_node *dp; + + if (!node) + return NULL; + + dp = prom_early_alloc(sizeof(*dp)); + dp->unique_id = prom_unique_id++; + dp->parent = parent; + + kref_init(&dp->kref); + + dp->name = get_one_property(node, "name"); + dp->type = get_one_property(node, "device_type"); + dp->phandle = node; + + dp->properties = build_prop_list(node); + + irq_trans_init(dp); + + return dp; +} + +char * __init build_full_name(struct device_node *dp) +{ + int len, ourlen, plen; + char *n; + + plen = strlen(dp->parent->full_name); + ourlen = strlen(dp->path_component_name); + len = ourlen + plen + 2; + + n = prom_early_alloc(len); + strcpy(n, dp->parent->full_name); + if (!of_node_is_root(dp->parent)) { + strcpy(n + plen, "/"); + plen++; + } + strcpy(n + plen, dp->path_component_name); + + return n; +} + +static struct device_node * __init prom_build_tree(struct device_node *parent, + phandle node, + struct device_node ***nextp) +{ + struct device_node *ret = NULL, *prev_sibling = NULL; + struct device_node *dp; + + while (1) { + dp = prom_create_node(node, parent); + if (!dp) + break; + + if (prev_sibling) + prev_sibling->sibling = dp; + + if (!ret) + ret = dp; + prev_sibling = dp; + + *(*nextp) = dp; + *nextp = &dp->allnext; + + dp->path_component_name = build_path_component(dp); + dp->full_name = build_full_name(dp); + + dp->child = prom_build_tree(dp, prom_getchild(node), nextp); + + if (prom_build_more) + prom_build_more(dp, nextp); + + node = prom_getsibling(node); + } + + return ret; +} + +void __init prom_build_devicetree(void) +{ + struct device_node **nextp; + + allnodes = prom_create_node(prom_root_node, NULL); + allnodes->path_component_name = ""; + allnodes->full_name = "/"; + + nextp = &allnodes->allnext; + allnodes->child = prom_build_tree(allnodes, + prom_getchild(allnodes->phandle), + &nextp); + of_console_init(); + + printk("PROM: Built device tree with %u bytes of memory.\n", + prom_early_allocated); +} -- cgit v0.10.2 From 3cfc535c5df8122af1258ae05aaf2770c033425d Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Sun, 10 Oct 2010 21:42:33 -0600 Subject: of/promtree: make drivers/of/pdt.c no longer sparc-only Clean up pdt.c: - make build dependent upon config OF_PROMTREE - #ifdef out the sparc-specific stuff - create pdt-specific header Signed-off-by: Andres Salomon Acked-by: David S. Miller Signed-off-by: Grant Likely diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 491e9d6..a06c959 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -19,6 +19,7 @@ config SPARC bool default y select OF + select OF_PROMTREE select HAVE_IDE select HAVE_OPROFILE select HAVE_ARCH_KGDB if !SMP || SPARC64 diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h index 291f125..56bbaad 100644 --- a/arch/sparc/include/asm/prom.h +++ b/arch/sparc/include/asm/prom.h @@ -18,6 +18,7 @@ * 2 of the License, or (at your option) any later version. */ #include +#include #include #include #include @@ -67,8 +68,8 @@ extern struct device_node *of_console_device; extern char *of_console_path; extern char *of_console_options; -extern void (*prom_build_more)(struct device_node *dp, struct device_node ***nextp); -extern char *build_full_name(struct device_node *dp); +extern void irq_trans_init(struct device_node *dp); +extern char *build_path_component(struct device_node *dp); #endif /* __KERNEL__ */ #endif /* _SPARC_PROM_H */ diff --git a/arch/sparc/kernel/prom.h b/arch/sparc/kernel/prom.h index eeb04a7..cf5fe1c 100644 --- a/arch/sparc/kernel/prom.h +++ b/arch/sparc/kernel/prom.h @@ -4,12 +4,6 @@ #include #include -extern void * prom_early_alloc(unsigned long size); -extern void irq_trans_init(struct device_node *dp); - -extern unsigned int prom_unique_id; - -extern char *build_path_component(struct device_node *dp); extern void of_console_init(void); extern unsigned int prom_early_allocated; diff --git a/arch/sparc/kernel/prom_common.c b/arch/sparc/kernel/prom_common.c index 7b454f6..fe84d56 100644 --- a/arch/sparc/kernel/prom_common.c +++ b/arch/sparc/kernel/prom_common.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -119,4 +120,11 @@ EXPORT_SYMBOL(of_find_in_proplist); unsigned int prom_early_allocated __initdata; -#include "../../../drivers/of/pdt.c" +void __init prom_build_devicetree(void) +{ + of_pdt_build_devicetree(prom_root_node); + of_console_init(); + + pr_info("PROM: Built device tree with %u bytes of memory.\n", + prom_early_allocated); +} diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index 6acbff3..aa675eb 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -4,7 +4,7 @@ config DTC config OF bool -menu "Flattened Device Tree and Open Firmware support" +menu "Device Tree and Open Firmware support" depends on OF config PROC_DEVICETREE @@ -19,6 +19,9 @@ config OF_FLATTREE bool select DTC +config OF_PROMTREE + bool + config OF_DYNAMIC def_bool y depends on PPC_OF diff --git a/drivers/of/Makefile b/drivers/of/Makefile index 0052c40..7888155 100644 --- a/drivers/of/Makefile +++ b/drivers/of/Makefile @@ -1,5 +1,6 @@ obj-y = base.o obj-$(CONFIG_OF_FLATTREE) += fdt.o +obj-$(CONFIG_OF_PROMTREE) += pdt.o obj-$(CONFIG_OF_ADDRESS) += address.o obj-$(CONFIG_OF_IRQ) += irq.o obj-$(CONFIG_OF_DEVICE) += device.o platform.o diff --git a/drivers/of/pdt.c b/drivers/of/pdt.c index c3c2d70..2fdb1b4 100644 --- a/drivers/of/pdt.c +++ b/drivers/of/pdt.c @@ -1,4 +1,4 @@ -/* prom_common.c: OF device tree support common code. +/* pdt.c: OF PROM device tree support code. * * Paul Mackerras August 1996. * Copyright (C) 1996-2005 Paul Mackerras. @@ -7,6 +7,7 @@ * {engebret|bergner}@us.ibm.com * * Adapted for sparc by David S. Miller davem@davemloft.net + * Adapted for multiple architectures by Andres Salomon * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -20,13 +21,36 @@ #include #include #include +#include #include #include -#include -void (*prom_build_more)(struct device_node *dp, struct device_node ***nextp); +void __initdata (*prom_build_more)(struct device_node *dp, + struct device_node ***nextp); -unsigned int prom_unique_id; +#if defined(CONFIG_SPARC) +unsigned int of_pdt_unique_id __initdata; + +#define of_pdt_incr_unique_id(p) do { \ + (p)->unique_id = of_pdt_unique_id++; \ +} while (0) + +static inline const char *of_pdt_node_name(struct device_node *dp) +{ + return dp->path_component_name; +} + +#else + +static inline void of_pdt_incr_unique_id(void *p) { } +static inline void irq_trans_init(struct device_node *dp) { } + +static inline const char *of_pdt_node_name(struct device_node *dp) +{ + return dp->name; +} + +#endif /* !CONFIG_SPARC */ static struct property * __init build_one_prop(phandle node, char *prev, char *special_name, @@ -43,7 +67,7 @@ static struct property * __init build_one_prop(phandle node, char *prev, tmp = NULL; } else { p = prom_early_alloc(sizeof(struct property) + 32); - p->unique_id = prom_unique_id++; + of_pdt_incr_unique_id(p); } p->name = (char *) (p + 1); @@ -124,7 +148,7 @@ static struct device_node * __init prom_create_node(phandle node, return NULL; dp = prom_early_alloc(sizeof(*dp)); - dp->unique_id = prom_unique_id++; + of_pdt_incr_unique_id(dp); dp->parent = parent; kref_init(&dp->kref); @@ -140,13 +164,13 @@ static struct device_node * __init prom_create_node(phandle node, return dp; } -char * __init build_full_name(struct device_node *dp) +static char * __init build_full_name(struct device_node *dp) { int len, ourlen, plen; char *n; plen = strlen(dp->parent->full_name); - ourlen = strlen(dp->path_component_name); + ourlen = strlen(of_pdt_node_name(dp)); len = ourlen + plen + 2; n = prom_early_alloc(len); @@ -155,7 +179,7 @@ char * __init build_full_name(struct device_node *dp) strcpy(n + plen, "/"); plen++; } - strcpy(n + plen, dp->path_component_name); + strcpy(n + plen, of_pdt_node_name(dp)); return n; } @@ -182,7 +206,9 @@ static struct device_node * __init prom_build_tree(struct device_node *parent, *(*nextp) = dp; *nextp = &dp->allnext; +#if defined(CONFIG_SPARC) dp->path_component_name = build_path_component(dp); +#endif dp->full_name = build_full_name(dp); dp->child = prom_build_tree(dp, prom_getchild(node), nextp); @@ -196,20 +222,18 @@ static struct device_node * __init prom_build_tree(struct device_node *parent, return ret; } -void __init prom_build_devicetree(void) +void __init of_pdt_build_devicetree(phandle root_node) { struct device_node **nextp; - allnodes = prom_create_node(prom_root_node, NULL); + allnodes = prom_create_node(root_node, NULL); +#if defined(CONFIG_SPARC) allnodes->path_component_name = ""; +#endif allnodes->full_name = "/"; nextp = &allnodes->allnext; allnodes->child = prom_build_tree(allnodes, prom_getchild(allnodes->phandle), &nextp); - of_console_init(); - - printk("PROM: Built device tree with %u bytes of memory.\n", - prom_early_allocated); } diff --git a/include/linux/of_pdt.h b/include/linux/of_pdt.h new file mode 100644 index 0000000..c0a8774 --- /dev/null +++ b/include/linux/of_pdt.h @@ -0,0 +1,24 @@ +/* + * Definitions for building a device tree by calling into the + * Open Firmware PROM. + * + * Copyright (C) 2010 Andres Salomon + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _LINUX_OF_PDT_H +#define _LINUX_OF_PDT_H + +extern void *prom_early_alloc(unsigned long size); + +/* for building the device tree */ +extern void of_pdt_build_devicetree(phandle root_node); + +extern void (*prom_build_more)(struct device_node *dp, + struct device_node ***nextp); + +#endif /* _LINUX_OF_PDT_H */ -- cgit v0.10.2 From f90c34bd658d240cb5ebc5fe0a17796e590c6ec8 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Sun, 10 Oct 2010 21:49:45 -0600 Subject: of/promtree: no longer call prom_ functions directly; use an ops structure Rather than assuming an architecture defines prom_getchild and friends, define an ops struct with hooks for the various prom functions that pdt.c needs. This ops struct is filled in by the arch-(and sometimes firmware-)specific code, and passed to of_pdt_build_devicetree. Update sparc code to define the ops struct as well. Signed-off-by: Andres Salomon Acked-by: David S. Miller Signed-off-by: Grant Likely diff --git a/arch/sparc/kernel/prom_common.c b/arch/sparc/kernel/prom_common.c index fe84d56..ed25834 100644 --- a/arch/sparc/kernel/prom_common.c +++ b/arch/sparc/kernel/prom_common.c @@ -118,11 +118,45 @@ int of_find_in_proplist(const char *list, const char *match, int len) } EXPORT_SYMBOL(of_find_in_proplist); +/* + * SPARC32 and SPARC64's prom_nextprop() do things differently + * here, despite sharing the same interface. SPARC32 doesn't fill in 'buf', + * returning NULL on an error. SPARC64 fills in 'buf', but sets it to an + * empty string upon error. + */ +static int __init handle_nextprop_quirks(char *buf, const char *name) +{ + if (!name || strlen(name) == 0) + return -1; + +#ifdef CONFIG_SPARC32 + strcpy(buf, name); +#endif + return 0; +} + +static int __init prom_common_nextprop(phandle node, char *prev, char *buf) +{ + const char *name; + + buf[0] = '\0'; + name = prom_nextprop(node, prev, buf); + return handle_nextprop_quirks(buf, name); +} + unsigned int prom_early_allocated __initdata; +static struct of_pdt_ops prom_sparc_ops __initdata = { + .nextprop = prom_common_nextprop, + .getproplen = prom_getproplen, + .getproperty = prom_getproperty, + .getchild = prom_getchild, + .getsibling = prom_getsibling, +}; + void __init prom_build_devicetree(void) { - of_pdt_build_devicetree(prom_root_node); + of_pdt_build_devicetree(prom_root_node, &prom_sparc_ops); of_console_init(); pr_info("PROM: Built device tree with %u bytes of memory.\n", diff --git a/drivers/of/pdt.c b/drivers/of/pdt.c index 2fdb1b4..fd02fc1 100644 --- a/drivers/of/pdt.c +++ b/drivers/of/pdt.c @@ -23,7 +23,8 @@ #include #include #include -#include + +static struct of_pdt_ops *of_pdt_prom_ops __initdata; void __initdata (*prom_build_more)(struct device_node *dp, struct device_node ***nextp); @@ -59,7 +60,7 @@ static struct property * __init build_one_prop(phandle node, char *prev, { static struct property *tmp = NULL; struct property *p; - const char *name; + int err; if (tmp) { p = tmp; @@ -77,28 +78,20 @@ static struct property * __init build_one_prop(phandle node, char *prev, p->value = prom_early_alloc(special_len); memcpy(p->value, special_val, special_len); } else { - if (prev == NULL) { - name = prom_firstprop(node, p->name); - } else { - name = prom_nextprop(node, prev, p->name); - } - - if (!name || strlen(name) == 0) { + err = of_pdt_prom_ops->nextprop(node, prev, p->name); + if (err) { tmp = p; return NULL; } -#ifdef CONFIG_SPARC32 - strcpy(p->name, name); -#endif - p->length = prom_getproplen(node, p->name); + p->length = of_pdt_prom_ops->getproplen(node, p->name); if (p->length <= 0) { p->length = 0; } else { int len; p->value = prom_early_alloc(p->length + 1); - len = prom_getproperty(node, p->name, p->value, - p->length); + len = of_pdt_prom_ops->getproperty(node, p->name, + p->value, p->length); if (len <= 0) p->length = 0; ((unsigned char *)p->value)[p->length] = '\0'; @@ -130,10 +123,10 @@ static char * __init get_one_property(phandle node, const char *name) char *buf = ""; int len; - len = prom_getproplen(node, name); + len = of_pdt_prom_ops->getproplen(node, name); if (len > 0) { buf = prom_early_alloc(len); - len = prom_getproperty(node, name, buf, len); + len = of_pdt_prom_ops->getproperty(node, name, buf, len); } return buf; @@ -211,21 +204,25 @@ static struct device_node * __init prom_build_tree(struct device_node *parent, #endif dp->full_name = build_full_name(dp); - dp->child = prom_build_tree(dp, prom_getchild(node), nextp); + dp->child = prom_build_tree(dp, + of_pdt_prom_ops->getchild(node), nextp); if (prom_build_more) prom_build_more(dp, nextp); - node = prom_getsibling(node); + node = of_pdt_prom_ops->getsibling(node); } return ret; } -void __init of_pdt_build_devicetree(phandle root_node) +void __init of_pdt_build_devicetree(phandle root_node, struct of_pdt_ops *ops) { struct device_node **nextp; + BUG_ON(!ops); + of_pdt_prom_ops = ops; + allnodes = prom_create_node(root_node, NULL); #if defined(CONFIG_SPARC) allnodes->path_component_name = ""; @@ -234,6 +231,5 @@ void __init of_pdt_build_devicetree(phandle root_node) nextp = &allnodes->allnext; allnodes->child = prom_build_tree(allnodes, - prom_getchild(allnodes->phandle), - &nextp); + of_pdt_prom_ops->getchild(allnodes->phandle), &nextp); } diff --git a/include/linux/of_pdt.h b/include/linux/of_pdt.h index c0a8774..303c5ff 100644 --- a/include/linux/of_pdt.h +++ b/include/linux/of_pdt.h @@ -13,10 +13,28 @@ #ifndef _LINUX_OF_PDT_H #define _LINUX_OF_PDT_H +/* overridable operations for calling into the PROM */ +struct of_pdt_ops { + /* + * buf should be 32 bytes; return 0 on success. + * If prev is NULL, the first property will be returned. + */ + int (*nextprop)(phandle node, char *prev, char *buf); + + /* for both functions, return proplen on success; -1 on error */ + int (*getproplen)(phandle node, const char *prop); + int (*getproperty)(phandle node, const char *prop, char *buf, + int bufsize); + + /* phandles are 0 if no child or sibling exists */ + phandle (*getchild)(phandle parent); + phandle (*getsibling)(phandle node); +}; + extern void *prom_early_alloc(unsigned long size); /* for building the device tree */ -extern void of_pdt_build_devicetree(phandle root_node); +extern void of_pdt_build_devicetree(phandle root_node, struct of_pdt_ops *ops); extern void (*prom_build_more)(struct device_node *dp, struct device_node ***nextp); -- cgit v0.10.2 From ed41850298f7a55519de0b8573e217ed8a45c199 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Sun, 10 Oct 2010 21:51:25 -0600 Subject: of/promtree: add of_pdt namespace to pdt code For symbols still lacking namespace qualifiers, add an of_pdt_ prefix. Signed-off-by: Andres Salomon Acked-by: David S. Miller Signed-off-by: Grant Likely diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c index 6a7b4db..2d51527 100644 --- a/arch/sparc/kernel/leon_kernel.c +++ b/arch/sparc/kernel/leon_kernel.c @@ -282,5 +282,5 @@ void __init leon_init_IRQ(void) void __init leon_init(void) { - prom_build_more = &leon_node_init; + of_pdt_build_more = &leon_node_init; } diff --git a/drivers/of/pdt.c b/drivers/of/pdt.c index fd02fc1..31a4fb8 100644 --- a/drivers/of/pdt.c +++ b/drivers/of/pdt.c @@ -26,7 +26,7 @@ static struct of_pdt_ops *of_pdt_prom_ops __initdata; -void __initdata (*prom_build_more)(struct device_node *dp, +void __initdata (*of_pdt_build_more)(struct device_node *dp, struct device_node ***nextp); #if defined(CONFIG_SPARC) @@ -53,7 +53,7 @@ static inline const char *of_pdt_node_name(struct device_node *dp) #endif /* !CONFIG_SPARC */ -static struct property * __init build_one_prop(phandle node, char *prev, +static struct property * __init of_pdt_build_one_prop(phandle node, char *prev, char *special_name, void *special_val, int special_len) @@ -100,17 +100,17 @@ static struct property * __init build_one_prop(phandle node, char *prev, return p; } -static struct property * __init build_prop_list(phandle node) +static struct property * __init of_pdt_build_prop_list(phandle node) { struct property *head, *tail; - head = tail = build_one_prop(node, NULL, + head = tail = of_pdt_build_one_prop(node, NULL, ".node", &node, sizeof(node)); - tail->next = build_one_prop(node, NULL, NULL, NULL, 0); + tail->next = of_pdt_build_one_prop(node, NULL, NULL, NULL, 0); tail = tail->next; while(tail) { - tail->next = build_one_prop(node, tail->name, + tail->next = of_pdt_build_one_prop(node, tail->name, NULL, NULL, 0); tail = tail->next; } @@ -118,7 +118,7 @@ static struct property * __init build_prop_list(phandle node) return head; } -static char * __init get_one_property(phandle node, const char *name) +static char * __init of_pdt_get_one_property(phandle node, const char *name) { char *buf = ""; int len; @@ -132,7 +132,7 @@ static char * __init get_one_property(phandle node, const char *name) return buf; } -static struct device_node * __init prom_create_node(phandle node, +static struct device_node * __init of_pdt_create_node(phandle node, struct device_node *parent) { struct device_node *dp; @@ -146,18 +146,18 @@ static struct device_node * __init prom_create_node(phandle node, kref_init(&dp->kref); - dp->name = get_one_property(node, "name"); - dp->type = get_one_property(node, "device_type"); + dp->name = of_pdt_get_one_property(node, "name"); + dp->type = of_pdt_get_one_property(node, "device_type"); dp->phandle = node; - dp->properties = build_prop_list(node); + dp->properties = of_pdt_build_prop_list(node); irq_trans_init(dp); return dp; } -static char * __init build_full_name(struct device_node *dp) +static char * __init of_pdt_build_full_name(struct device_node *dp) { int len, ourlen, plen; char *n; @@ -177,7 +177,7 @@ static char * __init build_full_name(struct device_node *dp) return n; } -static struct device_node * __init prom_build_tree(struct device_node *parent, +static struct device_node * __init of_pdt_build_tree(struct device_node *parent, phandle node, struct device_node ***nextp) { @@ -185,7 +185,7 @@ static struct device_node * __init prom_build_tree(struct device_node *parent, struct device_node *dp; while (1) { - dp = prom_create_node(node, parent); + dp = of_pdt_create_node(node, parent); if (!dp) break; @@ -202,13 +202,13 @@ static struct device_node * __init prom_build_tree(struct device_node *parent, #if defined(CONFIG_SPARC) dp->path_component_name = build_path_component(dp); #endif - dp->full_name = build_full_name(dp); + dp->full_name = of_pdt_build_full_name(dp); - dp->child = prom_build_tree(dp, + dp->child = of_pdt_build_tree(dp, of_pdt_prom_ops->getchild(node), nextp); - if (prom_build_more) - prom_build_more(dp, nextp); + if (of_pdt_build_more) + of_pdt_build_more(dp, nextp); node = of_pdt_prom_ops->getsibling(node); } @@ -223,13 +223,13 @@ void __init of_pdt_build_devicetree(phandle root_node, struct of_pdt_ops *ops) BUG_ON(!ops); of_pdt_prom_ops = ops; - allnodes = prom_create_node(root_node, NULL); + allnodes = of_pdt_create_node(root_node, NULL); #if defined(CONFIG_SPARC) allnodes->path_component_name = ""; #endif allnodes->full_name = "/"; nextp = &allnodes->allnext; - allnodes->child = prom_build_tree(allnodes, + allnodes->child = of_pdt_build_tree(allnodes, of_pdt_prom_ops->getchild(allnodes->phandle), &nextp); } diff --git a/include/linux/of_pdt.h b/include/linux/of_pdt.h index 303c5ff..0f7d0c5 100644 --- a/include/linux/of_pdt.h +++ b/include/linux/of_pdt.h @@ -36,7 +36,7 @@ extern void *prom_early_alloc(unsigned long size); /* for building the device tree */ extern void of_pdt_build_devicetree(phandle root_node, struct of_pdt_ops *ops); -extern void (*prom_build_more)(struct device_node *dp, +extern void (*of_pdt_build_more)(struct device_node *dp, struct device_node ***nextp); #endif /* _LINUX_OF_PDT_H */ -- cgit v0.10.2 From e2f2a93b6384cfe0face0be595bfbda1475d864b Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Sun, 10 Oct 2010 21:52:57 -0600 Subject: of/promtree: add package-to-path support to pdt package-to-path is a PROM function which tells us the real (full) name of the node. This provides a hook for that in the prom ops struct, and makes use of it in the pdt code when attempting to determine a node's name. If the hook is available, try using it (falling back to looking at the "name" property if it fails). Signed-off-by: Andres Salomon Signed-off-by: Grant Likely diff --git a/drivers/of/pdt.c b/drivers/of/pdt.c index 31a4fb8..28295d0 100644 --- a/drivers/of/pdt.c +++ b/drivers/of/pdt.c @@ -132,6 +132,47 @@ static char * __init of_pdt_get_one_property(phandle node, const char *name) return buf; } +static char * __init of_pdt_try_pkg2path(phandle node) +{ + char *res, *buf = NULL; + int len; + + if (!of_pdt_prom_ops->pkg2path) + return NULL; + + if (of_pdt_prom_ops->pkg2path(node, buf, 0, &len)) + return NULL; + buf = prom_early_alloc(len + 1); + if (of_pdt_prom_ops->pkg2path(node, buf, len, &len)) { + pr_err("%s: package-to-path failed\n", __func__); + return NULL; + } + + res = strrchr(buf, '/'); + if (!res) { + pr_err("%s: couldn't find / in %s\n", __func__, buf); + return NULL; + } + return res+1; +} + +/* + * When fetching the node's name, first try using package-to-path; if + * that fails (either because the arch hasn't supplied a PROM callback, + * or some other random failure), fall back to just looking at the node's + * 'name' property. + */ +static char * __init of_pdt_build_name(phandle node) +{ + char *buf; + + buf = of_pdt_try_pkg2path(node); + if (!buf) + buf = of_pdt_get_one_property(node, "name"); + + return buf; +} + static struct device_node * __init of_pdt_create_node(phandle node, struct device_node *parent) { @@ -146,7 +187,7 @@ static struct device_node * __init of_pdt_create_node(phandle node, kref_init(&dp->kref); - dp->name = of_pdt_get_one_property(node, "name"); + dp->name = of_pdt_build_name(node); dp->type = of_pdt_get_one_property(node, "device_type"); dp->phandle = node; diff --git a/include/linux/of_pdt.h b/include/linux/of_pdt.h index 0f7d0c5..c65a18a 100644 --- a/include/linux/of_pdt.h +++ b/include/linux/of_pdt.h @@ -29,6 +29,9 @@ struct of_pdt_ops { /* phandles are 0 if no child or sibling exists */ phandle (*getchild)(phandle parent); phandle (*getsibling)(phandle node); + + /* return 0 on success; fill in 'len' with number of bytes in path */ + int (*pkg2path)(phandle node, char *buf, const int buflen, int *len); }; extern void *prom_early_alloc(unsigned long size); -- cgit v0.10.2 From 52f6537cb2f0b461a9ce3457c01a6cfa2ae0bb22 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Sun, 10 Oct 2010 21:35:05 -0600 Subject: of/irq: remove references to NO_IRQ in drivers/of/platform.c Instead of referencing NO_IRQ in platform.c, define some helper functions in irq.c to call instead from platform.c. Keep NO_IRQ usage local to irq.c, and define NO_IRQ if not defined in headers. Signed-off-by: Andres Salomon Signed-off-by: Grant Likely diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 6e595e5..75b0d3c 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -24,6 +24,11 @@ #include #include +/* For archs that don't support NO_IRQ (such as x86), provide a dummy value */ +#ifndef NO_IRQ +#define NO_IRQ 0 +#endif + /** * irq_of_parse_and_map - Parse and map an interrupt into linux virq space * @device: Device node of the device whose interrupt is to be mapped @@ -347,3 +352,37 @@ int of_irq_to_resource(struct device_node *dev, int index, struct resource *r) return irq; } EXPORT_SYMBOL_GPL(of_irq_to_resource); + +/** + * of_irq_count - Count the number of IRQs a node uses + * @dev: pointer to device tree node + */ +int of_irq_count(struct device_node *dev) +{ + int nr = 0; + + while (of_irq_to_resource(dev, nr, NULL) != NO_IRQ) + nr++; + + return nr; +} + +/** + * of_irq_to_resource_table - Fill in resource table with node's IRQ info + * @dev: pointer to device tree node + * @res: array of resources to fill in + * @nr_irqs: the number of IRQs (and upper bound for num of @res elements) + * + * Returns the size of the filled in table (up to @nr_irqs). + */ +int of_irq_to_resource_table(struct device_node *dev, struct resource *res, + int nr_irqs) +{ + int i; + + for (i = 0; i < nr_irqs; i++, res++) + if (of_irq_to_resource(dev, i, res) == NO_IRQ) + break; + + return i; +} diff --git a/drivers/of/platform.c b/drivers/of/platform.c index bb72223..30726c8 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -584,14 +584,13 @@ struct platform_device *of_device_alloc(struct device_node *np, struct device *parent) { struct platform_device *dev; - int rc, i, num_reg = 0, num_irq = 0; + int rc, i, num_reg = 0, num_irq; struct resource *res, temp_res; /* First count how many resources are needed */ while (of_address_to_resource(np, num_reg, &temp_res) == 0) num_reg++; - while (of_irq_to_resource(np, num_irq, &temp_res) != NO_IRQ) - num_irq++; + num_irq = of_irq_count(np); /* Allocate memory for both the struct device and the resource table */ dev = kzalloc(sizeof(*dev) + (sizeof(*res) * (num_reg + num_irq)), @@ -608,10 +607,7 @@ struct platform_device *of_device_alloc(struct device_node *np, rc = of_address_to_resource(np, i, res); WARN_ON(rc); } - for (i = 0; i < num_irq; i++, res++) { - rc = of_irq_to_resource(np, i, res); - WARN_ON(rc == NO_IRQ); - } + WARN_ON(of_irq_to_resource_table(np, res, num_irq) != num_irq); } dev->dev.of_node = of_node_get(np); diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h index 5929781..090cbaa 100644 --- a/include/linux/of_irq.h +++ b/include/linux/of_irq.h @@ -64,6 +64,9 @@ extern unsigned int irq_create_of_mapping(struct device_node *controller, unsigned int intsize); extern int of_irq_to_resource(struct device_node *dev, int index, struct resource *r); +extern int of_irq_count(struct device_node *dev); +extern int of_irq_to_resource_table(struct device_node *dev, + struct resource *res, int nr_irqs); #endif /* CONFIG_OF_IRQ */ #endif /* CONFIG_OF */ -- cgit v0.10.2 From a9fadeefdc869ff792591f57a9e33d8790d63292 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Sun, 10 Oct 2010 21:24:10 -0600 Subject: of: use __be32 types for big-endian device tree data Use the sparse annotations so we can keep track of endianness. Signed-off-by: Jeremy Kerr Signed-off-by: Grant Likely diff --git a/drivers/of/address.c b/drivers/of/address.c index fcadb72..3a1c7e7 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -163,7 +163,7 @@ static int of_bus_pci_translate(u32 *addr, u64 offset, int na) const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, unsigned int *flags) { - const u32 *prop; + const __be32 *prop; unsigned int psize; struct device_node *parent; struct of_bus *bus; diff --git a/drivers/of/base.c b/drivers/of/base.c index aa80525..710b53b 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -33,7 +33,7 @@ DEFINE_RWLOCK(devtree_lock); int of_n_addr_cells(struct device_node *np) { - const int *ip; + const __be32 *ip; do { if (np->parent) @@ -49,7 +49,7 @@ EXPORT_SYMBOL(of_n_addr_cells); int of_n_size_cells(struct device_node *np) { - const int *ip; + const __be32 *ip; do { if (np->parent) -- cgit v0.10.2 From bda80da469a93122121de601dd469ce1aaa6effa Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 18 Oct 2010 15:33:09 +1000 Subject: of/xsysace: Fix OF probing on little-endian systems Convert big-endian DTB to little-endian if necessary. Signed-off-by: Michal Simek Signed-off-by: Grant Likely diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index 057413b..66911d3 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c @@ -1224,7 +1224,8 @@ ace_of_probe(struct platform_device *op, const struct of_device_id *match) bus_width = ACE_BUS_WIDTH_8; /* Call the bus-independant setup code */ - return ace_alloc(&op->dev, id ? *id : 0, physaddr, irq, bus_width); + return ace_alloc(&op->dev, id ? be32_to_cpup(id) : 0, + physaddr, irq, bus_width); } static int __devexit ace_of_remove(struct platform_device *op) -- cgit v0.10.2 From 7096d0422153ffcc2264eef652fc3a7bca3e6d3c Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Wed, 20 Oct 2010 11:45:13 -0600 Subject: of/device: Rework to use common platform_device_alloc() for allocating devices The current code allocates and manages platform_devices created from the device tree manually. It also uses an unsafe shortcut for allocating the platform_device and the resource table at the same time. (which I added in the last rework; sorry). This patch refactors the code to use platform_device_alloc() for allocating new devices. This reduces the amount of custom code implemented by of_platform, eliminates the unsafe alloc trick, and has the side benefit of letting the platform_bus code manage freeing the device data and resources when the device is freed. Signed-off-by: Grant Likely Cc: Benjamin Herrenschmidt Cc: Greg Kroah-Hartman Cc: "David S. Miller" Cc: Michal Simek diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index 9b626cf..f62efdf 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c @@ -162,13 +162,10 @@ static int ibmebus_create_device(struct device_node *dn) dev->dev.bus = &ibmebus_bus_type; dev->dev.archdata.dma_ops = &ibmebus_dma_ops; - ret = of_device_register(dev); - if (ret) { - of_device_free(dev); - return ret; - } - - return 0; + ret = of_device_add(dev); + if (ret) + platform_device_put(dev); + return ret; } static int ibmebus_create_devices(const struct of_device_id *matches) diff --git a/drivers/base/platform.c b/drivers/base/platform.c index c6c933f..2fff59c 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -147,6 +147,7 @@ static void platform_device_release(struct device *dev) struct platform_object *pa = container_of(dev, struct platform_object, pdev.dev); + of_device_node_put(&pa->pdev.dev); kfree(pa->pdev.dev.platform_data); kfree(pa->pdev.resource); kfree(pa); diff --git a/drivers/of/device.c b/drivers/of/device.c index 92de0eb..45d8653 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -81,29 +81,10 @@ struct device_attribute of_platform_device_attrs[] = { __ATTR_NULL }; -/** - * of_release_dev - free an of device structure when all users of it are finished. - * @dev: device that's been disconnected - * - * Will be called only by the device core when all users of this of device are - * done. - */ -void of_release_dev(struct device *dev) -{ - struct platform_device *ofdev; - - ofdev = to_platform_device(dev); - of_node_put(ofdev->dev.of_node); - kfree(ofdev); -} -EXPORT_SYMBOL(of_release_dev); - -int of_device_register(struct platform_device *ofdev) +int of_device_add(struct platform_device *ofdev) { BUG_ON(ofdev->dev.of_node == NULL); - device_initialize(&ofdev->dev); - /* name and id have to be set so that the platform bus doesn't get * confused on matching */ ofdev->name = dev_name(&ofdev->dev); @@ -117,6 +98,12 @@ int of_device_register(struct platform_device *ofdev) return device_add(&ofdev->dev); } + +int of_device_register(struct platform_device *pdev) +{ + device_initialize(&pdev->dev); + return of_device_add(pdev); +} EXPORT_SYMBOL(of_device_register); void of_device_unregister(struct platform_device *ofdev) diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 30726c8..5b4a07f 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -587,20 +587,23 @@ struct platform_device *of_device_alloc(struct device_node *np, int rc, i, num_reg = 0, num_irq; struct resource *res, temp_res; - /* First count how many resources are needed */ + dev = platform_device_alloc("", -1); + if (!dev) + return NULL; + + /* count the io and irq resources */ while (of_address_to_resource(np, num_reg, &temp_res) == 0) num_reg++; num_irq = of_irq_count(np); - /* Allocate memory for both the struct device and the resource table */ - dev = kzalloc(sizeof(*dev) + (sizeof(*res) * (num_reg + num_irq)), - GFP_KERNEL); - if (!dev) - return NULL; - res = (struct resource *) &dev[1]; - /* Populate the resource table */ if (num_irq || num_reg) { + res = kzalloc(sizeof(*res) * (num_irq + num_reg), GFP_KERNEL); + if (!res) { + platform_device_put(dev); + return NULL; + } + dev->num_resources = num_reg + num_irq; dev->resource = res; for (i = 0; i < num_reg; i++, res++) { @@ -615,7 +618,6 @@ struct platform_device *of_device_alloc(struct device_node *np, dev->dev.dma_mask = &dev->archdata.dma_mask; #endif dev->dev.parent = parent; - dev->dev.release = of_release_dev; if (bus_id) dev_set_name(&dev->dev, "%s", bus_id); @@ -653,8 +655,8 @@ struct platform_device *of_platform_device_create(struct device_node *np, * to do such, possibly using a device notifier */ - if (of_device_register(dev) != 0) { - of_device_free(dev); + if (of_device_add(dev) != 0) { + platform_device_put(dev); return NULL; } diff --git a/include/linux/of_device.h b/include/linux/of_device.h index 835f85e..975d347 100644 --- a/include/linux/of_device.h +++ b/include/linux/of_device.h @@ -27,20 +27,19 @@ static inline int of_driver_match_device(const struct device *dev, extern struct platform_device *of_dev_get(struct platform_device *dev); extern void of_dev_put(struct platform_device *dev); +extern int of_device_add(struct platform_device *pdev); extern int of_device_register(struct platform_device *ofdev); extern void of_device_unregister(struct platform_device *ofdev); -extern void of_release_dev(struct device *dev); - -static inline void of_device_free(struct platform_device *dev) -{ - of_release_dev(&dev->dev); -} extern ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len); extern int of_device_uevent(struct device *dev, struct kobj_uevent_env *env); +static inline void of_device_node_put(struct device *dev) +{ + of_node_put(dev->of_node); +} #else /* CONFIG_OF_DEVICE */ @@ -56,6 +55,8 @@ static inline int of_device_uevent(struct device *dev, return -ENODEV; } +static inline void of_device_node_put(struct device *dev) { } + #endif /* CONFIG_OF_DEVICE */ #endif /* _LINUX_OF_DEVICE_H */ -- cgit v0.10.2 From 32c97689c46b272302053778f1a6c2facb0e220c Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Wed, 20 Oct 2010 11:45:14 -0600 Subject: of/flattree: Eliminate need to provide early_init_dt_scan_chosen_arch This patch refactors the early init parsing of the chosen node so that architectures aren't forced to provide an empty implementation of early_init_dt_scan_chosen_arch. Instead, if an architecture wants to do something different, it can either use a wrapper function around early_init_dt_scan_chosen(), or it can replace it altogether. This patch was written in preparation to adding device tree support to both x86 ad MIPS. Signed-off-by: Grant Likely Tested-by: David Daney diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c index 427b13b..bacbd3d 100644 --- a/arch/microblaze/kernel/prom.c +++ b/arch/microblaze/kernel/prom.c @@ -42,11 +42,6 @@ #include #include -void __init early_init_dt_scan_chosen_arch(unsigned long node) -{ - /* No Microblaze specific code here */ -} - void __init early_init_dt_add_memory_arch(u64 base, u64 size) { memblock_add(base, size); diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index fed9bf6..e296aae 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -363,10 +363,15 @@ static int __init early_init_dt_scan_cpus(unsigned long node, return 0; } -void __init early_init_dt_scan_chosen_arch(unsigned long node) +int __init early_init_dt_scan_chosen_ppc(unsigned long node, const char *uname, + int depth, void *data) { unsigned long *lprop; + /* Use common scan routine to determine if this is the chosen node */ + if (early_init_dt_scan_chosen(node, uname, depth, data) == 0) + return 0; + #ifdef CONFIG_PPC64 /* check if iommu is forced on or off */ if (of_get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL) @@ -398,6 +403,9 @@ void __init early_init_dt_scan_chosen_arch(unsigned long node) if (lprop) crashk_res.end = crashk_res.start + *lprop - 1; #endif + + /* break now */ + return 1; } #ifdef CONFIG_PPC_PSERIES @@ -679,7 +687,7 @@ void __init early_init_devtree(void *params) * device-tree, including the platform type, initrd location and * size, TCE reserve, and more ... */ - of_scan_flat_dt(early_init_dt_scan_chosen, NULL); + of_scan_flat_dt(early_init_dt_scan_chosen_ppc, NULL); /* Scan memory nodes and rebuild MEMBLOCKs */ memblock_init(); diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 65da5ae..c1360e0 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -533,8 +533,6 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, 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 */ diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h index 71e1a91..7bbf5b3 100644 --- a/include/linux/of_fdt.h +++ b/include/linux/of_fdt.h @@ -72,7 +72,7 @@ extern void *of_get_flat_dt_prop(unsigned long node, const char *name, unsigned long *size); extern int of_flat_dt_is_compatible(unsigned long node, const char *name); extern unsigned long of_get_flat_dt_root(void); -extern void early_init_dt_scan_chosen_arch(unsigned long node); + extern int early_init_dt_scan_chosen(unsigned long node, const char *uname, int depth, void *data); extern void early_init_dt_check_for_initrd(unsigned long node); -- cgit v0.10.2 From f2ffa5ab74f4dfd598860f96ca37a71c4d0a28a8 Mon Sep 17 00:00:00 2001 From: Dezhong Diao Date: Wed, 13 Oct 2010 00:52:46 -0600 Subject: of/mips: Add device tree support to MIPS Add the ability to enable CONFIG_OF on the MIPS architecture. Signed-off-by: Dezhong Diao [grant.likely@secretlab.ca: cleared out obsolete hooks, removed ARCH_HAS_DEVTREE_MEM, remove __init tags from header file, removed debugfs support hunk] [ddaney@linux-mips.org: backed out over aggressive trimming of hooks] Acked-by: Ralf Baechle Tested-by: David Daney Signed-off-by: Grant Likely diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 3ad59dd..21c75a8 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -2107,6 +2107,13 @@ config SECCOMP If unsure, say Y. Only embedded should say N here. +config USE_OF + bool "Flattened Device Tree support" + select OF + select OF_FLATTREE + help + Include support for flattened device tree machine descriptions. + endmenu config LOCKDEP_SUPPORT diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h index dea4aed..b003ed5 100644 --- a/arch/mips/include/asm/irq.h +++ b/arch/mips/include/asm/irq.h @@ -16,6 +16,11 @@ #include +static inline void irq_dispose_mapping(unsigned int virq) +{ + return; +} + #ifdef CONFIG_I8259 static inline int irq_canonicalize(int irq) { diff --git a/arch/mips/include/asm/prom.h b/arch/mips/include/asm/prom.h new file mode 100644 index 0000000..23f8237 --- /dev/null +++ b/arch/mips/include/asm/prom.h @@ -0,0 +1,35 @@ +/* + * arch/mips/include/asm/prom.h + * + * Copyright (C) 2010 Cisco Systems Inc. + * + * 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. + * + */ +#ifndef __ASM_MIPS_PROM_H +#define __ASM_MIPS_PROM_H + +#ifdef CONFIG_OF +#include + +#include +#include +#include + +/* which is compatible with the flattened device tree (FDT) */ +#define cmd_line arcs_cmdline + +extern int early_init_dt_scan_memory_arch(unsigned long node, + const char *uname, int depth, void *data); + +extern int reserve_mem_mach(unsigned long addr, unsigned long size); +extern void free_mem_mach(unsigned long addr, unsigned long size); + +extern void __init device_tree_init(void); +#else /* CONFIG_OF */ +static inline void __init device_tree_init(void) { } +#endif /* CONFIG_OF */ + +#endif /* _ASM_MIPS_PROM_H */ diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 06f8482..8088498 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -96,6 +96,8 @@ obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_SPINLOCK_TEST) += spinlock_test.o +obj-$(CONFIG_OF) += prom.o + CFLAGS_cpu-bugs64.o = $(shell if $(CC) $(KBUILD_CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi) obj-$(CONFIG_HAVE_STD_PC_SERIAL_PORT) += 8250-platform.o diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c new file mode 100644 index 0000000..e000b27 --- /dev/null +++ b/arch/mips/kernel/prom.c @@ -0,0 +1,112 @@ +/* + * MIPS support for CONFIG_OF device tree support + * + * Copyright (C) 2010 Cisco Systems Inc. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +int __init early_init_dt_scan_memory_arch(unsigned long node, + const char *uname, int depth, + void *data) +{ + return early_init_dt_scan_memory(node, uname, depth, data); +} + +void __init early_init_dt_add_memory_arch(u64 base, u64 size) +{ + return add_memory_region(base, size, BOOT_MEM_RAM); +} + +int __init reserve_mem_mach(unsigned long addr, unsigned long size) +{ + return reserve_bootmem(addr, size, BOOTMEM_DEFAULT); +} + +void __init free_mem_mach(unsigned long addr, unsigned long size) +{ + return free_bootmem(addr, size); +} + +u64 __init early_init_dt_alloc_memory_arch(u64 size, u64 align) +{ + return virt_to_phys( + __alloc_bootmem(size, align, __pa(MAX_DMA_ADDRESS)) + ); +} + +#ifdef CONFIG_BLK_DEV_INITRD +void __init early_init_dt_setup_initrd_arch(unsigned long start, + unsigned long end) +{ + initrd_start = (unsigned long)__va(start); + initrd_end = (unsigned long)__va(end); + initrd_below_start_ok = 1; +} +#endif + +/* + * irq_create_of_mapping - Hook to resolve OF irq specifier into a Linux irq# + * + * Currently the mapping mechanism is trivial; simple flat hwirq numbers are + * mapped 1:1 onto Linux irq numbers. Cascaded irq controllers are not + * supported. + */ +unsigned int irq_create_of_mapping(struct device_node *controller, + const u32 *intspec, unsigned int intsize) +{ + return intspec[0]; +} +EXPORT_SYMBOL_GPL(irq_create_of_mapping); + +void __init early_init_devtree(void *params) +{ + /* Setup flat device-tree pointer */ + initial_boot_params = params; + + /* Retrieve various informations from the /chosen node of the + * device-tree, including the platform type, initrd location and + * size, and more ... + */ + of_scan_flat_dt(early_init_dt_scan_chosen, NULL); + + /* Scan memory nodes */ + of_scan_flat_dt(early_init_dt_scan_root, NULL); + of_scan_flat_dt(early_init_dt_scan_memory_arch, NULL); +} + +void __init device_tree_init(void) +{ + unsigned long base, size; + + if (!initial_boot_params) + return; + + base = virt_to_phys((void *)initial_boot_params); + size = initial_boot_params->totalsize; + + /* Before we do anything, lets reserve the dt blob */ + reserve_mem_mach(base, size); + + unflatten_device_tree(); + + /* free the space reserved for the dt blob */ + free_mem_mach(base, size); +} diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 85aef3f..a6b900f 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -31,6 +31,7 @@ #include #include #include +#include struct cpuinfo_mips cpu_data[NR_CPUS] __read_mostly; @@ -487,6 +488,7 @@ static void __init arch_mem_init(char **cmdline_p) } bootmem_init(); + device_tree_init(); sparse_init(); paging_init(); } -- cgit v0.10.2 From 4c60071c1ea3e204b9dc25c7519f7beef355d47f Mon Sep 17 00:00:00 2001 From: David Daney Date: Tue, 19 Oct 2010 15:50:31 -0700 Subject: of/mips: Cleanup some include directives/files. The __init directives should go on the definitions of things, not the declaration, also __init is meaningless for inline functions, so remove it from prom.h. This allows us to get rid of a useless #include, but most of the rest of them are useless too, so kill them as well. If of_i2c.c needs irq definitions, it should include linux/irq.h directly, not assume indirect inclusion via asm/prom.h. Signed-off-by: David Daney Acked-by: Ralf Baechle Signed-off-by: Grant Likely diff --git a/arch/mips/include/asm/prom.h b/arch/mips/include/asm/prom.h index 23f8237..f29b862 100644 --- a/arch/mips/include/asm/prom.h +++ b/arch/mips/include/asm/prom.h @@ -12,10 +12,6 @@ #define __ASM_MIPS_PROM_H #ifdef CONFIG_OF -#include - -#include -#include #include /* which is compatible with the flattened device tree (FDT) */ @@ -27,9 +23,9 @@ extern int early_init_dt_scan_memory_arch(unsigned long node, extern int reserve_mem_mach(unsigned long addr, unsigned long size); extern void free_mem_mach(unsigned long addr, unsigned long size); -extern void __init device_tree_init(void); +extern void device_tree_init(void); #else /* CONFIG_OF */ -static inline void __init device_tree_init(void) { } +static inline void device_tree_init(void) { } #endif /* CONFIG_OF */ #endif /* _ASM_MIPS_PROM_H */ diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c index 0a694de..c85d3c7 100644 --- a/drivers/of/of_i2c.c +++ b/drivers/of/of_i2c.c @@ -12,6 +12,7 @@ */ #include +#include #include #include #include -- cgit v0.10.2 From 530719b2341fea925f58a5d6be0353fa43a88baf Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 21 Oct 2010 11:34:55 -0600 Subject: of/irq: of_irq.c needs to include linux/irq.h It works on current architectures simply because asm/prom.h includes it, but it broke when x86 turned on CONFIG_OF. Signed-off-by: Grant Likely diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h index 090cbaa..109e013 100644 --- a/include/linux/of_irq.h +++ b/include/linux/of_irq.h @@ -5,6 +5,7 @@ struct of_irq; #include #include +#include #include #include -- cgit v0.10.2 From 97ff46cb69da22037346670ae515217c658ace02 Mon Sep 17 00:00:00 2001 From: Mingkai Hu Date: Tue, 12 Oct 2010 18:18:34 +0800 Subject: mtd/m25p80: add support to parse the partitions by OF node Signed-off-by: Mingkai Hu [grant.likely@secretlab.ca: wrap hunk with #ifdef CONFIG_OF] Signed-off-by: Grant Likely diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 6f512b5..ea22520 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -924,6 +924,13 @@ static int __devinit m25p_probe(struct spi_device *spi) nr_parts = data->nr_parts; } +#ifdef CONFIG_OF + if (nr_parts <= 0 && spi->dev.of_node) { + nr_parts = of_mtd_parse_partitions(&spi->dev, + spi->dev.of_node, &parts); + } +#endif + if (nr_parts > 0) { for (i = 0; i < nr_parts; i++) { DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = " -- cgit v0.10.2