From a8bf7527a2e17ccf1366e67f6ac728327ca34c40 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 26 Aug 2013 11:22:45 -0500 Subject: of: create unflatten_and_copy_device_tree Several architectures using DT support built-in dtb's in the init section. These platforms need to copy the dtb from init since the strings are referenced after unflattening. Every arch has their own copying routine which do the same thing. Create a common function, unflatten_and_copy_device_tree, to copy the dtb when unflattening the dtb. Signed-off-by: Rob Herring Acked-by: Grant Likely --- drivers/of/fdt.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'drivers') diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 229dd9d..5177616 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -802,6 +802,30 @@ 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 */ /* Feed entire flattened device tree into the random pool */ -- cgit v1.1 From 0288ffcbfdf9b8656e7320c24caa1e4c1d498287 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 26 Aug 2013 09:47:40 -0500 Subject: of: Introduce common early_init_dt_scan Most architectures scan the all the same items early in the FDT and none are really architecture specific. Create a common early_init_dt_scan to unify the early scan of root, memory, and chosen nodes in the flattened DT. Signed-off-by: Rob Herring Acked-by: Grant Likely --- drivers/of/fdt.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'drivers') diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 5177616..bfbfda5 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -785,6 +785,32 @@ 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 * -- cgit v1.1 From 068f6310b965d67d57f89ebf4c539e5933754366 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 24 Sep 2013 22:20:01 -0500 Subject: of: create default early_init_dt_add_memory_arch Create a weak version of early_init_dt_add_memory_arch which uses memblock. This will unify all architectures except ones with custom memory bank structs. Signed-off-by: Rob Herring Acked-by: Catalin Marinas Cc: Will Deacon Cc: Michal Simek Cc: Jonas Bonn Acked-by: Grant Likely Cc: linux-arm-kernel@lists.infradead.org Cc: microblaze-uclinux@itee.uq.edu.au Cc: linux@lists.openrisc.net Cc: devicetree@vger.kernel.org --- drivers/of/fdt.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'drivers') diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index bfbfda5..5bc55b6 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -775,6 +775,25 @@ 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 -- cgit v1.1 From 29eb45a9ab4839a1e9cef2bcf369b918c9c4fcad Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 30 Aug 2013 17:06:53 -0500 Subject: of: remove early_init_dt_setup_initrd_arch All arches do essentially the same thing now for early_init_dt_setup_initrd_arch, so it can now be removed. Signed-off-by: Rob Herring Acked-by: Vineet Gupta Cc: Russell King Cc: Mark Salter Cc: Aurelien Jacquiot Cc: James Hogan Cc: Michal Simek Cc: Ralf Baechle Cc: Jonas Bonn Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Thomas Gleixner Cc: Ingo Molnar Cc: "H. Peter Anvin" Cc: x86@kernel.org Cc: Chris Zankel Cc: Max Filippov Acked-by: Grant Likely --- drivers/of/fdt.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 5bc55b6..5f4cc88 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -624,7 +624,7 @@ int __init of_scan_flat_dt_by_path(const char *path, * early_init_dt_check_for_initrd - Decode initrd location from flat tree * @node: reference to node containing initrd location ('chosen') */ -void __init early_init_dt_check_for_initrd(unsigned long node) +static void __init early_init_dt_check_for_initrd(unsigned long node) { u64 start, end; unsigned long len; @@ -642,12 +642,15 @@ void __init early_init_dt_check_for_initrd(unsigned long node) return; end = of_read_number(prop, len/4); - early_init_dt_setup_initrd_arch(start, end); + initrd_start = (unsigned long)__va(start); + initrd_end = (unsigned long)__va(end); + initrd_below_start_ok = 1; + pr_debug("initrd_start=0x%llx initrd_end=0x%llx\n", (unsigned long long)start, (unsigned long long)end); } #else -inline void early_init_dt_check_for_initrd(unsigned long node) +static inline void early_init_dt_check_for_initrd(unsigned long node) { } #endif /* CONFIG_BLK_DEV_INITRD */ -- cgit v1.1 From 6a903a2551ef778d60ce4341722d611144251398 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 27 Aug 2013 21:41:56 -0500 Subject: of: introduce common FDT machine related functions Introduce common of_flat_dt_match_machine and of_flat_dt_get_machine_name functions to unify architectures' handling of machine level model and compatible properties. Several architectures match the root compatible string with an arch specific list of machine descriptors duplicating the same search algorithm. Create a common implementation with a simple architecture specific hook to iterate over each machine's match table. Signed-off-by: Rob Herring Acked-by: Grant Likely --- drivers/of/fdt.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'drivers') diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 5f4cc88..5c47910 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -619,6 +619,66 @@ 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 -- cgit v1.1 From fc84b0c3dc5dd42c6d040dcd11571c10b690d318 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Sat, 7 Sep 2013 16:35:13 -0500 Subject: drivers: remove unnecessary prom.h includes Remove unnecessary prom.h includes in preparation to remove implicit includes of prom.h. Signed-off-by: Rob Herring Acked-by: Marc Kleine-Budde Acked-by: Grant Likely Cc: Wolfgang Grandegger Cc: linux-can@vger.kernel.org Cc: netdev@vger.kernel.org --- drivers/net/can/grcan.c | 3 --- drivers/net/can/sja1000/sja1000_of_platform.c | 1 - 2 files changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c index 6aa737a..ab506d6 100644 --- a/drivers/net/can/grcan.c +++ b/drivers/net/can/grcan.c @@ -34,10 +34,7 @@ #include #include #include - #include -#include - #include #include diff --git a/drivers/net/can/sja1000/sja1000_of_platform.c b/drivers/net/can/sja1000/sja1000_of_platform.c index 31ad339..047accd 100644 --- a/drivers/net/can/sja1000/sja1000_of_platform.c +++ b/drivers/net/can/sja1000/sja1000_of_platform.c @@ -44,7 +44,6 @@ #include #include #include -#include #include "sja1000.h" -- cgit v1.1 From 9cae09c5a9940b9e02474be0639f0b49bd592a33 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 9 Sep 2013 18:13:46 -0500 Subject: of: remove unnecessary prom.h includes Remove unnecessary prom.h includes in preparation to make prom.h optional. Signed-off-by: Rob Herring Acked-by: Grant Likely --- drivers/of/of_pci_irq.c | 1 - drivers/of/pdt.c | 1 - 2 files changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/of/of_pci_irq.c b/drivers/of/of_pci_irq.c index 6770538..d8607643 100644 --- a/drivers/of/of_pci_irq.c +++ b/drivers/of/of_pci_irq.c @@ -2,7 +2,6 @@ #include #include #include -#include /** * of_irq_map_pci - Resolve the interrupt for a PCI device diff --git a/drivers/of/pdt.c b/drivers/of/pdt.c index 4ec19cb..7b66673 100644 --- a/drivers/of/pdt.c +++ b/drivers/of/pdt.c @@ -22,7 +22,6 @@ #include #include #include -#include static struct of_pdt_ops *of_pdt_prom_ops __initdata; -- cgit v1.1 From 5c9f303e996516dd0dcc2ce8c2b95504d3137b19 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Sat, 7 Sep 2013 14:05:10 -0500 Subject: microblaze: clean-up prom.h implicit includes While powerpc is a mess of implicit includes by prom.h, microblaze just copied this and is easily fixed. Add the necessary explicit includes and remove unnecessary includes and other parts from prom.h Signed-off-by: Rob Herring Acked-by: Grant Likely Cc: Michal Simek Cc: microblaze-uclinux@itee.uq.edu.au Cc: netdev@vger.kernel.org --- drivers/net/ethernet/xilinx/ll_temac_main.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c index b88121f..22478d5 100644 --- a/drivers/net/ethernet/xilinx/ll_temac_main.c +++ b/drivers/net/ethernet/xilinx/ll_temac_main.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include -- cgit v1.1 From 5af5073004071cedd0343eee51d77955037ec6f3 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 17 Sep 2013 14:28:33 -0500 Subject: drivers: clean-up prom.h implicit includes Powerpc is a mess of implicit includes by prom.h. Add the necessary explicit includes to drivers in preparation of prom.h cleanup. Signed-off-by: Rob Herring Acked-by: Grant Likely --- drivers/ata/sata_fsl.c | 2 ++ drivers/char/bsr.c | 1 + drivers/char/hw_random/pasemi-rng.c | 1 + drivers/cpufreq/pasemi-cpufreq.c | 1 + drivers/crypto/caam/ctrl.c | 3 +++ drivers/crypto/caam/jr.c | 2 ++ drivers/crypto/talitos.c | 2 ++ drivers/dma/bestcomm/sram.c | 1 + drivers/dma/fsldma.c | 2 ++ drivers/dma/mpc512x_dma.c | 2 ++ drivers/edac/cell_edac.c | 1 + drivers/gpio/gpio-mpc8xxx.c | 1 + drivers/i2c/busses/i2c-ibm_iic.c | 2 ++ drivers/i2c/busses/i2c-mpc.c | 2 ++ drivers/i2c/busses/i2c-powermac.c | 1 + drivers/input/serio/xilinx_ps2.c | 1 + drivers/macintosh/macio_asic.c | 2 ++ drivers/macintosh/rack-meter.c | 2 ++ drivers/macintosh/smu.c | 1 + drivers/macintosh/via-pmu.c | 2 ++ drivers/media/platform/fsl-viu.c | 2 ++ drivers/misc/carma/carma-fpga-program.c | 2 ++ drivers/misc/carma/carma-fpga.c | 2 ++ drivers/mtd/nand/fsl_elbc_nand.c | 1 + drivers/mtd/nand/fsl_ifc_nand.c | 1 + drivers/mtd/nand/fsl_upm.c | 1 + drivers/mtd/nand/mpc5121_nfc.c | 2 ++ drivers/mtd/nand/ndfc.c | 1 + drivers/mtd/nand/pasemi_nand.c | 2 ++ drivers/net/ethernet/freescale/fs_enet/mac-fcc.c | 2 ++ drivers/net/ethernet/freescale/fs_enet/mac-fec.c | 2 ++ drivers/net/ethernet/freescale/fs_enet/mac-scc.c | 2 ++ drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c | 1 + drivers/net/ethernet/freescale/fs_enet/mii-fec.c | 1 + drivers/net/ethernet/freescale/gianfar.c | 2 ++ drivers/net/ethernet/freescale/ucc_geth.c | 2 ++ drivers/net/ethernet/freescale/xgmac_mdio.c | 1 + drivers/net/ethernet/ibm/emac/core.c | 2 ++ drivers/net/ethernet/ibm/emac/mal.c | 1 + drivers/net/ethernet/ibm/emac/rgmii.c | 1 + drivers/net/ethernet/ibm/emac/tah.c | 1 + drivers/net/ethernet/ibm/emac/zmii.c | 1 + drivers/pcmcia/electra_cf.c | 2 ++ drivers/rtc/rtc-mpc5121.c | 2 ++ drivers/spi/spi-fsl-cpm.c | 1 + drivers/spi/spi-fsl-espi.c | 2 ++ drivers/spi/spi-mpc512x-psc.c | 1 + drivers/tty/ehv_bytechan.c | 1 + drivers/tty/serial/cpm_uart/cpm_uart_core.c | 2 ++ drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c | 1 + drivers/tty/serial/pmac_zilog.c | 2 ++ drivers/tty/serial/ucc_uart.c | 2 ++ drivers/usb/gadget/fsl_qe_udc.c | 1 + drivers/usb/host/ehci-ppc-of.c | 2 ++ drivers/usb/host/fhci-hcd.c | 2 ++ drivers/usb/host/ohci-ppc-of.c | 2 ++ drivers/video/fsl-diu-fb.c | 2 ++ drivers/virt/fsl_hypervisor.c | 1 + drivers/watchdog/gef_wdt.c | 1 + drivers/watchdog/mpc8xxx_wdt.c | 1 + 60 files changed, 93 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index 851bd3f..fb0b40a 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include static unsigned int intr_coalescing_count; diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c index 0671e45..8fedbc2 100644 --- a/drivers/char/bsr.c +++ b/drivers/char/bsr.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include diff --git a/drivers/char/hw_random/pasemi-rng.c b/drivers/char/hw_random/pasemi-rng.c index c6df5b2..c66279b 100644 --- a/drivers/char/hw_random/pasemi-rng.c +++ b/drivers/char/hw_random/pasemi-rng.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include diff --git a/drivers/cpufreq/pasemi-cpufreq.c b/drivers/cpufreq/pasemi-cpufreq.c index 534e43a..f4ec814 100644 --- a/drivers/cpufreq/pasemi-cpufreq.c +++ b/drivers/cpufreq/pasemi-cpufreq.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index b010d42..3054870 100644 --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c @@ -5,6 +5,9 @@ * Copyright 2008-2012 Freescale Semiconductor, Inc. */ +#include +#include + #include "compat.h" #include "regs.h" #include "intern.h" diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c index 105ba4d..94b80a9 100644 --- a/drivers/crypto/caam/jr.c +++ b/drivers/crypto/caam/jr.c @@ -5,6 +5,8 @@ * Copyright 2008-2012 Freescale Semiconductor, Inc. */ +#include + #include "compat.h" #include "regs.h" #include "jr.h" diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index 661dc3e..6cd0e60 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -32,6 +32,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/drivers/dma/bestcomm/sram.c b/drivers/dma/bestcomm/sram.c index 5e2ed30..2074e0e 100644 --- a/drivers/dma/bestcomm/sram.c +++ b/drivers/dma/bestcomm/sram.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index b3f3e90..61517dd 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -33,6 +33,8 @@ #include #include #include +#include +#include #include #include "dmaengine.h" diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c index 2fe4353..448750d 100644 --- a/drivers/dma/mpc512x_dma.c +++ b/drivers/dma/mpc512x_dma.c @@ -39,7 +39,9 @@ #include #include #include +#include #include +#include #include #include diff --git a/drivers/edac/cell_edac.c b/drivers/edac/cell_edac.c index c2eaf33..9ee1c76 100644 --- a/drivers/edac/cell_edac.c +++ b/drivers/edac/cell_edac.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c index a0b33a2..de9630b 100644 --- a/drivers/gpio/gpio-mpc8xxx.c +++ b/drivers/gpio/gpio-mpc8xxx.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index ff3caa0..f744410 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c @@ -41,6 +41,8 @@ #include #include #include +#include +#include #include #include "i2c-ibm_iic.h" diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index b80c768..b6a741c 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include #include diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c index 37e8cfa..8c87f4a 100644 --- a/drivers/i2c/busses/i2c-powermac.c +++ b/drivers/i2c/busses/i2c-powermac.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c index 4b7662a..b90eb4f 100644 --- a/drivers/input/serio/xilinx_ps2.c +++ b/drivers/input/serio/xilinx_ps2.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #define DRIVER_NAME "xilinx_ps2" diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index ac5c879..4f12c6f 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include diff --git a/drivers/macintosh/rack-meter.c b/drivers/macintosh/rack-meter.c index cad0e19..4192901 100644 --- a/drivers/macintosh/rack-meter.c +++ b/drivers/macintosh/rack-meter.c @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include #include diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c index b3b2d36..23b4a3b 100644 --- a/drivers/macintosh/smu.c +++ b/drivers/macintosh/smu.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index 283e1b5..dee88e5 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -46,6 +46,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/drivers/media/platform/fsl-viu.c b/drivers/media/platform/fsl-viu.c index fe9898c..6a23223 100644 --- a/drivers/media/platform/fsl-viu.c +++ b/drivers/media/platform/fsl-viu.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/drivers/misc/carma/carma-fpga-program.c b/drivers/misc/carma/carma-fpga-program.c index c6bd7e8..7be8983 100644 --- a/drivers/misc/carma/carma-fpga-program.c +++ b/drivers/misc/carma/carma-fpga-program.c @@ -10,6 +10,8 @@ */ #include +#include +#include #include #include #include diff --git a/drivers/misc/carma/carma-fpga.c b/drivers/misc/carma/carma-fpga.c index 7b56563f..08b18f3 100644 --- a/drivers/misc/carma/carma-fpga.c +++ b/drivers/misc/carma/carma-fpga.c @@ -88,6 +88,8 @@ * interrupt source to the GPIO pin. Tada, we hid the interrupt. :) */ +#include +#include #include #include #include diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index 2065720..e59c886 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c index 317a771..2730c78 100644 --- a/drivers/mtd/nand/fsl_ifc_nand.c +++ b/drivers/mtd/nand/fsl_ifc_nand.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c index 04e0725..4d203e8 100644 --- a/drivers/mtd/nand/fsl_upm.c +++ b/drivers/mtd/nand/fsl_upm.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/mtd/nand/mpc5121_nfc.c b/drivers/mtd/nand/mpc5121_nfc.c index 3c60a00..439bc38 100644 --- a/drivers/mtd/nand/mpc5121_nfc.c +++ b/drivers/mtd/nand/mpc5121_nfc.c @@ -36,7 +36,9 @@ #include #include #include +#include #include +#include #include #include diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index 8e148f1..69eaba6 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include diff --git a/drivers/mtd/nand/pasemi_nand.c b/drivers/mtd/nand/pasemi_nand.c index 5a67082..4d17436 100644 --- a/drivers/mtd/nand/pasemi_nand.c +++ b/drivers/mtd/nand/pasemi_nand.c @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/drivers/net/ethernet/freescale/fs_enet/mac-fcc.c b/drivers/net/ethernet/freescale/fs_enet/mac-fcc.c index 7583a95..005c2e0 100644 --- a/drivers/net/ethernet/freescale/fs_enet/mac-fcc.c +++ b/drivers/net/ethernet/freescale/fs_enet/mac-fcc.c @@ -32,7 +32,9 @@ #include #include #include +#include #include +#include #include #include diff --git a/drivers/net/ethernet/freescale/fs_enet/mac-fec.c b/drivers/net/ethernet/freescale/fs_enet/mac-fec.c index 9ae6cdb..8aac231 100644 --- a/drivers/net/ethernet/freescale/fs_enet/mac-fec.c +++ b/drivers/net/ethernet/freescale/fs_enet/mac-fec.c @@ -31,7 +31,9 @@ #include #include #include +#include #include +#include #include #include diff --git a/drivers/net/ethernet/freescale/fs_enet/mac-scc.c b/drivers/net/ethernet/freescale/fs_enet/mac-scc.c index 22a02a7..e151784 100644 --- a/drivers/net/ethernet/freescale/fs_enet/mac-scc.c +++ b/drivers/net/ethernet/freescale/fs_enet/mac-scc.c @@ -31,6 +31,8 @@ #include #include #include +#include +#include #include #include diff --git a/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c b/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c index 844ecfa..67caaac 100644 --- a/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c +++ b/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/ethernet/freescale/fs_enet/mii-fec.c b/drivers/net/ethernet/freescale/fs_enet/mii-fec.c index 2f1c46a..ac5d447 100644 --- a/drivers/net/ethernet/freescale/fs_enet/mii-fec.c +++ b/drivers/net/ethernet/freescale/fs_enet/mii-fec.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index c4eaade..c49abb4 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -78,6 +78,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c index 5930c39..64b329f 100644 --- a/drivers/net/ethernet/freescale/ucc_geth.c +++ b/drivers/net/ethernet/freescale/ucc_geth.c @@ -31,6 +31,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/drivers/net/ethernet/freescale/xgmac_mdio.c b/drivers/net/ethernet/freescale/xgmac_mdio.c index c1b6e7e..d449fcb9 100644 --- a/drivers/net/ethernet/freescale/xgmac_mdio.c +++ b/drivers/net/ethernet/freescale/xgmac_mdio.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c index 6b5c722..cdf2321 100644 --- a/drivers/net/ethernet/ibm/emac/core.c +++ b/drivers/net/ethernet/ibm/emac/core.c @@ -39,6 +39,8 @@ #include #include #include +#include +#include #include #include diff --git a/drivers/net/ethernet/ibm/emac/mal.c b/drivers/net/ethernet/ibm/emac/mal.c index dac564c..4742ba3 100644 --- a/drivers/net/ethernet/ibm/emac/mal.c +++ b/drivers/net/ethernet/ibm/emac/mal.c @@ -27,6 +27,7 @@ #include #include +#include #include "core.h" #include diff --git a/drivers/net/ethernet/ibm/emac/rgmii.c b/drivers/net/ethernet/ibm/emac/rgmii.c index c47e23d..4fb2f96 100644 --- a/drivers/net/ethernet/ibm/emac/rgmii.c +++ b/drivers/net/ethernet/ibm/emac/rgmii.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "emac.h" diff --git a/drivers/net/ethernet/ibm/emac/tah.c b/drivers/net/ethernet/ibm/emac/tah.c index c231a4a..9f24769 100644 --- a/drivers/net/ethernet/ibm/emac/tah.c +++ b/drivers/net/ethernet/ibm/emac/tah.c @@ -18,6 +18,7 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. */ +#include #include #include "emac.h" diff --git a/drivers/net/ethernet/ibm/emac/zmii.c b/drivers/net/ethernet/ibm/emac/zmii.c index 4cdf286..9ca67a3 100644 --- a/drivers/net/ethernet/ibm/emac/zmii.c +++ b/drivers/net/ethernet/ibm/emac/zmii.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "emac.h" diff --git a/drivers/pcmcia/electra_cf.c b/drivers/pcmcia/electra_cf.c index a007321a..1b206ea 100644 --- a/drivers/pcmcia/electra_cf.c +++ b/drivers/pcmcia/electra_cf.c @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include #include diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c index 9c8f609..dc4f142 100644 --- a/drivers/rtc/rtc-mpc5121.c +++ b/drivers/rtc/rtc-mpc5121.c @@ -14,7 +14,9 @@ #include #include #include +#include #include +#include #include #include #include diff --git a/drivers/spi/spi-fsl-cpm.c b/drivers/spi/spi-fsl-cpm.c index 07971e3..bd5aaf4 100644 --- a/drivers/spi/spi-fsl-cpm.c +++ b/drivers/spi/spi-fsl-cpm.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c index b8f1103..c1c936c 100644 --- a/drivers/spi/spi-fsl-espi.c +++ b/drivers/spi/spi-fsl-espi.c @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c index dbc5e99..6148b1d 100644 --- a/drivers/spi/spi-mpc512x-psc.c +++ b/drivers/spi/spi-mpc512x-psc.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c index 9bffcec..0419b69 100644 --- a/drivers/tty/ehv_bytechan.c +++ b/drivers/tty/ehv_bytechan.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c index 1a535f7..9f7ba6d 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c @@ -41,6 +41,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c index 18f7957..527a969 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c @@ -45,6 +45,7 @@ #include #include +#include #include "cpm_uart.h" diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index f87f1a0..246b4c3 100644 --- a/drivers/tty/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c @@ -57,6 +57,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c index 8831748..9de1da0 100644 --- a/drivers/tty/serial/ucc_uart.c +++ b/drivers/tty/serial/ucc_uart.c @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include #include diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index f3bb363..807127d 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c index 932293f..2b1694e 100644 --- a/drivers/usb/host/ehci-ppc-of.c +++ b/drivers/usb/host/ehci-ppc-of.c @@ -16,6 +16,8 @@ #include #include +#include +#include #include diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c index 0b4654259..0551c0a 100644 --- a/drivers/usb/host/fhci-hcd.c +++ b/drivers/usb/host/fhci-hcd.c @@ -26,6 +26,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c index 75f5a1e..81f3eba 100644 --- a/drivers/usb/host/ohci-ppc-of.c +++ b/drivers/usb/host/ohci-ppc-of.c @@ -14,6 +14,8 @@ */ #include +#include +#include #include #include diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c index 6dd7225..b047ec5 100644 --- a/drivers/video/fsl-diu-fb.c +++ b/drivers/video/fsl-diu-fb.c @@ -31,6 +31,8 @@ #include #include #include +#include +#include #include #include diff --git a/drivers/virt/fsl_hypervisor.c b/drivers/virt/fsl_hypervisor.c index d294f67..32c8fc5 100644 --- a/drivers/virt/fsl_hypervisor.c +++ b/drivers/virt/fsl_hypervisor.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/watchdog/gef_wdt.c b/drivers/watchdog/gef_wdt.c index 257cfba..3755833 100644 --- a/drivers/watchdog/gef_wdt.c +++ b/drivers/watchdog/gef_wdt.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c index da27520..d0ebeba 100644 --- a/drivers/watchdog/mpc8xxx_wdt.c +++ b/drivers/watchdog/mpc8xxx_wdt.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include -- cgit v1.1 From 25ff79443cbfa924b8df1d4a8a0fbff83816938a Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Sat, 7 Sep 2013 14:07:11 -0500 Subject: of: implement pci_address_to_pio as weak function Implement pci_address_to_pio as weak function to remove the dependency on asm/prom.h. This is in preparation to make prom.h optional. Signed-off-by: Rob Herring Acked-by: Grant Likely Cc: Michal Simek Cc: Ralf Baechle Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Thomas Gleixner Cc: Ingo Molnar Cc: "H. Peter Anvin" Cc: x86@kernel.org Cc: Grant Likely --- drivers/of/address.c | 8 ++++++++ drivers/of/of_pci.c | 1 - 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/of/address.c b/drivers/of/address.c index b55c218..556a7fb 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -626,6 +626,14 @@ 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/of_pci.c b/drivers/of/of_pci.c index e5ca008..8481996 100644 --- a/drivers/of/of_pci.c +++ b/drivers/of/of_pci.c @@ -2,7 +2,6 @@ #include #include #include -#include static inline int __of_pci_pci_compare(struct device_node *node, unsigned int data) -- cgit v1.1 From 0c3f061c195ceb891067b6de9e4ecc347c4dea31 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 17 Sep 2013 10:42:50 -0500 Subject: of: implement of_node_to_nid as a weak function Implement of_node_to_nid as weak function to remove the dependency on asm/prom.h. This is in preparation to make prom.h optional. Signed-off-by: Rob Herring Acked-by: Grant Likely --- drivers/of/base.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/of/base.c b/drivers/of/base.c index 865d3f6..ced4c06 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -74,6 +74,13 @@ 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 -- cgit v1.1 From d1cb9d1af0bc11b7450a6032f43935c746609418 Mon Sep 17 00:00:00 2001 From: David Miller Date: Thu, 3 Oct 2013 17:24:51 -0400 Subject: of: Make cpu node handling more portable. Use for_each_node_by_type() to iterate all cpu nodes in the system. Provide and overridable function arch_find_n_match_cpu_physical_id, which sees if the given device node matches 'cpu' and if so sets '*thread' when non-NULL to the cpu thread number within the core. The default implementation behaves the same as the existing code. Add a sparc64 implementation. Signed-off-by: David S. Miller Tested-by: Sudeep KarkadaNagesha Signed-off-by: Grant Likely --- drivers/of/base.c | 45 ++++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/of/base.c b/drivers/of/base.c index 7d4c70f..e4c9945 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -280,6 +280,31 @@ 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 * @@ -300,24 +325,10 @@ static bool __of_find_n_match_cpu_property(struct device_node *cpun, */ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) { - struct device_node *cpun, *cpus; - - cpus = of_find_node_by_path("/cpus"); - if (!cpus) - return NULL; + struct device_node *cpun; - 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)) + for_each_node_by_type(cpun, "cpu") { + if (arch_find_n_match_cpu_physical_id(cpun, cpu, thread)) return cpun; } return NULL; -- cgit v1.1 From f3cea45a77c8ebdb7efad100e576eb6cb401bf25 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 4 Oct 2013 17:24:26 +0100 Subject: of: Fix iteration bug over CPU reg properties The size of each hwid in a cpu nodes 'reg' property is defined by the parents #address-cells property in the normal way. The cpu parsing code has a bug where it will overrun the end of the property if address-cells is greater than one. This commit fixes the problem by adjusting the array size by the number of address cells. It also makes sure address-cells isn't zero for that would cause an infinite loop. v2: bail if #address-cells is zero instead of forcing to OF_ROOT_NODE_ADDR_CELLS_DEFAULT. Forcing it will cause the reg property to be parsed incorrectly. Signed-off-by: Grant Likely Cc: Rob Herring Cc: Benjamin Herrenschmidt --- drivers/of/base.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/of/base.c b/drivers/of/base.c index e4c9945..3ae106d 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -265,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) + if (!cell || !ac) return false; - prop_len /= sizeof(*cell); + prop_len /= sizeof(*cell) * ac; for (tid = 0; tid < prop_len; tid++) { hwid = of_read_number(cell, ac); if (arch_match_cpu_phys_id(cpu, hwid)) { -- cgit v1.1 From 8804827b305dbc1c6e24f2b36f1df4a9856b80e8 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 19 Sep 2013 11:01:52 -0500 Subject: of: Fix dereferencing node name in debug output to be safe Several locations in the of_address and of_irq code dereference the full_name parameter from a device_node pointer without checking if the pointer is valid. This patch switches to use of_node_full_name() which always checks the pointer. Signed-off-by: Grant Likely --- drivers/of/address.c | 6 +++--- drivers/of/irq.c | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/of/address.c b/drivers/of/address.c index b55c218..71180b9 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", dev->full_name); + pr_debug("OF: ** translation for device %s **\n", of_node_full_name(dev)); /* 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", - dev->full_name); + of_node_full_name(dev)); 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, parent->full_name); + bus->name, na, ns, of_node_full_name(parent)); of_dump_addr("OF: translating address:", addr, na); /* Translate */ diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 1752988..f5fa5d8 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -102,7 +102,7 @@ int of_irq_map_raw(struct device_node *parent, const __be32 *intspec, int imaplen, match, i; pr_debug("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n", - parent->full_name, be32_to_cpup(intspec), + of_node_full_name(parent), be32_to_cpup(intspec), be32_to_cpup(intspec + 1), ointsize); ipar = of_node_get(parent); @@ -126,7 +126,7 @@ int of_irq_map_raw(struct device_node *parent, const __be32 *intspec, goto fail; } - pr_debug("of_irq_map_raw: ipar=%s, size=%d\n", ipar->full_name, intsize); + pr_debug("of_irq_map_raw: ipar=%s, size=%d\n", of_node_full_name(ipar), intsize); if (ointsize != intsize) return -EINVAL; @@ -287,7 +287,7 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq u32 intsize, intlen; int res = -EINVAL; - pr_debug("of_irq_map_one: dev=%s, index=%d\n", device->full_name, index); + pr_debug("of_irq_map_one: dev=%s, index=%d\n", of_node_full_name(device), index); /* OldWorld mac stuff is "special", handle out of line */ if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC) @@ -355,7 +355,7 @@ int of_irq_to_resource(struct device_node *dev, int index, struct resource *r) r->start = r->end = irq; r->flags = IORESOURCE_IRQ; - r->name = name ? name : dev->full_name; + r->name = name ? name : of_node_full_name(dev); } return irq; -- cgit v1.1 From 4a43d686fe336cc0e955c4400ba4d3fcff788786 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Sat, 28 Sep 2013 19:52:51 +0200 Subject: of/irq: Pass trigger type in IRQ resource flags Some drivers might rely on availability of trigger flags in IRQ resource, for example to configure the hardware for particular interrupt type. However current code creating IRQ resources from data in device tree does not configure trigger flags in resulting resources. This patch tries to solve the problem, based on the fact that irq_of_parse_and_map() configures the trigger based on DT interrupt specifier and IRQD_TRIGGER_* flags are consistent with IORESOURCE_IRQ_*, and we can get correct trigger flags by calling irqd_get_trigger_type() after mapping the interrupt. Signed-off-by: Tomasz Figa [grant.likely: Merged the two assignments to r->flags] Signed-off-by: Grant Likely --- drivers/of/irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/of/irq.c b/drivers/of/irq.c index f5fa5d8..90068f9 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -354,7 +354,7 @@ int of_irq_to_resource(struct device_node *dev, int index, struct resource *r) &name); r->start = r->end = irq; - r->flags = IORESOURCE_IRQ; + r->flags = IORESOURCE_IRQ | irqd_get_trigger_type(irq_get_irq_data(irq)); r->name = name ? name : of_node_full_name(dev); } -- cgit v1.1 From 0c02c8007ea5554d028f99fd3e29fc201fdeeab3 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 19 Sep 2013 11:22:36 -0500 Subject: of/irq: Rename of_irq_map_* functions to of_irq_parse_* The OF irq handling code has been overloading the term 'map' to refer to both parsing the data in the device tree and mapping it to the internal linux irq system. This is probably because the device tree does have the concept of an 'interrupt-map' function for translating interrupt references from one node to another, but 'map' is still confusing when the primary purpose of some of the functions are to parse the DT data. This patch renames all the of_irq_map_* functions to of_irq_parse_* which makes it clear that there is a difference between the parsing phase and the mapping phase. Kernel code can make use of just the parsing or just the mapping support as needed by the subsystem. The patch was generated mechanically with a handful of sed commands. Signed-off-by: Grant Likely Acked-by: Michal Simek Acked-by: Tony Lindgren Cc: Ralf Baechle Cc: Benjamin Herrenschmidt --- drivers/of/address.c | 4 ++-- drivers/of/irq.c | 28 ++++++++++++++-------------- drivers/of/of_pci_irq.c | 10 +++++----- drivers/pci/host/pci-mvebu.c | 2 +- 4 files changed, 22 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/of/address.c b/drivers/of/address.c index 71180b9..994f293 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -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", - dev->full_name); + of_node_full_name(dev)); break; } pr_debug("OF: parent bus is %s (na=%d, ns=%d) on %s\n", - pbus->name, pna, pns, parent->full_name); + pbus->name, pna, pns, of_node_full_name(parent)); /* Apply bus translation */ if (of_translate_one(dev, bus, pbus, addr, na, ns, pna, rprop)) diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 90068f9..410aa24 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -31,14 +31,14 @@ * @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_map_one() and + * This function is a wrapper that chains of_irq_parse_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_irq oirq; - if (of_irq_map_one(dev, index, &oirq)) + if (of_irq_parse_one(dev, index, &oirq)) return 0; return irq_create_of_mapping(oirq.controller, oirq.specifier, @@ -79,7 +79,7 @@ struct device_node *of_irq_find_parent(struct device_node *child) } /** - * of_irq_map_raw - Low level interrupt tree parsing + * of_irq_parse_raw - Low level interrupt tree parsing * @parent: the device interrupt parent * @intspec: interrupt specifier ("interrupts" property of the device) * @ointsize: size of the passed in interrupt specifier @@ -93,7 +93,7 @@ struct device_node *of_irq_find_parent(struct device_node *child) * properties, for example when resolving PCI interrupts when no device * node exist for the parent. */ -int of_irq_map_raw(struct device_node *parent, const __be32 *intspec, +int of_irq_parse_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; @@ -101,7 +101,7 @@ int of_irq_map_raw(struct device_node *parent, const __be32 *intspec, u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0; int imaplen, match, i; - pr_debug("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n", + pr_debug("of_irq_parse_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n", of_node_full_name(parent), be32_to_cpup(intspec), be32_to_cpup(intspec + 1), ointsize); @@ -126,7 +126,7 @@ int of_irq_map_raw(struct device_node *parent, const __be32 *intspec, goto fail; } - pr_debug("of_irq_map_raw: ipar=%s, size=%d\n", of_node_full_name(ipar), intsize); + pr_debug("of_irq_parse_raw: ipar=%s, size=%d\n", of_node_full_name(ipar), intsize); if (ointsize != intsize) return -EINVAL; @@ -269,29 +269,29 @@ int of_irq_map_raw(struct device_node *parent, const __be32 *intspec, return -EINVAL; } -EXPORT_SYMBOL_GPL(of_irq_map_raw); +EXPORT_SYMBOL_GPL(of_irq_parse_raw); /** - * of_irq_map_one - Resolve an interrupt for a device + * of_irq_parse_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, walking the tree, for a given - * device-tree node. It's the high level pendant to of_irq_map_raw(). + * device-tree node. It's the high level pendant to of_irq_parse_raw(). */ -int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq) +int of_irq_parse_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 res = -EINVAL; - pr_debug("of_irq_map_one: dev=%s, index=%d\n", of_node_full_name(device), index); + pr_debug("of_irq_parse_one: dev=%s, index=%d\n", of_node_full_name(device), index); /* OldWorld mac stuff is "special", handle out of line */ if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC) - return of_irq_map_oldworld(device, index, out_irq); + return of_irq_parse_oldworld(device, index, out_irq); /* Get the interrupts property */ intspec = of_get_property(device, "interrupts", &intlen); @@ -322,13 +322,13 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq goto out; /* Get new specifier and map it */ - res = of_irq_map_raw(p, intspec + index * intsize, intsize, + res = of_irq_parse_raw(p, intspec + index * intsize, intsize, addr, out_irq); out: of_node_put(p); return res; } -EXPORT_SYMBOL_GPL(of_irq_map_one); +EXPORT_SYMBOL_GPL(of_irq_parse_one); /** * of_irq_to_resource - Decode a node's IRQ and return it as a resource diff --git a/drivers/of/of_pci_irq.c b/drivers/of/of_pci_irq.c index 6770538..dceec10 100644 --- a/drivers/of/of_pci_irq.c +++ b/drivers/of/of_pci_irq.c @@ -5,7 +5,7 @@ #include /** - * of_irq_map_pci - Resolve the interrupt for a PCI device + * of_irq_parse_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 * @@ -15,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_map_pci(const struct pci_dev *pdev, struct of_irq *out_irq) +int of_irq_parse_pci(const struct pci_dev *pdev, struct of_irq *out_irq) { struct device_node *dn, *ppnode; struct pci_dev *ppdev; @@ -30,7 +30,7 @@ int of_irq_map_pci(const struct pci_dev *pdev, struct of_irq *out_irq) */ dn = pci_device_to_OF_node(pdev); if (dn) { - rc = of_irq_map_one(dn, 0, out_irq); + rc = of_irq_parse_one(dn, 0, out_irq); if (!rc) return rc; } @@ -88,6 +88,6 @@ int of_irq_map_pci(const struct pci_dev *pdev, struct of_irq *out_irq) 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_map_raw(ppnode, &lspec_be, 1, laddr, out_irq); + return of_irq_parse_raw(ppnode, &lspec_be, 1, laddr, out_irq); } -EXPORT_SYMBOL_GPL(of_irq_map_pci); +EXPORT_SYMBOL_GPL(of_irq_parse_pci); diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c index 729d5a1..05f8180 100644 --- a/drivers/pci/host/pci-mvebu.c +++ b/drivers/pci/host/pci-mvebu.c @@ -650,7 +650,7 @@ static int __init mvebu_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) struct of_irq oirq; int ret; - ret = of_irq_map_pci(dev, &oirq); + ret = of_irq_parse_pci(dev, &oirq); if (ret) return ret; -- cgit v1.1 From 530210c7814e83564c7ca7bca8192515042c0b63 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Sun, 15 Sep 2013 16:39:11 +0100 Subject: of/irq: Replace of_irq with of_phandle_args struct of_irq and struct of_phandle_args are exactly the same structure. This patch makes the kernel use of_phandle_args everywhere. This in itself isn't a big deal, but it makes some follow-on patches simpler. Signed-off-by: Grant Likely Acked-by: Michal Simek Acked-by: Tony Lindgren Cc: Russell King Cc: Ralf Baechle Cc: Benjamin Herrenschmidt --- drivers/of/irq.c | 15 +++++++-------- drivers/of/of_pci_irq.c | 2 +- drivers/pci/host/pci-mvebu.c | 5 ++--- 3 files changed, 10 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 410aa24..a7db38a 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -36,13 +36,12 @@ */ unsigned int irq_of_parse_and_map(struct device_node *dev, int index) { - struct of_irq oirq; + struct of_phandle_args oirq; if (of_irq_parse_one(dev, index, &oirq)) return 0; - return irq_create_of_mapping(oirq.controller, oirq.specifier, - oirq.size); + return irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count); } EXPORT_SYMBOL_GPL(irq_of_parse_and_map); @@ -94,7 +93,7 @@ struct device_node *of_irq_find_parent(struct device_node *child) * node exist for the parent. */ int of_irq_parse_raw(struct device_node *parent, const __be32 *intspec, - u32 ointsize, const __be32 *addr, struct of_irq *out_irq) + u32 ointsize, const __be32 *addr, struct of_phandle_args *out_irq) { struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL; const __be32 *tmp, *imap, *imask; @@ -156,10 +155,10 @@ int of_irq_parse_raw(struct device_node *parent, const __be32 *intspec, NULL) { pr_debug(" -> got it !\n"); for (i = 0; i < intsize; i++) - out_irq->specifier[i] = + out_irq->args[i] = of_read_number(intspec +i, 1); - out_irq->size = intsize; - out_irq->controller = ipar; + out_irq->args_count = intsize; + out_irq->np = ipar; of_node_put(old); return 0; } @@ -280,7 +279,7 @@ EXPORT_SYMBOL_GPL(of_irq_parse_raw); * This function resolves an interrupt, walking the tree, for a given * device-tree node. It's the high level pendant to of_irq_parse_raw(). */ -int of_irq_parse_one(struct device_node *device, int index, struct of_irq *out_irq) +int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_args *out_irq) { struct device_node *p; const __be32 *intspec, *tmp, *addr; diff --git a/drivers/of/of_pci_irq.c b/drivers/of/of_pci_irq.c index dceec10..ee3293d 100644 --- a/drivers/of/of_pci_irq.c +++ b/drivers/of/of_pci_irq.c @@ -15,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_irq *out_irq) +int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq) { struct device_node *dn, *ppnode; struct pci_dev *ppdev; diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c index 05f8180..c5e57f8 100644 --- a/drivers/pci/host/pci-mvebu.c +++ b/drivers/pci/host/pci-mvebu.c @@ -647,15 +647,14 @@ static int __init mvebu_pcie_setup(int nr, struct pci_sys_data *sys) static int __init mvebu_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - struct of_irq oirq; + struct of_phandle_args oirq; int ret; ret = of_irq_parse_pci(dev, &oirq); if (ret) return ret; - return irq_create_of_mapping(oirq.controller, oirq.specifier, - oirq.size); + return irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count); } static struct pci_bus *mvebu_pcie_scan_bus(int nr, struct pci_sys_data *sys) -- cgit v1.1 From e6d30ab1e7d1281784672c0fc2ffa385cfb7279e Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Sun, 15 Sep 2013 16:55:53 +0100 Subject: of/irq: simplify args to irq_create_of_mapping All the callers of irq_create_of_mapping() pass the contents of a struct of_phandle_args structure to the function. Since all the callers already have an of_phandle_args pointer, why not pass it directly to irq_create_of_mapping()? Signed-off-by: Grant Likely Acked-by: Michal Simek Acked-by: Tony Lindgren Cc: Thomas Gleixner Cc: Russell King Cc: Ralf Baechle Cc: Benjamin Herrenschmidt --- drivers/of/irq.c | 2 +- drivers/pci/host/pci-mvebu.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/of/irq.c b/drivers/of/irq.c index a7db38a..84184c44 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -41,7 +41,7 @@ unsigned int irq_of_parse_and_map(struct device_node *dev, int index) if (of_irq_parse_one(dev, index, &oirq)) return 0; - return irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count); + return irq_create_of_mapping(&oirq); } EXPORT_SYMBOL_GPL(irq_of_parse_and_map); diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c index c5e57f8..3a8d01e 100644 --- a/drivers/pci/host/pci-mvebu.c +++ b/drivers/pci/host/pci-mvebu.c @@ -654,7 +654,7 @@ static int __init mvebu_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) if (ret) return ret; - return irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count); + return irq_create_of_mapping(&oirq); } static struct pci_bus *mvebu_pcie_scan_bus(int nr, struct pci_sys_data *sys) -- cgit v1.1 From 2361613206e66ce59cc0e08efa8d98ec15b84ed1 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Sun, 15 Sep 2013 22:32:39 +0100 Subject: of/irq: Refactor interrupt-map parsing All the users of of_irq_parse_raw pass in a raw interrupt specifier from the device tree and expect it to be returned (possibly modified) in an of_phandle_args structure. However, the primary function of of_irq_parse_raw() is to check for translations due to the presence of one or more interrupt-map properties. The actual placing of the data into an of_phandle_args structure is trivial. If it is refactored to accept an of_phandle_args structure directly, then it becomes possible to consume of_phandle_args from other sources. This is important for an upcoming patch that allows a device to be connected to more than one interrupt parent. It also simplifies the code a bit. The biggest complication with this patch is that the old version works on the interrupt specifiers in __be32 form, but the of_phandle_args structure is intended to carry it in the cpu-native version. A bit of churn was required to make this work. In the end it results in tighter code, so the churn is worth it. Signed-off-by: Grant Likely Acked-by: Tony Lindgren Cc: Benjamin Herrenschmidt --- drivers/of/irq.c | 108 +++++++++++++++++++++++++----------------------- drivers/of/of_pci_irq.c | 7 +++- 2 files changed, 62 insertions(+), 53 deletions(-) (limited to 'drivers') diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 84184c44..0ed5ed4 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -80,31 +80,32 @@ struct device_node *of_irq_find_parent(struct device_node *child) /** * of_irq_parse_raw - Low level interrupt tree parsing * @parent: the device interrupt parent - * @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 + * @addr: address specifier (start of "reg" property of the device) in be32 format + * @out_irq: structure of_irq updated 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. + * 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. */ -int of_irq_parse_raw(struct device_node *parent, const __be32 *intspec, - u32 ointsize, const __be32 *addr, struct of_phandle_args *out_irq) +int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) { struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL; - const __be32 *tmp, *imap, *imask; + __be32 initial_match_array[8]; + const __be32 *match_array = initial_match_array; + const __be32 *tmp, *imap, *imask, dummy_imask[] = { ~0, ~0, ~0, ~0, ~0 }; u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0; int imaplen, match, i; pr_debug("of_irq_parse_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n", - of_node_full_name(parent), be32_to_cpup(intspec), - be32_to_cpup(intspec + 1), ointsize); + of_node_full_name(out_irq->np), out_irq->args[0], out_irq->args[1], + out_irq->args_count); - ipar = of_node_get(parent); + ipar = of_node_get(out_irq->np); /* First get the #interrupt-cells property of the current cursor * that tells us how to interpret the passed-in intspec. If there @@ -127,7 +128,7 @@ int of_irq_parse_raw(struct device_node *parent, const __be32 *intspec, pr_debug("of_irq_parse_raw: ipar=%s, size=%d\n", of_node_full_name(ipar), intsize); - if (ointsize != intsize) + if (out_irq->args_count != intsize) return -EINVAL; /* Look for this #address-cells. We have to implement the old linux @@ -146,6 +147,21 @@ int of_irq_parse_raw(struct device_node *parent, const __be32 *intspec, pr_debug(" -> addrsize=%d\n", addrsize); + /* 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"); + return -EINVAL; + } + + /* Precalculate the match array - this simplifies match loop */ + for (i = 0; i < addrsize; i++) + initial_match_array[i] = addr[i]; + 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 @@ -154,11 +170,6 @@ int of_irq_parse_raw(struct device_node *parent, const __be32 *intspec, if (of_get_property(ipar, "interrupt-controller", NULL) != NULL) { pr_debug(" -> got it !\n"); - for (i = 0; i < intsize; i++) - out_irq->args[i] = - of_read_number(intspec +i, 1); - out_irq->args_count = intsize; - out_irq->np = ipar; of_node_put(old); return 0; } @@ -175,34 +186,16 @@ int of_irq_parse_raw(struct device_node *parent, const __be32 *intspec, /* Look for a mask */ imask = of_get_property(ipar, "interrupt-map-mask", NULL); - - /* 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; - } + if (!imask) + imask = dummy_imask; /* Parse interrupt-map */ match = 0; while (imaplen > (addrsize + intsize + 1) && !match) { /* Compare specifiers */ match = 1; - 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; + for (i = 0; i < (addrsize + intsize); i++, imaplen--) + match = !((match_array[i] ^ *imap++) & imask[i]); pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen); @@ -247,12 +240,18 @@ int of_irq_parse_raw(struct device_node *parent, const __be32 *intspec, if (!match) goto fail; - of_node_put(old); - old = of_node_get(newpar); + /* + * 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; addrsize = newaddrsize; - intsize = newintsize; - intspec = imap - intsize; - addr = intspec - addrsize; skiplevel: /* Iterate again with new parent */ @@ -263,7 +262,7 @@ int of_irq_parse_raw(struct device_node *parent, const __be32 *intspec, } fail: of_node_put(ipar); - of_node_put(old); + of_node_put(out_irq->np); of_node_put(newpar); return -EINVAL; @@ -276,15 +275,16 @@ EXPORT_SYMBOL_GPL(of_irq_parse_raw); * @index: index of the interrupt to resolve * @out_irq: structure of_irq filled by this function * - * This function resolves an interrupt, walking the tree, for a given - * device-tree node. It's the high level pendant to of_irq_parse_raw(). + * 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. */ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_args *out_irq) { struct device_node *p; const __be32 *intspec, *tmp, *addr; u32 intsize, intlen; - int res = -EINVAL; + int i, res = -EINVAL; pr_debug("of_irq_parse_one: dev=%s, index=%d\n", of_node_full_name(device), index); @@ -320,9 +320,15 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar if ((index + 1) * intsize > intlen) goto out; - /* Get new specifier and map it */ - res = of_irq_parse_raw(p, intspec + index * intsize, intsize, - addr, out_irq); + /* 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); out: of_node_put(p); return res; diff --git a/drivers/of/of_pci_irq.c b/drivers/of/of_pci_irq.c index ee3293d..303afeb 100644 --- a/drivers/of/of_pci_irq.c +++ b/drivers/of/of_pci_irq.c @@ -85,9 +85,12 @@ 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(ppnode, &lspec_be, 1, laddr, out_irq); + laddr[1] = laddr[2] = cpu_to_be32(0); + return of_irq_parse_raw(laddr, out_irq); } EXPORT_SYMBOL_GPL(of_irq_parse_pci); -- cgit v1.1 From 624cfca534f9b1ffb1326617b4e973a3d5ecff4a Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 11 Oct 2013 22:05:10 +0100 Subject: of: Add helper for printing an of_phandle_args structure It is sometimes useful for debug to get the contents of an of_phandle_args structure out into the kernel log. Signed-off-by: Grant Likely --- drivers/of/base.c | 9 +++++++++ drivers/of/irq.c | 6 +++--- 2 files changed, 12 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/of/base.c b/drivers/of/base.c index 3ae106d..021db96 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1185,6 +1185,15 @@ 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, diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 0ed5ed4..ddea945 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -101,9 +101,9 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0; int imaplen, match, i; - pr_debug("of_irq_parse_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n", - of_node_full_name(out_irq->np), out_irq->args[0], out_irq->args[1], - out_irq->args_count); +#ifdef DEBUG + of_print_phandle_args("of_irq_parse_raw: ", out_irq); +#endif ipar = of_node_get(out_irq->np); -- cgit v1.1 From a9f10ca76d784023fc45f01f025b54e9960f4ec1 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 11 Oct 2013 22:04:23 +0100 Subject: of: Add testcases for interrupt parsing This patch extends the DT selftest code with some test cases for the interrupt parsing functions. Signed-off-by: Grant Likely --- drivers/of/selftest.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 85 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/of/selftest.c b/drivers/of/selftest.c index 0eb5c38..9c80f0b 100644 --- a/drivers/of/selftest.c +++ b/drivers/of/selftest.c @@ -9,18 +9,24 @@ #include #include #include +#include #include #include #include #include -static bool selftest_passed = true; +static struct selftest_results { + int passed; + int failed; +} selftest_results; + #define selftest(result, fmt, ...) { \ if (!(result)) { \ - pr_err("FAIL %s:%i " fmt, __FILE__, __LINE__, ##__VA_ARGS__); \ - selftest_passed = false; \ + selftest_results.failed++; \ + pr_err("FAIL %s():%i " fmt, __func__, __LINE__, ##__VA_ARGS__); \ } else { \ - pr_info("pass %s:%i\n", __FILE__, __LINE__); \ + selftest_results.passed++; \ + pr_debug("pass %s():%i\n", __func__, __LINE__); \ } \ } @@ -131,7 +137,6 @@ 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"); @@ -154,6 +159,78 @@ 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 int __init of_selftest(void) { struct device_node *np; @@ -168,7 +245,9 @@ 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(); - pr_info("end of selftest - %s\n", selftest_passed ? "PASS" : "FAIL"); + of_selftest_parse_interrupts(); + pr_info("end of selftest - %i passed, %i failed\n", + selftest_results.passed, selftest_results.failed); return 0; } late_initcall(of_selftest); -- cgit v1.1 From 3da5278727a895d49a601f67fd49dffa0b80f9a5 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 18 Sep 2013 15:24:43 +0200 Subject: of/irq: Rework of_irq_count() The of_irq_to_resource() helper that is used to implement of_irq_count() tries to resolve interrupts and in fact creates a mapping for resolved interrupts. That's pretty heavy lifting for something that claims to just return the number of interrupts requested by a given device node. Instead, use the more lightweight of_irq_map_one(), which, despite the name, doesn't create an actual mapping. Perhaps a better name would be of_irq_translate_one(). Signed-off-by: Thierry Reding Acked-by: Rob Herring [grant.likely: fixup s/of_irq_map_one/of_irq_parse_one/] Signed-off-by: Grant Likely --- drivers/of/irq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/of/irq.c b/drivers/of/irq.c index ddea945..7c4ff12 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -373,9 +373,10 @@ 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_to_resource(dev, nr, NULL)) + while (of_irq_parse_one(dev, nr, &irq) == 0) nr++; return nr; -- cgit v1.1 From f7578496a671a96e501f16a5104893275e32c33a Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 18 Sep 2013 15:24:44 +0200 Subject: of/irq: Use irq_of_parse_and_map() Replace some instances of of_irq_map_one()/irq_create_of_mapping() and of_irq_to_resource() by the simpler equivalent irq_of_parse_and_map(). Signed-off-by: Thierry Reding Acked-by: Rob Herring [grant.likely: resolved conflicts with core code renames] Signed-off-by: Grant Likely --- drivers/crypto/caam/ctrl.c | 2 +- drivers/crypto/caam/jr.c | 2 +- drivers/crypto/omap-sham.c | 2 +- drivers/i2c/busses/i2c-cpm.c | 2 +- drivers/input/serio/xilinx_ps2.c | 7 ++++--- drivers/net/ethernet/arc/emac_main.c | 10 +++++----- drivers/net/ethernet/freescale/fs_enet/mac-fcc.c | 2 +- drivers/net/ethernet/freescale/fs_enet/mac-fec.c | 2 +- drivers/net/ethernet/freescale/fs_enet/mac-scc.c | 2 +- drivers/spi/spi-fsl-espi.c | 6 +++--- drivers/tty/serial/cpm_uart/cpm_uart_core.c | 2 +- 11 files changed, 20 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index b010d42..ae6e554 100644 --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c @@ -224,7 +224,7 @@ static int caam_probe(struct platform_device *pdev) topregs = (struct caam_full __iomem *)ctrl; /* Get the IRQ of the controller (for security violations only) */ - ctrlpriv->secvio_irq = of_irq_to_resource(nprop, 0, NULL); + ctrlpriv->secvio_irq = irq_of_parse_and_map(nprop, 0); /* * Enable DECO watchdogs and, if this is a PHYS_ADDR_T_64BIT kernel, diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c index 105ba4d..517a16d 100644 --- a/drivers/crypto/caam/jr.c +++ b/drivers/crypto/caam/jr.c @@ -403,7 +403,7 @@ int caam_jr_probe(struct platform_device *pdev, struct device_node *np, dma_set_mask(jrdev, DMA_BIT_MASK(32)); /* Identify the interrupt */ - jrpriv->irq = of_irq_to_resource(np, 0, NULL); + jrpriv->irq = irq_of_parse_and_map(np, 0); /* Now do the platform independent part */ error = caam_jr_init(jrdev); /* now turn on hardware */ diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c index 8bdde57..e28104b 100644 --- a/drivers/crypto/omap-sham.c +++ b/drivers/crypto/omap-sham.c @@ -1818,7 +1818,7 @@ static int omap_sham_get_res_of(struct omap_sham_dev *dd, goto err; } - dd->irq = of_irq_to_resource(node, 0, NULL); + dd->irq = irq_of_parse_and_map(node, 0); if (!dd->irq) { dev_err(dev, "can't translate OF irq value\n"); err = -EINVAL; diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c index b2b8aa9..3e5ea2c 100644 --- a/drivers/i2c/busses/i2c-cpm.c +++ b/drivers/i2c/busses/i2c-cpm.c @@ -447,7 +447,7 @@ static int cpm_i2c_setup(struct cpm_i2c *cpm) init_waitqueue_head(&cpm->i2c_wait); - cpm->irq = of_irq_to_resource(ofdev->dev.of_node, 0, NULL); + cpm->irq = irq_of_parse_and_map(ofdev->dev.of_node, 0); if (!cpm->irq) return -EINVAL; diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c index 4b7662a..36f7b95 100644 --- a/drivers/input/serio/xilinx_ps2.c +++ b/drivers/input/serio/xilinx_ps2.c @@ -235,12 +235,12 @@ static void sxps2_close(struct serio *pserio) */ static int xps2_of_probe(struct platform_device *ofdev) { - struct resource r_irq; /* Interrupt resources */ struct resource r_mem; /* IO mem resources */ struct xps2data *drvdata; struct serio *serio; struct device *dev = &ofdev->dev; resource_size_t remap_size, phys_addr; + unsigned int irq; int error; dev_info(dev, "Device Tree Probing \'%s\'\n", @@ -254,7 +254,8 @@ static int xps2_of_probe(struct platform_device *ofdev) } /* Get IRQ for the device */ - if (!of_irq_to_resource(ofdev->dev.of_node, 0, &r_irq)) { + irq = irq_of_parse_and_map(ofdev->dev.of_node, 0); + if (!irq) { dev_err(dev, "no IRQ found\n"); return -ENODEV; } @@ -267,7 +268,7 @@ static int xps2_of_probe(struct platform_device *ofdev) } spin_lock_init(&drvdata->lock); - drvdata->irq = r_irq.start; + drvdata->irq = irq; drvdata->serio = serio; drvdata->dev = dev; diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c index 9e16014..d087852 100644 --- a/drivers/net/ethernet/arc/emac_main.c +++ b/drivers/net/ethernet/arc/emac_main.c @@ -628,12 +628,12 @@ static const struct net_device_ops arc_emac_netdev_ops = { static int arc_emac_probe(struct platform_device *pdev) { - struct resource res_regs, res_irq; + struct resource res_regs; struct device_node *phy_node; struct arc_emac_priv *priv; struct net_device *ndev; const char *mac_addr; - unsigned int id, clock_frequency; + unsigned int id, clock_frequency, irq; int err; if (!pdev->dev.of_node) @@ -661,8 +661,8 @@ static int arc_emac_probe(struct platform_device *pdev) } /* Get IRQ from device tree */ - err = of_irq_to_resource(pdev->dev.of_node, 0, &res_irq); - if (!err) { + irq = irq_of_parse_and_map(pdev->dev.of_node, 0); + if (!irq) { dev_err(&pdev->dev, "failed to retrieve value from device tree\n"); return -ENODEV; } @@ -711,7 +711,7 @@ static int arc_emac_probe(struct platform_device *pdev) goto out; } - ndev->irq = res_irq.start; + ndev->irq = irq; dev_info(&pdev->dev, "IRQ is %d\n", ndev->irq); /* Register interrupt handler for device */ diff --git a/drivers/net/ethernet/freescale/fs_enet/mac-fcc.c b/drivers/net/ethernet/freescale/fs_enet/mac-fcc.c index 7583a95..10f781d 100644 --- a/drivers/net/ethernet/freescale/fs_enet/mac-fcc.c +++ b/drivers/net/ethernet/freescale/fs_enet/mac-fcc.c @@ -88,7 +88,7 @@ static int do_pd_setup(struct fs_enet_private *fep) struct fs_platform_info *fpi = fep->fpi; int ret = -EINVAL; - fep->interrupt = of_irq_to_resource(ofdev->dev.of_node, 0, NULL); + fep->interrupt = irq_of_parse_and_map(ofdev->dev.of_node, 0); if (fep->interrupt == NO_IRQ) goto out; diff --git a/drivers/net/ethernet/freescale/fs_enet/mac-fec.c b/drivers/net/ethernet/freescale/fs_enet/mac-fec.c index 9ae6cdb..53a0c23b 100644 --- a/drivers/net/ethernet/freescale/fs_enet/mac-fec.c +++ b/drivers/net/ethernet/freescale/fs_enet/mac-fec.c @@ -98,7 +98,7 @@ static int do_pd_setup(struct fs_enet_private *fep) { struct platform_device *ofdev = to_platform_device(fep->dev); - fep->interrupt = of_irq_to_resource(ofdev->dev.of_node, 0, NULL); + fep->interrupt = irq_of_parse_and_map(ofdev->dev.of_node, 0); if (fep->interrupt == NO_IRQ) return -EINVAL; diff --git a/drivers/net/ethernet/freescale/fs_enet/mac-scc.c b/drivers/net/ethernet/freescale/fs_enet/mac-scc.c index 22a02a7..631f098 100644 --- a/drivers/net/ethernet/freescale/fs_enet/mac-scc.c +++ b/drivers/net/ethernet/freescale/fs_enet/mac-scc.c @@ -98,7 +98,7 @@ static int do_pd_setup(struct fs_enet_private *fep) { struct platform_device *ofdev = to_platform_device(fep->dev); - fep->interrupt = of_irq_to_resource(ofdev->dev.of_node, 0, NULL); + fep->interrupt = irq_of_parse_and_map(ofdev->dev.of_node, 0); if (fep->interrupt == NO_IRQ) return -EINVAL; diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c index b8f1103..3197d55 100644 --- a/drivers/spi/spi-fsl-espi.c +++ b/drivers/spi/spi-fsl-espi.c @@ -687,7 +687,7 @@ static int of_fsl_espi_probe(struct platform_device *ofdev) struct device_node *np = ofdev->dev.of_node; struct spi_master *master; struct resource mem; - struct resource irq; + unsigned int irq; int ret = -ENOMEM; ret = of_mpc8xxx_spi_probe(ofdev); @@ -702,13 +702,13 @@ static int of_fsl_espi_probe(struct platform_device *ofdev) if (ret) goto err; - ret = of_irq_to_resource(np, 0, &irq); + irq = irq_of_parse_and_map(np, 0); if (!ret) { ret = -EINVAL; goto err; } - master = fsl_espi_probe(dev, &mem, irq.start); + master = fsl_espi_probe(dev, &mem, irq); if (IS_ERR(master)) { ret = PTR_ERR(master); goto err; diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c index 1a535f7..6957f44 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c @@ -1207,7 +1207,7 @@ static int cpm_uart_init_port(struct device_node *np, pinfo->port.fifosize = pinfo->tx_nrfifos * pinfo->tx_fifosize; spin_lock_init(&pinfo->port.lock); - pinfo->port.irq = of_irq_to_resource(np, 0, NULL); + pinfo->port.irq = irq_of_parse_and_map(np, 0); if (pinfo->port.irq == NO_IRQ) { ret = -EINVAL; goto out_pram; -- cgit v1.1 From 16b84e5a505c790538e534ad8dfda9c288691e40 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 19 Sep 2013 16:44:55 -0500 Subject: of/irq: Create of_irq_parse_and_map_pci() to consolidate arch code. Several architectures open code effectively the same code block for finding and mapping PCI irqs. This patch consolidates it down to a single function. Signed-off-by: Grant Likely Acked-by: Michal Simek Cc: Russell King Cc: Ralf Baechle Cc: Benjamin Herrenschmidt --- drivers/of/of_pci_irq.c | 25 +++++++++++++++++++++++++ drivers/pci/host/pci-mvebu.c | 14 +------------- 2 files changed, 26 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/of/of_pci_irq.c b/drivers/of/of_pci_irq.c index 303afeb..8e92acd 100644 --- a/drivers/of/of_pci_irq.c +++ b/drivers/of/of_pci_irq.c @@ -94,3 +94,28 @@ int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq return of_irq_parse_raw(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); + diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c index 3a8d01e..07ddb3a 100644 --- a/drivers/pci/host/pci-mvebu.c +++ b/drivers/pci/host/pci-mvebu.c @@ -645,18 +645,6 @@ static int __init mvebu_pcie_setup(int nr, struct pci_sys_data *sys) return 1; } -static int __init mvebu_pcie_map_irq(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) - return ret; - - return irq_create_of_mapping(&oirq); -} - static struct pci_bus *mvebu_pcie_scan_bus(int nr, struct pci_sys_data *sys) { struct mvebu_pcie *pcie = sys_to_pcie(sys); @@ -705,7 +693,7 @@ static void __init mvebu_pcie_enable(struct mvebu_pcie *pcie) hw.private_data = (void **)&pcie; hw.setup = mvebu_pcie_setup; hw.scan = mvebu_pcie_scan_bus; - hw.map_irq = mvebu_pcie_map_irq; + hw.map_irq = of_irq_parse_and_map_pci; hw.ops = &mvebu_pcie_ops; hw.align_resource = mvebu_pcie_align_resource; -- cgit v1.1 From 79d9701559a9f3e9b2021fbd292f5e70ad75f686 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 19 Sep 2013 16:47:37 -0500 Subject: of/irq: create interrupts-extended property The standard interrupts property in device tree can only handle interrupts coming from a single interrupt parent. If a device is wired to multiple interrupt controllers, then it needs to be attached to a node with an interrupt-map property to demux the interrupt specifiers which is confusing. It would be a lot easier if there was a form of the interrupts property that allows for a separate interrupt phandle for each interrupt specifier. This patch does exactly that by creating a new interrupts-extended property which reuses the phandle+arguments pattern used by GPIOs and other core bindings. Signed-off-by: Grant Likely Acked-by: Tony Lindgren Acked-by: Kumar Gala [grant.likely: removed versatile platform hunks into separate patch] Cc: Rob Herring --- drivers/of/irq.c | 16 ++++++++---- drivers/of/selftest.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 7c4ff12..8cc62b4 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -292,17 +292,23 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar 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); + /* Get the interrupts property */ intspec = of_get_property(device, "interrupts", &intlen); - if (intspec == NULL) - return -EINVAL; + 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); + } 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) diff --git a/drivers/of/selftest.c b/drivers/of/selftest.c index 9c80f0b..e21012b 100644 --- a/drivers/of/selftest.c +++ b/drivers/of/selftest.c @@ -231,6 +231,75 @@ static void __init of_selftest_parse_interrupts(void) 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; @@ -246,6 +315,7 @@ static int __init of_selftest(void) 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); return 0; -- cgit v1.1 From 0589342c27944e50ebd7a54f5215002b6598b748 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 29 Oct 2013 23:36:46 -0500 Subject: of: set dma_mask to point to coherent_dma_mask Platform devices created by DT code don't initialize dma_mask pointer to anything. Set it to coherent_dma_mask by default if the architecture code has not set it. Signed-off-by: Rob Herring --- drivers/of/platform.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 9b439ac..c005495 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -216,6 +216,8 @@ 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; -- cgit v1.1 From 78119fd1068cc068f6112a57a5f6de0e5b20245a Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 1 Nov 2013 10:50:50 -0700 Subject: of/irq: Fix bug in interrupt parsing refactor. Commit 2361613206e6, "of/irq: Refactor interrupt-map parsing" introduced a bug. The irq parsing will fail for some nodes that don't have a reg property. It is fixed by deferring the check for reg until it is actually needed. Also adjust the testcase data to catch the bug. Signed-off-by: Grant Likely Tested-by: Stephen Warren Tested-by: Ming Lei Tested-by: Stephen Warren Cc: Rob Herring --- drivers/of/irq.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 8cc62b4..52dba6a 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -147,18 +147,9 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) pr_debug(" -> addrsize=%d\n", addrsize); - /* 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"); - return -EINVAL; - } - /* Precalculate the match array - this simplifies match loop */ for (i = 0; i < addrsize; i++) - initial_match_array[i] = addr[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]); @@ -174,6 +165,15 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) 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 */ -- cgit v1.1 From 355e62f5ad12b005c862838156262eb2df2f8dff Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Sat, 2 Nov 2013 00:11:02 -0700 Subject: of/irq: Fix potential buffer overflow Commit 2361613206e6, "of/irq: Refactor interrupt-map parsing" introduced a potential buffer overflow bug because it doesn't do sufficient range checking on the input data. This patch adds the appropriate checking and buffer size adjustments. If the bounds are out of range then warn loudly. MAX_PHANDLE_ARGS should be sufficient. If it is not then the value can be increased. Signed-off-by: Grant Likely Cc: Rob Herring --- drivers/of/irq.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 52dba6a..d385bb8 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -95,9 +95,9 @@ struct device_node *of_irq_find_parent(struct device_node *child) int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) { struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL; - __be32 initial_match_array[8]; + __be32 initial_match_array[MAX_PHANDLE_ARGS]; const __be32 *match_array = initial_match_array; - const __be32 *tmp, *imap, *imask, dummy_imask[] = { ~0, ~0, ~0, ~0, ~0 }; + const __be32 *tmp, *imap, *imask, dummy_imask[] = { [0 ... MAX_PHANDLE_ARGS] = ~0 }; u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0; int imaplen, match, i; @@ -147,6 +147,10 @@ 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; @@ -229,6 +233,8 @@ 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; -- cgit v1.1 From 74dac2ed699cbe1dee0e4e7891619d53a5f2632f Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Tue, 5 Nov 2013 16:21:18 +0100 Subject: of: irq: Fix interrupt-map entry matching This patch fixes interrupt-map entry matching code to properly match all specifier cells with interrupt map entries. Signed-off-by: Tomasz Figa Tested-by: Sachin Kamat Signed-off-by: Rob Herring --- drivers/of/irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/of/irq.c b/drivers/of/irq.c index d385bb8..786b0b4 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -199,7 +199,7 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) /* Compare specifiers */ match = 1; for (i = 0; i < (addrsize + intsize); i++, imaplen--) - match = !((match_array[i] ^ *imap++) & imask[i]); + match &= !((match_array[i] ^ *imap++) & imask[i]); pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen); -- cgit v1.1 From f5ae18ece391c3bbf03bb1edc5fdcf23dc8b7e54 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 7 Nov 2013 11:54:27 -0600 Subject: dt: disable self-tests for !OF_IRQ Fix OF selftest compile on sparc which does not enable OF_IRQ. drivers/of/selftest.c:177: undefined reference to `of_irq_parse_one' drivers/of/selftest.c:197: undefined reference to `of_irq_parse_one' drivers/of/selftest.c:248: undefined reference to `of_irq_parse_one' Signed-off-by: Rob Herring Acked-by: Grant Likely --- drivers/of/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index 9d2009a..9b28f8b 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -17,6 +17,7 @@ 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 -- cgit v1.1 From c11eede69b6ad0ac44ebc1e021a8d2699c5f1f8f Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Sun, 10 Nov 2013 23:19:08 -0600 Subject: powerpc: add missing explicit OF includes for ppc Commit b5b4bb3f6a11f9 (of: only include prom.h on sparc) removed implicit includes of of_*.h headers by powerpc's prom.h. Some components were missed in initial clean-up patch, so add the necessary includes to fix powerpc builds. Signed-off-by: Rob Herring Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Tejun Heo Cc: Matt Mackall Cc: Herbert Xu Cc: "David S. Miller" Cc: Vinod Koul Cc: Dan Williams Cc: linuxppc-dev@lists.ozlabs.org Cc: linux-ide@vger.kernel.org Cc: linux-crypto@vger.kernel.org --- drivers/ata/sata_dwc_460ex.c | 2 ++ drivers/char/hw_random/ppc4xx-rng.c | 1 + drivers/clk/clk-ppc-corenet.c | 1 + drivers/crypto/amcc/crypto4xx_core.c | 3 +++ drivers/dma/ppc4xx/adma.c | 2 ++ drivers/mtd/nand/socrates_nand.c | 1 + drivers/pcmcia/m8xx_pcmcia.c | 2 ++ drivers/spi/spi-ppc4xx.c | 2 ++ drivers/watchdog/pika_wdt.c | 1 + 9 files changed, 15 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c index 2e39173..523524b 100644 --- a/drivers/ata/sata_dwc_460ex.c +++ b/drivers/ata/sata_dwc_460ex.c @@ -31,6 +31,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/drivers/char/hw_random/ppc4xx-rng.c b/drivers/char/hw_random/ppc4xx-rng.c index 732c330..521f76b 100644 --- a/drivers/char/hw_random/ppc4xx-rng.c +++ b/drivers/char/hw_random/ppc4xx-rng.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include diff --git a/drivers/clk/clk-ppc-corenet.c b/drivers/clk/clk-ppc-corenet.c index e9587073..c4f76ed 100644 --- a/drivers/clk/clk-ppc-corenet.c +++ b/drivers/clk/clk-ppc-corenet.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/crypto/amcc/crypto4xx_core.c b/drivers/crypto/amcc/crypto4xx_core.c index f88e3d8..efaf630 100644 --- a/drivers/crypto/amcc/crypto4xx_core.c +++ b/drivers/crypto/amcc/crypto4xx_core.c @@ -27,6 +27,9 @@ #include #include #include +#include +#include +#include #include #include #include diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c index 370ff82..e24b5ef 100644 --- a/drivers/dma/ppc4xx/adma.c +++ b/drivers/dma/ppc4xx/adma.c @@ -42,6 +42,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/drivers/mtd/nand/socrates_nand.c b/drivers/mtd/nand/socrates_nand.c index 09dde7d..49bd9155 100644 --- a/drivers/mtd/nand/socrates_nand.c +++ b/drivers/mtd/nand/socrates_nand.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c index 18c0d8d..182034d 100644 --- a/drivers/pcmcia/m8xx_pcmcia.c +++ b/drivers/pcmcia/m8xx_pcmcia.c @@ -48,7 +48,9 @@ #include #include #include +#include #include +#include #include #include diff --git a/drivers/spi/spi-ppc4xx.c b/drivers/spi/spi-ppc4xx.c index 0ee53c2..19d615b 100644 --- a/drivers/spi/spi-ppc4xx.c +++ b/drivers/spi/spi-ppc4xx.c @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/drivers/watchdog/pika_wdt.c b/drivers/watchdog/pika_wdt.c index 7d3d471..329bc60 100644 --- a/drivers/watchdog/pika_wdt.c +++ b/drivers/watchdog/pika_wdt.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #define DRV_NAME "PIKA-WDT" -- cgit v1.1