diff options
366 files changed, 8384 insertions, 8575 deletions
diff --git a/Documentation/IRQ-domain.txt b/Documentation/IRQ-domain.txt new file mode 100644 index 0000000..27dcaab --- /dev/null +++ b/Documentation/IRQ-domain.txt @@ -0,0 +1,117 @@ +irq_domain interrupt number mapping library + +The current design of the Linux kernel uses a single large number +space where each separate IRQ source is assigned a different number. +This is simple when there is only one interrupt controller, but in +systems with multiple interrupt controllers the kernel must ensure +that each one gets assigned non-overlapping allocations of Linux +IRQ numbers. + +The irq_alloc_desc*() and irq_free_desc*() APIs provide allocation of +irq numbers, but they don't provide any support for reverse mapping of +the controller-local IRQ (hwirq) number into the Linux IRQ number +space. + +The irq_domain library adds mapping between hwirq and IRQ numbers on +top of the irq_alloc_desc*() API. An irq_domain to manage mapping is +preferred over interrupt controller drivers open coding their own +reverse mapping scheme. + +irq_domain also implements translation from Device Tree interrupt +specifiers to hwirq numbers, and can be easily extended to support +other IRQ topology data sources. + +=== irq_domain usage === +An interrupt controller driver creates and registers an irq_domain by +calling one of the irq_domain_add_*() functions (each mapping method +has a different allocator function, more on that later). The function +will return a pointer to the irq_domain on success. The caller must +provide the allocator function with an irq_domain_ops structure with +the .map callback populated as a minimum. + +In most cases, the irq_domain will begin empty without any mappings +between hwirq and IRQ numbers. Mappings are added to the irq_domain +by calling irq_create_mapping() which accepts the irq_domain and a +hwirq number as arguments. If a mapping for the hwirq doesn't already +exist then it will allocate a new Linux irq_desc, associate it with +the hwirq, and call the .map() callback so the driver can perform any +required hardware setup. + +When an interrupt is received, irq_find_mapping() function should +be used to find the Linux IRQ number from the hwirq number. + +If the driver has the Linux IRQ number or the irq_data pointer, and +needs to know the associated hwirq number (such as in the irq_chip +callbacks) then it can be directly obtained from irq_data->hwirq. + +=== Types of irq_domain mappings === +There are several mechanisms available for reverse mapping from hwirq +to Linux irq, and each mechanism uses a different allocation function. +Which reverse map type should be used depends on the use case. Each +of the reverse map types are described below: + +==== Linear ==== +irq_domain_add_linear() + +The linear reverse map maintains a fixed size table indexed by the +hwirq number. When a hwirq is mapped, an irq_desc is allocated for +the hwirq, and the IRQ number is stored in the table. + +The Linear map is a good choice when the maximum number of hwirqs is +fixed and a relatively small number (~ < 256). The advantages of this +map are fixed time lookup for IRQ numbers, and irq_descs are only +allocated for in-use IRQs. The disadvantage is that the table must be +as large as the largest possible hwirq number. + +The majority of drivers should use the linear map. + +==== Tree ==== +irq_domain_add_tree() + +The irq_domain maintains a radix tree map from hwirq numbers to Linux +IRQs. When an hwirq is mapped, an irq_desc is allocated and the +hwirq is used as the lookup key for the radix tree. + +The tree map is a good choice if the hwirq number can be very large +since it doesn't need to allocate a table as large as the largest +hwirq number. The disadvantage is that hwirq to IRQ number lookup is +dependent on how many entries are in the table. + +Very few drivers should need this mapping. At the moment, powerpc +iseries is the only user. + +==== No Map ===- +irq_domain_add_nomap() + +The No Map mapping is to be used when the hwirq number is +programmable in the hardware. In this case it is best to program the +Linux IRQ number into the hardware itself so that no mapping is +required. Calling irq_create_direct_mapping() will allocate a Linux +IRQ number and call the .map() callback so that driver can program the +Linux IRQ number into the hardware. + +Most drivers cannot use this mapping. + +==== Legacy ==== +irq_domain_add_legacy() +irq_domain_add_legacy_isa() + +The Legacy mapping is a special case for drivers that already have a +range of irq_descs allocated for the hwirqs. It is used when the +driver cannot be immediately converted to use the linear mapping. For +example, many embedded system board support files use a set of #defines +for IRQ numbers that are passed to struct device registrations. In that +case the Linux IRQ numbers cannot be dynamically assigned and the legacy +mapping should be used. + +The legacy map assumes a contiguous range of IRQ numbers has already +been allocated for the controller and that the IRQ number can be +calculated by adding a fixed offset to the hwirq number, and +visa-versa. The disadvantage is that it requires the interrupt +controller to manage IRQ allocations and it requires an irq_desc to be +allocated for every hwirq, even if it is unused. + +The legacy map should only be used if fixed IRQ mappings must be +supported. For example, ISA controllers would use the legacy map for +mapping Linux IRQs 0-15 so that existing ISA drivers get the correct IRQ +numbers. diff --git a/Documentation/devicetree/bindings/arm/atmel-aic.txt b/Documentation/devicetree/bindings/arm/atmel-aic.txt new file mode 100644 index 0000000..aabca4f --- /dev/null +++ b/Documentation/devicetree/bindings/arm/atmel-aic.txt @@ -0,0 +1,38 @@ +* Advanced Interrupt Controller (AIC) + +Required properties: +- compatible: Should be "atmel,<chip>-aic" +- interrupt-controller: Identifies the node as an interrupt controller. +- interrupt-parent: For single AIC system, it is an empty property. +- #interrupt-cells: The number of cells to define the interrupts. It sould be 2. + The first cell is the IRQ number (aka "Peripheral IDentifier" on datasheet). + The second cell is used to specify flags: + bits[3:0] trigger type and level flags: + 1 = low-to-high edge triggered. + 2 = high-to-low edge triggered. + 4 = active high level-sensitive. + 8 = active low level-sensitive. + Valid combinations are 1, 2, 3, 4, 8. + Default flag for internal sources should be set to 4 (active high). +- reg: Should contain AIC registers location and length + +Examples: + /* + * AIC + */ + aic: interrupt-controller@fffff000 { + compatible = "atmel,at91rm9200-aic"; + interrupt-controller; + interrupt-parent; + #interrupt-cells = <2>; + reg = <0xfffff000 0x200>; + }; + + /* + * An interrupt generating device that is wired to an AIC. + */ + dma: dma-controller@ffffec00 { + compatible = "atmel,at91sam9g45-dma"; + reg = <0xffffec00 0x200>; + interrupts = <21 4>; + }; diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.txt b/Documentation/devicetree/bindings/arm/atmel-at91.txt new file mode 100644 index 0000000..1aeaf6f --- /dev/null +++ b/Documentation/devicetree/bindings/arm/atmel-at91.txt @@ -0,0 +1,32 @@ +Atmel AT91 device tree bindings. +================================ + +PIT Timer required properties: +- compatible: Should be "atmel,at91sam9260-pit" +- reg: Should contain registers location and length +- interrupts: Should contain interrupt for the PIT which is the IRQ line + shared across all System Controller members. + +TC/TCLIB Timer required properties: +- compatible: Should be "atmel,<chip>-pit". + <chip> can be "at91rm9200" or "at91sam9x5" +- reg: Should contain registers location and length +- interrupts: Should contain all interrupts for the TC block + Note that you can specify several interrupt cells if the TC + block has one interrupt per channel. + +Examples: + +One interrupt per TC block: + tcb0: timer@fff7c000 { + compatible = "atmel,at91rm9200-tcb"; + reg = <0xfff7c000 0x100>; + interrupts = <18 4>; + }; + +One interrupt per TC channel in a TC block: + tcb1: timer@fffdc000 { + compatible = "atmel,at91rm9200-tcb"; + reg = <0xfffdc000 0x100>; + interrupts = <26 4 27 4 28 4>; + }; diff --git a/Documentation/devicetree/bindings/arm/fsl.txt b/Documentation/devicetree/bindings/arm/fsl.txt index 54bddda..bfbc771 100644 --- a/Documentation/devicetree/bindings/arm/fsl.txt +++ b/Documentation/devicetree/bindings/arm/fsl.txt @@ -28,3 +28,25 @@ Required root node properties: i.MX6 Quad SABRE Lite Board Required root node properties: - compatible = "fsl,imx6q-sabrelite", "fsl,imx6q"; + +Generic i.MX boards +------------------- + +No iomux setup is done for these boards, so this must have been configured +by the bootloader for boards to work with the generic bindings. + +i.MX27 generic board +Required root node properties: + - compatible = "fsl,imx27"; + +i.MX51 generic board +Required root node properties: + - compatible = "fsl,imx51"; + +i.MX53 generic board +Required root node properties: + - compatible = "fsl,imx53"; + +i.MX6q generic board +Required root node properties: + - compatible = "fsl,imx6q"; diff --git a/Documentation/devicetree/bindings/arm/tegra/emc.txt b/Documentation/devicetree/bindings/arm/tegra/emc.txt new file mode 100644 index 0000000..09335f8 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/tegra/emc.txt @@ -0,0 +1,100 @@ +Embedded Memory Controller + +Properties: +- name : Should be emc +- #address-cells : Should be 1 +- #size-cells : Should be 0 +- compatible : Should contain "nvidia,tegra20-emc". +- reg : Offset and length of the register set for the device +- nvidia,use-ram-code : If present, the sub-nodes will be addressed + and chosen using the ramcode board selector. If omitted, only one + set of tables can be present and said tables will be used + irrespective of ram-code configuration. + +Child device nodes describe the memory settings for different configurations and clock rates. + +Example: + + emc@7000f400 { + #address-cells = < 1 >; + #size-cells = < 0 >; + compatible = "nvidia,tegra20-emc"; + reg = <0x7000f4000 0x200>; + } + + +Embedded Memory Controller ram-code table + +If the emc node has the nvidia,use-ram-code property present, then the +next level of nodes below the emc table are used to specify which settings +apply for which ram-code settings. + +If the emc node lacks the nvidia,use-ram-code property, this level is omitted +and the tables are stored directly under the emc node (see below). + +Properties: + +- name : Should be emc-tables +- nvidia,ram-code : the binary representation of the ram-code board strappings + for which this node (and children) are valid. + + + +Embedded Memory Controller configuration table + +This is a table containing the EMC register settings for the various +operating speeds of the memory controller. They are always located as +subnodes of the emc controller node. + +There are two ways of specifying which tables to use: + +* The simplest is if there is just one set of tables in the device tree, + and they will always be used (based on which frequency is used). + This is the preferred method, especially when firmware can fill in + this information based on the specific system information and just + pass it on to the kernel. + +* The slightly more complex one is when more than one memory configuration + might exist on the system. The Tegra20 platform handles this during + early boot by selecting one out of possible 4 memory settings based + on a 2-pin "ram code" bootstrap setting on the board. The values of + these strappings can be read through a register in the SoC, and thus + used to select which tables to use. + +Properties: +- name : Should be emc-table +- compatible : Should contain "nvidia,tegra20-emc-table". +- reg : either an opaque enumerator to tell different tables apart, or + the valid frequency for which the table should be used (in kHz). +- clock-frequency : the clock frequency for the EMC at which this + table should be used (in kHz). +- nvidia,emc-registers : a 46 word array of EMC registers to be programmed + for operation at the 'clock-frequency' setting. + The order and contents of the registers are: + RC, RFC, RAS, RP, R2W, W2R, R2P, W2P, RD_RCD, WR_RCD, RRD, REXT, + WDV, QUSE, QRST, QSAFE, RDV, REFRESH, BURST_REFRESH_NUM, PDEX2WR, + PDEX2RD, PCHG2PDEN, ACT2PDEN, AR2PDEN, RW2PDEN, TXSR, TCKE, TFAW, + TRPAB, TCLKSTABLE, TCLKSTOP, TREFBW, QUSE_EXTRA, FBIO_CFG6, ODT_WRITE, + ODT_READ, FBIO_CFG5, CFG_DIG_DLL, DLL_XFORM_DQS, DLL_XFORM_QUSE, + ZCAL_REF_CNT, ZCAL_WAIT_CNT, AUTO_CAL_INTERVAL, CFG_CLKTRIM_0, + CFG_CLKTRIM_1, CFG_CLKTRIM_2 + + emc-table@166000 { + reg = <166000>; + compatible = "nvidia,tegra20-emc-table"; + clock-frequency = < 166000 >; + nvidia,emc-registers = < 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 >; + }; + + emc-table@333000 { + reg = <333000>; + compatible = "nvidia,tegra20-emc-table"; + clock-frequency = < 333000 >; + nvidia,emc-registers = < 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 >; + }; diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt new file mode 100644 index 0000000..b5846e2 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt @@ -0,0 +1,19 @@ +NVIDIA Tegra Power Management Controller (PMC) + +Properties: +- name : Should be pmc +- compatible : Should contain "nvidia,tegra<chip>-pmc". +- reg : Offset and length of the register set for the device +- nvidia,invert-interrupt : If present, inverts the PMU interrupt signal. + The PMU is an external Power Management Unit, whose interrupt output + signal is fed into the PMC. This signal is optionally inverted, and then + fed into the ARM GIC. The PMC is not involved in the detection or + handling of this interrupt signal, merely its inversion. + +Example: + +pmc@7000f400 { + compatible = "nvidia,tegra20-pmc"; + reg = <0x7000e400 0x400>; + nvidia,invert-interrupt; +}; diff --git a/Documentation/devicetree/bindings/arm/vexpress.txt b/Documentation/devicetree/bindings/arm/vexpress.txt new file mode 100644 index 0000000..ec8b50c --- /dev/null +++ b/Documentation/devicetree/bindings/arm/vexpress.txt @@ -0,0 +1,146 @@ +ARM Versatile Express boards family +----------------------------------- + +ARM's Versatile Express platform consists of a motherboard and one +or more daughterboards (tiles). The motherboard provides a set of +peripherals. Processor and RAM "live" on the tiles. + +The motherboard and each core tile should be described by a separate +Device Tree source file, with the tile's description including +the motherboard file using a /include/ directive. As the motherboard +can be initialized in one of two different configurations ("memory +maps"), care must be taken to include the correct one. + +Required properties in the root node: +- compatible value: + compatible = "arm,vexpress,<model>", "arm,vexpress"; + where <model> is the full tile model name (as used in the tile's + Technical Reference Manual), eg.: + - for Coretile Express A5x2 (V2P-CA5s): + compatible = "arm,vexpress,v2p-ca5s", "arm,vexpress"; + - for Coretile Express A9x4 (V2P-CA9): + compatible = "arm,vexpress,v2p-ca9", "arm,vexpress"; + If a tile comes in several variants or can be used in more then one + configuration, the compatible value should be: + compatible = "arm,vexpress,<model>,<variant>", \ + "arm,vexpress,<model>", "arm,vexpress"; + eg: + - Coretile Express A15x2 (V2P-CA15) with Tech Chip 1: + compatible = "arm,vexpress,v2p-ca15,tc1", \ + "arm,vexpress,v2p-ca15", "arm,vexpress"; + - LogicTile Express 13MG (V2F-2XV6) running Cortex-A7 (3 cores) SMM: + compatible = "arm,vexpress,v2f-2xv6,ca7x3", \ + "arm,vexpress,v2f-2xv6", "arm,vexpress"; + +Optional properties in the root node: +- tile model name (use name from the tile's Technical Reference + Manual, eg. "V2P-CA5s") + model = "<model>"; +- tile's HBI number (unique ARM's board model ID, visible on the + PCB's silkscreen) in hexadecimal transcription: + arm,hbi = <0xhbi> + eg: + - for Coretile Express A5x2 (V2P-CA5s) HBI-0191: + arm,hbi = <0x191>; + - Coretile Express A9x4 (V2P-CA9) HBI-0225: + arm,hbi = <0x225>; + +Top-level standard "cpus" node is required. It must contain a node +with device_type = "cpu" property for every available core, eg.: + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a5"; + reg = <0>; + }; + }; + +The motherboard description file provides a single "motherboard" node +using 2 address cells corresponding to the Static Memory Bus used +between the motherboard and the tile. The first cell defines the Chip +Select (CS) line number, the second cell address offset within the CS. +All interrupt lines between the motherboard and the tile are active +high and are described using single cell. + +Optional properties of the "motherboard" node: +- motherboard's memory map variant: + arm,v2m-memory-map = "<name>"; + where name is one of: + - "rs1" - for RS1 map (i.a. peripherals on CS3); this map is also + referred to as "ARM Cortex-A Series memory map": + arm,v2m-memory-map = "rs1"; + When this property is missing, the motherboard is using the original + memory map (also known as the "Legacy memory map", primarily used + with the original CoreTile Express A9x4) with peripherals on CS7. + +Motherboard .dtsi files provide a set of labelled peripherals that +can be used to obtain required phandle in the tile's "aliases" node: +- UARTs, note that the numbers correspond to the physical connectors + on the motherboard's back panel: + v2m_serial0, v2m_serial1, v2m_serial2 and v2m_serial3 +- I2C controllers: + v2m_i2c_dvi and v2m_i2c_pcie +- SP804 timers: + v2m_timer01 and v2m_timer23 + +Current Linux implementation requires a "arm,v2m_timer" alias +pointing at one of the motherboard's SP804 timers, if it is to be +used as the system timer. This alias should be defined in the +motherboard files. + +The tile description must define "ranges", "interrupt-map-mask" and +"interrupt-map" properties to translate the motherboard's address +and interrupt space into one used by the tile's processor. + +Abbreviated example: + +/dts-v1/; + +/ { + model = "V2P-CA5s"; + arm,hbi = <0x225>; + compatible = "arm,vexpress-v2p-ca5s", "arm,vexpress"; + interrupt-parent = <&gic>; + #address-cells = <1>; + #size-cells = <1>; + + chosen { }; + + aliases { + serial0 = &v2m_serial0; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a5"; + reg = <0>; + }; + }; + + gic: interrupt-controller@2c001000 { + compatible = "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0x2c001000 0x1000>, + <0x2c000100 0x100>; + }; + + motherboard { + /* CS0 is visible at 0x08000000 */ + ranges = <0 0 0x08000000 0x04000000>; + interrupt-map-mask = <0 0 63>; + /* Active high IRQ 0 is connected to GIC's SPI0 */ + interrupt-map = <0 0 0 &gic 0 0 4>; + }; +}; + +/include/ "vexpress-v2m-rs1.dtsi" diff --git a/Documentation/devicetree/bindings/dma/tegra20-apbdma.txt b/Documentation/devicetree/bindings/dma/tegra20-apbdma.txt new file mode 100644 index 0000000..90fa7da --- /dev/null +++ b/Documentation/devicetree/bindings/dma/tegra20-apbdma.txt @@ -0,0 +1,30 @@ +* NVIDIA Tegra APB DMA controller + +Required properties: +- compatible: Should be "nvidia,<chip>-apbdma" +- reg: Should contain DMA registers location and length. This shuld include + all of the per-channel registers. +- interrupts: Should contain all of the per-channel DMA interrupts. + +Examples: + +apbdma: dma@6000a000 { + compatible = "nvidia,tegra20-apbdma"; + reg = <0x6000a000 0x1200>; + interrupts = < 0 136 0x04 + 0 137 0x04 + 0 138 0x04 + 0 139 0x04 + 0 140 0x04 + 0 141 0x04 + 0 142 0x04 + 0 143 0x04 + 0 144 0x04 + 0 145 0x04 + 0 146 0x04 + 0 147 0x04 + 0 148 0x04 + 0 149 0x04 + 0 150 0x04 + 0 151 0x04 >; +}; diff --git a/Documentation/devicetree/bindings/gpio/gpio_atmel.txt b/Documentation/devicetree/bindings/gpio/gpio_atmel.txt new file mode 100644 index 0000000..66efc80 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/gpio_atmel.txt @@ -0,0 +1,20 @@ +* Atmel GPIO controller (PIO) + +Required properties: +- compatible: "atmel,<chip>-gpio", where <chip> is at91rm9200 or at91sam9x5. +- reg: Should contain GPIO controller registers location and length +- interrupts: Should be the port interrupt shared by all the pins. +- #gpio-cells: Should be two. The first cell is the pin number and + the second cell is used to specify optional parameters (currently + unused). +- gpio-controller: Marks the device node as a GPIO controller. + +Example: + pioA: gpio@fffff200 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff200 0x100>; + interrupts = <2 4>; + #gpio-cells = <2>; + gpio-controller; + }; + diff --git a/Documentation/devicetree/bindings/gpio/gpio_nvidia.txt b/Documentation/devicetree/bindings/gpio/gpio_nvidia.txt index eb4b530..50b363c 100644 --- a/Documentation/devicetree/bindings/gpio/gpio_nvidia.txt +++ b/Documentation/devicetree/bindings/gpio/gpio_nvidia.txt @@ -2,7 +2,25 @@ NVIDIA Tegra 2 GPIO controller Required properties: - compatible : "nvidia,tegra20-gpio" +- reg : Physical base address and length of the controller's registers. +- interrupts : The interrupt outputs from the controller. - #gpio-cells : Should be two. The first cell is the pin number and the second cell is used to specify optional parameters: - bit 0 specifies polarity (0 for normal, 1 for inverted) - gpio-controller : Marks the device node as a GPIO controller. + +Example: + +gpio: gpio@6000d000 { + compatible = "nvidia,tegra20-gpio"; + reg = < 0x6000d000 0x1000 >; + interrupts = < 0 32 0x04 + 0 33 0x04 + 0 34 0x04 + 0 35 0x04 + 0 55 0x04 + 0 87 0x04 + 0 89 0x04 >; + #gpio-cells = <2>; + gpio-controller; +}; diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index a0ffac0..1bea46a 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -510,17 +510,3 @@ Why: The pci_scan_bus_parented() interface creates a new root bus. The convert to using pci_scan_root_bus() so they can supply a list of bus resources when the bus is created. Who: Bjorn Helgaas <bhelgaas@google.com> - ----------------------------- - -What: The CAP9 SoC family will be removed -When: 3.4 -Files: arch/arm/mach-at91/at91cap9.c - arch/arm/mach-at91/at91cap9_devices.c - arch/arm/mach-at91/include/mach/at91cap9.h - arch/arm/mach-at91/include/mach/at91cap9_matrix.h - arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h - arch/arm/mach-at91/board-cap9adk.c -Why: The code is not actively maintained and platforms are now hard to find. -Who: Nicolas Ferre <nicolas.ferre@atmel.com> - Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> diff --git a/MAINTAINERS b/MAINTAINERS index 4e41d52..f096b0d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3638,6 +3638,15 @@ S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core F: kernel/irq/ +IRQ DOMAINS (IRQ NUMBER MAPPING LIBRARY) +M: Benjamin Herrenschmidt <benh@kernel.crashing.org> +M: Grant Likely <grant.likely@secretlab.ca> +T: git git://git.secretlab.ca/git/linux-2.6.git irqdomain/next +S: Maintained +F: Documentation/IRQ-domain.txt +F: include/linux/irqdomain.h +F: kernel/irq/irqdomain.c + ISAPNP M: Jaroslav Kysela <perex@perex.cz> S: Maintained diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index a48aecc..cabd8f5 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -322,9 +322,10 @@ config ARCH_AT91 select ARCH_REQUIRE_GPIOLIB select HAVE_CLK select CLKDEV_LOOKUP + select IRQ_DOMAIN help This enables support for systems based on the Atmel AT91RM9200, - AT91SAM9 and AT91CAP9 processors. + AT91SAM9 processors. config ARCH_BCMRING bool "Broadcom BCMRING" diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index e0d236d..b895a2a 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -81,47 +81,14 @@ choice prompt "Kernel low-level debugging port" depends on DEBUG_LL - config DEBUG_LL_UART_NONE - bool "No low-level debugging UART" - help - Say Y here if your platform doesn't provide a UART option - below. This relies on your platform choosing the right UART - definition internally in order for low-level debugging to - work. - - config DEBUG_ICEDCC - bool "Kernel low-level debugging via EmbeddedICE DCC channel" - help - Say Y here if you want the debug print routines to direct - their output to the EmbeddedICE macrocell's DCC channel using - co-processor 14. This is known to work on the ARM9 style ICE - channel and on the XScale with the PEEDI. - - Note that the system will appear to hang during boot if there - is nothing connected to read from the DCC. - config AT91_DEBUG_LL_DBGU0 bool "Kernel low-level debugging on rm9200, 9260/9g20, 9261/9g10 and 9rl" depends on HAVE_AT91_DBGU0 config AT91_DEBUG_LL_DBGU1 - bool "Kernel low-level debugging on 9263, 9g45 and cap9" + bool "Kernel low-level debugging on 9263 and 9g45" depends on HAVE_AT91_DBGU1 - config DEBUG_FOOTBRIDGE_COM1 - bool "Kernel low-level debugging messages via footbridge 8250 at PCI COM1" - depends on FOOTBRIDGE - help - Say Y here if you want the debug print routines to direct - their output to the 8250 at PCI COM1. - - config DEBUG_DC21285_PORT - bool "Kernel low-level debugging messages via footbridge serial port" - depends on FOOTBRIDGE - help - Say Y here if you want the debug print routines to direct - their output to the serial port in the DC21285 (Footbridge). - config DEBUG_CLPS711X_UART1 bool "Kernel low-level debugging messages via UART1" depends on ARCH_CLPS711X @@ -136,6 +103,20 @@ choice Say Y here if you want the debug print routines to direct their output to the second serial port on these devices. + config DEBUG_DC21285_PORT + bool "Kernel low-level debugging messages via footbridge serial port" + depends on FOOTBRIDGE + help + Say Y here if you want the debug print routines to direct + their output to the serial port in the DC21285 (Footbridge). + + config DEBUG_FOOTBRIDGE_COM1 + bool "Kernel low-level debugging messages via footbridge 8250 at PCI COM1" + depends on FOOTBRIDGE + help + Say Y here if you want the debug print routines to direct + their output to the 8250 at PCI COM1. + config DEBUG_HIGHBANK_UART bool "Kernel low-level debugging messages via Highbank UART" depends on ARCH_HIGHBANK @@ -206,38 +187,42 @@ choice Say Y here if you want kernel low-level debugging support on i.MX6Q. - config DEBUG_S3C_UART0 - depends on PLAT_SAMSUNG - bool "Use S3C UART 0 for low-level debug" + config DEBUG_MSM_UART1 + bool "Kernel low-level debugging messages via MSM UART1" + depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50 help Say Y here if you want the debug print routines to direct - their output to UART 0. The port must have been initialised - by the boot-loader before use. - - The uncompressor code port configuration is now handled - by CONFIG_S3C_LOWLEVEL_UART_PORT. + their output to the first serial port on MSM devices. - config DEBUG_S3C_UART1 - depends on PLAT_SAMSUNG - bool "Use S3C UART 1 for low-level debug" + config DEBUG_MSM_UART2 + bool "Kernel low-level debugging messages via MSM UART2" + depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50 help Say Y here if you want the debug print routines to direct - their output to UART 1. The port must have been initialised - by the boot-loader before use. + their output to the second serial port on MSM devices. - The uncompressor code port configuration is now handled - by CONFIG_S3C_LOWLEVEL_UART_PORT. + config DEBUG_MSM_UART3 + bool "Kernel low-level debugging messages via MSM UART3" + depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50 + help + Say Y here if you want the debug print routines to direct + their output to the third serial port on MSM devices. - config DEBUG_S3C_UART2 - depends on PLAT_SAMSUNG - bool "Use S3C UART 2 for low-level debug" + config DEBUG_MSM8660_UART + bool "Kernel low-level debugging messages via MSM 8660 UART" + depends on ARCH_MSM8X60 + select MSM_HAS_DEBUG_UART_HS help Say Y here if you want the debug print routines to direct - their output to UART 2. The port must have been initialised - by the boot-loader before use. + their output to the serial port on MSM 8660 devices. - The uncompressor code port configuration is now handled - by CONFIG_S3C_LOWLEVEL_UART_PORT. + config DEBUG_MSM8960_UART + bool "Kernel low-level debugging messages via MSM 8960 UART" + depends on ARCH_MSM8960 + select MSM_HAS_DEBUG_UART_HS + help + Say Y here if you want the debug print routines to direct + their output to the serial port on MSM 8960 devices. config DEBUG_REALVIEW_STD_PORT bool "RealView Default UART" @@ -255,42 +240,57 @@ choice their output to the standard serial port on the RealView PB1176 platform. - config DEBUG_MSM_UART1 - bool "Kernel low-level debugging messages via MSM UART1" - depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50 + config DEBUG_S3C_UART0 + depends on PLAT_SAMSUNG + bool "Use S3C UART 0 for low-level debug" help Say Y here if you want the debug print routines to direct - their output to the first serial port on MSM devices. + their output to UART 0. The port must have been initialised + by the boot-loader before use. - config DEBUG_MSM_UART2 - bool "Kernel low-level debugging messages via MSM UART2" - depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50 + The uncompressor code port configuration is now handled + by CONFIG_S3C_LOWLEVEL_UART_PORT. + + config DEBUG_S3C_UART1 + depends on PLAT_SAMSUNG + bool "Use S3C UART 1 for low-level debug" help Say Y here if you want the debug print routines to direct - their output to the second serial port on MSM devices. + their output to UART 1. The port must have been initialised + by the boot-loader before use. - config DEBUG_MSM_UART3 - bool "Kernel low-level debugging messages via MSM UART3" - depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50 + The uncompressor code port configuration is now handled + by CONFIG_S3C_LOWLEVEL_UART_PORT. + + config DEBUG_S3C_UART2 + depends on PLAT_SAMSUNG + bool "Use S3C UART 2 for low-level debug" help Say Y here if you want the debug print routines to direct - their output to the third serial port on MSM devices. + their output to UART 2. The port must have been initialised + by the boot-loader before use. - config DEBUG_MSM8660_UART - bool "Kernel low-level debugging messages via MSM 8660 UART" - depends on ARCH_MSM8X60 - select MSM_HAS_DEBUG_UART_HS + The uncompressor code port configuration is now handled + by CONFIG_S3C_LOWLEVEL_UART_PORT. + + config DEBUG_LL_UART_NONE + bool "No low-level debugging UART" help - Say Y here if you want the debug print routines to direct - their output to the serial port on MSM 8660 devices. + Say Y here if your platform doesn't provide a UART option + below. This relies on your platform choosing the right UART + definition internally in order for low-level debugging to + work. - config DEBUG_MSM8960_UART - bool "Kernel low-level debugging messages via MSM 8960 UART" - depends on ARCH_MSM8960 - select MSM_HAS_DEBUG_UART_HS + config DEBUG_ICEDCC + bool "Kernel low-level debugging via EmbeddedICE DCC channel" help Say Y here if you want the debug print routines to direct - their output to the serial port on MSM 8960 devices. + their output to the EmbeddedICE macrocell's DCC channel using + co-processor 14. This is known to work on the ARM9 style ICE + channel and on the XScale with the PEEDI. + + Note that the system will appear to hang during boot if there + is nothing connected to read from the DCC. endchoice diff --git a/arch/arm/boot/dts/at91sam9g20.dtsi b/arch/arm/boot/dts/at91sam9g20.dtsi index 07603b8..a100db0 100644 --- a/arch/arm/boot/dts/at91sam9g20.dtsi +++ b/arch/arm/boot/dts/at91sam9g20.dtsi @@ -23,6 +23,11 @@ serial4 = &usart3; serial5 = &usart4; serial6 = &usart5; + gpio0 = &pioA; + gpio1 = &pioB; + gpio2 = &pioC; + tcb0 = &tcb0; + tcb1 = &tcb1; }; cpus { cpu@0 { @@ -47,24 +52,69 @@ ranges; aic: interrupt-controller@fffff000 { - #interrupt-cells = <1>; + #interrupt-cells = <2>; compatible = "atmel,at91rm9200-aic"; interrupt-controller; interrupt-parent; reg = <0xfffff000 0x200>; }; + pit: timer@fffffd30 { + compatible = "atmel,at91sam9260-pit"; + reg = <0xfffffd30 0xf>; + interrupts = <1 4>; + }; + + tcb0: timer@fffa0000 { + compatible = "atmel,at91rm9200-tcb"; + reg = <0xfffa0000 0x100>; + interrupts = <17 4 18 4 19 4>; + }; + + tcb1: timer@fffdc000 { + compatible = "atmel,at91rm9200-tcb"; + reg = <0xfffdc000 0x100>; + interrupts = <26 4 27 4 28 4>; + }; + + pioA: gpio@fffff400 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff400 0x100>; + interrupts = <2 4>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + }; + + pioB: gpio@fffff600 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff600 0x100>; + interrupts = <3 4>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + }; + + pioC: gpio@fffff800 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff800 0x100>; + interrupts = <4 4>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + }; + dbgu: serial@fffff200 { compatible = "atmel,at91sam9260-usart"; reg = <0xfffff200 0x200>; - interrupts = <1>; + interrupts = <1 4>; status = "disabled"; }; usart0: serial@fffb0000 { compatible = "atmel,at91sam9260-usart"; reg = <0xfffb0000 0x200>; - interrupts = <6>; + interrupts = <6 4>; atmel,use-dma-rx; atmel,use-dma-tx; status = "disabled"; @@ -73,7 +123,7 @@ usart1: serial@fffb4000 { compatible = "atmel,at91sam9260-usart"; reg = <0xfffb4000 0x200>; - interrupts = <7>; + interrupts = <7 4>; atmel,use-dma-rx; atmel,use-dma-tx; status = "disabled"; @@ -82,7 +132,7 @@ usart2: serial@fffb8000 { compatible = "atmel,at91sam9260-usart"; reg = <0xfffb8000 0x200>; - interrupts = <8>; + interrupts = <8 4>; atmel,use-dma-rx; atmel,use-dma-tx; status = "disabled"; @@ -91,7 +141,7 @@ usart3: serial@fffd0000 { compatible = "atmel,at91sam9260-usart"; reg = <0xfffd0000 0x200>; - interrupts = <23>; + interrupts = <23 4>; atmel,use-dma-rx; atmel,use-dma-tx; status = "disabled"; @@ -100,7 +150,7 @@ usart4: serial@fffd4000 { compatible = "atmel,at91sam9260-usart"; reg = <0xfffd4000 0x200>; - interrupts = <24>; + interrupts = <24 4>; atmel,use-dma-rx; atmel,use-dma-tx; status = "disabled"; @@ -109,7 +159,7 @@ usart5: serial@fffd8000 { compatible = "atmel,at91sam9260-usart"; reg = <0xfffd8000 0x200>; - interrupts = <25>; + interrupts = <25 4>; atmel,use-dma-rx; atmel,use-dma-tx; status = "disabled"; @@ -118,7 +168,7 @@ macb0: ethernet@fffc4000 { compatible = "cdns,at32ap7000-macb", "cdns,macb"; reg = <0xfffc4000 0x100>; - interrupts = <21>; + interrupts = <21 4>; status = "disabled"; }; }; diff --git a/arch/arm/boot/dts/at91sam9g25ek.dts b/arch/arm/boot/dts/at91sam9g25ek.dts new file mode 100644 index 0000000..e64eb93 --- /dev/null +++ b/arch/arm/boot/dts/at91sam9g25ek.dts @@ -0,0 +1,37 @@ +/* + * at91sam9g25ek.dts - Device Tree file for AT91SAM9G25-EK board + * + * Copyright (C) 2012 Atmel, + * 2012 Nicolas Ferre <nicolas.ferre@atmel.com> + * + * Licensed under GPLv2 or later. + */ +/dts-v1/; +/include/ "at91sam9x5.dtsi" +/include/ "at91sam9x5cm.dtsi" + +/ { + model = "Atmel AT91SAM9G25-EK"; + compatible = "atmel,at91sam9g25ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9"; + + chosen { + bootargs = "128M console=ttyS0,115200 mtdparts=atmel_nand:8M(bootstrap/uboot/kernel)ro,-(rootfs) root=/dev/mtdblock1 rw rootfstype=ubifs ubi.mtd=1 root=ubi0:rootfs"; + }; + + ahb { + apb { + dbgu: serial@fffff200 { + status = "okay"; + }; + + usart0: serial@f801c000 { + status = "okay"; + }; + + macb0: ethernet@f802c000 { + phy-mode = "rmii"; + status = "okay"; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index fffa005..f779667 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi @@ -22,6 +22,13 @@ serial2 = &usart1; serial3 = &usart2; serial4 = &usart3; + gpio0 = &pioA; + gpio1 = &pioB; + gpio2 = &pioC; + gpio3 = &pioD; + gpio4 = &pioE; + tcb0 = &tcb0; + tcb1 = &tcb1; }; cpus { cpu@0 { @@ -46,30 +53,94 @@ ranges; aic: interrupt-controller@fffff000 { - #interrupt-cells = <1>; + #interrupt-cells = <2>; compatible = "atmel,at91rm9200-aic"; interrupt-controller; interrupt-parent; reg = <0xfffff000 0x200>; }; + pit: timer@fffffd30 { + compatible = "atmel,at91sam9260-pit"; + reg = <0xfffffd30 0xf>; + interrupts = <1 4>; + }; + + + tcb0: timer@fff7c000 { + compatible = "atmel,at91rm9200-tcb"; + reg = <0xfff7c000 0x100>; + interrupts = <18 4>; + }; + + tcb1: timer@fffd4000 { + compatible = "atmel,at91rm9200-tcb"; + reg = <0xfffd4000 0x100>; + interrupts = <18 4>; + }; + dma: dma-controller@ffffec00 { compatible = "atmel,at91sam9g45-dma"; reg = <0xffffec00 0x200>; - interrupts = <21>; + interrupts = <21 4>; + }; + + pioA: gpio@fffff200 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff200 0x100>; + interrupts = <2 4>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + }; + + pioB: gpio@fffff400 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff400 0x100>; + interrupts = <3 4>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + }; + + pioC: gpio@fffff600 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff600 0x100>; + interrupts = <4 4>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + }; + + pioD: gpio@fffff800 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff800 0x100>; + interrupts = <5 4>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + }; + + pioE: gpio@fffffa00 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffffa00 0x100>; + interrupts = <5 4>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; }; dbgu: serial@ffffee00 { compatible = "atmel,at91sam9260-usart"; reg = <0xffffee00 0x200>; - interrupts = <1>; + interrupts = <1 4>; status = "disabled"; }; usart0: serial@fff8c000 { compatible = "atmel,at91sam9260-usart"; reg = <0xfff8c000 0x200>; - interrupts = <7>; + interrupts = <7 4>; atmel,use-dma-rx; atmel,use-dma-tx; status = "disabled"; @@ -78,7 +149,7 @@ usart1: serial@fff90000 { compatible = "atmel,at91sam9260-usart"; reg = <0xfff90000 0x200>; - interrupts = <8>; + interrupts = <8 4>; atmel,use-dma-rx; atmel,use-dma-tx; status = "disabled"; @@ -87,7 +158,7 @@ usart2: serial@fff94000 { compatible = "atmel,at91sam9260-usart"; reg = <0xfff94000 0x200>; - interrupts = <9>; + interrupts = <9 4>; atmel,use-dma-rx; atmel,use-dma-tx; status = "disabled"; @@ -96,7 +167,7 @@ usart3: serial@fff98000 { compatible = "atmel,at91sam9260-usart"; reg = <0xfff98000 0x200>; - interrupts = <10>; + interrupts = <10 4>; atmel,use-dma-rx; atmel,use-dma-tx; status = "disabled"; @@ -105,7 +176,7 @@ macb0: ethernet@fffbc000 { compatible = "cdns,at32ap7000-macb", "cdns,macb"; reg = <0xfffbc000 0x100>; - interrupts = <25>; + interrupts = <25 4>; status = "disabled"; }; }; diff --git a/arch/arm/boot/dts/at91sam9m10g45ek.dts b/arch/arm/boot/dts/at91sam9m10g45ek.dts index a387e77..15e25f9 100644 --- a/arch/arm/boot/dts/at91sam9m10g45ek.dts +++ b/arch/arm/boot/dts/at91sam9m10g45ek.dts @@ -37,4 +37,76 @@ }; }; }; + + leds { + compatible = "gpio-leds"; + + d8 { + label = "d8"; + gpios = <&pioD 30 0>; + linux,default-trigger = "heartbeat"; + }; + + d6 { + label = "d6"; + gpios = <&pioD 0 1>; + linux,default-trigger = "nand-disk"; + }; + + d7 { + label = "d7"; + gpios = <&pioD 31 1>; + linux,default-trigger = "mmc0"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + left_click { + label = "left_click"; + gpios = <&pioB 6 1>; + linux,code = <272>; + gpio-key,wakeup; + }; + + right_click { + label = "right_click"; + gpios = <&pioB 7 1>; + linux,code = <273>; + gpio-key,wakeup; + }; + + left { + label = "Joystick Left"; + gpios = <&pioB 14 1>; + linux,code = <105>; + }; + + right { + label = "Joystick Right"; + gpios = <&pioB 15 1>; + linux,code = <106>; + }; + + up { + label = "Joystick Up"; + gpios = <&pioB 16 1>; + linux,code = <103>; + }; + + down { + label = "Joystick Down"; + gpios = <&pioB 17 1>; + linux,code = <108>; + }; + + enter { + label = "Joystick Press"; + gpios = <&pioB 18 1>; + linux,code = <28>; + }; + }; }; diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi new file mode 100644 index 0000000..a02e636 --- /dev/null +++ b/arch/arm/boot/dts/at91sam9x5.dtsi @@ -0,0 +1,176 @@ +/* + * at91sam9x5.dtsi - Device Tree Include file for AT91SAM9x5 family SoC + * applies to AT91SAM9G15, AT91SAM9G25, AT91SAM9G35, + * AT91SAM9X25, AT91SAM9X35 SoC + * + * Copyright (C) 2012 Atmel, + * 2012 Nicolas Ferre <nicolas.ferre@atmel.com> + * + * Licensed under GPLv2 or later. + */ + +/include/ "skeleton.dtsi" + +/ { + model = "Atmel AT91SAM9x5 family SoC"; + compatible = "atmel,at91sam9x5"; + interrupt-parent = <&aic>; + + aliases { + serial0 = &dbgu; + serial1 = &usart0; + serial2 = &usart1; + serial3 = &usart2; + gpio0 = &pioA; + gpio1 = &pioB; + gpio2 = &pioC; + gpio3 = &pioD; + tcb0 = &tcb0; + tcb1 = &tcb1; + }; + cpus { + cpu@0 { + compatible = "arm,arm926ejs"; + }; + }; + + memory@20000000 { + reg = <0x20000000 0x10000000>; + }; + + ahb { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + apb { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + aic: interrupt-controller@fffff000 { + #interrupt-cells = <2>; + compatible = "atmel,at91rm9200-aic"; + interrupt-controller; + interrupt-parent; + reg = <0xfffff000 0x200>; + }; + + pit: timer@fffffe30 { + compatible = "atmel,at91sam9260-pit"; + reg = <0xfffffe30 0xf>; + interrupts = <1 4>; + }; + + tcb0: timer@f8008000 { + compatible = "atmel,at91sam9x5-tcb"; + reg = <0xf8008000 0x100>; + interrupts = <17 4>; + }; + + tcb1: timer@f800c000 { + compatible = "atmel,at91sam9x5-tcb"; + reg = <0xf800c000 0x100>; + interrupts = <17 4>; + }; + + dma0: dma-controller@ffffec00 { + compatible = "atmel,at91sam9g45-dma"; + reg = <0xffffec00 0x200>; + interrupts = <20 4>; + }; + + dma1: dma-controller@ffffee00 { + compatible = "atmel,at91sam9g45-dma"; + reg = <0xffffee00 0x200>; + interrupts = <21 4>; + }; + + pioA: gpio@fffff400 { + compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; + reg = <0xfffff400 0x100>; + interrupts = <2 4>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + }; + + pioB: gpio@fffff600 { + compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; + reg = <0xfffff600 0x100>; + interrupts = <2 4>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + }; + + pioC: gpio@fffff800 { + compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; + reg = <0xfffff800 0x100>; + interrupts = <3 4>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + }; + + pioD: gpio@fffffa00 { + compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; + reg = <0xfffffa00 0x100>; + interrupts = <3 4>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + }; + + dbgu: serial@fffff200 { + compatible = "atmel,at91sam9260-usart"; + reg = <0xfffff200 0x200>; + interrupts = <1 4>; + status = "disabled"; + }; + + usart0: serial@f801c000 { + compatible = "atmel,at91sam9260-usart"; + reg = <0xf801c000 0x200>; + interrupts = <5 4>; + atmel,use-dma-rx; + atmel,use-dma-tx; + status = "disabled"; + }; + + usart1: serial@f8020000 { + compatible = "atmel,at91sam9260-usart"; + reg = <0xf8020000 0x200>; + interrupts = <6 4>; + atmel,use-dma-rx; + atmel,use-dma-tx; + status = "disabled"; + }; + + usart2: serial@f8024000 { + compatible = "atmel,at91sam9260-usart"; + reg = <0xf8024000 0x200>; + interrupts = <7 4>; + atmel,use-dma-rx; + atmel,use-dma-tx; + status = "disabled"; + }; + + macb0: ethernet@f802c000 { + compatible = "cdns,at32ap7000-macb", "cdns,macb"; + reg = <0xf802c000 0x100>; + interrupts = <24 4>; + status = "disabled"; + }; + + macb1: ethernet@f8030000 { + compatible = "cdns,at32ap7000-macb", "cdns,macb"; + reg = <0xf8030000 0x100>; + interrupts = <27 4>; + status = "disabled"; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/at91sam9x5cm.dtsi b/arch/arm/boot/dts/at91sam9x5cm.dtsi new file mode 100644 index 0000000..64ae3e8 --- /dev/null +++ b/arch/arm/boot/dts/at91sam9x5cm.dtsi @@ -0,0 +1,29 @@ +/* + * at91sam9x5cm.dtsi - Device Tree Include file for AT91SAM9x5 CPU Module + * + * Copyright (C) 2012 Atmel, + * 2012 Nicolas Ferre <nicolas.ferre@atmel.com> + * + * Licensed under GPLv2 or later. + */ + +/ { + memory@20000000 { + reg = <0x20000000 0x8000000>; + }; + + leds { + compatible = "gpio-leds"; + + pb18 { + label = "pb18"; + gpios = <&pioB 18 1>; + linux,default-trigger = "heartbeat"; + }; + + pd21 { + label = "pd21"; + gpios = <&pioD 21 0>; + }; + }; +}; diff --git a/arch/arm/boot/dts/imx27-phytec-phycore.dts b/arch/arm/boot/dts/imx27-phytec-phycore.dts new file mode 100644 index 0000000..a51a08f --- /dev/null +++ b/arch/arm/boot/dts/imx27-phytec-phycore.dts @@ -0,0 +1,76 @@ +/* + * Copyright 2012 Sascha Hauer, Pengutronix + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/dts-v1/; +/include/ "imx27.dtsi" + +/ { + model = "Phytec pcm038"; + compatible = "phytec,imx27-pcm038", "fsl,imx27"; + + memory { + reg = <0x0 0x0>; + }; + + soc { + aipi@10000000 { /* aipi */ + + wdog@10002000 { + status = "okay"; + }; + + uart@1000a000 { + fsl,uart-has-rtscts; + status = "okay"; + }; + + uart@1000b000 { + fsl,uart-has-rtscts; + status = "okay"; + }; + + uart@1000c000 { + fsl,uart-has-rtscts; + status = "okay"; + }; + + fec@1002b000 { + status = "okay"; + }; + + i2c@1001d000 { + clock-frequency = <400000>; + status = "okay"; + at24@4c { + compatible = "at,24c32"; + pagesize = <32>; + reg = <0x52>; + }; + pcf8563@51 { + compatible = "nxp,pcf8563"; + reg = <0x51>; + }; + lm75@4a { + compatible = "national,lm75"; + reg = <0x4a>; + }; + }; + }; + }; + + nor_flash@c0000000 { + compatible = "cfi-flash"; + bank-width = <2>; + reg = <0xc0000000 0x02000000>; + #address-cells = <1>; + #size-cells = <1>; + }; +}; diff --git a/arch/arm/boot/dts/imx27.dtsi b/arch/arm/boot/dts/imx27.dtsi new file mode 100644 index 0000000..bc5e7d5 --- /dev/null +++ b/arch/arm/boot/dts/imx27.dtsi @@ -0,0 +1,217 @@ +/* + * Copyright 2012 Sascha Hauer, Pengutronix + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/include/ "skeleton.dtsi" + +/ { + aliases { + serial0 = &uart1; + serial1 = &uart2; + serial2 = &uart3; + serial3 = &uart4; + serial4 = &uart5; + serial5 = &uart6; + }; + + avic: avic-interrupt-controller@e0000000 { + compatible = "fsl,imx27-avic", "fsl,avic"; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0x10040000 0x1000>; + }; + + clocks { + #address-cells = <1>; + #size-cells = <0>; + + osc26m { + compatible = "fsl,imx-osc26m", "fixed-clock"; + clock-frequency = <26000000>; + }; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + interrupt-parent = <&avic>; + ranges; + + aipi@10000000 { /* AIPI1 */ + compatible = "fsl,aipi-bus", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x10000000 0x10000000>; + ranges; + + wdog@10002000 { + compatible = "fsl,imx27-wdt", "fsl,imx21-wdt"; + reg = <0x10002000 0x4000>; + interrupts = <27>; + status = "disabled"; + }; + + uart1: uart@1000a000 { + compatible = "fsl,imx27-uart", "fsl,imx21-uart"; + reg = <0x1000a000 0x1000>; + interrupts = <20>; + status = "disabled"; + }; + + uart2: uart@1000b000 { + compatible = "fsl,imx27-uart", "fsl,imx21-uart"; + reg = <0x1000b000 0x1000>; + interrupts = <19>; + status = "disabled"; + }; + + uart3: uart@1000c000 { + compatible = "fsl,imx27-uart", "fsl,imx21-uart"; + reg = <0x1000c000 0x1000>; + interrupts = <18>; + status = "disabled"; + }; + + uart4: uart@1000d000 { + compatible = "fsl,imx27-uart", "fsl,imx21-uart"; + reg = <0x1000d000 0x1000>; + interrupts = <17>; + status = "disabled"; + }; + + cspi1: cspi@1000e000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx27-cspi"; + reg = <0x1000e000 0x1000>; + interrupts = <16>; + status = "disabled"; + }; + + cspi2: cspi@1000f000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx27-cspi"; + reg = <0x1000f000 0x1000>; + interrupts = <15>; + status = "disabled"; + }; + + i2c1: i2c@10012000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx27-i2c", "fsl,imx1-i2c"; + reg = <0x10012000 0x1000>; + interrupts = <12>; + status = "disabled"; + }; + + gpio1: gpio@10015000 { + compatible = "fsl,imx27-gpio", "fsl,imx21-gpio"; + reg = <0x10015000 0x100>; + interrupts = <8>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + gpio2: gpio@10015100 { + compatible = "fsl,imx27-gpio", "fsl,imx21-gpio"; + reg = <0x10015100 0x100>; + interrupts = <8>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + gpio3: gpio@10015200 { + compatible = "fsl,imx27-gpio", "fsl,imx21-gpio"; + reg = <0x10015200 0x100>; + interrupts = <8>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + gpio4: gpio@10015300 { + compatible = "fsl,imx27-gpio", "fsl,imx21-gpio"; + reg = <0x10015300 0x100>; + interrupts = <8>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + gpio5: gpio@10015400 { + compatible = "fsl,imx27-gpio", "fsl,imx21-gpio"; + reg = <0x10015400 0x100>; + interrupts = <8>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + gpio6: gpio@10015500 { + compatible = "fsl,imx27-gpio", "fsl,imx21-gpio"; + reg = <0x10015500 0x100>; + interrupts = <8>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + cspi3: cspi@10017000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx27-cspi"; + reg = <0x10017000 0x1000>; + interrupts = <6>; + status = "disabled"; + }; + + uart5: uart@1001b000 { + compatible = "fsl,imx27-uart", "fsl,imx21-uart"; + reg = <0x1001b000 0x1000>; + interrupts = <49>; + status = "disabled"; + }; + + uart6: uart@1001c000 { + compatible = "fsl,imx27-uart", "fsl,imx21-uart"; + reg = <0x1001c000 0x1000>; + interrupts = <48>; + status = "disabled"; + }; + + i2c2: i2c@1001d000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx27-i2c", "fsl,imx1-i2c"; + reg = <0x1001d000 0x1000>; + interrupts = <1>; + status = "disabled"; + }; + + fec: fec@1002b000 { + compatible = "fsl,imx27-fec"; + reg = <0x1002b000 0x4000>; + interrupts = <50>; + status = "disabled"; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/imx51-babbage.dts b/arch/arm/boot/dts/imx51-babbage.dts index 564cb8c..9949e60 100644 --- a/arch/arm/boot/dts/imx51-babbage.dts +++ b/arch/arm/boot/dts/imx51-babbage.dts @@ -56,8 +56,95 @@ compatible = "fsl,mc13892"; spi-max-frequency = <6000000>; reg = <0>; - mc13xxx-irq-gpios = <&gpio1 8 0>; - fsl,mc13xxx-uses-regulator; + interrupt-parent = <&gpio1>; + interrupts = <8>; + + regulators { + sw1_reg: sw1 { + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <1375000>; + regulator-boot-on; + regulator-always-on; + }; + + sw2_reg: sw2 { + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1850000>; + regulator-boot-on; + regulator-always-on; + }; + + sw3_reg: sw3 { + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1850000>; + regulator-boot-on; + regulator-always-on; + }; + + sw4_reg: sw4 { + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1850000>; + regulator-boot-on; + regulator-always-on; + }; + + vpll_reg: vpll { + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + vdig_reg: vdig { + regulator-min-microvolt = <1650000>; + regulator-max-microvolt = <1650000>; + regulator-boot-on; + }; + + vsd_reg: vsd { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3150000>; + }; + + vusb2_reg: vusb2 { + regulator-min-microvolt = <2400000>; + regulator-max-microvolt = <2775000>; + regulator-boot-on; + regulator-always-on; + }; + + vvideo_reg: vvideo { + regulator-min-microvolt = <2775000>; + regulator-max-microvolt = <2775000>; + }; + + vaudio_reg: vaudio { + regulator-min-microvolt = <2300000>; + regulator-max-microvolt = <3000000>; + }; + + vcam_reg: vcam { + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <3000000>; + }; + + vgen1_reg: vgen1 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; + + vgen2_reg: vgen2 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3150000>; + regulator-always-on; + }; + + vgen3_reg: vgen3 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2900000>; + regulator-always-on; + }; + }; }; flash: at45db321d@1 { diff --git a/arch/arm/boot/dts/imx6q-arm2.dts b/arch/arm/boot/dts/imx6q-arm2.dts index c3977e0..ce1c823 100644 --- a/arch/arm/boot/dts/imx6q-arm2.dts +++ b/arch/arm/boot/dts/imx6q-arm2.dts @@ -36,11 +36,13 @@ usdhc@02198000 { /* uSDHC3 */ cd-gpios = <&gpio6 11 0>; wp-gpios = <&gpio6 14 0>; + vmmc-supply = <®_3p3v>; status = "okay"; }; usdhc@0219c000 { /* uSDHC4 */ fsl,card-wired; + vmmc-supply = <®_3p3v>; status = "okay"; }; @@ -50,6 +52,18 @@ }; }; + regulators { + compatible = "simple-bus"; + + reg_3p3v: 3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + }; + leds { compatible = "gpio-leds"; diff --git a/arch/arm/boot/dts/imx6q-sabrelite.dts b/arch/arm/boot/dts/imx6q-sabrelite.dts index 08d920d..4663a4e 100644 --- a/arch/arm/boot/dts/imx6q-sabrelite.dts +++ b/arch/arm/boot/dts/imx6q-sabrelite.dts @@ -32,18 +32,52 @@ usdhc@02198000 { /* uSDHC3 */ cd-gpios = <&gpio7 0 0>; wp-gpios = <&gpio7 1 0>; + vmmc-supply = <®_3p3v>; status = "okay"; }; usdhc@0219c000 { /* uSDHC4 */ cd-gpios = <&gpio2 6 0>; wp-gpios = <&gpio2 7 0>; + vmmc-supply = <®_3p3v>; status = "okay"; }; uart2: uart@021e8000 { status = "okay"; }; + + i2c@021a0000 { /* I2C1 */ + status = "okay"; + clock-frequency = <100000>; + + codec: sgtl5000@0a { + compatible = "fsl,sgtl5000"; + reg = <0x0a>; + VDDA-supply = <®_2p5v>; + VDDIO-supply = <®_3p3v>; + }; + }; + }; + }; + + regulators { + compatible = "simple-bus"; + + reg_2p5v: 2p5v { + compatible = "regulator-fixed"; + regulator-name = "2P5V"; + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + regulator-always-on; + }; + + reg_3p3v: 3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; }; }; }; diff --git a/arch/arm/boot/dts/omap3-beagle.dts b/arch/arm/boot/dts/omap3-beagle.dts index 9486be6..9f72cd4 100644 --- a/arch/arm/boot/dts/omap3-beagle.dts +++ b/arch/arm/boot/dts/omap3-beagle.dts @@ -13,15 +13,6 @@ model = "TI OMAP3 BeagleBoard"; compatible = "ti,omap3-beagle", "ti,omap3"; - /* - * Since the initial device tree board file does not create any - * devices (MMC, network...), the only way to boot is to provide a - * ramdisk. - */ - chosen { - bootargs = "root=/dev/ram0 rw console=ttyO2,115200n8 initrd=0x81600000,20M ramdisk_size=20480 no_console_suspend debug earlyprintk"; - }; - memory { device_type = "memory"; reg = <0x80000000 0x20000000>; /* 512 MB */ diff --git a/arch/arm/boot/dts/omap3-evm.dts b/arch/arm/boot/dts/omap3-evm.dts new file mode 100644 index 0000000..2eee16e --- /dev/null +++ b/arch/arm/boot/dts/omap3-evm.dts @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +/dts-v1/; + +/include/ "omap3.dtsi" + +/ { + model = "TI OMAP3 EVM (OMAP3530, AM/DM37x)"; + compatible = "ti,omap3-evm", "ti,omap3"; + + memory { + device_type = "memory"; + reg = <0x80000000 0x10000000>; /* 256 MB */ + }; +}; diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi index 216c331..e698064 100644 --- a/arch/arm/boot/dts/omap3.dtsi +++ b/arch/arm/boot/dts/omap3.dtsi @@ -67,28 +67,49 @@ #interrupt-cells = <1>; }; - uart1: serial@0x4806a000 { + uart1: serial@4806a000 { compatible = "ti,omap3-uart"; ti,hwmods = "uart1"; clock-frequency = <48000000>; }; - uart2: serial@0x4806c000 { + uart2: serial@4806c000 { compatible = "ti,omap3-uart"; ti,hwmods = "uart2"; clock-frequency = <48000000>; }; - uart3: serial@0x49020000 { + uart3: serial@49020000 { compatible = "ti,omap3-uart"; ti,hwmods = "uart3"; clock-frequency = <48000000>; }; - uart4: serial@0x49042000 { + uart4: serial@49042000 { compatible = "ti,omap3-uart"; ti,hwmods = "uart4"; clock-frequency = <48000000>; }; + + i2c1: i2c@48070000 { + compatible = "ti,omap3-i2c"; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "i2c1"; + }; + + i2c2: i2c@48072000 { + compatible = "ti,omap3-i2c"; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "i2c2"; + }; + + i2c3: i2c@48060000 { + compatible = "ti,omap3-i2c"; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "i2c3"; + }; }; }; diff --git a/arch/arm/boot/dts/omap4-panda.dts b/arch/arm/boot/dts/omap4-panda.dts index c702657..9755ad5 100644 --- a/arch/arm/boot/dts/omap4-panda.dts +++ b/arch/arm/boot/dts/omap4-panda.dts @@ -13,15 +13,6 @@ model = "TI OMAP4 PandaBoard"; compatible = "ti,omap4-panda", "ti,omap4430", "ti,omap4"; - /* - * Since the initial device tree board file does not create any - * devices (MMC, network...), the only way to boot is to provide a - * ramdisk. - */ - chosen { - bootargs = "root=/dev/ram0 rw console=ttyO2,115200n8 initrd=0x81600000,20M ramdisk_size=20480 no_console_suspend debug"; - }; - memory { device_type = "memory"; reg = <0x80000000 0x40000000>; /* 1 GB */ diff --git a/arch/arm/boot/dts/omap4-sdp.dts b/arch/arm/boot/dts/omap4-sdp.dts index 066e28c..63c6b2b 100644 --- a/arch/arm/boot/dts/omap4-sdp.dts +++ b/arch/arm/boot/dts/omap4-sdp.dts @@ -13,15 +13,6 @@ model = "TI OMAP4 SDP board"; compatible = "ti,omap4-sdp", "ti,omap4430", "ti,omap4"; - /* - * Since the initial device tree board file does not create any - * devices (MMC, network...), the only way to boot is to provide a - * ramdisk. - */ - chosen { - bootargs = "root=/dev/ram0 rw console=ttyO2,115200n8 initrd=0x81600000,20M ramdisk_size=20480 no_console_suspend debug"; - }; - memory { device_type = "memory"; reg = <0x80000000 0x40000000>; /* 1 GB */ diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi index e8fe75f..3d35559 100644 --- a/arch/arm/boot/dts/omap4.dtsi +++ b/arch/arm/boot/dts/omap4.dtsi @@ -99,33 +99,61 @@ gic: interrupt-controller@48241000 { compatible = "arm,cortex-a9-gic"; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <3>; reg = <0x48241000 0x1000>, <0x48240100 0x0100>; }; - uart1: serial@0x4806a000 { + uart1: serial@4806a000 { compatible = "ti,omap4-uart"; ti,hwmods = "uart1"; clock-frequency = <48000000>; }; - uart2: serial@0x4806c000 { + uart2: serial@4806c000 { compatible = "ti,omap4-uart"; ti,hwmods = "uart2"; clock-frequency = <48000000>; }; - uart3: serial@0x48020000 { + uart3: serial@48020000 { compatible = "ti,omap4-uart"; ti,hwmods = "uart3"; clock-frequency = <48000000>; }; - uart4: serial@0x4806e000 { + uart4: serial@4806e000 { compatible = "ti,omap4-uart"; ti,hwmods = "uart4"; clock-frequency = <48000000>; }; + + i2c1: i2c@48070000 { + compatible = "ti,omap4-i2c"; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "i2c1"; + }; + + i2c2: i2c@48072000 { + compatible = "ti,omap4-i2c"; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "i2c2"; + }; + + i2c3: i2c@48060000 { + compatible = "ti,omap4-i2c"; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "i2c3"; + }; + + i2c4: i2c@48350000 { + compatible = "ti,omap4-i2c"; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "i2c4"; + }; }; }; diff --git a/arch/arm/boot/dts/tegra-cardhu.dts b/arch/arm/boot/dts/tegra-cardhu.dts index 70c41fc..7326350 100644 --- a/arch/arm/boot/dts/tegra-cardhu.dts +++ b/arch/arm/boot/dts/tegra-cardhu.dts @@ -33,4 +33,22 @@ i2c@7000d000 { clock-frequency = <100000>; }; + + sdhci@78000000 { + cd-gpios = <&gpio 69 0>; /* gpio PI5 */ + wp-gpios = <&gpio 155 0>; /* gpio PT3 */ + power-gpios = <&gpio 31 0>; /* gpio PD7 */ + }; + + sdhci@78000200 { + status = "disable"; + }; + + sdhci@78000400 { + status = "disable"; + }; + + sdhci@78000400 { + support-8bit; + }; }; diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts index 80afa1b..6e8447d 100644 --- a/arch/arm/boot/dts/tegra-harmony.dts +++ b/arch/arm/boot/dts/tegra-harmony.dts @@ -10,19 +10,25 @@ reg = < 0x00000000 0x40000000 >; }; + pmc@7000f400 { + nvidia,invert-interrupt; + }; + i2c@7000c000 { clock-frequency = <400000>; - codec: wm8903@1a { + wm8903: wm8903@1a { compatible = "wlf,wm8903"; reg = <0x1a>; - interrupts = < 347 >; + interrupt-parent = <&gpio>; + interrupts = < 187 0x04 >; gpio-controller; #gpio-cells = <2>; - /* 0x8000 = Not configured */ - gpio-cfg = < 0x8000 0x8000 0 0x8000 0x8000 >; + micdet-cfg = <0>; + micdet-delay = <100>; + gpio-cfg = < 0xffffffff 0xffffffff 0 0xffffffff 0xffffffff >; }; }; @@ -38,13 +44,32 @@ clock-frequency = <400000>; }; - sound { - compatible = "nvidia,harmony-sound", "nvidia,tegra-wm8903"; + i2s@70002a00 { + status = "disable"; + }; - spkr-en-gpios = <&codec 2 0>; - hp-det-gpios = <&gpio 178 0>; - int-mic-en-gpios = <&gpio 184 0>; - ext-mic-en-gpios = <&gpio 185 0>; + sound { + compatible = "nvidia,tegra-audio-wm8903-harmony", + "nvidia,tegra-audio-wm8903"; + nvidia,model = "NVIDIA Tegra Harmony"; + + nvidia,audio-routing = + "Headphone Jack", "HPOUTR", + "Headphone Jack", "HPOUTL", + "Int Spk", "ROP", + "Int Spk", "RON", + "Int Spk", "LOP", + "Int Spk", "LON", + "Mic Jack", "MICBIAS", + "IN1L", "Mic Jack"; + + nvidia,i2s-controller = <&tegra_i2s1>; + nvidia,audio-codec = <&wm8903>; + + nvidia,spkr-en-gpios = <&wm8903 2 0>; + nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */ + nvidia,int-mic-en-gpios = <&gpio 184 0>; /*gpio PX0 */ + nvidia,ext-mic-en-gpios = <&gpio 185 0>; /* gpio PX1 */ }; serial@70006000 { diff --git a/arch/arm/boot/dts/tegra-paz00.dts b/arch/arm/boot/dts/tegra-paz00.dts index 825d295..3c1ff5a 100644 --- a/arch/arm/boot/dts/tegra-paz00.dts +++ b/arch/arm/boot/dts/tegra-paz00.dts @@ -12,6 +12,13 @@ i2c@7000c000 { clock-frequency = <400000>; + + alc5632: alc5632@1e { + compatible = "realtek,alc5632"; + reg = <0x1e>; + gpio-controller; + #gpio-cells = <2>; + }; }; i2c@7000c400 { @@ -37,6 +44,30 @@ clock-frequency = <400000>; }; + i2s@70002a00 { + status = "disable"; + }; + + sound { + compatible = "nvidia,tegra-audio-alc5632-paz00", + "nvidia,tegra-audio-alc5632"; + + nvidia,model = "Compal PAZ00"; + + nvidia,audio-routing = + "Int Spk", "SPKOUT", + "Int Spk", "SPKOUTN", + "Headset Mic", "MICBIAS1", + "MIC1", "Headset Mic", + "Headset Stereophone", "HPR", + "Headset Stereophone", "HPL", + "DMICDAT", "Digital Mic"; + + nvidia,audio-codec = <&alc5632>; + nvidia,i2s-controller = <&tegra_i2s1>; + nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */ + }; + serial@70006000 { clock-frequency = <216000000>; }; diff --git a/arch/arm/boot/dts/tegra-seaboard.dts b/arch/arm/boot/dts/tegra-seaboard.dts index b55a02e..876d5c9 100644 --- a/arch/arm/boot/dts/tegra-seaboard.dts +++ b/arch/arm/boot/dts/tegra-seaboard.dts @@ -13,6 +13,20 @@ i2c@7000c000 { clock-frequency = <400000>; + + wm8903: wm8903@1a { + compatible = "wlf,wm8903"; + reg = <0x1a>; + interrupt-parent = <&gpio>; + interrupts = < 187 0x04 >; + + gpio-controller; + #gpio-cells = <2>; + + micdet-cfg = <0>; + micdet-delay = <100>; + gpio-cfg = < 0xffffffff 0xffffffff 0 0xffffffff 0xffffffff >; + }; }; i2c@7000c400 { @@ -32,6 +46,32 @@ }; }; + i2s@70002a00 { + status = "disable"; + }; + + sound { + compatible = "nvidia,tegra-audio-wm8903-seaboard", + "nvidia,tegra-audio-wm8903"; + nvidia,model = "NVIDIA Tegra Seaboard"; + + nvidia,audio-routing = + "Headphone Jack", "HPOUTR", + "Headphone Jack", "HPOUTL", + "Int Spk", "ROP", + "Int Spk", "RON", + "Int Spk", "LOP", + "Int Spk", "LON", + "Mic Jack", "MICBIAS", + "IN1R", "Mic Jack"; + + nvidia,i2s-controller = <&tegra_i2s1>; + nvidia,audio-codec = <&wm8903>; + + nvidia,spkr-en-gpios = <&wm8903 2 0>; + nvidia,hp-det-gpios = <&gpio 185 0>; /* gpio PX1 */ + }; + serial@70006000 { status = "disable"; }; @@ -93,4 +133,42 @@ gpio-key,wakeup; }; }; + + emc@7000f400 { + emc-table@190000 { + reg = < 190000 >; + compatible = "nvidia,tegra20-emc-table"; + clock-frequency = < 190000 >; + nvidia,emc-registers = < 0x0000000c 0x00000026 + 0x00000009 0x00000003 0x00000004 0x00000004 + 0x00000002 0x0000000c 0x00000003 0x00000003 + 0x00000002 0x00000001 0x00000004 0x00000005 + 0x00000004 0x00000009 0x0000000d 0x0000059f + 0x00000000 0x00000003 0x00000003 0x00000003 + 0x00000003 0x00000001 0x0000000b 0x000000c8 + 0x00000003 0x00000007 0x00000004 0x0000000f + 0x00000002 0x00000000 0x00000000 0x00000002 + 0x00000000 0x00000000 0x00000083 0xa06204ae + 0x007dc010 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 >; + }; + + emc-table@380000 { + reg = < 380000 >; + compatible = "nvidia,tegra20-emc-table"; + clock-frequency = < 380000 >; + nvidia,emc-registers = < 0x00000017 0x0000004b + 0x00000012 0x00000006 0x00000004 0x00000005 + 0x00000003 0x0000000c 0x00000006 0x00000006 + 0x00000003 0x00000001 0x00000004 0x00000005 + 0x00000004 0x00000009 0x0000000d 0x00000b5f + 0x00000000 0x00000003 0x00000003 0x00000006 + 0x00000006 0x00000001 0x00000011 0x000000c8 + 0x00000003 0x0000000e 0x00000007 0x0000000f + 0x00000002 0x00000000 0x00000000 0x00000002 + 0x00000000 0x00000000 0x00000083 0xe044048b + 0x007d8010 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 >; + }; + }; }; diff --git a/arch/arm/boot/dts/tegra-trimslice.dts b/arch/arm/boot/dts/tegra-trimslice.dts index 3b3ee7d..2524768 100644 --- a/arch/arm/boot/dts/tegra-trimslice.dts +++ b/arch/arm/boot/dts/tegra-trimslice.dts @@ -26,6 +26,18 @@ status = "disable"; }; + i2s@70002800 { + status = "disable"; + }; + + i2s@70002a00 { + status = "disable"; + }; + + das@70000c00 { + status = "disable"; + }; + serial@70006000 { clock-frequency = < 216000000 >; }; diff --git a/arch/arm/boot/dts/tegra-ventana.dts b/arch/arm/boot/dts/tegra-ventana.dts index c7d3b87..2dcff87 100644 --- a/arch/arm/boot/dts/tegra-ventana.dts +++ b/arch/arm/boot/dts/tegra-ventana.dts @@ -12,6 +12,20 @@ i2c@7000c000 { clock-frequency = <400000>; + + wm8903: wm8903@1a { + compatible = "wlf,wm8903"; + reg = <0x1a>; + interrupt-parent = <&gpio>; + interrupts = < 187 0x04 >; + + gpio-controller; + #gpio-cells = <2>; + + micdet-cfg = <0>; + micdet-delay = <100>; + gpio-cfg = < 0xffffffff 0xffffffff 0 0xffffffff 0xffffffff >; + }; }; i2c@7000c400 { @@ -26,6 +40,34 @@ clock-frequency = <400000>; }; + i2s@70002a00 { + status = "disable"; + }; + + sound { + compatible = "nvidia,tegra-audio-wm8903-ventana", + "nvidia,tegra-audio-wm8903"; + nvidia,model = "NVIDIA Tegra Ventana"; + + nvidia,audio-routing = + "Headphone Jack", "HPOUTR", + "Headphone Jack", "HPOUTL", + "Int Spk", "ROP", + "Int Spk", "RON", + "Int Spk", "LOP", + "Int Spk", "LON", + "Mic Jack", "MICBIAS", + "IN1L", "Mic Jack"; + + nvidia,i2s-controller = <&tegra_i2s1>; + nvidia,audio-codec = <&wm8903>; + + nvidia,spkr-en-gpios = <&wm8903 2 0>; + nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */ + nvidia,int-mic-en-gpios = <&gpio 184 0>; /*gpio PX0 */ + nvidia,ext-mic-en-gpios = <&gpio 185 0>; /* gpio PX1 */ + }; + serial@70006000 { status = "disable"; }; diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi index 3da7afd..d2bc7e7 100644 --- a/arch/arm/boot/dts/tegra20.dtsi +++ b/arch/arm/boot/dts/tegra20.dtsi @@ -4,6 +4,11 @@ compatible = "nvidia,tegra20"; interrupt-parent = <&intc>; + pmc@7000f400 { + compatible = "nvidia,tegra20-pmc"; + reg = <0x7000e400 0x400>; + }; + intc: interrupt-controller@50041000 { compatible = "arm,cortex-a9-gic"; interrupt-controller; @@ -12,6 +17,33 @@ < 0x50040100 0x0100 >; }; + pmu { + compatible = "arm,cortex-a9-pmu"; + interrupts = <0 56 0x04 + 0 57 0x04>; + }; + + apbdma: dma@6000a000 { + compatible = "nvidia,tegra20-apbdma"; + reg = <0x6000a000 0x1200>; + interrupts = < 0 104 0x04 + 0 105 0x04 + 0 106 0x04 + 0 107 0x04 + 0 108 0x04 + 0 109 0x04 + 0 110 0x04 + 0 111 0x04 + 0 112 0x04 + 0 113 0x04 + 0 114 0x04 + 0 115 0x04 + 0 116 0x04 + 0 117 0x04 + 0 118 0x04 + 0 119 0x04 >; + }; + i2c@7000c000 { #address-cells = <1>; #size-cells = <0>; @@ -44,18 +76,18 @@ interrupts = < 0 53 0x04 >; }; - i2s@70002800 { + tegra_i2s1: i2s@70002800 { compatible = "nvidia,tegra20-i2s"; reg = <0x70002800 0x200>; interrupts = < 0 13 0x04 >; - dma-channel = < 2 >; + nvidia,dma-request-selector = < &apbdma 2 >; }; - i2s@70002a00 { + tegra_i2s2: i2s@70002a00 { compatible = "nvidia,tegra20-i2s"; reg = <0x70002a00 0x200>; interrupts = < 0 3 0x04 >; - dma-channel = < 1 >; + nvidia,dma-request-selector = < &apbdma 1 >; }; das@70000c00 { @@ -120,6 +152,13 @@ interrupts = < 0 91 0x04 >; }; + emc@7000f400 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nvidia,tegra20-emc"; + reg = <0x7000f400 0x200>; + }; + sdhci@c8000000 { compatible = "nvidia,tegra20-sdhci"; reg = <0xc8000000 0x200>; diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi index ee7db98..e957051 100644 --- a/arch/arm/boot/dts/tegra30.dtsi +++ b/arch/arm/boot/dts/tegra30.dtsi @@ -4,6 +4,11 @@ compatible = "nvidia,tegra30"; interrupt-parent = <&intc>; + pmc@7000f400 { + compatible = "nvidia,tegra20-pmc", "nvidia,tegra30-pmc"; + reg = <0x7000e400 0x400>; + }; + intc: interrupt-controller@50041000 { compatible = "arm,cortex-a9-gic"; interrupt-controller; @@ -12,6 +17,51 @@ < 0x50040100 0x0100 >; }; + pmu { + compatible = "arm,cortex-a9-pmu"; + interrupts = <0 144 0x04 + 0 145 0x04 + 0 146 0x04 + 0 147 0x04>; + }; + + apbdma: dma@6000a000 { + compatible = "nvidia,tegra30-apbdma", "nvidia,tegra20-apbdma"; + reg = <0x6000a000 0x1400>; + interrupts = < 0 104 0x04 + 0 105 0x04 + 0 106 0x04 + 0 107 0x04 + 0 108 0x04 + 0 109 0x04 + 0 110 0x04 + 0 111 0x04 + 0 112 0x04 + 0 113 0x04 + 0 114 0x04 + 0 115 0x04 + 0 116 0x04 + 0 117 0x04 + 0 118 0x04 + 0 119 0x04 + 0 128 0x04 + 0 129 0x04 + 0 130 0x04 + 0 131 0x04 + 0 132 0x04 + 0 133 0x04 + 0 134 0x04 + 0 135 0x04 + 0 136 0x04 + 0 137 0x04 + 0 138 0x04 + 0 139 0x04 + 0 140 0x04 + 0 141 0x04 + 0 142 0x04 + 0 143 0x04 >; + }; + i2c@7000c000 { #address-cells = <1>; #size-cells = <0>; @@ -55,7 +105,14 @@ gpio: gpio@6000d000 { compatible = "nvidia,tegra30-gpio", "nvidia,tegra20-gpio"; reg = < 0x6000d000 0x1000 >; - interrupts = < 0 32 0x04 0 33 0x04 0 34 0x04 0 35 0x04 0 55 0x04 0 87 0x04 0 89 0x04 >; + interrupts = < 0 32 0x04 + 0 33 0x04 + 0 34 0x04 + 0 35 0x04 + 0 55 0x04 + 0 87 0x04 + 0 89 0x04 + 0 125 0x04 >; #gpio-cells = <2>; gpio-controller; }; diff --git a/arch/arm/boot/dts/usb_a9g20.dts b/arch/arm/boot/dts/usb_a9g20.dts index f04b535..d74545a 100644 --- a/arch/arm/boot/dts/usb_a9g20.dts +++ b/arch/arm/boot/dts/usb_a9g20.dts @@ -32,4 +32,27 @@ }; }; }; + + leds { + compatible = "gpio-leds"; + + user_led { + label = "user_led"; + gpios = <&pioB 21 1>; + linux,default-trigger = "heartbeat"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + user_pb { + label = "user_pb"; + gpios = <&pioB 10 1>; + linux,code = <28>; + gpio-key,wakeup; + }; + }; }; diff --git a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi new file mode 100644 index 0000000..16076e2 --- /dev/null +++ b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi @@ -0,0 +1,201 @@ +/* + * ARM Ltd. Versatile Express + * + * Motherboard Express uATX + * V2M-P1 + * + * HBI-0190D + * + * RS1 memory map ("ARM Cortex-A Series memory map" in the board's + * Technical Reference Manual) + * + * WARNING! The hardware described in this file is independent from the + * original variant (vexpress-v2m.dtsi), but there is a strong + * correspondence between the two configurations. + * + * TAKE CARE WHEN MAINTAINING THIS FILE TO PROPAGATE ANY RELEVANT + * CHANGES TO vexpress-v2m.dtsi! + */ + +/ { + aliases { + arm,v2m_timer = &v2m_timer01; + }; + + motherboard { + compatible = "simple-bus"; + arm,v2m-memory-map = "rs1"; + #address-cells = <2>; /* SMB chipselect number and offset */ + #size-cells = <1>; + #interrupt-cells = <1>; + + flash@0,00000000 { + compatible = "arm,vexpress-flash", "cfi-flash"; + reg = <0 0x00000000 0x04000000>, + <4 0x00000000 0x04000000>; + bank-width = <4>; + }; + + psram@1,00000000 { + compatible = "arm,vexpress-psram", "mtd-ram"; + reg = <1 0x00000000 0x02000000>; + bank-width = <4>; + }; + + vram@2,00000000 { + compatible = "arm,vexpress-vram"; + reg = <2 0x00000000 0x00800000>; + }; + + ethernet@2,02000000 { + compatible = "smsc,lan9118", "smsc,lan9115"; + reg = <2 0x02000000 0x10000>; + interrupts = <15>; + phy-mode = "mii"; + reg-io-width = <4>; + smsc,irq-active-high; + smsc,irq-push-pull; + }; + + usb@2,03000000 { + compatible = "nxp,usb-isp1761"; + reg = <2 0x03000000 0x20000>; + interrupts = <16>; + port1-otg; + }; + + iofpga@3,00000000 { + compatible = "arm,amba-bus", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 3 0 0x200000>; + + sysreg@010000 { + compatible = "arm,vexpress-sysreg"; + reg = <0x010000 0x1000>; + }; + + sysctl@020000 { + compatible = "arm,sp810", "arm,primecell"; + reg = <0x020000 0x1000>; + }; + + /* PCI-E I2C bus */ + v2m_i2c_pcie: i2c@030000 { + compatible = "arm,versatile-i2c"; + reg = <0x030000 0x1000>; + + #address-cells = <1>; + #size-cells = <0>; + + pcie-switch@60 { + compatible = "idt,89hpes32h8"; + reg = <0x60>; + }; + }; + + aaci@040000 { + compatible = "arm,pl041", "arm,primecell"; + reg = <0x040000 0x1000>; + interrupts = <11>; + }; + + mmci@050000 { + compatible = "arm,pl180", "arm,primecell"; + reg = <0x050000 0x1000>; + interrupts = <9 10>; + }; + + kmi@060000 { + compatible = "arm,pl050", "arm,primecell"; + reg = <0x060000 0x1000>; + interrupts = <12>; + }; + + kmi@070000 { + compatible = "arm,pl050", "arm,primecell"; + reg = <0x070000 0x1000>; + interrupts = <13>; + }; + + v2m_serial0: uart@090000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x090000 0x1000>; + interrupts = <5>; + }; + + v2m_serial1: uart@0a0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0a0000 0x1000>; + interrupts = <6>; + }; + + v2m_serial2: uart@0b0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0b0000 0x1000>; + interrupts = <7>; + }; + + v2m_serial3: uart@0c0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0c0000 0x1000>; + interrupts = <8>; + }; + + wdt@0f0000 { + compatible = "arm,sp805", "arm,primecell"; + reg = <0x0f0000 0x1000>; + interrupts = <0>; + }; + + v2m_timer01: timer@110000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x110000 0x1000>; + interrupts = <2>; + }; + + v2m_timer23: timer@120000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x120000 0x1000>; + }; + + /* DVI I2C bus */ + v2m_i2c_dvi: i2c@160000 { + compatible = "arm,versatile-i2c"; + reg = <0x160000 0x1000>; + + #address-cells = <1>; + #size-cells = <0>; + + dvi-transmitter@39 { + compatible = "sil,sii9022-tpi", "sil,sii9022"; + reg = <0x39>; + }; + + dvi-transmitter@60 { + compatible = "sil,sii9022-cpi", "sil,sii9022"; + reg = <0x60>; + }; + }; + + rtc@170000 { + compatible = "arm,pl031", "arm,primecell"; + reg = <0x170000 0x1000>; + interrupts = <4>; + }; + + compact-flash@1a0000 { + compatible = "arm,vexpress-cf", "ata-generic"; + reg = <0x1a0000 0x100 + 0x1a0100 0xf00>; + reg-shift = <2>; + }; + + clcd@1f0000 { + compatible = "arm,pl111", "arm,primecell"; + reg = <0x1f0000 0x1000>; + interrupts = <14>; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/vexpress-v2m.dtsi b/arch/arm/boot/dts/vexpress-v2m.dtsi new file mode 100644 index 0000000..a6c9c7c --- /dev/null +++ b/arch/arm/boot/dts/vexpress-v2m.dtsi @@ -0,0 +1,200 @@ +/* + * ARM Ltd. Versatile Express + * + * Motherboard Express uATX + * V2M-P1 + * + * HBI-0190D + * + * Original memory map ("Legacy memory map" in the board's + * Technical Reference Manual) + * + * WARNING! The hardware described in this file is independent from the + * RS1 variant (vexpress-v2m-rs1.dtsi), but there is a strong + * correspondence between the two configurations. + * + * TAKE CARE WHEN MAINTAINING THIS FILE TO PROPAGATE ANY RELEVANT + * CHANGES TO vexpress-v2m-rs1.dtsi! + */ + +/ { + aliases { + arm,v2m_timer = &v2m_timer01; + }; + + motherboard { + compatible = "simple-bus"; + #address-cells = <2>; /* SMB chipselect number and offset */ + #size-cells = <1>; + #interrupt-cells = <1>; + + flash@0,00000000 { + compatible = "arm,vexpress-flash", "cfi-flash"; + reg = <0 0x00000000 0x04000000>, + <1 0x00000000 0x04000000>; + bank-width = <4>; + }; + + psram@2,00000000 { + compatible = "arm,vexpress-psram", "mtd-ram"; + reg = <2 0x00000000 0x02000000>; + bank-width = <4>; + }; + + vram@3,00000000 { + compatible = "arm,vexpress-vram"; + reg = <3 0x00000000 0x00800000>; + }; + + ethernet@3,02000000 { + compatible = "smsc,lan9118", "smsc,lan9115"; + reg = <3 0x02000000 0x10000>; + interrupts = <15>; + phy-mode = "mii"; + reg-io-width = <4>; + smsc,irq-active-high; + smsc,irq-push-pull; + }; + + usb@3,03000000 { + compatible = "nxp,usb-isp1761"; + reg = <3 0x03000000 0x20000>; + interrupts = <16>; + port1-otg; + }; + + iofpga@7,00000000 { + compatible = "arm,amba-bus", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 7 0 0x20000>; + + sysreg@00000 { + compatible = "arm,vexpress-sysreg"; + reg = <0x00000 0x1000>; + }; + + sysctl@01000 { + compatible = "arm,sp810", "arm,primecell"; + reg = <0x01000 0x1000>; + }; + + /* PCI-E I2C bus */ + v2m_i2c_pcie: i2c@02000 { + compatible = "arm,versatile-i2c"; + reg = <0x02000 0x1000>; + + #address-cells = <1>; + #size-cells = <0>; + + pcie-switch@60 { + compatible = "idt,89hpes32h8"; + reg = <0x60>; + }; + }; + + aaci@04000 { + compatible = "arm,pl041", "arm,primecell"; + reg = <0x04000 0x1000>; + interrupts = <11>; + }; + + mmci@05000 { + compatible = "arm,pl180", "arm,primecell"; + reg = <0x05000 0x1000>; + interrupts = <9 10>; + }; + + kmi@06000 { + compatible = "arm,pl050", "arm,primecell"; + reg = <0x06000 0x1000>; + interrupts = <12>; + }; + + kmi@07000 { + compatible = "arm,pl050", "arm,primecell"; + reg = <0x07000 0x1000>; + interrupts = <13>; + }; + + v2m_serial0: uart@09000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x09000 0x1000>; + interrupts = <5>; + }; + + v2m_serial1: uart@0a000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0a000 0x1000>; + interrupts = <6>; + }; + + v2m_serial2: uart@0b000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0b000 0x1000>; + interrupts = <7>; + }; + + v2m_serial3: uart@0c000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0c000 0x1000>; + interrupts = <8>; + }; + + wdt@0f000 { + compatible = "arm,sp805", "arm,primecell"; + reg = <0x0f000 0x1000>; + interrupts = <0>; + }; + + v2m_timer01: timer@11000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x11000 0x1000>; + interrupts = <2>; + }; + + v2m_timer23: timer@12000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x12000 0x1000>; + }; + + /* DVI I2C bus */ + v2m_i2c_dvi: i2c@16000 { + compatible = "arm,versatile-i2c"; + reg = <0x16000 0x1000>; + + #address-cells = <1>; + #size-cells = <0>; + + dvi-transmitter@39 { + compatible = "sil,sii9022-tpi", "sil,sii9022"; + reg = <0x39>; + }; + + dvi-transmitter@60 { + compatible = "sil,sii9022-cpi", "sil,sii9022"; + reg = <0x60>; + }; + }; + + rtc@17000 { + compatible = "arm,pl031", "arm,primecell"; + reg = <0x17000 0x1000>; + interrupts = <4>; + }; + + compact-flash@1a000 { + compatible = "arm,vexpress-cf", "ata-generic"; + reg = <0x1a000 0x100 + 0x1a100 0xf00>; + reg-shift = <2>; + }; + + clcd@1f000 { + compatible = "arm,pl111", "arm,primecell"; + reg = <0x1f000 0x1000>; + interrupts = <14>; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts new file mode 100644 index 0000000..941b161 --- /dev/null +++ b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts @@ -0,0 +1,157 @@ +/* + * ARM Ltd. Versatile Express + * + * CoreTile Express A15x2 (version with Test Chip 1) + * Cortex-A15 MPCore (V2P-CA15) + * + * HBI-0237A + */ + +/dts-v1/; + +/ { + model = "V2P-CA15"; + arm,hbi = <0x237>; + compatible = "arm,vexpress,v2p-ca15,tc1", "arm,vexpress,v2p-ca15", "arm,vexpress"; + interrupt-parent = <&gic>; + #address-cells = <1>; + #size-cells = <1>; + + chosen { }; + + aliases { + serial0 = &v2m_serial0; + serial1 = &v2m_serial1; + serial2 = &v2m_serial2; + serial3 = &v2m_serial3; + i2c0 = &v2m_i2c_dvi; + i2c1 = &v2m_i2c_pcie; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <1>; + }; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x80000000 0x40000000>; + }; + + hdlcd@2b000000 { + compatible = "arm,hdlcd"; + reg = <0x2b000000 0x1000>; + interrupts = <0 85 4>; + }; + + memory-controller@2b0a0000 { + compatible = "arm,pl341", "arm,primecell"; + reg = <0x2b0a0000 0x1000>; + }; + + wdt@2b060000 { + compatible = "arm,sp805", "arm,primecell"; + reg = <0x2b060000 0x1000>; + interrupts = <98>; + }; + + gic: interrupt-controller@2c001000 { + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0x2c001000 0x1000>, + <0x2c002000 0x100>; + }; + + memory-controller@7ffd0000 { + compatible = "arm,pl354", "arm,primecell"; + reg = <0x7ffd0000 0x1000>; + interrupts = <0 86 4>, + <0 87 4>; + }; + + dma@7ffb0000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0x7ffb0000 0x1000>; + interrupts = <0 92 4>, + <0 88 4>, + <0 89 4>, + <0 90 4>, + <0 91 4>; + }; + + pmu { + compatible = "arm,cortex-a15-pmu", "arm,cortex-a9-pmu"; + interrupts = <0 68 4>, + <0 69 4>; + }; + + motherboard { + ranges = <0 0 0x08000000 0x04000000>, + <1 0 0x14000000 0x04000000>, + <2 0 0x18000000 0x04000000>, + <3 0 0x1c000000 0x04000000>, + <4 0 0x0c000000 0x04000000>, + <5 0 0x10000000 0x04000000>; + + interrupt-map-mask = <0 0 63>; + interrupt-map = <0 0 0 &gic 0 0 4>, + <0 0 1 &gic 0 1 4>, + <0 0 2 &gic 0 2 4>, + <0 0 3 &gic 0 3 4>, + <0 0 4 &gic 0 4 4>, + <0 0 5 &gic 0 5 4>, + <0 0 6 &gic 0 6 4>, + <0 0 7 &gic 0 7 4>, + <0 0 8 &gic 0 8 4>, + <0 0 9 &gic 0 9 4>, + <0 0 10 &gic 0 10 4>, + <0 0 11 &gic 0 11 4>, + <0 0 12 &gic 0 12 4>, + <0 0 13 &gic 0 13 4>, + <0 0 14 &gic 0 14 4>, + <0 0 15 &gic 0 15 4>, + <0 0 16 &gic 0 16 4>, + <0 0 17 &gic 0 17 4>, + <0 0 18 &gic 0 18 4>, + <0 0 19 &gic 0 19 4>, + <0 0 20 &gic 0 20 4>, + <0 0 21 &gic 0 21 4>, + <0 0 22 &gic 0 22 4>, + <0 0 23 &gic 0 23 4>, + <0 0 24 &gic 0 24 4>, + <0 0 25 &gic 0 25 4>, + <0 0 26 &gic 0 26 4>, + <0 0 27 &gic 0 27 4>, + <0 0 28 &gic 0 28 4>, + <0 0 29 &gic 0 29 4>, + <0 0 30 &gic 0 30 4>, + <0 0 31 &gic 0 31 4>, + <0 0 32 &gic 0 32 4>, + <0 0 33 &gic 0 33 4>, + <0 0 34 &gic 0 34 4>, + <0 0 35 &gic 0 35 4>, + <0 0 36 &gic 0 36 4>, + <0 0 37 &gic 0 37 4>, + <0 0 38 &gic 0 38 4>, + <0 0 39 &gic 0 39 4>, + <0 0 40 &gic 0 40 4>, + <0 0 41 &gic 0 41 4>, + <0 0 42 &gic 0 42 4>; + }; +}; + +/include/ "vexpress-v2m-rs1.dtsi" diff --git a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts new file mode 100644 index 0000000..6905e66d --- /dev/null +++ b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts @@ -0,0 +1,162 @@ +/* + * ARM Ltd. Versatile Express + * + * CoreTile Express A5x2 + * Cortex-A5 MPCore (V2P-CA5s) + * + * HBI-0225B + */ + +/dts-v1/; + +/ { + model = "V2P-CA5s"; + arm,hbi = <0x225>; + compatible = "arm,vexpress,v2p-ca5s", "arm,vexpress"; + interrupt-parent = <&gic>; + #address-cells = <1>; + #size-cells = <1>; + + chosen { }; + + aliases { + serial0 = &v2m_serial0; + serial1 = &v2m_serial1; + serial2 = &v2m_serial2; + serial3 = &v2m_serial3; + i2c0 = &v2m_i2c_dvi; + i2c1 = &v2m_i2c_pcie; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a5"; + reg = <0>; + next-level-cache = <&L2>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a5"; + reg = <1>; + next-level-cache = <&L2>; + }; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x80000000 0x40000000>; + }; + + hdlcd@2a110000 { + compatible = "arm,hdlcd"; + reg = <0x2a110000 0x1000>; + interrupts = <0 85 4>; + }; + + memory-controller@2a150000 { + compatible = "arm,pl341", "arm,primecell"; + reg = <0x2a150000 0x1000>; + }; + + memory-controller@2a190000 { + compatible = "arm,pl354", "arm,primecell"; + reg = <0x2a190000 0x1000>; + interrupts = <0 86 4>, + <0 87 4>; + }; + + scu@2c000000 { + compatible = "arm,cortex-a5-scu"; + reg = <0x2c000000 0x58>; + }; + + timer@2c000600 { + compatible = "arm,cortex-a5-twd-timer"; + reg = <0x2c000600 0x38>; + interrupts = <1 2 0x304>, + <1 3 0x304>; + }; + + gic: interrupt-controller@2c001000 { + compatible = "arm,corex-a5-gic", "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0x2c001000 0x1000>, + <0x2c000100 0x100>; + }; + + L2: cache-controller@2c0f0000 { + compatible = "arm,pl310-cache"; + reg = <0x2c0f0000 0x1000>; + interrupts = <0 84 4>; + cache-level = <2>; + }; + + pmu { + compatible = "arm,cortex-a5-pmu", "arm,cortex-a9-pmu"; + interrupts = <0 68 4>, + <0 69 4>; + }; + + motherboard { + ranges = <0 0 0x08000000 0x04000000>, + <1 0 0x14000000 0x04000000>, + <2 0 0x18000000 0x04000000>, + <3 0 0x1c000000 0x04000000>, + <4 0 0x0c000000 0x04000000>, + <5 0 0x10000000 0x04000000>; + + interrupt-map-mask = <0 0 63>; + interrupt-map = <0 0 0 &gic 0 0 4>, + <0 0 1 &gic 0 1 4>, + <0 0 2 &gic 0 2 4>, + <0 0 3 &gic 0 3 4>, + <0 0 4 &gic 0 4 4>, + <0 0 5 &gic 0 5 4>, + <0 0 6 &gic 0 6 4>, + <0 0 7 &gic 0 7 4>, + <0 0 8 &gic 0 8 4>, + <0 0 9 &gic 0 9 4>, + <0 0 10 &gic 0 10 4>, + <0 0 11 &gic 0 11 4>, + <0 0 12 &gic 0 12 4>, + <0 0 13 &gic 0 13 4>, + <0 0 14 &gic 0 14 4>, + <0 0 15 &gic 0 15 4>, + <0 0 16 &gic 0 16 4>, + <0 0 17 &gic 0 17 4>, + <0 0 18 &gic 0 18 4>, + <0 0 19 &gic 0 19 4>, + <0 0 20 &gic 0 20 4>, + <0 0 21 &gic 0 21 4>, + <0 0 22 &gic 0 22 4>, + <0 0 23 &gic 0 23 4>, + <0 0 24 &gic 0 24 4>, + <0 0 25 &gic 0 25 4>, + <0 0 26 &gic 0 26 4>, + <0 0 27 &gic 0 27 4>, + <0 0 28 &gic 0 28 4>, + <0 0 29 &gic 0 29 4>, + <0 0 30 &gic 0 30 4>, + <0 0 31 &gic 0 31 4>, + <0 0 32 &gic 0 32 4>, + <0 0 33 &gic 0 33 4>, + <0 0 34 &gic 0 34 4>, + <0 0 35 &gic 0 35 4>, + <0 0 36 &gic 0 36 4>, + <0 0 37 &gic 0 37 4>, + <0 0 38 &gic 0 38 4>, + <0 0 39 &gic 0 39 4>, + <0 0 40 &gic 0 40 4>, + <0 0 41 &gic 0 41 4>, + <0 0 42 &gic 0 42 4>; + }; +}; + +/include/ "vexpress-v2m-rs1.dtsi" diff --git a/arch/arm/boot/dts/vexpress-v2p-ca9.dts b/arch/arm/boot/dts/vexpress-v2p-ca9.dts new file mode 100644 index 0000000..da77869 --- /dev/null +++ b/arch/arm/boot/dts/vexpress-v2p-ca9.dts @@ -0,0 +1,192 @@ +/* + * ARM Ltd. Versatile Express + * + * CoreTile Express A9x4 + * Cortex-A9 MPCore (V2P-CA9) + * + * HBI-0191B + */ + +/dts-v1/; + +/ { + model = "V2P-CA9"; + arm,hbi = <0x191>; + compatible = "arm,vexpress,v2p-ca9", "arm,vexpress"; + interrupt-parent = <&gic>; + #address-cells = <1>; + #size-cells = <1>; + + chosen { }; + + aliases { + serial0 = &v2m_serial0; + serial1 = &v2m_serial1; + serial2 = &v2m_serial2; + serial3 = &v2m_serial3; + i2c0 = &v2m_i2c_dvi; + i2c1 = &v2m_i2c_pcie; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <0>; + next-level-cache = <&L2>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <1>; + next-level-cache = <&L2>; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <2>; + next-level-cache = <&L2>; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <3>; + next-level-cache = <&L2>; + }; + }; + + memory@60000000 { + device_type = "memory"; + reg = <0x60000000 0x40000000>; + }; + + clcd@10020000 { + compatible = "arm,pl111", "arm,primecell"; + reg = <0x10020000 0x1000>; + interrupts = <0 44 4>; + }; + + memory-controller@100e0000 { + compatible = "arm,pl341", "arm,primecell"; + reg = <0x100e0000 0x1000>; + }; + + memory-controller@100e1000 { + compatible = "arm,pl354", "arm,primecell"; + reg = <0x100e1000 0x1000>; + interrupts = <0 45 4>, + <0 46 4>; + }; + + timer@100e4000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x100e4000 0x1000>; + interrupts = <0 48 4>, + <0 49 4>; + }; + + watchdog@100e5000 { + compatible = "arm,sp805", "arm,primecell"; + reg = <0x100e5000 0x1000>; + interrupts = <0 51 4>; + }; + + scu@1e000000 { + compatible = "arm,cortex-a9-scu"; + reg = <0x1e000000 0x58>; + }; + + timer@1e000600 { + compatible = "arm,cortex-a9-twd-timer"; + reg = <0x1e000600 0x20>; + interrupts = <1 2 0xf04>, + <1 3 0xf04>; + }; + + gic: interrupt-controller@1e001000 { + compatible = "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0x1e001000 0x1000>, + <0x1e000100 0x100>; + }; + + L2: cache-controller@1e00a000 { + compatible = "arm,pl310-cache"; + reg = <0x1e00a000 0x1000>; + interrupts = <0 43 4>; + cache-level = <2>; + arm,data-latency = <1 1 1>; + arm,tag-latency = <1 1 1>; + }; + + pmu { + compatible = "arm,cortex-a9-pmu"; + interrupts = <0 60 4>, + <0 61 4>, + <0 62 4>, + <0 63 4>; + }; + + motherboard { + ranges = <0 0 0x40000000 0x04000000>, + <1 0 0x44000000 0x04000000>, + <2 0 0x48000000 0x04000000>, + <3 0 0x4c000000 0x04000000>, + <7 0 0x10000000 0x00020000>; + + interrupt-map-mask = <0 0 63>; + interrupt-map = <0 0 0 &gic 0 0 4>, + <0 0 1 &gic 0 1 4>, + <0 0 2 &gic 0 2 4>, + <0 0 3 &gic 0 3 4>, + <0 0 4 &gic 0 4 4>, + <0 0 5 &gic 0 5 4>, + <0 0 6 &gic 0 6 4>, + <0 0 7 &gic 0 7 4>, + <0 0 8 &gic 0 8 4>, + <0 0 9 &gic 0 9 4>, + <0 0 10 &gic 0 10 4>, + <0 0 11 &gic 0 11 4>, + <0 0 12 &gic 0 12 4>, + <0 0 13 &gic 0 13 4>, + <0 0 14 &gic 0 14 4>, + <0 0 15 &gic 0 15 4>, + <0 0 16 &gic 0 16 4>, + <0 0 17 &gic 0 17 4>, + <0 0 18 &gic 0 18 4>, + <0 0 19 &gic 0 19 4>, + <0 0 20 &gic 0 20 4>, + <0 0 21 &gic 0 21 4>, + <0 0 22 &gic 0 22 4>, + <0 0 23 &gic 0 23 4>, + <0 0 24 &gic 0 24 4>, + <0 0 25 &gic 0 25 4>, + <0 0 26 &gic 0 26 4>, + <0 0 27 &gic 0 27 4>, + <0 0 28 &gic 0 28 4>, + <0 0 29 &gic 0 29 4>, + <0 0 30 &gic 0 30 4>, + <0 0 31 &gic 0 31 4>, + <0 0 32 &gic 0 32 4>, + <0 0 33 &gic 0 33 4>, + <0 0 34 &gic 0 34 4>, + <0 0 35 &gic 0 35 4>, + <0 0 36 &gic 0 36 4>, + <0 0 37 &gic 0 37 4>, + <0 0 38 &gic 0 38 4>, + <0 0 39 &gic 0 39 4>, + <0 0 40 &gic 0 40 4>, + <0 0 41 &gic 0 41 4>, + <0 0 42 &gic 0 42 4>; + }; +}; + +/include/ "vexpress-v2m.dtsi" diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c index c47d619..f0783be 100644 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c @@ -51,7 +51,6 @@ union gic_base { }; struct gic_chip_data { - unsigned int irq_offset; union gic_base dist_base; union gic_base cpu_base; #ifdef CONFIG_CPU_PM @@ -61,9 +60,7 @@ struct gic_chip_data { u32 __percpu *saved_ppi_enable; u32 __percpu *saved_ppi_conf; #endif -#ifdef CONFIG_IRQ_DOMAIN - struct irq_domain domain; -#endif + struct irq_domain *domain; unsigned int gic_irqs; #ifdef CONFIG_GIC_NON_BANKED void __iomem *(*get_base)(union gic_base *); @@ -282,7 +279,7 @@ asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) irqnr = irqstat & ~0x1c00; if (likely(irqnr > 15 && irqnr < 1021)) { - irqnr = irq_domain_to_irq(&gic->domain, irqnr); + irqnr = irq_find_mapping(gic->domain, irqnr); handle_IRQ(irqnr, regs); continue; } @@ -314,8 +311,8 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) if (gic_irq == 1023) goto out; - cascade_irq = irq_domain_to_irq(&chip_data->domain, gic_irq); - if (unlikely(gic_irq < 32 || gic_irq > 1020 || cascade_irq >= NR_IRQS)) + cascade_irq = irq_find_mapping(chip_data->domain, gic_irq); + if (unlikely(gic_irq < 32 || gic_irq > 1020)) do_bad_IRQ(cascade_irq, desc); else generic_handle_irq(cascade_irq); @@ -348,10 +345,9 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq) static void __init gic_dist_init(struct gic_chip_data *gic) { - unsigned int i, irq; + unsigned int i; u32 cpumask; unsigned int gic_irqs = gic->gic_irqs; - struct irq_domain *domain = &gic->domain; void __iomem *base = gic_data_dist_base(gic); u32 cpu = cpu_logical_map(smp_processor_id()); @@ -386,23 +382,6 @@ static void __init gic_dist_init(struct gic_chip_data *gic) for (i = 32; i < gic_irqs; i += 32) writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32); - /* - * Setup the Linux IRQ subsystem. - */ - irq_domain_for_each_irq(domain, i, irq) { - if (i < 32) { - irq_set_percpu_devid(irq); - irq_set_chip_and_handler(irq, &gic_chip, - handle_percpu_devid_irq); - set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN); - } else { - irq_set_chip_and_handler(irq, &gic_chip, - handle_fasteoi_irq); - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); - } - irq_set_chip_data(irq, gic); - } - writel_relaxed(1, base + GIC_DIST_CTRL); } @@ -618,11 +597,27 @@ static void __init gic_pm_init(struct gic_chip_data *gic) } #endif -#ifdef CONFIG_OF -static int gic_irq_domain_dt_translate(struct irq_domain *d, - struct device_node *controller, - const u32 *intspec, unsigned int intsize, - unsigned long *out_hwirq, unsigned int *out_type) +static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq, + irq_hw_number_t hw) +{ + if (hw < 32) { + irq_set_percpu_devid(irq); + irq_set_chip_and_handler(irq, &gic_chip, + handle_percpu_devid_irq); + set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN); + } else { + irq_set_chip_and_handler(irq, &gic_chip, + handle_fasteoi_irq); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + } + irq_set_chip_data(irq, d->host_data); + return 0; +} + +static int gic_irq_domain_xlate(struct irq_domain *d, + struct device_node *controller, + const u32 *intspec, unsigned int intsize, + unsigned long *out_hwirq, unsigned int *out_type) { if (d->of_node != controller) return -EINVAL; @@ -639,26 +634,23 @@ static int gic_irq_domain_dt_translate(struct irq_domain *d, *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK; return 0; } -#endif const struct irq_domain_ops gic_irq_domain_ops = { -#ifdef CONFIG_OF - .dt_translate = gic_irq_domain_dt_translate, -#endif + .map = gic_irq_domain_map, + .xlate = gic_irq_domain_xlate, }; void __init gic_init_bases(unsigned int gic_nr, int irq_start, void __iomem *dist_base, void __iomem *cpu_base, - u32 percpu_offset) + u32 percpu_offset, struct device_node *node) { + irq_hw_number_t hwirq_base; struct gic_chip_data *gic; - struct irq_domain *domain; - int gic_irqs; + int gic_irqs, irq_base; BUG_ON(gic_nr >= MAX_GIC_NR); gic = &gic_data[gic_nr]; - domain = &gic->domain; #ifdef CONFIG_GIC_NON_BANKED if (percpu_offset) { /* Frankein-GIC without banked registers... */ unsigned int cpu; @@ -694,10 +686,10 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, * For primary GICs, skip over SGIs. * For secondary GICs, skip over PPIs, too. */ - domain->hwirq_base = 32; + hwirq_base = 32; if (gic_nr == 0) { if ((irq_start & 31) > 0) { - domain->hwirq_base = 16; + hwirq_base = 16; if (irq_start != -1) irq_start = (irq_start & ~31) + 16; } @@ -713,17 +705,17 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, gic_irqs = 1020; gic->gic_irqs = gic_irqs; - domain->nr_irq = gic_irqs - domain->hwirq_base; - domain->irq_base = irq_alloc_descs(irq_start, 16, domain->nr_irq, - numa_node_id()); - if (IS_ERR_VALUE(domain->irq_base)) { + gic_irqs -= hwirq_base; /* calculate # of irqs to allocate */ + irq_base = irq_alloc_descs(irq_start, 16, gic_irqs, numa_node_id()); + if (IS_ERR_VALUE(irq_base)) { WARN(1, "Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n", irq_start); - domain->irq_base = irq_start; + irq_base = irq_start; } - domain->priv = gic; - domain->ops = &gic_irq_domain_ops; - irq_domain_add(domain); + gic->domain = irq_domain_add_legacy(node, gic_irqs, irq_base, + hwirq_base, &gic_irq_domain_ops, gic); + if (WARN_ON(!gic->domain)) + return; gic_chip.flags |= gic_arch_extn.flags; gic_dist_init(gic); @@ -768,7 +760,6 @@ int __init gic_of_init(struct device_node *node, struct device_node *parent) void __iomem *dist_base; u32 percpu_offset; int irq; - struct irq_domain *domain = &gic_data[gic_cnt].domain; if (WARN_ON(!node)) return -ENODEV; @@ -782,9 +773,7 @@ int __init gic_of_init(struct device_node *node, struct device_node *parent) if (of_property_read_u32(node, "cpu-offset", &percpu_offset)) percpu_offset = 0; - domain->of_node = of_node_get(node); - - gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset); + gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset, node); if (parent) { irq = irq_of_parse_and_map(node, 0); diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c index dcb004a..7a66311 100644 --- a/arch/arm/common/vic.c +++ b/arch/arm/common/vic.c @@ -56,7 +56,7 @@ struct vic_device { u32 int_enable; u32 soft_int; u32 protect; - struct irq_domain domain; + struct irq_domain *domain; }; /* we cannot allocate memory when VICs are initially registered */ @@ -192,14 +192,8 @@ static void __init vic_register(void __iomem *base, unsigned int irq, v->resume_sources = resume_sources; v->irq = irq; vic_id++; - - v->domain.irq_base = irq; - v->domain.nr_irq = 32; -#ifdef CONFIG_OF_IRQ - v->domain.of_node = of_node_get(node); -#endif /* CONFIG_OF */ - v->domain.ops = &irq_domain_simple_ops; - irq_domain_add(&v->domain); + v->domain = irq_domain_add_legacy(node, 32, irq, 0, + &irq_domain_simple_ops, v); } static void vic_ack_irq(struct irq_data *d) @@ -348,7 +342,7 @@ static void __init vic_init_st(void __iomem *base, unsigned int irq_start, vic_register(base, irq_start, 0, node); } -static void __init __vic_init(void __iomem *base, unsigned int irq_start, +void __init __vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources, struct device_node *node) { @@ -444,7 +438,7 @@ static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs) stat = readl_relaxed(vic->base + VIC_IRQ_STATUS); while (stat) { irq = ffs(stat) - 1; - handle_IRQ(irq_domain_to_irq(&vic->domain, irq), regs); + handle_IRQ(irq_find_mapping(vic->domain, irq), regs); stat &= ~(1 << irq); handled = 1; } diff --git a/arch/arm/configs/at91cap9_defconfig b/arch/arm/configs/at91cap9_defconfig deleted file mode 100644 index 8826eb2..0000000 --- a/arch/arm/configs/at91cap9_defconfig +++ /dev/null @@ -1,108 +0,0 @@ -CONFIG_EXPERIMENTAL=y -# CONFIG_LOCALVERSION_AUTO is not set -# CONFIG_SWAP is not set -CONFIG_SYSVIPC=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_BLK_DEV_INITRD=y -CONFIG_SLAB=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -CONFIG_ARCH_AT91=y -CONFIG_ARCH_AT91CAP9=y -CONFIG_MACH_AT91CAP9ADK=y -CONFIG_MTD_AT91_DATAFLASH_CARD=y -CONFIG_AT91_PROGRAMMABLE_CLOCKS=y -# CONFIG_ARM_THUMB is not set -CONFIG_AEABI=y -CONFIG_LEDS=y -CONFIG_LEDS_CPU=y -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/ram0 rw" -CONFIG_FPE_NWFPE=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_INET=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -# CONFIG_INET_DIAG is not set -# CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_JEDECPROBE=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_DATAFLASH=y -CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_ATMEL=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_SCSI=y -CONFIG_BLK_DEV_SD=y -CONFIG_SCSI_MULTI_LUN=y -CONFIG_NETDEVICES=y -CONFIG_MII=y -CONFIG_MACB=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -CONFIG_INPUT_EVDEV=y -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -CONFIG_INPUT_TOUCHSCREEN=y -CONFIG_TOUCHSCREEN_ADS7846=y -# CONFIG_SERIO is not set -CONFIG_SERIAL_ATMEL=y -CONFIG_SERIAL_ATMEL_CONSOLE=y -CONFIG_HW_RANDOM=y -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y -CONFIG_SPI=y -CONFIG_SPI_ATMEL=y -# CONFIG_HWMON is not set -CONFIG_WATCHDOG=y -CONFIG_WATCHDOG_NOWAYOUT=y -CONFIG_FB=y -CONFIG_FB_ATMEL=y -CONFIG_LOGO=y -# CONFIG_LOGO_LINUX_MONO is not set -# CONFIG_LOGO_LINUX_CLUT224 is not set -# CONFIG_USB_HID is not set -CONFIG_USB=y -CONFIG_USB_DEVICEFS=y -CONFIG_USB_MON=y -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_STORAGE=y -CONFIG_USB_GADGET=y -CONFIG_USB_ETH=m -CONFIG_USB_FILE_STORAGE=m -CONFIG_MMC=y -CONFIG_MMC_AT91=m -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_AT91SAM9=y -CONFIG_EXT2_FS=y -CONFIG_VFAT_FS=y -CONFIG_TMPFS=y -CONFIG_JFFS2_FS=y -CONFIG_CRAMFS=y -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_CODEPAGE_850=y -CONFIG_NLS_ISO8859_1=y -CONFIG_DEBUG_FS=y -CONFIG_DEBUG_KERNEL=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_USER=y diff --git a/arch/arm/include/asm/hardware/arm_timer.h b/arch/arm/include/asm/hardware/arm_timer.h index c0f4e7b..d6030ff 100644 --- a/arch/arm/include/asm/hardware/arm_timer.h +++ b/arch/arm/include/asm/hardware/arm_timer.h @@ -9,7 +9,12 @@ * * Integrator AP has 16-bit timers, Integrator CP, Versatile and Realview * can have 16-bit or 32-bit selectable via a bit in the control register. + * + * Every SP804 contains two identical timers. */ +#define TIMER_1_BASE 0x00 +#define TIMER_2_BASE 0x20 + #define TIMER_LOAD 0x00 /* ACVR rw */ #define TIMER_VALUE 0x04 /* ACVR ro */ #define TIMER_CTRL 0x08 /* ACVR rw */ diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h index 4bdfe00..4b1ce6c 100644 --- a/arch/arm/include/asm/hardware/gic.h +++ b/arch/arm/include/asm/hardware/gic.h @@ -39,7 +39,7 @@ struct device_node; extern struct irq_chip gic_arch_extn; void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *, - u32 offset); + u32 offset, struct device_node *); int gic_of_init(struct device_node *node, struct device_node *parent); void gic_secondary_init(unsigned int); void gic_handle_irq(struct pt_regs *regs); @@ -49,7 +49,7 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq); static inline void gic_init(unsigned int nr, int start, void __iomem *dist , void __iomem *cpu) { - gic_init_bases(nr, start, dist, cpu, 0); + gic_init_bases(nr, start, dist, cpu, 0, NULL); } #endif diff --git a/arch/arm/include/asm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h index f42ebd6..e14af1a 100644 --- a/arch/arm/include/asm/hardware/vic.h +++ b/arch/arm/include/asm/hardware/vic.h @@ -47,6 +47,8 @@ struct device_node; struct pt_regs; +void __vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, + u32 resume_sources, struct device_node *node); void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources); int vic_of_init(struct device_node *node, struct device_node *parent); void vic_handle_irq(struct pt_regs *regs); diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index e4c96cc..424aa45 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -110,6 +110,7 @@ extern void cpu_init(void); void soft_restart(unsigned long); extern void (*arm_pm_restart)(char str, const char *cmd); +extern void (*arm_pm_idle)(void); #define UDBG_UNDEFINED (1 << 0) #define UDBG_SYSCALL (1 << 1) diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 971d65c..008e7ce 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -61,8 +61,6 @@ extern void setup_mm_for_reboot(void); static volatile int hlt_counter; -#include <mach/system.h> - void disable_hlt(void) { hlt_counter++; @@ -181,13 +179,17 @@ void cpu_idle_wait(void) EXPORT_SYMBOL_GPL(cpu_idle_wait); /* - * This is our default idle handler. We need to disable - * interrupts here to ensure we don't miss a wakeup call. + * This is our default idle handler. */ + +void (*arm_pm_idle)(void); + static void default_idle(void) { - if (!need_resched()) - arch_idle(); + if (arm_pm_idle) + arm_pm_idle(); + else + cpu_do_idle(); local_irq_enable(); } @@ -215,6 +217,10 @@ void cpu_idle(void) cpu_die(); #endif + /* + * We need to disable interrupts here + * to ensure we don't miss a wakeup call. + */ local_irq_disable(); #ifdef CONFIG_PL310_ERRATA_769419 wmb(); @@ -222,19 +228,18 @@ void cpu_idle(void) if (hlt_counter) { local_irq_enable(); cpu_relax(); - } else { + } else if (!need_resched()) { stop_critical_timings(); if (cpuidle_idle_call()) pm_idle(); start_critical_timings(); /* - * This will eventually be removed - pm_idle - * functions should always return with IRQs - * enabled. + * pm_idle functions must always + * return with IRQs enabled. */ WARN_ON(irqs_disabled()); + } else local_irq_enable(); - } } leds_event(led_idle_end); rcu_idle_exit(); diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 71feb00..e55cdcb 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -102,13 +102,13 @@ config ARCH_AT91SAM9G45 select HAVE_AT91_DBGU1 select AT91_SAM9G45_RESET -config ARCH_AT91CAP9 - bool "AT91CAP9" +config ARCH_AT91SAM9X5 + bool "AT91SAM9x5 family" select CPU_ARM926T select GENERIC_CLOCKEVENTS select HAVE_FB_ATMEL select HAVE_NET_MACB - select HAVE_AT91_DBGU1 + select HAVE_AT91_DBGU0 select AT91_SAM9G45_RESET config ARCH_AT91X40 @@ -447,21 +447,6 @@ endif # ---------------------------------------------------------- -if ARCH_AT91CAP9 - -comment "AT91CAP9 Board Type" - -config MACH_AT91CAP9ADK - bool "Atmel AT91CAP9A-DK Evaluation Kit" - select HAVE_AT91_DATAFLASH_CARD - help - Select this if you are using Atmel's AT91CAP9A-DK Evaluation Kit. - <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4138> - -endif - -# ---------------------------------------------------------- - if ARCH_AT91X40 comment "AT91X40 Board Type" @@ -544,7 +529,7 @@ config AT91_EARLY_DBGU0 depends on HAVE_AT91_DBGU0 config AT91_EARLY_DBGU1 - bool "DBGU on 9263, 9g45 and cap9" + bool "DBGU on 9263 and 9g45" depends on HAVE_AT91_DBGU1 config AT91_EARLY_USART0 diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index 705e1fb..8512e53 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -20,7 +20,7 @@ obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_d obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o -obj-$(CONFIG_ARCH_AT91CAP9) += at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o +obj-$(CONFIG_ARCH_AT91SAM9X5) += at91sam9x5.o at91sam926x_time.o sam9_smc.o obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o # AT91RM9200 board-specific support @@ -81,9 +81,6 @@ obj-$(CONFIG_MACH_AT91SAM9M10G45EK) += board-sam9m10g45ek.o # AT91SAM board with device-tree obj-$(CONFIG_MACH_AT91SAM_DT) += board-dt.o -# AT91CAP9 board-specific support -obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o - # AT91X40 board-specific support obj-$(CONFIG_MACH_AT91EB01) += board-eb01.o diff --git a/arch/arm/mach-at91/Makefile.boot b/arch/arm/mach-at91/Makefile.boot index 8ddafad..0da66ca 100644 --- a/arch/arm/mach-at91/Makefile.boot +++ b/arch/arm/mach-at91/Makefile.boot @@ -3,11 +3,7 @@ # PARAMS_PHYS must be within 4MB of ZRELADDR # INITRD_PHYS must be in RAM -ifeq ($(CONFIG_ARCH_AT91CAP9),y) - zreladdr-y += 0x70008000 -params_phys-y := 0x70000100 -initrd_phys-y := 0x70410000 -else ifeq ($(CONFIG_ARCH_AT91SAM9G45),y) +ifeq ($(CONFIG_ARCH_AT91SAM9G45),y) zreladdr-y += 0x70008000 params_phys-y := 0x70000100 initrd_phys-y := 0x70410000 @@ -17,4 +13,10 @@ params_phys-y := 0x20000100 initrd_phys-y := 0x20410000 endif -dtb-$(CONFIG_MACH_AT91SAM_DT) += at91sam9m10g45ek.dtb usb_a9g20.dtb +# Keep dtb files sorted alphabetically for each SoC +# sam9g20 +dtb-$(CONFIG_MACH_AT91SAM_DT) += usb_a9g20.dtb +# sam9g45 +dtb-$(CONFIG_MACH_AT91SAM_DT) += at91sam9m10g45ek.dtb +# sam9x5 +dtb-$(CONFIG_MACH_AT91SAM_DT) += at91sam9g25ek.dtb diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c deleted file mode 100644 index a42edc2..0000000 --- a/arch/arm/mach-at91/at91cap9.c +++ /dev/null @@ -1,396 +0,0 @@ -/* - * arch/arm/mach-at91/at91cap9.c - * - * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com> - * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com> - * Copyright (C) 2007 Atmel Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - */ - -#include <linux/module.h> - -#include <asm/irq.h> -#include <asm/mach/arch.h> -#include <asm/mach/map.h> - -#include <mach/cpu.h> -#include <mach/at91cap9.h> -#include <mach/at91_pmc.h> - -#include "soc.h" -#include "generic.h" -#include "clock.h" -#include "sam9_smc.h" - -/* -------------------------------------------------------------------- - * Clocks - * -------------------------------------------------------------------- */ - -/* - * The peripheral clocks. - */ -static struct clk pioABCD_clk = { - .name = "pioABCD_clk", - .pmc_mask = 1 << AT91CAP9_ID_PIOABCD, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mpb0_clk = { - .name = "mpb0_clk", - .pmc_mask = 1 << AT91CAP9_ID_MPB0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mpb1_clk = { - .name = "mpb1_clk", - .pmc_mask = 1 << AT91CAP9_ID_MPB1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mpb2_clk = { - .name = "mpb2_clk", - .pmc_mask = 1 << AT91CAP9_ID_MPB2, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mpb3_clk = { - .name = "mpb3_clk", - .pmc_mask = 1 << AT91CAP9_ID_MPB3, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mpb4_clk = { - .name = "mpb4_clk", - .pmc_mask = 1 << AT91CAP9_ID_MPB4, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart0_clk = { - .name = "usart0_clk", - .pmc_mask = 1 << AT91CAP9_ID_US0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart1_clk = { - .name = "usart1_clk", - .pmc_mask = 1 << AT91CAP9_ID_US1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart2_clk = { - .name = "usart2_clk", - .pmc_mask = 1 << AT91CAP9_ID_US2, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mmc0_clk = { - .name = "mci0_clk", - .pmc_mask = 1 << AT91CAP9_ID_MCI0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mmc1_clk = { - .name = "mci1_clk", - .pmc_mask = 1 << AT91CAP9_ID_MCI1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk can_clk = { - .name = "can_clk", - .pmc_mask = 1 << AT91CAP9_ID_CAN, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk twi_clk = { - .name = "twi_clk", - .pmc_mask = 1 << AT91CAP9_ID_TWI, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk spi0_clk = { - .name = "spi0_clk", - .pmc_mask = 1 << AT91CAP9_ID_SPI0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk spi1_clk = { - .name = "spi1_clk", - .pmc_mask = 1 << AT91CAP9_ID_SPI1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ssc0_clk = { - .name = "ssc0_clk", - .pmc_mask = 1 << AT91CAP9_ID_SSC0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ssc1_clk = { - .name = "ssc1_clk", - .pmc_mask = 1 << AT91CAP9_ID_SSC1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ac97_clk = { - .name = "ac97_clk", - .pmc_mask = 1 << AT91CAP9_ID_AC97C, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk tcb_clk = { - .name = "tcb_clk", - .pmc_mask = 1 << AT91CAP9_ID_TCB, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pwm_clk = { - .name = "pwm_clk", - .pmc_mask = 1 << AT91CAP9_ID_PWMC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk macb_clk = { - .name = "pclk", - .pmc_mask = 1 << AT91CAP9_ID_EMAC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk aestdes_clk = { - .name = "aestdes_clk", - .pmc_mask = 1 << AT91CAP9_ID_AESTDES, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk adc_clk = { - .name = "adc_clk", - .pmc_mask = 1 << AT91CAP9_ID_ADC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk isi_clk = { - .name = "isi_clk", - .pmc_mask = 1 << AT91CAP9_ID_ISI, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk lcdc_clk = { - .name = "lcdc_clk", - .pmc_mask = 1 << AT91CAP9_ID_LCDC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk dma_clk = { - .name = "dma_clk", - .pmc_mask = 1 << AT91CAP9_ID_DMA, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk udphs_clk = { - .name = "udphs_clk", - .pmc_mask = 1 << AT91CAP9_ID_UDPHS, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ohci_clk = { - .name = "ohci_clk", - .pmc_mask = 1 << AT91CAP9_ID_UHP, - .type = CLK_TYPE_PERIPHERAL, -}; - -static struct clk *periph_clocks[] __initdata = { - &pioABCD_clk, - &mpb0_clk, - &mpb1_clk, - &mpb2_clk, - &mpb3_clk, - &mpb4_clk, - &usart0_clk, - &usart1_clk, - &usart2_clk, - &mmc0_clk, - &mmc1_clk, - &can_clk, - &twi_clk, - &spi0_clk, - &spi1_clk, - &ssc0_clk, - &ssc1_clk, - &ac97_clk, - &tcb_clk, - &pwm_clk, - &macb_clk, - &aestdes_clk, - &adc_clk, - &isi_clk, - &lcdc_clk, - &dma_clk, - &udphs_clk, - &ohci_clk, - // irq0 .. irq1 -}; - -static struct clk_lookup periph_clocks_lookups[] = { - /* One additional fake clock for macb_hclk */ - CLKDEV_CON_ID("hclk", &macb_clk), - CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk), - CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk), - CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.0", &mmc0_clk), - CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.1", &mmc1_clk), - CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), - CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), - CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk), - CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), - CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), - /* fake hclk clock */ - CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), - CLKDEV_CON_ID("pioA", &pioABCD_clk), - CLKDEV_CON_ID("pioB", &pioABCD_clk), - CLKDEV_CON_ID("pioC", &pioABCD_clk), - CLKDEV_CON_ID("pioD", &pioABCD_clk), -}; - -static struct clk_lookup usart_clocks_lookups[] = { - CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk), -}; - -/* - * The four programmable clocks. - * You must configure pin multiplexing to bring these signals out. - */ -static struct clk pck0 = { - .name = "pck0", - .pmc_mask = AT91_PMC_PCK0, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 0, -}; -static struct clk pck1 = { - .name = "pck1", - .pmc_mask = AT91_PMC_PCK1, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 1, -}; -static struct clk pck2 = { - .name = "pck2", - .pmc_mask = AT91_PMC_PCK2, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 2, -}; -static struct clk pck3 = { - .name = "pck3", - .pmc_mask = AT91_PMC_PCK3, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 3, -}; - -static void __init at91cap9_register_clocks(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) - clk_register(periph_clocks[i]); - - clkdev_add_table(periph_clocks_lookups, - ARRAY_SIZE(periph_clocks_lookups)); - clkdev_add_table(usart_clocks_lookups, - ARRAY_SIZE(usart_clocks_lookups)); - - clk_register(&pck0); - clk_register(&pck1); - clk_register(&pck2); - clk_register(&pck3); -} - -static struct clk_lookup console_clock_lookup; - -void __init at91cap9_set_console_clock(int id) -{ - if (id >= ARRAY_SIZE(usart_clocks_lookups)) - return; - - console_clock_lookup.con_id = "usart"; - console_clock_lookup.clk = usart_clocks_lookups[id].clk; - clkdev_add(&console_clock_lookup); -} - -/* -------------------------------------------------------------------- - * GPIO - * -------------------------------------------------------------------- */ - -static struct at91_gpio_bank at91cap9_gpio[] __initdata = { - { - .id = AT91CAP9_ID_PIOABCD, - .regbase = AT91CAP9_BASE_PIOA, - }, { - .id = AT91CAP9_ID_PIOABCD, - .regbase = AT91CAP9_BASE_PIOB, - }, { - .id = AT91CAP9_ID_PIOABCD, - .regbase = AT91CAP9_BASE_PIOC, - }, { - .id = AT91CAP9_ID_PIOABCD, - .regbase = AT91CAP9_BASE_PIOD, - } -}; - -/* -------------------------------------------------------------------- - * AT91CAP9 processor initialization - * -------------------------------------------------------------------- */ - -static void __init at91cap9_map_io(void) -{ - at91_init_sram(0, AT91CAP9_SRAM_BASE, AT91CAP9_SRAM_SIZE); -} - -static void __init at91cap9_ioremap_registers(void) -{ - at91_ioremap_shdwc(AT91CAP9_BASE_SHDWC); - at91_ioremap_rstc(AT91CAP9_BASE_RSTC); - at91sam926x_ioremap_pit(AT91CAP9_BASE_PIT); - at91sam9_ioremap_smc(0, AT91CAP9_BASE_SMC); -} - -static void __init at91cap9_initialize(void) -{ - arm_pm_restart = at91sam9g45_restart; - at91_extern_irq = (1 << AT91CAP9_ID_IRQ0) | (1 << AT91CAP9_ID_IRQ1); - - /* Register GPIO subsystem */ - at91_gpio_init(at91cap9_gpio, 4); - - /* Remember the silicon revision */ - if (cpu_is_at91cap9_revB()) - system_rev = 0xB; - else if (cpu_is_at91cap9_revC()) - system_rev = 0xC; -} - -/* -------------------------------------------------------------------- - * Interrupt initialization - * -------------------------------------------------------------------- */ - -/* - * The default interrupt priority levels (0 = lowest, 7 = highest). - */ -static unsigned int at91cap9_default_irq_priority[NR_AIC_IRQS] __initdata = { - 7, /* Advanced Interrupt Controller (FIQ) */ - 7, /* System Peripherals */ - 1, /* Parallel IO Controller A, B, C and D */ - 0, /* MP Block Peripheral 0 */ - 0, /* MP Block Peripheral 1 */ - 0, /* MP Block Peripheral 2 */ - 0, /* MP Block Peripheral 3 */ - 0, /* MP Block Peripheral 4 */ - 5, /* USART 0 */ - 5, /* USART 1 */ - 5, /* USART 2 */ - 0, /* Multimedia Card Interface 0 */ - 0, /* Multimedia Card Interface 1 */ - 3, /* CAN */ - 6, /* Two-Wire Interface */ - 5, /* Serial Peripheral Interface 0 */ - 5, /* Serial Peripheral Interface 1 */ - 4, /* Serial Synchronous Controller 0 */ - 4, /* Serial Synchronous Controller 1 */ - 5, /* AC97 Controller */ - 0, /* Timer Counter 0, 1 and 2 */ - 0, /* Pulse Width Modulation Controller */ - 3, /* Ethernet */ - 0, /* Advanced Encryption Standard, Triple DES*/ - 0, /* Analog-to-Digital Converter */ - 0, /* Image Sensor Interface */ - 3, /* LCD Controller */ - 0, /* DMA Controller */ - 2, /* USB Device Port */ - 2, /* USB Host port */ - 0, /* Advanced Interrupt Controller (IRQ0) */ - 0, /* Advanced Interrupt Controller (IRQ1) */ -}; - -struct at91_init_soc __initdata at91cap9_soc = { - .map_io = at91cap9_map_io, - .default_irq_priority = at91cap9_default_irq_priority, - .ioremap_registers = at91cap9_ioremap_registers, - .register_clocks = at91cap9_register_clocks, - .init = at91cap9_initialize, -}; diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c deleted file mode 100644 index d298fb7..0000000 --- a/arch/arm/mach-at91/at91cap9_devices.c +++ /dev/null @@ -1,1273 +0,0 @@ -/* - * arch/arm/mach-at91/at91cap9_devices.c - * - * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com> - * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com> - * Copyright (C) 2007 Atmel Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - */ -#include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/irq.h> - -#include <linux/dma-mapping.h> -#include <linux/gpio.h> -#include <linux/platform_device.h> -#include <linux/i2c-gpio.h> - -#include <video/atmel_lcdc.h> - -#include <mach/board.h> -#include <mach/cpu.h> -#include <mach/at91cap9.h> -#include <mach/at91cap9_matrix.h> -#include <mach/at91sam9_smc.h> - -#include "generic.h" - - -/* -------------------------------------------------------------------- - * USB Host - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) -static u64 ohci_dmamask = DMA_BIT_MASK(32); -static struct at91_usbh_data usbh_data; - -static struct resource usbh_resources[] = { - [0] = { - .start = AT91CAP9_UHP_BASE, - .end = AT91CAP9_UHP_BASE + SZ_1M - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_ID_UHP, - .end = AT91CAP9_ID_UHP, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91_usbh_device = { - .name = "at91_ohci", - .id = -1, - .dev = { - .dma_mask = &ohci_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &usbh_data, - }, - .resource = usbh_resources, - .num_resources = ARRAY_SIZE(usbh_resources), -}; - -void __init at91_add_device_usbh(struct at91_usbh_data *data) -{ - int i; - - if (!data) - return; - - if (cpu_is_at91cap9_revB()) - irq_set_irq_type(AT91CAP9_ID_UHP, IRQ_TYPE_LEVEL_HIGH); - - /* Enable VBus control for UHP ports */ - for (i = 0; i < data->ports; i++) { - if (gpio_is_valid(data->vbus_pin[i])) - at91_set_gpio_output(data->vbus_pin[i], 0); - } - - /* Enable overcurrent notification */ - for (i = 0; i < data->ports; i++) { - if (data->overcurrent_pin[i]) - at91_set_gpio_input(data->overcurrent_pin[i], 1); - } - - usbh_data = *data; - platform_device_register(&at91_usbh_device); -} -#else -void __init at91_add_device_usbh(struct at91_usbh_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * USB HS Device (Gadget) - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_USB_ATMEL_USBA) || defined(CONFIG_USB_ATMEL_USBA_MODULE) - -static struct resource usba_udc_resources[] = { - [0] = { - .start = AT91CAP9_UDPHS_FIFO, - .end = AT91CAP9_UDPHS_FIFO + SZ_512K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_BASE_UDPHS, - .end = AT91CAP9_BASE_UDPHS + SZ_1K - 1, - .flags = IORESOURCE_MEM, - }, - [2] = { - .start = AT91CAP9_ID_UDPHS, - .end = AT91CAP9_ID_UDPHS, - .flags = IORESOURCE_IRQ, - }, -}; - -#define EP(nam, idx, maxpkt, maxbk, dma, isoc) \ - [idx] = { \ - .name = nam, \ - .index = idx, \ - .fifo_size = maxpkt, \ - .nr_banks = maxbk, \ - .can_dma = dma, \ - .can_isoc = isoc, \ - } - -static struct usba_ep_data usba_udc_ep[] = { - EP("ep0", 0, 64, 1, 0, 0), - EP("ep1", 1, 1024, 3, 1, 1), - EP("ep2", 2, 1024, 3, 1, 1), - EP("ep3", 3, 1024, 2, 1, 1), - EP("ep4", 4, 1024, 2, 1, 1), - EP("ep5", 5, 1024, 2, 1, 0), - EP("ep6", 6, 1024, 2, 1, 0), - EP("ep7", 7, 1024, 2, 0, 0), -}; - -#undef EP - -/* - * pdata doesn't have room for any endpoints, so we need to - * append room for the ones we need right after it. - */ -static struct { - struct usba_platform_data pdata; - struct usba_ep_data ep[8]; -} usba_udc_data; - -static struct platform_device at91_usba_udc_device = { - .name = "atmel_usba_udc", - .id = -1, - .dev = { - .platform_data = &usba_udc_data.pdata, - }, - .resource = usba_udc_resources, - .num_resources = ARRAY_SIZE(usba_udc_resources), -}; - -void __init at91_add_device_usba(struct usba_platform_data *data) -{ - if (cpu_is_at91cap9_revB()) { - irq_set_irq_type(AT91CAP9_ID_UDPHS, IRQ_TYPE_LEVEL_HIGH); - at91_sys_write(AT91_MATRIX_UDPHS, AT91_MATRIX_SELECT_UDPHS | - AT91_MATRIX_UDPHS_BYPASS_LOCK); - } - else - at91_sys_write(AT91_MATRIX_UDPHS, AT91_MATRIX_SELECT_UDPHS); - - /* - * Invalid pins are 0 on AT91, but the usba driver is shared - * with AVR32, which use negative values instead. Once/if - * gpio_is_valid() is ported to AT91, revisit this code. - */ - usba_udc_data.pdata.vbus_pin = -EINVAL; - usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep); - memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep)); - - if (data && gpio_is_valid(data->vbus_pin)) { - at91_set_gpio_input(data->vbus_pin, 0); - at91_set_deglitch(data->vbus_pin, 1); - usba_udc_data.pdata.vbus_pin = data->vbus_pin; - } - - /* Pullup pin is handled internally by USB device peripheral */ - - platform_device_register(&at91_usba_udc_device); -} -#else -void __init at91_add_device_usba(struct usba_platform_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * Ethernet - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) -static u64 eth_dmamask = DMA_BIT_MASK(32); -static struct macb_platform_data eth_data; - -static struct resource eth_resources[] = { - [0] = { - .start = AT91CAP9_BASE_EMAC, - .end = AT91CAP9_BASE_EMAC + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_ID_EMAC, - .end = AT91CAP9_ID_EMAC, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91cap9_eth_device = { - .name = "macb", - .id = -1, - .dev = { - .dma_mask = ð_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = ð_data, - }, - .resource = eth_resources, - .num_resources = ARRAY_SIZE(eth_resources), -}; - -void __init at91_add_device_eth(struct macb_platform_data *data) -{ - if (!data) - return; - - if (gpio_is_valid(data->phy_irq_pin)) { - at91_set_gpio_input(data->phy_irq_pin, 0); - at91_set_deglitch(data->phy_irq_pin, 1); - } - - /* Pins used for MII and RMII */ - at91_set_A_periph(AT91_PIN_PB21, 0); /* ETXCK_EREFCK */ - at91_set_A_periph(AT91_PIN_PB22, 0); /* ERXDV */ - at91_set_A_periph(AT91_PIN_PB25, 0); /* ERX0 */ - at91_set_A_periph(AT91_PIN_PB26, 0); /* ERX1 */ - at91_set_A_periph(AT91_PIN_PB27, 0); /* ERXER */ - at91_set_A_periph(AT91_PIN_PB28, 0); /* ETXEN */ - at91_set_A_periph(AT91_PIN_PB23, 0); /* ETX0 */ - at91_set_A_periph(AT91_PIN_PB24, 0); /* ETX1 */ - at91_set_A_periph(AT91_PIN_PB30, 0); /* EMDIO */ - at91_set_A_periph(AT91_PIN_PB29, 0); /* EMDC */ - - if (!data->is_rmii) { - at91_set_B_periph(AT91_PIN_PC25, 0); /* ECRS */ - at91_set_B_periph(AT91_PIN_PC26, 0); /* ECOL */ - at91_set_B_periph(AT91_PIN_PC22, 0); /* ERX2 */ - at91_set_B_periph(AT91_PIN_PC23, 0); /* ERX3 */ - at91_set_B_periph(AT91_PIN_PC27, 0); /* ERXCK */ - at91_set_B_periph(AT91_PIN_PC20, 0); /* ETX2 */ - at91_set_B_periph(AT91_PIN_PC21, 0); /* ETX3 */ - at91_set_B_periph(AT91_PIN_PC24, 0); /* ETXER */ - } - - eth_data = *data; - platform_device_register(&at91cap9_eth_device); -} -#else -void __init at91_add_device_eth(struct macb_platform_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * MMC / SD - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) -static u64 mmc_dmamask = DMA_BIT_MASK(32); -static struct at91_mmc_data mmc0_data, mmc1_data; - -static struct resource mmc0_resources[] = { - [0] = { - .start = AT91CAP9_BASE_MCI0, - .end = AT91CAP9_BASE_MCI0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_ID_MCI0, - .end = AT91CAP9_ID_MCI0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91cap9_mmc0_device = { - .name = "at91_mci", - .id = 0, - .dev = { - .dma_mask = &mmc_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &mmc0_data, - }, - .resource = mmc0_resources, - .num_resources = ARRAY_SIZE(mmc0_resources), -}; - -static struct resource mmc1_resources[] = { - [0] = { - .start = AT91CAP9_BASE_MCI1, - .end = AT91CAP9_BASE_MCI1 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_ID_MCI1, - .end = AT91CAP9_ID_MCI1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91cap9_mmc1_device = { - .name = "at91_mci", - .id = 1, - .dev = { - .dma_mask = &mmc_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &mmc1_data, - }, - .resource = mmc1_resources, - .num_resources = ARRAY_SIZE(mmc1_resources), -}; - -void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) -{ - if (!data) - return; - - /* input/irq */ - if (gpio_is_valid(data->det_pin)) { - at91_set_gpio_input(data->det_pin, 1); - at91_set_deglitch(data->det_pin, 1); - } - if (gpio_is_valid(data->wp_pin)) - at91_set_gpio_input(data->wp_pin, 1); - if (gpio_is_valid(data->vcc_pin)) - at91_set_gpio_output(data->vcc_pin, 0); - - if (mmc_id == 0) { /* MCI0 */ - /* CLK */ - at91_set_A_periph(AT91_PIN_PA2, 0); - - /* CMD */ - at91_set_A_periph(AT91_PIN_PA1, 1); - - /* DAT0, maybe DAT1..DAT3 */ - at91_set_A_periph(AT91_PIN_PA0, 1); - if (data->wire4) { - at91_set_A_periph(AT91_PIN_PA3, 1); - at91_set_A_periph(AT91_PIN_PA4, 1); - at91_set_A_periph(AT91_PIN_PA5, 1); - } - - mmc0_data = *data; - platform_device_register(&at91cap9_mmc0_device); - } else { /* MCI1 */ - /* CLK */ - at91_set_A_periph(AT91_PIN_PA16, 0); - - /* CMD */ - at91_set_A_periph(AT91_PIN_PA17, 1); - - /* DAT0, maybe DAT1..DAT3 */ - at91_set_A_periph(AT91_PIN_PA18, 1); - if (data->wire4) { - at91_set_A_periph(AT91_PIN_PA19, 1); - at91_set_A_periph(AT91_PIN_PA20, 1); - at91_set_A_periph(AT91_PIN_PA21, 1); - } - - mmc1_data = *data; - platform_device_register(&at91cap9_mmc1_device); - } -} -#else -void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * NAND / SmartMedia - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE) -static struct atmel_nand_data nand_data; - -#define NAND_BASE AT91_CHIPSELECT_3 - -static struct resource nand_resources[] = { - [0] = { - .start = NAND_BASE, - .end = NAND_BASE + SZ_256M - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_BASE_ECC, - .end = AT91CAP9_BASE_ECC + SZ_512 - 1, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device at91cap9_nand_device = { - .name = "atmel_nand", - .id = -1, - .dev = { - .platform_data = &nand_data, - }, - .resource = nand_resources, - .num_resources = ARRAY_SIZE(nand_resources), -}; - -void __init at91_add_device_nand(struct atmel_nand_data *data) -{ - unsigned long csa; - - if (!data) - return; - - csa = at91_sys_read(AT91_MATRIX_EBICSA); - at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA); - - /* enable pin */ - if (gpio_is_valid(data->enable_pin)) - at91_set_gpio_output(data->enable_pin, 1); - - /* ready/busy pin */ - if (gpio_is_valid(data->rdy_pin)) - at91_set_gpio_input(data->rdy_pin, 1); - - /* card detect pin */ - if (gpio_is_valid(data->det_pin)) - at91_set_gpio_input(data->det_pin, 1); - - nand_data = *data; - platform_device_register(&at91cap9_nand_device); -} -#else -void __init at91_add_device_nand(struct atmel_nand_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * TWI (i2c) - * -------------------------------------------------------------------- */ - -/* - * Prefer the GPIO code since the TWI controller isn't robust - * (gets overruns and underruns under load) and can only issue - * repeated STARTs in one scenario (the driver doesn't yet handle them). - */ -#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) - -static struct i2c_gpio_platform_data pdata = { - .sda_pin = AT91_PIN_PB4, - .sda_is_open_drain = 1, - .scl_pin = AT91_PIN_PB5, - .scl_is_open_drain = 1, - .udelay = 2, /* ~100 kHz */ -}; - -static struct platform_device at91cap9_twi_device = { - .name = "i2c-gpio", - .id = -1, - .dev.platform_data = &pdata, -}; - -void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) -{ - at91_set_GPIO_periph(AT91_PIN_PB4, 1); /* TWD (SDA) */ - at91_set_multi_drive(AT91_PIN_PB4, 1); - - at91_set_GPIO_periph(AT91_PIN_PB5, 1); /* TWCK (SCL) */ - at91_set_multi_drive(AT91_PIN_PB5, 1); - - i2c_register_board_info(0, devices, nr_devices); - platform_device_register(&at91cap9_twi_device); -} - -#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) - -static struct resource twi_resources[] = { - [0] = { - .start = AT91CAP9_BASE_TWI, - .end = AT91CAP9_BASE_TWI + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_ID_TWI, - .end = AT91CAP9_ID_TWI, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91cap9_twi_device = { - .name = "at91_i2c", - .id = -1, - .resource = twi_resources, - .num_resources = ARRAY_SIZE(twi_resources), -}; - -void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) -{ - /* pins used for TWI interface */ - at91_set_B_periph(AT91_PIN_PB4, 0); /* TWD */ - at91_set_multi_drive(AT91_PIN_PB4, 1); - - at91_set_B_periph(AT91_PIN_PB5, 0); /* TWCK */ - at91_set_multi_drive(AT91_PIN_PB5, 1); - - i2c_register_board_info(0, devices, nr_devices); - platform_device_register(&at91cap9_twi_device); -} -#else -void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {} -#endif - -/* -------------------------------------------------------------------- - * SPI - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) -static u64 spi_dmamask = DMA_BIT_MASK(32); - -static struct resource spi0_resources[] = { - [0] = { - .start = AT91CAP9_BASE_SPI0, - .end = AT91CAP9_BASE_SPI0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_ID_SPI0, - .end = AT91CAP9_ID_SPI0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91cap9_spi0_device = { - .name = "atmel_spi", - .id = 0, - .dev = { - .dma_mask = &spi_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = spi0_resources, - .num_resources = ARRAY_SIZE(spi0_resources), -}; - -static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA5, AT91_PIN_PA3, AT91_PIN_PD0, AT91_PIN_PD1 }; - -static struct resource spi1_resources[] = { - [0] = { - .start = AT91CAP9_BASE_SPI1, - .end = AT91CAP9_BASE_SPI1 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_ID_SPI1, - .end = AT91CAP9_ID_SPI1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91cap9_spi1_device = { - .name = "atmel_spi", - .id = 1, - .dev = { - .dma_mask = &spi_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = spi1_resources, - .num_resources = ARRAY_SIZE(spi1_resources), -}; - -static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB15, AT91_PIN_PB16, AT91_PIN_PB17, AT91_PIN_PB18 }; - -void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) -{ - int i; - unsigned long cs_pin; - short enable_spi0 = 0; - short enable_spi1 = 0; - - /* Choose SPI chip-selects */ - for (i = 0; i < nr_devices; i++) { - if (devices[i].controller_data) - cs_pin = (unsigned long) devices[i].controller_data; - else if (devices[i].bus_num == 0) - cs_pin = spi0_standard_cs[devices[i].chip_select]; - else - cs_pin = spi1_standard_cs[devices[i].chip_select]; - - if (devices[i].bus_num == 0) - enable_spi0 = 1; - else - enable_spi1 = 1; - - /* enable chip-select pin */ - at91_set_gpio_output(cs_pin, 1); - - /* pass chip-select pin to driver */ - devices[i].controller_data = (void *) cs_pin; - } - - spi_register_board_info(devices, nr_devices); - - /* Configure SPI bus(es) */ - if (enable_spi0) { - at91_set_B_periph(AT91_PIN_PA0, 0); /* SPI0_MISO */ - at91_set_B_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */ - at91_set_B_periph(AT91_PIN_PA2, 0); /* SPI0_SPCK */ - - platform_device_register(&at91cap9_spi0_device); - } - if (enable_spi1) { - at91_set_A_periph(AT91_PIN_PB12, 0); /* SPI1_MISO */ - at91_set_A_periph(AT91_PIN_PB13, 0); /* SPI1_MOSI */ - at91_set_A_periph(AT91_PIN_PB14, 0); /* SPI1_SPCK */ - - platform_device_register(&at91cap9_spi1_device); - } -} -#else -void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} -#endif - - -/* -------------------------------------------------------------------- - * Timer/Counter block - * -------------------------------------------------------------------- */ - -#ifdef CONFIG_ATMEL_TCLIB - -static struct resource tcb_resources[] = { - [0] = { - .start = AT91CAP9_BASE_TCB0, - .end = AT91CAP9_BASE_TCB0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_ID_TCB, - .end = AT91CAP9_ID_TCB, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91cap9_tcb_device = { - .name = "atmel_tcb", - .id = 0, - .resource = tcb_resources, - .num_resources = ARRAY_SIZE(tcb_resources), -}; - -static void __init at91_add_device_tc(void) -{ - platform_device_register(&at91cap9_tcb_device); -} -#else -static void __init at91_add_device_tc(void) { } -#endif - - -/* -------------------------------------------------------------------- - * RTT - * -------------------------------------------------------------------- */ - -static struct resource rtt_resources[] = { - { - .start = AT91CAP9_BASE_RTT, - .end = AT91CAP9_BASE_RTT + SZ_16 - 1, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device at91cap9_rtt_device = { - .name = "at91_rtt", - .id = 0, - .resource = rtt_resources, - .num_resources = ARRAY_SIZE(rtt_resources), -}; - -static void __init at91_add_device_rtt(void) -{ - platform_device_register(&at91cap9_rtt_device); -} - - -/* -------------------------------------------------------------------- - * Watchdog - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) -static struct resource wdt_resources[] = { - { - .start = AT91CAP9_BASE_WDT, - .end = AT91CAP9_BASE_WDT + SZ_16 - 1, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device at91cap9_wdt_device = { - .name = "at91_wdt", - .id = -1, - .resource = wdt_resources, - .num_resources = ARRAY_SIZE(wdt_resources), -}; - -static void __init at91_add_device_watchdog(void) -{ - platform_device_register(&at91cap9_wdt_device); -} -#else -static void __init at91_add_device_watchdog(void) {} -#endif - - -/* -------------------------------------------------------------------- - * PWM - * --------------------------------------------------------------------*/ - -#if defined(CONFIG_ATMEL_PWM) -static u32 pwm_mask; - -static struct resource pwm_resources[] = { - [0] = { - .start = AT91CAP9_BASE_PWMC, - .end = AT91CAP9_BASE_PWMC + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_ID_PWMC, - .end = AT91CAP9_ID_PWMC, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91cap9_pwm0_device = { - .name = "atmel_pwm", - .id = -1, - .dev = { - .platform_data = &pwm_mask, - }, - .resource = pwm_resources, - .num_resources = ARRAY_SIZE(pwm_resources), -}; - -void __init at91_add_device_pwm(u32 mask) -{ - if (mask & (1 << AT91_PWM0)) - at91_set_A_periph(AT91_PIN_PB19, 1); /* enable PWM0 */ - - if (mask & (1 << AT91_PWM1)) - at91_set_B_periph(AT91_PIN_PB8, 1); /* enable PWM1 */ - - if (mask & (1 << AT91_PWM2)) - at91_set_B_periph(AT91_PIN_PC29, 1); /* enable PWM2 */ - - if (mask & (1 << AT91_PWM3)) - at91_set_B_periph(AT91_PIN_PA11, 1); /* enable PWM3 */ - - pwm_mask = mask; - - platform_device_register(&at91cap9_pwm0_device); -} -#else -void __init at91_add_device_pwm(u32 mask) {} -#endif - - - -/* -------------------------------------------------------------------- - * AC97 - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_SND_ATMEL_AC97C) || defined(CONFIG_SND_ATMEL_AC97C_MODULE) -static u64 ac97_dmamask = DMA_BIT_MASK(32); -static struct ac97c_platform_data ac97_data; - -static struct resource ac97_resources[] = { - [0] = { - .start = AT91CAP9_BASE_AC97C, - .end = AT91CAP9_BASE_AC97C + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_ID_AC97C, - .end = AT91CAP9_ID_AC97C, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91cap9_ac97_device = { - .name = "atmel_ac97c", - .id = 1, - .dev = { - .dma_mask = &ac97_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &ac97_data, - }, - .resource = ac97_resources, - .num_resources = ARRAY_SIZE(ac97_resources), -}; - -void __init at91_add_device_ac97(struct ac97c_platform_data *data) -{ - if (!data) - return; - - at91_set_A_periph(AT91_PIN_PA6, 0); /* AC97FS */ - at91_set_A_periph(AT91_PIN_PA7, 0); /* AC97CK */ - at91_set_A_periph(AT91_PIN_PA8, 0); /* AC97TX */ - at91_set_A_periph(AT91_PIN_PA9, 0); /* AC97RX */ - - /* reset */ - if (gpio_is_valid(data->reset_pin)) - at91_set_gpio_output(data->reset_pin, 0); - - ac97_data = *data; - platform_device_register(&at91cap9_ac97_device); -} -#else -void __init at91_add_device_ac97(struct ac97c_platform_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * LCD Controller - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) -static u64 lcdc_dmamask = DMA_BIT_MASK(32); -static struct atmel_lcdfb_info lcdc_data; - -static struct resource lcdc_resources[] = { - [0] = { - .start = AT91CAP9_LCDC_BASE, - .end = AT91CAP9_LCDC_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_ID_LCDC, - .end = AT91CAP9_ID_LCDC, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91_lcdc_device = { - .name = "atmel_lcdfb", - .id = 0, - .dev = { - .dma_mask = &lcdc_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &lcdc_data, - }, - .resource = lcdc_resources, - .num_resources = ARRAY_SIZE(lcdc_resources), -}; - -void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) -{ - if (!data) - return; - - if (cpu_is_at91cap9_revB()) - irq_set_irq_type(AT91CAP9_ID_LCDC, IRQ_TYPE_LEVEL_HIGH); - - at91_set_A_periph(AT91_PIN_PC1, 0); /* LCDHSYNC */ - at91_set_A_periph(AT91_PIN_PC2, 0); /* LCDDOTCK */ - at91_set_A_periph(AT91_PIN_PC3, 0); /* LCDDEN */ - at91_set_B_periph(AT91_PIN_PB9, 0); /* LCDCC */ - at91_set_A_periph(AT91_PIN_PC6, 0); /* LCDD2 */ - at91_set_A_periph(AT91_PIN_PC7, 0); /* LCDD3 */ - at91_set_A_periph(AT91_PIN_PC8, 0); /* LCDD4 */ - at91_set_A_periph(AT91_PIN_PC9, 0); /* LCDD5 */ - at91_set_A_periph(AT91_PIN_PC10, 0); /* LCDD6 */ - at91_set_A_periph(AT91_PIN_PC11, 0); /* LCDD7 */ - at91_set_A_periph(AT91_PIN_PC14, 0); /* LCDD10 */ - at91_set_A_periph(AT91_PIN_PC15, 0); /* LCDD11 */ - at91_set_A_periph(AT91_PIN_PC16, 0); /* LCDD12 */ - at91_set_A_periph(AT91_PIN_PC17, 0); /* LCDD13 */ - at91_set_A_periph(AT91_PIN_PC18, 0); /* LCDD14 */ - at91_set_A_periph(AT91_PIN_PC19, 0); /* LCDD15 */ - at91_set_A_periph(AT91_PIN_PC22, 0); /* LCDD18 */ - at91_set_A_periph(AT91_PIN_PC23, 0); /* LCDD19 */ - at91_set_A_periph(AT91_PIN_PC24, 0); /* LCDD20 */ - at91_set_A_periph(AT91_PIN_PC25, 0); /* LCDD21 */ - at91_set_A_periph(AT91_PIN_PC26, 0); /* LCDD22 */ - at91_set_A_periph(AT91_PIN_PC27, 0); /* LCDD23 */ - - lcdc_data = *data; - platform_device_register(&at91_lcdc_device); -} -#else -void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {} -#endif - - -/* -------------------------------------------------------------------- - * SSC -- Synchronous Serial Controller - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE) -static u64 ssc0_dmamask = DMA_BIT_MASK(32); - -static struct resource ssc0_resources[] = { - [0] = { - .start = AT91CAP9_BASE_SSC0, - .end = AT91CAP9_BASE_SSC0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_ID_SSC0, - .end = AT91CAP9_ID_SSC0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91cap9_ssc0_device = { - .name = "ssc", - .id = 0, - .dev = { - .dma_mask = &ssc0_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = ssc0_resources, - .num_resources = ARRAY_SIZE(ssc0_resources), -}; - -static inline void configure_ssc0_pins(unsigned pins) -{ - if (pins & ATMEL_SSC_TF) - at91_set_A_periph(AT91_PIN_PB0, 1); - if (pins & ATMEL_SSC_TK) - at91_set_A_periph(AT91_PIN_PB1, 1); - if (pins & ATMEL_SSC_TD) - at91_set_A_periph(AT91_PIN_PB2, 1); - if (pins & ATMEL_SSC_RD) - at91_set_A_periph(AT91_PIN_PB3, 1); - if (pins & ATMEL_SSC_RK) - at91_set_A_periph(AT91_PIN_PB4, 1); - if (pins & ATMEL_SSC_RF) - at91_set_A_periph(AT91_PIN_PB5, 1); -} - -static u64 ssc1_dmamask = DMA_BIT_MASK(32); - -static struct resource ssc1_resources[] = { - [0] = { - .start = AT91CAP9_BASE_SSC1, - .end = AT91CAP9_BASE_SSC1 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_ID_SSC1, - .end = AT91CAP9_ID_SSC1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91cap9_ssc1_device = { - .name = "ssc", - .id = 1, - .dev = { - .dma_mask = &ssc1_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = ssc1_resources, - .num_resources = ARRAY_SIZE(ssc1_resources), -}; - -static inline void configure_ssc1_pins(unsigned pins) -{ - if (pins & ATMEL_SSC_TF) - at91_set_A_periph(AT91_PIN_PB6, 1); - if (pins & ATMEL_SSC_TK) - at91_set_A_periph(AT91_PIN_PB7, 1); - if (pins & ATMEL_SSC_TD) - at91_set_A_periph(AT91_PIN_PB8, 1); - if (pins & ATMEL_SSC_RD) - at91_set_A_periph(AT91_PIN_PB9, 1); - if (pins & ATMEL_SSC_RK) - at91_set_A_periph(AT91_PIN_PB10, 1); - if (pins & ATMEL_SSC_RF) - at91_set_A_periph(AT91_PIN_PB11, 1); -} - -/* - * SSC controllers are accessed through library code, instead of any - * kind of all-singing/all-dancing driver. For example one could be - * used by a particular I2S audio codec's driver, while another one - * on the same system might be used by a custom data capture driver. - */ -void __init at91_add_device_ssc(unsigned id, unsigned pins) -{ - struct platform_device *pdev; - - /* - * NOTE: caller is responsible for passing information matching - * "pins" to whatever will be using each particular controller. - */ - switch (id) { - case AT91CAP9_ID_SSC0: - pdev = &at91cap9_ssc0_device; - configure_ssc0_pins(pins); - break; - case AT91CAP9_ID_SSC1: - pdev = &at91cap9_ssc1_device; - configure_ssc1_pins(pins); - break; - default: - return; - } - - platform_device_register(pdev); -} - -#else -void __init at91_add_device_ssc(unsigned id, unsigned pins) {} -#endif - - -/* -------------------------------------------------------------------- - * UART - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_SERIAL_ATMEL) -static struct resource dbgu_resources[] = { - [0] = { - .start = AT91CAP9_BASE_DBGU, - .end = AT91CAP9_BASE_DBGU + SZ_512 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91_ID_SYS, - .end = AT91_ID_SYS, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data dbgu_data = { - .use_dma_tx = 0, - .use_dma_rx = 0, /* DBGU not capable of receive DMA */ -}; - -static u64 dbgu_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91cap9_dbgu_device = { - .name = "atmel_usart", - .id = 0, - .dev = { - .dma_mask = &dbgu_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &dbgu_data, - }, - .resource = dbgu_resources, - .num_resources = ARRAY_SIZE(dbgu_resources), -}; - -static inline void configure_dbgu_pins(void) -{ - at91_set_A_periph(AT91_PIN_PC30, 0); /* DRXD */ - at91_set_A_periph(AT91_PIN_PC31, 1); /* DTXD */ -} - -static struct resource uart0_resources[] = { - [0] = { - .start = AT91CAP9_BASE_US0, - .end = AT91CAP9_BASE_US0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_ID_US0, - .end = AT91CAP9_ID_US0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart0_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static u64 uart0_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91cap9_uart0_device = { - .name = "atmel_usart", - .id = 1, - .dev = { - .dma_mask = &uart0_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &uart0_data, - }, - .resource = uart0_resources, - .num_resources = ARRAY_SIZE(uart0_resources), -}; - -static inline void configure_usart0_pins(unsigned pins) -{ - at91_set_A_periph(AT91_PIN_PA22, 1); /* TXD0 */ - at91_set_A_periph(AT91_PIN_PA23, 0); /* RXD0 */ - - if (pins & ATMEL_UART_RTS) - at91_set_A_periph(AT91_PIN_PA24, 0); /* RTS0 */ - if (pins & ATMEL_UART_CTS) - at91_set_A_periph(AT91_PIN_PA25, 0); /* CTS0 */ -} - -static struct resource uart1_resources[] = { - [0] = { - .start = AT91CAP9_BASE_US1, - .end = AT91CAP9_BASE_US1 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_ID_US1, - .end = AT91CAP9_ID_US1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart1_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static u64 uart1_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91cap9_uart1_device = { - .name = "atmel_usart", - .id = 2, - .dev = { - .dma_mask = &uart1_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &uart1_data, - }, - .resource = uart1_resources, - .num_resources = ARRAY_SIZE(uart1_resources), -}; - -static inline void configure_usart1_pins(unsigned pins) -{ - at91_set_A_periph(AT91_PIN_PD0, 1); /* TXD1 */ - at91_set_A_periph(AT91_PIN_PD1, 0); /* RXD1 */ - - if (pins & ATMEL_UART_RTS) - at91_set_B_periph(AT91_PIN_PD7, 0); /* RTS1 */ - if (pins & ATMEL_UART_CTS) - at91_set_B_periph(AT91_PIN_PD8, 0); /* CTS1 */ -} - -static struct resource uart2_resources[] = { - [0] = { - .start = AT91CAP9_BASE_US2, - .end = AT91CAP9_BASE_US2 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_ID_US2, - .end = AT91CAP9_ID_US2, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart2_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static u64 uart2_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91cap9_uart2_device = { - .name = "atmel_usart", - .id = 3, - .dev = { - .dma_mask = &uart2_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &uart2_data, - }, - .resource = uart2_resources, - .num_resources = ARRAY_SIZE(uart2_resources), -}; - -static inline void configure_usart2_pins(unsigned pins) -{ - at91_set_A_periph(AT91_PIN_PD2, 1); /* TXD2 */ - at91_set_A_periph(AT91_PIN_PD3, 0); /* RXD2 */ - - if (pins & ATMEL_UART_RTS) - at91_set_B_periph(AT91_PIN_PD5, 0); /* RTS2 */ - if (pins & ATMEL_UART_CTS) - at91_set_B_periph(AT91_PIN_PD6, 0); /* CTS2 */ -} - -static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ -struct platform_device *atmel_default_console_device; /* the serial console device */ - -void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) -{ - struct platform_device *pdev; - struct atmel_uart_data *pdata; - - switch (id) { - case 0: /* DBGU */ - pdev = &at91cap9_dbgu_device; - configure_dbgu_pins(); - break; - case AT91CAP9_ID_US0: - pdev = &at91cap9_uart0_device; - configure_usart0_pins(pins); - break; - case AT91CAP9_ID_US1: - pdev = &at91cap9_uart1_device; - configure_usart1_pins(pins); - break; - case AT91CAP9_ID_US2: - pdev = &at91cap9_uart2_device; - configure_usart2_pins(pins); - break; - default: - return; - } - pdata = pdev->dev.platform_data; - pdata->num = portnr; /* update to mapped ID */ - - if (portnr < ATMEL_MAX_UART) - at91_uarts[portnr] = pdev; -} - -void __init at91_set_serial_console(unsigned portnr) -{ - if (portnr < ATMEL_MAX_UART) { - atmel_default_console_device = at91_uarts[portnr]; - at91cap9_set_console_clock(at91_uarts[portnr]->id); - } -} - -void __init at91_add_device_serial(void) -{ - int i; - - for (i = 0; i < ATMEL_MAX_UART; i++) { - if (at91_uarts[i]) - platform_device_register(at91_uarts[i]); - } - - if (!atmel_default_console_device) - printk(KERN_INFO "AT91: No default serial console defined.\n"); -} -#else -void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} -void __init at91_set_serial_console(unsigned portnr) {} -void __init at91_add_device_serial(void) {} -#endif - - -/* -------------------------------------------------------------------- */ -/* - * These devices are always present and don't need any board-specific - * setup. - */ -static int __init at91_add_standard_devices(void) -{ - at91_add_device_rtt(); - at91_add_device_watchdog(); - at91_add_device_tc(); - return 0; -} - -arch_initcall(at91_add_standard_devices); diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c index 99c3174..0df1045 100644 --- a/arch/arm/mach-at91/at91rm9200.c +++ b/arch/arm/mach-at91/at91rm9200.c @@ -289,13 +289,22 @@ static struct at91_gpio_bank at91rm9200_gpio[] __initdata = { } }; +static void at91rm9200_idle(void) +{ + /* + * Disable the processor clock. The processor will be automatically + * re-enabled by an interrupt or by a reset. + */ + at91_pmc_write(AT91_PMC_SCDR, AT91_PMC_PCK); +} + static void at91rm9200_restart(char mode, const char *cmd) { /* * Perform a hardware reset with the use of the Watchdog timer. */ - at91_sys_write(AT91_ST_WDMR, AT91_ST_RSTEN | AT91_ST_EXTEN | 1); - at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); + at91_st_write(AT91_ST_WDMR, AT91_ST_RSTEN | AT91_ST_EXTEN | 1); + at91_st_write(AT91_ST_CR, AT91_ST_WDRST); } /* -------------------------------------------------------------------- @@ -310,10 +319,13 @@ static void __init at91rm9200_map_io(void) static void __init at91rm9200_ioremap_registers(void) { + at91rm9200_ioremap_st(AT91RM9200_BASE_ST); + at91_ioremap_ramc(0, AT91RM9200_BASE_MC, 256); } static void __init at91rm9200_initialize(void) { + arm_pm_idle = at91rm9200_idle; arm_pm_restart = at91rm9200_restart; at91_extern_irq = (1 << AT91RM9200_ID_IRQ0) | (1 << AT91RM9200_ID_IRQ1) | (1 << AT91RM9200_ID_IRQ2) | (1 << AT91RM9200_ID_IRQ3) diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c index 97676bd..99ce5c9 100644 --- a/arch/arm/mach-at91/at91rm9200_devices.c +++ b/arch/arm/mach-at91/at91rm9200_devices.c @@ -21,6 +21,7 @@ #include <mach/board.h> #include <mach/at91rm9200.h> #include <mach/at91rm9200_mc.h> +#include <mach/at91_ramc.h> #include "generic.h" @@ -241,15 +242,15 @@ void __init at91_add_device_cf(struct at91_cf_data *data) data->chipselect = 4; /* can only use EBI ChipSelect 4 */ /* CF takes over CS4, CS5, CS6 */ - csa = at91_sys_read(AT91_EBI_CSA); - at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS4A_SMC_COMPACTFLASH); + csa = at91_ramc_read(0, AT91_EBI_CSA); + at91_ramc_write(0, AT91_EBI_CSA, csa | AT91_EBI_CS4A_SMC_COMPACTFLASH); /* * Static memory controller timing adjustments. * REVISIT: these timings are in terms of MCK cycles, so * when MCK changes (cpufreq etc) so must these values... */ - at91_sys_write(AT91_SMC_CSR(4), + at91_ramc_write(0, AT91_SMC_CSR(4), AT91_SMC_ACSS_STD | AT91_SMC_DBW_16 | AT91_SMC_BAT @@ -407,11 +408,11 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) return; /* enable the address range of CS3 */ - csa = at91_sys_read(AT91_EBI_CSA); - at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS3A_SMC_SMARTMEDIA); + csa = at91_ramc_read(0, AT91_EBI_CSA); + at91_ramc_write(0, AT91_EBI_CSA, csa | AT91_EBI_CS3A_SMC_SMARTMEDIA); /* set the bus interface characteristics */ - at91_sys_write(AT91_SMC_CSR(3), AT91_SMC_ACSS_STD | AT91_SMC_DBW_8 | AT91_SMC_WSEN + at91_ramc_write(0, AT91_SMC_CSR(3), AT91_SMC_ACSS_STD | AT91_SMC_DBW_8 | AT91_SMC_WSEN | AT91_SMC_NWS_(5) | AT91_SMC_TDF_(1) | AT91_SMC_RWSETUP_(0) /* tDS Data Set up Time 30 - ns */ @@ -1114,7 +1115,6 @@ static inline void configure_usart3_pins(unsigned pins) } static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ -struct platform_device *atmel_default_console_device; /* the serial console device */ void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) { diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c index a028cdf..dd7f782 100644 --- a/arch/arm/mach-at91/at91rm9200_time.c +++ b/arch/arm/mach-at91/at91rm9200_time.c @@ -43,9 +43,9 @@ static inline unsigned long read_CRTR(void) { unsigned long x1, x2; - x1 = at91_sys_read(AT91_ST_CRTR); + x1 = at91_st_read(AT91_ST_CRTR); do { - x2 = at91_sys_read(AT91_ST_CRTR); + x2 = at91_st_read(AT91_ST_CRTR); if (x1 == x2) break; x1 = x2; @@ -58,7 +58,7 @@ static inline unsigned long read_CRTR(void) */ static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id) { - u32 sr = at91_sys_read(AT91_ST_SR) & irqmask; + u32 sr = at91_st_read(AT91_ST_SR) & irqmask; /* * irqs should be disabled here, but as the irq is shared they are only @@ -110,22 +110,22 @@ static void clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev) { /* Disable and flush pending timer interrupts */ - at91_sys_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_ALMS); - (void) at91_sys_read(AT91_ST_SR); + at91_st_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_ALMS); + at91_st_read(AT91_ST_SR); last_crtr = read_CRTR(); switch (mode) { case CLOCK_EVT_MODE_PERIODIC: /* PIT for periodic irqs; fixed rate of 1/HZ */ irqmask = AT91_ST_PITS; - at91_sys_write(AT91_ST_PIMR, RM9200_TIMER_LATCH); + at91_st_write(AT91_ST_PIMR, RM9200_TIMER_LATCH); break; case CLOCK_EVT_MODE_ONESHOT: /* ALM for oneshot irqs, set by next_event() * before 32 seconds have passed */ irqmask = AT91_ST_ALMS; - at91_sys_write(AT91_ST_RTAR, last_crtr); + at91_st_write(AT91_ST_RTAR, last_crtr); break; case CLOCK_EVT_MODE_SHUTDOWN: case CLOCK_EVT_MODE_UNUSED: @@ -133,7 +133,7 @@ clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev) irqmask = 0; break; } - at91_sys_write(AT91_ST_IER, irqmask); + at91_st_write(AT91_ST_IER, irqmask); } static int @@ -156,12 +156,12 @@ clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev) alm = read_CRTR(); /* Cancel any pending alarm; flush any pending IRQ */ - at91_sys_write(AT91_ST_RTAR, alm); - (void) at91_sys_read(AT91_ST_SR); + at91_st_write(AT91_ST_RTAR, alm); + at91_st_read(AT91_ST_SR); /* Schedule alarm by writing RTAR. */ alm += delta; - at91_sys_write(AT91_ST_RTAR, alm); + at91_st_write(AT91_ST_RTAR, alm); return status; } @@ -175,15 +175,24 @@ static struct clock_event_device clkevt = { .set_mode = clkevt32k_mode, }; +void __iomem *at91_st_base; + +void __init at91rm9200_ioremap_st(u32 addr) +{ + at91_st_base = ioremap(addr, 256); + if (!at91_st_base) + panic("Impossible to ioremap ST\n"); +} + /* * ST (system timer) module supports both clockevents and clocksource. */ void __init at91rm9200_timer_init(void) { /* Disable all timer interrupts, and clear any pending ones */ - at91_sys_write(AT91_ST_IDR, + at91_st_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS); - (void) at91_sys_read(AT91_ST_SR); + at91_st_read(AT91_ST_SR); /* Make IRQs happen for the system timer */ setup_irq(AT91_ID_SYS, &at91rm9200_timer_irq); @@ -192,7 +201,7 @@ void __init at91rm9200_timer_init(void) * directly for the clocksource and all clockevents, after adjusting * its prescaler from the 1 Hz default. */ - at91_sys_write(AT91_ST_RTMR, 1); + at91_st_write(AT91_ST_RTMR, 1); /* Setup timer clockevent, with minimum of two ticks (important!!) */ clkevt.mult = div_sc(AT91_SLOW_CLOCK, NSEC_PER_SEC, clkevt.shift); diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index d4036ba..14b5a9c 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -12,6 +12,7 @@ #include <linux/module.h> +#include <asm/proc-fns.h> #include <asm/irq.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -208,6 +209,13 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("usart", "fffd0000.serial", &usart3_clk), CLKDEV_CON_DEV_ID("usart", "fffd4000.serial", &usart4_clk), CLKDEV_CON_DEV_ID("usart", "fffd8000.serial", &usart5_clk), + /* more tc lookup table for DT entries */ + CLKDEV_CON_DEV_ID("t0_clk", "fffa0000.timer", &tc0_clk), + CLKDEV_CON_DEV_ID("t1_clk", "fffa0000.timer", &tc1_clk), + CLKDEV_CON_DEV_ID("t2_clk", "fffa0000.timer", &tc2_clk), + CLKDEV_CON_DEV_ID("t0_clk", "fffdc000.timer", &tc3_clk), + CLKDEV_CON_DEV_ID("t1_clk", "fffdc000.timer", &tc4_clk), + CLKDEV_CON_DEV_ID("t2_clk", "fffdc000.timer", &tc5_clk), /* fake hclk clock */ CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), CLKDEV_CON_ID("pioA", &pioA_clk), @@ -309,27 +317,27 @@ static void __init at91sam9xe_map_io(void) static void __init at91sam9260_map_io(void) { - if (cpu_is_at91sam9xe()) { + if (cpu_is_at91sam9xe()) at91sam9xe_map_io(); - } else if (cpu_is_at91sam9g20()) { - at91_init_sram(0, AT91SAM9G20_SRAM0_BASE, AT91SAM9G20_SRAM0_SIZE); - at91_init_sram(1, AT91SAM9G20_SRAM1_BASE, AT91SAM9G20_SRAM1_SIZE); - } else { - at91_init_sram(0, AT91SAM9260_SRAM0_BASE, AT91SAM9260_SRAM0_SIZE); - at91_init_sram(1, AT91SAM9260_SRAM1_BASE, AT91SAM9260_SRAM1_SIZE); - } + else if (cpu_is_at91sam9g20()) + at91_init_sram(0, AT91SAM9G20_SRAM_BASE, AT91SAM9G20_SRAM_SIZE); + else + at91_init_sram(0, AT91SAM9260_SRAM_BASE, AT91SAM9260_SRAM_SIZE); } static void __init at91sam9260_ioremap_registers(void) { at91_ioremap_shdwc(AT91SAM9260_BASE_SHDWC); at91_ioremap_rstc(AT91SAM9260_BASE_RSTC); + at91_ioremap_ramc(0, AT91SAM9260_BASE_SDRAMC, 512); at91sam926x_ioremap_pit(AT91SAM9260_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9260_BASE_SMC); + at91_ioremap_matrix(AT91SAM9260_BASE_MATRIX); } static void __init at91sam9260_initialize(void) { + arm_pm_idle = at91sam9_idle; arm_pm_restart = at91sam9_alt_restart; at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1) | (1 << AT91SAM9260_ID_IRQ2); diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index 5a24f0b..7e5651e 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -21,6 +21,7 @@ #include <mach/cpu.h> #include <mach/at91sam9260.h> #include <mach/at91sam9260_matrix.h> +#include <mach/at91_matrix.h> #include <mach/at91sam9_smc.h> #include "generic.h" @@ -422,8 +423,8 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) if (!data) return; - csa = at91_sys_read(AT91_MATRIX_EBICSA); - at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); + csa = at91_matrix_read(AT91_MATRIX_EBICSA); + at91_matrix_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); /* enable pin */ if (gpio_is_valid(data->enable_pin)) @@ -641,7 +642,7 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) static struct resource tcb0_resources[] = { [0] = { .start = AT91SAM9260_BASE_TCB0, - .end = AT91SAM9260_BASE_TCB0 + SZ_16K - 1, + .end = AT91SAM9260_BASE_TCB0 + SZ_256 - 1, .flags = IORESOURCE_MEM, }, [1] = { @@ -671,7 +672,7 @@ static struct platform_device at91sam9260_tcb0_device = { static struct resource tcb1_resources[] = { [0] = { .start = AT91SAM9260_BASE_TCB1, - .end = AT91SAM9260_BASE_TCB1 + SZ_16K - 1, + .end = AT91SAM9260_BASE_TCB1 + SZ_256 - 1, .flags = IORESOURCE_MEM, }, [1] = { @@ -698,8 +699,25 @@ static struct platform_device at91sam9260_tcb1_device = { .num_resources = ARRAY_SIZE(tcb1_resources), }; +#if defined(CONFIG_OF) +static struct of_device_id tcb_ids[] = { + { .compatible = "atmel,at91rm9200-tcb" }, + { /*sentinel*/ } +}; +#endif + static void __init at91_add_device_tc(void) { +#if defined(CONFIG_OF) + struct device_node *np; + + np = of_find_matching_node(NULL, tcb_ids); + if (np) { + of_node_put(np); + return; + } +#endif + platform_device_register(&at91sam9260_tcb0_device); platform_device_register(&at91sam9260_tcb1_device); } @@ -717,18 +735,42 @@ static struct resource rtt_resources[] = { .start = AT91SAM9260_BASE_RTT, .end = AT91SAM9260_BASE_RTT + SZ_16 - 1, .flags = IORESOURCE_MEM, - } + }, { + .flags = IORESOURCE_MEM, + }, }; static struct platform_device at91sam9260_rtt_device = { .name = "at91_rtt", .id = 0, .resource = rtt_resources, - .num_resources = ARRAY_SIZE(rtt_resources), }; + +#if IS_ENABLED(CONFIG_RTC_DRV_AT91SAM9) +static void __init at91_add_device_rtt_rtc(void) +{ + at91sam9260_rtt_device.name = "rtc-at91sam9"; + /* + * The second resource is needed: + * GPBR will serve as the storage for RTC time offset + */ + at91sam9260_rtt_device.num_resources = 2; + rtt_resources[1].start = AT91SAM9260_BASE_GPBR + + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR; + rtt_resources[1].end = rtt_resources[1].start + 3; +} +#else +static void __init at91_add_device_rtt_rtc(void) +{ + /* Only one resource is needed: RTT not used as RTC */ + at91sam9260_rtt_device.num_resources = 1; +} +#endif + static void __init at91_add_device_rtt(void) { + at91_add_device_rtt_rtc(); platform_device_register(&at91sam9260_rtt_device); } @@ -1139,7 +1181,6 @@ static inline void configure_usart5_pins(void) } static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ -struct platform_device *atmel_default_console_device; /* the serial console device */ void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) { @@ -1264,7 +1305,7 @@ void __init at91_add_device_cf(struct at91_cf_data *data) if (!data) return; - csa = at91_sys_read(AT91_MATRIX_EBICSA); + csa = at91_matrix_read(AT91_MATRIX_EBICSA); switch (data->chipselect) { case 4: @@ -1287,7 +1328,7 @@ void __init at91_add_device_cf(struct at91_cf_data *data) return; } - at91_sys_write(AT91_MATRIX_EBICSA, csa); + at91_matrix_write(AT91_MATRIX_EBICSA, csa); if (gpio_is_valid(data->rst_pin)) { at91_set_multi_drive(data->rst_pin, 0); diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index 023c2ff..684c5df 100644 --- a/arch/arm/mach-at91/at91sam9261.c +++ b/arch/arm/mach-at91/at91sam9261.c @@ -12,6 +12,7 @@ #include <linux/module.h> +#include <asm/proc-fns.h> #include <asm/irq.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -282,12 +283,15 @@ static void __init at91sam9261_ioremap_registers(void) { at91_ioremap_shdwc(AT91SAM9261_BASE_SHDWC); at91_ioremap_rstc(AT91SAM9261_BASE_RSTC); + at91_ioremap_ramc(0, AT91SAM9261_BASE_SDRAMC, 512); at91sam926x_ioremap_pit(AT91SAM9261_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9261_BASE_SMC); + at91_ioremap_matrix(AT91SAM9261_BASE_MATRIX); } static void __init at91sam9261_initialize(void) { + arm_pm_idle = at91sam9_idle; arm_pm_restart = at91sam9_alt_restart; at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1) | (1 << AT91SAM9261_ID_IRQ2); diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index 1e28bed..096da87 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c @@ -24,6 +24,7 @@ #include <mach/board.h> #include <mach/at91sam9261.h> #include <mach/at91sam9261_matrix.h> +#include <mach/at91_matrix.h> #include <mach/at91sam9_smc.h> #include "generic.h" @@ -236,8 +237,8 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) if (!data) return; - csa = at91_sys_read(AT91_MATRIX_EBICSA); - at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); + csa = at91_matrix_read(AT91_MATRIX_EBICSA); + at91_matrix_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); /* enable pin */ if (gpio_is_valid(data->enable_pin)) @@ -603,6 +604,8 @@ static struct resource rtt_resources[] = { .start = AT91SAM9261_BASE_RTT, .end = AT91SAM9261_BASE_RTT + SZ_16 - 1, .flags = IORESOURCE_MEM, + }, { + .flags = IORESOURCE_MEM, } }; @@ -610,11 +613,32 @@ static struct platform_device at91sam9261_rtt_device = { .name = "at91_rtt", .id = 0, .resource = rtt_resources, - .num_resources = ARRAY_SIZE(rtt_resources), }; +#if IS_ENABLED(CONFIG_RTC_DRV_AT91SAM9) +static void __init at91_add_device_rtt_rtc(void) +{ + at91sam9261_rtt_device.name = "rtc-at91sam9"; + /* + * The second resource is needed: + * GPBR will serve as the storage for RTC time offset + */ + at91sam9261_rtt_device.num_resources = 2; + rtt_resources[1].start = AT91SAM9261_BASE_GPBR + + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR; + rtt_resources[1].end = rtt_resources[1].start + 3; +} +#else +static void __init at91_add_device_rtt_rtc(void) +{ + /* Only one resource is needed: RTT not used as RTC */ + at91sam9261_rtt_device.num_resources = 1; +} +#endif + static void __init at91_add_device_rtt(void) { + at91_add_device_rtt_rtc(); platform_device_register(&at91sam9261_rtt_device); } @@ -991,7 +1015,6 @@ static inline void configure_usart2_pins(unsigned pins) } static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ -struct platform_device *atmel_default_console_device; /* the serial console device */ void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) { diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index 75e876c..0b4fa5a 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c @@ -12,6 +12,7 @@ #include <linux/module.h> +#include <asm/proc-fns.h> #include <asm/irq.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -302,13 +303,17 @@ static void __init at91sam9263_ioremap_registers(void) { at91_ioremap_shdwc(AT91SAM9263_BASE_SHDWC); at91_ioremap_rstc(AT91SAM9263_BASE_RSTC); + at91_ioremap_ramc(0, AT91SAM9263_BASE_SDRAMC0, 512); + at91_ioremap_ramc(1, AT91SAM9263_BASE_SDRAMC1, 512); at91sam926x_ioremap_pit(AT91SAM9263_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9263_BASE_SMC0); at91sam9_ioremap_smc(1, AT91SAM9263_BASE_SMC1); + at91_ioremap_matrix(AT91SAM9263_BASE_MATRIX); } static void __init at91sam9263_initialize(void) { + arm_pm_idle = at91sam9_idle; arm_pm_restart = at91sam9_alt_restart; at91_extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1); diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index 366a776..53688c46 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -23,6 +23,7 @@ #include <mach/board.h> #include <mach/at91sam9263.h> #include <mach/at91sam9263_matrix.h> +#include <mach/at91_matrix.h> #include <mach/at91sam9_smc.h> #include "generic.h" @@ -409,7 +410,7 @@ void __init at91_add_device_cf(struct at91_cf_data *data) * we assume SMC timings are configured by board code, * except True IDE where timings are controlled by driver */ - ebi0_csa = at91_sys_read(AT91_MATRIX_EBI0CSA); + ebi0_csa = at91_matrix_read(AT91_MATRIX_EBI0CSA); switch (data->chipselect) { case 4: at91_set_A_periph(AT91_PIN_PD6, 0); /* EBI0_NCS4/CFCS0 */ @@ -428,7 +429,7 @@ void __init at91_add_device_cf(struct at91_cf_data *data) data->chipselect); return; } - at91_sys_write(AT91_MATRIX_EBI0CSA, ebi0_csa); + at91_matrix_write(AT91_MATRIX_EBI0CSA, ebi0_csa); if (gpio_is_valid(data->det_pin)) { at91_set_gpio_input(data->det_pin, 1); @@ -496,8 +497,8 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) if (!data) return; - csa = at91_sys_read(AT91_MATRIX_EBI0CSA); - at91_sys_write(AT91_MATRIX_EBI0CSA, csa | AT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA); + csa = at91_matrix_read(AT91_MATRIX_EBI0CSA); + at91_matrix_write(AT91_MATRIX_EBI0CSA, csa | AT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA); /* enable pin */ if (gpio_is_valid(data->enable_pin)) @@ -891,7 +892,8 @@ static struct platform_device at91sam9263_isi_device = { .num_resources = ARRAY_SIZE(isi_resources), }; -void __init at91_add_device_isi(void) +void __init at91_add_device_isi(struct isi_platform_data *data, + bool use_pck_as_mck) { at91_set_A_periph(AT91_PIN_PE0, 0); /* ISI_D0 */ at91_set_A_periph(AT91_PIN_PE1, 0); /* ISI_D1 */ @@ -904,14 +906,20 @@ void __init at91_add_device_isi(void) at91_set_A_periph(AT91_PIN_PE8, 0); /* ISI_PCK */ at91_set_A_periph(AT91_PIN_PE9, 0); /* ISI_HSYNC */ at91_set_A_periph(AT91_PIN_PE10, 0); /* ISI_VSYNC */ - at91_set_B_periph(AT91_PIN_PE11, 0); /* ISI_MCK (PCK3) */ at91_set_B_periph(AT91_PIN_PE12, 0); /* ISI_PD8 */ at91_set_B_periph(AT91_PIN_PE13, 0); /* ISI_PD9 */ at91_set_B_periph(AT91_PIN_PE14, 0); /* ISI_PD10 */ at91_set_B_periph(AT91_PIN_PE15, 0); /* ISI_PD11 */ + + if (use_pck_as_mck) { + at91_set_B_periph(AT91_PIN_PE11, 0); /* ISI_MCK (PCK3) */ + + /* TODO: register the PCK for ISI_MCK and set its parent */ + } } #else -void __init at91_add_device_isi(void) {} +void __init at91_add_device_isi(struct isi_platform_data *data, + bool use_pck_as_mck) {} #endif @@ -959,6 +967,8 @@ static struct resource rtt0_resources[] = { .start = AT91SAM9263_BASE_RTT0, .end = AT91SAM9263_BASE_RTT0 + SZ_16 - 1, .flags = IORESOURCE_MEM, + }, { + .flags = IORESOURCE_MEM, } }; @@ -966,7 +976,6 @@ static struct platform_device at91sam9263_rtt0_device = { .name = "at91_rtt", .id = 0, .resource = rtt0_resources, - .num_resources = ARRAY_SIZE(rtt0_resources), }; static struct resource rtt1_resources[] = { @@ -974,6 +983,8 @@ static struct resource rtt1_resources[] = { .start = AT91SAM9263_BASE_RTT1, .end = AT91SAM9263_BASE_RTT1 + SZ_16 - 1, .flags = IORESOURCE_MEM, + }, { + .flags = IORESOURCE_MEM, } }; @@ -981,11 +992,53 @@ static struct platform_device at91sam9263_rtt1_device = { .name = "at91_rtt", .id = 1, .resource = rtt1_resources, - .num_resources = ARRAY_SIZE(rtt1_resources), }; +#if IS_ENABLED(CONFIG_RTC_DRV_AT91SAM9) +static void __init at91_add_device_rtt_rtc(void) +{ + struct platform_device *pdev; + struct resource *r; + + switch (CONFIG_RTC_DRV_AT91SAM9_RTT) { + case 0: + /* + * The second resource is needed only for the chosen RTT: + * GPBR will serve as the storage for RTC time offset + */ + at91sam9263_rtt0_device.num_resources = 2; + at91sam9263_rtt1_device.num_resources = 1; + pdev = &at91sam9263_rtt0_device; + r = rtt0_resources; + break; + case 1: + at91sam9263_rtt0_device.num_resources = 1; + at91sam9263_rtt1_device.num_resources = 2; + pdev = &at91sam9263_rtt1_device; + r = rtt1_resources; + break; + default: + pr_err("at91sam9263: only supports 2 RTT (%d)\n", + CONFIG_RTC_DRV_AT91SAM9_RTT); + return; + } + + pdev->name = "rtc-at91sam9"; + r[1].start = AT91SAM9263_BASE_GPBR + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR; + r[1].end = r[1].start + 3; +} +#else +static void __init at91_add_device_rtt_rtc(void) +{ + /* Only one resource is needed: RTT not used as RTC */ + at91sam9263_rtt0_device.num_resources = 1; + at91sam9263_rtt1_device.num_resources = 1; +} +#endif + static void __init at91_add_device_rtt(void) { + at91_add_device_rtt_rtc(); platform_device_register(&at91sam9263_rtt0_device); platform_device_register(&at91sam9263_rtt1_device); } @@ -1371,7 +1424,6 @@ static inline void configure_usart2_pins(unsigned pins) } static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ -struct platform_device *atmel_default_console_device; /* the serial console device */ void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) { diff --git a/arch/arm/mach-at91/at91sam926x_time.c b/arch/arm/mach-at91/at91sam926x_time.c index d89ead7..a94758b 100644 --- a/arch/arm/mach-at91/at91sam926x_time.c +++ b/arch/arm/mach-at91/at91sam926x_time.c @@ -14,6 +14,9 @@ #include <linux/kernel.h> #include <linux/clk.h> #include <linux/clockchips.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> #include <asm/mach/time.h> @@ -133,7 +136,8 @@ static irqreturn_t at91sam926x_pit_interrupt(int irq, void *dev_id) static struct irqaction at91sam926x_pit_irq = { .name = "at91_tick", .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, - .handler = at91sam926x_pit_interrupt + .handler = at91sam926x_pit_interrupt, + .irq = AT91_ID_SYS, }; static void at91sam926x_pit_reset(void) @@ -149,6 +153,51 @@ static void at91sam926x_pit_reset(void) pit_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN); } +#ifdef CONFIG_OF +static struct of_device_id pit_timer_ids[] = { + { .compatible = "atmel,at91sam9260-pit" }, + { /* sentinel */ } +}; + +static int __init of_at91sam926x_pit_init(void) +{ + struct device_node *np; + int ret; + + np = of_find_matching_node(NULL, pit_timer_ids); + if (!np) + goto err; + + pit_base_addr = of_iomap(np, 0); + if (!pit_base_addr) + goto node_err; + + /* Get the interrupts property */ + ret = irq_of_parse_and_map(np, 0); + if (!ret) { + pr_crit("AT91: PIT: Unable to get IRQ from DT\n"); + goto ioremap_err; + } + at91sam926x_pit_irq.irq = ret; + + of_node_put(np); + + return 0; + +ioremap_err: + iounmap(pit_base_addr); +node_err: + of_node_put(np); +err: + return -EINVAL; +} +#else +static int __init of_at91sam926x_pit_init(void) +{ + return -EINVAL; +} +#endif + /* * Set up both clocksource and clockevent support. */ @@ -156,6 +205,10 @@ static void __init at91sam926x_pit_init(void) { unsigned long pit_rate; unsigned bits; + int ret; + + /* For device tree enabled device: initialize here */ + of_at91sam926x_pit_init(); /* * Use our actual MCK to figure out how many MCK/16 ticks per @@ -177,7 +230,9 @@ static void __init at91sam926x_pit_init(void) clocksource_register_hz(&pit_clk, pit_rate); /* Set up irq handler */ - setup_irq(AT91_ID_SYS, &at91sam926x_pit_irq); + ret = setup_irq(at91sam926x_pit_irq.irq, &at91sam926x_pit_irq); + if (ret) + pr_crit("AT91: PIT: Unable to setup IRQ\n"); /* Set up and register clockevents */ pit_clkevt.mult = div_sc(pit_rate, NSEC_PER_SEC, pit_clkevt.shift); @@ -193,6 +248,15 @@ static void at91sam926x_pit_suspend(void) void __init at91sam926x_ioremap_pit(u32 addr) { +#if defined(CONFIG_OF) + struct device_node *np = + of_find_matching_node(NULL, pit_timer_ids); + + if (np) { + of_node_put(np); + return; + } +#endif pit_base_addr = ioremap(addr, 16); if (!pit_base_addr) diff --git a/arch/arm/mach-at91/at91sam9_alt_reset.S b/arch/arm/mach-at91/at91sam9_alt_reset.S index 518e423..7af2e10 100644 --- a/arch/arm/mach-at91/at91sam9_alt_reset.S +++ b/arch/arm/mach-at91/at91sam9_alt_reset.S @@ -15,16 +15,17 @@ #include <linux/linkage.h> #include <mach/hardware.h> -#include <mach/at91sam9_sdramc.h> +#include <mach/at91_ramc.h> #include <mach/at91_rstc.h> .arm .globl at91sam9_alt_restart -at91sam9_alt_restart: ldr r0, .at91_va_base_sdramc @ preload constants - ldr r1, =at91_rstc_base - ldr r1, [r1] +at91sam9_alt_restart: ldr r0, =at91_ramc_base @ preload constants + ldr r0, [r0] + ldr r4, =at91_rstc_base + ldr r1, [r4] mov r2, #1 mov r3, #AT91_SDRAMC_LPCB_POWER_DOWN @@ -37,6 +38,3 @@ at91sam9_alt_restart: ldr r0, .at91_va_base_sdramc @ preload constants str r4, [r1, #AT91_RSTC_CR] @ reset processor b . - -.at91_va_base_sdramc: - .word AT91_VA_BASE_SYS + AT91_SDRAMC0 diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index 1cb6a96..0014573 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -229,6 +229,9 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("usart", "fff90000.serial", &usart1_clk), CLKDEV_CON_DEV_ID("usart", "fff94000.serial", &usart2_clk), CLKDEV_CON_DEV_ID("usart", "fff98000.serial", &usart3_clk), + /* more tc lookup table for DT entries */ + CLKDEV_CON_DEV_ID("t0_clk", "fff7c000.timer", &tcb0_clk), + CLKDEV_CON_DEV_ID("t0_clk", "fffd4000.timer", &tcb0_clk), /* fake hclk clock */ CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &uhphs_clk), CLKDEV_CON_ID("pioA", &pioA_clk), @@ -331,12 +334,16 @@ static void __init at91sam9g45_ioremap_registers(void) { at91_ioremap_shdwc(AT91SAM9G45_BASE_SHDWC); at91_ioremap_rstc(AT91SAM9G45_BASE_RSTC); + at91_ioremap_ramc(0, AT91SAM9G45_BASE_DDRSDRC1, 512); + at91_ioremap_ramc(1, AT91SAM9G45_BASE_DDRSDRC0, 512); at91sam926x_ioremap_pit(AT91SAM9G45_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9G45_BASE_SMC); + at91_ioremap_matrix(AT91SAM9G45_BASE_MATRIX); } static void __init at91sam9g45_initialize(void) { + arm_pm_idle = at91sam9_idle; arm_pm_restart = at91sam9g45_restart; at91_extern_irq = (1 << AT91SAM9G45_ID_IRQ0); diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index b7582dd..4320b20 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -14,6 +14,7 @@ #include <linux/dma-mapping.h> #include <linux/gpio.h> +#include <linux/clk.h> #include <linux/platform_device.h> #include <linux/i2c-gpio.h> #include <linux/atmel-mci.h> @@ -24,11 +25,15 @@ #include <mach/board.h> #include <mach/at91sam9g45.h> #include <mach/at91sam9g45_matrix.h> +#include <mach/at91_matrix.h> #include <mach/at91sam9_smc.h> #include <mach/at_hdmac.h> #include <mach/atmel-mci.h> +#include <media/atmel-isi.h> + #include "generic.h" +#include "clock.h" /* -------------------------------------------------------------------- @@ -38,10 +43,6 @@ #if defined(CONFIG_AT_HDMAC) || defined(CONFIG_AT_HDMAC_MODULE) static u64 hdmac_dmamask = DMA_BIT_MASK(32); -static struct at_dma_platform_data atdma_pdata = { - .nr_channels = 8, -}; - static struct resource hdmac_resources[] = { [0] = { .start = AT91SAM9G45_BASE_DMA, @@ -56,12 +57,11 @@ static struct resource hdmac_resources[] = { }; static struct platform_device at_hdmac_device = { - .name = "at_hdmac", + .name = "at91sam9g45_dma", .id = -1, .dev = { .dma_mask = &hdmac_dmamask, .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &atdma_pdata, }, .resource = hdmac_resources, .num_resources = ARRAY_SIZE(hdmac_resources), @@ -69,9 +69,15 @@ static struct platform_device at_hdmac_device = { void __init at91_add_device_hdmac(void) { - dma_cap_set(DMA_MEMCPY, atdma_pdata.cap_mask); - dma_cap_set(DMA_SLAVE, atdma_pdata.cap_mask); - platform_device_register(&at_hdmac_device); +#if defined(CONFIG_OF) + struct device_node *of_node = + of_find_node_by_name(NULL, "dma-controller"); + + if (of_node) + of_node_put(of_node); + else +#endif + platform_device_register(&at_hdmac_device); } #else void __init at91_add_device_hdmac(void) {} @@ -552,8 +558,8 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) if (!data) return; - csa = at91_sys_read(AT91_MATRIX_EBICSA); - at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA); + csa = at91_matrix_read(AT91_MATRIX_EBICSA); + at91_matrix_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA); /* enable pin */ if (gpio_is_valid(data->enable_pin)) @@ -869,6 +875,96 @@ void __init at91_add_device_ac97(struct ac97c_platform_data *data) void __init at91_add_device_ac97(struct ac97c_platform_data *data) {} #endif +/* -------------------------------------------------------------------- + * Image Sensor Interface + * -------------------------------------------------------------------- */ +#if defined(CONFIG_VIDEO_ATMEL_ISI) || defined(CONFIG_VIDEO_ATMEL_ISI_MODULE) +static u64 isi_dmamask = DMA_BIT_MASK(32); +static struct isi_platform_data isi_data; + +struct resource isi_resources[] = { + [0] = { + .start = AT91SAM9G45_BASE_ISI, + .end = AT91SAM9G45_BASE_ISI + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9G45_ID_ISI, + .end = AT91SAM9G45_ID_ISI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9g45_isi_device = { + .name = "atmel_isi", + .id = 0, + .dev = { + .dma_mask = &isi_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &isi_data, + }, + .resource = isi_resources, + .num_resources = ARRAY_SIZE(isi_resources), +}; + +static struct clk_lookup isi_mck_lookups[] = { + CLKDEV_CON_DEV_ID("isi_mck", "atmel_isi.0", NULL), +}; + +void __init at91_add_device_isi(struct isi_platform_data *data, + bool use_pck_as_mck) +{ + struct clk *pck; + struct clk *parent; + + if (!data) + return; + isi_data = *data; + + at91_set_A_periph(AT91_PIN_PB20, 0); /* ISI_D0 */ + at91_set_A_periph(AT91_PIN_PB21, 0); /* ISI_D1 */ + at91_set_A_periph(AT91_PIN_PB22, 0); /* ISI_D2 */ + at91_set_A_periph(AT91_PIN_PB23, 0); /* ISI_D3 */ + at91_set_A_periph(AT91_PIN_PB24, 0); /* ISI_D4 */ + at91_set_A_periph(AT91_PIN_PB25, 0); /* ISI_D5 */ + at91_set_A_periph(AT91_PIN_PB26, 0); /* ISI_D6 */ + at91_set_A_periph(AT91_PIN_PB27, 0); /* ISI_D7 */ + at91_set_A_periph(AT91_PIN_PB28, 0); /* ISI_PCK */ + at91_set_A_periph(AT91_PIN_PB30, 0); /* ISI_HSYNC */ + at91_set_A_periph(AT91_PIN_PB29, 0); /* ISI_VSYNC */ + at91_set_B_periph(AT91_PIN_PB8, 0); /* ISI_PD8 */ + at91_set_B_periph(AT91_PIN_PB9, 0); /* ISI_PD9 */ + at91_set_B_periph(AT91_PIN_PB10, 0); /* ISI_PD10 */ + at91_set_B_periph(AT91_PIN_PB11, 0); /* ISI_PD11 */ + + platform_device_register(&at91sam9g45_isi_device); + + if (use_pck_as_mck) { + at91_set_B_periph(AT91_PIN_PB31, 0); /* ISI_MCK (PCK1) */ + + pck = clk_get(NULL, "pck1"); + parent = clk_get(NULL, "plla"); + + BUG_ON(IS_ERR(pck) || IS_ERR(parent)); + + if (clk_set_parent(pck, parent)) { + pr_err("Failed to set PCK's parent\n"); + } else { + /* Register PCK as ISI_MCK */ + isi_mck_lookups[0].clk = pck; + clkdev_add_table(isi_mck_lookups, + ARRAY_SIZE(isi_mck_lookups)); + } + + clk_put(pck); + clk_put(parent); + } +} +#else +void __init at91_add_device_isi(struct isi_platform_data *data, + bool use_pck_as_mck) {} +#endif + /* -------------------------------------------------------------------- * LCD Controller @@ -956,7 +1052,7 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {} static struct resource tcb0_resources[] = { [0] = { .start = AT91SAM9G45_BASE_TCB0, - .end = AT91SAM9G45_BASE_TCB0 + SZ_16K - 1, + .end = AT91SAM9G45_BASE_TCB0 + SZ_256 - 1, .flags = IORESOURCE_MEM, }, [1] = { @@ -977,7 +1073,7 @@ static struct platform_device at91sam9g45_tcb0_device = { static struct resource tcb1_resources[] = { [0] = { .start = AT91SAM9G45_BASE_TCB1, - .end = AT91SAM9G45_BASE_TCB1 + SZ_16K - 1, + .end = AT91SAM9G45_BASE_TCB1 + SZ_256 - 1, .flags = IORESOURCE_MEM, }, [1] = { @@ -994,8 +1090,25 @@ static struct platform_device at91sam9g45_tcb1_device = { .num_resources = ARRAY_SIZE(tcb1_resources), }; +#if defined(CONFIG_OF) +static struct of_device_id tcb_ids[] = { + { .compatible = "atmel,at91rm9200-tcb" }, + { /*sentinel*/ } +}; +#endif + static void __init at91_add_device_tc(void) { +#if defined(CONFIG_OF) + struct device_node *np; + + np = of_find_matching_node(NULL, tcb_ids); + if (np) { + of_node_put(np); + return; + } +#endif + platform_device_register(&at91sam9g45_tcb0_device); platform_device_register(&at91sam9g45_tcb1_device); } @@ -1098,6 +1211,8 @@ static struct resource rtt_resources[] = { .start = AT91SAM9G45_BASE_RTT, .end = AT91SAM9G45_BASE_RTT + SZ_16 - 1, .flags = IORESOURCE_MEM, + }, { + .flags = IORESOURCE_MEM, } }; @@ -1105,11 +1220,32 @@ static struct platform_device at91sam9g45_rtt_device = { .name = "at91_rtt", .id = 0, .resource = rtt_resources, - .num_resources = ARRAY_SIZE(rtt_resources), }; +#if IS_ENABLED(CONFIG_RTC_DRV_AT91SAM9) +static void __init at91_add_device_rtt_rtc(void) +{ + at91sam9g45_rtt_device.name = "rtc-at91sam9"; + /* + * The second resource is needed: + * GPBR will serve as the storage for RTC time offset + */ + at91sam9g45_rtt_device.num_resources = 2; + rtt_resources[1].start = AT91SAM9G45_BASE_GPBR + + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR; + rtt_resources[1].end = rtt_resources[1].start + 3; +} +#else +static void __init at91_add_device_rtt_rtc(void) +{ + /* Only one resource is needed: RTT not used as RTC */ + at91sam9g45_rtt_device.num_resources = 1; +} +#endif + static void __init at91_add_device_rtt(void) { + at91_add_device_rtt_rtc(); platform_device_register(&at91sam9g45_rtt_device); } @@ -1564,7 +1700,6 @@ static inline void configure_usart3_pins(unsigned pins) } static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ -struct platform_device *atmel_default_console_device; /* the serial console device */ void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) { diff --git a/arch/arm/mach-at91/at91sam9g45_reset.S b/arch/arm/mach-at91/at91sam9g45_reset.S index 0468be1..9d45718 100644 --- a/arch/arm/mach-at91/at91sam9g45_reset.S +++ b/arch/arm/mach-at91/at91sam9g45_reset.S @@ -12,7 +12,7 @@ #include <linux/linkage.h> #include <mach/hardware.h> -#include <mach/at91sam9_ddrsdr.h> +#include <mach/at91_ramc.h> #include <mach/at91_rstc.h> .arm @@ -20,9 +20,10 @@ .globl at91sam9g45_restart at91sam9g45_restart: - ldr r0, .at91_va_base_sdramc0 @ preload constants - ldr r1, =at91_rstc_base - ldr r1, [r1] + ldr r5, =at91_ramc_base @ preload constants + ldr r0, [r5] + ldr r4, =at91_rstc_base + ldr r1, [r4] mov r2, #1 mov r3, #AT91_DDRSDRC_LPCB_POWER_DOWN @@ -35,6 +36,3 @@ at91sam9g45_restart: str r4, [r1, #AT91_RSTC_CR] @ reset processor b . - -.at91_va_base_sdramc0: - .word AT91_VA_BASE_SYS + AT91_DDRSDRC0 diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c index d2c91a8..63d9372 100644 --- a/arch/arm/mach-at91/at91sam9rl.c +++ b/arch/arm/mach-at91/at91sam9rl.c @@ -11,6 +11,7 @@ #include <linux/module.h> +#include <asm/proc-fns.h> #include <asm/irq.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -287,12 +288,15 @@ static void __init at91sam9rl_ioremap_registers(void) { at91_ioremap_shdwc(AT91SAM9RL_BASE_SHDWC); at91_ioremap_rstc(AT91SAM9RL_BASE_RSTC); + at91_ioremap_ramc(0, AT91SAM9RL_BASE_SDRAMC, 512); at91sam926x_ioremap_pit(AT91SAM9RL_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9RL_BASE_SMC); + at91_ioremap_matrix(AT91SAM9RL_BASE_MATRIX); } static void __init at91sam9rl_initialize(void) { + arm_pm_idle = at91sam9_idle; arm_pm_restart = at91sam9_alt_restart; at91_extern_irq = (1 << AT91SAM9RL_ID_IRQ0); diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index 61908dc..eda72e8 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c @@ -20,6 +20,7 @@ #include <mach/board.h> #include <mach/at91sam9rl.h> #include <mach/at91sam9rl_matrix.h> +#include <mach/at91_matrix.h> #include <mach/at91sam9_smc.h> #include <mach/at_hdmac.h> @@ -33,10 +34,6 @@ #if defined(CONFIG_AT_HDMAC) || defined(CONFIG_AT_HDMAC_MODULE) static u64 hdmac_dmamask = DMA_BIT_MASK(32); -static struct at_dma_platform_data atdma_pdata = { - .nr_channels = 2, -}; - static struct resource hdmac_resources[] = { [0] = { .start = AT91SAM9RL_BASE_DMA, @@ -51,12 +48,11 @@ static struct resource hdmac_resources[] = { }; static struct platform_device at_hdmac_device = { - .name = "at_hdmac", + .name = "at91sam9rl_dma", .id = -1, .dev = { .dma_mask = &hdmac_dmamask, .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &atdma_pdata, }, .resource = hdmac_resources, .num_resources = ARRAY_SIZE(hdmac_resources), @@ -64,7 +60,6 @@ static struct platform_device at_hdmac_device = { void __init at91_add_device_hdmac(void) { - dma_cap_set(DMA_MEMCPY, atdma_pdata.cap_mask); platform_device_register(&at_hdmac_device); } #else @@ -271,8 +266,8 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) if (!data) return; - csa = at91_sys_read(AT91_MATRIX_EBICSA); - at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); + csa = at91_matrix_read(AT91_MATRIX_EBICSA); + at91_matrix_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); /* enable pin */ if (gpio_is_valid(data->enable_pin)) @@ -688,6 +683,8 @@ static struct resource rtt_resources[] = { .start = AT91SAM9RL_BASE_RTT, .end = AT91SAM9RL_BASE_RTT + SZ_16 - 1, .flags = IORESOURCE_MEM, + }, { + .flags = IORESOURCE_MEM, } }; @@ -695,11 +692,32 @@ static struct platform_device at91sam9rl_rtt_device = { .name = "at91_rtt", .id = 0, .resource = rtt_resources, - .num_resources = ARRAY_SIZE(rtt_resources), }; +#if IS_ENABLED(CONFIG_RTC_DRV_AT91SAM9) +static void __init at91_add_device_rtt_rtc(void) +{ + at91sam9rl_rtt_device.name = "rtc-at91sam9"; + /* + * The second resource is needed: + * GPBR will serve as the storage for RTC time offset + */ + at91sam9rl_rtt_device.num_resources = 2; + rtt_resources[1].start = AT91SAM9RL_BASE_GPBR + + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR; + rtt_resources[1].end = rtt_resources[1].start + 3; +} +#else +static void __init at91_add_device_rtt_rtc(void) +{ + /* Only one resource is needed: RTT not used as RTC */ + at91sam9rl_rtt_device.num_resources = 1; +} +#endif + static void __init at91_add_device_rtt(void) { + at91_add_device_rtt_rtc(); platform_device_register(&at91sam9rl_rtt_device); } @@ -1134,7 +1152,6 @@ static inline void configure_usart3_pins(unsigned pins) } static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ -struct platform_device *atmel_default_console_device; /* the serial console device */ void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) { diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c new file mode 100644 index 0000000..a34d96a --- /dev/null +++ b/arch/arm/mach-at91/at91sam9x5.c @@ -0,0 +1,368 @@ +/* + * Chip-specific setup code for the AT91SAM9x5 family + * + * Copyright (C) 2010-2012 Atmel Corporation. + * + * Licensed under GPLv2 or later. + */ + +#include <linux/module.h> +#include <linux/dma-mapping.h> + +#include <asm/irq.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <mach/at91sam9x5.h> +#include <mach/at91_pmc.h> +#include <mach/cpu.h> +#include <mach/board.h> + +#include "soc.h" +#include "generic.h" +#include "clock.h" +#include "sam9_smc.h" + +/* -------------------------------------------------------------------- + * Clocks + * -------------------------------------------------------------------- */ + +/* + * The peripheral clocks. + */ +static struct clk pioAB_clk = { + .name = "pioAB_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_PIOAB, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioCD_clk = { + .name = "pioCD_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_PIOCD, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk smd_clk = { + .name = "smd_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_SMD, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart0_clk = { + .name = "usart0_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_USART0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart1_clk = { + .name = "usart1_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_USART1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart2_clk = { + .name = "usart2_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_USART2, + .type = CLK_TYPE_PERIPHERAL, +}; +/* USART3 clock - Only for sam9g25/sam9x25 */ +static struct clk usart3_clk = { + .name = "usart3_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_USART3, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk twi0_clk = { + .name = "twi0_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_TWI0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk twi1_clk = { + .name = "twi1_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_TWI1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk twi2_clk = { + .name = "twi2_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_TWI2, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk mmc0_clk = { + .name = "mci0_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_MCI0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk spi0_clk = { + .name = "spi0_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_SPI0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk spi1_clk = { + .name = "spi1_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_SPI1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk uart0_clk = { + .name = "uart0_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_UART0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk uart1_clk = { + .name = "uart1_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_UART1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk tcb0_clk = { + .name = "tcb0_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_TCB, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pwm_clk = { + .name = "pwm_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_PWM, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk adc_clk = { + .name = "adc_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_ADC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk dma0_clk = { + .name = "dma0_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_DMA0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk dma1_clk = { + .name = "dma1_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_DMA1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk uhphs_clk = { + .name = "uhphs_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_UHPHS, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk udphs_clk = { + .name = "udphs_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_UDPHS, + .type = CLK_TYPE_PERIPHERAL, +}; +/* emac0 clock - Only for sam9g25/sam9x25/sam9g35/sam9x35 */ +static struct clk macb0_clk = { + .name = "pclk", + .pmc_mask = 1 << AT91SAM9X5_ID_EMAC0, + .type = CLK_TYPE_PERIPHERAL, +}; +/* lcd clock - Only for sam9g15/sam9g35/sam9x35 */ +static struct clk lcdc_clk = { + .name = "lcdc_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_LCDC, + .type = CLK_TYPE_PERIPHERAL, +}; +/* isi clock - Only for sam9g25 */ +static struct clk isi_clk = { + .name = "isi_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_ISI, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk mmc1_clk = { + .name = "mci1_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_MCI1, + .type = CLK_TYPE_PERIPHERAL, +}; +/* emac1 clock - Only for sam9x25 */ +static struct clk macb1_clk = { + .name = "pclk", + .pmc_mask = 1 << AT91SAM9X5_ID_EMAC1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ssc_clk = { + .name = "ssc_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_SSC, + .type = CLK_TYPE_PERIPHERAL, +}; +/* can0 clock - Only for sam9x35 */ +static struct clk can0_clk = { + .name = "can0_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_CAN0, + .type = CLK_TYPE_PERIPHERAL, +}; +/* can1 clock - Only for sam9x35 */ +static struct clk can1_clk = { + .name = "can1_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_CAN1, + .type = CLK_TYPE_PERIPHERAL, +}; + +static struct clk *periph_clocks[] __initdata = { + &pioAB_clk, + &pioCD_clk, + &smd_clk, + &usart0_clk, + &usart1_clk, + &usart2_clk, + &twi0_clk, + &twi1_clk, + &twi2_clk, + &mmc0_clk, + &spi0_clk, + &spi1_clk, + &uart0_clk, + &uart1_clk, + &tcb0_clk, + &pwm_clk, + &adc_clk, + &dma0_clk, + &dma1_clk, + &uhphs_clk, + &udphs_clk, + &mmc1_clk, + &ssc_clk, + // irq0 +}; + +static struct clk_lookup periph_clocks_lookups[] = { + /* lookup table for DT entries */ + CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck), + CLKDEV_CON_DEV_ID("usart", "f801c000.serial", &usart0_clk), + CLKDEV_CON_DEV_ID("usart", "f8020000.serial", &usart1_clk), + CLKDEV_CON_DEV_ID("usart", "f8024000.serial", &usart2_clk), + CLKDEV_CON_DEV_ID("usart", "f8028000.serial", &usart3_clk), + CLKDEV_CON_DEV_ID("t0_clk", "f8008000.timer", &tcb0_clk), + CLKDEV_CON_DEV_ID("t0_clk", "f800c000.timer", &tcb0_clk), + CLKDEV_CON_ID("pioA", &pioAB_clk), + CLKDEV_CON_ID("pioB", &pioAB_clk), + CLKDEV_CON_ID("pioC", &pioCD_clk), + CLKDEV_CON_ID("pioD", &pioCD_clk), + /* additional fake clock for macb_hclk */ + CLKDEV_CON_DEV_ID("hclk", "f802c000.ethernet", &macb0_clk), + CLKDEV_CON_DEV_ID("hclk", "f8030000.ethernet", &macb1_clk), +}; + +/* + * The two programmable clocks. + * You must configure pin multiplexing to bring these signals out. + */ +static struct clk pck0 = { + .name = "pck0", + .pmc_mask = AT91_PMC_PCK0, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 0, +}; +static struct clk pck1 = { + .name = "pck1", + .pmc_mask = AT91_PMC_PCK1, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 1, +}; + +static void __init at91sam9x5_register_clocks(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) + clk_register(periph_clocks[i]); + + clkdev_add_table(periph_clocks_lookups, + ARRAY_SIZE(periph_clocks_lookups)); + + if (cpu_is_at91sam9g25() + || cpu_is_at91sam9x25()) + clk_register(&usart3_clk); + + if (cpu_is_at91sam9g25() + || cpu_is_at91sam9x25() + || cpu_is_at91sam9g35() + || cpu_is_at91sam9x35()) + clk_register(&macb0_clk); + + if (cpu_is_at91sam9g15() + || cpu_is_at91sam9g35() + || cpu_is_at91sam9x35()) + clk_register(&lcdc_clk); + + if (cpu_is_at91sam9g25()) + clk_register(&isi_clk); + + if (cpu_is_at91sam9x25()) + clk_register(&macb1_clk); + + if (cpu_is_at91sam9x25() + || cpu_is_at91sam9x35()) { + clk_register(&can0_clk); + clk_register(&can1_clk); + } + + clk_register(&pck0); + clk_register(&pck1); +} + +/* -------------------------------------------------------------------- + * AT91SAM9x5 processor initialization + * -------------------------------------------------------------------- */ + +static void __init at91sam9x5_map_io(void) +{ + at91_init_sram(0, AT91SAM9X5_SRAM_BASE, AT91SAM9X5_SRAM_SIZE); +} + +static void __init at91sam9x5_ioremap_registers(void) +{ + at91_ioremap_ramc(0, AT91SAM9X5_BASE_DDRSDRC0, 512); +} + +void __init at91sam9x5_initialize(void) +{ + arm_pm_restart = at91sam9g45_restart; + at91_extern_irq = (1 << AT91SAM9X5_ID_IRQ0); + + /* Register GPIO subsystem (using DT) */ + at91_gpio_init(NULL, 0); +} + +/* -------------------------------------------------------------------- + * AT91SAM9x5 devices (temporary before modification of code) + * -------------------------------------------------------------------- */ +void __init at91_add_device_nand(struct atmel_nand_data *data) {} + +/* -------------------------------------------------------------------- + * Interrupt initialization + * -------------------------------------------------------------------- */ +/* + * The default interrupt priority levels (0 = lowest, 7 = highest). + */ +static unsigned int at91sam9x5_default_irq_priority[NR_AIC_IRQS] __initdata = { + 7, /* Advanced Interrupt Controller (FIQ) */ + 7, /* System Peripherals */ + 1, /* Parallel IO Controller A and B */ + 1, /* Parallel IO Controller C and D */ + 4, /* Soft Modem */ + 5, /* USART 0 */ + 5, /* USART 1 */ + 5, /* USART 2 */ + 5, /* USART 3 */ + 6, /* Two-Wire Interface 0 */ + 6, /* Two-Wire Interface 1 */ + 6, /* Two-Wire Interface 2 */ + 0, /* Multimedia Card Interface 0 */ + 5, /* Serial Peripheral Interface 0 */ + 5, /* Serial Peripheral Interface 1 */ + 5, /* UART 0 */ + 5, /* UART 1 */ + 0, /* Timer Counter 0, 1, 2, 3, 4 and 5 */ + 0, /* Pulse Width Modulation Controller */ + 0, /* ADC Controller */ + 0, /* DMA Controller 0 */ + 0, /* DMA Controller 1 */ + 2, /* USB Host High Speed port */ + 2, /* USB Device High speed port */ + 3, /* Ethernet MAC 0 */ + 3, /* LDC Controller or Image Sensor Interface */ + 0, /* Multimedia Card Interface 1 */ + 3, /* Ethernet MAC 1 */ + 4, /* Synchronous Serial Interface */ + 4, /* CAN Controller 0 */ + 4, /* CAN Controller 1 */ + 0, /* Advanced Interrupt Controller (IRQ0) */ +}; + +struct at91_init_soc __initdata at91sam9x5_soc = { + .map_io = at91sam9x5_map_io, + .default_irq_priority = at91sam9x5_default_irq_priority, + .ioremap_registers = at91sam9x5_ioremap_registers, + .register_clocks = at91sam9x5_register_clocks, + .init = at91sam9x5_initialize, +}; diff --git a/arch/arm/mach-at91/at91x40.c b/arch/arm/mach-at91/at91x40.c index 56ba3bd..5400a1d 100644 --- a/arch/arm/mach-at91/at91x40.c +++ b/arch/arm/mach-at91/at91x40.c @@ -13,6 +13,7 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/irq.h> +#include <asm/proc-fns.h> #include <asm/mach/arch.h> #include <mach/at91x40.h> #include <mach/at91_st.h> @@ -37,8 +38,19 @@ unsigned long clk_get_rate(struct clk *clk) return AT91X40_MASTER_CLOCK; } +static void at91x40_idle(void) +{ + /* + * Disable the processor clock. The processor will be automatically + * re-enabled by an interrupt or by a reset. + */ + __raw_writel(AT91_PS_CR_CPU, AT91_PS_CR); + cpu_do_idle(); +} + void __init at91x40_initialize(unsigned long main_clock) { + arm_pm_idle = at91x40_idle; at91_extern_irq = (1 << AT91X40_ID_IRQ0) | (1 << AT91X40_ID_IRQ1) | (1 << AT91X40_ID_IRQ2); } diff --git a/arch/arm/mach-at91/at91x40_time.c b/arch/arm/mach-at91/at91x40_time.c index dfff289..6ca680a 100644 --- a/arch/arm/mach-at91/at91x40_time.c +++ b/arch/arm/mach-at91/at91x40_time.c @@ -28,6 +28,12 @@ #include <asm/mach/time.h> #include <mach/at91_tc.h> +#define at91_tc_read(field) \ + __raw_readl(AT91_TC + field) + +#define at91_tc_write(field, value) \ + __raw_writel(value, AT91_TC + field); + /* * 3 counter/timer units present. */ @@ -37,12 +43,12 @@ static unsigned long at91x40_gettimeoffset(void) { - return (at91_sys_read(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CV) * 1000000 / (AT91X40_MASTER_CLOCK / 128)); + return (at91_tc_read(AT91_TC_CLK1BASE + AT91_TC_CV) * 1000000 / (AT91X40_MASTER_CLOCK / 128)); } static irqreturn_t at91x40_timer_interrupt(int irq, void *dev_id) { - at91_sys_read(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_SR); + at91_tc_read(AT91_TC_CLK1BASE + AT91_TC_SR); timer_tick(); return IRQ_HANDLED; } @@ -57,20 +63,20 @@ void __init at91x40_timer_init(void) { unsigned int v; - at91_sys_write(AT91_TC + AT91_TC_BCR, 0); - v = at91_sys_read(AT91_TC + AT91_TC_BMR); + at91_tc_write(AT91_TC_BCR, 0); + v = at91_tc_read(AT91_TC_BMR); v = (v & ~AT91_TC_TC1XC1S) | AT91_TC_TC1XC1S_NONE; - at91_sys_write(AT91_TC + AT91_TC_BMR, v); + at91_tc_write(AT91_TC_BMR, v); - at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CCR, AT91_TC_CLKDIS); - at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CMR, (AT91_TC_TIMER_CLOCK4 | AT91_TC_CPCTRG)); - at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_IDR, 0xffffffff); - at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_RC, (AT91X40_MASTER_CLOCK / 128) / HZ - 1); - at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_IER, (1<<4)); + at91_tc_write(AT91_TC_CLK1BASE + AT91_TC_CCR, AT91_TC_CLKDIS); + at91_tc_write(AT91_TC_CLK1BASE + AT91_TC_CMR, (AT91_TC_TIMER_CLOCK4 | AT91_TC_CPCTRG)); + at91_tc_write(AT91_TC_CLK1BASE + AT91_TC_IDR, 0xffffffff); + at91_tc_write(AT91_TC_CLK1BASE + AT91_TC_RC, (AT91X40_MASTER_CLOCK / 128) / HZ - 1); + at91_tc_write(AT91_TC_CLK1BASE + AT91_TC_IER, (1<<4)); setup_irq(AT91X40_ID_TC1, &at91x40_timer_irq); - at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CCR, (AT91_TC_SWTRG | AT91_TC_CLKEN)); + at91_tc_write(AT91_TC_CLK1BASE + AT91_TC_CCR, (AT91_TC_SWTRG | AT91_TC_CLKEN)); } struct sys_timer at91x40_timer = { diff --git a/arch/arm/mach-at91/board-cap9adk.c b/arch/arm/mach-at91/board-cap9adk.c deleted file mode 100644 index ac3de4f..0000000 --- a/arch/arm/mach-at91/board-cap9adk.c +++ /dev/null @@ -1,396 +0,0 @@ -/* - * linux/arch/arm/mach-at91/board-cap9adk.c - * - * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com> - * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com> - * Copyright (C) 2005 SAN People - * Copyright (C) 2007 Atmel Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <linux/types.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/spi/spi.h> -#include <linux/spi/ads7846.h> -#include <linux/fb.h> -#include <linux/mtd/physmap.h> - -#include <video/atmel_lcdc.h> - -#include <mach/hardware.h> -#include <asm/setup.h> -#include <asm/mach-types.h> - -#include <asm/mach/arch.h> -#include <asm/mach/map.h> - -#include <mach/board.h> -#include <mach/at91cap9_matrix.h> -#include <mach/at91sam9_smc.h> -#include <mach/system_rev.h> - -#include "sam9_smc.h" -#include "generic.h" - - -static void __init cap9adk_init_early(void) -{ - /* Initialize processor: 12 MHz crystal */ - at91_initialize(12000000); - - /* Setup the LEDs: USER1 and USER2 LED for cpu/timer... */ - at91_init_leds(AT91_PIN_PA10, AT91_PIN_PA11); - /* ... POWER LED always on */ - at91_set_gpio_output(AT91_PIN_PC29, 1); - - /* Setup the serial ports and console */ - at91_register_uart(0, 0, 0); /* DBGU = ttyS0 */ - at91_set_serial_console(0); -} - -/* - * USB Host port - */ -static struct at91_usbh_data __initdata cap9adk_usbh_data = { - .ports = 2, - .vbus_pin = {-EINVAL, -EINVAL}, - .overcurrent_pin= {-EINVAL, -EINVAL}, -}; - -/* - * USB HS Device port - */ -static struct usba_platform_data __initdata cap9adk_usba_udc_data = { - .vbus_pin = AT91_PIN_PB31, -}; - -/* - * ADS7846 Touchscreen - */ -#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) -static int ads7843_pendown_state(void) -{ - return !at91_get_gpio_value(AT91_PIN_PC4); /* Touchscreen PENIRQ */ -} - -static struct ads7846_platform_data ads_info = { - .model = 7843, - .x_min = 150, - .x_max = 3830, - .y_min = 190, - .y_max = 3830, - .vref_delay_usecs = 100, - .x_plate_ohms = 450, - .y_plate_ohms = 250, - .pressure_max = 15000, - .debounce_max = 1, - .debounce_rep = 0, - .debounce_tol = (~0), - .get_pendown_state = ads7843_pendown_state, -}; - -static void __init cap9adk_add_device_ts(void) -{ - at91_set_gpio_input(AT91_PIN_PC4, 1); /* Touchscreen PENIRQ */ - at91_set_gpio_input(AT91_PIN_PC5, 1); /* Touchscreen BUSY */ -} -#else -static void __init cap9adk_add_device_ts(void) {} -#endif - - -/* - * SPI devices. - */ -static struct spi_board_info cap9adk_spi_devices[] = { -#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) - { /* DataFlash card */ - .modalias = "mtd_dataflash", - .chip_select = 0, - .max_speed_hz = 15 * 1000 * 1000, - .bus_num = 0, - }, -#endif -#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) - { - .modalias = "ads7846", - .chip_select = 3, /* can be 2 or 3, depending on J2 jumper */ - .max_speed_hz = 125000 * 26, /* (max sample rate @ 3V) * (cmd + data + overhead) */ - .bus_num = 0, - .platform_data = &ads_info, - .irq = AT91_PIN_PC4, - }, -#endif -}; - - -/* - * MCI (SD/MMC) - */ -static struct at91_mmc_data __initdata cap9adk_mmc_data = { - .wire4 = 1, - .det_pin = -EINVAL, - .wp_pin = -EINVAL, - .vcc_pin = -EINVAL, -}; - - -/* - * MACB Ethernet device - */ -static struct macb_platform_data __initdata cap9adk_macb_data = { - .phy_irq_pin = -EINVAL, - .is_rmii = 1, -}; - - -/* - * NAND flash - */ -static struct mtd_partition __initdata cap9adk_nand_partitions[] = { - { - .name = "NAND partition", - .offset = 0, - .size = MTDPART_SIZ_FULL, - }, -}; - -static struct atmel_nand_data __initdata cap9adk_nand_data = { - .ale = 21, - .cle = 22, - .det_pin = -EINVAL, - .rdy_pin = -EINVAL, - .enable_pin = AT91_PIN_PD15, - .parts = cap9adk_nand_partitions, - .num_parts = ARRAY_SIZE(cap9adk_nand_partitions), -}; - -static struct sam9_smc_config __initdata cap9adk_nand_smc_config = { - .ncs_read_setup = 1, - .nrd_setup = 2, - .ncs_write_setup = 1, - .nwe_setup = 2, - - .ncs_read_pulse = 6, - .nrd_pulse = 4, - .ncs_write_pulse = 6, - .nwe_pulse = 4, - - .read_cycle = 8, - .write_cycle = 8, - - .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE, - .tdf_cycles = 1, -}; - -static void __init cap9adk_add_device_nand(void) -{ - unsigned long csa; - - csa = at91_sys_read(AT91_MATRIX_EBICSA); - at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_VDDIOMSEL_3_3V); - - cap9adk_nand_data.bus_width_16 = board_have_nand_16bit(); - /* setup bus-width (8 or 16) */ - if (cap9adk_nand_data.bus_width_16) - cap9adk_nand_smc_config.mode |= AT91_SMC_DBW_16; - else - cap9adk_nand_smc_config.mode |= AT91_SMC_DBW_8; - - /* configure chip-select 3 (NAND) */ - sam9_smc_configure(0, 3, &cap9adk_nand_smc_config); - - at91_add_device_nand(&cap9adk_nand_data); -} - - -/* - * NOR flash - */ -static struct mtd_partition cap9adk_nor_partitions[] = { - { - .name = "NOR partition", - .offset = 0, - .size = MTDPART_SIZ_FULL, - }, -}; - -static struct physmap_flash_data cap9adk_nor_data = { - .width = 2, - .parts = cap9adk_nor_partitions, - .nr_parts = ARRAY_SIZE(cap9adk_nor_partitions), -}; - -#define NOR_BASE AT91_CHIPSELECT_0 -#define NOR_SIZE SZ_8M - -static struct resource nor_flash_resources[] = { - { - .start = NOR_BASE, - .end = NOR_BASE + NOR_SIZE - 1, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device cap9adk_nor_flash = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &cap9adk_nor_data, - }, - .resource = nor_flash_resources, - .num_resources = ARRAY_SIZE(nor_flash_resources), -}; - -static struct sam9_smc_config __initdata cap9adk_nor_smc_config = { - .ncs_read_setup = 2, - .nrd_setup = 4, - .ncs_write_setup = 2, - .nwe_setup = 4, - - .ncs_read_pulse = 10, - .nrd_pulse = 8, - .ncs_write_pulse = 10, - .nwe_pulse = 8, - - .read_cycle = 16, - .write_cycle = 16, - - .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE | AT91_SMC_DBW_16, - .tdf_cycles = 1, -}; - -static __init void cap9adk_add_device_nor(void) -{ - unsigned long csa; - - csa = at91_sys_read(AT91_MATRIX_EBICSA); - at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_VDDIOMSEL_3_3V); - - /* configure chip-select 0 (NOR) */ - sam9_smc_configure(0, 0, &cap9adk_nor_smc_config); - - platform_device_register(&cap9adk_nor_flash); -} - - -/* - * LCD Controller - */ -#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) -static struct fb_videomode at91_tft_vga_modes[] = { - { - .name = "TX09D50VM1CCA @ 60", - .refresh = 60, - .xres = 240, .yres = 320, - .pixclock = KHZ2PICOS(4965), - - .left_margin = 1, .right_margin = 33, - .upper_margin = 1, .lower_margin = 0, - .hsync_len = 5, .vsync_len = 1, - - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - .vmode = FB_VMODE_NONINTERLACED, - }, -}; - -static struct fb_monspecs at91fb_default_monspecs = { - .manufacturer = "HIT", - .monitor = "TX09D70VM1CCA", - - .modedb = at91_tft_vga_modes, - .modedb_len = ARRAY_SIZE(at91_tft_vga_modes), - .hfmin = 15000, - .hfmax = 64000, - .vfmin = 50, - .vfmax = 150, -}; - -#define AT91CAP9_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \ - | ATMEL_LCDC_DISTYPE_TFT \ - | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE) - -static void at91_lcdc_power_control(int on) -{ - if (on) - at91_set_gpio_value(AT91_PIN_PC0, 0); /* power up */ - else - at91_set_gpio_value(AT91_PIN_PC0, 1); /* power down */ -} - -/* Driver datas */ -static struct atmel_lcdfb_info __initdata cap9adk_lcdc_data = { - .default_bpp = 16, - .default_dmacon = ATMEL_LCDC_DMAEN, - .default_lcdcon2 = AT91CAP9_DEFAULT_LCDCON2, - .default_monspecs = &at91fb_default_monspecs, - .atmel_lcdfb_power_control = at91_lcdc_power_control, - .guard_time = 1, -}; - -#else -static struct atmel_lcdfb_info __initdata cap9adk_lcdc_data; -#endif - - -/* - * AC97 - */ -static struct ac97c_platform_data cap9adk_ac97_data = { - .reset_pin = -EINVAL, -}; - - -static void __init cap9adk_board_init(void) -{ - /* Serial */ - at91_add_device_serial(); - /* USB Host */ - at91_add_device_usbh(&cap9adk_usbh_data); - /* USB HS */ - at91_add_device_usba(&cap9adk_usba_udc_data); - /* SPI */ - at91_add_device_spi(cap9adk_spi_devices, ARRAY_SIZE(cap9adk_spi_devices)); - /* Touchscreen */ - cap9adk_add_device_ts(); - /* MMC */ - at91_add_device_mmc(1, &cap9adk_mmc_data); - /* Ethernet */ - at91_add_device_eth(&cap9adk_macb_data); - /* NAND */ - cap9adk_add_device_nand(); - /* NOR Flash */ - cap9adk_add_device_nor(); - /* I2C */ - at91_add_device_i2c(NULL, 0); - /* LCD Controller */ - at91_add_device_lcdc(&cap9adk_lcdc_data); - /* AC97 */ - at91_add_device_ac97(&cap9adk_ac97_data); -} - -MACHINE_START(AT91CAP9ADK, "Atmel AT91CAP9A-DK") - /* Maintainer: Stelian Pop <stelian.pop@leadtechdesign.com> */ - .timer = &at91sam926x_timer, - .map_io = at91_map_io, - .init_early = cap9adk_init_early, - .init_irq = at91_init_irq_default, - .init_machine = cap9adk_board_init, -MACHINE_END diff --git a/arch/arm/mach-at91/board-cpu9krea.c b/arch/arm/mach-at91/board-cpu9krea.c index 9ab3d1e..989e1c5 100644 --- a/arch/arm/mach-at91/board-cpu9krea.c +++ b/arch/arm/mach-at91/board-cpu9krea.c @@ -43,6 +43,7 @@ #include <mach/board.h> #include <mach/at91sam9_smc.h> #include <mach/at91sam9260_matrix.h> +#include <mach/at91_matrix.h> #include "sam9_smc.h" #include "generic.h" @@ -238,8 +239,8 @@ static __init void cpu9krea_add_device_nor(void) { unsigned long csa; - csa = at91_sys_read(AT91_MATRIX_EBICSA); - at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_VDDIOMSEL_3_3V); + csa = at91_matrix_read(AT91_MATRIX_EBICSA); + at91_matrix_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_VDDIOMSEL_3_3V); /* configure chip-select 0 (NOR) */ sam9_smc_configure(0, 0, &cpu9krea_nor_smc_config); diff --git a/arch/arm/mach-at91/board-cpuat91.c b/arch/arm/mach-at91/board-cpuat91.c index 368e142..e094cc8 100644 --- a/arch/arm/mach-at91/board-cpuat91.c +++ b/arch/arm/mach-at91/board-cpuat91.c @@ -38,6 +38,7 @@ #include <mach/board.h> #include <mach/at91rm9200_mc.h> +#include <mach/at91_ramc.h> #include <mach/cpu.h> #include "generic.h" diff --git a/arch/arm/mach-at91/board-dt.c b/arch/arm/mach-at91/board-dt.c index bb6b434..583b724 100644 --- a/arch/arm/mach-at91/board-dt.c +++ b/arch/arm/mach-at91/board-dt.c @@ -15,7 +15,7 @@ #include <linux/init.h> #include <linux/module.h> #include <linux/gpio.h> -#include <linux/irqdomain.h> +#include <linux/of.h> #include <linux/of_irq.h> #include <linux/of_platform.h> @@ -38,12 +38,6 @@ static void __init ek_init_early(void) { /* Initialize processor: 12.000 MHz crystal */ at91_initialize(12000000); - - /* DGBU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* set serial console to ttyS0 (ie, DBGU) */ - at91_set_serial_console(0); } /* det_pin is not connected */ @@ -88,15 +82,17 @@ static void __init ek_add_device_nand(void) at91_add_device_nand(&ek_nand_data); } -static const struct of_device_id aic_of_match[] __initconst = { - { .compatible = "atmel,at91rm9200-aic", }, - {}, +static const struct of_device_id irq_of_match[] __initconst = { + + { .compatible = "atmel,at91rm9200-aic", .data = at91_aic_of_init }, + { .compatible = "atmel,at91rm9200-gpio", .data = at91_gpio_of_irq_setup }, + { .compatible = "atmel,at91sam9x5-gpio", .data = at91_gpio_of_irq_setup }, + { /*sentinel*/ } }; static void __init at91_dt_init_irq(void) { - irq_domain_generate_simple(aic_of_match, 0xfffff000, 0); - at91_init_irq_default(); + of_irq_init(irq_of_match); } static void __init at91_dt_device_init(void) @@ -109,6 +105,7 @@ static void __init at91_dt_device_init(void) static const char *at91_dt_board_compat[] __initdata = { "atmel,at91sam9m10g45ek", + "atmel,at91sam9x5ek", "calao,usb-a9g20", NULL }; diff --git a/arch/arm/mach-at91/board-eco920.c b/arch/arm/mach-at91/board-eco920.c index 07ef35b..f23aabe 100644 --- a/arch/arm/mach-at91/board-eco920.c +++ b/arch/arm/mach-at91/board-eco920.c @@ -26,6 +26,7 @@ #include <mach/board.h> #include <mach/at91rm9200_mc.h> +#include <mach/at91_ramc.h> #include <mach/cpu.h> #include "generic.h" @@ -110,7 +111,7 @@ static void __init eco920_board_init(void) at91_add_device_mmc(0, &eco920_mmc_data); platform_device_register(&eco920_flash); - at91_sys_write(AT91_SMC_CSR(7), AT91_SMC_RWHOLD_(1) + at91_ramc_write(0, AT91_SMC_CSR(7), AT91_SMC_RWHOLD_(1) | AT91_SMC_RWSETUP_(1) | AT91_SMC_DBW_8 | AT91_SMC_WSEN @@ -122,7 +123,7 @@ static void __init eco920_board_init(void) at91_set_deglitch(AT91_PIN_PA23, 1); /* Initialization of the Static Memory Controller for Chip Select 3 */ - at91_sys_write(AT91_SMC_CSR(3), + at91_ramc_write(0, AT91_SMC_CSR(3), AT91_SMC_DBW_16 | /* 16 bit */ AT91_SMC_WSEN | AT91_SMC_NWS_(5) | /* wait states */ diff --git a/arch/arm/mach-at91/board-flexibity.c b/arch/arm/mach-at91/board-flexibity.c index eec02cd..1815152 100644 --- a/arch/arm/mach-at91/board-flexibity.c +++ b/arch/arm/mach-at91/board-flexibity.c @@ -1,7 +1,7 @@ /* * linux/arch/arm/mach-at91/board-flexibity.c * - * Copyright (C) 2010 Flexibity + * Copyright (C) 2010-2011 Flexibity * Copyright (C) 2005 SAN People * Copyright (C) 2006 Atmel * @@ -62,6 +62,13 @@ static struct at91_udc_data __initdata flexibity_udc_data = { .pullup_pin = -EINVAL, /* pull-up driven by UDC */ }; +/* I2C devices */ +static struct i2c_board_info __initdata flexibity_i2c_devices[] = { + { + I2C_BOARD_INFO("ds1307", 0x68), + }, +}; + /* SPI devices */ static struct spi_board_info flexibity_spi_devices[] = { { /* DataFlash chip */ @@ -141,6 +148,9 @@ static void __init flexibity_board_init(void) at91_add_device_usbh(&flexibity_usbh_data); /* USB Device */ at91_add_device_udc(&flexibity_udc_data); + /* I2C */ + at91_add_device_i2c(flexibity_i2c_devices, + ARRAY_SIZE(flexibity_i2c_devices)); /* SPI */ at91_add_device_spi(flexibity_spi_devices, ARRAY_SIZE(flexibity_spi_devices)); diff --git a/arch/arm/mach-at91/board-kb9202.c b/arch/arm/mach-at91/board-kb9202.c index d75a4a2..bb99145 100644 --- a/arch/arm/mach-at91/board-kb9202.c +++ b/arch/arm/mach-at91/board-kb9202.c @@ -38,6 +38,7 @@ #include <mach/board.h> #include <mach/cpu.h> #include <mach/at91rm9200_mc.h> +#include <mach/at91_ramc.h> #include "generic.h" diff --git a/arch/arm/mach-at91/board-picotux200.c b/arch/arm/mach-at91/board-picotux200.c index ab024fa..59e35dd 100644 --- a/arch/arm/mach-at91/board-picotux200.c +++ b/arch/arm/mach-at91/board-picotux200.c @@ -39,6 +39,7 @@ #include <mach/board.h> #include <mach/at91rm9200_mc.h> +#include <mach/at91_ramc.h> #include "generic.h" diff --git a/arch/arm/mach-at91/board-rm9200dk.c b/arch/arm/mach-at91/board-rm9200dk.c index 782f379..9083df0 100644 --- a/arch/arm/mach-at91/board-rm9200dk.c +++ b/arch/arm/mach-at91/board-rm9200dk.c @@ -41,6 +41,7 @@ #include <mach/hardware.h> #include <mach/board.h> #include <mach/at91rm9200_mc.h> +#include <mach/at91_ramc.h> #include "generic.h" diff --git a/arch/arm/mach-at91/board-rm9200ek.c b/arch/arm/mach-at91/board-rm9200ek.c index ef7c12a..11cbaa8 100644 --- a/arch/arm/mach-at91/board-rm9200ek.c +++ b/arch/arm/mach-at91/board-rm9200ek.c @@ -41,6 +41,7 @@ #include <mach/hardware.h> #include <mach/board.h> #include <mach/at91rm9200_mc.h> +#include <mach/at91_ramc.h> #include "generic.h" diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c index ea0d1b9..57497e2 100644 --- a/arch/arm/mach-at91/board-sam9m10g45ek.c +++ b/arch/arm/mach-at91/board-sam9m10g45ek.c @@ -24,11 +24,13 @@ #include <linux/gpio_keys.h> #include <linux/input.h> #include <linux/leds.h> -#include <linux/clk.h> #include <linux/atmel-mci.h> +#include <linux/delay.h> #include <mach/hardware.h> #include <video/atmel_lcdc.h> +#include <media/soc_camera.h> +#include <media/atmel-isi.h> #include <asm/setup.h> #include <asm/mach-types.h> @@ -185,6 +187,71 @@ static void __init ek_add_device_nand(void) /* + * ISI + */ +static struct isi_platform_data __initdata isi_data = { + .frate = ISI_CFG1_FRATE_CAPTURE_ALL, + /* to use codec and preview path simultaneously */ + .full_mode = 1, + .data_width_flags = ISI_DATAWIDTH_8 | ISI_DATAWIDTH_10, + /* ISI_MCK is provided by programmable clock or external clock */ + .mck_hz = 25000000, +}; + + +/* + * soc-camera OV2640 + */ +#if defined(CONFIG_SOC_CAMERA_OV2640) || \ + defined(CONFIG_SOC_CAMERA_OV2640_MODULE) +static unsigned long isi_camera_query_bus_param(struct soc_camera_link *link) +{ + /* ISI board for ek using default 8-bits connection */ + return SOCAM_DATAWIDTH_8; +} + +static int i2c_camera_power(struct device *dev, int on) +{ + /* enable or disable the camera */ + pr_debug("%s: %s the camera\n", __func__, on ? "ENABLE" : "DISABLE"); + at91_set_gpio_output(AT91_PIN_PD13, !on); + + if (!on) + goto out; + + /* If enabled, give a reset impulse */ + at91_set_gpio_output(AT91_PIN_PD12, 0); + msleep(20); + at91_set_gpio_output(AT91_PIN_PD12, 1); + msleep(100); + +out: + return 0; +} + +static struct i2c_board_info i2c_camera = { + I2C_BOARD_INFO("ov2640", 0x30), +}; + +static struct soc_camera_link iclink_ov2640 = { + .bus_id = 0, + .board_info = &i2c_camera, + .i2c_adapter_id = 0, + .power = i2c_camera_power, + .query_bus_param = isi_camera_query_bus_param, +}; + +static struct platform_device isi_ov2640 = { + .name = "soc-camera-pdrv", + .id = 0, + .dev = { + .platform_data = &iclink_ov2640, + }, +}; +#endif + + +/* * LCD Controller */ #if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) @@ -377,7 +444,12 @@ static struct gpio_led ek_pwm_led[] = { #endif }; - +static struct platform_device *devices[] __initdata = { +#if defined(CONFIG_SOC_CAMERA_OV2640) || \ + defined(CONFIG_SOC_CAMERA_OV2640_MODULE) + &isi_ov2640, +#endif +}; static void __init ek_board_init(void) { @@ -399,6 +471,8 @@ static void __init ek_board_init(void) ek_add_device_nand(); /* I2C */ at91_add_device_i2c(0, NULL, 0); + /* ISI, using programmable clock as ISI_MCK */ + at91_add_device_isi(&isi_data, true); /* LCD Controller */ at91_add_device_lcdc(&ek_lcdc_data); /* Touch Screen */ @@ -410,6 +484,8 @@ static void __init ek_board_init(void) /* LEDs */ at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); at91_pwm_leds(ek_pwm_led, ARRAY_SIZE(ek_pwm_led)); + /* Other platform devices */ + platform_add_devices(devices, ARRAY_SIZE(devices)); } MACHINE_START(AT91SAM9M10G45EK, "Atmel AT91SAM9M10G45-EK") diff --git a/arch/arm/mach-at91/board-snapper9260.c b/arch/arm/mach-at91/board-snapper9260.c index 4770db0..3c2e3fc 100644 --- a/arch/arm/mach-at91/board-snapper9260.c +++ b/arch/arm/mach-at91/board-snapper9260.c @@ -145,11 +145,11 @@ static struct i2c_board_info __initdata snapper9260_i2c_devices[] = { /* Audio codec */ I2C_BOARD_INFO("tlv320aic23", 0x1a), }, - { +}; + +static struct i2c_board_info __initdata snapper9260_i2c_isl1208 = { /* RTC */ I2C_BOARD_INFO("isl1208", 0x6f), - .irq = gpio_to_irq(AT91_PIN_PA31), - }, }; static void __init snapper9260_add_device_nand(void) @@ -163,6 +163,10 @@ static void __init snapper9260_board_init(void) { at91_add_device_i2c(snapper9260_i2c_devices, ARRAY_SIZE(snapper9260_i2c_devices)); + + snapper9260_i2c_isl1208.irq = gpio_to_irq(AT91_PIN_PA31); + i2c_register_board_info(0, &snapper9260_i2c_isl1208, 1); + at91_add_device_serial(); at91_add_device_usbh(&snapper9260_usbh_data); at91_add_device_udc(&snapper9260_udc_data); diff --git a/arch/arm/mach-at91/board-yl-9200.c b/arch/arm/mach-at91/board-yl-9200.c index bbd553e..52f4607 100644 --- a/arch/arm/mach-at91/board-yl-9200.c +++ b/arch/arm/mach-at91/board-yl-9200.c @@ -45,6 +45,7 @@ #include <mach/hardware.h> #include <mach/board.h> #include <mach/at91rm9200_mc.h> +#include <mach/at91_ramc.h> #include <mach/cpu.h> #include "generic.h" @@ -393,7 +394,7 @@ static void yl9200_init_video(void) at91_set_A_periph(AT91_PIN_PC6, 0); /* Initialization of the Static Memory Controller for Chip Select 2 */ - at91_sys_write(AT91_SMC_CSR(2), AT91_SMC_DBW_16 /* 16 bit */ + at91_ramc_write(0, AT91_SMC_CSR(2), AT91_SMC_DBW_16 /* 16 bit */ | AT91_SMC_WSEN | AT91_SMC_NWS_(0x4) /* wait states */ | AT91_SMC_TDF_(0x100) /* float time */ ); diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index 61873f3..be51ca7 100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c @@ -28,9 +28,12 @@ #include <mach/at91_pmc.h> #include <mach/cpu.h> +#include <asm/proc-fns.h> + #include "clock.h" #include "generic.h" +void __iomem *at91_pmc_base; /* * There's a lot more which can be done with clocks, including cpufreq @@ -47,26 +50,38 @@ /* * Chips have some kind of clocks : group them by functionality */ -#define cpu_has_utmi() ( cpu_is_at91cap9() \ - || cpu_is_at91sam9rl() \ - || cpu_is_at91sam9g45()) +#define cpu_has_utmi() ( cpu_is_at91sam9rl() \ + || cpu_is_at91sam9g45() \ + || cpu_is_at91sam9x5()) #define cpu_has_800M_plla() ( cpu_is_at91sam9g20() \ - || cpu_is_at91sam9g45()) + || cpu_is_at91sam9g45() \ + || cpu_is_at91sam9x5()) #define cpu_has_300M_plla() (cpu_is_at91sam9g10()) #define cpu_has_pllb() (!(cpu_is_at91sam9rl() \ - || cpu_is_at91sam9g45())) + || cpu_is_at91sam9g45() \ + || cpu_is_at91sam9x5())) -#define cpu_has_upll() (cpu_is_at91sam9g45()) +#define cpu_has_upll() (cpu_is_at91sam9g45() \ + || cpu_is_at91sam9x5()) /* USB host HS & FS */ #define cpu_has_uhp() (!cpu_is_at91sam9rl()) /* USB device FS only */ #define cpu_has_udpfs() (!(cpu_is_at91sam9rl() \ - || cpu_is_at91sam9g45())) + || cpu_is_at91sam9g45() \ + || cpu_is_at91sam9x5())) + +#define cpu_has_plladiv2() (cpu_is_at91sam9g45() \ + || cpu_is_at91sam9x5()) + +#define cpu_has_mdiv3() (cpu_is_at91sam9g45() \ + || cpu_is_at91sam9x5()) + +#define cpu_has_alt_prescaler() (cpu_is_at91sam9x5()) static LIST_HEAD(clocks); static DEFINE_SPINLOCK(clk_lock); @@ -111,11 +126,11 @@ static void pllb_mode(struct clk *clk, int is_on) value = 0; // REVISIT: Add work-around for AT91RM9200 Errata #26 ? - at91_sys_write(AT91_CKGR_PLLBR, value); + at91_pmc_write(AT91_CKGR_PLLBR, value); do { cpu_relax(); - } while ((at91_sys_read(AT91_PMC_SR) & AT91_PMC_LOCKB) != is_on); + } while ((at91_pmc_read(AT91_PMC_SR) & AT91_PMC_LOCKB) != is_on); } static struct clk pllb = { @@ -130,31 +145,24 @@ static struct clk pllb = { static void pmc_sys_mode(struct clk *clk, int is_on) { if (is_on) - at91_sys_write(AT91_PMC_SCER, clk->pmc_mask); + at91_pmc_write(AT91_PMC_SCER, clk->pmc_mask); else - at91_sys_write(AT91_PMC_SCDR, clk->pmc_mask); + at91_pmc_write(AT91_PMC_SCDR, clk->pmc_mask); } static void pmc_uckr_mode(struct clk *clk, int is_on) { - unsigned int uckr = at91_sys_read(AT91_CKGR_UCKR); - - if (cpu_is_at91sam9g45()) { - if (is_on) - uckr |= AT91_PMC_BIASEN; - else - uckr &= ~AT91_PMC_BIASEN; - } + unsigned int uckr = at91_pmc_read(AT91_CKGR_UCKR); if (is_on) { is_on = AT91_PMC_LOCKU; - at91_sys_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask); + at91_pmc_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask); } else - at91_sys_write(AT91_CKGR_UCKR, uckr & ~(clk->pmc_mask)); + at91_pmc_write(AT91_CKGR_UCKR, uckr & ~(clk->pmc_mask)); do { cpu_relax(); - } while ((at91_sys_read(AT91_PMC_SR) & AT91_PMC_LOCKU) != is_on); + } while ((at91_pmc_read(AT91_PMC_SR) & AT91_PMC_LOCKU) != is_on); } /* USB function clocks (PLLB must be 48 MHz) */ @@ -190,9 +198,9 @@ struct clk mck = { static void pmc_periph_mode(struct clk *clk, int is_on) { if (is_on) - at91_sys_write(AT91_PMC_PCER, clk->pmc_mask); + at91_pmc_write(AT91_PMC_PCER, clk->pmc_mask); else - at91_sys_write(AT91_PMC_PCDR, clk->pmc_mask); + at91_pmc_write(AT91_PMC_PCDR, clk->pmc_mask); } static struct clk __init *at91_css_to_clk(unsigned long css) @@ -210,11 +218,24 @@ static struct clk __init *at91_css_to_clk(unsigned long css) return &utmi_clk; else if (cpu_has_pllb()) return &pllb; + break; + /* alternate PMC: can use master clock */ + case AT91_PMC_CSS_MASTER: + return &mck; } return NULL; } +static int pmc_prescaler_divider(u32 reg) +{ + if (cpu_has_alt_prescaler()) { + return 1 << ((reg & AT91_PMC_ALT_PRES) >> PMC_ALT_PRES_OFFSET); + } else { + return 1 << ((reg & AT91_PMC_PRES) >> PMC_PRES_OFFSET); + } +} + static void __clk_enable(struct clk *clk) { if (clk->parent) @@ -316,12 +337,22 @@ int clk_set_rate(struct clk *clk, unsigned long rate) { unsigned long flags; unsigned prescale; + unsigned long prescale_offset, css_mask; unsigned long actual; if (!clk_is_programmable(clk)) return -EINVAL; if (clk->users) return -EBUSY; + + if (cpu_has_alt_prescaler()) { + prescale_offset = PMC_ALT_PRES_OFFSET; + css_mask = AT91_PMC_ALT_PCKR_CSS; + } else { + prescale_offset = PMC_PRES_OFFSET; + css_mask = AT91_PMC_CSS; + } + spin_lock_irqsave(&clk_lock, flags); actual = clk->parent->rate_hz; @@ -329,10 +360,10 @@ int clk_set_rate(struct clk *clk, unsigned long rate) if (actual && actual <= rate) { u32 pckr; - pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); - pckr &= AT91_PMC_CSS; /* clock selection */ - pckr |= prescale << 2; - at91_sys_write(AT91_PMC_PCKR(clk->id), pckr); + pckr = at91_pmc_read(AT91_PMC_PCKR(clk->id)); + pckr &= css_mask; /* keep clock selection */ + pckr |= prescale << prescale_offset; + at91_pmc_write(AT91_PMC_PCKR(clk->id), pckr); clk->rate_hz = actual; break; } @@ -366,7 +397,7 @@ int clk_set_parent(struct clk *clk, struct clk *parent) clk->rate_hz = parent->rate_hz; clk->parent = parent; - at91_sys_write(AT91_PMC_PCKR(clk->id), parent->id); + at91_pmc_write(AT91_PMC_PCKR(clk->id), parent->id); spin_unlock_irqrestore(&clk_lock, flags); return 0; @@ -378,11 +409,17 @@ static void __init init_programmable_clock(struct clk *clk) { struct clk *parent; u32 pckr; + unsigned int css_mask; + + if (cpu_has_alt_prescaler()) + css_mask = AT91_PMC_ALT_PCKR_CSS; + else + css_mask = AT91_PMC_CSS; - pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); - parent = at91_css_to_clk(pckr & AT91_PMC_CSS); + pckr = at91_pmc_read(AT91_PMC_PCKR(clk->id)); + parent = at91_css_to_clk(pckr & css_mask); clk->parent = parent; - clk->rate_hz = parent->rate_hz / (1 << ((pckr & AT91_PMC_PRES) >> 2)); + clk->rate_hz = parent->rate_hz / pmc_prescaler_divider(pckr); } #endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */ @@ -396,19 +433,24 @@ static int at91_clk_show(struct seq_file *s, void *unused) u32 scsr, pcsr, uckr = 0, sr; struct clk *clk; - seq_printf(s, "SCSR = %8x\n", scsr = at91_sys_read(AT91_PMC_SCSR)); - seq_printf(s, "PCSR = %8x\n", pcsr = at91_sys_read(AT91_PMC_PCSR)); - seq_printf(s, "MOR = %8x\n", at91_sys_read(AT91_CKGR_MOR)); - seq_printf(s, "MCFR = %8x\n", at91_sys_read(AT91_CKGR_MCFR)); - seq_printf(s, "PLLA = %8x\n", at91_sys_read(AT91_CKGR_PLLAR)); + scsr = at91_pmc_read(AT91_PMC_SCSR); + pcsr = at91_pmc_read(AT91_PMC_PCSR); + sr = at91_pmc_read(AT91_PMC_SR); + seq_printf(s, "SCSR = %8x\n", scsr); + seq_printf(s, "PCSR = %8x\n", pcsr); + seq_printf(s, "MOR = %8x\n", at91_pmc_read(AT91_CKGR_MOR)); + seq_printf(s, "MCFR = %8x\n", at91_pmc_read(AT91_CKGR_MCFR)); + seq_printf(s, "PLLA = %8x\n", at91_pmc_read(AT91_CKGR_PLLAR)); if (cpu_has_pllb()) - seq_printf(s, "PLLB = %8x\n", at91_sys_read(AT91_CKGR_PLLBR)); - if (cpu_has_utmi()) - seq_printf(s, "UCKR = %8x\n", uckr = at91_sys_read(AT91_CKGR_UCKR)); - seq_printf(s, "MCKR = %8x\n", at91_sys_read(AT91_PMC_MCKR)); + seq_printf(s, "PLLB = %8x\n", at91_pmc_read(AT91_CKGR_PLLBR)); + if (cpu_has_utmi()) { + uckr = at91_pmc_read(AT91_CKGR_UCKR); + seq_printf(s, "UCKR = %8x\n", uckr); + } + seq_printf(s, "MCKR = %8x\n", at91_pmc_read(AT91_PMC_MCKR)); if (cpu_has_upll()) - seq_printf(s, "USB = %8x\n", at91_sys_read(AT91_PMC_USB)); - seq_printf(s, "SR = %8x\n", sr = at91_sys_read(AT91_PMC_SR)); + seq_printf(s, "USB = %8x\n", at91_pmc_read(AT91_PMC_USB)); + seq_printf(s, "SR = %8x\n", sr); seq_printf(s, "\n"); @@ -596,16 +638,14 @@ static void __init at91_pllb_usbfs_clock_init(unsigned long main_clock) if (cpu_is_at91rm9200()) { uhpck.pmc_mask = AT91RM9200_PMC_UHP; udpck.pmc_mask = AT91RM9200_PMC_UDP; - at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP); + at91_pmc_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP); } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() || cpu_is_at91sam9g20() || cpu_is_at91sam9g10()) { uhpck.pmc_mask = AT91SAM926x_PMC_UHP; udpck.pmc_mask = AT91SAM926x_PMC_UDP; - } else if (cpu_is_at91cap9()) { - uhpck.pmc_mask = AT91CAP9_PMC_UHP; } - at91_sys_write(AT91_CKGR_PLLBR, 0); + at91_pmc_write(AT91_CKGR_PLLBR, 0); udpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init); uhpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init); @@ -622,13 +662,13 @@ static void __init at91_upll_usbfs_clock_init(unsigned long main_clock) /* Setup divider by 10 to reach 48 MHz */ usbr |= ((10 - 1) << 8) & AT91_PMC_OHCIUSBDIV; - at91_sys_write(AT91_PMC_USB, usbr); + at91_pmc_write(AT91_PMC_USB, usbr); /* Now set uhpck values */ uhpck.parent = &utmi_clk; uhpck.pmc_mask = AT91SAM926x_PMC_UHP; uhpck.rate_hz = utmi_clk.rate_hz; - uhpck.rate_hz /= 1 + ((at91_sys_read(AT91_PMC_USB) & AT91_PMC_OHCIUSBDIV) >> 8); + uhpck.rate_hz /= 1 + ((at91_pmc_read(AT91_PMC_USB) & AT91_PMC_OHCIUSBDIV) >> 8); } int __init at91_clock_init(unsigned long main_clock) @@ -637,6 +677,10 @@ int __init at91_clock_init(unsigned long main_clock) int i; int pll_overclock = false; + at91_pmc_base = ioremap(AT91_PMC, 256); + if (!at91_pmc_base) + panic("Impossible to ioremap AT91_PMC 0x%x\n", AT91_PMC); + /* * When the bootloader initialized the main oscillator correctly, * there's no problem using the cycle counter. But if it didn't, @@ -645,14 +689,14 @@ int __init at91_clock_init(unsigned long main_clock) */ if (!main_clock) { do { - tmp = at91_sys_read(AT91_CKGR_MCFR); + tmp = at91_pmc_read(AT91_CKGR_MCFR); } while (!(tmp & AT91_PMC_MAINRDY)); main_clock = (tmp & AT91_PMC_MAINF) * (AT91_SLOW_CLOCK / 16); } main_clk.rate_hz = main_clock; /* report if PLLA is more than mildly overclocked */ - plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_sys_read(AT91_CKGR_PLLAR)); + plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_pmc_read(AT91_CKGR_PLLAR)); if (cpu_has_300M_plla()) { if (plla.rate_hz > 300000000) pll_overclock = true; @@ -666,8 +710,8 @@ int __init at91_clock_init(unsigned long main_clock) if (pll_overclock) pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000); - if (cpu_is_at91sam9g45()) { - mckr = at91_sys_read(AT91_PMC_MCKR); + if (cpu_has_plladiv2()) { + mckr = at91_pmc_read(AT91_PMC_MCKR); plla.rate_hz /= (1 << ((mckr & AT91_PMC_PLLADIV2) >> 12)); /* plla divisor by 2 */ } @@ -688,6 +732,10 @@ int __init at91_clock_init(unsigned long main_clock) * (obtain the USB High Speed 480 MHz when input is 12 MHz) */ utmi_clk.rate_hz = 40 * utmi_clk.parent->rate_hz; + + /* UTMI bias and PLL are managed at the same time */ + if (cpu_has_upll()) + utmi_clk.pmc_mask |= AT91_PMC_BIASEN; } /* @@ -703,10 +751,10 @@ int __init at91_clock_init(unsigned long main_clock) * MCK and CPU derive from one of those primary clocks. * For now, assume this parentage won't change. */ - mckr = at91_sys_read(AT91_PMC_MCKR); + mckr = at91_pmc_read(AT91_PMC_MCKR); mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS); freq = mck.parent->rate_hz; - freq /= (1 << ((mckr & AT91_PMC_PRES) >> 2)); /* prescale */ + freq /= pmc_prescaler_divider(mckr); /* prescale */ if (cpu_is_at91rm9200()) { mck.rate_hz = freq / (1 + ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ } else if (cpu_is_at91sam9g20()) { @@ -714,13 +762,19 @@ int __init at91_clock_init(unsigned long main_clock) freq / ((mckr & AT91_PMC_MDIV) >> 7) : freq; /* mdiv ; (x >> 7) = ((x >> 8) * 2) */ if (mckr & AT91_PMC_PDIV) freq /= 2; /* processor clock division */ - } else if (cpu_is_at91sam9g45()) { + } else if (cpu_has_mdiv3()) { mck.rate_hz = (mckr & AT91_PMC_MDIV) == AT91SAM9_PMC_MDIV_3 ? freq / 3 : freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ } else { mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ } + if (cpu_has_alt_prescaler()) { + /* Programmable clocks can use MCK */ + mck.type |= CLK_TYPE_PRIMARY; + mck.id = 4; + } + /* Register the PMC's standard clocks */ for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++) at91_clk_add(standard_pmc_clocks[i]); @@ -770,9 +824,15 @@ static int __init at91_clock_reset(void) pr_debug("Clocks: disable unused %s\n", clk->name); } - at91_sys_write(AT91_PMC_PCDR, pcdr); - at91_sys_write(AT91_PMC_SCDR, scdr); + at91_pmc_write(AT91_PMC_PCDR, pcdr); + at91_pmc_write(AT91_PMC_SCDR, scdr); return 0; } late_initcall(at91_clock_reset); + +void at91sam9_idle(void) +{ + at91_pmc_write(AT91_PMC_SCDR, AT91_PMC_PCK); + cpu_do_idle(); +} diff --git a/arch/arm/mach-at91/cpuidle.c b/arch/arm/mach-at91/cpuidle.c index a851e6c9..555d956 100644 --- a/arch/arm/mach-at91/cpuidle.c +++ b/arch/arm/mach-at91/cpuidle.c @@ -39,20 +39,15 @@ static int at91_enter_idle(struct cpuidle_device *dev, { struct timeval before, after; int idle_time; - u32 saved_lpr; local_irq_disable(); do_gettimeofday(&before); if (index == 0) /* Wait for interrupt state */ cpu_do_idle(); - else if (index == 1) { - asm("b 1f; .align 5; 1:"); - asm("mcr p15, 0, r0, c7, c10, 4"); /* drain write buffer */ - saved_lpr = sdram_selfrefresh_enable(); - cpu_do_idle(); - sdram_selfrefresh_disable(saved_lpr); - } + else if (index == 1) + at91_standby(); + do_gettimeofday(&after); local_irq_enable(); idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h index 5941334..459f01a 100644 --- a/arch/arm/mach-at91/generic.h +++ b/arch/arm/mach-at91/generic.h @@ -9,6 +9,7 @@ */ #include <linux/clkdev.h> +#include <linux/of.h> /* Map io */ extern void __init at91_map_io(void); @@ -25,9 +26,13 @@ extern void __init at91_init_irq_default(void); extern void __init at91_init_interrupts(unsigned int priority[]); extern void __init at91x40_init_interrupts(unsigned int priority[]); extern void __init at91_aic_init(unsigned int priority[]); +extern int __init at91_aic_of_init(struct device_node *node, + struct device_node *parent); + /* Timer */ struct sys_timer; +extern void at91rm9200_ioremap_st(u32 addr); extern struct sys_timer at91rm9200_timer; extern void at91sam926x_ioremap_pit(u32 addr); extern struct sys_timer at91sam926x_timer; @@ -45,7 +50,6 @@ extern void __init at91sam9261_set_console_clock(int id); extern void __init at91sam9263_set_console_clock(int id); extern void __init at91sam9rl_set_console_clock(int id); extern void __init at91sam9g45_set_console_clock(int id); -extern void __init at91cap9_set_console_clock(int id); #ifdef CONFIG_AT91_PMC_UNIT extern int __init at91_clock_init(unsigned long main_clock); #else @@ -57,6 +61,9 @@ struct device; extern void at91_irq_suspend(void); extern void at91_irq_resume(void); +/* idle */ +extern void at91sam9_idle(void); + /* reset */ extern void at91_ioremap_rstc(u32 base_addr); extern void at91sam9_alt_restart(char, const char *); @@ -65,6 +72,12 @@ extern void at91sam9g45_restart(char, const char *); /* shutdown */ extern void at91_ioremap_shdwc(u32 base_addr); +/* Matrix */ +extern void at91_ioremap_matrix(u32 base_addr); + +/* Ram Controler */ +extern void at91_ioremap_ramc(int id, u32 addr, u32 size); + /* GPIO */ #define AT91RM9200_PQFP 3 /* AT91RM9200 PQFP package has 3 banks */ #define AT91RM9200_BGA 4 /* AT91RM9200 BGA package has 4 banks */ @@ -75,5 +88,7 @@ struct at91_gpio_bank { }; extern void __init at91_gpio_init(struct at91_gpio_bank *, int nr_banks); extern void __init at91_gpio_irq_setup(void); +extern int __init at91_gpio_of_irq_setup(struct device_node *node, + struct device_node *parent); extern int at91_extern_irq; diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c index 74d6783..325837a 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c @@ -11,6 +11,7 @@ #include <linux/clk.h> #include <linux/errno.h> +#include <linux/device.h> #include <linux/gpio.h> #include <linux/interrupt.h> #include <linux/irq.h> @@ -20,6 +21,10 @@ #include <linux/list.h> #include <linux/module.h> #include <linux/io.h> +#include <linux/irqdomain.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> +#include <linux/of_gpio.h> #include <mach/hardware.h> #include <mach/at91_pio.h> @@ -29,9 +34,12 @@ struct at91_gpio_chip { struct gpio_chip chip; struct at91_gpio_chip *next; /* Bank sharing same clock */ - int id; /* ID of register bank */ - void __iomem *regbase; /* Base of register bank */ + int pioc_hwirq; /* PIO bank interrupt identifier on AIC */ + int pioc_virq; /* PIO bank Linux virtual interrupt */ + int pioc_idx; /* PIO bank index */ + void __iomem *regbase; /* PIO bank virtual address */ struct clk *clock; /* associated clock */ + struct irq_domain *domain; /* associated irq domain */ }; #define to_at91_gpio_chip(c) container_of(c, struct at91_gpio_chip, chip) @@ -43,8 +51,9 @@ static int at91_gpiolib_direction_output(struct gpio_chip *chip, unsigned offset, int val); static int at91_gpiolib_direction_input(struct gpio_chip *chip, unsigned offset); +static int at91_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset); -#define AT91_GPIO_CHIP(name, base_gpio, nr_gpio) \ +#define AT91_GPIO_CHIP(name, nr_gpio) \ { \ .chip = { \ .label = name, \ @@ -53,20 +62,28 @@ static int at91_gpiolib_direction_input(struct gpio_chip *chip, .get = at91_gpiolib_get, \ .set = at91_gpiolib_set, \ .dbg_show = at91_gpiolib_dbg_show, \ - .base = base_gpio, \ + .to_irq = at91_gpiolib_to_irq, \ .ngpio = nr_gpio, \ }, \ } static struct at91_gpio_chip gpio_chip[] = { - AT91_GPIO_CHIP("pioA", 0x00, 32), - AT91_GPIO_CHIP("pioB", 0x20, 32), - AT91_GPIO_CHIP("pioC", 0x40, 32), - AT91_GPIO_CHIP("pioD", 0x60, 32), - AT91_GPIO_CHIP("pioE", 0x80, 32), + AT91_GPIO_CHIP("pioA", 32), + AT91_GPIO_CHIP("pioB", 32), + AT91_GPIO_CHIP("pioC", 32), + AT91_GPIO_CHIP("pioD", 32), + AT91_GPIO_CHIP("pioE", 32), }; static int gpio_banks; +static unsigned long at91_gpio_caps; + +/* All PIO controllers support PIO3 features */ +#define AT91_GPIO_CAP_PIO3 (1 << 0) + +#define has_pio3() (at91_gpio_caps & AT91_GPIO_CAP_PIO3) + +/*--------------------------------------------------------------------------*/ static inline void __iomem *pin_to_controller(unsigned pin) { @@ -83,6 +100,25 @@ static inline unsigned pin_to_mask(unsigned pin) } +static char peripheral_function(void __iomem *pio, unsigned mask) +{ + char ret = 'X'; + u8 select; + + if (pio) { + if (has_pio3()) { + select = !!(__raw_readl(pio + PIO_ABCDSR1) & mask); + select |= (!!(__raw_readl(pio + PIO_ABCDSR2) & mask) << 1); + ret = 'A' + select; + } else { + ret = __raw_readl(pio + PIO_ABSR) & mask ? + 'B' : 'A'; + } + } + + return ret; +} + /*--------------------------------------------------------------------------*/ /* Not all hardware capabilities are exposed through these calls; they @@ -130,7 +166,14 @@ int __init_or_module at91_set_A_periph(unsigned pin, int use_pullup) __raw_writel(mask, pio + PIO_IDR); __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); - __raw_writel(mask, pio + PIO_ASR); + if (has_pio3()) { + __raw_writel(__raw_readl(pio + PIO_ABCDSR1) & ~mask, + pio + PIO_ABCDSR1); + __raw_writel(__raw_readl(pio + PIO_ABCDSR2) & ~mask, + pio + PIO_ABCDSR2); + } else { + __raw_writel(mask, pio + PIO_ASR); + } __raw_writel(mask, pio + PIO_PDR); return 0; } @@ -150,7 +193,14 @@ int __init_or_module at91_set_B_periph(unsigned pin, int use_pullup) __raw_writel(mask, pio + PIO_IDR); __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); - __raw_writel(mask, pio + PIO_BSR); + if (has_pio3()) { + __raw_writel(__raw_readl(pio + PIO_ABCDSR1) | mask, + pio + PIO_ABCDSR1); + __raw_writel(__raw_readl(pio + PIO_ABCDSR2) & ~mask, + pio + PIO_ABCDSR2); + } else { + __raw_writel(mask, pio + PIO_BSR); + } __raw_writel(mask, pio + PIO_PDR); return 0; } @@ -158,8 +208,50 @@ EXPORT_SYMBOL(at91_set_B_periph); /* - * mux the pin to the gpio controller (instead of "A" or "B" peripheral), and - * configure it for an input. + * mux the pin to the "C" internal peripheral role. + */ +int __init_or_module at91_set_C_periph(unsigned pin, int use_pullup) +{ + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); + + if (!pio || !has_pio3()) + return -EINVAL; + + __raw_writel(mask, pio + PIO_IDR); + __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); + __raw_writel(__raw_readl(pio + PIO_ABCDSR1) & ~mask, pio + PIO_ABCDSR1); + __raw_writel(__raw_readl(pio + PIO_ABCDSR2) | mask, pio + PIO_ABCDSR2); + __raw_writel(mask, pio + PIO_PDR); + return 0; +} +EXPORT_SYMBOL(at91_set_C_periph); + + +/* + * mux the pin to the "D" internal peripheral role. + */ +int __init_or_module at91_set_D_periph(unsigned pin, int use_pullup) +{ + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); + + if (!pio || !has_pio3()) + return -EINVAL; + + __raw_writel(mask, pio + PIO_IDR); + __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); + __raw_writel(__raw_readl(pio + PIO_ABCDSR1) | mask, pio + PIO_ABCDSR1); + __raw_writel(__raw_readl(pio + PIO_ABCDSR2) | mask, pio + PIO_ABCDSR2); + __raw_writel(mask, pio + PIO_PDR); + return 0; +} +EXPORT_SYMBOL(at91_set_D_periph); + + +/* + * mux the pin to the gpio controller (instead of "A", "B", "C" + * or "D" peripheral), and configure it for an input. */ int __init_or_module at91_set_gpio_input(unsigned pin, int use_pullup) { @@ -179,8 +271,8 @@ EXPORT_SYMBOL(at91_set_gpio_input); /* - * mux the pin to the gpio controller (instead of "A" or "B" peripheral), - * and configure it for an output. + * mux the pin to the gpio controller (instead of "A", "B", "C" + * or "D" peripheral), and configure it for an output. */ int __init_or_module at91_set_gpio_output(unsigned pin, int value) { @@ -210,12 +302,37 @@ int __init_or_module at91_set_deglitch(unsigned pin, int is_on) if (!pio) return -EINVAL; + + if (has_pio3() && is_on) + __raw_writel(mask, pio + PIO_IFSCDR); __raw_writel(mask, pio + (is_on ? PIO_IFER : PIO_IFDR)); return 0; } EXPORT_SYMBOL(at91_set_deglitch); /* + * enable/disable the debounce filter; + */ +int __init_or_module at91_set_debounce(unsigned pin, int is_on, int div) +{ + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); + + if (!pio || !has_pio3()) + return -EINVAL; + + if (is_on) { + __raw_writel(mask, pio + PIO_IFSCER); + __raw_writel(div & PIO_SCDR_DIV, pio + PIO_SCDR); + __raw_writel(mask, pio + PIO_IFER); + } else { + __raw_writel(mask, pio + PIO_IFDR); + } + return 0; +} +EXPORT_SYMBOL(at91_set_debounce); + +/* * enable/disable the multi-driver; This is only valid for output and * allows the output pin to run as an open collector output. */ @@ -233,6 +350,41 @@ int __init_or_module at91_set_multi_drive(unsigned pin, int is_on) EXPORT_SYMBOL(at91_set_multi_drive); /* + * enable/disable the pull-down. + * If pull-up already enabled while calling the function, we disable it. + */ +int __init_or_module at91_set_pulldown(unsigned pin, int is_on) +{ + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); + + if (!pio || !has_pio3()) + return -EINVAL; + + /* Disable pull-up anyway */ + __raw_writel(mask, pio + PIO_PUDR); + __raw_writel(mask, pio + (is_on ? PIO_PPDER : PIO_PPDDR)); + return 0; +} +EXPORT_SYMBOL(at91_set_pulldown); + +/* + * disable Schmitt trigger + */ +int __init_or_module at91_disable_schmitt_trig(unsigned pin) +{ + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); + + if (!pio || !has_pio3()) + return -EINVAL; + + __raw_writel(__raw_readl(pio + PIO_SCHMITT) | mask, pio + PIO_SCHMITT); + return 0; +} +EXPORT_SYMBOL(at91_disable_schmitt_trig); + +/* * assuming the pin is muxed as a gpio output, set its value. */ int at91_set_gpio_value(unsigned pin, int value) @@ -273,9 +425,9 @@ static u32 backups[MAX_GPIO_BANKS]; static int gpio_irq_set_wake(struct irq_data *d, unsigned state) { - unsigned pin = irq_to_gpio(d->irq); - unsigned mask = pin_to_mask(pin); - unsigned bank = pin / 32; + struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); + unsigned mask = 1 << d->hwirq; + unsigned bank = at91_gpio->pioc_idx; if (unlikely(bank >= MAX_GPIO_BANKS)) return -EINVAL; @@ -285,7 +437,7 @@ static int gpio_irq_set_wake(struct irq_data *d, unsigned state) else wakeups[bank] &= ~mask; - irq_set_irq_wake(gpio_chip[bank].id, state); + irq_set_irq_wake(at91_gpio->pioc_virq, state); return 0; } @@ -301,9 +453,10 @@ void at91_gpio_suspend(void) __raw_writel(backups[i], pio + PIO_IDR); __raw_writel(wakeups[i], pio + PIO_IER); - if (!wakeups[i]) + if (!wakeups[i]) { + clk_unprepare(gpio_chip[i].clock); clk_disable(gpio_chip[i].clock); - else { + } else { #ifdef CONFIG_PM_DEBUG printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", 'A'+i, wakeups[i]); #endif @@ -318,8 +471,10 @@ void at91_gpio_resume(void) for (i = 0; i < gpio_banks; i++) { void __iomem *pio = gpio_chip[i].regbase; - if (!wakeups[i]) - clk_enable(gpio_chip[i].clock); + if (!wakeups[i]) { + if (clk_prepare(gpio_chip[i].clock) == 0) + clk_enable(gpio_chip[i].clock); + } __raw_writel(wakeups[i], pio + PIO_IDR); __raw_writel(backups[i], pio + PIO_IER); @@ -335,7 +490,10 @@ void at91_gpio_resume(void) * To use any AT91_PIN_* as an externally triggered IRQ, first call * at91_set_gpio_input() then maybe enable its glitch filter. * Then just request_irq() with the pin ID; it works like any ARM IRQ - * handler, though it always triggers on rising and falling edges. + * handler. + * First implementation always triggers on rising and falling edges + * whereas the newer PIO3 can be additionally configured to trigger on + * level, edge with any polarity. * * Alternatively, certain pins may be used directly as IRQ0..IRQ6 after * configuring them with at91_set_a_periph() or at91_set_b_periph(). @@ -344,9 +502,9 @@ void at91_gpio_resume(void) static void gpio_irq_mask(struct irq_data *d) { - unsigned pin = irq_to_gpio(d->irq); - void __iomem *pio = pin_to_controller(pin); - unsigned mask = pin_to_mask(pin); + struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); + void __iomem *pio = at91_gpio->regbase; + unsigned mask = 1 << d->hwirq; if (pio) __raw_writel(mask, pio + PIO_IDR); @@ -354,9 +512,9 @@ static void gpio_irq_mask(struct irq_data *d) static void gpio_irq_unmask(struct irq_data *d) { - unsigned pin = irq_to_gpio(d->irq); - void __iomem *pio = pin_to_controller(pin); - unsigned mask = pin_to_mask(pin); + struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); + void __iomem *pio = at91_gpio->regbase; + unsigned mask = 1 << d->hwirq; if (pio) __raw_writel(mask, pio + PIO_IER); @@ -373,23 +531,66 @@ static int gpio_irq_type(struct irq_data *d, unsigned type) } } +/* Alternate irq type for PIO3 support */ +static int alt_gpio_irq_type(struct irq_data *d, unsigned type) +{ + struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); + void __iomem *pio = at91_gpio->regbase; + unsigned mask = 1 << d->hwirq; + + switch (type) { + case IRQ_TYPE_EDGE_RISING: + __raw_writel(mask, pio + PIO_ESR); + __raw_writel(mask, pio + PIO_REHLSR); + break; + case IRQ_TYPE_EDGE_FALLING: + __raw_writel(mask, pio + PIO_ESR); + __raw_writel(mask, pio + PIO_FELLSR); + break; + case IRQ_TYPE_LEVEL_LOW: + __raw_writel(mask, pio + PIO_LSR); + __raw_writel(mask, pio + PIO_FELLSR); + break; + case IRQ_TYPE_LEVEL_HIGH: + __raw_writel(mask, pio + PIO_LSR); + __raw_writel(mask, pio + PIO_REHLSR); + break; + case IRQ_TYPE_EDGE_BOTH: + /* + * disable additional interrupt modes: + * fall back to default behavior + */ + __raw_writel(mask, pio + PIO_AIMDR); + return 0; + case IRQ_TYPE_NONE: + default: + pr_warn("AT91: No type for irq %d\n", gpio_to_irq(d->irq)); + return -EINVAL; + } + + /* enable additional interrupt modes */ + __raw_writel(mask, pio + PIO_AIMER); + + return 0; +} + static struct irq_chip gpio_irqchip = { .name = "GPIO", .irq_disable = gpio_irq_mask, .irq_mask = gpio_irq_mask, .irq_unmask = gpio_irq_unmask, - .irq_set_type = gpio_irq_type, + /* .irq_set_type is set dynamically */ .irq_set_wake = gpio_irq_set_wake, }; static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) { - unsigned irq_pin; struct irq_data *idata = irq_desc_get_irq_data(desc); struct irq_chip *chip = irq_data_get_irq_chip(idata); struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(idata); void __iomem *pio = at91_gpio->regbase; - u32 isr; + unsigned long isr; + int n; /* temporarily mask (level sensitive) parent IRQ */ chip->irq_ack(idata); @@ -407,13 +608,10 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) continue; } - irq_pin = gpio_to_irq(at91_gpio->chip.base); - - while (isr) { - if (isr & 1) - generic_handle_irq(irq_pin); - irq_pin++; - isr >>= 1; + n = find_first_bit(&isr, BITS_PER_LONG); + while (n < BITS_PER_LONG) { + generic_handle_irq(irq_find_mapping(at91_gpio->domain, n)); + n = find_next_bit(&isr, BITS_PER_LONG, n + 1); } } chip->irq_unmask(idata); @@ -424,6 +622,33 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) #ifdef CONFIG_DEBUG_FS +static void gpio_printf(struct seq_file *s, void __iomem *pio, unsigned mask) +{ + char *trigger = NULL; + char *polarity = NULL; + + if (__raw_readl(pio + PIO_IMR) & mask) { + if (!has_pio3() || !(__raw_readl(pio + PIO_AIMMR) & mask )) { + trigger = "edge"; + polarity = "both"; + } else { + if (__raw_readl(pio + PIO_ELSR) & mask) { + trigger = "level"; + polarity = __raw_readl(pio + PIO_FRLHSR) & mask ? + "high" : "low"; + } else { + trigger = "edge"; + polarity = __raw_readl(pio + PIO_FRLHSR) & mask ? + "rising" : "falling"; + } + } + seq_printf(s, "IRQ:%s-%s\t", trigger, polarity); + } else { + seq_printf(s, "GPIO:%s\t\t", + __raw_readl(pio + PIO_PDSR) & mask ? "1" : "0"); + } +} + static int at91_gpio_show(struct seq_file *s, void *unused) { int bank, j; @@ -431,7 +656,7 @@ static int at91_gpio_show(struct seq_file *s, void *unused) /* print heading */ seq_printf(s, "Pin\t"); for (bank = 0; bank < gpio_banks; bank++) { - seq_printf(s, "PIO%c\t", 'A' + bank); + seq_printf(s, "PIO%c\t\t", 'A' + bank); }; seq_printf(s, "\n\n"); @@ -445,11 +670,10 @@ static int at91_gpio_show(struct seq_file *s, void *unused) unsigned mask = pin_to_mask(pin); if (__raw_readl(pio + PIO_PSR) & mask) - seq_printf(s, "GPIO:%s", __raw_readl(pio + PIO_PDSR) & mask ? "1" : "0"); + gpio_printf(s, pio, mask); else - seq_printf(s, "%s", __raw_readl(pio + PIO_ABSR) & mask ? "B" : "A"); - - seq_printf(s, "\t"); + seq_printf(s, "%c\t\t", + peripheral_function(pio, mask)); } seq_printf(s, "\n"); @@ -488,46 +712,152 @@ postcore_initcall(at91_gpio_debugfs_init); */ static struct lock_class_key gpio_lock_class; +#if defined(CONFIG_OF) +static int at91_gpio_irq_map(struct irq_domain *h, unsigned int virq, + irq_hw_number_t hw) +{ + struct at91_gpio_chip *at91_gpio = h->host_data; + + irq_set_lockdep_class(virq, &gpio_lock_class); + + /* + * Can use the "simple" and not "edge" handler since it's + * shorter, and the AIC handles interrupts sanely. + */ + irq_set_chip_and_handler(virq, &gpio_irqchip, + handle_simple_irq); + set_irq_flags(virq, IRQF_VALID); + irq_set_chip_data(virq, at91_gpio); + + return 0; +} + +static struct irq_domain_ops at91_gpio_ops = { + .map = at91_gpio_irq_map, + .xlate = irq_domain_xlate_twocell, +}; + +int __init at91_gpio_of_irq_setup(struct device_node *node, + struct device_node *parent) +{ + struct at91_gpio_chip *prev = NULL; + int alias_idx = of_alias_get_id(node, "gpio"); + struct at91_gpio_chip *at91_gpio = &gpio_chip[alias_idx]; + + /* Setup proper .irq_set_type function */ + if (has_pio3()) + gpio_irqchip.irq_set_type = alt_gpio_irq_type; + else + gpio_irqchip.irq_set_type = gpio_irq_type; + + /* Disable irqs of this PIO controller */ + __raw_writel(~0, at91_gpio->regbase + PIO_IDR); + + /* Setup irq domain */ + at91_gpio->domain = irq_domain_add_linear(node, at91_gpio->chip.ngpio, + &at91_gpio_ops, at91_gpio); + if (!at91_gpio->domain) + panic("at91_gpio.%d: couldn't allocate irq domain (DT).\n", + at91_gpio->pioc_idx); + + /* Setup chained handler */ + if (at91_gpio->pioc_idx) + prev = &gpio_chip[at91_gpio->pioc_idx - 1]; + + /* The toplevel handler handles one bank of GPIOs, except + * on some SoC it can handles up to three... + * We only set up the handler for the first of the list. + */ + if (prev && prev->next == at91_gpio) + return 0; + + at91_gpio->pioc_virq = irq_create_mapping(irq_find_host(parent), + at91_gpio->pioc_hwirq); + irq_set_chip_data(at91_gpio->pioc_virq, at91_gpio); + irq_set_chained_handler(at91_gpio->pioc_virq, gpio_irq_handler); + + return 0; +} +#else +int __init at91_gpio_of_irq_setup(struct device_node *node, + struct device_node *parent) +{ + return -EINVAL; +} +#endif + +/* + * irqdomain initialization: pile up irqdomains on top of AIC range + */ +static void __init at91_gpio_irqdomain(struct at91_gpio_chip *at91_gpio) +{ + int irq_base; + + irq_base = irq_alloc_descs(-1, 0, at91_gpio->chip.ngpio, 0); + if (irq_base < 0) + panic("at91_gpio.%d: error %d: couldn't allocate IRQ numbers.\n", + at91_gpio->pioc_idx, irq_base); + at91_gpio->domain = irq_domain_add_legacy(NULL, at91_gpio->chip.ngpio, + irq_base, 0, + &irq_domain_simple_ops, NULL); + if (!at91_gpio->domain) + panic("at91_gpio.%d: couldn't allocate irq domain.\n", + at91_gpio->pioc_idx); +} + /* * Called from the processor-specific init to enable GPIO interrupt support. */ void __init at91_gpio_irq_setup(void) { - unsigned pioc, irq = gpio_to_irq(0); + unsigned pioc; + int gpio_irqnbr = 0; struct at91_gpio_chip *this, *prev; + /* Setup proper .irq_set_type function */ + if (has_pio3()) + gpio_irqchip.irq_set_type = alt_gpio_irq_type; + else + gpio_irqchip.irq_set_type = gpio_irq_type; + for (pioc = 0, this = gpio_chip, prev = NULL; pioc++ < gpio_banks; prev = this, this++) { - unsigned id = this->id; - unsigned i; + int offset; __raw_writel(~0, this->regbase + PIO_IDR); - for (i = 0, irq = gpio_to_irq(this->chip.base); i < 32; - i++, irq++) { - irq_set_lockdep_class(irq, &gpio_lock_class); + /* setup irq domain for this GPIO controller */ + at91_gpio_irqdomain(this); + + for (offset = 0; offset < this->chip.ngpio; offset++) { + unsigned int virq = irq_find_mapping(this->domain, offset); + irq_set_lockdep_class(virq, &gpio_lock_class); /* * Can use the "simple" and not "edge" handler since it's * shorter, and the AIC handles interrupts sanely. */ - irq_set_chip_and_handler(irq, &gpio_irqchip, + irq_set_chip_and_handler(virq, &gpio_irqchip, handle_simple_irq); - set_irq_flags(irq, IRQF_VALID); + set_irq_flags(virq, IRQF_VALID); + irq_set_chip_data(virq, this); + + gpio_irqnbr++; } /* The toplevel handler handles one bank of GPIOs, except - * AT91SAM9263_ID_PIOCDE handles three... PIOC is first in - * the list, so we only set up that handler. + * on some SoC it can handles up to three... + * We only set up the handler for the first of the list. */ if (prev && prev->next == this) continue; - irq_set_chip_data(id, this); - irq_set_chained_handler(id, gpio_irq_handler); + this->pioc_virq = irq_create_mapping(NULL, this->pioc_hwirq); + irq_set_chip_data(this->pioc_virq, this); + irq_set_chained_handler(this->pioc_virq, gpio_irq_handler); } - pr_info("AT91: %d gpio irqs in %d banks\n", irq - gpio_to_irq(0), gpio_banks); + pr_info("AT91: %d gpio irqs in %d banks\n", gpio_irqnbr, gpio_banks); } /* gpiolib support */ @@ -593,48 +923,175 @@ static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) at91_get_gpio_value(pin) ? "set" : "clear"); else - seq_printf(s, "[periph %s]\n", - __raw_readl(pio + PIO_ABSR) & - mask ? "B" : "A"); + seq_printf(s, "[periph %c]\n", + peripheral_function(pio, mask)); } } } +static int at91_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset) +{ + struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); + int virq; + + if (offset < chip->ngpio) + virq = irq_create_mapping(at91_gpio->domain, offset); + else + virq = -ENXIO; + + dev_dbg(chip->dev, "%s: request IRQ for GPIO %d, return %d\n", + chip->label, offset + chip->base, virq); + return virq; +} + +static int __init at91_gpio_setup_clk(int idx) +{ + struct at91_gpio_chip *at91_gpio = &gpio_chip[idx]; + + /* retreive PIO controller's clock */ + at91_gpio->clock = clk_get_sys(NULL, at91_gpio->chip.label); + if (IS_ERR(at91_gpio->clock)) { + pr_err("at91_gpio.%d, failed to get clock, ignoring.\n", idx); + goto err; + } + + if (clk_prepare(at91_gpio->clock)) + goto clk_prep_err; + + /* enable PIO controller's clock */ + if (clk_enable(at91_gpio->clock)) { + pr_err("at91_gpio.%d, failed to enable clock, ignoring.\n", idx); + goto clk_err; + } + + return 0; + +clk_err: + clk_unprepare(at91_gpio->clock); +clk_prep_err: + clk_put(at91_gpio->clock); +err: + return -EINVAL; +} + +#ifdef CONFIG_OF_GPIO +static void __init of_at91_gpio_init_one(struct device_node *np) +{ + int alias_idx; + struct at91_gpio_chip *at91_gpio; + + if (!np) + return; + + alias_idx = of_alias_get_id(np, "gpio"); + if (alias_idx >= MAX_GPIO_BANKS) { + pr_err("at91_gpio, failed alias idx(%d) > MAX_GPIO_BANKS(%d), ignoring.\n", + alias_idx, MAX_GPIO_BANKS); + return; + } + + at91_gpio = &gpio_chip[alias_idx]; + at91_gpio->chip.base = alias_idx * at91_gpio->chip.ngpio; + + at91_gpio->regbase = of_iomap(np, 0); + if (!at91_gpio->regbase) { + pr_err("at91_gpio.%d, failed to map registers, ignoring.\n", + alias_idx); + return; + } + + /* Get the interrupts property */ + if (of_property_read_u32(np, "interrupts", &at91_gpio->pioc_hwirq)) { + pr_err("at91_gpio.%d, failed to get interrupts property, ignoring.\n", + alias_idx); + goto ioremap_err; + } + + /* Get capabilities from compatibility property */ + if (of_device_is_compatible(np, "atmel,at91sam9x5-gpio")) + at91_gpio_caps |= AT91_GPIO_CAP_PIO3; + + /* Setup clock */ + if (at91_gpio_setup_clk(alias_idx)) + goto ioremap_err; + + at91_gpio->chip.of_node = np; + gpio_banks = max(gpio_banks, alias_idx + 1); + at91_gpio->pioc_idx = alias_idx; + return; + +ioremap_err: + iounmap(at91_gpio->regbase); +} + +static int __init of_at91_gpio_init(void) +{ + struct device_node *np = NULL; + + /* + * This isn't ideal, but it gets things hooked up until this + * driver is converted into a platform_device + */ + for_each_compatible_node(np, NULL, "atmel,at91rm9200-gpio") + of_at91_gpio_init_one(np); + + return gpio_banks > 0 ? 0 : -EINVAL; +} +#else +static int __init of_at91_gpio_init(void) +{ + return -EINVAL; +} +#endif + +static void __init at91_gpio_init_one(int idx, u32 regbase, int pioc_hwirq) +{ + struct at91_gpio_chip *at91_gpio = &gpio_chip[idx]; + + at91_gpio->chip.base = idx * at91_gpio->chip.ngpio; + at91_gpio->pioc_hwirq = pioc_hwirq; + at91_gpio->pioc_idx = idx; + + at91_gpio->regbase = ioremap(regbase, 512); + if (!at91_gpio->regbase) { + pr_err("at91_gpio.%d, failed to map registers, ignoring.\n", idx); + return; + } + + if (at91_gpio_setup_clk(idx)) + goto ioremap_err; + + gpio_banks = max(gpio_banks, idx + 1); + return; + +ioremap_err: + iounmap(at91_gpio->regbase); +} + /* * Called from the processor-specific init to enable GPIO pin support. */ void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) { - unsigned i; + unsigned i; struct at91_gpio_chip *at91_gpio, *last = NULL; BUG_ON(nr_banks > MAX_GPIO_BANKS); - gpio_banks = nr_banks; + if (of_at91_gpio_init() < 0) { + /* No GPIO controller found in device tree */ + for (i = 0; i < nr_banks; i++) + at91_gpio_init_one(i, data[i].regbase, data[i].id); + } - for (i = 0; i < nr_banks; i++) { + for (i = 0; i < gpio_banks; i++) { at91_gpio = &gpio_chip[i]; - at91_gpio->id = data[i].id; - at91_gpio->chip.base = i * 32; - - at91_gpio->regbase = ioremap(data[i].regbase, 512); - if (!at91_gpio->regbase) { - pr_err("at91_gpio.%d, failed to map registers, ignoring.\n", i); - continue; - } - - at91_gpio->clock = clk_get_sys(NULL, at91_gpio->chip.label); - if (!at91_gpio->clock) { - pr_err("at91_gpio.%d, failed to get clock, ignoring.\n", i); - continue; - } - - /* enable PIO controller's clock */ - clk_enable(at91_gpio->clock); - - /* AT91SAM9263_ID_PIOCDE groups PIOC, PIOD, PIOE */ - if (last && last->id == at91_gpio->id) + /* + * GPIO controller are grouped on some SoC: + * PIOC, PIOD and PIOE can share the same IRQ line + */ + if (last && last->pioc_hwirq == at91_gpio->pioc_hwirq) last->next = at91_gpio; last = at91_gpio; diff --git a/arch/arm/mach-at91/include/mach/at91_matrix.h b/arch/arm/mach-at91/include/mach/at91_matrix.h new file mode 100644 index 0000000..02fae9d --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_matrix.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * Under GPLv2 + */ + +#ifndef __MACH_AT91_MATRIX_H__ +#define __MACH_AT91_MATRIX_H__ + +#ifndef __ASSEMBLY__ +extern void __iomem *at91_matrix_base; + +#define at91_matrix_read(field) \ + __raw_readl(at91_matrix_base + field) + +#define at91_matrix_write(field, value) \ + __raw_writel(value, at91_matrix_base + field); + +#else +.extern at91_matrix_base +#endif + +#endif /* __MACH_AT91_MATRIX_H__ */ diff --git a/arch/arm/mach-at91/include/mach/at91_pio.h b/arch/arm/mach-at91/include/mach/at91_pio.h index c6a31bf..732b11c 100644 --- a/arch/arm/mach-at91/include/mach/at91_pio.h +++ b/arch/arm/mach-at91/include/mach/at91_pio.h @@ -40,10 +40,35 @@ #define PIO_PUER 0x64 /* Pull-up Enable Register */ #define PIO_PUSR 0x68 /* Pull-up Status Register */ #define PIO_ASR 0x70 /* Peripheral A Select Register */ +#define PIO_ABCDSR1 0x70 /* Peripheral ABCD Select Register 1 [some sam9 only] */ #define PIO_BSR 0x74 /* Peripheral B Select Register */ +#define PIO_ABCDSR2 0x74 /* Peripheral ABCD Select Register 2 [some sam9 only] */ #define PIO_ABSR 0x78 /* AB Status Register */ +#define PIO_IFSCDR 0x80 /* Input Filter Slow Clock Disable Register */ +#define PIO_IFSCER 0x84 /* Input Filter Slow Clock Enable Register */ +#define PIO_IFSCSR 0x88 /* Input Filter Slow Clock Status Register */ +#define PIO_SCDR 0x8c /* Slow Clock Divider Debouncing Register */ +#define PIO_SCDR_DIV (0x3fff << 0) /* Slow Clock Divider Mask */ +#define PIO_PPDDR 0x90 /* Pad Pull-down Disable Register */ +#define PIO_PPDER 0x94 /* Pad Pull-down Enable Register */ +#define PIO_PPDSR 0x98 /* Pad Pull-down Status Register */ #define PIO_OWER 0xa0 /* Output Write Enable Register */ #define PIO_OWDR 0xa4 /* Output Write Disable Register */ #define PIO_OWSR 0xa8 /* Output Write Status Register */ +#define PIO_AIMER 0xb0 /* Additional Interrupt Modes Enable Register */ +#define PIO_AIMDR 0xb4 /* Additional Interrupt Modes Disable Register */ +#define PIO_AIMMR 0xb8 /* Additional Interrupt Modes Mask Register */ +#define PIO_ESR 0xc0 /* Edge Select Register */ +#define PIO_LSR 0xc4 /* Level Select Register */ +#define PIO_ELSR 0xc8 /* Edge/Level Status Register */ +#define PIO_FELLSR 0xd0 /* Falling Edge/Low Level Select Register */ +#define PIO_REHLSR 0xd4 /* Rising Edge/ High Level Select Register */ +#define PIO_FRLHSR 0xd8 /* Fall/Rise - Low/High Status Register */ +#define PIO_SCHMITT 0x100 /* Schmitt Trigger Register */ + +#define ABCDSR_PERIPH_A 0x0 +#define ABCDSR_PERIPH_B 0x1 +#define ABCDSR_PERIPH_C 0x2 +#define ABCDSR_PERIPH_D 0x3 #endif diff --git a/arch/arm/mach-at91/include/mach/at91_pmc.h b/arch/arm/mach-at91/include/mach/at91_pmc.h index e46f93e..3660478 100644 --- a/arch/arm/mach-at91/include/mach/at91_pmc.h +++ b/arch/arm/mach-at91/include/mach/at91_pmc.h @@ -16,17 +16,27 @@ #ifndef AT91_PMC_H #define AT91_PMC_H -#define AT91_PMC_SCER (AT91_PMC + 0x00) /* System Clock Enable Register */ -#define AT91_PMC_SCDR (AT91_PMC + 0x04) /* System Clock Disable Register */ +#ifndef __ASSEMBLY__ +extern void __iomem *at91_pmc_base; -#define AT91_PMC_SCSR (AT91_PMC + 0x08) /* System Clock Status Register */ +#define at91_pmc_read(field) \ + __raw_readl(at91_pmc_base + field) + +#define at91_pmc_write(field, value) \ + __raw_writel(value, at91_pmc_base + field) +#else +.extern at91_aic_base +#endif + +#define AT91_PMC_SCER 0x00 /* System Clock Enable Register */ +#define AT91_PMC_SCDR 0x04 /* System Clock Disable Register */ + +#define AT91_PMC_SCSR 0x08 /* System Clock Status Register */ #define AT91_PMC_PCK (1 << 0) /* Processor Clock */ #define AT91RM9200_PMC_UDP (1 << 1) /* USB Devcice Port Clock [AT91RM9200 only] */ #define AT91RM9200_PMC_MCKUDP (1 << 2) /* USB Device Port Master Clock Automatic Disable on Suspend [AT91RM9200 only] */ -#define AT91CAP9_PMC_DDR (1 << 2) /* DDR Clock [CAP9 revC & some SAM9 only] */ #define AT91RM9200_PMC_UHP (1 << 4) /* USB Host Port Clock [AT91RM9200 only] */ #define AT91SAM926x_PMC_UHP (1 << 6) /* USB Host Port Clock [AT91SAM926x only] */ -#define AT91CAP9_PMC_UHP (1 << 6) /* USB Host Port Clock [AT91CAP9 only] */ #define AT91SAM926x_PMC_UDP (1 << 7) /* USB Devcice Port Clock [AT91SAM926x only] */ #define AT91_PMC_PCK0 (1 << 8) /* Programmable Clock 0 */ #define AT91_PMC_PCK1 (1 << 9) /* Programmable Clock 1 */ @@ -36,27 +46,31 @@ #define AT91_PMC_HCK0 (1 << 16) /* AHB Clock (USB host) [AT91SAM9261 only] */ #define AT91_PMC_HCK1 (1 << 17) /* AHB Clock (LCD) [AT91SAM9261 only] */ -#define AT91_PMC_PCER (AT91_PMC + 0x10) /* Peripheral Clock Enable Register */ -#define AT91_PMC_PCDR (AT91_PMC + 0x14) /* Peripheral Clock Disable Register */ -#define AT91_PMC_PCSR (AT91_PMC + 0x18) /* Peripheral Clock Status Register */ +#define AT91_PMC_PCER 0x10 /* Peripheral Clock Enable Register */ +#define AT91_PMC_PCDR 0x14 /* Peripheral Clock Disable Register */ +#define AT91_PMC_PCSR 0x18 /* Peripheral Clock Status Register */ -#define AT91_CKGR_UCKR (AT91_PMC + 0x1C) /* UTMI Clock Register [some SAM9, CAP9] */ +#define AT91_CKGR_UCKR 0x1C /* UTMI Clock Register [some SAM9] */ #define AT91_PMC_UPLLEN (1 << 16) /* UTMI PLL Enable */ #define AT91_PMC_UPLLCOUNT (0xf << 20) /* UTMI PLL Start-up Time */ #define AT91_PMC_BIASEN (1 << 24) /* UTMI BIAS Enable */ #define AT91_PMC_BIASCOUNT (0xf << 28) /* UTMI BIAS Start-up Time */ -#define AT91_CKGR_MOR (AT91_PMC + 0x20) /* Main Oscillator Register [not on SAM9RL] */ -#define AT91_PMC_MOSCEN (1 << 0) /* Main Oscillator Enable */ -#define AT91_PMC_OSCBYPASS (1 << 1) /* Oscillator Bypass [SAM9x, CAP9] */ -#define AT91_PMC_OSCOUNT (0xff << 8) /* Main Oscillator Start-up Time */ +#define AT91_CKGR_MOR 0x20 /* Main Oscillator Register [not on SAM9RL] */ +#define AT91_PMC_MOSCEN (1 << 0) /* Main Oscillator Enable */ +#define AT91_PMC_OSCBYPASS (1 << 1) /* Oscillator Bypass */ +#define AT91_PMC_MOSCRCEN (1 << 3) /* Main On-Chip RC Oscillator Enable [some SAM9] */ +#define AT91_PMC_OSCOUNT (0xff << 8) /* Main Oscillator Start-up Time */ +#define AT91_PMC_KEY (0x37 << 16) /* MOR Writing Key */ +#define AT91_PMC_MOSCSEL (1 << 24) /* Main Oscillator Selection [some SAM9] */ +#define AT91_PMC_CFDEN (1 << 25) /* Clock Failure Detector Enable [some SAM9] */ -#define AT91_CKGR_MCFR (AT91_PMC + 0x24) /* Main Clock Frequency Register */ +#define AT91_CKGR_MCFR 0x24 /* Main Clock Frequency Register */ #define AT91_PMC_MAINF (0xffff << 0) /* Main Clock Frequency */ #define AT91_PMC_MAINRDY (1 << 16) /* Main Clock Ready */ -#define AT91_CKGR_PLLAR (AT91_PMC + 0x28) /* PLL A Register */ -#define AT91_CKGR_PLLBR (AT91_PMC + 0x2c) /* PLL B Register */ +#define AT91_CKGR_PLLAR 0x28 /* PLL A Register */ +#define AT91_CKGR_PLLBR 0x2c /* PLL B Register */ #define AT91_PMC_DIV (0xff << 0) /* Divider */ #define AT91_PMC_PLLCOUNT (0x3f << 8) /* PLL Counter */ #define AT91_PMC_OUT (3 << 14) /* PLL Clock Frequency Range */ @@ -67,27 +81,37 @@ #define AT91_PMC_USBDIV_4 (2 << 28) #define AT91_PMC_USB96M (1 << 28) /* Divider by 2 Enable (PLLB only) */ -#define AT91_PMC_MCKR (AT91_PMC + 0x30) /* Master Clock Register */ +#define AT91_PMC_MCKR 0x30 /* Master Clock Register */ #define AT91_PMC_CSS (3 << 0) /* Master Clock Selection */ #define AT91_PMC_CSS_SLOW (0 << 0) #define AT91_PMC_CSS_MAIN (1 << 0) #define AT91_PMC_CSS_PLLA (2 << 0) #define AT91_PMC_CSS_PLLB (3 << 0) #define AT91_PMC_CSS_UPLL (3 << 0) /* [some SAM9 only] */ -#define AT91_PMC_PRES (7 << 2) /* Master Clock Prescaler */ -#define AT91_PMC_PRES_1 (0 << 2) -#define AT91_PMC_PRES_2 (1 << 2) -#define AT91_PMC_PRES_4 (2 << 2) -#define AT91_PMC_PRES_8 (3 << 2) -#define AT91_PMC_PRES_16 (4 << 2) -#define AT91_PMC_PRES_32 (5 << 2) -#define AT91_PMC_PRES_64 (6 << 2) +#define PMC_PRES_OFFSET 2 +#define AT91_PMC_PRES (7 << PMC_PRES_OFFSET) /* Master Clock Prescaler */ +#define AT91_PMC_PRES_1 (0 << PMC_PRES_OFFSET) +#define AT91_PMC_PRES_2 (1 << PMC_PRES_OFFSET) +#define AT91_PMC_PRES_4 (2 << PMC_PRES_OFFSET) +#define AT91_PMC_PRES_8 (3 << PMC_PRES_OFFSET) +#define AT91_PMC_PRES_16 (4 << PMC_PRES_OFFSET) +#define AT91_PMC_PRES_32 (5 << PMC_PRES_OFFSET) +#define AT91_PMC_PRES_64 (6 << PMC_PRES_OFFSET) +#define PMC_ALT_PRES_OFFSET 4 +#define AT91_PMC_ALT_PRES (7 << PMC_ALT_PRES_OFFSET) /* Master Clock Prescaler [alternate location] */ +#define AT91_PMC_ALT_PRES_1 (0 << PMC_ALT_PRES_OFFSET) +#define AT91_PMC_ALT_PRES_2 (1 << PMC_ALT_PRES_OFFSET) +#define AT91_PMC_ALT_PRES_4 (2 << PMC_ALT_PRES_OFFSET) +#define AT91_PMC_ALT_PRES_8 (3 << PMC_ALT_PRES_OFFSET) +#define AT91_PMC_ALT_PRES_16 (4 << PMC_ALT_PRES_OFFSET) +#define AT91_PMC_ALT_PRES_32 (5 << PMC_ALT_PRES_OFFSET) +#define AT91_PMC_ALT_PRES_64 (6 << PMC_ALT_PRES_OFFSET) #define AT91_PMC_MDIV (3 << 8) /* Master Clock Division */ #define AT91RM9200_PMC_MDIV_1 (0 << 8) /* [AT91RM9200 only] */ #define AT91RM9200_PMC_MDIV_2 (1 << 8) #define AT91RM9200_PMC_MDIV_3 (2 << 8) #define AT91RM9200_PMC_MDIV_4 (3 << 8) -#define AT91SAM9_PMC_MDIV_1 (0 << 8) /* [SAM9,CAP9 only] */ +#define AT91SAM9_PMC_MDIV_1 (0 << 8) /* [SAM9 only] */ #define AT91SAM9_PMC_MDIV_2 (1 << 8) #define AT91SAM9_PMC_MDIV_4 (2 << 8) #define AT91SAM9_PMC_MDIV_6 (3 << 8) /* [some SAM9 only] */ @@ -99,35 +123,55 @@ #define AT91_PMC_PLLADIV2_OFF (0 << 12) #define AT91_PMC_PLLADIV2_ON (1 << 12) -#define AT91_PMC_USB (AT91_PMC + 0x38) /* USB Clock Register [some SAM9 only] */ +#define AT91_PMC_USB 0x38 /* USB Clock Register [some SAM9 only] */ #define AT91_PMC_USBS (0x1 << 0) /* USB OHCI Input clock selection */ #define AT91_PMC_USBS_PLLA (0 << 0) #define AT91_PMC_USBS_UPLL (1 << 0) #define AT91_PMC_OHCIUSBDIV (0xF << 8) /* Divider for USB OHCI Clock */ -#define AT91_PMC_PCKR(n) (AT91_PMC + 0x40 + ((n) * 4)) /* Programmable Clock 0-N Registers */ +#define AT91_PMC_SMD 0x3c /* Soft Modem Clock Register [some SAM9 only] */ +#define AT91_PMC_SMDS (0x1 << 0) /* SMD input clock selection */ +#define AT91_PMC_SMD_DIV (0x1f << 8) /* SMD input clock divider */ +#define AT91_PMC_SMDDIV(n) (((n) << 8) & AT91_PMC_SMD_DIV) + +#define AT91_PMC_PCKR(n) (0x40 + ((n) * 4)) /* Programmable Clock 0-N Registers */ +#define AT91_PMC_ALT_PCKR_CSS (0x7 << 0) /* Programmable Clock Source Selection [alternate length] */ +#define AT91_PMC_CSS_MASTER (4 << 0) /* [some SAM9 only] */ #define AT91_PMC_CSSMCK (0x1 << 8) /* CSS or Master Clock Selection */ #define AT91_PMC_CSSMCK_CSS (0 << 8) #define AT91_PMC_CSSMCK_MCK (1 << 8) -#define AT91_PMC_IER (AT91_PMC + 0x60) /* Interrupt Enable Register */ -#define AT91_PMC_IDR (AT91_PMC + 0x64) /* Interrupt Disable Register */ -#define AT91_PMC_SR (AT91_PMC + 0x68) /* Status Register */ +#define AT91_PMC_IER 0x60 /* Interrupt Enable Register */ +#define AT91_PMC_IDR 0x64 /* Interrupt Disable Register */ +#define AT91_PMC_SR 0x68 /* Status Register */ #define AT91_PMC_MOSCS (1 << 0) /* MOSCS Flag */ #define AT91_PMC_LOCKA (1 << 1) /* PLLA Lock */ #define AT91_PMC_LOCKB (1 << 2) /* PLLB Lock */ #define AT91_PMC_MCKRDY (1 << 3) /* Master Clock */ -#define AT91_PMC_LOCKU (1 << 6) /* UPLL Lock [some SAM9, AT91CAP9 only] */ -#define AT91_PMC_OSCSEL (1 << 7) /* Slow Clock Oscillator [AT91CAP9 revC only] */ +#define AT91_PMC_LOCKU (1 << 6) /* UPLL Lock [some SAM9] */ #define AT91_PMC_PCK0RDY (1 << 8) /* Programmable Clock 0 */ #define AT91_PMC_PCK1RDY (1 << 9) /* Programmable Clock 1 */ #define AT91_PMC_PCK2RDY (1 << 10) /* Programmable Clock 2 */ #define AT91_PMC_PCK3RDY (1 << 11) /* Programmable Clock 3 */ -#define AT91_PMC_IMR (AT91_PMC + 0x6c) /* Interrupt Mask Register */ +#define AT91_PMC_MOSCSELS (1 << 16) /* Main Oscillator Selection [some SAM9] */ +#define AT91_PMC_MOSCRCS (1 << 17) /* Main On-Chip RC [some SAM9] */ +#define AT91_PMC_CFDEV (1 << 18) /* Clock Failure Detector Event [some SAM9] */ +#define AT91_PMC_IMR 0x6c /* Interrupt Mask Register */ + +#define AT91_PMC_PROT 0xe4 /* Write Protect Mode Register [some SAM9] */ +#define AT91_PMC_WPEN (0x1 << 0) /* Write Protect Enable */ +#define AT91_PMC_WPKEY (0xffffff << 8) /* Write Protect Key */ +#define AT91_PMC_PROTKEY (0x504d43 << 8) /* Activation Code */ -#define AT91_PMC_PROT (AT91_PMC + 0xe4) /* Protect Register [AT91CAP9 revC only] */ -#define AT91_PMC_PROTKEY 0x504d4301 /* Activation Code */ +#define AT91_PMC_WPSR 0xe8 /* Write Protect Status Register [some SAM9] */ +#define AT91_PMC_WPVS (0x1 << 0) /* Write Protect Violation Status */ +#define AT91_PMC_WPVSRC (0xffff << 8) /* Write Protect Violation Source */ -#define AT91_PMC_VER (AT91_PMC + 0xfc) /* PMC Module Version [AT91CAP9 only] */ +#define AT91_PMC_PCR 0x10c /* Peripheral Control Register [some SAM9] */ +#define AT91_PMC_PCR_PID (0x3f << 0) /* Peripheral ID */ +#define AT91_PMC_PCR_CMD (0x1 << 12) /* Command */ +#define AT91_PMC_PCR_DIV (0x3 << 16) /* Divisor Value */ +#define AT91_PMC_PCRDIV(n) (((n) << 16) & AT91_PMC_PCR_DIV) +#define AT91_PMC_PCR_EN (0x1 << 28) /* Enable */ #endif diff --git a/arch/arm/mach-at91/include/mach/at91_ramc.h b/arch/arm/mach-at91/include/mach/at91_ramc.h new file mode 100644 index 0000000..d8aeb27 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_ramc.h @@ -0,0 +1,32 @@ +/* + * Header file for the Atmel RAM Controller + * + * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * Under GPLv2 only + */ + +#ifndef __AT91_RAMC_H__ +#define __AT91_RAMC_H__ + +#ifndef __ASSEMBLY__ +extern void __iomem *at91_ramc_base[]; + +#define at91_ramc_read(id, field) \ + __raw_readl(at91_ramc_base[id] + field) + +#define at91_ramc_write(id, field, value) \ + __raw_writel(value, at91_ramc_base[id] + field) +#else +.extern at91_ramc_base +#endif + +#define AT91_MEMCTRL_MC 0 +#define AT91_MEMCTRL_SDRAMC 1 +#define AT91_MEMCTRL_DDRSDR 2 + +#include <mach/at91rm9200_sdramc.h> +#include <mach/at91sam9_ddrsdr.h> +#include <mach/at91sam9_sdramc.h> + +#endif /* __AT91_RAMC_H__ */ diff --git a/arch/arm/mach-at91/include/mach/at91_st.h b/arch/arm/mach-at91/include/mach/at91_st.h index 8847173..969aac2 100644 --- a/arch/arm/mach-at91/include/mach/at91_st.h +++ b/arch/arm/mach-at91/include/mach/at91_st.h @@ -16,34 +16,46 @@ #ifndef AT91_ST_H #define AT91_ST_H -#define AT91_ST_CR (AT91_ST + 0x00) /* Control Register */ +#ifndef __ASSEMBLY__ +extern void __iomem *at91_st_base; + +#define at91_st_read(field) \ + __raw_readl(at91_st_base + field) + +#define at91_st_write(field, value) \ + __raw_writel(value, at91_st_base + field); +#else +.extern at91_st_base +#endif + +#define AT91_ST_CR 0x00 /* Control Register */ #define AT91_ST_WDRST (1 << 0) /* Watchdog Timer Restart */ -#define AT91_ST_PIMR (AT91_ST + 0x04) /* Period Interval Mode Register */ +#define AT91_ST_PIMR 0x04 /* Period Interval Mode Register */ #define AT91_ST_PIV (0xffff << 0) /* Period Interval Value */ -#define AT91_ST_WDMR (AT91_ST + 0x08) /* Watchdog Mode Register */ +#define AT91_ST_WDMR 0x08 /* Watchdog Mode Register */ #define AT91_ST_WDV (0xffff << 0) /* Watchdog Counter Value */ #define AT91_ST_RSTEN (1 << 16) /* Reset Enable */ #define AT91_ST_EXTEN (1 << 17) /* External Signal Assertion Enable */ -#define AT91_ST_RTMR (AT91_ST + 0x0c) /* Real-time Mode Register */ +#define AT91_ST_RTMR 0x0c /* Real-time Mode Register */ #define AT91_ST_RTPRES (0xffff << 0) /* Real-time Prescalar Value */ -#define AT91_ST_SR (AT91_ST + 0x10) /* Status Register */ +#define AT91_ST_SR 0x10 /* Status Register */ #define AT91_ST_PITS (1 << 0) /* Period Interval Timer Status */ #define AT91_ST_WDOVF (1 << 1) /* Watchdog Overflow */ #define AT91_ST_RTTINC (1 << 2) /* Real-time Timer Increment */ #define AT91_ST_ALMS (1 << 3) /* Alarm Status */ -#define AT91_ST_IER (AT91_ST + 0x14) /* Interrupt Enable Register */ -#define AT91_ST_IDR (AT91_ST + 0x18) /* Interrupt Disable Register */ -#define AT91_ST_IMR (AT91_ST + 0x1c) /* Interrupt Mask Register */ +#define AT91_ST_IER 0x14 /* Interrupt Enable Register */ +#define AT91_ST_IDR 0x18 /* Interrupt Disable Register */ +#define AT91_ST_IMR 0x1c /* Interrupt Mask Register */ -#define AT91_ST_RTAR (AT91_ST + 0x20) /* Real-time Alarm Register */ +#define AT91_ST_RTAR 0x20 /* Real-time Alarm Register */ #define AT91_ST_ALMV (0xfffff << 0) /* Alarm Value */ -#define AT91_ST_CRTR (AT91_ST + 0x24) /* Current Real-time Register */ +#define AT91_ST_CRTR 0x24 /* Current Real-time Register */ #define AT91_ST_CRTV (0xfffff << 0) /* Current Real-Time Value */ #endif diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h deleted file mode 100644 index 61d9529..0000000 --- a/arch/arm/mach-at91/include/mach/at91cap9.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * arch/arm/mach-at91/include/mach/at91cap9.h - * - * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com> - * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com> - * Copyright (C) 2007 Atmel Corporation. - * - * Common definitions. - * Based on AT91CAP9 datasheet revision B (Preliminary). - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#ifndef AT91CAP9_H -#define AT91CAP9_H - -/* - * Peripheral identifiers/interrupts. - */ -#define AT91CAP9_ID_PIOABCD 2 /* Parallel IO Controller A, B, C and D */ -#define AT91CAP9_ID_MPB0 3 /* MP Block Peripheral 0 */ -#define AT91CAP9_ID_MPB1 4 /* MP Block Peripheral 1 */ -#define AT91CAP9_ID_MPB2 5 /* MP Block Peripheral 2 */ -#define AT91CAP9_ID_MPB3 6 /* MP Block Peripheral 3 */ -#define AT91CAP9_ID_MPB4 7 /* MP Block Peripheral 4 */ -#define AT91CAP9_ID_US0 8 /* USART 0 */ -#define AT91CAP9_ID_US1 9 /* USART 1 */ -#define AT91CAP9_ID_US2 10 /* USART 2 */ -#define AT91CAP9_ID_MCI0 11 /* Multimedia Card Interface 0 */ -#define AT91CAP9_ID_MCI1 12 /* Multimedia Card Interface 1 */ -#define AT91CAP9_ID_CAN 13 /* CAN */ -#define AT91CAP9_ID_TWI 14 /* Two-Wire Interface */ -#define AT91CAP9_ID_SPI0 15 /* Serial Peripheral Interface 0 */ -#define AT91CAP9_ID_SPI1 16 /* Serial Peripheral Interface 0 */ -#define AT91CAP9_ID_SSC0 17 /* Serial Synchronous Controller 0 */ -#define AT91CAP9_ID_SSC1 18 /* Serial Synchronous Controller 1 */ -#define AT91CAP9_ID_AC97C 19 /* AC97 Controller */ -#define AT91CAP9_ID_TCB 20 /* Timer Counter 0, 1 and 2 */ -#define AT91CAP9_ID_PWMC 21 /* Pulse Width Modulation Controller */ -#define AT91CAP9_ID_EMAC 22 /* Ethernet */ -#define AT91CAP9_ID_AESTDES 23 /* Advanced Encryption Standard, Triple DES */ -#define AT91CAP9_ID_ADC 24 /* Analog-to-Digital Converter */ -#define AT91CAP9_ID_ISI 25 /* Image Sensor Interface */ -#define AT91CAP9_ID_LCDC 26 /* LCD Controller */ -#define AT91CAP9_ID_DMA 27 /* DMA Controller */ -#define AT91CAP9_ID_UDPHS 28 /* USB High Speed Device Port */ -#define AT91CAP9_ID_UHP 29 /* USB Host Port */ -#define AT91CAP9_ID_IRQ0 30 /* Advanced Interrupt Controller (IRQ0) */ -#define AT91CAP9_ID_IRQ1 31 /* Advanced Interrupt Controller (IRQ1) */ - -/* - * User Peripheral physical base addresses. - */ -#define AT91CAP9_BASE_UDPHS 0xfff78000 -#define AT91CAP9_BASE_TCB0 0xfff7c000 -#define AT91CAP9_BASE_TC0 0xfff7c000 -#define AT91CAP9_BASE_TC1 0xfff7c040 -#define AT91CAP9_BASE_TC2 0xfff7c080 -#define AT91CAP9_BASE_MCI0 0xfff80000 -#define AT91CAP9_BASE_MCI1 0xfff84000 -#define AT91CAP9_BASE_TWI 0xfff88000 -#define AT91CAP9_BASE_US0 0xfff8c000 -#define AT91CAP9_BASE_US1 0xfff90000 -#define AT91CAP9_BASE_US2 0xfff94000 -#define AT91CAP9_BASE_SSC0 0xfff98000 -#define AT91CAP9_BASE_SSC1 0xfff9c000 -#define AT91CAP9_BASE_AC97C 0xfffa0000 -#define AT91CAP9_BASE_SPI0 0xfffa4000 -#define AT91CAP9_BASE_SPI1 0xfffa8000 -#define AT91CAP9_BASE_CAN 0xfffac000 -#define AT91CAP9_BASE_PWMC 0xfffb8000 -#define AT91CAP9_BASE_EMAC 0xfffbc000 -#define AT91CAP9_BASE_ADC 0xfffc0000 -#define AT91CAP9_BASE_ISI 0xfffc4000 - -/* - * System Peripherals (offset from AT91_BASE_SYS) - */ -#define AT91_BCRAMC (0xffffe400 - AT91_BASE_SYS) -#define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) -#define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS) -#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) -#define AT91_GPBR (cpu_is_at91cap9_revB() ? \ - (0xfffffd50 - AT91_BASE_SYS) : \ - (0xfffffd60 - AT91_BASE_SYS)) - -#define AT91CAP9_BASE_ECC 0xffffe200 -#define AT91CAP9_BASE_DMA 0xffffec00 -#define AT91CAP9_BASE_SMC 0xffffe800 -#define AT91CAP9_BASE_DBGU AT91_BASE_DBGU1 -#define AT91CAP9_BASE_PIOA 0xfffff200 -#define AT91CAP9_BASE_PIOB 0xfffff400 -#define AT91CAP9_BASE_PIOC 0xfffff600 -#define AT91CAP9_BASE_PIOD 0xfffff800 -#define AT91CAP9_BASE_RSTC 0xfffffd00 -#define AT91CAP9_BASE_SHDWC 0xfffffd10 -#define AT91CAP9_BASE_RTT 0xfffffd20 -#define AT91CAP9_BASE_PIT 0xfffffd30 -#define AT91CAP9_BASE_WDT 0xfffffd40 - -#define AT91_USART0 AT91CAP9_BASE_US0 -#define AT91_USART1 AT91CAP9_BASE_US1 -#define AT91_USART2 AT91CAP9_BASE_US2 - - -/* - * Internal Memory. - */ -#define AT91CAP9_SRAM_BASE 0x00100000 /* Internal SRAM base address */ -#define AT91CAP9_SRAM_SIZE (32 * SZ_1K) /* Internal SRAM size (32Kb) */ - -#define AT91CAP9_ROM_BASE 0x00400000 /* Internal ROM base address */ -#define AT91CAP9_ROM_SIZE (32 * SZ_1K) /* Internal ROM size (32Kb) */ - -#define AT91CAP9_LCDC_BASE 0x00500000 /* LCD Controller */ -#define AT91CAP9_UDPHS_FIFO 0x00600000 /* USB High Speed Device Port */ -#define AT91CAP9_UHP_BASE 0x00700000 /* USB Host controller */ - -#endif diff --git a/arch/arm/mach-at91/include/mach/at91cap9_matrix.h b/arch/arm/mach-at91/include/mach/at91cap9_matrix.h deleted file mode 100644 index 4b9d4af..0000000 --- a/arch/arm/mach-at91/include/mach/at91cap9_matrix.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * arch/arm/mach-at91/include/mach/at91cap9_matrix.h - * - * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com> - * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com> - * Copyright (C) 2006 Atmel Corporation. - * - * Memory Controllers (MATRIX, EBI) - System peripherals registers. - * Based on AT91CAP9 datasheet revision B (Preliminary). - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#ifndef AT91CAP9_MATRIX_H -#define AT91CAP9_MATRIX_H - -#define AT91_MATRIX_MCFG0 (AT91_MATRIX + 0x00) /* Master Configuration Register 0 */ -#define AT91_MATRIX_MCFG1 (AT91_MATRIX + 0x04) /* Master Configuration Register 1 */ -#define AT91_MATRIX_MCFG2 (AT91_MATRIX + 0x08) /* Master Configuration Register 2 */ -#define AT91_MATRIX_MCFG3 (AT91_MATRIX + 0x0C) /* Master Configuration Register 3 */ -#define AT91_MATRIX_MCFG4 (AT91_MATRIX + 0x10) /* Master Configuration Register 4 */ -#define AT91_MATRIX_MCFG5 (AT91_MATRIX + 0x14) /* Master Configuration Register 5 */ -#define AT91_MATRIX_MCFG6 (AT91_MATRIX + 0x18) /* Master Configuration Register 6 */ -#define AT91_MATRIX_MCFG7 (AT91_MATRIX + 0x1C) /* Master Configuration Register 7 */ -#define AT91_MATRIX_MCFG8 (AT91_MATRIX + 0x20) /* Master Configuration Register 8 */ -#define AT91_MATRIX_MCFG9 (AT91_MATRIX + 0x24) /* Master Configuration Register 9 */ -#define AT91_MATRIX_MCFG10 (AT91_MATRIX + 0x28) /* Master Configuration Register 10 */ -#define AT91_MATRIX_MCFG11 (AT91_MATRIX + 0x2C) /* Master Configuration Register 11 */ -#define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */ -#define AT91_MATRIX_ULBT_INFINITE (0 << 0) -#define AT91_MATRIX_ULBT_SINGLE (1 << 0) -#define AT91_MATRIX_ULBT_FOUR (2 << 0) -#define AT91_MATRIX_ULBT_EIGHT (3 << 0) -#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0) - -#define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x40) /* Slave Configuration Register 0 */ -#define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x44) /* Slave Configuration Register 1 */ -#define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x48) /* Slave Configuration Register 2 */ -#define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x4C) /* Slave Configuration Register 3 */ -#define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x50) /* Slave Configuration Register 4 */ -#define AT91_MATRIX_SCFG5 (AT91_MATRIX + 0x54) /* Slave Configuration Register 5 */ -#define AT91_MATRIX_SCFG6 (AT91_MATRIX + 0x58) /* Slave Configuration Register 6 */ -#define AT91_MATRIX_SCFG7 (AT91_MATRIX + 0x5C) /* Slave Configuration Register 7 */ -#define AT91_MATRIX_SCFG8 (AT91_MATRIX + 0x60) /* Slave Configuration Register 8 */ -#define AT91_MATRIX_SCFG9 (AT91_MATRIX + 0x64) /* Slave Configuration Register 9 */ -#define AT91_MATRIX_SLOT_CYCLE (0xff << 0) /* Maximum Number of Allowed Cycles for a Burst */ -#define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */ -#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) -#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16) -#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) -#define AT91_MATRIX_FIXED_DEFMSTR (0xf << 18) /* Fixed Index of Default Master */ -#define AT91_MATRIX_ARBT (3 << 24) /* Arbitration Type */ -#define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24) -#define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24) - -#define AT91_MATRIX_PRAS0 (AT91_MATRIX + 0x80) /* Priority Register A for Slave 0 */ -#define AT91_MATRIX_PRBS0 (AT91_MATRIX + 0x84) /* Priority Register B for Slave 0 */ -#define AT91_MATRIX_PRAS1 (AT91_MATRIX + 0x88) /* Priority Register A for Slave 1 */ -#define AT91_MATRIX_PRBS1 (AT91_MATRIX + 0x8C) /* Priority Register B for Slave 1 */ -#define AT91_MATRIX_PRAS2 (AT91_MATRIX + 0x90) /* Priority Register A for Slave 2 */ -#define AT91_MATRIX_PRBS2 (AT91_MATRIX + 0x94) /* Priority Register B for Slave 2 */ -#define AT91_MATRIX_PRAS3 (AT91_MATRIX + 0x98) /* Priority Register A for Slave 3 */ -#define AT91_MATRIX_PRBS3 (AT91_MATRIX + 0x9C) /* Priority Register B for Slave 3 */ -#define AT91_MATRIX_PRAS4 (AT91_MATRIX + 0xA0) /* Priority Register A for Slave 4 */ -#define AT91_MATRIX_PRBS4 (AT91_MATRIX + 0xA4) /* Priority Register B for Slave 4 */ -#define AT91_MATRIX_PRAS5 (AT91_MATRIX + 0xA8) /* Priority Register A for Slave 5 */ -#define AT91_MATRIX_PRBS5 (AT91_MATRIX + 0xAC) /* Priority Register B for Slave 5 */ -#define AT91_MATRIX_PRAS6 (AT91_MATRIX + 0xB0) /* Priority Register A for Slave 6 */ -#define AT91_MATRIX_PRBS6 (AT91_MATRIX + 0xB4) /* Priority Register B for Slave 6 */ -#define AT91_MATRIX_PRAS7 (AT91_MATRIX + 0xB8) /* Priority Register A for Slave 7 */ -#define AT91_MATRIX_PRBS7 (AT91_MATRIX + 0xBC) /* Priority Register B for Slave 7 */ -#define AT91_MATRIX_PRAS8 (AT91_MATRIX + 0xC0) /* Priority Register A for Slave 8 */ -#define AT91_MATRIX_PRBS8 (AT91_MATRIX + 0xC4) /* Priority Register B for Slave 8 */ -#define AT91_MATRIX_PRAS9 (AT91_MATRIX + 0xC8) /* Priority Register A for Slave 9 */ -#define AT91_MATRIX_PRBS9 (AT91_MATRIX + 0xCC) /* Priority Register B for Slave 9 */ -#define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */ -#define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */ -#define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */ -#define AT91_MATRIX_M3PR (3 << 12) /* Master 3 Priority */ -#define AT91_MATRIX_M4PR (3 << 16) /* Master 4 Priority */ -#define AT91_MATRIX_M5PR (3 << 20) /* Master 5 Priority */ -#define AT91_MATRIX_M6PR (3 << 24) /* Master 6 Priority */ -#define AT91_MATRIX_M7PR (3 << 28) /* Master 7 Priority */ -#define AT91_MATRIX_M8PR (3 << 0) /* Master 8 Priority (in Register B) */ -#define AT91_MATRIX_M9PR (3 << 4) /* Master 9 Priority (in Register B) */ -#define AT91_MATRIX_M10PR (3 << 8) /* Master 10 Priority (in Register B) */ -#define AT91_MATRIX_M11PR (3 << 12) /* Master 11 Priority (in Register B) */ - -#define AT91_MATRIX_MRCR (AT91_MATRIX + 0x100) /* Master Remap Control Register */ -#define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */ -#define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */ -#define AT91_MATRIX_RCB2 (1 << 2) -#define AT91_MATRIX_RCB3 (1 << 3) -#define AT91_MATRIX_RCB4 (1 << 4) -#define AT91_MATRIX_RCB5 (1 << 5) -#define AT91_MATRIX_RCB6 (1 << 6) -#define AT91_MATRIX_RCB7 (1 << 7) -#define AT91_MATRIX_RCB8 (1 << 8) -#define AT91_MATRIX_RCB9 (1 << 9) -#define AT91_MATRIX_RCB10 (1 << 10) -#define AT91_MATRIX_RCB11 (1 << 11) - -#define AT91_MPBS0_SFR (AT91_MATRIX + 0x114) /* MPBlock Slave 0 Special Function Register */ -#define AT91_MPBS1_SFR (AT91_MATRIX + 0x11C) /* MPBlock Slave 1 Special Function Register */ - -#define AT91_MATRIX_UDPHS (AT91_MATRIX + 0x118) /* USBHS Special Function Register [AT91CAP9 only] */ -#define AT91_MATRIX_SELECT_UDPHS (0 << 31) /* select High Speed UDP */ -#define AT91_MATRIX_SELECT_UDP (1 << 31) /* select standard UDP */ -#define AT91_MATRIX_UDPHS_BYPASS_LOCK (1 << 30) /* bypass lock bit */ - -#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x120) /* EBI Chip Select Assignment Register */ -#define AT91_MATRIX_EBI_CS1A (1 << 1) /* Chip Select 1 Assignment */ -#define AT91_MATRIX_EBI_CS1A_SMC (0 << 1) -#define AT91_MATRIX_EBI_CS1A_BCRAMC (1 << 1) -#define AT91_MATRIX_EBI_CS3A (1 << 3) /* Chip Select 3 Assignment */ -#define AT91_MATRIX_EBI_CS3A_SMC (0 << 3) -#define AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA (1 << 3) -#define AT91_MATRIX_EBI_CS4A (1 << 4) /* Chip Select 4 Assignment */ -#define AT91_MATRIX_EBI_CS4A_SMC (0 << 4) -#define AT91_MATRIX_EBI_CS4A_SMC_CF1 (1 << 4) -#define AT91_MATRIX_EBI_CS5A (1 << 5) /* Chip Select 5 Assignment */ -#define AT91_MATRIX_EBI_CS5A_SMC (0 << 5) -#define AT91_MATRIX_EBI_CS5A_SMC_CF2 (1 << 5) -#define AT91_MATRIX_EBI_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */ -#define AT91_MATRIX_EBI_DQSPDC (1 << 9) /* Data Qualifier Strobe Pull-Down Configuration */ -#define AT91_MATRIX_EBI_VDDIOMSEL (1 << 16) /* Memory voltage selection */ -#define AT91_MATRIX_EBI_VDDIOMSEL_1_8V (0 << 16) -#define AT91_MATRIX_EBI_VDDIOMSEL_3_3V (1 << 16) - -#define AT91_MPBS2_SFR (AT91_MATRIX + 0x12C) /* MPBlock Slave 2 Special Function Register */ -#define AT91_MPBS3_SFR (AT91_MATRIX + 0x130) /* MPBlock Slave 3 Special Function Register */ -#define AT91_APB_SFR (AT91_MATRIX + 0x134) /* APB Bridge Special Function Register */ - -#endif diff --git a/arch/arm/mach-at91/include/mach/at91rm9200.h b/arch/arm/mach-at91/include/mach/at91rm9200.h index bacb511..603e6aa 100644 --- a/arch/arm/mach-at91/include/mach/at91rm9200.h +++ b/arch/arm/mach-at91/include/mach/at91rm9200.h @@ -77,26 +77,22 @@ /* - * System Peripherals (offset from AT91_BASE_SYS) + * System Peripherals */ -#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) /* Power Management Controller */ -#define AT91_ST (0xfffffd00 - AT91_BASE_SYS) /* System Timer */ -#define AT91_MC (0xffffff00 - AT91_BASE_SYS) /* Memory Controllers */ - #define AT91RM9200_BASE_DBGU AT91_BASE_DBGU0 /* Debug Unit */ #define AT91RM9200_BASE_PIOA 0xfffff400 /* PIO Controller A */ #define AT91RM9200_BASE_PIOB 0xfffff600 /* PIO Controller B */ #define AT91RM9200_BASE_PIOC 0xfffff800 /* PIO Controller C */ #define AT91RM9200_BASE_PIOD 0xfffffa00 /* PIO Controller D */ +#define AT91RM9200_BASE_ST 0xfffffd00 /* System Timer */ #define AT91RM9200_BASE_RTC 0xfffffe00 /* Real-Time Clock */ +#define AT91RM9200_BASE_MC 0xffffff00 /* Memory Controllers */ #define AT91_USART0 AT91RM9200_BASE_US0 #define AT91_USART1 AT91RM9200_BASE_US1 #define AT91_USART2 AT91RM9200_BASE_US2 #define AT91_USART3 AT91RM9200_BASE_US3 -#define AT91_MATRIX 0 /* not supported */ - /* * Internal Memory. */ diff --git a/arch/arm/mach-at91/include/mach/at91rm9200_mc.h b/arch/arm/mach-at91/include/mach/at91rm9200_mc.h index d34e4ed..aeaadfb 100644 --- a/arch/arm/mach-at91/include/mach/at91rm9200_mc.h +++ b/arch/arm/mach-at91/include/mach/at91rm9200_mc.h @@ -17,10 +17,10 @@ #define AT91RM9200_MC_H /* Memory Controller */ -#define AT91_MC_RCR (AT91_MC + 0x00) /* MC Remap Control Register */ +#define AT91_MC_RCR 0x00 /* MC Remap Control Register */ #define AT91_MC_RCB (1 << 0) /* Remap Command Bit */ -#define AT91_MC_ASR (AT91_MC + 0x04) /* MC Abort Status Register */ +#define AT91_MC_ASR 0x04 /* MC Abort Status Register */ #define AT91_MC_UNADD (1 << 0) /* Undefined Address Abort Status */ #define AT91_MC_MISADD (1 << 1) /* Misaligned Address Abort Status */ #define AT91_MC_ABTSZ (3 << 8) /* Abort Size Status */ @@ -40,16 +40,16 @@ #define AT91_MC_SVMST2 (1 << 26) /* Saved UHP Abort Source */ #define AT91_MC_SVMST3 (1 << 27) /* Saved EMAC Abort Source */ -#define AT91_MC_AASR (AT91_MC + 0x08) /* MC Abort Address Status Register */ +#define AT91_MC_AASR 0x08 /* MC Abort Address Status Register */ -#define AT91_MC_MPR (AT91_MC + 0x0c) /* MC Master Priority Register */ +#define AT91_MC_MPR 0x0c /* MC Master Priority Register */ #define AT91_MPR_MSTP0 (7 << 0) /* ARM920T Priority */ #define AT91_MPR_MSTP1 (7 << 4) /* PDC Priority */ #define AT91_MPR_MSTP2 (7 << 8) /* UHP Priority */ #define AT91_MPR_MSTP3 (7 << 12) /* EMAC Priority */ /* External Bus Interface (EBI) registers */ -#define AT91_EBI_CSA (AT91_MC + 0x60) /* Chip Select Assignment Register */ +#define AT91_EBI_CSA 0x60 /* Chip Select Assignment Register */ #define AT91_EBI_CS0A (1 << 0) /* Chip Select 0 Assignment */ #define AT91_EBI_CS0A_SMC (0 << 0) #define AT91_EBI_CS0A_BFC (1 << 0) @@ -66,7 +66,7 @@ #define AT91_EBI_DBPUC (1 << 0) /* Data Bus Pull-Up Configuration */ /* Static Memory Controller (SMC) registers */ -#define AT91_SMC_CSR(n) (AT91_MC + 0x70 + ((n) * 4))/* SMC Chip Select Register */ +#define AT91_SMC_CSR(n) (0x70 + ((n) * 4)) /* SMC Chip Select Register */ #define AT91_SMC_NWS (0x7f << 0) /* Number of Wait States */ #define AT91_SMC_NWS_(x) ((x) << 0) #define AT91_SMC_WSEN (1 << 7) /* Wait State Enable */ @@ -87,52 +87,8 @@ #define AT91_SMC_RWHOLD (7 << 28) /* Read & Write Signal Hold Time */ #define AT91_SMC_RWHOLD_(x) ((x) << 28) -/* SDRAM Controller registers */ -#define AT91_SDRAMC_MR (AT91_MC + 0x90) /* Mode Register */ -#define AT91_SDRAMC_MODE (0xf << 0) /* Command Mode */ -#define AT91_SDRAMC_MODE_NORMAL (0 << 0) -#define AT91_SDRAMC_MODE_NOP (1 << 0) -#define AT91_SDRAMC_MODE_PRECHARGE (2 << 0) -#define AT91_SDRAMC_MODE_LMR (3 << 0) -#define AT91_SDRAMC_MODE_REFRESH (4 << 0) -#define AT91_SDRAMC_DBW (1 << 4) /* Data Bus Width */ -#define AT91_SDRAMC_DBW_32 (0 << 4) -#define AT91_SDRAMC_DBW_16 (1 << 4) - -#define AT91_SDRAMC_TR (AT91_MC + 0x94) /* Refresh Timer Register */ -#define AT91_SDRAMC_COUNT (0xfff << 0) /* Refresh Timer Count */ - -#define AT91_SDRAMC_CR (AT91_MC + 0x98) /* Configuration Register */ -#define AT91_SDRAMC_NC (3 << 0) /* Number of Column Bits */ -#define AT91_SDRAMC_NC_8 (0 << 0) -#define AT91_SDRAMC_NC_9 (1 << 0) -#define AT91_SDRAMC_NC_10 (2 << 0) -#define AT91_SDRAMC_NC_11 (3 << 0) -#define AT91_SDRAMC_NR (3 << 2) /* Number of Row Bits */ -#define AT91_SDRAMC_NR_11 (0 << 2) -#define AT91_SDRAMC_NR_12 (1 << 2) -#define AT91_SDRAMC_NR_13 (2 << 2) -#define AT91_SDRAMC_NB (1 << 4) /* Number of Banks */ -#define AT91_SDRAMC_NB_2 (0 << 4) -#define AT91_SDRAMC_NB_4 (1 << 4) -#define AT91_SDRAMC_CAS (3 << 5) /* CAS Latency */ -#define AT91_SDRAMC_CAS_2 (2 << 5) -#define AT91_SDRAMC_TWR (0xf << 7) /* Write Recovery Delay */ -#define AT91_SDRAMC_TRC (0xf << 11) /* Row Cycle Delay */ -#define AT91_SDRAMC_TRP (0xf << 15) /* Row Precharge Delay */ -#define AT91_SDRAMC_TRCD (0xf << 19) /* Row to Column Delay */ -#define AT91_SDRAMC_TRAS (0xf << 23) /* Active to Precharge Delay */ -#define AT91_SDRAMC_TXSR (0xf << 27) /* Exit Self Refresh to Active Delay */ - -#define AT91_SDRAMC_SRR (AT91_MC + 0x9c) /* Self Refresh Register */ -#define AT91_SDRAMC_LPR (AT91_MC + 0xa0) /* Low Power Register */ -#define AT91_SDRAMC_IER (AT91_MC + 0xa4) /* Interrupt Enable Register */ -#define AT91_SDRAMC_IDR (AT91_MC + 0xa8) /* Interrupt Disable Register */ -#define AT91_SDRAMC_IMR (AT91_MC + 0xac) /* Interrupt Mask Register */ -#define AT91_SDRAMC_ISR (AT91_MC + 0xb0) /* Interrupt Status Register */ - /* Burst Flash Controller register */ -#define AT91_BFC_MR (AT91_MC + 0xc0) /* Mode Register */ +#define AT91_BFC_MR 0xc0 /* Mode Register */ #define AT91_BFC_BFCOM (3 << 0) /* Burst Flash Controller Operating Mode */ #define AT91_BFC_BFCOM_DISABLED (0 << 0) #define AT91_BFC_BFCOM_ASYNC (1 << 0) diff --git a/arch/arm/mach-at91/include/mach/at91rm9200_sdramc.h b/arch/arm/mach-at91/include/mach/at91rm9200_sdramc.h new file mode 100644 index 0000000..aa047f45 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91rm9200_sdramc.h @@ -0,0 +1,63 @@ +/* + * arch/arm/mach-at91/include/mach/at91rm9200_sdramc.h + * + * Copyright (C) 2005 Ivan Kokshaysky + * Copyright (C) SAN People + * + * Memory Controllers (SDRAMC only) - System peripherals registers. + * Based on AT91RM9200 datasheet revision E. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef AT91RM9200_SDRAMC_H +#define AT91RM9200_SDRAMC_H + +/* SDRAM Controller registers */ +#define AT91RM9200_SDRAMC_MR 0x90 /* Mode Register */ +#define AT91RM9200_SDRAMC_MODE (0xf << 0) /* Command Mode */ +#define AT91RM9200_SDRAMC_MODE_NORMAL (0 << 0) +#define AT91RM9200_SDRAMC_MODE_NOP (1 << 0) +#define AT91RM9200_SDRAMC_MODE_PRECHARGE (2 << 0) +#define AT91RM9200_SDRAMC_MODE_LMR (3 << 0) +#define AT91RM9200_SDRAMC_MODE_REFRESH (4 << 0) +#define AT91RM9200_SDRAMC_DBW (1 << 4) /* Data Bus Width */ +#define AT91RM9200_SDRAMC_DBW_32 (0 << 4) +#define AT91RM9200_SDRAMC_DBW_16 (1 << 4) + +#define AT91RM9200_SDRAMC_TR 0x94 /* Refresh Timer Register */ +#define AT91RM9200_SDRAMC_COUNT (0xfff << 0) /* Refresh Timer Count */ + +#define AT91RM9200_SDRAMC_CR 0x98 /* Configuration Register */ +#define AT91RM9200_SDRAMC_NC (3 << 0) /* Number of Column Bits */ +#define AT91RM9200_SDRAMC_NC_8 (0 << 0) +#define AT91RM9200_SDRAMC_NC_9 (1 << 0) +#define AT91RM9200_SDRAMC_NC_10 (2 << 0) +#define AT91RM9200_SDRAMC_NC_11 (3 << 0) +#define AT91RM9200_SDRAMC_NR (3 << 2) /* Number of Row Bits */ +#define AT91RM9200_SDRAMC_NR_11 (0 << 2) +#define AT91RM9200_SDRAMC_NR_12 (1 << 2) +#define AT91RM9200_SDRAMC_NR_13 (2 << 2) +#define AT91RM9200_SDRAMC_NB (1 << 4) /* Number of Banks */ +#define AT91RM9200_SDRAMC_NB_2 (0 << 4) +#define AT91RM9200_SDRAMC_NB_4 (1 << 4) +#define AT91RM9200_SDRAMC_CAS (3 << 5) /* CAS Latency */ +#define AT91RM9200_SDRAMC_CAS_2 (2 << 5) +#define AT91RM9200_SDRAMC_TWR (0xf << 7) /* Write Recovery Delay */ +#define AT91RM9200_SDRAMC_TRC (0xf << 11) /* Row Cycle Delay */ +#define AT91RM9200_SDRAMC_TRP (0xf << 15) /* Row Precharge Delay */ +#define AT91RM9200_SDRAMC_TRCD (0xf << 19) /* Row to Column Delay */ +#define AT91RM9200_SDRAMC_TRAS (0xf << 23) /* Active to Precharge Delay */ +#define AT91RM9200_SDRAMC_TXSR (0xf << 27) /* Exit Self Refresh to Active Delay */ + +#define AT91RM9200_SDRAMC_SRR 0x9c /* Self Refresh Register */ +#define AT91RM9200_SDRAMC_LPR 0xa0 /* Low Power Register */ +#define AT91RM9200_SDRAMC_IER 0xa4 /* Interrupt Enable Register */ +#define AT91RM9200_SDRAMC_IDR 0xa8 /* Interrupt Disable Register */ +#define AT91RM9200_SDRAMC_IMR 0xac /* Interrupt Mask Register */ +#define AT91RM9200_SDRAMC_ISR 0xb0 /* Interrupt Status Register */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h index fa5ca27..08ae9af 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9260.h +++ b/arch/arm/mach-at91/include/mach/at91sam9260.h @@ -78,15 +78,12 @@ #define AT91SAM9260_BASE_ADC 0xfffe0000 /* - * System Peripherals (offset from AT91_BASE_SYS) + * System Peripherals */ -#define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) -#define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) -#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) -#define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) - #define AT91SAM9260_BASE_ECC 0xffffe800 +#define AT91SAM9260_BASE_SDRAMC 0xffffea00 #define AT91SAM9260_BASE_SMC 0xffffec00 +#define AT91SAM9260_BASE_MATRIX 0xffffee00 #define AT91SAM9260_BASE_DBGU AT91_BASE_DBGU0 #define AT91SAM9260_BASE_PIOA 0xfffff400 #define AT91SAM9260_BASE_PIOB 0xfffff600 @@ -96,6 +93,7 @@ #define AT91SAM9260_BASE_RTT 0xfffffd20 #define AT91SAM9260_BASE_PIT 0xfffffd30 #define AT91SAM9260_BASE_WDT 0xfffffd40 +#define AT91SAM9260_BASE_GPBR 0xfffffd50 #define AT91_USART0 AT91SAM9260_BASE_US0 #define AT91_USART1 AT91SAM9260_BASE_US1 @@ -115,6 +113,8 @@ #define AT91SAM9260_SRAM0_SIZE SZ_4K /* Internal SRAM 0 size (4Kb) */ #define AT91SAM9260_SRAM1_BASE 0x00300000 /* Internal SRAM 1 base address */ #define AT91SAM9260_SRAM1_SIZE SZ_4K /* Internal SRAM 1 size (4Kb) */ +#define AT91SAM9260_SRAM_BASE 0x002FF000 /* Internal SRAM base address */ +#define AT91SAM9260_SRAM_SIZE SZ_8K /* Internal SRAM size (8Kb) */ #define AT91SAM9260_UHP_BASE 0x00500000 /* USB Host controller */ @@ -128,6 +128,8 @@ #define AT91SAM9G20_SRAM0_SIZE SZ_16K /* Internal SRAM 0 size (16Kb) */ #define AT91SAM9G20_SRAM1_BASE 0x00300000 /* Internal SRAM 1 base address */ #define AT91SAM9G20_SRAM1_SIZE SZ_16K /* Internal SRAM 1 size (16Kb) */ +#define AT91SAM9G20_SRAM_BASE 0x002FC000 /* Internal SRAM base address */ +#define AT91SAM9G20_SRAM_SIZE SZ_32K /* Internal SRAM size (32Kb) */ #define AT91SAM9G20_UHP_BASE 0x00500000 /* USB Host controller */ diff --git a/arch/arm/mach-at91/include/mach/at91sam9260_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9260_matrix.h index 020f02e..f459df4 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9260_matrix.h +++ b/arch/arm/mach-at91/include/mach/at91sam9260_matrix.h @@ -15,12 +15,12 @@ #ifndef AT91SAM9260_MATRIX_H #define AT91SAM9260_MATRIX_H -#define AT91_MATRIX_MCFG0 (AT91_MATRIX + 0x00) /* Master Configuration Register 0 */ -#define AT91_MATRIX_MCFG1 (AT91_MATRIX + 0x04) /* Master Configuration Register 1 */ -#define AT91_MATRIX_MCFG2 (AT91_MATRIX + 0x08) /* Master Configuration Register 2 */ -#define AT91_MATRIX_MCFG3 (AT91_MATRIX + 0x0C) /* Master Configuration Register 3 */ -#define AT91_MATRIX_MCFG4 (AT91_MATRIX + 0x10) /* Master Configuration Register 4 */ -#define AT91_MATRIX_MCFG5 (AT91_MATRIX + 0x14) /* Master Configuration Register 5 */ +#define AT91_MATRIX_MCFG0 0x00 /* Master Configuration Register 0 */ +#define AT91_MATRIX_MCFG1 0x04 /* Master Configuration Register 1 */ +#define AT91_MATRIX_MCFG2 0x08 /* Master Configuration Register 2 */ +#define AT91_MATRIX_MCFG3 0x0C /* Master Configuration Register 3 */ +#define AT91_MATRIX_MCFG4 0x10 /* Master Configuration Register 4 */ +#define AT91_MATRIX_MCFG5 0x14 /* Master Configuration Register 5 */ #define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */ #define AT91_MATRIX_ULBT_INFINITE (0 << 0) #define AT91_MATRIX_ULBT_SINGLE (1 << 0) @@ -28,11 +28,11 @@ #define AT91_MATRIX_ULBT_EIGHT (3 << 0) #define AT91_MATRIX_ULBT_SIXTEEN (4 << 0) -#define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x40) /* Slave Configuration Register 0 */ -#define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x44) /* Slave Configuration Register 1 */ -#define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x48) /* Slave Configuration Register 2 */ -#define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x4C) /* Slave Configuration Register 3 */ -#define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x50) /* Slave Configuration Register 4 */ +#define AT91_MATRIX_SCFG0 0x40 /* Slave Configuration Register 0 */ +#define AT91_MATRIX_SCFG1 0x44 /* Slave Configuration Register 1 */ +#define AT91_MATRIX_SCFG2 0x48 /* Slave Configuration Register 2 */ +#define AT91_MATRIX_SCFG3 0x4C /* Slave Configuration Register 3 */ +#define AT91_MATRIX_SCFG4 0x50 /* Slave Configuration Register 4 */ #define AT91_MATRIX_SLOT_CYCLE (0xff << 0) /* Maximum Number of Allowed Cycles for a Burst */ #define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */ #define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) @@ -43,11 +43,11 @@ #define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24) #define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24) -#define AT91_MATRIX_PRAS0 (AT91_MATRIX + 0x80) /* Priority Register A for Slave 0 */ -#define AT91_MATRIX_PRAS1 (AT91_MATRIX + 0x88) /* Priority Register A for Slave 1 */ -#define AT91_MATRIX_PRAS2 (AT91_MATRIX + 0x90) /* Priority Register A for Slave 2 */ -#define AT91_MATRIX_PRAS3 (AT91_MATRIX + 0x98) /* Priority Register A for Slave 3 */ -#define AT91_MATRIX_PRAS4 (AT91_MATRIX + 0xA0) /* Priority Register A for Slave 4 */ +#define AT91_MATRIX_PRAS0 0x80 /* Priority Register A for Slave 0 */ +#define AT91_MATRIX_PRAS1 0x88 /* Priority Register A for Slave 1 */ +#define AT91_MATRIX_PRAS2 0x90 /* Priority Register A for Slave 2 */ +#define AT91_MATRIX_PRAS3 0x98 /* Priority Register A for Slave 3 */ +#define AT91_MATRIX_PRAS4 0xA0 /* Priority Register A for Slave 4 */ #define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */ #define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */ #define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */ @@ -55,11 +55,11 @@ #define AT91_MATRIX_M4PR (3 << 16) /* Master 4 Priority */ #define AT91_MATRIX_M5PR (3 << 20) /* Master 5 Priority */ -#define AT91_MATRIX_MRCR (AT91_MATRIX + 0x100) /* Master Remap Control Register */ +#define AT91_MATRIX_MRCR 0x100 /* Master Remap Control Register */ #define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */ #define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */ -#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x11C) /* EBI Chip Select Assignment Register */ +#define AT91_MATRIX_EBICSA 0x11C /* EBI Chip Select Assignment Register */ #define AT91_MATRIX_CS1A (1 << 1) /* Chip Select 1 Assignment */ #define AT91_MATRIX_CS1A_SMC (0 << 1) #define AT91_MATRIX_CS1A_SDRAMC (1 << 1) diff --git a/arch/arm/mach-at91/include/mach/at91sam9261.h b/arch/arm/mach-at91/include/mach/at91sam9261.h index 7cde2d3..44fbdc1 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9261.h +++ b/arch/arm/mach-at91/include/mach/at91sam9261.h @@ -63,14 +63,11 @@ /* - * System Peripherals (offset from AT91_BASE_SYS) + * System Peripherals */ -#define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) -#define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) -#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) -#define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) - #define AT91SAM9261_BASE_SMC 0xffffec00 +#define AT91SAM9261_BASE_MATRIX 0xffffee00 +#define AT91SAM9261_BASE_SDRAMC 0xffffea00 #define AT91SAM9261_BASE_DBGU AT91_BASE_DBGU0 #define AT91SAM9261_BASE_PIOA 0xfffff400 #define AT91SAM9261_BASE_PIOB 0xfffff600 @@ -80,6 +77,7 @@ #define AT91SAM9261_BASE_RTT 0xfffffd20 #define AT91SAM9261_BASE_PIT 0xfffffd30 #define AT91SAM9261_BASE_WDT 0xfffffd40 +#define AT91SAM9261_BASE_GPBR 0xfffffd50 #define AT91_USART0 AT91SAM9261_BASE_US0 #define AT91_USART1 AT91SAM9261_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9261_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9261_matrix.h index 69c6501..a50cdf8 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9261_matrix.h +++ b/arch/arm/mach-at91/include/mach/at91sam9261_matrix.h @@ -15,15 +15,15 @@ #ifndef AT91SAM9261_MATRIX_H #define AT91SAM9261_MATRIX_H -#define AT91_MATRIX_MCFG (AT91_MATRIX + 0x00) /* Master Configuration Register */ +#define AT91_MATRIX_MCFG 0x00 /* Master Configuration Register */ #define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */ #define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */ -#define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x04) /* Slave Configuration Register 0 */ -#define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x08) /* Slave Configuration Register 1 */ -#define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x0C) /* Slave Configuration Register 2 */ -#define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x10) /* Slave Configuration Register 3 */ -#define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x14) /* Slave Configuration Register 4 */ +#define AT91_MATRIX_SCFG0 0x04 /* Slave Configuration Register 0 */ +#define AT91_MATRIX_SCFG1 0x08 /* Slave Configuration Register 1 */ +#define AT91_MATRIX_SCFG2 0x0C /* Slave Configuration Register 2 */ +#define AT91_MATRIX_SCFG3 0x10 /* Slave Configuration Register 3 */ +#define AT91_MATRIX_SCFG4 0x14 /* Slave Configuration Register 4 */ #define AT91_MATRIX_SLOT_CYCLE (0xff << 0) /* Maximum Number of Allowed Cycles for a Burst */ #define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */ #define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) @@ -31,7 +31,7 @@ #define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) #define AT91_MATRIX_FIXED_DEFMSTR (7 << 18) /* Fixed Index of Default Master */ -#define AT91_MATRIX_TCR (AT91_MATRIX + 0x24) /* TCM Configuration Register */ +#define AT91_MATRIX_TCR 0x24 /* TCM Configuration Register */ #define AT91_MATRIX_ITCM_SIZE (0xf << 0) /* Size of ITCM enabled memory block */ #define AT91_MATRIX_ITCM_0 (0 << 0) #define AT91_MATRIX_ITCM_16 (5 << 0) @@ -43,7 +43,7 @@ #define AT91_MATRIX_DTCM_32 (6 << 4) #define AT91_MATRIX_DTCM_64 (7 << 4) -#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x30) /* EBI Chip Select Assignment Register */ +#define AT91_MATRIX_EBICSA 0x30 /* EBI Chip Select Assignment Register */ #define AT91_MATRIX_CS1A (1 << 1) /* Chip Select 1 Assignment */ #define AT91_MATRIX_CS1A_SMC (0 << 1) #define AT91_MATRIX_CS1A_SDRAMC (1 << 1) @@ -58,7 +58,7 @@ #define AT91_MATRIX_CS5A_SMC_CF2 (1 << 5) #define AT91_MATRIX_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */ -#define AT91_MATRIX_USBPUCR (AT91_MATRIX + 0x34) /* USB Pad Pull-Up Control Register */ +#define AT91_MATRIX_USBPUCR 0x34 /* USB Pad Pull-Up Control Register */ #define AT91_MATRIX_USBPUCR_PUON (1 << 30) /* USB Device PAD Pull-up Enable */ #endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9263.h b/arch/arm/mach-at91/include/mach/at91sam9263.h index 5949abd..d96cbb2 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9263.h +++ b/arch/arm/mach-at91/include/mach/at91sam9263.h @@ -72,18 +72,15 @@ #define AT91SAM9263_BASE_2DGE 0xfffc8000 /* - * System Peripherals (offset from AT91_BASE_SYS) + * System Peripherals */ -#define AT91_SDRAMC0 (0xffffe200 - AT91_BASE_SYS) -#define AT91_SDRAMC1 (0xffffe800 - AT91_BASE_SYS) -#define AT91_MATRIX (0xffffec00 - AT91_BASE_SYS) -#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) -#define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) - #define AT91SAM9263_BASE_ECC0 0xffffe000 +#define AT91SAM9263_BASE_SDRAMC0 0xffffe200 #define AT91SAM9263_BASE_SMC0 0xffffe400 #define AT91SAM9263_BASE_ECC1 0xffffe600 +#define AT91SAM9263_BASE_SDRAMC1 0xffffe800 #define AT91SAM9263_BASE_SMC1 0xffffea00 +#define AT91SAM9263_BASE_MATRIX 0xffffec00 #define AT91SAM9263_BASE_DBGU AT91_BASE_DBGU1 #define AT91SAM9263_BASE_PIOA 0xfffff200 #define AT91SAM9263_BASE_PIOB 0xfffff400 @@ -96,6 +93,7 @@ #define AT91SAM9263_BASE_PIT 0xfffffd30 #define AT91SAM9263_BASE_WDT 0xfffffd40 #define AT91SAM9263_BASE_RTT1 0xfffffd50 +#define AT91SAM9263_BASE_GPBR 0xfffffd60 #define AT91_USART0 AT91SAM9263_BASE_US0 #define AT91_USART1 AT91SAM9263_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9263_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9263_matrix.h index 9b3efd3..ebb5fdb 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9263_matrix.h +++ b/arch/arm/mach-at91/include/mach/at91sam9263_matrix.h @@ -15,15 +15,15 @@ #ifndef AT91SAM9263_MATRIX_H #define AT91SAM9263_MATRIX_H -#define AT91_MATRIX_MCFG0 (AT91_MATRIX + 0x00) /* Master Configuration Register 0 */ -#define AT91_MATRIX_MCFG1 (AT91_MATRIX + 0x04) /* Master Configuration Register 1 */ -#define AT91_MATRIX_MCFG2 (AT91_MATRIX + 0x08) /* Master Configuration Register 2 */ -#define AT91_MATRIX_MCFG3 (AT91_MATRIX + 0x0C) /* Master Configuration Register 3 */ -#define AT91_MATRIX_MCFG4 (AT91_MATRIX + 0x10) /* Master Configuration Register 4 */ -#define AT91_MATRIX_MCFG5 (AT91_MATRIX + 0x14) /* Master Configuration Register 5 */ -#define AT91_MATRIX_MCFG6 (AT91_MATRIX + 0x18) /* Master Configuration Register 6 */ -#define AT91_MATRIX_MCFG7 (AT91_MATRIX + 0x1C) /* Master Configuration Register 7 */ -#define AT91_MATRIX_MCFG8 (AT91_MATRIX + 0x20) /* Master Configuration Register 8 */ +#define AT91_MATRIX_MCFG0 0x00 /* Master Configuration Register 0 */ +#define AT91_MATRIX_MCFG1 0x04 /* Master Configuration Register 1 */ +#define AT91_MATRIX_MCFG2 0x08 /* Master Configuration Register 2 */ +#define AT91_MATRIX_MCFG3 0x0C /* Master Configuration Register 3 */ +#define AT91_MATRIX_MCFG4 0x10 /* Master Configuration Register 4 */ +#define AT91_MATRIX_MCFG5 0x14 /* Master Configuration Register 5 */ +#define AT91_MATRIX_MCFG6 0x18 /* Master Configuration Register 6 */ +#define AT91_MATRIX_MCFG7 0x1C /* Master Configuration Register 7 */ +#define AT91_MATRIX_MCFG8 0x20 /* Master Configuration Register 8 */ #define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */ #define AT91_MATRIX_ULBT_INFINITE (0 << 0) #define AT91_MATRIX_ULBT_SINGLE (1 << 0) @@ -31,14 +31,14 @@ #define AT91_MATRIX_ULBT_EIGHT (3 << 0) #define AT91_MATRIX_ULBT_SIXTEEN (4 << 0) -#define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x40) /* Slave Configuration Register 0 */ -#define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x44) /* Slave Configuration Register 1 */ -#define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x48) /* Slave Configuration Register 2 */ -#define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x4C) /* Slave Configuration Register 3 */ -#define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x50) /* Slave Configuration Register 4 */ -#define AT91_MATRIX_SCFG5 (AT91_MATRIX + 0x54) /* Slave Configuration Register 5 */ -#define AT91_MATRIX_SCFG6 (AT91_MATRIX + 0x58) /* Slave Configuration Register 6 */ -#define AT91_MATRIX_SCFG7 (AT91_MATRIX + 0x5C) /* Slave Configuration Register 7 */ +#define AT91_MATRIX_SCFG0 0x40 /* Slave Configuration Register 0 */ +#define AT91_MATRIX_SCFG1 0x44 /* Slave Configuration Register 1 */ +#define AT91_MATRIX_SCFG2 0x48 /* Slave Configuration Register 2 */ +#define AT91_MATRIX_SCFG3 0x4C /* Slave Configuration Register 3 */ +#define AT91_MATRIX_SCFG4 0x50 /* Slave Configuration Register 4 */ +#define AT91_MATRIX_SCFG5 0x54 /* Slave Configuration Register 5 */ +#define AT91_MATRIX_SCFG6 0x58 /* Slave Configuration Register 6 */ +#define AT91_MATRIX_SCFG7 0x5C /* Slave Configuration Register 7 */ #define AT91_MATRIX_SLOT_CYCLE (0xff << 0) /* Maximum Number of Allowed Cycles for a Burst */ #define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */ #define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) @@ -49,22 +49,22 @@ #define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24) #define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24) -#define AT91_MATRIX_PRAS0 (AT91_MATRIX + 0x80) /* Priority Register A for Slave 0 */ -#define AT91_MATRIX_PRBS0 (AT91_MATRIX + 0x84) /* Priority Register B for Slave 0 */ -#define AT91_MATRIX_PRAS1 (AT91_MATRIX + 0x88) /* Priority Register A for Slave 1 */ -#define AT91_MATRIX_PRBS1 (AT91_MATRIX + 0x8C) /* Priority Register B for Slave 1 */ -#define AT91_MATRIX_PRAS2 (AT91_MATRIX + 0x90) /* Priority Register A for Slave 2 */ -#define AT91_MATRIX_PRBS2 (AT91_MATRIX + 0x94) /* Priority Register B for Slave 2 */ -#define AT91_MATRIX_PRAS3 (AT91_MATRIX + 0x98) /* Priority Register A for Slave 3 */ -#define AT91_MATRIX_PRBS3 (AT91_MATRIX + 0x9C) /* Priority Register B for Slave 3 */ -#define AT91_MATRIX_PRAS4 (AT91_MATRIX + 0xA0) /* Priority Register A for Slave 4 */ -#define AT91_MATRIX_PRBS4 (AT91_MATRIX + 0xA4) /* Priority Register B for Slave 4 */ -#define AT91_MATRIX_PRAS5 (AT91_MATRIX + 0xA8) /* Priority Register A for Slave 5 */ -#define AT91_MATRIX_PRBS5 (AT91_MATRIX + 0xAC) /* Priority Register B for Slave 5 */ -#define AT91_MATRIX_PRAS6 (AT91_MATRIX + 0xB0) /* Priority Register A for Slave 6 */ -#define AT91_MATRIX_PRBS6 (AT91_MATRIX + 0xB4) /* Priority Register B for Slave 6 */ -#define AT91_MATRIX_PRAS7 (AT91_MATRIX + 0xB8) /* Priority Register A for Slave 7 */ -#define AT91_MATRIX_PRBS7 (AT91_MATRIX + 0xBC) /* Priority Register B for Slave 7 */ +#define AT91_MATRIX_PRAS0 0x80 /* Priority Register A for Slave 0 */ +#define AT91_MATRIX_PRBS0 0x84 /* Priority Register B for Slave 0 */ +#define AT91_MATRIX_PRAS1 0x88 /* Priority Register A for Slave 1 */ +#define AT91_MATRIX_PRBS1 0x8C /* Priority Register B for Slave 1 */ +#define AT91_MATRIX_PRAS2 0x90 /* Priority Register A for Slave 2 */ +#define AT91_MATRIX_PRBS2 0x94 /* Priority Register B for Slave 2 */ +#define AT91_MATRIX_PRAS3 0x98 /* Priority Register A for Slave 3 */ +#define AT91_MATRIX_PRBS3 0x9C /* Priority Register B for Slave 3 */ +#define AT91_MATRIX_PRAS4 0xA0 /* Priority Register A for Slave 4 */ +#define AT91_MATRIX_PRBS4 0xA4 /* Priority Register B for Slave 4 */ +#define AT91_MATRIX_PRAS5 0xA8 /* Priority Register A for Slave 5 */ +#define AT91_MATRIX_PRBS5 0xAC /* Priority Register B for Slave 5 */ +#define AT91_MATRIX_PRAS6 0xB0 /* Priority Register A for Slave 6 */ +#define AT91_MATRIX_PRBS6 0xB4 /* Priority Register B for Slave 6 */ +#define AT91_MATRIX_PRAS7 0xB8 /* Priority Register A for Slave 7 */ +#define AT91_MATRIX_PRBS7 0xBC /* Priority Register B for Slave 7 */ #define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */ #define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */ #define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */ @@ -75,7 +75,7 @@ #define AT91_MATRIX_M7PR (3 << 28) /* Master 7 Priority */ #define AT91_MATRIX_M8PR (3 << 0) /* Master 8 Priority (in Register B) */ -#define AT91_MATRIX_MRCR (AT91_MATRIX + 0x100) /* Master Remap Control Register */ +#define AT91_MATRIX_MRCR 0x100 /* Master Remap Control Register */ #define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */ #define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */ #define AT91_MATRIX_RCB2 (1 << 2) @@ -86,7 +86,7 @@ #define AT91_MATRIX_RCB7 (1 << 7) #define AT91_MATRIX_RCB8 (1 << 8) -#define AT91_MATRIX_TCMR (AT91_MATRIX + 0x114) /* TCM Configuration Register */ +#define AT91_MATRIX_TCMR 0x114 /* TCM Configuration Register */ #define AT91_MATRIX_ITCM_SIZE (0xf << 0) /* Size of ITCM enabled memory block */ #define AT91_MATRIX_ITCM_0 (0 << 0) #define AT91_MATRIX_ITCM_16 (5 << 0) @@ -96,7 +96,7 @@ #define AT91_MATRIX_DTCM_16 (5 << 4) #define AT91_MATRIX_DTCM_32 (6 << 4) -#define AT91_MATRIX_EBI0CSA (AT91_MATRIX + 0x120) /* EBI0 Chip Select Assignment Register */ +#define AT91_MATRIX_EBI0CSA 0x120 /* EBI0 Chip Select Assignment Register */ #define AT91_MATRIX_EBI0_CS1A (1 << 1) /* Chip Select 1 Assignment */ #define AT91_MATRIX_EBI0_CS1A_SMC (0 << 1) #define AT91_MATRIX_EBI0_CS1A_SDRAMC (1 << 1) @@ -114,7 +114,7 @@ #define AT91_MATRIX_EBI0_VDDIOMSEL_1_8V (0 << 16) #define AT91_MATRIX_EBI0_VDDIOMSEL_3_3V (1 << 16) -#define AT91_MATRIX_EBI1CSA (AT91_MATRIX + 0x124) /* EBI1 Chip Select Assignment Register */ +#define AT91_MATRIX_EBI1CSA 0x124 /* EBI1 Chip Select Assignment Register */ #define AT91_MATRIX_EBI1_CS1A (1 << 1) /* Chip Select 1 Assignment */ #define AT91_MATRIX_EBI1_CS1A_SMC (0 << 1) #define AT91_MATRIX_EBI1_CS1A_SDRAMC (1 << 1) diff --git a/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h b/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h index e2f8da8..0210797 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h +++ b/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h @@ -59,7 +59,6 @@ #define AT91_DDRSDRC_TRP (0xf << 16) /* Row precharge delay */ #define AT91_DDRSDRC_TRRD (0xf << 20) /* Active BankA to BankB */ #define AT91_DDRSDRC_TWTR (0x7 << 24) /* Internal Write to Read delay */ -#define AT91CAP9_DDRSDRC_TWTR (1 << 24) /* Internal Write to Read delay */ #define AT91_DDRSDRC_RED_WRRD (0x1 << 27) /* Reduce Write to Read Delay [SAM9 Only] */ #define AT91_DDRSDRC_TMRD (0xf << 28) /* Load mode to active/refresh delay */ @@ -76,7 +75,6 @@ #define AT91_DDRSDRC_TRTP (0x7 << 12) /* Read to Precharge delay */ #define AT91_DDRSDRC_LPR 0x1C /* Low Power Register */ -#define AT91CAP9_DDRSDRC_LPR 0x18 /* Low Power Register */ #define AT91_DDRSDRC_LPCB (3 << 0) /* Low-power Configurations */ #define AT91_DDRSDRC_LPCB_DISABLE 0 #define AT91_DDRSDRC_LPCB_SELF_REFRESH 1 @@ -94,11 +92,9 @@ #define AT91_DDRSDRC_UPD_MR (3 << 20) /* Update load mode register and extended mode register */ #define AT91_DDRSDRC_MDR 0x20 /* Memory Device Register */ -#define AT91CAP9_DDRSDRC_MDR 0x1C /* Memory Device Register */ #define AT91_DDRSDRC_MD (3 << 0) /* Memory Device Type */ #define AT91_DDRSDRC_MD_SDR 0 #define AT91_DDRSDRC_MD_LOW_POWER_SDR 1 -#define AT91CAP9_DDRSDRC_MD_DDR 2 #define AT91_DDRSDRC_MD_LOW_POWER_DDR 3 #define AT91_DDRSDRC_MD_DDR2 6 /* [SAM9 Only] */ #define AT91_DDRSDRC_DBW (1 << 4) /* Data Bus Width */ @@ -106,16 +102,10 @@ #define AT91_DDRSDRC_DBW_16BITS (1 << 4) #define AT91_DDRSDRC_DLL 0x24 /* DLL Information Register */ -#define AT91CAP9_DDRSDRC_DLL 0x20 /* DLL Information Register */ #define AT91_DDRSDRC_MDINC (1 << 0) /* Master Delay increment */ #define AT91_DDRSDRC_MDDEC (1 << 1) /* Master Delay decrement */ #define AT91_DDRSDRC_MDOVF (1 << 2) /* Master Delay Overflow */ -#define AT91CAP9_DDRSDRC_SDCOVF (1 << 3) /* Slave Delay Correction Overflow */ -#define AT91CAP9_DDRSDRC_SDCUDF (1 << 4) /* Slave Delay Correction Underflow */ -#define AT91CAP9_DDRSDRC_SDERF (1 << 5) /* Slave Delay Correction error */ #define AT91_DDRSDRC_MDVAL (0xff << 8) /* Master Delay value */ -#define AT91CAP9_DDRSDRC_SDVAL (0xff << 16) /* Slave Delay value */ -#define AT91CAP9_DDRSDRC_SDCVAL (0xff << 24) /* Slave Delay Correction value */ #define AT91_DDRSDRC_HS 0x2C /* High Speed Register [SAM9 Only] */ #define AT91_DDRSDRC_DIS_ATCP_RD (1 << 2) /* Anticip read access is disabled */ @@ -131,10 +121,4 @@ #define AT91_DDRSDRC_WPVS (1 << 0) /* Write protect violation status */ #define AT91_DDRSDRC_WPVSRC (0xffff << 8) /* Write protect violation source */ -/* Register access macros */ -#define at91_ramc_read(num, reg) \ - at91_sys_read(AT91_DDRSDRC##num + reg) -#define at91_ramc_write(num, reg, value) \ - at91_sys_write(AT91_DDRSDRC##num + reg, value) - #endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h b/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h index 100f5a5..3d085a9 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h +++ b/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h @@ -82,10 +82,4 @@ #define AT91_SDRAMC_MD_SDRAM 0 #define AT91_SDRAMC_MD_LOW_POWER_SDRAM 1 -/* Register access macros */ -#define at91_ramc_read(num, reg) \ - at91_sys_read(AT91_SDRAMC##num + reg) -#define at91_ramc_write(num, reg, value) \ - at91_sys_write(AT91_SDRAMC##num + reg, value) - #endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h index dd9c95e..d052abc 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9g45.h +++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h @@ -84,17 +84,14 @@ #define AT91SAM9G45_BASE_TC5 0xfffd4080 /* - * System Peripherals (offset from AT91_BASE_SYS) + * System Peripherals */ -#define AT91_DDRSDRC1 (0xffffe400 - AT91_BASE_SYS) -#define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) -#define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS) -#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) -#define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) - #define AT91SAM9G45_BASE_ECC 0xffffe200 +#define AT91SAM9G45_BASE_DDRSDRC1 0xffffe400 +#define AT91SAM9G45_BASE_DDRSDRC0 0xffffe600 #define AT91SAM9G45_BASE_DMA 0xffffec00 #define AT91SAM9G45_BASE_SMC 0xffffe800 +#define AT91SAM9G45_BASE_MATRIX 0xffffea00 #define AT91SAM9G45_BASE_DBGU AT91_BASE_DBGU1 #define AT91SAM9G45_BASE_PIOA 0xfffff200 #define AT91SAM9G45_BASE_PIOB 0xfffff400 @@ -107,6 +104,7 @@ #define AT91SAM9G45_BASE_PIT 0xfffffd30 #define AT91SAM9G45_BASE_WDT 0xfffffd40 #define AT91SAM9G45_BASE_RTC 0xfffffdb0 +#define AT91SAM9G45_BASE_GPBR 0xfffffd60 #define AT91_USART0 AT91SAM9G45_BASE_US0 #define AT91_USART1 AT91SAM9G45_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h index c972d60..b76e2ed 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h +++ b/arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h @@ -15,18 +15,18 @@ #ifndef AT91SAM9G45_MATRIX_H #define AT91SAM9G45_MATRIX_H -#define AT91_MATRIX_MCFG0 (AT91_MATRIX + 0x00) /* Master Configuration Register 0 */ -#define AT91_MATRIX_MCFG1 (AT91_MATRIX + 0x04) /* Master Configuration Register 1 */ -#define AT91_MATRIX_MCFG2 (AT91_MATRIX + 0x08) /* Master Configuration Register 2 */ -#define AT91_MATRIX_MCFG3 (AT91_MATRIX + 0x0C) /* Master Configuration Register 3 */ -#define AT91_MATRIX_MCFG4 (AT91_MATRIX + 0x10) /* Master Configuration Register 4 */ -#define AT91_MATRIX_MCFG5 (AT91_MATRIX + 0x14) /* Master Configuration Register 5 */ -#define AT91_MATRIX_MCFG6 (AT91_MATRIX + 0x18) /* Master Configuration Register 6 */ -#define AT91_MATRIX_MCFG7 (AT91_MATRIX + 0x1C) /* Master Configuration Register 7 */ -#define AT91_MATRIX_MCFG8 (AT91_MATRIX + 0x20) /* Master Configuration Register 8 */ -#define AT91_MATRIX_MCFG9 (AT91_MATRIX + 0x24) /* Master Configuration Register 9 */ -#define AT91_MATRIX_MCFG10 (AT91_MATRIX + 0x28) /* Master Configuration Register 10 */ -#define AT91_MATRIX_MCFG11 (AT91_MATRIX + 0x2C) /* Master Configuration Register 11 */ +#define AT91_MATRIX_MCFG0 0x00 /* Master Configuration Register 0 */ +#define AT91_MATRIX_MCFG1 0x04 /* Master Configuration Register 1 */ +#define AT91_MATRIX_MCFG2 0x08 /* Master Configuration Register 2 */ +#define AT91_MATRIX_MCFG3 0x0C /* Master Configuration Register 3 */ +#define AT91_MATRIX_MCFG4 0x10 /* Master Configuration Register 4 */ +#define AT91_MATRIX_MCFG5 0x14 /* Master Configuration Register 5 */ +#define AT91_MATRIX_MCFG6 0x18 /* Master Configuration Register 6 */ +#define AT91_MATRIX_MCFG7 0x1C /* Master Configuration Register 7 */ +#define AT91_MATRIX_MCFG8 0x20 /* Master Configuration Register 8 */ +#define AT91_MATRIX_MCFG9 0x24 /* Master Configuration Register 9 */ +#define AT91_MATRIX_MCFG10 0x28 /* Master Configuration Register 10 */ +#define AT91_MATRIX_MCFG11 0x2C /* Master Configuration Register 11 */ #define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */ #define AT91_MATRIX_ULBT_INFINITE (0 << 0) #define AT91_MATRIX_ULBT_SINGLE (1 << 0) @@ -37,14 +37,14 @@ #define AT91_MATRIX_ULBT_SIXTYFOUR (6 << 0) #define AT91_MATRIX_ULBT_128 (7 << 0) -#define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x40) /* Slave Configuration Register 0 */ -#define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x44) /* Slave Configuration Register 1 */ -#define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x48) /* Slave Configuration Register 2 */ -#define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x4C) /* Slave Configuration Register 3 */ -#define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x50) /* Slave Configuration Register 4 */ -#define AT91_MATRIX_SCFG5 (AT91_MATRIX + 0x54) /* Slave Configuration Register 5 */ -#define AT91_MATRIX_SCFG6 (AT91_MATRIX + 0x58) /* Slave Configuration Register 6 */ -#define AT91_MATRIX_SCFG7 (AT91_MATRIX + 0x5C) /* Slave Configuration Register 7 */ +#define AT91_MATRIX_SCFG0 0x40 /* Slave Configuration Register 0 */ +#define AT91_MATRIX_SCFG1 0x44 /* Slave Configuration Register 1 */ +#define AT91_MATRIX_SCFG2 0x48 /* Slave Configuration Register 2 */ +#define AT91_MATRIX_SCFG3 0x4C /* Slave Configuration Register 3 */ +#define AT91_MATRIX_SCFG4 0x50 /* Slave Configuration Register 4 */ +#define AT91_MATRIX_SCFG5 0x54 /* Slave Configuration Register 5 */ +#define AT91_MATRIX_SCFG6 0x58 /* Slave Configuration Register 6 */ +#define AT91_MATRIX_SCFG7 0x5C /* Slave Configuration Register 7 */ #define AT91_MATRIX_SLOT_CYCLE (0x1ff << 0) /* Maximum Number of Allowed Cycles for a Burst */ #define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */ #define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) @@ -52,22 +52,22 @@ #define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) #define AT91_MATRIX_FIXED_DEFMSTR (0xf << 18) /* Fixed Index of Default Master */ -#define AT91_MATRIX_PRAS0 (AT91_MATRIX + 0x80) /* Priority Register A for Slave 0 */ -#define AT91_MATRIX_PRBS0 (AT91_MATRIX + 0x84) /* Priority Register B for Slave 0 */ -#define AT91_MATRIX_PRAS1 (AT91_MATRIX + 0x88) /* Priority Register A for Slave 1 */ -#define AT91_MATRIX_PRBS1 (AT91_MATRIX + 0x8C) /* Priority Register B for Slave 1 */ -#define AT91_MATRIX_PRAS2 (AT91_MATRIX + 0x90) /* Priority Register A for Slave 2 */ -#define AT91_MATRIX_PRBS2 (AT91_MATRIX + 0x94) /* Priority Register B for Slave 2 */ -#define AT91_MATRIX_PRAS3 (AT91_MATRIX + 0x98) /* Priority Register A for Slave 3 */ -#define AT91_MATRIX_PRBS3 (AT91_MATRIX + 0x9C) /* Priority Register B for Slave 3 */ -#define AT91_MATRIX_PRAS4 (AT91_MATRIX + 0xA0) /* Priority Register A for Slave 4 */ -#define AT91_MATRIX_PRBS4 (AT91_MATRIX + 0xA4) /* Priority Register B for Slave 4 */ -#define AT91_MATRIX_PRAS5 (AT91_MATRIX + 0xA8) /* Priority Register A for Slave 5 */ -#define AT91_MATRIX_PRBS5 (AT91_MATRIX + 0xAC) /* Priority Register B for Slave 5 */ -#define AT91_MATRIX_PRAS6 (AT91_MATRIX + 0xB0) /* Priority Register A for Slave 6 */ -#define AT91_MATRIX_PRBS6 (AT91_MATRIX + 0xB4) /* Priority Register B for Slave 6 */ -#define AT91_MATRIX_PRAS7 (AT91_MATRIX + 0xB8) /* Priority Register A for Slave 7 */ -#define AT91_MATRIX_PRBS7 (AT91_MATRIX + 0xBC) /* Priority Register B for Slave 7 */ +#define AT91_MATRIX_PRAS0 0x80 /* Priority Register A for Slave 0 */ +#define AT91_MATRIX_PRBS0 0x84 /* Priority Register B for Slave 0 */ +#define AT91_MATRIX_PRAS1 0x88 /* Priority Register A for Slave 1 */ +#define AT91_MATRIX_PRBS1 0x8C /* Priority Register B for Slave 1 */ +#define AT91_MATRIX_PRAS2 0x90 /* Priority Register A for Slave 2 */ +#define AT91_MATRIX_PRBS2 0x94 /* Priority Register B for Slave 2 */ +#define AT91_MATRIX_PRAS3 0x98 /* Priority Register A for Slave 3 */ +#define AT91_MATRIX_PRBS3 0x9C /* Priority Register B for Slave 3 */ +#define AT91_MATRIX_PRAS4 0xA0 /* Priority Register A for Slave 4 */ +#define AT91_MATRIX_PRBS4 0xA4 /* Priority Register B for Slave 4 */ +#define AT91_MATRIX_PRAS5 0xA8 /* Priority Register A for Slave 5 */ +#define AT91_MATRIX_PRBS5 0xAC /* Priority Register B for Slave 5 */ +#define AT91_MATRIX_PRAS6 0xB0 /* Priority Register A for Slave 6 */ +#define AT91_MATRIX_PRBS6 0xB4 /* Priority Register B for Slave 6 */ +#define AT91_MATRIX_PRAS7 0xB8 /* Priority Register A for Slave 7 */ +#define AT91_MATRIX_PRBS7 0xBC /* Priority Register B for Slave 7 */ #define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */ #define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */ #define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */ @@ -81,7 +81,7 @@ #define AT91_MATRIX_M10PR (3 << 8) /* Master 10 Priority (in Register B) */ #define AT91_MATRIX_M11PR (3 << 12) /* Master 11 Priority (in Register B) */ -#define AT91_MATRIX_MRCR (AT91_MATRIX + 0x100) /* Master Remap Control Register */ +#define AT91_MATRIX_MRCR 0x100 /* Master Remap Control Register */ #define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */ #define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */ #define AT91_MATRIX_RCB2 (1 << 2) @@ -95,7 +95,7 @@ #define AT91_MATRIX_RCB10 (1 << 10) #define AT91_MATRIX_RCB11 (1 << 11) -#define AT91_MATRIX_TCMR (AT91_MATRIX + 0x110) /* TCM Configuration Register */ +#define AT91_MATRIX_TCMR 0x110 /* TCM Configuration Register */ #define AT91_MATRIX_ITCM_SIZE (0xf << 0) /* Size of ITCM enabled memory block */ #define AT91_MATRIX_ITCM_0 (0 << 0) #define AT91_MATRIX_ITCM_32 (6 << 0) @@ -107,12 +107,12 @@ #define AT91_MATRIX_TCM_NO_WS (0x0 << 11) #define AT91_MATRIX_TCM_ONE_WS (0x1 << 11) -#define AT91_MATRIX_VIDEO (AT91_MATRIX + 0x118) /* Video Mode Configuration Register */ +#define AT91_MATRIX_VIDEO 0x118 /* Video Mode Configuration Register */ #define AT91C_VDEC_SEL (0x1 << 0) /* Video Mode Selection */ #define AT91C_VDEC_SEL_OFF (0 << 0) #define AT91C_VDEC_SEL_ON (1 << 0) -#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x128) /* EBI Chip Select Assignment Register */ +#define AT91_MATRIX_EBICSA 0x128 /* EBI Chip Select Assignment Register */ #define AT91_MATRIX_EBI_CS1A (1 << 1) /* Chip Select 1 Assignment */ #define AT91_MATRIX_EBI_CS1A_SMC (0 << 1) #define AT91_MATRIX_EBI_CS1A_SDRAMC (1 << 1) @@ -138,13 +138,13 @@ #define AT91_MATRIX_EBI_DDR_IOSR_REDUCED (0 << 18) #define AT91_MATRIX_EBI_DDR_IOSR_NORMAL (1 << 18) -#define AT91_MATRIX_WPMR (AT91_MATRIX + 0x1E4) /* Write Protect Mode Register */ +#define AT91_MATRIX_WPMR 0x1E4 /* Write Protect Mode Register */ #define AT91_MATRIX_WPMR_WPEN (1 << 0) /* Write Protect ENable */ #define AT91_MATRIX_WPMR_WP_WPDIS (0 << 0) #define AT91_MATRIX_WPMR_WP_WPEN (1 << 0) #define AT91_MATRIX_WPMR_WPKEY (0xFFFFFF << 8) /* Write Protect KEY */ -#define AT91_MATRIX_WPSR (AT91_MATRIX + 0x1E8) /* Write Protect Status Register */ +#define AT91_MATRIX_WPSR 0x1E8 /* Write Protect Status Register */ #define AT91_MATRIX_WPSR_WPVS (1 << 0) /* Write Protect Violation Status */ #define AT91_MATRIX_WPSR_NO_WPV (0 << 0) #define AT91_MATRIX_WPSR_WPV (1 << 0) diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h index d7bead7..e0073eb 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9rl.h +++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h @@ -69,15 +69,13 @@ /* * System Peripherals (offset from AT91_BASE_SYS) */ -#define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) -#define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) -#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_SCKCR (0xfffffd50 - AT91_BASE_SYS) -#define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) #define AT91SAM9RL_BASE_DMA 0xffffe600 #define AT91SAM9RL_BASE_ECC 0xffffe800 +#define AT91SAM9RL_BASE_SDRAMC 0xffffea00 #define AT91SAM9RL_BASE_SMC 0xffffec00 +#define AT91SAM9RL_BASE_MATRIX 0xffffee00 #define AT91SAM9RL_BASE_DBGU AT91_BASE_DBGU0 #define AT91SAM9RL_BASE_PIOA 0xfffff400 #define AT91SAM9RL_BASE_PIOB 0xfffff600 @@ -88,6 +86,7 @@ #define AT91SAM9RL_BASE_RTT 0xfffffd20 #define AT91SAM9RL_BASE_PIT 0xfffffd30 #define AT91SAM9RL_BASE_WDT 0xfffffd40 +#define AT91SAM9RL_BASE_GPBR 0xfffffd60 #define AT91SAM9RL_BASE_RTC 0xfffffe00 #define AT91_USART0 AT91SAM9RL_BASE_US0 diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9rl_matrix.h index 5f91490..6d160ada 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9rl_matrix.h +++ b/arch/arm/mach-at91/include/mach/at91sam9rl_matrix.h @@ -14,12 +14,12 @@ #ifndef AT91SAM9RL_MATRIX_H #define AT91SAM9RL_MATRIX_H -#define AT91_MATRIX_MCFG0 (AT91_MATRIX + 0x00) /* Master Configuration Register 0 */ -#define AT91_MATRIX_MCFG1 (AT91_MATRIX + 0x04) /* Master Configuration Register 1 */ -#define AT91_MATRIX_MCFG2 (AT91_MATRIX + 0x08) /* Master Configuration Register 2 */ -#define AT91_MATRIX_MCFG3 (AT91_MATRIX + 0x0C) /* Master Configuration Register 3 */ -#define AT91_MATRIX_MCFG4 (AT91_MATRIX + 0x10) /* Master Configuration Register 4 */ -#define AT91_MATRIX_MCFG5 (AT91_MATRIX + 0x14) /* Master Configuration Register 5 */ +#define AT91_MATRIX_MCFG0 0x00 /* Master Configuration Register 0 */ +#define AT91_MATRIX_MCFG1 0x04 /* Master Configuration Register 1 */ +#define AT91_MATRIX_MCFG2 0x08 /* Master Configuration Register 2 */ +#define AT91_MATRIX_MCFG3 0x0C /* Master Configuration Register 3 */ +#define AT91_MATRIX_MCFG4 0x10 /* Master Configuration Register 4 */ +#define AT91_MATRIX_MCFG5 0x14 /* Master Configuration Register 5 */ #define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */ #define AT91_MATRIX_ULBT_INFINITE (0 << 0) #define AT91_MATRIX_ULBT_SINGLE (1 << 0) @@ -27,12 +27,12 @@ #define AT91_MATRIX_ULBT_EIGHT (3 << 0) #define AT91_MATRIX_ULBT_SIXTEEN (4 << 0) -#define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x40) /* Slave Configuration Register 0 */ -#define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x44) /* Slave Configuration Register 1 */ -#define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x48) /* Slave Configuration Register 2 */ -#define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x4C) /* Slave Configuration Register 3 */ -#define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x50) /* Slave Configuration Register 4 */ -#define AT91_MATRIX_SCFG5 (AT91_MATRIX + 0x54) /* Slave Configuration Register 5 */ +#define AT91_MATRIX_SCFG0 0x40 /* Slave Configuration Register 0 */ +#define AT91_MATRIX_SCFG1 0x44 /* Slave Configuration Register 1 */ +#define AT91_MATRIX_SCFG2 0x48 /* Slave Configuration Register 2 */ +#define AT91_MATRIX_SCFG3 0x4C /* Slave Configuration Register 3 */ +#define AT91_MATRIX_SCFG4 0x50 /* Slave Configuration Register 4 */ +#define AT91_MATRIX_SCFG5 0x54 /* Slave Configuration Register 5 */ #define AT91_MATRIX_SLOT_CYCLE (0xff << 0) /* Maximum Number of Allowed Cycles for a Burst */ #define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */ #define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) @@ -43,12 +43,12 @@ #define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24) #define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24) -#define AT91_MATRIX_PRAS0 (AT91_MATRIX + 0x80) /* Priority Register A for Slave 0 */ -#define AT91_MATRIX_PRAS1 (AT91_MATRIX + 0x88) /* Priority Register A for Slave 1 */ -#define AT91_MATRIX_PRAS2 (AT91_MATRIX + 0x90) /* Priority Register A for Slave 2 */ -#define AT91_MATRIX_PRAS3 (AT91_MATRIX + 0x98) /* Priority Register A for Slave 3 */ -#define AT91_MATRIX_PRAS4 (AT91_MATRIX + 0xA0) /* Priority Register A for Slave 4 */ -#define AT91_MATRIX_PRAS5 (AT91_MATRIX + 0xA8) /* Priority Register A for Slave 5 */ +#define AT91_MATRIX_PRAS0 0x80 /* Priority Register A for Slave 0 */ +#define AT91_MATRIX_PRAS1 0x88 /* Priority Register A for Slave 1 */ +#define AT91_MATRIX_PRAS2 0x90 /* Priority Register A for Slave 2 */ +#define AT91_MATRIX_PRAS3 0x98 /* Priority Register A for Slave 3 */ +#define AT91_MATRIX_PRAS4 0xA0 /* Priority Register A for Slave 4 */ +#define AT91_MATRIX_PRAS5 0xA8 /* Priority Register A for Slave 5 */ #define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */ #define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */ #define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */ @@ -56,7 +56,7 @@ #define AT91_MATRIX_M4PR (3 << 16) /* Master 4 Priority */ #define AT91_MATRIX_M5PR (3 << 20) /* Master 5 Priority */ -#define AT91_MATRIX_MRCR (AT91_MATRIX + 0x100) /* Master Remap Control Register */ +#define AT91_MATRIX_MRCR 0x100 /* Master Remap Control Register */ #define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */ #define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */ #define AT91_MATRIX_RCB2 (1 << 2) @@ -64,7 +64,7 @@ #define AT91_MATRIX_RCB4 (1 << 4) #define AT91_MATRIX_RCB5 (1 << 5) -#define AT91_MATRIX_TCMR (AT91_MATRIX + 0x114) /* TCM Configuration Register */ +#define AT91_MATRIX_TCMR 0x114 /* TCM Configuration Register */ #define AT91_MATRIX_ITCM_SIZE (0xf << 0) /* Size of ITCM enabled memory block */ #define AT91_MATRIX_ITCM_0 (0 << 0) #define AT91_MATRIX_ITCM_16 (5 << 0) @@ -74,7 +74,7 @@ #define AT91_MATRIX_DTCM_16 (5 << 4) #define AT91_MATRIX_DTCM_32 (6 << 4) -#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x120) /* EBI0 Chip Select Assignment Register */ +#define AT91_MATRIX_EBICSA 0x120 /* EBI0 Chip Select Assignment Register */ #define AT91_MATRIX_CS1A (1 << 1) /* Chip Select 1 Assignment */ #define AT91_MATRIX_CS1A_SMC (0 << 1) #define AT91_MATRIX_CS1A_SDRAMC (1 << 1) diff --git a/arch/arm/mach-at91/include/mach/at91sam9x5.h b/arch/arm/mach-at91/include/mach/at91sam9x5.h new file mode 100644 index 0000000..a297a77 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9x5.h @@ -0,0 +1,79 @@ +/* + * Chip-specific header file for the AT91SAM9x5 family + * + * Copyright (C) 2009-2012 Atmel Corporation. + * + * Common definitions. + * Based on AT91SAM9x5 datasheet. + * + * Licensed under GPLv2 or later. + */ + +#ifndef AT91SAM9X5_H +#define AT91SAM9X5_H + +/* + * Peripheral identifiers/interrupts. + */ +#define AT91SAM9X5_ID_PIOAB 2 /* Parallel I/O Controller A and B */ +#define AT91SAM9X5_ID_PIOCD 3 /* Parallel I/O Controller C and D */ +#define AT91SAM9X5_ID_SMD 4 /* SMD Soft Modem (SMD) */ +#define AT91SAM9X5_ID_USART0 5 /* USART 0 */ +#define AT91SAM9X5_ID_USART1 6 /* USART 1 */ +#define AT91SAM9X5_ID_USART2 7 /* USART 2 */ +#define AT91SAM9X5_ID_USART3 8 /* USART 3 */ +#define AT91SAM9X5_ID_TWI0 9 /* Two-Wire Interface 0 */ +#define AT91SAM9X5_ID_TWI1 10 /* Two-Wire Interface 1 */ +#define AT91SAM9X5_ID_TWI2 11 /* Two-Wire Interface 2 */ +#define AT91SAM9X5_ID_MCI0 12 /* High Speed Multimedia Card Interface 0 */ +#define AT91SAM9X5_ID_SPI0 13 /* Serial Peripheral Interface 0 */ +#define AT91SAM9X5_ID_SPI1 14 /* Serial Peripheral Interface 1 */ +#define AT91SAM9X5_ID_UART0 15 /* UART 0 */ +#define AT91SAM9X5_ID_UART1 16 /* UART 1 */ +#define AT91SAM9X5_ID_TCB 17 /* Timer Counter 0, 1, 2, 3, 4 and 5 */ +#define AT91SAM9X5_ID_PWM 18 /* Pulse Width Modulation Controller */ +#define AT91SAM9X5_ID_ADC 19 /* ADC Controller */ +#define AT91SAM9X5_ID_DMA0 20 /* DMA Controller 0 */ +#define AT91SAM9X5_ID_DMA1 21 /* DMA Controller 1 */ +#define AT91SAM9X5_ID_UHPHS 22 /* USB Host High Speed */ +#define AT91SAM9X5_ID_UDPHS 23 /* USB Device High Speed */ +#define AT91SAM9X5_ID_EMAC0 24 /* Ethernet MAC0 */ +#define AT91SAM9X5_ID_LCDC 25 /* LCD Controller */ +#define AT91SAM9X5_ID_ISI 25 /* Image Sensor Interface */ +#define AT91SAM9X5_ID_MCI1 26 /* High Speed Multimedia Card Interface 1 */ +#define AT91SAM9X5_ID_EMAC1 27 /* Ethernet MAC1 */ +#define AT91SAM9X5_ID_SSC 28 /* Synchronous Serial Controller */ +#define AT91SAM9X5_ID_CAN0 29 /* CAN Controller 0 */ +#define AT91SAM9X5_ID_CAN1 30 /* CAN Controller 1 */ +#define AT91SAM9X5_ID_IRQ0 31 /* Advanced Interrupt Controller */ + +/* + * User Peripheral physical base addresses. + */ +#define AT91SAM9X5_BASE_USART0 0xf801c000 +#define AT91SAM9X5_BASE_USART1 0xf8020000 +#define AT91SAM9X5_BASE_USART2 0xf8024000 + +/* + * System Peripherals + */ +#define AT91SAM9X5_BASE_DDRSDRC0 0xffffe800 + +/* + * Base addresses for early serial code (uncompress.h) + */ +#define AT91_DBGU AT91_BASE_DBGU0 +#define AT91_USART0 AT91SAM9X5_BASE_USART0 +#define AT91_USART1 AT91SAM9X5_BASE_USART1 +#define AT91_USART2 AT91SAM9X5_BASE_USART2 + +/* + * Internal Memory. + */ +#define AT91SAM9X5_SRAM_BASE 0x00300000 /* Internal SRAM base address */ +#define AT91SAM9X5_SRAM_SIZE SZ_32K /* Internal SRAM size (32Kb) */ + +#define AT91SAM9X5_ROM_BASE 0x00400000 /* Internal ROM base address */ +#define AT91SAM9X5_ROM_SIZE SZ_64K /* Internal ROM size (64Kb) */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9x5_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9x5_matrix.h new file mode 100644 index 0000000..a606d39 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9x5_matrix.h @@ -0,0 +1,53 @@ +/* + * Matrix-centric header file for the AT91SAM9x5 family + * + * Copyright (C) 2009-2012 Atmel Corporation. + * + * Only EBI related registers. + * Write Protect register definitions may be useful. + * + * Licensed under GPLv2 or later. + */ + +#ifndef AT91SAM9X5_MATRIX_H +#define AT91SAM9X5_MATRIX_H + +#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x120) /* EBI Chip Select Assignment Register */ +#define AT91_MATRIX_EBI_CS1A (1 << 1) /* Chip Select 1 Assignment */ +#define AT91_MATRIX_EBI_CS1A_SMC (0 << 1) +#define AT91_MATRIX_EBI_CS1A_SDRAMC (1 << 1) +#define AT91_MATRIX_EBI_CS3A (1 << 3) /* Chip Select 3 Assignment */ +#define AT91_MATRIX_EBI_CS3A_SMC (0 << 3) +#define AT91_MATRIX_EBI_CS3A_SMC_NANDFLASH (1 << 3) +#define AT91_MATRIX_EBI_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */ +#define AT91_MATRIX_EBI_DBPU_ON (0 << 8) +#define AT91_MATRIX_EBI_DBPU_OFF (1 << 8) +#define AT91_MATRIX_EBI_VDDIOMSEL (1 << 16) /* Memory voltage selection */ +#define AT91_MATRIX_EBI_VDDIOMSEL_1_8V (0 << 16) +#define AT91_MATRIX_EBI_VDDIOMSEL_3_3V (1 << 16) +#define AT91_MATRIX_EBI_EBI_IOSR (1 << 17) /* EBI I/O slew rate selection */ +#define AT91_MATRIX_EBI_EBI_IOSR_REDUCED (0 << 17) +#define AT91_MATRIX_EBI_EBI_IOSR_NORMAL (1 << 17) +#define AT91_MATRIX_EBI_DDR_IOSR (1 << 18) /* DDR2 dedicated port I/O slew rate selection */ +#define AT91_MATRIX_EBI_DDR_IOSR_REDUCED (0 << 18) +#define AT91_MATRIX_EBI_DDR_IOSR_NORMAL (1 << 18) +#define AT91_MATRIX_NFD0_SELECT (1 << 24) /* NAND Flash Data Bus Selection */ +#define AT91_MATRIX_NFD0_ON_D0 (0 << 24) +#define AT91_MATRIX_NFD0_ON_D16 (1 << 24) +#define AT91_MATRIX_DDR_MP_EN (1 << 25) /* DDR Multi-port Enable */ +#define AT91_MATRIX_MP_OFF (0 << 25) +#define AT91_MATRIX_MP_ON (1 << 25) + +#define AT91_MATRIX_WPMR (AT91_MATRIX + 0x1E4) /* Write Protect Mode Register */ +#define AT91_MATRIX_WPMR_WPEN (1 << 0) /* Write Protect ENable */ +#define AT91_MATRIX_WPMR_WP_WPDIS (0 << 0) +#define AT91_MATRIX_WPMR_WP_WPEN (1 << 0) +#define AT91_MATRIX_WPMR_WPKEY (0xFFFFFF << 8) /* Write Protect KEY */ + +#define AT91_MATRIX_WPSR (AT91_MATRIX + 0x1E8) /* Write Protect Status Register */ +#define AT91_MATRIX_WPSR_WPVS (1 << 0) /* Write Protect Violation Status */ +#define AT91_MATRIX_WPSR_NO_WPV (0 << 0) +#define AT91_MATRIX_WPSR_WPV (1 << 0) +#define AT91_MATRIX_WPSR_WPVSRC (0xFFFF << 8) /* Write Protect Violation Source */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91x40.h b/arch/arm/mach-at91/include/mach/at91x40.h index a57829f..9068021 100644 --- a/arch/arm/mach-at91/include/mach/at91x40.h +++ b/arch/arm/mach-at91/include/mach/at91x40.h @@ -28,18 +28,18 @@ #define AT91X40_ID_IRQ2 18 /* External IRQ 2 */ /* - * System Peripherals (offset from AT91_BASE_SYS) + * System Peripherals */ #define AT91_BASE_SYS 0xffc00000 -#define AT91_EBI (0xffe00000 - AT91_BASE_SYS) /* External Bus Interface */ -#define AT91_SF (0xfff00000 - AT91_BASE_SYS) /* Special Function */ -#define AT91_USART1 (0xfffcc000 - AT91_BASE_SYS) /* USART 1 */ -#define AT91_USART0 (0xfffd0000 - AT91_BASE_SYS) /* USART 0 */ -#define AT91_TC (0xfffe0000 - AT91_BASE_SYS) /* Timer Counter */ -#define AT91_PIOA (0xffff0000 - AT91_BASE_SYS) /* PIO Controller A */ -#define AT91_PS (0xffff4000 - AT91_BASE_SYS) /* Power Save */ -#define AT91_WD (0xffff8000 - AT91_BASE_SYS) /* Watchdog Timer */ +#define AT91_EBI 0xffe00000 /* External Bus Interface */ +#define AT91_SF 0xfff00000 /* Special Function */ +#define AT91_USART1 0xfffcc000 /* USART 1 */ +#define AT91_USART0 0xfffd0000 /* USART 0 */ +#define AT91_TC 0xfffe0000 /* Timer Counter */ +#define AT91_PIOA 0xffff0000 /* PIO Controller A */ +#define AT91_PS 0xffff4000 /* Power Save */ +#define AT91_WD 0xffff8000 /* Watchdog Timer */ /* * The AT91x40 series doesn't have a debug unit like the other AT91 parts. diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h index 3b33f07..dc8d6d4 100644 --- a/arch/arm/mach-at91/include/mach/board.h +++ b/arch/arm/mach-at91/include/mach/board.h @@ -107,6 +107,8 @@ struct atmel_nand_data { u8 ale; /* address line number connected to ALE */ u8 cle; /* address line number connected to CLE */ u8 bus_width_16; /* buswidth is 16 bit */ + u8 correction_cap; /* PMECC correction capability */ + u16 sector_size; /* Sector size for PMECC */ struct mtd_partition *parts; unsigned int num_parts; }; @@ -179,7 +181,9 @@ extern void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data); extern void __init at91_add_device_ac97(struct ac97c_platform_data *data); /* ISI */ -extern void __init at91_add_device_isi(void); +struct isi_platform_data; +extern void __init at91_add_device_isi(struct isi_platform_data *data, + bool use_pck_as_mck); /* Touchscreen Controller */ struct at91_tsadcc_data { diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h index f6ce936..0118c33 100644 --- a/arch/arm/mach-at91/include/mach/cpu.h +++ b/arch/arm/mach-at91/include/mach/cpu.h @@ -25,7 +25,6 @@ #define ARCH_ID_AT91SAM9G45MRL 0x819b05a2 /* aka 9G45-ES2 & non ES lots */ #define ARCH_ID_AT91SAM9G45ES 0x819b05a1 /* 9G45-ES (Engineering Sample) */ #define ARCH_ID_AT91SAM9X5 0x819a05a0 -#define ARCH_ID_AT91CAP9 0x039A03A0 #define ARCH_ID_AT91SAM9XE128 0x329973a0 #define ARCH_ID_AT91SAM9XE256 0x329a93a0 @@ -51,10 +50,6 @@ #define ARCH_FAMILY_AT91SAM9 0x01900000 #define ARCH_FAMILY_AT91SAM9XE 0x02900000 -/* PMC revision */ -#define ARCH_REVISION_CAP9_B 0x399 -#define ARCH_REVISION_CAP9_C 0x601 - /* RM9200 type */ #define ARCH_REVISON_9200_BGA (0 << 0) #define ARCH_REVISON_9200_PQFP (1 << 0) @@ -63,9 +58,6 @@ enum at91_soc_type { /* 920T */ AT91_SOC_RM9200, - /* CAP */ - AT91_SOC_CAP9, - /* SAM92xx */ AT91_SOC_SAM9260, AT91_SOC_SAM9261, AT91_SOC_SAM9263, @@ -86,9 +78,6 @@ enum at91_soc_subtype { /* RM9200 */ AT91_SOC_RM9200_BGA, AT91_SOC_RM9200_PQFP, - /* CAP9 */ - AT91_SOC_CAP9_REV_B, AT91_SOC_CAP9_REV_C, - /* SAM9260 */ AT91_SOC_SAM9XE, @@ -195,16 +184,6 @@ static inline int at91_soc_is_detected(void) #define cpu_is_at91sam9x25() (0) #endif -#ifdef CONFIG_ARCH_AT91CAP9 -#define cpu_is_at91cap9() (at91_soc_initdata.type == AT91_SOC_CAP9) -#define cpu_is_at91cap9_revB() (at91_soc_initdata.subtype == AT91_SOC_CAP9_REV_B) -#define cpu_is_at91cap9_revC() (at91_soc_initdata.subtype == AT91_SOC_CAP9_REV_C) -#else -#define cpu_is_at91cap9() (0) -#define cpu_is_at91cap9_revB() (0) -#define cpu_is_at91cap9_revC() (0) -#endif - /* * Since this is ARM, we will never run on any AVR32 CPU. But these * definitions may reduce clutter in common drivers. diff --git a/arch/arm/mach-at91/include/mach/gpio.h b/arch/arm/mach-at91/include/mach/gpio.h index e3fd225..eed465a 100644 --- a/arch/arm/mach-at91/include/mach/gpio.h +++ b/arch/arm/mach-at91/include/mach/gpio.h @@ -191,10 +191,15 @@ extern int __init_or_module at91_set_GPIO_periph(unsigned pin, int use_pullup); extern int __init_or_module at91_set_A_periph(unsigned pin, int use_pullup); extern int __init_or_module at91_set_B_periph(unsigned pin, int use_pullup); +extern int __init_or_module at91_set_C_periph(unsigned pin, int use_pullup); +extern int __init_or_module at91_set_D_periph(unsigned pin, int use_pullup); extern int __init_or_module at91_set_gpio_input(unsigned pin, int use_pullup); extern int __init_or_module at91_set_gpio_output(unsigned pin, int value); extern int __init_or_module at91_set_deglitch(unsigned pin, int is_on); +extern int __init_or_module at91_set_debounce(unsigned pin, int is_on, int div); extern int __init_or_module at91_set_multi_drive(unsigned pin, int is_on); +extern int __init_or_module at91_set_pulldown(unsigned pin, int is_on); +extern int __init_or_module at91_disable_schmitt_trig(unsigned pin); /* callable at any time */ extern int at91_set_gpio_value(unsigned pin, int value); @@ -204,18 +209,6 @@ extern int at91_get_gpio_value(unsigned pin); extern void at91_gpio_suspend(void); extern void at91_gpio_resume(void); -/*-------------------------------------------------------------------------*/ - -/* wrappers for "new style" GPIO calls. the old AT91-specific ones should - * eventually be removed (along with this errno.h inclusion), and the - * gpio request/free calls should probably be implemented. - */ - -#include <asm/errno.h> - -#define gpio_to_irq(gpio) (gpio + NR_AIC_IRQS) -#define irq_to_gpio(irq) (irq - NR_AIC_IRQS) - #endif /* __ASSEMBLY__ */ #endif diff --git a/arch/arm/mach-at91/include/mach/hardware.h b/arch/arm/mach-at91/include/mach/hardware.h index 2d0e4e9..e9e29a6 100644 --- a/arch/arm/mach-at91/include/mach/hardware.h +++ b/arch/arm/mach-at91/include/mach/hardware.h @@ -19,7 +19,7 @@ /* DBGU base */ /* rm9200, 9260/9g20, 9261/9g10, 9rl */ #define AT91_BASE_DBGU0 0xfffff200 -/* 9263, 9g45, cap9 */ +/* 9263, 9g45 */ #define AT91_BASE_DBGU1 0xffffee00 #if defined(CONFIG_ARCH_AT91RM9200) @@ -34,8 +34,8 @@ #include <mach/at91sam9rl.h> #elif defined(CONFIG_ARCH_AT91SAM9G45) #include <mach/at91sam9g45.h> -#elif defined(CONFIG_ARCH_AT91CAP9) -#include <mach/at91cap9.h> +#elif defined(CONFIG_ARCH_AT91SAM9X5) +#include <mach/at91sam9x5.h> #elif defined(CONFIG_ARCH_AT91X40) #include <mach/at91x40.h> #else @@ -59,9 +59,10 @@ /* * On all at91 have the Advanced Interrupt Controller starts at address - * 0xfffff000 + * 0xfffff000 and the Power Management Controller starts at 0xfffffc00 */ #define AT91_AIC 0xfffff000 +#define AT91_PMC 0xfffffc00 /* * Peripheral identifiers/interrupts. diff --git a/arch/arm/mach-at91/include/mach/io.h b/arch/arm/mach-at91/include/mach/io.h index 4ca09ef..4003001 100644 --- a/arch/arm/mach-at91/include/mach/io.h +++ b/arch/arm/mach-at91/include/mach/io.h @@ -28,22 +28,4 @@ #define __io(a) __typesafe_io(a) #define __mem_pci(a) (a) -#ifndef __ASSEMBLY__ - -static inline unsigned int at91_sys_read(unsigned int reg_offset) -{ - void __iomem *addr = (void __iomem *)AT91_VA_BASE_SYS; - - return __raw_readl(addr + reg_offset); -} - -static inline void at91_sys_write(unsigned int reg_offset, unsigned long value) -{ - void __iomem *addr = (void __iomem *)AT91_VA_BASE_SYS; - - __raw_writel(value, addr + reg_offset); -} - -#endif - #endif diff --git a/arch/arm/mach-at91/include/mach/system.h b/arch/arm/mach-at91/include/mach/system.h deleted file mode 100644 index cbd64f3..0000000 --- a/arch/arm/mach-at91/include/mach/system.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * arch/arm/mach-at91/include/mach/system.h - * - * Copyright (C) 2003 SAN People - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -#include <mach/hardware.h> -#include <mach/at91_st.h> -#include <mach/at91_dbgu.h> -#include <mach/at91_pmc.h> - -static inline void arch_idle(void) -{ - /* - * Disable the processor clock. The processor will be automatically - * re-enabled by an interrupt or by a reset. - */ -#ifdef AT91_PS - at91_sys_write(AT91_PS_CR, AT91_PS_CR_CPU); -#else - at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK); -#endif -#ifndef CONFIG_CPU_ARM920T - /* - * Set the processor (CP15) into 'Wait for Interrupt' mode. - * Post-RM9200 processors need this in conjunction with the above - * to save power when idle. - */ - cpu_do_idle(); -#endif -} - -#endif diff --git a/arch/arm/mach-at91/irq.c b/arch/arm/mach-at91/irq.c index be6b639..cfcfcbe 100644 --- a/arch/arm/mach-at91/irq.c +++ b/arch/arm/mach-at91/irq.c @@ -24,6 +24,12 @@ #include <linux/module.h> #include <linux/mm.h> #include <linux/types.h> +#include <linux/irq.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> +#include <linux/irqdomain.h> +#include <linux/err.h> #include <mach/hardware.h> #include <asm/irq.h> @@ -34,22 +40,24 @@ #include <asm/mach/map.h> void __iomem *at91_aic_base; +static struct irq_domain *at91_aic_domain; +static struct device_node *at91_aic_np; static void at91_aic_mask_irq(struct irq_data *d) { /* Disable interrupt on AIC */ - at91_aic_write(AT91_AIC_IDCR, 1 << d->irq); + at91_aic_write(AT91_AIC_IDCR, 1 << d->hwirq); } static void at91_aic_unmask_irq(struct irq_data *d) { /* Enable interrupt on AIC */ - at91_aic_write(AT91_AIC_IECR, 1 << d->irq); + at91_aic_write(AT91_AIC_IECR, 1 << d->hwirq); } unsigned int at91_extern_irq; -#define is_extern_irq(irq) ((1 << (irq)) & at91_extern_irq) +#define is_extern_irq(hwirq) ((1 << (hwirq)) & at91_extern_irq) static int at91_aic_set_type(struct irq_data *d, unsigned type) { @@ -63,13 +71,13 @@ static int at91_aic_set_type(struct irq_data *d, unsigned type) srctype = AT91_AIC_SRCTYPE_RISING; break; case IRQ_TYPE_LEVEL_LOW: - if ((d->irq == AT91_ID_FIQ) || is_extern_irq(d->irq)) /* only supported on external interrupts */ + if ((d->hwirq == AT91_ID_FIQ) || is_extern_irq(d->hwirq)) /* only supported on external interrupts */ srctype = AT91_AIC_SRCTYPE_LOW; else return -EINVAL; break; case IRQ_TYPE_EDGE_FALLING: - if ((d->irq == AT91_ID_FIQ) || is_extern_irq(d->irq)) /* only supported on external interrupts */ + if ((d->hwirq == AT91_ID_FIQ) || is_extern_irq(d->hwirq)) /* only supported on external interrupts */ srctype = AT91_AIC_SRCTYPE_FALLING; else return -EINVAL; @@ -78,8 +86,8 @@ static int at91_aic_set_type(struct irq_data *d, unsigned type) return -EINVAL; } - smr = at91_aic_read(AT91_AIC_SMR(d->irq)) & ~AT91_AIC_SRCTYPE; - at91_aic_write(AT91_AIC_SMR(d->irq), smr | srctype); + smr = at91_aic_read(AT91_AIC_SMR(d->hwirq)) & ~AT91_AIC_SRCTYPE; + at91_aic_write(AT91_AIC_SMR(d->hwirq), smr | srctype); return 0; } @@ -90,13 +98,13 @@ static u32 backups; static int at91_aic_set_wake(struct irq_data *d, unsigned value) { - if (unlikely(d->irq >= 32)) + if (unlikely(d->hwirq >= NR_AIC_IRQS)) return -EINVAL; if (value) - wakeups |= (1 << d->irq); + wakeups |= (1 << d->hwirq); else - wakeups &= ~(1 << d->irq); + wakeups &= ~(1 << d->hwirq); return 0; } @@ -127,46 +135,112 @@ static struct irq_chip at91_aic_chip = { .irq_set_wake = at91_aic_set_wake, }; +static void __init at91_aic_hw_init(unsigned int spu_vector) +{ + int i; + + /* + * Perform 8 End Of Interrupt Command to make sure AIC + * will not Lock out nIRQ + */ + for (i = 0; i < 8; i++) + at91_aic_write(AT91_AIC_EOICR, 0); + + /* + * Spurious Interrupt ID in Spurious Vector Register. + * When there is no current interrupt, the IRQ Vector Register + * reads the value stored in AIC_SPU + */ + at91_aic_write(AT91_AIC_SPU, spu_vector); + + /* No debugging in AIC: Debug (Protect) Control Register */ + at91_aic_write(AT91_AIC_DCR, 0); + + /* Disable and clear all interrupts initially */ + at91_aic_write(AT91_AIC_IDCR, 0xFFFFFFFF); + at91_aic_write(AT91_AIC_ICCR, 0xFFFFFFFF); +} + +#if defined(CONFIG_OF) +static int at91_aic_irq_map(struct irq_domain *h, unsigned int virq, + irq_hw_number_t hw) +{ + /* Put virq number in Source Vector Register */ + at91_aic_write(AT91_AIC_SVR(hw), virq); + + /* Active Low interrupt, without priority */ + at91_aic_write(AT91_AIC_SMR(hw), AT91_AIC_SRCTYPE_LOW); + + irq_set_chip_and_handler(virq, &at91_aic_chip, handle_level_irq); + set_irq_flags(virq, IRQF_VALID | IRQF_PROBE); + + return 0; +} + +static struct irq_domain_ops at91_aic_irq_ops = { + .map = at91_aic_irq_map, + .xlate = irq_domain_xlate_twocell, +}; + +int __init at91_aic_of_init(struct device_node *node, + struct device_node *parent) +{ + at91_aic_base = of_iomap(node, 0); + at91_aic_np = node; + + at91_aic_domain = irq_domain_add_linear(at91_aic_np, NR_AIC_IRQS, + &at91_aic_irq_ops, NULL); + if (!at91_aic_domain) + panic("Unable to add AIC irq domain (DT)\n"); + + irq_set_default_host(at91_aic_domain); + + at91_aic_hw_init(NR_AIC_IRQS); + + return 0; +} +#endif + /* * Initialize the AIC interrupt controller. */ void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS]) { unsigned int i; + int irq_base; at91_aic_base = ioremap(AT91_AIC, 512); - if (!at91_aic_base) - panic("Impossible to ioremap AT91_AIC\n"); + panic("Unable to ioremap AIC registers\n"); + + /* Add irq domain for AIC */ + irq_base = irq_alloc_descs(-1, 0, NR_AIC_IRQS, 0); + if (irq_base < 0) { + WARN(1, "Cannot allocate irq_descs, assuming pre-allocated\n"); + irq_base = 0; + } + at91_aic_domain = irq_domain_add_legacy(at91_aic_np, NR_AIC_IRQS, + irq_base, 0, + &irq_domain_simple_ops, NULL); + + if (!at91_aic_domain) + panic("Unable to add AIC irq domain\n"); + + irq_set_default_host(at91_aic_domain); /* * The IVR is used by macro get_irqnr_and_base to read and verify. * The irq number is NR_AIC_IRQS when a spurious interrupt has occurred. */ for (i = 0; i < NR_AIC_IRQS; i++) { - /* Put irq number in Source Vector Register: */ + /* Put hardware irq number in Source Vector Register: */ at91_aic_write(AT91_AIC_SVR(i), i); /* Active Low interrupt, with the specified priority */ at91_aic_write(AT91_AIC_SMR(i), AT91_AIC_SRCTYPE_LOW | priority[i]); irq_set_chip_and_handler(i, &at91_aic_chip, handle_level_irq); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); - - /* Perform 8 End Of Interrupt Command to make sure AIC will not Lock out nIRQ */ - if (i < 8) - at91_aic_write(AT91_AIC_EOICR, 0); } - /* - * Spurious Interrupt ID in Spurious Vector Register is NR_AIC_IRQS - * When there is no current interrupt, the IRQ Vector Register reads the value stored in AIC_SPU - */ - at91_aic_write(AT91_AIC_SPU, NR_AIC_IRQS); - - /* No debugging in AIC: Debug (Protect) Control Register */ - at91_aic_write(AT91_AIC_DCR, 0); - - /* Disable and clear all interrupts initially */ - at91_aic_write(AT91_AIC_IDCR, 0xFFFFFFFF); - at91_aic_write(AT91_AIC_ICCR, 0xFFFFFFFF); + at91_aic_hw_init(NR_AIC_IRQS); } diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 1606379..6c9d5e6 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -136,7 +136,7 @@ static int at91_pm_verify_clocks(void) unsigned long scsr; int i; - scsr = at91_sys_read(AT91_PMC_SCSR); + scsr = at91_pmc_read(AT91_PMC_SCSR); /* USB must not be using PLLB */ if (cpu_is_at91rm9200()) { @@ -150,11 +150,6 @@ static int at91_pm_verify_clocks(void) pr_err("AT91: PM - Suspend-to-RAM with USB still active\n"); return 0; } - } else if (cpu_is_at91cap9()) { - if ((scsr & AT91CAP9_PMC_UHP) != 0) { - pr_err("AT91: PM - Suspend-to-RAM with USB still active\n"); - return 0; - } } #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS @@ -165,7 +160,7 @@ static int at91_pm_verify_clocks(void) if ((scsr & (AT91_PMC_PCK0 << i)) == 0) continue; - css = at91_sys_read(AT91_PMC_PCKR(i)) & AT91_PMC_CSS; + css = at91_pmc_read(AT91_PMC_PCKR(i)) & AT91_PMC_CSS; if (css != AT91_PMC_CSS_SLOW) { pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css); return 0; @@ -193,23 +188,36 @@ int at91_suspend_entering_slow_clock(void) EXPORT_SYMBOL(at91_suspend_entering_slow_clock); -static void (*slow_clock)(void); +static void (*slow_clock)(void __iomem *pmc, void __iomem *ramc0, + void __iomem *ramc1, int memctrl); #ifdef CONFIG_AT91_SLOW_CLOCK -extern void at91_slow_clock(void); +extern void at91_slow_clock(void __iomem *pmc, void __iomem *ramc0, + void __iomem *ramc1, int memctrl); extern u32 at91_slow_clock_sz; #endif +void __iomem *at91_ramc_base[2]; + +void __init at91_ioremap_ramc(int id, u32 addr, u32 size) +{ + if (id < 0 || id > 1) { + pr_emerg("Wrong RAM controller id (%d), cannot continue\n", id); + BUG(); + } + at91_ramc_base[id] = ioremap(addr, size); + if (!at91_ramc_base[id]) + panic("Impossible to ioremap ramc.%d 0x%x\n", id, addr); +} static int at91_pm_enter(suspend_state_t state) { - u32 saved_lpr; at91_gpio_suspend(); at91_irq_suspend(); pr_debug("AT91: PM - wake mask %08x, pm state %d\n", /* remember all the always-wake irqs */ - (at91_sys_read(AT91_PMC_PCSR) + (at91_pmc_read(AT91_PMC_PCSR) | (1 << AT91_ID_FIQ) | (1 << AT91_ID_SYS) | (at91_extern_irq)) @@ -234,11 +242,18 @@ static int at91_pm_enter(suspend_state_t state) * turning off the main oscillator; reverse on wakeup. */ if (slow_clock) { + int memctrl = AT91_MEMCTRL_SDRAMC; + + if (cpu_is_at91rm9200()) + memctrl = AT91_MEMCTRL_MC; + else if (cpu_is_at91sam9g45()) + memctrl = AT91_MEMCTRL_DDRSDR; #ifdef CONFIG_AT91_SLOW_CLOCK /* copy slow_clock handler to SRAM, and call it */ memcpy(slow_clock, at91_slow_clock, at91_slow_clock_sz); #endif - slow_clock(); + slow_clock(at91_pmc_base, at91_ramc_base[0], + at91_ramc_base[1], memctrl); break; } else { pr_info("AT91: PM - no slow clock mode enabled ...\n"); @@ -259,16 +274,7 @@ static int at91_pm_enter(suspend_state_t state) * For ARM 926 based chips, this requirement is weaker * as at91sam9 can access a RAM in self-refresh mode. */ - asm volatile ( "mov r0, #0\n\t" - "b 1f\n\t" - ".align 5\n\t" - "1: mcr p15, 0, r0, c7, c10, 4\n\t" - : /* no output */ - : /* no input */ - : "r0"); - saved_lpr = sdram_selfrefresh_enable(); - wait_for_interrupt_enable(); - sdram_selfrefresh_disable(saved_lpr); + at91_standby(); break; case PM_SUSPEND_ON: @@ -316,7 +322,7 @@ static int __init at91_pm_init(void) #ifdef CONFIG_ARCH_AT91RM9200 /* AT91RM9200 SDRAM low-power mode cannot be used with self-refresh. */ - at91_sys_write(AT91_SDRAMC_LPR, 0); + at91_ramc_write(0, AT91RM9200_SDRAMC_LPR, 0); #endif suspend_set_ops(&at91_pm_ops); diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h index 7eb40d2..89f56f3 100644 --- a/arch/arm/mach-at91/pm.h +++ b/arch/arm/mach-at91/pm.h @@ -1,5 +1,19 @@ +/* + * AT91 Power Management + * + * Copyright (C) 2005 David Brownell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#ifndef __ARCH_ARM_MACH_AT91_PM +#define __ARCH_ARM_MACH_AT91_PM + +#include <mach/at91_ramc.h> #ifdef CONFIG_ARCH_AT91RM9200 -#include <mach/at91rm9200_mc.h> +#include <mach/at91rm9200_sdramc.h> /* * The AT91RM9200 goes into self-refresh mode with this command, and will @@ -11,51 +25,37 @@ * still in self-refresh is "not recommended", but seems to work. */ -static inline u32 sdram_selfrefresh_enable(void) +static inline void at91rm9200_standby(void) { - u32 saved_lpr = at91_sys_read(AT91_SDRAMC_LPR); - - at91_sys_write(AT91_SDRAMC_LPR, 0); - at91_sys_write(AT91_SDRAMC_SRR, 1); - return saved_lpr; + u32 lpr = at91_ramc_read(0, AT91RM9200_SDRAMC_LPR); + + asm volatile( + "b 1f\n\t" + ".align 5\n\t" + "1: mcr p15, 0, %0, c7, c10, 4\n\t" + " str %0, [%1, %2]\n\t" + " str %3, [%1, %4]\n\t" + " mcr p15, 0, %0, c7, c0, 4\n\t" + " str %5, [%1, %2]" + : + : "r" (0), "r" (AT91_BASE_SYS), "r" (AT91RM9200_SDRAMC_LPR), + "r" (1), "r" (AT91RM9200_SDRAMC_SRR), + "r" (lpr)); } -#define sdram_selfrefresh_disable(saved_lpr) at91_sys_write(AT91_SDRAMC_LPR, saved_lpr) -#define wait_for_interrupt_enable() asm volatile ("mcr p15, 0, %0, c7, c0, 4" \ - : : "r" (0)) - -#elif defined(CONFIG_ARCH_AT91CAP9) -#include <mach/at91sam9_ddrsdr.h> - - -static inline u32 sdram_selfrefresh_enable(void) -{ - u32 saved_lpr, lpr; - - saved_lpr = at91_ramc_read(0, AT91CAP9_DDRSDRC_LPR); - - lpr = saved_lpr & ~AT91_DDRSDRC_LPCB; - at91_ramc_write(0, AT91CAP9_DDRSDRC_LPR, lpr | AT91_DDRSDRC_LPCB_SELF_REFRESH); - return saved_lpr; -} - -#define sdram_selfrefresh_disable(saved_lpr) at91_ramc_write(0, AT91CAP9_DDRSDRC_LPR, saved_lpr) -#define wait_for_interrupt_enable() cpu_do_idle() +#define at91_standby at91rm9200_standby #elif defined(CONFIG_ARCH_AT91SAM9G45) -#include <mach/at91sam9_ddrsdr.h> /* We manage both DDRAM/SDRAM controllers, we need more than one value to * remember. */ -static u32 saved_lpr1; - -static inline u32 sdram_selfrefresh_enable(void) +static inline void at91sam9g45_standby(void) { - /* Those tow values allow us to delay self-refresh activation + /* Those two values allow us to delay self-refresh activation * to the maximum. */ u32 lpr0, lpr1; - u32 saved_lpr0; + u32 saved_lpr0, saved_lpr1; saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR); lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB; @@ -69,18 +69,15 @@ static inline u32 sdram_selfrefresh_enable(void) at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0); at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1); - return saved_lpr0; + cpu_do_idle(); + + at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0); + at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1); } -#define sdram_selfrefresh_disable(saved_lpr0) \ - do { \ - at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0); \ - at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1); \ - } while (0) -#define wait_for_interrupt_enable() cpu_do_idle() +#define at91_standby at91sam9g45_standby #else -#include <mach/at91sam9_sdramc.h> #ifdef CONFIG_ARCH_AT91SAM9263 /* @@ -90,18 +87,23 @@ static inline u32 sdram_selfrefresh_enable(void) #warning Assuming EB1 SDRAM controller is *NOT* used #endif -static inline u32 sdram_selfrefresh_enable(void) +static inline void at91sam9_standby(void) { u32 saved_lpr, lpr; saved_lpr = at91_ramc_read(0, AT91_SDRAMC_LPR); lpr = saved_lpr & ~AT91_SDRAMC_LPCB; - at91_ramc_write(0, AT91_SDRAMC_LPR, lpr | AT91_SDRAMC_LPCB_SELF_REFRESH); - return saved_lpr; + at91_ramc_write(0, AT91_SDRAMC_LPR, lpr | + AT91_SDRAMC_LPCB_SELF_REFRESH); + + cpu_do_idle(); + + at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr); } -#define sdram_selfrefresh_disable(saved_lpr) at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr) -#define wait_for_interrupt_enable() cpu_do_idle() +#define at91_standby at91sam9_standby + +#endif #endif diff --git a/arch/arm/mach-at91/pm_slowclock.S b/arch/arm/mach-at91/pm_slowclock.S index 92dfb84..db54521 100644 --- a/arch/arm/mach-at91/pm_slowclock.S +++ b/arch/arm/mach-at91/pm_slowclock.S @@ -15,15 +15,7 @@ #include <linux/linkage.h> #include <mach/hardware.h> #include <mach/at91_pmc.h> - -#if defined(CONFIG_ARCH_AT91RM9200) -#include <mach/at91rm9200_mc.h> -#elif defined(CONFIG_ARCH_AT91CAP9) \ - || defined(CONFIG_ARCH_AT91SAM9G45) -#include <mach/at91sam9_ddrsdr.h> -#else -#include <mach/at91sam9_sdramc.h> -#endif +#include <mach/at91_ramc.h> #ifdef CONFIG_ARCH_AT91SAM9263 @@ -47,17 +39,23 @@ #define PLLALOCK_TIMEOUT 1000 #define PLLBLOCK_TIMEOUT 1000 +pmc .req r0 +sdramc .req r1 +ramc1 .req r2 +memctrl .req r3 +tmp1 .req r4 +tmp2 .req r5 /* * Wait until master clock is ready (after switching master clock source) */ .macro wait_mckrdy - mov r4, #MCKRDY_TIMEOUT -1: sub r4, r4, #1 - cmp r4, #0 + mov tmp2, #MCKRDY_TIMEOUT +1: sub tmp2, tmp2, #1 + cmp tmp2, #0 beq 2f - ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)] - tst r3, #AT91_PMC_MCKRDY + ldr tmp1, [pmc, #AT91_PMC_SR] + tst tmp1, #AT91_PMC_MCKRDY beq 1b 2: .endm @@ -66,12 +64,12 @@ * Wait until master oscillator has stabilized. */ .macro wait_moscrdy - mov r4, #MOSCRDY_TIMEOUT -1: sub r4, r4, #1 - cmp r4, #0 + mov tmp2, #MOSCRDY_TIMEOUT +1: sub tmp2, tmp2, #1 + cmp tmp2, #0 beq 2f - ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)] - tst r3, #AT91_PMC_MOSCS + ldr tmp1, [pmc, #AT91_PMC_SR] + tst tmp1, #AT91_PMC_MOSCS beq 1b 2: .endm @@ -80,12 +78,12 @@ * Wait until PLLA has locked. */ .macro wait_pllalock - mov r4, #PLLALOCK_TIMEOUT -1: sub r4, r4, #1 - cmp r4, #0 + mov tmp2, #PLLALOCK_TIMEOUT +1: sub tmp2, tmp2, #1 + cmp tmp2, #0 beq 2f - ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)] - tst r3, #AT91_PMC_LOCKA + ldr tmp1, [pmc, #AT91_PMC_SR] + tst tmp1, #AT91_PMC_LOCKA beq 1b 2: .endm @@ -94,80 +92,98 @@ * Wait until PLLB has locked. */ .macro wait_pllblock - mov r4, #PLLBLOCK_TIMEOUT -1: sub r4, r4, #1 - cmp r4, #0 + mov tmp2, #PLLBLOCK_TIMEOUT +1: sub tmp2, tmp2, #1 + cmp tmp2, #0 beq 2f - ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)] - tst r3, #AT91_PMC_LOCKB + ldr tmp1, [pmc, #AT91_PMC_SR] + tst tmp1, #AT91_PMC_LOCKB beq 1b 2: .endm .text +/* void at91_slow_clock(void __iomem *pmc, void __iomem *sdramc, + * void __iomem *ramc1, int memctrl) + */ ENTRY(at91_slow_clock) /* Save registers on stack */ - stmfd sp!, {r0 - r12, lr} + stmfd sp!, {r4 - r12, lr} /* * Register usage: - * R1 = Base address of AT91_PMC - * R2 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS) - * R3 = temporary register + * R0 = Base address of AT91_PMC + * R1 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS) + * R2 = Base address of second RAM Controller or 0 if not present + * R3 = Memory controller * R4 = temporary register - * R5 = Base address of second RAM Controller or 0 if not present + * R5 = temporary register */ - ldr r1, .at91_va_base_pmc - ldr r2, .at91_va_base_sdramc - ldr r5, .at91_va_base_ramc1 /* Drain write buffer */ - mov r0, #0 - mcr p15, 0, r0, c7, c10, 4 + mov tmp1, #0 + mcr p15, 0, tmp1, c7, c10, 4 + + cmp memctrl, #AT91_MEMCTRL_MC + bne ddr_sr_enable -#ifdef CONFIG_ARCH_AT91RM9200 + /* + * at91rm9200 Memory controller + */ /* Put SDRAM in self-refresh mode */ - mov r3, #1 - str r3, [r2, #AT91_SDRAMC_SRR] -#elif defined(CONFIG_ARCH_AT91CAP9) \ - || defined(CONFIG_ARCH_AT91SAM9G45) + mov tmp1, #1 + str tmp1, [sdramc, #AT91RM9200_SDRAMC_SRR] + b sdr_sr_done + + /* + * DDRSDR Memory controller + */ +ddr_sr_enable: + cmp memctrl, #AT91_MEMCTRL_DDRSDR + bne sdr_sr_enable /* prepare for DDRAM self-refresh mode */ - ldr r3, [r2, #AT91_DDRSDRC_LPR] - str r3, .saved_sam9_lpr - bic r3, #AT91_DDRSDRC_LPCB - orr r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH + ldr tmp1, [sdramc, #AT91_DDRSDRC_LPR] + str tmp1, .saved_sam9_lpr + bic tmp1, #AT91_DDRSDRC_LPCB + orr tmp1, #AT91_DDRSDRC_LPCB_SELF_REFRESH /* figure out if we use the second ram controller */ - cmp r5, #0 - ldrne r4, [r5, #AT91_DDRSDRC_LPR] - strne r4, .saved_sam9_lpr1 - bicne r4, #AT91_DDRSDRC_LPCB - orrne r4, #AT91_DDRSDRC_LPCB_SELF_REFRESH + cmp ramc1, #0 + ldrne tmp2, [ramc1, #AT91_DDRSDRC_LPR] + strne tmp2, .saved_sam9_lpr1 + bicne tmp2, #AT91_DDRSDRC_LPCB + orrne tmp2, #AT91_DDRSDRC_LPCB_SELF_REFRESH /* Enable DDRAM self-refresh mode */ - str r3, [r2, #AT91_DDRSDRC_LPR] - strne r4, [r5, #AT91_DDRSDRC_LPR] -#else + str tmp1, [sdramc, #AT91_DDRSDRC_LPR] + strne tmp2, [ramc1, #AT91_DDRSDRC_LPR] + + b sdr_sr_done + + /* + * SDRAMC Memory controller + */ +sdr_sr_enable: /* Enable SDRAM self-refresh mode */ - ldr r3, [r2, #AT91_SDRAMC_LPR] - str r3, .saved_sam9_lpr + ldr tmp1, [sdramc, #AT91_SDRAMC_LPR] + str tmp1, .saved_sam9_lpr - bic r3, #AT91_SDRAMC_LPCB - orr r3, #AT91_SDRAMC_LPCB_SELF_REFRESH - str r3, [r2, #AT91_SDRAMC_LPR] -#endif + bic tmp1, #AT91_SDRAMC_LPCB + orr tmp1, #AT91_SDRAMC_LPCB_SELF_REFRESH + str tmp1, [sdramc, #AT91_SDRAMC_LPR] +sdr_sr_done: /* Save Master clock setting */ - ldr r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)] - str r3, .saved_mckr + ldr tmp1, [pmc, #AT91_PMC_MCKR] + str tmp1, .saved_mckr /* * Set the Master clock source to slow clock */ - bic r3, r3, #AT91_PMC_CSS - str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)] + bic tmp1, tmp1, #AT91_PMC_CSS + str tmp1, [pmc, #AT91_PMC_MCKR] wait_mckrdy @@ -177,61 +193,61 @@ ENTRY(at91_slow_clock) * * See AT91RM9200 errata #27 and #28 for details. */ - mov r3, #0 - str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)] + mov tmp1, #0 + str tmp1, [pmc, #AT91_PMC_MCKR] wait_mckrdy #endif /* Save PLLA setting and disable it */ - ldr r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)] - str r3, .saved_pllar + ldr tmp1, [pmc, #AT91_CKGR_PLLAR] + str tmp1, .saved_pllar - mov r3, #AT91_PMC_PLLCOUNT - orr r3, r3, #(1 << 29) /* bit 29 always set */ - str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)] + mov tmp1, #AT91_PMC_PLLCOUNT + orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */ + str tmp1, [pmc, #AT91_CKGR_PLLAR] /* Save PLLB setting and disable it */ - ldr r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)] - str r3, .saved_pllbr + ldr tmp1, [pmc, #AT91_CKGR_PLLBR] + str tmp1, .saved_pllbr - mov r3, #AT91_PMC_PLLCOUNT - str r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)] + mov tmp1, #AT91_PMC_PLLCOUNT + str tmp1, [pmc, #AT91_CKGR_PLLBR] /* Turn off the main oscillator */ - ldr r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)] - bic r3, r3, #AT91_PMC_MOSCEN - str r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)] + ldr tmp1, [pmc, #AT91_CKGR_MOR] + bic tmp1, tmp1, #AT91_PMC_MOSCEN + str tmp1, [pmc, #AT91_CKGR_MOR] /* Wait for interrupt */ - mcr p15, 0, r0, c7, c0, 4 + mcr p15, 0, tmp1, c7, c0, 4 /* Turn on the main oscillator */ - ldr r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)] - orr r3, r3, #AT91_PMC_MOSCEN - str r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)] + ldr tmp1, [pmc, #AT91_CKGR_MOR] + orr tmp1, tmp1, #AT91_PMC_MOSCEN + str tmp1, [pmc, #AT91_CKGR_MOR] wait_moscrdy /* Restore PLLB setting */ - ldr r3, .saved_pllbr - str r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)] + ldr tmp1, .saved_pllbr + str tmp1, [pmc, #AT91_CKGR_PLLBR] - tst r3, #(AT91_PMC_MUL & 0xff0000) + tst tmp1, #(AT91_PMC_MUL & 0xff0000) bne 1f - tst r3, #(AT91_PMC_MUL & ~0xff0000) + tst tmp1, #(AT91_PMC_MUL & ~0xff0000) beq 2f 1: wait_pllblock 2: /* Restore PLLA setting */ - ldr r3, .saved_pllar - str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)] + ldr tmp1, .saved_pllar + str tmp1, [pmc, #AT91_CKGR_PLLAR] - tst r3, #(AT91_PMC_MUL & 0xff0000) + tst tmp1, #(AT91_PMC_MUL & 0xff0000) bne 3f - tst r3, #(AT91_PMC_MUL & ~0xff0000) + tst tmp1, #(AT91_PMC_MUL & ~0xff0000) beq 4f 3: wait_pllalock @@ -244,11 +260,11 @@ ENTRY(at91_slow_clock) * * See AT91RM9200 errata #27 and #28 for details. */ - ldr r3, .saved_mckr - tst r3, #AT91_PMC_PRES + ldr tmp1, .saved_mckr + tst tmp1, #AT91_PMC_PRES beq 2f - and r3, r3, #AT91_PMC_PRES - str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)] + and tmp1, tmp1, #AT91_PMC_PRES + str tmp1, [pmc, #AT91_PMC_MCKR] wait_mckrdy #endif @@ -256,32 +272,45 @@ ENTRY(at91_slow_clock) /* * Restore master clock setting */ -2: ldr r3, .saved_mckr - str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)] +2: ldr tmp1, .saved_mckr + str tmp1, [pmc, #AT91_PMC_MCKR] wait_mckrdy -#ifdef CONFIG_ARCH_AT91RM9200 - /* Do nothing - self-refresh is automatically disabled. */ -#elif defined(CONFIG_ARCH_AT91CAP9) \ - || defined(CONFIG_ARCH_AT91SAM9G45) + /* + * at91rm9200 Memory controller + * Do nothing - self-refresh is automatically disabled. + */ + cmp memctrl, #AT91_MEMCTRL_MC + beq ram_restored + + /* + * DDRSDR Memory controller + */ + cmp memctrl, #AT91_MEMCTRL_DDRSDR + bne sdr_en_restore /* Restore LPR on AT91 with DDRAM */ - ldr r3, .saved_sam9_lpr - str r3, [r2, #AT91_DDRSDRC_LPR] + ldr tmp1, .saved_sam9_lpr + str tmp1, [sdramc, #AT91_DDRSDRC_LPR] /* if we use the second ram controller */ - cmp r5, #0 - ldrne r4, .saved_sam9_lpr1 - strne r4, [r5, #AT91_DDRSDRC_LPR] + cmp ramc1, #0 + ldrne tmp2, .saved_sam9_lpr1 + strne tmp2, [ramc1, #AT91_DDRSDRC_LPR] + + b ram_restored -#else + /* + * SDRAMC Memory controller + */ +sdr_en_restore: /* Restore LPR on AT91 with SDRAM */ - ldr r3, .saved_sam9_lpr - str r3, [r2, #AT91_SDRAMC_LPR] -#endif + ldr tmp1, .saved_sam9_lpr + str tmp1, [sdramc, #AT91_SDRAMC_LPR] +ram_restored: /* Restore registers, and return */ - ldmfd sp!, {r0 - r12, pc} + ldmfd sp!, {r4 - r12, pc} .saved_mckr: @@ -299,27 +328,5 @@ ENTRY(at91_slow_clock) .saved_sam9_lpr1: .word 0 -.at91_va_base_pmc: - .word AT91_VA_BASE_SYS + AT91_PMC - -#ifdef CONFIG_ARCH_AT91RM9200 -.at91_va_base_sdramc: - .word AT91_VA_BASE_SYS -#elif defined(CONFIG_ARCH_AT91CAP9) \ - || defined(CONFIG_ARCH_AT91SAM9G45) -.at91_va_base_sdramc: - .word AT91_VA_BASE_SYS + AT91_DDRSDRC0 -#else -.at91_va_base_sdramc: - .word AT91_VA_BASE_SYS + AT91_SDRAMC0 -#endif - -.at91_va_base_ramc1: -#if defined(CONFIG_ARCH_AT91SAM9G45) - .word AT91_VA_BASE_SYS + AT91_DDRSDRC1 -#else - .word 0 -#endif - ENTRY(at91_slow_clock_sz) .word .-at91_slow_clock diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c index 69d3fc4..372396c 100644 --- a/arch/arm/mach-at91/setup.c +++ b/arch/arm/mach-at91/setup.c @@ -86,20 +86,6 @@ static void __init soc_detect(u32 dbgu_base) socid = cidr & ~AT91_CIDR_VERSION; switch (socid) { - case ARCH_ID_AT91CAP9: { -#ifdef CONFIG_AT91_PMC_UNIT - u32 pmc_ver = at91_sys_read(AT91_PMC_VER); - - if (pmc_ver == ARCH_REVISION_CAP9_B) - at91_soc_initdata.subtype = AT91_SOC_CAP9_REV_B; - else if (pmc_ver == ARCH_REVISION_CAP9_C) - at91_soc_initdata.subtype = AT91_SOC_CAP9_REV_C; -#endif - at91_soc_initdata.type = AT91_SOC_CAP9; - at91_boot_soc = at91cap9_soc; - break; - } - case ARCH_ID_AT91RM9200: at91_soc_initdata.type = AT91_SOC_RM9200; at91_boot_soc = at91rm9200_soc; @@ -200,7 +186,6 @@ static void __init soc_detect(u32 dbgu_base) static const char *soc_name[] = { [AT91_SOC_RM9200] = "at91rm9200", - [AT91_SOC_CAP9] = "at91cap9", [AT91_SOC_SAM9260] = "at91sam9260", [AT91_SOC_SAM9261] = "at91sam9261", [AT91_SOC_SAM9263] = "at91sam9263", @@ -221,8 +206,6 @@ EXPORT_SYMBOL(at91_get_soc_type); static const char *soc_subtype_name[] = { [AT91_SOC_RM9200_BGA] = "at91rm9200 BGA", [AT91_SOC_RM9200_PQFP] = "at91rm9200 PQFP", - [AT91_SOC_CAP9_REV_B] = "at91cap9 revB", - [AT91_SOC_CAP9_REV_C] = "at91cap9 revC", [AT91_SOC_SAM9XE] = "at91sam9xe", [AT91_SOC_SAM9G45ES] = "at91sam9g45es", [AT91_SOC_SAM9M10] = "at91sam9m10", @@ -293,6 +276,15 @@ void __init at91_ioremap_rstc(u32 base_addr) panic("Impossible to ioremap at91_rstc_base\n"); } +void __iomem *at91_matrix_base; + +void __init at91_ioremap_matrix(u32 base_addr) +{ + at91_matrix_base = ioremap(base_addr, 512); + if (!at91_matrix_base) + panic("Impossible to ioremap at91_matrix_base\n"); +} + void __init at91_initialize(unsigned long main_clock) { at91_boot_soc.ioremap_registers(); diff --git a/arch/arm/mach-at91/soc.h b/arch/arm/mach-at91/soc.h index 4588ae6..5db4aa4 100644 --- a/arch/arm/mach-at91/soc.h +++ b/arch/arm/mach-at91/soc.h @@ -13,7 +13,6 @@ struct at91_init_soc { }; extern struct at91_init_soc at91_boot_soc; -extern struct at91_init_soc at91cap9_soc; extern struct at91_init_soc at91rm9200_soc; extern struct at91_init_soc at91sam9260_soc; extern struct at91_init_soc at91sam9261_soc; @@ -27,10 +26,6 @@ static inline int at91_soc_is_enabled(void) return at91_boot_soc.init != NULL; } -#if !defined(CONFIG_ARCH_AT91CAP9) -#define at91cap9_soc at91_boot_soc -#endif - #if !defined(CONFIG_ARCH_AT91RM9200) #define at91rm9200_soc at91_boot_soc #endif diff --git a/arch/arm/mach-bcmring/core.c b/arch/arm/mach-bcmring/core.c index 6b67b7e..22e4e0a 100644 --- a/arch/arm/mach-bcmring/core.c +++ b/arch/arm/mach-bcmring/core.c @@ -52,27 +52,8 @@ #include <mach/csp/chipcHw_inline.h> #include <mach/csp/tmrHw_reg.h> -#define AMBA_DEVICE(name, initname, base, plat, size) \ -static struct amba_device name##_device = { \ - .dev = { \ - .coherent_dma_mask = ~0, \ - .init_name = initname, \ - .platform_data = plat \ - }, \ - .res = { \ - .start = MM_ADDR_IO_##base, \ - .end = MM_ADDR_IO_##base + (size) - 1, \ - .flags = IORESOURCE_MEM \ - }, \ - .dma_mask = ~0, \ - .irq = { \ - IRQ_##base \ - } \ -} - - -AMBA_DEVICE(uartA, "uarta", UARTA, NULL, SZ_4K); -AMBA_DEVICE(uartB, "uartb", UARTB, NULL, SZ_4K); +static AMBA_APB_DEVICE(uartA, "uarta", MM_ADDR_IO_UARTA, { IRQ_UARTA }, NULL); +static AMBA_APB_DEVICE(uartB, "uartb", MM_ADDR_IO_UARTB, { IRQ_UARTB }, NULL); static struct clk pll1_clk = { .name = "PLL1", diff --git a/arch/arm/mach-bcmring/include/mach/system.h b/arch/arm/mach-bcmring/include/mach/system.h deleted file mode 100644 index cb78250..0000000 --- a/arch/arm/mach-bcmring/include/mach/system.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * - * Copyright (C) 1999 ARM Limited - * Copyright (C) 2000 Deep Blue Solutions Ltd - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static inline void arch_idle(void) -{ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/mach-clps711x/common.c b/arch/arm/mach-clps711x/common.c index ab1711b..8736c1a 100644 --- a/arch/arm/mach-clps711x/common.c +++ b/arch/arm/mach-clps711x/common.c @@ -225,3 +225,19 @@ void clps711x_restart(char mode, const char *cmd) { soft_restart(0); } + +static void clps711x_idle(void) +{ + clps_writel(1, HALT); + __asm__ __volatile__( + "mov r0, r0\n\ + mov r0, r0"); +} + +static int __init clps711x_idle_init(void) +{ + arm_pm_idle = clps711x_idle; + return 0; +} + +arch_initcall(clps711x_idle_init); diff --git a/arch/arm/mach-clps711x/include/mach/system.h b/arch/arm/mach-clps711x/include/mach/system.h deleted file mode 100644 index 23d6ef8..0000000 --- a/arch/arm/mach-clps711x/include/mach/system.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * arch/arm/mach-clps711x/include/mach/system.h - * - * Copyright (C) 2000 Deep Blue Solutions Ltd - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -#include <linux/io.h> -#include <mach/hardware.h> -#include <asm/hardware/clps7111.h> - -static inline void arch_idle(void) -{ - clps_writel(1, HALT); - __asm__ __volatile__( - "mov r0, r0\n\ - mov r0, r0"); -} - -#endif diff --git a/arch/arm/mach-cns3xxx/include/mach/system.h b/arch/arm/mach-cns3xxx/include/mach/system.h deleted file mode 100644 index 9e56b7d..0000000 --- a/arch/arm/mach-cns3xxx/include/mach/system.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2000 Deep Blue Solutions Ltd - * Copyright 2003 ARM Limited - * Copyright 2008 Cavium Networks - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, Version 2, as - * published by the Free Software Foundation. - */ - -#ifndef __MACH_SYSTEM_H -#define __MACH_SYSTEM_H - -#include <asm/proc-fns.h> - -static inline void arch_idle(void) -{ - /* - * This should do all the clock switching - * and wait for interrupt tricks - */ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/mach-davinci/include/mach/system.h b/arch/arm/mach-davinci/include/mach/system.h deleted file mode 100644 index fcb7a01..0000000 --- a/arch/arm/mach-davinci/include/mach/system.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * DaVinci system defines - * - * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com> - * - * 2007 (c) MontaVista Software, Inc. This file is licensed under - * the terms of the GNU General Public License version 2. This program - * is licensed "as is" without any warranty of any kind, whether express - * or implied. - */ -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -#include <mach/common.h> - -static inline void arch_idle(void) -{ - cpu_do_idle(); -} - -#endif /* __ASM_ARCH_SYSTEM_H */ diff --git a/arch/arm/mach-dove/include/mach/system.h b/arch/arm/mach-dove/include/mach/system.h deleted file mode 100644 index 3027954..0000000 --- a/arch/arm/mach-dove/include/mach/system.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * arch/arm/mach-dove/include/mach/system.h - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static inline void arch_idle(void) -{ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c index 294aad0..804c912 100644 --- a/arch/arm/mach-ebsa110/core.c +++ b/arch/arm/mach-ebsa110/core.c @@ -271,8 +271,33 @@ static struct platform_device *ebsa110_devices[] = { &am79c961_device, }; +/* + * EBSA110 idling methodology: + * + * We can not execute the "wait for interrupt" instruction since that + * will stop our MCLK signal (which provides the clock for the glue + * logic, and therefore the timer interrupt). + * + * Instead, we spin, polling the IRQ_STAT register for the occurrence + * of any interrupt with core clock down to the memory clock. + */ +static void ebsa110_idle(void) +{ + const char *irq_stat = (char *)0xff000000; + + /* disable clock switching */ + asm volatile ("mcr p15, 0, ip, c15, c2, 2" : : : "cc"); + + /* wait for an interrupt to occur */ + while (!*irq_stat); + + /* enable clock switching */ + asm volatile ("mcr p15, 0, ip, c15, c1, 2" : : : "cc"); +} + static int __init ebsa110_init(void) { + arm_pm_idle = ebsa110_idle; return platform_add_devices(ebsa110_devices, ARRAY_SIZE(ebsa110_devices)); } diff --git a/arch/arm/mach-ebsa110/include/mach/system.h b/arch/arm/mach-ebsa110/include/mach/system.h deleted file mode 100644 index 2e4af65..0000000 --- a/arch/arm/mach-ebsa110/include/mach/system.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * arch/arm/mach-ebsa110/include/mach/system.h - * - * Copyright (C) 1996-2000 Russell King. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -/* - * EBSA110 idling methodology: - * - * We can not execute the "wait for interrupt" instruction since that - * will stop our MCLK signal (which provides the clock for the glue - * logic, and therefore the timer interrupt). - * - * Instead, we spin, polling the IRQ_STAT register for the occurrence - * of any interrupt with core clock down to the memory clock. - */ -static inline void arch_idle(void) -{ - const char *irq_stat = (char *)0xff000000; - - /* disable clock switching */ - asm volatile ("mcr p15, 0, ip, c15, c2, 2" : : : "cc"); - - /* wait for an interrupt to occur */ - while (!*irq_stat); - - /* enable clock switching */ - asm volatile ("mcr p15, 0, ip, c15, c1, 2" : : : "cc"); -} - -#endif diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index 24203f9..903edb0 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c @@ -279,48 +279,14 @@ static struct amba_pl010_data ep93xx_uart_data = { .set_mctrl = ep93xx_uart_set_mctrl, }; -static struct amba_device uart1_device = { - .dev = { - .init_name = "apb:uart1", - .platform_data = &ep93xx_uart_data, - }, - .res = { - .start = EP93XX_UART1_PHYS_BASE, - .end = EP93XX_UART1_PHYS_BASE + 0x0fff, - .flags = IORESOURCE_MEM, - }, - .irq = { IRQ_EP93XX_UART1, NO_IRQ }, - .periphid = 0x00041010, -}; - -static struct amba_device uart2_device = { - .dev = { - .init_name = "apb:uart2", - .platform_data = &ep93xx_uart_data, - }, - .res = { - .start = EP93XX_UART2_PHYS_BASE, - .end = EP93XX_UART2_PHYS_BASE + 0x0fff, - .flags = IORESOURCE_MEM, - }, - .irq = { IRQ_EP93XX_UART2, NO_IRQ }, - .periphid = 0x00041010, -}; +static AMBA_APB_DEVICE(uart1, "apb:uart1", 0x00041010, EP93XX_UART1_PHYS_BASE, + { IRQ_EP93XX_UART1 }, &ep93xx_uart_data); -static struct amba_device uart3_device = { - .dev = { - .init_name = "apb:uart3", - .platform_data = &ep93xx_uart_data, - }, - .res = { - .start = EP93XX_UART3_PHYS_BASE, - .end = EP93XX_UART3_PHYS_BASE + 0x0fff, - .flags = IORESOURCE_MEM, - }, - .irq = { IRQ_EP93XX_UART3, NO_IRQ }, - .periphid = 0x00041010, -}; +static AMBA_APB_DEVICE(uart2, "apb:uart2", 0x00041010, EP93XX_UART2_PHYS_BASE, + { IRQ_EP93XX_UART2 }, &ep93xx_uart_data); +static AMBA_APB_DEVICE(uart3, "apb:uart3", 0x00041010, EP93XX_UART3_PHYS_BASE, + { IRQ_EP93XX_UART3 }, &ep93xx_uart_data); static struct resource ep93xx_rtc_resource[] = { { diff --git a/arch/arm/mach-ep93xx/include/mach/system.h b/arch/arm/mach-ep93xx/include/mach/system.h deleted file mode 100644 index b5bec7c..0000000 --- a/arch/arm/mach-ep93xx/include/mach/system.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * arch/arm/mach-ep93xx/include/mach/system.h - */ -static inline void arch_idle(void) -{ - cpu_do_idle(); -} diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c index c59e188..93fa2d53 100644 --- a/arch/arm/mach-exynos/common.c +++ b/arch/arm/mach-exynos/common.c @@ -201,14 +201,6 @@ static struct map_desc exynos4_iodesc1[] __initdata = { }, }; -static void exynos_idle(void) -{ - if (!need_resched()) - cpu_do_idle(); - - local_irq_enable(); -} - void exynos4_restart(char mode, const char *cmd) { __raw_writel(0x1, S5P_SWRESET); @@ -402,7 +394,7 @@ void __init exynos4_init_irq(void) gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000; if (!of_have_populated_dt()) - gic_init_bases(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU, gic_bank_offset); + gic_init_bases(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU, gic_bank_offset, NULL); #ifdef CONFIG_OF else of_irq_init(exynos4_dt_irq_match); @@ -467,10 +459,6 @@ early_initcall(exynos4_l2x0_cache_init); int __init exynos_init(void) { printk(KERN_INFO "EXYNOS: Initializing architecture\n"); - - /* set idle function */ - pm_idle = exynos_idle; - return device_register(&exynos4_dev); } diff --git a/arch/arm/mach-exynos/dma.c b/arch/arm/mach-exynos/dma.c index b10fcd2..91370de 100644 --- a/arch/arm/mach-exynos/dma.c +++ b/arch/arm/mach-exynos/dma.c @@ -74,21 +74,8 @@ struct dma_pl330_platdata exynos4_pdma0_pdata = { .peri_id = pdma0_peri, }; -struct amba_device exynos4_device_pdma0 = { - .dev = { - .init_name = "dma-pl330.0", - .dma_mask = &dma_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &exynos4_pdma0_pdata, - }, - .res = { - .start = EXYNOS4_PA_PDMA0, - .end = EXYNOS4_PA_PDMA0 + SZ_4K, - .flags = IORESOURCE_MEM, - }, - .irq = {IRQ_PDMA0, NO_IRQ}, - .periphid = 0x00041330, -}; +AMBA_AHB_DEVICE(exynos4_pdma0, "dma-pl330.0", 0x00041330, EXYNOS4_PA_PDMA0, + {IRQ_PDMA0}, &exynos4_pdma0_pdata); u8 pdma1_peri[] = { DMACH_PCM0_RX, @@ -123,21 +110,8 @@ struct dma_pl330_platdata exynos4_pdma1_pdata = { .peri_id = pdma1_peri, }; -struct amba_device exynos4_device_pdma1 = { - .dev = { - .init_name = "dma-pl330.1", - .dma_mask = &dma_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &exynos4_pdma1_pdata, - }, - .res = { - .start = EXYNOS4_PA_PDMA1, - .end = EXYNOS4_PA_PDMA1 + SZ_4K, - .flags = IORESOURCE_MEM, - }, - .irq = {IRQ_PDMA1, NO_IRQ}, - .periphid = 0x00041330, -}; +AMBA_AHB_DEVICE(exynos4_pdma1, "dma-pl330.1", 0x00041330, EXYNOS4_PA_PDMA1, + {IRQ_PDMA1}, &exynos4_pdma1_pdata); static int __init exynos4_dma_init(void) { @@ -146,11 +120,11 @@ static int __init exynos4_dma_init(void) dma_cap_set(DMA_SLAVE, exynos4_pdma0_pdata.cap_mask); dma_cap_set(DMA_CYCLIC, exynos4_pdma0_pdata.cap_mask); - amba_device_register(&exynos4_device_pdma0, &iomem_resource); + amba_device_register(&exynos4_pdma0_device, &iomem_resource); dma_cap_set(DMA_SLAVE, exynos4_pdma1_pdata.cap_mask); dma_cap_set(DMA_CYCLIC, exynos4_pdma1_pdata.cap_mask); - amba_device_register(&exynos4_device_pdma1, &iomem_resource); + amba_device_register(&exynos4_pdma1_device, &iomem_resource); return 0; } diff --git a/arch/arm/mach-exynos/include/mach/system.h b/arch/arm/mach-exynos/include/mach/system.h deleted file mode 100644 index 0063a6d..0000000 --- a/arch/arm/mach-exynos/include/mach/system.h +++ /dev/null @@ -1,20 +0,0 @@ -/* linux/arch/arm/mach-exynos4/include/mach/system.h - * - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * EXYNOS4 - system support header - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H __FILE__ - -static void arch_idle(void) -{ - /* nothing here yet */ -} -#endif /* __ASM_ARCH_SYSTEM_H */ diff --git a/arch/arm/mach-footbridge/include/mach/system.h b/arch/arm/mach-footbridge/include/mach/system.h deleted file mode 100644 index a174a58..0000000 --- a/arch/arm/mach-footbridge/include/mach/system.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/arm/mach-footbridge/include/mach/system.h - * - * Copyright (C) 1996-1999 Russell King. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -static inline void arch_idle(void) -{ - cpu_do_idle(); -} diff --git a/arch/arm/mach-gemini/Makefile b/arch/arm/mach-gemini/Makefile index c5b24b9..7355c0b 100644 --- a/arch/arm/mach-gemini/Makefile +++ b/arch/arm/mach-gemini/Makefile @@ -4,7 +4,7 @@ # Object file lists. -obj-y := irq.o mm.o time.o devices.o gpio.o +obj-y := irq.o mm.o time.o devices.o gpio.o idle.o # Board-specific support obj-$(CONFIG_MACH_NAS4220B) += board-nas4220b.o diff --git a/arch/arm/mach-gemini/idle.c b/arch/arm/mach-gemini/idle.c new file mode 100644 index 0000000..92bbd6b --- /dev/null +++ b/arch/arm/mach-gemini/idle.c @@ -0,0 +1,29 @@ +/* + * arch/arm/mach-gemini/idle.c + */ + +#include <linux/init.h> +#include <asm/system.h> +#include <asm/proc-fns.h> + +static void gemini_idle(void) +{ + /* + * Because of broken hardware we have to enable interrupts or the CPU + * will never wakeup... Acctualy it is not very good to enable + * interrupts first since scheduler can miss a tick, but there is + * no other way around this. Platforms that needs it for power saving + * should call enable_hlt() in init code, since by default it is + * disabled. + */ + local_irq_enable(); + cpu_do_idle(); +} + +static int __init gemini_idle_init(void) +{ + arm_pm_idle = gemini_idle; + return 0; +} + +arch_initcall(gemini_idle_init); diff --git a/arch/arm/mach-gemini/include/mach/system.h b/arch/arm/mach-gemini/include/mach/system.h index 4d9c1f8..a33b5a1 100644 --- a/arch/arm/mach-gemini/include/mach/system.h +++ b/arch/arm/mach-gemini/include/mach/system.h @@ -14,20 +14,6 @@ #include <mach/hardware.h> #include <mach/global_reg.h> -static inline void arch_idle(void) -{ - /* - * Because of broken hardware we have to enable interrupts or the CPU - * will never wakeup... Acctualy it is not very good to enable - * interrupts here since scheduler can miss a tick, but there is - * no other way around this. Platforms that needs it for power saving - * should call enable_hlt() in init code, since by default it is - * disabled. - */ - local_irq_enable(); - cpu_do_idle(); -} - static inline void arch_reset(char mode, const char *cmd) { __raw_writel(RESET_GLOBAL | RESET_CPU1, diff --git a/arch/arm/mach-gemini/irq.c b/arch/arm/mach-gemini/irq.c index 9485a8f..ca70e5f 100644 --- a/arch/arm/mach-gemini/irq.c +++ b/arch/arm/mach-gemini/irq.c @@ -73,8 +73,8 @@ void __init gemini_init_irq(void) unsigned int i, mode = 0, level = 0; /* - * Disable arch_idle() by default since it is buggy - * For more info see arch/arm/mach-gemini/include/mach/system.h + * Disable the idle handler by default since it is buggy + * For more info see arch/arm/mach-gemini/idle.c */ disable_hlt(); diff --git a/arch/arm/mach-h720x/common.c b/arch/arm/mach-h720x/common.c index f8a2f6b..e756d1a 100644 --- a/arch/arm/mach-h720x/common.c +++ b/arch/arm/mach-h720x/common.c @@ -247,3 +247,21 @@ void h720x_restart(char mode, const char *cmd) { CPU_REG (PMU_BASE, PMU_STAT) |= PMU_WARMRESET; } + +static void h720x__idle(void) +{ + CPU_REG (PMU_BASE, PMU_MODE) = PMU_MODE_IDLE; + nop(); + nop(); + CPU_REG (PMU_BASE, PMU_MODE) = PMU_MODE_RUN; + nop(); + nop(); +} + +static int __init h720x_idle_init(void) +{ + arm_pm_idle = h720x__idle; + return 0; +} + +arch_initcall(h720x_idle_init); diff --git a/arch/arm/mach-h720x/include/mach/system.h b/arch/arm/mach-h720x/include/mach/system.h deleted file mode 100644 index 16ac46e..0000000 --- a/arch/arm/mach-h720x/include/mach/system.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * arch/arm/mach-h720x/include/mach/system.h - * - * Copyright (C) 2001-2002 Jungjun Kim, Hynix Semiconductor Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * arch/arm/mach-h720x/include/mach/system.h - * - */ - -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H -#include <mach/hardware.h> - -static void arch_idle(void) -{ - CPU_REG (PMU_BASE, PMU_MODE) = PMU_MODE_IDLE; - nop(); - nop(); - CPU_REG (PMU_BASE, PMU_MODE) = PMU_MODE_RUN; - nop(); - nop(); -} - -#endif diff --git a/arch/arm/mach-highbank/include/mach/system.h b/arch/arm/mach-highbank/include/mach/system.h deleted file mode 100644 index b1d8b5f..0000000 --- a/arch/arm/mach-highbank/include/mach/system.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2010-2011 Calxeda, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see <http://www.gnu.org/licenses/>. - */ -#ifndef __MACH_SYSTEM_H -#define __MACH_SYSTEM_H - -static inline void arch_idle(void) -{ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 4defb97b..85433b9 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -376,6 +376,14 @@ config MACH_IMX27IPCAM Include support for IMX27 IPCAM platform. This includes specific configurations for the board and its peripherals. +config MACH_IMX27_DT + bool "Support i.MX27 platforms from device tree" + select SOC_IMX27 + select USE_OF + help + Include support for Freescale i.MX27 based platforms + using the device tree for discovery + endif if ARCH_IMX_V6_V7 diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 55db9c4..4ffeca7 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -41,6 +41,7 @@ obj-$(CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD) += eukrea_mbimx27-baseboard.o obj-$(CONFIG_MACH_PCA100) += mach-pca100.o obj-$(CONFIG_MACH_MXT_TD60) += mach-mxt_td60.o obj-$(CONFIG_MACH_IMX27IPCAM) += mach-imx27ipcam.o +obj-$(CONFIG_MACH_IMX27_DT) += imx27-dt.o # i.MX31 based machines obj-$(CONFIG_MACH_MX31ADS) += mach-mx31ads.o diff --git a/arch/arm/mach-imx/Makefile.boot b/arch/arm/mach-imx/Makefile.boot index 6dfdbcc..3851d8a 100644 --- a/arch/arm/mach-imx/Makefile.boot +++ b/arch/arm/mach-imx/Makefile.boot @@ -38,5 +38,8 @@ zreladdr-$(CONFIG_SOC_IMX6Q) += 0x10008000 params_phys-$(CONFIG_SOC_IMX6Q) := 0x10000100 initrd_phys-$(CONFIG_SOC_IMX6Q) := 0x10800000 +dtb-$(CONFIG_MACH_IMX51_DT) += imx51-babbage.dtb +dtb-$(CONFIG_MACH_IMX53_DT) += imx53-ard.dtb imx53-evk.dtb \ + imx53-qsb.dtb imx53-smd.dtb dtb-$(CONFIG_SOC_IMX6Q) += imx6q-arm2.dtb \ imx6q-sabrelite.dtb diff --git a/arch/arm/mach-imx/clock-imx27.c b/arch/arm/mach-imx/clock-imx27.c index 88fe00a..01ae3a4 100644 --- a/arch/arm/mach-imx/clock-imx27.c +++ b/arch/arm/mach-imx/clock-imx27.c @@ -22,6 +22,7 @@ #include <linux/io.h> #include <linux/module.h> #include <linux/clkdev.h> +#include <linux/of.h> #include <asm/div64.h> @@ -764,3 +765,20 @@ int __init mx27_clocks_init(unsigned long fref) return 0; } +#ifdef CONFIG_OF +int __init mx27_clocks_init_dt(void) +{ + struct device_node *np; + u32 fref = 26000000; /* default */ + + for_each_compatible_node(np, NULL, "fixed-clock") { + if (!of_device_is_compatible(np, "fsl,imx-osc26m")) + continue; + + if (!of_property_read_u32(np, "clock-frequency", &fref)) + break; + } + + return mx27_clocks_init(fref); +} +#endif diff --git a/arch/arm/mach-imx/imx27-dt.c b/arch/arm/mach-imx/imx27-dt.c new file mode 100644 index 0000000..861ceb8 --- /dev/null +++ b/arch/arm/mach-imx/imx27-dt.c @@ -0,0 +1,89 @@ +/* + * Copyright 2012 Sascha Hauer, Pengutronix + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include <linux/irq.h> +#include <linux/irqdomain.h> +#include <linux/of_irq.h> +#include <linux/of_platform.h> +#include <asm/mach/arch.h> +#include <asm/mach/time.h> +#include <mach/common.h> +#include <mach/mx27.h> + +static const struct of_dev_auxdata imx27_auxdata_lookup[] __initconst = { + OF_DEV_AUXDATA("fsl,imx27-uart", MX27_UART1_BASE_ADDR, "imx21-uart.0", NULL), + OF_DEV_AUXDATA("fsl,imx27-uart", MX27_UART2_BASE_ADDR, "imx21-uart.1", NULL), + OF_DEV_AUXDATA("fsl,imx27-uart", MX27_UART3_BASE_ADDR, "imx21-uart.2", NULL), + OF_DEV_AUXDATA("fsl,imx27-fec", MX27_FEC_BASE_ADDR, "imx27-fec.0", NULL), + OF_DEV_AUXDATA("fsl,imx27-i2c", MX27_I2C1_BASE_ADDR, "imx-i2c.0", NULL), + OF_DEV_AUXDATA("fsl,imx27-i2c", MX27_I2C2_BASE_ADDR, "imx-i2c.1", NULL), + OF_DEV_AUXDATA("fsl,imx27-cspi", MX27_CSPI1_BASE_ADDR, "imx27-cspi.0", NULL), + OF_DEV_AUXDATA("fsl,imx27-cspi", MX27_CSPI2_BASE_ADDR, "imx27-cspi.1", NULL), + OF_DEV_AUXDATA("fsl,imx27-cspi", MX27_CSPI3_BASE_ADDR, "imx27-cspi.2", NULL), + OF_DEV_AUXDATA("fsl,imx27-wdt", MX27_WDOG_BASE_ADDR, "imx2-wdt.0", NULL), + { /* sentinel */ } +}; + +static int __init imx27_avic_add_irq_domain(struct device_node *np, + struct device_node *interrupt_parent) +{ + irq_domain_add_simple(np, 0); + return 0; +} + +static int __init imx27_gpio_add_irq_domain(struct device_node *np, + struct device_node *interrupt_parent) +{ + static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS; + + irq_domain_add_simple(np, gpio_irq_base); + + return 0; +} + +static const struct of_device_id imx27_irq_match[] __initconst = { + { .compatible = "fsl,imx27-avic", .data = imx27_avic_add_irq_domain, }, + { .compatible = "fsl,imx27-gpio", .data = imx27_gpio_add_irq_domain, }, + { /* sentinel */ } +}; + +static void __init imx27_dt_init(void) +{ + of_irq_init(imx27_irq_match); + + of_platform_populate(NULL, of_default_bus_match_table, + imx27_auxdata_lookup, NULL); +} + +static void __init imx27_timer_init(void) +{ + mx27_clocks_init_dt(); +} + +static struct sys_timer imx27_timer = { + .init = imx27_timer_init, +}; + +static const char *imx27_dt_board_compat[] __initdata = { + "fsl,imx27", + NULL +}; + +DT_MACHINE_START(IMX27_DT, "Freescale i.MX27 (Device Tree Support)") + .map_io = mx27_map_io, + .init_early = imx27_init_early, + .init_irq = mx27_init_irq, + .handle_irq = imx27_handle_irq, + .timer = &imx27_timer, + .init_machine = imx27_dt_init, + .dt_compat = imx27_dt_board_compat, + .restart = mxc_restart, +MACHINE_END diff --git a/arch/arm/mach-imx/imx51-dt.c b/arch/arm/mach-imx/imx51-dt.c index e6bad17..5cca573 100644 --- a/arch/arm/mach-imx/imx51-dt.c +++ b/arch/arm/mach-imx/imx51-dt.c @@ -47,7 +47,7 @@ static const struct of_dev_auxdata imx51_auxdata_lookup[] __initconst = { static int __init imx51_tzic_add_irq_domain(struct device_node *np, struct device_node *interrupt_parent) { - irq_domain_add_simple(np, 0); + irq_domain_add_legacy(np, 128, 0, 0, &irq_domain_simple_ops, NULL); return 0; } @@ -57,7 +57,7 @@ static int __init imx51_gpio_add_irq_domain(struct device_node *np, static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS; gpio_irq_base -= 32; - irq_domain_add_simple(np, gpio_irq_base); + irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops, NULL); return 0; } @@ -104,6 +104,7 @@ static struct sys_timer imx51_timer = { static const char *imx51_dt_board_compat[] __initdata = { "fsl,imx51-babbage", + "fsl,imx51", NULL }; diff --git a/arch/arm/mach-imx/imx53-dt.c b/arch/arm/mach-imx/imx53-dt.c index 05ebb3e..4172279 100644 --- a/arch/arm/mach-imx/imx53-dt.c +++ b/arch/arm/mach-imx/imx53-dt.c @@ -51,7 +51,7 @@ static const struct of_dev_auxdata imx53_auxdata_lookup[] __initconst = { static int __init imx53_tzic_add_irq_domain(struct device_node *np, struct device_node *interrupt_parent) { - irq_domain_add_simple(np, 0); + irq_domain_add_legacy(np, 128, 0, 0, &irq_domain_simple_ops, NULL); return 0; } @@ -61,7 +61,7 @@ static int __init imx53_gpio_add_irq_domain(struct device_node *np, static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS; gpio_irq_base -= 32; - irq_domain_add_simple(np, gpio_irq_base); + irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops, NULL); return 0; } @@ -114,6 +114,7 @@ static const char *imx53_dt_board_compat[] __initdata = { "fsl,imx53-evk", "fsl,imx53-qsb", "fsl,imx53-smd", + "fsl,imx53", NULL }; diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index c257281..379b1a9 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -97,7 +97,8 @@ static int __init imx6q_gpio_add_irq_domain(struct device_node *np, static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS; gpio_irq_base -= 32; - irq_domain_add_simple(np, gpio_irq_base); + irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops, + NULL); return 0; } @@ -128,6 +129,7 @@ static struct sys_timer imx6q_timer = { static const char *imx6q_dt_compat[] __initdata = { "fsl,imx6q-arm2", "fsl,imx6q-sabrelite", + "fsl,imx6q", NULL, }; diff --git a/arch/arm/mach-imx/mm-imx3.c b/arch/arm/mach-imx/mm-imx3.c index 31807d2..8404ee7 100644 --- a/arch/arm/mach-imx/mm-imx3.c +++ b/arch/arm/mach-imx/mm-imx3.c @@ -34,31 +34,29 @@ static void imx3_idle(void) { unsigned long reg = 0; - if (!need_resched()) - __asm__ __volatile__( - /* disable I and D cache */ - "mrc p15, 0, %0, c1, c0, 0\n" - "bic %0, %0, #0x00001000\n" - "bic %0, %0, #0x00000004\n" - "mcr p15, 0, %0, c1, c0, 0\n" - /* invalidate I cache */ - "mov %0, #0\n" - "mcr p15, 0, %0, c7, c5, 0\n" - /* clear and invalidate D cache */ - "mov %0, #0\n" - "mcr p15, 0, %0, c7, c14, 0\n" - /* WFI */ - "mov %0, #0\n" - "mcr p15, 0, %0, c7, c0, 4\n" - "nop\n" "nop\n" "nop\n" "nop\n" - "nop\n" "nop\n" "nop\n" - /* enable I and D cache */ - "mrc p15, 0, %0, c1, c0, 0\n" - "orr %0, %0, #0x00001000\n" - "orr %0, %0, #0x00000004\n" - "mcr p15, 0, %0, c1, c0, 0\n" - : "=r" (reg)); - local_irq_enable(); + __asm__ __volatile__( + /* disable I and D cache */ + "mrc p15, 0, %0, c1, c0, 0\n" + "bic %0, %0, #0x00001000\n" + "bic %0, %0, #0x00000004\n" + "mcr p15, 0, %0, c1, c0, 0\n" + /* invalidate I cache */ + "mov %0, #0\n" + "mcr p15, 0, %0, c7, c5, 0\n" + /* clear and invalidate D cache */ + "mov %0, #0\n" + "mcr p15, 0, %0, c7, c14, 0\n" + /* WFI */ + "mov %0, #0\n" + "mcr p15, 0, %0, c7, c0, 4\n" + "nop\n" "nop\n" "nop\n" "nop\n" + "nop\n" "nop\n" "nop\n" + /* enable I and D cache */ + "mrc p15, 0, %0, c1, c0, 0\n" + "orr %0, %0, #0x00001000\n" + "orr %0, %0, #0x00000004\n" + "mcr p15, 0, %0, c1, c0, 0\n" + : "=r" (reg)); } static void __iomem *imx3_ioremap(unsigned long phys_addr, size_t size, @@ -134,8 +132,8 @@ void __init imx31_init_early(void) { mxc_set_cpu_type(MXC_CPU_MX31); mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR)); - pm_idle = imx3_idle; imx_ioremap = imx3_ioremap; + arm_pm_idle = imx3_idle; } void __init mx31_init_irq(void) @@ -197,7 +195,7 @@ void __init imx35_init_early(void) mxc_set_cpu_type(MXC_CPU_MX35); mxc_iomux_v3_init(MX35_IO_ADDRESS(MX35_IOMUXC_BASE_ADDR)); mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR)); - pm_idle = imx3_idle; + arm_pm_idle = imx3_idle; imx_ioremap = imx3_ioremap; } diff --git a/arch/arm/mach-imx/mm-imx5.c b/arch/arm/mach-imx/mm-imx5.c index bc17dfe..49549a7 100644 --- a/arch/arm/mach-imx/mm-imx5.c +++ b/arch/arm/mach-imx/mm-imx5.c @@ -26,23 +26,17 @@ static struct clk *gpc_dvfs_clk; static void imx5_idle(void) { - if (!need_resched()) { - /* gpc clock is needed for SRPG */ - if (gpc_dvfs_clk == NULL) { - gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs"); - if (IS_ERR(gpc_dvfs_clk)) - goto err0; - } - clk_enable(gpc_dvfs_clk); - mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF); - if (tzic_enable_wake()) - goto err1; - cpu_do_idle(); -err1: - clk_disable(gpc_dvfs_clk); + /* gpc clock is needed for SRPG */ + if (gpc_dvfs_clk == NULL) { + gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs"); + if (IS_ERR(gpc_dvfs_clk)) + return; } -err0: - local_irq_enable(); + clk_enable(gpc_dvfs_clk); + mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF); + if (tzic_enable_wake() != 0) + cpu_do_idle(); + clk_disable(gpc_dvfs_clk); } /* @@ -108,7 +102,7 @@ void __init imx51_init_early(void) mxc_set_cpu_type(MXC_CPU_MX51); mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR)); mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG1_BASE_ADDR)); - pm_idle = imx5_idle; + arm_pm_idle = imx5_idle; } void __init imx53_init_early(void) diff --git a/arch/arm/mach-imx/pm-imx27.c b/arch/arm/mach-imx/pm-imx27.c index e455d2f..6fcffa7 100644 --- a/arch/arm/mach-imx/pm-imx27.c +++ b/arch/arm/mach-imx/pm-imx27.c @@ -10,7 +10,6 @@ #include <linux/kernel.h> #include <linux/suspend.h> #include <linux/io.h> -#include <mach/system.h> #include <mach/hardware.h> static int mx27_suspend_enter(suspend_state_t state) @@ -23,7 +22,7 @@ static int mx27_suspend_enter(suspend_state_t state) cscr &= 0xFFFFFFFC; __raw_writel(cscr, MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR)); /* Executes WFI */ - arch_idle(); + cpu_do_idle(); break; default: diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index 019f0ab..15b87f2 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -35,67 +35,23 @@ static struct amba_pl010_data integrator_uart_data; -static struct amba_device rtc_device = { - .dev = { - .init_name = "mb:15", - }, - .res = { - .start = INTEGRATOR_RTC_BASE, - .end = INTEGRATOR_RTC_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = { IRQ_RTCINT, NO_IRQ }, -}; +#define INTEGRATOR_RTC_IRQ { IRQ_RTCINT } +#define INTEGRATOR_UART0_IRQ { IRQ_UARTINT0 } +#define INTEGRATOR_UART1_IRQ { IRQ_UARTINT1 } +#define KMI0_IRQ { IRQ_KMIINT0 } +#define KMI1_IRQ { IRQ_KMIINT1 } -static struct amba_device uart0_device = { - .dev = { - .init_name = "mb:16", - .platform_data = &integrator_uart_data, - }, - .res = { - .start = INTEGRATOR_UART0_BASE, - .end = INTEGRATOR_UART0_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = { IRQ_UARTINT0, NO_IRQ }, -}; +static AMBA_APB_DEVICE(rtc, "mb:15", 0, + INTEGRATOR_RTC_BASE, INTEGRATOR_RTC_IRQ, NULL); -static struct amba_device uart1_device = { - .dev = { - .init_name = "mb:17", - .platform_data = &integrator_uart_data, - }, - .res = { - .start = INTEGRATOR_UART1_BASE, - .end = INTEGRATOR_UART1_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = { IRQ_UARTINT1, NO_IRQ }, -}; +static AMBA_APB_DEVICE(uart0, "mb:16", 0, + INTEGRATOR_UART0_BASE, INTEGRATOR_UART0_IRQ, &integrator_uart_data); -static struct amba_device kmi0_device = { - .dev = { - .init_name = "mb:18", - }, - .res = { - .start = KMI0_BASE, - .end = KMI0_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = { IRQ_KMIINT0, NO_IRQ }, -}; +static AMBA_APB_DEVICE(uart1, "mb:17", 0, + INTEGRATOR_UART1_BASE, INTEGRATOR_UART1_IRQ, &integrator_uart_data); -static struct amba_device kmi1_device = { - .dev = { - .init_name = "mb:19", - }, - .res = { - .start = KMI1_BASE, - .end = KMI1_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = { IRQ_KMIINT1, NO_IRQ }, -}; +static AMBA_APB_DEVICE(kmi0, "mb:18", 0, KMI0_BASE, KMI0_IRQ, NULL); +static AMBA_APB_DEVICE(kmi1, "mb:19", 0, KMI1_BASE, KMI1_IRQ, NULL); static struct amba_device *amba_devs[] __initdata = { &rtc_device, diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c index 8cbb75a..3e538da 100644 --- a/arch/arm/mach-integrator/impd1.c +++ b/arch/arm/mach-integrator/impd1.c @@ -401,24 +401,21 @@ static int impd1_probe(struct lm_device *dev) pc_base = dev->resource.start + idev->offset; - d = kzalloc(sizeof(struct amba_device), GFP_KERNEL); + d = amba_device_alloc(NULL, pc_base, SZ_4K); if (!d) continue; dev_set_name(&d->dev, "lm%x:%5.5lx", dev->id, idev->offset >> 12); d->dev.parent = &dev->dev; - d->res.start = dev->resource.start + idev->offset; - d->res.end = d->res.start + SZ_4K - 1; - d->res.flags = IORESOURCE_MEM; d->irq[0] = dev->irq; d->irq[1] = dev->irq; d->periphid = idev->id; d->dev.platform_data = idev->platform_data; - ret = amba_device_register(d, &dev->resource); + ret = amba_device_add(d, &dev->resource); if (ret) { dev_err(&d->dev, "unable to register device: %d\n", ret); - kfree(d); + amba_device_put(d); } } diff --git a/arch/arm/mach-integrator/include/mach/system.h b/arch/arm/mach-integrator/include/mach/system.h deleted file mode 100644 index 901514e..0000000 --- a/arch/arm/mach-integrator/include/mach/system.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * arch/arm/mach-integrator/include/mach/system.h - * - * Copyright (C) 1999 ARM Limited - * Copyright (C) 2000 Deep Blue Solutions Ltd - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static inline void arch_idle(void) -{ - /* - * This should do all the clock switching - * and wait for interrupt tricks - */ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index a8b6aa6..be9ead4 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -347,32 +347,14 @@ static struct mmci_platform_data mmc_data = { .gpio_cd = -1, }; -static struct amba_device mmc_device = { - .dev = { - .init_name = "mb:1c", - .platform_data = &mmc_data, - }, - .res = { - .start = INTEGRATOR_CP_MMC_BASE, - .end = INTEGRATOR_CP_MMC_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = { IRQ_CP_MMCIINT0, IRQ_CP_MMCIINT1 }, - .periphid = 0, -}; +#define INTEGRATOR_CP_MMC_IRQS { IRQ_CP_MMCIINT0, IRQ_CP_MMCIINT1 } +#define INTEGRATOR_CP_AACI_IRQS { IRQ_CP_AACIINT } -static struct amba_device aaci_device = { - .dev = { - .init_name = "mb:1d", - }, - .res = { - .start = INTEGRATOR_CP_AACI_BASE, - .end = INTEGRATOR_CP_AACI_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = { IRQ_CP_AACIINT, NO_IRQ }, - .periphid = 0, -}; +static AMBA_APB_DEVICE(mmc, "mb:1c", 0, INTEGRATOR_CP_MMC_BASE, + INTEGRATOR_CP_MMC_IRQS, &mmc_data); + +static AMBA_APB_DEVICE(aaci, "mb:1d", 0, INTEGRATOR_CP_AACI_BASE, + INTEGRATOR_CP_AACI_IRQS, NULL); /* @@ -425,21 +407,8 @@ static struct clcd_board clcd_data = { .remove = versatile_clcd_remove_dma, }; -static struct amba_device clcd_device = { - .dev = { - .init_name = "mb:c0", - .coherent_dma_mask = ~0, - .platform_data = &clcd_data, - }, - .res = { - .start = INTCP_PA_CLCD_BASE, - .end = INTCP_PA_CLCD_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .dma_mask = ~0, - .irq = { IRQ_CP_CLCDCINT, NO_IRQ }, - .periphid = 0, -}; +static AMBA_AHB_DEVICE(clcd, "mb:c0", 0, INTCP_PA_CLCD_BASE, + { IRQ_CP_CLCDCINT }, &clcd_data); static struct amba_device *amba_devs[] __initdata = { &mmc_device, diff --git a/arch/arm/mach-iop13xx/include/mach/system.h b/arch/arm/mach-iop13xx/include/mach/system.h deleted file mode 100644 index 1f31ed3..0000000 --- a/arch/arm/mach-iop13xx/include/mach/system.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/arm/mach-iop13xx/include/mach/system.h - * - * Copyright (C) 2004 Intel Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -static inline void arch_idle(void) -{ - cpu_do_idle(); -} diff --git a/arch/arm/mach-iop32x/include/mach/system.h b/arch/arm/mach-iop32x/include/mach/system.h deleted file mode 100644 index 4a88727..0000000 --- a/arch/arm/mach-iop32x/include/mach/system.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/arm/mach-iop32x/include/mach/system.h - * - * Copyright (C) 2001 MontaVista Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -static inline void arch_idle(void) -{ - cpu_do_idle(); -} diff --git a/arch/arm/mach-iop33x/include/mach/system.h b/arch/arm/mach-iop33x/include/mach/system.h deleted file mode 100644 index 4f98e76..0000000 --- a/arch/arm/mach-iop33x/include/mach/system.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/arm/mach-iop33x/include/mach/system.h - * - * Copyright (C) 2001 MontaVista Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -static inline void arch_idle(void) -{ - cpu_do_idle(); -} diff --git a/arch/arm/mach-ixp2000/include/mach/system.h b/arch/arm/mach-ixp2000/include/mach/system.h deleted file mode 100644 index a7fb08b..0000000 --- a/arch/arm/mach-ixp2000/include/mach/system.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * arch/arm/mach-ixp2000/include/mach/system.h - * - * Copyright (C) 2002 Intel Corp. - * Copyricht (C) 2003-2005 MontaVista Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -static inline void arch_idle(void) -{ - cpu_do_idle(); -} diff --git a/arch/arm/mach-ixp23xx/core.c b/arch/arm/mach-ixp23xx/core.c index 0923bb9..7c1495e 100644 --- a/arch/arm/mach-ixp23xx/core.c +++ b/arch/arm/mach-ixp23xx/core.c @@ -441,6 +441,9 @@ static struct platform_device *ixp23xx_devices[] __initdata = { void __init ixp23xx_sys_init(void) { + /* by default, the idle code is disabled */ + disable_hlt(); + *IXP23XX_EXP_UNIT_FUSE |= 0xf; platform_add_devices(ixp23xx_devices, ARRAY_SIZE(ixp23xx_devices)); } diff --git a/arch/arm/mach-ixp23xx/include/mach/system.h b/arch/arm/mach-ixp23xx/include/mach/system.h deleted file mode 100644 index 277dda7..0000000 --- a/arch/arm/mach-ixp23xx/include/mach/system.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * arch/arm/mach-ixp23xx/include/mach/system.h - * - * Copyright (C) 2003 Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -static inline void arch_idle(void) -{ -#if 0 - if (!hlt_counter) - cpu_do_idle(); -#endif -} diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index 3841ab4..a6329a0 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -236,6 +236,12 @@ void __init ixp4xx_init_irq(void) { int i = 0; + /* + * ixp4xx does not implement the XScale PWRMODE register + * so it must not call cpu_do_idle(). + */ + disable_hlt(); + /* Route all sources to IRQ instead of FIQ */ *IXP4XX_ICLR = 0x0; diff --git a/arch/arm/mach-ixp4xx/include/mach/system.h b/arch/arm/mach-ixp4xx/include/mach/system.h deleted file mode 100644 index 140a9be..0000000 --- a/arch/arm/mach-ixp4xx/include/mach/system.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * arch/arm/mach-ixp4xx/include/mach/system.h - * - * Copyright (C) 2002 Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ -static inline void arch_idle(void) -{ - /* ixp4xx does not implement the XScale PWRMODE register, - * so it must not call cpu_do_idle() here. - */ -#if 0 - cpu_do_idle(); -#endif -} diff --git a/arch/arm/mach-kirkwood/include/mach/system.h b/arch/arm/mach-kirkwood/include/mach/system.h deleted file mode 100644 index 5fddde0..0000000 --- a/arch/arm/mach-kirkwood/include/mach/system.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * arch/arm/mach-kirkwood/include/mach/system.h - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static inline void arch_idle(void) -{ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/mach-ks8695/include/mach/system.h b/arch/arm/mach-ks8695/include/mach/system.h deleted file mode 100644 index 59fe992..0000000 --- a/arch/arm/mach-ks8695/include/mach/system.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * arch/arm/mach-s3c2410/include/mach/system.h - * - * Copyright (C) 2006 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * - * KS8695 - System function defines and includes - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static void arch_idle(void) -{ - /* - * This should do all the clock switching - * and wait for interrupt tricks, - */ - cpu_do_idle(); - -} - -#endif diff --git a/arch/arm/mach-lpc32xx/include/mach/system.h b/arch/arm/mach-lpc32xx/include/mach/system.h deleted file mode 100644 index bf176c9..0000000 --- a/arch/arm/mach-lpc32xx/include/mach/system.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * arch/arm/mach-lpc32xx/include/mach/system.h - * - * Author: Kevin Wells <kevin.wells@nxp.com> - * - * Copyright (C) 2010 NXP Semiconductors - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static void arch_idle(void) -{ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/mach-lpc32xx/phy3250.c b/arch/arm/mach-lpc32xx/phy3250.c index bfee5b4..5d51c10 100644 --- a/arch/arm/mach-lpc32xx/phy3250.c +++ b/arch/arm/mach-lpc32xx/phy3250.c @@ -149,20 +149,8 @@ static struct clcd_board lpc32xx_clcd_data = { .remove = lpc32xx_clcd_remove, }; -static struct amba_device lpc32xx_clcd_device = { - .dev = { - .coherent_dma_mask = ~0, - .init_name = "dev:clcd", - .platform_data = &lpc32xx_clcd_data, - }, - .res = { - .start = LPC32XX_LCD_BASE, - .end = (LPC32XX_LCD_BASE + SZ_4K - 1), - .flags = IORESOURCE_MEM, - }, - .dma_mask = ~0, - .irq = {IRQ_LPC32XX_LCD, NO_IRQ}, -}; +static AMBA_AHB_DEVICE(lpc32xx_clcd, "dev:clcd", 0, + LPC32XX_LCD_BASE, { IRQ_LPC32XX_LCD }, &lpc32xx_clcd_data); /* * AMBA SSP (SPI) @@ -191,20 +179,8 @@ static struct pl022_ssp_controller lpc32xx_ssp0_data = { .enable_dma = 0, }; -static struct amba_device lpc32xx_ssp0_device = { - .dev = { - .coherent_dma_mask = ~0, - .init_name = "dev:ssp0", - .platform_data = &lpc32xx_ssp0_data, - }, - .res = { - .start = LPC32XX_SSP0_BASE, - .end = (LPC32XX_SSP0_BASE + SZ_4K - 1), - .flags = IORESOURCE_MEM, - }, - .dma_mask = ~0, - .irq = {IRQ_LPC32XX_SSP0, NO_IRQ}, -}; +static AMBA_APB_DEVICE(lpc32xx_ssp0, "dev:ssp0", 0, + LPC32XX_SSP0_BASE, { IRQ_LPC32XX_SSP0 }, &lpc32xx_ssp0_data); /* AT25 driver registration */ static int __init phy3250_spi_board_register(void) diff --git a/arch/arm/mach-mmp/include/mach/system.h b/arch/arm/mach-mmp/include/mach/system.h deleted file mode 100644 index 1d001ea..0000000 --- a/arch/arm/mach-mmp/include/mach/system.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * linux/arch/arm/mach-mmp/include/mach/system.h - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __ASM_MACH_SYSTEM_H -#define __ASM_MACH_SYSTEM_H - -static inline void arch_idle(void) -{ - cpu_do_idle(); -} -#endif /* __ASM_MACH_SYSTEM_H */ diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c index 0a11342..962e711 100644 --- a/arch/arm/mach-msm/board-msm8x60.c +++ b/arch/arm/mach-msm/board-msm8x60.c @@ -80,12 +80,8 @@ static struct of_device_id msm_dt_gic_match[] __initdata = { static void __init msm8x60_dt_init(void) { - struct device_node *node; - - node = of_find_matching_node_by_address(NULL, msm_dt_gic_match, - MSM8X60_QGIC_DIST_PHYS); - if (node) - irq_domain_add_simple(node, GIC_SPI_START); + irq_domain_generate_simple(msm_dt_gic_match, MSM8X60_QGIC_DIST_PHYS, + GIC_SPI_START); if (of_machine_is_compatible("qcom,msm8660-surf")) { printk(KERN_INFO "Init surf UART registers\n"); diff --git a/arch/arm/mach-msm/idle.S b/arch/arm/mach-msm/idle.S deleted file mode 100644 index 6a94f05..0000000 --- a/arch/arm/mach-msm/idle.S +++ /dev/null @@ -1,36 +0,0 @@ -/* arch/arm/mach-msm/include/mach/idle.S - * - * Idle processing for MSM7K - work around bugs with SWFI. - * - * Copyright (c) 2007 QUALCOMM Incorporated. - * Copyright (C) 2007 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include <linux/linkage.h> -#include <asm/assembler.h> - -ENTRY(arch_idle) -#ifdef CONFIG_MSM7X00A_IDLE - mrc p15, 0, r1, c1, c0, 0 /* read current CR */ - bic r0, r1, #(1 << 2) /* clear dcache bit */ - bic r0, r0, #(1 << 12) /* clear icache bit */ - mcr p15, 0, r0, c1, c0, 0 /* disable d/i cache */ - - mov r0, #0 /* prepare wfi value */ - mcr p15, 0, r0, c7, c10, 0 /* flush the cache */ - mcr p15, 0, r0, c7, c10, 4 /* memory barrier */ - mcr p15, 0, r0, c7, c0, 4 /* wait for interrupt */ - - mcr p15, 0, r1, c1, c0, 0 /* restore d/i cache */ -#endif - mov pc, lr diff --git a/arch/arm/mach-msm/idle.c b/arch/arm/mach-msm/idle.c new file mode 100644 index 0000000..0c9e13c --- /dev/null +++ b/arch/arm/mach-msm/idle.c @@ -0,0 +1,49 @@ +/* arch/arm/mach-msm/idle.c + * + * Idle processing for MSM7K - work around bugs with SWFI. + * + * Copyright (c) 2007 QUALCOMM Incorporated. + * Copyright (C) 2007 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <linux/init.h> +#include <asm/system.h> + +static void msm_idle(void) +{ +#ifdef CONFIG_MSM7X00A_IDLE + asm volatile ( + + "mrc p15, 0, r1, c1, c0, 0 /* read current CR */ \n\t" + "bic r0, r1, #(1 << 2) /* clear dcache bit */ \n\t" + "bic r0, r0, #(1 << 12) /* clear icache bit */ \n\t" + "mcr p15, 0, r0, c1, c0, 0 /* disable d/i cache */ \n\t" + + "mov r0, #0 /* prepare wfi value */ \n\t" + "mcr p15, 0, r0, c7, c10, 0 /* flush the cache */ \n\t" + "mcr p15, 0, r0, c7, c10, 4 /* memory barrier */ \n\t" + "mcr p15, 0, r0, c7, c0, 4 /* wait for interrupt */ \n\t" + + "mcr p15, 0, r1, c1, c0, 0 /* restore d/i cache */ \n\t" + + : : : "r0","r1" ); +#endif +} + +static int __init msm_idle_init(void) +{ + arm_pm_idle = msm_idle; + return 0; +} + +arch_initcall(msm_idle_init); diff --git a/arch/arm/mach-msm/include/mach/system.h b/arch/arm/mach-msm/include/mach/system.h index 311db2b..f5fb2ec 100644 --- a/arch/arm/mach-msm/include/mach/system.h +++ b/arch/arm/mach-msm/include/mach/system.h @@ -12,7 +12,6 @@ * GNU General Public License for more details. * */ -void arch_idle(void); /* low level hardware reset hook -- for example, hitting the * PSHOLD line on the PMIC to hard reset the system diff --git a/arch/arm/mach-mv78xx0/include/mach/system.h b/arch/arm/mach-mv78xx0/include/mach/system.h deleted file mode 100644 index 8c3a538..0000000 --- a/arch/arm/mach-mv78xx0/include/mach/system.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * arch/arm/mach-mv78xx0/include/mach/system.h - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static inline void arch_idle(void) -{ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/mach-mxs/devices.c b/arch/arm/mach-mxs/devices.c index fe3e847..01faffe 100644 --- a/arch/arm/mach-mxs/devices.c +++ b/arch/arm/mach-mxs/devices.c @@ -77,16 +77,18 @@ err: int __init mxs_add_amba_device(const struct amba_device *dev) { - struct amba_device *adev = kmalloc(sizeof(*adev), GFP_KERNEL); + struct amba_device *adev = amba_device_alloc(dev->dev.init_name, + dev->res.start, resource_size(&dev->res)); if (!adev) { pr_err("%s: failed to allocate memory", __func__); return -ENOMEM; } - *adev = *dev; + adev->irq[0] = dev->irq[0]; + adev->irq[1] = dev->irq[1]; - return amba_device_register(adev, &iomem_resource); + return amba_device_add(adev, &iomem_resource); } struct device mxs_apbh_bus = { diff --git a/arch/arm/mach-mxs/devices/amba-duart.c b/arch/arm/mach-mxs/devices/amba-duart.c index a559db0..a5479f7 100644 --- a/arch/arm/mach-mxs/devices/amba-duart.c +++ b/arch/arm/mach-mxs/devices/amba-duart.c @@ -23,7 +23,7 @@ const struct amba_device name##_device __initconst = { \ .end = (soc ## _DUART_BASE_ADDR) + SZ_8K - 1, \ .flags = IORESOURCE_MEM, \ }, \ - .irq = {soc ## _INT_DUART, NO_IRQ}, \ + .irq = {soc ## _INT_DUART}, \ } #ifdef CONFIG_SOC_IMX23 diff --git a/arch/arm/mach-mxs/include/mach/system.h b/arch/arm/mach-mxs/include/mach/system.h deleted file mode 100644 index e7ad1bb..0000000 --- a/arch/arm/mach-mxs/include/mach/system.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 1999 ARM Limited - * Copyright (C) 2000 Deep Blue Solutions Ltd - * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __MACH_MXS_SYSTEM_H__ -#define __MACH_MXS_SYSTEM_H__ - -static inline void arch_idle(void) -{ - cpu_do_idle(); -} - -#endif /* __MACH_MXS_SYSTEM_H__ */ diff --git a/arch/arm/mach-mxs/pm.c b/arch/arm/mach-mxs/pm.c index fb042da..a9b4bbc 100644 --- a/arch/arm/mach-mxs/pm.c +++ b/arch/arm/mach-mxs/pm.c @@ -15,13 +15,12 @@ #include <linux/kernel.h> #include <linux/suspend.h> #include <linux/io.h> -#include <mach/system.h> static int mxs_suspend_enter(suspend_state_t state) { switch (state) { case PM_SUSPEND_MEM: - arch_idle(); + cpu_do_idle(); break; default: diff --git a/arch/arm/mach-netx/fb.c b/arch/arm/mach-netx/fb.c index b991323..2cdf6ef 100644 --- a/arch/arm/mach-netx/fb.c +++ b/arch/arm/mach-netx/fb.c @@ -92,18 +92,7 @@ void clk_put(struct clk *clk) { } -static struct amba_device fb_device = { - .dev = { - .init_name = "fb", - .coherent_dma_mask = ~0, - }, - .res = { - .start = 0x00104000, - .end = 0x00104fff, - .flags = IORESOURCE_MEM, - }, - .irq = { NETX_IRQ_LCD, NO_IRQ }, -}; +static AMBA_AHB_DEVICE(fb, "fb", 0, 0x00104000, { NETX_IRQ_LCD }, NULL); int netx_fb_init(struct clcd_board *board, struct clcd_panel *panel) { diff --git a/arch/arm/mach-netx/include/mach/system.h b/arch/arm/mach-netx/include/mach/system.h deleted file mode 100644 index b38fa36..0000000 --- a/arch/arm/mach-netx/include/mach/system.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * arch/arm/mach-netx/include/mach/system.h - * - * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static inline void arch_idle(void) -{ - cpu_do_idle(); -} - -#endif - diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c index 7c878bf..f6f74ad 100644 --- a/arch/arm/mach-nomadik/board-nhk8815.c +++ b/arch/arm/mach-nomadik/board-nhk8815.c @@ -185,20 +185,11 @@ static void __init nhk8815_onenand_init(void) #endif } -#define __MEM_4K_RESOURCE(x) \ - .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM} +static AMBA_APB_DEVICE(uart0, "uart0", 0, NOMADIK_UART0_BASE, + { IRQ_UART0 }, NULL); -static struct amba_device uart0_device = { - .dev = { .init_name = "uart0" }, - __MEM_4K_RESOURCE(NOMADIK_UART0_BASE), - .irq = {IRQ_UART0, NO_IRQ}, -}; - -static struct amba_device uart1_device = { - .dev = { .init_name = "uart1" }, - __MEM_4K_RESOURCE(NOMADIK_UART1_BASE), - .irq = {IRQ_UART1, NO_IRQ}, -}; +static AMBA_APB_DEVICE(uart1, "uart1", 0, NOMADIK_UART1_BASE, + { IRQ_UART1 }, NULL); static struct amba_device *amba_devs[] __initdata = { &uart0_device, diff --git a/arch/arm/mach-nomadik/cpu-8815.c b/arch/arm/mach-nomadik/cpu-8815.c index 65df7b4..27f43a4 100644 --- a/arch/arm/mach-nomadik/cpu-8815.c +++ b/arch/arm/mach-nomadik/cpu-8815.c @@ -97,12 +97,7 @@ static struct platform_device cpu8815_platform_gpio[] = { GPIO_DEVICE(3), }; -static struct amba_device cpu8815_amba_rng = { - .dev = { - .init_name = "rng", - }, - __MEM_4K_RESOURCE(NOMADIK_RNG_BASE), -}; +static AMBA_APB_DEVICE(cpu8815_amba_rng, "rng", 0, NOMADIK_RNG_BASE, { }, NULL); static struct platform_device *platform_devs[] __initdata = { cpu8815_platform_gpio + 0, @@ -112,7 +107,7 @@ static struct platform_device *platform_devs[] __initdata = { }; static struct amba_device *amba_devs[] __initdata = { - &cpu8815_amba_rng + &cpu8815_amba_rng_device }; static int __init cpu8815_init(void) diff --git a/arch/arm/mach-nomadik/include/mach/system.h b/arch/arm/mach-nomadik/include/mach/system.h deleted file mode 100644 index 25e198b..0000000 --- a/arch/arm/mach-nomadik/include/mach/system.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * mach-nomadik/include/mach/system.h - * - * Copyright (C) 2008 STMicroelectronics - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static inline void arch_idle(void) -{ - /* - * This should do all the clock switching - * and wait for interrupt tricks - */ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/mach-omap1/include/mach/system.h b/arch/arm/mach-omap1/include/mach/system.h deleted file mode 100644 index a6c1b3a..0000000 --- a/arch/arm/mach-omap1/include/mach/system.h +++ /dev/null @@ -1,5 +0,0 @@ -/* - * arch/arm/mach-omap1/include/mach/system.h - */ - -#include <plat/system.h> diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c index 89ea20c..0c2c366 100644 --- a/arch/arm/mach-omap1/pm.c +++ b/arch/arm/mach-omap1/pm.c @@ -42,9 +42,9 @@ #include <linux/sysfs.h> #include <linux/module.h> #include <linux/io.h> +#include <linux/atomic.h> #include <asm/irq.h> -#include <linux/atomic.h> #include <asm/mach/time.h> #include <asm/mach/irq.h> @@ -108,13 +108,7 @@ void omap1_pm_idle(void) __u32 use_idlect1 = arm_idlect1_mask; int do_sleep = 0; - local_irq_disable(); local_fiq_disable(); - if (need_resched()) { - local_fiq_enable(); - local_irq_enable(); - return; - } #if defined(CONFIG_OMAP_MPU_TIMER) && !defined(CONFIG_OMAP_DM_TIMER) #warning Enable 32kHz OS timer in order to allow sleep states in idle @@ -157,14 +151,12 @@ void omap1_pm_idle(void) omap_writel(saved_idlect1, ARM_IDLECT1); local_fiq_enable(); - local_irq_enable(); return; } omap_sram_suspend(omap_readl(ARM_IDLECT1), omap_readl(ARM_IDLECT2)); local_fiq_enable(); - local_irq_enable(); } /* @@ -583,8 +575,6 @@ static void omap_pm_init_proc(void) #endif /* DEBUG && CONFIG_PROC_FS */ -static void (*saved_idle)(void) = NULL; - /* * omap_pm_prepare - Do preliminary suspend work. * @@ -592,8 +582,7 @@ static void (*saved_idle)(void) = NULL; static int omap_pm_prepare(void) { /* We cannot sleep in idle until we have resumed */ - saved_idle = pm_idle; - pm_idle = NULL; + disable_hlt(); return 0; } @@ -630,7 +619,7 @@ static int omap_pm_enter(suspend_state_t state) static void omap_pm_finish(void) { - pm_idle = saved_idle; + enable_hlt(); } @@ -687,7 +676,7 @@ static int __init omap_pm_init(void) return -ENODEV; } - pm_idle = omap1_pm_idle; + arm_pm_idle = omap1_pm_idle; if (cpu_is_omap7xx()) setup_irq(INT_7XX_WAKE_UP_REQ, &omap_wakeup_irq); diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index e20c8ab..3fdfaeb 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -117,7 +117,6 @@ comment "OMAP Board Type" config MACH_OMAP_GENERIC bool "Generic OMAP2+ board" depends on ARCH_OMAP2PLUS - select USE_OF default y help Support for generic TI OMAP2+ boards using Flattened Device Tree. diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index ad49762..02d7e82 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c @@ -68,7 +68,7 @@ static void __init omap_generic_init(void) { struct device_node *node = of_find_matching_node(NULL, intc_match); if (node) - irq_domain_add_simple(node, 0); + irq_domain_add_legacy(node, 32, 0, 0, &irq_domain_simple_ops, NULL); omap_sdrc_init(NULL, NULL); @@ -91,14 +91,13 @@ static void __init omap3_init(void) } #endif -#if defined(CONFIG_SOC_OMAP2420) +#ifdef CONFIG_SOC_OMAP2420 static const char *omap242x_boards_compat[] __initdata = { "ti,omap2420", NULL, }; DT_MACHINE_START(OMAP242X_DT, "Generic OMAP2420 (Flattened Device Tree)") - .atag_offset = 0x100, .reserve = omap_reserve, .map_io = omap242x_map_io, .init_early = omap2420_init_early, @@ -111,14 +110,13 @@ DT_MACHINE_START(OMAP242X_DT, "Generic OMAP2420 (Flattened Device Tree)") MACHINE_END #endif -#if defined(CONFIG_SOC_OMAP2430) +#ifdef CONFIG_SOC_OMAP2430 static const char *omap243x_boards_compat[] __initdata = { "ti,omap2430", NULL, }; DT_MACHINE_START(OMAP243X_DT, "Generic OMAP2430 (Flattened Device Tree)") - .atag_offset = 0x100, .reserve = omap_reserve, .map_io = omap243x_map_io, .init_early = omap2430_init_early, @@ -131,14 +129,13 @@ DT_MACHINE_START(OMAP243X_DT, "Generic OMAP2430 (Flattened Device Tree)") MACHINE_END #endif -#if defined(CONFIG_ARCH_OMAP3) +#ifdef CONFIG_ARCH_OMAP3 static const char *omap3_boards_compat[] __initdata = { "ti,omap3", NULL, }; DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)") - .atag_offset = 0x100, .reserve = omap_reserve, .map_io = omap3_map_io, .init_early = omap3430_init_early, @@ -151,14 +148,13 @@ DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)") MACHINE_END #endif -#if defined(CONFIG_ARCH_OMAP4) +#ifdef CONFIG_ARCH_OMAP4 static const char *omap4_boards_compat[] __initdata = { "ti,omap4", NULL, }; DT_MACHINE_START(OMAP4_DT, "Generic OMAP4 (Flattened Device Tree)") - .atag_offset = 0x100, .reserve = omap_reserve, .map_io = omap4_map_io, .init_early = omap4430_init_early, diff --git a/arch/arm/mach-omap2/emu.c b/arch/arm/mach-omap2/emu.c index 9c442e2..ce91aad 100644 --- a/arch/arm/mach-omap2/emu.c +++ b/arch/arm/mach-omap2/emu.c @@ -30,29 +30,8 @@ MODULE_AUTHOR("Alexander Shishkin"); #define ETB_BASE (L4_EMU_34XX_PHYS + 0x1b000) #define DAPCTL (L4_EMU_34XX_PHYS + 0x1d000) -static struct amba_device omap3_etb_device = { - .dev = { - .init_name = "etb", - }, - .res = { - .start = ETB_BASE, - .end = ETB_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .periphid = 0x000bb907, -}; - -static struct amba_device omap3_etm_device = { - .dev = { - .init_name = "etm", - }, - .res = { - .start = ETM_BASE, - .end = ETM_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .periphid = 0x102bb921, -}; +static AMBA_APB_DEVICE(omap3_etb, "etb", 0x000bb907, ETB_BASE, { }, NULL); +static AMBA_APB_DEVICE(omap3_etm, "etm", 0x102bb921, ETM_BASE, { }, NULL); static int __init emu_init(void) { @@ -66,4 +45,3 @@ static int __init emu_init(void) } subsys_initcall(emu_init); - diff --git a/arch/arm/mach-omap2/include/mach/system.h b/arch/arm/mach-omap2/include/mach/system.h deleted file mode 100644 index d488721..0000000 --- a/arch/arm/mach-omap2/include/mach/system.h +++ /dev/null @@ -1,5 +0,0 @@ -/* - * arch/arm/mach-omap2/include/mach/system.h - */ - -#include <plat/system.h> diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 5a65dd0..44551edd 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -230,6 +230,14 @@ postcore_initcall(omap2_common_pm_init); static int __init omap2_common_pm_late_init(void) { + /* + * In the case of DT, the PMIC and SR initialization will be done using + * a completely different mechanism. + * Disable this part if a DT blob is available. + */ + if (of_have_populated_dt()) + return 0; + /* Init the voltage layer */ omap_pmic_late_init(); omap_voltage_late_init(); diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index 23de98d..a4eb5c2 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c @@ -226,7 +226,6 @@ static int omap2_can_sleep(void) static void omap2_pm_idle(void) { - local_irq_disable(); local_fiq_disable(); if (!omap2_can_sleep()) { @@ -243,7 +242,6 @@ static void omap2_pm_idle(void) out: local_fiq_enable(); - local_irq_enable(); } #ifdef CONFIG_SUSPEND @@ -462,7 +460,7 @@ static int __init omap2_pm_init(void) } suspend_set_ops(&omap_pm_ops); - pm_idle = omap2_pm_idle; + arm_pm_idle = omap2_pm_idle; return 0; } diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index fc69875..b77df73 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -418,10 +418,9 @@ void omap_sram_idle(void) static void omap3_pm_idle(void) { - local_irq_disable(); local_fiq_disable(); - if (omap_irq_pending() || need_resched()) + if (omap_irq_pending()) goto out; trace_power_start(POWER_CSTATE, 1, smp_processor_id()); @@ -434,7 +433,6 @@ static void omap3_pm_idle(void) out: local_fiq_enable(); - local_irq_enable(); } #ifdef CONFIG_SUSPEND @@ -848,7 +846,7 @@ static int __init omap3_pm_init(void) suspend_set_ops(&omap_pm_ops); #endif /* CONFIG_SUSPEND */ - pm_idle = omap3_pm_idle; + arm_pm_idle = omap3_pm_idle; omap3_idle_init(); /* diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index c264ef7..c840689 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -173,18 +173,16 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) * omap_default_idle - OMAP4 default ilde routine.' * * Implements OMAP4 memory, IO ordering requirements which can't be addressed - * with default arch_idle() hook. Used by all CPUs with !CONFIG_CPUIDLE and + * with default cpu_do_idle() hook. Used by all CPUs with !CONFIG_CPUIDLE and * by secondary CPU with CONFIG_CPUIDLE. */ static void omap_default_idle(void) { - local_irq_disable(); local_fiq_disable(); omap_do_wfi(); local_fiq_enable(); - local_irq_enable(); } /** @@ -255,8 +253,8 @@ static int __init omap4_pm_init(void) suspend_set_ops(&omap_pm_ops); #endif /* CONFIG_SUSPEND */ - /* Overwrite the default arch_idle() */ - pm_idle = omap_default_idle; + /* Overwrite the default cpu_do_idle() */ + arm_pm_idle = omap_default_idle; omap4_idle_init(); diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c index 860118a..873b51d 100644 --- a/arch/arm/mach-omap2/prm_common.c +++ b/arch/arm/mach-omap2/prm_common.c @@ -24,7 +24,6 @@ #include <linux/interrupt.h> #include <linux/slab.h> -#include <mach/system.h> #include <plat/common.h> #include <plat/prcm.h> #include <plat/irqs.h> diff --git a/arch/arm/mach-orion5x/include/mach/system.h b/arch/arm/mach-orion5x/include/mach/system.h deleted file mode 100644 index 825a265..0000000 --- a/arch/arm/mach-orion5x/include/mach/system.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * arch/arm/mach-orion5x/include/mach/system.h - * - * Tzachi Perelstein <tzachi@marvell.com> - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static inline void arch_idle(void) -{ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/mach-picoxcell/include/mach/system.h b/arch/arm/mach-picoxcell/include/mach/system.h deleted file mode 100644 index 1a5d8cb..0000000 --- a/arch/arm/mach-picoxcell/include/mach/system.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2011 Picochip Ltd., Jamie Iles - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static inline void arch_idle(void) -{ - /* - * This should do all the clock switching and wait for interrupt - * tricks. - */ - cpu_do_idle(); -} - -#endif /* __ASM_ARCH_SYSTEM_H */ diff --git a/arch/arm/mach-pnx4008/include/mach/system.h b/arch/arm/mach-pnx4008/include/mach/system.h deleted file mode 100644 index 60cfe71..0000000 --- a/arch/arm/mach-pnx4008/include/mach/system.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * arch/arm/mach-pnx4008/include/mach/system.h - * - * Copyright (C) 2003 Philips Semiconductors - * Copyright (C) 2005 MontaVista Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static void arch_idle(void) -{ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/mach-prima2/include/mach/system.h b/arch/arm/mach-prima2/include/mach/system.h deleted file mode 100644 index 2c7d2a9..0000000 --- a/arch/arm/mach-prima2/include/mach/system.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * arch/arm/mach-prima2/include/mach/system.h - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - * - * Licensed under GPLv2 or later. - */ - -#ifndef __MACH_SYSTEM_H__ -#define __MACH_SYSTEM_H__ - -static inline void arch_idle(void) -{ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/mach-prima2/irq.c b/arch/arm/mach-prima2/irq.c index d93ceef..37c2de9 100644 --- a/arch/arm/mach-prima2/irq.c +++ b/arch/arm/mach-prima2/irq.c @@ -68,7 +68,7 @@ void __init sirfsoc_of_irq_init(void) if (!sirfsoc_intc_base) panic("unable to map intc cpu registers\n"); - irq_domain_add_simple(np, 0); + irq_domain_add_legacy(np, 32, 0, 0, &irq_domain_simple_ops, NULL); of_node_put(np); diff --git a/arch/arm/mach-pxa/include/mach/system.h b/arch/arm/mach-pxa/include/mach/system.h deleted file mode 100644 index c5afacd..0000000 --- a/arch/arm/mach-pxa/include/mach/system.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * arch/arm/mach-pxa/include/mach/system.h - * - * Author: Nicolas Pitre - * Created: Jun 15, 2001 - * Copyright: MontaVista Software Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -static inline void arch_idle(void) -{ - cpu_do_idle(); -} diff --git a/arch/arm/mach-realview/core.h b/arch/arm/mach-realview/core.h index 735b57a..f8f2c0a 100644 --- a/arch/arm/mach-realview/core.h +++ b/arch/arm/mach-realview/core.h @@ -28,21 +28,11 @@ #include <asm/setup.h> #include <asm/leds.h> -#define AMBA_DEVICE(name,busid,base,plat) \ -static struct amba_device name##_device = { \ - .dev = { \ - .coherent_dma_mask = ~0, \ - .init_name = busid, \ - .platform_data = plat, \ - }, \ - .res = { \ - .start = REALVIEW_##base##_BASE, \ - .end = (REALVIEW_##base##_BASE) + SZ_4K - 1, \ - .flags = IORESOURCE_MEM, \ - }, \ - .dma_mask = ~0, \ - .irq = base##_IRQ, \ -} +#define APB_DEVICE(name, busid, base, plat) \ +static AMBA_APB_DEVICE(name, busid, 0, REALVIEW_##base##_BASE, base##_IRQ, plat) + +#define AHB_DEVICE(name, busid, base, plat) \ +static AMBA_AHB_DEVICE(name, busid, 0, REALVIEW_##base##_BASE, base##_IRQ, plat) struct machine_desc; diff --git a/arch/arm/mach-realview/include/mach/irqs-pb1176.h b/arch/arm/mach-realview/include/mach/irqs-pb1176.h index 5c3c625..708f841 100644 --- a/arch/arm/mach-realview/include/mach/irqs-pb1176.h +++ b/arch/arm/mach-realview/include/mach/irqs-pb1176.h @@ -40,6 +40,7 @@ #define IRQ_DC1176_L2CC (IRQ_DC1176_GIC_START + 13) #define IRQ_DC1176_RTC (IRQ_DC1176_GIC_START + 14) #define IRQ_DC1176_CLCD (IRQ_DC1176_GIC_START + 15) /* CLCD controller */ +#define IRQ_DC1176_GPIO0 (IRQ_DC1176_GIC_START + 16) #define IRQ_DC1176_SSP (IRQ_DC1176_GIC_START + 17) /* SSP port */ #define IRQ_DC1176_UART0 (IRQ_DC1176_GIC_START + 18) /* UART 0 on development chip */ #define IRQ_DC1176_UART1 (IRQ_DC1176_GIC_START + 19) /* UART 1 on development chip */ @@ -73,7 +74,6 @@ #define IRQ_PB1176_DMAC (IRQ_PB1176_GIC_START + 24) /* DMA controller */ #define IRQ_PB1176_RTC (IRQ_PB1176_GIC_START + 25) /* Real Time Clock */ -#define IRQ_PB1176_GPIO0 -1 #define IRQ_PB1176_SCTL -1 #define NR_GIC_PB1176 2 diff --git a/arch/arm/mach-realview/include/mach/system.h b/arch/arm/mach-realview/include/mach/system.h deleted file mode 100644 index 471b671..0000000 --- a/arch/arm/mach-realview/include/mach/system.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * arch/arm/mach-realview/include/mach/system.h - * - * Copyright (C) 2003 ARM Limited - * Copyright (C) 2000 Deep Blue Solutions Ltd - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static inline void arch_idle(void) -{ - /* - * This should do all the clock switching - * and wait for interrupt tricks - */ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c index 9578145..157e1bc6 100644 --- a/arch/arm/mach-realview/realview_eb.c +++ b/arch/arm/mach-realview/realview_eb.c @@ -135,63 +135,63 @@ static struct pl022_ssp_controller ssp0_plat_data = { /* * These devices are connected via the core APB bridge */ -#define GPIO2_IRQ { IRQ_EB_GPIO2, NO_IRQ } -#define GPIO3_IRQ { IRQ_EB_GPIO3, NO_IRQ } +#define GPIO2_IRQ { IRQ_EB_GPIO2 } +#define GPIO3_IRQ { IRQ_EB_GPIO3 } -#define AACI_IRQ { IRQ_EB_AACI, NO_IRQ } +#define AACI_IRQ { IRQ_EB_AACI } #define MMCI0_IRQ { IRQ_EB_MMCI0A, IRQ_EB_MMCI0B } -#define KMI0_IRQ { IRQ_EB_KMI0, NO_IRQ } -#define KMI1_IRQ { IRQ_EB_KMI1, NO_IRQ } +#define KMI0_IRQ { IRQ_EB_KMI0 } +#define KMI1_IRQ { IRQ_EB_KMI1 } /* * These devices are connected directly to the multi-layer AHB switch */ -#define EB_SMC_IRQ { NO_IRQ, NO_IRQ } -#define MPMC_IRQ { NO_IRQ, NO_IRQ } -#define EB_CLCD_IRQ { IRQ_EB_CLCD, NO_IRQ } -#define DMAC_IRQ { IRQ_EB_DMA, NO_IRQ } +#define EB_SMC_IRQ { } +#define MPMC_IRQ { } +#define EB_CLCD_IRQ { IRQ_EB_CLCD } +#define DMAC_IRQ { IRQ_EB_DMA } /* * These devices are connected via the core APB bridge */ -#define SCTL_IRQ { NO_IRQ, NO_IRQ } -#define EB_WATCHDOG_IRQ { IRQ_EB_WDOG, NO_IRQ } -#define EB_GPIO0_IRQ { IRQ_EB_GPIO0, NO_IRQ } -#define GPIO1_IRQ { IRQ_EB_GPIO1, NO_IRQ } -#define EB_RTC_IRQ { IRQ_EB_RTC, NO_IRQ } +#define SCTL_IRQ { } +#define EB_WATCHDOG_IRQ { IRQ_EB_WDOG } +#define EB_GPIO0_IRQ { IRQ_EB_GPIO0 } +#define GPIO1_IRQ { IRQ_EB_GPIO1 } +#define EB_RTC_IRQ { IRQ_EB_RTC } /* * These devices are connected via the DMA APB bridge */ -#define SCI_IRQ { IRQ_EB_SCI, NO_IRQ } -#define EB_UART0_IRQ { IRQ_EB_UART0, NO_IRQ } -#define EB_UART1_IRQ { IRQ_EB_UART1, NO_IRQ } -#define EB_UART2_IRQ { IRQ_EB_UART2, NO_IRQ } -#define EB_UART3_IRQ { IRQ_EB_UART3, NO_IRQ } -#define EB_SSP_IRQ { IRQ_EB_SSP, NO_IRQ } +#define SCI_IRQ { IRQ_EB_SCI } +#define EB_UART0_IRQ { IRQ_EB_UART0 } +#define EB_UART1_IRQ { IRQ_EB_UART1 } +#define EB_UART2_IRQ { IRQ_EB_UART2 } +#define EB_UART3_IRQ { IRQ_EB_UART3 } +#define EB_SSP_IRQ { IRQ_EB_SSP } /* FPGA Primecells */ -AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL); -AMBA_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data); -AMBA_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL); -AMBA_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL); -AMBA_DEVICE(uart3, "fpga:uart3", EB_UART3, NULL); +APB_DEVICE(aaci, "fpga:aaci", AACI, NULL); +APB_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data); +APB_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL); +APB_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL); +APB_DEVICE(uart3, "fpga:uart3", EB_UART3, NULL); /* DevChip Primecells */ -AMBA_DEVICE(smc, "dev:smc", EB_SMC, NULL); -AMBA_DEVICE(clcd, "dev:clcd", EB_CLCD, &clcd_plat_data); -AMBA_DEVICE(dmac, "dev:dmac", DMAC, NULL); -AMBA_DEVICE(sctl, "dev:sctl", SCTL, NULL); -AMBA_DEVICE(wdog, "dev:wdog", EB_WATCHDOG, NULL); -AMBA_DEVICE(gpio0, "dev:gpio0", EB_GPIO0, &gpio0_plat_data); -AMBA_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data); -AMBA_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data); -AMBA_DEVICE(rtc, "dev:rtc", EB_RTC, NULL); -AMBA_DEVICE(sci0, "dev:sci0", SCI, NULL); -AMBA_DEVICE(uart0, "dev:uart0", EB_UART0, NULL); -AMBA_DEVICE(uart1, "dev:uart1", EB_UART1, NULL); -AMBA_DEVICE(uart2, "dev:uart2", EB_UART2, NULL); -AMBA_DEVICE(ssp0, "dev:ssp0", EB_SSP, &ssp0_plat_data); +AHB_DEVICE(smc, "dev:smc", EB_SMC, NULL); +AHB_DEVICE(clcd, "dev:clcd", EB_CLCD, &clcd_plat_data); +AHB_DEVICE(dmac, "dev:dmac", DMAC, NULL); +AHB_DEVICE(sctl, "dev:sctl", SCTL, NULL); +APB_DEVICE(wdog, "dev:wdog", EB_WATCHDOG, NULL); +APB_DEVICE(gpio0, "dev:gpio0", EB_GPIO0, &gpio0_plat_data); +APB_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data); +APB_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data); +APB_DEVICE(rtc, "dev:rtc", EB_RTC, NULL); +APB_DEVICE(sci0, "dev:sci0", SCI, NULL); +APB_DEVICE(uart0, "dev:uart0", EB_UART0, NULL); +APB_DEVICE(uart1, "dev:uart1", EB_UART1, NULL); +APB_DEVICE(uart2, "dev:uart2", EB_UART2, NULL); +APB_DEVICE(ssp0, "dev:ssp0", EB_SSP, &ssp0_plat_data); static struct amba_device *amba_devs[] __initdata = { &dmac_device, diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c index e4abe94..b1d7caf 100644 --- a/arch/arm/mach-realview/realview_pb1176.c +++ b/arch/arm/mach-realview/realview_pb1176.c @@ -132,50 +132,50 @@ static struct pl022_ssp_controller ssp0_plat_data = { /* * RealView PB1176 AMBA devices */ -#define GPIO2_IRQ { IRQ_PB1176_GPIO2, NO_IRQ } -#define GPIO3_IRQ { IRQ_PB1176_GPIO3, NO_IRQ } -#define AACI_IRQ { IRQ_PB1176_AACI, NO_IRQ } +#define GPIO2_IRQ { IRQ_PB1176_GPIO2 } +#define GPIO3_IRQ { IRQ_PB1176_GPIO3 } +#define AACI_IRQ { IRQ_PB1176_AACI } #define MMCI0_IRQ { IRQ_PB1176_MMCI0A, IRQ_PB1176_MMCI0B } -#define KMI0_IRQ { IRQ_PB1176_KMI0, NO_IRQ } -#define KMI1_IRQ { IRQ_PB1176_KMI1, NO_IRQ } -#define PB1176_SMC_IRQ { NO_IRQ, NO_IRQ } -#define MPMC_IRQ { NO_IRQ, NO_IRQ } -#define PB1176_CLCD_IRQ { IRQ_DC1176_CLCD, NO_IRQ } -#define SCTL_IRQ { NO_IRQ, NO_IRQ } -#define PB1176_WATCHDOG_IRQ { IRQ_DC1176_WATCHDOG, NO_IRQ } -#define PB1176_GPIO0_IRQ { IRQ_PB1176_GPIO0, NO_IRQ } -#define GPIO1_IRQ { IRQ_PB1176_GPIO1, NO_IRQ } -#define PB1176_RTC_IRQ { IRQ_DC1176_RTC, NO_IRQ } -#define SCI_IRQ { IRQ_PB1176_SCI, NO_IRQ } -#define PB1176_UART0_IRQ { IRQ_DC1176_UART0, NO_IRQ } -#define PB1176_UART1_IRQ { IRQ_DC1176_UART1, NO_IRQ } -#define PB1176_UART2_IRQ { IRQ_DC1176_UART2, NO_IRQ } -#define PB1176_UART3_IRQ { IRQ_DC1176_UART3, NO_IRQ } -#define PB1176_UART4_IRQ { IRQ_PB1176_UART4, NO_IRQ } -#define PB1176_SSP_IRQ { IRQ_DC1176_SSP, NO_IRQ } +#define KMI0_IRQ { IRQ_PB1176_KMI0 } +#define KMI1_IRQ { IRQ_PB1176_KMI1 } +#define PB1176_SMC_IRQ { } +#define MPMC_IRQ { } +#define PB1176_CLCD_IRQ { IRQ_DC1176_CLCD } +#define SCTL_IRQ { } +#define PB1176_WATCHDOG_IRQ { IRQ_DC1176_WATCHDOG } +#define PB1176_GPIO0_IRQ { IRQ_DC1176_GPIO0 } +#define GPIO1_IRQ { IRQ_PB1176_GPIO1 } +#define PB1176_RTC_IRQ { IRQ_DC1176_RTC } +#define SCI_IRQ { IRQ_PB1176_SCI } +#define PB1176_UART0_IRQ { IRQ_DC1176_UART0 } +#define PB1176_UART1_IRQ { IRQ_DC1176_UART1 } +#define PB1176_UART2_IRQ { IRQ_DC1176_UART2 } +#define PB1176_UART3_IRQ { IRQ_DC1176_UART3 } +#define PB1176_UART4_IRQ { IRQ_PB1176_UART4 } +#define PB1176_SSP_IRQ { IRQ_DC1176_SSP } /* FPGA Primecells */ -AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL); -AMBA_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data); -AMBA_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL); -AMBA_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL); -AMBA_DEVICE(uart4, "fpga:uart4", PB1176_UART4, NULL); +APB_DEVICE(aaci, "fpga:aaci", AACI, NULL); +APB_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data); +APB_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL); +APB_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL); +APB_DEVICE(uart4, "fpga:uart4", PB1176_UART4, NULL); /* DevChip Primecells */ -AMBA_DEVICE(smc, "dev:smc", PB1176_SMC, NULL); -AMBA_DEVICE(sctl, "dev:sctl", SCTL, NULL); -AMBA_DEVICE(wdog, "dev:wdog", PB1176_WATCHDOG, NULL); -AMBA_DEVICE(gpio0, "dev:gpio0", PB1176_GPIO0, &gpio0_plat_data); -AMBA_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data); -AMBA_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data); -AMBA_DEVICE(rtc, "dev:rtc", PB1176_RTC, NULL); -AMBA_DEVICE(sci0, "dev:sci0", SCI, NULL); -AMBA_DEVICE(uart0, "dev:uart0", PB1176_UART0, NULL); -AMBA_DEVICE(uart1, "dev:uart1", PB1176_UART1, NULL); -AMBA_DEVICE(uart2, "dev:uart2", PB1176_UART2, NULL); -AMBA_DEVICE(uart3, "dev:uart3", PB1176_UART3, NULL); -AMBA_DEVICE(ssp0, "dev:ssp0", PB1176_SSP, &ssp0_plat_data); -AMBA_DEVICE(clcd, "dev:clcd", PB1176_CLCD, &clcd_plat_data); +AHB_DEVICE(smc, "dev:smc", PB1176_SMC, NULL); +AHB_DEVICE(sctl, "dev:sctl", SCTL, NULL); +APB_DEVICE(wdog, "dev:wdog", PB1176_WATCHDOG, NULL); +APB_DEVICE(gpio0, "dev:gpio0", PB1176_GPIO0, &gpio0_plat_data); +APB_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data); +APB_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data); +APB_DEVICE(rtc, "dev:rtc", PB1176_RTC, NULL); +APB_DEVICE(sci0, "dev:sci0", SCI, NULL); +APB_DEVICE(uart0, "dev:uart0", PB1176_UART0, NULL); +APB_DEVICE(uart1, "dev:uart1", PB1176_UART1, NULL); +APB_DEVICE(uart2, "dev:uart2", PB1176_UART2, NULL); +APB_DEVICE(uart3, "dev:uart3", PB1176_UART3, NULL); +APB_DEVICE(ssp0, "dev:ssp0", PB1176_SSP, &ssp0_plat_data); +AHB_DEVICE(clcd, "dev:clcd", PB1176_CLCD, &clcd_plat_data); static struct amba_device *amba_devs[] __initdata = { &uart0_device, diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c index 2147335..ae7fe54 100644 --- a/arch/arm/mach-realview/realview_pb11mp.c +++ b/arch/arm/mach-realview/realview_pb11mp.c @@ -127,52 +127,52 @@ static struct pl022_ssp_controller ssp0_plat_data = { * RealView PB11MPCore AMBA devices */ -#define GPIO2_IRQ { IRQ_PB11MP_GPIO2, NO_IRQ } -#define GPIO3_IRQ { IRQ_PB11MP_GPIO3, NO_IRQ } -#define AACI_IRQ { IRQ_TC11MP_AACI, NO_IRQ } +#define GPIO2_IRQ { IRQ_PB11MP_GPIO2 } +#define GPIO3_IRQ { IRQ_PB11MP_GPIO3 } +#define AACI_IRQ { IRQ_TC11MP_AACI } #define MMCI0_IRQ { IRQ_TC11MP_MMCI0A, IRQ_TC11MP_MMCI0B } -#define KMI0_IRQ { IRQ_TC11MP_KMI0, NO_IRQ } -#define KMI1_IRQ { IRQ_TC11MP_KMI1, NO_IRQ } -#define PB11MP_SMC_IRQ { NO_IRQ, NO_IRQ } -#define MPMC_IRQ { NO_IRQ, NO_IRQ } -#define PB11MP_CLCD_IRQ { IRQ_PB11MP_CLCD, NO_IRQ } -#define DMAC_IRQ { IRQ_PB11MP_DMAC, NO_IRQ } -#define SCTL_IRQ { NO_IRQ, NO_IRQ } -#define PB11MP_WATCHDOG_IRQ { IRQ_PB11MP_WATCHDOG, NO_IRQ } -#define PB11MP_GPIO0_IRQ { IRQ_PB11MP_GPIO0, NO_IRQ } -#define GPIO1_IRQ { IRQ_PB11MP_GPIO1, NO_IRQ } -#define PB11MP_RTC_IRQ { IRQ_TC11MP_RTC, NO_IRQ } -#define SCI_IRQ { IRQ_PB11MP_SCI, NO_IRQ } -#define PB11MP_UART0_IRQ { IRQ_TC11MP_UART0, NO_IRQ } -#define PB11MP_UART1_IRQ { IRQ_TC11MP_UART1, NO_IRQ } -#define PB11MP_UART2_IRQ { IRQ_PB11MP_UART2, NO_IRQ } -#define PB11MP_UART3_IRQ { IRQ_PB11MP_UART3, NO_IRQ } -#define PB11MP_SSP_IRQ { IRQ_PB11MP_SSP, NO_IRQ } +#define KMI0_IRQ { IRQ_TC11MP_KMI0 } +#define KMI1_IRQ { IRQ_TC11MP_KMI1 } +#define PB11MP_SMC_IRQ { } +#define MPMC_IRQ { } +#define PB11MP_CLCD_IRQ { IRQ_PB11MP_CLCD } +#define DMAC_IRQ { IRQ_PB11MP_DMAC } +#define SCTL_IRQ { } +#define PB11MP_WATCHDOG_IRQ { IRQ_PB11MP_WATCHDOG } +#define PB11MP_GPIO0_IRQ { IRQ_PB11MP_GPIO0 } +#define GPIO1_IRQ { IRQ_PB11MP_GPIO1 } +#define PB11MP_RTC_IRQ { IRQ_TC11MP_RTC } +#define SCI_IRQ { IRQ_PB11MP_SCI } +#define PB11MP_UART0_IRQ { IRQ_TC11MP_UART0 } +#define PB11MP_UART1_IRQ { IRQ_TC11MP_UART1 } +#define PB11MP_UART2_IRQ { IRQ_PB11MP_UART2 } +#define PB11MP_UART3_IRQ { IRQ_PB11MP_UART3 } +#define PB11MP_SSP_IRQ { IRQ_PB11MP_SSP } /* FPGA Primecells */ -AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL); -AMBA_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data); -AMBA_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL); -AMBA_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL); -AMBA_DEVICE(uart3, "fpga:uart3", PB11MP_UART3, NULL); +APB_DEVICE(aaci, "fpga:aaci", AACI, NULL); +APB_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data); +APB_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL); +APB_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL); +APB_DEVICE(uart3, "fpga:uart3", PB11MP_UART3, NULL); /* DevChip Primecells */ -AMBA_DEVICE(smc, "dev:smc", PB11MP_SMC, NULL); -AMBA_DEVICE(sctl, "dev:sctl", SCTL, NULL); -AMBA_DEVICE(wdog, "dev:wdog", PB11MP_WATCHDOG, NULL); -AMBA_DEVICE(gpio0, "dev:gpio0", PB11MP_GPIO0, &gpio0_plat_data); -AMBA_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data); -AMBA_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data); -AMBA_DEVICE(rtc, "dev:rtc", PB11MP_RTC, NULL); -AMBA_DEVICE(sci0, "dev:sci0", SCI, NULL); -AMBA_DEVICE(uart0, "dev:uart0", PB11MP_UART0, NULL); -AMBA_DEVICE(uart1, "dev:uart1", PB11MP_UART1, NULL); -AMBA_DEVICE(uart2, "dev:uart2", PB11MP_UART2, NULL); -AMBA_DEVICE(ssp0, "dev:ssp0", PB11MP_SSP, &ssp0_plat_data); +AHB_DEVICE(smc, "dev:smc", PB11MP_SMC, NULL); +AHB_DEVICE(sctl, "dev:sctl", SCTL, NULL); +APB_DEVICE(wdog, "dev:wdog", PB11MP_WATCHDOG, NULL); +APB_DEVICE(gpio0, "dev:gpio0", PB11MP_GPIO0, &gpio0_plat_data); +APB_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data); +APB_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data); +APB_DEVICE(rtc, "dev:rtc", PB11MP_RTC, NULL); +APB_DEVICE(sci0, "dev:sci0", SCI, NULL); +APB_DEVICE(uart0, "dev:uart0", PB11MP_UART0, NULL); +APB_DEVICE(uart1, "dev:uart1", PB11MP_UART1, NULL); +APB_DEVICE(uart2, "dev:uart2", PB11MP_UART2, NULL); +APB_DEVICE(ssp0, "dev:ssp0", PB11MP_SSP, &ssp0_plat_data); /* Primecells on the NEC ISSP chip */ -AMBA_DEVICE(clcd, "issp:clcd", PB11MP_CLCD, &clcd_plat_data); -AMBA_DEVICE(dmac, "issp:dmac", DMAC, NULL); +AHB_DEVICE(clcd, "issp:clcd", PB11MP_CLCD, &clcd_plat_data); +AHB_DEVICE(dmac, "issp:dmac", DMAC, NULL); static struct amba_device *amba_devs[] __initdata = { &dmac_device, diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c index 25b2e59..5965017 100644 --- a/arch/arm/mach-realview/realview_pba8.c +++ b/arch/arm/mach-realview/realview_pba8.c @@ -122,52 +122,52 @@ static struct pl022_ssp_controller ssp0_plat_data = { * RealView PBA8Core AMBA devices */ -#define GPIO2_IRQ { IRQ_PBA8_GPIO2, NO_IRQ } -#define GPIO3_IRQ { IRQ_PBA8_GPIO3, NO_IRQ } -#define AACI_IRQ { IRQ_PBA8_AACI, NO_IRQ } +#define GPIO2_IRQ { IRQ_PBA8_GPIO2 } +#define GPIO3_IRQ { IRQ_PBA8_GPIO3 } +#define AACI_IRQ { IRQ_PBA8_AACI } #define MMCI0_IRQ { IRQ_PBA8_MMCI0A, IRQ_PBA8_MMCI0B } -#define KMI0_IRQ { IRQ_PBA8_KMI0, NO_IRQ } -#define KMI1_IRQ { IRQ_PBA8_KMI1, NO_IRQ } -#define PBA8_SMC_IRQ { NO_IRQ, NO_IRQ } -#define MPMC_IRQ { NO_IRQ, NO_IRQ } -#define PBA8_CLCD_IRQ { IRQ_PBA8_CLCD, NO_IRQ } -#define DMAC_IRQ { IRQ_PBA8_DMAC, NO_IRQ } -#define SCTL_IRQ { NO_IRQ, NO_IRQ } -#define PBA8_WATCHDOG_IRQ { IRQ_PBA8_WATCHDOG, NO_IRQ } -#define PBA8_GPIO0_IRQ { IRQ_PBA8_GPIO0, NO_IRQ } -#define GPIO1_IRQ { IRQ_PBA8_GPIO1, NO_IRQ } -#define PBA8_RTC_IRQ { IRQ_PBA8_RTC, NO_IRQ } -#define SCI_IRQ { IRQ_PBA8_SCI, NO_IRQ } -#define PBA8_UART0_IRQ { IRQ_PBA8_UART0, NO_IRQ } -#define PBA8_UART1_IRQ { IRQ_PBA8_UART1, NO_IRQ } -#define PBA8_UART2_IRQ { IRQ_PBA8_UART2, NO_IRQ } -#define PBA8_UART3_IRQ { IRQ_PBA8_UART3, NO_IRQ } -#define PBA8_SSP_IRQ { IRQ_PBA8_SSP, NO_IRQ } +#define KMI0_IRQ { IRQ_PBA8_KMI0 } +#define KMI1_IRQ { IRQ_PBA8_KMI1 } +#define PBA8_SMC_IRQ { } +#define MPMC_IRQ { } +#define PBA8_CLCD_IRQ { IRQ_PBA8_CLCD } +#define DMAC_IRQ { IRQ_PBA8_DMAC } +#define SCTL_IRQ { } +#define PBA8_WATCHDOG_IRQ { IRQ_PBA8_WATCHDOG } +#define PBA8_GPIO0_IRQ { IRQ_PBA8_GPIO0 } +#define GPIO1_IRQ { IRQ_PBA8_GPIO1 } +#define PBA8_RTC_IRQ { IRQ_PBA8_RTC } +#define SCI_IRQ { IRQ_PBA8_SCI } +#define PBA8_UART0_IRQ { IRQ_PBA8_UART0 } +#define PBA8_UART1_IRQ { IRQ_PBA8_UART1 } +#define PBA8_UART2_IRQ { IRQ_PBA8_UART2 } +#define PBA8_UART3_IRQ { IRQ_PBA8_UART3 } +#define PBA8_SSP_IRQ { IRQ_PBA8_SSP } /* FPGA Primecells */ -AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL); -AMBA_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data); -AMBA_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL); -AMBA_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL); -AMBA_DEVICE(uart3, "fpga:uart3", PBA8_UART3, NULL); +APB_DEVICE(aaci, "fpga:aaci", AACI, NULL); +APB_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data); +APB_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL); +APB_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL); +APB_DEVICE(uart3, "fpga:uart3", PBA8_UART3, NULL); /* DevChip Primecells */ -AMBA_DEVICE(smc, "dev:smc", PBA8_SMC, NULL); -AMBA_DEVICE(sctl, "dev:sctl", SCTL, NULL); -AMBA_DEVICE(wdog, "dev:wdog", PBA8_WATCHDOG, NULL); -AMBA_DEVICE(gpio0, "dev:gpio0", PBA8_GPIO0, &gpio0_plat_data); -AMBA_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data); -AMBA_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data); -AMBA_DEVICE(rtc, "dev:rtc", PBA8_RTC, NULL); -AMBA_DEVICE(sci0, "dev:sci0", SCI, NULL); -AMBA_DEVICE(uart0, "dev:uart0", PBA8_UART0, NULL); -AMBA_DEVICE(uart1, "dev:uart1", PBA8_UART1, NULL); -AMBA_DEVICE(uart2, "dev:uart2", PBA8_UART2, NULL); -AMBA_DEVICE(ssp0, "dev:ssp0", PBA8_SSP, &ssp0_plat_data); +AHB_DEVICE(smc, "dev:smc", PBA8_SMC, NULL); +AHB_DEVICE(sctl, "dev:sctl", SCTL, NULL); +APB_DEVICE(wdog, "dev:wdog", PBA8_WATCHDOG, NULL); +APB_DEVICE(gpio0, "dev:gpio0", PBA8_GPIO0, &gpio0_plat_data); +APB_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data); +APB_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data); +APB_DEVICE(rtc, "dev:rtc", PBA8_RTC, NULL); +APB_DEVICE(sci0, "dev:sci0", SCI, NULL); +APB_DEVICE(uart0, "dev:uart0", PBA8_UART0, NULL); +APB_DEVICE(uart1, "dev:uart1", PBA8_UART1, NULL); +APB_DEVICE(uart2, "dev:uart2", PBA8_UART2, NULL); +APB_DEVICE(ssp0, "dev:ssp0", PBA8_SSP, &ssp0_plat_data); /* Primecells on the NEC ISSP chip */ -AMBA_DEVICE(clcd, "issp:clcd", PBA8_CLCD, &clcd_plat_data); -AMBA_DEVICE(dmac, "issp:dmac", DMAC, NULL); +AHB_DEVICE(clcd, "issp:clcd", PBA8_CLCD, &clcd_plat_data); +AHB_DEVICE(dmac, "issp:dmac", DMAC, NULL); static struct amba_device *amba_devs[] __initdata = { &dmac_device, diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c index ac71564..1cd9956 100644 --- a/arch/arm/mach-realview/realview_pbx.c +++ b/arch/arm/mach-realview/realview_pbx.c @@ -144,52 +144,52 @@ static struct pl022_ssp_controller ssp0_plat_data = { * RealView PBXCore AMBA devices */ -#define GPIO2_IRQ { IRQ_PBX_GPIO2, NO_IRQ } -#define GPIO3_IRQ { IRQ_PBX_GPIO3, NO_IRQ } -#define AACI_IRQ { IRQ_PBX_AACI, NO_IRQ } +#define GPIO2_IRQ { IRQ_PBX_GPIO2 } +#define GPIO3_IRQ { IRQ_PBX_GPIO3 } +#define AACI_IRQ { IRQ_PBX_AACI } #define MMCI0_IRQ { IRQ_PBX_MMCI0A, IRQ_PBX_MMCI0B } -#define KMI0_IRQ { IRQ_PBX_KMI0, NO_IRQ } -#define KMI1_IRQ { IRQ_PBX_KMI1, NO_IRQ } -#define PBX_SMC_IRQ { NO_IRQ, NO_IRQ } -#define MPMC_IRQ { NO_IRQ, NO_IRQ } -#define PBX_CLCD_IRQ { IRQ_PBX_CLCD, NO_IRQ } -#define DMAC_IRQ { IRQ_PBX_DMAC, NO_IRQ } -#define SCTL_IRQ { NO_IRQ, NO_IRQ } -#define PBX_WATCHDOG_IRQ { IRQ_PBX_WATCHDOG, NO_IRQ } -#define PBX_GPIO0_IRQ { IRQ_PBX_GPIO0, NO_IRQ } -#define GPIO1_IRQ { IRQ_PBX_GPIO1, NO_IRQ } -#define PBX_RTC_IRQ { IRQ_PBX_RTC, NO_IRQ } -#define SCI_IRQ { IRQ_PBX_SCI, NO_IRQ } -#define PBX_UART0_IRQ { IRQ_PBX_UART0, NO_IRQ } -#define PBX_UART1_IRQ { IRQ_PBX_UART1, NO_IRQ } -#define PBX_UART2_IRQ { IRQ_PBX_UART2, NO_IRQ } -#define PBX_UART3_IRQ { IRQ_PBX_UART3, NO_IRQ } -#define PBX_SSP_IRQ { IRQ_PBX_SSP, NO_IRQ } +#define KMI0_IRQ { IRQ_PBX_KMI0 } +#define KMI1_IRQ { IRQ_PBX_KMI1 } +#define PBX_SMC_IRQ { } +#define MPMC_IRQ { } +#define PBX_CLCD_IRQ { IRQ_PBX_CLCD } +#define DMAC_IRQ { IRQ_PBX_DMAC } +#define SCTL_IRQ { } +#define PBX_WATCHDOG_IRQ { IRQ_PBX_WATCHDOG } +#define PBX_GPIO0_IRQ { IRQ_PBX_GPIO0 } +#define GPIO1_IRQ { IRQ_PBX_GPIO1 } +#define PBX_RTC_IRQ { IRQ_PBX_RTC } +#define SCI_IRQ { IRQ_PBX_SCI } +#define PBX_UART0_IRQ { IRQ_PBX_UART0 } +#define PBX_UART1_IRQ { IRQ_PBX_UART1 } +#define PBX_UART2_IRQ { IRQ_PBX_UART2 } +#define PBX_UART3_IRQ { IRQ_PBX_UART3 } +#define PBX_SSP_IRQ { IRQ_PBX_SSP } /* FPGA Primecells */ -AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL); -AMBA_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data); -AMBA_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL); -AMBA_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL); -AMBA_DEVICE(uart3, "fpga:uart3", PBX_UART3, NULL); +APB_DEVICE(aaci, "fpga:aaci", AACI, NULL); +APB_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data); +APB_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL); +APB_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL); +APB_DEVICE(uart3, "fpga:uart3", PBX_UART3, NULL); /* DevChip Primecells */ -AMBA_DEVICE(smc, "dev:smc", PBX_SMC, NULL); -AMBA_DEVICE(sctl, "dev:sctl", SCTL, NULL); -AMBA_DEVICE(wdog, "dev:wdog", PBX_WATCHDOG, NULL); -AMBA_DEVICE(gpio0, "dev:gpio0", PBX_GPIO0, &gpio0_plat_data); -AMBA_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data); -AMBA_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data); -AMBA_DEVICE(rtc, "dev:rtc", PBX_RTC, NULL); -AMBA_DEVICE(sci0, "dev:sci0", SCI, NULL); -AMBA_DEVICE(uart0, "dev:uart0", PBX_UART0, NULL); -AMBA_DEVICE(uart1, "dev:uart1", PBX_UART1, NULL); -AMBA_DEVICE(uart2, "dev:uart2", PBX_UART2, NULL); -AMBA_DEVICE(ssp0, "dev:ssp0", PBX_SSP, &ssp0_plat_data); +AHB_DEVICE(smc, "dev:smc", PBX_SMC, NULL); +AHB_DEVICE(sctl, "dev:sctl", SCTL, NULL); +APB_DEVICE(wdog, "dev:wdog", PBX_WATCHDOG, NULL); +APB_DEVICE(gpio0, "dev:gpio0", PBX_GPIO0, &gpio0_plat_data); +APB_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data); +APB_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data); +APB_DEVICE(rtc, "dev:rtc", PBX_RTC, NULL); +APB_DEVICE(sci0, "dev:sci0", SCI, NULL); +APB_DEVICE(uart0, "dev:uart0", PBX_UART0, NULL); +APB_DEVICE(uart1, "dev:uart1", PBX_UART1, NULL); +APB_DEVICE(uart2, "dev:uart2", PBX_UART2, NULL); +APB_DEVICE(ssp0, "dev:ssp0", PBX_SSP, &ssp0_plat_data); /* Primecells on the NEC ISSP chip */ -AMBA_DEVICE(clcd, "issp:clcd", PBX_CLCD, &clcd_plat_data); -AMBA_DEVICE(dmac, "issp:dmac", DMAC, NULL); +AHB_DEVICE(clcd, "issp:clcd", PBX_CLCD, &clcd_plat_data); +AHB_DEVICE(dmac, "issp:dmac", DMAC, NULL); static struct amba_device *amba_devs[] __initdata = { &dmac_device, diff --git a/arch/arm/mach-rpc/include/mach/system.h b/arch/arm/mach-rpc/include/mach/system.h deleted file mode 100644 index 359bab9..0000000 --- a/arch/arm/mach-rpc/include/mach/system.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/arm/mach-rpc/include/mach/system.h - * - * Copyright (C) 1996-1999 Russell King. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -static inline void arch_idle(void) -{ - cpu_do_idle(); -} diff --git a/arch/arm/mach-s3c2410/include/mach/system.h b/arch/arm/mach-s3c2410/include/mach/system.h deleted file mode 100644 index 5e215c1..0000000 --- a/arch/arm/mach-s3c2410/include/mach/system.h +++ /dev/null @@ -1,54 +0,0 @@ -/* arch/arm/mach-s3c2410/include/mach/system.h - * - * Copyright (c) 2003 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * - * S3C2410 - System function defines and includes - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include <linux/io.h> -#include <mach/hardware.h> - -#include <mach/map.h> -#include <mach/idle.h> - -#include <mach/regs-clock.h> - -void (*s3c24xx_idle)(void); - -void s3c24xx_default_idle(void) -{ - unsigned long tmp; - int i; - - /* idle the system by using the idle mode which will wait for an - * interrupt to happen before restarting the system. - */ - - /* Warning: going into idle state upsets jtag scanning */ - - __raw_writel(__raw_readl(S3C2410_CLKCON) | S3C2410_CLKCON_IDLE, - S3C2410_CLKCON); - - /* the samsung port seems to do a loop and then unset idle.. */ - for (i = 0; i < 50; i++) { - tmp += __raw_readl(S3C2410_CLKCON); /* ensure loop not optimised out */ - } - - /* this bit is not cleared on re-start... */ - - __raw_writel(__raw_readl(S3C2410_CLKCON) & ~S3C2410_CLKCON_IDLE, - S3C2410_CLKCON); -} - -static void arch_idle(void) -{ - if (s3c24xx_idle != NULL) - (s3c24xx_idle)(); - else - s3c24xx_default_idle(); -} diff --git a/arch/arm/mach-s3c2412/s3c2412.c b/arch/arm/mach-s3c2412/s3c2412.c index aff6e85..c6eac98 100644 --- a/arch/arm/mach-s3c2412/s3c2412.c +++ b/arch/arm/mach-s3c2412/s3c2412.c @@ -32,8 +32,6 @@ #include <asm/proc-fns.h> #include <asm/irq.h> -#include <mach/idle.h> - #include <plat/cpu-freq.h> #include <mach/regs-clock.h> @@ -164,7 +162,7 @@ void __init s3c2412_map_io(void) /* set our idle function */ - s3c24xx_idle = s3c2412_idle; + arm_pm_idle = s3c2412_idle; /* register our io-tables */ diff --git a/arch/arm/mach-s3c2416/s3c2416.c b/arch/arm/mach-s3c2416/s3c2416.c index 5287d28..08bb035 100644 --- a/arch/arm/mach-s3c2416/s3c2416.c +++ b/arch/arm/mach-s3c2416/s3c2416.c @@ -44,7 +44,6 @@ #include <asm/proc-fns.h> #include <asm/irq.h> -#include <mach/idle.h> #include <mach/regs-s3c2443-clock.h> #include <plat/gpio-core.h> @@ -88,8 +87,6 @@ int __init s3c2416_init(void) { printk(KERN_INFO "S3C2416: Initializing architecture\n"); - /* s3c24xx_idle = s3c2416_idle; */ - /* change WDT IRQ number */ s3c_device_wdt.resource[1].start = IRQ_S3C2443_WDT; s3c_device_wdt.resource[1].end = IRQ_S3C2443_WDT; diff --git a/arch/arm/mach-s3c64xx/include/mach/system.h b/arch/arm/mach-s3c64xx/include/mach/system.h deleted file mode 100644 index 353ed43..0000000 --- a/arch/arm/mach-s3c64xx/include/mach/system.h +++ /dev/null @@ -1,19 +0,0 @@ -/* linux/arch/arm/mach-s3c6400/include/mach/system.h - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * http://armlinux.simtec.co.uk/ - * - * S3C6400 - system implementation - */ - -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H __FILE__ - -static void arch_idle(void) -{ - /* nothing here yet */ -} - -#endif /* __ASM_ARCH_IRQ_H */ diff --git a/arch/arm/mach-s5p64x0/common.c b/arch/arm/mach-s5p64x0/common.c index 52b89a3..9143f8b 100644 --- a/arch/arm/mach-s5p64x0/common.c +++ b/arch/arm/mach-s5p64x0/common.c @@ -146,15 +146,12 @@ static void s5p64x0_idle(void) { unsigned long val; - if (!need_resched()) { - val = __raw_readl(S5P64X0_PWR_CFG); - val &= ~(0x3 << 5); - val |= (0x1 << 5); - __raw_writel(val, S5P64X0_PWR_CFG); + val = __raw_readl(S5P64X0_PWR_CFG); + val &= ~(0x3 << 5); + val |= (0x1 << 5); + __raw_writel(val, S5P64X0_PWR_CFG); - cpu_do_idle(); - } - local_irq_enable(); + cpu_do_idle(); } /* @@ -286,7 +283,7 @@ int __init s5p64x0_init(void) printk(KERN_INFO "S5P64X0(S5P6440/S5P6450): Initializing architecture\n"); /* set idle function */ - pm_idle = s5p64x0_idle; + arm_pm_idle = s5p64x0_idle; return device_register(&s5p64x0_dev); } diff --git a/arch/arm/mach-s5p64x0/dma.c b/arch/arm/mach-s5p64x0/dma.c index f820c07..f7f68ad 100644 --- a/arch/arm/mach-s5p64x0/dma.c +++ b/arch/arm/mach-s5p64x0/dma.c @@ -108,34 +108,22 @@ struct dma_pl330_platdata s5p6450_pdma_pdata = { .peri_id = s5p6450_pdma_peri, }; -struct amba_device s5p64x0_device_pdma = { - .dev = { - .init_name = "dma-pl330", - .dma_mask = &dma_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .res = { - .start = S5P64X0_PA_PDMA, - .end = S5P64X0_PA_PDMA + SZ_4K, - .flags = IORESOURCE_MEM, - }, - .irq = {IRQ_DMA0, NO_IRQ}, - .periphid = 0x00041330, -}; +AMBA_AHB_DEVICE(s5p64x0_pdma, "dma-pl330", 0x00041330, S5P64X0_PA_PDMA, + {IRQ_DMA0}, NULL); static int __init s5p64x0_dma_init(void) { if (soc_is_s5p6450()) { dma_cap_set(DMA_SLAVE, s5p6450_pdma_pdata.cap_mask); dma_cap_set(DMA_CYCLIC, s5p6450_pdma_pdata.cap_mask); - s5p64x0_device_pdma.dev.platform_data = &s5p6450_pdma_pdata; + s5p64x0_pdma_device.dev.platform_data = &s5p6450_pdma_pdata; } else { dma_cap_set(DMA_SLAVE, s5p6440_pdma_pdata.cap_mask); dma_cap_set(DMA_CYCLIC, s5p6440_pdma_pdata.cap_mask); - s5p64x0_device_pdma.dev.platform_data = &s5p6440_pdma_pdata; + s5p64x0_pdma_device.dev.platform_data = &s5p6440_pdma_pdata; } - amba_device_register(&s5p64x0_device_pdma, &iomem_resource); + amba_device_register(&s5p64x0_pdma_device, &iomem_resource); return 0; } diff --git a/arch/arm/mach-s5p64x0/include/mach/system.h b/arch/arm/mach-s5p64x0/include/mach/system.h deleted file mode 100644 index cf26e09..0000000 --- a/arch/arm/mach-s5p64x0/include/mach/system.h +++ /dev/null @@ -1,21 +0,0 @@ -/* linux/arch/arm/mach-s5p64x0/include/mach/system.h - * - * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * S5P64X0 - system support header - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H __FILE__ - -static void arch_idle(void) -{ - /* nothing here yet */ -} - -#endif /* __ASM_ARCH_SYSTEM_H */ diff --git a/arch/arm/mach-s5pc100/common.c b/arch/arm/mach-s5pc100/common.c index c909573..ff71e2d 100644 --- a/arch/arm/mach-s5pc100/common.c +++ b/arch/arm/mach-s5pc100/common.c @@ -129,14 +129,6 @@ static struct map_desc s5pc100_iodesc[] __initdata = { } }; -static void s5pc100_idle(void) -{ - if (!need_resched()) - cpu_do_idle(); - - local_irq_enable(); -} - /* * s5pc100_map_io * @@ -210,10 +202,6 @@ core_initcall(s5pc100_core_init); int __init s5pc100_init(void) { printk(KERN_INFO "S5PC100: Initializing architecture\n"); - - /* set idle function */ - pm_idle = s5pc100_idle; - return device_register(&s5pc100_dev); } diff --git a/arch/arm/mach-s5pc100/dma.c b/arch/arm/mach-s5pc100/dma.c index c841f4d3..96b1ab3 100644 --- a/arch/arm/mach-s5pc100/dma.c +++ b/arch/arm/mach-s5pc100/dma.c @@ -73,21 +73,8 @@ struct dma_pl330_platdata s5pc100_pdma0_pdata = { .peri_id = pdma0_peri, }; -struct amba_device s5pc100_device_pdma0 = { - .dev = { - .init_name = "dma-pl330.0", - .dma_mask = &dma_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &s5pc100_pdma0_pdata, - }, - .res = { - .start = S5PC100_PA_PDMA0, - .end = S5PC100_PA_PDMA0 + SZ_4K, - .flags = IORESOURCE_MEM, - }, - .irq = {IRQ_PDMA0, NO_IRQ}, - .periphid = 0x00041330, -}; +AMBA_AHB_DEVICE(s5pc100_pdma0, "dma-pl330.0", 0x00041330, S5PC100_PA_PDMA0, + {IRQ_PDMA0}, &s5pc100_pdma0_pdata); u8 pdma1_peri[] = { DMACH_UART0_RX, @@ -127,31 +114,18 @@ struct dma_pl330_platdata s5pc100_pdma1_pdata = { .peri_id = pdma1_peri, }; -struct amba_device s5pc100_device_pdma1 = { - .dev = { - .init_name = "dma-pl330.1", - .dma_mask = &dma_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &s5pc100_pdma1_pdata, - }, - .res = { - .start = S5PC100_PA_PDMA1, - .end = S5PC100_PA_PDMA1 + SZ_4K, - .flags = IORESOURCE_MEM, - }, - .irq = {IRQ_PDMA1, NO_IRQ}, - .periphid = 0x00041330, -}; +AMBA_AHB_DEVICE(s5pc100_pdma1, "dma-pl330.1", 0x00041330, S5PC100_PA_PDMA1, + {IRQ_PDMA1}, &s5pc100_pdma1_pdata); static int __init s5pc100_dma_init(void) { dma_cap_set(DMA_SLAVE, s5pc100_pdma0_pdata.cap_mask); dma_cap_set(DMA_CYCLIC, s5pc100_pdma0_pdata.cap_mask); - amba_device_register(&s5pc100_device_pdma0, &iomem_resource); + amba_device_register(&s5pc100_pdma0_device, &iomem_resource); dma_cap_set(DMA_SLAVE, s5pc100_pdma1_pdata.cap_mask); dma_cap_set(DMA_CYCLIC, s5pc100_pdma1_pdata.cap_mask); - amba_device_register(&s5pc100_device_pdma1, &iomem_resource); + amba_device_register(&s5pc100_pdma1_device, &iomem_resource); return 0; } diff --git a/arch/arm/mach-s5pc100/include/mach/system.h b/arch/arm/mach-s5pc100/include/mach/system.h deleted file mode 100644 index afc96c2..0000000 --- a/arch/arm/mach-s5pc100/include/mach/system.h +++ /dev/null @@ -1,19 +0,0 @@ -/* linux/arch/arm/mach-s5pc100/include/mach/system.h - * - * Copyright 2009 Samsung Electronics Co. - * Byungho Min <bhmin@samsung.com> - * - * S5PC100 - system implementation - * - * Based on mach-s3c6400/include/mach/system.h - */ - -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H __FILE__ - -static void arch_idle(void) -{ - /* nothing here yet */ -} - -#endif /* __ASM_ARCH_IRQ_H */ diff --git a/arch/arm/mach-s5pv210/common.c b/arch/arm/mach-s5pv210/common.c index 9c1bcdc..4c9e902 100644 --- a/arch/arm/mach-s5pv210/common.c +++ b/arch/arm/mach-s5pv210/common.c @@ -142,14 +142,6 @@ static struct map_desc s5pv210_iodesc[] __initdata = { } }; -static void s5pv210_idle(void) -{ - if (!need_resched()) - cpu_do_idle(); - - local_irq_enable(); -} - void s5pv210_restart(char mode, const char *cmd) { __raw_writel(0x1, S5P_SWRESET); @@ -247,10 +239,6 @@ core_initcall(s5pv210_core_init); int __init s5pv210_init(void) { printk(KERN_INFO "S5PV210: Initializing architecture\n"); - - /* set idle function */ - pm_idle = s5pv210_idle; - return device_register(&s5pv210_dev); } diff --git a/arch/arm/mach-s5pv210/dma.c b/arch/arm/mach-s5pv210/dma.c index a6113e0..f6885d2 100644 --- a/arch/arm/mach-s5pv210/dma.c +++ b/arch/arm/mach-s5pv210/dma.c @@ -71,21 +71,8 @@ struct dma_pl330_platdata s5pv210_pdma0_pdata = { .peri_id = pdma0_peri, }; -struct amba_device s5pv210_device_pdma0 = { - .dev = { - .init_name = "dma-pl330.0", - .dma_mask = &dma_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &s5pv210_pdma0_pdata, - }, - .res = { - .start = S5PV210_PA_PDMA0, - .end = S5PV210_PA_PDMA0 + SZ_4K, - .flags = IORESOURCE_MEM, - }, - .irq = {IRQ_PDMA0, NO_IRQ}, - .periphid = 0x00041330, -}; +AMBA_AHB_DEVICE(s5pv210_pdma0, "dma-pl330.0", 0x00041330, S5PV210_PA_PDMA0, + {IRQ_PDMA0}, &s5pv210_pdma0_pdata); u8 pdma1_peri[] = { DMACH_UART0_RX, @@ -127,31 +114,18 @@ struct dma_pl330_platdata s5pv210_pdma1_pdata = { .peri_id = pdma1_peri, }; -struct amba_device s5pv210_device_pdma1 = { - .dev = { - .init_name = "dma-pl330.1", - .dma_mask = &dma_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &s5pv210_pdma1_pdata, - }, - .res = { - .start = S5PV210_PA_PDMA1, - .end = S5PV210_PA_PDMA1 + SZ_4K, - .flags = IORESOURCE_MEM, - }, - .irq = {IRQ_PDMA1, NO_IRQ}, - .periphid = 0x00041330, -}; +AMBA_AHB_DEVICE(s5pv210_pdma1, "dma-pl330.1", 0x00041330, S5PV210_PA_PDMA1, + {IRQ_PDMA1}, &s5pv210_pdma1_pdata); static int __init s5pv210_dma_init(void) { dma_cap_set(DMA_SLAVE, s5pv210_pdma0_pdata.cap_mask); dma_cap_set(DMA_CYCLIC, s5pv210_pdma0_pdata.cap_mask); - amba_device_register(&s5pv210_device_pdma0, &iomem_resource); + amba_device_register(&s5pv210_pdma0_device, &iomem_resource); dma_cap_set(DMA_SLAVE, s5pv210_pdma1_pdata.cap_mask); dma_cap_set(DMA_CYCLIC, s5pv210_pdma1_pdata.cap_mask); - amba_device_register(&s5pv210_device_pdma1, &iomem_resource); + amba_device_register(&s5pv210_pdma1_device, &iomem_resource); return 0; } diff --git a/arch/arm/mach-s5pv210/include/mach/system.h b/arch/arm/mach-s5pv210/include/mach/system.h deleted file mode 100644 index bf288ce..0000000 --- a/arch/arm/mach-s5pv210/include/mach/system.h +++ /dev/null @@ -1,21 +0,0 @@ -/* linux/arch/arm/mach-s5pv210/include/mach/system.h - * - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * S5PV210 - system support header - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H __FILE__ - -static void arch_idle(void) -{ - /* nothing here yet */ -} - -#endif /* __ASM_ARCH_SYSTEM_H */ diff --git a/arch/arm/mach-sa1100/include/mach/system.h b/arch/arm/mach-sa1100/include/mach/system.h deleted file mode 100644 index e17b208..0000000 --- a/arch/arm/mach-sa1100/include/mach/system.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * arch/arm/mach-sa1100/include/mach/system.h - * - * Copyright (c) 1999 Nicolas Pitre <nico@fluxnic.net> - */ -static inline void arch_idle(void) -{ - cpu_do_idle(); -} diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c index a851c25..6a2a7f2 100644 --- a/arch/arm/mach-shark/core.c +++ b/arch/arm/mach-shark/core.c @@ -149,10 +149,16 @@ static struct sys_timer shark_timer = { .init = shark_timer_init, }; +static void shark_init_early(void) +{ + disable_hlt(); +} + MACHINE_START(SHARK, "Shark") /* Maintainer: Alexander Schulz */ .atag_offset = 0x3000, .map_io = shark_map_io, + .init_early = shark_init_early, .init_irq = shark_init_irq, .timer = &shark_timer, .dma_zone_size = SZ_4M, diff --git a/arch/arm/mach-shark/include/mach/system.h b/arch/arm/mach-shark/include/mach/system.h deleted file mode 100644 index 1b2f2c5..0000000 --- a/arch/arm/mach-shark/include/mach/system.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/arm/mach-shark/include/mach/system.h - * - * by Alexander Schulz - */ -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static inline void arch_idle(void) -{ -} - -#endif diff --git a/arch/arm/mach-shmobile/include/mach/system.h b/arch/arm/mach-shmobile/include/mach/system.h index 956ac18..3bbcb3f 100644 --- a/arch/arm/mach-shmobile/include/mach/system.h +++ b/arch/arm/mach-shmobile/include/mach/system.h @@ -1,11 +1,6 @@ #ifndef __ASM_ARCH_SYSTEM_H #define __ASM_ARCH_SYSTEM_H -static inline void arch_idle(void) -{ - cpu_do_idle(); -} - static inline void arch_reset(char mode, const char *cmd) { soft_restart(0); diff --git a/arch/arm/mach-spear3xx/include/mach/system.h b/arch/arm/mach-spear3xx/include/mach/system.h deleted file mode 100644 index 92cee63..0000000 --- a/arch/arm/mach-spear3xx/include/mach/system.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * arch/arm/mach-spear3xx/include/mach/system.h - * - * SPEAr3xx Machine family specific architecture functions - * - * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar<viresh.kumar@st.com> - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#ifndef __MACH_SYSTEM_H -#define __MACH_SYSTEM_H - -#include <plat/system.h> - -#endif /* __MACH_SYSTEM_H */ diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c index a5e46b4..9da50e281 100644 --- a/arch/arm/mach-spear3xx/spear300.c +++ b/arch/arm/mach-spear3xx/spear300.c @@ -430,18 +430,8 @@ static struct pl061_platform_data gpio1_plat_data = { .irq_base = SPEAR300_GPIO1_INT_BASE, }; -struct amba_device spear300_gpio1_device = { - .dev = { - .init_name = "gpio1", - .platform_data = &gpio1_plat_data, - }, - .res = { - .start = SPEAR300_GPIO_BASE, - .end = SPEAR300_GPIO_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = {SPEAR300_VIRQ_GPIO1, NO_IRQ}, -}; +AMBA_APB_DEVICE(spear300_gpio1, "gpio1", 0, SPEAR300_GPIO_BASE, + {SPEAR300_VIRQ_GPIO1}, &gpio1_plat_data); /* spear300 routines */ void __init spear300_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs, diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c index 10af45d..b1733c3 100644 --- a/arch/arm/mach-spear3xx/spear3xx.c +++ b/arch/arm/mach-spear3xx/spear3xx.c @@ -28,31 +28,12 @@ static struct pl061_platform_data gpio_plat_data = { .irq_base = SPEAR3XX_GPIO_INT_BASE, }; -struct amba_device spear3xx_gpio_device = { - .dev = { - .init_name = "gpio", - .platform_data = &gpio_plat_data, - }, - .res = { - .start = SPEAR3XX_ICM3_GPIO_BASE, - .end = SPEAR3XX_ICM3_GPIO_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = {SPEAR3XX_IRQ_BASIC_GPIO, NO_IRQ}, -}; +AMBA_APB_DEVICE(spear3xx_gpio, "gpio", 0, SPEAR3XX_ICM3_GPIO_BASE, + {SPEAR3XX_IRQ_BASIC_GPIO}, &gpio_plat_data); /* uart device registration */ -struct amba_device spear3xx_uart_device = { - .dev = { - .init_name = "uart", - }, - .res = { - .start = SPEAR3XX_ICM1_UART_BASE, - .end = SPEAR3XX_ICM1_UART_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = {SPEAR3XX_IRQ_UART, NO_IRQ}, -}; +AMBA_APB_DEVICE(spear3xx_uart, "uart", 0, SPEAR3XX_ICM1_UART_BASE, + {SPEAR3XX_IRQ_UART}, NULL); /* Do spear3xx familiy common initialization part here */ void __init spear3xx_init(void) diff --git a/arch/arm/mach-spear6xx/include/mach/system.h b/arch/arm/mach-spear6xx/include/mach/system.h deleted file mode 100644 index 0b1d2be..0000000 --- a/arch/arm/mach-spear6xx/include/mach/system.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * arch/arm/mach-spear6xx/include/mach/system.h - * - * SPEAr6xx Machine family specific architecture functions - * - * Copyright (C) 2009 ST Microelectronics - * Rajeev Kumar<rajeev-dlh.kumar@st.com> - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#ifndef __MACH_SYSTEM_H -#define __MACH_SYSTEM_H - -#include <plat/system.h> - -#endif /* __MACH_SYSTEM_H */ diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c index e0f6628..b997b1b 100644 --- a/arch/arm/mach-spear6xx/spear6xx.c +++ b/arch/arm/mach-spear6xx/spear6xx.c @@ -34,7 +34,7 @@ struct amba_device uart_device[] = { .end = SPEAR6XX_ICM1_UART0_BASE + SZ_4K - 1, .flags = IORESOURCE_MEM, }, - .irq = {IRQ_UART_0, NO_IRQ}, + .irq = {IRQ_UART_0}, }, { .dev = { .init_name = "uart1", @@ -44,7 +44,7 @@ struct amba_device uart_device[] = { .end = SPEAR6XX_ICM1_UART1_BASE + SZ_4K - 1, .flags = IORESOURCE_MEM, }, - .irq = {IRQ_UART_1, NO_IRQ}, + .irq = {IRQ_UART_1}, } }; @@ -73,7 +73,7 @@ struct amba_device gpio_device[] = { .end = SPEAR6XX_CPU_GPIO_BASE + SZ_4K - 1, .flags = IORESOURCE_MEM, }, - .irq = {IRQ_LOCAL_GPIO, NO_IRQ}, + .irq = {IRQ_LOCAL_GPIO}, }, { .dev = { .init_name = "gpio1", @@ -84,7 +84,7 @@ struct amba_device gpio_device[] = { .end = SPEAR6XX_ICM3_GPIO_BASE + SZ_4K - 1, .flags = IORESOURCE_MEM, }, - .irq = {IRQ_BASIC_GPIO, NO_IRQ}, + .irq = {IRQ_BASIC_GPIO}, }, { .dev = { .init_name = "gpio2", @@ -95,7 +95,7 @@ struct amba_device gpio_device[] = { .end = SPEAR6XX_ICM2_GPIO_BASE + SZ_4K - 1, .flags = IORESOURCE_MEM, }, - .irq = {IRQ_APPL_GPIO, NO_IRQ}, + .irq = {IRQ_APPL_GPIO}, } }; diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c index a2eb901..2db20da 100644 --- a/arch/arm/mach-tegra/common.c +++ b/arch/arm/mach-tegra/common.c @@ -27,7 +27,6 @@ #include <asm/hardware/gic.h> #include <mach/iomap.h> -#include <mach/system.h> #include "board.h" #include "clock.h" @@ -96,6 +95,8 @@ static void __init tegra_init_cache(u32 tag_latency, u32 data_latency) #ifdef CONFIG_ARCH_TEGRA_2x_SOC void __init tegra20_init_early(void) { + disable_hlt(); /* idle WFI usage needs to be confirmed */ + tegra_init_fuse(); tegra2_init_clocks(); tegra_clk_init_from_table(tegra20_clk_init_table); diff --git a/arch/arm/mach-tegra/include/mach/system.h b/arch/arm/mach-tegra/include/mach/system.h deleted file mode 100644 index a312988..0000000 --- a/arch/arm/mach-tegra/include/mach/system.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * arch/arm/mach-tegra/include/mach/system.h - * - * Copyright (C) 2010 Google, Inc. - * - * Author: - * Colin Cross <ccross@google.com> - * Erik Gilling <konkers@google.com> - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __MACH_TEGRA_SYSTEM_H -#define __MACH_TEGRA_SYSTEM_H - -static inline void arch_idle(void) -{ -} - -#endif diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index b4c6926..b986560 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c @@ -94,19 +94,9 @@ static struct amba_pl011_data uart0_plat_data = { #endif }; -static struct amba_device uart0_device = { - .dev = { - .coherent_dma_mask = ~0, - .init_name = "uart0", /* Slow device at 0x3000 offset */ - .platform_data = &uart0_plat_data, - }, - .res = { - .start = U300_UART0_BASE, - .end = U300_UART0_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = { IRQ_U300_UART0, NO_IRQ }, -}; +/* Slow device at 0x3000 offset */ +static AMBA_APB_DEVICE(uart0, "uart0", 0, U300_UART0_BASE, + { IRQ_U300_UART0 }, &uart0_plat_data); /* The U335 have an additional UART1 on the APP CPU */ #ifdef CONFIG_MACH_U300_BS335 @@ -118,71 +108,28 @@ static struct amba_pl011_data uart1_plat_data = { #endif }; -static struct amba_device uart1_device = { - .dev = { - .coherent_dma_mask = ~0, - .init_name = "uart1", /* Fast device at 0x7000 offset */ - .platform_data = &uart1_plat_data, - }, - .res = { - .start = U300_UART1_BASE, - .end = U300_UART1_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = { IRQ_U300_UART1, NO_IRQ }, -}; +/* Fast device at 0x7000 offset */ +static AMBA_APB_DEVICE(uart1, "uart1", 0, U300_UART1_BASE, + { IRQ_U300_UART1 }, &uart1_plat_data); #endif -static struct amba_device pl172_device = { - .dev = { - .init_name = "pl172", /* AHB device at 0x4000 offset */ - .platform_data = NULL, - }, - .res = { - .start = U300_EMIF_CFG_BASE, - .end = U300_EMIF_CFG_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, -}; +/* AHB device at 0x4000 offset */ +static AMBA_APB_DEVICE(pl172, "pl172", 0, U300_EMIF_CFG_BASE, { }, NULL); /* * Everything within this next ifdef deals with external devices connected to * the APP SPI bus. */ -static struct amba_device pl022_device = { - .dev = { - .coherent_dma_mask = ~0, - .init_name = "pl022", /* Fast device at 0x6000 offset */ - }, - .res = { - .start = U300_SPI_BASE, - .end = U300_SPI_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = {IRQ_U300_SPI, NO_IRQ }, - /* - * This device has a DMA channel but the Linux driver does not use - * it currently. - */ -}; +/* Fast device at 0x6000 offset */ +static AMBA_APB_DEVICE(pl022, "pl022", 0, U300_SPI_BASE, + { IRQ_U300_SPI }, NULL); -static struct amba_device mmcsd_device = { - .dev = { - .init_name = "mmci", /* Fast device at 0x1000 offset */ - .platform_data = NULL, /* Added later */ - }, - .res = { - .start = U300_MMCSD_BASE, - .end = U300_MMCSD_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = {IRQ_U300_MMCSD_MCIINTR0, IRQ_U300_MMCSD_MCIINTR1 }, - /* - * This device has a DMA channel but the Linux driver does not use - * it currently. - */ -}; +/* Fast device at 0x1000 offset */ +#define U300_MMCSD_IRQS { IRQ_U300_MMCSD_MCIINTR0, IRQ_U300_MMCSD_MCIINTR1 } + +static AMBA_APB_DEVICE(mmcsd, "mmci", 0, U300_MMCSD_BASE, + U300_MMCSD_IRQS, NULL); /* * The order of device declaration may be important, since some devices diff --git a/arch/arm/mach-u300/include/mach/system.h b/arch/arm/mach-u300/include/mach/system.h deleted file mode 100644 index 574d46e..0000000 --- a/arch/arm/mach-u300/include/mach/system.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * - * arch/arm/mach-u300/include/mach/system.h - * - * - * Copyright (C) 2007-2009 ST-Ericsson AB - * License terms: GNU General Public License (GPL) version 2 - * System shutdown and reset functions. - * Author: Linus Walleij <linus.walleij@stericsson.com> - */ -static inline void arch_idle(void) -{ - cpu_do_idle(); -} diff --git a/arch/arm/mach-ux500/devices-common.c b/arch/arm/mach-ux500/devices-common.c index c563e54..898a645 100644 --- a/arch/arm/mach-ux500/devices-common.c +++ b/arch/arm/mach-ux500/devices-common.c @@ -26,29 +26,22 @@ dbx500_add_amba_device(const char *name, resource_size_t base, struct amba_device *dev; int ret; - dev = kzalloc(sizeof *dev, GFP_KERNEL); + dev = amba_device_alloc(name, base, SZ_4K); if (!dev) return ERR_PTR(-ENOMEM); - dev->dev.init_name = name; - - dev->res.start = base; - dev->res.end = base + SZ_4K - 1; - dev->res.flags = IORESOURCE_MEM; - dev->dma_mask = DMA_BIT_MASK(32); dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); dev->irq[0] = irq; - dev->irq[1] = NO_IRQ; dev->periphid = periphid; dev->dev.platform_data = pdata; - ret = amba_device_register(dev, &iomem_resource); + ret = amba_device_add(dev, &iomem_resource); if (ret) { - kfree(dev); + amba_device_put(dev); return ERR_PTR(ret); } diff --git a/arch/arm/mach-ux500/include/mach/system.h b/arch/arm/mach-ux500/include/mach/system.h deleted file mode 100644 index 258e5c9..0000000 --- a/arch/arm/mach-ux500/include/mach/system.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2009 ST-Ericsson. - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static inline void arch_idle(void) -{ - /* - * This should do all the clock switching - * and wait for interrupt tricks - */ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 02b7b93..0968772 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -98,8 +98,11 @@ static const struct of_device_id sic_of_match[] __initconst = { void __init versatile_init_irq(void) { - vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0, 0); - irq_domain_generate_simple(vic_of_match, VERSATILE_VIC_BASE, IRQ_VIC_START); + struct device_node *np; + + np = of_find_matching_node_by_address(NULL, vic_of_match, + VERSATILE_VIC_BASE); + __vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0, 0, np); writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR); @@ -582,58 +585,58 @@ static struct pl022_ssp_controller ssp0_plat_data = { .num_chipselect = 1, }; -#define AACI_IRQ { IRQ_AACI, NO_IRQ } +#define AACI_IRQ { IRQ_AACI } #define MMCI0_IRQ { IRQ_MMCI0A,IRQ_SIC_MMCI0B } -#define KMI0_IRQ { IRQ_SIC_KMI0, NO_IRQ } -#define KMI1_IRQ { IRQ_SIC_KMI1, NO_IRQ } +#define KMI0_IRQ { IRQ_SIC_KMI0 } +#define KMI1_IRQ { IRQ_SIC_KMI1 } /* * These devices are connected directly to the multi-layer AHB switch */ -#define SMC_IRQ { NO_IRQ, NO_IRQ } -#define MPMC_IRQ { NO_IRQ, NO_IRQ } -#define CLCD_IRQ { IRQ_CLCDINT, NO_IRQ } -#define DMAC_IRQ { IRQ_DMAINT, NO_IRQ } +#define SMC_IRQ { } +#define MPMC_IRQ { } +#define CLCD_IRQ { IRQ_CLCDINT } +#define DMAC_IRQ { IRQ_DMAINT } /* * These devices are connected via the core APB bridge */ -#define SCTL_IRQ { NO_IRQ, NO_IRQ } -#define WATCHDOG_IRQ { IRQ_WDOGINT, NO_IRQ } -#define GPIO0_IRQ { IRQ_GPIOINT0, NO_IRQ } -#define GPIO1_IRQ { IRQ_GPIOINT1, NO_IRQ } -#define RTC_IRQ { IRQ_RTCINT, NO_IRQ } +#define SCTL_IRQ { } +#define WATCHDOG_IRQ { IRQ_WDOGINT } +#define GPIO0_IRQ { IRQ_GPIOINT0 } +#define GPIO1_IRQ { IRQ_GPIOINT1 } +#define RTC_IRQ { IRQ_RTCINT } /* * These devices are connected via the DMA APB bridge */ -#define SCI_IRQ { IRQ_SCIINT, NO_IRQ } -#define UART0_IRQ { IRQ_UARTINT0, NO_IRQ } -#define UART1_IRQ { IRQ_UARTINT1, NO_IRQ } -#define UART2_IRQ { IRQ_UARTINT2, NO_IRQ } -#define SSP_IRQ { IRQ_SSPINT, NO_IRQ } +#define SCI_IRQ { IRQ_SCIINT } +#define UART0_IRQ { IRQ_UARTINT0 } +#define UART1_IRQ { IRQ_UARTINT1 } +#define UART2_IRQ { IRQ_UARTINT2 } +#define SSP_IRQ { IRQ_SSPINT } /* FPGA Primecells */ -AMBA_DEVICE(aaci, "fpga:04", AACI, NULL); -AMBA_DEVICE(mmc0, "fpga:05", MMCI0, &mmc0_plat_data); -AMBA_DEVICE(kmi0, "fpga:06", KMI0, NULL); -AMBA_DEVICE(kmi1, "fpga:07", KMI1, NULL); +APB_DEVICE(aaci, "fpga:04", AACI, NULL); +APB_DEVICE(mmc0, "fpga:05", MMCI0, &mmc0_plat_data); +APB_DEVICE(kmi0, "fpga:06", KMI0, NULL); +APB_DEVICE(kmi1, "fpga:07", KMI1, NULL); /* DevChip Primecells */ -AMBA_DEVICE(smc, "dev:00", SMC, NULL); -AMBA_DEVICE(mpmc, "dev:10", MPMC, NULL); -AMBA_DEVICE(clcd, "dev:20", CLCD, &clcd_plat_data); -AMBA_DEVICE(dmac, "dev:30", DMAC, NULL); -AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL); -AMBA_DEVICE(wdog, "dev:e1", WATCHDOG, NULL); -AMBA_DEVICE(gpio0, "dev:e4", GPIO0, &gpio0_plat_data); -AMBA_DEVICE(gpio1, "dev:e5", GPIO1, &gpio1_plat_data); -AMBA_DEVICE(rtc, "dev:e8", RTC, NULL); -AMBA_DEVICE(sci0, "dev:f0", SCI, NULL); -AMBA_DEVICE(uart0, "dev:f1", UART0, NULL); -AMBA_DEVICE(uart1, "dev:f2", UART1, NULL); -AMBA_DEVICE(uart2, "dev:f3", UART2, NULL); -AMBA_DEVICE(ssp0, "dev:f4", SSP, &ssp0_plat_data); +AHB_DEVICE(smc, "dev:00", SMC, NULL); +AHB_DEVICE(mpmc, "dev:10", MPMC, NULL); +AHB_DEVICE(clcd, "dev:20", CLCD, &clcd_plat_data); +AHB_DEVICE(dmac, "dev:30", DMAC, NULL); +APB_DEVICE(sctl, "dev:e0", SCTL, NULL); +APB_DEVICE(wdog, "dev:e1", WATCHDOG, NULL); +APB_DEVICE(gpio0, "dev:e4", GPIO0, &gpio0_plat_data); +APB_DEVICE(gpio1, "dev:e5", GPIO1, &gpio1_plat_data); +APB_DEVICE(rtc, "dev:e8", RTC, NULL); +APB_DEVICE(sci0, "dev:f0", SCI, NULL); +APB_DEVICE(uart0, "dev:f1", UART0, NULL); +APB_DEVICE(uart1, "dev:f2", UART1, NULL); +APB_DEVICE(uart2, "dev:f3", UART2, NULL); +APB_DEVICE(ssp0, "dev:f4", SSP, &ssp0_plat_data); static struct amba_device *amba_devs[] __initdata = { &dmac_device, diff --git a/arch/arm/mach-versatile/core.h b/arch/arm/mach-versatile/core.h index 2ef2f55..683e607 100644 --- a/arch/arm/mach-versatile/core.h +++ b/arch/arm/mach-versatile/core.h @@ -36,20 +36,10 @@ extern unsigned int mmc_status(struct device *dev); extern struct of_dev_auxdata versatile_auxdata_lookup[]; #endif -#define AMBA_DEVICE(name,busid,base,plat) \ -static struct amba_device name##_device = { \ - .dev = { \ - .coherent_dma_mask = ~0, \ - .init_name = busid, \ - .platform_data = plat, \ - }, \ - .res = { \ - .start = VERSATILE_##base##_BASE, \ - .end = (VERSATILE_##base##_BASE) + SZ_4K - 1,\ - .flags = IORESOURCE_MEM, \ - }, \ - .dma_mask = ~0, \ - .irq = base##_IRQ, \ -} +#define APB_DEVICE(name, busid, base, plat) \ +static AMBA_APB_DEVICE(name, busid, 0, VERSATILE_##base##_BASE, base##_IRQ, plat) + +#define AHB_DEVICE(name, busid, base, plat) \ +static AMBA_AHB_DEVICE(name, busid, 0, VERSATILE_##base##_BASE, base##_IRQ, plat) #endif diff --git a/arch/arm/mach-versatile/include/mach/system.h b/arch/arm/mach-versatile/include/mach/system.h deleted file mode 100644 index f3fa347..0000000 --- a/arch/arm/mach-versatile/include/mach/system.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * arch/arm/mach-versatile/include/mach/system.h - * - * Copyright (C) 2003 ARM Limited - * Copyright (C) 2000 Deep Blue Solutions Ltd - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static inline void arch_idle(void) -{ - /* - * This should do all the clock switching - * and wait for interrupt tricks - */ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/mach-versatile/versatile_pb.c b/arch/arm/mach-versatile/versatile_pb.c index 9581c19..1973833 100644 --- a/arch/arm/mach-versatile/versatile_pb.c +++ b/arch/arm/mach-versatile/versatile_pb.c @@ -58,28 +58,28 @@ static struct pl061_platform_data gpio3_plat_data = { .irq_base = IRQ_GPIO3_START, }; -#define UART3_IRQ { IRQ_SIC_UART3, NO_IRQ } -#define SCI1_IRQ { IRQ_SIC_SCI3, NO_IRQ } +#define UART3_IRQ { IRQ_SIC_UART3 } +#define SCI1_IRQ { IRQ_SIC_SCI3 } #define MMCI1_IRQ { IRQ_MMCI1A, IRQ_SIC_MMCI1B } /* * These devices are connected via the core APB bridge */ -#define GPIO2_IRQ { IRQ_GPIOINT2, NO_IRQ } -#define GPIO3_IRQ { IRQ_GPIOINT3, NO_IRQ } +#define GPIO2_IRQ { IRQ_GPIOINT2 } +#define GPIO3_IRQ { IRQ_GPIOINT3 } /* * These devices are connected via the DMA APB bridge */ /* FPGA Primecells */ -AMBA_DEVICE(uart3, "fpga:09", UART3, NULL); -AMBA_DEVICE(sci1, "fpga:0a", SCI1, NULL); -AMBA_DEVICE(mmc1, "fpga:0b", MMCI1, &mmc1_plat_data); +APB_DEVICE(uart3, "fpga:09", UART3, NULL); +APB_DEVICE(sci1, "fpga:0a", SCI1, NULL); +APB_DEVICE(mmc1, "fpga:0b", MMCI1, &mmc1_plat_data); /* DevChip Primecells */ -AMBA_DEVICE(gpio2, "dev:e6", GPIO2, &gpio2_plat_data); -AMBA_DEVICE(gpio3, "dev:e7", GPIO3, &gpio3_plat_data); +APB_DEVICE(gpio2, "dev:e6", GPIO2, &gpio2_plat_data); +APB_DEVICE(gpio3, "dev:e7", GPIO3, &gpio3_plat_data); static struct amba_device *amba_devs[] __initdata = { &uart3_device, diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig index 9b3d0fb..cf8730d 100644 --- a/arch/arm/mach-vexpress/Kconfig +++ b/arch/arm/mach-vexpress/Kconfig @@ -1,14 +1,55 @@ menu "Versatile Express platform type" depends on ARCH_VEXPRESS +config ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA + bool + select ARM_ERRATA_720789 + select ARM_ERRATA_751472 + select PL310_ERRATA_753970 if CACHE_PL310 + help + Provides common dependencies for Versatile Express platforms + based on Cortex-A5 and Cortex-A9 processors. In order to + build a working kernel, you must also enable relevant core + tile support or Flattened Device Tree based support options. + config ARCH_VEXPRESS_CA9X4 bool "Versatile Express Cortex-A9x4 tile" + select ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA + select ARM_GIC select CPU_V7 + select HAVE_SMP + select MIGHT_HAVE_CACHE_L2X0 + +config ARCH_VEXPRESS_DT + bool "Device Tree support for Versatile Express platforms" + select ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA select ARM_GIC - select ARM_ERRATA_720789 - select ARM_ERRATA_751472 - select ARM_ERRATA_753970 + select ARM_PATCH_PHYS_VIRT + select AUTO_ZRELADDR + select CPU_V7 select HAVE_SMP select MIGHT_HAVE_CACHE_L2X0 + select USE_OF + help + New Versatile Express platforms require Flattened Device Tree to + be passed to the kernel. + + This option enables support for systems using Cortex processor based + ARM core and logic (FPGA) tiles on the Versatile Express motherboard, + for example: + + - CoreTile Express A5x2 (V2P-CA5s) + - CoreTile Express A9x4 (V2P-CA9) + - CoreTile Express A15x2 (V2P-CA15) + - LogicTile Express 13MG (V2F-2XV6) with A5, A7, A9 or A15 SMMs + (Soft Macrocell Models) + - Versatile Express RTSMs (Models) + + You must boot using a Flattened Device Tree in order to use these + platforms. The traditional (ATAGs) boot method is not usable on + these boards with this option. + + If your bootloader supports Flattened Device Tree based booting, + say Y here. endmenu diff --git a/arch/arm/mach-vexpress/Makefile.boot b/arch/arm/mach-vexpress/Makefile.boot index 8630b3d..909f85e 100644 --- a/arch/arm/mach-vexpress/Makefile.boot +++ b/arch/arm/mach-vexpress/Makefile.boot @@ -1,3 +1,9 @@ +# Those numbers are used only by the non-DT V2P-CA9 platform +# The DT-enabled ones require CONFIG_AUTO_ZRELADDR=y zreladdr-y += 0x60008000 params_phys-y := 0x60000100 initrd_phys-y := 0x60800000 + +dtb-$(CONFIG_ARCH_VEXPRESS_DT) += vexpress-v2p-ca5s.dtb \ + vexpress-v2p-ca9.dtb \ + vexpress-v2p-ca15-tc1.dtb diff --git a/arch/arm/mach-vexpress/core.h b/arch/arm/mach-vexpress/core.h index f439715..a3a4980 100644 --- a/arch/arm/mach-vexpress/core.h +++ b/arch/arm/mach-vexpress/core.h @@ -1,19 +1,7 @@ -#define __MMIO_P2V(x) (((x) & 0xfffff) | (((x) & 0x0f000000) >> 4) | 0xf8000000) -#define MMIO_P2V(x) ((void __iomem *)__MMIO_P2V(x)) +/* 2MB large area for motherboard's peripherals static mapping */ +#define V2M_PERIPH 0xf8000000 -#define AMBA_DEVICE(name,busid,base,plat) \ -struct amba_device name##_device = { \ - .dev = { \ - .coherent_dma_mask = ~0UL, \ - .init_name = busid, \ - .platform_data = plat, \ - }, \ - .res = { \ - .start = base, \ - .end = base + SZ_4K - 1, \ - .flags = IORESOURCE_MEM, \ - }, \ - .dma_mask = ~0UL, \ - .irq = IRQ_##base, \ - /* .dma = DMA_##base,*/ \ -} +/* Tile's peripherals static mappings should start here */ +#define V2T_PERIPH 0xf8200000 + +void vexpress_dt_smp_map_io(void); diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c index b1e87c1..73791f0 100644 --- a/arch/arm/mach-vexpress/ct-ca9x4.c +++ b/arch/arm/mach-vexpress/ct-ca9x4.c @@ -30,57 +30,29 @@ #include <plat/clcd.h> -#define V2M_PA_CS7 0x10000000 - static struct map_desc ct_ca9x4_io_desc[] __initdata = { { - .virtual = __MMIO_P2V(CT_CA9X4_MPIC), - .pfn = __phys_to_pfn(CT_CA9X4_MPIC), - .length = SZ_16K, - .type = MT_DEVICE, - }, { - .virtual = __MMIO_P2V(CT_CA9X4_SP804_TIMER), - .pfn = __phys_to_pfn(CT_CA9X4_SP804_TIMER), - .length = SZ_4K, - .type = MT_DEVICE, - }, { - .virtual = __MMIO_P2V(CT_CA9X4_L2CC), - .pfn = __phys_to_pfn(CT_CA9X4_L2CC), - .length = SZ_4K, - .type = MT_DEVICE, + .virtual = V2T_PERIPH, + .pfn = __phys_to_pfn(CT_CA9X4_MPIC), + .length = SZ_8K, + .type = MT_DEVICE, }, }; static void __init ct_ca9x4_map_io(void) { + iotable_init(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc)); #ifdef CONFIG_LOCAL_TIMERS - twd_base = MMIO_P2V(A9_MPCORE_TWD); + twd_base = ioremap(A9_MPCORE_TWD, SZ_32); #endif - iotable_init(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc)); } static void __init ct_ca9x4_init_irq(void) { - gic_init(0, 29, MMIO_P2V(A9_MPCORE_GIC_DIST), - MMIO_P2V(A9_MPCORE_GIC_CPU)); -} - -#if 0 -static void __init ct_ca9x4_timer_init(void) -{ - writel(0, MMIO_P2V(CT_CA9X4_TIMER0) + TIMER_CTRL); - writel(0, MMIO_P2V(CT_CA9X4_TIMER1) + TIMER_CTRL); - - sp804_clocksource_init(MMIO_P2V(CT_CA9X4_TIMER1), "ct-timer1"); - sp804_clockevents_init(MMIO_P2V(CT_CA9X4_TIMER0), IRQ_CT_CA9X4_TIMER0, - "ct-timer0"); + gic_init(0, 29, ioremap(A9_MPCORE_GIC_DIST, SZ_4K), + ioremap(A9_MPCORE_GIC_CPU, SZ_256)); } -static struct sys_timer ct_ca9x4_timer = { - .init = ct_ca9x4_timer_init, -}; -#endif - static void ct_ca9x4_clcd_enable(struct clcd_fb *fb) { v2m_cfg_write(SYS_CFG_MUXFPGA | SYS_CFG_SITE_DB1, 0); @@ -109,10 +81,10 @@ static struct clcd_board ct_ca9x4_clcd_data = { .remove = versatile_clcd_remove_dma, }; -static AMBA_DEVICE(clcd, "ct:clcd", CT_CA9X4_CLCDC, &ct_ca9x4_clcd_data); -static AMBA_DEVICE(dmc, "ct:dmc", CT_CA9X4_DMC, NULL); -static AMBA_DEVICE(smc, "ct:smc", CT_CA9X4_SMC, NULL); -static AMBA_DEVICE(gpio, "ct:gpio", CT_CA9X4_GPIO, NULL); +static AMBA_AHB_DEVICE(clcd, "ct:clcd", 0, CT_CA9X4_CLCDC, IRQ_CT_CA9X4_CLCDC, &ct_ca9x4_clcd_data); +static AMBA_APB_DEVICE(dmc, "ct:dmc", 0, CT_CA9X4_DMC, IRQ_CT_CA9X4_DMC, NULL); +static AMBA_APB_DEVICE(smc, "ct:smc", 0, CT_CA9X4_SMC, IRQ_CT_CA9X4_SMC, NULL); +static AMBA_APB_DEVICE(gpio, "ct:gpio", 0, CT_CA9X4_GPIO, IRQ_CT_CA9X4_GPIO, NULL); static struct amba_device *ct_ca9x4_amba_devs[] __initdata = { &clcd_device, @@ -201,7 +173,7 @@ static void __init ct_ca9x4_init(void) int i; #ifdef CONFIG_CACHE_L2X0 - void __iomem *l2x0_base = MMIO_P2V(CT_CA9X4_L2CC); + void __iomem *l2x0_base = ioremap(CT_CA9X4_L2CC, SZ_4K); /* set RAM latencies to 1 cycle for this core tile. */ writel(0, l2x0_base + L2X0_TAG_LATENCY_CTRL); @@ -217,9 +189,17 @@ static void __init ct_ca9x4_init(void) } #ifdef CONFIG_SMP +static void *ct_ca9x4_scu_base __initdata; + static void __init ct_ca9x4_init_cpu_map(void) { - int i, ncores = scu_get_core_count(MMIO_P2V(A9_MPCORE_SCU)); + int i, ncores; + + ct_ca9x4_scu_base = ioremap(A9_MPCORE_SCU, SZ_128); + if (WARN_ON(!ct_ca9x4_scu_base)) + return; + + ncores = scu_get_core_count(ct_ca9x4_scu_base); if (ncores > nr_cpu_ids) { pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", @@ -235,7 +215,7 @@ static void __init ct_ca9x4_init_cpu_map(void) static void __init ct_ca9x4_smp_enable(unsigned int max_cpus) { - scu_enable(MMIO_P2V(A9_MPCORE_SCU)); + scu_enable(ct_ca9x4_scu_base); } #endif diff --git a/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h b/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h index a34d3d4..84acf84 100644 --- a/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h +++ b/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h @@ -22,9 +22,6 @@ #define CT_CA9X4_SYSWDT (0x1e007000) #define CT_CA9X4_L2CC (0x1e00a000) -#define CT_CA9X4_TIMER0 (CT_CA9X4_SP804_TIMER + 0x000) -#define CT_CA9X4_TIMER1 (CT_CA9X4_SP804_TIMER + 0x020) - #define A9_MPCORE_SCU (CT_CA9X4_MPIC + 0x0000) #define A9_MPCORE_GIC_CPU (CT_CA9X4_MPIC + 0x0100) #define A9_MPCORE_GIT (CT_CA9X4_MPIC + 0x0200) @@ -35,7 +32,7 @@ * Interrupts. Those in {} are for AMBA devices */ #define IRQ_CT_CA9X4_CLCDC { 76 } -#define IRQ_CT_CA9X4_DMC { -1 } +#define IRQ_CT_CA9X4_DMC { 0 } #define IRQ_CT_CA9X4_SMC { 77, 78 } #define IRQ_CT_CA9X4_TIMER0 80 #define IRQ_CT_CA9X4_TIMER1 81 diff --git a/arch/arm/mach-vexpress/include/mach/debug-macro.S b/arch/arm/mach-vexpress/include/mach/debug-macro.S index fd9e6c7..fa82247 100644 --- a/arch/arm/mach-vexpress/include/mach/debug-macro.S +++ b/arch/arm/mach-vexpress/include/mach/debug-macro.S @@ -10,12 +10,34 @@ * published by the Free Software Foundation. */ -#define DEBUG_LL_UART_OFFSET 0x00009000 +#define DEBUG_LL_PHYS_BASE 0x10000000 +#define DEBUG_LL_UART_OFFSET 0x00009000 + +#define DEBUG_LL_PHYS_BASE_RS1 0x1c000000 +#define DEBUG_LL_UART_OFFSET_RS1 0x00090000 + +#define DEBUG_LL_VIRT_BASE 0xf8000000 .macro addruart,rp,rv,tmp - mov \rp, #DEBUG_LL_UART_OFFSET - orr \rv, \rp, #0xf8000000 @ virtual base - orr \rp, \rp, #0x10000000 @ physical base + + @ Make an educated guess regarding the memory map: + @ - the original A9 core tile, which has MPCore peripherals + @ located at 0x1e000000, should use UART at 0x10009000 + @ - all other (RS1 complaint) tiles use UART mapped + @ at 0x1c090000 + mrc p15, 4, \tmp, c15, c0, 0 + cmp \tmp, #0x1e000000 + + @ Original memory map + moveq \rp, #DEBUG_LL_UART_OFFSET + orreq \rv, \rp, #DEBUG_LL_VIRT_BASE + orreq \rp, \rp, #DEBUG_LL_PHYS_BASE + + @ RS1 memory map + movne \rp, #DEBUG_LL_UART_OFFSET_RS1 + orrne \rv, \rp, #DEBUG_LL_VIRT_BASE + orrne \rp, \rp, #DEBUG_LL_PHYS_BASE_RS1 + .endm #include <asm/hardware/debug-pl01x.S> diff --git a/arch/arm/mach-vexpress/include/mach/irqs.h b/arch/arm/mach-vexpress/include/mach/irqs.h index 7054cbf..4b10ee7 100644 --- a/arch/arm/mach-vexpress/include/mach/irqs.h +++ b/arch/arm/mach-vexpress/include/mach/irqs.h @@ -1,4 +1,4 @@ #define IRQ_LOCALTIMER 29 #define IRQ_LOCALWDOG 30 -#define NR_IRQS 128 +#define NR_IRQS 256 diff --git a/arch/arm/mach-vexpress/include/mach/motherboard.h b/arch/arm/mach-vexpress/include/mach/motherboard.h index 0a3a375..31a9289 100644 --- a/arch/arm/mach-vexpress/include/mach/motherboard.h +++ b/arch/arm/mach-vexpress/include/mach/motherboard.h @@ -39,33 +39,30 @@ #define V2M_CF (V2M_PA_CS7 + 0x0001a000) #define V2M_CLCD (V2M_PA_CS7 + 0x0001f000) -#define V2M_SYS_ID (V2M_SYSREGS + 0x000) -#define V2M_SYS_SW (V2M_SYSREGS + 0x004) -#define V2M_SYS_LED (V2M_SYSREGS + 0x008) -#define V2M_SYS_100HZ (V2M_SYSREGS + 0x024) -#define V2M_SYS_FLAGS (V2M_SYSREGS + 0x030) -#define V2M_SYS_FLAGSSET (V2M_SYSREGS + 0x030) -#define V2M_SYS_FLAGSCLR (V2M_SYSREGS + 0x034) -#define V2M_SYS_NVFLAGS (V2M_SYSREGS + 0x038) -#define V2M_SYS_NVFLAGSSET (V2M_SYSREGS + 0x038) -#define V2M_SYS_NVFLAGSCLR (V2M_SYSREGS + 0x03c) -#define V2M_SYS_MCI (V2M_SYSREGS + 0x048) -#define V2M_SYS_FLASH (V2M_SYSREGS + 0x03c) -#define V2M_SYS_CFGSW (V2M_SYSREGS + 0x058) -#define V2M_SYS_24MHZ (V2M_SYSREGS + 0x05c) -#define V2M_SYS_MISC (V2M_SYSREGS + 0x060) -#define V2M_SYS_DMA (V2M_SYSREGS + 0x064) -#define V2M_SYS_PROCID0 (V2M_SYSREGS + 0x084) -#define V2M_SYS_PROCID1 (V2M_SYSREGS + 0x088) -#define V2M_SYS_CFGDATA (V2M_SYSREGS + 0x0a0) -#define V2M_SYS_CFGCTRL (V2M_SYSREGS + 0x0a4) -#define V2M_SYS_CFGSTAT (V2M_SYSREGS + 0x0a8) - -#define V2M_TIMER0 (V2M_TIMER01 + 0x000) -#define V2M_TIMER1 (V2M_TIMER01 + 0x020) - -#define V2M_TIMER2 (V2M_TIMER23 + 0x000) -#define V2M_TIMER3 (V2M_TIMER23 + 0x020) +/* + * Offsets from SYSREGS base + */ +#define V2M_SYS_ID 0x000 +#define V2M_SYS_SW 0x004 +#define V2M_SYS_LED 0x008 +#define V2M_SYS_100HZ 0x024 +#define V2M_SYS_FLAGS 0x030 +#define V2M_SYS_FLAGSSET 0x030 +#define V2M_SYS_FLAGSCLR 0x034 +#define V2M_SYS_NVFLAGS 0x038 +#define V2M_SYS_NVFLAGSSET 0x038 +#define V2M_SYS_NVFLAGSCLR 0x03c +#define V2M_SYS_MCI 0x048 +#define V2M_SYS_FLASH 0x03c +#define V2M_SYS_CFGSW 0x058 +#define V2M_SYS_24MHZ 0x05c +#define V2M_SYS_MISC 0x060 +#define V2M_SYS_DMA 0x064 +#define V2M_SYS_PROCID0 0x084 +#define V2M_SYS_PROCID1 0x088 +#define V2M_SYS_CFGDATA 0x0a0 +#define V2M_SYS_CFGCTRL 0x0a4 +#define V2M_SYS_CFGSTAT 0x0a8 /* @@ -117,6 +114,13 @@ int v2m_cfg_write(u32 devfn, u32 data); int v2m_cfg_read(u32 devfn, u32 *data); +void v2m_flags_set(u32 data); + +/* + * Miscellaneous + */ +#define SYS_MISC_MASTERSITE (1 << 14) +#define SYS_PROCIDx_HBI_MASK 0xfff /* * Core tile IDs diff --git a/arch/arm/mach-vexpress/include/mach/system.h b/arch/arm/mach-vexpress/include/mach/system.h deleted file mode 100644 index f653a8e..0000000 --- a/arch/arm/mach-vexpress/include/mach/system.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * arch/arm/mach-vexpress/include/mach/system.h - * - * Copyright (C) 2003 ARM Limited - * Copyright (C) 2000 Deep Blue Solutions Ltd - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static inline void arch_idle(void) -{ - /* - * This should do all the clock switching - * and wait for interrupt tricks - */ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/mach-vexpress/include/mach/uncompress.h b/arch/arm/mach-vexpress/include/mach/uncompress.h index 7972c57..7dab559 100644 --- a/arch/arm/mach-vexpress/include/mach/uncompress.h +++ b/arch/arm/mach-vexpress/include/mach/uncompress.h @@ -22,7 +22,27 @@ #define AMBA_UART_CR(base) (*(volatile unsigned char *)((base) + 0x30)) #define AMBA_UART_FR(base) (*(volatile unsigned char *)((base) + 0x18)) -#define get_uart_base() (0x10000000 + 0x00009000) +#define UART_BASE 0x10009000 +#define UART_BASE_RS1 0x1c090000 + +static unsigned long get_uart_base(void) +{ + unsigned long mpcore_periph; + + /* + * Make an educated guess regarding the memory map: + * - the original A9 core tile, which has MPCore peripherals + * located at 0x1e000000, should use UART at 0x10009000 + * - all other (RS1 complaint) tiles use UART mapped + * at 0x1c090000 + */ + asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (mpcore_periph)); + + if (mpcore_periph == 0x1e000000) + return UART_BASE; + else + return UART_BASE_RS1; +} /* * This does not append a newline diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c index 124ffb1..14ba112 100644 --- a/arch/arm/mach-vexpress/platsmp.c +++ b/arch/arm/mach-vexpress/platsmp.c @@ -12,21 +12,168 @@ #include <linux/errno.h> #include <linux/smp.h> #include <linux/io.h> +#include <linux/of_fdt.h> + +#include <asm/smp_scu.h> +#include <asm/hardware/gic.h> +#include <asm/mach/map.h> #include <mach/motherboard.h> -#define V2M_PA_CS7 0x10000000 #include "core.h" extern void versatile_secondary_startup(void); +#if defined(CONFIG_OF) + +static enum { + GENERIC_SCU, + CORTEX_A9_SCU, +} vexpress_dt_scu __initdata = GENERIC_SCU; + +static struct map_desc vexpress_dt_cortex_a9_scu_map __initdata = { + .virtual = V2T_PERIPH, + /* .pfn set in vexpress_dt_init_cortex_a9_scu() */ + .length = SZ_128, + .type = MT_DEVICE, +}; + +static void *vexpress_dt_cortex_a9_scu_base __initdata; + +const static char *vexpress_dt_cortex_a9_match[] __initconst = { + "arm,cortex-a5-scu", + "arm,cortex-a9-scu", + NULL +}; + +static int __init vexpress_dt_find_scu(unsigned long node, + const char *uname, int depth, void *data) +{ + if (of_flat_dt_match(node, vexpress_dt_cortex_a9_match)) { + phys_addr_t phys_addr; + __be32 *reg = of_get_flat_dt_prop(node, "reg", NULL); + + if (WARN_ON(!reg)) + return -EINVAL; + + phys_addr = be32_to_cpup(reg); + vexpress_dt_scu = CORTEX_A9_SCU; + + vexpress_dt_cortex_a9_scu_map.pfn = __phys_to_pfn(phys_addr); + iotable_init(&vexpress_dt_cortex_a9_scu_map, 1); + vexpress_dt_cortex_a9_scu_base = ioremap(phys_addr, SZ_256); + if (WARN_ON(!vexpress_dt_cortex_a9_scu_base)) + return -EFAULT; + } + + return 0; +} + +void __init vexpress_dt_smp_map_io(void) +{ + if (initial_boot_params) + WARN_ON(of_scan_flat_dt(vexpress_dt_find_scu, NULL)); +} + +static int __init vexpress_dt_cpus_num(unsigned long node, const char *uname, + int depth, void *data) +{ + static int prev_depth = -1; + static int nr_cpus = -1; + + if (prev_depth > depth && nr_cpus > 0) + return nr_cpus; + + if (nr_cpus < 0 && strcmp(uname, "cpus") == 0) + nr_cpus = 0; + + if (nr_cpus >= 0) { + const char *device_type = of_get_flat_dt_prop(node, + "device_type", NULL); + + if (device_type && strcmp(device_type, "cpu") == 0) + nr_cpus++; + } + + prev_depth = depth; + + return 0; +} + +static void __init vexpress_dt_smp_init_cpus(void) +{ + int ncores = 0, i; + + switch (vexpress_dt_scu) { + case GENERIC_SCU: + ncores = of_scan_flat_dt(vexpress_dt_cpus_num, NULL); + break; + case CORTEX_A9_SCU: + ncores = scu_get_core_count(vexpress_dt_cortex_a9_scu_base); + break; + default: + WARN_ON(1); + break; + } + + if (ncores < 2) + return; + + if (ncores > nr_cpu_ids) { + pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", + ncores, nr_cpu_ids); + ncores = nr_cpu_ids; + } + + for (i = 0; i < ncores; ++i) + set_cpu_possible(i, true); + + set_smp_cross_call(gic_raise_softirq); +} + +static void __init vexpress_dt_smp_prepare_cpus(unsigned int max_cpus) +{ + int i; + + switch (vexpress_dt_scu) { + case GENERIC_SCU: + for (i = 0; i < max_cpus; i++) + set_cpu_present(i, true); + break; + case CORTEX_A9_SCU: + scu_enable(vexpress_dt_cortex_a9_scu_base); + break; + default: + WARN_ON(1); + break; + } +} + +#else + +static void __init vexpress_dt_smp_init_cpus(void) +{ + WARN_ON(1); +} + +void __init vexpress_dt_smp_prepare_cpus(unsigned int max_cpus) +{ + WARN_ON(1); +} + +#endif + /* * Initialise the CPU possible map early - this describes the CPUs * which may be present or become present in the system. */ void __init smp_init_cpus(void) { - ct_desc->init_cpu_map(); + if (ct_desc) + ct_desc->init_cpu_map(); + else + vexpress_dt_smp_init_cpus(); + } void __init platform_smp_prepare_cpus(unsigned int max_cpus) @@ -35,7 +182,10 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus) * Initialise the present map, which describes the set of CPUs * actually populated at the present time. */ - ct_desc->smp_enable(max_cpus); + if (ct_desc) + ct_desc->smp_enable(max_cpus); + else + vexpress_dt_smp_prepare_cpus(max_cpus); /* * Write the address of secondary startup into the @@ -43,7 +193,5 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus) * until it receives a soft interrupt, and then the * secondary CPU branches to this address. */ - writel(~0, MMIO_P2V(V2M_SYS_FLAGSCLR)); - writel(virt_to_phys(versatile_secondary_startup), - MMIO_P2V(V2M_SYS_FLAGSSET)); + v2m_flags_set(virt_to_phys(versatile_secondary_startup)); } diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c index b4a28ca..47cdcca 100644 --- a/arch/arm/mach-vexpress/v2m.c +++ b/arch/arm/mach-vexpress/v2m.c @@ -6,6 +6,10 @@ #include <linux/amba/mmci.h> #include <linux/io.h> #include <linux/init.h> +#include <linux/of_address.h> +#include <linux/of_fdt.h> +#include <linux/of_irq.h> +#include <linux/of_platform.h> #include <linux/platform_device.h> #include <linux/ata_platform.h> #include <linux/smsc911x.h> @@ -21,6 +25,8 @@ #include <asm/mach/map.h> #include <asm/mach/time.h> #include <asm/hardware/arm_timer.h> +#include <asm/hardware/cache-l2x0.h> +#include <asm/hardware/gic.h> #include <asm/hardware/timer-sp.h> #include <asm/hardware/sp810.h> #include <asm/hardware/gic.h> @@ -40,29 +46,45 @@ static struct map_desc v2m_io_desc[] __initdata = { { - .virtual = __MMIO_P2V(V2M_PA_CS7), + .virtual = V2M_PERIPH, .pfn = __phys_to_pfn(V2M_PA_CS7), .length = SZ_128K, .type = MT_DEVICE, }, }; -static void __init v2m_timer_init(void) +static void __iomem *v2m_sysreg_base; + +static void __init v2m_sysctl_init(void __iomem *base) { u32 scctrl; + if (WARN_ON(!base)) + return; + /* Select 1MHz TIMCLK as the reference clock for SP804 timers */ - scctrl = readl(MMIO_P2V(V2M_SYSCTL + SCCTRL)); + scctrl = readl(base + SCCTRL); scctrl |= SCCTRL_TIMEREN0SEL_TIMCLK; scctrl |= SCCTRL_TIMEREN1SEL_TIMCLK; - writel(scctrl, MMIO_P2V(V2M_SYSCTL + SCCTRL)); + writel(scctrl, base + SCCTRL); +} + +static void __init v2m_sp804_init(void __iomem *base, unsigned int irq) +{ + if (WARN_ON(!base || irq == NO_IRQ)) + return; + + writel(0, base + TIMER_1_BASE + TIMER_CTRL); + writel(0, base + TIMER_2_BASE + TIMER_CTRL); - writel(0, MMIO_P2V(V2M_TIMER0) + TIMER_CTRL); - writel(0, MMIO_P2V(V2M_TIMER1) + TIMER_CTRL); + sp804_clocksource_init(base + TIMER_2_BASE, "v2m-timer1"); + sp804_clockevents_init(base + TIMER_1_BASE, irq, "v2m-timer0"); +} - sp804_clocksource_init(MMIO_P2V(V2M_TIMER1), "v2m-timer1"); - sp804_clockevents_init(MMIO_P2V(V2M_TIMER0), IRQ_V2M_TIMER0, - "v2m-timer0"); +static void __init v2m_timer_init(void) +{ + v2m_sysctl_init(ioremap(V2M_SYSCTL, SZ_4K)); + v2m_sp804_init(ioremap(V2M_TIMER01, SZ_4K), IRQ_V2M_TIMER0); } static struct sys_timer v2m_timer = { @@ -82,14 +104,14 @@ int v2m_cfg_write(u32 devfn, u32 data) devfn |= SYS_CFG_START | SYS_CFG_WRITE; spin_lock(&v2m_cfg_lock); - val = readl(MMIO_P2V(V2M_SYS_CFGSTAT)); - writel(val & ~SYS_CFG_COMPLETE, MMIO_P2V(V2M_SYS_CFGSTAT)); + val = readl(v2m_sysreg_base + V2M_SYS_CFGSTAT); + writel(val & ~SYS_CFG_COMPLETE, v2m_sysreg_base + V2M_SYS_CFGSTAT); - writel(data, MMIO_P2V(V2M_SYS_CFGDATA)); - writel(devfn, MMIO_P2V(V2M_SYS_CFGCTRL)); + writel(data, v2m_sysreg_base + V2M_SYS_CFGDATA); + writel(devfn, v2m_sysreg_base + V2M_SYS_CFGCTRL); do { - val = readl(MMIO_P2V(V2M_SYS_CFGSTAT)); + val = readl(v2m_sysreg_base + V2M_SYS_CFGSTAT); } while (val == 0); spin_unlock(&v2m_cfg_lock); @@ -103,22 +125,28 @@ int v2m_cfg_read(u32 devfn, u32 *data) devfn |= SYS_CFG_START; spin_lock(&v2m_cfg_lock); - writel(0, MMIO_P2V(V2M_SYS_CFGSTAT)); - writel(devfn, MMIO_P2V(V2M_SYS_CFGCTRL)); + writel(0, v2m_sysreg_base + V2M_SYS_CFGSTAT); + writel(devfn, v2m_sysreg_base + V2M_SYS_CFGCTRL); mb(); do { cpu_relax(); - val = readl(MMIO_P2V(V2M_SYS_CFGSTAT)); + val = readl(v2m_sysreg_base + V2M_SYS_CFGSTAT); } while (val == 0); - *data = readl(MMIO_P2V(V2M_SYS_CFGDATA)); + *data = readl(v2m_sysreg_base + V2M_SYS_CFGDATA); spin_unlock(&v2m_cfg_lock); return !!(val & SYS_CFG_ERR); } +void __init v2m_flags_set(u32 data) +{ + writel(~0, v2m_sysreg_base + V2M_SYS_FLAGSCLR); + writel(data, v2m_sysreg_base + V2M_SYS_FLAGSSET); +} + static struct resource v2m_pcie_i2c_resource = { .start = V2M_SERIAL_BUS_PCI, @@ -204,7 +232,7 @@ static struct platform_device v2m_usb_device = { static void v2m_flash_set_vpp(struct platform_device *pdev, int on) { - writel(on != 0, MMIO_P2V(V2M_SYS_FLASH)); + writel(on != 0, v2m_sysreg_base + V2M_SYS_FLASH); } static struct physmap_flash_data v2m_flash_data = { @@ -258,7 +286,7 @@ static struct platform_device v2m_cf_device = { static unsigned int v2m_mmci_status(struct device *dev) { - return readl(MMIO_P2V(V2M_SYS_MCI)) & (1 << 0); + return readl(v2m_sysreg_base + V2M_SYS_MCI) & (1 << 0); } static struct mmci_platform_data v2m_mmci_data = { @@ -266,16 +294,16 @@ static struct mmci_platform_data v2m_mmci_data = { .status = v2m_mmci_status, }; -static AMBA_DEVICE(aaci, "mb:aaci", V2M_AACI, NULL); -static AMBA_DEVICE(mmci, "mb:mmci", V2M_MMCI, &v2m_mmci_data); -static AMBA_DEVICE(kmi0, "mb:kmi0", V2M_KMI0, NULL); -static AMBA_DEVICE(kmi1, "mb:kmi1", V2M_KMI1, NULL); -static AMBA_DEVICE(uart0, "mb:uart0", V2M_UART0, NULL); -static AMBA_DEVICE(uart1, "mb:uart1", V2M_UART1, NULL); -static AMBA_DEVICE(uart2, "mb:uart2", V2M_UART2, NULL); -static AMBA_DEVICE(uart3, "mb:uart3", V2M_UART3, NULL); -static AMBA_DEVICE(wdt, "mb:wdt", V2M_WDT, NULL); -static AMBA_DEVICE(rtc, "mb:rtc", V2M_RTC, NULL); +static AMBA_APB_DEVICE(aaci, "mb:aaci", 0, V2M_AACI, IRQ_V2M_AACI, NULL); +static AMBA_APB_DEVICE(mmci, "mb:mmci", 0, V2M_MMCI, IRQ_V2M_MMCI, &v2m_mmci_data); +static AMBA_APB_DEVICE(kmi0, "mb:kmi0", 0, V2M_KMI0, IRQ_V2M_KMI0, NULL); +static AMBA_APB_DEVICE(kmi1, "mb:kmi1", 0, V2M_KMI1, IRQ_V2M_KMI1, NULL); +static AMBA_APB_DEVICE(uart0, "mb:uart0", 0, V2M_UART0, IRQ_V2M_UART0, NULL); +static AMBA_APB_DEVICE(uart1, "mb:uart1", 0, V2M_UART1, IRQ_V2M_UART1, NULL); +static AMBA_APB_DEVICE(uart2, "mb:uart2", 0, V2M_UART2, IRQ_V2M_UART2, NULL); +static AMBA_APB_DEVICE(uart3, "mb:uart3", 0, V2M_UART3, IRQ_V2M_UART3, NULL); +static AMBA_APB_DEVICE(wdt, "mb:wdt", 0, V2M_WDT, IRQ_V2M_WDT, NULL); +static AMBA_APB_DEVICE(rtc, "mb:rtc", 0, V2M_RTC, IRQ_V2M_RTC, NULL); static struct amba_device *v2m_amba_devs[] __initdata = { &aaci_device, @@ -371,7 +399,7 @@ static void __init v2m_init_early(void) { ct_desc->init_early(); clkdev_add_table(v2m_lookups, ARRAY_SIZE(v2m_lookups)); - versatile_sched_clock_init(MMIO_P2V(V2M_SYS_24MHZ), 24000000); + versatile_sched_clock_init(v2m_sysreg_base + V2M_SYS_24MHZ, 24000000); } static void v2m_power_off(void) @@ -400,20 +428,23 @@ static void __init v2m_populate_ct_desc(void) u32 current_tile_id; ct_desc = NULL; - current_tile_id = readl(MMIO_P2V(V2M_SYS_PROCID0)) & V2M_CT_ID_MASK; + current_tile_id = readl(v2m_sysreg_base + V2M_SYS_PROCID0) + & V2M_CT_ID_MASK; for (i = 0; i < ARRAY_SIZE(ct_descs) && !ct_desc; ++i) if (ct_descs[i]->id == current_tile_id) ct_desc = ct_descs[i]; if (!ct_desc) - panic("vexpress: failed to populate core tile description " - "for tile ID 0x%8x\n", current_tile_id); + panic("vexpress: this kernel does not support core tile ID 0x%08x when booting via ATAGs.\n" + "You may need a device tree blob or a different kernel to boot on this board.\n", + current_tile_id); } static void __init v2m_map_io(void) { iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc)); + v2m_sysreg_base = ioremap(V2M_SYSREGS, SZ_4K); v2m_populate_ct_desc(); ct_desc->map_io(); } @@ -452,3 +483,205 @@ MACHINE_START(VEXPRESS, "ARM-Versatile Express") .init_machine = v2m_init, .restart = v2m_restart, MACHINE_END + +#if defined(CONFIG_ARCH_VEXPRESS_DT) + +static struct map_desc v2m_rs1_io_desc __initdata = { + .virtual = V2M_PERIPH, + .pfn = __phys_to_pfn(0x1c000000), + .length = SZ_2M, + .type = MT_DEVICE, +}; + +static int __init v2m_dt_scan_memory_map(unsigned long node, const char *uname, + int depth, void *data) +{ + const char **map = data; + + if (strcmp(uname, "motherboard") != 0) + return 0; + + *map = of_get_flat_dt_prop(node, "arm,v2m-memory-map", NULL); + + return 1; +} + +void __init v2m_dt_map_io(void) +{ + const char *map = NULL; + + of_scan_flat_dt(v2m_dt_scan_memory_map, &map); + + if (map && strcmp(map, "rs1") == 0) + iotable_init(&v2m_rs1_io_desc, 1); + else + iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc)); + +#if defined(CONFIG_SMP) + vexpress_dt_smp_map_io(); +#endif +} + +static struct clk_lookup v2m_dt_lookups[] = { + { /* AMBA bus clock */ + .con_id = "apb_pclk", + .clk = &dummy_apb_pclk, + }, { /* SP804 timers */ + .dev_id = "sp804", + .con_id = "v2m-timer0", + .clk = &v2m_sp804_clk, + }, { /* SP804 timers */ + .dev_id = "sp804", + .con_id = "v2m-timer1", + .clk = &v2m_sp804_clk, + }, { /* PL180 MMCI */ + .dev_id = "mb:mmci", /* 10005000.mmci */ + .clk = &osc2_clk, + }, { /* PL050 KMI0 */ + .dev_id = "10006000.kmi", + .clk = &osc2_clk, + }, { /* PL050 KMI1 */ + .dev_id = "10007000.kmi", + .clk = &osc2_clk, + }, { /* PL011 UART0 */ + .dev_id = "10009000.uart", + .clk = &osc2_clk, + }, { /* PL011 UART1 */ + .dev_id = "1000a000.uart", + .clk = &osc2_clk, + }, { /* PL011 UART2 */ + .dev_id = "1000b000.uart", + .clk = &osc2_clk, + }, { /* PL011 UART3 */ + .dev_id = "1000c000.uart", + .clk = &osc2_clk, + }, { /* SP805 WDT */ + .dev_id = "1000f000.wdt", + .clk = &v2m_ref_clk, + }, { /* PL111 CLCD */ + .dev_id = "1001f000.clcd", + .clk = &osc1_clk, + }, + /* RS1 memory map */ + { /* PL180 MMCI */ + .dev_id = "mb:mmci", /* 1c050000.mmci */ + .clk = &osc2_clk, + }, { /* PL050 KMI0 */ + .dev_id = "1c060000.kmi", + .clk = &osc2_clk, + }, { /* PL050 KMI1 */ + .dev_id = "1c070000.kmi", + .clk = &osc2_clk, + }, { /* PL011 UART0 */ + .dev_id = "1c090000.uart", + .clk = &osc2_clk, + }, { /* PL011 UART1 */ + .dev_id = "1c0a0000.uart", + .clk = &osc2_clk, + }, { /* PL011 UART2 */ + .dev_id = "1c0b0000.uart", + .clk = &osc2_clk, + }, { /* PL011 UART3 */ + .dev_id = "1c0c0000.uart", + .clk = &osc2_clk, + }, { /* SP805 WDT */ + .dev_id = "1c0f0000.wdt", + .clk = &v2m_ref_clk, + }, { /* PL111 CLCD */ + .dev_id = "1c1f0000.clcd", + .clk = &osc1_clk, + }, +}; + +void __init v2m_dt_init_early(void) +{ + struct device_node *node; + u32 dt_hbi; + + node = of_find_compatible_node(NULL, NULL, "arm,vexpress-sysreg"); + v2m_sysreg_base = of_iomap(node, 0); + if (WARN_ON(!v2m_sysreg_base)) + return; + + /* Confirm board type against DT property, if available */ + if (of_property_read_u32(allnodes, "arm,hbi", &dt_hbi) == 0) { + u32 misc = readl(v2m_sysreg_base + V2M_SYS_MISC); + u32 id = readl(v2m_sysreg_base + (misc & SYS_MISC_MASTERSITE ? + V2M_SYS_PROCID1 : V2M_SYS_PROCID0)); + u32 hbi = id & SYS_PROCIDx_HBI_MASK; + + if (WARN_ON(dt_hbi != hbi)) + pr_warning("vexpress: DT HBI (%x) is not matching " + "hardware (%x)!\n", dt_hbi, hbi); + } + + clkdev_add_table(v2m_dt_lookups, ARRAY_SIZE(v2m_dt_lookups)); + versatile_sched_clock_init(v2m_sysreg_base + V2M_SYS_24MHZ, 24000000); +} + +static struct of_device_id vexpress_irq_match[] __initdata = { + { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, }, + {} +}; + +static void __init v2m_dt_init_irq(void) +{ + of_irq_init(vexpress_irq_match); +} + +static void __init v2m_dt_timer_init(void) +{ + struct device_node *node; + const char *path; + int err; + + node = of_find_compatible_node(NULL, NULL, "arm,sp810"); + v2m_sysctl_init(of_iomap(node, 0)); + + err = of_property_read_string(of_aliases, "arm,v2m_timer", &path); + if (WARN_ON(err)) + return; + node = of_find_node_by_path(path); + v2m_sp804_init(of_iomap(node, 0), irq_of_parse_and_map(node, 0)); +} + +static struct sys_timer v2m_dt_timer = { + .init = v2m_dt_timer_init, +}; + +static struct of_dev_auxdata v2m_dt_auxdata_lookup[] __initdata = { + OF_DEV_AUXDATA("arm,vexpress-flash", V2M_NOR0, "physmap-flash", + &v2m_flash_data), + OF_DEV_AUXDATA("arm,primecell", V2M_MMCI, "mb:mmci", &v2m_mmci_data), + /* RS1 memory map */ + OF_DEV_AUXDATA("arm,vexpress-flash", 0x08000000, "physmap-flash", + &v2m_flash_data), + OF_DEV_AUXDATA("arm,primecell", 0x1c050000, "mb:mmci", &v2m_mmci_data), + {} +}; + +static void __init v2m_dt_init(void) +{ + l2x0_of_init(0x00400000, 0xfe0fffff); + of_platform_populate(NULL, of_default_bus_match_table, + v2m_dt_auxdata_lookup, NULL); + pm_power_off = v2m_power_off; +} + +const static char *v2m_dt_match[] __initconst = { + "arm,vexpress", + NULL, +}; + +DT_MACHINE_START(VEXPRESS_DT, "ARM-Versatile Express") + .dt_compat = v2m_dt_match, + .map_io = v2m_dt_map_io, + .init_early = v2m_dt_init_early, + .init_irq = v2m_dt_init_irq, + .timer = &v2m_dt_timer, + .init_machine = v2m_dt_init, + .handle_irq = gic_handle_irq, + .restart = v2m_restart, +MACHINE_END + +#endif diff --git a/arch/arm/mach-vt8500/include/mach/system.h b/arch/arm/mach-vt8500/include/mach/system.h index d6c757e..58fa801 100644 --- a/arch/arm/mach-vt8500/include/mach/system.h +++ b/arch/arm/mach-vt8500/include/mach/system.h @@ -7,11 +7,6 @@ /* PM Software Reset request register */ #define VT8500_PMSR_VIRT 0xf8130060 -static inline void arch_idle(void) -{ - cpu_do_idle(); -} - static inline void arch_reset(char mode, const char *cmd) { writel(1, VT8500_PMSR_VIRT); diff --git a/arch/arm/mach-w90x900/dev.c b/arch/arm/mach-w90x900/dev.c index 78110be..db82568 100644 --- a/arch/arm/mach-w90x900/dev.c +++ b/arch/arm/mach-w90x900/dev.c @@ -530,6 +530,7 @@ static struct platform_device *nuc900_public_dev[] __initdata = { void __init nuc900_board_init(struct platform_device **device, int size) { + disable_hlt(); platform_add_devices(device, size); platform_add_devices(nuc900_public_dev, ARRAY_SIZE(nuc900_public_dev)); spi_register_board_info(nuc900_spi_board_info, diff --git a/arch/arm/mach-w90x900/include/mach/system.h b/arch/arm/mach-w90x900/include/mach/system.h deleted file mode 100644 index 2aaeb93..0000000 --- a/arch/arm/mach-w90x900/include/mach/system.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * arch/arm/mach-w90x900/include/mach/system.h - * - * Copyright (c) 2008 Nuvoton technology corporation - * All rights reserved. - * - * Wan ZongShun <mcuos.com@gmail.com> - * - * Based on arch/arm/mach-s3c2410/include/mach/system.h - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - */ -static void arch_idle(void) -{ -} diff --git a/arch/arm/mach-zynq/include/mach/system.h b/arch/arm/mach-zynq/include/mach/system.h deleted file mode 100644 index 8e88e0b..0000000 --- a/arch/arm/mach-zynq/include/mach/system.h +++ /dev/null @@ -1,23 +0,0 @@ -/* arch/arm/mach-zynq/include/mach/system.h - * - * Copyright (C) 2011 Xilinx - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __MACH_SYSTEM_H__ -#define __MACH_SYSTEM_H__ - -static inline void arch_idle(void) -{ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h index 1bf0df8..16d10a8 100644 --- a/arch/arm/plat-mxc/include/mach/common.h +++ b/arch/arm/plat-mxc/include/mach/common.h @@ -65,6 +65,7 @@ extern int mx51_clocks_init(unsigned long ckil, unsigned long osc, unsigned long ckih1, unsigned long ckih2); extern int mx53_clocks_init(unsigned long ckil, unsigned long osc, unsigned long ckih1, unsigned long ckih2); +extern int mx27_clocks_init_dt(void); extern int mx51_clocks_init_dt(void); extern int mx53_clocks_init_dt(void); extern int mx6q_clocks_init(void); diff --git a/arch/arm/plat-mxc/include/mach/system.h b/arch/arm/plat-mxc/include/mach/system.h deleted file mode 100644 index 13ad0df..0000000 --- a/arch/arm/plat-mxc/include/mach/system.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 1999 ARM Limited - * Copyright (C) 2000 Deep Blue Solutions Ltd - * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __ASM_ARCH_MXC_SYSTEM_H__ -#define __ASM_ARCH_MXC_SYSTEM_H__ - -static inline void arch_idle(void) -{ - cpu_do_idle(); -} - -#endif /* __ASM_ARCH_MXC_SYSTEM_H__ */ diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index aa59f42..f419a082 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig @@ -14,6 +14,7 @@ config ARCH_OMAP1 select CLKDEV_LOOKUP select CLKSRC_MMIO select GENERIC_IRQ_CHIP + select IRQ_DOMAIN select HAVE_IDE select NEED_MACH_MEMORY_H help @@ -24,6 +25,8 @@ config ARCH_OMAP2PLUS select CLKDEV_LOOKUP select GENERIC_IRQ_CHIP select OMAP_DM_TIMER + select USE_OF + select PROC_DEVICETREE if PROC_FS help "Systems based on OMAP2, OMAP3 or OMAP4" diff --git a/arch/arm/plat-omap/include/plat/system.h b/arch/arm/plat-omap/include/plat/system.h deleted file mode 100644 index 8e5ebd7..0000000 --- a/arch/arm/plat-omap/include/plat/system.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copied from arch/arm/mach-sa1100/include/mach/system.h - * Copyright (c) 1999 Nicolas Pitre <nico@fluxnic.net> - */ -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -#include <asm/proc-fns.h> - -static inline void arch_idle(void) -{ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index e8d9869..69fde03 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c @@ -348,7 +348,7 @@ static int omap_device_build_from_dt(struct platform_device *pdev) oh_cnt = of_property_count_strings(node, "ti,hwmods"); if (!oh_cnt || IS_ERR_VALUE(oh_cnt)) { - dev_warn(&pdev->dev, "No 'hwmods' to build omap_device\n"); + dev_dbg(&pdev->dev, "No 'hwmods' to build omap_device\n"); return -ENODEV; } diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c index 21f1fda..32a0993 100644 --- a/arch/arm/plat-s3c24xx/cpu.c +++ b/arch/arm/plat-s3c24xx/cpu.c @@ -32,6 +32,7 @@ #include <linux/io.h> #include <mach/hardware.h> +#include <mach/regs-clock.h> #include <asm/irq.h> #include <asm/cacheflush.h> @@ -190,8 +191,34 @@ static unsigned long s3c24xx_read_idcode_v4(void) return __raw_readl(S3C2410_GSTATUS1); } +static void s3c24xx_default_idle(void) +{ + unsigned long tmp; + int i; + + /* idle the system by using the idle mode which will wait for an + * interrupt to happen before restarting the system. + */ + + /* Warning: going into idle state upsets jtag scanning */ + + __raw_writel(__raw_readl(S3C2410_CLKCON) | S3C2410_CLKCON_IDLE, + S3C2410_CLKCON); + + /* the samsung port seems to do a loop and then unset idle.. */ + for (i = 0; i < 50; i++) + tmp += __raw_readl(S3C2410_CLKCON); /* ensure loop not optimised out */ + + /* this bit is not cleared on re-start... */ + + __raw_writel(__raw_readl(S3C2410_CLKCON) & ~S3C2410_CLKCON_IDLE, + S3C2410_CLKCON); +} + void __init s3c24xx_init_io(struct map_desc *mach_desc, int size) { + arm_pm_idle = s3c24xx_default_idle; + /* initialise the io descriptors we need for initialisation */ iotable_init(mach_desc, size); iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc)); diff --git a/arch/arm/plat-spear/include/plat/system.h b/arch/arm/plat-spear/include/plat/system.h deleted file mode 100644 index 86c6f83..0000000 --- a/arch/arm/plat-spear/include/plat/system.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * arch/arm/plat-spear/include/plat/system.h - * - * SPEAr platform specific architecture functions - * - * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar<viresh.kumar@st.com> - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#ifndef __PLAT_SYSTEM_H -#define __PLAT_SYSTEM_H - -static inline void arch_idle(void) -{ - /* - * This should do all the clock switching - * and wait for interrupt tricks - */ - cpu_do_idle(); -} - -#endif /* __PLAT_SYSTEM_H */ diff --git a/arch/arm/plat-versatile/localtimer.c b/arch/arm/plat-versatile/localtimer.c index 0fb3961..e156687 100644 --- a/arch/arm/plat-versatile/localtimer.c +++ b/arch/arm/plat-versatile/localtimer.c @@ -11,16 +11,42 @@ #include <linux/init.h> #include <linux/smp.h> #include <linux/clockchips.h> +#include <linux/of.h> +#include <linux/of_address.h> #include <asm/smp_twd.h> #include <asm/localtimer.h> #include <mach/irqs.h> +const static struct of_device_id twd_of_match[] __initconst = { + { .compatible = "arm,cortex-a9-twd-timer", }, + { .compatible = "arm,cortex-a5-twd-timer", }, + { .compatible = "arm,arm11mp-twd-timer", }, + { }, +}; + /* * Setup the local clock events for a CPU. */ int __cpuinit local_timer_setup(struct clock_event_device *evt) { +#if defined(CONFIG_OF) + static int dt_node_probed; + + /* Look for TWD node only once */ + if (!dt_node_probed) { + struct device_node *node = of_find_matching_node(NULL, + twd_of_match); + + if (node) + twd_base = of_iomap(node, 0); + + dt_node_probed = 1; + } +#endif + if (!twd_base) + return -ENXIO; + evt->irq = IRQ_LOCALTIMER; twd_timer_setup(evt); return 0; diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c index 402a7bb..889c544 100644 --- a/arch/avr32/mach-at32ap/at32ap700x.c +++ b/arch/avr32/mach-at32ap/at32ap700x.c @@ -1055,8 +1055,6 @@ struct platform_device *__init at32_add_device_usart(unsigned int id) return at32_usarts[id]; } -struct platform_device *atmel_default_console_device; - void __init at32_setup_serial_console(unsigned int usart_id) { atmel_default_console_device = at32_usarts[usart_id]; diff --git a/arch/avr32/mach-at32ap/include/mach/cpu.h b/arch/avr32/mach-at32ap/include/mach/cpu.h index 8181293..16a24b1 100644 --- a/arch/avr32/mach-at32ap/include/mach/cpu.h +++ b/arch/avr32/mach-at32ap/include/mach/cpu.h @@ -30,9 +30,6 @@ #define cpu_is_at91sam9261() (0) #define cpu_is_at91sam9263() (0) #define cpu_is_at91sam9rl() (0) -#define cpu_is_at91cap9() (0) -#define cpu_is_at91cap9_revB() (0) -#define cpu_is_at91cap9_revC() (0) #define cpu_is_at91sam9g10() (0) #define cpu_is_at91sam9g20() (0) #define cpu_is_at91sam9g45() (0) diff --git a/arch/c6x/Kconfig b/arch/c6x/Kconfig index 26e67f0..3c64b28 100644 --- a/arch/c6x/Kconfig +++ b/arch/c6x/Kconfig @@ -12,6 +12,7 @@ config TMS320C6X select HAVE_GENERIC_HARDIRQS select HAVE_MEMBLOCK select HAVE_SPARSE_IRQ + select IRQ_DOMAIN select OF select OF_EARLY_FLATTREE diff --git a/arch/c6x/include/asm/irq.h b/arch/c6x/include/asm/irq.h index a6ae3c9..f13b78d 100644 --- a/arch/c6x/include/asm/irq.h +++ b/arch/c6x/include/asm/irq.h @@ -13,6 +13,7 @@ #ifndef _ASM_C6X_IRQ_H #define _ASM_C6X_IRQ_H +#include <linux/irqdomain.h> #include <linux/threads.h> #include <linux/list.h> #include <linux/radix-tree.h> @@ -41,253 +42,9 @@ /* This number is used when no interrupt has been assigned */ #define NO_IRQ 0 -/* This type is the placeholder for a hardware interrupt number. It has to - * be big enough to enclose whatever representation is used by a given - * platform. - */ -typedef unsigned long irq_hw_number_t; - -/* Interrupt controller "host" data structure. This could be defined as a - * irq domain controller. That is, it handles the mapping between hardware - * and virtual interrupt numbers for a given interrupt domain. The host - * structure is generally created by the PIC code for a given PIC instance - * (though a host can cover more than one PIC if they have a flat number - * model). It's the host callbacks that are responsible for setting the - * irq_chip on a given irq_desc after it's been mapped. - * - * The host code and data structures are fairly agnostic to the fact that - * we use an open firmware device-tree. We do have references to struct - * device_node in two places: in irq_find_host() to find the host matching - * a given interrupt controller node, and of course as an argument to its - * counterpart host->ops->match() callback. However, those are treated as - * generic pointers by the core and the fact that it's actually a device-node - * pointer is purely a convention between callers and implementation. This - * code could thus be used on other architectures by replacing those two - * by some sort of arch-specific void * "token" used to identify interrupt - * controllers. - */ -struct irq_host; -struct radix_tree_root; -struct device_node; - -/* Functions below are provided by the host and called whenever a new mapping - * is created or an old mapping is disposed. The host can then proceed to - * whatever internal data structures management is required. It also needs - * to setup the irq_desc when returning from map(). - */ -struct irq_host_ops { - /* Match an interrupt controller device node to a host, returns - * 1 on a match - */ - int (*match)(struct irq_host *h, struct device_node *node); - - /* Create or update a mapping between a virtual irq number and a hw - * irq number. This is called only once for a given mapping. - */ - int (*map)(struct irq_host *h, unsigned int virq, irq_hw_number_t hw); - - /* Dispose of such a mapping */ - void (*unmap)(struct irq_host *h, unsigned int virq); - - /* Translate device-tree interrupt specifier from raw format coming - * from the firmware to a irq_hw_number_t (interrupt line number) and - * type (sense) that can be passed to set_irq_type(). In the absence - * of this callback, irq_create_of_mapping() and irq_of_parse_and_map() - * will return the hw number in the first cell and IRQ_TYPE_NONE for - * the type (which amount to keeping whatever default value the - * interrupt controller has for that line) - */ - int (*xlate)(struct irq_host *h, struct device_node *ctrler, - const u32 *intspec, unsigned int intsize, - irq_hw_number_t *out_hwirq, unsigned int *out_type); -}; - -struct irq_host { - struct list_head link; - - /* type of reverse mapping technique */ - unsigned int revmap_type; -#define IRQ_HOST_MAP_PRIORITY 0 /* core priority irqs, get irqs 1..15 */ -#define IRQ_HOST_MAP_NOMAP 1 /* no fast reverse mapping */ -#define IRQ_HOST_MAP_LINEAR 2 /* linear map of interrupts */ -#define IRQ_HOST_MAP_TREE 3 /* radix tree */ - union { - struct { - unsigned int size; - unsigned int *revmap; - } linear; - struct radix_tree_root tree; - } revmap_data; - struct irq_host_ops *ops; - void *host_data; - irq_hw_number_t inval_irq; - - /* Optional device node pointer */ - struct device_node *of_node; -}; - struct irq_data; extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d); extern irq_hw_number_t virq_to_hw(unsigned int virq); -extern bool virq_is_host(unsigned int virq, struct irq_host *host); - -/** - * irq_alloc_host - Allocate a new irq_host data structure - * @of_node: optional device-tree node of the interrupt controller - * @revmap_type: type of reverse mapping to use - * @revmap_arg: for IRQ_HOST_MAP_LINEAR linear only: size of the map - * @ops: map/unmap host callbacks - * @inval_irq: provide a hw number in that host space that is always invalid - * - * Allocates and initialize and irq_host structure. Note that in the case of - * IRQ_HOST_MAP_LEGACY, the map() callback will be called before this returns - * for all legacy interrupts except 0 (which is always the invalid irq for - * a legacy controller). For a IRQ_HOST_MAP_LINEAR, the map is allocated by - * this call as well. For a IRQ_HOST_MAP_TREE, the radix tree will be allocated - * later during boot automatically (the reverse mapping will use the slow path - * until that happens). - */ -extern struct irq_host *irq_alloc_host(struct device_node *of_node, - unsigned int revmap_type, - unsigned int revmap_arg, - struct irq_host_ops *ops, - irq_hw_number_t inval_irq); - - -/** - * irq_find_host - Locates a host for a given device node - * @node: device-tree node of the interrupt controller - */ -extern struct irq_host *irq_find_host(struct device_node *node); - - -/** - * irq_set_default_host - Set a "default" host - * @host: default host pointer - * - * For convenience, it's possible to set a "default" host that will be used - * whenever NULL is passed to irq_create_mapping(). It makes life easier for - * platforms that want to manipulate a few hard coded interrupt numbers that - * aren't properly represented in the device-tree. - */ -extern void irq_set_default_host(struct irq_host *host); - - -/** - * irq_set_virq_count - Set the maximum number of virt irqs - * @count: number of linux virtual irqs, capped with NR_IRQS - * - * This is mainly for use by platforms like iSeries who want to program - * the virtual irq number in the controller to avoid the reverse mapping - */ -extern void irq_set_virq_count(unsigned int count); - - -/** - * irq_create_mapping - Map a hardware interrupt into linux virq space - * @host: host owning this hardware interrupt or NULL for default host - * @hwirq: hardware irq number in that host space - * - * Only one mapping per hardware interrupt is permitted. Returns a linux - * virq number. - * If the sense/trigger is to be specified, set_irq_type() should be called - * on the number returned from that call. - */ -extern unsigned int irq_create_mapping(struct irq_host *host, - irq_hw_number_t hwirq); - - -/** - * irq_dispose_mapping - Unmap an interrupt - * @virq: linux virq number of the interrupt to unmap - */ -extern void irq_dispose_mapping(unsigned int virq); - -/** - * irq_find_mapping - Find a linux virq from an hw irq number. - * @host: host owning this hardware interrupt - * @hwirq: hardware irq number in that host space - * - * This is a slow path, for use by generic code. It's expected that an - * irq controller implementation directly calls the appropriate low level - * mapping function. - */ -extern unsigned int irq_find_mapping(struct irq_host *host, - irq_hw_number_t hwirq); - -/** - * irq_create_direct_mapping - Allocate a virq for direct mapping - * @host: host to allocate the virq for or NULL for default host - * - * This routine is used for irq controllers which can choose the hardware - * interrupt numbers they generate. In such a case it's simplest to use - * the linux virq as the hardware interrupt number. - */ -extern unsigned int irq_create_direct_mapping(struct irq_host *host); - -/** - * irq_radix_revmap_insert - Insert a hw irq to linux virq number mapping. - * @host: host owning this hardware interrupt - * @virq: linux irq number - * @hwirq: hardware irq number in that host space - * - * This is for use by irq controllers that use a radix tree reverse - * mapping for fast lookup. - */ -extern void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq, - irq_hw_number_t hwirq); - -/** - * irq_radix_revmap_lookup - Find a linux virq from a hw irq number. - * @host: host owning this hardware interrupt - * @hwirq: hardware irq number in that host space - * - * This is a fast path, for use by irq controller code that uses radix tree - * revmaps - */ -extern unsigned int irq_radix_revmap_lookup(struct irq_host *host, - irq_hw_number_t hwirq); - -/** - * irq_linear_revmap - Find a linux virq from a hw irq number. - * @host: host owning this hardware interrupt - * @hwirq: hardware irq number in that host space - * - * This is a fast path, for use by irq controller code that uses linear - * revmaps. It does fallback to the slow path if the revmap doesn't exist - * yet and will create the revmap entry with appropriate locking - */ - -extern unsigned int irq_linear_revmap(struct irq_host *host, - irq_hw_number_t hwirq); - - - -/** - * irq_alloc_virt - Allocate virtual irq numbers - * @host: host owning these new virtual irqs - * @count: number of consecutive numbers to allocate - * @hint: pass a hint number, the allocator will try to use a 1:1 mapping - * - * This is a low level function that is used internally by irq_create_mapping() - * and that can be used by some irq controllers implementations for things - * like allocating ranges of numbers for MSIs. The revmaps are left untouched. - */ -extern unsigned int irq_alloc_virt(struct irq_host *host, - unsigned int count, - unsigned int hint); - -/** - * irq_free_virt - Free virtual irq numbers - * @virq: virtual irq number of the first interrupt to free - * @count: number of interrupts to free - * - * This function is the opposite of irq_alloc_virt. It will not clear reverse - * maps, this should be done previously by unmap'ing the interrupt. In fact, - * all interrupts covered by the range being freed should have been unmapped - * prior to calling this. - */ -extern void irq_free_virt(unsigned int virq, unsigned int count); extern void __init init_pic_c64xplus(void); diff --git a/arch/c6x/kernel/irq.c b/arch/c6x/kernel/irq.c index 0929e4b..d77bcfd 100644 --- a/arch/c6x/kernel/irq.c +++ b/arch/c6x/kernel/irq.c @@ -73,10 +73,10 @@ asmlinkage void c6x_do_IRQ(unsigned int prio, struct pt_regs *regs) set_irq_regs(old_regs); } -static struct irq_host *core_host; +static struct irq_domain *core_domain; -static int core_host_map(struct irq_host *h, unsigned int virq, - irq_hw_number_t hw) +static int core_domain_map(struct irq_domain *h, unsigned int virq, + irq_hw_number_t hw) { if (hw < 4 || hw >= NR_PRIORITY_IRQS) return -EINVAL; @@ -86,8 +86,9 @@ static int core_host_map(struct irq_host *h, unsigned int virq, return 0; } -static struct irq_host_ops core_host_ops = { - .map = core_host_map, +static const struct irq_domain_ops core_domain_ops = { + .map = core_domain_map, + .xlate = irq_domain_xlate_onecell, }; void __init init_IRQ(void) @@ -100,10 +101,11 @@ void __init init_IRQ(void) np = of_find_compatible_node(NULL, NULL, "ti,c64x+core-pic"); if (np != NULL) { /* create the core host */ - core_host = irq_alloc_host(np, IRQ_HOST_MAP_PRIORITY, 0, - &core_host_ops, 0); - if (core_host) - irq_set_default_host(core_host); + core_domain = irq_domain_add_legacy(np, NR_PRIORITY_IRQS, + 0, 0, &core_domain_ops, + NULL); + if (core_domain) + irq_set_default_host(core_domain); of_node_put(np); } @@ -128,601 +130,15 @@ int arch_show_interrupts(struct seq_file *p, int prec) return 0; } -/* - * IRQ controller and virtual interrupts - */ - -/* The main irq map itself is an array of NR_IRQ entries containing the - * associate host and irq number. An entry with a host of NULL is free. - * An entry can be allocated if it's free, the allocator always then sets - * hwirq first to the host's invalid irq number and then fills ops. - */ -struct irq_map_entry { - irq_hw_number_t hwirq; - struct irq_host *host; -}; - -static LIST_HEAD(irq_hosts); -static DEFINE_RAW_SPINLOCK(irq_big_lock); -static DEFINE_MUTEX(revmap_trees_mutex); -static struct irq_map_entry irq_map[NR_IRQS]; -static unsigned int irq_virq_count = NR_IRQS; -static struct irq_host *irq_default_host; - irq_hw_number_t irqd_to_hwirq(struct irq_data *d) { - return irq_map[d->irq].hwirq; + return d->hwirq; } EXPORT_SYMBOL_GPL(irqd_to_hwirq); irq_hw_number_t virq_to_hw(unsigned int virq) { - return irq_map[virq].hwirq; + struct irq_data *irq_data = irq_get_irq_data(virq); + return WARN_ON(!irq_data) ? 0 : irq_data->hwirq; } EXPORT_SYMBOL_GPL(virq_to_hw); - -bool virq_is_host(unsigned int virq, struct irq_host *host) -{ - return irq_map[virq].host == host; -} -EXPORT_SYMBOL_GPL(virq_is_host); - -static int default_irq_host_match(struct irq_host *h, struct device_node *np) -{ - return h->of_node != NULL && h->of_node == np; -} - -struct irq_host *irq_alloc_host(struct device_node *of_node, - unsigned int revmap_type, - unsigned int revmap_arg, - struct irq_host_ops *ops, - irq_hw_number_t inval_irq) -{ - struct irq_host *host; - unsigned int size = sizeof(struct irq_host); - unsigned int i; - unsigned int *rmap; - unsigned long flags; - - /* Allocate structure and revmap table if using linear mapping */ - if (revmap_type == IRQ_HOST_MAP_LINEAR) - size += revmap_arg * sizeof(unsigned int); - host = kzalloc(size, GFP_KERNEL); - if (host == NULL) - return NULL; - - /* Fill structure */ - host->revmap_type = revmap_type; - host->inval_irq = inval_irq; - host->ops = ops; - host->of_node = of_node_get(of_node); - - if (host->ops->match == NULL) - host->ops->match = default_irq_host_match; - - raw_spin_lock_irqsave(&irq_big_lock, flags); - - /* Check for the priority controller. */ - if (revmap_type == IRQ_HOST_MAP_PRIORITY) { - if (irq_map[0].host != NULL) { - raw_spin_unlock_irqrestore(&irq_big_lock, flags); - of_node_put(host->of_node); - kfree(host); - return NULL; - } - irq_map[0].host = host; - } - - list_add(&host->link, &irq_hosts); - raw_spin_unlock_irqrestore(&irq_big_lock, flags); - - /* Additional setups per revmap type */ - switch (revmap_type) { - case IRQ_HOST_MAP_PRIORITY: - /* 0 is always the invalid number for priority */ - host->inval_irq = 0; - /* setup us as the host for all priority interrupts */ - for (i = 1; i < NR_PRIORITY_IRQS; i++) { - irq_map[i].hwirq = i; - smp_wmb(); - irq_map[i].host = host; - smp_wmb(); - - ops->map(host, i, i); - } - break; - case IRQ_HOST_MAP_LINEAR: - rmap = (unsigned int *)(host + 1); - for (i = 0; i < revmap_arg; i++) - rmap[i] = NO_IRQ; - host->revmap_data.linear.size = revmap_arg; - smp_wmb(); - host->revmap_data.linear.revmap = rmap; - break; - case IRQ_HOST_MAP_TREE: - INIT_RADIX_TREE(&host->revmap_data.tree, GFP_KERNEL); - break; - default: - break; - } - - pr_debug("irq: Allocated host of type %d @0x%p\n", revmap_type, host); - - return host; -} - -struct irq_host *irq_find_host(struct device_node *node) -{ - struct irq_host *h, *found = NULL; - unsigned long flags; - - /* We might want to match the legacy controller last since - * it might potentially be set to match all interrupts in - * the absence of a device node. This isn't a problem so far - * yet though... - */ - raw_spin_lock_irqsave(&irq_big_lock, flags); - list_for_each_entry(h, &irq_hosts, link) - if (h->ops->match(h, node)) { - found = h; - break; - } - raw_spin_unlock_irqrestore(&irq_big_lock, flags); - return found; -} -EXPORT_SYMBOL_GPL(irq_find_host); - -void irq_set_default_host(struct irq_host *host) -{ - pr_debug("irq: Default host set to @0x%p\n", host); - - irq_default_host = host; -} - -void irq_set_virq_count(unsigned int count) -{ - pr_debug("irq: Trying to set virq count to %d\n", count); - - BUG_ON(count < NR_PRIORITY_IRQS); - if (count < NR_IRQS) - irq_virq_count = count; -} - -static int irq_setup_virq(struct irq_host *host, unsigned int virq, - irq_hw_number_t hwirq) -{ - int res; - - res = irq_alloc_desc_at(virq, 0); - if (res != virq) { - pr_debug("irq: -> allocating desc failed\n"); - goto error; - } - - /* map it */ - smp_wmb(); - irq_map[virq].hwirq = hwirq; - smp_mb(); - - if (host->ops->map(host, virq, hwirq)) { - pr_debug("irq: -> mapping failed, freeing\n"); - goto errdesc; - } - - irq_clear_status_flags(virq, IRQ_NOREQUEST); - - return 0; - -errdesc: - irq_free_descs(virq, 1); -error: - irq_free_virt(virq, 1); - return -1; -} - -unsigned int irq_create_direct_mapping(struct irq_host *host) -{ - unsigned int virq; - - if (host == NULL) - host = irq_default_host; - - BUG_ON(host == NULL); - WARN_ON(host->revmap_type != IRQ_HOST_MAP_NOMAP); - - virq = irq_alloc_virt(host, 1, 0); - if (virq == NO_IRQ) { - pr_debug("irq: create_direct virq allocation failed\n"); - return NO_IRQ; - } - - pr_debug("irq: create_direct obtained virq %d\n", virq); - - if (irq_setup_virq(host, virq, virq)) - return NO_IRQ; - - return virq; -} - -unsigned int irq_create_mapping(struct irq_host *host, - irq_hw_number_t hwirq) -{ - unsigned int virq, hint; - - pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", host, hwirq); - - /* Look for default host if nececssary */ - if (host == NULL) - host = irq_default_host; - if (host == NULL) { - printk(KERN_WARNING "irq_create_mapping called for" - " NULL host, hwirq=%lx\n", hwirq); - WARN_ON(1); - return NO_IRQ; - } - pr_debug("irq: -> using host @%p\n", host); - - /* Check if mapping already exists */ - virq = irq_find_mapping(host, hwirq); - if (virq != NO_IRQ) { - pr_debug("irq: -> existing mapping on virq %d\n", virq); - return virq; - } - - /* Allocate a virtual interrupt number */ - hint = hwirq % irq_virq_count; - virq = irq_alloc_virt(host, 1, hint); - if (virq == NO_IRQ) { - pr_debug("irq: -> virq allocation failed\n"); - return NO_IRQ; - } - - if (irq_setup_virq(host, virq, hwirq)) - return NO_IRQ; - - pr_debug("irq: irq %lu on host %s mapped to virtual irq %u\n", - hwirq, host->of_node ? host->of_node->full_name : "null", virq); - - return virq; -} -EXPORT_SYMBOL_GPL(irq_create_mapping); - -unsigned int irq_create_of_mapping(struct device_node *controller, - const u32 *intspec, unsigned int intsize) -{ - struct irq_host *host; - irq_hw_number_t hwirq; - unsigned int type = IRQ_TYPE_NONE; - unsigned int virq; - - if (controller == NULL) - host = irq_default_host; - else - host = irq_find_host(controller); - if (host == NULL) { - printk(KERN_WARNING "irq: no irq host found for %s !\n", - controller->full_name); - return NO_IRQ; - } - - /* If host has no translation, then we assume interrupt line */ - if (host->ops->xlate == NULL) - hwirq = intspec[0]; - else { - if (host->ops->xlate(host, controller, intspec, intsize, - &hwirq, &type)) - return NO_IRQ; - } - - /* Create mapping */ - virq = irq_create_mapping(host, hwirq); - if (virq == NO_IRQ) - return virq; - - /* Set type if specified and different than the current one */ - if (type != IRQ_TYPE_NONE && - type != (irqd_get_trigger_type(irq_get_irq_data(virq)))) - irq_set_irq_type(virq, type); - return virq; -} -EXPORT_SYMBOL_GPL(irq_create_of_mapping); - -void irq_dispose_mapping(unsigned int virq) -{ - struct irq_host *host; - irq_hw_number_t hwirq; - - if (virq == NO_IRQ) - return; - - /* Never unmap priority interrupts */ - if (virq < NR_PRIORITY_IRQS) - return; - - host = irq_map[virq].host; - if (WARN_ON(host == NULL)) - return; - - irq_set_status_flags(virq, IRQ_NOREQUEST); - - /* remove chip and handler */ - irq_set_chip_and_handler(virq, NULL, NULL); - - /* Make sure it's completed */ - synchronize_irq(virq); - - /* Tell the PIC about it */ - if (host->ops->unmap) - host->ops->unmap(host, virq); - smp_mb(); - - /* Clear reverse map */ - hwirq = irq_map[virq].hwirq; - switch (host->revmap_type) { - case IRQ_HOST_MAP_LINEAR: - if (hwirq < host->revmap_data.linear.size) - host->revmap_data.linear.revmap[hwirq] = NO_IRQ; - break; - case IRQ_HOST_MAP_TREE: - mutex_lock(&revmap_trees_mutex); - radix_tree_delete(&host->revmap_data.tree, hwirq); - mutex_unlock(&revmap_trees_mutex); - break; - } - - /* Destroy map */ - smp_mb(); - irq_map[virq].hwirq = host->inval_irq; - - irq_free_descs(virq, 1); - /* Free it */ - irq_free_virt(virq, 1); -} -EXPORT_SYMBOL_GPL(irq_dispose_mapping); - -unsigned int irq_find_mapping(struct irq_host *host, - irq_hw_number_t hwirq) -{ - unsigned int i; - unsigned int hint = hwirq % irq_virq_count; - - /* Look for default host if nececssary */ - if (host == NULL) - host = irq_default_host; - if (host == NULL) - return NO_IRQ; - - /* Slow path does a linear search of the map */ - i = hint; - do { - if (irq_map[i].host == host && - irq_map[i].hwirq == hwirq) - return i; - i++; - if (i >= irq_virq_count) - i = 4; - } while (i != hint); - return NO_IRQ; -} -EXPORT_SYMBOL_GPL(irq_find_mapping); - -unsigned int irq_radix_revmap_lookup(struct irq_host *host, - irq_hw_number_t hwirq) -{ - struct irq_map_entry *ptr; - unsigned int virq; - - if (WARN_ON_ONCE(host->revmap_type != IRQ_HOST_MAP_TREE)) - return irq_find_mapping(host, hwirq); - - /* - * The ptr returned references the static global irq_map. - * but freeing an irq can delete nodes along the path to - * do the lookup via call_rcu. - */ - rcu_read_lock(); - ptr = radix_tree_lookup(&host->revmap_data.tree, hwirq); - rcu_read_unlock(); - - /* - * If found in radix tree, then fine. - * Else fallback to linear lookup - this should not happen in practice - * as it means that we failed to insert the node in the radix tree. - */ - if (ptr) - virq = ptr - irq_map; - else - virq = irq_find_mapping(host, hwirq); - - return virq; -} - -void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq, - irq_hw_number_t hwirq) -{ - if (WARN_ON(host->revmap_type != IRQ_HOST_MAP_TREE)) - return; - - if (virq != NO_IRQ) { - mutex_lock(&revmap_trees_mutex); - radix_tree_insert(&host->revmap_data.tree, hwirq, - &irq_map[virq]); - mutex_unlock(&revmap_trees_mutex); - } -} - -unsigned int irq_linear_revmap(struct irq_host *host, - irq_hw_number_t hwirq) -{ - unsigned int *revmap; - - if (WARN_ON_ONCE(host->revmap_type != IRQ_HOST_MAP_LINEAR)) - return irq_find_mapping(host, hwirq); - - /* Check revmap bounds */ - if (unlikely(hwirq >= host->revmap_data.linear.size)) - return irq_find_mapping(host, hwirq); - - /* Check if revmap was allocated */ - revmap = host->revmap_data.linear.revmap; - if (unlikely(revmap == NULL)) - return irq_find_mapping(host, hwirq); - - /* Fill up revmap with slow path if no mapping found */ - if (unlikely(revmap[hwirq] == NO_IRQ)) - revmap[hwirq] = irq_find_mapping(host, hwirq); - - return revmap[hwirq]; -} - -unsigned int irq_alloc_virt(struct irq_host *host, - unsigned int count, - unsigned int hint) -{ - unsigned long flags; - unsigned int i, j, found = NO_IRQ; - - if (count == 0 || count > (irq_virq_count - NR_PRIORITY_IRQS)) - return NO_IRQ; - - raw_spin_lock_irqsave(&irq_big_lock, flags); - - /* Use hint for 1 interrupt if any */ - if (count == 1 && hint >= NR_PRIORITY_IRQS && - hint < irq_virq_count && irq_map[hint].host == NULL) { - found = hint; - goto hint_found; - } - - /* Look for count consecutive numbers in the allocatable - * (non-legacy) space - */ - for (i = NR_PRIORITY_IRQS, j = 0; i < irq_virq_count; i++) { - if (irq_map[i].host != NULL) - j = 0; - else - j++; - - if (j == count) { - found = i - count + 1; - break; - } - } - if (found == NO_IRQ) { - raw_spin_unlock_irqrestore(&irq_big_lock, flags); - return NO_IRQ; - } - hint_found: - for (i = found; i < (found + count); i++) { - irq_map[i].hwirq = host->inval_irq; - smp_wmb(); - irq_map[i].host = host; - } - raw_spin_unlock_irqrestore(&irq_big_lock, flags); - return found; -} - -void irq_free_virt(unsigned int virq, unsigned int count) -{ - unsigned long flags; - unsigned int i; - - WARN_ON(virq < NR_PRIORITY_IRQS); - WARN_ON(count == 0 || (virq + count) > irq_virq_count); - - if (virq < NR_PRIORITY_IRQS) { - if (virq + count < NR_PRIORITY_IRQS) - return; - count -= NR_PRIORITY_IRQS - virq; - virq = NR_PRIORITY_IRQS; - } - - if (count > irq_virq_count || virq > irq_virq_count - count) { - if (virq > irq_virq_count) - return; - count = irq_virq_count - virq; - } - - raw_spin_lock_irqsave(&irq_big_lock, flags); - for (i = virq; i < (virq + count); i++) { - struct irq_host *host; - - host = irq_map[i].host; - irq_map[i].hwirq = host->inval_irq; - smp_wmb(); - irq_map[i].host = NULL; - } - raw_spin_unlock_irqrestore(&irq_big_lock, flags); -} - -#ifdef CONFIG_VIRQ_DEBUG -static int virq_debug_show(struct seq_file *m, void *private) -{ - unsigned long flags; - struct irq_desc *desc; - const char *p; - static const char none[] = "none"; - void *data; - int i; - - seq_printf(m, "%-5s %-7s %-15s %-18s %s\n", "virq", "hwirq", - "chip name", "chip data", "host name"); - - for (i = 1; i < nr_irqs; i++) { - desc = irq_to_desc(i); - if (!desc) - continue; - - raw_spin_lock_irqsave(&desc->lock, flags); - - if (desc->action && desc->action->handler) { - struct irq_chip *chip; - - seq_printf(m, "%5d ", i); - seq_printf(m, "0x%05lx ", irq_map[i].hwirq); - - chip = irq_desc_get_chip(desc); - if (chip && chip->name) - p = chip->name; - else - p = none; - seq_printf(m, "%-15s ", p); - - data = irq_desc_get_chip_data(desc); - seq_printf(m, "0x%16p ", data); - - if (irq_map[i].host && irq_map[i].host->of_node) - p = irq_map[i].host->of_node->full_name; - else - p = none; - seq_printf(m, "%s\n", p); - } - - raw_spin_unlock_irqrestore(&desc->lock, flags); - } - - return 0; -} - -static int virq_debug_open(struct inode *inode, struct file *file) -{ - return single_open(file, virq_debug_show, inode->i_private); -} - -static const struct file_operations virq_debug_fops = { - .open = virq_debug_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int __init irq_debugfs_init(void) -{ - if (debugfs_create_file("virq_mapping", S_IRUGO, powerpc_debugfs_root, - NULL, &virq_debug_fops) == NULL) - return -ENOMEM; - - return 0; -} -device_initcall(irq_debugfs_init); -#endif /* CONFIG_VIRQ_DEBUG */ diff --git a/arch/c6x/platforms/megamod-pic.c b/arch/c6x/platforms/megamod-pic.c index 7c37a94..c1c4e2a 100644 --- a/arch/c6x/platforms/megamod-pic.c +++ b/arch/c6x/platforms/megamod-pic.c @@ -48,7 +48,7 @@ struct megamod_regs { }; struct megamod_pic { - struct irq_host *irqhost; + struct irq_domain *irqhost; struct megamod_regs __iomem *regs; raw_spinlock_t lock; @@ -116,7 +116,7 @@ static void megamod_irq_cascade(unsigned int irq, struct irq_desc *desc) } } -static int megamod_map(struct irq_host *h, unsigned int virq, +static int megamod_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { struct megamod_pic *pic = h->host_data; @@ -136,21 +136,9 @@ static int megamod_map(struct irq_host *h, unsigned int virq, return 0; } -static int megamod_xlate(struct irq_host *h, struct device_node *ct, - const u32 *intspec, unsigned int intsize, - irq_hw_number_t *out_hwirq, unsigned int *out_type) - -{ - /* megamod intspecs must have 1 cell */ - BUG_ON(intsize != 1); - *out_hwirq = intspec[0]; - *out_type = IRQ_TYPE_NONE; - return 0; -} - -static struct irq_host_ops megamod_host_ops = { +static const struct irq_domain_ops megamod_domain_ops = { .map = megamod_map, - .xlate = megamod_xlate, + .xlate = irq_domain_xlate_onecell, }; static void __init set_megamod_mux(struct megamod_pic *pic, int src, int output) @@ -223,9 +211,8 @@ static struct megamod_pic * __init init_megamod_pic(struct device_node *np) return NULL; } - pic->irqhost = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, - NR_COMBINERS * 32, &megamod_host_ops, - IRQ_UNMAPPED); + pic->irqhost = irq_domain_add_linear(np, NR_COMBINERS * 32, + &megamod_domain_ops, pic); if (!pic->irqhost) { pr_err("%s: Could not alloc host.\n", np->full_name); goto error_free; diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index c8d6efb..11060fa 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -14,6 +14,7 @@ config MICROBLAZE select TRACING_SUPPORT select OF select OF_EARLY_FLATTREE + select IRQ_DOMAIN select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW diff --git a/arch/microblaze/include/asm/hardirq.h b/arch/microblaze/include/asm/hardirq.h index cd1ac9a..fb3c05a 100644 --- a/arch/microblaze/include/asm/hardirq.h +++ b/arch/microblaze/include/asm/hardirq.h @@ -1,17 +1 @@ -/* - * Copyright (C) 2006 Atmark Techno, Inc. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ - -#ifndef _ASM_MICROBLAZE_HARDIRQ_H -#define _ASM_MICROBLAZE_HARDIRQ_H - -/* should be defined in each interrupt controller driver */ -extern unsigned int get_irq(struct pt_regs *regs); - #include <asm-generic/hardirq.h> - -#endif /* _ASM_MICROBLAZE_HARDIRQ_H */ diff --git a/arch/microblaze/include/asm/irq.h b/arch/microblaze/include/asm/irq.h index a175132..bab3b13 100644 --- a/arch/microblaze/include/asm/irq.h +++ b/arch/microblaze/include/asm/irq.h @@ -9,49 +9,13 @@ #ifndef _ASM_MICROBLAZE_IRQ_H #define _ASM_MICROBLAZE_IRQ_H - -/* - * Linux IRQ# is currently offset by one to map to the hardware - * irq number. So hardware IRQ0 maps to Linux irq 1. - */ -#define NO_IRQ_OFFSET 1 -#define IRQ_OFFSET NO_IRQ_OFFSET -#define NR_IRQS (32 + IRQ_OFFSET) +#define NR_IRQS (32 + 1) #include <asm-generic/irq.h> -/* This type is the placeholder for a hardware interrupt number. It has to - * be big enough to enclose whatever representation is used by a given - * platform. - */ -typedef unsigned long irq_hw_number_t; - -extern unsigned int nr_irq; - struct pt_regs; extern void do_IRQ(struct pt_regs *regs); -/** FIXME - not implement - * irq_dispose_mapping - Unmap an interrupt - * @virq: linux virq number of the interrupt to unmap - */ -static inline void irq_dispose_mapping(unsigned int virq) -{ - return; -} - -struct irq_host; - -/** - * irq_create_mapping - Map a hardware interrupt into linux virq space - * @host: host owning this hardware interrupt or NULL for default host - * @hwirq: hardware irq number in that host space - * - * Only one mapping per hardware interrupt is permitted. Returns a linux - * virq number. - * If the sense/trigger is to be specified, set_irq_type() should be called - * on the number returned from that call. - */ -extern unsigned int irq_create_mapping(struct irq_host *host, - irq_hw_number_t hwirq); +/* should be defined in each interrupt controller driver */ +extern unsigned int get_irq(void); #endif /* _ASM_MICROBLAZE_IRQ_H */ diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c index 44b177e..ad12067 100644 --- a/arch/microblaze/kernel/intc.c +++ b/arch/microblaze/kernel/intc.c @@ -9,6 +9,7 @@ */ #include <linux/init.h> +#include <linux/irqdomain.h> #include <linux/irq.h> #include <asm/page.h> #include <linux/io.h> @@ -25,8 +26,6 @@ static unsigned int intc_baseaddr; #define INTC_BASE intc_baseaddr #endif -unsigned int nr_irq; - /* No one else should require these constants, so define them locally here. */ #define ISR 0x00 /* Interrupt Status Register */ #define IPR 0x04 /* Interrupt Pending Register */ @@ -84,24 +83,45 @@ static struct irq_chip intc_dev = { .irq_mask_ack = intc_mask_ack, }; -unsigned int get_irq(struct pt_regs *regs) +static struct irq_domain *root_domain; + +unsigned int get_irq(void) { - int irq; + unsigned int hwirq, irq = -1; - /* - * NOTE: This function is the one that needs to be improved in - * order to handle multiple interrupt controllers. It currently - * is hardcoded to check for interrupts only on the first INTC. - */ - irq = in_be32(INTC_BASE + IVR) + NO_IRQ_OFFSET; - pr_debug("get_irq: %d\n", irq); + hwirq = in_be32(INTC_BASE + IVR); + if (hwirq != -1U) + irq = irq_find_mapping(root_domain, hwirq); + + pr_debug("get_irq: hwirq=%d, irq=%d\n", hwirq, irq); return irq; } +int xintc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) +{ + u32 intr_mask = (u32)d->host_data; + + if (intr_mask & (1 << hw)) { + irq_set_chip_and_handler_name(irq, &intc_dev, + handle_edge_irq, "edge"); + irq_clear_status_flags(irq, IRQ_LEVEL); + } else { + irq_set_chip_and_handler_name(irq, &intc_dev, + handle_level_irq, "level"); + irq_set_status_flags(irq, IRQ_LEVEL); + } + return 0; +} + +static const struct irq_domain_ops xintc_irq_domain_ops = { + .xlate = irq_domain_xlate_onetwocell, + .map = xintc_map, +}; + void __init init_IRQ(void) { - u32 i, intr_mask; + u32 nr_irq, intr_mask; struct device_node *intc = NULL; #ifdef CONFIG_SELFMOD_INTC unsigned int intc_baseaddr = 0; @@ -146,16 +166,9 @@ void __init init_IRQ(void) /* Turn on the Master Enable. */ out_be32(intc_baseaddr + MER, MER_HIE | MER_ME); - for (i = IRQ_OFFSET; i < (nr_irq + IRQ_OFFSET); ++i) { - if (intr_mask & (0x00000001 << (i - IRQ_OFFSET))) { - irq_set_chip_and_handler_name(i, &intc_dev, - handle_edge_irq, "edge"); - irq_clear_status_flags(i, IRQ_LEVEL); - } else { - irq_set_chip_and_handler_name(i, &intc_dev, - handle_level_irq, "level"); - irq_set_status_flags(i, IRQ_LEVEL); - } - irq_get_irq_data(i)->hwirq = i - IRQ_OFFSET; - } + /* Yeah, okay, casting the intr_mask to a void* is butt-ugly, but I'm + * lazy and Michal can clean it up to something nicer when he tests + * and commits this patch. ~~gcl */ + root_domain = irq_domain_add_linear(intc, nr_irq, &xintc_irq_domain_ops, + (void *)intr_mask); } diff --git a/arch/microblaze/kernel/irq.c b/arch/microblaze/kernel/irq.c index bbebcae..ace700a 100644 --- a/arch/microblaze/kernel/irq.c +++ b/arch/microblaze/kernel/irq.c @@ -31,14 +31,13 @@ void __irq_entry do_IRQ(struct pt_regs *regs) trace_hardirqs_off(); irq_enter(); - irq = get_irq(regs); + irq = get_irq(); next_irq: BUG_ON(!irq); - /* Substract 1 because of get_irq */ - generic_handle_irq(irq + IRQ_OFFSET - NO_IRQ_OFFSET); + generic_handle_irq(irq); - irq = get_irq(regs); - if (irq) { + irq = get_irq(); + if (irq != -1U) { pr_debug("next irq: %d\n", irq); ++concurrent_irq; goto next_irq; @@ -48,18 +47,3 @@ next_irq: set_irq_regs(old_regs); trace_hardirqs_on(); } - -/* MS: There is no any advance mapping mechanism. We are using simple 32bit - intc without any cascades or any connection that's why mapping is 1:1 */ -unsigned int irq_create_mapping(struct irq_host *host, irq_hw_number_t hwirq) -{ - return hwirq + IRQ_OFFSET; -} -EXPORT_SYMBOL_GPL(irq_create_mapping); - -unsigned int irq_create_of_mapping(struct device_node *controller, - const u32 *intspec, unsigned int intsize) -{ - return intspec[0] + IRQ_OFFSET; -} -EXPORT_SYMBOL_GPL(irq_create_of_mapping); diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c index 604cd9d..70e6d0b 100644 --- a/arch/microblaze/kernel/setup.c +++ b/arch/microblaze/kernel/setup.c @@ -51,8 +51,6 @@ void __init setup_arch(char **cmdline_p) unflatten_device_tree(); - /* NOTE I think that this function is not necessary to call */ - /* irq_early_init(); */ setup_cpuinfo(); microblaze_cache_init(); diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 5ab6e89..edbbae1 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -2327,6 +2327,7 @@ config USE_OF bool "Flattened Device Tree support" select OF select OF_EARLY_FLATTREE + select IRQ_DOMAIN help Include support for flattened device tree machine descriptions. diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h index 2354c87..fb698dc 100644 --- a/arch/mips/include/asm/irq.h +++ b/arch/mips/include/asm/irq.h @@ -11,15 +11,12 @@ #include <linux/linkage.h> #include <linux/smp.h> +#include <linux/irqdomain.h> #include <asm/mipsmtregs.h> #include <irq.h> -static inline void irq_dispose_mapping(unsigned int virq) -{ -} - #ifdef CONFIG_I8259 static inline int irq_canonicalize(int irq) { diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c index 6b8b420..558b539 100644 --- a/arch/mips/kernel/prom.c +++ b/arch/mips/kernel/prom.c @@ -60,20 +60,6 @@ void __init early_init_dt_setup_initrd_arch(unsigned long start, } #endif -/* - * irq_create_of_mapping - Hook to resolve OF irq specifier into a Linux irq# - * - * Currently the mapping mechanism is trivial; simple flat hwirq numbers are - * mapped 1:1 onto Linux irq numbers. Cascaded irq controllers are not - * supported. - */ -unsigned int irq_create_of_mapping(struct device_node *controller, - const u32 *intspec, unsigned int intsize) -{ - return intspec[0]; -} -EXPORT_SYMBOL_GPL(irq_create_of_mapping); - void __init early_init_devtree(void *params) { /* Setup flat device-tree pointer */ diff --git a/arch/openrisc/include/asm/prom.h b/arch/openrisc/include/asm/prom.h index e1f3fe2..bbb34e5 100644 --- a/arch/openrisc/include/asm/prom.h +++ b/arch/openrisc/include/asm/prom.h @@ -24,6 +24,7 @@ #include <linux/types.h> #include <asm/irq.h> +#include <linux/irqdomain.h> #include <linux/atomic.h> #include <linux/of_irq.h> #include <linux/of_fdt.h> @@ -63,15 +64,6 @@ extern const void *of_get_mac_address(struct device_node *np); struct pci_dev; extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq); -/* This routine is here to provide compatibility with how powerpc - * handles IRQ mapping for OF device nodes. We precompute and permanently - * register them in the platform_device objects, whereas powerpc computes them - * on request. - */ -static inline void irq_dispose_mapping(unsigned int virq) -{ -} - #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ #endif /* _ASM_OPENRISC_PROM_H */ diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 1919634..303703d 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -135,6 +135,7 @@ config PPC select HAVE_GENERIC_HARDIRQS select HAVE_SPARSE_IRQ select IRQ_PER_CPU + select IRQ_DOMAIN select GENERIC_IRQ_SHOW select GENERIC_IRQ_SHOW_LEVEL select IRQ_FORCED_THREADING diff --git a/arch/powerpc/include/asm/ehv_pic.h b/arch/powerpc/include/asm/ehv_pic.h index a9e1f4f..dc7d48e 100644 --- a/arch/powerpc/include/asm/ehv_pic.h +++ b/arch/powerpc/include/asm/ehv_pic.h @@ -25,7 +25,7 @@ struct ehv_pic { /* The remapper for this EHV_PIC */ - struct irq_host *irqhost; + struct irq_domain *irqhost; /* The "linux" controller struct */ struct irq_chip hc_irq; diff --git a/arch/powerpc/include/asm/i8259.h b/arch/powerpc/include/asm/i8259.h index 105ade2..c3fdfbd 100644 --- a/arch/powerpc/include/asm/i8259.h +++ b/arch/powerpc/include/asm/i8259.h @@ -6,7 +6,7 @@ extern void i8259_init(struct device_node *node, unsigned long intack_addr); extern unsigned int i8259_irq(void); -extern struct irq_host *i8259_get_host(void); +extern struct irq_domain *i8259_get_host(void); #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_I8259_H */ diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h index c0e1bc3..fe0b09d 100644 --- a/arch/powerpc/include/asm/irq.h +++ b/arch/powerpc/include/asm/irq.h @@ -9,6 +9,7 @@ * 2 of the License, or (at your option) any later version. */ +#include <linux/irqdomain.h> #include <linux/threads.h> #include <linux/list.h> #include <linux/radix-tree.h> @@ -35,258 +36,12 @@ extern atomic_t ppc_n_lost_interrupts; /* Total number of virq in the platform */ #define NR_IRQS CONFIG_NR_IRQS -/* Number of irqs reserved for the legacy controller */ -#define NUM_ISA_INTERRUPTS 16 - /* Same thing, used by the generic IRQ code */ #define NR_IRQS_LEGACY NUM_ISA_INTERRUPTS -/* This type is the placeholder for a hardware interrupt number. It has to - * be big enough to enclose whatever representation is used by a given - * platform. - */ -typedef unsigned long irq_hw_number_t; - -/* Interrupt controller "host" data structure. This could be defined as a - * irq domain controller. That is, it handles the mapping between hardware - * and virtual interrupt numbers for a given interrupt domain. The host - * structure is generally created by the PIC code for a given PIC instance - * (though a host can cover more than one PIC if they have a flat number - * model). It's the host callbacks that are responsible for setting the - * irq_chip on a given irq_desc after it's been mapped. - * - * The host code and data structures are fairly agnostic to the fact that - * we use an open firmware device-tree. We do have references to struct - * device_node in two places: in irq_find_host() to find the host matching - * a given interrupt controller node, and of course as an argument to its - * counterpart host->ops->match() callback. However, those are treated as - * generic pointers by the core and the fact that it's actually a device-node - * pointer is purely a convention between callers and implementation. This - * code could thus be used on other architectures by replacing those two - * by some sort of arch-specific void * "token" used to identify interrupt - * controllers. - */ -struct irq_host; -struct radix_tree_root; - -/* Functions below are provided by the host and called whenever a new mapping - * is created or an old mapping is disposed. The host can then proceed to - * whatever internal data structures management is required. It also needs - * to setup the irq_desc when returning from map(). - */ -struct irq_host_ops { - /* Match an interrupt controller device node to a host, returns - * 1 on a match - */ - int (*match)(struct irq_host *h, struct device_node *node); - - /* Create or update a mapping between a virtual irq number and a hw - * irq number. This is called only once for a given mapping. - */ - int (*map)(struct irq_host *h, unsigned int virq, irq_hw_number_t hw); - - /* Dispose of such a mapping */ - void (*unmap)(struct irq_host *h, unsigned int virq); - - /* Translate device-tree interrupt specifier from raw format coming - * from the firmware to a irq_hw_number_t (interrupt line number) and - * type (sense) that can be passed to set_irq_type(). In the absence - * of this callback, irq_create_of_mapping() and irq_of_parse_and_map() - * will return the hw number in the first cell and IRQ_TYPE_NONE for - * the type (which amount to keeping whatever default value the - * interrupt controller has for that line) - */ - int (*xlate)(struct irq_host *h, struct device_node *ctrler, - const u32 *intspec, unsigned int intsize, - irq_hw_number_t *out_hwirq, unsigned int *out_type); -}; - -struct irq_host { - struct list_head link; - - /* type of reverse mapping technique */ - unsigned int revmap_type; -#define IRQ_HOST_MAP_LEGACY 0 /* legacy 8259, gets irqs 1..15 */ -#define IRQ_HOST_MAP_NOMAP 1 /* no fast reverse mapping */ -#define IRQ_HOST_MAP_LINEAR 2 /* linear map of interrupts */ -#define IRQ_HOST_MAP_TREE 3 /* radix tree */ - union { - struct { - unsigned int size; - unsigned int *revmap; - } linear; - struct radix_tree_root tree; - } revmap_data; - struct irq_host_ops *ops; - void *host_data; - irq_hw_number_t inval_irq; - - /* Optional device node pointer */ - struct device_node *of_node; -}; - struct irq_data; extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d); extern irq_hw_number_t virq_to_hw(unsigned int virq); -extern bool virq_is_host(unsigned int virq, struct irq_host *host); - -/** - * irq_alloc_host - Allocate a new irq_host data structure - * @of_node: optional device-tree node of the interrupt controller - * @revmap_type: type of reverse mapping to use - * @revmap_arg: for IRQ_HOST_MAP_LINEAR linear only: size of the map - * @ops: map/unmap host callbacks - * @inval_irq: provide a hw number in that host space that is always invalid - * - * Allocates and initialize and irq_host structure. Note that in the case of - * IRQ_HOST_MAP_LEGACY, the map() callback will be called before this returns - * for all legacy interrupts except 0 (which is always the invalid irq for - * a legacy controller). For a IRQ_HOST_MAP_LINEAR, the map is allocated by - * this call as well. For a IRQ_HOST_MAP_TREE, the radix tree will be allocated - * later during boot automatically (the reverse mapping will use the slow path - * until that happens). - */ -extern struct irq_host *irq_alloc_host(struct device_node *of_node, - unsigned int revmap_type, - unsigned int revmap_arg, - struct irq_host_ops *ops, - irq_hw_number_t inval_irq); - - -/** - * irq_find_host - Locates a host for a given device node - * @node: device-tree node of the interrupt controller - */ -extern struct irq_host *irq_find_host(struct device_node *node); - - -/** - * irq_set_default_host - Set a "default" host - * @host: default host pointer - * - * For convenience, it's possible to set a "default" host that will be used - * whenever NULL is passed to irq_create_mapping(). It makes life easier for - * platforms that want to manipulate a few hard coded interrupt numbers that - * aren't properly represented in the device-tree. - */ -extern void irq_set_default_host(struct irq_host *host); - - -/** - * irq_set_virq_count - Set the maximum number of virt irqs - * @count: number of linux virtual irqs, capped with NR_IRQS - * - * This is mainly for use by platforms like iSeries who want to program - * the virtual irq number in the controller to avoid the reverse mapping - */ -extern void irq_set_virq_count(unsigned int count); - - -/** - * irq_create_mapping - Map a hardware interrupt into linux virq space - * @host: host owning this hardware interrupt or NULL for default host - * @hwirq: hardware irq number in that host space - * - * Only one mapping per hardware interrupt is permitted. Returns a linux - * virq number. - * If the sense/trigger is to be specified, set_irq_type() should be called - * on the number returned from that call. - */ -extern unsigned int irq_create_mapping(struct irq_host *host, - irq_hw_number_t hwirq); - - -/** - * irq_dispose_mapping - Unmap an interrupt - * @virq: linux virq number of the interrupt to unmap - */ -extern void irq_dispose_mapping(unsigned int virq); - -/** - * irq_find_mapping - Find a linux virq from an hw irq number. - * @host: host owning this hardware interrupt - * @hwirq: hardware irq number in that host space - * - * This is a slow path, for use by generic code. It's expected that an - * irq controller implementation directly calls the appropriate low level - * mapping function. - */ -extern unsigned int irq_find_mapping(struct irq_host *host, - irq_hw_number_t hwirq); - -/** - * irq_create_direct_mapping - Allocate a virq for direct mapping - * @host: host to allocate the virq for or NULL for default host - * - * This routine is used for irq controllers which can choose the hardware - * interrupt numbers they generate. In such a case it's simplest to use - * the linux virq as the hardware interrupt number. - */ -extern unsigned int irq_create_direct_mapping(struct irq_host *host); - -/** - * irq_radix_revmap_insert - Insert a hw irq to linux virq number mapping. - * @host: host owning this hardware interrupt - * @virq: linux irq number - * @hwirq: hardware irq number in that host space - * - * This is for use by irq controllers that use a radix tree reverse - * mapping for fast lookup. - */ -extern void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq, - irq_hw_number_t hwirq); - -/** - * irq_radix_revmap_lookup - Find a linux virq from a hw irq number. - * @host: host owning this hardware interrupt - * @hwirq: hardware irq number in that host space - * - * This is a fast path, for use by irq controller code that uses radix tree - * revmaps - */ -extern unsigned int irq_radix_revmap_lookup(struct irq_host *host, - irq_hw_number_t hwirq); - -/** - * irq_linear_revmap - Find a linux virq from a hw irq number. - * @host: host owning this hardware interrupt - * @hwirq: hardware irq number in that host space - * - * This is a fast path, for use by irq controller code that uses linear - * revmaps. It does fallback to the slow path if the revmap doesn't exist - * yet and will create the revmap entry with appropriate locking - */ - -extern unsigned int irq_linear_revmap(struct irq_host *host, - irq_hw_number_t hwirq); - - - -/** - * irq_alloc_virt - Allocate virtual irq numbers - * @host: host owning these new virtual irqs - * @count: number of consecutive numbers to allocate - * @hint: pass a hint number, the allocator will try to use a 1:1 mapping - * - * This is a low level function that is used internally by irq_create_mapping() - * and that can be used by some irq controllers implementations for things - * like allocating ranges of numbers for MSIs. The revmaps are left untouched. - */ -extern unsigned int irq_alloc_virt(struct irq_host *host, - unsigned int count, - unsigned int hint); - -/** - * irq_free_virt - Free virtual irq numbers - * @virq: virtual irq number of the first interrupt to free - * @count: number of interrupts to free - * - * This function is the opposite of irq_alloc_virt. It will not clear reverse - * maps, this should be done previously by unmap'ing the interrupt. In fact, - * all interrupts covered by the range being freed should have been unmapped - * prior to calling this. - */ -extern void irq_free_virt(unsigned int virq, unsigned int count); /** * irq_early_init - Init irq remapping subsystem diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h index 67b4d98..a5b7c56 100644 --- a/arch/powerpc/include/asm/mpic.h +++ b/arch/powerpc/include/asm/mpic.h @@ -255,7 +255,7 @@ struct mpic struct device_node *node; /* The remapper for this MPIC */ - struct irq_host *irqhost; + struct irq_domain *irqhost; /* The "linux" controller struct */ struct irq_chip hc_irq; diff --git a/arch/powerpc/include/asm/xics.h b/arch/powerpc/include/asm/xics.h index c48de98..4ae9a09 100644 --- a/arch/powerpc/include/asm/xics.h +++ b/arch/powerpc/include/asm/xics.h @@ -86,7 +86,7 @@ struct ics { extern unsigned int xics_default_server; extern unsigned int xics_default_distrib_server; extern unsigned int xics_interrupt_server_size; -extern struct irq_host *xics_host; +extern struct irq_domain *xics_host; struct xics_cppr { unsigned char stack[MAX_NUM_PRIORITIES]; diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 01e2877..bdfb3eee 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -490,409 +490,19 @@ void do_softirq(void) local_irq_restore(flags); } - -/* - * IRQ controller and virtual interrupts - */ - -/* The main irq map itself is an array of NR_IRQ entries containing the - * associate host and irq number. An entry with a host of NULL is free. - * An entry can be allocated if it's free, the allocator always then sets - * hwirq first to the host's invalid irq number and then fills ops. - */ -struct irq_map_entry { - irq_hw_number_t hwirq; - struct irq_host *host; -}; - -static LIST_HEAD(irq_hosts); -static DEFINE_RAW_SPINLOCK(irq_big_lock); -static DEFINE_MUTEX(revmap_trees_mutex); -static struct irq_map_entry irq_map[NR_IRQS]; -static unsigned int irq_virq_count = NR_IRQS; -static struct irq_host *irq_default_host; - irq_hw_number_t irqd_to_hwirq(struct irq_data *d) { - return irq_map[d->irq].hwirq; + return d->hwirq; } EXPORT_SYMBOL_GPL(irqd_to_hwirq); irq_hw_number_t virq_to_hw(unsigned int virq) { - return irq_map[virq].hwirq; + struct irq_data *irq_data = irq_get_irq_data(virq); + return WARN_ON(!irq_data) ? 0 : irq_data->hwirq; } EXPORT_SYMBOL_GPL(virq_to_hw); -bool virq_is_host(unsigned int virq, struct irq_host *host) -{ - return irq_map[virq].host == host; -} -EXPORT_SYMBOL_GPL(virq_is_host); - -static int default_irq_host_match(struct irq_host *h, struct device_node *np) -{ - return h->of_node != NULL && h->of_node == np; -} - -struct irq_host *irq_alloc_host(struct device_node *of_node, - unsigned int revmap_type, - unsigned int revmap_arg, - struct irq_host_ops *ops, - irq_hw_number_t inval_irq) -{ - struct irq_host *host; - unsigned int size = sizeof(struct irq_host); - unsigned int i; - unsigned int *rmap; - unsigned long flags; - - /* Allocate structure and revmap table if using linear mapping */ - if (revmap_type == IRQ_HOST_MAP_LINEAR) - size += revmap_arg * sizeof(unsigned int); - host = kzalloc(size, GFP_KERNEL); - if (host == NULL) - return NULL; - - /* Fill structure */ - host->revmap_type = revmap_type; - host->inval_irq = inval_irq; - host->ops = ops; - host->of_node = of_node_get(of_node); - - if (host->ops->match == NULL) - host->ops->match = default_irq_host_match; - - raw_spin_lock_irqsave(&irq_big_lock, flags); - - /* If it's a legacy controller, check for duplicates and - * mark it as allocated (we use irq 0 host pointer for that - */ - if (revmap_type == IRQ_HOST_MAP_LEGACY) { - if (irq_map[0].host != NULL) { - raw_spin_unlock_irqrestore(&irq_big_lock, flags); - of_node_put(host->of_node); - kfree(host); - return NULL; - } - irq_map[0].host = host; - } - - list_add(&host->link, &irq_hosts); - raw_spin_unlock_irqrestore(&irq_big_lock, flags); - - /* Additional setups per revmap type */ - switch(revmap_type) { - case IRQ_HOST_MAP_LEGACY: - /* 0 is always the invalid number for legacy */ - host->inval_irq = 0; - /* setup us as the host for all legacy interrupts */ - for (i = 1; i < NUM_ISA_INTERRUPTS; i++) { - irq_map[i].hwirq = i; - smp_wmb(); - irq_map[i].host = host; - smp_wmb(); - - /* Legacy flags are left to default at this point, - * one can then use irq_create_mapping() to - * explicitly change them - */ - ops->map(host, i, i); - - /* Clear norequest flags */ - irq_clear_status_flags(i, IRQ_NOREQUEST); - } - break; - case IRQ_HOST_MAP_LINEAR: - rmap = (unsigned int *)(host + 1); - for (i = 0; i < revmap_arg; i++) - rmap[i] = NO_IRQ; - host->revmap_data.linear.size = revmap_arg; - smp_wmb(); - host->revmap_data.linear.revmap = rmap; - break; - case IRQ_HOST_MAP_TREE: - INIT_RADIX_TREE(&host->revmap_data.tree, GFP_KERNEL); - break; - default: - break; - } - - pr_debug("irq: Allocated host of type %d @0x%p\n", revmap_type, host); - - return host; -} - -struct irq_host *irq_find_host(struct device_node *node) -{ - struct irq_host *h, *found = NULL; - unsigned long flags; - - /* We might want to match the legacy controller last since - * it might potentially be set to match all interrupts in - * the absence of a device node. This isn't a problem so far - * yet though... - */ - raw_spin_lock_irqsave(&irq_big_lock, flags); - list_for_each_entry(h, &irq_hosts, link) - if (h->ops->match(h, node)) { - found = h; - break; - } - raw_spin_unlock_irqrestore(&irq_big_lock, flags); - return found; -} -EXPORT_SYMBOL_GPL(irq_find_host); - -void irq_set_default_host(struct irq_host *host) -{ - pr_debug("irq: Default host set to @0x%p\n", host); - - irq_default_host = host; -} - -void irq_set_virq_count(unsigned int count) -{ - pr_debug("irq: Trying to set virq count to %d\n", count); - - BUG_ON(count < NUM_ISA_INTERRUPTS); - if (count < NR_IRQS) - irq_virq_count = count; -} - -static int irq_setup_virq(struct irq_host *host, unsigned int virq, - irq_hw_number_t hwirq) -{ - int res; - - res = irq_alloc_desc_at(virq, 0); - if (res != virq) { - pr_debug("irq: -> allocating desc failed\n"); - goto error; - } - - /* map it */ - smp_wmb(); - irq_map[virq].hwirq = hwirq; - smp_mb(); - - if (host->ops->map(host, virq, hwirq)) { - pr_debug("irq: -> mapping failed, freeing\n"); - goto errdesc; - } - - irq_clear_status_flags(virq, IRQ_NOREQUEST); - - return 0; - -errdesc: - irq_free_descs(virq, 1); -error: - irq_free_virt(virq, 1); - return -1; -} - -unsigned int irq_create_direct_mapping(struct irq_host *host) -{ - unsigned int virq; - - if (host == NULL) - host = irq_default_host; - - BUG_ON(host == NULL); - WARN_ON(host->revmap_type != IRQ_HOST_MAP_NOMAP); - - virq = irq_alloc_virt(host, 1, 0); - if (virq == NO_IRQ) { - pr_debug("irq: create_direct virq allocation failed\n"); - return NO_IRQ; - } - - pr_debug("irq: create_direct obtained virq %d\n", virq); - - if (irq_setup_virq(host, virq, virq)) - return NO_IRQ; - - return virq; -} - -unsigned int irq_create_mapping(struct irq_host *host, - irq_hw_number_t hwirq) -{ - unsigned int virq, hint; - - pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", host, hwirq); - - /* Look for default host if nececssary */ - if (host == NULL) - host = irq_default_host; - if (host == NULL) { - printk(KERN_WARNING "irq_create_mapping called for" - " NULL host, hwirq=%lx\n", hwirq); - WARN_ON(1); - return NO_IRQ; - } - pr_debug("irq: -> using host @%p\n", host); - - /* Check if mapping already exists */ - virq = irq_find_mapping(host, hwirq); - if (virq != NO_IRQ) { - pr_debug("irq: -> existing mapping on virq %d\n", virq); - return virq; - } - - /* Get a virtual interrupt number */ - if (host->revmap_type == IRQ_HOST_MAP_LEGACY) { - /* Handle legacy */ - virq = (unsigned int)hwirq; - if (virq == 0 || virq >= NUM_ISA_INTERRUPTS) - return NO_IRQ; - return virq; - } else { - /* Allocate a virtual interrupt number */ - hint = hwirq % irq_virq_count; - virq = irq_alloc_virt(host, 1, hint); - if (virq == NO_IRQ) { - pr_debug("irq: -> virq allocation failed\n"); - return NO_IRQ; - } - } - - if (irq_setup_virq(host, virq, hwirq)) - return NO_IRQ; - - pr_debug("irq: irq %lu on host %s mapped to virtual irq %u\n", - hwirq, host->of_node ? host->of_node->full_name : "null", virq); - - return virq; -} -EXPORT_SYMBOL_GPL(irq_create_mapping); - -unsigned int irq_create_of_mapping(struct device_node *controller, - const u32 *intspec, unsigned int intsize) -{ - struct irq_host *host; - irq_hw_number_t hwirq; - unsigned int type = IRQ_TYPE_NONE; - unsigned int virq; - - if (controller == NULL) - host = irq_default_host; - else - host = irq_find_host(controller); - if (host == NULL) { - printk(KERN_WARNING "irq: no irq host found for %s !\n", - controller->full_name); - return NO_IRQ; - } - - /* If host has no translation, then we assume interrupt line */ - if (host->ops->xlate == NULL) - hwirq = intspec[0]; - else { - if (host->ops->xlate(host, controller, intspec, intsize, - &hwirq, &type)) - return NO_IRQ; - } - - /* Create mapping */ - virq = irq_create_mapping(host, hwirq); - if (virq == NO_IRQ) - return virq; - - /* Set type if specified and different than the current one */ - if (type != IRQ_TYPE_NONE && - type != (irqd_get_trigger_type(irq_get_irq_data(virq)))) - irq_set_irq_type(virq, type); - return virq; -} -EXPORT_SYMBOL_GPL(irq_create_of_mapping); - -void irq_dispose_mapping(unsigned int virq) -{ - struct irq_host *host; - irq_hw_number_t hwirq; - - if (virq == NO_IRQ) - return; - - host = irq_map[virq].host; - if (WARN_ON(host == NULL)) - return; - - /* Never unmap legacy interrupts */ - if (host->revmap_type == IRQ_HOST_MAP_LEGACY) - return; - - irq_set_status_flags(virq, IRQ_NOREQUEST); - - /* remove chip and handler */ - irq_set_chip_and_handler(virq, NULL, NULL); - - /* Make sure it's completed */ - synchronize_irq(virq); - - /* Tell the PIC about it */ - if (host->ops->unmap) - host->ops->unmap(host, virq); - smp_mb(); - - /* Clear reverse map */ - hwirq = irq_map[virq].hwirq; - switch(host->revmap_type) { - case IRQ_HOST_MAP_LINEAR: - if (hwirq < host->revmap_data.linear.size) - host->revmap_data.linear.revmap[hwirq] = NO_IRQ; - break; - case IRQ_HOST_MAP_TREE: - mutex_lock(&revmap_trees_mutex); - radix_tree_delete(&host->revmap_data.tree, hwirq); - mutex_unlock(&revmap_trees_mutex); - break; - } - - /* Destroy map */ - smp_mb(); - irq_map[virq].hwirq = host->inval_irq; - - irq_free_descs(virq, 1); - /* Free it */ - irq_free_virt(virq, 1); -} -EXPORT_SYMBOL_GPL(irq_dispose_mapping); - -unsigned int irq_find_mapping(struct irq_host *host, - irq_hw_number_t hwirq) -{ - unsigned int i; - unsigned int hint = hwirq % irq_virq_count; - - /* Look for default host if nececssary */ - if (host == NULL) - host = irq_default_host; - if (host == NULL) - return NO_IRQ; - - /* legacy -> bail early */ - if (host->revmap_type == IRQ_HOST_MAP_LEGACY) - return hwirq; - - /* Slow path does a linear search of the map */ - if (hint < NUM_ISA_INTERRUPTS) - hint = NUM_ISA_INTERRUPTS; - i = hint; - do { - if (irq_map[i].host == host && - irq_map[i].hwirq == hwirq) - return i; - i++; - if (i >= irq_virq_count) - i = NUM_ISA_INTERRUPTS; - } while(i != hint); - return NO_IRQ; -} -EXPORT_SYMBOL_GPL(irq_find_mapping); - #ifdef CONFIG_SMP int irq_choose_cpu(const struct cpumask *mask) { @@ -929,232 +539,11 @@ int irq_choose_cpu(const struct cpumask *mask) } #endif -unsigned int irq_radix_revmap_lookup(struct irq_host *host, - irq_hw_number_t hwirq) -{ - struct irq_map_entry *ptr; - unsigned int virq; - - if (WARN_ON_ONCE(host->revmap_type != IRQ_HOST_MAP_TREE)) - return irq_find_mapping(host, hwirq); - - /* - * The ptr returned references the static global irq_map. - * but freeing an irq can delete nodes along the path to - * do the lookup via call_rcu. - */ - rcu_read_lock(); - ptr = radix_tree_lookup(&host->revmap_data.tree, hwirq); - rcu_read_unlock(); - - /* - * If found in radix tree, then fine. - * Else fallback to linear lookup - this should not happen in practice - * as it means that we failed to insert the node in the radix tree. - */ - if (ptr) - virq = ptr - irq_map; - else - virq = irq_find_mapping(host, hwirq); - - return virq; -} - -void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq, - irq_hw_number_t hwirq) -{ - if (WARN_ON(host->revmap_type != IRQ_HOST_MAP_TREE)) - return; - - if (virq != NO_IRQ) { - mutex_lock(&revmap_trees_mutex); - radix_tree_insert(&host->revmap_data.tree, hwirq, - &irq_map[virq]); - mutex_unlock(&revmap_trees_mutex); - } -} - -unsigned int irq_linear_revmap(struct irq_host *host, - irq_hw_number_t hwirq) -{ - unsigned int *revmap; - - if (WARN_ON_ONCE(host->revmap_type != IRQ_HOST_MAP_LINEAR)) - return irq_find_mapping(host, hwirq); - - /* Check revmap bounds */ - if (unlikely(hwirq >= host->revmap_data.linear.size)) - return irq_find_mapping(host, hwirq); - - /* Check if revmap was allocated */ - revmap = host->revmap_data.linear.revmap; - if (unlikely(revmap == NULL)) - return irq_find_mapping(host, hwirq); - - /* Fill up revmap with slow path if no mapping found */ - if (unlikely(revmap[hwirq] == NO_IRQ)) - revmap[hwirq] = irq_find_mapping(host, hwirq); - - return revmap[hwirq]; -} - -unsigned int irq_alloc_virt(struct irq_host *host, - unsigned int count, - unsigned int hint) -{ - unsigned long flags; - unsigned int i, j, found = NO_IRQ; - - if (count == 0 || count > (irq_virq_count - NUM_ISA_INTERRUPTS)) - return NO_IRQ; - - raw_spin_lock_irqsave(&irq_big_lock, flags); - - /* Use hint for 1 interrupt if any */ - if (count == 1 && hint >= NUM_ISA_INTERRUPTS && - hint < irq_virq_count && irq_map[hint].host == NULL) { - found = hint; - goto hint_found; - } - - /* Look for count consecutive numbers in the allocatable - * (non-legacy) space - */ - for (i = NUM_ISA_INTERRUPTS, j = 0; i < irq_virq_count; i++) { - if (irq_map[i].host != NULL) - j = 0; - else - j++; - - if (j == count) { - found = i - count + 1; - break; - } - } - if (found == NO_IRQ) { - raw_spin_unlock_irqrestore(&irq_big_lock, flags); - return NO_IRQ; - } - hint_found: - for (i = found; i < (found + count); i++) { - irq_map[i].hwirq = host->inval_irq; - smp_wmb(); - irq_map[i].host = host; - } - raw_spin_unlock_irqrestore(&irq_big_lock, flags); - return found; -} - -void irq_free_virt(unsigned int virq, unsigned int count) -{ - unsigned long flags; - unsigned int i; - - WARN_ON (virq < NUM_ISA_INTERRUPTS); - WARN_ON (count == 0 || (virq + count) > irq_virq_count); - - if (virq < NUM_ISA_INTERRUPTS) { - if (virq + count < NUM_ISA_INTERRUPTS) - return; - count =- NUM_ISA_INTERRUPTS - virq; - virq = NUM_ISA_INTERRUPTS; - } - - if (count > irq_virq_count || virq > irq_virq_count - count) { - if (virq > irq_virq_count) - return; - count = irq_virq_count - virq; - } - - raw_spin_lock_irqsave(&irq_big_lock, flags); - for (i = virq; i < (virq + count); i++) { - struct irq_host *host; - - host = irq_map[i].host; - irq_map[i].hwirq = host->inval_irq; - smp_wmb(); - irq_map[i].host = NULL; - } - raw_spin_unlock_irqrestore(&irq_big_lock, flags); -} - int arch_early_irq_init(void) { return 0; } -#ifdef CONFIG_VIRQ_DEBUG -static int virq_debug_show(struct seq_file *m, void *private) -{ - unsigned long flags; - struct irq_desc *desc; - const char *p; - static const char none[] = "none"; - void *data; - int i; - - seq_printf(m, "%-5s %-7s %-15s %-18s %s\n", "virq", "hwirq", - "chip name", "chip data", "host name"); - - for (i = 1; i < nr_irqs; i++) { - desc = irq_to_desc(i); - if (!desc) - continue; - - raw_spin_lock_irqsave(&desc->lock, flags); - - if (desc->action && desc->action->handler) { - struct irq_chip *chip; - - seq_printf(m, "%5d ", i); - seq_printf(m, "0x%05lx ", irq_map[i].hwirq); - - chip = irq_desc_get_chip(desc); - if (chip && chip->name) - p = chip->name; - else - p = none; - seq_printf(m, "%-15s ", p); - - data = irq_desc_get_chip_data(desc); - seq_printf(m, "0x%16p ", data); - - if (irq_map[i].host && irq_map[i].host->of_node) - p = irq_map[i].host->of_node->full_name; - else - p = none; - seq_printf(m, "%s\n", p); - } - - raw_spin_unlock_irqrestore(&desc->lock, flags); - } - - return 0; -} - -static int virq_debug_open(struct inode *inode, struct file *file) -{ - return single_open(file, virq_debug_show, inode->i_private); -} - -static const struct file_operations virq_debug_fops = { - .open = virq_debug_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int __init irq_debugfs_init(void) -{ - if (debugfs_create_file("virq_mapping", S_IRUGO, powerpc_debugfs_root, - NULL, &virq_debug_fops) == NULL) - return -ENOMEM; - - return 0; -} -__initcall(irq_debugfs_init); -#endif /* CONFIG_VIRQ_DEBUG */ - #ifdef CONFIG_PPC64 static int __init setup_noirqdistrib(char *str) { diff --git a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c index 9f09319..ca3a062 100644 --- a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c +++ b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c @@ -21,7 +21,7 @@ #include <asm/prom.h> static struct device_node *cpld_pic_node; -static struct irq_host *cpld_pic_host; +static struct irq_domain *cpld_pic_host; /* * Bits to ignore in the misc_status register @@ -123,13 +123,13 @@ cpld_pic_cascade(unsigned int irq, struct irq_desc *desc) } static int -cpld_pic_host_match(struct irq_host *h, struct device_node *node) +cpld_pic_host_match(struct irq_domain *h, struct device_node *node) { return cpld_pic_node == node; } static int -cpld_pic_host_map(struct irq_host *h, unsigned int virq, +cpld_pic_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { irq_set_status_flags(virq, IRQ_LEVEL); @@ -137,8 +137,7 @@ cpld_pic_host_map(struct irq_host *h, unsigned int virq, return 0; } -static struct -irq_host_ops cpld_pic_host_ops = { +static const struct irq_domain_ops cpld_pic_host_ops = { .match = cpld_pic_host_match, .map = cpld_pic_host_map, }; @@ -191,8 +190,7 @@ mpc5121_ads_cpld_pic_init(void) cpld_pic_node = of_node_get(np); - cpld_pic_host = - irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, 16, &cpld_pic_host_ops, 16); + cpld_pic_host = irq_domain_add_linear(np, 16, &cpld_pic_host_ops, NULL); if (!cpld_pic_host) { printk(KERN_ERR "CPLD PIC: failed to allocate irq host!\n"); goto end; diff --git a/arch/powerpc/platforms/52xx/media5200.c b/arch/powerpc/platforms/52xx/media5200.c index 96f85e5..17d91b7 100644 --- a/arch/powerpc/platforms/52xx/media5200.c +++ b/arch/powerpc/platforms/52xx/media5200.c @@ -45,7 +45,7 @@ static struct of_device_id mpc5200_gpio_ids[] __initdata = { struct media5200_irq { void __iomem *regs; spinlock_t lock; - struct irq_host *irqhost; + struct irq_domain *irqhost; }; struct media5200_irq media5200_irq; @@ -112,7 +112,7 @@ void media5200_irq_cascade(unsigned int virq, struct irq_desc *desc) raw_spin_unlock(&desc->lock); } -static int media5200_irq_map(struct irq_host *h, unsigned int virq, +static int media5200_irq_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { pr_debug("%s: h=%p, virq=%i, hwirq=%i\n", __func__, h, virq, (int)hw); @@ -122,7 +122,7 @@ static int media5200_irq_map(struct irq_host *h, unsigned int virq, return 0; } -static int media5200_irq_xlate(struct irq_host *h, struct device_node *ct, +static int media5200_irq_xlate(struct irq_domain *h, struct device_node *ct, const u32 *intspec, unsigned int intsize, irq_hw_number_t *out_hwirq, unsigned int *out_flags) @@ -136,7 +136,7 @@ static int media5200_irq_xlate(struct irq_host *h, struct device_node *ct, return 0; } -static struct irq_host_ops media5200_irq_ops = { +static const struct irq_domain_ops media5200_irq_ops = { .map = media5200_irq_map, .xlate = media5200_irq_xlate, }; @@ -173,15 +173,12 @@ static void __init media5200_init_irq(void) spin_lock_init(&media5200_irq.lock); - media5200_irq.irqhost = irq_alloc_host(fpga_np, IRQ_HOST_MAP_LINEAR, - MEDIA5200_NUM_IRQS, - &media5200_irq_ops, -1); + media5200_irq.irqhost = irq_domain_add_linear(fpga_np, + MEDIA5200_NUM_IRQS, &media5200_irq_ops, &media5200_irq); if (!media5200_irq.irqhost) goto out; pr_debug("%s: allocated irqhost\n", __func__); - media5200_irq.irqhost->host_data = &media5200_irq; - irq_set_handler_data(cascade_virq, &media5200_irq); irq_set_chained_handler(cascade_virq, media5200_irq_cascade); diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c index f94f06e..028470b 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c @@ -81,7 +81,7 @@ MODULE_LICENSE("GPL"); * @regs: virtual address of GPT registers * @lock: spinlock to coordinate between different functions. * @gc: gpio_chip instance structure; used when GPIO is enabled - * @irqhost: Pointer to irq_host instance; used when IRQ mode is supported + * @irqhost: Pointer to irq_domain instance; used when IRQ mode is supported * @wdt_mode: only relevant for gpt0: bit 0 (MPC52xx_GPT_CAN_WDT) indicates * if the gpt may be used as wdt, bit 1 (MPC52xx_GPT_IS_WDT) indicates * if the timer is actively used as wdt which blocks gpt functions @@ -91,7 +91,7 @@ struct mpc52xx_gpt_priv { struct device *dev; struct mpc52xx_gpt __iomem *regs; spinlock_t lock; - struct irq_host *irqhost; + struct irq_domain *irqhost; u32 ipb_freq; u8 wdt_mode; @@ -204,7 +204,7 @@ void mpc52xx_gpt_irq_cascade(unsigned int virq, struct irq_desc *desc) } } -static int mpc52xx_gpt_irq_map(struct irq_host *h, unsigned int virq, +static int mpc52xx_gpt_irq_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { struct mpc52xx_gpt_priv *gpt = h->host_data; @@ -216,7 +216,7 @@ static int mpc52xx_gpt_irq_map(struct irq_host *h, unsigned int virq, return 0; } -static int mpc52xx_gpt_irq_xlate(struct irq_host *h, struct device_node *ct, +static int mpc52xx_gpt_irq_xlate(struct irq_domain *h, struct device_node *ct, const u32 *intspec, unsigned int intsize, irq_hw_number_t *out_hwirq, unsigned int *out_flags) @@ -236,7 +236,7 @@ static int mpc52xx_gpt_irq_xlate(struct irq_host *h, struct device_node *ct, return 0; } -static struct irq_host_ops mpc52xx_gpt_irq_ops = { +static const struct irq_domain_ops mpc52xx_gpt_irq_ops = { .map = mpc52xx_gpt_irq_map, .xlate = mpc52xx_gpt_irq_xlate, }; @@ -252,14 +252,12 @@ mpc52xx_gpt_irq_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node) if (!cascade_virq) return; - gpt->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR, 1, - &mpc52xx_gpt_irq_ops, -1); + gpt->irqhost = irq_domain_add_linear(node, 1, &mpc52xx_gpt_irq_ops, gpt); if (!gpt->irqhost) { - dev_err(gpt->dev, "irq_alloc_host() failed\n"); + dev_err(gpt->dev, "irq_domain_add_linear() failed\n"); return; } - gpt->irqhost->host_data = gpt; irq_set_handler_data(cascade_virq, gpt); irq_set_chained_handler(cascade_virq, mpc52xx_gpt_irq_cascade); diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c index 1a9a495..8520b58 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c @@ -132,7 +132,7 @@ static struct of_device_id mpc52xx_sdma_ids[] __initdata = { static struct mpc52xx_intr __iomem *intr; static struct mpc52xx_sdma __iomem *sdma; -static struct irq_host *mpc52xx_irqhost = NULL; +static struct irq_domain *mpc52xx_irqhost = NULL; static unsigned char mpc52xx_map_senses[4] = { IRQ_TYPE_LEVEL_HIGH, @@ -301,7 +301,7 @@ static int mpc52xx_is_extirq(int l1, int l2) /** * mpc52xx_irqhost_xlate - translate virq# from device tree interrupts property */ -static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct, +static int mpc52xx_irqhost_xlate(struct irq_domain *h, struct device_node *ct, const u32 *intspec, unsigned int intsize, irq_hw_number_t *out_hwirq, unsigned int *out_flags) @@ -335,7 +335,7 @@ static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct, /** * mpc52xx_irqhost_map - Hook to map from virq to an irq_chip structure */ -static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq, +static int mpc52xx_irqhost_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t irq) { int l1irq; @@ -384,7 +384,7 @@ static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq, return 0; } -static struct irq_host_ops mpc52xx_irqhost_ops = { +static const struct irq_domain_ops mpc52xx_irqhost_ops = { .xlate = mpc52xx_irqhost_xlate, .map = mpc52xx_irqhost_map, }; @@ -444,9 +444,9 @@ void __init mpc52xx_init_irq(void) * As last step, add an irq host to translate the real * hw irq information provided by the ofw to linux virq */ - mpc52xx_irqhost = irq_alloc_host(picnode, IRQ_HOST_MAP_LINEAR, + mpc52xx_irqhost = irq_domain_add_linear(picnode, MPC52xx_IRQ_HIGHTESTHWIRQ, - &mpc52xx_irqhost_ops, -1); + &mpc52xx_irqhost_ops, NULL); if (!mpc52xx_irqhost) panic(__FILE__ ": Cannot allocate the IRQ host\n"); diff --git a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c index 8ccf9ed..328d221 100644 --- a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c +++ b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c @@ -29,7 +29,7 @@ static DEFINE_RAW_SPINLOCK(pci_pic_lock); struct pq2ads_pci_pic { struct device_node *node; - struct irq_host *host; + struct irq_domain *host; struct { u32 stat; @@ -103,7 +103,7 @@ static void pq2ads_pci_irq_demux(unsigned int irq, struct irq_desc *desc) } } -static int pci_pic_host_map(struct irq_host *h, unsigned int virq, +static int pci_pic_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { irq_set_status_flags(virq, IRQ_LEVEL); @@ -112,14 +112,14 @@ static int pci_pic_host_map(struct irq_host *h, unsigned int virq, return 0; } -static struct irq_host_ops pci_pic_host_ops = { +static const struct irq_domain_ops pci_pic_host_ops = { .map = pci_pic_host_map, }; int __init pq2ads_pci_init_irq(void) { struct pq2ads_pci_pic *priv; - struct irq_host *host; + struct irq_domain *host; struct device_node *np; int ret = -ENODEV; int irq; @@ -156,17 +156,13 @@ int __init pq2ads_pci_init_irq(void) out_be32(&priv->regs->mask, ~0); mb(); - host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, NUM_IRQS, - &pci_pic_host_ops, NUM_IRQS); + host = irq_domain_add_linear(np, NUM_IRQS, &pci_pic_host_ops, priv); if (!host) { ret = -ENOMEM; goto out_unmap_regs; } - host->host_data = priv; - priv->host = host; - host->host_data = priv; irq_set_handler_data(irq, priv); irq_set_chained_handler(irq, pq2ads_pci_irq_demux); diff --git a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c index 12cb9bb..3bbbf74 100644 --- a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c +++ b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c @@ -51,7 +51,7 @@ static struct socrates_fpga_irq_info fpga_irqs[SOCRATES_FPGA_NUM_IRQS] = { static DEFINE_RAW_SPINLOCK(socrates_fpga_pic_lock); static void __iomem *socrates_fpga_pic_iobase; -static struct irq_host *socrates_fpga_pic_irq_host; +static struct irq_domain *socrates_fpga_pic_irq_host; static unsigned int socrates_fpga_irqs[3]; static inline uint32_t socrates_fpga_pic_read(int reg) @@ -227,7 +227,7 @@ static struct irq_chip socrates_fpga_pic_chip = { .irq_set_type = socrates_fpga_pic_set_type, }; -static int socrates_fpga_pic_host_map(struct irq_host *h, unsigned int virq, +static int socrates_fpga_pic_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hwirq) { /* All interrupts are LEVEL sensitive */ @@ -238,7 +238,7 @@ static int socrates_fpga_pic_host_map(struct irq_host *h, unsigned int virq, return 0; } -static int socrates_fpga_pic_host_xlate(struct irq_host *h, +static int socrates_fpga_pic_host_xlate(struct irq_domain *h, struct device_node *ct, const u32 *intspec, unsigned int intsize, irq_hw_number_t *out_hwirq, unsigned int *out_flags) { @@ -269,7 +269,7 @@ static int socrates_fpga_pic_host_xlate(struct irq_host *h, return 0; } -static struct irq_host_ops socrates_fpga_pic_host_ops = { +static const struct irq_domain_ops socrates_fpga_pic_host_ops = { .map = socrates_fpga_pic_host_map, .xlate = socrates_fpga_pic_host_xlate, }; @@ -279,10 +279,9 @@ void socrates_fpga_pic_init(struct device_node *pic) unsigned long flags; int i; - /* Setup an irq_host structure */ - socrates_fpga_pic_irq_host = irq_alloc_host(pic, IRQ_HOST_MAP_LINEAR, - SOCRATES_FPGA_NUM_IRQS, &socrates_fpga_pic_host_ops, - SOCRATES_FPGA_NUM_IRQS); + /* Setup an irq_domain structure */ + socrates_fpga_pic_irq_host = irq_domain_add_linear(pic, + SOCRATES_FPGA_NUM_IRQS, &socrates_fpga_pic_host_ops, NULL); if (socrates_fpga_pic_irq_host == NULL) { pr_err("FPGA PIC: Unable to allocate host\n"); return; diff --git a/arch/powerpc/platforms/86xx/gef_pic.c b/arch/powerpc/platforms/86xx/gef_pic.c index 94594e5..af3fd69 100644 --- a/arch/powerpc/platforms/86xx/gef_pic.c +++ b/arch/powerpc/platforms/86xx/gef_pic.c @@ -50,7 +50,7 @@ static DEFINE_RAW_SPINLOCK(gef_pic_lock); static void __iomem *gef_pic_irq_reg_base; -static struct irq_host *gef_pic_irq_host; +static struct irq_domain *gef_pic_irq_host; static int gef_pic_cascade_irq; /* @@ -153,7 +153,7 @@ static struct irq_chip gef_pic_chip = { /* When an interrupt is being configured, this call allows some flexibilty * in deciding which irq_chip structure is used */ -static int gef_pic_host_map(struct irq_host *h, unsigned int virq, +static int gef_pic_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hwirq) { /* All interrupts are LEVEL sensitive */ @@ -163,7 +163,7 @@ static int gef_pic_host_map(struct irq_host *h, unsigned int virq, return 0; } -static int gef_pic_host_xlate(struct irq_host *h, struct device_node *ct, +static int gef_pic_host_xlate(struct irq_domain *h, struct device_node *ct, const u32 *intspec, unsigned int intsize, irq_hw_number_t *out_hwirq, unsigned int *out_flags) { @@ -177,7 +177,7 @@ static int gef_pic_host_xlate(struct irq_host *h, struct device_node *ct, return 0; } -static struct irq_host_ops gef_pic_host_ops = { +static const struct irq_domain_ops gef_pic_host_ops = { .map = gef_pic_host_map, .xlate = gef_pic_host_xlate, }; @@ -211,10 +211,9 @@ void __init gef_pic_init(struct device_node *np) return; } - /* Setup an irq_host structure */ - gef_pic_irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, - GEF_PIC_NUM_IRQS, - &gef_pic_host_ops, NO_IRQ); + /* Setup an irq_domain structure */ + gef_pic_irq_host = irq_domain_add_linear(np, GEF_PIC_NUM_IRQS, + &gef_pic_host_ops, NULL); if (gef_pic_irq_host == NULL) return; diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c index 40a6e34..db360fc 100644 --- a/arch/powerpc/platforms/cell/axon_msi.c +++ b/arch/powerpc/platforms/cell/axon_msi.c @@ -67,7 +67,7 @@ struct axon_msic { - struct irq_host *irq_host; + struct irq_domain *irq_domain; __le32 *fifo_virt; dma_addr_t fifo_phys; dcr_host_t dcr_host; @@ -152,7 +152,7 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc) static struct axon_msic *find_msi_translator(struct pci_dev *dev) { - struct irq_host *irq_host; + struct irq_domain *irq_domain; struct device_node *dn, *tmp; const phandle *ph; struct axon_msic *msic = NULL; @@ -184,14 +184,14 @@ static struct axon_msic *find_msi_translator(struct pci_dev *dev) goto out_error; } - irq_host = irq_find_host(dn); - if (!irq_host) { - dev_dbg(&dev->dev, "axon_msi: no irq_host found for node %s\n", + irq_domain = irq_find_host(dn); + if (!irq_domain) { + dev_dbg(&dev->dev, "axon_msi: no irq_domain found for node %s\n", dn->full_name); goto out_error; } - msic = irq_host->host_data; + msic = irq_domain->host_data; out_error: of_node_put(dn); @@ -280,7 +280,7 @@ static int axon_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) BUILD_BUG_ON(NR_IRQS > 65536); list_for_each_entry(entry, &dev->msi_list, list) { - virq = irq_create_direct_mapping(msic->irq_host); + virq = irq_create_direct_mapping(msic->irq_domain); if (virq == NO_IRQ) { dev_warn(&dev->dev, "axon_msi: virq allocation failed!\n"); @@ -318,7 +318,7 @@ static struct irq_chip msic_irq_chip = { .name = "AXON-MSI", }; -static int msic_host_map(struct irq_host *h, unsigned int virq, +static int msic_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { irq_set_chip_data(virq, h->host_data); @@ -327,7 +327,7 @@ static int msic_host_map(struct irq_host *h, unsigned int virq, return 0; } -static struct irq_host_ops msic_host_ops = { +static const struct irq_domain_ops msic_host_ops = { .map = msic_host_map, }; @@ -337,7 +337,7 @@ static void axon_msi_shutdown(struct platform_device *device) u32 tmp; pr_devel("axon_msi: disabling %s\n", - msic->irq_host->of_node->full_name); + msic->irq_domain->of_node->full_name); tmp = dcr_read(msic->dcr_host, MSIC_CTRL_REG); tmp &= ~MSIC_CTRL_ENABLE & ~MSIC_CTRL_IRQ_ENABLE; msic_dcr_write(msic, MSIC_CTRL_REG, tmp); @@ -392,16 +392,13 @@ static int axon_msi_probe(struct platform_device *device) } memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES); - msic->irq_host = irq_alloc_host(dn, IRQ_HOST_MAP_NOMAP, - NR_IRQS, &msic_host_ops, 0); - if (!msic->irq_host) { - printk(KERN_ERR "axon_msi: couldn't allocate irq_host for %s\n", + msic->irq_domain = irq_domain_add_nomap(dn, &msic_host_ops, msic); + if (!msic->irq_domain) { + printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %s\n", dn->full_name); goto out_free_fifo; } - msic->irq_host->host_data = msic; - irq_set_handler_data(virq, msic); irq_set_chained_handler(virq, axon_msi_cascade); pr_devel("axon_msi: irq 0x%x setup for axon_msi\n", virq); diff --git a/arch/powerpc/platforms/cell/beat_interrupt.c b/arch/powerpc/platforms/cell/beat_interrupt.c index 55015e1..e5c3a2c 100644 --- a/arch/powerpc/platforms/cell/beat_interrupt.c +++ b/arch/powerpc/platforms/cell/beat_interrupt.c @@ -34,7 +34,7 @@ static DEFINE_RAW_SPINLOCK(beatic_irq_mask_lock); static uint64_t beatic_irq_mask_enable[(MAX_IRQS+255)/64]; static uint64_t beatic_irq_mask_ack[(MAX_IRQS+255)/64]; -static struct irq_host *beatic_host; +static struct irq_domain *beatic_host; /* * In this implementation, "virq" == "IRQ plug number", @@ -122,7 +122,7 @@ static struct irq_chip beatic_pic = { * * Note that the number (virq) is already assigned at upper layer. */ -static void beatic_pic_host_unmap(struct irq_host *h, unsigned int virq) +static void beatic_pic_host_unmap(struct irq_domain *h, unsigned int virq) { beat_destruct_irq_plug(virq); } @@ -133,7 +133,7 @@ static void beatic_pic_host_unmap(struct irq_host *h, unsigned int virq) * * Note that the number (virq) is already assigned at upper layer. */ -static int beatic_pic_host_map(struct irq_host *h, unsigned int virq, +static int beatic_pic_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { int64_t err; @@ -154,7 +154,7 @@ static int beatic_pic_host_map(struct irq_host *h, unsigned int virq, * Called from irq_create_of_mapping() only. * Note: We have only 1 entry to translate. */ -static int beatic_pic_host_xlate(struct irq_host *h, struct device_node *ct, +static int beatic_pic_host_xlate(struct irq_domain *h, struct device_node *ct, const u32 *intspec, unsigned int intsize, irq_hw_number_t *out_hwirq, unsigned int *out_flags) @@ -166,13 +166,13 @@ static int beatic_pic_host_xlate(struct irq_host *h, struct device_node *ct, return 0; } -static int beatic_pic_host_match(struct irq_host *h, struct device_node *np) +static int beatic_pic_host_match(struct irq_domain *h, struct device_node *np) { /* Match all */ return 1; } -static struct irq_host_ops beatic_pic_host_ops = { +static const struct irq_domain_ops beatic_pic_host_ops = { .map = beatic_pic_host_map, .unmap = beatic_pic_host_unmap, .xlate = beatic_pic_host_xlate, @@ -239,9 +239,7 @@ void __init beatic_init_IRQ(void) ppc_md.get_irq = beatic_get_irq; /* Allocate an irq host */ - beatic_host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0, - &beatic_pic_host_ops, - 0); + beatic_host = irq_domain_add_nomap(NULL, &beatic_pic_host_ops, NULL); BUG_ON(beatic_host == NULL); irq_set_default_host(beatic_host); } diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c index 96a433d..2d42f3b 100644 --- a/arch/powerpc/platforms/cell/interrupt.c +++ b/arch/powerpc/platforms/cell/interrupt.c @@ -56,7 +56,7 @@ struct iic { static DEFINE_PER_CPU(struct iic, cpu_iic); #define IIC_NODE_COUNT 2 -static struct irq_host *iic_host; +static struct irq_domain *iic_host; /* Convert between "pending" bits and hw irq number */ static irq_hw_number_t iic_pending_to_hwnum(struct cbe_iic_pending_bits bits) @@ -186,7 +186,7 @@ void iic_message_pass(int cpu, int msg) out_be64(&per_cpu(cpu_iic, cpu).regs->generate, (0xf - msg) << 4); } -struct irq_host *iic_get_irq_host(int node) +struct irq_domain *iic_get_irq_host(int node) { return iic_host; } @@ -222,13 +222,13 @@ void iic_request_IPIs(void) #endif /* CONFIG_SMP */ -static int iic_host_match(struct irq_host *h, struct device_node *node) +static int iic_host_match(struct irq_domain *h, struct device_node *node) { return of_device_is_compatible(node, "IBM,CBEA-Internal-Interrupt-Controller"); } -static int iic_host_map(struct irq_host *h, unsigned int virq, +static int iic_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { switch (hw & IIC_IRQ_TYPE_MASK) { @@ -245,7 +245,7 @@ static int iic_host_map(struct irq_host *h, unsigned int virq, return 0; } -static int iic_host_xlate(struct irq_host *h, struct device_node *ct, +static int iic_host_xlate(struct irq_domain *h, struct device_node *ct, const u32 *intspec, unsigned int intsize, irq_hw_number_t *out_hwirq, unsigned int *out_flags) @@ -285,7 +285,7 @@ static int iic_host_xlate(struct irq_host *h, struct device_node *ct, return 0; } -static struct irq_host_ops iic_host_ops = { +static const struct irq_domain_ops iic_host_ops = { .match = iic_host_match, .map = iic_host_map, .xlate = iic_host_xlate, @@ -378,8 +378,8 @@ static int __init setup_iic(void) void __init iic_init_IRQ(void) { /* Setup an irq host data structure */ - iic_host = irq_alloc_host(NULL, IRQ_HOST_MAP_LINEAR, IIC_SOURCE_COUNT, - &iic_host_ops, IIC_IRQ_INVALID); + iic_host = irq_domain_add_linear(NULL, IIC_SOURCE_COUNT, &iic_host_ops, + NULL); BUG_ON(iic_host == NULL); irq_set_default_host(iic_host); diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c index 442c28c..d8b7cc8 100644 --- a/arch/powerpc/platforms/cell/spider-pic.c +++ b/arch/powerpc/platforms/cell/spider-pic.c @@ -62,7 +62,7 @@ enum { #define SPIDER_IRQ_INVALID 63 struct spider_pic { - struct irq_host *host; + struct irq_domain *host; void __iomem *regs; unsigned int node_id; }; @@ -168,7 +168,7 @@ static struct irq_chip spider_pic = { .irq_set_type = spider_set_irq_type, }; -static int spider_host_map(struct irq_host *h, unsigned int virq, +static int spider_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { irq_set_chip_data(virq, h->host_data); @@ -180,7 +180,7 @@ static int spider_host_map(struct irq_host *h, unsigned int virq, return 0; } -static int spider_host_xlate(struct irq_host *h, struct device_node *ct, +static int spider_host_xlate(struct irq_domain *h, struct device_node *ct, const u32 *intspec, unsigned int intsize, irq_hw_number_t *out_hwirq, unsigned int *out_flags) @@ -194,7 +194,7 @@ static int spider_host_xlate(struct irq_host *h, struct device_node *ct, return 0; } -static struct irq_host_ops spider_host_ops = { +static const struct irq_domain_ops spider_host_ops = { .map = spider_host_map, .xlate = spider_host_xlate, }; @@ -299,12 +299,10 @@ static void __init spider_init_one(struct device_node *of_node, int chip, panic("spider_pic: can't map registers !"); /* Allocate a host */ - pic->host = irq_alloc_host(of_node, IRQ_HOST_MAP_LINEAR, - SPIDER_SRC_COUNT, &spider_host_ops, - SPIDER_IRQ_INVALID); + pic->host = irq_domain_add_linear(of_node, SPIDER_SRC_COUNT, + &spider_host_ops, pic); if (pic->host == NULL) panic("spider_pic: can't allocate irq host !"); - pic->host->host_data = pic; /* Go through all sources and disable them */ for (i = 0; i < SPIDER_SRC_COUNT; i++) { diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.c b/arch/powerpc/platforms/embedded6xx/flipper-pic.c index f61a2dd..53d6eee0 100644 --- a/arch/powerpc/platforms/embedded6xx/flipper-pic.c +++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.c @@ -96,9 +96,9 @@ static struct irq_chip flipper_pic = { * */ -static struct irq_host *flipper_irq_host; +static struct irq_domain *flipper_irq_host; -static int flipper_pic_map(struct irq_host *h, unsigned int virq, +static int flipper_pic_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hwirq) { irq_set_chip_data(virq, h->host_data); @@ -107,13 +107,13 @@ static int flipper_pic_map(struct irq_host *h, unsigned int virq, return 0; } -static int flipper_pic_match(struct irq_host *h, struct device_node *np) +static int flipper_pic_match(struct irq_domain *h, struct device_node *np) { return 1; } -static struct irq_host_ops flipper_irq_host_ops = { +static const struct irq_domain_ops flipper_irq_domain_ops = { .map = flipper_pic_map, .match = flipper_pic_match, }; @@ -130,10 +130,10 @@ static void __flipper_quiesce(void __iomem *io_base) out_be32(io_base + FLIPPER_ICR, 0xffffffff); } -struct irq_host * __init flipper_pic_init(struct device_node *np) +struct irq_domain * __init flipper_pic_init(struct device_node *np) { struct device_node *pi; - struct irq_host *irq_host = NULL; + struct irq_domain *irq_domain = NULL; struct resource res; void __iomem *io_base; int retval; @@ -159,17 +159,15 @@ struct irq_host * __init flipper_pic_init(struct device_node *np) __flipper_quiesce(io_base); - irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, FLIPPER_NR_IRQS, - &flipper_irq_host_ops, -1); - if (!irq_host) { - pr_err("failed to allocate irq_host\n"); + irq_domain = irq_domain_add_linear(np, FLIPPER_NR_IRQS, + &flipper_irq_domain_ops, io_base); + if (!irq_domain) { + pr_err("failed to allocate irq_domain\n"); return NULL; } - irq_host->host_data = io_base; - out: - return irq_host; + return irq_domain; } unsigned int flipper_pic_get_irq(void) diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c index e491917..3006b51 100644 --- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c +++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c @@ -89,9 +89,9 @@ static struct irq_chip hlwd_pic = { * */ -static struct irq_host *hlwd_irq_host; +static struct irq_domain *hlwd_irq_host; -static int hlwd_pic_map(struct irq_host *h, unsigned int virq, +static int hlwd_pic_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hwirq) { irq_set_chip_data(virq, h->host_data); @@ -100,11 +100,11 @@ static int hlwd_pic_map(struct irq_host *h, unsigned int virq, return 0; } -static struct irq_host_ops hlwd_irq_host_ops = { +static const struct irq_domain_ops hlwd_irq_domain_ops = { .map = hlwd_pic_map, }; -static unsigned int __hlwd_pic_get_irq(struct irq_host *h) +static unsigned int __hlwd_pic_get_irq(struct irq_domain *h) { void __iomem *io_base = h->host_data; int irq; @@ -123,14 +123,14 @@ static void hlwd_pic_irq_cascade(unsigned int cascade_virq, struct irq_desc *desc) { struct irq_chip *chip = irq_desc_get_chip(desc); - struct irq_host *irq_host = irq_get_handler_data(cascade_virq); + struct irq_domain *irq_domain = irq_get_handler_data(cascade_virq); unsigned int virq; raw_spin_lock(&desc->lock); chip->irq_mask(&desc->irq_data); /* IRQ_LEVEL */ raw_spin_unlock(&desc->lock); - virq = __hlwd_pic_get_irq(irq_host); + virq = __hlwd_pic_get_irq(irq_domain); if (virq != NO_IRQ) generic_handle_irq(virq); else @@ -155,9 +155,9 @@ static void __hlwd_quiesce(void __iomem *io_base) out_be32(io_base + HW_BROADWAY_ICR, 0xffffffff); } -struct irq_host *hlwd_pic_init(struct device_node *np) +struct irq_domain *hlwd_pic_init(struct device_node *np) { - struct irq_host *irq_host; + struct irq_domain *irq_domain; struct resource res; void __iomem *io_base; int retval; @@ -177,15 +177,14 @@ struct irq_host *hlwd_pic_init(struct device_node *np) __hlwd_quiesce(io_base); - irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, HLWD_NR_IRQS, - &hlwd_irq_host_ops, -1); - if (!irq_host) { - pr_err("failed to allocate irq_host\n"); + irq_domain = irq_domain_add_linear(np, HLWD_NR_IRQS, + &hlwd_irq_domain_ops, io_base); + if (!irq_domain) { + pr_err("failed to allocate irq_domain\n"); return NULL; } - irq_host->host_data = io_base; - return irq_host; + return irq_domain; } unsigned int hlwd_pic_get_irq(void) @@ -200,7 +199,7 @@ unsigned int hlwd_pic_get_irq(void) void hlwd_pic_probe(void) { - struct irq_host *host; + struct irq_domain *host; struct device_node *np; const u32 *interrupts; int cascade_virq; diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c index b210345..05ce516 100644 --- a/arch/powerpc/platforms/iseries/irq.c +++ b/arch/powerpc/platforms/iseries/irq.c @@ -342,7 +342,7 @@ unsigned int iSeries_get_irq(void) #ifdef CONFIG_PCI -static int iseries_irq_host_map(struct irq_host *h, unsigned int virq, +static int iseries_irq_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { irq_set_chip_and_handler(virq, &iseries_pic, handle_fasteoi_irq); @@ -350,13 +350,13 @@ static int iseries_irq_host_map(struct irq_host *h, unsigned int virq, return 0; } -static int iseries_irq_host_match(struct irq_host *h, struct device_node *np) +static int iseries_irq_host_match(struct irq_domain *h, struct device_node *np) { /* Match all */ return 1; } -static struct irq_host_ops iseries_irq_host_ops = { +static const struct irq_domain_ops iseries_irq_domain_ops = { .map = iseries_irq_host_map, .match = iseries_irq_host_match, }; @@ -368,7 +368,7 @@ static struct irq_host_ops iseries_irq_host_ops = { void __init iSeries_init_IRQ(void) { /* Register PCI event handler and open an event path */ - struct irq_host *host; + struct irq_domain *host; int ret; /* @@ -380,8 +380,7 @@ void __init iSeries_init_IRQ(void) /* Create irq host. No need for a revmap since HV will give us * back our virtual irq number */ - host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0, - &iseries_irq_host_ops, 0); + host = irq_domain_add_nomap(NULL, &iseries_irq_domain_ops, NULL); BUG_ON(host == NULL); irq_set_default_host(host); diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index 7761aab..92afc38 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c @@ -61,7 +61,7 @@ static DEFINE_RAW_SPINLOCK(pmac_pic_lock); static unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; static int pmac_irq_cascade = -1; -static struct irq_host *pmac_pic_host; +static struct irq_domain *pmac_pic_host; static void __pmac_retrigger(unsigned int irq_nr) { @@ -268,13 +268,13 @@ static struct irqaction gatwick_cascade_action = { .name = "cascade", }; -static int pmac_pic_host_match(struct irq_host *h, struct device_node *node) +static int pmac_pic_host_match(struct irq_domain *h, struct device_node *node) { /* We match all, we don't always have a node anyway */ return 1; } -static int pmac_pic_host_map(struct irq_host *h, unsigned int virq, +static int pmac_pic_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { if (hw >= max_irqs) @@ -288,21 +288,10 @@ static int pmac_pic_host_map(struct irq_host *h, unsigned int virq, return 0; } -static int pmac_pic_host_xlate(struct irq_host *h, struct device_node *ct, - const u32 *intspec, unsigned int intsize, - irq_hw_number_t *out_hwirq, - unsigned int *out_flags) - -{ - *out_flags = IRQ_TYPE_NONE; - *out_hwirq = *intspec; - return 0; -} - -static struct irq_host_ops pmac_pic_host_ops = { +static const struct irq_domain_ops pmac_pic_host_ops = { .match = pmac_pic_host_match, .map = pmac_pic_host_map, - .xlate = pmac_pic_host_xlate, + .xlate = irq_domain_xlate_onecell, }; static void __init pmac_pic_probe_oldstyle(void) @@ -352,9 +341,8 @@ static void __init pmac_pic_probe_oldstyle(void) /* * Allocate an irq host */ - pmac_pic_host = irq_alloc_host(master, IRQ_HOST_MAP_LINEAR, max_irqs, - &pmac_pic_host_ops, - max_irqs); + pmac_pic_host = irq_domain_add_linear(master, max_irqs, + &pmac_pic_host_ops, NULL); BUG_ON(pmac_pic_host == NULL); irq_set_default_host(pmac_pic_host); diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c index 44d7692..a81e5a8 100644 --- a/arch/powerpc/platforms/powermac/smp.c +++ b/arch/powerpc/platforms/powermac/smp.c @@ -125,7 +125,7 @@ static volatile u32 __iomem *psurge_start; static int psurge_type = PSURGE_NONE; /* irq for secondary cpus to report */ -static struct irq_host *psurge_host; +static struct irq_domain *psurge_host; int psurge_secondary_virq; /* @@ -176,7 +176,7 @@ static void smp_psurge_cause_ipi(int cpu, unsigned long data) psurge_set_ipi(cpu); } -static int psurge_host_map(struct irq_host *h, unsigned int virq, +static int psurge_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { irq_set_chip_and_handler(virq, &dummy_irq_chip, handle_percpu_irq); @@ -184,7 +184,7 @@ static int psurge_host_map(struct irq_host *h, unsigned int virq, return 0; } -struct irq_host_ops psurge_host_ops = { +static const struct irq_domain_ops psurge_host_ops = { .map = psurge_host_map, }; @@ -192,8 +192,7 @@ static int psurge_secondary_ipi_init(void) { int rc = -ENOMEM; - psurge_host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0, - &psurge_host_ops, 0); + psurge_host = irq_domain_add_nomap(NULL, &psurge_host_ops, NULL); if (psurge_host) psurge_secondary_virq = irq_create_direct_mapping(psurge_host); diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c index 617efa1..2a4ff86 100644 --- a/arch/powerpc/platforms/ps3/interrupt.c +++ b/arch/powerpc/platforms/ps3/interrupt.c @@ -667,7 +667,7 @@ static void __maybe_unused _dump_mask(struct ps3_private *pd, static void dump_bmp(struct ps3_private* pd) {}; #endif /* defined(DEBUG) */ -static int ps3_host_map(struct irq_host *h, unsigned int virq, +static int ps3_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hwirq) { DBG("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq, @@ -678,13 +678,13 @@ static int ps3_host_map(struct irq_host *h, unsigned int virq, return 0; } -static int ps3_host_match(struct irq_host *h, struct device_node *np) +static int ps3_host_match(struct irq_domain *h, struct device_node *np) { /* Match all */ return 1; } -static struct irq_host_ops ps3_host_ops = { +static const struct irq_domain_ops ps3_host_ops = { .map = ps3_host_map, .match = ps3_host_match, }; @@ -751,10 +751,9 @@ void __init ps3_init_IRQ(void) { int result; unsigned cpu; - struct irq_host *host; + struct irq_domain *host; - host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0, &ps3_host_ops, - PS3_INVALID_OUTLET); + host = irq_domain_add_nomap(NULL, &ps3_host_ops, NULL); irq_set_default_host(host); irq_set_virq_count(PS3_PLUG_MAX + 1); diff --git a/arch/powerpc/platforms/wsp/opb_pic.c b/arch/powerpc/platforms/wsp/opb_pic.c index 19f353d..cb565bf 100644 --- a/arch/powerpc/platforms/wsp/opb_pic.c +++ b/arch/powerpc/platforms/wsp/opb_pic.c @@ -30,7 +30,7 @@ static int opb_index = 0; struct opb_pic { - struct irq_host *host; + struct irq_domain *host; void *regs; int index; spinlock_t lock; @@ -179,7 +179,7 @@ static struct irq_chip opb_irq_chip = { .irq_set_type = opb_set_irq_type }; -static int opb_host_map(struct irq_host *host, unsigned int virq, +static int opb_host_map(struct irq_domain *host, unsigned int virq, irq_hw_number_t hwirq) { struct opb_pic *opb; @@ -196,20 +196,9 @@ static int opb_host_map(struct irq_host *host, unsigned int virq, return 0; } -static int opb_host_xlate(struct irq_host *host, struct device_node *dn, - const u32 *intspec, unsigned int intsize, - irq_hw_number_t *out_hwirq, unsigned int *out_type) -{ - /* Interrupt size must == 2 */ - BUG_ON(intsize != 2); - *out_hwirq = intspec[0]; - *out_type = intspec[1]; - return 0; -} - -static struct irq_host_ops opb_host_ops = { +static const struct irq_domain_ops opb_host_ops = { .map = opb_host_map, - .xlate = opb_host_xlate, + .xlate = irq_domain_xlate_twocell, }; irqreturn_t opb_irq_handler(int irq, void *private) @@ -263,13 +252,11 @@ struct opb_pic *opb_pic_init_one(struct device_node *dn) goto free_opb; } - /* Allocate an irq host so that Linux knows that despite only + /* Allocate an irq domain so that Linux knows that despite only * having one interrupt to issue, we're the controller for multiple * hardware IRQs, so later we can lookup their virtual IRQs. */ - opb->host = irq_alloc_host(dn, IRQ_HOST_MAP_LINEAR, - OPB_NR_IRQS, &opb_host_ops, -1); - + opb->host = irq_domain_add_linear(dn, OPB_NR_IRQS, &opb_host_ops, opb); if (!opb->host) { printk(KERN_ERR "opb: Failed to allocate IRQ host!\n"); goto free_regs; @@ -277,7 +264,6 @@ struct opb_pic *opb_pic_init_one(struct device_node *dn) opb->index = opb_index++; spin_lock_init(&opb->lock); - opb->host->host_data = opb; /* Disable all interrupts by default */ opb_out(opb, OPB_MLSASIER, 0); diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c index 5d7d59a..d4fa03f 100644 --- a/arch/powerpc/sysdev/cpm1.c +++ b/arch/powerpc/sysdev/cpm1.c @@ -54,7 +54,7 @@ cpm8xx_t __iomem *cpmp; /* Pointer to comm processor space */ immap_t __iomem *mpc8xx_immr; static cpic8xx_t __iomem *cpic_reg; -static struct irq_host *cpm_pic_host; +static struct irq_domain *cpm_pic_host; static void cpm_mask_irq(struct irq_data *d) { @@ -98,7 +98,7 @@ int cpm_get_irq(void) return irq_linear_revmap(cpm_pic_host, cpm_vec); } -static int cpm_pic_host_map(struct irq_host *h, unsigned int virq, +static int cpm_pic_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { pr_debug("cpm_pic_host_map(%d, 0x%lx)\n", virq, hw); @@ -123,7 +123,7 @@ static struct irqaction cpm_error_irqaction = { .name = "error", }; -static struct irq_host_ops cpm_pic_host_ops = { +static const struct irq_domain_ops cpm_pic_host_ops = { .map = cpm_pic_host_map, }; @@ -164,8 +164,7 @@ unsigned int cpm_pic_init(void) out_be32(&cpic_reg->cpic_cimr, 0); - cpm_pic_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, - 64, &cpm_pic_host_ops, 64); + cpm_pic_host = irq_domain_add_linear(np, 64, &cpm_pic_host_ops, NULL); if (cpm_pic_host == NULL) { printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n"); sirq = NO_IRQ; diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c index bcab50e..d3be961 100644 --- a/arch/powerpc/sysdev/cpm2_pic.c +++ b/arch/powerpc/sysdev/cpm2_pic.c @@ -50,7 +50,7 @@ static intctl_cpm2_t __iomem *cpm2_intctl; -static struct irq_host *cpm2_pic_host; +static struct irq_domain *cpm2_pic_host; #define NR_MASK_WORDS ((NR_IRQS + 31) / 32) static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; @@ -214,7 +214,7 @@ unsigned int cpm2_get_irq(void) return irq_linear_revmap(cpm2_pic_host, irq); } -static int cpm2_pic_host_map(struct irq_host *h, unsigned int virq, +static int cpm2_pic_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { pr_debug("cpm2_pic_host_map(%d, 0x%lx)\n", virq, hw); @@ -224,21 +224,9 @@ static int cpm2_pic_host_map(struct irq_host *h, unsigned int virq, return 0; } -static int cpm2_pic_host_xlate(struct irq_host *h, struct device_node *ct, - const u32 *intspec, unsigned int intsize, - irq_hw_number_t *out_hwirq, unsigned int *out_flags) -{ - *out_hwirq = intspec[0]; - if (intsize > 1) - *out_flags = intspec[1]; - else - *out_flags = IRQ_TYPE_NONE; - return 0; -} - -static struct irq_host_ops cpm2_pic_host_ops = { +static const struct irq_domain_ops cpm2_pic_host_ops = { .map = cpm2_pic_host_map, - .xlate = cpm2_pic_host_xlate, + .xlate = irq_domain_xlate_onetwocell, }; void cpm2_pic_init(struct device_node *node) @@ -275,8 +263,7 @@ void cpm2_pic_init(struct device_node *node) out_be32(&cpm2_intctl->ic_scprrl, 0x05309770); /* create a legacy host */ - cpm2_pic_host = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR, - 64, &cpm2_pic_host_ops, 64); + cpm2_pic_host = irq_domain_add_linear(node, 64, &cpm2_pic_host_ops, NULL); if (cpm2_pic_host == NULL) { printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n"); return; diff --git a/arch/powerpc/sysdev/ehv_pic.c b/arch/powerpc/sysdev/ehv_pic.c index b6731e4..6e0e100 100644 --- a/arch/powerpc/sysdev/ehv_pic.c +++ b/arch/powerpc/sysdev/ehv_pic.c @@ -182,13 +182,13 @@ unsigned int ehv_pic_get_irq(void) return irq_linear_revmap(global_ehv_pic->irqhost, irq); } -static int ehv_pic_host_match(struct irq_host *h, struct device_node *node) +static int ehv_pic_host_match(struct irq_domain *h, struct device_node *node) { /* Exact match, unless ehv_pic node is NULL */ return h->of_node == NULL || h->of_node == node; } -static int ehv_pic_host_map(struct irq_host *h, unsigned int virq, +static int ehv_pic_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { struct ehv_pic *ehv_pic = h->host_data; @@ -217,7 +217,7 @@ static int ehv_pic_host_map(struct irq_host *h, unsigned int virq, return 0; } -static int ehv_pic_host_xlate(struct irq_host *h, struct device_node *ct, +static int ehv_pic_host_xlate(struct irq_domain *h, struct device_node *ct, const u32 *intspec, unsigned int intsize, irq_hw_number_t *out_hwirq, unsigned int *out_flags) @@ -248,7 +248,7 @@ static int ehv_pic_host_xlate(struct irq_host *h, struct device_node *ct, return 0; } -static struct irq_host_ops ehv_pic_host_ops = { +static const struct irq_domain_ops ehv_pic_host_ops = { .match = ehv_pic_host_match, .map = ehv_pic_host_map, .xlate = ehv_pic_host_xlate, @@ -275,9 +275,8 @@ void __init ehv_pic_init(void) return; } - ehv_pic->irqhost = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, - NR_EHV_PIC_INTS, &ehv_pic_host_ops, 0); - + ehv_pic->irqhost = irq_domain_add_linear(np, NR_EHV_PIC_INTS, + &ehv_pic_host_ops, ehv_pic); if (!ehv_pic->irqhost) { of_node_put(np); kfree(ehv_pic); @@ -293,7 +292,6 @@ void __init ehv_pic_init(void) of_node_put(np2); } - ehv_pic->irqhost->host_data = ehv_pic; ehv_pic->hc_irq = ehv_pic_irq_chip; ehv_pic->hc_irq.irq_set_affinity = ehv_pic_set_affinity; ehv_pic->coreint_flag = coreint_flag; diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index ecb5c19..0c01deb 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -60,7 +60,7 @@ static struct irq_chip fsl_msi_chip = { .name = "FSL-MSI", }; -static int fsl_msi_host_map(struct irq_host *h, unsigned int virq, +static int fsl_msi_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { struct fsl_msi *msi_data = h->host_data; @@ -74,7 +74,7 @@ static int fsl_msi_host_map(struct irq_host *h, unsigned int virq, return 0; } -static struct irq_host_ops fsl_msi_host_ops = { +static const struct irq_domain_ops fsl_msi_host_ops = { .map = fsl_msi_host_map, }; @@ -387,8 +387,8 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev) } platform_set_drvdata(dev, msi); - msi->irqhost = irq_alloc_host(dev->dev.of_node, IRQ_HOST_MAP_LINEAR, - NR_MSI_IRQS, &fsl_msi_host_ops, 0); + msi->irqhost = irq_domain_add_linear(dev->dev.of_node, + NR_MSI_IRQS, &fsl_msi_host_ops, msi); if (msi->irqhost == NULL) { dev_err(&dev->dev, "No memory for MSI irqhost\n"); @@ -420,8 +420,6 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev) msi->feature = features->fsl_pic_ip; - msi->irqhost->host_data = msi; - /* * Remember the phandle, so that we can match with any PCI nodes * that have an "fsl,msi" property. diff --git a/arch/powerpc/sysdev/fsl_msi.h b/arch/powerpc/sysdev/fsl_msi.h index f6c646a..8225f86 100644 --- a/arch/powerpc/sysdev/fsl_msi.h +++ b/arch/powerpc/sysdev/fsl_msi.h @@ -26,7 +26,7 @@ #define FSL_PIC_IP_VMPIC 0x00000003 struct fsl_msi { - struct irq_host *irqhost; + struct irq_domain *irqhost; unsigned long cascade_irq; diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c index d18bb27..997df6a 100644 --- a/arch/powerpc/sysdev/i8259.c +++ b/arch/powerpc/sysdev/i8259.c @@ -25,7 +25,7 @@ static unsigned char cached_8259[2] = { 0xff, 0xff }; static DEFINE_RAW_SPINLOCK(i8259_lock); -static struct irq_host *i8259_host; +static struct irq_domain *i8259_host; /* * Acknowledge the IRQ using either the PCI host bridge's interrupt @@ -163,12 +163,12 @@ static struct resource pic_edgectrl_iores = { .flags = IORESOURCE_BUSY, }; -static int i8259_host_match(struct irq_host *h, struct device_node *node) +static int i8259_host_match(struct irq_domain *h, struct device_node *node) { return h->of_node == NULL || h->of_node == node; } -static int i8259_host_map(struct irq_host *h, unsigned int virq, +static int i8259_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { pr_debug("i8259_host_map(%d, 0x%lx)\n", virq, hw); @@ -185,7 +185,7 @@ static int i8259_host_map(struct irq_host *h, unsigned int virq, return 0; } -static int i8259_host_xlate(struct irq_host *h, struct device_node *ct, +static int i8259_host_xlate(struct irq_domain *h, struct device_node *ct, const u32 *intspec, unsigned int intsize, irq_hw_number_t *out_hwirq, unsigned int *out_flags) { @@ -205,13 +205,13 @@ static int i8259_host_xlate(struct irq_host *h, struct device_node *ct, return 0; } -static struct irq_host_ops i8259_host_ops = { +static struct irq_domain_ops i8259_host_ops = { .match = i8259_host_match, .map = i8259_host_map, .xlate = i8259_host_xlate, }; -struct irq_host *i8259_get_host(void) +struct irq_domain *i8259_get_host(void) { return i8259_host; } @@ -263,8 +263,7 @@ void i8259_init(struct device_node *node, unsigned long intack_addr) raw_spin_unlock_irqrestore(&i8259_lock, flags); /* create a legacy host */ - i8259_host = irq_alloc_host(node, IRQ_HOST_MAP_LEGACY, - 0, &i8259_host_ops, 0); + i8259_host = irq_domain_add_legacy_isa(node, &i8259_host_ops, NULL); if (i8259_host == NULL) { printk(KERN_ERR "i8259: failed to allocate irq host !\n"); return; diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c index 95da897..b50f978 100644 --- a/arch/powerpc/sysdev/ipic.c +++ b/arch/powerpc/sysdev/ipic.c @@ -672,13 +672,13 @@ static struct irq_chip ipic_edge_irq_chip = { .irq_set_type = ipic_set_irq_type, }; -static int ipic_host_match(struct irq_host *h, struct device_node *node) +static int ipic_host_match(struct irq_domain *h, struct device_node *node) { /* Exact match, unless ipic node is NULL */ return h->of_node == NULL || h->of_node == node; } -static int ipic_host_map(struct irq_host *h, unsigned int virq, +static int ipic_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { struct ipic *ipic = h->host_data; @@ -692,26 +692,10 @@ static int ipic_host_map(struct irq_host *h, unsigned int virq, return 0; } -static int ipic_host_xlate(struct irq_host *h, struct device_node *ct, - const u32 *intspec, unsigned int intsize, - irq_hw_number_t *out_hwirq, unsigned int *out_flags) - -{ - /* interrupt sense values coming from the device tree equal either - * LEVEL_LOW (low assertion) or EDGE_FALLING (high-to-low change) - */ - *out_hwirq = intspec[0]; - if (intsize > 1) - *out_flags = intspec[1]; - else - *out_flags = IRQ_TYPE_NONE; - return 0; -} - -static struct irq_host_ops ipic_host_ops = { +static struct irq_domain_ops ipic_host_ops = { .match = ipic_host_match, .map = ipic_host_map, - .xlate = ipic_host_xlate, + .xlate = irq_domain_xlate_onetwocell, }; struct ipic * __init ipic_init(struct device_node *node, unsigned int flags) @@ -728,9 +712,8 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags) if (ipic == NULL) return NULL; - ipic->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR, - NR_IPIC_INTS, - &ipic_host_ops, 0); + ipic->irqhost = irq_domain_add_linear(node, NR_IPIC_INTS, + &ipic_host_ops, ipic); if (ipic->irqhost == NULL) { kfree(ipic); return NULL; @@ -738,8 +721,6 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags) ipic->regs = ioremap(res.start, resource_size(&res)); - ipic->irqhost->host_data = ipic; - /* init hw */ ipic_write(ipic->regs, IPIC_SICNR, 0x0); diff --git a/arch/powerpc/sysdev/ipic.h b/arch/powerpc/sysdev/ipic.h index 9391c57..90031d1 100644 --- a/arch/powerpc/sysdev/ipic.h +++ b/arch/powerpc/sysdev/ipic.h @@ -43,7 +43,7 @@ struct ipic { volatile u32 __iomem *regs; /* The remapper for this IPIC */ - struct irq_host *irqhost; + struct irq_domain *irqhost; }; struct ipic_info { diff --git a/arch/powerpc/sysdev/mpc8xx_pic.c b/arch/powerpc/sysdev/mpc8xx_pic.c index 2ca0a85..d5f5416 100644 --- a/arch/powerpc/sysdev/mpc8xx_pic.c +++ b/arch/powerpc/sysdev/mpc8xx_pic.c @@ -17,7 +17,7 @@ extern int cpm_get_irq(struct pt_regs *regs); -static struct irq_host *mpc8xx_pic_host; +static struct irq_domain *mpc8xx_pic_host; #define NR_MASK_WORDS ((NR_IRQS + 31) / 32) static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; static sysconf8xx_t __iomem *siu_reg; @@ -110,7 +110,7 @@ unsigned int mpc8xx_get_irq(void) } -static int mpc8xx_pic_host_map(struct irq_host *h, unsigned int virq, +static int mpc8xx_pic_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { pr_debug("mpc8xx_pic_host_map(%d, 0x%lx)\n", virq, hw); @@ -121,7 +121,7 @@ static int mpc8xx_pic_host_map(struct irq_host *h, unsigned int virq, } -static int mpc8xx_pic_host_xlate(struct irq_host *h, struct device_node *ct, +static int mpc8xx_pic_host_xlate(struct irq_domain *h, struct device_node *ct, const u32 *intspec, unsigned int intsize, irq_hw_number_t *out_hwirq, unsigned int *out_flags) { @@ -142,7 +142,7 @@ static int mpc8xx_pic_host_xlate(struct irq_host *h, struct device_node *ct, } -static struct irq_host_ops mpc8xx_pic_host_ops = { +static struct irq_domain_ops mpc8xx_pic_host_ops = { .map = mpc8xx_pic_host_map, .xlate = mpc8xx_pic_host_xlate, }; @@ -171,8 +171,7 @@ int mpc8xx_pic_init(void) goto out; } - mpc8xx_pic_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, - 64, &mpc8xx_pic_host_ops, 64); + mpc8xx_pic_host = irq_domain_add_linear(np, 64, &mpc8xx_pic_host_ops, NULL); if (mpc8xx_pic_host == NULL) { printk(KERN_ERR "MPC8xx PIC: failed to allocate irq host!\n"); ret = -ENOMEM; diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 4e9ccb1..c83a512 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -965,13 +965,13 @@ static struct irq_chip mpic_irq_ht_chip = { #endif /* CONFIG_MPIC_U3_HT_IRQS */ -static int mpic_host_match(struct irq_host *h, struct device_node *node) +static int mpic_host_match(struct irq_domain *h, struct device_node *node) { /* Exact match, unless mpic node is NULL */ return h->of_node == NULL || h->of_node == node; } -static int mpic_host_map(struct irq_host *h, unsigned int virq, +static int mpic_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { struct mpic *mpic = h->host_data; @@ -1041,7 +1041,7 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq, return 0; } -static int mpic_host_xlate(struct irq_host *h, struct device_node *ct, +static int mpic_host_xlate(struct irq_domain *h, struct device_node *ct, const u32 *intspec, unsigned int intsize, irq_hw_number_t *out_hwirq, unsigned int *out_flags) @@ -1121,13 +1121,13 @@ static void mpic_cascade(unsigned int irq, struct irq_desc *desc) BUG_ON(!(mpic->flags & MPIC_SECONDARY)); virq = mpic_get_one_irq(mpic); - if (virq != NO_IRQ) + if (virq) generic_handle_irq(virq); chip->irq_eoi(&desc->irq_data); } -static struct irq_host_ops mpic_host_ops = { +static struct irq_domain_ops mpic_host_ops = { .match = mpic_host_match, .map = mpic_host_map, .xlate = mpic_host_xlate, @@ -1345,10 +1345,9 @@ struct mpic * __init mpic_alloc(struct device_node *node, mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1); mpic->isu_mask = (1 << mpic->isu_shift) - 1; - mpic->irqhost = irq_alloc_host(mpic->node, IRQ_HOST_MAP_LINEAR, + mpic->irqhost = irq_domain_add_linear(mpic->node, isu_size ? isu_size : mpic->num_sources, - &mpic_host_ops, - flags & MPIC_LARGE_VECTORS ? 2048 : 256); + &mpic_host_ops, mpic); /* * FIXME: The code leaks the MPIC object and mappings here; this @@ -1357,8 +1356,6 @@ struct mpic * __init mpic_alloc(struct device_node *node, if (mpic->irqhost == NULL) return NULL; - mpic->irqhost->host_data = mpic; - /* Display version */ switch (greg_feature & MPIC_GREG_FEATURE_VERSION_MASK) { case 1: diff --git a/arch/powerpc/sysdev/mpic_msi.c b/arch/powerpc/sysdev/mpic_msi.c index 0f67cd7..0622aa9 100644 --- a/arch/powerpc/sysdev/mpic_msi.c +++ b/arch/powerpc/sysdev/mpic_msi.c @@ -32,7 +32,7 @@ void mpic_msi_reserve_hwirq(struct mpic *mpic, irq_hw_number_t hwirq) static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic) { irq_hw_number_t hwirq; - struct irq_host_ops *ops = mpic->irqhost->ops; + const struct irq_domain_ops *ops = mpic->irqhost->ops; struct device_node *np; int flags, index, i; struct of_irq oirq; diff --git a/arch/powerpc/sysdev/mv64x60_pic.c b/arch/powerpc/sysdev/mv64x60_pic.c index 14d1302..8848e99 100644 --- a/arch/powerpc/sysdev/mv64x60_pic.c +++ b/arch/powerpc/sysdev/mv64x60_pic.c @@ -70,7 +70,7 @@ static u32 mv64x60_cached_low_mask; static u32 mv64x60_cached_high_mask = MV64X60_HIGH_GPP_GROUPS; static u32 mv64x60_cached_gpp_mask; -static struct irq_host *mv64x60_irq_host; +static struct irq_domain *mv64x60_irq_host; /* * mv64x60_chip_low functions @@ -208,7 +208,7 @@ static struct irq_chip *mv64x60_chips[] = { [MV64x60_LEVEL1_GPP] = &mv64x60_chip_gpp, }; -static int mv64x60_host_map(struct irq_host *h, unsigned int virq, +static int mv64x60_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hwirq) { int level1; @@ -223,7 +223,7 @@ static int mv64x60_host_map(struct irq_host *h, unsigned int virq, return 0; } -static struct irq_host_ops mv64x60_host_ops = { +static struct irq_domain_ops mv64x60_host_ops = { .map = mv64x60_host_map, }; @@ -250,9 +250,8 @@ void __init mv64x60_init_irq(void) paddr = of_translate_address(np, reg); mv64x60_irq_reg_base = ioremap(paddr, reg[1]); - mv64x60_irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, - MV64x60_NUM_IRQS, - &mv64x60_host_ops, MV64x60_NUM_IRQS); + mv64x60_irq_host = irq_domain_add_linear(np, MV64x60_NUM_IRQS, + &mv64x60_host_ops, NULL); spin_lock_irqsave(&mv64x60_lock, flags); out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK, diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c index 73034bd..2fba6ef2 100644 --- a/arch/powerpc/sysdev/qe_lib/qe_ic.c +++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c @@ -245,13 +245,13 @@ static struct irq_chip qe_ic_irq_chip = { .irq_mask_ack = qe_ic_mask_irq, }; -static int qe_ic_host_match(struct irq_host *h, struct device_node *node) +static int qe_ic_host_match(struct irq_domain *h, struct device_node *node) { /* Exact match, unless qe_ic node is NULL */ return h->of_node == NULL || h->of_node == node; } -static int qe_ic_host_map(struct irq_host *h, unsigned int virq, +static int qe_ic_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { struct qe_ic *qe_ic = h->host_data; @@ -272,23 +272,10 @@ static int qe_ic_host_map(struct irq_host *h, unsigned int virq, return 0; } -static int qe_ic_host_xlate(struct irq_host *h, struct device_node *ct, - const u32 * intspec, unsigned int intsize, - irq_hw_number_t * out_hwirq, - unsigned int *out_flags) -{ - *out_hwirq = intspec[0]; - if (intsize > 1) - *out_flags = intspec[1]; - else - *out_flags = IRQ_TYPE_NONE; - return 0; -} - -static struct irq_host_ops qe_ic_host_ops = { +static struct irq_domain_ops qe_ic_host_ops = { .match = qe_ic_host_match, .map = qe_ic_host_map, - .xlate = qe_ic_host_xlate, + .xlate = irq_domain_xlate_onetwocell, }; /* Return an interrupt vector or NO_IRQ if no interrupt is pending. */ @@ -339,8 +326,8 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags, if (qe_ic == NULL) return; - qe_ic->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR, - NR_QE_IC_INTS, &qe_ic_host_ops, 0); + qe_ic->irqhost = irq_domain_add_linear(node, NR_QE_IC_INTS, + &qe_ic_host_ops, qe_ic); if (qe_ic->irqhost == NULL) { kfree(qe_ic); return; @@ -348,7 +335,6 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags, qe_ic->regs = ioremap(res.start, resource_size(&res)); - qe_ic->irqhost->host_data = qe_ic; qe_ic->hc_irq = qe_ic_irq_chip; qe_ic->virq_high = irq_of_parse_and_map(node, 0); diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.h b/arch/powerpc/sysdev/qe_lib/qe_ic.h index c1361d0..c327872 100644 --- a/arch/powerpc/sysdev/qe_lib/qe_ic.h +++ b/arch/powerpc/sysdev/qe_lib/qe_ic.h @@ -79,7 +79,7 @@ struct qe_ic { volatile u32 __iomem *regs; /* The remapper for this QEIC */ - struct irq_host *irqhost; + struct irq_domain *irqhost; /* The "linux" controller struct */ struct irq_chip hc_irq; diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c index 4d18658..188012c 100644 --- a/arch/powerpc/sysdev/tsi108_pci.c +++ b/arch/powerpc/sysdev/tsi108_pci.c @@ -51,7 +51,7 @@ u32 tsi108_pci_cfg_base; static u32 tsi108_pci_cfg_phys; u32 tsi108_csr_vir_base; -static struct irq_host *pci_irq_host; +static struct irq_domain *pci_irq_host; extern u32 get_vir_csrbase(void); extern u32 tsi108_read_reg(u32 reg_offset); @@ -376,7 +376,7 @@ static struct irq_chip tsi108_pci_irq = { .irq_unmask = tsi108_pci_irq_unmask, }; -static int pci_irq_host_xlate(struct irq_host *h, struct device_node *ct, +static int pci_irq_host_xlate(struct irq_domain *h, struct device_node *ct, const u32 *intspec, unsigned int intsize, irq_hw_number_t *out_hwirq, unsigned int *out_flags) { @@ -385,7 +385,7 @@ static int pci_irq_host_xlate(struct irq_host *h, struct device_node *ct, return 0; } -static int pci_irq_host_map(struct irq_host *h, unsigned int virq, +static int pci_irq_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { unsigned int irq; DBG("%s(%d, 0x%lx)\n", __func__, virq, hw); @@ -397,7 +397,7 @@ static int pci_irq_host_map(struct irq_host *h, unsigned int virq, return 0; } -static struct irq_host_ops pci_irq_host_ops = { +static struct irq_domain_ops pci_irq_domain_ops = { .map = pci_irq_host_map, .xlate = pci_irq_host_xlate, }; @@ -419,10 +419,9 @@ void __init tsi108_pci_int_init(struct device_node *node) { DBG("Tsi108_pci_int_init: initializing PCI interrupts\n"); - pci_irq_host = irq_alloc_host(node, IRQ_HOST_MAP_LEGACY, - 0, &pci_irq_host_ops, 0); + pci_irq_host = irq_domain_add_legacy_isa(node, &pci_irq_domain_ops, NULL); if (pci_irq_host == NULL) { - printk(KERN_ERR "pci_irq_host: failed to allocate irq host !\n"); + printk(KERN_ERR "pci_irq_host: failed to allocate irq domain!\n"); return; } diff --git a/arch/powerpc/sysdev/uic.c b/arch/powerpc/sysdev/uic.c index 063c901..9203393 100644 --- a/arch/powerpc/sysdev/uic.c +++ b/arch/powerpc/sysdev/uic.c @@ -49,7 +49,7 @@ struct uic { raw_spinlock_t lock; /* The remapper for this UIC */ - struct irq_host *irqhost; + struct irq_domain *irqhost; }; static void uic_unmask_irq(struct irq_data *d) @@ -174,7 +174,7 @@ static struct irq_chip uic_irq_chip = { .irq_set_type = uic_set_irq_type, }; -static int uic_host_map(struct irq_host *h, unsigned int virq, +static int uic_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { struct uic *uic = h->host_data; @@ -190,21 +190,9 @@ static int uic_host_map(struct irq_host *h, unsigned int virq, return 0; } -static int uic_host_xlate(struct irq_host *h, struct device_node *ct, - const u32 *intspec, unsigned int intsize, - irq_hw_number_t *out_hwirq, unsigned int *out_type) - -{ - /* UIC intspecs must have 2 cells */ - BUG_ON(intsize != 2); - *out_hwirq = intspec[0]; - *out_type = intspec[1]; - return 0; -} - -static struct irq_host_ops uic_host_ops = { +static struct irq_domain_ops uic_host_ops = { .map = uic_host_map, - .xlate = uic_host_xlate, + .xlate = irq_domain_xlate_twocell, }; void uic_irq_cascade(unsigned int virq, struct irq_desc *desc) @@ -270,13 +258,11 @@ static struct uic * __init uic_init_one(struct device_node *node) } uic->dcrbase = *dcrreg; - uic->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR, - NR_UIC_INTS, &uic_host_ops, -1); + uic->irqhost = irq_domain_add_linear(node, NR_UIC_INTS, &uic_host_ops, + uic); if (! uic->irqhost) return NULL; /* FIXME: panic? */ - uic->irqhost->host_data = uic; - /* Start with all interrupts disabled, level and non-critical */ mtdcr(uic->dcrbase + UIC_ER, 0); mtdcr(uic->dcrbase + UIC_CR, 0); diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c index d72eda6..ea5e204 100644 --- a/arch/powerpc/sysdev/xics/xics-common.c +++ b/arch/powerpc/sysdev/xics/xics-common.c @@ -40,7 +40,7 @@ unsigned int xics_interrupt_server_size = 8; DEFINE_PER_CPU(struct xics_cppr, xics_cppr); -struct irq_host *xics_host; +struct irq_domain *xics_host; static LIST_HEAD(ics_list); @@ -212,16 +212,16 @@ void xics_migrate_irqs_away(void) /* We can't set affinity on ISA interrupts */ if (virq < NUM_ISA_INTERRUPTS) continue; - if (!virq_is_host(virq, xics_host)) - continue; - irq = (unsigned int)virq_to_hw(virq); - /* We need to get IPIs still. */ - if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS) - continue; desc = irq_to_desc(virq); /* We only need to migrate enabled IRQS */ if (!desc || !desc->action) continue; + if (desc->irq_data.domain != xics_host) + continue; + irq = desc->irq_data.hwirq; + /* We need to get IPIs still. */ + if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS) + continue; chip = irq_desc_get_chip(desc); if (!chip || !chip->irq_set_affinity) continue; @@ -301,7 +301,7 @@ int xics_get_irq_server(unsigned int virq, const struct cpumask *cpumask, } #endif /* CONFIG_SMP */ -static int xics_host_match(struct irq_host *h, struct device_node *node) +static int xics_host_match(struct irq_domain *h, struct device_node *node) { struct ics *ics; @@ -323,7 +323,7 @@ static struct irq_chip xics_ipi_chip = { .irq_unmask = xics_ipi_unmask, }; -static int xics_host_map(struct irq_host *h, unsigned int virq, +static int xics_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { struct ics *ics; @@ -351,7 +351,7 @@ static int xics_host_map(struct irq_host *h, unsigned int virq, return -EINVAL; } -static int xics_host_xlate(struct irq_host *h, struct device_node *ct, +static int xics_host_xlate(struct irq_domain *h, struct device_node *ct, const u32 *intspec, unsigned int intsize, irq_hw_number_t *out_hwirq, unsigned int *out_flags) @@ -366,7 +366,7 @@ static int xics_host_xlate(struct irq_host *h, struct device_node *ct, return 0; } -static struct irq_host_ops xics_host_ops = { +static struct irq_domain_ops xics_host_ops = { .match = xics_host_match, .map = xics_host_map, .xlate = xics_host_xlate, @@ -374,8 +374,7 @@ static struct irq_host_ops xics_host_ops = { static void __init xics_init_host(void) { - xics_host = irq_alloc_host(NULL, IRQ_HOST_MAP_TREE, 0, &xics_host_ops, - XICS_IRQ_SPURIOUS); + xics_host = irq_domain_add_tree(NULL, &xics_host_ops, NULL); BUG_ON(xics_host == NULL); irq_set_default_host(xics_host); } diff --git a/arch/powerpc/sysdev/xilinx_intc.c b/arch/powerpc/sysdev/xilinx_intc.c index 6183799..8d73c3c 100644 --- a/arch/powerpc/sysdev/xilinx_intc.c +++ b/arch/powerpc/sysdev/xilinx_intc.c @@ -40,7 +40,7 @@ #define XINTC_IVR 24 /* Interrupt Vector */ #define XINTC_MER 28 /* Master Enable */ -static struct irq_host *master_irqhost; +static struct irq_domain *master_irqhost; #define XILINX_INTC_MAXIRQS (32) @@ -141,7 +141,7 @@ static struct irq_chip xilinx_intc_edge_irqchip = { /** * xilinx_intc_xlate - translate virq# from device tree interrupts property */ -static int xilinx_intc_xlate(struct irq_host *h, struct device_node *ct, +static int xilinx_intc_xlate(struct irq_domain *h, struct device_node *ct, const u32 *intspec, unsigned int intsize, irq_hw_number_t *out_hwirq, unsigned int *out_flags) @@ -161,7 +161,7 @@ static int xilinx_intc_xlate(struct irq_host *h, struct device_node *ct, return 0; } -static int xilinx_intc_map(struct irq_host *h, unsigned int virq, +static int xilinx_intc_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t irq) { irq_set_chip_data(virq, h->host_data); @@ -177,15 +177,15 @@ static int xilinx_intc_map(struct irq_host *h, unsigned int virq, return 0; } -static struct irq_host_ops xilinx_intc_ops = { +static struct irq_domain_ops xilinx_intc_ops = { .map = xilinx_intc_map, .xlate = xilinx_intc_xlate, }; -struct irq_host * __init +struct irq_domain * __init xilinx_intc_init(struct device_node *np) { - struct irq_host * irq; + struct irq_domain * irq; void * regs; /* Find and map the intc registers */ @@ -200,12 +200,11 @@ xilinx_intc_init(struct device_node *np) out_be32(regs + XINTC_IAR, ~(u32) 0); /* Acknowledge pending irqs */ out_be32(regs + XINTC_MER, 0x3UL); /* Turn on the Master Enable. */ - /* Allocate and initialize an irq_host structure. */ - irq = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, XILINX_INTC_MAXIRQS, - &xilinx_intc_ops, -1); + /* Allocate and initialize an irq_domain structure. */ + irq = irq_domain_add_linear(np, XILINX_INTC_MAXIRQS, &xilinx_intc_ops, + regs); if (!irq) panic(__FILE__ ": Cannot allocate IRQ host\n"); - irq->host_data = regs; return irq; } diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h index edd3d3cde..c287651 100644 --- a/arch/sparc/include/asm/prom.h +++ b/arch/sparc/include/asm/prom.h @@ -22,6 +22,7 @@ #include <linux/proc_fs.h> #include <linux/mutex.h> #include <linux/atomic.h> +#include <linux/irqdomain.h> #define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 2 #define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1 @@ -55,15 +56,6 @@ struct resource; extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name); extern void of_iounmap(struct resource *res, void __iomem *base, unsigned long size); -/* These routines are here to provide compatibility with how powerpc - * handles IRQ mapping for OF device nodes. We precompute and permanently - * register them in the platform_device objects, whereas powerpc computes them - * on request. - */ -static inline void irq_dispose_mapping(unsigned int virq) -{ -} - extern struct device_node *of_console_device; extern char *of_console_path; extern char *of_console_options; diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 5bed94e1..e0829a6 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -398,6 +398,7 @@ config X86_INTEL_CE select X86_REBOOTFIXUPS select OF select OF_EARLY_FLATTREE + select IRQ_DOMAIN ---help--- Select for the Intel CE media processor (CE4100) SOC. This option compiles in support for the CE4100 SOC for settop @@ -2076,6 +2077,7 @@ config OLPC select GPIOLIB select OF select OF_PROMTREE + select IRQ_DOMAIN ---help--- Add support for detecting the unique features of the OLPC XO hardware. diff --git a/arch/x86/include/asm/irq_controller.h b/arch/x86/include/asm/irq_controller.h deleted file mode 100644 index 423bbbd..0000000 --- a/arch/x86/include/asm/irq_controller.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __IRQ_CONTROLLER__ -#define __IRQ_CONTROLLER__ - -struct irq_domain { - int (*xlate)(struct irq_domain *h, const u32 *intspec, u32 intsize, - u32 *out_hwirq, u32 *out_type); - void *priv; - struct device_node *controller; - struct list_head l; -}; - -#endif diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h index 644dd885..60bef66 100644 --- a/arch/x86/include/asm/prom.h +++ b/arch/x86/include/asm/prom.h @@ -21,7 +21,6 @@ #include <asm/irq.h> #include <linux/atomic.h> #include <asm/setup.h> -#include <asm/irq_controller.h> #ifdef CONFIG_OF extern int of_ioapic; @@ -43,15 +42,6 @@ extern char cmd_line[COMMAND_LINE_SIZE]; #define pci_address_to_pio pci_address_to_pio unsigned long pci_address_to_pio(phys_addr_t addr); -/** - * irq_dispose_mapping - Unmap an interrupt - * @virq: linux virq number of the interrupt to unmap - * - * FIXME: We really should implement proper virq handling like power, - * but that's going to be major surgery. - */ -static inline void irq_dispose_mapping(unsigned int virq) { } - #define HAVE_ARCH_DEVTREE_FIXUPS #endif /* __ASSEMBLY__ */ diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c index 5282179..3ae2ced 100644 --- a/arch/x86/kernel/devicetree.c +++ b/arch/x86/kernel/devicetree.c @@ -4,6 +4,7 @@ #include <linux/bootmem.h> #include <linux/export.h> #include <linux/io.h> +#include <linux/irqdomain.h> #include <linux/interrupt.h> #include <linux/list.h> #include <linux/of.h> @@ -17,64 +18,14 @@ #include <linux/initrd.h> #include <asm/hpet.h> -#include <asm/irq_controller.h> #include <asm/apic.h> #include <asm/pci_x86.h> __initdata u64 initial_dtb; char __initdata cmd_line[COMMAND_LINE_SIZE]; -static LIST_HEAD(irq_domains); -static DEFINE_RAW_SPINLOCK(big_irq_lock); int __initdata of_ioapic; -#ifdef CONFIG_X86_IO_APIC -static void add_interrupt_host(struct irq_domain *ih) -{ - unsigned long flags; - - raw_spin_lock_irqsave(&big_irq_lock, flags); - list_add(&ih->l, &irq_domains); - raw_spin_unlock_irqrestore(&big_irq_lock, flags); -} -#endif - -static struct irq_domain *get_ih_from_node(struct device_node *controller) -{ - struct irq_domain *ih, *found = NULL; - unsigned long flags; - - raw_spin_lock_irqsave(&big_irq_lock, flags); - list_for_each_entry(ih, &irq_domains, l) { - if (ih->controller == controller) { - found = ih; - break; - } - } - raw_spin_unlock_irqrestore(&big_irq_lock, flags); - return found; -} - -unsigned int irq_create_of_mapping(struct device_node *controller, - const u32 *intspec, unsigned int intsize) -{ - struct irq_domain *ih; - u32 virq, type; - int ret; - - ih = get_ih_from_node(controller); - if (!ih) - return 0; - ret = ih->xlate(ih, intspec, intsize, &virq, &type); - if (ret) - return 0; - if (type == IRQ_TYPE_NONE) - return virq; - irq_set_irq_type(virq, type); - return virq; -} -EXPORT_SYMBOL_GPL(irq_create_of_mapping); - unsigned long pci_address_to_pio(phys_addr_t address) { /* @@ -354,36 +305,43 @@ static struct of_ioapic_type of_ioapic_type[] = }, }; -static int ioapic_xlate(struct irq_domain *id, const u32 *intspec, u32 intsize, - u32 *out_hwirq, u32 *out_type) +static int ioapic_xlate(struct irq_domain *domain, + struct device_node *controller, + const u32 *intspec, u32 intsize, + irq_hw_number_t *out_hwirq, u32 *out_type) { - struct mp_ioapic_gsi *gsi_cfg; struct io_apic_irq_attr attr; struct of_ioapic_type *it; - u32 line, idx, type; + u32 line, idx; + int rc; - if (intsize < 2) + if (WARN_ON(intsize < 2)) return -EINVAL; - line = *intspec; - idx = (u32) id->priv; - gsi_cfg = mp_ioapic_gsi_routing(idx); - *out_hwirq = line + gsi_cfg->gsi_base; - - intspec++; - type = *intspec; + line = intspec[0]; - if (type >= ARRAY_SIZE(of_ioapic_type)) + if (intspec[1] >= ARRAY_SIZE(of_ioapic_type)) return -EINVAL; - it = of_ioapic_type + type; - *out_type = it->out_type; + it = &of_ioapic_type[intspec[1]]; + idx = (u32) domain->host_data; set_io_apic_irq_attr(&attr, idx, line, it->trigger, it->polarity); - return io_apic_setup_irq_pin_once(*out_hwirq, cpu_to_node(0), &attr); + rc = io_apic_setup_irq_pin_once(irq_find_mapping(domain, line), + cpu_to_node(0), &attr); + if (rc) + return rc; + + *out_hwirq = line; + *out_type = it->out_type; + return 0; } +const struct irq_domain_ops ioapic_irq_domain_ops = { + .xlate = ioapic_xlate, +}; + static void __init ioapic_add_ofnode(struct device_node *np) { struct resource r; @@ -399,13 +357,14 @@ static void __init ioapic_add_ofnode(struct device_node *np) for (i = 0; i < nr_ioapics; i++) { if (r.start == mpc_ioapic_addr(i)) { struct irq_domain *id; + struct mp_ioapic_gsi *gsi_cfg; + + gsi_cfg = mp_ioapic_gsi_routing(i); - id = kzalloc(sizeof(*id), GFP_KERNEL); + id = irq_domain_add_legacy(np, 32, gsi_cfg->gsi_base, 0, + &ioapic_irq_domain_ops, + (void*)i); BUG_ON(!id); - id->controller = np; - id->xlate = ioapic_xlate; - id->priv = (void *)i; - add_interrupt_host(id); return; } } diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index 54eaf96..01c2cf4 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -497,37 +497,22 @@ static void amba_device_release(struct device *dev) } /** - * amba_device_register - register an AMBA device - * @dev: AMBA device to register - * @parent: parent memory resource + * amba_device_add - add a previously allocated AMBA device structure + * @dev: AMBA device allocated by amba_device_alloc + * @parent: resource parent for this devices resources * - * Setup the AMBA device, reading the cell ID if present. - * Claim the resource, and register the AMBA device with - * the Linux device manager. + * Claim the resource, and read the device cell ID if not already + * initialized. Register the AMBA device with the Linux device + * manager. */ -int amba_device_register(struct amba_device *dev, struct resource *parent) +int amba_device_add(struct amba_device *dev, struct resource *parent) { u32 size; void __iomem *tmp; int i, ret; - device_initialize(&dev->dev); - - /* - * Copy from device_add - */ - if (dev->dev.init_name) { - dev_set_name(&dev->dev, "%s", dev->dev.init_name); - dev->dev.init_name = NULL; - } - - dev->dev.release = amba_device_release; - dev->dev.bus = &amba_bustype; - dev->dev.dma_mask = &dev->dma_mask; - dev->res.name = dev_name(&dev->dev); - - if (!dev->dev.coherent_dma_mask && dev->dma_mask) - dev_warn(&dev->dev, "coherent dma mask is unset\n"); + WARN_ON(dev->irq[0] == (unsigned int)-1); + WARN_ON(dev->irq[1] == (unsigned int)-1); ret = request_resource(parent, &dev->res); if (ret) @@ -582,9 +567,9 @@ int amba_device_register(struct amba_device *dev, struct resource *parent) if (ret) goto err_release; - if (dev->irq[0] != NO_IRQ) + if (dev->irq[0] && dev->irq[0] != NO_IRQ) ret = device_create_file(&dev->dev, &dev_attr_irq0); - if (ret == 0 && dev->irq[1] != NO_IRQ) + if (ret == 0 && dev->irq[1] && dev->irq[1] != NO_IRQ) ret = device_create_file(&dev->dev, &dev_attr_irq1); if (ret == 0) return ret; @@ -596,6 +581,74 @@ int amba_device_register(struct amba_device *dev, struct resource *parent) err_out: return ret; } +EXPORT_SYMBOL_GPL(amba_device_add); + +static void amba_device_initialize(struct amba_device *dev, const char *name) +{ + device_initialize(&dev->dev); + if (name) + dev_set_name(&dev->dev, "%s", name); + dev->dev.release = amba_device_release; + dev->dev.bus = &amba_bustype; + dev->dev.dma_mask = &dev->dma_mask; + dev->res.name = dev_name(&dev->dev); +} + +/** + * amba_device_alloc - allocate an AMBA device + * @name: sysfs name of the AMBA device + * @base: base of AMBA device + * @size: size of AMBA device + * + * Allocate and initialize an AMBA device structure. Returns %NULL + * on failure. + */ +struct amba_device *amba_device_alloc(const char *name, resource_size_t base, + size_t size) +{ + struct amba_device *dev; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (dev) { + amba_device_initialize(dev, name); + dev->res.start = base; + dev->res.end = base + size - 1; + dev->res.flags = IORESOURCE_MEM; + } + + return dev; +} +EXPORT_SYMBOL_GPL(amba_device_alloc); + +/** + * amba_device_register - register an AMBA device + * @dev: AMBA device to register + * @parent: parent memory resource + * + * Setup the AMBA device, reading the cell ID if present. + * Claim the resource, and register the AMBA device with + * the Linux device manager. + */ +int amba_device_register(struct amba_device *dev, struct resource *parent) +{ + amba_device_initialize(dev, dev->dev.init_name); + dev->dev.init_name = NULL; + + if (!dev->dev.coherent_dma_mask && dev->dma_mask) + dev_warn(&dev->dev, "coherent dma mask is unset\n"); + + return amba_device_add(dev, parent); +} + +/** + * amba_device_put - put an AMBA device + * @dev: AMBA device to put + */ +void amba_device_put(struct amba_device *dev) +{ + put_device(&dev->dev); +} +EXPORT_SYMBOL_GPL(amba_device_put); /** * amba_device_unregister - unregister an AMBA device diff --git a/drivers/clocksource/tcb_clksrc.c b/drivers/clocksource/tcb_clksrc.c index 55d0f95..32cb929 100644 --- a/drivers/clocksource/tcb_clksrc.c +++ b/drivers/clocksource/tcb_clksrc.c @@ -19,6 +19,8 @@ * - Two channels combine to create a free-running 32 bit counter * with a base rate of 5+ MHz, packaged as a clocksource (with * resolution better than 200 nsec). + * - Some chips support 32 bit counter. A single channel is used for + * this 32 bit free-running counter. the second channel is not used. * * - The third channel may be used to provide a 16-bit clockevent * source, used in either periodic or oneshot mode. This runs @@ -54,6 +56,11 @@ static cycle_t tc_get_cycles(struct clocksource *cs) return (upper << 16) | lower; } +static cycle_t tc_get_cycles32(struct clocksource *cs) +{ + return __raw_readl(tcaddr + ATMEL_TC_REG(0, CV)); +} + static struct clocksource clksrc = { .name = "tcb_clksrc", .rating = 200, @@ -209,6 +216,48 @@ static void __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx) #endif +static void __init tcb_setup_dual_chan(struct atmel_tc *tc, int mck_divisor_idx) +{ + /* channel 0: waveform mode, input mclk/8, clock TIOA0 on overflow */ + __raw_writel(mck_divisor_idx /* likely divide-by-8 */ + | ATMEL_TC_WAVE + | ATMEL_TC_WAVESEL_UP /* free-run */ + | ATMEL_TC_ACPA_SET /* TIOA0 rises at 0 */ + | ATMEL_TC_ACPC_CLEAR, /* (duty cycle 50%) */ + tcaddr + ATMEL_TC_REG(0, CMR)); + __raw_writel(0x0000, tcaddr + ATMEL_TC_REG(0, RA)); + __raw_writel(0x8000, tcaddr + ATMEL_TC_REG(0, RC)); + __raw_writel(0xff, tcaddr + ATMEL_TC_REG(0, IDR)); /* no irqs */ + __raw_writel(ATMEL_TC_CLKEN, tcaddr + ATMEL_TC_REG(0, CCR)); + + /* channel 1: waveform mode, input TIOA0 */ + __raw_writel(ATMEL_TC_XC1 /* input: TIOA0 */ + | ATMEL_TC_WAVE + | ATMEL_TC_WAVESEL_UP, /* free-run */ + tcaddr + ATMEL_TC_REG(1, CMR)); + __raw_writel(0xff, tcaddr + ATMEL_TC_REG(1, IDR)); /* no irqs */ + __raw_writel(ATMEL_TC_CLKEN, tcaddr + ATMEL_TC_REG(1, CCR)); + + /* chain channel 0 to channel 1*/ + __raw_writel(ATMEL_TC_TC1XC1S_TIOA0, tcaddr + ATMEL_TC_BMR); + /* then reset all the timers */ + __raw_writel(ATMEL_TC_SYNC, tcaddr + ATMEL_TC_BCR); +} + +static void __init tcb_setup_single_chan(struct atmel_tc *tc, int mck_divisor_idx) +{ + /* channel 0: waveform mode, input mclk/8 */ + __raw_writel(mck_divisor_idx /* likely divide-by-8 */ + | ATMEL_TC_WAVE + | ATMEL_TC_WAVESEL_UP, /* free-run */ + tcaddr + ATMEL_TC_REG(0, CMR)); + __raw_writel(0xff, tcaddr + ATMEL_TC_REG(0, IDR)); /* no irqs */ + __raw_writel(ATMEL_TC_CLKEN, tcaddr + ATMEL_TC_REG(0, CCR)); + + /* then reset all the timers */ + __raw_writel(ATMEL_TC_SYNC, tcaddr + ATMEL_TC_BCR); +} + static int __init tcb_clksrc_init(void) { static char bootinfo[] __initdata @@ -260,34 +309,19 @@ static int __init tcb_clksrc_init(void) divided_rate / 1000000, ((divided_rate + 500000) % 1000000) / 1000); - /* tclib will give us three clocks no matter what the - * underlying platform supports. - */ - clk_enable(tc->clk[1]); - - /* channel 0: waveform mode, input mclk/8, clock TIOA0 on overflow */ - __raw_writel(best_divisor_idx /* likely divide-by-8 */ - | ATMEL_TC_WAVE - | ATMEL_TC_WAVESEL_UP /* free-run */ - | ATMEL_TC_ACPA_SET /* TIOA0 rises at 0 */ - | ATMEL_TC_ACPC_CLEAR, /* (duty cycle 50%) */ - tcaddr + ATMEL_TC_REG(0, CMR)); - __raw_writel(0x0000, tcaddr + ATMEL_TC_REG(0, RA)); - __raw_writel(0x8000, tcaddr + ATMEL_TC_REG(0, RC)); - __raw_writel(0xff, tcaddr + ATMEL_TC_REG(0, IDR)); /* no irqs */ - __raw_writel(ATMEL_TC_CLKEN, tcaddr + ATMEL_TC_REG(0, CCR)); - - /* channel 1: waveform mode, input TIOA0 */ - __raw_writel(ATMEL_TC_XC1 /* input: TIOA0 */ - | ATMEL_TC_WAVE - | ATMEL_TC_WAVESEL_UP, /* free-run */ - tcaddr + ATMEL_TC_REG(1, CMR)); - __raw_writel(0xff, tcaddr + ATMEL_TC_REG(1, IDR)); /* no irqs */ - __raw_writel(ATMEL_TC_CLKEN, tcaddr + ATMEL_TC_REG(1, CCR)); - - /* chain channel 0 to channel 1, then reset all the timers */ - __raw_writel(ATMEL_TC_TC1XC1S_TIOA0, tcaddr + ATMEL_TC_BMR); - __raw_writel(ATMEL_TC_SYNC, tcaddr + ATMEL_TC_BCR); + if (tc->tcb_config && tc->tcb_config->counter_width == 32) { + /* use apropriate function to read 32 bit counter */ + clksrc.read = tc_get_cycles32; + /* setup ony channel 0 */ + tcb_setup_single_chan(tc, best_divisor_idx); + } else { + /* tclib will give us three clocks no matter what the + * underlying platform supports. + */ + clk_enable(tc->clk[1]); + /* setup both channel 0 & 1 */ + tcb_setup_dual_chan(tc, best_divisor_idx); + } /* and away we go! */ clocksource_register_hz(&clksrc, divided_rate); diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c index 5cd04b6..e6568c1 100644 --- a/drivers/gpio/gpio-mpc8xxx.c +++ b/drivers/gpio/gpio-mpc8xxx.c @@ -37,7 +37,7 @@ struct mpc8xxx_gpio_chip { * open drain mode safely */ u32 data; - struct irq_host *irq; + struct irq_domain *irq; void *of_dev_id_data; }; @@ -281,7 +281,7 @@ static struct irq_chip mpc8xxx_irq_chip = { .irq_set_type = mpc8xxx_irq_set_type, }; -static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq, +static int mpc8xxx_gpio_irq_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { struct mpc8xxx_gpio_chip *mpc8xxx_gc = h->host_data; @@ -296,24 +296,9 @@ static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq, return 0; } -static int mpc8xxx_gpio_irq_xlate(struct irq_host *h, struct device_node *ct, - const u32 *intspec, unsigned int intsize, - irq_hw_number_t *out_hwirq, - unsigned int *out_flags) - -{ - /* interrupt sense values coming from the device tree equal either - * EDGE_FALLING or EDGE_BOTH - */ - *out_hwirq = intspec[0]; - *out_flags = intspec[1]; - - return 0; -} - -static struct irq_host_ops mpc8xxx_gpio_irq_ops = { +static struct irq_domain_ops mpc8xxx_gpio_irq_ops = { .map = mpc8xxx_gpio_irq_map, - .xlate = mpc8xxx_gpio_irq_xlate, + .xlate = irq_domain_xlate_twocell, }; static struct of_device_id mpc8xxx_gpio_ids[] __initdata = { @@ -364,9 +349,8 @@ static void __init mpc8xxx_add_controller(struct device_node *np) if (hwirq == NO_IRQ) goto skip_irq; - mpc8xxx_gc->irq = - irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, MPC8XXX_GPIO_PINS, - &mpc8xxx_gpio_irq_ops, MPC8XXX_GPIO_PINS); + mpc8xxx_gc->irq = irq_domain_add_linear(np, MPC8XXX_GPIO_PINS, + &mpc8xxx_gpio_irq_ops, mpc8xxx_gc); if (!mpc8xxx_gc->irq) goto skip_irq; @@ -374,8 +358,6 @@ static void __init mpc8xxx_add_controller(struct device_node *np) if (id) mpc8xxx_gc->of_dev_id_data = id->data; - mpc8xxx_gc->irq->host_data = mpc8xxx_gc; - /* ack and mask all irqs */ out_be32(mm_gc->regs + GPIO_IER, 0xffffffff); out_be32(mm_gc->regs + GPIO_IMR, 0); diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index f147395..1489c35 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -201,6 +201,7 @@ config MENELAUS config TWL4030_CORE bool "Texas Instruments TWL4030/TWL5030/TWL6030/TPS659x0 Support" depends on I2C=y && GENERIC_HARDIRQS + select IRQ_DOMAIN help Say yes here if you have TWL4030 / TWL6030 family chip on your board. This core driver provides register access and IRQ handling diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index 8ce3959..4970d43 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -149,7 +149,7 @@ #define TWL_MODULE_LAST TWL4030_MODULE_LAST -#define TWL4030_NR_IRQS 8 +#define TWL4030_NR_IRQS 34 /* core:8, power:8, gpio: 18 */ #define TWL6030_NR_IRQS 20 /* Base Address defns for twl4030_map[] */ @@ -263,10 +263,6 @@ struct twl_client { static struct twl_client twl_modules[TWL_NUM_SLAVES]; -#ifdef CONFIG_IRQ_DOMAIN -static struct irq_domain domain; -#endif - /* mapping the module id to slave id and base address */ struct twl_mapping { unsigned char sid; /* Slave ID */ @@ -1227,14 +1223,8 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) pdata->irq_base = status; pdata->irq_end = pdata->irq_base + nr_irqs; - -#ifdef CONFIG_IRQ_DOMAIN - domain.irq_base = pdata->irq_base; - domain.nr_irq = nr_irqs; - domain.of_node = of_node_get(node); - domain.ops = &irq_domain_simple_ops; - irq_domain_add(&domain); -#endif + irq_domain_add_legacy(node, nr_irqs, pdata->irq_base, 0, + &irq_domain_simple_ops, NULL); if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) { dev_dbg(&client->dev, "can't talk I2C?\n"); @@ -1315,11 +1305,10 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) twl_i2c_write_u8(TWL4030_MODULE_INTBR, temp, REG_GPPUPDCTR1); } -#ifdef CONFIG_OF_DEVICE + status = -ENODEV; if (node) status = of_platform_populate(node, NULL, NULL, &client->dev); - else -#endif + if (status) status = add_children(pdata, id->driver_data); fail: diff --git a/drivers/misc/atmel_tclib.c b/drivers/misc/atmel_tclib.c index 4bcfc37..c8d8e38 100644 --- a/drivers/misc/atmel_tclib.c +++ b/drivers/misc/atmel_tclib.c @@ -6,12 +6,10 @@ #include <linux/ioport.h> #include <linux/kernel.h> #include <linux/platform_device.h> +#include <linux/module.h> #include <linux/slab.h> #include <linux/export.h> - -/* Number of bytes to reserve for the iomem resource */ -#define ATMEL_TC_IOMEM_SIZE 256 - +#include <linux/of.h> /* * This is a thin library to solve the problem of how to portably allocate @@ -48,10 +46,17 @@ struct atmel_tc *atmel_tc_alloc(unsigned block, const char *name) struct atmel_tc *tc; struct platform_device *pdev = NULL; struct resource *r; + size_t size; spin_lock(&tc_list_lock); list_for_each_entry(tc, &tc_list, node) { - if (tc->pdev->id == block) { + if (tc->pdev->dev.of_node) { + if (of_alias_get_id(tc->pdev->dev.of_node, "tcb") + == block) { + pdev = tc->pdev; + break; + } + } else if (tc->pdev->id == block) { pdev = tc->pdev; break; } @@ -61,11 +66,15 @@ struct atmel_tc *atmel_tc_alloc(unsigned block, const char *name) goto fail; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - r = request_mem_region(r->start, ATMEL_TC_IOMEM_SIZE, name); if (!r) goto fail; - tc->regs = ioremap(r->start, ATMEL_TC_IOMEM_SIZE); + size = resource_size(r); + r = request_mem_region(r->start, size, name); + if (!r) + goto fail; + + tc->regs = ioremap(r->start, size); if (!tc->regs) goto fail_ioremap; @@ -76,7 +85,7 @@ out: return tc; fail_ioremap: - release_mem_region(r->start, ATMEL_TC_IOMEM_SIZE); + release_mem_region(r->start, size); fail: tc = NULL; goto out; @@ -96,7 +105,7 @@ void atmel_tc_free(struct atmel_tc *tc) spin_lock(&tc_list_lock); if (tc->regs) { iounmap(tc->regs); - release_mem_region(tc->iomem->start, ATMEL_TC_IOMEM_SIZE); + release_mem_region(tc->iomem->start, resource_size(tc->iomem)); tc->regs = NULL; tc->iomem = NULL; } @@ -104,6 +113,30 @@ void atmel_tc_free(struct atmel_tc *tc) } EXPORT_SYMBOL_GPL(atmel_tc_free); +#if defined(CONFIG_OF) +static struct atmel_tcb_config tcb_rm9200_config = { + .counter_width = 16, +}; + +static struct atmel_tcb_config tcb_sam9x5_config = { + .counter_width = 32, +}; + +static const struct of_device_id atmel_tcb_dt_ids[] = { + { + .compatible = "atmel,at91rm9200-tcb", + .data = &tcb_rm9200_config, + }, { + .compatible = "atmel,at91sam9x5-tcb", + .data = &tcb_sam9x5_config, + }, { + /* sentinel */ + } +}; + +MODULE_DEVICE_TABLE(of, atmel_tcb_dt_ids); +#endif + static int __init tc_probe(struct platform_device *pdev) { struct atmel_tc *tc; @@ -129,6 +162,14 @@ static int __init tc_probe(struct platform_device *pdev) return -EINVAL; } + /* Now take SoC information if available */ + if (pdev->dev.of_node) { + const struct of_device_id *match; + match = of_match_node(atmel_tcb_dt_ids, pdev->dev.of_node); + if (match) + tc->tcb_config = match->data; + } + tc->clk[0] = clk; tc->clk[1] = clk_get(&pdev->dev, "t1_clk"); if (IS_ERR(tc->clk[1])) @@ -153,7 +194,10 @@ static int __init tc_probe(struct platform_device *pdev) } static struct platform_driver tc_driver = { - .driver.name = "atmel_tcb", + .driver = { + .name = "atmel_tcb", + .of_match_table = of_match_ptr(atmel_tcb_dt_ids), + }, }; static int __init tc_init(void) diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index 947faa5..efdb81d 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c @@ -86,7 +86,6 @@ static inline int at91mci_is_mci1rev2xx(void) { return ( cpu_is_at91sam9260() || cpu_is_at91sam9263() - || cpu_is_at91cap9() || cpu_is_at91sam9rl() || cpu_is_at91sam9g10() || cpu_is_at91sam9g20() diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 0d955ff..304f2f9 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -1325,7 +1325,7 @@ static int __devinit mmci_probe(struct amba_device *dev, if (ret) goto unmap; - if (dev->irq[1] == NO_IRQ) + if (dev->irq[1] == NO_IRQ || !dev->irq[1]) host->singleirq = true; else { ret = request_irq(dev->irq[1], mmci_pio_irq, IRQF_SHARED, diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c index 50e8e5e..7189adf 100644 --- a/drivers/net/phy/mdio-gpio.c +++ b/drivers/net/phy/mdio-gpio.c @@ -255,13 +255,13 @@ static inline int __init mdio_ofgpio_init(void) return platform_driver_register(&mdio_ofgpio_driver); } -static inline void __exit mdio_ofgpio_exit(void) +static inline void mdio_ofgpio_exit(void) { platform_driver_unregister(&mdio_ofgpio_driver); } #else static inline int __init mdio_ofgpio_init(void) { return 0; } -static inline void __exit mdio_ofgpio_exit(void) { } +static inline void mdio_ofgpio_exit(void) { } #endif /* CONFIG_OF_GPIO */ static struct platform_driver mdio_gpio_driver = { diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 63b3ec4..343ad29 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -55,7 +55,7 @@ EXPORT_SYMBOL(of_find_device_by_node); #include <asm/dcr.h> #endif -#if !defined(CONFIG_SPARC) +#ifdef CONFIG_OF_ADDRESS /* * The following routines scan a subtree and registers a device for * each applicable node. @@ -253,7 +253,7 @@ static struct amba_device *of_amba_device_create(struct device_node *node, if (!of_device_is_available(node)) return NULL; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = amba_device_alloc(NULL, 0, 0); if (!dev) return NULL; @@ -283,14 +283,14 @@ static struct amba_device *of_amba_device_create(struct device_node *node, if (ret) goto err_free; - ret = amba_device_register(dev, &iomem_resource); + ret = amba_device_add(dev, &iomem_resource); if (ret) goto err_free; return dev; err_free: - kfree(dev); + amba_device_put(dev); return NULL; } #else /* CONFIG_ARM_AMBA */ @@ -462,4 +462,4 @@ int of_platform_populate(struct device_node *root, of_node_put(root); return rc; } -#endif /* !CONFIG_SPARC */ +#endif /* CONFIG_OF_ADDRESS */ diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c index 4902206..1dd68f5 100644 --- a/drivers/pcmcia/at91_cf.c +++ b/drivers/pcmcia/at91_cf.c @@ -26,6 +26,7 @@ #include <mach/board.h> #include <mach/at91rm9200_mc.h> +#include <mach/at91_ramc.h> /* @@ -156,7 +157,7 @@ static int at91_cf_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io) /* * Use 16 bit accesses unless/until we need 8-bit i/o space. */ - csr = at91_sys_read(AT91_SMC_CSR(cf->board->chipselect)) & ~AT91_SMC_DBW; + csr = at91_ramc_read(0, AT91_SMC_CSR(cf->board->chipselect)) & ~AT91_SMC_DBW; /* * NOTE: this CF controller ignores IOIS16, so we can't really do @@ -175,7 +176,7 @@ static int at91_cf_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io) csr |= AT91_SMC_DBW_16; pr_debug("%s: 16bit i/o bus\n", driver_name); } - at91_sys_write(AT91_SMC_CSR(cf->board->chipselect), csr); + at91_ramc_write(0, AT91_SMC_CSR(cf->board->chipselect), csr); io->start = cf->socket.io_offset; io->stop = io->start + SZ_2K - 1; diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index ee3c122..729fb84 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c @@ -57,6 +57,7 @@ struct sam9_rtc { void __iomem *rtt; struct rtc_device *rtcdev; u32 imr; + void __iomem *gpbr; }; #define rtt_readl(rtc, field) \ @@ -65,9 +66,9 @@ struct sam9_rtc { __raw_writel((val), (rtc)->rtt + AT91_RTT_ ## field) #define gpbr_readl(rtc) \ - at91_sys_read(AT91_GPBR + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR) + __raw_readl((rtc)->gpbr) #define gpbr_writel(rtc, val) \ - at91_sys_write(AT91_GPBR + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR, (val)) + __raw_writel((val), (rtc)->gpbr) /* * Read current time and date in RTC @@ -287,16 +288,19 @@ static const struct rtc_class_ops at91_rtc_ops = { /* * Initialize and install RTC driver */ -static int __init at91_rtc_probe(struct platform_device *pdev) +static int __devinit at91_rtc_probe(struct platform_device *pdev) { - struct resource *r; + struct resource *r, *r_gpbr; struct sam9_rtc *rtc; int ret; u32 mr; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!r) + r_gpbr = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!r || !r_gpbr) { + dev_err(&pdev->dev, "need 2 ressources\n"); return -ENODEV; + } rtc = kzalloc(sizeof *rtc, GFP_KERNEL); if (!rtc) @@ -314,6 +318,13 @@ static int __init at91_rtc_probe(struct platform_device *pdev) goto fail; } + rtc->gpbr = ioremap(r_gpbr->start, resource_size(r_gpbr)); + if (!rtc->gpbr) { + dev_err(&pdev->dev, "failed to map gpbr registers, aborting.\n"); + ret = -ENOMEM; + goto fail_gpbr; + } + mr = rtt_readl(rtc, MR); /* unless RTT is counting at 1 Hz, re-initialize it */ @@ -340,7 +351,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev) if (ret) { dev_dbg(&pdev->dev, "can't share IRQ %d?\n", AT91_ID_SYS); rtc_device_unregister(rtc->rtcdev); - goto fail; + goto fail_register; } /* NOTE: sam9260 rev A silicon has a ROM bug which resets the @@ -356,6 +367,8 @@ static int __init at91_rtc_probe(struct platform_device *pdev) return 0; fail_register: + iounmap(rtc->gpbr); +fail_gpbr: iounmap(rtc->rtt); fail: platform_set_drvdata(pdev, NULL); @@ -366,7 +379,7 @@ fail: /* * Disable and remove the RTC driver */ -static int __exit at91_rtc_remove(struct platform_device *pdev) +static int __devexit at91_rtc_remove(struct platform_device *pdev) { struct sam9_rtc *rtc = platform_get_drvdata(pdev); u32 mr = rtt_readl(rtc, MR); @@ -377,6 +390,7 @@ static int __exit at91_rtc_remove(struct platform_device *pdev) rtc_device_unregister(rtc->rtcdev); + iounmap(rtc->gpbr); iounmap(rtc->rtt); platform_set_drvdata(pdev, NULL); kfree(rtc); @@ -440,63 +454,20 @@ static int at91_rtc_resume(struct platform_device *pdev) #endif static struct platform_driver at91_rtc_driver = { - .driver.name = "rtc-at91sam9", - .driver.owner = THIS_MODULE, - .remove = __exit_p(at91_rtc_remove), + .probe = at91_rtc_probe, + .remove = __devexit_p(at91_rtc_remove), .shutdown = at91_rtc_shutdown, .suspend = at91_rtc_suspend, .resume = at91_rtc_resume, + .driver = { + .name = "rtc-at91sam9", + .owner = THIS_MODULE, + }, }; -/* Chips can have more than one RTT module, and they can be used for more - * than just RTCs. So we can't just register as "the" RTT driver. - * - * A normal approach in such cases is to create a library to allocate and - * free the modules. Here we just use bus_find_device() as like such a - * library, binding directly ... no runtime "library" footprint is needed. - */ -static int __init at91_rtc_match(struct device *dev, void *v) -{ - struct platform_device *pdev = to_platform_device(dev); - int ret; - - /* continue searching if this isn't the RTT we need */ - if (strcmp("at91_rtt", pdev->name) != 0 - || pdev->id != CONFIG_RTC_DRV_AT91SAM9_RTT) - goto fail; - - /* else we found it ... but fail unless we can bind to the RTC driver */ - if (dev->driver) { - dev_dbg(dev, "busy, can't use as RTC!\n"); - goto fail; - } - dev->driver = &at91_rtc_driver.driver; - if (device_attach(dev) == 0) { - dev_dbg(dev, "can't attach RTC!\n"); - goto fail; - } - ret = at91_rtc_probe(pdev); - if (ret == 0) - return true; - - dev_dbg(dev, "RTC probe err %d!\n", ret); -fail: - return false; -} - static int __init at91_rtc_init(void) { - int status; - struct device *rtc; - - status = platform_driver_register(&at91_rtc_driver); - if (status) - return status; - rtc = bus_find_device(&platform_bus_type, NULL, - NULL, at91_rtc_match); - if (!rtc) - platform_driver_unregister(&at91_rtc_driver); - return rtc ? 0 : -ENODEV; + return platform_driver_register(&at91_rtc_driver); } module_init(at91_rtc_init); diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 10605ec..f9a6be7 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -1526,6 +1526,8 @@ void __init atmel_register_uart_fns(struct atmel_port_fns *fns) atmel_pops.set_wake = fns->set_wake; } +struct platform_device *atmel_default_console_device; /* the serial console device */ + #ifdef CONFIG_SERIAL_ATMEL_CONSOLE static void atmel_console_putchar(struct uart_port *port, int ch) { diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 7ecb68a..85ae4b4 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -137,7 +137,7 @@ choice config USB_AT91 tristate "Atmel AT91 USB Device Port" - depends on ARCH_AT91 && !ARCH_AT91SAM9RL && !ARCH_AT91CAP9 && !ARCH_AT91SAM9G45 + depends on ARCH_AT91 && !ARCH_AT91SAM9RL && !ARCH_AT91SAM9G45 help Many Atmel AT91 processors (such as the AT91RM2000) have a full speed USB Device Port with support for five configurable @@ -150,7 +150,7 @@ config USB_AT91 config USB_ATMEL_USBA tristate "Atmel USBA" select USB_GADGET_DUALSPEED - depends on AVR32 || ARCH_AT91CAP9 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 + depends on AVR32 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 help USBA is the integrated high-speed USB Device controller on the AT32AP700x, some AT91SAM9 and AT91CAP9 processors from Atmel. diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 143a725..f99b3dc 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -41,6 +41,7 @@ #include <mach/board.h> #include <mach/cpu.h> #include <mach/at91sam9261_matrix.h> +#include <mach/at91_matrix.h> #include "at91_udc.h" @@ -910,9 +911,9 @@ static void pullup(struct at91_udc *udc, int is_on) } else if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()) { u32 usbpucr; - usbpucr = at91_sys_read(AT91_MATRIX_USBPUCR); + usbpucr = at91_matrix_read(AT91_MATRIX_USBPUCR); usbpucr |= AT91_MATRIX_USBPUCR_PUON; - at91_sys_write(AT91_MATRIX_USBPUCR, usbpucr); + at91_matrix_write(AT91_MATRIX_USBPUCR, usbpucr); } } else { stop_activity(udc); @@ -928,9 +929,9 @@ static void pullup(struct at91_udc *udc, int is_on) } else if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()) { u32 usbpucr; - usbpucr = at91_sys_read(AT91_MATRIX_USBPUCR); + usbpucr = at91_matrix_read(AT91_MATRIX_USBPUCR); usbpucr &= ~AT91_MATRIX_USBPUCR_PUON; - at91_sys_write(AT91_MATRIX_USBPUCR, usbpucr); + at91_matrix_write(AT91_MATRIX_USBPUCR, usbpucr); } clk_off(udc); } diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index e2fb6d5..ce9dffb 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c @@ -332,12 +332,12 @@ static int vbus_is_present(struct usba_udc *udc) static void toggle_bias(int is_on) { - unsigned int uckr = at91_sys_read(AT91_CKGR_UCKR); + unsigned int uckr = at91_pmc_read(AT91_CKGR_UCKR); if (is_on) - at91_sys_write(AT91_CKGR_UCKR, uckr | AT91_PMC_BIASEN); + at91_pmc_write(AT91_CKGR_UCKR, uckr | AT91_PMC_BIASEN); else - at91_sys_write(AT91_CKGR_UCKR, uckr & ~(AT91_PMC_BIASEN)); + at91_pmc_write(AT91_CKGR_UCKR, uckr & ~(AT91_PMC_BIASEN)); } #else diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index 77afabc..8e855eb 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -448,10 +448,11 @@ static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data) /* From the GPIO notifying the over-current situation, find * out the corresponding port */ - gpio = irq_to_gpio(irq); for (port = 0; port < ARRAY_SIZE(pdata->overcurrent_pin); port++) { - if (pdata->overcurrent_pin[port] == gpio) + if (gpio_to_irq(pdata->overcurrent_pin[port]) == irq) { + gpio = pdata->overcurrent_pin[port]; break; + } } if (port == ARRAY_SIZE(pdata->overcurrent_pin)) { diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c index b3046dc..7ceefd2 100644 --- a/drivers/watchdog/at91rm9200_wdt.c +++ b/drivers/watchdog/at91rm9200_wdt.c @@ -51,7 +51,7 @@ static unsigned long at91wdt_busy; */ static inline void at91_wdt_stop(void) { - at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN); + at91_st_write(AT91_ST_WDMR, AT91_ST_EXTEN); } /* @@ -59,9 +59,9 @@ static inline void at91_wdt_stop(void) */ static inline void at91_wdt_start(void) { - at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN | AT91_ST_RSTEN | + at91_st_write(AT91_ST_WDMR, AT91_ST_EXTEN | AT91_ST_RSTEN | (((65536 * wdt_time) >> 8) & AT91_ST_WDV)); - at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); + at91_st_write(AT91_ST_CR, AT91_ST_WDRST); } /* @@ -69,7 +69,7 @@ static inline void at91_wdt_start(void) */ static inline void at91_wdt_reload(void) { - at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); + at91_st_write(AT91_ST_CR, AT91_ST_WDRST); } /* ......................................................................... */ diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h index 724c69c..a9fab83 100644 --- a/include/linux/amba/bus.h +++ b/include/linux/amba/bus.h @@ -60,6 +60,9 @@ extern struct bus_type amba_bustype; int amba_driver_register(struct amba_driver *); void amba_driver_unregister(struct amba_driver *); +struct amba_device *amba_device_alloc(const char *, resource_size_t, size_t); +void amba_device_put(struct amba_device *); +int amba_device_add(struct amba_device *, struct resource *); int amba_device_register(struct amba_device *, struct resource *); void amba_device_unregister(struct amba_device *); struct amba_device *amba_find_device(const char *, struct device *, unsigned int, unsigned int); @@ -89,4 +92,37 @@ void amba_release_regions(struct amba_device *); #define amba_manf(d) AMBA_MANF_BITS((d)->periphid) #define amba_part(d) AMBA_PART_BITS((d)->periphid) +#define __AMBA_DEV(busid, data, mask) \ + { \ + .coherent_dma_mask = mask, \ + .init_name = busid, \ + .platform_data = data, \ + } + +/* + * APB devices do not themselves have the ability to address memory, + * so DMA masks should be zero (much like USB peripheral devices.) + * The DMA controller DMA masks should be used instead (much like + * USB host controllers in conventional PCs.) + */ +#define AMBA_APB_DEVICE(name, busid, id, base, irqs, data) \ +struct amba_device name##_device = { \ + .dev = __AMBA_DEV(busid, data, 0), \ + .res = DEFINE_RES_MEM(base, SZ_4K), \ + .irq = irqs, \ + .periphid = id, \ +} + +/* + * AHB devices are DMA capable, so set their DMA masks + */ +#define AMBA_AHB_DEVICE(name, busid, id, base, irqs, data) \ +struct amba_device name##_device = { \ + .dev = __AMBA_DEV(busid, data, ~0ULL), \ + .res = DEFINE_RES_MEM(base, SZ_4K), \ + .dma_mask = ~0ULL, \ + .irq = irqs, \ + .periphid = id, \ +} + #endif diff --git a/include/linux/atmel_tc.h b/include/linux/atmel_tc.h index 53ba65e..1d14b1dc 100644 --- a/include/linux/atmel_tc.h +++ b/include/linux/atmel_tc.h @@ -34,10 +34,19 @@ struct clk; /** + * struct atmel_tcb_config - SoC data for a Timer/Counter Block + * @counter_width: size in bits of a timer counter register + */ +struct atmel_tcb_config { + size_t counter_width; +}; + +/** * struct atmel_tc - information about a Timer/Counter Block * @pdev: physical device * @iomem: resource associated with the I/O register * @regs: mapping through which the I/O registers can be accessed + * @tcb_config: configuration data from SoC * @irq: irq for each of the three channels * @clk: internal clock source for each of the three channels * @node: list node, for tclib internal use @@ -54,6 +63,7 @@ struct atmel_tc { struct platform_device *pdev; struct resource *iomem; void __iomem *regs; + struct atmel_tcb_config *tcb_config; int irq[3]; struct clk *clk[3]; struct list_head node; diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index bd4272b..ead4a42 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h @@ -9,99 +9,182 @@ * representation into a hardware irq number that can be mapped back to a * Linux irq number without any extra platform support code. * - * irq_domain is expected to be embedded in an interrupt controller's private - * data structure. + * Interrupt controller "domain" data structure. This could be defined as a + * irq domain controller. That is, it handles the mapping between hardware + * and virtual interrupt numbers for a given interrupt domain. The domain + * structure is generally created by the PIC code for a given PIC instance + * (though a domain can cover more than one PIC if they have a flat number + * model). It's the domain callbacks that are responsible for setting the + * irq_chip on a given irq_desc after it's been mapped. + * + * The host code and data structures are agnostic to whether or not + * we use an open firmware device-tree. We do have references to struct + * device_node in two places: in irq_find_host() to find the host matching + * a given interrupt controller node, and of course as an argument to its + * counterpart domain->ops->match() callback. However, those are treated as + * generic pointers by the core and the fact that it's actually a device-node + * pointer is purely a convention between callers and implementation. This + * code could thus be used on other architectures by replacing those two + * by some sort of arch-specific void * "token" used to identify interrupt + * controllers. */ + #ifndef _LINUX_IRQDOMAIN_H #define _LINUX_IRQDOMAIN_H -#include <linux/irq.h> -#include <linux/mod_devicetable.h> +#include <linux/types.h> +#include <linux/radix-tree.h> -#ifdef CONFIG_IRQ_DOMAIN struct device_node; struct irq_domain; +struct of_device_id; + +/* Number of irqs reserved for a legacy isa controller */ +#define NUM_ISA_INTERRUPTS 16 + +/* This type is the placeholder for a hardware interrupt number. It has to + * be big enough to enclose whatever representation is used by a given + * platform. + */ +typedef unsigned long irq_hw_number_t; /** * struct irq_domain_ops - Methods for irq_domain objects - * @to_irq: (optional) given a local hardware irq number, return the linux - * irq number. If to_irq is not implemented, then the irq_domain - * will use this translation: irq = (domain->irq_base + hwirq) - * @dt_translate: Given a device tree node and interrupt specifier, decode - * the hardware irq number and linux irq type value. + * @match: Match an interrupt controller device node to a host, returns + * 1 on a match + * @map: Create or update a mapping between a virtual irq number and a hw + * irq number. This is called only once for a given mapping. + * @unmap: Dispose of such a mapping + * @xlate: Given a device tree node and interrupt specifier, decode + * the hardware irq number and linux irq type value. + * + * Functions below are provided by the driver and called whenever a new mapping + * is created or an old mapping is disposed. The driver can then proceed to + * whatever internal data structures management is required. It also needs + * to setup the irq_desc when returning from map(). */ struct irq_domain_ops { - unsigned int (*to_irq)(struct irq_domain *d, unsigned long hwirq); - -#ifdef CONFIG_OF - int (*dt_translate)(struct irq_domain *d, struct device_node *node, - const u32 *intspec, unsigned int intsize, - unsigned long *out_hwirq, unsigned int *out_type); -#endif /* CONFIG_OF */ + int (*match)(struct irq_domain *d, struct device_node *node); + int (*map)(struct irq_domain *d, unsigned int virq, irq_hw_number_t hw); + void (*unmap)(struct irq_domain *d, unsigned int virq); + int (*xlate)(struct irq_domain *d, struct device_node *node, + const u32 *intspec, unsigned int intsize, + unsigned long *out_hwirq, unsigned int *out_type); }; /** * struct irq_domain - Hardware interrupt number translation object - * @list: Element in global irq_domain list. + * @link: Element in global irq_domain list. + * @revmap_type: Method used for reverse mapping hwirq numbers to linux irq. This + * will be one of the IRQ_DOMAIN_MAP_* values. + * @revmap_data: Revmap method specific data. + * @ops: pointer to irq_domain methods + * @host_data: private data pointer for use by owner. Not touched by irq_domain + * core code. * @irq_base: Start of irq_desc range assigned to the irq_domain. The creator * of the irq_domain is responsible for allocating the array of * irq_desc structures. * @nr_irq: Number of irqs managed by the irq domain * @hwirq_base: Starting number for hwirqs managed by the irq domain - * @ops: pointer to irq_domain methods - * @priv: private data pointer for use by owner. Not touched by irq_domain - * core code. * @of_node: (optional) Pointer to device tree nodes associated with the * irq_domain. Used when decoding device tree interrupt specifiers. */ struct irq_domain { - struct list_head list; - unsigned int irq_base; - unsigned int nr_irq; - unsigned int hwirq_base; + struct list_head link; + + /* type of reverse mapping_technique */ + unsigned int revmap_type; + union { + struct { + unsigned int size; + unsigned int first_irq; + irq_hw_number_t first_hwirq; + } legacy; + struct { + unsigned int size; + unsigned int *revmap; + } linear; + struct radix_tree_root tree; + } revmap_data; const struct irq_domain_ops *ops; - void *priv; + void *host_data; + irq_hw_number_t inval_irq; + + /* Optional device node pointer */ struct device_node *of_node; }; -/** - * irq_domain_to_irq() - Translate from a hardware irq to a linux irq number - * - * Returns the linux irq number associated with a hardware irq. By default, - * the mapping is irq == domain->irq_base + hwirq, but this mapping can - * be overridden if the irq_domain implements a .to_irq() hook. - */ -static inline unsigned int irq_domain_to_irq(struct irq_domain *d, - unsigned long hwirq) +#ifdef CONFIG_IRQ_DOMAIN +struct irq_domain *irq_domain_add_legacy(struct device_node *of_node, + unsigned int size, + unsigned int first_irq, + irq_hw_number_t first_hwirq, + const struct irq_domain_ops *ops, + void *host_data); +struct irq_domain *irq_domain_add_linear(struct device_node *of_node, + unsigned int size, + const struct irq_domain_ops *ops, + void *host_data); +struct irq_domain *irq_domain_add_nomap(struct device_node *of_node, + const struct irq_domain_ops *ops, + void *host_data); +struct irq_domain *irq_domain_add_tree(struct device_node *of_node, + const struct irq_domain_ops *ops, + void *host_data); + +extern struct irq_domain *irq_find_host(struct device_node *node); +extern void irq_set_default_host(struct irq_domain *host); +extern void irq_set_virq_count(unsigned int count); + +static inline struct irq_domain *irq_domain_add_legacy_isa( + struct device_node *of_node, + const struct irq_domain_ops *ops, + void *host_data) { - if (d->ops->to_irq) - return d->ops->to_irq(d, hwirq); - if (WARN_ON(hwirq < d->hwirq_base)) - return 0; - return d->irq_base + hwirq - d->hwirq_base; + return irq_domain_add_legacy(of_node, NUM_ISA_INTERRUPTS, 0, 0, ops, + host_data); } +extern struct irq_domain *irq_find_host(struct device_node *node); +extern void irq_set_default_host(struct irq_domain *host); +extern void irq_set_virq_count(unsigned int count); -#define irq_domain_for_each_hwirq(d, hw) \ - for (hw = d->hwirq_base; hw < d->hwirq_base + d->nr_irq; hw++) -#define irq_domain_for_each_irq(d, hw, irq) \ - for (hw = d->hwirq_base, irq = irq_domain_to_irq(d, hw); \ - hw < d->hwirq_base + d->nr_irq; \ - hw++, irq = irq_domain_to_irq(d, hw)) +extern unsigned int irq_create_mapping(struct irq_domain *host, + irq_hw_number_t hwirq); +extern void irq_dispose_mapping(unsigned int virq); +extern unsigned int irq_find_mapping(struct irq_domain *host, + irq_hw_number_t hwirq); +extern unsigned int irq_create_direct_mapping(struct irq_domain *host); +extern void irq_radix_revmap_insert(struct irq_domain *host, unsigned int virq, + irq_hw_number_t hwirq); +extern unsigned int irq_radix_revmap_lookup(struct irq_domain *host, + irq_hw_number_t hwirq); +extern unsigned int irq_linear_revmap(struct irq_domain *host, + irq_hw_number_t hwirq); -extern void irq_domain_add(struct irq_domain *domain); -extern void irq_domain_del(struct irq_domain *domain); +extern const struct irq_domain_ops irq_domain_simple_ops; -extern struct irq_domain_ops irq_domain_simple_ops; -#endif /* CONFIG_IRQ_DOMAIN */ +/* stock xlate functions */ +int irq_domain_xlate_onecell(struct irq_domain *d, struct device_node *ctrlr, + const u32 *intspec, unsigned int intsize, + irq_hw_number_t *out_hwirq, unsigned int *out_type); +int irq_domain_xlate_twocell(struct irq_domain *d, struct device_node *ctrlr, + const u32 *intspec, unsigned int intsize, + irq_hw_number_t *out_hwirq, unsigned int *out_type); +int irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr, + const u32 *intspec, unsigned int intsize, + irq_hw_number_t *out_hwirq, unsigned int *out_type); -#if defined(CONFIG_IRQ_DOMAIN) && defined(CONFIG_OF_IRQ) -extern void irq_domain_add_simple(struct device_node *controller, int irq_base); +#if defined(CONFIG_OF_IRQ) extern void irq_domain_generate_simple(const struct of_device_id *match, u64 phys_base, unsigned int irq_start); -#else /* CONFIG_IRQ_DOMAIN && CONFIG_OF_IRQ */ +#else /* CONFIG_OF_IRQ */ static inline void irq_domain_generate_simple(const struct of_device_id *match, u64 phys_base, unsigned int irq_start) { } -#endif /* CONFIG_IRQ_DOMAIN && CONFIG_OF_IRQ */ +#endif /* !CONFIG_OF_IRQ */ + +#else /* CONFIG_IRQ_DOMAIN */ +static inline void irq_dispose_mapping(unsigned int virq) { } +#endif /* !CONFIG_IRQ_DOMAIN */ #endif /* _LINUX_IRQDOMAIN_H */ diff --git a/include/linux/of_address.h b/include/linux/of_address.h index 3118623..01b925a 100644 --- a/include/linux/of_address.h +++ b/include/linux/of_address.h @@ -4,6 +4,7 @@ #include <linux/errno.h> #include <linux/of.h> +#ifdef CONFIG_OF_ADDRESS extern u64 of_translate_address(struct device_node *np, const __be32 *addr); extern int of_address_to_resource(struct device_node *dev, int index, struct resource *r); @@ -25,12 +26,37 @@ static inline unsigned long pci_address_to_pio(phys_addr_t addr) { return -1; } #define pci_address_to_pio pci_address_to_pio #endif -#ifdef CONFIG_PCI +#else /* CONFIG_OF_ADDRESS */ +static inline int of_address_to_resource(struct device_node *dev, int index, + struct resource *r) +{ + return -EINVAL; +} +static inline struct device_node *of_find_matching_node_by_address( + struct device_node *from, + const struct of_device_id *matches, + u64 base_address) +{ + return NULL; +} +static inline void __iomem *of_iomap(struct device_node *device, int index) +{ + return NULL; +} +static inline const u32 *of_get_address(struct device_node *dev, int index, + u64 *size, unsigned int *flags) +{ + return NULL; +} +#endif /* CONFIG_OF_ADDRESS */ + + +#if defined(CONFIG_OF_ADDRESS) && defined(CONFIG_PCI) extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, unsigned int *flags); extern int of_pci_address_to_resource(struct device_node *dev, int bar, struct resource *r); -#else /* CONFIG_PCI */ +#else /* CONFIG_OF_ADDRESS && CONFIG_PCI */ static inline int of_pci_address_to_resource(struct device_node *dev, int bar, struct resource *r) { @@ -42,8 +68,7 @@ static inline const __be32 *of_get_pci_address(struct device_node *dev, { return NULL; } -#endif /* CONFIG_PCI */ - +#endif /* CONFIG_OF_ADDRESS && CONFIG_PCI */ #endif /* __OF_ADDRESS_H */ diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h index d0307ee..d229ad3 100644 --- a/include/linux/of_irq.h +++ b/include/linux/of_irq.h @@ -6,6 +6,7 @@ struct of_irq; #include <linux/types.h> #include <linux/errno.h> #include <linux/irq.h> +#include <linux/irqdomain.h> #include <linux/ioport.h> #include <linux/of.h> @@ -65,9 +66,6 @@ extern int of_irq_map_one(struct device_node *device, int index, extern unsigned int irq_create_of_mapping(struct device_node *controller, const u32 *intspec, unsigned int intsize); -#ifdef CONFIG_IRQ_DOMAIN -extern void irq_dispose_mapping(unsigned int irq); -#endif extern int of_irq_to_resource(struct device_node *dev, int index, struct resource *r); extern int of_irq_count(struct device_node *dev); diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h index 040ce2f..242fa35 100644 --- a/include/linux/of_platform.h +++ b/include/linux/of_platform.h @@ -81,7 +81,7 @@ extern struct platform_device *of_device_alloc(struct device_node *np, struct device *parent); extern struct platform_device *of_find_device_by_node(struct device_node *np); -#if !defined(CONFIG_SPARC) /* SPARC has its own device registration method */ +#ifdef CONFIG_OF_ADDRESS /* device reg helpers depend on OF_ADDRESS */ /* Platform devices and busses creation */ extern struct platform_device *of_platform_device_create(struct device_node *np, const char *bus_id, @@ -94,7 +94,15 @@ extern int of_platform_populate(struct device_node *root, const struct of_device_id *matches, const struct of_dev_auxdata *lookup, struct device *parent); -#endif /* !CONFIG_SPARC */ +#else +static inline int of_platform_populate(struct device_node *root, + const struct of_device_id *matches, + const struct of_dev_auxdata *lookup, + struct device *parent) +{ + return -ENODEV; +} +#endif /* !CONFIG_OF_ADDRESS */ #endif /* CONFIG_OF_DEVICE */ diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index 1f9e265..af48e59 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -1,189 +1,793 @@ +#include <linux/debugfs.h> +#include <linux/hardirq.h> +#include <linux/interrupt.h> #include <linux/irq.h> +#include <linux/irqdesc.h> #include <linux/irqdomain.h> #include <linux/module.h> #include <linux/mutex.h> #include <linux/of.h> #include <linux/of_address.h> +#include <linux/seq_file.h> #include <linux/slab.h> +#include <linux/smp.h> +#include <linux/fs.h> + +#define IRQ_DOMAIN_MAP_LEGACY 0 /* driver allocated fixed range of irqs. + * ie. legacy 8259, gets irqs 1..15 */ +#define IRQ_DOMAIN_MAP_NOMAP 1 /* no fast reverse mapping */ +#define IRQ_DOMAIN_MAP_LINEAR 2 /* linear map of interrupts */ +#define IRQ_DOMAIN_MAP_TREE 3 /* radix tree */ static LIST_HEAD(irq_domain_list); static DEFINE_MUTEX(irq_domain_mutex); +static DEFINE_MUTEX(revmap_trees_mutex); +static unsigned int irq_virq_count = NR_IRQS; +static struct irq_domain *irq_default_domain; + /** - * irq_domain_add() - Register an irq_domain - * @domain: ptr to initialized irq_domain structure + * irq_domain_alloc() - Allocate a new irq_domain data structure + * @of_node: optional device-tree node of the interrupt controller + * @revmap_type: type of reverse mapping to use + * @ops: map/unmap domain callbacks + * @host_data: Controller private data pointer * - * Registers an irq_domain structure. The irq_domain must at a minimum be - * initialized with an ops structure pointer, and either a ->to_irq hook or - * a valid irq_base value. Everything else is optional. + * Allocates and initialize and irq_domain structure. Caller is expected to + * register allocated irq_domain with irq_domain_register(). Returns pointer + * to IRQ domain, or NULL on failure. */ -void irq_domain_add(struct irq_domain *domain) +static struct irq_domain *irq_domain_alloc(struct device_node *of_node, + unsigned int revmap_type, + const struct irq_domain_ops *ops, + void *host_data) { - struct irq_data *d; - int hwirq, irq; + struct irq_domain *domain; - /* - * This assumes that the irq_domain owner has already allocated - * the irq_descs. This block will be removed when support for dynamic - * allocation of irq_descs is added to irq_domain. - */ - irq_domain_for_each_irq(domain, hwirq, irq) { - d = irq_get_irq_data(irq); - if (!d) { - WARN(1, "error: assigning domain to non existant irq_desc"); - return; - } - if (d->domain) { - /* things are broken; just report, don't clean up */ - WARN(1, "error: irq_desc already assigned to a domain"); - return; + domain = kzalloc(sizeof(*domain), GFP_KERNEL); + if (WARN_ON(!domain)) + return NULL; + + /* Fill structure */ + domain->revmap_type = revmap_type; + domain->ops = ops; + domain->host_data = host_data; + domain->of_node = of_node_get(of_node); + + return domain; +} + +static void irq_domain_add(struct irq_domain *domain) +{ + mutex_lock(&irq_domain_mutex); + list_add(&domain->link, &irq_domain_list); + mutex_unlock(&irq_domain_mutex); + pr_debug("irq: Allocated domain of type %d @0x%p\n", + domain->revmap_type, domain); +} + +static unsigned int irq_domain_legacy_revmap(struct irq_domain *domain, + irq_hw_number_t hwirq) +{ + irq_hw_number_t first_hwirq = domain->revmap_data.legacy.first_hwirq; + int size = domain->revmap_data.legacy.size; + + if (WARN_ON(hwirq < first_hwirq || hwirq >= first_hwirq + size)) + return 0; + return hwirq - first_hwirq + domain->revmap_data.legacy.first_irq; +} + +/** + * irq_domain_add_legacy() - Allocate and register a legacy revmap irq_domain. + * @of_node: pointer to interrupt controller's device tree node. + * @size: total number of irqs in legacy mapping + * @first_irq: first number of irq block assigned to the domain + * @first_hwirq: first hwirq number to use for the translation. Should normally + * be '0', but a positive integer can be used if the effective + * hwirqs numbering does not begin at zero. + * @ops: map/unmap domain callbacks + * @host_data: Controller private data pointer + * + * Note: the map() callback will be called before this function returns + * for all legacy interrupts except 0 (which is always the invalid irq for + * a legacy controller). + */ +struct irq_domain *irq_domain_add_legacy(struct device_node *of_node, + unsigned int size, + unsigned int first_irq, + irq_hw_number_t first_hwirq, + const struct irq_domain_ops *ops, + void *host_data) +{ + struct irq_domain *domain; + unsigned int i; + + domain = irq_domain_alloc(of_node, IRQ_DOMAIN_MAP_LEGACY, ops, host_data); + if (!domain) + return NULL; + + domain->revmap_data.legacy.first_irq = first_irq; + domain->revmap_data.legacy.first_hwirq = first_hwirq; + domain->revmap_data.legacy.size = size; + + mutex_lock(&irq_domain_mutex); + /* Verify that all the irqs are available */ + for (i = 0; i < size; i++) { + int irq = first_irq + i; + struct irq_data *irq_data = irq_get_irq_data(irq); + + if (WARN_ON(!irq_data || irq_data->domain)) { + mutex_unlock(&irq_domain_mutex); + of_node_put(domain->of_node); + kfree(domain); + return NULL; } - d->domain = domain; - d->hwirq = hwirq; } - mutex_lock(&irq_domain_mutex); - list_add(&domain->list, &irq_domain_list); + /* Claim all of the irqs before registering a legacy domain */ + for (i = 0; i < size; i++) { + struct irq_data *irq_data = irq_get_irq_data(first_irq + i); + irq_data->hwirq = first_hwirq + i; + irq_data->domain = domain; + } mutex_unlock(&irq_domain_mutex); + + for (i = 0; i < size; i++) { + int irq = first_irq + i; + int hwirq = first_hwirq + i; + + /* IRQ0 gets ignored */ + if (!irq) + continue; + + /* Legacy flags are left to default at this point, + * one can then use irq_create_mapping() to + * explicitly change them + */ + ops->map(domain, irq, hwirq); + + /* Clear norequest flags */ + irq_clear_status_flags(irq, IRQ_NOREQUEST); + } + + irq_domain_add(domain); + return domain; +} + +/** + * irq_domain_add_linear() - Allocate and register a legacy revmap irq_domain. + * @of_node: pointer to interrupt controller's device tree node. + * @ops: map/unmap domain callbacks + * @host_data: Controller private data pointer + */ +struct irq_domain *irq_domain_add_linear(struct device_node *of_node, + unsigned int size, + const struct irq_domain_ops *ops, + void *host_data) +{ + struct irq_domain *domain; + unsigned int *revmap; + + revmap = kzalloc(sizeof(*revmap) * size, GFP_KERNEL); + if (WARN_ON(!revmap)) + return NULL; + + domain = irq_domain_alloc(of_node, IRQ_DOMAIN_MAP_LINEAR, ops, host_data); + if (!domain) { + kfree(revmap); + return NULL; + } + domain->revmap_data.linear.size = size; + domain->revmap_data.linear.revmap = revmap; + irq_domain_add(domain); + return domain; +} + +struct irq_domain *irq_domain_add_nomap(struct device_node *of_node, + const struct irq_domain_ops *ops, + void *host_data) +{ + struct irq_domain *domain = irq_domain_alloc(of_node, + IRQ_DOMAIN_MAP_NOMAP, ops, host_data); + if (domain) + irq_domain_add(domain); + return domain; +} + +/** + * irq_domain_add_tree() + * @of_node: pointer to interrupt controller's device tree node. + * @ops: map/unmap domain callbacks + * + * Note: The radix tree will be allocated later during boot automatically + * (the reverse mapping will use the slow path until that happens). + */ +struct irq_domain *irq_domain_add_tree(struct device_node *of_node, + const struct irq_domain_ops *ops, + void *host_data) +{ + struct irq_domain *domain = irq_domain_alloc(of_node, + IRQ_DOMAIN_MAP_TREE, ops, host_data); + if (domain) { + INIT_RADIX_TREE(&domain->revmap_data.tree, GFP_KERNEL); + irq_domain_add(domain); + } + return domain; } /** - * irq_domain_del() - Unregister an irq_domain - * @domain: ptr to registered irq_domain. + * irq_find_host() - Locates a domain for a given device node + * @node: device-tree node of the interrupt controller */ -void irq_domain_del(struct irq_domain *domain) +struct irq_domain *irq_find_host(struct device_node *node) { - struct irq_data *d; - int hwirq, irq; + struct irq_domain *h, *found = NULL; + int rc; + /* We might want to match the legacy controller last since + * it might potentially be set to match all interrupts in + * the absence of a device node. This isn't a problem so far + * yet though... + */ mutex_lock(&irq_domain_mutex); - list_del(&domain->list); + list_for_each_entry(h, &irq_domain_list, link) { + if (h->ops->match) + rc = h->ops->match(h, node); + else + rc = (h->of_node != NULL) && (h->of_node == node); + + if (rc) { + found = h; + break; + } + } mutex_unlock(&irq_domain_mutex); + return found; +} +EXPORT_SYMBOL_GPL(irq_find_host); + +/** + * irq_set_default_host() - Set a "default" irq domain + * @domain: default domain pointer + * + * For convenience, it's possible to set a "default" domain that will be used + * whenever NULL is passed to irq_create_mapping(). It makes life easier for + * platforms that want to manipulate a few hard coded interrupt numbers that + * aren't properly represented in the device-tree. + */ +void irq_set_default_host(struct irq_domain *domain) +{ + pr_debug("irq: Default domain set to @0x%p\n", domain); + + irq_default_domain = domain; +} + +/** + * irq_set_virq_count() - Set the maximum number of linux irqs + * @count: number of linux irqs, capped with NR_IRQS + * + * This is mainly for use by platforms like iSeries who want to program + * the virtual irq number in the controller to avoid the reverse mapping + */ +void irq_set_virq_count(unsigned int count) +{ + pr_debug("irq: Trying to set virq count to %d\n", count); - /* Clear the irq_domain assignments */ - irq_domain_for_each_irq(domain, hwirq, irq) { - d = irq_get_irq_data(irq); - d->domain = NULL; + BUG_ON(count < NUM_ISA_INTERRUPTS); + if (count < NR_IRQS) + irq_virq_count = count; +} + +static int irq_setup_virq(struct irq_domain *domain, unsigned int virq, + irq_hw_number_t hwirq) +{ + struct irq_data *irq_data = irq_get_irq_data(virq); + + irq_data->hwirq = hwirq; + irq_data->domain = domain; + if (domain->ops->map(domain, virq, hwirq)) { + pr_debug("irq: -> mapping failed, freeing\n"); + irq_data->domain = NULL; + irq_data->hwirq = 0; + return -1; } + + irq_clear_status_flags(virq, IRQ_NOREQUEST); + + return 0; } -#if defined(CONFIG_OF_IRQ) /** - * irq_create_of_mapping() - Map a linux irq number from a DT interrupt spec + * irq_create_direct_mapping() - Allocate an irq for direct mapping + * @domain: domain to allocate the irq for or NULL for default domain * - * Used by the device tree interrupt mapping code to translate a device tree - * interrupt specifier to a valid linux irq number. Returns either a valid - * linux IRQ number or 0. + * This routine is used for irq controllers which can choose the hardware + * interrupt numbers they generate. In such a case it's simplest to use + * the linux irq as the hardware interrupt number. + */ +unsigned int irq_create_direct_mapping(struct irq_domain *domain) +{ + unsigned int virq; + + if (domain == NULL) + domain = irq_default_domain; + + BUG_ON(domain == NULL); + WARN_ON(domain->revmap_type != IRQ_DOMAIN_MAP_NOMAP); + + virq = irq_alloc_desc_from(1, 0); + if (!virq) { + pr_debug("irq: create_direct virq allocation failed\n"); + return 0; + } + if (virq >= irq_virq_count) { + pr_err("ERROR: no free irqs available below %i maximum\n", + irq_virq_count); + irq_free_desc(virq); + return 0; + } + + pr_debug("irq: create_direct obtained virq %d\n", virq); + + if (irq_setup_virq(domain, virq, virq)) { + irq_free_desc(virq); + return 0; + } + + return virq; +} + +/** + * irq_create_mapping() - Map a hardware interrupt into linux irq space + * @domain: domain owning this hardware interrupt or NULL for default domain + * @hwirq: hardware irq number in that domain space * - * When the caller no longer need the irq number returned by this function it - * should arrange to call irq_dispose_mapping(). + * Only one mapping per hardware interrupt is permitted. Returns a linux + * irq number. + * If the sense/trigger is to be specified, set_irq_type() should be called + * on the number returned from that call. */ +unsigned int irq_create_mapping(struct irq_domain *domain, + irq_hw_number_t hwirq) +{ + unsigned int virq, hint; + + pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", domain, hwirq); + + /* Look for default domain if nececssary */ + if (domain == NULL) + domain = irq_default_domain; + if (domain == NULL) { + printk(KERN_WARNING "irq_create_mapping called for" + " NULL domain, hwirq=%lx\n", hwirq); + WARN_ON(1); + return 0; + } + pr_debug("irq: -> using domain @%p\n", domain); + + /* Check if mapping already exists */ + virq = irq_find_mapping(domain, hwirq); + if (virq) { + pr_debug("irq: -> existing mapping on virq %d\n", virq); + return virq; + } + + /* Get a virtual interrupt number */ + if (domain->revmap_type == IRQ_DOMAIN_MAP_LEGACY) + return irq_domain_legacy_revmap(domain, hwirq); + + /* Allocate a virtual interrupt number */ + hint = hwirq % irq_virq_count; + if (hint == 0) + hint++; + virq = irq_alloc_desc_from(hint, 0); + if (!virq) + virq = irq_alloc_desc_from(1, 0); + if (!virq) { + pr_debug("irq: -> virq allocation failed\n"); + return 0; + } + + if (irq_setup_virq(domain, virq, hwirq)) { + if (domain->revmap_type != IRQ_DOMAIN_MAP_LEGACY) + irq_free_desc(virq); + return 0; + } + + pr_debug("irq: irq %lu on domain %s mapped to virtual irq %u\n", + hwirq, domain->of_node ? domain->of_node->full_name : "null", virq); + + return virq; +} +EXPORT_SYMBOL_GPL(irq_create_mapping); + unsigned int irq_create_of_mapping(struct device_node *controller, const u32 *intspec, unsigned int intsize) { struct irq_domain *domain; - unsigned long hwirq; - unsigned int irq, type; - int rc = -EINVAL; + irq_hw_number_t hwirq; + unsigned int type = IRQ_TYPE_NONE; + unsigned int virq; - /* Find a domain which can translate the irq spec */ - mutex_lock(&irq_domain_mutex); - list_for_each_entry(domain, &irq_domain_list, list) { - if (!domain->ops->dt_translate) - continue; - rc = domain->ops->dt_translate(domain, controller, - intspec, intsize, &hwirq, &type); - if (rc == 0) - break; + domain = controller ? irq_find_host(controller) : irq_default_domain; + if (!domain) { +#ifdef CONFIG_MIPS + /* + * Workaround to avoid breaking interrupt controller drivers + * that don't yet register an irq_domain. This is temporary + * code. ~~~gcl, Feb 24, 2012 + * + * Scheduled for removal in Linux v3.6. That should be enough + * time. + */ + if (intsize > 0) + return intspec[0]; +#endif + printk(KERN_WARNING "irq: no irq domain found for %s !\n", + controller->full_name); + return 0; } - mutex_unlock(&irq_domain_mutex); - if (rc != 0) - return 0; + /* If domain has no translation, then we assume interrupt line */ + if (domain->ops->xlate == NULL) + hwirq = intspec[0]; + else { + if (domain->ops->xlate(domain, controller, intspec, intsize, + &hwirq, &type)) + return 0; + } + + /* Create mapping */ + virq = irq_create_mapping(domain, hwirq); + if (!virq) + return virq; - irq = irq_domain_to_irq(domain, hwirq); - if (type != IRQ_TYPE_NONE) - irq_set_irq_type(irq, type); - pr_debug("%s: mapped hwirq=%i to irq=%i, flags=%x\n", - controller->full_name, (int)hwirq, irq, type); - return irq; + /* Set type if specified and different than the current one */ + if (type != IRQ_TYPE_NONE && + type != (irqd_get_trigger_type(irq_get_irq_data(virq)))) + irq_set_irq_type(virq, type); + return virq; } EXPORT_SYMBOL_GPL(irq_create_of_mapping); /** - * irq_dispose_mapping() - Discard a mapping created by irq_create_of_mapping() - * @irq: linux irq number to be discarded + * irq_dispose_mapping() - Unmap an interrupt + * @virq: linux irq number of the interrupt to unmap + */ +void irq_dispose_mapping(unsigned int virq) +{ + struct irq_data *irq_data = irq_get_irq_data(virq); + struct irq_domain *domain; + irq_hw_number_t hwirq; + + if (!virq || !irq_data) + return; + + domain = irq_data->domain; + if (WARN_ON(domain == NULL)) + return; + + /* Never unmap legacy interrupts */ + if (domain->revmap_type == IRQ_DOMAIN_MAP_LEGACY) + return; + + irq_set_status_flags(virq, IRQ_NOREQUEST); + + /* remove chip and handler */ + irq_set_chip_and_handler(virq, NULL, NULL); + + /* Make sure it's completed */ + synchronize_irq(virq); + + /* Tell the PIC about it */ + if (domain->ops->unmap) + domain->ops->unmap(domain, virq); + smp_mb(); + + /* Clear reverse map */ + hwirq = irq_data->hwirq; + switch(domain->revmap_type) { + case IRQ_DOMAIN_MAP_LINEAR: + if (hwirq < domain->revmap_data.linear.size) + domain->revmap_data.linear.revmap[hwirq] = 0; + break; + case IRQ_DOMAIN_MAP_TREE: + mutex_lock(&revmap_trees_mutex); + radix_tree_delete(&domain->revmap_data.tree, hwirq); + mutex_unlock(&revmap_trees_mutex); + break; + } + + irq_free_desc(virq); +} +EXPORT_SYMBOL_GPL(irq_dispose_mapping); + +/** + * irq_find_mapping() - Find a linux irq from an hw irq number. + * @domain: domain owning this hardware interrupt + * @hwirq: hardware irq number in that domain space + * + * This is a slow path, for use by generic code. It's expected that an + * irq controller implementation directly calls the appropriate low level + * mapping function. + */ +unsigned int irq_find_mapping(struct irq_domain *domain, + irq_hw_number_t hwirq) +{ + unsigned int i; + unsigned int hint = hwirq % irq_virq_count; + + /* Look for default domain if nececssary */ + if (domain == NULL) + domain = irq_default_domain; + if (domain == NULL) + return 0; + + /* legacy -> bail early */ + if (domain->revmap_type == IRQ_DOMAIN_MAP_LEGACY) + return irq_domain_legacy_revmap(domain, hwirq); + + /* Slow path does a linear search of the map */ + if (hint == 0) + hint = 1; + i = hint; + do { + struct irq_data *data = irq_get_irq_data(i); + if (data && (data->domain == domain) && (data->hwirq == hwirq)) + return i; + i++; + if (i >= irq_virq_count) + i = 1; + } while(i != hint); + return 0; +} +EXPORT_SYMBOL_GPL(irq_find_mapping); + +/** + * irq_radix_revmap_lookup() - Find a linux irq from a hw irq number. + * @domain: domain owning this hardware interrupt + * @hwirq: hardware irq number in that domain space * - * Calling this function indicates the caller no longer needs a reference to - * the linux irq number returned by a prior call to irq_create_of_mapping(). + * This is a fast path, for use by irq controller code that uses radix tree + * revmaps */ -void irq_dispose_mapping(unsigned int irq) +unsigned int irq_radix_revmap_lookup(struct irq_domain *domain, + irq_hw_number_t hwirq) { + struct irq_data *irq_data; + + if (WARN_ON_ONCE(domain->revmap_type != IRQ_DOMAIN_MAP_TREE)) + return irq_find_mapping(domain, hwirq); + + /* + * Freeing an irq can delete nodes along the path to + * do the lookup via call_rcu. + */ + rcu_read_lock(); + irq_data = radix_tree_lookup(&domain->revmap_data.tree, hwirq); + rcu_read_unlock(); + /* - * nothing yet; will be filled when support for dynamic allocation of - * irq_descs is added to irq_domain + * If found in radix tree, then fine. + * Else fallback to linear lookup - this should not happen in practice + * as it means that we failed to insert the node in the radix tree. */ + return irq_data ? irq_data->irq : irq_find_mapping(domain, hwirq); } -EXPORT_SYMBOL_GPL(irq_dispose_mapping); -int irq_domain_simple_dt_translate(struct irq_domain *d, - struct device_node *controller, - const u32 *intspec, unsigned int intsize, - unsigned long *out_hwirq, unsigned int *out_type) +/** + * irq_radix_revmap_insert() - Insert a hw irq to linux irq number mapping. + * @domain: domain owning this hardware interrupt + * @virq: linux irq number + * @hwirq: hardware irq number in that domain space + * + * This is for use by irq controllers that use a radix tree reverse + * mapping for fast lookup. + */ +void irq_radix_revmap_insert(struct irq_domain *domain, unsigned int virq, + irq_hw_number_t hwirq) { - if (d->of_node != controller) - return -EINVAL; - if (intsize < 1) - return -EINVAL; - if (d->nr_irq && ((intspec[0] < d->hwirq_base) || - (intspec[0] >= d->hwirq_base + d->nr_irq))) - return -EINVAL; + struct irq_data *irq_data = irq_get_irq_data(virq); + + if (WARN_ON(domain->revmap_type != IRQ_DOMAIN_MAP_TREE)) + return; + + if (virq) { + mutex_lock(&revmap_trees_mutex); + radix_tree_insert(&domain->revmap_data.tree, hwirq, irq_data); + mutex_unlock(&revmap_trees_mutex); + } +} + +/** + * irq_linear_revmap() - Find a linux irq from a hw irq number. + * @domain: domain owning this hardware interrupt + * @hwirq: hardware irq number in that domain space + * + * This is a fast path, for use by irq controller code that uses linear + * revmaps. It does fallback to the slow path if the revmap doesn't exist + * yet and will create the revmap entry with appropriate locking + */ +unsigned int irq_linear_revmap(struct irq_domain *domain, + irq_hw_number_t hwirq) +{ + unsigned int *revmap; + + if (WARN_ON_ONCE(domain->revmap_type != IRQ_DOMAIN_MAP_LINEAR)) + return irq_find_mapping(domain, hwirq); + + /* Check revmap bounds */ + if (unlikely(hwirq >= domain->revmap_data.linear.size)) + return irq_find_mapping(domain, hwirq); + + /* Check if revmap was allocated */ + revmap = domain->revmap_data.linear.revmap; + if (unlikely(revmap == NULL)) + return irq_find_mapping(domain, hwirq); + + /* Fill up revmap with slow path if no mapping found */ + if (unlikely(!revmap[hwirq])) + revmap[hwirq] = irq_find_mapping(domain, hwirq); + + return revmap[hwirq]; +} + +#ifdef CONFIG_VIRQ_DEBUG +static int virq_debug_show(struct seq_file *m, void *private) +{ + unsigned long flags; + struct irq_desc *desc; + const char *p; + static const char none[] = "none"; + void *data; + int i; + + seq_printf(m, "%-5s %-7s %-15s %-18s %s\n", "virq", "hwirq", + "chip name", "chip data", "domain name"); + + for (i = 1; i < nr_irqs; i++) { + desc = irq_to_desc(i); + if (!desc) + continue; + + raw_spin_lock_irqsave(&desc->lock, flags); + + if (desc->action && desc->action->handler) { + struct irq_chip *chip; + + seq_printf(m, "%5d ", i); + seq_printf(m, "0x%05lx ", desc->irq_data.hwirq); + + chip = irq_desc_get_chip(desc); + if (chip && chip->name) + p = chip->name; + else + p = none; + seq_printf(m, "%-15s ", p); + + data = irq_desc_get_chip_data(desc); + seq_printf(m, "0x%16p ", data); + + if (desc->irq_data.domain->of_node) + p = desc->irq_data.domain->of_node->full_name; + else + p = none; + seq_printf(m, "%s\n", p); + } + + raw_spin_unlock_irqrestore(&desc->lock, flags); + } + + return 0; +} +static int virq_debug_open(struct inode *inode, struct file *file) +{ + return single_open(file, virq_debug_show, inode->i_private); +} + +static const struct file_operations virq_debug_fops = { + .open = virq_debug_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __init irq_debugfs_init(void) +{ + if (debugfs_create_file("virq_mapping", S_IRUGO, powerpc_debugfs_root, + NULL, &virq_debug_fops) == NULL) + return -ENOMEM; + + return 0; +} +__initcall(irq_debugfs_init); +#endif /* CONFIG_VIRQ_DEBUG */ + +int irq_domain_simple_map(struct irq_domain *d, unsigned int irq, + irq_hw_number_t hwirq) +{ + return 0; +} + +/** + * irq_domain_xlate_onecell() - Generic xlate for direct one cell bindings + * + * Device Tree IRQ specifier translation function which works with one cell + * bindings where the cell value maps directly to the hwirq number. + */ +int irq_domain_xlate_onecell(struct irq_domain *d, struct device_node *ctrlr, + const u32 *intspec, unsigned int intsize, + unsigned long *out_hwirq, unsigned int *out_type) +{ + if (WARN_ON(intsize < 1)) + return -EINVAL; *out_hwirq = intspec[0]; *out_type = IRQ_TYPE_NONE; - if (intsize > 1) - *out_type = intspec[1] & IRQ_TYPE_SENSE_MASK; return 0; } +EXPORT_SYMBOL_GPL(irq_domain_xlate_onecell); /** - * irq_domain_create_simple() - Set up a 'simple' translation range + * irq_domain_xlate_twocell() - Generic xlate for direct two cell bindings + * + * Device Tree IRQ specifier translation function which works with two cell + * bindings where the cell values map directly to the hwirq number + * and linux irq flags. */ -void irq_domain_add_simple(struct device_node *controller, int irq_base) +int irq_domain_xlate_twocell(struct irq_domain *d, struct device_node *ctrlr, + const u32 *intspec, unsigned int intsize, + irq_hw_number_t *out_hwirq, unsigned int *out_type) { - struct irq_domain *domain; - - domain = kzalloc(sizeof(*domain), GFP_KERNEL); - if (!domain) { - WARN_ON(1); - return; - } + if (WARN_ON(intsize < 2)) + return -EINVAL; + *out_hwirq = intspec[0]; + *out_type = intspec[1] & IRQ_TYPE_SENSE_MASK; + return 0; +} +EXPORT_SYMBOL_GPL(irq_domain_xlate_twocell); - domain->irq_base = irq_base; - domain->of_node = of_node_get(controller); - domain->ops = &irq_domain_simple_ops; - irq_domain_add(domain); +/** + * irq_domain_xlate_onetwocell() - Generic xlate for one or two cell bindings + * + * Device Tree IRQ specifier translation function which works with either one + * or two cell bindings where the cell values map directly to the hwirq number + * and linux irq flags. + * + * Note: don't use this function unless your interrupt controller explicitly + * supports both one and two cell bindings. For the majority of controllers + * the _onecell() or _twocell() variants above should be used. + */ +int irq_domain_xlate_onetwocell(struct irq_domain *d, + struct device_node *ctrlr, + const u32 *intspec, unsigned int intsize, + unsigned long *out_hwirq, unsigned int *out_type) +{ + if (WARN_ON(intsize < 1)) + return -EINVAL; + *out_hwirq = intspec[0]; + *out_type = (intsize > 1) ? intspec[1] : IRQ_TYPE_NONE; + return 0; } -EXPORT_SYMBOL_GPL(irq_domain_add_simple); +EXPORT_SYMBOL_GPL(irq_domain_xlate_onetwocell); +const struct irq_domain_ops irq_domain_simple_ops = { + .map = irq_domain_simple_map, + .xlate = irq_domain_xlate_onetwocell, +}; +EXPORT_SYMBOL_GPL(irq_domain_simple_ops); + +#ifdef CONFIG_OF_IRQ void irq_domain_generate_simple(const struct of_device_id *match, u64 phys_base, unsigned int irq_start) { struct device_node *node; - pr_info("looking for phys_base=%llx, irq_start=%i\n", + pr_debug("looking for phys_base=%llx, irq_start=%i\n", (unsigned long long) phys_base, (int) irq_start); node = of_find_matching_node_by_address(NULL, match, phys_base); if (node) - irq_domain_add_simple(node, irq_start); - else - pr_info("no node found\n"); + irq_domain_add_legacy(node, 32, irq_start, 0, + &irq_domain_simple_ops, NULL); } EXPORT_SYMBOL_GPL(irq_domain_generate_simple); -#endif /* CONFIG_OF_IRQ */ - -struct irq_domain_ops irq_domain_simple_ops = { -#ifdef CONFIG_OF_IRQ - .dt_translate = irq_domain_simple_dt_translate, -#endif /* CONFIG_OF_IRQ */ -}; -EXPORT_SYMBOL_GPL(irq_domain_simple_ops); +#endif |