aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-05 20:46:42 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-05 20:46:42 -0400
commite7fda6c4c3c1a7d6996dd75fd84670fa0b5d448f (patch)
treedaa51c16462c318b890acf7f01fba5827275dd74 /Documentation
parent08d69a25714429850cf9ef71f22d8cdc9189d93f (diff)
parent953dec21aed4038464fec02f96a2f1b8701a5bce (diff)
Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer and time updates from Thomas Gleixner: "A rather large update of timers, timekeeping & co - Core timekeeping code is year-2038 safe now for 32bit machines. Now we just need to fix all in kernel users and the gazillion of user space interfaces which rely on timespec/timeval :) - Better cache layout for the timekeeping internal data structures. - Proper nanosecond based interfaces for in kernel users. - Tree wide cleanup of code which wants nanoseconds but does hoops and loops to convert back and forth from timespecs. Some of it definitely belongs into the ugly code museum. - Consolidation of the timekeeping interface zoo. - A fast NMI safe accessor to clock monotonic for tracing. This is a long standing request to support correlated user/kernel space traces. With proper NTP frequency correction it's also suitable for correlation of traces accross separate machines. - Checkpoint/restart support for timerfd. - A few NOHZ[_FULL] improvements in the [hr]timer code. - Code move from kernel to kernel/time of all time* related code. - New clocksource/event drivers from the ARM universe. I'm really impressed that despite an architected timer in the newer chips SoC manufacturers insist on inventing new and differently broken SoC specific timers. [ Ed. "Impressed"? I don't think that word means what you think it means ] - Another round of code move from arch to drivers. Looks like most of the legacy mess in ARM regarding timers is sorted out except for a few obnoxious strongholds. - The usual updates and fixlets all over the place" * 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (114 commits) timekeeping: Fixup typo in update_vsyscall_old definition clocksource: document some basic timekeeping concepts timekeeping: Use cached ntp_tick_length when accumulating error timekeeping: Rework frequency adjustments to work better w/ nohz timekeeping: Minor fixup for timespec64->timespec assignment ftrace: Provide trace clocks monotonic timekeeping: Provide fast and NMI safe access to CLOCK_MONOTONIC seqcount: Add raw_write_seqcount_latch() seqcount: Provide raw_read_seqcount() timekeeping: Use tk_read_base as argument for timekeeping_get_ns() timekeeping: Create struct tk_read_base and use it in struct timekeeper timekeeping: Restructure the timekeeper some more clocksource: Get rid of cycle_last clocksource: Move cycle_last validation to core code clocksource: Make delta calculation a function wireless: ath9k: Get rid of timespec conversions drm: vmwgfx: Use nsec based interfaces drm: i915: Use nsec based interfaces timekeeping: Provide ktime_get_raw() hangcheck-timer: Use ktime_get_ns() ...
Diffstat (limited to 'Documentation')
-rw-r--r--Documentation/DocBook/device-drivers.tmpl4
-rw-r--r--Documentation/devicetree/bindings/timer/cirrus,clps711x-timer.txt29
-rw-r--r--Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt17
-rw-r--r--Documentation/devicetree/bindings/timer/renesas,cmt.txt47
-rw-r--r--Documentation/devicetree/bindings/timer/renesas,mtu2.txt39
-rw-r--r--Documentation/devicetree/bindings/timer/renesas,tmu.txt39
-rw-r--r--Documentation/devicetree/bindings/vendor-prefixes.txt1
-rw-r--r--Documentation/filesystems/proc.txt19
-rw-r--r--Documentation/timers/00-INDEX2
-rw-r--r--Documentation/timers/timekeeping.txt179
10 files changed, 374 insertions, 2 deletions
diff --git a/Documentation/DocBook/device-drivers.tmpl b/Documentation/DocBook/device-drivers.tmpl
index dd3f278faa8a..f2130586ef5d 100644
--- a/Documentation/DocBook/device-drivers.tmpl
+++ b/Documentation/DocBook/device-drivers.tmpl
@@ -54,7 +54,7 @@
54!Ikernel/sched/cpupri.c 54!Ikernel/sched/cpupri.c
55!Ikernel/sched/fair.c 55!Ikernel/sched/fair.c
56!Iinclude/linux/completion.h 56!Iinclude/linux/completion.h
57!Ekernel/timer.c 57!Ekernel/time/timer.c
58 </sect1> 58 </sect1>
59 <sect1><title>Wait queues and Wake events</title> 59 <sect1><title>Wait queues and Wake events</title>
60!Iinclude/linux/wait.h 60!Iinclude/linux/wait.h
@@ -63,7 +63,7 @@
63 <sect1><title>High-resolution timers</title> 63 <sect1><title>High-resolution timers</title>
64!Iinclude/linux/ktime.h 64!Iinclude/linux/ktime.h
65!Iinclude/linux/hrtimer.h 65!Iinclude/linux/hrtimer.h
66!Ekernel/hrtimer.c 66!Ekernel/time/hrtimer.c
67 </sect1> 67 </sect1>
68 <sect1><title>Workqueues and Kevents</title> 68 <sect1><title>Workqueues and Kevents</title>
69!Ekernel/workqueue.c 69!Ekernel/workqueue.c
diff --git a/Documentation/devicetree/bindings/timer/cirrus,clps711x-timer.txt b/Documentation/devicetree/bindings/timer/cirrus,clps711x-timer.txt
new file mode 100644
index 000000000000..cd55b52548e4
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/cirrus,clps711x-timer.txt
@@ -0,0 +1,29 @@
1* Cirrus Logic CLPS711X Timer Counter
2
3Required properties:
4- compatible: Shall contain "cirrus,clps711x-timer".
5- reg : Address and length of the register set.
6- interrupts: The interrupt number of the timer.
7- clocks : phandle of timer reference clock.
8
9Note: Each timer should have an alias correctly numbered in "aliases" node.
10
11Example:
12 aliases {
13 timer0 = &timer1;
14 timer1 = &timer2;
15 };
16
17 timer1: timer@80000300 {
18 compatible = "cirrus,ep7312-timer", "cirrus,clps711x-timer";
19 reg = <0x80000300 0x4>;
20 interrupts = <8>;
21 clocks = <&clks 5>;
22 };
23
24 timer2: timer@80000340 {
25 compatible = "cirrus,ep7312-timer", "cirrus,clps711x-timer";
26 reg = <0x80000340 0x4>;
27 interrupts = <9>;
28 clocks = <&clks 6>;
29 };
diff --git a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
new file mode 100644
index 000000000000..7c4408ff4b83
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
@@ -0,0 +1,17 @@
1Mediatek MT6577, MT6572 and MT6589 Timers
2---------------------------------------
3
4Required properties:
5- compatible: Should be "mediatek,mt6577-timer"
6- reg: Should contain location and length for timers register.
7- clocks: Clocks driving the timer hardware. This list should include two
8 clocks. The order is system clock and as second clock the RTC clock.
9
10Examples:
11
12 timer@10008000 {
13 compatible = "mediatek,mt6577-timer";
14 reg = <0x10008000 0x80>;
15 interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_LOW>;
16 clocks = <&system_clk>, <&rtc_clk>;
17 };
diff --git a/Documentation/devicetree/bindings/timer/renesas,cmt.txt b/Documentation/devicetree/bindings/timer/renesas,cmt.txt
new file mode 100644
index 000000000000..a17418b0ece3
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/renesas,cmt.txt
@@ -0,0 +1,47 @@
1* Renesas R-Car Compare Match Timer (CMT)
2
3The CMT is a multi-channel 16/32/48-bit timer/counter with configurable clock
4inputs and programmable compare match.
5
6Channels share hardware resources but their counter and compare match value
7are independent. A particular CMT instance can implement only a subset of the
8channels supported by the CMT model. Channel indices represent the hardware
9position of the channel in the CMT and don't match the channel numbers in the
10datasheets.
11
12Required Properties:
13
14 - compatible: must contain one of the following.
15 - "renesas,cmt-32" for the 32-bit CMT
16 (CMT0 on sh7372, sh73a0 and r8a7740)
17 - "renesas,cmt-32-fast" for the 32-bit CMT with fast clock support
18 (CMT[234] on sh7372, sh73a0 and r8a7740)
19 - "renesas,cmt-48" for the 48-bit CMT
20 (CMT1 on sh7372, sh73a0 and r8a7740)
21 - "renesas,cmt-48-gen2" for the second generation 48-bit CMT
22 (CMT[01] on r8a73a4, r8a7790 and r8a7791)
23
24 - reg: base address and length of the registers block for the timer module.
25 - interrupts: interrupt-specifier for the timer, one per channel.
26 - clocks: a list of phandle + clock-specifier pairs, one for each entry
27 in clock-names.
28 - clock-names: must contain "fck" for the functional clock.
29
30 - renesas,channels-mask: bitmask of the available channels.
31
32
33Example: R8A7790 (R-Car H2) CMT0 node
34
35 CMT0 on R8A7790 implements hardware channels 5 and 6 only and names
36 them channels 0 and 1 in the documentation.
37
38 cmt0: timer@ffca0000 {
39 compatible = "renesas,cmt-48-gen2";
40 reg = <0 0xffca0000 0 0x1004>;
41 interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>,
42 <0 142 IRQ_TYPE_LEVEL_HIGH>;
43 clocks = <&mstp1_clks R8A7790_CLK_CMT0>;
44 clock-names = "fck";
45
46 renesas,channels-mask = <0x60>;
47 };
diff --git a/Documentation/devicetree/bindings/timer/renesas,mtu2.txt b/Documentation/devicetree/bindings/timer/renesas,mtu2.txt
new file mode 100644
index 000000000000..917453f826bc
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/renesas,mtu2.txt
@@ -0,0 +1,39 @@
1* Renesas R-Car Multi-Function Timer Pulse Unit 2 (MTU2)
2
3The MTU2 is a multi-purpose, multi-channel timer/counter with configurable
4clock inputs and programmable compare match.
5
6Channels share hardware resources but their counter and compare match value
7are independent. The MTU2 hardware supports five channels indexed from 0 to 4.
8
9Required Properties:
10
11 - compatible: must contain "renesas,mtu2"
12
13 - reg: base address and length of the registers block for the timer module.
14
15 - interrupts: interrupt specifiers for the timer, one for each entry in
16 interrupt-names.
17 - interrupt-names: must contain one entry named "tgi?a" for each enabled
18 channel, where "?" is the channel index expressed as one digit from "0" to
19 "4".
20
21 - clocks: a list of phandle + clock-specifier pairs, one for each entry
22 in clock-names.
23 - clock-names: must contain "fck" for the functional clock.
24
25
26Example: R7S72100 (RZ/A1H) MTU2 node
27
28 mtu2: timer@fcff0000 {
29 compatible = "renesas,mtu2";
30 reg = <0xfcff0000 0x400>;
31 interrupts = <0 139 IRQ_TYPE_LEVEL_HIGH>,
32 <0 146 IRQ_TYPE_LEVEL_HIGH>,
33 <0 150 IRQ_TYPE_LEVEL_HIGH>,
34 <0 154 IRQ_TYPE_LEVEL_HIGH>,
35 <0 159 IRQ_TYPE_LEVEL_HIGH>;
36 interrupt-names = "tgi0a", "tgi1a", "tgi2a", "tgi3a", "tgi4a";
37 clocks = <&mstp3_clks R7S72100_CLK_MTU2>;
38 clock-names = "fck";
39 };
diff --git a/Documentation/devicetree/bindings/timer/renesas,tmu.txt b/Documentation/devicetree/bindings/timer/renesas,tmu.txt
new file mode 100644
index 000000000000..425d0c5f4aee
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/renesas,tmu.txt
@@ -0,0 +1,39 @@
1* Renesas R-Car Timer Unit (TMU)
2
3The TMU is a 32-bit timer/counter with configurable clock inputs and
4programmable compare match.
5
6Channels share hardware resources but their counter and compare match value
7are independent. The TMU hardware supports up to three channels.
8
9Required Properties:
10
11 - compatible: must contain "renesas,tmu"
12
13 - reg: base address and length of the registers block for the timer module.
14
15 - interrupts: interrupt-specifier for the timer, one per channel.
16
17 - clocks: a list of phandle + clock-specifier pairs, one for each entry
18 in clock-names.
19 - clock-names: must contain "fck" for the functional clock.
20
21Optional Properties:
22
23 - #renesas,channels: number of channels implemented by the timer, must be 2
24 or 3 (if not specified the value defaults to 3).
25
26
27Example: R8A7779 (R-Car H1) TMU0 node
28
29 tmu0: timer@ffd80000 {
30 compatible = "renesas,tmu";
31 reg = <0xffd80000 0x30>;
32 interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>,
33 <0 33 IRQ_TYPE_LEVEL_HIGH>,
34 <0 34 IRQ_TYPE_LEVEL_HIGH>;
35 clocks = <&mstp0_clks R8A7779_CLK_TMU0>;
36 clock-names = "fck";
37
38 #renesas,channels = <3>;
39 };
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 97c9c06132c4..d415b38ec8ca 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -78,6 +78,7 @@ lsi LSI Corp. (LSI Logic)
78lltc Linear Technology Corporation 78lltc Linear Technology Corporation
79marvell Marvell Technology Group Ltd. 79marvell Marvell Technology Group Ltd.
80maxim Maxim Integrated Products 80maxim Maxim Integrated Products
81mediatek MediaTek Inc.
81micrel Micrel Inc. 82micrel Micrel Inc.
82microchip Microchip Technology Inc. 83microchip Microchip Technology Inc.
83mosaixtech Mosaix Technologies, Inc. 84mosaixtech Mosaix Technologies, Inc.
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index ddc531a74d04..eb8a10e22f7c 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -1743,6 +1743,25 @@ pair provide additional information particular to the objects they represent.
1743 While the first three lines are mandatory and always printed, the rest is 1743 While the first three lines are mandatory and always printed, the rest is
1744 optional and may be omitted if no marks created yet. 1744 optional and may be omitted if no marks created yet.
1745 1745
1746 Timerfd files
1747 ~~~~~~~~~~~~~
1748
1749 pos: 0
1750 flags: 02
1751 mnt_id: 9
1752 clockid: 0
1753 ticks: 0
1754 settime flags: 01
1755 it_value: (0, 49406829)
1756 it_interval: (1, 0)
1757
1758 where 'clockid' is the clock type and 'ticks' is the number of the timer expirations
1759 that have occurred [see timerfd_create(2) for details]. 'settime flags' are
1760 flags in octal form been used to setup the timer [see timerfd_settime(2) for
1761 details]. 'it_value' is remaining time until the timer exiration.
1762 'it_interval' is the interval for the timer. Note the timer might be set up
1763 with TIMER_ABSTIME option which will be shown in 'settime flags', but 'it_value'
1764 still exhibits timer's remaining time.
1746 1765
1747------------------------------------------------------------------------------ 1766------------------------------------------------------------------------------
1748Configuring procfs 1767Configuring procfs
diff --git a/Documentation/timers/00-INDEX b/Documentation/timers/00-INDEX
index 6d042dc1cce0..ee212a27772f 100644
--- a/Documentation/timers/00-INDEX
+++ b/Documentation/timers/00-INDEX
@@ -12,6 +12,8 @@ Makefile
12 - Build and link hpet_example 12 - Build and link hpet_example
13NO_HZ.txt 13NO_HZ.txt
14 - Summary of the different methods for the scheduler clock-interrupts management. 14 - Summary of the different methods for the scheduler clock-interrupts management.
15timekeeping.txt
16 - Clock sources, clock events, sched_clock() and delay timer notes
15timers-howto.txt 17timers-howto.txt
16 - how to insert delays in the kernel the right (tm) way. 18 - how to insert delays in the kernel the right (tm) way.
17timer_stats.txt 19timer_stats.txt
diff --git a/Documentation/timers/timekeeping.txt b/Documentation/timers/timekeeping.txt
new file mode 100644
index 000000000000..f3a8cf28f802
--- /dev/null
+++ b/Documentation/timers/timekeeping.txt
@@ -0,0 +1,179 @@
1Clock sources, Clock events, sched_clock() and delay timers
2-----------------------------------------------------------
3
4This document tries to briefly explain some basic kernel timekeeping
5abstractions. It partly pertains to the drivers usually found in
6drivers/clocksource in the kernel tree, but the code may be spread out
7across the kernel.
8
9If you grep through the kernel source you will find a number of architecture-
10specific implementations of clock sources, clockevents and several likewise
11architecture-specific overrides of the sched_clock() function and some
12delay timers.
13
14To provide timekeeping for your platform, the clock source provides
15the basic timeline, whereas clock events shoot interrupts on certain points
16on this timeline, providing facilities such as high-resolution timers.
17sched_clock() is used for scheduling and timestamping, and delay timers
18provide an accurate delay source using hardware counters.
19
20
21Clock sources
22-------------
23
24The purpose of the clock source is to provide a timeline for the system that
25tells you where you are in time. For example issuing the command 'date' on
26a Linux system will eventually read the clock source to determine exactly
27what time it is.
28
29Typically the clock source is a monotonic, atomic counter which will provide
30n bits which count from 0 to 2^(n-1) and then wraps around to 0 and start over.
31It will ideally NEVER stop ticking as long as the system is running. It
32may stop during system suspend.
33
34The clock source shall have as high resolution as possible, and the frequency
35shall be as stable and correct as possible as compared to a real-world wall
36clock. It should not move unpredictably back and forth in time or miss a few
37cycles here and there.
38
39It must be immune to the kind of effects that occur in hardware where e.g.
40the counter register is read in two phases on the bus lowest 16 bits first
41and the higher 16 bits in a second bus cycle with the counter bits
42potentially being updated in between leading to the risk of very strange
43values from the counter.
44
45When the wall-clock accuracy of the clock source isn't satisfactory, there
46are various quirks and layers in the timekeeping code for e.g. synchronizing
47the user-visible time to RTC clocks in the system or against networked time
48servers using NTP, but all they do basically is update an offset against
49the clock source, which provides the fundamental timeline for the system.
50These measures does not affect the clock source per se, they only adapt the
51system to the shortcomings of it.
52
53The clock source struct shall provide means to translate the provided counter
54into a nanosecond value as an unsigned long long (unsigned 64 bit) number.
55Since this operation may be invoked very often, doing this in a strict
56mathematical sense is not desirable: instead the number is taken as close as
57possible to a nanosecond value using only the arithmetic operations
58multiply and shift, so in clocksource_cyc2ns() you find:
59
60 ns ~= (clocksource * mult) >> shift
61
62You will find a number of helper functions in the clock source code intended
63to aid in providing these mult and shift values, such as
64clocksource_khz2mult(), clocksource_hz2mult() that help determine the
65mult factor from a fixed shift, and clocksource_register_hz() and
66clocksource_register_khz() which will help out assigning both shift and mult
67factors using the frequency of the clock source as the only input.
68
69For real simple clock sources accessed from a single I/O memory location
70there is nowadays even clocksource_mmio_init() which will take a memory
71location, bit width, a parameter telling whether the counter in the
72register counts up or down, and the timer clock rate, and then conjure all
73necessary parameters.
74
75Since a 32-bit counter at say 100 MHz will wrap around to zero after some 43
76seconds, the code handling the clock source will have to compensate for this.
77That is the reason why the clock source struct also contains a 'mask'
78member telling how many bits of the source are valid. This way the timekeeping
79code knows when the counter will wrap around and can insert the necessary
80compensation code on both sides of the wrap point so that the system timeline
81remains monotonic.
82
83
84Clock events
85------------
86
87Clock events are the conceptual reverse of clock sources: they take a
88desired time specification value and calculate the values to poke into
89hardware timer registers.
90
91Clock events are orthogonal to clock sources. The same hardware
92and register range may be used for the clock event, but it is essentially
93a different thing. The hardware driving clock events has to be able to
94fire interrupts, so as to trigger events on the system timeline. On an SMP
95system, it is ideal (and customary) to have one such event driving timer per
96CPU core, so that each core can trigger events independently of any other
97core.
98
99You will notice that the clock event device code is based on the same basic
100idea about translating counters to nanoseconds using mult and shift
101arithmetic, and you find the same family of helper functions again for
102assigning these values. The clock event driver does not need a 'mask'
103attribute however: the system will not try to plan events beyond the time
104horizon of the clock event.
105
106
107sched_clock()
108-------------
109
110In addition to the clock sources and clock events there is a special weak
111function in the kernel called sched_clock(). This function shall return the
112number of nanoseconds since the system was started. An architecture may or
113may not provide an implementation of sched_clock() on its own. If a local
114implementation is not provided, the system jiffy counter will be used as
115sched_clock().
116
117As the name suggests, sched_clock() is used for scheduling the system,
118determining the absolute timeslice for a certain process in the CFS scheduler
119for example. It is also used for printk timestamps when you have selected to
120include time information in printk for things like bootcharts.
121
122Compared to clock sources, sched_clock() has to be very fast: it is called
123much more often, especially by the scheduler. If you have to do trade-offs
124between accuracy compared to the clock source, you may sacrifice accuracy
125for speed in sched_clock(). It however requires some of the same basic
126characteristics as the clock source, i.e. it should be monotonic.
127
128The sched_clock() function may wrap only on unsigned long long boundaries,
129i.e. after 64 bits. Since this is a nanosecond value this will mean it wraps
130after circa 585 years. (For most practical systems this means "never".)
131
132If an architecture does not provide its own implementation of this function,
133it will fall back to using jiffies, making its maximum resolution 1/HZ of the
134jiffy frequency for the architecture. This will affect scheduling accuracy
135and will likely show up in system benchmarks.
136
137The clock driving sched_clock() may stop or reset to zero during system
138suspend/sleep. This does not matter to the function it serves of scheduling
139events on the system. However it may result in interesting timestamps in
140printk().
141
142The sched_clock() function should be callable in any context, IRQ- and
143NMI-safe and return a sane value in any context.
144
145Some architectures may have a limited set of time sources and lack a nice
146counter to derive a 64-bit nanosecond value, so for example on the ARM
147architecture, special helper functions have been created to provide a
148sched_clock() nanosecond base from a 16- or 32-bit counter. Sometimes the
149same counter that is also used as clock source is used for this purpose.
150
151On SMP systems, it is crucial for performance that sched_clock() can be called
152independently on each CPU without any synchronization performance hits.
153Some hardware (such as the x86 TSC) will cause the sched_clock() function to
154drift between the CPUs on the system. The kernel can work around this by
155enabling the CONFIG_HAVE_UNSTABLE_SCHED_CLOCK option. This is another aspect
156that makes sched_clock() different from the ordinary clock source.
157
158
159Delay timers (some architectures only)
160--------------------------------------
161
162On systems with variable CPU frequency, the various kernel delay() functions
163will sometimes behave strangely. Basically these delays usually use a hard
164loop to delay a certain number of jiffy fractions using a "lpj" (loops per
165jiffy) value, calibrated on boot.
166
167Let's hope that your system is running on maximum frequency when this value
168is calibrated: as an effect when the frequency is geared down to half the
169full frequency, any delay() will be twice as long. Usually this does not
170hurt, as you're commonly requesting that amount of delay *or more*. But
171basically the semantics are quite unpredictable on such systems.
172
173Enter timer-based delays. Using these, a timer read may be used instead of
174a hard-coded loop for providing the desired delay.
175
176This is done by declaring a struct delay_timer and assigning the appropriate
177function pointers and rate settings for this delay timer.
178
179This is available on some architectures like OpenRISC or ARM.