diff options
30 files changed, 929 insertions, 310 deletions
diff --git a/Documentation/devicetree/bindings/arm/omap/dsp.txt b/Documentation/devicetree/bindings/arm/omap/dsp.txt new file mode 100644 index 000000000000..d3830a32ce08 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/omap/dsp.txt | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | * TI - DSP (Digital Signal Processor) | ||
| 2 | |||
| 3 | TI DSP included in OMAP SoC | ||
| 4 | |||
| 5 | Required properties: | ||
| 6 | - compatible : Should be "ti,omap3-c64" for OMAP3 & 4 | ||
| 7 | - ti,hwmods: "dsp" | ||
| 8 | |||
| 9 | Examples: | ||
| 10 | |||
| 11 | dsp { | ||
| 12 | compatible = "ti,omap3-c64"; | ||
| 13 | ti,hwmods = "dsp"; | ||
| 14 | }; | ||
diff --git a/Documentation/devicetree/bindings/arm/omap/iva.txt b/Documentation/devicetree/bindings/arm/omap/iva.txt new file mode 100644 index 000000000000..6d6295171358 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/omap/iva.txt | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | * TI - IVA (Imaging and Video Accelerator) subsystem | ||
| 2 | |||
| 3 | The IVA contain various audio, video or imaging HW accelerator | ||
| 4 | depending of the version. | ||
| 5 | |||
| 6 | Required properties: | ||
| 7 | - compatible : Should be: | ||
| 8 | - "ti,ivahd" for OMAP4 | ||
| 9 | - "ti,iva2.2" for OMAP3 | ||
| 10 | - "ti,iva2.1" for OMAP2430 | ||
| 11 | - "ti,iva1" for OMAP2420 | ||
| 12 | - ti,hwmods: "iva" | ||
| 13 | |||
| 14 | Examples: | ||
| 15 | |||
| 16 | iva { | ||
| 17 | compatible = "ti,ivahd", "ti,iva"; | ||
| 18 | ti,hwmods = "iva"; | ||
| 19 | }; | ||
diff --git a/Documentation/devicetree/bindings/arm/omap/l3-noc.txt b/Documentation/devicetree/bindings/arm/omap/l3-noc.txt new file mode 100644 index 000000000000..6888a5efc860 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/omap/l3-noc.txt | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | * TI - L3 Network On Chip (NoC) | ||
| 2 | |||
| 3 | This version is an implementation of the generic NoC IP | ||
| 4 | provided by Arteris. | ||
| 5 | |||
| 6 | Required properties: | ||
| 7 | - compatible : Should be "ti,omap3-l3-smx" for OMAP3 family | ||
| 8 | Should be "ti,omap4-l3-noc" for OMAP4 family | ||
| 9 | - ti,hwmods: "l3_main_1", ... One hwmod for each noc domain. | ||
| 10 | |||
| 11 | Examples: | ||
| 12 | |||
| 13 | ocp { | ||
| 14 | compatible = "ti,omap4-l3-noc", "simple-bus"; | ||
| 15 | #address-cells = <1>; | ||
| 16 | #size-cells = <1>; | ||
| 17 | ranges; | ||
| 18 | ti,hwmods = "l3_main_1", "l3_main_2", "l3_main_3"; | ||
| 19 | }; | ||
diff --git a/Documentation/devicetree/bindings/arm/omap/mpu.txt b/Documentation/devicetree/bindings/arm/omap/mpu.txt new file mode 100644 index 000000000000..1a5a42ce21bb --- /dev/null +++ b/Documentation/devicetree/bindings/arm/omap/mpu.txt | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | * TI - MPU (Main Processor Unit) subsystem | ||
| 2 | |||
| 3 | The MPU subsystem contain one or several ARM cores | ||
| 4 | depending of the version. | ||
| 5 | The MPU contain CPUs, GIC, L2 cache and a local PRCM. | ||
| 6 | |||
| 7 | Required properties: | ||
| 8 | - compatible : Should be "ti,omap3-mpu" for OMAP3 | ||
| 9 | Should be "ti,omap4-mpu" for OMAP4 | ||
| 10 | - ti,hwmods: "mpu" | ||
| 11 | |||
| 12 | Examples: | ||
| 13 | |||
| 14 | - For an OMAP4 SMP system: | ||
| 15 | |||
| 16 | mpu { | ||
| 17 | compatible = "ti,omap4-mpu"; | ||
| 18 | ti,hwmods = "mpu"; | ||
| 19 | }; | ||
| 20 | |||
| 21 | |||
| 22 | - For an OMAP3 monocore system: | ||
| 23 | |||
| 24 | mpu { | ||
| 25 | compatible = "ti,omap3-mpu"; | ||
| 26 | ti,hwmods = "mpu"; | ||
| 27 | }; | ||
diff --git a/Documentation/devicetree/bindings/arm/omap/omap.txt b/Documentation/devicetree/bindings/arm/omap/omap.txt new file mode 100644 index 000000000000..dbdab40ed3a6 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/omap/omap.txt | |||
| @@ -0,0 +1,43 @@ | |||
| 1 | * Texas Instruments OMAP | ||
| 2 | |||
| 3 | OMAP is currently using a static file per SoC family to describe the | ||
| 4 | IPs present in the SoC. | ||
| 5 | On top of that an omap_device is created to extend the platform_device | ||
| 6 | capabilities and to allow binding with one or several hwmods. | ||
| 7 | The hwmods will contain all the information to build the device: | ||
| 8 | adresse range, irq lines, dma lines, interconnect, PRCM register, | ||
| 9 | clock domain, input clocks. | ||
| 10 | For the moment just point to the existing hwmod, the next step will be | ||
| 11 | to move data from hwmod to device-tree representation. | ||
| 12 | |||
| 13 | |||
| 14 | Required properties: | ||
| 15 | - compatible: Every devices present in OMAP SoC should be in the | ||
| 16 | form: "ti,XXX" | ||
| 17 | - ti,hwmods: list of hwmod names (ascii strings), that comes from the OMAP | ||
| 18 | HW documentation, attached to a device. Must contain at least | ||
| 19 | one hwmod. | ||
| 20 | |||
| 21 | Optional properties: | ||
| 22 | - ti,no_idle_on_suspend: When present, it prevents the PM to idle the module | ||
| 23 | during suspend. | ||
| 24 | |||
| 25 | |||
| 26 | Example: | ||
| 27 | |||
| 28 | spinlock@1 { | ||
| 29 | compatible = "ti,omap4-spinlock"; | ||
| 30 | ti,hwmods = "spinlock"; | ||
| 31 | }; | ||
| 32 | |||
| 33 | |||
| 34 | Boards: | ||
| 35 | |||
| 36 | - OMAP3 BeagleBoard : Low cost community board | ||
| 37 | compatible = "ti,omap3-beagle", "ti,omap3" | ||
| 38 | |||
| 39 | - OMAP4 SDP : Software Developement Board | ||
| 40 | compatible = "ti,omap4-sdp", "ti,omap4430" | ||
| 41 | |||
| 42 | - OMAP4 PandaBoard : Low cost community board | ||
| 43 | compatible = "ti,omap4-panda", "ti,omap4430" | ||
diff --git a/arch/arm/boot/dts/omap3-beagle.dts b/arch/arm/boot/dts/omap3-beagle.dts new file mode 100644 index 000000000000..9486be62bcdd --- /dev/null +++ b/arch/arm/boot/dts/omap3-beagle.dts | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | */ | ||
| 8 | /dts-v1/; | ||
| 9 | |||
| 10 | /include/ "omap3.dtsi" | ||
| 11 | |||
| 12 | / { | ||
| 13 | model = "TI OMAP3 BeagleBoard"; | ||
| 14 | compatible = "ti,omap3-beagle", "ti,omap3"; | ||
| 15 | |||
| 16 | /* | ||
| 17 | * Since the initial device tree board file does not create any | ||
| 18 | * devices (MMC, network...), the only way to boot is to provide a | ||
| 19 | * ramdisk. | ||
| 20 | */ | ||
| 21 | chosen { | ||
| 22 | bootargs = "root=/dev/ram0 rw console=ttyO2,115200n8 initrd=0x81600000,20M ramdisk_size=20480 no_console_suspend debug earlyprintk"; | ||
| 23 | }; | ||
| 24 | |||
| 25 | memory { | ||
| 26 | device_type = "memory"; | ||
| 27 | reg = <0x80000000 0x20000000>; /* 512 MB */ | ||
| 28 | }; | ||
| 29 | }; | ||
diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi new file mode 100644 index 000000000000..d202bb5ec7ef --- /dev/null +++ b/arch/arm/boot/dts/omap3.dtsi | |||
| @@ -0,0 +1,63 @@ | |||
| 1 | /* | ||
| 2 | * Device Tree Source for OMAP3 SoC | ||
| 3 | * | ||
| 4 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ | ||
| 5 | * | ||
| 6 | * This file is licensed under the terms of the GNU General Public License | ||
| 7 | * version 2. This program is licensed "as is" without any warranty of any | ||
| 8 | * kind, whether express or implied. | ||
| 9 | */ | ||
| 10 | |||
| 11 | /include/ "skeleton.dtsi" | ||
| 12 | |||
| 13 | / { | ||
| 14 | compatible = "ti,omap3430", "ti,omap3"; | ||
| 15 | |||
| 16 | cpus { | ||
| 17 | cpu@0 { | ||
| 18 | compatible = "arm,cortex-a8"; | ||
| 19 | }; | ||
| 20 | }; | ||
| 21 | |||
| 22 | /* | ||
| 23 | * The soc node represents the soc top level view. It is uses for IPs | ||
| 24 | * that are not memory mapped in the MPU view or for the MPU itself. | ||
| 25 | */ | ||
| 26 | soc { | ||
| 27 | compatible = "ti,omap-infra"; | ||
| 28 | mpu { | ||
| 29 | compatible = "ti,omap3-mpu"; | ||
| 30 | ti,hwmods = "mpu"; | ||
| 31 | }; | ||
| 32 | |||
| 33 | iva { | ||
| 34 | compatible = "ti,iva2.2"; | ||
| 35 | ti,hwmods = "iva"; | ||
| 36 | |||
| 37 | dsp { | ||
| 38 | compatible = "ti,omap3-c64"; | ||
| 39 | }; | ||
| 40 | }; | ||
| 41 | }; | ||
| 42 | |||
| 43 | /* | ||
| 44 | * XXX: Use a flat representation of the OMAP3 interconnect. | ||
| 45 | * The real OMAP interconnect network is quite complex. | ||
| 46 | * Since that will not bring real advantage to represent that in DT for | ||
| 47 | * the moment, just use a fake OCP bus entry to represent the whole bus | ||
| 48 | * hierarchy. | ||
| 49 | */ | ||
| 50 | ocp { | ||
| 51 | compatible = "simple-bus"; | ||
| 52 | #address-cells = <1>; | ||
| 53 | #size-cells = <1>; | ||
| 54 | ranges; | ||
| 55 | ti,hwmods = "l3_main"; | ||
| 56 | |||
| 57 | intc: interrupt-controller@1 { | ||
| 58 | compatible = "ti,omap3-intc"; | ||
| 59 | interrupt-controller; | ||
| 60 | #interrupt-cells = <1>; | ||
| 61 | }; | ||
| 62 | }; | ||
| 63 | }; | ||
diff --git a/arch/arm/boot/dts/omap4-panda.dts b/arch/arm/boot/dts/omap4-panda.dts new file mode 100644 index 000000000000..c7026578ce7d --- /dev/null +++ b/arch/arm/boot/dts/omap4-panda.dts | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | */ | ||
| 8 | /dts-v1/; | ||
| 9 | |||
| 10 | /include/ "omap4.dtsi" | ||
| 11 | |||
| 12 | / { | ||
| 13 | model = "TI OMAP4 PandaBoard"; | ||
| 14 | compatible = "ti,omap4-panda", "ti,omap4430", "ti,omap4"; | ||
| 15 | |||
| 16 | /* | ||
| 17 | * Since the initial device tree board file does not create any | ||
| 18 | * devices (MMC, network...), the only way to boot is to provide a | ||
| 19 | * ramdisk. | ||
| 20 | */ | ||
| 21 | chosen { | ||
| 22 | bootargs = "root=/dev/ram0 rw console=ttyO2,115200n8 initrd=0x81600000,20M ramdisk_size=20480 no_console_suspend debug"; | ||
| 23 | }; | ||
| 24 | |||
| 25 | memory { | ||
| 26 | device_type = "memory"; | ||
| 27 | reg = <0x80000000 0x40000000>; /* 1 GB */ | ||
| 28 | }; | ||
| 29 | }; | ||
diff --git a/arch/arm/boot/dts/omap4-sdp.dts b/arch/arm/boot/dts/omap4-sdp.dts new file mode 100644 index 000000000000..066e28c90328 --- /dev/null +++ b/arch/arm/boot/dts/omap4-sdp.dts | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | */ | ||
| 8 | /dts-v1/; | ||
| 9 | |||
| 10 | /include/ "omap4.dtsi" | ||
| 11 | |||
| 12 | / { | ||
| 13 | model = "TI OMAP4 SDP board"; | ||
| 14 | compatible = "ti,omap4-sdp", "ti,omap4430", "ti,omap4"; | ||
| 15 | |||
| 16 | /* | ||
| 17 | * Since the initial device tree board file does not create any | ||
| 18 | * devices (MMC, network...), the only way to boot is to provide a | ||
| 19 | * ramdisk. | ||
| 20 | */ | ||
| 21 | chosen { | ||
| 22 | bootargs = "root=/dev/ram0 rw console=ttyO2,115200n8 initrd=0x81600000,20M ramdisk_size=20480 no_console_suspend debug"; | ||
| 23 | }; | ||
| 24 | |||
| 25 | memory { | ||
| 26 | device_type = "memory"; | ||
| 27 | reg = <0x80000000 0x40000000>; /* 1 GB */ | ||
| 28 | }; | ||
| 29 | }; | ||
diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi new file mode 100644 index 000000000000..4c61c829043a --- /dev/null +++ b/arch/arm/boot/dts/omap4.dtsi | |||
| @@ -0,0 +1,103 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | * Carveout for multimedia usecases | ||
| 11 | * It should be the last 48MB of the first 512MB memory part | ||
| 12 | * In theory, it should not even exist. That zone should be reserved | ||
| 13 | * dynamically during the .reserve callback. | ||
| 14 | */ | ||
| 15 | /memreserve/ 0x9d000000 0x03000000; | ||
| 16 | |||
| 17 | /include/ "skeleton.dtsi" | ||
| 18 | |||
| 19 | / { | ||
| 20 | compatible = "ti,omap4430", "ti,omap4"; | ||
| 21 | interrupt-parent = <&gic>; | ||
| 22 | |||
| 23 | aliases { | ||
| 24 | }; | ||
| 25 | |||
| 26 | cpus { | ||
| 27 | cpu@0 { | ||
| 28 | compatible = "arm,cortex-a9"; | ||
| 29 | }; | ||
| 30 | cpu@1 { | ||
| 31 | compatible = "arm,cortex-a9"; | ||
| 32 | }; | ||
| 33 | }; | ||
| 34 | |||
| 35 | /* | ||
| 36 | * The soc node represents the soc top level view. It is uses for IPs | ||
| 37 | * that are not memory mapped in the MPU view or for the MPU itself. | ||
| 38 | */ | ||
| 39 | soc { | ||
| 40 | compatible = "ti,omap-infra"; | ||
| 41 | mpu { | ||
| 42 | compatible = "ti,omap4-mpu"; | ||
| 43 | ti,hwmods = "mpu"; | ||
| 44 | }; | ||
| 45 | |||
| 46 | dsp { | ||
| 47 | compatible = "ti,omap3-c64"; | ||
| 48 | ti,hwmods = "dsp"; | ||
| 49 | }; | ||
| 50 | |||
| 51 | iva { | ||
| 52 | compatible = "ti,ivahd"; | ||
| 53 | ti,hwmods = "iva"; | ||
| 54 | }; | ||
| 55 | }; | ||
| 56 | |||
| 57 | /* | ||
| 58 | * XXX: Use a flat representation of the OMAP4 interconnect. | ||
| 59 | * The real OMAP interconnect network is quite complex. | ||
| 60 | * | ||
| 61 | * MPU -+-- MPU_PRIVATE - GIC, L2 | ||
| 62 | * | | ||
| 63 | * +----------------+----------+ | ||
| 64 | * | | | | ||
| 65 | * + +- EMIF - DDR | | ||
| 66 | * | | | | ||
| 67 | * | + +--------+ | ||
| 68 | * | | | | ||
| 69 | * | +- L4_ABE - AESS, MCBSP, TIMERs... | ||
| 70 | * | | | ||
| 71 | * +- L3_MAIN --+- L4_CORE - IPs... | ||
| 72 | * | | ||
| 73 | * +- L4_PER - IPs... | ||
| 74 | * | | ||
| 75 | * +- L4_CFG -+- L4_WKUP - IPs... | ||
| 76 | * | | | ||
| 77 | * | +- IPs... | ||
| 78 | * +- IPU ----+ | ||
| 79 | * | | | ||
| 80 | * +- DSP ----+ | ||
| 81 | * | | | ||
| 82 | * +- DSS ----+ | ||
| 83 | * | ||
| 84 | * Since that will not bring real advantage to represent that in DT for | ||
| 85 | * the moment, just use a fake OCP bus entry to represent the whole bus | ||
| 86 | * hierarchy. | ||
| 87 | */ | ||
| 88 | ocp { | ||
| 89 | compatible = "ti,omap4-l3-noc", "simple-bus"; | ||
| 90 | #address-cells = <1>; | ||
| 91 | #size-cells = <1>; | ||
| 92 | ranges; | ||
| 93 | ti,hwmods = "l3_main_1", "l3_main_2", "l3_main_3"; | ||
| 94 | |||
| 95 | gic: interrupt-controller@48241000 { | ||
| 96 | compatible = "arm,cortex-a9-gic"; | ||
| 97 | interrupt-controller; | ||
| 98 | #interrupt-cells = <1>; | ||
| 99 | reg = <0x48241000 0x1000>, | ||
| 100 | <0x48240100 0x0100>; | ||
| 101 | }; | ||
| 102 | }; | ||
| 103 | }; | ||
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 57b66d590c52..e0a318df95bc 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig | |||
| @@ -106,9 +106,13 @@ comment "OMAP Board Type" | |||
| 106 | depends on ARCH_OMAP2PLUS | 106 | depends on ARCH_OMAP2PLUS |
| 107 | 107 | ||
| 108 | config MACH_OMAP_GENERIC | 108 | config MACH_OMAP_GENERIC |
| 109 | bool "Generic OMAP board" | 109 | bool "Generic OMAP2+ board" |
| 110 | depends on ARCH_OMAP2 | 110 | depends on ARCH_OMAP2PLUS |
| 111 | select USE_OF | ||
| 111 | default y | 112 | default y |
| 113 | help | ||
| 114 | Support for generic TI OMAP2+ boards using Flattened Device Tree. | ||
| 115 | More information at Documentation/devicetree | ||
| 112 | 116 | ||
| 113 | config MACH_OMAP2_TUSB6010 | 117 | config MACH_OMAP2_TUSB6010 |
| 114 | bool | 118 | bool |
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index 5223898f50e4..d9ccb9d98e15 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c | |||
| @@ -1,76 +1,154 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * linux/arch/arm/mach-omap2/board-generic.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2005 Nokia Corporation | 2 | * Copyright (C) 2005 Nokia Corporation |
| 5 | * Author: Paul Mundt <paul.mundt@nokia.com> | 3 | * Author: Paul Mundt <paul.mundt@nokia.com> |
| 6 | * | 4 | * |
| 7 | * Modified from mach-omap/omap1/board-generic.c | 5 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ |
| 8 | * | 6 | * |
| 9 | * Code for generic OMAP2 board. Should work on many OMAP2 systems where | 7 | * Modified from the original mach-omap/omap2/board-generic.c did by Paul |
| 10 | * the bootloader passes the board-specific data to the kernel. | 8 | * to support the OMAP2+ device tree boards with an unique board file. |
| 11 | * Do not put any board specific code to this file; create a new machine | ||
| 12 | * type if you need custom low-level initializations. | ||
| 13 | * | 9 | * |
| 14 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
| 15 | * it under the terms of the GNU General Public License version 2 as | 11 | * it under the terms of the GNU General Public License version 2 as |
| 16 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
| 17 | */ | 13 | */ |
| 18 | 14 | ||
| 19 | #include <linux/kernel.h> | 15 | #include <linux/io.h> |
| 20 | #include <linux/init.h> | 16 | #include <linux/of_platform.h> |
| 21 | #include <linux/device.h> | 17 | #include <linux/irqdomain.h> |
| 18 | #include <linux/i2c/twl.h> | ||
| 22 | 19 | ||
| 23 | #include <mach/hardware.h> | 20 | #include <mach/hardware.h> |
| 24 | #include <asm/mach-types.h> | ||
| 25 | #include <asm/mach/arch.h> | 21 | #include <asm/mach/arch.h> |
| 26 | #include <asm/mach/map.h> | ||
| 27 | 22 | ||
| 28 | #include <mach/gpio.h> | ||
| 29 | #include <plat/usb.h> | ||
| 30 | #include <plat/board.h> | 23 | #include <plat/board.h> |
| 31 | #include <plat/common.h> | 24 | #include <plat/common.h> |
| 25 | #include <mach/omap4-common.h> | ||
| 26 | #include "common-board-devices.h" | ||
| 27 | |||
| 28 | /* | ||
| 29 | * XXX: Still needed to boot until the i2c & twl driver is adapted to | ||
| 30 | * device-tree | ||
| 31 | */ | ||
| 32 | static struct twl4030_platform_data sdp4430_twldata = { | ||
| 33 | .irq_base = TWL6030_IRQ_BASE, | ||
| 34 | .irq_end = TWL6030_IRQ_END, | ||
| 35 | }; | ||
| 32 | 36 | ||
| 33 | static struct omap_board_config_kernel generic_config[] = { | 37 | static void __init omap4_i2c_init(void) |
| 38 | { | ||
| 39 | omap4_pmic_init("twl6030", &sdp4430_twldata); | ||
| 40 | } | ||
| 41 | |||
| 42 | static struct twl4030_platform_data beagle_twldata = { | ||
| 43 | .irq_base = TWL4030_IRQ_BASE, | ||
| 44 | .irq_end = TWL4030_IRQ_END, | ||
| 34 | }; | 45 | }; |
| 35 | 46 | ||
| 36 | static void __init omap_generic_init_early(void) | 47 | static void __init omap3_i2c_init(void) |
| 37 | { | 48 | { |
| 38 | omap2_init_common_infrastructure(); | 49 | omap3_pmic_init("twl4030", &beagle_twldata); |
| 39 | } | 50 | } |
| 40 | 51 | ||
| 52 | static struct of_device_id omap_dt_match_table[] __initdata = { | ||
| 53 | { .compatible = "simple-bus", }, | ||
| 54 | { .compatible = "ti,omap-infra", }, | ||
| 55 | { } | ||
| 56 | }; | ||
| 57 | |||
| 58 | static struct of_device_id intc_match[] __initdata = { | ||
| 59 | { .compatible = "ti,omap3-intc", }, | ||
| 60 | { .compatible = "arm,cortex-a9-gic", }, | ||
| 61 | { } | ||
| 62 | }; | ||
| 63 | |||
| 41 | static void __init omap_generic_init(void) | 64 | static void __init omap_generic_init(void) |
| 42 | { | 65 | { |
| 66 | struct device_node *node = of_find_matching_node(NULL, intc_match); | ||
| 67 | if (node) | ||
| 68 | irq_domain_add_simple(node, 0); | ||
| 69 | |||
| 43 | omap_serial_init(); | 70 | omap_serial_init(); |
| 44 | omap_sdrc_init(NULL, NULL); | 71 | omap_sdrc_init(NULL, NULL); |
| 45 | omap_board_config = generic_config; | 72 | |
| 46 | omap_board_config_size = ARRAY_SIZE(generic_config); | 73 | of_platform_populate(NULL, omap_dt_match_table, NULL, NULL); |
| 47 | } | 74 | } |
| 48 | 75 | ||
| 49 | static void __init omap_generic_map_io(void) | 76 | static void __init omap4_init(void) |
| 50 | { | 77 | { |
| 51 | if (cpu_is_omap242x()) { | 78 | omap4_i2c_init(); |
| 52 | omap2_set_globals_242x(); | 79 | omap_generic_init(); |
| 53 | omap242x_map_common_io(); | ||
| 54 | } else if (cpu_is_omap243x()) { | ||
| 55 | omap2_set_globals_243x(); | ||
| 56 | omap243x_map_common_io(); | ||
| 57 | } else if (cpu_is_omap34xx()) { | ||
| 58 | omap2_set_globals_3xxx(); | ||
| 59 | omap34xx_map_common_io(); | ||
| 60 | } else if (cpu_is_omap44xx()) { | ||
| 61 | omap2_set_globals_443x(); | ||
| 62 | omap44xx_map_common_io(); | ||
| 63 | } | ||
| 64 | } | 80 | } |
| 65 | 81 | ||
| 66 | /* XXX This machine entry name should be updated */ | 82 | static void __init omap3_init(void) |
| 67 | MACHINE_START(OMAP_GENERIC, "Generic OMAP24xx") | 83 | { |
| 68 | /* Maintainer: Paul Mundt <paul.mundt@nokia.com> */ | 84 | omap3_i2c_init(); |
| 69 | .boot_params = 0x80000100, | 85 | omap_generic_init(); |
| 86 | } | ||
| 87 | |||
| 88 | #if defined(CONFIG_SOC_OMAP2420) | ||
| 89 | static const char *omap242x_boards_compat[] __initdata = { | ||
| 90 | "ti,omap2420", | ||
| 91 | NULL, | ||
| 92 | }; | ||
| 93 | |||
| 94 | DT_MACHINE_START(OMAP242X_DT, "Generic OMAP2420 (Flattened Device Tree)") | ||
| 70 | .reserve = omap_reserve, | 95 | .reserve = omap_reserve, |
| 71 | .map_io = omap_generic_map_io, | 96 | .map_io = omap242x_map_io, |
| 72 | .init_early = omap_generic_init_early, | 97 | .init_early = omap2420_init_early, |
| 73 | .init_irq = omap2_init_irq, | 98 | .init_irq = omap2_init_irq, |
| 74 | .init_machine = omap_generic_init, | 99 | .init_machine = omap_generic_init, |
| 75 | .timer = &omap2_timer, | 100 | .timer = &omap2_timer, |
| 101 | .dt_compat = omap242x_boards_compat, | ||
| 102 | MACHINE_END | ||
| 103 | #endif | ||
| 104 | |||
| 105 | #if defined(CONFIG_SOC_OMAP2430) | ||
| 106 | static const char *omap243x_boards_compat[] __initdata = { | ||
| 107 | "ti,omap2430", | ||
| 108 | NULL, | ||
| 109 | }; | ||
| 110 | |||
| 111 | DT_MACHINE_START(OMAP243X_DT, "Generic OMAP2430 (Flattened Device Tree)") | ||
| 112 | .reserve = omap_reserve, | ||
| 113 | .map_io = omap243x_map_io, | ||
| 114 | .init_early = omap2430_init_early, | ||
| 115 | .init_irq = omap2_init_irq, | ||
| 116 | .init_machine = omap_generic_init, | ||
| 117 | .timer = &omap2_timer, | ||
| 118 | .dt_compat = omap243x_boards_compat, | ||
| 119 | MACHINE_END | ||
| 120 | #endif | ||
| 121 | |||
| 122 | #if defined(CONFIG_ARCH_OMAP3) | ||
| 123 | static const char *omap3_boards_compat[] __initdata = { | ||
| 124 | "ti,omap3", | ||
| 125 | NULL, | ||
| 126 | }; | ||
| 127 | |||
| 128 | DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)") | ||
| 129 | .reserve = omap_reserve, | ||
| 130 | .map_io = omap3_map_io, | ||
| 131 | .init_early = omap3430_init_early, | ||
| 132 | .init_irq = omap3_init_irq, | ||
| 133 | .init_machine = omap3_init, | ||
| 134 | .timer = &omap3_timer, | ||
| 135 | .dt_compat = omap3_boards_compat, | ||
| 136 | MACHINE_END | ||
| 137 | #endif | ||
| 138 | |||
| 139 | #if defined(CONFIG_ARCH_OMAP4) | ||
| 140 | static const char *omap4_boards_compat[] __initdata = { | ||
| 141 | "ti,omap4", | ||
| 142 | NULL, | ||
| 143 | }; | ||
| 144 | |||
| 145 | DT_MACHINE_START(OMAP4_DT, "Generic OMAP4 (Flattened Device Tree)") | ||
| 146 | .reserve = omap_reserve, | ||
| 147 | .map_io = omap4_map_io, | ||
| 148 | .init_early = omap4430_init_early, | ||
| 149 | .init_irq = gic_init_irq, | ||
| 150 | .init_machine = omap4_init, | ||
| 151 | .timer = &omap4_timer, | ||
| 152 | .dt_compat = omap4_boards_compat, | ||
| 76 | MACHINE_END | 153 | MACHINE_END |
| 154 | #endif | ||
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index e085371eb494..4a5d75f11610 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c | |||
| @@ -486,8 +486,8 @@ static void __init beagle_opp_init(void) | |||
| 486 | if (cpu_is_omap3630()) { | 486 | if (cpu_is_omap3630()) { |
| 487 | struct device *mpu_dev, *iva_dev; | 487 | struct device *mpu_dev, *iva_dev; |
| 488 | 488 | ||
| 489 | mpu_dev = omap2_get_mpuss_device(); | 489 | mpu_dev = omap_device_get_by_hwmod_name("mpu"); |
| 490 | iva_dev = omap2_get_iva_device(); | 490 | iva_dev = omap_device_get_by_hwmod_name("iva"); |
| 491 | 491 | ||
| 492 | if (!mpu_dev || !iva_dev) { | 492 | if (!mpu_dev || !iva_dev) { |
| 493 | pr_err("%s: Aiee.. no mpu/dsp devices? %p %p\n", | 493 | pr_err("%s: Aiee.. no mpu/dsp devices? %p %p\n", |
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 10adf66be7ba..0f8e0eb18166 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <linux/clk.h> | 16 | #include <linux/clk.h> |
| 17 | #include <linux/err.h> | 17 | #include <linux/err.h> |
| 18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
| 19 | #include <linux/of.h> | ||
| 19 | 20 | ||
| 20 | #include <mach/hardware.h> | 21 | #include <mach/hardware.h> |
| 21 | #include <mach/irqs.h> | 22 | #include <mach/irqs.h> |
| @@ -77,6 +78,10 @@ static int __init omap4_l3_init(void) | |||
| 77 | struct platform_device *pdev; | 78 | struct platform_device *pdev; |
| 78 | char oh_name[L3_MODULES_MAX_LEN]; | 79 | char oh_name[L3_MODULES_MAX_LEN]; |
| 79 | 80 | ||
| 81 | /* If dtb is there, the devices will be created dynamically */ | ||
| 82 | if (of_have_populated_dt()) | ||
| 83 | return -ENODEV; | ||
| 84 | |||
| 80 | /* | 85 | /* |
| 81 | * To avoid code running on other OMAPs in | 86 | * To avoid code running on other OMAPs in |
| 82 | * multi-omap builds | 87 | * multi-omap builds |
| @@ -221,14 +226,6 @@ static inline void omap_init_camera(void) | |||
| 221 | #endif | 226 | #endif |
| 222 | } | 227 | } |
| 223 | 228 | ||
| 224 | struct omap_device_pm_latency omap_keyboard_latency[] = { | ||
| 225 | { | ||
| 226 | .deactivate_func = omap_device_idle_hwmods, | ||
| 227 | .activate_func = omap_device_enable_hwmods, | ||
| 228 | .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, | ||
| 229 | }, | ||
| 230 | }; | ||
| 231 | |||
| 232 | int __init omap4_keyboard_init(struct omap4_keypad_platform_data | 229 | int __init omap4_keyboard_init(struct omap4_keypad_platform_data |
| 233 | *sdp4430_keypad_data, struct omap_board_data *bdata) | 230 | *sdp4430_keypad_data, struct omap_board_data *bdata) |
| 234 | { | 231 | { |
| @@ -248,9 +245,7 @@ int __init omap4_keyboard_init(struct omap4_keypad_platform_data | |||
| 248 | keypad_data = sdp4430_keypad_data; | 245 | keypad_data = sdp4430_keypad_data; |
| 249 | 246 | ||
| 250 | pdev = omap_device_build(name, id, oh, keypad_data, | 247 | pdev = omap_device_build(name, id, oh, keypad_data, |
| 251 | sizeof(struct omap4_keypad_platform_data), | 248 | sizeof(struct omap4_keypad_platform_data), NULL, 0, 0); |
| 252 | omap_keyboard_latency, | ||
| 253 | ARRAY_SIZE(omap_keyboard_latency), 0); | ||
| 254 | 249 | ||
| 255 | if (IS_ERR(pdev)) { | 250 | if (IS_ERR(pdev)) { |
| 256 | WARN(1, "Can't build omap_device for %s:%s.\n", | 251 | WARN(1, "Can't build omap_device for %s:%s.\n", |
| @@ -263,14 +258,6 @@ int __init omap4_keyboard_init(struct omap4_keypad_platform_data | |||
| 263 | } | 258 | } |
| 264 | 259 | ||
| 265 | #if defined(CONFIG_OMAP_MBOX_FWK) || defined(CONFIG_OMAP_MBOX_FWK_MODULE) | 260 | #if defined(CONFIG_OMAP_MBOX_FWK) || defined(CONFIG_OMAP_MBOX_FWK_MODULE) |
| 266 | static struct omap_device_pm_latency mbox_latencies[] = { | ||
| 267 | [0] = { | ||
| 268 | .activate_func = omap_device_enable_hwmods, | ||
| 269 | .deactivate_func = omap_device_idle_hwmods, | ||
| 270 | .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, | ||
| 271 | }, | ||
| 272 | }; | ||
| 273 | |||
| 274 | static inline void omap_init_mbox(void) | 261 | static inline void omap_init_mbox(void) |
| 275 | { | 262 | { |
| 276 | struct omap_hwmod *oh; | 263 | struct omap_hwmod *oh; |
| @@ -282,8 +269,7 @@ static inline void omap_init_mbox(void) | |||
| 282 | return; | 269 | return; |
| 283 | } | 270 | } |
| 284 | 271 | ||
| 285 | pdev = omap_device_build("omap-mailbox", -1, oh, NULL, 0, | 272 | pdev = omap_device_build("omap-mailbox", -1, oh, NULL, 0, NULL, 0, 0); |
| 286 | mbox_latencies, ARRAY_SIZE(mbox_latencies), 0); | ||
| 287 | WARN(IS_ERR(pdev), "%s: could not build device, err %ld\n", | 273 | WARN(IS_ERR(pdev), "%s: could not build device, err %ld\n", |
| 288 | __func__, PTR_ERR(pdev)); | 274 | __func__, PTR_ERR(pdev)); |
| 289 | } | 275 | } |
| @@ -334,14 +320,6 @@ static inline void omap_init_audio(void) {} | |||
| 334 | 320 | ||
| 335 | #include <plat/mcspi.h> | 321 | #include <plat/mcspi.h> |
| 336 | 322 | ||
| 337 | struct omap_device_pm_latency omap_mcspi_latency[] = { | ||
| 338 | [0] = { | ||
| 339 | .deactivate_func = omap_device_idle_hwmods, | ||
| 340 | .activate_func = omap_device_enable_hwmods, | ||
| 341 | .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, | ||
| 342 | }, | ||
| 343 | }; | ||
| 344 | |||
| 345 | static int omap_mcspi_init(struct omap_hwmod *oh, void *unused) | 323 | static int omap_mcspi_init(struct omap_hwmod *oh, void *unused) |
| 346 | { | 324 | { |
| 347 | struct platform_device *pdev; | 325 | struct platform_device *pdev; |
| @@ -372,8 +350,7 @@ static int omap_mcspi_init(struct omap_hwmod *oh, void *unused) | |||
| 372 | 350 | ||
| 373 | spi_num++; | 351 | spi_num++; |
| 374 | pdev = omap_device_build(name, spi_num, oh, pdata, | 352 | pdev = omap_device_build(name, spi_num, oh, pdata, |
| 375 | sizeof(*pdata), omap_mcspi_latency, | 353 | sizeof(*pdata), NULL, 0, 0); |
| 376 | ARRAY_SIZE(omap_mcspi_latency), 0); | ||
| 377 | WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s\n", | 354 | WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s\n", |
| 378 | name, oh->name); | 355 | name, oh->name); |
| 379 | kfree(pdata); | 356 | kfree(pdata); |
| @@ -698,14 +675,6 @@ static int __init omap2_init_devices(void) | |||
| 698 | arch_initcall(omap2_init_devices); | 675 | arch_initcall(omap2_init_devices); |
| 699 | 676 | ||
| 700 | #if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE) | 677 | #if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE) |
| 701 | static struct omap_device_pm_latency omap_wdt_latency[] = { | ||
| 702 | [0] = { | ||
| 703 | .deactivate_func = omap_device_idle_hwmods, | ||
| 704 | .activate_func = omap_device_enable_hwmods, | ||
| 705 | .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, | ||
| 706 | }, | ||
| 707 | }; | ||
| 708 | |||
| 709 | static int __init omap_init_wdt(void) | 678 | static int __init omap_init_wdt(void) |
| 710 | { | 679 | { |
| 711 | int id = -1; | 680 | int id = -1; |
| @@ -723,9 +692,7 @@ static int __init omap_init_wdt(void) | |||
| 723 | return -EINVAL; | 692 | return -EINVAL; |
| 724 | } | 693 | } |
| 725 | 694 | ||
| 726 | pdev = omap_device_build(dev_name, id, oh, NULL, 0, | 695 | pdev = omap_device_build(dev_name, id, oh, NULL, 0, NULL, 0, 0); |
| 727 | omap_wdt_latency, | ||
| 728 | ARRAY_SIZE(omap_wdt_latency), 0); | ||
| 729 | WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n", | 696 | WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n", |
| 730 | dev_name, oh->name); | 697 | dev_name, oh->name); |
| 731 | return 0; | 698 | return 0; |
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index 18693f6de041..8ad0a2f0367d 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c | |||
| @@ -35,14 +35,6 @@ static struct platform_device omap_display_device = { | |||
| 35 | }, | 35 | }, |
| 36 | }; | 36 | }; |
| 37 | 37 | ||
| 38 | static struct omap_device_pm_latency omap_dss_latency[] = { | ||
| 39 | [0] = { | ||
| 40 | .deactivate_func = omap_device_idle_hwmods, | ||
| 41 | .activate_func = omap_device_enable_hwmods, | ||
| 42 | .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, | ||
| 43 | }, | ||
| 44 | }; | ||
| 45 | |||
| 46 | struct omap_dss_hwmod_data { | 38 | struct omap_dss_hwmod_data { |
| 47 | const char *oh_name; | 39 | const char *oh_name; |
| 48 | const char *dev_name; | 40 | const char *dev_name; |
| @@ -111,8 +103,7 @@ int __init omap_display_init(struct omap_dss_board_info *board_data) | |||
| 111 | pdev = omap_device_build(curr_dss_hwmod[i].dev_name, | 103 | pdev = omap_device_build(curr_dss_hwmod[i].dev_name, |
| 112 | curr_dss_hwmod[i].id, oh, &pdata, | 104 | curr_dss_hwmod[i].id, oh, &pdata, |
| 113 | sizeof(struct omap_display_platform_data), | 105 | sizeof(struct omap_display_platform_data), |
| 114 | omap_dss_latency, | 106 | NULL, 0, 0); |
| 115 | ARRAY_SIZE(omap_dss_latency), 0); | ||
| 116 | 107 | ||
| 117 | if (WARN((IS_ERR(pdev)), "Could not build omap_device for %s\n", | 108 | if (WARN((IS_ERR(pdev)), "Could not build omap_device for %s\n", |
| 118 | curr_dss_hwmod[i].oh_name)) | 109 | curr_dss_hwmod[i].oh_name)) |
diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c index ae8cb3fb1830..a59a45a0096e 100644 --- a/arch/arm/mach-omap2/dma.c +++ b/arch/arm/mach-omap2/dma.c | |||
| @@ -87,14 +87,6 @@ static u16 reg_map[] = { | |||
| 87 | [CCDN] = 0xd8, | 87 | [CCDN] = 0xd8, |
| 88 | }; | 88 | }; |
| 89 | 89 | ||
| 90 | static struct omap_device_pm_latency omap2_dma_latency[] = { | ||
| 91 | { | ||
| 92 | .deactivate_func = omap_device_idle_hwmods, | ||
| 93 | .activate_func = omap_device_enable_hwmods, | ||
| 94 | .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, | ||
| 95 | }, | ||
| 96 | }; | ||
| 97 | |||
| 98 | static void __iomem *dma_base; | 90 | static void __iomem *dma_base; |
| 99 | static inline void dma_write(u32 val, int reg, int lch) | 91 | static inline void dma_write(u32 val, int reg, int lch) |
| 100 | { | 92 | { |
| @@ -258,8 +250,7 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused) | |||
| 258 | 250 | ||
| 259 | p->errata = configure_dma_errata(); | 251 | p->errata = configure_dma_errata(); |
| 260 | 252 | ||
| 261 | pdev = omap_device_build(name, 0, oh, p, sizeof(*p), | 253 | pdev = omap_device_build(name, 0, oh, p, sizeof(*p), NULL, 0, 0); |
| 262 | omap2_dma_latency, ARRAY_SIZE(omap2_dma_latency), 0); | ||
| 263 | kfree(p); | 254 | kfree(p); |
| 264 | if (IS_ERR(pdev)) { | 255 | if (IS_ERR(pdev)) { |
| 265 | pr_err("%s: Can't build omap_device for %s:%s.\n", | 256 | pr_err("%s: Can't build omap_device for %s:%s.\n", |
diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c index 652ccc574196..8cbfbc2918ce 100644 --- a/arch/arm/mach-omap2/gpio.c +++ b/arch/arm/mach-omap2/gpio.c | |||
| @@ -24,14 +24,6 @@ | |||
| 24 | #include <plat/omap_hwmod.h> | 24 | #include <plat/omap_hwmod.h> |
| 25 | #include <plat/omap_device.h> | 25 | #include <plat/omap_device.h> |
| 26 | 26 | ||
| 27 | static struct omap_device_pm_latency omap_gpio_latency[] = { | ||
| 28 | [0] = { | ||
| 29 | .deactivate_func = omap_device_idle_hwmods, | ||
| 30 | .activate_func = omap_device_enable_hwmods, | ||
| 31 | .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, | ||
| 32 | }, | ||
| 33 | }; | ||
| 34 | |||
| 35 | static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) | 27 | static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) |
| 36 | { | 28 | { |
| 37 | struct platform_device *pdev; | 29 | struct platform_device *pdev; |
| @@ -108,9 +100,7 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) | |||
| 108 | } | 100 | } |
| 109 | 101 | ||
| 110 | pdev = omap_device_build(name, id - 1, oh, pdata, | 102 | pdev = omap_device_build(name, id - 1, oh, pdata, |
| 111 | sizeof(*pdata), omap_gpio_latency, | 103 | sizeof(*pdata), NULL, 0, false); |
| 112 | ARRAY_SIZE(omap_gpio_latency), | ||
| 113 | false); | ||
| 114 | kfree(pdata); | 104 | kfree(pdata); |
| 115 | 105 | ||
| 116 | if (IS_ERR(pdev)) { | 106 | if (IS_ERR(pdev)) { |
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c index 2dc002a388b3..77085847e4e7 100644 --- a/arch/arm/mach-omap2/hsmmc.c +++ b/arch/arm/mach-omap2/hsmmc.c | |||
| @@ -409,31 +409,17 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, | |||
| 409 | return 0; | 409 | return 0; |
| 410 | } | 410 | } |
| 411 | 411 | ||
| 412 | static struct omap_device_pm_latency omap_hsmmc_latency[] = { | ||
| 413 | [0] = { | ||
| 414 | .deactivate_func = omap_device_idle_hwmods, | ||
| 415 | .activate_func = omap_device_enable_hwmods, | ||
| 416 | .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, | ||
| 417 | }, | ||
| 418 | /* | ||
| 419 | * XXX There should also be an entry here to power off/on the | ||
| 420 | * MMC regulators/PBIAS cells, etc. | ||
| 421 | */ | ||
| 422 | }; | ||
| 423 | |||
| 424 | #define MAX_OMAP_MMC_HWMOD_NAME_LEN 16 | 412 | #define MAX_OMAP_MMC_HWMOD_NAME_LEN 16 |
| 425 | 413 | ||
| 426 | void __init omap_init_hsmmc(struct omap2_hsmmc_info *hsmmcinfo, int ctrl_nr) | 414 | void __init omap_init_hsmmc(struct omap2_hsmmc_info *hsmmcinfo, int ctrl_nr) |
| 427 | { | 415 | { |
| 428 | struct omap_hwmod *oh; | 416 | struct omap_hwmod *oh; |
| 429 | struct platform_device *pdev; | 417 | struct platform_device *pdev; |
| 430 | struct omap_device_pm_latency *ohl; | ||
| 431 | char oh_name[MAX_OMAP_MMC_HWMOD_NAME_LEN]; | 418 | char oh_name[MAX_OMAP_MMC_HWMOD_NAME_LEN]; |
| 432 | struct omap_mmc_platform_data *mmc_data; | 419 | struct omap_mmc_platform_data *mmc_data; |
| 433 | struct omap_mmc_dev_attr *mmc_dev_attr; | 420 | struct omap_mmc_dev_attr *mmc_dev_attr; |
| 434 | char *name; | 421 | char *name; |
| 435 | int l; | 422 | int l; |
| 436 | int ohl_cnt = 0; | ||
| 437 | 423 | ||
| 438 | mmc_data = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL); | 424 | mmc_data = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL); |
| 439 | if (!mmc_data) { | 425 | if (!mmc_data) { |
| @@ -448,8 +434,6 @@ void __init omap_init_hsmmc(struct omap2_hsmmc_info *hsmmcinfo, int ctrl_nr) | |||
| 448 | omap_hsmmc_mux(mmc_data, (ctrl_nr - 1)); | 434 | omap_hsmmc_mux(mmc_data, (ctrl_nr - 1)); |
| 449 | 435 | ||
| 450 | name = "omap_hsmmc"; | 436 | name = "omap_hsmmc"; |
| 451 | ohl = omap_hsmmc_latency; | ||
| 452 | ohl_cnt = ARRAY_SIZE(omap_hsmmc_latency); | ||
| 453 | 437 | ||
| 454 | l = snprintf(oh_name, MAX_OMAP_MMC_HWMOD_NAME_LEN, | 438 | l = snprintf(oh_name, MAX_OMAP_MMC_HWMOD_NAME_LEN, |
| 455 | "mmc%d", ctrl_nr); | 439 | "mmc%d", ctrl_nr); |
| @@ -468,7 +452,7 @@ void __init omap_init_hsmmc(struct omap2_hsmmc_info *hsmmcinfo, int ctrl_nr) | |||
| 468 | } | 452 | } |
| 469 | 453 | ||
| 470 | pdev = omap_device_build(name, ctrl_nr - 1, oh, mmc_data, | 454 | pdev = omap_device_build(name, ctrl_nr - 1, oh, mmc_data, |
| 471 | sizeof(struct omap_mmc_platform_data), ohl, ohl_cnt, false); | 455 | sizeof(struct omap_mmc_platform_data), NULL, 0, false); |
| 472 | if (IS_ERR(pdev)) { | 456 | if (IS_ERR(pdev)) { |
| 473 | WARN(1, "Can't build omap_device for %s:%s.\n", name, oh->name); | 457 | WARN(1, "Can't build omap_device for %s:%s.\n", name, oh->name); |
| 474 | kfree(mmc_data->slots[0].name); | 458 | kfree(mmc_data->slots[0].name); |
diff --git a/arch/arm/mach-omap2/hwspinlock.c b/arch/arm/mach-omap2/hwspinlock.c index 0b3ae9d9c3b3..36e21091b06a 100644 --- a/arch/arm/mach-omap2/hwspinlock.c +++ b/arch/arm/mach-omap2/hwspinlock.c | |||
| @@ -23,14 +23,6 @@ | |||
| 23 | #include <plat/omap_hwmod.h> | 23 | #include <plat/omap_hwmod.h> |
| 24 | #include <plat/omap_device.h> | 24 | #include <plat/omap_device.h> |
| 25 | 25 | ||
| 26 | struct omap_device_pm_latency omap_spinlock_latency[] = { | ||
| 27 | { | ||
| 28 | .deactivate_func = omap_device_idle_hwmods, | ||
| 29 | .activate_func = omap_device_enable_hwmods, | ||
| 30 | .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, | ||
| 31 | } | ||
| 32 | }; | ||
| 33 | |||
| 34 | int __init hwspinlocks_init(void) | 26 | int __init hwspinlocks_init(void) |
| 35 | { | 27 | { |
| 36 | int retval = 0; | 28 | int retval = 0; |
| @@ -48,9 +40,7 @@ int __init hwspinlocks_init(void) | |||
| 48 | if (oh == NULL) | 40 | if (oh == NULL) |
| 49 | return -EINVAL; | 41 | return -EINVAL; |
| 50 | 42 | ||
| 51 | pdev = omap_device_build(dev_name, 0, oh, NULL, 0, | 43 | pdev = omap_device_build(dev_name, 0, oh, NULL, 0, NULL, 0, false); |
| 52 | omap_spinlock_latency, | ||
| 53 | ARRAY_SIZE(omap_spinlock_latency), false); | ||
| 54 | if (IS_ERR(pdev)) { | 44 | if (IS_ERR(pdev)) { |
| 55 | pr_err("Can't build omap_device for %s:%s\n", dev_name, | 45 | pr_err("Can't build omap_device for %s:%s\n", dev_name, |
| 56 | oh_name); | 46 | oh_name); |
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c index 5063f253c4b9..292eee3be15f 100644 --- a/arch/arm/mach-omap2/mcbsp.c +++ b/arch/arm/mach-omap2/mcbsp.c | |||
| @@ -122,14 +122,6 @@ static int omap3_enable_st_clock(unsigned int id, bool enable) | |||
| 122 | return 0; | 122 | return 0; |
| 123 | } | 123 | } |
| 124 | 124 | ||
| 125 | struct omap_device_pm_latency omap2_mcbsp_latency[] = { | ||
| 126 | { | ||
| 127 | .deactivate_func = omap_device_idle_hwmods, | ||
| 128 | .activate_func = omap_device_enable_hwmods, | ||
| 129 | .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, | ||
| 130 | }, | ||
| 131 | }; | ||
| 132 | |||
| 133 | static int omap_init_mcbsp(struct omap_hwmod *oh, void *unused) | 125 | static int omap_init_mcbsp(struct omap_hwmod *oh, void *unused) |
| 134 | { | 126 | { |
| 135 | int id, count = 1; | 127 | int id, count = 1; |
| @@ -175,8 +167,7 @@ static int omap_init_mcbsp(struct omap_hwmod *oh, void *unused) | |||
| 175 | count++; | 167 | count++; |
| 176 | } | 168 | } |
| 177 | pdev = omap_device_build_ss(name, id, oh_device, count, pdata, | 169 | pdev = omap_device_build_ss(name, id, oh_device, count, pdata, |
| 178 | sizeof(*pdata), omap2_mcbsp_latency, | 170 | sizeof(*pdata), NULL, 0, false); |
| 179 | ARRAY_SIZE(omap2_mcbsp_latency), false); | ||
| 180 | kfree(pdata); | 171 | kfree(pdata); |
| 181 | if (IS_ERR(pdev)) { | 172 | if (IS_ERR(pdev)) { |
| 182 | pr_err("%s: Can't build omap_device for %s:%s.\n", __func__, | 173 | pr_err("%s: Can't build omap_device for %s:%s.\n", __func__, |
diff --git a/arch/arm/mach-omap2/omap_l3_noc.c b/arch/arm/mach-omap2/omap_l3_noc.c index 07a3d3ede768..c8b1bef92e5a 100644 --- a/arch/arm/mach-omap2/omap_l3_noc.c +++ b/arch/arm/mach-omap2/omap_l3_noc.c | |||
| @@ -127,7 +127,7 @@ static irqreturn_t l3_interrupt_handler(int irq, void *_l3) | |||
| 127 | return IRQ_HANDLED; | 127 | return IRQ_HANDLED; |
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | static int __init omap4_l3_probe(struct platform_device *pdev) | 130 | static int __devinit omap4_l3_probe(struct platform_device *pdev) |
| 131 | { | 131 | { |
| 132 | static struct omap4_l3 *l3; | 132 | static struct omap4_l3 *l3; |
| 133 | struct resource *res; | 133 | struct resource *res; |
| @@ -218,7 +218,7 @@ err0: | |||
| 218 | return ret; | 218 | return ret; |
| 219 | } | 219 | } |
| 220 | 220 | ||
| 221 | static int __exit omap4_l3_remove(struct platform_device *pdev) | 221 | static int __devexit omap4_l3_remove(struct platform_device *pdev) |
| 222 | { | 222 | { |
| 223 | struct omap4_l3 *l3 = platform_get_drvdata(pdev); | 223 | struct omap4_l3 *l3 = platform_get_drvdata(pdev); |
| 224 | 224 | ||
| @@ -232,16 +232,29 @@ static int __exit omap4_l3_remove(struct platform_device *pdev) | |||
| 232 | return 0; | 232 | return 0; |
| 233 | } | 233 | } |
| 234 | 234 | ||
| 235 | #if defined(CONFIG_OF) | ||
| 236 | static const struct of_device_id l3_noc_match[] = { | ||
| 237 | {.compatible = "ti,omap4-l3-noc", }, | ||
| 238 | {}, | ||
| 239 | } | ||
| 240 | MODULE_DEVICE_TABLE(of, l3_noc_match); | ||
| 241 | #else | ||
| 242 | #define l3_noc_match NULL | ||
| 243 | #endif | ||
| 244 | |||
| 235 | static struct platform_driver omap4_l3_driver = { | 245 | static struct platform_driver omap4_l3_driver = { |
| 236 | .remove = __exit_p(omap4_l3_remove), | 246 | .probe = omap4_l3_probe, |
| 237 | .driver = { | 247 | .remove = __devexit_p(omap4_l3_remove), |
| 238 | .name = "omap_l3_noc", | 248 | .driver = { |
| 249 | .name = "omap_l3_noc", | ||
| 250 | .owner = THIS_MODULE, | ||
| 251 | .of_match_table = l3_noc_match, | ||
| 239 | }, | 252 | }, |
| 240 | }; | 253 | }; |
| 241 | 254 | ||
| 242 | static int __init omap4_l3_init(void) | 255 | static int __init omap4_l3_init(void) |
| 243 | { | 256 | { |
| 244 | return platform_driver_probe(&omap4_l3_driver, omap4_l3_probe); | 257 | return platform_driver_register(&omap4_l3_driver); |
| 245 | } | 258 | } |
| 246 | postcore_initcall_sync(omap4_l3_init); | 259 | postcore_initcall_sync(omap4_l3_init); |
| 247 | 260 | ||
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 0844e2ecfb4a..2ab7a9e17fe2 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c | |||
| @@ -26,38 +26,7 @@ | |||
| 26 | 26 | ||
| 27 | static struct omap_device_pm_latency *pm_lats; | 27 | static struct omap_device_pm_latency *pm_lats; |
| 28 | 28 | ||
| 29 | static struct device *mpu_dev; | 29 | static int _init_omap_device(char *name) |
| 30 | static struct device *iva_dev; | ||
| 31 | static struct device *l3_dev; | ||
| 32 | static struct device *dsp_dev; | ||
| 33 | |||
| 34 | struct device *omap2_get_mpuss_device(void) | ||
| 35 | { | ||
| 36 | WARN_ON_ONCE(!mpu_dev); | ||
| 37 | return mpu_dev; | ||
| 38 | } | ||
| 39 | |||
| 40 | struct device *omap2_get_iva_device(void) | ||
| 41 | { | ||
| 42 | WARN_ON_ONCE(!iva_dev); | ||
| 43 | return iva_dev; | ||
| 44 | } | ||
| 45 | |||
| 46 | struct device *omap2_get_l3_device(void) | ||
| 47 | { | ||
| 48 | WARN_ON_ONCE(!l3_dev); | ||
| 49 | return l3_dev; | ||
| 50 | } | ||
| 51 | |||
| 52 | struct device *omap4_get_dsp_device(void) | ||
| 53 | { | ||
| 54 | WARN_ON_ONCE(!dsp_dev); | ||
| 55 | return dsp_dev; | ||
| 56 | } | ||
| 57 | EXPORT_SYMBOL(omap4_get_dsp_device); | ||
| 58 | |||
| 59 | /* static int _init_omap_device(struct omap_hwmod *oh, void *user) */ | ||
| 60 | static int _init_omap_device(char *name, struct device **new_dev) | ||
| 61 | { | 30 | { |
| 62 | struct omap_hwmod *oh; | 31 | struct omap_hwmod *oh; |
| 63 | struct platform_device *pdev; | 32 | struct platform_device *pdev; |
| @@ -72,8 +41,6 @@ static int _init_omap_device(char *name, struct device **new_dev) | |||
| 72 | __func__, name)) | 41 | __func__, name)) |
| 73 | return -ENODEV; | 42 | return -ENODEV; |
| 74 | 43 | ||
| 75 | *new_dev = &pdev->dev; | ||
| 76 | |||
| 77 | return 0; | 44 | return 0; |
| 78 | } | 45 | } |
| 79 | 46 | ||
| @@ -82,16 +49,16 @@ static int _init_omap_device(char *name, struct device **new_dev) | |||
| 82 | */ | 49 | */ |
| 83 | static void omap2_init_processor_devices(void) | 50 | static void omap2_init_processor_devices(void) |
| 84 | { | 51 | { |
| 85 | _init_omap_device("mpu", &mpu_dev); | 52 | _init_omap_device("mpu"); |
| 86 | if (omap3_has_iva()) | 53 | if (omap3_has_iva()) |
| 87 | _init_omap_device("iva", &iva_dev); | 54 | _init_omap_device("iva"); |
| 88 | 55 | ||
| 89 | if (cpu_is_omap44xx()) { | 56 | if (cpu_is_omap44xx()) { |
| 90 | _init_omap_device("l3_main_1", &l3_dev); | 57 | _init_omap_device("l3_main_1"); |
| 91 | _init_omap_device("dsp", &dsp_dev); | 58 | _init_omap_device("dsp"); |
| 92 | _init_omap_device("iva", &iva_dev); | 59 | _init_omap_device("iva"); |
| 93 | } else { | 60 | } else { |
| 94 | _init_omap_device("l3_main", &l3_dev); | 61 | _init_omap_device("l3_main"); |
| 95 | } | 62 | } |
| 96 | } | 63 | } |
| 97 | 64 | ||
| @@ -169,18 +136,26 @@ err: | |||
| 169 | * in the opp entry | 136 | * in the opp entry |
| 170 | */ | 137 | */ |
| 171 | static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name, | 138 | static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name, |
| 172 | struct device *dev) | 139 | const char *oh_name) |
| 173 | { | 140 | { |
| 174 | struct voltagedomain *voltdm; | 141 | struct voltagedomain *voltdm; |
| 175 | struct clk *clk; | 142 | struct clk *clk; |
| 176 | struct opp *opp; | 143 | struct opp *opp; |
| 177 | unsigned long freq, bootup_volt; | 144 | unsigned long freq, bootup_volt; |
| 145 | struct device *dev; | ||
| 178 | 146 | ||
| 179 | if (!vdd_name || !clk_name || !dev) { | 147 | if (!vdd_name || !clk_name || !oh_name) { |
| 180 | pr_err("%s: invalid parameters\n", __func__); | 148 | pr_err("%s: invalid parameters\n", __func__); |
| 181 | goto exit; | 149 | goto exit; |
| 182 | } | 150 | } |
| 183 | 151 | ||
| 152 | dev = omap_device_get_by_hwmod_name(oh_name); | ||
| 153 | if (IS_ERR(dev)) { | ||
| 154 | pr_err("%s: Unable to get dev pointer for hwmod %s\n", | ||
| 155 | __func__, oh_name); | ||
| 156 | goto exit; | ||
| 157 | } | ||
| 158 | |||
| 184 | voltdm = voltdm_lookup(vdd_name); | 159 | voltdm = voltdm_lookup(vdd_name); |
| 185 | if (IS_ERR(voltdm)) { | 160 | if (IS_ERR(voltdm)) { |
| 186 | pr_err("%s: unable to get vdd pointer for vdd_%s\n", | 161 | pr_err("%s: unable to get vdd pointer for vdd_%s\n", |
| @@ -224,8 +199,8 @@ static void __init omap3_init_voltages(void) | |||
| 224 | if (!cpu_is_omap34xx()) | 199 | if (!cpu_is_omap34xx()) |
| 225 | return; | 200 | return; |
| 226 | 201 | ||
| 227 | omap2_set_init_voltage("mpu_iva", "dpll1_ck", mpu_dev); | 202 | omap2_set_init_voltage("mpu_iva", "dpll1_ck", "mpu"); |
| 228 | omap2_set_init_voltage("core", "l3_ick", l3_dev); | 203 | omap2_set_init_voltage("core", "l3_ick", "l3_main"); |
| 229 | } | 204 | } |
| 230 | 205 | ||
| 231 | static void __init omap4_init_voltages(void) | 206 | static void __init omap4_init_voltages(void) |
| @@ -233,14 +208,15 @@ static void __init omap4_init_voltages(void) | |||
| 233 | if (!cpu_is_omap44xx()) | 208 | if (!cpu_is_omap44xx()) |
| 234 | return; | 209 | return; |
| 235 | 210 | ||
| 236 | omap2_set_init_voltage("mpu", "dpll_mpu_ck", mpu_dev); | 211 | omap2_set_init_voltage("mpu", "dpll_mpu_ck", "mpu"); |
| 237 | omap2_set_init_voltage("core", "l3_div_ck", l3_dev); | 212 | omap2_set_init_voltage("core", "l3_div_ck", "l3_main_1"); |
| 238 | omap2_set_init_voltage("iva", "dpll_iva_m5x2_ck", iva_dev); | 213 | omap2_set_init_voltage("iva", "dpll_iva_m5x2_ck", "iva"); |
| 239 | } | 214 | } |
| 240 | 215 | ||
| 241 | static int __init omap2_common_pm_init(void) | 216 | static int __init omap2_common_pm_init(void) |
| 242 | { | 217 | { |
| 243 | omap2_init_processor_devices(); | 218 | if (!of_have_populated_dt()) |
| 219 | omap2_init_processor_devices(); | ||
| 244 | omap_pm_if_init(); | 220 | omap_pm_if_init(); |
| 245 | 221 | ||
| 246 | return 0; | 222 | return 0; |
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 3d1c1d393f8f..9992dbfdfdb3 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c | |||
| @@ -107,28 +107,6 @@ struct omap_uart_state { | |||
| 107 | static LIST_HEAD(uart_list); | 107 | static LIST_HEAD(uart_list); |
| 108 | static u8 num_uarts; | 108 | static u8 num_uarts; |
| 109 | 109 | ||
| 110 | static int uart_idle_hwmod(struct omap_device *od) | ||
| 111 | { | ||
| 112 | omap_hwmod_idle(od->hwmods[0]); | ||
| 113 | |||
| 114 | return 0; | ||
| 115 | } | ||
| 116 | |||
| 117 | static int uart_enable_hwmod(struct omap_device *od) | ||
| 118 | { | ||
| 119 | omap_hwmod_enable(od->hwmods[0]); | ||
| 120 | |||
| 121 | return 0; | ||
| 122 | } | ||
| 123 | |||
| 124 | static struct omap_device_pm_latency omap_uart_latency[] = { | ||
| 125 | { | ||
| 126 | .deactivate_func = uart_idle_hwmod, | ||
| 127 | .activate_func = uart_enable_hwmod, | ||
| 128 | .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, | ||
| 129 | }, | ||
| 130 | }; | ||
| 131 | |||
| 132 | static inline unsigned int __serial_read_reg(struct uart_port *up, | 110 | static inline unsigned int __serial_read_reg(struct uart_port *up, |
| 133 | int offset) | 111 | int offset) |
| 134 | { | 112 | { |
| @@ -800,8 +778,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) | |||
| 800 | return; | 778 | return; |
| 801 | 779 | ||
| 802 | pdev = omap_device_build(name, uart->num, oh, pdata, pdata_size, | 780 | pdev = omap_device_build(name, uart->num, oh, pdata, pdata_size, |
| 803 | omap_uart_latency, | 781 | NULL, 0, false); |
| 804 | ARRAY_SIZE(omap_uart_latency), false); | ||
| 805 | WARN(IS_ERR(pdev), "Could not build omap_device for %s: %s.\n", | 782 | WARN(IS_ERR(pdev), "Could not build omap_device for %s: %s.\n", |
| 806 | name, oh->name); | 783 | name, oh->name); |
| 807 | 784 | ||
diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c index eba9f9a8ab65..9f43fcc05d3e 100644 --- a/arch/arm/mach-omap2/sr_device.c +++ b/arch/arm/mach-omap2/sr_device.c | |||
| @@ -31,14 +31,6 @@ | |||
| 31 | 31 | ||
| 32 | static bool sr_enable_on_init; | 32 | static bool sr_enable_on_init; |
| 33 | 33 | ||
| 34 | static struct omap_device_pm_latency omap_sr_latency[] = { | ||
| 35 | { | ||
| 36 | .deactivate_func = omap_device_idle_hwmods, | ||
| 37 | .activate_func = omap_device_enable_hwmods, | ||
| 38 | .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST | ||
| 39 | }, | ||
| 40 | }; | ||
| 41 | |||
| 42 | /* Read EFUSE values from control registers for OMAP3430 */ | 34 | /* Read EFUSE values from control registers for OMAP3430 */ |
| 43 | static void __init sr_set_nvalues(struct omap_volt_data *volt_data, | 35 | static void __init sr_set_nvalues(struct omap_volt_data *volt_data, |
| 44 | struct omap_sr_data *sr_data) | 36 | struct omap_sr_data *sr_data) |
| @@ -121,8 +113,7 @@ static int sr_dev_init(struct omap_hwmod *oh, void *user) | |||
| 121 | sr_data->enable_on_init = sr_enable_on_init; | 113 | sr_data->enable_on_init = sr_enable_on_init; |
| 122 | 114 | ||
| 123 | pdev = omap_device_build(name, i, oh, sr_data, sizeof(*sr_data), | 115 | pdev = omap_device_build(name, i, oh, sr_data, sizeof(*sr_data), |
| 124 | omap_sr_latency, | 116 | NULL, 0, 0); |
| 125 | ARRAY_SIZE(omap_sr_latency), 0); | ||
| 126 | if (IS_ERR(pdev)) | 117 | if (IS_ERR(pdev)) |
| 127 | pr_warning("%s: Could not build omap_device for %s: %s.\n\n", | 118 | pr_warning("%s: Could not build omap_device for %s: %s.\n\n", |
| 128 | __func__, name, oh->name); | 119 | __func__, name, oh->name); |
diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c index d86af3cda8c7..47fb5d607630 100644 --- a/arch/arm/mach-omap2/usb-musb.c +++ b/arch/arm/mach-omap2/usb-musb.c | |||
| @@ -60,14 +60,6 @@ static struct musb_hdrc_platform_data musb_plat = { | |||
| 60 | 60 | ||
| 61 | static u64 musb_dmamask = DMA_BIT_MASK(32); | 61 | static u64 musb_dmamask = DMA_BIT_MASK(32); |
| 62 | 62 | ||
| 63 | static struct omap_device_pm_latency omap_musb_latency[] = { | ||
| 64 | { | ||
| 65 | .deactivate_func = omap_device_idle_hwmods, | ||
| 66 | .activate_func = omap_device_enable_hwmods, | ||
| 67 | .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, | ||
| 68 | }, | ||
| 69 | }; | ||
| 70 | |||
| 71 | static void usb_musb_mux_init(struct omap_musb_board_data *board_data) | 63 | static void usb_musb_mux_init(struct omap_musb_board_data *board_data) |
| 72 | { | 64 | { |
| 73 | switch (board_data->interface_type) { | 65 | switch (board_data->interface_type) { |
| @@ -150,8 +142,7 @@ void __init usb_musb_init(struct omap_musb_board_data *musb_board_data) | |||
| 150 | return; | 142 | return; |
| 151 | 143 | ||
| 152 | pdev = omap_device_build(name, bus_id, oh, &musb_plat, | 144 | pdev = omap_device_build(name, bus_id, oh, &musb_plat, |
| 153 | sizeof(musb_plat), omap_musb_latency, | 145 | sizeof(musb_plat), NULL, 0, false); |
| 154 | ARRAY_SIZE(omap_musb_latency), false); | ||
| 155 | if (IS_ERR(pdev)) { | 146 | if (IS_ERR(pdev)) { |
| 156 | pr_err("Could not build omap_device for %s %s\n", | 147 | pr_err("Could not build omap_device for %s %s\n", |
| 157 | name, oh_name); | 148 | name, oh_name); |
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c index 0c7caf2458b4..c20beb8ed38b 100644 --- a/arch/arm/plat-omap/i2c.c +++ b/arch/arm/plat-omap/i2c.c | |||
| @@ -123,14 +123,6 @@ static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t) | |||
| 123 | omap_pm_set_max_mpu_wakeup_lat(dev, t); | 123 | omap_pm_set_max_mpu_wakeup_lat(dev, t); |
| 124 | } | 124 | } |
| 125 | 125 | ||
| 126 | static struct omap_device_pm_latency omap_i2c_latency[] = { | ||
| 127 | [0] = { | ||
| 128 | .deactivate_func = omap_device_idle_hwmods, | ||
| 129 | .activate_func = omap_device_enable_hwmods, | ||
| 130 | .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, | ||
| 131 | }, | ||
| 132 | }; | ||
| 133 | |||
| 134 | static inline int omap2_i2c_add_bus(int bus_id) | 126 | static inline int omap2_i2c_add_bus(int bus_id) |
| 135 | { | 127 | { |
| 136 | int l; | 128 | int l; |
| @@ -162,7 +154,7 @@ static inline int omap2_i2c_add_bus(int bus_id) | |||
| 162 | pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat; | 154 | pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat; |
| 163 | pdev = omap_device_build(name, bus_id, oh, pdata, | 155 | pdev = omap_device_build(name, bus_id, oh, pdata, |
| 164 | sizeof(struct omap_i2c_bus_platform_data), | 156 | sizeof(struct omap_i2c_bus_platform_data), |
| 165 | omap_i2c_latency, ARRAY_SIZE(omap_i2c_latency), 0); | 157 | NULL, 0, 0); |
| 166 | WARN(IS_ERR(pdev), "Could not build omap_device for %s\n", name); | 158 | WARN(IS_ERR(pdev), "Could not build omap_device for %s\n", name); |
| 167 | 159 | ||
| 168 | return PTR_ERR(pdev); | 160 | return PTR_ERR(pdev); |
diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h index d4d9b96f961e..12c5b0c345bf 100644 --- a/arch/arm/plat-omap/include/plat/omap_device.h +++ b/arch/arm/plat-omap/include/plat/omap_device.h | |||
| @@ -101,6 +101,7 @@ struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id, | |||
| 101 | int pm_lats_cnt, int is_early_device); | 101 | int pm_lats_cnt, int is_early_device); |
| 102 | 102 | ||
| 103 | void __iomem *omap_device_get_rt_va(struct omap_device *od); | 103 | void __iomem *omap_device_get_rt_va(struct omap_device *od); |
| 104 | struct device *omap_device_get_by_hwmod_name(const char *oh_name); | ||
| 104 | 105 | ||
| 105 | /* OMAP PM interface */ | 106 | /* OMAP PM interface */ |
| 106 | int omap_device_align_pm_lat(struct platform_device *pdev, | 107 | int omap_device_align_pm_lat(struct platform_device *pdev, |
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index 26aee5cc1fc1..cd90bedd9306 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c | |||
| @@ -85,6 +85,8 @@ | |||
| 85 | #include <linux/clk.h> | 85 | #include <linux/clk.h> |
| 86 | #include <linux/clkdev.h> | 86 | #include <linux/clkdev.h> |
| 87 | #include <linux/pm_runtime.h> | 87 | #include <linux/pm_runtime.h> |
| 88 | #include <linux/of.h> | ||
| 89 | #include <linux/notifier.h> | ||
| 88 | 90 | ||
| 89 | #include <plat/omap_device.h> | 91 | #include <plat/omap_device.h> |
| 90 | #include <plat/omap_hwmod.h> | 92 | #include <plat/omap_hwmod.h> |
| @@ -96,6 +98,20 @@ | |||
| 96 | 98 | ||
| 97 | static int omap_device_register(struct platform_device *pdev); | 99 | static int omap_device_register(struct platform_device *pdev); |
| 98 | static int omap_early_device_register(struct platform_device *pdev); | 100 | static int omap_early_device_register(struct platform_device *pdev); |
| 101 | static struct omap_device *omap_device_alloc(struct platform_device *pdev, | ||
| 102 | struct omap_hwmod **ohs, int oh_cnt, | ||
| 103 | struct omap_device_pm_latency *pm_lats, | ||
| 104 | int pm_lats_cnt); | ||
| 105 | static void omap_device_delete(struct omap_device *od); | ||
| 106 | |||
| 107 | |||
| 108 | static struct omap_device_pm_latency omap_default_latency[] = { | ||
| 109 | { | ||
| 110 | .deactivate_func = omap_device_idle_hwmods, | ||
| 111 | .activate_func = omap_device_enable_hwmods, | ||
| 112 | .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, | ||
| 113 | } | ||
| 114 | }; | ||
| 99 | 115 | ||
| 100 | /* Private functions */ | 116 | /* Private functions */ |
| 101 | 117 | ||
| @@ -303,6 +319,96 @@ static void _add_hwmod_clocks_clkdev(struct omap_device *od, | |||
| 303 | } | 319 | } |
| 304 | 320 | ||
| 305 | 321 | ||
| 322 | static struct dev_pm_domain omap_device_pm_domain; | ||
| 323 | |||
| 324 | /** | ||
| 325 | * omap_device_build_from_dt - build an omap_device with multiple hwmods | ||
| 326 | * @pdev_name: name of the platform_device driver to use | ||
| 327 | * @pdev_id: this platform_device's connection ID | ||
| 328 | * @oh: ptr to the single omap_hwmod that backs this omap_device | ||
| 329 | * @pdata: platform_data ptr to associate with the platform_device | ||
| 330 | * @pdata_len: amount of memory pointed to by @pdata | ||
| 331 | * @pm_lats: pointer to a omap_device_pm_latency array for this device | ||
| 332 | * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats | ||
| 333 | * @is_early_device: should the device be registered as an early device or not | ||
| 334 | * | ||
| 335 | * Function for building an omap_device already registered from device-tree | ||
| 336 | * | ||
| 337 | * Returns 0 or PTR_ERR() on error. | ||
| 338 | */ | ||
| 339 | static int omap_device_build_from_dt(struct platform_device *pdev) | ||
| 340 | { | ||
| 341 | struct omap_hwmod **hwmods; | ||
| 342 | struct omap_device *od; | ||
| 343 | struct omap_hwmod *oh; | ||
| 344 | struct device_node *node = pdev->dev.of_node; | ||
| 345 | const char *oh_name; | ||
| 346 | int oh_cnt, i, ret = 0; | ||
| 347 | |||
| 348 | oh_cnt = of_property_count_strings(node, "ti,hwmods"); | ||
| 349 | if (!oh_cnt || IS_ERR_VALUE(oh_cnt)) { | ||
| 350 | dev_warn(&pdev->dev, "No 'hwmods' to build omap_device\n"); | ||
| 351 | return -ENODEV; | ||
| 352 | } | ||
| 353 | |||
| 354 | hwmods = kzalloc(sizeof(struct omap_hwmod *) * oh_cnt, GFP_KERNEL); | ||
| 355 | if (!hwmods) { | ||
| 356 | ret = -ENOMEM; | ||
| 357 | goto odbfd_exit; | ||
| 358 | } | ||
| 359 | |||
| 360 | for (i = 0; i < oh_cnt; i++) { | ||
| 361 | of_property_read_string_index(node, "ti,hwmods", i, &oh_name); | ||
| 362 | oh = omap_hwmod_lookup(oh_name); | ||
| 363 | if (!oh) { | ||
| 364 | dev_err(&pdev->dev, "Cannot lookup hwmod '%s'\n", | ||
| 365 | oh_name); | ||
| 366 | ret = -EINVAL; | ||
| 367 | goto odbfd_exit1; | ||
| 368 | } | ||
| 369 | hwmods[i] = oh; | ||
| 370 | } | ||
| 371 | |||
| 372 | od = omap_device_alloc(pdev, hwmods, oh_cnt, NULL, 0); | ||
| 373 | if (!od) { | ||
| 374 | dev_err(&pdev->dev, "Cannot allocate omap_device for :%s\n", | ||
| 375 | oh_name); | ||
| 376 | ret = PTR_ERR(od); | ||
| 377 | goto odbfd_exit1; | ||
| 378 | } | ||
| 379 | |||
| 380 | if (of_get_property(node, "ti,no_idle_on_suspend", NULL)) | ||
| 381 | omap_device_disable_idle_on_suspend(pdev); | ||
| 382 | |||
| 383 | pdev->dev.pm_domain = &omap_device_pm_domain; | ||
| 384 | |||
| 385 | odbfd_exit1: | ||
| 386 | kfree(hwmods); | ||
| 387 | odbfd_exit: | ||
| 388 | return ret; | ||
| 389 | } | ||
| 390 | |||
| 391 | static int _omap_device_notifier_call(struct notifier_block *nb, | ||
| 392 | unsigned long event, void *dev) | ||
| 393 | { | ||
| 394 | struct platform_device *pdev = to_platform_device(dev); | ||
| 395 | |||
| 396 | switch (event) { | ||
| 397 | case BUS_NOTIFY_ADD_DEVICE: | ||
| 398 | if (pdev->dev.of_node) | ||
| 399 | omap_device_build_from_dt(pdev); | ||
| 400 | break; | ||
| 401 | |||
| 402 | case BUS_NOTIFY_DEL_DEVICE: | ||
| 403 | if (pdev->archdata.od) | ||
| 404 | omap_device_delete(pdev->archdata.od); | ||
| 405 | break; | ||
| 406 | } | ||
| 407 | |||
| 408 | return NOTIFY_DONE; | ||
| 409 | } | ||
| 410 | |||
| 411 | |||
| 306 | /* Public functions for use by core code */ | 412 | /* Public functions for use by core code */ |
| 307 | 413 | ||
| 308 | /** | 414 | /** |
| @@ -389,6 +495,113 @@ static int omap_device_fill_resources(struct omap_device *od, | |||
| 389 | } | 495 | } |
| 390 | 496 | ||
| 391 | /** | 497 | /** |
| 498 | * omap_device_alloc - allocate an omap_device | ||
| 499 | * @pdev: platform_device that will be included in this omap_device | ||
| 500 | * @oh: ptr to the single omap_hwmod that backs this omap_device | ||
| 501 | * @pdata: platform_data ptr to associate with the platform_device | ||
| 502 | * @pdata_len: amount of memory pointed to by @pdata | ||
| 503 | * @pm_lats: pointer to a omap_device_pm_latency array for this device | ||
| 504 | * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats | ||
| 505 | * | ||
| 506 | * Convenience function for allocating an omap_device structure and filling | ||
| 507 | * hwmods, resources and pm_latency attributes. | ||
| 508 | * | ||
| 509 | * Returns an struct omap_device pointer or ERR_PTR() on error; | ||
| 510 | */ | ||
| 511 | static struct omap_device *omap_device_alloc(struct platform_device *pdev, | ||
| 512 | struct omap_hwmod **ohs, int oh_cnt, | ||
| 513 | struct omap_device_pm_latency *pm_lats, | ||
| 514 | int pm_lats_cnt) | ||
| 515 | { | ||
| 516 | int ret = -ENOMEM; | ||
| 517 | struct omap_device *od; | ||
| 518 | struct resource *res = NULL; | ||
| 519 | int i, res_count; | ||
| 520 | struct omap_hwmod **hwmods; | ||
| 521 | |||
| 522 | od = kzalloc(sizeof(struct omap_device), GFP_KERNEL); | ||
| 523 | if (!od) { | ||
| 524 | ret = -ENOMEM; | ||
| 525 | goto oda_exit1; | ||
| 526 | } | ||
| 527 | od->hwmods_cnt = oh_cnt; | ||
| 528 | |||
| 529 | hwmods = kmemdup(ohs, sizeof(struct omap_hwmod *) * oh_cnt, GFP_KERNEL); | ||
| 530 | if (!hwmods) | ||
| 531 | goto oda_exit2; | ||
| 532 | |||
| 533 | od->hwmods = hwmods; | ||
| 534 | od->pdev = pdev; | ||
| 535 | |||
| 536 | /* | ||
| 537 | * HACK: Ideally the resources from DT should match, and hwmod | ||
| 538 | * should just add the missing ones. Since the name is not | ||
| 539 | * properly populated by DT, stick to hwmod resources only. | ||
| 540 | */ | ||
| 541 | if (pdev->num_resources && pdev->resource) | ||
| 542 | dev_warn(&pdev->dev, "%s(): resources already allocated %d\n", | ||
| 543 | __func__, pdev->num_resources); | ||
| 544 | |||
| 545 | res_count = omap_device_count_resources(od); | ||
| 546 | if (res_count > 0) { | ||
| 547 | dev_dbg(&pdev->dev, "%s(): resources allocated from hwmod %d\n", | ||
| 548 | __func__, res_count); | ||
| 549 | res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL); | ||
| 550 | if (!res) | ||
| 551 | goto oda_exit3; | ||
| 552 | |||
| 553 | omap_device_fill_resources(od, res); | ||
| 554 | |||
| 555 | ret = platform_device_add_resources(pdev, res, res_count); | ||
| 556 | kfree(res); | ||
| 557 | |||
| 558 | if (ret) | ||
| 559 | goto oda_exit3; | ||
| 560 | } | ||
| 561 | |||
| 562 | if (!pm_lats) { | ||
| 563 | pm_lats = omap_default_latency; | ||
| 564 | pm_lats_cnt = ARRAY_SIZE(omap_default_latency); | ||
| 565 | } | ||
| 566 | |||
| 567 | od->pm_lats_cnt = pm_lats_cnt; | ||
| 568 | od->pm_lats = kmemdup(pm_lats, | ||
| 569 | sizeof(struct omap_device_pm_latency) * pm_lats_cnt, | ||
| 570 | GFP_KERNEL); | ||
| 571 | if (!od->pm_lats) | ||
| 572 | goto oda_exit3; | ||
| 573 | |||
| 574 | pdev->archdata.od = od; | ||
| 575 | |||
| 576 | for (i = 0; i < oh_cnt; i++) { | ||
| 577 | hwmods[i]->od = od; | ||
| 578 | _add_hwmod_clocks_clkdev(od, hwmods[i]); | ||
| 579 | } | ||
| 580 | |||
| 581 | return od; | ||
| 582 | |||
| 583 | oda_exit3: | ||
| 584 | kfree(hwmods); | ||
| 585 | oda_exit2: | ||
| 586 | kfree(od); | ||
| 587 | oda_exit1: | ||
| 588 | dev_err(&pdev->dev, "omap_device: build failed (%d)\n", ret); | ||
| 589 | |||
| 590 | return ERR_PTR(ret); | ||
| 591 | } | ||
| 592 | |||
| 593 | static void omap_device_delete(struct omap_device *od) | ||
| 594 | { | ||
| 595 | if (!od) | ||
| 596 | return; | ||
| 597 | |||
| 598 | od->pdev->archdata.od = NULL; | ||
| 599 | kfree(od->pm_lats); | ||
| 600 | kfree(od->hwmods); | ||
| 601 | kfree(od); | ||
| 602 | } | ||
| 603 | |||
| 604 | /** | ||
| 392 | * omap_device_build - build and register an omap_device with one omap_hwmod | 605 | * omap_device_build - build and register an omap_device with one omap_hwmod |
| 393 | * @pdev_name: name of the platform_device driver to use | 606 | * @pdev_name: name of the platform_device driver to use |
| 394 | * @pdev_id: this platform_device's connection ID | 607 | * @pdev_id: this platform_device's connection ID |
| @@ -447,9 +660,6 @@ struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id, | |||
| 447 | int ret = -ENOMEM; | 660 | int ret = -ENOMEM; |
| 448 | struct platform_device *pdev; | 661 | struct platform_device *pdev; |
| 449 | struct omap_device *od; | 662 | struct omap_device *od; |
| 450 | struct resource *res = NULL; | ||
| 451 | int i, res_count; | ||
| 452 | struct omap_hwmod **hwmods; | ||
| 453 | 663 | ||
| 454 | if (!ohs || oh_cnt == 0 || !pdev_name) | 664 | if (!ohs || oh_cnt == 0 || !pdev_name) |
| 455 | return ERR_PTR(-EINVAL); | 665 | return ERR_PTR(-EINVAL); |
| @@ -463,67 +673,31 @@ struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id, | |||
| 463 | goto odbs_exit; | 673 | goto odbs_exit; |
| 464 | } | 674 | } |
| 465 | 675 | ||
| 466 | pr_debug("omap_device: %s: building with %d hwmods\n", pdev_name, | 676 | /* Set the dev_name early to allow dev_xxx in omap_device_alloc */ |
| 467 | oh_cnt); | 677 | if (pdev->id != -1) |
| 678 | dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id); | ||
| 679 | else | ||
| 680 | dev_set_name(&pdev->dev, "%s", pdev->name); | ||
| 468 | 681 | ||
| 469 | od = kzalloc(sizeof(struct omap_device), GFP_KERNEL); | 682 | od = omap_device_alloc(pdev, ohs, oh_cnt, pm_lats, pm_lats_cnt); |
| 470 | if (!od) { | 683 | if (!od) |
| 471 | ret = -ENOMEM; | ||
| 472 | goto odbs_exit1; | 684 | goto odbs_exit1; |
| 473 | } | ||
| 474 | od->hwmods_cnt = oh_cnt; | ||
| 475 | |||
| 476 | hwmods = kzalloc(sizeof(struct omap_hwmod *) * oh_cnt, | ||
| 477 | GFP_KERNEL); | ||
| 478 | if (!hwmods) | ||
| 479 | goto odbs_exit2; | ||
| 480 | |||
| 481 | memcpy(hwmods, ohs, sizeof(struct omap_hwmod *) * oh_cnt); | ||
| 482 | od->hwmods = hwmods; | ||
| 483 | od->pdev = pdev; | ||
| 484 | |||
| 485 | res_count = omap_device_count_resources(od); | ||
| 486 | if (res_count > 0) { | ||
| 487 | res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL); | ||
| 488 | if (!res) | ||
| 489 | goto odbs_exit3; | ||
| 490 | |||
| 491 | omap_device_fill_resources(od, res); | ||
| 492 | |||
| 493 | ret = platform_device_add_resources(pdev, res, res_count); | ||
| 494 | kfree(res); | ||
| 495 | |||
| 496 | if (ret) | ||
| 497 | goto odbs_exit3; | ||
| 498 | } | ||
| 499 | 685 | ||
| 500 | ret = platform_device_add_data(pdev, pdata, pdata_len); | 686 | ret = platform_device_add_data(pdev, pdata, pdata_len); |
| 501 | if (ret) | 687 | if (ret) |
| 502 | goto odbs_exit3; | 688 | goto odbs_exit2; |
| 503 | |||
| 504 | pdev->archdata.od = od; | ||
| 505 | 689 | ||
| 506 | if (is_early_device) | 690 | if (is_early_device) |
| 507 | ret = omap_early_device_register(pdev); | 691 | ret = omap_early_device_register(pdev); |
| 508 | else | 692 | else |
| 509 | ret = omap_device_register(pdev); | 693 | ret = omap_device_register(pdev); |
| 510 | if (ret) | 694 | if (ret) |
| 511 | goto odbs_exit3; | 695 | goto odbs_exit2; |
| 512 | |||
| 513 | od->pm_lats = pm_lats; | ||
| 514 | od->pm_lats_cnt = pm_lats_cnt; | ||
| 515 | |||
| 516 | for (i = 0; i < oh_cnt; i++) { | ||
| 517 | hwmods[i]->od = od; | ||
| 518 | _add_hwmod_clocks_clkdev(od, hwmods[i]); | ||
| 519 | } | ||
| 520 | 696 | ||
| 521 | return pdev; | 697 | return pdev; |
| 522 | 698 | ||
| 523 | odbs_exit3: | ||
| 524 | kfree(hwmods); | ||
| 525 | odbs_exit2: | 699 | odbs_exit2: |
| 526 | kfree(od); | 700 | omap_device_delete(od); |
| 527 | odbs_exit1: | 701 | odbs_exit1: |
| 528 | platform_device_put(pdev); | 702 | platform_device_put(pdev); |
| 529 | odbs_exit: | 703 | odbs_exit: |
| @@ -844,6 +1018,42 @@ void __iomem *omap_device_get_rt_va(struct omap_device *od) | |||
| 844 | return omap_hwmod_get_mpu_rt_va(od->hwmods[0]); | 1018 | return omap_hwmod_get_mpu_rt_va(od->hwmods[0]); |
| 845 | } | 1019 | } |
| 846 | 1020 | ||
| 1021 | /** | ||
| 1022 | * omap_device_get_by_hwmod_name() - convert a hwmod name to | ||
| 1023 | * device pointer. | ||
| 1024 | * @oh_name: name of the hwmod device | ||
| 1025 | * | ||
| 1026 | * Returns back a struct device * pointer associated with a hwmod | ||
| 1027 | * device represented by a hwmod_name | ||
| 1028 | */ | ||
| 1029 | struct device *omap_device_get_by_hwmod_name(const char *oh_name) | ||
| 1030 | { | ||
| 1031 | struct omap_hwmod *oh; | ||
| 1032 | |||
| 1033 | if (!oh_name) { | ||
| 1034 | WARN(1, "%s: no hwmod name!\n", __func__); | ||
| 1035 | return ERR_PTR(-EINVAL); | ||
| 1036 | } | ||
| 1037 | |||
| 1038 | oh = omap_hwmod_lookup(oh_name); | ||
| 1039 | if (IS_ERR_OR_NULL(oh)) { | ||
| 1040 | WARN(1, "%s: no hwmod for %s\n", __func__, | ||
| 1041 | oh_name); | ||
| 1042 | return ERR_PTR(oh ? PTR_ERR(oh) : -ENODEV); | ||
| 1043 | } | ||
| 1044 | if (IS_ERR_OR_NULL(oh->od)) { | ||
| 1045 | WARN(1, "%s: no omap_device for %s\n", __func__, | ||
| 1046 | oh_name); | ||
| 1047 | return ERR_PTR(oh->od ? PTR_ERR(oh->od) : -ENODEV); | ||
| 1048 | } | ||
| 1049 | |||
| 1050 | if (IS_ERR_OR_NULL(oh->od->pdev)) | ||
| 1051 | return ERR_PTR(oh->od->pdev ? PTR_ERR(oh->od->pdev) : -ENODEV); | ||
| 1052 | |||
| 1053 | return &oh->od->pdev->dev; | ||
| 1054 | } | ||
| 1055 | EXPORT_SYMBOL(omap_device_get_by_hwmod_name); | ||
| 1056 | |||
| 847 | /* | 1057 | /* |
| 848 | * Public functions intended for use in omap_device_pm_latency | 1058 | * Public functions intended for use in omap_device_pm_latency |
| 849 | * .activate_func and .deactivate_func function pointers | 1059 | * .activate_func and .deactivate_func function pointers |
| @@ -924,8 +1134,13 @@ struct device omap_device_parent = { | |||
| 924 | .parent = &platform_bus, | 1134 | .parent = &platform_bus, |
| 925 | }; | 1135 | }; |
| 926 | 1136 | ||
| 1137 | static struct notifier_block platform_nb = { | ||
| 1138 | .notifier_call = _omap_device_notifier_call, | ||
| 1139 | }; | ||
| 1140 | |||
| 927 | static int __init omap_device_init(void) | 1141 | static int __init omap_device_init(void) |
| 928 | { | 1142 | { |
| 1143 | bus_register_notifier(&platform_bus_type, &platform_nb); | ||
| 929 | return device_register(&omap_device_parent); | 1144 | return device_register(&omap_device_parent); |
| 930 | } | 1145 | } |
| 931 | core_initcall(omap_device_init); | 1146 | core_initcall(omap_device_init); |
diff --git a/drivers/of/base.c b/drivers/of/base.c index 3ff22e32b602..f7239b33d762 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c | |||
| @@ -662,6 +662,90 @@ int of_property_read_string(struct device_node *np, const char *propname, | |||
| 662 | EXPORT_SYMBOL_GPL(of_property_read_string); | 662 | EXPORT_SYMBOL_GPL(of_property_read_string); |
| 663 | 663 | ||
| 664 | /** | 664 | /** |
| 665 | * of_property_read_string_index - Find and read a string from a multiple | ||
| 666 | * strings property. | ||
| 667 | * @np: device node from which the property value is to be read. | ||
| 668 | * @propname: name of the property to be searched. | ||
| 669 | * @index: index of the string in the list of strings | ||
| 670 | * @out_string: pointer to null terminated return string, modified only if | ||
| 671 | * return value is 0. | ||
| 672 | * | ||
| 673 | * Search for a property in a device tree node and retrieve a null | ||
| 674 | * terminated string value (pointer to data, not a copy) in the list of strings | ||
| 675 | * contained in that property. | ||
| 676 | * Returns 0 on success, -EINVAL if the property does not exist, -ENODATA if | ||
| 677 | * property does not have a value, and -EILSEQ if the string is not | ||
| 678 | * null-terminated within the length of the property data. | ||
| 679 | * | ||
| 680 | * The out_string pointer is modified only if a valid string can be decoded. | ||
| 681 | */ | ||
| 682 | int of_property_read_string_index(struct device_node *np, const char *propname, | ||
| 683 | int index, const char **output) | ||
| 684 | { | ||
| 685 | struct property *prop = of_find_property(np, propname, NULL); | ||
| 686 | int i = 0; | ||
| 687 | size_t l = 0, total = 0; | ||
| 688 | const char *p; | ||
| 689 | |||
| 690 | if (!prop) | ||
| 691 | return -EINVAL; | ||
| 692 | if (!prop->value) | ||
| 693 | return -ENODATA; | ||
| 694 | if (strnlen(prop->value, prop->length) >= prop->length) | ||
| 695 | return -EILSEQ; | ||
| 696 | |||
| 697 | p = prop->value; | ||
| 698 | |||
| 699 | for (i = 0; total < prop->length; total += l, p += l) { | ||
| 700 | l = strlen(p) + 1; | ||
| 701 | if ((*p != 0) && (i++ == index)) { | ||
| 702 | *output = p; | ||
| 703 | return 0; | ||
| 704 | } | ||
| 705 | } | ||
| 706 | return -ENODATA; | ||
| 707 | } | ||
| 708 | EXPORT_SYMBOL_GPL(of_property_read_string_index); | ||
| 709 | |||
| 710 | |||
| 711 | /** | ||
| 712 | * of_property_count_strings - Find and return the number of strings from a | ||
| 713 | * multiple strings property. | ||
| 714 | * @np: device node from which the property value is to be read. | ||
| 715 | * @propname: name of the property to be searched. | ||
| 716 | * | ||
| 717 | * Search for a property in a device tree node and retrieve the number of null | ||
| 718 | * terminated string contain in it. Returns the number of strings on | ||
| 719 | * success, -EINVAL if the property does not exist, -ENODATA if property | ||
| 720 | * does not have a value, and -EILSEQ if the string is not null-terminated | ||
| 721 | * within the length of the property data. | ||
| 722 | */ | ||
| 723 | int of_property_count_strings(struct device_node *np, const char *propname) | ||
| 724 | { | ||
| 725 | struct property *prop = of_find_property(np, propname, NULL); | ||
| 726 | int i = 0; | ||
| 727 | size_t l = 0, total = 0; | ||
| 728 | const char *p; | ||
| 729 | |||
| 730 | if (!prop) | ||
| 731 | return -EINVAL; | ||
| 732 | if (!prop->value) | ||
| 733 | return -ENODATA; | ||
| 734 | if (strnlen(prop->value, prop->length) >= prop->length) | ||
| 735 | return -EILSEQ; | ||
| 736 | |||
| 737 | p = prop->value; | ||
| 738 | |||
| 739 | for (i = 0; total < prop->length; total += l, p += l) { | ||
| 740 | l = strlen(p) + 1; | ||
| 741 | if (*p != 0) | ||
| 742 | i++; | ||
| 743 | } | ||
| 744 | return i; | ||
| 745 | } | ||
| 746 | EXPORT_SYMBOL_GPL(of_property_count_strings); | ||
| 747 | |||
| 748 | /** | ||
| 665 | * of_parse_phandle - Resolve a phandle property to a device_node pointer | 749 | * of_parse_phandle - Resolve a phandle property to a device_node pointer |
| 666 | * @np: Pointer to device node holding phandle property | 750 | * @np: Pointer to device node holding phandle property |
| 667 | * @phandle_name: Name of property holding a phandle value | 751 | * @phandle_name: Name of property holding a phandle value |
diff --git a/include/linux/of.h b/include/linux/of.h index 9180dc5cb00b..5dfe2d5a8b5d 100644 --- a/include/linux/of.h +++ b/include/linux/of.h | |||
| @@ -203,6 +203,11 @@ extern int of_property_read_u32_array(const struct device_node *np, | |||
| 203 | extern int of_property_read_string(struct device_node *np, | 203 | extern int of_property_read_string(struct device_node *np, |
| 204 | const char *propname, | 204 | const char *propname, |
| 205 | const char **out_string); | 205 | const char **out_string); |
| 206 | extern int of_property_read_string_index(struct device_node *np, | ||
| 207 | const char *propname, | ||
| 208 | int index, const char **output); | ||
| 209 | extern int of_property_count_strings(struct device_node *np, | ||
| 210 | const char *propname); | ||
| 206 | extern int of_device_is_compatible(const struct device_node *device, | 211 | extern int of_device_is_compatible(const struct device_node *device, |
| 207 | const char *); | 212 | const char *); |
| 208 | extern int of_device_is_available(const struct device_node *device); | 213 | extern int of_device_is_available(const struct device_node *device); |
| @@ -256,6 +261,19 @@ static inline int of_property_read_string(struct device_node *np, | |||
| 256 | return -ENOSYS; | 261 | return -ENOSYS; |
| 257 | } | 262 | } |
| 258 | 263 | ||
| 264 | static inline int of_property_read_string_index(struct device_node *np, | ||
| 265 | const char *propname, int index, | ||
| 266 | const char **out_string) | ||
| 267 | { | ||
| 268 | return -ENOSYS; | ||
| 269 | } | ||
| 270 | |||
| 271 | static inline int of_property_count_strings(struct device_node *np, | ||
| 272 | const char *propname) | ||
| 273 | { | ||
| 274 | return -ENOSYS; | ||
| 275 | } | ||
| 276 | |||
| 259 | static inline const void *of_get_property(const struct device_node *node, | 277 | static inline const void *of_get_property(const struct device_node *node, |
| 260 | const char *name, | 278 | const char *name, |
| 261 | int *lenp) | 279 | int *lenp) |
