Merge branch 'linus' into x86/x2apic
This commit is contained in:
commit
a208f37a46
|
@ -26,3 +26,37 @@ Description:
|
||||||
I/O statistics of partition <part>. The format is the
|
I/O statistics of partition <part>. The format is the
|
||||||
same as the above-written /sys/block/<disk>/stat
|
same as the above-written /sys/block/<disk>/stat
|
||||||
format.
|
format.
|
||||||
|
|
||||||
|
|
||||||
|
What: /sys/block/<disk>/integrity/format
|
||||||
|
Date: June 2008
|
||||||
|
Contact: Martin K. Petersen <martin.petersen@oracle.com>
|
||||||
|
Description:
|
||||||
|
Metadata format for integrity capable block device.
|
||||||
|
E.g. T10-DIF-TYPE1-CRC.
|
||||||
|
|
||||||
|
|
||||||
|
What: /sys/block/<disk>/integrity/read_verify
|
||||||
|
Date: June 2008
|
||||||
|
Contact: Martin K. Petersen <martin.petersen@oracle.com>
|
||||||
|
Description:
|
||||||
|
Indicates whether the block layer should verify the
|
||||||
|
integrity of read requests serviced by devices that
|
||||||
|
support sending integrity metadata.
|
||||||
|
|
||||||
|
|
||||||
|
What: /sys/block/<disk>/integrity/tag_size
|
||||||
|
Date: June 2008
|
||||||
|
Contact: Martin K. Petersen <martin.petersen@oracle.com>
|
||||||
|
Description:
|
||||||
|
Number of bytes of integrity tag space available per
|
||||||
|
512 bytes of data.
|
||||||
|
|
||||||
|
|
||||||
|
What: /sys/block/<disk>/integrity/write_generate
|
||||||
|
Date: June 2008
|
||||||
|
Contact: Martin K. Petersen <martin.petersen@oracle.com>
|
||||||
|
Description:
|
||||||
|
Indicates whether the block layer should automatically
|
||||||
|
generate checksums for write requests bound for
|
||||||
|
devices that support receiving integrity metadata.
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
What: /sys/bus/css/devices/.../type
|
||||||
|
Date: March 2008
|
||||||
|
Contact: Cornelia Huck <cornelia.huck@de.ibm.com>
|
||||||
|
linux-s390@vger.kernel.org
|
||||||
|
Description: Contains the subchannel type, as reported by the hardware.
|
||||||
|
This attribute is present for all subchannel types.
|
||||||
|
|
||||||
|
What: /sys/bus/css/devices/.../modalias
|
||||||
|
Date: March 2008
|
||||||
|
Contact: Cornelia Huck <cornelia.huck@de.ibm.com>
|
||||||
|
linux-s390@vger.kernel.org
|
||||||
|
Description: Contains the module alias as reported with uevents.
|
||||||
|
It is of the format css:t<type> and present for all
|
||||||
|
subchannel types.
|
||||||
|
|
||||||
|
What: /sys/bus/css/drivers/io_subchannel/.../chpids
|
||||||
|
Date: December 2002
|
||||||
|
Contact: Cornelia Huck <cornelia.huck@de.ibm.com>
|
||||||
|
linux-s390@vger.kernel.org
|
||||||
|
Description: Contains the ids of the channel paths used by this
|
||||||
|
subchannel, as reported by the channel subsystem
|
||||||
|
during subchannel recognition.
|
||||||
|
Note: This is an I/O-subchannel specific attribute.
|
||||||
|
Users: s390-tools, HAL
|
||||||
|
|
||||||
|
What: /sys/bus/css/drivers/io_subchannel/.../pimpampom
|
||||||
|
Date: December 2002
|
||||||
|
Contact: Cornelia Huck <cornelia.huck@de.ibm.com>
|
||||||
|
linux-s390@vger.kernel.org
|
||||||
|
Description: Contains the PIM/PAM/POM values, as reported by the
|
||||||
|
channel subsystem when last queried by the common I/O
|
||||||
|
layer (this implies that this attribute is not neccessarily
|
||||||
|
in sync with the values current in the channel subsystem).
|
||||||
|
Note: This is an I/O-subchannel specific attribute.
|
||||||
|
Users: s390-tools, HAL
|
|
@ -30,45 +30,45 @@ Description:
|
||||||
$ cd /sys/firmware/acpi/interrupts
|
$ cd /sys/firmware/acpi/interrupts
|
||||||
$ grep . *
|
$ grep . *
|
||||||
error: 0
|
error: 0
|
||||||
ff_gbl_lock:0
|
ff_gbl_lock: 0 enable
|
||||||
ff_pmtimer:0
|
ff_pmtimer: 0 invalid
|
||||||
ff_pwr_btn:0
|
ff_pwr_btn: 0 enable
|
||||||
ff_rt_clk:0
|
ff_rt_clk: 2 disable
|
||||||
ff_slp_btn:0
|
ff_slp_btn: 0 invalid
|
||||||
gpe00:0
|
gpe00: 0 invalid
|
||||||
gpe01:0
|
gpe01: 0 enable
|
||||||
gpe02:0
|
gpe02: 108 enable
|
||||||
gpe03:0
|
gpe03: 0 invalid
|
||||||
gpe04:0
|
gpe04: 0 invalid
|
||||||
gpe05:0
|
gpe05: 0 invalid
|
||||||
gpe06:0
|
gpe06: 0 enable
|
||||||
gpe07:0
|
gpe07: 0 enable
|
||||||
gpe08:0
|
gpe08: 0 invalid
|
||||||
gpe09:174
|
gpe09: 0 invalid
|
||||||
gpe0A:0
|
gpe0A: 0 invalid
|
||||||
gpe0B:0
|
gpe0B: 0 invalid
|
||||||
gpe0C:0
|
gpe0C: 0 invalid
|
||||||
gpe0D:0
|
gpe0D: 0 invalid
|
||||||
gpe0E:0
|
gpe0E: 0 invalid
|
||||||
gpe0F:0
|
gpe0F: 0 invalid
|
||||||
gpe10:0
|
gpe10: 0 invalid
|
||||||
gpe11:60
|
gpe11: 0 invalid
|
||||||
gpe12:0
|
gpe12: 0 invalid
|
||||||
gpe13:0
|
gpe13: 0 invalid
|
||||||
gpe14:0
|
gpe14: 0 invalid
|
||||||
gpe15:0
|
gpe15: 0 invalid
|
||||||
gpe16:0
|
gpe16: 0 invalid
|
||||||
gpe17:0
|
gpe17: 1084 enable
|
||||||
gpe18:0
|
gpe18: 0 enable
|
||||||
gpe19:7
|
gpe19: 0 invalid
|
||||||
gpe1A:0
|
gpe1A: 0 invalid
|
||||||
gpe1B:0
|
gpe1B: 0 invalid
|
||||||
gpe1C:0
|
gpe1C: 0 invalid
|
||||||
gpe1D:0
|
gpe1D: 0 invalid
|
||||||
gpe1E:0
|
gpe1E: 0 invalid
|
||||||
gpe1F:0
|
gpe1F: 0 invalid
|
||||||
gpe_all:241
|
gpe_all: 1192
|
||||||
sci:241
|
sci: 1194
|
||||||
|
|
||||||
sci - The total number of times the ACPI SCI
|
sci - The total number of times the ACPI SCI
|
||||||
has claimed an interrupt.
|
has claimed an interrupt.
|
||||||
|
@ -89,6 +89,13 @@ Description:
|
||||||
|
|
||||||
error - an interrupt that can't be accounted for above.
|
error - an interrupt that can't be accounted for above.
|
||||||
|
|
||||||
|
invalid: it's either a wakeup GPE or a GPE/Fixed Event that
|
||||||
|
doesn't have an event handler.
|
||||||
|
|
||||||
|
disable: the GPE/Fixed Event is valid but disabled.
|
||||||
|
|
||||||
|
enable: the GPE/Fixed Event is valid and enabled.
|
||||||
|
|
||||||
Root has permission to clear any of these counters. Eg.
|
Root has permission to clear any of these counters. Eg.
|
||||||
# echo 0 > gpe11
|
# echo 0 > gpe11
|
||||||
|
|
||||||
|
@ -97,3 +104,43 @@ Description:
|
||||||
|
|
||||||
None of these counters has an effect on the function
|
None of these counters has an effect on the function
|
||||||
of the system, they are simply statistics.
|
of the system, they are simply statistics.
|
||||||
|
|
||||||
|
Besides this, user can also write specific strings to these files
|
||||||
|
to enable/disable/clear ACPI interrupts in user space, which can be
|
||||||
|
used to debug some ACPI interrupt storm issues.
|
||||||
|
|
||||||
|
Note that only writting to VALID GPE/Fixed Event is allowed,
|
||||||
|
i.e. user can only change the status of runtime GPE and
|
||||||
|
Fixed Event with event handler installed.
|
||||||
|
|
||||||
|
Let's take power button fixed event for example, please kill acpid
|
||||||
|
and other user space applications so that the machine won't shutdown
|
||||||
|
when pressing the power button.
|
||||||
|
# cat ff_pwr_btn
|
||||||
|
0
|
||||||
|
# press the power button for 3 times;
|
||||||
|
# cat ff_pwr_btn
|
||||||
|
3
|
||||||
|
# echo disable > ff_pwr_btn
|
||||||
|
# cat ff_pwr_btn
|
||||||
|
disable
|
||||||
|
# press the power button for 3 times;
|
||||||
|
# cat ff_pwr_btn
|
||||||
|
disable
|
||||||
|
# echo enable > ff_pwr_btn
|
||||||
|
# cat ff_pwr_btn
|
||||||
|
4
|
||||||
|
/*
|
||||||
|
* this is because the status bit is set even if the enable bit is cleared,
|
||||||
|
* and it triggers an ACPI fixed event when the enable bit is set again
|
||||||
|
*/
|
||||||
|
# press the power button for 3 times;
|
||||||
|
# cat ff_pwr_btn
|
||||||
|
7
|
||||||
|
# echo disable > ff_pwr_btn
|
||||||
|
# press the power button for 3 times;
|
||||||
|
# echo clear > ff_pwr_btn /* clear the status bit */
|
||||||
|
# echo disable > ff_pwr_btn
|
||||||
|
# cat ff_pwr_btn
|
||||||
|
7
|
||||||
|
|
||||||
|
|
|
@ -377,7 +377,7 @@ Bug Reporting
|
||||||
bugzilla.kernel.org is where the Linux kernel developers track kernel
|
bugzilla.kernel.org is where the Linux kernel developers track kernel
|
||||||
bugs. Users are encouraged to report all bugs that they find in this
|
bugs. Users are encouraged to report all bugs that they find in this
|
||||||
tool. For details on how to use the kernel bugzilla, please see:
|
tool. For details on how to use the kernel bugzilla, please see:
|
||||||
http://test.kernel.org/bugzilla/faq.html
|
http://bugzilla.kernel.org/page.cgi?id=faq.html
|
||||||
|
|
||||||
The file REPORTING-BUGS in the main kernel source directory has a good
|
The file REPORTING-BUGS in the main kernel source directory has a good
|
||||||
template for how to report a possible kernel bug, and details what kind
|
template for how to report a possible kernel bug, and details what kind
|
||||||
|
|
|
@ -1,17 +1,26 @@
|
||||||
|
ChangeLog:
|
||||||
|
Started by Ingo Molnar <mingo@redhat.com>
|
||||||
|
Update by Max Krasnyansky <maxk@qualcomm.com>
|
||||||
|
|
||||||
SMP IRQ affinity, started by Ingo Molnar <mingo@redhat.com>
|
SMP IRQ affinity
|
||||||
|
|
||||||
|
|
||||||
/proc/irq/IRQ#/smp_affinity specifies which target CPUs are permitted
|
/proc/irq/IRQ#/smp_affinity specifies which target CPUs are permitted
|
||||||
for a given IRQ source. It's a bitmask of allowed CPUs. It's not allowed
|
for a given IRQ source. It's a bitmask of allowed CPUs. It's not allowed
|
||||||
to turn off all CPUs, and if an IRQ controller does not support IRQ
|
to turn off all CPUs, and if an IRQ controller does not support IRQ
|
||||||
affinity then the value will not change from the default 0xffffffff.
|
affinity then the value will not change from the default 0xffffffff.
|
||||||
|
|
||||||
Here is an example of restricting IRQ44 (eth1) to CPU0-3 then restricting
|
/proc/irq/default_smp_affinity specifies default affinity mask that applies
|
||||||
the IRQ to CPU4-7 (this is an 8-CPU SMP box):
|
to all non-active IRQs. Once IRQ is allocated/activated its affinity bitmask
|
||||||
|
will be set to the default mask. It can then be changed as described above.
|
||||||
|
Default mask is 0xffffffff.
|
||||||
|
|
||||||
|
Here is an example of restricting IRQ44 (eth1) to CPU0-3 then restricting
|
||||||
|
it to CPU4-7 (this is an 8-CPU SMP box):
|
||||||
|
|
||||||
|
[root@moon 44]# cd /proc/irq/44
|
||||||
[root@moon 44]# cat smp_affinity
|
[root@moon 44]# cat smp_affinity
|
||||||
ffffffff
|
ffffffff
|
||||||
|
|
||||||
[root@moon 44]# echo 0f > smp_affinity
|
[root@moon 44]# echo 0f > smp_affinity
|
||||||
[root@moon 44]# cat smp_affinity
|
[root@moon 44]# cat smp_affinity
|
||||||
0000000f
|
0000000f
|
||||||
|
@ -21,17 +30,27 @@ PING hell (195.4.7.3): 56 data bytes
|
||||||
--- hell ping statistics ---
|
--- hell ping statistics ---
|
||||||
6029 packets transmitted, 6027 packets received, 0% packet loss
|
6029 packets transmitted, 6027 packets received, 0% packet loss
|
||||||
round-trip min/avg/max = 0.1/0.1/0.4 ms
|
round-trip min/avg/max = 0.1/0.1/0.4 ms
|
||||||
[root@moon 44]# cat /proc/interrupts | grep 44:
|
[root@moon 44]# cat /proc/interrupts | grep 'CPU\|44:'
|
||||||
44: 0 1785 1785 1783 1783 1
|
CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7
|
||||||
1 0 IO-APIC-level eth1
|
44: 1068 1785 1785 1783 0 0 0 0 IO-APIC-level eth1
|
||||||
|
|
||||||
|
As can be seen from the line above IRQ44 was delivered only to the first four
|
||||||
|
processors (0-3).
|
||||||
|
Now lets restrict that IRQ to CPU(4-7).
|
||||||
|
|
||||||
[root@moon 44]# echo f0 > smp_affinity
|
[root@moon 44]# echo f0 > smp_affinity
|
||||||
|
[root@moon 44]# cat smp_affinity
|
||||||
|
000000f0
|
||||||
[root@moon 44]# ping -f h
|
[root@moon 44]# ping -f h
|
||||||
PING hell (195.4.7.3): 56 data bytes
|
PING hell (195.4.7.3): 56 data bytes
|
||||||
..
|
..
|
||||||
--- hell ping statistics ---
|
--- hell ping statistics ---
|
||||||
2779 packets transmitted, 2777 packets received, 0% packet loss
|
2779 packets transmitted, 2777 packets received, 0% packet loss
|
||||||
round-trip min/avg/max = 0.1/0.5/585.4 ms
|
round-trip min/avg/max = 0.1/0.5/585.4 ms
|
||||||
[root@moon 44]# cat /proc/interrupts | grep 44:
|
[root@moon 44]# cat /proc/interrupts | 'CPU\|44:'
|
||||||
44: 1068 1785 1785 1784 1784 1069 1070 1069 IO-APIC-level eth1
|
CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7
|
||||||
[root@moon 44]#
|
44: 1068 1785 1785 1783 1784 1069 1070 1069 IO-APIC-level eth1
|
||||||
|
|
||||||
|
This time around IRQ44 was delivered only to the last four processors.
|
||||||
|
i.e counters for the CPU0-3 did not change.
|
||||||
|
|
||||||
|
|
|
@ -93,6 +93,9 @@ Since NMI handlers disable preemption, synchronize_sched() is guaranteed
|
||||||
not to return until all ongoing NMI handlers exit. It is therefore safe
|
not to return until all ongoing NMI handlers exit. It is therefore safe
|
||||||
to free up the handler's data as soon as synchronize_sched() returns.
|
to free up the handler's data as soon as synchronize_sched() returns.
|
||||||
|
|
||||||
|
Important note: for this to work, the architecture in question must
|
||||||
|
invoke irq_enter() and irq_exit() on NMI entry and exit, respectively.
|
||||||
|
|
||||||
|
|
||||||
Answer to Quick Quiz
|
Answer to Quick Quiz
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,10 @@ of each iteration. Unfortunately, chaotic relaxation requires highly
|
||||||
structured data, such as the matrices used in scientific programs, and
|
structured data, such as the matrices used in scientific programs, and
|
||||||
is thus inapplicable to most data structures in operating-system kernels.
|
is thus inapplicable to most data structures in operating-system kernels.
|
||||||
|
|
||||||
|
In 1992, Henry (now Alexia) Massalin completed a dissertation advising
|
||||||
|
parallel programmers to defer processing when feasible to simplify
|
||||||
|
synchronization. RCU makes extremely heavy use of this advice.
|
||||||
|
|
||||||
In 1993, Jacobson [Jacobson93] verbally described what is perhaps the
|
In 1993, Jacobson [Jacobson93] verbally described what is perhaps the
|
||||||
simplest deferred-free technique: simply waiting a fixed amount of time
|
simplest deferred-free technique: simply waiting a fixed amount of time
|
||||||
before freeing blocks awaiting deferred free. Jacobson did not describe
|
before freeing blocks awaiting deferred free. Jacobson did not describe
|
||||||
|
@ -138,6 +142,13 @@ blocking in read-side critical sections appeared [PaulEMcKenney2006c],
|
||||||
Robert Olsson described an RCU-protected trie-hash combination
|
Robert Olsson described an RCU-protected trie-hash combination
|
||||||
[RobertOlsson2006a].
|
[RobertOlsson2006a].
|
||||||
|
|
||||||
|
2007 saw the journal version of the award-winning RCU paper from 2006
|
||||||
|
[ThomasEHart2007a], as well as a paper demonstrating use of Promela
|
||||||
|
and Spin to mechanically verify an optimization to Oleg Nesterov's
|
||||||
|
QRCU [PaulEMcKenney2007QRCUspin], a design document describing
|
||||||
|
preemptible RCU [PaulEMcKenney2007PreemptibleRCU], and the three-part
|
||||||
|
LWN "What is RCU?" series [PaulEMcKenney2007WhatIsRCUFundamentally,
|
||||||
|
PaulEMcKenney2008WhatIsRCUUsage, and PaulEMcKenney2008WhatIsRCUAPI].
|
||||||
|
|
||||||
Bibtex Entries
|
Bibtex Entries
|
||||||
|
|
||||||
|
@ -202,6 +213,20 @@ Bibtex Entries
|
||||||
,Year="1991"
|
,Year="1991"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@phdthesis{HMassalinPhD
|
||||||
|
,author="H. Massalin"
|
||||||
|
,title="Synthesis: An Efficient Implementation of Fundamental Operating
|
||||||
|
System Services"
|
||||||
|
,school="Columbia University"
|
||||||
|
,address="New York, NY"
|
||||||
|
,year="1992"
|
||||||
|
,annotation="
|
||||||
|
Mondo optimizing compiler.
|
||||||
|
Wait-free stuff.
|
||||||
|
Good advice: defer work to avoid synchronization.
|
||||||
|
"
|
||||||
|
}
|
||||||
|
|
||||||
@unpublished{Jacobson93
|
@unpublished{Jacobson93
|
||||||
,author="Van Jacobson"
|
,author="Van Jacobson"
|
||||||
,title="Avoid Read-Side Locking Via Delayed Free"
|
,title="Avoid Read-Side Locking Via Delayed Free"
|
||||||
|
@ -635,3 +660,86 @@ Revised:
|
||||||
"
|
"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@unpublished{PaulEMcKenney2007PreemptibleRCU
|
||||||
|
,Author="Paul E. McKenney"
|
||||||
|
,Title="The design of preemptible read-copy-update"
|
||||||
|
,month="October"
|
||||||
|
,day="8"
|
||||||
|
,year="2007"
|
||||||
|
,note="Available:
|
||||||
|
\url{http://lwn.net/Articles/253651/}
|
||||||
|
[Viewed October 25, 2007]"
|
||||||
|
,annotation="
|
||||||
|
LWN article describing the design of preemptible RCU.
|
||||||
|
"
|
||||||
|
}
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
#
|
||||||
|
# "What is RCU?" LWN series.
|
||||||
|
#
|
||||||
|
|
||||||
|
@unpublished{PaulEMcKenney2007WhatIsRCUFundamentally
|
||||||
|
,Author="Paul E. McKenney and Jonathan Walpole"
|
||||||
|
,Title="What is {RCU}, Fundamentally?"
|
||||||
|
,month="December"
|
||||||
|
,day="17"
|
||||||
|
,year="2007"
|
||||||
|
,note="Available:
|
||||||
|
\url{http://lwn.net/Articles/262464/}
|
||||||
|
[Viewed December 27, 2007]"
|
||||||
|
,annotation="
|
||||||
|
Lays out the three basic components of RCU: (1) publish-subscribe,
|
||||||
|
(2) wait for pre-existing readers to complete, and (2) maintain
|
||||||
|
multiple versions.
|
||||||
|
"
|
||||||
|
}
|
||||||
|
|
||||||
|
@unpublished{PaulEMcKenney2008WhatIsRCUUsage
|
||||||
|
,Author="Paul E. McKenney"
|
||||||
|
,Title="What is {RCU}? Part 2: Usage"
|
||||||
|
,month="January"
|
||||||
|
,day="4"
|
||||||
|
,year="2008"
|
||||||
|
,note="Available:
|
||||||
|
\url{http://lwn.net/Articles/263130/}
|
||||||
|
[Viewed January 4, 2008]"
|
||||||
|
,annotation="
|
||||||
|
Lays out six uses of RCU:
|
||||||
|
1. RCU is a Reader-Writer Lock Replacement
|
||||||
|
2. RCU is a Restricted Reference-Counting Mechanism
|
||||||
|
3. RCU is a Bulk Reference-Counting Mechanism
|
||||||
|
4. RCU is a Poor Man's Garbage Collector
|
||||||
|
5. RCU is a Way of Providing Existence Guarantees
|
||||||
|
6. RCU is a Way of Waiting for Things to Finish
|
||||||
|
"
|
||||||
|
}
|
||||||
|
|
||||||
|
@unpublished{PaulEMcKenney2008WhatIsRCUAPI
|
||||||
|
,Author="Paul E. McKenney"
|
||||||
|
,Title="{RCU} part 3: the {RCU} {API}"
|
||||||
|
,month="January"
|
||||||
|
,day="17"
|
||||||
|
,year="2008"
|
||||||
|
,note="Available:
|
||||||
|
\url{http://lwn.net/Articles/264090/}
|
||||||
|
[Viewed January 10, 2008]"
|
||||||
|
,annotation="
|
||||||
|
Gives an overview of the Linux-kernel RCU API and a brief annotated RCU
|
||||||
|
bibliography.
|
||||||
|
"
|
||||||
|
}
|
||||||
|
|
||||||
|
@article{DinakarGuniguntala2008IBMSysJ
|
||||||
|
,author="D. Guniguntala and P. E. McKenney and J. Triplett and J. Walpole"
|
||||||
|
,title="The read-copy-update mechanism for supporting real-time applications on shared-memory multiprocessor systems with {Linux}"
|
||||||
|
,Year="2008"
|
||||||
|
,Month="April"
|
||||||
|
,journal="IBM Systems Journal"
|
||||||
|
,volume="47"
|
||||||
|
,number="2"
|
||||||
|
,pages="@@-@@"
|
||||||
|
,annotation="
|
||||||
|
RCU, realtime RCU, sleepable RCU, performance.
|
||||||
|
"
|
||||||
|
}
|
||||||
|
|
|
@ -13,10 +13,13 @@ over a rather long period of time, but improvements are always welcome!
|
||||||
detailed performance measurements show that RCU is nonetheless
|
detailed performance measurements show that RCU is nonetheless
|
||||||
the right tool for the job.
|
the right tool for the job.
|
||||||
|
|
||||||
The other exception would be where performance is not an issue,
|
Another exception is where performance is not an issue, and RCU
|
||||||
and RCU provides a simpler implementation. An example of this
|
provides a simpler implementation. An example of this situation
|
||||||
situation is the dynamic NMI code in the Linux 2.6 kernel,
|
is the dynamic NMI code in the Linux 2.6 kernel, at least on
|
||||||
at least on architectures where NMIs are rare.
|
architectures where NMIs are rare.
|
||||||
|
|
||||||
|
Yet another exception is where the low real-time latency of RCU's
|
||||||
|
read-side primitives is critically important.
|
||||||
|
|
||||||
1. Does the update code have proper mutual exclusion?
|
1. Does the update code have proper mutual exclusion?
|
||||||
|
|
||||||
|
@ -39,9 +42,10 @@ over a rather long period of time, but improvements are always welcome!
|
||||||
|
|
||||||
2. Do the RCU read-side critical sections make proper use of
|
2. Do the RCU read-side critical sections make proper use of
|
||||||
rcu_read_lock() and friends? These primitives are needed
|
rcu_read_lock() and friends? These primitives are needed
|
||||||
to suppress preemption (or bottom halves, in the case of
|
to prevent grace periods from ending prematurely, which
|
||||||
rcu_read_lock_bh()) in the read-side critical sections,
|
could result in data being unceremoniously freed out from
|
||||||
and are also an excellent aid to readability.
|
under your read-side code, which can greatly increase the
|
||||||
|
actuarial risk of your kernel.
|
||||||
|
|
||||||
As a rough rule of thumb, any dereference of an RCU-protected
|
As a rough rule of thumb, any dereference of an RCU-protected
|
||||||
pointer must be covered by rcu_read_lock() or rcu_read_lock_bh()
|
pointer must be covered by rcu_read_lock() or rcu_read_lock_bh()
|
||||||
|
@ -54,15 +58,30 @@ over a rather long period of time, but improvements are always welcome!
|
||||||
be running while updates are in progress. There are a number
|
be running while updates are in progress. There are a number
|
||||||
of ways to handle this concurrency, depending on the situation:
|
of ways to handle this concurrency, depending on the situation:
|
||||||
|
|
||||||
a. Make updates appear atomic to readers. For example,
|
a. Use the RCU variants of the list and hlist update
|
||||||
|
primitives to add, remove, and replace elements on an
|
||||||
|
RCU-protected list. Alternatively, use the RCU-protected
|
||||||
|
trees that have been added to the Linux kernel.
|
||||||
|
|
||||||
|
This is almost always the best approach.
|
||||||
|
|
||||||
|
b. Proceed as in (a) above, but also maintain per-element
|
||||||
|
locks (that are acquired by both readers and writers)
|
||||||
|
that guard per-element state. Of course, fields that
|
||||||
|
the readers refrain from accessing can be guarded by the
|
||||||
|
update-side lock.
|
||||||
|
|
||||||
|
This works quite well, also.
|
||||||
|
|
||||||
|
c. Make updates appear atomic to readers. For example,
|
||||||
pointer updates to properly aligned fields will appear
|
pointer updates to properly aligned fields will appear
|
||||||
atomic, as will individual atomic primitives. Operations
|
atomic, as will individual atomic primitives. Operations
|
||||||
performed under a lock and sequences of multiple atomic
|
performed under a lock and sequences of multiple atomic
|
||||||
primitives will -not- appear to be atomic.
|
primitives will -not- appear to be atomic.
|
||||||
|
|
||||||
This is almost always the best approach.
|
This can work, but is starting to get a bit tricky.
|
||||||
|
|
||||||
b. Carefully order the updates and the reads so that
|
d. Carefully order the updates and the reads so that
|
||||||
readers see valid data at all phases of the update.
|
readers see valid data at all phases of the update.
|
||||||
This is often more difficult than it sounds, especially
|
This is often more difficult than it sounds, especially
|
||||||
given modern CPUs' tendency to reorder memory references.
|
given modern CPUs' tendency to reorder memory references.
|
||||||
|
@ -123,18 +142,22 @@ over a rather long period of time, but improvements are always welcome!
|
||||||
when publicizing a pointer to a structure that can
|
when publicizing a pointer to a structure that can
|
||||||
be traversed by an RCU read-side critical section.
|
be traversed by an RCU read-side critical section.
|
||||||
|
|
||||||
5. If call_rcu(), or a related primitive such as call_rcu_bh(),
|
5. If call_rcu(), or a related primitive such as call_rcu_bh() or
|
||||||
is used, the callback function must be written to be called
|
call_rcu_sched(), is used, the callback function must be
|
||||||
from softirq context. In particular, it cannot block.
|
written to be called from softirq context. In particular,
|
||||||
|
it cannot block.
|
||||||
|
|
||||||
6. Since synchronize_rcu() can block, it cannot be called from
|
6. Since synchronize_rcu() can block, it cannot be called from
|
||||||
any sort of irq context.
|
any sort of irq context. Ditto for synchronize_sched() and
|
||||||
|
synchronize_srcu().
|
||||||
|
|
||||||
7. If the updater uses call_rcu(), then the corresponding readers
|
7. If the updater uses call_rcu(), then the corresponding readers
|
||||||
must use rcu_read_lock() and rcu_read_unlock(). If the updater
|
must use rcu_read_lock() and rcu_read_unlock(). If the updater
|
||||||
uses call_rcu_bh(), then the corresponding readers must use
|
uses call_rcu_bh(), then the corresponding readers must use
|
||||||
rcu_read_lock_bh() and rcu_read_unlock_bh(). Mixing things up
|
rcu_read_lock_bh() and rcu_read_unlock_bh(). If the updater
|
||||||
will result in confusion and broken kernels.
|
uses call_rcu_sched(), then the corresponding readers must
|
||||||
|
disable preemption. Mixing things up will result in confusion
|
||||||
|
and broken kernels.
|
||||||
|
|
||||||
One exception to this rule: rcu_read_lock() and rcu_read_unlock()
|
One exception to this rule: rcu_read_lock() and rcu_read_unlock()
|
||||||
may be substituted for rcu_read_lock_bh() and rcu_read_unlock_bh()
|
may be substituted for rcu_read_lock_bh() and rcu_read_unlock_bh()
|
||||||
|
@ -143,9 +166,9 @@ over a rather long period of time, but improvements are always welcome!
|
||||||
such cases is a must, of course! And the jury is still out on
|
such cases is a must, of course! And the jury is still out on
|
||||||
whether the increased speed is worth it.
|
whether the increased speed is worth it.
|
||||||
|
|
||||||
8. Although synchronize_rcu() is a bit slower than is call_rcu(),
|
8. Although synchronize_rcu() is slower than is call_rcu(), it
|
||||||
it usually results in simpler code. So, unless update
|
usually results in simpler code. So, unless update performance
|
||||||
performance is critically important or the updaters cannot block,
|
is critically important or the updaters cannot block,
|
||||||
synchronize_rcu() should be used in preference to call_rcu().
|
synchronize_rcu() should be used in preference to call_rcu().
|
||||||
|
|
||||||
An especially important property of the synchronize_rcu()
|
An especially important property of the synchronize_rcu()
|
||||||
|
@ -187,23 +210,23 @@ over a rather long period of time, but improvements are always welcome!
|
||||||
number of updates per grace period.
|
number of updates per grace period.
|
||||||
|
|
||||||
9. All RCU list-traversal primitives, which include
|
9. All RCU list-traversal primitives, which include
|
||||||
list_for_each_rcu(), list_for_each_entry_rcu(),
|
rcu_dereference(), list_for_each_rcu(), list_for_each_entry_rcu(),
|
||||||
list_for_each_continue_rcu(), and list_for_each_safe_rcu(),
|
list_for_each_continue_rcu(), and list_for_each_safe_rcu(),
|
||||||
must be within an RCU read-side critical section. RCU
|
must be either within an RCU read-side critical section or
|
||||||
|
must be protected by appropriate update-side locks. RCU
|
||||||
read-side critical sections are delimited by rcu_read_lock()
|
read-side critical sections are delimited by rcu_read_lock()
|
||||||
and rcu_read_unlock(), or by similar primitives such as
|
and rcu_read_unlock(), or by similar primitives such as
|
||||||
rcu_read_lock_bh() and rcu_read_unlock_bh().
|
rcu_read_lock_bh() and rcu_read_unlock_bh().
|
||||||
|
|
||||||
Use of the _rcu() list-traversal primitives outside of an
|
The reason that it is permissible to use RCU list-traversal
|
||||||
RCU read-side critical section causes no harm other than
|
primitives when the update-side lock is held is that doing so
|
||||||
a slight performance degradation on Alpha CPUs. It can
|
can be quite helpful in reducing code bloat when common code is
|
||||||
also be quite helpful in reducing code bloat when common
|
shared between readers and updaters.
|
||||||
code is shared between readers and updaters.
|
|
||||||
|
|
||||||
10. Conversely, if you are in an RCU read-side critical section,
|
10. Conversely, if you are in an RCU read-side critical section,
|
||||||
you -must- use the "_rcu()" variants of the list macros.
|
and you don't hold the appropriate update-side lock, you -must-
|
||||||
Failing to do so will break Alpha and confuse people reading
|
use the "_rcu()" variants of the list macros. Failing to do so
|
||||||
your code.
|
will break Alpha and confuse people reading your code.
|
||||||
|
|
||||||
11. Note that synchronize_rcu() -only- guarantees to wait until
|
11. Note that synchronize_rcu() -only- guarantees to wait until
|
||||||
all currently executing rcu_read_lock()-protected RCU read-side
|
all currently executing rcu_read_lock()-protected RCU read-side
|
||||||
|
@ -230,6 +253,14 @@ over a rather long period of time, but improvements are always welcome!
|
||||||
must use whatever locking or other synchronization is required
|
must use whatever locking or other synchronization is required
|
||||||
to safely access and/or modify that data structure.
|
to safely access and/or modify that data structure.
|
||||||
|
|
||||||
|
RCU callbacks are -usually- executed on the same CPU that executed
|
||||||
|
the corresponding call_rcu(), call_rcu_bh(), or call_rcu_sched(),
|
||||||
|
but are by -no- means guaranteed to be. For example, if a given
|
||||||
|
CPU goes offline while having an RCU callback pending, then that
|
||||||
|
RCU callback will execute on some surviving CPU. (If this was
|
||||||
|
not the case, a self-spawning RCU callback would prevent the
|
||||||
|
victim CPU from ever going offline.)
|
||||||
|
|
||||||
14. SRCU (srcu_read_lock(), srcu_read_unlock(), and synchronize_srcu())
|
14. SRCU (srcu_read_lock(), srcu_read_unlock(), and synchronize_srcu())
|
||||||
may only be invoked from process context. Unlike other forms of
|
may only be invoked from process context. Unlike other forms of
|
||||||
RCU, it -is- permissible to block in an SRCU read-side critical
|
RCU, it -is- permissible to block in an SRCU read-side critical
|
||||||
|
|
|
@ -10,23 +10,30 @@ status messages via printk(), which can be examined via the dmesg
|
||||||
command (perhaps grepping for "torture"). The test is started
|
command (perhaps grepping for "torture"). The test is started
|
||||||
when the module is loaded, and stops when the module is unloaded.
|
when the module is loaded, and stops when the module is unloaded.
|
||||||
|
|
||||||
However, actually setting this config option to "y" results in the system
|
CONFIG_RCU_TORTURE_TEST_RUNNABLE
|
||||||
running the test immediately upon boot, and ending only when the system
|
|
||||||
is taken down. Normally, one will instead want to build the system
|
It is also possible to specify CONFIG_RCU_TORTURE_TEST=y, which will
|
||||||
with CONFIG_RCU_TORTURE_TEST=m and to use modprobe and rmmod to control
|
result in the tests being loaded into the base kernel. In this case,
|
||||||
the test, perhaps using a script similar to the one shown at the end of
|
the CONFIG_RCU_TORTURE_TEST_RUNNABLE config option is used to specify
|
||||||
this document. Note that you will need CONFIG_MODULE_UNLOAD in order
|
whether the RCU torture tests are to be started immediately during
|
||||||
to be able to end the test.
|
boot or whether the /proc/sys/kernel/rcutorture_runnable file is used
|
||||||
|
to enable them. This /proc file can be used to repeatedly pause and
|
||||||
|
restart the tests, regardless of the initial state specified by the
|
||||||
|
CONFIG_RCU_TORTURE_TEST_RUNNABLE config option.
|
||||||
|
|
||||||
|
You will normally -not- want to start the RCU torture tests during boot
|
||||||
|
(and thus the default is CONFIG_RCU_TORTURE_TEST_RUNNABLE=n), but doing
|
||||||
|
this can sometimes be useful in finding boot-time bugs.
|
||||||
|
|
||||||
|
|
||||||
MODULE PARAMETERS
|
MODULE PARAMETERS
|
||||||
|
|
||||||
This module has the following parameters:
|
This module has the following parameters:
|
||||||
|
|
||||||
nreaders This is the number of RCU reading threads supported.
|
irqreaders Says to invoke RCU readers from irq level. This is currently
|
||||||
The default is twice the number of CPUs. Why twice?
|
done via timers. Defaults to "1" for variants of RCU that
|
||||||
To properly exercise RCU implementations with preemptible
|
permit this. (Or, more accurately, variants of RCU that do
|
||||||
read-side critical sections.
|
-not- permit this know to ignore this variable.)
|
||||||
|
|
||||||
nfakewriters This is the number of RCU fake writer threads to run. Fake
|
nfakewriters This is the number of RCU fake writer threads to run. Fake
|
||||||
writer threads repeatedly use the synchronous "wait for
|
writer threads repeatedly use the synchronous "wait for
|
||||||
|
@ -37,6 +44,16 @@ nfakewriters This is the number of RCU fake writer threads to run. Fake
|
||||||
to trigger special cases caused by multiple writers, such as
|
to trigger special cases caused by multiple writers, such as
|
||||||
the synchronize_srcu() early return optimization.
|
the synchronize_srcu() early return optimization.
|
||||||
|
|
||||||
|
nreaders This is the number of RCU reading threads supported.
|
||||||
|
The default is twice the number of CPUs. Why twice?
|
||||||
|
To properly exercise RCU implementations with preemptible
|
||||||
|
read-side critical sections.
|
||||||
|
|
||||||
|
shuffle_interval
|
||||||
|
The number of seconds to keep the test threads affinitied
|
||||||
|
to a particular subset of the CPUs, defaults to 3 seconds.
|
||||||
|
Used in conjunction with test_no_idle_hz.
|
||||||
|
|
||||||
stat_interval The number of seconds between output of torture
|
stat_interval The number of seconds between output of torture
|
||||||
statistics (via printk()). Regardless of the interval,
|
statistics (via printk()). Regardless of the interval,
|
||||||
statistics are printed when the module is unloaded.
|
statistics are printed when the module is unloaded.
|
||||||
|
@ -44,10 +61,11 @@ stat_interval The number of seconds between output of torture
|
||||||
be printed -only- when the module is unloaded, and this
|
be printed -only- when the module is unloaded, and this
|
||||||
is the default.
|
is the default.
|
||||||
|
|
||||||
shuffle_interval
|
stutter The length of time to run the test before pausing for this
|
||||||
The number of seconds to keep the test threads affinitied
|
same period of time. Defaults to "stutter=5", so as
|
||||||
to a particular subset of the CPUs, defaults to 5 seconds.
|
to run and pause for (roughly) five-second intervals.
|
||||||
Used in conjunction with test_no_idle_hz.
|
Specifying "stutter=0" causes the test to run continuously
|
||||||
|
without pausing, which is the old default behavior.
|
||||||
|
|
||||||
test_no_idle_hz Whether or not to test the ability of RCU to operate in
|
test_no_idle_hz Whether or not to test the ability of RCU to operate in
|
||||||
a kernel that disables the scheduling-clock interrupt to
|
a kernel that disables the scheduling-clock interrupt to
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
Please note that the "What is RCU?" LWN series is an excellent place
|
||||||
|
to start learning about RCU:
|
||||||
|
|
||||||
|
1. What is RCU, Fundamentally? http://lwn.net/Articles/262464/
|
||||||
|
2. What is RCU? Part 2: Usage http://lwn.net/Articles/263130/
|
||||||
|
3. RCU part 3: the RCU API http://lwn.net/Articles/264090/
|
||||||
|
|
||||||
|
|
||||||
What is RCU?
|
What is RCU?
|
||||||
|
|
||||||
RCU is a synchronization mechanism that was added to the Linux kernel
|
RCU is a synchronization mechanism that was added to the Linux kernel
|
||||||
|
@ -772,26 +780,18 @@ Linux-kernel source code, but it helps to have a full list of the
|
||||||
APIs, since there does not appear to be a way to categorize them
|
APIs, since there does not appear to be a way to categorize them
|
||||||
in docbook. Here is the list, by category.
|
in docbook. Here is the list, by category.
|
||||||
|
|
||||||
Markers for RCU read-side critical sections:
|
|
||||||
|
|
||||||
rcu_read_lock
|
|
||||||
rcu_read_unlock
|
|
||||||
rcu_read_lock_bh
|
|
||||||
rcu_read_unlock_bh
|
|
||||||
srcu_read_lock
|
|
||||||
srcu_read_unlock
|
|
||||||
|
|
||||||
RCU pointer/list traversal:
|
RCU pointer/list traversal:
|
||||||
|
|
||||||
rcu_dereference
|
rcu_dereference
|
||||||
list_for_each_rcu (to be deprecated in favor of
|
|
||||||
list_for_each_entry_rcu)
|
|
||||||
list_for_each_entry_rcu
|
list_for_each_entry_rcu
|
||||||
list_for_each_continue_rcu (to be deprecated in favor of new
|
|
||||||
list_for_each_entry_continue_rcu)
|
|
||||||
hlist_for_each_entry_rcu
|
hlist_for_each_entry_rcu
|
||||||
|
|
||||||
RCU pointer update:
|
list_for_each_rcu (to be deprecated in favor of
|
||||||
|
list_for_each_entry_rcu)
|
||||||
|
list_for_each_continue_rcu (to be deprecated in favor of new
|
||||||
|
list_for_each_entry_continue_rcu)
|
||||||
|
|
||||||
|
RCU pointer/list update:
|
||||||
|
|
||||||
rcu_assign_pointer
|
rcu_assign_pointer
|
||||||
list_add_rcu
|
list_add_rcu
|
||||||
|
@ -799,16 +799,36 @@ RCU pointer update:
|
||||||
list_del_rcu
|
list_del_rcu
|
||||||
list_replace_rcu
|
list_replace_rcu
|
||||||
hlist_del_rcu
|
hlist_del_rcu
|
||||||
|
hlist_add_after_rcu
|
||||||
|
hlist_add_before_rcu
|
||||||
hlist_add_head_rcu
|
hlist_add_head_rcu
|
||||||
|
hlist_replace_rcu
|
||||||
|
list_splice_init_rcu()
|
||||||
|
|
||||||
RCU grace period:
|
RCU: Critical sections Grace period Barrier
|
||||||
|
|
||||||
synchronize_net
|
rcu_read_lock synchronize_net rcu_barrier
|
||||||
synchronize_sched
|
rcu_read_unlock synchronize_rcu
|
||||||
synchronize_rcu
|
|
||||||
synchronize_srcu
|
|
||||||
call_rcu
|
call_rcu
|
||||||
call_rcu_bh
|
|
||||||
|
|
||||||
|
bh: Critical sections Grace period Barrier
|
||||||
|
|
||||||
|
rcu_read_lock_bh call_rcu_bh rcu_barrier_bh
|
||||||
|
rcu_read_unlock_bh
|
||||||
|
|
||||||
|
|
||||||
|
sched: Critical sections Grace period Barrier
|
||||||
|
|
||||||
|
[preempt_disable] synchronize_sched rcu_barrier_sched
|
||||||
|
[and friends] call_rcu_sched
|
||||||
|
|
||||||
|
|
||||||
|
SRCU: Critical sections Grace period Barrier
|
||||||
|
|
||||||
|
srcu_read_lock synchronize_srcu N/A
|
||||||
|
srcu_read_unlock
|
||||||
|
|
||||||
|
|
||||||
See the comment headers in the source code (or the docbook generated
|
See the comment headers in the source code (or the docbook generated
|
||||||
from them) for more information.
|
from them) for more information.
|
||||||
|
|
|
@ -0,0 +1,327 @@
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
1. INTRODUCTION
|
||||||
|
|
||||||
|
Modern filesystems feature checksumming of data and metadata to
|
||||||
|
protect against data corruption. However, the detection of the
|
||||||
|
corruption is done at read time which could potentially be months
|
||||||
|
after the data was written. At that point the original data that the
|
||||||
|
application tried to write is most likely lost.
|
||||||
|
|
||||||
|
The solution is to ensure that the disk is actually storing what the
|
||||||
|
application meant it to. Recent additions to both the SCSI family
|
||||||
|
protocols (SBC Data Integrity Field, SCC protection proposal) as well
|
||||||
|
as SATA/T13 (External Path Protection) try to remedy this by adding
|
||||||
|
support for appending integrity metadata to an I/O. The integrity
|
||||||
|
metadata (or protection information in SCSI terminology) includes a
|
||||||
|
checksum for each sector as well as an incrementing counter that
|
||||||
|
ensures the individual sectors are written in the right order. And
|
||||||
|
for some protection schemes also that the I/O is written to the right
|
||||||
|
place on disk.
|
||||||
|
|
||||||
|
Current storage controllers and devices implement various protective
|
||||||
|
measures, for instance checksumming and scrubbing. But these
|
||||||
|
technologies are working in their own isolated domains or at best
|
||||||
|
between adjacent nodes in the I/O path. The interesting thing about
|
||||||
|
DIF and the other integrity extensions is that the protection format
|
||||||
|
is well defined and every node in the I/O path can verify the
|
||||||
|
integrity of the I/O and reject it if corruption is detected. This
|
||||||
|
allows not only corruption prevention but also isolation of the point
|
||||||
|
of failure.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
2. THE DATA INTEGRITY EXTENSIONS
|
||||||
|
|
||||||
|
As written, the protocol extensions only protect the path between
|
||||||
|
controller and storage device. However, many controllers actually
|
||||||
|
allow the operating system to interact with the integrity metadata
|
||||||
|
(IMD). We have been working with several FC/SAS HBA vendors to enable
|
||||||
|
the protection information to be transferred to and from their
|
||||||
|
controllers.
|
||||||
|
|
||||||
|
The SCSI Data Integrity Field works by appending 8 bytes of protection
|
||||||
|
information to each sector. The data + integrity metadata is stored
|
||||||
|
in 520 byte sectors on disk. Data + IMD are interleaved when
|
||||||
|
transferred between the controller and target. The T13 proposal is
|
||||||
|
similar.
|
||||||
|
|
||||||
|
Because it is highly inconvenient for operating systems to deal with
|
||||||
|
520 (and 4104) byte sectors, we approached several HBA vendors and
|
||||||
|
encouraged them to allow separation of the data and integrity metadata
|
||||||
|
scatter-gather lists.
|
||||||
|
|
||||||
|
The controller will interleave the buffers on write and split them on
|
||||||
|
read. This means that the Linux can DMA the data buffers to and from
|
||||||
|
host memory without changes to the page cache.
|
||||||
|
|
||||||
|
Also, the 16-bit CRC checksum mandated by both the SCSI and SATA specs
|
||||||
|
is somewhat heavy to compute in software. Benchmarks found that
|
||||||
|
calculating this checksum had a significant impact on system
|
||||||
|
performance for a number of workloads. Some controllers allow a
|
||||||
|
lighter-weight checksum to be used when interfacing with the operating
|
||||||
|
system. Emulex, for instance, supports the TCP/IP checksum instead.
|
||||||
|
The IP checksum received from the OS is converted to the 16-bit CRC
|
||||||
|
when writing and vice versa. This allows the integrity metadata to be
|
||||||
|
generated by Linux or the application at very low cost (comparable to
|
||||||
|
software RAID5).
|
||||||
|
|
||||||
|
The IP checksum is weaker than the CRC in terms of detecting bit
|
||||||
|
errors. However, the strength is really in the separation of the data
|
||||||
|
buffers and the integrity metadata. These two distinct buffers much
|
||||||
|
match up for an I/O to complete.
|
||||||
|
|
||||||
|
The separation of the data and integrity metadata buffers as well as
|
||||||
|
the choice in checksums is referred to as the Data Integrity
|
||||||
|
Extensions. As these extensions are outside the scope of the protocol
|
||||||
|
bodies (T10, T13), Oracle and its partners are trying to standardize
|
||||||
|
them within the Storage Networking Industry Association.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
3. KERNEL CHANGES
|
||||||
|
|
||||||
|
The data integrity framework in Linux enables protection information
|
||||||
|
to be pinned to I/Os and sent to/received from controllers that
|
||||||
|
support it.
|
||||||
|
|
||||||
|
The advantage to the integrity extensions in SCSI and SATA is that
|
||||||
|
they enable us to protect the entire path from application to storage
|
||||||
|
device. However, at the same time this is also the biggest
|
||||||
|
disadvantage. It means that the protection information must be in a
|
||||||
|
format that can be understood by the disk.
|
||||||
|
|
||||||
|
Generally Linux/POSIX applications are agnostic to the intricacies of
|
||||||
|
the storage devices they are accessing. The virtual filesystem switch
|
||||||
|
and the block layer make things like hardware sector size and
|
||||||
|
transport protocols completely transparent to the application.
|
||||||
|
|
||||||
|
However, this level of detail is required when preparing the
|
||||||
|
protection information to send to a disk. Consequently, the very
|
||||||
|
concept of an end-to-end protection scheme is a layering violation.
|
||||||
|
It is completely unreasonable for an application to be aware whether
|
||||||
|
it is accessing a SCSI or SATA disk.
|
||||||
|
|
||||||
|
The data integrity support implemented in Linux attempts to hide this
|
||||||
|
from the application. As far as the application (and to some extent
|
||||||
|
the kernel) is concerned, the integrity metadata is opaque information
|
||||||
|
that's attached to the I/O.
|
||||||
|
|
||||||
|
The current implementation allows the block layer to automatically
|
||||||
|
generate the protection information for any I/O. Eventually the
|
||||||
|
intent is to move the integrity metadata calculation to userspace for
|
||||||
|
user data. Metadata and other I/O that originates within the kernel
|
||||||
|
will still use the automatic generation interface.
|
||||||
|
|
||||||
|
Some storage devices allow each hardware sector to be tagged with a
|
||||||
|
16-bit value. The owner of this tag space is the owner of the block
|
||||||
|
device. I.e. the filesystem in most cases. The filesystem can use
|
||||||
|
this extra space to tag sectors as they see fit. Because the tag
|
||||||
|
space is limited, the block interface allows tagging bigger chunks by
|
||||||
|
way of interleaving. This way, 8*16 bits of information can be
|
||||||
|
attached to a typical 4KB filesystem block.
|
||||||
|
|
||||||
|
This also means that applications such as fsck and mkfs will need
|
||||||
|
access to manipulate the tags from user space. A passthrough
|
||||||
|
interface for this is being worked on.
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
4. BLOCK LAYER IMPLEMENTATION DETAILS
|
||||||
|
|
||||||
|
4.1 BIO
|
||||||
|
|
||||||
|
The data integrity patches add a new field to struct bio when
|
||||||
|
CONFIG_BLK_DEV_INTEGRITY is enabled. bio->bi_integrity is a pointer
|
||||||
|
to a struct bip which contains the bio integrity payload. Essentially
|
||||||
|
a bip is a trimmed down struct bio which holds a bio_vec containing
|
||||||
|
the integrity metadata and the required housekeeping information (bvec
|
||||||
|
pool, vector count, etc.)
|
||||||
|
|
||||||
|
A kernel subsystem can enable data integrity protection on a bio by
|
||||||
|
calling bio_integrity_alloc(bio). This will allocate and attach the
|
||||||
|
bip to the bio.
|
||||||
|
|
||||||
|
Individual pages containing integrity metadata can subsequently be
|
||||||
|
attached using bio_integrity_add_page().
|
||||||
|
|
||||||
|
bio_free() will automatically free the bip.
|
||||||
|
|
||||||
|
|
||||||
|
4.2 BLOCK DEVICE
|
||||||
|
|
||||||
|
Because the format of the protection data is tied to the physical
|
||||||
|
disk, each block device has been extended with a block integrity
|
||||||
|
profile (struct blk_integrity). This optional profile is registered
|
||||||
|
with the block layer using blk_integrity_register().
|
||||||
|
|
||||||
|
The profile contains callback functions for generating and verifying
|
||||||
|
the protection data, as well as getting and setting application tags.
|
||||||
|
The profile also contains a few constants to aid in completing,
|
||||||
|
merging and splitting the integrity metadata.
|
||||||
|
|
||||||
|
Layered block devices will need to pick a profile that's appropriate
|
||||||
|
for all subdevices. blk_integrity_compare() can help with that. DM
|
||||||
|
and MD linear, RAID0 and RAID1 are currently supported. RAID4/5/6
|
||||||
|
will require extra work due to the application tag.
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
5.0 BLOCK LAYER INTEGRITY API
|
||||||
|
|
||||||
|
5.1 NORMAL FILESYSTEM
|
||||||
|
|
||||||
|
The normal filesystem is unaware that the underlying block device
|
||||||
|
is capable of sending/receiving integrity metadata. The IMD will
|
||||||
|
be automatically generated by the block layer at submit_bio() time
|
||||||
|
in case of a WRITE. A READ request will cause the I/O integrity
|
||||||
|
to be verified upon completion.
|
||||||
|
|
||||||
|
IMD generation and verification can be toggled using the
|
||||||
|
|
||||||
|
/sys/block/<bdev>/integrity/write_generate
|
||||||
|
|
||||||
|
and
|
||||||
|
|
||||||
|
/sys/block/<bdev>/integrity/read_verify
|
||||||
|
|
||||||
|
flags.
|
||||||
|
|
||||||
|
|
||||||
|
5.2 INTEGRITY-AWARE FILESYSTEM
|
||||||
|
|
||||||
|
A filesystem that is integrity-aware can prepare I/Os with IMD
|
||||||
|
attached. It can also use the application tag space if this is
|
||||||
|
supported by the block device.
|
||||||
|
|
||||||
|
|
||||||
|
int bdev_integrity_enabled(block_device, int rw);
|
||||||
|
|
||||||
|
bdev_integrity_enabled() will return 1 if the block device
|
||||||
|
supports integrity metadata transfer for the data direction
|
||||||
|
specified in 'rw'.
|
||||||
|
|
||||||
|
bdev_integrity_enabled() honors the write_generate and
|
||||||
|
read_verify flags in sysfs and will respond accordingly.
|
||||||
|
|
||||||
|
|
||||||
|
int bio_integrity_prep(bio);
|
||||||
|
|
||||||
|
To generate IMD for WRITE and to set up buffers for READ, the
|
||||||
|
filesystem must call bio_integrity_prep(bio).
|
||||||
|
|
||||||
|
Prior to calling this function, the bio data direction and start
|
||||||
|
sector must be set, and the bio should have all data pages
|
||||||
|
added. It is up to the caller to ensure that the bio does not
|
||||||
|
change while I/O is in progress.
|
||||||
|
|
||||||
|
bio_integrity_prep() should only be called if
|
||||||
|
bio_integrity_enabled() returned 1.
|
||||||
|
|
||||||
|
|
||||||
|
int bio_integrity_tag_size(bio);
|
||||||
|
|
||||||
|
If the filesystem wants to use the application tag space it will
|
||||||
|
first have to find out how much storage space is available.
|
||||||
|
Because tag space is generally limited (usually 2 bytes per
|
||||||
|
sector regardless of sector size), the integrity framework
|
||||||
|
supports interleaving the information between the sectors in an
|
||||||
|
I/O.
|
||||||
|
|
||||||
|
Filesystems can call bio_integrity_tag_size(bio) to find out how
|
||||||
|
many bytes of storage are available for that particular bio.
|
||||||
|
|
||||||
|
Another option is bdev_get_tag_size(block_device) which will
|
||||||
|
return the number of available bytes per hardware sector.
|
||||||
|
|
||||||
|
|
||||||
|
int bio_integrity_set_tag(bio, void *tag_buf, len);
|
||||||
|
|
||||||
|
After a successful return from bio_integrity_prep(),
|
||||||
|
bio_integrity_set_tag() can be used to attach an opaque tag
|
||||||
|
buffer to a bio. Obviously this only makes sense if the I/O is
|
||||||
|
a WRITE.
|
||||||
|
|
||||||
|
|
||||||
|
int bio_integrity_get_tag(bio, void *tag_buf, len);
|
||||||
|
|
||||||
|
Similarly, at READ I/O completion time the filesystem can
|
||||||
|
retrieve the tag buffer using bio_integrity_get_tag().
|
||||||
|
|
||||||
|
|
||||||
|
6.3 PASSING EXISTING INTEGRITY METADATA
|
||||||
|
|
||||||
|
Filesystems that either generate their own integrity metadata or
|
||||||
|
are capable of transferring IMD from user space can use the
|
||||||
|
following calls:
|
||||||
|
|
||||||
|
|
||||||
|
struct bip * bio_integrity_alloc(bio, gfp_mask, nr_pages);
|
||||||
|
|
||||||
|
Allocates the bio integrity payload and hangs it off of the bio.
|
||||||
|
nr_pages indicate how many pages of protection data need to be
|
||||||
|
stored in the integrity bio_vec list (similar to bio_alloc()).
|
||||||
|
|
||||||
|
The integrity payload will be freed at bio_free() time.
|
||||||
|
|
||||||
|
|
||||||
|
int bio_integrity_add_page(bio, page, len, offset);
|
||||||
|
|
||||||
|
Attaches a page containing integrity metadata to an existing
|
||||||
|
bio. The bio must have an existing bip,
|
||||||
|
i.e. bio_integrity_alloc() must have been called. For a WRITE,
|
||||||
|
the integrity metadata in the pages must be in a format
|
||||||
|
understood by the target device with the notable exception that
|
||||||
|
the sector numbers will be remapped as the request traverses the
|
||||||
|
I/O stack. This implies that the pages added using this call
|
||||||
|
will be modified during I/O! The first reference tag in the
|
||||||
|
integrity metadata must have a value of bip->bip_sector.
|
||||||
|
|
||||||
|
Pages can be added using bio_integrity_add_page() as long as
|
||||||
|
there is room in the bip bio_vec array (nr_pages).
|
||||||
|
|
||||||
|
Upon completion of a READ operation, the attached pages will
|
||||||
|
contain the integrity metadata received from the storage device.
|
||||||
|
It is up to the receiver to process them and verify data
|
||||||
|
integrity upon completion.
|
||||||
|
|
||||||
|
|
||||||
|
6.4 REGISTERING A BLOCK DEVICE AS CAPABLE OF EXCHANGING INTEGRITY
|
||||||
|
METADATA
|
||||||
|
|
||||||
|
To enable integrity exchange on a block device the gendisk must be
|
||||||
|
registered as capable:
|
||||||
|
|
||||||
|
int blk_integrity_register(gendisk, blk_integrity);
|
||||||
|
|
||||||
|
The blk_integrity struct is a template and should contain the
|
||||||
|
following:
|
||||||
|
|
||||||
|
static struct blk_integrity my_profile = {
|
||||||
|
.name = "STANDARDSBODY-TYPE-VARIANT-CSUM",
|
||||||
|
.generate_fn = my_generate_fn,
|
||||||
|
.verify_fn = my_verify_fn,
|
||||||
|
.get_tag_fn = my_get_tag_fn,
|
||||||
|
.set_tag_fn = my_set_tag_fn,
|
||||||
|
.tuple_size = sizeof(struct my_tuple_size),
|
||||||
|
.tag_size = <tag bytes per hw sector>,
|
||||||
|
};
|
||||||
|
|
||||||
|
'name' is a text string which will be visible in sysfs. This is
|
||||||
|
part of the userland API so chose it carefully and never change
|
||||||
|
it. The format is standards body-type-variant.
|
||||||
|
E.g. T10-DIF-TYPE1-IP or T13-EPP-0-CRC.
|
||||||
|
|
||||||
|
'generate_fn' generates appropriate integrity metadata (for WRITE).
|
||||||
|
|
||||||
|
'verify_fn' verifies that the data buffer matches the integrity
|
||||||
|
metadata.
|
||||||
|
|
||||||
|
'tuple_size' must be set to match the size of the integrity
|
||||||
|
metadata per sector. I.e. 8 for DIF and EPP.
|
||||||
|
|
||||||
|
'tag_size' must be set to identify how many bytes of tag space
|
||||||
|
are available per hardware sector. For DIF this is either 2 or
|
||||||
|
0 depending on the value of the Control Mode Page ATO bit.
|
||||||
|
|
||||||
|
See 6.2 for a description of get_tag_fn and set_tag_fn.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
2007-12-24 Martin K. Petersen <martin.petersen@oracle.com>
|
|
@ -14,9 +14,8 @@ represent the thread siblings to cpu X in the same physical package;
|
||||||
To implement it in an architecture-neutral way, a new source file,
|
To implement it in an architecture-neutral way, a new source file,
|
||||||
drivers/base/topology.c, is to export the 4 attributes.
|
drivers/base/topology.c, is to export the 4 attributes.
|
||||||
|
|
||||||
If one architecture wants to support this feature, it just needs to
|
For an architecture to support this feature, it must define some of
|
||||||
implement 4 defines, typically in file include/asm-XXX/topology.h.
|
these macros in include/asm-XXX/topology.h:
|
||||||
The 4 defines are:
|
|
||||||
#define topology_physical_package_id(cpu)
|
#define topology_physical_package_id(cpu)
|
||||||
#define topology_core_id(cpu)
|
#define topology_core_id(cpu)
|
||||||
#define topology_thread_siblings(cpu)
|
#define topology_thread_siblings(cpu)
|
||||||
|
@ -25,17 +24,10 @@ The 4 defines are:
|
||||||
The type of **_id is int.
|
The type of **_id is int.
|
||||||
The type of siblings is cpumask_t.
|
The type of siblings is cpumask_t.
|
||||||
|
|
||||||
To be consistent on all architectures, the 4 attributes should have
|
To be consistent on all architectures, include/linux/topology.h
|
||||||
default values if their values are unavailable. Below is the rule.
|
provides default definitions for any of the above macros that are
|
||||||
1) physical_package_id: If cpu has no physical package id, -1 is the
|
not defined by include/asm-XXX/topology.h:
|
||||||
default value.
|
1) physical_package_id: -1
|
||||||
2) core_id: If cpu doesn't support multi-core, its core id is 0.
|
2) core_id: 0
|
||||||
3) thread_siblings: Just include itself, if the cpu doesn't support
|
3) thread_siblings: just the given CPU
|
||||||
HT/multi-thread.
|
4) core_siblings: just the given CPU
|
||||||
4) core_siblings: Just include itself, if the cpu doesn't support
|
|
||||||
multi-core and HT/Multi-thread.
|
|
||||||
|
|
||||||
So be careful when declaring the 4 defines in include/asm-XXX/topology.h.
|
|
||||||
|
|
||||||
If an attribute isn't defined on an architecture, it won't be exported.
|
|
||||||
|
|
||||||
|
|
|
@ -222,13 +222,6 @@ Who: Thomas Gleixner <tglx@linutronix.de>
|
||||||
|
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
What: i2c-i810, i2c-prosavage and i2c-savage4
|
|
||||||
When: May 2008
|
|
||||||
Why: These drivers are superseded by i810fb, intelfb and savagefb.
|
|
||||||
Who: Jean Delvare <khali@linux-fr.org>
|
|
||||||
|
|
||||||
---------------------------
|
|
||||||
|
|
||||||
What (Why):
|
What (Why):
|
||||||
- include/linux/netfilter_ipv4/ipt_TOS.h ipt_tos.h header files
|
- include/linux/netfilter_ipv4/ipt_TOS.h ipt_tos.h header files
|
||||||
(superseded by xt_TOS/xt_tos target & match)
|
(superseded by xt_TOS/xt_tos target & match)
|
||||||
|
|
|
@ -233,10 +233,12 @@ accomplished via the group operations specified on the group's
|
||||||
config_item_type.
|
config_item_type.
|
||||||
|
|
||||||
struct configfs_group_operations {
|
struct configfs_group_operations {
|
||||||
struct config_item *(*make_item)(struct config_group *group,
|
int (*make_item)(struct config_group *group,
|
||||||
const char *name);
|
const char *name,
|
||||||
struct config_group *(*make_group)(struct config_group *group,
|
struct config_item **new_item);
|
||||||
const char *name);
|
int (*make_group)(struct config_group *group,
|
||||||
|
const char *name,
|
||||||
|
struct config_group **new_group);
|
||||||
int (*commit_item)(struct config_item *item);
|
int (*commit_item)(struct config_item *item);
|
||||||
void (*disconnect_notify)(struct config_group *group,
|
void (*disconnect_notify)(struct config_group *group,
|
||||||
struct config_item *item);
|
struct config_item *item);
|
||||||
|
|
|
@ -273,13 +273,13 @@ static inline struct simple_children *to_simple_children(struct config_item *ite
|
||||||
return item ? container_of(to_config_group(item), struct simple_children, group) : NULL;
|
return item ? container_of(to_config_group(item), struct simple_children, group) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct config_item *simple_children_make_item(struct config_group *group, const char *name)
|
static int simple_children_make_item(struct config_group *group, const char *name, struct config_item **new_item)
|
||||||
{
|
{
|
||||||
struct simple_child *simple_child;
|
struct simple_child *simple_child;
|
||||||
|
|
||||||
simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL);
|
simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL);
|
||||||
if (!simple_child)
|
if (!simple_child)
|
||||||
return NULL;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
|
||||||
config_item_init_type_name(&simple_child->item, name,
|
config_item_init_type_name(&simple_child->item, name,
|
||||||
|
@ -287,7 +287,8 @@ static struct config_item *simple_children_make_item(struct config_group *group,
|
||||||
|
|
||||||
simple_child->storeme = 0;
|
simple_child->storeme = 0;
|
||||||
|
|
||||||
return &simple_child->item;
|
*new_item = &simple_child->item;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct configfs_attribute simple_children_attr_description = {
|
static struct configfs_attribute simple_children_attr_description = {
|
||||||
|
@ -359,20 +360,21 @@ static struct configfs_subsystem simple_children_subsys = {
|
||||||
* children of its own.
|
* children of its own.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static struct config_group *group_children_make_group(struct config_group *group, const char *name)
|
static int group_children_make_group(struct config_group *group, const char *name, struct config_group **new_group)
|
||||||
{
|
{
|
||||||
struct simple_children *simple_children;
|
struct simple_children *simple_children;
|
||||||
|
|
||||||
simple_children = kzalloc(sizeof(struct simple_children),
|
simple_children = kzalloc(sizeof(struct simple_children),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!simple_children)
|
if (!simple_children)
|
||||||
return NULL;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
|
||||||
config_group_init_type_name(&simple_children->group, name,
|
config_group_init_type_name(&simple_children->group, name,
|
||||||
&simple_children_type);
|
&simple_children_type);
|
||||||
|
|
||||||
return &simple_children->group;
|
*new_group = &simple_children->group;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct configfs_attribute group_children_attr_description = {
|
static struct configfs_attribute group_children_attr_description = {
|
||||||
|
|
|
@ -13,72 +13,93 @@ Mailing list: linux-ext4@vger.kernel.org
|
||||||
1. Quick usage instructions:
|
1. Quick usage instructions:
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
- Grab updated e2fsprogs from
|
- Compile and install the latest version of e2fsprogs (as of this
|
||||||
ftp://ftp.kernel.org/pub/linux/kernel/people/tytso/e2fsprogs-interim/
|
writing version 1.41) from:
|
||||||
This is a patchset on top of e2fsprogs-1.39, which can be found at
|
|
||||||
|
http://sourceforge.net/project/showfiles.php?group_id=2406
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
ftp://ftp.kernel.org/pub/linux/kernel/people/tytso/e2fsprogs/
|
ftp://ftp.kernel.org/pub/linux/kernel/people/tytso/e2fsprogs/
|
||||||
|
|
||||||
- It's still mke2fs -j /dev/hda1
|
or grab the latest git repository from:
|
||||||
|
|
||||||
- mount /dev/hda1 /wherever -t ext4dev
|
git://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git
|
||||||
|
|
||||||
- To enable extents,
|
- Create a new filesystem using the ext4dev filesystem type:
|
||||||
|
|
||||||
mount /dev/hda1 /wherever -t ext4dev -o extents
|
# mke2fs -t ext4dev /dev/hda1
|
||||||
|
|
||||||
- The filesystem is compatible with the ext3 driver until you add a file
|
Or configure an existing ext3 filesystem to support extents and set
|
||||||
which has extents (ie: `mount -o extents', then create a file).
|
the test_fs flag to indicate that it's ok for an in-development
|
||||||
|
filesystem to touch this filesystem:
|
||||||
|
|
||||||
NOTE: The "extents" mount flag is temporary. It will soon go away and
|
# tune2fs -O extents -E test_fs /dev/hda1
|
||||||
extents will be enabled by the "-o extents" flag to mke2fs or tune2fs
|
|
||||||
|
If the filesystem was created with 128 byte inodes, it can be
|
||||||
|
converted to use 256 byte for greater efficiency via:
|
||||||
|
|
||||||
|
# tune2fs -I 256 /dev/hda1
|
||||||
|
|
||||||
|
(Note: we currently do not have tools to convert an ext4dev
|
||||||
|
filesystem back to ext3; so please do not do try this on production
|
||||||
|
filesystems.)
|
||||||
|
|
||||||
|
- Mounting:
|
||||||
|
|
||||||
|
# mount -t ext4dev /dev/hda1 /wherever
|
||||||
|
|
||||||
- When comparing performance with other filesystems, remember that
|
- When comparing performance with other filesystems, remember that
|
||||||
ext3/4 by default offers higher data integrity guarantees than most. So
|
ext3/4 by default offers higher data integrity guarantees than most.
|
||||||
when comparing with a metadata-only journalling filesystem, use `mount -o
|
So when comparing with a metadata-only journalling filesystem, such
|
||||||
data=writeback'. And you might as well use `mount -o nobh' too along
|
as ext3, use `mount -o data=writeback'. And you might as well use
|
||||||
with it. Making the journal larger than the mke2fs default often helps
|
`mount -o nobh' too along with it. Making the journal larger than
|
||||||
performance with metadata-intensive workloads.
|
the mke2fs default often helps performance with metadata-intensive
|
||||||
|
workloads.
|
||||||
|
|
||||||
2. Features
|
2. Features
|
||||||
===========
|
===========
|
||||||
|
|
||||||
2.1 Currently available
|
2.1 Currently available
|
||||||
|
|
||||||
* ability to use filesystems > 16TB
|
* ability to use filesystems > 16TB (e2fsprogs support not available yet)
|
||||||
* extent format reduces metadata overhead (RAM, IO for access, transactions)
|
* extent format reduces metadata overhead (RAM, IO for access, transactions)
|
||||||
* extent format more robust in face of on-disk corruption due to magics,
|
* extent format more robust in face of on-disk corruption due to magics,
|
||||||
* internal redunancy in tree
|
* internal redunancy in tree
|
||||||
|
* improved file allocation (multi-block alloc)
|
||||||
2.1 Previously available, soon to be enabled by default by "mkefs.ext4":
|
* fix 32000 subdirectory limit
|
||||||
|
* nsec timestamps for mtime, atime, ctime, create time
|
||||||
* dir_index and resize inode will be on by default
|
* inode version field on disk (NFSv4, Lustre)
|
||||||
* large inodes will be used by default for fast EAs, nsec timestamps, etc
|
* reduced e2fsck time via uninit_bg feature
|
||||||
|
* journal checksumming for robustness, performance
|
||||||
|
* persistent file preallocation (e.g for streaming media, databases)
|
||||||
|
* ability to pack bitmaps and inode tables into larger virtual groups via the
|
||||||
|
flex_bg feature
|
||||||
|
* large file support
|
||||||
|
* Inode allocation using large virtual block groups via flex_bg
|
||||||
|
* delayed allocation
|
||||||
|
* large block (up to pagesize) support
|
||||||
|
* efficent new ordered mode in JBD2 and ext4(avoid using buffer head to force
|
||||||
|
the ordering)
|
||||||
|
|
||||||
2.2 Candidate features for future inclusion
|
2.2 Candidate features for future inclusion
|
||||||
|
|
||||||
There are several under discussion, whether they all make it in is
|
* Online defrag (patches available but not well tested)
|
||||||
partly a function of how much time everyone has to work on them:
|
* reduced mke2fs time via lazy itable initialization in conjuction with
|
||||||
|
the uninit_bg feature (capability to do this is available in e2fsprogs
|
||||||
|
but a kernel thread to do lazy zeroing of unused inode table blocks
|
||||||
|
after filesystem is first mounted is required for safety)
|
||||||
|
|
||||||
* improved file allocation (multi-block alloc, delayed alloc; basically done)
|
There are several others under discussion, whether they all make it in is
|
||||||
* fix 32000 subdirectory limit (patch exists, needs some e2fsck work)
|
partly a function of how much time everyone has to work on them. Features like
|
||||||
* nsec timestamps for mtime, atime, ctime, create time (patch exists,
|
metadata checksumming have been discussed and planned for a bit but no patches
|
||||||
needs some e2fsck work)
|
exist yet so I'm not sure they're in the near-term roadmap.
|
||||||
* inode version field on disk (NFSv4, Lustre; prototype exists)
|
|
||||||
* reduced mke2fs/e2fsck time via uninitialized groups (prototype exists)
|
|
||||||
* journal checksumming for robustness, performance (prototype exists)
|
|
||||||
* persistent file preallocation (e.g for streaming media, databases)
|
|
||||||
|
|
||||||
Features like metadata checksumming have been discussed and planned for
|
The big performance win will come with mballoc, delalloc and flex_bg
|
||||||
a bit but no patches exist yet so I'm not sure they're in the near-term
|
grouping of bitmaps and inode tables. Some test results available here:
|
||||||
roadmap.
|
|
||||||
|
|
||||||
The big performance win will come with mballoc and delalloc. CFS has
|
- http://www.bullopensource.org/ext4/20080530/ffsb-write-2.6.26-rc2.html
|
||||||
been using mballoc for a few years already with Lustre, and IBM + Bull
|
- http://www.bullopensource.org/ext4/20080530/ffsb-readwrite-2.6.26-rc2.html
|
||||||
did a lot of benchmarking on it. The reason it isn't in the first set of
|
|
||||||
patches is partly a manageability issue, and partly because it doesn't
|
|
||||||
directly affect the on-disk format (outside of much better allocation)
|
|
||||||
so it isn't critical to get into the first round of changes. I believe
|
|
||||||
Alex is working on a new set of patches right now.
|
|
||||||
|
|
||||||
3. Options
|
3. Options
|
||||||
==========
|
==========
|
||||||
|
@ -222,9 +243,11 @@ stripe=n Number of filesystem blocks that mballoc will try
|
||||||
to use for allocation size and alignment. For RAID5/6
|
to use for allocation size and alignment. For RAID5/6
|
||||||
systems this should be the number of data
|
systems this should be the number of data
|
||||||
disks * RAID chunk size in file system blocks.
|
disks * RAID chunk size in file system blocks.
|
||||||
|
delalloc (*) Deferring block allocation until write-out time.
|
||||||
|
nodelalloc Disable delayed allocation. Blocks are allocation
|
||||||
|
when data is copied from user to page cache.
|
||||||
Data Mode
|
Data Mode
|
||||||
---------
|
=========
|
||||||
There are 3 different data modes:
|
There are 3 different data modes:
|
||||||
|
|
||||||
* writeback mode
|
* writeback mode
|
||||||
|
@ -236,10 +259,10 @@ typically provide the best ext4 performance.
|
||||||
|
|
||||||
* ordered mode
|
* ordered mode
|
||||||
In data=ordered mode, ext4 only officially journals metadata, but it logically
|
In data=ordered mode, ext4 only officially journals metadata, but it logically
|
||||||
groups metadata and data blocks into a single unit called a transaction. When
|
groups metadata information related to data changes with the data blocks into a
|
||||||
it's time to write the new metadata out to disk, the associated data blocks
|
single unit called a transaction. When it's time to write the new metadata
|
||||||
are written first. In general, this mode performs slightly slower than
|
out to disk, the associated data blocks are written first. In general,
|
||||||
writeback but significantly faster than journal mode.
|
this mode performs slightly slower than writeback but significantly faster than journal mode.
|
||||||
|
|
||||||
* journal mode
|
* journal mode
|
||||||
data=journal mode provides full data and metadata journaling. All new data is
|
data=journal mode provides full data and metadata journaling. All new data is
|
||||||
|
@ -247,7 +270,8 @@ written to the journal first, and then to its final location.
|
||||||
In the event of a crash, the journal can be replayed, bringing both data and
|
In the event of a crash, the journal can be replayed, bringing both data and
|
||||||
metadata into a consistent state. This mode is the slowest except when data
|
metadata into a consistent state. This mode is the slowest except when data
|
||||||
needs to be read from and written to disk at the same time where it
|
needs to be read from and written to disk at the same time where it
|
||||||
outperforms all others modes.
|
outperforms all others modes. Curently ext4 does not have delayed
|
||||||
|
allocation support if this data journalling mode is selected.
|
||||||
|
|
||||||
References
|
References
|
||||||
==========
|
==========
|
||||||
|
@ -256,7 +280,8 @@ kernel source: <file:fs/ext4/>
|
||||||
<file:fs/jbd2/>
|
<file:fs/jbd2/>
|
||||||
|
|
||||||
programs: http://e2fsprogs.sourceforge.net/
|
programs: http://e2fsprogs.sourceforge.net/
|
||||||
http://ext2resize.sourceforge.net
|
|
||||||
|
|
||||||
useful links: http://fedoraproject.org/wiki/ext3-devel
|
useful links: http://fedoraproject.org/wiki/ext3-devel
|
||||||
http://www.bullopensource.org/ext4/
|
http://www.bullopensource.org/ext4/
|
||||||
|
http://ext4.wiki.kernel.org/index.php/Main_Page
|
||||||
|
http://fedoraproject.org/wiki/Features/Ext4
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
Glock internal locking rules
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
This documents the basic principles of the glock state machine
|
||||||
|
internals. Each glock (struct gfs2_glock in fs/gfs2/incore.h)
|
||||||
|
has two main (internal) locks:
|
||||||
|
|
||||||
|
1. A spinlock (gl_spin) which protects the internal state such
|
||||||
|
as gl_state, gl_target and the list of holders (gl_holders)
|
||||||
|
2. A non-blocking bit lock, GLF_LOCK, which is used to prevent other
|
||||||
|
threads from making calls to the DLM, etc. at the same time. If a
|
||||||
|
thread takes this lock, it must then call run_queue (usually via the
|
||||||
|
workqueue) when it releases it in order to ensure any pending tasks
|
||||||
|
are completed.
|
||||||
|
|
||||||
|
The gl_holders list contains all the queued lock requests (not
|
||||||
|
just the holders) associated with the glock. If there are any
|
||||||
|
held locks, then they will be contiguous entries at the head
|
||||||
|
of the list. Locks are granted in strictly the order that they
|
||||||
|
are queued, except for those marked LM_FLAG_PRIORITY which are
|
||||||
|
used only during recovery, and even then only for journal locks.
|
||||||
|
|
||||||
|
There are three lock states that users of the glock layer can request,
|
||||||
|
namely shared (SH), deferred (DF) and exclusive (EX). Those translate
|
||||||
|
to the following DLM lock modes:
|
||||||
|
|
||||||
|
Glock mode | DLM lock mode
|
||||||
|
------------------------------
|
||||||
|
UN | IV/NL Unlocked (no DLM lock associated with glock) or NL
|
||||||
|
SH | PR (Protected read)
|
||||||
|
DF | CW (Concurrent write)
|
||||||
|
EX | EX (Exclusive)
|
||||||
|
|
||||||
|
Thus DF is basically a shared mode which is incompatible with the "normal"
|
||||||
|
shared lock mode, SH. In GFS2 the DF mode is used exclusively for direct I/O
|
||||||
|
operations. The glocks are basically a lock plus some routines which deal
|
||||||
|
with cache management. The following rules apply for the cache:
|
||||||
|
|
||||||
|
Glock mode | Cache data | Cache Metadata | Dirty Data | Dirty Metadata
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
UN | No | No | No | No
|
||||||
|
SH | Yes | Yes | No | No
|
||||||
|
DF | No | Yes | No | No
|
||||||
|
EX | Yes | Yes | Yes | Yes
|
||||||
|
|
||||||
|
These rules are implemented using the various glock operations which
|
||||||
|
are defined for each type of glock. Not all types of glocks use
|
||||||
|
all the modes. Only inode glocks use the DF mode for example.
|
||||||
|
|
||||||
|
Table of glock operations and per type constants:
|
||||||
|
|
||||||
|
Field | Purpose
|
||||||
|
----------------------------------------------------------------------------
|
||||||
|
go_xmote_th | Called before remote state change (e.g. to sync dirty data)
|
||||||
|
go_xmote_bh | Called after remote state change (e.g. to refill cache)
|
||||||
|
go_inval | Called if remote state change requires invalidating the cache
|
||||||
|
go_demote_ok | Returns boolean value of whether its ok to demote a glock
|
||||||
|
| (e.g. checks timeout, and that there is no cached data)
|
||||||
|
go_lock | Called for the first local holder of a lock
|
||||||
|
go_unlock | Called on the final local unlock of a lock
|
||||||
|
go_dump | Called to print content of object for debugfs file, or on
|
||||||
|
| error to dump glock to the log.
|
||||||
|
go_type; | The type of the glock, LM_TYPE_.....
|
||||||
|
go_min_hold_time | The minimum hold time
|
||||||
|
|
||||||
|
The minimum hold time for each lock is the time after a remote lock
|
||||||
|
grant for which we ignore remote demote requests. This is in order to
|
||||||
|
prevent a situation where locks are being bounced around the cluster
|
||||||
|
from node to node with none of the nodes making any progress. This
|
||||||
|
tends to show up most with shared mmaped files which are being written
|
||||||
|
to by multiple nodes. By delaying the demotion in response to a
|
||||||
|
remote callback, that gives the userspace program time to make
|
||||||
|
some progress before the pages are unmapped.
|
||||||
|
|
||||||
|
There is a plan to try and remove the go_lock and go_unlock callbacks
|
||||||
|
if possible, in order to try and speed up the fast path though the locking.
|
||||||
|
Also, eventually we hope to make the glock "EX" mode locally shared
|
||||||
|
such that any local locking will be done with the i_mutex as required
|
||||||
|
rather than via the glock.
|
||||||
|
|
||||||
|
Locking rules for glock operations:
|
||||||
|
|
||||||
|
Operation | GLF_LOCK bit lock held | gl_spin spinlock held
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
go_xmote_th | Yes | No
|
||||||
|
go_xmote_bh | Yes | No
|
||||||
|
go_inval | Yes | No
|
||||||
|
go_demote_ok | Sometimes | Yes
|
||||||
|
go_lock | Yes | No
|
||||||
|
go_unlock | Yes | No
|
||||||
|
go_dump | Sometimes | Yes
|
||||||
|
|
||||||
|
N.B. Operations must not drop either the bit lock or the spinlock
|
||||||
|
if its held on entry. go_dump and do_demote_ok must never block.
|
||||||
|
Note that go_dump will only be called if the glock's state
|
||||||
|
indicates that it is caching uptodate data.
|
||||||
|
|
||||||
|
Glock locking order within GFS2:
|
||||||
|
|
||||||
|
1. i_mutex (if required)
|
||||||
|
2. Rename glock (for rename only)
|
||||||
|
3. Inode glock(s)
|
||||||
|
(Parents before children, inodes at "same level" with same parent in
|
||||||
|
lock number order)
|
||||||
|
4. Rgrp glock(s) (for (de)allocation operations)
|
||||||
|
5. Transaction glock (via gfs2_trans_begin) for non-read operations
|
||||||
|
6. Page lock (always last, very important!)
|
||||||
|
|
||||||
|
There are two glocks per inode. One deals with access to the inode
|
||||||
|
itself (locking order as above), and the other, known as the iopen
|
||||||
|
glock is used in conjunction with the i_nlink field in the inode to
|
||||||
|
determine the lifetime of the inode in question. Locking of inodes
|
||||||
|
is on a per-inode basis. Locking of rgrps is on a per rgrp basis.
|
||||||
|
|
|
@ -380,28 +380,35 @@ i386 and x86_64 platforms support the new IRQ vector displays.
|
||||||
Of some interest is the introduction of the /proc/irq directory to 2.4.
|
Of some interest is the introduction of the /proc/irq directory to 2.4.
|
||||||
It could be used to set IRQ to CPU affinity, this means that you can "hook" an
|
It could be used to set IRQ to CPU affinity, this means that you can "hook" an
|
||||||
IRQ to only one CPU, or to exclude a CPU of handling IRQs. The contents of the
|
IRQ to only one CPU, or to exclude a CPU of handling IRQs. The contents of the
|
||||||
irq subdir is one subdir for each IRQ, and one file; prof_cpu_mask
|
irq subdir is one subdir for each IRQ, and two files; default_smp_affinity and
|
||||||
|
prof_cpu_mask.
|
||||||
|
|
||||||
For example
|
For example
|
||||||
> ls /proc/irq/
|
> ls /proc/irq/
|
||||||
0 10 12 14 16 18 2 4 6 8 prof_cpu_mask
|
0 10 12 14 16 18 2 4 6 8 prof_cpu_mask
|
||||||
1 11 13 15 17 19 3 5 7 9
|
1 11 13 15 17 19 3 5 7 9 default_smp_affinity
|
||||||
> ls /proc/irq/0/
|
> ls /proc/irq/0/
|
||||||
smp_affinity
|
smp_affinity
|
||||||
|
|
||||||
The contents of the prof_cpu_mask file and each smp_affinity file for each IRQ
|
smp_affinity is a bitmask, in which you can specify which CPUs can handle the
|
||||||
is the same by default:
|
IRQ, you can set it by doing:
|
||||||
|
|
||||||
|
> echo 1 > /proc/irq/10/smp_affinity
|
||||||
|
|
||||||
|
This means that only the first CPU will handle the IRQ, but you can also echo
|
||||||
|
5 which means that only the first and fourth CPU can handle the IRQ.
|
||||||
|
|
||||||
|
The contents of each smp_affinity file is the same by default:
|
||||||
|
|
||||||
> cat /proc/irq/0/smp_affinity
|
> cat /proc/irq/0/smp_affinity
|
||||||
ffffffff
|
ffffffff
|
||||||
|
|
||||||
It's a bitmask, in which you can specify which CPUs can handle the IRQ, you can
|
The default_smp_affinity mask applies to all non-active IRQs, which are the
|
||||||
set it by doing:
|
IRQs which have not yet been allocated/activated, and hence which lack a
|
||||||
|
/proc/irq/[0-9]* directory.
|
||||||
|
|
||||||
> echo 1 > /proc/irq/prof_cpu_mask
|
prof_cpu_mask specifies which CPUs are to be profiled by the system wide
|
||||||
|
profiler. Default value is ffffffff (all cpus).
|
||||||
This means that only the first CPU will handle the IRQ, but you can also echo 5
|
|
||||||
which means that only the first and fourth CPU can handle the IRQ.
|
|
||||||
|
|
||||||
The way IRQs are routed is handled by the IO-APIC, and it's Round Robin
|
The way IRQs are routed is handled by the IO-APIC, and it's Round Robin
|
||||||
between all the CPUs which are allowed to handle it. As usual the kernel has
|
between all the CPUs which are allowed to handle it. As usual the kernel has
|
||||||
|
|
|
@ -0,0 +1,164 @@
|
||||||
|
Introduction
|
||||||
|
=============
|
||||||
|
|
||||||
|
UBIFS file-system stands for UBI File System. UBI stands for "Unsorted
|
||||||
|
Block Images". UBIFS is a flash file system, which means it is designed
|
||||||
|
to work with flash devices. It is important to understand, that UBIFS
|
||||||
|
is completely different to any traditional file-system in Linux, like
|
||||||
|
Ext2, XFS, JFS, etc. UBIFS represents a separate class of file-systems
|
||||||
|
which work with MTD devices, not block devices. The other Linux
|
||||||
|
file-system of this class is JFFS2.
|
||||||
|
|
||||||
|
To make it more clear, here is a small comparison of MTD devices and
|
||||||
|
block devices.
|
||||||
|
|
||||||
|
1 MTD devices represent flash devices and they consist of eraseblocks of
|
||||||
|
rather large size, typically about 128KiB. Block devices consist of
|
||||||
|
small blocks, typically 512 bytes.
|
||||||
|
2 MTD devices support 3 main operations - read from some offset within an
|
||||||
|
eraseblock, write to some offset within an eraseblock, and erase a whole
|
||||||
|
eraseblock. Block devices support 2 main operations - read a whole
|
||||||
|
block and write a whole block.
|
||||||
|
3 The whole eraseblock has to be erased before it becomes possible to
|
||||||
|
re-write its contents. Blocks may be just re-written.
|
||||||
|
4 Eraseblocks become worn out after some number of erase cycles -
|
||||||
|
typically 100K-1G for SLC NAND and NOR flashes, and 1K-10K for MLC
|
||||||
|
NAND flashes. Blocks do not have the wear-out property.
|
||||||
|
5 Eraseblocks may become bad (only on NAND flashes) and software should
|
||||||
|
deal with this. Blocks on hard drives typically do not become bad,
|
||||||
|
because hardware has mechanisms to substitute bad blocks, at least in
|
||||||
|
modern LBA disks.
|
||||||
|
|
||||||
|
It should be quite obvious why UBIFS is very different to traditional
|
||||||
|
file-systems.
|
||||||
|
|
||||||
|
UBIFS works on top of UBI. UBI is a separate software layer which may be
|
||||||
|
found in drivers/mtd/ubi. UBI is basically a volume management and
|
||||||
|
wear-leveling layer. It provides so called UBI volumes which is a higher
|
||||||
|
level abstraction than a MTD device. The programming model of UBI devices
|
||||||
|
is very similar to MTD devices - they still consist of large eraseblocks,
|
||||||
|
they have read/write/erase operations, but UBI devices are devoid of
|
||||||
|
limitations like wear and bad blocks (items 4 and 5 in the above list).
|
||||||
|
|
||||||
|
In a sense, UBIFS is a next generation of JFFS2 file-system, but it is
|
||||||
|
very different and incompatible to JFFS2. The following are the main
|
||||||
|
differences.
|
||||||
|
|
||||||
|
* JFFS2 works on top of MTD devices, UBIFS depends on UBI and works on
|
||||||
|
top of UBI volumes.
|
||||||
|
* JFFS2 does not have on-media index and has to build it while mounting,
|
||||||
|
which requires full media scan. UBIFS maintains the FS indexing
|
||||||
|
information on the flash media and does not require full media scan,
|
||||||
|
so it mounts many times faster than JFFS2.
|
||||||
|
* JFFS2 is a write-through file-system, while UBIFS supports write-back,
|
||||||
|
which makes UBIFS much faster on writes.
|
||||||
|
|
||||||
|
Similarly to JFFS2, UBIFS supports on-the-flight compression which makes
|
||||||
|
it possible to fit quite a lot of data to the flash.
|
||||||
|
|
||||||
|
Similarly to JFFS2, UBIFS is tolerant of unclean reboots and power-cuts.
|
||||||
|
It does not need stuff like ckfs.ext2. UBIFS automatically replays its
|
||||||
|
journal and recovers from crashes, ensuring that the on-flash data
|
||||||
|
structures are consistent.
|
||||||
|
|
||||||
|
UBIFS scales logarithmically (most of the data structures it uses are
|
||||||
|
trees), so the mount time and memory consumption do not linearly depend
|
||||||
|
on the flash size, like in case of JFFS2. This is because UBIFS
|
||||||
|
maintains the FS index on the flash media. However, UBIFS depends on
|
||||||
|
UBI, which scales linearly. So overall UBI/UBIFS stack scales linearly.
|
||||||
|
Nevertheless, UBI/UBIFS scales considerably better than JFFS2.
|
||||||
|
|
||||||
|
The authors of UBIFS believe, that it is possible to develop UBI2 which
|
||||||
|
would scale logarithmically as well. UBI2 would support the same API as UBI,
|
||||||
|
but it would be binary incompatible to UBI. So UBIFS would not need to be
|
||||||
|
changed to use UBI2
|
||||||
|
|
||||||
|
|
||||||
|
Mount options
|
||||||
|
=============
|
||||||
|
|
||||||
|
(*) == default.
|
||||||
|
|
||||||
|
norm_unmount (*) commit on unmount; the journal is committed
|
||||||
|
when the file-system is unmounted so that the
|
||||||
|
next mount does not have to replay the journal
|
||||||
|
and it becomes very fast;
|
||||||
|
fast_unmount do not commit on unmount; this option makes
|
||||||
|
unmount faster, but the next mount slower
|
||||||
|
because of the need to replay the journal.
|
||||||
|
|
||||||
|
|
||||||
|
Quick usage instructions
|
||||||
|
========================
|
||||||
|
|
||||||
|
The UBI volume to mount is specified using "ubiX_Y" or "ubiX:NAME" syntax,
|
||||||
|
where "X" is UBI device number, "Y" is UBI volume number, and "NAME" is
|
||||||
|
UBI volume name.
|
||||||
|
|
||||||
|
Mount volume 0 on UBI device 0 to /mnt/ubifs:
|
||||||
|
$ mount -t ubifs ubi0_0 /mnt/ubifs
|
||||||
|
|
||||||
|
Mount "rootfs" volume of UBI device 0 to /mnt/ubifs ("rootfs" is volume
|
||||||
|
name):
|
||||||
|
$ mount -t ubifs ubi0:rootfs /mnt/ubifs
|
||||||
|
|
||||||
|
The following is an example of the kernel boot arguments to attach mtd0
|
||||||
|
to UBI and mount volume "rootfs":
|
||||||
|
ubi.mtd=0 root=ubi0:rootfs rootfstype=ubifs
|
||||||
|
|
||||||
|
|
||||||
|
Module Parameters for Debugging
|
||||||
|
===============================
|
||||||
|
|
||||||
|
When UBIFS has been compiled with debugging enabled, there are 3 module
|
||||||
|
parameters that are available to control aspects of testing and debugging.
|
||||||
|
The parameters are unsigned integers where each bit controls an option.
|
||||||
|
The parameters are:
|
||||||
|
|
||||||
|
debug_msgs Selects which debug messages to display, as follows:
|
||||||
|
|
||||||
|
Message Type Flag value
|
||||||
|
|
||||||
|
General messages 1
|
||||||
|
Journal messages 2
|
||||||
|
Mount messages 4
|
||||||
|
Commit messages 8
|
||||||
|
LEB search messages 16
|
||||||
|
Budgeting messages 32
|
||||||
|
Garbage collection messages 64
|
||||||
|
Tree Node Cache (TNC) messages 128
|
||||||
|
LEB properties (lprops) messages 256
|
||||||
|
Input/output messages 512
|
||||||
|
Log messages 1024
|
||||||
|
Scan messages 2048
|
||||||
|
Recovery messages 4096
|
||||||
|
|
||||||
|
debug_chks Selects extra checks that UBIFS can do while running:
|
||||||
|
|
||||||
|
Check Flag value
|
||||||
|
|
||||||
|
General checks 1
|
||||||
|
Check Tree Node Cache (TNC) 2
|
||||||
|
Check indexing tree size 4
|
||||||
|
Check orphan area 8
|
||||||
|
Check old indexing tree 16
|
||||||
|
Check LEB properties (lprops) 32
|
||||||
|
Check leaf nodes and inodes 64
|
||||||
|
|
||||||
|
debug_tsts Selects a mode of testing, as follows:
|
||||||
|
|
||||||
|
Test mode Flag value
|
||||||
|
|
||||||
|
Force in-the-gaps method 2
|
||||||
|
Failure mode for recovery testing 4
|
||||||
|
|
||||||
|
For example, set debug_msgs to 5 to display General messages and Mount
|
||||||
|
messages.
|
||||||
|
|
||||||
|
|
||||||
|
References
|
||||||
|
==========
|
||||||
|
|
||||||
|
UBIFS documentation and FAQ/HOWTO at the MTD web site:
|
||||||
|
http://www.linux-mtd.infradead.org/doc/ubifs.html
|
||||||
|
http://www.linux-mtd.infradead.org/faq/ubifs.html
|
|
@ -3,7 +3,11 @@
|
||||||
|
|
||||||
Copyright 2008 Red Hat Inc.
|
Copyright 2008 Red Hat Inc.
|
||||||
Author: Steven Rostedt <srostedt@redhat.com>
|
Author: Steven Rostedt <srostedt@redhat.com>
|
||||||
|
License: The GNU Free Documentation License, Version 1.2
|
||||||
|
Reviewers: Elias Oltmanns, Randy Dunlap, Andrew Morton,
|
||||||
|
John Kacur, and David Teigland.
|
||||||
|
|
||||||
|
Written for: 2.6.27-rc1
|
||||||
|
|
||||||
Introduction
|
Introduction
|
||||||
------------
|
------------
|
||||||
|
@ -15,10 +19,11 @@ issues that take place outside of user-space.
|
||||||
|
|
||||||
Although ftrace is the function tracer, it also includes an
|
Although ftrace is the function tracer, it also includes an
|
||||||
infrastructure that allows for other types of tracing. Some of the
|
infrastructure that allows for other types of tracing. Some of the
|
||||||
tracers that are currently in ftrace is a tracer to trace
|
tracers that are currently in ftrace include a tracer to trace
|
||||||
context switches, the time it takes for a high priority task to
|
context switches, the time it takes for a high priority task to
|
||||||
run after it was woken up, the time interrupts are disabled, and
|
run after it was woken up, the time interrupts are disabled, and
|
||||||
more.
|
more (ftrace allows for tracer plugins, which means that the list of
|
||||||
|
tracers can always grow).
|
||||||
|
|
||||||
|
|
||||||
The File System
|
The File System
|
||||||
|
@ -32,6 +37,8 @@ To mount the debugfs system:
|
||||||
# mkdir /debug
|
# mkdir /debug
|
||||||
# mount -t debugfs nodev /debug
|
# mount -t debugfs nodev /debug
|
||||||
|
|
||||||
|
(Note: it is more common to mount at /sys/kernel/debug, but for simplicity
|
||||||
|
this document will use /debug)
|
||||||
|
|
||||||
That's it! (assuming that you have ftrace configured into your kernel)
|
That's it! (assuming that you have ftrace configured into your kernel)
|
||||||
|
|
||||||
|
@ -46,21 +53,20 @@ of ftrace. Here is a list of some of the key files:
|
||||||
that is configured.
|
that is configured.
|
||||||
|
|
||||||
available_tracers : This holds the different types of tracers that
|
available_tracers : This holds the different types of tracers that
|
||||||
has been compiled into the kernel. The tracers
|
have been compiled into the kernel. The tracers
|
||||||
listed here can be configured by echoing in their
|
listed here can be configured by echoing their name
|
||||||
name into current_tracer.
|
into current_tracer.
|
||||||
|
|
||||||
tracing_enabled : This sets or displays whether the current_tracer
|
tracing_enabled : This sets or displays whether the current_tracer
|
||||||
is activated and tracing or not. Echo 0 into this
|
is activated and tracing or not. Echo 0 into this
|
||||||
file to disable the tracer or 1 (or non-zero) to
|
file to disable the tracer or 1 to enable it.
|
||||||
enable it.
|
|
||||||
|
|
||||||
trace : This file holds the output of the trace in a human readable
|
trace : This file holds the output of the trace in a human readable
|
||||||
format.
|
format (described below).
|
||||||
|
|
||||||
latency_trace : This file shows the same trace but the information
|
latency_trace : This file shows the same trace but the information
|
||||||
is organized more to display possible latencies
|
is organized more to display possible latencies
|
||||||
in the system.
|
in the system (described below).
|
||||||
|
|
||||||
trace_pipe : The output is the same as the "trace" file but this
|
trace_pipe : The output is the same as the "trace" file but this
|
||||||
file is meant to be streamed with live tracing.
|
file is meant to be streamed with live tracing.
|
||||||
|
@ -72,7 +78,7 @@ of ftrace. Here is a list of some of the key files:
|
||||||
file, it is consumed, and will not be read
|
file, it is consumed, and will not be read
|
||||||
again with a sequential read. The "trace" and
|
again with a sequential read. The "trace" and
|
||||||
"latency_trace" files are static, and if the
|
"latency_trace" files are static, and if the
|
||||||
tracer isn't adding more data, they will display
|
tracer is not adding more data, they will display
|
||||||
the same information every time they are read.
|
the same information every time they are read.
|
||||||
|
|
||||||
iter_ctrl : This file lets the user control the amount of data
|
iter_ctrl : This file lets the user control the amount of data
|
||||||
|
@ -89,12 +95,14 @@ of ftrace. Here is a list of some of the key files:
|
||||||
|
|
||||||
trace_entries : This sets or displays the number of trace
|
trace_entries : This sets or displays the number of trace
|
||||||
entries each CPU buffer can hold. The tracer buffers
|
entries each CPU buffer can hold. The tracer buffers
|
||||||
are the same size for each CPU, so care must be
|
are the same size for each CPU. The displayed number
|
||||||
taken when modifying the trace_entries. The number
|
is the size of the CPU buffer and not total size. The
|
||||||
of actually entries will be the number given
|
trace buffers are allocated in pages (blocks of memory
|
||||||
times the number of possible CPUS. The buffers
|
that the kernel uses for allocation, usually 4 KB in size).
|
||||||
are saved as individual pages, and the actual entries
|
Since each entry is smaller than a page, if the last
|
||||||
will always be rounded up to entries per page.
|
allocated page has room for more entries than were
|
||||||
|
requested, the rest of the page is used to allocate
|
||||||
|
entries.
|
||||||
|
|
||||||
This can only be updated when the current_tracer
|
This can only be updated when the current_tracer
|
||||||
is set to "none".
|
is set to "none".
|
||||||
|
@ -107,20 +115,19 @@ of ftrace. Here is a list of some of the key files:
|
||||||
on specified CPUS. The format is a hex string
|
on specified CPUS. The format is a hex string
|
||||||
representing the CPUS.
|
representing the CPUS.
|
||||||
|
|
||||||
set_ftrace_filter : When dynamic ftrace is configured in, the
|
set_ftrace_filter : When dynamic ftrace is configured in (see the
|
||||||
code is dynamically modified to disable calling
|
section below "dynamic ftrace"), the code is dynamically
|
||||||
of the function profiler (mcount). This lets
|
modified (code text rewrite) to disable calling of the
|
||||||
tracing be configured in with practically no overhead
|
function profiler (mcount). This lets tracing be configured
|
||||||
in performance. This also has a side effect of
|
in with practically no overhead in performance. This also
|
||||||
enabling or disabling specific functions to be
|
has a side effect of enabling or disabling specific functions
|
||||||
traced. Echoing in names of functions into this
|
to be traced. Echoing names of functions into this file
|
||||||
file will limit the trace to only those files.
|
will limit the trace to only those functions.
|
||||||
|
|
||||||
set_ftrace_notrace: This has the opposite effect that
|
set_ftrace_notrace: This has an effect opposite to that of
|
||||||
set_ftrace_filter has. Any function that is added
|
set_ftrace_filter. Any function that is added here will not
|
||||||
here will not be traced. If a function exists
|
be traced. If a function exists in both set_ftrace_filter
|
||||||
in both set_ftrace_filter and set_ftrace_notrace
|
and set_ftrace_notrace, the function will _not_ be traced.
|
||||||
the function will _not_ bet traced.
|
|
||||||
|
|
||||||
available_filter_functions : When a function is encountered the first
|
available_filter_functions : When a function is encountered the first
|
||||||
time by the dynamic tracer, it is recorded and
|
time by the dynamic tracer, it is recorded and
|
||||||
|
@ -128,32 +135,31 @@ of ftrace. Here is a list of some of the key files:
|
||||||
lists the functions that have been recorded
|
lists the functions that have been recorded
|
||||||
by the dynamic tracer and these functions can
|
by the dynamic tracer and these functions can
|
||||||
be used to set the ftrace filter by the above
|
be used to set the ftrace filter by the above
|
||||||
"set_ftrace_filter" file.
|
"set_ftrace_filter" file. (See the section "dynamic ftrace"
|
||||||
|
below for more details).
|
||||||
|
|
||||||
|
|
||||||
The Tracers
|
The Tracers
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
Here are the list of current tracers that can be configured.
|
Here is the list of current tracers that may be configured.
|
||||||
|
|
||||||
ftrace - function tracer that uses mcount to trace all functions.
|
ftrace - function tracer that uses mcount to trace all functions.
|
||||||
It is possible to filter out which functions that are
|
|
||||||
traced when dynamic ftrace is configured in.
|
|
||||||
|
|
||||||
sched_switch - traces the context switches between tasks.
|
sched_switch - traces the context switches between tasks.
|
||||||
|
|
||||||
irqsoff - traces the areas that disable interrupts and saves off
|
irqsoff - traces the areas that disable interrupts and saves
|
||||||
the trace with the longest max latency.
|
the trace with the longest max latency.
|
||||||
See tracing_max_latency. When a new max is recorded,
|
See tracing_max_latency. When a new max is recorded,
|
||||||
it replaces the old trace. It is best to view this
|
it replaces the old trace. It is best to view this
|
||||||
trace with the latency_trace file.
|
trace via the latency_trace file.
|
||||||
|
|
||||||
preemptoff - Similar to irqsoff but traces and records the time
|
preemptoff - Similar to irqsoff but traces and records the amount of
|
||||||
preemption is disabled.
|
time for which preemption is disabled.
|
||||||
|
|
||||||
preemptirqsoff - Similar to irqsoff and preemptoff, but traces and
|
preemptirqsoff - Similar to irqsoff and preemptoff, but traces and
|
||||||
records the largest time irqs and/or preemption is
|
records the largest time for which irqs and/or preemption
|
||||||
disabled.
|
is disabled.
|
||||||
|
|
||||||
wakeup - Traces and records the max latency that it takes for
|
wakeup - Traces and records the max latency that it takes for
|
||||||
the highest priority task to get scheduled after
|
the highest priority task to get scheduled after
|
||||||
|
@ -166,13 +172,13 @@ Here are the list of current tracers that can be configured.
|
||||||
Examples of using the tracer
|
Examples of using the tracer
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
Here are typical examples of using the tracers with only controlling
|
Here are typical examples of using the tracers when controlling them only
|
||||||
them with the debugfs interface (without using any user-land utilities).
|
with the debugfs interface (without using any user-land utilities).
|
||||||
|
|
||||||
Output format:
|
Output format:
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
Here's an example of the output format of the file "trace"
|
Here is an example of the output format of the file "trace"
|
||||||
|
|
||||||
--------
|
--------
|
||||||
# tracer: ftrace
|
# tracer: ftrace
|
||||||
|
@ -184,12 +190,13 @@ Here's an example of the output format of the file "trace"
|
||||||
bash-4251 [01] 10152.583855: _atomic_dec_and_lock <-dput
|
bash-4251 [01] 10152.583855: _atomic_dec_and_lock <-dput
|
||||||
--------
|
--------
|
||||||
|
|
||||||
A header is printed with the trace that is represented. In this case
|
A header is printed with the tracer name that is represented by the trace.
|
||||||
the tracer is "ftrace". Then a header showing the format. Task name
|
In this case the tracer is "ftrace". Then a header showing the format. Task
|
||||||
"bash", the task PID "4251", the CPU that it was running on
|
name "bash", the task PID "4251", the CPU that it was running on
|
||||||
"01", the timestamp in <secs>.<usecs> format, the function name that was
|
"01", the timestamp in <secs>.<usecs> format, the function name that was
|
||||||
traced "path_put" and the parent function that called this function
|
traced "path_put" and the parent function that called this function
|
||||||
"path_walk".
|
"path_walk". The timestamp is the time at which the function was
|
||||||
|
entered.
|
||||||
|
|
||||||
The sched_switch tracer also includes tracing of task wakeups and
|
The sched_switch tracer also includes tracing of task wakeups and
|
||||||
context switches.
|
context switches.
|
||||||
|
@ -201,7 +208,7 @@ context switches.
|
||||||
kondemand/1-2916 [01] 1453.070013: 2916:115:S ==> 7:115:R
|
kondemand/1-2916 [01] 1453.070013: 2916:115:S ==> 7:115:R
|
||||||
ksoftirqd/1-7 [01] 1453.070013: 7:115:S ==> 0:140:R
|
ksoftirqd/1-7 [01] 1453.070013: 7:115:S ==> 0:140:R
|
||||||
|
|
||||||
Wake ups are represented by a "+" and the context switches show
|
Wake ups are represented by a "+" and the context switches are shown as
|
||||||
"==>". The format is:
|
"==>". The format is:
|
||||||
|
|
||||||
Context switches:
|
Context switches:
|
||||||
|
@ -216,7 +223,7 @@ Wake ups are represented by a "+" and the context switches show
|
||||||
|
|
||||||
<pid>:<prio>:<state> + <pid>:<prio>:<state>
|
<pid>:<prio>:<state> + <pid>:<prio>:<state>
|
||||||
|
|
||||||
The prio is the internal kernel priority, which is inverse to the
|
The prio is the internal kernel priority, which is the inverse of the
|
||||||
priority that is usually displayed by user-space tools. Zero represents
|
priority that is usually displayed by user-space tools. Zero represents
|
||||||
the highest priority (99). Prio 100 starts the "nice" priorities with
|
the highest priority (99). Prio 100 starts the "nice" priorities with
|
||||||
100 being equal to nice -20 and 139 being nice 19. The prio "140" is
|
100 being equal to nice -20 and 139 being nice 19. The prio "140" is
|
||||||
|
@ -227,7 +234,7 @@ Latency trace format
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
For traces that display latency times, the latency_trace file gives
|
For traces that display latency times, the latency_trace file gives
|
||||||
a bit more information to see why a latency happened. Here's a typical
|
somewhat more information to see why a latency happened. Here is a typical
|
||||||
trace.
|
trace.
|
||||||
|
|
||||||
# tracer: irqsoff
|
# tracer: irqsoff
|
||||||
|
@ -255,21 +262,20 @@ irqsoff latency trace v1.1.5 on 2.6.26-rc8
|
||||||
<idle>-0 0d.s1 98us : trace_hardirqs_on (do_softirq)
|
<idle>-0 0d.s1 98us : trace_hardirqs_on (do_softirq)
|
||||||
|
|
||||||
|
|
||||||
vim:ft=help
|
|
||||||
|
|
||||||
|
This shows that the current tracer is "irqsoff" tracing the time for which
|
||||||
This shows that the current tracer is "irqsoff" tracing the time
|
interrupts were disabled. It gives the trace version and the version
|
||||||
interrupts are disabled. It gives the trace version and the kernel
|
of the kernel upon which this was executed on (2.6.26-rc8). Then it displays
|
||||||
this was executed on (2.6.26-rc8). Then it displays the max latency
|
the max latency in microsecs (97 us). The number of trace entries displayed
|
||||||
in microsecs (97 us). The number of trace entries displayed
|
and the total number recorded (both are three: #3/3). The type of
|
||||||
by the total number recorded (both are three: #3/3). The type of
|
|
||||||
preemption that was used (PREEMPT). VP, KP, SP, and HP are always zero
|
preemption that was used (PREEMPT). VP, KP, SP, and HP are always zero
|
||||||
and reserved for later use. #P is the number of online CPUS (#P:2).
|
and are reserved for later use. #P is the number of online CPUS (#P:2).
|
||||||
|
|
||||||
The task is the process that was running when the latency happened.
|
The task is the process that was running when the latency occurred.
|
||||||
(swapper pid: 0).
|
(swapper pid: 0).
|
||||||
|
|
||||||
The start and stop that caused the latencies:
|
The start and stop (the functions in which the interrupts were disabled and
|
||||||
|
enabled respectively) that caused the latencies:
|
||||||
|
|
||||||
apic_timer_interrupt is where the interrupts were disabled.
|
apic_timer_interrupt is where the interrupts were disabled.
|
||||||
do_softirq is where they were enabled again.
|
do_softirq is where they were enabled again.
|
||||||
|
@ -281,14 +287,14 @@ explains which is which.
|
||||||
|
|
||||||
pid: The PID of that process.
|
pid: The PID of that process.
|
||||||
|
|
||||||
CPU#: The CPU that the process was running on.
|
CPU#: The CPU which the process was running on.
|
||||||
|
|
||||||
irqs-off: 'd' interrupts are disabled. '.' otherwise.
|
irqs-off: 'd' interrupts are disabled. '.' otherwise.
|
||||||
|
|
||||||
need-resched: 'N' task need_resched is set, '.' otherwise.
|
need-resched: 'N' task need_resched is set, '.' otherwise.
|
||||||
|
|
||||||
hardirq/softirq:
|
hardirq/softirq:
|
||||||
'H' - hard irq happened inside a softirq.
|
'H' - hard irq occurred inside a softirq.
|
||||||
'h' - hard irq is running
|
'h' - hard irq is running
|
||||||
's' - soft irq is running
|
's' - soft irq is running
|
||||||
'.' - normal context.
|
'.' - normal context.
|
||||||
|
@ -297,13 +303,13 @@ explains which is which.
|
||||||
|
|
||||||
The above is mostly meaningful for kernel developers.
|
The above is mostly meaningful for kernel developers.
|
||||||
|
|
||||||
time: This differs from the trace output where as the trace output
|
time: This differs from the trace file output. The trace file output
|
||||||
contained a absolute timestamp. This timestamp is relative
|
includes an absolute timestamp. The timestamp used by the
|
||||||
to the start of the first entry in the the trace.
|
latency_trace file is relative to the start of the trace.
|
||||||
|
|
||||||
delay: This is just to help catch your eye a bit better. And
|
delay: This is just to help catch your eye a bit better. And
|
||||||
needs to be fixed to be only relative to the same CPU.
|
needs to be fixed to be only relative to the same CPU.
|
||||||
The marks is determined by the difference between this
|
The marks are determined by the difference between this
|
||||||
current trace and the next trace.
|
current trace and the next trace.
|
||||||
'!' - greater than preempt_mark_thresh (default 100)
|
'!' - greater than preempt_mark_thresh (default 100)
|
||||||
'+' - greater than 1 microsecond
|
'+' - greater than 1 microsecond
|
||||||
|
@ -322,13 +328,13 @@ output. To see what is available, simply cat the file:
|
||||||
print-parent nosym-offset nosym-addr noverbose noraw nohex nobin \
|
print-parent nosym-offset nosym-addr noverbose noraw nohex nobin \
|
||||||
noblock nostacktrace nosched-tree
|
noblock nostacktrace nosched-tree
|
||||||
|
|
||||||
To disable one of the options, echo in the option appended with "no".
|
To disable one of the options, echo in the option prepended with "no".
|
||||||
|
|
||||||
echo noprint-parent > /debug/tracing/iter_ctrl
|
echo noprint-parent > /debug/tracing/iter_ctrl
|
||||||
|
|
||||||
To enable an option, leave off the "no".
|
To enable an option, leave off the "no".
|
||||||
|
|
||||||
echo sym-offest > /debug/tracing/iter_ctrl
|
echo sym-offset > /debug/tracing/iter_ctrl
|
||||||
|
|
||||||
Here are the available options:
|
Here are the available options:
|
||||||
|
|
||||||
|
@ -344,7 +350,7 @@ Here are the available options:
|
||||||
|
|
||||||
sym-offset - Display not only the function name, but also the offset
|
sym-offset - Display not only the function name, but also the offset
|
||||||
in the function. For example, instead of seeing just
|
in the function. For example, instead of seeing just
|
||||||
"ktime_get" you will see "ktime_get+0xb/0x20"
|
"ktime_get", you will see "ktime_get+0xb/0x20".
|
||||||
|
|
||||||
sym-offset:
|
sym-offset:
|
||||||
bash-4000 [01] 1477.606694: simple_strtoul+0x6/0xa0
|
bash-4000 [01] 1477.606694: simple_strtoul+0x6/0xa0
|
||||||
|
@ -364,7 +370,7 @@ Here are the available options:
|
||||||
user applications that can translate the raw numbers better than
|
user applications that can translate the raw numbers better than
|
||||||
having it done in the kernel.
|
having it done in the kernel.
|
||||||
|
|
||||||
hex - similar to raw, but the numbers will be in a hexadecimal format.
|
hex - Similar to raw, but the numbers will be in a hexadecimal format.
|
||||||
|
|
||||||
bin - This will print out the formats in raw binary.
|
bin - This will print out the formats in raw binary.
|
||||||
|
|
||||||
|
@ -380,8 +386,8 @@ Here are the available options:
|
||||||
sched_switch
|
sched_switch
|
||||||
------------
|
------------
|
||||||
|
|
||||||
This tracer simply records schedule switches. Here's an example
|
This tracer simply records schedule switches. Here is an example
|
||||||
on how to implement it.
|
of how to use it.
|
||||||
|
|
||||||
# echo sched_switch > /debug/tracing/current_tracer
|
# echo sched_switch > /debug/tracing/current_tracer
|
||||||
# echo 1 > /debug/tracing/tracing_enabled
|
# echo 1 > /debug/tracing/tracing_enabled
|
||||||
|
@ -416,8 +422,8 @@ the name of the trace and points to the options. The "FUNCTION"
|
||||||
is a misnomer since here it represents the wake ups and context
|
is a misnomer since here it represents the wake ups and context
|
||||||
switches.
|
switches.
|
||||||
|
|
||||||
The sched_switch only lists the wake ups (represented with '+')
|
The sched_switch file only lists the wake ups (represented with '+')
|
||||||
and context switches ('==>') with the previous task or current
|
and context switches ('==>') with the previous task or current task
|
||||||
first followed by the next task or task waking up. The format for both
|
first followed by the next task or task waking up. The format for both
|
||||||
of these is PID:KERNEL-PRIO:TASK-STATE. Remember that the KERNEL-PRIO
|
of these is PID:KERNEL-PRIO:TASK-STATE. Remember that the KERNEL-PRIO
|
||||||
is the inverse of the actual priority with zero (0) being the highest
|
is the inverse of the actual priority with zero (0) being the highest
|
||||||
|
@ -432,7 +438,8 @@ The task states are:
|
||||||
|
|
||||||
R - running : wants to run, may not actually be running
|
R - running : wants to run, may not actually be running
|
||||||
S - sleep : process is waiting to be woken up (handles signals)
|
S - sleep : process is waiting to be woken up (handles signals)
|
||||||
D - deep sleep : process must be woken up (ignores signals)
|
D - disk sleep (uninterruptible sleep) : process must be woken up
|
||||||
|
(ignores signals)
|
||||||
T - stopped : process suspended
|
T - stopped : process suspended
|
||||||
t - traced : process is being traced (with something like gdb)
|
t - traced : process is being traced (with something like gdb)
|
||||||
Z - zombie : process waiting to be cleaned up
|
Z - zombie : process waiting to be cleaned up
|
||||||
|
@ -442,8 +449,8 @@ The task states are:
|
||||||
ftrace_enabled
|
ftrace_enabled
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
The following tracers give different output depending on whether
|
The following tracers (listed below) give different output depending
|
||||||
or not the sysctl ftrace_enabled is set. To set ftrace_enabled,
|
on whether or not the sysctl ftrace_enabled is set. To set ftrace_enabled,
|
||||||
one can either use the sysctl function or set it via the proc
|
one can either use the sysctl function or set it via the proc
|
||||||
file system interface.
|
file system interface.
|
||||||
|
|
||||||
|
@ -470,13 +477,12 @@ interrupt from triggering or the mouse interrupt from letting the
|
||||||
kernel know of a new mouse event. The result is a latency with the
|
kernel know of a new mouse event. The result is a latency with the
|
||||||
reaction time.
|
reaction time.
|
||||||
|
|
||||||
The irqsoff tracer tracks the time interrupts are disabled and when
|
The irqsoff tracer tracks the time for which interrupts are disabled.
|
||||||
they are re-enabled. When a new maximum latency is hit, it saves off
|
When a new maximum latency is hit, the tracer saves the trace leading up
|
||||||
the trace so that it may be retrieved at a later time. Every time a
|
to that latency point so that every time a new maximum is reached, the old
|
||||||
new maximum in reached, the old saved trace is discarded and the new
|
saved trace is discarded and the new trace is saved.
|
||||||
trace is saved.
|
|
||||||
|
|
||||||
To reset the maximum, echo 0 into tracing_max_latency. Here's an
|
To reset the maximum, echo 0 into tracing_max_latency. Here is an
|
||||||
example:
|
example:
|
||||||
|
|
||||||
# echo irqsoff > /debug/tracing/current_tracer
|
# echo irqsoff > /debug/tracing/current_tracer
|
||||||
|
@ -488,14 +494,14 @@ example:
|
||||||
# cat /debug/tracing/latency_trace
|
# cat /debug/tracing/latency_trace
|
||||||
# tracer: irqsoff
|
# tracer: irqsoff
|
||||||
#
|
#
|
||||||
irqsoff latency trace v1.1.5 on 2.6.26-rc8
|
irqsoff latency trace v1.1.5 on 2.6.26
|
||||||
--------------------------------------------------------------------
|
--------------------------------------------------------------------
|
||||||
latency: 6 us, #3/3, CPU#1 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
|
latency: 12 us, #3/3, CPU#1 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
|
||||||
-----------------
|
-----------------
|
||||||
| task: bash-4269 (uid:0 nice:0 policy:0 rt_prio:0)
|
| task: bash-3730 (uid:0 nice:0 policy:0 rt_prio:0)
|
||||||
-----------------
|
-----------------
|
||||||
=> started at: copy_page_range
|
=> started at: sys_setpgid
|
||||||
=> ended at: copy_page_range
|
=> ended at: sys_setpgid
|
||||||
|
|
||||||
# _------=> CPU#
|
# _------=> CPU#
|
||||||
# / _-----=> irqs-off
|
# / _-----=> irqs-off
|
||||||
|
@ -506,21 +512,19 @@ irqsoff latency trace v1.1.5 on 2.6.26-rc8
|
||||||
# ||||| delay
|
# ||||| delay
|
||||||
# cmd pid ||||| time | caller
|
# cmd pid ||||| time | caller
|
||||||
# \ / ||||| \ | /
|
# \ / ||||| \ | /
|
||||||
bash-4269 1...1 0us+: _spin_lock (copy_page_range)
|
bash-3730 1d... 0us : _write_lock_irq (sys_setpgid)
|
||||||
bash-4269 1...1 7us : _spin_unlock (copy_page_range)
|
bash-3730 1d..1 1us+: _write_unlock_irq (sys_setpgid)
|
||||||
bash-4269 1...2 7us : trace_preempt_on (copy_page_range)
|
bash-3730 1d..2 14us : trace_hardirqs_on (sys_setpgid)
|
||||||
|
|
||||||
|
|
||||||
vim:ft=help
|
Here we see that that we had a latency of 12 microsecs (which is
|
||||||
|
very good). The _write_lock_irq in sys_setpgid disabled interrupts.
|
||||||
|
The difference between the 12 and the displayed timestamp 14us occurred
|
||||||
|
because the clock was incremented between the time of recording the max
|
||||||
|
latency and the time of recording the function that had that latency.
|
||||||
|
|
||||||
Here we see that that we had a latency of 6 microsecs (which is
|
Note the above example had ftrace_enabled not set. If we set the
|
||||||
very good). The spin_lock in copy_page_range disabled interrupts.
|
ftrace_enabled, we get a much larger output:
|
||||||
The difference between the 6 and the displayed timestamp 7us is
|
|
||||||
because the clock must have incremented between the time of recording
|
|
||||||
the max latency and recording the function that had that latency.
|
|
||||||
|
|
||||||
Note the above had ftrace_enabled not set. If we set the ftrace_enabled
|
|
||||||
we get a much larger output:
|
|
||||||
|
|
||||||
# tracer: irqsoff
|
# tracer: irqsoff
|
||||||
#
|
#
|
||||||
|
@ -566,27 +570,26 @@ irqsoff latency trace v1.1.5 on 2.6.26-rc8
|
||||||
ls-4339 0d..2 51us : trace_hardirqs_on (__alloc_pages_internal)
|
ls-4339 0d..2 51us : trace_hardirqs_on (__alloc_pages_internal)
|
||||||
|
|
||||||
|
|
||||||
vim:ft=help
|
|
||||||
|
|
||||||
|
|
||||||
Here we traced a 50 microsecond latency. But we also see all the
|
Here we traced a 50 microsecond latency. But we also see all the
|
||||||
functions that were called during that time. Note that enabling
|
functions that were called during that time. Note that by enabling
|
||||||
function tracing we endure an added overhead. This overhead may
|
function tracing, we incur an added overhead. This overhead may
|
||||||
extend the latency times. But nevertheless, this trace has provided
|
extend the latency times. But nevertheless, this trace has provided
|
||||||
some very helpful debugging.
|
some very helpful debugging information.
|
||||||
|
|
||||||
|
|
||||||
preemptoff
|
preemptoff
|
||||||
----------
|
----------
|
||||||
|
|
||||||
When preemption is disabled we may be able to receive interrupts but
|
When preemption is disabled, we may be able to receive interrupts but
|
||||||
the task cannot be preempted and a higher priority task must wait
|
the task cannot be preempted and a higher priority task must wait
|
||||||
for preemption to be enabled again before it can preempt a lower
|
for preemption to be enabled again before it can preempt a lower
|
||||||
priority task.
|
priority task.
|
||||||
|
|
||||||
The preemptoff tracer traces the places that disables preemption.
|
The preemptoff tracer traces the places that disable preemption.
|
||||||
Like the irqsoff, it records the maximum latency that preemption
|
Like the irqsoff tracer, it records the maximum latency for which preemption
|
||||||
was disabled. The control of preemptoff is much like the irqsoff.
|
was disabled. The control of preemptoff tracer is much like the irqsoff
|
||||||
|
tracer.
|
||||||
|
|
||||||
# echo preemptoff > /debug/tracing/current_tracer
|
# echo preemptoff > /debug/tracing/current_tracer
|
||||||
# echo 0 > /debug/tracing/tracing_max_latency
|
# echo 0 > /debug/tracing/tracing_max_latency
|
||||||
|
@ -620,8 +623,6 @@ preemptoff latency trace v1.1.5 on 2.6.26-rc8
|
||||||
sshd-4261 0d.s1 30us : trace_preempt_on (__do_softirq)
|
sshd-4261 0d.s1 30us : trace_preempt_on (__do_softirq)
|
||||||
|
|
||||||
|
|
||||||
vim:ft=help
|
|
||||||
|
|
||||||
This has some more changes. Preemption was disabled when an interrupt
|
This has some more changes. Preemption was disabled when an interrupt
|
||||||
came in (notice the 'h'), and was enabled while doing a softirq.
|
came in (notice the 'h'), and was enabled while doing a softirq.
|
||||||
(notice the 's'). But we also see that interrupts have been disabled
|
(notice the 's'). But we also see that interrupts have been disabled
|
||||||
|
@ -689,16 +690,16 @@ The above is an example of the preemptoff trace with ftrace_enabled
|
||||||
set. Here we see that interrupts were disabled the entire time.
|
set. Here we see that interrupts were disabled the entire time.
|
||||||
The irq_enter code lets us know that we entered an interrupt 'h'.
|
The irq_enter code lets us know that we entered an interrupt 'h'.
|
||||||
Before that, the functions being traced still show that it is not
|
Before that, the functions being traced still show that it is not
|
||||||
in an interrupt, but we can see by the functions themselves that
|
in an interrupt, but we can see from the functions themselves that
|
||||||
this is not the case.
|
this is not the case.
|
||||||
|
|
||||||
Notice that the __do_softirq when called doesn't have a preempt_count.
|
Notice that __do_softirq when called does not have a preempt_count.
|
||||||
It may seem that we missed a preempt enabled. What really happened
|
It may seem that we missed a preempt enabling. What really happened
|
||||||
is that the preempt count is held on the threads stack and we
|
is that the preempt count is held on the thread's stack and we
|
||||||
switched to the softirq stack (4K stacks in effect). The code
|
switched to the softirq stack (4K stacks in effect). The code
|
||||||
does not copy the preempt count, but because interrupts are disabled
|
does not copy the preempt count, but because interrupts are disabled,
|
||||||
we don't need to worry about it. Having a tracer like this is good
|
we do not need to worry about it. Having a tracer like this is good
|
||||||
to let people know what really happens inside the kernel.
|
for letting people know what really happens inside the kernel.
|
||||||
|
|
||||||
|
|
||||||
preemptirqsoff
|
preemptirqsoff
|
||||||
|
@ -708,7 +709,7 @@ Knowing the locations that have interrupts disabled or preemption
|
||||||
disabled for the longest times is helpful. But sometimes we would
|
disabled for the longest times is helpful. But sometimes we would
|
||||||
like to know when either preemption and/or interrupts are disabled.
|
like to know when either preemption and/or interrupts are disabled.
|
||||||
|
|
||||||
The following code:
|
Consider the following code:
|
||||||
|
|
||||||
local_irq_disable();
|
local_irq_disable();
|
||||||
call_function_with_irqs_off();
|
call_function_with_irqs_off();
|
||||||
|
@ -732,7 +733,7 @@ To record this time, use the preemptirqsoff tracer.
|
||||||
|
|
||||||
Again, using this trace is much like the irqsoff and preemptoff tracers.
|
Again, using this trace is much like the irqsoff and preemptoff tracers.
|
||||||
|
|
||||||
# echo preemptoff > /debug/tracing/current_tracer
|
# echo preemptirqsoff > /debug/tracing/current_tracer
|
||||||
# echo 0 > /debug/tracing/tracing_max_latency
|
# echo 0 > /debug/tracing/tracing_max_latency
|
||||||
# echo 1 > /debug/tracing/tracing_enabled
|
# echo 1 > /debug/tracing/tracing_enabled
|
||||||
# ls -ltr
|
# ls -ltr
|
||||||
|
@ -764,12 +765,10 @@ preemptirqsoff latency trace v1.1.5 on 2.6.26-rc8
|
||||||
ls-4860 0d.s1 294us : trace_preempt_on (__do_softirq)
|
ls-4860 0d.s1 294us : trace_preempt_on (__do_softirq)
|
||||||
|
|
||||||
|
|
||||||
vim:ft=help
|
|
||||||
|
|
||||||
|
|
||||||
The trace_hardirqs_off_thunk is called from assembly on x86 when
|
The trace_hardirqs_off_thunk is called from assembly on x86 when
|
||||||
interrupts are disabled in the assembly code. Without the function
|
interrupts are disabled in the assembly code. Without the function
|
||||||
tracing, we don't know if interrupts were enabled within the preemption
|
tracing, we do not know if interrupts were enabled within the preemption
|
||||||
points. We do see that it started with preemption enabled.
|
points. We do see that it started with preemption enabled.
|
||||||
|
|
||||||
Here is a trace with ftrace_enabled set:
|
Here is a trace with ftrace_enabled set:
|
||||||
|
@ -860,25 +859,25 @@ preemptirqsoff latency trace v1.1.5 on 2.6.26-rc8
|
||||||
|
|
||||||
This is a very interesting trace. It started with the preemption of
|
This is a very interesting trace. It started with the preemption of
|
||||||
the ls task. We see that the task had the "need_resched" bit set
|
the ls task. We see that the task had the "need_resched" bit set
|
||||||
with the 'N' in the trace. Interrupts are disabled in the spin_lock
|
via the 'N' in the trace. Interrupts were disabled before the spin_lock
|
||||||
and the trace started. We see that a schedule took place to run
|
at the beginning of the trace. We see that a schedule took place to run
|
||||||
sshd. When the interrupts were enabled we took an interrupt.
|
sshd. When the interrupts were enabled, we took an interrupt.
|
||||||
On return of the interrupt the softirq ran. We took another interrupt
|
On return from the interrupt handler, the softirq ran. We took another
|
||||||
while running the softirq as we see with the capital 'H'.
|
interrupt while running the softirq as we see from the capital 'H'.
|
||||||
|
|
||||||
|
|
||||||
wakeup
|
wakeup
|
||||||
------
|
------
|
||||||
|
|
||||||
In Real-Time environment it is very important to know the wakeup
|
In a Real-Time environment it is very important to know the wakeup
|
||||||
time it takes for the highest priority task that wakes up to the
|
time it takes for the highest priority task that is woken up to the
|
||||||
time it executes. This is also known as "schedule latency".
|
time that it executes. This is also known as "schedule latency".
|
||||||
I stress the point that this is about RT tasks. It is also important
|
I stress the point that this is about RT tasks. It is also important
|
||||||
to know the scheduling latency of non-RT tasks, but the average
|
to know the scheduling latency of non-RT tasks, but the average
|
||||||
schedule latency is better for non-RT tasks. Tools like
|
schedule latency is better for non-RT tasks. Tools like
|
||||||
LatencyTop is more appropriate for such measurements.
|
LatencyTop are more appropriate for such measurements.
|
||||||
|
|
||||||
Real-Time environments is interested in the worst case latency.
|
Real-Time environments are interested in the worst case latency.
|
||||||
That is the longest latency it takes for something to happen, and
|
That is the longest latency it takes for something to happen, and
|
||||||
not the average. We can have a very fast scheduler that may only
|
not the average. We can have a very fast scheduler that may only
|
||||||
have a large latency once in a while, but that would not work well
|
have a large latency once in a while, but that would not work well
|
||||||
|
@ -889,8 +888,8 @@ tasks that are unpredictable will overwrite the worst case latency
|
||||||
of RT tasks.
|
of RT tasks.
|
||||||
|
|
||||||
Since this tracer only deals with RT tasks, we will run this slightly
|
Since this tracer only deals with RT tasks, we will run this slightly
|
||||||
different than we did with the previous tracers. Instead of performing
|
differently than we did with the previous tracers. Instead of performing
|
||||||
an 'ls' we will run 'sleep 1' under 'chrt' which changes the
|
an 'ls', we will run 'sleep 1' under 'chrt' which changes the
|
||||||
priority of the task.
|
priority of the task.
|
||||||
|
|
||||||
# echo wakeup > /debug/tracing/current_tracer
|
# echo wakeup > /debug/tracing/current_tracer
|
||||||
|
@ -921,12 +920,10 @@ wakeup latency trace v1.1.5 on 2.6.26-rc8
|
||||||
<idle>-0 1d..4 4us : schedule (cpu_idle)
|
<idle>-0 1d..4 4us : schedule (cpu_idle)
|
||||||
|
|
||||||
|
|
||||||
vim:ft=help
|
|
||||||
|
|
||||||
|
Running this on an idle system, we see that it only took 4 microseconds
|
||||||
Running this on an idle system we see that it only took 4 microseconds
|
|
||||||
to perform the task switch. Note, since the trace marker in the
|
to perform the task switch. Note, since the trace marker in the
|
||||||
schedule is before the actual "switch" we stop the tracing when
|
schedule is before the actual "switch", we stop the tracing when
|
||||||
the recorded task is about to schedule in. This may change if
|
the recorded task is about to schedule in. This may change if
|
||||||
we add a new marker at the end of the scheduler.
|
we add a new marker at the end of the scheduler.
|
||||||
|
|
||||||
|
@ -991,13 +988,16 @@ ksoftirq-7 1d..6 49us : sub_preempt_count (_spin_unlock)
|
||||||
ksoftirq-7 1d..4 50us : schedule (__cond_resched)
|
ksoftirq-7 1d..4 50us : schedule (__cond_resched)
|
||||||
|
|
||||||
The interrupt went off while running ksoftirqd. This task runs at
|
The interrupt went off while running ksoftirqd. This task runs at
|
||||||
SCHED_OTHER. Why didn't we see the 'N' set early? This may be
|
SCHED_OTHER. Why did not we see the 'N' set early? This may be
|
||||||
a harmless bug with x86_32 and 4K stacks. The need_reched() function
|
a harmless bug with x86_32 and 4K stacks. On x86_32 with 4K stacks
|
||||||
that tests if we need to reschedule looks on the actual stack.
|
configured, the interrupt and softirq run with their own stack.
|
||||||
Where as the setting of the NEED_RESCHED bit happens on the
|
Some information is held on the top of the task's stack (need_resched
|
||||||
task's stack. But because we are in a hard interrupt, the test
|
and preempt_count are both stored there). The setting of the NEED_RESCHED
|
||||||
is with the interrupts stack which has that to be false. We don't
|
bit is done directly to the task's stack, but the reading of the
|
||||||
see the 'N' until we switch back to the task's stack.
|
NEED_RESCHED is done by looking at the current stack, which in this case
|
||||||
|
is the stack for the hard interrupt. This hides the fact that NEED_RESCHED
|
||||||
|
has been set. We do not see the 'N' until we switch back to the task's
|
||||||
|
assigned stack.
|
||||||
|
|
||||||
ftrace
|
ftrace
|
||||||
------
|
------
|
||||||
|
@ -1036,14 +1036,14 @@ this tracer is a nop.
|
||||||
[...]
|
[...]
|
||||||
|
|
||||||
|
|
||||||
Note: It is sometimes better to enable or disable tracing directly from
|
Note: ftrace uses ring buffers to store the above entries. The newest data
|
||||||
a program, because the buffer may be overflowed by the echo commands
|
may overwrite the oldest data. Sometimes using echo to stop the trace
|
||||||
before you get to the point you want to trace. It is also easier to
|
is not sufficient because the tracing could have overwritten the data
|
||||||
stop the tracing at the point that you hit the part that you are
|
that you wanted to record. For this reason, it is sometimes better to
|
||||||
interested in. Since the ftrace buffer is a ring buffer with the
|
disable tracing directly from a program. This allows you to stop the
|
||||||
oldest data being overwritten, usually it is sufficient to start the
|
tracing at the point that you hit the part that you are interested in.
|
||||||
tracer with an echo command but have you code stop it. Something
|
To disable the tracing directly from a C program, something like following
|
||||||
like the following is usually appropriate for this.
|
code snippet can be used:
|
||||||
|
|
||||||
int trace_fd;
|
int trace_fd;
|
||||||
[...]
|
[...]
|
||||||
|
@ -1057,20 +1057,26 @@ int main(int argc, char *argv[]) {
|
||||||
[...]
|
[...]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Note: Here we hard coded the path name. The debugfs mount is not
|
||||||
|
guaranteed to be at /debug (and is more commonly at /sys/kernel/debug).
|
||||||
|
For simple one time traces, the above is sufficent. For anything else,
|
||||||
|
a search through /proc/mounts may be needed to find where the debugfs
|
||||||
|
file-system is mounted.
|
||||||
|
|
||||||
dynamic ftrace
|
dynamic ftrace
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
If CONFIG_DYNAMIC_FTRACE is set, then the system will run with
|
If CONFIG_DYNAMIC_FTRACE is set, the system will run with
|
||||||
virtually no overhead when function tracing is disabled. The way
|
virtually no overhead when function tracing is disabled. The way
|
||||||
this works is the mcount function call (placed at the start of
|
this works is the mcount function call (placed at the start of
|
||||||
every kernel function, produced by the -pg switch in gcc), starts
|
every kernel function, produced by the -pg switch in gcc), starts
|
||||||
of pointing to a simple return.
|
of pointing to a simple return. (Enabling FTRACE will include the
|
||||||
|
-pg switch in the compiling of the kernel.)
|
||||||
|
|
||||||
When dynamic ftrace is initialized, it calls kstop_machine to make it
|
When dynamic ftrace is initialized, it calls kstop_machine to make
|
||||||
act like a uniprocessor so that it can freely modify code without
|
the machine act like a uniprocessor so that it can freely modify code
|
||||||
worrying about other processors executing that same code. At
|
without worrying about other processors executing that same code. At
|
||||||
initialization, the mcount calls are change to call a "record_ip"
|
initialization, the mcount calls are changed to call a "record_ip"
|
||||||
function. After this, the first time a kernel function is called,
|
function. After this, the first time a kernel function is called,
|
||||||
it has the calling address saved in a hash table.
|
it has the calling address saved in a hash table.
|
||||||
|
|
||||||
|
@ -1078,15 +1084,15 @@ Later on the ftraced kernel thread is awoken and will again call
|
||||||
kstop_machine if new functions have been recorded. The ftraced thread
|
kstop_machine if new functions have been recorded. The ftraced thread
|
||||||
will change all calls to mcount to "nop". Just calling mcount
|
will change all calls to mcount to "nop". Just calling mcount
|
||||||
and having mcount return has shown a 10% overhead. By converting
|
and having mcount return has shown a 10% overhead. By converting
|
||||||
it to a nop, there is no recordable overhead to the system.
|
it to a nop, there is no measurable overhead to the system.
|
||||||
|
|
||||||
One special side-effect to the recording of the functions being
|
One special side-effect to the recording of the functions being
|
||||||
traced, is that we can now selectively choose which functions we
|
traced is that we can now selectively choose which functions we
|
||||||
want to trace and which ones we want the mcount calls to remain as
|
wish to trace and which ones we want the mcount calls to remain as
|
||||||
nops.
|
nops.
|
||||||
|
|
||||||
Two files that contain to the enabling and disabling of recorded
|
Two files are used, one for enabling and one for disabling the tracing
|
||||||
functions are:
|
of specified functions. They are:
|
||||||
|
|
||||||
set_ftrace_filter
|
set_ftrace_filter
|
||||||
|
|
||||||
|
@ -1094,7 +1100,7 @@ and
|
||||||
|
|
||||||
set_ftrace_notrace
|
set_ftrace_notrace
|
||||||
|
|
||||||
A list of available functions that you can add to this files is listed
|
A list of available functions that you can add to these files is listed
|
||||||
in:
|
in:
|
||||||
|
|
||||||
available_filter_functions
|
available_filter_functions
|
||||||
|
@ -1108,7 +1114,7 @@ pick_next_task_fair
|
||||||
mutex_lock
|
mutex_lock
|
||||||
[...]
|
[...]
|
||||||
|
|
||||||
If I'm only interested in sys_nanosleep and hrtimer_interrupt:
|
If I am only interested in sys_nanosleep and hrtimer_interrupt:
|
||||||
|
|
||||||
# echo sys_nanosleep hrtimer_interrupt \
|
# echo sys_nanosleep hrtimer_interrupt \
|
||||||
> /debug/tracing/set_ftrace_filter
|
> /debug/tracing/set_ftrace_filter
|
||||||
|
@ -1125,21 +1131,21 @@ If I'm only interested in sys_nanosleep and hrtimer_interrupt:
|
||||||
usleep-4134 [00] 1317.070111: sys_nanosleep <-syscall_call
|
usleep-4134 [00] 1317.070111: sys_nanosleep <-syscall_call
|
||||||
<idle>-0 [00] 1317.070115: hrtimer_interrupt <-smp_apic_timer_interrupt
|
<idle>-0 [00] 1317.070115: hrtimer_interrupt <-smp_apic_timer_interrupt
|
||||||
|
|
||||||
To see what functions are being traced, you can cat the file:
|
To see which functions are being traced, you can cat the file:
|
||||||
|
|
||||||
# cat /debug/tracing/set_ftrace_filter
|
# cat /debug/tracing/set_ftrace_filter
|
||||||
hrtimer_interrupt
|
hrtimer_interrupt
|
||||||
sys_nanosleep
|
sys_nanosleep
|
||||||
|
|
||||||
|
|
||||||
Perhaps this isn't enough. The filters also allow simple wild cards.
|
Perhaps this is not enough. The filters also allow simple wild cards.
|
||||||
Only the following is currently available
|
Only the following are currently available
|
||||||
|
|
||||||
<match>* - will match functions that begins with <match>
|
<match>* - will match functions that begin with <match>
|
||||||
*<match> - will match functions that end with <match>
|
*<match> - will match functions that end with <match>
|
||||||
*<match>* - will match functions that have <match> in it
|
*<match>* - will match functions that have <match> in it
|
||||||
|
|
||||||
Thats all the wild cards that are allowed.
|
These are the only wild cards which are supported.
|
||||||
|
|
||||||
<match>*<match> will not work.
|
<match>*<match> will not work.
|
||||||
|
|
||||||
|
@ -1187,7 +1193,7 @@ This is because the '>' and '>>' act just like they do in bash.
|
||||||
To rewrite the filters, use '>'
|
To rewrite the filters, use '>'
|
||||||
To append to the filters, use '>>'
|
To append to the filters, use '>>'
|
||||||
|
|
||||||
To clear out a filter so that all functions will be recorded again.
|
To clear out a filter so that all functions will be recorded again:
|
||||||
|
|
||||||
# echo > /debug/tracing/set_ftrace_filter
|
# echo > /debug/tracing/set_ftrace_filter
|
||||||
# cat /debug/tracing/set_ftrace_filter
|
# cat /debug/tracing/set_ftrace_filter
|
||||||
|
@ -1246,24 +1252,24 @@ ftraced
|
||||||
|
|
||||||
As mentioned above, when dynamic ftrace is configured in, a kernel
|
As mentioned above, when dynamic ftrace is configured in, a kernel
|
||||||
thread wakes up once a second and checks to see if there are mcount
|
thread wakes up once a second and checks to see if there are mcount
|
||||||
calls that need to be converted into nops. If there is not, then
|
calls that need to be converted into nops. If there are not any, then
|
||||||
it simply goes back to sleep. But if there is, it will call
|
it simply goes back to sleep. But if there are some, it will call
|
||||||
kstop_machine to convert the calls to nops.
|
kstop_machine to convert the calls to nops.
|
||||||
|
|
||||||
There may be a case that you do not want this added latency.
|
There may be a case in which you do not want this added latency.
|
||||||
Perhaps you are doing some audio recording and this activity might
|
Perhaps you are doing some audio recording and this activity might
|
||||||
cause skips in the playback. There is an interface to disable
|
cause skips in the playback. There is an interface to disable
|
||||||
and enable the ftraced kernel thread.
|
and enable the "ftraced" kernel thread.
|
||||||
|
|
||||||
# echo 0 > /debug/tracing/ftraced_enabled
|
# echo 0 > /debug/tracing/ftraced_enabled
|
||||||
|
|
||||||
This will disable the calling of the kstop_machine to update the
|
This will disable the calling of kstop_machine to update the
|
||||||
mcount calls to nops. Remember that there's a large overhead
|
mcount calls to nops. Remember that there is a large overhead
|
||||||
to calling mcount. Without this kernel thread, that overhead will
|
to calling mcount. Without this kernel thread, that overhead will
|
||||||
exist.
|
exist.
|
||||||
|
|
||||||
Any write to the ftraced_enabled file will cause the kstop_machine
|
If there are recorded calls to mcount, any write to the ftraced_enabled
|
||||||
to run if there are recorded calls to mcount. This means that a
|
file will cause the kstop_machine to run. This means that a
|
||||||
user can manually perform the updates when they want to by simply
|
user can manually perform the updates when they want to by simply
|
||||||
echoing a '0' into the ftraced_enabled file.
|
echoing a '0' into the ftraced_enabled file.
|
||||||
|
|
||||||
|
@ -1274,8 +1280,8 @@ that uses ftrace function recording.
|
||||||
trace_pipe
|
trace_pipe
|
||||||
----------
|
----------
|
||||||
|
|
||||||
The trace_pipe outputs the same as trace, but the effect on the
|
The trace_pipe outputs the same content as the trace file, but the effect
|
||||||
tracing is different. Every read from trace_pipe is consumed.
|
on the tracing is different. Every read from trace_pipe is consumed.
|
||||||
This means that subsequent reads will be different. The trace
|
This means that subsequent reads will be different. The trace
|
||||||
is live.
|
is live.
|
||||||
|
|
||||||
|
@ -1305,7 +1311,7 @@ is live.
|
||||||
bash-4043 [00] 41.267111: select_task_rq_rt <-try_to_wake_up
|
bash-4043 [00] 41.267111: select_task_rq_rt <-try_to_wake_up
|
||||||
|
|
||||||
|
|
||||||
Note, reading the trace_pipe will block until more input is added.
|
Note, reading the trace_pipe file will block until more input is added.
|
||||||
By changing the tracer, trace_pipe will issue an EOF. We needed
|
By changing the tracer, trace_pipe will issue an EOF. We needed
|
||||||
to set the ftrace tracer _before_ cating the trace_pipe file.
|
to set the ftrace tracer _before_ cating the trace_pipe file.
|
||||||
|
|
||||||
|
@ -1314,8 +1320,8 @@ trace entries
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
Having too much or not enough data can be troublesome in diagnosing
|
Having too much or not enough data can be troublesome in diagnosing
|
||||||
some issue in the kernel. The file trace_entries is used to modify
|
an issue in the kernel. The file trace_entries is used to modify
|
||||||
the size of the internal trace buffers. The numbers listed
|
the size of the internal trace buffers. The number listed
|
||||||
is the number of entries that can be recorded per CPU. To know
|
is the number of entries that can be recorded per CPU. To know
|
||||||
the full size, multiply the number of possible CPUS with the
|
the full size, multiply the number of possible CPUS with the
|
||||||
number of entries.
|
number of entries.
|
||||||
|
@ -1323,8 +1329,9 @@ number of entries.
|
||||||
# cat /debug/tracing/trace_entries
|
# cat /debug/tracing/trace_entries
|
||||||
65620
|
65620
|
||||||
|
|
||||||
Note, to modify this you must have tracing fulling disabled. To do that,
|
Note, to modify this, you must have tracing completely disabled. To do that,
|
||||||
echo "none" into the current_tracer.
|
echo "none" into the current_tracer. If the current_tracer is not set
|
||||||
|
to "none", an EINVAL error will be returned.
|
||||||
|
|
||||||
# echo none > /debug/tracing/current_tracer
|
# echo none > /debug/tracing/current_tracer
|
||||||
# echo 100000 > /debug/tracing/trace_entries
|
# echo 100000 > /debug/tracing/trace_entries
|
||||||
|
@ -1333,18 +1340,18 @@ echo "none" into the current_tracer.
|
||||||
|
|
||||||
|
|
||||||
Notice that we echoed in 100,000 but the size is 100,045. The entries
|
Notice that we echoed in 100,000 but the size is 100,045. The entries
|
||||||
are held by individual pages. It allocates the number of pages it takes
|
are held in individual pages. It allocates the number of pages it takes
|
||||||
to fulfill the request. If more entries may fit on the last page
|
to fulfill the request. If more entries may fit on the last page
|
||||||
it will add them.
|
then they will be added.
|
||||||
|
|
||||||
# echo 1 > /debug/tracing/trace_entries
|
# echo 1 > /debug/tracing/trace_entries
|
||||||
# cat /debug/tracing/trace_entries
|
# cat /debug/tracing/trace_entries
|
||||||
85
|
85
|
||||||
|
|
||||||
This shows us that 85 entries can fit on a single page.
|
This shows us that 85 entries can fit in a single page.
|
||||||
|
|
||||||
The number of pages that will be allocated is a percentage of available
|
The number of pages which will be allocated is limited to a percentage
|
||||||
memory. Allocating too much will produces an error.
|
of available memory. Allocating too much will produce an error.
|
||||||
|
|
||||||
# echo 1000000000000 > /debug/tracing/trace_entries
|
# echo 1000000000000 > /debug/tracing/trace_entries
|
||||||
-bash: echo: write error: Cannot allocate memory
|
-bash: echo: write error: Cannot allocate memory
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
Kernel driver i2c-i810
|
|
||||||
|
|
||||||
Supported adapters:
|
|
||||||
* Intel 82810, 82810-DC100, 82810E, and 82815 (GMCH)
|
|
||||||
* Intel 82845G (GMCH)
|
|
||||||
|
|
||||||
Authors:
|
|
||||||
Frodo Looijaard <frodol@dds.nl>,
|
|
||||||
Philip Edelbrock <phil@netroedge.com>,
|
|
||||||
Kyösti Mälkki <kmalkki@cc.hut.fi>,
|
|
||||||
Ralph Metzler <rjkm@thp.uni-koeln.de>,
|
|
||||||
Mark D. Studebaker <mdsxyz123@yahoo.com>
|
|
||||||
|
|
||||||
Main contact: Mark Studebaker <mdsxyz123@yahoo.com>
|
|
||||||
|
|
||||||
Description
|
|
||||||
-----------
|
|
||||||
|
|
||||||
WARNING: If you have an '810' or '815' motherboard, your standard I2C
|
|
||||||
temperature sensors are most likely on the 801's I2C bus. You want the
|
|
||||||
i2c-i801 driver for those, not this driver.
|
|
||||||
|
|
||||||
Now for the i2c-i810...
|
|
||||||
|
|
||||||
The GMCH chip contains two I2C interfaces.
|
|
||||||
|
|
||||||
The first interface is used for DDC (Data Display Channel) which is a
|
|
||||||
serial channel through the VGA monitor connector to a DDC-compliant
|
|
||||||
monitor. This interface is defined by the Video Electronics Standards
|
|
||||||
Association (VESA). The standards are available for purchase at
|
|
||||||
http://www.vesa.org .
|
|
||||||
|
|
||||||
The second interface is a general-purpose I2C bus. It may be connected to a
|
|
||||||
TV-out chip such as the BT869 or possibly to a digital flat-panel display.
|
|
||||||
|
|
||||||
Features
|
|
||||||
--------
|
|
||||||
|
|
||||||
Both busses use the i2c-algo-bit driver for 'bit banging'
|
|
||||||
and support for specific transactions is provided by i2c-algo-bit.
|
|
||||||
|
|
||||||
Issues
|
|
||||||
------
|
|
||||||
|
|
||||||
If you enable bus testing in i2c-algo-bit (insmod i2c-algo-bit bit_test=1),
|
|
||||||
the test may fail; if so, the i2c-i810 driver won't be inserted. However,
|
|
||||||
we think this has been fixed.
|
|
|
@ -1,23 +0,0 @@
|
||||||
Kernel driver i2c-prosavage
|
|
||||||
|
|
||||||
Supported adapters:
|
|
||||||
|
|
||||||
S3/VIA KM266/VT8375 aka ProSavage8
|
|
||||||
S3/VIA KM133/VT8365 aka Savage4
|
|
||||||
|
|
||||||
Author: Henk Vergonet <henk@god.dyndns.org>
|
|
||||||
|
|
||||||
Description
|
|
||||||
-----------
|
|
||||||
|
|
||||||
The Savage4 chips contain two I2C interfaces (aka a I2C 'master' or
|
|
||||||
'host').
|
|
||||||
|
|
||||||
The first interface is used for DDC (Data Display Channel) which is a
|
|
||||||
serial channel through the VGA monitor connector to a DDC-compliant
|
|
||||||
monitor. This interface is defined by the Video Electronics Standards
|
|
||||||
Association (VESA). The standards are available for purchase at
|
|
||||||
http://www.vesa.org . The second interface is a general-purpose I2C bus.
|
|
||||||
|
|
||||||
Usefull for gaining access to the TV Encoder chips.
|
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
Kernel driver i2c-savage4
|
|
||||||
|
|
||||||
Supported adapters:
|
|
||||||
* Savage4
|
|
||||||
* Savage2000
|
|
||||||
|
|
||||||
Authors:
|
|
||||||
Alexander Wold <awold@bigfoot.com>,
|
|
||||||
Mark D. Studebaker <mdsxyz123@yahoo.com>
|
|
||||||
|
|
||||||
Description
|
|
||||||
-----------
|
|
||||||
|
|
||||||
The Savage4 chips contain two I2C interfaces (aka a I2C 'master'
|
|
||||||
or 'host').
|
|
||||||
|
|
||||||
The first interface is used for DDC (Data Display Channel) which is a
|
|
||||||
serial channel through the VGA monitor connector to a DDC-compliant
|
|
||||||
monitor. This interface is defined by the Video Electronics Standards
|
|
||||||
Association (VESA). The standards are available for purchase at
|
|
||||||
http://www.vesa.org . The DDC bus is not yet supported because its register
|
|
||||||
is not directly memory-mapped.
|
|
||||||
|
|
||||||
The second interface is a general-purpose I2C bus. This is the only
|
|
||||||
interface supported by the driver at the moment.
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ $ modprobe max6875 force=0,0x50
|
||||||
|
|
||||||
The MAX6874/MAX6875 ignores address bit 0, so this driver attaches to multiple
|
The MAX6874/MAX6875 ignores address bit 0, so this driver attaches to multiple
|
||||||
addresses. For example, for address 0x50, it also reserves 0x51.
|
addresses. For example, for address 0x50, it also reserves 0x51.
|
||||||
The even-address instance is called 'max6875', the odd one is 'max6875 subclient'.
|
The even-address instance is called 'max6875', the odd one is 'dummy'.
|
||||||
|
|
||||||
|
|
||||||
Programming the chip using i2c-dev
|
Programming the chip using i2c-dev
|
||||||
|
|
|
@ -7,7 +7,7 @@ drivers/gpio/pca9539.c instead.
|
||||||
Supported chips:
|
Supported chips:
|
||||||
* Philips PCA9539
|
* Philips PCA9539
|
||||||
Prefix: 'pca9539'
|
Prefix: 'pca9539'
|
||||||
Addresses scanned: 0x74 - 0x77
|
Addresses scanned: none
|
||||||
Datasheet:
|
Datasheet:
|
||||||
http://www.semiconductors.philips.com/acrobat/datasheets/PCA9539_2.pdf
|
http://www.semiconductors.philips.com/acrobat/datasheets/PCA9539_2.pdf
|
||||||
|
|
||||||
|
@ -23,6 +23,14 @@ The input sense can also be inverted.
|
||||||
The 16 lines are split between two bytes.
|
The 16 lines are split between two bytes.
|
||||||
|
|
||||||
|
|
||||||
|
Detection
|
||||||
|
---------
|
||||||
|
|
||||||
|
The PCA9539 is difficult to detect and not commonly found in PC machines,
|
||||||
|
so you have to pass the I2C bus and address of the installed PCA9539
|
||||||
|
devices explicitly to the driver at load time via the force=... parameter.
|
||||||
|
|
||||||
|
|
||||||
Sysfs entries
|
Sysfs entries
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,13 @@ Kernel driver pcf8574
|
||||||
Supported chips:
|
Supported chips:
|
||||||
* Philips PCF8574
|
* Philips PCF8574
|
||||||
Prefix: 'pcf8574'
|
Prefix: 'pcf8574'
|
||||||
Addresses scanned: I2C 0x20 - 0x27
|
Addresses scanned: none
|
||||||
Datasheet: Publicly available at the Philips Semiconductors website
|
Datasheet: Publicly available at the Philips Semiconductors website
|
||||||
http://www.semiconductors.philips.com/pip/PCF8574P.html
|
http://www.semiconductors.philips.com/pip/PCF8574P.html
|
||||||
|
|
||||||
* Philips PCF8574A
|
* Philips PCF8574A
|
||||||
Prefix: 'pcf8574a'
|
Prefix: 'pcf8574a'
|
||||||
Addresses scanned: I2C 0x38 - 0x3f
|
Addresses scanned: none
|
||||||
Datasheet: Publicly available at the Philips Semiconductors website
|
Datasheet: Publicly available at the Philips Semiconductors website
|
||||||
http://www.semiconductors.philips.com/pip/PCF8574P.html
|
http://www.semiconductors.philips.com/pip/PCF8574P.html
|
||||||
|
|
||||||
|
@ -38,12 +38,10 @@ For more informations see the datasheet.
|
||||||
Accessing PCF8574(A) via /sys interface
|
Accessing PCF8574(A) via /sys interface
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
|
||||||
! Be careful !
|
|
||||||
The PCF8574(A) is plainly impossible to detect ! Stupid chip.
|
The PCF8574(A) is plainly impossible to detect ! Stupid chip.
|
||||||
So every chip with address in the interval [20..27] and [38..3f] are
|
So, you have to pass the I2C bus and address of the installed PCF857A
|
||||||
detected as PCF8574(A). If you have other chips in this address
|
and PCF8574A devices explicitly to the driver at load time via the
|
||||||
range, the workaround is to load this module after the one
|
force=... parameter.
|
||||||
for your others chips.
|
|
||||||
|
|
||||||
On detection (i.e. insmod, modprobe et al.), directories are being
|
On detection (i.e. insmod, modprobe et al.), directories are being
|
||||||
created for each detected PCF8574(A):
|
created for each detected PCF8574(A):
|
||||||
|
|
|
@ -40,12 +40,9 @@ Detection
|
||||||
---------
|
---------
|
||||||
|
|
||||||
There is no method known to detect whether a chip on a given I2C address is
|
There is no method known to detect whether a chip on a given I2C address is
|
||||||
a PCF8575 or whether it is any other I2C device. So there are two alternatives
|
a PCF8575 or whether it is any other I2C device, so you have to pass the I2C
|
||||||
to let the driver find the installed PCF8575 devices:
|
bus and address of the installed PCF8575 devices explicitly to the driver at
|
||||||
- Load this driver after any other I2C driver for I2C devices with addresses
|
load time via the force=... parameter.
|
||||||
in the range 0x20 .. 0x27.
|
|
||||||
- Pass the I2C bus and address of the installed PCF8575 devices explicitly to
|
|
||||||
the driver at load time via the probe=... or force=... parameters.
|
|
||||||
|
|
||||||
/sys interface
|
/sys interface
|
||||||
--------------
|
--------------
|
||||||
|
|
|
@ -0,0 +1,127 @@
|
||||||
|
This is a summary of the most important conventions for use of fault
|
||||||
|
codes in the I2C/SMBus stack.
|
||||||
|
|
||||||
|
|
||||||
|
A "Fault" is not always an "Error"
|
||||||
|
----------------------------------
|
||||||
|
Not all fault reports imply errors; "page faults" should be a familiar
|
||||||
|
example. Software often retries idempotent operations after transient
|
||||||
|
faults. There may be fancier recovery schemes that are appropriate in
|
||||||
|
some cases, such as re-initializing (and maybe resetting). After such
|
||||||
|
recovery, triggered by a fault report, there is no error.
|
||||||
|
|
||||||
|
In a similar way, sometimes a "fault" code just reports one defined
|
||||||
|
result for an operation ... it doesn't indicate that anything is wrong
|
||||||
|
at all, just that the outcome wasn't on the "golden path".
|
||||||
|
|
||||||
|
In short, your I2C driver code may need to know these codes in order
|
||||||
|
to respond correctly. Other code may need to rely on YOUR code reporting
|
||||||
|
the right fault code, so that it can (in turn) behave correctly.
|
||||||
|
|
||||||
|
|
||||||
|
I2C and SMBus fault codes
|
||||||
|
-------------------------
|
||||||
|
These are returned as negative numbers from most calls, with zero or
|
||||||
|
some positive number indicating a non-fault return. The specific
|
||||||
|
numbers associated with these symbols differ between architectures,
|
||||||
|
though most Linux systems use <asm-generic/errno*.h> numbering.
|
||||||
|
|
||||||
|
Note that the descriptions here are not exhaustive. There are other
|
||||||
|
codes that may be returned, and other cases where these codes should
|
||||||
|
be returned. However, drivers should not return other codes for these
|
||||||
|
cases (unless the hardware doesn't provide unique fault reports).
|
||||||
|
|
||||||
|
Also, codes returned by adapter probe methods follow rules which are
|
||||||
|
specific to their host bus (such as PCI, or the platform bus).
|
||||||
|
|
||||||
|
|
||||||
|
EAGAIN
|
||||||
|
Returned by I2C adapters when they lose arbitration in master
|
||||||
|
transmit mode: some other master was transmitting different
|
||||||
|
data at the same time.
|
||||||
|
|
||||||
|
Also returned when trying to invoke an I2C operation in an
|
||||||
|
atomic context, when some task is already using that I2C bus
|
||||||
|
to execute some other operation.
|
||||||
|
|
||||||
|
EBADMSG
|
||||||
|
Returned by SMBus logic when an invalid Packet Error Code byte
|
||||||
|
is received. This code is a CRC covering all bytes in the
|
||||||
|
transaction, and is sent before the terminating STOP. This
|
||||||
|
fault is only reported on read transactions; the SMBus slave
|
||||||
|
may have a way to report PEC mismatches on writes from the
|
||||||
|
host. Note that even if PECs are in use, you should not rely
|
||||||
|
on these as the only way to detect incorrect data transfers.
|
||||||
|
|
||||||
|
EBUSY
|
||||||
|
Returned by SMBus adapters when the bus was busy for longer
|
||||||
|
than allowed. This usually indicates some device (maybe the
|
||||||
|
SMBus adapter) needs some fault recovery (such as resetting),
|
||||||
|
or that the reset was attempted but failed.
|
||||||
|
|
||||||
|
EINVAL
|
||||||
|
This rather vague error means an invalid parameter has been
|
||||||
|
detected before any I/O operation was started. Use a more
|
||||||
|
specific fault code when you can.
|
||||||
|
|
||||||
|
One example would be a driver trying an SMBus Block Write
|
||||||
|
with block size outside the range of 1-32 bytes.
|
||||||
|
|
||||||
|
EIO
|
||||||
|
This rather vague error means something went wrong when
|
||||||
|
performing an I/O operation. Use a more specific fault
|
||||||
|
code when you can.
|
||||||
|
|
||||||
|
ENODEV
|
||||||
|
Returned by driver probe() methods. This is a bit more
|
||||||
|
specific than ENXIO, implying the problem isn't with the
|
||||||
|
address, but with the device found there. Driver probes
|
||||||
|
may verify the device returns *correct* responses, and
|
||||||
|
return this as appropriate. (The driver core will warn
|
||||||
|
about probe faults other than ENXIO and ENODEV.)
|
||||||
|
|
||||||
|
ENOMEM
|
||||||
|
Returned by any component that can't allocate memory when
|
||||||
|
it needs to do so.
|
||||||
|
|
||||||
|
ENXIO
|
||||||
|
Returned by I2C adapters to indicate that the address phase
|
||||||
|
of a transfer didn't get an ACK. While it might just mean
|
||||||
|
an I2C device was temporarily not responding, usually it
|
||||||
|
means there's nothing listening at that address.
|
||||||
|
|
||||||
|
Returned by driver probe() methods to indicate that they
|
||||||
|
found no device to bind to. (ENODEV may also be used.)
|
||||||
|
|
||||||
|
EOPNOTSUPP
|
||||||
|
Returned by an adapter when asked to perform an operation
|
||||||
|
that it doesn't, or can't, support.
|
||||||
|
|
||||||
|
For example, this would be returned when an adapter that
|
||||||
|
doesn't support SMBus block transfers is asked to execute
|
||||||
|
one. In that case, the driver making that request should
|
||||||
|
have verified that functionality was supported before it
|
||||||
|
made that block transfer request.
|
||||||
|
|
||||||
|
Similarly, if an I2C adapter can't execute all legal I2C
|
||||||
|
messages, it should return this when asked to perform a
|
||||||
|
transaction it can't. (These limitations can't be seen in
|
||||||
|
the adapter's functionality mask, since the assumption is
|
||||||
|
that if an adapter supports I2C it supports all of I2C.)
|
||||||
|
|
||||||
|
EPROTO
|
||||||
|
Returned when slave does not conform to the relevant I2C
|
||||||
|
or SMBus (or chip-specific) protocol specifications. One
|
||||||
|
case is when the length of an SMBus block data response
|
||||||
|
(from the SMBus slave) is outside the range 1-32 bytes.
|
||||||
|
|
||||||
|
ETIMEDOUT
|
||||||
|
This is returned by drivers when an operation took too much
|
||||||
|
time, and was aborted before it completed.
|
||||||
|
|
||||||
|
SMBus adapters may return it when an operation took more
|
||||||
|
time than allowed by the SMBus specification; for example,
|
||||||
|
when a slave stretches clocks too far. I2C has no such
|
||||||
|
timeouts, but it's normal for I2C adapters to impose some
|
||||||
|
arbitrary limits (much longer than SMBus!) too.
|
||||||
|
|
|
@ -42,8 +42,8 @@ Count (8 bits): A data byte containing the length of a block operation.
|
||||||
[..]: Data sent by I2C device, as opposed to data sent by the host adapter.
|
[..]: Data sent by I2C device, as opposed to data sent by the host adapter.
|
||||||
|
|
||||||
|
|
||||||
SMBus Quick Command: i2c_smbus_write_quick()
|
SMBus Quick Command
|
||||||
=============================================
|
===================
|
||||||
|
|
||||||
This sends a single bit to the device, at the place of the Rd/Wr bit.
|
This sends a single bit to the device, at the place of the Rd/Wr bit.
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,10 @@ static struct i2c_driver foo_driver = {
|
||||||
.id_table = foo_ids,
|
.id_table = foo_ids,
|
||||||
.probe = foo_probe,
|
.probe = foo_probe,
|
||||||
.remove = foo_remove,
|
.remove = foo_remove,
|
||||||
|
/* if device autodetection is needed: */
|
||||||
|
.class = I2C_CLASS_SOMETHING,
|
||||||
|
.detect = foo_detect,
|
||||||
|
.address_data = &addr_data,
|
||||||
|
|
||||||
/* else, driver uses "legacy" binding model: */
|
/* else, driver uses "legacy" binding model: */
|
||||||
.attach_adapter = foo_attach_adapter,
|
.attach_adapter = foo_attach_adapter,
|
||||||
|
@ -217,6 +221,31 @@ in the I2C bus driver. You may want to save the returned i2c_client
|
||||||
reference for later use.
|
reference for later use.
|
||||||
|
|
||||||
|
|
||||||
|
Device Detection (Standard driver model)
|
||||||
|
----------------------------------------
|
||||||
|
|
||||||
|
Sometimes you do not know in advance which I2C devices are connected to
|
||||||
|
a given I2C bus. This is for example the case of hardware monitoring
|
||||||
|
devices on a PC's SMBus. In that case, you may want to let your driver
|
||||||
|
detect supported devices automatically. This is how the legacy model
|
||||||
|
was working, and is now available as an extension to the standard
|
||||||
|
driver model (so that we can finally get rid of the legacy model.)
|
||||||
|
|
||||||
|
You simply have to define a detect callback which will attempt to
|
||||||
|
identify supported devices (returning 0 for supported ones and -ENODEV
|
||||||
|
for unsupported ones), a list of addresses to probe, and a device type
|
||||||
|
(or class) so that only I2C buses which may have that type of device
|
||||||
|
connected (and not otherwise enumerated) will be probed. The i2c
|
||||||
|
core will then call you back as needed and will instantiate a device
|
||||||
|
for you for every successful detection.
|
||||||
|
|
||||||
|
Note that this mechanism is purely optional and not suitable for all
|
||||||
|
devices. You need some reliable way to identify the supported devices
|
||||||
|
(typically using device-specific, dedicated identification registers),
|
||||||
|
otherwise misdetections are likely to occur and things can get wrong
|
||||||
|
quickly.
|
||||||
|
|
||||||
|
|
||||||
Device Deletion (Standard driver model)
|
Device Deletion (Standard driver model)
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
|
|
||||||
|
@ -569,7 +598,6 @@ SMBus communication
|
||||||
in terms of it. Never use this function directly!
|
in terms of it. Never use this function directly!
|
||||||
|
|
||||||
|
|
||||||
extern s32 i2c_smbus_write_quick(struct i2c_client * client, u8 value);
|
|
||||||
extern s32 i2c_smbus_read_byte(struct i2c_client * client);
|
extern s32 i2c_smbus_read_byte(struct i2c_client * client);
|
||||||
extern s32 i2c_smbus_write_byte(struct i2c_client * client, u8 value);
|
extern s32 i2c_smbus_write_byte(struct i2c_client * client, u8 value);
|
||||||
extern s32 i2c_smbus_read_byte_data(struct i2c_client * client, u8 command);
|
extern s32 i2c_smbus_read_byte_data(struct i2c_client * client, u8 command);
|
||||||
|
@ -578,30 +606,31 @@ SMBus communication
|
||||||
extern s32 i2c_smbus_read_word_data(struct i2c_client * client, u8 command);
|
extern s32 i2c_smbus_read_word_data(struct i2c_client * client, u8 command);
|
||||||
extern s32 i2c_smbus_write_word_data(struct i2c_client * client,
|
extern s32 i2c_smbus_write_word_data(struct i2c_client * client,
|
||||||
u8 command, u16 value);
|
u8 command, u16 value);
|
||||||
|
extern s32 i2c_smbus_read_block_data(struct i2c_client * client,
|
||||||
|
u8 command, u8 *values);
|
||||||
extern s32 i2c_smbus_write_block_data(struct i2c_client * client,
|
extern s32 i2c_smbus_write_block_data(struct i2c_client * client,
|
||||||
u8 command, u8 length,
|
u8 command, u8 length,
|
||||||
u8 *values);
|
u8 *values);
|
||||||
extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client,
|
extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client,
|
||||||
u8 command, u8 length, u8 *values);
|
u8 command, u8 length, u8 *values);
|
||||||
|
|
||||||
These ones were removed in Linux 2.6.10 because they had no users, but could
|
|
||||||
be added back later if needed:
|
|
||||||
|
|
||||||
extern s32 i2c_smbus_read_block_data(struct i2c_client * client,
|
|
||||||
u8 command, u8 *values);
|
|
||||||
extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client,
|
extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client,
|
||||||
u8 command, u8 length,
|
u8 command, u8 length,
|
||||||
u8 *values);
|
u8 *values);
|
||||||
|
|
||||||
|
These ones were removed from i2c-core because they had no users, but could
|
||||||
|
be added back later if needed:
|
||||||
|
|
||||||
|
extern s32 i2c_smbus_write_quick(struct i2c_client * client, u8 value);
|
||||||
extern s32 i2c_smbus_process_call(struct i2c_client * client,
|
extern s32 i2c_smbus_process_call(struct i2c_client * client,
|
||||||
u8 command, u16 value);
|
u8 command, u16 value);
|
||||||
extern s32 i2c_smbus_block_process_call(struct i2c_client *client,
|
extern s32 i2c_smbus_block_process_call(struct i2c_client *client,
|
||||||
u8 command, u8 length,
|
u8 command, u8 length,
|
||||||
u8 *values)
|
u8 *values)
|
||||||
|
|
||||||
All these transactions return -1 on failure. The 'write' transactions
|
All these transactions return a negative errno value on failure. The 'write'
|
||||||
return 0 on success; the 'read' transactions return the read value, except
|
transactions return 0 on success; the 'read' transactions return the read
|
||||||
for read_block, which returns the number of values read. The block buffers
|
value, except for block transactions, which return the number of values
|
||||||
need not be longer than 32 bytes.
|
read. The block buffers need not be longer than 32 bytes.
|
||||||
|
|
||||||
You can read the file `smbus-protocol' for more information about the
|
You can read the file `smbus-protocol' for more information about the
|
||||||
actual SMBus protocol.
|
actual SMBus protocol.
|
||||||
|
|
|
@ -117,6 +117,7 @@ Code Seq# Include File Comments
|
||||||
<mailto:natalia@nikhefk.nikhef.nl>
|
<mailto:natalia@nikhefk.nikhef.nl>
|
||||||
'c' 00-7F linux/comstats.h conflict!
|
'c' 00-7F linux/comstats.h conflict!
|
||||||
'c' 00-7F linux/coda.h conflict!
|
'c' 00-7F linux/coda.h conflict!
|
||||||
|
'c' 80-9F asm-s390/chsc.h
|
||||||
'd' 00-FF linux/char/drm/drm/h conflict!
|
'd' 00-FF linux/char/drm/drm/h conflict!
|
||||||
'd' 00-DF linux/video_decoder.h conflict!
|
'd' 00-DF linux/video_decoder.h conflict!
|
||||||
'd' F0-FF linux/digi1.h
|
'd' F0-FF linux/digi1.h
|
||||||
|
|
|
@ -508,12 +508,13 @@ HDIO_DRIVE_RESET execute a device reset
|
||||||
|
|
||||||
error returns:
|
error returns:
|
||||||
EACCES Access denied: requires CAP_SYS_ADMIN
|
EACCES Access denied: requires CAP_SYS_ADMIN
|
||||||
|
ENXIO No such device: phy dead or ctl_addr == 0
|
||||||
|
EIO I/O error: reset timed out or hardware error
|
||||||
|
|
||||||
notes:
|
notes:
|
||||||
|
|
||||||
Abort any current command, prevent anything else from being
|
Execute a reset on the device as soon as the current IO
|
||||||
queued, execute a reset on the device, and issue BLKRRPART
|
operation has completed.
|
||||||
ioctl on the block device.
|
|
||||||
|
|
||||||
Executes an ATAPI soft reset if applicable, otherwise
|
Executes an ATAPI soft reset if applicable, otherwise
|
||||||
executes an ATA soft reset on the controller.
|
executes an ATA soft reset on the controller.
|
||||||
|
|
|
@ -147,10 +147,14 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||||
default: 0
|
default: 0
|
||||||
|
|
||||||
acpi_sleep= [HW,ACPI] Sleep options
|
acpi_sleep= [HW,ACPI] Sleep options
|
||||||
Format: { s3_bios, s3_mode, s3_beep }
|
Format: { s3_bios, s3_mode, s3_beep, old_ordering }
|
||||||
See Documentation/power/video.txt for s3_bios and s3_mode.
|
See Documentation/power/video.txt for s3_bios and s3_mode.
|
||||||
s3_beep is for debugging; it makes the PC's speaker beep
|
s3_beep is for debugging; it makes the PC's speaker beep
|
||||||
as soon as the kernel's real-mode entry point is called.
|
as soon as the kernel's real-mode entry point is called.
|
||||||
|
old_ordering causes the ACPI 1.0 ordering of the _PTS
|
||||||
|
control method, wrt putting devices into low power
|
||||||
|
states, to be enforced (the ACPI 2.0 ordering of _PTS is
|
||||||
|
used by default).
|
||||||
|
|
||||||
acpi_sci= [HW,ACPI] ACPI System Control Interrupt trigger mode
|
acpi_sci= [HW,ACPI] ACPI System Control Interrupt trigger mode
|
||||||
Format: { level | edge | high | low }
|
Format: { level | edge | high | low }
|
||||||
|
@ -571,6 +575,8 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||||
|
|
||||||
debug_objects [KNL] Enable object debugging
|
debug_objects [KNL] Enable object debugging
|
||||||
|
|
||||||
|
debugpat [X86] Enable PAT debugging
|
||||||
|
|
||||||
decnet.addr= [HW,NET]
|
decnet.addr= [HW,NET]
|
||||||
Format: <area>[,<node>]
|
Format: <area>[,<node>]
|
||||||
See also Documentation/networking/decnet.txt.
|
See also Documentation/networking/decnet.txt.
|
||||||
|
@ -756,9 +762,6 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||||
hd= [EIDE] (E)IDE hard drive subsystem geometry
|
hd= [EIDE] (E)IDE hard drive subsystem geometry
|
||||||
Format: <cyl>,<head>,<sect>
|
Format: <cyl>,<head>,<sect>
|
||||||
|
|
||||||
hd?= [HW] (E)IDE subsystem
|
|
||||||
hd?lun= See Documentation/ide/ide.txt.
|
|
||||||
|
|
||||||
highmem=nn[KMG] [KNL,BOOT] forces the highmem zone to have an exact
|
highmem=nn[KMG] [KNL,BOOT] forces the highmem zone to have an exact
|
||||||
size of <nn>. This works even on boxes that have no
|
size of <nn>. This works even on boxes that have no
|
||||||
highmem otherwise. This also works to reduce highmem
|
highmem otherwise. This also works to reduce highmem
|
||||||
|
@ -819,7 +822,7 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||||
See Documentation/ide/ide.txt.
|
See Documentation/ide/ide.txt.
|
||||||
|
|
||||||
idle= [X86]
|
idle= [X86]
|
||||||
Format: idle=poll or idle=mwait
|
Format: idle=poll or idle=mwait, idle=halt, idle=nomwait
|
||||||
Poll forces a polling idle loop that can slightly improves the performance
|
Poll forces a polling idle loop that can slightly improves the performance
|
||||||
of waking up a idle CPU, but will use a lot of power and make the system
|
of waking up a idle CPU, but will use a lot of power and make the system
|
||||||
run hot. Not recommended.
|
run hot. Not recommended.
|
||||||
|
@ -827,6 +830,9 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||||
to not use it because it doesn't save as much power as a normal idle
|
to not use it because it doesn't save as much power as a normal idle
|
||||||
loop use the MONITOR/MWAIT idle loop anyways. Performance should be the same
|
loop use the MONITOR/MWAIT idle loop anyways. Performance should be the same
|
||||||
as idle=poll.
|
as idle=poll.
|
||||||
|
idle=halt. Halt is forced to be used for CPU idle.
|
||||||
|
In such case C2/C3 won't be used again.
|
||||||
|
idle=nomwait. Disable mwait for CPU C-states
|
||||||
|
|
||||||
ide-pci-generic.all-generic-ide [HW] (E)IDE subsystem
|
ide-pci-generic.all-generic-ide [HW] (E)IDE subsystem
|
||||||
Claim all unknown PCI IDE storage controllers.
|
Claim all unknown PCI IDE storage controllers.
|
||||||
|
@ -1242,6 +1248,11 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||||
mtdparts= [MTD]
|
mtdparts= [MTD]
|
||||||
See drivers/mtd/cmdlinepart.c.
|
See drivers/mtd/cmdlinepart.c.
|
||||||
|
|
||||||
|
mtdset= [ARM]
|
||||||
|
ARM/S3C2412 JIVE boot control
|
||||||
|
|
||||||
|
See arch/arm/mach-s3c2412/mach-jive.c
|
||||||
|
|
||||||
mtouchusb.raw_coordinates=
|
mtouchusb.raw_coordinates=
|
||||||
[HW] Make the MicroTouch USB driver use raw coordinates
|
[HW] Make the MicroTouch USB driver use raw coordinates
|
||||||
('y', default) or cooked coordinates ('n')
|
('y', default) or cooked coordinates ('n')
|
||||||
|
@ -1536,6 +1547,9 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||||
Use with caution as certain devices share
|
Use with caution as certain devices share
|
||||||
address decoders between ROMs and other
|
address decoders between ROMs and other
|
||||||
resources.
|
resources.
|
||||||
|
norom [X86-32,X86_64] Do not assign address space to
|
||||||
|
expansion ROMs that do not already have
|
||||||
|
BIOS assigned address ranges.
|
||||||
irqmask=0xMMMM [X86-32] Set a bit mask of IRQs allowed to be
|
irqmask=0xMMMM [X86-32] Set a bit mask of IRQs allowed to be
|
||||||
assigned automatically to PCI devices. You can
|
assigned automatically to PCI devices. You can
|
||||||
make the kernel exclude IRQs of your ISA cards
|
make the kernel exclude IRQs of your ISA cards
|
||||||
|
@ -1611,6 +1625,10 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||||
Format: { parport<nr> | timid | 0 }
|
Format: { parport<nr> | timid | 0 }
|
||||||
See also Documentation/parport.txt.
|
See also Documentation/parport.txt.
|
||||||
|
|
||||||
|
pmtmr= [X86] Manual setup of pmtmr I/O Port.
|
||||||
|
Override pmtimer IOPort with a hex value.
|
||||||
|
e.g. pmtmr=0x508
|
||||||
|
|
||||||
pnpacpi= [ACPI]
|
pnpacpi= [ACPI]
|
||||||
{ off }
|
{ off }
|
||||||
|
|
||||||
|
|
|
@ -172,6 +172,7 @@ architectures:
|
||||||
- ia64 (Does not support probes on instruction slot1.)
|
- ia64 (Does not support probes on instruction slot1.)
|
||||||
- sparc64 (Return probes not yet implemented.)
|
- sparc64 (Return probes not yet implemented.)
|
||||||
- arm
|
- arm
|
||||||
|
- ppc
|
||||||
|
|
||||||
3. Configuring Kprobes
|
3. Configuring Kprobes
|
||||||
|
|
||||||
|
|
|
@ -174,8 +174,6 @@ The LED is exposed through the LED subsystem, and can be found in:
|
||||||
The mail LED is autodetected, so if you don't have one, the LED device won't
|
The mail LED is autodetected, so if you don't have one, the LED device won't
|
||||||
be registered.
|
be registered.
|
||||||
|
|
||||||
If you have a mail LED that is not green, please report this to me.
|
|
||||||
|
|
||||||
Backlight
|
Backlight
|
||||||
*********
|
*********
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,141 @@
|
||||||
|
The PowerPC boot wrapper
|
||||||
|
------------------------
|
||||||
|
Copyright (C) Secret Lab Technologies Ltd.
|
||||||
|
|
||||||
|
PowerPC image targets compresses and wraps the kernel image (vmlinux) with
|
||||||
|
a boot wrapper to make it usable by the system firmware. There is no
|
||||||
|
standard PowerPC firmware interface, so the boot wrapper is designed to
|
||||||
|
be adaptable for each kind of image that needs to be built.
|
||||||
|
|
||||||
|
The boot wrapper can be found in the arch/powerpc/boot/ directory. The
|
||||||
|
Makefile in that directory has targets for all the available image types.
|
||||||
|
The different image types are used to support all of the various firmware
|
||||||
|
interfaces found on PowerPC platforms. OpenFirmware is the most commonly
|
||||||
|
used firmware type on general purpose PowerPC systems from Apple, IBM and
|
||||||
|
others. U-Boot is typically found on embedded PowerPC hardware, but there
|
||||||
|
are a handful of other firmware implementations which are also popular. Each
|
||||||
|
firmware interface requires a different image format.
|
||||||
|
|
||||||
|
The boot wrapper is built from the makefile in arch/powerpc/boot/Makefile and
|
||||||
|
it uses the wrapper script (arch/powerpc/boot/wrapper) to generate target
|
||||||
|
image. The details of the build system is discussed in the next section.
|
||||||
|
Currently, the following image format targets exist:
|
||||||
|
|
||||||
|
cuImage.%: Backwards compatible uImage for older version of
|
||||||
|
U-Boot (for versions that don't understand the device
|
||||||
|
tree). This image embeds a device tree blob inside
|
||||||
|
the image. The boot wrapper, kernel and device tree
|
||||||
|
are all embedded inside the U-Boot uImage file format
|
||||||
|
with boot wrapper code that extracts data from the old
|
||||||
|
bd_info structure and loads the data into the device
|
||||||
|
tree before jumping into the kernel.
|
||||||
|
Because of the series of #ifdefs found in the
|
||||||
|
bd_info structure used in the old U-Boot interfaces,
|
||||||
|
cuImages are platform specific. Each specific
|
||||||
|
U-Boot platform has a different platform init file
|
||||||
|
which populates the embedded device tree with data
|
||||||
|
from the platform specific bd_info file. The platform
|
||||||
|
specific cuImage platform init code can be found in
|
||||||
|
arch/powerpc/boot/cuboot.*.c. Selection of the correct
|
||||||
|
cuImage init code for a specific board can be found in
|
||||||
|
the wrapper structure.
|
||||||
|
dtbImage.%: Similar to zImage, except device tree blob is embedded
|
||||||
|
inside the image instead of provided by firmware. The
|
||||||
|
output image file can be either an elf file or a flat
|
||||||
|
binary depending on the platform.
|
||||||
|
dtbImages are used on systems which do not have an
|
||||||
|
interface for passing a device tree directly.
|
||||||
|
dtbImages are similar to simpleImages except that
|
||||||
|
dtbImages have platform specific code for extracting
|
||||||
|
data from the board firmware, but simpleImages do not
|
||||||
|
talk to the firmware at all.
|
||||||
|
PlayStation 3 support uses dtbImage. So do Embedded
|
||||||
|
Planet boards using the PlanetCore firmware. Board
|
||||||
|
specific initialization code is typically found in a
|
||||||
|
file named arch/powerpc/boot/<platform>.c; but this
|
||||||
|
can be overridden by the wrapper script.
|
||||||
|
simpleImage.%: Firmware independent compressed image that does not
|
||||||
|
depend on any particular firmware interface and embeds
|
||||||
|
a device tree blob. This image is a flat binary that
|
||||||
|
can be loaded to any location in RAM and jumped to.
|
||||||
|
Firmware cannot pass any configuration data to the
|
||||||
|
kernel with this image type and it depends entirely on
|
||||||
|
the embedded device tree for all information.
|
||||||
|
The simpleImage is useful for booting systems with
|
||||||
|
an unknown firmware interface or for booting from
|
||||||
|
a debugger when no firmware is present (such as on
|
||||||
|
the Xilinx Virtex platform). The only assumption that
|
||||||
|
simpleImage makes is that RAM is correctly initialized
|
||||||
|
and that the MMU is either off or has RAM mapped to
|
||||||
|
base address 0.
|
||||||
|
simpleImage also supports inserting special platform
|
||||||
|
specific initialization code to the start of the bootup
|
||||||
|
sequence. The virtex405 platform uses this feature to
|
||||||
|
ensure that the cache is invalidated before caching
|
||||||
|
is enabled. Platform specific initialization code is
|
||||||
|
added as part of the wrapper script and is keyed on
|
||||||
|
the image target name. For example, all
|
||||||
|
simpleImage.virtex405-* targets will add the
|
||||||
|
virtex405-head.S initialization code (This also means
|
||||||
|
that the dts file for virtex405 targets should be
|
||||||
|
named (virtex405-<board>.dts). Search the wrapper
|
||||||
|
script for 'virtex405' and see the file
|
||||||
|
arch/powerpc/boot/virtex405-head.S for details.
|
||||||
|
treeImage.%; Image format for used with OpenBIOS firmware found
|
||||||
|
on some ppc4xx hardware. This image embeds a device
|
||||||
|
tree blob inside the image.
|
||||||
|
uImage: Native image format used by U-Boot. The uImage target
|
||||||
|
does not add any boot code. It just wraps a compressed
|
||||||
|
vmlinux in the uImage data structure. This image
|
||||||
|
requires a version of U-Boot that is able to pass
|
||||||
|
a device tree to the kernel at boot. If using an older
|
||||||
|
version of U-Boot, then you need to use a cuImage
|
||||||
|
instead.
|
||||||
|
zImage.%: Image format which does not embed a device tree.
|
||||||
|
Used by OpenFirmware and other firmware interfaces
|
||||||
|
which are able to supply a device tree. This image
|
||||||
|
expects firmware to provide the device tree at boot.
|
||||||
|
Typically, if you have general purpose PowerPC
|
||||||
|
hardware then you want this image format.
|
||||||
|
|
||||||
|
Image types which embed a device tree blob (simpleImage, dtbImage, treeImage,
|
||||||
|
and cuImage) all generate the device tree blob from a file in the
|
||||||
|
arch/powerpc/boot/dts/ directory. The Makefile selects the correct device
|
||||||
|
tree source based on the name of the target. Therefore, if the kernel is
|
||||||
|
built with 'make treeImage.walnut simpleImage.virtex405-ml403', then the
|
||||||
|
build system will use arch/powerpc/boot/dts/walnut.dts to build
|
||||||
|
treeImage.walnut and arch/powerpc/boot/dts/virtex405-ml403.dts to build
|
||||||
|
the simpleImage.virtex405-ml403.
|
||||||
|
|
||||||
|
Two special targets called 'zImage' and 'zImage.initrd' also exist. These
|
||||||
|
targets build all the default images as selected by the kernel configuration.
|
||||||
|
Default images are selected by the boot wrapper Makefile
|
||||||
|
(arch/powerpc/boot/Makefile) by adding targets to the $image-y variable. Look
|
||||||
|
at the Makefile to see which default image targets are available.
|
||||||
|
|
||||||
|
How it is built
|
||||||
|
---------------
|
||||||
|
arch/powerpc is designed to support multiplatform kernels, which means
|
||||||
|
that a single vmlinux image can be booted on many different target boards.
|
||||||
|
It also means that the boot wrapper must be able to wrap for many kinds of
|
||||||
|
images on a single build. The design decision was made to not use any
|
||||||
|
conditional compilation code (#ifdef, etc) in the boot wrapper source code.
|
||||||
|
All of the boot wrapper pieces are buildable at any time regardless of the
|
||||||
|
kernel configuration. Building all the wrapper bits on every kernel build
|
||||||
|
also ensures that obscure parts of the wrapper are at the very least compile
|
||||||
|
tested in a large variety of environments.
|
||||||
|
|
||||||
|
The wrapper is adapted for different image types at link time by linking in
|
||||||
|
just the wrapper bits that are appropriate for the image type. The 'wrapper
|
||||||
|
script' (found in arch/powerpc/boot/wrapper) is called by the Makefile and
|
||||||
|
is responsible for selecting the correct wrapper bits for the image type.
|
||||||
|
The arguments are well documented in the script's comment block, so they
|
||||||
|
are not repeated here. However, it is worth mentioning that the script
|
||||||
|
uses the -p (platform) argument as the main method of deciding which wrapper
|
||||||
|
bits to compile in. Look for the large 'case "$platform" in' block in the
|
||||||
|
middle of the script. This is also the place where platform specific fixups
|
||||||
|
can be selected by changing the link order.
|
||||||
|
|
||||||
|
In particular, care should be taken when working with cuImages. cuImage
|
||||||
|
wrapper bits are very board specific and care should be taken to make sure
|
||||||
|
the target you are trying to build is supported by the wrapper bits.
|
|
@ -0,0 +1,29 @@
|
||||||
|
* Board Control and Status (BCSR)
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
|
||||||
|
- device_type : Should be "board-control"
|
||||||
|
- reg : Offset and length of the register set for the device
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
bcsr@f8000000 {
|
||||||
|
device_type = "board-control";
|
||||||
|
reg = <f8000000 8000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
* Freescale on board FPGA
|
||||||
|
|
||||||
|
This is the memory-mapped registers for on board FPGA.
|
||||||
|
|
||||||
|
Required properities:
|
||||||
|
- compatible : should be "fsl,fpga-pixis".
|
||||||
|
- reg : should contain the address and the lenght of the FPPGA register
|
||||||
|
set.
|
||||||
|
|
||||||
|
Example (MPC8610HPCD):
|
||||||
|
|
||||||
|
board-control@e8000000 {
|
||||||
|
compatible = "fsl,fpga-pixis";
|
||||||
|
reg = <0xe8000000 32>;
|
||||||
|
};
|
|
@ -0,0 +1,67 @@
|
||||||
|
* Freescale Communications Processor Module
|
||||||
|
|
||||||
|
NOTE: This is an interim binding, and will likely change slightly,
|
||||||
|
as more devices are supported. The QE bindings especially are
|
||||||
|
incomplete.
|
||||||
|
|
||||||
|
* Root CPM node
|
||||||
|
|
||||||
|
Properties:
|
||||||
|
- compatible : "fsl,cpm1", "fsl,cpm2", or "fsl,qe".
|
||||||
|
- reg : A 48-byte region beginning with CPCR.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
cpm@119c0 {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
#interrupt-cells = <2>;
|
||||||
|
compatible = "fsl,mpc8272-cpm", "fsl,cpm2";
|
||||||
|
reg = <119c0 30>;
|
||||||
|
}
|
||||||
|
|
||||||
|
* Properties common to mulitple CPM/QE devices
|
||||||
|
|
||||||
|
- fsl,cpm-command : This value is ORed with the opcode and command flag
|
||||||
|
to specify the device on which a CPM command operates.
|
||||||
|
|
||||||
|
- fsl,cpm-brg : Indicates which baud rate generator the device
|
||||||
|
is associated with. If absent, an unused BRG
|
||||||
|
should be dynamically allocated. If zero, the
|
||||||
|
device uses an external clock rather than a BRG.
|
||||||
|
|
||||||
|
- reg : Unless otherwise specified, the first resource represents the
|
||||||
|
scc/fcc/ucc registers, and the second represents the device's
|
||||||
|
parameter RAM region (if it has one).
|
||||||
|
|
||||||
|
* Multi-User RAM (MURAM)
|
||||||
|
|
||||||
|
The multi-user/dual-ported RAM is expressed as a bus under the CPM node.
|
||||||
|
|
||||||
|
Ranges must be set up subject to the following restrictions:
|
||||||
|
|
||||||
|
- Children's reg nodes must be offsets from the start of all muram, even
|
||||||
|
if the user-data area does not begin at zero.
|
||||||
|
- If multiple range entries are used, the difference between the parent
|
||||||
|
address and the child address must be the same in all, so that a single
|
||||||
|
mapping can cover them all while maintaining the ability to determine
|
||||||
|
CPM-side offsets with pointer subtraction. It is recommended that
|
||||||
|
multiple range entries not be used.
|
||||||
|
- A child address of zero must be translatable, even if no reg resources
|
||||||
|
contain it.
|
||||||
|
|
||||||
|
A child "data" node must exist, compatible with "fsl,cpm-muram-data", to
|
||||||
|
indicate the portion of muram that is usable by the OS for arbitrary
|
||||||
|
purposes. The data node may have an arbitrary number of reg resources,
|
||||||
|
all of which contribute to the allocatable muram pool.
|
||||||
|
|
||||||
|
Example, based on mpc8272:
|
||||||
|
muram@0 {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
ranges = <0 0 10000>;
|
||||||
|
|
||||||
|
data@0 {
|
||||||
|
compatible = "fsl,cpm-muram-data";
|
||||||
|
reg = <0 2000 9800 800>;
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,21 @@
|
||||||
|
* Baud Rate Generators
|
||||||
|
|
||||||
|
Currently defined compatibles:
|
||||||
|
fsl,cpm-brg
|
||||||
|
fsl,cpm1-brg
|
||||||
|
fsl,cpm2-brg
|
||||||
|
|
||||||
|
Properties:
|
||||||
|
- reg : There may be an arbitrary number of reg resources; BRG
|
||||||
|
numbers are assigned to these in order.
|
||||||
|
- clock-frequency : Specifies the base frequency driving
|
||||||
|
the BRG.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
brg@119f0 {
|
||||||
|
compatible = "fsl,mpc8272-brg",
|
||||||
|
"fsl,cpm2-brg",
|
||||||
|
"fsl,cpm-brg";
|
||||||
|
reg = <119f0 10 115f0 10>;
|
||||||
|
clock-frequency = <d#25000000>;
|
||||||
|
};
|
|
@ -0,0 +1,41 @@
|
||||||
|
* I2C
|
||||||
|
|
||||||
|
The I2C controller is expressed as a bus under the CPM node.
|
||||||
|
|
||||||
|
Properties:
|
||||||
|
- compatible : "fsl,cpm1-i2c", "fsl,cpm2-i2c"
|
||||||
|
- reg : On CPM2 devices, the second resource doesn't specify the I2C
|
||||||
|
Parameter RAM itself, but the I2C_BASE field of the CPM2 Parameter RAM
|
||||||
|
(typically 0x8afc 0x2).
|
||||||
|
- #address-cells : Should be one. The cell is the i2c device address with
|
||||||
|
the r/w bit set to zero.
|
||||||
|
- #size-cells : Should be zero.
|
||||||
|
- clock-frequency : Can be used to set the i2c clock frequency. If
|
||||||
|
unspecified, a default frequency of 60kHz is being used.
|
||||||
|
The following two properties are deprecated. They are only used by legacy
|
||||||
|
i2c drivers to find the bus to probe:
|
||||||
|
- linux,i2c-index : Can be used to hard code an i2c bus number. By default,
|
||||||
|
the bus number is dynamically assigned by the i2c core.
|
||||||
|
- linux,i2c-class : Can be used to override the i2c class. The class is used
|
||||||
|
by legacy i2c device drivers to find a bus in a specific context like
|
||||||
|
system management, video or sound. By default, I2C_CLASS_HWMON (1) is
|
||||||
|
being used. The definition of the classes can be found in
|
||||||
|
include/i2c/i2c.h
|
||||||
|
|
||||||
|
Example, based on mpc823:
|
||||||
|
|
||||||
|
i2c@860 {
|
||||||
|
compatible = "fsl,mpc823-i2c",
|
||||||
|
"fsl,cpm1-i2c";
|
||||||
|
reg = <0x860 0x20 0x3c80 0x30>;
|
||||||
|
interrupts = <16>;
|
||||||
|
interrupt-parent = <&CPM_PIC>;
|
||||||
|
fsl,cpm-command = <0x10>;
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
rtc@68 {
|
||||||
|
compatible = "dallas,ds1307";
|
||||||
|
reg = <0x68>;
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,18 @@
|
||||||
|
* Interrupt Controllers
|
||||||
|
|
||||||
|
Currently defined compatibles:
|
||||||
|
- fsl,cpm1-pic
|
||||||
|
- only one interrupt cell
|
||||||
|
- fsl,pq1-pic
|
||||||
|
- fsl,cpm2-pic
|
||||||
|
- second interrupt cell is level/sense:
|
||||||
|
- 2 is falling edge
|
||||||
|
- 8 is active low
|
||||||
|
|
||||||
|
Example:
|
||||||
|
interrupt-controller@10c00 {
|
||||||
|
#interrupt-cells = <2>;
|
||||||
|
interrupt-controller;
|
||||||
|
reg = <10c00 80>;
|
||||||
|
compatible = "mpc8272-pic", "fsl,cpm2-pic";
|
||||||
|
};
|
|
@ -0,0 +1,15 @@
|
||||||
|
* USB (Universal Serial Bus Controller)
|
||||||
|
|
||||||
|
Properties:
|
||||||
|
- compatible : "fsl,cpm1-usb", "fsl,cpm2-usb", "fsl,qe-usb"
|
||||||
|
|
||||||
|
Example:
|
||||||
|
usb@11bc0 {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
compatible = "fsl,cpm2-usb";
|
||||||
|
reg = <11b60 18 8b00 100>;
|
||||||
|
interrupts = <b 8>;
|
||||||
|
interrupt-parent = <&PIC>;
|
||||||
|
fsl,cpm-command = <2e600000>;
|
||||||
|
};
|
|
@ -0,0 +1,45 @@
|
||||||
|
* Network
|
||||||
|
|
||||||
|
Currently defined compatibles:
|
||||||
|
- fsl,cpm1-scc-enet
|
||||||
|
- fsl,cpm2-scc-enet
|
||||||
|
- fsl,cpm1-fec-enet
|
||||||
|
- fsl,cpm2-fcc-enet (third resource is GFEMR)
|
||||||
|
- fsl,qe-enet
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
ethernet@11300 {
|
||||||
|
device_type = "network";
|
||||||
|
compatible = "fsl,mpc8272-fcc-enet",
|
||||||
|
"fsl,cpm2-fcc-enet";
|
||||||
|
reg = <11300 20 8400 100 11390 1>;
|
||||||
|
local-mac-address = [ 00 00 00 00 00 00 ];
|
||||||
|
interrupts = <20 8>;
|
||||||
|
interrupt-parent = <&PIC>;
|
||||||
|
phy-handle = <&PHY0>;
|
||||||
|
fsl,cpm-command = <12000300>;
|
||||||
|
};
|
||||||
|
|
||||||
|
* MDIO
|
||||||
|
|
||||||
|
Currently defined compatibles:
|
||||||
|
fsl,pq1-fec-mdio (reg is same as first resource of FEC device)
|
||||||
|
fsl,cpm2-mdio-bitbang (reg is port C registers)
|
||||||
|
|
||||||
|
Properties for fsl,cpm2-mdio-bitbang:
|
||||||
|
fsl,mdio-pin : pin of port C controlling mdio data
|
||||||
|
fsl,mdc-pin : pin of port C controlling mdio clock
|
||||||
|
|
||||||
|
Example:
|
||||||
|
mdio@10d40 {
|
||||||
|
device_type = "mdio";
|
||||||
|
compatible = "fsl,mpc8272ads-mdio-bitbang",
|
||||||
|
"fsl,mpc8272-mdio-bitbang",
|
||||||
|
"fsl,cpm2-mdio-bitbang";
|
||||||
|
reg = <10d40 14>;
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
fsl,mdio-pin = <12>;
|
||||||
|
fsl,mdc-pin = <13>;
|
||||||
|
};
|
|
@ -0,0 +1,58 @@
|
||||||
|
* Freescale QUICC Engine module (QE)
|
||||||
|
This represents qe module that is installed on PowerQUICC II Pro.
|
||||||
|
|
||||||
|
NOTE: This is an interim binding; it should be updated to fit
|
||||||
|
in with the CPM binding later in this document.
|
||||||
|
|
||||||
|
Basically, it is a bus of devices, that could act more or less
|
||||||
|
as a complete entity (UCC, USB etc ). All of them should be siblings on
|
||||||
|
the "root" qe node, using the common properties from there.
|
||||||
|
The description below applies to the qe of MPC8360 and
|
||||||
|
more nodes and properties would be extended in the future.
|
||||||
|
|
||||||
|
i) Root QE device
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible : should be "fsl,qe";
|
||||||
|
- model : precise model of the QE, Can be "QE", "CPM", or "CPM2"
|
||||||
|
- reg : offset and length of the device registers.
|
||||||
|
- bus-frequency : the clock frequency for QUICC Engine.
|
||||||
|
|
||||||
|
Recommended properties
|
||||||
|
- brg-frequency : the internal clock source frequency for baud-rate
|
||||||
|
generators in Hz.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
qe@e0100000 {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
#interrupt-cells = <2>;
|
||||||
|
compatible = "fsl,qe";
|
||||||
|
ranges = <0 e0100000 00100000>;
|
||||||
|
reg = <e0100000 480>;
|
||||||
|
brg-frequency = <0>;
|
||||||
|
bus-frequency = <179A7B00>;
|
||||||
|
}
|
||||||
|
|
||||||
|
* Multi-User RAM (MURAM)
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible : should be "fsl,qe-muram", "fsl,cpm-muram".
|
||||||
|
- mode : the could be "host" or "slave".
|
||||||
|
- ranges : Should be defined as specified in 1) to describe the
|
||||||
|
translation of MURAM addresses.
|
||||||
|
- data-only : sub-node which defines the address area under MURAM
|
||||||
|
bus that can be allocated as data/parameter
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
muram@10000 {
|
||||||
|
compatible = "fsl,qe-muram", "fsl,cpm-muram";
|
||||||
|
ranges = <0 00010000 0000c000>;
|
||||||
|
|
||||||
|
data-only@0{
|
||||||
|
compatible = "fsl,qe-muram-data",
|
||||||
|
"fsl,cpm-muram-data";
|
||||||
|
reg = <0 c000>;
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,24 @@
|
||||||
|
* Uploaded QE firmware
|
||||||
|
|
||||||
|
If a new firwmare has been uploaded to the QE (usually by the
|
||||||
|
boot loader), then a 'firmware' child node should be added to the QE
|
||||||
|
node. This node provides information on the uploaded firmware that
|
||||||
|
device drivers may need.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- id: The string name of the firmware. This is taken from the 'id'
|
||||||
|
member of the qe_firmware structure of the uploaded firmware.
|
||||||
|
Device drivers can search this string to determine if the
|
||||||
|
firmware they want is already present.
|
||||||
|
- extended-modes: The Extended Modes bitfield, taken from the
|
||||||
|
firmware binary. It is a 64-bit number represented
|
||||||
|
as an array of two 32-bit numbers.
|
||||||
|
- virtual-traps: The virtual traps, taken from the firmware binary.
|
||||||
|
It is an array of 8 32-bit numbers.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
firmware {
|
||||||
|
id = "Soft-UART";
|
||||||
|
extended-modes = <0 0>;
|
||||||
|
virtual-traps = <0 0 0 0 0 0 0 0>;
|
||||||
|
};
|
|
@ -0,0 +1,51 @@
|
||||||
|
* Parallel I/O Ports
|
||||||
|
|
||||||
|
This node configures Parallel I/O ports for CPUs with QE support.
|
||||||
|
The node should reside in the "soc" node of the tree. For each
|
||||||
|
device that using parallel I/O ports, a child node should be created.
|
||||||
|
See the definition of the Pin configuration nodes below for more
|
||||||
|
information.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- device_type : should be "par_io".
|
||||||
|
- reg : offset to the register set and its length.
|
||||||
|
- num-ports : number of Parallel I/O ports
|
||||||
|
|
||||||
|
Example:
|
||||||
|
par_io@1400 {
|
||||||
|
reg = <1400 100>;
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
device_type = "par_io";
|
||||||
|
num-ports = <7>;
|
||||||
|
ucc_pin@01 {
|
||||||
|
......
|
||||||
|
};
|
||||||
|
|
||||||
|
Note that "par_io" nodes are obsolete, and should not be used for
|
||||||
|
the new device trees. Instead, each Par I/O bank should be represented
|
||||||
|
via its own gpio-controller node:
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- #gpio-cells : should be "2".
|
||||||
|
- compatible : should be "fsl,<chip>-qe-pario-bank",
|
||||||
|
"fsl,mpc8323-qe-pario-bank".
|
||||||
|
- reg : offset to the register set and its length.
|
||||||
|
- gpio-controller : node to identify gpio controllers.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
qe_pio_a: gpio-controller@1400 {
|
||||||
|
#gpio-cells = <2>;
|
||||||
|
compatible = "fsl,mpc8360-qe-pario-bank",
|
||||||
|
"fsl,mpc8323-qe-pario-bank";
|
||||||
|
reg = <0x1400 0x18>;
|
||||||
|
gpio-controller;
|
||||||
|
};
|
||||||
|
|
||||||
|
qe_pio_e: gpio-controller@1460 {
|
||||||
|
#gpio-cells = <2>;
|
||||||
|
compatible = "fsl,mpc8360-qe-pario-bank",
|
||||||
|
"fsl,mpc8323-qe-pario-bank";
|
||||||
|
reg = <0x1460 0x18>;
|
||||||
|
gpio-controller;
|
||||||
|
};
|
|
@ -0,0 +1,60 @@
|
||||||
|
* Pin configuration nodes
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- linux,phandle : phandle of this node; likely referenced by a QE
|
||||||
|
device.
|
||||||
|
- pio-map : array of pin configurations. Each pin is defined by 6
|
||||||
|
integers. The six numbers are respectively: port, pin, dir,
|
||||||
|
open_drain, assignment, has_irq.
|
||||||
|
- port : port number of the pin; 0-6 represent port A-G in UM.
|
||||||
|
- pin : pin number in the port.
|
||||||
|
- dir : direction of the pin, should encode as follows:
|
||||||
|
|
||||||
|
0 = The pin is disabled
|
||||||
|
1 = The pin is an output
|
||||||
|
2 = The pin is an input
|
||||||
|
3 = The pin is I/O
|
||||||
|
|
||||||
|
- open_drain : indicates the pin is normal or wired-OR:
|
||||||
|
|
||||||
|
0 = The pin is actively driven as an output
|
||||||
|
1 = The pin is an open-drain driver. As an output, the pin is
|
||||||
|
driven active-low, otherwise it is three-stated.
|
||||||
|
|
||||||
|
- assignment : function number of the pin according to the Pin Assignment
|
||||||
|
tables in User Manual. Each pin can have up to 4 possible functions in
|
||||||
|
QE and two options for CPM.
|
||||||
|
- has_irq : indicates if the pin is used as source of external
|
||||||
|
interrupts.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
ucc_pin@01 {
|
||||||
|
linux,phandle = <140001>;
|
||||||
|
pio-map = <
|
||||||
|
/* port pin dir open_drain assignment has_irq */
|
||||||
|
0 3 1 0 1 0 /* TxD0 */
|
||||||
|
0 4 1 0 1 0 /* TxD1 */
|
||||||
|
0 5 1 0 1 0 /* TxD2 */
|
||||||
|
0 6 1 0 1 0 /* TxD3 */
|
||||||
|
1 6 1 0 3 0 /* TxD4 */
|
||||||
|
1 7 1 0 1 0 /* TxD5 */
|
||||||
|
1 9 1 0 2 0 /* TxD6 */
|
||||||
|
1 a 1 0 2 0 /* TxD7 */
|
||||||
|
0 9 2 0 1 0 /* RxD0 */
|
||||||
|
0 a 2 0 1 0 /* RxD1 */
|
||||||
|
0 b 2 0 1 0 /* RxD2 */
|
||||||
|
0 c 2 0 1 0 /* RxD3 */
|
||||||
|
0 d 2 0 1 0 /* RxD4 */
|
||||||
|
1 1 2 0 2 0 /* RxD5 */
|
||||||
|
1 0 2 0 2 0 /* RxD6 */
|
||||||
|
1 4 2 0 2 0 /* RxD7 */
|
||||||
|
0 7 1 0 1 0 /* TX_EN */
|
||||||
|
0 8 1 0 1 0 /* TX_ER */
|
||||||
|
0 f 2 0 1 0 /* RX_DV */
|
||||||
|
0 10 2 0 1 0 /* RX_ER */
|
||||||
|
0 0 2 0 1 0 /* RX_CLK */
|
||||||
|
2 9 1 0 3 0 /* GTX_CLK - CLK10 */
|
||||||
|
2 8 2 0 1 0>; /* GTX125 - CLK9 */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
* UCC (Unified Communications Controllers)
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- device_type : should be "network", "hldc", "uart", "transparent"
|
||||||
|
"bisync", "atm", or "serial".
|
||||||
|
- compatible : could be "ucc_geth" or "fsl_atm" and so on.
|
||||||
|
- cell-index : the ucc number(1-8), corresponding to UCCx in UM.
|
||||||
|
- reg : Offset and length of the register set for the device
|
||||||
|
- interrupts : <a b> where a is the interrupt number and b is a
|
||||||
|
field that represents an encoding of the sense and level
|
||||||
|
information for the interrupt. This should be encoded based on
|
||||||
|
the information in section 2) depending on the type of interrupt
|
||||||
|
controller you have.
|
||||||
|
- interrupt-parent : the phandle for the interrupt controller that
|
||||||
|
services interrupts for this device.
|
||||||
|
- pio-handle : The phandle for the Parallel I/O port configuration.
|
||||||
|
- port-number : for UART drivers, the port number to use, between 0 and 3.
|
||||||
|
This usually corresponds to the /dev/ttyQE device, e.g. <0> = /dev/ttyQE0.
|
||||||
|
The port number is added to the minor number of the device. Unlike the
|
||||||
|
CPM UART driver, the port-number is required for the QE UART driver.
|
||||||
|
- soft-uart : for UART drivers, if specified this means the QE UART device
|
||||||
|
driver should use "Soft-UART" mode, which is needed on some SOCs that have
|
||||||
|
broken UART hardware. Soft-UART is provided via a microcode upload.
|
||||||
|
- rx-clock-name: the UCC receive clock source
|
||||||
|
"none": clock source is disabled
|
||||||
|
"brg1" through "brg16": clock source is BRG1-BRG16, respectively
|
||||||
|
"clk1" through "clk24": clock source is CLK1-CLK24, respectively
|
||||||
|
- tx-clock-name: the UCC transmit clock source
|
||||||
|
"none": clock source is disabled
|
||||||
|
"brg1" through "brg16": clock source is BRG1-BRG16, respectively
|
||||||
|
"clk1" through "clk24": clock source is CLK1-CLK24, respectively
|
||||||
|
The following two properties are deprecated. rx-clock has been replaced
|
||||||
|
with rx-clock-name, and tx-clock has been replaced with tx-clock-name.
|
||||||
|
Drivers that currently use the deprecated properties should continue to
|
||||||
|
do so, in order to support older device trees, but they should be updated
|
||||||
|
to check for the new properties first.
|
||||||
|
- rx-clock : represents the UCC receive clock source.
|
||||||
|
0x00 : clock source is disabled;
|
||||||
|
0x1~0x10 : clock source is BRG1~BRG16 respectively;
|
||||||
|
0x11~0x28: clock source is QE_CLK1~QE_CLK24 respectively.
|
||||||
|
- tx-clock: represents the UCC transmit clock source;
|
||||||
|
0x00 : clock source is disabled;
|
||||||
|
0x1~0x10 : clock source is BRG1~BRG16 respectively;
|
||||||
|
0x11~0x28: clock source is QE_CLK1~QE_CLK24 respectively.
|
||||||
|
|
||||||
|
Required properties for network device_type:
|
||||||
|
- mac-address : list of bytes representing the ethernet address.
|
||||||
|
- phy-handle : The phandle for the PHY connected to this controller.
|
||||||
|
|
||||||
|
Recommended properties:
|
||||||
|
- phy-connection-type : a string naming the controller/PHY interface type,
|
||||||
|
i.e., "mii" (default), "rmii", "gmii", "rgmii", "rgmii-id" (Internal
|
||||||
|
Delay), "rgmii-txid" (delay on TX only), "rgmii-rxid" (delay on RX only),
|
||||||
|
"tbi", or "rtbi".
|
||||||
|
|
||||||
|
Example:
|
||||||
|
ucc@2000 {
|
||||||
|
device_type = "network";
|
||||||
|
compatible = "ucc_geth";
|
||||||
|
cell-index = <1>;
|
||||||
|
reg = <2000 200>;
|
||||||
|
interrupts = <a0 0>;
|
||||||
|
interrupt-parent = <700>;
|
||||||
|
mac-address = [ 00 04 9f 00 23 23 ];
|
||||||
|
rx-clock = "none";
|
||||||
|
tx-clock = "clk9";
|
||||||
|
phy-handle = <212000>;
|
||||||
|
phy-connection-type = "gmii";
|
||||||
|
pio-handle = <140001>;
|
||||||
|
};
|
|
@ -0,0 +1,22 @@
|
||||||
|
* USB (Universal Serial Bus Controller)
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible : could be "qe_udc" or "fhci-hcd".
|
||||||
|
- mode : the could be "host" or "slave".
|
||||||
|
- reg : Offset and length of the register set for the device
|
||||||
|
- interrupts : <a b> where a is the interrupt number and b is a
|
||||||
|
field that represents an encoding of the sense and level
|
||||||
|
information for the interrupt. This should be encoded based on
|
||||||
|
the information in section 2) depending on the type of interrupt
|
||||||
|
controller you have.
|
||||||
|
- interrupt-parent : the phandle for the interrupt controller that
|
||||||
|
services interrupts for this device.
|
||||||
|
|
||||||
|
Example(slave):
|
||||||
|
usb@6c0 {
|
||||||
|
compatible = "qe_udc";
|
||||||
|
reg = <6c0 40>;
|
||||||
|
interrupts = <8b 0>;
|
||||||
|
interrupt-parent = <700>;
|
||||||
|
mode = "slave";
|
||||||
|
};
|
|
@ -0,0 +1,21 @@
|
||||||
|
* Serial
|
||||||
|
|
||||||
|
Currently defined compatibles:
|
||||||
|
- fsl,cpm1-smc-uart
|
||||||
|
- fsl,cpm2-smc-uart
|
||||||
|
- fsl,cpm1-scc-uart
|
||||||
|
- fsl,cpm2-scc-uart
|
||||||
|
- fsl,qe-uart
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
serial@11a00 {
|
||||||
|
device_type = "serial";
|
||||||
|
compatible = "fsl,mpc8272-scc-uart",
|
||||||
|
"fsl,cpm2-scc-uart";
|
||||||
|
reg = <11a00 20 8000 100>;
|
||||||
|
interrupts = <28 8>;
|
||||||
|
interrupt-parent = <&PIC>;
|
||||||
|
fsl,cpm-brg = <1>;
|
||||||
|
fsl,cpm-command = <00800000>;
|
||||||
|
};
|
|
@ -0,0 +1,18 @@
|
||||||
|
* Freescale Display Interface Unit
|
||||||
|
|
||||||
|
The Freescale DIU is a LCD controller, with proper hardware, it can also
|
||||||
|
drive DVI monitors.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible : should be "fsl-diu".
|
||||||
|
- reg : should contain at least address and length of the DIU register
|
||||||
|
set.
|
||||||
|
- Interrupts : one DIU interrupt should be describe here.
|
||||||
|
|
||||||
|
Example (MPC8610HPCD):
|
||||||
|
display@2c000 {
|
||||||
|
compatible = "fsl,diu";
|
||||||
|
reg = <0x2c000 100>;
|
||||||
|
interrupts = <72 2>;
|
||||||
|
interrupt-parent = <&mpic>;
|
||||||
|
};
|
|
@ -0,0 +1,127 @@
|
||||||
|
* Freescale 83xx DMA Controller
|
||||||
|
|
||||||
|
Freescale PowerPC 83xx have on chip general purpose DMA controllers.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
|
||||||
|
- compatible : compatible list, contains 2 entries, first is
|
||||||
|
"fsl,CHIP-dma", where CHIP is the processor
|
||||||
|
(mpc8349, mpc8360, etc.) and the second is
|
||||||
|
"fsl,elo-dma"
|
||||||
|
- reg : <registers mapping for DMA general status reg>
|
||||||
|
- ranges : Should be defined as specified in 1) to describe the
|
||||||
|
DMA controller channels.
|
||||||
|
- cell-index : controller index. 0 for controller @ 0x8100
|
||||||
|
- interrupts : <interrupt mapping for DMA IRQ>
|
||||||
|
- interrupt-parent : optional, if needed for interrupt mapping
|
||||||
|
|
||||||
|
|
||||||
|
- DMA channel nodes:
|
||||||
|
- compatible : compatible list, contains 2 entries, first is
|
||||||
|
"fsl,CHIP-dma-channel", where CHIP is the processor
|
||||||
|
(mpc8349, mpc8350, etc.) and the second is
|
||||||
|
"fsl,elo-dma-channel"
|
||||||
|
- reg : <registers mapping for channel>
|
||||||
|
- cell-index : dma channel index starts at 0.
|
||||||
|
|
||||||
|
Optional properties:
|
||||||
|
- interrupts : <interrupt mapping for DMA channel IRQ>
|
||||||
|
(on 83xx this is expected to be identical to
|
||||||
|
the interrupts property of the parent node)
|
||||||
|
- interrupt-parent : optional, if needed for interrupt mapping
|
||||||
|
|
||||||
|
Example:
|
||||||
|
dma@82a8 {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
compatible = "fsl,mpc8349-dma", "fsl,elo-dma";
|
||||||
|
reg = <82a8 4>;
|
||||||
|
ranges = <0 8100 1a4>;
|
||||||
|
interrupt-parent = <&ipic>;
|
||||||
|
interrupts = <47 8>;
|
||||||
|
cell-index = <0>;
|
||||||
|
dma-channel@0 {
|
||||||
|
compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
|
||||||
|
cell-index = <0>;
|
||||||
|
reg = <0 80>;
|
||||||
|
};
|
||||||
|
dma-channel@80 {
|
||||||
|
compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
|
||||||
|
cell-index = <1>;
|
||||||
|
reg = <80 80>;
|
||||||
|
};
|
||||||
|
dma-channel@100 {
|
||||||
|
compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
|
||||||
|
cell-index = <2>;
|
||||||
|
reg = <100 80>;
|
||||||
|
};
|
||||||
|
dma-channel@180 {
|
||||||
|
compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
|
||||||
|
cell-index = <3>;
|
||||||
|
reg = <180 80>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
* Freescale 85xx/86xx DMA Controller
|
||||||
|
|
||||||
|
Freescale PowerPC 85xx/86xx have on chip general purpose DMA controllers.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
|
||||||
|
- compatible : compatible list, contains 2 entries, first is
|
||||||
|
"fsl,CHIP-dma", where CHIP is the processor
|
||||||
|
(mpc8540, mpc8540, etc.) and the second is
|
||||||
|
"fsl,eloplus-dma"
|
||||||
|
- reg : <registers mapping for DMA general status reg>
|
||||||
|
- cell-index : controller index. 0 for controller @ 0x21000,
|
||||||
|
1 for controller @ 0xc000
|
||||||
|
- ranges : Should be defined as specified in 1) to describe the
|
||||||
|
DMA controller channels.
|
||||||
|
|
||||||
|
- DMA channel nodes:
|
||||||
|
- compatible : compatible list, contains 2 entries, first is
|
||||||
|
"fsl,CHIP-dma-channel", where CHIP is the processor
|
||||||
|
(mpc8540, mpc8560, etc.) and the second is
|
||||||
|
"fsl,eloplus-dma-channel"
|
||||||
|
- cell-index : dma channel index starts at 0.
|
||||||
|
- reg : <registers mapping for channel>
|
||||||
|
- interrupts : <interrupt mapping for DMA channel IRQ>
|
||||||
|
- interrupt-parent : optional, if needed for interrupt mapping
|
||||||
|
|
||||||
|
Example:
|
||||||
|
dma@21300 {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
compatible = "fsl,mpc8540-dma", "fsl,eloplus-dma";
|
||||||
|
reg = <21300 4>;
|
||||||
|
ranges = <0 21100 200>;
|
||||||
|
cell-index = <0>;
|
||||||
|
dma-channel@0 {
|
||||||
|
compatible = "fsl,mpc8540-dma-channel", "fsl,eloplus-dma-channel";
|
||||||
|
reg = <0 80>;
|
||||||
|
cell-index = <0>;
|
||||||
|
interrupt-parent = <&mpic>;
|
||||||
|
interrupts = <14 2>;
|
||||||
|
};
|
||||||
|
dma-channel@80 {
|
||||||
|
compatible = "fsl,mpc8540-dma-channel", "fsl,eloplus-dma-channel";
|
||||||
|
reg = <80 80>;
|
||||||
|
cell-index = <1>;
|
||||||
|
interrupt-parent = <&mpic>;
|
||||||
|
interrupts = <15 2>;
|
||||||
|
};
|
||||||
|
dma-channel@100 {
|
||||||
|
compatible = "fsl,mpc8540-dma-channel", "fsl,eloplus-dma-channel";
|
||||||
|
reg = <100 80>;
|
||||||
|
cell-index = <2>;
|
||||||
|
interrupt-parent = <&mpic>;
|
||||||
|
interrupts = <16 2>;
|
||||||
|
};
|
||||||
|
dma-channel@180 {
|
||||||
|
compatible = "fsl,mpc8540-dma-channel", "fsl,eloplus-dma-channel";
|
||||||
|
reg = <180 80>;
|
||||||
|
cell-index = <3>;
|
||||||
|
interrupt-parent = <&mpic>;
|
||||||
|
interrupts = <17 2>;
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,31 @@
|
||||||
|
* Freescale General-purpose Timers Module
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible : should be
|
||||||
|
"fsl,<chip>-gtm", "fsl,gtm" for SOC GTMs
|
||||||
|
"fsl,<chip>-qe-gtm", "fsl,qe-gtm", "fsl,gtm" for QE GTMs
|
||||||
|
"fsl,<chip>-cpm2-gtm", "fsl,cpm2-gtm", "fsl,gtm" for CPM2 GTMs
|
||||||
|
- reg : should contain gtm registers location and length (0x40).
|
||||||
|
- interrupts : should contain four interrupts.
|
||||||
|
- interrupt-parent : interrupt source phandle.
|
||||||
|
- clock-frequency : specifies the frequency driving the timer.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
timer@500 {
|
||||||
|
compatible = "fsl,mpc8360-gtm", "fsl,gtm";
|
||||||
|
reg = <0x500 0x40>;
|
||||||
|
interrupts = <90 8 78 8 84 8 72 8>;
|
||||||
|
interrupt-parent = <&ipic>;
|
||||||
|
/* filled by u-boot */
|
||||||
|
clock-frequency = <0>;
|
||||||
|
};
|
||||||
|
|
||||||
|
timer@440 {
|
||||||
|
compatible = "fsl,mpc8360-qe-gtm", "fsl,qe-gtm", "fsl,gtm";
|
||||||
|
reg = <0x440 0x40>;
|
||||||
|
interrupts = <12 13 14 15>;
|
||||||
|
interrupt-parent = <&qeic>;
|
||||||
|
/* filled by u-boot */
|
||||||
|
clock-frequency = <0>;
|
||||||
|
};
|
|
@ -0,0 +1,25 @@
|
||||||
|
* Global Utilities Block
|
||||||
|
|
||||||
|
The global utilities block controls power management, I/O device
|
||||||
|
enabling, power-on-reset configuration monitoring, general-purpose
|
||||||
|
I/O signal configuration, alternate function selection for multiplexed
|
||||||
|
signals, and clock control.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
|
||||||
|
- compatible : Should define the compatible device type for
|
||||||
|
global-utilities.
|
||||||
|
- reg : Offset and length of the register set for the device.
|
||||||
|
|
||||||
|
Recommended properties:
|
||||||
|
|
||||||
|
- fsl,has-rstcr : Indicates that the global utilities register set
|
||||||
|
contains a functioning "reset control register" (i.e. the board
|
||||||
|
is wired to reset upon setting the HRESET_REQ bit in this register).
|
||||||
|
|
||||||
|
Example:
|
||||||
|
global-utilities@e0000 { /* global utilities block */
|
||||||
|
compatible = "fsl,mpc8548-guts";
|
||||||
|
reg = <e0000 1000>;
|
||||||
|
fsl,has-rstcr;
|
||||||
|
};
|
|
@ -0,0 +1,32 @@
|
||||||
|
* I2C
|
||||||
|
|
||||||
|
Required properties :
|
||||||
|
|
||||||
|
- device_type : Should be "i2c"
|
||||||
|
- reg : Offset and length of the register set for the device
|
||||||
|
|
||||||
|
Recommended properties :
|
||||||
|
|
||||||
|
- compatible : Should be "fsl-i2c" for parts compatible with
|
||||||
|
Freescale I2C specifications.
|
||||||
|
- interrupts : <a b> where a is the interrupt number and b is a
|
||||||
|
field that represents an encoding of the sense and level
|
||||||
|
information for the interrupt. This should be encoded based on
|
||||||
|
the information in section 2) depending on the type of interrupt
|
||||||
|
controller you have.
|
||||||
|
- interrupt-parent : the phandle for the interrupt controller that
|
||||||
|
services interrupts for this device.
|
||||||
|
- dfsrr : boolean; if defined, indicates that this I2C device has
|
||||||
|
a digital filter sampling rate register
|
||||||
|
- fsl5200-clocking : boolean; if defined, indicated that this device
|
||||||
|
uses the FSL 5200 clocking mechanism.
|
||||||
|
|
||||||
|
Example :
|
||||||
|
i2c@3000 {
|
||||||
|
interrupt-parent = <40000>;
|
||||||
|
interrupts = <1b 3>;
|
||||||
|
reg = <3000 18>;
|
||||||
|
device_type = "i2c";
|
||||||
|
compatible = "fsl-i2c";
|
||||||
|
dfsrr;
|
||||||
|
};
|
|
@ -0,0 +1,35 @@
|
||||||
|
* Chipselect/Local Bus
|
||||||
|
|
||||||
|
Properties:
|
||||||
|
- name : Should be localbus
|
||||||
|
- #address-cells : Should be either two or three. The first cell is the
|
||||||
|
chipselect number, and the remaining cells are the
|
||||||
|
offset into the chipselect.
|
||||||
|
- #size-cells : Either one or two, depending on how large each chipselect
|
||||||
|
can be.
|
||||||
|
- ranges : Each range corresponds to a single chipselect, and cover
|
||||||
|
the entire access window as configured.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
localbus@f0010100 {
|
||||||
|
compatible = "fsl,mpc8272-localbus",
|
||||||
|
"fsl,pq2-localbus";
|
||||||
|
#address-cells = <2>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
reg = <f0010100 40>;
|
||||||
|
|
||||||
|
ranges = <0 0 fe000000 02000000
|
||||||
|
1 0 f4500000 00008000>;
|
||||||
|
|
||||||
|
flash@0,0 {
|
||||||
|
compatible = "jedec-flash";
|
||||||
|
reg = <0 0 2000000>;
|
||||||
|
bank-width = <4>;
|
||||||
|
device-width = <1>;
|
||||||
|
};
|
||||||
|
|
||||||
|
board-control@1,0 {
|
||||||
|
reg = <1 0 20>;
|
||||||
|
compatible = "fsl,mpc8272ads-bcsr";
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,36 @@
|
||||||
|
* Freescale MSI interrupt controller
|
||||||
|
|
||||||
|
Reguired properities:
|
||||||
|
- compatible : compatible list, contains 2 entries,
|
||||||
|
first is "fsl,CHIP-msi", where CHIP is the processor(mpc8610, mpc8572,
|
||||||
|
etc.) and the second is "fsl,mpic-msi" or "fsl,ipic-msi" depending on
|
||||||
|
the parent type.
|
||||||
|
- reg : should contain the address and the length of the shared message
|
||||||
|
interrupt register set.
|
||||||
|
- msi-available-ranges: use <start count> style section to define which
|
||||||
|
msi interrupt can be used in the 256 msi interrupts. This property is
|
||||||
|
optional, without this, all the 256 MSI interrupts can be used.
|
||||||
|
- interrupts : each one of the interrupts here is one entry per 32 MSIs,
|
||||||
|
and routed to the host interrupt controller. the interrupts should
|
||||||
|
be set as edge sensitive.
|
||||||
|
- interrupt-parent: the phandle for the interrupt controller
|
||||||
|
that services interrupts for this device. for 83xx cpu, the interrupts
|
||||||
|
are routed to IPIC, and for 85xx/86xx cpu the interrupts are routed
|
||||||
|
to MPIC.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
msi@41600 {
|
||||||
|
compatible = "fsl,mpc8610-msi", "fsl,mpic-msi";
|
||||||
|
reg = <0x41600 0x80>;
|
||||||
|
msi-available-ranges = <0 0x100>;
|
||||||
|
interrupts = <
|
||||||
|
0xe0 0
|
||||||
|
0xe1 0
|
||||||
|
0xe2 0
|
||||||
|
0xe3 0
|
||||||
|
0xe4 0
|
||||||
|
0xe5 0
|
||||||
|
0xe6 0
|
||||||
|
0xe7 0>;
|
||||||
|
interrupt-parent = <&mpic>;
|
||||||
|
};
|
|
@ -0,0 +1,29 @@
|
||||||
|
* Freescale 8xxx/3.0 Gb/s SATA nodes
|
||||||
|
|
||||||
|
SATA nodes are defined to describe on-chip Serial ATA controllers.
|
||||||
|
Each SATA port should have its own node.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible : compatible list, contains 2 entries, first is
|
||||||
|
"fsl,CHIP-sata", where CHIP is the processor
|
||||||
|
(mpc8315, mpc8379, etc.) and the second is
|
||||||
|
"fsl,pq-sata"
|
||||||
|
- interrupts : <interrupt mapping for SATA IRQ>
|
||||||
|
- cell-index : controller index.
|
||||||
|
1 for controller @ 0x18000
|
||||||
|
2 for controller @ 0x19000
|
||||||
|
3 for controller @ 0x1a000
|
||||||
|
4 for controller @ 0x1b000
|
||||||
|
|
||||||
|
Optional properties:
|
||||||
|
- interrupt-parent : optional, if needed for interrupt mapping
|
||||||
|
- reg : <registers mapping>
|
||||||
|
|
||||||
|
Example:
|
||||||
|
sata@18000 {
|
||||||
|
compatible = "fsl,mpc8379-sata", "fsl,pq-sata";
|
||||||
|
reg = <0x18000 0x1000>;
|
||||||
|
cell-index = <1>;
|
||||||
|
interrupts = <2c 8>;
|
||||||
|
interrupt-parent = < &ipic >;
|
||||||
|
};
|
|
@ -0,0 +1,68 @@
|
||||||
|
Freescale SoC SEC Security Engines
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
|
||||||
|
- compatible : Should contain entries for this and backward compatible
|
||||||
|
SEC versions, high to low, e.g., "fsl,sec2.1", "fsl,sec2.0"
|
||||||
|
- reg : Offset and length of the register set for the device
|
||||||
|
- interrupts : the SEC's interrupt number
|
||||||
|
- fsl,num-channels : An integer representing the number of channels
|
||||||
|
available.
|
||||||
|
- fsl,channel-fifo-len : An integer representing the number of
|
||||||
|
descriptor pointers each channel fetch fifo can hold.
|
||||||
|
- fsl,exec-units-mask : The bitmask representing what execution units
|
||||||
|
(EUs) are available. It's a single 32-bit cell. EU information
|
||||||
|
should be encoded following the SEC's Descriptor Header Dword
|
||||||
|
EU_SEL0 field documentation, i.e. as follows:
|
||||||
|
|
||||||
|
bit 0 = reserved - should be 0
|
||||||
|
bit 1 = set if SEC has the ARC4 EU (AFEU)
|
||||||
|
bit 2 = set if SEC has the DES/3DES EU (DEU)
|
||||||
|
bit 3 = set if SEC has the message digest EU (MDEU/MDEU-A)
|
||||||
|
bit 4 = set if SEC has the random number generator EU (RNG)
|
||||||
|
bit 5 = set if SEC has the public key EU (PKEU)
|
||||||
|
bit 6 = set if SEC has the AES EU (AESU)
|
||||||
|
bit 7 = set if SEC has the Kasumi EU (KEU)
|
||||||
|
bit 8 = set if SEC has the CRC EU (CRCU)
|
||||||
|
bit 11 = set if SEC has the message digest EU extended alg set (MDEU-B)
|
||||||
|
|
||||||
|
remaining bits are reserved for future SEC EUs.
|
||||||
|
|
||||||
|
- fsl,descriptor-types-mask : The bitmask representing what descriptors
|
||||||
|
are available. It's a single 32-bit cell. Descriptor type information
|
||||||
|
should be encoded following the SEC's Descriptor Header Dword DESC_TYPE
|
||||||
|
field documentation, i.e. as follows:
|
||||||
|
|
||||||
|
bit 0 = set if SEC supports the aesu_ctr_nonsnoop desc. type
|
||||||
|
bit 1 = set if SEC supports the ipsec_esp descriptor type
|
||||||
|
bit 2 = set if SEC supports the common_nonsnoop desc. type
|
||||||
|
bit 3 = set if SEC supports the 802.11i AES ccmp desc. type
|
||||||
|
bit 4 = set if SEC supports the hmac_snoop_no_afeu desc. type
|
||||||
|
bit 5 = set if SEC supports the srtp descriptor type
|
||||||
|
bit 6 = set if SEC supports the non_hmac_snoop_no_afeu desc.type
|
||||||
|
bit 7 = set if SEC supports the pkeu_assemble descriptor type
|
||||||
|
bit 8 = set if SEC supports the aesu_key_expand_output desc.type
|
||||||
|
bit 9 = set if SEC supports the pkeu_ptmul descriptor type
|
||||||
|
bit 10 = set if SEC supports the common_nonsnoop_afeu desc. type
|
||||||
|
bit 11 = set if SEC supports the pkeu_ptadd_dbl descriptor type
|
||||||
|
|
||||||
|
..and so on and so forth.
|
||||||
|
|
||||||
|
Optional properties:
|
||||||
|
|
||||||
|
- interrupt-parent : the phandle for the interrupt controller that
|
||||||
|
services interrupts for this device.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
/* MPC8548E */
|
||||||
|
crypto@30000 {
|
||||||
|
compatible = "fsl,sec2.1", "fsl,sec2.0";
|
||||||
|
reg = <0x30000 0x10000>;
|
||||||
|
interrupts = <29 2>;
|
||||||
|
interrupt-parent = <&mpic>;
|
||||||
|
fsl,num-channels = <4>;
|
||||||
|
fsl,channel-fifo-len = <24>;
|
||||||
|
fsl,exec-units-mask = <0xfe>;
|
||||||
|
fsl,descriptor-types-mask = <0x12b0ebf>;
|
||||||
|
};
|
|
@ -0,0 +1,24 @@
|
||||||
|
* SPI (Serial Peripheral Interface)
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- cell-index : SPI controller index.
|
||||||
|
- compatible : should be "fsl,spi".
|
||||||
|
- mode : the SPI operation mode, it can be "cpu" or "cpu-qe".
|
||||||
|
- reg : Offset and length of the register set for the device
|
||||||
|
- interrupts : <a b> where a is the interrupt number and b is a
|
||||||
|
field that represents an encoding of the sense and level
|
||||||
|
information for the interrupt. This should be encoded based on
|
||||||
|
the information in section 2) depending on the type of interrupt
|
||||||
|
controller you have.
|
||||||
|
- interrupt-parent : the phandle for the interrupt controller that
|
||||||
|
services interrupts for this device.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
spi@4c0 {
|
||||||
|
cell-index = <0>;
|
||||||
|
compatible = "fsl,spi";
|
||||||
|
reg = <4c0 40>;
|
||||||
|
interrupts = <82 0>;
|
||||||
|
interrupt-parent = <700>;
|
||||||
|
mode = "cpu";
|
||||||
|
};
|
|
@ -0,0 +1,38 @@
|
||||||
|
Freescale Synchronous Serial Interface
|
||||||
|
|
||||||
|
The SSI is a serial device that communicates with audio codecs. It can
|
||||||
|
be programmed in AC97, I2S, left-justified, or right-justified modes.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible : compatible list, containing "fsl,ssi"
|
||||||
|
- cell-index : the SSI, <0> = SSI1, <1> = SSI2, and so on
|
||||||
|
- reg : offset and length of the register set for the device
|
||||||
|
- interrupts : <a b> where a is the interrupt number and b is a
|
||||||
|
field that represents an encoding of the sense and
|
||||||
|
level information for the interrupt. This should be
|
||||||
|
encoded based on the information in section 2)
|
||||||
|
depending on the type of interrupt controller you
|
||||||
|
have.
|
||||||
|
- interrupt-parent : the phandle for the interrupt controller that
|
||||||
|
services interrupts for this device.
|
||||||
|
- fsl,mode : the operating mode for the SSI interface
|
||||||
|
"i2s-slave" - I2S mode, SSI is clock slave
|
||||||
|
"i2s-master" - I2S mode, SSI is clock master
|
||||||
|
"lj-slave" - left-justified mode, SSI is clock slave
|
||||||
|
"lj-master" - l.j. mode, SSI is clock master
|
||||||
|
"rj-slave" - right-justified mode, SSI is clock slave
|
||||||
|
"rj-master" - r.j., SSI is clock master
|
||||||
|
"ac97-slave" - AC97 mode, SSI is clock slave
|
||||||
|
"ac97-master" - AC97 mode, SSI is clock master
|
||||||
|
|
||||||
|
Optional properties:
|
||||||
|
- codec-handle : phandle to a 'codec' node that defines an audio
|
||||||
|
codec connected to this SSI. This node is typically
|
||||||
|
a child of an I2C or other control node.
|
||||||
|
|
||||||
|
Child 'codec' node required properties:
|
||||||
|
- compatible : compatible list, contains the name of the codec
|
||||||
|
|
||||||
|
Child 'codec' node optional properties:
|
||||||
|
- clock-frequency : The frequency of the input clock, which typically
|
||||||
|
comes from an on-board dedicated oscillator.
|
|
@ -0,0 +1,69 @@
|
||||||
|
* MDIO IO device
|
||||||
|
|
||||||
|
The MDIO is a bus to which the PHY devices are connected. For each
|
||||||
|
device that exists on this bus, a child node should be created. See
|
||||||
|
the definition of the PHY node below for an example of how to define
|
||||||
|
a PHY.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- reg : Offset and length of the register set for the device
|
||||||
|
- compatible : Should define the compatible device type for the
|
||||||
|
mdio. Currently, this is most likely to be "fsl,gianfar-mdio"
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
mdio@24520 {
|
||||||
|
reg = <24520 20>;
|
||||||
|
compatible = "fsl,gianfar-mdio";
|
||||||
|
|
||||||
|
ethernet-phy@0 {
|
||||||
|
......
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
* Gianfar-compatible ethernet nodes
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
|
||||||
|
- device_type : Should be "network"
|
||||||
|
- model : Model of the device. Can be "TSEC", "eTSEC", or "FEC"
|
||||||
|
- compatible : Should be "gianfar"
|
||||||
|
- reg : Offset and length of the register set for the device
|
||||||
|
- mac-address : List of bytes representing the ethernet address of
|
||||||
|
this controller
|
||||||
|
- interrupts : <a b> where a is the interrupt number and b is a
|
||||||
|
field that represents an encoding of the sense and level
|
||||||
|
information for the interrupt. This should be encoded based on
|
||||||
|
the information in section 2) depending on the type of interrupt
|
||||||
|
controller you have.
|
||||||
|
- interrupt-parent : the phandle for the interrupt controller that
|
||||||
|
services interrupts for this device.
|
||||||
|
- phy-handle : The phandle for the PHY connected to this ethernet
|
||||||
|
controller.
|
||||||
|
- fixed-link : <a b c d e> where a is emulated phy id - choose any,
|
||||||
|
but unique to the all specified fixed-links, b is duplex - 0 half,
|
||||||
|
1 full, c is link speed - d#10/d#100/d#1000, d is pause - 0 no
|
||||||
|
pause, 1 pause, e is asym_pause - 0 no asym_pause, 1 asym_pause.
|
||||||
|
|
||||||
|
Recommended properties:
|
||||||
|
|
||||||
|
- phy-connection-type : a string naming the controller/PHY interface type,
|
||||||
|
i.e., "mii" (default), "rmii", "gmii", "rgmii", "rgmii-id", "sgmii",
|
||||||
|
"tbi", or "rtbi". This property is only really needed if the connection
|
||||||
|
is of type "rgmii-id", as all other connection types are detected by
|
||||||
|
hardware.
|
||||||
|
|
||||||
|
|
||||||
|
Example:
|
||||||
|
ethernet@24000 {
|
||||||
|
#size-cells = <0>;
|
||||||
|
device_type = "network";
|
||||||
|
model = "TSEC";
|
||||||
|
compatible = "gianfar";
|
||||||
|
reg = <24000 1000>;
|
||||||
|
mac-address = [ 00 E0 0C 00 73 00 ];
|
||||||
|
interrupts = <d 3 e 3 12 3>;
|
||||||
|
interrupt-parent = <40000>;
|
||||||
|
phy-handle = <2452000>
|
||||||
|
};
|
|
@ -0,0 +1,59 @@
|
||||||
|
Freescale SOC USB controllers
|
||||||
|
|
||||||
|
The device node for a USB controller that is part of a Freescale
|
||||||
|
SOC is as described in the document "Open Firmware Recommended
|
||||||
|
Practice : Universal Serial Bus" with the following modifications
|
||||||
|
and additions :
|
||||||
|
|
||||||
|
Required properties :
|
||||||
|
- compatible : Should be "fsl-usb2-mph" for multi port host USB
|
||||||
|
controllers, or "fsl-usb2-dr" for dual role USB controllers
|
||||||
|
- phy_type : For multi port host USB controllers, should be one of
|
||||||
|
"ulpi", or "serial". For dual role USB controllers, should be
|
||||||
|
one of "ulpi", "utmi", "utmi_wide", or "serial".
|
||||||
|
- reg : Offset and length of the register set for the device
|
||||||
|
- port0 : boolean; if defined, indicates port0 is connected for
|
||||||
|
fsl-usb2-mph compatible controllers. Either this property or
|
||||||
|
"port1" (or both) must be defined for "fsl-usb2-mph" compatible
|
||||||
|
controllers.
|
||||||
|
- port1 : boolean; if defined, indicates port1 is connected for
|
||||||
|
fsl-usb2-mph compatible controllers. Either this property or
|
||||||
|
"port0" (or both) must be defined for "fsl-usb2-mph" compatible
|
||||||
|
controllers.
|
||||||
|
- dr_mode : indicates the working mode for "fsl-usb2-dr" compatible
|
||||||
|
controllers. Can be "host", "peripheral", or "otg". Default to
|
||||||
|
"host" if not defined for backward compatibility.
|
||||||
|
|
||||||
|
Recommended properties :
|
||||||
|
- interrupts : <a b> where a is the interrupt number and b is a
|
||||||
|
field that represents an encoding of the sense and level
|
||||||
|
information for the interrupt. This should be encoded based on
|
||||||
|
the information in section 2) depending on the type of interrupt
|
||||||
|
controller you have.
|
||||||
|
- interrupt-parent : the phandle for the interrupt controller that
|
||||||
|
services interrupts for this device.
|
||||||
|
|
||||||
|
Example multi port host USB controller device node :
|
||||||
|
usb@22000 {
|
||||||
|
compatible = "fsl-usb2-mph";
|
||||||
|
reg = <22000 1000>;
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
interrupt-parent = <700>;
|
||||||
|
interrupts = <27 1>;
|
||||||
|
phy_type = "ulpi";
|
||||||
|
port0;
|
||||||
|
port1;
|
||||||
|
};
|
||||||
|
|
||||||
|
Example dual role USB controller device node :
|
||||||
|
usb@23000 {
|
||||||
|
compatible = "fsl-usb2-dr";
|
||||||
|
reg = <23000 1000>;
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
interrupt-parent = <700>;
|
||||||
|
interrupts = <26 1>;
|
||||||
|
dr_mode = "otg";
|
||||||
|
phy = "ulpi";
|
||||||
|
};
|
|
@ -61,10 +61,7 @@ builder by #define'ing ARCH_HASH_SCHED_DOMAIN, and exporting your
|
||||||
arch_init_sched_domains function. This function will attach domains to all
|
arch_init_sched_domains function. This function will attach domains to all
|
||||||
CPUs using cpu_attach_domain.
|
CPUs using cpu_attach_domain.
|
||||||
|
|
||||||
Implementors should change the line
|
The sched-domains debugging infrastructure can be enabled by enabling
|
||||||
#undef SCHED_DOMAIN_DEBUG
|
CONFIG_SCHED_DEBUG. This enables an error checking parse of the sched domains
|
||||||
to
|
|
||||||
#define SCHED_DOMAIN_DEBUG
|
|
||||||
in kernel/sched.c as this enables an error checking parse of the sched domains
|
|
||||||
which should catch most possible errors (described above). It also prints out
|
which should catch most possible errors (described above). It also prints out
|
||||||
the domain structure in a visual format.
|
the domain structure in a visual format.
|
||||||
|
|
|
@ -51,9 +51,9 @@ needs only about 3% CPU time to do so, it can do with a 0.03 * 0.005s =
|
||||||
0.00015s. So this group can be scheduled with a period of 0.005s and a run time
|
0.00015s. So this group can be scheduled with a period of 0.005s and a run time
|
||||||
of 0.00015s.
|
of 0.00015s.
|
||||||
|
|
||||||
The remaining CPU time will be used for user input and other tass. Because
|
The remaining CPU time will be used for user input and other tasks. Because
|
||||||
realtime tasks have explicitly allocated the CPU time they need to perform
|
realtime tasks have explicitly allocated the CPU time they need to perform
|
||||||
their tasks, buffer underruns in the graphocs or audio can be eliminated.
|
their tasks, buffer underruns in the graphics or audio can be eliminated.
|
||||||
|
|
||||||
NOTE: the above example is not fully implemented as of yet (2.6.25). We still
|
NOTE: the above example is not fully implemented as of yet (2.6.25). We still
|
||||||
lack an EDF scheduler to make non-uniform periods usable.
|
lack an EDF scheduler to make non-uniform periods usable.
|
||||||
|
|
|
@ -56,19 +56,33 @@ Supported Cards/Chipsets
|
||||||
9005:0285:9005:02d1 Adaptec 5405 (Voodoo40)
|
9005:0285:9005:02d1 Adaptec 5405 (Voodoo40)
|
||||||
9005:0285:15d9:02d2 SMC AOC-USAS-S8i-LP
|
9005:0285:15d9:02d2 SMC AOC-USAS-S8i-LP
|
||||||
9005:0285:15d9:02d3 SMC AOC-USAS-S8iR-LP
|
9005:0285:15d9:02d3 SMC AOC-USAS-S8iR-LP
|
||||||
9005:0285:9005:02d4 Adaptec 2045 (Voodoo04 Lite)
|
9005:0285:9005:02d4 Adaptec ASR-2045 (Voodoo04 Lite)
|
||||||
9005:0285:9005:02d5 Adaptec 2405 (Voodoo40 Lite)
|
9005:0285:9005:02d5 Adaptec ASR-2405 (Voodoo40 Lite)
|
||||||
9005:0285:9005:02d6 Adaptec 2445 (Voodoo44 Lite)
|
9005:0285:9005:02d6 Adaptec ASR-2445 (Voodoo44 Lite)
|
||||||
9005:0285:9005:02d7 Adaptec 2805 (Voodoo80 Lite)
|
9005:0285:9005:02d7 Adaptec ASR-2805 (Voodoo80 Lite)
|
||||||
|
9005:0285:9005:02d8 Adaptec 5405G (Voodoo40 PM)
|
||||||
|
9005:0285:9005:02d9 Adaptec 5445G (Voodoo44 PM)
|
||||||
|
9005:0285:9005:02da Adaptec 5805G (Voodoo80 PM)
|
||||||
|
9005:0285:9005:02db Adaptec 5085G (Voodoo08 PM)
|
||||||
|
9005:0285:9005:02dc Adaptec 51245G (Voodoo124 PM)
|
||||||
|
9005:0285:9005:02dd Adaptec 51645G (Voodoo164 PM)
|
||||||
|
9005:0285:9005:02de Adaptec 52445G (Voodoo244 PM)
|
||||||
|
9005:0285:9005:02df Adaptec ASR-2045G (Voodoo04 Lite PM)
|
||||||
|
9005:0285:9005:02e0 Adaptec ASR-2405G (Voodoo40 Lite PM)
|
||||||
|
9005:0285:9005:02e1 Adaptec ASR-2445G (Voodoo44 Lite PM)
|
||||||
|
9005:0285:9005:02e2 Adaptec ASR-2805G (Voodoo80 Lite PM)
|
||||||
1011:0046:9005:0364 Adaptec 5400S (Mustang)
|
1011:0046:9005:0364 Adaptec 5400S (Mustang)
|
||||||
|
1011:0046:9005:0365 Adaptec 5400S (Mustang)
|
||||||
9005:0287:9005:0800 Adaptec Themisto (Jupiter)
|
9005:0287:9005:0800 Adaptec Themisto (Jupiter)
|
||||||
9005:0200:9005:0200 Adaptec Themisto (Jupiter)
|
9005:0200:9005:0200 Adaptec Themisto (Jupiter)
|
||||||
9005:0286:9005:0800 Adaptec Callisto (Jupiter)
|
9005:0286:9005:0800 Adaptec Callisto (Jupiter)
|
||||||
1011:0046:9005:1364 Dell PERC 2/QC (Quad Channel, Mustang)
|
1011:0046:9005:1364 Dell PERC 2/QC (Quad Channel, Mustang)
|
||||||
|
1011:0046:9005:1365 Dell PERC 2/QC (Quad Channel, Mustang)
|
||||||
1028:0001:1028:0001 Dell PERC 2/Si (Iguana)
|
1028:0001:1028:0001 Dell PERC 2/Si (Iguana)
|
||||||
1028:0003:1028:0003 Dell PERC 3/Si (SlimFast)
|
1028:0003:1028:0003 Dell PERC 3/Si (SlimFast)
|
||||||
1028:0002:1028:0002 Dell PERC 3/Di (Opal)
|
1028:0002:1028:0002 Dell PERC 3/Di (Opal)
|
||||||
1028:0004:1028:0004 Dell PERC 3/DiF (Iguana)
|
1028:0004:1028:0004 Dell PERC 3/SiF (Iguana)
|
||||||
|
1028:0004:1028:00d0 Dell PERC 3/DiF (Iguana)
|
||||||
1028:0002:1028:00d1 Dell PERC 3/DiV (Viper)
|
1028:0002:1028:00d1 Dell PERC 3/DiV (Viper)
|
||||||
1028:0002:1028:00d9 Dell PERC 3/DiL (Lexus)
|
1028:0002:1028:00d9 Dell PERC 3/DiL (Lexus)
|
||||||
1028:000a:1028:0106 Dell PERC 3/DiJ (Jaguar)
|
1028:000a:1028:0106 Dell PERC 3/DiJ (Jaguar)
|
||||||
|
|
|
@ -753,8 +753,11 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||||
|
|
||||||
[Multiple options for each card instance]
|
[Multiple options for each card instance]
|
||||||
model - force the model name
|
model - force the model name
|
||||||
position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)
|
position_fix - Fix DMA pointer (0 = auto, 1 = use LPIB, 2 = POSBUF)
|
||||||
probe_mask - Bitmask to probe codecs (default = -1, meaning all slots)
|
probe_mask - Bitmask to probe codecs (default = -1, meaning all slots)
|
||||||
|
bdl_pos_adj - Specifies the DMA IRQ timing delay in samples.
|
||||||
|
Passing -1 will make the driver to choose the appropriate
|
||||||
|
value based on the controller chip.
|
||||||
|
|
||||||
[Single (global) options]
|
[Single (global) options]
|
||||||
single_cmd - Use single immediate commands to communicate with
|
single_cmd - Use single immediate commands to communicate with
|
||||||
|
@ -845,7 +848,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||||
ALC269
|
ALC269
|
||||||
basic Basic preset
|
basic Basic preset
|
||||||
|
|
||||||
ALC662
|
ALC662/663
|
||||||
3stack-dig 3-stack (2-channel) with SPDIF
|
3stack-dig 3-stack (2-channel) with SPDIF
|
||||||
3stack-6ch 3-stack (6-channel)
|
3stack-6ch 3-stack (6-channel)
|
||||||
3stack-6ch-dig 3-stack (6-channel) with SPDIF
|
3stack-6ch-dig 3-stack (6-channel) with SPDIF
|
||||||
|
@ -853,6 +856,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||||
lenovo-101e Lenovo laptop
|
lenovo-101e Lenovo laptop
|
||||||
eeepc-p701 ASUS Eeepc P701
|
eeepc-p701 ASUS Eeepc P701
|
||||||
eeepc-ep20 ASUS Eeepc EP20
|
eeepc-ep20 ASUS Eeepc EP20
|
||||||
|
m51va ASUS M51VA
|
||||||
|
g71v ASUS G71V
|
||||||
|
h13 ASUS H13
|
||||||
|
g50v ASUS G50V
|
||||||
auto auto-config reading BIOS (default)
|
auto auto-config reading BIOS (default)
|
||||||
|
|
||||||
ALC882/885
|
ALC882/885
|
||||||
|
@ -1091,7 +1098,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||||
This occurs when the access to non-existing or non-working codec slot
|
This occurs when the access to non-existing or non-working codec slot
|
||||||
(likely a modem one) causes a stall of the communication via HD-audio
|
(likely a modem one) causes a stall of the communication via HD-audio
|
||||||
bus. You can see which codec slots are probed by enabling
|
bus. You can see which codec slots are probed by enabling
|
||||||
CONFIG_SND_DEBUG_DETECT, or simply from the file name of the codec
|
CONFIG_SND_DEBUG_VERBOSE, or simply from the file name of the codec
|
||||||
proc files. Then limit the slots to probe by probe_mask option.
|
proc files. Then limit the slots to probe by probe_mask option.
|
||||||
For example, probe_mask=1 means to probe only the first slot, and
|
For example, probe_mask=1 means to probe only the first slot, and
|
||||||
probe_mask=4 means only the third slot.
|
probe_mask=4 means only the third slot.
|
||||||
|
@ -2267,6 +2274,10 @@ case above again, the first two slots are already reserved. If any
|
||||||
other driver (e.g. snd-usb-audio) is loaded before snd-interwave or
|
other driver (e.g. snd-usb-audio) is loaded before snd-interwave or
|
||||||
snd-ens1371, it will be assigned to the third or later slot.
|
snd-ens1371, it will be assigned to the third or later slot.
|
||||||
|
|
||||||
|
When a module name is given with '!', the slot will be given for any
|
||||||
|
modules but that name. For example, "slots=!snd-pcsp" will reserve
|
||||||
|
the first slot for any modules but snd-pcsp.
|
||||||
|
|
||||||
|
|
||||||
ALSA PCM devices to OSS devices mapping
|
ALSA PCM devices to OSS devices mapping
|
||||||
=======================================
|
=======================================
|
||||||
|
|
|
@ -6127,8 +6127,8 @@ struct _snd_pcm_runtime {
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
<function>snd_printdd()</function> is compiled in only when
|
<function>snd_printdd()</function> is compiled in only when
|
||||||
<constant>CONFIG_SND_DEBUG_DETECT</constant> is set. Please note
|
<constant>CONFIG_SND_DEBUG_VERBOSE</constant> is set. Please note
|
||||||
that <constant>DEBUG_DETECT</constant> is not set as default
|
that <constant>CONFIG_SND_DEBUG_VERBOSE</constant> is not set as default
|
||||||
even if you configure the alsa-driver with
|
even if you configure the alsa-driver with
|
||||||
<option>--with-debug=full</option> option. You need to give
|
<option>--with-debug=full</option> option. You need to give
|
||||||
explicitly <option>--with-debug=detect</option> option instead.
|
explicitly <option>--with-debug=detect</option> option instead.
|
||||||
|
|
|
@ -0,0 +1,164 @@
|
||||||
|
In-kernel memory-mapped I/O tracing
|
||||||
|
|
||||||
|
|
||||||
|
Home page and links to optional user space tools:
|
||||||
|
|
||||||
|
http://nouveau.freedesktop.org/wiki/MmioTrace
|
||||||
|
|
||||||
|
MMIO tracing was originally developed by Intel around 2003 for their Fault
|
||||||
|
Injection Test Harness. In Dec 2006 - Jan 2007, using the code from Intel,
|
||||||
|
Jeff Muizelaar created a tool for tracing MMIO accesses with the Nouveau
|
||||||
|
project in mind. Since then many people have contributed.
|
||||||
|
|
||||||
|
Mmiotrace was built for reverse engineering any memory-mapped IO device with
|
||||||
|
the Nouveau project as the first real user. Only x86 and x86_64 architectures
|
||||||
|
are supported.
|
||||||
|
|
||||||
|
Out-of-tree mmiotrace was originally modified for mainline inclusion and
|
||||||
|
ftrace framework by Pekka Paalanen <pq@iki.fi>.
|
||||||
|
|
||||||
|
|
||||||
|
Preparation
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Mmiotrace feature is compiled in by the CONFIG_MMIOTRACE option. Tracing is
|
||||||
|
disabled by default, so it is safe to have this set to yes. SMP systems are
|
||||||
|
supported, but tracing is unreliable and may miss events if more than one CPU
|
||||||
|
is on-line, therefore mmiotrace takes all but one CPU off-line during run-time
|
||||||
|
activation. You can re-enable CPUs by hand, but you have been warned, there
|
||||||
|
is no way to automatically detect if you are losing events due to CPUs racing.
|
||||||
|
|
||||||
|
|
||||||
|
Usage Quick Reference
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
$ mount -t debugfs debugfs /debug
|
||||||
|
$ echo mmiotrace > /debug/tracing/current_tracer
|
||||||
|
$ cat /debug/tracing/trace_pipe > mydump.txt &
|
||||||
|
Start X or whatever.
|
||||||
|
$ echo "X is up" > /debug/tracing/marker
|
||||||
|
$ echo none > /debug/tracing/current_tracer
|
||||||
|
Check for lost events.
|
||||||
|
|
||||||
|
|
||||||
|
Usage
|
||||||
|
-----
|
||||||
|
|
||||||
|
Make sure debugfs is mounted to /debug. If not, (requires root privileges)
|
||||||
|
$ mount -t debugfs debugfs /debug
|
||||||
|
|
||||||
|
Check that the driver you are about to trace is not loaded.
|
||||||
|
|
||||||
|
Activate mmiotrace (requires root privileges):
|
||||||
|
$ echo mmiotrace > /debug/tracing/current_tracer
|
||||||
|
|
||||||
|
Start storing the trace:
|
||||||
|
$ cat /debug/tracing/trace_pipe > mydump.txt &
|
||||||
|
The 'cat' process should stay running (sleeping) in the background.
|
||||||
|
|
||||||
|
Load the driver you want to trace and use it. Mmiotrace will only catch MMIO
|
||||||
|
accesses to areas that are ioremapped while mmiotrace is active.
|
||||||
|
|
||||||
|
[Unimplemented feature:]
|
||||||
|
During tracing you can place comments (markers) into the trace by
|
||||||
|
$ echo "X is up" > /debug/tracing/marker
|
||||||
|
This makes it easier to see which part of the (huge) trace corresponds to
|
||||||
|
which action. It is recommended to place descriptive markers about what you
|
||||||
|
do.
|
||||||
|
|
||||||
|
Shut down mmiotrace (requires root privileges):
|
||||||
|
$ echo none > /debug/tracing/current_tracer
|
||||||
|
The 'cat' process exits. If it does not, kill it by issuing 'fg' command and
|
||||||
|
pressing ctrl+c.
|
||||||
|
|
||||||
|
Check that mmiotrace did not lose events due to a buffer filling up. Either
|
||||||
|
$ grep -i lost mydump.txt
|
||||||
|
which tells you exactly how many events were lost, or use
|
||||||
|
$ dmesg
|
||||||
|
to view your kernel log and look for "mmiotrace has lost events" warning. If
|
||||||
|
events were lost, the trace is incomplete. You should enlarge the buffers and
|
||||||
|
try again. Buffers are enlarged by first seeing how large the current buffers
|
||||||
|
are:
|
||||||
|
$ cat /debug/tracing/trace_entries
|
||||||
|
gives you a number. Approximately double this number and write it back, for
|
||||||
|
instance:
|
||||||
|
$ echo 128000 > /debug/tracing/trace_entries
|
||||||
|
Then start again from the top.
|
||||||
|
|
||||||
|
If you are doing a trace for a driver project, e.g. Nouveau, you should also
|
||||||
|
do the following before sending your results:
|
||||||
|
$ lspci -vvv > lspci.txt
|
||||||
|
$ dmesg > dmesg.txt
|
||||||
|
$ tar zcf pciid-nick-mmiotrace.tar.gz mydump.txt lspci.txt dmesg.txt
|
||||||
|
and then send the .tar.gz file. The trace compresses considerably. Replace
|
||||||
|
"pciid" and "nick" with the PCI ID or model name of your piece of hardware
|
||||||
|
under investigation and your nick name.
|
||||||
|
|
||||||
|
|
||||||
|
How Mmiotrace Works
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
Access to hardware IO-memory is gained by mapping addresses from PCI bus by
|
||||||
|
calling one of the ioremap_*() functions. Mmiotrace is hooked into the
|
||||||
|
__ioremap() function and gets called whenever a mapping is created. Mapping is
|
||||||
|
an event that is recorded into the trace log. Note, that ISA range mappings
|
||||||
|
are not caught, since the mapping always exists and is returned directly.
|
||||||
|
|
||||||
|
MMIO accesses are recorded via page faults. Just before __ioremap() returns,
|
||||||
|
the mapped pages are marked as not present. Any access to the pages causes a
|
||||||
|
fault. The page fault handler calls mmiotrace to handle the fault. Mmiotrace
|
||||||
|
marks the page present, sets TF flag to achieve single stepping and exits the
|
||||||
|
fault handler. The instruction that faulted is executed and debug trap is
|
||||||
|
entered. Here mmiotrace again marks the page as not present. The instruction
|
||||||
|
is decoded to get the type of operation (read/write), data width and the value
|
||||||
|
read or written. These are stored to the trace log.
|
||||||
|
|
||||||
|
Setting the page present in the page fault handler has a race condition on SMP
|
||||||
|
machines. During the single stepping other CPUs may run freely on that page
|
||||||
|
and events can be missed without a notice. Re-enabling other CPUs during
|
||||||
|
tracing is discouraged.
|
||||||
|
|
||||||
|
|
||||||
|
Trace Log Format
|
||||||
|
----------------
|
||||||
|
|
||||||
|
The raw log is text and easily filtered with e.g. grep and awk. One record is
|
||||||
|
one line in the log. A record starts with a keyword, followed by keyword
|
||||||
|
dependant arguments. Arguments are separated by a space, or continue until the
|
||||||
|
end of line. The format for version 20070824 is as follows:
|
||||||
|
|
||||||
|
Explanation Keyword Space separated arguments
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
read event R width, timestamp, map id, physical, value, PC, PID
|
||||||
|
write event W width, timestamp, map id, physical, value, PC, PID
|
||||||
|
ioremap event MAP timestamp, map id, physical, virtual, length, PC, PID
|
||||||
|
iounmap event UNMAP timestamp, map id, PC, PID
|
||||||
|
marker MARK timestamp, text
|
||||||
|
version VERSION the string "20070824"
|
||||||
|
info for reader LSPCI one line from lspci -v
|
||||||
|
PCI address map PCIDEV space separated /proc/bus/pci/devices data
|
||||||
|
unk. opcode UNKNOWN timestamp, map id, physical, data, PC, PID
|
||||||
|
|
||||||
|
Timestamp is in seconds with decimals. Physical is a PCI bus address, virtual
|
||||||
|
is a kernel virtual address. Width is the data width in bytes and value is the
|
||||||
|
data value. Map id is an arbitrary id number identifying the mapping that was
|
||||||
|
used in an operation. PC is the program counter and PID is process id. PC is
|
||||||
|
zero if it is not recorded. PID is always zero as tracing MMIO accesses
|
||||||
|
originating in user space memory is not yet supported.
|
||||||
|
|
||||||
|
For instance, the following awk filter will pass all 32-bit writes that target
|
||||||
|
physical addresses in the range [0xfb73ce40, 0xfb800000[
|
||||||
|
|
||||||
|
$ awk '/W 4 / { adr=strtonum($5); if (adr >= 0xfb73ce40 &&
|
||||||
|
adr < 0xfb800000) print; }'
|
||||||
|
|
||||||
|
|
||||||
|
Tools for Developers
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
The user space tools include utilities for:
|
||||||
|
- replacing numeric addresses and values with hardware register names
|
||||||
|
- replaying MMIO logs, i.e., re-executing the recorded writes
|
||||||
|
|
||||||
|
|
84
MAINTAINERS
84
MAINTAINERS
|
@ -216,8 +216,8 @@ W: http://code.google.com/p/aceracpi
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
ACPI
|
ACPI
|
||||||
P: Len Brown
|
P: Andi Kleen
|
||||||
M: len.brown@intel.com
|
M: ak@linux.intel.com
|
||||||
M: lenb@kernel.org
|
M: lenb@kernel.org
|
||||||
L: linux-acpi@vger.kernel.org
|
L: linux-acpi@vger.kernel.org
|
||||||
W: http://www.lesswatts.org/projects/acpi/
|
W: http://www.lesswatts.org/projects/acpi/
|
||||||
|
@ -239,8 +239,8 @@ W: http://www.lesswatts.org/projects/acpi/
|
||||||
S: Supported
|
S: Supported
|
||||||
|
|
||||||
ACPI FAN DRIVER
|
ACPI FAN DRIVER
|
||||||
P: Len Brown
|
P: Zhang Rui
|
||||||
M: len.brown@intel.com
|
M: rui.zhang@intel.com
|
||||||
L: linux-acpi@vger.kernel.org
|
L: linux-acpi@vger.kernel.org
|
||||||
W: http://www.lesswatts.org/projects/acpi/
|
W: http://www.lesswatts.org/projects/acpi/
|
||||||
S: Supported
|
S: Supported
|
||||||
|
@ -248,18 +248,18 @@ S: Supported
|
||||||
ACPI PCI HOTPLUG DRIVER
|
ACPI PCI HOTPLUG DRIVER
|
||||||
P: Kristen Carlson Accardi
|
P: Kristen Carlson Accardi
|
||||||
M: kristen.c.accardi@intel.com
|
M: kristen.c.accardi@intel.com
|
||||||
L: pcihpd-discuss@lists.sourceforge.net
|
L: linux-pci@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
|
|
||||||
ACPI THERMAL DRIVER
|
ACPI THERMAL DRIVER
|
||||||
P: Len Brown
|
P: Zhang Rui
|
||||||
M: len.brown@intel.com
|
M: rui.zhang@intel.com
|
||||||
L: linux-acpi@vger.kernel.org
|
L: linux-acpi@vger.kernel.org
|
||||||
W: http://www.lesswatts.org/projects/acpi/
|
W: http://www.lesswatts.org/projects/acpi/
|
||||||
S: Supported
|
S: Supported
|
||||||
|
|
||||||
ACPI VIDEO DRIVER
|
ACPI VIDEO DRIVER
|
||||||
P: Rui Zhang
|
P: Zhang Rui
|
||||||
M: rui.zhang@intel.com
|
M: rui.zhang@intel.com
|
||||||
L: linux-acpi@vger.kernel.org
|
L: linux-acpi@vger.kernel.org
|
||||||
W: http://www.lesswatts.org/projects/acpi/
|
W: http://www.lesswatts.org/projects/acpi/
|
||||||
|
@ -348,7 +348,9 @@ W: http://www.linux-usb.org/SpeedTouch/
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
ALCHEMY AU1XX0 MMC DRIVER
|
ALCHEMY AU1XX0 MMC DRIVER
|
||||||
S: Orphan
|
P: Manuel Lauss
|
||||||
|
M: manuel.lauss@gmail.com
|
||||||
|
S: Maintained
|
||||||
|
|
||||||
ALI1563 I2C DRIVER
|
ALI1563 I2C DRIVER
|
||||||
P: Rudolf Marek
|
P: Rudolf Marek
|
||||||
|
@ -1143,23 +1145,28 @@ COMPACTPCI HOTPLUG CORE
|
||||||
P: Scott Murray
|
P: Scott Murray
|
||||||
M: scottm@somanetworks.com
|
M: scottm@somanetworks.com
|
||||||
M: scott@spiteful.org
|
M: scott@spiteful.org
|
||||||
L: pcihpd-discuss@lists.sourceforge.net
|
L: linux-pci@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
|
|
||||||
COMPACTPCI HOTPLUG ZIATECH ZT5550 DRIVER
|
COMPACTPCI HOTPLUG ZIATECH ZT5550 DRIVER
|
||||||
P: Scott Murray
|
P: Scott Murray
|
||||||
M: scottm@somanetworks.com
|
M: scottm@somanetworks.com
|
||||||
M: scott@spiteful.org
|
M: scott@spiteful.org
|
||||||
L: pcihpd-discuss@lists.sourceforge.net
|
L: linux-pci@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
|
|
||||||
COMPACTPCI HOTPLUG GENERIC DRIVER
|
COMPACTPCI HOTPLUG GENERIC DRIVER
|
||||||
P: Scott Murray
|
P: Scott Murray
|
||||||
M: scottm@somanetworks.com
|
M: scottm@somanetworks.com
|
||||||
M: scott@spiteful.org
|
M: scott@spiteful.org
|
||||||
L: pcihpd-discuss@lists.sourceforge.net
|
L: linux-pci@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
|
|
||||||
|
COMPAL LAPTOP SUPPORT
|
||||||
|
P: Cezary Jackiewicz
|
||||||
|
M: cezary.jackiewicz@gmail.com
|
||||||
|
S: Maintained
|
||||||
|
|
||||||
COMPUTONE INTELLIPORT MULTIPORT CARD
|
COMPUTONE INTELLIPORT MULTIPORT CARD
|
||||||
P: Michael H. Warfield
|
P: Michael H. Warfield
|
||||||
M: mhw@wittsend.com
|
M: mhw@wittsend.com
|
||||||
|
@ -1686,6 +1693,13 @@ L: linuxppc-embedded@ozlabs.org
|
||||||
L: linux-kernel@vger.kernel.org
|
L: linux-kernel@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
FREESCALE I2C CPM DRIVER
|
||||||
|
P: Jochen Friedrich
|
||||||
|
M: jochen@scram.de
|
||||||
|
L: linuxppc-dev@ozlabs.org
|
||||||
|
L: i2c@lm-sensors.org
|
||||||
|
S: Maintained
|
||||||
|
|
||||||
FREESCALE SOC FS_ENET DRIVER
|
FREESCALE SOC FS_ENET DRIVER
|
||||||
P: Pantelis Antoniou
|
P: Pantelis Antoniou
|
||||||
M: pantelis.antoniou@gmail.com
|
M: pantelis.antoniou@gmail.com
|
||||||
|
@ -1770,11 +1784,22 @@ M: hch@infradead.org
|
||||||
W: ftp://ftp.openlinux.org/pub/people/hch/vxfs
|
W: ftp://ftp.openlinux.org/pub/people/hch/vxfs
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
FTRACE
|
||||||
|
P: Steven Rostedt
|
||||||
|
M: srostedt@redhat.com
|
||||||
|
S: Maintained
|
||||||
|
|
||||||
FUJITSU FR-V (FRV) PORT
|
FUJITSU FR-V (FRV) PORT
|
||||||
P: David Howells
|
P: David Howells
|
||||||
M: dhowells@redhat.com
|
M: dhowells@redhat.com
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
FUJITSU LAPTOP EXTRAS
|
||||||
|
P: Jonathan Woithe
|
||||||
|
M: jwoithe@physics.adelaide.edu.au
|
||||||
|
L: linux-acpi@vger.kernel.org
|
||||||
|
S: Maintained
|
||||||
|
|
||||||
FUSE: FILESYSTEM IN USERSPACE
|
FUSE: FILESYSTEM IN USERSPACE
|
||||||
P: Miklos Szeredi
|
P: Miklos Szeredi
|
||||||
M: miklos@szeredi.hu
|
M: miklos@szeredi.hu
|
||||||
|
@ -2313,6 +2338,16 @@ L: linux-mtd@lists.infradead.org
|
||||||
W: http://www.linux-mtd.infradead.org/doc/jffs2.html
|
W: http://www.linux-mtd.infradead.org/doc/jffs2.html
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
UBI FILE SYSTEM (UBIFS)
|
||||||
|
P: Artem Bityutskiy
|
||||||
|
M: dedekind@infradead.org
|
||||||
|
P: Adrian Hunter
|
||||||
|
M: ext-adrian.hunter@nokia.com
|
||||||
|
L: linux-mtd@lists.infradead.org
|
||||||
|
T: git git://git.infradead.org/~dedekind/ubifs-2.6.git
|
||||||
|
W: http://www.linux-mtd.infradead.org/doc/ubifs.html
|
||||||
|
S: Maintained
|
||||||
|
|
||||||
JFS FILESYSTEM
|
JFS FILESYSTEM
|
||||||
P: Dave Kleikamp
|
P: Dave Kleikamp
|
||||||
M: shaggy@austin.ibm.com
|
M: shaggy@austin.ibm.com
|
||||||
|
@ -2509,13 +2544,11 @@ W: http://www.penguinppc.org/
|
||||||
L: linuxppc-dev@ozlabs.org
|
L: linuxppc-dev@ozlabs.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
LINUX FOR POWERPC EMBEDDED MPC52XX
|
LINUX FOR POWERPC EMBEDDED MPC5XXX
|
||||||
P: Sylvain Munaut
|
P: Sylvain Munaut
|
||||||
M: tnt@246tNt.com
|
M: tnt@246tNt.com
|
||||||
P: Grant Likely
|
P: Grant Likely
|
||||||
M: grant.likely@secretlab.ca
|
M: grant.likely@secretlab.ca
|
||||||
W: http://www.246tNt.com/mpc52xx/
|
|
||||||
W: http://www.penguinppc.org/
|
|
||||||
L: linuxppc-dev@ozlabs.org
|
L: linuxppc-dev@ozlabs.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
@ -3088,8 +3121,8 @@ L: linux-scsi@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
OPROFILE
|
OPROFILE
|
||||||
P: Philippe Elie
|
P: Robert Richter
|
||||||
M: phil.el@wanadoo.fr
|
M: robert.richter@amd.com
|
||||||
L: oprofile-list@lists.sf.net
|
L: oprofile-list@lists.sf.net
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
@ -3186,7 +3219,7 @@ S: Supported
|
||||||
PCIE HOTPLUG DRIVER
|
PCIE HOTPLUG DRIVER
|
||||||
P: Kristen Carlson Accardi
|
P: Kristen Carlson Accardi
|
||||||
M: kristen.c.accardi@intel.com
|
M: kristen.c.accardi@intel.com
|
||||||
L: pcihpd-discuss@lists.sourceforge.net
|
L: linux-pci@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
|
|
||||||
PCMCIA SUBSYSTEM
|
PCMCIA SUBSYSTEM
|
||||||
|
@ -3528,6 +3561,13 @@ L: linux-s390@vger.kernel.org
|
||||||
W: http://www.ibm.com/developerworks/linux/linux390/
|
W: http://www.ibm.com/developerworks/linux/linux390/
|
||||||
S: Supported
|
S: Supported
|
||||||
|
|
||||||
|
S3C24XX SD/MMC Driver
|
||||||
|
P: Ben Dooks
|
||||||
|
M: ben-linux@fluff.org
|
||||||
|
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
|
||||||
|
L: linux-kernel@vger.kernel.org
|
||||||
|
S: Supported
|
||||||
|
|
||||||
SAA7146 VIDEO4LINUX-2 DRIVER
|
SAA7146 VIDEO4LINUX-2 DRIVER
|
||||||
P: Michael Hunold
|
P: Michael Hunold
|
||||||
M: michael@mihu.de
|
M: michael@mihu.de
|
||||||
|
@ -3600,6 +3640,12 @@ P: Jim Cromie
|
||||||
M: jim.cromie@gmail.com
|
M: jim.cromie@gmail.com
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
SDRICOH_CS MMC/SD HOST CONTROLLER INTERFACE DRIVER
|
||||||
|
P: Sascha Sommer
|
||||||
|
M: saschasommer@freenet.de
|
||||||
|
L: sdricohcs-devel@lists.sourceforge.net (subscribers-only)
|
||||||
|
S: Maintained
|
||||||
|
|
||||||
SECURITY CONTACT
|
SECURITY CONTACT
|
||||||
P: Security Officers
|
P: Security Officers
|
||||||
M: security@kernel.org
|
M: security@kernel.org
|
||||||
|
@ -3819,7 +3865,7 @@ S: Maintained
|
||||||
SHPC HOTPLUG DRIVER
|
SHPC HOTPLUG DRIVER
|
||||||
P: Kristen Carlson Accardi
|
P: Kristen Carlson Accardi
|
||||||
M: kristen.c.accardi@intel.com
|
M: kristen.c.accardi@intel.com
|
||||||
L: pcihpd-discuss@lists.sourceforge.net
|
L: linux-pci@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
|
|
||||||
SECURE DIGITAL HOST CONTROLLER INTERFACE DRIVER
|
SECURE DIGITAL HOST CONTROLLER INTERFACE DRIVER
|
||||||
|
|
25
Makefile
25
Makefile
|
@ -1,7 +1,7 @@
|
||||||
VERSION = 2
|
VERSION = 2
|
||||||
PATCHLEVEL = 6
|
PATCHLEVEL = 6
|
||||||
SUBLEVEL = 26
|
SUBLEVEL = 26
|
||||||
EXTRAVERSION = -rc9
|
EXTRAVERSION =
|
||||||
NAME = Rotary Wombat
|
NAME = Rotary Wombat
|
||||||
|
|
||||||
# *DOCUMENTATION*
|
# *DOCUMENTATION*
|
||||||
|
@ -450,7 +450,7 @@ scripts: scripts_basic include/config/auto.conf
|
||||||
|
|
||||||
# Objects we will link into vmlinux / subdirs we need to visit
|
# Objects we will link into vmlinux / subdirs we need to visit
|
||||||
init-y := init/
|
init-y := init/
|
||||||
drivers-y := drivers/ sound/
|
drivers-y := drivers/ sound/ firmware/
|
||||||
net-y := net/
|
net-y := net/
|
||||||
libs-y := lib/
|
libs-y := lib/
|
||||||
core-y := usr/
|
core-y := usr/
|
||||||
|
@ -507,6 +507,8 @@ else
|
||||||
KBUILD_CFLAGS += -O2
|
KBUILD_CFLAGS += -O2
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
include $(srctree)/arch/$(SRCARCH)/Makefile
|
||||||
|
|
||||||
ifneq (CONFIG_FRAME_WARN,0)
|
ifneq (CONFIG_FRAME_WARN,0)
|
||||||
KBUILD_CFLAGS += $(call cc-option,-Wframe-larger-than=${CONFIG_FRAME_WARN})
|
KBUILD_CFLAGS += $(call cc-option,-Wframe-larger-than=${CONFIG_FRAME_WARN})
|
||||||
endif
|
endif
|
||||||
|
@ -515,8 +517,6 @@ endif
|
||||||
# Arch Makefiles may override this setting
|
# Arch Makefiles may override this setting
|
||||||
KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector)
|
KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector)
|
||||||
|
|
||||||
include $(srctree)/arch/$(SRCARCH)/Makefile
|
|
||||||
|
|
||||||
ifdef CONFIG_FRAME_POINTER
|
ifdef CONFIG_FRAME_POINTER
|
||||||
KBUILD_CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls
|
KBUILD_CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls
|
||||||
else
|
else
|
||||||
|
@ -528,6 +528,10 @@ KBUILD_CFLAGS += -g
|
||||||
KBUILD_AFLAGS += -gdwarf-2
|
KBUILD_AFLAGS += -gdwarf-2
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_FTRACE
|
||||||
|
KBUILD_CFLAGS += -pg
|
||||||
|
endif
|
||||||
|
|
||||||
# We trigger additional mismatches with less inlining
|
# We trigger additional mismatches with less inlining
|
||||||
ifdef CONFIG_DEBUG_SECTION_MISMATCH
|
ifdef CONFIG_DEBUG_SECTION_MISMATCH
|
||||||
KBUILD_CFLAGS += $(call cc-option, -fno-inline-functions-called-once)
|
KBUILD_CFLAGS += $(call cc-option, -fno-inline-functions-called-once)
|
||||||
|
@ -994,6 +998,16 @@ PHONY += depend dep
|
||||||
depend dep:
|
depend dep:
|
||||||
@echo '*** Warning: make $@ is unnecessary now.'
|
@echo '*** Warning: make $@ is unnecessary now.'
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Firmware install
|
||||||
|
INSTALL_FW_PATH=$(INSTALL_MOD_PATH)/lib/firmware
|
||||||
|
export INSTALL_FW_PATH
|
||||||
|
|
||||||
|
PHONY += firmware_install
|
||||||
|
firmware_install: FORCE
|
||||||
|
@mkdir -p $(objtree)/firmware
|
||||||
|
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_install
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Kernel headers
|
# Kernel headers
|
||||||
INSTALL_HDR_PATH=$(objtree)/usr
|
INSTALL_HDR_PATH=$(objtree)/usr
|
||||||
|
@ -1080,6 +1094,7 @@ _modinst_:
|
||||||
# boot script depmod is the master version.
|
# boot script depmod is the master version.
|
||||||
PHONY += _modinst_post
|
PHONY += _modinst_post
|
||||||
_modinst_post: _modinst_
|
_modinst_post: _modinst_
|
||||||
|
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_modinst
|
||||||
$(call cmd,depmod)
|
$(call cmd,depmod)
|
||||||
|
|
||||||
else # CONFIG_MODULES
|
else # CONFIG_MODULES
|
||||||
|
@ -1197,6 +1212,8 @@ help:
|
||||||
@echo '* vmlinux - Build the bare kernel'
|
@echo '* vmlinux - Build the bare kernel'
|
||||||
@echo '* modules - Build all modules'
|
@echo '* modules - Build all modules'
|
||||||
@echo ' modules_install - Install all modules to INSTALL_MOD_PATH (default: /)'
|
@echo ' modules_install - Install all modules to INSTALL_MOD_PATH (default: /)'
|
||||||
|
@echo ' firmware_install- Install all firmware to INSTALL_FW_PATH'
|
||||||
|
@echo ' (default: $$(INSTALL_MOD_PATH)/lib/firmware)'
|
||||||
@echo ' dir/ - Build all files in dir and below'
|
@echo ' dir/ - Build all files in dir and below'
|
||||||
@echo ' dir/file.[ois] - Build specified target only'
|
@echo ' dir/file.[ois] - Build specified target only'
|
||||||
@echo ' dir/file.ko - Build module including final link'
|
@echo ' dir/file.ko - Build module including final link'
|
||||||
|
|
|
@ -39,3 +39,6 @@ config HAVE_KRETPROBES
|
||||||
|
|
||||||
config HAVE_DMA_ATTRS
|
config HAVE_DMA_ATTRS
|
||||||
def_bool n
|
def_bool n
|
||||||
|
|
||||||
|
config USE_GENERIC_SMP_HELPERS
|
||||||
|
def_bool n
|
||||||
|
|
|
@ -528,6 +528,7 @@ config ARCH_MAY_HAVE_PC_FDC
|
||||||
config SMP
|
config SMP
|
||||||
bool "Symmetric multi-processing support"
|
bool "Symmetric multi-processing support"
|
||||||
depends on ALPHA_SABLE || ALPHA_LYNX || ALPHA_RAWHIDE || ALPHA_DP264 || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_GENERIC || ALPHA_SHARK || ALPHA_MARVEL
|
depends on ALPHA_SABLE || ALPHA_LYNX || ALPHA_RAWHIDE || ALPHA_DP264 || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_GENERIC || ALPHA_SHARK || ALPHA_MARVEL
|
||||||
|
select USE_GENERIC_SMP_HELPERS
|
||||||
---help---
|
---help---
|
||||||
This enables support for systems with more than one CPU. If you have
|
This enables support for systems with more than one CPU. If you have
|
||||||
a system with only one CPU, like most personal computers, say N. If
|
a system with only one CPU, like most personal computers, say N. If
|
||||||
|
|
|
@ -660,9 +660,9 @@ __marvel_rtc_io(u8 b, unsigned long addr, int write)
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
if (smp_processor_id() != boot_cpuid)
|
if (smp_processor_id() != boot_cpuid)
|
||||||
smp_call_function_on_cpu(__marvel_access_rtc,
|
smp_call_function_single(boot_cpuid,
|
||||||
&rtc_access, 1, 1,
|
__marvel_access_rtc,
|
||||||
cpumask_of_cpu(boot_cpuid));
|
&rtc_access, 1);
|
||||||
else
|
else
|
||||||
__marvel_access_rtc(&rtc_access);
|
__marvel_access_rtc(&rtc_access);
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -42,8 +42,7 @@ void ack_bad_irq(unsigned int irq)
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
static char irq_user_affinity[NR_IRQS];
|
static char irq_user_affinity[NR_IRQS];
|
||||||
|
|
||||||
int
|
int irq_select_affinity(unsigned int irq)
|
||||||
select_smp_affinity(unsigned int irq)
|
|
||||||
{
|
{
|
||||||
static int last_cpu;
|
static int last_cpu;
|
||||||
int cpu = last_cpu + 1;
|
int cpu = last_cpu + 1;
|
||||||
|
@ -51,7 +50,7 @@ select_smp_affinity(unsigned int irq)
|
||||||
if (!irq_desc[irq].chip->set_affinity || irq_user_affinity[irq])
|
if (!irq_desc[irq].chip->set_affinity || irq_user_affinity[irq])
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
while (!cpu_possible(cpu))
|
while (!cpu_possible(cpu) || !cpu_isset(cpu, irq_default_affinity))
|
||||||
cpu = (cpu < (NR_CPUS-1) ? cpu + 1 : 0);
|
cpu = (cpu < (NR_CPUS-1) ? cpu + 1 : 0);
|
||||||
last_cpu = cpu;
|
last_cpu = cpu;
|
||||||
|
|
||||||
|
|
|
@ -160,7 +160,7 @@ common_shutdown(int mode, char *restart_cmd)
|
||||||
struct halt_info args;
|
struct halt_info args;
|
||||||
args.mode = mode;
|
args.mode = mode;
|
||||||
args.restart_cmd = restart_cmd;
|
args.restart_cmd = restart_cmd;
|
||||||
on_each_cpu(common_shutdown_1, &args, 1, 0);
|
on_each_cpu(common_shutdown_1, &args, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -62,6 +62,7 @@ static struct {
|
||||||
enum ipi_message_type {
|
enum ipi_message_type {
|
||||||
IPI_RESCHEDULE,
|
IPI_RESCHEDULE,
|
||||||
IPI_CALL_FUNC,
|
IPI_CALL_FUNC,
|
||||||
|
IPI_CALL_FUNC_SINGLE,
|
||||||
IPI_CPU_STOP,
|
IPI_CPU_STOP,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -558,51 +559,6 @@ send_ipi_message(cpumask_t to_whom, enum ipi_message_type operation)
|
||||||
wripir(i);
|
wripir(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Structure and data for smp_call_function. This is designed to
|
|
||||||
minimize static memory requirements. Plus it looks cleaner. */
|
|
||||||
|
|
||||||
struct smp_call_struct {
|
|
||||||
void (*func) (void *info);
|
|
||||||
void *info;
|
|
||||||
long wait;
|
|
||||||
atomic_t unstarted_count;
|
|
||||||
atomic_t unfinished_count;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct smp_call_struct *smp_call_function_data;
|
|
||||||
|
|
||||||
/* Atomicly drop data into a shared pointer. The pointer is free if
|
|
||||||
it is initially locked. If retry, spin until free. */
|
|
||||||
|
|
||||||
static int
|
|
||||||
pointer_lock (void *lock, void *data, int retry)
|
|
||||||
{
|
|
||||||
void *old, *tmp;
|
|
||||||
|
|
||||||
mb();
|
|
||||||
again:
|
|
||||||
/* Compare and swap with zero. */
|
|
||||||
asm volatile (
|
|
||||||
"1: ldq_l %0,%1\n"
|
|
||||||
" mov %3,%2\n"
|
|
||||||
" bne %0,2f\n"
|
|
||||||
" stq_c %2,%1\n"
|
|
||||||
" beq %2,1b\n"
|
|
||||||
"2:"
|
|
||||||
: "=&r"(old), "=m"(*(void **)lock), "=&r"(tmp)
|
|
||||||
: "r"(data)
|
|
||||||
: "memory");
|
|
||||||
|
|
||||||
if (old == 0)
|
|
||||||
return 0;
|
|
||||||
if (! retry)
|
|
||||||
return -EBUSY;
|
|
||||||
|
|
||||||
while (*(void **)lock)
|
|
||||||
barrier();
|
|
||||||
goto again;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
handle_ipi(struct pt_regs *regs)
|
handle_ipi(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
|
@ -632,31 +588,12 @@ handle_ipi(struct pt_regs *regs)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IPI_CALL_FUNC:
|
case IPI_CALL_FUNC:
|
||||||
{
|
generic_smp_call_function_interrupt();
|
||||||
struct smp_call_struct *data;
|
break;
|
||||||
void (*func)(void *info);
|
|
||||||
void *info;
|
case IPI_CALL_FUNC_SINGLE:
|
||||||
int wait;
|
generic_smp_call_function_single_interrupt();
|
||||||
|
|
||||||
data = smp_call_function_data;
|
|
||||||
func = data->func;
|
|
||||||
info = data->info;
|
|
||||||
wait = data->wait;
|
|
||||||
|
|
||||||
/* Notify the sending CPU that the data has been
|
|
||||||
received, and execution is about to begin. */
|
|
||||||
mb();
|
|
||||||
atomic_dec (&data->unstarted_count);
|
|
||||||
|
|
||||||
/* At this point the structure may be gone unless
|
|
||||||
wait is true. */
|
|
||||||
(*func)(info);
|
|
||||||
|
|
||||||
/* Notify the sending CPU that the task is done. */
|
|
||||||
mb();
|
|
||||||
if (wait) atomic_dec (&data->unfinished_count);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case IPI_CPU_STOP:
|
case IPI_CPU_STOP:
|
||||||
halt();
|
halt();
|
||||||
|
@ -700,102 +637,15 @@ smp_send_stop(void)
|
||||||
send_ipi_message(to_whom, IPI_CPU_STOP);
|
send_ipi_message(to_whom, IPI_CPU_STOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
void arch_send_call_function_ipi(cpumask_t mask)
|
||||||
* Run a function on all other CPUs.
|
|
||||||
* <func> The function to run. This must be fast and non-blocking.
|
|
||||||
* <info> An arbitrary pointer to pass to the function.
|
|
||||||
* <retry> If true, keep retrying until ready.
|
|
||||||
* <wait> If true, wait until function has completed on other CPUs.
|
|
||||||
* [RETURNS] 0 on success, else a negative status code.
|
|
||||||
*
|
|
||||||
* Does not return until remote CPUs are nearly ready to execute <func>
|
|
||||||
* or are or have executed.
|
|
||||||
* You must not call this function with disabled interrupts or from a
|
|
||||||
* hardware interrupt handler or from a bottom half handler.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
smp_call_function_on_cpu (void (*func) (void *info), void *info, int retry,
|
|
||||||
int wait, cpumask_t to_whom)
|
|
||||||
{
|
{
|
||||||
struct smp_call_struct data;
|
send_ipi_message(mask, IPI_CALL_FUNC);
|
||||||
unsigned long timeout;
|
|
||||||
int num_cpus_to_call;
|
|
||||||
|
|
||||||
/* Can deadlock when called with interrupts disabled */
|
|
||||||
WARN_ON(irqs_disabled());
|
|
||||||
|
|
||||||
data.func = func;
|
|
||||||
data.info = info;
|
|
||||||
data.wait = wait;
|
|
||||||
|
|
||||||
cpu_clear(smp_processor_id(), to_whom);
|
|
||||||
num_cpus_to_call = cpus_weight(to_whom);
|
|
||||||
|
|
||||||
atomic_set(&data.unstarted_count, num_cpus_to_call);
|
|
||||||
atomic_set(&data.unfinished_count, num_cpus_to_call);
|
|
||||||
|
|
||||||
/* Acquire the smp_call_function_data mutex. */
|
|
||||||
if (pointer_lock(&smp_call_function_data, &data, retry))
|
|
||||||
return -EBUSY;
|
|
||||||
|
|
||||||
/* Send a message to the requested CPUs. */
|
|
||||||
send_ipi_message(to_whom, IPI_CALL_FUNC);
|
|
||||||
|
|
||||||
/* Wait for a minimal response. */
|
|
||||||
timeout = jiffies + HZ;
|
|
||||||
while (atomic_read (&data.unstarted_count) > 0
|
|
||||||
&& time_before (jiffies, timeout))
|
|
||||||
barrier();
|
|
||||||
|
|
||||||
/* If there's no response yet, log a message but allow a longer
|
|
||||||
* timeout period -- if we get a response this time, log
|
|
||||||
* a message saying when we got it..
|
|
||||||
*/
|
|
||||||
if (atomic_read(&data.unstarted_count) > 0) {
|
|
||||||
long start_time = jiffies;
|
|
||||||
printk(KERN_ERR "%s: initial timeout -- trying long wait\n",
|
|
||||||
__func__);
|
|
||||||
timeout = jiffies + 30 * HZ;
|
|
||||||
while (atomic_read(&data.unstarted_count) > 0
|
|
||||||
&& time_before(jiffies, timeout))
|
|
||||||
barrier();
|
|
||||||
if (atomic_read(&data.unstarted_count) <= 0) {
|
|
||||||
long delta = jiffies - start_time;
|
|
||||||
printk(KERN_ERR
|
|
||||||
"%s: response %ld.%ld seconds into long wait\n",
|
|
||||||
__func__, delta / HZ,
|
|
||||||
(100 * (delta - ((delta / HZ) * HZ))) / HZ);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We either got one or timed out -- clear the lock. */
|
void arch_send_call_function_single_ipi(int cpu)
|
||||||
mb();
|
|
||||||
smp_call_function_data = NULL;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If after both the initial and long timeout periods we still don't
|
|
||||||
* have a response, something is very wrong...
|
|
||||||
*/
|
|
||||||
BUG_ON(atomic_read (&data.unstarted_count) > 0);
|
|
||||||
|
|
||||||
/* Wait for a complete response, if needed. */
|
|
||||||
if (wait) {
|
|
||||||
while (atomic_read (&data.unfinished_count) > 0)
|
|
||||||
barrier();
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(smp_call_function_on_cpu);
|
|
||||||
|
|
||||||
int
|
|
||||||
smp_call_function (void (*func) (void *info), void *info, int retry, int wait)
|
|
||||||
{
|
{
|
||||||
return smp_call_function_on_cpu (func, info, retry, wait,
|
send_ipi_message(cpumask_of_cpu(cpu), IPI_CALL_FUNC_SINGLE);
|
||||||
cpu_online_map);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(smp_call_function);
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ipi_imb(void *ignored)
|
ipi_imb(void *ignored)
|
||||||
|
@ -807,7 +657,7 @@ void
|
||||||
smp_imb(void)
|
smp_imb(void)
|
||||||
{
|
{
|
||||||
/* Must wait other processors to flush their icache before continue. */
|
/* Must wait other processors to flush their icache before continue. */
|
||||||
if (on_each_cpu(ipi_imb, NULL, 1, 1))
|
if (on_each_cpu(ipi_imb, NULL, 1))
|
||||||
printk(KERN_CRIT "smp_imb: timed out\n");
|
printk(KERN_CRIT "smp_imb: timed out\n");
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(smp_imb);
|
EXPORT_SYMBOL(smp_imb);
|
||||||
|
@ -823,7 +673,7 @@ flush_tlb_all(void)
|
||||||
{
|
{
|
||||||
/* Although we don't have any data to pass, we do want to
|
/* Although we don't have any data to pass, we do want to
|
||||||
synchronize with the other processors. */
|
synchronize with the other processors. */
|
||||||
if (on_each_cpu(ipi_flush_tlb_all, NULL, 1, 1)) {
|
if (on_each_cpu(ipi_flush_tlb_all, NULL, 1)) {
|
||||||
printk(KERN_CRIT "flush_tlb_all: timed out\n");
|
printk(KERN_CRIT "flush_tlb_all: timed out\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -860,7 +710,7 @@ flush_tlb_mm(struct mm_struct *mm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (smp_call_function(ipi_flush_tlb_mm, mm, 1, 1)) {
|
if (smp_call_function(ipi_flush_tlb_mm, mm, 1)) {
|
||||||
printk(KERN_CRIT "flush_tlb_mm: timed out\n");
|
printk(KERN_CRIT "flush_tlb_mm: timed out\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -913,7 +763,7 @@ flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
|
||||||
data.mm = mm;
|
data.mm = mm;
|
||||||
data.addr = addr;
|
data.addr = addr;
|
||||||
|
|
||||||
if (smp_call_function(ipi_flush_tlb_page, &data, 1, 1)) {
|
if (smp_call_function(ipi_flush_tlb_page, &data, 1)) {
|
||||||
printk(KERN_CRIT "flush_tlb_page: timed out\n");
|
printk(KERN_CRIT "flush_tlb_page: timed out\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -965,7 +815,7 @@ flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (smp_call_function(ipi_flush_icache_page, mm, 1, 1)) {
|
if (smp_call_function(ipi_flush_icache_page, mm, 1)) {
|
||||||
printk(KERN_CRIT "flush_icache_page: timed out\n");
|
printk(KERN_CRIT "flush_icache_page: timed out\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ op_axp_setup(void)
|
||||||
model->reg_setup(®, ctr, &sys);
|
model->reg_setup(®, ctr, &sys);
|
||||||
|
|
||||||
/* Configure the registers on all cpus. */
|
/* Configure the registers on all cpus. */
|
||||||
(void)smp_call_function(model->cpu_setup, ®, 0, 1);
|
(void)smp_call_function(model->cpu_setup, ®, 1);
|
||||||
model->cpu_setup(®);
|
model->cpu_setup(®);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ op_axp_cpu_start(void *dummy)
|
||||||
static int
|
static int
|
||||||
op_axp_start(void)
|
op_axp_start(void)
|
||||||
{
|
{
|
||||||
(void)smp_call_function(op_axp_cpu_start, NULL, 0, 1);
|
(void)smp_call_function(op_axp_cpu_start, NULL, 1);
|
||||||
op_axp_cpu_start(NULL);
|
op_axp_cpu_start(NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ op_axp_cpu_stop(void *dummy)
|
||||||
static void
|
static void
|
||||||
op_axp_stop(void)
|
op_axp_stop(void)
|
||||||
{
|
{
|
||||||
(void)smp_call_function(op_axp_cpu_stop, NULL, 0, 1);
|
(void)smp_call_function(op_axp_cpu_stop, NULL, 1);
|
||||||
op_axp_cpu_stop(NULL);
|
op_axp_cpu_stop(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,8 @@ config ARM
|
||||||
select HAVE_OPROFILE
|
select HAVE_OPROFILE
|
||||||
select HAVE_KPROBES if (!XIP_KERNEL)
|
select HAVE_KPROBES if (!XIP_KERNEL)
|
||||||
select HAVE_KRETPROBES if (HAVE_KPROBES)
|
select HAVE_KRETPROBES if (HAVE_KPROBES)
|
||||||
|
select HAVE_FTRACE if (!XIP_KERNEL)
|
||||||
|
select HAVE_DYNAMIC_FTRACE if (HAVE_FTRACE)
|
||||||
help
|
help
|
||||||
The ARM series is a line of low-power-consumption RISC chip designs
|
The ARM series is a line of low-power-consumption RISC chip designs
|
||||||
licensed by ARM Ltd and targeted at embedded applications and
|
licensed by ARM Ltd and targeted at embedded applications and
|
||||||
|
@ -22,6 +24,9 @@ config ARM
|
||||||
Europe. There is an ARM Linux project with a web page at
|
Europe. There is an ARM Linux project with a web page at
|
||||||
<http://www.arm.linux.org.uk/>.
|
<http://www.arm.linux.org.uk/>.
|
||||||
|
|
||||||
|
config HAVE_PWM
|
||||||
|
bool
|
||||||
|
|
||||||
config SYS_SUPPORTS_APM_EMULATION
|
config SYS_SUPPORTS_APM_EMULATION
|
||||||
bool
|
bool
|
||||||
|
|
||||||
|
@ -84,6 +89,11 @@ config STACKTRACE_SUPPORT
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config HAVE_LATENCYTOP_SUPPORT
|
||||||
|
bool
|
||||||
|
depends on !SMP
|
||||||
|
default y
|
||||||
|
|
||||||
config LOCKDEP_SUPPORT
|
config LOCKDEP_SUPPORT
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
@ -147,6 +157,10 @@ config FIQ
|
||||||
config ARCH_MTD_XIP
|
config ARCH_MTD_XIP
|
||||||
bool
|
bool
|
||||||
|
|
||||||
|
config GENERIC_HARDIRQS_NO__DO_IRQ
|
||||||
|
bool
|
||||||
|
def_bool y
|
||||||
|
|
||||||
if OPROFILE
|
if OPROFILE
|
||||||
|
|
||||||
config OPROFILE_ARMV6
|
config OPROFILE_ARMV6
|
||||||
|
@ -232,13 +246,6 @@ config ARCH_CLPS711X
|
||||||
help
|
help
|
||||||
Support for Cirrus Logic 711x/721x based boards.
|
Support for Cirrus Logic 711x/721x based boards.
|
||||||
|
|
||||||
config ARCH_CO285
|
|
||||||
bool "Co-EBSA285"
|
|
||||||
select FOOTBRIDGE
|
|
||||||
select FOOTBRIDGE_ADDIN
|
|
||||||
help
|
|
||||||
Support for Intel's EBSA285 companion chip.
|
|
||||||
|
|
||||||
config ARCH_EBSA110
|
config ARCH_EBSA110
|
||||||
bool "EBSA-110"
|
bool "EBSA-110"
|
||||||
select ISA
|
select ISA
|
||||||
|
@ -299,6 +306,8 @@ config ARCH_IOP32X
|
||||||
depends on MMU
|
depends on MMU
|
||||||
select PLAT_IOP
|
select PLAT_IOP
|
||||||
select PCI
|
select PCI
|
||||||
|
select GENERIC_GPIO
|
||||||
|
select HAVE_GPIO_LIB
|
||||||
help
|
help
|
||||||
Support for Intel's 80219 and IOP32X (XScale) family of
|
Support for Intel's 80219 and IOP32X (XScale) family of
|
||||||
processors.
|
processors.
|
||||||
|
@ -308,6 +317,8 @@ config ARCH_IOP33X
|
||||||
depends on MMU
|
depends on MMU
|
||||||
select PLAT_IOP
|
select PLAT_IOP
|
||||||
select PCI
|
select PCI
|
||||||
|
select GENERIC_GPIO
|
||||||
|
select HAVE_GPIO_LIB
|
||||||
help
|
help
|
||||||
Support for Intel's IOP33X (XScale) family of processors.
|
Support for Intel's IOP33X (XScale) family of processors.
|
||||||
|
|
||||||
|
@ -347,6 +358,16 @@ config ARCH_L7200
|
||||||
If you have any questions or comments about the Linux kernel port
|
If you have any questions or comments about the Linux kernel port
|
||||||
to this board, send e-mail to <sjhill@cotw.com>.
|
to this board, send e-mail to <sjhill@cotw.com>.
|
||||||
|
|
||||||
|
config ARCH_KIRKWOOD
|
||||||
|
bool "Marvell Kirkwood"
|
||||||
|
select PCI
|
||||||
|
select GENERIC_TIME
|
||||||
|
select GENERIC_CLOCKEVENTS
|
||||||
|
select PLAT_ORION
|
||||||
|
help
|
||||||
|
Support for the following Marvell Kirkwood series SoCs:
|
||||||
|
88F6180, 88F6192 and 88F6281.
|
||||||
|
|
||||||
config ARCH_KS8695
|
config ARCH_KS8695
|
||||||
bool "Micrel/Kendin KS8695"
|
bool "Micrel/Kendin KS8695"
|
||||||
select GENERIC_GPIO
|
select GENERIC_GPIO
|
||||||
|
@ -365,9 +386,31 @@ config ARCH_NS9XXX
|
||||||
|
|
||||||
<http://www.digi.com/products/microprocessors/index.jsp>
|
<http://www.digi.com/products/microprocessors/index.jsp>
|
||||||
|
|
||||||
|
config ARCH_LOKI
|
||||||
|
bool "Marvell Loki (88RC8480)"
|
||||||
|
select GENERIC_TIME
|
||||||
|
select GENERIC_CLOCKEVENTS
|
||||||
|
select PLAT_ORION
|
||||||
|
help
|
||||||
|
Support for the Marvell Loki (88RC8480) SoC.
|
||||||
|
|
||||||
|
config ARCH_MV78XX0
|
||||||
|
bool "Marvell MV78xx0"
|
||||||
|
select PCI
|
||||||
|
select GENERIC_TIME
|
||||||
|
select GENERIC_CLOCKEVENTS
|
||||||
|
select PLAT_ORION
|
||||||
|
help
|
||||||
|
Support for the following Marvell MV78xx0 series SoCs:
|
||||||
|
MV781x0, MV782x0.
|
||||||
|
|
||||||
config ARCH_MXC
|
config ARCH_MXC
|
||||||
bool "Freescale MXC/iMX-based"
|
bool "Freescale MXC/iMX-based"
|
||||||
|
select GENERIC_TIME
|
||||||
|
select GENERIC_CLOCKEVENTS
|
||||||
select ARCH_MTD_XIP
|
select ARCH_MTD_XIP
|
||||||
|
select GENERIC_GPIO
|
||||||
|
select HAVE_GPIO_LIB
|
||||||
help
|
help
|
||||||
Support for Freescale MXC/iMX-based family of processors
|
Support for Freescale MXC/iMX-based family of processors
|
||||||
|
|
||||||
|
@ -381,7 +424,8 @@ config ARCH_ORION5X
|
||||||
select PLAT_ORION
|
select PLAT_ORION
|
||||||
help
|
help
|
||||||
Support for the following Marvell Orion 5x series SoCs:
|
Support for the following Marvell Orion 5x series SoCs:
|
||||||
Orion-1 (5181), Orion-NAS (5182), Orion-2 (5281.)
|
Orion-1 (5181), Orion-VoIP (5181L), Orion-NAS (5182),
|
||||||
|
Orion-2 (5281).
|
||||||
|
|
||||||
config ARCH_PNX4008
|
config ARCH_PNX4008
|
||||||
bool "Philips Nexperia PNX4008 Mobile"
|
bool "Philips Nexperia PNX4008 Mobile"
|
||||||
|
@ -406,6 +450,7 @@ config ARCH_RPC
|
||||||
select FIQ
|
select FIQ
|
||||||
select TIMER_ACORN
|
select TIMER_ACORN
|
||||||
select ARCH_MAY_HAVE_PC_FDC
|
select ARCH_MAY_HAVE_PC_FDC
|
||||||
|
select HAVE_PATA_PLATFORM
|
||||||
select ISA_DMA_API
|
select ISA_DMA_API
|
||||||
select NO_IOPORT
|
select NO_IOPORT
|
||||||
help
|
help
|
||||||
|
@ -502,6 +547,10 @@ source "arch/arm/mach-ixp2000/Kconfig"
|
||||||
|
|
||||||
source "arch/arm/mach-ixp23xx/Kconfig"
|
source "arch/arm/mach-ixp23xx/Kconfig"
|
||||||
|
|
||||||
|
source "arch/arm/mach-loki/Kconfig"
|
||||||
|
|
||||||
|
source "arch/arm/mach-mv78xx0/Kconfig"
|
||||||
|
|
||||||
source "arch/arm/mach-pxa/Kconfig"
|
source "arch/arm/mach-pxa/Kconfig"
|
||||||
|
|
||||||
source "arch/arm/mach-sa1100/Kconfig"
|
source "arch/arm/mach-sa1100/Kconfig"
|
||||||
|
@ -514,6 +563,8 @@ source "arch/arm/mach-omap2/Kconfig"
|
||||||
|
|
||||||
source "arch/arm/mach-orion5x/Kconfig"
|
source "arch/arm/mach-orion5x/Kconfig"
|
||||||
|
|
||||||
|
source "arch/arm/mach-kirkwood/Kconfig"
|
||||||
|
|
||||||
source "arch/arm/plat-s3c24xx/Kconfig"
|
source "arch/arm/plat-s3c24xx/Kconfig"
|
||||||
source "arch/arm/plat-s3c/Kconfig"
|
source "arch/arm/plat-s3c/Kconfig"
|
||||||
|
|
||||||
|
@ -650,6 +701,7 @@ source "kernel/time/Kconfig"
|
||||||
config SMP
|
config SMP
|
||||||
bool "Symmetric Multi-Processing (EXPERIMENTAL)"
|
bool "Symmetric Multi-Processing (EXPERIMENTAL)"
|
||||||
depends on EXPERIMENTAL && (REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP)
|
depends on EXPERIMENTAL && (REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP)
|
||||||
|
select USE_GENERIC_SMP_HELPERS
|
||||||
help
|
help
|
||||||
This enables support for systems with more than one CPU. If you have
|
This enables support for systems with more than one CPU. If you have
|
||||||
a system with only one CPU, like most personal computers, say N. If
|
a system with only one CPU, like most personal computers, say N. If
|
||||||
|
@ -703,27 +755,6 @@ config PREEMPT
|
||||||
Say Y here if you are building a kernel for a desktop, embedded
|
Say Y here if you are building a kernel for a desktop, embedded
|
||||||
or real-time system. Say N if you are unsure.
|
or real-time system. Say N if you are unsure.
|
||||||
|
|
||||||
config NO_IDLE_HZ
|
|
||||||
bool "Dynamic tick timer"
|
|
||||||
depends on !GENERIC_CLOCKEVENTS
|
|
||||||
help
|
|
||||||
Select this option if you want to disable continuous timer ticks
|
|
||||||
and have them programmed to occur as required. This option saves
|
|
||||||
power as the system can remain in idle state for longer.
|
|
||||||
|
|
||||||
By default dynamic tick is disabled during the boot, and can be
|
|
||||||
manually enabled with:
|
|
||||||
|
|
||||||
echo 1 > /sys/devices/system/timer/timer0/dyn_tick
|
|
||||||
|
|
||||||
Alternatively, if you want dynamic tick automatically enabled
|
|
||||||
during boot, pass "dyntick=enable" via the kernel command string.
|
|
||||||
|
|
||||||
Please note that dynamic tick may affect the accuracy of
|
|
||||||
timekeeping on some platforms depending on the implementation.
|
|
||||||
Currently at least OMAP, PXA2xx and SA11x0 platforms are known
|
|
||||||
to have accurate timekeeping with dynamic tick.
|
|
||||||
|
|
||||||
config HZ
|
config HZ
|
||||||
int
|
int
|
||||||
default 128 if ARCH_L7200
|
default 128 if ARCH_L7200
|
||||||
|
@ -789,7 +820,7 @@ source "mm/Kconfig"
|
||||||
|
|
||||||
config LEDS
|
config LEDS
|
||||||
bool "Timer and CPU usage LEDs"
|
bool "Timer and CPU usage LEDs"
|
||||||
depends on ARCH_CDB89712 || ARCH_CO285 || ARCH_EBSA110 || \
|
depends on ARCH_CDB89712 || ARCH_EBSA110 || \
|
||||||
ARCH_EBSA285 || ARCH_IMX || ARCH_INTEGRATOR || \
|
ARCH_EBSA285 || ARCH_IMX || ARCH_INTEGRATOR || \
|
||||||
ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_NETWINDER || \
|
ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_NETWINDER || \
|
||||||
ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \
|
ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \
|
||||||
|
|
|
@ -100,8 +100,6 @@ textofs-y := 0x00008000
|
||||||
incdir-$(CONFIG_ARCH_CLPS7500) := cl7500
|
incdir-$(CONFIG_ARCH_CLPS7500) := cl7500
|
||||||
machine-$(CONFIG_FOOTBRIDGE) := footbridge
|
machine-$(CONFIG_FOOTBRIDGE) := footbridge
|
||||||
incdir-$(CONFIG_FOOTBRIDGE) := ebsa285
|
incdir-$(CONFIG_FOOTBRIDGE) := ebsa285
|
||||||
machine-$(CONFIG_ARCH_CO285) := footbridge
|
|
||||||
incdir-$(CONFIG_ARCH_CO285) := ebsa285
|
|
||||||
machine-$(CONFIG_ARCH_SHARK) := shark
|
machine-$(CONFIG_ARCH_SHARK) := shark
|
||||||
machine-$(CONFIG_ARCH_SA1100) := sa1100
|
machine-$(CONFIG_ARCH_SA1100) := sa1100
|
||||||
ifeq ($(CONFIG_ARCH_SA1100),y)
|
ifeq ($(CONFIG_ARCH_SA1100),y)
|
||||||
|
@ -135,11 +133,15 @@ endif
|
||||||
machine-$(CONFIG_ARCH_NETX) := netx
|
machine-$(CONFIG_ARCH_NETX) := netx
|
||||||
machine-$(CONFIG_ARCH_NS9XXX) := ns9xxx
|
machine-$(CONFIG_ARCH_NS9XXX) := ns9xxx
|
||||||
machine-$(CONFIG_ARCH_DAVINCI) := davinci
|
machine-$(CONFIG_ARCH_DAVINCI) := davinci
|
||||||
|
machine-$(CONFIG_ARCH_KIRKWOOD) := kirkwood
|
||||||
machine-$(CONFIG_ARCH_KS8695) := ks8695
|
machine-$(CONFIG_ARCH_KS8695) := ks8695
|
||||||
incdir-$(CONFIG_ARCH_MXC) := mxc
|
incdir-$(CONFIG_ARCH_MXC) := mxc
|
||||||
|
machine-$(CONFIG_ARCH_MX2) := mx2
|
||||||
machine-$(CONFIG_ARCH_MX3) := mx3
|
machine-$(CONFIG_ARCH_MX3) := mx3
|
||||||
machine-$(CONFIG_ARCH_ORION5X) := orion5x
|
machine-$(CONFIG_ARCH_ORION5X) := orion5x
|
||||||
machine-$(CONFIG_ARCH_MSM7X00A) := msm
|
machine-$(CONFIG_ARCH_MSM7X00A) := msm
|
||||||
|
machine-$(CONFIG_ARCH_LOKI) := loki
|
||||||
|
machine-$(CONFIG_ARCH_MV78XX0) := mv78xx0
|
||||||
|
|
||||||
ifeq ($(CONFIG_ARCH_EBSA110),y)
|
ifeq ($(CONFIG_ARCH_EBSA110),y)
|
||||||
# This is what happens if you forget the IOCS16 line.
|
# This is what happens if you forget the IOCS16 line.
|
||||||
|
@ -190,8 +192,6 @@ core-$(CONFIG_PLAT_S3C24XX) += arch/arm/plat-s3c24xx/
|
||||||
core-$(CONFIG_ARCH_MXC) += arch/arm/plat-mxc/
|
core-$(CONFIG_ARCH_MXC) += arch/arm/plat-mxc/
|
||||||
|
|
||||||
drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/
|
drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/
|
||||||
drivers-$(CONFIG_ARCH_CLPS7500) += drivers/acorn/char/
|
|
||||||
drivers-$(CONFIG_ARCH_L7200) += drivers/acorn/char/
|
|
||||||
|
|
||||||
libs-y := arch/arm/lib/ $(libs-y)
|
libs-y := arch/arm/lib/ $(libs-y)
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,12 @@ SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/
|
||||||
|
|
||||||
targets := vmlinux vmlinux.lds piggy.gz piggy.o font.o font.c \
|
targets := vmlinux vmlinux.lds piggy.gz piggy.o font.o font.c \
|
||||||
head.o misc.o $(OBJS)
|
head.o misc.o $(OBJS)
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_FTRACE),y)
|
||||||
|
ORIG_CFLAGS := $(KBUILD_CFLAGS)
|
||||||
|
KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
|
||||||
|
endif
|
||||||
|
|
||||||
EXTRA_CFLAGS := -fpic -fno-builtin
|
EXTRA_CFLAGS := -fpic -fno-builtin
|
||||||
EXTRA_AFLAGS :=
|
EXTRA_AFLAGS :=
|
||||||
|
|
||||||
|
|
|
@ -623,8 +623,8 @@ proc_types:
|
||||||
b __armv4_mmu_cache_off
|
b __armv4_mmu_cache_off
|
||||||
b __armv4_mmu_cache_flush
|
b __armv4_mmu_cache_flush
|
||||||
|
|
||||||
.word 0x56055310 @ Feroceon
|
.word 0x56050000 @ Feroceon
|
||||||
.word 0xfffffff0
|
.word 0xff0f0000
|
||||||
b __armv4_mmu_cache_on
|
b __armv4_mmu_cache_on
|
||||||
b __armv4_mmu_cache_off
|
b __armv4_mmu_cache_off
|
||||||
b __armv5tej_mmu_cache_flush
|
b __armv5tej_mmu_cache_flush
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
# Makefile for the linux kernel.
|
# Makefile for the linux kernel.
|
||||||
#
|
#
|
||||||
|
|
||||||
obj-y += rtctime.o
|
|
||||||
obj-$(CONFIG_ARM_GIC) += gic.o
|
obj-$(CONFIG_ARM_GIC) += gic.o
|
||||||
obj-$(CONFIG_ARM_VIC) += vic.o
|
obj-$(CONFIG_ARM_VIC) += vic.o
|
||||||
obj-$(CONFIG_ICST525) += icst525.o
|
obj-$(CONFIG_ICST525) += icst525.o
|
||||||
|
|
|
@ -1,434 +0,0 @@
|
||||||
/*
|
|
||||||
* linux/arch/arm/common/rtctime.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 2003 Deep Blue Solutions Ltd.
|
|
||||||
* Based on sa1100-rtc.c, Nils Faerber, CIH, Nicolas Pitre.
|
|
||||||
* Based on rtc.c by Paul Gortmaker
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/time.h>
|
|
||||||
#include <linux/rtc.h>
|
|
||||||
#include <linux/poll.h>
|
|
||||||
#include <linux/proc_fs.h>
|
|
||||||
#include <linux/miscdevice.h>
|
|
||||||
#include <linux/spinlock.h>
|
|
||||||
#include <linux/capability.h>
|
|
||||||
#include <linux/device.h>
|
|
||||||
#include <linux/mutex.h>
|
|
||||||
|
|
||||||
#include <asm/rtc.h>
|
|
||||||
|
|
||||||
static DECLARE_WAIT_QUEUE_HEAD(rtc_wait);
|
|
||||||
static struct fasync_struct *rtc_async_queue;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtc_lock protects rtc_irq_data
|
|
||||||
*/
|
|
||||||
static DEFINE_SPINLOCK(rtc_lock);
|
|
||||||
static unsigned long rtc_irq_data;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtc_sem protects rtc_inuse and rtc_ops
|
|
||||||
*/
|
|
||||||
static DEFINE_MUTEX(rtc_mutex);
|
|
||||||
static unsigned long rtc_inuse;
|
|
||||||
static struct rtc_ops *rtc_ops;
|
|
||||||
|
|
||||||
#define rtc_epoch 1900UL
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Calculate the next alarm time given the requested alarm time mask
|
|
||||||
* and the current time.
|
|
||||||
*/
|
|
||||||
void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, struct rtc_time *alrm)
|
|
||||||
{
|
|
||||||
unsigned long next_time;
|
|
||||||
unsigned long now_time;
|
|
||||||
|
|
||||||
next->tm_year = now->tm_year;
|
|
||||||
next->tm_mon = now->tm_mon;
|
|
||||||
next->tm_mday = now->tm_mday;
|
|
||||||
next->tm_hour = alrm->tm_hour;
|
|
||||||
next->tm_min = alrm->tm_min;
|
|
||||||
next->tm_sec = alrm->tm_sec;
|
|
||||||
|
|
||||||
rtc_tm_to_time(now, &now_time);
|
|
||||||
rtc_tm_to_time(next, &next_time);
|
|
||||||
|
|
||||||
if (next_time < now_time) {
|
|
||||||
/* Advance one day */
|
|
||||||
next_time += 60 * 60 * 24;
|
|
||||||
rtc_time_to_tm(next_time, next);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(rtc_next_alarm_time);
|
|
||||||
|
|
||||||
static inline int rtc_arm_read_time(struct rtc_ops *ops, struct rtc_time *tm)
|
|
||||||
{
|
|
||||||
memset(tm, 0, sizeof(struct rtc_time));
|
|
||||||
return ops->read_time(tm);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int rtc_arm_set_time(struct rtc_ops *ops, struct rtc_time *tm)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = rtc_valid_tm(tm);
|
|
||||||
if (ret == 0)
|
|
||||||
ret = ops->set_time(tm);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int rtc_arm_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm)
|
|
||||||
{
|
|
||||||
int ret = -EINVAL;
|
|
||||||
if (ops->read_alarm) {
|
|
||||||
memset(alrm, 0, sizeof(struct rtc_wkalrm));
|
|
||||||
ret = ops->read_alarm(alrm);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int rtc_arm_set_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm)
|
|
||||||
{
|
|
||||||
int ret = -EINVAL;
|
|
||||||
if (ops->set_alarm)
|
|
||||||
ret = ops->set_alarm(alrm);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void rtc_update(unsigned long num, unsigned long events)
|
|
||||||
{
|
|
||||||
spin_lock(&rtc_lock);
|
|
||||||
rtc_irq_data = (rtc_irq_data + (num << 8)) | events;
|
|
||||||
spin_unlock(&rtc_lock);
|
|
||||||
|
|
||||||
wake_up_interruptible(&rtc_wait);
|
|
||||||
kill_fasync(&rtc_async_queue, SIGIO, POLL_IN);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(rtc_update);
|
|
||||||
|
|
||||||
|
|
||||||
static ssize_t
|
|
||||||
rtc_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
|
|
||||||
{
|
|
||||||
DECLARE_WAITQUEUE(wait, current);
|
|
||||||
unsigned long data;
|
|
||||||
ssize_t ret;
|
|
||||||
|
|
||||||
if (count < sizeof(unsigned long))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
add_wait_queue(&rtc_wait, &wait);
|
|
||||||
do {
|
|
||||||
__set_current_state(TASK_INTERRUPTIBLE);
|
|
||||||
|
|
||||||
spin_lock_irq(&rtc_lock);
|
|
||||||
data = rtc_irq_data;
|
|
||||||
rtc_irq_data = 0;
|
|
||||||
spin_unlock_irq(&rtc_lock);
|
|
||||||
|
|
||||||
if (data != 0) {
|
|
||||||
ret = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (file->f_flags & O_NONBLOCK) {
|
|
||||||
ret = -EAGAIN;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (signal_pending(current)) {
|
|
||||||
ret = -ERESTARTSYS;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
schedule();
|
|
||||||
} while (1);
|
|
||||||
set_current_state(TASK_RUNNING);
|
|
||||||
remove_wait_queue(&rtc_wait, &wait);
|
|
||||||
|
|
||||||
if (ret == 0) {
|
|
||||||
ret = put_user(data, (unsigned long __user *)buf);
|
|
||||||
if (ret == 0)
|
|
||||||
ret = sizeof(unsigned long);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int rtc_poll(struct file *file, poll_table *wait)
|
|
||||||
{
|
|
||||||
unsigned long data;
|
|
||||||
|
|
||||||
poll_wait(file, &rtc_wait, wait);
|
|
||||||
|
|
||||||
spin_lock_irq(&rtc_lock);
|
|
||||||
data = rtc_irq_data;
|
|
||||||
spin_unlock_irq(&rtc_lock);
|
|
||||||
|
|
||||||
return data != 0 ? POLLIN | POLLRDNORM : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
|
|
||||||
unsigned long arg)
|
|
||||||
{
|
|
||||||
struct rtc_ops *ops = file->private_data;
|
|
||||||
struct rtc_time tm;
|
|
||||||
struct rtc_wkalrm alrm;
|
|
||||||
void __user *uarg = (void __user *)arg;
|
|
||||||
int ret = -EINVAL;
|
|
||||||
|
|
||||||
switch (cmd) {
|
|
||||||
case RTC_ALM_READ:
|
|
||||||
ret = rtc_arm_read_alarm(ops, &alrm);
|
|
||||||
if (ret)
|
|
||||||
break;
|
|
||||||
ret = copy_to_user(uarg, &alrm.time, sizeof(tm));
|
|
||||||
if (ret)
|
|
||||||
ret = -EFAULT;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RTC_ALM_SET:
|
|
||||||
ret = copy_from_user(&alrm.time, uarg, sizeof(tm));
|
|
||||||
if (ret) {
|
|
||||||
ret = -EFAULT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
alrm.enabled = 0;
|
|
||||||
alrm.pending = 0;
|
|
||||||
alrm.time.tm_mday = -1;
|
|
||||||
alrm.time.tm_mon = -1;
|
|
||||||
alrm.time.tm_year = -1;
|
|
||||||
alrm.time.tm_wday = -1;
|
|
||||||
alrm.time.tm_yday = -1;
|
|
||||||
alrm.time.tm_isdst = -1;
|
|
||||||
ret = rtc_arm_set_alarm(ops, &alrm);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RTC_RD_TIME:
|
|
||||||
ret = rtc_arm_read_time(ops, &tm);
|
|
||||||
if (ret)
|
|
||||||
break;
|
|
||||||
ret = copy_to_user(uarg, &tm, sizeof(tm));
|
|
||||||
if (ret)
|
|
||||||
ret = -EFAULT;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RTC_SET_TIME:
|
|
||||||
if (!capable(CAP_SYS_TIME)) {
|
|
||||||
ret = -EACCES;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ret = copy_from_user(&tm, uarg, sizeof(tm));
|
|
||||||
if (ret) {
|
|
||||||
ret = -EFAULT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ret = rtc_arm_set_time(ops, &tm);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RTC_EPOCH_SET:
|
|
||||||
#ifndef rtc_epoch
|
|
||||||
/*
|
|
||||||
* There were no RTC clocks before 1900.
|
|
||||||
*/
|
|
||||||
if (arg < 1900) {
|
|
||||||
ret = -EINVAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!capable(CAP_SYS_TIME)) {
|
|
||||||
ret = -EACCES;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
rtc_epoch = arg;
|
|
||||||
ret = 0;
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RTC_EPOCH_READ:
|
|
||||||
ret = put_user(rtc_epoch, (unsigned long __user *)uarg);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RTC_WKALM_SET:
|
|
||||||
ret = copy_from_user(&alrm, uarg, sizeof(alrm));
|
|
||||||
if (ret) {
|
|
||||||
ret = -EFAULT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ret = rtc_arm_set_alarm(ops, &alrm);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RTC_WKALM_RD:
|
|
||||||
ret = rtc_arm_read_alarm(ops, &alrm);
|
|
||||||
if (ret)
|
|
||||||
break;
|
|
||||||
ret = copy_to_user(uarg, &alrm, sizeof(alrm));
|
|
||||||
if (ret)
|
|
||||||
ret = -EFAULT;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
if (ops->ioctl)
|
|
||||||
ret = ops->ioctl(cmd, arg);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int rtc_open(struct inode *inode, struct file *file)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
mutex_lock(&rtc_mutex);
|
|
||||||
|
|
||||||
if (rtc_inuse) {
|
|
||||||
ret = -EBUSY;
|
|
||||||
} else if (!rtc_ops || !try_module_get(rtc_ops->owner)) {
|
|
||||||
ret = -ENODEV;
|
|
||||||
} else {
|
|
||||||
file->private_data = rtc_ops;
|
|
||||||
|
|
||||||
ret = rtc_ops->open ? rtc_ops->open() : 0;
|
|
||||||
if (ret == 0) {
|
|
||||||
spin_lock_irq(&rtc_lock);
|
|
||||||
rtc_irq_data = 0;
|
|
||||||
spin_unlock_irq(&rtc_lock);
|
|
||||||
|
|
||||||
rtc_inuse = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mutex_unlock(&rtc_mutex);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int rtc_release(struct inode *inode, struct file *file)
|
|
||||||
{
|
|
||||||
struct rtc_ops *ops = file->private_data;
|
|
||||||
|
|
||||||
if (ops->release)
|
|
||||||
ops->release();
|
|
||||||
|
|
||||||
spin_lock_irq(&rtc_lock);
|
|
||||||
rtc_irq_data = 0;
|
|
||||||
spin_unlock_irq(&rtc_lock);
|
|
||||||
|
|
||||||
module_put(rtc_ops->owner);
|
|
||||||
rtc_inuse = 0;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int rtc_fasync(int fd, struct file *file, int on)
|
|
||||||
{
|
|
||||||
return fasync_helper(fd, file, on, &rtc_async_queue);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations rtc_fops = {
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
.llseek = no_llseek,
|
|
||||||
.read = rtc_read,
|
|
||||||
.poll = rtc_poll,
|
|
||||||
.ioctl = rtc_ioctl,
|
|
||||||
.open = rtc_open,
|
|
||||||
.release = rtc_release,
|
|
||||||
.fasync = rtc_fasync,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct miscdevice rtc_miscdev = {
|
|
||||||
.minor = RTC_MINOR,
|
|
||||||
.name = "rtc",
|
|
||||||
.fops = &rtc_fops,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
|
|
||||||
{
|
|
||||||
struct rtc_ops *ops = data;
|
|
||||||
struct rtc_wkalrm alrm;
|
|
||||||
struct rtc_time tm;
|
|
||||||
char *p = page;
|
|
||||||
|
|
||||||
if (rtc_arm_read_time(ops, &tm) == 0) {
|
|
||||||
p += sprintf(p,
|
|
||||||
"rtc_time\t: %02d:%02d:%02d\n"
|
|
||||||
"rtc_date\t: %04d-%02d-%02d\n"
|
|
||||||
"rtc_epoch\t: %04lu\n",
|
|
||||||
tm.tm_hour, tm.tm_min, tm.tm_sec,
|
|
||||||
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
|
|
||||||
rtc_epoch);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rtc_arm_read_alarm(ops, &alrm) == 0) {
|
|
||||||
p += sprintf(p, "alrm_time\t: ");
|
|
||||||
if ((unsigned int)alrm.time.tm_hour <= 24)
|
|
||||||
p += sprintf(p, "%02d:", alrm.time.tm_hour);
|
|
||||||
else
|
|
||||||
p += sprintf(p, "**:");
|
|
||||||
if ((unsigned int)alrm.time.tm_min <= 59)
|
|
||||||
p += sprintf(p, "%02d:", alrm.time.tm_min);
|
|
||||||
else
|
|
||||||
p += sprintf(p, "**:");
|
|
||||||
if ((unsigned int)alrm.time.tm_sec <= 59)
|
|
||||||
p += sprintf(p, "%02d\n", alrm.time.tm_sec);
|
|
||||||
else
|
|
||||||
p += sprintf(p, "**\n");
|
|
||||||
|
|
||||||
p += sprintf(p, "alrm_date\t: ");
|
|
||||||
if ((unsigned int)alrm.time.tm_year <= 200)
|
|
||||||
p += sprintf(p, "%04d-", alrm.time.tm_year + 1900);
|
|
||||||
else
|
|
||||||
p += sprintf(p, "****-");
|
|
||||||
if ((unsigned int)alrm.time.tm_mon <= 11)
|
|
||||||
p += sprintf(p, "%02d-", alrm.time.tm_mon + 1);
|
|
||||||
else
|
|
||||||
p += sprintf(p, "**-");
|
|
||||||
if ((unsigned int)alrm.time.tm_mday <= 31)
|
|
||||||
p += sprintf(p, "%02d\n", alrm.time.tm_mday);
|
|
||||||
else
|
|
||||||
p += sprintf(p, "**\n");
|
|
||||||
p += sprintf(p, "alrm_wakeup\t: %s\n",
|
|
||||||
alrm.enabled ? "yes" : "no");
|
|
||||||
p += sprintf(p, "alrm_pending\t: %s\n",
|
|
||||||
alrm.pending ? "yes" : "no");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ops->proc)
|
|
||||||
p += ops->proc(p);
|
|
||||||
|
|
||||||
return p - page;
|
|
||||||
}
|
|
||||||
|
|
||||||
int register_rtc(struct rtc_ops *ops)
|
|
||||||
{
|
|
||||||
int ret = -EBUSY;
|
|
||||||
|
|
||||||
mutex_lock(&rtc_mutex);
|
|
||||||
if (rtc_ops == NULL) {
|
|
||||||
rtc_ops = ops;
|
|
||||||
|
|
||||||
ret = misc_register(&rtc_miscdev);
|
|
||||||
if (ret == 0)
|
|
||||||
create_proc_read_entry("driver/rtc", 0, NULL,
|
|
||||||
rtc_read_proc, ops);
|
|
||||||
}
|
|
||||||
mutex_unlock(&rtc_mutex);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(register_rtc);
|
|
||||||
|
|
||||||
void unregister_rtc(struct rtc_ops *rtc)
|
|
||||||
{
|
|
||||||
mutex_lock(&rtc_mutex);
|
|
||||||
if (rtc == rtc_ops) {
|
|
||||||
remove_proc_entry("driver/rtc", NULL);
|
|
||||||
misc_deregister(&rtc_miscdev);
|
|
||||||
rtc_ops = NULL;
|
|
||||||
}
|
|
||||||
mutex_unlock(&rtc_mutex);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(unregister_rtc);
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
#include <asm/arch/pm.h>
|
#include <asm/arch/pm.h>
|
||||||
#include <asm/arch/pxa-regs.h>
|
#include <asm/arch/pxa-regs.h>
|
||||||
|
#include <asm/arch/pxa2xx-regs.h>
|
||||||
#include <asm/arch/sharpsl.h>
|
#include <asm/arch/sharpsl.h>
|
||||||
#include <asm/hardware/sharpsl_pm.h>
|
#include <asm/hardware/sharpsl_pm.h>
|
||||||
|
|
||||||
|
@ -157,6 +158,7 @@ static void sharpsl_battery_thread(struct work_struct *private_)
|
||||||
dev_dbg(sharpsl_pm.dev, "Battery: voltage: %d, status: %d, percentage: %d, time: %ld\n", voltage,
|
dev_dbg(sharpsl_pm.dev, "Battery: voltage: %d, status: %d, percentage: %d, time: %ld\n", voltage,
|
||||||
sharpsl_pm.battstat.mainbat_status, sharpsl_pm.battstat.mainbat_percent, jiffies);
|
sharpsl_pm.battstat.mainbat_status, sharpsl_pm.battstat.mainbat_percent, jiffies);
|
||||||
|
|
||||||
|
#ifdef CONFIG_BACKLIGHT_CORGI
|
||||||
/* If battery is low. limit backlight intensity to save power. */
|
/* If battery is low. limit backlight intensity to save power. */
|
||||||
if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE)
|
if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE)
|
||||||
&& ((sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_LOW) ||
|
&& ((sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_LOW) ||
|
||||||
|
@ -169,6 +171,7 @@ static void sharpsl_battery_thread(struct work_struct *private_)
|
||||||
sharpsl_pm.machinfo->backlight_limit(0);
|
sharpsl_pm.machinfo->backlight_limit(0);
|
||||||
sharpsl_pm.flags &= ~SHARPSL_BL_LIMIT;
|
sharpsl_pm.flags &= ~SHARPSL_BL_LIMIT;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Suspend if critical battery level */
|
/* Suspend if critical battery level */
|
||||||
if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE)
|
if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE)
|
||||||
|
|
|
@ -213,7 +213,6 @@ CONFIG_CPU_CP15_MMU=y
|
||||||
#
|
#
|
||||||
# CONFIG_TICK_ONESHOT is not set
|
# CONFIG_TICK_ONESHOT is not set
|
||||||
# CONFIG_PREEMPT is not set
|
# CONFIG_PREEMPT is not set
|
||||||
# CONFIG_NO_IDLE_HZ is not set
|
|
||||||
CONFIG_HZ=100
|
CONFIG_HZ=100
|
||||||
CONFIG_AEABI=y
|
CONFIG_AEABI=y
|
||||||
CONFIG_OABI_COMPAT=y
|
CONFIG_OABI_COMPAT=y
|
||||||
|
@ -907,7 +906,32 @@ CONFIG_USB_MON=y
|
||||||
#
|
#
|
||||||
# USB Gadget Support
|
# USB Gadget Support
|
||||||
#
|
#
|
||||||
# CONFIG_USB_GADGET is not set
|
CONFIG_USB_GADGET=y
|
||||||
|
# CONFIG_USB_GADGET_DEBUG is not set
|
||||||
|
# CONFIG_USB_GADGET_DEBUG_FILES is not set
|
||||||
|
CONFIG_USB_GADGET_SELECTED=y
|
||||||
|
# CONFIG_USB_GADGET_AMD5536UDC is not set
|
||||||
|
CONFIG_USB_GADGET_ATMEL_USBA=y
|
||||||
|
CONFIG_USB_ATMEL_USBA=y
|
||||||
|
# CONFIG_USB_GADGET_FSL_USB2 is not set
|
||||||
|
# CONFIG_USB_GADGET_NET2280 is not set
|
||||||
|
# CONFIG_USB_GADGET_PXA2XX is not set
|
||||||
|
# CONFIG_USB_GADGET_M66592 is not set
|
||||||
|
# CONFIG_USB_GADGET_GOKU is not set
|
||||||
|
# CONFIG_USB_GADGET_LH7A40X is not set
|
||||||
|
# CONFIG_USB_GADGET_OMAP is not set
|
||||||
|
# CONFIG_USB_GADGET_S3C2410 is not set
|
||||||
|
# CONFIG_USB_GADGET_AT91 is not set
|
||||||
|
# CONFIG_USB_GADGET_DUMMY_HCD is not set
|
||||||
|
CONFIG_USB_GADGET_DUALSPEED=y
|
||||||
|
# CONFIG_USB_ZERO is not set
|
||||||
|
CONFIG_USB_ETH=m
|
||||||
|
CONFIG_USB_ETH_RNDIS=y
|
||||||
|
# CONFIG_USB_GADGETFS is not set
|
||||||
|
CONFIG_USB_FILE_STORAGE=m
|
||||||
|
# CONFIG_USB_FILE_STORAGE_TEST is not set
|
||||||
|
# CONFIG_USB_G_SERIAL is not set
|
||||||
|
# CONFIG_USB_MIDI_GADGET is not set
|
||||||
CONFIG_MMC=y
|
CONFIG_MMC=y
|
||||||
# CONFIG_MMC_DEBUG is not set
|
# CONFIG_MMC_DEBUG is not set
|
||||||
# CONFIG_MMC_UNSAFE_RESUME is not set
|
# CONFIG_MMC_UNSAFE_RESUME is not set
|
||||||
|
@ -926,7 +950,59 @@ CONFIG_MMC_AT91=y
|
||||||
# CONFIG_MMC_SPI is not set
|
# CONFIG_MMC_SPI is not set
|
||||||
# CONFIG_NEW_LEDS is not set
|
# CONFIG_NEW_LEDS is not set
|
||||||
CONFIG_RTC_LIB=y
|
CONFIG_RTC_LIB=y
|
||||||
# CONFIG_RTC_CLASS is not set
|
CONFIG_RTC_CLASS=y
|
||||||
|
CONFIG_RTC_HCTOSYS=y
|
||||||
|
CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
|
||||||
|
# CONFIG_RTC_DEBUG is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# RTC interfaces
|
||||||
|
#
|
||||||
|
CONFIG_RTC_INTF_SYSFS=y
|
||||||
|
CONFIG_RTC_INTF_PROC=y
|
||||||
|
CONFIG_RTC_INTF_DEV=y
|
||||||
|
# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
|
||||||
|
# CONFIG_RTC_DRV_TEST is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# I2C RTC drivers
|
||||||
|
#
|
||||||
|
# CONFIG_RTC_DRV_DS1307 is not set
|
||||||
|
# CONFIG_RTC_DRV_DS1374 is not set
|
||||||
|
# CONFIG_RTC_DRV_DS1672 is not set
|
||||||
|
# CONFIG_RTC_DRV_MAX6900 is not set
|
||||||
|
# CONFIG_RTC_DRV_RS5C372 is not set
|
||||||
|
# CONFIG_RTC_DRV_ISL1208 is not set
|
||||||
|
# CONFIG_RTC_DRV_X1205 is not set
|
||||||
|
# CONFIG_RTC_DRV_PCF8563 is not set
|
||||||
|
# CONFIG_RTC_DRV_PCF8583 is not set
|
||||||
|
# CONFIG_RTC_DRV_M41T80 is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# SPI RTC drivers
|
||||||
|
#
|
||||||
|
# CONFIG_RTC_DRV_MAX6902 is not set
|
||||||
|
# CONFIG_RTC_DRV_R9701 is not set
|
||||||
|
# CONFIG_RTC_DRV_RS5C348 is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Platform RTC drivers
|
||||||
|
#
|
||||||
|
# CONFIG_RTC_DRV_CMOS is not set
|
||||||
|
# CONFIG_RTC_DRV_DS1511 is not set
|
||||||
|
# CONFIG_RTC_DRV_DS1553 is not set
|
||||||
|
# CONFIG_RTC_DRV_DS1742 is not set
|
||||||
|
# CONFIG_RTC_DRV_STK17TA8 is not set
|
||||||
|
# CONFIG_RTC_DRV_M48T86 is not set
|
||||||
|
# CONFIG_RTC_DRV_M48T59 is not set
|
||||||
|
# CONFIG_RTC_DRV_V3020 is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# on-CPU RTC drivers
|
||||||
|
#
|
||||||
|
CONFIG_RTC_DRV_AT91SAM9=y
|
||||||
|
CONFIG_RTC_DRV_AT91SAM9_RTT=0
|
||||||
|
CONFIG_RTC_DRV_AT91SAM9_GPBR=0
|
||||||
|
|
||||||
#
|
#
|
||||||
# File systems
|
# File systems
|
||||||
|
|
|
@ -169,7 +169,6 @@ CONFIG_AT91_CF=y
|
||||||
# Kernel Features
|
# Kernel Features
|
||||||
#
|
#
|
||||||
# CONFIG_PREEMPT is not set
|
# CONFIG_PREEMPT is not set
|
||||||
# CONFIG_NO_IDLE_HZ is not set
|
|
||||||
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
|
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
|
||||||
CONFIG_SELECT_MEMORY_MODEL=y
|
CONFIG_SELECT_MEMORY_MODEL=y
|
||||||
CONFIG_FLATMEM_MANUAL=y
|
CONFIG_FLATMEM_MANUAL=y
|
||||||
|
|
|
@ -160,7 +160,6 @@ CONFIG_ISA_DMA_API=y
|
||||||
# Kernel Features
|
# Kernel Features
|
||||||
#
|
#
|
||||||
# CONFIG_PREEMPT is not set
|
# CONFIG_PREEMPT is not set
|
||||||
# CONFIG_NO_IDLE_HZ is not set
|
|
||||||
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
|
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
|
||||||
CONFIG_SELECT_MEMORY_MODEL=y
|
CONFIG_SELECT_MEMORY_MODEL=y
|
||||||
CONFIG_FLATMEM_MANUAL=y
|
CONFIG_FLATMEM_MANUAL=y
|
||||||
|
|
|
@ -220,7 +220,6 @@ CONFIG_CPU_CP15_MMU=y
|
||||||
#
|
#
|
||||||
# CONFIG_TICK_ONESHOT is not set
|
# CONFIG_TICK_ONESHOT is not set
|
||||||
# CONFIG_PREEMPT is not set
|
# CONFIG_PREEMPT is not set
|
||||||
# CONFIG_NO_IDLE_HZ is not set
|
|
||||||
CONFIG_HZ=100
|
CONFIG_HZ=100
|
||||||
# CONFIG_AEABI is not set
|
# CONFIG_AEABI is not set
|
||||||
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
|
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
|
||||||
|
|
|
@ -213,7 +213,6 @@ CONFIG_CPU_CP15_MMU=y
|
||||||
#
|
#
|
||||||
# CONFIG_TICK_ONESHOT is not set
|
# CONFIG_TICK_ONESHOT is not set
|
||||||
# CONFIG_PREEMPT is not set
|
# CONFIG_PREEMPT is not set
|
||||||
# CONFIG_NO_IDLE_HZ is not set
|
|
||||||
CONFIG_HZ=100
|
CONFIG_HZ=100
|
||||||
# CONFIG_AEABI is not set
|
# CONFIG_AEABI is not set
|
||||||
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
|
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
|
||||||
|
|
|
@ -213,7 +213,6 @@ CONFIG_CPU_CP15_MMU=y
|
||||||
#
|
#
|
||||||
# CONFIG_TICK_ONESHOT is not set
|
# CONFIG_TICK_ONESHOT is not set
|
||||||
# CONFIG_PREEMPT is not set
|
# CONFIG_PREEMPT is not set
|
||||||
# CONFIG_NO_IDLE_HZ is not set
|
|
||||||
CONFIG_HZ=100
|
CONFIG_HZ=100
|
||||||
# CONFIG_AEABI is not set
|
# CONFIG_AEABI is not set
|
||||||
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
|
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -211,7 +211,6 @@ CONFIG_CPU_CP15_MMU=y
|
||||||
#
|
#
|
||||||
# CONFIG_TICK_ONESHOT is not set
|
# CONFIG_TICK_ONESHOT is not set
|
||||||
# CONFIG_PREEMPT is not set
|
# CONFIG_PREEMPT is not set
|
||||||
# CONFIG_NO_IDLE_HZ is not set
|
|
||||||
CONFIG_HZ=100
|
CONFIG_HZ=100
|
||||||
# CONFIG_AEABI is not set
|
# CONFIG_AEABI is not set
|
||||||
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
|
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
|
||||||
|
|
|
@ -171,7 +171,6 @@ CONFIG_AT91_CF=m
|
||||||
# Kernel Features
|
# Kernel Features
|
||||||
#
|
#
|
||||||
CONFIG_PREEMPT=y
|
CONFIG_PREEMPT=y
|
||||||
CONFIG_NO_IDLE_HZ=y
|
|
||||||
CONFIG_HZ=100
|
CONFIG_HZ=100
|
||||||
# CONFIG_AEABI is not set
|
# CONFIG_AEABI is not set
|
||||||
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
|
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
|
||||||
|
|
|
@ -166,7 +166,6 @@ CONFIG_PCMCIA_SA1100=y
|
||||||
# Kernel Features
|
# Kernel Features
|
||||||
#
|
#
|
||||||
# CONFIG_PREEMPT is not set
|
# CONFIG_PREEMPT is not set
|
||||||
# CONFIG_NO_IDLE_HZ is not set
|
|
||||||
CONFIG_HZ=100
|
CONFIG_HZ=100
|
||||||
# CONFIG_AEABI is not set
|
# CONFIG_AEABI is not set
|
||||||
CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
|
CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
|
||||||
|
|
|
@ -165,7 +165,6 @@ CONFIG_PCMCIA_PXA2XX=y
|
||||||
# Kernel Features
|
# Kernel Features
|
||||||
#
|
#
|
||||||
CONFIG_PREEMPT=y
|
CONFIG_PREEMPT=y
|
||||||
# CONFIG_NO_IDLE_HZ is not set
|
|
||||||
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
|
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
|
||||||
CONFIG_SELECT_MEMORY_MODEL=y
|
CONFIG_SELECT_MEMORY_MODEL=y
|
||||||
CONFIG_FLATMEM_MANUAL=y
|
CONFIG_FLATMEM_MANUAL=y
|
||||||
|
|
|
@ -230,7 +230,6 @@ CONFIG_AT91_CF=y
|
||||||
#
|
#
|
||||||
# CONFIG_TICK_ONESHOT is not set
|
# CONFIG_TICK_ONESHOT is not set
|
||||||
CONFIG_PREEMPT=y
|
CONFIG_PREEMPT=y
|
||||||
# CONFIG_NO_IDLE_HZ is not set
|
|
||||||
CONFIG_HZ=100
|
CONFIG_HZ=100
|
||||||
# CONFIG_AEABI is not set
|
# CONFIG_AEABI is not set
|
||||||
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
|
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
|
||||||
|
|
|
@ -184,7 +184,6 @@ CONFIG_ARM_AMBA=y
|
||||||
# Kernel Features
|
# Kernel Features
|
||||||
#
|
#
|
||||||
# CONFIG_PREEMPT is not set
|
# CONFIG_PREEMPT is not set
|
||||||
# CONFIG_NO_IDLE_HZ is not set
|
|
||||||
CONFIG_HZ=100
|
CONFIG_HZ=100
|
||||||
# CONFIG_AEABI is not set
|
# CONFIG_AEABI is not set
|
||||||
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
|
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
|
||||||
|
|
|
@ -251,7 +251,6 @@ CONFIG_PCMCIA_PXA2XX=m
|
||||||
# Kernel Features
|
# Kernel Features
|
||||||
#
|
#
|
||||||
# CONFIG_PREEMPT is not set
|
# CONFIG_PREEMPT is not set
|
||||||
# CONFIG_NO_IDLE_HZ is not set
|
|
||||||
CONFIG_HZ=100
|
CONFIG_HZ=100
|
||||||
CONFIG_AEABI=y
|
CONFIG_AEABI=y
|
||||||
CONFIG_OABI_COMPAT=y
|
CONFIG_OABI_COMPAT=y
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue