aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-10-08 17:37:16 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-10-08 17:37:16 -0400
commit8b45bc892e6842115fc87c2b2a3b86a20617606a (patch)
tree636c804eb29bb97070e7d2bc4d5ab9d1dad27cac
parenteb785bef684f2b7d03b530efc8e6f199e9777e2f (diff)
parentfa637bf0595ee1796d728a0d33b6b7fff12e1f3d (diff)
Merge tag 'drivers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC driver updates from Arnd Bergmann: "These are changes for drivers that are intimately tied to some SoC and for some reason could not get merged through the respective subsystem maintainer tree. Most of the new code is for the Keystone Navigator driver, which is new base support that is going to be needed for their hardware accelerated network driver and other units. Most of the commits are for moving old code around from at91 and omap for things that are done in device drivers nowadays. - at91: move reset, poweroff, memory and clocksource code into drivers directories - socfpga: add edac driver (through arm-soc, as requested by Boris) - omap: move omap-intc code to drivers/irqchip - sunxi: added an RTC driver for sun6i - omap: mailbox driver related changes - keystone: support for the "Navigator" component - versatile: new reboot, led and soc drivers" * tag 'drivers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (92 commits) bus: arm-ccn: Fix spurious warning message leds: add device tree bindings for register bit LEDs soc: add driver for the ARM RealView power: reset: driver for the Versatile syscon reboot leds: add a driver for syscon-based LEDs drivers/soc: ti: fix build break with modules MAINTAINERS: Add Keystone Multicore Navigator drivers entry soc: ti: add Keystone Navigator DMA support Documentation: dt: soc: add Keystone Navigator DMA bindings soc: ti: add Keystone Navigator QMSS driver Documentation: dt: soc: add Keystone Navigator QMSS bindings rtc: sunxi: Depend on platforms sun4i/sun7i that actually have the rtc rtc: sun6i: Add sun6i RTC driver irqchip: omap-intc: remove unnecessary comments irqchip: omap-intc: correct maximum number or MIR registers irqchip: omap-intc: enable TURBO idle mode irqchip: omap-intc: enable IP protection irqchip: omap-intc: remove unnecesary of_address_to_resource() call irqchip: omap-intc: comment style cleanup irqchip: omap-intc: minor improvement to omap_irq_pending() ...
-rw-r--r--Documentation/devicetree/bindings/arm/atmel-at91.txt8
-rw-r--r--Documentation/devicetree/bindings/leds/register-bit-led.txt99
-rw-r--r--Documentation/devicetree/bindings/mailbox/omap-mailbox.txt108
-rw-r--r--Documentation/devicetree/bindings/rtc/sun6i-rtc.txt17
-rw-r--r--Documentation/devicetree/bindings/soc/ti/keystone-navigator-dma.txt111
-rw-r--r--Documentation/devicetree/bindings/soc/ti/keystone-navigator-qmss.txt232
-rw-r--r--MAINTAINERS14
-rw-r--r--arch/arm/boot/dts/am33xx.dtsi3
-rw-r--r--arch/arm/boot/dts/omap2.dtsi1
-rw-r--r--arch/arm/boot/dts/omap2420-n810.dts7
-rw-r--r--arch/arm/boot/dts/omap2420-n8x0-common.dtsi6
-rw-r--r--arch/arm/boot/dts/omap3.dtsi3
-rw-r--r--arch/arm/mach-at91/Kconfig17
-rw-r--r--arch/arm/mach-at91/Makefile3
-rw-r--r--arch/arm/mach-at91/at91_rstc.h53
-rw-r--r--arch/arm/mach-at91/at91_shdwc.h50
-rw-r--r--arch/arm/mach-at91/at91sam9260.c51
-rw-r--r--arch/arm/mach-at91/at91sam9261.c51
-rw-r--r--arch/arm/mach-at91/at91sam9263.c51
-rw-r--r--arch/arm/mach-at91/at91sam926x_time.c294
-rw-r--r--arch/arm/mach-at91/at91sam9_alt_reset.S40
-rw-r--r--arch/arm/mach-at91/at91sam9g45.c55
-rw-r--r--arch/arm/mach-at91/at91sam9g45_reset.S45
-rw-r--r--arch/arm/mach-at91/at91sam9rl.c51
-rw-r--r--arch/arm/mach-at91/board-afeb-9260v1.c4
-rw-r--r--arch/arm/mach-at91/board-cam60.c4
-rw-r--r--arch/arm/mach-at91/board-cpu9krea.c4
-rw-r--r--arch/arm/mach-at91/board-dt-sam9.c10
-rw-r--r--arch/arm/mach-at91/board-dt-sama5.c9
-rw-r--r--arch/arm/mach-at91/board-flexibity.c4
-rw-r--r--arch/arm/mach-at91/board-gsia18s.c2
-rw-r--r--arch/arm/mach-at91/board-pcontrol-g20.c2
-rw-r--r--arch/arm/mach-at91/board-sam9-l9260.c4
-rw-r--r--arch/arm/mach-at91/board-sam9260ek.c5
-rw-r--r--arch/arm/mach-at91/board-sam9261ek.c7
-rw-r--r--arch/arm/mach-at91/board-sam9263ek.c5
-rw-r--r--arch/arm/mach-at91/board-sam9g20ek.c4
-rw-r--r--arch/arm/mach-at91/board-sam9m10g45ek.c5
-rw-r--r--arch/arm/mach-at91/board-sam9rlek.c5
-rw-r--r--arch/arm/mach-at91/board-snapper9260.c4
-rw-r--r--arch/arm/mach-at91/board-stamp9g20.c4
-rw-r--r--arch/arm/mach-at91/generic.h18
-rw-r--r--arch/arm/mach-at91/pm.c72
-rw-r--r--arch/arm/mach-at91/setup.c185
-rw-r--r--arch/arm/mach-at91/soc.h2
-rw-r--r--arch/arm/mach-omap2/Kconfig1
-rw-r--r--arch/arm/mach-omap2/Makefile3
-rw-r--r--arch/arm/mach-omap2/board-3430sdp.c1
-rw-r--r--arch/arm/mach-omap2/board-am3517crane.c1
-rw-r--r--arch/arm/mach-omap2/board-am3517evm.c1
-rw-r--r--arch/arm/mach-omap2/board-cm-t35.c2
-rw-r--r--arch/arm/mach-omap2/board-cm-t3517.c1
-rw-r--r--arch/arm/mach-omap2/board-devkit8000.c1
-rw-r--r--arch/arm/mach-omap2/board-generic.c14
-rw-r--r--arch/arm/mach-omap2/board-ldp.c1
-rw-r--r--arch/arm/mach-omap2/board-n8x0.c26
-rw-r--r--arch/arm/mach-omap2/board-omap3beagle.c1
-rw-r--r--arch/arm/mach-omap2/board-omap3logic.c2
-rw-r--r--arch/arm/mach-omap2/board-omap3pandora.c1
-rw-r--r--arch/arm/mach-omap2/board-omap3stalker.c1
-rw-r--r--arch/arm/mach-omap2/board-omap3touchbook.c1
-rw-r--r--arch/arm/mach-omap2/board-overo.c1
-rw-r--r--arch/arm/mach-omap2/board-rx51.c1
-rw-r--r--arch/arm/mach-omap2/common-board-devices.h5
-rw-r--r--arch/arm/mach-omap2/common.h23
-rw-r--r--arch/arm/mach-omap2/irq.c380
-rw-r--r--arch/arm/mach-omap2/pdata-quirks.c2
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/bus/arm-ccn.c5
-rw-r--r--drivers/clk/at91/clk-system.c8
-rw-r--r--drivers/clocksource/Kconfig4
-rw-r--r--drivers/clocksource/Makefile1
-rw-r--r--drivers/clocksource/timer-atmel-pit.c296
-rw-r--r--drivers/edac/Kconfig9
-rw-r--r--drivers/edac/Makefile2
-rw-r--r--drivers/edac/altera_edac.c410
-rw-r--r--drivers/irqchip/Kconfig5
-rw-r--r--drivers/irqchip/Makefile1
-rw-r--r--drivers/irqchip/irq-omap-intc.c403
-rw-r--r--drivers/leds/Kconfig10
-rw-r--r--drivers/leds/Makefile1
-rw-r--r--drivers/leds/leds-syscon.c166
-rw-r--r--drivers/mailbox/omap-mailbox.c156
-rw-r--r--drivers/memory/Kconfig10
-rw-r--r--drivers/memory/Makefile1
-rw-r--r--drivers/memory/atmel-sdramc.c98
-rw-r--r--drivers/power/reset/Kconfig42
-rw-r--r--drivers/power/reset/Makefile3
-rw-r--r--drivers/power/reset/arm-versatile-reboot.c111
-rw-r--r--drivers/power/reset/at91-poweroff.c156
-rw-r--r--drivers/power/reset/at91-reset.c252
-rw-r--r--drivers/rtc/Kconfig9
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/rtc-sun6i.c447
-rw-r--r--drivers/soc/Kconfig2
-rw-r--r--drivers/soc/Makefile2
-rw-r--r--drivers/soc/ti/Kconfig31
-rw-r--r--drivers/soc/ti/Makefile5
-rw-r--r--drivers/soc/ti/knav_dma.c815
-rw-r--r--drivers/soc/ti/knav_qmss.h386
-rw-r--r--drivers/soc/ti/knav_qmss_acc.c591
-rw-r--r--drivers/soc/ti/knav_qmss_queue.c1816
-rw-r--r--drivers/soc/versatile/Kconfig10
-rw-r--r--drivers/soc/versatile/Makefile1
-rw-r--r--drivers/soc/versatile/soc-realview.c144
-rw-r--r--include/linux/irqchip/irq-omap-intc.h32
-rw-r--r--include/linux/soc/ti/knav_dma.h175
-rw-r--r--include/linux/soc/ti/knav_qmss.h90
108 files changed, 7609 insertions, 1299 deletions
diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.txt b/Documentation/devicetree/bindings/arm/atmel-at91.txt
index 4949e805f7fc..562cda9d86d9 100644
--- a/Documentation/devicetree/bindings/arm/atmel-at91.txt
+++ b/Documentation/devicetree/bindings/arm/atmel-at91.txt
@@ -98,8 +98,8 @@ RAMC SDRAM/DDR Controller required properties:
98- compatible: Should be "atmel,at91rm9200-sdramc", 98- compatible: Should be "atmel,at91rm9200-sdramc",
99 "atmel,at91sam9260-sdramc", 99 "atmel,at91sam9260-sdramc",
100 "atmel,at91sam9g45-ddramc", 100 "atmel,at91sam9g45-ddramc",
101 "atmel,sama5d3-ddramc",
101- reg: Should contain registers location and length 102- reg: Should contain registers location and length
102 For at91sam9263 and at91sam9g45 you must specify 2 entries.
103 103
104Examples: 104Examples:
105 105
@@ -108,12 +108,6 @@ Examples:
108 reg = <0xffffe800 0x200>; 108 reg = <0xffffe800 0x200>;
109 }; 109 };
110 110
111 ramc0: ramc@ffffe400 {
112 compatible = "atmel,at91sam9g45-ddramc";
113 reg = <0xffffe400 0x200
114 0xffffe600 0x200>;
115 };
116
117SHDWC Shutdown Controller 111SHDWC Shutdown Controller
118 112
119required properties: 113required properties:
diff --git a/Documentation/devicetree/bindings/leds/register-bit-led.txt b/Documentation/devicetree/bindings/leds/register-bit-led.txt
new file mode 100644
index 000000000000..379cefdc0bda
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/register-bit-led.txt
@@ -0,0 +1,99 @@
1Device Tree Bindings for Register Bit LEDs
2
3Register bit leds are used with syscon multifunctional devices
4where single bits in a certain register can turn on/off a
5single LED. The register bit LEDs appear as children to the
6syscon device, with the proper compatible string. For the
7syscon bindings see:
8Documentation/devicetree/bindings/mfd/syscon.txt
9
10Each LED is represented as a sub-node of the syscon device. Each
11node's name represents the name of the corresponding LED.
12
13LED sub-node properties:
14
15Required properties:
16- compatible : must be "register-bit-led"
17- offset : register offset to the register controlling this LED
18- mask : bit mask for the bit controlling this LED in the register
19 typically 0x01, 0x02, 0x04 ...
20
21Optional properties:
22- label : (optional)
23 see Documentation/devicetree/bindings/leds/common.txt
24- linux,default-trigger : (optional)
25 see Documentation/devicetree/bindings/leds/common.txt
26- default-state: (optional) The initial state of the LED. Valid
27 values are "on", "off", and "keep". If the LED is already on or off
28 and the default-state property is set the to same value, then no
29 glitch should be produced where the LED momentarily turns off (or
30 on). The "keep" setting will keep the LED at whatever its current
31 state is, without producing a glitch. The default is off if this
32 property is not present.
33
34Example:
35
36syscon: syscon@10000000 {
37 compatible = "arm,realview-pb1176-syscon", "syscon";
38 reg = <0x10000000 0x1000>;
39
40 led@08.0 {
41 compatible = "register-bit-led";
42 offset = <0x08>;
43 mask = <0x01>;
44 label = "versatile:0";
45 linux,default-trigger = "heartbeat";
46 default-state = "on";
47 };
48 led@08.1 {
49 compatible = "register-bit-led";
50 offset = <0x08>;
51 mask = <0x02>;
52 label = "versatile:1";
53 linux,default-trigger = "mmc0";
54 default-state = "off";
55 };
56 led@08.2 {
57 compatible = "register-bit-led";
58 offset = <0x08>;
59 mask = <0x04>;
60 label = "versatile:2";
61 linux,default-trigger = "cpu0";
62 default-state = "off";
63 };
64 led@08.3 {
65 compatible = "register-bit-led";
66 offset = <0x08>;
67 mask = <0x08>;
68 label = "versatile:3";
69 default-state = "off";
70 };
71 led@08.4 {
72 compatible = "register-bit-led";
73 offset = <0x08>;
74 mask = <0x10>;
75 label = "versatile:4";
76 default-state = "off";
77 };
78 led@08.5 {
79 compatible = "register-bit-led";
80 offset = <0x08>;
81 mask = <0x20>;
82 label = "versatile:5";
83 default-state = "off";
84 };
85 led@08.6 {
86 compatible = "register-bit-led";
87 offset = <0x08>;
88 mask = <0x40>;
89 label = "versatile:6";
90 default-state = "off";
91 };
92 led@08.7 {
93 compatible = "register-bit-led";
94 offset = <0x08>;
95 mask = <0x80>;
96 label = "versatile:7";
97 default-state = "off";
98 };
99};
diff --git a/Documentation/devicetree/bindings/mailbox/omap-mailbox.txt b/Documentation/devicetree/bindings/mailbox/omap-mailbox.txt
new file mode 100644
index 000000000000..48edc4b92afb
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/omap-mailbox.txt
@@ -0,0 +1,108 @@
1OMAP2+ Mailbox Driver
2=====================
3
4The OMAP mailbox hardware facilitates communication between different processors
5using a queued mailbox interrupt mechanism. The IP block is external to the
6various processor subsystems and is connected on an interconnect bus. The
7communication is achieved through a set of registers for message storage and
8interrupt configuration registers.
9
10Each mailbox IP block has a certain number of h/w fifo queues and output
11interrupt lines. An output interrupt line is routed to an interrupt controller
12within a processor subsystem, and there can be more than one line going to a
13specific processor's interrupt controller. The interrupt line connections are
14fixed for an instance and are dictated by the IP integration into the SoC
15(excluding the SoCs that have a Interrupt Crossbar IP). Each interrupt line is
16programmable through a set of interrupt configuration registers, and have a rx
17and tx interrupt source per h/w fifo. Communication between different processors
18is achieved through the appropriate programming of the rx and tx interrupt
19sources on the appropriate interrupt lines.
20
21The number of h/w fifo queues and interrupt lines dictate the usable registers.
22All the current OMAP SoCs except for the newest DRA7xx SoC has a single IP
23instance. DRA7xx has multiple instances with different number of h/w fifo queues
24and interrupt lines between different instances. The interrupt lines can also be
25routed to different processor sub-systems on DRA7xx as they are routed through
26the Crossbar, a kind of interrupt router/multiplexer.
27
28Mailbox Device Node:
29====================
30A Mailbox device node is used to represent a Mailbox IP instance within a SoC.
31The sub-mailboxes are represented as child nodes of this parent node.
32
33Required properties:
34--------------------
35- compatible: Should be one of the following,
36 "ti,omap2-mailbox" for OMAP2420, OMAP2430 SoCs
37 "ti,omap3-mailbox" for OMAP3430, OMAP3630 SoCs
38 "ti,omap4-mailbox" for OMAP44xx, OMAP54xx, AM33xx,
39 AM43xx and DRA7xx SoCs
40- reg: Contains the mailbox register address range (base
41 address and length)
42- interrupts: Contains the interrupt information for the mailbox
43 device. The format is dependent on which interrupt
44 controller the OMAP device uses
45- ti,hwmods: Name of the hwmod associated with the mailbox
46- ti,mbox-num-users: Number of targets (processor devices) that the mailbox
47 device can interrupt
48- ti,mbox-num-fifos: Number of h/w fifo queues within the mailbox IP block
49
50Child Nodes:
51============
52A child node is used for representing the actual sub-mailbox device that is
53used for the communication between the host processor and a remote processor.
54Each child node should have a unique node name across all the different
55mailbox device nodes.
56
57Required properties:
58--------------------
59- ti,mbox-tx: sub-mailbox descriptor property defining a Tx fifo
60- ti,mbox-rx: sub-mailbox descriptor property defining a Rx fifo
61
62Sub-mailbox Descriptor Data
63---------------------------
64Each of the above ti,mbox-tx and ti,mbox-rx properties should have 3 cells of
65data that represent the following:
66 Cell #1 (fifo_id) - mailbox fifo id used either for transmitting
67 (ti,mbox-tx) or for receiving (ti,mbox-rx)
68 Cell #2 (irq_id) - irq identifier index number to use from the parent's
69 interrupts data. Should be 0 for most of the cases, a
70 positive index value is seen only on mailboxes that have
71 multiple interrupt lines connected to the MPU processor.
72 Cell #3 (usr_id) - mailbox user id for identifying the interrupt line
73 associated with generating a tx/rx fifo interrupt.
74
75Example:
76--------
77
78/* OMAP4 */
79mailbox: mailbox@4a0f4000 {
80 compatible = "ti,omap4-mailbox";
81 reg = <0x4a0f4000 0x200>;
82 interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
83 ti,hwmods = "mailbox";
84 ti,mbox-num-users = <3>;
85 ti,mbox-num-fifos = <8>;
86 mbox_ipu: mbox_ipu {
87 ti,mbox-tx = <0 0 0>;
88 ti,mbox-rx = <1 0 0>;
89 };
90 mbox_dsp: mbox_dsp {
91 ti,mbox-tx = <3 0 0>;
92 ti,mbox-rx = <2 0 0>;
93 };
94};
95
96/* AM33xx */
97mailbox: mailbox@480C8000 {
98 compatible = "ti,omap4-mailbox";
99 reg = <0x480C8000 0x200>;
100 interrupts = <77>;
101 ti,hwmods = "mailbox";
102 ti,mbox-num-users = <4>;
103 ti,mbox-num-fifos = <8>;
104 mbox_wkupm3: wkup_m3 {
105 ti,mbox-tx = <0 0 0>;
106 ti,mbox-rx = <0 0 3>;
107 };
108};
diff --git a/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt b/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt
new file mode 100644
index 000000000000..f007e428a1ab
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt
@@ -0,0 +1,17 @@
1* sun6i Real Time Clock
2
3RTC controller for the Allwinner A31
4
5Required properties:
6- compatible : Should be "allwinner,sun6i-a31-rtc"
7- reg : physical base address of the controller and length of
8 memory mapped region.
9- interrupts : IRQ lines for the RTC alarm 0 and alarm 1, in that order.
10
11Example:
12
13rtc: rtc@01f00000 {
14 compatible = "allwinner,sun6i-a31-rtc";
15 reg = <0x01f00000 0x54>;
16 interrupts = <0 40 4>, <0 41 4>;
17};
diff --git a/Documentation/devicetree/bindings/soc/ti/keystone-navigator-dma.txt b/Documentation/devicetree/bindings/soc/ti/keystone-navigator-dma.txt
new file mode 100644
index 000000000000..337c4ea5c57b
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/ti/keystone-navigator-dma.txt
@@ -0,0 +1,111 @@
1Keystone Navigator DMA Controller
2
3This document explains the device tree bindings for the packet dma
4on keystone devices. The Keystone Navigator DMA driver sets up the dma
5channels and flows for the QMSS(Queue Manager SubSystem) who triggers
6the actual data movements across clients using destination queues. Every
7client modules like NETCP(Network Coprocessor), SRIO(Serial Rapid IO),
8CRYPTO Engines etc has its own instance of dma hardware. QMSS has also
9an internal packet DMA module which is used as an infrastructure DMA
10with zero copy.
11
12Navigator DMA cloud layout:
13 ------------------
14 | Navigator DMAs |
15 ------------------
16 |
17 |-> DMA instance #0
18 |
19 |-> DMA instance #1
20 .
21 .
22 |
23 |-> DMA instance #n
24
25Navigator DMA properties:
26Required properties:
27 - compatible: Should be "ti,keystone-navigator-dma"
28 - clocks: phandle to dma instances clocks. The clock handles can be as
29 many as the dma instances. The order should be maintained as per
30 the dma instances.
31 - ti,navigator-cloud-address: Should contain base address for the multi-core
32 navigator cloud and number of addresses depends on SOC integration
33 configuration.. Navigator cloud global address needs to be programmed
34 into DMA and the DMA uses it as the physical addresses to reach queue
35 managers. Note that these addresses though points to queue managers,
36 they are relevant only from DMA perspective. The QMSS may not choose to
37 use them since it has a different address space view to reach all
38 its components.
39
40DMA instance properties:
41Required properties:
42 - reg: Should contain register location and length of the following dma
43 register regions. Register regions should be specified in the following
44 order.
45 - Global control register region (global).
46 - Tx DMA channel configuration register region (txchan).
47 - Rx DMA channel configuration register region (rxchan).
48 - Tx DMA channel Scheduler configuration register region (txsched).
49 - Rx DMA flow configuration register region (rxflow).
50
51Optional properties:
52 - reg-names: Names for the register regions.
53 - ti,enable-all: Enable all DMA channels vs clients opening specific channels
54 what they need. This property is useful for the userspace fast path
55 case where the linux drivers enables the channels used by userland
56 stack.
57 - ti,loop-back: To loopback Tx streaming I/F to Rx streaming I/F. Used for
58 infrastructure transfers.
59 - ti,rx-retry-timeout: Number of dma cycles to wait before retry on buffer
60 starvation.
61
62Example:
63
64 knav_dmas: knav_dmas@0 {
65 compatible = "ti,keystone-navigator-dma";
66 clocks = <&papllclk>, <&clkxge>;
67 #address-cells = <1>;
68 #size-cells = <1>;
69 ranges;
70 ti,navigator-cloud-address = <0x23a80000 0x23a90000
71 0x23aa0000 0x23ab0000>;
72
73 dma_gbe: dma_gbe@0 {
74 reg = <0x2004000 0x100>,
75 <0x2004400 0x120>,
76 <0x2004800 0x300>,
77 <0x2004c00 0x120>,
78 <0x2005000 0x400>;
79 reg-names = "global", "txchan", "rxchan",
80 "txsched", "rxflow";
81 };
82
83 dma_xgbe: dma_xgbe@0 {
84 reg = <0x2fa1000 0x100>,
85 <0x2fa1400 0x200>,
86 <0x2fa1800 0x200>,
87 <0x2fa1c00 0x200>,
88 <0x2fa2000 0x400>;
89 reg-names = "global", "txchan", "rxchan",
90 "txsched", "rxflow";
91 };
92 };
93
94Navigator DMA client:
95Required properties:
96 - ti,navigator-dmas: List of one or more DMA specifiers, each consisting of
97 - A phandle pointing to DMA instance node
98 - A DMA channel number as a phandle arg.
99 - ti,navigator-dma-names: Contains dma channel name for each DMA specifier in
100 the 'ti,navigator-dmas' property.
101
102Example:
103
104 netcp: netcp@2090000 {
105 ..
106 ti,navigator-dmas = <&dma_gbe 22>,
107 <&dma_gbe 23>,
108 <&dma_gbe 8>;
109 ti,navigator-dma-names = "netrx0", "netrx1", "nettx";
110 ..
111 };
diff --git a/Documentation/devicetree/bindings/soc/ti/keystone-navigator-qmss.txt b/Documentation/devicetree/bindings/soc/ti/keystone-navigator-qmss.txt
new file mode 100644
index 000000000000..d8e8cdb733f9
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/ti/keystone-navigator-qmss.txt
@@ -0,0 +1,232 @@
1* Texas Instruments Keystone Navigator Queue Management SubSystem driver
2
3The QMSS (Queue Manager Sub System) found on Keystone SOCs is one of
4the main hardware sub system which forms the backbone of the Keystone
5multi-core Navigator. QMSS consist of queue managers, packed-data structure
6processors(PDSP), linking RAM, descriptor pools and infrastructure
7Packet DMA.
8The Queue Manager is a hardware module that is responsible for accelerating
9management of the packet queues. Packets are queued/de-queued by writing or
10reading descriptor address to a particular memory mapped location. The PDSPs
11perform QMSS related functions like accumulation, QoS, or event management.
12Linking RAM registers are used to link the descriptors which are stored in
13descriptor RAM. Descriptor RAM is configurable as internal or external memory.
14The QMSS driver manages the PDSP setups, linking RAM regions,
15queue pool management (allocation, push, pop and notify) and descriptor
16pool management.
17
18
19Required properties:
20- compatible : Must be "ti,keystone-navigator-qmss";
21- clocks : phandle to the reference clock for this device.
22- queue-range : <start number> total range of queue numbers for the device.
23- linkram0 : <address size> for internal link ram, where size is the total
24 link ram entries.
25- linkram1 : <address size> for external link ram, where size is the total
26 external link ram entries. If the address is specified as "0"
27 driver will allocate memory.
28- qmgrs : child node describing the individual queue managers on the
29 SoC. On keystone 1 devices there should be only one node.
30 On keystone 2 devices there can be more than 1 node.
31 -- managed-queues : the actual queues managed by each queue manager
32 instance, specified as <"base queue #" "# of queues">.
33 -- reg : Address and size of the register set for the device.
34 Register regions should be specified in the following
35 order
36 - Queue Peek region.
37 - Queue status RAM.
38 - Queue configuration region.
39 - Descriptor memory setup region.
40 - Queue Management/Queue Proxy region for queue Push.
41 - Queue Management/Queue Proxy region for queue Pop.
42- queue-pools : child node classifying the queue ranges into pools.
43 Queue ranges are grouped into 3 type of pools:
44 - qpend : pool of qpend(interruptible) queues
45 - general-purpose : pool of general queues, primarly used
46 as free descriptor queues or the
47 transmit DMA queues.
48 - accumulator : pool of queues on PDSP accumulator channel
49 Each range can have the following properties:
50 -- qrange : number of queues to use per queue range, specified as
51 <"base queue #" "# of queues">.
52 -- interrupts : Optional property to specify the interrupt mapping
53 for interruptible queues. The driver additionaly sets
54 the interrupt affinity hint based on the cpu mask.
55 -- qalloc-by-id : Optional property to specify that the queues in this
56 range can only be allocated by queue id.
57 -- accumulator : Accumulator channel specification. Any of the PDSPs in
58 QMSS can be loaded with the accumulator firmware. The
59 accumulator firmware’s job is to poll a select number of
60 queues looking for descriptors that have been pushed
61 into them. Descriptors are popped from the queue and
62 placed in a buffer provided by the host. When the list
63 becomes full or a programmed time period expires, the
64 accumulator triggers an interrupt to the host to read
65 the buffer for descriptor information. This firmware
66 comes in 16, 32, and 48 channel builds. Each of these
67 channels can be configured to monitor 32 contiguous
68 queues. Accumulator channel property is specified as:
69 <pdsp-id, channel, entries, pacing mode, latency>
70 pdsp-id : QMSS PDSP running accumulator firmware
71 on which the channel has to be
72 configured
73 channel : Accumulator channel number
74 entries : Size of the accumulator descriptor list
75 pacing mode : Interrupt pacing mode
76 0 : None, i.e interrupt on list full only
77 1 : Time delay since last interrupt
78 2 : Time delay since first new packet
79 3 : Time delay since last new packet
80 latency : time to delay the interrupt, specified
81 in microseconds.
82 -- multi-queue : Optional property to specify that the channel has to
83 monitor upto 32 queues starting at the base queue #.
84- descriptor-regions : child node describing the memory regions for keystone
85 navigator packet DMA descriptors. The memory for
86 descriptors will be allocated by the driver.
87 -- id : region number in QMSS.
88 -- region-spec : specifies the number of descriptors in the
89 region, specified as
90 <"# of descriptors" "descriptor size">.
91 -- link-index : start index, i.e. index of the first
92 descriptor in the region.
93
94Optional properties:
95- dma-coherent : Present if DMA operations are coherent.
96- pdsps : child node describing the PDSP configuration.
97 -- firmware : firmware to be loaded on the PDSP.
98 -- id : the qmss pdsp that will run the firmware.
99 -- reg : Address and size of the register set for the PDSP.
100 Register regions should be specified in the following
101 order
102 - PDSP internal RAM region.
103 - PDSP control/status region registers.
104 - QMSS interrupt distributor registers.
105 - PDSP command interface region.
106
107Example:
108
109qmss: qmss@2a40000 {
110 compatible = "ti,keystone-qmss";
111 dma-coherent;
112 #address-cells = <1>;
113 #size-cells = <1>;
114 clocks = <&chipclk13>;
115 ranges;
116 queue-range = <0 0x4000>;
117 linkram0 = <0x100000 0x8000>;
118 linkram1 = <0x0 0x10000>;
119
120 qmgrs {
121 #address-cells = <1>;
122 #size-cells = <1>;
123 ranges;
124 qmgr0 {
125 managed-queues = <0 0x2000>;
126 reg = <0x2a40000 0x20000>,
127 <0x2a06000 0x400>,
128 <0x2a02000 0x1000>,
129 <0x2a03000 0x1000>,
130 <0x23a80000 0x20000>,
131 <0x2a80000 0x20000>;
132 };
133
134 qmgr1 {
135 managed-queues = <0x2000 0x2000>;
136 reg = <0x2a60000 0x20000>,
137 <0x2a06400 0x400>,
138 <0x2a04000 0x1000>,
139 <0x2a05000 0x1000>,
140 <0x23aa0000 0x20000>,
141 <0x2aa0000 0x20000>;
142 };
143 };
144 queue-pools {
145 qpend {
146 qpend-0 {
147 qrange = <658 8>;
148 interrupts =<0 40 0xf04 0 41 0xf04 0 42 0xf04
149 0 43 0xf04 0 44 0xf04 0 45 0xf04
150 0 46 0xf04 0 47 0xf04>;
151 };
152 qpend-1 {
153 qrange = <8704 16>;
154 interrupts = <0 48 0xf04 0 49 0xf04 0 50 0xf04
155 0 51 0xf04 0 52 0xf04 0 53 0xf04
156 0 54 0xf04 0 55 0xf04 0 56 0xf04
157 0 57 0xf04 0 58 0xf04 0 59 0xf04
158 0 60 0xf04 0 61 0xf04 0 62 0xf04
159 0 63 0xf04>;
160 qalloc-by-id;
161 };
162 qpend-2 {
163 qrange = <8720 16>;
164 interrupts = <0 64 0xf04 0 65 0xf04 0 66 0xf04
165 0 59 0xf04 0 68 0xf04 0 69 0xf04
166 0 70 0xf04 0 71 0xf04 0 72 0xf04
167 0 73 0xf04 0 74 0xf04 0 75 0xf04
168 0 76 0xf04 0 77 0xf04 0 78 0xf04
169 0 79 0xf04>;
170 };
171 };
172 general-purpose {
173 gp-0 {
174 qrange = <4000 64>;
175 };
176 netcp-tx {
177 qrange = <640 9>;
178 qalloc-by-id;
179 };
180 };
181 accumulator {
182 acc-0 {
183 qrange = <128 32>;
184 accumulator = <0 36 16 2 50>;
185 interrupts = <0 215 0xf01>;
186 multi-queue;
187 qalloc-by-id;
188 };
189 acc-1 {
190 qrange = <160 32>;
191 accumulator = <0 37 16 2 50>;
192 interrupts = <0 216 0xf01>;
193 multi-queue;
194 };
195 acc-2 {
196 qrange = <192 32>;
197 accumulator = <0 38 16 2 50>;
198 interrupts = <0 217 0xf01>;
199 multi-queue;
200 };
201 acc-3 {
202 qrange = <224 32>;
203 accumulator = <0 39 16 2 50>;
204 interrupts = <0 218 0xf01>;
205 multi-queue;
206 };
207 };
208 };
209 descriptor-regions {
210 #address-cells = <1>;
211 #size-cells = <1>;
212 ranges;
213 region-12 {
214 id = <12>;
215 region-spec = <8192 128>; /* num_desc desc_size */
216 link-index = <0x4000>;
217 };
218 };
219 pdsps {
220 #address-cells = <1>;
221 #size-cells = <1>;
222 ranges;
223 pdsp0@0x2a10000 {
224 firmware = "keystone/qmss_pdsp_acc48_k2_le_1_0_0_8.fw";
225 reg = <0x2a10000 0x1000>,
226 <0x2a0f000 0x100>,
227 <0x2a0c000 0x3c8>,
228 <0x2a20000 0x4000>;
229 id = <0>;
230 };
231 };
232}; /* qmss */
diff --git a/MAINTAINERS b/MAINTAINERS
index d172f636df24..0fa3ff342af6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1404,6 +1404,11 @@ M: Dinh Nguyen <dinguyen@opensource.altera.com>
1404S: Maintained 1404S: Maintained
1405F: drivers/clk/socfpga/ 1405F: drivers/clk/socfpga/
1406 1406
1407ARM/SOCFPGA EDAC SUPPORT
1408M: Thor Thayer <tthayer@opensource.altera.com>
1409S: Maintained
1410F: drivers/edac/altera_edac.
1411
1407ARM/STI ARCHITECTURE 1412ARM/STI ARCHITECTURE
1408M: Srinivas Kandagatla <srinivas.kandagatla@gmail.com> 1413M: Srinivas Kandagatla <srinivas.kandagatla@gmail.com>
1409M: Maxime Coquelin <maxime.coquelin@st.com> 1414M: Maxime Coquelin <maxime.coquelin@st.com>
@@ -9194,6 +9199,15 @@ F: drivers/misc/tifm*
9194F: drivers/mmc/host/tifm_sd.c 9199F: drivers/mmc/host/tifm_sd.c
9195F: include/linux/tifm.h 9200F: include/linux/tifm.h
9196 9201
9202TI KEYSTONE MULTICORE NAVIGATOR DRIVERS
9203M: Santosh Shilimkar <santosh.shilimkar@ti.com>
9204L: linux-kernel@vger.kernel.org
9205L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
9206S: Maintained
9207F: drivers/soc/ti/*
9208T: git git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git
9209
9210
9197TI LM49xxx FAMILY ASoC CODEC DRIVERS 9211TI LM49xxx FAMILY ASoC CODEC DRIVERS
9198M: M R Swami Reddy <mr.swami.reddy@ti.com> 9212M: M R Swami Reddy <mr.swami.reddy@ti.com>
9199M: Vishwas A Deshpande <vishwas.a.deshpande@ti.com> 9213M: Vishwas A Deshpande <vishwas.a.deshpande@ti.com>
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
index 9e7d45571cd5..abe530f70296 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -133,10 +133,9 @@
133 }; 133 };
134 134
135 intc: interrupt-controller@48200000 { 135 intc: interrupt-controller@48200000 {
136 compatible = "ti,omap2-intc"; 136 compatible = "ti,am33xx-intc";
137 interrupt-controller; 137 interrupt-controller;
138 #interrupt-cells = <1>; 138 #interrupt-cells = <1>;
139 ti,intc-size = <128>;
140 reg = <0x48200000 0x1000>; 139 reg = <0x48200000 0x1000>;
141 }; 140 };
142 141
diff --git a/arch/arm/boot/dts/omap2.dtsi b/arch/arm/boot/dts/omap2.dtsi
index 8f8c07da4ac1..59d1c297bb30 100644
--- a/arch/arm/boot/dts/omap2.dtsi
+++ b/arch/arm/boot/dts/omap2.dtsi
@@ -75,7 +75,6 @@
75 compatible = "ti,omap2-intc"; 75 compatible = "ti,omap2-intc";
76 interrupt-controller; 76 interrupt-controller;
77 #interrupt-cells = <1>; 77 #interrupt-cells = <1>;
78 ti,intc-size = <96>;
79 reg = <0x480FE000 0x1000>; 78 reg = <0x480FE000 0x1000>;
80 }; 79 };
81 80
diff --git a/arch/arm/boot/dts/omap2420-n810.dts b/arch/arm/boot/dts/omap2420-n810.dts
index 21baec154b78..b604d26bd48c 100644
--- a/arch/arm/boot/dts/omap2420-n810.dts
+++ b/arch/arm/boot/dts/omap2420-n810.dts
@@ -6,3 +6,10 @@
6 model = "Nokia N810"; 6 model = "Nokia N810";
7 compatible = "nokia,n810", "nokia,n8x0", "ti,omap2420", "ti,omap2"; 7 compatible = "nokia,n810", "nokia,n8x0", "ti,omap2420", "ti,omap2";
8}; 8};
9
10&i2c2 {
11 aic3x@18 {
12 compatible = "tlv320aic3x";
13 reg = <0x18>;
14 };
15};
diff --git a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
index 89608b206519..24c50db2a478 100644
--- a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
+++ b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
@@ -27,6 +27,12 @@
27 27
28&i2c1 { 28&i2c1 {
29 clock-frequency = <400000>; 29 clock-frequency = <400000>;
30
31 pmic@72 {
32 compatible = "menelaus";
33 reg = <0x72>;
34 interrupts = <7 IRQ_TYPE_EDGE_RISING>;
35 };
30}; 36};
31 37
32&i2c2 { 38&i2c2 {
diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi
index 226f3631c230..d0e884d3a737 100644
--- a/arch/arm/boot/dts/omap3.dtsi
+++ b/arch/arm/boot/dts/omap3.dtsi
@@ -141,10 +141,9 @@
141 }; 141 };
142 142
143 intc: interrupt-controller@48200000 { 143 intc: interrupt-controller@48200000 {
144 compatible = "ti,omap2-intc"; 144 compatible = "ti,omap3-intc";
145 interrupt-controller; 145 interrupt-controller;
146 #interrupt-cells = <1>; 146 #interrupt-cells = <1>;
147 ti,intc-size = <96>;
148 reg = <0x48200000 0x1000>; 147 reg = <0x48200000 0x1000>;
149 }; 148 };
150 149
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 1947a09e5a3f..0e6d548b70d9 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -36,17 +36,6 @@ config OLD_IRQ_AT91
36 select MULTI_IRQ_HANDLER 36 select MULTI_IRQ_HANDLER
37 select SPARSE_IRQ 37 select SPARSE_IRQ
38 38
39config AT91_SAM9_ALT_RESET
40 bool
41 default !ARCH_AT91X40
42
43config AT91_SAM9G45_RESET
44 bool
45 default !ARCH_AT91X40
46
47config AT91_SAM9_TIME
48 bool
49
50config HAVE_AT91_SMD 39config HAVE_AT91_SMD
51 bool 40 bool
52 41
@@ -55,18 +44,20 @@ config HAVE_AT91_H32MX
55 44
56config SOC_AT91SAM9 45config SOC_AT91SAM9
57 bool 46 bool
58 select AT91_SAM9_TIME
59 select ATMEL_AIC_IRQ if !OLD_IRQ_AT91 47 select ATMEL_AIC_IRQ if !OLD_IRQ_AT91
60 select CPU_ARM926T 48 select CPU_ARM926T
61 select GENERIC_CLOCKEVENTS 49 select GENERIC_CLOCKEVENTS
50 select MEMORY if USE_OF
51 select ATMEL_SDRAMC if USE_OF
62 52
63config SOC_SAMA5 53config SOC_SAMA5
64 bool 54 bool
65 select AT91_SAM9_TIME
66 select ATMEL_AIC5_IRQ 55 select ATMEL_AIC5_IRQ
67 select CPU_V7 56 select CPU_V7
68 select GENERIC_CLOCKEVENTS 57 select GENERIC_CLOCKEVENTS
69 select USE_OF 58 select USE_OF
59 select MEMORY
60 select ATMEL_SDRAMC
70 61
71menu "Atmel AT91 System-on-Chip" 62menu "Atmel AT91 System-on-Chip"
72 63
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index 603365e44ed5..ac99d87ffefe 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -9,9 +9,6 @@ obj- :=
9 9
10obj-$(CONFIG_OLD_IRQ_AT91) += irq.o 10obj-$(CONFIG_OLD_IRQ_AT91) += irq.o
11obj-$(CONFIG_OLD_CLK_AT91) += clock.o 11obj-$(CONFIG_OLD_CLK_AT91) += clock.o
12obj-$(CONFIG_AT91_SAM9_ALT_RESET) += at91sam9_alt_reset.o
13obj-$(CONFIG_AT91_SAM9G45_RESET) += at91sam9g45_reset.o
14obj-$(CONFIG_AT91_SAM9_TIME) += at91sam926x_time.o
15obj-$(CONFIG_SOC_AT91SAM9) += sam9_smc.o 12obj-$(CONFIG_SOC_AT91SAM9) += sam9_smc.o
16 13
17# CPU-specific support 14# CPU-specific support
diff --git a/arch/arm/mach-at91/at91_rstc.h b/arch/arm/mach-at91/at91_rstc.h
deleted file mode 100644
index a600e6992920..000000000000
--- a/arch/arm/mach-at91/at91_rstc.h
+++ /dev/null
@@ -1,53 +0,0 @@
1/*
2 * arch/arm/mach-at91/include/mach/at91_rstc.h
3 *
4 * Copyright (C) 2007 Andrew Victor
5 * Copyright (C) 2007 Atmel Corporation.
6 *
7 * Reset Controller (RSTC) - System peripherals regsters.
8 * Based on AT91SAM9261 datasheet revision D.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 */
15
16#ifndef AT91_RSTC_H
17#define AT91_RSTC_H
18
19#ifndef __ASSEMBLY__
20extern void __iomem *at91_rstc_base;
21
22#define at91_rstc_read(field) \
23 __raw_readl(at91_rstc_base + field)
24
25#define at91_rstc_write(field, value) \
26 __raw_writel(value, at91_rstc_base + field)
27#else
28.extern at91_rstc_base
29#endif
30
31#define AT91_RSTC_CR 0x00 /* Reset Controller Control Register */
32#define AT91_RSTC_PROCRST (1 << 0) /* Processor Reset */
33#define AT91_RSTC_PERRST (1 << 2) /* Peripheral Reset */
34#define AT91_RSTC_EXTRST (1 << 3) /* External Reset */
35#define AT91_RSTC_KEY (0xa5 << 24) /* KEY Password */
36
37#define AT91_RSTC_SR 0x04 /* Reset Controller Status Register */
38#define AT91_RSTC_URSTS (1 << 0) /* User Reset Status */
39#define AT91_RSTC_RSTTYP (7 << 8) /* Reset Type */
40#define AT91_RSTC_RSTTYP_GENERAL (0 << 8)
41#define AT91_RSTC_RSTTYP_WAKEUP (1 << 8)
42#define AT91_RSTC_RSTTYP_WATCHDOG (2 << 8)
43#define AT91_RSTC_RSTTYP_SOFTWARE (3 << 8)
44#define AT91_RSTC_RSTTYP_USER (4 << 8)
45#define AT91_RSTC_NRSTL (1 << 16) /* NRST Pin Level */
46#define AT91_RSTC_SRCMP (1 << 17) /* Software Reset Command in Progress */
47
48#define AT91_RSTC_MR 0x08 /* Reset Controller Mode Register */
49#define AT91_RSTC_URSTEN (1 << 0) /* User Reset Enable */
50#define AT91_RSTC_URSTIEN (1 << 4) /* User Reset Interrupt Enable */
51#define AT91_RSTC_ERSTL (0xf << 8) /* External Reset Length */
52
53#endif
diff --git a/arch/arm/mach-at91/at91_shdwc.h b/arch/arm/mach-at91/at91_shdwc.h
deleted file mode 100644
index 9e29f31ec9a6..000000000000
--- a/arch/arm/mach-at91/at91_shdwc.h
+++ /dev/null
@@ -1,50 +0,0 @@
1/*
2 * arch/arm/mach-at91/include/mach/at91_shdwc.h
3 *
4 * Copyright (C) 2007 Andrew Victor
5 * Copyright (C) 2007 Atmel Corporation.
6 *
7 * Shutdown Controller (SHDWC) - System peripherals regsters.
8 * Based on AT91SAM9261 datasheet revision D.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 */
15
16#ifndef AT91_SHDWC_H
17#define AT91_SHDWC_H
18
19#ifndef __ASSEMBLY__
20extern void __iomem *at91_shdwc_base;
21
22#define at91_shdwc_read(field) \
23 __raw_readl(at91_shdwc_base + field)
24
25#define at91_shdwc_write(field, value) \
26 __raw_writel(value, at91_shdwc_base + field)
27#endif
28
29#define AT91_SHDW_CR 0x00 /* Shut Down Control Register */
30#define AT91_SHDW_SHDW (1 << 0) /* Shut Down command */
31#define AT91_SHDW_KEY (0xa5 << 24) /* KEY Password */
32
33#define AT91_SHDW_MR 0x04 /* Shut Down Mode Register */
34#define AT91_SHDW_WKMODE0 (3 << 0) /* Wake-up 0 Mode Selection */
35#define AT91_SHDW_WKMODE0_NONE 0
36#define AT91_SHDW_WKMODE0_HIGH 1
37#define AT91_SHDW_WKMODE0_LOW 2
38#define AT91_SHDW_WKMODE0_ANYLEVEL 3
39#define AT91_SHDW_CPTWK0_MAX 0xf /* Maximum Counter On Wake Up 0 */
40#define AT91_SHDW_CPTWK0 (AT91_SHDW_CPTWK0_MAX << 4) /* Counter On Wake Up 0 */
41#define AT91_SHDW_CPTWK0_(x) ((x) << 4)
42#define AT91_SHDW_RTTWKEN (1 << 16) /* Real Time Timer Wake-up Enable */
43#define AT91_SHDW_RTCWKEN (1 << 17) /* Real Time Clock Wake-up Enable */
44
45#define AT91_SHDW_SR 0x08 /* Shut Down Status Register */
46#define AT91_SHDW_WAKEUP0 (1 << 0) /* Wake-up 0 Status */
47#define AT91_SHDW_RTTWK (1 << 16) /* Real-time Timer Wake-up */
48#define AT91_SHDW_RTCWK (1 << 17) /* Real-time Clock Wake-up [SAM9RL] */
49
50#endif
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
index 3477ba94c4c5..aab1f969a7c3 100644
--- a/arch/arm/mach-at91/at91sam9260.c
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/platform_device.h>
14#include <linux/clk/at91_pmc.h> 15#include <linux/clk/at91_pmc.h>
15 16
16#include <asm/proc-fns.h> 17#include <asm/proc-fns.h>
@@ -24,7 +25,6 @@
24#include <mach/hardware.h> 25#include <mach/hardware.h>
25 26
26#include "at91_aic.h" 27#include "at91_aic.h"
27#include "at91_rstc.h"
28#include "soc.h" 28#include "soc.h"
29#include "generic.h" 29#include "generic.h"
30#include "sam9_smc.h" 30#include "sam9_smc.h"
@@ -342,8 +342,6 @@ static void __init at91sam9260_map_io(void)
342 342
343static void __init at91sam9260_ioremap_registers(void) 343static void __init at91sam9260_ioremap_registers(void)
344{ 344{
345 at91_ioremap_shdwc(AT91SAM9260_BASE_SHDWC);
346 at91_ioremap_rstc(AT91SAM9260_BASE_RSTC);
347 at91_ioremap_ramc(0, AT91SAM9260_BASE_SDRAMC, 512); 345 at91_ioremap_ramc(0, AT91SAM9260_BASE_SDRAMC, 512);
348 at91sam926x_ioremap_pit(AT91SAM9260_BASE_PIT); 346 at91sam926x_ioremap_pit(AT91SAM9260_BASE_PIT);
349 at91sam9_ioremap_smc(0, AT91SAM9260_BASE_SMC); 347 at91sam9_ioremap_smc(0, AT91SAM9260_BASE_SMC);
@@ -354,7 +352,6 @@ static void __init at91sam9260_ioremap_registers(void)
354static void __init at91sam9260_initialize(void) 352static void __init at91sam9260_initialize(void)
355{ 353{
356 arm_pm_idle = at91sam9_idle; 354 arm_pm_idle = at91sam9_idle;
357 arm_pm_restart = at91sam9_alt_restart;
358 355
359 at91_sysirq_mask_rtt(AT91SAM9260_BASE_RTT); 356 at91_sysirq_mask_rtt(AT91SAM9260_BASE_RTT);
360 357
@@ -362,6 +359,45 @@ static void __init at91sam9260_initialize(void)
362 at91_gpio_init(at91sam9260_gpio, 3); 359 at91_gpio_init(at91sam9260_gpio, 3);
363} 360}
364 361
362static struct resource rstc_resources[] = {
363 [0] = {
364 .start = AT91SAM9260_BASE_RSTC,
365 .end = AT91SAM9260_BASE_RSTC + SZ_16 - 1,
366 .flags = IORESOURCE_MEM,
367 },
368 [1] = {
369 .start = AT91SAM9260_BASE_SDRAMC,
370 .end = AT91SAM9260_BASE_SDRAMC + SZ_512 - 1,
371 .flags = IORESOURCE_MEM,
372 },
373};
374
375static struct platform_device rstc_device = {
376 .name = "at91-sam9260-reset",
377 .resource = rstc_resources,
378 .num_resources = ARRAY_SIZE(rstc_resources),
379};
380
381static struct resource shdwc_resources[] = {
382 [0] = {
383 .start = AT91SAM9260_BASE_SHDWC,
384 .end = AT91SAM9260_BASE_SHDWC + SZ_16 - 1,
385 .flags = IORESOURCE_MEM,
386 },
387};
388
389static struct platform_device shdwc_device = {
390 .name = "at91-poweroff",
391 .resource = shdwc_resources,
392 .num_resources = ARRAY_SIZE(shdwc_resources),
393};
394
395static void __init at91sam9260_register_devices(void)
396{
397 platform_device_register(&rstc_device);
398 platform_device_register(&shdwc_device);
399}
400
365/* -------------------------------------------------------------------- 401/* --------------------------------------------------------------------
366 * Interrupt initialization 402 * Interrupt initialization
367 * -------------------------------------------------------------------- */ 403 * -------------------------------------------------------------------- */
@@ -404,6 +440,11 @@ static unsigned int at91sam9260_default_irq_priority[NR_AIC_IRQS] __initdata = {
404 0, /* Advanced Interrupt Controller */ 440 0, /* Advanced Interrupt Controller */
405}; 441};
406 442
443static void __init at91sam9260_init_time(void)
444{
445 at91sam926x_pit_init(NR_IRQS_LEGACY + AT91_ID_SYS);
446}
447
407AT91_SOC_START(at91sam9260) 448AT91_SOC_START(at91sam9260)
408 .map_io = at91sam9260_map_io, 449 .map_io = at91sam9260_map_io,
409 .default_irq_priority = at91sam9260_default_irq_priority, 450 .default_irq_priority = at91sam9260_default_irq_priority,
@@ -411,5 +452,7 @@ AT91_SOC_START(at91sam9260)
411 | (1 << AT91SAM9260_ID_IRQ2), 452 | (1 << AT91SAM9260_ID_IRQ2),
412 .ioremap_registers = at91sam9260_ioremap_registers, 453 .ioremap_registers = at91sam9260_ioremap_registers,
413 .register_clocks = at91sam9260_register_clocks, 454 .register_clocks = at91sam9260_register_clocks,
455 .register_devices = at91sam9260_register_devices,
414 .init = at91sam9260_initialize, 456 .init = at91sam9260_initialize,
457 .init_time = at91sam9260_init_time,
415AT91_SOC_END 458AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
index fb164a5d04a9..a8bd35963332 100644
--- a/arch/arm/mach-at91/at91sam9261.c
+++ b/arch/arm/mach-at91/at91sam9261.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/platform_device.h>
14#include <linux/clk/at91_pmc.h> 15#include <linux/clk/at91_pmc.h>
15 16
16#include <asm/proc-fns.h> 17#include <asm/proc-fns.h>
@@ -23,7 +24,6 @@
23#include <mach/hardware.h> 24#include <mach/hardware.h>
24 25
25#include "at91_aic.h" 26#include "at91_aic.h"
26#include "at91_rstc.h"
27#include "soc.h" 27#include "soc.h"
28#include "generic.h" 28#include "generic.h"
29#include "sam9_smc.h" 29#include "sam9_smc.h"
@@ -301,8 +301,6 @@ static void __init at91sam9261_map_io(void)
301 301
302static void __init at91sam9261_ioremap_registers(void) 302static void __init at91sam9261_ioremap_registers(void)
303{ 303{
304 at91_ioremap_shdwc(AT91SAM9261_BASE_SHDWC);
305 at91_ioremap_rstc(AT91SAM9261_BASE_RSTC);
306 at91_ioremap_ramc(0, AT91SAM9261_BASE_SDRAMC, 512); 304 at91_ioremap_ramc(0, AT91SAM9261_BASE_SDRAMC, 512);
307 at91sam926x_ioremap_pit(AT91SAM9261_BASE_PIT); 305 at91sam926x_ioremap_pit(AT91SAM9261_BASE_PIT);
308 at91sam9_ioremap_smc(0, AT91SAM9261_BASE_SMC); 306 at91sam9_ioremap_smc(0, AT91SAM9261_BASE_SMC);
@@ -313,7 +311,6 @@ static void __init at91sam9261_ioremap_registers(void)
313static void __init at91sam9261_initialize(void) 311static void __init at91sam9261_initialize(void)
314{ 312{
315 arm_pm_idle = at91sam9_idle; 313 arm_pm_idle = at91sam9_idle;
316 arm_pm_restart = at91sam9_alt_restart;
317 314
318 at91_sysirq_mask_rtt(AT91SAM9261_BASE_RTT); 315 at91_sysirq_mask_rtt(AT91SAM9261_BASE_RTT);
319 316
@@ -321,6 +318,45 @@ static void __init at91sam9261_initialize(void)
321 at91_gpio_init(at91sam9261_gpio, 3); 318 at91_gpio_init(at91sam9261_gpio, 3);
322} 319}
323 320
321static struct resource rstc_resources[] = {
322 [0] = {
323 .start = AT91SAM9261_BASE_RSTC,
324 .end = AT91SAM9261_BASE_RSTC + SZ_16 - 1,
325 .flags = IORESOURCE_MEM,
326 },
327 [1] = {
328 .start = AT91SAM9261_BASE_SDRAMC,
329 .end = AT91SAM9261_BASE_SDRAMC + SZ_512 - 1,
330 .flags = IORESOURCE_MEM,
331 },
332};
333
334static struct platform_device rstc_device = {
335 .name = "at91-sam9260-reset",
336 .resource = rstc_resources,
337 .num_resources = ARRAY_SIZE(rstc_resources),
338};
339
340static struct resource shdwc_resources[] = {
341 [0] = {
342 .start = AT91SAM9261_BASE_SHDWC,
343 .end = AT91SAM9261_BASE_SHDWC + SZ_16 - 1,
344 .flags = IORESOURCE_MEM,
345 },
346};
347
348static struct platform_device shdwc_device = {
349 .name = "at91-poweroff",
350 .resource = shdwc_resources,
351 .num_resources = ARRAY_SIZE(shdwc_resources),
352};
353
354static void __init at91sam9261_register_devices(void)
355{
356 platform_device_register(&rstc_device);
357 platform_device_register(&shdwc_device);
358}
359
324/* -------------------------------------------------------------------- 360/* --------------------------------------------------------------------
325 * Interrupt initialization 361 * Interrupt initialization
326 * -------------------------------------------------------------------- */ 362 * -------------------------------------------------------------------- */
@@ -363,6 +399,11 @@ static unsigned int at91sam9261_default_irq_priority[NR_AIC_IRQS] __initdata = {
363 0, /* Advanced Interrupt Controller */ 399 0, /* Advanced Interrupt Controller */
364}; 400};
365 401
402static void __init at91sam9261_init_time(void)
403{
404 at91sam926x_pit_init(NR_IRQS_LEGACY + AT91_ID_SYS);
405}
406
366AT91_SOC_START(at91sam9261) 407AT91_SOC_START(at91sam9261)
367 .map_io = at91sam9261_map_io, 408 .map_io = at91sam9261_map_io,
368 .default_irq_priority = at91sam9261_default_irq_priority, 409 .default_irq_priority = at91sam9261_default_irq_priority,
@@ -370,5 +411,7 @@ AT91_SOC_START(at91sam9261)
370 | (1 << AT91SAM9261_ID_IRQ2), 411 | (1 << AT91SAM9261_ID_IRQ2),
371 .ioremap_registers = at91sam9261_ioremap_registers, 412 .ioremap_registers = at91sam9261_ioremap_registers,
372 .register_clocks = at91sam9261_register_clocks, 413 .register_clocks = at91sam9261_register_clocks,
414 .register_devices = at91sam9261_register_devices,
373 .init = at91sam9261_initialize, 415 .init = at91sam9261_initialize,
416 .init_time = at91sam9261_init_time,
374AT91_SOC_END 417AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
index 810fa5f15a51..fbff228cc63e 100644
--- a/arch/arm/mach-at91/at91sam9263.c
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/platform_device.h>
14#include <linux/clk/at91_pmc.h> 15#include <linux/clk/at91_pmc.h>
15 16
16#include <asm/proc-fns.h> 17#include <asm/proc-fns.h>
@@ -22,7 +23,6 @@
22#include <mach/hardware.h> 23#include <mach/hardware.h>
23 24
24#include "at91_aic.h" 25#include "at91_aic.h"
25#include "at91_rstc.h"
26#include "soc.h" 26#include "soc.h"
27#include "generic.h" 27#include "generic.h"
28#include "sam9_smc.h" 28#include "sam9_smc.h"
@@ -321,8 +321,6 @@ static void __init at91sam9263_map_io(void)
321 321
322static void __init at91sam9263_ioremap_registers(void) 322static void __init at91sam9263_ioremap_registers(void)
323{ 323{
324 at91_ioremap_shdwc(AT91SAM9263_BASE_SHDWC);
325 at91_ioremap_rstc(AT91SAM9263_BASE_RSTC);
326 at91_ioremap_ramc(0, AT91SAM9263_BASE_SDRAMC0, 512); 324 at91_ioremap_ramc(0, AT91SAM9263_BASE_SDRAMC0, 512);
327 at91_ioremap_ramc(1, AT91SAM9263_BASE_SDRAMC1, 512); 325 at91_ioremap_ramc(1, AT91SAM9263_BASE_SDRAMC1, 512);
328 at91sam926x_ioremap_pit(AT91SAM9263_BASE_PIT); 326 at91sam926x_ioremap_pit(AT91SAM9263_BASE_PIT);
@@ -335,7 +333,6 @@ static void __init at91sam9263_ioremap_registers(void)
335static void __init at91sam9263_initialize(void) 333static void __init at91sam9263_initialize(void)
336{ 334{
337 arm_pm_idle = at91sam9_idle; 335 arm_pm_idle = at91sam9_idle;
338 arm_pm_restart = at91sam9_alt_restart;
339 336
340 at91_sysirq_mask_rtt(AT91SAM9263_BASE_RTT0); 337 at91_sysirq_mask_rtt(AT91SAM9263_BASE_RTT0);
341 at91_sysirq_mask_rtt(AT91SAM9263_BASE_RTT1); 338 at91_sysirq_mask_rtt(AT91SAM9263_BASE_RTT1);
@@ -344,6 +341,45 @@ static void __init at91sam9263_initialize(void)
344 at91_gpio_init(at91sam9263_gpio, 5); 341 at91_gpio_init(at91sam9263_gpio, 5);
345} 342}
346 343
344static struct resource rstc_resources[] = {
345 [0] = {
346 .start = AT91SAM9263_BASE_RSTC,
347 .end = AT91SAM9263_BASE_RSTC + SZ_16 - 1,
348 .flags = IORESOURCE_MEM,
349 },
350 [1] = {
351 .start = AT91SAM9263_BASE_SDRAMC0,
352 .end = AT91SAM9263_BASE_SDRAMC0 + SZ_512 - 1,
353 .flags = IORESOURCE_MEM,
354 },
355};
356
357static struct platform_device rstc_device = {
358 .name = "at91-sam9260-reset",
359 .resource = rstc_resources,
360 .num_resources = ARRAY_SIZE(rstc_resources),
361};
362
363static struct resource shdwc_resources[] = {
364 [0] = {
365 .start = AT91SAM9263_BASE_SHDWC,
366 .end = AT91SAM9263_BASE_SHDWC + SZ_16 - 1,
367 .flags = IORESOURCE_MEM,
368 },
369};
370
371static struct platform_device shdwc_device = {
372 .name = "at91-poweroff",
373 .resource = shdwc_resources,
374 .num_resources = ARRAY_SIZE(shdwc_resources),
375};
376
377static void __init at91sam9263_register_devices(void)
378{
379 platform_device_register(&rstc_device);
380 platform_device_register(&shdwc_device);
381}
382
347/* -------------------------------------------------------------------- 383/* --------------------------------------------------------------------
348 * Interrupt initialization 384 * Interrupt initialization
349 * -------------------------------------------------------------------- */ 385 * -------------------------------------------------------------------- */
@@ -386,11 +422,18 @@ static unsigned int at91sam9263_default_irq_priority[NR_AIC_IRQS] __initdata = {
386 0, /* Advanced Interrupt Controller (IRQ1) */ 422 0, /* Advanced Interrupt Controller (IRQ1) */
387}; 423};
388 424
425static void __init at91sam9263_init_time(void)
426{
427 at91sam926x_pit_init(NR_IRQS_LEGACY + AT91_ID_SYS);
428}
429
389AT91_SOC_START(at91sam9263) 430AT91_SOC_START(at91sam9263)
390 .map_io = at91sam9263_map_io, 431 .map_io = at91sam9263_map_io,
391 .default_irq_priority = at91sam9263_default_irq_priority, 432 .default_irq_priority = at91sam9263_default_irq_priority,
392 .extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1), 433 .extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1),
393 .ioremap_registers = at91sam9263_ioremap_registers, 434 .ioremap_registers = at91sam9263_ioremap_registers,
394 .register_clocks = at91sam9263_register_clocks, 435 .register_clocks = at91sam9263_register_clocks,
436 .register_devices = at91sam9263_register_devices,
395 .init = at91sam9263_initialize, 437 .init = at91sam9263_initialize,
438 .init_time = at91sam9263_init_time,
396AT91_SOC_END 439AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam926x_time.c b/arch/arm/mach-at91/at91sam926x_time.c
deleted file mode 100644
index 0a9e2fc8f796..000000000000
--- a/arch/arm/mach-at91/at91sam926x_time.c
+++ /dev/null
@@ -1,294 +0,0 @@
1/*
2 * at91sam926x_time.c - Periodic Interval Timer (PIT) for at91sam926x
3 *
4 * Copyright (C) 2005-2006 M. Amine SAYA, ATMEL Rousset, France
5 * Revision 2005 M. Nicolas Diremdjian, ATMEL Rousset, France
6 * Converted to ClockSource/ClockEvents by David Brownell.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#include <linux/interrupt.h>
13#include <linux/irq.h>
14#include <linux/kernel.h>
15#include <linux/clk.h>
16#include <linux/clockchips.h>
17#include <linux/of.h>
18#include <linux/of_address.h>
19#include <linux/of_irq.h>
20
21#include <asm/mach/time.h>
22#include <mach/hardware.h>
23
24#define AT91_PIT_MR 0x00 /* Mode Register */
25#define AT91_PIT_PITIEN (1 << 25) /* Timer Interrupt Enable */
26#define AT91_PIT_PITEN (1 << 24) /* Timer Enabled */
27#define AT91_PIT_PIV (0xfffff) /* Periodic Interval Value */
28
29#define AT91_PIT_SR 0x04 /* Status Register */
30#define AT91_PIT_PITS (1 << 0) /* Timer Status */
31
32#define AT91_PIT_PIVR 0x08 /* Periodic Interval Value Register */
33#define AT91_PIT_PIIR 0x0c /* Periodic Interval Image Register */
34#define AT91_PIT_PICNT (0xfff << 20) /* Interval Counter */
35#define AT91_PIT_CPIV (0xfffff) /* Inverval Value */
36
37#define PIT_CPIV(x) ((x) & AT91_PIT_CPIV)
38#define PIT_PICNT(x) (((x) & AT91_PIT_PICNT) >> 20)
39
40static u32 pit_cycle; /* write-once */
41static u32 pit_cnt; /* access only w/system irq blocked */
42static void __iomem *pit_base_addr __read_mostly;
43static struct clk *mck;
44
45static inline unsigned int pit_read(unsigned int reg_offset)
46{
47 return __raw_readl(pit_base_addr + reg_offset);
48}
49
50static inline void pit_write(unsigned int reg_offset, unsigned long value)
51{
52 __raw_writel(value, pit_base_addr + reg_offset);
53}
54
55/*
56 * Clocksource: just a monotonic counter of MCK/16 cycles.
57 * We don't care whether or not PIT irqs are enabled.
58 */
59static cycle_t read_pit_clk(struct clocksource *cs)
60{
61 unsigned long flags;
62 u32 elapsed;
63 u32 t;
64
65 raw_local_irq_save(flags);
66 elapsed = pit_cnt;
67 t = pit_read(AT91_PIT_PIIR);
68 raw_local_irq_restore(flags);
69
70 elapsed += PIT_PICNT(t) * pit_cycle;
71 elapsed += PIT_CPIV(t);
72 return elapsed;
73}
74
75static struct clocksource pit_clk = {
76 .name = "pit",
77 .rating = 175,
78 .read = read_pit_clk,
79 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
80};
81
82
83/*
84 * Clockevent device: interrupts every 1/HZ (== pit_cycles * MCK/16)
85 */
86static void
87pit_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev)
88{
89 switch (mode) {
90 case CLOCK_EVT_MODE_PERIODIC:
91 /* update clocksource counter */
92 pit_cnt += pit_cycle * PIT_PICNT(pit_read(AT91_PIT_PIVR));
93 pit_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN
94 | AT91_PIT_PITIEN);
95 break;
96 case CLOCK_EVT_MODE_ONESHOT:
97 BUG();
98 /* FALLTHROUGH */
99 case CLOCK_EVT_MODE_SHUTDOWN:
100 case CLOCK_EVT_MODE_UNUSED:
101 /* disable irq, leaving the clocksource active */
102 pit_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN);
103 break;
104 case CLOCK_EVT_MODE_RESUME:
105 break;
106 }
107}
108
109static void at91sam926x_pit_suspend(struct clock_event_device *cedev)
110{
111 /* Disable timer */
112 pit_write(AT91_PIT_MR, 0);
113}
114
115static void at91sam926x_pit_reset(void)
116{
117 /* Disable timer and irqs */
118 pit_write(AT91_PIT_MR, 0);
119
120 /* Clear any pending interrupts, wait for PIT to stop counting */
121 while (PIT_CPIV(pit_read(AT91_PIT_PIVR)) != 0)
122 cpu_relax();
123
124 /* Start PIT but don't enable IRQ */
125 pit_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN);
126}
127
128static void at91sam926x_pit_resume(struct clock_event_device *cedev)
129{
130 at91sam926x_pit_reset();
131}
132
133static struct clock_event_device pit_clkevt = {
134 .name = "pit",
135 .features = CLOCK_EVT_FEAT_PERIODIC,
136 .shift = 32,
137 .rating = 100,
138 .set_mode = pit_clkevt_mode,
139 .suspend = at91sam926x_pit_suspend,
140 .resume = at91sam926x_pit_resume,
141};
142
143
144/*
145 * IRQ handler for the timer.
146 */
147static irqreturn_t at91sam926x_pit_interrupt(int irq, void *dev_id)
148{
149 /*
150 * irqs should be disabled here, but as the irq is shared they are only
151 * guaranteed to be off if the timer irq is registered first.
152 */
153 WARN_ON_ONCE(!irqs_disabled());
154
155 /* The PIT interrupt may be disabled, and is shared */
156 if ((pit_clkevt.mode == CLOCK_EVT_MODE_PERIODIC)
157 && (pit_read(AT91_PIT_SR) & AT91_PIT_PITS)) {
158 unsigned nr_ticks;
159
160 /* Get number of ticks performed before irq, and ack it */
161 nr_ticks = PIT_PICNT(pit_read(AT91_PIT_PIVR));
162 do {
163 pit_cnt += pit_cycle;
164 pit_clkevt.event_handler(&pit_clkevt);
165 nr_ticks--;
166 } while (nr_ticks);
167
168 return IRQ_HANDLED;
169 }
170
171 return IRQ_NONE;
172}
173
174static struct irqaction at91sam926x_pit_irq = {
175 .name = "at91_tick",
176 .flags = IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL,
177 .handler = at91sam926x_pit_interrupt,
178 .irq = NR_IRQS_LEGACY + AT91_ID_SYS,
179};
180
181#ifdef CONFIG_OF
182static struct of_device_id pit_timer_ids[] = {
183 { .compatible = "atmel,at91sam9260-pit" },
184 { /* sentinel */ }
185};
186
187static int __init of_at91sam926x_pit_init(void)
188{
189 struct device_node *np;
190 int ret;
191
192 np = of_find_matching_node(NULL, pit_timer_ids);
193 if (!np)
194 goto err;
195
196 pit_base_addr = of_iomap(np, 0);
197 if (!pit_base_addr)
198 goto node_err;
199
200 mck = of_clk_get(np, 0);
201
202 /* Get the interrupts property */
203 ret = irq_of_parse_and_map(np, 0);
204 if (!ret) {
205 pr_crit("AT91: PIT: Unable to get IRQ from DT\n");
206 if (!IS_ERR(mck))
207 clk_put(mck);
208 goto ioremap_err;
209 }
210 at91sam926x_pit_irq.irq = ret;
211
212 of_node_put(np);
213
214 return 0;
215
216ioremap_err:
217 iounmap(pit_base_addr);
218node_err:
219 of_node_put(np);
220err:
221 return -EINVAL;
222}
223#else
224static int __init of_at91sam926x_pit_init(void)
225{
226 return -EINVAL;
227}
228#endif
229
230/*
231 * Set up both clocksource and clockevent support.
232 */
233void __init at91sam926x_pit_init(void)
234{
235 unsigned long pit_rate;
236 unsigned bits;
237 int ret;
238
239 mck = ERR_PTR(-ENOENT);
240
241 /* For device tree enabled device: initialize here */
242 of_at91sam926x_pit_init();
243
244 /*
245 * Use our actual MCK to figure out how many MCK/16 ticks per
246 * 1/HZ period (instead of a compile-time constant LATCH).
247 */
248 if (IS_ERR(mck))
249 mck = clk_get(NULL, "mck");
250
251 if (IS_ERR(mck))
252 panic("AT91: PIT: Unable to get mck clk\n");
253 pit_rate = clk_get_rate(mck) / 16;
254 pit_cycle = (pit_rate + HZ/2) / HZ;
255 WARN_ON(((pit_cycle - 1) & ~AT91_PIT_PIV) != 0);
256
257 /* Initialize and enable the timer */
258 at91sam926x_pit_reset();
259
260 /*
261 * Register clocksource. The high order bits of PIV are unused,
262 * so this isn't a 32-bit counter unless we get clockevent irqs.
263 */
264 bits = 12 /* PICNT */ + ilog2(pit_cycle) /* PIV */;
265 pit_clk.mask = CLOCKSOURCE_MASK(bits);
266 clocksource_register_hz(&pit_clk, pit_rate);
267
268 /* Set up irq handler */
269 ret = setup_irq(at91sam926x_pit_irq.irq, &at91sam926x_pit_irq);
270 if (ret)
271 pr_crit("AT91: PIT: Unable to setup IRQ\n");
272
273 /* Set up and register clockevents */
274 pit_clkevt.mult = div_sc(pit_rate, NSEC_PER_SEC, pit_clkevt.shift);
275 pit_clkevt.cpumask = cpumask_of(0);
276 clockevents_register_device(&pit_clkevt);
277}
278
279void __init at91sam926x_ioremap_pit(u32 addr)
280{
281#if defined(CONFIG_OF)
282 struct device_node *np =
283 of_find_matching_node(NULL, pit_timer_ids);
284
285 if (np) {
286 of_node_put(np);
287 return;
288 }
289#endif
290 pit_base_addr = ioremap(addr, 16);
291
292 if (!pit_base_addr)
293 panic("Impossible to ioremap PIT\n");
294}
diff --git a/arch/arm/mach-at91/at91sam9_alt_reset.S b/arch/arm/mach-at91/at91sam9_alt_reset.S
deleted file mode 100644
index f039538d3bdb..000000000000
--- a/arch/arm/mach-at91/at91sam9_alt_reset.S
+++ /dev/null
@@ -1,40 +0,0 @@
1/*
2 * reset AT91SAM9G20 as per errata
3 *
4 * (C) BitBox Ltd 2010
5 *
6 * unless the SDRAM is cleanly shutdown before we hit the
7 * reset register it can be left driving the data bus and
8 * killing the chance of a subsequent boot from NAND
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 */
15
16#include <linux/linkage.h>
17#include <mach/hardware.h>
18#include <mach/at91_ramc.h>
19#include "at91_rstc.h"
20
21 .arm
22
23 .globl at91sam9_alt_restart
24
25at91sam9_alt_restart: ldr r0, =at91_ramc_base @ preload constants
26 ldr r0, [r0]
27 ldr r4, =at91_rstc_base
28 ldr r1, [r4]
29
30 mov r2, #1
31 mov r3, #AT91_SDRAMC_LPCB_POWER_DOWN
32 ldr r4, =AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST
33
34 .balign 32 @ align to cache line
35
36 str r2, [r0, #AT91_SDRAMC_TR] @ disable SDRAM access
37 str r3, [r0, #AT91_SDRAMC_LPR] @ power down SDRAM
38 str r4, [r1, #AT91_RSTC_CR] @ reset processor
39
40 b .
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c
index 9d45496e4932..405427ec05f8 100644
--- a/arch/arm/mach-at91/at91sam9g45.c
+++ b/arch/arm/mach-at91/at91sam9g45.c
@@ -13,6 +13,7 @@
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/dma-mapping.h> 14#include <linux/dma-mapping.h>
15#include <linux/clk/at91_pmc.h> 15#include <linux/clk/at91_pmc.h>
16#include <linux/platform_device.h>
16 17
17#include <asm/irq.h> 18#include <asm/irq.h>
18#include <asm/mach/arch.h> 19#include <asm/mach/arch.h>
@@ -371,8 +372,6 @@ static void __init at91sam9g45_map_io(void)
371 372
372static void __init at91sam9g45_ioremap_registers(void) 373static void __init at91sam9g45_ioremap_registers(void)
373{ 374{
374 at91_ioremap_shdwc(AT91SAM9G45_BASE_SHDWC);
375 at91_ioremap_rstc(AT91SAM9G45_BASE_RSTC);
376 at91_ioremap_ramc(0, AT91SAM9G45_BASE_DDRSDRC1, 512); 375 at91_ioremap_ramc(0, AT91SAM9G45_BASE_DDRSDRC1, 512);
377 at91_ioremap_ramc(1, AT91SAM9G45_BASE_DDRSDRC0, 512); 376 at91_ioremap_ramc(1, AT91SAM9G45_BASE_DDRSDRC0, 512);
378 at91sam926x_ioremap_pit(AT91SAM9G45_BASE_PIT); 377 at91sam926x_ioremap_pit(AT91SAM9G45_BASE_PIT);
@@ -384,7 +383,6 @@ static void __init at91sam9g45_ioremap_registers(void)
384static void __init at91sam9g45_initialize(void) 383static void __init at91sam9g45_initialize(void)
385{ 384{
386 arm_pm_idle = at91sam9_idle; 385 arm_pm_idle = at91sam9_idle;
387 arm_pm_restart = at91sam9g45_restart;
388 386
389 at91_sysirq_mask_rtc(AT91SAM9G45_BASE_RTC); 387 at91_sysirq_mask_rtc(AT91SAM9G45_BASE_RTC);
390 at91_sysirq_mask_rtt(AT91SAM9G45_BASE_RTT); 388 at91_sysirq_mask_rtt(AT91SAM9G45_BASE_RTT);
@@ -393,6 +391,50 @@ static void __init at91sam9g45_initialize(void)
393 at91_gpio_init(at91sam9g45_gpio, 5); 391 at91_gpio_init(at91sam9g45_gpio, 5);
394} 392}
395 393
394static struct resource rstc_resources[] = {
395 [0] = {
396 .start = AT91SAM9G45_BASE_RSTC,
397 .end = AT91SAM9G45_BASE_RSTC + SZ_16 - 1,
398 .flags = IORESOURCE_MEM,
399 },
400 [1] = {
401 .start = AT91SAM9G45_BASE_DDRSDRC1,
402 .end = AT91SAM9G45_BASE_DDRSDRC1 + SZ_512 - 1,
403 .flags = IORESOURCE_MEM,
404 },
405 [2] = {
406 .start = AT91SAM9G45_BASE_DDRSDRC0,
407 .end = AT91SAM9G45_BASE_DDRSDRC0 + SZ_512 - 1,
408 .flags = IORESOURCE_MEM,
409 },
410};
411
412static struct platform_device rstc_device = {
413 .name = "at91-sam9g45-reset",
414 .resource = rstc_resources,
415 .num_resources = ARRAY_SIZE(rstc_resources),
416};
417
418static struct resource shdwc_resources[] = {
419 [0] = {
420 .start = AT91SAM9G45_BASE_SHDWC,
421 .end = AT91SAM9G45_BASE_SHDWC + SZ_16 - 1,
422 .flags = IORESOURCE_MEM,
423 },
424};
425
426static struct platform_device shdwc_device = {
427 .name = "at91-poweroff",
428 .resource = shdwc_resources,
429 .num_resources = ARRAY_SIZE(shdwc_resources),
430};
431
432static void __init at91sam9g45_register_devices(void)
433{
434 platform_device_register(&rstc_device);
435 platform_device_register(&shdwc_device);
436}
437
396/* -------------------------------------------------------------------- 438/* --------------------------------------------------------------------
397 * Interrupt initialization 439 * Interrupt initialization
398 * -------------------------------------------------------------------- */ 440 * -------------------------------------------------------------------- */
@@ -435,11 +477,18 @@ static unsigned int at91sam9g45_default_irq_priority[NR_AIC_IRQS] __initdata = {
435 0, /* Advanced Interrupt Controller (IRQ0) */ 477 0, /* Advanced Interrupt Controller (IRQ0) */
436}; 478};
437 479
480static void __init at91sam9g45_init_time(void)
481{
482 at91sam926x_pit_init(NR_IRQS_LEGACY + AT91_ID_SYS);
483}
484
438AT91_SOC_START(at91sam9g45) 485AT91_SOC_START(at91sam9g45)
439 .map_io = at91sam9g45_map_io, 486 .map_io = at91sam9g45_map_io,
440 .default_irq_priority = at91sam9g45_default_irq_priority, 487 .default_irq_priority = at91sam9g45_default_irq_priority,
441 .extern_irq = (1 << AT91SAM9G45_ID_IRQ0), 488 .extern_irq = (1 << AT91SAM9G45_ID_IRQ0),
442 .ioremap_registers = at91sam9g45_ioremap_registers, 489 .ioremap_registers = at91sam9g45_ioremap_registers,
443 .register_clocks = at91sam9g45_register_clocks, 490 .register_clocks = at91sam9g45_register_clocks,
491 .register_devices = at91sam9g45_register_devices,
444 .init = at91sam9g45_initialize, 492 .init = at91sam9g45_initialize,
493 .init_time = at91sam9g45_init_time,
445AT91_SOC_END 494AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9g45_reset.S b/arch/arm/mach-at91/at91sam9g45_reset.S
deleted file mode 100644
index c40c1e2ef80f..000000000000
--- a/arch/arm/mach-at91/at91sam9g45_reset.S
+++ /dev/null
@@ -1,45 +0,0 @@
1/*
2 * reset AT91SAM9G45 as per errata
3 *
4 * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcosoft.com>
5 *
6 * unless the SDRAM is cleanly shutdown before we hit the
7 * reset register it can be left driving the data bus and
8 * killing the chance of a subsequent boot from NAND
9 *
10 * GPLv2 Only
11 */
12
13#include <linux/linkage.h>
14#include <mach/hardware.h>
15#include <mach/at91_ramc.h>
16#include "at91_rstc.h"
17 .arm
18
19/*
20 * at91_ramc_base is an array void*
21 * init at NULL if only one DDR controler is present in or DT
22 */
23 .globl at91sam9g45_restart
24
25at91sam9g45_restart:
26 ldr r5, =at91_ramc_base @ preload constants
27 ldr r0, [r5]
28 ldr r5, [r5, #4] @ ddr1
29 cmp r5, #0
30 ldr r4, =at91_rstc_base
31 ldr r1, [r4]
32
33 mov r2, #1
34 mov r3, #AT91_DDRSDRC_LPCB_POWER_DOWN
35 ldr r4, =AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST
36
37 .balign 32 @ align to cache line
38
39 strne r2, [r5, #AT91_DDRSDRC_RTR] @ disable DDR1 access
40 strne r3, [r5, #AT91_DDRSDRC_LPR] @ power down DDR1
41 str r2, [r0, #AT91_DDRSDRC_RTR] @ disable DDR0 access
42 str r3, [r0, #AT91_DDRSDRC_LPR] @ power down DDR0
43 str r4, [r1, #AT91_RSTC_CR] @ reset processor
44
45 b .
diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c
index 878d5015daab..f553e4ea034b 100644
--- a/arch/arm/mach-at91/at91sam9rl.c
+++ b/arch/arm/mach-at91/at91sam9rl.c
@@ -10,6 +10,7 @@
10 */ 10 */
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/platform_device.h>
13#include <linux/clk/at91_pmc.h> 14#include <linux/clk/at91_pmc.h>
14 15
15#include <asm/proc-fns.h> 16#include <asm/proc-fns.h>
@@ -23,7 +24,6 @@
23#include <mach/hardware.h> 24#include <mach/hardware.h>
24 25
25#include "at91_aic.h" 26#include "at91_aic.h"
26#include "at91_rstc.h"
27#include "soc.h" 27#include "soc.h"
28#include "generic.h" 28#include "generic.h"
29#include "sam9_smc.h" 29#include "sam9_smc.h"
@@ -311,8 +311,6 @@ static void __init at91sam9rl_map_io(void)
311 311
312static void __init at91sam9rl_ioremap_registers(void) 312static void __init at91sam9rl_ioremap_registers(void)
313{ 313{
314 at91_ioremap_shdwc(AT91SAM9RL_BASE_SHDWC);
315 at91_ioremap_rstc(AT91SAM9RL_BASE_RSTC);
316 at91_ioremap_ramc(0, AT91SAM9RL_BASE_SDRAMC, 512); 314 at91_ioremap_ramc(0, AT91SAM9RL_BASE_SDRAMC, 512);
317 at91sam926x_ioremap_pit(AT91SAM9RL_BASE_PIT); 315 at91sam926x_ioremap_pit(AT91SAM9RL_BASE_PIT);
318 at91sam9_ioremap_smc(0, AT91SAM9RL_BASE_SMC); 316 at91sam9_ioremap_smc(0, AT91SAM9RL_BASE_SMC);
@@ -323,7 +321,6 @@ static void __init at91sam9rl_ioremap_registers(void)
323static void __init at91sam9rl_initialize(void) 321static void __init at91sam9rl_initialize(void)
324{ 322{
325 arm_pm_idle = at91sam9_idle; 323 arm_pm_idle = at91sam9_idle;
326 arm_pm_restart = at91sam9_alt_restart;
327 324
328 at91_sysirq_mask_rtc(AT91SAM9RL_BASE_RTC); 325 at91_sysirq_mask_rtc(AT91SAM9RL_BASE_RTC);
329 at91_sysirq_mask_rtt(AT91SAM9RL_BASE_RTT); 326 at91_sysirq_mask_rtt(AT91SAM9RL_BASE_RTT);
@@ -332,6 +329,45 @@ static void __init at91sam9rl_initialize(void)
332 at91_gpio_init(at91sam9rl_gpio, 4); 329 at91_gpio_init(at91sam9rl_gpio, 4);
333} 330}
334 331
332static struct resource rstc_resources[] = {
333 [0] = {
334 .start = AT91SAM9RL_BASE_RSTC,
335 .end = AT91SAM9RL_BASE_RSTC + SZ_16 - 1,
336 .flags = IORESOURCE_MEM,
337 },
338 [1] = {
339 .start = AT91SAM9RL_BASE_SDRAMC,
340 .end = AT91SAM9RL_BASE_SDRAMC + SZ_512 - 1,
341 .flags = IORESOURCE_MEM,
342 },
343};
344
345static struct platform_device rstc_device = {
346 .name = "at91-sam9260-reset",
347 .resource = rstc_resources,
348 .num_resources = ARRAY_SIZE(rstc_resources),
349};
350
351static struct resource shdwc_resources[] = {
352 [0] = {
353 .start = AT91SAM9RL_BASE_SHDWC,
354 .end = AT91SAM9RL_BASE_SHDWC + SZ_16 - 1,
355 .flags = IORESOURCE_MEM,
356 },
357};
358
359static struct platform_device shdwc_device = {
360 .name = "at91-poweroff",
361 .resource = shdwc_resources,
362 .num_resources = ARRAY_SIZE(shdwc_resources),
363};
364
365static void __init at91sam9rl_register_devices(void)
366{
367 platform_device_register(&rstc_device);
368 platform_device_register(&shdwc_device);
369}
370
335/* -------------------------------------------------------------------- 371/* --------------------------------------------------------------------
336 * Interrupt initialization 372 * Interrupt initialization
337 * -------------------------------------------------------------------- */ 373 * -------------------------------------------------------------------- */
@@ -374,6 +410,11 @@ static unsigned int at91sam9rl_default_irq_priority[NR_AIC_IRQS] __initdata = {
374 0, /* Advanced Interrupt Controller */ 410 0, /* Advanced Interrupt Controller */
375}; 411};
376 412
413static void __init at91sam9rl_init_time(void)
414{
415 at91sam926x_pit_init(NR_IRQS_LEGACY + AT91_ID_SYS);
416}
417
377AT91_SOC_START(at91sam9rl) 418AT91_SOC_START(at91sam9rl)
378 .map_io = at91sam9rl_map_io, 419 .map_io = at91sam9rl_map_io,
379 .default_irq_priority = at91sam9rl_default_irq_priority, 420 .default_irq_priority = at91sam9rl_default_irq_priority,
@@ -382,5 +423,7 @@ AT91_SOC_START(at91sam9rl)
382#if defined(CONFIG_OLD_CLK_AT91) 423#if defined(CONFIG_OLD_CLK_AT91)
383 .register_clocks = at91sam9rl_register_clocks, 424 .register_clocks = at91sam9rl_register_clocks,
384#endif 425#endif
426 .register_devices = at91sam9rl_register_devices,
385 .init = at91sam9rl_initialize, 427 .init = at91sam9rl_initialize,
428 .init_time = at91sam9rl_init_time,
386AT91_SOC_END 429AT91_SOC_END
diff --git a/arch/arm/mach-at91/board-afeb-9260v1.c b/arch/arm/mach-at91/board-afeb-9260v1.c
index 597c649170aa..e76e35ce81e7 100644
--- a/arch/arm/mach-at91/board-afeb-9260v1.c
+++ b/arch/arm/mach-at91/board-afeb-9260v1.c
@@ -167,6 +167,8 @@ static struct at91_cf_data afeb9260_cf_data = {
167 167
168static void __init afeb9260_board_init(void) 168static void __init afeb9260_board_init(void)
169{ 169{
170 at91_register_devices();
171
170 /* Serial */ 172 /* Serial */
171 /* DBGU on ttyS0. (Rx & Tx only) */ 173 /* DBGU on ttyS0. (Rx & Tx only) */
172 at91_register_uart(0, 0, 0); 174 at91_register_uart(0, 0, 0);
@@ -211,7 +213,7 @@ static void __init afeb9260_board_init(void)
211 213
212MACHINE_START(AFEB9260, "Custom afeb9260 board") 214MACHINE_START(AFEB9260, "Custom afeb9260 board")
213 /* Maintainer: Sergey Lapin <slapin@ossfans.org> */ 215 /* Maintainer: Sergey Lapin <slapin@ossfans.org> */
214 .init_time = at91sam926x_pit_init, 216 .init_time = at91_init_time,
215 .map_io = at91_map_io, 217 .map_io = at91_map_io,
216 .handle_irq = at91_aic_handle_irq, 218 .handle_irq = at91_aic_handle_irq,
217 .init_early = afeb9260_init_early, 219 .init_early = afeb9260_init_early,
diff --git a/arch/arm/mach-at91/board-cam60.c b/arch/arm/mach-at91/board-cam60.c
index a30502c8d379..ae827dd2d0d2 100644
--- a/arch/arm/mach-at91/board-cam60.c
+++ b/arch/arm/mach-at91/board-cam60.c
@@ -170,6 +170,8 @@ static void __init cam60_add_device_nand(void)
170 170
171static void __init cam60_board_init(void) 171static void __init cam60_board_init(void)
172{ 172{
173 at91_register_devices();
174
173 /* Serial */ 175 /* Serial */
174 /* DBGU on ttyS0. (Rx & Tx only) */ 176 /* DBGU on ttyS0. (Rx & Tx only) */
175 at91_register_uart(0, 0, 0); 177 at91_register_uart(0, 0, 0);
@@ -188,7 +190,7 @@ static void __init cam60_board_init(void)
188 190
189MACHINE_START(CAM60, "KwikByte CAM60") 191MACHINE_START(CAM60, "KwikByte CAM60")
190 /* Maintainer: KwikByte */ 192 /* Maintainer: KwikByte */
191 .init_time = at91sam926x_pit_init, 193 .init_time = at91_init_time,
192 .map_io = at91_map_io, 194 .map_io = at91_map_io,
193 .handle_irq = at91_aic_handle_irq, 195 .handle_irq = at91_aic_handle_irq,
194 .init_early = cam60_init_early, 196 .init_early = cam60_init_early,
diff --git a/arch/arm/mach-at91/board-cpu9krea.c b/arch/arm/mach-at91/board-cpu9krea.c
index 2037f78c84e7..731c8318f4f5 100644
--- a/arch/arm/mach-at91/board-cpu9krea.c
+++ b/arch/arm/mach-at91/board-cpu9krea.c
@@ -322,6 +322,8 @@ static struct mci_platform_data __initdata cpu9krea_mci0_data = {
322 322
323static void __init cpu9krea_board_init(void) 323static void __init cpu9krea_board_init(void)
324{ 324{
325 at91_register_devices();
326
325 /* NOR */ 327 /* NOR */
326 cpu9krea_add_device_nor(); 328 cpu9krea_add_device_nor();
327 /* Serial */ 329 /* Serial */
@@ -375,7 +377,7 @@ MACHINE_START(CPUAT9260, "Eukrea CPU9260")
375MACHINE_START(CPUAT9G20, "Eukrea CPU9G20") 377MACHINE_START(CPUAT9G20, "Eukrea CPU9G20")
376#endif 378#endif
377 /* Maintainer: Eric Benard - EUKREA Electromatique */ 379 /* Maintainer: Eric Benard - EUKREA Electromatique */
378 .init_time = at91sam926x_pit_init, 380 .init_time = at91_init_time,
379 .map_io = at91_map_io, 381 .map_io = at91_map_io,
380 .handle_irq = at91_aic_handle_irq, 382 .handle_irq = at91_aic_handle_irq,
381 .init_early = cpu9krea_init_early, 383 .init_early = cpu9krea_init_early,
diff --git a/arch/arm/mach-at91/board-dt-sam9.c b/arch/arm/mach-at91/board-dt-sam9.c
index dfa8d48146fe..d3048ccdc41f 100644
--- a/arch/arm/mach-at91/board-dt-sam9.c
+++ b/arch/arm/mach-at91/board-dt-sam9.c
@@ -25,15 +25,6 @@
25#include "board.h" 25#include "board.h"
26#include "generic.h" 26#include "generic.h"
27 27
28
29static void __init sam9_dt_timer_init(void)
30{
31#if defined(CONFIG_COMMON_CLK)
32 of_clk_init(NULL);
33#endif
34 at91sam926x_pit_init();
35}
36
37static const char *at91_dt_board_compat[] __initdata = { 28static const char *at91_dt_board_compat[] __initdata = {
38 "atmel,at91sam9", 29 "atmel,at91sam9",
39 NULL 30 NULL
@@ -41,7 +32,6 @@ static const char *at91_dt_board_compat[] __initdata = {
41 32
42DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM (Device Tree)") 33DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM (Device Tree)")
43 /* Maintainer: Atmel */ 34 /* Maintainer: Atmel */
44 .init_time = sam9_dt_timer_init,
45 .map_io = at91_map_io, 35 .map_io = at91_map_io,
46 .init_early = at91_dt_initialize, 36 .init_early = at91_dt_initialize,
47 .dt_compat = at91_dt_board_compat, 37 .dt_compat = at91_dt_board_compat,
diff --git a/arch/arm/mach-at91/board-dt-sama5.c b/arch/arm/mach-at91/board-dt-sama5.c
index 6a064e53f4d6..129e2917506b 100644
--- a/arch/arm/mach-at91/board-dt-sama5.c
+++ b/arch/arm/mach-at91/board-dt-sama5.c
@@ -27,14 +27,6 @@
27#include "at91_aic.h" 27#include "at91_aic.h"
28#include "generic.h" 28#include "generic.h"
29 29
30static void __init sama5_dt_timer_init(void)
31{
32#if defined(CONFIG_COMMON_CLK)
33 of_clk_init(NULL);
34#endif
35 at91sam926x_pit_init();
36}
37
38static void __init sama5_dt_device_init(void) 30static void __init sama5_dt_device_init(void)
39{ 31{
40 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); 32 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
@@ -47,7 +39,6 @@ static const char *sama5_dt_board_compat[] __initconst = {
47 39
48DT_MACHINE_START(sama5_dt, "Atmel SAMA5 (Device Tree)") 40DT_MACHINE_START(sama5_dt, "Atmel SAMA5 (Device Tree)")
49 /* Maintainer: Atmel */ 41 /* Maintainer: Atmel */
50 .init_time = sama5_dt_timer_init,
51 .map_io = at91_map_io, 42 .map_io = at91_map_io,
52 .init_early = at91_dt_initialize, 43 .init_early = at91_dt_initialize,
53 .init_machine = sama5_dt_device_init, 44 .init_machine = sama5_dt_device_init,
diff --git a/arch/arm/mach-at91/board-flexibity.c b/arch/arm/mach-at91/board-flexibity.c
index 68f1ab6bd08f..a6aa4a2432f2 100644
--- a/arch/arm/mach-at91/board-flexibity.c
+++ b/arch/arm/mach-at91/board-flexibity.c
@@ -138,6 +138,8 @@ static struct gpio_led flexibity_leds[] = {
138 138
139static void __init flexibity_board_init(void) 139static void __init flexibity_board_init(void)
140{ 140{
141 at91_register_devices();
142
141 /* Serial */ 143 /* Serial */
142 /* DBGU on ttyS0. (Rx & Tx only) */ 144 /* DBGU on ttyS0. (Rx & Tx only) */
143 at91_register_uart(0, 0, 0); 145 at91_register_uart(0, 0, 0);
@@ -160,7 +162,7 @@ static void __init flexibity_board_init(void)
160 162
161MACHINE_START(FLEXIBITY, "Flexibity Connect") 163MACHINE_START(FLEXIBITY, "Flexibity Connect")
162 /* Maintainer: Maxim Osipov */ 164 /* Maintainer: Maxim Osipov */
163 .init_time = at91sam926x_pit_init, 165 .init_time = at91_init_time,
164 .map_io = at91_map_io, 166 .map_io = at91_map_io,
165 .handle_irq = at91_aic_handle_irq, 167 .handle_irq = at91_aic_handle_irq,
166 .init_early = flexibity_init_early, 168 .init_early = flexibity_init_early,
diff --git a/arch/arm/mach-at91/board-gsia18s.c b/arch/arm/mach-at91/board-gsia18s.c
index b729dd1271bf..bf5cc55c7db6 100644
--- a/arch/arm/mach-at91/board-gsia18s.c
+++ b/arch/arm/mach-at91/board-gsia18s.c
@@ -576,7 +576,7 @@ static void __init gsia18s_board_init(void)
576} 576}
577 577
578MACHINE_START(GSIA18S, "GS_IA18_S") 578MACHINE_START(GSIA18S, "GS_IA18_S")
579 .init_time = at91sam926x_pit_init, 579 .init_time = at91_init_time,
580 .map_io = at91_map_io, 580 .map_io = at91_map_io,
581 .handle_irq = at91_aic_handle_irq, 581 .handle_irq = at91_aic_handle_irq,
582 .init_early = gsia18s_init_early, 582 .init_early = gsia18s_init_early,
diff --git a/arch/arm/mach-at91/board-pcontrol-g20.c b/arch/arm/mach-at91/board-pcontrol-g20.c
index b48d95ec5152..9c26b94ce448 100644
--- a/arch/arm/mach-at91/board-pcontrol-g20.c
+++ b/arch/arm/mach-at91/board-pcontrol-g20.c
@@ -219,7 +219,7 @@ static void __init pcontrol_g20_board_init(void)
219 219
220MACHINE_START(PCONTROL_G20, "PControl G20") 220MACHINE_START(PCONTROL_G20, "PControl G20")
221 /* Maintainer: pgsellmann@portner-elektronik.at */ 221 /* Maintainer: pgsellmann@portner-elektronik.at */
222 .init_time = at91sam926x_pit_init, 222 .init_time = at91_init_time,
223 .map_io = at91_map_io, 223 .map_io = at91_map_io,
224 .handle_irq = at91_aic_handle_irq, 224 .handle_irq = at91_aic_handle_irq,
225 .init_early = pcontrol_g20_init_early, 225 .init_early = pcontrol_g20_init_early,
diff --git a/arch/arm/mach-at91/board-sam9-l9260.c b/arch/arm/mach-at91/board-sam9-l9260.c
index d24dda67e2d3..c2166e3a236c 100644
--- a/arch/arm/mach-at91/board-sam9-l9260.c
+++ b/arch/arm/mach-at91/board-sam9-l9260.c
@@ -187,6 +187,8 @@ static struct gpio_led ek_leds[] = {
187 187
188static void __init ek_board_init(void) 188static void __init ek_board_init(void)
189{ 189{
190 at91_register_devices();
191
190 /* Serial */ 192 /* Serial */
191 /* DBGU on ttyS0. (Rx & Tx only) */ 193 /* DBGU on ttyS0. (Rx & Tx only) */
192 at91_register_uart(0, 0, 0); 194 at91_register_uart(0, 0, 0);
@@ -219,7 +221,7 @@ static void __init ek_board_init(void)
219 221
220MACHINE_START(SAM9_L9260, "Olimex SAM9-L9260") 222MACHINE_START(SAM9_L9260, "Olimex SAM9-L9260")
221 /* Maintainer: Olimex */ 223 /* Maintainer: Olimex */
222 .init_time = at91sam926x_pit_init, 224 .init_time = at91_init_time,
223 .map_io = at91_map_io, 225 .map_io = at91_map_io,
224 .handle_irq = at91_aic_handle_irq, 226 .handle_irq = at91_aic_handle_irq,
225 .init_early = ek_init_early, 227 .init_early = ek_init_early,
diff --git a/arch/arm/mach-at91/board-sam9260ek.c b/arch/arm/mach-at91/board-sam9260ek.c
index 65dea12d685e..bf8a946b4cd0 100644
--- a/arch/arm/mach-at91/board-sam9260ek.c
+++ b/arch/arm/mach-at91/board-sam9260ek.c
@@ -45,7 +45,6 @@
45#include <mach/system_rev.h> 45#include <mach/system_rev.h>
46 46
47#include "at91_aic.h" 47#include "at91_aic.h"
48#include "at91_shdwc.h"
49#include "board.h" 48#include "board.h"
50#include "sam9_smc.h" 49#include "sam9_smc.h"
51#include "generic.h" 50#include "generic.h"
@@ -307,6 +306,8 @@ static void __init ek_add_device_buttons(void) {}
307 306
308static void __init ek_board_init(void) 307static void __init ek_board_init(void)
309{ 308{
309 at91_register_devices();
310
310 /* Serial */ 311 /* Serial */
311 /* DBGU on ttyS0. (Rx & Tx only) */ 312 /* DBGU on ttyS0. (Rx & Tx only) */
312 at91_register_uart(0, 0, 0); 313 at91_register_uart(0, 0, 0);
@@ -344,7 +345,7 @@ static void __init ek_board_init(void)
344 345
345MACHINE_START(AT91SAM9260EK, "Atmel AT91SAM9260-EK") 346MACHINE_START(AT91SAM9260EK, "Atmel AT91SAM9260-EK")
346 /* Maintainer: Atmel */ 347 /* Maintainer: Atmel */
347 .init_time = at91sam926x_pit_init, 348 .init_time = at91_init_time,
348 .map_io = at91_map_io, 349 .map_io = at91_map_io,
349 .handle_irq = at91_aic_handle_irq, 350 .handle_irq = at91_aic_handle_irq,
350 .init_early = ek_init_early, 351 .init_early = ek_init_early,
diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c
index 4637432de08f..e85ada820bfb 100644
--- a/arch/arm/mach-at91/board-sam9261ek.c
+++ b/arch/arm/mach-at91/board-sam9261ek.c
@@ -49,7 +49,6 @@
49#include <mach/system_rev.h> 49#include <mach/system_rev.h>
50 50
51#include "at91_aic.h" 51#include "at91_aic.h"
52#include "at91_shdwc.h"
53#include "board.h" 52#include "board.h"
54#include "sam9_smc.h" 53#include "sam9_smc.h"
55#include "generic.h" 54#include "generic.h"
@@ -561,6 +560,8 @@ static struct gpio_led ek_leds[] = {
561 560
562static void __init ek_board_init(void) 561static void __init ek_board_init(void)
563{ 562{
563 at91_register_devices();
564
564 /* Serial */ 565 /* Serial */
565 /* DBGU on ttyS0. (Rx & Tx only) */ 566 /* DBGU on ttyS0. (Rx & Tx only) */
566 at91_register_uart(0, 0, 0); 567 at91_register_uart(0, 0, 0);
@@ -603,7 +604,7 @@ static void __init ek_board_init(void)
603 604
604MACHINE_START(AT91SAM9261EK, "Atmel AT91SAM9261-EK") 605MACHINE_START(AT91SAM9261EK, "Atmel AT91SAM9261-EK")
605 /* Maintainer: Atmel */ 606 /* Maintainer: Atmel */
606 .init_time = at91sam926x_pit_init, 607 .init_time = at91_init_time,
607 .map_io = at91_map_io, 608 .map_io = at91_map_io,
608 .handle_irq = at91_aic_handle_irq, 609 .handle_irq = at91_aic_handle_irq,
609 .init_early = ek_init_early, 610 .init_early = ek_init_early,
@@ -613,7 +614,7 @@ MACHINE_END
613 614
614MACHINE_START(AT91SAM9G10EK, "Atmel AT91SAM9G10-EK") 615MACHINE_START(AT91SAM9G10EK, "Atmel AT91SAM9G10-EK")
615 /* Maintainer: Atmel */ 616 /* Maintainer: Atmel */
616 .init_time = at91sam926x_pit_init, 617 .init_time = at91_init_time,
617 .map_io = at91_map_io, 618 .map_io = at91_map_io,
618 .handle_irq = at91_aic_handle_irq, 619 .handle_irq = at91_aic_handle_irq,
619 .init_early = ek_init_early, 620 .init_early = ek_init_early,
diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c
index fc446097f410..d76680f2a209 100644
--- a/arch/arm/mach-at91/board-sam9263ek.c
+++ b/arch/arm/mach-at91/board-sam9263ek.c
@@ -50,7 +50,6 @@
50#include <mach/system_rev.h> 50#include <mach/system_rev.h>
51 51
52#include "at91_aic.h" 52#include "at91_aic.h"
53#include "at91_shdwc.h"
54#include "board.h" 53#include "board.h"
55#include "sam9_smc.h" 54#include "sam9_smc.h"
56#include "generic.h" 55#include "generic.h"
@@ -439,6 +438,8 @@ static struct platform_device *devices[] __initdata = {
439 438
440static void __init ek_board_init(void) 439static void __init ek_board_init(void)
441{ 440{
441 at91_register_devices();
442
442 /* Serial */ 443 /* Serial */
443 /* DBGU on ttyS0. (Rx & Tx only) */ 444 /* DBGU on ttyS0. (Rx & Tx only) */
444 at91_register_uart(0, 0, 0); 445 at91_register_uart(0, 0, 0);
@@ -483,7 +484,7 @@ static void __init ek_board_init(void)
483 484
484MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK") 485MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK")
485 /* Maintainer: Atmel */ 486 /* Maintainer: Atmel */
486 .init_time = at91sam926x_pit_init, 487 .init_time = at91_init_time,
487 .map_io = at91_map_io, 488 .map_io = at91_map_io,
488 .handle_irq = at91_aic_handle_irq, 489 .handle_irq = at91_aic_handle_irq,
489 .init_early = ek_init_early, 490 .init_early = ek_init_early,
diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c
index e1be6e25b380..49f075213451 100644
--- a/arch/arm/mach-at91/board-sam9g20ek.c
+++ b/arch/arm/mach-at91/board-sam9g20ek.c
@@ -410,7 +410,7 @@ static void __init ek_board_init(void)
410 410
411MACHINE_START(AT91SAM9G20EK, "Atmel AT91SAM9G20-EK") 411MACHINE_START(AT91SAM9G20EK, "Atmel AT91SAM9G20-EK")
412 /* Maintainer: Atmel */ 412 /* Maintainer: Atmel */
413 .init_time = at91sam926x_pit_init, 413 .init_time = at91_init_time,
414 .map_io = at91_map_io, 414 .map_io = at91_map_io,
415 .handle_irq = at91_aic_handle_irq, 415 .handle_irq = at91_aic_handle_irq,
416 .init_early = ek_init_early, 416 .init_early = ek_init_early,
@@ -420,7 +420,7 @@ MACHINE_END
420 420
421MACHINE_START(AT91SAM9G20EK_2MMC, "Atmel AT91SAM9G20-EK 2 MMC Slot Mod") 421MACHINE_START(AT91SAM9G20EK_2MMC, "Atmel AT91SAM9G20-EK 2 MMC Slot Mod")
422 /* Maintainer: Atmel */ 422 /* Maintainer: Atmel */
423 .init_time = at91sam926x_pit_init, 423 .init_time = at91_init_time,
424 .map_io = at91_map_io, 424 .map_io = at91_map_io,
425 .handle_irq = at91_aic_handle_irq, 425 .handle_irq = at91_aic_handle_irq,
426 .init_early = ek_init_early, 426 .init_early = ek_init_early,
diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c
index b227732b0c83..a517c7f7af92 100644
--- a/arch/arm/mach-at91/board-sam9m10g45ek.c
+++ b/arch/arm/mach-at91/board-sam9m10g45ek.c
@@ -48,7 +48,6 @@
48#include <mach/system_rev.h> 48#include <mach/system_rev.h>
49 49
50#include "at91_aic.h" 50#include "at91_aic.h"
51#include "at91_shdwc.h"
52#include "board.h" 51#include "board.h"
53#include "sam9_smc.h" 52#include "sam9_smc.h"
54#include "generic.h" 53#include "generic.h"
@@ -471,6 +470,8 @@ static struct platform_device *devices[] __initdata = {
471 470
472static void __init ek_board_init(void) 471static void __init ek_board_init(void)
473{ 472{
473 at91_register_devices();
474
474 /* Serial */ 475 /* Serial */
475 /* DGBU on ttyS0. (Rx & Tx only) */ 476 /* DGBU on ttyS0. (Rx & Tx only) */
476 at91_register_uart(0, 0, 0); 477 at91_register_uart(0, 0, 0);
@@ -517,7 +518,7 @@ static void __init ek_board_init(void)
517 518
518MACHINE_START(AT91SAM9M10G45EK, "Atmel AT91SAM9M10G45-EK") 519MACHINE_START(AT91SAM9M10G45EK, "Atmel AT91SAM9M10G45-EK")
519 /* Maintainer: Atmel */ 520 /* Maintainer: Atmel */
520 .init_time = at91sam926x_pit_init, 521 .init_time = at91_init_time,
521 .map_io = at91_map_io, 522 .map_io = at91_map_io,
522 .handle_irq = at91_aic_handle_irq, 523 .handle_irq = at91_aic_handle_irq,
523 .init_early = ek_init_early, 524 .init_early = ek_init_early,
diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c
index b64648b4a1fc..8bca329b0293 100644
--- a/arch/arm/mach-at91/board-sam9rlek.c
+++ b/arch/arm/mach-at91/board-sam9rlek.c
@@ -35,7 +35,6 @@
35 35
36 36
37#include "at91_aic.h" 37#include "at91_aic.h"
38#include "at91_shdwc.h"
39#include "board.h" 38#include "board.h"
40#include "sam9_smc.h" 39#include "sam9_smc.h"
41#include "generic.h" 40#include "generic.h"
@@ -292,6 +291,8 @@ static void __init ek_add_device_buttons(void) {}
292 291
293static void __init ek_board_init(void) 292static void __init ek_board_init(void)
294{ 293{
294 at91_register_devices();
295
295 /* Serial */ 296 /* Serial */
296 /* DBGU on ttyS0. (Rx & Tx only) */ 297 /* DBGU on ttyS0. (Rx & Tx only) */
297 at91_register_uart(0, 0, 0); 298 at91_register_uart(0, 0, 0);
@@ -323,7 +324,7 @@ static void __init ek_board_init(void)
323 324
324MACHINE_START(AT91SAM9RLEK, "Atmel AT91SAM9RL-EK") 325MACHINE_START(AT91SAM9RLEK, "Atmel AT91SAM9RL-EK")
325 /* Maintainer: Atmel */ 326 /* Maintainer: Atmel */
326 .init_time = at91sam926x_pit_init, 327 .init_time = at91_init_time,
327 .map_io = at91_map_io, 328 .map_io = at91_map_io,
328 .handle_irq = at91_aic_handle_irq, 329 .handle_irq = at91_aic_handle_irq,
329 .init_early = ek_init_early, 330 .init_early = ek_init_early,
diff --git a/arch/arm/mach-at91/board-snapper9260.c b/arch/arm/mach-at91/board-snapper9260.c
index 1b870e6def0c..b4aff840a1a0 100644
--- a/arch/arm/mach-at91/board-snapper9260.c
+++ b/arch/arm/mach-at91/board-snapper9260.c
@@ -154,6 +154,8 @@ static void __init snapper9260_add_device_nand(void)
154 154
155static void __init snapper9260_board_init(void) 155static void __init snapper9260_board_init(void)
156{ 156{
157 at91_register_devices();
158
157 at91_add_device_i2c(snapper9260_i2c_devices, 159 at91_add_device_i2c(snapper9260_i2c_devices,
158 ARRAY_SIZE(snapper9260_i2c_devices)); 160 ARRAY_SIZE(snapper9260_i2c_devices));
159 161
@@ -178,7 +180,7 @@ static void __init snapper9260_board_init(void)
178} 180}
179 181
180MACHINE_START(SNAPPER_9260, "Bluewater Systems Snapper 9260/9G20 module") 182MACHINE_START(SNAPPER_9260, "Bluewater Systems Snapper 9260/9G20 module")
181 .init_time = at91sam926x_pit_init, 183 .init_time = at91_init_time,
182 .map_io = at91_map_io, 184 .map_io = at91_map_io,
183 .handle_irq = at91_aic_handle_irq, 185 .handle_irq = at91_aic_handle_irq,
184 .init_early = snapper9260_init_early, 186 .init_early = snapper9260_init_early,
diff --git a/arch/arm/mach-at91/board-stamp9g20.c b/arch/arm/mach-at91/board-stamp9g20.c
index 3b575036ff96..e825641a1dee 100644
--- a/arch/arm/mach-at91/board-stamp9g20.c
+++ b/arch/arm/mach-at91/board-stamp9g20.c
@@ -275,7 +275,7 @@ static void __init stamp9g20evb_board_init(void)
275 275
276MACHINE_START(PORTUXG20, "taskit PortuxG20") 276MACHINE_START(PORTUXG20, "taskit PortuxG20")
277 /* Maintainer: taskit GmbH */ 277 /* Maintainer: taskit GmbH */
278 .init_time = at91sam926x_pit_init, 278 .init_time = at91_init_time,
279 .map_io = at91_map_io, 279 .map_io = at91_map_io,
280 .handle_irq = at91_aic_handle_irq, 280 .handle_irq = at91_aic_handle_irq,
281 .init_early = stamp9g20_init_early, 281 .init_early = stamp9g20_init_early,
@@ -285,7 +285,7 @@ MACHINE_END
285 285
286MACHINE_START(STAMP9G20, "taskit Stamp9G20") 286MACHINE_START(STAMP9G20, "taskit Stamp9G20")
287 /* Maintainer: taskit GmbH */ 287 /* Maintainer: taskit GmbH */
288 .init_time = at91sam926x_pit_init, 288 .init_time = at91_init_time,
289 .map_io = at91_map_io, 289 .map_io = at91_map_io,
290 .handle_irq = at91_aic_handle_irq, 290 .handle_irq = at91_aic_handle_irq,
291 .init_early = stamp9g20_init_early, 291 .init_early = stamp9g20_init_early,
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index cddf1e51c50e..81959cf4a137 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -8,6 +8,9 @@
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 */ 9 */
10 10
11#ifndef _AT91_GENERIC_H
12#define _AT91_GENERIC_H
13
11#include <linux/clkdev.h> 14#include <linux/clkdev.h>
12#include <linux/of.h> 15#include <linux/of.h>
13#include <linux/reboot.h> 16#include <linux/reboot.h>
@@ -38,12 +41,15 @@ extern int __init at91_aic5_of_init(struct device_node *node,
38extern void __init at91_sysirq_mask_rtc(u32 rtc_base); 41extern void __init at91_sysirq_mask_rtc(u32 rtc_base);
39extern void __init at91_sysirq_mask_rtt(u32 rtt_base); 42extern void __init at91_sysirq_mask_rtt(u32 rtt_base);
40 43
44 /* Devices */
45extern void __init at91_register_devices(void);
41 46
42 /* Timer */ 47 /* Timer */
48extern void __init at91_init_time(void);
43extern void at91rm9200_ioremap_st(u32 addr); 49extern void at91rm9200_ioremap_st(u32 addr);
44extern void at91rm9200_timer_init(void); 50extern void at91rm9200_timer_init(void);
45extern void at91sam926x_ioremap_pit(u32 addr); 51extern void at91sam926x_ioremap_pit(u32 addr);
46extern void at91sam926x_pit_init(void); 52extern void at91sam926x_pit_init(int irq);
47extern void at91x40_timer_init(void); 53extern void at91x40_timer_init(void);
48 54
49 /* Clocks */ 55 /* Clocks */
@@ -63,14 +69,6 @@ extern void at91_irq_resume(void);
63/* idle */ 69/* idle */
64extern void at91sam9_idle(void); 70extern void at91sam9_idle(void);
65 71
66/* reset */
67extern void at91_ioremap_rstc(u32 base_addr);
68extern void at91sam9_alt_restart(enum reboot_mode, const char *);
69extern void at91sam9g45_restart(enum reboot_mode, const char *);
70
71/* shutdown */
72extern void at91_ioremap_shdwc(u32 base_addr);
73
74/* Matrix */ 72/* Matrix */
75extern void at91_ioremap_matrix(u32 base_addr); 73extern void at91_ioremap_matrix(u32 base_addr);
76 74
@@ -91,3 +89,5 @@ extern int __init at91_gpio_of_irq_setup(struct device_node *node,
91 struct device_node *parent); 89 struct device_node *parent);
92 90
93extern u32 at91_get_extern_irq(void); 91extern u32 at91_get_extern_irq(void);
92
93#endif /* _AT91_GENERIC_H */
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 5920373809c5..4073ab7f38f3 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -34,79 +34,8 @@
34#include "pm.h" 34#include "pm.h"
35#include "gpio.h" 35#include "gpio.h"
36 36
37/*
38 * Show the reason for the previous system reset.
39 */
40
41#include "at91_rstc.h"
42#include "at91_shdwc.h"
43
44static void (*at91_pm_standby)(void); 37static void (*at91_pm_standby)(void);
45 38
46static void __init show_reset_status(void)
47{
48 static char reset[] __initdata = "reset";
49
50 static char general[] __initdata = "general";
51 static char wakeup[] __initdata = "wakeup";
52 static char watchdog[] __initdata = "watchdog";
53 static char software[] __initdata = "software";
54 static char user[] __initdata = "user";
55 static char unknown[] __initdata = "unknown";
56
57 static char signal[] __initdata = "signal";
58 static char rtc[] __initdata = "rtc";
59 static char rtt[] __initdata = "rtt";
60 static char restore[] __initdata = "power-restored";
61
62 char *reason, *r2 = reset;
63 u32 reset_type, wake_type;
64
65 if (!at91_shdwc_base || !at91_rstc_base)
66 return;
67
68 reset_type = at91_rstc_read(AT91_RSTC_SR) & AT91_RSTC_RSTTYP;
69 wake_type = at91_shdwc_read(AT91_SHDW_SR);
70
71 switch (reset_type) {
72 case AT91_RSTC_RSTTYP_GENERAL:
73 reason = general;
74 break;
75 case AT91_RSTC_RSTTYP_WAKEUP:
76 /* board-specific code enabled the wakeup sources */
77 reason = wakeup;
78
79 /* "wakeup signal" */
80 if (wake_type & AT91_SHDW_WAKEUP0)
81 r2 = signal;
82 else {
83 r2 = reason;
84 if (wake_type & AT91_SHDW_RTTWK) /* rtt wakeup */
85 reason = rtt;
86 else if (wake_type & AT91_SHDW_RTCWK) /* rtc wakeup */
87 reason = rtc;
88 else if (wake_type == 0) /* power-restored wakeup */
89 reason = restore;
90 else /* unknown wakeup */
91 reason = unknown;
92 }
93 break;
94 case AT91_RSTC_RSTTYP_WATCHDOG:
95 reason = watchdog;
96 break;
97 case AT91_RSTC_RSTTYP_SOFTWARE:
98 reason = software;
99 break;
100 case AT91_RSTC_RSTTYP_USER:
101 reason = user;
102 break;
103 default:
104 reason = unknown;
105 break;
106 }
107 pr_info("AT91: Starting after %s %s\n", reason, r2);
108}
109
110static int at91_pm_valid_state(suspend_state_t state) 39static int at91_pm_valid_state(suspend_state_t state)
111{ 40{
112 switch (state) { 41 switch (state) {
@@ -346,7 +275,6 @@ static int __init at91_pm_init(void)
346 275
347 suspend_set_ops(&at91_pm_ops); 276 suspend_set_ops(&at91_pm_ops);
348 277
349 show_reset_status();
350 return 0; 278 return 0;
351} 279}
352arch_initcall(at91_pm_init); 280arch_initcall(at91_pm_init);
diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c
index ebe7fdca9e83..961079250b83 100644
--- a/arch/arm/mach-at91/setup.c
+++ b/arch/arm/mach-at91/setup.c
@@ -5,6 +5,8 @@
5 * Under GPLv2 5 * Under GPLv2
6 */ 6 */
7 7
8#define pr_fmt(fmt) "AT91: " fmt
9
8#include <linux/module.h> 10#include <linux/module.h>
9#include <linux/io.h> 11#include <linux/io.h>
10#include <linux/mm.h> 12#include <linux/mm.h>
@@ -20,7 +22,6 @@
20#include <mach/cpu.h> 22#include <mach/cpu.h>
21#include <mach/at91_dbgu.h> 23#include <mach/at91_dbgu.h>
22 24
23#include "at91_shdwc.h"
24#include "soc.h" 25#include "soc.h"
25#include "generic.h" 26#include "generic.h"
26#include "pm.h" 27#include "pm.h"
@@ -37,7 +38,7 @@ void __init at91rm9200_set_type(int type)
37 else 38 else
38 at91_soc_initdata.subtype = AT91_SOC_RM9200_BGA; 39 at91_soc_initdata.subtype = AT91_SOC_RM9200_BGA;
39 40
40 pr_info("AT91: filled in soc subtype: %s\n", 41 pr_info("filled in soc subtype: %s\n",
41 at91_get_soc_subtype(&at91_soc_initdata)); 42 at91_get_soc_subtype(&at91_soc_initdata));
42} 43}
43 44
@@ -67,7 +68,7 @@ void __init at91_ioremap_ramc(int id, u32 addr, u32 size)
67 } 68 }
68 at91_ramc_base[id] = ioremap(addr, size); 69 at91_ramc_base[id] = ioremap(addr, size);
69 if (!at91_ramc_base[id]) 70 if (!at91_ramc_base[id])
70 panic("Impossible to ioremap ramc.%d 0x%x\n", id, addr); 71 panic(pr_fmt("Impossible to ioremap ramc.%d 0x%x\n"), id, addr);
71} 72}
72 73
73static struct map_desc sram_desc[2] __initdata; 74static struct map_desc sram_desc[2] __initdata;
@@ -84,7 +85,7 @@ void __init at91_init_sram(int bank, unsigned long base, unsigned int length)
84 desc->length = length; 85 desc->length = length;
85 desc->type = MT_MEMORY_RWX_NONCACHED; 86 desc->type = MT_MEMORY_RWX_NONCACHED;
86 87
87 pr_info("AT91: sram at 0x%lx of 0x%x mapped at 0x%lx\n", 88 pr_info("sram at 0x%lx of 0x%x mapped at 0x%lx\n",
88 base, length, desc->virtual); 89 base, length, desc->virtual);
89 90
90 iotable_init(desc, 1); 91 iotable_init(desc, 1);
@@ -367,45 +368,21 @@ void __init at91_map_io(void)
367 soc_detect(AT91_BASE_DBGU1); 368 soc_detect(AT91_BASE_DBGU1);
368 369
369 if (!at91_soc_is_detected()) 370 if (!at91_soc_is_detected())
370 panic("AT91: Impossible to detect the SOC type"); 371 panic(pr_fmt("Impossible to detect the SOC type"));
371 372
372 pr_info("AT91: Detected soc type: %s\n", 373 pr_info("Detected soc type: %s\n",
373 at91_get_soc_type(&at91_soc_initdata)); 374 at91_get_soc_type(&at91_soc_initdata));
374 if (at91_soc_initdata.subtype != AT91_SOC_SUBTYPE_NONE) 375 if (at91_soc_initdata.subtype != AT91_SOC_SUBTYPE_NONE)
375 pr_info("AT91: Detected soc subtype: %s\n", 376 pr_info("Detected soc subtype: %s\n",
376 at91_get_soc_subtype(&at91_soc_initdata)); 377 at91_get_soc_subtype(&at91_soc_initdata));
377 378
378 if (!at91_soc_is_enabled()) 379 if (!at91_soc_is_enabled())
379 panic("AT91: Soc not enabled"); 380 panic(pr_fmt("Soc not enabled"));
380 381
381 if (at91_boot_soc.map_io) 382 if (at91_boot_soc.map_io)
382 at91_boot_soc.map_io(); 383 at91_boot_soc.map_io();
383} 384}
384 385
385void __iomem *at91_shdwc_base = NULL;
386
387static void at91sam9_poweroff(void)
388{
389 at91_shdwc_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
390}
391
392void __init at91_ioremap_shdwc(u32 base_addr)
393{
394 at91_shdwc_base = ioremap(base_addr, 16);
395 if (!at91_shdwc_base)
396 panic("Impossible to ioremap at91_shdwc_base\n");
397 pm_power_off = at91sam9_poweroff;
398}
399
400void __iomem *at91_rstc_base;
401
402void __init at91_ioremap_rstc(u32 base_addr)
403{
404 at91_rstc_base = ioremap(base_addr, 16);
405 if (!at91_rstc_base)
406 panic("Impossible to ioremap at91_rstc_base\n");
407}
408
409void __init at91_alt_map_io(void) 386void __init at91_alt_map_io(void)
410{ 387{
411 /* Map peripherals */ 388 /* Map peripherals */
@@ -438,42 +415,15 @@ void __init at91_ioremap_matrix(u32 base_addr)
438{ 415{
439 at91_matrix_base = ioremap(base_addr, 512); 416 at91_matrix_base = ioremap(base_addr, 512);
440 if (!at91_matrix_base) 417 if (!at91_matrix_base)
441 panic("Impossible to ioremap at91_matrix_base\n"); 418 panic(pr_fmt("Impossible to ioremap at91_matrix_base\n"));
442} 419}
443 420
444#if defined(CONFIG_OF) && !defined(CONFIG_ARCH_AT91X40) 421#if defined(CONFIG_OF) && !defined(CONFIG_ARCH_AT91X40)
445static struct of_device_id rstc_ids[] = {
446 { .compatible = "atmel,at91sam9260-rstc", .data = at91sam9_alt_restart },
447 { .compatible = "atmel,at91sam9g45-rstc", .data = at91sam9g45_restart },
448 { /*sentinel*/ }
449};
450
451static void at91_dt_rstc(void)
452{
453 struct device_node *np;
454 const struct of_device_id *of_id;
455
456 np = of_find_matching_node(NULL, rstc_ids);
457 if (!np)
458 panic("unable to find compatible rstc node in dtb\n");
459
460 at91_rstc_base = of_iomap(np, 0);
461 if (!at91_rstc_base)
462 panic("unable to map rstc cpu registers\n");
463
464 of_id = of_match_node(rstc_ids, np);
465 if (!of_id)
466 panic("AT91: rtsc no restart function available\n");
467
468 arm_pm_restart = of_id->data;
469
470 of_node_put(np);
471}
472
473static struct of_device_id ramc_ids[] = { 422static struct of_device_id ramc_ids[] = {
474 { .compatible = "atmel,at91rm9200-sdramc", .data = at91rm9200_standby }, 423 { .compatible = "atmel,at91rm9200-sdramc", .data = at91rm9200_standby },
475 { .compatible = "atmel,at91sam9260-sdramc", .data = at91sam9_sdram_standby }, 424 { .compatible = "atmel,at91sam9260-sdramc", .data = at91sam9_sdram_standby },
476 { .compatible = "atmel,at91sam9g45-ddramc", .data = at91_ddr_standby }, 425 { .compatible = "atmel,at91sam9g45-ddramc", .data = at91_ddr_standby },
426 { .compatible = "atmel,sama5d3-ddramc", .data = at91_ddr_standby },
477 { /*sentinel*/ } 427 { /*sentinel*/ }
478}; 428};
479 429
@@ -481,100 +431,29 @@ static void at91_dt_ramc(void)
481{ 431{
482 struct device_node *np; 432 struct device_node *np;
483 const struct of_device_id *of_id; 433 const struct of_device_id *of_id;
434 int idx = 0;
435 const void *standby = NULL;
484 436
485 np = of_find_matching_node(NULL, ramc_ids); 437 for_each_matching_node_and_match(np, ramc_ids, &of_id) {
486 if (!np) 438 at91_ramc_base[idx] = of_iomap(np, 0);
487 panic("unable to find compatible ram controller node in dtb\n"); 439 if (!at91_ramc_base[idx])
488 440 panic(pr_fmt("unable to map ramc[%d] cpu registers\n"), idx);
489 at91_ramc_base[0] = of_iomap(np, 0);
490 if (!at91_ramc_base[0])
491 panic("unable to map ramc[0] cpu registers\n");
492 /* the controller may have 2 banks */
493 at91_ramc_base[1] = of_iomap(np, 1);
494
495 of_id = of_match_node(ramc_ids, np);
496 if (!of_id)
497 pr_warn("AT91: ramc no standby function available\n");
498 else
499 at91_pm_set_standby(of_id->data);
500
501 of_node_put(np);
502}
503
504static struct of_device_id shdwc_ids[] = {
505 { .compatible = "atmel,at91sam9260-shdwc", },
506 { .compatible = "atmel,at91sam9rl-shdwc", },
507 { .compatible = "atmel,at91sam9x5-shdwc", },
508 { /*sentinel*/ }
509};
510
511static const char *shdwc_wakeup_modes[] = {
512 [AT91_SHDW_WKMODE0_NONE] = "none",
513 [AT91_SHDW_WKMODE0_HIGH] = "high",
514 [AT91_SHDW_WKMODE0_LOW] = "low",
515 [AT91_SHDW_WKMODE0_ANYLEVEL] = "any",
516};
517 441
518const int at91_dtget_shdwc_wakeup_mode(struct device_node *np) 442 if (!standby)
519{ 443 standby = of_id->data;
520 const char *pm;
521 int err, i;
522
523 err = of_property_read_string(np, "atmel,wakeup-mode", &pm);
524 if (err < 0)
525 return AT91_SHDW_WKMODE0_ANYLEVEL;
526
527 for (i = 0; i < ARRAY_SIZE(shdwc_wakeup_modes); i++)
528 if (!strcasecmp(pm, shdwc_wakeup_modes[i]))
529 return i;
530
531 return -ENODEV;
532}
533
534static void at91_dt_shdwc(void)
535{
536 struct device_node *np;
537 int wakeup_mode;
538 u32 reg;
539 u32 mode = 0;
540 444
541 np = of_find_matching_node(NULL, shdwc_ids); 445 idx++;
542 if (!np) {
543 pr_debug("AT91: unable to find compatible shutdown (shdwc) controller node in dtb\n");
544 return;
545 } 446 }
546 447
547 at91_shdwc_base = of_iomap(np, 0); 448 if (!idx)
548 if (!at91_shdwc_base) 449 panic(pr_fmt("unable to find compatible ram controller node in dtb\n"));
549 panic("AT91: unable to map shdwc cpu registers\n");
550
551 wakeup_mode = at91_dtget_shdwc_wakeup_mode(np);
552 if (wakeup_mode < 0) {
553 pr_warn("AT91: shdwc unknown wakeup mode\n");
554 goto end;
555 }
556 450
557 if (!of_property_read_u32(np, "atmel,wakeup-counter", &reg)) { 451 if (!standby) {
558 if (reg > AT91_SHDW_CPTWK0_MAX) { 452 pr_warn("ramc no standby function available\n");
559 pr_warn("AT91: shdwc wakeup counter 0x%x > 0x%x reduce it to 0x%x\n", 453 return;
560 reg, AT91_SHDW_CPTWK0_MAX, AT91_SHDW_CPTWK0_MAX);
561 reg = AT91_SHDW_CPTWK0_MAX;
562 }
563 mode |= AT91_SHDW_CPTWK0_(reg);
564 } 454 }
565 455
566 if (of_property_read_bool(np, "atmel,wakeup-rtc-timer")) 456 at91_pm_set_standby(standby);
567 mode |= AT91_SHDW_RTCWKEN;
568
569 if (of_property_read_bool(np, "atmel,wakeup-rtt-timer"))
570 mode |= AT91_SHDW_RTTWKEN;
571
572 at91_shdwc_write(AT91_SHDW_MR, wakeup_mode | mode);
573
574end:
575 pm_power_off = at91sam9_poweroff;
576
577 of_node_put(np);
578} 457}
579 458
580void __init at91rm9200_dt_initialize(void) 459void __init at91rm9200_dt_initialize(void)
@@ -593,9 +472,7 @@ void __init at91rm9200_dt_initialize(void)
593 472
594void __init at91_dt_initialize(void) 473void __init at91_dt_initialize(void)
595{ 474{
596 at91_dt_rstc();
597 at91_dt_ramc(); 475 at91_dt_ramc();
598 at91_dt_shdwc();
599 476
600 /* Init clock subsystem */ 477 /* Init clock subsystem */
601 at91_dt_clock_init(); 478 at91_dt_clock_init();
@@ -623,3 +500,13 @@ void __init at91_initialize(unsigned long main_clock)
623 500
624 pinctrl_provide_dummies(); 501 pinctrl_provide_dummies();
625} 502}
503
504void __init at91_register_devices(void)
505{
506 at91_boot_soc.register_devices();
507}
508
509void __init at91_init_time(void)
510{
511 at91_boot_soc.init_time();
512}
diff --git a/arch/arm/mach-at91/soc.h b/arch/arm/mach-at91/soc.h
index 8ecaee67f953..9a8fd97a8bef 100644
--- a/arch/arm/mach-at91/soc.h
+++ b/arch/arm/mach-at91/soc.h
@@ -11,7 +11,9 @@ struct at91_init_soc {
11 void (*map_io)(void); 11 void (*map_io)(void);
12 void (*ioremap_registers)(void); 12 void (*ioremap_registers)(void);
13 void (*register_clocks)(void); 13 void (*register_clocks)(void);
14 void (*register_devices)(void);
14 void (*init)(void); 15 void (*init)(void);
16 void (*init_time)(void);
15}; 17};
16 18
17extern struct at91_init_soc at91_boot_soc; 19extern struct at91_init_soc at91_boot_soc;
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 75212c064b31..f4d06aea8460 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -83,6 +83,7 @@ config ARCH_OMAP2PLUS
83 select PINCTRL 83 select PINCTRL
84 select SOC_BUS 84 select SOC_BUS
85 select TI_PRIV_EDMA 85 select TI_PRIV_EDMA
86 select OMAP_IRQCHIP
86 help 87 help
87 Systems based on OMAP2, OMAP3, OMAP4 or OMAP5 88 Systems based on OMAP2, OMAP3, OMAP4 or OMAP5
88 89
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index d9dd99c6aa28..d9e94122073e 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -10,7 +10,6 @@ obj-y := id.o io.o control.o mux.o devices.o fb.o serial.o gpmc.o timer.o pm.o \
10 common.o gpio.o dma.o wd_timer.o display.o i2c.o hdq1w.o omap_hwmod.o \ 10 common.o gpio.o dma.o wd_timer.o display.o i2c.o hdq1w.o omap_hwmod.o \
11 omap_device.o sram.o drm.o 11 omap_device.o sram.o drm.o
12 12
13omap-2-3-common = irq.o
14hwmod-common = omap_hwmod.o omap_hwmod_reset.o \ 13hwmod-common = omap_hwmod.o omap_hwmod_reset.o \
15 omap_hwmod_common_data.o 14 omap_hwmod_common_data.o
16clock-common = clock.o clock_common_data.o \ 15clock-common = clock.o clock_common_data.o \
@@ -20,7 +19,7 @@ secure-common = omap-smc.o omap-secure.o
20obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common) 19obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common)
21obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common) $(secure-common) 20obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common) $(secure-common)
22obj-$(CONFIG_ARCH_OMAP4) += $(hwmod-common) $(secure-common) 21obj-$(CONFIG_ARCH_OMAP4) += $(hwmod-common) $(secure-common)
23obj-$(CONFIG_SOC_AM33XX) += irq.o $(hwmod-common) 22obj-$(CONFIG_SOC_AM33XX) += $(hwmod-common)
24obj-$(CONFIG_SOC_OMAP5) += $(hwmod-common) $(secure-common) 23obj-$(CONFIG_SOC_OMAP5) += $(hwmod-common) $(secure-common)
25obj-$(CONFIG_SOC_AM43XX) += $(hwmod-common) $(secure-common) 24obj-$(CONFIG_SOC_AM43XX) += $(hwmod-common) $(secure-common)
26obj-$(CONFIG_SOC_DRA7XX) += $(hwmod-common) $(secure-common) 25obj-$(CONFIG_SOC_DRA7XX) += $(hwmod-common) $(secure-common)
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index d95d0ef1354a..d21a3048d06b 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -625,7 +625,6 @@ MACHINE_START(OMAP_3430SDP, "OMAP3430 3430SDP board")
625 .map_io = omap3_map_io, 625 .map_io = omap3_map_io,
626 .init_early = omap3430_init_early, 626 .init_early = omap3430_init_early,
627 .init_irq = omap3_init_irq, 627 .init_irq = omap3_init_irq,
628 .handle_irq = omap3_intc_handle_irq,
629 .init_machine = omap_3430sdp_init, 628 .init_machine = omap_3430sdp_init,
630 .init_late = omap3430_init_late, 629 .init_late = omap3430_init_late,
631 .init_time = omap3_sync32k_timer_init, 630 .init_time = omap3_sync32k_timer_init,
diff --git a/arch/arm/mach-omap2/board-am3517crane.c b/arch/arm/mach-omap2/board-am3517crane.c
index 0d499a1878f6..212c3160de18 100644
--- a/arch/arm/mach-omap2/board-am3517crane.c
+++ b/arch/arm/mach-omap2/board-am3517crane.c
@@ -142,7 +142,6 @@ MACHINE_START(CRANEBOARD, "AM3517/05 CRANEBOARD")
142 .map_io = omap3_map_io, 142 .map_io = omap3_map_io,
143 .init_early = am35xx_init_early, 143 .init_early = am35xx_init_early,
144 .init_irq = omap3_init_irq, 144 .init_irq = omap3_init_irq,
145 .handle_irq = omap3_intc_handle_irq,
146 .init_machine = am3517_crane_init, 145 .init_machine = am3517_crane_init,
147 .init_late = am35xx_init_late, 146 .init_late = am35xx_init_late,
148 .init_time = omap3_sync32k_timer_init, 147 .init_time = omap3_sync32k_timer_init,
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
index 4f9383cecf76..1c091b3fa312 100644
--- a/arch/arm/mach-omap2/board-am3517evm.c
+++ b/arch/arm/mach-omap2/board-am3517evm.c
@@ -366,7 +366,6 @@ MACHINE_START(OMAP3517EVM, "OMAP3517/AM3517 EVM")
366 .map_io = omap3_map_io, 366 .map_io = omap3_map_io,
367 .init_early = am35xx_init_early, 367 .init_early = am35xx_init_early,
368 .init_irq = omap3_init_irq, 368 .init_irq = omap3_init_irq,
369 .handle_irq = omap3_intc_handle_irq,
370 .init_machine = am3517_evm_init, 369 .init_machine = am3517_evm_init,
371 .init_late = am35xx_init_late, 370 .init_late = am35xx_init_late,
372 .init_time = omap3_sync32k_timer_init, 371 .init_time = omap3_sync32k_timer_init,
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index 018353d88b96..c6df8eec4553 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -766,7 +766,6 @@ MACHINE_START(CM_T35, "Compulab CM-T35")
766 .map_io = omap3_map_io, 766 .map_io = omap3_map_io,
767 .init_early = omap35xx_init_early, 767 .init_early = omap35xx_init_early,
768 .init_irq = omap3_init_irq, 768 .init_irq = omap3_init_irq,
769 .handle_irq = omap3_intc_handle_irq,
770 .init_machine = cm_t35_init, 769 .init_machine = cm_t35_init,
771 .init_late = omap35xx_init_late, 770 .init_late = omap35xx_init_late,
772 .init_time = omap3_sync32k_timer_init, 771 .init_time = omap3_sync32k_timer_init,
@@ -779,7 +778,6 @@ MACHINE_START(CM_T3730, "Compulab CM-T3730")
779 .map_io = omap3_map_io, 778 .map_io = omap3_map_io,
780 .init_early = omap3630_init_early, 779 .init_early = omap3630_init_early,
781 .init_irq = omap3_init_irq, 780 .init_irq = omap3_init_irq,
782 .handle_irq = omap3_intc_handle_irq,
783 .init_machine = cm_t3730_init, 781 .init_machine = cm_t3730_init,
784 .init_late = omap3630_init_late, 782 .init_late = omap3630_init_late,
785 .init_time = omap3_sync32k_timer_init, 783 .init_time = omap3_sync32k_timer_init,
diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c
index 4eb5e6f2f7f5..8a2c1677964c 100644
--- a/arch/arm/mach-omap2/board-cm-t3517.c
+++ b/arch/arm/mach-omap2/board-cm-t3517.c
@@ -329,7 +329,6 @@ MACHINE_START(CM_T3517, "Compulab CM-T3517")
329 .map_io = omap3_map_io, 329 .map_io = omap3_map_io,
330 .init_early = am35xx_init_early, 330 .init_early = am35xx_init_early,
331 .init_irq = omap3_init_irq, 331 .init_irq = omap3_init_irq,
332 .handle_irq = omap3_intc_handle_irq,
333 .init_machine = cm_t3517_init, 332 .init_machine = cm_t3517_init,
334 .init_late = am35xx_init_late, 333 .init_late = am35xx_init_late,
335 .init_time = omap3_gptimer_timer_init, 334 .init_time = omap3_gptimer_timer_init,
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index cdc4fb9960a9..d8e4f346936a 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -647,7 +647,6 @@ MACHINE_START(DEVKIT8000, "OMAP3 Devkit8000")
647 .map_io = omap3_map_io, 647 .map_io = omap3_map_io,
648 .init_early = omap35xx_init_early, 648 .init_early = omap35xx_init_early,
649 .init_irq = omap3_init_irq, 649 .init_irq = omap3_init_irq,
650 .handle_irq = omap3_intc_handle_irq,
651 .init_machine = devkit8000_init, 650 .init_machine = devkit8000_init,
652 .init_late = omap35xx_init_late, 651 .init_late = omap35xx_init_late,
653 .init_time = omap3_secure_sync32k_timer_init, 652 .init_time = omap3_secure_sync32k_timer_init,
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 69166eed5dba..608079a1aba6 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -52,8 +52,6 @@ DT_MACHINE_START(OMAP242X_DT, "Generic OMAP2420 (Flattened Device Tree)")
52 .reserve = omap_reserve, 52 .reserve = omap_reserve,
53 .map_io = omap242x_map_io, 53 .map_io = omap242x_map_io,
54 .init_early = omap2420_init_early, 54 .init_early = omap2420_init_early,
55 .init_irq = omap_intc_of_init,
56 .handle_irq = omap2_intc_handle_irq,
57 .init_machine = omap_generic_init, 55 .init_machine = omap_generic_init,
58 .init_time = omap2_sync32k_timer_init, 56 .init_time = omap2_sync32k_timer_init,
59 .dt_compat = omap242x_boards_compat, 57 .dt_compat = omap242x_boards_compat,
@@ -71,8 +69,6 @@ DT_MACHINE_START(OMAP243X_DT, "Generic OMAP2430 (Flattened Device Tree)")
71 .reserve = omap_reserve, 69 .reserve = omap_reserve,
72 .map_io = omap243x_map_io, 70 .map_io = omap243x_map_io,
73 .init_early = omap2430_init_early, 71 .init_early = omap2430_init_early,
74 .init_irq = omap_intc_of_init,
75 .handle_irq = omap2_intc_handle_irq,
76 .init_machine = omap_generic_init, 72 .init_machine = omap_generic_init,
77 .init_time = omap2_sync32k_timer_init, 73 .init_time = omap2_sync32k_timer_init,
78 .dt_compat = omap243x_boards_compat, 74 .dt_compat = omap243x_boards_compat,
@@ -91,8 +87,6 @@ DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)")
91 .reserve = omap_reserve, 87 .reserve = omap_reserve,
92 .map_io = omap3_map_io, 88 .map_io = omap3_map_io,
93 .init_early = omap3430_init_early, 89 .init_early = omap3430_init_early,
94 .init_irq = omap_intc_of_init,
95 .handle_irq = omap3_intc_handle_irq,
96 .init_machine = omap_generic_init, 90 .init_machine = omap_generic_init,
97 .init_late = omap3_init_late, 91 .init_late = omap3_init_late,
98 .init_time = omap3_sync32k_timer_init, 92 .init_time = omap3_sync32k_timer_init,
@@ -109,8 +103,6 @@ DT_MACHINE_START(OMAP36XX_DT, "Generic OMAP36xx (Flattened Device Tree)")
109 .reserve = omap_reserve, 103 .reserve = omap_reserve,
110 .map_io = omap3_map_io, 104 .map_io = omap3_map_io,
111 .init_early = omap3630_init_early, 105 .init_early = omap3630_init_early,
112 .init_irq = omap_intc_of_init,
113 .handle_irq = omap3_intc_handle_irq,
114 .init_machine = omap_generic_init, 106 .init_machine = omap_generic_init,
115 .init_late = omap3_init_late, 107 .init_late = omap3_init_late,
116 .init_time = omap3_sync32k_timer_init, 108 .init_time = omap3_sync32k_timer_init,
@@ -128,8 +120,6 @@ DT_MACHINE_START(OMAP3_GP_DT, "Generic OMAP3-GP (Flattened Device Tree)")
128 .reserve = omap_reserve, 120 .reserve = omap_reserve,
129 .map_io = omap3_map_io, 121 .map_io = omap3_map_io,
130 .init_early = omap3430_init_early, 122 .init_early = omap3430_init_early,
131 .init_irq = omap_intc_of_init,
132 .handle_irq = omap3_intc_handle_irq,
133 .init_machine = omap_generic_init, 123 .init_machine = omap_generic_init,
134 .init_late = omap3_init_late, 124 .init_late = omap3_init_late,
135 .init_time = omap3_secure_sync32k_timer_init, 125 .init_time = omap3_secure_sync32k_timer_init,
@@ -146,8 +136,6 @@ DT_MACHINE_START(AM3517_DT, "Generic AM3517 (Flattened Device Tree)")
146 .reserve = omap_reserve, 136 .reserve = omap_reserve,
147 .map_io = omap3_map_io, 137 .map_io = omap3_map_io,
148 .init_early = am35xx_init_early, 138 .init_early = am35xx_init_early,
149 .init_irq = omap_intc_of_init,
150 .handle_irq = omap3_intc_handle_irq,
151 .init_machine = omap_generic_init, 139 .init_machine = omap_generic_init,
152 .init_late = omap3_init_late, 140 .init_late = omap3_init_late,
153 .init_time = omap3_gptimer_timer_init, 141 .init_time = omap3_gptimer_timer_init,
@@ -166,8 +154,6 @@ DT_MACHINE_START(AM33XX_DT, "Generic AM33XX (Flattened Device Tree)")
166 .reserve = omap_reserve, 154 .reserve = omap_reserve,
167 .map_io = am33xx_map_io, 155 .map_io = am33xx_map_io,
168 .init_early = am33xx_init_early, 156 .init_early = am33xx_init_early,
169 .init_irq = omap_intc_of_init,
170 .handle_irq = omap3_intc_handle_irq,
171 .init_machine = omap_generic_init, 157 .init_machine = omap_generic_init,
172 .init_late = am33xx_init_late, 158 .init_late = am33xx_init_late,
173 .init_time = omap3_gptimer_timer_init, 159 .init_time = omap3_gptimer_timer_init,
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index 44a59c3abfb0..c2975af4cd5d 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -422,7 +422,6 @@ MACHINE_START(OMAP_LDP, "OMAP LDP board")
422 .map_io = omap3_map_io, 422 .map_io = omap3_map_io,
423 .init_early = omap3430_init_early, 423 .init_early = omap3430_init_early,
424 .init_irq = omap3_init_irq, 424 .init_irq = omap3_init_irq,
425 .handle_irq = omap3_intc_handle_irq,
426 .init_machine = omap_ldp_init, 425 .init_machine = omap_ldp_init,
427 .init_late = omap3430_init_late, 426 .init_late = omap3430_init_late,
428 .init_time = omap3_sync32k_timer_init, 427 .init_time = omap3_sync32k_timer_init,
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index aead77a4bc6d..97767a27ca9d 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -33,6 +33,7 @@
33#include "mmc.h" 33#include "mmc.h"
34#include "soc.h" 34#include "soc.h"
35#include "gpmc-onenand.h" 35#include "gpmc-onenand.h"
36#include "common-board-devices.h"
36 37
37#define TUSB6010_ASYNC_CS 1 38#define TUSB6010_ASYNC_CS 1
38#define TUSB6010_SYNC_CS 4 39#define TUSB6010_SYNC_CS 4
@@ -568,29 +569,14 @@ static int n8x0_menelaus_late_init(struct device *dev)
568} 569}
569#endif 570#endif
570 571
571static struct menelaus_platform_data n8x0_menelaus_platform_data __initdata = { 572struct menelaus_platform_data n8x0_menelaus_platform_data __initdata = {
572 .late_init = n8x0_menelaus_late_init, 573 .late_init = n8x0_menelaus_late_init,
573}; 574};
574 575
575static struct i2c_board_info __initdata n8x0_i2c_board_info_1[] __initdata = { 576struct aic3x_pdata n810_aic33_data __initdata = {
576 {
577 I2C_BOARD_INFO("menelaus", 0x72),
578 .irq = 7 + OMAP_INTC_START,
579 .platform_data = &n8x0_menelaus_platform_data,
580 },
581};
582
583static struct aic3x_pdata n810_aic33_data __initdata = {
584 .gpio_reset = 118, 577 .gpio_reset = 118,
585}; 578};
586 579
587static struct i2c_board_info n810_i2c_board_info_2[] __initdata = {
588 {
589 I2C_BOARD_INFO("tlv320aic3x", 0x18),
590 .platform_data = &n810_aic33_data,
591 },
592};
593
594static int __init n8x0_late_initcall(void) 580static int __init n8x0_late_initcall(void)
595{ 581{
596 if (!board_caps) 582 if (!board_caps)
@@ -612,11 +598,5 @@ void * __init n8x0_legacy_init(void)
612 board_check_revision(); 598 board_check_revision();
613 spi_register_board_info(n800_spi_board_info, 599 spi_register_board_info(n800_spi_board_info,
614 ARRAY_SIZE(n800_spi_board_info)); 600 ARRAY_SIZE(n800_spi_board_info));
615 i2c_register_board_info(0, n8x0_i2c_board_info_1,
616 ARRAY_SIZE(n8x0_i2c_board_info_1));
617 if (board_is_n810())
618 i2c_register_board_info(1, n810_i2c_board_info_2,
619 ARRAY_SIZE(n810_i2c_board_info_2));
620
621 return &mmc1_data; 601 return &mmc1_data;
622} 602}
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index e2e52031f056..81de1c68b360 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -588,7 +588,6 @@ MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board")
588 .map_io = omap3_map_io, 588 .map_io = omap3_map_io,
589 .init_early = omap3_init_early, 589 .init_early = omap3_init_early,
590 .init_irq = omap3_init_irq, 590 .init_irq = omap3_init_irq,
591 .handle_irq = omap3_intc_handle_irq,
592 .init_machine = omap3_beagle_init, 591 .init_machine = omap3_beagle_init,
593 .init_late = omap3_init_late, 592 .init_late = omap3_init_late,
594 .init_time = omap3_secure_sync32k_timer_init, 593 .init_time = omap3_secure_sync32k_timer_init,
diff --git a/arch/arm/mach-omap2/board-omap3logic.c b/arch/arm/mach-omap2/board-omap3logic.c
index bab51e64c4b5..6049f60a8813 100644
--- a/arch/arm/mach-omap2/board-omap3logic.c
+++ b/arch/arm/mach-omap2/board-omap3logic.c
@@ -230,7 +230,6 @@ MACHINE_START(OMAP3_TORPEDO, "Logic OMAP3 Torpedo board")
230 .map_io = omap3_map_io, 230 .map_io = omap3_map_io,
231 .init_early = omap35xx_init_early, 231 .init_early = omap35xx_init_early,
232 .init_irq = omap3_init_irq, 232 .init_irq = omap3_init_irq,
233 .handle_irq = omap3_intc_handle_irq,
234 .init_machine = omap3logic_init, 233 .init_machine = omap3logic_init,
235 .init_late = omap35xx_init_late, 234 .init_late = omap35xx_init_late,
236 .init_time = omap3_sync32k_timer_init, 235 .init_time = omap3_sync32k_timer_init,
@@ -243,7 +242,6 @@ MACHINE_START(OMAP3530_LV_SOM, "OMAP Logic 3530 LV SOM board")
243 .map_io = omap3_map_io, 242 .map_io = omap3_map_io,
244 .init_early = omap35xx_init_early, 243 .init_early = omap35xx_init_early,
245 .init_irq = omap3_init_irq, 244 .init_irq = omap3_init_irq,
246 .handle_irq = omap3_intc_handle_irq,
247 .init_machine = omap3logic_init, 245 .init_machine = omap3logic_init,
248 .init_late = omap35xx_init_late, 246 .init_late = omap35xx_init_late,
249 .init_time = omap3_sync32k_timer_init, 247 .init_time = omap3_sync32k_timer_init,
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index cf18340eb3bb..f32201656cf3 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -624,7 +624,6 @@ MACHINE_START(OMAP3_PANDORA, "Pandora Handheld Console")
624 .map_io = omap3_map_io, 624 .map_io = omap3_map_io,
625 .init_early = omap35xx_init_early, 625 .init_early = omap35xx_init_early,
626 .init_irq = omap3_init_irq, 626 .init_irq = omap3_init_irq,
627 .handle_irq = omap3_intc_handle_irq,
628 .init_machine = omap3pandora_init, 627 .init_machine = omap3pandora_init,
629 .init_late = omap35xx_init_late, 628 .init_late = omap35xx_init_late,
630 .init_time = omap3_sync32k_timer_init, 629 .init_time = omap3_sync32k_timer_init,
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index a2e035e0792a..6311f4b1ee44 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -426,7 +426,6 @@ MACHINE_START(SBC3530, "OMAP3 STALKER")
426 .map_io = omap3_map_io, 426 .map_io = omap3_map_io,
427 .init_early = omap35xx_init_early, 427 .init_early = omap35xx_init_early,
428 .init_irq = omap3_init_irq, 428 .init_irq = omap3_init_irq,
429 .handle_irq = omap3_intc_handle_irq,
430 .init_machine = omap3_stalker_init, 429 .init_machine = omap3_stalker_init,
431 .init_late = omap35xx_init_late, 430 .init_late = omap35xx_init_late,
432 .init_time = omap3_secure_sync32k_timer_init, 431 .init_time = omap3_secure_sync32k_timer_init,
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
index 70b904c010c6..a01993e5500f 100644
--- a/arch/arm/mach-omap2/board-omap3touchbook.c
+++ b/arch/arm/mach-omap2/board-omap3touchbook.c
@@ -388,7 +388,6 @@ MACHINE_START(TOUCHBOOK, "OMAP3 touchbook Board")
388 .map_io = omap3_map_io, 388 .map_io = omap3_map_io,
389 .init_early = omap3430_init_early, 389 .init_early = omap3430_init_early,
390 .init_irq = omap3_init_irq, 390 .init_irq = omap3_init_irq,
391 .handle_irq = omap3_intc_handle_irq,
392 .init_machine = omap3_touchbook_init, 391 .init_machine = omap3_touchbook_init,
393 .init_late = omap3430_init_late, 392 .init_late = omap3430_init_late,
394 .init_time = omap3_secure_sync32k_timer_init, 393 .init_time = omap3_secure_sync32k_timer_init,
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index f6d384111911..2dae6ccd39bb 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -564,7 +564,6 @@ MACHINE_START(OVERO, "Gumstix Overo")
564 .map_io = omap3_map_io, 564 .map_io = omap3_map_io,
565 .init_early = omap35xx_init_early, 565 .init_early = omap35xx_init_early,
566 .init_irq = omap3_init_irq, 566 .init_irq = omap3_init_irq,
567 .handle_irq = omap3_intc_handle_irq,
568 .init_machine = overo_init, 567 .init_machine = overo_init,
569 .init_late = omap35xx_init_late, 568 .init_late = omap35xx_init_late,
570 .init_time = omap3_sync32k_timer_init, 569 .init_time = omap3_sync32k_timer_init,
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index db168c9627a1..2d1e5a6beb85 100644
--- a/arch/arm/mach-omap2/board-rx51.c
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -134,7 +134,6 @@ MACHINE_START(NOKIA_RX51, "Nokia RX-51 board")
134 .map_io = omap3_map_io, 134 .map_io = omap3_map_io,
135 .init_early = omap3430_init_early, 135 .init_early = omap3430_init_early,
136 .init_irq = omap3_init_irq, 136 .init_irq = omap3_init_irq,
137 .handle_irq = omap3_intc_handle_irq,
138 .init_machine = rx51_init, 137 .init_machine = rx51_init,
139 .init_late = omap3430_init_late, 138 .init_late = omap3430_init_late,
140 .init_time = omap3_sync32k_timer_init, 139 .init_time = omap3_sync32k_timer_init,
diff --git a/arch/arm/mach-omap2/common-board-devices.h b/arch/arm/mach-omap2/common-board-devices.h
index f338177e6900..07c88ae083fb 100644
--- a/arch/arm/mach-omap2/common-board-devices.h
+++ b/arch/arm/mach-omap2/common-board-devices.h
@@ -1,6 +1,8 @@
1#ifndef __OMAP_COMMON_BOARD_DEVICES__ 1#ifndef __OMAP_COMMON_BOARD_DEVICES__
2#define __OMAP_COMMON_BOARD_DEVICES__ 2#define __OMAP_COMMON_BOARD_DEVICES__
3 3
4#include <sound/tlv320aic3x.h>
5#include <linux/mfd/menelaus.h>
4#include "twl-common.h" 6#include "twl-common.h"
5 7
6#define NAND_BLOCK_SIZE SZ_128K 8#define NAND_BLOCK_SIZE SZ_128K
@@ -12,4 +14,7 @@ void omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce,
12 struct ads7846_platform_data *board_pdata); 14 struct ads7846_platform_data *board_pdata);
13void *n8x0_legacy_init(void); 15void *n8x0_legacy_init(void);
14 16
17extern struct menelaus_platform_data n8x0_menelaus_platform_data;
18extern struct aic3x_pdata n810_aic33_data;
19
15#endif /* __OMAP_COMMON_BOARD_DEVICES__ */ 20#endif /* __OMAP_COMMON_BOARD_DEVICES__ */
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
index 98fe235f6670..377eea849e7b 100644
--- a/arch/arm/mach-omap2/common.h
+++ b/arch/arm/mach-omap2/common.h
@@ -32,6 +32,7 @@
32#include <linux/i2c/twl.h> 32#include <linux/i2c/twl.h>
33#include <linux/i2c-omap.h> 33#include <linux/i2c-omap.h>
34#include <linux/reboot.h> 34#include <linux/reboot.h>
35#include <linux/irqchip/irq-omap-intc.h>
35 36
36#include <asm/proc-fns.h> 37#include <asm/proc-fns.h>
37 38
@@ -210,18 +211,6 @@ extern struct device *omap2_get_iva_device(void);
210extern struct device *omap2_get_l3_device(void); 211extern struct device *omap2_get_l3_device(void);
211extern struct device *omap4_get_dsp_device(void); 212extern struct device *omap4_get_dsp_device(void);
212 213
213void omap2_init_irq(void);
214void omap3_init_irq(void);
215void ti81xx_init_irq(void);
216extern int omap_irq_pending(void);
217void omap_intc_save_context(void);
218void omap_intc_restore_context(void);
219void omap3_intc_suspend(void);
220void omap3_intc_prepare_idle(void);
221void omap3_intc_resume_idle(void);
222void omap2_intc_handle_irq(struct pt_regs *regs);
223void omap3_intc_handle_irq(struct pt_regs *regs);
224void omap_intc_of_init(void);
225void omap_gic_of_init(void); 214void omap_gic_of_init(void);
226 215
227#ifdef CONFIG_CACHE_L2X0 216#ifdef CONFIG_CACHE_L2X0
@@ -229,16 +218,6 @@ extern void __iomem *omap4_get_l2cache_base(void);
229#endif 218#endif
230 219
231struct device_node; 220struct device_node;
232#ifdef CONFIG_OF
233int __init intc_of_init(struct device_node *node,
234 struct device_node *parent);
235#else
236int __init intc_of_init(struct device_node *node,
237 struct device_node *parent)
238{
239 return 0;
240}
241#endif
242 221
243#ifdef CONFIG_SMP 222#ifdef CONFIG_SMP
244extern void __iomem *omap4_get_scu_base(void); 223extern void __iomem *omap4_get_scu_base(void);
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
deleted file mode 100644
index 604a976abf14..000000000000
--- a/arch/arm/mach-omap2/irq.c
+++ /dev/null
@@ -1,380 +0,0 @@
1/*
2 * linux/arch/arm/mach-omap2/irq.c
3 *
4 * Interrupt handler for OMAP2 boards.
5 *
6 * Copyright (C) 2005 Nokia Corporation
7 * Author: Paul Mundt <paul.mundt@nokia.com>
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/interrupt.h>
17#include <linux/io.h>
18
19#include <asm/exception.h>
20#include <asm/mach/irq.h>
21#include <linux/irqdomain.h>
22#include <linux/of.h>
23#include <linux/of_address.h>
24#include <linux/of_irq.h>
25
26#include "soc.h"
27#include "iomap.h"
28#include "common.h"
29
30/* selected INTC register offsets */
31
32#define INTC_REVISION 0x0000
33#define INTC_SYSCONFIG 0x0010
34#define INTC_SYSSTATUS 0x0014
35#define INTC_SIR 0x0040
36#define INTC_CONTROL 0x0048
37#define INTC_PROTECTION 0x004C
38#define INTC_IDLE 0x0050
39#define INTC_THRESHOLD 0x0068
40#define INTC_MIR0 0x0084
41#define INTC_MIR_CLEAR0 0x0088
42#define INTC_MIR_SET0 0x008c
43#define INTC_PENDING_IRQ0 0x0098
44/* Number of IRQ state bits in each MIR register */
45#define IRQ_BITS_PER_REG 32
46
47#define OMAP2_IRQ_BASE OMAP2_L4_IO_ADDRESS(OMAP24XX_IC_BASE)
48#define OMAP3_IRQ_BASE OMAP2_L4_IO_ADDRESS(OMAP34XX_IC_BASE)
49#define INTCPS_SIR_IRQ_OFFSET 0x0040 /* omap2/3 active interrupt offset */
50#define ACTIVEIRQ_MASK 0x7f /* omap2/3 active interrupt bits */
51#define INTCPS_NR_MIR_REGS 3
52#define INTCPS_NR_IRQS 96
53
54/*
55 * OMAP2 has a number of different interrupt controllers, each interrupt
56 * controller is identified as its own "bank". Register definitions are
57 * fairly consistent for each bank, but not all registers are implemented
58 * for each bank.. when in doubt, consult the TRM.
59 */
60static struct omap_irq_bank {
61 void __iomem *base_reg;
62 unsigned int nr_irqs;
63} __attribute__ ((aligned(4))) irq_banks[] = {
64 {
65 /* MPU INTC */
66 .nr_irqs = 96,
67 },
68};
69
70static struct irq_domain *domain;
71
72/* Structure to save interrupt controller context */
73struct omap3_intc_regs {
74 u32 sysconfig;
75 u32 protection;
76 u32 idle;
77 u32 threshold;
78 u32 ilr[INTCPS_NR_IRQS];
79 u32 mir[INTCPS_NR_MIR_REGS];
80};
81
82/* INTC bank register get/set */
83
84static void intc_bank_write_reg(u32 val, struct omap_irq_bank *bank, u16 reg)
85{
86 writel_relaxed(val, bank->base_reg + reg);
87}
88
89static u32 intc_bank_read_reg(struct omap_irq_bank *bank, u16 reg)
90{
91 return readl_relaxed(bank->base_reg + reg);
92}
93
94/* XXX: FIQ and additional INTC support (only MPU at the moment) */
95static void omap_ack_irq(struct irq_data *d)
96{
97 intc_bank_write_reg(0x1, &irq_banks[0], INTC_CONTROL);
98}
99
100static void omap_mask_ack_irq(struct irq_data *d)
101{
102 irq_gc_mask_disable_reg(d);
103 omap_ack_irq(d);
104}
105
106static void __init omap_irq_bank_init_one(struct omap_irq_bank *bank)
107{
108 unsigned long tmp;
109
110 tmp = intc_bank_read_reg(bank, INTC_REVISION) & 0xff;
111 pr_info("IRQ: Found an INTC at 0x%p (revision %ld.%ld) with %d interrupts\n",
112 bank->base_reg, tmp >> 4, tmp & 0xf, bank->nr_irqs);
113
114 tmp = intc_bank_read_reg(bank, INTC_SYSCONFIG);
115 tmp |= 1 << 1; /* soft reset */
116 intc_bank_write_reg(tmp, bank, INTC_SYSCONFIG);
117
118 while (!(intc_bank_read_reg(bank, INTC_SYSSTATUS) & 0x1))
119 /* Wait for reset to complete */;
120
121 /* Enable autoidle */
122 intc_bank_write_reg(1 << 0, bank, INTC_SYSCONFIG);
123}
124
125int omap_irq_pending(void)
126{
127 int i;
128
129 for (i = 0; i < ARRAY_SIZE(irq_banks); i++) {
130 struct omap_irq_bank *bank = irq_banks + i;
131 int irq;
132
133 for (irq = 0; irq < bank->nr_irqs; irq += 32)
134 if (intc_bank_read_reg(bank, INTC_PENDING_IRQ0 +
135 ((irq >> 5) << 5)))
136 return 1;
137 }
138 return 0;
139}
140
141static __init void
142omap_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num)
143{
144 struct irq_chip_generic *gc;
145 struct irq_chip_type *ct;
146
147 gc = irq_alloc_generic_chip("INTC", 1, irq_start, base,
148 handle_level_irq);
149 ct = gc->chip_types;
150 ct->chip.irq_ack = omap_mask_ack_irq;
151 ct->chip.irq_mask = irq_gc_mask_disable_reg;
152 ct->chip.irq_unmask = irq_gc_unmask_enable_reg;
153 ct->chip.flags |= IRQCHIP_SKIP_SET_WAKE;
154
155 ct->regs.enable = INTC_MIR_CLEAR0;
156 ct->regs.disable = INTC_MIR_SET0;
157 irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE,
158 IRQ_NOREQUEST | IRQ_NOPROBE, 0);
159}
160
161static void __init omap_init_irq(u32 base, int nr_irqs,
162 struct device_node *node)
163{
164 void __iomem *omap_irq_base;
165 unsigned long nr_of_irqs = 0;
166 unsigned int nr_banks = 0;
167 int i, j, irq_base;
168
169 omap_irq_base = ioremap(base, SZ_4K);
170 if (WARN_ON(!omap_irq_base))
171 return;
172
173 irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0);
174 if (irq_base < 0) {
175 pr_warn("Couldn't allocate IRQ numbers\n");
176 irq_base = 0;
177 }
178
179 domain = irq_domain_add_legacy(node, nr_irqs, irq_base, 0,
180 &irq_domain_simple_ops, NULL);
181
182 for (i = 0; i < ARRAY_SIZE(irq_banks); i++) {
183 struct omap_irq_bank *bank = irq_banks + i;
184
185 bank->nr_irqs = nr_irqs;
186
187 /* Static mapping, never released */
188 bank->base_reg = ioremap(base, SZ_4K);
189 if (!bank->base_reg) {
190 pr_err("Could not ioremap irq bank%i\n", i);
191 continue;
192 }
193
194 omap_irq_bank_init_one(bank);
195
196 for (j = 0; j < bank->nr_irqs; j += 32)
197 omap_alloc_gc(bank->base_reg + j, j + irq_base, 32);
198
199 nr_of_irqs += bank->nr_irqs;
200 nr_banks++;
201 }
202
203 pr_info("Total of %ld interrupts on %d active controller%s\n",
204 nr_of_irqs, nr_banks, nr_banks > 1 ? "s" : "");
205}
206
207void __init omap2_init_irq(void)
208{
209 omap_init_irq(OMAP24XX_IC_BASE, 96, NULL);
210}
211
212void __init omap3_init_irq(void)
213{
214 omap_init_irq(OMAP34XX_IC_BASE, 96, NULL);
215}
216
217void __init ti81xx_init_irq(void)
218{
219 omap_init_irq(OMAP34XX_IC_BASE, 128, NULL);
220}
221
222static inline void omap_intc_handle_irq(void __iomem *base_addr, struct pt_regs *regs)
223{
224 u32 irqnr;
225 int handled_irq = 0;
226
227 do {
228 irqnr = readl_relaxed(base_addr + 0x98);
229 if (irqnr)
230 goto out;
231
232 irqnr = readl_relaxed(base_addr + 0xb8);
233 if (irqnr)
234 goto out;
235
236 irqnr = readl_relaxed(base_addr + 0xd8);
237#if IS_ENABLED(CONFIG_SOC_TI81XX) || IS_ENABLED(CONFIG_SOC_AM33XX)
238 if (irqnr)
239 goto out;
240 irqnr = readl_relaxed(base_addr + 0xf8);
241#endif
242
243out:
244 if (!irqnr)
245 break;
246
247 irqnr = readl_relaxed(base_addr + INTCPS_SIR_IRQ_OFFSET);
248 irqnr &= ACTIVEIRQ_MASK;
249
250 if (irqnr) {
251 irqnr = irq_find_mapping(domain, irqnr);
252 handle_IRQ(irqnr, regs);
253 handled_irq = 1;
254 }
255 } while (irqnr);
256
257 /* If an irq is masked or deasserted while active, we will
258 * keep ending up here with no irq handled. So remove it from
259 * the INTC with an ack.*/
260 if (!handled_irq)
261 omap_ack_irq(NULL);
262}
263
264asmlinkage void __exception_irq_entry omap2_intc_handle_irq(struct pt_regs *regs)
265{
266 void __iomem *base_addr = OMAP2_IRQ_BASE;
267 omap_intc_handle_irq(base_addr, regs);
268}
269
270int __init intc_of_init(struct device_node *node,
271 struct device_node *parent)
272{
273 struct resource res;
274 u32 nr_irq = 96;
275
276 if (WARN_ON(!node))
277 return -ENODEV;
278
279 if (of_address_to_resource(node, 0, &res)) {
280 WARN(1, "unable to get intc registers\n");
281 return -EINVAL;
282 }
283
284 if (of_property_read_u32(node, "ti,intc-size", &nr_irq))
285 pr_warn("unable to get intc-size, default to %d\n", nr_irq);
286
287 omap_init_irq(res.start, nr_irq, of_node_get(node));
288
289 return 0;
290}
291
292static const struct of_device_id irq_match[] __initconst = {
293 { .compatible = "ti,omap2-intc", .data = intc_of_init, },
294 { }
295};
296
297void __init omap_intc_of_init(void)
298{
299 of_irq_init(irq_match);
300}
301
302#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX)
303static struct omap3_intc_regs intc_context[ARRAY_SIZE(irq_banks)];
304
305void omap_intc_save_context(void)
306{
307 int ind = 0, i = 0;
308 for (ind = 0; ind < ARRAY_SIZE(irq_banks); ind++) {
309 struct omap_irq_bank *bank = irq_banks + ind;
310 intc_context[ind].sysconfig =
311 intc_bank_read_reg(bank, INTC_SYSCONFIG);
312 intc_context[ind].protection =
313 intc_bank_read_reg(bank, INTC_PROTECTION);
314 intc_context[ind].idle =
315 intc_bank_read_reg(bank, INTC_IDLE);
316 intc_context[ind].threshold =
317 intc_bank_read_reg(bank, INTC_THRESHOLD);
318 for (i = 0; i < INTCPS_NR_IRQS; i++)
319 intc_context[ind].ilr[i] =
320 intc_bank_read_reg(bank, (0x100 + 0x4*i));
321 for (i = 0; i < INTCPS_NR_MIR_REGS; i++)
322 intc_context[ind].mir[i] =
323 intc_bank_read_reg(&irq_banks[0], INTC_MIR0 +
324 (0x20 * i));
325 }
326}
327
328void omap_intc_restore_context(void)
329{
330 int ind = 0, i = 0;
331
332 for (ind = 0; ind < ARRAY_SIZE(irq_banks); ind++) {
333 struct omap_irq_bank *bank = irq_banks + ind;
334 intc_bank_write_reg(intc_context[ind].sysconfig,
335 bank, INTC_SYSCONFIG);
336 intc_bank_write_reg(intc_context[ind].sysconfig,
337 bank, INTC_SYSCONFIG);
338 intc_bank_write_reg(intc_context[ind].protection,
339 bank, INTC_PROTECTION);
340 intc_bank_write_reg(intc_context[ind].idle,
341 bank, INTC_IDLE);
342 intc_bank_write_reg(intc_context[ind].threshold,
343 bank, INTC_THRESHOLD);
344 for (i = 0; i < INTCPS_NR_IRQS; i++)
345 intc_bank_write_reg(intc_context[ind].ilr[i],
346 bank, (0x100 + 0x4*i));
347 for (i = 0; i < INTCPS_NR_MIR_REGS; i++)
348 intc_bank_write_reg(intc_context[ind].mir[i],
349 &irq_banks[0], INTC_MIR0 + (0x20 * i));
350 }
351 /* MIRs are saved and restore with other PRCM registers */
352}
353
354void omap3_intc_suspend(void)
355{
356 /* A pending interrupt would prevent OMAP from entering suspend */
357 omap_ack_irq(NULL);
358}
359
360void omap3_intc_prepare_idle(void)
361{
362 /*
363 * Disable autoidle as it can stall interrupt controller,
364 * cf. errata ID i540 for 3430 (all revisions up to 3.1.x)
365 */
366 intc_bank_write_reg(0, &irq_banks[0], INTC_SYSCONFIG);
367}
368
369void omap3_intc_resume_idle(void)
370{
371 /* Re-enable autoidle */
372 intc_bank_write_reg(1, &irq_banks[0], INTC_SYSCONFIG);
373}
374
375asmlinkage void __exception_irq_entry omap3_intc_handle_irq(struct pt_regs *regs)
376{
377 void __iomem *base_addr = OMAP3_IRQ_BASE;
378 omap_intc_handle_irq(base_addr, regs);
379}
380#endif /* CONFIG_ARCH_OMAP3 */
diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
index c8ac72604207..c95346c94829 100644
--- a/arch/arm/mach-omap2/pdata-quirks.c
+++ b/arch/arm/mach-omap2/pdata-quirks.c
@@ -344,6 +344,8 @@ static struct pdata_init auxdata_quirks[] __initdata = {
344struct of_dev_auxdata omap_auxdata_lookup[] __initdata = { 344struct of_dev_auxdata omap_auxdata_lookup[] __initdata = {
345#ifdef CONFIG_MACH_NOKIA_N8X0 345#ifdef CONFIG_MACH_NOKIA_N8X0
346 OF_DEV_AUXDATA("ti,omap2420-mmc", 0x4809c000, "mmci-omap.0", NULL), 346 OF_DEV_AUXDATA("ti,omap2420-mmc", 0x4809c000, "mmci-omap.0", NULL),
347 OF_DEV_AUXDATA("menelaus", 0x72, "1-0072", &n8x0_menelaus_platform_data),
348 OF_DEV_AUXDATA("tlv320aic3x", 0x18, "2-0018", &n810_aic33_data),
347#endif 349#endif
348#ifdef CONFIG_ARCH_OMAP3 350#ifdef CONFIG_ARCH_OMAP3
349 OF_DEV_AUXDATA("ti,omap3-padconf", 0x48002030, "48002030.pinmux", &pcs_pdata), 351 OF_DEV_AUXDATA("ti,omap3-padconf", 0x48002030, "48002030.pinmux", &pcs_pdata),
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 622fa266b29e..1a693d3f9d51 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -148,6 +148,8 @@ source "drivers/remoteproc/Kconfig"
148 148
149source "drivers/rpmsg/Kconfig" 149source "drivers/rpmsg/Kconfig"
150 150
151source "drivers/soc/Kconfig"
152
151source "drivers/devfreq/Kconfig" 153source "drivers/devfreq/Kconfig"
152 154
153source "drivers/extcon/Kconfig" 155source "drivers/extcon/Kconfig"
diff --git a/drivers/bus/arm-ccn.c b/drivers/bus/arm-ccn.c
index a60f26400705..aaa0f2a87118 100644
--- a/drivers/bus/arm-ccn.c
+++ b/drivers/bus/arm-ccn.c
@@ -57,6 +57,7 @@
57#define CCN_DT_PMCCNTRSR 0x0190 57#define CCN_DT_PMCCNTRSR 0x0190
58#define CCN_DT_PMOVSR 0x0198 58#define CCN_DT_PMOVSR 0x0198
59#define CCN_DT_PMOVSR_CLR 0x01a0 59#define CCN_DT_PMOVSR_CLR 0x01a0
60#define CCN_DT_PMOVSR_CLR__MASK 0x1f
60#define CCN_DT_PMCR 0x01a8 61#define CCN_DT_PMCR 0x01a8
61#define CCN_DT_PMCR__OVFL_INTR_EN (1 << 6) 62#define CCN_DT_PMCR__OVFL_INTR_EN (1 << 6)
62#define CCN_DT_PMCR__PMU_EN (1 << 0) 63#define CCN_DT_PMCR__PMU_EN (1 << 0)
@@ -1051,7 +1052,8 @@ static irqreturn_t arm_ccn_pmu_overflow_handler(struct arm_ccn_dt *dt)
1051 struct perf_event *event = dt->pmu_counters[idx].event; 1052 struct perf_event *event = dt->pmu_counters[idx].event;
1052 int overflowed = pmovsr & BIT(idx); 1053 int overflowed = pmovsr & BIT(idx);
1053 1054
1054 WARN_ON_ONCE(overflowed && !event); 1055 WARN_ON_ONCE(overflowed && !event &&
1056 idx != CCN_IDX_PMU_CYCLE_COUNTER);
1055 1057
1056 if (!event || !overflowed) 1058 if (!event || !overflowed)
1057 continue; 1059 continue;
@@ -1087,6 +1089,7 @@ static int arm_ccn_pmu_init(struct arm_ccn *ccn)
1087 /* Initialize DT subsystem */ 1089 /* Initialize DT subsystem */
1088 ccn->dt.base = ccn->base + CCN_REGION_SIZE; 1090 ccn->dt.base = ccn->base + CCN_REGION_SIZE;
1089 spin_lock_init(&ccn->dt.config_lock); 1091 spin_lock_init(&ccn->dt.config_lock);
1092 writel(CCN_DT_PMOVSR_CLR__MASK, ccn->dt.base + CCN_DT_PMOVSR_CLR);
1090 writel(CCN_DT_CTL__DT_EN, ccn->dt.base + CCN_DT_CTL); 1093 writel(CCN_DT_CTL__DT_EN, ccn->dt.base + CCN_DT_CTL);
1091 writel(CCN_DT_PMCR__OVFL_INTR_EN | CCN_DT_PMCR__PMU_EN, 1094 writel(CCN_DT_PMCR__OVFL_INTR_EN | CCN_DT_PMCR__PMU_EN,
1092 ccn->dt.base + CCN_DT_PMCR); 1095 ccn->dt.base + CCN_DT_PMCR);
diff --git a/drivers/clk/at91/clk-system.c b/drivers/clk/at91/clk-system.c
index 8c96307d7363..a76d03fd577b 100644
--- a/drivers/clk/at91/clk-system.c
+++ b/drivers/clk/at91/clk-system.c
@@ -119,13 +119,7 @@ at91_clk_register_system(struct at91_pmc *pmc, const char *name,
119 init.ops = &system_ops; 119 init.ops = &system_ops;
120 init.parent_names = &parent_name; 120 init.parent_names = &parent_name;
121 init.num_parents = 1; 121 init.num_parents = 1;
122 /* 122 init.flags = CLK_SET_RATE_PARENT;
123 * CLK_IGNORE_UNUSED is used to avoid ddrck switch off.
124 * TODO : we should implement a driver supporting at91 ddr controller
125 * (see drivers/memory) which would request and enable the ddrck clock.
126 * When this is done we will be able to remove CLK_IGNORE_UNUSED flag.
127 */
128 init.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED;
129 123
130 sys->id = id; 124 sys->id = id;
131 sys->hw.init = &init; 125 sys->hw.init = &init;
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index cfd6519df661..82a2ebe41e27 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -120,6 +120,10 @@ config CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
120 help 120 help
121 Use ARM global timer clock source as sched_clock 121 Use ARM global timer clock source as sched_clock
122 122
123config ATMEL_PIT
124 select CLKSRC_OF if OF
125 def_bool SOC_AT91SAM9 || SOC_SAMA5
126
123config CLKSRC_METAG_GENERIC 127config CLKSRC_METAG_GENERIC
124 def_bool y if METAG 128 def_bool y if METAG
125 help 129 help
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 7fd9fd1dff42..e566f6c7ded4 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -1,4 +1,5 @@
1obj-$(CONFIG_CLKSRC_OF) += clksrc-of.o 1obj-$(CONFIG_CLKSRC_OF) += clksrc-of.o
2obj-$(CONFIG_ATMEL_PIT) += timer-atmel-pit.o
2obj-$(CONFIG_ATMEL_TCB_CLKSRC) += tcb_clksrc.o 3obj-$(CONFIG_ATMEL_TCB_CLKSRC) += tcb_clksrc.o
3obj-$(CONFIG_X86_PM_TIMER) += acpi_pm.o 4obj-$(CONFIG_X86_PM_TIMER) += acpi_pm.o
4obj-$(CONFIG_SCx200HR_TIMER) += scx200_hrt.o 5obj-$(CONFIG_SCx200HR_TIMER) += scx200_hrt.o
diff --git a/drivers/clocksource/timer-atmel-pit.c b/drivers/clocksource/timer-atmel-pit.c
new file mode 100644
index 000000000000..d5289098b3df
--- /dev/null
+++ b/drivers/clocksource/timer-atmel-pit.c
@@ -0,0 +1,296 @@
1/*
2 * at91sam926x_time.c - Periodic Interval Timer (PIT) for at91sam926x
3 *
4 * Copyright (C) 2005-2006 M. Amine SAYA, ATMEL Rousset, France
5 * Revision 2005 M. Nicolas Diremdjian, ATMEL Rousset, France
6 * Converted to ClockSource/ClockEvents by David Brownell.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#define pr_fmt(fmt) "AT91: PIT: " fmt
14
15#include <linux/clk.h>
16#include <linux/clockchips.h>
17#include <linux/interrupt.h>
18#include <linux/irq.h>
19#include <linux/kernel.h>
20#include <linux/of.h>
21#include <linux/of_address.h>
22#include <linux/of_irq.h>
23#include <linux/slab.h>
24
25#define AT91_PIT_MR 0x00 /* Mode Register */
26#define AT91_PIT_PITIEN BIT(25) /* Timer Interrupt Enable */
27#define AT91_PIT_PITEN BIT(24) /* Timer Enabled */
28#define AT91_PIT_PIV GENMASK(19, 0) /* Periodic Interval Value */
29
30#define AT91_PIT_SR 0x04 /* Status Register */
31#define AT91_PIT_PITS BIT(0) /* Timer Status */
32
33#define AT91_PIT_PIVR 0x08 /* Periodic Interval Value Register */
34#define AT91_PIT_PIIR 0x0c /* Periodic Interval Image Register */
35#define AT91_PIT_PICNT GENMASK(31, 20) /* Interval Counter */
36#define AT91_PIT_CPIV GENMASK(19, 0) /* Inverval Value */
37
38#define PIT_CPIV(x) ((x) & AT91_PIT_CPIV)
39#define PIT_PICNT(x) (((x) & AT91_PIT_PICNT) >> 20)
40
41struct pit_data {
42 struct clock_event_device clkevt;
43 struct clocksource clksrc;
44
45 void __iomem *base;
46 u32 cycle;
47 u32 cnt;
48 unsigned int irq;
49 struct clk *mck;
50};
51
52static inline struct pit_data *clksrc_to_pit_data(struct clocksource *clksrc)
53{
54 return container_of(clksrc, struct pit_data, clksrc);
55}
56
57static inline struct pit_data *clkevt_to_pit_data(struct clock_event_device *clkevt)
58{
59 return container_of(clkevt, struct pit_data, clkevt);
60}
61
62static inline unsigned int pit_read(void __iomem *base, unsigned int reg_offset)
63{
64 return __raw_readl(base + reg_offset);
65}
66
67static inline void pit_write(void __iomem *base, unsigned int reg_offset, unsigned long value)
68{
69 __raw_writel(value, base + reg_offset);
70}
71
72/*
73 * Clocksource: just a monotonic counter of MCK/16 cycles.
74 * We don't care whether or not PIT irqs are enabled.
75 */
76static cycle_t read_pit_clk(struct clocksource *cs)
77{
78 struct pit_data *data = clksrc_to_pit_data(cs);
79 unsigned long flags;
80 u32 elapsed;
81 u32 t;
82
83 raw_local_irq_save(flags);
84 elapsed = data->cnt;
85 t = pit_read(data->base, AT91_PIT_PIIR);
86 raw_local_irq_restore(flags);
87
88 elapsed += PIT_PICNT(t) * data->cycle;
89 elapsed += PIT_CPIV(t);
90 return elapsed;
91}
92
93/*
94 * Clockevent device: interrupts every 1/HZ (== pit_cycles * MCK/16)
95 */
96static void
97pit_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev)
98{
99 struct pit_data *data = clkevt_to_pit_data(dev);
100
101 switch (mode) {
102 case CLOCK_EVT_MODE_PERIODIC:
103 /* update clocksource counter */
104 data->cnt += data->cycle * PIT_PICNT(pit_read(data->base, AT91_PIT_PIVR));
105 pit_write(data->base, AT91_PIT_MR,
106 (data->cycle - 1) | AT91_PIT_PITEN | AT91_PIT_PITIEN);
107 break;
108 case CLOCK_EVT_MODE_ONESHOT:
109 BUG();
110 /* FALLTHROUGH */
111 case CLOCK_EVT_MODE_SHUTDOWN:
112 case CLOCK_EVT_MODE_UNUSED:
113 /* disable irq, leaving the clocksource active */
114 pit_write(data->base, AT91_PIT_MR,
115 (data->cycle - 1) | AT91_PIT_PITEN);
116 break;
117 case CLOCK_EVT_MODE_RESUME:
118 break;
119 }
120}
121
122static void at91sam926x_pit_suspend(struct clock_event_device *cedev)
123{
124 struct pit_data *data = clkevt_to_pit_data(cedev);
125
126 /* Disable timer */
127 pit_write(data->base, AT91_PIT_MR, 0);
128}
129
130static void at91sam926x_pit_reset(struct pit_data *data)
131{
132 /* Disable timer and irqs */
133 pit_write(data->base, AT91_PIT_MR, 0);
134
135 /* Clear any pending interrupts, wait for PIT to stop counting */
136 while (PIT_CPIV(pit_read(data->base, AT91_PIT_PIVR)) != 0)
137 cpu_relax();
138
139 /* Start PIT but don't enable IRQ */
140 pit_write(data->base, AT91_PIT_MR,
141 (data->cycle - 1) | AT91_PIT_PITEN);
142}
143
144static void at91sam926x_pit_resume(struct clock_event_device *cedev)
145{
146 struct pit_data *data = clkevt_to_pit_data(cedev);
147
148 at91sam926x_pit_reset(data);
149}
150
151/*
152 * IRQ handler for the timer.
153 */
154static irqreturn_t at91sam926x_pit_interrupt(int irq, void *dev_id)
155{
156 struct pit_data *data = dev_id;
157
158 /*
159 * irqs should be disabled here, but as the irq is shared they are only
160 * guaranteed to be off if the timer irq is registered first.
161 */
162 WARN_ON_ONCE(!irqs_disabled());
163
164 /* The PIT interrupt may be disabled, and is shared */
165 if ((data->clkevt.mode == CLOCK_EVT_MODE_PERIODIC) &&
166 (pit_read(data->base, AT91_PIT_SR) & AT91_PIT_PITS)) {
167 unsigned nr_ticks;
168
169 /* Get number of ticks performed before irq, and ack it */
170 nr_ticks = PIT_PICNT(pit_read(data->base, AT91_PIT_PIVR));
171 do {
172 data->cnt += data->cycle;
173 data->clkevt.event_handler(&data->clkevt);
174 nr_ticks--;
175 } while (nr_ticks);
176
177 return IRQ_HANDLED;
178 }
179
180 return IRQ_NONE;
181}
182
183/*
184 * Set up both clocksource and clockevent support.
185 */
186static void __init at91sam926x_pit_common_init(struct pit_data *data)
187{
188 unsigned long pit_rate;
189 unsigned bits;
190 int ret;
191
192 /*
193 * Use our actual MCK to figure out how many MCK/16 ticks per
194 * 1/HZ period (instead of a compile-time constant LATCH).
195 */
196 pit_rate = clk_get_rate(data->mck) / 16;
197 data->cycle = DIV_ROUND_CLOSEST(pit_rate, HZ);
198 WARN_ON(((data->cycle - 1) & ~AT91_PIT_PIV) != 0);
199
200 /* Initialize and enable the timer */
201 at91sam926x_pit_reset(data);
202
203 /*
204 * Register clocksource. The high order bits of PIV are unused,
205 * so this isn't a 32-bit counter unless we get clockevent irqs.
206 */
207 bits = 12 /* PICNT */ + ilog2(data->cycle) /* PIV */;
208 data->clksrc.mask = CLOCKSOURCE_MASK(bits);
209 data->clksrc.name = "pit";
210 data->clksrc.rating = 175;
211 data->clksrc.read = read_pit_clk,
212 data->clksrc.flags = CLOCK_SOURCE_IS_CONTINUOUS,
213 clocksource_register_hz(&data->clksrc, pit_rate);
214
215 /* Set up irq handler */
216 ret = request_irq(data->irq, at91sam926x_pit_interrupt,
217 IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL,
218 "at91_tick", data);
219 if (ret)
220 panic(pr_fmt("Unable to setup IRQ\n"));
221
222 /* Set up and register clockevents */
223 data->clkevt.name = "pit";
224 data->clkevt.features = CLOCK_EVT_FEAT_PERIODIC;
225 data->clkevt.shift = 32;
226 data->clkevt.mult = div_sc(pit_rate, NSEC_PER_SEC, data->clkevt.shift);
227 data->clkevt.rating = 100;
228 data->clkevt.cpumask = cpumask_of(0);
229
230 data->clkevt.set_mode = pit_clkevt_mode;
231 data->clkevt.resume = at91sam926x_pit_resume;
232 data->clkevt.suspend = at91sam926x_pit_suspend;
233 clockevents_register_device(&data->clkevt);
234}
235
236static void __init at91sam926x_pit_dt_init(struct device_node *node)
237{
238 struct pit_data *data;
239
240 data = kzalloc(sizeof(*data), GFP_KERNEL);
241 if (!data)
242 panic(pr_fmt("Unable to allocate memory\n"));
243
244 data->base = of_iomap(node, 0);
245 if (!data->base)
246 panic(pr_fmt("Could not map PIT address\n"));
247
248 data->mck = of_clk_get(node, 0);
249 if (IS_ERR(data->mck))
250 /* Fallback on clkdev for !CCF-based boards */
251 data->mck = clk_get(NULL, "mck");
252
253 if (IS_ERR(data->mck))
254 panic(pr_fmt("Unable to get mck clk\n"));
255
256 /* Get the interrupts property */
257 data->irq = irq_of_parse_and_map(node, 0);
258 if (!data->irq)
259 panic(pr_fmt("Unable to get IRQ from DT\n"));
260
261 at91sam926x_pit_common_init(data);
262}
263CLOCKSOURCE_OF_DECLARE(at91sam926x_pit, "atmel,at91sam9260-pit",
264 at91sam926x_pit_dt_init);
265
266static void __iomem *pit_base_addr;
267
268void __init at91sam926x_pit_init(int irq)
269{
270 struct pit_data *data;
271
272 data = kzalloc(sizeof(*data), GFP_KERNEL);
273 if (!data)
274 panic(pr_fmt("Unable to allocate memory\n"));
275
276 data->base = pit_base_addr;
277
278 data->mck = clk_get(NULL, "mck");
279 if (IS_ERR(data->mck))
280 panic(pr_fmt("Unable to get mck clk\n"));
281
282 data->irq = irq;
283
284 at91sam926x_pit_common_init(data);
285}
286
287void __init at91sam926x_ioremap_pit(u32 addr)
288{
289 if (of_have_populated_dt())
290 return;
291
292 pit_base_addr = ioremap(addr, 16);
293
294 if (!pit_base_addr)
295 panic(pr_fmt("Impossible to ioremap PIT\n"));
296}
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index fd89ca982748..7072c2892d63 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -376,4 +376,13 @@ config EDAC_OCTEON_PCI
376 Support for error detection and correction on the 376 Support for error detection and correction on the
377 Cavium Octeon family of SOCs. 377 Cavium Octeon family of SOCs.
378 378
379config EDAC_ALTERA_MC
380 tristate "Altera SDRAM Memory Controller EDAC"
381 depends on EDAC_MM_EDAC && ARCH_SOCFPGA
382 help
383 Support for error detection and correction on the
384 Altera SDRAM memory controller. Note that the
385 preloader must initialize the SDRAM before loading
386 the kernel.
387
379endif # EDAC 388endif # EDAC
diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile
index c479a24d8f77..359aa499b200 100644
--- a/drivers/edac/Makefile
+++ b/drivers/edac/Makefile
@@ -65,3 +65,5 @@ obj-$(CONFIG_EDAC_OCTEON_PC) += octeon_edac-pc.o
65obj-$(CONFIG_EDAC_OCTEON_L2C) += octeon_edac-l2c.o 65obj-$(CONFIG_EDAC_OCTEON_L2C) += octeon_edac-l2c.o
66obj-$(CONFIG_EDAC_OCTEON_LMC) += octeon_edac-lmc.o 66obj-$(CONFIG_EDAC_OCTEON_LMC) += octeon_edac-lmc.o
67obj-$(CONFIG_EDAC_OCTEON_PCI) += octeon_edac-pci.o 67obj-$(CONFIG_EDAC_OCTEON_PCI) += octeon_edac-pci.o
68
69obj-$(CONFIG_EDAC_ALTERA_MC) += altera_edac.o
diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c
new file mode 100644
index 000000000000..3c4929fda9d5
--- /dev/null
+++ b/drivers/edac/altera_edac.c
@@ -0,0 +1,410 @@
1/*
2 * Copyright Altera Corporation (C) 2014. All rights reserved.
3 * Copyright 2011-2012 Calxeda, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Adapted from the highbank_mc_edac driver.
18 */
19
20#include <linux/ctype.h>
21#include <linux/edac.h>
22#include <linux/interrupt.h>
23#include <linux/kernel.h>
24#include <linux/mfd/syscon.h>
25#include <linux/of_platform.h>
26#include <linux/platform_device.h>
27#include <linux/regmap.h>
28#include <linux/types.h>
29#include <linux/uaccess.h>
30
31#include "edac_core.h"
32#include "edac_module.h"
33
34#define EDAC_MOD_STR "altera_edac"
35#define EDAC_VERSION "1"
36
37/* SDRAM Controller CtrlCfg Register */
38#define CTLCFG_OFST 0x00
39
40/* SDRAM Controller CtrlCfg Register Bit Masks */
41#define CTLCFG_ECC_EN 0x400
42#define CTLCFG_ECC_CORR_EN 0x800
43#define CTLCFG_GEN_SB_ERR 0x2000
44#define CTLCFG_GEN_DB_ERR 0x4000
45
46#define CTLCFG_ECC_AUTO_EN (CTLCFG_ECC_EN | \
47 CTLCFG_ECC_CORR_EN)
48
49/* SDRAM Controller Address Width Register */
50#define DRAMADDRW_OFST 0x2C
51
52/* SDRAM Controller Address Widths Field Register */
53#define DRAMADDRW_COLBIT_MASK 0x001F
54#define DRAMADDRW_COLBIT_SHIFT 0
55#define DRAMADDRW_ROWBIT_MASK 0x03E0
56#define DRAMADDRW_ROWBIT_SHIFT 5
57#define DRAMADDRW_BANKBIT_MASK 0x1C00
58#define DRAMADDRW_BANKBIT_SHIFT 10
59#define DRAMADDRW_CSBIT_MASK 0xE000
60#define DRAMADDRW_CSBIT_SHIFT 13
61
62/* SDRAM Controller Interface Data Width Register */
63#define DRAMIFWIDTH_OFST 0x30
64
65/* SDRAM Controller Interface Data Width Defines */
66#define DRAMIFWIDTH_16B_ECC 24
67#define DRAMIFWIDTH_32B_ECC 40
68
69/* SDRAM Controller DRAM Status Register */
70#define DRAMSTS_OFST 0x38
71
72/* SDRAM Controller DRAM Status Register Bit Masks */
73#define DRAMSTS_SBEERR 0x04
74#define DRAMSTS_DBEERR 0x08
75#define DRAMSTS_CORR_DROP 0x10
76
77/* SDRAM Controller DRAM IRQ Register */
78#define DRAMINTR_OFST 0x3C
79
80/* SDRAM Controller DRAM IRQ Register Bit Masks */
81#define DRAMINTR_INTREN 0x01
82#define DRAMINTR_SBEMASK 0x02
83#define DRAMINTR_DBEMASK 0x04
84#define DRAMINTR_CORRDROPMASK 0x08
85#define DRAMINTR_INTRCLR 0x10
86
87/* SDRAM Controller Single Bit Error Count Register */
88#define SBECOUNT_OFST 0x40
89
90/* SDRAM Controller Single Bit Error Count Register Bit Masks */
91#define SBECOUNT_MASK 0x0F
92
93/* SDRAM Controller Double Bit Error Count Register */
94#define DBECOUNT_OFST 0x44
95
96/* SDRAM Controller Double Bit Error Count Register Bit Masks */
97#define DBECOUNT_MASK 0x0F
98
99/* SDRAM Controller ECC Error Address Register */
100#define ERRADDR_OFST 0x48
101
102/* SDRAM Controller ECC Error Address Register Bit Masks */
103#define ERRADDR_MASK 0xFFFFFFFF
104
105/* Altera SDRAM Memory Controller data */
106struct altr_sdram_mc_data {
107 struct regmap *mc_vbase;
108};
109
110static irqreturn_t altr_sdram_mc_err_handler(int irq, void *dev_id)
111{
112 struct mem_ctl_info *mci = dev_id;
113 struct altr_sdram_mc_data *drvdata = mci->pvt_info;
114 u32 status, err_count, err_addr;
115
116 /* Error Address is shared by both SBE & DBE */
117 regmap_read(drvdata->mc_vbase, ERRADDR_OFST, &err_addr);
118
119 regmap_read(drvdata->mc_vbase, DRAMSTS_OFST, &status);
120
121 if (status & DRAMSTS_DBEERR) {
122 regmap_read(drvdata->mc_vbase, DBECOUNT_OFST, &err_count);
123 panic("\nEDAC: [%d Uncorrectable errors @ 0x%08X]\n",
124 err_count, err_addr);
125 }
126 if (status & DRAMSTS_SBEERR) {
127 regmap_read(drvdata->mc_vbase, SBECOUNT_OFST, &err_count);
128 edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, err_count,
129 err_addr >> PAGE_SHIFT,
130 err_addr & ~PAGE_MASK, 0,
131 0, 0, -1, mci->ctl_name, "");
132 }
133
134 regmap_write(drvdata->mc_vbase, DRAMINTR_OFST,
135 (DRAMINTR_INTRCLR | DRAMINTR_INTREN));
136
137 return IRQ_HANDLED;
138}
139
140#ifdef CONFIG_EDAC_DEBUG
141static ssize_t altr_sdr_mc_err_inject_write(struct file *file,
142 const char __user *data,
143 size_t count, loff_t *ppos)
144{
145 struct mem_ctl_info *mci = file->private_data;
146 struct altr_sdram_mc_data *drvdata = mci->pvt_info;
147 u32 *ptemp;
148 dma_addr_t dma_handle;
149 u32 reg, read_reg;
150
151 ptemp = dma_alloc_coherent(mci->pdev, 16, &dma_handle, GFP_KERNEL);
152 if (!ptemp) {
153 dma_free_coherent(mci->pdev, 16, ptemp, dma_handle);
154 edac_printk(KERN_ERR, EDAC_MC,
155 "Inject: Buffer Allocation error\n");
156 return -ENOMEM;
157 }
158
159 regmap_read(drvdata->mc_vbase, CTLCFG_OFST, &read_reg);
160 read_reg &= ~(CTLCFG_GEN_SB_ERR | CTLCFG_GEN_DB_ERR);
161
162 /* Error are injected by writing a word while the SBE or DBE
163 * bit in the CTLCFG register is set. Reading the word will
164 * trigger the SBE or DBE error and the corresponding IRQ.
165 */
166 if (count == 3) {
167 edac_printk(KERN_ALERT, EDAC_MC,
168 "Inject Double bit error\n");
169 regmap_write(drvdata->mc_vbase, CTLCFG_OFST,
170 (read_reg | CTLCFG_GEN_DB_ERR));
171 } else {
172 edac_printk(KERN_ALERT, EDAC_MC,
173 "Inject Single bit error\n");
174 regmap_write(drvdata->mc_vbase, CTLCFG_OFST,
175 (read_reg | CTLCFG_GEN_SB_ERR));
176 }
177
178 ptemp[0] = 0x5A5A5A5A;
179 ptemp[1] = 0xA5A5A5A5;
180
181 /* Clear the error injection bits */
182 regmap_write(drvdata->mc_vbase, CTLCFG_OFST, read_reg);
183 /* Ensure it has been written out */
184 wmb();
185
186 /*
187 * To trigger the error, we need to read the data back
188 * (the data was written with errors above).
189 * The ACCESS_ONCE macros and printk are used to prevent the
190 * the compiler optimizing these reads out.
191 */
192 reg = ACCESS_ONCE(ptemp[0]);
193 read_reg = ACCESS_ONCE(ptemp[1]);
194 /* Force Read */
195 rmb();
196
197 edac_printk(KERN_ALERT, EDAC_MC, "Read Data [0x%X, 0x%X]\n",
198 reg, read_reg);
199
200 dma_free_coherent(mci->pdev, 16, ptemp, dma_handle);
201
202 return count;
203}
204
205static const struct file_operations altr_sdr_mc_debug_inject_fops = {
206 .open = simple_open,
207 .write = altr_sdr_mc_err_inject_write,
208 .llseek = generic_file_llseek,
209};
210
211static void altr_sdr_mc_create_debugfs_nodes(struct mem_ctl_info *mci)
212{
213 if (mci->debugfs)
214 debugfs_create_file("inject_ctrl", S_IWUSR, mci->debugfs, mci,
215 &altr_sdr_mc_debug_inject_fops);
216}
217#else
218static void altr_sdr_mc_create_debugfs_nodes(struct mem_ctl_info *mci)
219{}
220#endif
221
222/* Get total memory size in bytes */
223static u32 altr_sdram_get_total_mem_size(struct regmap *mc_vbase)
224{
225 u32 size, read_reg, row, bank, col, cs, width;
226
227 if (regmap_read(mc_vbase, DRAMADDRW_OFST, &read_reg) < 0)
228 return 0;
229
230 if (regmap_read(mc_vbase, DRAMIFWIDTH_OFST, &width) < 0)
231 return 0;
232
233 col = (read_reg & DRAMADDRW_COLBIT_MASK) >>
234 DRAMADDRW_COLBIT_SHIFT;
235 row = (read_reg & DRAMADDRW_ROWBIT_MASK) >>
236 DRAMADDRW_ROWBIT_SHIFT;
237 bank = (read_reg & DRAMADDRW_BANKBIT_MASK) >>
238 DRAMADDRW_BANKBIT_SHIFT;
239 cs = (read_reg & DRAMADDRW_CSBIT_MASK) >>
240 DRAMADDRW_CSBIT_SHIFT;
241
242 /* Correct for ECC as its not addressible */
243 if (width == DRAMIFWIDTH_32B_ECC)
244 width = 32;
245 if (width == DRAMIFWIDTH_16B_ECC)
246 width = 16;
247
248 /* calculate the SDRAM size base on this info */
249 size = 1 << (row + bank + col);
250 size = size * cs * (width / 8);
251 return size;
252}
253
254static int altr_sdram_probe(struct platform_device *pdev)
255{
256 struct edac_mc_layer layers[2];
257 struct mem_ctl_info *mci;
258 struct altr_sdram_mc_data *drvdata;
259 struct regmap *mc_vbase;
260 struct dimm_info *dimm;
261 u32 read_reg, mem_size;
262 int irq;
263 int res = 0;
264
265 /* Validate the SDRAM controller has ECC enabled */
266 /* Grab the register range from the sdr controller in device tree */
267 mc_vbase = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
268 "altr,sdr-syscon");
269 if (IS_ERR(mc_vbase)) {
270 edac_printk(KERN_ERR, EDAC_MC,
271 "regmap for altr,sdr-syscon lookup failed.\n");
272 return -ENODEV;
273 }
274
275 if (regmap_read(mc_vbase, CTLCFG_OFST, &read_reg) ||
276 ((read_reg & CTLCFG_ECC_AUTO_EN) != CTLCFG_ECC_AUTO_EN)) {
277 edac_printk(KERN_ERR, EDAC_MC,
278 "No ECC/ECC disabled [0x%08X]\n", read_reg);
279 return -ENODEV;
280 }
281
282 /* Grab memory size from device tree. */
283 mem_size = altr_sdram_get_total_mem_size(mc_vbase);
284 if (!mem_size) {
285 edac_printk(KERN_ERR, EDAC_MC,
286 "Unable to calculate memory size\n");
287 return -ENODEV;
288 }
289
290 /* Ensure the SDRAM Interrupt is disabled and cleared */
291 if (regmap_write(mc_vbase, DRAMINTR_OFST, DRAMINTR_INTRCLR)) {
292 edac_printk(KERN_ERR, EDAC_MC,
293 "Error clearing SDRAM ECC IRQ\n");
294 return -ENODEV;
295 }
296
297 irq = platform_get_irq(pdev, 0);
298 if (irq < 0) {
299 edac_printk(KERN_ERR, EDAC_MC,
300 "No irq %d in DT\n", irq);
301 return -ENODEV;
302 }
303
304 layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
305 layers[0].size = 1;
306 layers[0].is_virt_csrow = true;
307 layers[1].type = EDAC_MC_LAYER_CHANNEL;
308 layers[1].size = 1;
309 layers[1].is_virt_csrow = false;
310 mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers,
311 sizeof(struct altr_sdram_mc_data));
312 if (!mci)
313 return -ENOMEM;
314
315 mci->pdev = &pdev->dev;
316 drvdata = mci->pvt_info;
317 drvdata->mc_vbase = mc_vbase;
318 platform_set_drvdata(pdev, mci);
319
320 if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL)) {
321 res = -ENOMEM;
322 goto free;
323 }
324
325 mci->mtype_cap = MEM_FLAG_DDR3;
326 mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED;
327 mci->edac_cap = EDAC_FLAG_SECDED;
328 mci->mod_name = EDAC_MOD_STR;
329 mci->mod_ver = EDAC_VERSION;
330 mci->ctl_name = dev_name(&pdev->dev);
331 mci->scrub_mode = SCRUB_SW_SRC;
332 mci->dev_name = dev_name(&pdev->dev);
333
334 dimm = *mci->dimms;
335 dimm->nr_pages = ((mem_size - 1) >> PAGE_SHIFT) + 1;
336 dimm->grain = 8;
337 dimm->dtype = DEV_X8;
338 dimm->mtype = MEM_DDR3;
339 dimm->edac_mode = EDAC_SECDED;
340
341 res = edac_mc_add_mc(mci);
342 if (res < 0)
343 goto err;
344
345 res = devm_request_irq(&pdev->dev, irq, altr_sdram_mc_err_handler,
346 0, dev_name(&pdev->dev), mci);
347 if (res < 0) {
348 edac_mc_printk(mci, KERN_ERR,
349 "Unable to request irq %d\n", irq);
350 res = -ENODEV;
351 goto err2;
352 }
353
354 if (regmap_write(drvdata->mc_vbase, DRAMINTR_OFST,
355 (DRAMINTR_INTRCLR | DRAMINTR_INTREN))) {
356 edac_mc_printk(mci, KERN_ERR,
357 "Error enabling SDRAM ECC IRQ\n");
358 res = -ENODEV;
359 goto err2;
360 }
361
362 altr_sdr_mc_create_debugfs_nodes(mci);
363
364 devres_close_group(&pdev->dev, NULL);
365
366 return 0;
367
368err2:
369 edac_mc_del_mc(&pdev->dev);
370err:
371 devres_release_group(&pdev->dev, NULL);
372free:
373 edac_mc_free(mci);
374 edac_printk(KERN_ERR, EDAC_MC,
375 "EDAC Probe Failed; Error %d\n", res);
376
377 return res;
378}
379
380static int altr_sdram_remove(struct platform_device *pdev)
381{
382 struct mem_ctl_info *mci = platform_get_drvdata(pdev);
383
384 edac_mc_del_mc(&pdev->dev);
385 edac_mc_free(mci);
386 platform_set_drvdata(pdev, NULL);
387
388 return 0;
389}
390
391static const struct of_device_id altr_sdram_ctrl_of_match[] = {
392 { .compatible = "altr,sdram-edac", },
393 {},
394};
395MODULE_DEVICE_TABLE(of, altr_sdram_ctrl_of_match);
396
397static struct platform_driver altr_sdram_edac_driver = {
398 .probe = altr_sdram_probe,
399 .remove = altr_sdram_remove,
400 .driver = {
401 .name = "altr_sdram_edac",
402 .of_match_table = altr_sdram_ctrl_of_match,
403 },
404};
405
406module_platform_driver(altr_sdram_edac_driver);
407
408MODULE_LICENSE("GPL v2");
409MODULE_AUTHOR("Thor Thayer");
410MODULE_DESCRIPTION("EDAC Driver for Altera SDRAM Controller");
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index a31a9e40eed9..78d4ff551590 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -75,6 +75,11 @@ config OR1K_PIC
75 bool 75 bool
76 select IRQ_DOMAIN 76 select IRQ_DOMAIN
77 77
78config OMAP_IRQCHIP
79 bool
80 select GENERIC_IRQ_CHIP
81 select IRQ_DOMAIN
82
78config ORION_IRQCHIP 83config ORION_IRQCHIP
79 bool 84 bool
80 select IRQ_DOMAIN 85 select IRQ_DOMAIN
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 73052ba9ca62..d0a2613c73bc 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_ARCH_MOXART) += irq-moxart.o
13obj-$(CONFIG_CLPS711X_IRQCHIP) += irq-clps711x.o 13obj-$(CONFIG_CLPS711X_IRQCHIP) += irq-clps711x.o
14obj-$(CONFIG_OR1K_PIC) += irq-or1k-pic.o 14obj-$(CONFIG_OR1K_PIC) += irq-or1k-pic.o
15obj-$(CONFIG_ORION_IRQCHIP) += irq-orion.o 15obj-$(CONFIG_ORION_IRQCHIP) += irq-orion.o
16obj-$(CONFIG_OMAP_IRQCHIP) += irq-omap-intc.o
16obj-$(CONFIG_ARCH_SUNXI) += irq-sun4i.o 17obj-$(CONFIG_ARCH_SUNXI) += irq-sun4i.o
17obj-$(CONFIG_ARCH_SUNXI) += irq-sunxi-nmi.o 18obj-$(CONFIG_ARCH_SUNXI) += irq-sunxi-nmi.o
18obj-$(CONFIG_ARCH_SPEAR3XX) += spear-shirq.o 19obj-$(CONFIG_ARCH_SPEAR3XX) += spear-shirq.o
diff --git a/drivers/irqchip/irq-omap-intc.c b/drivers/irqchip/irq-omap-intc.c
new file mode 100644
index 000000000000..f3814e79192d
--- /dev/null
+++ b/drivers/irqchip/irq-omap-intc.c
@@ -0,0 +1,403 @@
1/*
2 * linux/arch/arm/mach-omap2/irq.c
3 *
4 * Interrupt handler for OMAP2 boards.
5 *
6 * Copyright (C) 2005 Nokia Corporation
7 * Author: Paul Mundt <paul.mundt@nokia.com>
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/interrupt.h>
17#include <linux/io.h>
18
19#include <asm/exception.h>
20#include <linux/irqdomain.h>
21#include <linux/of.h>
22#include <linux/of_address.h>
23#include <linux/of_irq.h>
24
25#include "irqchip.h"
26
27/* Define these here for now until we drop all board-files */
28#define OMAP24XX_IC_BASE 0x480fe000
29#define OMAP34XX_IC_BASE 0x48200000
30
31/* selected INTC register offsets */
32
33#define INTC_REVISION 0x0000
34#define INTC_SYSCONFIG 0x0010
35#define INTC_SYSSTATUS 0x0014
36#define INTC_SIR 0x0040
37#define INTC_CONTROL 0x0048
38#define INTC_PROTECTION 0x004C
39#define INTC_IDLE 0x0050
40#define INTC_THRESHOLD 0x0068
41#define INTC_MIR0 0x0084
42#define INTC_MIR_CLEAR0 0x0088
43#define INTC_MIR_SET0 0x008c
44#define INTC_PENDING_IRQ0 0x0098
45#define INTC_PENDING_IRQ1 0x00b8
46#define INTC_PENDING_IRQ2 0x00d8
47#define INTC_PENDING_IRQ3 0x00f8
48#define INTC_ILR0 0x0100
49
50#define ACTIVEIRQ_MASK 0x7f /* omap2/3 active interrupt bits */
51#define INTCPS_NR_ILR_REGS 128
52#define INTCPS_NR_MIR_REGS 4
53
54#define INTC_IDLE_FUNCIDLE (1 << 0)
55#define INTC_IDLE_TURBO (1 << 1)
56
57#define INTC_PROTECTION_ENABLE (1 << 0)
58
59struct omap_intc_regs {
60 u32 sysconfig;
61 u32 protection;
62 u32 idle;
63 u32 threshold;
64 u32 ilr[INTCPS_NR_ILR_REGS];
65 u32 mir[INTCPS_NR_MIR_REGS];
66};
67static struct omap_intc_regs intc_context;
68
69static struct irq_domain *domain;
70static void __iomem *omap_irq_base;
71static int omap_nr_pending = 3;
72static int omap_nr_irqs = 96;
73
74static void intc_writel(u32 reg, u32 val)
75{
76 writel_relaxed(val, omap_irq_base + reg);
77}
78
79static u32 intc_readl(u32 reg)
80{
81 return readl_relaxed(omap_irq_base + reg);
82}
83
84void omap_intc_save_context(void)
85{
86 int i;
87
88 intc_context.sysconfig =
89 intc_readl(INTC_SYSCONFIG);
90 intc_context.protection =
91 intc_readl(INTC_PROTECTION);
92 intc_context.idle =
93 intc_readl(INTC_IDLE);
94 intc_context.threshold =
95 intc_readl(INTC_THRESHOLD);
96
97 for (i = 0; i < omap_nr_irqs; i++)
98 intc_context.ilr[i] =
99 intc_readl((INTC_ILR0 + 0x4 * i));
100 for (i = 0; i < INTCPS_NR_MIR_REGS; i++)
101 intc_context.mir[i] =
102 intc_readl(INTC_MIR0 + (0x20 * i));
103}
104
105void omap_intc_restore_context(void)
106{
107 int i;
108
109 intc_writel(INTC_SYSCONFIG, intc_context.sysconfig);
110 intc_writel(INTC_PROTECTION, intc_context.protection);
111 intc_writel(INTC_IDLE, intc_context.idle);
112 intc_writel(INTC_THRESHOLD, intc_context.threshold);
113
114 for (i = 0; i < omap_nr_irqs; i++)
115 intc_writel(INTC_ILR0 + 0x4 * i,
116 intc_context.ilr[i]);
117
118 for (i = 0; i < INTCPS_NR_MIR_REGS; i++)
119 intc_writel(INTC_MIR0 + 0x20 * i,
120 intc_context.mir[i]);
121 /* MIRs are saved and restore with other PRCM registers */
122}
123
124void omap3_intc_prepare_idle(void)
125{
126 /*
127 * Disable autoidle as it can stall interrupt controller,
128 * cf. errata ID i540 for 3430 (all revisions up to 3.1.x)
129 */
130 intc_writel(INTC_SYSCONFIG, 0);
131 intc_writel(INTC_IDLE, INTC_IDLE_TURBO);
132}
133
134void omap3_intc_resume_idle(void)
135{
136 /* Re-enable autoidle */
137 intc_writel(INTC_SYSCONFIG, 1);
138 intc_writel(INTC_IDLE, 0);
139}
140
141/* XXX: FIQ and additional INTC support (only MPU at the moment) */
142static void omap_ack_irq(struct irq_data *d)
143{
144 intc_writel(INTC_CONTROL, 0x1);
145}
146
147static void omap_mask_ack_irq(struct irq_data *d)
148{
149 irq_gc_mask_disable_reg(d);
150 omap_ack_irq(d);
151}
152
153static void __init omap_irq_soft_reset(void)
154{
155 unsigned long tmp;
156
157 tmp = intc_readl(INTC_REVISION) & 0xff;
158
159 pr_info("IRQ: Found an INTC at 0x%p (revision %ld.%ld) with %d interrupts\n",
160 omap_irq_base, tmp >> 4, tmp & 0xf, omap_nr_irqs);
161
162 tmp = intc_readl(INTC_SYSCONFIG);
163 tmp |= 1 << 1; /* soft reset */
164 intc_writel(INTC_SYSCONFIG, tmp);
165
166 while (!(intc_readl(INTC_SYSSTATUS) & 0x1))
167 /* Wait for reset to complete */;
168
169 /* Enable autoidle */
170 intc_writel(INTC_SYSCONFIG, 1 << 0);
171}
172
173int omap_irq_pending(void)
174{
175 int i;
176
177 for (i = 0; i < omap_nr_pending; i++)
178 if (intc_readl(INTC_PENDING_IRQ0 + (0x20 * i)))
179 return 1;
180 return 0;
181}
182
183void omap3_intc_suspend(void)
184{
185 /* A pending interrupt would prevent OMAP from entering suspend */
186 omap_ack_irq(NULL);
187}
188
189static int __init omap_alloc_gc_of(struct irq_domain *d, void __iomem *base)
190{
191 int ret;
192 int i;
193
194 ret = irq_alloc_domain_generic_chips(d, 32, 1, "INTC",
195 handle_level_irq, IRQ_NOREQUEST | IRQ_NOPROBE,
196 IRQ_LEVEL, 0);
197 if (ret) {
198 pr_warn("Failed to allocate irq chips\n");
199 return ret;
200 }
201
202 for (i = 0; i < omap_nr_pending; i++) {
203 struct irq_chip_generic *gc;
204 struct irq_chip_type *ct;
205
206 gc = irq_get_domain_generic_chip(d, 32 * i);
207 gc->reg_base = base;
208 ct = gc->chip_types;
209
210 ct->type = IRQ_TYPE_LEVEL_MASK;
211 ct->handler = handle_level_irq;
212
213 ct->chip.irq_ack = omap_mask_ack_irq;
214 ct->chip.irq_mask = irq_gc_mask_disable_reg;
215 ct->chip.irq_unmask = irq_gc_unmask_enable_reg;
216
217 ct->chip.flags |= IRQCHIP_SKIP_SET_WAKE;
218
219 ct->regs.enable = INTC_MIR_CLEAR0 + 32 * i;
220 ct->regs.disable = INTC_MIR_SET0 + 32 * i;
221 }
222
223 return 0;
224}
225
226static void __init omap_alloc_gc_legacy(void __iomem *base,
227 unsigned int irq_start, unsigned int num)
228{
229 struct irq_chip_generic *gc;
230 struct irq_chip_type *ct;
231
232 gc = irq_alloc_generic_chip("INTC", 1, irq_start, base,
233 handle_level_irq);
234 ct = gc->chip_types;
235 ct->chip.irq_ack = omap_mask_ack_irq;
236 ct->chip.irq_mask = irq_gc_mask_disable_reg;
237 ct->chip.irq_unmask = irq_gc_unmask_enable_reg;
238 ct->chip.flags |= IRQCHIP_SKIP_SET_WAKE;
239
240 ct->regs.enable = INTC_MIR_CLEAR0;
241 ct->regs.disable = INTC_MIR_SET0;
242 irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE,
243 IRQ_NOREQUEST | IRQ_NOPROBE, 0);
244}
245
246static int __init omap_init_irq_of(struct device_node *node)
247{
248 int ret;
249
250 omap_irq_base = of_iomap(node, 0);
251 if (WARN_ON(!omap_irq_base))
252 return -ENOMEM;
253
254 domain = irq_domain_add_linear(node, omap_nr_irqs,
255 &irq_generic_chip_ops, NULL);
256
257 omap_irq_soft_reset();
258
259 ret = omap_alloc_gc_of(domain, omap_irq_base);
260 if (ret < 0)
261 irq_domain_remove(domain);
262
263 return ret;
264}
265
266static int __init omap_init_irq_legacy(u32 base)
267{
268 int j, irq_base;
269
270 omap_irq_base = ioremap(base, SZ_4K);
271 if (WARN_ON(!omap_irq_base))
272 return -ENOMEM;
273
274 irq_base = irq_alloc_descs(-1, 0, omap_nr_irqs, 0);
275 if (irq_base < 0) {
276 pr_warn("Couldn't allocate IRQ numbers\n");
277 irq_base = 0;
278 }
279
280 domain = irq_domain_add_legacy(NULL, omap_nr_irqs, irq_base, 0,
281 &irq_domain_simple_ops, NULL);
282
283 omap_irq_soft_reset();
284
285 for (j = 0; j < omap_nr_irqs; j += 32)
286 omap_alloc_gc_legacy(omap_irq_base + j, j + irq_base, 32);
287
288 return 0;
289}
290
291static void __init omap_irq_enable_protection(void)
292{
293 u32 reg;
294
295 reg = intc_readl(INTC_PROTECTION);
296 reg |= INTC_PROTECTION_ENABLE;
297 intc_writel(INTC_PROTECTION, reg);
298}
299
300static int __init omap_init_irq(u32 base, struct device_node *node)
301{
302 int ret;
303
304 if (node)
305 ret = omap_init_irq_of(node);
306 else
307 ret = omap_init_irq_legacy(base);
308
309 if (ret == 0)
310 omap_irq_enable_protection();
311
312 return ret;
313}
314
315static asmlinkage void __exception_irq_entry
316omap_intc_handle_irq(struct pt_regs *regs)
317{
318 u32 irqnr = 0;
319 int handled_irq = 0;
320 int i;
321
322 do {
323 for (i = 0; i < omap_nr_pending; i++) {
324 irqnr = intc_readl(INTC_PENDING_IRQ0 + (0x20 * i));
325 if (irqnr)
326 goto out;
327 }
328
329out:
330 if (!irqnr)
331 break;
332
333 irqnr = intc_readl(INTC_SIR);
334 irqnr &= ACTIVEIRQ_MASK;
335
336 if (irqnr) {
337 irqnr = irq_find_mapping(domain, irqnr);
338 handle_IRQ(irqnr, regs);
339 handled_irq = 1;
340 }
341 } while (irqnr);
342
343 /*
344 * If an irq is masked or deasserted while active, we will
345 * keep ending up here with no irq handled. So remove it from
346 * the INTC with an ack.
347 */
348 if (!handled_irq)
349 omap_ack_irq(NULL);
350}
351
352void __init omap2_init_irq(void)
353{
354 omap_nr_irqs = 96;
355 omap_nr_pending = 3;
356 omap_init_irq(OMAP24XX_IC_BASE, NULL);
357 set_handle_irq(omap_intc_handle_irq);
358}
359
360void __init omap3_init_irq(void)
361{
362 omap_nr_irqs = 96;
363 omap_nr_pending = 3;
364 omap_init_irq(OMAP34XX_IC_BASE, NULL);
365 set_handle_irq(omap_intc_handle_irq);
366}
367
368void __init ti81xx_init_irq(void)
369{
370 omap_nr_irqs = 96;
371 omap_nr_pending = 4;
372 omap_init_irq(OMAP34XX_IC_BASE, NULL);
373 set_handle_irq(omap_intc_handle_irq);
374}
375
376static int __init intc_of_init(struct device_node *node,
377 struct device_node *parent)
378{
379 int ret;
380
381 omap_nr_pending = 3;
382 omap_nr_irqs = 96;
383
384 if (WARN_ON(!node))
385 return -ENODEV;
386
387 if (of_device_is_compatible(node, "ti,am33xx-intc")) {
388 omap_nr_irqs = 128;
389 omap_nr_pending = 4;
390 }
391
392 ret = omap_init_irq(-1, of_node_get(node));
393 if (ret < 0)
394 return ret;
395
396 set_handle_irq(omap_intc_handle_irq);
397
398 return 0;
399}
400
401IRQCHIP_DECLARE(omap2_intc, "ti,omap2-intc", intc_of_init);
402IRQCHIP_DECLARE(omap3_intc, "ti,omap3-intc", intc_of_init);
403IRQCHIP_DECLARE(am33xx_intc, "ti,am33xx-intc", intc_of_init);
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index f6ef7bb2dc11..90e108f9e22e 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -478,6 +478,16 @@ config LEDS_BLINKM
478 This option enables support for the BlinkM RGB LED connected 478 This option enables support for the BlinkM RGB LED connected
479 through I2C. Say Y to enable support for the BlinkM LED. 479 through I2C. Say Y to enable support for the BlinkM LED.
480 480
481config LEDS_SYSCON
482 bool "LED support for LEDs on system controllers"
483 depends on LEDS_CLASS=y
484 depends on MFD_SYSCON
485 depends on OF
486 help
487 This option enabled support for the LEDs on syscon type
488 devices. This will only work with device tree enabled
489 devices.
490
481config LEDS_VERSATILE 491config LEDS_VERSATILE
482 tristate "LED support for the ARM Versatile and RealView" 492 tristate "LED support for the ARM Versatile and RealView"
483 depends on ARCH_REALVIEW || ARCH_VERSATILE 493 depends on ARCH_REALVIEW || ARCH_VERSATILE
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index d8cc5f2777de..822dd83ef97a 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -53,6 +53,7 @@ obj-$(CONFIG_LEDS_ASIC3) += leds-asic3.o
53obj-$(CONFIG_LEDS_MAX8997) += leds-max8997.o 53obj-$(CONFIG_LEDS_MAX8997) += leds-max8997.o
54obj-$(CONFIG_LEDS_LM355x) += leds-lm355x.o 54obj-$(CONFIG_LEDS_LM355x) += leds-lm355x.o
55obj-$(CONFIG_LEDS_BLINKM) += leds-blinkm.o 55obj-$(CONFIG_LEDS_BLINKM) += leds-blinkm.o
56obj-$(CONFIG_LEDS_SYSCON) += leds-syscon.o
56obj-$(CONFIG_LEDS_VERSATILE) += leds-versatile.o 57obj-$(CONFIG_LEDS_VERSATILE) += leds-versatile.o
57 58
58# LED SPI Drivers 59# LED SPI Drivers
diff --git a/drivers/leds/leds-syscon.c b/drivers/leds/leds-syscon.c
new file mode 100644
index 000000000000..3afec79c43f4
--- /dev/null
+++ b/drivers/leds/leds-syscon.c
@@ -0,0 +1,166 @@
1/*
2 * Generic Syscon LEDs Driver
3 *
4 * Copyright (c) 2014, Linaro Limited
5 * Author: Linus Walleij <linus.walleij@linaro.org>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 * MA 02111-1307 USA
21 *
22 * This driver provides system reboot functionality for APM X-Gene SoC.
23 * For system shutdown, this is board specify. If a board designer
24 * implements GPIO shutdown, use the gpio-poweroff.c driver.
25 */
26#include <linux/io.h>
27#include <linux/of_device.h>
28#include <linux/of_address.h>
29#include <linux/platform_device.h>
30#include <linux/stat.h>
31#include <linux/slab.h>
32#include <linux/mfd/syscon.h>
33#include <linux/regmap.h>
34#include <linux/leds.h>
35
36/**
37 * struct syscon_led - state container for syscon based LEDs
38 * @cdev: LED class device for this LED
39 * @map: regmap to access the syscon device backing this LED
40 * @offset: the offset into the syscon regmap for the LED register
41 * @mask: the bit in the register corresponding to the LED
42 * @state: current state of the LED
43 */
44struct syscon_led {
45 struct led_classdev cdev;
46 struct regmap *map;
47 u32 offset;
48 u32 mask;
49 bool state;
50};
51
52static void syscon_led_set(struct led_classdev *led_cdev,
53 enum led_brightness value)
54{
55 struct syscon_led *sled =
56 container_of(led_cdev, struct syscon_led, cdev);
57 u32 val;
58 int ret;
59
60 if (value == LED_OFF) {
61 val = 0;
62 sled->state = false;
63 } else {
64 val = sled->mask;
65 sled->state = true;
66 }
67
68 ret = regmap_update_bits(sled->map, sled->offset, sled->mask, val);
69 if (ret < 0)
70 dev_err(sled->cdev.dev, "error updating LED status\n");
71}
72
73static const struct of_device_id syscon_match[] = {
74 { .compatible = "syscon", },
75 {},
76};
77
78static int __init syscon_leds_init(void)
79{
80 const struct of_device_id *devid;
81 struct device_node *np;
82 struct device_node *child;
83 struct regmap *map;
84 struct platform_device *pdev;
85 struct device *dev;
86 int ret;
87
88 np = of_find_matching_node_and_match(NULL, syscon_match,
89 &devid);
90 if (!np)
91 return -ENODEV;
92
93 map = syscon_node_to_regmap(np);
94 if (IS_ERR(map))
95 return PTR_ERR(map);
96
97 /*
98 * If the map is there, the device should be there, we allocate
99 * memory on the syscon device's behalf here.
100 */
101 pdev = of_find_device_by_node(np);
102 if (!pdev)
103 return -ENODEV;
104 dev = &pdev->dev;
105
106 for_each_available_child_of_node(np, child) {
107 struct syscon_led *sled;
108 const char *state;
109
110 /* Only check for register-bit-leds */
111 if (of_property_match_string(child, "compatible",
112 "register-bit-led") < 0)
113 continue;
114
115 sled = devm_kzalloc(dev, sizeof(*sled), GFP_KERNEL);
116 if (!sled)
117 return -ENOMEM;
118
119 sled->map = map;
120
121 if (of_property_read_u32(child, "offset", &sled->offset))
122 return -EINVAL;
123 if (of_property_read_u32(child, "mask", &sled->mask))
124 return -EINVAL;
125 sled->cdev.name =
126 of_get_property(child, "label", NULL) ? : child->name;
127 sled->cdev.default_trigger =
128 of_get_property(child, "linux,default-trigger", NULL);
129
130 state = of_get_property(child, "default-state", NULL);
131 if (state) {
132 if (!strcmp(state, "keep")) {
133 u32 val;
134
135 ret = regmap_read(map, sled->offset, &val);
136 if (ret < 0)
137 return ret;
138 sled->state = !!(val & sled->mask);
139 } else if (!strcmp(state, "on")) {
140 sled->state = true;
141 ret = regmap_update_bits(map, sled->offset,
142 sled->mask,
143 sled->mask);
144 if (ret < 0)
145 return ret;
146 } else {
147 sled->state = false;
148 ret = regmap_update_bits(map, sled->offset,
149 sled->mask, 0);
150 if (ret < 0)
151 return ret;
152 }
153
154 }
155 sled->cdev.brightness_set = syscon_led_set;
156
157 ret = led_classdev_register(dev, &sled->cdev);
158 if (ret < 0)
159 return ret;
160
161 dev_info(dev, "registered LED %s\n", sled->cdev.name);
162 }
163
164 return 0;
165}
166device_initcall(syscon_leds_init);
diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index a27e00e63a8a..bcc7ee129276 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -31,6 +31,7 @@
31#include <linux/err.h> 31#include <linux/err.h>
32#include <linux/notifier.h> 32#include <linux/notifier.h>
33#include <linux/module.h> 33#include <linux/module.h>
34#include <linux/of_device.h>
34#include <linux/platform_device.h> 35#include <linux/platform_device.h>
35#include <linux/pm_runtime.h> 36#include <linux/pm_runtime.h>
36#include <linux/platform_data/mailbox-omap.h> 37#include <linux/platform_data/mailbox-omap.h>
@@ -94,6 +95,18 @@ struct omap_mbox_device {
94 struct list_head elem; 95 struct list_head elem;
95}; 96};
96 97
98struct omap_mbox_fifo_info {
99 int tx_id;
100 int tx_usr;
101 int tx_irq;
102
103 int rx_id;
104 int rx_usr;
105 int rx_irq;
106
107 const char *name;
108};
109
97struct omap_mbox { 110struct omap_mbox {
98 const char *name; 111 const char *name;
99 int irq; 112 int irq;
@@ -587,24 +600,118 @@ static int omap_mbox_unregister(struct omap_mbox_device *mdev)
587 return 0; 600 return 0;
588} 601}
589 602
603static const struct of_device_id omap_mailbox_of_match[] = {
604 {
605 .compatible = "ti,omap2-mailbox",
606 .data = (void *)MBOX_INTR_CFG_TYPE1,
607 },
608 {
609 .compatible = "ti,omap3-mailbox",
610 .data = (void *)MBOX_INTR_CFG_TYPE1,
611 },
612 {
613 .compatible = "ti,omap4-mailbox",
614 .data = (void *)MBOX_INTR_CFG_TYPE2,
615 },
616 {
617 /* end */
618 },
619};
620MODULE_DEVICE_TABLE(of, omap_mailbox_of_match);
621
590static int omap_mbox_probe(struct platform_device *pdev) 622static int omap_mbox_probe(struct platform_device *pdev)
591{ 623{
592 struct resource *mem; 624 struct resource *mem;
593 int ret; 625 int ret;
594 struct omap_mbox **list, *mbox, *mboxblk; 626 struct omap_mbox **list, *mbox, *mboxblk;
595 struct omap_mbox_pdata *pdata = pdev->dev.platform_data; 627 struct omap_mbox_pdata *pdata = pdev->dev.platform_data;
596 struct omap_mbox_dev_info *info; 628 struct omap_mbox_dev_info *info = NULL;
629 struct omap_mbox_fifo_info *finfo, *finfoblk;
597 struct omap_mbox_device *mdev; 630 struct omap_mbox_device *mdev;
598 struct omap_mbox_fifo *fifo; 631 struct omap_mbox_fifo *fifo;
599 u32 intr_type; 632 struct device_node *node = pdev->dev.of_node;
633 struct device_node *child;
634 const struct of_device_id *match;
635 u32 intr_type, info_count;
636 u32 num_users, num_fifos;
637 u32 tmp[3];
600 u32 l; 638 u32 l;
601 int i; 639 int i;
602 640
603 if (!pdata || !pdata->info_cnt || !pdata->info) { 641 if (!node && (!pdata || !pdata->info_cnt || !pdata->info)) {
604 pr_err("%s: platform not supported\n", __func__); 642 pr_err("%s: platform not supported\n", __func__);
605 return -ENODEV; 643 return -ENODEV;
606 } 644 }
607 645
646 if (node) {
647 match = of_match_device(omap_mailbox_of_match, &pdev->dev);
648 if (!match)
649 return -ENODEV;
650 intr_type = (u32)match->data;
651
652 if (of_property_read_u32(node, "ti,mbox-num-users",
653 &num_users))
654 return -ENODEV;
655
656 if (of_property_read_u32(node, "ti,mbox-num-fifos",
657 &num_fifos))
658 return -ENODEV;
659
660 info_count = of_get_available_child_count(node);
661 if (!info_count) {
662 dev_err(&pdev->dev, "no available mbox devices found\n");
663 return -ENODEV;
664 }
665 } else { /* non-DT device creation */
666 info_count = pdata->info_cnt;
667 info = pdata->info;
668 intr_type = pdata->intr_type;
669 num_users = pdata->num_users;
670 num_fifos = pdata->num_fifos;
671 }
672
673 finfoblk = devm_kzalloc(&pdev->dev, info_count * sizeof(*finfoblk),
674 GFP_KERNEL);
675 if (!finfoblk)
676 return -ENOMEM;
677
678 finfo = finfoblk;
679 child = NULL;
680 for (i = 0; i < info_count; i++, finfo++) {
681 if (node) {
682 child = of_get_next_available_child(node, child);
683 ret = of_property_read_u32_array(child, "ti,mbox-tx",
684 tmp, ARRAY_SIZE(tmp));
685 if (ret)
686 return ret;
687 finfo->tx_id = tmp[0];
688 finfo->tx_irq = tmp[1];
689 finfo->tx_usr = tmp[2];
690
691 ret = of_property_read_u32_array(child, "ti,mbox-rx",
692 tmp, ARRAY_SIZE(tmp));
693 if (ret)
694 return ret;
695 finfo->rx_id = tmp[0];
696 finfo->rx_irq = tmp[1];
697 finfo->rx_usr = tmp[2];
698
699 finfo->name = child->name;
700 } else {
701 finfo->tx_id = info->tx_id;
702 finfo->rx_id = info->rx_id;
703 finfo->tx_usr = info->usr_id;
704 finfo->tx_irq = info->irq_id;
705 finfo->rx_usr = info->usr_id;
706 finfo->rx_irq = info->irq_id;
707 finfo->name = info->name;
708 info++;
709 }
710 if (finfo->tx_id >= num_fifos || finfo->rx_id >= num_fifos ||
711 finfo->tx_usr >= num_users || finfo->rx_usr >= num_users)
712 return -EINVAL;
713 }
714
608 mdev = devm_kzalloc(&pdev->dev, sizeof(*mdev), GFP_KERNEL); 715 mdev = devm_kzalloc(&pdev->dev, sizeof(*mdev), GFP_KERNEL);
609 if (!mdev) 716 if (!mdev)
610 return -ENOMEM; 717 return -ENOMEM;
@@ -615,41 +722,40 @@ static int omap_mbox_probe(struct platform_device *pdev)
615 return PTR_ERR(mdev->mbox_base); 722 return PTR_ERR(mdev->mbox_base);
616 723
617 /* allocate one extra for marking end of list */ 724 /* allocate one extra for marking end of list */
618 list = devm_kzalloc(&pdev->dev, (pdata->info_cnt + 1) * sizeof(*list), 725 list = devm_kzalloc(&pdev->dev, (info_count + 1) * sizeof(*list),
619 GFP_KERNEL); 726 GFP_KERNEL);
620 if (!list) 727 if (!list)
621 return -ENOMEM; 728 return -ENOMEM;
622 729
623 mboxblk = devm_kzalloc(&pdev->dev, pdata->info_cnt * sizeof(*mbox), 730 mboxblk = devm_kzalloc(&pdev->dev, info_count * sizeof(*mbox),
624 GFP_KERNEL); 731 GFP_KERNEL);
625 if (!mboxblk) 732 if (!mboxblk)
626 return -ENOMEM; 733 return -ENOMEM;
627 734
628 info = pdata->info;
629 intr_type = pdata->intr_type;
630 mbox = mboxblk; 735 mbox = mboxblk;
631 for (i = 0; i < pdata->info_cnt; i++, info++) { 736 finfo = finfoblk;
737 for (i = 0; i < info_count; i++, finfo++) {
632 fifo = &mbox->tx_fifo; 738 fifo = &mbox->tx_fifo;
633 fifo->msg = MAILBOX_MESSAGE(info->tx_id); 739 fifo->msg = MAILBOX_MESSAGE(finfo->tx_id);
634 fifo->fifo_stat = MAILBOX_FIFOSTATUS(info->tx_id); 740 fifo->fifo_stat = MAILBOX_FIFOSTATUS(finfo->tx_id);
635 fifo->intr_bit = MAILBOX_IRQ_NOTFULL(info->tx_id); 741 fifo->intr_bit = MAILBOX_IRQ_NOTFULL(finfo->tx_id);
636 fifo->irqenable = MAILBOX_IRQENABLE(intr_type, info->usr_id); 742 fifo->irqenable = MAILBOX_IRQENABLE(intr_type, finfo->tx_usr);
637 fifo->irqstatus = MAILBOX_IRQSTATUS(intr_type, info->usr_id); 743 fifo->irqstatus = MAILBOX_IRQSTATUS(intr_type, finfo->tx_usr);
638 fifo->irqdisable = MAILBOX_IRQDISABLE(intr_type, info->usr_id); 744 fifo->irqdisable = MAILBOX_IRQDISABLE(intr_type, finfo->tx_usr);
639 745
640 fifo = &mbox->rx_fifo; 746 fifo = &mbox->rx_fifo;
641 fifo->msg = MAILBOX_MESSAGE(info->rx_id); 747 fifo->msg = MAILBOX_MESSAGE(finfo->rx_id);
642 fifo->msg_stat = MAILBOX_MSGSTATUS(info->rx_id); 748 fifo->msg_stat = MAILBOX_MSGSTATUS(finfo->rx_id);
643 fifo->intr_bit = MAILBOX_IRQ_NEWMSG(info->rx_id); 749 fifo->intr_bit = MAILBOX_IRQ_NEWMSG(finfo->rx_id);
644 fifo->irqenable = MAILBOX_IRQENABLE(intr_type, info->usr_id); 750 fifo->irqenable = MAILBOX_IRQENABLE(intr_type, finfo->rx_usr);
645 fifo->irqstatus = MAILBOX_IRQSTATUS(intr_type, info->usr_id); 751 fifo->irqstatus = MAILBOX_IRQSTATUS(intr_type, finfo->rx_usr);
646 fifo->irqdisable = MAILBOX_IRQDISABLE(intr_type, info->usr_id); 752 fifo->irqdisable = MAILBOX_IRQDISABLE(intr_type, finfo->rx_usr);
647 753
648 mbox->intr_type = intr_type; 754 mbox->intr_type = intr_type;
649 755
650 mbox->parent = mdev; 756 mbox->parent = mdev;
651 mbox->name = info->name; 757 mbox->name = finfo->name;
652 mbox->irq = platform_get_irq(pdev, info->irq_id); 758 mbox->irq = platform_get_irq(pdev, finfo->tx_irq);
653 if (mbox->irq < 0) 759 if (mbox->irq < 0)
654 return mbox->irq; 760 return mbox->irq;
655 list[i] = mbox++; 761 list[i] = mbox++;
@@ -657,8 +763,8 @@ static int omap_mbox_probe(struct platform_device *pdev)
657 763
658 mutex_init(&mdev->cfg_lock); 764 mutex_init(&mdev->cfg_lock);
659 mdev->dev = &pdev->dev; 765 mdev->dev = &pdev->dev;
660 mdev->num_users = pdata->num_users; 766 mdev->num_users = num_users;
661 mdev->num_fifos = pdata->num_fifos; 767 mdev->num_fifos = num_fifos;
662 mdev->mboxes = list; 768 mdev->mboxes = list;
663 ret = omap_mbox_register(mdev); 769 ret = omap_mbox_register(mdev);
664 if (ret) 770 if (ret)
@@ -684,6 +790,7 @@ static int omap_mbox_probe(struct platform_device *pdev)
684 if (ret < 0) 790 if (ret < 0)
685 goto unregister; 791 goto unregister;
686 792
793 devm_kfree(&pdev->dev, finfoblk);
687 return 0; 794 return 0;
688 795
689unregister: 796unregister:
@@ -708,6 +815,7 @@ static struct platform_driver omap_mbox_driver = {
708 .driver = { 815 .driver = {
709 .name = "omap-mailbox", 816 .name = "omap-mailbox",
710 .owner = THIS_MODULE, 817 .owner = THIS_MODULE,
818 .of_match_table = of_match_ptr(omap_mailbox_of_match),
711 }, 819 },
712}; 820};
713 821
diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
index fab81a143bd7..6d91c27fd4c8 100644
--- a/drivers/memory/Kconfig
+++ b/drivers/memory/Kconfig
@@ -7,6 +7,16 @@ menuconfig MEMORY
7 7
8if MEMORY 8if MEMORY
9 9
10config ATMEL_SDRAMC
11 bool "Atmel (Multi-port DDR-)SDRAM Controller"
12 default y
13 depends on ARCH_AT91 && OF
14 help
15 This driver is for Atmel SDRAM Controller or Atmel Multi-port
16 DDR-SDRAM Controller available on Atmel AT91SAM9 and SAMA5 SoCs.
17 Starting with the at91sam9g45, this controller supports SDR, DDR and
18 LP-DDR memories.
19
10config TI_AEMIF 20config TI_AEMIF
11 tristate "Texas Instruments AEMIF driver" 21 tristate "Texas Instruments AEMIF driver"
12 depends on (ARCH_DAVINCI || ARCH_KEYSTONE) && OF 22 depends on (ARCH_DAVINCI || ARCH_KEYSTONE) && OF
diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile
index 4055c47f45ab..c32d31981be3 100644
--- a/drivers/memory/Makefile
+++ b/drivers/memory/Makefile
@@ -5,6 +5,7 @@
5ifeq ($(CONFIG_DDR),y) 5ifeq ($(CONFIG_DDR),y)
6obj-$(CONFIG_OF) += of_memory.o 6obj-$(CONFIG_OF) += of_memory.o
7endif 7endif
8obj-$(CONFIG_ATMEL_SDRAMC) += atmel-sdramc.o
8obj-$(CONFIG_TI_AEMIF) += ti-aemif.o 9obj-$(CONFIG_TI_AEMIF) += ti-aemif.o
9obj-$(CONFIG_TI_EMIF) += emif.o 10obj-$(CONFIG_TI_EMIF) += emif.o
10obj-$(CONFIG_FSL_CORENET_CF) += fsl-corenet-cf.o 11obj-$(CONFIG_FSL_CORENET_CF) += fsl-corenet-cf.o
diff --git a/drivers/memory/atmel-sdramc.c b/drivers/memory/atmel-sdramc.c
new file mode 100644
index 000000000000..fed04e8efe75
--- /dev/null
+++ b/drivers/memory/atmel-sdramc.c
@@ -0,0 +1,98 @@
1/*
2 * Atmel (Multi-port DDR-)SDRAM Controller driver
3 *
4 * Copyright (C) 2014 Atmel
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 */
19
20#include <linux/clk.h>
21#include <linux/err.h>
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/of_platform.h>
25#include <linux/platform_device.h>
26
27struct at91_ramc_caps {
28 bool has_ddrck;
29 bool has_mpddr_clk;
30};
31
32static const struct at91_ramc_caps at91rm9200_caps = { };
33
34static const struct at91_ramc_caps at91sam9g45_caps = {
35 .has_ddrck = 1,
36 .has_mpddr_clk = 0,
37};
38
39static const struct at91_ramc_caps sama5d3_caps = {
40 .has_ddrck = 1,
41 .has_mpddr_clk = 1,
42};
43
44static const struct of_device_id atmel_ramc_of_match[] = {
45 { .compatible = "atmel,at91rm9200-sdramc", .data = &at91rm9200_caps, },
46 { .compatible = "atmel,at91sam9260-sdramc", .data = &at91rm9200_caps, },
47 { .compatible = "atmel,at91sam9g45-ddramc", .data = &at91sam9g45_caps, },
48 { .compatible = "atmel,sama5d3-ddramc", .data = &sama5d3_caps, },
49 {},
50};
51MODULE_DEVICE_TABLE(of, atmel_ramc_of_match);
52
53static int atmel_ramc_probe(struct platform_device *pdev)
54{
55 const struct of_device_id *match;
56 const struct at91_ramc_caps *caps;
57 struct clk *clk;
58
59 match = of_match_device(atmel_ramc_of_match, &pdev->dev);
60 caps = match->data;
61
62 if (caps->has_ddrck) {
63 clk = devm_clk_get(&pdev->dev, "ddrck");
64 if (IS_ERR(clk))
65 return PTR_ERR(clk);
66 clk_prepare_enable(clk);
67 }
68
69 if (caps->has_mpddr_clk) {
70 clk = devm_clk_get(&pdev->dev, "mpddr");
71 if (IS_ERR(clk)) {
72 pr_err("AT91 RAMC: couldn't get mpddr clock\n");
73 return PTR_ERR(clk);
74 }
75 clk_prepare_enable(clk);
76 }
77
78 return 0;
79}
80
81static struct platform_driver atmel_ramc_driver = {
82 .probe = atmel_ramc_probe,
83 .driver = {
84 .name = "atmel-ramc",
85 .owner = THIS_MODULE,
86 .of_match_table = atmel_ramc_of_match,
87 },
88};
89
90static int __init atmel_ramc_init(void)
91{
92 return platform_driver_register(&atmel_ramc_driver);
93}
94module_init(atmel_ramc_init);
95
96MODULE_LICENSE("GPL v2");
97MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@free-electrons.com>");
98MODULE_DESCRIPTION("Atmel (Multi-port DDR-)SDRAM Controller");
diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index ca41523bbebf..527a0f47ef44 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -6,15 +6,33 @@ menuconfig POWER_RESET
6 6
7 Say Y here to enable board reset and power off 7 Say Y here to enable board reset and power off
8 8
9if POWER_RESET
10
9config POWER_RESET_AS3722 11config POWER_RESET_AS3722
10 bool "ams AS3722 power-off driver" 12 bool "ams AS3722 power-off driver"
11 depends on MFD_AS3722 && POWER_RESET 13 depends on MFD_AS3722
12 help 14 help
13 This driver supports turning off board via a ams AS3722 power-off. 15 This driver supports turning off board via a ams AS3722 power-off.
14 16
17config POWER_RESET_AT91_POWEROFF
18 bool "Atmel AT91 poweroff driver"
19 depends on ARCH_AT91
20 default SOC_AT91SAM9 || SOC_SAMA5
21 help
22 This driver supports poweroff for Atmel AT91SAM9 and SAMA5
23 SoCs
24
25config POWER_RESET_AT91_RESET
26 bool "Atmel AT91 reset driver"
27 depends on ARCH_AT91
28 default SOC_AT91SAM9 || SOC_SAMA5
29 help
30 This driver supports restart for Atmel AT91SAM9 and SAMA5
31 SoCs
32
15config POWER_RESET_AXXIA 33config POWER_RESET_AXXIA
16 bool "LSI Axxia reset driver" 34 bool "LSI Axxia reset driver"
17 depends on POWER_RESET && ARCH_AXXIA 35 depends on ARCH_AXXIA
18 help 36 help
19 This driver supports restart for Axxia SoC. 37 This driver supports restart for Axxia SoC.
20 38
@@ -33,7 +51,7 @@ config POWER_RESET_BRCMSTB
33 51
34config POWER_RESET_GPIO 52config POWER_RESET_GPIO
35 bool "GPIO power-off driver" 53 bool "GPIO power-off driver"
36 depends on OF_GPIO && POWER_RESET 54 depends on OF_GPIO
37 help 55 help
38 This driver supports turning off your board via a GPIO line. 56 This driver supports turning off your board via a GPIO line.
39 If your board needs a GPIO high/low to power down, say Y and 57 If your board needs a GPIO high/low to power down, say Y and
@@ -47,13 +65,13 @@ config POWER_RESET_HISI
47 65
48config POWER_RESET_MSM 66config POWER_RESET_MSM
49 bool "Qualcomm MSM power-off driver" 67 bool "Qualcomm MSM power-off driver"
50 depends on POWER_RESET && ARCH_QCOM 68 depends on ARCH_QCOM
51 help 69 help
52 Power off and restart support for Qualcomm boards. 70 Power off and restart support for Qualcomm boards.
53 71
54config POWER_RESET_QNAP 72config POWER_RESET_QNAP
55 bool "QNAP power-off driver" 73 bool "QNAP power-off driver"
56 depends on OF_GPIO && POWER_RESET && PLAT_ORION 74 depends on OF_GPIO && PLAT_ORION
57 help 75 help
58 This driver supports turning off QNAP NAS devices by sending 76 This driver supports turning off QNAP NAS devices by sending
59 commands to the microcontroller which controls the main power. 77 commands to the microcontroller which controls the main power.
@@ -71,14 +89,22 @@ config POWER_RESET_RESTART
71config POWER_RESET_SUN6I 89config POWER_RESET_SUN6I
72 bool "Allwinner A31 SoC reset driver" 90 bool "Allwinner A31 SoC reset driver"
73 depends on ARCH_SUNXI 91 depends on ARCH_SUNXI
74 depends on POWER_RESET
75 help 92 help
76 Reboot support for the Allwinner A31 SoCs. 93 Reboot support for the Allwinner A31 SoCs.
77 94
95config POWER_RESET_VERSATILE
96 bool "ARM Versatile family reboot driver"
97 depends on ARM
98 depends on MFD_SYSCON
99 depends on OF
100 help
101 Power off and restart support for ARM Versatile family of
102 reference boards.
103
78config POWER_RESET_VEXPRESS 104config POWER_RESET_VEXPRESS
79 bool "ARM Versatile Express power-off and reset driver" 105 bool "ARM Versatile Express power-off and reset driver"
80 depends on ARM || ARM64 106 depends on ARM || ARM64
81 depends on POWER_RESET && VEXPRESS_CONFIG 107 depends on VEXPRESS_CONFIG
82 help 108 help
83 Power off and reset support for the ARM Ltd. Versatile 109 Power off and reset support for the ARM Ltd. Versatile
84 Express boards. 110 Express boards.
@@ -86,7 +112,6 @@ config POWER_RESET_VEXPRESS
86config POWER_RESET_XGENE 112config POWER_RESET_XGENE
87 bool "APM SoC X-Gene reset driver" 113 bool "APM SoC X-Gene reset driver"
88 depends on ARM64 114 depends on ARM64
89 depends on POWER_RESET
90 help 115 help
91 Reboot support for the APM SoC X-Gene Eval boards. 116 Reboot support for the APM SoC X-Gene Eval boards.
92 117
@@ -97,3 +122,4 @@ config POWER_RESET_KEYSTONE
97 help 122 help
98 Reboot support for the KEYSTONE SoCs. 123 Reboot support for the KEYSTONE SoCs.
99 124
125endif
diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile
index a42e70edd037..73221009f2bf 100644
--- a/drivers/power/reset/Makefile
+++ b/drivers/power/reset/Makefile
@@ -1,4 +1,6 @@
1obj-$(CONFIG_POWER_RESET_AS3722) += as3722-poweroff.o 1obj-$(CONFIG_POWER_RESET_AS3722) += as3722-poweroff.o
2obj-$(CONFIG_POWER_RESET_AT91_POWEROFF) += at91-poweroff.o
3obj-$(CONFIG_POWER_RESET_AT91_RESET) += at91-reset.o
2obj-$(CONFIG_POWER_RESET_AXXIA) += axxia-reset.o 4obj-$(CONFIG_POWER_RESET_AXXIA) += axxia-reset.o
3obj-$(CONFIG_POWER_RESET_BRCMSTB) += brcmstb-reboot.o 5obj-$(CONFIG_POWER_RESET_BRCMSTB) += brcmstb-reboot.o
4obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o 6obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o
@@ -7,6 +9,7 @@ obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o
7obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o 9obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o
8obj-$(CONFIG_POWER_RESET_RESTART) += restart-poweroff.o 10obj-$(CONFIG_POWER_RESET_RESTART) += restart-poweroff.o
9obj-$(CONFIG_POWER_RESET_SUN6I) += sun6i-reboot.o 11obj-$(CONFIG_POWER_RESET_SUN6I) += sun6i-reboot.o
12obj-$(CONFIG_POWER_RESET_VERSATILE) += arm-versatile-reboot.o
10obj-$(CONFIG_POWER_RESET_VEXPRESS) += vexpress-poweroff.o 13obj-$(CONFIG_POWER_RESET_VEXPRESS) += vexpress-poweroff.o
11obj-$(CONFIG_POWER_RESET_XGENE) += xgene-reboot.o 14obj-$(CONFIG_POWER_RESET_XGENE) += xgene-reboot.o
12obj-$(CONFIG_POWER_RESET_KEYSTONE) += keystone-reset.o 15obj-$(CONFIG_POWER_RESET_KEYSTONE) += keystone-reset.o
diff --git a/drivers/power/reset/arm-versatile-reboot.c b/drivers/power/reset/arm-versatile-reboot.c
new file mode 100644
index 000000000000..5b08bffcf1a8
--- /dev/null
+++ b/drivers/power/reset/arm-versatile-reboot.c
@@ -0,0 +1,111 @@
1/*
2 * Copyright (C) 2014 Linaro Ltd.
3 *
4 * Author: Linus Walleij <linus.walleij@linaro.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2, as
8 * published by the Free Software Foundation.
9 *
10 */
11#include <linux/init.h>
12#include <linux/mfd/syscon.h>
13#include <linux/reboot.h>
14#include <linux/regmap.h>
15#include <linux/of.h>
16#include <asm/system_misc.h>
17
18#define REALVIEW_SYS_LOCK_OFFSET 0x20
19#define REALVIEW_SYS_LOCK_VAL 0xA05F
20#define REALVIEW_SYS_RESETCTL_OFFSET 0x40
21
22/*
23 * We detect the different syscon types from the compatible strings.
24 */
25enum versatile_reboot {
26 REALVIEW_REBOOT_EB,
27 REALVIEW_REBOOT_PB1176,
28 REALVIEW_REBOOT_PB11MP,
29 REALVIEW_REBOOT_PBA8,
30 REALVIEW_REBOOT_PBX,
31};
32
33/* Pointer to the system controller */
34static struct regmap *syscon_regmap;
35static enum versatile_reboot versatile_reboot_type;
36
37static const struct of_device_id versatile_reboot_of_match[] = {
38 {
39 .compatible = "arm,realview-eb-syscon",
40 .data = (void *)REALVIEW_REBOOT_EB,
41 },
42 {
43 .compatible = "arm,realview-pb1176-syscon",
44 .data = (void *)REALVIEW_REBOOT_PB1176,
45 },
46 {
47 .compatible = "arm,realview-pb11mp-syscon",
48 .data = (void *)REALVIEW_REBOOT_PB11MP,
49 },
50 {
51 .compatible = "arm,realview-pba8-syscon",
52 .data = (void *)REALVIEW_REBOOT_PBA8,
53 },
54 {
55 .compatible = "arm,realview-pbx-syscon",
56 .data = (void *)REALVIEW_REBOOT_PBX,
57 },
58};
59
60static void versatile_reboot(enum reboot_mode mode, const char *cmd)
61{
62 /* Unlock the reset register */
63 regmap_write(syscon_regmap, REALVIEW_SYS_LOCK_OFFSET,
64 REALVIEW_SYS_LOCK_VAL);
65 /* Then hit reset on the different machines */
66 switch (versatile_reboot_type) {
67 case REALVIEW_REBOOT_EB:
68 regmap_write(syscon_regmap,
69 REALVIEW_SYS_RESETCTL_OFFSET, 0x0008);
70 break;
71 case REALVIEW_REBOOT_PB1176:
72 regmap_write(syscon_regmap,
73 REALVIEW_SYS_RESETCTL_OFFSET, 0x0100);
74 break;
75 case REALVIEW_REBOOT_PB11MP:
76 case REALVIEW_REBOOT_PBA8:
77 regmap_write(syscon_regmap, REALVIEW_SYS_RESETCTL_OFFSET,
78 0x0000);
79 regmap_write(syscon_regmap, REALVIEW_SYS_RESETCTL_OFFSET,
80 0x0004);
81 break;
82 case REALVIEW_REBOOT_PBX:
83 regmap_write(syscon_regmap, REALVIEW_SYS_RESETCTL_OFFSET,
84 0x00f0);
85 regmap_write(syscon_regmap, REALVIEW_SYS_RESETCTL_OFFSET,
86 0x00f4);
87 break;
88 }
89 dsb();
90}
91
92static int __init versatile_reboot_probe(void)
93{
94 const struct of_device_id *reboot_id;
95 struct device_node *np;
96
97 np = of_find_matching_node_and_match(NULL, versatile_reboot_of_match,
98 &reboot_id);
99 if (!np)
100 return -ENODEV;
101 versatile_reboot_type = (enum versatile_reboot)reboot_id->data;
102
103 syscon_regmap = syscon_node_to_regmap(np);
104 if (IS_ERR(syscon_regmap))
105 return PTR_ERR(syscon_regmap);
106
107 arm_pm_restart = versatile_reboot;
108 pr_info("versatile reboot driver registered\n");
109 return 0;
110}
111device_initcall(versatile_reboot_probe);
diff --git a/drivers/power/reset/at91-poweroff.c b/drivers/power/reset/at91-poweroff.c
new file mode 100644
index 000000000000..c61000333bb9
--- /dev/null
+++ b/drivers/power/reset/at91-poweroff.c
@@ -0,0 +1,156 @@
1/*
2 * Atmel AT91 SAM9 SoCs reset code
3 *
4 * Copyright (C) 2007 Atmel Corporation.
5 * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
6 * Copyright (C) 2014 Free Electrons
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 */
12
13#include <linux/io.h>
14#include <linux/module.h>
15#include <linux/of.h>
16#include <linux/platform_device.h>
17#include <linux/printk.h>
18
19#define AT91_SHDW_CR 0x00 /* Shut Down Control Register */
20#define AT91_SHDW_SHDW BIT(0) /* Shut Down command */
21#define AT91_SHDW_KEY (0xa5 << 24) /* KEY Password */
22
23#define AT91_SHDW_MR 0x04 /* Shut Down Mode Register */
24#define AT91_SHDW_WKMODE0 GENMASK(2, 0) /* Wake-up 0 Mode Selection */
25#define AT91_SHDW_CPTWK0_MAX 0xf /* Maximum Counter On Wake Up 0 */
26#define AT91_SHDW_CPTWK0 (AT91_SHDW_CPTWK0_MAX << 4) /* Counter On Wake Up 0 */
27#define AT91_SHDW_CPTWK0_(x) ((x) << 4)
28#define AT91_SHDW_RTTWKEN BIT(16) /* Real Time Timer Wake-up Enable */
29#define AT91_SHDW_RTCWKEN BIT(17) /* Real Time Clock Wake-up Enable */
30
31#define AT91_SHDW_SR 0x08 /* Shut Down Status Register */
32#define AT91_SHDW_WAKEUP0 BIT(0) /* Wake-up 0 Status */
33#define AT91_SHDW_RTTWK BIT(16) /* Real-time Timer Wake-up */
34#define AT91_SHDW_RTCWK BIT(17) /* Real-time Clock Wake-up [SAM9RL] */
35
36enum wakeup_type {
37 AT91_SHDW_WKMODE0_NONE = 0,
38 AT91_SHDW_WKMODE0_HIGH = 1,
39 AT91_SHDW_WKMODE0_LOW = 2,
40 AT91_SHDW_WKMODE0_ANYLEVEL = 3,
41};
42
43static const char *shdwc_wakeup_modes[] = {
44 [AT91_SHDW_WKMODE0_NONE] = "none",
45 [AT91_SHDW_WKMODE0_HIGH] = "high",
46 [AT91_SHDW_WKMODE0_LOW] = "low",
47 [AT91_SHDW_WKMODE0_ANYLEVEL] = "any",
48};
49
50static void __iomem *at91_shdwc_base;
51
52static void __init at91_wakeup_status(void)
53{
54 u32 reg = readl(at91_shdwc_base + AT91_SHDW_SR);
55 char *reason = "unknown";
56
57 /* Simple power-on, just bail out */
58 if (!reg)
59 return;
60
61 if (reg & AT91_SHDW_RTTWK)
62 reason = "RTT";
63 else if (reg & AT91_SHDW_RTCWK)
64 reason = "RTC";
65
66 pr_info("AT91: Wake-Up source: %s\n", reason);
67}
68
69static void at91_poweroff(void)
70{
71 writel(AT91_SHDW_KEY | AT91_SHDW_SHDW, at91_shdwc_base + AT91_SHDW_CR);
72}
73
74const enum wakeup_type at91_poweroff_get_wakeup_mode(struct device_node *np)
75{
76 const char *pm;
77 int err, i;
78
79 err = of_property_read_string(np, "atmel,wakeup-mode", &pm);
80 if (err < 0)
81 return AT91_SHDW_WKMODE0_ANYLEVEL;
82
83 for (i = 0; i < ARRAY_SIZE(shdwc_wakeup_modes); i++)
84 if (!strcasecmp(pm, shdwc_wakeup_modes[i]))
85 return i;
86
87 return -ENODEV;
88}
89
90static void at91_poweroff_dt_set_wakeup_mode(struct platform_device *pdev)
91{
92 struct device_node *np = pdev->dev.of_node;
93 enum wakeup_type wakeup_mode;
94 u32 mode = 0, tmp;
95
96 wakeup_mode = at91_poweroff_get_wakeup_mode(np);
97 if (wakeup_mode < 0) {
98 dev_warn(&pdev->dev, "shdwc unknown wakeup mode\n");
99 return;
100 }
101
102 if (!of_property_read_u32(np, "atmel,wakeup-counter", &tmp)) {
103 if (tmp > AT91_SHDW_CPTWK0_MAX) {
104 dev_warn(&pdev->dev,
105 "shdwc wakeup counter 0x%x > 0x%x reduce it to 0x%x\n",
106 tmp, AT91_SHDW_CPTWK0_MAX, AT91_SHDW_CPTWK0_MAX);
107 tmp = AT91_SHDW_CPTWK0_MAX;
108 }
109 mode |= AT91_SHDW_CPTWK0_(tmp);
110 }
111
112 if (of_property_read_bool(np, "atmel,wakeup-rtc-timer"))
113 mode |= AT91_SHDW_RTCWKEN;
114
115 if (of_property_read_bool(np, "atmel,wakeup-rtt-timer"))
116 mode |= AT91_SHDW_RTTWKEN;
117
118 writel(wakeup_mode | mode, at91_shdwc_base + AT91_SHDW_MR);
119}
120
121static int at91_poweroff_probe(struct platform_device *pdev)
122{
123 struct resource *res;
124
125 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
126 at91_shdwc_base = devm_ioremap_resource(&pdev->dev, res);
127 if (IS_ERR(at91_shdwc_base)) {
128 dev_err(&pdev->dev, "Could not map reset controller address\n");
129 return PTR_ERR(at91_shdwc_base);
130 }
131
132 at91_wakeup_status();
133
134 if (pdev->dev.of_node)
135 at91_poweroff_dt_set_wakeup_mode(pdev);
136
137 pm_power_off = at91_poweroff;
138
139 return 0;
140}
141
142static struct of_device_id at91_poweroff_of_match[] = {
143 { .compatible = "atmel,at91sam9260-shdwc", },
144 { .compatible = "atmel,at91sam9rl-shdwc", },
145 { .compatible = "atmel,at91sam9x5-shdwc", },
146 { /*sentinel*/ }
147};
148
149static struct platform_driver at91_poweroff_driver = {
150 .probe = at91_poweroff_probe,
151 .driver = {
152 .name = "at91-poweroff",
153 .of_match_table = at91_poweroff_of_match,
154 },
155};
156module_platform_driver(at91_poweroff_driver);
diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c
new file mode 100644
index 000000000000..3611806c9cfd
--- /dev/null
+++ b/drivers/power/reset/at91-reset.c
@@ -0,0 +1,252 @@
1/*
2 * Atmel AT91 SAM9 SoCs reset code
3 *
4 * Copyright (C) 2007 Atmel Corporation.
5 * Copyright (C) BitBox Ltd 2010
6 * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcosoft.com>
7 * Copyright (C) 2014 Free Electrons
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#include <linux/io.h>
15#include <linux/module.h>
16#include <linux/of_address.h>
17#include <linux/platform_device.h>
18#include <linux/reboot.h>
19
20#include <asm/system_misc.h>
21
22#include <mach/at91sam9_ddrsdr.h>
23#include <mach/at91sam9_sdramc.h>
24
25#define AT91_RSTC_CR 0x00 /* Reset Controller Control Register */
26#define AT91_RSTC_PROCRST BIT(0) /* Processor Reset */
27#define AT91_RSTC_PERRST BIT(2) /* Peripheral Reset */
28#define AT91_RSTC_EXTRST BIT(3) /* External Reset */
29#define AT91_RSTC_KEY (0xa5 << 24) /* KEY Password */
30
31#define AT91_RSTC_SR 0x04 /* Reset Controller Status Register */
32#define AT91_RSTC_URSTS BIT(0) /* User Reset Status */
33#define AT91_RSTC_RSTTYP GENMASK(10, 8) /* Reset Type */
34#define AT91_RSTC_NRSTL BIT(16) /* NRST Pin Level */
35#define AT91_RSTC_SRCMP BIT(17) /* Software Reset Command in Progress */
36
37#define AT91_RSTC_MR 0x08 /* Reset Controller Mode Register */
38#define AT91_RSTC_URSTEN BIT(0) /* User Reset Enable */
39#define AT91_RSTC_URSTIEN BIT(4) /* User Reset Interrupt Enable */
40#define AT91_RSTC_ERSTL GENMASK(11, 8) /* External Reset Length */
41
42enum reset_type {
43 RESET_TYPE_GENERAL = 0,
44 RESET_TYPE_WAKEUP = 1,
45 RESET_TYPE_WATCHDOG = 2,
46 RESET_TYPE_SOFTWARE = 3,
47 RESET_TYPE_USER = 4,
48};
49
50static void __iomem *at91_ramc_base[2], *at91_rstc_base;
51
52/*
53* unless the SDRAM is cleanly shutdown before we hit the
54* reset register it can be left driving the data bus and
55* killing the chance of a subsequent boot from NAND
56*/
57static void at91sam9260_restart(enum reboot_mode mode, const char *cmd)
58{
59 asm volatile(
60 /* Align to cache lines */
61 ".balign 32\n\t"
62
63 /* Disable SDRAM accesses */
64 "str %2, [%0, #" __stringify(AT91_SDRAMC_TR) "]\n\t"
65
66 /* Power down SDRAM */
67 "str %3, [%0, #" __stringify(AT91_SDRAMC_LPR) "]\n\t"
68
69 /* Reset CPU */
70 "str %4, [%1, #" __stringify(AT91_RSTC_CR) "]\n\t"
71
72 "b .\n\t"
73 :
74 : "r" (at91_ramc_base[0]),
75 "r" (at91_rstc_base),
76 "r" (1),
77 "r" (AT91_SDRAMC_LPCB_POWER_DOWN),
78 "r" (AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST));
79}
80
81static void at91sam9g45_restart(enum reboot_mode mode, const char *cmd)
82{
83 asm volatile(
84 /*
85 * Test wether we have a second RAM controller to care
86 * about.
87 *
88 * First, test that we can dereference the virtual address.
89 */
90 "cmp %1, #0\n\t"
91 "beq 1f\n\t"
92
93 /* Then, test that the RAM controller is enabled */
94 "ldr r0, [%1]\n\t"
95 "cmp r0, #0\n\t"
96
97 /* Align to cache lines */
98 ".balign 32\n\t"
99
100 /* Disable SDRAM0 accesses */
101 "1: str %3, [%0, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t"
102 /* Power down SDRAM0 */
103 " str %4, [%0, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t"
104 /* Disable SDRAM1 accesses */
105 " strne %3, [%1, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t"
106 /* Power down SDRAM1 */
107 " strne %4, [%1, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t"
108 /* Reset CPU */
109 " str %5, [%2, #" __stringify(AT91_RSTC_CR) "]\n\t"
110
111 " b .\n\t"
112 :
113 : "r" (at91_ramc_base[0]),
114 "r" (at91_ramc_base[1]),
115 "r" (at91_rstc_base),
116 "r" (1),
117 "r" (AT91_DDRSDRC_LPCB_POWER_DOWN),
118 "r" (AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST)
119 : "r0");
120}
121
122static void __init at91_reset_status(struct platform_device *pdev)
123{
124 u32 reg = readl(at91_rstc_base + AT91_RSTC_SR);
125 char *reason;
126
127 switch ((reg & AT91_RSTC_RSTTYP) >> 8) {
128 case RESET_TYPE_GENERAL:
129 reason = "general reset";
130 break;
131 case RESET_TYPE_WAKEUP:
132 reason = "wakeup";
133 break;
134 case RESET_TYPE_WATCHDOG:
135 reason = "watchdog reset";
136 break;
137 case RESET_TYPE_SOFTWARE:
138 reason = "software reset";
139 break;
140 case RESET_TYPE_USER:
141 reason = "user reset";
142 break;
143 default:
144 reason = "unknown reset";
145 break;
146 }
147
148 pr_info("AT91: Starting after %s\n", reason);
149}
150
151static struct of_device_id at91_ramc_of_match[] = {
152 { .compatible = "atmel,at91sam9260-sdramc", },
153 { .compatible = "atmel,at91sam9g45-ddramc", },
154 { .compatible = "atmel,sama5d3-ddramc", },
155 { /* sentinel */ }
156};
157
158static struct of_device_id at91_reset_of_match[] = {
159 { .compatible = "atmel,at91sam9260-rstc", .data = at91sam9260_restart },
160 { .compatible = "atmel,at91sam9g45-rstc", .data = at91sam9g45_restart },
161 { /* sentinel */ }
162};
163
164static int at91_reset_of_probe(struct platform_device *pdev)
165{
166 const struct of_device_id *match;
167 struct device_node *np;
168 int idx = 0;
169
170 at91_rstc_base = of_iomap(pdev->dev.of_node, 0);
171 if (!at91_rstc_base) {
172 dev_err(&pdev->dev, "Could not map reset controller address\n");
173 return -ENODEV;
174 }
175
176 for_each_matching_node(np, at91_ramc_of_match) {
177 at91_ramc_base[idx] = of_iomap(np, 0);
178 if (!at91_ramc_base[idx]) {
179 dev_err(&pdev->dev, "Could not map ram controller address\n");
180 return -ENODEV;
181 }
182 idx++;
183 }
184
185 match = of_match_node(at91_reset_of_match, pdev->dev.of_node);
186 arm_pm_restart = match->data;
187
188 return 0;
189}
190
191static int at91_reset_platform_probe(struct platform_device *pdev)
192{
193 const struct platform_device_id *match;
194 struct resource *res;
195 int idx = 0;
196
197 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
198 at91_rstc_base = devm_ioremap_resource(&pdev->dev, res);
199 if (IS_ERR(at91_rstc_base)) {
200 dev_err(&pdev->dev, "Could not map reset controller address\n");
201 return PTR_ERR(at91_rstc_base);
202 }
203
204 for (idx = 0; idx < 2; idx++) {
205 res = platform_get_resource(pdev, IORESOURCE_MEM, idx + 1 );
206 at91_ramc_base[idx] = devm_ioremap(&pdev->dev, res->start,
207 resource_size(res));
208 if (IS_ERR(at91_ramc_base[idx])) {
209 dev_err(&pdev->dev, "Could not map ram controller address\n");
210 return PTR_ERR(at91_ramc_base[idx]);
211 }
212 }
213
214 match = platform_get_device_id(pdev);
215 arm_pm_restart = (void (*)(enum reboot_mode, const char*))
216 match->driver_data;
217
218 return 0;
219}
220
221static int at91_reset_probe(struct platform_device *pdev)
222{
223 int ret;
224
225 if (pdev->dev.of_node)
226 ret = at91_reset_of_probe(pdev);
227 else
228 ret = at91_reset_platform_probe(pdev);
229
230 if (ret)
231 return ret;
232
233 at91_reset_status(pdev);
234
235 return 0;
236}
237
238static struct platform_device_id at91_reset_plat_match[] = {
239 { "at91-sam9260-reset", (unsigned long)at91sam9260_restart },
240 { "at91-sam9g45-reset", (unsigned long)at91sam9g45_restart },
241 { /* sentinel */ }
242};
243
244static struct platform_driver at91_reset_driver = {
245 .probe = at91_reset_probe,
246 .driver = {
247 .name = "at91-reset",
248 .of_match_table = at91_reset_of_match,
249 },
250 .id_table = at91_reset_plat_match,
251};
252module_platform_driver(at91_reset_driver);
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index fae9464eed9c..1bea0fc43464 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1175,9 +1175,16 @@ config RTC_DRV_SUN4V
1175 If you say Y here you will get support for the Hypervisor 1175 If you say Y here you will get support for the Hypervisor
1176 based RTC on SUN4V systems. 1176 based RTC on SUN4V systems.
1177 1177
1178config RTC_DRV_SUN6I
1179 tristate "Allwinner A31 RTC"
1180 depends on MACH_SUN6I || MACH_SUN8I
1181 help
1182 If you say Y here you will get support for the RTC found on
1183 Allwinner A31.
1184
1178config RTC_DRV_SUNXI 1185config RTC_DRV_SUNXI
1179 tristate "Allwinner sun4i/sun7i RTC" 1186 tristate "Allwinner sun4i/sun7i RTC"
1180 depends on ARCH_SUNXI 1187 depends on MACH_SUN4I || MACH_SUN7I
1181 help 1188 help
1182 If you say Y here you will get support for the RTC found on 1189 If you say Y here you will get support for the RTC found on
1183 Allwinner A10/A20. 1190 Allwinner A10/A20.
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 56f061c7c815..9055b7dd3dc5 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -128,6 +128,7 @@ obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o
128obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o 128obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o
129obj-$(CONFIG_RTC_DRV_STMP) += rtc-stmp3xxx.o 129obj-$(CONFIG_RTC_DRV_STMP) += rtc-stmp3xxx.o
130obj-$(CONFIG_RTC_DRV_SUN4V) += rtc-sun4v.o 130obj-$(CONFIG_RTC_DRV_SUN4V) += rtc-sun4v.o
131obj-$(CONFIG_RTC_DRV_SUN6I) += rtc-sun6i.o
131obj-$(CONFIG_RTC_DRV_SUNXI) += rtc-sunxi.o 132obj-$(CONFIG_RTC_DRV_SUNXI) += rtc-sunxi.o
132obj-$(CONFIG_RTC_DRV_TEGRA) += rtc-tegra.o 133obj-$(CONFIG_RTC_DRV_TEGRA) += rtc-tegra.o
133obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o 134obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o
diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
new file mode 100644
index 000000000000..c169a2cd4727
--- /dev/null
+++ b/drivers/rtc/rtc-sun6i.c
@@ -0,0 +1,447 @@
1/*
2 * An RTC driver for Allwinner A31/A23
3 *
4 * Copyright (c) 2014, Chen-Yu Tsai <wens@csie.org>
5 *
6 * based on rtc-sunxi.c
7 *
8 * An RTC driver for Allwinner A10/A20
9 *
10 * Copyright (c) 2013, Carlo Caione <carlo.caione@gmail.com>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
20 * more details.
21 */
22
23#include <linux/delay.h>
24#include <linux/err.h>
25#include <linux/fs.h>
26#include <linux/init.h>
27#include <linux/interrupt.h>
28#include <linux/io.h>
29#include <linux/kernel.h>
30#include <linux/module.h>
31#include <linux/of.h>
32#include <linux/of_address.h>
33#include <linux/of_device.h>
34#include <linux/platform_device.h>
35#include <linux/rtc.h>
36#include <linux/types.h>
37
38/* Control register */
39#define SUN6I_LOSC_CTRL 0x0000
40#define SUN6I_LOSC_CTRL_ALM_DHMS_ACC BIT(9)
41#define SUN6I_LOSC_CTRL_RTC_HMS_ACC BIT(8)
42#define SUN6I_LOSC_CTRL_RTC_YMD_ACC BIT(7)
43#define SUN6I_LOSC_CTRL_ACC_MASK GENMASK(9, 7)
44
45/* RTC */
46#define SUN6I_RTC_YMD 0x0010
47#define SUN6I_RTC_HMS 0x0014
48
49/* Alarm 0 (counter) */
50#define SUN6I_ALRM_COUNTER 0x0020
51#define SUN6I_ALRM_CUR_VAL 0x0024
52#define SUN6I_ALRM_EN 0x0028
53#define SUN6I_ALRM_EN_CNT_EN BIT(0)
54#define SUN6I_ALRM_IRQ_EN 0x002c
55#define SUN6I_ALRM_IRQ_EN_CNT_IRQ_EN BIT(0)
56#define SUN6I_ALRM_IRQ_STA 0x0030
57#define SUN6I_ALRM_IRQ_STA_CNT_IRQ_PEND BIT(0)
58
59/* Alarm 1 (wall clock) */
60#define SUN6I_ALRM1_EN 0x0044
61#define SUN6I_ALRM1_IRQ_EN 0x0048
62#define SUN6I_ALRM1_IRQ_STA 0x004c
63#define SUN6I_ALRM1_IRQ_STA_WEEK_IRQ_PEND BIT(0)
64
65/* Alarm config */
66#define SUN6I_ALARM_CONFIG 0x0050
67#define SUN6I_ALARM_CONFIG_WAKEUP BIT(0)
68
69/*
70 * Get date values
71 */
72#define SUN6I_DATE_GET_DAY_VALUE(x) ((x) & 0x0000001f)
73#define SUN6I_DATE_GET_MON_VALUE(x) (((x) & 0x00000f00) >> 8)
74#define SUN6I_DATE_GET_YEAR_VALUE(x) (((x) & 0x003f0000) >> 16)
75#define SUN6I_LEAP_GET_VALUE(x) (((x) & 0x00400000) >> 22)
76
77/*
78 * Get time values
79 */
80#define SUN6I_TIME_GET_SEC_VALUE(x) ((x) & 0x0000003f)
81#define SUN6I_TIME_GET_MIN_VALUE(x) (((x) & 0x00003f00) >> 8)
82#define SUN6I_TIME_GET_HOUR_VALUE(x) (((x) & 0x001f0000) >> 16)
83
84/*
85 * Set date values
86 */
87#define SUN6I_DATE_SET_DAY_VALUE(x) ((x) & 0x0000001f)
88#define SUN6I_DATE_SET_MON_VALUE(x) ((x) << 8 & 0x00000f00)
89#define SUN6I_DATE_SET_YEAR_VALUE(x) ((x) << 16 & 0x003f0000)
90#define SUN6I_LEAP_SET_VALUE(x) ((x) << 22 & 0x00400000)
91
92/*
93 * Set time values
94 */
95#define SUN6I_TIME_SET_SEC_VALUE(x) ((x) & 0x0000003f)
96#define SUN6I_TIME_SET_MIN_VALUE(x) ((x) << 8 & 0x00003f00)
97#define SUN6I_TIME_SET_HOUR_VALUE(x) ((x) << 16 & 0x001f0000)
98
99/*
100 * The year parameter passed to the driver is usually an offset relative to
101 * the year 1900. This macro is used to convert this offset to another one
102 * relative to the minimum year allowed by the hardware.
103 *
104 * The year range is 1970 - 2033. This range is selected to match Allwinner's
105 * driver, even though it is somewhat limited.
106 */
107#define SUN6I_YEAR_MIN 1970
108#define SUN6I_YEAR_MAX 2033
109#define SUN6I_YEAR_OFF (SUN6I_YEAR_MIN - 1900)
110
111struct sun6i_rtc_dev {
112 struct rtc_device *rtc;
113 struct device *dev;
114 void __iomem *base;
115 int irq;
116 unsigned long alarm;
117};
118
119static irqreturn_t sun6i_rtc_alarmirq(int irq, void *id)
120{
121 struct sun6i_rtc_dev *chip = (struct sun6i_rtc_dev *) id;
122 u32 val;
123
124 val = readl(chip->base + SUN6I_ALRM_IRQ_STA);
125
126 if (val & SUN6I_ALRM_IRQ_STA_CNT_IRQ_PEND) {
127 val |= SUN6I_ALRM_IRQ_STA_CNT_IRQ_PEND;
128 writel(val, chip->base + SUN6I_ALRM_IRQ_STA);
129
130 rtc_update_irq(chip->rtc, 1, RTC_AF | RTC_IRQF);
131
132 return IRQ_HANDLED;
133 }
134
135 return IRQ_NONE;
136}
137
138static void sun6i_rtc_setaie(int to, struct sun6i_rtc_dev *chip)
139{
140 u32 alrm_val = 0;
141 u32 alrm_irq_val = 0;
142 u32 alrm_wake_val = 0;
143
144 if (to) {
145 alrm_val = SUN6I_ALRM_EN_CNT_EN;
146 alrm_irq_val = SUN6I_ALRM_IRQ_EN_CNT_IRQ_EN;
147 alrm_wake_val = SUN6I_ALARM_CONFIG_WAKEUP;
148 } else {
149 writel(SUN6I_ALRM_IRQ_STA_CNT_IRQ_PEND,
150 chip->base + SUN6I_ALRM_IRQ_STA);
151 }
152
153 writel(alrm_val, chip->base + SUN6I_ALRM_EN);
154 writel(alrm_irq_val, chip->base + SUN6I_ALRM_IRQ_EN);
155 writel(alrm_wake_val, chip->base + SUN6I_ALARM_CONFIG);
156}
157
158static int sun6i_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
159{
160 struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
161 u32 date, time;
162
163 /*
164 * read again in case it changes
165 */
166 do {
167 date = readl(chip->base + SUN6I_RTC_YMD);
168 time = readl(chip->base + SUN6I_RTC_HMS);
169 } while ((date != readl(chip->base + SUN6I_RTC_YMD)) ||
170 (time != readl(chip->base + SUN6I_RTC_HMS)));
171
172 rtc_tm->tm_sec = SUN6I_TIME_GET_SEC_VALUE(time);
173 rtc_tm->tm_min = SUN6I_TIME_GET_MIN_VALUE(time);
174 rtc_tm->tm_hour = SUN6I_TIME_GET_HOUR_VALUE(time);
175
176 rtc_tm->tm_mday = SUN6I_DATE_GET_DAY_VALUE(date);
177 rtc_tm->tm_mon = SUN6I_DATE_GET_MON_VALUE(date);
178 rtc_tm->tm_year = SUN6I_DATE_GET_YEAR_VALUE(date);
179
180 rtc_tm->tm_mon -= 1;
181
182 /*
183 * switch from (data_year->min)-relative offset to
184 * a (1900)-relative one
185 */
186 rtc_tm->tm_year += SUN6I_YEAR_OFF;
187
188 return rtc_valid_tm(rtc_tm);
189}
190
191static int sun6i_rtc_getalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
192{
193 struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
194 u32 alrm_st;
195 u32 alrm_en;
196
197 alrm_en = readl(chip->base + SUN6I_ALRM_IRQ_EN);
198 alrm_st = readl(chip->base + SUN6I_ALRM_IRQ_STA);
199 wkalrm->enabled = !!(alrm_en & SUN6I_ALRM_EN_CNT_EN);
200 wkalrm->pending = !!(alrm_st & SUN6I_ALRM_EN_CNT_EN);
201 rtc_time_to_tm(chip->alarm, &wkalrm->time);
202
203 return 0;
204}
205
206static int sun6i_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
207{
208 struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
209 struct rtc_time *alrm_tm = &wkalrm->time;
210 struct rtc_time tm_now;
211 unsigned long time_now = 0;
212 unsigned long time_set = 0;
213 unsigned long time_gap = 0;
214 int ret = 0;
215
216 ret = sun6i_rtc_gettime(dev, &tm_now);
217 if (ret < 0) {
218 dev_err(dev, "Error in getting time\n");
219 return -EINVAL;
220 }
221
222 rtc_tm_to_time(alrm_tm, &time_set);
223 rtc_tm_to_time(&tm_now, &time_now);
224 if (time_set <= time_now) {
225 dev_err(dev, "Date to set in the past\n");
226 return -EINVAL;
227 }
228
229 time_gap = time_set - time_now;
230
231 if (time_gap > U32_MAX) {
232 dev_err(dev, "Date too far in the future\n");
233 return -EINVAL;
234 }
235
236 sun6i_rtc_setaie(0, chip);
237 writel(0, chip->base + SUN6I_ALRM_COUNTER);
238 usleep_range(100, 300);
239
240 writel(time_gap, chip->base + SUN6I_ALRM_COUNTER);
241 chip->alarm = time_set;
242
243 sun6i_rtc_setaie(wkalrm->enabled, chip);
244
245 return 0;
246}
247
248static int sun6i_rtc_wait(struct sun6i_rtc_dev *chip, int offset,
249 unsigned int mask, unsigned int ms_timeout)
250{
251 const unsigned long timeout = jiffies + msecs_to_jiffies(ms_timeout);
252 u32 reg;
253
254 do {
255 reg = readl(chip->base + offset);
256 reg &= mask;
257
258 if (!reg)
259 return 0;
260
261 } while (time_before(jiffies, timeout));
262
263 return -ETIMEDOUT;
264}
265
266static int sun6i_rtc_settime(struct device *dev, struct rtc_time *rtc_tm)
267{
268 struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
269 u32 date = 0;
270 u32 time = 0;
271 int year;
272
273 year = rtc_tm->tm_year + 1900;
274 if (year < SUN6I_YEAR_MIN || year > SUN6I_YEAR_MAX) {
275 dev_err(dev, "rtc only supports year in range %d - %d\n",
276 SUN6I_YEAR_MIN, SUN6I_YEAR_MAX);
277 return -EINVAL;
278 }
279
280 rtc_tm->tm_year -= SUN6I_YEAR_OFF;
281 rtc_tm->tm_mon += 1;
282
283 date = SUN6I_DATE_SET_DAY_VALUE(rtc_tm->tm_mday) |
284 SUN6I_DATE_SET_MON_VALUE(rtc_tm->tm_mon) |
285 SUN6I_DATE_SET_YEAR_VALUE(rtc_tm->tm_year);
286
287 if (is_leap_year(year))
288 date |= SUN6I_LEAP_SET_VALUE(1);
289
290 time = SUN6I_TIME_SET_SEC_VALUE(rtc_tm->tm_sec) |
291 SUN6I_TIME_SET_MIN_VALUE(rtc_tm->tm_min) |
292 SUN6I_TIME_SET_HOUR_VALUE(rtc_tm->tm_hour);
293
294 /* Check whether registers are writable */
295 if (sun6i_rtc_wait(chip, SUN6I_LOSC_CTRL,
296 SUN6I_LOSC_CTRL_ACC_MASK, 50)) {
297 dev_err(dev, "rtc is still busy.\n");
298 return -EBUSY;
299 }
300
301 writel(time, chip->base + SUN6I_RTC_HMS);
302
303 /*
304 * After writing the RTC HH-MM-SS register, the
305 * SUN6I_LOSC_CTRL_RTC_HMS_ACC bit is set and it will not
306 * be cleared until the real writing operation is finished
307 */
308
309 if (sun6i_rtc_wait(chip, SUN6I_LOSC_CTRL,
310 SUN6I_LOSC_CTRL_RTC_HMS_ACC, 50)) {
311 dev_err(dev, "Failed to set rtc time.\n");
312 return -ETIMEDOUT;
313 }
314
315 writel(date, chip->base + SUN6I_RTC_YMD);
316
317 /*
318 * After writing the RTC YY-MM-DD register, the
319 * SUN6I_LOSC_CTRL_RTC_YMD_ACC bit is set and it will not
320 * be cleared until the real writing operation is finished
321 */
322
323 if (sun6i_rtc_wait(chip, SUN6I_LOSC_CTRL,
324 SUN6I_LOSC_CTRL_RTC_YMD_ACC, 50)) {
325 dev_err(dev, "Failed to set rtc time.\n");
326 return -ETIMEDOUT;
327 }
328
329 return 0;
330}
331
332static int sun6i_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
333{
334 struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
335
336 if (!enabled)
337 sun6i_rtc_setaie(enabled, chip);
338
339 return 0;
340}
341
342static const struct rtc_class_ops sun6i_rtc_ops = {
343 .read_time = sun6i_rtc_gettime,
344 .set_time = sun6i_rtc_settime,
345 .read_alarm = sun6i_rtc_getalarm,
346 .set_alarm = sun6i_rtc_setalarm,
347 .alarm_irq_enable = sun6i_rtc_alarm_irq_enable
348};
349
350static int sun6i_rtc_probe(struct platform_device *pdev)
351{
352 struct sun6i_rtc_dev *chip;
353 struct resource *res;
354 int ret;
355
356 chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
357 if (!chip)
358 return -ENOMEM;
359
360 platform_set_drvdata(pdev, chip);
361 chip->dev = &pdev->dev;
362
363 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
364 chip->base = devm_ioremap_resource(&pdev->dev, res);
365 if (IS_ERR(chip->base))
366 return PTR_ERR(chip->base);
367
368 chip->irq = platform_get_irq(pdev, 0);
369 if (chip->irq < 0) {
370 dev_err(&pdev->dev, "No IRQ resource\n");
371 return chip->irq;
372 }
373
374 ret = devm_request_irq(&pdev->dev, chip->irq, sun6i_rtc_alarmirq,
375 0, dev_name(&pdev->dev), chip);
376 if (ret) {
377 dev_err(&pdev->dev, "Could not request IRQ\n");
378 return ret;
379 }
380
381 /* clear the alarm counter value */
382 writel(0, chip->base + SUN6I_ALRM_COUNTER);
383
384 /* disable counter alarm */
385 writel(0, chip->base + SUN6I_ALRM_EN);
386
387 /* disable counter alarm interrupt */
388 writel(0, chip->base + SUN6I_ALRM_IRQ_EN);
389
390 /* disable week alarm */
391 writel(0, chip->base + SUN6I_ALRM1_EN);
392
393 /* disable week alarm interrupt */
394 writel(0, chip->base + SUN6I_ALRM1_IRQ_EN);
395
396 /* clear counter alarm pending interrupts */
397 writel(SUN6I_ALRM_IRQ_STA_CNT_IRQ_PEND,
398 chip->base + SUN6I_ALRM_IRQ_STA);
399
400 /* clear week alarm pending interrupts */
401 writel(SUN6I_ALRM1_IRQ_STA_WEEK_IRQ_PEND,
402 chip->base + SUN6I_ALRM1_IRQ_STA);
403
404 /* disable alarm wakeup */
405 writel(0, chip->base + SUN6I_ALARM_CONFIG);
406
407 chip->rtc = rtc_device_register("rtc-sun6i", &pdev->dev,
408 &sun6i_rtc_ops, THIS_MODULE);
409 if (IS_ERR(chip->rtc)) {
410 dev_err(&pdev->dev, "unable to register device\n");
411 return PTR_ERR(chip->rtc);
412 }
413
414 dev_info(&pdev->dev, "RTC enabled\n");
415
416 return 0;
417}
418
419static int sun6i_rtc_remove(struct platform_device *pdev)
420{
421 struct sun6i_rtc_dev *chip = platform_get_drvdata(pdev);
422
423 rtc_device_unregister(chip->rtc);
424
425 return 0;
426}
427
428static const struct of_device_id sun6i_rtc_dt_ids[] = {
429 { .compatible = "allwinner,sun6i-a31-rtc" },
430 { /* sentinel */ },
431};
432MODULE_DEVICE_TABLE(of, sun6i_rtc_dt_ids);
433
434static struct platform_driver sun6i_rtc_driver = {
435 .probe = sun6i_rtc_probe,
436 .remove = sun6i_rtc_remove,
437 .driver = {
438 .name = "sun6i-rtc",
439 .of_match_table = sun6i_rtc_dt_ids,
440 },
441};
442
443module_platform_driver(sun6i_rtc_driver);
444
445MODULE_DESCRIPTION("sun6i RTC driver");
446MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
447MODULE_LICENSE("GPL");
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index c8543855aa82..76d6bd4da138 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -1,5 +1,7 @@
1menu "SOC (System On Chip) specific Drivers" 1menu "SOC (System On Chip) specific Drivers"
2 2
3source "drivers/soc/qcom/Kconfig" 3source "drivers/soc/qcom/Kconfig"
4source "drivers/soc/ti/Kconfig"
5source "drivers/soc/versatile/Kconfig"
4 6
5endmenu 7endmenu
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 3b1b95d932d1..063113d0bd38 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -4,3 +4,5 @@
4 4
5obj-$(CONFIG_ARCH_QCOM) += qcom/ 5obj-$(CONFIG_ARCH_QCOM) += qcom/
6obj-$(CONFIG_ARCH_TEGRA) += tegra/ 6obj-$(CONFIG_ARCH_TEGRA) += tegra/
7obj-$(CONFIG_SOC_TI) += ti/
8obj-$(CONFIG_PLAT_VERSATILE) += versatile/
diff --git a/drivers/soc/ti/Kconfig b/drivers/soc/ti/Kconfig
new file mode 100644
index 000000000000..7266b2165183
--- /dev/null
+++ b/drivers/soc/ti/Kconfig
@@ -0,0 +1,31 @@
1#
2# TI SOC drivers
3#
4menuconfig SOC_TI
5 bool "TI SOC drivers support"
6
7if SOC_TI
8
9config KEYSTONE_NAVIGATOR_QMSS
10 tristate "Keystone Queue Manager Sub System"
11 depends on ARCH_KEYSTONE
12 help
13 Say y here to support the Keystone multicore Navigator Queue
14 Manager support. The Queue Manager is a hardware module that
15 is responsible for accelerating management of the packet queues.
16 Packets are queued/de-queued by writing/reading descriptor address
17 to a particular memory mapped location in the Queue Manager module.
18
19 If unsure, say N.
20
21config KEYSTONE_NAVIGATOR_DMA
22 tristate "TI Keystone Navigator Packet DMA support"
23 depends on ARCH_KEYSTONE
24 help
25 Say y tp enable support for the Keystone Navigator Packet DMA on
26 on Keystone family of devices. It sets up the dma channels for the
27 Queue Manager Sub System.
28
29 If unsure, say N.
30
31endif # SOC_TI
diff --git a/drivers/soc/ti/Makefile b/drivers/soc/ti/Makefile
new file mode 100644
index 000000000000..6bed611e1934
--- /dev/null
+++ b/drivers/soc/ti/Makefile
@@ -0,0 +1,5 @@
1#
2# TI Keystone SOC drivers
3#
4obj-$(CONFIG_KEYSTONE_NAVIGATOR_QMSS) += knav_qmss_queue.o knav_qmss_acc.o
5obj-$(CONFIG_KEYSTONE_NAVIGATOR_DMA) += knav_dma.o
diff --git a/drivers/soc/ti/knav_dma.c b/drivers/soc/ti/knav_dma.c
new file mode 100644
index 000000000000..17264275f32b
--- /dev/null
+++ b/drivers/soc/ti/knav_dma.c
@@ -0,0 +1,815 @@
1/*
2 * Copyright (C) 2014 Texas Instruments Incorporated
3 * Authors: Santosh Shilimkar <santosh.shilimkar@ti.com>
4 * Sandeep Nair <sandeep_n@ti.com>
5 * Cyril Chemparathy <cyril@ti.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation version 2.
10 *
11 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
12 * kind, whether express or implied; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/io.h>
18#include <linux/sched.h>
19#include <linux/module.h>
20#include <linux/dma-direction.h>
21#include <linux/interrupt.h>
22#include <linux/pm_runtime.h>
23#include <linux/of_dma.h>
24#include <linux/of_address.h>
25#include <linux/platform_device.h>
26#include <linux/soc/ti/knav_dma.h>
27#include <linux/debugfs.h>
28#include <linux/seq_file.h>
29
30#define REG_MASK 0xffffffff
31
32#define DMA_LOOPBACK BIT(31)
33#define DMA_ENABLE BIT(31)
34#define DMA_TEARDOWN BIT(30)
35
36#define DMA_TX_FILT_PSWORDS BIT(29)
37#define DMA_TX_FILT_EINFO BIT(30)
38#define DMA_TX_PRIO_SHIFT 0
39#define DMA_RX_PRIO_SHIFT 16
40#define DMA_PRIO_MASK GENMASK(3, 0)
41#define DMA_PRIO_DEFAULT 0
42#define DMA_RX_TIMEOUT_DEFAULT 17500 /* cycles */
43#define DMA_RX_TIMEOUT_MASK GENMASK(16, 0)
44#define DMA_RX_TIMEOUT_SHIFT 0
45
46#define CHAN_HAS_EPIB BIT(30)
47#define CHAN_HAS_PSINFO BIT(29)
48#define CHAN_ERR_RETRY BIT(28)
49#define CHAN_PSINFO_AT_SOP BIT(25)
50#define CHAN_SOP_OFF_SHIFT 16
51#define CHAN_SOP_OFF_MASK GENMASK(9, 0)
52#define DESC_TYPE_SHIFT 26
53#define DESC_TYPE_MASK GENMASK(2, 0)
54
55/*
56 * QMGR & QNUM together make up 14 bits with QMGR as the 2 MSb's in the logical
57 * navigator cloud mapping scheme.
58 * using the 14bit physical queue numbers directly maps into this scheme.
59 */
60#define CHAN_QNUM_MASK GENMASK(14, 0)
61#define DMA_MAX_QMS 4
62#define DMA_TIMEOUT 1 /* msecs */
63#define DMA_INVALID_ID 0xffff
64
65struct reg_global {
66 u32 revision;
67 u32 perf_control;
68 u32 emulation_control;
69 u32 priority_control;
70 u32 qm_base_address[DMA_MAX_QMS];
71};
72
73struct reg_chan {
74 u32 control;
75 u32 mode;
76 u32 __rsvd[6];
77};
78
79struct reg_tx_sched {
80 u32 prio;
81};
82
83struct reg_rx_flow {
84 u32 control;
85 u32 tags;
86 u32 tag_sel;
87 u32 fdq_sel[2];
88 u32 thresh[3];
89};
90
91struct knav_dma_pool_device {
92 struct device *dev;
93 struct list_head list;
94};
95
96struct knav_dma_device {
97 bool loopback, enable_all;
98 unsigned tx_priority, rx_priority, rx_timeout;
99 unsigned logical_queue_managers;
100 unsigned qm_base_address[DMA_MAX_QMS];
101 struct reg_global __iomem *reg_global;
102 struct reg_chan __iomem *reg_tx_chan;
103 struct reg_rx_flow __iomem *reg_rx_flow;
104 struct reg_chan __iomem *reg_rx_chan;
105 struct reg_tx_sched __iomem *reg_tx_sched;
106 unsigned max_rx_chan, max_tx_chan;
107 unsigned max_rx_flow;
108 char name[32];
109 atomic_t ref_count;
110 struct list_head list;
111 struct list_head chan_list;
112 spinlock_t lock;
113};
114
115struct knav_dma_chan {
116 enum dma_transfer_direction direction;
117 struct knav_dma_device *dma;
118 atomic_t ref_count;
119
120 /* registers */
121 struct reg_chan __iomem *reg_chan;
122 struct reg_tx_sched __iomem *reg_tx_sched;
123 struct reg_rx_flow __iomem *reg_rx_flow;
124
125 /* configuration stuff */
126 unsigned channel, flow;
127 struct knav_dma_cfg cfg;
128 struct list_head list;
129 spinlock_t lock;
130};
131
132#define chan_number(ch) ((ch->direction == DMA_MEM_TO_DEV) ? \
133 ch->channel : ch->flow)
134
135static struct knav_dma_pool_device *kdev;
136
137static bool check_config(struct knav_dma_chan *chan, struct knav_dma_cfg *cfg)
138{
139 if (!memcmp(&chan->cfg, cfg, sizeof(*cfg)))
140 return true;
141 else
142 return false;
143}
144
145static int chan_start(struct knav_dma_chan *chan,
146 struct knav_dma_cfg *cfg)
147{
148 u32 v = 0;
149
150 spin_lock(&chan->lock);
151 if ((chan->direction == DMA_MEM_TO_DEV) && chan->reg_chan) {
152 if (cfg->u.tx.filt_pswords)
153 v |= DMA_TX_FILT_PSWORDS;
154 if (cfg->u.tx.filt_einfo)
155 v |= DMA_TX_FILT_EINFO;
156 writel_relaxed(v, &chan->reg_chan->mode);
157 writel_relaxed(DMA_ENABLE, &chan->reg_chan->control);
158 }
159
160 if (chan->reg_tx_sched)
161 writel_relaxed(cfg->u.tx.priority, &chan->reg_tx_sched->prio);
162
163 if (chan->reg_rx_flow) {
164 v = 0;
165
166 if (cfg->u.rx.einfo_present)
167 v |= CHAN_HAS_EPIB;
168 if (cfg->u.rx.psinfo_present)
169 v |= CHAN_HAS_PSINFO;
170 if (cfg->u.rx.err_mode == DMA_RETRY)
171 v |= CHAN_ERR_RETRY;
172 v |= (cfg->u.rx.desc_type & DESC_TYPE_MASK) << DESC_TYPE_SHIFT;
173 if (cfg->u.rx.psinfo_at_sop)
174 v |= CHAN_PSINFO_AT_SOP;
175 v |= (cfg->u.rx.sop_offset & CHAN_SOP_OFF_MASK)
176 << CHAN_SOP_OFF_SHIFT;
177 v |= cfg->u.rx.dst_q & CHAN_QNUM_MASK;
178
179 writel_relaxed(v, &chan->reg_rx_flow->control);
180 writel_relaxed(0, &chan->reg_rx_flow->tags);
181 writel_relaxed(0, &chan->reg_rx_flow->tag_sel);
182
183 v = cfg->u.rx.fdq[0] << 16;
184 v |= cfg->u.rx.fdq[1] & CHAN_QNUM_MASK;
185 writel_relaxed(v, &chan->reg_rx_flow->fdq_sel[0]);
186
187 v = cfg->u.rx.fdq[2] << 16;
188 v |= cfg->u.rx.fdq[3] & CHAN_QNUM_MASK;
189 writel_relaxed(v, &chan->reg_rx_flow->fdq_sel[1]);
190
191 writel_relaxed(0, &chan->reg_rx_flow->thresh[0]);
192 writel_relaxed(0, &chan->reg_rx_flow->thresh[1]);
193 writel_relaxed(0, &chan->reg_rx_flow->thresh[2]);
194 }
195
196 /* Keep a copy of the cfg */
197 memcpy(&chan->cfg, cfg, sizeof(*cfg));
198 spin_unlock(&chan->lock);
199
200 return 0;
201}
202
203static int chan_teardown(struct knav_dma_chan *chan)
204{
205 unsigned long end, value;
206
207 if (!chan->reg_chan)
208 return 0;
209
210 /* indicate teardown */
211 writel_relaxed(DMA_TEARDOWN, &chan->reg_chan->control);
212
213 /* wait for the dma to shut itself down */
214 end = jiffies + msecs_to_jiffies(DMA_TIMEOUT);
215 do {
216 value = readl_relaxed(&chan->reg_chan->control);
217 if ((value & DMA_ENABLE) == 0)
218 break;
219 } while (time_after(end, jiffies));
220
221 if (readl_relaxed(&chan->reg_chan->control) & DMA_ENABLE) {
222 dev_err(kdev->dev, "timeout waiting for teardown\n");
223 return -ETIMEDOUT;
224 }
225
226 return 0;
227}
228
229static void chan_stop(struct knav_dma_chan *chan)
230{
231 spin_lock(&chan->lock);
232 if (chan->reg_rx_flow) {
233 /* first detach fdqs, starve out the flow */
234 writel_relaxed(0, &chan->reg_rx_flow->fdq_sel[0]);
235 writel_relaxed(0, &chan->reg_rx_flow->fdq_sel[1]);
236 writel_relaxed(0, &chan->reg_rx_flow->thresh[0]);
237 writel_relaxed(0, &chan->reg_rx_flow->thresh[1]);
238 writel_relaxed(0, &chan->reg_rx_flow->thresh[2]);
239 }
240
241 /* teardown the dma channel */
242 chan_teardown(chan);
243
244 /* then disconnect the completion side */
245 if (chan->reg_rx_flow) {
246 writel_relaxed(0, &chan->reg_rx_flow->control);
247 writel_relaxed(0, &chan->reg_rx_flow->tags);
248 writel_relaxed(0, &chan->reg_rx_flow->tag_sel);
249 }
250
251 memset(&chan->cfg, 0, sizeof(struct knav_dma_cfg));
252 spin_unlock(&chan->lock);
253
254 dev_dbg(kdev->dev, "channel stopped\n");
255}
256
257static void dma_hw_enable_all(struct knav_dma_device *dma)
258{
259 int i;
260
261 for (i = 0; i < dma->max_tx_chan; i++) {
262 writel_relaxed(0, &dma->reg_tx_chan[i].mode);
263 writel_relaxed(DMA_ENABLE, &dma->reg_tx_chan[i].control);
264 }
265}
266
267
268static void knav_dma_hw_init(struct knav_dma_device *dma)
269{
270 unsigned v;
271 int i;
272
273 spin_lock(&dma->lock);
274 v = dma->loopback ? DMA_LOOPBACK : 0;
275 writel_relaxed(v, &dma->reg_global->emulation_control);
276
277 v = readl_relaxed(&dma->reg_global->perf_control);
278 v |= ((dma->rx_timeout & DMA_RX_TIMEOUT_MASK) << DMA_RX_TIMEOUT_SHIFT);
279 writel_relaxed(v, &dma->reg_global->perf_control);
280
281 v = ((dma->tx_priority << DMA_TX_PRIO_SHIFT) |
282 (dma->rx_priority << DMA_RX_PRIO_SHIFT));
283
284 writel_relaxed(v, &dma->reg_global->priority_control);
285
286 /* Always enable all Rx channels. Rx paths are managed using flows */
287 for (i = 0; i < dma->max_rx_chan; i++)
288 writel_relaxed(DMA_ENABLE, &dma->reg_rx_chan[i].control);
289
290 for (i = 0; i < dma->logical_queue_managers; i++)
291 writel_relaxed(dma->qm_base_address[i],
292 &dma->reg_global->qm_base_address[i]);
293 spin_unlock(&dma->lock);
294}
295
296static void knav_dma_hw_destroy(struct knav_dma_device *dma)
297{
298 int i;
299 unsigned v;
300
301 spin_lock(&dma->lock);
302 v = ~DMA_ENABLE & REG_MASK;
303
304 for (i = 0; i < dma->max_rx_chan; i++)
305 writel_relaxed(v, &dma->reg_rx_chan[i].control);
306
307 for (i = 0; i < dma->max_tx_chan; i++)
308 writel_relaxed(v, &dma->reg_tx_chan[i].control);
309 spin_unlock(&dma->lock);
310}
311
312static void dma_debug_show_channels(struct seq_file *s,
313 struct knav_dma_chan *chan)
314{
315 int i;
316
317 seq_printf(s, "\t%s %d:\t",
318 ((chan->direction == DMA_MEM_TO_DEV) ? "tx chan" : "rx flow"),
319 chan_number(chan));
320
321 if (chan->direction == DMA_MEM_TO_DEV) {
322 seq_printf(s, "einfo - %d, pswords - %d, priority - %d\n",
323 chan->cfg.u.tx.filt_einfo,
324 chan->cfg.u.tx.filt_pswords,
325 chan->cfg.u.tx.priority);
326 } else {
327 seq_printf(s, "einfo - %d, psinfo - %d, desc_type - %d\n",
328 chan->cfg.u.rx.einfo_present,
329 chan->cfg.u.rx.psinfo_present,
330 chan->cfg.u.rx.desc_type);
331 seq_printf(s, "\t\t\tdst_q: [%d], thresh: %d fdq: ",
332 chan->cfg.u.rx.dst_q,
333 chan->cfg.u.rx.thresh);
334 for (i = 0; i < KNAV_DMA_FDQ_PER_CHAN; i++)
335 seq_printf(s, "[%d]", chan->cfg.u.rx.fdq[i]);
336 seq_printf(s, "\n");
337 }
338}
339
340static void dma_debug_show_devices(struct seq_file *s,
341 struct knav_dma_device *dma)
342{
343 struct knav_dma_chan *chan;
344
345 list_for_each_entry(chan, &dma->chan_list, list) {
346 if (atomic_read(&chan->ref_count))
347 dma_debug_show_channels(s, chan);
348 }
349}
350
351static int dma_debug_show(struct seq_file *s, void *v)
352{
353 struct knav_dma_device *dma;
354
355 list_for_each_entry(dma, &kdev->list, list) {
356 if (atomic_read(&dma->ref_count)) {
357 seq_printf(s, "%s : max_tx_chan: (%d), max_rx_flows: (%d)\n",
358 dma->name, dma->max_tx_chan, dma->max_rx_flow);
359 dma_debug_show_devices(s, dma);
360 }
361 }
362
363 return 0;
364}
365
366static int knav_dma_debug_open(struct inode *inode, struct file *file)
367{
368 return single_open(file, dma_debug_show, NULL);
369}
370
371static const struct file_operations knav_dma_debug_ops = {
372 .open = knav_dma_debug_open,
373 .read = seq_read,
374 .llseek = seq_lseek,
375 .release = single_release,
376};
377
378static int of_channel_match_helper(struct device_node *np, const char *name,
379 const char **dma_instance)
380{
381 struct of_phandle_args args;
382 struct device_node *dma_node;
383 int index;
384
385 dma_node = of_parse_phandle(np, "ti,navigator-dmas", 0);
386 if (!dma_node)
387 return -ENODEV;
388
389 *dma_instance = dma_node->name;
390 index = of_property_match_string(np, "ti,navigator-dma-names", name);
391 if (index < 0) {
392 dev_err(kdev->dev, "No 'ti,navigator-dma-names' propery\n");
393 return -ENODEV;
394 }
395
396 if (of_parse_phandle_with_fixed_args(np, "ti,navigator-dmas",
397 1, index, &args)) {
398 dev_err(kdev->dev, "Missing the pahndle args name %s\n", name);
399 return -ENODEV;
400 }
401
402 if (args.args[0] < 0) {
403 dev_err(kdev->dev, "Missing args for %s\n", name);
404 return -ENODEV;
405 }
406
407 return args.args[0];
408}
409
410/**
411 * knav_dma_open_channel() - try to setup an exclusive slave channel
412 * @dev: pointer to client device structure
413 * @name: slave channel name
414 * @config: dma configuration parameters
415 *
416 * Returns pointer to appropriate DMA channel on success or NULL.
417 */
418void *knav_dma_open_channel(struct device *dev, const char *name,
419 struct knav_dma_cfg *config)
420{
421 struct knav_dma_chan *chan;
422 struct knav_dma_device *dma;
423 bool found = false;
424 int chan_num = -1;
425 const char *instance;
426
427 if (!kdev) {
428 pr_err("keystone-navigator-dma driver not registered\n");
429 return (void *)-EINVAL;
430 }
431
432 chan_num = of_channel_match_helper(dev->of_node, name, &instance);
433 if (chan_num < 0) {
434 dev_err(kdev->dev, "No DMA instace with name %s\n", name);
435 return (void *)-EINVAL;
436 }
437
438 dev_dbg(kdev->dev, "initializing %s channel %d from DMA %s\n",
439 config->direction == DMA_MEM_TO_DEV ? "transmit" :
440 config->direction == DMA_DEV_TO_MEM ? "receive" :
441 "unknown", chan_num, instance);
442
443 if (config->direction != DMA_MEM_TO_DEV &&
444 config->direction != DMA_DEV_TO_MEM) {
445 dev_err(kdev->dev, "bad direction\n");
446 return (void *)-EINVAL;
447 }
448
449 /* Look for correct dma instance */
450 list_for_each_entry(dma, &kdev->list, list) {
451 if (!strcmp(dma->name, instance)) {
452 found = true;
453 break;
454 }
455 }
456 if (!found) {
457 dev_err(kdev->dev, "No DMA instace with name %s\n", instance);
458 return (void *)-EINVAL;
459 }
460
461 /* Look for correct dma channel from dma instance */
462 found = false;
463 list_for_each_entry(chan, &dma->chan_list, list) {
464 if (config->direction == DMA_MEM_TO_DEV) {
465 if (chan->channel == chan_num) {
466 found = true;
467 break;
468 }
469 } else {
470 if (chan->flow == chan_num) {
471 found = true;
472 break;
473 }
474 }
475 }
476 if (!found) {
477 dev_err(kdev->dev, "channel %d is not in DMA %s\n",
478 chan_num, instance);
479 return (void *)-EINVAL;
480 }
481
482 if (atomic_read(&chan->ref_count) >= 1) {
483 if (!check_config(chan, config)) {
484 dev_err(kdev->dev, "channel %d config miss-match\n",
485 chan_num);
486 return (void *)-EINVAL;
487 }
488 }
489
490 if (atomic_inc_return(&chan->dma->ref_count) <= 1)
491 knav_dma_hw_init(chan->dma);
492
493 if (atomic_inc_return(&chan->ref_count) <= 1)
494 chan_start(chan, config);
495
496 dev_dbg(kdev->dev, "channel %d opened from DMA %s\n",
497 chan_num, instance);
498
499 return chan;
500}
501EXPORT_SYMBOL_GPL(knav_dma_open_channel);
502
503/**
504 * knav_dma_close_channel() - Destroy a dma channel
505 *
506 * channel: dma channel handle
507 *
508 */
509void knav_dma_close_channel(void *channel)
510{
511 struct knav_dma_chan *chan = channel;
512
513 if (!kdev) {
514 pr_err("keystone-navigator-dma driver not registered\n");
515 return;
516 }
517
518 if (atomic_dec_return(&chan->ref_count) <= 0)
519 chan_stop(chan);
520
521 if (atomic_dec_return(&chan->dma->ref_count) <= 0)
522 knav_dma_hw_destroy(chan->dma);
523
524 dev_dbg(kdev->dev, "channel %d or flow %d closed from DMA %s\n",
525 chan->channel, chan->flow, chan->dma->name);
526}
527EXPORT_SYMBOL_GPL(knav_dma_close_channel);
528
529static void __iomem *pktdma_get_regs(struct knav_dma_device *dma,
530 struct device_node *node,
531 unsigned index, resource_size_t *_size)
532{
533 struct device *dev = kdev->dev;
534 struct resource res;
535 void __iomem *regs;
536 int ret;
537
538 ret = of_address_to_resource(node, index, &res);
539 if (ret) {
540 dev_err(dev, "Can't translate of node(%s) address for index(%d)\n",
541 node->name, index);
542 return ERR_PTR(ret);
543 }
544
545 regs = devm_ioremap_resource(kdev->dev, &res);
546 if (IS_ERR(regs))
547 dev_err(dev, "Failed to map register base for index(%d) node(%s)\n",
548 index, node->name);
549 if (_size)
550 *_size = resource_size(&res);
551
552 return regs;
553}
554
555static int pktdma_init_rx_chan(struct knav_dma_chan *chan, u32 flow)
556{
557 struct knav_dma_device *dma = chan->dma;
558
559 chan->flow = flow;
560 chan->reg_rx_flow = dma->reg_rx_flow + flow;
561 chan->channel = DMA_INVALID_ID;
562 dev_dbg(kdev->dev, "rx flow(%d) (%p)\n", chan->flow, chan->reg_rx_flow);
563
564 return 0;
565}
566
567static int pktdma_init_tx_chan(struct knav_dma_chan *chan, u32 channel)
568{
569 struct knav_dma_device *dma = chan->dma;
570
571 chan->channel = channel;
572 chan->reg_chan = dma->reg_tx_chan + channel;
573 chan->reg_tx_sched = dma->reg_tx_sched + channel;
574 chan->flow = DMA_INVALID_ID;
575 dev_dbg(kdev->dev, "tx channel(%d) (%p)\n", chan->channel, chan->reg_chan);
576
577 return 0;
578}
579
580static int pktdma_init_chan(struct knav_dma_device *dma,
581 enum dma_transfer_direction dir,
582 unsigned chan_num)
583{
584 struct device *dev = kdev->dev;
585 struct knav_dma_chan *chan;
586 int ret = -EINVAL;
587
588 chan = devm_kzalloc(dev, sizeof(*chan), GFP_KERNEL);
589 if (!chan)
590 return -ENOMEM;
591
592 INIT_LIST_HEAD(&chan->list);
593 chan->dma = dma;
594 chan->direction = DMA_NONE;
595 atomic_set(&chan->ref_count, 0);
596 spin_lock_init(&chan->lock);
597
598 if (dir == DMA_MEM_TO_DEV) {
599 chan->direction = dir;
600 ret = pktdma_init_tx_chan(chan, chan_num);
601 } else if (dir == DMA_DEV_TO_MEM) {
602 chan->direction = dir;
603 ret = pktdma_init_rx_chan(chan, chan_num);
604 } else {
605 dev_err(dev, "channel(%d) direction unknown\n", chan_num);
606 }
607
608 list_add_tail(&chan->list, &dma->chan_list);
609
610 return ret;
611}
612
613static int dma_init(struct device_node *cloud, struct device_node *dma_node)
614{
615 unsigned max_tx_chan, max_rx_chan, max_rx_flow, max_tx_sched;
616 struct device_node *node = dma_node;
617 struct knav_dma_device *dma;
618 int ret, len, num_chan = 0;
619 resource_size_t size;
620 u32 timeout;
621 u32 i;
622
623 dma = devm_kzalloc(kdev->dev, sizeof(*dma), GFP_KERNEL);
624 if (!dma) {
625 dev_err(kdev->dev, "could not allocate driver mem\n");
626 return -ENOMEM;
627 }
628 INIT_LIST_HEAD(&dma->list);
629 INIT_LIST_HEAD(&dma->chan_list);
630
631 if (!of_find_property(cloud, "ti,navigator-cloud-address", &len)) {
632 dev_err(kdev->dev, "unspecified navigator cloud addresses\n");
633 return -ENODEV;
634 }
635
636 dma->logical_queue_managers = len / sizeof(u32);
637 if (dma->logical_queue_managers > DMA_MAX_QMS) {
638 dev_warn(kdev->dev, "too many queue mgrs(>%d) rest ignored\n",
639 dma->logical_queue_managers);
640 dma->logical_queue_managers = DMA_MAX_QMS;
641 }
642
643 ret = of_property_read_u32_array(cloud, "ti,navigator-cloud-address",
644 dma->qm_base_address,
645 dma->logical_queue_managers);
646 if (ret) {
647 dev_err(kdev->dev, "invalid navigator cloud addresses\n");
648 return -ENODEV;
649 }
650
651 dma->reg_global = pktdma_get_regs(dma, node, 0, &size);
652 if (!dma->reg_global)
653 return -ENODEV;
654 if (size < sizeof(struct reg_global)) {
655 dev_err(kdev->dev, "bad size %pa for global regs\n", &size);
656 return -ENODEV;
657 }
658
659 dma->reg_tx_chan = pktdma_get_regs(dma, node, 1, &size);
660 if (!dma->reg_tx_chan)
661 return -ENODEV;
662
663 max_tx_chan = size / sizeof(struct reg_chan);
664 dma->reg_rx_chan = pktdma_get_regs(dma, node, 2, &size);
665 if (!dma->reg_rx_chan)
666 return -ENODEV;
667
668 max_rx_chan = size / sizeof(struct reg_chan);
669 dma->reg_tx_sched = pktdma_get_regs(dma, node, 3, &size);
670 if (!dma->reg_tx_sched)
671 return -ENODEV;
672
673 max_tx_sched = size / sizeof(struct reg_tx_sched);
674 dma->reg_rx_flow = pktdma_get_regs(dma, node, 4, &size);
675 if (!dma->reg_rx_flow)
676 return -ENODEV;
677
678 max_rx_flow = size / sizeof(struct reg_rx_flow);
679 dma->rx_priority = DMA_PRIO_DEFAULT;
680 dma->tx_priority = DMA_PRIO_DEFAULT;
681
682 dma->enable_all = (of_get_property(node, "ti,enable-all", NULL) != NULL);
683 dma->loopback = (of_get_property(node, "ti,loop-back", NULL) != NULL);
684
685 ret = of_property_read_u32(node, "ti,rx-retry-timeout", &timeout);
686 if (ret < 0) {
687 dev_dbg(kdev->dev, "unspecified rx timeout using value %d\n",
688 DMA_RX_TIMEOUT_DEFAULT);
689 timeout = DMA_RX_TIMEOUT_DEFAULT;
690 }
691
692 dma->rx_timeout = timeout;
693 dma->max_rx_chan = max_rx_chan;
694 dma->max_rx_flow = max_rx_flow;
695 dma->max_tx_chan = min(max_tx_chan, max_tx_sched);
696 atomic_set(&dma->ref_count, 0);
697 strcpy(dma->name, node->name);
698 spin_lock_init(&dma->lock);
699
700 for (i = 0; i < dma->max_tx_chan; i++) {
701 if (pktdma_init_chan(dma, DMA_MEM_TO_DEV, i) >= 0)
702 num_chan++;
703 }
704
705 for (i = 0; i < dma->max_rx_flow; i++) {
706 if (pktdma_init_chan(dma, DMA_DEV_TO_MEM, i) >= 0)
707 num_chan++;
708 }
709
710 list_add_tail(&dma->list, &kdev->list);
711
712 /*
713 * For DSP software usecases or userpace transport software, setup all
714 * the DMA hardware resources.
715 */
716 if (dma->enable_all) {
717 atomic_inc(&dma->ref_count);
718 knav_dma_hw_init(dma);
719 dma_hw_enable_all(dma);
720 }
721
722 dev_info(kdev->dev, "DMA %s registered %d logical channels, flows %d, tx chans: %d, rx chans: %d%s\n",
723 dma->name, num_chan, dma->max_rx_flow,
724 dma->max_tx_chan, dma->max_rx_chan,
725 dma->loopback ? ", loopback" : "");
726
727 return 0;
728}
729
730static int knav_dma_probe(struct platform_device *pdev)
731{
732 struct device *dev = &pdev->dev;
733 struct device_node *node = pdev->dev.of_node;
734 struct device_node *child;
735 int ret = 0;
736
737 if (!node) {
738 dev_err(&pdev->dev, "could not find device info\n");
739 return -EINVAL;
740 }
741
742 kdev = devm_kzalloc(dev,
743 sizeof(struct knav_dma_pool_device), GFP_KERNEL);
744 if (!kdev) {
745 dev_err(dev, "could not allocate driver mem\n");
746 return -ENOMEM;
747 }
748
749 kdev->dev = dev;
750 INIT_LIST_HEAD(&kdev->list);
751
752 pm_runtime_enable(kdev->dev);
753 ret = pm_runtime_get_sync(kdev->dev);
754 if (ret < 0) {
755 dev_err(kdev->dev, "unable to enable pktdma, err %d\n", ret);
756 return ret;
757 }
758
759 /* Initialise all packet dmas */
760 for_each_child_of_node(node, child) {
761 ret = dma_init(node, child);
762 if (ret) {
763 dev_err(&pdev->dev, "init failed with %d\n", ret);
764 break;
765 }
766 }
767
768 if (list_empty(&kdev->list)) {
769 dev_err(dev, "no valid dma instance\n");
770 return -ENODEV;
771 }
772
773 debugfs_create_file("knav_dma", S_IFREG | S_IRUGO, NULL, NULL,
774 &knav_dma_debug_ops);
775
776 return ret;
777}
778
779static int knav_dma_remove(struct platform_device *pdev)
780{
781 struct knav_dma_device *dma;
782
783 list_for_each_entry(dma, &kdev->list, list) {
784 if (atomic_dec_return(&dma->ref_count) == 0)
785 knav_dma_hw_destroy(dma);
786 }
787
788 pm_runtime_put_sync(&pdev->dev);
789 pm_runtime_disable(&pdev->dev);
790
791 return 0;
792}
793
794static struct of_device_id of_match[] = {
795 { .compatible = "ti,keystone-navigator-dma", },
796 {},
797};
798
799MODULE_DEVICE_TABLE(of, of_match);
800
801static struct platform_driver knav_dma_driver = {
802 .probe = knav_dma_probe,
803 .remove = knav_dma_remove,
804 .driver = {
805 .name = "keystone-navigator-dma",
806 .owner = THIS_MODULE,
807 .of_match_table = of_match,
808 },
809};
810module_platform_driver(knav_dma_driver);
811
812MODULE_LICENSE("GPL v2");
813MODULE_DESCRIPTION("TI Keystone Navigator Packet DMA driver");
814MODULE_AUTHOR("Sandeep Nair <sandeep_n@ti.com>");
815MODULE_AUTHOR("Santosh Shilimkar <santosh.shilimkar@ti.com>");
diff --git a/drivers/soc/ti/knav_qmss.h b/drivers/soc/ti/knav_qmss.h
new file mode 100644
index 000000000000..bc9dcc8cc3ce
--- /dev/null
+++ b/drivers/soc/ti/knav_qmss.h
@@ -0,0 +1,386 @@
1/*
2 * Keystone Navigator QMSS driver internal header
3 *
4 * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
5 * Author: Sandeep Nair <sandeep_n@ti.com>
6 * Cyril Chemparathy <cyril@ti.com>
7 * Santosh Shilimkar <santosh.shilimkar@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 */
18
19#ifndef __KNAV_QMSS_H__
20#define __KNAV_QMSS_H__
21
22#define THRESH_GTE BIT(7)
23#define THRESH_LT 0
24
25#define PDSP_CTRL_PC_MASK 0xffff0000
26#define PDSP_CTRL_SOFT_RESET BIT(0)
27#define PDSP_CTRL_ENABLE BIT(1)
28#define PDSP_CTRL_RUNNING BIT(15)
29
30#define ACC_MAX_CHANNEL 48
31#define ACC_DEFAULT_PERIOD 25 /* usecs */
32
33#define ACC_CHANNEL_INT_BASE 2
34
35#define ACC_LIST_ENTRY_TYPE 1
36#define ACC_LIST_ENTRY_WORDS (1 << ACC_LIST_ENTRY_TYPE)
37#define ACC_LIST_ENTRY_QUEUE_IDX 0
38#define ACC_LIST_ENTRY_DESC_IDX (ACC_LIST_ENTRY_WORDS - 1)
39
40#define ACC_CMD_DISABLE_CHANNEL 0x80
41#define ACC_CMD_ENABLE_CHANNEL 0x81
42#define ACC_CFG_MULTI_QUEUE BIT(21)
43
44#define ACC_INTD_OFFSET_EOI (0x0010)
45#define ACC_INTD_OFFSET_COUNT(ch) (0x0300 + 4 * (ch))
46#define ACC_INTD_OFFSET_STATUS(ch) (0x0200 + 4 * ((ch) / 32))
47
48#define RANGE_MAX_IRQS 64
49
50#define ACC_DESCS_MAX SZ_1K
51#define ACC_DESCS_MASK (ACC_DESCS_MAX - 1)
52#define DESC_SIZE_MASK 0xful
53#define DESC_PTR_MASK (~DESC_SIZE_MASK)
54
55#define KNAV_NAME_SIZE 32
56
57enum knav_acc_result {
58 ACC_RET_IDLE,
59 ACC_RET_SUCCESS,
60 ACC_RET_INVALID_COMMAND,
61 ACC_RET_INVALID_CHANNEL,
62 ACC_RET_INACTIVE_CHANNEL,
63 ACC_RET_ACTIVE_CHANNEL,
64 ACC_RET_INVALID_QUEUE,
65 ACC_RET_INVALID_RET,
66};
67
68struct knav_reg_config {
69 u32 revision;
70 u32 __pad1;
71 u32 divert;
72 u32 link_ram_base0;
73 u32 link_ram_size0;
74 u32 link_ram_base1;
75 u32 __pad2[2];
76 u32 starvation[0];
77};
78
79struct knav_reg_region {
80 u32 base;
81 u32 start_index;
82 u32 size_count;
83 u32 __pad;
84};
85
86struct knav_reg_pdsp_regs {
87 u32 control;
88 u32 status;
89 u32 cycle_count;
90 u32 stall_count;
91};
92
93struct knav_reg_acc_command {
94 u32 command;
95 u32 queue_mask;
96 u32 list_phys;
97 u32 queue_num;
98 u32 timer_config;
99};
100
101struct knav_link_ram_block {
102 dma_addr_t phys;
103 void *virt;
104 size_t size;
105};
106
107struct knav_acc_info {
108 u32 pdsp_id;
109 u32 start_channel;
110 u32 list_entries;
111 u32 pacing_mode;
112 u32 timer_count;
113 int mem_size;
114 int list_size;
115 struct knav_pdsp_info *pdsp;
116};
117
118struct knav_acc_channel {
119 u32 channel;
120 u32 list_index;
121 u32 open_mask;
122 u32 *list_cpu[2];
123 dma_addr_t list_dma[2];
124 char name[KNAV_NAME_SIZE];
125 atomic_t retrigger_count;
126};
127
128struct knav_pdsp_info {
129 const char *name;
130 struct knav_reg_pdsp_regs __iomem *regs;
131 union {
132 void __iomem *command;
133 struct knav_reg_acc_command __iomem *acc_command;
134 u32 __iomem *qos_command;
135 };
136 void __iomem *intd;
137 u32 __iomem *iram;
138 const char *firmware;
139 u32 id;
140 struct list_head list;
141};
142
143struct knav_qmgr_info {
144 unsigned start_queue;
145 unsigned num_queues;
146 struct knav_reg_config __iomem *reg_config;
147 struct knav_reg_region __iomem *reg_region;
148 struct knav_reg_queue __iomem *reg_push, *reg_pop, *reg_peek;
149 void __iomem *reg_status;
150 struct list_head list;
151};
152
153#define KNAV_NUM_LINKRAM 2
154
155/**
156 * struct knav_queue_stats: queue statistics
157 * pushes: number of push operations
158 * pops: number of pop operations
159 * push_errors: number of push errors
160 * pop_errors: number of pop errors
161 * notifies: notifier counts
162 */
163struct knav_queue_stats {
164 atomic_t pushes;
165 atomic_t pops;
166 atomic_t push_errors;
167 atomic_t pop_errors;
168 atomic_t notifies;
169};
170
171/**
172 * struct knav_reg_queue: queue registers
173 * @entry_count: valid entries in the queue
174 * @byte_count: total byte count in thhe queue
175 * @packet_size: packet size for the queue
176 * @ptr_size_thresh: packet pointer size threshold
177 */
178struct knav_reg_queue {
179 u32 entry_count;
180 u32 byte_count;
181 u32 packet_size;
182 u32 ptr_size_thresh;
183};
184
185/**
186 * struct knav_region: qmss region info
187 * @dma_start, dma_end: start and end dma address
188 * @virt_start, virt_end: start and end virtual address
189 * @desc_size: descriptor size
190 * @used_desc: consumed descriptors
191 * @id: region number
192 * @num_desc: total descriptors
193 * @link_index: index of the first descriptor
194 * @name: region name
195 * @list: instance in the device's region list
196 * @pools: list of descriptor pools in the region
197 */
198struct knav_region {
199 dma_addr_t dma_start, dma_end;
200 void *virt_start, *virt_end;
201 unsigned desc_size;
202 unsigned used_desc;
203 unsigned id;
204 unsigned num_desc;
205 unsigned link_index;
206 const char *name;
207 struct list_head list;
208 struct list_head pools;
209};
210
211/**
212 * struct knav_pool: qmss pools
213 * @dev: device pointer
214 * @region: qmss region info
215 * @queue: queue registers
216 * @kdev: qmss device pointer
217 * @region_offset: offset from the base
218 * @num_desc: total descriptors
219 * @desc_size: descriptor size
220 * @region_id: region number
221 * @name: pool name
222 * @list: list head
223 * @region_inst: instance in the region's pool list
224 */
225struct knav_pool {
226 struct device *dev;
227 struct knav_region *region;
228 struct knav_queue *queue;
229 struct knav_device *kdev;
230 int region_offset;
231 int num_desc;
232 int desc_size;
233 int region_id;
234 const char *name;
235 struct list_head list;
236 struct list_head region_inst;
237};
238
239/**
240 * struct knav_queue_inst: qmss queue instace properties
241 * @descs: descriptor pointer
242 * @desc_head, desc_tail, desc_count: descriptor counters
243 * @acc: accumulator channel pointer
244 * @kdev: qmss device pointer
245 * @range: range info
246 * @qmgr: queue manager info
247 * @id: queue instace id
248 * @irq_num: irq line number
249 * @notify_needed: notifier needed based on queue type
250 * @num_notifiers: total notifiers
251 * @handles: list head
252 * @name: queue instance name
253 * @irq_name: irq line name
254 */
255struct knav_queue_inst {
256 u32 *descs;
257 atomic_t desc_head, desc_tail, desc_count;
258 struct knav_acc_channel *acc;
259 struct knav_device *kdev;
260 struct knav_range_info *range;
261 struct knav_qmgr_info *qmgr;
262 u32 id;
263 int irq_num;
264 int notify_needed;
265 atomic_t num_notifiers;
266 struct list_head handles;
267 const char *name;
268 const char *irq_name;
269};
270
271/**
272 * struct knav_queue: qmss queue properties
273 * @reg_push, reg_pop, reg_peek: push, pop queue registers
274 * @inst: qmss queue instace properties
275 * @notifier_fn: notifier function
276 * @notifier_fn_arg: notifier function argument
277 * @notifier_enabled: notier enabled for a give queue
278 * @rcu: rcu head
279 * @flags: queue flags
280 * @list: list head
281 */
282struct knav_queue {
283 struct knav_reg_queue __iomem *reg_push, *reg_pop, *reg_peek;
284 struct knav_queue_inst *inst;
285 struct knav_queue_stats stats;
286 knav_queue_notify_fn notifier_fn;
287 void *notifier_fn_arg;
288 atomic_t notifier_enabled;
289 struct rcu_head rcu;
290 unsigned flags;
291 struct list_head list;
292};
293
294struct knav_device {
295 struct device *dev;
296 unsigned base_id;
297 unsigned num_queues;
298 unsigned num_queues_in_use;
299 unsigned inst_shift;
300 struct knav_link_ram_block link_rams[KNAV_NUM_LINKRAM];
301 void *instances;
302 struct list_head regions;
303 struct list_head queue_ranges;
304 struct list_head pools;
305 struct list_head pdsps;
306 struct list_head qmgrs;
307};
308
309struct knav_range_ops {
310 int (*init_range)(struct knav_range_info *range);
311 int (*free_range)(struct knav_range_info *range);
312 int (*init_queue)(struct knav_range_info *range,
313 struct knav_queue_inst *inst);
314 int (*open_queue)(struct knav_range_info *range,
315 struct knav_queue_inst *inst, unsigned flags);
316 int (*close_queue)(struct knav_range_info *range,
317 struct knav_queue_inst *inst);
318 int (*set_notify)(struct knav_range_info *range,
319 struct knav_queue_inst *inst, bool enabled);
320};
321
322struct knav_irq_info {
323 int irq;
324 u32 cpu_map;
325};
326
327struct knav_range_info {
328 const char *name;
329 struct knav_device *kdev;
330 unsigned queue_base;
331 unsigned num_queues;
332 void *queue_base_inst;
333 unsigned flags;
334 struct list_head list;
335 struct knav_range_ops *ops;
336 struct knav_acc_info acc_info;
337 struct knav_acc_channel *acc;
338 unsigned num_irqs;
339 struct knav_irq_info irqs[RANGE_MAX_IRQS];
340};
341
342#define RANGE_RESERVED BIT(0)
343#define RANGE_HAS_IRQ BIT(1)
344#define RANGE_HAS_ACCUMULATOR BIT(2)
345#define RANGE_MULTI_QUEUE BIT(3)
346
347#define for_each_region(kdev, region) \
348 list_for_each_entry(region, &kdev->regions, list)
349
350#define first_region(kdev) \
351 list_first_entry(&kdev->regions, \
352 struct knav_region, list)
353
354#define for_each_queue_range(kdev, range) \
355 list_for_each_entry(range, &kdev->queue_ranges, list)
356
357#define first_queue_range(kdev) \
358 list_first_entry(&kdev->queue_ranges, \
359 struct knav_range_info, list)
360
361#define for_each_pool(kdev, pool) \
362 list_for_each_entry(pool, &kdev->pools, list)
363
364#define for_each_pdsp(kdev, pdsp) \
365 list_for_each_entry(pdsp, &kdev->pdsps, list)
366
367#define for_each_qmgr(kdev, qmgr) \
368 list_for_each_entry(qmgr, &kdev->qmgrs, list)
369
370static inline struct knav_pdsp_info *
371knav_find_pdsp(struct knav_device *kdev, unsigned pdsp_id)
372{
373 struct knav_pdsp_info *pdsp;
374
375 for_each_pdsp(kdev, pdsp)
376 if (pdsp_id == pdsp->id)
377 return pdsp;
378 return NULL;
379}
380
381extern int knav_init_acc_range(struct knav_device *kdev,
382 struct device_node *node,
383 struct knav_range_info *range);
384extern void knav_queue_notify(struct knav_queue_inst *inst);
385
386#endif /* __KNAV_QMSS_H__ */
diff --git a/drivers/soc/ti/knav_qmss_acc.c b/drivers/soc/ti/knav_qmss_acc.c
new file mode 100644
index 000000000000..6fbfde6e748f
--- /dev/null
+++ b/drivers/soc/ti/knav_qmss_acc.c
@@ -0,0 +1,591 @@
1/*
2 * Keystone accumulator queue manager
3 *
4 * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
5 * Author: Sandeep Nair <sandeep_n@ti.com>
6 * Cyril Chemparathy <cyril@ti.com>
7 * Santosh Shilimkar <santosh.shilimkar@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 */
18
19#include <linux/kernel.h>
20#include <linux/module.h>
21#include <linux/device.h>
22#include <linux/io.h>
23#include <linux/interrupt.h>
24#include <linux/bitops.h>
25#include <linux/slab.h>
26#include <linux/spinlock.h>
27#include <linux/soc/ti/knav_qmss.h>
28#include <linux/platform_device.h>
29#include <linux/dma-mapping.h>
30#include <linux/of.h>
31#include <linux/of_device.h>
32#include <linux/of_address.h>
33#include <linux/firmware.h>
34
35#include "knav_qmss.h"
36
37#define knav_range_offset_to_inst(kdev, range, q) \
38 (range->queue_base_inst + (q << kdev->inst_shift))
39
40static void __knav_acc_notify(struct knav_range_info *range,
41 struct knav_acc_channel *acc)
42{
43 struct knav_device *kdev = range->kdev;
44 struct knav_queue_inst *inst;
45 int range_base, queue;
46
47 range_base = kdev->base_id + range->queue_base;
48
49 if (range->flags & RANGE_MULTI_QUEUE) {
50 for (queue = 0; queue < range->num_queues; queue++) {
51 inst = knav_range_offset_to_inst(kdev, range,
52 queue);
53 if (inst->notify_needed) {
54 inst->notify_needed = 0;
55 dev_dbg(kdev->dev, "acc-irq: notifying %d\n",
56 range_base + queue);
57 knav_queue_notify(inst);
58 }
59 }
60 } else {
61 queue = acc->channel - range->acc_info.start_channel;
62 inst = knav_range_offset_to_inst(kdev, range, queue);
63 dev_dbg(kdev->dev, "acc-irq: notifying %d\n",
64 range_base + queue);
65 knav_queue_notify(inst);
66 }
67}
68
69static int knav_acc_set_notify(struct knav_range_info *range,
70 struct knav_queue_inst *kq,
71 bool enabled)
72{
73 struct knav_pdsp_info *pdsp = range->acc_info.pdsp;
74 struct knav_device *kdev = range->kdev;
75 u32 mask, offset;
76
77 /*
78 * when enabling, we need to re-trigger an interrupt if we
79 * have descriptors pending
80 */
81 if (!enabled || atomic_read(&kq->desc_count) <= 0)
82 return 0;
83
84 kq->notify_needed = 1;
85 atomic_inc(&kq->acc->retrigger_count);
86 mask = BIT(kq->acc->channel % 32);
87 offset = ACC_INTD_OFFSET_STATUS(kq->acc->channel);
88 dev_dbg(kdev->dev, "setup-notify: re-triggering irq for %s\n",
89 kq->acc->name);
90 writel_relaxed(mask, pdsp->intd + offset);
91 return 0;
92}
93
94static irqreturn_t knav_acc_int_handler(int irq, void *_instdata)
95{
96 struct knav_acc_channel *acc;
97 struct knav_queue_inst *kq = NULL;
98 struct knav_range_info *range;
99 struct knav_pdsp_info *pdsp;
100 struct knav_acc_info *info;
101 struct knav_device *kdev;
102
103 u32 *list, *list_cpu, val, idx, notifies;
104 int range_base, channel, queue = 0;
105 dma_addr_t list_dma;
106
107 range = _instdata;
108 info = &range->acc_info;
109 kdev = range->kdev;
110 pdsp = range->acc_info.pdsp;
111 acc = range->acc;
112
113 range_base = kdev->base_id + range->queue_base;
114 if ((range->flags & RANGE_MULTI_QUEUE) == 0) {
115 for (queue = 0; queue < range->num_irqs; queue++)
116 if (range->irqs[queue].irq == irq)
117 break;
118 kq = knav_range_offset_to_inst(kdev, range, queue);
119 acc += queue;
120 }
121
122 channel = acc->channel;
123 list_dma = acc->list_dma[acc->list_index];
124 list_cpu = acc->list_cpu[acc->list_index];
125 dev_dbg(kdev->dev, "acc-irq: channel %d, list %d, virt %p, phys %x\n",
126 channel, acc->list_index, list_cpu, list_dma);
127 if (atomic_read(&acc->retrigger_count)) {
128 atomic_dec(&acc->retrigger_count);
129 __knav_acc_notify(range, acc);
130 writel_relaxed(1, pdsp->intd + ACC_INTD_OFFSET_COUNT(channel));
131 /* ack the interrupt */
132 writel_relaxed(ACC_CHANNEL_INT_BASE + channel,
133 pdsp->intd + ACC_INTD_OFFSET_EOI);
134
135 return IRQ_HANDLED;
136 }
137
138 notifies = readl_relaxed(pdsp->intd + ACC_INTD_OFFSET_COUNT(channel));
139 WARN_ON(!notifies);
140 dma_sync_single_for_cpu(kdev->dev, list_dma, info->list_size,
141 DMA_FROM_DEVICE);
142
143 for (list = list_cpu; list < list_cpu + (info->list_size / sizeof(u32));
144 list += ACC_LIST_ENTRY_WORDS) {
145 if (ACC_LIST_ENTRY_WORDS == 1) {
146 dev_dbg(kdev->dev,
147 "acc-irq: list %d, entry @%p, %08x\n",
148 acc->list_index, list, list[0]);
149 } else if (ACC_LIST_ENTRY_WORDS == 2) {
150 dev_dbg(kdev->dev,
151 "acc-irq: list %d, entry @%p, %08x %08x\n",
152 acc->list_index, list, list[0], list[1]);
153 } else if (ACC_LIST_ENTRY_WORDS == 4) {
154 dev_dbg(kdev->dev,
155 "acc-irq: list %d, entry @%p, %08x %08x %08x %08x\n",
156 acc->list_index, list, list[0], list[1],
157 list[2], list[3]);
158 }
159
160 val = list[ACC_LIST_ENTRY_DESC_IDX];
161 if (!val)
162 break;
163
164 if (range->flags & RANGE_MULTI_QUEUE) {
165 queue = list[ACC_LIST_ENTRY_QUEUE_IDX] >> 16;
166 if (queue < range_base ||
167 queue >= range_base + range->num_queues) {
168 dev_err(kdev->dev,
169 "bad queue %d, expecting %d-%d\n",
170 queue, range_base,
171 range_base + range->num_queues);
172 break;
173 }
174 queue -= range_base;
175 kq = knav_range_offset_to_inst(kdev, range,
176 queue);
177 }
178
179 if (atomic_inc_return(&kq->desc_count) >= ACC_DESCS_MAX) {
180 atomic_dec(&kq->desc_count);
181 dev_err(kdev->dev,
182 "acc-irq: queue %d full, entry dropped\n",
183 queue + range_base);
184 continue;
185 }
186
187 idx = atomic_inc_return(&kq->desc_tail) & ACC_DESCS_MASK;
188 kq->descs[idx] = val;
189 kq->notify_needed = 1;
190 dev_dbg(kdev->dev, "acc-irq: enqueue %08x at %d, queue %d\n",
191 val, idx, queue + range_base);
192 }
193
194 __knav_acc_notify(range, acc);
195 memset(list_cpu, 0, info->list_size);
196 dma_sync_single_for_device(kdev->dev, list_dma, info->list_size,
197 DMA_TO_DEVICE);
198
199 /* flip to the other list */
200 acc->list_index ^= 1;
201
202 /* reset the interrupt counter */
203 writel_relaxed(1, pdsp->intd + ACC_INTD_OFFSET_COUNT(channel));
204
205 /* ack the interrupt */
206 writel_relaxed(ACC_CHANNEL_INT_BASE + channel,
207 pdsp->intd + ACC_INTD_OFFSET_EOI);
208
209 return IRQ_HANDLED;
210}
211
212int knav_range_setup_acc_irq(struct knav_range_info *range,
213 int queue, bool enabled)
214{
215 struct knav_device *kdev = range->kdev;
216 struct knav_acc_channel *acc;
217 unsigned long cpu_map;
218 int ret = 0, irq;
219 u32 old, new;
220
221 if (range->flags & RANGE_MULTI_QUEUE) {
222 acc = range->acc;
223 irq = range->irqs[0].irq;
224 cpu_map = range->irqs[0].cpu_map;
225 } else {
226 acc = range->acc + queue;
227 irq = range->irqs[queue].irq;
228 cpu_map = range->irqs[queue].cpu_map;
229 }
230
231 old = acc->open_mask;
232 if (enabled)
233 new = old | BIT(queue);
234 else
235 new = old & ~BIT(queue);
236 acc->open_mask = new;
237
238 dev_dbg(kdev->dev,
239 "setup-acc-irq: open mask old %08x, new %08x, channel %s\n",
240 old, new, acc->name);
241
242 if (likely(new == old))
243 return 0;
244
245 if (new && !old) {
246 dev_dbg(kdev->dev,
247 "setup-acc-irq: requesting %s for channel %s\n",
248 acc->name, acc->name);
249 ret = request_irq(irq, knav_acc_int_handler, 0, acc->name,
250 range);
251 if (!ret && cpu_map) {
252 ret = irq_set_affinity_hint(irq, to_cpumask(&cpu_map));
253 if (ret) {
254 dev_warn(range->kdev->dev,
255 "Failed to set IRQ affinity\n");
256 return ret;
257 }
258 }
259 }
260
261 if (old && !new) {
262 dev_dbg(kdev->dev, "setup-acc-irq: freeing %s for channel %s\n",
263 acc->name, acc->name);
264 free_irq(irq, range);
265 }
266
267 return ret;
268}
269
270static const char *knav_acc_result_str(enum knav_acc_result result)
271{
272 static const char * const result_str[] = {
273 [ACC_RET_IDLE] = "idle",
274 [ACC_RET_SUCCESS] = "success",
275 [ACC_RET_INVALID_COMMAND] = "invalid command",
276 [ACC_RET_INVALID_CHANNEL] = "invalid channel",
277 [ACC_RET_INACTIVE_CHANNEL] = "inactive channel",
278 [ACC_RET_ACTIVE_CHANNEL] = "active channel",
279 [ACC_RET_INVALID_QUEUE] = "invalid queue",
280 [ACC_RET_INVALID_RET] = "invalid return code",
281 };
282
283 if (result >= ARRAY_SIZE(result_str))
284 return result_str[ACC_RET_INVALID_RET];
285 else
286 return result_str[result];
287}
288
289static enum knav_acc_result
290knav_acc_write(struct knav_device *kdev, struct knav_pdsp_info *pdsp,
291 struct knav_reg_acc_command *cmd)
292{
293 u32 result;
294
295 dev_dbg(kdev->dev, "acc command %08x %08x %08x %08x %08x\n",
296 cmd->command, cmd->queue_mask, cmd->list_phys,
297 cmd->queue_num, cmd->timer_config);
298
299 writel_relaxed(cmd->timer_config, &pdsp->acc_command->timer_config);
300 writel_relaxed(cmd->queue_num, &pdsp->acc_command->queue_num);
301 writel_relaxed(cmd->list_phys, &pdsp->acc_command->list_phys);
302 writel_relaxed(cmd->queue_mask, &pdsp->acc_command->queue_mask);
303 writel_relaxed(cmd->command, &pdsp->acc_command->command);
304
305 /* wait for the command to clear */
306 do {
307 result = readl_relaxed(&pdsp->acc_command->command);
308 } while ((result >> 8) & 0xff);
309
310 return (result >> 24) & 0xff;
311}
312
313static void knav_acc_setup_cmd(struct knav_device *kdev,
314 struct knav_range_info *range,
315 struct knav_reg_acc_command *cmd,
316 int queue)
317{
318 struct knav_acc_info *info = &range->acc_info;
319 struct knav_acc_channel *acc;
320 int queue_base;
321 u32 queue_mask;
322
323 if (range->flags & RANGE_MULTI_QUEUE) {
324 acc = range->acc;
325 queue_base = range->queue_base;
326 queue_mask = BIT(range->num_queues) - 1;
327 } else {
328 acc = range->acc + queue;
329 queue_base = range->queue_base + queue;
330 queue_mask = 0;
331 }
332
333 memset(cmd, 0, sizeof(*cmd));
334 cmd->command = acc->channel;
335 cmd->queue_mask = queue_mask;
336 cmd->list_phys = acc->list_dma[0];
337 cmd->queue_num = info->list_entries << 16;
338 cmd->queue_num |= queue_base;
339
340 cmd->timer_config = ACC_LIST_ENTRY_TYPE << 18;
341 if (range->flags & RANGE_MULTI_QUEUE)
342 cmd->timer_config |= ACC_CFG_MULTI_QUEUE;
343 cmd->timer_config |= info->pacing_mode << 16;
344 cmd->timer_config |= info->timer_count;
345}
346
347static void knav_acc_stop(struct knav_device *kdev,
348 struct knav_range_info *range,
349 int queue)
350{
351 struct knav_reg_acc_command cmd;
352 struct knav_acc_channel *acc;
353 enum knav_acc_result result;
354
355 acc = range->acc + queue;
356
357 knav_acc_setup_cmd(kdev, range, &cmd, queue);
358 cmd.command |= ACC_CMD_DISABLE_CHANNEL << 8;
359 result = knav_acc_write(kdev, range->acc_info.pdsp, &cmd);
360
361 dev_dbg(kdev->dev, "stopped acc channel %s, result %s\n",
362 acc->name, knav_acc_result_str(result));
363}
364
365static enum knav_acc_result knav_acc_start(struct knav_device *kdev,
366 struct knav_range_info *range,
367 int queue)
368{
369 struct knav_reg_acc_command cmd;
370 struct knav_acc_channel *acc;
371 enum knav_acc_result result;
372
373 acc = range->acc + queue;
374
375 knav_acc_setup_cmd(kdev, range, &cmd, queue);
376 cmd.command |= ACC_CMD_ENABLE_CHANNEL << 8;
377 result = knav_acc_write(kdev, range->acc_info.pdsp, &cmd);
378
379 dev_dbg(kdev->dev, "started acc channel %s, result %s\n",
380 acc->name, knav_acc_result_str(result));
381
382 return result;
383}
384
385static int knav_acc_init_range(struct knav_range_info *range)
386{
387 struct knav_device *kdev = range->kdev;
388 struct knav_acc_channel *acc;
389 enum knav_acc_result result;
390 int queue;
391
392 for (queue = 0; queue < range->num_queues; queue++) {
393 acc = range->acc + queue;
394
395 knav_acc_stop(kdev, range, queue);
396 acc->list_index = 0;
397 result = knav_acc_start(kdev, range, queue);
398
399 if (result != ACC_RET_SUCCESS)
400 return -EIO;
401
402 if (range->flags & RANGE_MULTI_QUEUE)
403 return 0;
404 }
405 return 0;
406}
407
408static int knav_acc_init_queue(struct knav_range_info *range,
409 struct knav_queue_inst *kq)
410{
411 unsigned id = kq->id - range->queue_base;
412
413 kq->descs = devm_kzalloc(range->kdev->dev,
414 ACC_DESCS_MAX * sizeof(u32), GFP_KERNEL);
415 if (!kq->descs)
416 return -ENOMEM;
417
418 kq->acc = range->acc;
419 if ((range->flags & RANGE_MULTI_QUEUE) == 0)
420 kq->acc += id;
421 return 0;
422}
423
424static int knav_acc_open_queue(struct knav_range_info *range,
425 struct knav_queue_inst *inst, unsigned flags)
426{
427 unsigned id = inst->id - range->queue_base;
428
429 return knav_range_setup_acc_irq(range, id, true);
430}
431
432static int knav_acc_close_queue(struct knav_range_info *range,
433 struct knav_queue_inst *inst)
434{
435 unsigned id = inst->id - range->queue_base;
436
437 return knav_range_setup_acc_irq(range, id, false);
438}
439
440static int knav_acc_free_range(struct knav_range_info *range)
441{
442 struct knav_device *kdev = range->kdev;
443 struct knav_acc_channel *acc;
444 struct knav_acc_info *info;
445 int channel, channels;
446
447 info = &range->acc_info;
448
449 if (range->flags & RANGE_MULTI_QUEUE)
450 channels = 1;
451 else
452 channels = range->num_queues;
453
454 for (channel = 0; channel < channels; channel++) {
455 acc = range->acc + channel;
456 if (!acc->list_cpu[0])
457 continue;
458 dma_unmap_single(kdev->dev, acc->list_dma[0],
459 info->mem_size, DMA_BIDIRECTIONAL);
460 free_pages_exact(acc->list_cpu[0], info->mem_size);
461 }
462 devm_kfree(range->kdev->dev, range->acc);
463 return 0;
464}
465
466struct knav_range_ops knav_acc_range_ops = {
467 .set_notify = knav_acc_set_notify,
468 .init_queue = knav_acc_init_queue,
469 .open_queue = knav_acc_open_queue,
470 .close_queue = knav_acc_close_queue,
471 .init_range = knav_acc_init_range,
472 .free_range = knav_acc_free_range,
473};
474
475/**
476 * knav_init_acc_range: Initialise accumulator ranges
477 *
478 * @kdev: qmss device
479 * @node: device node
480 * @range: qmms range information
481 *
482 * Return 0 on success or error
483 */
484int knav_init_acc_range(struct knav_device *kdev,
485 struct device_node *node,
486 struct knav_range_info *range)
487{
488 struct knav_acc_channel *acc;
489 struct knav_pdsp_info *pdsp;
490 struct knav_acc_info *info;
491 int ret, channel, channels;
492 int list_size, mem_size;
493 dma_addr_t list_dma;
494 void *list_mem;
495 u32 config[5];
496
497 range->flags |= RANGE_HAS_ACCUMULATOR;
498 info = &range->acc_info;
499
500 ret = of_property_read_u32_array(node, "accumulator", config, 5);
501 if (ret)
502 return ret;
503
504 info->pdsp_id = config[0];
505 info->start_channel = config[1];
506 info->list_entries = config[2];
507 info->pacing_mode = config[3];
508 info->timer_count = config[4] / ACC_DEFAULT_PERIOD;
509
510 if (info->start_channel > ACC_MAX_CHANNEL) {
511 dev_err(kdev->dev, "channel %d invalid for range %s\n",
512 info->start_channel, range->name);
513 return -EINVAL;
514 }
515
516 if (info->pacing_mode > 3) {
517 dev_err(kdev->dev, "pacing mode %d invalid for range %s\n",
518 info->pacing_mode, range->name);
519 return -EINVAL;
520 }
521
522 pdsp = knav_find_pdsp(kdev, info->pdsp_id);
523 if (!pdsp) {
524 dev_err(kdev->dev, "pdsp id %d not found for range %s\n",
525 info->pdsp_id, range->name);
526 return -EINVAL;
527 }
528
529 info->pdsp = pdsp;
530 channels = range->num_queues;
531 if (of_get_property(node, "multi-queue", NULL)) {
532 range->flags |= RANGE_MULTI_QUEUE;
533 channels = 1;
534 if (range->queue_base & (32 - 1)) {
535 dev_err(kdev->dev,
536 "misaligned multi-queue accumulator range %s\n",
537 range->name);
538 return -EINVAL;
539 }
540 if (range->num_queues > 32) {
541 dev_err(kdev->dev,
542 "too many queues in accumulator range %s\n",
543 range->name);
544 return -EINVAL;
545 }
546 }
547
548 /* figure out list size */
549 list_size = info->list_entries;
550 list_size *= ACC_LIST_ENTRY_WORDS * sizeof(u32);
551 info->list_size = list_size;
552 mem_size = PAGE_ALIGN(list_size * 2);
553 info->mem_size = mem_size;
554 range->acc = devm_kzalloc(kdev->dev, channels * sizeof(*range->acc),
555 GFP_KERNEL);
556 if (!range->acc)
557 return -ENOMEM;
558
559 for (channel = 0; channel < channels; channel++) {
560 acc = range->acc + channel;
561 acc->channel = info->start_channel + channel;
562
563 /* allocate memory for the two lists */
564 list_mem = alloc_pages_exact(mem_size, GFP_KERNEL | GFP_DMA);
565 if (!list_mem)
566 return -ENOMEM;
567
568 list_dma = dma_map_single(kdev->dev, list_mem, mem_size,
569 DMA_BIDIRECTIONAL);
570 if (dma_mapping_error(kdev->dev, list_dma)) {
571 free_pages_exact(list_mem, mem_size);
572 return -ENOMEM;
573 }
574
575 memset(list_mem, 0, mem_size);
576 dma_sync_single_for_device(kdev->dev, list_dma, mem_size,
577 DMA_TO_DEVICE);
578 scnprintf(acc->name, sizeof(acc->name), "hwqueue-acc-%d",
579 acc->channel);
580 acc->list_cpu[0] = list_mem;
581 acc->list_cpu[1] = list_mem + list_size;
582 acc->list_dma[0] = list_dma;
583 acc->list_dma[1] = list_dma + list_size;
584 dev_dbg(kdev->dev, "%s: channel %d, phys %08x, virt %8p\n",
585 acc->name, acc->channel, list_dma, list_mem);
586 }
587
588 range->ops = &knav_acc_range_ops;
589 return 0;
590}
591EXPORT_SYMBOL_GPL(knav_init_acc_range);
diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c
new file mode 100644
index 000000000000..0a2c8634c48b
--- /dev/null
+++ b/drivers/soc/ti/knav_qmss_queue.c
@@ -0,0 +1,1816 @@
1/*
2 * Keystone Queue Manager subsystem driver
3 *
4 * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
5 * Authors: Sandeep Nair <sandeep_n@ti.com>
6 * Cyril Chemparathy <cyril@ti.com>
7 * Santosh Shilimkar <santosh.shilimkar@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 */
18
19#include <linux/kernel.h>
20#include <linux/module.h>
21#include <linux/device.h>
22#include <linux/clk.h>
23#include <linux/io.h>
24#include <linux/interrupt.h>
25#include <linux/bitops.h>
26#include <linux/slab.h>
27#include <linux/spinlock.h>
28#include <linux/platform_device.h>
29#include <linux/dma-mapping.h>
30#include <linux/of.h>
31#include <linux/of_irq.h>
32#include <linux/of_device.h>
33#include <linux/of_address.h>
34#include <linux/pm_runtime.h>
35#include <linux/firmware.h>
36#include <linux/debugfs.h>
37#include <linux/seq_file.h>
38#include <linux/string.h>
39#include <linux/soc/ti/knav_qmss.h>
40
41#include "knav_qmss.h"
42
43static struct knav_device *kdev;
44static DEFINE_MUTEX(knav_dev_lock);
45
46/* Queue manager register indices in DTS */
47#define KNAV_QUEUE_PEEK_REG_INDEX 0
48#define KNAV_QUEUE_STATUS_REG_INDEX 1
49#define KNAV_QUEUE_CONFIG_REG_INDEX 2
50#define KNAV_QUEUE_REGION_REG_INDEX 3
51#define KNAV_QUEUE_PUSH_REG_INDEX 4
52#define KNAV_QUEUE_POP_REG_INDEX 5
53
54/* PDSP register indices in DTS */
55#define KNAV_QUEUE_PDSP_IRAM_REG_INDEX 0
56#define KNAV_QUEUE_PDSP_REGS_REG_INDEX 1
57#define KNAV_QUEUE_PDSP_INTD_REG_INDEX 2
58#define KNAV_QUEUE_PDSP_CMD_REG_INDEX 3
59
60#define knav_queue_idx_to_inst(kdev, idx) \
61 (kdev->instances + (idx << kdev->inst_shift))
62
63#define for_each_handle_rcu(qh, inst) \
64 list_for_each_entry_rcu(qh, &inst->handles, list)
65
66#define for_each_instance(idx, inst, kdev) \
67 for (idx = 0, inst = kdev->instances; \
68 idx < (kdev)->num_queues_in_use; \
69 idx++, inst = knav_queue_idx_to_inst(kdev, idx))
70
71/**
72 * knav_queue_notify: qmss queue notfier call
73 *
74 * @inst: qmss queue instance like accumulator
75 */
76void knav_queue_notify(struct knav_queue_inst *inst)
77{
78 struct knav_queue *qh;
79
80 if (!inst)
81 return;
82
83 rcu_read_lock();
84 for_each_handle_rcu(qh, inst) {
85 if (atomic_read(&qh->notifier_enabled) <= 0)
86 continue;
87 if (WARN_ON(!qh->notifier_fn))
88 continue;
89 atomic_inc(&qh->stats.notifies);
90 qh->notifier_fn(qh->notifier_fn_arg);
91 }
92 rcu_read_unlock();
93}
94EXPORT_SYMBOL_GPL(knav_queue_notify);
95
96static irqreturn_t knav_queue_int_handler(int irq, void *_instdata)
97{
98 struct knav_queue_inst *inst = _instdata;
99
100 knav_queue_notify(inst);
101 return IRQ_HANDLED;
102}
103
104static int knav_queue_setup_irq(struct knav_range_info *range,
105 struct knav_queue_inst *inst)
106{
107 unsigned queue = inst->id - range->queue_base;
108 unsigned long cpu_map;
109 int ret = 0, irq;
110
111 if (range->flags & RANGE_HAS_IRQ) {
112 irq = range->irqs[queue].irq;
113 cpu_map = range->irqs[queue].cpu_map;
114 ret = request_irq(irq, knav_queue_int_handler, 0,
115 inst->irq_name, inst);
116 if (ret)
117 return ret;
118 disable_irq(irq);
119 if (cpu_map) {
120 ret = irq_set_affinity_hint(irq, to_cpumask(&cpu_map));
121 if (ret) {
122 dev_warn(range->kdev->dev,
123 "Failed to set IRQ affinity\n");
124 return ret;
125 }
126 }
127 }
128 return ret;
129}
130
131static void knav_queue_free_irq(struct knav_queue_inst *inst)
132{
133 struct knav_range_info *range = inst->range;
134 unsigned queue = inst->id - inst->range->queue_base;
135 int irq;
136
137 if (range->flags & RANGE_HAS_IRQ) {
138 irq = range->irqs[queue].irq;
139 irq_set_affinity_hint(irq, NULL);
140 free_irq(irq, inst);
141 }
142}
143
144static inline bool knav_queue_is_busy(struct knav_queue_inst *inst)
145{
146 return !list_empty(&inst->handles);
147}
148
149static inline bool knav_queue_is_reserved(struct knav_queue_inst *inst)
150{
151 return inst->range->flags & RANGE_RESERVED;
152}
153
154static inline bool knav_queue_is_shared(struct knav_queue_inst *inst)
155{
156 struct knav_queue *tmp;
157
158 rcu_read_lock();
159 for_each_handle_rcu(tmp, inst) {
160 if (tmp->flags & KNAV_QUEUE_SHARED) {
161 rcu_read_unlock();
162 return true;
163 }
164 }
165 rcu_read_unlock();
166 return false;
167}
168
169static inline bool knav_queue_match_type(struct knav_queue_inst *inst,
170 unsigned type)
171{
172 if ((type == KNAV_QUEUE_QPEND) &&
173 (inst->range->flags & RANGE_HAS_IRQ)) {
174 return true;
175 } else if ((type == KNAV_QUEUE_ACC) &&
176 (inst->range->flags & RANGE_HAS_ACCUMULATOR)) {
177 return true;
178 } else if ((type == KNAV_QUEUE_GP) &&
179 !(inst->range->flags &
180 (RANGE_HAS_ACCUMULATOR | RANGE_HAS_IRQ))) {
181 return true;
182 }
183 return false;
184}
185
186static inline struct knav_queue_inst *
187knav_queue_match_id_to_inst(struct knav_device *kdev, unsigned id)
188{
189 struct knav_queue_inst *inst;
190 int idx;
191
192 for_each_instance(idx, inst, kdev) {
193 if (inst->id == id)
194 return inst;
195 }
196 return NULL;
197}
198
199static inline struct knav_queue_inst *knav_queue_find_by_id(int id)
200{
201 if (kdev->base_id <= id &&
202 kdev->base_id + kdev->num_queues > id) {
203 id -= kdev->base_id;
204 return knav_queue_match_id_to_inst(kdev, id);
205 }
206 return NULL;
207}
208
209static struct knav_queue *__knav_queue_open(struct knav_queue_inst *inst,
210 const char *name, unsigned flags)
211{
212 struct knav_queue *qh;
213 unsigned id;
214 int ret = 0;
215
216 qh = devm_kzalloc(inst->kdev->dev, sizeof(*qh), GFP_KERNEL);
217 if (!qh)
218 return ERR_PTR(-ENOMEM);
219
220 qh->flags = flags;
221 qh->inst = inst;
222 id = inst->id - inst->qmgr->start_queue;
223 qh->reg_push = &inst->qmgr->reg_push[id];
224 qh->reg_pop = &inst->qmgr->reg_pop[id];
225 qh->reg_peek = &inst->qmgr->reg_peek[id];
226
227 /* first opener? */
228 if (!knav_queue_is_busy(inst)) {
229 struct knav_range_info *range = inst->range;
230
231 inst->name = kstrndup(name, KNAV_NAME_SIZE, GFP_KERNEL);
232 if (range->ops && range->ops->open_queue)
233 ret = range->ops->open_queue(range, inst, flags);
234
235 if (ret) {
236 devm_kfree(inst->kdev->dev, qh);
237 return ERR_PTR(ret);
238 }
239 }
240 list_add_tail_rcu(&qh->list, &inst->handles);
241 return qh;
242}
243
244static struct knav_queue *
245knav_queue_open_by_id(const char *name, unsigned id, unsigned flags)
246{
247 struct knav_queue_inst *inst;
248 struct knav_queue *qh;
249
250 mutex_lock(&knav_dev_lock);
251
252 qh = ERR_PTR(-ENODEV);
253 inst = knav_queue_find_by_id(id);
254 if (!inst)
255 goto unlock_ret;
256
257 qh = ERR_PTR(-EEXIST);
258 if (!(flags & KNAV_QUEUE_SHARED) && knav_queue_is_busy(inst))
259 goto unlock_ret;
260
261 qh = ERR_PTR(-EBUSY);
262 if ((flags & KNAV_QUEUE_SHARED) &&
263 (knav_queue_is_busy(inst) && !knav_queue_is_shared(inst)))
264 goto unlock_ret;
265
266 qh = __knav_queue_open(inst, name, flags);
267
268unlock_ret:
269 mutex_unlock(&knav_dev_lock);
270
271 return qh;
272}
273
274static struct knav_queue *knav_queue_open_by_type(const char *name,
275 unsigned type, unsigned flags)
276{
277 struct knav_queue_inst *inst;
278 struct knav_queue *qh = ERR_PTR(-EINVAL);
279 int idx;
280
281 mutex_lock(&knav_dev_lock);
282
283 for_each_instance(idx, inst, kdev) {
284 if (knav_queue_is_reserved(inst))
285 continue;
286 if (!knav_queue_match_type(inst, type))
287 continue;
288 if (knav_queue_is_busy(inst))
289 continue;
290 qh = __knav_queue_open(inst, name, flags);
291 goto unlock_ret;
292 }
293
294unlock_ret:
295 mutex_unlock(&knav_dev_lock);
296 return qh;
297}
298
299static void knav_queue_set_notify(struct knav_queue_inst *inst, bool enabled)
300{
301 struct knav_range_info *range = inst->range;
302
303 if (range->ops && range->ops->set_notify)
304 range->ops->set_notify(range, inst, enabled);
305}
306
307static int knav_queue_enable_notifier(struct knav_queue *qh)
308{
309 struct knav_queue_inst *inst = qh->inst;
310 bool first;
311
312 if (WARN_ON(!qh->notifier_fn))
313 return -EINVAL;
314
315 /* Adjust the per handle notifier count */
316 first = (atomic_inc_return(&qh->notifier_enabled) == 1);
317 if (!first)
318 return 0; /* nothing to do */
319
320 /* Now adjust the per instance notifier count */
321 first = (atomic_inc_return(&inst->num_notifiers) == 1);
322 if (first)
323 knav_queue_set_notify(inst, true);
324
325 return 0;
326}
327
328static int knav_queue_disable_notifier(struct knav_queue *qh)
329{
330 struct knav_queue_inst *inst = qh->inst;
331 bool last;
332
333 last = (atomic_dec_return(&qh->notifier_enabled) == 0);
334 if (!last)
335 return 0; /* nothing to do */
336
337 last = (atomic_dec_return(&inst->num_notifiers) == 0);
338 if (last)
339 knav_queue_set_notify(inst, false);
340
341 return 0;
342}
343
344static int knav_queue_set_notifier(struct knav_queue *qh,
345 struct knav_queue_notify_config *cfg)
346{
347 knav_queue_notify_fn old_fn = qh->notifier_fn;
348
349 if (!cfg)
350 return -EINVAL;
351
352 if (!(qh->inst->range->flags & (RANGE_HAS_ACCUMULATOR | RANGE_HAS_IRQ)))
353 return -ENOTSUPP;
354
355 if (!cfg->fn && old_fn)
356 knav_queue_disable_notifier(qh);
357
358 qh->notifier_fn = cfg->fn;
359 qh->notifier_fn_arg = cfg->fn_arg;
360
361 if (cfg->fn && !old_fn)
362 knav_queue_enable_notifier(qh);
363
364 return 0;
365}
366
367static int knav_gp_set_notify(struct knav_range_info *range,
368 struct knav_queue_inst *inst,
369 bool enabled)
370{
371 unsigned queue;
372
373 if (range->flags & RANGE_HAS_IRQ) {
374 queue = inst->id - range->queue_base;
375 if (enabled)
376 enable_irq(range->irqs[queue].irq);
377 else
378 disable_irq_nosync(range->irqs[queue].irq);
379 }
380 return 0;
381}
382
383static int knav_gp_open_queue(struct knav_range_info *range,
384 struct knav_queue_inst *inst, unsigned flags)
385{
386 return knav_queue_setup_irq(range, inst);
387}
388
389static int knav_gp_close_queue(struct knav_range_info *range,
390 struct knav_queue_inst *inst)
391{
392 knav_queue_free_irq(inst);
393 return 0;
394}
395
396struct knav_range_ops knav_gp_range_ops = {
397 .set_notify = knav_gp_set_notify,
398 .open_queue = knav_gp_open_queue,
399 .close_queue = knav_gp_close_queue,
400};
401
402
403static int knav_queue_get_count(void *qhandle)
404{
405 struct knav_queue *qh = qhandle;
406 struct knav_queue_inst *inst = qh->inst;
407
408 return readl_relaxed(&qh->reg_peek[0].entry_count) +
409 atomic_read(&inst->desc_count);
410}
411
412static void knav_queue_debug_show_instance(struct seq_file *s,
413 struct knav_queue_inst *inst)
414{
415 struct knav_device *kdev = inst->kdev;
416 struct knav_queue *qh;
417
418 if (!knav_queue_is_busy(inst))
419 return;
420
421 seq_printf(s, "\tqueue id %d (%s)\n",
422 kdev->base_id + inst->id, inst->name);
423 for_each_handle_rcu(qh, inst) {
424 seq_printf(s, "\t\thandle %p: ", qh);
425 seq_printf(s, "pushes %8d, ",
426 atomic_read(&qh->stats.pushes));
427 seq_printf(s, "pops %8d, ",
428 atomic_read(&qh->stats.pops));
429 seq_printf(s, "count %8d, ",
430 knav_queue_get_count(qh));
431 seq_printf(s, "notifies %8d, ",
432 atomic_read(&qh->stats.notifies));
433 seq_printf(s, "push errors %8d, ",
434 atomic_read(&qh->stats.push_errors));
435 seq_printf(s, "pop errors %8d\n",
436 atomic_read(&qh->stats.pop_errors));
437 }
438}
439
440static int knav_queue_debug_show(struct seq_file *s, void *v)
441{
442 struct knav_queue_inst *inst;
443 int idx;
444
445 mutex_lock(&knav_dev_lock);
446 seq_printf(s, "%s: %u-%u\n",
447 dev_name(kdev->dev), kdev->base_id,
448 kdev->base_id + kdev->num_queues - 1);
449 for_each_instance(idx, inst, kdev)
450 knav_queue_debug_show_instance(s, inst);
451 mutex_unlock(&knav_dev_lock);
452
453 return 0;
454}
455
456static int knav_queue_debug_open(struct inode *inode, struct file *file)
457{
458 return single_open(file, knav_queue_debug_show, NULL);
459}
460
461static const struct file_operations knav_queue_debug_ops = {
462 .open = knav_queue_debug_open,
463 .read = seq_read,
464 .llseek = seq_lseek,
465 .release = single_release,
466};
467
468static inline int knav_queue_pdsp_wait(u32 * __iomem addr, unsigned timeout,
469 u32 flags)
470{
471 unsigned long end;
472 u32 val = 0;
473
474 end = jiffies + msecs_to_jiffies(timeout);
475 while (time_after(end, jiffies)) {
476 val = readl_relaxed(addr);
477 if (flags)
478 val &= flags;
479 if (!val)
480 break;
481 cpu_relax();
482 }
483 return val ? -ETIMEDOUT : 0;
484}
485
486
487static int knav_queue_flush(struct knav_queue *qh)
488{
489 struct knav_queue_inst *inst = qh->inst;
490 unsigned id = inst->id - inst->qmgr->start_queue;
491
492 atomic_set(&inst->desc_count, 0);
493 writel_relaxed(0, &inst->qmgr->reg_push[id].ptr_size_thresh);
494 return 0;
495}
496
497/**
498 * knav_queue_open() - open a hardware queue
499 * @name - name to give the queue handle
500 * @id - desired queue number if any or specifes the type
501 * of queue
502 * @flags - the following flags are applicable to queues:
503 * KNAV_QUEUE_SHARED - allow the queue to be shared. Queues are
504 * exclusive by default.
505 * Subsequent attempts to open a shared queue should
506 * also have this flag.
507 *
508 * Returns a handle to the open hardware queue if successful. Use IS_ERR()
509 * to check the returned value for error codes.
510 */
511void *knav_queue_open(const char *name, unsigned id,
512 unsigned flags)
513{
514 struct knav_queue *qh = ERR_PTR(-EINVAL);
515
516 switch (id) {
517 case KNAV_QUEUE_QPEND:
518 case KNAV_QUEUE_ACC:
519 case KNAV_QUEUE_GP:
520 qh = knav_queue_open_by_type(name, id, flags);
521 break;
522
523 default:
524 qh = knav_queue_open_by_id(name, id, flags);
525 break;
526 }
527 return qh;
528}
529EXPORT_SYMBOL_GPL(knav_queue_open);
530
531/**
532 * knav_queue_close() - close a hardware queue handle
533 * @qh - handle to close
534 */
535void knav_queue_close(void *qhandle)
536{
537 struct knav_queue *qh = qhandle;
538 struct knav_queue_inst *inst = qh->inst;
539
540 while (atomic_read(&qh->notifier_enabled) > 0)
541 knav_queue_disable_notifier(qh);
542
543 mutex_lock(&knav_dev_lock);
544 list_del_rcu(&qh->list);
545 mutex_unlock(&knav_dev_lock);
546 synchronize_rcu();
547 if (!knav_queue_is_busy(inst)) {
548 struct knav_range_info *range = inst->range;
549
550 if (range->ops && range->ops->close_queue)
551 range->ops->close_queue(range, inst);
552 }
553 devm_kfree(inst->kdev->dev, qh);
554}
555EXPORT_SYMBOL_GPL(knav_queue_close);
556
557/**
558 * knav_queue_device_control() - Perform control operations on a queue
559 * @qh - queue handle
560 * @cmd - control commands
561 * @arg - command argument
562 *
563 * Returns 0 on success, errno otherwise.
564 */
565int knav_queue_device_control(void *qhandle, enum knav_queue_ctrl_cmd cmd,
566 unsigned long arg)
567{
568 struct knav_queue *qh = qhandle;
569 struct knav_queue_notify_config *cfg;
570 int ret;
571
572 switch ((int)cmd) {
573 case KNAV_QUEUE_GET_ID:
574 ret = qh->inst->kdev->base_id + qh->inst->id;
575 break;
576
577 case KNAV_QUEUE_FLUSH:
578 ret = knav_queue_flush(qh);
579 break;
580
581 case KNAV_QUEUE_SET_NOTIFIER:
582 cfg = (void *)arg;
583 ret = knav_queue_set_notifier(qh, cfg);
584 break;
585
586 case KNAV_QUEUE_ENABLE_NOTIFY:
587 ret = knav_queue_enable_notifier(qh);
588 break;
589
590 case KNAV_QUEUE_DISABLE_NOTIFY:
591 ret = knav_queue_disable_notifier(qh);
592 break;
593
594 case KNAV_QUEUE_GET_COUNT:
595 ret = knav_queue_get_count(qh);
596 break;
597
598 default:
599 ret = -ENOTSUPP;
600 break;
601 }
602 return ret;
603}
604EXPORT_SYMBOL_GPL(knav_queue_device_control);
605
606
607
608/**
609 * knav_queue_push() - push data (or descriptor) to the tail of a queue
610 * @qh - hardware queue handle
611 * @data - data to push
612 * @size - size of data to push
613 * @flags - can be used to pass additional information
614 *
615 * Returns 0 on success, errno otherwise.
616 */
617int knav_queue_push(void *qhandle, dma_addr_t dma,
618 unsigned size, unsigned flags)
619{
620 struct knav_queue *qh = qhandle;
621 u32 val;
622
623 val = (u32)dma | ((size / 16) - 1);
624 writel_relaxed(val, &qh->reg_push[0].ptr_size_thresh);
625
626 atomic_inc(&qh->stats.pushes);
627 return 0;
628}
629
630/**
631 * knav_queue_pop() - pop data (or descriptor) from the head of a queue
632 * @qh - hardware queue handle
633 * @size - (optional) size of the data pop'ed.
634 *
635 * Returns a DMA address on success, 0 on failure.
636 */
637dma_addr_t knav_queue_pop(void *qhandle, unsigned *size)
638{
639 struct knav_queue *qh = qhandle;
640 struct knav_queue_inst *inst = qh->inst;
641 dma_addr_t dma;
642 u32 val, idx;
643
644 /* are we accumulated? */
645 if (inst->descs) {
646 if (unlikely(atomic_dec_return(&inst->desc_count) < 0)) {
647 atomic_inc(&inst->desc_count);
648 return 0;
649 }
650 idx = atomic_inc_return(&inst->desc_head);
651 idx &= ACC_DESCS_MASK;
652 val = inst->descs[idx];
653 } else {
654 val = readl_relaxed(&qh->reg_pop[0].ptr_size_thresh);
655 if (unlikely(!val))
656 return 0;
657 }
658
659 dma = val & DESC_PTR_MASK;
660 if (size)
661 *size = ((val & DESC_SIZE_MASK) + 1) * 16;
662
663 atomic_inc(&qh->stats.pops);
664 return dma;
665}
666
667/* carve out descriptors and push into queue */
668static void kdesc_fill_pool(struct knav_pool *pool)
669{
670 struct knav_region *region;
671 int i;
672
673 region = pool->region;
674 pool->desc_size = region->desc_size;
675 for (i = 0; i < pool->num_desc; i++) {
676 int index = pool->region_offset + i;
677 dma_addr_t dma_addr;
678 unsigned dma_size;
679 dma_addr = region->dma_start + (region->desc_size * index);
680 dma_size = ALIGN(pool->desc_size, SMP_CACHE_BYTES);
681 dma_sync_single_for_device(pool->dev, dma_addr, dma_size,
682 DMA_TO_DEVICE);
683 knav_queue_push(pool->queue, dma_addr, dma_size, 0);
684 }
685}
686
687/* pop out descriptors and close the queue */
688static void kdesc_empty_pool(struct knav_pool *pool)
689{
690 dma_addr_t dma;
691 unsigned size;
692 void *desc;
693 int i;
694
695 if (!pool->queue)
696 return;
697
698 for (i = 0;; i++) {
699 dma = knav_queue_pop(pool->queue, &size);
700 if (!dma)
701 break;
702 desc = knav_pool_desc_dma_to_virt(pool, dma);
703 if (!desc) {
704 dev_dbg(pool->kdev->dev,
705 "couldn't unmap desc, continuing\n");
706 continue;
707 }
708 }
709 WARN_ON(i != pool->num_desc);
710 knav_queue_close(pool->queue);
711}
712
713
714/* Get the DMA address of a descriptor */
715dma_addr_t knav_pool_desc_virt_to_dma(void *ph, void *virt)
716{
717 struct knav_pool *pool = ph;
718 return pool->region->dma_start + (virt - pool->region->virt_start);
719}
720
721void *knav_pool_desc_dma_to_virt(void *ph, dma_addr_t dma)
722{
723 struct knav_pool *pool = ph;
724 return pool->region->virt_start + (dma - pool->region->dma_start);
725}
726
727/**
728 * knav_pool_create() - Create a pool of descriptors
729 * @name - name to give the pool handle
730 * @num_desc - numbers of descriptors in the pool
731 * @region_id - QMSS region id from which the descriptors are to be
732 * allocated.
733 *
734 * Returns a pool handle on success.
735 * Use IS_ERR_OR_NULL() to identify error values on return.
736 */
737void *knav_pool_create(const char *name,
738 int num_desc, int region_id)
739{
740 struct knav_region *reg_itr, *region = NULL;
741 struct knav_pool *pool, *pi;
742 struct list_head *node;
743 unsigned last_offset;
744 bool slot_found;
745 int ret;
746
747 if (!kdev->dev)
748 return ERR_PTR(-ENODEV);
749
750 pool = devm_kzalloc(kdev->dev, sizeof(*pool), GFP_KERNEL);
751 if (!pool) {
752 dev_err(kdev->dev, "out of memory allocating pool\n");
753 return ERR_PTR(-ENOMEM);
754 }
755
756 for_each_region(kdev, reg_itr) {
757 if (reg_itr->id != region_id)
758 continue;
759 region = reg_itr;
760 break;
761 }
762
763 if (!region) {
764 dev_err(kdev->dev, "region-id(%d) not found\n", region_id);
765 ret = -EINVAL;
766 goto err;
767 }
768
769 pool->queue = knav_queue_open(name, KNAV_QUEUE_GP, 0);
770 if (IS_ERR_OR_NULL(pool->queue)) {
771 dev_err(kdev->dev,
772 "failed to open queue for pool(%s), error %ld\n",
773 name, PTR_ERR(pool->queue));
774 ret = PTR_ERR(pool->queue);
775 goto err;
776 }
777
778 pool->name = kstrndup(name, KNAV_NAME_SIZE, GFP_KERNEL);
779 pool->kdev = kdev;
780 pool->dev = kdev->dev;
781
782 mutex_lock(&knav_dev_lock);
783
784 if (num_desc > (region->num_desc - region->used_desc)) {
785 dev_err(kdev->dev, "out of descs in region(%d) for pool(%s)\n",
786 region_id, name);
787 ret = -ENOMEM;
788 goto err;
789 }
790
791 /* Region maintains a sorted (by region offset) list of pools
792 * use the first free slot which is large enough to accomodate
793 * the request
794 */
795 last_offset = 0;
796 slot_found = false;
797 node = &region->pools;
798 list_for_each_entry(pi, &region->pools, region_inst) {
799 if ((pi->region_offset - last_offset) >= num_desc) {
800 slot_found = true;
801 break;
802 }
803 last_offset = pi->region_offset + pi->num_desc;
804 }
805 node = &pi->region_inst;
806
807 if (slot_found) {
808 pool->region = region;
809 pool->num_desc = num_desc;
810 pool->region_offset = last_offset;
811 region->used_desc += num_desc;
812 list_add_tail(&pool->list, &kdev->pools);
813 list_add_tail(&pool->region_inst, node);
814 } else {
815 dev_err(kdev->dev, "pool(%s) create failed: fragmented desc pool in region(%d)\n",
816 name, region_id);
817 ret = -ENOMEM;
818 goto err;
819 }
820
821 mutex_unlock(&knav_dev_lock);
822 kdesc_fill_pool(pool);
823 return pool;
824
825err:
826 mutex_unlock(&knav_dev_lock);
827 kfree(pool->name);
828 devm_kfree(kdev->dev, pool);
829 return ERR_PTR(ret);
830}
831EXPORT_SYMBOL_GPL(knav_pool_create);
832
833/**
834 * knav_pool_destroy() - Free a pool of descriptors
835 * @pool - pool handle
836 */
837void knav_pool_destroy(void *ph)
838{
839 struct knav_pool *pool = ph;
840
841 if (!pool)
842 return;
843
844 if (!pool->region)
845 return;
846
847 kdesc_empty_pool(pool);
848 mutex_lock(&knav_dev_lock);
849
850 pool->region->used_desc -= pool->num_desc;
851 list_del(&pool->region_inst);
852 list_del(&pool->list);
853
854 mutex_unlock(&knav_dev_lock);
855 kfree(pool->name);
856 devm_kfree(kdev->dev, pool);
857}
858EXPORT_SYMBOL_GPL(knav_pool_destroy);
859
860
861/**
862 * knav_pool_desc_get() - Get a descriptor from the pool
863 * @pool - pool handle
864 *
865 * Returns descriptor from the pool.
866 */
867void *knav_pool_desc_get(void *ph)
868{
869 struct knav_pool *pool = ph;
870 dma_addr_t dma;
871 unsigned size;
872 void *data;
873
874 dma = knav_queue_pop(pool->queue, &size);
875 if (unlikely(!dma))
876 return ERR_PTR(-ENOMEM);
877 data = knav_pool_desc_dma_to_virt(pool, dma);
878 return data;
879}
880
881/**
882 * knav_pool_desc_put() - return a descriptor to the pool
883 * @pool - pool handle
884 */
885void knav_pool_desc_put(void *ph, void *desc)
886{
887 struct knav_pool *pool = ph;
888 dma_addr_t dma;
889 dma = knav_pool_desc_virt_to_dma(pool, desc);
890 knav_queue_push(pool->queue, dma, pool->region->desc_size, 0);
891}
892
893/**
894 * knav_pool_desc_map() - Map descriptor for DMA transfer
895 * @pool - pool handle
896 * @desc - address of descriptor to map
897 * @size - size of descriptor to map
898 * @dma - DMA address return pointer
899 * @dma_sz - adjusted return pointer
900 *
901 * Returns 0 on success, errno otherwise.
902 */
903int knav_pool_desc_map(void *ph, void *desc, unsigned size,
904 dma_addr_t *dma, unsigned *dma_sz)
905{
906 struct knav_pool *pool = ph;
907 *dma = knav_pool_desc_virt_to_dma(pool, desc);
908 size = min(size, pool->region->desc_size);
909 size = ALIGN(size, SMP_CACHE_BYTES);
910 *dma_sz = size;
911 dma_sync_single_for_device(pool->dev, *dma, size, DMA_TO_DEVICE);
912
913 /* Ensure the descriptor reaches to the memory */
914 __iowmb();
915
916 return 0;
917}
918
919/**
920 * knav_pool_desc_unmap() - Unmap descriptor after DMA transfer
921 * @pool - pool handle
922 * @dma - DMA address of descriptor to unmap
923 * @dma_sz - size of descriptor to unmap
924 *
925 * Returns descriptor address on success, Use IS_ERR_OR_NULL() to identify
926 * error values on return.
927 */
928void *knav_pool_desc_unmap(void *ph, dma_addr_t dma, unsigned dma_sz)
929{
930 struct knav_pool *pool = ph;
931 unsigned desc_sz;
932 void *desc;
933
934 desc_sz = min(dma_sz, pool->region->desc_size);
935 desc = knav_pool_desc_dma_to_virt(pool, dma);
936 dma_sync_single_for_cpu(pool->dev, dma, desc_sz, DMA_FROM_DEVICE);
937 prefetch(desc);
938 return desc;
939}
940
941/**
942 * knav_pool_count() - Get the number of descriptors in pool.
943 * @pool - pool handle
944 * Returns number of elements in the pool.
945 */
946int knav_pool_count(void *ph)
947{
948 struct knav_pool *pool = ph;
949 return knav_queue_get_count(pool->queue);
950}
951
952static void knav_queue_setup_region(struct knav_device *kdev,
953 struct knav_region *region)
954{
955 unsigned hw_num_desc, hw_desc_size, size;
956 struct knav_reg_region __iomem *regs;
957 struct knav_qmgr_info *qmgr;
958 struct knav_pool *pool;
959 int id = region->id;
960 struct page *page;
961
962 /* unused region? */
963 if (!region->num_desc) {
964 dev_warn(kdev->dev, "unused region %s\n", region->name);
965 return;
966 }
967
968 /* get hardware descriptor value */
969 hw_num_desc = ilog2(region->num_desc - 1) + 1;
970
971 /* did we force fit ourselves into nothingness? */
972 if (region->num_desc < 32) {
973 region->num_desc = 0;
974 dev_warn(kdev->dev, "too few descriptors in region %s\n",
975 region->name);
976 return;
977 }
978
979 size = region->num_desc * region->desc_size;
980 region->virt_start = alloc_pages_exact(size, GFP_KERNEL | GFP_DMA |
981 GFP_DMA32);
982 if (!region->virt_start) {
983 region->num_desc = 0;
984 dev_err(kdev->dev, "memory alloc failed for region %s\n",
985 region->name);
986 return;
987 }
988 region->virt_end = region->virt_start + size;
989 page = virt_to_page(region->virt_start);
990
991 region->dma_start = dma_map_page(kdev->dev, page, 0, size,
992 DMA_BIDIRECTIONAL);
993 if (dma_mapping_error(kdev->dev, region->dma_start)) {
994 dev_err(kdev->dev, "dma map failed for region %s\n",
995 region->name);
996 goto fail;
997 }
998 region->dma_end = region->dma_start + size;
999
1000 pool = devm_kzalloc(kdev->dev, sizeof(*pool), GFP_KERNEL);
1001 if (!pool) {
1002 dev_err(kdev->dev, "out of memory allocating dummy pool\n");
1003 goto fail;
1004 }
1005 pool->num_desc = 0;
1006 pool->region_offset = region->num_desc;
1007 list_add(&pool->region_inst, &region->pools);
1008
1009 dev_dbg(kdev->dev,
1010 "region %s (%d): size:%d, link:%d@%d, phys:%08x-%08x, virt:%p-%p\n",
1011 region->name, id, region->desc_size, region->num_desc,
1012 region->link_index, region->dma_start, region->dma_end,
1013 region->virt_start, region->virt_end);
1014
1015 hw_desc_size = (region->desc_size / 16) - 1;
1016 hw_num_desc -= 5;
1017
1018 for_each_qmgr(kdev, qmgr) {
1019 regs = qmgr->reg_region + id;
1020 writel_relaxed(region->dma_start, &regs->base);
1021 writel_relaxed(region->link_index, &regs->start_index);
1022 writel_relaxed(hw_desc_size << 16 | hw_num_desc,
1023 &regs->size_count);
1024 }
1025 return;
1026
1027fail:
1028 if (region->dma_start)
1029 dma_unmap_page(kdev->dev, region->dma_start, size,
1030 DMA_BIDIRECTIONAL);
1031 if (region->virt_start)
1032 free_pages_exact(region->virt_start, size);
1033 region->num_desc = 0;
1034 return;
1035}
1036
1037static const char *knav_queue_find_name(struct device_node *node)
1038{
1039 const char *name;
1040
1041 if (of_property_read_string(node, "label", &name) < 0)
1042 name = node->name;
1043 if (!name)
1044 name = "unknown";
1045 return name;
1046}
1047
1048static int knav_queue_setup_regions(struct knav_device *kdev,
1049 struct device_node *regions)
1050{
1051 struct device *dev = kdev->dev;
1052 struct knav_region *region;
1053 struct device_node *child;
1054 u32 temp[2];
1055 int ret;
1056
1057 for_each_child_of_node(regions, child) {
1058 region = devm_kzalloc(dev, sizeof(*region), GFP_KERNEL);
1059 if (!region) {
1060 dev_err(dev, "out of memory allocating region\n");
1061 return -ENOMEM;
1062 }
1063
1064 region->name = knav_queue_find_name(child);
1065 of_property_read_u32(child, "id", &region->id);
1066 ret = of_property_read_u32_array(child, "region-spec", temp, 2);
1067 if (!ret) {
1068 region->num_desc = temp[0];
1069 region->desc_size = temp[1];
1070 } else {
1071 dev_err(dev, "invalid region info %s\n", region->name);
1072 devm_kfree(dev, region);
1073 continue;
1074 }
1075
1076 if (!of_get_property(child, "link-index", NULL)) {
1077 dev_err(dev, "No link info for %s\n", region->name);
1078 devm_kfree(dev, region);
1079 continue;
1080 }
1081 ret = of_property_read_u32(child, "link-index",
1082 &region->link_index);
1083 if (ret) {
1084 dev_err(dev, "link index not found for %s\n",
1085 region->name);
1086 devm_kfree(dev, region);
1087 continue;
1088 }
1089
1090 INIT_LIST_HEAD(&region->pools);
1091 list_add_tail(&region->list, &kdev->regions);
1092 }
1093 if (list_empty(&kdev->regions)) {
1094 dev_err(dev, "no valid region information found\n");
1095 return -ENODEV;
1096 }
1097
1098 /* Next, we run through the regions and set things up */
1099 for_each_region(kdev, region)
1100 knav_queue_setup_region(kdev, region);
1101
1102 return 0;
1103}
1104
1105static int knav_get_link_ram(struct knav_device *kdev,
1106 const char *name,
1107 struct knav_link_ram_block *block)
1108{
1109 struct platform_device *pdev = to_platform_device(kdev->dev);
1110 struct device_node *node = pdev->dev.of_node;
1111 u32 temp[2];
1112
1113 /*
1114 * Note: link ram resources are specified in "entry" sized units. In
1115 * reality, although entries are ~40bits in hardware, we treat them as
1116 * 64-bit entities here.
1117 *
1118 * For example, to specify the internal link ram for Keystone-I class
1119 * devices, we would set the linkram0 resource to 0x80000-0x83fff.
1120 *
1121 * This gets a bit weird when other link rams are used. For example,
1122 * if the range specified is 0x0c000000-0x0c003fff (i.e., 16K entries
1123 * in MSMC SRAM), the actual memory used is 0x0c000000-0x0c020000,
1124 * which accounts for 64-bits per entry, for 16K entries.
1125 */
1126 if (!of_property_read_u32_array(node, name , temp, 2)) {
1127 if (temp[0]) {
1128 /*
1129 * queue_base specified => using internal or onchip
1130 * link ram WARNING - we do not "reserve" this block
1131 */
1132 block->phys = (dma_addr_t)temp[0];
1133 block->virt = NULL;
1134 block->size = temp[1];
1135 } else {
1136 block->size = temp[1];
1137 /* queue_base not specific => allocate requested size */
1138 block->virt = dmam_alloc_coherent(kdev->dev,
1139 8 * block->size, &block->phys,
1140 GFP_KERNEL);
1141 if (!block->virt) {
1142 dev_err(kdev->dev, "failed to alloc linkram\n");
1143 return -ENOMEM;
1144 }
1145 }
1146 } else {
1147 return -ENODEV;
1148 }
1149 return 0;
1150}
1151
1152static int knav_queue_setup_link_ram(struct knav_device *kdev)
1153{
1154 struct knav_link_ram_block *block;
1155 struct knav_qmgr_info *qmgr;
1156
1157 for_each_qmgr(kdev, qmgr) {
1158 block = &kdev->link_rams[0];
1159 dev_dbg(kdev->dev, "linkram0: phys:%x, virt:%p, size:%x\n",
1160 block->phys, block->virt, block->size);
1161 writel_relaxed(block->phys, &qmgr->reg_config->link_ram_base0);
1162 writel_relaxed(block->size, &qmgr->reg_config->link_ram_size0);
1163
1164 block++;
1165 if (!block->size)
1166 return 0;
1167
1168 dev_dbg(kdev->dev, "linkram1: phys:%x, virt:%p, size:%x\n",
1169 block->phys, block->virt, block->size);
1170 writel_relaxed(block->phys, &qmgr->reg_config->link_ram_base1);
1171 }
1172
1173 return 0;
1174}
1175
1176static int knav_setup_queue_range(struct knav_device *kdev,
1177 struct device_node *node)
1178{
1179 struct device *dev = kdev->dev;
1180 struct knav_range_info *range;
1181 struct knav_qmgr_info *qmgr;
1182 u32 temp[2], start, end, id, index;
1183 int ret, i;
1184
1185 range = devm_kzalloc(dev, sizeof(*range), GFP_KERNEL);
1186 if (!range) {
1187 dev_err(dev, "out of memory allocating range\n");
1188 return -ENOMEM;
1189 }
1190
1191 range->kdev = kdev;
1192 range->name = knav_queue_find_name(node);
1193 ret = of_property_read_u32_array(node, "qrange", temp, 2);
1194 if (!ret) {
1195 range->queue_base = temp[0] - kdev->base_id;
1196 range->num_queues = temp[1];
1197 } else {
1198 dev_err(dev, "invalid queue range %s\n", range->name);
1199 devm_kfree(dev, range);
1200 return -EINVAL;
1201 }
1202
1203 for (i = 0; i < RANGE_MAX_IRQS; i++) {
1204 struct of_phandle_args oirq;
1205
1206 if (of_irq_parse_one(node, i, &oirq))
1207 break;
1208
1209 range->irqs[i].irq = irq_create_of_mapping(&oirq);
1210 if (range->irqs[i].irq == IRQ_NONE)
1211 break;
1212
1213 range->num_irqs++;
1214
1215 if (oirq.args_count == 3)
1216 range->irqs[i].cpu_map =
1217 (oirq.args[2] & 0x0000ff00) >> 8;
1218 }
1219
1220 range->num_irqs = min(range->num_irqs, range->num_queues);
1221 if (range->num_irqs)
1222 range->flags |= RANGE_HAS_IRQ;
1223
1224 if (of_get_property(node, "qalloc-by-id", NULL))
1225 range->flags |= RANGE_RESERVED;
1226
1227 if (of_get_property(node, "accumulator", NULL)) {
1228 ret = knav_init_acc_range(kdev, node, range);
1229 if (ret < 0) {
1230 devm_kfree(dev, range);
1231 return ret;
1232 }
1233 } else {
1234 range->ops = &knav_gp_range_ops;
1235 }
1236
1237 /* set threshold to 1, and flush out the queues */
1238 for_each_qmgr(kdev, qmgr) {
1239 start = max(qmgr->start_queue, range->queue_base);
1240 end = min(qmgr->start_queue + qmgr->num_queues,
1241 range->queue_base + range->num_queues);
1242 for (id = start; id < end; id++) {
1243 index = id - qmgr->start_queue;
1244 writel_relaxed(THRESH_GTE | 1,
1245 &qmgr->reg_peek[index].ptr_size_thresh);
1246 writel_relaxed(0,
1247 &qmgr->reg_push[index].ptr_size_thresh);
1248 }
1249 }
1250
1251 list_add_tail(&range->list, &kdev->queue_ranges);
1252 dev_dbg(dev, "added range %s: %d-%d, %d irqs%s%s%s\n",
1253 range->name, range->queue_base,
1254 range->queue_base + range->num_queues - 1,
1255 range->num_irqs,
1256 (range->flags & RANGE_HAS_IRQ) ? ", has irq" : "",
1257 (range->flags & RANGE_RESERVED) ? ", reserved" : "",
1258 (range->flags & RANGE_HAS_ACCUMULATOR) ? ", acc" : "");
1259 kdev->num_queues_in_use += range->num_queues;
1260 return 0;
1261}
1262
1263static int knav_setup_queue_pools(struct knav_device *kdev,
1264 struct device_node *queue_pools)
1265{
1266 struct device_node *type, *range;
1267 int ret;
1268
1269 for_each_child_of_node(queue_pools, type) {
1270 for_each_child_of_node(type, range) {
1271 ret = knav_setup_queue_range(kdev, range);
1272 /* return value ignored, we init the rest... */
1273 }
1274 }
1275
1276 /* ... and barf if they all failed! */
1277 if (list_empty(&kdev->queue_ranges)) {
1278 dev_err(kdev->dev, "no valid queue range found\n");
1279 return -ENODEV;
1280 }
1281 return 0;
1282}
1283
1284static void knav_free_queue_range(struct knav_device *kdev,
1285 struct knav_range_info *range)
1286{
1287 if (range->ops && range->ops->free_range)
1288 range->ops->free_range(range);
1289 list_del(&range->list);
1290 devm_kfree(kdev->dev, range);
1291}
1292
1293static void knav_free_queue_ranges(struct knav_device *kdev)
1294{
1295 struct knav_range_info *range;
1296
1297 for (;;) {
1298 range = first_queue_range(kdev);
1299 if (!range)
1300 break;
1301 knav_free_queue_range(kdev, range);
1302 }
1303}
1304
1305static void knav_queue_free_regions(struct knav_device *kdev)
1306{
1307 struct knav_region *region;
1308 struct knav_pool *pool;
1309 unsigned size;
1310
1311 for (;;) {
1312 region = first_region(kdev);
1313 if (!region)
1314 break;
1315 list_for_each_entry(pool, &region->pools, region_inst)
1316 knav_pool_destroy(pool);
1317
1318 size = region->virt_end - region->virt_start;
1319 if (size)
1320 free_pages_exact(region->virt_start, size);
1321 list_del(&region->list);
1322 devm_kfree(kdev->dev, region);
1323 }
1324}
1325
1326static void __iomem *knav_queue_map_reg(struct knav_device *kdev,
1327 struct device_node *node, int index)
1328{
1329 struct resource res;
1330 void __iomem *regs;
1331 int ret;
1332
1333 ret = of_address_to_resource(node, index, &res);
1334 if (ret) {
1335 dev_err(kdev->dev, "Can't translate of node(%s) address for index(%d)\n",
1336 node->name, index);
1337 return ERR_PTR(ret);
1338 }
1339
1340 regs = devm_ioremap_resource(kdev->dev, &res);
1341 if (IS_ERR(regs))
1342 dev_err(kdev->dev, "Failed to map register base for index(%d) node(%s)\n",
1343 index, node->name);
1344 return regs;
1345}
1346
1347static int knav_queue_init_qmgrs(struct knav_device *kdev,
1348 struct device_node *qmgrs)
1349{
1350 struct device *dev = kdev->dev;
1351 struct knav_qmgr_info *qmgr;
1352 struct device_node *child;
1353 u32 temp[2];
1354 int ret;
1355
1356 for_each_child_of_node(qmgrs, child) {
1357 qmgr = devm_kzalloc(dev, sizeof(*qmgr), GFP_KERNEL);
1358 if (!qmgr) {
1359 dev_err(dev, "out of memory allocating qmgr\n");
1360 return -ENOMEM;
1361 }
1362
1363 ret = of_property_read_u32_array(child, "managed-queues",
1364 temp, 2);
1365 if (!ret) {
1366 qmgr->start_queue = temp[0];
1367 qmgr->num_queues = temp[1];
1368 } else {
1369 dev_err(dev, "invalid qmgr queue range\n");
1370 devm_kfree(dev, qmgr);
1371 continue;
1372 }
1373
1374 dev_info(dev, "qmgr start queue %d, number of queues %d\n",
1375 qmgr->start_queue, qmgr->num_queues);
1376
1377 qmgr->reg_peek =
1378 knav_queue_map_reg(kdev, child,
1379 KNAV_QUEUE_PEEK_REG_INDEX);
1380 qmgr->reg_status =
1381 knav_queue_map_reg(kdev, child,
1382 KNAV_QUEUE_STATUS_REG_INDEX);
1383 qmgr->reg_config =
1384 knav_queue_map_reg(kdev, child,
1385 KNAV_QUEUE_CONFIG_REG_INDEX);
1386 qmgr->reg_region =
1387 knav_queue_map_reg(kdev, child,
1388 KNAV_QUEUE_REGION_REG_INDEX);
1389 qmgr->reg_push =
1390 knav_queue_map_reg(kdev, child,
1391 KNAV_QUEUE_PUSH_REG_INDEX);
1392 qmgr->reg_pop =
1393 knav_queue_map_reg(kdev, child,
1394 KNAV_QUEUE_POP_REG_INDEX);
1395
1396 if (IS_ERR(qmgr->reg_peek) || IS_ERR(qmgr->reg_status) ||
1397 IS_ERR(qmgr->reg_config) || IS_ERR(qmgr->reg_region) ||
1398 IS_ERR(qmgr->reg_push) || IS_ERR(qmgr->reg_pop)) {
1399 dev_err(dev, "failed to map qmgr regs\n");
1400 if (!IS_ERR(qmgr->reg_peek))
1401 devm_iounmap(dev, qmgr->reg_peek);
1402 if (!IS_ERR(qmgr->reg_status))
1403 devm_iounmap(dev, qmgr->reg_status);
1404 if (!IS_ERR(qmgr->reg_config))
1405 devm_iounmap(dev, qmgr->reg_config);
1406 if (!IS_ERR(qmgr->reg_region))
1407 devm_iounmap(dev, qmgr->reg_region);
1408 if (!IS_ERR(qmgr->reg_push))
1409 devm_iounmap(dev, qmgr->reg_push);
1410 if (!IS_ERR(qmgr->reg_pop))
1411 devm_iounmap(dev, qmgr->reg_pop);
1412 devm_kfree(dev, qmgr);
1413 continue;
1414 }
1415
1416 list_add_tail(&qmgr->list, &kdev->qmgrs);
1417 dev_info(dev, "added qmgr start queue %d, num of queues %d, reg_peek %p, reg_status %p, reg_config %p, reg_region %p, reg_push %p, reg_pop %p\n",
1418 qmgr->start_queue, qmgr->num_queues,
1419 qmgr->reg_peek, qmgr->reg_status,
1420 qmgr->reg_config, qmgr->reg_region,
1421 qmgr->reg_push, qmgr->reg_pop);
1422 }
1423 return 0;
1424}
1425
1426static int knav_queue_init_pdsps(struct knav_device *kdev,
1427 struct device_node *pdsps)
1428{
1429 struct device *dev = kdev->dev;
1430 struct knav_pdsp_info *pdsp;
1431 struct device_node *child;
1432 int ret;
1433
1434 for_each_child_of_node(pdsps, child) {
1435 pdsp = devm_kzalloc(dev, sizeof(*pdsp), GFP_KERNEL);
1436 if (!pdsp) {
1437 dev_err(dev, "out of memory allocating pdsp\n");
1438 return -ENOMEM;
1439 }
1440 pdsp->name = knav_queue_find_name(child);
1441 ret = of_property_read_string(child, "firmware",
1442 &pdsp->firmware);
1443 if (ret < 0 || !pdsp->firmware) {
1444 dev_err(dev, "unknown firmware for pdsp %s\n",
1445 pdsp->name);
1446 devm_kfree(dev, pdsp);
1447 continue;
1448 }
1449 dev_dbg(dev, "pdsp name %s fw name :%s\n", pdsp->name,
1450 pdsp->firmware);
1451
1452 pdsp->iram =
1453 knav_queue_map_reg(kdev, child,
1454 KNAV_QUEUE_PDSP_IRAM_REG_INDEX);
1455 pdsp->regs =
1456 knav_queue_map_reg(kdev, child,
1457 KNAV_QUEUE_PDSP_REGS_REG_INDEX);
1458 pdsp->intd =
1459 knav_queue_map_reg(kdev, child,
1460 KNAV_QUEUE_PDSP_INTD_REG_INDEX);
1461 pdsp->command =
1462 knav_queue_map_reg(kdev, child,
1463 KNAV_QUEUE_PDSP_CMD_REG_INDEX);
1464
1465 if (IS_ERR(pdsp->command) || IS_ERR(pdsp->iram) ||
1466 IS_ERR(pdsp->regs) || IS_ERR(pdsp->intd)) {
1467 dev_err(dev, "failed to map pdsp %s regs\n",
1468 pdsp->name);
1469 if (!IS_ERR(pdsp->command))
1470 devm_iounmap(dev, pdsp->command);
1471 if (!IS_ERR(pdsp->iram))
1472 devm_iounmap(dev, pdsp->iram);
1473 if (!IS_ERR(pdsp->regs))
1474 devm_iounmap(dev, pdsp->regs);
1475 if (!IS_ERR(pdsp->intd))
1476 devm_iounmap(dev, pdsp->intd);
1477 devm_kfree(dev, pdsp);
1478 continue;
1479 }
1480 of_property_read_u32(child, "id", &pdsp->id);
1481 list_add_tail(&pdsp->list, &kdev->pdsps);
1482 dev_dbg(dev, "added pdsp %s: command %p, iram %p, regs %p, intd %p, firmware %s\n",
1483 pdsp->name, pdsp->command, pdsp->iram, pdsp->regs,
1484 pdsp->intd, pdsp->firmware);
1485 }
1486 return 0;
1487}
1488
1489static int knav_queue_stop_pdsp(struct knav_device *kdev,
1490 struct knav_pdsp_info *pdsp)
1491{
1492 u32 val, timeout = 1000;
1493 int ret;
1494
1495 val = readl_relaxed(&pdsp->regs->control) & ~PDSP_CTRL_ENABLE;
1496 writel_relaxed(val, &pdsp->regs->control);
1497 ret = knav_queue_pdsp_wait(&pdsp->regs->control, timeout,
1498 PDSP_CTRL_RUNNING);
1499 if (ret < 0) {
1500 dev_err(kdev->dev, "timed out on pdsp %s stop\n", pdsp->name);
1501 return ret;
1502 }
1503 return 0;
1504}
1505
1506static int knav_queue_load_pdsp(struct knav_device *kdev,
1507 struct knav_pdsp_info *pdsp)
1508{
1509 int i, ret, fwlen;
1510 const struct firmware *fw;
1511 u32 *fwdata;
1512
1513 ret = request_firmware(&fw, pdsp->firmware, kdev->dev);
1514 if (ret) {
1515 dev_err(kdev->dev, "failed to get firmware %s for pdsp %s\n",
1516 pdsp->firmware, pdsp->name);
1517 return ret;
1518 }
1519 writel_relaxed(pdsp->id + 1, pdsp->command + 0x18);
1520 /* download the firmware */
1521 fwdata = (u32 *)fw->data;
1522 fwlen = (fw->size + sizeof(u32) - 1) / sizeof(u32);
1523 for (i = 0; i < fwlen; i++)
1524 writel_relaxed(be32_to_cpu(fwdata[i]), pdsp->iram + i);
1525
1526 release_firmware(fw);
1527 return 0;
1528}
1529
1530static int knav_queue_start_pdsp(struct knav_device *kdev,
1531 struct knav_pdsp_info *pdsp)
1532{
1533 u32 val, timeout = 1000;
1534 int ret;
1535
1536 /* write a command for sync */
1537 writel_relaxed(0xffffffff, pdsp->command);
1538 while (readl_relaxed(pdsp->command) != 0xffffffff)
1539 cpu_relax();
1540
1541 /* soft reset the PDSP */
1542 val = readl_relaxed(&pdsp->regs->control);
1543 val &= ~(PDSP_CTRL_PC_MASK | PDSP_CTRL_SOFT_RESET);
1544 writel_relaxed(val, &pdsp->regs->control);
1545
1546 /* enable pdsp */
1547 val = readl_relaxed(&pdsp->regs->control) | PDSP_CTRL_ENABLE;
1548 writel_relaxed(val, &pdsp->regs->control);
1549
1550 /* wait for command register to clear */
1551 ret = knav_queue_pdsp_wait(pdsp->command, timeout, 0);
1552 if (ret < 0) {
1553 dev_err(kdev->dev,
1554 "timed out on pdsp %s command register wait\n",
1555 pdsp->name);
1556 return ret;
1557 }
1558 return 0;
1559}
1560
1561static void knav_queue_stop_pdsps(struct knav_device *kdev)
1562{
1563 struct knav_pdsp_info *pdsp;
1564
1565 /* disable all pdsps */
1566 for_each_pdsp(kdev, pdsp)
1567 knav_queue_stop_pdsp(kdev, pdsp);
1568}
1569
1570static int knav_queue_start_pdsps(struct knav_device *kdev)
1571{
1572 struct knav_pdsp_info *pdsp;
1573 int ret;
1574
1575 knav_queue_stop_pdsps(kdev);
1576 /* now load them all */
1577 for_each_pdsp(kdev, pdsp) {
1578 ret = knav_queue_load_pdsp(kdev, pdsp);
1579 if (ret < 0)
1580 return ret;
1581 }
1582
1583 for_each_pdsp(kdev, pdsp) {
1584 ret = knav_queue_start_pdsp(kdev, pdsp);
1585 WARN_ON(ret);
1586 }
1587 return 0;
1588}
1589
1590static inline struct knav_qmgr_info *knav_find_qmgr(unsigned id)
1591{
1592 struct knav_qmgr_info *qmgr;
1593
1594 for_each_qmgr(kdev, qmgr) {
1595 if ((id >= qmgr->start_queue) &&
1596 (id < qmgr->start_queue + qmgr->num_queues))
1597 return qmgr;
1598 }
1599 return NULL;
1600}
1601
1602static int knav_queue_init_queue(struct knav_device *kdev,
1603 struct knav_range_info *range,
1604 struct knav_queue_inst *inst,
1605 unsigned id)
1606{
1607 char irq_name[KNAV_NAME_SIZE];
1608 inst->qmgr = knav_find_qmgr(id);
1609 if (!inst->qmgr)
1610 return -1;
1611
1612 INIT_LIST_HEAD(&inst->handles);
1613 inst->kdev = kdev;
1614 inst->range = range;
1615 inst->irq_num = -1;
1616 inst->id = id;
1617 scnprintf(irq_name, sizeof(irq_name), "hwqueue-%d", id);
1618 inst->irq_name = kstrndup(irq_name, sizeof(irq_name), GFP_KERNEL);
1619
1620 if (range->ops && range->ops->init_queue)
1621 return range->ops->init_queue(range, inst);
1622 else
1623 return 0;
1624}
1625
1626static int knav_queue_init_queues(struct knav_device *kdev)
1627{
1628 struct knav_range_info *range;
1629 int size, id, base_idx;
1630 int idx = 0, ret = 0;
1631
1632 /* how much do we need for instance data? */
1633 size = sizeof(struct knav_queue_inst);
1634
1635 /* round this up to a power of 2, keep the index to instance
1636 * arithmetic fast.
1637 * */
1638 kdev->inst_shift = order_base_2(size);
1639 size = (1 << kdev->inst_shift) * kdev->num_queues_in_use;
1640 kdev->instances = devm_kzalloc(kdev->dev, size, GFP_KERNEL);
1641 if (!kdev->instances)
1642 return -1;
1643
1644 for_each_queue_range(kdev, range) {
1645 if (range->ops && range->ops->init_range)
1646 range->ops->init_range(range);
1647 base_idx = idx;
1648 for (id = range->queue_base;
1649 id < range->queue_base + range->num_queues; id++, idx++) {
1650 ret = knav_queue_init_queue(kdev, range,
1651 knav_queue_idx_to_inst(kdev, idx), id);
1652 if (ret < 0)
1653 return ret;
1654 }
1655 range->queue_base_inst =
1656 knav_queue_idx_to_inst(kdev, base_idx);
1657 }
1658 return 0;
1659}
1660
1661static int knav_queue_probe(struct platform_device *pdev)
1662{
1663 struct device_node *node = pdev->dev.of_node;
1664 struct device_node *qmgrs, *queue_pools, *regions, *pdsps;
1665 struct device *dev = &pdev->dev;
1666 u32 temp[2];
1667 int ret;
1668
1669 if (!node) {
1670 dev_err(dev, "device tree info unavailable\n");
1671 return -ENODEV;
1672 }
1673
1674 kdev = devm_kzalloc(dev, sizeof(struct knav_device), GFP_KERNEL);
1675 if (!kdev) {
1676 dev_err(dev, "memory allocation failed\n");
1677 return -ENOMEM;
1678 }
1679
1680 platform_set_drvdata(pdev, kdev);
1681 kdev->dev = dev;
1682 INIT_LIST_HEAD(&kdev->queue_ranges);
1683 INIT_LIST_HEAD(&kdev->qmgrs);
1684 INIT_LIST_HEAD(&kdev->pools);
1685 INIT_LIST_HEAD(&kdev->regions);
1686 INIT_LIST_HEAD(&kdev->pdsps);
1687
1688 pm_runtime_enable(&pdev->dev);
1689 ret = pm_runtime_get_sync(&pdev->dev);
1690 if (ret < 0) {
1691 dev_err(dev, "Failed to enable QMSS\n");
1692 return ret;
1693 }
1694
1695 if (of_property_read_u32_array(node, "queue-range", temp, 2)) {
1696 dev_err(dev, "queue-range not specified\n");
1697 ret = -ENODEV;
1698 goto err;
1699 }
1700 kdev->base_id = temp[0];
1701 kdev->num_queues = temp[1];
1702
1703 /* Initialize queue managers using device tree configuration */
1704 qmgrs = of_get_child_by_name(node, "qmgrs");
1705 if (!qmgrs) {
1706 dev_err(dev, "queue manager info not specified\n");
1707 ret = -ENODEV;
1708 goto err;
1709 }
1710 ret = knav_queue_init_qmgrs(kdev, qmgrs);
1711 of_node_put(qmgrs);
1712 if (ret)
1713 goto err;
1714
1715 /* get pdsp configuration values from device tree */
1716 pdsps = of_get_child_by_name(node, "pdsps");
1717 if (pdsps) {
1718 ret = knav_queue_init_pdsps(kdev, pdsps);
1719 if (ret)
1720 goto err;
1721
1722 ret = knav_queue_start_pdsps(kdev);
1723 if (ret)
1724 goto err;
1725 }
1726 of_node_put(pdsps);
1727
1728 /* get usable queue range values from device tree */
1729 queue_pools = of_get_child_by_name(node, "queue-pools");
1730 if (!queue_pools) {
1731 dev_err(dev, "queue-pools not specified\n");
1732 ret = -ENODEV;
1733 goto err;
1734 }
1735 ret = knav_setup_queue_pools(kdev, queue_pools);
1736 of_node_put(queue_pools);
1737 if (ret)
1738 goto err;
1739
1740 ret = knav_get_link_ram(kdev, "linkram0", &kdev->link_rams[0]);
1741 if (ret) {
1742 dev_err(kdev->dev, "could not setup linking ram\n");
1743 goto err;
1744 }
1745
1746 ret = knav_get_link_ram(kdev, "linkram1", &kdev->link_rams[1]);
1747 if (ret) {
1748 /*
1749 * nothing really, we have one linking ram already, so we just
1750 * live within our means
1751 */
1752 }
1753
1754 ret = knav_queue_setup_link_ram(kdev);
1755 if (ret)
1756 goto err;
1757
1758 regions = of_get_child_by_name(node, "descriptor-regions");
1759 if (!regions) {
1760 dev_err(dev, "descriptor-regions not specified\n");
1761 goto err;
1762 }
1763 ret = knav_queue_setup_regions(kdev, regions);
1764 of_node_put(regions);
1765 if (ret)
1766 goto err;
1767
1768 ret = knav_queue_init_queues(kdev);
1769 if (ret < 0) {
1770 dev_err(dev, "hwqueue initialization failed\n");
1771 goto err;
1772 }
1773
1774 debugfs_create_file("qmss", S_IFREG | S_IRUGO, NULL, NULL,
1775 &knav_queue_debug_ops);
1776 return 0;
1777
1778err:
1779 knav_queue_stop_pdsps(kdev);
1780 knav_queue_free_regions(kdev);
1781 knav_free_queue_ranges(kdev);
1782 pm_runtime_put_sync(&pdev->dev);
1783 pm_runtime_disable(&pdev->dev);
1784 return ret;
1785}
1786
1787static int knav_queue_remove(struct platform_device *pdev)
1788{
1789 /* TODO: Free resources */
1790 pm_runtime_put_sync(&pdev->dev);
1791 pm_runtime_disable(&pdev->dev);
1792 return 0;
1793}
1794
1795/* Match table for of_platform binding */
1796static struct of_device_id keystone_qmss_of_match[] = {
1797 { .compatible = "ti,keystone-navigator-qmss", },
1798 {},
1799};
1800MODULE_DEVICE_TABLE(of, keystone_qmss_of_match);
1801
1802static struct platform_driver keystone_qmss_driver = {
1803 .probe = knav_queue_probe,
1804 .remove = knav_queue_remove,
1805 .driver = {
1806 .name = "keystone-navigator-qmss",
1807 .owner = THIS_MODULE,
1808 .of_match_table = keystone_qmss_of_match,
1809 },
1810};
1811module_platform_driver(keystone_qmss_driver);
1812
1813MODULE_LICENSE("GPL v2");
1814MODULE_DESCRIPTION("TI QMSS driver for Keystone SOCs");
1815MODULE_AUTHOR("Sandeep Nair <sandeep_n@ti.com>");
1816MODULE_AUTHOR("Santosh Shilimkar <santosh.shilimkar@ti.com>");
diff --git a/drivers/soc/versatile/Kconfig b/drivers/soc/versatile/Kconfig
new file mode 100644
index 000000000000..bf5ee9c85330
--- /dev/null
+++ b/drivers/soc/versatile/Kconfig
@@ -0,0 +1,10 @@
1#
2# ARM Versatile SoC drivers
3#
4config SOC_REALVIEW
5 bool "SoC bus device for the ARM RealView platforms"
6 depends on ARCH_REALVIEW
7 select SOC_BUS
8 help
9 Include support for the SoC bus on the ARM RealView platforms
10 providing some sysfs information about the ASIC variant.
diff --git a/drivers/soc/versatile/Makefile b/drivers/soc/versatile/Makefile
new file mode 100644
index 000000000000..ad547435648e
--- /dev/null
+++ b/drivers/soc/versatile/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_SOC_REALVIEW) += soc-realview.o
diff --git a/drivers/soc/versatile/soc-realview.c b/drivers/soc/versatile/soc-realview.c
new file mode 100644
index 000000000000..cea8ea3491d2
--- /dev/null
+++ b/drivers/soc/versatile/soc-realview.c
@@ -0,0 +1,144 @@
1/*
2 * Copyright (C) 2014 Linaro Ltd.
3 *
4 * Author: Linus Walleij <linus.walleij@linaro.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2, as
8 * published by the Free Software Foundation.
9 *
10 */
11#include <linux/init.h>
12#include <linux/io.h>
13#include <linux/slab.h>
14#include <linux/sys_soc.h>
15#include <linux/platform_device.h>
16#include <linux/mfd/syscon.h>
17#include <linux/regmap.h>
18#include <linux/of.h>
19
20/* System ID in syscon */
21#define REALVIEW_SYS_ID_OFFSET 0x00
22
23static const struct of_device_id realview_soc_of_match[] = {
24 { .compatible = "arm,realview-eb-soc", },
25 { .compatible = "arm,realview-pb1176-soc", },
26 { .compatible = "arm,realview-pb11mp-soc", },
27 { .compatible = "arm,realview-pba8-soc", },
28 { .compatible = "arm,realview-pbx-soc", },
29};
30
31static u32 realview_coreid;
32
33static const char *realview_board_str(u32 id)
34{
35 switch ((id >> 16) & 0xfff) {
36 case 0x0147:
37 return "HBI-0147";
38 default:
39 return "Unknown";
40 }
41}
42
43static const char *realview_arch_str(u32 id)
44{
45 switch ((id >> 8) & 0xf) {
46 case 0x05:
47 return "Multi-layer AXI";
48 default:
49 return "Unknown";
50 }
51}
52
53static ssize_t realview_get_manf(struct device *dev,
54 struct device_attribute *attr,
55 char *buf)
56{
57 return sprintf(buf, "%02x\n", realview_coreid >> 24);
58}
59
60static struct device_attribute realview_manf_attr =
61 __ATTR(manufacturer, S_IRUGO, realview_get_manf, NULL);
62
63static ssize_t realview_get_board(struct device *dev,
64 struct device_attribute *attr,
65 char *buf)
66{
67 return sprintf(buf, "%s\n", realview_board_str(realview_coreid));
68}
69
70static struct device_attribute realview_board_attr =
71 __ATTR(board, S_IRUGO, realview_get_board, NULL);
72
73static ssize_t realview_get_arch(struct device *dev,
74 struct device_attribute *attr,
75 char *buf)
76{
77 return sprintf(buf, "%s\n", realview_arch_str(realview_coreid));
78}
79
80static struct device_attribute realview_arch_attr =
81 __ATTR(fpga, S_IRUGO, realview_get_arch, NULL);
82
83static ssize_t realview_get_build(struct device *dev,
84 struct device_attribute *attr,
85 char *buf)
86{
87 return sprintf(buf, "%02x\n", (realview_coreid & 0xFF));
88}
89
90static struct device_attribute realview_build_attr =
91 __ATTR(build, S_IRUGO, realview_get_build, NULL);
92
93static int realview_soc_probe(struct platform_device *pdev)
94{
95 static struct regmap *syscon_regmap;
96 struct soc_device *soc_dev;
97 struct soc_device_attribute *soc_dev_attr;
98 struct device_node *np = pdev->dev.of_node;
99 int ret;
100
101 syscon_regmap = syscon_regmap_lookup_by_phandle(np, "regmap");
102 if (IS_ERR(syscon_regmap))
103 return PTR_ERR(syscon_regmap);
104
105 soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
106 if (!soc_dev_attr)
107 return -ENOMEM;
108
109 ret = of_property_read_string(np, "compatible",
110 &soc_dev_attr->soc_id);
111 if (ret)
112 return -EINVAL;
113
114 soc_dev_attr->machine = "RealView";
115 soc_dev_attr->family = "Versatile";
116 soc_dev = soc_device_register(soc_dev_attr);
117 if (IS_ERR(soc_dev)) {
118 kfree(soc_dev_attr);
119 return -ENODEV;
120 }
121 ret = regmap_read(syscon_regmap, REALVIEW_SYS_ID_OFFSET,
122 &realview_coreid);
123 if (ret)
124 return -ENODEV;
125
126 device_create_file(soc_device_to_device(soc_dev), &realview_manf_attr);
127 device_create_file(soc_device_to_device(soc_dev), &realview_board_attr);
128 device_create_file(soc_device_to_device(soc_dev), &realview_arch_attr);
129 device_create_file(soc_device_to_device(soc_dev), &realview_build_attr);
130
131 dev_info(&pdev->dev, "RealView Syscon Core ID: 0x%08x\n",
132 realview_coreid);
133 /* FIXME: add attributes for SoC to sysfs */
134 return 0;
135}
136
137static struct platform_driver realview_soc_driver = {
138 .probe = realview_soc_probe,
139 .driver = {
140 .name = "realview-soc",
141 .of_match_table = realview_soc_of_match,
142 },
143};
144module_platform_driver(realview_soc_driver);
diff --git a/include/linux/irqchip/irq-omap-intc.h b/include/linux/irqchip/irq-omap-intc.h
new file mode 100644
index 000000000000..e06b370cfc0d
--- /dev/null
+++ b/include/linux/irqchip/irq-omap-intc.h
@@ -0,0 +1,32 @@
1/**
2 * irq-omap-intc.h - INTC Idle Functions
3 *
4 * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
5 *
6 * Author: Felipe Balbi <balbi@ti.com>
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 of
10 * the License as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#ifndef __INCLUDE_LINUX_IRQCHIP_IRQ_OMAP_INTC_H
19#define __INCLUDE_LINUX_IRQCHIP_IRQ_OMAP_INTC_H
20
21void omap2_init_irq(void);
22void omap3_init_irq(void);
23void ti81xx_init_irq(void);
24
25int omap_irq_pending(void);
26void omap_intc_save_context(void);
27void omap_intc_restore_context(void);
28void omap3_intc_suspend(void);
29void omap3_intc_prepare_idle(void);
30void omap3_intc_resume_idle(void);
31
32#endif /* __INCLUDE_LINUX_IRQCHIP_IRQ_OMAP_INTC_H */
diff --git a/include/linux/soc/ti/knav_dma.h b/include/linux/soc/ti/knav_dma.h
new file mode 100644
index 000000000000..dad035c16d94
--- /dev/null
+++ b/include/linux/soc/ti/knav_dma.h
@@ -0,0 +1,175 @@
1/*
2 * Copyright (C) 2014 Texas Instruments Incorporated
3 * Authors: Sandeep Nair <sandeep_n@ti.com
4 * Cyril Chemparathy <cyril@ti.com
5 Santosh Shilimkar <santosh.shilimkar@ti.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation version 2.
10 *
11 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
12 * kind, whether express or implied; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#ifndef __SOC_TI_KEYSTONE_NAVIGATOR_DMA_H__
18#define __SOC_TI_KEYSTONE_NAVIGATOR_DMA_H__
19
20/*
21 * PKTDMA descriptor manipulation macros for host packet descriptor
22 */
23#define MASK(x) (BIT(x) - 1)
24#define KNAV_DMA_DESC_PKT_LEN_MASK MASK(22)
25#define KNAV_DMA_DESC_PKT_LEN_SHIFT 0
26#define KNAV_DMA_DESC_PS_INFO_IN_SOP BIT(22)
27#define KNAV_DMA_DESC_PS_INFO_IN_DESC 0
28#define KNAV_DMA_DESC_TAG_MASK MASK(8)
29#define KNAV_DMA_DESC_SAG_HI_SHIFT 24
30#define KNAV_DMA_DESC_STAG_LO_SHIFT 16
31#define KNAV_DMA_DESC_DTAG_HI_SHIFT 8
32#define KNAV_DMA_DESC_DTAG_LO_SHIFT 0
33#define KNAV_DMA_DESC_HAS_EPIB BIT(31)
34#define KNAV_DMA_DESC_NO_EPIB 0
35#define KNAV_DMA_DESC_PSLEN_SHIFT 24
36#define KNAV_DMA_DESC_PSLEN_MASK MASK(6)
37#define KNAV_DMA_DESC_ERR_FLAG_SHIFT 20
38#define KNAV_DMA_DESC_ERR_FLAG_MASK MASK(4)
39#define KNAV_DMA_DESC_PSFLAG_SHIFT 16
40#define KNAV_DMA_DESC_PSFLAG_MASK MASK(4)
41#define KNAV_DMA_DESC_RETQ_SHIFT 0
42#define KNAV_DMA_DESC_RETQ_MASK MASK(14)
43#define KNAV_DMA_DESC_BUF_LEN_MASK MASK(22)
44
45#define KNAV_DMA_NUM_EPIB_WORDS 4
46#define KNAV_DMA_NUM_PS_WORDS 16
47#define KNAV_DMA_FDQ_PER_CHAN 4
48
49/* Tx channel scheduling priority */
50enum knav_dma_tx_priority {
51 DMA_PRIO_HIGH = 0,
52 DMA_PRIO_MED_H,
53 DMA_PRIO_MED_L,
54 DMA_PRIO_LOW
55};
56
57/* Rx channel error handling mode during buffer starvation */
58enum knav_dma_rx_err_mode {
59 DMA_DROP = 0,
60 DMA_RETRY
61};
62
63/* Rx flow size threshold configuration */
64enum knav_dma_rx_thresholds {
65 DMA_THRESH_NONE = 0,
66 DMA_THRESH_0 = 1,
67 DMA_THRESH_0_1 = 3,
68 DMA_THRESH_0_1_2 = 7
69};
70
71/* Descriptor type */
72enum knav_dma_desc_type {
73 DMA_DESC_HOST = 0,
74 DMA_DESC_MONOLITHIC = 2
75};
76
77/**
78 * struct knav_dma_tx_cfg: Tx channel configuration
79 * @filt_einfo: Filter extended packet info
80 * @filt_pswords: Filter PS words present
81 * @knav_dma_tx_priority: Tx channel scheduling priority
82 */
83struct knav_dma_tx_cfg {
84 bool filt_einfo;
85 bool filt_pswords;
86 enum knav_dma_tx_priority priority;
87};
88
89/**
90 * struct knav_dma_rx_cfg: Rx flow configuration
91 * @einfo_present: Extended packet info present
92 * @psinfo_present: PS words present
93 * @knav_dma_rx_err_mode: Error during buffer starvation
94 * @knav_dma_desc_type: Host or Monolithic desc
95 * @psinfo_at_sop: PS word located at start of packet
96 * @sop_offset: Start of packet offset
97 * @dst_q: Destination queue for a given flow
98 * @thresh: Rx flow size threshold
99 * @fdq[]: Free desc Queue array
100 * @sz_thresh0: RX packet size threshold 0
101 * @sz_thresh1: RX packet size threshold 1
102 * @sz_thresh2: RX packet size threshold 2
103 */
104struct knav_dma_rx_cfg {
105 bool einfo_present;
106 bool psinfo_present;
107 enum knav_dma_rx_err_mode err_mode;
108 enum knav_dma_desc_type desc_type;
109 bool psinfo_at_sop;
110 unsigned int sop_offset;
111 unsigned int dst_q;
112 enum knav_dma_rx_thresholds thresh;
113 unsigned int fdq[KNAV_DMA_FDQ_PER_CHAN];
114 unsigned int sz_thresh0;
115 unsigned int sz_thresh1;
116 unsigned int sz_thresh2;
117};
118
119/**
120 * struct knav_dma_cfg: Pktdma channel configuration
121 * @sl_cfg: Slave configuration
122 * @tx: Tx channel configuration
123 * @rx: Rx flow configuration
124 */
125struct knav_dma_cfg {
126 enum dma_transfer_direction direction;
127 union {
128 struct knav_dma_tx_cfg tx;
129 struct knav_dma_rx_cfg rx;
130 } u;
131};
132
133/**
134 * struct knav_dma_desc: Host packet descriptor layout
135 * @desc_info: Descriptor information like id, type, length
136 * @tag_info: Flow tag info written in during RX
137 * @packet_info: Queue Manager, policy, flags etc
138 * @buff_len: Buffer length in bytes
139 * @buff: Buffer pointer
140 * @next_desc: For chaining the descriptors
141 * @orig_len: length since 'buff_len' can be overwritten
142 * @orig_buff: buff pointer since 'buff' can be overwritten
143 * @epib: Extended packet info block
144 * @psdata: Protocol specific
145 */
146struct knav_dma_desc {
147 u32 desc_info;
148 u32 tag_info;
149 u32 packet_info;
150 u32 buff_len;
151 u32 buff;
152 u32 next_desc;
153 u32 orig_len;
154 u32 orig_buff;
155 u32 epib[KNAV_DMA_NUM_EPIB_WORDS];
156 u32 psdata[KNAV_DMA_NUM_PS_WORDS];
157 u32 pad[4];
158} ____cacheline_aligned;
159
160#if IS_ENABLED(CONFIG_KEYSTONE_NAVIGATOR_DMA)
161void *knav_dma_open_channel(struct device *dev, const char *name,
162 struct knav_dma_cfg *config);
163void knav_dma_close_channel(void *channel);
164#else
165static inline void *knav_dma_open_channel(struct device *dev, const char *name,
166 struct knav_dma_cfg *config)
167{
168 return (void *) NULL;
169}
170static inline void knav_dma_close_channel(void *channel)
171{}
172
173#endif
174
175#endif /* __SOC_TI_KEYSTONE_NAVIGATOR_DMA_H__ */
diff --git a/include/linux/soc/ti/knav_qmss.h b/include/linux/soc/ti/knav_qmss.h
new file mode 100644
index 000000000000..9f0ebb3bad27
--- /dev/null
+++ b/include/linux/soc/ti/knav_qmss.h
@@ -0,0 +1,90 @@
1/*
2 * Keystone Navigator Queue Management Sub-System header
3 *
4 * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
5 * Author: Sandeep Nair <sandeep_n@ti.com>
6 * Cyril Chemparathy <cyril@ti.com>
7 * Santosh Shilimkar <santosh.shilimkar@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation version 2.
12 *
13 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
14 * kind, whether express or implied; without even the implied warranty
15 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#ifndef __SOC_TI_KNAV_QMSS_H__
20#define __SOC_TI_KNAV_QMSS_H__
21
22#include <linux/err.h>
23#include <linux/time.h>
24#include <linux/atomic.h>
25#include <linux/device.h>
26#include <linux/fcntl.h>
27#include <linux/dma-mapping.h>
28
29/* queue types */
30#define KNAV_QUEUE_QPEND ((unsigned)-2) /* interruptible qpend queue */
31#define KNAV_QUEUE_ACC ((unsigned)-3) /* Accumulated queue */
32#define KNAV_QUEUE_GP ((unsigned)-4) /* General purpose queue */
33
34/* queue flags */
35#define KNAV_QUEUE_SHARED 0x0001 /* Queue can be shared */
36
37/**
38 * enum knav_queue_ctrl_cmd - queue operations.
39 * @KNAV_QUEUE_GET_ID: Get the ID number for an open queue
40 * @KNAV_QUEUE_FLUSH: forcibly empty a queue if possible
41 * @KNAV_QUEUE_SET_NOTIFIER: Set a notifier callback to a queue handle.
42 * @KNAV_QUEUE_ENABLE_NOTIFY: Enable notifier callback for a queue handle.
43 * @KNAV_QUEUE_DISABLE_NOTIFY: Disable notifier callback for a queue handle.
44 * @KNAV_QUEUE_GET_COUNT: Get number of queues.
45 */
46enum knav_queue_ctrl_cmd {
47 KNAV_QUEUE_GET_ID,
48 KNAV_QUEUE_FLUSH,
49 KNAV_QUEUE_SET_NOTIFIER,
50 KNAV_QUEUE_ENABLE_NOTIFY,
51 KNAV_QUEUE_DISABLE_NOTIFY,
52 KNAV_QUEUE_GET_COUNT
53};
54
55/* Queue notifier callback prototype */
56typedef void (*knav_queue_notify_fn)(void *arg);
57
58/**
59 * struct knav_queue_notify_config: Notifier configuration
60 * @fn: Notifier function
61 * @fn_arg: Notifier function arguments
62 */
63struct knav_queue_notify_config {
64 knav_queue_notify_fn fn;
65 void *fn_arg;
66};
67
68void *knav_queue_open(const char *name, unsigned id,
69 unsigned flags);
70void knav_queue_close(void *qhandle);
71int knav_queue_device_control(void *qhandle,
72 enum knav_queue_ctrl_cmd cmd,
73 unsigned long arg);
74dma_addr_t knav_queue_pop(void *qhandle, unsigned *size);
75int knav_queue_push(void *qhandle, dma_addr_t dma,
76 unsigned size, unsigned flags);
77
78void *knav_pool_create(const char *name,
79 int num_desc, int region_id);
80void knav_pool_destroy(void *ph);
81int knav_pool_count(void *ph);
82void *knav_pool_desc_get(void *ph);
83void knav_pool_desc_put(void *ph, void *desc);
84int knav_pool_desc_map(void *ph, void *desc, unsigned size,
85 dma_addr_t *dma, unsigned *dma_sz);
86void *knav_pool_desc_unmap(void *ph, dma_addr_t dma, unsigned dma_sz);
87dma_addr_t knav_pool_desc_virt_to_dma(void *ph, void *virt);
88void *knav_pool_desc_dma_to_virt(void *ph, dma_addr_t dma);
89
90#endif /* __SOC_TI_KNAV_QMSS_H__ */