diff options
Diffstat (limited to 'drivers/of')
-rw-r--r-- | drivers/of/Kconfig | 1 | ||||
-rw-r--r-- | drivers/of/address.c | 18 | ||||
-rw-r--r-- | drivers/of/base.c | 96 | ||||
-rw-r--r-- | drivers/of/fdt.c | 138 | ||||
-rw-r--r-- | drivers/of/irq.c | 164 | ||||
-rw-r--r-- | drivers/of/of_pci.c | 1 | ||||
-rw-r--r-- | drivers/of/of_pci_irq.c | 41 | ||||
-rw-r--r-- | drivers/of/pdt.c | 1 | ||||
-rw-r--r-- | drivers/of/platform.c | 5 | ||||
-rw-r--r-- | drivers/of/selftest.c | 161 |
10 files changed, 118 insertions, 508 deletions
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index de6f899..78cc760 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -17,7 +17,6 @@ config PROC_DEVICETREE config OF_SELFTEST bool "Device Tree Runtime self tests" - depends on OF_IRQ help This option builds in test cases for the device tree infrastructure that are executed one at boot time, and the results dumped to the diff --git a/drivers/of/address.c b/drivers/of/address.c index 4b9317b..b55c218 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -489,7 +489,7 @@ static u64 __of_translate_address(struct device_node *dev, int na, ns, pna, pns; u64 result = OF_BAD_ADDR; - pr_debug("OF: ** translation for device %s **\n", of_node_full_name(dev)); + pr_debug("OF: ** translation for device %s **\n", dev->full_name); /* Increase refcount at current level */ of_node_get(dev); @@ -504,13 +504,13 @@ static u64 __of_translate_address(struct device_node *dev, bus->count_cells(dev, &na, &ns); if (!OF_CHECK_COUNTS(na, ns)) { printk(KERN_ERR "prom_parse: Bad cell count for %s\n", - of_node_full_name(dev)); + dev->full_name); goto bail; } memcpy(addr, in_addr, na * 4); pr_debug("OF: bus is %s (na=%d, ns=%d) on %s\n", - bus->name, na, ns, of_node_full_name(parent)); + bus->name, na, ns, parent->full_name); of_dump_addr("OF: translating address:", addr, na); /* Translate */ @@ -532,12 +532,12 @@ static u64 __of_translate_address(struct device_node *dev, pbus->count_cells(dev, &pna, &pns); if (!OF_CHECK_COUNTS(pna, pns)) { printk(KERN_ERR "prom_parse: Bad cell count for %s\n", - of_node_full_name(dev)); + dev->full_name); break; } pr_debug("OF: parent bus is %s (na=%d, ns=%d) on %s\n", - pbus->name, pna, pns, of_node_full_name(parent)); + pbus->name, pna, pns, parent->full_name); /* Apply bus translation */ if (of_translate_one(dev, bus, pbus, addr, na, ns, pna, rprop)) @@ -626,14 +626,6 @@ const __be32 *of_get_address(struct device_node *dev, int index, u64 *size, } EXPORT_SYMBOL(of_get_address); -unsigned long __weak pci_address_to_pio(phys_addr_t address) -{ - if (address > IO_SPACE_LIMIT) - return (unsigned long)-1; - - return (unsigned long) address; -} - static int __of_address_to_resource(struct device_node *dev, const __be32 *addrp, u64 size, unsigned int flags, const char *name, struct resource *r) diff --git a/drivers/of/base.c b/drivers/of/base.c index f807d0e..7d4c70f 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -74,13 +74,6 @@ int of_n_size_cells(struct device_node *np) } EXPORT_SYMBOL(of_n_size_cells); -#ifdef CONFIG_NUMA -int __weak of_node_to_nid(struct device_node *np) -{ - return numa_node_id(); -} -#endif - #if defined(CONFIG_OF_DYNAMIC) /** * of_node_get - Increment refcount of a node @@ -272,9 +265,9 @@ static bool __of_find_n_match_cpu_property(struct device_node *cpun, ac = of_n_addr_cells(cpun); cell = of_get_property(cpun, prop_name, &prop_len); - if (!cell || !ac) + if (!cell) return false; - prop_len /= sizeof(*cell) * ac; + prop_len /= sizeof(*cell); for (tid = 0; tid < prop_len; tid++) { hwid = of_read_number(cell, ac); if (arch_match_cpu_phys_id(cpu, hwid)) { @@ -287,31 +280,6 @@ static bool __of_find_n_match_cpu_property(struct device_node *cpun, return false; } -/* - * arch_find_n_match_cpu_physical_id - See if the given device node is - * for the cpu corresponding to logical cpu 'cpu'. Return true if so, - * else false. If 'thread' is non-NULL, the local thread number within the - * core is returned in it. - */ -bool __weak arch_find_n_match_cpu_physical_id(struct device_node *cpun, - int cpu, unsigned int *thread) -{ - /* Check for non-standard "ibm,ppc-interrupt-server#s" property - * for thread ids on PowerPC. If it doesn't exist fallback to - * standard "reg" property. - */ - if (IS_ENABLED(CONFIG_PPC) && - __of_find_n_match_cpu_property(cpun, - "ibm,ppc-interrupt-server#s", - cpu, thread)) - return true; - - if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread)) - return true; - - return false; -} - /** * of_get_cpu_node - Get device node associated with the given logical CPU * @@ -332,10 +300,24 @@ bool __weak arch_find_n_match_cpu_physical_id(struct device_node *cpun, */ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) { - struct device_node *cpun; + struct device_node *cpun, *cpus; - for_each_node_by_type(cpun, "cpu") { - if (arch_find_n_match_cpu_physical_id(cpun, cpu, thread)) + cpus = of_find_node_by_path("/cpus"); + if (!cpus) + return NULL; + + for_each_child_of_node(cpus, cpun) { + if (of_node_cmp(cpun->type, "cpu")) + continue; + /* Check for non-standard "ibm,ppc-interrupt-server#s" property + * for thread ids on PowerPC. If it doesn't exist fallback to + * standard "reg" property. + */ + if (IS_ENABLED(CONFIG_PPC) && + __of_find_n_match_cpu_property(cpun, + "ibm,ppc-interrupt-server#s", cpu, thread)) + return cpun; + if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread)) return cpun; } return NULL; @@ -1192,15 +1174,6 @@ int of_property_count_strings(struct device_node *np, const char *propname) } EXPORT_SYMBOL_GPL(of_property_count_strings); -void of_print_phandle_args(const char *msg, const struct of_phandle_args *args) -{ - int i; - printk("%s %s", msg, of_node_full_name(args->np)); - for (i = 0; i < args->args_count; i++) - printk(i ? ",%08x" : ":%08x", args->args[i]); - printk("\n"); -} - static int __of_parse_phandle_with_args(const struct device_node *np, const char *list_name, const char *cells_name, @@ -1909,34 +1882,3 @@ int of_device_is_stdout_path(struct device_node *dn) return of_stdout == dn; } EXPORT_SYMBOL_GPL(of_device_is_stdout_path); - -/** - * of_find_next_cache_node - Find a node's subsidiary cache - * @np: node of type "cpu" or "cache" - * - * Returns a node pointer with refcount incremented, use - * of_node_put() on it when done. Caller should hold a reference - * to np. - */ -struct device_node *of_find_next_cache_node(const struct device_node *np) -{ - struct device_node *child; - const phandle *handle; - - handle = of_get_property(np, "l2-cache", NULL); - if (!handle) - handle = of_get_property(np, "next-level-cache", NULL); - - if (handle) - return of_find_node_by_phandle(be32_to_cpup(handle)); - - /* OF on pmac has nodes instead of properties named "l2-cache" - * beneath CPU nodes. - */ - if (!strcmp(np->type, "cpu")) - for_each_child_of_node(np, child) - if (!strcmp(child->type, "cache")) - return child; - - return NULL; -} diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 2fa024b..a4fa9ad 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -618,72 +618,12 @@ int __init of_scan_flat_dt_by_path(const char *path, return ret; } -const char * __init of_flat_dt_get_machine_name(void) -{ - const char *name; - unsigned long dt_root = of_get_flat_dt_root(); - - name = of_get_flat_dt_prop(dt_root, "model", NULL); - if (!name) - name = of_get_flat_dt_prop(dt_root, "compatible", NULL); - return name; -} - -/** - * of_flat_dt_match_machine - Iterate match tables to find matching machine. - * - * @default_match: A machine specific ptr to return in case of no match. - * @get_next_compat: callback function to return next compatible match table. - * - * Iterate through machine match tables to find the best match for the machine - * compatible string in the FDT. - */ -const void * __init of_flat_dt_match_machine(const void *default_match, - const void * (*get_next_compat)(const char * const**)) -{ - const void *data = NULL; - const void *best_data = default_match; - const char *const *compat; - unsigned long dt_root; - unsigned int best_score = ~1, score = 0; - - dt_root = of_get_flat_dt_root(); - while ((data = get_next_compat(&compat))) { - score = of_flat_dt_match(dt_root, compat); - if (score > 0 && score < best_score) { - best_data = data; - best_score = score; - } - } - if (!best_data) { - const char *prop; - long size; - - pr_err("\n unrecognized device tree list:\n[ "); - - prop = of_get_flat_dt_prop(dt_root, "compatible", &size); - if (prop) { - while (size > 0) { - printk("'%s' ", prop); - size -= strlen(prop) + 1; - prop += strlen(prop) + 1; - } - } - printk("]\n\n"); - return NULL; - } - - pr_info("Machine model: %s\n", of_flat_dt_get_machine_name()); - - return best_data; -} - #ifdef CONFIG_BLK_DEV_INITRD /** * early_init_dt_check_for_initrd - Decode initrd location from flat tree * @node: reference to node containing initrd location ('chosen') */ -static void __init early_init_dt_check_for_initrd(unsigned long node) +void __init early_init_dt_check_for_initrd(unsigned long node) { u64 start, end; unsigned long len; @@ -701,15 +641,12 @@ static void __init early_init_dt_check_for_initrd(unsigned long node) return; end = of_read_number(prop, len/4); - initrd_start = (unsigned long)__va(start); - initrd_end = (unsigned long)__va(end); - initrd_below_start_ok = 1; - + early_init_dt_setup_initrd_arch(start, end); pr_debug("initrd_start=0x%llx initrd_end=0x%llx\n", (unsigned long long)start, (unsigned long long)end); } #else -static inline void early_init_dt_check_for_initrd(unsigned long node) +inline void early_init_dt_check_for_initrd(unsigned long node) { } #endif /* CONFIG_BLK_DEV_INITRD */ @@ -837,25 +774,6 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, } #ifdef CONFIG_HAVE_MEMBLOCK -void __init __weak early_init_dt_add_memory_arch(u64 base, u64 size) -{ - const u64 phys_offset = __pa(PAGE_OFFSET); - base &= PAGE_MASK; - size &= PAGE_MASK; - if (base + size < phys_offset) { - pr_warning("Ignoring memory block 0x%llx - 0x%llx\n", - base, base + size); - return; - } - if (base < phys_offset) { - pr_warning("Ignoring memory range 0x%llx - 0x%llx\n", - base, phys_offset); - size -= phys_offset - base; - base = phys_offset; - } - memblock_add(base, size); -} - /* * called from unflatten_device_tree() to bootstrap devicetree itself * Architectures can override this definition if memblock isn't used @@ -866,32 +784,6 @@ void * __init __weak early_init_dt_alloc_memory_arch(u64 size, u64 align) } #endif -bool __init early_init_dt_scan(void *params) -{ - if (!params) - return false; - - /* Setup flat device-tree pointer */ - initial_boot_params = params; - - /* check device tree validity */ - if (be32_to_cpu(initial_boot_params->magic) != OF_DT_HEADER) { - initial_boot_params = NULL; - return false; - } - - /* Retrieve various information from the /chosen node */ - of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line); - - /* Initialize {size,address}-cells info */ - of_scan_flat_dt(early_init_dt_scan_root, NULL); - - /* Setup memory, calling early_init_dt_add_memory_arch */ - of_scan_flat_dt(early_init_dt_scan_memory, NULL); - - return true; -} - /** * unflatten_device_tree - create tree of device_nodes from flat blob * @@ -909,28 +801,4 @@ void __init unflatten_device_tree(void) of_alias_scan(early_init_dt_alloc_memory_arch); } -/** - * unflatten_and_copy_device_tree - copy and create tree of device_nodes from flat blob - * - * Copies and unflattens the device-tree passed by the firmware, creating the - * tree of struct device_node. It also fills the "name" and "type" - * pointers of the nodes so the normal device-tree walking functions - * can be used. This should only be used when the FDT memory has not been - * reserved such is the case when the FDT is built-in to the kernel init - * section. If the FDT memory is reserved already then unflatten_device_tree - * should be used instead. - */ -void __init unflatten_and_copy_device_tree(void) -{ - int size = __be32_to_cpu(initial_boot_params->totalsize); - void *dt = early_init_dt_alloc_memory_arch(size, - __alignof__(struct boot_param_header)); - - if (dt) { - memcpy(dt, initial_boot_params, size); - initial_boot_params = dt; - } - unflatten_device_tree(); -} - #endif /* CONFIG_OF_EARLY_FLATTREE */ diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 786b0b4..1752988 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -31,17 +31,18 @@ * @dev: Device node of the device whose interrupt is to be mapped * @index: Index of the interrupt to map * - * This function is a wrapper that chains of_irq_parse_one() and + * This function is a wrapper that chains of_irq_map_one() and * irq_create_of_mapping() to make things easier to callers */ unsigned int irq_of_parse_and_map(struct device_node *dev, int index) { - struct of_phandle_args oirq; + struct of_irq oirq; - if (of_irq_parse_one(dev, index, &oirq)) + if (of_irq_map_one(dev, index, &oirq)) return 0; - return irq_create_of_mapping(&oirq); + return irq_create_of_mapping(oirq.controller, oirq.specifier, + oirq.size); } EXPORT_SYMBOL_GPL(irq_of_parse_and_map); @@ -78,34 +79,33 @@ struct device_node *of_irq_find_parent(struct device_node *child) } /** - * of_irq_parse_raw - Low level interrupt tree parsing + * of_irq_map_raw - Low level interrupt tree parsing * @parent: the device interrupt parent - * @addr: address specifier (start of "reg" property of the device) in be32 format - * @out_irq: structure of_irq updated by this function + * @intspec: interrupt specifier ("interrupts" property of the device) + * @ointsize: size of the passed in interrupt specifier + * @addr: address specifier (start of "reg" property of the device) + * @out_irq: structure of_irq filled by this function * * Returns 0 on success and a negative number on error * * This function is a low-level interrupt tree walking function. It * can be used to do a partial walk with synthetized reg and interrupts * properties, for example when resolving PCI interrupts when no device - * node exist for the parent. It takes an interrupt specifier structure as - * input, walks the tree looking for any interrupt-map properties, translates - * the specifier for each map, and then returns the translated map. + * node exist for the parent. */ -int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) +int of_irq_map_raw(struct device_node *parent, const __be32 *intspec, + u32 ointsize, const __be32 *addr, struct of_irq *out_irq) { struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL; - __be32 initial_match_array[MAX_PHANDLE_ARGS]; - const __be32 *match_array = initial_match_array; - const __be32 *tmp, *imap, *imask, dummy_imask[] = { [0 ... MAX_PHANDLE_ARGS] = ~0 }; + const __be32 *tmp, *imap, *imask; u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0; int imaplen, match, i; -#ifdef DEBUG - of_print_phandle_args("of_irq_parse_raw: ", out_irq); -#endif + pr_debug("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n", + parent->full_name, be32_to_cpup(intspec), + be32_to_cpup(intspec + 1), ointsize); - ipar = of_node_get(out_irq->np); + ipar = of_node_get(parent); /* First get the #interrupt-cells property of the current cursor * that tells us how to interpret the passed-in intspec. If there @@ -126,9 +126,9 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) goto fail; } - pr_debug("of_irq_parse_raw: ipar=%s, size=%d\n", of_node_full_name(ipar), intsize); + pr_debug("of_irq_map_raw: ipar=%s, size=%d\n", ipar->full_name, intsize); - if (out_irq->args_count != intsize) + if (ointsize != intsize) return -EINVAL; /* Look for this #address-cells. We have to implement the old linux @@ -147,16 +147,6 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) pr_debug(" -> addrsize=%d\n", addrsize); - /* Range check so that the temporary buffer doesn't overflow */ - if (WARN_ON(addrsize + intsize > MAX_PHANDLE_ARGS)) - goto fail; - - /* Precalculate the match array - this simplifies match loop */ - for (i = 0; i < addrsize; i++) - initial_match_array[i] = addr ? addr[i] : 0; - for (i = 0; i < intsize; i++) - initial_match_array[addrsize + i] = cpu_to_be32(out_irq->args[i]); - /* Now start the actual "proper" walk of the interrupt tree */ while (ipar != NULL) { /* Now check if cursor is an interrupt-controller and if it is @@ -165,19 +155,15 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) if (of_get_property(ipar, "interrupt-controller", NULL) != NULL) { pr_debug(" -> got it !\n"); + for (i = 0; i < intsize; i++) + out_irq->specifier[i] = + of_read_number(intspec +i, 1); + out_irq->size = intsize; + out_irq->controller = ipar; of_node_put(old); return 0; } - /* - * interrupt-map parsing does not work without a reg - * property when #address-cells != 0 - */ - if (addrsize && !addr) { - pr_debug(" -> no reg passed in when needed !\n"); - goto fail; - } - /* Now look for an interrupt-map */ imap = of_get_property(ipar, "interrupt-map", &imaplen); /* No interrupt map, check for an interrupt parent */ @@ -190,16 +176,34 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) /* Look for a mask */ imask = of_get_property(ipar, "interrupt-map-mask", NULL); - if (!imask) - imask = dummy_imask; + + /* If we were passed no "reg" property and we attempt to parse + * an interrupt-map, then #address-cells must be 0. + * Fail if it's not. + */ + if (addr == NULL && addrsize != 0) { + pr_debug(" -> no reg passed in when needed !\n"); + goto fail; + } /* Parse interrupt-map */ match = 0; while (imaplen > (addrsize + intsize + 1) && !match) { /* Compare specifiers */ match = 1; - for (i = 0; i < (addrsize + intsize); i++, imaplen--) - match &= !((match_array[i] ^ *imap++) & imask[i]); + for (i = 0; i < addrsize && match; ++i) { + __be32 mask = imask ? imask[i] + : cpu_to_be32(0xffffffffu); + match = ((addr[i] ^ imap[i]) & mask) == 0; + } + for (; i < (addrsize + intsize) && match; ++i) { + __be32 mask = imask ? imask[i] + : cpu_to_be32(0xffffffffu); + match = + ((intspec[i-addrsize] ^ imap[i]) & mask) == 0; + } + imap += addrsize + intsize; + imaplen -= addrsize + intsize; pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen); @@ -233,8 +237,6 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) newintsize, newaddrsize); /* Check for malformed properties */ - if (WARN_ON(newaddrsize + newintsize > MAX_PHANDLE_ARGS)) - goto fail; if (imaplen < (newaddrsize + newintsize)) goto fail; @@ -246,18 +248,12 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) if (!match) goto fail; - /* - * Successfully parsed an interrrupt-map translation; copy new - * interrupt specifier into the out_irq structure - */ - of_node_put(out_irq->np); - out_irq->np = of_node_get(newpar); - - match_array = imap - newaddrsize - newintsize; - for (i = 0; i < newintsize; i++) - out_irq->args[i] = be32_to_cpup(imap - newintsize + i); - out_irq->args_count = intsize = newintsize; + of_node_put(old); + old = of_node_get(newpar); addrsize = newaddrsize; + intsize = newintsize; + intspec = imap - intsize; + addr = intspec - addrsize; skiplevel: /* Iterate again with new parent */ @@ -268,53 +264,46 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) } fail: of_node_put(ipar); - of_node_put(out_irq->np); + of_node_put(old); of_node_put(newpar); return -EINVAL; } -EXPORT_SYMBOL_GPL(of_irq_parse_raw); +EXPORT_SYMBOL_GPL(of_irq_map_raw); /** - * of_irq_parse_one - Resolve an interrupt for a device + * of_irq_map_one - Resolve an interrupt for a device * @device: the device whose interrupt is to be resolved * @index: index of the interrupt to resolve * @out_irq: structure of_irq filled by this function * - * This function resolves an interrupt for a node by walking the interrupt tree, - * finding which interrupt controller node it is attached to, and returning the - * interrupt specifier that can be used to retrieve a Linux IRQ number. + * This function resolves an interrupt, walking the tree, for a given + * device-tree node. It's the high level pendant to of_irq_map_raw(). */ -int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_args *out_irq) +int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq) { struct device_node *p; const __be32 *intspec, *tmp, *addr; u32 intsize, intlen; - int i, res = -EINVAL; + int res = -EINVAL; - pr_debug("of_irq_parse_one: dev=%s, index=%d\n", of_node_full_name(device), index); + pr_debug("of_irq_map_one: dev=%s, index=%d\n", device->full_name, index); /* OldWorld mac stuff is "special", handle out of line */ if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC) - return of_irq_parse_oldworld(device, index, out_irq); - - /* Get the reg property (if any) */ - addr = of_get_property(device, "reg", NULL); + return of_irq_map_oldworld(device, index, out_irq); /* Get the interrupts property */ intspec = of_get_property(device, "interrupts", &intlen); - if (intspec == NULL) { - /* Try the new-style interrupts-extended */ - res = of_parse_phandle_with_args(device, "interrupts-extended", - "#interrupt-cells", index, out_irq); - if (res) - return -EINVAL; - return of_irq_parse_raw(addr, out_irq); - } + if (intspec == NULL) + return -EINVAL; intlen /= sizeof(*intspec); pr_debug(" intspec=%d intlen=%d\n", be32_to_cpup(intspec), intlen); + /* Get the reg property (if any) */ + addr = of_get_property(device, "reg", NULL); + /* Look for the interrupt parent. */ p = of_irq_find_parent(device); if (p == NULL) @@ -332,20 +321,14 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar if ((index + 1) * intsize > intlen) goto out; - /* Copy intspec into irq structure */ - intspec += index * intsize; - out_irq->np = p; - out_irq->args_count = intsize; - for (i = 0; i < intsize; i++) - out_irq->args[i] = be32_to_cpup(intspec++); - - /* Check if there are any interrupt-map translations to process */ - res = of_irq_parse_raw(addr, out_irq); + /* Get new specifier and map it */ + res = of_irq_map_raw(p, intspec + index * intsize, intsize, + addr, out_irq); out: of_node_put(p); return res; } -EXPORT_SYMBOL_GPL(of_irq_parse_one); +EXPORT_SYMBOL_GPL(of_irq_map_one); /** * of_irq_to_resource - Decode a node's IRQ and return it as a resource @@ -371,8 +354,8 @@ int of_irq_to_resource(struct device_node *dev, int index, struct resource *r) &name); r->start = r->end = irq; - r->flags = IORESOURCE_IRQ | irqd_get_trigger_type(irq_get_irq_data(irq)); - r->name = name ? name : of_node_full_name(dev); + r->flags = IORESOURCE_IRQ; + r->name = name ? name : dev->full_name; } return irq; @@ -385,10 +368,9 @@ EXPORT_SYMBOL_GPL(of_irq_to_resource); */ int of_irq_count(struct device_node *dev) { - struct of_phandle_args irq; int nr = 0; - while (of_irq_parse_one(dev, nr, &irq) == 0) + while (of_irq_to_resource(dev, nr, NULL)) nr++; return nr; diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c index 8481996..e5ca008 100644 --- a/drivers/of/of_pci.c +++ b/drivers/of/of_pci.c @@ -2,6 +2,7 @@ #include <linux/export.h> #include <linux/of.h> #include <linux/of_pci.h> +#include <asm/prom.h> static inline int __of_pci_pci_compare(struct device_node *node, unsigned int data) diff --git a/drivers/of/of_pci_irq.c b/drivers/of/of_pci_irq.c index 8736bc7..6770538 100644 --- a/drivers/of/of_pci_irq.c +++ b/drivers/of/of_pci_irq.c @@ -2,9 +2,10 @@ #include <linux/of_pci.h> #include <linux/of_irq.h> #include <linux/export.h> +#include <asm/prom.h> /** - * of_irq_parse_pci - Resolve the interrupt for a PCI device + * of_irq_map_pci - Resolve the interrupt for a PCI device * @pdev: the device whose interrupt is to be resolved * @out_irq: structure of_irq filled by this function * @@ -14,7 +15,7 @@ * PCI tree until an device-node is found, at which point it will finish * resolving using the OF tree walking. */ -int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq) +int of_irq_map_pci(const struct pci_dev *pdev, struct of_irq *out_irq) { struct device_node *dn, *ppnode; struct pci_dev *ppdev; @@ -29,7 +30,7 @@ int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq */ dn = pci_device_to_OF_node(pdev); if (dn) { - rc = of_irq_parse_one(dn, 0, out_irq); + rc = of_irq_map_one(dn, 0, out_irq); if (!rc) return rc; } @@ -84,37 +85,9 @@ int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq pdev = ppdev; } - out_irq->np = ppnode; - out_irq->args_count = 1; - out_irq->args[0] = lspec; lspec_be = cpu_to_be32(lspec); laddr[0] = cpu_to_be32((pdev->bus->number << 16) | (pdev->devfn << 8)); - laddr[1] = laddr[2] = cpu_to_be32(0); - return of_irq_parse_raw(laddr, out_irq); + laddr[1] = laddr[2] = cpu_to_be32(0); + return of_irq_map_raw(ppnode, &lspec_be, 1, laddr, out_irq); } -EXPORT_SYMBOL_GPL(of_irq_parse_pci); - -/** - * of_irq_parse_and_map_pci() - Decode a PCI irq from the device tree and map to a virq - * @dev: The pci device needing an irq - * @slot: PCI slot number; passed when used as map_irq callback. Unused - * @pin: PCI irq pin number; passed when used as map_irq callback. Unused - * - * @slot and @pin are unused, but included in the function so that this - * function can be used directly as the map_irq callback to pci_fixup_irqs(). - */ -int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin) -{ - struct of_phandle_args oirq; - int ret; - - ret = of_irq_parse_pci(dev, &oirq); - if (ret) { - dev_err(&dev->dev, "of_irq_parse_pci() failed with rc=%d\n", ret); - return 0; /* Proper return code 0 == NO_IRQ */ - } - - return irq_create_of_mapping(&oirq); -} -EXPORT_SYMBOL_GPL(of_irq_parse_and_map_pci); - +EXPORT_SYMBOL_GPL(of_irq_map_pci); diff --git a/drivers/of/pdt.c b/drivers/of/pdt.c index 7b66673..4ec19cb 100644 --- a/drivers/of/pdt.c +++ b/drivers/of/pdt.c @@ -22,6 +22,7 @@ #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; diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 404d1da..f6dcde2 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -215,8 +215,6 @@ static struct platform_device *of_platform_device_create_pdata( dev->archdata.dma_mask = 0xffffffffUL; #endif dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); - if (!dev->dev.dma_mask) - dev->dev.dma_mask = &dev->dev.coherent_dma_mask; dev->dev.bus = &platform_bus_type; dev->dev.platform_data = platform_data; @@ -282,6 +280,9 @@ static struct amba_device *of_amba_device_create(struct device_node *node, else of_device_make_bus_id(&dev->dev); + /* setup amba-specific device info */ + dev->dma_mask = ~0; + /* Allow the HW Peripheral ID to be overridden */ prop = of_get_property(node, "arm,primecell-periphid", NULL); if (prop) diff --git a/drivers/of/selftest.c b/drivers/of/selftest.c index e21012b..0eb5c38 100644 --- a/drivers/of/selftest.c +++ b/drivers/of/selftest.c @@ -9,24 +9,18 @@ #include <linux/errno.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_irq.h> #include <linux/list.h> #include <linux/mutex.h> #include <linux/slab.h> #include <linux/device.h> -static struct selftest_results { - int passed; - int failed; -} selftest_results; - +static bool selftest_passed = true; #define selftest(result, fmt, ...) { \ if (!(result)) { \ - selftest_results.failed++; \ - pr_err("FAIL %s():%i " fmt, __func__, __LINE__, ##__VA_ARGS__); \ + pr_err("FAIL %s:%i " fmt, __FILE__, __LINE__, ##__VA_ARGS__); \ + selftest_passed = false; \ } else { \ - selftest_results.passed++; \ - pr_debug("pass %s():%i\n", __func__, __LINE__); \ + pr_info("pass %s:%i\n", __FILE__, __LINE__); \ } \ } @@ -137,6 +131,7 @@ static void __init of_selftest_property_match_string(void) struct device_node *np; int rc; + pr_info("start\n"); np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a"); if (!np) { pr_err("No testcase data in device tree\n"); @@ -159,147 +154,6 @@ static void __init of_selftest_property_match_string(void) selftest(rc == -EILSEQ, "unterminated string; rc=%i", rc); } -static void __init of_selftest_parse_interrupts(void) -{ - struct device_node *np; - struct of_phandle_args args; - int i, rc; - - np = of_find_node_by_path("/testcase-data/interrupts/interrupts0"); - if (!np) { - pr_err("missing testcase data\n"); - return; - } - - for (i = 0; i < 4; i++) { - bool passed = true; - args.args_count = 0; - rc = of_irq_parse_one(np, i, &args); - - passed &= !rc; - passed &= (args.args_count == 1); - passed &= (args.args[0] == (i + 1)); - - selftest(passed, "index %i - data error on node %s rc=%i\n", - i, args.np->full_name, rc); - } - of_node_put(np); - - np = of_find_node_by_path("/testcase-data/interrupts/interrupts1"); - if (!np) { - pr_err("missing testcase data\n"); - return; - } - - for (i = 0; i < 4; i++) { - bool passed = true; - args.args_count = 0; - rc = of_irq_parse_one(np, i, &args); - - /* Test the values from tests-phandle.dtsi */ - switch (i) { - case 0: - passed &= !rc; - passed &= (args.args_count == 1); - passed &= (args.args[0] == 9); - break; - case 1: - passed &= !rc; - passed &= (args.args_count == 3); - passed &= (args.args[0] == 10); - passed &= (args.args[1] == 11); - passed &= (args.args[2] == 12); - break; - case 2: - passed &= !rc; - passed &= (args.args_count == 2); - passed &= (args.args[0] == 13); - passed &= (args.args[1] == 14); - break; - case 3: - passed &= !rc; - passed &= (args.args_count == 2); - passed &= (args.args[0] == 15); - passed &= (args.args[1] == 16); - break; - default: - passed = false; - } - selftest(passed, "index %i - data error on node %s rc=%i\n", - i, args.np->full_name, rc); - } - of_node_put(np); -} - -static void __init of_selftest_parse_interrupts_extended(void) -{ - struct device_node *np; - struct of_phandle_args args; - int i, rc; - - np = of_find_node_by_path("/testcase-data/interrupts/interrupts-extended0"); - if (!np) { - pr_err("missing testcase data\n"); - return; - } - - for (i = 0; i < 7; i++) { - bool passed = true; - rc = of_irq_parse_one(np, i, &args); - - /* Test the values from tests-phandle.dtsi */ - switch (i) { - case 0: - passed &= !rc; - passed &= (args.args_count == 1); - passed &= (args.args[0] == 1); - break; - case 1: - passed &= !rc; - passed &= (args.args_count == 3); - passed &= (args.args[0] == 2); - passed &= (args.args[1] == 3); - passed &= (args.args[2] == 4); - break; - case 2: - passed &= !rc; - passed &= (args.args_count == 2); - passed &= (args.args[0] == 5); - passed &= (args.args[1] == 6); - break; - case 3: - passed &= !rc; - passed &= (args.args_count == 1); - passed &= (args.args[0] == 9); - break; - case 4: - passed &= !rc; - passed &= (args.args_count == 3); - passed &= (args.args[0] == 10); - passed &= (args.args[1] == 11); - passed &= (args.args[2] == 12); - break; - case 5: - passed &= !rc; - passed &= (args.args_count == 2); - passed &= (args.args[0] == 13); - passed &= (args.args[1] == 14); - break; - case 6: - passed &= !rc; - passed &= (args.args_count == 1); - passed &= (args.args[0] == 15); - break; - default: - passed = false; - } - - selftest(passed, "index %i - data error on node %s rc=%i\n", - i, args.np->full_name, rc); - } - of_node_put(np); -} - static int __init of_selftest(void) { struct device_node *np; @@ -314,10 +168,7 @@ static int __init of_selftest(void) pr_info("start of selftest - you will see error messages\n"); of_selftest_parse_phandle_with_args(); of_selftest_property_match_string(); - of_selftest_parse_interrupts(); - of_selftest_parse_interrupts_extended(); - pr_info("end of selftest - %i passed, %i failed\n", - selftest_results.passed, selftest_results.failed); + pr_info("end of selftest - %s\n", selftest_passed ? "PASS" : "FAIL"); return 0; } late_initcall(of_selftest); |