Merge branch 'master' of /home/davem/src/GIT/linux-2.6/
Conflicts: drivers/firmware/iscsi_ibft.c
This commit is contained in:
		
						commit
						47871889c6
					
				
							
								
								
									
										79
									
								
								Documentation/ABI/testing/sysfs-devices-power
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								Documentation/ABI/testing/sysfs-devices-power
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,79 @@ | ||||
| What:		/sys/devices/.../power/ | ||||
| Date:		January 2009 | ||||
| Contact:	Rafael J. Wysocki <rjw@sisk.pl> | ||||
| Description: | ||||
| 		The /sys/devices/.../power directory contains attributes | ||||
| 		allowing the user space to check and modify some power | ||||
| 		management related properties of given device. | ||||
| 
 | ||||
| What:		/sys/devices/.../power/wakeup | ||||
| Date:		January 2009 | ||||
| Contact:	Rafael J. Wysocki <rjw@sisk.pl> | ||||
| Description: | ||||
| 		The /sys/devices/.../power/wakeup attribute allows the user | ||||
| 		space to check if the device is enabled to wake up the system | ||||
| 		from sleep states, such as the memory sleep state (suspend to | ||||
| 		RAM) and hibernation (suspend to disk), and to enable or disable | ||||
| 		it to do that as desired. | ||||
| 
 | ||||
| 		Some devices support "wakeup" events, which are hardware signals | ||||
| 		used to activate the system from a sleep state.  Such devices | ||||
| 		have one of the following two values for the sysfs power/wakeup | ||||
| 		file: | ||||
| 
 | ||||
| 		+ "enabled\n" to issue the events; | ||||
| 		+ "disabled\n" not to do so; | ||||
| 
 | ||||
| 		In that cases the user space can change the setting represented | ||||
| 		by the contents of this file by writing either "enabled", or | ||||
| 		"disabled" to it. | ||||
| 
 | ||||
| 		For the devices that are not capable of generating system wakeup | ||||
| 		events this file contains "\n".  In that cases the user space | ||||
| 		cannot modify the contents of this file and the device cannot be | ||||
| 		enabled to wake up the system. | ||||
| 
 | ||||
| What:		/sys/devices/.../power/control | ||||
| Date:		January 2009 | ||||
| Contact:	Rafael J. Wysocki <rjw@sisk.pl> | ||||
| Description: | ||||
| 		The /sys/devices/.../power/control attribute allows the user | ||||
| 		space to control the run-time power management of the device. | ||||
| 
 | ||||
| 		All devices have one of the following two values for the | ||||
| 		power/control file: | ||||
| 
 | ||||
| 		+ "auto\n" to allow the device to be power managed at run time; | ||||
| 		+ "on\n" to prevent the device from being power managed; | ||||
| 
 | ||||
| 		The default for all devices is "auto", which means that they may | ||||
| 		be subject to automatic power management, depending on their | ||||
| 		drivers.  Changing this attribute to "on" prevents the driver | ||||
| 		from power managing the device at run time.  Doing that while | ||||
| 		the device is suspended causes it to be woken up. | ||||
| 
 | ||||
| What:		/sys/devices/.../power/async | ||||
| Date:		January 2009 | ||||
| Contact:	Rafael J. Wysocki <rjw@sisk.pl> | ||||
| Description: | ||||
| 		The /sys/devices/.../async attribute allows the user space to | ||||
| 		enable or diasble the device's suspend and resume callbacks to | ||||
| 		be executed asynchronously (ie. in separate threads, in parallel | ||||
| 		with the main suspend/resume thread) during system-wide power | ||||
| 		transitions (eg. suspend to RAM, hibernation). | ||||
| 
 | ||||
| 		All devices have one of the following two values for the | ||||
| 		power/async file: | ||||
| 
 | ||||
| 		+ "enabled\n" to permit the asynchronous suspend/resume; | ||||
| 		+ "disabled\n" to forbid it; | ||||
| 
 | ||||
| 		The value of this attribute may be changed by writing either | ||||
| 		"enabled", or "disabled" to it. | ||||
| 
 | ||||
| 		It generally is unsafe to permit the asynchronous suspend/resume | ||||
| 		of a device unless it is certain that all of the PM dependencies | ||||
| 		of the device are known to the PM core.  However, for some | ||||
| 		devices this attribute is set to "enabled" by bus type code or | ||||
| 		device drivers and in that cases it should be safe to leave the | ||||
| 		default value. | ||||
| @ -101,3 +101,16 @@ Description: | ||||
| 
 | ||||
| 		CAUTION: Using it will cause your machine's real-time (CMOS) | ||||
| 		clock to be set to a random invalid time after a resume. | ||||
| 
 | ||||
| What:		/sys/power/pm_async | ||||
| Date:		January 2009 | ||||
| Contact:	Rafael J. Wysocki <rjw@sisk.pl> | ||||
| Description: | ||||
| 		The /sys/power/pm_async file controls the switch allowing the | ||||
| 		user space to enable or disable asynchronous suspend and resume | ||||
| 		of devices.  If enabled, this feature will cause some device | ||||
| 		drivers' suspend and resume callbacks to be executed in parallel | ||||
| 		with each other and with the main suspend thread.  It is enabled | ||||
| 		if this file contains "1", which is the default.  It may be | ||||
| 		disabled by writing "0" to this file, in which case all devices | ||||
| 		will be suspended and resumed synchronously. | ||||
|  | ||||
| @ -589,7 +589,8 @@ number of a video input as in &v4l2-input; field | ||||
| 	    <entry></entry> | ||||
| 	    <entry>A place holder for future extensions and custom | ||||
| (driver defined) buffer types | ||||
| <constant>V4L2_BUF_TYPE_PRIVATE</constant> and higher.</entry> | ||||
| <constant>V4L2_BUF_TYPE_PRIVATE</constant> and higher. Applications | ||||
| should set this to 0.</entry> | ||||
| 	  </row> | ||||
| 	</tbody> | ||||
|       </tgroup> | ||||
|  | ||||
| @ -54,12 +54,10 @@ to enqueue an empty (capturing) or filled (output) buffer in the | ||||
| driver's incoming queue. The semantics depend on the selected I/O | ||||
| method.</para> | ||||
| 
 | ||||
|     <para>To enqueue a <link linkend="mmap">memory mapped</link> | ||||
| buffer applications set the <structfield>type</structfield> field of a | ||||
| &v4l2-buffer; to the same buffer type as previously &v4l2-format; | ||||
| <structfield>type</structfield> and &v4l2-requestbuffers; | ||||
| <structfield>type</structfield>, the <structfield>memory</structfield> | ||||
| field to <constant>V4L2_MEMORY_MMAP</constant> and the | ||||
|     <para>To enqueue a buffer applications set the <structfield>type</structfield> | ||||
| field of a &v4l2-buffer; to the same buffer type as was previously used | ||||
| with &v4l2-format; <structfield>type</structfield> and &v4l2-requestbuffers; | ||||
| <structfield>type</structfield>. Applications must also set the | ||||
| <structfield>index</structfield> field. Valid index numbers range from | ||||
| zero to the number of buffers allocated with &VIDIOC-REQBUFS; | ||||
| (&v4l2-requestbuffers; <structfield>count</structfield>) minus one. The | ||||
| @ -70,8 +68,19 @@ intended for output (<structfield>type</structfield> is | ||||
| <constant>V4L2_BUF_TYPE_VBI_OUTPUT</constant>) applications must also | ||||
| initialize the <structfield>bytesused</structfield>, | ||||
| <structfield>field</structfield> and | ||||
| <structfield>timestamp</structfield> fields. See <xref | ||||
| 	linkend="buffer" /> for details. When | ||||
| <structfield>timestamp</structfield> fields, see <xref | ||||
| linkend="buffer" /> for details. | ||||
| Applications must also set <structfield>flags</structfield> to 0. If a driver | ||||
| supports capturing from specific video inputs and you want to specify a video | ||||
| input, then <structfield>flags</structfield> should be set to | ||||
| <constant>V4L2_BUF_FLAG_INPUT</constant> and the field | ||||
| <structfield>input</structfield> must be initialized to the desired input. | ||||
| The <structfield>reserved</structfield> field must be set to 0. | ||||
| </para> | ||||
| 
 | ||||
|     <para>To enqueue a <link linkend="mmap">memory mapped</link> | ||||
| buffer applications set the <structfield>memory</structfield> | ||||
| field to <constant>V4L2_MEMORY_MMAP</constant>. When | ||||
| <constant>VIDIOC_QBUF</constant> is called with a pointer to this | ||||
| structure the driver sets the | ||||
| <constant>V4L2_BUF_FLAG_MAPPED</constant> and | ||||
| @ -81,14 +90,10 @@ structure the driver sets the | ||||
| &EINVAL;.</para> | ||||
| 
 | ||||
|     <para>To enqueue a <link linkend="userp">user pointer</link> | ||||
| buffer applications set the <structfield>type</structfield> field of a | ||||
| &v4l2-buffer; to the same buffer type as previously &v4l2-format; | ||||
| <structfield>type</structfield> and &v4l2-requestbuffers; | ||||
| <structfield>type</structfield>, the <structfield>memory</structfield> | ||||
| field to <constant>V4L2_MEMORY_USERPTR</constant> and the | ||||
| buffer applications set the <structfield>memory</structfield> | ||||
| field to <constant>V4L2_MEMORY_USERPTR</constant>, the | ||||
| <structfield>m.userptr</structfield> field to the address of the | ||||
| buffer and <structfield>length</structfield> to its size. When the | ||||
| buffer is intended for output additional fields must be set as above. | ||||
| buffer and <structfield>length</structfield> to its size. | ||||
| When <constant>VIDIOC_QBUF</constant> is called with a pointer to this | ||||
| structure the driver sets the <constant>V4L2_BUF_FLAG_QUEUED</constant> | ||||
| flag and clears the <constant>V4L2_BUF_FLAG_MAPPED</constant> and | ||||
| @ -96,13 +101,14 @@ flag and clears the <constant>V4L2_BUF_FLAG_MAPPED</constant> and | ||||
| <structfield>flags</structfield> field, or it returns an error code. | ||||
| This ioctl locks the memory pages of the buffer in physical memory, | ||||
| they cannot be swapped out to disk. Buffers remain locked until | ||||
| dequeued, until the &VIDIOC-STREAMOFF; or &VIDIOC-REQBUFS; ioctl are | ||||
| dequeued, until the &VIDIOC-STREAMOFF; or &VIDIOC-REQBUFS; ioctl is | ||||
| called, or until the device is closed.</para> | ||||
| 
 | ||||
|     <para>Applications call the <constant>VIDIOC_DQBUF</constant> | ||||
| ioctl to dequeue a filled (capturing) or displayed (output) buffer | ||||
| from the driver's outgoing queue. They just set the | ||||
| <structfield>type</structfield> and <structfield>memory</structfield> | ||||
| <structfield>type</structfield>, <structfield>memory</structfield> | ||||
| and <structfield>reserved</structfield> | ||||
| fields of a &v4l2-buffer; as above, when <constant>VIDIOC_DQBUF</constant> | ||||
| is called with a pointer to this structure the driver fills the | ||||
| remaining fields or returns an error code.</para> | ||||
|  | ||||
| @ -54,12 +54,13 @@ buffer at any time after buffers have been allocated with the | ||||
| &VIDIOC-REQBUFS; ioctl.</para> | ||||
| 
 | ||||
|     <para>Applications set the <structfield>type</structfield> field | ||||
|     of a &v4l2-buffer; to the same buffer type as previously | ||||
|     of a &v4l2-buffer; to the same buffer type as was previously used with | ||||
| &v4l2-format; <structfield>type</structfield> and &v4l2-requestbuffers; | ||||
| <structfield>type</structfield>, and the <structfield>index</structfield> | ||||
|     field. Valid index numbers range from zero | ||||
| to the number of buffers allocated with &VIDIOC-REQBUFS; | ||||
|     (&v4l2-requestbuffers; <structfield>count</structfield>) minus one. | ||||
| The <structfield>reserved</structfield> field should to set to 0. | ||||
| After calling <constant>VIDIOC_QUERYBUF</constant> with a pointer to | ||||
|     this structure drivers return an error code or fill the rest of | ||||
| the structure.</para> | ||||
| @ -68,8 +69,8 @@ the structure.</para> | ||||
| <constant>V4L2_BUF_FLAG_MAPPED</constant>, | ||||
| <constant>V4L2_BUF_FLAG_QUEUED</constant> and | ||||
| <constant>V4L2_BUF_FLAG_DONE</constant> flags will be valid. The | ||||
| <structfield>memory</structfield> field will be set to | ||||
| <constant>V4L2_MEMORY_MMAP</constant>, the <structfield>m.offset</structfield> | ||||
| <structfield>memory</structfield> field will be set to the current | ||||
| I/O method, the <structfield>m.offset</structfield> | ||||
| contains the offset of the buffer from the start of the device memory, | ||||
| the <structfield>length</structfield> field its size. The driver may | ||||
| or may not set the remaining fields and flags, they are meaningless in | ||||
|  | ||||
| @ -54,23 +54,23 @@ I/O. Memory mapped buffers are located in device memory and must be | ||||
| allocated with this ioctl before they can be mapped into the | ||||
| application's address space. User buffers are allocated by | ||||
| applications themselves, and this ioctl is merely used to switch the | ||||
| driver into user pointer I/O mode.</para> | ||||
| driver into user pointer I/O mode and to setup some internal structures.</para> | ||||
| 
 | ||||
|     <para>To allocate device buffers applications initialize three | ||||
| fields of a <structname>v4l2_requestbuffers</structname> structure. | ||||
|     <para>To allocate device buffers applications initialize all | ||||
| fields of the <structname>v4l2_requestbuffers</structname> structure. | ||||
| They set the <structfield>type</structfield> field to the respective | ||||
| stream or buffer type, the <structfield>count</structfield> field to | ||||
| the desired number of buffers, and <structfield>memory</structfield> | ||||
| must be set to <constant>V4L2_MEMORY_MMAP</constant>. When the ioctl | ||||
| is called with a pointer to this structure the driver attempts to | ||||
| allocate the requested number of buffers and stores the actual number | ||||
| the desired number of buffers, <structfield>memory</structfield> | ||||
| must be set to the requested I/O method and the reserved array | ||||
| must be zeroed. When the ioctl | ||||
| is called with a pointer to this structure the driver will attempt to allocate | ||||
| the requested number of buffers and it stores the actual number | ||||
| allocated in the <structfield>count</structfield> field. It can be | ||||
| smaller than the number requested, even zero, when the driver runs out | ||||
| of free memory. A larger number is possible when the driver requires | ||||
| more buffers to function correctly.<footnote> | ||||
| 	<para>For example video output requires at least two buffers, | ||||
| of free memory. A larger number is also possible when the driver requires | ||||
| more buffers to function correctly. For example video output requires at least two buffers, | ||||
| one displayed and one filled by the application.</para> | ||||
| 	</footnote> When memory mapping I/O is not supported the ioctl | ||||
|     <para>When the I/O method is not supported the ioctl | ||||
| returns an &EINVAL;.</para> | ||||
| 
 | ||||
|     <para>Applications can call <constant>VIDIOC_REQBUFS</constant> | ||||
| @ -81,14 +81,6 @@ in progress, an implicit &VIDIOC-STREAMOFF;. <!-- mhs: I see no | ||||
| reason why munmap()ping one or even all buffers must imply | ||||
| streamoff.--></para> | ||||
| 
 | ||||
|     <para>To negotiate user pointer I/O, applications initialize only | ||||
| the <structfield>type</structfield> field and set | ||||
| <structfield>memory</structfield> to | ||||
| <constant>V4L2_MEMORY_USERPTR</constant>. When the ioctl is called | ||||
| with a pointer to this structure the driver prepares for user pointer | ||||
| I/O, when this I/O method is not supported the ioctl returns an | ||||
| &EINVAL;.</para> | ||||
| 
 | ||||
|     <table pgwide="1" frame="none" id="v4l2-requestbuffers"> | ||||
|       <title>struct <structname>v4l2_requestbuffers</structname></title> | ||||
|       <tgroup cols="3"> | ||||
| @ -97,9 +89,7 @@ I/O, when this I/O method is not supported the ioctl returns an | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>count</structfield></entry> | ||||
| 	    <entry>The number of buffers requested or granted. This | ||||
| field is only used when <structfield>memory</structfield> is set to | ||||
| <constant>V4L2_MEMORY_MMAP</constant>.</entry> | ||||
| 	    <entry>The number of buffers requested or granted.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>&v4l2-buf-type;</entry> | ||||
| @ -120,7 +110,7 @@ as the &v4l2-format; <structfield>type</structfield> field. See <xref | ||||
| 	    <entry><structfield>reserved</structfield>[2]</entry> | ||||
| 	    <entry>A place holder for future extensions and custom | ||||
| (driver defined) buffer types <constant>V4L2_BUF_TYPE_PRIVATE</constant> and | ||||
| higher.</entry> | ||||
| higher. This array should be zeroed by applications.</entry> | ||||
| 	  </row> | ||||
| 	</tbody> | ||||
|       </tgroup> | ||||
|  | ||||
| @ -6,16 +6,22 @@ checklist.txt | ||||
| 	- Review Checklist for RCU Patches | ||||
| listRCU.txt | ||||
| 	- Using RCU to Protect Read-Mostly Linked Lists | ||||
| lockdep.txt | ||||
| 	- RCU and lockdep checking | ||||
| NMI-RCU.txt | ||||
| 	- Using RCU to Protect Dynamic NMI Handlers | ||||
| rcubarrier.txt | ||||
| 	- RCU and Unloadable Modules | ||||
| rculist_nulls.txt | ||||
| 	- RCU list primitives for use with SLAB_DESTROY_BY_RCU | ||||
| rcuref.txt | ||||
| 	- Reference-count design for elements of lists/arrays protected by RCU | ||||
| rcu.txt | ||||
| 	- RCU Concepts | ||||
| rcubarrier.txt | ||||
| 	- Unloading modules that use RCU callbacks | ||||
| RTFP.txt | ||||
| 	- List of RCU papers (bibliography) going back to 1980. | ||||
| stallwarn.txt | ||||
| 	- RCU CPU stall warnings (CONFIG_RCU_CPU_STALL_DETECTOR) | ||||
| torture.txt | ||||
| 	- RCU Torture Test Operation (CONFIG_RCU_TORTURE_TEST) | ||||
| trace.txt | ||||
|  | ||||
| @ -25,10 +25,10 @@ to be referencing the data structure.  However, this mechanism was not | ||||
| optimized for modern computer systems, which is not surprising given | ||||
| that these overheads were not so expensive in the mid-80s.  Nonetheless, | ||||
| passive serialization appears to be the first deferred-destruction | ||||
| mechanism to be used in production.  Furthermore, the relevant patent has | ||||
| lapsed, so this approach may be used in non-GPL software, if desired. | ||||
| (In contrast, use of RCU is permitted only in software licensed under | ||||
| GPL.  Sorry!!!) | ||||
| mechanism to be used in production.  Furthermore, the relevant patent | ||||
| has lapsed, so this approach may be used in non-GPL software, if desired. | ||||
| (In contrast, implementation of RCU is permitted only in software licensed | ||||
| under either GPL or LGPL.  Sorry!!!) | ||||
| 
 | ||||
| In 1990, Pugh [Pugh90] noted that explicitly tracking which threads | ||||
| were reading a given data structure permitted deferred free to operate | ||||
| @ -150,6 +150,18 @@ preemptible RCU [PaulEMcKenney2007PreemptibleRCU], and the three-part | ||||
| LWN "What is RCU?" series [PaulEMcKenney2007WhatIsRCUFundamentally, | ||||
| PaulEMcKenney2008WhatIsRCUUsage, and PaulEMcKenney2008WhatIsRCUAPI]. | ||||
| 
 | ||||
| 2008 saw a journal paper on real-time RCU [DinakarGuniguntala2008IBMSysJ], | ||||
| a history of how Linux changed RCU more than RCU changed Linux | ||||
| [PaulEMcKenney2008RCUOSR], and a design overview of hierarchical RCU | ||||
| [PaulEMcKenney2008HierarchicalRCU]. | ||||
| 
 | ||||
| 2009 introduced user-level RCU algorithms [PaulEMcKenney2009MaliciousURCU], | ||||
| which Mathieu Desnoyers is now maintaining [MathieuDesnoyers2009URCU] | ||||
| [MathieuDesnoyersPhD].  TINY_RCU [PaulEMcKenney2009BloatWatchRCU] made | ||||
| its appearance, as did expedited RCU [PaulEMcKenney2009expeditedRCU]. | ||||
| The problem of resizeable RCU-protected hash tables may now be on a path | ||||
| to a solution [JoshTriplett2009RPHash]. | ||||
| 
 | ||||
| Bibtex Entries | ||||
| 
 | ||||
| @article{Kung80 | ||||
| @ -730,6 +742,11 @@ Revised: | ||||
| " | ||||
| } | ||||
| 
 | ||||
| # | ||||
| #	"What is RCU?" LWN series. | ||||
| # | ||||
| ######################################################################## | ||||
| 
 | ||||
| @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}" | ||||
| @ -820,3 +837,39 @@ Revised: | ||||
| 	Uniprocessor assumptions allow simplified RCU implementation. | ||||
| " | ||||
| } | ||||
| 
 | ||||
| @unpublished{PaulEMcKenney2009expeditedRCU | ||||
| ,Author="Paul E. McKenney" | ||||
| ,Title="[{PATCH} -tip 0/3] expedited 'big hammer' {RCU} grace periods" | ||||
| ,month="June" | ||||
| ,day="25" | ||||
| ,year="2009" | ||||
| ,note="Available: | ||||
| \url{http://lkml.org/lkml/2009/6/25/306} | ||||
| [Viewed August 16, 2009]" | ||||
| ,annotation=" | ||||
| 	First posting of expedited RCU to be accepted into -tip. | ||||
| " | ||||
| } | ||||
| 
 | ||||
| @unpublished{JoshTriplett2009RPHash | ||||
| ,Author="Josh Triplett" | ||||
| ,Title="Scalable concurrent hash tables via relativistic programming" | ||||
| ,month="September" | ||||
| ,year="2009" | ||||
| ,note="Linux Plumbers Conference presentation" | ||||
| ,annotation=" | ||||
| 	RP fun with hash tables. | ||||
| " | ||||
| } | ||||
| 
 | ||||
| @phdthesis{MathieuDesnoyersPhD | ||||
| , title  = "Low-Impact Operating System Tracing" | ||||
| , author = "Mathieu Desnoyers" | ||||
| , school = "Ecole Polytechnique de Montr\'{e}al" | ||||
| , month  = "December" | ||||
| , year   = 2009 | ||||
| ,note="Available: | ||||
| \url{http://www.lttng.org/pub/thesis/desnoyers-dissertation-2009-12.pdf} | ||||
| [Viewed December 9, 2009]" | ||||
| } | ||||
|  | ||||
| @ -8,13 +8,12 @@ would cause.  This list is based on experiences reviewing such patches | ||||
| over a rather long period of time, but improvements are always welcome! | ||||
| 
 | ||||
| 0.	Is RCU being applied to a read-mostly situation?  If the data | ||||
| 	structure is updated more than about 10% of the time, then | ||||
| 	you should strongly consider some other approach, unless | ||||
| 	detailed performance measurements show that RCU is nonetheless | ||||
| 	the right tool for the job.  Yes, you might think of RCU | ||||
| 	as simply cutting overhead off of the readers and imposing it | ||||
| 	on the writers.  That is exactly why normal uses of RCU will | ||||
| 	do much more reading than updating. | ||||
| 	structure is updated more than about 10% of the time, then you | ||||
| 	should strongly consider some other approach, unless detailed | ||||
| 	performance measurements show that RCU is nonetheless the right | ||||
| 	tool for the job.  Yes, RCU does reduce read-side overhead by | ||||
| 	increasing write-side overhead, which is exactly why normal uses | ||||
| 	of RCU will do much more reading than updating. | ||||
| 
 | ||||
| 	Another exception is where performance is not an issue, and RCU | ||||
| 	provides a simpler implementation.  An example of this situation | ||||
| @ -35,13 +34,13 @@ over a rather long period of time, but improvements are always welcome! | ||||
| 
 | ||||
| 	If you choose #b, be prepared to describe how you have handled | ||||
| 	memory barriers on weakly ordered machines (pretty much all of | ||||
| 	them -- even x86 allows reads to be reordered), and be prepared | ||||
| 	to explain why this added complexity is worthwhile.  If you | ||||
| 	choose #c, be prepared to explain how this single task does not | ||||
| 	become a major bottleneck on big multiprocessor machines (for | ||||
| 	example, if the task is updating information relating to itself | ||||
| 	that other tasks can read, there by definition can be no | ||||
| 	bottleneck). | ||||
| 	them -- even x86 allows later loads to be reordered to precede | ||||
| 	earlier stores), and be prepared to explain why this added | ||||
| 	complexity is worthwhile.  If you choose #c, be prepared to | ||||
| 	explain how this single task does not become a major bottleneck on | ||||
| 	big multiprocessor machines (for example, if the task is updating | ||||
| 	information relating to itself that other tasks can read, there | ||||
| 	by definition can be no bottleneck). | ||||
| 
 | ||||
| 2.	Do the RCU read-side critical sections make proper use of | ||||
| 	rcu_read_lock() and friends?  These primitives are needed | ||||
| @ -51,8 +50,10 @@ over a rather long period of time, but improvements are always welcome! | ||||
| 	actuarial risk of your kernel. | ||||
| 
 | ||||
| 	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() | ||||
| 	or by the appropriate update-side lock. | ||||
| 	pointer must be covered by rcu_read_lock(), rcu_read_lock_bh(), | ||||
| 	rcu_read_lock_sched(), or by the appropriate update-side lock. | ||||
| 	Disabling of preemption can serve as rcu_read_lock_sched(), but | ||||
| 	is less readable. | ||||
| 
 | ||||
| 3.	Does the update code tolerate concurrent accesses? | ||||
| 
 | ||||
| @ -62,25 +63,27 @@ over a rather long period of time, but improvements are always welcome! | ||||
| 	of ways to handle this concurrency, depending on the situation: | ||||
| 
 | ||||
| 	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. | ||||
| 		primitives to add, remove, and replace elements on | ||||
| 		an RCU-protected list.	Alternatively, use the other | ||||
| 		RCU-protected data structures 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. | ||||
| 		the readers refrain from accessing can be guarded by | ||||
| 		some other lock acquired only by updaters, if desired. | ||||
| 
 | ||||
| 		This works quite well, also. | ||||
| 
 | ||||
| 	c.	Make updates appear atomic to readers.  For example, | ||||
| 		pointer updates to properly aligned fields will appear | ||||
| 		atomic, as will individual atomic primitives.  Operations | ||||
| 		performed under a lock and sequences of multiple atomic | ||||
| 		primitives will -not- appear to be atomic. | ||||
| 		pointer updates to properly aligned fields will | ||||
| 		appear atomic, as will individual atomic primitives. | ||||
| 		Sequences of perations performed under a lock will -not- | ||||
| 		appear to be atomic to RCU readers, nor will sequences | ||||
| 		of multiple atomic primitives. | ||||
| 
 | ||||
| 		This can work, but is starting to get a bit tricky. | ||||
| 
 | ||||
| @ -98,9 +101,9 @@ over a rather long period of time, but improvements are always welcome! | ||||
| 		a new structure containing updated values. | ||||
| 
 | ||||
| 4.	Weakly ordered CPUs pose special challenges.  Almost all CPUs | ||||
| 	are weakly ordered -- even i386 CPUs allow reads to be reordered. | ||||
| 	RCU code must take all of the following measures to prevent | ||||
| 	memory-corruption problems: | ||||
| 	are weakly ordered -- even x86 CPUs allow later loads to be | ||||
| 	reordered to precede earlier stores.  RCU code must take all of | ||||
| 	the following measures to prevent memory-corruption problems: | ||||
| 
 | ||||
| 	a.	Readers must maintain proper ordering of their memory | ||||
| 		accesses.  The rcu_dereference() primitive ensures that | ||||
| @ -113,14 +116,25 @@ over a rather long period of time, but improvements are always welcome! | ||||
| 		The rcu_dereference() primitive is also an excellent | ||||
| 		documentation aid, letting the person reading the code | ||||
| 		know exactly which pointers are protected by RCU. | ||||
| 		Please note that compilers can also reorder code, and | ||||
| 		they are becoming increasingly aggressive about doing | ||||
| 		just that.  The rcu_dereference() primitive therefore | ||||
| 		also prevents destructive compiler optimizations. | ||||
| 
 | ||||
| 		The rcu_dereference() primitive is used by the various | ||||
| 		"_rcu()" list-traversal primitives, such as the | ||||
| 		list_for_each_entry_rcu().  Note that it is perfectly | ||||
| 		legal (if redundant) for update-side code to use | ||||
| 		rcu_dereference() and the "_rcu()" list-traversal | ||||
| 		primitives.  This is particularly useful in code | ||||
| 		that is common to readers and updaters. | ||||
| 		The rcu_dereference() primitive is used by the | ||||
| 		various "_rcu()" list-traversal primitives, such | ||||
| 		as the list_for_each_entry_rcu().  Note that it is | ||||
| 		perfectly legal (if redundant) for update-side code to | ||||
| 		use rcu_dereference() and the "_rcu()" list-traversal | ||||
| 		primitives.  This is particularly useful in code that | ||||
| 		is common to readers and updaters.  However, lockdep | ||||
| 		will complain if you access rcu_dereference() outside | ||||
| 		of an RCU read-side critical section.  See lockdep.txt | ||||
| 		to learn what to do about this. | ||||
| 
 | ||||
| 		Of course, neither rcu_dereference() nor the "_rcu()" | ||||
| 		list-traversal primitives can substitute for a good | ||||
| 		concurrency design coordinating among multiple updaters. | ||||
| 
 | ||||
| 	b.	If the list macros are being used, the list_add_tail_rcu() | ||||
| 		and list_add_rcu() primitives must be used in order | ||||
| @ -135,11 +149,14 @@ over a rather long period of time, but improvements are always welcome! | ||||
| 		readers.  Similarly, if the hlist macros are being used, | ||||
| 		the hlist_del_rcu() primitive is required. | ||||
| 
 | ||||
| 		The list_replace_rcu() primitive may be used to | ||||
| 		replace an old structure with a new one in an | ||||
| 		RCU-protected list. | ||||
| 		The list_replace_rcu() and hlist_replace_rcu() primitives | ||||
| 		may be used to replace an old structure with a new one | ||||
| 		in their respective types of RCU-protected lists. | ||||
| 
 | ||||
| 	d.	Updates must ensure that initialization of a given | ||||
| 	d.	Rules similar to (4b) and (4c) apply to the "hlist_nulls" | ||||
| 		type of RCU-protected linked lists. | ||||
| 
 | ||||
| 	e.	Updates must ensure that initialization of a given | ||||
| 		structure happens before pointers to that structure are | ||||
| 		publicized.  Use the rcu_assign_pointer() primitive | ||||
| 		when publicizing a pointer to a structure that can | ||||
| @ -151,16 +168,31 @@ over a rather long period of time, but improvements are always welcome! | ||||
| 	it cannot block. | ||||
| 
 | ||||
| 6.	Since synchronize_rcu() can block, it cannot be called from | ||||
| 	any sort of irq context.  Ditto for synchronize_sched() and | ||||
| 	synchronize_srcu(). | ||||
| 	any sort of irq context.  The same rule applies for | ||||
| 	synchronize_rcu_bh(), synchronize_sched(), synchronize_srcu(), | ||||
| 	synchronize_rcu_expedited(), synchronize_rcu_bh_expedited(), | ||||
| 	synchronize_sched_expedite(), and synchronize_srcu_expedited(). | ||||
| 
 | ||||
| 7.	If the updater uses call_rcu(), then the corresponding readers | ||||
| 	must use rcu_read_lock() and rcu_read_unlock().  If the updater | ||||
| 	uses call_rcu_bh(), then the corresponding readers must use | ||||
| 	rcu_read_lock_bh() and rcu_read_unlock_bh().  If the updater | ||||
| 	uses call_rcu_sched(), then the corresponding readers must | ||||
| 	disable preemption.  Mixing things up will result in confusion | ||||
| 	and broken kernels. | ||||
| 	The expedited forms of these primitives have the same semantics | ||||
| 	as the non-expedited forms, but expediting is both expensive | ||||
| 	and unfriendly to real-time workloads.	Use of the expedited | ||||
| 	primitives should be restricted to rare configuration-change | ||||
| 	operations that would not normally be undertaken while a real-time | ||||
| 	workload is running. | ||||
| 
 | ||||
| 7.	If the updater uses call_rcu() or synchronize_rcu(), then the | ||||
| 	corresponding readers must use rcu_read_lock() and | ||||
| 	rcu_read_unlock().  If the updater uses call_rcu_bh() or | ||||
| 	synchronize_rcu_bh(), then the corresponding readers must | ||||
| 	use rcu_read_lock_bh() and rcu_read_unlock_bh().  If the | ||||
| 	updater uses call_rcu_sched() or synchronize_sched(), then | ||||
| 	the corresponding readers must disable preemption, possibly | ||||
| 	by calling rcu_read_lock_sched() and rcu_read_unlock_sched(). | ||||
| 	If the updater uses synchronize_srcu(), the the corresponding | ||||
| 	readers must use srcu_read_lock() and srcu_read_unlock(), | ||||
| 	and with the same srcu_struct.	The rules for the expedited | ||||
| 	primitives are the same as for their non-expedited counterparts. | ||||
| 	Mixing things up will result in confusion and broken kernels. | ||||
| 
 | ||||
| 	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() | ||||
| @ -212,6 +244,8 @@ over a rather long period of time, but improvements are always welcome! | ||||
| 	e.	Periodically invoke synchronize_rcu(), permitting a limited | ||||
| 		number of updates per grace period. | ||||
| 
 | ||||
| 	The same cautions apply to call_rcu_bh() and call_rcu_sched(). | ||||
| 
 | ||||
| 9.	All RCU list-traversal primitives, which include | ||||
| 	rcu_dereference(), list_for_each_entry_rcu(), | ||||
| 	list_for_each_continue_rcu(), and list_for_each_safe_rcu(), | ||||
| @ -219,7 +253,9 @@ over a rather long period of time, but improvements are always welcome! | ||||
| 	must be protected by appropriate update-side locks.  RCU | ||||
| 	read-side critical sections are delimited by rcu_read_lock() | ||||
| 	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(), in which case | ||||
| 	the matching rcu_dereference() primitive must be used in order | ||||
| 	to keep lockdep happy, in this case, rcu_dereference_bh(). | ||||
| 
 | ||||
| 	The reason that it is permissible to use RCU list-traversal | ||||
| 	primitives when the update-side lock is held is that doing so | ||||
| @ -229,7 +265,8 @@ over a rather long period of time, but improvements are always welcome! | ||||
| 10.	Conversely, if you are in an RCU read-side critical section, | ||||
| 	and you don't hold the appropriate update-side lock, you -must- | ||||
| 	use the "_rcu()" variants of the list macros.  Failing to do so | ||||
| 	will break Alpha and confuse people reading your code. | ||||
| 	will break Alpha, cause aggressive compilers to generate bad code, | ||||
| 	and confuse people trying to read your code. | ||||
| 
 | ||||
| 11.	Note that synchronize_rcu() -only- guarantees to wait until | ||||
| 	all currently executing rcu_read_lock()-protected RCU read-side | ||||
| @ -239,15 +276,21 @@ over a rather long period of time, but improvements are always welcome! | ||||
| 	rcu_read_lock()-protected read-side critical sections, do -not- | ||||
| 	use synchronize_rcu(). | ||||
| 
 | ||||
| 	If you want to wait for some of these other things, you might | ||||
| 	instead need to use synchronize_irq() or synchronize_sched(). | ||||
| 	Similarly, disabling preemption is not an acceptable substitute | ||||
| 	for rcu_read_lock().  Code that attempts to use preemption | ||||
| 	disabling where it should be using rcu_read_lock() will break | ||||
| 	in real-time kernel builds. | ||||
| 
 | ||||
| 	If you want to wait for interrupt handlers, NMI handlers, and | ||||
| 	code under the influence of preempt_disable(), you instead | ||||
| 	need to use synchronize_irq() or synchronize_sched(). | ||||
| 
 | ||||
| 12.	Any lock acquired by an RCU callback must be acquired elsewhere | ||||
| 	with softirq disabled, e.g., via spin_lock_irqsave(), | ||||
| 	spin_lock_bh(), etc.  Failing to disable irq on a given | ||||
| 	acquisition of that lock will result in deadlock as soon as the | ||||
| 	RCU callback happens to interrupt that acquisition's critical | ||||
| 	section. | ||||
| 	acquisition of that lock will result in deadlock as soon as | ||||
| 	the RCU softirq handler happens to run your RCU callback while | ||||
| 	interrupting that acquisition's critical section. | ||||
| 
 | ||||
| 13.	RCU callbacks can be and are executed in parallel.  In many cases, | ||||
| 	the callback code simply wrappers around kfree(), so that this | ||||
| @ -265,29 +308,30 @@ over a rather long period of time, but improvements are always welcome! | ||||
| 	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()) | ||||
| 	may only be invoked from process context.  Unlike other forms of | ||||
| 	RCU, it -is- permissible to block in an SRCU read-side critical | ||||
| 	section (demarked by srcu_read_lock() and srcu_read_unlock()), | ||||
| 	hence the "SRCU": "sleepable RCU".  Please note that if you | ||||
| 	don't need to sleep in read-side critical sections, you should | ||||
| 	be using RCU rather than SRCU, because RCU is almost always | ||||
| 	faster and easier to use than is SRCU. | ||||
| 14.	SRCU (srcu_read_lock(), srcu_read_unlock(), srcu_dereference(), | ||||
| 	synchronize_srcu(), and synchronize_srcu_expedited()) may only | ||||
| 	be invoked from process context.  Unlike other forms of RCU, it | ||||
| 	-is- permissible to block in an SRCU read-side critical section | ||||
| 	(demarked by srcu_read_lock() and srcu_read_unlock()), hence the | ||||
| 	"SRCU": "sleepable RCU".  Please note that if you don't need | ||||
| 	to sleep in read-side critical sections, you should be using | ||||
| 	RCU rather than SRCU, because RCU is almost always faster and | ||||
| 	easier to use than is SRCU. | ||||
| 
 | ||||
| 	Also unlike other forms of RCU, explicit initialization | ||||
| 	and cleanup is required via init_srcu_struct() and | ||||
| 	cleanup_srcu_struct().	These are passed a "struct srcu_struct" | ||||
| 	that defines the scope of a given SRCU domain.	Once initialized, | ||||
| 	the srcu_struct is passed to srcu_read_lock(), srcu_read_unlock() | ||||
| 	and synchronize_srcu().  A given synchronize_srcu() waits only | ||||
| 	for SRCU read-side critical sections governed by srcu_read_lock() | ||||
| 	and srcu_read_unlock() calls that have been passd the same | ||||
| 	srcu_struct.  This property is what makes sleeping read-side | ||||
| 	critical sections tolerable -- a given subsystem delays only | ||||
| 	its own updates, not those of other subsystems using SRCU. | ||||
| 	Therefore, SRCU is less prone to OOM the system than RCU would | ||||
| 	be if RCU's read-side critical sections were permitted to | ||||
| 	sleep. | ||||
| 	synchronize_srcu(), and synchronize_srcu_expedited().  A given | ||||
| 	synchronize_srcu() waits only for SRCU read-side critical | ||||
| 	sections governed by srcu_read_lock() and srcu_read_unlock() | ||||
| 	calls that have been passed the same srcu_struct.  This property | ||||
| 	is what makes sleeping read-side critical sections tolerable -- | ||||
| 	a given subsystem delays only its own updates, not those of other | ||||
| 	subsystems using SRCU.	Therefore, SRCU is less prone to OOM the | ||||
| 	system than RCU would be if RCU's read-side critical sections | ||||
| 	were permitted to sleep. | ||||
| 
 | ||||
| 	The ability to sleep in read-side critical sections does not | ||||
| 	come for free.	First, corresponding srcu_read_lock() and | ||||
| @ -311,12 +355,12 @@ over a rather long period of time, but improvements are always welcome! | ||||
| 	destructive operation, and -only- -then- invoke call_rcu(), | ||||
| 	synchronize_rcu(), or friends. | ||||
| 
 | ||||
| 	Because these primitives only wait for pre-existing readers, | ||||
| 	it is the caller's responsibility to guarantee safety to | ||||
| 	any subsequent readers. | ||||
| 	Because these primitives only wait for pre-existing readers, it | ||||
| 	is the caller's responsibility to guarantee that any subsequent | ||||
| 	readers will execute safely. | ||||
| 
 | ||||
| 16.	The various RCU read-side primitives do -not- contain memory | ||||
| 	barriers.  The CPU (and in some cases, the compiler) is free | ||||
| 	to reorder code into and out of RCU read-side critical sections. | ||||
| 	It is the responsibility of the RCU update-side primitives to | ||||
| 	deal with this. | ||||
| 16.	The various RCU read-side primitives do -not- necessarily contain | ||||
| 	memory barriers.  You should therefore plan for the CPU | ||||
| 	and the compiler to freely reorder code into and out of RCU | ||||
| 	read-side critical sections.  It is the responsibility of the | ||||
| 	RCU update-side primitives to deal with this. | ||||
|  | ||||
							
								
								
									
										67
									
								
								Documentation/RCU/lockdep.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								Documentation/RCU/lockdep.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,67 @@ | ||||
| RCU and lockdep checking | ||||
| 
 | ||||
| All flavors of RCU have lockdep checking available, so that lockdep is | ||||
| aware of when each task enters and leaves any flavor of RCU read-side | ||||
| critical section.  Each flavor of RCU is tracked separately (but note | ||||
| that this is not the case in 2.6.32 and earlier).  This allows lockdep's | ||||
| tracking to include RCU state, which can sometimes help when debugging | ||||
| deadlocks and the like. | ||||
| 
 | ||||
| In addition, RCU provides the following primitives that check lockdep's | ||||
| state: | ||||
| 
 | ||||
| 	rcu_read_lock_held() for normal RCU. | ||||
| 	rcu_read_lock_bh_held() for RCU-bh. | ||||
| 	rcu_read_lock_sched_held() for RCU-sched. | ||||
| 	srcu_read_lock_held() for SRCU. | ||||
| 
 | ||||
| These functions are conservative, and will therefore return 1 if they | ||||
| aren't certain (for example, if CONFIG_DEBUG_LOCK_ALLOC is not set). | ||||
| This prevents things like WARN_ON(!rcu_read_lock_held()) from giving false | ||||
| positives when lockdep is disabled. | ||||
| 
 | ||||
| In addition, a separate kernel config parameter CONFIG_PROVE_RCU enables | ||||
| checking of rcu_dereference() primitives: | ||||
| 
 | ||||
| 	rcu_dereference(p): | ||||
| 		Check for RCU read-side critical section. | ||||
| 	rcu_dereference_bh(p): | ||||
| 		Check for RCU-bh read-side critical section. | ||||
| 	rcu_dereference_sched(p): | ||||
| 		Check for RCU-sched read-side critical section. | ||||
| 	srcu_dereference(p, sp): | ||||
| 		Check for SRCU read-side critical section. | ||||
| 	rcu_dereference_check(p, c): | ||||
| 		Use explicit check expression "c". | ||||
| 	rcu_dereference_raw(p) | ||||
| 		Don't check.  (Use sparingly, if at all.) | ||||
| 
 | ||||
| The rcu_dereference_check() check expression can be any boolean | ||||
| expression, but would normally include one of the rcu_read_lock_held() | ||||
| family of functions and a lockdep expression.  However, any boolean | ||||
| expression can be used.  For a moderately ornate example, consider | ||||
| the following: | ||||
| 
 | ||||
| 	file = rcu_dereference_check(fdt->fd[fd], | ||||
| 				     rcu_read_lock_held() || | ||||
| 				     lockdep_is_held(&files->file_lock) || | ||||
| 				     atomic_read(&files->count) == 1); | ||||
| 
 | ||||
| This expression picks up the pointer "fdt->fd[fd]" in an RCU-safe manner, | ||||
| and, if CONFIG_PROVE_RCU is configured, verifies that this expression | ||||
| is used in: | ||||
| 
 | ||||
| 1.	An RCU read-side critical section, or | ||||
| 2.	with files->file_lock held, or | ||||
| 3.	on an unshared files_struct. | ||||
| 
 | ||||
| In case (1), the pointer is picked up in an RCU-safe manner for vanilla | ||||
| RCU read-side critical sections, in case (2) the ->file_lock prevents | ||||
| any change from taking place, and finally, in case (3) the current task | ||||
| is the only task accessing the file_struct, again preventing any change | ||||
| from taking place. | ||||
| 
 | ||||
| There are currently only "universal" versions of the rcu_assign_pointer() | ||||
| and RCU list-/tree-traversal primitives, which do not (yet) check for | ||||
| being in an RCU read-side critical section.  In the future, separate | ||||
| versions of these primitives might be created. | ||||
| @ -75,6 +75,8 @@ o	I hear that RCU is patented?  What is with that? | ||||
| 	search for the string "Patent" in RTFP.txt to find them. | ||||
| 	Of these, one was allowed to lapse by the assignee, and the | ||||
| 	others have been contributed to the Linux kernel under GPL. | ||||
| 	There are now also LGPL implementations of user-level RCU | ||||
| 	available (http://lttng.org/?q=node/18). | ||||
| 
 | ||||
| o	I hear that RCU needs work in order to support realtime kernels? | ||||
| 
 | ||||
| @ -91,48 +93,4 @@ o	Where can I find more information on RCU? | ||||
| 
 | ||||
| o	What are all these files in this directory? | ||||
| 
 | ||||
| 
 | ||||
| 	NMI-RCU.txt | ||||
| 
 | ||||
| 		Describes how to use RCU to implement dynamic | ||||
| 		NMI handlers, which can be revectored on the fly, | ||||
| 		without rebooting. | ||||
| 
 | ||||
| 	RTFP.txt | ||||
| 
 | ||||
| 		List of RCU-related publications and web sites. | ||||
| 
 | ||||
| 	UP.txt | ||||
| 
 | ||||
| 		Discussion of RCU usage in UP kernels. | ||||
| 
 | ||||
| 	arrayRCU.txt | ||||
| 
 | ||||
| 		Describes how to use RCU to protect arrays, with | ||||
| 		resizeable arrays whose elements reference other | ||||
| 		data structures being of the most interest. | ||||
| 
 | ||||
| 	checklist.txt | ||||
| 
 | ||||
| 		Lists things to check for when inspecting code that | ||||
| 		uses RCU. | ||||
| 
 | ||||
| 	listRCU.txt | ||||
| 
 | ||||
| 		Describes how to use RCU to protect linked lists. | ||||
| 		This is the simplest and most common use of RCU | ||||
| 		in the Linux kernel. | ||||
| 
 | ||||
| 	rcu.txt | ||||
| 
 | ||||
| 		You are reading it! | ||||
| 
 | ||||
| 	rcuref.txt | ||||
| 
 | ||||
| 		Describes how to combine use of reference counts | ||||
| 		with RCU. | ||||
| 
 | ||||
| 	whatisRCU.txt | ||||
| 
 | ||||
| 		Overview of how the RCU implementation works.  Along | ||||
| 		the way, presents a conceptual view of RCU. | ||||
| 	See 00-INDEX for the list. | ||||
|  | ||||
							
								
								
									
										58
									
								
								Documentation/RCU/stallwarn.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								Documentation/RCU/stallwarn.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,58 @@ | ||||
| Using RCU's CPU Stall Detector | ||||
| 
 | ||||
| The CONFIG_RCU_CPU_STALL_DETECTOR kernel config parameter enables | ||||
| RCU's CPU stall detector, which detects conditions that unduly delay | ||||
| RCU grace periods.  The stall detector's idea of what constitutes | ||||
| "unduly delayed" is controlled by a pair of C preprocessor macros: | ||||
| 
 | ||||
| RCU_SECONDS_TILL_STALL_CHECK | ||||
| 
 | ||||
| 	This macro defines the period of time that RCU will wait from | ||||
| 	the beginning of a grace period until it issues an RCU CPU | ||||
| 	stall warning.	It is normally ten seconds. | ||||
| 
 | ||||
| RCU_SECONDS_TILL_STALL_RECHECK | ||||
| 
 | ||||
| 	This macro defines the period of time that RCU will wait after | ||||
| 	issuing a stall warning until it issues another stall warning. | ||||
| 	It is normally set to thirty seconds. | ||||
| 
 | ||||
| RCU_STALL_RAT_DELAY | ||||
| 
 | ||||
| 	The CPU stall detector tries to make the offending CPU rat on itself, | ||||
| 	as this often gives better-quality stack traces.  However, if | ||||
| 	the offending CPU does not detect its own stall in the number | ||||
| 	of jiffies specified by RCU_STALL_RAT_DELAY, then other CPUs will | ||||
| 	complain.  This is normally set to two jiffies. | ||||
| 
 | ||||
| The following problems can result in an RCU CPU stall warning: | ||||
| 
 | ||||
| o	A CPU looping in an RCU read-side critical section. | ||||
| 	 | ||||
| o	A CPU looping with interrupts disabled. | ||||
| 
 | ||||
| o	A CPU looping with preemption disabled. | ||||
| 
 | ||||
| o	For !CONFIG_PREEMPT kernels, a CPU looping anywhere in the kernel | ||||
| 	without invoking schedule(). | ||||
| 
 | ||||
| o	A bug in the RCU implementation. | ||||
| 
 | ||||
| o	A hardware failure.  This is quite unlikely, but has occurred | ||||
| 	at least once in a former life.  A CPU failed in a running system, | ||||
| 	becoming unresponsive, but not causing an immediate crash. | ||||
| 	This resulted in a series of RCU CPU stall warnings, eventually | ||||
| 	leading the realization that the CPU had failed. | ||||
| 
 | ||||
| The RCU, RCU-sched, and RCU-bh implementations have CPU stall warning. | ||||
| SRCU does not do so directly, but its calls to synchronize_sched() will | ||||
| result in RCU-sched detecting any CPU stalls that might be occurring. | ||||
| 
 | ||||
| To diagnose the cause of the stall, inspect the stack traces.  The offending | ||||
| function will usually be near the top of the stack.  If you have a series | ||||
| of stall warnings from a single extended stall, comparing the stack traces | ||||
| can often help determine where the stall is occurring, which will usually | ||||
| be in the function nearest the top of the stack that stays the same from | ||||
| trace to trace. | ||||
| 
 | ||||
| RCU bugs can often be debugged with the help of CONFIG_RCU_TRACE. | ||||
| @ -30,6 +30,18 @@ MODULE PARAMETERS | ||||
| 
 | ||||
| This module has the following parameters: | ||||
| 
 | ||||
| fqs_duration	Duration (in microseconds) of artificially induced bursts | ||||
| 		of force_quiescent_state() invocations.  In RCU | ||||
| 		implementations having force_quiescent_state(), these | ||||
| 		bursts help force races between forcing a given grace | ||||
| 		period and that grace period ending on its own. | ||||
| 
 | ||||
| fqs_holdoff	Holdoff time (in microseconds) between consecutive calls | ||||
| 		to force_quiescent_state() within a burst. | ||||
| 
 | ||||
| fqs_stutter	Wait time (in seconds) between consecutive bursts | ||||
| 		of calls to force_quiescent_state(). | ||||
| 
 | ||||
| irqreaders	Says to invoke RCU readers from irq level.  This is currently | ||||
| 		done via timers.  Defaults to "1" for variants of RCU that | ||||
| 		permit this.  (Or, more accurately, variants of RCU that do | ||||
|  | ||||
| @ -323,14 +323,17 @@ used as follows: | ||||
| 	Defer			Protect | ||||
| 
 | ||||
| a.	synchronize_rcu()	rcu_read_lock() / rcu_read_unlock() | ||||
| 	call_rcu() | ||||
| 	call_rcu()		rcu_dereference() | ||||
| 
 | ||||
| b.	call_rcu_bh()		rcu_read_lock_bh() / rcu_read_unlock_bh() | ||||
| 				rcu_dereference_bh() | ||||
| 
 | ||||
| c.	synchronize_sched()	preempt_disable() / preempt_enable() | ||||
| c.	synchronize_sched()	rcu_read_lock_sched() / rcu_read_unlock_sched() | ||||
| 				preempt_disable() / preempt_enable() | ||||
| 				local_irq_save() / local_irq_restore() | ||||
| 				hardirq enter / hardirq exit | ||||
| 				NMI enter / NMI exit | ||||
| 				rcu_dereference_sched() | ||||
| 
 | ||||
| These three mechanisms are used as follows: | ||||
| 
 | ||||
| @ -780,9 +783,8 @@ 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 | ||||
| in docbook.  Here is the list, by category. | ||||
| 
 | ||||
| RCU pointer/list traversal: | ||||
| RCU list traversal: | ||||
| 
 | ||||
| 	rcu_dereference | ||||
| 	list_for_each_entry_rcu | ||||
| 	hlist_for_each_entry_rcu | ||||
| 	hlist_nulls_for_each_entry_rcu | ||||
| @ -808,7 +810,7 @@ RCU:	Critical sections	Grace period		Barrier | ||||
| 
 | ||||
| 	rcu_read_lock		synchronize_net		rcu_barrier | ||||
| 	rcu_read_unlock		synchronize_rcu | ||||
| 				synchronize_rcu_expedited | ||||
| 	rcu_dereference		synchronize_rcu_expedited | ||||
| 				call_rcu | ||||
| 
 | ||||
| 
 | ||||
| @ -816,7 +818,7 @@ bh:	Critical sections	Grace period		Barrier | ||||
| 
 | ||||
| 	rcu_read_lock_bh	call_rcu_bh		rcu_barrier_bh | ||||
| 	rcu_read_unlock_bh	synchronize_rcu_bh | ||||
| 				synchronize_rcu_bh_expedited | ||||
| 	rcu_dereference_bh	synchronize_rcu_bh_expedited | ||||
| 
 | ||||
| 
 | ||||
| sched:	Critical sections	Grace period		Barrier | ||||
| @ -825,12 +827,14 @@ sched:	Critical sections	Grace period		Barrier | ||||
| 	rcu_read_unlock_sched	call_rcu_sched | ||||
| 	[preempt_disable]	synchronize_sched_expedited | ||||
| 	[and friends] | ||||
| 	rcu_dereference_sched | ||||
| 
 | ||||
| 
 | ||||
| SRCU:	Critical sections	Grace period		Barrier | ||||
| 
 | ||||
| 	srcu_read_lock		synchronize_srcu	N/A | ||||
| 	srcu_read_unlock	synchronize_srcu_expedited | ||||
| 	srcu_dereference | ||||
| 
 | ||||
| SRCU:	Initialization/cleanup | ||||
| 	init_srcu_struct | ||||
|  | ||||
| @ -377,3 +377,27 @@ maps this page at its virtual address. | ||||
| 	All the functionality of flush_icache_page can be implemented in | ||||
| 	flush_dcache_page and update_mmu_cache. In 2.7 the hope is to | ||||
| 	remove this interface completely. | ||||
| 
 | ||||
| The final category of APIs is for I/O to deliberately aliased address | ||||
| ranges inside the kernel.  Such aliases are set up by use of the | ||||
| vmap/vmalloc API.  Since kernel I/O goes via physical pages, the I/O | ||||
| subsystem assumes that the user mapping and kernel offset mapping are | ||||
| the only aliases.  This isn't true for vmap aliases, so anything in | ||||
| the kernel trying to do I/O to vmap areas must manually manage | ||||
| coherency.  It must do this by flushing the vmap range before doing | ||||
| I/O and invalidating it after the I/O returns. | ||||
| 
 | ||||
|   void flush_kernel_vmap_range(void *vaddr, int size) | ||||
|        flushes the kernel cache for a given virtual address range in | ||||
|        the vmap area.  This is to make sure that any data the kernel | ||||
|        modified in the vmap range is made visible to the physical | ||||
|        page.  The design is to make this area safe to perform I/O on. | ||||
|        Note that this API does *not* also flush the offset map alias | ||||
|        of the area. | ||||
| 
 | ||||
|   void invalidate_kernel_vmap_range(void *vaddr, int size) invalidates | ||||
|        the cache for a given virtual address range in the vmap area | ||||
|        which prevents the processor from making the cache stale by | ||||
|        speculatively reading data while the I/O was occurring to the | ||||
|        physical pages.  This is only necessary for data reads into the | ||||
|        vmap area. | ||||
|  | ||||
| @ -69,7 +69,6 @@ av_permissions.h | ||||
| bbootsect | ||||
| bin2c | ||||
| binkernel.spec | ||||
| binoffset | ||||
| bootsect | ||||
| bounds.h | ||||
| bsetup | ||||
|  | ||||
| @ -26,7 +26,7 @@ use IO::Handle; | ||||
| 		"dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004", | ||||
| 		"or51211", "or51132_qam", "or51132_vsb", "bluebird", | ||||
| 		"opera1", "cx231xx", "cx18", "cx23885", "pvrusb2", "mpc718", | ||||
| 		"af9015"); | ||||
| 		"af9015", "ngene"); | ||||
| 
 | ||||
| # Check args | ||||
| syntax() if (scalar(@ARGV) != 1); | ||||
| @ -39,7 +39,7 @@ for ($i=0; $i < scalar(@components); $i++) { | ||||
| 	die $@ if $@; | ||||
| 	print STDERR <<EOF; | ||||
| Firmware(s) $outfile extracted successfully. | ||||
| Now copy it(they) to either /usr/lib/hotplug/firmware or /lib/firmware | ||||
| Now copy it(them) to either /usr/lib/hotplug/firmware or /lib/firmware | ||||
| (depending on configuration of firmware hotplug). | ||||
| EOF | ||||
| 	exit(0); | ||||
| @ -549,6 +549,24 @@ sub af9015 { | ||||
| 	close INFILE; | ||||
| } | ||||
| 
 | ||||
| sub ngene { | ||||
|     my $url = "http://www.digitaldevices.de/download/"; | ||||
|     my $file1 = "ngene_15.fw"; | ||||
|     my $hash1 = "d798d5a757121174f0dbc5f2833c0c85"; | ||||
|     my $file2 = "ngene_17.fw"; | ||||
|     my $hash2 = "26b687136e127b8ac24b81e0eeafc20b"; | ||||
| 
 | ||||
|     checkstandard(); | ||||
| 
 | ||||
|     wgetfile($file1, $url . $file1); | ||||
|     verify($file1, $hash1); | ||||
| 
 | ||||
|     wgetfile($file2, $url . $file2); | ||||
|     verify($file2, $hash2); | ||||
| 
 | ||||
|     "$file1, $file2"; | ||||
| } | ||||
| 
 | ||||
| # --------------------------------------------------------------- | ||||
| # Utilities | ||||
| 
 | ||||
| @ -667,6 +685,7 @@ sub delzero{ | ||||
| sub syntax() { | ||||
|     print STDERR "syntax: get_dvb_firmware <component>\n"; | ||||
|     print STDERR "Supported components:\n"; | ||||
|     @components = sort @components; | ||||
|     for($i=0; $i < scalar(@components); $i++) { | ||||
| 	print STDERR "\t" . $components[$i] . "\n"; | ||||
|     } | ||||
|  | ||||
| @ -6,21 +6,6 @@ be removed from this file. | ||||
| 
 | ||||
| --------------------------- | ||||
| 
 | ||||
| What:	USER_SCHED | ||||
| When:	2.6.34 | ||||
| 
 | ||||
| Why:	USER_SCHED was implemented as a proof of concept for group scheduling. | ||||
| 	The effect of USER_SCHED can already be achieved from userspace with | ||||
| 	the help of libcgroup. The removal of USER_SCHED will also simplify | ||||
| 	the scheduler code with the removal of one major ifdef. There are also | ||||
| 	issues USER_SCHED has with USER_NS. A decision was taken not to fix | ||||
| 	those and instead remove USER_SCHED. Also new group scheduling | ||||
| 	features will not be implemented for USER_SCHED. | ||||
| 
 | ||||
| Who:	Dhaval Giani <dhaval@linux.vnet.ibm.com> | ||||
| 
 | ||||
| --------------------------- | ||||
| 
 | ||||
| What:	PRISM54 | ||||
| When:	2.6.34 | ||||
| 
 | ||||
| @ -64,6 +49,17 @@ Who:	Robin Getz <rgetz@blackfin.uclinux.org> & Matt Mackall <mpm@selenic.com> | ||||
| 
 | ||||
| --------------------------- | ||||
| 
 | ||||
| What:	Deprecated snapshot ioctls | ||||
| When:	2.6.36 | ||||
| 
 | ||||
| Why:	The ioctls in kernel/power/user.c were marked as deprecated long time | ||||
| 	ago. Now they notify users about that so that they need to replace | ||||
| 	their userspace. After some more time, remove them completely. | ||||
| 
 | ||||
| Who:	Jiri Slaby <jirislaby@gmail.com> | ||||
| 
 | ||||
| --------------------------- | ||||
| 
 | ||||
| What:	The ieee80211_regdom module parameter | ||||
| When:	March 2010 / desktop catchup | ||||
| 
 | ||||
|  | ||||
| @ -62,7 +62,8 @@ changes are : | ||||
| 2. Insertion of a dentry into the hash table is done using | ||||
|    hlist_add_head_rcu() which take care of ordering the writes - the | ||||
|    writes to the dentry must be visible before the dentry is | ||||
|    inserted. This works in conjunction with hlist_for_each_rcu() while | ||||
|    inserted. This works in conjunction with hlist_for_each_rcu(), | ||||
|    which has since been replaced by hlist_for_each_entry_rcu(), while | ||||
|    walking the hash chain. The only requirement is that all | ||||
|    initialization to the dentry must be done before | ||||
|    hlist_add_head_rcu() since we don't have dcache_lock protection | ||||
|  | ||||
| @ -200,6 +200,10 @@ and is between 256 and 4096 characters. It is defined in the file | ||||
| 			acpi_display_output=video | ||||
| 			See above. | ||||
| 
 | ||||
| 	acpi_early_pdc_eval	[HW,ACPI] Evaluate processor _PDC methods | ||||
| 				early. Needed on some platforms to properly | ||||
| 				initialize the EC. | ||||
| 
 | ||||
| 	acpi_irq_balance [HW,ACPI] | ||||
| 			ACPI will balance active IRQs | ||||
| 			default in APIC mode | ||||
| @ -312,6 +316,11 @@ and is between 256 and 4096 characters. It is defined in the file | ||||
| 	aic79xx=	[HW,SCSI] | ||||
| 			See Documentation/scsi/aic79xx.txt. | ||||
| 
 | ||||
| 	alignment=	[KNL,ARM] | ||||
| 			Allow the default userspace alignment fault handler | ||||
| 			behaviour to be specified.  Bit 0 enables warnings, | ||||
| 			bit 1 enables fixups, and bit 2 sends a segfault. | ||||
| 
 | ||||
| 	amd_iommu=	[HW,X86-84] | ||||
| 			Pass parameters to the AMD IOMMU driver in the system. | ||||
| 			Possible values are: | ||||
| @ -1739,6 +1748,9 @@ and is between 256 and 4096 characters. It is defined in the file | ||||
| 	nomfgpt		[X86-32] Disable Multi-Function General Purpose | ||||
| 			Timer usage (for AMD Geode machines). | ||||
| 
 | ||||
| 	nopat		[X86] Disable PAT (page attribute table extension of | ||||
| 			pagetables) support. | ||||
| 
 | ||||
| 	norandmaps	Don't use address space randomization.  Equivalent to | ||||
| 			echo 0 > /proc/sys/kernel/randomize_va_space | ||||
| 
 | ||||
| @ -1949,8 +1961,12 @@ and is between 256 and 4096 characters. It is defined in the file | ||||
| 				IRQ routing is enabled. | ||||
| 		noacpi		[X86] Do not use ACPI for IRQ routing | ||||
| 				or for PCI scanning. | ||||
| 		use_crs		[X86] Use _CRS for PCI resource | ||||
| 				allocation. | ||||
| 		use_crs		[X86] Use PCI host bridge window information | ||||
| 				from ACPI.  On BIOSes from 2008 or later, this | ||||
| 				is enabled by default.  If you need to use this, | ||||
| 				please report a bug. | ||||
| 		nocrs		[X86] Ignore PCI host bridge windows from ACPI. | ||||
| 			        If you need to use this, please report a bug. | ||||
| 		routeirq	Do IRQ routing for all PCI devices. | ||||
| 				This is normally done in pci_enable_device(), | ||||
| 				so this option is a temporary workaround | ||||
| @ -1999,6 +2015,14 @@ and is between 256 and 4096 characters. It is defined in the file | ||||
| 		force	Enable ASPM even on devices that claim not to support it. | ||||
| 			WARNING: Forcing ASPM on may cause system lockups. | ||||
| 
 | ||||
| 	pcie_pme=	[PCIE,PM] Native PCIe PME signaling options: | ||||
| 		off	Do not use native PCIe PME signaling. | ||||
| 		force	Use native PCIe PME signaling even if the BIOS refuses | ||||
| 			to allow the kernel to control the relevant PCIe config | ||||
| 			registers. | ||||
| 		nomsi	Do not use MSI for native PCIe PME signaling (this makes | ||||
| 			all PCIe root ports use INTx for everything). | ||||
| 
 | ||||
| 	pcmv=		[HW,PCMCIA] BadgePAD 4 | ||||
| 
 | ||||
| 	pd.		[PARIDE] | ||||
| @ -2704,6 +2728,13 @@ and is between 256 and 4096 characters. It is defined in the file | ||||
| 					medium is write-protected). | ||||
| 			Example: quirks=0419:aaf5:rl,0421:0433:rc | ||||
| 
 | ||||
| 	userpte= | ||||
| 			[X86] Flags controlling user PTE allocations. | ||||
| 
 | ||||
| 				nohigh = do not allocate PTE pages in | ||||
| 					HIGHMEM regardless of setting | ||||
| 					of CONFIG_HIGHPTE. | ||||
| 
 | ||||
| 	vdso=		[X86,SH] | ||||
| 			vdso=2: enable compat VDSO (default with COMPAT_VDSO) | ||||
| 			vdso=1: enable VDSO (default) | ||||
|  | ||||
| @ -34,7 +34,6 @@ | ||||
| #include <sys/uio.h> | ||||
| #include <termios.h> | ||||
| #include <getopt.h> | ||||
| #include <zlib.h> | ||||
| #include <assert.h> | ||||
| #include <sched.h> | ||||
| #include <limits.h> | ||||
|  | ||||
							
								
								
									
										118
									
								
								Documentation/pcmcia/locking.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								Documentation/pcmcia/locking.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,118 @@ | ||||
| This file explains the locking and exclusion scheme used in the PCCARD | ||||
| and PCMCIA subsystems. | ||||
| 
 | ||||
| 
 | ||||
| A) Overview, Locking Hierarchy: | ||||
| =============================== | ||||
| 
 | ||||
| pcmcia_socket_list_rwsem	- protects only the list of sockets | ||||
| - skt_mutex			- serializes card insert / ejection | ||||
|   - ops_mutex			- serializes socket operation | ||||
| 
 | ||||
| 
 | ||||
| B) Exclusion | ||||
| ============ | ||||
| 
 | ||||
| The following functions and callbacks to struct pcmcia_socket must | ||||
| be called with "skt_mutex" held: | ||||
| 
 | ||||
| 	socket_detect_change() | ||||
| 	send_event() | ||||
| 	socket_reset() | ||||
| 	socket_shutdown() | ||||
| 	socket_setup() | ||||
| 	socket_remove() | ||||
| 	socket_insert() | ||||
| 	socket_early_resume() | ||||
| 	socket_late_resume() | ||||
| 	socket_resume() | ||||
| 	socket_suspend() | ||||
| 
 | ||||
| 	struct pcmcia_callback	*callback | ||||
| 
 | ||||
| The following functions and callbacks to struct pcmcia_socket must | ||||
| be called with "ops_mutex" held: | ||||
| 
 | ||||
| 	socket_reset() | ||||
| 	socket_setup() | ||||
| 
 | ||||
| 	struct pccard_operations	*ops | ||||
| 	struct pccard_resource_ops	*resource_ops; | ||||
| 
 | ||||
| Note that send_event() and struct pcmcia_callback *callback must not be | ||||
| called with "ops_mutex" held. | ||||
| 
 | ||||
| 
 | ||||
| C) Protection | ||||
| ============= | ||||
| 
 | ||||
| 1. Global Data: | ||||
| --------------- | ||||
| struct list_head	pcmcia_socket_list; | ||||
| 
 | ||||
| protected by pcmcia_socket_list_rwsem; | ||||
| 
 | ||||
| 
 | ||||
| 2. Per-Socket Data: | ||||
| ------------------- | ||||
| The resource_ops and their data are protected by ops_mutex. | ||||
| 
 | ||||
| The "main" struct pcmcia_socket is protected as follows (read-only fields | ||||
| or single-use fields not mentioned): | ||||
| 
 | ||||
| - by pcmcia_socket_list_rwsem: | ||||
| 	struct list_head	socket_list; | ||||
| 
 | ||||
| - by thread_lock: | ||||
| 	unsigned int		thread_events; | ||||
| 
 | ||||
| - by skt_mutex: | ||||
| 	u_int			suspended_state; | ||||
| 	void			(*tune_bridge); | ||||
| 	struct pcmcia_callback	*callback; | ||||
| 	int			resume_status; | ||||
| 
 | ||||
| - by ops_mutex: | ||||
| 	socket_state_t		socket; | ||||
| 	u_int			state; | ||||
| 	u_short			lock_count; | ||||
| 	pccard_mem_map		cis_mem; | ||||
| 	void __iomem 		*cis_virt; | ||||
| 	struct { }		irq; | ||||
| 	io_window_t		io[]; | ||||
| 	pccard_mem_map		win[]; | ||||
| 	struct list_head	cis_cache; | ||||
| 	size_t			fake_cis_len; | ||||
| 	u8			*fake_cis; | ||||
| 	u_int			irq_mask; | ||||
| 	void 			(*zoom_video); | ||||
| 	int 			(*power_hook); | ||||
| 	u8			resource...; | ||||
| 	struct list_head	devices_list; | ||||
| 	u8			device_count; | ||||
| 	struct 			pcmcia_state; | ||||
| 
 | ||||
| 
 | ||||
| 3. Per PCMCIA-device Data: | ||||
| -------------------------- | ||||
| 
 | ||||
| The "main" struct pcmcia_devie is protected as follows (read-only fields | ||||
| or single-use fields not mentioned): | ||||
| 
 | ||||
| 
 | ||||
| - by pcmcia_socket->ops_mutex: | ||||
| 	struct list_head	socket_device_list; | ||||
| 	struct config_t		*function_config; | ||||
| 	u16			_irq:1; | ||||
| 	u16			_io:1; | ||||
| 	u16			_win:4; | ||||
| 	u16			_locked:1; | ||||
| 	u16			allow_func_id_match:1; | ||||
| 	u16			suspended:1; | ||||
| 	u16			_removed:1; | ||||
| 
 | ||||
| - by the PCMCIA driver: | ||||
| 	io_req_t		io; | ||||
| 	irq_req_t		irq; | ||||
| 	config_req_t		conf; | ||||
| 	window_handle_t		win; | ||||
							
								
								
									
										70
									
								
								Documentation/powerpc/dts-bindings/fsl/mpc5121-psc.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								Documentation/powerpc/dts-bindings/fsl/mpc5121-psc.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,70 @@ | ||||
| MPC5121 PSC Device Tree Bindings | ||||
| 
 | ||||
| PSC in UART mode | ||||
| ---------------- | ||||
| 
 | ||||
| For PSC in UART mode the needed PSC serial devices | ||||
| are specified by fsl,mpc5121-psc-uart nodes in the | ||||
| fsl,mpc5121-immr SoC node. Additionally the PSC FIFO | ||||
| Controller node fsl,mpc5121-psc-fifo is requered there: | ||||
| 
 | ||||
| fsl,mpc5121-psc-uart nodes | ||||
| -------------------------- | ||||
| 
 | ||||
| Required properties : | ||||
|  - compatible : Should contain "fsl,mpc5121-psc-uart" and "fsl,mpc5121-psc" | ||||
|  - cell-index : Index of the PSC in hardware | ||||
|  - reg : Offset and length of the register set for the PSC device | ||||
|  - interrupts : <a b> where a is the interrupt number of the | ||||
|    PSC FIFO Controller and b is a field that represents an | ||||
|    encoding of the sense and level information for the interrupt. | ||||
|  - interrupt-parent : the phandle for the interrupt controller that | ||||
|    services interrupts for this device. | ||||
| 
 | ||||
| Recommended properties : | ||||
|  - fsl,rx-fifo-size : the size of the RX fifo slice (a multiple of 4) | ||||
|  - fsl,tx-fifo-size : the size of the TX fifo slice (a multiple of 4) | ||||
| 
 | ||||
| 
 | ||||
| fsl,mpc5121-psc-fifo node | ||||
| ------------------------- | ||||
| 
 | ||||
| Required properties : | ||||
|  - compatible : Should be "fsl,mpc5121-psc-fifo" | ||||
|  - reg : Offset and length of the register set for the PSC | ||||
|          FIFO Controller | ||||
|  - interrupts : <a b> where a is the interrupt number of the | ||||
|    PSC FIFO Controller and b is a field that represents an | ||||
|    encoding of the sense and level information for the interrupt. | ||||
|  - interrupt-parent : the phandle for the interrupt controller that | ||||
|    services interrupts for this device. | ||||
| 
 | ||||
| 
 | ||||
| Example for a board using PSC0 and PSC1 devices in serial mode: | ||||
| 
 | ||||
| serial@11000 { | ||||
| 	compatible = "fsl,mpc5121-psc-uart", "fsl,mpc5121-psc"; | ||||
| 	cell-index = <0>; | ||||
| 	reg = <0x11000 0x100>; | ||||
| 	interrupts = <40 0x8>; | ||||
| 	interrupt-parent = < &ipic >; | ||||
| 	fsl,rx-fifo-size = <16>; | ||||
| 	fsl,tx-fifo-size = <16>; | ||||
| }; | ||||
| 
 | ||||
| serial@11100 { | ||||
| 	compatible = "fsl,mpc5121-psc-uart", "fsl,mpc5121-psc"; | ||||
| 	cell-index = <1>; | ||||
| 	reg = <0x11100 0x100>; | ||||
| 	interrupts = <40 0x8>; | ||||
| 	interrupt-parent = < &ipic >; | ||||
| 	fsl,rx-fifo-size = <16>; | ||||
| 	fsl,tx-fifo-size = <16>; | ||||
| }; | ||||
| 
 | ||||
| pscfifo@11f00 { | ||||
| 	compatible = "fsl,mpc5121-psc-fifo"; | ||||
| 	reg = <0x11f00 0x100>; | ||||
| 	interrupts = <40 0x8>; | ||||
| 	interrupt-parent = < &ipic >; | ||||
| }; | ||||
| @ -13,6 +13,11 @@ Required properties: | ||||
| - interrupt-parent : the phandle for the interrupt controller that | ||||
|   services interrupts for this device. | ||||
| 
 | ||||
| Optional properties: | ||||
| - gpios : specifies the gpio pins to be used for chipselects. | ||||
|   The gpios will be referred to as reg = <index> in the SPI child nodes. | ||||
|   If unspecified, a single SPI device without a chip select can be used. | ||||
| 
 | ||||
| Example: | ||||
| 	spi@4c0 { | ||||
| 		cell-index = <0>; | ||||
| @ -21,4 +26,6 @@ Example: | ||||
| 		interrupts = <82 0>; | ||||
| 		interrupt-parent = <700>; | ||||
| 		mode = "cpu"; | ||||
| 		gpios = <&gpio 18 1	// device reg=<0> | ||||
| 			 &gpio 19 1>;	// device reg=<1> | ||||
| 	}; | ||||
|  | ||||
							
								
								
									
										134
									
								
								Documentation/powerpc/ptrace.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								Documentation/powerpc/ptrace.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,134 @@ | ||||
| GDB intends to support the following hardware debug features of BookE | ||||
| processors: | ||||
| 
 | ||||
| 4 hardware breakpoints (IAC) | ||||
| 2 hardware watchpoints (read, write and read-write) (DAC) | ||||
| 2 value conditions for the hardware watchpoints (DVC) | ||||
| 
 | ||||
| For that, we need to extend ptrace so that GDB can query and set these | ||||
| resources. Since we're extending, we're trying to create an interface | ||||
| that's extendable and that covers both BookE and server processors, so | ||||
| that GDB doesn't need to special-case each of them. We added the | ||||
| following 3 new ptrace requests. | ||||
| 
 | ||||
| 1. PTRACE_PPC_GETHWDEBUGINFO | ||||
| 
 | ||||
| Query for GDB to discover the hardware debug features. The main info to | ||||
| be returned here is the minimum alignment for the hardware watchpoints. | ||||
| BookE processors don't have restrictions here, but server processors have | ||||
| an 8-byte alignment restriction for hardware watchpoints. We'd like to avoid | ||||
| adding special cases to GDB based on what it sees in AUXV. | ||||
| 
 | ||||
| Since we're at it, we added other useful info that the kernel can return to | ||||
| GDB: this query will return the number of hardware breakpoints, hardware | ||||
| watchpoints and whether it supports a range of addresses and a condition. | ||||
| The query will fill the following structure provided by the requesting process: | ||||
| 
 | ||||
| struct ppc_debug_info { | ||||
|        unit32_t version; | ||||
|        unit32_t num_instruction_bps; | ||||
|        unit32_t num_data_bps; | ||||
|        unit32_t num_condition_regs; | ||||
|        unit32_t data_bp_alignment; | ||||
|        unit32_t sizeof_condition; /* size of the DVC register */ | ||||
|        uint64_t features; /* bitmask of the individual flags */ | ||||
| }; | ||||
| 
 | ||||
| features will have bits indicating whether there is support for: | ||||
| 
 | ||||
| #define PPC_DEBUG_FEATURE_INSN_BP_RANGE		0x1 | ||||
| #define PPC_DEBUG_FEATURE_INSN_BP_MASK		0x2 | ||||
| #define PPC_DEBUG_FEATURE_DATA_BP_RANGE		0x4 | ||||
| #define PPC_DEBUG_FEATURE_DATA_BP_MASK		0x8 | ||||
| 
 | ||||
| 2. PTRACE_SETHWDEBUG | ||||
| 
 | ||||
| Sets a hardware breakpoint or watchpoint, according to the provided structure: | ||||
| 
 | ||||
| struct ppc_hw_breakpoint { | ||||
|         uint32_t version; | ||||
| #define PPC_BREAKPOINT_TRIGGER_EXECUTE  0x1 | ||||
| #define PPC_BREAKPOINT_TRIGGER_READ     0x2 | ||||
| #define PPC_BREAKPOINT_TRIGGER_WRITE    0x4 | ||||
|         uint32_t trigger_type;       /* only some combinations allowed */ | ||||
| #define PPC_BREAKPOINT_MODE_EXACT               0x0 | ||||
| #define PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE     0x1 | ||||
| #define PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE     0x2 | ||||
| #define PPC_BREAKPOINT_MODE_MASK                0x3 | ||||
|         uint32_t addr_mode;          /* address match mode */ | ||||
| 
 | ||||
| #define PPC_BREAKPOINT_CONDITION_MODE   0x3 | ||||
| #define PPC_BREAKPOINT_CONDITION_NONE   0x0 | ||||
| #define PPC_BREAKPOINT_CONDITION_AND    0x1 | ||||
| #define PPC_BREAKPOINT_CONDITION_EXACT  0x1	/* different name for the same thing as above */ | ||||
| #define PPC_BREAKPOINT_CONDITION_OR     0x2 | ||||
| #define PPC_BREAKPOINT_CONDITION_AND_OR 0x3 | ||||
| #define PPC_BREAKPOINT_CONDITION_BE_ALL 0x00ff0000	/* byte enable bits */ | ||||
| #define PPC_BREAKPOINT_CONDITION_BE(n)  (1<<((n)+16)) | ||||
|         uint32_t condition_mode;     /* break/watchpoint condition flags */ | ||||
| 
 | ||||
|         uint64_t addr; | ||||
|         uint64_t addr2; | ||||
|         uint64_t condition_value; | ||||
| }; | ||||
| 
 | ||||
| A request specifies one event, not necessarily just one register to be set. | ||||
| For instance, if the request is for a watchpoint with a condition, both the | ||||
| DAC and DVC registers will be set in the same request. | ||||
| 
 | ||||
| With this GDB can ask for all kinds of hardware breakpoints and watchpoints | ||||
| that the BookE supports. COMEFROM breakpoints available in server processors | ||||
| are not contemplated, but that is out of the scope of this work. | ||||
| 
 | ||||
| ptrace will return an integer (handle) uniquely identifying the breakpoint or | ||||
| watchpoint just created. This integer will be used in the PTRACE_DELHWDEBUG | ||||
| request to ask for its removal. Return -ENOSPC if the requested breakpoint | ||||
| can't be allocated on the registers. | ||||
| 
 | ||||
| Some examples of using the structure to: | ||||
| 
 | ||||
| - set a breakpoint in the first breakpoint register | ||||
| 
 | ||||
|   p.version         = PPC_DEBUG_CURRENT_VERSION; | ||||
|   p.trigger_type    = PPC_BREAKPOINT_TRIGGER_EXECUTE; | ||||
|   p.addr_mode       = PPC_BREAKPOINT_MODE_EXACT; | ||||
|   p.condition_mode  = PPC_BREAKPOINT_CONDITION_NONE; | ||||
|   p.addr            = (uint64_t) address; | ||||
|   p.addr2           = 0; | ||||
|   p.condition_value = 0; | ||||
| 
 | ||||
| - set a watchpoint which triggers on reads in the second watchpoint register | ||||
| 
 | ||||
|   p.version         = PPC_DEBUG_CURRENT_VERSION; | ||||
|   p.trigger_type    = PPC_BREAKPOINT_TRIGGER_READ; | ||||
|   p.addr_mode       = PPC_BREAKPOINT_MODE_EXACT; | ||||
|   p.condition_mode  = PPC_BREAKPOINT_CONDITION_NONE; | ||||
|   p.addr            = (uint64_t) address; | ||||
|   p.addr2           = 0; | ||||
|   p.condition_value = 0; | ||||
| 
 | ||||
| - set a watchpoint which triggers only with a specific value | ||||
| 
 | ||||
|   p.version         = PPC_DEBUG_CURRENT_VERSION; | ||||
|   p.trigger_type    = PPC_BREAKPOINT_TRIGGER_READ; | ||||
|   p.addr_mode       = PPC_BREAKPOINT_MODE_EXACT; | ||||
|   p.condition_mode  = PPC_BREAKPOINT_CONDITION_AND | PPC_BREAKPOINT_CONDITION_BE_ALL; | ||||
|   p.addr            = (uint64_t) address; | ||||
|   p.addr2           = 0; | ||||
|   p.condition_value = (uint64_t) condition; | ||||
| 
 | ||||
| - set a ranged hardware breakpoint | ||||
| 
 | ||||
|   p.version         = PPC_DEBUG_CURRENT_VERSION; | ||||
|   p.trigger_type    = PPC_BREAKPOINT_TRIGGER_EXECUTE; | ||||
|   p.addr_mode       = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE; | ||||
|   p.condition_mode  = PPC_BREAKPOINT_CONDITION_NONE; | ||||
|   p.addr            = (uint64_t) begin_range; | ||||
|   p.addr2           = (uint64_t) end_range; | ||||
|   p.condition_value = 0; | ||||
| 
 | ||||
| 3. PTRACE_DELHWDEBUG | ||||
| 
 | ||||
| Takes an integer which identifies an existing breakpoint or watchpoint | ||||
| (i.e., the value returned from PTRACE_SETHWDEBUG), and deletes the | ||||
| corresponding breakpoint or watchpoint.. | ||||
| @ -87,6 +87,12 @@ Command line parameters | ||||
|   compatibility, by the device number in hexadecimal (0xabcd or abcd). Device | ||||
|   numbers given as 0xabcd will be interpreted as 0.0.abcd. | ||||
| 
 | ||||
| * /proc/cio_settle | ||||
| 
 | ||||
|   A write request to this file is blocked until all queued cio actions are | ||||
|   handled. This will allow userspace to wait for pending work affecting | ||||
|   device availability after changing cio_ignore or the hardware configuration. | ||||
| 
 | ||||
| * For some of the information present in the /proc filesystem in 2.4 (namely, | ||||
|   /proc/subchannels and /proc/chpids), see driver-model.txt. | ||||
|   Information formerly in /proc/irq_count is now in /proc/interrupts. | ||||
|  | ||||
| @ -223,8 +223,8 @@ touched by the driver - it should use the ccwgroup device's driver_data for its | ||||
| private data. | ||||
| 
 | ||||
| To implement a ccwgroup driver, please refer to include/asm/ccwgroup.h. Keep in | ||||
| mind that most drivers will need to implement both a ccwgroup and a ccw driver | ||||
| (unless you have a meta ccw driver, like cu3088 for lcs and ctc). | ||||
| mind that most drivers will need to implement both a ccwgroup and a ccw | ||||
| driver. | ||||
| 
 | ||||
| 
 | ||||
| 2. Channel paths | ||||
|  | ||||
| @ -1,3 +1,19 @@ | ||||
| 1 Release Date    : Thur.  Oct 29, 2009 09:12:45 PST 2009 - | ||||
| 			(emaild-id:megaraidlinux@lsi.com) | ||||
| 			Bo Yang | ||||
| 
 | ||||
| 2 Current Version : 00.00.04.17.1-rc1 | ||||
| 3 Older Version   : 00.00.04.12 | ||||
| 
 | ||||
| 1.	Add the pad_0 in mfi frame structure to 0 to fix the | ||||
| 	context value larger than 32bit value issue. | ||||
| 
 | ||||
| 2.	Add the logic drive list to the driver.  Driver will | ||||
| 	keep the logic drive list internal after driver load. | ||||
| 
 | ||||
| 3.	driver fixed the device update issue after get the AEN | ||||
| 	PD delete/ADD, LD add/delete from FW. | ||||
| 
 | ||||
| 1 Release Date    : Tues.  July 28, 2009 10:12:45 PST 2009 - | ||||
| 			(emaild-id:megaraidlinux@lsi.com) | ||||
| 			Bo Yang | ||||
|  | ||||
| @ -238,11 +238,10 @@ HAVE_SYSCALL_TRACEPOINTS | ||||
| 
 | ||||
| You need very few things to get the syscalls tracing in an arch. | ||||
| 
 | ||||
| - Support HAVE_ARCH_TRACEHOOK (see arch/Kconfig). | ||||
| - Have a NR_syscalls variable in <asm/unistd.h> that provides the number | ||||
|   of syscalls supported by the arch. | ||||
| - Implement arch_syscall_addr() that resolves a syscall address from a | ||||
|   syscall number. | ||||
| - Support the TIF_SYSCALL_TRACEPOINT thread flags | ||||
| - Support the TIF_SYSCALL_TRACEPOINT thread flags. | ||||
| - Put the trace_sys_enter() and trace_sys_exit() tracepoints calls from ptrace | ||||
|   in the ptrace syscalls tracing path. | ||||
| - Tag this arch as HAVE_SYSCALL_TRACEPOINTS. | ||||
|  | ||||
| @ -24,6 +24,7 @@ Synopsis of kprobe_events | ||||
| ------------------------- | ||||
|   p[:[GRP/]EVENT] SYMBOL[+offs]|MEMADDR [FETCHARGS]	: Set a probe | ||||
|   r[:[GRP/]EVENT] SYMBOL[+0] [FETCHARGS]		: Set a return probe | ||||
|   -:[GRP/]EVENT						: Clear a probe | ||||
| 
 | ||||
|  GRP		: Group name. If omitted, use "kprobes" for it. | ||||
|  EVENT		: Event name. If omitted, the event name is generated | ||||
| @ -37,15 +38,12 @@ Synopsis of kprobe_events | ||||
|   @SYM[+|-offs]	: Fetch memory at SYM +|- offs (SYM should be a data symbol) | ||||
|   $stackN	: Fetch Nth entry of stack (N >= 0) | ||||
|   $stack	: Fetch stack address. | ||||
|   $argN		: Fetch function argument. (N >= 0)(*) | ||||
|   $retval	: Fetch return value.(**) | ||||
|   +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(***) | ||||
|   $retval	: Fetch return value.(*) | ||||
|   +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(**) | ||||
|   NAME=FETCHARG: Set NAME as the argument name of FETCHARG. | ||||
| 
 | ||||
|   (*) aN may not correct on asmlinkaged functions and at the middle of | ||||
|       function body. | ||||
|   (**) only for return probe. | ||||
|   (***) this is useful for fetching a field of data structures. | ||||
|   (*) only for return probe. | ||||
|   (**) this is useful for fetching a field of data structures. | ||||
| 
 | ||||
| 
 | ||||
| Per-Probe Event Filtering | ||||
| @ -82,13 +80,16 @@ Usage examples | ||||
| To add a probe as a new event, write a new definition to kprobe_events | ||||
| as below. | ||||
| 
 | ||||
|   echo p:myprobe do_sys_open dfd=$arg0 filename=$arg1 flags=$arg2 mode=$arg3 > /sys/kernel/debug/tracing/kprobe_events | ||||
|   echo 'p:myprobe do_sys_open dfd=%ax filename=%dx flags=%cx mode=+4($stack)' > /sys/kernel/debug/tracing/kprobe_events | ||||
| 
 | ||||
|  This sets a kprobe on the top of do_sys_open() function with recording | ||||
| 1st to 4th arguments as "myprobe" event. As this example shows, users can | ||||
| choose more familiar names for each arguments. | ||||
| 1st to 4th arguments as "myprobe" event. Note, which register/stack entry is | ||||
| assigned to each function argument depends on arch-specific ABI. If you unsure | ||||
| the ABI, please try to use probe subcommand of perf-tools (you can find it | ||||
| under tools/perf/). | ||||
| As this example shows, users can choose more familiar names for each arguments. | ||||
| 
 | ||||
|   echo r:myretprobe do_sys_open $retval >> /sys/kernel/debug/tracing/kprobe_events | ||||
|   echo 'r:myretprobe do_sys_open $retval' >> /sys/kernel/debug/tracing/kprobe_events | ||||
| 
 | ||||
|  This sets a kretprobe on the return point of do_sys_open() function with | ||||
| recording return value as "myretprobe" event. | ||||
| @ -97,23 +98,24 @@ recording return value as "myretprobe" event. | ||||
| 
 | ||||
|   cat /sys/kernel/debug/tracing/events/kprobes/myprobe/format | ||||
| name: myprobe | ||||
| ID: 75 | ||||
| ID: 780 | ||||
| format: | ||||
| 	field:unsigned short common_type;	offset:0;	size:2; | ||||
| 	field:unsigned char common_flags;	offset:2;	size:1; | ||||
| 	field:unsigned char common_preempt_count;	offset:3;	size:1; | ||||
| 	field:int common_pid;	offset:4;	size:4; | ||||
| 	field:int common_tgid;	offset:8;	size:4; | ||||
|         field:unsigned short common_type;       offset:0;       size:2; signed:0; | ||||
|         field:unsigned char common_flags;       offset:2;       size:1; signed:0; | ||||
|         field:unsigned char common_preempt_count;       offset:3; size:1;signed:0; | ||||
|         field:int common_pid;   offset:4;       size:4; signed:1; | ||||
|         field:int common_lock_depth;    offset:8;       size:4; signed:1; | ||||
| 
 | ||||
| 	field: unsigned long ip;	offset:16;tsize:8; | ||||
| 	field: int nargs;	offset:24;tsize:4; | ||||
| 	field: unsigned long dfd;	offset:32;tsize:8; | ||||
| 	field: unsigned long filename;	offset:40;tsize:8; | ||||
| 	field: unsigned long flags;	offset:48;tsize:8; | ||||
| 	field: unsigned long mode;	offset:56;tsize:8; | ||||
|         field:unsigned long __probe_ip; offset:12;      size:4; signed:0; | ||||
|         field:int __probe_nargs;        offset:16;      size:4; signed:1; | ||||
|         field:unsigned long dfd;        offset:20;      size:4; signed:0; | ||||
|         field:unsigned long filename;   offset:24;      size:4; signed:0; | ||||
|         field:unsigned long flags;      offset:28;      size:4; signed:0; | ||||
|         field:unsigned long mode;       offset:32;      size:4; signed:0; | ||||
| 
 | ||||
| print fmt: "(%lx) dfd=%lx filename=%lx flags=%lx mode=%lx", REC->ip, REC->dfd, REC->filename, REC->flags, REC->mode | ||||
| 
 | ||||
| print fmt: "(%lx) dfd=%lx filename=%lx flags=%lx mode=%lx", REC->__probe_ip, | ||||
| REC->dfd, REC->filename, REC->flags, REC->mode | ||||
| 
 | ||||
|  You can see that the event has 4 arguments as in the expressions you specified. | ||||
| 
 | ||||
| @ -121,6 +123,12 @@ print fmt: "(%lx) dfd=%lx filename=%lx flags=%lx mode=%lx", REC->ip, REC->dfd, R | ||||
| 
 | ||||
|  This clears all probe points. | ||||
| 
 | ||||
|  Or, | ||||
| 
 | ||||
|   echo -:myprobe >> kprobe_events | ||||
| 
 | ||||
|  This clears probe points selectively. | ||||
| 
 | ||||
|  Right after definition, each event is disabled by default. For tracing these | ||||
| events, you need to enable it. | ||||
| 
 | ||||
| @ -146,4 +154,3 @@ events, you need to enable it. | ||||
| returns from SYMBOL(e.g. "sys_open+0x1b/0x1d <- do_sys_open" means kernel | ||||
| returns from do_sys_open to sys_open+0x1b). | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -26,3 +26,4 @@ | ||||
|  25 -> Compro VideoMate E800                               [1858:e800] | ||||
|  26 -> Hauppauge WinTV-HVR1290                             [0070:8551] | ||||
|  27 -> Mygica X8558 PRO DMB-TH                             [14f1:8578] | ||||
|  28 -> LEADTEK WinFast PxTV1200                            [107d:6f22] | ||||
|  | ||||
| @ -174,3 +174,4 @@ | ||||
| 173 -> Zolid Hybrid TV Tuner PCI                [1131:2004] | ||||
| 174 -> Asus Europa Hybrid OEM                   [1043:4847] | ||||
| 175 -> Leadtek Winfast DTV1000S                 [107d:6655] | ||||
| 176 -> Beholder BeholdTV 505 RDS                [0000:5051] | ||||
|  | ||||
| @ -81,3 +81,4 @@ tuner=80 - Philips FQ1216LME MK3 PAL/SECAM w/active loopthrough | ||||
| tuner=81 - Partsnic (Daewoo) PTI-5NF05 | ||||
| tuner=82 - Philips CU1216L | ||||
| tuner=83 - NXP TDA18271 | ||||
| tuner=84 - Sony BTF-Pxn01Z | ||||
|  | ||||
							
								
								
									
										47
									
								
								Documentation/video4linux/README.tlg2300
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								Documentation/video4linux/README.tlg2300
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,47 @@ | ||||
| tlg2300 release notes | ||||
| ==================== | ||||
| 
 | ||||
| This is a v4l2/dvb device driver for the tlg2300 chip. | ||||
| 
 | ||||
| 
 | ||||
| current status | ||||
| ============== | ||||
| 
 | ||||
| video | ||||
| 	- support mmap and read().(no overlay) | ||||
| 
 | ||||
| audio | ||||
| 	- The driver will register a ALSA card for the audio input. | ||||
| 
 | ||||
| vbi | ||||
| 	- Works for almost TV norms. | ||||
| 
 | ||||
| dvb-t | ||||
| 	- works for DVB-T | ||||
| 
 | ||||
| FM | ||||
| 	- Works for radio. | ||||
| 
 | ||||
| --------------------------------------------------------------------------- | ||||
| TESTED APPLICATIONS: | ||||
| 
 | ||||
| -VLC1.0.4 test the video and dvb. The GUI is friendly to use. | ||||
| 
 | ||||
| -Mplayer test the video. | ||||
| 
 | ||||
| -Mplayer test the FM. The mplayer should be compiled with --enable-radio and | ||||
| 	 --enable-radio-capture. | ||||
| 	The command runs as this(The alsa audio registers to card 1): | ||||
| 	#mplayer radio://103.7/capture/ -radio adevice=hw=1,0:arate=48000 \ | ||||
| 		-rawaudio rate=48000:channels=2 | ||||
| 
 | ||||
| --------------------------------------------------------------------------- | ||||
| KNOWN PROBLEMS: | ||||
| about preemphasis: | ||||
| 	You can set the preemphasis for radio by the following command: | ||||
| 	#v4l2-ctl -d /dev/radio0 --set-ctrl=pre_emphasis_settings=1 | ||||
| 
 | ||||
| 	"pre_emphasis_settings=1" means that you select the 50us. If you want | ||||
| 	to select the 75us, please use "pre_emphasis_settings=2" | ||||
| 
 | ||||
| 
 | ||||
| @ -42,6 +42,7 @@ ov519		041e:4064	Creative Live! VISTA VF0420 | ||||
| ov519		041e:4067	Creative Live! Cam Video IM (VF0350) | ||||
| ov519		041e:4068	Creative Live! VISTA VF0470 | ||||
| spca561		0458:7004	Genius VideoCAM Express V2 | ||||
| sn9c2028	0458:7005	Genius Smart 300, version 2 | ||||
| sunplus		0458:7006	Genius Dsc 1.3 Smart | ||||
| zc3xx		0458:7007	Genius VideoCam V2 | ||||
| zc3xx		0458:700c	Genius VideoCam V3 | ||||
| @ -109,6 +110,7 @@ sunplus		04a5:3003	Benq DC 1300 | ||||
| sunplus		04a5:3008	Benq DC 1500 | ||||
| sunplus		04a5:300a	Benq DC 3410 | ||||
| spca500		04a5:300c	Benq DC 1016 | ||||
| benq		04a5:3035	Benq DC E300 | ||||
| finepix		04cb:0104	Fujifilm FinePix 4800 | ||||
| finepix		04cb:0109	Fujifilm FinePix A202 | ||||
| finepix		04cb:010b	Fujifilm FinePix A203 | ||||
| @ -142,6 +144,7 @@ sunplus		04fc:5360	Sunplus Generic | ||||
| spca500		04fc:7333	PalmPixDC85 | ||||
| sunplus		04fc:ffff	Pure DigitalDakota | ||||
| spca501		0506:00df	3Com HomeConnect Lite | ||||
| sunplus		052b:1507	Megapixel 5 Pretec DC-1007 | ||||
| sunplus		052b:1513	Megapix V4 | ||||
| sunplus		052b:1803	MegaImage VI | ||||
| tv8532		0545:808b	Veo Stingray | ||||
| @ -151,6 +154,7 @@ sunplus		0546:3191	Polaroid Ion 80 | ||||
| sunplus		0546:3273	Polaroid PDC2030 | ||||
| ov519		054c:0154	Sonny toy4 | ||||
| ov519		054c:0155	Sonny toy5 | ||||
| cpia1		0553:0002	CPIA CPiA (version1) based cameras | ||||
| zc3xx		055f:c005	Mustek Wcam300A | ||||
| spca500		055f:c200	Mustek Gsmart 300 | ||||
| sunplus		055f:c211	Kowa Bs888e Microcamera | ||||
| @ -188,8 +192,7 @@ spca500		06bd:0404	Agfa CL20 | ||||
| spca500		06be:0800	Optimedia | ||||
| sunplus		06d6:0031	Trust 610 LCD PowerC@m Zoom | ||||
| spca506		06e1:a190	ADS Instant VCD | ||||
| ov534		06f8:3002	Hercules Blog Webcam | ||||
| ov534		06f8:3003	Hercules Dualpix HD Weblog | ||||
| ov534_9		06f8:3003	Hercules Dualpix HD Weblog | ||||
| sonixj		06f8:3004	Hercules Classic Silver | ||||
| sonixj		06f8:3008	Hercules Deluxe Optical Glass | ||||
| pac7302		06f8:3009	Hercules Classic Link | ||||
| @ -204,6 +207,7 @@ sunplus		0733:2221	Mercury Digital Pro 3.1p | ||||
| sunplus		0733:3261	Concord 3045 spca536a | ||||
| sunplus		0733:3281	Cyberpix S550V | ||||
| spca506		0734:043b	3DeMon USB Capture aka | ||||
| cpia1		0813:0001	QX3 camera | ||||
| ov519		0813:0002	Dual Mode USB Camera Plus | ||||
| spca500		084d:0003	D-Link DSC-350 | ||||
| spca500		08ca:0103	Aiptek PocketDV | ||||
| @ -225,7 +229,8 @@ sunplus		08ca:2050	Medion MD 41437 | ||||
| sunplus		08ca:2060	Aiptek PocketDV5300 | ||||
| tv8532		0923:010f	ICM532 cams | ||||
| mars		093a:050f	Mars-Semi Pc-Camera | ||||
| mr97310a	093a:010f	Sakar Digital no. 77379 | ||||
| mr97310a	093a:010e	All known CIF cams with this ID | ||||
| mr97310a	093a:010f	All known VGA cams with this ID | ||||
| pac207		093a:2460	Qtec Webcam 100 | ||||
| pac207		093a:2461	HP Webcam | ||||
| pac207		093a:2463	Philips SPC 220 NC | ||||
| @ -302,6 +307,7 @@ sonixj		0c45:613b	Surfer SN-206 | ||||
| sonixj		0c45:613c	Sonix Pccam168 | ||||
| sonixj		0c45:6143	Sonix Pccam168 | ||||
| sonixj		0c45:6148	Digitus DA-70811/ZSMC USB PC Camera ZS211/Microdia | ||||
| sonixj		0c45:614a	Frontech E-Ccam (JIL-2225) | ||||
| sn9c20x		0c45:6240	PC Camera (SN9C201 + MT9M001) | ||||
| sn9c20x		0c45:6242	PC Camera (SN9C201 + MT9M111) | ||||
| sn9c20x		0c45:6248	PC Camera (SN9C201 + OV9655) | ||||
| @ -324,6 +330,10 @@ sn9c20x		0c45:62b0	PC Camera (SN9C202 + MT9V011/MT9V111/MT9V112) | ||||
| sn9c20x		0c45:62b3	PC Camera (SN9C202 + OV9655) | ||||
| sn9c20x		0c45:62bb	PC Camera (SN9C202 + OV7660) | ||||
| sn9c20x		0c45:62bc	PC Camera (SN9C202 + HV7131R) | ||||
| sn9c2028	0c45:8001	Wild Planet Digital Spy Camera | ||||
| sn9c2028	0c45:8003	Sakar #11199, #6637x, #67480 keychain cams | ||||
| sn9c2028	0c45:8008	Mini-Shotz ms-350 | ||||
| sn9c2028	0c45:800a	Vivitar Vivicam 3350B | ||||
| sunplus		0d64:0303	Sunplus FashionCam DXG | ||||
| ov519		0e96:c001	TRUST 380 USB2 SPACEC@M | ||||
| etoms		102c:6151	Qcam Sangha CIF | ||||
| @ -341,10 +351,11 @@ spca501		1776:501c	Arowana 300K CMOS Camera | ||||
| t613		17a1:0128	TASCORP JPEG Webcam, NGS Cyclops | ||||
| vc032x		17ef:4802	Lenovo Vc0323+MI1310_SOC | ||||
| pac207		2001:f115	D-Link DSB-C120 | ||||
| sq905c		2770:9050	sq905c | ||||
| sq905c		2770:905c	DualCamera | ||||
| sq905		2770:9120	Argus Digital Camera DC1512 | ||||
| sq905c		2770:913d	sq905c | ||||
| sq905c		2770:9050	Disney pix micro (CIF) | ||||
| sq905c		2770:9052	Disney pix micro 2 (VGA) | ||||
| sq905c		2770:905c	All 11 known cameras with this ID | ||||
| sq905		2770:9120	All 24 known cameras with this ID | ||||
| sq905c		2770:913d	All 4 known cameras with this ID | ||||
| spca500		2899:012c	Toptro Industrial | ||||
| ov519		8020:ef04	ov519 | ||||
| spca508		8086:0110	Intel Easy PC Camera | ||||
|  | ||||
| @ -599,99 +599,13 @@ video_device::minor fields. | ||||
| video buffer helper functions | ||||
| ----------------------------- | ||||
| 
 | ||||
| The v4l2 core API provides a standard method for dealing with video | ||||
| buffers. Those methods allow a driver to implement read(), mmap() and | ||||
| overlay() on a consistent way. | ||||
| The v4l2 core API provides a set of standard methods (called "videobuf") | ||||
| for dealing with video buffers. Those methods allow a driver to implement | ||||
| read(), mmap() and overlay() in a consistent way.  There are currently | ||||
| methods for using video buffers on devices that supports DMA with | ||||
| scatter/gather method (videobuf-dma-sg), DMA with linear access | ||||
| (videobuf-dma-contig), and vmalloced buffers, mostly used on USB drivers | ||||
| (videobuf-vmalloc). | ||||
| 
 | ||||
| There are currently methods for using video buffers on devices that | ||||
| supports DMA with scatter/gather method (videobuf-dma-sg), DMA with | ||||
| linear access (videobuf-dma-contig), and vmalloced buffers, mostly | ||||
| used on USB drivers (videobuf-vmalloc). | ||||
| 
 | ||||
| Any driver using videobuf should provide operations (callbacks) for | ||||
| four handlers: | ||||
| 
 | ||||
| ops->buf_setup   - calculates the size of the video buffers and avoid they | ||||
| 		   to waste more than some maximum limit of RAM; | ||||
| ops->buf_prepare - fills the video buffer structs and calls | ||||
| 		   videobuf_iolock() to alloc and prepare mmaped memory; | ||||
| ops->buf_queue   - advices the driver that another buffer were | ||||
| 		   requested (by read() or by QBUF); | ||||
| ops->buf_release - frees any buffer that were allocated. | ||||
| 
 | ||||
| In order to use it, the driver need to have a code (generally called at | ||||
| interrupt context) that will properly handle the buffer request lists, | ||||
| announcing that a new buffer were filled. | ||||
| 
 | ||||
| The irq handling code should handle the videobuf task lists, in order | ||||
| to advice videobuf that a new frame were filled, in order to honor to a | ||||
| request. The code is generally like this one: | ||||
| 	if (list_empty(&dma_q->active)) | ||||
| 		return; | ||||
| 
 | ||||
| 	buf = list_entry(dma_q->active.next, struct vbuffer, vb.queue); | ||||
| 
 | ||||
| 	if (!waitqueue_active(&buf->vb.done)) | ||||
| 		return; | ||||
| 
 | ||||
| 	/* Some logic to handle the buf may be needed here */ | ||||
| 
 | ||||
| 	list_del(&buf->vb.queue); | ||||
| 	do_gettimeofday(&buf->vb.ts); | ||||
| 	wake_up(&buf->vb.done); | ||||
| 
 | ||||
| Those are the videobuffer functions used on drivers, implemented on | ||||
| videobuf-core: | ||||
| 
 | ||||
| - Videobuf init functions | ||||
|   videobuf_queue_sg_init() | ||||
|       Initializes the videobuf infrastructure. This function should be | ||||
|       called before any other videobuf function on drivers that uses DMA | ||||
|       Scatter/Gather buffers. | ||||
| 
 | ||||
|   videobuf_queue_dma_contig_init | ||||
|       Initializes the videobuf infrastructure. This function should be | ||||
|       called before any other videobuf function on drivers that need DMA | ||||
|       contiguous buffers. | ||||
| 
 | ||||
|   videobuf_queue_vmalloc_init() | ||||
|       Initializes the videobuf infrastructure. This function should be | ||||
|       called before any other videobuf function on USB (and other drivers) | ||||
|       that need a vmalloced type of videobuf. | ||||
| 
 | ||||
| - videobuf_iolock() | ||||
|   Prepares the videobuf memory for the proper method (read, mmap, overlay). | ||||
| 
 | ||||
| - videobuf_queue_is_busy() | ||||
|   Checks if a videobuf is streaming. | ||||
| 
 | ||||
| - videobuf_queue_cancel() | ||||
|   Stops video handling. | ||||
| 
 | ||||
| - videobuf_mmap_free() | ||||
|   frees mmap buffers. | ||||
| 
 | ||||
| - videobuf_stop() | ||||
|   Stops video handling, ends mmap and frees mmap and other buffers. | ||||
| 
 | ||||
| - V4L2 api functions. Those functions correspond to VIDIOC_foo ioctls: | ||||
|    videobuf_reqbufs(), videobuf_querybuf(), videobuf_qbuf(), | ||||
|    videobuf_dqbuf(), videobuf_streamon(), videobuf_streamoff(). | ||||
| 
 | ||||
| - V4L1 api function (corresponds to VIDIOCMBUF ioctl): | ||||
|    videobuf_cgmbuf() | ||||
|       This function is used to provide backward compatibility with V4L1 | ||||
|       API. | ||||
| 
 | ||||
| - Some help functions for read()/poll() operations: | ||||
|    videobuf_read_stream() | ||||
|       For continuous stream read() | ||||
|    videobuf_read_one() | ||||
|       For snapshot read() | ||||
|    videobuf_poll_stream() | ||||
|       polling help function | ||||
| 
 | ||||
| The better way to understand it is to take a look at vivi driver. One | ||||
| of the main reasons for vivi is to be a videobuf usage example. the | ||||
| vivi_thread_tick() does the task that the IRQ callback would do on PCI | ||||
| drivers (or the irq callback on USB). | ||||
| Please see Documentation/video4linux/videobuf for more information on how | ||||
| to use the videobuf layer. | ||||
|  | ||||
							
								
								
									
										360
									
								
								Documentation/video4linux/videobuf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										360
									
								
								Documentation/video4linux/videobuf
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,360 @@ | ||||
| An introduction to the videobuf layer | ||||
| Jonathan Corbet <corbet@lwn.net> | ||||
| Current as of 2.6.33 | ||||
| 
 | ||||
| The videobuf layer functions as a sort of glue layer between a V4L2 driver | ||||
| and user space.  It handles the allocation and management of buffers for | ||||
| the storage of video frames.  There is a set of functions which can be used | ||||
| to implement many of the standard POSIX I/O system calls, including read(), | ||||
| poll(), and, happily, mmap().  Another set of functions can be used to | ||||
| implement the bulk of the V4L2 ioctl() calls related to streaming I/O, | ||||
| including buffer allocation, queueing and dequeueing, and streaming | ||||
| control.  Using videobuf imposes a few design decisions on the driver | ||||
| author, but the payback comes in the form of reduced code in the driver and | ||||
| a consistent implementation of the V4L2 user-space API. | ||||
| 
 | ||||
| Buffer types | ||||
| 
 | ||||
| Not all video devices use the same kind of buffers.  In fact, there are (at | ||||
| least) three common variations: | ||||
| 
 | ||||
|  - Buffers which are scattered in both the physical and (kernel) virtual | ||||
|    address spaces.  (Almost) all user-space buffers are like this, but it | ||||
|    makes great sense to allocate kernel-space buffers this way as well when | ||||
|    it is possible.  Unfortunately, it is not always possible; working with | ||||
|    this kind of buffer normally requires hardware which can do | ||||
|    scatter/gather DMA operations. | ||||
| 
 | ||||
|  - Buffers which are physically scattered, but which are virtually | ||||
|    contiguous; buffers allocated with vmalloc(), in other words.  These | ||||
|    buffers are just as hard to use for DMA operations, but they can be | ||||
|    useful in situations where DMA is not available but virtually-contiguous | ||||
|    buffers are convenient. | ||||
| 
 | ||||
|  - Buffers which are physically contiguous.  Allocation of this kind of | ||||
|    buffer can be unreliable on fragmented systems, but simpler DMA | ||||
|    controllers cannot deal with anything else. | ||||
| 
 | ||||
| Videobuf can work with all three types of buffers, but the driver author | ||||
| must pick one at the outset and design the driver around that decision. | ||||
| 
 | ||||
| [It's worth noting that there's a fourth kind of buffer: "overlay" buffers | ||||
| which are located within the system's video memory.  The overlay | ||||
| functionality is considered to be deprecated for most use, but it still | ||||
| shows up occasionally in system-on-chip drivers where the performance | ||||
| benefits merit the use of this technique.  Overlay buffers can be handled | ||||
| as a form of scattered buffer, but there are very few implementations in | ||||
| the kernel and a description of this technique is currently beyond the | ||||
| scope of this document.] | ||||
| 
 | ||||
| Data structures, callbacks, and initialization | ||||
| 
 | ||||
| Depending on which type of buffers are being used, the driver should | ||||
| include one of the following files: | ||||
| 
 | ||||
|     <media/videobuf-dma-sg.h>		/* Physically scattered */ | ||||
|     <media/videobuf-vmalloc.h>		/* vmalloc() buffers	*/ | ||||
|     <media/videobuf-dma-contig.h>	/* Physically contiguous */ | ||||
| 
 | ||||
| The driver's data structure describing a V4L2 device should include a | ||||
| struct videobuf_queue instance for the management of the buffer queue, | ||||
| along with a list_head for the queue of available buffers.  There will also | ||||
| need to be an interrupt-safe spinlock which is used to protect (at least) | ||||
| the queue. | ||||
| 
 | ||||
| The next step is to write four simple callbacks to help videobuf deal with | ||||
| the management of buffers: | ||||
| 
 | ||||
|     struct videobuf_queue_ops { | ||||
| 	int (*buf_setup)(struct videobuf_queue *q, | ||||
| 			 unsigned int *count, unsigned int *size); | ||||
| 	int (*buf_prepare)(struct videobuf_queue *q, | ||||
| 			   struct videobuf_buffer *vb, | ||||
| 			   enum v4l2_field field); | ||||
| 	void (*buf_queue)(struct videobuf_queue *q, | ||||
| 			  struct videobuf_buffer *vb); | ||||
| 	void (*buf_release)(struct videobuf_queue *q, | ||||
| 			    struct videobuf_buffer *vb); | ||||
|     }; | ||||
| 
 | ||||
| buf_setup() is called early in the I/O process, when streaming is being | ||||
| initiated; its purpose is to tell videobuf about the I/O stream.  The count | ||||
| parameter will be a suggested number of buffers to use; the driver should | ||||
| check it for rationality and adjust it if need be.  As a practical rule, a | ||||
| minimum of two buffers are needed for proper streaming, and there is | ||||
| usually a maximum (which cannot exceed 32) which makes sense for each | ||||
| device.  The size parameter should be set to the expected (maximum) size | ||||
| for each frame of data. | ||||
| 
 | ||||
| Each buffer (in the form of a struct videobuf_buffer pointer) will be | ||||
| passed to buf_prepare(), which should set the buffer's size, width, height, | ||||
| and field fields properly.  If the buffer's state field is | ||||
| VIDEOBUF_NEEDS_INIT, the driver should pass it to: | ||||
| 
 | ||||
|     int videobuf_iolock(struct videobuf_queue* q, struct videobuf_buffer *vb, | ||||
| 			struct v4l2_framebuffer *fbuf); | ||||
| 
 | ||||
| Among other things, this call will usually allocate memory for the buffer. | ||||
| Finally, the buf_prepare() function should set the buffer's state to | ||||
| VIDEOBUF_PREPARED. | ||||
| 
 | ||||
| When a buffer is queued for I/O, it is passed to buf_queue(), which should | ||||
| put it onto the driver's list of available buffers and set its state to | ||||
| VIDEOBUF_QUEUED.  Note that this function is called with the queue spinlock | ||||
| held; if it tries to acquire it as well things will come to a screeching | ||||
| halt.  Yes, this is the voice of experience.  Note also that videobuf may | ||||
| wait on the first buffer in the queue; placing other buffers in front of it | ||||
| could again gum up the works.  So use list_add_tail() to enqueue buffers. | ||||
| 
 | ||||
| Finally, buf_release() is called when a buffer is no longer intended to be | ||||
| used.  The driver should ensure that there is no I/O active on the buffer, | ||||
| then pass it to the appropriate free routine(s): | ||||
| 
 | ||||
|     /* Scatter/gather drivers */ | ||||
|     int videobuf_dma_unmap(struct videobuf_queue *q, | ||||
| 			   struct videobuf_dmabuf *dma); | ||||
|     int videobuf_dma_free(struct videobuf_dmabuf *dma); | ||||
| 
 | ||||
|     /* vmalloc drivers */ | ||||
|     void videobuf_vmalloc_free (struct videobuf_buffer *buf); | ||||
| 
 | ||||
|     /* Contiguous drivers */ | ||||
|     void videobuf_dma_contig_free(struct videobuf_queue *q, | ||||
| 				  struct videobuf_buffer *buf); | ||||
| 
 | ||||
| One way to ensure that a buffer is no longer under I/O is to pass it to: | ||||
| 
 | ||||
|     int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr); | ||||
| 
 | ||||
| Here, vb is the buffer, non_blocking indicates whether non-blocking I/O | ||||
| should be used (it should be zero in the buf_release() case), and intr | ||||
| controls whether an interruptible wait is used. | ||||
| 
 | ||||
| File operations | ||||
| 
 | ||||
| At this point, much of the work is done; much of the rest is slipping | ||||
| videobuf calls into the implementation of the other driver callbacks.  The | ||||
| first step is in the open() function, which must initialize the | ||||
| videobuf queue.  The function to use depends on the type of buffer used: | ||||
| 
 | ||||
|     void videobuf_queue_sg_init(struct videobuf_queue *q, | ||||
| 				struct videobuf_queue_ops *ops, | ||||
| 				struct device *dev, | ||||
| 				spinlock_t *irqlock, | ||||
| 				enum v4l2_buf_type type, | ||||
| 				enum v4l2_field field, | ||||
| 				unsigned int msize, | ||||
| 				void *priv); | ||||
| 
 | ||||
|     void videobuf_queue_vmalloc_init(struct videobuf_queue *q, | ||||
| 				struct videobuf_queue_ops *ops, | ||||
| 				struct device *dev, | ||||
| 				spinlock_t *irqlock, | ||||
| 				enum v4l2_buf_type type, | ||||
| 				enum v4l2_field field, | ||||
| 				unsigned int msize, | ||||
| 				void *priv); | ||||
| 
 | ||||
|     void videobuf_queue_dma_contig_init(struct videobuf_queue *q, | ||||
| 				       struct videobuf_queue_ops *ops, | ||||
| 				       struct device *dev, | ||||
| 				       spinlock_t *irqlock, | ||||
| 				       enum v4l2_buf_type type, | ||||
| 				       enum v4l2_field field, | ||||
| 				       unsigned int msize, | ||||
| 				       void *priv); | ||||
| 
 | ||||
| In each case, the parameters are the same: q is the queue structure for the | ||||
| device, ops is the set of callbacks as described above, dev is the device | ||||
| structure for this video device, irqlock is an interrupt-safe spinlock to | ||||
| protect access to the data structures, type is the buffer type used by the | ||||
| device (cameras will use V4L2_BUF_TYPE_VIDEO_CAPTURE, for example), field | ||||
| describes which field is being captured (often V4L2_FIELD_NONE for | ||||
| progressive devices), msize is the size of any containing structure used | ||||
| around struct videobuf_buffer, and priv is a private data pointer which | ||||
| shows up in the priv_data field of struct videobuf_queue.  Note that these | ||||
| are void functions which, evidently, are immune to failure. | ||||
| 
 | ||||
| V4L2 capture drivers can be written to support either of two APIs: the | ||||
| read() system call and the rather more complicated streaming mechanism.  As | ||||
| a general rule, it is necessary to support both to ensure that all | ||||
| applications have a chance of working with the device.  Videobuf makes it | ||||
| easy to do that with the same code.  To implement read(), the driver need | ||||
| only make a call to one of: | ||||
| 
 | ||||
|     ssize_t videobuf_read_one(struct videobuf_queue *q, | ||||
| 			      char __user *data, size_t count, | ||||
| 			      loff_t *ppos, int nonblocking); | ||||
| 
 | ||||
|     ssize_t videobuf_read_stream(struct videobuf_queue *q, | ||||
| 				 char __user *data, size_t count, | ||||
| 				 loff_t *ppos, int vbihack, int nonblocking); | ||||
| 
 | ||||
| Either one of these functions will read frame data into data, returning the | ||||
| amount actually read; the difference is that videobuf_read_one() will only | ||||
| read a single frame, while videobuf_read_stream() will read multiple frames | ||||
| if they are needed to satisfy the count requested by the application.  A | ||||
| typical driver read() implementation will start the capture engine, call | ||||
| one of the above functions, then stop the engine before returning (though a | ||||
| smarter implementation might leave the engine running for a little while in | ||||
| anticipation of another read() call happening in the near future). | ||||
| 
 | ||||
| The poll() function can usually be implemented with a direct call to: | ||||
| 
 | ||||
|     unsigned int videobuf_poll_stream(struct file *file, | ||||
| 				      struct videobuf_queue *q, | ||||
| 				      poll_table *wait); | ||||
| 
 | ||||
| Note that the actual wait queue eventually used will be the one associated | ||||
| with the first available buffer. | ||||
| 
 | ||||
| When streaming I/O is done to kernel-space buffers, the driver must support | ||||
| the mmap() system call to enable user space to access the data.  In many | ||||
| V4L2 drivers, the often-complex mmap() implementation simplifies to a | ||||
| single call to: | ||||
| 
 | ||||
|     int videobuf_mmap_mapper(struct videobuf_queue *q, | ||||
| 			     struct vm_area_struct *vma); | ||||
| 
 | ||||
| Everything else is handled by the videobuf code. | ||||
| 
 | ||||
| The release() function requires two separate videobuf calls: | ||||
| 
 | ||||
|     void videobuf_stop(struct videobuf_queue *q); | ||||
|     int videobuf_mmap_free(struct videobuf_queue *q); | ||||
| 
 | ||||
| The call to videobuf_stop() terminates any I/O in progress - though it is | ||||
| still up to the driver to stop the capture engine.  The call to | ||||
| videobuf_mmap_free() will ensure that all buffers have been unmapped; if | ||||
| so, they will all be passed to the buf_release() callback.  If buffers | ||||
| remain mapped, videobuf_mmap_free() returns an error code instead.  The | ||||
| purpose is clearly to cause the closing of the file descriptor to fail if | ||||
| buffers are still mapped, but every driver in the 2.6.32 kernel cheerfully | ||||
| ignores its return value. | ||||
| 
 | ||||
| ioctl() operations | ||||
| 
 | ||||
| The V4L2 API includes a very long list of driver callbacks to respond to | ||||
| the many ioctl() commands made available to user space.  A number of these | ||||
| - those associated with streaming I/O - turn almost directly into videobuf | ||||
| calls.  The relevant helper functions are: | ||||
| 
 | ||||
|     int videobuf_reqbufs(struct videobuf_queue *q, | ||||
| 			 struct v4l2_requestbuffers *req); | ||||
|     int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b); | ||||
|     int videobuf_qbuf(struct videobuf_queue *q, struct v4l2_buffer *b); | ||||
|     int videobuf_dqbuf(struct videobuf_queue *q, struct v4l2_buffer *b, | ||||
| 		       int nonblocking); | ||||
|     int videobuf_streamon(struct videobuf_queue *q); | ||||
|     int videobuf_streamoff(struct videobuf_queue *q); | ||||
|     int videobuf_cgmbuf(struct videobuf_queue *q, struct video_mbuf *mbuf, | ||||
| 			int count); | ||||
| 
 | ||||
| So, for example, a VIDIOC_REQBUFS call turns into a call to the driver's | ||||
| vidioc_reqbufs() callback which, in turn, usually only needs to locate the | ||||
| proper struct videobuf_queue pointer and pass it to videobuf_reqbufs(). | ||||
| These support functions can replace a great deal of buffer management | ||||
| boilerplate in a lot of V4L2 drivers. | ||||
| 
 | ||||
| The vidioc_streamon() and vidioc_streamoff() functions will be a bit more | ||||
| complex, of course, since they will also need to deal with starting and | ||||
| stopping the capture engine.  videobuf_cgmbuf(), called from the driver's | ||||
| vidiocgmbuf() function, only exists if the V4L1 compatibility module has | ||||
| been selected with CONFIG_VIDEO_V4L1_COMPAT, so its use must be surrounded | ||||
| with #ifdef directives. | ||||
| 
 | ||||
| Buffer allocation | ||||
| 
 | ||||
| Thus far, we have talked about buffers, but have not looked at how they are | ||||
| allocated.  The scatter/gather case is the most complex on this front.  For | ||||
| allocation, the driver can leave buffer allocation entirely up to the | ||||
| videobuf layer; in this case, buffers will be allocated as anonymous | ||||
| user-space pages and will be very scattered indeed.  If the application is | ||||
| using user-space buffers, no allocation is needed; the videobuf layer will | ||||
| take care of calling get_user_pages() and filling in the scatterlist array. | ||||
| 
 | ||||
| If the driver needs to do its own memory allocation, it should be done in | ||||
| the vidioc_reqbufs() function, *after* calling videobuf_reqbufs().  The | ||||
| first step is a call to: | ||||
| 
 | ||||
|     struct videobuf_dmabuf *videobuf_to_dma(struct videobuf_buffer *buf); | ||||
| 
 | ||||
| The returned videobuf_dmabuf structure (defined in | ||||
| <media/videobuf-dma-sg.h>) includes a couple of relevant fields: | ||||
| 
 | ||||
|     struct scatterlist  *sglist; | ||||
|     int                 sglen; | ||||
| 
 | ||||
| The driver must allocate an appropriately-sized scatterlist array and | ||||
| populate it with pointers to the pieces of the allocated buffer; sglen | ||||
| should be set to the length of the array. | ||||
| 
 | ||||
| Drivers using the vmalloc() method need not (and cannot) concern themselves | ||||
| with buffer allocation at all; videobuf will handle those details.  The | ||||
| same is normally true of contiguous-DMA drivers as well; videobuf will | ||||
| allocate the buffers (with dma_alloc_coherent()) when it sees fit.  That | ||||
| means that these drivers may be trying to do high-order allocations at any | ||||
| time, an operation which is not always guaranteed to work.  Some drivers | ||||
| play tricks by allocating DMA space at system boot time; videobuf does not | ||||
| currently play well with those drivers. | ||||
| 
 | ||||
| As of 2.6.31, contiguous-DMA drivers can work with a user-supplied buffer, | ||||
| as long as that buffer is physically contiguous.  Normal user-space | ||||
| allocations will not meet that criterion, but buffers obtained from other | ||||
| kernel drivers, or those contained within huge pages, will work with these | ||||
| drivers. | ||||
| 
 | ||||
| Filling the buffers | ||||
| 
 | ||||
| The final part of a videobuf implementation has no direct callback - it's | ||||
| the portion of the code which actually puts frame data into the buffers, | ||||
| usually in response to interrupts from the device.  For all types of | ||||
| drivers, this process works approximately as follows: | ||||
| 
 | ||||
|  - Obtain the next available buffer and make sure that somebody is actually | ||||
|    waiting for it. | ||||
| 
 | ||||
|  - Get a pointer to the memory and put video data there. | ||||
| 
 | ||||
|  - Mark the buffer as done and wake up the process waiting for it. | ||||
| 
 | ||||
| Step (1) above is done by looking at the driver-managed list_head structure | ||||
| - the one which is filled in the buf_queue() callback.  Because starting | ||||
| the engine and enqueueing buffers are done in separate steps, it's possible | ||||
| for the engine to be running without any buffers available - in the | ||||
| vmalloc() case especially.  So the driver should be prepared for the list | ||||
| to be empty.  It is equally possible that nobody is yet interested in the | ||||
| buffer; the driver should not remove it from the list or fill it until a | ||||
| process is waiting on it.  That test can be done by examining the buffer's | ||||
| done field (a wait_queue_head_t structure) with waitqueue_active(). | ||||
| 
 | ||||
| A buffer's state should be set to VIDEOBUF_ACTIVE before being mapped for | ||||
| DMA; that ensures that the videobuf layer will not try to do anything with | ||||
| it while the device is transferring data. | ||||
| 
 | ||||
| For scatter/gather drivers, the needed memory pointers will be found in the | ||||
| scatterlist structure described above.  Drivers using the vmalloc() method | ||||
| can get a memory pointer with: | ||||
| 
 | ||||
|     void *videobuf_to_vmalloc(struct videobuf_buffer *buf); | ||||
| 
 | ||||
| For contiguous DMA drivers, the function to use is: | ||||
| 
 | ||||
|     dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf); | ||||
| 
 | ||||
| The contiguous DMA API goes out of its way to hide the kernel-space address | ||||
| of the DMA buffer from drivers. | ||||
| 
 | ||||
| The final step is to set the size field of the relevant videobuf_buffer | ||||
| structure to the actual size of the captured image, set state to | ||||
| VIDEOBUF_DONE, then call wake_up() on the done queue.  At this point, the | ||||
| buffer is owned by the videobuf layer and the driver should not touch it | ||||
| again. | ||||
| 
 | ||||
| Developers who are interested in more information can go into the relevant | ||||
| header files; there are a few low-level functions declared there which have | ||||
| not been talked about here.  Also worthwhile is the vivi driver | ||||
| (drivers/media/video/vivi.c), which is maintained as an example of how V4L2 | ||||
| drivers should be written.  Vivi only uses the vmalloc() API, but it's good | ||||
| enough to get started with.  Note also that all of these calls are exported | ||||
| GPL-only, so they will not be available to non-GPL kernel modules. | ||||
| @ -166,19 +166,13 @@ NUMA | ||||
| 
 | ||||
|   numa=noacpi   Don't parse the SRAT table for NUMA setup | ||||
| 
 | ||||
|   numa=fake=CMDLINE | ||||
| 		If a number, fakes CMDLINE nodes and ignores NUMA setup of the | ||||
| 		actual machine.  Otherwise, system memory is configured | ||||
| 		depending on the sizes and coefficients listed.  For example: | ||||
| 			numa=fake=2*512,1024,4*256,*128 | ||||
| 		gives two 512M nodes, a 1024M node, four 256M nodes, and the | ||||
| 		rest split into 128M chunks.  If the last character of CMDLINE | ||||
| 		is a *, the remaining memory is divided up equally among its | ||||
| 		coefficient: | ||||
| 			numa=fake=2*512,2* | ||||
| 		gives two 512M nodes and the rest split into two nodes. | ||||
| 		Otherwise, the remaining system RAM is allocated to an | ||||
| 		additional node. | ||||
|   numa=fake=<size>[MG] | ||||
| 		If given as a memory unit, fills all system RAM with nodes of | ||||
| 		size interleaved over physical nodes. | ||||
| 
 | ||||
|   numa=fake=<N> | ||||
| 		If given as an integer, fills all system RAM with N fake nodes | ||||
| 		interleaved over physical nodes. | ||||
| 
 | ||||
| ACPI | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										80
									
								
								MAINTAINERS
									
									
									
									
									
								
							
							
						
						
									
										80
									
								
								MAINTAINERS
									
									
									
									
									
								
							| @ -221,6 +221,7 @@ F:	drivers/net/acenic* | ||||
| 
 | ||||
| ACER ASPIRE ONE TEMPERATURE AND FAN DRIVER | ||||
| M:	Peter Feuerer <peter@piie.net> | ||||
| L:	platform-driver-x86@vger.kernel.org | ||||
| W:	http://piie.net/?section=acerhdf | ||||
| S:	Maintained | ||||
| F:	drivers/platform/x86/acerhdf.c | ||||
| @ -228,6 +229,7 @@ F:	drivers/platform/x86/acerhdf.c | ||||
| ACER WMI LAPTOP EXTRAS | ||||
| M:	Carlos Corbacho <carlos@strangeworlds.co.uk> | ||||
| L:	aceracpi@googlegroups.com (subscribers-only) | ||||
| L:	platform-driver-x86@vger.kernel.org | ||||
| W:	http://code.google.com/p/aceracpi | ||||
| S:	Maintained | ||||
| F:	drivers/platform/x86/acer-wmi.c | ||||
| @ -288,7 +290,7 @@ F:	drivers/acpi/video.c | ||||
| 
 | ||||
| ACPI WMI DRIVER | ||||
| M:	Carlos Corbacho <carlos@strangeworlds.co.uk> | ||||
| L:	linux-acpi@vger.kernel.org | ||||
| L:	platform-driver-x86@vger.kernel.org | ||||
| W:	http://www.lesswatts.org/projects/acpi/ | ||||
| S:	Maintained | ||||
| F:	drivers/platform/x86/wmi.c | ||||
| @ -616,10 +618,10 @@ M:	Richard Purdie <rpurdie@rpsys.net> | ||||
| S:	Maintained | ||||
| 
 | ||||
| ARM/CORTINA SYSTEMS GEMINI ARM ARCHITECTURE | ||||
| M:	Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | ||||
| M:	Paulius Zaleckas <paulius.zaleckas@gmail.com> | ||||
| L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | ||||
| T:	git git://gitorious.org/linux-gemini/mainline.git | ||||
| S:	Maintained | ||||
| S:	Odd Fixes | ||||
| F:	arch/arm/mach-gemini/ | ||||
| 
 | ||||
| ARM/EBSA110 MACHINE SUPPORT | ||||
| @ -641,9 +643,9 @@ T:	topgit git://git.openezx.org/openezx.git | ||||
| F:	arch/arm/mach-pxa/ezx.c | ||||
| 
 | ||||
| ARM/FARADAY FA526 PORT | ||||
| M:	Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | ||||
| M:	Paulius Zaleckas <paulius.zaleckas@gmail.com> | ||||
| L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | ||||
| S:	Maintained | ||||
| S:	Odd Fixes | ||||
| F:	arch/arm/mm/*-fa* | ||||
| 
 | ||||
| ARM/FOOTBRIDGE ARCHITECTURE | ||||
| @ -968,6 +970,7 @@ ASUS ACPI EXTRAS DRIVER | ||||
| M:	Corentin Chary <corentincj@iksaif.net> | ||||
| M:	Karol Kozimor <sziwan@users.sourceforge.net> | ||||
| L:	acpi4asus-user@lists.sourceforge.net | ||||
| L:	platform-driver-x86@vger.kernel.org | ||||
| W:	http://acpi4asus.sf.net | ||||
| S:	Maintained | ||||
| F:	drivers/platform/x86/asus_acpi.c | ||||
| @ -981,6 +984,7 @@ F:	drivers/hwmon/asb100.c | ||||
| ASUS LAPTOP EXTRAS DRIVER | ||||
| M:	Corentin Chary <corentincj@iksaif.net> | ||||
| L:	acpi4asus-user@lists.sourceforge.net | ||||
| L:	platform-driver-x86@vger.kernel.org | ||||
| W:	http://acpi4asus.sf.net | ||||
| S:	Maintained | ||||
| F:	drivers/platform/x86/asus-laptop.c | ||||
| @ -1473,6 +1477,7 @@ F:	drivers/scsi/fnic/ | ||||
| CMPC ACPI DRIVER | ||||
| M:	Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com> | ||||
| M:	Daniel Oliveira Nascimento <don@syst.com.br> | ||||
| L:	platform-driver-x86@vger.kernel.org | ||||
| S:	Supported | ||||
| F:	drivers/platform/x86/classmate-laptop.c | ||||
| 
 | ||||
| @ -1516,6 +1521,7 @@ F:	drivers/pci/hotplug/cpcihp_generic.c | ||||
| 
 | ||||
| COMPAL LAPTOP SUPPORT | ||||
| M:	Cezary Jackiewicz <cezary.jackiewicz@gmail.com> | ||||
| L:	platform-driver-x86@vger.kernel.org | ||||
| S:	Maintained | ||||
| F:	drivers/platform/x86/compal-laptop.c | ||||
| 
 | ||||
| @ -1746,6 +1752,7 @@ F:	drivers/net/defxx.* | ||||
| 
 | ||||
| DELL LAPTOP DRIVER | ||||
| M:	Matthew Garrett <mjg59@srcf.ucam.org> | ||||
| L:	platform-driver-x86@vger.kernel.org | ||||
| S:	Maintained | ||||
| F:	drivers/platform/x86/dell-laptop.c | ||||
| 
 | ||||
| @ -2028,6 +2035,7 @@ F:	drivers/edac/r82600_edac.c | ||||
| EEEPC LAPTOP EXTRAS DRIVER | ||||
| M:	Corentin Chary <corentincj@iksaif.net> | ||||
| L:	acpi4asus-user@lists.sourceforge.net | ||||
| L:	platform-driver-x86@vger.kernel.org | ||||
| W:	http://acpi4asus.sf.net | ||||
| S:	Maintained | ||||
| F:	drivers/platform/x86/eeepc-laptop.c | ||||
| @ -2141,6 +2149,17 @@ S:	Supported | ||||
| F:	Documentation/fault-injection/ | ||||
| F:	lib/fault-inject.c | ||||
| 
 | ||||
| FCOE SUBSYSTEM (libfc, libfcoe, fcoe) | ||||
| M:	Robert Love <robert.w.love@intel.com> | ||||
| L:	devel@open-fcoe.org | ||||
| W:	www.Open-FCoE.org | ||||
| S:	Supported | ||||
| F:	drivers/scsi/libfc/ | ||||
| F:	drivers/scsi/fcoe/ | ||||
| F:	include/scsi/fc/ | ||||
| F:	include/scsi/libfc.h | ||||
| F:	include/scsi/libfcoe.h | ||||
| 
 | ||||
| FILE LOCKING (flock() and fcntl()/lockf()) | ||||
| M:	Matthew Wilcox <matthew@wil.cx> | ||||
| L:	linux-fsdevel@vger.kernel.org | ||||
| @ -2295,7 +2314,7 @@ F:	arch/frv/ | ||||
| 
 | ||||
| FUJITSU LAPTOP EXTRAS | ||||
| M:	Jonathan Woithe <jwoithe@physics.adelaide.edu.au> | ||||
| L:	linux-acpi@vger.kernel.org | ||||
| L:	platform-driver-x86@vger.kernel.org | ||||
| S:	Maintained | ||||
| F:	drivers/platform/x86/fujitsu-laptop.c | ||||
| 
 | ||||
| @ -2399,6 +2418,18 @@ L:	linuxppc-dev@ozlabs.org | ||||
| S:	Odd Fixes | ||||
| F:	drivers/char/hvc_* | ||||
| 
 | ||||
| VIRTIO CONSOLE DRIVER | ||||
| M:	Amit Shah <amit.shah@redhat.com> | ||||
| L:	virtualization@lists.linux-foundation.org | ||||
| S:	Maintained | ||||
| F:	drivers/char/virtio_console.c | ||||
| 
 | ||||
| iSCSI BOOT FIRMWARE TABLE (iBFT) DRIVER | ||||
| M:	Peter Jones <pjones@redhat.com> | ||||
| M:	Konrad Rzeszutek Wilk <konrad@kernel.org> | ||||
| S:	Maintained | ||||
| F:	drivers/firmware/iscsi_ibft* | ||||
| 
 | ||||
| GSPCA FINEPIX SUBDRIVER | ||||
| M:	Frank Zago <frank@zago.net> | ||||
| L:	linux-media@vger.kernel.org | ||||
| @ -2567,6 +2598,7 @@ F:	drivers/net/wireless/hostap/ | ||||
| 
 | ||||
| HP COMPAQ TC1100 TABLET WMI EXTRAS DRIVER | ||||
| M:	Carlos Corbacho <carlos@strangeworlds.co.uk> | ||||
| L:	platform-driver-x86@vger.kernel.org | ||||
| S:	Odd Fixes | ||||
| F:	drivers/platform/x86/tc1100-wmi.c | ||||
| 
 | ||||
| @ -2777,7 +2809,7 @@ F:	drivers/video/i810/ | ||||
| 
 | ||||
| INTEL MENLOW THERMAL DRIVER | ||||
| M:	Sujith Thomas <sujith.thomas@intel.com> | ||||
| L:	linux-acpi@vger.kernel.org | ||||
| L:	platform-driver-x86@vger.kernel.org | ||||
| W:	http://www.lesswatts.org/projects/acpi/ | ||||
| S:	Supported | ||||
| F:	drivers/platform/x86/intel_menlow.c | ||||
| @ -3643,6 +3675,7 @@ F:	drivers/char/mxser.* | ||||
| 
 | ||||
| MSI LAPTOP SUPPORT | ||||
| M:	Lennart Poettering <mzxreary@0pointer.de> | ||||
| L:	platform-driver-x86@vger.kernel.org | ||||
| W:	https://tango.0pointer.de/mailman/listinfo/s270-linux | ||||
| W:	http://0pointer.de/lennart/tchibo.html | ||||
| S:	Maintained | ||||
| @ -3650,6 +3683,7 @@ F:	drivers/platform/x86/msi-laptop.c | ||||
| 
 | ||||
| MSI WMI SUPPORT | ||||
| M:	Anisse Astier <anisse@astier.eu> | ||||
| L:	platform-driver-x86@vger.kernel.org | ||||
| S:	Supported | ||||
| F:	drivers/platform/x86/msi-wmi.c | ||||
| 
 | ||||
| @ -4102,6 +4136,7 @@ F:	drivers/i2c/busses/i2c-pasemi.c | ||||
| 
 | ||||
| PANASONIC LAPTOP ACPI EXTRAS DRIVER | ||||
| M:	Harald Welte <laforge@gnumonks.org> | ||||
| L:	platform-driver-x86@vger.kernel.org | ||||
| S:	Maintained | ||||
| F:	drivers/platform/x86/panasonic-laptop.c | ||||
| 
 | ||||
| @ -4522,7 +4557,7 @@ F:	drivers/net/wireless/ray* | ||||
| RCUTORTURE MODULE | ||||
| M:	Josh Triplett <josh@freedesktop.org> | ||||
| M:	"Paul E. McKenney" <paulmck@linux.vnet.ibm.com> | ||||
| S:	Maintained | ||||
| S:	Supported | ||||
| F:	Documentation/RCU/torture.txt | ||||
| F:	kernel/rcutorture.c | ||||
| 
 | ||||
| @ -4547,11 +4582,12 @@ M:	Dipankar Sarma <dipankar@in.ibm.com> | ||||
| M:	"Paul E. McKenney" <paulmck@linux.vnet.ibm.com> | ||||
| W:	http://www.rdrop.com/users/paulmck/rclock/ | ||||
| S:	Supported | ||||
| F:	Documentation/RCU/rcu.txt | ||||
| F:	Documentation/RCU/rcuref.txt | ||||
| F:	include/linux/rcupdate.h | ||||
| F:	include/linux/srcu.h | ||||
| F:	kernel/rcupdate.c | ||||
| F:	Documentation/RCU/ | ||||
| F:	include/linux/rcu* | ||||
| F:	include/linux/srcu* | ||||
| F:	kernel/rcu* | ||||
| F:	kernel/srcu* | ||||
| X:	kernel/rcutorture.c | ||||
| 
 | ||||
| REAL TIME CLOCK DRIVER | ||||
| M:	Paul Gortmaker <p_gortmaker@yahoo.com> | ||||
| @ -4689,6 +4725,13 @@ F:	drivers/media/common/saa7146* | ||||
| F:	drivers/media/video/*7146* | ||||
| F:	include/media/*7146* | ||||
| 
 | ||||
| TLG2300 VIDEO4LINUX-2 DRIVER | ||||
| M:	Huang Shijie <shijie8@gmail.com> | ||||
| M:	Kang Yong <kangyong@telegent.com> | ||||
| M:	Zhang Xiaobing <xbzhang@telegent.com> | ||||
| S:	Supported | ||||
| F:	drivers/media/video/tlg2300 | ||||
| 
 | ||||
| SC1200 WDT DRIVER | ||||
| M:	Zwane Mwaikambo <zwane@arm.linux.org.uk> | ||||
| S:	Maintained | ||||
| @ -5049,7 +5092,7 @@ F:	include/linux/ssb/ | ||||
| 
 | ||||
| SONY VAIO CONTROL DEVICE DRIVER | ||||
| M:	Mattia Dongili <malattia@linux.it> | ||||
| L:	linux-acpi@vger.kernel.org | ||||
| L:	platform-driver-x86@vger.kernel.org | ||||
| W:	http://www.linux.it/~malattia/wiki/index.php/Sony_drivers | ||||
| S:	Maintained | ||||
| F:	Documentation/laptops/sony-laptop.txt | ||||
| @ -5255,6 +5298,7 @@ F:	arch/xtensa/ | ||||
| THINKPAD ACPI EXTRAS DRIVER | ||||
| M:	Henrique de Moraes Holschuh <ibm-acpi@hmh.eng.br> | ||||
| L:	ibm-acpi-devel@lists.sourceforge.net | ||||
| L:	platform-driver-x86@vger.kernel.org | ||||
| W:	http://ibm-acpi.sourceforge.net | ||||
| W:	http://thinkwiki.org/wiki/Ibm-acpi | ||||
| T:	git git://repo.or.cz/linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git | ||||
| @ -5308,10 +5352,12 @@ F:	security/tomoyo/ | ||||
| 
 | ||||
| TOPSTAR LAPTOP EXTRAS DRIVER | ||||
| M:	Herton Ronaldo Krzesinski <herton@mandriva.com.br> | ||||
| L:	platform-driver-x86@vger.kernel.org | ||||
| S:	Maintained | ||||
| F:	drivers/platform/x86/topstar-laptop.c | ||||
| 
 | ||||
| TOSHIBA ACPI EXTRAS DRIVER | ||||
| L:	platform-driver-x86@vger.kernel.org | ||||
| S:	Orphan | ||||
| F:	drivers/platform/x86/toshiba_acpi.c | ||||
| 
 | ||||
| @ -6048,6 +6094,12 @@ S:	Maintained | ||||
| F:	Documentation/x86/ | ||||
| F:	arch/x86/ | ||||
| 
 | ||||
| X86 PLATFORM DRIVERS | ||||
| M:	Matthew Garrett <mjg@redhat.com> | ||||
| L:	platform-driver-x86@vger.kernel.org | ||||
| S:	Maintained | ||||
| F:	drivers/platform/x86 | ||||
| 
 | ||||
| XEN HYPERVISOR INTERFACE | ||||
| M:	Jeremy Fitzhardinge <jeremy@xensource.com> | ||||
| M:	Chris Wright <chrisw@sous-sol.org> | ||||
|  | ||||
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							| @ -1,7 +1,7 @@ | ||||
| VERSION = 2 | ||||
| PATCHLEVEL = 6 | ||||
| SUBLEVEL = 33 | ||||
| EXTRAVERSION = -rc8 | ||||
| EXTRAVERSION = | ||||
| NAME = Man-Eating Seals of Antiquity | ||||
| 
 | ||||
| # *DOCUMENTATION*
 | ||||
|  | ||||
							
								
								
									
										26
									
								
								arch/Kconfig
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								arch/Kconfig
									
									
									
									
									
								
							| @ -3,11 +3,9 @@ | ||||
| # | ||||
| 
 | ||||
| config OPROFILE | ||||
| 	tristate "OProfile system profiling (EXPERIMENTAL)" | ||||
| 	tristate "OProfile system profiling" | ||||
| 	depends on PROFILING | ||||
| 	depends on HAVE_OPROFILE | ||||
| 	depends on TRACING_SUPPORT | ||||
| 	select TRACING | ||||
| 	select RING_BUFFER | ||||
| 	select RING_BUFFER_ALLOW_SWAP | ||||
| 	help | ||||
| @ -17,20 +15,6 @@ config OPROFILE | ||||
| 
 | ||||
| 	  If unsure, say N. | ||||
| 
 | ||||
| config OPROFILE_IBS | ||||
| 	bool "OProfile AMD IBS support (EXPERIMENTAL)" | ||||
| 	default n | ||||
| 	depends on OPROFILE && SMP && X86 | ||||
| 	help | ||||
|           Instruction-Based Sampling (IBS) is a new profiling | ||||
|           technique that provides rich, precise program performance | ||||
|           information. IBS is introduced by AMD Family10h processors | ||||
|           (AMD Opteron Quad-Core processor "Barcelona") to overcome | ||||
|           the limitations of conventional performance counter | ||||
|           sampling. | ||||
| 
 | ||||
| 	  If unsure, say N. | ||||
| 
 | ||||
| config OPROFILE_EVENT_MULTIPLEX | ||||
| 	bool "OProfile multiplexing support (EXPERIMENTAL)" | ||||
| 	default n | ||||
| @ -121,6 +105,14 @@ config HAVE_DMA_ATTRS | ||||
| config USE_GENERIC_SMP_HELPERS | ||||
| 	bool | ||||
| 
 | ||||
| config HAVE_REGS_AND_STACK_ACCESS_API | ||||
| 	bool | ||||
| 	help | ||||
| 	  This symbol should be selected by an architecure if it supports | ||||
| 	  the API needed to access registers and stack entries from pt_regs, | ||||
| 	  declared in asm/ptrace.h | ||||
| 	  For example the kprobes-based event tracer needs this API. | ||||
| 
 | ||||
| config HAVE_CLK | ||||
| 	bool | ||||
| 	help | ||||
|  | ||||
| @ -126,8 +126,8 @@ DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_final); | ||||
| #define MB			(1024*KB) | ||||
| #define GB			(1024*MB) | ||||
| 
 | ||||
| void | ||||
| pcibios_align_resource(void *data, struct resource *res, | ||||
| resource_size_t | ||||
| pcibios_align_resource(void *data, const struct resource *res, | ||||
| 		       resource_size_t size, resource_size_t align) | ||||
| { | ||||
| 	struct pci_dev *dev = data; | ||||
| @ -184,7 +184,7 @@ pcibios_align_resource(void *data, struct resource *res, | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	res->start = start; | ||||
| 	return start; | ||||
| } | ||||
| #undef KB | ||||
| #undef MB | ||||
|  | ||||
| @ -42,7 +42,8 @@ | ||||
| #endif | ||||
| 
 | ||||
| #if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \ | ||||
|     defined(CONFIG_CPU_ARM925T) || defined(CONFIG_CPU_ARM1020) | ||||
|     defined(CONFIG_CPU_ARM925T) || defined(CONFIG_CPU_ARM1020) || \ | ||||
|     defined(CONFIG_CPU_ARM1026) | ||||
| # define MULTI_CACHE 1 | ||||
| #endif | ||||
| 
 | ||||
| @ -446,6 +447,16 @@ static inline void __flush_icache_all(void) | ||||
| 	    : "r" (0)); | ||||
| #endif | ||||
| } | ||||
| static inline void flush_kernel_vmap_range(void *addr, int size) | ||||
| { | ||||
| 	if ((cache_is_vivt() || cache_is_vipt_aliasing())) | ||||
| 	  __cpuc_flush_dcache_area(addr, (size_t)size); | ||||
| } | ||||
| static inline void invalidate_kernel_vmap_range(void *addr, int size) | ||||
| { | ||||
| 	if ((cache_is_vivt() || cache_is_vipt_aliasing())) | ||||
| 	  __cpuc_flush_dcache_area(addr, (size_t)size); | ||||
| } | ||||
| 
 | ||||
| #define ARCH_HAS_FLUSH_ANON_PAGE | ||||
| static inline void flush_anon_page(struct vm_area_struct *vma, | ||||
|  | ||||
| @ -616,15 +616,17 @@ char * __init pcibios_setup(char *str) | ||||
|  * but we want to try to avoid allocating at 0x2900-0x2bff | ||||
|  * which might be mirrored at 0x0100-0x03ff.. | ||||
|  */ | ||||
| void pcibios_align_resource(void *data, struct resource *res, | ||||
| 			    resource_size_t size, resource_size_t align) | ||||
| resource_size_t pcibios_align_resource(void *data, const struct resource *res, | ||||
| 				resource_size_t size, resource_size_t align) | ||||
| { | ||||
| 	resource_size_t start = res->start; | ||||
| 
 | ||||
| 	if (res->flags & IORESOURCE_IO && start & 0x300) | ||||
| 		start = (start + 0x3ff) & ~0x3ff; | ||||
| 
 | ||||
| 	res->start = (start + align - 1) & ~(align - 1); | ||||
| 	start = (start + align - 1) & ~(align - 1); | ||||
| 
 | ||||
| 	return start; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  | ||||
| @ -102,6 +102,7 @@ struct cpu_cache_fns cpu_cache; | ||||
| #endif | ||||
| #ifdef CONFIG_OUTER_CACHE | ||||
| struct outer_cache_fns outer_cache; | ||||
| EXPORT_SYMBOL(outer_cache); | ||||
| #endif | ||||
| 
 | ||||
| struct stack { | ||||
|  | ||||
| @ -37,6 +37,8 @@ | ||||
| #include <mach/nand.h> | ||||
| #include <mach/keyscan.h> | ||||
| 
 | ||||
| #include <media/tvp514x.h> | ||||
| 
 | ||||
| static inline int have_imager(void) | ||||
| { | ||||
| 	/* REVISIT when it's supported, trigger via Kconfig */ | ||||
| @ -306,6 +308,73 @@ static void dm365evm_mmc_configure(void) | ||||
| 	davinci_cfg_reg(DM365_SD1_DATA0); | ||||
| } | ||||
| 
 | ||||
| static struct tvp514x_platform_data tvp5146_pdata = { | ||||
| 	.clk_polarity = 0, | ||||
| 	.hs_polarity = 1, | ||||
| 	.vs_polarity = 1 | ||||
| }; | ||||
| 
 | ||||
| #define TVP514X_STD_ALL        (V4L2_STD_NTSC | V4L2_STD_PAL) | ||||
| /* Inputs available at the TVP5146 */ | ||||
| static struct v4l2_input tvp5146_inputs[] = { | ||||
| 	{ | ||||
| 		.index = 0, | ||||
| 		.name = "Composite", | ||||
| 		.type = V4L2_INPUT_TYPE_CAMERA, | ||||
| 		.std = TVP514X_STD_ALL, | ||||
| 	}, | ||||
| 	{ | ||||
| 		.index = 1, | ||||
| 		.name = "S-Video", | ||||
| 		.type = V4L2_INPUT_TYPE_CAMERA, | ||||
| 		.std = TVP514X_STD_ALL, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * this is the route info for connecting each input to decoder | ||||
|  * ouput that goes to vpfe. There is a one to one correspondence | ||||
|  * with tvp5146_inputs | ||||
|  */ | ||||
| static struct vpfe_route tvp5146_routes[] = { | ||||
| 	{ | ||||
| 		.input = INPUT_CVBS_VI2B, | ||||
| 		.output = OUTPUT_10BIT_422_EMBEDDED_SYNC, | ||||
| 	}, | ||||
| { | ||||
| 		.input = INPUT_SVIDEO_VI2C_VI1C, | ||||
| 		.output = OUTPUT_10BIT_422_EMBEDDED_SYNC, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| static struct vpfe_subdev_info vpfe_sub_devs[] = { | ||||
| 	{ | ||||
| 		.name = "tvp5146", | ||||
| 		.grp_id = 0, | ||||
| 		.num_inputs = ARRAY_SIZE(tvp5146_inputs), | ||||
| 		.inputs = tvp5146_inputs, | ||||
| 		.routes = tvp5146_routes, | ||||
| 		.can_route = 1, | ||||
| 		.ccdc_if_params = { | ||||
| 			.if_type = VPFE_BT656, | ||||
| 			.hdpol = VPFE_PINPOL_POSITIVE, | ||||
| 			.vdpol = VPFE_PINPOL_POSITIVE, | ||||
| 		}, | ||||
| 		.board_info = { | ||||
| 			I2C_BOARD_INFO("tvp5146", 0x5d), | ||||
| 			.platform_data = &tvp5146_pdata, | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| static struct vpfe_config vpfe_cfg = { | ||||
| 	.num_subdevs = ARRAY_SIZE(vpfe_sub_devs), | ||||
| 	.sub_devs = vpfe_sub_devs, | ||||
| 	.i2c_adapter_id = 1, | ||||
| 	.card_name = "DM365 EVM", | ||||
| 	.ccdc = "ISIF", | ||||
| }; | ||||
| 
 | ||||
| static void __init evm_init_i2c(void) | ||||
| { | ||||
| 	davinci_init_i2c(&i2c_pdata); | ||||
| @ -497,6 +566,8 @@ static struct davinci_uart_config uart_config __initdata = { | ||||
| 
 | ||||
| static void __init dm365_evm_map_io(void) | ||||
| { | ||||
| 	/* setup input configuration for VPFE input devices */ | ||||
| 	dm365_set_vpfe_config(&vpfe_cfg); | ||||
| 	dm365_init(); | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -125,7 +125,6 @@ static struct clk vpss_slave_clk = { | ||||
| 	.lpsc = DAVINCI_LPSC_VPSSSLV, | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| static struct clk clkout1_clk = { | ||||
| 	.name = "clkout1", | ||||
| 	.parent = &pll1_aux_clk, | ||||
| @ -665,6 +664,17 @@ static struct platform_device dm355_asp1_device = { | ||||
| 	.resource	= dm355_asp1_resources, | ||||
| }; | ||||
| 
 | ||||
| static void dm355_ccdc_setup_pinmux(void) | ||||
| { | ||||
| 	davinci_cfg_reg(DM355_VIN_PCLK); | ||||
| 	davinci_cfg_reg(DM355_VIN_CAM_WEN); | ||||
| 	davinci_cfg_reg(DM355_VIN_CAM_VD); | ||||
| 	davinci_cfg_reg(DM355_VIN_CAM_HD); | ||||
| 	davinci_cfg_reg(DM355_VIN_YIN_EN); | ||||
| 	davinci_cfg_reg(DM355_VIN_CINL_EN); | ||||
| 	davinci_cfg_reg(DM355_VIN_CINH_EN); | ||||
| } | ||||
| 
 | ||||
| static struct resource dm355_vpss_resources[] = { | ||||
| 	{ | ||||
| 		/* VPSS BL Base address */ | ||||
| @ -701,6 +711,10 @@ static struct resource vpfe_resources[] = { | ||||
| 		.end            = IRQ_VDINT1, | ||||
| 		.flags          = IORESOURCE_IRQ, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| static u64 vpfe_capture_dma_mask = DMA_BIT_MASK(32); | ||||
| static struct resource dm355_ccdc_resource[] = { | ||||
| 	/* CCDC Base address */ | ||||
| 	{ | ||||
| 		.flags          = IORESOURCE_MEM, | ||||
| @ -708,8 +722,18 @@ static struct resource vpfe_resources[] = { | ||||
| 		.end            = 0x01c70600 + 0x1ff, | ||||
| 	}, | ||||
| }; | ||||
| static struct platform_device dm355_ccdc_dev = { | ||||
| 	.name           = "dm355_ccdc", | ||||
| 	.id             = -1, | ||||
| 	.num_resources  = ARRAY_SIZE(dm355_ccdc_resource), | ||||
| 	.resource       = dm355_ccdc_resource, | ||||
| 	.dev = { | ||||
| 		.dma_mask               = &vpfe_capture_dma_mask, | ||||
| 		.coherent_dma_mask      = DMA_BIT_MASK(32), | ||||
| 		.platform_data		= dm355_ccdc_setup_pinmux, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| static u64 vpfe_capture_dma_mask = DMA_BIT_MASK(32); | ||||
| static struct platform_device vpfe_capture_dev = { | ||||
| 	.name		= CAPTURE_DRV_NAME, | ||||
| 	.id		= -1, | ||||
| @ -857,20 +881,13 @@ static int __init dm355_init_devices(void) | ||||
| 	if (!cpu_is_davinci_dm355()) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	/* Add ccdc clock aliases */ | ||||
| 	clk_add_alias("master", dm355_ccdc_dev.name, "vpss_master", NULL); | ||||
| 	clk_add_alias("slave", dm355_ccdc_dev.name, "vpss_master", NULL); | ||||
| 	davinci_cfg_reg(DM355_INT_EDMA_CC); | ||||
| 	platform_device_register(&dm355_edma_device); | ||||
| 	platform_device_register(&dm355_vpss_device); | ||||
| 	/*
 | ||||
| 	 * setup Mux configuration for vpfe input and register | ||||
| 	 * vpfe capture platform device | ||||
| 	 */ | ||||
| 	davinci_cfg_reg(DM355_VIN_PCLK); | ||||
| 	davinci_cfg_reg(DM355_VIN_CAM_WEN); | ||||
| 	davinci_cfg_reg(DM355_VIN_CAM_VD); | ||||
| 	davinci_cfg_reg(DM355_VIN_CAM_HD); | ||||
| 	davinci_cfg_reg(DM355_VIN_YIN_EN); | ||||
| 	davinci_cfg_reg(DM355_VIN_CINL_EN); | ||||
| 	davinci_cfg_reg(DM355_VIN_CINH_EN); | ||||
| 	platform_device_register(&dm355_ccdc_dev); | ||||
| 	platform_device_register(&vpfe_capture_dev); | ||||
| 
 | ||||
| 	return 0; | ||||
|  | ||||
| @ -1008,6 +1008,97 @@ void __init dm365_init(void) | ||||
| 	davinci_common_init(&davinci_soc_info_dm365); | ||||
| } | ||||
| 
 | ||||
| static struct resource dm365_vpss_resources[] = { | ||||
| 	{ | ||||
| 		/* VPSS ISP5 Base address */ | ||||
| 		.name           = "isp5", | ||||
| 		.start          = 0x01c70000, | ||||
| 		.end            = 0x01c70000 + 0xff, | ||||
| 		.flags          = IORESOURCE_MEM, | ||||
| 	}, | ||||
| 	{ | ||||
| 		/* VPSS CLK Base address */ | ||||
| 		.name           = "vpss", | ||||
| 		.start          = 0x01c70200, | ||||
| 		.end            = 0x01c70200 + 0xff, | ||||
| 		.flags          = IORESOURCE_MEM, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| static struct platform_device dm365_vpss_device = { | ||||
|        .name                   = "vpss", | ||||
|        .id                     = -1, | ||||
|        .dev.platform_data      = "dm365_vpss", | ||||
|        .num_resources          = ARRAY_SIZE(dm365_vpss_resources), | ||||
|        .resource               = dm365_vpss_resources, | ||||
| }; | ||||
| 
 | ||||
| static struct resource vpfe_resources[] = { | ||||
| 	{ | ||||
| 		.start          = IRQ_VDINT0, | ||||
| 		.end            = IRQ_VDINT0, | ||||
| 		.flags          = IORESOURCE_IRQ, | ||||
| 	}, | ||||
| 	{ | ||||
| 		.start          = IRQ_VDINT1, | ||||
| 		.end            = IRQ_VDINT1, | ||||
| 		.flags          = IORESOURCE_IRQ, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| static u64 vpfe_capture_dma_mask = DMA_BIT_MASK(32); | ||||
| static struct platform_device vpfe_capture_dev = { | ||||
| 	.name           = CAPTURE_DRV_NAME, | ||||
| 	.id             = -1, | ||||
| 	.num_resources  = ARRAY_SIZE(vpfe_resources), | ||||
| 	.resource       = vpfe_resources, | ||||
| 	.dev = { | ||||
| 		.dma_mask               = &vpfe_capture_dma_mask, | ||||
| 		.coherent_dma_mask      = DMA_BIT_MASK(32), | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| static void dm365_isif_setup_pinmux(void) | ||||
| { | ||||
| 	davinci_cfg_reg(DM365_VIN_CAM_WEN); | ||||
| 	davinci_cfg_reg(DM365_VIN_CAM_VD); | ||||
| 	davinci_cfg_reg(DM365_VIN_CAM_HD); | ||||
| 	davinci_cfg_reg(DM365_VIN_YIN4_7_EN); | ||||
| 	davinci_cfg_reg(DM365_VIN_YIN0_3_EN); | ||||
| } | ||||
| 
 | ||||
| static struct resource isif_resource[] = { | ||||
| 	/* ISIF Base address */ | ||||
| 	{ | ||||
| 		.start          = 0x01c71000, | ||||
| 		.end            = 0x01c71000 + 0x1ff, | ||||
| 		.flags          = IORESOURCE_MEM, | ||||
| 	}, | ||||
| 	/* ISIF Linearization table 0 */ | ||||
| 	{ | ||||
| 		.start          = 0x1C7C000, | ||||
| 		.end            = 0x1C7C000 + 0x2ff, | ||||
| 		.flags          = IORESOURCE_MEM, | ||||
| 	}, | ||||
| 	/* ISIF Linearization table 1 */ | ||||
| 	{ | ||||
| 		.start          = 0x1C7C400, | ||||
| 		.end            = 0x1C7C400 + 0x2ff, | ||||
| 		.flags          = IORESOURCE_MEM, | ||||
| 	}, | ||||
| }; | ||||
| static struct platform_device dm365_isif_dev = { | ||||
| 	.name           = "isif", | ||||
| 	.id             = -1, | ||||
| 	.num_resources  = ARRAY_SIZE(isif_resource), | ||||
| 	.resource       = isif_resource, | ||||
| 	.dev = { | ||||
| 		.dma_mask               = &vpfe_capture_dma_mask, | ||||
| 		.coherent_dma_mask      = DMA_BIT_MASK(32), | ||||
| 		.platform_data		= dm365_isif_setup_pinmux, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| static int __init dm365_init_devices(void) | ||||
| { | ||||
| 	if (!cpu_is_davinci_dm365()) | ||||
| @ -1016,7 +1107,16 @@ static int __init dm365_init_devices(void) | ||||
| 	davinci_cfg_reg(DM365_INT_EDMA_CC); | ||||
| 	platform_device_register(&dm365_edma_device); | ||||
| 	platform_device_register(&dm365_emac_device); | ||||
| 
 | ||||
| 	/* Add isif clock alias */ | ||||
| 	clk_add_alias("master", dm365_isif_dev.name, "vpss_master", NULL); | ||||
| 	platform_device_register(&dm365_vpss_device); | ||||
| 	platform_device_register(&dm365_isif_dev); | ||||
| 	platform_device_register(&vpfe_capture_dev); | ||||
| 	return 0; | ||||
| } | ||||
| postcore_initcall(dm365_init_devices); | ||||
| 
 | ||||
| void dm365_set_vpfe_config(struct vpfe_config *cfg) | ||||
| { | ||||
|        vpfe_capture_dev.dev.platform_data = cfg; | ||||
| } | ||||
|  | ||||
| @ -612,6 +612,11 @@ static struct resource vpfe_resources[] = { | ||||
| 		.end            = IRQ_VDINT1, | ||||
| 		.flags          = IORESOURCE_IRQ, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| static u64 vpfe_capture_dma_mask = DMA_BIT_MASK(32); | ||||
| static struct resource dm644x_ccdc_resource[] = { | ||||
| 	/* CCDC Base address */ | ||||
| 	{ | ||||
| 		.start          = 0x01c70400, | ||||
| 		.end            = 0x01c70400 + 0xff, | ||||
| @ -619,7 +624,17 @@ static struct resource vpfe_resources[] = { | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| static u64 vpfe_capture_dma_mask = DMA_BIT_MASK(32); | ||||
| static struct platform_device dm644x_ccdc_dev = { | ||||
| 	.name           = "dm644x_ccdc", | ||||
| 	.id             = -1, | ||||
| 	.num_resources  = ARRAY_SIZE(dm644x_ccdc_resource), | ||||
| 	.resource       = dm644x_ccdc_resource, | ||||
| 	.dev = { | ||||
| 		.dma_mask               = &vpfe_capture_dma_mask, | ||||
| 		.coherent_dma_mask      = DMA_BIT_MASK(32), | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| static struct platform_device vpfe_capture_dev = { | ||||
| 	.name		= CAPTURE_DRV_NAME, | ||||
| 	.id		= -1, | ||||
| @ -769,9 +784,13 @@ static int __init dm644x_init_devices(void) | ||||
| 	if (!cpu_is_davinci_dm644x()) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	/* Add ccdc clock aliases */ | ||||
| 	clk_add_alias("master", dm644x_ccdc_dev.name, "vpss_master", NULL); | ||||
| 	clk_add_alias("slave", dm644x_ccdc_dev.name, "vpss_slave", NULL); | ||||
| 	platform_device_register(&dm644x_edma_device); | ||||
| 	platform_device_register(&dm644x_emac_device); | ||||
| 	platform_device_register(&dm644x_vpss_device); | ||||
| 	platform_device_register(&dm644x_ccdc_dev); | ||||
| 	platform_device_register(&vpfe_capture_dev); | ||||
| 
 | ||||
| 	return 0; | ||||
|  | ||||
| @ -18,6 +18,7 @@ | ||||
| #include <mach/emac.h> | ||||
| #include <mach/asp.h> | ||||
| #include <mach/keyscan.h> | ||||
| #include <media/davinci/vpfe_capture.h> | ||||
| 
 | ||||
| #define DM365_EMAC_BASE			(0x01D07000) | ||||
| #define DM365_EMAC_CNTRL_OFFSET		(0x0000) | ||||
| @ -36,4 +37,5 @@ void __init dm365_init_asp(struct snd_platform_data *pdata); | ||||
| void __init dm365_init_ks(struct davinci_ks_platform_data *pdata); | ||||
| void __init dm365_init_rtc(void); | ||||
| 
 | ||||
| void dm365_set_vpfe_config(struct vpfe_config *cfg); | ||||
| #endif /* __ASM_ARCH_DM365_H */ | ||||
|  | ||||
| @ -86,7 +86,7 @@ static int gpio_set_irq_type(unsigned int irq, unsigned int type) | ||||
| 	unsigned int reg_both, reg_level, reg_type; | ||||
| 
 | ||||
| 	reg_type = __raw_readl(base + GPIO_INT_TYPE); | ||||
| 	reg_level = __raw_readl(base + GPIO_INT_BOTH_EDGE); | ||||
| 	reg_level = __raw_readl(base + GPIO_INT_LEVEL); | ||||
| 	reg_both = __raw_readl(base + GPIO_INT_BOTH_EDGE); | ||||
| 
 | ||||
| 	switch (type) { | ||||
| @ -117,7 +117,7 @@ static int gpio_set_irq_type(unsigned int irq, unsigned int type) | ||||
| 	} | ||||
| 
 | ||||
| 	__raw_writel(reg_type, base + GPIO_INT_TYPE); | ||||
| 	__raw_writel(reg_level, base + GPIO_INT_BOTH_EDGE); | ||||
| 	__raw_writel(reg_level, base + GPIO_INT_LEVEL); | ||||
| 	__raw_writel(reg_both, base + GPIO_INT_BOTH_EDGE); | ||||
| 
 | ||||
| 	gpio_ack_irq(irq); | ||||
|  | ||||
| @ -86,11 +86,19 @@ static struct amba_device cpu8815_amba_gpio[] = { | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| static struct amba_device cpu8815_amba_rng = { | ||||
| 	.dev = { | ||||
| 		.init_name = "rng", | ||||
| 	}, | ||||
| 	__MEM_4K_RESOURCE(NOMADIK_RNG_BASE), | ||||
| }; | ||||
| 
 | ||||
| static struct amba_device *amba_devs[] __initdata = { | ||||
| 	cpu8815_amba_gpio + 0, | ||||
| 	cpu8815_amba_gpio + 1, | ||||
| 	cpu8815_amba_gpio + 2, | ||||
| 	cpu8815_amba_gpio + 3, | ||||
| 	&cpu8815_amba_rng | ||||
| }; | ||||
| 
 | ||||
| static int __init cpu8815_init(void) | ||||
|  | ||||
| @ -961,16 +961,14 @@ static void __init omap_mux_init_list(struct omap_mux *superset) | ||||
| 	while (superset->reg_offset !=  OMAP_MUX_TERMINATOR) { | ||||
| 		struct omap_mux *entry; | ||||
| 
 | ||||
| #ifndef CONFIG_OMAP_MUX | ||||
| 		/* Skip pins that are not muxed as GPIO by bootloader */ | ||||
| 		if (!OMAP_MODE_GPIO(omap_mux_read(superset->reg_offset))) { | ||||
| #ifdef CONFIG_OMAP_MUX | ||||
| 		if (!superset->muxnames || !superset->muxnames[0]) { | ||||
| 			superset++; | ||||
| 			continue; | ||||
| 		} | ||||
| #endif | ||||
| 
 | ||||
| #if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS) | ||||
| 		if (!superset->muxnames || !superset->muxnames[0]) { | ||||
| #else | ||||
| 		/* Skip pins that are not muxed as GPIO by bootloader */ | ||||
| 		if (!OMAP_MODE_GPIO(omap_mux_read(superset->reg_offset))) { | ||||
| 			superset++; | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| @ -35,8 +35,6 @@ | ||||
| #define PXA_CAMERA_VSP		0x400 | ||||
| 
 | ||||
| struct pxacamera_platform_data { | ||||
| 	int (*init)(struct device *); | ||||
| 
 | ||||
| 	unsigned long flags; | ||||
| 	unsigned long mclk_10khz; | ||||
| }; | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
|  * it under the terms of the GNU General Public License version 2 as | ||||
|  * published by the Free Software Foundation. | ||||
|  */ | ||||
| #include <linux/moduleparam.h> | ||||
| #include <linux/compiler.h> | ||||
| #include <linux/kernel.h> | ||||
| #include <linux/errno.h> | ||||
| @ -77,6 +78,8 @@ static unsigned long ai_dword; | ||||
| static unsigned long ai_multi; | ||||
| static int ai_usermode; | ||||
| 
 | ||||
| core_param(alignment, ai_usermode, int, 0600); | ||||
| 
 | ||||
| #define UM_WARN		(1 << 0) | ||||
| #define UM_FIXUP	(1 << 1) | ||||
| #define UM_SIGNAL	(1 << 2) | ||||
|  | ||||
| @ -12,7 +12,7 @@ | ||||
| # | ||||
| #   http://www.arm.linux.org.uk/developer/machines/?action=new | ||||
| # | ||||
| # Last update: Thu Jan 28 22:15:54 2010 | ||||
| # Last update: Sat Feb 20 14:16:15 2010 | ||||
| # | ||||
| # machine_is_xxx	CONFIG_xxxx		MACH_TYPE_xxx		number | ||||
| # | ||||
| @ -2257,7 +2257,7 @@ oratisalog		MACH_ORATISALOG		ORATISALOG		2268 | ||||
| oratismadi		MACH_ORATISMADI		ORATISMADI		2269 | ||||
| oratisot16		MACH_ORATISOT16		ORATISOT16		2270 | ||||
| oratisdesk		MACH_ORATISDESK		ORATISDESK		2271 | ||||
| v2_ca9			MACH_V2P_CA9		V2P_CA9			2272 | ||||
| vexpress		MACH_VEXPRESS		VEXPRESS		2272 | ||||
| sintexo			MACH_SINTEXO		SINTEXO			2273 | ||||
| cm3389			MACH_CM3389		CM3389			2274 | ||||
| omap3_cio		MACH_OMAP3_CIO		OMAP3_CIO		2275 | ||||
| @ -2636,3 +2636,45 @@ hw90240			MACH_HW90240		HW90240			2648 | ||||
| dm365_leopard		MACH_DM365_LEOPARD	DM365_LEOPARD		2649 | ||||
| mityomapl138		MACH_MITYOMAPL138	MITYOMAPL138		2650 | ||||
| scat110			MACH_SCAT110		SCAT110			2651 | ||||
| acer_a1			MACH_ACER_A1		ACER_A1			2652 | ||||
| cmcontrol		MACH_CMCONTROL		CMCONTROL		2653 | ||||
| pelco_lamar		MACH_PELCO_LAMAR	PELCO_LAMAR		2654 | ||||
| rfp43			MACH_RFP43		RFP43			2655 | ||||
| sk86r0301		MACH_SK86R0301		SK86R0301		2656 | ||||
| ctpxa			MACH_CTPXA		CTPXA			2657 | ||||
| epb_arm9_a		MACH_EPB_ARM9_A		EPB_ARM9_A		2658 | ||||
| guruplug		MACH_GURUPLUG		GURUPLUG		2659 | ||||
| spear310		MACH_SPEAR310		SPEAR310		2660 | ||||
| spear320		MACH_SPEAR320		SPEAR320		2661 | ||||
| robotx			MACH_ROBOTX		ROBOTX			2662 | ||||
| lsxhl			MACH_LSXHL		LSXHL			2663 | ||||
| smartlite		MACH_SMARTLITE		SMARTLITE		2664 | ||||
| cws2			MACH_CWS2		CWS2			2665 | ||||
| m619			MACH_M619		M619			2666 | ||||
| smartview		MACH_SMARTVIEW		SMARTVIEW		2667 | ||||
| lsa_salsa		MACH_LSA_SALSA		LSA_SALSA		2668 | ||||
| kizbox			MACH_KIZBOX		KIZBOX			2669 | ||||
| htccharmer		MACH_HTCCHARMER		HTCCHARMER		2670 | ||||
| guf_neso_lt		MACH_GUF_NESO_LT	GUF_NESO_LT		2671 | ||||
| pm9g45			MACH_PM9G45		PM9G45			2672 | ||||
| htcpanther		MACH_HTCPANTHER		HTCPANTHER		2673 | ||||
| htcpanther_cdma		MACH_HTCPANTHER_CDMA	HTCPANTHER_CDMA		2674 | ||||
| reb01			MACH_REB01		REB01			2675 | ||||
| aquila			MACH_AQUILA		AQUILA			2676 | ||||
| spark_sls_hw2		MACH_SPARK_SLS_HW2	SPARK_SLS_HW2		2677 | ||||
| sheeva_esata		MACH_ESATA_SHEEVAPLUG	ESATA_SHEEVAPLUG	2678 | ||||
| surf7x30		MACH_SURF7X30		SURF7X30		2679 | ||||
| micro2440		MACH_MICRO2440		MICRO2440		2680 | ||||
| am2440			MACH_AM2440		AM2440			2681 | ||||
| tq2440			MACH_TQ2440		TQ2440			2682 | ||||
| lpc2478oem		MACH_LPC2478OEM		LPC2478OEM		2683 | ||||
| ak880x			MACH_AK880X		AK880X			2684 | ||||
| cobra3530		MACH_COBRA3530		COBRA3530		2685 | ||||
| pmppb			MACH_PMPPB		PMPPB			2686 | ||||
| u6715			MACH_U6715		U6715			2687 | ||||
| axar1500_sender		MACH_AXAR1500_SENDER	AXAR1500_SENDER		2688 | ||||
| g30_dvb			MACH_G30_DVB		G30_DVB			2689 | ||||
| vc088x			MACH_VC088X		VC088X			2690 | ||||
| mioa702			MACH_MIOA702		MIOA702			2691 | ||||
| hpmin			MACH_HPMIN		HPMIN			2692 | ||||
| ak880xak		MACH_AK880XAK		AK880XAK		2693 | ||||
|  | ||||
| @ -41,18 +41,16 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| void | ||||
| pcibios_align_resource(void *data, struct resource *res, | ||||
| resource_size_t | ||||
| pcibios_align_resource(void *data, const struct resource *res, | ||||
| 		       resource_size_t size, resource_size_t align) | ||||
| { | ||||
| 	if (res->flags & IORESOURCE_IO) { | ||||
| 		resource_size_t start = res->start; | ||||
| 	resource_size_t start = res->start; | ||||
| 
 | ||||
| 		if (start & 0x300) { | ||||
| 			start = (start + 0x3ff) & ~0x3ff; | ||||
| 			res->start = start; | ||||
| 		} | ||||
| 	} | ||||
| 	if ((res->flags & IORESOURCE_IO) && (start & 0x300)) | ||||
| 		start = (start + 0x3ff) & ~0x3ff; | ||||
| 
 | ||||
| 	return start | ||||
| } | ||||
| 
 | ||||
| int pcibios_enable_resources(struct pci_dev *dev, int mask) | ||||
|  | ||||
| @ -32,18 +32,16 @@ | ||||
|  * but we want to try to avoid allocating at 0x2900-0x2bff | ||||
|  * which might have be mirrored at 0x0100-0x03ff.. | ||||
|  */ | ||||
| void | ||||
| pcibios_align_resource(void *data, struct resource *res, | ||||
| resource_size_t | ||||
| pcibios_align_resource(void *data, const struct resource *res, | ||||
| 		       resource_size_t size, resource_size_t align) | ||||
| { | ||||
| 	if (res->flags & IORESOURCE_IO) { | ||||
| 		resource_size_t start = res->start; | ||||
| 	resource_size_t start = res->start; | ||||
| 
 | ||||
| 		if (start & 0x300) { | ||||
| 			start = (start + 0x3ff) & ~0x3ff; | ||||
| 			res->start = start; | ||||
| 		} | ||||
| 	} | ||||
| 	if ((res->flags & IORESOURCE_IO) && (start & 0x300)) | ||||
| 		start = (start + 0x3ff) & ~0x3ff; | ||||
| 
 | ||||
| 	return start | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -44,8 +44,8 @@ void cache_push_v (unsigned long vaddr, int len) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| /* Map some physical address range into the kernel address space. The
 | ||||
|  * code is copied and adapted from map_chunk(). | ||||
| /*
 | ||||
|  * Map some physical address range into the kernel address space. | ||||
|  */ | ||||
| 
 | ||||
| unsigned long kernel_map(unsigned long paddr, unsigned long size, | ||||
|  | ||||
| @ -94,9 +94,11 @@ ia64_acpi_release_global_lock (unsigned int *lock) | ||||
| #define acpi_noirq 0	/* ACPI always enabled on IA64 */ | ||||
| #define acpi_pci_disabled 0 /* ACPI PCI always enabled on IA64 */ | ||||
| #define acpi_strict 1	/* no ACPI spec workarounds on IA64 */ | ||||
| #define acpi_ht 0	/* no HT-only mode on IA64 */ | ||||
| #endif | ||||
| #define acpi_processor_cstate_check(x) (x) /* no idle limits on IA64 :) */ | ||||
| static inline void disable_acpi(void) { } | ||||
| static inline void pci_acpi_crs_quirks(void) { } | ||||
| 
 | ||||
| const char *acpi_get_sysname (void); | ||||
| int acpi_request_vector (u32 int_type); | ||||
|  | ||||
| @ -870,7 +870,7 @@ static int __kprobes pre_kprobes_handler(struct die_args *args) | ||||
| 		return 1; | ||||
| 
 | ||||
| ss_probe: | ||||
| #if !defined(CONFIG_PREEMPT) || defined(CONFIG_FREEZER) | ||||
| #if !defined(CONFIG_PREEMPT) | ||||
| 	if (p->ainsn.inst_flag == INST_FLAG_BOOSTABLE && !p->post_handler) { | ||||
| 		/* Boost up -- we can execute copied instructions directly */ | ||||
| 		ia64_psr(regs)->ri = p->ainsn.slot; | ||||
|  | ||||
| @ -320,9 +320,9 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data) | ||||
| static void __devinit | ||||
| pcibios_setup_root_windows(struct pci_bus *bus, struct pci_controller *ctrl) | ||||
| { | ||||
| 	int i, j; | ||||
| 	int i; | ||||
| 
 | ||||
| 	j = 0; | ||||
| 	pci_bus_remove_resources(bus); | ||||
| 	for (i = 0; i < ctrl->windows; i++) { | ||||
| 		struct resource *res = &ctrl->window[i].resource; | ||||
| 		/* HP's firmware has a hack to work around a Windows bug.
 | ||||
| @ -330,13 +330,7 @@ pcibios_setup_root_windows(struct pci_bus *bus, struct pci_controller *ctrl) | ||||
| 		if ((res->flags & IORESOURCE_MEM) && | ||||
| 		    (res->end - res->start < 16)) | ||||
| 			continue; | ||||
| 		if (j >= PCI_BUS_NUM_RESOURCES) { | ||||
| 			dev_warn(&bus->dev, | ||||
| 				 "ignoring host bridge window %pR (no space)\n", | ||||
| 				 res); | ||||
| 			continue; | ||||
| 		} | ||||
| 		bus->resource[j++] = res; | ||||
| 		pci_bus_add_resource(bus, res, 0); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -452,13 +446,12 @@ EXPORT_SYMBOL(pcibios_bus_to_resource); | ||||
| static int __devinit is_valid_resource(struct pci_dev *dev, int idx) | ||||
| { | ||||
| 	unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM; | ||||
| 	struct resource *devr = &dev->resource[idx]; | ||||
| 	struct resource *devr = &dev->resource[idx], *busr; | ||||
| 
 | ||||
| 	if (!dev->bus) | ||||
| 		return 0; | ||||
| 	for (i=0; i<PCI_BUS_NUM_RESOURCES; i++) { | ||||
| 		struct resource *busr = dev->bus->resource[i]; | ||||
| 
 | ||||
| 	pci_bus_for_each_resource(dev->bus, busr, i) { | ||||
| 		if (!busr || ((busr->flags ^ devr->flags) & type_mask)) | ||||
| 			continue; | ||||
| 		if ((devr->start) && (devr->start >= busr->start) && | ||||
| @ -547,10 +540,11 @@ pcibios_disable_device (struct pci_dev *dev) | ||||
| 		acpi_pci_irq_disable(dev); | ||||
| } | ||||
| 
 | ||||
| void | ||||
| pcibios_align_resource (void *data, struct resource *res, | ||||
| resource_size_t | ||||
| pcibios_align_resource (void *data, const struct resource *res, | ||||
| 		        resource_size_t size, resource_size_t align) | ||||
| { | ||||
| 	return res->start; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  | ||||
| @ -71,7 +71,7 @@ EXPORT_SYMBOL(sn_rtc_cycles_per_second); | ||||
| DEFINE_PER_CPU(struct sn_hub_info_s, __sn_hub_info); | ||||
| EXPORT_PER_CPU_SYMBOL(__sn_hub_info); | ||||
| 
 | ||||
| DEFINE_PER_CPU(short [MAX_COMPACT_NODES], __sn_cnodeid_to_nasid); | ||||
| DEFINE_PER_CPU(short, __sn_cnodeid_to_nasid[MAX_COMPACT_NODES]); | ||||
| EXPORT_PER_CPU_SYMBOL(__sn_cnodeid_to_nasid); | ||||
| 
 | ||||
| DEFINE_PER_CPU(struct nodepda_s *, __sn_nodepda); | ||||
|  | ||||
| @ -536,10 +536,6 @@ config GVPIOEXT_PLIP | ||||
| 	  Say Y to enable doing IP over the parallel port on your GVP | ||||
| 	  IO-Extender card, N otherwise. | ||||
| 
 | ||||
| config MAC_SCC | ||||
| 	tristate "Macintosh serial support" | ||||
| 	depends on MAC | ||||
| 
 | ||||
| config MAC_HID | ||||
| 	bool | ||||
| 	depends on INPUT_ADBHID | ||||
| @ -595,7 +591,7 @@ config DN_SERIAL | ||||
| 
 | ||||
| config SERIAL_CONSOLE | ||||
| 	bool "Support for serial port console" | ||||
| 	depends on (AMIGA || ATARI || MAC || SUN3 || SUN3X || VME || APOLLO) && (ATARI_MFPSER=y || ATARI_MIDI=y || MAC_SCC=y || AMIGA_BUILTIN_SERIAL=y || GVPIOEXT=y || MULTIFACE_III_TTY=y || SERIAL=y || MVME147_SCC || SERIAL167 || MVME162_SCC || BVME6000_SCC || DN_SERIAL) | ||||
| 	depends on (AMIGA || ATARI || SUN3 || SUN3X || VME || APOLLO) && (ATARI_MFPSER=y || ATARI_MIDI=y || AMIGA_BUILTIN_SERIAL=y || GVPIOEXT=y || MULTIFACE_III_TTY=y || SERIAL=y || MVME147_SCC || SERIAL167 || MVME162_SCC || BVME6000_SCC || DN_SERIAL) | ||||
| 	---help--- | ||||
| 	  If you say Y here, it will be possible to use a serial port as the | ||||
| 	  system console (the system console is the device which receives all | ||||
|  | ||||
| @ -480,7 +480,7 @@ static void __init amiga_sched_init(irq_handler_t timer_routine) | ||||
| 	static struct resource sched_res = { | ||||
| 		.name = "timer", .start = 0x00bfd400, .end = 0x00bfd5ff, | ||||
| 	}; | ||||
| 	jiffy_ticks = (amiga_eclock+HZ/2)/HZ; | ||||
| 	jiffy_ticks = DIV_ROUND_CLOSEST(amiga_eclock, HZ); | ||||
| 
 | ||||
| 	if (request_resource(&mb_resources._ciab, &sched_res)) | ||||
| 		printk("Cannot allocate ciab.ta{lo,hi}\n"); | ||||
|  | ||||
| @ -701,6 +701,11 @@ CONFIG_VT_HW_CONSOLE_BINDING=y | ||||
| # | ||||
| # Non-8250 serial port support | ||||
| # | ||||
| CONFIG_SERIAL_CORE=y | ||||
| CONFIG_SERIAL_CORE_CONSOLE=y | ||||
| CONFIG_SERIAL_PMACZILOG=y | ||||
| CONFIG_SERIAL_PMACZILOG_TTYS=y | ||||
| CONFIG_SERIAL_PMACZILOG_CONSOLE=y | ||||
| CONFIG_UNIX98_PTYS=y | ||||
| # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set | ||||
| CONFIG_LEGACY_PTYS=y | ||||
| @ -834,9 +839,7 @@ CONFIG_HIDRAW=y | ||||
| # | ||||
| # Character devices | ||||
| # | ||||
| CONFIG_MAC_SCC=y | ||||
| CONFIG_MAC_HID=y | ||||
| CONFIG_SERIAL_CONSOLE=y | ||||
| 
 | ||||
| # | ||||
| # File systems | ||||
|  | ||||
| @ -822,6 +822,11 @@ CONFIG_A2232=y | ||||
| # | ||||
| # Non-8250 serial port support | ||||
| # | ||||
| CONFIG_SERIAL_CORE=y | ||||
| CONFIG_SERIAL_CORE_CONSOLE=y | ||||
| CONFIG_SERIAL_PMACZILOG=y | ||||
| CONFIG_SERIAL_PMACZILOG_TTYS=y | ||||
| CONFIG_SERIAL_PMACZILOG_CONSOLE=y | ||||
| CONFIG_UNIX98_PTYS=y | ||||
| # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set | ||||
| CONFIG_LEGACY_PTYS=y | ||||
| @ -982,7 +987,6 @@ CONFIG_ATARI_MIDI=y | ||||
| CONFIG_ATARI_DSP56K=m | ||||
| CONFIG_AMIGA_BUILTIN_SERIAL=y | ||||
| CONFIG_MULTIFACE_III_TTY=m | ||||
| CONFIG_MAC_SCC=y | ||||
| CONFIG_MAC_HID=y | ||||
| CONFIG_MVME147_SCC=y | ||||
| CONFIG_SERIAL167=y | ||||
|  | ||||
| @ -21,29 +21,4 @@ | ||||
| #define VIDEOMEMSIZE	(4096*1024) | ||||
| #define VIDEOMEMMASK	(-4096*1024) | ||||
| 
 | ||||
| #ifndef __ASSEMBLY__ | ||||
| 
 | ||||
| #include <linux/types.h> | ||||
| 
 | ||||
| #if 0 | ||||
| /*
 | ||||
| ** SCC Z8530 | ||||
| */ | ||||
| 
 | ||||
| #define MAC_SCC_BAS (0x50F04000) | ||||
| struct MAC_SCC | ||||
|  { | ||||
|   u_char cha_a_ctrl; | ||||
|   u_char char_dummy1; | ||||
|   u_char cha_a_data; | ||||
|   u_char char_dummy2; | ||||
|   u_char cha_b_ctrl; | ||||
|   u_char char_dummy3; | ||||
|   u_char cha_b_data; | ||||
|  }; | ||||
| # define mac_scc ((*(volatile struct SCC*)MAC_SCC_BAS)) | ||||
| #endif | ||||
| 
 | ||||
| #endif /* __ASSEMBLY__ */ | ||||
| 
 | ||||
| #endif /* linux/machw.h */ | ||||
|  | ||||
| @ -37,7 +37,6 @@ | ||||
| 
 | ||||
| #define VIA1_SOURCE_BASE	8 | ||||
| #define VIA2_SOURCE_BASE	16 | ||||
| #define MAC_SCC_SOURCE_BASE	24 | ||||
| #define PSC3_SOURCE_BASE	24 | ||||
| #define PSC4_SOURCE_BASE	32 | ||||
| #define PSC5_SOURCE_BASE	40 | ||||
| @ -96,26 +95,12 @@ | ||||
| #define IRQ_PSC3_2	  (26) | ||||
| #define IRQ_PSC3_3	  (27) | ||||
| 
 | ||||
| /* Level 4 (SCC) interrupts */ | ||||
| #define IRQ_SCC		     (32) | ||||
| #define IRQ_SCCA	     (33) | ||||
| #define IRQ_SCCB	     (34) | ||||
| #if 0 /* FIXME: are there multiple interrupt conditions on the SCC ?? */
 | ||||
| /* SCC interrupts */ | ||||
| #define IRQ_SCCB_TX	     (32) | ||||
| #define IRQ_SCCB_STAT	     (33) | ||||
| #define IRQ_SCCB_RX	     (34) | ||||
| #define IRQ_SCCB_SPCOND	     (35) | ||||
| #define IRQ_SCCA_TX	     (36) | ||||
| #define IRQ_SCCA_STAT	     (37) | ||||
| #define IRQ_SCCA_RX	     (38) | ||||
| #define IRQ_SCCA_SPCOND	     (39) | ||||
| #endif | ||||
| 
 | ||||
| /* Level 4 (PSC, AV Macs only) interrupts */ | ||||
| #define IRQ_PSC4_0	  (32) | ||||
| #define IRQ_PSC4_1	  (33) | ||||
| #define IRQ_MAC_SCC_A	  IRQ_PSC4_1 | ||||
| #define IRQ_PSC4_2	  (34) | ||||
| #define IRQ_MAC_SCC_B	  IRQ_PSC4_2 | ||||
| #define IRQ_PSC4_3	  (35) | ||||
| #define IRQ_MAC_MACE_DMA  IRQ_PSC4_3 | ||||
| 
 | ||||
| @ -146,6 +131,9 @@ | ||||
| #define IRQ_BABOON_2	  (66) | ||||
| #define IRQ_BABOON_3	  (67) | ||||
| 
 | ||||
| /* On non-PSC machines, the serial ports share an IRQ */ | ||||
| #define IRQ_MAC_SCC	  IRQ_AUTO_4 | ||||
| 
 | ||||
| #define SLOT2IRQ(x)	  (x + 47) | ||||
| #define IRQ2SLOT(x)	  (x - 47) | ||||
| 
 | ||||
|  | ||||
| @ -71,6 +71,8 @@ struct switch_stack { | ||||
| #define PTRACE_GETFPREGS          14 | ||||
| #define PTRACE_SETFPREGS          15 | ||||
| 
 | ||||
| #define PTRACE_GET_THREAD_AREA    25 | ||||
| 
 | ||||
| #define PTRACE_SINGLEBLOCK	33	/* resume execution until next branch */ | ||||
| 
 | ||||
| #ifdef __KERNEL__ | ||||
|  | ||||
| @ -15,9 +15,15 @@ struct sigcontext { | ||||
| 	unsigned long  sc_pc; | ||||
| 	unsigned short sc_formatvec; | ||||
| #ifndef __uClinux__ | ||||
| # ifdef __mcoldfire__ | ||||
| 	unsigned long  sc_fpregs[2][2];	/* room for two fp registers */ | ||||
| 	unsigned long  sc_fpcntl[3]; | ||||
| 	unsigned char  sc_fpstate[16+6*8]; | ||||
| # else | ||||
| 	unsigned long  sc_fpregs[2*3];  /* room for two fp registers */ | ||||
| 	unsigned long  sc_fpcntl[3]; | ||||
| 	unsigned char  sc_fpstate[216]; | ||||
| # endif | ||||
| #endif | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -1,97 +1,6 @@ | ||||
| #ifndef _M68K_SIGINFO_H | ||||
| #define _M68K_SIGINFO_H | ||||
| 
 | ||||
| #ifndef __uClinux__ | ||||
| #define HAVE_ARCH_SIGINFO_T | ||||
| #define HAVE_ARCH_COPY_SIGINFO | ||||
| #endif | ||||
| 
 | ||||
| #include <asm-generic/siginfo.h> | ||||
| 
 | ||||
| #ifndef __uClinux__ | ||||
| 
 | ||||
| typedef struct siginfo { | ||||
| 	int si_signo; | ||||
| 	int si_errno; | ||||
| 	int si_code; | ||||
| 
 | ||||
| 	union { | ||||
| 		int _pad[SI_PAD_SIZE]; | ||||
| 
 | ||||
| 		/* kill() */ | ||||
| 		struct { | ||||
| 			__kernel_pid_t _pid;	/* sender's pid */ | ||||
| 			__kernel_uid_t _uid;	/* backwards compatibility */ | ||||
| 			__kernel_uid32_t _uid32; /* sender's uid */ | ||||
| 		} _kill; | ||||
| 
 | ||||
| 		/* POSIX.1b timers */ | ||||
| 		struct { | ||||
| 			timer_t _tid;		/* timer id */ | ||||
| 			int _overrun;		/* overrun count */ | ||||
| 			char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)]; | ||||
| 			sigval_t _sigval;	/* same as below */ | ||||
| 			int _sys_private;       /* not to be passed to user */ | ||||
| 		} _timer; | ||||
| 
 | ||||
| 		/* POSIX.1b signals */ | ||||
| 		struct { | ||||
| 			__kernel_pid_t _pid;	/* sender's pid */ | ||||
| 			__kernel_uid_t _uid;	/* backwards compatibility */ | ||||
| 			sigval_t _sigval; | ||||
| 			__kernel_uid32_t _uid32; /* sender's uid */ | ||||
| 		} _rt; | ||||
| 
 | ||||
| 		/* SIGCHLD */ | ||||
| 		struct { | ||||
| 			__kernel_pid_t _pid;	/* which child */ | ||||
| 			__kernel_uid_t _uid;	/* backwards compatibility */ | ||||
| 			int _status;		/* exit code */ | ||||
| 			clock_t _utime; | ||||
| 			clock_t _stime; | ||||
| 			__kernel_uid32_t _uid32; /* sender's uid */ | ||||
| 		} _sigchld; | ||||
| 
 | ||||
| 		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | ||||
| 		struct { | ||||
| 			void *_addr; /* faulting insn/memory ref. */ | ||||
| 		} _sigfault; | ||||
| 
 | ||||
| 		/* SIGPOLL */ | ||||
| 		struct { | ||||
| 			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */ | ||||
| 			int _fd; | ||||
| 		} _sigpoll; | ||||
| 	} _sifields; | ||||
| } siginfo_t; | ||||
| 
 | ||||
| #define UID16_SIGINFO_COMPAT_NEEDED | ||||
| 
 | ||||
| /*
 | ||||
|  * How these fields are to be accessed. | ||||
|  */ | ||||
| #undef si_uid | ||||
| #ifdef __KERNEL__ | ||||
| #define si_uid		_sifields._kill._uid32 | ||||
| #define si_uid16	_sifields._kill._uid | ||||
| #else | ||||
| #define si_uid		_sifields._kill._uid | ||||
| #endif | ||||
| 
 | ||||
| #ifdef __KERNEL__ | ||||
| 
 | ||||
| #include <linux/string.h> | ||||
| 
 | ||||
| static inline void copy_siginfo(struct siginfo *to, struct siginfo *from) | ||||
| { | ||||
| 	if (from->si_code < 0) | ||||
| 		memcpy(to, from, sizeof(*to)); | ||||
| 	else | ||||
| 		/* _sigchld is currently the largest know union member */ | ||||
| 		memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld)); | ||||
| } | ||||
| 
 | ||||
| #endif /* __KERNEL__ */ | ||||
| #endif /* !__uClinux__ */ | ||||
| 
 | ||||
| #endif | ||||
|  | ||||
| @ -14,7 +14,7 @@ static inline __attribute_const__ __u32 __arch_swab32(__u32 val) | ||||
| } | ||||
| 
 | ||||
| #define __arch_swab32 __arch_swab32 | ||||
| #elif !defined(__uClinux__) | ||||
| #elif !defined(__mcoldfire__) | ||||
| 
 | ||||
| static inline __attribute_const__ __u32 __arch_swab32(__u32 val) | ||||
| { | ||||
|  | ||||
| @ -16,6 +16,7 @@ struct thread_info { | ||||
| 	struct exec_domain	*exec_domain;	/* execution domain */ | ||||
| 	int			preempt_count;	/* 0 => preemptable, <0 => BUG */ | ||||
| 	__u32 cpu; /* should always be 0 on m68k */ | ||||
| 	unsigned long		tp_value;	/* thread pointer */ | ||||
| 	struct restart_block    restart_block; | ||||
| }; | ||||
| #endif /* __ASSEMBLY__ */ | ||||
|  | ||||
| @ -37,6 +37,7 @@ struct thread_info { | ||||
| 	unsigned long	   flags;		/* low level flags */ | ||||
| 	int		   cpu;			/* cpu we're on */ | ||||
| 	int		   preempt_count;	/* 0 => preemptable, <0 => BUG */ | ||||
| 	unsigned long	   tp_value;		/* thread pointer */ | ||||
| 	struct restart_block restart_block; | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -7,7 +7,11 @@ typedef greg_t gregset_t[NGREG]; | ||||
| 
 | ||||
| typedef struct fpregset { | ||||
| 	int f_fpcntl[3]; | ||||
| #ifdef __mcoldfire__ | ||||
| 	int f_fpregs[8][2]; | ||||
| #else | ||||
| 	int f_fpregs[8*3]; | ||||
| #endif | ||||
| } fpregset_t; | ||||
| 
 | ||||
| struct mcontext { | ||||
|  | ||||
| @ -336,10 +336,14 @@ | ||||
| #define __NR_pwritev		330 | ||||
| #define __NR_rt_tgsigqueueinfo	331 | ||||
| #define __NR_perf_event_open	332 | ||||
| #define __NR_get_thread_area	333 | ||||
| #define __NR_set_thread_area	334 | ||||
| #define __NR_atomic_cmpxchg_32	335 | ||||
| #define __NR_atomic_barrier	336 | ||||
| 
 | ||||
| #ifdef __KERNEL__ | ||||
| 
 | ||||
| #define NR_syscalls		333 | ||||
| #define NR_syscalls		337 | ||||
| 
 | ||||
| #define __ARCH_WANT_IPC_PARSE_VERSION | ||||
| #define __ARCH_WANT_OLD_READDIR | ||||
|  | ||||
| @ -31,12 +31,7 @@ static inline void *phys_to_virt(unsigned long address) | ||||
| #define page_to_phys(page) \ | ||||
| 	__pa(PAGE_OFFSET + (((page) - pg_data_map[0].node_mem_map) << PAGE_SHIFT)) | ||||
| #else | ||||
| #define page_to_phys(_page) ({						\ | ||||
| 	struct page *__page = _page;					\ | ||||
| 	struct pglist_data *pgdat;					\ | ||||
| 	pgdat = pg_data_table[page_to_nid(__page)];			\ | ||||
| 	page_to_pfn(__page) << PAGE_SHIFT;				\ | ||||
| }) | ||||
| #define page_to_phys(page)	(page_to_pfn(page) << PAGE_SHIFT) | ||||
| #endif | ||||
| #else | ||||
| #define page_to_phys(page)	(((page) - mem_map) << PAGE_SHIFT) | ||||
|  | ||||
| @ -761,4 +761,8 @@ sys_call_table: | ||||
| 	.long sys_pwritev		/* 330 */ | ||||
| 	.long sys_rt_tgsigqueueinfo
 | ||||
| 	.long sys_perf_event_open
 | ||||
| 	.long sys_get_thread_area
 | ||||
| 	.long sys_set_thread_area
 | ||||
| 	.long sys_atomic_cmpxchg_32	/* 335 */ | ||||
| 	.long sys_atomic_barrier
 | ||||
| 
 | ||||
|  | ||||
| @ -251,6 +251,10 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | ||||
| 
 | ||||
| 	p->thread.usp = usp; | ||||
| 	p->thread.ksp = (unsigned long)childstack; | ||||
| 
 | ||||
| 	if (clone_flags & CLONE_SETTLS) | ||||
| 		task_thread_info(p)->tp_value = regs->d5; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Must save the current SFC/DFC value, NOT the value when | ||||
| 	 * the parent was last descheduled - RGH  10-08-96 | ||||
|  | ||||
| @ -245,6 +245,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | ||||
| 			ret = -EFAULT; | ||||
| 		break; | ||||
| 
 | ||||
| 	case PTRACE_GET_THREAD_AREA: | ||||
| 		ret = put_user(task_thread_info(child)->tp_value, | ||||
| 			       (unsigned long __user *)data); | ||||
| 		break; | ||||
| 
 | ||||
| 	default: | ||||
| 		ret = ptrace_request(child, request, addr, data); | ||||
| 		break; | ||||
|  | ||||
| @ -897,10 +897,17 @@ static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, | ||||
| 
 | ||||
| 	/* Set up to return from userspace.  */ | ||||
| 	err |= __put_user(frame->retcode, &frame->pretcode); | ||||
| #ifdef __mcoldfire__ | ||||
| 	/* movel #__NR_rt_sigreturn,d0; trap #0 */ | ||||
| 	err |= __put_user(0x203c0000, (long __user *)(frame->retcode + 0)); | ||||
| 	err |= __put_user(0x00004e40 + (__NR_rt_sigreturn << 16), | ||||
| 			  (long __user *)(frame->retcode + 4)); | ||||
| #else | ||||
| 	/* moveq #,d0; notb d0; trap #0 */ | ||||
| 	err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16), | ||||
| 			  (long __user *)(frame->retcode + 0)); | ||||
| 	err |= __put_user(0x4e40, (short __user *)(frame->retcode + 4)); | ||||
| #endif | ||||
| 
 | ||||
| 	if (err) | ||||
| 		goto give_sigsegv; | ||||
|  | ||||
| @ -28,6 +28,11 @@ | ||||
| #include <asm/traps.h> | ||||
| #include <asm/page.h> | ||||
| #include <asm/unistd.h> | ||||
| #include <linux/elf.h> | ||||
| #include <asm/tlb.h> | ||||
| 
 | ||||
| asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address, | ||||
| 			     unsigned long error_code); | ||||
| 
 | ||||
| asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, | ||||
| 	unsigned long prot, unsigned long flags, | ||||
| @ -595,3 +600,79 @@ int kernel_execve(const char *filename, char *const argv[], char *const envp[]) | ||||
| 			: "d" (__a), "d" (__b), "d" (__c)); | ||||
| 	return __res; | ||||
| } | ||||
| 
 | ||||
| asmlinkage unsigned long sys_get_thread_area(void) | ||||
| { | ||||
| 	return current_thread_info()->tp_value; | ||||
| } | ||||
| 
 | ||||
| asmlinkage int sys_set_thread_area(unsigned long tp) | ||||
| { | ||||
| 	current_thread_info()->tp_value = tp; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /* This syscall gets its arguments in A0 (mem), D2 (oldval) and
 | ||||
|    D1 (newval).  */ | ||||
| asmlinkage int | ||||
| sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5, | ||||
| 		      unsigned long __user * mem) | ||||
| { | ||||
| 	/* This was borrowed from ARM's implementation.  */ | ||||
| 	for (;;) { | ||||
| 		struct mm_struct *mm = current->mm; | ||||
| 		pgd_t *pgd; | ||||
| 		pmd_t *pmd; | ||||
| 		pte_t *pte; | ||||
| 		spinlock_t *ptl; | ||||
| 		unsigned long mem_value; | ||||
| 
 | ||||
| 		down_read(&mm->mmap_sem); | ||||
| 		pgd = pgd_offset(mm, (unsigned long)mem); | ||||
| 		if (!pgd_present(*pgd)) | ||||
| 			goto bad_access; | ||||
| 		pmd = pmd_offset(pgd, (unsigned long)mem); | ||||
| 		if (!pmd_present(*pmd)) | ||||
| 			goto bad_access; | ||||
| 		pte = pte_offset_map_lock(mm, pmd, (unsigned long)mem, &ptl); | ||||
| 		if (!pte_present(*pte) || !pte_dirty(*pte) | ||||
| 		    || !pte_write(*pte)) { | ||||
| 			pte_unmap_unlock(pte, ptl); | ||||
| 			goto bad_access; | ||||
| 		} | ||||
| 
 | ||||
| 		mem_value = *mem; | ||||
| 		if (mem_value == oldval) | ||||
| 			*mem = newval; | ||||
| 
 | ||||
| 		pte_unmap_unlock(pte, ptl); | ||||
| 		up_read(&mm->mmap_sem); | ||||
| 		return mem_value; | ||||
| 
 | ||||
| 	      bad_access: | ||||
| 		up_read(&mm->mmap_sem); | ||||
| 		/* This is not necessarily a bad access, we can get here if
 | ||||
| 		   a memory we're trying to write to should be copied-on-write. | ||||
| 		   Make the kernel do the necessary page stuff, then re-iterate. | ||||
| 		   Simulate a write access fault to do that.  */ | ||||
| 		{ | ||||
| 			/* The first argument of the function corresponds to
 | ||||
| 			   D1, which is the first field of struct pt_regs.  */ | ||||
| 			struct pt_regs *fp = (struct pt_regs *)&newval; | ||||
| 
 | ||||
| 			/* '3' is an RMW flag.  */ | ||||
| 			if (do_page_fault(fp, (unsigned long)mem, 3)) | ||||
| 				/* If the do_page_fault() failed, we don't
 | ||||
| 				   have anything meaningful to return. | ||||
| 				   There should be a SIGSEGV pending for | ||||
| 				   the process.  */ | ||||
| 				return 0xdeadbeef; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| asmlinkage int sys_atomic_barrier(void) | ||||
| { | ||||
| 	/* no code needed for uniprocs */ | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @ -3,4 +3,4 @@ | ||||
| #
 | ||||
| 
 | ||||
| obj-y		:= config.o macints.o iop.o via.o oss.o psc.o \
 | ||||
| 			baboon.o macboing.o debug.o misc.o | ||||
| 			baboon.o macboing.o misc.o | ||||
|  | ||||
| @ -23,6 +23,8 @@ | ||||
| #include <linux/init.h> | ||||
| #include <linux/vt_kern.h> | ||||
| #include <linux/platform_device.h> | ||||
| #include <linux/adb.h> | ||||
| #include <linux/cuda.h> | ||||
| 
 | ||||
| #define BOOTINFO_COMPAT_1_0 | ||||
| #include <asm/setup.h> | ||||
| @ -44,12 +46,7 @@ | ||||
| #include <asm/mac_oss.h> | ||||
| #include <asm/mac_psc.h> | ||||
| 
 | ||||
| /* platform device info */ | ||||
| 
 | ||||
| #define SWIM_IO_SIZE 0x2000	/* SWIM IO resource size */ | ||||
| 
 | ||||
| /* Mac bootinfo struct */ | ||||
| 
 | ||||
| struct mac_booter_data mac_bi_data; | ||||
| 
 | ||||
| /* The phys. video addr. - might be bogus on some machines */ | ||||
| @ -70,8 +67,6 @@ extern void baboon_init(void); | ||||
| 
 | ||||
| extern void mac_mksound(unsigned int, unsigned int); | ||||
| 
 | ||||
| extern void nubus_sweep_video(void); | ||||
| 
 | ||||
| static void mac_get_model(char *str); | ||||
| static void mac_identify(void); | ||||
| static void mac_report_hardware(void); | ||||
| @ -167,12 +162,6 @@ void __init config_mac(void) | ||||
| 	mach_max_dma_address = 0xffffffff; | ||||
| #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE) | ||||
| 	mach_beep = mac_mksound; | ||||
| #endif | ||||
| #ifdef CONFIG_HEARTBEAT | ||||
| #if 0 | ||||
| 	mach_heartbeat = mac_heartbeat; | ||||
| 	mach_heartbeat_irq = IRQ_MAC_TIMER; | ||||
| #endif | ||||
| #endif | ||||
| 
 | ||||
| 	/*
 | ||||
| @ -191,27 +180,19 @@ void __init config_mac(void) | ||||
| 	if (macintosh_config->ident == MAC_MODEL_IICI | ||||
| 	    || macintosh_config->ident == MAC_MODEL_IIFX) | ||||
| 		mach_l2_flush = mac_cache_card_flush; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Check for machine specific fixups. | ||||
| 	 */ | ||||
| 
 | ||||
| #ifdef OLD_NUBUS_CODE | ||||
| 	nubus_sweep_video(); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /*
 | ||||
|  *	Macintosh Table: hardcoded model configuration data. | ||||
|  * Macintosh Table: hardcoded model configuration data. | ||||
|  * | ||||
|  *	Much of this was defined by Alan, based on who knows what docs. | ||||
|  *	I've added a lot more, and some of that was pure guesswork based | ||||
|  *	on hardware pages present on the Mac web site. Possibly wildly | ||||
|  *	inaccurate, so look here if a new Mac model won't run. Example: if | ||||
|  *	a Mac crashes immediately after the VIA1 registers have been dumped | ||||
|  *	to the screen, it probably died attempting to read DirB on a RBV. | ||||
|  *	Meaning it should have MAC_VIA_IIci here :-) | ||||
|  * Much of this was defined by Alan, based on who knows what docs. | ||||
|  * I've added a lot more, and some of that was pure guesswork based | ||||
|  * on hardware pages present on the Mac web site. Possibly wildly | ||||
|  * inaccurate, so look here if a new Mac model won't run. Example: if | ||||
|  * a Mac crashes immediately after the VIA1 registers have been dumped | ||||
|  * to the screen, it probably died attempting to read DirB on a RBV. | ||||
|  * Meaning it should have MAC_VIA_IIci here :-) | ||||
|  */ | ||||
| 
 | ||||
| struct mac_model *macintosh_config; | ||||
| @ -219,7 +200,7 @@ EXPORT_SYMBOL(macintosh_config); | ||||
| 
 | ||||
| static struct mac_model mac_data_table[] = { | ||||
| 	/*
 | ||||
| 	 *	We'll pretend to be a Macintosh II, that's pretty safe. | ||||
| 	 * We'll pretend to be a Macintosh II, that's pretty safe. | ||||
| 	 */ | ||||
| 
 | ||||
| 	{ | ||||
| @ -230,12 +211,11 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_II, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type	= MAC_FLOPPY_IWM | ||||
| 		.floppy_type	= MAC_FLOPPY_IWM, | ||||
| 	}, | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 *	Original MacII hardware | ||||
| 	 * | ||||
| 	 * Original Mac II hardware | ||||
| 	 */ | ||||
| 
 | ||||
| 	{ | ||||
| @ -246,7 +226,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_II, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type	= MAC_FLOPPY_IWM | ||||
| 		.floppy_type	= MAC_FLOPPY_IWM, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_IIX, | ||||
| 		.name		= "IIx", | ||||
| @ -255,7 +235,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_II, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_IICX, | ||||
| 		.name		= "IIcx", | ||||
| @ -264,7 +244,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_II, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_SE30, | ||||
| 		.name		= "SE/30", | ||||
| @ -273,13 +253,13 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_II, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 *	Weirdified MacII hardware - all subtly different. Gee thanks | ||||
| 	 *	Apple. All these boxes seem to have VIA2 in a different place to | ||||
| 	 *	the MacII (+1A000 rather than +4000) | ||||
| 	 * Weirdified Mac II hardware - all subtly different. Gee thanks | ||||
| 	 * Apple. All these boxes seem to have VIA2 in a different place to | ||||
| 	 * the Mac II (+1A000 rather than +4000) | ||||
| 	 * CSA: see http://developer.apple.com/technotes/hw/hw_09.html
 | ||||
| 	 */ | ||||
| 
 | ||||
| @ -291,7 +271,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_II, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_IIFX, | ||||
| 		.name		= "IIfx", | ||||
| @ -300,7 +280,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_IOP, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_IOP | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_IOP, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_IISI, | ||||
| 		.name		= "IIsi", | ||||
| @ -309,7 +289,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_II, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_IIVI, | ||||
| 		.name		= "IIvi", | ||||
| @ -318,7 +298,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_II, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_IIVX, | ||||
| 		.name		= "IIvx", | ||||
| @ -327,11 +307,11 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_II, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 *	Classic models (guessing: similar to SE/30 ?? Nope, similar to LC ...) | ||||
| 	 * Classic models (guessing: similar to SE/30? Nope, similar to LC...) | ||||
| 	 */ | ||||
| 
 | ||||
| 	{ | ||||
| @ -342,7 +322,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_II, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_CCL, | ||||
| 		.name		= "Color Classic", | ||||
| @ -351,11 +331,11 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_II, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 *	Some Mac LC machines. Basically the same as the IIci, ADB like IIsi | ||||
| 	 * Some Mac LC machines. Basically the same as the IIci, ADB like IIsi | ||||
| 	 */ | ||||
| 
 | ||||
| 	{ | ||||
| @ -366,7 +346,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_II, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_LCII, | ||||
| 		.name		= "LC II", | ||||
| @ -375,7 +355,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_II, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_LCIII, | ||||
| 		.name		= "LC III", | ||||
| @ -384,17 +364,17 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_II, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 *	Quadra. Video is at 0xF9000000, via is like a MacII. We label it differently | ||||
| 	 *	as some of the stuff connected to VIA2 seems different. Better SCSI chip and | ||||
| 	 *	onboard ethernet using a NatSemi SONIC except the 660AV and 840AV which use an | ||||
| 	 *	AMD 79C940 (MACE). | ||||
| 	 *	The 700, 900 and 950 have some I/O chips in the wrong place to | ||||
| 	 *	confuse us. The 840AV has a SCSI location of its own (same as | ||||
| 	 *	the 660AV). | ||||
| 	 * Quadra. Video is at 0xF9000000, via is like a MacII. We label it | ||||
| 	 * differently as some of the stuff connected to VIA2 seems different. | ||||
| 	 * Better SCSI chip and onboard ethernet using a NatSemi SONIC except | ||||
| 	 * the 660AV and 840AV which use an AMD 79C940 (MACE). | ||||
| 	 * The 700, 900 and 950 have some I/O chips in the wrong place to | ||||
| 	 * confuse us. The 840AV has a SCSI location of its own (same as | ||||
| 	 * the 660AV). | ||||
| 	 */ | ||||
| 
 | ||||
| 	{ | ||||
| @ -405,7 +385,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_QUADRA, | ||||
| 		.scc_type	= MAC_SCC_QUADRA, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_Q605_ACC, | ||||
| 		.name		= "Quadra 605", | ||||
| @ -414,7 +394,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_QUADRA, | ||||
| 		.scc_type	= MAC_SCC_QUADRA, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_Q610, | ||||
| 		.name		= "Quadra 610", | ||||
| @ -424,7 +404,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scc_type	= MAC_SCC_QUADRA, | ||||
| 		.ether_type	= MAC_ETHER_SONIC, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_Q630, | ||||
| 		.name		= "Quadra 630", | ||||
| @ -435,7 +415,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scc_type	= MAC_SCC_QUADRA, | ||||
| 		.ether_type	= MAC_ETHER_SONIC, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_Q650, | ||||
| 		.name		= "Quadra 650", | ||||
| @ -445,9 +425,9 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scc_type	= MAC_SCC_QUADRA, | ||||
| 		.ether_type	= MAC_ETHER_SONIC, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1, | ||||
| 	}, | ||||
| 	/*	The Q700 does have a NS Sonic */ | ||||
| 	/* The Q700 does have a NS Sonic */ | ||||
| 	{ | ||||
| 		.ident		= MAC_MODEL_Q700, | ||||
| 		.name		= "Quadra 700", | ||||
| @ -457,7 +437,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scc_type	= MAC_SCC_QUADRA, | ||||
| 		.ether_type	= MAC_ETHER_SONIC, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_Q800, | ||||
| 		.name		= "Quadra 800", | ||||
| @ -467,7 +447,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scc_type	= MAC_SCC_QUADRA, | ||||
| 		.ether_type	= MAC_ETHER_SONIC, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_Q840, | ||||
| 		.name		= "Quadra 840AV", | ||||
| @ -477,7 +457,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scc_type	= MAC_SCC_PSC, | ||||
| 		.ether_type	= MAC_ETHER_MACE, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_AV | ||||
| 		.floppy_type	= MAC_FLOPPY_AV, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_Q900, | ||||
| 		.name		= "Quadra 900", | ||||
| @ -487,7 +467,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scc_type	= MAC_SCC_IOP, | ||||
| 		.ether_type	= MAC_ETHER_SONIC, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_IOP | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_IOP, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_Q950, | ||||
| 		.name		= "Quadra 950", | ||||
| @ -497,60 +477,60 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scc_type	= MAC_SCC_IOP, | ||||
| 		.ether_type	= MAC_ETHER_SONIC, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_IOP | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_IOP, | ||||
| 	}, | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 *	Performa - more LC type machines | ||||
| 	 * Performa - more LC type machines | ||||
| 	 */ | ||||
| 
 | ||||
| 	{ | ||||
| 		.ident		= MAC_MODEL_P460, | ||||
| 		.name		=  "Performa 460", | ||||
| 		.name		= "Performa 460", | ||||
| 		.adb_type	= MAC_ADB_IISI, | ||||
| 		.via_type	= MAC_VIA_IIci, | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_II, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_P475, | ||||
| 		.name		=  "Performa 475", | ||||
| 		.name		= "Performa 475", | ||||
| 		.adb_type	= MAC_ADB_CUDA, | ||||
| 		.via_type	= MAC_VIA_QUADRA, | ||||
| 		.scsi_type	= MAC_SCSI_QUADRA, | ||||
| 		.scc_type	= MAC_SCC_II, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_P475F, | ||||
| 		.name		=  "Performa 475", | ||||
| 		.name		= "Performa 475", | ||||
| 		.adb_type	= MAC_ADB_CUDA, | ||||
| 		.via_type	= MAC_VIA_QUADRA, | ||||
| 		.scsi_type	= MAC_SCSI_QUADRA, | ||||
| 		.scc_type	= MAC_SCC_II, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_P520, | ||||
| 		.name		=  "Performa 520", | ||||
| 		.name		= "Performa 520", | ||||
| 		.adb_type	= MAC_ADB_CUDA, | ||||
| 		.via_type	= MAC_VIA_IIci, | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_II, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_P550, | ||||
| 		.name		=  "Performa 550", | ||||
| 		.name		= "Performa 550", | ||||
| 		.adb_type	= MAC_ADB_CUDA, | ||||
| 		.via_type	= MAC_VIA_IIci, | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_II, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, | ||||
| 	/* These have the comm slot, and therefore the possibility of SONIC ethernet */ | ||||
| 	/* These have the comm slot, and therefore possibly SONIC ethernet */ | ||||
| 	{ | ||||
| 		.ident		= MAC_MODEL_P575, | ||||
| 		.name		= "Performa 575", | ||||
| @ -560,7 +540,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scc_type	= MAC_SCC_II, | ||||
| 		.ether_type	= MAC_ETHER_SONIC, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_P588, | ||||
| 		.name		= "Performa 588", | ||||
| @ -571,7 +551,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scc_type	= MAC_SCC_II, | ||||
| 		.ether_type	= MAC_ETHER_SONIC, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_TV, | ||||
| 		.name		= "TV", | ||||
| @ -580,7 +560,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_II, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_P600, | ||||
| 		.name		= "Performa 600", | ||||
| @ -589,14 +569,14 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_II, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 *	Centris - just guessing again; maybe like Quadra | ||||
| 	 * Centris - just guessing again; maybe like Quadra. | ||||
| 	 * The C610 may or may not have SONIC. We probe to make sure. | ||||
| 	 */ | ||||
| 
 | ||||
| 	/* The C610 may or may not have SONIC.  We probe to make sure */ | ||||
| 	{ | ||||
| 		.ident		= MAC_MODEL_C610, | ||||
| 		.name		= "Centris 610", | ||||
| @ -606,7 +586,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scc_type	= MAC_SCC_QUADRA, | ||||
| 		.ether_type	= MAC_ETHER_SONIC, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR1 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_C650, | ||||
| 		.name		= "Centris 650", | ||||
| @ -616,7 +596,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scc_type	= MAC_SCC_QUADRA, | ||||
| 		.ether_type	= MAC_ETHER_SONIC, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR1 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_C660, | ||||
| 		.name		= "Centris 660AV", | ||||
| @ -626,7 +606,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scc_type	= MAC_SCC_PSC, | ||||
| 		.ether_type	= MAC_ETHER_MACE, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_AV | ||||
| 		.floppy_type	= MAC_FLOPPY_AV, | ||||
| 	}, | ||||
| 
 | ||||
| 	/*
 | ||||
| @ -643,7 +623,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_QUADRA, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_PB145, | ||||
| 		.name		= "PowerBook 145", | ||||
| @ -652,7 +632,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_QUADRA, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_PB150, | ||||
| 		.name		= "PowerBook 150", | ||||
| @ -662,7 +642,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.ide_type	= MAC_IDE_PB, | ||||
| 		.scc_type	= MAC_SCC_QUADRA, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_PB160, | ||||
| 		.name		= "PowerBook 160", | ||||
| @ -671,7 +651,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_QUADRA, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_PB165, | ||||
| 		.name		= "PowerBook 165", | ||||
| @ -680,7 +660,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_QUADRA, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_PB165C, | ||||
| 		.name		= "PowerBook 165c", | ||||
| @ -689,7 +669,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_QUADRA, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_PB170, | ||||
| 		.name		= "PowerBook 170", | ||||
| @ -698,7 +678,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_QUADRA, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_PB180, | ||||
| 		.name		= "PowerBook 180", | ||||
| @ -707,7 +687,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_QUADRA, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_PB180C, | ||||
| 		.name		= "PowerBook 180c", | ||||
| @ -716,7 +696,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_QUADRA, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_PB190, | ||||
| 		.name		= "PowerBook 190", | ||||
| @ -726,7 +706,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.ide_type	= MAC_IDE_BABOON, | ||||
| 		.scc_type	= MAC_SCC_QUADRA, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_PB520, | ||||
| 		.name		= "PowerBook 520", | ||||
| @ -736,7 +716,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scc_type	= MAC_SCC_QUADRA, | ||||
| 		.ether_type	= MAC_ETHER_SONIC, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, | ||||
| 
 | ||||
| 	/*
 | ||||
| @ -757,7 +737,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_QUADRA, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_PB230, | ||||
| 		.name		= "PowerBook Duo 230", | ||||
| @ -766,7 +746,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_QUADRA, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_PB250, | ||||
| 		.name		= "PowerBook Duo 250", | ||||
| @ -775,7 +755,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_QUADRA, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_PB270C, | ||||
| 		.name		= "PowerBook Duo 270c", | ||||
| @ -784,7 +764,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_QUADRA, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_PB280, | ||||
| 		.name		= "PowerBook Duo 280", | ||||
| @ -793,7 +773,7 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_QUADRA, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, { | ||||
| 		.ident		= MAC_MODEL_PB280C, | ||||
| 		.name		= "PowerBook Duo 280c", | ||||
| @ -802,17 +782,44 @@ static struct mac_model mac_data_table[] = { | ||||
| 		.scsi_type	= MAC_SCSI_OLD, | ||||
| 		.scc_type	= MAC_SCC_QUADRA, | ||||
| 		.nubus_type	= MAC_NUBUS, | ||||
| 		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2 | ||||
| 		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2, | ||||
| 	}, | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 *	Other stuff ?? | ||||
| 	 * Other stuff? | ||||
| 	 */ | ||||
| 
 | ||||
| 	{ | ||||
| 		.ident		= -1 | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| static struct resource scc_a_rsrcs[] = { | ||||
| 	{ .flags = IORESOURCE_MEM }, | ||||
| 	{ .flags = IORESOURCE_IRQ }, | ||||
| }; | ||||
| 
 | ||||
| static struct resource scc_b_rsrcs[] = { | ||||
| 	{ .flags = IORESOURCE_MEM }, | ||||
| 	{ .flags = IORESOURCE_IRQ }, | ||||
| }; | ||||
| 
 | ||||
| struct platform_device scc_a_pdev = { | ||||
| 	.name           = "scc", | ||||
| 	.id             = 0, | ||||
| 	.num_resources  = ARRAY_SIZE(scc_a_rsrcs), | ||||
| 	.resource       = scc_a_rsrcs, | ||||
| }; | ||||
| EXPORT_SYMBOL(scc_a_pdev); | ||||
| 
 | ||||
| struct platform_device scc_b_pdev = { | ||||
| 	.name           = "scc", | ||||
| 	.id             = 1, | ||||
| 	.num_resources  = ARRAY_SIZE(scc_b_rsrcs), | ||||
| 	.resource       = scc_b_rsrcs, | ||||
| }; | ||||
| EXPORT_SYMBOL(scc_b_pdev); | ||||
| 
 | ||||
| static void __init mac_identify(void) | ||||
| { | ||||
| 	struct mac_model *m; | ||||
| @ -823,7 +830,8 @@ static void __init mac_identify(void) | ||||
| 		/* no bootinfo model id -> NetBSD booter was used! */ | ||||
| 		/* XXX FIXME: breaks for model > 31 */ | ||||
| 		model = (mac_bi_data.cpuid >> 2) & 63; | ||||
| 		printk(KERN_WARNING "No bootinfo model ID, using cpuid instead (hey, use Penguin!)\n"); | ||||
| 		printk(KERN_WARNING "No bootinfo model ID, using cpuid instead " | ||||
| 		       "(obsolete bootloader?)\n"); | ||||
| 	} | ||||
| 
 | ||||
| 	macintosh_config = mac_data_table; | ||||
| @ -834,10 +842,29 @@ static void __init mac_identify(void) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/* We need to pre-init the IOPs, if any. Otherwise */ | ||||
| 	/* the serial console won't work if the user had   */ | ||||
| 	/* the serial ports set to "Faster" mode in MacOS. */ | ||||
| 	/* Set up serial port resources for the console initcall. */ | ||||
| 
 | ||||
| 	scc_a_rsrcs[0].start = (resource_size_t) mac_bi_data.sccbase + 2; | ||||
| 	scc_a_rsrcs[0].end   = scc_a_rsrcs[0].start; | ||||
| 	scc_b_rsrcs[0].start = (resource_size_t) mac_bi_data.sccbase; | ||||
| 	scc_b_rsrcs[0].end   = scc_b_rsrcs[0].start; | ||||
| 
 | ||||
| 	switch (macintosh_config->scc_type) { | ||||
| 	case MAC_SCC_PSC: | ||||
| 		scc_a_rsrcs[1].start = scc_a_rsrcs[1].end = IRQ_MAC_SCC_A; | ||||
| 		scc_b_rsrcs[1].start = scc_b_rsrcs[1].end = IRQ_MAC_SCC_B; | ||||
| 		break; | ||||
| 	default: | ||||
| 		scc_a_rsrcs[1].start = scc_a_rsrcs[1].end = IRQ_MAC_SCC; | ||||
| 		scc_b_rsrcs[1].start = scc_b_rsrcs[1].end = IRQ_MAC_SCC; | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * We need to pre-init the IOPs, if any. Otherwise | ||||
| 	 * the serial console won't work if the user had | ||||
| 	 * the serial ports set to "Faster" mode in MacOS. | ||||
| 	 */ | ||||
| 	iop_preinit(); | ||||
| 
 | ||||
| 	printk(KERN_INFO "Detected Macintosh model: %d \n", model); | ||||
| @ -846,7 +873,8 @@ static void __init mac_identify(void) | ||||
| 	 * Report booter data: | ||||
| 	 */ | ||||
| 	printk(KERN_DEBUG " Penguin bootinfo data:\n"); | ||||
| 	printk(KERN_DEBUG " Video: addr 0x%lx row 0x%lx depth %lx dimensions %ld x %ld\n", | ||||
| 	printk(KERN_DEBUG " Video: addr 0x%lx " | ||||
| 		"row 0x%lx depth %lx dimensions %ld x %ld\n", | ||||
| 		mac_bi_data.videoaddr, mac_bi_data.videorow, | ||||
| 		mac_bi_data.videodepth, mac_bi_data.dimensions & 0xFFFF, | ||||
| 		mac_bi_data.dimensions >> 16); | ||||
| @ -863,6 +891,10 @@ static void __init mac_identify(void) | ||||
| 	oss_init(); | ||||
| 	psc_init(); | ||||
| 	baboon_init(); | ||||
| 
 | ||||
| #ifdef CONFIG_ADB_CUDA | ||||
| 	find_via_cuda(); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| static void __init mac_report_hardware(void) | ||||
| @ -876,23 +908,50 @@ static void mac_get_model(char *str) | ||||
| 	strcat(str, macintosh_config->name); | ||||
| } | ||||
| 
 | ||||
| static struct resource swim_resources[1]; | ||||
| static struct resource swim_rsrc = { .flags = IORESOURCE_MEM }; | ||||
| 
 | ||||
| static struct platform_device swim_device = { | ||||
| static struct platform_device swim_pdev = { | ||||
| 	.name		= "swim", | ||||
| 	.id		= -1, | ||||
| 	.num_resources	= ARRAY_SIZE(swim_resources), | ||||
| 	.resource	= swim_resources, | ||||
| 	.num_resources	= 1, | ||||
| 	.resource	= &swim_rsrc, | ||||
| }; | ||||
| 
 | ||||
| static struct platform_device *mac_platform_devices[] __initdata = { | ||||
| 	&swim_device | ||||
| static struct platform_device esp_0_pdev = { | ||||
| 	.name		= "mac_esp", | ||||
| 	.id		= 0, | ||||
| }; | ||||
| 
 | ||||
| static struct platform_device esp_1_pdev = { | ||||
| 	.name		= "mac_esp", | ||||
| 	.id		= 1, | ||||
| }; | ||||
| 
 | ||||
| static struct platform_device sonic_pdev = { | ||||
| 	.name		= "macsonic", | ||||
| 	.id		= -1, | ||||
| }; | ||||
| 
 | ||||
| static struct platform_device mace_pdev = { | ||||
| 	.name		= "macmace", | ||||
| 	.id		= -1, | ||||
| }; | ||||
| 
 | ||||
| int __init mac_platform_init(void) | ||||
| { | ||||
| 	u8 *swim_base; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Serial devices | ||||
| 	 */ | ||||
| 
 | ||||
| 	platform_device_register(&scc_a_pdev); | ||||
| 	platform_device_register(&scc_b_pdev); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Floppy device | ||||
| 	 */ | ||||
| 
 | ||||
| 	switch (macintosh_config->floppy_type) { | ||||
| 	case MAC_FLOPPY_SWIM_ADDR1: | ||||
| 		swim_base = (u8 *)(VIA1_BASE + 0x1E000); | ||||
| @ -901,16 +960,47 @@ int __init mac_platform_init(void) | ||||
| 		swim_base = (u8 *)(VIA1_BASE + 0x16000); | ||||
| 		break; | ||||
| 	default: | ||||
| 		return 0; | ||||
| 		swim_base = NULL; | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	swim_resources[0].name = "swim-regs"; | ||||
| 	swim_resources[0].start = (resource_size_t)swim_base; | ||||
| 	swim_resources[0].end = (resource_size_t)(swim_base + SWIM_IO_SIZE); | ||||
| 	swim_resources[0].flags = IORESOURCE_MEM; | ||||
| 	if (swim_base) { | ||||
| 		swim_rsrc.start = (resource_size_t) swim_base, | ||||
| 		swim_rsrc.end   = (resource_size_t) swim_base + 0x2000, | ||||
| 		platform_device_register(&swim_pdev); | ||||
| 	} | ||||
| 
 | ||||
| 	return platform_add_devices(mac_platform_devices, | ||||
| 				    ARRAY_SIZE(mac_platform_devices)); | ||||
| 	/*
 | ||||
| 	 * SCSI device(s) | ||||
| 	 */ | ||||
| 
 | ||||
| 	switch (macintosh_config->scsi_type) { | ||||
| 	case MAC_SCSI_QUADRA: | ||||
| 	case MAC_SCSI_QUADRA3: | ||||
| 		platform_device_register(&esp_0_pdev); | ||||
| 		break; | ||||
| 	case MAC_SCSI_QUADRA2: | ||||
| 		platform_device_register(&esp_0_pdev); | ||||
| 		if ((macintosh_config->ident == MAC_MODEL_Q900) || | ||||
| 		    (macintosh_config->ident == MAC_MODEL_Q950)) | ||||
| 			platform_device_register(&esp_1_pdev); | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Ethernet device | ||||
| 	 */ | ||||
| 
 | ||||
| 	switch (macintosh_config->ether_type) { | ||||
| 	case MAC_ETHER_SONIC: | ||||
| 		platform_device_register(&sonic_pdev); | ||||
| 		break; | ||||
| 	case MAC_ETHER_MACE: | ||||
| 		platform_device_register(&mace_pdev); | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| arch_initcall(mac_platform_init); | ||||
|  | ||||
| @ -1,365 +0,0 @@ | ||||
| /*
 | ||||
|  * linux/arch/m68k/mac/debug.c | ||||
|  * | ||||
|  * Shamelessly stolen (SCC code and general framework) from: | ||||
|  * | ||||
|  * linux/arch/m68k/atari/debug.c | ||||
|  * | ||||
|  * Atari debugging and serial console stuff | ||||
|  * | ||||
|  * Assembled of parts of former atari/config.c 97-12-18 by Roman Hodek | ||||
|  * | ||||
|  * This file is subject to the terms and conditions of the GNU General Public | ||||
|  * License.  See the file COPYING in the main directory of this archive | ||||
|  * for more details. | ||||
|  */ | ||||
| 
 | ||||
| #include <linux/types.h> | ||||
| #include <linux/sched.h> | ||||
| #include <linux/tty.h> | ||||
| #include <linux/console.h> | ||||
| #include <linux/init.h> | ||||
| #include <linux/delay.h> | ||||
| 
 | ||||
| #define BOOTINFO_COMPAT_1_0 | ||||
| #include <asm/setup.h> | ||||
| #include <asm/bootinfo.h> | ||||
| #include <asm/macints.h> | ||||
| 
 | ||||
| extern unsigned long mac_videobase; | ||||
| extern unsigned long mac_rowbytes; | ||||
| 
 | ||||
| extern void mac_serial_print(const char *); | ||||
| 
 | ||||
| #define DEBUG_HEADS | ||||
| #undef DEBUG_SCREEN | ||||
| #define DEBUG_SERIAL | ||||
| 
 | ||||
| /*
 | ||||
|  * These two auxiliary debug functions should go away ASAP. Only usage: | ||||
|  * before the console output is up (after head.S come some other crucial | ||||
|  * setup routines :-) it permits writing 'data' to the screen as bit patterns | ||||
|  * (good luck reading those). Helped to figure that the bootinfo contained | ||||
|  * garbage data on the amount and size of memory chunks ... | ||||
|  * | ||||
|  * The 'pos' argument now simply means 'linefeed after print' ... | ||||
|  */ | ||||
| 
 | ||||
| #ifdef DEBUG_SCREEN | ||||
| static int peng, line; | ||||
| #endif | ||||
| 
 | ||||
| #if 0 | ||||
| 
 | ||||
| void mac_debugging_short(int pos, short num) | ||||
| { | ||||
| #ifdef DEBUG_SCREEN | ||||
| 	unsigned char *pengoffset; | ||||
| 	unsigned char *pptr; | ||||
| 	int i; | ||||
| #endif | ||||
| 
 | ||||
| #ifdef DEBUG_SERIAL | ||||
| 	printk("debug: %d !\n", num); | ||||
| #endif | ||||
| 
 | ||||
| #ifdef DEBUG_SCREEN | ||||
| 	if (!MACH_IS_MAC) { | ||||
| 		/* printk("debug: %d !\n", num); */ | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	/* calculate current offset */ | ||||
| 	pengoffset = (unsigned char *)mac_videobase + | ||||
| 		(150+line*2) * mac_rowbytes + 80 * peng; | ||||
| 
 | ||||
| 	pptr = pengoffset; | ||||
| 
 | ||||
| 	for (i = 0; i < 8 * sizeof(short); i++) { /* # of bits */ | ||||
| 		/*        value        mask for bit i, reverse order */ | ||||
| 		*pptr++ = (num & (1 << (8*sizeof(short)-i-1)) ? 0xFF : 0x00); | ||||
| 	} | ||||
| 
 | ||||
| 	peng++; | ||||
| 
 | ||||
| 	if (pos) { | ||||
| 		line++; | ||||
| 		peng = 0; | ||||
| 	} | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void mac_debugging_long(int pos, long addr) | ||||
| { | ||||
| #ifdef DEBUG_SCREEN | ||||
| 	unsigned char *pengoffset; | ||||
| 	unsigned char *pptr; | ||||
| 	int i; | ||||
| #endif | ||||
| 
 | ||||
| #ifdef DEBUG_SERIAL | ||||
| 	printk("debug: #%ld !\n", addr); | ||||
| #endif | ||||
| 
 | ||||
| #ifdef DEBUG_SCREEN | ||||
| 	if (!MACH_IS_MAC) { | ||||
| 		/* printk("debug: #%ld !\n", addr); */ | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	pengoffset=(unsigned char *)(mac_videobase+(150+line*2)*mac_rowbytes) | ||||
| 		    +80*peng; | ||||
| 
 | ||||
| 	pptr = pengoffset; | ||||
| 
 | ||||
| 	for (i = 0; i < 8 * sizeof(long); i++) { /* # of bits */ | ||||
| 		*pptr++ = (addr & (1 << (8*sizeof(long)-i-1)) ? 0xFF : 0x00); | ||||
| 	} | ||||
| 
 | ||||
| 	peng++; | ||||
| 
 | ||||
| 	if (pos) { | ||||
| 		line++; | ||||
| 		peng = 0; | ||||
| 	} | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| #endif  /*  0  */ | ||||
| 
 | ||||
| #ifdef DEBUG_SERIAL | ||||
| /*
 | ||||
|  * TODO: serial debug code | ||||
|  */ | ||||
| 
 | ||||
| struct mac_SCC { | ||||
| 	u_char cha_b_ctrl; | ||||
| 	u_char char_dummy1; | ||||
| 	u_char cha_a_ctrl; | ||||
| 	u_char char_dummy2; | ||||
| 	u_char cha_b_data; | ||||
| 	u_char char_dummy3; | ||||
| 	u_char cha_a_data; | ||||
| }; | ||||
| 
 | ||||
| # define scc (*((volatile struct mac_SCC*)mac_bi_data.sccbase)) | ||||
| 
 | ||||
| static int scc_port = -1; | ||||
| 
 | ||||
| static struct console mac_console_driver = { | ||||
| 	.name	= "debug", | ||||
| 	.flags	= CON_PRINTBUFFER, | ||||
| 	.index	= -1, | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * Crude hack to get console output to the screen before the framebuffer | ||||
|  * is initialized (happens a lot later in 2.1!). | ||||
|  * We just use the console routines declared in head.S, this will interfere | ||||
|  * with regular framebuffer console output and should be used exclusively | ||||
|  * to debug kernel problems manifesting before framebuffer init (aka WSOD) | ||||
|  * | ||||
|  * To keep this hack from interfering with the regular console driver, either | ||||
|  * deregister this driver before/on framebuffer console init, or silence this | ||||
|  * function after the fbcon driver is running (will lose console messages!?). | ||||
|  * To debug real early bugs, need to write a 'mac_register_console_hack()' | ||||
|  * that is called from start_kernel() before setup_arch() and just registers | ||||
|  * this driver if Mac. | ||||
|  */ | ||||
| 
 | ||||
| static void mac_debug_console_write(struct console *co, const char *str, | ||||
| 				    unsigned int count) | ||||
| { | ||||
| 	mac_serial_print(str); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /* Mac: loops_per_jiffy min. 19000 ^= .5 us; MFPDELAY was 0.6 us*/ | ||||
| 
 | ||||
| #define uSEC 1 | ||||
| 
 | ||||
| static inline void mac_sccb_out(char c) | ||||
| { | ||||
| 	int i; | ||||
| 
 | ||||
| 	do { | ||||
| 		for (i = uSEC; i > 0; --i) | ||||
| 			barrier(); | ||||
| 	} while (!(scc.cha_b_ctrl & 0x04)); /* wait for tx buf empty */ | ||||
| 	for (i = uSEC; i > 0; --i) | ||||
| 		barrier(); | ||||
| 	scc.cha_b_data = c; | ||||
| } | ||||
| 
 | ||||
| static inline void mac_scca_out(char c) | ||||
| { | ||||
| 	int i; | ||||
| 
 | ||||
| 	do { | ||||
| 		for (i = uSEC; i > 0; --i) | ||||
| 			barrier(); | ||||
| 	} while (!(scc.cha_a_ctrl & 0x04)); /* wait for tx buf empty */ | ||||
| 	for (i = uSEC; i > 0; --i) | ||||
| 		barrier(); | ||||
| 	scc.cha_a_data = c; | ||||
| } | ||||
| 
 | ||||
| static void mac_sccb_console_write(struct console *co, const char *str, | ||||
| 				   unsigned int count) | ||||
| { | ||||
| 	while (count--) { | ||||
| 		if (*str == '\n') | ||||
| 			mac_sccb_out('\r'); | ||||
| 		mac_sccb_out(*str++); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void mac_scca_console_write(struct console *co, const char *str, | ||||
| 				   unsigned int count) | ||||
| { | ||||
| 	while (count--) { | ||||
| 		if (*str == '\n') | ||||
| 			mac_scca_out('\r'); | ||||
| 		mac_scca_out(*str++); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* The following two functions do a quick'n'dirty initialization of the MFP or
 | ||||
|  * SCC serial ports. They're used by the debugging interface, kgdb, and the | ||||
|  * serial console code. */ | ||||
| #define SCCB_WRITE(reg,val)				\ | ||||
| 	do {						\ | ||||
| 		int i;					\ | ||||
| 		scc.cha_b_ctrl = (reg);			\ | ||||
| 		for (i = uSEC; i > 0; --i)		\ | ||||
| 			barrier();			\ | ||||
| 		scc.cha_b_ctrl = (val);			\ | ||||
| 		for (i = uSEC; i > 0; --i)		\ | ||||
| 			barrier();			\ | ||||
| 	} while(0) | ||||
| 
 | ||||
| #define SCCA_WRITE(reg,val)				\ | ||||
| 	do {						\ | ||||
| 		int i;					\ | ||||
| 		scc.cha_a_ctrl = (reg);			\ | ||||
| 		for (i = uSEC; i > 0; --i)		\ | ||||
| 			barrier();			\ | ||||
| 		scc.cha_a_ctrl = (val);			\ | ||||
| 		for (i = uSEC; i > 0; --i)		\ | ||||
| 			barrier();			\ | ||||
| 	} while(0) | ||||
| 
 | ||||
| /* loops_per_jiffy isn't initialized yet, so we can't use udelay(). This does a
 | ||||
|  * delay of ~ 60us. */ | ||||
| /* Mac: loops_per_jiffy min. 19000 ^= .5 us; MFPDELAY was 0.6 us*/ | ||||
| #define LONG_DELAY()					\ | ||||
| 	do {						\ | ||||
| 		int i;					\ | ||||
| 		for (i = 60*uSEC; i > 0; --i)		\ | ||||
| 		    barrier();				\ | ||||
| 	} while(0) | ||||
| 
 | ||||
| static void __init mac_init_scc_port(int cflag, int port) | ||||
| { | ||||
| 	/*
 | ||||
| 	 * baud rates: 1200, 1800, 2400, 4800, 9600, 19.2k, 38.4k, 57.6k, 115.2k | ||||
| 	 */ | ||||
| 
 | ||||
| 	static int clksrc_table[9] = | ||||
| 		/* reg 11: 0x50 = BRG, 0x00 = RTxC, 0x28 = TRxC */ | ||||
| 		{ 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x00, 0x00 }; | ||||
| 	static int clkmode_table[9] = | ||||
| 		/* reg 4: 0x40 = x16, 0x80 = x32, 0xc0 = x64 */ | ||||
| 		{ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xc0, 0x80 }; | ||||
| 	static int div_table[9] = | ||||
| 		/* reg12 (BRG low) */ | ||||
| 		{ 94, 62, 46, 22, 10, 4, 1, 0, 0 }; | ||||
| 
 | ||||
| 	int baud = cflag & CBAUD; | ||||
| 	int clksrc, clkmode, div, reg3, reg5; | ||||
| 
 | ||||
| 	if (cflag & CBAUDEX) | ||||
| 		baud += B38400; | ||||
| 	if (baud < B1200 || baud > B38400+2) | ||||
| 		baud = B9600; /* use default 9600bps for non-implemented rates */ | ||||
| 	baud -= B1200; /* tables starts at 1200bps */ | ||||
| 
 | ||||
| 	clksrc  = clksrc_table[baud]; | ||||
| 	clkmode = clkmode_table[baud]; | ||||
| 	div     = div_table[baud]; | ||||
| 
 | ||||
| 	reg3 = (((cflag & CSIZE) == CS8) ? 0xc0 : 0x40); | ||||
| 	reg5 = (((cflag & CSIZE) == CS8) ? 0x60 : 0x20) | 0x82 /* assert DTR/RTS */; | ||||
| 
 | ||||
| 	if (port == 1) { | ||||
| 		(void)scc.cha_b_ctrl;	/* reset reg pointer */ | ||||
| 		SCCB_WRITE(9, 0xc0);	/* reset */ | ||||
| 		LONG_DELAY();		/* extra delay after WR9 access */ | ||||
| 		SCCB_WRITE(4, (cflag & PARENB) ? ((cflag & PARODD) ? 0x01 : 0x03) : 0 | | ||||
| 			   0x04 /* 1 stopbit */ | | ||||
| 			   clkmode); | ||||
| 		SCCB_WRITE(3, reg3); | ||||
| 		SCCB_WRITE(5, reg5); | ||||
| 		SCCB_WRITE(9, 0);	/* no interrupts */ | ||||
| 		LONG_DELAY();		/* extra delay after WR9 access */ | ||||
| 		SCCB_WRITE(10, 0);	/* NRZ mode */ | ||||
| 		SCCB_WRITE(11, clksrc);	/* main clock source */ | ||||
| 		SCCB_WRITE(12, div);	/* BRG value */ | ||||
| 		SCCB_WRITE(13, 0);	/* BRG high byte */ | ||||
| 		SCCB_WRITE(14, 1); | ||||
| 		SCCB_WRITE(3, reg3 | 1); | ||||
| 		SCCB_WRITE(5, reg5 | 8); | ||||
| 	} else if (port == 0) { | ||||
| 		(void)scc.cha_a_ctrl;	/* reset reg pointer */ | ||||
| 		SCCA_WRITE(9, 0xc0);	/* reset */ | ||||
| 		LONG_DELAY();		/* extra delay after WR9 access */ | ||||
| 		SCCA_WRITE(4, (cflag & PARENB) ? ((cflag & PARODD) ? 0x01 : 0x03) : 0 | | ||||
| 			  0x04 /* 1 stopbit */ | | ||||
| 			  clkmode); | ||||
| 		SCCA_WRITE(3, reg3); | ||||
| 		SCCA_WRITE(5, reg5); | ||||
| 		SCCA_WRITE(9, 0);	/* no interrupts */ | ||||
| 		LONG_DELAY();		/* extra delay after WR9 access */ | ||||
| 		SCCA_WRITE(10, 0);	/* NRZ mode */ | ||||
| 		SCCA_WRITE(11, clksrc);	/* main clock source */ | ||||
| 		SCCA_WRITE(12, div);	/* BRG value */ | ||||
| 		SCCA_WRITE(13, 0);	/* BRG high byte */ | ||||
| 		SCCA_WRITE(14, 1); | ||||
| 		SCCA_WRITE(3, reg3 | 1); | ||||
| 		SCCA_WRITE(5, reg5 | 8); | ||||
| 	} | ||||
| } | ||||
| #endif /* DEBUG_SERIAL */ | ||||
| 
 | ||||
| static int __init mac_debug_setup(char *arg) | ||||
| { | ||||
| 	if (!MACH_IS_MAC) | ||||
| 		return 0; | ||||
| 
 | ||||
| #ifdef DEBUG_SERIAL | ||||
| 	if (!strcmp(arg, "ser") || !strcmp(arg, "ser1")) { | ||||
| 		/* Mac modem port */ | ||||
| 		mac_init_scc_port(B9600|CS8, 0); | ||||
| 		mac_console_driver.write = mac_scca_console_write; | ||||
| 		scc_port = 0; | ||||
| 	} else if (!strcmp(arg, "ser2")) { | ||||
| 		/* Mac printer port */ | ||||
| 		mac_init_scc_port(B9600|CS8, 1); | ||||
| 		mac_console_driver.write = mac_sccb_console_write; | ||||
| 		scc_port = 1; | ||||
| 	} | ||||
| #endif | ||||
| #ifdef DEBUG_HEADS | ||||
| 	if (!strcmp(arg, "scn") || !strcmp(arg, "con")) { | ||||
| 		/* display, using head.S console routines */ | ||||
| 		mac_console_driver.write = mac_debug_console_write; | ||||
| 	} | ||||
| #endif | ||||
| 	if (mac_console_driver.write) | ||||
| 		register_console(&mac_console_driver); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| early_param("debug", mac_debug_setup); | ||||
| @ -34,9 +34,7 @@ | ||||
|  * | ||||
|  *	3	- unused (?) | ||||
|  * | ||||
|  *	4	- SCC (slot number determined by reading RR3 on the SSC itself) | ||||
|  *		  - slot 1: SCC channel A | ||||
|  *		  - slot 2: SCC channel B | ||||
|  *	4	- SCC | ||||
|  * | ||||
|  *	5	- unused (?) | ||||
|  *		  [serial errors or special conditions seem to raise level 6 | ||||
| @ -55,8 +53,6 @@ | ||||
|  *		  - slot 5: Slot $E | ||||
|  * | ||||
|  *	4	- SCC IOP | ||||
|  *		  - slot 1: SCC channel A | ||||
|  *		  - slot 2: SCC channel B | ||||
|  * | ||||
|  *	5	- ISM IOP (ADB?) | ||||
|  * | ||||
| @ -136,13 +132,8 @@ | ||||
| #include <asm/irq_regs.h> | ||||
| #include <asm/mac_oss.h> | ||||
| 
 | ||||
| #define DEBUG_SPURIOUS | ||||
| #define SHUTUP_SONIC | ||||
| 
 | ||||
| /* SCC interrupt mask */ | ||||
| 
 | ||||
| static int scc_mask; | ||||
| 
 | ||||
| /*
 | ||||
|  * VIA/RBV hooks | ||||
|  */ | ||||
| @ -190,13 +181,6 @@ extern void baboon_irq_enable(int); | ||||
| extern void baboon_irq_disable(int); | ||||
| extern void baboon_irq_clear(int); | ||||
| 
 | ||||
| /*
 | ||||
|  * SCC interrupt routines | ||||
|  */ | ||||
| 
 | ||||
| static void scc_irq_enable(unsigned int); | ||||
| static void scc_irq_disable(unsigned int); | ||||
| 
 | ||||
| /*
 | ||||
|  * console_loglevel determines NMI handler function | ||||
|  */ | ||||
| @ -221,8 +205,6 @@ void __init mac_init_IRQ(void) | ||||
| #ifdef DEBUG_MACINTS | ||||
| 	printk("mac_init_IRQ(): Setting things up...\n"); | ||||
| #endif | ||||
| 	scc_mask = 0; | ||||
| 
 | ||||
| 	m68k_setup_irq_controller(&mac_irq_controller, IRQ_USER, | ||||
| 				  NUM_MAC_SOURCES - IRQ_USER); | ||||
| 	/* Make sure the SONIC interrupt is cleared or things get ugly */ | ||||
| @ -283,15 +265,16 @@ void mac_enable_irq(unsigned int irq) | ||||
| 			via_irq_enable(irq); | ||||
| 		break; | ||||
| 	case 3: | ||||
| 	case 4: | ||||
| 	case 5: | ||||
| 	case 6: | ||||
| 		if (psc_present) | ||||
| 			psc_irq_enable(irq); | ||||
| 		else if (oss_present) | ||||
| 			oss_irq_enable(irq); | ||||
| 		else if (irq_src == 4) | ||||
| 			scc_irq_enable(irq); | ||||
| 		break; | ||||
| 	case 4: | ||||
| 		if (psc_present) | ||||
| 			psc_irq_enable(irq); | ||||
| 		break; | ||||
| 	case 8: | ||||
| 		if (baboon_present) | ||||
| @ -316,15 +299,16 @@ void mac_disable_irq(unsigned int irq) | ||||
| 			via_irq_disable(irq); | ||||
| 		break; | ||||
| 	case 3: | ||||
| 	case 4: | ||||
| 	case 5: | ||||
| 	case 6: | ||||
| 		if (psc_present) | ||||
| 			psc_irq_disable(irq); | ||||
| 		else if (oss_present) | ||||
| 			oss_irq_disable(irq); | ||||
| 		else if (irq_src == 4) | ||||
| 			scc_irq_disable(irq); | ||||
| 		break; | ||||
| 	case 4: | ||||
| 		if (psc_present) | ||||
| 			psc_irq_disable(irq); | ||||
| 		break; | ||||
| 	case 8: | ||||
| 		if (baboon_present) | ||||
| @ -347,7 +331,6 @@ void mac_clear_irq(unsigned int irq) | ||||
| 			via_irq_clear(irq); | ||||
| 		break; | ||||
| 	case 3: | ||||
| 	case 4: | ||||
| 	case 5: | ||||
| 	case 6: | ||||
| 		if (psc_present) | ||||
| @ -355,6 +338,10 @@ void mac_clear_irq(unsigned int irq) | ||||
| 		else if (oss_present) | ||||
| 			oss_irq_clear(irq); | ||||
| 		break; | ||||
| 	case 4: | ||||
| 		if (psc_present) | ||||
| 			psc_irq_clear(irq); | ||||
| 		break; | ||||
| 	case 8: | ||||
| 		if (baboon_present) | ||||
| 			baboon_irq_clear(irq); | ||||
| @ -374,13 +361,17 @@ int mac_irq_pending(unsigned int irq) | ||||
| 		else | ||||
| 			return via_irq_pending(irq); | ||||
| 	case 3: | ||||
| 	case 4: | ||||
| 	case 5: | ||||
| 	case 6: | ||||
| 		if (psc_present) | ||||
| 			return psc_irq_pending(irq); | ||||
| 		else if (oss_present) | ||||
| 			return oss_irq_pending(irq); | ||||
| 		break; | ||||
| 	case 4: | ||||
| 		if (psc_present) | ||||
| 			psc_irq_pending(irq); | ||||
| 		break; | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
| @ -448,59 +439,3 @@ irqreturn_t mac_nmi_handler(int irq, void *dev_id) | ||||
| 	in_nmi--; | ||||
| 	return IRQ_HANDLED; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Simple routines for masking and unmasking | ||||
|  * SCC interrupts in cases where this can't be | ||||
|  * done in hardware (only the PSC can do that.) | ||||
|  */ | ||||
| 
 | ||||
| static void scc_irq_enable(unsigned int irq) | ||||
| { | ||||
| 	int irq_idx = IRQ_IDX(irq); | ||||
| 
 | ||||
| 	scc_mask |= (1 << irq_idx); | ||||
| } | ||||
| 
 | ||||
| static void scc_irq_disable(unsigned int irq) | ||||
| { | ||||
| 	int irq_idx = IRQ_IDX(irq); | ||||
| 
 | ||||
| 	scc_mask &= ~(1 << irq_idx); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * SCC master interrupt handler. We have to do a bit of magic here | ||||
|  * to figure out what channel gave us the interrupt; putting this | ||||
|  * here is cleaner than hacking it into drivers/char/macserial.c. | ||||
|  */ | ||||
| 
 | ||||
| void mac_scc_dispatch(int irq, void *dev_id) | ||||
| { | ||||
| 	volatile unsigned char *scc = (unsigned char *) mac_bi_data.sccbase + 2; | ||||
| 	unsigned char reg; | ||||
| 	unsigned long flags; | ||||
| 
 | ||||
| 	/* Read RR3 from the chip. Always do this on channel A */ | ||||
| 	/* This must be an atomic operation so disable irqs.   */ | ||||
| 
 | ||||
| 	local_irq_save(flags); | ||||
| 	*scc = 3; | ||||
| 	reg = *scc; | ||||
| 	local_irq_restore(flags); | ||||
| 
 | ||||
| 	/* Now dispatch. Bits 0-2 are for channel B and */ | ||||
| 	/* bits 3-5 are for channel A. We can safely    */ | ||||
| 	/* ignore the remaining bits here.              */ | ||||
| 	/*                                              */ | ||||
| 	/* Note that we're ignoring scc_mask for now.   */ | ||||
| 	/* If we actually mask the ints then we tend to */ | ||||
| 	/* get hammered by very persistent SCC irqs,    */ | ||||
| 	/* and since they're autovector interrupts they */ | ||||
| 	/* pretty much kill the system.                 */ | ||||
| 
 | ||||
| 	if (reg & 0x38) | ||||
| 		m68k_handle_int(IRQ_SCCA); | ||||
| 	if (reg & 0x07) | ||||
| 		m68k_handle_int(IRQ_SCCB); | ||||
| } | ||||
|  | ||||
| @ -33,7 +33,6 @@ static irqreturn_t oss_irq(int, void *); | ||||
| static irqreturn_t oss_nubus_irq(int, void *); | ||||
| 
 | ||||
| extern irqreturn_t via1_irq(int, void *); | ||||
| extern irqreturn_t mac_scc_dispatch(int, void *); | ||||
| 
 | ||||
| /*
 | ||||
|  * Initialize the OSS | ||||
| @ -69,9 +68,6 @@ void __init oss_register_interrupts(void) | ||||
| 	if (request_irq(OSS_IRQLEV_SCSI, oss_irq, IRQ_FLG_LOCK, | ||||
| 			"scsi", (void *) oss)) | ||||
| 		pr_err("Couldn't register %s interrupt\n", "scsi"); | ||||
| 	if (request_irq(OSS_IRQLEV_IOPSCC, mac_scc_dispatch, IRQ_FLG_LOCK, | ||||
| 			"scc", mac_scc_dispatch)) | ||||
| 		pr_err("Couldn't register %s interrupt\n", "scc"); | ||||
| 	if (request_irq(OSS_IRQLEV_NUBUS, oss_nubus_irq, IRQ_FLG_LOCK, | ||||
| 			"nubus", (void *) oss)) | ||||
| 		pr_err("Couldn't register %s interrupt\n", "nubus"); | ||||
| @ -172,9 +168,7 @@ void oss_irq_enable(int irq) { | ||||
| 	printk("oss_irq_enable(%d)\n", irq); | ||||
| #endif | ||||
| 	switch(irq) { | ||||
| 		case IRQ_SCC: | ||||
| 		case IRQ_SCCA: | ||||
| 		case IRQ_SCCB: | ||||
| 		case IRQ_MAC_SCC: | ||||
| 			oss->irq_level[OSS_IOPSCC] = OSS_IRQLEV_IOPSCC; | ||||
| 			break; | ||||
| 		case IRQ_MAC_ADB: | ||||
| @ -212,9 +206,7 @@ void oss_irq_disable(int irq) { | ||||
| 	printk("oss_irq_disable(%d)\n", irq); | ||||
| #endif | ||||
| 	switch(irq) { | ||||
| 		case IRQ_SCC: | ||||
| 		case IRQ_SCCA: | ||||
| 		case IRQ_SCCB: | ||||
| 		case IRQ_MAC_SCC: | ||||
| 			oss->irq_level[OSS_IOPSCC] = OSS_IRQLEV_DISABLED; | ||||
| 			break; | ||||
| 		case IRQ_MAC_ADB: | ||||
| @ -250,9 +242,7 @@ void oss_irq_disable(int irq) { | ||||
| void oss_irq_clear(int irq) { | ||||
| 	/* FIXME: how to do this on OSS? */ | ||||
| 	switch(irq) { | ||||
| 		case IRQ_SCC: | ||||
| 		case IRQ_SCCA: | ||||
| 		case IRQ_SCCB: | ||||
| 		case IRQ_MAC_SCC: | ||||
| 			oss->irq_pending &= ~OSS_IP_IOPSCC; | ||||
| 			break; | ||||
| 		case IRQ_MAC_ADB: | ||||
| @ -280,9 +270,7 @@ void oss_irq_clear(int irq) { | ||||
| int oss_irq_pending(int irq) | ||||
| { | ||||
| 	switch(irq) { | ||||
| 		case IRQ_SCC: | ||||
| 		case IRQ_SCCA: | ||||
| 		case IRQ_SCCB: | ||||
| 		case IRQ_MAC_SCC: | ||||
| 			return oss->irq_pending & OSS_IP_IOPSCC; | ||||
| 			break; | ||||
| 		case IRQ_MAC_ADB: | ||||
|  | ||||
| @ -84,8 +84,6 @@ void via_irq_enable(int irq); | ||||
| void via_irq_disable(int irq); | ||||
| void via_irq_clear(int irq); | ||||
| 
 | ||||
| extern irqreturn_t mac_scc_dispatch(int, void *); | ||||
| 
 | ||||
| /*
 | ||||
|  * Initialize the VIAs | ||||
|  * | ||||
| @ -311,11 +309,6 @@ void __init via_register_interrupts(void) | ||||
| 	if (request_irq(IRQ_AUTO_2, via2_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST, | ||||
| 			"via2", (void *) via2)) | ||||
| 		pr_err("Couldn't register %s interrupt\n", "via2"); | ||||
| 	if (!psc_present) { | ||||
| 		if (request_irq(IRQ_AUTO_4, mac_scc_dispatch, IRQ_FLG_LOCK, | ||||
| 				"scc", mac_scc_dispatch)) | ||||
| 			pr_err("Couldn't register %s interrupt\n", "scc"); | ||||
| 	} | ||||
| 	if (request_irq(IRQ_MAC_NUBUS, via_nubus_irq, | ||||
| 			IRQ_FLG_LOCK|IRQ_FLG_FAST, "nubus", (void *) via2)) | ||||
| 		pr_err("Couldn't register %s interrupt\n", "nubus"); | ||||
|  | ||||
| @ -99,8 +99,7 @@ static inline void free_io_area(void *addr) | ||||
| #endif | ||||
| 
 | ||||
| /*
 | ||||
|  * Map some physical address range into the kernel address space. The | ||||
|  * code is copied and adapted from map_chunk(). | ||||
|  * Map some physical address range into the kernel address space. | ||||
|  */ | ||||
| /* Rewritten by Andreas Schwab to remove all races. */ | ||||
| 
 | ||||
| @ -116,7 +115,7 @@ void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cachefla | ||||
| 	/*
 | ||||
| 	 * Don't allow mappings that wrap.. | ||||
| 	 */ | ||||
| 	if (!size || size > physaddr + size) | ||||
| 	if (!size || physaddr > (unsigned long)(-size)) | ||||
| 		return NULL; | ||||
| 
 | ||||
| #ifdef CONFIG_AMIGA | ||||
|  | ||||
| @ -221,6 +221,10 @@ int copy_thread(unsigned long clone_flags, | ||||
| 
 | ||||
| 	p->thread.usp = usp; | ||||
| 	p->thread.ksp = (unsigned long)childstack; | ||||
| 
 | ||||
| 	if (clone_flags & CLONE_SETTLS) | ||||
| 		task_thread_info(p)->tp_value = regs->d5; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Must save the current SFC/DFC value, NOT the value when | ||||
| 	 * the parent was last descheduled - RGH  10-08-96 | ||||
|  | ||||
| @ -319,6 +319,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | ||||
| 		} | ||||
| #endif | ||||
| 
 | ||||
| 	case PTRACE_GET_THREAD_AREA: | ||||
| 		ret = put_user(task_thread_info(child)->tp_value, | ||||
| 			       (unsigned long __user *)data); | ||||
| 		break; | ||||
| 
 | ||||
| 		default: | ||||
| 			ret = -EIO; | ||||
| 			break; | ||||
|  | ||||
| @ -190,3 +190,39 @@ int kernel_execve(const char *filename, char *const argv[], char *const envp[]) | ||||
| 			: "d" (__a), "d" (__b), "d" (__c)); | ||||
| 	return __res; | ||||
| } | ||||
| 
 | ||||
| asmlinkage unsigned long sys_get_thread_area(void) | ||||
| { | ||||
| 	return current_thread_info()->tp_value; | ||||
| } | ||||
| 
 | ||||
| asmlinkage int sys_set_thread_area(unsigned long tp) | ||||
| { | ||||
| 	current_thread_info()->tp_value = tp; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /* This syscall gets its arguments in A0 (mem), D2 (oldval) and
 | ||||
|    D1 (newval).  */ | ||||
| asmlinkage int | ||||
| sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5, | ||||
| 		      unsigned long __user * mem) | ||||
| { | ||||
| 	struct mm_struct *mm = current->mm; | ||||
| 	unsigned long mem_value; | ||||
| 
 | ||||
| 	down_read(&mm->mmap_sem); | ||||
| 
 | ||||
| 	mem_value = *mem; | ||||
| 	if (mem_value == oldval) | ||||
| 		*mem = newval; | ||||
| 
 | ||||
| 	up_read(&mm->mmap_sem); | ||||
| 	return mem_value; | ||||
| } | ||||
| 
 | ||||
| asmlinkage int sys_atomic_barrier(void) | ||||
| { | ||||
| 	/* no code needed for uniprocs */ | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @ -351,6 +351,10 @@ ENTRY(sys_call_table) | ||||
| 	.long sys_pwritev		/* 330 */ | ||||
| 	.long sys_rt_tgsigqueueinfo
 | ||||
| 	.long sys_perf_event_open
 | ||||
| 	.long sys_get_thread_area
 | ||||
| 	.long sys_set_thread_area
 | ||||
| 	.long sys_atomic_cmpxchg_32	/* 335 */ | ||||
| 	.long sys_atomic_barrier
 | ||||
| 
 | ||||
| 	.rept NR_syscalls-(.-sys_call_table)/4 | ||||
| 		.long sys_ni_syscall
 | ||||
|  | ||||
| @ -24,7 +24,6 @@ | ||||
| 
 | ||||
| /*
 | ||||
|  * Map some physical address range into the kernel address space. | ||||
|  * The code is copied and adapted from map_chunk(). | ||||
|  */ | ||||
| 
 | ||||
| unsigned long kernel_map(unsigned long paddr, unsigned long size, | ||||
|  | ||||
| @ -130,6 +130,7 @@ config CMDLINE_FORCE | ||||
| 
 | ||||
| config OF | ||||
| 	def_bool y | ||||
| 	select OF_FLATTREE | ||||
| 
 | ||||
| config PROC_DEVICETREE | ||||
| 	bool "Support for device tree in /proc" | ||||
|  | ||||
| @ -217,7 +217,7 @@ static inline void __iomem *__ioremap(phys_addr_t address, unsigned long size, | ||||
|  * Little endian | ||||
|  */ | ||||
| 
 | ||||
| #define out_le32(a, v) __raw_writel(__cpu_to_le32(v), (a)); | ||||
| #define out_le32(a, v) __raw_writel(__cpu_to_le32(v), (a)) | ||||
| #define out_le16(a, v) __raw_writew(__cpu_to_le16(v), (a)) | ||||
| 
 | ||||
| #define in_le32(a) __le32_to_cpu(__raw_readl(a)) | ||||
|  | ||||
| @ -26,31 +26,11 @@ | ||||
| #include <asm/irq.h> | ||||
| #include <asm/atomic.h> | ||||
| 
 | ||||
| #define OF_ROOT_NODE_ADDR_CELLS_DEFAULT	1 | ||||
| #define OF_ROOT_NODE_SIZE_CELLS_DEFAULT	1 | ||||
| 
 | ||||
| #define of_compat_cmp(s1, s2, l)	strncasecmp((s1), (s2), (l)) | ||||
| #define of_prop_cmp(s1, s2)		strcmp((s1), (s2)) | ||||
| #define of_node_cmp(s1, s2)		strcasecmp((s1), (s2)) | ||||
| 
 | ||||
| extern struct device_node *of_chosen; | ||||
| 
 | ||||
| #define HAVE_ARCH_DEVTREE_FIXUPS | ||||
| 
 | ||||
| extern struct device_node *allnodes;	/* temporary while merging */ | ||||
| extern rwlock_t devtree_lock;	/* temporary while merging */ | ||||
| 
 | ||||
| /* For updating the device tree at runtime */ | ||||
| extern void of_attach_node(struct device_node *); | ||||
| extern void of_detach_node(struct device_node *); | ||||
| 
 | ||||
| /* Other Prototypes */ | ||||
| extern int early_uartlite_console(void); | ||||
| 
 | ||||
| extern struct resource *request_OF_resource(struct device_node *node, | ||||
| 				int index, const char *name_postfix); | ||||
| extern int release_OF_resource(struct device_node *node, int index); | ||||
| 
 | ||||
| /*
 | ||||
|  * OF address retreival & translation | ||||
|  */ | ||||
|  | ||||
| @ -172,16 +172,15 @@ do {									\ | ||||
| /* It is used only first parameter for OP - for wic, wdc */ | ||||
| #define CACHE_RANGE_LOOP_1(start, end, line_length, op)			\ | ||||
| do {									\ | ||||
| 	int step = -line_length;					\ | ||||
| 	int count = end - start;					\ | ||||
| 	BUG_ON(count <= 0);						\ | ||||
| 	int volatile temp;						\ | ||||
| 	BUG_ON(end - start <= 0);					\ | ||||
| 									\ | ||||
| 	__asm__ __volatile__ (" 1:	addk	%0, %0, %1;		\
 | ||||
| 					" #op " %0, r0;			\ | ||||
| 					bgtid   %1, 1b;			\ | ||||
| 					addk    %1, %1, %2;		\ | ||||
| 					" : : "r" (start), "r" (count),	\
 | ||||
| 					"r" (step) : "memory");		\ | ||||
| 	__asm__ __volatile__ (" 1:	" #op " %1, r0;			\
 | ||||
| 					cmpu	%0, %1, %2;		\ | ||||
| 					bgtid	%0, 1b;			\ | ||||
| 					addk	%1, %1, %3;		\ | ||||
| 				" : : "r" (temp), "r" (start), "r" (end),\
 | ||||
| 					"r" (line_length) : "memory");	\ | ||||
| } while (0); | ||||
| 
 | ||||
| static void __flush_icache_range_msr_irq(unsigned long start, unsigned long end) | ||||
| @ -313,16 +312,6 @@ static void __invalidate_dcache_all_wb(void) | ||||
| 	pr_debug("%s\n", __func__); | ||||
| 	CACHE_ALL_LOOP2(cpuinfo.dcache_size, cpuinfo.dcache_line_length, | ||||
| 					wdc.clear) | ||||
| 
 | ||||
| #if 0 | ||||
| 	unsigned int i; | ||||
| 
 | ||||
| 	pr_debug("%s\n", __func__); | ||||
| 
 | ||||
| 	/* Just loop through cache size and invalidate it */ | ||||
| 	for (i = 0; i < cpuinfo.dcache_size; i += cpuinfo.dcache_line_length) | ||||
| 			__invalidate_dcache(0, i); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| static void __invalidate_dcache_range_wb(unsigned long start, | ||||
|  | ||||
| @ -185,7 +185,7 @@ EXPORT_SYMBOL(of_find_device_by_node); | ||||
| static int of_dev_phandle_match(struct device *dev, void *data) | ||||
| { | ||||
| 	phandle *ph = data; | ||||
| 	return to_of_device(dev)->node->linux_phandle == *ph; | ||||
| 	return to_of_device(dev)->node->phandle == *ph; | ||||
| } | ||||
| 
 | ||||
| struct of_device *of_find_device_by_phandle(phandle ph) | ||||
|  | ||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue
	
	Block a user