diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/base/platform.c | 1 | ||||
-rw-r--r-- | drivers/block/xsysace.c | 3 | ||||
-rw-r--r-- | drivers/gpio/xilinx_gpio.c | 6 | ||||
-rw-r--r-- | drivers/mtd/devices/m25p80.c | 7 | ||||
-rw-r--r-- | drivers/mtd/maps/physmap_of.c | 2 | ||||
-rw-r--r-- | drivers/mtd/ofpart.c | 4 | ||||
-rw-r--r-- | drivers/of/Kconfig | 5 | ||||
-rw-r--r-- | drivers/of/Makefile | 1 | ||||
-rw-r--r-- | drivers/of/address.c | 2 | ||||
-rw-r--r-- | drivers/of/base.c | 4 | ||||
-rw-r--r-- | drivers/of/device.c | 27 | ||||
-rw-r--r-- | drivers/of/fdt.c | 2 | ||||
-rw-r--r-- | drivers/of/irq.c | 39 | ||||
-rw-r--r-- | drivers/of/of_i2c.c | 1 | ||||
-rw-r--r-- | drivers/of/pdt.c | 276 | ||||
-rw-r--r-- | drivers/of/platform.c | 34 | ||||
-rw-r--r-- | drivers/sbus/char/jsflash.c | 2 | ||||
-rw-r--r-- | drivers/serial/of_serial.c | 12 | ||||
-rw-r--r-- | drivers/video/aty/atyfb_base.c | 3 |
19 files changed, 372 insertions, 59 deletions
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 3966e62..f051cff 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/block/xsysace.c b/drivers/block/xsysace.c index 6e968cd..829161e 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c @@ -1225,7 +1225,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) 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); 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] = " 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) 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/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) 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/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/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 <linux/of_irq.h> #include <linux/string.h> +/* 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/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 <linux/i2c.h> +#include <linux/irq.h> #include <linux/of.h> #include <linux/of_i2c.h> #include <linux/of_irq.h> diff --git a/drivers/of/pdt.c b/drivers/of/pdt.c new file mode 100644 index 0000000..28295d0 --- /dev/null +++ b/drivers/of/pdt.c @@ -0,0 +1,276 @@ +/* pdt.c: OF PROM device tree support 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 + * Adapted for multiple architectures by Andres Salomon <dilinger@queued.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 <linux/kernel.h> +#include <linux/module.h> +#include <linux/errno.h> +#include <linux/mutex.h> +#include <linux/slab.h> +#include <linux/of.h> +#include <linux/of_pdt.h> +#include <asm/prom.h> + +static struct of_pdt_ops *of_pdt_prom_ops __initdata; + +void __initdata (*of_pdt_build_more)(struct device_node *dp, + struct device_node ***nextp); + +#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 of_pdt_build_one_prop(phandle node, char *prev, + char *special_name, + void *special_val, + int special_len) +{ + static struct property *tmp = NULL; + struct property *p; + int err; + + if (tmp) { + p = tmp; + memset(p, 0, sizeof(*p) + 32); + tmp = NULL; + } else { + p = prom_early_alloc(sizeof(struct property) + 32); + of_pdt_incr_unique_id(p); + } + + 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 { + err = of_pdt_prom_ops->nextprop(node, prev, p->name); + if (err) { + tmp = p; + return NULL; + } + 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 = 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'; + } + } + return p; +} + +static struct property * __init of_pdt_build_prop_list(phandle node) +{ + struct property *head, *tail; + + head = tail = of_pdt_build_one_prop(node, NULL, + ".node", &node, sizeof(node)); + + tail->next = of_pdt_build_one_prop(node, NULL, NULL, NULL, 0); + tail = tail->next; + while(tail) { + tail->next = of_pdt_build_one_prop(node, tail->name, + NULL, NULL, 0); + tail = tail->next; + } + + return head; +} + +static char * __init of_pdt_get_one_property(phandle node, const char *name) +{ + char *buf = "<NULL>"; + int len; + + len = of_pdt_prom_ops->getproplen(node, name); + if (len > 0) { + buf = prom_early_alloc(len); + len = of_pdt_prom_ops->getproperty(node, name, buf, len); + } + + 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) +{ + struct device_node *dp; + + if (!node) + return NULL; + + dp = prom_early_alloc(sizeof(*dp)); + of_pdt_incr_unique_id(dp); + dp->parent = parent; + + kref_init(&dp->kref); + + dp->name = of_pdt_build_name(node); + dp->type = of_pdt_get_one_property(node, "device_type"); + dp->phandle = node; + + dp->properties = of_pdt_build_prop_list(node); + + irq_trans_init(dp); + + return dp; +} + +static char * __init of_pdt_build_full_name(struct device_node *dp) +{ + int len, ourlen, plen; + char *n; + + plen = strlen(dp->parent->full_name); + ourlen = strlen(of_pdt_node_name(dp)); + 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, of_pdt_node_name(dp)); + + return n; +} + +static struct device_node * __init of_pdt_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 = of_pdt_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; + +#if defined(CONFIG_SPARC) + dp->path_component_name = build_path_component(dp); +#endif + dp->full_name = of_pdt_build_full_name(dp); + + dp->child = of_pdt_build_tree(dp, + of_pdt_prom_ops->getchild(node), nextp); + + if (of_pdt_build_more) + of_pdt_build_more(dp, nextp); + + node = of_pdt_prom_ops->getsibling(node); + } + + return ret; +} + +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 = of_pdt_create_node(root_node, NULL); +#if defined(CONFIG_SPARC) + allnodes->path_component_name = ""; +#endif + allnodes->full_name = "/"; + + nextp = &allnodes->allnext; + allnodes->child = of_pdt_build_tree(allnodes, + of_pdt_prom_ops->getchild(allnodes->phandle), &nextp); +} diff --git a/drivers/of/platform.c b/drivers/of/platform.c index bb72223..5b4a07f 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -584,34 +584,33 @@ 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++; - - /* Allocate memory for both the struct device and the resource table */ - dev = kzalloc(sizeof(*dev) + (sizeof(*res) * (num_reg + num_irq)), - GFP_KERNEL); + dev = platform_device_alloc("", -1); if (!dev) return NULL; - res = (struct resource *) &dev[1]; + + /* 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); /* 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++) { 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); @@ -619,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); @@ -657,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/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c index 13f48e2..a624f5a 100644 --- a/drivers/sbus/char/jsflash.c +++ b/drivers/sbus/char/jsflash.c @@ -461,7 +461,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/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; } 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; /* |