Merge branch 'drm-patches' of master.kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6
* 'drm-patches' of master.kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6:
via: Make sure we flush write-combining using a follow-up read.
via: Try to improve command-buffer chaining.
drm: remove old taskqueue remnant
drm: rename badly named define and cleanup ioctl code spacing
radeon: Don't mess up page flipping when a file descriptor is closed.
drm/radeon: upgrade to 1.27 - make PCI GART more flexible
diff --git a/CREDITS b/CREDITS
index c5f819b..80e2413 100644
--- a/CREDITS
+++ b/CREDITS
@@ -661,7 +661,7 @@
E: kees@outflux.net
W: http://outflux.net/
P: 1024D/17063E6D 9FA3 C49C 23C9 D1BC 2E30 1975 1FFF 4BA9 1706 3E6D
-D: Minor updates to SCSI code for the Communications type
+D: Minor updates to SCSI types, added /proc/pid/maps protection
S: (ask for current address)
S: USA
@@ -2580,10 +2580,9 @@
N: Miguel Ojeda Sandonis
E: maxextreme@gmail.com
-D: Author: Auxiliary LCD Controller driver (ks0108)
-D: Author: Auxiliary LCD driver (cfag12864b)
-D: Author: Auxiliary LCD framebuffer driver (cfag12864bfb)
-D: Maintainer: Auxiliary display drivers tree (drivers/auxdisplay/*)
+W: http://maxextreme.googlepages.com/
+D: Author of the ks0108, cfag12864b and cfag12864bfb auxiliary display drivers.
+D: Maintainer of the auxiliary display drivers tree (drivers/auxdisplay/*)
S: C/ Mieses 20, 9-B
S: Valladolid 47009
S: Spain
diff --git a/Documentation/CodingStyle b/Documentation/CodingStyle
index 9069189..afc2867 100644
--- a/Documentation/CodingStyle
+++ b/Documentation/CodingStyle
@@ -160,6 +160,21 @@
25-line terminal screens here), you have more empty lines to put
comments on.
+Do not unnecessarily use braces where a single statement will do.
+
+if (condition)
+ action();
+
+This does not apply if one branch of a conditional statement is a single
+statement. Use braces in both branches.
+
+if (condition) {
+ do_this();
+ do_that();
+} else {
+ otherwise();
+}
+
3.1: Spaces
Linux kernel style for use of spaces depends (mostly) on
@@ -625,7 +640,7 @@
There appears to be a common misperception that gcc has a magic "make me
faster" speedup option called "inline". While the use of inlines can be
-appropriate (for example as a means of replacing macros, see Chapter 11), it
+appropriate (for example as a means of replacing macros, see Chapter 12), it
very often is not. Abundant use of the inline keyword leads to a much bigger
kernel, which in turn slows the system as a whole down, due to a bigger
icache footprint for the CPU and simply because there is less memory
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
index 10b5cd6..6fd1646 100644
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -43,6 +43,7 @@
HTML := $(sort $(patsubst %.xml, %.html, $(BOOKS)))
htmldocs: $(HTML)
+ $(call build_main_index)
MAN := $(patsubst %.xml, %.9, $(BOOKS))
mandocs: $(MAN)
@@ -132,10 +133,17 @@
%.pdf : %.xml
$(call cmd,db2pdf)
+
+main_idx = Documentation/DocBook/index.html
+build_main_index = rm -rf $(main_idx) && \
+ echo '<h1>Linux Kernel HTML Documentation</h1>' >> $(main_idx) && \
+ echo '<h2>Kernel Version: $(KERNELVERSION)</h2>' >> $(main_idx) && \
+ cat $(HTML) >> $(main_idx)
+
quiet_cmd_db2html = HTML $@
cmd_db2html = xmlto xhtml $(XMLTOFLAGS) -o $(patsubst %.html,%,$@) $< && \
echo '<a HREF="$(patsubst %.html,%,$(notdir $@))/index.html"> \
- Goto $(patsubst %.html,%,$(notdir $@))</a><p>' > $@
+ $(patsubst %.html,%,$(notdir $@))</a><p>' > $@
%.html: %.xml
@(which xmlto > /dev/null 2>&1) || \
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
index b61dfc7..a2b2b4d 100644
--- a/Documentation/DocBook/kernel-api.tmpl
+++ b/Documentation/DocBook/kernel-api.tmpl
@@ -576,4 +576,67 @@
!Edrivers/input/ff-core.c
!Edrivers/input/ff-memless.c
</chapter>
+
+ <chapter id="spi">
+ <title>Serial Peripheral Interface (SPI)</title>
+ <para>
+ SPI is the "Serial Peripheral Interface", widely used with
+ embedded systems because it is a simple and efficient
+ interface: basically a multiplexed shift register.
+ Its three signal wires hold a clock (SCK, often in the range
+ of 1-20 MHz), a "Master Out, Slave In" (MOSI) data line, and
+ a "Master In, Slave Out" (MISO) data line.
+ SPI is a full duplex protocol; for each bit shifted out the
+ MOSI line (one per clock) another is shifted in on the MISO line.
+ Those bits are assembled into words of various sizes on the
+ way to and from system memory.
+ An additional chipselect line is usually active-low (nCS);
+ four signals are normally used for each peripheral, plus
+ sometimes an interrupt.
+ </para>
+ <para>
+ The SPI bus facilities listed here provide a generalized
+ interface to declare SPI busses and devices, manage them
+ according to the standard Linux driver model, and perform
+ input/output operations.
+ At this time, only "master" side interfaces are supported,
+ where Linux talks to SPI peripherals and does not implement
+ such a peripheral itself.
+ (Interfaces to support implementing SPI slaves would
+ necessarily look different.)
+ </para>
+ <para>
+ The programming interface is structured around two kinds of driver,
+ and two kinds of device.
+ A "Controller Driver" abstracts the controller hardware, which may
+ be as simple as a set of GPIO pins or as complex as a pair of FIFOs
+ connected to dual DMA engines on the other side of the SPI shift
+ register (maximizing throughput). Such drivers bridge between
+ whatever bus they sit on (often the platform bus) and SPI, and
+ expose the SPI side of their device as a
+ <structname>struct spi_master</structname>.
+ SPI devices are children of that master, represented as a
+ <structname>struct spi_device</structname> and manufactured from
+ <structname>struct spi_board_info</structname> descriptors which
+ are usually provided by board-specific initialization code.
+ A <structname>struct spi_driver</structname> is called a
+ "Protocol Driver", and is bound to a spi_device using normal
+ driver model calls.
+ </para>
+ <para>
+ The I/O model is a set of queued messages. Protocol drivers
+ submit one or more <structname>struct spi_message</structname>
+ objects, which are processed and completed asynchronously.
+ (There are synchronous wrappers, however.) Messages are
+ built from one or more <structname>struct spi_transfer</structname>
+ objects, each of which wraps a full duplex SPI transfer.
+ A variety of protocol tweaking options are needed, because
+ different chips adopt very different policies for how they
+ use the bits transferred with SPI.
+ </para>
+!Iinclude/linux/spi/spi.h
+!Fdrivers/spi/spi.c spi_register_board_info
+!Edrivers/spi/spi.c
+ </chapter>
+
</book>
diff --git a/Documentation/DocBook/librs.tmpl b/Documentation/DocBook/librs.tmpl
index 3ff39ba..94f2136 100644
--- a/Documentation/DocBook/librs.tmpl
+++ b/Documentation/DocBook/librs.tmpl
@@ -79,12 +79,12 @@
<chapter id="usage">
<title>Usage</title>
<para>
- This chapter provides examples how to use the library.
+ This chapter provides examples of how to use the library.
</para>
<sect1>
<title>Initializing</title>
<para>
- The init function init_rs returns a pointer to a
+ The init function init_rs returns a pointer to an
rs decoder structure, which holds the necessary
information for encoding, decoding and error correction
with the given polynomial. It either uses an existing
@@ -98,10 +98,10 @@
static struct rs_control *rs_decoder;
/* Symbolsize is 10 (bits)
- * Primitve polynomial is x^10+x^3+1
+ * Primitive polynomial is x^10+x^3+1
* first consecutive root is 0
- * primitve element to generate roots = 1
- * generator polinomial degree (number of roots) = 6
+ * primitive element to generate roots = 1
+ * generator polynomial degree (number of roots) = 6
*/
rs_decoder = init_rs (10, 0x409, 0, 1, 6);
</programlisting>
@@ -116,12 +116,12 @@
</para>
<para>
The expanded data can be inverted on the fly by
- providing a non zero inversion mask. The expanded data is
+ providing a non-zero inversion mask. The expanded data is
XOR'ed with the mask. This is used e.g. for FLASH
ECC, where the all 0xFF is inverted to an all 0x00.
The Reed-Solomon code for all 0x00 is all 0x00. The
code is inverted before storing to FLASH so it is 0xFF
- too. This prevent's that reading from an erased FLASH
+ too. This prevents that reading from an erased FLASH
results in ECC errors.
</para>
<para>
@@ -273,7 +273,7 @@
May be used under the terms of the GNU General Public License (GPL)
</programlisting>
<para>
- The wrapper functions and interfaces are written by Thomas Gleixner
+ The wrapper functions and interfaces are written by Thomas Gleixner.
</para>
<para>
Many users have provided bugfixes, improvements and helping hands for testing.
diff --git a/Documentation/SubmittingDrivers b/Documentation/SubmittingDrivers
index 58bead0..d7e2642 100644
--- a/Documentation/SubmittingDrivers
+++ b/Documentation/SubmittingDrivers
@@ -87,6 +87,21 @@
driver that intentionally obfuscates how the hardware works
it will go in the bitbucket.
+PM support: Since Linux is used on many portable and desktop systems, your
+ driver is likely to be used on such a system and therefore it
+ should support basic power management by implementing, if
+ necessary, the .suspend and .resume methods used during the
+ system-wide suspend and resume transitions. You should verify
+ that your driver correctly handles the suspend and resume, but
+ if you are unable to ensure that, please at least define the
+ .suspend method returning the -ENOSYS ("Function not
+ implemented") error. You should also try to make sure that your
+ driver uses as little power as possible when it's not doing
+ anything. For the driver testing instructions see
+ Documentation/power/drivers-testing.txt and for a relatively
+ complete overview of the power management issues related to
+ drivers see Documentation/power/devices.txt .
+
Control: In general if there is active maintainance of a driver by
the author then patches will be redirected to them unless
they are totally obvious and without need of checking.
diff --git a/Documentation/accounting/getdelays.c b/Documentation/accounting/getdelays.c
index e9126e7..71acc28 100644
--- a/Documentation/accounting/getdelays.c
+++ b/Documentation/accounting/getdelays.c
@@ -61,8 +61,6 @@
#define MAX_MSG_SIZE 1024
/* Maximum number of cpus expected to be specified in a cpumask */
#define MAX_CPUS 32
-/* Maximum length of pathname to log file */
-#define MAX_FILENAME 256
struct msgtemplate {
struct nlmsghdr n;
@@ -72,6 +70,16 @@
char cpumask[100+6*MAX_CPUS];
+static void usage(void)
+{
+ fprintf(stderr, "getdelays [-dilv] [-w logfile] [-r bufsize] "
+ "[-m cpumask] [-t tgid] [-p pid]\n");
+ fprintf(stderr, " -d: print delayacct stats\n");
+ fprintf(stderr, " -i: print IO accounting (works only with -p)\n");
+ fprintf(stderr, " -l: listen forever\n");
+ fprintf(stderr, " -v: debug on\n");
+}
+
/*
* Create a raw netlink socket and bind
*/
@@ -221,13 +229,13 @@
int count = 0;
int write_file = 0;
int maskset = 0;
- char logfile[128];
+ char *logfile = NULL;
int loop = 0;
struct msgtemplate msg;
while (1) {
- c = getopt(argc, argv, "diw:r:m:t:p:v:l");
+ c = getopt(argc, argv, "diw:r:m:t:p:vl");
if (c < 0)
break;
@@ -241,7 +249,7 @@
print_io_accounting = 1;
break;
case 'w':
- strncpy(logfile, optarg, MAX_FILENAME);
+ logfile = strdup(optarg);
printf("write to file %s\n", logfile);
write_file = 1;
break;
@@ -277,7 +285,7 @@
loop = 1;
break;
default:
- printf("Unknown option %d\n", c);
+ usage();
exit(-1);
}
}
diff --git a/Documentation/cciss.txt b/Documentation/cciss.txt
index f74affe..e65736c 100644
--- a/Documentation/cciss.txt
+++ b/Documentation/cciss.txt
@@ -22,14 +22,21 @@
* SA E200i
* SA E500
+Detecting drive failures:
+-------------------------
+
+To get the status of logical volumes and to detect physical drive
+failures, you can use the cciss_vol_status program found here:
+http://cciss.sourceforge.net/#cciss_utils
+
+Device Naming:
+--------------
+
If nodes are not already created in the /dev/cciss directory, run as root:
# cd /dev
# ./MAKEDEV cciss
-Device Naming:
---------------
-
You need some entries in /dev for the cciss device. The MAKEDEV script
can make device nodes for you automatically. Currently the device setup
is as follows:
diff --git a/Documentation/fb/deferred_io.txt b/Documentation/fb/deferred_io.txt
new file mode 100644
index 0000000..73cf9fb
--- /dev/null
+++ b/Documentation/fb/deferred_io.txt
@@ -0,0 +1,75 @@
+Deferred IO
+-----------
+
+Deferred IO is a way to delay and repurpose IO. It uses host memory as a
+buffer and the MMU pagefault as a pretrigger for when to perform the device
+IO. The following example may be a useful explaination of how one such setup
+works:
+
+- userspace app like Xfbdev mmaps framebuffer
+- deferred IO and driver sets up nopage and page_mkwrite handlers
+- userspace app tries to write to mmaped vaddress
+- we get pagefault and reach nopage handler
+- nopage handler finds and returns physical page
+- we get page_mkwrite where we add this page to a list
+- schedule a workqueue task to be run after a delay
+- app continues writing to that page with no additional cost. this is
+ the key benefit.
+- the workqueue task comes in and mkcleans the pages on the list, then
+ completes the work associated with updating the framebuffer. this is
+ the real work talking to the device.
+- app tries to write to the address (that has now been mkcleaned)
+- get pagefault and the above sequence occurs again
+
+As can be seen from above, one benefit is roughly to allow bursty framebuffer
+writes to occur at minimum cost. Then after some time when hopefully things
+have gone quiet, we go and really update the framebuffer which would be
+a relatively more expensive operation.
+
+For some types of nonvolatile high latency displays, the desired image is
+the final image rather than the intermediate stages which is why it's okay
+to not update for each write that is occuring.
+
+It may be the case that this is useful in other scenarios as well. Paul Mundt
+has mentioned a case where it is beneficial to use the page count to decide
+whether to coalesce and issue SG DMA or to do memory bursts.
+
+Another one may be if one has a device framebuffer that is in an usual format,
+say diagonally shifting RGB, this may then be a mechanism for you to allow
+apps to pretend to have a normal framebuffer but reswizzle for the device
+framebuffer at vsync time based on the touched pagelist.
+
+How to use it: (for applications)
+---------------------------------
+No changes needed. mmap the framebuffer like normal and just use it.
+
+How to use it: (for fbdev drivers)
+----------------------------------
+The following example may be helpful.
+
+1. Setup your structure. Eg:
+
+static struct fb_deferred_io hecubafb_defio = {
+ .delay = HZ,
+ .deferred_io = hecubafb_dpy_deferred_io,
+};
+
+The delay is the minimum delay between when the page_mkwrite trigger occurs
+and when the deferred_io callback is called. The deferred_io callback is
+explained below.
+
+2. Setup your deferred IO callback. Eg:
+static void hecubafb_dpy_deferred_io(struct fb_info *info,
+ struct list_head *pagelist)
+
+The deferred_io callback is where you would perform all your IO to the display
+device. You receive the pagelist which is the list of pages that were written
+to during the delay. You must not modify this list. This callback is called
+from a workqueue.
+
+3. Call init
+ info->fbdefio = &hecubafb_defio;
+ fb_deferred_io_init(info);
+
+4. Call cleanup
+ fb_deferred_io_cleanup(info);
diff --git a/Documentation/fb/s3fb.txt b/Documentation/fb/s3fb.txt
index 8a04c0d..2c97770 100644
--- a/Documentation/fb/s3fb.txt
+++ b/Documentation/fb/s3fb.txt
@@ -35,10 +35,12 @@
* suspend/resume support
* DPMS support
-Text mode is supported even in higher resolutions, but there is limitation
-to lower pixclocks (maximum between 50-60 MHz, depending on specific hardware).
-This limitation is not enforced by driver. Text mode supports 8bit wide fonts
-only (hardware limitation) and 16bit tall fonts (driver limitation).
+Text mode is supported even in higher resolutions, but there is limitation to
+lower pixclocks (maximum usually between 50-60 MHz, depending on specific
+hardware, i get best results from plain S3 Trio32 card - about 75 MHz). This
+limitation is not enforced by driver. Text mode supports 8bit wide fonts only
+(hardware limitation) and 16bit tall fonts (driver limitation). Text mode
+support is broken on S3 Trio64 V2/DX.
There are two 4 bpp modes. First mode (selected if nonstd == 0) is mode with
packed pixels, high nibble first. Second mode (selected if nonstd == 1) is mode
@@ -73,6 +75,8 @@
==========
* cursor disable in text mode doesn't work
+ * text mode broken on S3 Trio64 V2/DX
+
--
Ondrej Zajicek <santiago@crfreenet.org>
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 5f96cb3..2291ff6 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -6,6 +6,14 @@
---------------------------
+What: MXSER
+When: December 2007
+Why: Old mxser driver is obsoleted by the mxser_new. Give it some time yet
+ and remove it.
+Who: Jiri Slaby <jirislaby@gmail.com>
+
+---------------------------
+
What: V4L2 VIDIOC_G_MPEGCOMP and VIDIOC_S_MPEGCOMP
When: October 2007
Why: Broken attempt to set MPEG compression parameters. These ioctls are
@@ -117,18 +125,6 @@
---------------------------
-What: Usage of invalid timevals in setitimer
-When: March 2007
-Why: POSIX requires to validate timevals in the setitimer call. This
- was never done by Linux. The invalid (e.g. negative timevals) were
- silently converted to more or less random timeouts and intervals.
- Until the removal a per boot limited number of warnings is printed
- and the timevals are sanitized.
-
-Who: Thomas Gleixner <tglx@linutronix.de>
-
----------------------------
-
What: Unused EXPORT_SYMBOL/EXPORT_SYMBOL_GPL exports
(temporary transition config option provided until then)
The transition config option will also be removed at the same time.
@@ -156,7 +152,7 @@
---------------------------
What: Interrupt only SA_* flags
-When: Januar 2007
+When: September 2007
Why: The interrupt related SA_* flags are replaced by IRQF_* to move them
out of the signal namespace.
@@ -323,3 +319,11 @@
Who: Jean Delvare <khali@linux-fr.org>
---------------------------
+
+What: drivers depending on OSS_OBSOLETE
+When: options in 2.6.23, code in 2.6.25
+Why: obsolete OSS drivers
+Who: Adrian Bunk <bunk@stusta.de>
+
+---------------------------
+
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index 28bfea7..59c1415 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -15,6 +15,7 @@
int (*d_delete)(struct dentry *);
void (*d_release)(struct dentry *);
void (*d_iput)(struct dentry *, struct inode *);
+ char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen);
locking rules:
none have BKL
@@ -25,6 +26,7 @@
d_delete: yes no yes no
d_release: no no no yes
d_iput: no no no yes
+d_dname: no no no no
--------------------------- inode_operations ---------------------------
prototypes:
diff --git a/Documentation/filesystems/jfs.txt b/Documentation/filesystems/jfs.txt
index bae1286..26ebde7 100644
--- a/Documentation/filesystems/jfs.txt
+++ b/Documentation/filesystems/jfs.txt
@@ -29,7 +29,13 @@
errors=remount-ro Default. Remount the filesystem read-only on an error.
errors=panic Panic and halt the machine if an error occurs.
-Please send bugs, comments, cards and letters to shaggy@austin.ibm.com.
+uid=value Override on-disk uid with specified value
+gid=value Override on-disk gid with specified value
+umask=value Override on-disk umask with specified octal value. For
+ directories, the execute bit will be set if the corresponding
+ read bit is set.
+
+Please send bugs, comments, cards and letters to shaggy@linux.vnet.ibm.com.
The JFS mailing list can be subscribed to by using the link labeled
"Mail list Subscribe" at our web page http://jfs.sourceforge.net/
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index 3f4b226..4f3e84c 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -1138,6 +1138,13 @@
Because the NMI watchdog shares registers with oprofile, by disabling the NMI
watchdog, oprofile may have more registers to utilize.
+maps_protect
+------------
+
+Enables/Disables the protection of the per-process proc entries "maps" and
+"smaps". When enabled, the contents of these files are visible only to
+readers that are allowed to ptrace() the given process.
+
2.4 /proc/sys/vm - The virtual memory subsystem
-----------------------------------------------
diff --git a/Documentation/filesystems/vfat.txt b/Documentation/filesystems/vfat.txt
index 069cb10..fcc123f 100644
--- a/Documentation/filesystems/vfat.txt
+++ b/Documentation/filesystems/vfat.txt
@@ -57,6 +57,13 @@
currently exist in the directory, 'longfile.txt' will
be the short alias instead of 'longfi~1.txt'.
+usefree -- Use the "free clusters" value stored on FSINFO. It'll
+ be used to determine number of free clusters without
+ scanning disk. But it's not used by default, because
+ recent Windows don't update it correctly in some
+ case. If you are sure the "free clusters" on FSINFO is
+ correct, by this option you can avoid scanning disk.
+
quiet -- Stops printing certain warning messages.
check=s|r|n -- Case sensitivity checking setting.
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index ea271f2..a47cc81 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -827,7 +827,7 @@
operations. Dentries and the dcache are the domain of the VFS and the
individual filesystem implementations. Device drivers have no business
here. These methods may be set to NULL, as they are either optional or
-the VFS uses a default. As of kernel 2.6.13, the following members are
+the VFS uses a default. As of kernel 2.6.22, the following members are
defined:
struct dentry_operations {
@@ -837,6 +837,7 @@
int (*d_delete)(struct dentry *);
void (*d_release)(struct dentry *);
void (*d_iput)(struct dentry *, struct inode *);
+ char *(*d_dname)(struct dentry *, char *, int);
};
d_revalidate: called when the VFS needs to revalidate a dentry. This
@@ -859,6 +860,26 @@
VFS calls iput(). If you define this method, you must call
iput() yourself
+ d_dname: called when the pathname of a dentry should be generated.
+ Usefull for some pseudo filesystems (sockfs, pipefs, ...) to delay
+ pathname generation. (Instead of doing it when dentry is created,
+ its done only when the path is needed.). Real filesystems probably
+ dont want to use it, because their dentries are present in global
+ dcache hash, so their hash should be an invariant. As no lock is
+ held, d_dname() should not try to modify the dentry itself, unless
+ appropriate SMP safety is used. CAUTION : d_path() logic is quite
+ tricky. The correct way to return for example "Hello" is to put it
+ at the end of the buffer, and returns a pointer to the first char.
+ dynamic_dname() helper function is provided to take care of this.
+
+Example :
+
+static char *pipefs_dname(struct dentry *dent, char *buffer, int buflen)
+{
+ return dynamic_dname(dentry, buffer, buflen, "pipe:[%lu]",
+ dentry->d_inode->i_ino);
+}
+
Each dentry has a pointer to its parent dentry, as well as a hash list
of child dentries. Child dentries are basically like files in a
directory.
diff --git a/Documentation/ioctl-number.txt b/Documentation/ioctl-number.txt
index 8f750c0..3de7d37 100644
--- a/Documentation/ioctl-number.txt
+++ b/Documentation/ioctl-number.txt
@@ -138,7 +138,8 @@
'm' 00-1F net/irda/irmod.h conflict!
'n' 00-7F linux/ncp_fs.h
'n' E0-FF video/matrox.h matroxfb
-'p' 00-3F linux/mc146818rtc.h
+'p' 00-0F linux/phantom.h conflict! (OpenHaptics needs this)
+'p' 00-3F linux/mc146818rtc.h conflict!
'p' 40-7F linux/nvram.h
'p' 80-9F user-space parport
<mailto:tim@cyberelk.net>
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 38d7db3..6b8ad06 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -496,6 +496,30 @@
Format: <area>[,<node>]
See also Documentation/networking/decnet.txt.
+ default_blu= [VT]
+ Format: <blue0>,<blue1>,<blue2>,...,<blue15>
+ Change the default blue palette of the console.
+ This is a 16-member array composed of values
+ ranging from 0-255.
+
+ default_grn= [VT]
+ Format: <green0>,<green1>,<green2>,...,<green15>
+ Change the default green palette of the console.
+ This is a 16-member array composed of values
+ ranging from 0-255.
+
+ default_red= [VT]
+ Format: <red0>,<red1>,<red2>,...,<red15>
+ Change the default red palette of the console.
+ This is a 16-member array composed of values
+ ranging from 0-255.
+
+ default_utf8= [VT]
+ Format=<0|1>
+ Set system-wide default UTF-8 mode for all tty's.
+ Default is 0 and by setting to 1, it enables UTF-8
+ mode for all newly opened or allocated terminals.
+
dhash_entries= [KNL]
Set number of hash buckets for dentry cache.
@@ -816,6 +840,11 @@
lasi= [HW,SCSI] PARISC LASI driver for the 53c700 chip
Format: addr:<io>,irq:<irq>
+ legacy_serial.force [HW,IA-32,X86-64]
+ Probe for COM ports at legacy addresses even
+ if PNPBIOS or ACPI should describe them. This
+ is for working around firmware defects.
+
llsc*= [IA64] See function print_params() in
arch/ia64/sn/kernel/llsc4.c.
@@ -1578,6 +1607,17 @@
smp-alt-once [IA-32,SMP] On a hotplug CPU system, only
attempt to substitute SMP alternatives once at boot.
+ smsc-ircc2.nopnp [HW] Don't use PNP to discover SMC devices
+ smsc-ircc2.ircc_cfg= [HW] Device configuration I/O port
+ smsc-ircc2.ircc_sir= [HW] SIR base I/O port
+ smsc-ircc2.ircc_fir= [HW] FIR base I/O port
+ smsc-ircc2.ircc_irq= [HW] IRQ line
+ smsc-ircc2.ircc_dma= [HW] DMA channel
+ smsc-ircc2.ircc_transceiver= [HW] Transceiver type:
+ 0: Toshiba Satellite 1800 (GP data pin select)
+ 1: Fast pin select (default)
+ 2: ATC IRMode
+
snd-ad1816a= [HW,ALSA]
snd-ad1848= [HW,ALSA]
diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt
index d71faff..da5404ab 100644
--- a/Documentation/kprobes.txt
+++ b/Documentation/kprobes.txt
@@ -14,6 +14,7 @@
8. Kprobes Example
9. Jprobes Example
10. Kretprobes Example
+Appendix A: The kprobes debugfs interface
1. Concepts: Kprobes, Jprobes, Return Probes
@@ -349,9 +350,12 @@
If the number of times a function is called does not match the number
of times it returns, registering a return probe on that function may
-produce undesirable results. We have the do_exit() case covered.
-do_execve() and do_fork() are not an issue. We're unaware of other
-specific cases where this could be a problem.
+produce undesirable results. In such a case, a line:
+kretprobe BUG!: Processing kretprobe d000000000041aa8 @ c00000000004f48c
+gets printed. With this information, one will be able to correlate the
+exact instance of the kretprobe that caused the problem. We have the
+do_exit() case covered. do_execve() and do_fork() are not an issue.
+We're unaware of other specific cases where this could be a problem.
If, upon entry to or exit from a function, the CPU is running on
a stack other than that of the current task, registering a return
@@ -614,3 +618,27 @@
http://www.redhat.com/magazine/005mar05/features/kprobes/
http://www-users.cs.umn.edu/~boutcher/kprobes/
http://www.linuxsymposium.org/2006/linuxsymposium_procv2.pdf (pages 101-115)
+
+
+Appendix A: The kprobes debugfs interface
+
+With recent kernels (> 2.6.20) the list of registered kprobes is visible
+under the /debug/kprobes/ directory (assuming debugfs is mounted at /debug).
+
+/debug/kprobes/list: Lists all registered probes on the system
+
+c015d71a k vfs_read+0x0
+c011a316 j do_fork+0x0
+c03dedc5 r tcp_v4_rcv+0x0
+
+The first column provides the kernel address where the probe is inserted.
+The second column identifies the type of probe (k - kprobe, r - kretprobe
+and j - jprobe), while the third column specifies the symbol+offset of
+the probe. If the probed function belongs to a module, the module name
+is also specified.
+
+/debug/kprobes/enabled: Turn kprobes ON/OFF
+
+Provides a knob to globally turn registered kprobes ON or OFF. By default,
+all kprobes are enabled. By echoing "0" to this file, all registered probes
+will be disarmed, till such time a "1" is echoed to this file.
diff --git a/Documentation/laptop-mode.txt b/Documentation/laptop-mode.txt
index 6f639e3..eeedee1 100644
--- a/Documentation/laptop-mode.txt
+++ b/Documentation/laptop-mode.txt
@@ -33,7 +33,7 @@
laptop mode will automatically be started when you're on battery. For
your convenience, a tarball containing an installer can be downloaded at:
-http://www.xs4all.nl/~bsamwel/laptop_mode/tools/
+http://www.samwel.tk/laptop_mode/laptop_mode/
To configure laptop mode, you need to edit the configuration file, which is
located in /etc/default/laptop-mode on Debian-based systems, or in
diff --git a/Documentation/oops-tracing.txt b/Documentation/oops-tracing.txt
index ea55ea8..7d5b60d 100644
--- a/Documentation/oops-tracing.txt
+++ b/Documentation/oops-tracing.txt
@@ -234,9 +234,6 @@
6: 'B' if a page-release function has found a bad page reference or
some unexpected page flags.
- 7: 'U' if a user specifically requested that the Tainted flag be set,
- ' ' otherwise.
-
7: 'U' if a user or user application specifically requested that the
Tainted flag be set, ' ' otherwise.
diff --git a/Documentation/power/basic-pm-debugging.txt b/Documentation/power/basic-pm-debugging.txt
new file mode 100644
index 0000000..1a85e2b
--- /dev/null
+++ b/Documentation/power/basic-pm-debugging.txt
@@ -0,0 +1,106 @@
+Debugging suspend and resume
+ (C) 2007 Rafael J. Wysocki <rjw@sisk.pl>, GPL
+
+1. Testing suspend to disk (STD)
+
+To verify that the STD works, you can try to suspend in the "reboot" mode:
+
+# echo reboot > /sys/power/disk
+# echo disk > /sys/power/state
+
+and the system should suspend, reboot, resume and get back to the command prompt
+where you have started the transition. If that happens, the STD is most likely
+to work correctly, but you need to repeat the test at least a couple of times in
+a row for confidence. This is necessary, because some problems only show up on
+a second attempt at suspending and resuming the system. You should also test
+the "platform" and "shutdown" modes of suspend:
+
+# echo platform > /sys/power/disk
+# echo disk > /sys/power/state
+
+or
+
+# echo shutdown > /sys/power/disk
+# echo disk > /sys/power/state
+
+in which cases you will have to press the power button to make the system
+resume. If that does not work, you will need to identify what goes wrong.
+
+a) Test mode of STD
+
+To verify if there are any drivers that cause problems you can run the STD
+in the test mode:
+
+# echo test > /sys/power/disk
+# echo disk > /sys/power/state
+
+in which case the system should freeze tasks, suspend devices, disable nonboot
+CPUs (if any), wait for 5 seconds, enable nonboot CPUs, resume devices, thaw
+tasks and return to your command prompt. If that fails, most likely there is
+a driver that fails to either suspend or resume (in the latter case the system
+may hang or be unstable after the test, so please take that into consideration).
+To find this driver, you can carry out a binary search according to the rules:
+- if the test fails, unload a half of the drivers currently loaded and repeat
+(that would probably involve rebooting the system, so always note what drivers
+have been loaded before the test),
+- if the test succeeds, load a half of the drivers you have unloaded most
+recently and repeat.
+
+Once you have found the failing driver (there can be more than just one of
+them), you have to unload it every time before the STD transition. In that case
+please make sure to report the problem with the driver.
+
+It is also possible that a cycle can still fail after you have unloaded
+all modules. In that case, you would want to look in your kernel configuration
+for the drivers that can be compiled as modules (testing again with them as
+modules), and possibly also try boot time options such as "noapic" or "noacpi".
+
+b) Testing minimal configuration
+
+If the test mode of STD works, you can boot the system with "init=/bin/bash"
+and attempt to suspend in the "reboot", "shutdown" and "platform" modes. If
+that does not work, there probably is a problem with a driver statically
+compiled into the kernel and you can try to compile more drivers as modules,
+so that they can be tested individually. Otherwise, there is a problem with a
+modular driver and you can find it by loading a half of the modules you normally
+use and binary searching in accordance with the algorithm:
+- if there are n modules loaded and the attempt to suspend and resume fails,
+unload n/2 of the modules and try again (that would probably involve rebooting
+the system),
+- if there are n modules loaded and the attempt to suspend and resume succeeds,
+load n/2 modules more and try again.
+
+Again, if you find the offending module(s), it(they) must be unloaded every time
+before the STD transition, and please report the problem with it(them).
+
+c) Advanced debugging
+
+In case the STD does not work on your system even in the minimal configuration
+and compiling more drivers as modules is not practical or some modules cannot
+be unloaded, you can use one of the more advanced debugging techniques to find
+the problem. First, if there is a serial port in your box, you can set the
+CONFIG_DISABLE_CONSOLE_SUSPEND kernel configuration option and try to log kernel
+messages using the serial console. This may provide you with some information
+about the reasons of the suspend (resume) failure. Alternatively, it may be
+possible to use a FireWire port for debugging with firescope
+(ftp://ftp.firstfloor.org/pub/ak/firescope/). On i386 it is also possible to
+use the PM_TRACE mechanism documented in Documentation/s2ram.txt .
+
+2. Testing suspend to RAM (STR)
+
+To verify that the STR works, it is generally more convenient to use the s2ram
+tool available from http://suspend.sf.net and documented at
+http://en.opensuse.org/s2ram . However, before doing that it is recommended to
+carry out the procedure described in section 1.
+
+Assume you have resolved the problems with the STD and you have found some
+failing drivers. These drivers are also likely to fail during the STR or
+during the resume, so it is better to unload them every time before the STR
+transition. Now, you can follow the instructions at
+http://en.opensuse.org/s2ram to test the system, but if it does not work
+"out of the box", you may need to boot it with "init=/bin/bash" and test
+s2ram in the minimal configuration. In that case, you may be able to search
+for failing drivers by following the procedure analogous to the one described in
+1b). If you find some failing drivers, you will have to unload them every time
+before the STR transition (ie. before you run s2ram), and please report the
+problems with them.
diff --git a/Documentation/power/drivers-testing.txt b/Documentation/power/drivers-testing.txt
new file mode 100644
index 0000000..33016c2
--- /dev/null
+++ b/Documentation/power/drivers-testing.txt
@@ -0,0 +1,42 @@
+Testing suspend and resume support in device drivers
+ (C) 2007 Rafael J. Wysocki <rjw@sisk.pl>, GPL
+
+1. Preparing the test system
+
+Unfortunately, to effectively test the support for the system-wide suspend and
+resume transitions in a driver, it is necessary to suspend and resume a fully
+functional system with this driver loaded. Moreover, that should be done
+several times, preferably several times in a row, and separately for the suspend
+to disk (STD) and the suspend to RAM (STR) transitions, because each of these
+cases involves different ordering of operations and different interactions with
+the machine's BIOS.
+
+Of course, for this purpose the test system has to be known to suspend and
+resume without the driver being tested. Thus, if possible, you should first
+resolve all suspend/resume-related problems in the test system before you start
+testing the new driver. Please see Documents/power/basic-pm-debugging.txt for
+more information about the debugging of suspend/resume functionality.
+
+2. Testing the driver
+
+Once you have resolved the suspend/resume-related problems with your test system
+without the new driver, you are ready to test it:
+
+a) Build the driver as a module, load it and try the STD in the test mode (see:
+Documents/power/basic-pm-debugging.txt, 1a)).
+
+b) Load the driver and attempt to suspend to disk in the "reboot", "shutdown"
+and "platform" modes (see: Documents/power/basic-pm-debugging.txt, 1).
+
+c) Compile the driver directly into the kernel and try the STD in the test mode.
+
+d) Attempt to suspend to disk with the driver compiled directly into the kernel
+in the "reboot", "shutdown" and "platform" modes.
+
+e) Attempt to suspend to RAM using the s2ram tool with the driver loaded (see:
+Documents/power/basic-pm-debugging.txt, 2). As far as the STR tests are
+concerned, it should not matter whether or not the driver is built as a module.
+
+Each of the above tests should be repeated several times and the STD tests
+should be mixed with the STR tests. If any of them fails, the driver cannot be
+regarded as suspend/resume-safe.
diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
index 033a3f3..d4bfae7 100644
--- a/Documentation/powerpc/booting-without-of.txt
+++ b/Documentation/powerpc/booting-without-of.txt
@@ -1560,6 +1560,9 @@
network device. This is used by the bootwrapper to interpret
MAC addresses passed by the firmware when no information other
than indices is available to associate an address with a device.
+ - phy-connection-type : a string naming the controller/PHY interface type,
+ i.e., "mii" (default), "rmii", "gmii", "rgmii", "rgmii-id", "tbi",
+ or "rtbi".
Example:
ucc@2000 {
@@ -1574,6 +1577,7 @@
rx-clock = "none";
tx-clock = "clk9";
phy-handle = <212000>;
+ phy-connection-type = "gmii";
pio-handle = <140001>;
};
diff --git a/Documentation/rtc.txt b/Documentation/rtc.txt
index 1ef6bb8..7c701b8 100644
--- a/Documentation/rtc.txt
+++ b/Documentation/rtc.txt
@@ -147,7 +147,7 @@
* RTC_AIE_ON, RTC_AIE_OFF, RTC_ALM_SET, RTC_ALM_READ ... when the RTC
is connected to an IRQ line, it can often issue an alarm IRQ up to
- 24 hours in the future.
+ 24 hours in the future. (Use RTC_WKALM_* by preference.)
* RTC_WKALM_SET, RTC_WKALM_RD ... RTCs that can issue alarms beyond
the next 24 hours use a slightly more powerful API, which supports
@@ -175,10 +175,7 @@
called with appropriate values.
* RTC_ALM_SET, RTC_ALM_READ, RTC_WKALM_SET, RTC_WKALM_RD: the
- set_alarm/read_alarm functions will be called. To differentiate
- between the ALM and WKALM, check the larger fields of the rtc_wkalrm
- struct (like tm_year). These will be set to -1 when using ALM and
- will be set to proper values when using WKALM.
+ set_alarm/read_alarm functions will be called.
* RTC_IRQP_SET, RTC_IRQP_READ: the irq_set_freq function will be called
to set the frequency while the framework will handle the read for you
diff --git a/Documentation/spi/spi-summary b/Documentation/spi/spi-summary
index ecc7c9e..795fbb4 100644
--- a/Documentation/spi/spi-summary
+++ b/Documentation/spi/spi-summary
@@ -8,7 +8,7 @@
The "Serial Peripheral Interface" (SPI) is a synchronous four wire serial
link used to connect microcontrollers to sensors, memory, and peripherals.
-The three signal wires hold a clock (SCLK, often on the order of 10 MHz),
+The three signal wires hold a clock (SCK, often on the order of 10 MHz),
and parallel data lines with "Master Out, Slave In" (MOSI) or "Master In,
Slave Out" (MISO) signals. (Other names are also used.) There are four
clocking modes through which data is exchanged; mode-0 and mode-3 are most
@@ -22,7 +22,7 @@
Unlike serial busses like USB or SMBUS, even low level protocols for
SPI slave functions are usually not interoperable between vendors
-(except for cases like SPI memory chips).
+(except for commodities like SPI memory chips).
- SPI may be used for request/response style device protocols, as with
touchscreen sensors and memory chips.
@@ -77,8 +77,9 @@
How do these driver programming interfaces work?
------------------------------------------------
The <linux/spi/spi.h> header file includes kerneldoc, as does the
-main source code, and you should certainly read that. This is just
-an overview, so you get the big picture before the details.
+main source code, and you should certainly read that chapter of the
+kernel API document. This is just an overview, so you get the big
+picture before those details.
SPI requests always go into I/O queues. Requests for a given SPI device
are always executed in FIFO order, and complete asynchronously through
@@ -88,7 +89,7 @@
There are two types of SPI driver, here called:
- Controller drivers ... these are often built in to System-On-Chip
+ Controller drivers ... controllers may be built in to System-On-Chip
processors, and often support both Master and Slave roles.
These drivers touch hardware registers and may use DMA.
Or they can be PIO bitbangers, needing just GPIO pins.
@@ -108,18 +109,18 @@
programming interface.
There is a minimal core of SPI programming interfaces, focussing on
-using driver model to connect controller and protocol drivers using
+using the driver model to connect controller and protocol drivers using
device tables provided by board specific initialization code. SPI
shows up in sysfs in several locations:
- /sys/devices/.../CTLR/spiB.C ... spi_device for on bus "B",
+ /sys/devices/.../CTLR/spiB.C ... spi_device on bus "B",
chipselect C, accessed through CTLR.
/sys/devices/.../CTLR/spiB.C/modalias ... identifies the driver
that should be used with this device (for hotplug/coldplug)
/sys/bus/spi/devices/spiB.C ... symlink to the physical
- spiB-C device
+ spiB.C device
/sys/bus/spi/drivers/D ... driver for one or more spi*.* devices
@@ -240,7 +241,7 @@
without the chip's driver being loaded. The most troublesome aspect of
that is likely the SPI_CS_HIGH bit in the spi_device.mode field, since
sharing a bus with a device that interprets chipselect "backwards" is
-not possible.
+not possible until the infrastructure knows how to deselect it.
Then your board initialization code would register that table with the SPI
infrastructure, so that it's available later when the SPI master controller
@@ -268,16 +269,14 @@
call at least spi_unregister_device() when that board is removed.
When Linux includes support for MMC/SD/SDIO/DataFlash cards through SPI, those
-configurations will also be dynamic. Fortunately, those devices all support
-basic device identification probes, so that support should hotplug normally.
+configurations will also be dynamic. Fortunately, such devices all support
+basic device identification probes, so they should hotplug normally.
How do I write an "SPI Protocol Driver"?
----------------------------------------
-All SPI drivers are currently kernel drivers. A userspace driver API
-would just be another kernel driver, probably offering some lowlevel
-access through aio_read(), aio_write(), and ioctl() calls and using the
-standard userspace sysfs mechanisms to bind to a given SPI device.
+Most SPI drivers are currently kernel drivers, but there's also support
+for userspace drivers. Here we talk only about kernel drivers.
SPI protocol drivers somewhat resemble platform device drivers:
@@ -319,7 +318,8 @@
As soon as it enters probe(), the driver may issue I/O requests to
the SPI device using "struct spi_message". When remove() returns,
-the driver guarantees that it won't submit any more such messages.
+or after probe() fails, the driver guarantees that it won't submit
+any more such messages.
- An spi_message is a sequence of protocol operations, executed
as one atomic sequence. SPI driver controls include:
@@ -368,7 +368,8 @@
Some drivers may need to modify spi_device characteristics like the
transfer mode, wordsize, or clock rate. This is done with spi_setup(),
which would normally be called from probe() before the first I/O is
-done to the device.
+done to the device. However, that can also be called at any time
+that no message is pending for that device.
While "spi_device" would be the bottom boundary of the driver, the
upper boundaries might include sysfs (especially for sensor readings),
@@ -445,11 +446,15 @@
This sets up the device clock rate, SPI mode, and word sizes.
Drivers may change the defaults provided by board_info, and then
call spi_setup(spi) to invoke this routine. It may sleep.
+ Unless each SPI slave has its own configuration registers, don't
+ change them right away ... otherwise drivers could corrupt I/O
+ that's in progress for other SPI devices.
master->transfer(struct spi_device *spi, struct spi_message *message)
This must not sleep. Its responsibility is arrange that the
- transfer happens and its complete() callback is issued; the two
- will normally happen later, after other transfers complete.
+ transfer happens and its complete() callback is issued. The two
+ will normally happen later, after other transfers complete, and
+ if the controller is idle it will need to be kickstarted.
master->cleanup(struct spi_device *spi)
Your controller driver may use spi_device.controller_state to hold
diff --git a/Documentation/spi/spidev b/Documentation/spi/spidev
new file mode 100644
index 0000000..5c8e1b98
--- /dev/null
+++ b/Documentation/spi/spidev
@@ -0,0 +1,307 @@
+SPI devices have a limited userspace API, supporting basic half-duplex
+read() and write() access to SPI slave devices. Using ioctl() requests,
+full duplex transfers and device I/O configuration are also available.
+
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <sys/ioctl.h>
+ #include <linux/types.h>
+ #include <linux/spi/spidev.h>
+
+Some reasons you might want to use this programming interface include:
+
+ * Prototyping in an environment that's not crash-prone; stray pointers
+ in userspace won't normally bring down any Linux system.
+
+ * Developing simple protocols used to talk to microcontrollers acting
+ as SPI slaves, which you may need to change quite often.
+
+Of course there are drivers that can never be written in userspace, because
+they need to access kernel interfaces (such as IRQ handlers or other layers
+of the driver stack) that are not accessible to userspace.
+
+
+DEVICE CREATION, DRIVER BINDING
+===============================
+The simplest way to arrange to use this driver is to just list it in the
+spi_board_info for a device as the driver it should use: the "modalias"
+entry is "spidev", matching the name of the driver exposing this API.
+Set up the other device characteristics (bits per word, SPI clocking,
+chipselect polarity, etc) as usual, so you won't always need to override
+them later.
+
+(Sysfs also supports userspace driven binding/unbinding of drivers to
+devices. That mechanism might be supported here in the future.)
+
+When you do that, the sysfs node for the SPI device will include a child
+device node with a "dev" attribute that will be understood by udev or mdev.
+(Larger systems will have "udev". Smaller ones may configure "mdev" into
+busybox; it's less featureful, but often enough.) For a SPI device with
+chipselect C on bus B, you should see:
+
+ /dev/spidevB.C ... character special device, major number 153 with
+ a dynamically chosen minor device number. This is the node
+ that userspace programs will open, created by "udev" or "mdev".
+
+ /sys/devices/.../spiB.C ... as usual, the SPI device node will
+ be a child of its SPI master controller.
+
+ /sys/class/spidev/spidevB.C ... created when the "spidev" driver
+ binds to that device. (Directory or symlink, based on whether
+ or not you enabled the "deprecated sysfs files" Kconfig option.)
+
+Do not try to manage the /dev character device special file nodes by hand.
+That's error prone, and you'd need to pay careful attention to system
+security issues; udev/mdev should already be configured securely.
+
+If you unbind the "spidev" driver from that device, those two "spidev" nodes
+(in sysfs and in /dev) should automatically be removed (respectively by the
+kernel and by udev/mdev). You can unbind by removing the "spidev" driver
+module, which will affect all devices using this driver. You can also unbind
+by having kernel code remove the SPI device, probably by removing the driver
+for its SPI controller (so its spi_master vanishes).
+
+Since this is a standard Linux device driver -- even though it just happens
+to expose a low level API to userspace -- it can be associated with any number
+of devices at a time. Just provide one spi_board_info record for each such
+SPI device, and you'll get a /dev device node for each device.
+
+
+BASIC CHARACTER DEVICE API
+==========================
+Normal open() and close() operations on /dev/spidevB.D files work as you
+would expect.
+
+Standard read() and write() operations are obviously only half-duplex, and
+the chipselect is deactivated between those operations. Full-duplex access,
+and composite operation without chipselect de-activation, is available using
+the SPI_IOC_MESSAGE(N) request.
+
+Several ioctl() requests let your driver read or override the device's current
+settings for data transfer parameters:
+
+ SPI_IOC_RD_MODE, SPI_IOC_WR_MODE ... pass a pointer to a byte which will
+ return (RD) or assign (WR) the SPI transfer mode. Use the constants
+ SPI_MODE_0..SPI_MODE_3; or if you prefer you can combine SPI_CPOL
+ (clock polarity, idle high iff this is set) or SPI_CPHA (clock phase,
+ sample on trailing edge iff this is set) flags.
+
+ SPI_IOC_RD_LSB_FIRST, SPI_IOC_WR_LSB_FIRST ... pass a pointer to a byte
+ which will return (RD) or assign (WR) the bit justification used to
+ transfer SPI words. Zero indicates MSB-first; other values indicate
+ the less common LSB-first encoding. In both cases the specified value
+ is right-justified in each word, so that unused (TX) or undefined (RX)
+ bits are in the MSBs.
+
+ SPI_IOC_RD_BITS_PER_WORD, SPI_IOC_WR_BITS_PER_WORD ... pass a pointer to
+ a byte which will return (RD) or assign (WR) the number of bits in
+ each SPI transfer word. The value zero signifies eight bits.
+
+ SPI_IOC_RD_MAX_SPEED_HZ, SPI_IOC_WR_MAX_SPEED_HZ ... pass a pointer to a
+ u32 which will return (RD) or assign (WR) the maximum SPI transfer
+ speed, in Hz. The controller can't necessarily assign that specific
+ clock speed.
+
+NOTES:
+
+ - At this time there is no async I/O support; everything is purely
+ synchronous.
+
+ - There's currently no way to report the actual bit rate used to
+ shift data to/from a given device.
+
+ - From userspace, you can't currently change the chip select polarity;
+ that could corrupt transfers to other devices sharing the SPI bus.
+ Each SPI device is deselected when it's not in active use, allowing
+ other drivers to talk to other devices.
+
+ - There's a limit on the number of bytes each I/O request can transfer
+ to the SPI device. It defaults to one page, but that can be changed
+ using a module parameter.
+
+ - Because SPI has no low-level transfer acknowledgement, you usually
+ won't see any I/O errors when talking to a non-existent device.
+
+
+FULL DUPLEX CHARACTER DEVICE API
+================================
+
+See the sample program below for one example showing the use of the full
+duplex programming interface. (Although it doesn't perform a full duplex
+transfer.) The model is the same as that used in the kernel spi_sync()
+request; the individual transfers offer the same capabilities as are
+available to kernel drivers (except that it's not asynchronous).
+
+The example shows one half-duplex RPC-style request and response message.
+These requests commonly require that the chip not be deselected between
+the request and response. Several such requests could be chained into
+a single kernel request, even allowing the chip to be deselected after
+each response. (Other protocol options include changing the word size
+and bitrate for each transfer segment.)
+
+To make a full duplex request, provide both rx_buf and tx_buf for the
+same transfer. It's even OK if those are the same buffer.
+
+
+SAMPLE PROGRAM
+==============
+
+-------------------------------- CUT HERE
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <linux/types.h>
+#include <linux/spi/spidev.h>
+
+
+static int verbose;
+
+static void do_read(int fd, int len)
+{
+ unsigned char buf[32], *bp;
+ int status;
+
+ /* read at least 2 bytes, no more than 32 */
+ if (len < 2)
+ len = 2;
+ else if (len > sizeof(buf))
+ len = sizeof(buf);
+ memset(buf, 0, sizeof buf);
+
+ status = read(fd, buf, len);
+ if (status < 0) {
+ perror("read");
+ return;
+ }
+ if (status != len) {
+ fprintf(stderr, "short read\n");
+ return;
+ }
+
+ printf("read(%2d, %2d): %02x %02x,", len, status,
+ buf[0], buf[1]);
+ status -= 2;
+ bp = buf + 2;
+ while (status-- > 0)
+ printf(" %02x", *bp++);
+ printf("\n");
+}
+
+static void do_msg(int fd, int len)
+{
+ struct spi_ioc_transfer xfer[2];
+ unsigned char buf[32], *bp;
+ int status;
+
+ memset(xfer, 0, sizeof xfer);
+ memset(buf, 0, sizeof buf);
+
+ if (len > sizeof buf)
+ len = sizeof buf;
+
+ buf[0] = 0xaa;
+ xfer[0].tx_buf = (__u64) buf;
+ xfer[0].len = 1;
+
+ xfer[1].rx_buf = (__u64) buf;
+ xfer[1].len = len;
+
+ status = ioctl(fd, SPI_IOC_MESSAGE(2), xfer);
+ if (status < 0) {
+ perror("SPI_IOC_MESSAGE");
+ return;
+ }
+
+ printf("response(%2d, %2d): ", len, status);
+ for (bp = buf; len; len--)
+ printf(" %02x", *bp++);
+ printf("\n");
+}
+
+static void dumpstat(const char *name, int fd)
+{
+ __u8 mode, lsb, bits;
+ __u32 speed;
+
+ if (ioctl(fd, SPI_IOC_RD_MODE, &mode) < 0) {
+ perror("SPI rd_mode");
+ return;
+ }
+ if (ioctl(fd, SPI_IOC_RD_LSB_FIRST, &lsb) < 0) {
+ perror("SPI rd_lsb_fist");
+ return;
+ }
+ if (ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits) < 0) {
+ perror("SPI bits_per_word");
+ return;
+ }
+ if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0) {
+ perror("SPI max_speed_hz");
+ return;
+ }
+
+ printf("%s: spi mode %d, %d bits %sper word, %d Hz max\n",
+ name, mode, bits, lsb ? "(lsb first) " : "", speed);
+}
+
+int main(int argc, char **argv)
+{
+ int c;
+ int readcount = 0;
+ int msglen = 0;
+ int fd;
+ const char *name;
+
+ while ((c = getopt(argc, argv, "hm:r:v")) != EOF) {
+ switch (c) {
+ case 'm':
+ msglen = atoi(optarg);
+ if (msglen < 0)
+ goto usage;
+ continue;
+ case 'r':
+ readcount = atoi(optarg);
+ if (readcount < 0)
+ goto usage;
+ continue;
+ case 'v':
+ verbose++;
+ continue;
+ case 'h':
+ case '?':
+usage:
+ fprintf(stderr,
+ "usage: %s [-h] [-m N] [-r N] /dev/spidevB.D\n",
+ argv[0]);
+ return 1;
+ }
+ }
+
+ if ((optind + 1) != argc)
+ goto usage;
+ name = argv[optind];
+
+ fd = open(name, O_RDWR);
+ if (fd < 0) {
+ perror("open");
+ return 1;
+ }
+
+ dumpstat(name, fd);
+
+ if (msglen)
+ do_msg(fd, msglen);
+
+ if (readcount)
+ do_read(fd, readcount);
+
+ close(fd);
+ return 0;
+}
diff --git a/Documentation/tty.txt b/Documentation/tty.txt
index 5f799e6..048a876 100644
--- a/Documentation/tty.txt
+++ b/Documentation/tty.txt
@@ -108,7 +108,9 @@
structure:
write() Write a block of characters to the tty device.
- Returns the number of characters accepted.
+ Returns the number of characters accepted. The
+ character buffer passed to this method is already
+ in kernel space.
put_char() Queues a character for writing to the tty device.
If there is no room in the queue, the character is
diff --git a/MAINTAINERS b/MAINTAINERS
index 6d665ac..69f3f66 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -382,6 +382,12 @@
W: http://www.canb.auug.org.au/~sfr/
S: Supported
+APPLE SMC DRIVER
+P: Nicolas Boichat
+M: nicolas@boichat.ch
+L: mactel-linux-devel@lists.sourceforge.net
+S: Maintained
+
APPLETALK NETWORK LAYER
P: Arnaldo Carvalho de Melo
M: acme@ghostprotocols.net
@@ -673,6 +679,7 @@
P: Miguel Ojeda Sandonis
M: maxextreme@gmail.com
L: linux-kernel@vger.kernel.org
+W: http://auxdisplay.googlepages.com/
S: Maintained
AVR32 ARCHITECTURE
@@ -937,12 +944,14 @@
P: Miguel Ojeda Sandonis
M: maxextreme@gmail.com
L: linux-kernel@vger.kernel.org
+W: http://auxdisplay.googlepages.com/
S: Maintained
CFAG12864BFB LCD FRAMEBUFFER DRIVER
P: Miguel Ojeda Sandonis
M: maxextreme@gmail.com
L: linux-kernel@vger.kernel.org
+W: http://auxdisplay.googlepages.com/
S: Maintained
CFG80211 and NL80211
@@ -2021,7 +2030,7 @@
M: vgoyal@in.ibm.com
P: Haren Myneni
M: hbabu@us.ibm.com
-L: fastboot@lists.linux-foundation.org
+L: kexec@lists.infradead.org
L: linux-kernel@vger.kernel.org
W: http://lse.sourceforge.net/kdump/
S: Maintained
@@ -2071,7 +2080,7 @@
M: ebiederm@xmission.com
W: http://www.xmission.com/~ebiederm/files/kexec/
L: linux-kernel@vger.kernel.org
-L: fastboot@lists.linux-foundation.org
+L: kexec@lists.infradead.org
S: Maintained
KPROBES
@@ -2090,6 +2099,7 @@
P: Miguel Ojeda Sandonis
M: maxextreme@gmail.com
L: linux-kernel@vger.kernel.org
+W: http://auxdisplay.googlepages.com/
S: Maintained
LAPB module
@@ -3098,6 +3108,11 @@
W: http://www.nsa.gov/selinux
S: Supported
+SENSABLE PHANTOM
+P: Jiri Slaby
+M: jirislaby@gmail.com
+S: Maintained
+
SERIAL ATA (SATA) SUBSYSTEM:
P: Jeff Garzik
M: jgarzik@pobox.com
diff --git a/arch/alpha/Kconfig.debug b/arch/alpha/Kconfig.debug
index 36d0106..f45f28c 100644
--- a/arch/alpha/Kconfig.debug
+++ b/arch/alpha/Kconfig.debug
@@ -16,14 +16,6 @@
too many attempts. If you suspect a rwlock problem or a kernel
hacker asks for this option then say Y. Otherwise say N.
-config DEBUG_SEMAPHORE
- bool "Semaphore debugging"
- depends on DEBUG_KERNEL
- help
- If you say Y here then semaphore processing will issue lots of
- verbose debugging messages. If you suspect a semaphore problem or a
- kernel hacker asks for this option then say Y. Otherwise say N.
-
config ALPHA_LEGACY_START_ADDRESS
bool "Legacy kernel start address"
depends on ALPHA_GENERIC
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index ea405f5..ce85715 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -953,15 +953,25 @@
asmlinkage int
osf_utimes(char __user *filename, struct timeval32 __user *tvs)
{
- struct timeval ktvs[2];
+ struct timespec tv[2];
if (tvs) {
+ struct timeval ktvs[2];
if (get_tv32(&ktvs[0], &tvs[0]) ||
get_tv32(&ktvs[1], &tvs[1]))
return -EFAULT;
+
+ if (ktvs[0].tv_usec < 0 || ktvs[0].tv_usec >= 1000000 ||
+ ktvs[1].tv_usec < 0 || ktvs[1].tv_usec >= 1000000)
+ return -EINVAL;
+
+ tv[0].tv_sec = ktvs[0].tv_sec;
+ tv[0].tv_nsec = 1000 * ktvs[0].tv_usec;
+ tv[1].tv_sec = ktvs[1].tv_sec;
+ tv[1].tv_nsec = 1000 * ktvs[1].tv_usec;
}
- return do_utimes(AT_FDCWD, filename, tvs ? ktvs : NULL);
+ return do_utimes(AT_FDCWD, filename, tvs ? tv : NULL, 0);
}
#define MAX_SELECT_SECONDS \
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index c151863..92b6162 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -14,7 +14,6 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
index d352c2b..915f263 100644
--- a/arch/alpha/kernel/setup.c
+++ b/arch/alpha/kernel/setup.c
@@ -744,15 +744,6 @@
paging_init();
}
-void __init
-disable_early_printk(void)
-{
- if (alpha_using_srm && srmcons_output) {
- unregister_srm_console();
- srmcons_output = 0;
- }
-}
-
static char sys_unknown[] = "Unknown";
static char systype_names[][16] = {
"0",
diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c
index 741da09..7f64aa7 100644
--- a/arch/alpha/kernel/signal.c
+++ b/arch/alpha/kernel/signal.c
@@ -15,7 +15,6 @@
#include <linux/unistd.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/tty.h>
#include <linux/binfmts.h>
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index d1ec4f5..80cfb75 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -18,7 +18,6 @@
#include <linux/mm.h>
#include <linux/threads.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/delay.h>
diff --git a/arch/alpha/kernel/srmcons.c b/arch/alpha/kernel/srmcons.c
index 85a821a..930cedc 100644
--- a/arch/alpha/kernel/srmcons.c
+++ b/arch/alpha/kernel/srmcons.c
@@ -300,7 +300,7 @@
.write = srm_console_write,
.device = srm_console_device,
.setup = srm_console_setup,
- .flags = CON_PRINTBUFFER,
+ .flags = CON_PRINTBUFFER | CON_BOOT,
.index = -1,
};
diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c
index 8aa9db8..f586279 100644
--- a/arch/alpha/mm/fault.c
+++ b/arch/alpha/mm/fault.c
@@ -21,7 +21,6 @@
#include <linux/ptrace.h>
#include <linux/mman.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/module.h>
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 13af400..6f2f46c 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -13,7 +13,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/ptrace.h>
#include <linux/user.h>
#include <linux/security.h>
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index f05e66b..10ff36e 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -245,8 +245,8 @@
do_exit(SIGSEGV);
}
-void notify_die(const char *str, struct pt_regs *regs, struct siginfo *info,
- unsigned long err, unsigned long trap)
+void arm_notify_die(const char *str, struct pt_regs *regs,
+ struct siginfo *info, unsigned long err, unsigned long trap)
{
if (user_mode(regs)) {
current->thread.error_code = err;
@@ -330,7 +330,7 @@
info.si_code = ILL_ILLOPC;
info.si_addr = pc;
- notify_die("Oops - undefined instruction", regs, &info, 0, 6);
+ arm_notify_die("Oops - undefined instruction", regs, &info, 0, 6);
}
asmlinkage void do_unexp_fiq (struct pt_regs *regs)
@@ -384,7 +384,7 @@
info.si_addr = (void __user *)instruction_pointer(regs) -
(thumb_mode(regs) ? 2 : 4);
- notify_die("Oops - bad syscall", regs, &info, n, 0);
+ arm_notify_die("Oops - bad syscall", regs, &info, n, 0);
return regs->ARM_r0;
}
@@ -428,7 +428,7 @@
info.si_code = SEGV_MAPERR;
info.si_addr = NULL;
- notify_die("branch through zero", regs, &info, 0, 0);
+ arm_notify_die("branch through zero", regs, &info, 0, 0);
return 0;
case NR(breakpoint): /* SWI BREAK_POINT */
@@ -564,7 +564,7 @@
info.si_addr = (void __user *)instruction_pointer(regs) -
(thumb_mode(regs) ? 2 : 4);
- notify_die("Oops - bad syscall(2)", regs, &info, no, 0);
+ arm_notify_die("Oops - bad syscall(2)", regs, &info, no, 0);
return 0;
}
@@ -638,7 +638,7 @@
info.si_code = ILL_ILLOPC;
info.si_addr = (void __user *)addr;
- notify_die("unknown data abort code", regs, &info, instr, 0);
+ arm_notify_die("unknown data abort code", regs, &info, instr, 0);
}
void __attribute__((noreturn)) __bug(const char *file, int line)
diff --git a/arch/arm/mach-aaec2000/core.c b/arch/arm/mach-aaec2000/core.c
index a950160..0446ef2 100644
--- a/arch/arm/mach-aaec2000/core.c
+++ b/arch/arm/mach-aaec2000/core.c
@@ -142,7 +142,7 @@
static struct irqaction aaec2000_timer_irq = {
.name = "AAEC-2000 Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = aaec2000_timer_interrupt,
};
diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c
index 949199a..a634035 100644
--- a/arch/arm/mach-at91/at91rm9200_time.c
+++ b/arch/arm/mach-at91/at91rm9200_time.c
@@ -87,7 +87,7 @@
static struct irqaction at91rm9200_timer_irq = {
.name = "at91_tick",
- .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = at91rm9200_timer_interrupt
};
diff --git a/arch/arm/mach-at91/at91sam926x_time.c b/arch/arm/mach-at91/at91sam926x_time.c
index a4dded2..5c090c9 100644
--- a/arch/arm/mach-at91/at91sam926x_time.c
+++ b/arch/arm/mach-at91/at91sam926x_time.c
@@ -66,7 +66,7 @@
static struct irqaction at91sam926x_timer_irq = {
.name = "at91_tick",
- .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = at91sam926x_timer_interrupt
};
diff --git a/arch/arm/mach-clps711x/time.c b/arch/arm/mach-clps711x/time.c
index 428493d..f428af7 100644
--- a/arch/arm/mach-clps711x/time.c
+++ b/arch/arm/mach-clps711x/time.c
@@ -58,7 +58,7 @@
static struct irqaction clps711x_timer_irq = {
.name = "CLPS711x Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = p720t_timer_interrupt,
};
diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c
index 231b900..4dde34f 100644
--- a/arch/arm/mach-clps7500/core.c
+++ b/arch/arm/mach-clps7500/core.c
@@ -316,7 +316,7 @@
static struct irqaction clps7500_timer_irq = {
.name = "CLPS7500 Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = clps7500_timer_interrupt,
};
diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c
index 8459431..8c1b569 100644
--- a/arch/arm/mach-ebsa110/core.c
+++ b/arch/arm/mach-ebsa110/core.c
@@ -199,7 +199,7 @@
static struct irqaction ebsa110_timer_irq = {
.name = "EBSA110 Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = ebsa110_timer_interrupt,
};
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 829aed6..851cc71 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -116,7 +116,7 @@
static struct irqaction ep93xx_timer_irq = {
.name = "ep93xx timer",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = ep93xx_timer_interrupt,
};
diff --git a/arch/arm/mach-footbridge/dc21285-timer.c b/arch/arm/mach-footbridge/dc21285-timer.c
index fa6be87..3a63941 100644
--- a/arch/arm/mach-footbridge/dc21285-timer.c
+++ b/arch/arm/mach-footbridge/dc21285-timer.c
@@ -44,7 +44,7 @@
static struct irqaction footbridge_timer_irq = {
.name = "Timer1 timer tick",
.handler = timer1_interrupt,
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
};
/*
diff --git a/arch/arm/mach-footbridge/isa-timer.c b/arch/arm/mach-footbridge/isa-timer.c
index d884a39..d08d641 100644
--- a/arch/arm/mach-footbridge/isa-timer.c
+++ b/arch/arm/mach-footbridge/isa-timer.c
@@ -73,7 +73,7 @@
static struct irqaction isa_timer_irq = {
.name = "ISA timer tick",
.handler = isa_timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
};
static void __init isa_timer_init(void)
diff --git a/arch/arm/mach-h720x/cpu-h7201.c b/arch/arm/mach-h720x/cpu-h7201.c
index 13f76bd..9107b8e 100644
--- a/arch/arm/mach-h720x/cpu-h7201.c
+++ b/arch/arm/mach-h720x/cpu-h7201.c
@@ -41,7 +41,7 @@
static struct irqaction h7201_timer_irq = {
.name = "h7201 Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = h7201_timer_interrupt,
};
diff --git a/arch/arm/mach-h720x/cpu-h7202.c b/arch/arm/mach-h720x/cpu-h7202.c
index 703870f..82e420d 100644
--- a/arch/arm/mach-h720x/cpu-h7202.c
+++ b/arch/arm/mach-h720x/cpu-h7202.c
@@ -170,7 +170,7 @@
static struct irqaction h7202_timer_irq = {
.name = "h7202 Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = h7202_timer_interrupt,
};
diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index 2703a73..6960a9d 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -56,7 +56,7 @@
static struct irqaction imx_timer_irq = {
.name = "i.MX Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = imx_timer_interrupt,
};
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index 8d880cb..897c21c 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -282,7 +282,7 @@
static struct irqaction integrator_timer_irq = {
.name = "Integrator Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = integrator_timer_interrupt,
};
diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c
index 9cf2498..cb6ad21 100644
--- a/arch/arm/mach-ixp2000/core.c
+++ b/arch/arm/mach-ixp2000/core.c
@@ -224,7 +224,7 @@
static struct irqaction ixp2000_timer_irq = {
.name = "IXP2000 Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = ixp2000_timer_interrupt,
};
diff --git a/arch/arm/mach-ixp23xx/core.c b/arch/arm/mach-ixp23xx/core.c
index ce6ad63..b644bba 100644
--- a/arch/arm/mach-ixp23xx/core.c
+++ b/arch/arm/mach-ixp23xx/core.c
@@ -363,7 +363,7 @@
static struct irqaction ixp23xx_timer_irq = {
.name = "IXP23xx Timer Tick",
.handler = ixp23xx_timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
};
void __init ixp23xx_init_timer(void)
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index f5cae1e..64685da 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -279,7 +279,7 @@
static struct irqaction ixp4xx_timer_irq = {
.name = "timer1",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = ixp4xx_timer_interrupt,
};
diff --git a/arch/arm/mach-lh7a40x/time.c b/arch/arm/mach-lh7a40x/time.c
index bef3c4b..c25316d 100644
--- a/arch/arm/mach-lh7a40x/time.c
+++ b/arch/arm/mach-lh7a40x/time.c
@@ -53,7 +53,7 @@
static struct irqaction lh7a40x_timer_irq = {
.name = "LHA740x Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = lh7a40x_timer_interrupt,
};
diff --git a/arch/arm/mach-netx/time.c b/arch/arm/mach-netx/time.c
index 7e132fc..4762e20 100644
--- a/arch/arm/mach-netx/time.c
+++ b/arch/arm/mach-netx/time.c
@@ -47,7 +47,7 @@
static struct irqaction netx_timer_irq = {
.name = "NetX Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = netx_timer_interrupt,
};
diff --git a/arch/arm/mach-ns9xxx/time.c b/arch/arm/mach-ns9xxx/time.c
index eec05f1..dd25708 100644
--- a/arch/arm/mach-ns9xxx/time.c
+++ b/arch/arm/mach-ns9xxx/time.c
@@ -53,7 +53,7 @@
static struct irqaction ns9xxx_timer_irq = {
.name = "NS9xxx Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = ns9xxx_timer_interrupt,
};
diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c
index 85e048b..3705d20 100644
--- a/arch/arm/mach-omap1/time.c
+++ b/arch/arm/mach-omap1/time.c
@@ -179,7 +179,7 @@
static struct irqaction omap_mpu_timer1_irq = {
.name = "mpu_timer1",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = omap_mpu_timer1_interrupt,
};
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
index 45d1aaa..62e801e 100644
--- a/arch/arm/mach-omap2/timer-gp.c
+++ b/arch/arm/mach-omap2/timer-gp.c
@@ -52,7 +52,7 @@
static struct irqaction omap2_gp_timer_irq = {
.name = "gp timer",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = omap2_gp_timer_interrupt,
};
diff --git a/arch/arm/mach-pnx4008/time.c b/arch/arm/mach-pnx4008/time.c
index 8621c20..67e05f0 100644
--- a/arch/arm/mach-pnx4008/time.c
+++ b/arch/arm/mach-pnx4008/time.c
@@ -82,7 +82,7 @@
static struct irqaction pnx4008_timer_irq = {
.name = "PNX4008 Tick Timer",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = pnx4008_timer_interrupt
};
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
index fc3b82a..5248abe 100644
--- a/arch/arm/mach-pxa/time.c
+++ b/arch/arm/mach-pxa/time.c
@@ -97,7 +97,7 @@
static struct irqaction pxa_timer_irq = {
.name = "PXA Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = pxa_timer_interrupt,
};
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index 84d3fe7..c7f1b44 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -549,7 +549,7 @@
static struct irqaction realview_timer_irq = {
.name = "RealView Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = realview_timer_interrupt,
};
diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c
index b034ad6..b72fee0 100644
--- a/arch/arm/mach-sa1100/h3600.c
+++ b/arch/arm/mach-sa1100/h3600.c
@@ -740,7 +740,7 @@
static struct irqaction h3800_irq = {
.name = "h3800_asic",
.handler = h3800_IRQ_demux,
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
};
u32 kpio_int_shadow = 0;
diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c
index 29c89f9..416e277 100644
--- a/arch/arm/mach-sa1100/time.c
+++ b/arch/arm/mach-sa1100/time.c
@@ -111,7 +111,7 @@
static struct irqaction sa1100_timer_irq = {
.name = "SA11xx Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = sa1100_timer_interrupt,
};
diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c
index 0e480fa..a0545db 100644
--- a/arch/arm/mach-shark/core.c
+++ b/arch/arm/mach-shark/core.c
@@ -90,7 +90,7 @@
static struct irqaction shark_timer_irq = {
.name = "Shark Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = shark_timer_interrupt,
};
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 1275aa7..a7dd094 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -891,7 +891,7 @@
static struct irqaction versatile_timer_irq = {
.name = "Versatile Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = versatile_timer_interrupt,
};
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 5d9ce7d..75d4914 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -453,7 +453,7 @@
info.si_errno = 0;
info.si_code = inf->code;
info.si_addr = (void __user *)addr;
- notify_die("", regs, &info, fsr, 0);
+ arm_notify_die("", regs, &info, fsr, 0);
}
asmlinkage void __exception
diff --git a/arch/arm/plat-iop/time.c b/arch/arm/plat-iop/time.c
index 0cc26da..100d57a 100644
--- a/arch/arm/plat-iop/time.c
+++ b/arch/arm/plat-iop/time.c
@@ -75,7 +75,7 @@
static struct irqaction iop_timer_irq = {
.name = "IOP Timer Tick",
.handler = iop_timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
};
void __init iop_init_time(unsigned long tick_rate)
diff --git a/arch/arm/plat-omap/timer32k.c b/arch/arm/plat-omap/timer32k.c
index 114f871..2feceec 100644
--- a/arch/arm/plat-omap/timer32k.c
+++ b/arch/arm/plat-omap/timer32k.c
@@ -215,7 +215,7 @@
static struct irqaction omap_32k_timer_irq = {
.name = "32KHz timer",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = omap_32k_timer_interrupt,
};
diff --git a/arch/arm/plat-s3c24xx/time.c b/arch/arm/plat-s3c24xx/time.c
index c523d1c..b766737 100644
--- a/arch/arm/plat-s3c24xx/time.c
+++ b/arch/arm/plat-s3c24xx/time.c
@@ -138,7 +138,7 @@
static struct irqaction s3c2410_timer_irq = {
.name = "S3C2410 Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = s3c2410_timer_interrupt,
};
diff --git a/arch/arm26/kernel/armksyms.c b/arch/arm26/kernel/armksyms.c
index 93293d0..f735d7e 100644
--- a/arch/arm26/kernel/armksyms.c
+++ b/arch/arm26/kernel/armksyms.c
@@ -20,7 +20,6 @@
#include <linux/pm.h>
#include <linux/tty.h>
#include <linux/vt_kern.h>
-#include <linux/smp_lock.h>
#include <linux/syscalls.h>
#include <asm/byteorder.h>
diff --git a/arch/arm26/kernel/ptrace.c b/arch/arm26/kernel/ptrace.c
index 9343889..4169279 100644
--- a/arch/arm26/kernel/ptrace.c
+++ b/arch/arm26/kernel/ptrace.c
@@ -13,7 +13,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/ptrace.h>
#include <linux/user.h>
#include <linux/security.h>
diff --git a/arch/arm26/kernel/signal.c b/arch/arm26/kernel/signal.c
index 6a8ef8d..379b82d 100644
--- a/arch/arm26/kernel/signal.c
+++ b/arch/arm26/kernel/signal.c
@@ -13,7 +13,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/signal.h>
diff --git a/arch/arm26/mm/memc.c b/arch/arm26/mm/memc.c
index f290158..4250554 100644
--- a/arch/arm26/mm/memc.c
+++ b/arch/arm26/mm/memc.c
@@ -176,13 +176,9 @@
{
pte_cache = kmem_cache_create("pte-cache",
sizeof(pte_t) * PTRS_PER_PTE,
- 0, 0, pte_cache_ctor, NULL);
- if (!pte_cache)
- BUG();
+ 0, SLAB_PANIC, pte_cache_ctor, NULL);
pgd_cache = kmem_cache_create("pgd-cache", MEMC_TABLE_SIZE +
sizeof(pgd_t) * PTRS_PER_PGD,
- 0, 0, pgd_cache_ctor, NULL);
- if (!pgd_cache)
- BUG();
+ 0, SLAB_PANIC, pgd_cache_ctor, NULL);
}
diff --git a/arch/avr32/kernel/kprobes.c b/arch/avr32/kernel/kprobes.c
index d0abbca..004c94b 100644
--- a/arch/avr32/kernel/kprobes.c
+++ b/arch/avr32/kernel/kprobes.c
@@ -15,7 +15,7 @@
#include <linux/ptrace.h>
#include <asm/cacheflush.h>
-#include <asm/kdebug.h>
+#include <linux/kdebug.h>
#include <asm/ocd.h>
DEFINE_PER_CPU(struct kprobe *, current_kprobe);
diff --git a/arch/avr32/kernel/ptrace.c b/arch/avr32/kernel/ptrace.c
index 6f4388f..8ac74dd 100644
--- a/arch/avr32/kernel/ptrace.c
+++ b/arch/avr32/kernel/ptrace.c
@@ -9,7 +9,6 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
-#include <linux/smp_lock.h>
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/user.h>
@@ -21,7 +20,7 @@
#include <asm/uaccess.h>
#include <asm/ocd.h>
#include <asm/mmu_context.h>
-#include <asm/kdebug.h>
+#include <linux/kdebug.h>
static struct pt_regs *get_user_regs(struct task_struct *tsk)
{
@@ -300,7 +299,7 @@
else
die_val = DIE_BREAKPOINT;
- if (notify_die(die_val, regs, 0, SIGTRAP) == NOTIFY_STOP)
+ if (notify_die(die_val, "ptrace", regs, 0, 0, SIGTRAP) == NOTIFY_STOP)
return;
if (likely(ds & DS_SSS)) {
diff --git a/arch/avr32/kernel/traps.c b/arch/avr32/kernel/traps.c
index 4f0382d..4de9edf 100644
--- a/arch/avr32/kernel/traps.c
+++ b/arch/avr32/kernel/traps.c
@@ -20,20 +20,6 @@
#include <asm/sysreg.h>
#include <asm/traps.h>
-ATOMIC_NOTIFIER_HEAD(avr32_die_chain);
-
-int register_die_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_register(&avr32_die_chain, nb);
-}
-EXPORT_SYMBOL(register_die_notifier);
-
-int unregister_die_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_unregister(&avr32_die_chain, nb);
-}
-EXPORT_SYMBOL(unregister_die_notifier);
-
static DEFINE_SPINLOCK(die_lock);
void NORET_TYPE die(const char *str, struct pt_regs *regs, long err)
diff --git a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c
index 146ebdb..88b00b1 100644
--- a/arch/avr32/mm/fault.c
+++ b/arch/avr32/mm/fault.c
@@ -13,7 +13,7 @@
#include <linux/module.h>
#include <linux/pagemap.h>
-#include <asm/kdebug.h>
+#include <linux/kdebug.h>
#include <asm/mmu_context.h>
#include <asm/sysreg.h>
#include <asm/tlb.h>
diff --git a/arch/cris/arch-v10/kernel/ptrace.c b/arch/cris/arch-v10/kernel/ptrace.c
index 961c0d5..fd2129a 100644
--- a/arch/cris/arch-v10/kernel/ptrace.c
+++ b/arch/cris/arch-v10/kernel/ptrace.c
@@ -6,7 +6,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
diff --git a/arch/cris/arch-v10/kernel/signal.c b/arch/cris/arch-v10/kernel/signal.c
index 19bcad0..41d4a5f 100644
--- a/arch/cris/arch-v10/kernel/signal.c
+++ b/arch/cris/arch-v10/kernel/signal.c
@@ -16,7 +16,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/cris/arch-v32/drivers/pci/dma.c b/arch/cris/arch-v32/drivers/pci/dma.c
index 70d3bf0..832fc63 100644
--- a/arch/cris/arch-v32/drivers/pci/dma.c
+++ b/arch/cris/arch-v32/drivers/pci/dma.c
@@ -76,7 +76,7 @@
{
void __iomem *mem_base;
int pages = size >> PAGE_SHIFT;
- int bitmap_size = (pages + 31)/32;
+ int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0)
goto out;
diff --git a/arch/cris/arch-v32/kernel/ptrace.c b/arch/cris/arch-v32/kernel/ptrace.c
index 82cf2e3..d4d57b7 100644
--- a/arch/cris/arch-v32/kernel/ptrace.c
+++ b/arch/cris/arch-v32/kernel/ptrace.c
@@ -6,7 +6,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
diff --git a/arch/cris/kernel/crisksyms.c b/arch/cris/kernel/crisksyms.c
index 1f20c16..105bb5e 100644
--- a/arch/cris/kernel/crisksyms.c
+++ b/arch/cris/kernel/crisksyms.c
@@ -4,7 +4,6 @@
#include <linux/sched.h>
#include <linux/in6.h>
#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
#include <linux/pm.h>
#include <linux/kernel.h>
#include <linux/string.h>
diff --git a/arch/cris/kernel/ptrace.c b/arch/cris/kernel/ptrace.c
index 2b6363c..1085d03 100644
--- a/arch/cris/kernel/ptrace.c
+++ b/arch/cris/kernel/ptrace.c
@@ -67,7 +67,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
diff --git a/arch/frv/kernel/irq.c b/arch/frv/kernel/irq.c
index 87f360a..c7e59dc 100644
--- a/arch/frv/kernel/irq.c
+++ b/arch/frv/kernel/irq.c
@@ -18,7 +18,6 @@
#include <linux/timex.h>
#include <linux/slab.h>
#include <linux/random.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/kernel_stat.h>
#include <linux/irq.h>
diff --git a/arch/frv/kernel/ptrace.c b/arch/frv/kernel/ptrace.c
index fcff819..ce88fb9 100644
--- a/arch/frv/kernel/ptrace.c
+++ b/arch/frv/kernel/ptrace.c
@@ -14,7 +14,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
diff --git a/arch/frv/kernel/semaphore.c b/arch/frv/kernel/semaphore.c
index f278cdf..8e182ce 100644
--- a/arch/frv/kernel/semaphore.c
+++ b/arch/frv/kernel/semaphore.c
@@ -19,7 +19,7 @@
struct task_struct *task;
};
-#if SEMAPHORE_DEBUG
+#ifdef CONFIG_DEBUG_SEMAPHORE
void semtrace(struct semaphore *sem, const char *str)
{
if (sem->debug)
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c
index 85baeae..d64bcaf 100644
--- a/arch/frv/kernel/signal.c
+++ b/arch/frv/kernel/signal.c
@@ -13,7 +13,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/frv/kernel/sys_frv.c b/arch/frv/kernel/sys_frv.c
index c4d4348..26b3df3 100644
--- a/arch/frv/kernel/sys_frv.c
+++ b/arch/frv/kernel/sys_frv.c
@@ -14,7 +14,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
diff --git a/arch/frv/mm/pgalloc.c b/arch/frv/mm/pgalloc.c
index 19b13be..598a26a 100644
--- a/arch/frv/mm/pgalloc.c
+++ b/arch/frv/mm/pgalloc.c
@@ -151,9 +151,7 @@
pgd_cache = kmem_cache_create("pgd",
PTRS_PER_PGD * sizeof(pgd_t),
PTRS_PER_PGD * sizeof(pgd_t),
- 0,
+ SLAB_PANIC,
pgd_ctor,
pgd_dtor);
- if (!pgd_cache)
- panic("pgtable_cache_init(): Cannot create pgd cache");
}
diff --git a/arch/h8300/kernel/ptrace.c b/arch/h8300/kernel/ptrace.c
index f603137..8f2411d 100644
--- a/arch/h8300/kernel/ptrace.c
+++ b/arch/h8300/kernel/ptrace.c
@@ -19,7 +19,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
diff --git a/arch/h8300/kernel/sys_h8300.c b/arch/h8300/kernel/sys_h8300.c
index 302a2df..11ba75a 100644
--- a/arch/h8300/kernel/sys_h8300.c
+++ b/arch/h8300/kernel/sys_h8300.c
@@ -10,7 +10,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
diff --git a/arch/i386/boot/video.S b/arch/i386/boot/video.S
index 8143c95..5e2280c 100644
--- a/arch/i386/boot/video.S
+++ b/arch/i386/boot/video.S
@@ -496,9 +496,11 @@
cmpb $VIDEO_FIRST_V7>>8, %ah
jz setv7
+#ifdef CONFIG_FB
cmpb $VIDEO_FIRST_VESA>>8, %ah
jnc check_vesa
-
+#endif
+
orb %ah, %ah
jz setmenu
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
index 4f98516..91cff8d 100644
--- a/arch/i386/kernel/Makefile
+++ b/arch/i386/kernel/Makefile
@@ -34,6 +34,7 @@
obj-$(CONFIG_ACPI_SRAT) += srat.o
obj-$(CONFIG_EFI) += efi.o efi_stub.o
obj-$(CONFIG_DOUBLEFAULT) += doublefault.o
+obj-$(CONFIG_SERIAL_8250) += legacy_serial.o
obj-$(CONFIG_VM86) += vm86.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_HPET_TIMER) += hpet.o
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index aca054c..67824f3 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -19,7 +19,6 @@
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/bootmem.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/mc146818rtc.h>
#include <linux/kernel_stat.h>
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index 367ff1d..4112afe 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -223,7 +223,6 @@
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/dmi.h>
#include <linux/suspend.h>
#include <linux/kthread.h>
@@ -1173,7 +1172,7 @@
unsigned long flags;
spin_lock_irqsave(&i8253_lock, flags);
- /* set the clock to 100 Hz */
+ /* set the clock to HZ */
outb_p(0x34, PIT_MODE); /* binary, mode 2, LSB/MSB, ch 0 */
udelay(10);
outb_p(LATCH & 0xff, PIT_CH0); /* LSB */
diff --git a/arch/i386/kernel/crash.c b/arch/i386/kernel/crash.c
index a5e0e99..53589d1 100644
--- a/arch/i386/kernel/crash.c
+++ b/arch/i386/kernel/crash.c
@@ -22,7 +22,7 @@
#include <asm/nmi.h>
#include <asm/hw_irq.h>
#include <asm/apic.h>
-#include <asm/kdebug.h>
+#include <linux/kdebug.h>
#include <asm/smp.h>
#include <mach_ipi.h>
diff --git a/arch/i386/kernel/efi.c b/arch/i386/kernel/efi.c
index dd9e7fa..a180802 100644
--- a/arch/i386/kernel/efi.c
+++ b/arch/i386/kernel/efi.c
@@ -347,14 +347,12 @@
printk(KERN_ERR PFX "Woah! Couldn't map the EFI system table.\n");
if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
printk(KERN_ERR PFX "Woah! EFI system table signature incorrect\n");
- if ((efi.systab->hdr.revision ^ EFI_SYSTEM_TABLE_REVISION) >> 16 != 0)
- printk(KERN_ERR PFX
- "Warning: EFI system table major version mismatch: "
- "got %d.%02d, expected %d.%02d\n",
+ if ((efi.systab->hdr.revision >> 16) == 0)
+ printk(KERN_ERR PFX "Warning: EFI system table version "
+ "%d.%02d, expected 1.00 or greater\n",
efi.systab->hdr.revision >> 16,
- efi.systab->hdr.revision & 0xffff,
- EFI_SYSTEM_TABLE_REVISION >> 16,
- EFI_SYSTEM_TABLE_REVISION & 0xffff);
+ efi.systab->hdr.revision & 0xffff);
+
/*
* Grab some details from the system table
*/
diff --git a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c
index 03abfdb..0499cbe 100644
--- a/arch/i386/kernel/i8259.c
+++ b/arch/i386/kernel/i8259.c
@@ -5,7 +5,6 @@
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/random.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/kernel_stat.h>
#include <linux/sysdev.h>
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index 1b623cd..7f8b7af 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -25,7 +25,6 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/sched.h>
-#include <linux/smp_lock.h>
#include <linux/mc146818rtc.h>
#include <linux/compiler.h>
#include <linux/acpi.h>
diff --git a/arch/i386/kernel/ioport.c b/arch/i386/kernel/ioport.c
index d1e42e0..3d310a9 100644
--- a/arch/i386/kernel/ioport.c
+++ b/arch/i386/kernel/ioport.c
@@ -12,7 +12,6 @@
#include <linux/types.h>
#include <linux/ioport.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/slab.h>
#include <linux/thread_info.h>
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c
index b545bc7..dde828a 100644
--- a/arch/i386/kernel/kprobes.c
+++ b/arch/i386/kernel/kprobes.c
@@ -31,8 +31,8 @@
#include <linux/kprobes.h>
#include <linux/ptrace.h>
#include <linux/preempt.h>
+#include <linux/kdebug.h>
#include <asm/cacheflush.h>
-#include <asm/kdebug.h>
#include <asm/desc.h>
#include <asm/uaccess.h>
@@ -226,24 +226,15 @@
}
/* Called with kretprobe_lock held */
-void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
+void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
struct pt_regs *regs)
{
unsigned long *sara = (unsigned long *)®s->esp;
- struct kretprobe_instance *ri;
+ ri->ret_addr = (kprobe_opcode_t *) *sara;
- if ((ri = get_free_rp_inst(rp)) != NULL) {
- ri->rp = rp;
- ri->task = current;
- ri->ret_addr = (kprobe_opcode_t *) *sara;
-
- /* Replace the return addr with trampoline addr */
- *sara = (unsigned long) &kretprobe_trampoline;
- add_rp_inst(ri);
- } else {
- rp->nmissed++;
- }
+ /* Replace the return addr with trampoline addr */
+ *sara = (unsigned long) &kretprobe_trampoline;
}
/*
@@ -449,8 +440,7 @@
break;
}
- BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
-
+ kretprobe_assert(ri, orig_ret_address, trampoline_address);
spin_unlock_irqrestore(&kretprobe_lock, flags);
hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
@@ -753,6 +743,11 @@
return 0;
}
+int __kprobes arch_trampoline_kprobe(struct kprobe *p)
+{
+ return 0;
+}
+
int __init arch_init_kprobes(void)
{
return 0;
diff --git a/arch/i386/kernel/ldt.c b/arch/i386/kernel/ldt.c
index b410e5f..e0b2d17 100644
--- a/arch/i386/kernel/ldt.c
+++ b/arch/i386/kernel/ldt.c
@@ -10,7 +10,6 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/vmalloc.h>
#include <linux/slab.h>
diff --git a/arch/i386/kernel/legacy_serial.c b/arch/i386/kernel/legacy_serial.c
new file mode 100644
index 0000000..2151011
--- /dev/null
+++ b/arch/i386/kernel/legacy_serial.c
@@ -0,0 +1,67 @@
+/*
+ * Legacy COM port devices for x86 platforms without PNPBIOS or ACPI.
+ * Data taken from include/asm-i386/serial.h.
+ *
+ * (c) Copyright 2007 Hewlett-Packard Development Company, L.P.
+ * Bjorn Helgaas <bjorn.helgaas@hp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pnp.h>
+#include <linux/serial_8250.h>
+
+/* Standard COM flags (except for COM4, because of the 8514 problem) */
+#ifdef CONFIG_SERIAL_DETECT_IRQ
+#define COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ)
+#define COM4_FLAGS (UPF_BOOT_AUTOCONF | UPF_AUTO_IRQ)
+#else
+#define COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST)
+#define COM4_FLAGS UPF_BOOT_AUTOCONF
+#endif
+
+#define PORT(_base,_irq,_flags) \
+ { \
+ .iobase = _base, \
+ .irq = _irq, \
+ .uartclk = 1843200, \
+ .iotype = UPIO_PORT, \
+ .flags = _flags, \
+ }
+
+static struct plat_serial8250_port x86_com_data[] = {
+ PORT(0x3F8, 4, COM_FLAGS),
+ PORT(0x2F8, 3, COM_FLAGS),
+ PORT(0x3E8, 4, COM_FLAGS),
+ PORT(0x2E8, 3, COM4_FLAGS),
+ { },
+};
+
+static struct platform_device x86_com_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = x86_com_data,
+ },
+};
+
+static int force_legacy_probe;
+module_param_named(force, force_legacy_probe, bool, 0);
+MODULE_PARM_DESC(force, "Force legacy serial port probe");
+
+static int __init serial8250_x86_com_init(void)
+{
+ if (pnp_platform_devices && !force_legacy_probe)
+ return -ENODEV;
+
+ return platform_device_register(&x86_com_device);
+}
+
+module_init(serial8250_x86_com_init);
+
+MODULE_AUTHOR("Bjorn Helgaas");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Generic 8250/16x50 legacy probe module");
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
index 0952ecc..13abb4e 100644
--- a/arch/i386/kernel/mpparse.c
+++ b/arch/i386/kernel/mpparse.c
@@ -18,7 +18,6 @@
#include <linux/acpi.h>
#include <linux/delay.h>
#include <linux/bootmem.h>
-#include <linux/smp_lock.h>
#include <linux/kernel_stat.h>
#include <linux/mc146818rtc.h>
#include <linux/bitops.h>
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
index 33cf2f3..fba121f 100644
--- a/arch/i386/kernel/nmi.c
+++ b/arch/i386/kernel/nmi.c
@@ -23,10 +23,10 @@
#include <linux/kprobes.h>
#include <linux/cpumask.h>
#include <linux/kernel_stat.h>
+#include <linux/kdebug.h>
#include <asm/smp.h>
#include <asm/nmi.h>
-#include <asm/kdebug.h>
#include "mach_traps.h"
diff --git a/arch/i386/kernel/pci-dma.c b/arch/i386/kernel/pci-dma.c
index 3ebcea0..30b754f 100644
--- a/arch/i386/kernel/pci-dma.c
+++ b/arch/i386/kernel/pci-dma.c
@@ -77,7 +77,7 @@
{
void __iomem *mem_base = NULL;
int pages = size >> PAGE_SHIFT;
- int bitmap_size = (pages + 31)/32;
+ int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0)
goto out;
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 6199947..d76d9bc 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -21,7 +21,6 @@
#include <linux/mm.h>
#include <linux/elfcore.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index 4a8f8a2..0c0ceec 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -9,7 +9,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c
index 4f99e87..d574e38 100644
--- a/arch/i386/kernel/signal.c
+++ b/arch/i386/kernel/signal.c
@@ -10,7 +10,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c
index 89a45a9..93f202a 100644
--- a/arch/i386/kernel/smp.c
+++ b/arch/i386/kernel/smp.c
@@ -13,7 +13,6 @@
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
#include <linux/kernel_stat.h>
#include <linux/mc146818rtc.h>
#include <linux/cache.h>
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index a4b7ad2..b92cc4e 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -40,7 +40,6 @@
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/kernel_stat.h>
-#include <linux/smp_lock.h>
#include <linux/bootmem.h>
#include <linux/notifier.h>
#include <linux/cpu.h>
diff --git a/arch/i386/kernel/sys_i386.c b/arch/i386/kernel/sys_i386.c
index 4048397..e5dcb93 100644
--- a/arch/i386/kernel/sys_i386.c
+++ b/arch/i386/kernel/sys_i386.c
@@ -10,7 +10,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S
index 2697e92..0772678 100644
--- a/arch/i386/kernel/syscall_table.S
+++ b/arch/i386/kernel/syscall_table.S
@@ -319,3 +319,4 @@
.long sys_move_pages
.long sys_getcpu
.long sys_epoll_pwait
+ .long sys_utimensat /* 320 */
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index f21b41e..4bec0cb 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -52,7 +52,7 @@
#include <asm/unwind.h>
#include <asm/smp.h>
#include <asm/arch_hooks.h>
-#include <asm/kdebug.h>
+#include <linux/kdebug.h>
#include <asm/stacktrace.h>
#include <linux/module.h>
@@ -95,20 +95,6 @@
int kstack_depth_to_print = 24;
static unsigned int code_bytes = 64;
-ATOMIC_NOTIFIER_HEAD(i386die_chain);
-
-int register_die_notifier(struct notifier_block *nb)
-{
- vmalloc_sync_all();
- return atomic_notifier_chain_register(&i386die_chain, nb);
-}
-EXPORT_SYMBOL(register_die_notifier); /* used modular by kdb */
-
-int unregister_die_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_unregister(&i386die_chain, nb);
-}
-EXPORT_SYMBOL(unregister_die_notifier); /* used modular by kdb */
static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
{
@@ -747,6 +733,11 @@
*/
if (nmi_watchdog_tick(regs, reason))
return;
+#endif
+ if (notify_die(DIE_NMI_POST, "nmi_post", regs, reason, 2, 0)
+ == NOTIFY_STOP)
+ return;
+#ifdef CONFIG_X86_LOCAL_APIC
if (!do_nmi_callback(regs, smp_processor_id()))
#endif
unknown_nmi_error(reason, regs);
diff --git a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c
index d1b8f2b..f2dcd1d 100644
--- a/arch/i386/kernel/vm86.c
+++ b/arch/i386/kernel/vm86.c
@@ -39,7 +39,6 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/highmem.h>
#include <linux/ptrace.h>
#include <linux/audit.h>
diff --git a/arch/i386/mach-default/setup.c b/arch/i386/mach-default/setup.c
index c788162..7f635c7 100644
--- a/arch/i386/mach-default/setup.c
+++ b/arch/i386/mach-default/setup.c
@@ -81,7 +81,7 @@
static struct irqaction irq0 = {
.handler = timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_NOBALANCING,
+ .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL,
.mask = CPU_MASK_NONE,
.name = "timer"
};
diff --git a/arch/i386/mach-visws/setup.c b/arch/i386/mach-visws/setup.c
index 233ee20..1f81f10 100644
--- a/arch/i386/mach-visws/setup.c
+++ b/arch/i386/mach-visws/setup.c
@@ -116,7 +116,7 @@
static struct irqaction irq0 = {
.handler = timer_interrupt,
- .flags = IRQF_DISABLED,
+ .flags = IRQF_DISABLED | IRQF_IRQPOLL,
.name = "timer",
};
diff --git a/arch/i386/mach-visws/visws_apic.c b/arch/i386/mach-visws/visws_apic.c
index 38c2b13..710faf7 100644
--- a/arch/i386/mach-visws/visws_apic.c
+++ b/arch/i386/mach-visws/visws_apic.c
@@ -18,7 +18,6 @@
#include <linux/kernel_stat.h>
#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <asm/io.h>
diff --git a/arch/i386/mach-voyager/setup.c b/arch/i386/mach-voyager/setup.c
index 447bb10..2b55694 100644
--- a/arch/i386/mach-voyager/setup.c
+++ b/arch/i386/mach-voyager/setup.c
@@ -42,7 +42,7 @@
static struct irqaction irq0 = {
.handler = timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_NOBALANCING,
+ .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL,
.mask = CPU_MASK_NONE,
.name = "timer"
};
diff --git a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c
index 1a5e448..50d9c52 100644
--- a/arch/i386/mach-voyager/voyager_smp.c
+++ b/arch/i386/mach-voyager/voyager_smp.c
@@ -16,7 +16,6 @@
#include <linux/mc146818rtc.h>
#include <linux/cache.h>
#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/bootmem.h>
diff --git a/arch/i386/mach-voyager/voyager_thread.c b/arch/i386/mach-voyager/voyager_thread.c
index fdc1d92..b4b24e0 100644
--- a/arch/i386/mach-voyager/voyager_thread.c
+++ b/arch/i386/mach-voyager/voyager_thread.c
@@ -18,7 +18,6 @@
#include <linux/kernel_stat.h>
#include <linux/delay.h>
#include <linux/mc146818rtc.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/bootmem.h>
#include <linux/kmod.h>
diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c
index f534c29..29d7d61 100644
--- a/arch/i386/mm/fault.c
+++ b/arch/i386/mm/fault.c
@@ -14,20 +14,20 @@
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/tty.h>
#include <linux/vt_kern.h> /* For unblank_screen() */
#include <linux/highmem.h>
#include <linux/bootmem.h> /* for max_low_pfn */
+#include <linux/vmalloc.h>
#include <linux/module.h>
#include <linux/kprobes.h>
#include <linux/uaccess.h>
+#include <linux/kdebug.h>
#include <asm/system.h>
#include <asm/desc.h>
-#include <asm/kdebug.h>
#include <asm/segment.h>
extern void die(const char *,struct pt_regs *,long);
diff --git a/arch/i386/mm/hugetlbpage.c b/arch/i386/mm/hugetlbpage.c
index 6272a4f..efdf95a 100644
--- a/arch/i386/mm/hugetlbpage.c
+++ b/arch/i386/mm/hugetlbpage.c
@@ -9,7 +9,6 @@
#include <linux/mm.h>
#include <linux/hugetlb.h>
#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/sysctl.h>
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index 1a7197e..c50782e 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -751,12 +751,9 @@
pmd_cache = kmem_cache_create("pmd",
PTRS_PER_PMD*sizeof(pmd_t),
PTRS_PER_PMD*sizeof(pmd_t),
- 0,
+ SLAB_PANIC,
pmd_ctor,
NULL);
- if (!pmd_cache)
- panic("pgtable_cache_init(): cannot create pmd cache");
-
if (!SHARED_KERNEL_PMD) {
/* If we're in PAE mode and have a non-shared
kernel pmd, then the pgd size must be a
@@ -770,11 +767,9 @@
pgd_cache = kmem_cache_create("pgd",
pgd_size,
pgd_size,
- 0,
+ SLAB_PANIC,
pgd_ctor,
(!SHARED_KERNEL_PMD) ? pgd_dtor : NULL);
- if (!pgd_cache)
- panic("pgtable_cache_init(): Cannot create pgd cache");
}
/*
diff --git a/arch/i386/oprofile/nmi_int.c b/arch/i386/oprofile/nmi_int.c
index 695f737..8e18520 100644
--- a/arch/i386/oprofile/nmi_int.c
+++ b/arch/i386/oprofile/nmi_int.c
@@ -14,10 +14,10 @@
#include <linux/sysdev.h>
#include <linux/slab.h>
#include <linux/moduleparam.h>
+#include <linux/kdebug.h>
#include <asm/nmi.h>
#include <asm/msr.h>
#include <asm/apic.h>
-#include <asm/kdebug.h>
#include "op_counter.h"
#include "op_x86_model.h"
diff --git a/arch/i386/oprofile/nmi_timer_int.c b/arch/i386/oprofile/nmi_timer_int.c
index abf0ba5..1418e36 100644
--- a/arch/i386/oprofile/nmi_timer_int.c
+++ b/arch/i386/oprofile/nmi_timer_int.c
@@ -12,12 +12,11 @@
#include <linux/errno.h>
#include <linux/oprofile.h>
#include <linux/rcupdate.h>
-
+#include <linux/kdebug.h>
#include <asm/nmi.h>
#include <asm/apic.h>
#include <asm/ptrace.h>
-#include <asm/kdebug.h>
static int profile_timer_exceptions_notify(struct notifier_block *self,
unsigned long val, void *data)
diff --git a/arch/ia64/hp/sim/boot/fw-emu.c b/arch/ia64/hp/sim/boot/fw-emu.c
index 5a0a7af..300acd9 100644
--- a/arch/ia64/hp/sim/boot/fw-emu.c
+++ b/arch/ia64/hp/sim/boot/fw-emu.c
@@ -287,7 +287,7 @@
memset(efi_systab, 0, sizeof(efi_systab));
efi_systab->hdr.signature = EFI_SYSTEM_TABLE_SIGNATURE;
- efi_systab->hdr.revision = EFI_SYSTEM_TABLE_REVISION;
+ efi_systab->hdr.revision = ((1 << 16) | 00);
efi_systab->hdr.headersize = sizeof(efi_systab->hdr);
efi_systab->fw_vendor = __pa("H\0e\0w\0l\0e\0t\0t\0-\0P\0a\0c\0k\0a\0r\0d\0\0");
efi_systab->fw_revision = 1;
diff --git a/arch/ia64/ia32/ia32_ldt.c b/arch/ia64/ia32/ia32_ldt.c
index a152738..16d51c1 100644
--- a/arch/ia64/ia32/ia32_ldt.c
+++ b/arch/ia64/ia32/ia32_ldt.c
@@ -10,7 +10,6 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/vmalloc.h>
#include <asm/uaccess.h>
diff --git a/arch/ia64/ia32/ia32_signal.c b/arch/ia64/ia32/ia32_signal.c
index b3355a9..10510e5 100644
--- a/arch/ia64/ia32/ia32_signal.c
+++ b/arch/ia64/ia32/ia32_signal.c
@@ -18,7 +18,6 @@
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/syscalls.h>
#include <linux/unistd.h>
diff --git a/arch/ia64/ia32/ia32_support.c b/arch/ia64/ia32/ia32_support.c
index 6af400a..beea7a0 100644
--- a/arch/ia64/ia32/ia32_support.c
+++ b/arch/ia64/ia32/ia32_support.c
@@ -252,10 +252,8 @@
extern struct kmem_cache *partial_page_cachep;
partial_page_cachep = kmem_cache_create("partial_page_cache",
- sizeof(struct partial_page), 0, 0,
- NULL, NULL);
- if (!partial_page_cachep)
- panic("Cannot create partial page SLAB cache");
+ sizeof(struct partial_page),
+ 0, SLAB_PANIC, NULL, NULL);
}
#endif
return 0;
diff --git a/arch/ia64/kernel/crash.c b/arch/ia64/kernel/crash.c
index 80a94e7..aeb79fb 100644
--- a/arch/ia64/kernel/crash.c
+++ b/arch/ia64/kernel/crash.c
@@ -16,8 +16,8 @@
#include <linux/elfcore.h>
#include <linux/sysctl.h>
#include <linux/init.h>
+#include <linux/kdebug.h>
-#include <asm/kdebug.h>
#include <asm/mca.h>
int kdump_status[NR_CPUS];
@@ -74,7 +74,7 @@
buf = (u64 *) per_cpu_ptr(crash_notes, cpu);
if (!buf)
return;
- buf = append_elf_note(buf, "CORE", NT_PRSTATUS, prstatus,
+ buf = append_elf_note(buf, KEXEC_CORE_NOTE_NAME, NT_PRSTATUS, prstatus,
sizeof(*prstatus));
final_note(buf);
}
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index 78d29b7..75ec347 100644
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -445,11 +445,11 @@
panic("Woah! Can't find EFI system table.\n");
if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
panic("Woah! EFI system table signature incorrect\n");
- if ((efi.systab->hdr.revision ^ EFI_SYSTEM_TABLE_REVISION) >> 16 != 0)
- printk(KERN_WARNING "Warning: EFI system table major version mismatch: "
- "got %d.%02d, expected %d.%02d\n",
- efi.systab->hdr.revision >> 16, efi.systab->hdr.revision & 0xffff,
- EFI_SYSTEM_TABLE_REVISION >> 16, EFI_SYSTEM_TABLE_REVISION & 0xffff);
+ if ((efi.systab->hdr.revision >> 16) == 0)
+ printk(KERN_WARNING "Warning: EFI system table version "
+ "%d.%02d, expected 1.00 or greater\n",
+ efi.systab->hdr.revision >> 16,
+ efi.systab->hdr.revision & 0xffff);
config_tables = __va(efi.systab->tables);
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index dcfbf3e..93d9ab1 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -87,7 +87,6 @@
#include <linux/list.h>
#include <linux/pci.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/string.h>
#include <linux/bootmem.h>
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c
index 456f57b..1c5044a 100644
--- a/arch/ia64/kernel/irq_ia64.c
+++ b/arch/ia64/kernel/irq_ia64.c
@@ -27,7 +27,6 @@
#include <linux/random.h> /* for rand_initialize_irq() */
#include <linux/signal.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/threads.h>
#include <linux/bitops.h>
#include <linux/irq.h>
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c
index 6cb56dd..4f5fd09 100644
--- a/arch/ia64/kernel/kprobes.c
+++ b/arch/ia64/kernel/kprobes.c
@@ -29,9 +29,9 @@
#include <linux/slab.h>
#include <linux/preempt.h>
#include <linux/moduleloader.h>
+#include <linux/kdebug.h>
#include <asm/pgtable.h>
-#include <asm/kdebug.h>
#include <asm/sections.h>
#include <asm/uaccess.h>
@@ -444,7 +444,8 @@
break;
}
- BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
+ kretprobe_assert(ri, orig_ret_address, trampoline_address);
+
regs->cr_iip = orig_ret_address;
reset_current_kprobe();
@@ -464,23 +465,13 @@
}
/* Called with kretprobe_lock held */
-void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
+void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
struct pt_regs *regs)
{
- struct kretprobe_instance *ri;
+ ri->ret_addr = (kprobe_opcode_t *)regs->b0;
- if ((ri = get_free_rp_inst(rp)) != NULL) {
- ri->rp = rp;
- ri->task = current;
- ri->ret_addr = (kprobe_opcode_t *)regs->b0;
-
- /* Replace the return addr with trampoline addr */
- regs->b0 = ((struct fnptr *)kretprobe_trampoline)->ip;
-
- add_rp_inst(ri);
- } else {
- rp->nmissed++;
- }
+ /* Replace the return addr with trampoline addr */
+ regs->b0 = ((struct fnptr *)kretprobe_trampoline)->ip;
}
int __kprobes arch_prepare_kprobe(struct kprobe *p)
@@ -1021,3 +1012,12 @@
(kprobe_opcode_t *)((struct fnptr *)kretprobe_trampoline)->ip;
return register_kprobe(&trampoline_p);
}
+
+int __kprobes arch_trampoline_kprobe(struct kprobe *p)
+{
+ if (p->addr ==
+ (kprobe_opcode_t *)((struct fnptr *)kretprobe_trampoline)->ip)
+ return 1;
+
+ return 0;
+}
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
index 491687f..1d7cc7e 100644
--- a/arch/ia64/kernel/mca.c
+++ b/arch/ia64/kernel/mca.c
@@ -63,7 +63,6 @@
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
-#include <linux/smp_lock.h>
#include <linux/bootmem.h>
#include <linux/acpi.h>
#include <linux/timer.h>
@@ -72,9 +71,9 @@
#include <linux/smp.h>
#include <linux/workqueue.h>
#include <linux/cpumask.h>
+#include <linux/kdebug.h>
#include <asm/delay.h>
-#include <asm/kdebug.h>
#include <asm/machvec.h>
#include <asm/meminit.h>
#include <asm/page.h>
diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c
index 832cf1e..70b8bdb 100644
--- a/arch/ia64/kernel/mca_drv.c
+++ b/arch/ia64/kernel/mca_drv.c
@@ -14,7 +14,6 @@
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/kallsyms.h>
-#include <linux/smp_lock.h>
#include <linux/bootmem.h>
#include <linux/acpi.h>
#include <linux/timer.h>
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index abc7ad0..e7191ca 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -23,7 +23,6 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/init.h>
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index ae96d41..8bb571a 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -20,20 +20,19 @@
#include <linux/personality.h>
#include <linux/sched.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/thread_info.h>
#include <linux/unistd.h>
#include <linux/efi.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
+#include <linux/kdebug.h>
#include <asm/cpu.h>
#include <asm/delay.h>
#include <asm/elf.h>
#include <asm/ia32.h>
#include <asm/irq.h>
-#include <asm/kdebug.h>
#include <asm/kexec.h>
#include <asm/pgalloc.h>
#include <asm/processor.h>
diff --git a/arch/ia64/kernel/salinfo.c b/arch/ia64/kernel/salinfo.c
index af9f875..a51f1d0 100644
--- a/arch/ia64/kernel/salinfo.c
+++ b/arch/ia64/kernel/salinfo.c
@@ -42,7 +42,6 @@
#include <linux/proc_fs.h>
#include <linux/module.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/timer.h>
#include <linux/vmalloc.h>
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
index 77f8b49..0dcd56da 100644
--- a/arch/ia64/kernel/signal.c
+++ b/arch/ia64/kernel/signal.c
@@ -14,7 +14,6 @@
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/tty.h>
#include <linux/binfmts.h>
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
index ff7df43..a44792d 100644
--- a/arch/ia64/kernel/smpboot.c
+++ b/arch/ia64/kernel/smpboot.c
@@ -35,7 +35,6 @@
#include <linux/mm.h>
#include <linux/notifier.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/efi.h>
#include <linux/percpu.h>
diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c
index 2fcaa20..1eda194 100644
--- a/arch/ia64/kernel/sys_ia64.c
+++ b/arch/ia64/kernel/sys_ia64.c
@@ -13,7 +13,6 @@
#include <linux/shm.h>
#include <linux/file.h> /* doh, must come after sched.h... */
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/syscalls.h>
#include <linux/highuid.h>
#include <linux/hugetlb.h>
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index 39e0cd3..a06667c 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -235,7 +235,7 @@
static struct irqaction timer_irqaction = {
.handler = timer_interrupt,
- .flags = IRQF_DISABLED,
+ .flags = IRQF_DISABLED | IRQF_IRQPOLL,
.name = "timer"
};
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c
index 765cbe5..5bfb8be 100644
--- a/arch/ia64/kernel/traps.c
+++ b/arch/ia64/kernel/traps.c
@@ -16,33 +16,17 @@
#include <linux/hardirq.h>
#include <linux/kprobes.h>
#include <linux/delay.h> /* for ssleep() */
+#include <linux/kdebug.h>
#include <asm/fpswa.h>
#include <asm/ia32.h>
#include <asm/intrinsics.h>
#include <asm/processor.h>
#include <asm/uaccess.h>
-#include <asm/kdebug.h>
fpswa_interface_t *fpswa_interface;
EXPORT_SYMBOL(fpswa_interface);
-ATOMIC_NOTIFIER_HEAD(ia64die_chain);
-
-int
-register_die_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_register(&ia64die_chain, nb);
-}
-EXPORT_SYMBOL_GPL(register_die_notifier);
-
-int
-unregister_die_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_unregister(&ia64die_chain, nb);
-}
-EXPORT_SYMBOL_GPL(unregister_die_notifier);
-
void __init
trap_init (void)
{
diff --git a/arch/ia64/kernel/unaligned.c b/arch/ia64/kernel/unaligned.c
index 1e35755..fe6aa5a 100644
--- a/arch/ia64/kernel/unaligned.c
+++ b/arch/ia64/kernel/unaligned.c
@@ -15,7 +15,6 @@
*/
#include <linux/kernel.h>
#include <linux/sched.h>
-#include <linux/smp_lock.h>
#include <linux/tty.h>
#include <asm/intrinsics.h>
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
index 872da7a..9484444 100644
--- a/arch/ia64/mm/discontig.c
+++ b/arch/ia64/mm/discontig.c
@@ -693,6 +693,7 @@
zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page));
}
+#ifdef CONFIG_MEMORY_HOTPLUG
pg_data_t *arch_alloc_nodedata(int nid)
{
unsigned long size = compute_pernodesize(nid);
@@ -710,3 +711,4 @@
pgdat_list[update_node] = update_pgdat;
scatter_node_data();
}
+#endif
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
index 59f3ab9..21658e0 100644
--- a/arch/ia64/mm/fault.c
+++ b/arch/ia64/mm/fault.c
@@ -7,15 +7,14 @@
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/kprobes.h>
+#include <linux/kdebug.h>
#include <asm/pgtable.h>
#include <asm/processor.h>
#include <asm/system.h>
#include <asm/uaccess.h>
-#include <asm/kdebug.h>
extern void die (char *, struct pt_regs *, long);
diff --git a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c
index c7c90f4..1346b7f 100644
--- a/arch/ia64/mm/hugetlbpage.c
+++ b/arch/ia64/mm/hugetlbpage.c
@@ -13,7 +13,6 @@
#include <linux/mm.h>
#include <linux/hugetlb.h>
#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/sysctl.h>
#include <asm/mman.h>
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 9f63589..3549f3b 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -18,7 +18,6 @@
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <asm/machvec.h>
diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c
index 68355ef..e336e16 100644
--- a/arch/ia64/sn/kernel/xpc_main.c
+++ b/arch/ia64/sn/kernel/xpc_main.c
@@ -55,9 +55,9 @@
#include <linux/delay.h>
#include <linux/reboot.h>
#include <linux/completion.h>
+#include <linux/kdebug.h>
#include <asm/sn/intr.h>
#include <asm/sn/sn_sal.h>
-#include <asm/kdebug.h>
#include <asm/uaccess.h>
#include <asm/sn/xpc.h>
@@ -1332,7 +1332,7 @@
dev_warn(xpc_part, "can't register reboot notifier\n");
}
- /* add ourselves to the die_notifier list (i.e., ia64die_chain) */
+ /* add ourselves to the die_notifier list */
ret = register_die_notifier(&xpc_die_notifier);
if (ret != 0) {
dev_warn(xpc_part, "can't register die notifier\n");
diff --git a/arch/m32r/kernel/m32r_ksyms.c b/arch/m32r/kernel/m32r_ksyms.c
index 8cbbb0b..41a4c95 100644
--- a/arch/m32r/kernel/m32r_ksyms.c
+++ b/arch/m32r/kernel/m32r_ksyms.c
@@ -5,7 +5,6 @@
#include <linux/sched.h>
#include <linux/in6.h>
#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
#include <linux/string.h>
#include <asm/semaphore.h>
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c
index 4b15605..916faf6 100644
--- a/arch/m32r/kernel/signal.c
+++ b/arch/m32r/kernel/signal.c
@@ -13,7 +13,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/m32r/kernel/smpboot.c b/arch/m32r/kernel/smpboot.c
index 48d376f..3eb3059 100644
--- a/arch/m32r/kernel/smpboot.c
+++ b/arch/m32r/kernel/smpboot.c
@@ -43,7 +43,6 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/mm.h>
-#include <linux/smp_lock.h>
#include <linux/irq.h>
#include <linux/bootmem.h>
#include <linux/delay.h>
diff --git a/arch/m32r/kernel/sys_m32r.c b/arch/m32r/kernel/sys_m32r.c
index b4e7bcb..bda8554 100644
--- a/arch/m32r/kernel/sys_m32r.c
+++ b/arch/m32r/kernel/sys_m32r.c
@@ -11,7 +11,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
diff --git a/arch/m32r/mm/fault-nommu.c b/arch/m32r/mm/fault-nommu.c
index 9880aba..8846917 100644
--- a/arch/m32r/mm/fault-nommu.c
+++ b/arch/m32r/mm/fault-nommu.c
@@ -17,7 +17,6 @@
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/vt_kern.h> /* For unblank_screen() */
diff --git a/arch/m32r/mm/fault.c b/arch/m32r/mm/fault.c
index 037d58e..f3935ba 100644
--- a/arch/m32r/mm/fault.c
+++ b/arch/m32r/mm/fault.c
@@ -18,7 +18,6 @@
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/tty.h>
diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c
index 7fd2720..cdba9fd 100644
--- a/arch/m68k/kernel/ptrace.c
+++ b/arch/m68k/kernel/ptrace.c
@@ -14,7 +14,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
diff --git a/arch/m68k/mvme16x/rtc.c b/arch/m68k/mvme16x/rtc.c
index 272d47e..e341387 100644
--- a/arch/m68k/mvme16x/rtc.c
+++ b/arch/m68k/mvme16x/rtc.c
@@ -16,7 +16,6 @@
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/mc146818rtc.h> /* For struct rtc_time and ioctls, etc */
-#include <linux/smp_lock.h>
#include <linux/bcd.h>
#include <asm/mvme16xhw.h>
diff --git a/arch/m68knommu/kernel/ptrace.c b/arch/m68knommu/kernel/ptrace.c
index 72d3496..f54b6a3 100644
--- a/arch/m68knommu/kernel/ptrace.c
+++ b/arch/m68knommu/kernel/ptrace.c
@@ -14,7 +14,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
diff --git a/arch/m68knommu/kernel/sys_m68k.c b/arch/m68knommu/kernel/sys_m68k.c
index 3265b2d..48e6b33 100644
--- a/arch/m68knommu/kernel/sys_m68k.c
+++ b/arch/m68knommu/kernel/sys_m68k.c
@@ -10,7 +10,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
diff --git a/arch/mips/kernel/early_printk.c b/arch/mips/kernel/early_printk.c
index 304efdc..4fa54b2 100644
--- a/arch/mips/kernel/early_printk.c
+++ b/arch/mips/kernel/early_printk.c
@@ -33,8 +33,3 @@
{
register_console(&early_console);
}
-
-void __init disable_early_printk(void)
-{
- unregister_console(&early_console);
-}
diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c
index 3cc25c0..403d96f 100644
--- a/arch/mips/kernel/irixelf.c
+++ b/arch/mips/kernel/irixelf.c
@@ -31,7 +31,6 @@
#include <linux/shm.h>
#include <linux/personality.h>
#include <linux/elfcore.h>
-#include <linux/smp_lock.h>
#include <asm/mipsregs.h>
#include <asm/namei.h>
diff --git a/arch/mips/kernel/irixioctl.c b/arch/mips/kernel/irixioctl.c
index e286382..30f9eb0 100644
--- a/arch/mips/kernel/irixioctl.c
+++ b/arch/mips/kernel/irixioctl.c
@@ -9,7 +9,6 @@
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/sockios.h>
#include <linux/syscalls.h>
#include <linux/tty.h>
diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c
index 2132485..6980deb 100644
--- a/arch/mips/kernel/irixsig.c
+++ b/arch/mips/kernel/irixsig.c
@@ -10,7 +10,6 @@
#include <linux/mm.h>
#include <linux/errno.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/time.h>
#include <linux/ptrace.h>
#include <linux/resource.h>
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 201ae19..b5a7b46 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -22,7 +22,6 @@
#include <linux/ptrace.h>
#include <linux/audit.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/user.h>
#include <linux/security.h>
#include <linux/signal.h>
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index 07d6730..2a08ce4 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -12,7 +12,6 @@
#include <linux/mm.h>
#include <linux/personality.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index b9a0144..003f815 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -12,7 +12,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/syscalls.h>
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c
index a9202fa..4cf9ff2 100644
--- a/arch/mips/kernel/signal_n32.c
+++ b/arch/mips/kernel/signal_n32.c
@@ -19,7 +19,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/mips/kernel/stacktrace.c b/arch/mips/kernel/stacktrace.c
index a586aba..ebd9db8 100644
--- a/arch/mips/kernel/stacktrace.c
+++ b/arch/mips/kernel/stacktrace.c
@@ -31,8 +31,7 @@
}
}
-static void save_context_stack(struct stack_trace *trace,
- struct task_struct *task, struct pt_regs *regs)
+static void save_context_stack(struct stack_trace *trace, struct pt_regs *regs)
{
unsigned long sp = regs->regs[29];
#ifdef CONFIG_KALLSYMS
@@ -41,7 +40,7 @@
if (raw_show_trace || !__kernel_text_address(pc)) {
unsigned long stack_page =
- (unsigned long)task_stack_page(task);
+ (unsigned long)task_stack_page(current);
if (stack_page && sp >= stack_page &&
sp <= stack_page + THREAD_SIZE - 32)
save_raw_context_stack(trace, sp);
@@ -54,7 +53,7 @@
trace->entries[trace->nr_entries++] = pc;
if (trace->nr_entries >= trace->max_entries)
break;
- pc = unwind_stack(task, &sp, pc, &ra);
+ pc = unwind_stack(current, &sp, pc, &ra);
} while (pc);
#else
save_raw_context_stack(trace, sp);
@@ -64,22 +63,13 @@
/*
* Save stack-backtrace addresses into a stack_trace buffer.
*/
-void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
+void save_stack_trace(struct stack_trace *trace)
{
struct pt_regs dummyregs;
struct pt_regs *regs = &dummyregs;
WARN_ON(trace->nr_entries || !trace->max_entries);
- if (task && task != current) {
- regs->regs[29] = task->thread.reg29;
- regs->regs[31] = 0;
- regs->cp0_epc = task->thread.reg31;
- } else {
- if (!task)
- task = current;
- prepare_frametrace(regs);
- }
-
- save_context_stack(trace, task, regs);
+ prepare_frametrace(regs);
+ save_context_stack(trace, regs);
}
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index 26e1a7e..9dd5a2d 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -13,7 +13,6 @@
#include <linux/linkage.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/mman.h>
#include <linux/ptrace.h>
#include <linux/sched.h>
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 493cb29..ff45a4b 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -16,7 +16,6 @@
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/kallsyms.h>
#include <linux/bootmem.h>
diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c
index 24b7b05..a7d49ae 100644
--- a/arch/mips/kernel/unaligned.c
+++ b/arch/mips/kernel/unaligned.c
@@ -76,7 +76,6 @@
#include <linux/module.h>
#include <linux/signal.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <asm/asm.h>
#include <asm/branch.h>
diff --git a/arch/mips/math-emu/dsemul.c b/arch/mips/math-emu/dsemul.c
index 8079f3d..ea6ba72 100644
--- a/arch/mips/math-emu/dsemul.c
+++ b/arch/mips/math-emu/dsemul.c
@@ -2,7 +2,6 @@
#include <linux/mm.h>
#include <linux/signal.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <asm/asm.h>
#include <asm/bootinfo.h>
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index f9c595d..7ebea33 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -16,7 +16,6 @@
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/vt_kern.h> /* For unblank_screen() */
#include <linux/module.h>
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c
index 60ade76..ba8e079 100644
--- a/arch/mips/sgi-ip27/ip27-irq.c
+++ b/arch/mips/sgi-ip27/ip27-irq.c
@@ -19,7 +19,6 @@
#include <linux/timex.h>
#include <linux/slab.h>
#include <linux/random.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/kernel_stat.h>
#include <linux/delay.h>
diff --git a/arch/mips/sni/irq.c b/arch/mips/sni/irq.c
index ad5fc47..9ccffdf 100644
--- a/arch/mips/sni/irq.c
+++ b/arch/mips/sni/irq.c
@@ -42,7 +42,7 @@
struct irqaction sni_isa_irq = {
.handler = sni_isa_irq_handler,
.name = "ISA",
- .flags = SA_SHIRQ
+ .flags = IRQF_SHARED
};
/*
diff --git a/arch/parisc/hpux/fs.c b/arch/parisc/hpux/fs.c
index c7a81a2..d86e157 100644
--- a/arch/parisc/hpux/fs.c
+++ b/arch/parisc/hpux/fs.c
@@ -24,7 +24,6 @@
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/file.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/ptrace.h>
#include <asm/errno.h>
diff --git a/arch/parisc/hpux/ioctl.c b/arch/parisc/hpux/ioctl.c
index b34b4f3..dede476 100644
--- a/arch/parisc/hpux/ioctl.c
+++ b/arch/parisc/hpux/ioctl.c
@@ -34,7 +34,6 @@
*/
#include <linux/sched.h>
-#include <linux/smp_lock.h>
#include <linux/syscalls.h>
#include <asm/errno.h>
#include <asm/ioctl.h>
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index e9d09b0..c5c9125 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -388,7 +388,7 @@
static struct irqaction timer_action = {
.handler = timer_interrupt,
.name = "timer",
- .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_PERCPU,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_PERCPU | IRQF_IRQPOLL,
};
#ifdef CONFIG_SMP
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
index 0d0d617..8a0db37 100644
--- a/arch/parisc/kernel/ptrace.c
+++ b/arch/parisc/kernel/ptrace.c
@@ -10,7 +10,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
index 9784e40..fb35ebc 100644
--- a/arch/parisc/kernel/signal.c
+++ b/arch/parisc/kernel/signal.c
@@ -16,7 +16,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c
index 1c1a37f..db94aff 100644
--- a/arch/parisc/kernel/signal32.c
+++ b/arch/parisc/kernel/signal32.c
@@ -26,7 +26,6 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/unistd.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/syscalls.h>
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
index 6fed080..4f58921 100644
--- a/arch/parisc/kernel/sys_parisc.c
+++ b/arch/parisc/kernel/sys_parisc.c
@@ -29,7 +29,6 @@
#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/shm.h>
-#include <linux/smp_lock.h>
#include <linux/syscalls.h>
#include <linux/utsname.h>
#include <linux/personality.h>
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
index 55bc147..745ff74 100644
--- a/arch/parisc/kernel/traps.c
+++ b/arch/parisc/kernel/traps.c
@@ -20,7 +20,6 @@
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/init.h>
#include <linux/interrupt.h>
diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c
index 5f75b3e..89c0370 100644
--- a/arch/parisc/kernel/unwind.c
+++ b/arch/parisc/kernel/unwind.c
@@ -216,11 +216,8 @@
/* Handle some frequent special cases.... */
{
char symname[KSYM_NAME_LEN+1];
- char *modname;
- unsigned long symsize, offset;
- kallsyms_lookup(info->ip, &symsize, &offset,
- &modname, symname);
+ kallsyms_lookup(info->ip, NULL, NULL, NULL, symname);
dbg("info->ip = 0x%lx, name = %s\n", info->ip, symname);
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 8de5f9f..808d2ef 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -117,6 +117,9 @@
default y
depends on BUG
+config SYS_SUPPORTS_APM_EMULATION
+ bool
+
#
# Powerpc uses the slab allocator to manage its ptes and the
# page structs of ptes are used for splitting the page table
@@ -136,6 +139,11 @@
Used to allow a board to specify it wants a uImage built by default
default n
+config PPC64_SWSUSP
+ bool
+ depends on PPC64 && (BROKEN || (PPC_PMAC64 && EXPERIMENTAL))
+ default y
+
menu "Processor support"
choice
prompt "Processor Type"
@@ -206,6 +214,7 @@
config 44x
bool "AMCC 44x"
select PPC_DCR_NATIVE
+ select WANT_DEVICE_TREE
config E200
bool "Freescale e200"
@@ -270,9 +279,14 @@
depends on PPC64 # not supported on 32 bits yet
default n
+config 4xx
+ bool
+ depends on 40x || 44x
+ default y
+
config BOOKE
bool
- depends on E200 || E500
+ depends on E200 || E500 || 44x
default y
config FSL_BOOKE
@@ -669,11 +683,12 @@
config PCI
bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_86xx \
|| PPC_MPC52xx || (EMBEDDED && (PPC_PSERIES || PPC_ISERIES)) \
- || MPC7448HPC2 || PPC_PS3
+ || MPC7448HPC2 || PPC_PS3 || PPC_HOLLY
default y if !40x && !CPM2 && !8xx && !APUS && !PPC_83xx \
&& !PPC_85xx && !PPC_86xx
default PCI_PERMEDIA if !4xx && !CPM2 && !8xx && APUS
default PCI_QSPAN if !4xx && !CPM2 && 8xx
+ select ARCH_SUPPORTS_MSI
help
Find out whether your system includes a PCI bus. PCI is the name of
a bus system, i.e. the way the CPU talks to the other stuff inside
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 86aa374..f70e795 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -139,10 +139,6 @@
Say Y here to see progress messages from the boot firmware in text
mode. Requires either BootX or Open Firmware.
-config SERIAL_TEXT_DEBUG
- bool "Support for early boot texts over serial port"
- depends on 4xx
-
config PPC_EARLY_DEBUG
bool "Early debugging (dangerous)"
@@ -207,6 +203,24 @@
help
Select this to enable early debugging for Celleb with Beat.
+config PPC_EARLY_DEBUG_44x
+ bool "Early serial debugging for IBM/AMCC 44x CPUs"
+ depends on 44x
+ select PPC_UDBG_16550
+ help
+ Select this to enable early debugging for IBM 44x chips via the
+ inbuilt serial port.
+
endchoice
+config PPC_EARLY_DEBUG_44x_PHYSLOW
+ hex "Low 32 bits of early debug UART physical address"
+ depends PPC_EARLY_DEBUG_44x
+ default "0x40000200"
+
+config PPC_EARLY_DEBUG_44x_PHYSHIGH
+ hex "EPRN of early debug UART physical address"
+ depends PPC_EARLY_DEBUG_44x
+ default "0x1"
+
endmenu
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 7949920..81a531d 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -148,7 +148,7 @@
CPPFLAGS_vmlinux.lds := -Upowerpc
-BOOT_TARGETS = zImage zImage.initrd uImage cuImage
+BOOT_TARGETS = zImage zImage.initrd uImage
PHONY += $(BOOT_TARGETS)
diff --git a/arch/powerpc/boot/44x.c b/arch/powerpc/boot/44x.c
new file mode 100644
index 0000000..d51377d
--- /dev/null
+++ b/arch/powerpc/boot/44x.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2007 David Gibson, IBM Corporation.
+ *
+ * Based on earlier code:
+ * Matt Porter <mporter@kernel.crashing.org>
+ * Copyright 2002-2005 MontaVista Software Inc.
+ *
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ * Copyright (c) 2003, 2004 Zultys Technologies
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <stddef.h>
+#include "types.h"
+#include "string.h"
+#include "stdio.h"
+#include "ops.h"
+#include "reg.h"
+#include "dcr.h"
+
+/* Read the 44x memory controller to get size of system memory. */
+void ibm44x_fixup_memsize(void)
+{
+ int i;
+ unsigned long memsize, bank_config;
+
+ memsize = 0;
+ for (i = 0; i < ARRAY_SIZE(sdram_bxcr); i++) {
+ mtdcr(DCRN_SDRAM0_CFGADDR, sdram_bxcr[i]);
+ bank_config = mfdcr(DCRN_SDRAM0_CFGDATA);
+
+ if (bank_config & SDRAM_CONFIG_BANK_ENABLE)
+ memsize += SDRAM_CONFIG_BANK_SIZE(bank_config);
+ }
+
+ dt_fixup_memory(0, memsize);
+}
diff --git a/arch/powerpc/boot/44x.h b/arch/powerpc/boot/44x.h
new file mode 100644
index 0000000..7b129ad
--- /dev/null
+++ b/arch/powerpc/boot/44x.h
@@ -0,0 +1,16 @@
+/*
+ * PowerPC 44x related functions
+ *
+ * Copyright 2007 David Gibson, IBM Corporation.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#ifndef _PPC_BOOT_44X_H_
+#define _PPC_BOOT_44X_H_
+
+void ibm44x_fixup_memsize(void);
+void ebony_init(void *mac0, void *mac1);
+
+#endif /* _PPC_BOOT_44X_H_ */
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 3716594..5c384aa 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -37,13 +37,15 @@
zlibheader := inffast.h inffixed.h inflate.h inftrees.h infutil.h
zliblinuxheader := zlib.h zconf.h zutil.h
-$(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) \
- $(addprefix $(obj)/,$(zlibheader))
+$(addprefix $(obj)/,$(zlib) gunzip_util.o main.o): \
+ $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \
ns16550.c serial.c simple_alloc.c div64.S util.S \
- gunzip_util.c elf_util.c $(zlib) devtree.c
-src-plat := of.c cuboot-83xx.c cuboot-85xx.c
+ gunzip_util.c elf_util.c $(zlib) devtree.c \
+ 44x.c ebony.c
+src-plat := of.c cuboot-83xx.c cuboot-85xx.c holly.c \
+ cuboot-ebony.c treeboot-ebony.c
src-boot := $(src-wlib) $(src-plat) empty.c
src-boot := $(addprefix $(obj)/, $(src-boot))
@@ -129,7 +131,14 @@
image-$(CONFIG_PPC_CHRP) += zImage.chrp
image-$(CONFIG_PPC_EFIKA) += zImage.chrp
image-$(CONFIG_PPC_PMAC) += zImage.pmac
-image-$(CONFIG_DEFAULT_UIMAGE) += uImage cuImage
+image-$(CONFIG_PPC_HOLLY) += zImage.holly-elf
+image-$(CONFIG_DEFAULT_UIMAGE) += uImage
+
+ifneq ($(CONFIG_DEVICE_TREE),"")
+image-$(CONFIG_PPC_83xx) += cuImage.83xx
+image-$(CONFIG_PPC_85xx) += cuImage.85xx
+image-$(CONFIG_EBONY) += treeImage.ebony cuImage.ebony
+endif
# For 32-bit powermacs, build the COFF and miboot images
# as well as the ELF images.
@@ -138,7 +147,8 @@
endif
initrd- := $(patsubst zImage%, zImage.initrd%, $(image-n) $(image-))
-initrd-y := $(patsubst zImage%, zImage.initrd%, $(image-y))
+initrd-y := $(patsubst zImage%, zImage.initrd%, \
+ $(patsubst treeImage%, treeImage.initrd%, $(image-y)))
initrd-y := $(filter-out $(image-y), $(initrd-y))
targets += $(image-y) $(initrd-y)
@@ -159,18 +169,27 @@
$(obj)/zImage.initrd.ps3: vmlinux
@echo " WARNING zImage.initrd.ps3 not supported (yet)"
+$(obj)/zImage.holly-elf: vmlinux $(wrapperbits)
+ $(call if_changed,wrap,holly,$(obj)/dts/holly.dts,,)
+
+$(obj)/zImage.initrd.holly-elf: vmlinux $(wrapperbits) $(obj)/ramdisk.image.gz
+ $(call if_changed,wrap,holly,$(obj)/dts/holly.dts,,$(obj)/ramdisk.image.gz)
+
$(obj)/uImage: vmlinux $(wrapperbits)
$(call if_changed,wrap,uboot)
-cuboot-plat-$(CONFIG_83xx) += 83xx
-cuboot-plat-$(CONFIG_85xx) += 85xx
-cuboot-plat-y += unknown-platform
-
+# CONFIG_DEVICE_TREE will have "" around it, make sure to strip them
dts = $(if $(shell echo $(CONFIG_DEVICE_TREE) | grep '^/'),\
- ,$(srctree)/$(src)/dts/)$(CONFIG_DEVICE_TREE)
+ ,$(srctree)/$(src)/dts/)$(CONFIG_DEVICE_TREE:"%"=%)
-$(obj)/cuImage: vmlinux $(wrapperbits)
- $(call if_changed,wrap,cuboot-$(word 1,$(cuboot-plat-y)),$(dts))
+$(obj)/cuImage.%: vmlinux $(dts) $(wrapperbits)
+ $(call if_changed,wrap,cuboot-$*,$(dts))
+
+$(obj)/treeImage.%: vmlinux $(dts) $(wrapperbits)
+ $(call if_changed,wrap,treeboot-$*,$(dts))
+
+$(obj)/treeImage.initrd.%: vmlinux $(dts) $(wrapperbits)
+ $(call if_changed,wrap,treeboot-$*,$(dts),,$(obj)/ramdisk.image.gz)
$(obj)/zImage: $(addprefix $(obj)/, $(image-y))
@rm -f $@; ln $< $@
@@ -181,8 +200,8 @@
sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" $<
# anything not in $(targets)
-clean-files += $(image-) $(initrd-) zImage zImage.initrd \
- cuImage.elf cuImage.bin.gz
+clean-files += $(image-) $(initrd-) zImage zImage.initrd cuImage.* \
+ treeImage.*
# clean up files cached by wrapper
clean-kernel := vmlinux.strip vmlinux.bin
diff --git a/arch/powerpc/boot/cuboot-ebony.c b/arch/powerpc/boot/cuboot-ebony.c
new file mode 100644
index 0000000..4464c5f
--- /dev/null
+++ b/arch/powerpc/boot/cuboot-ebony.c
@@ -0,0 +1,42 @@
+/*
+ * Old U-boot compatibility for Ebony
+ *
+ * Author: David Gibson <david@gibson.dropbear.id.au>
+ *
+ * Copyright 2007 David Gibson, IBM Corporatio.
+ * Based on cuboot-83xx.c, which is:
+ * Copyright (c) 2007 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include "ops.h"
+#include "stdio.h"
+#include "44x.h"
+
+#define TARGET_44x
+#include "ppcboot.h"
+
+static bd_t bd;
+extern char _end[];
+
+BSS_STACK(4096);
+
+void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7)
+{
+ unsigned long end_of_ram = bd.bi_memstart + bd.bi_memsize;
+ unsigned long avail_ram = end_of_ram - (unsigned long)_end;
+
+ memcpy(&bd, (bd_t *)r3, sizeof(bd));
+ loader_info.initrd_addr = r4;
+ loader_info.initrd_size = r4 ? r5 : 0;
+ loader_info.cmdline = (char *)r6;
+ loader_info.cmdline_len = r7 - r6;
+
+ simple_alloc_init(_end, avail_ram, 32, 64);
+
+ ebony_init(&bd.bi_enetaddr, &bd.bi_enet1addr);
+}
diff --git a/arch/powerpc/boot/dcr.h b/arch/powerpc/boot/dcr.h
new file mode 100644
index 0000000..877bc97
--- /dev/null
+++ b/arch/powerpc/boot/dcr.h
@@ -0,0 +1,87 @@
+#ifndef _PPC_BOOT_DCR_H_
+#define _PPC_BOOT_DCR_H_
+
+#define mfdcr(rn) \
+ ({ \
+ unsigned long rval; \
+ asm volatile("mfdcr %0,%1" : "=r"(rval) : "i"(rn)); \
+ rval; \
+ })
+#define mtdcr(rn, val) \
+ asm volatile("mtdcr %0,%1" : : "i"(rn), "r"(val))
+
+/* 440GP/440GX SDRAM controller DCRs */
+#define DCRN_SDRAM0_CFGADDR 0x010
+#define DCRN_SDRAM0_CFGDATA 0x011
+
+#define SDRAM0_B0CR 0x40
+#define SDRAM0_B1CR 0x44
+#define SDRAM0_B2CR 0x48
+#define SDRAM0_B3CR 0x4c
+
+static const unsigned long sdram_bxcr[] = { SDRAM0_B0CR, SDRAM0_B1CR, SDRAM0_B2CR, SDRAM0_B3CR };
+
+#define SDRAM_CONFIG_BANK_ENABLE 0x00000001
+#define SDRAM_CONFIG_SIZE_MASK 0x000e0000
+#define SDRAM_CONFIG_BANK_SIZE(reg) \
+ (0x00400000 << ((reg & SDRAM_CONFIG_SIZE_MASK) >> 17))
+
+/* 440GP Clock, PM, chip control */
+#define DCRN_CPC0_SR 0x0b0
+#define DCRN_CPC0_ER 0x0b1
+#define DCRN_CPC0_FR 0x0b2
+#define DCRN_CPC0_SYS0 0x0e0
+#define CPC0_SYS0_TUNE 0xffc00000
+#define CPC0_SYS0_FBDV_MASK 0x003c0000
+#define CPC0_SYS0_FWDVA_MASK 0x00038000
+#define CPC0_SYS0_FWDVB_MASK 0x00007000
+#define CPC0_SYS0_OPDV_MASK 0x00000c00
+#define CPC0_SYS0_EPDV_MASK 0x00000300
+/* Helper macros to compute the actual clock divider values from the
+ * encodings in the CPC0 register */
+#define CPC0_SYS0_FBDV(reg) \
+ ((((((reg) & CPC0_SYS0_FBDV_MASK) >> 18) - 1) & 0xf) + 1)
+#define CPC0_SYS0_FWDVA(reg) \
+ (8 - (((reg) & CPC0_SYS0_FWDVA_MASK) >> 15))
+#define CPC0_SYS0_FWDVB(reg) \
+ (8 - (((reg) & CPC0_SYS0_FWDVB_MASK) >> 12))
+#define CPC0_SYS0_OPDV(reg) \
+ ((((reg) & CPC0_SYS0_OPDV_MASK) >> 10) + 1)
+#define CPC0_SYS0_EPDV(reg) \
+ ((((reg) & CPC0_SYS0_EPDV_MASK) >> 8) + 1)
+#define CPC0_SYS0_EXTSL 0x00000080
+#define CPC0_SYS0_RW_MASK 0x00000060
+#define CPC0_SYS0_RL 0x00000010
+#define CPC0_SYS0_ZMIISL_MASK 0x0000000c
+#define CPC0_SYS0_BYPASS 0x00000002
+#define CPC0_SYS0_NTO1 0x00000001
+#define DCRN_CPC0_SYS1 0x0e1
+#define DCRN_CPC0_CUST0 0x0e2
+#define DCRN_CPC0_CUST1 0x0e3
+#define DCRN_CPC0_STRP0 0x0e4
+#define DCRN_CPC0_STRP1 0x0e5
+#define DCRN_CPC0_STRP2 0x0e6
+#define DCRN_CPC0_STRP3 0x0e7
+#define DCRN_CPC0_GPIO 0x0e8
+#define DCRN_CPC0_PLB 0x0e9
+#define DCRN_CPC0_CR1 0x0ea
+#define DCRN_CPC0_CR0 0x0eb
+#define CPC0_CR0_SWE 0x80000000
+#define CPC0_CR0_CETE 0x40000000
+#define CPC0_CR0_U1FCS 0x20000000
+#define CPC0_CR0_U0DTE 0x10000000
+#define CPC0_CR0_U0DRE 0x08000000
+#define CPC0_CR0_U0DC 0x04000000
+#define CPC0_CR0_U1DTE 0x02000000
+#define CPC0_CR0_U1DRE 0x01000000
+#define CPC0_CR0_U1DC 0x00800000
+#define CPC0_CR0_U0EC 0x00400000
+#define CPC0_CR0_U1EC 0x00200000
+#define CPC0_CR0_UDIV_MASK 0x001f0000
+#define CPC0_CR0_UDIV(reg) \
+ ((((reg) & CPC0_CR0_UDIV_MASK) >> 16) + 1)
+#define DCRN_CPC0_MIRQ0 0x0ec
+#define DCRN_CPC0_MIRQ1 0x0ed
+#define DCRN_CPC0_JTAGID 0x0ef
+
+#endif /* _PPC_BOOT_DCR_H_ */
diff --git a/arch/powerpc/boot/dts/ebony.dts b/arch/powerpc/boot/dts/ebony.dts
new file mode 100644
index 0000000..b679186
--- /dev/null
+++ b/arch/powerpc/boot/dts/ebony.dts
@@ -0,0 +1,307 @@
+/*
+ * Device Tree Source for IBM Ebony
+ *
+ * Copyright (c) 2006, 2007 IBM Corp.
+ * Josh Boyer <jwboyer@linux.vnet.ibm.com>, David Gibson <dwg@au1.ibm.com>
+ *
+ * FIXME: Draft only!
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without
+ * any warranty of any kind, whether express or implied.
+ *
+ * To build:
+ * dtc -I dts -O asm -o ebony.S -b 0 ebony.dts
+ * dtc -I dts -O dtb -o ebony.dtb -b 0 ebony.dts
+ */
+
+/ {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ model = "ibm,ebony";
+ compatible = "ibm,ebony";
+ dcr-parent = <&/cpus/PowerPC,440GP@0>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,440GP@0 {
+ device_type = "cpu";
+ reg = <0>;
+ clock-frequency = <0>; // Filled in by zImage
+ timebase-frequency = <0>; // Filled in by zImage
+ i-cache-line-size = <32>;
+ d-cache-line-size = <32>;
+ i-cache-size = <0>;
+ d-cache-size = <0>;
+ dcr-controller;
+ dcr-access-method = "native";
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0 0 0>; // Filled in by zImage
+ };
+
+ UIC0: interrupt-controller0 {
+ device_type = "ibm,uic";
+ compatible = "ibm,uic-440gp", "ibm,uic";
+ interrupt-controller;
+ cell-index = <0>;
+ dcr-reg = <0c0 009>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ #interrupt-cells = <2>;
+
+ };
+
+ UIC1: interrupt-controller1 {
+ device_type = "ibm,uic";
+ compatible = "ibm,uic-440gp", "ibm,uic";
+ interrupt-controller;
+ cell-index = <1>;
+ dcr-reg = <0d0 009>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ #interrupt-cells = <2>;
+ interrupts = <1e 4 1f 4>; /* cascade */
+ interrupt-parent = <&UIC0>;
+ };
+
+ CPC0: cpc {
+ device_type = "ibm,cpc";
+ compatible = "ibm,cpc-440gp";
+ dcr-reg = <0b0 003 0e0 010>;
+ // FIXME: anything else?
+ };
+
+ plb {
+ device_type = "ibm,plb";
+ compatible = "ibm,plb-440gp", "ibm,plb4";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges;
+ clock-frequency = <0>; // Filled in by zImage
+
+ SDRAM0: sdram {
+ device_type = "memory-controller";
+ compatible = "ibm,sdram-440gp", "ibm,sdram";
+ dcr-reg = <010 2>;
+ // FIXME: anything else?
+ };
+
+ DMA0: dma {
+ // FIXME: ???
+ device_type = "ibm,dma-4xx";
+ compatible = "ibm,dma-440gp", "ibm,dma-4xx";
+ dcr-reg = <100 027>;
+ };
+
+ MAL0: mcmal {
+ device_type = "mcmal-dma";
+ compatible = "ibm,mcmal-440gp", "ibm,mcmal";
+ dcr-reg = <180 62>;
+ num-tx-chans = <4>;
+ num-rx-chans = <4>;
+ interrupt-parent = <&MAL0>;
+ interrupts = <0 1 2 3 4>;
+ #interrupt-cells = <1>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ interrupt-map = </*TXEOB*/ 0 &UIC0 a 4
+ /*RXEOB*/ 1 &UIC0 b 4
+ /*SERR*/ 2 &UIC1 0 4
+ /*TXDE*/ 3 &UIC1 1 4
+ /*RXDE*/ 4 &UIC1 2 4>;
+ interrupt-map-mask = <ffffffff>;
+ };
+
+ POB0: opb {
+ device_type = "ibm,opb";
+ compatible = "ibm,opb-440gp", "ibm,opb";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ /* Wish there was a nicer way of specifying a full 32-bit
+ range */
+ ranges = <00000000 1 00000000 80000000
+ 80000000 1 80000000 80000000>;
+ dcr-reg = <090 00b>;
+ interrupt-parent = <&UIC1>;
+ interrupts = <7 4>;
+ clock-frequency = <0>; // Filled in by zImage
+
+ EBC0: ebc {
+ device_type = "ibm,ebc";
+ compatible = "ibm,ebc-440gp";
+ dcr-reg = <012 2>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ clock-frequency = <0>; // Filled in by zImage
+ ranges = <0 00000000 fff00000 100000
+ 1 00000000 48000000 100000
+ 2 00000000 ff800000 400000
+ 3 00000000 48200000 100000
+ 7 00000000 48300000 100000>;
+ interrupts = <5 4>;
+ interrupt-parent = <&UIC1>;
+
+ small-flash@0,0 {
+ device_type = "rom";
+ compatible = "direct-mapped";
+ probe-type = "JEDEC";
+ bank-width = <1>;
+ partitions = <0 80000>;
+ partition-names = "OpenBIOS";
+ reg = <0 80000 80000>;
+ };
+
+ ds1743@1,0 {
+ /* NVRAM & RTC */
+ device_type = "nvram";
+ compatible = "ds1743";
+ reg = <1 0 2000>;
+ };
+
+ large-flash@2,0 {
+ device_type = "rom";
+ compatible = "direct-mapped";
+ probe-type = "JEDEC";
+ bank-width = <1>;
+ partitions = <0 380000
+ 280000 80000>;
+ partition-names = "fs", "firmware";
+ reg = <2 0 400000>;
+ };
+
+ ir@3,0 {
+ reg = <3 0 10>;
+ };
+
+ fpga@7,0 {
+ compatible = "Ebony-FPGA";
+ reg = <7 0 10>;
+ };
+ };
+
+ UART0: serial@40000200 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <40000200 8>;
+ virtual-reg = <e0000200>;
+ clock-frequency = <A8C000>;
+ current-speed = <2580>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <0 4>;
+ };
+
+ UART1: serial@40000300 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <40000300 8>;
+ virtual-reg = <e0000300>;
+ clock-frequency = <A8C000>;
+ current-speed = <2580>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <1 4>;
+ };
+
+ IIC0: i2c@40000400 {
+ /* FIXME */
+ device_type = "i2c";
+ compatible = "ibm,iic-440gp", "ibm,iic";
+ reg = <40000400 14>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <2 4>;
+ };
+ IIC1: i2c@40000500 {
+ /* FIXME */
+ device_type = "i2c";
+ compatible = "ibm,iic-440gp", "ibm,iic";
+ reg = <40000500 14>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <3 4>;
+ };
+
+ GPIO0: gpio@40000700 {
+ /* FIXME */
+ device_type = "gpio";
+ compatible = "ibm,gpio-440gp";
+ reg = <40000700 20>;
+ };
+
+ ZMII0: emac-zmii@40000780 {
+ device_type = "emac-zmii";
+ compatible = "ibm,zmii-440gp", "ibm,zmii";
+ reg = <40000780 c>;
+ };
+
+ EMAC0: ethernet@40000800 {
+ linux,network-index = <0>;
+ device_type = "network";
+ compatible = "ibm,emac-440gp", "ibm,emac";
+ interrupt-parent = <&UIC1>;
+ interrupts = <1c 4 1d 4>;
+ reg = <40000800 70>;
+ local-mac-address = [000000000000]; // Filled in by zImage
+ mal-device = <&MAL0>;
+ mal-tx-channel = <0 1>;
+ mal-rx-channel = <0>;
+ cell-index = <0>;
+ max-frame-size = <5dc>;
+ rx-fifo-size = <1000>;
+ tx-fifo-size = <800>;
+ phy-mode = "rmii";
+ phy-map = <00000001>;
+ zmii-device = <&ZMII0>;
+ zmii-channel = <0>;
+ };
+ EMAC1: ethernet@40000900 {
+ linux,network-index = <1>;
+ device_type = "network";
+ compatible = "ibm,emac-440gp", "ibm,emac";
+ interrupt-parent = <&UIC1>;
+ interrupts = <1e 4 1f 4>;
+ reg = <40000900 70>;
+ local-mac-address = [000000000000]; // Filled in by zImage
+ mal-device = <&MAL0>;
+ mal-tx-channel = <2 3>;
+ mal-rx-channel = <1>;
+ cell-index = <1>;
+ max-frame-size = <5dc>;
+ rx-fifo-size = <1000>;
+ tx-fifo-size = <800>;
+ phy-mode = "rmii";
+ phy-map = <00000001>;
+ zmii-device = <&ZMII0>;
+ zmii-channel = <1>;
+ };
+
+
+ GPT0: gpt@40000a00 {
+ /* FIXME */
+ reg = <40000a00 d4>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <12 4 13 4 14 4 15 4 16 4>;
+ };
+
+ };
+
+ PCIX0: pci@1234 {
+ device_type = "pci";
+ /* FIXME */
+ reg = <2 0ec00000 8
+ 2 0ec80000 f0
+ 2 0ec80100 fc>;
+ };
+ };
+
+ chosen {
+ linux,stdout-path = "/plb/opb/serial@40000200";
+// linux,initrd-start = <0>; /* FIXME */
+// linux,initrd-end = <0>;
+// bootargs = "";
+ };
+};
+
diff --git a/arch/powerpc/boot/dts/holly.dts b/arch/powerpc/boot/dts/holly.dts
new file mode 100644
index 0000000..254499b
--- /dev/null
+++ b/arch/powerpc/boot/dts/holly.dts
@@ -0,0 +1,198 @@
+/*
+ * Device Tree Source for IBM Holly (PPC 750CL with TSI controller)
+ * Copyright 2007, IBM Corporation
+ *
+ * Stephen Winiecki <stevewin@us.ibm.com>
+ * Josh Boyer <jwboyer@linux.vnet.ibm.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without
+ * any warranty of any kind, whether express or implied.
+ *
+ * To build:
+ * dtc -I dts -O asm -o holly.S -b 0 holly.dts
+ * dtc -I dts -O dtb -o holly.dtb -b 0 holly.dts
+ */
+
+/ {
+ model = "41K7339";
+ compatible = "ibm,holly";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells =<0>;
+ PowerPC,750CL@0 {
+ device_type = "cpu";
+ reg = <0>;
+ d-cache-line-size = <20>;
+ i-cache-line-size = <20>;
+ d-cache-size = <8000>;
+ i-cache-size = <8000>;
+ d-cache-sets = <80>;
+ i-cache-sets = <80>;
+ timebase-frequency = <2faf080>;
+ clock-frequency = <23c34600>;
+ bus-frequency = <bebc200>;
+ 32-bit;
+ };
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <00000000 20000000>;
+ };
+
+ tsi109@c0000000 {
+ device_type = "tsi-bridge";
+ compatible = "tsi-bridge";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <00000000 c0000000 00010000>;
+ reg = <c0000000 00010000>;
+
+ i2c@7000 {
+ device_type = "i2c";
+ compatible = "tsi-i2c";
+ interrupt-parent = < &/tsi109@c0000000/pic@7400 >;
+ interrupts = <e 2>;
+ reg = <7000 400>;
+ };
+
+ mdio@6000 {
+ device_type = "mdio";
+ compatible = "tsi-ethernet";
+
+ PHY1: ethernet-phy@6000 {
+ device_type = "ethernet-phy";
+ compatible = "bcm54xx";
+ reg = <6000 50>;
+ phy-id = <1>;
+ };
+
+ PHY2: ethernet-phy@6400 {
+ device_type = "ethernet-phy";
+ compatible = "bcm54xx";
+ reg = <6000 50>;
+ phy-id = <2>;
+ };
+ };
+
+ ethernet@6200 {
+ device_type = "network";
+ compatible = "tsi-ethernet";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <6000 200>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupt-parent = < &/tsi109@c0000000/pic@7400 >;
+ interrupts = <10 2>;
+ phy-handle = <&PHY1>;
+ };
+
+ ethernet@6600 {
+ device_type = "network";
+ compatible = "tsi-ethernet";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <6400 200>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupt-parent = < &/tsi109@c0000000/pic@7400 >;
+ interrupts = <11 2>;
+ phy-handle = <&PHY2>;
+ };
+
+ serial@7808 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <7808 200>;
+ virtual-reg = <c0007808>;
+ clock-frequency = <3F9C6000>;
+ current-speed = <1c200>;
+ interrupt-parent = < &/tsi109@c0000000/pic@7400 >;
+ interrupts = <c 2>;
+ };
+
+ serial@7c08 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <7c08 200>;
+ virtual-reg = <c0007c08>;
+ clock-frequency = <3F9C6000>;
+ current-speed = <1c200>;
+ interrupt-parent = < &/tsi109@c0000000/pic@7400 >;
+ interrupts = <d 2>;
+ };
+
+ MPIC: pic@7400 {
+ device_type = "open-pic";
+ compatible = "chrp,open-pic";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <7400 400>;
+ big-endian;
+ };
+
+ pci@1000 {
+ device_type = "pci";
+ compatible = "tsi109";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <1000 1000>;
+ bus-range = <0 0>;
+ /*----------------------------------------------------+
+ | PCI memory range.
+ | 01 denotes I/O space
+ | 02 denotes 32-bit memory space
+ +----------------------------------------------------*/
+ ranges = <02000000 0 40000000 40000000 0 10000000
+ 01000000 0 00000000 7e000000 0 00010000>;
+ clock-frequency = <7f28154>;
+ interrupt-parent = < &/tsi109@c0000000/pic@7400 >;
+ interrupts = <17 2>;
+ interrupt-map-mask = <f800 0 0 7>;
+ /*----------------------------------------------------+
+ | The INTA, INTB, INTC, INTD are shared.
+ +----------------------------------------------------*/
+ interrupt-map = <
+ 0800 0 0 1 &RT0 24 0
+ 0800 0 0 2 &RT0 25 0
+ 0800 0 0 3 &RT0 26 0
+ 0800 0 0 4 &RT0 27 0
+
+ 1000 0 0 1 &RT0 25 0
+ 1000 0 0 2 &RT0 26 0
+ 1000 0 0 3 &RT0 27 0
+ 1000 0 0 4 &RT0 24 0
+
+ 1800 0 0 1 &RT0 26 0
+ 1800 0 0 2 &RT0 27 0
+ 1800 0 0 3 &RT0 24 0
+ 1800 0 0 4 &RT0 25 0
+
+ 2000 0 0 1 &RT0 27 0
+ 2000 0 0 2 &RT0 24 0
+ 2000 0 0 3 &RT0 25 0
+ 2000 0 0 4 &RT0 26 0
+ >;
+
+ RT0: router@1180 {
+ device_type = "pic-router";
+ interrupt-controller;
+ big-endian;
+ clock-frequency = <0>;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ interrupts = <17 2>;
+ interrupt-parent = < &/tsi109@c0000000/pic@7400 >;
+ };
+ };
+ };
+
+ chosen {
+ linux,stdout-path = "/tsi109@c0000000/serial@7808";
+ bootargs = "console=ttyS0,115200";
+ };
+};
diff --git a/arch/powerpc/boot/dts/lite5200.dts b/arch/powerpc/boot/dts/lite5200.dts
index ba54c6b..e13ac6e 100644
--- a/arch/powerpc/boot/dts/lite5200.dts
+++ b/arch/powerpc/boot/dts/lite5200.dts
@@ -48,6 +48,7 @@
soc5200@f0000000 {
model = "fsl,mpc5200";
+ compatible = "mpc5200";
revision = "" // from bootloader
#interrupt-cells = <3>;
device_type = "soc";
@@ -166,7 +167,7 @@
device_type = "mscan";
compatible = "mpc5200-mscan";
cell-index = <1>;
- interrupts = <1 12 0>;
+ interrupts = <2 12 0>;
interrupt-parent = <500>;
reg = <980 80>;
};
@@ -178,7 +179,7 @@
interrupt-parent = <500>;
};
- gpio-wkup@b00 {
+ gpio-wkup@c00 {
compatible = "mpc5200-gpio-wkup";
reg = <c00 40>;
interrupts = <1 8 0 0 3 0>;
@@ -317,20 +318,22 @@
i2c@3d00 {
device_type = "i2c";
- compatible = "mpc5200-i2c";
+ compatible = "mpc5200-i2c\0fsl-i2c";
cell-index = <0>;
reg = <3d00 40>;
interrupts = <2 f 0>;
interrupt-parent = <500>;
+ fsl5200-clocking;
};
i2c@3d40 {
device_type = "i2c";
- compatible = "mpc5200-i2c";
+ compatible = "mpc5200-i2c\0fsl-i2c";
cell-index = <1>;
reg = <3d40 40>;
interrupts = <2 10 0>;
interrupt-parent = <500>;
+ fsl5200-clocking;
};
sram@8000 {
device_type = "sram";
diff --git a/arch/powerpc/boot/dts/lite5200b.dts b/arch/powerpc/boot/dts/lite5200b.dts
index 2e00308..00211b3 100644
--- a/arch/powerpc/boot/dts/lite5200b.dts
+++ b/arch/powerpc/boot/dts/lite5200b.dts
@@ -48,6 +48,7 @@
soc5200@f0000000 {
model = "fsl,mpc5200b";
+ compatible = "mpc5200";
revision = ""; // from bootloader
#interrupt-cells = <3>;
device_type = "soc";
@@ -166,7 +167,7 @@
device_type = "mscan";
compatible = "mpc5200b-mscan\0mpc5200-mscan";
cell-index = <1>;
- interrupts = <1 12 0>;
+ interrupts = <2 12 0>;
interrupt-parent = <500>;
reg = <980 80>;
};
@@ -178,7 +179,7 @@
interrupt-parent = <500>;
};
- gpio-wkup@b00 {
+ gpio-wkup@c00 {
compatible = "mpc5200b-gpio-wkup\0mpc5200-gpio-wkup";
reg = <c00 40>;
interrupts = <1 8 0 0 3 0>;
@@ -322,20 +323,22 @@
i2c@3d00 {
device_type = "i2c";
- compatible = "mpc5200b-i2c\0mpc5200-i2c";
+ compatible = "mpc5200b-i2c\0mpc5200-i2c\0fsl-i2c";
cell-index = <0>;
reg = <3d00 40>;
interrupts = <2 f 0>;
interrupt-parent = <500>;
+ fsl5200-clocking;
};
i2c@3d40 {
device_type = "i2c";
- compatible = "mpc5200b-i2c\0mpc5200-i2c";
+ compatible = "mpc5200b-i2c\0mpc5200-i2c\0fsl-i2c";
cell-index = <1>;
reg = <3d40 40>;
interrupts = <2 10 0>;
interrupt-parent = <500>;
+ fsl5200-clocking;
};
sram@8000 {
device_type = "sram";
diff --git a/arch/powerpc/boot/dts/mpc832x_mds.dts b/arch/powerpc/boot/dts/mpc832x_mds.dts
index c798491..93b7606 100644
--- a/arch/powerpc/boot/dts/mpc832x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc832x_mds.dts
@@ -306,14 +306,12 @@
interrupts = <11 8>;
reg = <3>;
device_type = "ethernet-phy";
- interface = <3>; //ENET_100_MII
};
phy4: ethernet-phy@04 {
interrupt-parent = < &ipic >;
interrupts = <12 8>;
reg = <4>;
device_type = "ethernet-phy";
- interface = <3>;
};
};
diff --git a/arch/powerpc/boot/dts/mpc832x_rdb.dts b/arch/powerpc/boot/dts/mpc832x_rdb.dts
index b55bced..be4c357 100644
--- a/arch/powerpc/boot/dts/mpc832x_rdb.dts
+++ b/arch/powerpc/boot/dts/mpc832x_rdb.dts
@@ -265,14 +265,12 @@
interrupts = <0>;
reg = <0>;
device_type = "ethernet-phy";
- interface = <3>; //ENET_100_MII
};
phy04:ethernet-phy@04 {
interrupt-parent = <&pic>;
interrupts = <0>;
reg = <4>;
device_type = "ethernet-phy";
- interface = <3>;
};
};
diff --git a/arch/powerpc/boot/dts/mpc836x_mds.dts b/arch/powerpc/boot/dts/mpc836x_mds.dts
index 7f578eb..38c8594 100644
--- a/arch/powerpc/boot/dts/mpc836x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc836x_mds.dts
@@ -305,6 +305,7 @@
rx-clock = <0>;
tx-clock = <19>;
phy-handle = < &phy0 >;
+ phy-connection-type = "rgmii-id";
pio-handle = < &pio1 >;
};
@@ -320,6 +321,7 @@
rx-clock = <0>;
tx-clock = <14>;
phy-handle = < &phy1 >;
+ phy-connection-type = "rgmii-id";
pio-handle = < &pio2 >;
};
@@ -335,14 +337,12 @@
interrupts = <11 8>;
reg = <0>;
device_type = "ethernet-phy";
- interface = <6>; //ENET_1000_GMII
};
phy1: ethernet-phy@01 {
interrupt-parent = < &ipic >;
interrupts = <12 8>;
reg = <1>;
device_type = "ethernet-phy";
- interface = <6>;
};
};
diff --git a/arch/powerpc/boot/dts/mpc8568mds.dts b/arch/powerpc/boot/dts/mpc8568mds.dts
index 7361b36..948a3b6 100644
--- a/arch/powerpc/boot/dts/mpc8568mds.dts
+++ b/arch/powerpc/boot/dts/mpc8568mds.dts
@@ -288,6 +288,7 @@
rx-clock = <0>;
tx-clock = <19>;
phy-handle = <&qe_phy0>;
+ phy-connection-type = "gmii";
pio-handle = <&pio1>;
};
@@ -303,6 +304,7 @@
rx-clock = <0>;
tx-clock = <14>;
phy-handle = <&qe_phy1>;
+ phy-connection-type = "gmii";
pio-handle = <&pio2>;
};
@@ -320,28 +322,24 @@
interrupts = <31 1>;
reg = <0>;
device_type = "ethernet-phy";
- interface = <6>; //ENET_1000_GMII
};
qe_phy1: ethernet-phy@01 {
interrupt-parent = <&mpic>;
interrupts = <32 1>;
reg = <1>;
device_type = "ethernet-phy";
- interface = <6>;
};
qe_phy2: ethernet-phy@02 {
interrupt-parent = <&mpic>;
interrupts = <31 1>;
reg = <2>;
device_type = "ethernet-phy";
- interface = <6>; //ENET_1000_GMII
};
qe_phy3: ethernet-phy@03 {
interrupt-parent = <&mpic>;
interrupts = <32 1>;
reg = <3>;
device_type = "ethernet-phy";
- interface = <6>; //ENET_1000_GMII
};
};
diff --git a/arch/powerpc/boot/ebony.c b/arch/powerpc/boot/ebony.c
new file mode 100644
index 0000000..b1251ee
--- /dev/null
+++ b/arch/powerpc/boot/ebony.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2007 David Gibson, IBM Corporation.
+ *
+ * Based on earlier code:
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * Matt Porter <mporter@kernel.crashing.org>
+ * Copyright 2002-2005 MontaVista Software Inc.
+ *
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ * Copyright (c) 2003, 2004 Zultys Technologies
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <stdarg.h>
+#include <stddef.h>
+#include "types.h"
+#include "elf.h"
+#include "string.h"
+#include "stdio.h"
+#include "page.h"
+#include "ops.h"
+#include "reg.h"
+#include "dcr.h"
+#include "44x.h"
+
+extern char _dtb_start[];
+extern char _dtb_end[];
+
+static u8 *ebony_mac0, *ebony_mac1;
+
+/* Calculate 440GP clocks */
+void ibm440gp_fixup_clocks(unsigned int sysclk, unsigned int ser_clk)
+{
+ u32 sys0 = mfdcr(DCRN_CPC0_SYS0);
+ u32 cr0 = mfdcr(DCRN_CPC0_CR0);
+ u32 cpu, plb, opb, ebc, tb, uart0, uart1, m;
+ u32 opdv = CPC0_SYS0_OPDV(sys0);
+ u32 epdv = CPC0_SYS0_EPDV(sys0);
+
+ if (sys0 & CPC0_SYS0_BYPASS) {
+ /* Bypass system PLL */
+ cpu = plb = sysclk;
+ } else {
+ if (sys0 & CPC0_SYS0_EXTSL)
+ /* PerClk */
+ m = CPC0_SYS0_FWDVB(sys0) * opdv * epdv;
+ else
+ /* CPU clock */
+ m = CPC0_SYS0_FBDV(sys0) * CPC0_SYS0_FWDVA(sys0);
+ cpu = sysclk * m / CPC0_SYS0_FWDVA(sys0);
+ plb = sysclk * m / CPC0_SYS0_FWDVB(sys0);
+ }
+
+ opb = plb / opdv;
+ ebc = opb / epdv;
+
+ /* FIXME: Check if this is for all 440GP, or just Ebony */
+ if ((mfpvr() & 0xf0000fff) == 0x40000440)
+ /* Rev. B 440GP, use external system clock */
+ tb = sysclk;
+ else
+ /* Rev. C 440GP, errata force us to use internal clock */
+ tb = cpu;
+
+ if (cr0 & CPC0_CR0_U0EC)
+ /* External UART clock */
+ uart0 = ser_clk;
+ else
+ /* Internal UART clock */
+ uart0 = plb / CPC0_CR0_UDIV(cr0);
+
+ if (cr0 & CPC0_CR0_U1EC)
+ /* External UART clock */
+ uart1 = ser_clk;
+ else
+ /* Internal UART clock */
+ uart1 = plb / CPC0_CR0_UDIV(cr0);
+
+ printf("PPC440GP: SysClk = %dMHz (%x)\n\r",
+ (sysclk + 500000) / 1000000, sysclk);
+
+ dt_fixup_cpu_clocks(cpu, tb, 0);
+
+ dt_fixup_clock("/plb", plb);
+ dt_fixup_clock("/plb/opb", opb);
+ dt_fixup_clock("/plb/opb/ebc", ebc);
+ dt_fixup_clock("/plb/opb/serial@40000200", uart0);
+ dt_fixup_clock("/plb/opb/serial@40000300", uart1);
+}
+
+static void ebony_fixups(void)
+{
+ // FIXME: sysclk should be derived by reading the FPGA registers
+ unsigned long sysclk = 33000000;
+
+ ibm440gp_fixup_clocks(sysclk, 6 * 1843200);
+ ibm44x_fixup_memsize();
+ dt_fixup_mac_addresses(ebony_mac0, ebony_mac1);
+}
+
+#define SPRN_DBCR0 0x134
+#define DBCR0_RST_SYSTEM 0x30000000
+
+static void ebony_exit(void)
+{
+ unsigned long tmp;
+
+ asm volatile (
+ "mfspr %0,%1\n"
+ "oris %0,%0,%2@h\n"
+ "mtspr %1,%0"
+ : "=&r"(tmp) : "i"(SPRN_DBCR0), "i"(DBCR0_RST_SYSTEM)
+ );
+
+}
+
+void ebony_init(void *mac0, void *mac1)
+{
+ platform_ops.fixups = ebony_fixups;
+ platform_ops.exit = ebony_exit;
+ ebony_mac0 = mac0;
+ ebony_mac1 = mac1;
+ ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
+ serial_console_init();
+}
diff --git a/arch/powerpc/boot/holly.c b/arch/powerpc/boot/holly.c
new file mode 100644
index 0000000..7d6539f
--- /dev/null
+++ b/arch/powerpc/boot/holly.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2007 IBM Corporation
+ *
+ * Stephen Winiecki <stevewin@us.ibm.com>
+ * Josh Boyer <jwboyer@linux.vnet.ibm.com>
+ *
+ * Based on earlier code:
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ */
+#include <stdarg.h>
+#include <stddef.h>
+#include "types.h"
+#include "elf.h"
+#include "string.h"
+#include "stdio.h"
+#include "page.h"
+#include "ops.h"
+#include "io.h"
+
+extern char _start[];
+extern char _end[];
+extern char _dtb_start[];
+extern char _dtb_end[];
+
+BSS_STACK(4096);
+
+void platform_init(unsigned long r3, unsigned long r4, unsigned long r5)
+{
+ u32 heapsize = 0x8000000 - (u32)_end; /* 128M */
+
+ simple_alloc_init(_end, heapsize, 32, 64);
+ ft_init(_dtb_start, 0, 4);
+ serial_console_init();
+}
diff --git a/arch/powerpc/boot/mktree.c b/arch/powerpc/boot/mktree.c
index 4cb8929..45d06a8 100644
--- a/arch/powerpc/boot/mktree.c
+++ b/arch/powerpc/boot/mktree.c
@@ -46,8 +46,8 @@
struct stat st;
boot_block_t bt;
- if (argc < 3) {
- fprintf(stderr, "usage: %s <zImage-file> <boot-image> [entry-point]\n",argv[0]);
+ if (argc < 5) {
+ fprintf(stderr, "usage: %s <zImage-file> <boot-image> <load address> <entry point>\n",argv[0]);
exit(1);
}
@@ -61,10 +61,8 @@
bt.bb_magic = htonl(0x0052504F);
/* If we have the optional entry point parameter, use it */
- if (argc == 4)
- bt.bb_dest = bt.bb_entry_point = htonl(strtoul(argv[3], NULL, 0));
- else
- bt.bb_dest = bt.bb_entry_point = htonl(0x500000);
+ bt.bb_dest = htonl(strtoul(argv[3], NULL, 0));
+ bt.bb_entry_point = htonl(strtoul(argv[4], NULL, 0));
/* We know these from the linker command.
* ...and then move it up into memory a little more so the
diff --git a/arch/powerpc/boot/treeboot-ebony.c b/arch/powerpc/boot/treeboot-ebony.c
new file mode 100644
index 0000000..8436a9c
--- /dev/null
+++ b/arch/powerpc/boot/treeboot-ebony.c
@@ -0,0 +1,34 @@
+/*
+ * Old U-boot compatibility for Ebony
+ *
+ * Author: David Gibson <david@gibson.dropbear.id.au>
+ *
+ * Copyright 2007 David Gibson, IBM Corporatio.
+ * Based on cuboot-83xx.c, which is:
+ * Copyright (c) 2007 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include "ops.h"
+#include "stdio.h"
+#include "44x.h"
+
+extern char _end[];
+
+BSS_STACK(4096);
+
+#define OPENBIOS_MAC_BASE 0xfffffe0c
+#define OPENBIOS_MAC_OFFSET 0xc
+
+void platform_init(void)
+{
+ unsigned long end_of_ram = 0x8000000;
+ unsigned long avail_ram = end_of_ram - (unsigned long)_end;
+
+ simple_alloc_init(_end, avail_ram, 32, 64);
+ ebony_init((u8 *)OPENBIOS_MAC_BASE,
+ (u8 *)(OPENBIOS_MAC_BASE + OPENBIOS_MAC_OFFSET));
+}
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper
index 5cedd90..2ed8b8b 100755
--- a/arch/powerpc/boot/wrapper
+++ b/arch/powerpc/boot/wrapper
@@ -163,20 +163,19 @@
vmz="$vmz$gzip"
-case "$platform" in
-uboot|cuboot*)
- version=`${CROSS}strings "$kernel" | grep '^Linux version [-0-9.]' | \
- cut -d' ' -f3`
- if [ -n "$version" ]; then
- version="-n Linux-$version"
- fi
-esac
+# Extract kernel version information, some platforms want to include
+# it in the image header
+version=`${CROSS}strings "$kernel" | grep '^Linux version [-0-9.]' | \
+ cut -d' ' -f3`
+if [ -n "$version" ]; then
+ uboot_version="-n Linux-$version"
+fi
case "$platform" in
uboot)
rm -f "$ofile"
mkimage -A ppc -O linux -T kernel -C gzip -a 00000000 -e 00000000 \
- $version -d "$vmz" "$ofile"
+ $uboot_version -d "$vmz" "$ofile"
if [ -z "$cacheit" ]; then
rm -f "$vmz"
fi
@@ -212,25 +211,32 @@
rm $tmp
fi
+# Some platforms need the zImage's entry point and base address
+base=0x`${CROSS}nm "$ofile" | grep ' _start$' | cut -d' ' -f1`
+entry=`${CROSS}objdump -f "$ofile" | grep '^start address ' | cut -d' ' -f3`
+
# post-processing needed for some platforms
case "$platform" in
pseries|chrp)
$object/addnote "$ofile"
;;
pmaccoff)
- entry=`objdump -f "$ofile" | grep '^start address ' | \
- cut -d' ' -f3`
${CROSS}objcopy -O aixcoff-rs6000 --set-start "$entry" "$ofile"
$object/hack-coff "$ofile"
;;
cuboot*)
- base=`${CROSS}nm "$ofile" | grep ' _start$' | cut -d' ' -f1`
- entry=`${CROSS}objdump -f "$ofile" | grep '^start address ' | \
- cut -d' ' -f3`
mv "$ofile" "$ofile".elf
${CROSS}objcopy -O binary "$ofile".elf "$ofile".bin
gzip -f -9 "$ofile".bin
mkimage -A ppc -O linux -T kernel -C gzip -a "$base" -e "$entry" \
- $version -d "$ofile".bin.gz "$ofile"
+ $uboot_version -d "$ofile".bin.gz "$ofile"
+ ;;
+treeboot*)
+ mv "$ofile" "$ofile.elf"
+ $object/mktree "$ofile.elf" "$ofile" "$base" "$entry"
+ if [ -z "$cacheit" ]; then
+ rm -f "$ofile.elf"
+ fi
+ exit 0
;;
esac
diff --git a/arch/powerpc/configs/ebony_defconfig b/arch/powerpc/configs/ebony_defconfig
new file mode 100644
index 0000000..c3b96ef
--- /dev/null
+++ b/arch/powerpc/configs/ebony_defconfig
@@ -0,0 +1,905 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.21
+# Fri May 4 13:47:08 2007
+#
+# CONFIG_PPC64 is not set
+CONFIG_PPC32=y
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+# CONFIG_PPC_UDBG_16550 is not set
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+# CONFIG_DEFAULT_UIMAGE is not set
+
+#
+# Processor support
+#
+# CONFIG_CLASSIC32 is not set
+# CONFIG_PPC_82xx is not set
+# CONFIG_PPC_83xx is not set
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_86xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+CONFIG_44x=y
+# CONFIG_E200 is not set
+CONFIG_PPC_DCR_NATIVE=y
+# CONFIG_PPC_DCR_MMIO is not set
+CONFIG_PPC_DCR=y
+CONFIG_4xx=y
+CONFIG_BOOKE=y
+CONFIG_PTE_64BIT=y
+CONFIG_PHYS_64BIT=y
+CONFIG_NOT_COHERENT_CACHE=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+CONFIG_LBD=y
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# Platform support
+#
+# CONFIG_PPC_MPC52xx is not set
+# CONFIG_PPC_MPC5200 is not set
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PQ2ADS is not set
+CONFIG_EBONY=y
+CONFIG_440GP=y
+# CONFIG_MPIC is not set
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_CPM2 is not set
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_MATH_EMULATION=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_RESOURCES_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_SECCOMP=y
+CONFIG_WANT_DEVICE_TREE=y
+CONFIG_DEVICE_TREE="ebony.dts"
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_PPC_INDIRECT_PCI=y
+# CONFIG_PPC_INDIRECT_PCI_BE is not set
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_PCIEPORTBUS is not set
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_CONSISTENT_START=0xff100000
+CONFIG_CONSISTENT_SIZE=0x00200000
+CONFIG_BOOT_LOAD=0x01000000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNPACPI is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=35000
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# Misc devices
+#
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+
+#
+# Ethernet (10 or 100Mbit)
+#
+# CONFIG_NET_ETHERNET is not set
+CONFIG_IBM_NEW_EMAC=y
+CONFIG_IBM_NEW_EMAC_RXB=128
+CONFIG_IBM_NEW_EMAC_TXB=64
+CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32
+CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256
+CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0
+# CONFIG_IBM_NEW_EMAC_DEBUG is not set
+CONFIG_IBM_NEW_EMAC_ZMII=y
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_RSA is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_FB is not set
+# CONFIG_FB_IBM_GXT4500 is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+# CONFIG_UCC_SLOW is not set
+# CONFIG_UCC_FAST is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+
+#
+# Instrumentation Support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_DEBUGGER is not set
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_SERIAL_TEXT_DEBUG is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=y
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
diff --git a/arch/powerpc/configs/holly_defconfig b/arch/powerpc/configs/holly_defconfig
new file mode 100644
index 0000000..be633b9
--- /dev/null
+++ b/arch/powerpc/configs/holly_defconfig
@@ -0,0 +1,1070 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.21
+# Sat May 5 11:02:35 2007
+#
+# CONFIG_PPC64 is not set
+CONFIG_PPC32=y
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_PPC_UDBG_16550=y
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+# CONFIG_DEFAULT_UIMAGE is not set
+
+#
+# Processor support
+#
+CONFIG_CLASSIC32=y
+# CONFIG_PPC_82xx is not set
+# CONFIG_PPC_83xx is not set
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_86xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+CONFIG_6xx=y
+CONFIG_PPC_FPU=y
+# CONFIG_PPC_DCR_NATIVE is not set
+# CONFIG_PPC_DCR_MMIO is not set
+# CONFIG_ALTIVEC is not set
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_SMP is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODULE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_KMOD is not set
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+CONFIG_LBD=y
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# Platform support
+#
+# CONFIG_PPC_MULTIPLATFORM is not set
+CONFIG_EMBEDDED6xx=y
+# CONFIG_APUS is not set
+# CONFIG_PPC_MPC52xx is not set
+# CONFIG_PPC_MPC5200 is not set
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PQ2ADS is not set
+# CONFIG_LINKSTATION is not set
+# CONFIG_MPC7448HPC2 is not set
+CONFIG_PPC_HOLLY=y
+CONFIG_TSI108_BRIDGE=y
+CONFIG_MPIC=y
+CONFIG_MPIC_WEIRD=y
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_TAU is not set
+# CONFIG_CPM2 is not set
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+# CONFIG_SECCOMP is not set
+# CONFIG_WANT_DEVICE_TREE is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_ISA_DMA=y
+# CONFIG_PPC_INDIRECT_PCI is not set
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_PCIEPORTBUS is not set
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_BOOT_LOAD=0x00800000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNPACPI is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=131072
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# Misc devices
+#
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_ESP_CORE is not set
+# CONFIG_SCSI_SRP is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_SATA_INIC162X is not set
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD640_PCI is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+# CONFIG_PATA_PLATFORM is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+CONFIG_NET_VENDOR_3COM=y
+CONFIG_VORTEX=y
+# CONFIG_TYPHOON is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+CONFIG_TSI108_ETH=y
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_RSA is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+CONFIG_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_FB is not set
+# CONFIG_FB_IBM_GXT4500 is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+# CONFIG_UCC_SLOW is not set
+# CONFIG_UCC_FAST is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+
+#
+# Instrumentation Support
+#
+# CONFIG_PROFILING is not set
+# CONFIG_KPROBES is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_DEBUGGER=y
+CONFIG_XMON=y
+CONFIG_XMON_DEFAULT=y
+CONFIG_XMON_DISASSEMBLY=y
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
diff --git a/arch/powerpc/configs/mpc832x_mds_defconfig b/arch/powerpc/configs/mpc832x_mds_defconfig
index e1b36de..83192c0 100644
--- a/arch/powerpc/configs/mpc832x_mds_defconfig
+++ b/arch/powerpc/configs/mpc832x_mds_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20-rc5
-# Tue Jan 30 14:27:25 2007
+# Linux kernel version: 2.6.21-rc5
+# Mon Apr 9 16:09:16 2007
#
# CONFIG_PPC64 is not set
CONFIG_PPC32=y
@@ -34,9 +34,9 @@
CONFIG_PPC_83xx=y
# CONFIG_PPC_85xx is not set
# CONFIG_PPC_86xx is not set
+# CONFIG_PPC_8xx is not set
# CONFIG_40x is not set
# CONFIG_44x is not set
-# CONFIG_8xx is not set
# CONFIG_E200 is not set
CONFIG_6xx=y
CONFIG_83xx=y
@@ -63,6 +63,7 @@
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
@@ -71,6 +72,7 @@
# CONFIG_IKCONFIG is not set
CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
@@ -123,16 +125,17 @@
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
CONFIG_QUICC_ENGINE=y
-CONFIG_PPC_GEN550=y
# CONFIG_WANT_EARLY_SERIAL is not set
#
# Platform support
#
+# CONFIG_MPC8313_RDB is not set
CONFIG_MPC832x_MDS=y
-# CONFIG_MPC834x_SYS is not set
+# CONFIG_MPC832x_RDB is not set
+# CONFIG_MPC834x_MDS is not set
# CONFIG_MPC834x_ITX is not set
-# CONFIG_MPC8360E_PB is not set
+# CONFIG_MPC836x_MDS is not set
CONFIG_PPC_MPC832x=y
# CONFIG_MPIC is not set
@@ -163,6 +166,7 @@
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
CONFIG_PROC_DEVICETREE=y
# CONFIG_CMDLINE_BOOL is not set
# CONFIG_PM is not set
@@ -172,6 +176,7 @@
#
# Bus options
#
+CONFIG_ZONE_DMA=y
CONFIG_GENERIC_ISA_DMA=y
# CONFIG_MPIC_WEIRD is not set
# CONFIG_PPC_I8259 is not set
@@ -220,6 +225,7 @@
CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
@@ -324,6 +330,7 @@
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -342,7 +349,6 @@
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=32768
CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-CONFIG_BLK_DEV_INITRD=y
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
@@ -482,7 +488,21 @@
#
# PHY device support
#
-# CONFIG_PHYLIB is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+CONFIG_DAVICOM_PHY=y
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_FIXED_PHY is not set
#
# Ethernet (10 or 100Mbit)
@@ -524,11 +544,13 @@
# CONFIG_UGETH_FILTERING is not set
# CONFIG_UGETH_TX_ON_DEMOND is not set
# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
#
# Ethernet (10000 Mbit)
#
# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
# CONFIG_MYRI10GE is not set
@@ -621,6 +643,7 @@
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_OF_PLATFORM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -691,6 +714,7 @@
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PASEMI is not set
# CONFIG_I2C_PROSAVAGE is not set
# CONFIG_I2C_SAVAGE4 is not set
# CONFIG_I2C_SIS5595 is not set
@@ -738,6 +762,7 @@
# CONFIG_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
# CONFIG_SENSORS_ASB100 is not set
@@ -779,6 +804,11 @@
# CONFIG_HWMON_DEBUG_CHIP is not set
#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -791,10 +821,9 @@
#
# Graphics support
#
-CONFIG_FIRMWARE_EDID=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
# CONFIG_FB is not set
# CONFIG_FB_IBM_GXT4500 is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -805,6 +834,7 @@
# HID Devices
#
CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
#
# USB support
@@ -869,6 +899,10 @@
#
#
+# Auxiliary Display support
+#
+
+#
# Virtualization
#
@@ -995,11 +1029,7 @@
# Distributed Lock Manager
#
# CONFIG_DLM is not set
-
-#
-# QE Options
-#
-CONFIG_UCC_SLOW=y
+# CONFIG_UCC_SLOW is not set
CONFIG_UCC_FAST=y
CONFIG_UCC=y
@@ -1012,7 +1042,8 @@
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_PLIST=y
-CONFIG_IOMAP_COPY=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
#
# Instrumentation Support
@@ -1032,7 +1063,6 @@
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_DEBUG_BUGVERBOSE is not set
# CONFIG_BOOTX_TEXT is not set
-# CONFIG_SERIAL_TEXT_DEBUG is not set
# CONFIG_PPC_EARLY_DEBUG is not set
#
@@ -1061,8 +1091,10 @@
# CONFIG_CRYPTO_GF128MUL is not set
CONFIG_CRYPTO_ECB=m
CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=m
# CONFIG_CRYPTO_LRW is not set
CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_TWOFISH is not set
# CONFIG_CRYPTO_SERPENT is not set
@@ -1076,6 +1108,7 @@
# CONFIG_CRYPTO_DEFLATE is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_TEST is not set
#
diff --git a/arch/powerpc/configs/mpc832x_rdb_defconfig b/arch/powerpc/configs/mpc832x_rdb_defconfig
index 56fc0a8..4a4da87 100644
--- a/arch/powerpc/configs/mpc832x_rdb_defconfig
+++ b/arch/powerpc/configs/mpc832x_rdb_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.21-rc3
-# Mon Mar 12 17:32:19 2007
+# Linux kernel version: 2.6.21-rc5
+# Mon Apr 9 16:12:43 2007
#
# CONFIG_PPC64 is not set
CONFIG_PPC32=y
@@ -125,7 +125,6 @@
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
CONFIG_QUICC_ENGINE=y
-CONFIG_PPC_GEN550=y
# CONFIG_WANT_EARLY_SERIAL is not set
#
@@ -490,7 +489,21 @@
#
# PHY device support
#
-# CONFIG_PHYLIB is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+CONFIG_ICPLUS_PHY=y
+# CONFIG_FIXED_PHY is not set
#
# Ethernet (10 or 100Mbit)
@@ -1200,11 +1213,7 @@
# Distributed Lock Manager
#
# CONFIG_DLM is not set
-
-#
-# QE Options
-#
-CONFIG_UCC_SLOW=y
+# CONFIG_UCC_SLOW is not set
CONFIG_UCC_FAST=y
CONFIG_UCC=y
@@ -1238,7 +1247,6 @@
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_DEBUG_BUGVERBOSE is not set
# CONFIG_BOOTX_TEXT is not set
-# CONFIG_SERIAL_TEXT_DEBUG is not set
# CONFIG_PPC_EARLY_DEBUG is not set
#
diff --git a/arch/powerpc/configs/mpc836x_mds_defconfig b/arch/powerpc/configs/mpc836x_mds_defconfig
index 8eb475c..921a151 100644
--- a/arch/powerpc/configs/mpc836x_mds_defconfig
+++ b/arch/powerpc/configs/mpc836x_mds_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20
-# Sat Feb 17 10:09:26 2007
+# Linux kernel version: 2.6.21-rc5
+# Mon Apr 9 16:14:05 2007
#
# CONFIG_PPC64 is not set
CONFIG_PPC32=y
@@ -72,6 +72,7 @@
# CONFIG_IKCONFIG is not set
CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
@@ -124,7 +125,6 @@
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
CONFIG_QUICC_ENGINE=y
-CONFIG_PPC_GEN550=y
# CONFIG_WANT_EARLY_SERIAL is not set
#
@@ -132,6 +132,7 @@
#
# CONFIG_MPC8313_RDB is not set
# CONFIG_MPC832x_MDS is not set
+# CONFIG_MPC832x_RDB is not set
# CONFIG_MPC834x_MDS is not set
# CONFIG_MPC834x_ITX is not set
CONFIG_MPC836x_MDS=y
@@ -328,6 +329,7 @@
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -346,7 +348,6 @@
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=32768
CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-CONFIG_BLK_DEV_INITRD=y
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
@@ -486,7 +487,21 @@
#
# PHY device support
#
-# CONFIG_PHYLIB is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_FIXED_PHY is not set
#
# Ethernet (10 or 100Mbit)
@@ -528,6 +543,7 @@
# CONFIG_UGETH_FILTERING is not set
# CONFIG_UGETH_TX_ON_DEMOND is not set
# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
#
# Ethernet (10000 Mbit)
@@ -745,6 +761,7 @@
# CONFIG_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
# CONFIG_SENSORS_ASB100 is not set
@@ -786,6 +803,11 @@
# CONFIG_HWMON_DEBUG_CHIP is not set
#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -798,10 +820,9 @@
#
# Graphics support
#
-CONFIG_FIRMWARE_EDID=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
# CONFIG_FB is not set
# CONFIG_FB_IBM_GXT4500 is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -1007,11 +1028,7 @@
# Distributed Lock Manager
#
# CONFIG_DLM is not set
-
-#
-# QE Options
-#
-CONFIG_UCC_SLOW=y
+# CONFIG_UCC_SLOW is not set
CONFIG_UCC_FAST=y
CONFIG_UCC=y
@@ -1045,7 +1062,6 @@
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_DEBUG_BUGVERBOSE is not set
# CONFIG_BOOTX_TEXT is not set
-# CONFIG_SERIAL_TEXT_DEBUG is not set
# CONFIG_PPC_EARLY_DEBUG is not set
#
diff --git a/arch/powerpc/configs/ps3_defconfig b/arch/powerpc/configs/ps3_defconfig
index 0345a2c..fd60496 100644
--- a/arch/powerpc/configs/ps3_defconfig
+++ b/arch/powerpc/configs/ps3_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20-rc6
-# Thu Jan 25 13:35:34 2007
+# Linux kernel version: 2.6.21
+# Mon Apr 30 12:03:35 2007
#
CONFIG_PPC64=y
CONFIG_64BIT=y
@@ -60,6 +60,7 @@
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
@@ -69,6 +70,7 @@
# CONFIG_CPUSETS is not set
CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
@@ -131,13 +133,36 @@
# CONFIG_PPC_PSERIES is not set
# CONFIG_PPC_ISERIES is not set
# CONFIG_PPC_MPC52xx is not set
+# CONFIG_PPC_MPC5200 is not set
# CONFIG_PPC_PMAC is not set
# CONFIG_PPC_MAPLE is not set
# CONFIG_PPC_PASEMI is not set
+# CONFIG_PPC_CELLEB is not set
+CONFIG_PPC_PS3=y
+
+#
+# PS3 Platform Options
+#
+# CONFIG_PS3_ADVANCED is not set
+CONFIG_PS3_HTAB_SIZE=20
+# CONFIG_PS3_DYNAMIC_DMA is not set
+CONFIG_PS3_USE_LPAR_ADDR=y
+CONFIG_PS3_VUART=y
+CONFIG_PS3_PS3AV=y
+CONFIG_PS3_SYS_MANAGER=y
CONFIG_PPC_CELL=y
# CONFIG_PPC_CELL_NATIVE is not set
# CONFIG_PPC_IBM_CELL_BLADE is not set
-CONFIG_PPC_PS3=y
+
+#
+# Cell Broadband Engine options
+#
+CONFIG_SPU_FS=y
+CONFIG_SPU_BASE=y
+# CONFIG_PQ2ADS is not set
+# CONFIG_MPIC is not set
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
# CONFIG_U3_DART is not set
# CONFIG_PPC_RTAS is not set
# CONFIG_MMIO_NVRAM is not set
@@ -146,24 +171,7 @@
# CONFIG_PPC_INDIRECT_IO is not set
# CONFIG_GENERIC_IOMAP is not set
# CONFIG_CPU_FREQ is not set
-# CONFIG_WANT_EARLY_SERIAL is not set
-# CONFIG_MPIC is not set
-
-#
-# Cell Broadband Engine options
-#
-CONFIG_SPU_FS=y
-CONFIG_SPU_BASE=y
-# CONFIG_CBE_RAS is not set
-
-#
-# PS3 Platform Options
-#
-CONFIG_PS3_HTAB_SIZE=20
-# CONFIG_PS3_DYNAMIC_DMA is not set
-CONFIG_PS3_USE_LPAR_ADDR=y
-CONFIG_PS3_VUART=y
-CONFIG_PS3_PS3AV=y
+# CONFIG_CPM2 is not set
#
# Kernel options
@@ -179,10 +187,10 @@
# CONFIG_PREEMPT_BKL is not set
CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_MISC=y
-CONFIG_FORCE_MAX_ZONEORDER=9
+CONFIG_FORCE_MAX_ZONEORDER=13
# CONFIG_IOMMU_VMERGE is not set
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
-# CONFIG_KEXEC is not set
+CONFIG_KEXEC=y
# CONFIG_CRASH_DUMP is not set
# CONFIG_IRQ_ALL_CPUS is not set
# CONFIG_NUMA is not set
@@ -203,22 +211,22 @@
CONFIG_MEMORY_HOTPLUG_SPARSE=y
CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_RESOURCES_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
CONFIG_ARCH_MEMORY_PROBE=y
-CONFIG_PPC_64K_PAGES=y
+# CONFIG_PPC_64K_PAGES is not set
# CONFIG_SCHED_SMT is not set
CONFIG_PROC_DEVICETREE=y
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="root=/dev/sda1 ip=dhcp"
+# CONFIG_CMDLINE_BOOL is not set
# CONFIG_PM is not set
# CONFIG_SECCOMP is not set
+# CONFIG_WANT_DEVICE_TREE is not set
CONFIG_ISA_DMA_API=y
#
# Bus options
#
+CONFIG_ZONE_DMA=y
CONFIG_GENERIC_ISA_DMA=y
-# CONFIG_MPIC_WEIRD is not set
-# CONFIG_PPC_I8259 is not set
# CONFIG_PCI is not set
# CONFIG_PCI_DOMAINS is not set
@@ -240,10 +248,13 @@
#
# Networking options
#
-# CONFIG_NETDEBUG is not set
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
@@ -261,7 +272,7 @@
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_TUNNEL=y
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
# CONFIG_INET_XFRM_MODE_BEET is not set
@@ -270,9 +281,23 @@
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_TCP_MD5SIG is not set
-# CONFIG_IPV6 is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_BEET=y
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
@@ -313,7 +338,31 @@
# CONFIG_NET_PKTGEN is not set
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
-# CONFIG_BT is not set
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+# CONFIG_BT_RFCOMM_TTY is not set
+# CONFIG_BT_BNEP is not set
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+# CONFIG_BT_HCIUART is not set
+# CONFIG_BT_HCIBCM203X is not set
+# CONFIG_BT_HCIBPA10X is not set
+# CONFIG_BT_HCIBFUSB is not set
+# CONFIG_BT_HCIVHCI is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_EXT=y
# CONFIG_IEEE80211 is not set
#
@@ -327,16 +376,13 @@
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
#
# Connector - unified userspace <-> kernelspace linker
#
# CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
# CONFIG_MTD is not set
#
@@ -347,24 +393,27 @@
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
#
# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_LOOP is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_UB is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=65535
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
#
# Misc devices
#
-# CONFIG_TIFM_CORE is not set
#
# ATA/ATAPI/MFM/RLL support
@@ -388,7 +437,7 @@
# CONFIG_CHR_DEV_OSST is not set
CONFIG_BLK_DEV_SR=y
# CONFIG_BLK_DEV_SR_VENDOR is not set
-# CONFIG_CHR_DEV_SG is not set
+CONFIG_CHR_DEV_SG=m
# CONFIG_CHR_DEV_SCH is not set
#
@@ -413,6 +462,7 @@
#
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_ESP_CORE is not set
#
# Serial ATA (prod) and Parallel ATA (experimental) drivers
@@ -460,7 +510,7 @@
# Ethernet (10 or 100Mbit)
#
# CONFIG_NET_ETHERNET is not set
-CONFIG_MII=y
+CONFIG_MII=m
#
# Ethernet (1000 Mbit)
@@ -475,9 +525,10 @@
#
#
-# Wireless LAN (non-hamradio)
+# Wireless LAN
#
-# CONFIG_NET_RADIO is not set
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
#
# Wan interfaces
@@ -551,7 +602,8 @@
# Non-8250 serial port support
#
CONFIG_UNIX98_PTYS=y
-# CONFIG_LEGACY_PTYS is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=16
#
# IPMI
@@ -598,6 +650,11 @@
# CONFIG_HWMON_VID is not set
#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -611,15 +668,22 @@
#
# Graphics support
#
-# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_SVGALIB is not set
# CONFIG_FB_MACMODES is not set
# CONFIG_FB_BACKLIGHT is not set
# CONFIG_FB_MODE_HELPERS is not set
# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
# CONFIG_FB_OF is not set
# CONFIG_FB_VGA16 is not set
# CONFIG_FB_S1D13XXX is not set
@@ -634,7 +698,7 @@
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
-# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
# CONFIG_FONTS is not set
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
@@ -646,17 +710,62 @@
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
CONFIG_LOGO_LINUX_CLUT224=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
#
-# CONFIG_SOUND is not set
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# ALSA PowerMac devices
+#
+
+#
+# ALSA PowerMac requires I2C
+#
+
+#
+# USB devices
+#
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_USX2Y is not set
+
+#
+# SoC audio support
+#
+# CONFIG_SND_SOC is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
#
# HID Devices
#
CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
#
# USB support
@@ -665,13 +774,13 @@
CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_USB_ARCH_HAS_EHCI=y
CONFIG_USB=y
-CONFIG_USB_DEBUG=y
+# CONFIG_USB_DEBUG is not set
#
# Miscellaneous USB options
#
-# CONFIG_USB_DEVICEFS is not set
-# CONFIG_USB_BANDWIDTH is not set
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
# CONFIG_USB_DYNAMIC_MINORS is not set
# CONFIG_USB_OTG is not set
@@ -704,7 +813,7 @@
#
# may also be needed; see USB_STORAGE Help for more information
#
-CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE=m
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
@@ -720,10 +829,16 @@
#
# USB Input Devices
#
-CONFIG_USB_HID=y
+CONFIG_USB_HID=m
# CONFIG_USB_HIDINPUT_POWERBOOK is not set
# CONFIG_HID_FF is not set
# CONFIG_USB_HIDDEV is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
# CONFIG_USB_AIPTEK is not set
# CONFIG_USB_WACOM is not set
# CONFIG_USB_ACECAD is not set
@@ -736,6 +851,7 @@
# CONFIG_USB_ATI_REMOTE2 is not set
# CONFIG_USB_KEYSPAN_REMOTE is not set
# CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_GTCO is not set
#
# USB Imaging devices
@@ -748,15 +864,16 @@
#
# CONFIG_USB_CATC is not set
# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
+CONFIG_USB_PEGASUS=m
# CONFIG_USB_RTL8150 is not set
-CONFIG_USB_USBNET_MII=y
-CONFIG_USB_USBNET=y
-CONFIG_USB_NET_CDCETHER=y
+CONFIG_USB_USBNET_MII=m
+CONFIG_USB_USBNET=m
+# CONFIG_USB_NET_CDCETHER is not set
+# CONFIG_USB_NET_DM9601 is not set
# CONFIG_USB_NET_GL620A is not set
# CONFIG_USB_NET_NET1080 is not set
# CONFIG_USB_NET_PLUSB is not set
-CONFIG_USB_NET_MCS7830=y
+CONFIG_USB_NET_MCS7830=m
# CONFIG_USB_NET_RNDIS_HOST is not set
# CONFIG_USB_NET_CDC_SUBSET is not set
# CONFIG_USB_NET_ZAURUS is not set
@@ -781,6 +898,7 @@
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
@@ -791,6 +909,8 @@
# CONFIG_USB_SISUSBVGA is not set
# CONFIG_USB_LD is not set
# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
#
# USB DSL modem support
@@ -846,13 +966,19 @@
#
#
+# Auxiliary Display support
+#
+
+#
# Virtualization
#
#
# File systems
#
-# CONFIG_EXT2_FS is not set
+CONFIG_EXT2_FS=m
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -871,27 +997,30 @@
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
-# CONFIG_QUOTA is not set
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
+CONFIG_AUTOFS4_FS=y
# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
#
-CONFIG_ISO9660_FS=y
+CONFIG_ISO9660_FS=m
CONFIG_JOLIET=y
# CONFIG_ZISOFS is not set
-CONFIG_UDF_FS=y
+CONFIG_UDF_FS=m
CONFIG_UDF_NLS=y
#
# DOS/FAT/NT Filesystems
#
-CONFIG_FAT_FS=y
+CONFIG_FAT_FS=m
# CONFIG_MSDOS_FS is not set
-CONFIG_VFAT_FS=y
+CONFIG_VFAT_FS=m
CONFIG_FAT_DEFAULT_CODEPAGE=437
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
# CONFIG_NTFS_FS is not set
@@ -933,7 +1062,7 @@
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
# CONFIG_NFS_V3_ACL is not set
-# CONFIG_NFS_V4 is not set
+CONFIG_NFS_V4=y
# CONFIG_NFS_DIRECTIO is not set
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
@@ -941,10 +1070,16 @@
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
@@ -1004,6 +1139,8 @@
# Distributed Lock Manager
#
# CONFIG_DLM is not set
+# CONFIG_UCC_SLOW is not set
+# CONFIG_UCC_FAST is not set
#
# Library routines
@@ -1014,7 +1151,8 @@
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_PLIST=y
-CONFIG_IOMAP_COPY=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
#
# Instrumentation Support
@@ -1032,16 +1170,16 @@
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
CONFIG_LOG_BUF_SHIFT=17
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
-CONFIG_DEBUG_SLAB=y
-# CONFIG_DEBUG_SLAB_LEAK is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
-CONFIG_DEBUG_RWSEMS=y
CONFIG_DEBUG_SPINLOCK_SLEEP=y
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
@@ -1051,8 +1189,10 @@
CONFIG_DEBUG_LIST=y
CONFIG_FORCED_INLINING=y
# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
CONFIG_DEBUG_STACKOVERFLOW=y
# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
# CONFIG_DEBUGGER is not set
CONFIG_IRQSTACKS=y
# CONFIG_BOOTX_TEXT is not set
@@ -1063,6 +1203,8 @@
# CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE is not set
# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set
# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set
+# CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE is not set
+# CONFIG_PPC_EARLY_DEBUG_BEAT is not set
#
# Security options
@@ -1073,4 +1215,43 @@
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index aa693d0..3e779f0 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -36,8 +36,9 @@
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o
obj-$(CONFIG_TAU) += tau_6xx.o
+obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o suspend.o
obj32-$(CONFIG_SOFTWARE_SUSPEND) += swsusp_32.o
-obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend.o
+obj64-$(CONFIG_SOFTWARE_SUSPEND) += swsusp_64.o swsusp_asm64.o
obj32-$(CONFIG_MODULES) += module_32.o
ifeq ($(CONFIG_PPC_MERGE),y)
@@ -67,6 +68,7 @@
pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o
pci32-$(CONFIG_PPC32) := pci_32.o
obj-$(CONFIG_PCI) += $(pci64-y) $(pci32-y)
+obj-$(CONFIG_PCI_MSI) += msi.o
kexec-$(CONFIG_PPC64) := machine_kexec_64.o
kexec-$(CONFIG_PPC32) := machine_kexec_32.o
obj-$(CONFIG_KEXEC) += machine_kexec.o crash.o $(kexec-y)
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 0c5150c..8f48560 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -21,12 +21,12 @@
#include <linux/types.h>
#include <linux/mman.h>
#include <linux/mm.h>
+#include <linux/suspend.h>
#ifdef CONFIG_PPC64
#include <linux/time.h>
#include <linux/hardirq.h>
#else
#include <linux/ptrace.h>
-#include <linux/suspend.h>
#endif
#include <asm/io.h>
@@ -257,11 +257,11 @@
DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
DEFINE(CPU_SPEC_RESTORE, offsetof(struct cpu_spec, cpu_restore));
-#ifndef CONFIG_PPC64
DEFINE(pbe_address, offsetof(struct pbe, address));
DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address));
DEFINE(pbe_next, offsetof(struct pbe, next));
+#ifndef CONFIG_PPC64
DEFINE(TASK_SIZE, TASK_SIZE);
DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28);
#endif /* ! CONFIG_PPC64 */
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S
index a15d4b8..8869596 100644
--- a/arch/powerpc/kernel/head_44x.S
+++ b/arch/powerpc/kernel/head_44x.S
@@ -120,8 +120,8 @@
* Configure and load pinned entry into TLB slot 63.
*/
- lis r3,KERNELBASE@h /* Load the kernel virtual address */
- ori r3,r3,KERNELBASE@l
+ lis r3,PAGE_OFFSET@h
+ ori r3,r3,PAGE_OFFSET@l
/* Kernel is at the base of RAM */
li r4, 0 /* Load the kernel physical address */
@@ -172,36 +172,28 @@
isync
4:
-#ifdef CONFIG_SERIAL_TEXT_DEBUG
- /*
- * Add temporary UART mapping for early debug.
- * We can map UART registers wherever we want as long as they don't
- * interfere with other system mappings (e.g. with pinned entries).
- * For an example of how we handle this - see ocotea.h. --ebs
- */
+#ifdef CONFIG_PPC_EARLY_DEBUG_44x
+ /* Add UART mapping for early debug. */
+
/* pageid fields */
- lis r3,UART0_IO_BASE@h
- ori r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_4K
+ lis r3,PPC44x_EARLY_DEBUG_VIRTADDR@h
+ ori r3,r3,PPC44x_TLB_VALID|PPC44x_TLB_TS|PPC44x_TLB_64K
/* xlat fields */
- lis r4,UART0_PHYS_IO_BASE@h /* RPN depends on SoC */
-#ifndef CONFIG_440EP
- ori r4,r4,0x0001 /* ERPN is 1 for second 4GB page */
-#endif
+ lis r4,CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW@h
+ ori r4,r4,CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH
/* attrib fields */
- li r5,0
- ori r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_I | PPC44x_TLB_G)
+ li r5,(PPC44x_TLB_SW|PPC44x_TLB_SR|PPC44x_TLB_I|PPC44x_TLB_G)
+ li r0,62 /* TLB slot 0 */
- li r0,0 /* TLB slot 0 */
-
- tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */
- tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */
- tlbwe r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */
+ tlbwe r3,r0,PPC44x_TLB_PAGEID
+ tlbwe r4,r0,PPC44x_TLB_XLAT
+ tlbwe r5,r0,PPC44x_TLB_ATTRIB
/* Force context change */
isync
-#endif /* CONFIG_SERIAL_TEXT_DEBUG */
+#endif /* CONFIG_PPC_EARLY_DEBUG_44x */
/* Establish the interrupt vector offsets */
SET_IVOR(0, CriticalInput);
@@ -709,16 +701,6 @@
blr
#endif
-/*
- * extern void abort(void)
- *
- * At present, this routine just applies a system reset.
- */
-_GLOBAL(abort)
- mfspr r13,SPRN_DBCR0
- oris r13,r13,DBCR0_RST_SYSTEM@h
- mtspr SPRN_DBCR0,r13
-
_GLOBAL(set_context)
#ifdef CONFIG_BDI_SWITCH
diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c
index 6e7f509..a9e9cbd 100644
--- a/arch/powerpc/kernel/idle.c
+++ b/arch/powerpc/kernel/idle.c
@@ -33,8 +33,11 @@
#include <asm/smp.h>
#ifdef CONFIG_HOTPLUG_CPU
+/* this is used for software suspend, and that shuts down
+ * CPUs even while the system is still booting... */
#define cpu_should_die() (cpu_is_offline(smp_processor_id()) && \
- system_state == SYSTEM_RUNNING)
+ (system_state == SYSTEM_RUNNING \
+ || system_state == SYSTEM_BOOTING))
#else
#define cpu_should_die() 0
#endif
diff --git a/arch/powerpc/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S
index ba31954..5328709 100644
--- a/arch/powerpc/kernel/idle_power4.S
+++ b/arch/powerpc/kernel/idle_power4.S
@@ -53,3 +53,24 @@
isync
b 1b
+_GLOBAL(power4_cpu_offline_powersave)
+ /* Go to NAP now */
+ mfmsr r7
+ rldicl r0,r7,48,1
+ rotldi r0,r0,16
+ mtmsrd r0,1 /* hard-disable interrupts */
+ li r0,1
+ li r6,0
+ stb r0,PACAHARDIRQEN(r13) /* we'll hard-enable shortly */
+ stb r6,PACASOFTIRQEN(r13) /* soft-disable irqs */
+BEGIN_FTR_SECTION
+ DSSALL
+ sync
+END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+ ori r7,r7,MSR_EE
+ oris r7,r7,MSR_POW@h
+ sync
+ isync
+ mtmsrd r7
+ isync
+ blr
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 6c83fe2..9ed4931 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -67,6 +67,7 @@
#ifdef CONFIG_PPC64
#include <asm/paca.h>
#include <asm/firmware.h>
+#include <asm/lv1call.h>
#endif
int __irq_offset_value;
@@ -162,6 +163,16 @@
local_paca->hard_enabled = en;
if ((int)mfspr(SPRN_DEC) < 0)
mtspr(SPRN_DEC, 1);
+
+ /*
+ * Force the delivery of pending soft-disabled interrupts on PS3.
+ * Any HV call will have this side effect.
+ */
+ if (firmware_has_feature(FW_FEATURE_PS3_LV1)) {
+ u64 tmp;
+ lv1_get_version_info(&tmp);
+ }
+
hard_irq_enable();
}
#endif /* CONFIG_PPC64 */
@@ -947,33 +958,6 @@
#endif /* CONFIG_PPC_MERGE */
-#ifdef CONFIG_PCI_MSI
-int pci_enable_msi(struct pci_dev * pdev)
-{
- if (ppc_md.enable_msi)
- return ppc_md.enable_msi(pdev);
- else
- return -1;
-}
-EXPORT_SYMBOL(pci_enable_msi);
-
-void pci_disable_msi(struct pci_dev * pdev)
-{
- if (ppc_md.disable_msi)
- ppc_md.disable_msi(pdev);
-}
-EXPORT_SYMBOL(pci_disable_msi);
-
-void pci_scan_msi_device(struct pci_dev *dev) {}
-int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) {return -1;}
-void pci_disable_msix(struct pci_dev *dev) {}
-void msi_remove_pci_irq_vectors(struct pci_dev *dev) {}
-void pci_no_msi(void) {}
-EXPORT_SYMBOL(pci_enable_msix);
-EXPORT_SYMBOL(pci_disable_msix);
-
-#endif
-
#ifdef CONFIG_PPC64
static int __init setup_noirqdistrib(char *str)
{
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index ef647e7..0c96611 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -30,8 +30,8 @@
#include <linux/ptrace.h>
#include <linux/preempt.h>
#include <linux/module.h>
+#include <linux/kdebug.h>
#include <asm/cacheflush.h>
-#include <asm/kdebug.h>
#include <asm/sstep.h>
#include <asm/uaccess.h>
@@ -126,22 +126,13 @@
}
/* Called with kretprobe_lock held */
-void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
+void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
struct pt_regs *regs)
{
- struct kretprobe_instance *ri;
+ ri->ret_addr = (kprobe_opcode_t *)regs->link;
- if ((ri = get_free_rp_inst(rp)) != NULL) {
- ri->rp = rp;
- ri->task = current;
- ri->ret_addr = (kprobe_opcode_t *)regs->link;
-
- /* Replace the return addr with trampoline addr */
- regs->link = (unsigned long)kretprobe_trampoline;
- add_rp_inst(ri);
- } else {
- rp->nmissed++;
- }
+ /* Replace the return addr with trampoline addr */
+ regs->link = (unsigned long)kretprobe_trampoline;
}
static int __kprobes kprobe_handler(struct pt_regs *regs)
@@ -336,7 +327,7 @@
break;
}
- BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
+ kretprobe_assert(ri, orig_ret_address, trampoline_address);
regs->nip = orig_ret_address;
reset_current_kprobe();
@@ -410,7 +401,7 @@
return 1;
}
-static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
+int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
{
struct kprobe *cur = kprobe_running();
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
@@ -495,14 +486,6 @@
if (post_kprobe_handler(args->regs))
ret = NOTIFY_STOP;
break;
- case DIE_PAGE_FAULT:
- /* kprobe_running() needs smp_processor_id() */
- preempt_disable();
- if (kprobe_running() &&
- kprobe_fault_handler(args->regs, args->trapnr))
- ret = NOTIFY_STOP;
- preempt_enable();
- break;
default:
break;
}
@@ -559,3 +542,11 @@
{
return register_kprobe(&trampoline_p);
}
+
+int __kprobes arch_trampoline_kprobe(struct kprobe *p)
+{
+ if (p->addr == (kprobe_opcode_t *)&kretprobe_trampoline)
+ return 1;
+
+ return 0;
+}
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
index ae4836e..cea8045 100644
--- a/arch/powerpc/kernel/legacy_serial.c
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -244,9 +244,9 @@
* doesn't work for these settings, you'll have to add your own special
* cases here
*/
- if (device_is_compatible(pci_dev, "pci13a8,152") ||
- device_is_compatible(pci_dev, "pci13a8,154") ||
- device_is_compatible(pci_dev, "pci13a8,158")) {
+ if (of_device_is_compatible(pci_dev, "pci13a8,152") ||
+ of_device_is_compatible(pci_dev, "pci13a8,154") ||
+ of_device_is_compatible(pci_dev, "pci13a8,158")) {
addr += 0x200 * lindex;
base += 0x200 * lindex;
} else {
@@ -365,11 +365,11 @@
/* Check for known pciclass, and also check wether we have
* a device with child nodes for ports or not
*/
- if (device_is_compatible(np, "pciclass,0700") ||
- device_is_compatible(np, "pciclass,070002"))
+ if (of_device_is_compatible(np, "pciclass,0700") ||
+ of_device_is_compatible(np, "pciclass,070002"))
pci = np;
- else if (device_is_compatible(parent, "pciclass,0700") ||
- device_is_compatible(parent, "pciclass,070002"))
+ else if (of_device_is_compatible(parent, "pciclass,0700") ||
+ of_device_is_compatible(parent, "pciclass,070002"))
pci = parent;
else {
of_node_put(parent);
diff --git a/arch/powerpc/kernel/msi.c b/arch/powerpc/kernel/msi.c
new file mode 100644
index 0000000..c62d101
--- /dev/null
+++ b/arch/powerpc/kernel/msi.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2006-2007, Michael Ellerman, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/msi.h>
+
+#include <asm/machdep.h>
+
+int arch_msi_check_device(struct pci_dev* dev, int nvec, int type)
+{
+ if (!ppc_md.setup_msi_irqs || !ppc_md.teardown_msi_irqs) {
+ pr_debug("msi: Platform doesn't provide MSI callbacks.\n");
+ return -ENOSYS;
+ }
+
+ if (ppc_md.msi_check_device) {
+ pr_debug("msi: Using platform check routine.\n");
+ return ppc_md.msi_check_device(dev, nvec, type);
+ }
+
+ return 0;
+}
+
+int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+{
+ return ppc_md.setup_msi_irqs(dev, nvec, type);
+}
+
+void arch_teardown_msi_irqs(struct pci_dev *dev)
+{
+ return ppc_md.teardown_msi_irqs(dev);
+}
diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c
index 0c8ea76..a464d67 100644
--- a/arch/powerpc/kernel/of_device.c
+++ b/arch/powerpc/kernel/of_device.c
@@ -27,7 +27,7 @@
match &= node->type
&& !strcmp(matches->type, node->type);
if (matches->compatible[0])
- match &= device_is_compatible(node,
+ match &= of_device_is_compatible(node,
matches->compatible);
if (match)
return matches;
@@ -120,8 +120,8 @@
}
-static ssize_t of_device_get_modalias(struct of_device *ofdev,
- char *str, ssize_t len)
+ssize_t of_device_get_modalias(struct of_device *ofdev,
+ char *str, ssize_t len)
{
const char *compat;
int cplen, i;
@@ -239,3 +239,4 @@
EXPORT_SYMBOL(of_dev_put);
EXPORT_SYMBOL(of_release_dev);
EXPORT_SYMBOL(of_device_uevent);
+EXPORT_SYMBOL(of_device_get_modalias);
diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c
index 908ed79..84c34d9 100644
--- a/arch/powerpc/kernel/of_platform.c
+++ b/arch/powerpc/kernel/of_platform.c
@@ -29,7 +29,6 @@
#include <asm/ppc-pci.h>
#include <asm/atomic.h>
-
/*
* The list of OF IDs below is used for matching bus types in the
* system whose devices are to be exposed as of_platform_devices.
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index f022862..e66064b 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -1658,7 +1658,7 @@
int i;
if (page_is_ram(pfn))
- return prot;
+ return __pgprot(prot);
prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 7138092..6d05a1f 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -1006,8 +1006,9 @@
switch ((pci_space >> 24) & 0x3) {
case 1: /* I/O space */
- hose->io_base_phys = cpu_phys_addr;
- hose->pci_io_size = size;
+ hose->io_base_phys = cpu_phys_addr - pci_addr;
+ /* handle from 0 to top of I/O window */
+ hose->pci_io_size = pci_addr + size;
res = &hose->io_resource;
res->flags = IORESOURCE_IO;
@@ -1117,8 +1118,8 @@
} else {
/* Root Bus */
res = &hose->io_resource;
- *start_phys = hose->io_base_phys;
- *start_virt = (unsigned long) hose->io_base_virt;
+ *start_phys = hose->io_base_phys + res->start;
+ *start_virt = (unsigned long) hose->io_base_virt + res->start;
if (res->end > res->start)
*size = res->end - res->start + 1;
else {
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index ff252aa..c96fa9b 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -66,7 +66,6 @@
EXPORT_SYMBOL(ISA_DMA_THRESHOLD);
EXPORT_SYMBOL(DMA_MODE_READ);
EXPORT_SYMBOL(DMA_MODE_WRITE);
-EXPORT_SYMBOL(__div64_32);
EXPORT_SYMBOL(do_signal);
EXPORT_SYMBOL(transfer_to_handler);
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index e509aae..6e2f035 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -19,7 +19,6 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index e27d9d1..d6047c4 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -635,6 +635,12 @@
/* ibm,dynamic-reconfiguration-memory property supported */
#define OV5_DRCONF_MEMORY 0x20
#define OV5_LARGE_PAGES 0x10 /* large pages supported */
+/* PCIe/MSI support. Without MSI full PCIe is not supported */
+#ifdef CONFIG_PCI_MSI
+#define OV5_MSI 0x01 /* PCIe/MSI support */
+#else
+#define OV5_MSI 0x00
+#endif /* CONFIG_PCI_MSI */
/*
* The architecture vector has an array of PVR mask/value pairs,
@@ -679,7 +685,7 @@
/* option vector 5: PAPR/OF options */
3 - 2, /* length */
0, /* don't ignore, don't halt */
- OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY,
+ OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY | OV5_MSI,
};
/* Old method - ELF header with PT_NOTE sections */
@@ -967,7 +973,7 @@
* If problems seem to show up, it would be a good start to track
* them down.
*/
-static void reserve_mem(u64 base, u64 size)
+static void __init reserve_mem(u64 base, u64 size)
{
u64 top = base + size;
unsigned long cnt = RELOC(mem_reserve_cnt);
@@ -2153,7 +2159,7 @@
3,12,0, 3,13,0, 3,14,0, 3,15,0 };
struct subst_entry efika_subst_table[] = {
{ "/", "device_type", prop_cstr("efika") },
- { "/builtin", "compatible", prop_cstr("soc") },
+ { "/builtin", "device_type", prop_cstr("soc") },
{ "/builtin/ata", "compatible", prop_cstr("mpc5200b-ata\0mpc5200-ata"), },
{ "/builtin/bestcomm", "compatible", prop_cstr("mpc5200b-bestcomm\0mpc5200-bestcomm") },
{ "/builtin/bestcomm", "interrupts", prop_bcomm_irq, sizeof(prop_bcomm_irq) },
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index aa40a53..b5c96af 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -1042,3 +1042,28 @@
}
EXPORT_SYMBOL(of_get_mac_address);
+int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
+{
+ int irq = irq_of_parse_and_map(dev, index);
+
+ /* Only dereference the resource if both the
+ * resource and the irq are valid. */
+ if (r && irq != NO_IRQ) {
+ r->start = r->end = irq;
+ r->flags = IORESOURCE_IRQ;
+ }
+
+ return irq;
+}
+EXPORT_SYMBOL_GPL(of_irq_to_resource);
+
+void __iomem *of_iomap(struct device_node *np, int index)
+{
+ struct resource res;
+
+ if (of_address_to_resource(np, index, &res))
+ return NULL;
+
+ return ioremap(res.start, 1 + res.end - res.start);
+}
+EXPORT_SYMBOL(of_iomap);
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index cc44c7b..f4f391c 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -19,7 +19,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 6b405a3..dd1dca5 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -20,7 +20,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index f72e8e8..1ce0ae3 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -15,7 +15,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index d8e503b..22f1ef1 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -176,10 +176,10 @@
#define SMP_CALL_TIMEOUT 8
/*
- * This function sends a 'generic call function' IPI to all other CPUs
- * in the system.
+ * These functions send a 'generic call function' IPI to other online
+ * CPUS in the system.
*
- * [SUMMARY] Run a function on all other CPUs.
+ * [SUMMARY] Run a function on other CPUs.
* <func> The function to run. This must be fast and non-blocking.
* <info> An arbitrary pointer to pass to the function.
* <nonatomic> currently unused.
@@ -190,18 +190,26 @@
* You must not call this function with disabled interrupts or from a
* hardware interrupt handler or from a bottom half handler.
*/
-int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
- int wait)
-{
+int smp_call_function_map(void (*func) (void *info), void *info, int nonatomic,
+ int wait, cpumask_t map)
+{
struct call_data_struct data;
- int ret = -1, cpus;
+ int ret = -1, num_cpus;
+ int cpu;
u64 timeout;
/* Can deadlock when called with interrupts disabled */
WARN_ON(irqs_disabled());
+ /* remove 'self' from the map */
+ if (cpu_isset(smp_processor_id(), map))
+ cpu_clear(smp_processor_id(), map);
+
+ /* sanity check the map, remove any non-online processors. */
+ cpus_and(map, map, cpu_online_map);
+
if (unlikely(smp_ops == NULL))
- return -1;
+ return ret;
data.func = func;
data.info = info;
@@ -213,40 +221,42 @@
spin_lock(&call_lock);
/* Must grab online cpu count with preempt disabled, otherwise
* it can change. */
- cpus = num_online_cpus() - 1;
- if (!cpus) {
+ num_cpus = num_online_cpus() - 1;
+ if (!num_cpus || cpus_empty(map)) {
ret = 0;
goto out;
}
call_data = &data;
smp_wmb();
- /* Send a message to all other CPUs and wait for them to respond */
- smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_CALL_FUNCTION);
+ /* Send a message to all CPUs in the map */
+ for_each_cpu_mask(cpu, map)
+ smp_ops->message_pass(cpu, PPC_MSG_CALL_FUNCTION);
timeout = get_tb() + (u64) SMP_CALL_TIMEOUT * tb_ticks_per_sec;
- /* Wait for response */
- while (atomic_read(&data.started) != cpus) {
+ /* Wait for indication that they have received the message */
+ while (atomic_read(&data.started) != num_cpus) {
HMT_low();
if (get_tb() >= timeout) {
printk("smp_call_function on cpu %d: other cpus not "
- "responding (%d)\n", smp_processor_id(),
- atomic_read(&data.started));
+ "responding (%d)\n", smp_processor_id(),
+ atomic_read(&data.started));
debugger(NULL);
goto out;
}
}
+ /* optionally wait for the CPUs to complete */
if (wait) {
- while (atomic_read(&data.finished) != cpus) {
+ while (atomic_read(&data.finished) != num_cpus) {
HMT_low();
if (get_tb() >= timeout) {
printk("smp_call_function on cpu %d: other "
- "cpus not finishing (%d/%d)\n",
- smp_processor_id(),
- atomic_read(&data.finished),
- atomic_read(&data.started));
+ "cpus not finishing (%d/%d)\n",
+ smp_processor_id(),
+ atomic_read(&data.finished),
+ atomic_read(&data.started));
debugger(NULL);
goto out;
}
@@ -262,8 +272,29 @@
return ret;
}
+int smp_call_function(void (*func) (void *info), void *info, int nonatomic,
+ int wait)
+{
+ return smp_call_function_map(func,info,nonatomic,wait,cpu_online_map);
+}
EXPORT_SYMBOL(smp_call_function);
+int smp_call_function_single(int cpu, void (*func) (void *info), void *info, int nonatomic,
+ int wait)
+{
+ cpumask_t map=CPU_MASK_NONE;
+
+ if (!cpu_online(cpu))
+ return -EINVAL;
+
+ if (cpu == smp_processor_id())
+ return -EBUSY;
+
+ cpu_set(cpu, map);
+ return smp_call_function_map(func,info,nonatomic,wait,map);
+}
+EXPORT_SYMBOL(smp_call_function_single);
+
void smp_call_function_interrupt(void)
{
void (*func) (void *info);
diff --git a/arch/powerpc/kernel/swsusp.c b/arch/powerpc/kernel/swsusp.c
new file mode 100644
index 0000000..064a7ba
--- /dev/null
+++ b/arch/powerpc/kernel/swsusp.c
@@ -0,0 +1,43 @@
+/*
+ * Common powerpc suspend code for 32 and 64 bits
+ *
+ * Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/sched.h>
+#include <asm/suspend.h>
+#include <asm/system.h>
+#include <asm/current.h>
+#include <asm/mmu_context.h>
+
+void save_processor_state(void)
+{
+ /*
+ * flush out all the special registers so we don't need
+ * to save them in the snapshot
+ */
+ flush_fp_to_thread(current);
+ flush_altivec_to_thread(current);
+ flush_spe_to_thread(current);
+
+#ifdef CONFIG_PPC64
+ hard_irq_disable();
+#endif
+
+}
+
+void restore_processor_state(void)
+{
+#ifdef CONFIG_PPC32
+ set_context(current->active_mm->context.id, current->active_mm->pgd);
+#endif
+
+#ifdef CONFIG_PPC64
+ hard_irq_enable();
+#endif
+}
diff --git a/arch/powerpc/kernel/swsusp_64.c b/arch/powerpc/kernel/swsusp_64.c
new file mode 100644
index 0000000..6f3f069
--- /dev/null
+++ b/arch/powerpc/kernel/swsusp_64.c
@@ -0,0 +1,24 @@
+/*
+ * PowerPC 64-bit swsusp implementation
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * GPLv2
+ */
+
+#include <asm/system.h>
+#include <asm/iommu.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+
+void do_after_copyback(void)
+{
+ iommu_restore();
+ touch_softlockup_watchdog();
+ mb();
+}
+
+void _iommu_save(void)
+{
+ iommu_save();
+}
diff --git a/arch/powerpc/kernel/swsusp_asm64.S b/arch/powerpc/kernel/swsusp_asm64.S
new file mode 100644
index 0000000..e092c3c
--- /dev/null
+++ b/arch/powerpc/kernel/swsusp_asm64.S
@@ -0,0 +1,228 @@
+/*
+ * PowerPC 64-bit swsusp implementation
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * GPLv2
+ */
+
+#include <linux/threads.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/cputable.h>
+#include <asm/thread_info.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+
+/*
+ * Structure for storing CPU registers on the save area.
+ */
+#define SL_r1 0x00 /* stack pointer */
+#define SL_PC 0x08
+#define SL_MSR 0x10
+#define SL_SDR1 0x18
+#define SL_XER 0x20
+#define SL_TB 0x40
+#define SL_r2 0x48
+#define SL_CR 0x50
+#define SL_LR 0x58
+#define SL_r12 0x60
+#define SL_r13 0x68
+#define SL_r14 0x70
+#define SL_r15 0x78
+#define SL_r16 0x80
+#define SL_r17 0x88
+#define SL_r18 0x90
+#define SL_r19 0x98
+#define SL_r20 0xa0
+#define SL_r21 0xa8
+#define SL_r22 0xb0
+#define SL_r23 0xb8
+#define SL_r24 0xc0
+#define SL_r25 0xc8
+#define SL_r26 0xd0
+#define SL_r27 0xd8
+#define SL_r28 0xe0
+#define SL_r29 0xe8
+#define SL_r30 0xf0
+#define SL_r31 0xf8
+#define SL_SIZE SL_r31+8
+
+/* these macros rely on the save area being
+ * pointed to by r11 */
+#define SAVE_SPECIAL(special) \
+ mf##special r0 ;\
+ std r0, SL_##special(r11)
+#define RESTORE_SPECIAL(special) \
+ ld r0, SL_##special(r11) ;\
+ mt##special r0
+#define SAVE_REGISTER(reg) \
+ std reg, SL_##reg(r11)
+#define RESTORE_REGISTER(reg) \
+ ld reg, SL_##reg(r11)
+
+/* space for storing cpu state */
+ .section .data
+ .align 5
+swsusp_save_area:
+ .space SL_SIZE
+
+ .section ".toc","aw"
+swsusp_save_area_ptr:
+ .tc swsusp_save_area[TC],swsusp_save_area
+restore_pblist_ptr:
+ .tc restore_pblist[TC],restore_pblist
+
+ .section .text
+ .align 5
+_GLOBAL(swsusp_arch_suspend)
+ ld r11,swsusp_save_area_ptr@toc(r2)
+ SAVE_SPECIAL(LR)
+ SAVE_REGISTER(r1)
+ SAVE_SPECIAL(CR)
+ SAVE_SPECIAL(TB)
+ SAVE_REGISTER(r2)
+ SAVE_REGISTER(r12)
+ SAVE_REGISTER(r13)
+ SAVE_REGISTER(r14)
+ SAVE_REGISTER(r15)
+ SAVE_REGISTER(r16)
+ SAVE_REGISTER(r17)
+ SAVE_REGISTER(r18)
+ SAVE_REGISTER(r19)
+ SAVE_REGISTER(r20)
+ SAVE_REGISTER(r21)
+ SAVE_REGISTER(r22)
+ SAVE_REGISTER(r23)
+ SAVE_REGISTER(r24)
+ SAVE_REGISTER(r25)
+ SAVE_REGISTER(r26)
+ SAVE_REGISTER(r27)
+ SAVE_REGISTER(r28)
+ SAVE_REGISTER(r29)
+ SAVE_REGISTER(r30)
+ SAVE_REGISTER(r31)
+ SAVE_SPECIAL(MSR)
+ SAVE_SPECIAL(SDR1)
+ SAVE_SPECIAL(XER)
+
+ /* we push the stack up 128 bytes but don't store the
+ * stack pointer on the stack like a real stackframe */
+ addi r1,r1,-128
+
+ bl _iommu_save
+ bl swsusp_save
+
+ /* restore LR */
+ ld r11,swsusp_save_area_ptr@toc(r2)
+ RESTORE_SPECIAL(LR)
+ addi r1,r1,128
+
+ blr
+
+/* Resume code */
+_GLOBAL(swsusp_arch_resume)
+ /* Stop pending alitvec streams and memory accesses */
+BEGIN_FTR_SECTION
+ DSSALL
+END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+ sync
+
+ ld r12,restore_pblist_ptr@toc(r2)
+ ld r12,0(r12)
+
+ cmpdi r12,0
+ beq- nothing_to_copy
+ li r15,512
+copyloop:
+ ld r13,pbe_address(r12)
+ ld r14,pbe_orig_address(r12)
+
+ mtctr r15
+ li r10,0
+copy_page_loop:
+ ldx r0,r10,r13
+ stdx r0,r10,r14
+ addi r10,r10,8
+ bdnz copy_page_loop
+
+ ld r12,pbe_next(r12)
+ cmpdi r12,0
+ bne+ copyloop
+nothing_to_copy:
+
+ /* flush caches */
+ lis r3, 0x10
+ mtctr r3
+ li r3, 0
+ ori r3, r3, CONFIG_KERNEL_START>>48
+ li r0, 48
+ sld r3, r3, r0
+ li r0, 0
+1:
+ dcbf r0,r3
+ addi r3,r3,0x20
+ bdnz 1b
+
+ sync
+
+ tlbia
+
+ ld r11,swsusp_save_area_ptr@toc(r2)
+
+ RESTORE_SPECIAL(CR)
+
+ /* restore timebase */
+ /* load saved tb */
+ ld r1, SL_TB(r11)
+ /* get upper 32 bits of it */
+ srdi r2, r1, 32
+ /* clear tb lower to avoid wrap */
+ li r0, 0
+ mttbl r0
+ /* set tb upper */
+ mttbu r2
+ /* set tb lower */
+ mttbl r1
+
+ /* restore registers */
+ RESTORE_REGISTER(r1)
+ RESTORE_REGISTER(r2)
+ RESTORE_REGISTER(r12)
+ RESTORE_REGISTER(r13)
+ RESTORE_REGISTER(r14)
+ RESTORE_REGISTER(r15)
+ RESTORE_REGISTER(r16)
+ RESTORE_REGISTER(r17)
+ RESTORE_REGISTER(r18)
+ RESTORE_REGISTER(r19)
+ RESTORE_REGISTER(r20)
+ RESTORE_REGISTER(r21)
+ RESTORE_REGISTER(r22)
+ RESTORE_REGISTER(r23)
+ RESTORE_REGISTER(r24)
+ RESTORE_REGISTER(r25)
+ RESTORE_REGISTER(r26)
+ RESTORE_REGISTER(r27)
+ RESTORE_REGISTER(r28)
+ RESTORE_REGISTER(r29)
+ RESTORE_REGISTER(r30)
+ RESTORE_REGISTER(r31)
+ /* can't use RESTORE_SPECIAL(MSR) */
+ ld r0, SL_MSR(r11)
+ mtmsrd r0, 0
+ RESTORE_SPECIAL(SDR1)
+ RESTORE_SPECIAL(XER)
+
+ sync
+
+ addi r1,r1,-128
+ bl slb_flush_and_rebolt
+ bl do_after_copyback
+ addi r1,r1,128
+
+ ld r11,swsusp_save_area_ptr@toc(r2)
+ RESTORE_SPECIAL(LR)
+
+ li r3, 0
+ blr
diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c
index d358866..fc6647d 100644
--- a/arch/powerpc/kernel/syscalls.c
+++ b/arch/powerpc/kernel/syscalls.c
@@ -24,7 +24,6 @@
#include <linux/syscalls.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index 933e214..cae39d9 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -499,4 +499,4 @@
return 0;
}
-__initcall(topology_init);
+subsys_initcall(topology_init);
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index f786222..bf6445a 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -33,8 +33,8 @@
#include <linux/kexec.h>
#include <linux/backlight.h>
#include <linux/bug.h>
+#include <linux/kdebug.h>
-#include <asm/kdebug.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
#include <asm/system.h>
@@ -72,20 +72,6 @@
EXPORT_SYMBOL(__debugger_fault_handler);
#endif
-ATOMIC_NOTIFIER_HEAD(powerpc_die_chain);
-
-int register_die_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_register(&powerpc_die_chain, nb);
-}
-EXPORT_SYMBOL(register_die_notifier);
-
-int unregister_die_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_unregister(&powerpc_die_chain, nb);
-}
-EXPORT_SYMBOL(unregister_die_notifier);
-
/*
* Trap & Exception support
*/
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c
index 7e09718..87703df 100644
--- a/arch/powerpc/kernel/udbg.c
+++ b/arch/powerpc/kernel/udbg.c
@@ -51,6 +51,9 @@
udbg_init_pas_realmode();
#elif defined(CONFIG_BOOTX_TEXT)
udbg_init_btext();
+#elif defined(CONFIG_PPC_EARLY_DEBUG_44x)
+ /* PPC44x debug */
+ udbg_init_44x_as1();
#endif
}
@@ -142,29 +145,22 @@
static struct console udbg_console = {
.name = "udbg",
.write = udbg_console_write,
- .flags = CON_PRINTBUFFER | CON_ENABLED,
+ .flags = CON_PRINTBUFFER | CON_ENABLED | CON_BOOT,
.index = -1,
};
static int early_console_initialized;
-void __init disable_early_printk(void)
-{
- if (!early_console_initialized)
- return;
- if (strstr(boot_command_line, "udbg-immortal")) {
- printk(KERN_INFO "early console immortal !\n");
- return;
- }
- unregister_console(&udbg_console);
- early_console_initialized = 0;
-}
-
/* called by setup_system */
void register_early_udbg_console(void)
{
if (early_console_initialized)
return;
+
+ if (strstr(boot_command_line, "udbg-immortal")) {
+ printk(KERN_INFO "early console immortal !\n");
+ udbg_console.flags &= ~CON_BOOT;
+ }
early_console_initialized = 1;
register_console(&udbg_console);
}
diff --git a/arch/powerpc/kernel/udbg_16550.c b/arch/powerpc/kernel/udbg_16550.c
index a963f65..7afab5b 100644
--- a/arch/powerpc/kernel/udbg_16550.c
+++ b/arch/powerpc/kernel/udbg_16550.c
@@ -191,3 +191,26 @@
udbg_getc_poll = NULL;
}
#endif /* CONFIG_PPC_MAPLE */
+
+#ifdef CONFIG_PPC_EARLY_DEBUG_44x
+#include <platforms/44x/44x.h>
+
+static void udbg_44x_as1_putc(char c)
+{
+ if (udbg_comport) {
+ while ((as1_readb(&udbg_comport->lsr) & LSR_THRE) == 0)
+ /* wait for idle */;
+ as1_writeb(c, &udbg_comport->thr); eieio();
+ if (c == '\n')
+ udbg_44x_as1_putc('\r');
+ }
+}
+
+void __init udbg_init_44x_as1(void)
+{
+ udbg_comport =
+ (volatile struct NS16550 __iomem *)PPC44x_EARLY_DEBUG_VIRTADDR;
+
+ udbg_putc = udbg_44x_as1_putc;
+}
+#endif /* CONFIG_PPC_EARLY_DEBUG_44x */
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index e46c31b..4245579 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -14,7 +14,6 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/slab.h>
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index b2c1b67a..62c1bc1 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -117,7 +117,7 @@
{
while (ids->type[0] != '\0') {
if ((strncmp(dev->type, ids->type, strlen(ids->type)) == 0) &&
- device_is_compatible(dev->dev.archdata.of_node,
+ of_device_is_compatible(dev->dev.archdata.of_node,
ids->compat))
return ids;
ids++;
diff --git a/arch/powerpc/lib/dma-noncoherent.c b/arch/powerpc/lib/dma-noncoherent.c
index 48f3d13..6656d47 100644
--- a/arch/powerpc/lib/dma-noncoherent.c
+++ b/arch/powerpc/lib/dma-noncoherent.c
@@ -306,13 +306,15 @@
static int __init dma_alloc_init(void)
{
pgd_t *pgd;
+ pud_t *pud;
pmd_t *pmd;
pte_t *pte;
int ret = 0;
do {
pgd = pgd_offset(&init_mm, CONSISTENT_BASE);
- pmd = pmd_alloc(&init_mm, pgd, CONSISTENT_BASE);
+ pud = pud_alloc(&init_mm, pgd, CONSISTENT_BASE);
+ pmd = pmd_alloc(&init_mm, pud, CONSISTENT_BASE);
if (!pmd) {
printk(KERN_ERR "%s: no pmd tables\n", __func__);
ret = -ENOMEM;
diff --git a/arch/powerpc/mm/44x_mmu.c b/arch/powerpc/mm/44x_mmu.c
index 0a0a0487b..ca4dcb0 100644
--- a/arch/powerpc/mm/44x_mmu.c
+++ b/arch/powerpc/mm/44x_mmu.c
@@ -24,73 +24,38 @@
*
*/
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/ptrace.h>
-#include <linux/mman.h>
-#include <linux/mm.h>
-#include <linux/swap.h>
-#include <linux/stddef.h>
-#include <linux/vmalloc.h>
#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/highmem.h>
-
-#include <asm/pgalloc.h>
-#include <asm/prom.h>
-#include <asm/io.h>
-#include <asm/mmu_context.h>
-#include <asm/pgtable.h>
#include <asm/mmu.h>
-#include <asm/uaccess.h>
-#include <asm/smp.h>
-#include <asm/bootx.h>
-#include <asm/machdep.h>
-#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/page.h>
#include "mmu_decl.h"
-extern char etext[], _stext[];
-
/* Used by the 44x TLB replacement exception handler.
* Just needed it declared someplace.
*/
-unsigned int tlb_44x_index = 0;
-unsigned int tlb_44x_hwater = 62;
+unsigned int tlb_44x_index; /* = 0 */
+unsigned int tlb_44x_hwater = PPC44x_TLB_SIZE - 1 - PPC44x_EARLY_TLBS;
/*
* "Pins" a 256MB TLB entry in AS0 for kernel lowmem
*/
-static void __init
-ppc44x_pin_tlb(int slot, unsigned int virt, unsigned int phys)
+static void __init ppc44x_pin_tlb(unsigned int virt, unsigned int phys)
{
- unsigned long attrib = 0;
-
- __asm__ __volatile__("\
- clrrwi %2,%2,10\n\
- ori %2,%2,%4\n\
- clrrwi %1,%1,10\n\
- li %0,0\n\
- ori %0,%0,%5\n\
- tlbwe %2,%3,%6\n\
- tlbwe %1,%3,%7\n\
- tlbwe %0,%3,%8"
+ __asm__ __volatile__(
+ "tlbwe %2,%3,%4\n"
+ "tlbwe %1,%3,%5\n"
+ "tlbwe %0,%3,%6\n"
:
- : "r" (attrib), "r" (phys), "r" (virt), "r" (slot),
- "i" (PPC44x_TLB_VALID | PPC44x_TLB_256M),
- "i" (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G),
+ : "r" (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G),
+ "r" (phys),
+ "r" (virt | PPC44x_TLB_VALID | PPC44x_TLB_256M),
+ "r" (tlb_44x_hwater--), /* slot for this TLB entry */
"i" (PPC44x_TLB_PAGEID),
"i" (PPC44x_TLB_XLAT),
"i" (PPC44x_TLB_ATTRIB));
}
-/*
- * MMU_init_hw does the chip-specific initialization of the MMU hardware.
- */
void __init MMU_init_hw(void)
{
flush_instruction_cache();
@@ -98,22 +63,13 @@
unsigned long __init mmu_mapin_ram(void)
{
- unsigned int pinned_tlbs = 1;
- int i;
+ unsigned long addr;
- /* Determine number of entries necessary to cover lowmem */
- pinned_tlbs = (unsigned int)
- (_ALIGN(total_lowmem, PPC_PIN_SIZE) >> PPC44x_PIN_SHIFT);
-
- /* Write upper watermark to save location */
- tlb_44x_hwater = PPC44x_LOW_SLOT - pinned_tlbs;
-
- /* If necessary, set additional pinned TLBs */
- if (pinned_tlbs > 1)
- for (i = (PPC44x_LOW_SLOT-(pinned_tlbs-1)); i < PPC44x_LOW_SLOT; i++) {
- unsigned int phys_addr = (PPC44x_LOW_SLOT-i) * PPC_PIN_SIZE;
- ppc44x_pin_tlb(i, phys_addr+PAGE_OFFSET, phys_addr);
- }
+ /* Pin in enough TLBs to cover any lowmem not covered by the
+ * initial 256M mapping established in head_44x.S */
+ for (addr = PPC_PIN_SIZE; addr < total_lowmem;
+ addr += PPC_PIN_SIZE)
+ ppc44x_pin_tlb(addr + PAGE_OFFSET, addr);
return total_lowmem;
}
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index 03aeb3a..bfe9013 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -28,6 +28,7 @@
#include <linux/highmem.h>
#include <linux/module.h>
#include <linux/kprobes.h>
+#include <linux/kdebug.h>
#include <asm/page.h>
#include <asm/pgtable.h>
@@ -36,40 +37,28 @@
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/tlbflush.h>
-#include <asm/kdebug.h>
#include <asm/siginfo.h>
+
#ifdef CONFIG_KPROBES
-ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain);
-
-/* Hook to register for page fault notifications */
-int register_page_fault_notifier(struct notifier_block *nb)
+static inline int notify_page_fault(struct pt_regs *regs)
{
- return atomic_notifier_chain_register(¬ify_page_fault_chain, nb);
-}
+ int ret = 0;
-int unregister_page_fault_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb);
-}
+ /* kprobe_running() needs smp_processor_id() */
+ if (!user_mode(regs)) {
+ preempt_disable();
+ if (kprobe_running() && kprobe_fault_handler(regs, 11))
+ ret = 1;
+ preempt_enable();
+ }
-static inline int notify_page_fault(enum die_val val, const char *str,
- struct pt_regs *regs, long err, int trap, int sig)
-{
- struct die_args args = {
- .regs = regs,
- .str = str,
- .err = err,
- .trapnr = trap,
- .signr = sig
- };
- return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args);
+ return ret;
}
#else
-static inline int notify_page_fault(enum die_val val, const char *str,
- struct pt_regs *regs, long err, int trap, int sig)
+static inline int notify_page_fault(struct pt_regs *regs)
{
- return NOTIFY_DONE;
+ return 0;
}
#endif
@@ -175,8 +164,7 @@
is_write = error_code & ESR_DST;
#endif /* CONFIG_4xx || CONFIG_BOOKE */
- if (notify_page_fault(DIE_PAGE_FAULT, "page_fault", regs, error_code,
- 11, SIGSEGV) == NOTIFY_STOP)
+ if (notify_page_fault(regs))
return 0;
if (trap == 0x300) {
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c
index 79aedaf..7b7fe2d 100644
--- a/arch/powerpc/mm/hash_native_64.c
+++ b/arch/powerpc/mm/hash_native_64.c
@@ -26,6 +26,7 @@
#include <asm/tlb.h>
#include <asm/cputable.h>
#include <asm/udbg.h>
+#include <asm/kexec.h>
#ifdef DEBUG_LOW
#define DBG_LOW(fmt...) udbg_printf(fmt)
@@ -340,31 +341,70 @@
local_irq_restore(flags);
}
-/*
- * XXX This need fixing based on page size. It's only used by
- * native_hpte_clear() for now which needs fixing too so they
- * make a good pair...
- */
-static unsigned long slot2va(unsigned long hpte_v, unsigned long slot)
+#define LP_SHIFT 12
+#define LP_BITS 8
+#define LP_MASK(i) ((0xFF >> (i)) << LP_SHIFT)
+
+static void hpte_decode(hpte_t *hpte, unsigned long slot,
+ int *psize, unsigned long *va)
{
- unsigned long avpn = HPTE_V_AVPN_VAL(hpte_v);
- unsigned long va;
+ unsigned long hpte_r = hpte->r;
+ unsigned long hpte_v = hpte->v;
+ unsigned long avpn;
+ int i, size, shift, penc, avpnm_bits;
- va = avpn << 23;
+ if (!(hpte_v & HPTE_V_LARGE))
+ size = MMU_PAGE_4K;
+ else {
+ for (i = 0; i < LP_BITS; i++) {
+ if ((hpte_r & LP_MASK(i+1)) == LP_MASK(i+1))
+ break;
+ }
+ penc = LP_MASK(i+1) >> LP_SHIFT;
+ for (size = 0; size < MMU_PAGE_COUNT; size++) {
- if (! (hpte_v & HPTE_V_LARGE)) {
- unsigned long vpi, pteg;
+ /* 4K pages are not represented by LP */
+ if (size == MMU_PAGE_4K)
+ continue;
- pteg = slot / HPTES_PER_GROUP;
- if (hpte_v & HPTE_V_SECONDARY)
- pteg = ~pteg;
+ /* valid entries have a shift value */
+ if (!mmu_psize_defs[size].shift)
+ continue;
- vpi = ((va >> 28) ^ pteg) & htab_hash_mask;
-
- va |= vpi << PAGE_SHIFT;
+ if (penc == mmu_psize_defs[size].penc)
+ break;
+ }
}
- return va;
+ /*
+ * FIXME, the code below works for 16M, 64K, and 4K pages as these
+ * fall under the p<=23 rules for calculating the virtual address.
+ * In the case of 16M pages, an extra bit is stolen from the AVPN
+ * field to achieve the requisite 24 bits.
+ *
+ * Does not work for 16G pages or 1 TB segments.
+ */
+ shift = mmu_psize_defs[size].shift;
+ if (mmu_psize_defs[size].avpnm)
+ avpnm_bits = __ilog2_u64(mmu_psize_defs[size].avpnm) + 1;
+ else
+ avpnm_bits = 0;
+ if (shift - avpnm_bits <= 23) {
+ avpn = HPTE_V_AVPN_VAL(hpte_v) << 23;
+
+ if (shift < 23) {
+ unsigned long vpi, pteg;
+
+ pteg = slot / HPTES_PER_GROUP;
+ if (hpte_v & HPTE_V_SECONDARY)
+ pteg = ~pteg;
+ vpi = ((avpn >> 28) ^ pteg) & htab_hash_mask;
+ avpn |= (vpi << mmu_psize_defs[size].shift);
+ }
+ }
+
+ *va = avpn;
+ *psize = size;
}
/*
@@ -374,15 +414,14 @@
*
* TODO: add batching support when enabled. remember, no dynamic memory here,
* athough there is the control page available...
- *
- * XXX FIXME: 4k only for now !
*/
static void native_hpte_clear(void)
{
unsigned long slot, slots, flags;
hpte_t *hptep = htab_address;
- unsigned long hpte_v;
+ unsigned long hpte_v, va;
unsigned long pteg_count;
+ int psize;
pteg_count = htab_hash_mask + 1;
@@ -408,8 +447,9 @@
* already hold the native_tlbie_lock.
*/
if (hpte_v & HPTE_V_VALID) {
+ hpte_decode(hptep, slot, &psize, &va);
hptep->v = 0;
- __tlbie(slot2va(hpte_v, slot), MMU_PAGE_4K);
+ __tlbie(va, psize);
}
}
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 4961846..9b226fa 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -103,7 +103,7 @@
#ifdef CONFIG_DEBUG_PAGEALLOC
static u8 *linear_map_hash_slots;
static unsigned long linear_map_hash_count;
-static spinlock_t linear_map_hash_lock;
+static DEFINE_SPINLOCK(linear_map_hash_lock);
#endif /* CONFIG_DEBUG_PAGEALLOC */
/* There are definitions of page sizes arrays to be used when none
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 1f07f70..fb95926 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -12,7 +12,6 @@
#include <linux/mm.h>
#include <linux/hugetlb.h>
#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/sysctl.h>
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index 4416d51..fe1fe85 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -183,11 +183,8 @@
"for size: %08x...\n", name, i, size);
pgtable_cache[i] = kmem_cache_create(name,
size, size,
- 0,
+ SLAB_PANIC,
zero_ctor,
NULL);
- if (! pgtable_cache[i])
- panic("pgtable_cache_init(): could not create %s!\n",
- name);
}
}
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index c4bcd75..1a6e08f 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -80,7 +80,6 @@
return 0;
#endif
}
-EXPORT_SYMBOL(page_is_ram);
pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
unsigned long size, pgprot_t vma_prot)
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index 9c4538b..2558c34 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -40,7 +40,8 @@
extern unsigned long ioremap_base;
extern unsigned int rtas_data, rtas_size;
-extern PTE *Hash, *Hash_end;
+struct _PTE;
+extern struct _PTE *Hash, *Hash_end;
extern unsigned long Hash_size, Hash_mask;
extern unsigned int num_tlbcam_entries;
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index bca5603..d8232b7 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -261,7 +261,7 @@
int err = -ENOMEM;
/* Use upper 10 bits of VA to index the first level map */
- pd = pmd_offset(pgd_offset_k(va), va);
+ pd = pmd_offset(pud_offset(pgd_offset_k(va), va), va);
/* Use middle 10 bits of VA to index the second-level map */
pg = pte_alloc_kernel(pd, va);
if (pg != 0) {
@@ -354,23 +354,27 @@
get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, pmd_t **pmdp)
{
pgd_t *pgd;
+ pud_t *pud;
pmd_t *pmd;
pte_t *pte;
int retval = 0;
pgd = pgd_offset(mm, addr & PAGE_MASK);
if (pgd) {
- pmd = pmd_offset(pgd, addr & PAGE_MASK);
- if (pmd_present(*pmd)) {
- pte = pte_offset_map(pmd, addr & PAGE_MASK);
- if (pte) {
- retval = 1;
- *ptep = pte;
- if (pmdp)
- *pmdp = pmd;
- /* XXX caller needs to do pte_unmap, yuck */
- }
- }
+ pud = pud_offset(pgd, addr & PAGE_MASK);
+ if (pud && pud_present(*pud)) {
+ pmd = pmd_offset(pud, addr & PAGE_MASK);
+ if (pmd_present(*pmd)) {
+ pte = pte_offset_map(pmd, addr & PAGE_MASK);
+ if (pte) {
+ retval = 1;
+ *ptep = pte;
+ if (pmdp)
+ *pmdp = pmd;
+ /* XXX caller needs to do pte_unmap, yuck */
+ }
+ }
+ }
}
return(retval);
}
diff --git a/arch/powerpc/mm/stab.c b/arch/powerpc/mm/stab.c
index eeeacab..132c6bc 100644
--- a/arch/powerpc/mm/stab.c
+++ b/arch/powerpc/mm/stab.c
@@ -227,7 +227,7 @@
* the first (bolted) segment, so that do_stab_bolted won't get a
* recursive segment miss on the segment table itself.
*/
-void stabs_alloc(void)
+void __init stabs_alloc(void)
{
int cpu;
diff --git a/arch/powerpc/platforms/44x/44x.h b/arch/powerpc/platforms/44x/44x.h
new file mode 100644
index 0000000..42eabf8
--- /dev/null
+++ b/arch/powerpc/platforms/44x/44x.h
@@ -0,0 +1,8 @@
+#ifndef __POWERPC_PLATFORMS_44X_44X_H
+#define __POWERPC_PLATFORMS_44X_44X_H
+
+extern u8 as1_readb(volatile u8 __iomem *addr);
+extern void as1_writeb(u8 data, volatile u8 __iomem *addr);
+extern void ppc44x_reset_system(char *cmd);
+
+#endif /* __POWERPC_PLATFORMS_44X_44X_H */
diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig
new file mode 100644
index 0000000..8e66949
--- /dev/null
+++ b/arch/powerpc/platforms/44x/Kconfig
@@ -0,0 +1,56 @@
+#config BAMBOO
+# bool "Bamboo"
+# depends on 44x
+# default n
+# select 440EP
+# help
+# This option enables support for the IBM PPC440EP evaluation board.
+
+config EBONY
+ bool "Ebony"
+ depends on 44x
+ default y
+ select 440GP
+ help
+ This option enables support for the IBM PPC440GP evaluation board.
+
+#config LUAN
+# bool "Luan"
+# depends on 44x
+# default n
+# select 440SP
+# help
+# This option enables support for the IBM PPC440SP evaluation board.
+
+#config OCOTEA
+# bool "Ocotea"
+# depends on 44x
+# default n
+# select 440GX
+# help
+# This option enables support for the IBM PPC440GX evaluation board.
+
+# 44x specific CPU modules, selected based on the board above.
+config 440EP
+ bool
+ select PPC_FPU
+ select IBM440EP_ERR42
+
+config 440GP
+ bool
+ select IBM_NEW_EMAC_ZMII
+
+config 440GX
+ bool
+
+config 440SP
+ bool
+
+config 440A
+ bool
+ depends on 440GX
+ default y
+
+# 44x errata/workaround config symbols, selected by the CPU models above
+config IBM440EP_ERR42
+ bool
diff --git a/arch/powerpc/platforms/44x/Makefile b/arch/powerpc/platforms/44x/Makefile
new file mode 100644
index 0000000..41d0a18
--- /dev/null
+++ b/arch/powerpc/platforms/44x/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_44x) := misc_44x.o
+obj-$(CONFIG_EBONY) += ebony.o
diff --git a/arch/powerpc/platforms/44x/ebony.c b/arch/powerpc/platforms/44x/ebony.c
new file mode 100644
index 0000000..ad526ea
--- /dev/null
+++ b/arch/powerpc/platforms/44x/ebony.c
@@ -0,0 +1,73 @@
+/*
+ * Ebony board specific routines
+ *
+ * Matt Porter <mporter@kernel.crashing.org>
+ * Copyright 2002-2005 MontaVista Software Inc.
+ *
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ * Copyright (c) 2003-2005 Zultys Technologies
+ *
+ * Rewritten and ported to the merged powerpc tree:
+ * Copyright 2007 David Gibson <dwg@au1.ibm.com>, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/init.h>
+#include <asm/machdep.h>
+#include <asm/prom.h>
+#include <asm/udbg.h>
+#include <asm/time.h>
+#include <asm/uic.h>
+#include <asm/of_platform.h>
+
+#include "44x.h"
+
+static struct of_device_id ebony_of_bus[] = {
+ { .type = "ibm,plb", },
+ { .type = "ibm,opb", },
+ { .type = "ibm,ebc", },
+ {},
+};
+
+static int __init ebony_device_probe(void)
+{
+ if (!machine_is(ebony))
+ return 0;
+
+ of_platform_bus_probe(NULL, ebony_of_bus, NULL);
+
+ return 0;
+}
+device_initcall(ebony_device_probe);
+
+/*
+ * Called very early, MMU is off, device-tree isn't unflattened
+ */
+static int __init ebony_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ if (!of_flat_dt_is_compatible(root, "ibm,ebony"))
+ return 0;
+
+ return 1;
+}
+
+static void __init ebony_setup_arch(void)
+{
+}
+
+define_machine(ebony) {
+ .name = "Ebony",
+ .probe = ebony_probe,
+ .setup_arch = ebony_setup_arch,
+ .progress = udbg_progress,
+ .init_IRQ = uic_init_tree,
+ .get_irq = uic_get_irq,
+ .restart = ppc44x_reset_system,
+ .calibrate_decr = generic_calibrate_decr,
+};
diff --git a/arch/powerpc/platforms/44x/misc_44x.S b/arch/powerpc/platforms/44x/misc_44x.S
new file mode 100644
index 0000000..3bce71d
--- /dev/null
+++ b/arch/powerpc/platforms/44x/misc_44x.S
@@ -0,0 +1,57 @@
+/*
+ * This file contains miscellaneous low-level functions for PPC 44x.
+ * Copyright 2007 David Gibson <dwg@au1.ibm.com>, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <asm/reg.h>
+#include <asm/ppc_asm.h>
+
+ .text
+
+/*
+ * Do an IO access in AS1
+ */
+_GLOBAL(as1_readb)
+ mfmsr r7
+ ori r0,r7,MSR_DS
+ sync
+ mtmsr r0
+ sync
+ isync
+ lbz r3,0(r3)
+ sync
+ mtmsr r7
+ sync
+ isync
+ blr
+
+_GLOBAL(as1_writeb)
+ mfmsr r7
+ ori r0,r7,MSR_DS
+ sync
+ mtmsr r0
+ sync
+ isync
+ stb r3,0(r4)
+ sync
+ mtmsr r7
+ sync
+ isync
+ blr
+
+/*
+ * void ppc44x_reset_system(char *cmd)
+ *
+ * At present, this routine just applies a system reset.
+ */
+_GLOBAL(ppc44x_reset_system)
+ mfspr r13,SPRN_DBCR0
+ oris r13,r13,DBCR0_RST_SYSTEM@h
+ mtspr SPRN_DBCR0,r13
+ b . /* Just in case the reset doesn't work */
diff --git a/arch/powerpc/platforms/52xx/Kconfig b/arch/powerpc/platforms/52xx/Kconfig
index bc4aa4a..3ffaa06 100644
--- a/arch/powerpc/platforms/52xx/Kconfig
+++ b/arch/powerpc/platforms/52xx/Kconfig
@@ -1,5 +1,6 @@
config PPC_MPC52xx
bool
+ select FSL_SOC
default n
config PPC_MPC5200
diff --git a/arch/powerpc/platforms/52xx/Makefile b/arch/powerpc/platforms/52xx/Makefile
index 07cdbca..b91e39c 100644
--- a/arch/powerpc/platforms/52xx/Makefile
+++ b/arch/powerpc/platforms/52xx/Makefile
@@ -8,3 +8,5 @@
obj-$(CONFIG_PPC_EFIKA) += efika.o
obj-$(CONFIG_PPC_LITE5200) += lite5200.o
+
+obj-$(CONFIG_PM) += mpc52xx_sleep.o mpc52xx_pm.o
diff --git a/arch/powerpc/platforms/52xx/efika.c b/arch/powerpc/platforms/52xx/efika.c
index a6bba97..f591a9f 100644
--- a/arch/powerpc/platforms/52xx/efika.c
+++ b/arch/powerpc/platforms/52xx/efika.c
@@ -184,6 +184,16 @@
of_node_put(root);
}
+#ifdef CONFIG_PM
+static void efika_suspend_prepare(void __iomem *mbar)
+{
+ u8 pin = 4; /* GPIO_WKUP_4 (GPIO_PSC6_0 - IRDA_RX) */
+ u8 level = 1; /* wakeup on high level */
+ /* IOW. to wake it up, short pins 1 and 3 on IRDA connector */
+ mpc52xx_set_wakeup_gpio(pin, level);
+}
+#endif
+
static void __init efika_setup_arch(void)
{
rtas_initialize();
@@ -199,6 +209,11 @@
efika_pcisetup();
+#ifdef CONFIG_PM
+ mpc52xx_suspend.board_suspend_prepare = efika_suspend_prepare;
+ mpc52xx_pm_init();
+#endif
+
if (ppc_md.progress)
ppc_md.progress("Linux/PPC " UTS_RELEASE " running on Efika ;-)\n", 0x0);
}
diff --git a/arch/powerpc/platforms/52xx/lite5200.c b/arch/powerpc/platforms/52xx/lite5200.c
index 8e2646a..1cfc00d 100644
--- a/arch/powerpc/platforms/52xx/lite5200.c
+++ b/arch/powerpc/platforms/52xx/lite5200.c
@@ -85,6 +85,28 @@
iounmap(gpio);
}
+#ifdef CONFIG_PM
+static u32 descr_a;
+static void lite5200_suspend_prepare(void __iomem *mbar)
+{
+ u8 pin = 1; /* GPIO_WKUP_1 (GPIO_PSC2_4) */
+ u8 level = 0; /* wakeup on low level */
+ mpc52xx_set_wakeup_gpio(pin, level);
+
+ /*
+ * power down usb port
+ * this needs to be called before of-ohci suspend code
+ */
+ descr_a = in_be32(mbar + 0x1048);
+ out_be32(mbar + 0x1048, (descr_a & ~0x200) | 0x100);
+}
+
+static void lite5200_resume_finish(void __iomem *mbar)
+{
+ out_be32(mbar + 0x1048, descr_a);
+}
+#endif
+
static void __init lite5200_setup_arch(void)
{
struct device_node *np;
@@ -107,6 +129,12 @@
mpc52xx_setup_cpu(); /* Generic */
lite5200_setup_cpu(); /* Platorm specific */
+#ifdef CONFIG_PM
+ mpc52xx_suspend.board_suspend_prepare = lite5200_suspend_prepare;
+ mpc52xx_suspend.board_resume_finish = lite5200_resume_finish;
+ mpc52xx_pm_init();
+#endif
+
#ifdef CONFIG_PCI
np = of_find_node_by_type(NULL, "pci");
if (np) {
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pm.c b/arch/powerpc/platforms/52xx/mpc52xx_pm.c
new file mode 100644
index 0000000..fd40044
--- /dev/null
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pm.c
@@ -0,0 +1,191 @@
+#include <linux/init.h>
+#include <linux/pm.h>
+#include <linux/io.h>
+#include <asm/time.h>
+#include <asm/cacheflush.h>
+#include <asm/mpc52xx.h>
+
+#include "mpc52xx_pic.h"
+
+
+/* these are defined in mpc52xx_sleep.S, and only used here */
+extern void mpc52xx_deep_sleep(void *sram, void *sdram_regs,
+ struct mpc52xx_cdm *, struct mpc52xx_intr *);
+extern void mpc52xx_ds_sram(void);
+extern const long mpc52xx_ds_sram_size;
+extern void mpc52xx_ds_cached(void);
+extern const long mpc52xx_ds_cached_size;
+
+static void __iomem *mbar;
+static void __iomem *sdram;
+static struct mpc52xx_cdm __iomem *cdm;
+static struct mpc52xx_intr __iomem *intr;
+static struct mpc52xx_gpio_wkup __iomem *gpiow;
+static void *sram;
+static int sram_size;
+
+struct mpc52xx_suspend mpc52xx_suspend;
+
+static int mpc52xx_pm_valid(suspend_state_t state)
+{
+ switch (state) {
+ case PM_SUSPEND_STANDBY:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+int mpc52xx_set_wakeup_gpio(u8 pin, u8 level)
+{
+ u16 tmp;
+
+ /* enable gpio */
+ out_8(&gpiow->wkup_gpioe, in_8(&gpiow->wkup_gpioe) | (1 << pin));
+ /* set as input */
+ out_8(&gpiow->wkup_ddr, in_8(&gpiow->wkup_ddr) & ~(1 << pin));
+ /* enable deep sleep interrupt */
+ out_8(&gpiow->wkup_inten, in_8(&gpiow->wkup_inten) | (1 << pin));
+ /* low/high level creates wakeup interrupt */
+ tmp = in_be16(&gpiow->wkup_itype);
+ tmp &= ~(0x3 << (pin * 2));
+ tmp |= (!level + 1) << (pin * 2);
+ out_be16(&gpiow->wkup_itype, tmp);
+ /* master enable */
+ out_8(&gpiow->wkup_maste, 1);
+
+ return 0;
+}
+
+int mpc52xx_pm_prepare(suspend_state_t state)
+{
+ if (state != PM_SUSPEND_STANDBY)
+ return -EINVAL;
+
+ /* map the whole register space */
+ mbar = mpc52xx_find_and_map("mpc5200");
+ if (!mbar) {
+ printk(KERN_ERR "%s:%i Error mapping registers\n", __func__, __LINE__);
+ return -ENOSYS;
+ }
+ /* these offsets are from mpc5200 users manual */
+ sdram = mbar + 0x100;
+ cdm = mbar + 0x200;
+ intr = mbar + 0x500;
+ gpiow = mbar + 0xc00;
+ sram = mbar + 0x8000; /* Those will be handled by the */
+ sram_size = 0x4000; /* bestcomm driver soon */
+
+ /* call board suspend code, if applicable */
+ if (mpc52xx_suspend.board_suspend_prepare)
+ mpc52xx_suspend.board_suspend_prepare(mbar);
+ else {
+ printk(KERN_ALERT "%s: %i don't know how to wake up the board\n",
+ __func__, __LINE__);
+ goto out_unmap;
+ }
+
+ return 0;
+
+ out_unmap:
+ iounmap(mbar);
+ return -ENOSYS;
+}
+
+
+char saved_sram[0x4000];
+
+int mpc52xx_pm_enter(suspend_state_t state)
+{
+ u32 clk_enables;
+ u32 msr, hid0;
+ u32 intr_main_mask;
+ void __iomem * irq_0x500 = (void *)CONFIG_KERNEL_START + 0x500;
+ unsigned long irq_0x500_stop = (unsigned long)irq_0x500 + mpc52xx_ds_cached_size;
+ char saved_0x500[mpc52xx_ds_cached_size];
+
+ /* disable all interrupts in PIC */
+ intr_main_mask = in_be32(&intr->main_mask);
+ out_be32(&intr->main_mask, intr_main_mask | 0x1ffff);
+
+ /* don't let DEC expire any time soon */
+ mtspr(SPRN_DEC, 0x7fffffff);
+
+ /* save SRAM */
+ memcpy(saved_sram, sram, sram_size);
+
+ /* copy low level suspend code to sram */
+ memcpy(sram, mpc52xx_ds_sram, mpc52xx_ds_sram_size);
+
+ out_8(&cdm->ccs_sleep_enable, 1);
+ out_8(&cdm->osc_sleep_enable, 1);
+ out_8(&cdm->ccs_qreq_test, 1);
+
+ /* disable all but SDRAM and bestcomm (SRAM) clocks */
+ clk_enables = in_be32(&cdm->clk_enables);
+ out_be32(&cdm->clk_enables, clk_enables & 0x00088000);
+
+ /* disable power management */
+ msr = mfmsr();
+ mtmsr(msr & ~MSR_POW);
+
+ /* enable sleep mode, disable others */
+ hid0 = mfspr(SPRN_HID0);
+ mtspr(SPRN_HID0, (hid0 & ~(HID0_DOZE | HID0_NAP | HID0_DPM)) | HID0_SLEEP);
+
+ /* save original, copy our irq handler, flush from dcache and invalidate icache */
+ memcpy(saved_0x500, irq_0x500, mpc52xx_ds_cached_size);
+ memcpy(irq_0x500, mpc52xx_ds_cached, mpc52xx_ds_cached_size);
+ flush_icache_range((unsigned long)irq_0x500, irq_0x500_stop);
+
+ /* call low-level sleep code */
+ mpc52xx_deep_sleep(sram, sdram, cdm, intr);
+
+ /* restore original irq handler */
+ memcpy(irq_0x500, saved_0x500, mpc52xx_ds_cached_size);
+ flush_icache_range((unsigned long)irq_0x500, irq_0x500_stop);
+
+ /* restore old power mode */
+ mtmsr(msr & ~MSR_POW);
+ mtspr(SPRN_HID0, hid0);
+ mtmsr(msr);
+
+ out_be32(&cdm->clk_enables, clk_enables);
+ out_8(&cdm->ccs_sleep_enable, 0);
+ out_8(&cdm->osc_sleep_enable, 0);
+
+ /* restore SRAM */
+ memcpy(sram, saved_sram, sram_size);
+
+ /* restart jiffies */
+ wakeup_decrementer();
+
+ /* reenable interrupts in PIC */
+ out_be32(&intr->main_mask, intr_main_mask);
+
+ return 0;
+}
+
+int mpc52xx_pm_finish(suspend_state_t state)
+{
+ /* call board resume code */
+ if (mpc52xx_suspend.board_resume_finish)
+ mpc52xx_suspend.board_resume_finish(mbar);
+
+ iounmap(mbar);
+
+ return 0;
+}
+
+static struct pm_ops mpc52xx_pm_ops = {
+ .valid = mpc52xx_pm_valid,
+ .prepare = mpc52xx_pm_prepare,
+ .enter = mpc52xx_pm_enter,
+ .finish = mpc52xx_pm_finish,
+};
+
+int __init mpc52xx_pm_init(void)
+{
+ pm_set_ops(&mpc52xx_pm_ops);
+ return 0;
+}
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_sleep.S b/arch/powerpc/platforms/52xx/mpc52xx_sleep.S
new file mode 100644
index 0000000..4dc170b
--- /dev/null
+++ b/arch/powerpc/platforms/52xx/mpc52xx_sleep.S
@@ -0,0 +1,154 @@
+#include <asm/reg.h>
+#include <asm/ppc_asm.h>
+#include <asm/processor.h>
+
+
+.text
+
+_GLOBAL(mpc52xx_deep_sleep)
+mpc52xx_deep_sleep: /* args r3-r6: SRAM, SDRAM regs, CDM regs, INTR regs */
+
+ /* enable interrupts */
+ mfmsr r7
+ ori r7, r7, 0x8000 /* EE */
+ mtmsr r7
+ sync; isync;
+
+ li r10, 0 /* flag that irq handler sets */
+
+ /* enable tmr7 (or any other) interrupt */
+ lwz r8, 0x14(r6) /* intr->main_mask */
+ ori r8, r8, 0x1
+ xori r8, r8, 0x1
+ stw r8, 0x14(r6)
+ sync
+
+ /* emulate tmr7 interrupt */
+ li r8, 0x1
+ stw r8, 0x40(r6) /* intr->main_emulate */
+ sync
+
+ /* wait for it to happen */
+1:
+ cmpi cr0, r10, 1
+ bne cr0, 1b
+
+ /* lock icache */
+ mfspr r10, SPRN_HID0
+ ori r10, r10, 0x2000
+ sync; isync;
+ mtspr SPRN_HID0, r10
+ sync; isync;
+
+
+ mflr r9 /* save LR */
+
+ /* jump to sram */
+ mtlr r3
+ blrl
+
+ mtlr r9 /* restore LR */
+
+ /* unlock icache */
+ mfspr r10, SPRN_HID0
+ ori r10, r10, 0x2000
+ xori r10, r10, 0x2000
+ sync; isync;
+ mtspr SPRN_HID0, r10
+ sync; isync;
+
+
+ /* return to C code */
+ blr
+
+
+_GLOBAL(mpc52xx_ds_sram)
+mpc52xx_ds_sram:
+ /* put SDRAM into self-refresh */
+ lwz r8, 0x4(r4) /* sdram->ctrl */
+
+ oris r8, r8, 0x8000 /* mode_en */
+ stw r8, 0x4(r4)
+ sync
+
+ ori r8, r8, 0x0002 /* soft_pre */
+ stw r8, 0x4(r4)
+ sync
+ xori r8, r8, 0x0002
+
+ xoris r8, r8, 0x8000 /* !mode_en */
+ stw r8, 0x4(r4)
+ sync
+
+ oris r8, r8, 0x5000
+ xoris r8, r8, 0x4000 /* ref_en !cke */
+ stw r8, 0x4(r4)
+ sync
+
+ /* disable SDRAM clock */
+ lwz r8, 0x14(r5) /* cdm->clkenable */
+ ori r8, r8, 0x0008
+ xori r8, r8, 0x0008
+ stw r8, 0x14(r5)
+ sync
+
+
+ /* put mpc5200 to sleep */
+ mfmsr r10
+ oris r10, r10, 0x0004 /* POW = 1 */
+ sync; isync;
+ mtmsr r10
+ sync; isync;
+
+
+ /* enable clock */
+ lwz r8, 0x14(r5)
+ ori r8, r8, 0x0008
+ stw r8, 0x14(r5)
+ sync
+
+ /* get ram out of self-refresh */
+ lwz r8, 0x4(r4)
+ oris r8, r8, 0x5000 /* cke ref_en */
+ stw r8, 0x4(r4)
+ sync
+
+ blr
+_GLOBAL(mpc52xx_ds_sram_size)
+mpc52xx_ds_sram_size:
+ .long $-mpc52xx_ds_sram
+
+
+/* ### interrupt handler for wakeup from deep-sleep ### */
+_GLOBAL(mpc52xx_ds_cached)
+mpc52xx_ds_cached:
+ mtspr SPRN_SPRG0, r7
+ mtspr SPRN_SPRG1, r8
+
+ /* disable emulated interrupt */
+ mfspr r7, 311 /* MBAR */
+ addi r7, r7, 0x540 /* intr->main_emul */
+ li r8, 0
+ stw r8, 0(r7)
+ sync
+ dcbf 0, r7
+
+ /* acknowledge wakeup, so CCS releases power pown */
+ mfspr r7, 311 /* MBAR */
+ addi r7, r7, 0x524 /* intr->enc_status */
+ lwz r8, 0(r7)
+ ori r8, r8, 0x0400
+ stw r8, 0(r7)
+ sync
+ dcbf 0, r7
+
+ /* flag - we handled the interrupt */
+ li r10, 1
+
+ mfspr r8, SPRN_SPRG1
+ mfspr r7, SPRN_SPRG0
+
+ rfi
+_GLOBAL(mpc52xx_ds_cached_size)
+mpc52xx_ds_cached_size:
+ .long $-mpc52xx_ds_cached
diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c
index fff09f5..94843ed 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c
@@ -111,6 +111,7 @@
{ .type = "soc", },
{ .compatible = "soc", },
{ .type = "qe", },
+ { .type = "mdio", },
{},
};
diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
index 6b71e9f..b0b22bb 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
@@ -73,6 +73,7 @@
{ .type = "soc", },
{ .compatible = "soc", },
{ .type = "qe", },
+ { .type = "mdio", },
{},
};
diff --git a/arch/powerpc/platforms/83xx/mpc836x_mds.c b/arch/powerpc/platforms/83xx/mpc836x_mds.c
index 526ed09..bceeff8 100644
--- a/arch/powerpc/platforms/83xx/mpc836x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc836x_mds.c
@@ -118,6 +118,7 @@
{ .type = "soc", },
{ .compatible = "soc", },
{ .type = "qe", },
+ { .type = "mdio", },
{},
};
diff --git a/arch/powerpc/platforms/85xx/mpc8544_ds.c b/arch/powerpc/platforms/85xx/mpc8544_ds.c
index 2867f85..bec84ff 100644
--- a/arch/powerpc/platforms/85xx/mpc8544_ds.c
+++ b/arch/powerpc/platforms/85xx/mpc8544_ds.c
@@ -84,7 +84,7 @@
#ifdef CONFIG_PPC_I8259
/* Initialize the i8259 controller */
for_each_node_by_type(np, "interrupt-controller")
- if (device_is_compatible(np, "chrp,iic")) {
+ if (of_device_is_compatible(np, "chrp,iic")) {
cascade_node = np;
break;
}
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
index 7e71636..1490eb3 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
@@ -197,7 +197,7 @@
#ifdef CONFIG_PPC_I8259
/* Initialize the i8259 controller */
for_each_node_by_type(np, "interrupt-controller")
- if (device_is_compatible(np, "chrp,iic")) {
+ if (of_device_is_compatible(np, "chrp,iic")) {
cascade_node = np;
break;
}
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index 54db416..e3dddbf 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -147,6 +147,7 @@
{ .type = "soc", },
{ .compatible = "soc", },
{ .type = "qe", },
+ { .type = "mdio", },
{},
};
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index 3d3d98f..9087756 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -102,7 +102,7 @@
#ifdef CONFIG_PCI
/* Initialize i8259 controller */
for_each_node_by_type(np, "interrupt-controller")
- if (device_is_compatible(np, "chrp,iic")) {
+ if (of_device_is_compatible(np, "chrp,iic")) {
cascade_node = np;
break;
}
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index 51e3334..361acfa 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -42,6 +42,7 @@
source "arch/powerpc/platforms/85xx/Kconfig"
source "arch/powerpc/platforms/86xx/Kconfig"
source "arch/powerpc/platforms/embedded6xx/Kconfig"
+source "arch/powerpc/platforms/44x/Kconfig"
#source "arch/powerpc/platforms/4xx/Kconfig
config PPC_NATIVE
diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile
index 4520042..d6e041a 100644
--- a/arch/powerpc/platforms/Makefile
+++ b/arch/powerpc/platforms/Makefile
@@ -6,7 +6,8 @@
endif
endif
obj-$(CONFIG_PPC_CHRP) += chrp/
-obj-$(CONFIG_4xx) += 4xx/
+#obj-$(CONFIG_4xx) += 4xx/
+obj-$(CONFIG_44x) += 44x/
obj-$(CONFIG_PPC_MPC52xx) += 52xx/
obj-$(CONFIG_PPC_8xx) += 8xx/
obj-$(CONFIG_PPC_82xx) += 82xx/
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index 4fc4e927..47264e7 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -227,7 +227,7 @@
static int iic_host_match(struct irq_host *h, struct device_node *node)
{
- return device_is_compatible(node,
+ return of_device_is_compatible(node,
"IBM,CBEA-Internal-Interrupt-Controller");
}
@@ -256,7 +256,7 @@
unsigned int node, ext, unit, class;
const u32 *val;
- if (!device_is_compatible(ct,
+ if (!of_device_is_compatible(ct,
"IBM,CBEA-Internal-Interrupt-Controller"))
return -ENODEV;
if (intsize != 1)
@@ -324,7 +324,7 @@
for (dn = NULL;
(dn = of_find_node_by_name(dn,"interrupt-controller")) != NULL;) {
- if (!device_is_compatible(dn,
+ if (!of_device_is_compatible(dn,
"IBM,CBEA-Internal-Interrupt-Controller"))
continue;
np = of_get_property(dn, "ibm,interrupt-server-ranges", NULL);
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
index 54b9618..db66542 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -112,7 +112,7 @@
for (dn = NULL;
(dn = of_find_node_by_name(dn, "interrupt-controller"));) {
- if (!device_is_compatible(dn, "CBEA,platform-open-pic"))
+ if (!of_device_is_compatible(dn, "CBEA,platform-open-pic"))
continue;
/* The MPIC driver will get everything it needs from the
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index fb1f157..05f4b3d 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -358,12 +358,12 @@
*/
for (dn = NULL;
(dn = of_find_node_by_name(dn, "interrupt-controller"));) {
- if (device_is_compatible(dn, "CBEA,platform-spider-pic")) {
+ if (of_device_is_compatible(dn, "CBEA,platform-spider-pic")) {
if (of_address_to_resource(dn, 0, &r)) {
printk(KERN_WARNING "spider-pic: Failed\n");
continue;
}
- } else if (device_is_compatible(dn, "sti,platform-spider-pic")
+ } else if (of_device_is_compatible(dn, "sti,platform-spider-pic")
&& (chip < 2)) {
static long hard_coded_pics[] =
{ 0x24000008000ul, 0x34000008000ul};
diff --git a/arch/powerpc/platforms/cell/spufs/backing_ops.c b/arch/powerpc/platforms/cell/spufs/backing_ops.c
index 3322528..d32db9f 100644
--- a/arch/powerpc/platforms/cell/spufs/backing_ops.c
+++ b/arch/powerpc/platforms/cell/spufs/backing_ops.c
@@ -28,7 +28,6 @@
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/poll.h>
diff --git a/arch/powerpc/platforms/cell/spufs/hw_ops.c b/arch/powerpc/platforms/cell/spufs/hw_ops.c
index 428875c..fc4ed1f 100644
--- a/arch/powerpc/platforms/cell/spufs/hw_ops.c
+++ b/arch/powerpc/platforms/cell/spufs/hw_ops.c
@@ -25,7 +25,6 @@
#include <linux/mm.h>
#include <linux/poll.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index 91030b8..b6ecb30 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -30,7 +30,6 @@
#include <linux/completion.h>
#include <linux/vmalloc.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/numa.h>
diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c
index 8347c4a..29dc59c 100644
--- a/arch/powerpc/platforms/cell/spufs/switch.c
+++ b/arch/powerpc/platforms/cell/spufs/switch.c
@@ -39,7 +39,6 @@
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c
index 1469d64..d32fedc 100644
--- a/arch/powerpc/platforms/chrp/pci.c
+++ b/arch/powerpc/platforms/chrp/pci.c
@@ -267,7 +267,7 @@
model = of_get_property(dev, "model", NULL);
if (model == NULL)
model = "<none>";
- if (device_is_compatible(dev, "IBM,python")) {
+ if (of_device_is_compatible(dev, "IBM,python")) {
setup_python(hose, dev);
} else if (is_mot
|| strncmp(model, "Motorola, Grackle", 17) == 0) {
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
index 1870038..373de4c 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -448,7 +448,7 @@
/* Look for cascade */
for_each_node_by_type(np, "interrupt-controller")
- if (device_is_compatible(np, "chrp,iic")) {
+ if (of_device_is_compatible(np, "chrp,iic")) {
pic = np;
break;
}
diff --git a/arch/powerpc/platforms/chrp/smp.c b/arch/powerpc/platforms/chrp/smp.c
index 1d2307e..3ea0eb7 100644
--- a/arch/powerpc/platforms/chrp/smp.c
+++ b/arch/powerpc/platforms/chrp/smp.c
@@ -11,7 +11,6 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
#include <linux/delay.h>
diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig
index 9557908..8f3c2a7 100644
--- a/arch/powerpc/platforms/embedded6xx/Kconfig
+++ b/arch/powerpc/platforms/embedded6xx/Kconfig
@@ -20,16 +20,24 @@
select TSI108_BRIDGE
select DEFAULT_UIMAGE
select PPC_UDBG_16550
- select MPIC
- select MPIC_WEIRD
help
Select MPC7448HPC2 if configuring for Freescale MPC7448HPC2 (Taiga)
platform
+
+config PPC_HOLLY
+ bool "PPC750GX/CL with TSI10x bridge (Hickory/Holly)"
+ select TSI108_BRIDGE
+ select PPC_UDBG_16550
+ help
+ Select PPC_HOLLY if configuring for an IBM 750GX/CL Eval
+ Board with TSI108/9 bridge (Hickory/Holly)
endchoice
config TSI108_BRIDGE
bool
- depends on MPC7448HPC2
+ depends on MPC7448HPC2 || PPC_HOLLY
+ select MPIC
+ select MPIC_WEIRD
default y
config MPC10X_BRIDGE
diff --git a/arch/powerpc/platforms/embedded6xx/Makefile b/arch/powerpc/platforms/embedded6xx/Makefile
index d3d11a3..b39fe4f 100644
--- a/arch/powerpc/platforms/embedded6xx/Makefile
+++ b/arch/powerpc/platforms/embedded6xx/Makefile
@@ -3,3 +3,4 @@
#
obj-$(CONFIG_MPC7448HPC2) += mpc7448_hpc2.o
obj-$(CONFIG_LINKSTATION) += linkstation.o ls_uart.o
+obj-$(CONFIG_PPC_HOLLY) += holly.o
diff --git a/arch/powerpc/platforms/embedded6xx/holly.c b/arch/powerpc/platforms/embedded6xx/holly.c
new file mode 100644
index 0000000..3a0b4a0
--- /dev/null
+++ b/arch/powerpc/platforms/embedded6xx/holly.c
@@ -0,0 +1,317 @@
+/*
+ * Board setup routines for the IBM 750GX/CL platform w/ TSI10x bridge
+ *
+ * Copyright 2007 IBM Corporation
+ *
+ * Stephen Winiecki <stevewin@us.ibm.com>
+ * Josh Boyer <jwboyer@linux.vnet.ibm.com>
+ *
+ * Based on code from mpc7448_hpc2.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/ide.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_core.h>
+
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/machdep.h>
+#include <asm/prom.h>
+#include <asm/udbg.h>
+#include <asm/tsi108.h>
+#include <asm/pci-bridge.h>
+#include <asm/reg.h>
+#include <mm/mmu_decl.h>
+#include <asm/tsi108_irq.h>
+#include <asm/tsi108_pci.h>
+#include <asm/mpic.h>
+#include <asm/of_platform.h>
+
+#undef DEBUG
+
+#define HOLLY_PCI_CFG_PHYS 0x7c000000
+
+int holly_exclude_device(u_char bus, u_char devfn)
+{
+ if (bus == 0 && PCI_SLOT(devfn) == 0)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ else
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static void holly_remap_bridge(void)
+{
+ u32 lut_val, lut_addr;
+ int i;
+
+ printk(KERN_INFO "Remapping PCI bridge\n");
+
+ /* Re-init the PCI bridge and LUT registers to have mappings that don't
+ * rely on PIBS
+ */
+ lut_addr = 0x900;
+ for (i = 0; i < 31; i++) {
+ tsi108_write_reg(TSI108_PB_OFFSET + lut_addr, 0x00000201);
+ lut_addr += 4;
+ tsi108_write_reg(TSI108_PB_OFFSET + lut_addr, 0x0);
+ lut_addr += 4;
+ }
+
+ /* Reserve the last LUT entry for PCI I/O space */
+ tsi108_write_reg(TSI108_PB_OFFSET + lut_addr, 0x00000241);
+ lut_addr += 4;
+ tsi108_write_reg(TSI108_PB_OFFSET + lut_addr, 0x0);
+
+ /* Map PCI I/O space */
+ tsi108_write_reg(TSI108_PCI_PFAB_IO_UPPER, 0x0);
+ tsi108_write_reg(TSI108_PCI_PFAB_IO, 0x1);
+
+ /* Map PCI CFG space */
+ tsi108_write_reg(TSI108_PCI_PFAB_BAR0_UPPER, 0x0);
+ tsi108_write_reg(TSI108_PCI_PFAB_BAR0, 0x7c000000 | 0x01);
+
+ /* We don't need MEM32 and PRM remapping so disable them */
+ tsi108_write_reg(TSI108_PCI_PFAB_MEM32, 0x0);
+ tsi108_write_reg(TSI108_PCI_PFAB_PFM3, 0x0);
+ tsi108_write_reg(TSI108_PCI_PFAB_PFM4, 0x0);
+
+ /* Set P2O_BAR0 */
+ tsi108_write_reg(TSI108_PCI_P2O_BAR0_UPPER, 0x0);
+ tsi108_write_reg(TSI108_PCI_P2O_BAR0, 0xc0000000);
+
+ /* Init the PCI LUTs to do no remapping */
+ lut_addr = 0x500;
+ lut_val = 0x00000002;
+
+ for (i = 0; i < 32; i++) {
+ tsi108_write_reg(TSI108_PCI_OFFSET + lut_addr, lut_val);
+ lut_addr += 4;
+ tsi108_write_reg(TSI108_PCI_OFFSET + lut_addr, 0x40000000);
+ lut_addr += 4;
+ lut_val += 0x02000000;
+ }
+ tsi108_write_reg(TSI108_PCI_P2O_PAGE_SIZES, 0x00007900);
+
+ /* Set 64-bit PCI bus address for system memory */
+ tsi108_write_reg(TSI108_PCI_P2O_BAR2_UPPER, 0x0);
+ tsi108_write_reg(TSI108_PCI_P2O_BAR2, 0x0);
+}
+
+static void __init holly_setup_arch(void)
+{
+ struct device_node *cpu;
+ struct device_node *np;
+
+ if (ppc_md.progress)
+ ppc_md.progress("holly_setup_arch():set_bridge", 0);
+
+ cpu = of_find_node_by_type(NULL, "cpu");
+ if (cpu) {
+ const unsigned int *fp;
+
+ fp = of_get_property(cpu, "clock-frequency", NULL);
+ if (fp)
+ loops_per_jiffy = *fp / HZ;
+ else
+ loops_per_jiffy = 50000000 / HZ;
+ of_node_put(cpu);
+ }
+ tsi108_csr_vir_base = get_vir_csrbase();
+
+ /* setup PCI host bridge */
+ holly_remap_bridge();
+
+ np = of_find_node_by_type(NULL, "pci");
+ if (np)
+ tsi108_setup_pci(np, HOLLY_PCI_CFG_PHYS, 1);
+
+ ppc_md.pci_exclude_device = holly_exclude_device;
+ if (ppc_md.progress)
+ ppc_md.progress("tsi108: resources set", 0x100);
+
+ printk(KERN_INFO "PPC750GX/CL Platform\n");
+}
+
+/*
+ * Interrupt setup and service. Interrrupts on the holly come
+ * from the four external INT pins, PCI interrupts are routed via
+ * PCI interrupt control registers, it generates internal IRQ23
+ *
+ * Interrupt routing on the Holly Board:
+ * TSI108:PB_INT[0] -> CPU0:INT#
+ * TSI108:PB_INT[1] -> CPU0:MCP#
+ * TSI108:PB_INT[2] -> N/C
+ * TSI108:PB_INT[3] -> N/C
+ */
+static void __init holly_init_IRQ(void)
+{
+ struct mpic *mpic;
+ phys_addr_t mpic_paddr = 0;
+ struct device_node *tsi_pic;
+#ifdef CONFIG_PCI
+ unsigned int cascade_pci_irq;
+ struct device_node *tsi_pci;
+ struct device_node *cascade_node = NULL;
+#endif
+
+ tsi_pic = of_find_node_by_type(NULL, "open-pic");
+ if (tsi_pic) {
+ unsigned int size;
+ const void *prop = of_get_property(tsi_pic, "reg", &size);
+ mpic_paddr = of_translate_address(tsi_pic, prop);
+ }
+
+ if (mpic_paddr == 0) {
+ printk(KERN_ERR "%s: No tsi108 PIC found !\n", __func__);
+ return;
+ }
+
+ pr_debug("%s: tsi108 pic phys_addr = 0x%x\n", __func__, (u32) mpic_paddr);
+
+ mpic = mpic_alloc(tsi_pic, mpic_paddr,
+ MPIC_PRIMARY | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET |
+ MPIC_SPV_EOI | MPIC_NO_PTHROU_DIS | MPIC_REGSET_TSI108,
+ 24,
+ NR_IRQS-4, /* num_sources used */
+ "Tsi108_PIC");
+
+ BUG_ON(mpic == NULL);
+
+ mpic_assign_isu(mpic, 0, mpic_paddr + 0x100);
+
+ mpic_init(mpic);
+
+#ifdef CONFIG_PCI
+ tsi_pci = of_find_node_by_type(NULL, "pci");
+ if (tsi_pci == NULL) {
+ printk(KERN_ERR "%s: No tsi108 pci node found !\n", __func__);
+ return;
+ }
+
+ cascade_node = of_find_node_by_type(NULL, "pic-router");
+ if (cascade_node == NULL) {
+ printk(KERN_ERR "%s: No tsi108 pci cascade node found !\n", __func__);
+ return;
+ }
+
+ cascade_pci_irq = irq_of_parse_and_map(tsi_pci, 0);
+ pr_debug("%s: tsi108 cascade_pci_irq = 0x%x\n", __func__, (u32) cascade_pci_irq);
+ tsi108_pci_int_init(cascade_node);
+ set_irq_data(cascade_pci_irq, mpic);
+ set_irq_chained_handler(cascade_pci_irq, tsi108_irq_cascade);
+#endif
+ /* Configure MPIC outputs to CPU0 */
+ tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0);
+ of_node_put(tsi_pic);
+}
+
+void holly_show_cpuinfo(struct seq_file *m)
+{
+ seq_printf(m, "vendor\t\t: IBM\n");
+ seq_printf(m, "machine\t\t: PPC750 GX/CL\n");
+}
+
+void holly_restart(char *cmd)
+{
+ __be32 __iomem *ocn_bar1 = NULL;
+ unsigned long bar;
+ struct device_node *bridge = NULL;
+ const void *prop;
+ int size;
+ phys_addr_t addr = 0xc0000000;
+
+ local_irq_disable();
+
+ bridge = of_find_node_by_type(NULL, "tsi-bridge");
+ if (bridge) {
+ prop = of_get_property(bridge, "reg", &size);
+ addr = of_translate_address(bridge, prop);
+ }
+ addr += (TSI108_PB_OFFSET + 0x414);
+
+ ocn_bar1 = ioremap(addr, 0x4);
+
+ /* Turn on the BOOT bit so the addresses are correctly
+ * routed to the HLP interface */
+ bar = ioread32be(ocn_bar1);
+ bar |= 2;
+ iowrite32be(bar, ocn_bar1);
+ iosync();
+
+ /* Set SRR0 to the reset vector and turn on MSR_IP */
+ mtspr(SPRN_SRR0, 0xfff00100);
+ mtspr(SPRN_SRR1, MSR_IP);
+
+ /* Do an rfi to jump back to firmware. Somewhat evil,
+ * but it works
+ */
+ __asm__ __volatile__("rfi" : : : "memory");
+
+ /* Spin until reset happens. Shouldn't really get here */
+ for (;;) ;
+}
+
+void holly_power_off(void)
+{
+ local_irq_disable();
+ /* No way to shut power off with software */
+ for (;;) ;
+}
+
+void holly_halt(void)
+{
+ holly_power_off();
+}
+
+/*
+ * Called very early, device-tree isn't unflattened
+ */
+static int __init holly_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ if (!of_flat_dt_is_compatible(root, "ibm,holly"))
+ return 0;
+ return 1;
+}
+
+static int ppc750_machine_check_exception(struct pt_regs *regs)
+{
+ const struct exception_table_entry *entry;
+
+ /* Are we prepared to handle this fault */
+ if ((entry = search_exception_tables(regs->nip)) != NULL) {
+ tsi108_clear_pci_cfg_error();
+ regs->msr |= MSR_RI;
+ regs->nip = entry->fixup;
+ return 1;
+ }
+ return 0;
+}
+
+define_machine(holly){
+ .name = "PPC750 GX/CL TSI",
+ .probe = holly_probe,
+ .setup_arch = holly_setup_arch,
+ .init_IRQ = holly_init_IRQ,
+ .show_cpuinfo = holly_show_cpuinfo,
+ .get_irq = mpic_get_irq,
+ .restart = holly_restart,
+ .calibrate_decr = generic_calibrate_decr,
+ .machine_check_exception = ppc750_machine_check_exception,
+ .progress = udbg_progress,
+};
diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
index c3f64dd..4542e0c8 100644
--- a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
+++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
@@ -41,6 +41,7 @@
#include <asm/reg.h>
#include <mm/mmu_decl.h>
#include "mpc7448_hpc2.h"
+#include <asm/tsi108_pci.h>
#include <asm/tsi108_irq.h>
#include <asm/mpic.h>
@@ -51,16 +52,15 @@
#define DBG(fmt...) do { } while(0)
#endif
+#define MPC7448HPC2_PCI_CFG_PHYS 0xfb000000
+
#ifndef CONFIG_PCI
isa_io_base = MPC7448_HPC2_ISA_IO_BASE;
isa_mem_base = MPC7448_HPC2_ISA_MEM_BASE;
pci_dram_offset = MPC7448_HPC2_PCI_MEM_OFFSET;
#endif
-extern int tsi108_setup_pci(struct device_node *dev);
extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val);
-extern void tsi108_pci_int_init(struct device_node *node);
-extern void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc);
int mpc7448_hpc2_exclude_device(u_char bus, u_char devfn)
{
@@ -72,28 +72,16 @@
static void __init mpc7448_hpc2_setup_arch(void)
{
- struct device_node *cpu;
struct device_node *np;
if (ppc_md.progress)
ppc_md.progress("mpc7448_hpc2_setup_arch():set_bridge", 0);
- cpu = of_find_node_by_type(NULL, "cpu");
- if (cpu != 0) {
- const unsigned int *fp;
-
- fp = of_get_property(cpu, "clock-frequency", NULL);
- if (fp != 0)
- loops_per_jiffy = *fp / HZ;
- else
- loops_per_jiffy = 50000000 / HZ;
- of_node_put(cpu);
- }
tsi108_csr_vir_base = get_vir_csrbase();
/* setup PCI host bridge */
#ifdef CONFIG_PCI
for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
- tsi108_setup_pci(np);
+ tsi108_setup_pci(np, MPC7448HPC2_PCI_CFG_PHYS, 0);
ppc_md.pci_exclude_device = mpc7448_hpc2_exclude_device;
if (ppc_md.progress)
@@ -222,7 +210,6 @@
static int mpc7448_machine_check_exception(struct pt_regs *regs)
{
- extern void tsi108_clear_pci_cfg_error(void);
const struct exception_table_entry *entry;
/* Are we prepared to handle this fault */
diff --git a/arch/powerpc/platforms/iseries/smp.c b/arch/powerpc/platforms/iseries/smp.c
index aee5908..722335e 100644
--- a/arch/powerpc/platforms/iseries/smp.c
+++ b/arch/powerpc/platforms/iseries/smp.c
@@ -18,7 +18,6 @@
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
#include <linux/delay.h>
diff --git a/arch/powerpc/platforms/iseries/viopath.c b/arch/powerpc/platforms/iseries/viopath.c
index 2ca2d8a..354b8dd 100644
--- a/arch/powerpc/platforms/iseries/viopath.c
+++ b/arch/powerpc/platforms/iseries/viopath.c
@@ -36,7 +36,6 @@
#include <linux/dma-mapping.h>
#include <linux/wait.h>
#include <linux/seq_file.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <asm/system.h>
diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c
index b1d3b99..7aaa5bb 100644
--- a/arch/powerpc/platforms/maple/pci.c
+++ b/arch/powerpc/platforms/maple/pci.c
@@ -467,15 +467,15 @@
hose->last_busno = bus_range ? bus_range[1] : 0xff;
disp_name = NULL;
- if (device_is_compatible(dev, "u3-agp")) {
+ if (of_device_is_compatible(dev, "u3-agp")) {
setup_u3_agp(hose);
disp_name = "U3-AGP";
primary = 0;
- } else if (device_is_compatible(dev, "u3-ht")) {
+ } else if (of_device_is_compatible(dev, "u3-ht")) {
setup_u3_ht(hose);
disp_name = "U3-HT";
primary = 1;
- } else if (device_is_compatible(dev, "u4-pcie")) {
+ } else if (of_device_is_compatible(dev, "u4-pcie")) {
setup_u4_pcie(hose);
disp_name = "U4-PCIE";
primary = 0;
@@ -556,12 +556,12 @@
continue;
if (strcmp(np->type, "pci") && strcmp(np->type, "ht"))
continue;
- if ((device_is_compatible(np, "u4-pcie") ||
- device_is_compatible(np, "u3-agp")) &&
+ if ((of_device_is_compatible(np, "u4-pcie") ||
+ of_device_is_compatible(np, "u3-agp")) &&
add_bridge(np) == 0)
of_node_get(np);
- if (device_is_compatible(np, "u3-ht")) {
+ if (of_device_is_compatible(np, "u3-ht")) {
of_node_get(np);
ht = np;
}
diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c
index 2a30c5b..354c058 100644
--- a/arch/powerpc/platforms/maple/setup.c
+++ b/arch/powerpc/platforms/maple/setup.c
@@ -231,7 +231,7 @@
*/
for_each_node_by_type(np, "interrupt-controller")
- if (device_is_compatible(np, "open-pic")) {
+ if (of_device_is_compatible(np, "open-pic")) {
mpic_node = np;
break;
}
diff --git a/arch/powerpc/platforms/pasemi/cpufreq.c b/arch/powerpc/platforms/pasemi/cpufreq.c
index 2a57d60..3ae0838 100644
--- a/arch/powerpc/platforms/pasemi/cpufreq.c
+++ b/arch/powerpc/platforms/pasemi/cpufreq.c
@@ -31,6 +31,7 @@
#include <asm/hw_irq.h>
#include <asm/io.h>
#include <asm/prom.h>
+#include <asm/time.h>
#define SDCASR_REG 0x0100
#define SDCASR_REG_STRIDE 0x1000
@@ -204,6 +205,8 @@
policy->cur = pas_freqs[cur_astate].frequency;
policy->cpus = cpu_online_map;
+ ppc_proc_freq = policy->cur * 1000ul;
+
cpufreq_frequency_table_get_attr(pas_freqs, policy->cpu);
/* this ensures that policy->cpuinfo_min and policy->cpuinfo_max
@@ -270,6 +273,7 @@
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
mutex_unlock(&pas_switch_mutex);
+ ppc_proc_freq = freqs.new * 1000ul;
return 0;
}
diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c
index f88f0ec..38f107b 100644
--- a/arch/powerpc/platforms/pasemi/setup.c
+++ b/arch/powerpc/platforms/pasemi/setup.c
@@ -114,7 +114,7 @@
mpic_node = NULL;
for_each_node_by_type(np, "interrupt-controller")
- if (device_is_compatible(np, "open-pic")) {
+ if (of_device_is_compatible(np, "open-pic")) {
mpic_node = np;
break;
}
@@ -211,7 +211,10 @@
static int __init pasemi_publish_devices(void)
{
- /* Publish OF platform devices for southbridge IOs */
+ if (!machine_is(pasemi))
+ return 0;
+
+ /* Publish OF platform devices for SDC and other non-PCI devices */
of_platform_bus_probe(NULL, pasemi_bus_ids, NULL);
return 0;
diff --git a/arch/powerpc/platforms/powermac/cpufreq_64.c b/arch/powerpc/platforms/powermac/cpufreq_64.c
index 567d552..00f5029 100644
--- a/arch/powerpc/platforms/powermac/cpufreq_64.c
+++ b/arch/powerpc/platforms/powermac/cpufreq_64.c
@@ -357,13 +357,13 @@
static int g5_cpufreq_cpu_init(struct cpufreq_policy *policy)
{
- if (policy->cpu != 0)
- return -ENODEV;
-
policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
policy->cur = g5_cpu_freqs[g5_query_freq()].frequency;
- policy->cpus = cpu_possible_map;
+ /* secondary CPUs are tied to the primary one by the
+ * cpufreq core if in the secondary policy we tell it that
+ * it actually must be one policy together with all others. */
+ policy->cpus = cpu_online_map;
cpufreq_frequency_table_get_attr(g5_cpu_freqs, policy->cpu);
return cpufreq_frequency_table_cpuinfo(policy,
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c
index 52cfdd8..f29705f 100644
--- a/arch/powerpc/platforms/powermac/feature.c
+++ b/arch/powerpc/platforms/powermac/feature.c
@@ -1418,7 +1418,7 @@
phy = of_get_next_child(node, NULL);
if (!phy)
return -ENODEV;
- need_reset = device_is_compatible(phy, "B5221");
+ need_reset = of_device_is_compatible(phy, "B5221");
of_node_put(phy);
if (!need_reset)
return 0;
@@ -2624,7 +2624,7 @@
for (node = NULL; (node = of_find_node_by_name(node, name)) != NULL;) {
if (!compat)
break;
- if (device_is_compatible(node, compat))
+ if (of_device_is_compatible(node, compat))
break;
}
if (!node)
@@ -2728,7 +2728,7 @@
conn = of_get_property(np, "AAPL,connector", &len);
if (conn && (strcmp(conn, "infrared") == 0))
port_type = PMAC_SCC_IRDA;
- else if (device_is_compatible(np, "cobalt"))
+ else if (of_device_is_compatible(np, "cobalt"))
modem = 1;
else if (slots && slots->count > 0) {
if (strcmp(slots->name, "IrDA") == 0)
@@ -2787,7 +2787,7 @@
*/
np = of_find_node_by_name(NULL, "ethernet");
while(np) {
- if (device_is_compatible(np, "K2-GMAC"))
+ if (of_device_is_compatible(np, "K2-GMAC"))
g5_gmac_enable(np, 0, 1);
np = of_find_node_by_name(np, "ethernet");
}
@@ -2799,7 +2799,7 @@
*/
np = of_find_node_by_name(NULL, "firewire");
while(np) {
- if (device_is_compatible(np, "pci106b,5811")) {
+ if (of_device_is_compatible(np, "pci106b,5811")) {
macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED;
g5_fw_enable(np, 0, 1);
}
@@ -2817,8 +2817,8 @@
np = of_find_node_by_name(NULL, "ethernet");
while(np) {
if (np->parent
- && device_is_compatible(np->parent, "uni-north")
- && device_is_compatible(np, "gmac"))
+ && of_device_is_compatible(np->parent, "uni-north")
+ && of_device_is_compatible(np, "gmac"))
core99_gmac_enable(np, 0, 1);
np = of_find_node_by_name(np, "ethernet");
}
@@ -2831,10 +2831,10 @@
np = of_find_node_by_name(NULL, "firewire");
while(np) {
if (np->parent
- && device_is_compatible(np->parent, "uni-north")
- && (device_is_compatible(np, "pci106b,18") ||
- device_is_compatible(np, "pci106b,30") ||
- device_is_compatible(np, "pci11c1,5811"))) {
+ && of_device_is_compatible(np->parent, "uni-north")
+ && (of_device_is_compatible(np, "pci106b,18") ||
+ of_device_is_compatible(np, "pci106b,30") ||
+ of_device_is_compatible(np, "pci11c1,5811"))) {
macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED;
core99_firewire_enable(np, 0, 1);
}
@@ -2845,8 +2845,8 @@
np = of_find_node_by_name(NULL, "ata-6");
while(np) {
if (np->parent
- && device_is_compatible(np->parent, "uni-north")
- && device_is_compatible(np, "kauai-ata")) {
+ && of_device_is_compatible(np->parent, "uni-north")
+ && of_device_is_compatible(np, "kauai-ata")) {
core99_ata100_enable(np, 1);
}
np = of_find_node_by_name(np, "ata-6");
diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c
index 5430e14..3f507ab 100644
--- a/arch/powerpc/platforms/powermac/low_i2c.c
+++ b/arch/powerpc/platforms/powermac/low_i2c.c
@@ -1207,7 +1207,7 @@
if (strcmp(np->name, p->name))
continue;
if (p->compatible &&
- !device_is_compatible(np, p->compatible))
+ !of_device_is_compatible(np, p->compatible))
continue;
if (p->quirks & pmac_i2c_quirk_skip)
break;
diff --git a/arch/powerpc/platforms/powermac/nvram.c b/arch/powerpc/platforms/powermac/nvram.c
index 692945c..c6f0f9e 100644
--- a/arch/powerpc/platforms/powermac/nvram.c
+++ b/arch/powerpc/platforms/powermac/nvram.c
@@ -553,7 +553,7 @@
* identify the chip using flash id commands and base ourselves on
* a list of known chips IDs
*/
- if (device_is_compatible(dp, "amd-0137")) {
+ if (of_device_is_compatible(dp, "amd-0137")) {
core99_erase_bank = amd_erase_bank;
core99_write_bank = amd_write_bank;
} else {
@@ -588,7 +588,7 @@
}
}
- is_core_99 = device_is_compatible(dp, "nvram,flash");
+ is_core_99 = of_device_is_compatible(dp, "nvram,flash");
if (is_core_99) {
err = core99_nvram_setup(dp, r1.start);
goto bail;
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index 22c4ae4..c4af9e2 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -934,15 +934,15 @@
/* 64 bits only bridges */
#ifdef CONFIG_PPC64
- if (device_is_compatible(dev, "u3-agp")) {
+ if (of_device_is_compatible(dev, "u3-agp")) {
setup_u3_agp(hose);
disp_name = "U3-AGP";
primary = 0;
- } else if (device_is_compatible(dev, "u3-ht")) {
+ } else if (of_device_is_compatible(dev, "u3-ht")) {
setup_u3_ht(hose);
disp_name = "U3-HT";
primary = 1;
- } else if (device_is_compatible(dev, "u4-pcie")) {
+ } else if (of_device_is_compatible(dev, "u4-pcie")) {
setup_u4_pcie(hose);
disp_name = "U4-PCIE";
primary = 0;
@@ -953,7 +953,7 @@
/* 32 bits only bridges */
#ifdef CONFIG_PPC32
- if (device_is_compatible(dev, "uni-north")) {
+ if (of_device_is_compatible(dev, "uni-north")) {
primary = setup_uninorth(hose, &rsrc);
disp_name = "UniNorth";
} else if (strcmp(dev->name, "pci") == 0) {
@@ -1129,21 +1129,21 @@
return 0;
uninorth_child = node->parent &&
- device_is_compatible(node->parent, "uni-north");
+ of_device_is_compatible(node->parent, "uni-north");
/* Firewire & GMAC were disabled after PCI probe, the driver is
* claiming them, we must re-enable them now.
*/
if (uninorth_child && !strcmp(node->name, "firewire") &&
- (device_is_compatible(node, "pci106b,18") ||
- device_is_compatible(node, "pci106b,30") ||
- device_is_compatible(node, "pci11c1,5811"))) {
+ (of_device_is_compatible(node, "pci106b,18") ||
+ of_device_is_compatible(node, "pci106b,30") ||
+ of_device_is_compatible(node, "pci11c1,5811"))) {
pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, node, 0, 1);
pmac_call_feature(PMAC_FTR_1394_ENABLE, node, 0, 1);
updatecfg = 1;
}
if (uninorth_child && !strcmp(node->name, "ethernet") &&
- device_is_compatible(node, "gmac")) {
+ of_device_is_compatible(node, "gmac")) {
pmac_call_feature(PMAC_FTR_GMAC_ENABLE, node, 0, 1);
updatecfg = 1;
}
@@ -1203,18 +1203,18 @@
#endif /* CONFIG_BLK_DEV_IDE */
for_each_node_by_name(nd, "firewire") {
- if (nd->parent && (device_is_compatible(nd, "pci106b,18") ||
- device_is_compatible(nd, "pci106b,30") ||
- device_is_compatible(nd, "pci11c1,5811"))
- && device_is_compatible(nd->parent, "uni-north")) {
+ if (nd->parent && (of_device_is_compatible(nd, "pci106b,18") ||
+ of_device_is_compatible(nd, "pci106b,30") ||
+ of_device_is_compatible(nd, "pci11c1,5811"))
+ && of_device_is_compatible(nd->parent, "uni-north")) {
pmac_call_feature(PMAC_FTR_1394_ENABLE, nd, 0, 0);
pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, nd, 0, 0);
}
}
of_node_put(nd);
for_each_node_by_name(nd, "ethernet") {
- if (nd->parent && device_is_compatible(nd, "gmac")
- && device_is_compatible(nd->parent, "uni-north"))
+ if (nd->parent && of_device_is_compatible(nd, "gmac")
+ && of_device_is_compatible(nd->parent, "uni-north"))
pmac_call_feature(PMAC_FTR_GMAC_ENABLE, nd, 0, 0);
}
of_node_put(nd);
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index ae5097a..87cd68051 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -364,7 +364,7 @@
slave = of_find_node_by_name(master, "mac-io");
/* Check ordering of master & slave */
- if (device_is_compatible(master, "gatwick")) {
+ if (of_device_is_compatible(master, "gatwick")) {
struct device_node *tmp;
BUG_ON(slave == NULL);
tmp = master;
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index b820cab..a410bc76 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -439,76 +439,14 @@
#endif
}
-/* TODO: Merge the suspend-to-ram with the common code !!!
- * currently, this is a stub implementation for suspend-to-disk
- * only
- */
-
-#ifdef CONFIG_SOFTWARE_SUSPEND
-
-static int pmac_pm_prepare(suspend_state_t state)
-{
- printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
-
- return 0;
-}
-
-static int pmac_pm_enter(suspend_state_t state)
-{
- printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
-
- /* Giveup the lazy FPU & vec so we don't have to back them
- * up from the low level code
- */
- enable_kernel_fp();
-
-#ifdef CONFIG_ALTIVEC
- if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC)
- enable_kernel_altivec();
-#endif /* CONFIG_ALTIVEC */
-
- return 0;
-}
-
-static int pmac_pm_finish(suspend_state_t state)
-{
- printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
-
- /* Restore userland MMU context */
- set_context(current->active_mm->context.id, current->active_mm->pgd);
-
- return 0;
-}
-
-static int pmac_pm_valid(suspend_state_t state)
-{
- switch (state) {
- case PM_SUSPEND_DISK:
- return 1;
- /* can't do any other states via generic mechanism yet */
- default:
- return 0;
- }
-}
-
-static struct pm_ops pmac_pm_ops = {
- .pm_disk_mode = PM_DISK_SHUTDOWN,
- .prepare = pmac_pm_prepare,
- .enter = pmac_pm_enter,
- .finish = pmac_pm_finish,
- .valid = pmac_pm_valid,
-};
-
-#endif /* CONFIG_SOFTWARE_SUSPEND */
-
static int initializing = 1;
static int pmac_late_init(void)
{
initializing = 0;
-#ifdef CONFIG_SOFTWARE_SUSPEND
- pm_set_ops(&pmac_pm_ops);
-#endif /* CONFIG_SOFTWARE_SUSPEND */
+ /* this is udbg (which is __init) and we can later use it during
+ * cpu hotplug (in smp_core99_kick_cpu) */
+ ppc_md.progress = NULL;
return 0;
}
@@ -721,12 +659,57 @@
/* We need to use normal PCI probing for the AGP bus,
* since the device for the AGP bridge isn't in the tree.
*/
- if (bus->self == NULL && (device_is_compatible(node, "u3-agp") ||
- device_is_compatible(node, "u4-pcie")))
+ if (bus->self == NULL && (of_device_is_compatible(node, "u3-agp") ||
+ of_device_is_compatible(node, "u4-pcie")))
return PCI_PROBE_NORMAL;
return PCI_PROBE_DEVTREE;
}
-#endif
+
+#ifdef CONFIG_HOTPLUG_CPU
+/* access per cpu vars from generic smp.c */
+DECLARE_PER_CPU(int, cpu_state);
+
+static void pmac_cpu_die(void)
+{
+ /*
+ * turn off as much as possible, we'll be
+ * kicked out as this will only be invoked
+ * on core99 platforms for now ...
+ */
+
+ printk(KERN_INFO "CPU#%d offline\n", smp_processor_id());
+ __get_cpu_var(cpu_state) = CPU_DEAD;
+ smp_wmb();
+
+ /*
+ * during the path that leads here preemption is disabled,
+ * reenable it now so that when coming up preempt count is
+ * zero correctly
+ */
+ preempt_enable();
+
+ /*
+ * hard-disable interrupts for the non-NAP case, the NAP code
+ * needs to re-enable interrupts (but soft-disables them)
+ */
+ hard_irq_disable();
+
+ while (1) {
+ /* let's not take timer interrupts too often ... */
+ set_dec(0x7fffffff);
+
+ /* should always be true at this point */
+ if (cpu_has_feature(CPU_FTR_CAN_NAP))
+ power4_cpu_offline_powersave();
+ else {
+ HMT_low();
+ HMT_very_low();
+ }
+ }
+}
+#endif /* CONFIG_HOTPLUG_CPU */
+
+#endif /* CONFIG_PPC64 */
define_machine(powermac) {
.name = "PowerMac",
@@ -763,6 +746,6 @@
.phys_mem_access_prot = pci_phys_mem_access_prot,
#endif
#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC64)
- .cpu_die = generic_mach_cpu_die,
+ .cpu_die = pmac_cpu_die,
#endif
};
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index 6f32c4e..686ed82 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -24,7 +24,6 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
#include <linux/delay.h>
@@ -562,7 +561,7 @@
/* Look for the clock chip */
while ((cc = of_find_node_by_name(cc, "i2c-hwclock")) != NULL) {
p = of_get_parent(cc);
- ok = p && device_is_compatible(p, "uni-n-i2c");
+ ok = p && of_device_is_compatible(p, "uni-n-i2c");
of_node_put(p);
if (!ok)
continue;
@@ -575,11 +574,11 @@
continue;
switch (*reg) {
case 0xd2:
- if (device_is_compatible(cc,"pulsar-legacy-slewing")) {
+ if (of_device_is_compatible(cc,"pulsar-legacy-slewing")) {
pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
pmac_tb_pulsar_addr = 0xd2;
name = "Pulsar";
- } else if (device_is_compatible(cc, "cy28508")) {
+ } else if (of_device_is_compatible(cc, "cy28508")) {
pmac_tb_freeze = smp_core99_cypress_tb_freeze;
name = "Cypress";
}
@@ -900,7 +899,7 @@
cpu_dead[cpu] = 0;
}
-#endif
+#endif /* CONFIG_HOTPLUG_CPU && CONFIG_PP32 */
/* Core99 Macs (dual G4s and G5s) */
struct smp_ops_t core99_smp_ops = {
@@ -910,8 +909,16 @@
.setup_cpu = smp_core99_setup_cpu,
.give_timebase = smp_core99_give_timebase,
.take_timebase = smp_core99_take_timebase,
-#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)
+#if defined(CONFIG_HOTPLUG_CPU)
+# if defined(CONFIG_PPC32)
.cpu_disable = smp_core99_cpu_disable,
.cpu_die = smp_core99_cpu_die,
+# endif
+# if defined(CONFIG_PPC64)
+ .cpu_disable = generic_cpu_disable,
+ .cpu_die = generic_cpu_die,
+ /* intentionally do *NOT* assign cpu_enable,
+ * the generic code will use kick_cpu then! */
+# endif
#endif
};
diff --git a/arch/powerpc/platforms/ps3/htab.c b/arch/powerpc/platforms/ps3/htab.c
index ea60c45..a1409e4 100644
--- a/arch/powerpc/platforms/ps3/htab.c
+++ b/arch/powerpc/platforms/ps3/htab.c
@@ -273,7 +273,8 @@
result = lv1_map_htab(0, &htab_addr);
- htab = (hpte_t *)__ioremap(htab_addr, htab_size, PAGE_READONLY_X);
+ htab = (hpte_t *)__ioremap(htab_addr, htab_size,
+ pgprot_val(PAGE_READONLY_X));
DBG("%s:%d: lpar %016lxh, virt %016lxh\n", __func__, __LINE__,
htab_addr, (unsigned long)htab);
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
index 631c300..9da82c2 100644
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -89,7 +89,18 @@
static DEFINE_PER_CPU(struct ps3_private, ps3_private);
-int ps3_alloc_irq(enum ps3_cpu_binding cpu, unsigned long outlet,
+/**
+ * ps3_virq_setup - virq related setup.
+ * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
+ * serviced on.
+ * @outlet: The HV outlet from the various create outlet routines.
+ * @virq: The assigned Linux virq.
+ *
+ * Calls irq_create_mapping() to get a virq and sets the chip data to
+ * ps3_private data.
+ */
+
+int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
unsigned int *virq)
{
int result;
@@ -111,17 +122,6 @@
goto fail_create;
}
- /* Binds outlet to cpu + virq. */
-
- result = lv1_connect_irq_plug_ext(pd->node, pd->cpu, *virq, outlet, 0);
-
- if (result) {
- pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n",
- __func__, __LINE__, ps3_result(result));
- result = -EPERM;
- goto fail_connect;
- }
-
pr_debug("%s:%d: outlet %lu => cpu %u, virq %u\n", __func__, __LINE__,
outlet, cpu, *virq);
@@ -136,15 +136,87 @@
return result;
fail_set:
- lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, *virq);
-fail_connect:
irq_dispose_mapping(*virq);
fail_create:
return result;
}
-EXPORT_SYMBOL_GPL(ps3_alloc_irq);
-int ps3_free_irq(unsigned int virq)
+/**
+ * ps3_virq_destroy - virq related teardown.
+ * @virq: The assigned Linux virq.
+ *
+ * Clears chip data and calls irq_dispose_mapping() for the virq.
+ */
+
+int ps3_virq_destroy(unsigned int virq)
+{
+ const struct ps3_private *pd = get_irq_chip_data(virq);
+
+ pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__,
+ pd->node, pd->cpu, virq);
+
+ set_irq_chip_data(virq, NULL);
+ irq_dispose_mapping(virq);
+
+ pr_debug("%s:%d <-\n", __func__, __LINE__);
+ return 0;
+}
+
+/**
+ * ps3_irq_plug_setup - Generic outlet and virq related setup.
+ * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
+ * serviced on.
+ * @outlet: The HV outlet from the various create outlet routines.
+ * @virq: The assigned Linux virq.
+ *
+ * Sets up virq and connects the irq plug.
+ */
+
+int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
+ unsigned int *virq)
+{
+ int result;
+ struct ps3_private *pd;
+
+ result = ps3_virq_setup(cpu, outlet, virq);
+
+ if (result) {
+ pr_debug("%s:%d: ps3_virq_setup failed\n", __func__, __LINE__);
+ goto fail_setup;
+ }
+
+ pd = get_irq_chip_data(*virq);
+
+ /* Binds outlet to cpu + virq. */
+
+ result = lv1_connect_irq_plug_ext(pd->node, pd->cpu, *virq, outlet, 0);
+
+ if (result) {
+ pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n",
+ __func__, __LINE__, ps3_result(result));
+ result = -EPERM;
+ goto fail_connect;
+ }
+
+ return result;
+
+fail_connect:
+ ps3_virq_destroy(*virq);
+fail_setup:
+ return result;
+}
+EXPORT_SYMBOL_GPL(ps3_irq_plug_setup);
+
+/**
+ * ps3_irq_plug_destroy - Generic outlet and virq related teardown.
+ * @virq: The assigned Linux virq.
+ *
+ * Disconnects the irq plug and tears down virq.
+ * Do not call for system bus event interrupts setup with
+ * ps3_sb_event_receive_port_setup().
+ */
+
+int ps3_irq_plug_destroy(unsigned int virq)
{
int result;
const struct ps3_private *pd = get_irq_chip_data(virq);
@@ -158,72 +230,24 @@
pr_info("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n",
__func__, __LINE__, ps3_result(result));
- set_irq_chip_data(virq, NULL);
- irq_dispose_mapping(virq);
+ ps3_virq_destroy(virq);
+
return result;
}
-EXPORT_SYMBOL_GPL(ps3_free_irq);
+EXPORT_SYMBOL_GPL(ps3_irq_plug_destroy);
/**
- * ps3_alloc_io_irq - Assign a virq to a system bus device.
- * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
- * serviced on.
- * @interrupt_id: The device interrupt id read from the system repository.
- * @virq: The assigned Linux virq.
- *
- * An io irq represents a non-virtualized device interrupt. interrupt_id
- * coresponds to the interrupt number of the interrupt controller.
- */
-
-int ps3_alloc_io_irq(enum ps3_cpu_binding cpu, unsigned int interrupt_id,
- unsigned int *virq)
-{
- int result;
- unsigned long outlet;
-
- result = lv1_construct_io_irq_outlet(interrupt_id, &outlet);
-
- if (result) {
- pr_debug("%s:%d: lv1_construct_io_irq_outlet failed: %s\n",
- __func__, __LINE__, ps3_result(result));
- return result;
- }
-
- result = ps3_alloc_irq(cpu, outlet, virq);
- BUG_ON(result);
-
- return result;
-}
-EXPORT_SYMBOL_GPL(ps3_alloc_io_irq);
-
-int ps3_free_io_irq(unsigned int virq)
-{
- int result;
-
- result = lv1_destruct_io_irq_outlet(virq_to_hw(virq));
-
- if (result)
- pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n",
- __func__, __LINE__, ps3_result(result));
-
- ps3_free_irq(virq);
-
- return result;
-}
-EXPORT_SYMBOL_GPL(ps3_free_io_irq);
-
-/**
- * ps3_alloc_event_irq - Allocate a virq for use with a system event.
+ * ps3_event_receive_port_setup - Setup an event receive port.
* @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
* serviced on.
* @virq: The assigned Linux virq.
*
* The virq can be used with lv1_connect_interrupt_event_receive_port() to
- * arrange to receive events, or with ps3_send_event_locally() to signal
- * events.
+ * arrange to receive interrupts from system-bus devices, or with
+ * ps3_send_event_locally() to signal events.
*/
-int ps3_alloc_event_irq(enum ps3_cpu_binding cpu, unsigned int *virq)
+int ps3_event_receive_port_setup(enum ps3_cpu_binding cpu, unsigned int *virq)
{
int result;
unsigned long outlet;
@@ -237,17 +261,27 @@
return result;
}
- result = ps3_alloc_irq(cpu, outlet, virq);
+ result = ps3_irq_plug_setup(cpu, outlet, virq);
BUG_ON(result);
return result;
}
+EXPORT_SYMBOL_GPL(ps3_event_receive_port_setup);
-int ps3_free_event_irq(unsigned int virq)
+/**
+ * ps3_event_receive_port_destroy - Destroy an event receive port.
+ * @virq: The assigned Linux virq.
+ *
+ * Since ps3_event_receive_port_destroy destroys the receive port outlet,
+ * SB devices need to call disconnect_interrupt_event_receive_port() before
+ * this.
+ */
+
+int ps3_event_receive_port_destroy(unsigned int virq)
{
int result;
- pr_debug(" -> %s:%d\n", __func__, __LINE__);
+ pr_debug(" -> %s:%d virq: %u\n", __func__, __LINE__, virq);
result = lv1_destruct_event_receive_port(virq_to_hw(virq));
@@ -255,11 +289,17 @@
pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n",
__func__, __LINE__, ps3_result(result));
- ps3_free_irq(virq);
+ /* lv1_destruct_event_receive_port() destroys the IRQ plug,
+ * so don't call ps3_irq_plug_destroy() here.
+ */
+
+ result = ps3_virq_destroy(virq);
+ BUG_ON(result);
pr_debug(" <- %s:%d\n", __func__, __LINE__);
return result;
}
+EXPORT_SYMBOL_GPL(ps3_event_receive_port_destroy);
int ps3_send_event_locally(unsigned int virq)
{
@@ -267,7 +307,7 @@
}
/**
- * ps3_connect_event_irq - Assign a virq to a system bus device.
+ * ps3_sb_event_receive_port_setup - Setup a system bus event receive port.
* @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
* serviced on.
* @did: The HV device identifier read from the system repository.
@@ -278,13 +318,15 @@
* coresponds to the software interrupt number.
*/
-int ps3_connect_event_irq(enum ps3_cpu_binding cpu,
+int ps3_sb_event_receive_port_setup(enum ps3_cpu_binding cpu,
const struct ps3_device_id *did, unsigned int interrupt_id,
unsigned int *virq)
{
+ /* this should go in system-bus.c */
+
int result;
- result = ps3_alloc_event_irq(cpu, virq);
+ result = ps3_event_receive_port_setup(cpu, virq);
if (result)
return result;
@@ -296,7 +338,7 @@
pr_debug("%s:%d: lv1_connect_interrupt_event_receive_port"
" failed: %s\n", __func__, __LINE__,
ps3_result(result));
- ps3_free_event_irq(*virq);
+ ps3_event_receive_port_destroy(*virq);
*virq = NO_IRQ;
return result;
}
@@ -306,10 +348,13 @@
return 0;
}
+EXPORT_SYMBOL(ps3_sb_event_receive_port_setup);
-int ps3_disconnect_event_irq(const struct ps3_device_id *did,
+int ps3_sb_event_receive_port_destroy(const struct ps3_device_id *did,
unsigned int interrupt_id, unsigned int virq)
{
+ /* this should go in system-bus.c */
+
int result;
pr_debug(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__,
@@ -323,14 +368,65 @@
" failed: %s\n", __func__, __LINE__,
ps3_result(result));
- ps3_free_event_irq(virq);
+ result = ps3_event_receive_port_destroy(virq);
+ BUG_ON(result);
pr_debug(" <- %s:%d\n", __func__, __LINE__);
return result;
}
+EXPORT_SYMBOL(ps3_sb_event_receive_port_destroy);
/**
- * ps3_alloc_vuart_irq - Configure the system virtual uart virq.
+ * ps3_io_irq_setup - Setup a system bus io irq.
+ * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
+ * serviced on.
+ * @interrupt_id: The device interrupt id read from the system repository.
+ * @virq: The assigned Linux virq.
+ *
+ * An io irq represents a non-virtualized device interrupt. interrupt_id
+ * coresponds to the interrupt number of the interrupt controller.
+ */
+
+int ps3_io_irq_setup(enum ps3_cpu_binding cpu, unsigned int interrupt_id,
+ unsigned int *virq)
+{
+ int result;
+ unsigned long outlet;
+
+ result = lv1_construct_io_irq_outlet(interrupt_id, &outlet);
+
+ if (result) {
+ pr_debug("%s:%d: lv1_construct_io_irq_outlet failed: %s\n",
+ __func__, __LINE__, ps3_result(result));
+ return result;
+ }
+
+ result = ps3_irq_plug_setup(cpu, outlet, virq);
+ BUG_ON(result);
+
+ return result;
+}
+EXPORT_SYMBOL_GPL(ps3_io_irq_setup);
+
+int ps3_io_irq_destroy(unsigned int virq)
+{
+ int result;
+
+ result = lv1_destruct_io_irq_outlet(virq_to_hw(virq));
+
+ if (result)
+ pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n",
+ __func__, __LINE__, ps3_result(result));
+
+ result = ps3_irq_plug_destroy(virq);
+ BUG_ON(result);
+
+ return result;
+}
+EXPORT_SYMBOL_GPL(ps3_io_irq_destroy);
+
+/**
+ * ps3_vuart_irq_setup - Setup the system virtual uart virq.
* @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
* serviced on.
* @virt_addr_bmp: The caller supplied virtual uart interrupt bitmap.
@@ -340,7 +436,7 @@
* freeing the interrupt will return a wrong state error.
*/
-int ps3_alloc_vuart_irq(enum ps3_cpu_binding cpu, void* virt_addr_bmp,
+int ps3_vuart_irq_setup(enum ps3_cpu_binding cpu, void* virt_addr_bmp,
unsigned int *virq)
{
int result;
@@ -359,13 +455,13 @@
return result;
}
- result = ps3_alloc_irq(cpu, outlet, virq);
+ result = ps3_irq_plug_setup(cpu, outlet, virq);
BUG_ON(result);
return result;
}
-int ps3_free_vuart_irq(unsigned int virq)
+int ps3_vuart_irq_destroy(unsigned int virq)
{
int result;
@@ -377,13 +473,14 @@
return result;
}
- ps3_free_irq(virq);
+ result = ps3_irq_plug_destroy(virq);
+ BUG_ON(result);
return result;
}
/**
- * ps3_alloc_spe_irq - Configure an spe virq.
+ * ps3_spe_irq_setup - Setup an spe virq.
* @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
* serviced on.
* @spe_id: The spe_id returned from lv1_construct_logical_spe().
@@ -392,7 +489,7 @@
*
*/
-int ps3_alloc_spe_irq(enum ps3_cpu_binding cpu, unsigned long spe_id,
+int ps3_spe_irq_setup(enum ps3_cpu_binding cpu, unsigned long spe_id,
unsigned int class, unsigned int *virq)
{
int result;
@@ -408,15 +505,16 @@
return result;
}
- result = ps3_alloc_irq(cpu, outlet, virq);
+ result = ps3_irq_plug_setup(cpu, outlet, virq);
BUG_ON(result);
return result;
}
-int ps3_free_spe_irq(unsigned int virq)
+int ps3_spe_irq_destroy(unsigned int virq)
{
- ps3_free_irq(virq);
+ int result = ps3_irq_plug_destroy(virq);
+ BUG_ON(result);
return 0;
}
diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
index 2014d2b..f8a3e20 100644
--- a/arch/powerpc/platforms/ps3/mm.c
+++ b/arch/powerpc/platforms/ps3/mm.c
@@ -826,5 +826,4 @@
void ps3_mm_shutdown(void)
{
ps3_mm_region_destroy(&map.r1);
- map.total = map.rm.size;
}
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
index ac5df96..c989493 100644
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -137,6 +137,12 @@
#define prealloc_ps3fb_videomemory() do { } while (0)
#endif
+static int ps3_set_dabr(u64 dabr)
+{
+ enum {DABR_USER = 1, DABR_KERNEL = 2,};
+
+ return lv1_set_dabr(dabr, DABR_KERNEL | DABR_USER) ? -1 : 0;
+}
static void __init ps3_setup_arch(void)
{
@@ -234,6 +240,7 @@
.get_boot_time = ps3_get_boot_time,
.set_rtc_time = ps3_set_rtc_time,
.get_rtc_time = ps3_get_rtc_time,
+ .set_dabr = ps3_set_dabr,
.calibrate_decr = ps3_calibrate_decr,
.progress = ps3_progress,
.restart = ps3_restart,
diff --git a/arch/powerpc/platforms/ps3/smp.c b/arch/powerpc/platforms/ps3/smp.c
index 6fb8879..8729348 100644
--- a/arch/powerpc/platforms/ps3/smp.c
+++ b/arch/powerpc/platforms/ps3/smp.c
@@ -110,7 +110,7 @@
BUILD_BUG_ON(PPC_MSG_DEBUGGER_BREAK != 3);
for (i = 0; i < MSG_COUNT; i++) {
- result = ps3_alloc_event_irq(cpu, &virqs[i]);
+ result = ps3_event_receive_port_setup(cpu, &virqs[i]);
if (result)
continue;
@@ -134,11 +134,13 @@
int i;
DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu);
+
for (i = 0; i < MSG_COUNT; i++) {
- ps3_free_event_irq(virqs[i]);
free_irq(virqs[i], (void*)(long)i);
+ ps3_event_receive_port_destroy(virqs[i]);
virqs[i] = NO_IRQ;
}
+
DBG(" <- %s:%d: (%d)\n", __func__, __LINE__, cpu);
}
diff --git a/arch/powerpc/platforms/ps3/spu.c b/arch/powerpc/platforms/ps3/spu.c
index a397e4e..651437c 100644
--- a/arch/powerpc/platforms/ps3/spu.c
+++ b/arch/powerpc/platforms/ps3/spu.c
@@ -184,7 +184,7 @@
spu_pdata(spu)->shadow = __ioremap(
spu_pdata(spu)->shadow_addr, sizeof(struct spe_shadow),
- PAGE_READONLY | _PAGE_NO_CACHE | _PAGE_GUARDED);
+ pgprot_val(PAGE_READONLY) | _PAGE_NO_CACHE | _PAGE_GUARDED);
if (!spu_pdata(spu)->shadow) {
pr_debug("%s:%d: ioremap shadow failed\n", __func__, __LINE__);
goto fail_ioremap;
@@ -230,19 +230,19 @@
{
int result;
- result = ps3_alloc_spe_irq(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
+ result = ps3_spe_irq_setup(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
0, &spu->irqs[0]);
if (result)
goto fail_alloc_0;
- result = ps3_alloc_spe_irq(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
+ result = ps3_spe_irq_setup(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
1, &spu->irqs[1]);
if (result)
goto fail_alloc_1;
- result = ps3_alloc_spe_irq(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
+ result = ps3_spe_irq_setup(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
2, &spu->irqs[2]);
if (result)
@@ -251,9 +251,9 @@
return result;
fail_alloc_2:
- ps3_free_spe_irq(spu->irqs[1]);
+ ps3_spe_irq_destroy(spu->irqs[1]);
fail_alloc_1:
- ps3_free_spe_irq(spu->irqs[0]);
+ ps3_spe_irq_destroy(spu->irqs[0]);
fail_alloc_0:
spu->irqs[0] = spu->irqs[1] = spu->irqs[2] = NO_IRQ;
return result;
@@ -301,9 +301,9 @@
result = lv1_disable_logical_spe(spu_pdata(spu)->spe_id, 0);
BUG_ON(result);
- ps3_free_spe_irq(spu->irqs[2]);
- ps3_free_spe_irq(spu->irqs[1]);
- ps3_free_spe_irq(spu->irqs[0]);
+ ps3_spe_irq_destroy(spu->irqs[2]);
+ ps3_spe_irq_destroy(spu->irqs[1]);
+ ps3_spe_irq_destroy(spu->irqs[0]);
spu->irqs[0] = spu->irqs[1] = spu->irqs[2] = NO_IRQ;
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index 90235d5..ae1fc92 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -11,6 +11,7 @@
obj-$(CONFIG_EEH) += eeh.o eeh_cache.o eeh_driver.o eeh_event.o
obj-$(CONFIG_KEXEC) += kexec.o
obj-$(CONFIG_PCI) += pci.o pci_dlpar.o
+obj-$(CONFIG_PCI_MSI) += msi.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug-cpu.o
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 48fbd44..63e2306 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -580,6 +580,36 @@
}
/**
+ * pcibios_set_pcie_slot_reset - Set PCI-E reset state
+ * @dev: pci device struct
+ * @state: reset state to enter
+ *
+ * Return value:
+ * 0 if success
+ **/
+int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state)
+{
+ struct device_node *dn = pci_device_to_OF_node(dev);
+ struct pci_dn *pdn = PCI_DN(dn);
+
+ switch (state) {
+ case pcie_deassert_reset:
+ rtas_pci_slot_reset(pdn, 0);
+ break;
+ case pcie_hot_reset:
+ rtas_pci_slot_reset(pdn, 1);
+ break;
+ case pcie_warm_reset:
+ rtas_pci_slot_reset(pdn, 3);
+ break;
+ default:
+ return -EINVAL;
+ };
+
+ return 0;
+}
+
+/**
* rtas_set_slot_reset -- assert the pci #RST line for 1/4 second
* @pdn: pci device node to be reset.
*
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 66665c8..eec684a 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -504,6 +504,12 @@
break;
}
+ if (!pdn || !PCI_DN(pdn)) {
+ printk(KERN_WARNING "pci_dma_dev_setup_pSeriesLP: "
+ "no DMA window found for pci dev=%s dn=%s\n",
+ pci_name(dev), dn? dn->full_name : "<null>");
+ return;
+ }
DBG(" parent is %s\n", pdn->full_name);
/* Check for parent == NULL so we don't try to setup the empty EADS
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 3a70e8a..362dfbc 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -231,13 +231,13 @@
goto out;
vtermno = termno[0];
- if (device_is_compatible(stdout_node, "hvterm1")) {
+ if (of_device_is_compatible(stdout_node, "hvterm1")) {
udbg_putc = udbg_putcLP;
udbg_getc = udbg_getcLP;
udbg_getc_poll = udbg_getc_pollLP;
if (add_console)
add_preferred_console("hvc", termno[0] & 0xff, NULL);
- } else if (device_is_compatible(stdout_node, "hvterm-protocol")) {
+ } else if (of_device_is_compatible(stdout_node, "hvterm-protocol")) {
vtermno = termno[0];
udbg_putc = udbg_hvsi_putc;
udbg_getc = udbg_hvsi_getc;
diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c
new file mode 100644
index 0000000..6063ea2
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/msi.c
@@ -0,0 +1,270 @@
+/*
+ * Copyright 2006 Jake Moilanen <moilanen@austin.ibm.com>, IBM Corp.
+ * Copyright 2006-2007 Michael Ellerman, IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2 of the
+ * License.
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/irq.h>
+#include <linux/msi.h>
+
+#include <asm/rtas.h>
+#include <asm/hw_irq.h>
+#include <asm/ppc-pci.h>
+
+static int query_token, change_token;
+
+#define RTAS_QUERY_FN 0
+#define RTAS_CHANGE_FN 1
+#define RTAS_RESET_FN 2
+#define RTAS_CHANGE_MSI_FN 3
+#define RTAS_CHANGE_MSIX_FN 4
+
+static struct pci_dn *get_pdn(struct pci_dev *pdev)
+{
+ struct device_node *dn;
+ struct pci_dn *pdn;
+
+ dn = pci_device_to_OF_node(pdev);
+ if (!dn) {
+ dev_dbg(&pdev->dev, "rtas_msi: No OF device node\n");
+ return NULL;
+ }
+
+ pdn = PCI_DN(dn);
+ if (!pdn) {
+ dev_dbg(&pdev->dev, "rtas_msi: No PCI DN\n");
+ return NULL;
+ }
+
+ return pdn;
+}
+
+/* RTAS Helpers */
+
+static int rtas_change_msi(struct pci_dn *pdn, u32 func, u32 num_irqs)
+{
+ u32 addr, seq_num, rtas_ret[3];
+ unsigned long buid;
+ int rc;
+
+ addr = rtas_config_addr(pdn->busno, pdn->devfn, 0);
+ buid = pdn->phb->buid;
+
+ seq_num = 1;
+ do {
+ if (func == RTAS_CHANGE_MSI_FN || func == RTAS_CHANGE_MSIX_FN)
+ rc = rtas_call(change_token, 6, 4, rtas_ret, addr,
+ BUID_HI(buid), BUID_LO(buid),
+ func, num_irqs, seq_num);
+ else
+ rc = rtas_call(change_token, 6, 3, rtas_ret, addr,
+ BUID_HI(buid), BUID_LO(buid),
+ func, num_irqs, seq_num);
+
+ seq_num = rtas_ret[1];
+ } while (rtas_busy_delay(rc));
+
+ if (rc == 0) /* Success */
+ rc = rtas_ret[0];
+
+ pr_debug("rtas_msi: ibm,change_msi(func=%d,num=%d) = (%d)\n",
+ func, num_irqs, rc);
+
+ return rc;
+}
+
+static void rtas_disable_msi(struct pci_dev *pdev)
+{
+ struct pci_dn *pdn;
+
+ pdn = get_pdn(pdev);
+ if (!pdn)
+ return;
+
+ if (rtas_change_msi(pdn, RTAS_CHANGE_FN, 0) != 0)
+ pr_debug("rtas_msi: Setting MSIs to 0 failed!\n");
+}
+
+static int rtas_query_irq_number(struct pci_dn *pdn, int offset)
+{
+ u32 addr, rtas_ret[2];
+ unsigned long buid;
+ int rc;
+
+ addr = rtas_config_addr(pdn->busno, pdn->devfn, 0);
+ buid = pdn->phb->buid;
+
+ do {
+ rc = rtas_call(query_token, 4, 3, rtas_ret, addr,
+ BUID_HI(buid), BUID_LO(buid), offset);
+ } while (rtas_busy_delay(rc));
+
+ if (rc) {
+ pr_debug("rtas_msi: error (%d) querying source number\n", rc);
+ return rc;
+ }
+
+ return rtas_ret[0];
+}
+
+static void rtas_teardown_msi_irqs(struct pci_dev *pdev)
+{
+ struct msi_desc *entry;
+
+ list_for_each_entry(entry, &pdev->msi_list, list) {
+ if (entry->irq == NO_IRQ)
+ continue;
+
+ set_irq_msi(entry->irq, NULL);
+ irq_dispose_mapping(entry->irq);
+ }
+
+ rtas_disable_msi(pdev);
+}
+
+static int check_req_msi(struct pci_dev *pdev, int nvec)
+{
+ struct device_node *dn;
+ struct pci_dn *pdn;
+ const u32 *req_msi;
+
+ pdn = get_pdn(pdev);
+ if (!pdn)
+ return -ENODEV;
+
+ dn = pdn->node;
+
+ req_msi = of_get_property(dn, "ibm,req#msi", NULL);
+ if (!req_msi) {
+ pr_debug("rtas_msi: No ibm,req#msi on %s\n", dn->full_name);
+ return -ENOENT;
+ }
+
+ if (*req_msi < nvec) {
+ pr_debug("rtas_msi: ibm,req#msi requests < %d MSIs\n", nvec);
+ return -ENOSPC;
+ }
+
+ return 0;
+}
+
+static int rtas_msi_check_device(struct pci_dev *pdev, int nvec, int type)
+{
+ if (type == PCI_CAP_ID_MSIX)
+ pr_debug("rtas_msi: MSI-X untested, trying anyway.\n");
+
+ return check_req_msi(pdev, nvec);
+}
+
+static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
+{
+ struct pci_dn *pdn;
+ int hwirq, virq, i, rc;
+ struct msi_desc *entry;
+
+ pdn = get_pdn(pdev);
+ if (!pdn)
+ return -ENODEV;
+
+ /*
+ * Try the new more explicit firmware interface, if that fails fall
+ * back to the old interface. The old interface is known to never
+ * return MSI-Xs.
+ */
+ if (type == PCI_CAP_ID_MSI) {
+ rc = rtas_change_msi(pdn, RTAS_CHANGE_MSI_FN, nvec);
+
+ if (rc != nvec) {
+ pr_debug("rtas_msi: trying the old firmware call.\n");
+ rc = rtas_change_msi(pdn, RTAS_CHANGE_FN, nvec);
+ }
+ } else
+ rc = rtas_change_msi(pdn, RTAS_CHANGE_MSIX_FN, nvec);
+
+ if (rc != nvec) {
+ pr_debug("rtas_msi: rtas_change_msi() failed\n");
+
+ /*
+ * In case of an error it's not clear whether the device is
+ * left with MSI enabled or not, so we explicitly disable.
+ */
+ goto out_free;
+ }
+
+ i = 0;
+ list_for_each_entry(entry, &pdev->msi_list, list) {
+ hwirq = rtas_query_irq_number(pdn, i);
+ if (hwirq < 0) {
+ rc = hwirq;
+ pr_debug("rtas_msi: error (%d) getting hwirq\n", rc);
+ goto out_free;
+ }
+
+ virq = irq_create_mapping(NULL, hwirq);
+
+ if (virq == NO_IRQ) {
+ pr_debug("rtas_msi: Failed mapping hwirq %d\n", hwirq);
+ rc = -ENOSPC;
+ goto out_free;
+ }
+
+ dev_dbg(&pdev->dev, "rtas_msi: allocated virq %d\n", virq);
+ set_irq_msi(virq, entry);
+ unmask_msi_irq(virq);
+ }
+
+ return 0;
+
+ out_free:
+ rtas_teardown_msi_irqs(pdev);
+ return rc;
+}
+
+static void rtas_msi_pci_irq_fixup(struct pci_dev *pdev)
+{
+ /* No LSI -> leave MSIs (if any) configured */
+ if (pdev->irq == NO_IRQ) {
+ dev_dbg(&pdev->dev, "rtas_msi: no LSI, nothing to do.\n");
+ return;
+ }
+
+ /* No MSI -> MSIs can't have been assigned by fw, leave LSI */
+ if (check_req_msi(pdev, 1)) {
+ dev_dbg(&pdev->dev, "rtas_msi: no req#msi, nothing to do.\n");
+ return;
+ }
+
+ dev_dbg(&pdev->dev, "rtas_msi: disabling existing MSI.\n");
+ rtas_disable_msi(pdev);
+}
+
+static int rtas_msi_init(void)
+{
+ query_token = rtas_token("ibm,query-interrupt-source-number");
+ change_token = rtas_token("ibm,change-msi");
+
+ if ((query_token == RTAS_UNKNOWN_SERVICE) ||
+ (change_token == RTAS_UNKNOWN_SERVICE)) {
+ pr_debug("rtas_msi: no RTAS tokens, no MSI support.\n");
+ return -1;
+ }
+
+ pr_debug("rtas_msi: Registering RTAS MSI callbacks.\n");
+
+ WARN_ON(ppc_md.setup_msi_irqs);
+ ppc_md.setup_msi_irqs = rtas_setup_msi_irqs;
+ ppc_md.teardown_msi_irqs = rtas_teardown_msi_irqs;
+ ppc_md.msi_check_device = rtas_msi_check_device;
+
+ WARN_ON(ppc_md.pci_irq_fixup);
+ ppc_md.pci_irq_fixup = rtas_msi_pci_irq_fixup;
+
+ return 0;
+}
+arch_initcall(rtas_msi_init);
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c
index fdc1a36..ffaf6c5 100644
--- a/arch/powerpc/platforms/pseries/pci_dlpar.c
+++ b/arch/powerpc/platforms/pseries/pci_dlpar.c
@@ -79,6 +79,7 @@
pci_remove_bus_device(dev);
}
}
+EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices);
/* Must be called before pci_bus_add_devices */
void
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 33eec28..470db6e 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -168,7 +168,7 @@
/* Look for cascade */
for_each_node_by_type(np, "interrupt-controller")
- if (device_is_compatible(np, "chrp,iic")) {
+ if (of_device_is_compatible(np, "chrp,iic")) {
cascade = np;
break;
}
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 896cbf3..b854e7f 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -477,7 +477,7 @@
* like vdevices, events, etc... The trick we use here is to match
* everything here except the legacy 8259 which is compatible "chrp,iic"
*/
- return !device_is_compatible(node, "chrp,iic");
+ return !of_device_is_compatible(node, "chrp,iic");
}
static int xics_host_map_direct(struct irq_host *h, unsigned int virq,
@@ -618,7 +618,7 @@
unsigned long intack = 0;
for_each_node_by_type(np, "interrupt-controller")
- if (device_is_compatible(np, "chrp,iic")) {
+ if (of_device_is_compatible(np, "chrp,iic")) {
found = np;
break;
}
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index e96ca96..9ce775c 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -2,7 +2,9 @@
EXTRA_CFLAGS += -mno-minimal-toc
endif
-obj-$(CONFIG_MPIC) += mpic.o
+mpic-msi-obj-$(CONFIG_PCI_MSI) += mpic_msi.o mpic_u3msi.o
+obj-$(CONFIG_MPIC) += mpic.o $(mpic-msi-obj-y)
+
obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o
obj-$(CONFIG_PPC_MPC106) += grackle.o
obj-$(CONFIG_PPC_DCR) += dcr.o
@@ -26,7 +28,6 @@
# Temporary hack until we have migrated to asm-powerpc
ifeq ($(ARCH),powerpc)
-obj-$(CONFIG_MTD) += rom.o
obj-$(CONFIG_CPM2) += cpm2_common.o cpm2_pic.o
obj-$(CONFIG_8xx) += mpc8xx_pic.o commproc.o
obj-$(CONFIG_UCODE_PATCH) += micropatch.o
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c
index 336186d..a1d2042 100644
--- a/arch/powerpc/sysdev/dart_iommu.c
+++ b/arch/powerpc/sysdev/dart_iommu.c
@@ -36,6 +36,7 @@
#include <linux/pci.h>
#include <linux/dma-mapping.h>
#include <linux/vmalloc.h>
+#include <linux/suspend.h>
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/iommu.h>
@@ -54,6 +55,9 @@
/* Virtual base address of the DART table */
static u32 *dart_vbase;
+#ifdef CONFIG_PM
+static u32 *dart_copy;
+#endif
/* Mapped base address for the dart */
static unsigned int __iomem *dart;
@@ -346,6 +350,48 @@
set_pci_dma_ops(&dma_direct_ops);
}
+#ifdef CONFIG_PM
+static void iommu_dart_save(void)
+{
+ memcpy(dart_copy, dart_vbase, 2*1024*1024);
+}
+
+static void iommu_dart_restore(void)
+{
+ memcpy(dart_vbase, dart_copy, 2*1024*1024);
+ dart_tlb_invalidate_all();
+}
+
+static int __init iommu_init_late_dart(void)
+{
+ unsigned long tbasepfn;
+ struct page *p;
+
+ /* if no dart table exists then we won't need to save it
+ * and the area has also not been reserved */
+ if (!dart_tablebase)
+ return 0;
+
+ tbasepfn = __pa(dart_tablebase) >> PAGE_SHIFT;
+ register_nosave_region_late(tbasepfn,
+ tbasepfn + ((1<<24) >> PAGE_SHIFT));
+
+ /* For suspend we need to copy the dart contents because
+ * it is not part of the regular mapping (see above) and
+ * thus not saved automatically. The memory for this copy
+ * must be allocated early because we need 2 MB. */
+ p = alloc_pages(GFP_KERNEL, 21 - PAGE_SHIFT);
+ BUG_ON(!p);
+ dart_copy = page_address(p);
+
+ ppc_md.iommu_save = iommu_dart_save;
+ ppc_md.iommu_restore = iommu_dart_restore;
+
+ return 0;
+}
+
+late_initcall(iommu_init_late_dart);
+#endif
void __init alloc_dart_table(void)
{
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 0b84b7c..4fd2bec 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -36,6 +36,8 @@
#include <asm/mpic.h>
#include <asm/smp.h>
+#include "mpic.h"
+
#ifdef DEBUG
#define DBG(fmt...) printk(fmt)
#else
@@ -354,6 +356,12 @@
tmp |= 0x22;
writel(tmp, fixup->base + 4);
spin_unlock_irqrestore(&mpic->fixup_lock, flags);
+
+#ifdef CONFIG_PM
+ /* use the lowest bit inverted to the actual HW,
+ * set if this fixup was enabled, clear otherwise */
+ mpic->save_data[source].fixup_data = tmp | 1;
+#endif
}
static void mpic_shutdown_ht_interrupt(struct mpic *mpic, unsigned int source,
@@ -375,8 +383,58 @@
tmp |= 1;
writel(tmp, fixup->base + 4);
spin_unlock_irqrestore(&mpic->fixup_lock, flags);
+
+#ifdef CONFIG_PM
+ /* use the lowest bit inverted to the actual HW,
+ * set if this fixup was enabled, clear otherwise */
+ mpic->save_data[source].fixup_data = tmp & ~1;
+#endif
}
+#ifdef CONFIG_PCI_MSI
+static void __init mpic_scan_ht_msi(struct mpic *mpic, u8 __iomem *devbase,
+ unsigned int devfn)
+{
+ u8 __iomem *base;
+ u8 pos, flags;
+ u64 addr = 0;
+
+ for (pos = readb(devbase + PCI_CAPABILITY_LIST); pos != 0;
+ pos = readb(devbase + pos + PCI_CAP_LIST_NEXT)) {
+ u8 id = readb(devbase + pos + PCI_CAP_LIST_ID);
+ if (id == PCI_CAP_ID_HT) {
+ id = readb(devbase + pos + 3);
+ if ((id & HT_5BIT_CAP_MASK) == HT_CAPTYPE_MSI_MAPPING)
+ break;
+ }
+ }
+
+ if (pos == 0)
+ return;
+
+ base = devbase + pos;
+
+ flags = readb(base + HT_MSI_FLAGS);
+ if (!(flags & HT_MSI_FLAGS_FIXED)) {
+ addr = readl(base + HT_MSI_ADDR_LO) & HT_MSI_ADDR_LO_MASK;
+ addr = addr | ((u64)readl(base + HT_MSI_ADDR_HI) << 32);
+ }
+
+ printk(KERN_DEBUG "mpic: - HT:%02x.%x %s MSI mapping found @ 0x%lx\n",
+ PCI_SLOT(devfn), PCI_FUNC(devfn),
+ flags & HT_MSI_FLAGS_ENABLE ? "enabled" : "disabled", addr);
+
+ if (!(flags & HT_MSI_FLAGS_ENABLE))
+ writeb(flags | HT_MSI_FLAGS_ENABLE, base + HT_MSI_FLAGS);
+}
+#else
+static void __init mpic_scan_ht_msi(struct mpic *mpic, u8 __iomem *devbase,
+ unsigned int devfn)
+{
+ return;
+}
+#endif
+
static void __init mpic_scan_ht_pic(struct mpic *mpic, u8 __iomem *devbase,
unsigned int devfn, u32 vdid)
{
@@ -468,6 +526,7 @@
goto next;
mpic_scan_ht_pic(mpic, devbase, devfn, l);
+ mpic_scan_ht_msi(mpic, devbase, devfn);
next:
/* next device, if function 0 */
@@ -559,7 +618,7 @@
*/
-static void mpic_unmask_irq(unsigned int irq)
+void mpic_unmask_irq(unsigned int irq)
{
unsigned int loops = 100000;
struct mpic *mpic = mpic_from_irq(irq);
@@ -579,7 +638,7 @@
} while(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK);
}
-static void mpic_mask_irq(unsigned int irq)
+void mpic_mask_irq(unsigned int irq)
{
unsigned int loops = 100000;
struct mpic *mpic = mpic_from_irq(irq);
@@ -600,7 +659,7 @@
} while(!(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK));
}
-static void mpic_end_irq(unsigned int irq)
+void mpic_end_irq(unsigned int irq)
{
struct mpic *mpic = mpic_from_irq(irq);
@@ -733,7 +792,7 @@
}
}
-static int mpic_set_irq_type(unsigned int virq, unsigned int flow_type)
+int mpic_set_irq_type(unsigned int virq, unsigned int flow_type)
{
struct mpic *mpic = mpic_from_irq(virq);
unsigned int src = mpic_irq_to_hw(virq);
@@ -834,6 +893,8 @@
if (hw >= mpic->irq_count)
return -EINVAL;
+ mpic_msi_reserve_hwirq(mpic, hw);
+
/* Default chip */
chip = &mpic->hc_irq;
@@ -1142,8 +1203,10 @@
/* Do the HT PIC fixups on U3 broken mpic */
DBG("MPIC flags: %x\n", mpic->flags);
- if ((mpic->flags & MPIC_U3_HT_IRQS) && (mpic->flags & MPIC_PRIMARY))
- mpic_scan_ht_pics(mpic);
+ if ((mpic->flags & MPIC_U3_HT_IRQS) && (mpic->flags & MPIC_PRIMARY)) {
+ mpic_scan_ht_pics(mpic);
+ mpic_u3msi_init(mpic);
+ }
for (i = 0; i < mpic->num_sources; i++) {
/* start with vector = source number, and masked */
@@ -1167,6 +1230,12 @@
/* Set current processor priority to 0 */
mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0);
+
+#ifdef CONFIG_PM
+ /* allocate memory to save mpic state */
+ mpic->save_data = alloc_bootmem(mpic->num_sources * sizeof(struct mpic_irq_save));
+ BUG_ON(mpic->save_data == NULL);
+#endif
}
void __init mpic_set_clk_ratio(struct mpic *mpic, u32 clock_ratio)
@@ -1333,8 +1402,11 @@
#ifdef DEBUG_LOW
DBG("%s: get_one_irq(): %d\n", mpic->name, src);
#endif
- if (unlikely(src == mpic->spurious_vec))
+ if (unlikely(src == mpic->spurious_vec)) {
+ if (mpic->flags & MPIC_SPV_EOI)
+ mpic_eoi(mpic);
return NO_IRQ;
+ }
return irq_linear_revmap(mpic->irqhost, src);
}
@@ -1417,3 +1489,79 @@
mpic_setup_this_cpu();
}
#endif /* CONFIG_SMP */
+
+#ifdef CONFIG_PM
+static int mpic_suspend(struct sys_device *dev, pm_message_t state)
+{
+ struct mpic *mpic = container_of(dev, struct mpic, sysdev);
+ int i;
+
+ for (i = 0; i < mpic->num_sources; i++) {
+ mpic->save_data[i].vecprio =
+ mpic_irq_read(i, MPIC_INFO(IRQ_VECTOR_PRI));
+ mpic->save_data[i].dest =
+ mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION));
+ }
+
+ return 0;
+}
+
+static int mpic_resume(struct sys_device *dev)
+{
+ struct mpic *mpic = container_of(dev, struct mpic, sysdev);
+ int i;
+
+ for (i = 0; i < mpic->num_sources; i++) {
+ mpic_irq_write(i, MPIC_INFO(IRQ_VECTOR_PRI),
+ mpic->save_data[i].vecprio);
+ mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION),
+ mpic->save_data[i].dest);
+
+#ifdef CONFIG_MPIC_U3_HT_IRQS
+ {
+ struct mpic_irq_fixup *fixup = &mpic->fixups[i];
+
+ if (fixup->base) {
+ /* we use the lowest bit in an inverted meaning */
+ if ((mpic->save_data[i].fixup_data & 1) == 0)
+ continue;
+
+ /* Enable and configure */
+ writeb(0x10 + 2 * fixup->index, fixup->base + 2);
+
+ writel(mpic->save_data[i].fixup_data & ~1,
+ fixup->base + 4);
+ }
+ }
+#endif
+ } /* end for loop */
+
+ return 0;
+}
+#endif
+
+static struct sysdev_class mpic_sysclass = {
+#ifdef CONFIG_PM
+ .resume = mpic_resume,
+ .suspend = mpic_suspend,
+#endif
+ set_kset_name("mpic"),
+};
+
+static int mpic_init_sys(void)
+{
+ struct mpic *mpic = mpics;
+ int error, id = 0;
+
+ error = sysdev_class_register(&mpic_sysclass);
+
+ while (mpic && !error) {
+ mpic->sysdev.cls = &mpic_sysclass;
+ mpic->sysdev.id = id++;
+ error = sysdev_register(&mpic->sysdev);
+ mpic = mpic->next;
+ }
+ return error;
+}
+
+device_initcall(mpic_init_sys);
diff --git a/arch/powerpc/sysdev/mpic.h b/arch/powerpc/sysdev/mpic.h
new file mode 100644
index 0000000..3a1c3d2
--- /dev/null
+++ b/arch/powerpc/sysdev/mpic.h
@@ -0,0 +1,38 @@
+#ifndef _POWERPC_SYSDEV_MPIC_H
+#define _POWERPC_SYSDEV_MPIC_H
+
+/*
+ * Copyright 2006-2007, Michael Ellerman, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2 of the
+ * License.
+ *
+ */
+
+#ifdef CONFIG_PCI_MSI
+extern void mpic_msi_reserve_hwirq(struct mpic *mpic, irq_hw_number_t hwirq);
+extern int mpic_msi_init_allocator(struct mpic *mpic);
+extern irq_hw_number_t mpic_msi_alloc_hwirqs(struct mpic *mpic, int num);
+extern void mpic_msi_free_hwirqs(struct mpic *mpic, int offset, int num);
+extern int mpic_u3msi_init(struct mpic *mpic);
+#else
+static inline void mpic_msi_reserve_hwirq(struct mpic *mpic,
+ irq_hw_number_t hwirq)
+{
+ return;
+}
+
+static inline int mpic_u3msi_init(struct mpic *mpic)
+{
+ return -1;
+}
+#endif
+
+extern int mpic_set_irq_type(unsigned int virq, unsigned int flow_type);
+extern void mpic_end_irq(unsigned int irq);
+extern void mpic_mask_irq(unsigned int irq);
+extern void mpic_unmask_irq(unsigned int irq);
+
+#endif /* _POWERPC_SYSDEV_MPIC_H */
diff --git a/arch/powerpc/sysdev/mpic_msi.c b/arch/powerpc/sysdev/mpic_msi.c
new file mode 100644
index 0000000..b076793
--- /dev/null
+++ b/arch/powerpc/sysdev/mpic_msi.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2006-2007, Michael Ellerman, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2 of the
+ * License.
+ *
+ */
+
+#include <linux/irq.h>
+#include <linux/bootmem.h>
+#include <linux/bitmap.h>
+#include <linux/msi.h>
+#include <asm/mpic.h>
+#include <asm/prom.h>
+#include <asm/hw_irq.h>
+#include <asm/ppc-pci.h>
+
+
+static void __mpic_msi_reserve_hwirq(struct mpic *mpic, irq_hw_number_t hwirq)
+{
+ pr_debug("mpic: reserving hwirq 0x%lx\n", hwirq);
+ bitmap_allocate_region(mpic->hwirq_bitmap, hwirq, 0);
+}
+
+void mpic_msi_reserve_hwirq(struct mpic *mpic, irq_hw_number_t hwirq)
+{
+ unsigned long flags;
+
+ /* The mpic calls this even when there is no allocator setup */
+ if (!mpic->hwirq_bitmap)
+ return;
+
+ spin_lock_irqsave(&mpic->bitmap_lock, flags);
+ __mpic_msi_reserve_hwirq(mpic, hwirq);
+ spin_unlock_irqrestore(&mpic->bitmap_lock, flags);
+}
+
+irq_hw_number_t mpic_msi_alloc_hwirqs(struct mpic *mpic, int num)
+{
+ unsigned long flags;
+ int offset, order = get_count_order(num);
+
+ spin_lock_irqsave(&mpic->bitmap_lock, flags);
+ /*
+ * This is fast, but stricter than we need. We might want to add
+ * a fallback routine which does a linear search with no alignment.
+ */
+ offset = bitmap_find_free_region(mpic->hwirq_bitmap, mpic->irq_count,
+ order);
+ spin_unlock_irqrestore(&mpic->bitmap_lock, flags);
+
+ pr_debug("mpic: allocated 0x%x (2^%d) at offset 0x%x\n",
+ num, order, offset);
+
+ return offset;
+}
+
+void mpic_msi_free_hwirqs(struct mpic *mpic, int offset, int num)
+{
+ unsigned long flags;
+ int order = get_count_order(num);
+
+ pr_debug("mpic: freeing 0x%x (2^%d) at offset 0x%x\n",
+ num, order, offset);
+
+ spin_lock_irqsave(&mpic->bitmap_lock, flags);
+ bitmap_release_region(mpic->hwirq_bitmap, offset, order);
+ spin_unlock_irqrestore(&mpic->bitmap_lock, flags);
+}
+
+#ifdef CONFIG_MPIC_U3_HT_IRQS
+static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic)
+{
+ irq_hw_number_t hwirq;
+ struct irq_host_ops *ops = mpic->irqhost->ops;
+ struct device_node *np;
+ int flags, index, i;
+ struct of_irq oirq;
+
+ pr_debug("mpic: found U3, guessing msi allocator setup\n");
+
+ /* Reserve source numbers we know are reserved in the HW */
+ for (i = 0; i < 8; i++)
+ __mpic_msi_reserve_hwirq(mpic, i);
+
+ for (i = 42; i < 46; i++)
+ __mpic_msi_reserve_hwirq(mpic, i);
+
+ for (i = 100; i < 105; i++)
+ __mpic_msi_reserve_hwirq(mpic, i);
+
+ np = NULL;
+ while ((np = of_find_all_nodes(np))) {
+ pr_debug("mpic: mapping hwirqs for %s\n", np->full_name);
+
+ index = 0;
+ while (of_irq_map_one(np, index++, &oirq) == 0) {
+ ops->xlate(mpic->irqhost, NULL, oirq.specifier,
+ oirq.size, &hwirq, &flags);
+ __mpic_msi_reserve_hwirq(mpic, hwirq);
+ }
+ }
+
+ return 0;
+}
+#else
+static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic)
+{
+ return -1;
+}
+#endif
+
+static int mpic_msi_reserve_dt_hwirqs(struct mpic *mpic)
+{
+ int i, len;
+ const u32 *p;
+
+ p = of_get_property(mpic->of_node, "msi-available-ranges", &len);
+ if (!p) {
+ pr_debug("mpic: no msi-available-ranges property found on %s\n",
+ mpic->of_node->full_name);
+ return -ENODEV;
+ }
+
+ if (len % 8 != 0) {
+ printk(KERN_WARNING "mpic: Malformed msi-available-ranges "
+ "property on %s\n", mpic->of_node->full_name);
+ return -EINVAL;
+ }
+
+ bitmap_allocate_region(mpic->hwirq_bitmap, 0,
+ get_count_order(mpic->irq_count));
+
+ /* Format is: (<u32 start> <u32 count>)+ */
+ len /= sizeof(u32);
+ for (i = 0; i < len / 2; i++, p += 2)
+ mpic_msi_free_hwirqs(mpic, *p, *(p + 1));
+
+ return 0;
+}
+
+int mpic_msi_init_allocator(struct mpic *mpic)
+{
+ int rc, size;
+
+ BUG_ON(mpic->hwirq_bitmap);
+ spin_lock_init(&mpic->bitmap_lock);
+
+ size = BITS_TO_LONGS(mpic->irq_count) * sizeof(long);
+ pr_debug("mpic: allocator bitmap size is 0x%x bytes\n", size);
+
+ if (mem_init_done)
+ mpic->hwirq_bitmap = kmalloc(size, GFP_KERNEL);
+ else
+ mpic->hwirq_bitmap = alloc_bootmem(size);
+
+ if (!mpic->hwirq_bitmap) {
+ pr_debug("mpic: ENOMEM allocating allocator bitmap!\n");
+ return -ENOMEM;
+ }
+
+ memset(mpic->hwirq_bitmap, 0, size);
+
+ rc = mpic_msi_reserve_dt_hwirqs(mpic);
+ if (rc) {
+ if (mpic->flags & MPIC_U3_HT_IRQS)
+ rc = mpic_msi_reserve_u3_hwirqs(mpic);
+
+ if (rc)
+ goto out_free;
+ }
+
+ return 0;
+
+ out_free:
+ if (mem_init_done)
+ kfree(mpic->hwirq_bitmap);
+
+ mpic->hwirq_bitmap = NULL;
+ return rc;
+}
diff --git a/arch/powerpc/sysdev/mpic_u3msi.c b/arch/powerpc/sysdev/mpic_u3msi.c
new file mode 100644
index 0000000..305b864
--- /dev/null
+++ b/arch/powerpc/sysdev/mpic_u3msi.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2006, Segher Boessenkool, IBM Corporation.
+ * Copyright 2006-2007, Michael Ellerman, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2 of the
+ * License.
+ *
+ */
+
+#include <linux/irq.h>
+#include <linux/bootmem.h>
+#include <linux/msi.h>
+#include <asm/mpic.h>
+#include <asm/prom.h>
+#include <asm/hw_irq.h>
+#include <asm/ppc-pci.h>
+
+#include "mpic.h"
+
+/* A bit ugly, can we get this from the pci_dev somehow? */
+static struct mpic *msi_mpic;
+
+static void mpic_u3msi_mask_irq(unsigned int irq)
+{
+ mask_msi_irq(irq);
+ mpic_mask_irq(irq);
+}
+
+static void mpic_u3msi_unmask_irq(unsigned int irq)
+{
+ mpic_unmask_irq(irq);
+ unmask_msi_irq(irq);
+}
+
+static struct irq_chip mpic_u3msi_chip = {
+ .shutdown = mpic_u3msi_mask_irq,
+ .mask = mpic_u3msi_mask_irq,
+ .unmask = mpic_u3msi_unmask_irq,
+ .eoi = mpic_end_irq,
+ .set_type = mpic_set_irq_type,
+ .typename = "MPIC-U3MSI",
+};
+
+static u64 read_ht_magic_addr(struct pci_dev *pdev, unsigned int pos)
+{
+ u8 flags;
+ u32 tmp;
+ u64 addr;
+
+ pci_read_config_byte(pdev, pos + HT_MSI_FLAGS, &flags);
+
+ if (flags & HT_MSI_FLAGS_FIXED)
+ return HT_MSI_FIXED_ADDR;
+
+ pci_read_config_dword(pdev, pos + HT_MSI_ADDR_LO, &tmp);
+ addr = tmp & HT_MSI_ADDR_LO_MASK;
+ pci_read_config_dword(pdev, pos + HT_MSI_ADDR_HI, &tmp);
+ addr = addr | ((u64)tmp << 32);
+
+ return addr;
+}
+
+static u64 find_ht_magic_addr(struct pci_dev *pdev)
+{
+ struct pci_bus *bus;
+ unsigned int pos;
+
+ for (bus = pdev->bus; bus; bus = bus->parent) {
+ pos = pci_find_ht_capability(bus->self, HT_CAPTYPE_MSI_MAPPING);
+ if (pos)
+ return read_ht_magic_addr(bus->self, pos);
+ }
+
+ return 0;
+}
+
+static int u3msi_msi_check_device(struct pci_dev *pdev, int nvec, int type)
+{
+ if (type == PCI_CAP_ID_MSIX)
+ pr_debug("u3msi: MSI-X untested, trying anyway.\n");
+
+ /* If we can't find a magic address then MSI ain't gonna work */
+ if (find_ht_magic_addr(pdev) == 0) {
+ pr_debug("u3msi: no magic address found for %s\n",
+ pci_name(pdev));
+ return -ENXIO;
+ }
+
+ return 0;
+}
+
+static void u3msi_teardown_msi_irqs(struct pci_dev *pdev)
+{
+ struct msi_desc *entry;
+
+ list_for_each_entry(entry, &pdev->msi_list, list) {
+ if (entry->irq == NO_IRQ)
+ continue;
+
+ set_irq_msi(entry->irq, NULL);
+ mpic_msi_free_hwirqs(msi_mpic, virq_to_hw(entry->irq), 1);
+ irq_dispose_mapping(entry->irq);
+ }
+
+ return;
+}
+
+static void u3msi_compose_msi_msg(struct pci_dev *pdev, int virq,
+ struct msi_msg *msg)
+{
+ u64 addr;
+
+ addr = find_ht_magic_addr(pdev);
+ msg->address_lo = addr & 0xFFFFFFFF;
+ msg->address_hi = addr >> 32;
+ msg->data = virq_to_hw(virq);
+
+ pr_debug("u3msi: allocated virq 0x%x (hw 0x%lx) at address 0x%lx\n",
+ virq, virq_to_hw(virq), addr);
+}
+
+static int u3msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
+{
+ irq_hw_number_t hwirq;
+ int rc;
+ unsigned int virq;
+ struct msi_desc *entry;
+ struct msi_msg msg;
+
+ list_for_each_entry(entry, &pdev->msi_list, list) {
+ hwirq = mpic_msi_alloc_hwirqs(msi_mpic, 1);
+ if (hwirq < 0) {
+ rc = hwirq;
+ pr_debug("u3msi: failed allocating hwirq\n");
+ goto out_free;
+ }
+
+ virq = irq_create_mapping(msi_mpic->irqhost, hwirq);
+ if (virq == NO_IRQ) {
+ pr_debug("u3msi: failed mapping hwirq 0x%lx\n", hwirq);
+ mpic_msi_free_hwirqs(msi_mpic, hwirq, 1);
+ rc = -ENOSPC;
+ goto out_free;
+ }
+
+ set_irq_msi(virq, entry);
+ set_irq_chip(virq, &mpic_u3msi_chip);
+ set_irq_type(virq, IRQ_TYPE_EDGE_RISING);
+
+ u3msi_compose_msi_msg(pdev, virq, &msg);
+ write_msi_msg(virq, &msg);
+
+ hwirq++;
+ }
+
+ return 0;
+
+ out_free:
+ u3msi_teardown_msi_irqs(pdev);
+ return rc;
+}
+
+int mpic_u3msi_init(struct mpic *mpic)
+{
+ int rc;
+
+ rc = mpic_msi_init_allocator(mpic);
+ if (rc) {
+ pr_debug("u3msi: Error allocating bitmap!\n");
+ return rc;
+ }
+
+ pr_debug("u3msi: Registering MPIC U3 MSI callbacks.\n");
+
+ BUG_ON(msi_mpic);
+ msi_mpic = mpic;
+
+ WARN_ON(ppc_md.setup_msi_irqs);
+ ppc_md.setup_msi_irqs = u3msi_setup_msi_irqs;
+ ppc_md.teardown_msi_irqs = u3msi_teardown_msi_irqs;
+ ppc_md.msi_check_device = u3msi_msi_check_device;
+
+ return 0;
+}
diff --git a/arch/powerpc/sysdev/rom.c b/arch/powerpc/sysdev/rom.c
deleted file mode 100644
index c855a3b..0000000
--- a/arch/powerpc/sysdev/rom.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * ROM device registration
- *
- * (C) 2006 MontaVista Software, Inc. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-
-#include <linux/kernel.h>
-#include <asm/of_device.h>
-#include <asm/of_platform.h>
-
-static int __init powerpc_flash_init(void)
-{
- struct device_node *node = NULL;
-
- /*
- * Register all the devices which type is "rom"
- */
- while ((node = of_find_node_by_type(node, "rom")) != NULL) {
- if (node->name == NULL) {
- printk(KERN_WARNING "powerpc_flash_init: found 'rom' "
- "device, but with no name, skipping...\n");
- continue;
- }
- of_platform_device_create(node, node->name, NULL);
- }
- return 0;
-}
-
-arch_initcall(powerpc_flash_init);
diff --git a/arch/powerpc/sysdev/tsi108_dev.c b/arch/powerpc/sysdev/tsi108_dev.c
index 337039e..7d3b09b 100644
--- a/arch/powerpc/sysdev/tsi108_dev.c
+++ b/arch/powerpc/sysdev/tsi108_dev.c
@@ -107,8 +107,9 @@
goto err;
}
- mac_addr = of_get_property(np, "address", NULL);
- memcpy(tsi_eth_data.mac_addr, mac_addr, 6);
+ mac_addr = of_get_mac_address(np);
+ if (mac_addr)
+ memcpy(tsi_eth_data.mac_addr, mac_addr, 6);
ph = of_get_property(np, "phy-handle", NULL);
phy = of_find_node_by_phandle(*ph);
@@ -129,6 +130,8 @@
tsi_eth_data.phyregs = res.start;
tsi_eth_data.phy = *phy_id;
tsi_eth_data.irq_num = irq_of_parse_and_map(np, 0);
+ if (of_device_is_compatible(phy, "bcm54xx"))
+ tsi_eth_data.phy_type = TSI108_PHY_BCM54XX;
of_node_put(phy);
ret =
platform_device_add_data(tsi_eth_dev, &tsi_eth_data,
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c
index 58b9e7f..2153163 100644
--- a/arch/powerpc/sysdev/tsi108_pci.c
+++ b/arch/powerpc/sysdev/tsi108_pci.c
@@ -35,6 +35,7 @@
#include <asm/machdep.h>
#include <asm/pci-bridge.h>
#include <asm/tsi108.h>
+#include <asm/tsi108_pci.h>
#include <asm/tsi108_irq.h>
#include <asm/prom.h>
@@ -49,6 +50,7 @@
((((bus)<<16) | ((devfunc)<<8) | (offset & 0xfc)) + tsi108_pci_cfg_base)
u32 tsi108_pci_cfg_base;
+static u32 tsi108_pci_cfg_phys;
u32 tsi108_csr_vir_base;
static struct device_node *pci_irq_node;
static struct irq_host *pci_irq_host;
@@ -185,7 +187,7 @@
void tsi108_clear_pci_cfg_error(void)
{
- tsi108_clear_pci_error(TSI108_PCI_CFG_BASE_PHYS);
+ tsi108_clear_pci_error(tsi108_pci_cfg_phys);
}
static struct pci_ops tsi108_direct_pci_ops = {
@@ -193,17 +195,17 @@
tsi108_direct_write_config
};
-int __init tsi108_setup_pci(struct device_node *dev)
+int __init tsi108_setup_pci(struct device_node *dev, u32 cfg_phys, int primary)
{
int len;
struct pci_controller *hose;
struct resource rsrc;
const int *bus_range;
- int primary = 0, has_address = 0;
+ int has_address = 0;
/* PCI Config mapping */
- tsi108_pci_cfg_base = (u32)ioremap(TSI108_PCI_CFG_BASE_PHYS,
- TSI108_PCI_CFG_SIZE);
+ tsi108_pci_cfg_base = (u32)ioremap(cfg_phys, TSI108_PCI_CFG_SIZE);
+ tsi108_pci_cfg_phys = cfg_phys;
DBG("TSI_PCI: %s tsi108_pci_cfg_base=0x%x\n", __FUNCTION__,
tsi108_pci_cfg_base);
diff --git a/arch/powerpc/sysdev/uic.c b/arch/powerpc/sysdev/uic.c
index 968fb40..8905989 100644
--- a/arch/powerpc/sysdev/uic.c
+++ b/arch/powerpc/sysdev/uic.c
@@ -221,7 +221,7 @@
const u32 *indexp, *dcrreg;
int len;
- BUG_ON(! device_is_compatible(node, "ibm,uic"));
+ BUG_ON(! of_device_is_compatible(node, "ibm,uic"));
uic = alloc_bootmem(sizeof(*uic));
if (! uic)
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index b481db1..28fdf4f 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -1217,7 +1217,6 @@
{
unsigned long size, offset;
const char *name;
- char *modname;
*startp = *endp = 0;
if (pc == 0)
@@ -1225,7 +1224,7 @@
if (setjmp(bus_error_jmp) == 0) {
catch_memory_errors = 1;
sync();
- name = kallsyms_lookup(pc, &size, &offset, &modname, tmpstr);
+ name = kallsyms_lookup(pc, &size, &offset, NULL, tmpstr);
if (name != NULL) {
*startp = pc - offset;
*endp = pc - offset + size;
diff --git a/arch/ppc/kernel/ppc_htab.c b/arch/ppc/kernel/ppc_htab.c
index 0a7e42d..aa07b63 100644
--- a/arch/ppc/kernel/ppc_htab.c
+++ b/arch/ppc/kernel/ppc_htab.c
@@ -18,7 +18,6 @@
#include <linux/capability.h>
#include <linux/ctype.h>
#include <linux/threads.h>
-#include <linux/smp_lock.h>
#include <linux/seq_file.h>
#include <linux/init.h>
#include <linux/bitops.h>
diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c
index 96a5597..0559985 100644
--- a/arch/ppc/kernel/smp.c
+++ b/arch/ppc/kernel/smp.c
@@ -12,7 +12,6 @@
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
#include <linux/delay.h>
diff --git a/arch/ppc/syslib/ppc4xx_sgdma.c b/arch/ppc/syslib/ppc4xx_sgdma.c
index 5dadca3e..c4b369b 100644
--- a/arch/ppc/syslib/ppc4xx_sgdma.c
+++ b/arch/ppc/syslib/ppc4xx_sgdma.c
@@ -23,10 +23,10 @@
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/dma-mapping.h>
#include <asm/system.h>
#include <asm/io.h>
-#include <asm/dma-mapping.h>
#include <asm/ppc4xx_dma.h>
void
diff --git a/arch/ppc/syslib/virtex_devices.h b/arch/ppc/syslib/virtex_devices.h
index 4a17dd3..3d4be14 100644
--- a/arch/ppc/syslib/virtex_devices.h
+++ b/arch/ppc/syslib/virtex_devices.h
@@ -13,6 +13,13 @@
#include <linux/platform_device.h>
+/* ML300/403 reference design framebuffer driver platform data struct */
+struct xilinxfb_platform_data {
+ u32 rotate_screen;
+ u32 screen_height_mm;
+ u32 screen_width_mm;
+};
+
void __init virtex_early_serial_map(void);
/* Prototype for device fixup routine. Implement this routine in the
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c
index 80a54a0..a5692c4 100644
--- a/arch/s390/kernel/compat_signal.c
+++ b/arch/s390/kernel/compat_signal.c
@@ -14,7 +14,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c
index dabaf98..a057ebf 100644
--- a/arch/s390/kernel/dis.c
+++ b/arch/s390/kernel/dis.c
@@ -23,6 +23,7 @@
#include <linux/kallsyms.h>
#include <linux/reboot.h>
#include <linux/kprobes.h>
+#include <linux/kdebug.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -33,7 +34,6 @@
#include <asm/s390_ext.h>
#include <asm/lowcore.h>
#include <asm/debug.h>
-#include <asm/kdebug.h>
#ifndef CONFIG_64BIT
#define ONELONG "%08lx: "
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c
index 23c61f6..e39333a 100644
--- a/arch/s390/kernel/kprobes.c
+++ b/arch/s390/kernel/kprobes.c
@@ -24,8 +24,8 @@
#include <linux/ptrace.h>
#include <linux/preempt.h>
#include <linux/stop_machine.h>
+#include <linux/kdebug.h>
#include <asm/cacheflush.h>
-#include <asm/kdebug.h>
#include <asm/sections.h>
#include <asm/uaccess.h>
#include <linux/module.h>
@@ -271,23 +271,13 @@
}
/* Called with kretprobe_lock held */
-void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
+void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
struct pt_regs *regs)
{
- struct kretprobe_instance *ri;
+ ri->ret_addr = (kprobe_opcode_t *) regs->gprs[14];
- if ((ri = get_free_rp_inst(rp)) != NULL) {
- ri->rp = rp;
- ri->task = current;
- ri->ret_addr = (kprobe_opcode_t *) regs->gprs[14];
-
- /* Replace the return addr with trampoline addr */
- regs->gprs[14] = (unsigned long)&kretprobe_trampoline;
-
- add_rp_inst(ri);
- } else {
- rp->nmissed++;
- }
+ /* Replace the return addr with trampoline addr */
+ regs->gprs[14] = (unsigned long)&kretprobe_trampoline;
}
static int __kprobes kprobe_handler(struct pt_regs *regs)
@@ -671,3 +661,10 @@
{
return register_kprobe(&trampoline_p);
}
+
+int __kprobes arch_trampoline_kprobe(struct kprobe *p)
+{
+ if (p->addr == (kprobe_opcode_t *) & kretprobe_trampoline)
+ return 1;
+ return 0;
+}
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 11d9b01..eb43c3b 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -22,7 +22,6 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index 3c41907..d264671 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -14,7 +14,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 3754e20..b797702 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -25,7 +25,6 @@
#include <linux/mm.h>
#include <linux/spinlock.h>
#include <linux/kernel_stat.h>
-#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <linux/cache.h>
#include <linux/interrupt.h>
diff --git a/arch/s390/kernel/stacktrace.c b/arch/s390/kernel/stacktrace.c
index 2e5c65a..515ff90 100644
--- a/arch/s390/kernel/stacktrace.c
+++ b/arch/s390/kernel/stacktrace.c
@@ -59,7 +59,7 @@
}
}
-void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
+void save_stack_trace(struct stack_trace *trace)
{
register unsigned long sp asm ("15");
unsigned long orig_sp, new_sp;
@@ -69,20 +69,16 @@
new_sp = save_context_stack(trace, &trace->skip, orig_sp,
S390_lowcore.panic_stack - PAGE_SIZE,
S390_lowcore.panic_stack);
- if ((new_sp != orig_sp) && !trace->all_contexts)
+ if (new_sp != orig_sp)
return;
new_sp = save_context_stack(trace, &trace->skip, new_sp,
S390_lowcore.async_stack - ASYNC_SIZE,
S390_lowcore.async_stack);
- if ((new_sp != orig_sp) && !trace->all_contexts)
+ if (new_sp != orig_sp)
return;
- if (task)
- save_context_stack(trace, &trace->skip, new_sp,
- (unsigned long) task_stack_page(task),
- (unsigned long) task_stack_page(task) + THREAD_SIZE);
- else
- save_context_stack(trace, &trace->skip, new_sp,
- S390_lowcore.thread_info,
- S390_lowcore.thread_info + THREAD_SIZE);
+
+ save_context_stack(trace, &trace->skip, new_sp,
+ S390_lowcore.thread_info,
+ S390_lowcore.thread_info + THREAD_SIZE);
return;
}
diff --git a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c
index 3a77c22..1c90c7e 100644
--- a/arch/s390/kernel/sys_s390.c
+++ b/arch/s390/kernel/sys_s390.c
@@ -17,7 +17,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 711dae8..9c2872a 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -21,6 +21,7 @@
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/time.h>
+#include <linux/sysdev.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/smp.h>
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 49dec83..cbfe730 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -22,11 +22,11 @@
#include <linux/timer.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/module.h>
+#include <linux/kdebug.h>
#include <linux/kallsyms.h>
#include <linux/reboot.h>
#include <linux/kprobes.h>
@@ -40,7 +40,6 @@
#include <asm/s390_ext.h>
#include <asm/lowcore.h>
#include <asm/debug.h>
-#include <asm/kdebug.h>
/* Called from entry.S only */
extern void handle_per_exception(struct pt_regs *regs);
@@ -70,20 +69,6 @@
static int kstack_depth_to_print = 20;
#endif /* CONFIG_64BIT */
-ATOMIC_NOTIFIER_HEAD(s390die_chain);
-
-int register_die_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_register(&s390die_chain, nb);
-}
-EXPORT_SYMBOL(register_die_notifier);
-
-int unregister_die_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_unregister(&s390die_chain, nb);
-}
-EXPORT_SYMBOL(unregister_die_notifier);
-
/*
* For show_trace we have tree different stack to consider:
* - the panic stack which is used if the kernel stack has overflown
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 91f705a..8b924b3 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -20,6 +20,7 @@
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/smp.h>
+#include <linux/kdebug.h>
#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/console.h>
@@ -30,7 +31,6 @@
#include <asm/system.h>
#include <asm/pgtable.h>
-#include <asm/kdebug.h>
#include <asm/s390_ext.h>
#ifndef CONFIG_64BIT
diff --git a/arch/sh/drivers/pci/pci-st40.c b/arch/sh/drivers/pci/pci-st40.c
index efecb3d..d67656a 100644
--- a/arch/sh/drivers/pci/pci-st40.c
+++ b/arch/sh/drivers/pci/pci-st40.c
@@ -9,7 +9,6 @@
#include <linux/kernel.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/pci.h>
diff --git a/arch/sh/kernel/early_printk.c b/arch/sh/kernel/early_printk.c
index 9048c03..9833493 100644
--- a/arch/sh/kernel/early_printk.c
+++ b/arch/sh/kernel/early_printk.c
@@ -192,20 +192,14 @@
}
#endif
- if (likely(early_console))
+ if (likely(early_console)) {
+ if (keep_early)
+ early_console->flags &= ~CON_BOOT;
+ else
+ early_console->flags |= CON_BOOT;
register_console(early_console);
+ }
return 0;
}
early_param("earlyprintk", setup_early_printk);
-
-void __init disable_early_printk(void)
-{
- if (!early_console_initialized || !early_console)
- return;
- if (!keep_early) {
- printk("disabling early console\n");
- unregister_console(early_console);
- } else
- printk("keeping early console\n");
-}
diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c
index 855f724..3fb5fc0 100644
--- a/arch/sh/kernel/ptrace.c
+++ b/arch/sh/kernel/ptrace.c
@@ -12,7 +12,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c
index 17f0b50..fa91641 100644
--- a/arch/sh/kernel/sh_ksyms.c
+++ b/arch/sh/kernel/sh_ksyms.c
@@ -5,7 +5,6 @@
#include <linux/sched.h>
#include <linux/in6.h>
#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
#include <linux/vmalloc.h>
#include <linux/pci.h>
#include <linux/irq.h>
diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c
index 9f39ef1..eb0191c 100644
--- a/arch/sh/kernel/signal.c
+++ b/arch/sh/kernel/signal.c
@@ -11,7 +11,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/sh/kernel/stacktrace.c b/arch/sh/kernel/stacktrace.c
index 0d5268a..4bdd2f8 100644
--- a/arch/sh/kernel/stacktrace.c
+++ b/arch/sh/kernel/stacktrace.c
@@ -19,14 +19,7 @@
*/
void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
{
- unsigned long *sp;
-
- if (!task)
- task = current;
- if (task == current)
- sp = (unsigned long *)current_stack_pointer;
- else
- sp = (unsigned long *)task->thread.sp;
+ unsigned long *sp = (unsigned long *)current_stack_pointer;
while (!kstack_end(sp)) {
unsigned long addr = *sp++;
diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c
index e18f183..76b1bc7 100644
--- a/arch/sh/kernel/sys_sh.c
+++ b/arch/sh/kernel/sys_sh.c
@@ -12,7 +12,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
diff --git a/arch/sh/kernel/timers/timer-cmt.c b/arch/sh/kernel/timers/timer-cmt.c
index a574b93..82de689 100644
--- a/arch/sh/kernel/timers/timer-cmt.c
+++ b/arch/sh/kernel/timers/timer-cmt.c
@@ -115,7 +115,7 @@
static struct irqaction cmt_irq = {
.name = "timer",
.handler = cmt_timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.mask = CPU_MASK_NONE,
};
diff --git a/arch/sh/kernel/timers/timer-mtu2.c b/arch/sh/kernel/timers/timer-mtu2.c
index fffcd1c..b7499a2 100644
--- a/arch/sh/kernel/timers/timer-mtu2.c
+++ b/arch/sh/kernel/timers/timer-mtu2.c
@@ -110,7 +110,7 @@
static struct irqaction mtu2_irq = {
.name = "timer",
.handler = mtu2_timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.mask = CPU_MASK_NONE,
};
diff --git a/arch/sh/kernel/timers/timer-tmu.c b/arch/sh/kernel/timers/timer-tmu.c
index ad1ede5..d9e3151 100644
--- a/arch/sh/kernel/timers/timer-tmu.c
+++ b/arch/sh/kernel/timers/timer-tmu.c
@@ -99,7 +99,7 @@
static struct irqaction tmu_irq = {
.name = "timer",
.handler = tmu_timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.mask = CPU_MASK_NONE,
};
diff --git a/arch/sh/mm/fault-nommu.c b/arch/sh/mm/fault-nommu.c
index 34d4e0c..923cb45 100644
--- a/arch/sh/mm/fault-nommu.c
+++ b/arch/sh/mm/fault-nommu.c
@@ -19,7 +19,6 @@
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <asm/system.h>
diff --git a/arch/sh/mm/hugetlbpage.c b/arch/sh/mm/hugetlbpage.c
index cf2c2ee..ae8c321 100644
--- a/arch/sh/mm/hugetlbpage.c
+++ b/arch/sh/mm/hugetlbpage.c
@@ -13,7 +13,6 @@
#include <linux/mm.h>
#include <linux/hugetlb.h>
#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/sysctl.h>
diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c
index d0d45e2..02aae06 100644
--- a/arch/sh/mm/pmb.c
+++ b/arch/sh/mm/pmb.c
@@ -311,9 +311,9 @@
BUG_ON(unlikely(nr_entries >= NR_PMB_ENTRIES));
- pmb_cache = kmem_cache_create("pmb", sizeof(struct pmb_entry),
- 0, 0, pmb_cache_ctor, pmb_cache_dtor);
- BUG_ON(!pmb_cache);
+ pmb_cache = kmem_cache_create("pmb", sizeof(struct pmb_entry), 0,
+ SLAB_PANIC, pmb_cache_ctor,
+ pmb_cache_dtor);
jump_to_P2();
diff --git a/arch/sh64/kernel/early_printk.c b/arch/sh64/kernel/early_printk.c
index 8c8a76e..4f91311 100644
--- a/arch/sh64/kernel/early_printk.c
+++ b/arch/sh64/kernel/early_printk.c
@@ -79,7 +79,7 @@
.name = "scifcon",
.write = sh_console_write,
.setup = sh_console_setup,
- .flags = CON_PRINTBUFFER,
+ .flags = CON_PRINTBUFFER | CON_BOOT,
.index = -1,
};
@@ -97,9 +97,3 @@
register_console(&sh_console);
}
-
-void disable_early_printk(void)
-{
- unregister_console(&sh_console);
-}
-
diff --git a/arch/sh64/kernel/irq.c b/arch/sh64/kernel/irq.c
index e7e07f8..f68b4f6 100644
--- a/arch/sh64/kernel/irq.c
+++ b/arch/sh64/kernel/irq.c
@@ -26,7 +26,6 @@
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/seq_file.h>
#include <linux/bitops.h>
diff --git a/arch/sh64/kernel/pci_sh5.c b/arch/sh64/kernel/pci_sh5.c
index 9dae689..49862e1 100644
--- a/arch/sh64/kernel/pci_sh5.c
+++ b/arch/sh64/kernel/pci_sh5.c
@@ -12,7 +12,6 @@
#include <linux/kernel.h>
#include <linux/rwsem.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/errno.h>
diff --git a/arch/sh64/kernel/sh_ksyms.c b/arch/sh64/kernel/sh_ksyms.c
index 7aa4b4f..461ea3d 100644
--- a/arch/sh64/kernel/sh_ksyms.c
+++ b/arch/sh64/kernel/sh_ksyms.c
@@ -17,7 +17,6 @@
#include <linux/sched.h>
#include <linux/in6.h>
#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
#include <linux/screen_info.h>
#include <asm/semaphore.h>
diff --git a/arch/sh64/kernel/signal.c b/arch/sh64/kernel/signal.c
index 1666d3e..b76bdfa 100644
--- a/arch/sh64/kernel/signal.c
+++ b/arch/sh64/kernel/signal.c
@@ -16,7 +16,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/sh64/kernel/sys_sh64.c b/arch/sh64/kernel/sys_sh64.c
index ad0fa4e..19126da 100644
--- a/arch/sh64/kernel/sys_sh64.c
+++ b/arch/sh64/kernel/sys_sh64.c
@@ -20,7 +20,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
diff --git a/arch/sh64/kernel/traps.c b/arch/sh64/kernel/traps.c
index c346d7e..9d0d58f 100644
--- a/arch/sh64/kernel/traps.c
+++ b/arch/sh64/kernel/traps.c
@@ -23,7 +23,6 @@
#include <linux/timer.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
diff --git a/arch/sh64/kernel/unwind.c b/arch/sh64/kernel/unwind.c
index f934f97..1214c78 100644
--- a/arch/sh64/kernel/unwind.c
+++ b/arch/sh64/kernel/unwind.c
@@ -46,15 +46,15 @@
struct pt_regs *regs)
{
const char *sym;
- char *modname, namebuf[128];
- unsigned long offset, size;
+ char namebuf[128];
+ unsigned long offset;
unsigned long prologue = 0;
unsigned long fp_displacement = 0;
unsigned long fp_prev = 0;
unsigned long offset_r14 = 0, offset_r18 = 0;
int i, found_prologue_end = 0;
- sym = kallsyms_lookup(pc, &size, &offset, &modname, namebuf);
+ sym = kallsyms_lookup(pc, NULL, &offset, NULL, namebuf);
if (!sym)
return -EINVAL;
diff --git a/arch/sh64/mm/fault.c b/arch/sh64/mm/fault.c
index 4f72ab3..4dd8ee8 100644
--- a/arch/sh64/mm/fault.c
+++ b/arch/sh64/mm/fault.c
@@ -22,7 +22,6 @@
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <asm/system.h>
diff --git a/arch/sh64/mm/hugetlbpage.c b/arch/sh64/mm/hugetlbpage.c
index 4b455f6..fa66daa 100644
--- a/arch/sh64/mm/hugetlbpage.c
+++ b/arch/sh64/mm/hugetlbpage.c
@@ -13,7 +13,6 @@
#include <linux/mm.h>
#include <linux/hugetlb.h>
#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/sysctl.h>
diff --git a/arch/sh64/mm/tlbmiss.c b/arch/sh64/mm/tlbmiss.c
index c861595..d4c5334 100644
--- a/arch/sh64/mm/tlbmiss.c
+++ b/arch/sh64/mm/tlbmiss.c
@@ -32,7 +32,6 @@
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <asm/system.h>
diff --git a/arch/sparc/kernel/head.S b/arch/sparc/kernel/head.S
index 9a219e8..97da13c 100644
--- a/arch/sparc/kernel/head.S
+++ b/arch/sparc/kernel/head.S
@@ -19,7 +19,7 @@
#include <asm/ptrace.h>
#include <asm/psr.h>
#include <asm/page.h>
-#include <asm/kdebug.h>
+#include <linux/kdebug.h>
#include <asm/winmacro.h>
#include <asm/thread_info.h> /* TI_UWINMASK */
#include <asm/errno.h>
diff --git a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c
index 5b4841d..bdbefa8 100644
--- a/arch/sparc/kernel/irq.c
+++ b/arch/sparc/kernel/irq.c
@@ -24,7 +24,6 @@
#include <linux/random.h>
#include <linux/init.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <linux/threads.h>
#include <linux/spinlock.h>
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
index fc874e6..2940d2c 100644
--- a/arch/sparc/kernel/process.c
+++ b/arch/sparc/kernel/process.c
@@ -23,7 +23,6 @@
#include <linux/user.h>
#include <linux/a.out.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/reboot.h>
#include <linux/delay.h>
#include <linux/pm.h>
diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c
index eccd8e8..64c0ed9 100644
--- a/arch/sparc/kernel/setup.c
+++ b/arch/sparc/kernel/setup.c
@@ -31,6 +31,7 @@
#include <linux/spinlock.h>
#include <linux/root_dev.h>
#include <linux/cpu.h>
+#include <linux/kdebug.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -40,7 +41,6 @@
#include <asm/pgtable.h>
#include <asm/traps.h>
#include <asm/vaddrs.h>
-#include <asm/kdebug.h>
#include <asm/mbus.h>
#include <asm/idprom.h>
#include <asm/machines.h>
diff --git a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c
index c9301b9..9994cac 100644
--- a/arch/sparc/kernel/signal.c
+++ b/arch/sparc/kernel/signal.c
@@ -17,7 +17,6 @@
#include <linux/mm.h>
#include <linux/tty.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/binfmts.h> /* do_coredum */
#include <linux/bitops.h>
diff --git a/arch/sparc/kernel/smp.c b/arch/sparc/kernel/smp.c
index 6b5f26b..4d9ad590 100644
--- a/arch/sparc/kernel/smp.c
+++ b/arch/sparc/kernel/smp.c
@@ -11,7 +11,6 @@
#include <linux/sched.h>
#include <linux/threads.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
#include <linux/init.h>
diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c
index 0e27e22..116d6a2 100644
--- a/arch/sparc/kernel/sun4d_irq.c
+++ b/arch/sparc/kernel/sun4d_irq.c
@@ -17,7 +17,6 @@
#include <linux/random.h>
#include <linux/init.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/seq_file.h>
diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c
index c69de5d..098c94f 100644
--- a/arch/sparc/kernel/sun4d_smp.c
+++ b/arch/sparc/kernel/sun4d_smp.c
@@ -12,7 +12,6 @@
#include <linux/sched.h>
#include <linux/threads.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
#include <linux/init.h>
diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c
index 4e07bdb..63ed19b 100644
--- a/arch/sparc/kernel/sun4m_smp.c
+++ b/arch/sparc/kernel/sun4m_smp.c
@@ -9,7 +9,6 @@
#include <linux/sched.h>
#include <linux/threads.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
#include <linux/init.h>
diff --git a/arch/sparc/kernel/sunos_ioctl.c b/arch/sparc/kernel/sunos_ioctl.c
index 32e8274..e613cc6 100644
--- a/arch/sparc/kernel/sunos_ioctl.c
+++ b/arch/sparc/kernel/sunos_ioctl.c
@@ -21,7 +21,6 @@
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/syscalls.h>
#include <linux/file.h>
diff --git a/arch/sparc/kernel/sys_solaris.c b/arch/sparc/kernel/sys_solaris.c
index 01b07bb..2226a59 100644
--- a/arch/sparc/kernel/sys_solaris.c
+++ b/arch/sparc/kernel/sys_solaris.c
@@ -12,7 +12,6 @@
#include <linux/ptrace.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/module.h>
asmlinkage int
diff --git a/arch/sparc/kernel/traps.c b/arch/sparc/kernel/traps.c
index 527687a..dc9ffea 100644
--- a/arch/sparc/kernel/traps.c
+++ b/arch/sparc/kernel/traps.c
@@ -15,6 +15,7 @@
#include <linux/signal.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
+#include <linux/kdebug.h>
#include <asm/delay.h>
#include <asm/system.h>
@@ -22,7 +23,6 @@
#include <asm/oplib.h>
#include <asm/page.h>
#include <asm/pgtable.h>
-#include <asm/kdebug.h>
#include <asm/unistd.h>
#include <asm/traps.h>
diff --git a/arch/sparc/lib/bitext.c b/arch/sparc/lib/bitext.c
index 2e168d1..764b3eb 100644
--- a/arch/sparc/lib/bitext.c
+++ b/arch/sparc/lib/bitext.c
@@ -9,7 +9,6 @@
* fragmentation.
*/
-#include <linux/smp_lock.h>
#include <linux/string.h>
#include <linux/bitops.h>
diff --git a/arch/sparc/mm/fault.c b/arch/sparc/mm/fault.c
index 9eeed33..c348336 100644
--- a/arch/sparc/mm/fault.c
+++ b/arch/sparc/mm/fault.c
@@ -18,9 +18,9 @@
#include <linux/signal.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/module.h>
+#include <linux/kdebug.h>
#include <asm/system.h>
#include <asm/page.h>
@@ -30,7 +30,6 @@
#include <asm/oplib.h>
#include <asm/smp.h>
#include <asm/traps.h>
-#include <asm/kdebug.h>
#include <asm/uaccess.h>
extern int prom_node_root;
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index 0df7121..e5eaa80 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -18,13 +18,13 @@
#include <linux/bootmem.h>
#include <linux/fs.h>
#include <linux/seq_file.h>
+#include <linux/kdebug.h>
#include <asm/bitext.h>
#include <asm/page.h>
#include <asm/pgalloc.h>
#include <asm/pgtable.h>
#include <asm/io.h>
-#include <asm/kdebug.h>
#include <asm/vaddrs.h>
#include <asm/traps.h>
#include <asm/smp.h>
diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c
index ae221f0..a44fe47 100644
--- a/arch/sparc64/kernel/kprobes.c
+++ b/arch/sparc64/kernel/kprobes.c
@@ -6,7 +6,7 @@
#include <linux/kernel.h>
#include <linux/kprobes.h>
#include <linux/module.h>
-#include <asm/kdebug.h>
+#include <linux/kdebug.h>
#include <asm/signal.h>
#include <asm/cacheflush.h>
#include <asm/uaccess.h>
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index af2c7ff..966861b 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -14,7 +14,6 @@
#include <linux/sched.h>
#include <linux/capability.h>
#include <linux/errno.h>
-#include <linux/smp_lock.h>
#include <linux/msi.h>
#include <linux/irq.h>
#include <linux/init.h>
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index a114151..8e3c6e4 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -19,7 +19,6 @@
#include <linux/kallsyms.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/ptrace.h>
#include <linux/slab.h>
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c
index 96d56a8..203e873 100644
--- a/arch/sparc64/kernel/signal.c
+++ b/arch/sparc64/kernel/signal.c
@@ -20,7 +20,6 @@
#include <linux/unistd.h>
#include <linux/mm.h>
#include <linux/tty.h>
-#include <linux/smp_lock.h>
#include <linux/binfmts.h>
#include <linux/bitops.h>
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
index c45f21b..8c1c121 100644
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -17,7 +17,6 @@
#include <linux/unistd.h>
#include <linux/mm.h>
#include <linux/tty.h>
-#include <linux/smp_lock.h>
#include <linux/binfmts.h>
#include <linux/compat.h>
#include <linux/bitops.h>
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index 1fac215..8087d67 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -10,7 +10,6 @@
#include <linux/pagemap.h>
#include <linux/threads.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
#include <linux/delay.h>
diff --git a/arch/sparc64/kernel/stacktrace.c b/arch/sparc64/kernel/stacktrace.c
index c4d15f2..47f92a5 100644
--- a/arch/sparc64/kernel/stacktrace.c
+++ b/arch/sparc64/kernel/stacktrace.c
@@ -3,22 +3,16 @@
#include <linux/thread_info.h>
#include <asm/ptrace.h>
-void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
+void save_stack_trace(struct stack_trace *trace)
{
unsigned long ksp, fp, thread_base;
- struct thread_info *tp;
+ struct thread_info *tp = task_thread_info(current);
- if (!task)
- task = current;
- tp = task_thread_info(task);
- if (task == current) {
- flushw_all();
- __asm__ __volatile__(
- "mov %%fp, %0"
- : "=r" (ksp)
- );
- } else
- ksp = tp->ksp;
+ flushw_all();
+ __asm__ __volatile__(
+ "mov %%fp, %0"
+ : "=r" (ksp)
+ );
fp = ksp + STACK_BIAS;
thread_base = (unsigned long) tp;
diff --git a/arch/sparc64/kernel/sunos_ioctl32.c b/arch/sparc64/kernel/sunos_ioctl32.c
index a05e43d..75d2bad 100644
--- a/arch/sparc64/kernel/sunos_ioctl32.c
+++ b/arch/sparc64/kernel/sunos_ioctl32.c
@@ -22,7 +22,6 @@
#include <linux/file.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/syscalls.h>
#include <linux/compat.h>
diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c
index a53d4ab..d108eeb 100644
--- a/arch/sparc64/kernel/sys_sparc.c
+++ b/arch/sparc64/kernel/sys_sparc.c
@@ -19,7 +19,6 @@
#include <linux/mman.h>
#include <linux/utsname.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/syscalls.h>
#include <linux/ipc.h>
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index 7876a02..692e46a 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -775,15 +775,25 @@
asmlinkage long sys32_utimes(char __user *filename,
struct compat_timeval __user *tvs)
{
- struct timeval ktvs[2];
+ struct timespec tv[2];
if (tvs) {
+ struct timeval ktvs[2];
if (get_tv32(&ktvs[0], tvs) ||
get_tv32(&ktvs[1], 1+tvs))
return -EFAULT;
+
+ if (ktvs[0].tv_usec < 0 || ktvs[0].tv_usec >= 1000000 ||
+ ktvs[1].tv_usec < 0 || ktvs[1].tv_usec >= 1000000)
+ return -EINVAL;
+
+ tv[0].tv_sec = ktvs[0].tv_sec;
+ tv[0].tv_nsec = 1000 * ktvs[0].tv_usec;
+ tv[1].tv_sec = ktvs[1].tv_sec;
+ tv[1].tv_nsec = 1000 * ktvs[1].tv_usec;
}
- return do_utimes(AT_FDCWD, filename, (tvs ? &ktvs[0] : NULL));
+ return do_utimes(AT_FDCWD, filename, tvs ? tv : NULL);
}
/* These are here just in case some old sparc32 binary calls it. */
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index ad67784..dc652f2 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -15,9 +15,9 @@
#include <linux/kallsyms.h>
#include <linux/signal.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/mm.h>
#include <linux/init.h>
+#include <linux/kdebug.h>
#include <asm/delay.h>
#include <asm/system.h>
@@ -36,26 +36,12 @@
#include <asm/psrcompat.h>
#include <asm/processor.h>
#include <asm/timer.h>
-#include <asm/kdebug.h>
#include <asm/head.h>
#ifdef CONFIG_KMOD
#include <linux/kmod.h>
#endif
#include <asm/prom.h>
-ATOMIC_NOTIFIER_HEAD(sparc64die_chain);
-
-int register_die_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_register(&sparc64die_chain, nb);
-}
-EXPORT_SYMBOL(register_die_notifier);
-
-int unregister_die_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_unregister(&sparc64die_chain, nb);
-}
-EXPORT_SYMBOL(unregister_die_notifier);
/* When an irrecoverable trap occurs at tl > 0, the trap entry
* code logs the trap state registers at every level in the trap
diff --git a/arch/sparc64/kernel/unaligned.c b/arch/sparc64/kernel/unaligned.c
index bc18d48..953be81 100644
--- a/arch/sparc64/kernel/unaligned.c
+++ b/arch/sparc64/kernel/unaligned.c
@@ -18,7 +18,6 @@
#include <asm/system.h>
#include <asm/uaccess.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/bitops.h>
#include <linux/kallsyms.h>
#include <asm/fpumacro.h>
diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c
index 55ae802..c32e309 100644
--- a/arch/sparc64/mm/fault.c
+++ b/arch/sparc64/mm/fault.c
@@ -15,11 +15,11 @@
#include <linux/signal.h>
#include <linux/mm.h>
#include <linux/module.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kprobes.h>
#include <linux/kallsyms.h>
+#include <linux/kdebug.h>
#include <asm/page.h>
#include <asm/pgtable.h>
@@ -29,7 +29,6 @@
#include <asm/asi.h>
#include <asm/lsu.h>
#include <asm/sections.h>
-#include <asm/kdebug.h>
#include <asm/mmu_context.h>
#ifdef CONFIG_KPROBES
diff --git a/arch/sparc64/mm/hugetlbpage.c b/arch/sparc64/mm/hugetlbpage.c
index e224a94..eaba9b7 100644
--- a/arch/sparc64/mm/hugetlbpage.c
+++ b/arch/sparc64/mm/hugetlbpage.c
@@ -10,7 +10,6 @@
#include <linux/mm.h>
#include <linux/hugetlb.h>
#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/sysctl.h>
diff --git a/arch/sparc64/solaris/ipc.c b/arch/sparc64/solaris/ipc.c
index 8cef5fd..a531a2c 100644
--- a/arch/sparc64/solaris/ipc.c
+++ b/arch/sparc64/solaris/ipc.c
@@ -6,7 +6,6 @@
#include <linux/kernel.h>
#include <linux/types.h>
-#include <linux/smp_lock.h>
#include <linux/wait.h>
#include <linux/mm.h>
#include <linux/shm.h>
diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c
index 542c808..3b67de7 100644
--- a/arch/sparc64/solaris/misc.c
+++ b/arch/sparc64/solaris/misc.c
@@ -6,7 +6,6 @@
#include <linux/module.h>
#include <linux/types.h>
-#include <linux/smp_lock.h>
#include <linux/utsname.h>
#include <linux/limits.h>
#include <linux/mm.h>
diff --git a/arch/sparc64/solaris/signal.c b/arch/sparc64/solaris/signal.c
index 7fa2634..de10c97 100644
--- a/arch/sparc64/solaris/signal.c
+++ b/arch/sparc64/solaris/signal.c
@@ -5,7 +5,6 @@
*/
#include <linux/types.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <asm/uaccess.h>
diff --git a/arch/sparc64/solaris/socket.c b/arch/sparc64/solaris/socket.c
index d3a66ea..cc69847 100644
--- a/arch/sparc64/solaris/socket.c
+++ b/arch/sparc64/solaris/socket.c
@@ -8,7 +8,6 @@
*/
#include <linux/types.h>
-#include <linux/smp_lock.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/socket.h>
diff --git a/arch/sparc64/solaris/socksys.c b/arch/sparc64/solaris/socksys.c
index c286444..e94f6e5 100644
--- a/arch/sparc64/solaris/socksys.c
+++ b/arch/sparc64/solaris/socksys.c
@@ -17,7 +17,6 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/ioctl.h>
#include <linux/fs.h>
#include <linux/file.h>
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index baac4ad..72773dd 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -316,12 +316,14 @@
}
if (!is_local_ether_addr(addr)) {
printk(KERN_WARNING
- "Warning: attempt to assign a globally valid ethernet address to a "
- "device\n");
- printk(KERN_WARNING "You should better enable the 2nd rightmost bit "
- "in the first byte of the MAC, i.e. "
- "%02x:%02x:%02x:%02x:%02x:%02x\n",
- addr[0] | 0x02, addr[1], addr[2], addr[3], addr[4], addr[5]);
+ "Warning: attempt to assign a globally valid ethernet "
+ "address to a device\n");
+ printk(KERN_WARNING "You should better enable the 2nd "
+ "rightmost bit in the first byte of the MAC,\n");
+ printk(KERN_WARNING "i.e. %02x:%02x:%02x:%02x:%02x:%02x\n",
+ addr[0] | 0x02, addr[1], addr[2], addr[3], addr[4],
+ addr[5]);
+ goto random;
}
return;
@@ -478,6 +480,7 @@
(*transport->user->remove)(&lp->user);
out_unregister:
platform_device_unregister(&device->pdev);
+ return; /* platform_device_unregister frees dev and device */
out_free_netdev:
free_netdev(dev);
out_free_device:
diff --git a/arch/um/drivers/pcap_kern.c b/arch/um/drivers/pcap_kern.c
index 9488493..c329931 100644
--- a/arch/um/drivers/pcap_kern.c
+++ b/arch/um/drivers/pcap_kern.c
@@ -29,21 +29,25 @@
ppri->promisc = init->promisc;
ppri->optimize = init->optimize;
ppri->filter = init->filter;
+
+ printk("pcap backend, host interface %s\n", ppri->host_if);
}
-static int pcap_read(int fd, struct sk_buff **skb,
+static int pcap_read(int fd, struct sk_buff **skb,
struct uml_net_private *lp)
{
*skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
- if(*skb == NULL) return(-ENOMEM);
- return(pcap_user_read(fd, skb_mac_header(*skb),
+ if(*skb == NULL)
+ return -ENOMEM;
+
+ return pcap_user_read(fd, skb_mac_header(*skb),
(*skb)->dev->mtu + ETH_HEADER_OTHER,
- (struct pcap_data *) &lp->user));
+ (struct pcap_data *) &lp->user);
}
static int pcap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp)
{
- return(-EPERM);
+ return -EPERM;
}
static const struct net_kern_info pcap_kern_info = {
@@ -65,12 +69,12 @@
.optimize = 0,
.filter = NULL });
- remain = split_if_spec(str, &host_if, &init->filter,
- &options[0], &options[1], NULL);
+ remain = split_if_spec(str, &host_if, &init->filter,
+ &options[0], &options[1], mac_out, NULL);
if(remain != NULL){
printk(KERN_ERR "pcap_setup - Extra garbage on "
"specification : '%s'\n", remain);
- return(0);
+ return 0;
}
if(host_if != NULL)
@@ -87,10 +91,13 @@
init->optimize = 1;
else if(!strcmp(options[i], "nooptimize"))
init->optimize = 0;
- else printk("pcap_setup : bad option - '%s'\n", options[i]);
+ else {
+ printk("pcap_setup : bad option - '%s'\n", options[i]);
+ return 0;
+ }
}
- return(1);
+ return 1;
}
static struct transport pcap_transport = {
diff --git a/arch/um/drivers/pcap_user.c b/arch/um/drivers/pcap_user.c
index dc0a903..483aa15 100644
--- a/arch/um/drivers/pcap_user.c
+++ b/arch/um/drivers/pcap_user.c
@@ -13,6 +13,7 @@
#include "pcap_user.h"
#include "user.h"
#include "um_malloc.h"
+#include "kern_constants.h"
#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
@@ -26,8 +27,8 @@
p = pcap_open_live(pri->host_if, MAX_PACKET, pri->promisc, 0, errors);
if(p == NULL){
- printk("pcap_user_init : pcap_open_live failed - '%s'\n",
- errors);
+ printk(UM_KERN_ERR "pcap_user_init : pcap_open_live failed - "
+ "'%s'\n", errors);
return -EINVAL;
}
@@ -48,13 +49,13 @@
if(pri->filter != NULL){
err = dev_netmask(pri->dev, &netmask);
if(err < 0){
- printk("pcap_open : dev_netmask failed\n");
+ printk(UM_KERN_ERR "pcap_open : dev_netmask failed\n");
return -EIO;
}
pri->compiled = um_kmalloc(sizeof(struct bpf_program));
if(pri->compiled == NULL){
- printk("pcap_open : kmalloc failed\n");
+ printk(UM_KERN_ERR "pcap_open : kmalloc failed\n");
return -ENOMEM;
}
@@ -62,15 +63,15 @@
(struct bpf_program *) pri->compiled,
pri->filter, pri->optimize, netmask);
if(err < 0){
- printk("pcap_open : pcap_compile failed - '%s'\n",
- pcap_geterr(pri->pcap));
+ printk(UM_KERN_ERR "pcap_open : pcap_compile failed - "
+ "'%s'\n", pcap_geterr(pri->pcap));
return -EIO;
}
err = pcap_setfilter(pri->pcap, pri->compiled);
if(err < 0){
- printk("pcap_open : pcap_setfilter failed - '%s'\n",
- pcap_geterr(pri->pcap));
+ printk(UM_KERN_ERR "pcap_open : pcap_setfilter "
+ "failed - '%s'\n", pcap_geterr(pri->pcap));
return -EIO;
}
}
@@ -85,7 +86,8 @@
if(pri->compiled != NULL)
pcap_freecode(pri->compiled);
- pcap_close(pri->pcap);
+ if(pri->pcap != NULL)
+ pcap_close(pri->pcap);
}
struct pcap_handler_data {
@@ -114,7 +116,8 @@
n = pcap_dispatch(pri->pcap, 1, handler, (u_char *) &hdata);
if(n < 0){
- printk("pcap_dispatch failed - %s\n", pcap_geterr(pri->pcap));
+ printk(UM_KERN_ERR "pcap_dispatch failed - %s\n",
+ pcap_geterr(pri->pcap));
return -EIO;
}
else if(n == 0)
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c
index cd7349d..259c49d 100644
--- a/arch/um/kernel/time.c
+++ b/arch/um/kernel/time.c
@@ -177,6 +177,8 @@
void timer_handler(int sig, union uml_pt_regs *regs)
{
+ if(current_thread->cpu == 0)
+ timer_irq(regs);
local_irq_disable();
irq_enter();
update_process_times(CHOOSE_MODE(
@@ -184,6 +186,4 @@
(regs)->skas.is_user));
irq_exit();
local_irq_enable();
- if(current_thread->cpu == 0)
- timer_irq(regs);
}
diff --git a/arch/v850/kernel/process.c b/arch/v850/kernel/process.c
index c4f844c..e4a4b8e 100644
--- a/arch/v850/kernel/process.c
+++ b/arch/v850/kernel/process.c
@@ -16,7 +16,6 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
diff --git a/arch/v850/kernel/ptrace.c b/arch/v850/kernel/ptrace.c
index 67e0575..a9b0934 100644
--- a/arch/v850/kernel/ptrace.c
+++ b/arch/v850/kernel/ptrace.c
@@ -21,7 +21,6 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/sched.h>
-#include <linux/smp_lock.h>
#include <linux/ptrace.h>
#include <linux/signal.h>
diff --git a/arch/v850/kernel/signal.c b/arch/v850/kernel/signal.c
index 17c2d43..bf166e7 100644
--- a/arch/v850/kernel/signal.c
+++ b/arch/v850/kernel/signal.c
@@ -17,7 +17,6 @@
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/v850/kernel/syscalls.c b/arch/v850/kernel/syscalls.c
index d2b1fb1..f9f00cc 100644
--- a/arch/v850/kernel/syscalls.c
+++ b/arch/v850/kernel/syscalls.c
@@ -18,7 +18,6 @@
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/syscalls.h>
#include <linux/sem.h>
#include <linux/msg.h>
diff --git a/arch/x86_64/ia32/ia32_signal.c b/arch/x86_64/ia32/ia32_signal.c
index 359eacc..6ea19c2 100644
--- a/arch/x86_64/ia32/ia32_signal.c
+++ b/arch/x86_64/ia32/ia32_signal.c
@@ -11,7 +11,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S
index c48087d..f210683 100644
--- a/arch/x86_64/ia32/ia32entry.S
+++ b/arch/x86_64/ia32/ia32entry.S
@@ -710,9 +710,10 @@
.quad compat_sys_get_robust_list
.quad sys_splice
.quad sys_sync_file_range
- .quad sys_tee
+ .quad sys_tee /* 315 */
.quad compat_sys_vmsplice
.quad compat_sys_move_pages
.quad sys_getcpu
.quad sys_epoll_pwait
+ .quad compat_sys_utimensat /* 320 */
ia32_syscall_end:
diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile
index 4d94c51..de1de8a 100644
--- a/arch/x86_64/kernel/Makefile
+++ b/arch/x86_64/kernel/Makefile
@@ -32,6 +32,7 @@
obj-$(CONFIG_IOMMU) += pci-gart.o aperture.o
obj-$(CONFIG_CALGARY_IOMMU) += pci-calgary.o tce.o
obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o
+obj-$(CONFIG_SERIAL_8250) += legacy_serial.o
obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_X86_PM_TIMER) += pmtimer.o
obj-$(CONFIG_X86_VSMP) += vsmp.o
@@ -49,6 +50,7 @@
therm_throt-y += ../../i386/kernel/cpu/mcheck/therm_throt.o
bootflag-y += ../../i386/kernel/bootflag.o
+legacy_serial-y += ../../i386/kernel/legacy_serial.o
cpuid-$(subst m,y,$(CONFIG_X86_CPUID)) += ../../i386/kernel/cpuid.o
topology-y += ../../i386/kernel/topology.o
microcode-$(subst m,y,$(CONFIG_MICROCODE)) += ../../i386/kernel/microcode.o
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
index d198f7d..1b0e07b 100644
--- a/arch/x86_64/kernel/apic.c
+++ b/arch/x86_64/kernel/apic.c
@@ -19,7 +19,6 @@
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/bootmem.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/mc146818rtc.h>
#include <linux/kernel_stat.h>
diff --git a/arch/x86_64/kernel/crash.c b/arch/x86_64/kernel/crash.c
index 95a7a2c..13432a1 100644
--- a/arch/x86_64/kernel/crash.c
+++ b/arch/x86_64/kernel/crash.c
@@ -17,13 +17,13 @@
#include <linux/delay.h>
#include <linux/elf.h>
#include <linux/elfcore.h>
+#include <linux/kdebug.h>
#include <asm/processor.h>
#include <asm/hardirq.h>
#include <asm/nmi.h>
#include <asm/hw_irq.h>
#include <asm/mach_apic.h>
-#include <asm/kdebug.h>
/* This keeps a track of which one is crashing cpu. */
static int crashing_cpu;
diff --git a/arch/x86_64/kernel/early_printk.c b/arch/x86_64/kernel/early_printk.c
index 92213d2..56eaa25 100644
--- a/arch/x86_64/kernel/early_printk.c
+++ b/arch/x86_64/kernel/early_printk.c
@@ -243,22 +243,12 @@
early_console = &simnow_console;
keep_early = 1;
}
+
+ if (keep_early)
+ early_console->flags &= ~CON_BOOT;
+ else
+ early_console->flags |= CON_BOOT;
register_console(early_console);
return 0;
}
-
early_param("earlyprintk", setup_early_printk);
-
-void __init disable_early_printk(void)
-{
- if (!early_console_initialized || !early_console)
- return;
- if (!keep_early) {
- printk("disabling early console\n");
- unregister_console(early_console);
- early_console_initialized = 0;
- } else {
- printk("keeping early console\n");
- }
-}
-
diff --git a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c
index 4894266..4b32665 100644
--- a/arch/x86_64/kernel/i8259.c
+++ b/arch/x86_64/kernel/i8259.c
@@ -7,7 +7,6 @@
#include <linux/timex.h>
#include <linux/slab.h>
#include <linux/random.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/kernel_stat.h>
#include <linux/sysdev.h>
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
index 2a2df14..4d58258 100644
--- a/arch/x86_64/kernel/io_apic.c
+++ b/arch/x86_64/kernel/io_apic.c
@@ -25,7 +25,6 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/sched.h>
-#include <linux/smp_lock.h>
#include <linux/pci.h>
#include <linux/mc146818rtc.h>
#include <linux/acpi.h>
diff --git a/arch/x86_64/kernel/ioport.c b/arch/x86_64/kernel/ioport.c
index 387d347..653efa3 100644
--- a/arch/x86_64/kernel/ioport.c
+++ b/arch/x86_64/kernel/ioport.c
@@ -12,7 +12,6 @@
#include <linux/types.h>
#include <linux/ioport.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/slab.h>
#include <linux/thread_info.h>
diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c
index 209c8c0..d4a0d0a 100644
--- a/arch/x86_64/kernel/kprobes.c
+++ b/arch/x86_64/kernel/kprobes.c
@@ -37,10 +37,10 @@
#include <linux/slab.h>
#include <linux/preempt.h>
#include <linux/module.h>
+#include <linux/kdebug.h>
#include <asm/cacheflush.h>
#include <asm/pgtable.h>
-#include <asm/kdebug.h>
#include <asm/uaccess.h>
void jprobe_return_end(void);
@@ -266,23 +266,14 @@
}
/* Called with kretprobe_lock held */
-void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
+void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
struct pt_regs *regs)
{
unsigned long *sara = (unsigned long *)regs->rsp;
- struct kretprobe_instance *ri;
- if ((ri = get_free_rp_inst(rp)) != NULL) {
- ri->rp = rp;
- ri->task = current;
- ri->ret_addr = (kprobe_opcode_t *) *sara;
-
- /* Replace the return addr with trampoline addr */
- *sara = (unsigned long) &kretprobe_trampoline;
- add_rp_inst(ri);
- } else {
- rp->nmissed++;
- }
+ ri->ret_addr = (kprobe_opcode_t *) *sara;
+ /* Replace the return addr with trampoline addr */
+ *sara = (unsigned long) &kretprobe_trampoline;
}
int __kprobes kprobe_handler(struct pt_regs *regs)
@@ -447,7 +438,7 @@
break;
}
- BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
+ kretprobe_assert(ri, orig_ret_address, trampoline_address);
regs->rip = orig_ret_address;
reset_current_kprobe();
@@ -752,3 +743,11 @@
{
return register_kprobe(&trampoline_p);
}
+
+int __kprobes arch_trampoline_kprobe(struct kprobe *p)
+{
+ if (p->addr == (kprobe_opcode_t *)&kretprobe_trampoline)
+ return 1;
+
+ return 0;
+}
diff --git a/arch/x86_64/kernel/ldt.c b/arch/x86_64/kernel/ldt.c
index d7e5d0c..bc9ffd5 100644
--- a/arch/x86_64/kernel/ldt.c
+++ b/arch/x86_64/kernel/ldt.c
@@ -13,7 +13,6 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/vmalloc.h>
#include <linux/slab.h>
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c
index fa26726..44216964 100644
--- a/arch/x86_64/kernel/mce.c
+++ b/arch/x86_64/kernel/mce.c
@@ -20,10 +20,10 @@
#include <linux/percpu.h>
#include <linux/ctype.h>
#include <linux/kmod.h>
+#include <linux/kdebug.h>
#include <asm/processor.h>
#include <asm/msr.h>
#include <asm/mce.h>
-#include <asm/kdebug.h>
#include <asm/uaccess.h>
#include <asm/smp.h>
diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c
index d0dc489..61ae57e 100644
--- a/arch/x86_64/kernel/mpparse.c
+++ b/arch/x86_64/kernel/mpparse.c
@@ -17,7 +17,6 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/bootmem.h>
-#include <linux/smp_lock.h>
#include <linux/kernel_stat.h>
#include <linux/mc146818rtc.h>
#include <linux/acpi.h>
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c
index 6cd2b30..931c64b 100644
--- a/arch/x86_64/kernel/nmi.c
+++ b/arch/x86_64/kernel/nmi.c
@@ -21,11 +21,11 @@
#include <linux/sysctl.h>
#include <linux/kprobes.h>
#include <linux/cpumask.h>
+#include <linux/kdebug.h>
#include <asm/smp.h>
#include <asm/nmi.h>
#include <asm/proto.h>
-#include <asm/kdebug.h>
#include <asm/mce.h>
int unknown_nmi_panic;
diff --git a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c
index 0a762e1..373ef66 100644
--- a/arch/x86_64/kernel/pci-gart.c
+++ b/arch/x86_64/kernel/pci-gart.c
@@ -22,13 +22,13 @@
#include <linux/topology.h>
#include <linux/interrupt.h>
#include <linux/bitops.h>
+#include <linux/kdebug.h>
#include <asm/atomic.h>
#include <asm/io.h>
#include <asm/mtrr.h>
#include <asm/pgtable.h>
#include <asm/proto.h>
#include <asm/cacheflush.h>
-#include <asm/kdebug.h>
#include <asm/swiotlb.h>
#include <asm/dma.h>
#include <asm/k8.h>
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index 4f21765..5909039 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -36,6 +36,7 @@
#include <linux/random.h>
#include <linux/notifier.h>
#include <linux/kprobes.h>
+#include <linux/kdebug.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
@@ -46,7 +47,6 @@
#include <asm/mmu_context.h>
#include <asm/pda.h>
#include <asm/prctl.h>
-#include <asm/kdebug.h>
#include <asm/desc.h>
#include <asm/proto.h>
#include <asm/ia32.h>
diff --git a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c
index 4326a69..9409117 100644
--- a/arch/x86_64/kernel/ptrace.c
+++ b/arch/x86_64/kernel/ptrace.c
@@ -11,7 +11,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
diff --git a/arch/x86_64/kernel/reboot.c b/arch/x86_64/kernel/reboot.c
index 2d67698..c116b54 100644
--- a/arch/x86_64/kernel/reboot.c
+++ b/arch/x86_64/kernel/reboot.c
@@ -7,8 +7,8 @@
#include <linux/ctype.h>
#include <linux/string.h>
#include <linux/pm.h>
+#include <linux/kdebug.h>
#include <asm/io.h>
-#include <asm/kdebug.h>
#include <asm/delay.h>
#include <asm/hw_irq.h>
#include <asm/system.h>
diff --git a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c
index c819625..290f5d8 100644
--- a/arch/x86_64/kernel/signal.c
+++ b/arch/x86_64/kernel/signal.c
@@ -12,7 +12,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c
index bd1d123..2ff4685 100644
--- a/arch/x86_64/kernel/smp.c
+++ b/arch/x86_64/kernel/smp.c
@@ -14,7 +14,6 @@
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
#include <linux/smp.h>
#include <linux/kernel_stat.h>
#include <linux/mc146818rtc.h>
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index 4d9dacf..32f5078 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -42,18 +42,17 @@
#include <linux/mm.h>
#include <linux/kernel_stat.h>
-#include <linux/smp_lock.h>
#include <linux/bootmem.h>
#include <linux/thread_info.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/mc146818rtc.h>
#include <linux/smp.h>
+#include <linux/kdebug.h>
#include <asm/mtrr.h>
#include <asm/pgalloc.h>
#include <asm/desc.h>
-#include <asm/kdebug.h>
#include <asm/tlbflush.h>
#include <asm/proto.h>
#include <asm/nmi.h>
diff --git a/arch/x86_64/kernel/stacktrace.c b/arch/x86_64/kernel/stacktrace.c
index 65ac2c6..cb91091 100644
--- a/arch/x86_64/kernel/stacktrace.c
+++ b/arch/x86_64/kernel/stacktrace.c
@@ -21,8 +21,7 @@
static int save_stack_stack(void *data, char *name)
{
- struct stack_trace *trace = (struct stack_trace *)data;
- return trace->all_contexts ? 0 : -1;
+ return -1;
}
static void save_stack_address(void *data, unsigned long addr)
@@ -46,11 +45,10 @@
/*
* Save stack-backtrace addresses into a stack_trace buffer.
*/
-void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
+void save_stack_trace(struct stack_trace *trace)
{
- dump_trace(task, NULL, NULL, &save_stack_ops, trace);
+ dump_trace(current, NULL, NULL, &save_stack_ops, trace);
if (trace->nr_entries < trace->max_entries)
trace->entries[trace->nr_entries++] = ULONG_MAX;
}
EXPORT_SYMBOL(save_stack_trace);
-
diff --git a/arch/x86_64/kernel/sys_x86_64.c b/arch/x86_64/kernel/sys_x86_64.c
index f891931..d067d9a 100644
--- a/arch/x86_64/kernel/sys_x86_64.c
+++ b/arch/x86_64/kernel/sys_x86_64.c
@@ -7,7 +7,6 @@
#include <linux/syscalls.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
index 0652e17..4a0895b 100644
--- a/arch/x86_64/kernel/time.c
+++ b/arch/x86_64/kernel/time.c
@@ -363,7 +363,10 @@
}
static struct irqaction irq0 = {
- timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL
+ .handler = timer_interrupt,
+ .flags = IRQF_DISABLED | IRQF_IRQPOLL,
+ .mask = CPU_MASK_NONE,
+ .name = "timer"
};
void __init time_init(void)
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index d76fc32..8c2ac41 100644
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -32,6 +32,7 @@
#include <linux/unwind.h>
#include <linux/uaccess.h>
#include <linux/bug.h>
+#include <linux/kdebug.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -39,7 +40,6 @@
#include <asm/debugreg.h>
#include <asm/desc.h>
#include <asm/i387.h>
-#include <asm/kdebug.h>
#include <asm/processor.h>
#include <asm/unwind.h>
#include <asm/smp.h>
@@ -71,22 +71,6 @@
asmlinkage void machine_check(void);
asmlinkage void spurious_interrupt_bug(void);
-ATOMIC_NOTIFIER_HEAD(die_chain);
-EXPORT_SYMBOL(die_chain);
-
-int register_die_notifier(struct notifier_block *nb)
-{
- vmalloc_sync_all();
- return atomic_notifier_chain_register(&die_chain, nb);
-}
-EXPORT_SYMBOL(register_die_notifier); /* used modular by kdb */
-
-int unregister_die_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_unregister(&die_chain, nb);
-}
-EXPORT_SYMBOL(unregister_die_notifier); /* used modular by kdb */
-
static inline void conditional_sti(struct pt_regs *regs)
{
if (regs->eflags & X86_EFLAGS_IF)
@@ -792,6 +776,8 @@
*/
if (nmi_watchdog_tick(regs,reason))
return;
+ if (notify_die(DIE_NMI_POST, "nmi_post", regs, reason, 2, 0)
+ == NOTIFY_STOP)
if (!do_nmi_callback(regs,cpu))
unknown_nmi_error(reason, regs);
diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c
index de99dba..bfb62a1 100644
--- a/arch/x86_64/mm/fault.c
+++ b/arch/x86_64/mm/fault.c
@@ -15,22 +15,22 @@
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/tty.h>
#include <linux/vt_kern.h> /* For unblank_screen() */
#include <linux/compiler.h>
+#include <linux/vmalloc.h>
#include <linux/module.h>
#include <linux/kprobes.h>
#include <linux/uaccess.h>
+#include <linux/kdebug.h>
#include <asm/system.h>
#include <asm/pgalloc.h>
#include <asm/smp.h>
#include <asm/tlbflush.h>
#include <asm/proto.h>
-#include <asm/kdebug.h>
#include <asm-generic/sections.h>
/* Page fault error code bits */
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c
index c082268..1336da8 100644
--- a/arch/x86_64/mm/init.c
+++ b/arch/x86_64/mm/init.c
@@ -172,7 +172,7 @@
set_pte_phys(address, phys, prot);
}
-unsigned long __initdata table_start, table_end;
+unsigned long __meminitdata table_start, table_end;
static __meminit void *alloc_low_page(unsigned long *phys)
{
@@ -204,7 +204,7 @@
}
/* Must run before zap_low_mappings */
-__init void *early_ioremap(unsigned long addr, unsigned long size)
+__meminit void *early_ioremap(unsigned long addr, unsigned long size)
{
unsigned long vaddr;
pmd_t *pmd, *last_pmd;
@@ -233,7 +233,7 @@
}
/* To avoid virtual aliases later */
-__init void early_iounmap(void *addr, unsigned long size)
+__meminit void early_iounmap(void *addr, unsigned long size)
{
unsigned long vaddr;
pmd_t *pmd;
diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c
index 795bd5a..ce758ba 100644
--- a/arch/xtensa/kernel/process.c
+++ b/arch/xtensa/kernel/process.c
@@ -20,7 +20,6 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c
index 8b6d3d0..14104ff 100644
--- a/arch/xtensa/kernel/ptrace.c
+++ b/arch/xtensa/kernel/ptrace.c
@@ -19,7 +19,6 @@
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/security.h>
#include <linux/signal.h>
diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c
index c6d9880..5810767 100644
--- a/arch/xtensa/kernel/signal.c
+++ b/arch/xtensa/kernel/signal.c
@@ -17,7 +17,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/block/as-iosched.c b/block/as-iosched.c
index ef12627..640aa83 100644
--- a/block/as-iosched.c
+++ b/block/as-iosched.c
@@ -569,7 +569,7 @@
static int as_close_req(struct as_data *ad, struct as_io_context *aic,
struct request *rq)
{
- unsigned long delay; /* milliseconds */
+ unsigned long delay; /* jiffies */
sector_t last = ad->last_sector[ad->batch_data_dir];
sector_t next = rq->sector;
sector_t delta; /* acceptable close offset (in sectors) */
@@ -578,11 +578,11 @@
if (ad->antic_status == ANTIC_OFF || !ad->ioc_finished)
delay = 0;
else
- delay = ((jiffies - ad->antic_start) * 1000) / HZ;
+ delay = jiffies - ad->antic_start;
if (delay == 0)
delta = 8192;
- else if (delay <= 20 && delay <= ad->antic_expire)
+ else if (delay <= (20 * HZ / 1000) && delay <= ad->antic_expire)
delta = 8192 << delay;
else
return 1;
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 5873861..d99d402 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -2558,6 +2558,7 @@
bio->bi_rw |= (1 << BIO_RW);
blk_rq_bio_prep(q, rq, bio);
+ blk_queue_bounce(q, &rq->bio);
rq->buffer = rq->data = NULL;
return 0;
}
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 4334c20..41427a4 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -245,6 +245,35 @@
#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
+#ifdef CONFIG_PM
+static u32 rtc_handler(void *context)
+{
+ acpi_clear_event(ACPI_EVENT_RTC);
+ acpi_disable_event(ACPI_EVENT_RTC, 0);
+ return ACPI_INTERRUPT_HANDLED;
+}
+
+static inline void rtc_wake_setup(void)
+{
+ acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL);
+}
+
+static void rtc_wake_on(struct device *dev)
+{
+ acpi_clear_event(ACPI_EVENT_RTC);
+ acpi_enable_event(ACPI_EVENT_RTC, 0);
+}
+
+static void rtc_wake_off(struct device *dev)
+{
+ acpi_disable_event(ACPI_EVENT_RTC, 0);
+}
+#else
+#define rtc_wake_setup() do{}while(0)
+#define rtc_wake_on NULL
+#define rtc_wake_off NULL
+#endif
+
/* Every ACPI platform has a mc146818 compatible "cmos rtc". Here we find
* its device node and pass extra config data. This helps its driver use
* capabilities that the now-obsolete mc146818 didn't have, and informs it
@@ -283,11 +312,24 @@
struct device *dev = get_rtc_dev();
if (dev) {
+ rtc_wake_setup();
+ rtc_info.wake_on = rtc_wake_on;
+ rtc_info.wake_off = rtc_wake_off;
+
+ /* workaround bug in some ACPI tables */
+ if (acpi_gbl_FADT.month_alarm && !acpi_gbl_FADT.day_alarm) {
+ DBG("bogus FADT month_alarm\n");
+ acpi_gbl_FADT.month_alarm = 0;
+ }
+
rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm;
rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm;
rtc_info.rtc_century = acpi_gbl_FADT.century;
- /* NOTE: acpi_gbl_FADT->rtcs4 is NOT currently useful */
+ /* NOTE: S4_RTC_WAKE is NOT currently useful to Linux */
+ if (acpi_gbl_FADT.flags & ACPI_FADT_S4_RTC_WAKE)
+ printk(PREFIX "RTC can wake from S4\n");
+
dev->platform_data = &rtc_info;
@@ -296,7 +338,7 @@
put_device(dev);
} else
- pr_debug("ACPI: RTC unavailable?\n");
+ DBG("RTC unavailable?\n");
return 0;
}
/* do this between RTC subsys_initcall() and rtc_cmos driver_initcall() */
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
index 8fcd6a1..4dd0dab 100644
--- a/drivers/acpi/numa.c
+++ b/drivers/acpi/numa.c
@@ -228,7 +228,7 @@
return 0;
}
-int acpi_get_pxm(acpi_handle h)
+int __meminit acpi_get_pxm(acpi_handle h)
{
unsigned long pxm;
acpi_status status;
@@ -246,7 +246,7 @@
}
EXPORT_SYMBOL(acpi_get_pxm);
-int acpi_get_node(acpi_handle *handle)
+int __meminit acpi_get_node(acpi_handle *handle)
{
int pxm, node = -1;
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 971eca4..c2bed56 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -30,7 +30,6 @@
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/pci.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/kmod.h>
#include <linux/delay.h>
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index d80dd84..6b3b8a5 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -302,7 +302,7 @@
return ;
}
-static struct bus_type acpi_bus_type = {
+struct bus_type acpi_bus_type = {
.name = "acpi",
.suspend = acpi_device_suspend,
.resume = acpi_device_resume,
diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c
index dcde9dd..5a76e5b 100644
--- a/drivers/acpi/sleep/proc.c
+++ b/drivers/acpi/sleep/proc.c
@@ -70,6 +70,14 @@
}
#endif /* CONFIG_ACPI_SLEEP_PROC_SLEEP */
+#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
+/* use /sys/class/rtc/rtcX/wakealarm instead; it's not ACPI-specific */
+#else
+#define HAVE_ACPI_LEGACY_ALARM
+#endif
+
+#ifdef HAVE_ACPI_LEGACY_ALARM
+
static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
{
u32 sec, min, hr;
@@ -341,6 +349,8 @@
end:
return_VALUE(result ? result : count);
}
+#endif /* HAVE_ACPI_LEGACY_ALARM */
+
extern struct list_head acpi_wakeup_device_list;
extern spinlock_t acpi_device_lock;
@@ -464,6 +474,7 @@
};
#endif /* CONFIG_ACPI_SLEEP_PROC_SLEEP */
+#ifdef HAVE_ACPI_LEGACY_ALARM
static const struct file_operations acpi_system_alarm_fops = {
.open = acpi_system_alarm_open_fs,
.read = seq_read,
@@ -479,8 +490,9 @@
return ACPI_INTERRUPT_HANDLED;
}
+#endif /* HAVE_ACPI_LEGACY_ALARM */
-static int acpi_sleep_proc_init(void)
+static int __init acpi_sleep_proc_init(void)
{
struct proc_dir_entry *entry = NULL;
@@ -496,6 +508,7 @@
entry->proc_fops = &acpi_system_sleep_fops;
#endif
+#ifdef HAVE_ACPI_LEGACY_ALARM
/* 'alarm' [R/W] */
entry =
create_proc_entry("alarm", S_IFREG | S_IRUGO | S_IWUSR,
@@ -503,6 +516,9 @@
if (entry)
entry->proc_fops = &acpi_system_alarm_fops;
+ acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL);
+#endif /* HAVE_ACPI_LEGACY_ALARM */
+
/* 'wakeup device' [R/W] */
entry =
create_proc_entry("wakeup", S_IFREG | S_IRUGO | S_IWUSR,
@@ -510,7 +526,6 @@
if (entry)
entry->proc_fops = &acpi_system_wakeup_device_fops;
- acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL);
return 0;
}
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c
index cc07aac..1724673 100644
--- a/drivers/ata/sata_svw.c
+++ b/drivers/ata/sata_svw.c
@@ -288,7 +288,7 @@
/* Match it to a port node */
index = (ap == ap->host->ports[0]) ? 0 : 1;
for (np = np->child; np != NULL; np = np->sibling) {
- const u32 *reg = get_property(np, "reg", NULL);
+ const u32 *reg = of_get_property(np, "reg", NULL);
if (!reg)
continue;
if (index == *reg)
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 17b5ece..eb84d9d 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -160,6 +160,11 @@
*
* Create a platform device object which can have other objects attached
* to it, and which will have attached objects freed when it is released.
+ *
+ * This device will be marked as not supporting hotpluggable drivers; no
+ * device add/remove uevents will be generated. In the unusual case that
+ * the device isn't being dynamically allocated as a legacy "probe the
+ * hardware" driver, infrastructure code should reverse this marking.
*/
struct platform_device *platform_device_alloc(const char *name, unsigned int id)
{
@@ -172,6 +177,12 @@
pa->pdev.id = id;
device_initialize(&pa->pdev.dev);
pa->pdev.dev.release = platform_device_release;
+
+ /* prevent hotplug "modprobe $(MODALIAS)" from causing trouble in
+ * legacy probe-the-hardware drivers, which don't properly split
+ * out device enumeration logic from drivers.
+ */
+ pa->pdev.dev.uevent_suppress = 1;
}
return pa ? &pa->pdev : NULL;
@@ -351,6 +362,13 @@
* memory allocated for the device allows drivers using such devices
* to be unloaded iwithout waiting for the last reference to the device
* to be dropped.
+ *
+ * This interface is primarily intended for use with legacy drivers
+ * which probe hardware directly. Because such drivers create sysfs
+ * device nodes themselves, rather than letting system infrastructure
+ * handle such device enumeration tasks, they don't fully conform to
+ * the Linux driver model. In particular, when such drivers are built
+ * as modules, they can't be "hotplugged".
*/
struct platform_device *platform_device_register_simple(char *name, unsigned int id,
struct resource *res, unsigned int num)
diff --git a/drivers/block/acsi_slm.c b/drivers/block/acsi_slm.c
index e2e0432..1d9d9b4 100644
--- a/drivers/block/acsi_slm.c
+++ b/drivers/block/acsi_slm.c
@@ -65,7 +65,6 @@
#include <linux/time.h>
#include <linux/mm.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <asm/pgtable.h>
#include <asm/system.h>
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 65a725c..370dfe1 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -45,6 +45,10 @@
#include <linux/blkdev.h>
#include <linux/genhd.h>
#include <linux/completion.h>
+#include <scsi/scsi.h>
+#include <scsi/sg.h>
+#include <scsi/scsi_ioctl.h>
+#include <linux/cdrom.h>
#define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
#define DRIVER_NAME "HP CISS Driver (v 3.6.14)"
@@ -1152,6 +1156,30 @@
kfree(ioc);
return status;
}
+
+ /* scsi_cmd_ioctl handles these, below, though some are not */
+ /* very meaningful for cciss. SG_IO is the main one people want. */
+
+ case SG_GET_VERSION_NUM:
+ case SG_SET_TIMEOUT:
+ case SG_GET_TIMEOUT:
+ case SG_GET_RESERVED_SIZE:
+ case SG_SET_RESERVED_SIZE:
+ case SG_EMULATED_HOST:
+ case SG_IO:
+ case SCSI_IOCTL_SEND_COMMAND:
+ return scsi_cmd_ioctl(filep, disk, cmd, argp);
+
+ /* scsi_cmd_ioctl would normally handle these, below, but */
+ /* they aren't a good fit for cciss, as CD-ROMs are */
+ /* not supported, and we don't have any bus/target/lun */
+ /* which we present to the kernel. */
+
+ case CDROM_SEND_PACKET:
+ case CDROMCLOSETRAY:
+ case CDROMEJECT:
+ case SCSI_IOCTL_GET_IDLUN:
+ case SCSI_IOCTL_GET_BUS_NUMBER:
default:
return -ENOTTY;
}
@@ -1234,7 +1262,7 @@
pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir);
}
- complete_buffers(rq->bio, rq->errors);
+ complete_buffers(rq->bio, (rq->errors == 0));
if (blk_fs_request(rq)) {
const int rw = rq_data_dir(rq);
@@ -1248,7 +1276,7 @@
add_disk_randomness(rq->rq_disk);
spin_lock_irqsave(&h->lock, flags);
- end_that_request_last(rq, rq->errors);
+ end_that_request_last(rq, (rq->errors == 0));
cmd_free(h, cmd, 1);
cciss_check_queues(h);
spin_unlock_irqrestore(&h->lock, flags);
@@ -2336,6 +2364,44 @@
start_io(h);
}
+static inline int evaluate_target_status(CommandList_struct *cmd)
+{
+ unsigned char sense_key;
+ int error_count = 1;
+
+ if (cmd->err_info->ScsiStatus != 0x02) { /* not check condition? */
+ if (!blk_pc_request(cmd->rq))
+ printk(KERN_WARNING "cciss: cmd %p "
+ "has SCSI Status 0x%x\n",
+ cmd, cmd->err_info->ScsiStatus);
+ return error_count;
+ }
+
+ /* check the sense key */
+ sense_key = 0xf & cmd->err_info->SenseInfo[2];
+ /* no status or recovered error */
+ if ((sense_key == 0x0) || (sense_key == 0x1))
+ error_count = 0;
+
+ if (!blk_pc_request(cmd->rq)) { /* Not SG_IO or similar? */
+ if (error_count != 0)
+ printk(KERN_WARNING "cciss: cmd %p has CHECK CONDITION"
+ " sense key = 0x%x\n", cmd, sense_key);
+ return error_count;
+ }
+
+ /* SG_IO or similar, copy sense data back */
+ if (cmd->rq->sense) {
+ if (cmd->rq->sense_len > cmd->err_info->SenseLen)
+ cmd->rq->sense_len = cmd->err_info->SenseLen;
+ memcpy(cmd->rq->sense, cmd->err_info->SenseInfo,
+ cmd->rq->sense_len);
+ } else
+ cmd->rq->sense_len = 0;
+
+ return error_count;
+}
+
/* checks the status of the job and calls complete buffers to mark all
* buffers for the completed job. Note that this function does not need
* to hold the hba/queue lock.
@@ -2343,109 +2409,99 @@
static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd,
int timeout)
{
- int status = 1;
int retry_cmd = 0;
+ struct request *rq = cmd->rq;
+
+ rq->errors = 0;
if (timeout)
- status = 0;
+ rq->errors = 1;
- if (cmd->err_info->CommandStatus != 0) { /* an error has occurred */
- switch (cmd->err_info->CommandStatus) {
- unsigned char sense_key;
- case CMD_TARGET_STATUS:
- status = 0;
+ if (cmd->err_info->CommandStatus == 0) /* no error has occurred */
+ goto after_error_processing;
- if (cmd->err_info->ScsiStatus == 0x02) {
- printk(KERN_WARNING "cciss: cmd %p "
- "has CHECK CONDITION "
- " byte 2 = 0x%x\n", cmd,
- cmd->err_info->SenseInfo[2]
- );
- /* check the sense key */
- sense_key = 0xf & cmd->err_info->SenseInfo[2];
- /* no status or recovered error */
- if ((sense_key == 0x0) || (sense_key == 0x1)) {
- status = 1;
- }
- } else {
- printk(KERN_WARNING "cciss: cmd %p "
- "has SCSI Status 0x%x\n",
- cmd, cmd->err_info->ScsiStatus);
- }
- break;
- case CMD_DATA_UNDERRUN:
+ switch (cmd->err_info->CommandStatus) {
+ case CMD_TARGET_STATUS:
+ rq->errors = evaluate_target_status(cmd);
+ break;
+ case CMD_DATA_UNDERRUN:
+ if (blk_fs_request(cmd->rq)) {
printk(KERN_WARNING "cciss: cmd %p has"
" completed with data underrun "
"reported\n", cmd);
- break;
- case CMD_DATA_OVERRUN:
+ cmd->rq->data_len = cmd->err_info->ResidualCnt;
+ }
+ break;
+ case CMD_DATA_OVERRUN:
+ if (blk_fs_request(cmd->rq))
printk(KERN_WARNING "cciss: cmd %p has"
" completed with data overrun "
"reported\n", cmd);
- break;
- case CMD_INVALID:
- printk(KERN_WARNING "cciss: cmd %p is "
- "reported invalid\n", cmd);
- status = 0;
- break;
- case CMD_PROTOCOL_ERR:
- printk(KERN_WARNING "cciss: cmd %p has "
- "protocol error \n", cmd);
- status = 0;
- break;
- case CMD_HARDWARE_ERR:
- printk(KERN_WARNING "cciss: cmd %p had "
- " hardware error\n", cmd);
- status = 0;
- break;
- case CMD_CONNECTION_LOST:
- printk(KERN_WARNING "cciss: cmd %p had "
- "connection lost\n", cmd);
- status = 0;
- break;
- case CMD_ABORTED:
- printk(KERN_WARNING "cciss: cmd %p was "
- "aborted\n", cmd);
- status = 0;
- break;
- case CMD_ABORT_FAILED:
- printk(KERN_WARNING "cciss: cmd %p reports "
- "abort failed\n", cmd);
- status = 0;
- break;
- case CMD_UNSOLICITED_ABORT:
- printk(KERN_WARNING "cciss%d: unsolicited "
- "abort %p\n", h->ctlr, cmd);
- if (cmd->retry_count < MAX_CMD_RETRIES) {
- retry_cmd = 1;
- printk(KERN_WARNING
- "cciss%d: retrying %p\n", h->ctlr, cmd);
- cmd->retry_count++;
- } else
- printk(KERN_WARNING
- "cciss%d: %p retried too "
- "many times\n", h->ctlr, cmd);
- status = 0;
- break;
- case CMD_TIMEOUT:
- printk(KERN_WARNING "cciss: cmd %p timedout\n", cmd);
- status = 0;
- break;
- default:
- printk(KERN_WARNING "cciss: cmd %p returned "
- "unknown status %x\n", cmd,
- cmd->err_info->CommandStatus);
- status = 0;
- }
+ break;
+ case CMD_INVALID:
+ printk(KERN_WARNING "cciss: cmd %p is "
+ "reported invalid\n", cmd);
+ rq->errors = 1;
+ break;
+ case CMD_PROTOCOL_ERR:
+ printk(KERN_WARNING "cciss: cmd %p has "
+ "protocol error \n", cmd);
+ rq->errors = 1;
+ break;
+ case CMD_HARDWARE_ERR:
+ printk(KERN_WARNING "cciss: cmd %p had "
+ " hardware error\n", cmd);
+ rq->errors = 1;
+ break;
+ case CMD_CONNECTION_LOST:
+ printk(KERN_WARNING "cciss: cmd %p had "
+ "connection lost\n", cmd);
+ rq->errors = 1;
+ break;
+ case CMD_ABORTED:
+ printk(KERN_WARNING "cciss: cmd %p was "
+ "aborted\n", cmd);
+ rq->errors = 1;
+ break;
+ case CMD_ABORT_FAILED:
+ printk(KERN_WARNING "cciss: cmd %p reports "
+ "abort failed\n", cmd);
+ rq->errors = 1;
+ break;
+ case CMD_UNSOLICITED_ABORT:
+ printk(KERN_WARNING "cciss%d: unsolicited "
+ "abort %p\n", h->ctlr, cmd);
+ if (cmd->retry_count < MAX_CMD_RETRIES) {
+ retry_cmd = 1;
+ printk(KERN_WARNING
+ "cciss%d: retrying %p\n", h->ctlr, cmd);
+ cmd->retry_count++;
+ } else
+ printk(KERN_WARNING
+ "cciss%d: %p retried too "
+ "many times\n", h->ctlr, cmd);
+ rq->errors = 1;
+ break;
+ case CMD_TIMEOUT:
+ printk(KERN_WARNING "cciss: cmd %p timedout\n", cmd);
+ rq->errors = 1;
+ break;
+ default:
+ printk(KERN_WARNING "cciss: cmd %p returned "
+ "unknown status %x\n", cmd,
+ cmd->err_info->CommandStatus);
+ rq->errors = 1;
}
+
+after_error_processing:
+
/* We need to return this command */
if (retry_cmd) {
resend_cciss_cmd(h, cmd);
return;
}
-
+ cmd->rq->data_len = 0;
cmd->rq->completion_data = cmd;
- cmd->rq->errors = status;
blk_add_trace_rq(cmd->rq->q, cmd->rq, BLK_TA_COMPLETE);
blk_complete_request(cmd->rq);
}
@@ -2539,32 +2595,40 @@
#endif /* CCISS_DEBUG */
c->Header.SGList = c->Header.SGTotal = seg;
- if(h->cciss_read == CCISS_READ_10) {
- c->Request.CDB[1] = 0;
- c->Request.CDB[2] = (start_blk >> 24) & 0xff; //MSB
- c->Request.CDB[3] = (start_blk >> 16) & 0xff;
- c->Request.CDB[4] = (start_blk >> 8) & 0xff;
- c->Request.CDB[5] = start_blk & 0xff;
- c->Request.CDB[6] = 0; // (sect >> 24) & 0xff; MSB
- c->Request.CDB[7] = (creq->nr_sectors >> 8) & 0xff;
- c->Request.CDB[8] = creq->nr_sectors & 0xff;
- c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0;
+ if (likely(blk_fs_request(creq))) {
+ if(h->cciss_read == CCISS_READ_10) {
+ c->Request.CDB[1] = 0;
+ c->Request.CDB[2] = (start_blk >> 24) & 0xff; //MSB
+ c->Request.CDB[3] = (start_blk >> 16) & 0xff;
+ c->Request.CDB[4] = (start_blk >> 8) & 0xff;
+ c->Request.CDB[5] = start_blk & 0xff;
+ c->Request.CDB[6] = 0; // (sect >> 24) & 0xff; MSB
+ c->Request.CDB[7] = (creq->nr_sectors >> 8) & 0xff;
+ c->Request.CDB[8] = creq->nr_sectors & 0xff;
+ c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0;
+ } else {
+ c->Request.CDBLen = 16;
+ c->Request.CDB[1]= 0;
+ c->Request.CDB[2]= (start_blk >> 56) & 0xff; //MSB
+ c->Request.CDB[3]= (start_blk >> 48) & 0xff;
+ c->Request.CDB[4]= (start_blk >> 40) & 0xff;
+ c->Request.CDB[5]= (start_blk >> 32) & 0xff;
+ c->Request.CDB[6]= (start_blk >> 24) & 0xff;
+ c->Request.CDB[7]= (start_blk >> 16) & 0xff;
+ c->Request.CDB[8]= (start_blk >> 8) & 0xff;
+ c->Request.CDB[9]= start_blk & 0xff;
+ c->Request.CDB[10]= (creq->nr_sectors >> 24) & 0xff;
+ c->Request.CDB[11]= (creq->nr_sectors >> 16) & 0xff;
+ c->Request.CDB[12]= (creq->nr_sectors >> 8) & 0xff;
+ c->Request.CDB[13]= creq->nr_sectors & 0xff;
+ c->Request.CDB[14] = c->Request.CDB[15] = 0;
+ }
+ } else if (blk_pc_request(creq)) {
+ c->Request.CDBLen = creq->cmd_len;
+ memcpy(c->Request.CDB, creq->cmd, BLK_MAX_CDB);
} else {
- c->Request.CDBLen = 16;
- c->Request.CDB[1]= 0;
- c->Request.CDB[2]= (start_blk >> 56) & 0xff; //MSB
- c->Request.CDB[3]= (start_blk >> 48) & 0xff;
- c->Request.CDB[4]= (start_blk >> 40) & 0xff;
- c->Request.CDB[5]= (start_blk >> 32) & 0xff;
- c->Request.CDB[6]= (start_blk >> 24) & 0xff;
- c->Request.CDB[7]= (start_blk >> 16) & 0xff;
- c->Request.CDB[8]= (start_blk >> 8) & 0xff;
- c->Request.CDB[9]= start_blk & 0xff;
- c->Request.CDB[10]= (creq->nr_sectors >> 24) & 0xff;
- c->Request.CDB[11]= (creq->nr_sectors >> 16) & 0xff;
- c->Request.CDB[12]= (creq->nr_sectors >> 8) & 0xff;
- c->Request.CDB[13]= creq->nr_sectors & 0xff;
- c->Request.CDB[14] = c->Request.CDB[15] = 0;
+ printk(KERN_WARNING "cciss%d: bad request type %d\n", h->ctlr, creq->cmd_type);
+ BUG();
}
spin_lock_irq(q->queue_lock);
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
index bb15051..90961a8 100644
--- a/drivers/block/cciss_scsi.c
+++ b/drivers/block/cciss_scsi.c
@@ -35,7 +35,6 @@
#include <asm/atomic.h>
-#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 5231ed7..3587cb4 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -4334,7 +4334,10 @@
if (err)
goto out_flush_work;
- device_create_file(&floppy_device[drive].dev,&dev_attr_cmos);
+ err = device_create_file(&floppy_device[drive].dev,&dev_attr_cmos);
+ if (err)
+ goto out_unreg_platform_dev;
+
/* to be cleaned up... */
disks[drive]->private_data = (void *)(long)drive;
disks[drive]->queue = floppy_queue;
@@ -4345,6 +4348,8 @@
return 0;
+out_unreg_platform_dev:
+ platform_device_unregister(&floppy_device[drive]);
out_flush_work:
flush_scheduled_work();
if (usage_count)
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 0d4ccd4..af6d727 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -77,9 +77,8 @@
#include <asm/uaccess.h>
-static int max_loop = 8;
-static struct loop_device *loop_dev;
-static struct gendisk **disks;
+static LIST_HEAD(loop_devices);
+static DEFINE_MUTEX(loop_devices_mutex);
/*
* Transfer functions
@@ -183,7 +182,7 @@
if (unlikely((loff_t)x != size))
return -EFBIG;
- set_capacity(disks[lo->lo_number], x);
+ set_capacity(lo->lo_disk, x);
return 0;
}
@@ -812,7 +811,7 @@
lo->lo_queue->queuedata = lo;
lo->lo_queue->unplug_fn = loop_unplug;
- set_capacity(disks[lo->lo_number], size);
+ set_capacity(lo->lo_disk, size);
bd_set_size(bdev, size << 9);
set_blocksize(bdev, lo_blocksize);
@@ -832,7 +831,7 @@
lo->lo_device = NULL;
lo->lo_backing_file = NULL;
lo->lo_flags = 0;
- set_capacity(disks[lo->lo_number], 0);
+ set_capacity(lo->lo_disk, 0);
invalidate_bdev(bdev);
bd_set_size(bdev, 0);
mapping_set_gfp_mask(mapping, lo->old_gfp_mask);
@@ -918,7 +917,7 @@
memset(lo->lo_crypt_name, 0, LO_NAME_SIZE);
memset(lo->lo_file_name, 0, LO_NAME_SIZE);
invalidate_bdev(bdev);
- set_capacity(disks[lo->lo_number], 0);
+ set_capacity(lo->lo_disk, 0);
bd_set_size(bdev, 0);
mapping_set_gfp_mask(filp->f_mapping, gfp);
lo->lo_state = Lo_unbound;
@@ -1322,6 +1321,18 @@
}
#endif
+static struct loop_device *loop_find_dev(int number)
+{
+ struct loop_device *lo;
+
+ list_for_each_entry(lo, &loop_devices, lo_list) {
+ if (lo->lo_number == number)
+ return lo;
+ }
+ return NULL;
+}
+
+static struct loop_device *loop_init_one(int i);
static int lo_open(struct inode *inode, struct file *file)
{
struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
@@ -1330,6 +1341,11 @@
lo->lo_refcnt++;
mutex_unlock(&lo->lo_ctl_mutex);
+ mutex_lock(&loop_devices_mutex);
+ if (!loop_find_dev(lo->lo_number + 1))
+ loop_init_one(lo->lo_number + 1);
+ mutex_unlock(&loop_devices_mutex);
+
return 0;
}
@@ -1357,8 +1373,9 @@
/*
* And now the modules code and kernel interface.
*/
+static int max_loop;
module_param(max_loop, int, 0);
-MODULE_PARM_DESC(max_loop, "Maximum number of loop devices (1-256)");
+MODULE_PARM_DESC(max_loop, "obsolete, loop device is created on-demand");
MODULE_LICENSE("GPL");
MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR);
@@ -1383,7 +1400,7 @@
xfer_funcs[n] = NULL;
- for (lo = &loop_dev[0]; lo < &loop_dev[max_loop]; lo++) {
+ list_for_each_entry(lo, &loop_devices, lo_list) {
mutex_lock(&lo->lo_ctl_mutex);
if (lo->lo_encryption == xfer)
@@ -1398,91 +1415,110 @@
EXPORT_SYMBOL(loop_register_transfer);
EXPORT_SYMBOL(loop_unregister_transfer);
+static struct loop_device *loop_init_one(int i)
+{
+ struct loop_device *lo;
+ struct gendisk *disk;
+
+ lo = kzalloc(sizeof(*lo), GFP_KERNEL);
+ if (!lo)
+ goto out;
+
+ lo->lo_queue = blk_alloc_queue(GFP_KERNEL);
+ if (!lo->lo_queue)
+ goto out_free_dev;
+
+ disk = lo->lo_disk = alloc_disk(1);
+ if (!disk)
+ goto out_free_queue;
+
+ mutex_init(&lo->lo_ctl_mutex);
+ lo->lo_number = i;
+ lo->lo_thread = NULL;
+ init_waitqueue_head(&lo->lo_event);
+ spin_lock_init(&lo->lo_lock);
+ disk->major = LOOP_MAJOR;
+ disk->first_minor = i;
+ disk->fops = &lo_fops;
+ disk->private_data = lo;
+ disk->queue = lo->lo_queue;
+ sprintf(disk->disk_name, "loop%d", i);
+ add_disk(disk);
+ list_add_tail(&lo->lo_list, &loop_devices);
+ return lo;
+
+out_free_queue:
+ blk_cleanup_queue(lo->lo_queue);
+out_free_dev:
+ kfree(lo);
+out:
+ return ERR_PTR(-ENOMEM);
+}
+
+static void loop_del_one(struct loop_device *lo)
+{
+ del_gendisk(lo->lo_disk);
+ blk_cleanup_queue(lo->lo_queue);
+ put_disk(lo->lo_disk);
+ list_del(&lo->lo_list);
+ kfree(lo);
+}
+
+static struct kobject *loop_probe(dev_t dev, int *part, void *data)
+{
+ unsigned int number = dev & MINORMASK;
+ struct loop_device *lo;
+
+ mutex_lock(&loop_devices_mutex);
+ lo = loop_find_dev(number);
+ if (lo == NULL)
+ lo = loop_init_one(number);
+ mutex_unlock(&loop_devices_mutex);
+
+ *part = 0;
+ if (IS_ERR(lo))
+ return (void *)lo;
+ else
+ return &lo->lo_disk->kobj;
+}
+
static int __init loop_init(void)
{
- int i;
-
- if (max_loop < 1 || max_loop > 256) {
- printk(KERN_WARNING "loop: invalid max_loop (must be between"
- " 1 and 256), using default (8)\n");
- max_loop = 8;
- }
+ struct loop_device *lo;
if (register_blkdev(LOOP_MAJOR, "loop"))
return -EIO;
+ blk_register_region(MKDEV(LOOP_MAJOR, 0), 1UL << MINORBITS,
+ THIS_MODULE, loop_probe, NULL, NULL);
- loop_dev = kmalloc(max_loop * sizeof(struct loop_device), GFP_KERNEL);
- if (!loop_dev)
- goto out_mem1;
- memset(loop_dev, 0, max_loop * sizeof(struct loop_device));
+ lo = loop_init_one(0);
+ if (IS_ERR(lo))
+ goto out;
- disks = kmalloc(max_loop * sizeof(struct gendisk *), GFP_KERNEL);
- if (!disks)
- goto out_mem2;
+ if (max_loop) {
+ printk(KERN_INFO "loop: the max_loop option is obsolete "
+ "and will be removed in March 2008\n");
- for (i = 0; i < max_loop; i++) {
- disks[i] = alloc_disk(1);
- if (!disks[i])
- goto out_mem3;
}
-
- for (i = 0; i < max_loop; i++) {
- struct loop_device *lo = &loop_dev[i];
- struct gendisk *disk = disks[i];
-
- memset(lo, 0, sizeof(*lo));
- lo->lo_queue = blk_alloc_queue(GFP_KERNEL);
- if (!lo->lo_queue)
- goto out_mem4;
- mutex_init(&lo->lo_ctl_mutex);
- lo->lo_number = i;
- lo->lo_thread = NULL;
- init_waitqueue_head(&lo->lo_event);
- spin_lock_init(&lo->lo_lock);
- disk->major = LOOP_MAJOR;
- disk->first_minor = i;
- disk->fops = &lo_fops;
- sprintf(disk->disk_name, "loop%d", i);
- disk->private_data = lo;
- disk->queue = lo->lo_queue;
- }
-
- /* We cannot fail after we call this, so another loop!*/
- for (i = 0; i < max_loop; i++)
- add_disk(disks[i]);
- printk(KERN_INFO "loop: loaded (max %d devices)\n", max_loop);
+ printk(KERN_INFO "loop: module loaded\n");
return 0;
-out_mem4:
- while (i--)
- blk_cleanup_queue(loop_dev[i].lo_queue);
- i = max_loop;
-out_mem3:
- while (i--)
- put_disk(disks[i]);
- kfree(disks);
-out_mem2:
- kfree(loop_dev);
-out_mem1:
+out:
unregister_blkdev(LOOP_MAJOR, "loop");
printk(KERN_ERR "loop: ran out of memory\n");
return -ENOMEM;
}
-static void loop_exit(void)
+static void __exit loop_exit(void)
{
- int i;
+ struct loop_device *lo, *next;
- for (i = 0; i < max_loop; i++) {
- del_gendisk(disks[i]);
- blk_cleanup_queue(loop_dev[i].lo_queue);
- put_disk(disks[i]);
- }
+ list_for_each_entry_safe(lo, next, &loop_devices, lo_list)
+ loop_del_one(lo);
+
+ blk_unregister_region(MKDEV(LOOP_MAJOR, 0), 1UL << MINORBITS);
if (unregister_blkdev(LOOP_MAJOR, "loop"))
printk(KERN_WARNING "loop: cannot unregister blkdev\n");
-
- kfree(disks);
- kfree(loop_dev);
}
module_init(loop_init);
diff --git a/drivers/block/umem.c b/drivers/block/umem.c
index 5872036..6f5d620 100644
--- a/drivers/block/umem.c
+++ b/drivers/block/umem.c
@@ -44,7 +44,6 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
#include <linux/timer.h>
#include <linux/pci.h>
#include <linux/slab.h>
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index a26d917..1e32fb8 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -127,7 +127,7 @@
config CYCLADES
tristate "Cyclades async mux support"
- depends on SERIAL_NONSTANDARD
+ depends on SERIAL_NONSTANDARD && (PCI || ISA)
---help---
This driver supports Cyclades Z and Y multiserial boards.
You would need something like this to connect more than two modems to
@@ -1071,5 +1071,11 @@
/sys/devices/platform/telco_clock, with a number of files for
controlling the behavior of this hardware.
+config DEVPORT
+ bool
+ depends on !M68K
+ depends on ISA || PCI
+ default y
+
endmenu
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c
index 91b0621..42c0a60 100644
--- a/drivers/char/agp/uninorth-agp.c
+++ b/drivers/char/agp/uninorth-agp.c
@@ -613,7 +613,7 @@
uninorth_node = of_find_node_by_name(NULL, "u3");
}
if (uninorth_node) {
- const int *revprop = get_property(uninorth_node,
+ const int *revprop = of_get_property(uninorth_node,
"device-rev", NULL);
if (revprop != NULL)
uninorth_rev = *revprop & 0x3f;
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index 0e2b72f..4eaceab 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -1574,7 +1574,7 @@
if (timeout && time_after(jiffies, orig_jiffies + timeout))
break;
}
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
#endif
@@ -1700,7 +1700,7 @@
#endif
schedule();
}
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(&info->open_wait, &wait);
if (extra_count)
state->count++;
diff --git a/drivers/char/briq_panel.c b/drivers/char/briq_panel.c
index c70d52a..ed53f54 100644
--- a/drivers/char/briq_panel.c
+++ b/drivers/char/briq_panel.c
@@ -206,7 +206,7 @@
const char *machine;
int i;
- machine = get_property(root, "model", NULL);
+ machine = of_get_property(root, "model", NULL);
if (!machine || strncmp(machine, "TotalImpact,BRIQ-1", 18) != 0) {
of_node_put(root);
return -ENODEV;
diff --git a/drivers/char/consolemap.c b/drivers/char/consolemap.c
index b99b756..fd40b95 100644
--- a/drivers/char/consolemap.c
+++ b/drivers/char/consolemap.c
@@ -626,10 +626,10 @@
/* Only 16-bit codes supported at this time */
if (ucs > 0xffff)
- ucs = 0xfffd; /* U+FFFD: REPLACEMENT CHARACTER */
- else if (ucs < 0x20 || ucs >= 0xfffe)
+ return -4; /* Not found */
+ else if (ucs < 0x20)
return -1; /* Not a printable character */
- else if (ucs == 0xfeff || (ucs >= 0x200a && ucs <= 0x200f))
+ else if (ucs == 0xfeff || (ucs >= 0x200b && ucs <= 0x200f))
return -2; /* Zero-width space */
/*
* UNI_DIRECT_BASE indicates the start of the region in the User Zone
diff --git a/drivers/char/cs5535_gpio.c b/drivers/char/cs5535_gpio.c
index c02d9e9..fe6d240 100644
--- a/drivers/char/cs5535_gpio.c
+++ b/drivers/char/cs5535_gpio.c
@@ -44,6 +44,7 @@
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) },
{ } /* NULL entry */
};
+MODULE_DEVICE_TABLE(pci, divil_pci);
static struct cdev cs5535_gpio_cdev;
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index 16dc5d1..c72ee97 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -10,15 +10,14 @@
*
* Initially written by Randolph Bentson <bentson@grieg.seaslug.org>.
* Modified and maintained by Marcio Saito <marcio@cyclades.com>.
- * Currently maintained by Cyclades team <async@cyclades.com>.
*
- * For Technical support and installation problems, please send e-mail
- * to support@cyclades.com.
+ * Copyright (C) 2007 Jiri Slaby <jirislaby@gmail.com>
*
* Much of the design and some of the code came from serial.c
* which was copyright (C) 1991, 1992 Linus Torvalds. It was
* extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92,
* and then fixed as suggested by Michael K. Johnson 12/12/92.
+ * Converted to pci probing and cleaned up by Jiri Slaby.
*
* This version supports shared IRQ's (only for PCI boards).
*
@@ -591,7 +590,7 @@
*
*/
-#define CY_VERSION "2.4"
+#define CY_VERSION "2.5"
/* If you need to install more boards than NR_CARDS, change the constant
in the definition below. No other change is necessary to support up to
@@ -624,12 +623,6 @@
#undef CY_ENABLE_MONITORING
#undef CY_PCI_DEBUG
-#if 0
-#define PAUSE __asm__("nop")
-#else
-#define PAUSE do {} while (0)
-#endif
-
/*
* Include section
*/
@@ -659,17 +652,6 @@
#include <asm/irq.h>
#include <asm/uaccess.h>
-#define CY_LOCK(info,flags) \
- do { \
- spin_lock_irqsave(&cy_card[info->card].card_lock, flags); \
- } while (0)
-
-#define CY_UNLOCK(info,flags) \
- do { \
- spin_unlock_irqrestore(&cy_card[info->card].card_lock, flags); \
- } while (0)
-
-#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/pci.h>
@@ -682,13 +664,13 @@
#define IS_CYC_Z(card) ((card).num_chips == -1)
#define Z_FPGA_CHECK(card) \
- ((cy_readl(&((struct RUNTIME_9060 __iomem *) \
+ ((readl(&((struct RUNTIME_9060 __iomem *) \
((card).ctl_addr))->init_ctrl) & (1<<17)) != 0)
-#define ISZLOADED(card) (((ZO_V1==cy_readl(&((struct RUNTIME_9060 __iomem *) \
+#define ISZLOADED(card) (((ZO_V1==readl(&((struct RUNTIME_9060 __iomem *) \
((card).ctl_addr))->mail_box_0)) || \
Z_FPGA_CHECK(card)) && \
- (ZFIRM_ID==cy_readl(&((struct FIRM_ID __iomem *) \
+ (ZFIRM_ID==readl(&((struct FIRM_ID __iomem *) \
((card).base_addr+ID_ADDRESS))->signature)))
#ifndef SERIAL_XMIT_SIZE
@@ -725,8 +707,8 @@
#define NR_ISA_ADDRS ARRAY_SIZE(cy_isa_addresses)
#ifdef MODULE
-static long maddr[NR_CARDS] = { 0, };
-static int irq[NR_CARDS] = { 0, };
+static long maddr[NR_CARDS];
+static int irq[NR_CARDS];
module_param_array(maddr, long, NULL, 0);
module_param_array(irq, int, NULL, 0);
@@ -739,11 +721,6 @@
*/
static struct cyclades_card cy_card[NR_CARDS];
-/* This is the per-channel data structure containing pointers, flags
- and variables for the port. This driver supports a maximum of NR_PORTS.
-*/
-static struct cyclades_port cy_port[NR_PORTS];
-
static int cy_next_channel; /* next minor available */
/*
@@ -825,9 +802,6 @@
/* PCI related definitions */
-static unsigned short cy_pci_nboard;
-static unsigned short cy_isa_nboard;
-static unsigned short cy_nboard;
#ifdef CONFIG_PCI
static struct pci_device_id cy_pci_dev_id[] __devinitdata = {
{ PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Y_Lo) }, /* PCI < 1Mb */
@@ -845,7 +819,7 @@
static void cy_start(struct tty_struct *);
static void set_line_char(struct cyclades_port *);
-static int cyz_issue_cmd(struct cyclades_card *, uclong, ucchar, uclong);
+static int cyz_issue_cmd(struct cyclades_card *, __u32, __u8, __u32);
#ifdef CONFIG_ISA
static unsigned detect_isa_irq(void __iomem *);
#endif /* CONFIG_ISA */
@@ -858,7 +832,6 @@
/* The Cyclades-Z polling cycle is defined by this variable */
static long cyz_polling_cycle = CZ_DEF_POLL;
-static int cyz_timeron = 0;
static DEFINE_TIMER(cyz_timerlist, cyz_poll, 0, 0);
#else /* CONFIG_CYZ_INTR */
@@ -871,21 +844,14 @@
{
#ifdef SERIAL_PARANOIA_CHECK
if (!info) {
- printk("cyc Warning: null cyclades_port for (%s) in %s\n",
- name, routine);
- return 1;
- }
-
- if ((long)info < (long)(&cy_port[0]) ||
- (long)(&cy_port[NR_PORTS]) < (long)info) {
- printk("cyc Warning: cyclades_port out of range for (%s) in "
- "%s\n", name, routine);
+ printk(KERN_WARNING "cyc Warning: null cyclades_port for (%s) "
+ "in %s\n", name, routine);
return 1;
}
if (info->magic != CYCLADES_MAGIC) {
- printk("cyc Warning: bad magic number for serial struct (%s) "
- "in %s\n", name, routine);
+ printk(KERN_WARNING "cyc Warning: bad magic number for serial "
+ "struct (%s) in %s\n", name, routine);
return 1;
}
#endif
@@ -943,22 +909,16 @@
if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event))
wake_up_interruptible(&info->open_wait);
#ifdef CONFIG_CYZ_INTR
- if (test_and_clear_bit(Cy_EVENT_Z_RX_FULL, &info->event)) {
- if (cyz_rx_full_timer[info->line].function == NULL) {
- cyz_rx_full_timer[info->line].expires = jiffies + 1;
- cyz_rx_full_timer[info->line].function = cyz_rx_restart;
- cyz_rx_full_timer[info->line].data =
- (unsigned long)info;
- add_timer(&cyz_rx_full_timer[info->line]);
- }
- }
+ if (test_and_clear_bit(Cy_EVENT_Z_RX_FULL, &info->event) &&
+ !timer_pending(&cyz_rx_full_timer[info->line]))
+ mod_timer(&cyz_rx_full_timer[info->line], jiffies + 1);
#endif
if (test_and_clear_bit(Cy_EVENT_DELTA_WAKEUP, &info->event))
wake_up_interruptible(&info->delta_msr_wait);
tty_wakeup(tty);
#ifdef Z_WAKE
if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event))
- wake_up_interruptible(&info->shutdown_wait);
+ complete(&info->shutdown_wait);
#endif
} /* do_softint */
@@ -975,11 +935,11 @@
*/
static int cyy_issue_cmd(void __iomem * base_addr, u_char cmd, int index)
{
- volatile int i;
+ unsigned int i;
/* Check to see that the previous command has completed */
for (i = 0; i < 100; i++) {
- if (cy_readb(base_addr + (CyCCR << index)) == 0) {
+ if (readb(base_addr + (CyCCR << index)) == 0) {
break;
}
udelay(10L);
@@ -1022,7 +982,7 @@
cy_writeb(address + (CyCAR << index), 0);
cy_writeb(address + (CySRER << index),
- cy_readb(address + (CySRER << index)) | CyTxRdy);
+ readb(address + (CySRER << index)) | CyTxRdy);
local_irq_restore(flags);
/* Wait ... */
@@ -1032,11 +992,11 @@
irq = probe_irq_off(irqs);
/* Clean up */
- save_xir = (u_char) cy_readb(address + (CyTIR << index));
- save_car = cy_readb(address + (CyCAR << index));
+ save_xir = (u_char) readb(address + (CyTIR << index));
+ save_car = readb(address + (CyCAR << index));
cy_writeb(address + (CyCAR << index), (save_xir & 0x3));
cy_writeb(address + (CySRER << index),
- cy_readb(address + (CySRER << index)) & ~CyTxRdy);
+ readb(address + (CySRER << index)) & ~CyTxRdy);
cy_writeb(address + (CyTIR << index), (save_xir & 0x3f));
cy_writeb(address + (CyCAR << index), (save_car));
cy_writeb(address + (Cy_ClrIntr << index), 0);
@@ -1051,45 +1011,43 @@
{
struct cyclades_port *info;
struct tty_struct *tty;
- volatile int char_count;
- int i, j, len, mdm_change, mdm_status, outch;
+ int char_count;
+ int j, len, mdm_change, mdm_status, outch;
int save_xir, channel, save_car;
char data;
if (status & CySRReceive) { /* reception interrupt */
#ifdef CY_DEBUG_INTERRUPTS
- printk("cyy_interrupt: rcvd intr, chip %d\n\r", chip);
+ printk(KERN_DEBUG "cyy_interrupt: rcvd intr, chip %d\n", chip);
#endif
/* determine the channel & change to that context */
spin_lock(&cinfo->card_lock);
- save_xir = (u_char) cy_readb(base_addr + (CyRIR << index));
+ save_xir = (u_char) readb(base_addr + (CyRIR << index));
channel = (u_short) (save_xir & CyIRChannel);
- i = channel + chip * 4 + cinfo->first_line;
- info = &cy_port[i];
- info->last_active = jiffies;
- save_car = cy_readb(base_addr + (CyCAR << index));
+ info = &cinfo->ports[channel + chip * 4];
+ save_car = readb(base_addr + (CyCAR << index));
cy_writeb(base_addr + (CyCAR << index), save_xir);
/* if there is nowhere to put the data, discard it */
- if (info->tty == 0) {
- j = (cy_readb(base_addr + (CyRIVR << index)) &
+ if (info->tty == NULL) {
+ j = (readb(base_addr + (CyRIVR << index)) &
CyIVRMask);
if (j == CyIVRRxEx) { /* exception */
- data = cy_readb(base_addr + (CyRDSR << index));
+ data = readb(base_addr + (CyRDSR << index));
} else { /* normal character reception */
- char_count = cy_readb(base_addr +
+ char_count = readb(base_addr +
(CyRDCR << index));
while (char_count--) {
- data = cy_readb(base_addr +
+ data = readb(base_addr +
(CyRDSR << index));
}
}
} else { /* there is an open port for this data */
tty = info->tty;
- j = (cy_readb(base_addr + (CyRIVR << index)) &
+ j = (readb(base_addr + (CyRIVR << index)) &
CyIVRMask);
if (j == CyIVRRxEx) { /* exception */
- data = cy_readb(base_addr + (CyRDSR << index));
+ data = readb(base_addr + (CyRDSR << index));
/* For statistics only */
if (data & CyBREAK)
@@ -1110,7 +1068,7 @@
if (data & CyBREAK) {
tty_insert_flip_char(
tty,
- cy_readb(
+ readb(
base_addr +
(CyRDSR <<
index)),
@@ -1123,7 +1081,7 @@
} else if (data & CyFRAME) {
tty_insert_flip_char(
tty,
- cy_readb(
+ readb(
base_addr +
(CyRDSR <<
index)),
@@ -1135,7 +1093,7 @@
/* Pieces of seven... */
tty_insert_flip_char(
tty,
- cy_readb(
+ readb(
base_addr +
(CyRDSR <<
index)),
@@ -1154,7 +1112,7 @@
*/
tty_insert_flip_char(
tty,
- cy_readb(
+ readb(
base_addr +
(CyRDSR <<
index)),
@@ -1186,7 +1144,7 @@
}
} else { /* normal character reception */
/* load # chars available from the chip */
- char_count = cy_readb(base_addr +
+ char_count = readb(base_addr +
(CyRDCR << index));
#ifdef CY_ENABLE_MONITORING
@@ -1198,7 +1156,7 @@
#endif
len = tty_buffer_request_room(tty, char_count);
while (len--) {
- data = cy_readb(base_addr +
+ data = readb(base_addr +
(CyRDSR << index));
tty_insert_flip_char(tty, data,
TTY_NORMAL);
@@ -1223,29 +1181,27 @@
is empty, we know we can always stuff a dozen
characters. */
#ifdef CY_DEBUG_INTERRUPTS
- printk("cyy_interrupt: xmit intr, chip %d\n\r", chip);
+ printk(KERN_DEBUG "cyy_interrupt: xmit intr, chip %d\n", chip);
#endif
/* determine the channel & change to that context */
spin_lock(&cinfo->card_lock);
- save_xir = (u_char) cy_readb(base_addr + (CyTIR << index));
+ save_xir = (u_char) readb(base_addr + (CyTIR << index));
channel = (u_short) (save_xir & CyIRChannel);
- i = channel + chip * 4 + cinfo->first_line;
- save_car = cy_readb(base_addr + (CyCAR << index));
+ save_car = readb(base_addr + (CyCAR << index));
cy_writeb(base_addr + (CyCAR << index), save_xir);
/* validate the port# (as configured and open) */
- if ((i < 0) || (NR_PORTS <= i)) {
+ if (channel + chip * 4 >= cinfo->nports) {
cy_writeb(base_addr + (CySRER << index),
- cy_readb(base_addr + (CySRER << index)) &
+ readb(base_addr + (CySRER << index)) &
~CyTxRdy);
goto txend;
}
- info = &cy_port[i];
- info->last_active = jiffies;
- if (info->tty == 0) {
+ info = &cinfo->ports[channel + chip * 4];
+ if (info->tty == NULL) {
cy_writeb(base_addr + (CySRER << index),
- cy_readb(base_addr + (CySRER << index)) &
+ readb(base_addr + (CySRER << index)) &
~CyTxRdy);
goto txdone;
}
@@ -1278,29 +1234,29 @@
while (char_count-- > 0) {
if (!info->xmit_cnt) {
- if (cy_readb(base_addr + (CySRER << index)) &
+ if (readb(base_addr + (CySRER << index)) &
CyTxMpty) {
cy_writeb(base_addr + (CySRER << index),
- cy_readb(base_addr +
+ readb(base_addr +
(CySRER << index)) &
~CyTxMpty);
} else {
cy_writeb(base_addr + (CySRER << index),
- (cy_readb(base_addr +
+ (readb(base_addr +
(CySRER << index)) &
~CyTxRdy) | CyTxMpty);
}
goto txdone;
}
- if (info->xmit_buf == 0) {
+ if (info->xmit_buf == NULL) {
cy_writeb(base_addr + (CySRER << index),
- cy_readb(base_addr + (CySRER << index))&
+ readb(base_addr + (CySRER << index)) &
~CyTxRdy);
goto txdone;
}
if (info->tty->stopped || info->tty->hw_stopped) {
cy_writeb(base_addr + (CySRER << index),
- cy_readb(base_addr + (CySRER << index))&
+ readb(base_addr + (CySRER << index)) &
~CyTxRdy);
goto txdone;
}
@@ -1333,7 +1289,6 @@
0);
info->icount.tx++;
char_count--;
- } else {
}
}
}
@@ -1353,19 +1308,16 @@
/* determine the channel & change to that context */
spin_lock(&cinfo->card_lock);
- save_xir = (u_char) cy_readb(base_addr + (CyMIR << index));
+ save_xir = (u_char) readb(base_addr + (CyMIR << index));
channel = (u_short) (save_xir & CyIRChannel);
- info = &cy_port[channel + chip * 4 + cinfo->first_line];
- info->last_active = jiffies;
- save_car = cy_readb(base_addr + (CyCAR << index));
+ info = &cinfo->ports[channel + chip * 4];
+ save_car = readb(base_addr + (CyCAR << index));
cy_writeb(base_addr + (CyCAR << index), save_xir);
- mdm_change = cy_readb(base_addr + (CyMISR << index));
- mdm_status = cy_readb(base_addr + (CyMSVR1 << index));
+ mdm_change = readb(base_addr + (CyMISR << index));
+ mdm_status = readb(base_addr + (CyMSVR1 << index));
- if (info->tty == 0) { /* no place for data, ignore it */
- ;
- } else {
+ if (info->tty) {
if (mdm_change & CyANY_DELTA) {
/* For statistics only */
if (mdm_change & CyDCD)
@@ -1398,7 +1350,7 @@
info->tty->hw_stopped = 0;
cy_writeb(base_addr +
(CySRER << index),
- cy_readb(base_addr +
+ readb(base_addr +
(CySRER <<
index))|
CyTxRdy);
@@ -1412,17 +1364,17 @@
info->tty->hw_stopped = 1;
cy_writeb(base_addr +
(CySRER << index),
- cy_readb(base_addr +
+ readb(base_addr +
(CySRER <<
index)) &
~CyTxRdy);
}
}
}
- if (mdm_change & CyDSR) {
+/* if (mdm_change & CyDSR) {
}
if (mdm_change & CyRI) {
- }
+ }*/
}
/* end of service */
cy_writeb(base_addr + (CyMIR << index), (save_xir & 0x3f));
@@ -1438,16 +1390,16 @@
static irqreturn_t cyy_interrupt(int irq, void *dev_id)
{
int status;
- struct cyclades_card *cinfo;
+ struct cyclades_card *cinfo = dev_id;
void __iomem *base_addr, *card_base_addr;
int chip;
int index;
int too_many;
int had_work;
- if ((cinfo = (struct cyclades_card *)dev_id) == 0) {
+ if (unlikely(cinfo == NULL)) {
#ifdef CY_DEBUG_INTERRUPTS
- printk("cyy_interrupt: spurious interrupt %d\n\r", irq);
+ printk(KERN_DEBUG "cyy_interrupt: spurious interrupt %d\n",irq);
#endif
return IRQ_NONE; /* spurious interrupt */
}
@@ -1455,6 +1407,10 @@
card_base_addr = cinfo->base_addr;
index = cinfo->bus_index;
+ /* card was not initialized yet (e.g. DEBUG_SHIRQ) */
+ if (unlikely(card_base_addr == NULL))
+ return IRQ_HANDLED;
+
/* This loop checks all chips in the card. Make a note whenever
_any_ chip had some work to do, as this is considered an
indication that there will be more to do. Only when no chip
@@ -1466,7 +1422,7 @@
base_addr = cinfo->base_addr +
(cy_chip_offset[chip] << index);
too_many = 0;
- while ((status = cy_readb(base_addr +
+ while ((status = readb(base_addr +
(CySVRR << index))) != 0x00) {
had_work++;
/* The purpose of the following test is to ensure that
@@ -1498,7 +1454,7 @@
static int
cyz_fetch_msg(struct cyclades_card *cinfo,
- uclong * channel, ucchar * cmd, uclong * param)
+ __u32 * channel, __u8 * cmd, __u32 * param)
{
struct FIRM_ID __iomem *firm_id;
struct ZFW_CTRL __iomem *zfw_ctrl;
@@ -1509,16 +1465,15 @@
if (!ISZLOADED(*cinfo)) {
return -1;
}
- zfw_ctrl = cinfo->base_addr + (cy_readl(&firm_id->zfwctrl_addr) &
- 0xfffff);
+ zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
board_ctrl = &zfw_ctrl->board_ctrl;
- loc_doorbell = cy_readl(&((struct RUNTIME_9060 __iomem *)
+ loc_doorbell = readl(&((struct RUNTIME_9060 __iomem *)
(cinfo->ctl_addr))->loc_doorbell);
if (loc_doorbell) {
*cmd = (char)(0xff & loc_doorbell);
- *channel = cy_readl(&board_ctrl->fwcmd_channel);
- *param = (uclong) cy_readl(&board_ctrl->fwcmd_param);
+ *channel = readl(&board_ctrl->fwcmd_channel);
+ *param = (__u32) readl(&board_ctrl->fwcmd_param);
cy_writel(&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))->
loc_doorbell, 0xffffffff);
return 1;
@@ -1528,28 +1483,27 @@
static int
cyz_issue_cmd(struct cyclades_card *cinfo,
- uclong channel, ucchar cmd, uclong param)
+ __u32 channel, __u8 cmd, __u32 param)
{
struct FIRM_ID __iomem *firm_id;
struct ZFW_CTRL __iomem *zfw_ctrl;
struct BOARD_CTRL __iomem *board_ctrl;
- unsigned long __iomem *pci_doorbell;
+ __u32 __iomem *pci_doorbell;
int index;
firm_id = cinfo->base_addr + ID_ADDRESS;
if (!ISZLOADED(*cinfo)) {
return -1;
}
- zfw_ctrl = cinfo->base_addr + (cy_readl(&firm_id->zfwctrl_addr) &
- 0xfffff);
+ zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
board_ctrl = &zfw_ctrl->board_ctrl;
index = 0;
pci_doorbell =
&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))->pci_doorbell;
- while ((cy_readl(pci_doorbell) & 0xff) != 0) {
+ while ((readl(pci_doorbell) & 0xff) != 0) {
if (index++ == 1000) {
- return (int)(cy_readl(pci_doorbell) & 0xff);
+ return (int)(readl(pci_doorbell) & 0xff);
}
udelay(50L);
}
@@ -1561,34 +1515,30 @@
} /* cyz_issue_cmd */
static void
-cyz_handle_rx(struct cyclades_port *info,
- volatile struct CH_CTRL __iomem * ch_ctrl,
- volatile struct BUF_CTRL __iomem * buf_ctrl)
+cyz_handle_rx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl,
+ struct BUF_CTRL __iomem *buf_ctrl)
{
- struct cyclades_card *cinfo = &cy_card[info->card];
+ struct cyclades_card *cinfo = info->card;
struct tty_struct *tty = info->tty;
- volatile int char_count;
+ int char_count;
int len;
#ifdef BLOCKMOVE
- int small_count;
+ unsigned char *buf;
#else
char data;
#endif
- volatile uclong rx_put, rx_get, new_rx_get, rx_bufsize, rx_bufaddr;
+ __u32 rx_put, rx_get, new_rx_get, rx_bufsize, rx_bufaddr;
- rx_get = new_rx_get = cy_readl(&buf_ctrl->rx_get);
- rx_put = cy_readl(&buf_ctrl->rx_put);
- rx_bufsize = cy_readl(&buf_ctrl->rx_bufsize);
- rx_bufaddr = cy_readl(&buf_ctrl->rx_bufaddr);
+ rx_get = new_rx_get = readl(&buf_ctrl->rx_get);
+ rx_put = readl(&buf_ctrl->rx_put);
+ rx_bufsize = readl(&buf_ctrl->rx_bufsize);
+ rx_bufaddr = readl(&buf_ctrl->rx_bufaddr);
if (rx_put >= rx_get)
char_count = rx_put - rx_get;
else
char_count = rx_put - rx_get + rx_bufsize;
if (char_count) {
- info->last_active = jiffies;
- info->jiffies[1] = jiffies;
-
#ifdef CY_ENABLE_MONITORING
info->mon.int_count++;
info->mon.char_count += char_count;
@@ -1596,7 +1546,7 @@
info->mon.char_max = char_count;
info->mon.char_last = char_count;
#endif
- if (tty == 0) {
+ if (tty == NULL) {
/* flush received characters */
new_rx_get = (new_rx_get + char_count) &
(rx_bufsize - 1);
@@ -1606,30 +1556,28 @@
/* we'd like to use memcpy(t, f, n) and memset(s, c, count)
for performance, but because of buffer boundaries, there
may be several steps to the operation */
- while (0 < (small_count = min_t(unsigned int,
- rx_bufsize - new_rx_get,
- min_t(unsigned int, TTY_FLIPBUF_SIZE -
- tty->flip.count, char_count)))){
- memcpy_fromio(tty->flip.char_buf_ptr,
- (char *)(cinfo->base_addr + rx_bufaddr +
- new_rx_get),
- small_count);
+ while (1) {
+ len = tty_prepare_flip_string(tty, &buf,
+ char_count);
+ if (!len)
+ break;
- tty->flip.char_buf_ptr += small_count;
- memset(tty->flip.flag_buf_ptr, TTY_NORMAL,
- small_count);
- tty->flip.flag_buf_ptr += small_count;
- new_rx_get = (new_rx_get + small_count) &
+ len = min_t(unsigned int, min(len, char_count),
+ rx_bufsize - new_rx_get);
+
+ memcpy_fromio(buf, cinfo->base_addr +
+ rx_bufaddr + new_rx_get, len);
+
+ new_rx_get = (new_rx_get + len) &
(rx_bufsize - 1);
- char_count -= small_count;
- info->icount.rx += small_count;
- info->idle_stats.recv_bytes += small_count;
- tty->flip.count += small_count;
+ char_count -= len;
+ info->icount.rx += len;
+ info->idle_stats.recv_bytes += len;
}
#else
len = tty_buffer_request_room(tty, char_count);
while (len--) {
- data = cy_readb(cinfo->base_addr + rx_bufaddr +
+ data = readb(cinfo->base_addr + rx_bufaddr +
new_rx_get);
new_rx_get = (new_rx_get + 1)& (rx_bufsize - 1);
tty_insert_flip_char(tty, data, TTY_NORMAL);
@@ -1640,13 +1588,12 @@
#ifdef CONFIG_CYZ_INTR
/* Recalculate the number of chars in the RX buffer and issue
a cmd in case it's higher than the RX high water mark */
- rx_put = cy_readl(&buf_ctrl->rx_put);
+ rx_put = readl(&buf_ctrl->rx_put);
if (rx_put >= rx_get)
char_count = rx_put - rx_get;
else
char_count = rx_put - rx_get + rx_bufsize;
- if (char_count >= (int)cy_readl(&buf_ctrl->
- rx_threshold)) {
+ if (char_count >= (int)readl(&buf_ctrl->rx_threshold)) {
cy_sched_event(info, Cy_EVENT_Z_RX_FULL);
}
#endif
@@ -1659,26 +1606,25 @@
}
static void
-cyz_handle_tx(struct cyclades_port *info,
- volatile struct CH_CTRL __iomem * ch_ctrl,
- volatile struct BUF_CTRL __iomem * buf_ctrl)
+cyz_handle_tx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl,
+ struct BUF_CTRL __iomem *buf_ctrl)
{
- struct cyclades_card *cinfo = &cy_card[info->card];
+ struct cyclades_card *cinfo = info->card;
struct tty_struct *tty = info->tty;
char data;
- volatile int char_count;
+ int char_count;
#ifdef BLOCKMOVE
int small_count;
#endif
- volatile uclong tx_put, tx_get, tx_bufsize, tx_bufaddr;
+ __u32 tx_put, tx_get, tx_bufsize, tx_bufaddr;
if (info->xmit_cnt <= 0) /* Nothing to transmit */
return;
- tx_get = cy_readl(&buf_ctrl->tx_get);
- tx_put = cy_readl(&buf_ctrl->tx_put);
- tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize);
- tx_bufaddr = cy_readl(&buf_ctrl->tx_bufaddr);
+ tx_get = readl(&buf_ctrl->tx_get);
+ tx_put = readl(&buf_ctrl->tx_put);
+ tx_bufsize = readl(&buf_ctrl->tx_bufsize);
+ tx_bufaddr = readl(&buf_ctrl->tx_bufaddr);
if (tx_put >= tx_get)
char_count = tx_get - tx_put - 1 + tx_bufsize;
else
@@ -1686,9 +1632,8 @@
if (char_count) {
- if (tty == 0) {
+ if (tty == NULL)
goto ztxdone;
- }
if (info->x_char) { /* send special char */
data = info->x_char;
@@ -1698,8 +1643,6 @@
info->x_char = 0;
char_count--;
info->icount.tx++;
- info->last_active = jiffies;
- info->jiffies[2] = jiffies;
}
#ifdef BLOCKMOVE
while (0 < (small_count = min_t(unsigned int,
@@ -1719,8 +1662,6 @@
info->xmit_cnt -= small_count;
info->xmit_tail = (info->xmit_tail + small_count) &
(SERIAL_XMIT_SIZE - 1);
- info->last_active = jiffies;
- info->jiffies[2] = jiffies;
}
#else
while (info->xmit_cnt && char_count) {
@@ -1733,8 +1674,6 @@
tx_put = (tx_put + 1) & (tx_bufsize - 1);
char_count--;
info->icount.tx++;
- info->last_active = jiffies;
- info->jiffies[2] = jiffies;
}
#endif
ztxdone:
@@ -1750,33 +1689,32 @@
{
struct tty_struct *tty;
struct cyclades_port *info;
- static volatile struct FIRM_ID __iomem *firm_id;
- static volatile struct ZFW_CTRL __iomem *zfw_ctrl;
- static volatile struct BOARD_CTRL __iomem *board_ctrl;
- static volatile struct CH_CTRL __iomem *ch_ctrl;
- static volatile struct BUF_CTRL __iomem *buf_ctrl;
- uclong channel;
- ucchar cmd;
- uclong param;
- uclong hw_ver, fw_ver;
+ static struct FIRM_ID __iomem *firm_id;
+ static struct ZFW_CTRL __iomem *zfw_ctrl;
+ static struct BOARD_CTRL __iomem *board_ctrl;
+ static struct CH_CTRL __iomem *ch_ctrl;
+ static struct BUF_CTRL __iomem *buf_ctrl;
+ __u32 channel;
+ __u8 cmd;
+ __u32 param;
+ __u32 hw_ver, fw_ver;
int special_count;
int delta_count;
firm_id = cinfo->base_addr + ID_ADDRESS;
- zfw_ctrl = cinfo->base_addr + (cy_readl(&firm_id->zfwctrl_addr) &
- 0xfffff);
+ zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
board_ctrl = &zfw_ctrl->board_ctrl;
- fw_ver = cy_readl(&board_ctrl->fw_version);
- hw_ver = cy_readl(&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))->
+ fw_ver = readl(&board_ctrl->fw_version);
+ hw_ver = readl(&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))->
mail_box_0);
while (cyz_fetch_msg(cinfo, &channel, &cmd, ¶m) == 1) {
special_count = 0;
delta_count = 0;
- info = &cy_port[channel + cinfo->first_line];
- if ((tty = info->tty) == 0) {
+ info = &cinfo->ports[channel];
+ if ((tty = info->tty) == NULL)
continue;
- }
+
ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
@@ -1801,7 +1739,7 @@
delta_count++;
if (info->flags & ASYNC_CHECK_CD) {
if ((fw_ver > 241 ? ((u_long) param) :
- cy_readl(&ch_ctrl->rs_status)) &
+ readl(&ch_ctrl->rs_status)) &
C_RS_DCD) {
cy_sched_event(info,
Cy_EVENT_OPEN_WAKEUP);
@@ -1833,8 +1771,8 @@
case C_CM_INTBACK2:
/* Reception Interrupt */
#ifdef CY_DEBUG_INTERRUPTS
- printk("cyz_interrupt: rcvd intr, card %d, "
- "port %ld\n\r", info->card, channel);
+ printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, "
+ "port %ld\n", info->card, channel);
#endif
cyz_handle_rx(info, ch_ctrl, buf_ctrl);
break;
@@ -1843,8 +1781,8 @@
case C_CM_INTBACK:
/* Transmission Interrupt */
#ifdef CY_DEBUG_INTERRUPTS
- printk("cyz_interrupt: xmit intr, card %d, "
- "port %ld\n\r", info->card, channel);
+ printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, "
+ "port %ld\n", info->card, channel);
#endif
cyz_handle_tx(info, ch_ctrl, buf_ctrl);
break;
@@ -1865,18 +1803,19 @@
#ifdef CONFIG_CYZ_INTR
static irqreturn_t cyz_interrupt(int irq, void *dev_id)
{
- struct cyclades_card *cinfo;
+ struct cyclades_card *cinfo = dev_id;
- if ((cinfo = (struct cyclades_card *)dev_id) == 0) {
+ if (unlikely(cinfo == NULL)) {
#ifdef CY_DEBUG_INTERRUPTS
- printk("cyz_interrupt: spurious interrupt %d\n\r", irq);
+ printk(KERN_DEBUG "cyz_interrupt: spurious interrupt %d\n",irq);
#endif
return IRQ_NONE; /* spurious interrupt */
}
- if (!ISZLOADED(*cinfo)) {
+ if (unlikely(!ISZLOADED(*cinfo))) {
#ifdef CY_DEBUG_INTERRUPTS
- printk("cyz_interrupt: board not yet loaded (IRQ%d).\n\r", irq);
+ printk(KERN_DEBUG "cyz_interrupt: board not yet loaded "
+ "(IRQ%d).\n", irq);
#endif
return IRQ_NONE;
}
@@ -1890,19 +1829,18 @@
static void cyz_rx_restart(unsigned long arg)
{
struct cyclades_port *info = (struct cyclades_port *)arg;
+ struct cyclades_card *card = info->card;
int retval;
- int card = info->card;
- uclong channel = (info->line) - (cy_card[card].first_line);
+ __u32 channel = info->line - card->first_line;
unsigned long flags;
- CY_LOCK(info, flags);
- retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_INTBACK2, 0L);
+ spin_lock_irqsave(&card->card_lock, flags);
+ retval = cyz_issue_cmd(card, channel, C_CM_INTBACK2, 0L);
if (retval != 0) {
- printk("cyc:cyz_rx_restart retval on ttyC%d was %x\n",
+ printk(KERN_ERR "cyc:cyz_rx_restart retval on ttyC%d was %x\n",
info->line, retval);
}
- cyz_rx_full_timer[info->line].function = NULL;
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
}
#else /* CONFIG_CYZ_INTR */
@@ -1912,14 +1850,14 @@
struct cyclades_card *cinfo;
struct cyclades_port *info;
struct tty_struct *tty;
- static volatile struct FIRM_ID *firm_id;
- static volatile struct ZFW_CTRL *zfw_ctrl;
- static volatile struct BOARD_CTRL *board_ctrl;
- static volatile struct CH_CTRL *ch_ctrl;
- static volatile struct BUF_CTRL *buf_ctrl;
+ static struct FIRM_ID *firm_id;
+ static struct ZFW_CTRL *zfw_ctrl;
+ static struct BOARD_CTRL *board_ctrl;
+ static struct CH_CTRL *ch_ctrl;
+ static struct BUF_CTRL *buf_ctrl;
+ unsigned long expires = jiffies + HZ;
int card, port;
- cyz_timerlist.expires = jiffies + (HZ);
for (card = 0; card < NR_CARDS; card++) {
cinfo = &cy_card[card];
@@ -1930,12 +1868,12 @@
firm_id = cinfo->base_addr + ID_ADDRESS;
zfw_ctrl = cinfo->base_addr +
- (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
+ (readl(&firm_id->zfwctrl_addr) & 0xfffff);
board_ctrl = &(zfw_ctrl->board_ctrl);
/* Skip first polling cycle to avoid racing conditions with the FW */
if (!cinfo->intr_enabled) {
- cinfo->nports = (int)cy_readl(&board_ctrl->n_channel);
+ cinfo->nports = (int)readl(&board_ctrl->n_channel);
cinfo->intr_enabled = 1;
continue;
}
@@ -1943,7 +1881,7 @@
cyz_handle_cmd(cinfo);
for (port = 0; port < cinfo->nports; port++) {
- info = &cy_port[port + cinfo->first_line];
+ info = &cinfo->ports[port];
tty = info->tty;
ch_ctrl = &(zfw_ctrl->ch_ctrl[port]);
buf_ctrl = &(zfw_ctrl->buf_ctrl[port]);
@@ -1953,9 +1891,9 @@
cyz_handle_tx(info, ch_ctrl, buf_ctrl);
}
/* poll every 'cyz_polling_cycle' period */
- cyz_timerlist.expires = jiffies + cyz_polling_cycle;
+ expires = jiffies + cyz_polling_cycle;
}
- add_timer(&cyz_timerlist);
+ mod_timer(&cyz_timerlist, expires);
} /* cyz_poll */
#endif /* CONFIG_CYZ_INTR */
@@ -1968,20 +1906,21 @@
*/
static int startup(struct cyclades_port *info)
{
+ struct cyclades_card *card;
unsigned long flags;
int retval = 0;
void __iomem *base_addr;
- int card, chip, channel, index;
+ int chip, channel, index;
unsigned long page;
card = info->card;
- channel = (info->line) - (cy_card[card].first_line);
+ channel = info->line - card->first_line;
page = get_zeroed_page(GFP_KERNEL);
if (!page)
return -ENOMEM;
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
if (info->flags & ASYNC_INITIALIZED) {
free_page(page);
@@ -2001,24 +1940,22 @@
else
info->xmit_buf = (unsigned char *)page;
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
set_line_char(info);
- if (!IS_CYC_Z(cy_card[card])) {
+ if (!IS_CYC_Z(*card)) {
chip = channel >> 2;
channel &= 0x03;
- index = cy_card[card].bus_index;
- base_addr = cy_card[card].base_addr +
- (cy_chip_offset[chip] << index);
+ index = card->bus_index;
+ base_addr = card->base_addr + (cy_chip_offset[chip] << index);
#ifdef CY_DEBUG_OPEN
- printk("cyc startup card %d, chip %d, channel %d, "
- "base_addr %lx\n",
- card, chip, channel, (long)base_addr);
- /**/
+ printk(KERN_DEBUG "cyc startup card %d, chip %d, channel %d, "
+ "base_addr %p\n",
+ card, chip, channel, base_addr);
#endif
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
@@ -2034,14 +1971,14 @@
cy_writeb(base_addr + (CyMSVR2 << index), CyDTR);
#ifdef CY_DEBUG_DTR
- printk("cyc:startup raising DTR\n");
- printk(" status: 0x%x, 0x%x\n",
- cy_readb(base_addr + (CyMSVR1 << index)),
- cy_readb(base_addr + (CyMSVR2 << index)));
+ printk(KERN_DEBUG "cyc:startup raising DTR\n");
+ printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
+ readb(base_addr + (CyMSVR1 << index)),
+ readb(base_addr + (CyMSVR2 << index)));
#endif
cy_writeb(base_addr + (CySRER << index),
- cy_readb(base_addr + (CySRER << index)) | CyRxData);
+ readb(base_addr + (CySRER << index)) | CyRxData);
info->flags |= ASYNC_INITIALIZED;
if (info->tty) {
@@ -2054,7 +1991,7 @@
info->idle_stats.recv_idle =
info->idle_stats.xmit_idle = jiffies;
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
} else {
struct FIRM_ID __iomem *firm_id;
@@ -2063,24 +2000,23 @@
struct CH_CTRL __iomem *ch_ctrl;
int retval;
- base_addr = cy_card[card].base_addr;
+ base_addr = card->base_addr;
firm_id = base_addr + ID_ADDRESS;
- if (!ISZLOADED(cy_card[card])) {
+ if (!ISZLOADED(*card)) {
return -ENODEV;
}
- zfw_ctrl = cy_card[card].base_addr +
- (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
+ zfw_ctrl = card->base_addr +
+ (readl(&firm_id->zfwctrl_addr) & 0xfffff);
board_ctrl = &zfw_ctrl->board_ctrl;
ch_ctrl = zfw_ctrl->ch_ctrl;
#ifdef CY_DEBUG_OPEN
- printk("cyc startup Z card %d, channel %d, base_addr %lx\n",
- card, channel, (long)base_addr);
- /**/
+ printk(KERN_DEBUG "cyc startup Z card %d, channel %d, "
+ "base_addr %p\n", card, channel, base_addr);
#endif
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writel(&ch_ctrl[channel].op_mode, C_CH_ENABLE);
#ifdef Z_WAKE
@@ -2102,33 +2038,31 @@
#endif /* CONFIG_CYZ_INTR */
#endif /* Z_WAKE */
- retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTL, 0L);
+ retval = cyz_issue_cmd(card, channel, C_CM_IOCTL, 0L);
if (retval != 0) {
- printk("cyc:startup(1) retval on ttyC%d was %x\n",
- info->line, retval);
+ printk(KERN_ERR "cyc:startup(1) retval on ttyC%d was "
+ "%x\n", info->line, retval);
}
/* Flush RX buffers before raising DTR and RTS */
- retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_FLUSH_RX,
- 0L);
+ retval = cyz_issue_cmd(card, channel, C_CM_FLUSH_RX, 0L);
if (retval != 0) {
- printk("cyc:startup(2) retval on ttyC%d was %x\n",
- info->line, retval);
+ printk(KERN_ERR "cyc:startup(2) retval on ttyC%d was "
+ "%x\n", info->line, retval);
}
/* set timeout !!! */
/* set RTS and DTR !!! */
cy_writel(&ch_ctrl[channel].rs_control,
- cy_readl(&ch_ctrl[channel].rs_control) | C_RS_RTS |
+ readl(&ch_ctrl[channel].rs_control) | C_RS_RTS |
C_RS_DTR);
- retval = cyz_issue_cmd(&cy_card[info->card], channel,
- C_CM_IOCTLM, 0L);
+ retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM, 0L);
if (retval != 0) {
- printk("cyc:startup(3) retval on ttyC%d was %x\n",
- info->line, retval);
+ printk(KERN_ERR "cyc:startup(3) retval on ttyC%d was "
+ "%x\n", info->line, retval);
}
#ifdef CY_DEBUG_DTR
- printk("cyc:startup raising Z DTR\n");
+ printk(KERN_DEBUG "cyc:startup raising Z DTR\n");
#endif
/* enable send, recv, modem !!! */
@@ -2144,51 +2078,50 @@
info->idle_stats.recv_idle =
info->idle_stats.xmit_idle = jiffies;
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
}
#ifdef CY_DEBUG_OPEN
- printk(" cyc startup done\n");
+ printk(KERN_DEBUG "cyc startup done\n");
#endif
return 0;
errout:
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
return retval;
} /* startup */
static void start_xmit(struct cyclades_port *info)
{
+ struct cyclades_card *card;
unsigned long flags;
void __iomem *base_addr;
- int card, chip, channel, index;
+ int chip, channel, index;
card = info->card;
- channel = (info->line) - (cy_card[card].first_line);
- if (!IS_CYC_Z(cy_card[card])) {
+ channel = info->line - card->first_line;
+ if (!IS_CYC_Z(*card)) {
chip = channel >> 2;
channel &= 0x03;
- index = cy_card[card].bus_index;
- base_addr = cy_card[card].base_addr +
- (cy_chip_offset[chip] << index);
+ index = card->bus_index;
+ base_addr = card->base_addr + (cy_chip_offset[chip] << index);
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writeb(base_addr + (CyCAR << index), channel);
cy_writeb(base_addr + (CySRER << index),
- cy_readb(base_addr + (CySRER << index)) | CyTxRdy);
- CY_UNLOCK(info, flags);
+ readb(base_addr + (CySRER << index)) | CyTxRdy);
+ spin_unlock_irqrestore(&card->card_lock, flags);
} else {
#ifdef CONFIG_CYZ_INTR
int retval;
- CY_LOCK(info, flags);
- retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_INTBACK,
- 0L);
+ spin_lock_irqsave(&card->card_lock, flags);
+ retval = cyz_issue_cmd(card, channel, C_CM_INTBACK, 0L);
if (retval != 0) {
- printk("cyc:start_xmit retval on ttyC%d was %x\n",
- info->line, retval);
+ printk(KERN_ERR "cyc:start_xmit retval on ttyC%d was "
+ "%x\n", info->line, retval);
}
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
#else /* CONFIG_CYZ_INTR */
/* Don't have to do anything at this time */
#endif /* CONFIG_CYZ_INTR */
@@ -2201,30 +2134,30 @@
*/
static void shutdown(struct cyclades_port *info)
{
+ struct cyclades_card *card;
unsigned long flags;
void __iomem *base_addr;
- int card, chip, channel, index;
+ int chip, channel, index;
if (!(info->flags & ASYNC_INITIALIZED)) {
return;
}
card = info->card;
- channel = info->line - cy_card[card].first_line;
- if (!IS_CYC_Z(cy_card[card])) {
+ channel = info->line - card->first_line;
+ if (!IS_CYC_Z(*card)) {
chip = channel >> 2;
channel &= 0x03;
- index = cy_card[card].bus_index;
- base_addr = cy_card[card].base_addr +
- (cy_chip_offset[chip] << index);
+ index = card->bus_index;
+ base_addr = card->base_addr + (cy_chip_offset[chip] << index);
#ifdef CY_DEBUG_OPEN
- printk("cyc shutdown Y card %d, chip %d, channel %d, "
- "base_addr %lx\n",
- card, chip, channel, (long)base_addr);
+ printk(KERN_DEBUG "cyc shutdown Y card %d, chip %d, "
+ "channel %d, base_addr %p\n",
+ card, chip, channel, base_addr);
#endif
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
/* Clear delta_msr_wait queue to avoid mem leaks. */
wake_up_interruptible(&info->delta_msr_wait);
@@ -2240,10 +2173,10 @@
cy_writeb(base_addr + (CyMSVR1 << index), ~CyRTS);
cy_writeb(base_addr + (CyMSVR2 << index), ~CyDTR);
#ifdef CY_DEBUG_DTR
- printk("cyc shutdown dropping DTR\n");
- printk(" status: 0x%x, 0x%x\n",
- cy_readb(base_addr + (CyMSVR1 << index)),
- cy_readb(base_addr + (CyMSVR2 << index)));
+ printk(KERN_DEBUG "cyc shutdown dropping DTR\n");
+ printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
+ readb(base_addr + (CyMSVR1 << index)),
+ readb(base_addr + (CyMSVR2 << index)));
#endif
}
cyy_issue_cmd(base_addr, CyCHAN_CTL | CyDIS_RCVR, index);
@@ -2254,7 +2187,7 @@
set_bit(TTY_IO_ERROR, &info->tty->flags);
}
info->flags &= ~ASYNC_INITIALIZED;
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
} else {
struct FIRM_ID __iomem *firm_id;
struct ZFW_CTRL __iomem *zfw_ctrl;
@@ -2262,23 +2195,23 @@
struct CH_CTRL __iomem *ch_ctrl;
int retval;
- base_addr = cy_card[card].base_addr;
+ base_addr = card->base_addr;
#ifdef CY_DEBUG_OPEN
- printk("cyc shutdown Z card %d, channel %d, base_addr %lx\n",
- card, channel, (long)base_addr);
+ printk(KERN_DEBUG "cyc shutdown Z card %d, channel %d, "
+ "base_addr %p\n", card, channel, base_addr);
#endif
firm_id = base_addr + ID_ADDRESS;
- if (!ISZLOADED(cy_card[card])) {
+ if (!ISZLOADED(*card)) {
return;
}
- zfw_ctrl = cy_card[card].base_addr +
- (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
+ zfw_ctrl = card->base_addr +
+ (readl(&firm_id->zfwctrl_addr) & 0xfffff);
board_ctrl = &zfw_ctrl->board_ctrl;
ch_ctrl = zfw_ctrl->ch_ctrl;
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
if (info->xmit_buf) {
unsigned char *temp;
@@ -2289,16 +2222,16 @@
if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
cy_writel(&ch_ctrl[channel].rs_control,
- (uclong)(cy_readl(&ch_ctrl[channel].rs_control)&
+ (__u32)(readl(&ch_ctrl[channel].rs_control) &
~(C_RS_RTS | C_RS_DTR)));
- retval = cyz_issue_cmd(&cy_card[info->card], channel,
+ retval = cyz_issue_cmd(info->card, channel,
C_CM_IOCTLM, 0L);
if (retval != 0) {
- printk("cyc:shutdown retval on ttyC%d was %x\n",
- info->line, retval);
+ printk(KERN_ERR"cyc:shutdown retval on ttyC%d "
+ "was %x\n", info->line, retval);
}
#ifdef CY_DEBUG_DTR
- printk("cyc:shutdown dropping Z DTR\n");
+ printk(KERN_DEBUG "cyc:shutdown dropping Z DTR\n");
#endif
}
@@ -2307,11 +2240,11 @@
}
info->flags &= ~ASYNC_INITIALIZED;
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
}
#ifdef CY_DEBUG_OPEN
- printk(" cyc shutdown done\n");
+ printk(KERN_DEBUG "cyc shutdown done\n");
#endif
} /* shutdown */
@@ -2332,7 +2265,7 @@
int retval;
void __iomem *base_addr;
- cinfo = &cy_card[info->card];
+ cinfo = info->card;
channel = info->line - cinfo->first_line;
/*
@@ -2340,9 +2273,8 @@
* until it's done, and then try again.
*/
if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) {
- if (info->flags & ASYNC_CLOSING) {
- interruptible_sleep_on(&info->close_wait);
- }
+ wait_event_interruptible(info->close_wait,
+ !(info->flags & ASYNC_CLOSING));
return (info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS;
}
@@ -2365,17 +2297,16 @@
retval = 0;
add_wait_queue(&info->open_wait, &wait);
#ifdef CY_DEBUG_OPEN
- printk("cyc block_til_ready before block: ttyC%d, count = %d\n",
- info->line, info->count);
- /**/
+ printk(KERN_DEBUG "cyc block_til_ready before block: ttyC%d, "
+ "count = %d\n", info->line, info->count);
#endif
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&cinfo->card_lock, flags);
if (!tty_hung_up_p(filp))
info->count--;
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&cinfo->card_lock, flags);
#ifdef CY_DEBUG_COUNT
- printk("cyc block_til_ready: (%d): decrementing count to %d\n",
- current->pid, info->count);
+ printk(KERN_DEBUG "cyc block_til_ready: (%d): decrementing count to "
+ "%d\n", current->pid, info->count);
#endif
info->blocked_open++;
@@ -2386,7 +2317,7 @@
base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index);
while (1) {
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&cinfo->card_lock, flags);
if ((tty->termios->c_cflag & CBAUD)) {
cy_writeb(base_addr + (CyCAR << index),
(u_char) channel);
@@ -2395,15 +2326,14 @@
cy_writeb(base_addr + (CyMSVR2 << index),
CyDTR);
#ifdef CY_DEBUG_DTR
- printk("cyc:block_til_ready raising DTR\n");
- printk(" status: 0x%x, 0x%x\n",
- cy_readb(base_addr +
- (CyMSVR1 << index)),
- cy_readb(base_addr +
- (CyMSVR2 << index)));
+ printk(KERN_DEBUG "cyc:block_til_ready raising "
+ "DTR\n");
+ printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
+ readb(base_addr + (CyMSVR1 << index)),
+ readb(base_addr + (CyMSVR2 << index)));
#endif
}
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&cinfo->card_lock, flags);
set_current_state(TASK_INTERRUPTIBLE);
if (tty_hung_up_p(filp) ||
@@ -2413,26 +2343,25 @@
break;
}
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&cinfo->card_lock, flags);
cy_writeb(base_addr + (CyCAR << index),
(u_char) channel);
if (!(info->flags & ASYNC_CLOSING) && (C_CLOCAL(tty) ||
- (cy_readb(base_addr +
+ (readb(base_addr +
(CyMSVR1 << index)) & CyDCD))) {
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&cinfo->card_lock, flags);
break;
}
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&cinfo->card_lock, flags);
if (signal_pending(current)) {
retval = -ERESTARTSYS;
break;
}
#ifdef CY_DEBUG_OPEN
- printk("cyc block_til_ready blocking: ttyC%d, "
- "count = %d\n",
- info->line, info->count);
- /**/
+ printk(KERN_DEBUG "cyc block_til_ready blocking: "
+ "ttyC%d, count = %d\n",
+ info->line, info->count);
#endif
schedule();
}
@@ -2446,31 +2375,30 @@
base_addr = cinfo->base_addr;
firm_id = base_addr + ID_ADDRESS;
if (!ISZLOADED(*cinfo)) {
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(&info->open_wait, &wait);
return -EINVAL;
}
- zfw_ctrl = base_addr + (cy_readl(&firm_id->zfwctrl_addr) &
- 0xfffff);
+ zfw_ctrl = base_addr + (readl(&firm_id->zfwctrl_addr)& 0xfffff);
board_ctrl = &zfw_ctrl->board_ctrl;
ch_ctrl = zfw_ctrl->ch_ctrl;
while (1) {
if ((tty->termios->c_cflag & CBAUD)) {
cy_writel(&ch_ctrl[channel].rs_control,
- cy_readl(&ch_ctrl[channel].
- rs_control) | (C_RS_RTS |
- C_RS_DTR));
- retval = cyz_issue_cmd(&cy_card[info->card],
- channel, C_CM_IOCTLM, 0L);
+ readl(&ch_ctrl[channel].rs_control) |
+ C_RS_RTS | C_RS_DTR);
+ retval = cyz_issue_cmd(cinfo,
+ channel, C_CM_IOCTLM, 0L);
if (retval != 0) {
- printk("cyc:block_til_ready retval on "
- "ttyC%d was %x\n",
+ printk(KERN_ERR "cyc:block_til_ready "
+ "retval on ttyC%d was %x\n",
info->line, retval);
}
#ifdef CY_DEBUG_DTR
- printk("cyc:block_til_ready raising Z DTR\n");
+ printk(KERN_DEBUG "cyc:block_til_ready raising "
+ "Z DTR\n");
#endif
}
@@ -2482,7 +2410,7 @@
break;
}
if (!(info->flags & ASYNC_CLOSING) && (C_CLOCAL(tty) ||
- (cy_readl(&ch_ctrl[channel].rs_status) &
+ (readl(&ch_ctrl[channel].rs_status) &
C_RS_DCD))) {
break;
}
@@ -2491,28 +2419,26 @@
break;
}
#ifdef CY_DEBUG_OPEN
- printk("cyc block_til_ready blocking: ttyC%d, "
- "count = %d\n",
- info->line, info->count);
- /**/
+ printk(KERN_DEBUG "cyc block_til_ready blocking: "
+ "ttyC%d, count = %d\n",
+ info->line, info->count);
#endif
schedule();
}
}
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(&info->open_wait, &wait);
if (!tty_hung_up_p(filp)) {
info->count++;
#ifdef CY_DEBUG_COUNT
- printk("cyc:block_til_ready (%d): incrementing count to %d\n",
- current->pid, info->count);
+ printk(KERN_DEBUG "cyc:block_til_ready (%d): incrementing "
+ "count to %d\n", current->pid, info->count);
#endif
}
info->blocked_open--;
#ifdef CY_DEBUG_OPEN
- printk("cyc:block_til_ready after blocking: ttyC%d, count = %d\n",
- info->line, info->count);
- /**/
+ printk(KERN_DEBUG "cyc:block_til_ready after blocking: ttyC%d, "
+ "count = %d\n", info->line, info->count);
#endif
if (retval)
return retval;
@@ -2527,13 +2453,20 @@
static int cy_open(struct tty_struct *tty, struct file *filp)
{
struct cyclades_port *info;
+ unsigned int i;
int retval, line;
line = tty->index;
if ((line < 0) || (NR_PORTS <= line)) {
return -ENODEV;
}
- info = &cy_port[line];
+ for (i = 0; i < NR_CARDS; i++)
+ if (line < cy_card[i].first_line + cy_card[i].nports &&
+ line >= cy_card[i].first_line)
+ break;
+ if (i >= NR_CARDS)
+ return -ENODEV;
+ info = &cy_card[i].ports[line - cy_card[i].first_line];
if (info->line < 0) {
return -ENODEV;
}
@@ -2542,23 +2475,23 @@
treat it as absent from the system. This
will make the user pay attention.
*/
- if (IS_CYC_Z(cy_card[info->card])) {
- struct cyclades_card *cinfo = &cy_card[info->card];
+ if (IS_CYC_Z(*info->card)) {
+ struct cyclades_card *cinfo = info->card;
struct FIRM_ID __iomem *firm_id = cinfo->base_addr + ID_ADDRESS;
if (!ISZLOADED(*cinfo)) {
- if (((ZE_V1 == cy_readl(
- &((struct RUNTIME_9060 __iomem *)
+ if (((ZE_V1 == readl(&((struct RUNTIME_9060 __iomem *)
(cinfo->ctl_addr))->mail_box_0)) &&
Z_FPGA_CHECK(*cinfo)) &&
- (ZFIRM_HLT == cy_readl(
+ (ZFIRM_HLT == readl(
&firm_id->signature))) {
- printk("cyc:Cyclades-Z Error: you need an "
- "external power supply for this number "
- "of ports.\n\rFirmware halted.\r\n");
+ printk(KERN_ERR "cyc:Cyclades-Z Error: you "
+ "need an external power supply for "
+ "this number of ports.\nFirmware "
+ "halted.\n");
} else {
- printk("cyc:Cyclades-Z firmware not yet "
- "loaded\n");
+ printk(KERN_ERR "cyc:Cyclades-Z firmware not "
+ "yet loaded\n");
}
return -ENODEV;
}
@@ -2572,24 +2505,23 @@
struct BOARD_CTRL __iomem *board_ctrl;
zfw_ctrl = cinfo->base_addr +
- (cy_readl(&firm_id->zfwctrl_addr) &
- 0xfffff);
+ (readl(&firm_id->zfwctrl_addr) &
+ 0xfffff);
board_ctrl = &zfw_ctrl->board_ctrl;
/* Enable interrupts on the PLX chip */
cy_writew(cinfo->ctl_addr + 0x68,
- cy_readw(cinfo->ctl_addr +
- 0x68) | 0x0900);
+ readw(cinfo->ctl_addr + 0x68) | 0x0900);
/* Enable interrupts on the FW */
retval = cyz_issue_cmd(cinfo, 0,
C_CM_IRQ_ENBL, 0L);
if (retval != 0) {
- printk("cyc:IRQ enable retval was %x\n",
- retval);
+ printk(KERN_ERR "cyc:IRQ enable retval "
+ "was %x\n", retval);
}
cinfo->nports =
- (int)cy_readl(&board_ctrl->n_channel);
+ (int)readl(&board_ctrl->n_channel);
cinfo->intr_enabled = 1;
}
}
@@ -2599,7 +2531,7 @@
return -ENODEV;
}
#ifdef CY_DEBUG_OTHER
- printk("cyc:cy_open ttyC%d\n", info->line); /* */
+ printk(KERN_DEBUG "cyc:cy_open ttyC%d\n", info->line);
#endif
tty->driver_data = info;
info->tty = tty;
@@ -2607,12 +2539,12 @@
return -ENODEV;
}
#ifdef CY_DEBUG_OPEN
- printk("cyc:cy_open ttyC%d, count = %d\n", info->line, info->count);
- /**/
+ printk(KERN_DEBUG "cyc:cy_open ttyC%d, count = %d\n", info->line,
+ info->count);
#endif
info->count++;
#ifdef CY_DEBUG_COUNT
- printk("cyc:cy_open (%d): incrementing count to %d\n",
+ printk(KERN_DEBUG "cyc:cy_open (%d): incrementing count to %d\n",
current->pid, info->count);
#endif
@@ -2620,8 +2552,8 @@
* If the port is the middle of closing, bail out now
*/
if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) {
- if (info->flags & ASYNC_CLOSING)
- interruptible_sleep_on(&info->close_wait);
+ wait_event_interruptible(info->close_wait,
+ !(info->flags & ASYNC_CLOSING));
return (info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS;
}
@@ -2636,8 +2568,8 @@
retval = block_til_ready(tty, filp, info);
if (retval) {
#ifdef CY_DEBUG_OPEN
- printk("cyc:cy_open returning after block_til_ready with %d\n",
- retval);
+ printk(KERN_DEBUG "cyc:cy_open returning after block_til_ready "
+ "with %d\n", retval);
#endif
return retval;
}
@@ -2645,8 +2577,7 @@
info->throttle = 0;
#ifdef CY_DEBUG_OPEN
- printk(" cyc:cy_open done\n");
- /**/
+ printk(KERN_DEBUG "cyc:cy_open done\n");
#endif
return 0;
} /* cy_open */
@@ -2656,9 +2587,10 @@
*/
static void cy_wait_until_sent(struct tty_struct *tty, int timeout)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ struct cyclades_card *card;
+ struct cyclades_port *info = tty->driver_data;
void __iomem *base_addr;
- int card, chip, channel, index;
+ int chip, channel, index;
unsigned long orig_jiffies;
int char_time;
@@ -2697,20 +2629,19 @@
if (!timeout || timeout > 2 * info->timeout)
timeout = 2 * info->timeout;
#ifdef CY_DEBUG_WAIT_UNTIL_SENT
- printk("In cy_wait_until_sent(%d) check=%lu...", timeout, char_time);
- printk("jiff=%lu...", jiffies);
+ printk(KERN_DEBUG "In cy_wait_until_sent(%d) check=%d, jiff=%lu...",
+ timeout, char_time, jiffies);
#endif
card = info->card;
- channel = (info->line) - (cy_card[card].first_line);
- if (!IS_CYC_Z(cy_card[card])) {
+ channel = (info->line) - (card->first_line);
+ if (!IS_CYC_Z(*card)) {
chip = channel >> 2;
channel &= 0x03;
- index = cy_card[card].bus_index;
- base_addr =
- cy_card[card].base_addr + (cy_chip_offset[chip] << index);
- while (cy_readb(base_addr + (CySRER << index)) & CyTxRdy) {
+ index = card->bus_index;
+ base_addr = card->base_addr + (cy_chip_offset[chip] << index);
+ while (readb(base_addr + (CySRER << index)) & CyTxRdy) {
#ifdef CY_DEBUG_WAIT_UNTIL_SENT
- printk("Not clean (jiff=%lu)...", jiffies);
+ printk(KERN_DEBUG "Not clean (jiff=%lu)...", jiffies);
#endif
if (msleep_interruptible(jiffies_to_msecs(char_time)))
break;
@@ -2718,13 +2649,11 @@
timeout))
break;
}
- } else {
- /* Nothing to do! */
}
/* Run one more char cycle */
msleep_interruptible(jiffies_to_msecs(char_time * 5));
#ifdef CY_DEBUG_WAIT_UNTIL_SENT
- printk("Clean (jiff=%lu)...done\n", jiffies);
+ printk(KERN_DEBUG "Clean (jiff=%lu)...done\n", jiffies);
#endif
}
@@ -2733,25 +2662,29 @@
*/
static void cy_close(struct tty_struct *tty, struct file *filp)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ struct cyclades_port *info = tty->driver_data;
+ struct cyclades_card *card;
unsigned long flags;
#ifdef CY_DEBUG_OTHER
- printk("cyc:cy_close ttyC%d\n", info->line);
+ printk(KERN_DEBUG "cyc:cy_close ttyC%d\n", info->line);
#endif
if (!info || serial_paranoia_check(info, tty->name, "cy_close")) {
return;
}
- CY_LOCK(info, flags);
+ card = info->card;
+
+ spin_lock_irqsave(&card->card_lock, flags);
/* If the TTY is being hung up, nothing to do */
if (tty_hung_up_p(filp)) {
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
return;
}
#ifdef CY_DEBUG_OPEN
- printk("cyc:cy_close ttyC%d, count = %d\n", info->line, info->count);
+ printk(KERN_DEBUG "cyc:cy_close ttyC%d, count = %d\n", info->line,
+ info->count);
#endif
if ((tty->count == 1) && (info->count != 1)) {
/*
@@ -2761,22 +2694,22 @@
* one, we've got real problems, since it means the
* serial port won't be shutdown.
*/
- printk("cyc:cy_close: bad serial port count; tty->count is 1, "
- "info->count is %d\n", info->count);
+ printk(KERN_ERR "cyc:cy_close: bad serial port count; "
+ "tty->count is 1, info->count is %d\n", info->count);
info->count = 1;
}
#ifdef CY_DEBUG_COUNT
- printk("cyc:cy_close at (%d): decrementing count to %d\n",
+ printk(KERN_DEBUG "cyc:cy_close at (%d): decrementing count to %d\n",
current->pid, info->count - 1);
#endif
if (--info->count < 0) {
#ifdef CY_DEBUG_COUNT
- printk("cyc:cyc_close setting count to 0\n");
+ printk(KERN_DEBUG "cyc:cyc_close setting count to 0\n");
#endif
info->count = 0;
}
if (info->count) {
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
return;
}
info->flags |= ASYNC_CLOSING;
@@ -2786,81 +2719,80 @@
* the line discipline to only process XON/XOFF characters.
*/
tty->closing = 1;
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
if (info->closing_wait != CY_CLOSING_WAIT_NONE) {
tty_wait_until_sent(tty, info->closing_wait);
}
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
- if (!IS_CYC_Z(cy_card[info->card])) {
- int channel = info->line - cy_card[info->card].first_line;
- int index = cy_card[info->card].bus_index;
- void __iomem *base_addr = cy_card[info->card].base_addr +
+ if (!IS_CYC_Z(*card)) {
+ int channel = info->line - card->first_line;
+ int index = card->bus_index;
+ void __iomem *base_addr = card->base_addr +
(cy_chip_offset[channel >> 2] << index);
/* Stop accepting input */
channel &= 0x03;
cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
cy_writeb(base_addr + (CySRER << index),
- cy_readb(base_addr + (CySRER << index)) & ~CyRxData);
+ readb(base_addr + (CySRER << index)) & ~CyRxData);
if (info->flags & ASYNC_INITIALIZED) {
/* Waiting for on-board buffers to be empty before closing
the port */
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
cy_wait_until_sent(tty, info->timeout);
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
}
} else {
#ifdef Z_WAKE
/* Waiting for on-board buffers to be empty before closing the port */
- void __iomem *base_addr = cy_card[info->card].base_addr;
+ void __iomem *base_addr = card->base_addr;
struct FIRM_ID __iomem *firm_id = base_addr + ID_ADDRESS;
struct ZFW_CTRL __iomem *zfw_ctrl =
- base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
+ base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
struct CH_CTRL __iomem *ch_ctrl = zfw_ctrl->ch_ctrl;
- int channel = info->line - cy_card[info->card].first_line;
+ int channel = info->line - card->first_line;
int retval;
- if (cy_readl(&ch_ctrl[channel].flow_status) != C_FS_TXIDLE) {
- retval = cyz_issue_cmd(&cy_card[info->card], channel,
- C_CM_IOCTLW, 0L);
+ if (readl(&ch_ctrl[channel].flow_status) != C_FS_TXIDLE) {
+ retval = cyz_issue_cmd(card, channel, C_CM_IOCTLW, 0L);
if (retval != 0) {
- printk("cyc:cy_close retval on ttyC%d was %x\n",
- info->line, retval);
+ printk(KERN_DEBUG "cyc:cy_close retval on "
+ "ttyC%d was %x\n", info->line, retval);
}
- CY_UNLOCK(info, flags);
- interruptible_sleep_on(&info->shutdown_wait);
- CY_LOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
+ wait_for_completion_interruptible(&info->shutdown_wait);
+ spin_lock_irqsave(&card->card_lock, flags);
}
#endif
}
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
shutdown(info);
if (tty->driver->flush_buffer)
tty->driver->flush_buffer(tty);
tty_ldisc_flush(tty);
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
tty->closing = 0;
info->event = 0;
info->tty = NULL;
if (info->blocked_open) {
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
if (info->close_delay) {
msleep_interruptible(jiffies_to_msecs
(info->close_delay));
}
wake_up_interruptible(&info->open_wait);
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
}
info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
wake_up_interruptible(&info->close_wait);
#ifdef CY_DEBUG_OTHER
- printk(" cyc:cy_close done\n");
+ printk(KERN_DEBUG "cyc:cy_close done\n");
#endif
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
} /* cy_close */
/* This routine gets called when tty_write has put something into
@@ -2878,12 +2810,12 @@
*/
static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ struct cyclades_port *info = tty->driver_data;
unsigned long flags;
int c, ret = 0;
#ifdef CY_DEBUG_IO
- printk("cyc:cy_write ttyC%d\n", info->line); /* */
+ printk(KERN_DEBUG "cyc:cy_write ttyC%d\n", info->line);
#endif
if (serial_paranoia_check(info, tty->name, "cy_write")) {
@@ -2893,7 +2825,7 @@
if (!info->xmit_buf)
return 0;
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&info->card->card_lock, flags);
while (1) {
c = min(count, min((int)(SERIAL_XMIT_SIZE - info->xmit_cnt - 1),
(int)(SERIAL_XMIT_SIZE - info->xmit_head)));
@@ -2909,7 +2841,7 @@
count -= c;
ret += c;
}
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&info->card->card_lock, flags);
info->idle_stats.xmit_bytes += ret;
info->idle_stats.xmit_idle = jiffies;
@@ -2929,11 +2861,11 @@
*/
static void cy_put_char(struct tty_struct *tty, unsigned char ch)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ struct cyclades_port *info = tty->driver_data;
unsigned long flags;
#ifdef CY_DEBUG_IO
- printk("cyc:cy_put_char ttyC%d\n", info->line);
+ printk(KERN_DEBUG "cyc:cy_put_char ttyC%d\n", info->line);
#endif
if (serial_paranoia_check(info, tty->name, "cy_put_char"))
@@ -2942,9 +2874,9 @@
if (!info->xmit_buf)
return;
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&info->card->card_lock, flags);
if (info->xmit_cnt >= (int)(SERIAL_XMIT_SIZE - 1)) {
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&info->card->card_lock, flags);
return;
}
@@ -2953,7 +2885,7 @@
info->xmit_cnt++;
info->idle_stats.xmit_bytes++;
info->idle_stats.xmit_idle = jiffies;
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&info->card->card_lock, flags);
} /* cy_put_char */
/*
@@ -2962,10 +2894,10 @@
*/
static void cy_flush_chars(struct tty_struct *tty)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ struct cyclades_port *info = tty->driver_data;
#ifdef CY_DEBUG_IO
- printk("cyc:cy_flush_chars ttyC%d\n", info->line); /* */
+ printk(KERN_DEBUG "cyc:cy_flush_chars ttyC%d\n", info->line);
#endif
if (serial_paranoia_check(info, tty->name, "cy_flush_chars"))
@@ -2986,11 +2918,11 @@
*/
static int cy_write_room(struct tty_struct *tty)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ struct cyclades_port *info = tty->driver_data;
int ret;
#ifdef CY_DEBUG_IO
- printk("cyc:cy_write_room ttyC%d\n", info->line); /* */
+ printk(KERN_DEBUG "cyc:cy_write_room ttyC%d\n", info->line);
#endif
if (serial_paranoia_check(info, tty->name, "cy_write_room"))
@@ -3003,46 +2935,49 @@
static int cy_chars_in_buffer(struct tty_struct *tty)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
- int card, channel;
+ struct cyclades_card *card;
+ struct cyclades_port *info = tty->driver_data;
+ int channel;
if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer"))
return 0;
card = info->card;
- channel = (info->line) - (cy_card[card].first_line);
+ channel = (info->line) - (card->first_line);
#ifdef Z_EXT_CHARS_IN_BUFFER
if (!IS_CYC_Z(cy_card[card])) {
#endif /* Z_EXT_CHARS_IN_BUFFER */
#ifdef CY_DEBUG_IO
- printk("cyc:cy_chars_in_buffer ttyC%d %d\n", info->line, info->xmit_cnt); /* */
+ printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n",
+ info->line, info->xmit_cnt);
#endif
return info->xmit_cnt;
#ifdef Z_EXT_CHARS_IN_BUFFER
} else {
- static volatile struct FIRM_ID *firm_id;
- static volatile struct ZFW_CTRL *zfw_ctrl;
- static volatile struct CH_CTRL *ch_ctrl;
- static volatile struct BUF_CTRL *buf_ctrl;
+ static struct FIRM_ID *firm_id;
+ static struct ZFW_CTRL *zfw_ctrl;
+ static struct CH_CTRL *ch_ctrl;
+ static struct BUF_CTRL *buf_ctrl;
int char_count;
- volatile uclong tx_put, tx_get, tx_bufsize;
+ __u32 tx_put, tx_get, tx_bufsize;
- firm_id = cy_card[card].base_addr + ID_ADDRESS;
- zfw_ctrl = cy_card[card].base_addr +
- (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
+ firm_id = card->base_addr + ID_ADDRESS;
+ zfw_ctrl = card->base_addr +
+ (readl(&firm_id->zfwctrl_addr) & 0xfffff);
ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
- tx_get = cy_readl(&buf_ctrl->tx_get);
- tx_put = cy_readl(&buf_ctrl->tx_put);
- tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize);
+ tx_get = readl(&buf_ctrl->tx_get);
+ tx_put = readl(&buf_ctrl->tx_put);
+ tx_bufsize = readl(&buf_ctrl->tx_bufsize);
if (tx_put >= tx_get)
char_count = tx_put - tx_get;
else
char_count = tx_put - tx_get + tx_bufsize;
#ifdef CY_DEBUG_IO
- printk("cyc:cy_chars_in_buffer ttyC%d %d\n", info->line, info->xmit_cnt + char_count); /* */
+ printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n",
+ info->line, info->xmit_cnt + char_count);
#endif
return info->xmit_cnt + char_count;
}
@@ -3055,10 +2990,10 @@
* ------------------------------------------------------------
*/
-static void cyy_baud_calc(struct cyclades_port *info, uclong baud)
+static void cyy_baud_calc(struct cyclades_port *info, __u32 baud)
{
int co, co_val, bpr;
- uclong cy_clock = ((info->chip_rev >= CD1400_REV_J) ? 60000000 :
+ __u32 cy_clock = ((info->chip_rev >= CD1400_REV_J) ? 60000000 :
25000000);
if (baud == 0) {
@@ -3086,9 +3021,10 @@
*/
static void set_line_char(struct cyclades_port *info)
{
+ struct cyclades_card *card;
unsigned long flags;
void __iomem *base_addr;
- int card, chip, channel, index;
+ int chip, channel, index;
unsigned cflag, iflag;
unsigned short chip_number;
int baud, baud_rate = 0;
@@ -3118,12 +3054,12 @@
}
card = info->card;
- channel = (info->line) - (cy_card[card].first_line);
+ channel = info->line - card->first_line;
chip_number = channel / 4;
- if (!IS_CYC_Z(cy_card[card])) {
+ if (!IS_CYC_Z(*card)) {
- index = cy_card[card].bus_index;
+ index = card->bus_index;
/* baud rate */
baud = tty_get_baud_rate(info->tty);
@@ -3241,10 +3177,9 @@
chip = channel >> 2;
channel &= 0x03;
- base_addr = cy_card[card].base_addr +
- (cy_chip_offset[chip] << index);
+ base_addr = card->base_addr + (cy_chip_offset[chip] << index);
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
/* tx and rx baud rate */
@@ -3276,8 +3211,7 @@
if (C_CLOCAL(info->tty)) {
/* without modem intr */
cy_writeb(base_addr + (CySRER << index),
- cy_readb(base_addr +
- (CySRER << index)) | CyMdmCh);
+ readb(base_addr + (CySRER << index)) | CyMdmCh);
/* act on 1->0 modem transitions */
if ((cflag & CRTSCTS) && info->rflow) {
cy_writeb(base_addr + (CyMCOR1 << index),
@@ -3291,7 +3225,7 @@
} else {
/* without modem intr */
cy_writeb(base_addr + (CySRER << index),
- cy_readb(base_addr +
+ readb(base_addr +
(CySRER << index)) | CyMdmCh);
/* act on 1->0 modem transitions */
if ((cflag & CRTSCTS) && info->rflow) {
@@ -3316,10 +3250,10 @@
~CyDTR);
}
#ifdef CY_DEBUG_DTR
- printk("cyc:set_line_char dropping DTR\n");
- printk(" status: 0x%x, 0x%x\n",
- cy_readb(base_addr + (CyMSVR1 << index)),
- cy_readb(base_addr + (CyMSVR2 << index)));
+ printk(KERN_DEBUG "cyc:set_line_char dropping DTR\n");
+ printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
+ readb(base_addr + (CyMSVR1 << index)),
+ readb(base_addr + (CyMSVR2 << index)));
#endif
} else {
if (info->rtsdtr_inv) {
@@ -3330,17 +3264,17 @@
CyDTR);
}
#ifdef CY_DEBUG_DTR
- printk("cyc:set_line_char raising DTR\n");
- printk(" status: 0x%x, 0x%x\n",
- cy_readb(base_addr + (CyMSVR1 << index)),
- cy_readb(base_addr + (CyMSVR2 << index)));
+ printk(KERN_DEBUG "cyc:set_line_char raising DTR\n");
+ printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
+ readb(base_addr + (CyMSVR1 << index)),
+ readb(base_addr + (CyMSVR2 << index)));
#endif
}
if (info->tty) {
clear_bit(TTY_IO_ERROR, &info->tty->flags);
}
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
} else {
struct FIRM_ID __iomem *firm_id;
@@ -3348,16 +3282,16 @@
struct BOARD_CTRL __iomem *board_ctrl;
struct CH_CTRL __iomem *ch_ctrl;
struct BUF_CTRL __iomem *buf_ctrl;
- uclong sw_flow;
+ __u32 sw_flow;
int retval;
- firm_id = cy_card[card].base_addr + ID_ADDRESS;
- if (!ISZLOADED(cy_card[card])) {
+ firm_id = card->base_addr + ID_ADDRESS;
+ if (!ISZLOADED(*card)) {
return;
}
- zfw_ctrl = cy_card[card].base_addr +
- (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
+ zfw_ctrl = card->base_addr +
+ (readl(&firm_id->zfwctrl_addr) & 0xfffff);
board_ctrl = &zfw_ctrl->board_ctrl;
ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
buf_ctrl = &zfw_ctrl->buf_ctrl[channel];
@@ -3408,10 +3342,10 @@
}
if (cflag & CSTOPB) {
cy_writel(&ch_ctrl->comm_data_l,
- cy_readl(&ch_ctrl->comm_data_l) | C_DL_2STOP);
+ readl(&ch_ctrl->comm_data_l) | C_DL_2STOP);
} else {
cy_writel(&ch_ctrl->comm_data_l,
- cy_readl(&ch_ctrl->comm_data_l) | C_DL_1STOP);
+ readl(&ch_ctrl->comm_data_l) | C_DL_1STOP);
}
if (cflag & PARENB) {
if (cflag & PARODD) {
@@ -3426,12 +3360,10 @@
/* CTS flow control flag */
if (cflag & CRTSCTS) {
cy_writel(&ch_ctrl->hw_flow,
- cy_readl(&ch_ctrl->
- hw_flow) | C_RS_CTS | C_RS_RTS);
+ readl(&ch_ctrl->hw_flow) | C_RS_CTS | C_RS_RTS);
} else {
- cy_writel(&ch_ctrl->hw_flow,
- cy_readl(&ch_ctrl->
- hw_flow) & ~(C_RS_CTS | C_RS_RTS));
+ cy_writel(&ch_ctrl->hw_flow, readl(&ch_ctrl->hw_flow) &
+ ~(C_RS_CTS | C_RS_RTS));
}
/* As the HW flow control is done in firmware, the driver
doesn't need to care about it */
@@ -3446,10 +3378,10 @@
}
cy_writel(&ch_ctrl->sw_flow, sw_flow);
- retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTL, 0L);
+ retval = cyz_issue_cmd(card, channel, C_CM_IOCTL, 0L);
if (retval != 0) {
- printk("cyc:set_line_char retval on ttyC%d was %x\n",
- info->line, retval);
+ printk(KERN_ERR "cyc:set_line_char retval on ttyC%d "
+ "was %x\n", info->line, retval);
}
/* CD sensitivity */
@@ -3461,22 +3393,22 @@
if (baud == 0) { /* baud rate is zero, turn off line */
cy_writel(&ch_ctrl->rs_control,
- cy_readl(&ch_ctrl->rs_control) & ~C_RS_DTR);
+ readl(&ch_ctrl->rs_control) & ~C_RS_DTR);
#ifdef CY_DEBUG_DTR
- printk("cyc:set_line_char dropping Z DTR\n");
+ printk(KERN_DEBUG "cyc:set_line_char dropping Z DTR\n");
#endif
} else {
cy_writel(&ch_ctrl->rs_control,
- cy_readl(&ch_ctrl->rs_control) | C_RS_DTR);
+ readl(&ch_ctrl->rs_control) | C_RS_DTR);
#ifdef CY_DEBUG_DTR
- printk("cyc:set_line_char raising Z DTR\n");
+ printk(KERN_DEBUG "cyc:set_line_char raising Z DTR\n");
#endif
}
- retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTLM,0L);
+ retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM,0L);
if (retval != 0) {
- printk("cyc:set_line_char(2) retval on ttyC%d was %x\n",
- info->line, retval);
+ printk(KERN_ERR "cyc:set_line_char(2) retval on ttyC%d "
+ "was %x\n", info->line, retval);
}
if (info->tty) {
@@ -3490,14 +3422,15 @@
struct serial_struct __user * retinfo)
{
struct serial_struct tmp;
- struct cyclades_card *cinfo = &cy_card[info->card];
+ struct cyclades_card *cinfo = info->card;
if (!retinfo)
return -EFAULT;
memset(&tmp, 0, sizeof(tmp));
tmp.type = info->type;
tmp.line = info->line;
- tmp.port = info->card * 0x100 + info->line - cinfo->first_line;
+ tmp.port = (info->card - cy_card) * 0x100 + info->line -
+ cinfo->first_line;
tmp.irq = cinfo->irq;
tmp.flags = info->flags;
tmp.close_delay = info->close_delay;
@@ -3566,25 +3499,25 @@
*/
static int get_lsr_info(struct cyclades_port *info, unsigned int __user * value)
{
- int card, chip, channel, index;
+ struct cyclades_card *card;
+ int chip, channel, index;
unsigned char status;
unsigned int result;
unsigned long flags;
void __iomem *base_addr;
card = info->card;
- channel = (info->line) - (cy_card[card].first_line);
- if (!IS_CYC_Z(cy_card[card])) {
+ channel = (info->line) - (card->first_line);
+ if (!IS_CYC_Z(*card)) {
chip = channel >> 2;
channel &= 0x03;
- index = cy_card[card].bus_index;
- base_addr =
- cy_card[card].base_addr + (cy_chip_offset[chip] << index);
+ index = card->bus_index;
+ base_addr = card->base_addr + (cy_chip_offset[chip] << index);
- CY_LOCK(info, flags);
- status = cy_readb(base_addr + (CySRER << index)) &
+ spin_lock_irqsave(&card->card_lock, flags);
+ status = readb(base_addr + (CySRER << index)) &
(CyTxRdy | CyTxMpty);
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
result = (status ? 0 : TIOCSER_TEMT);
} else {
/* Not supported yet */
@@ -3595,8 +3528,9 @@
static int cy_tiocmget(struct tty_struct *tty, struct file *file)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
- int card, chip, channel, index;
+ struct cyclades_port *info = tty->driver_data;
+ struct cyclades_card *card;
+ int chip, channel, index;
void __iomem *base_addr;
unsigned long flags;
unsigned char status;
@@ -3611,19 +3545,18 @@
return -ENODEV;
card = info->card;
- channel = (info->line) - (cy_card[card].first_line);
- if (!IS_CYC_Z(cy_card[card])) {
+ channel = info->line - card->first_line;
+ if (!IS_CYC_Z(*card)) {
chip = channel >> 2;
channel &= 0x03;
- index = cy_card[card].bus_index;
- base_addr =
- cy_card[card].base_addr + (cy_chip_offset[chip] << index);
+ index = card->bus_index;
+ base_addr = card->base_addr + (cy_chip_offset[chip] << index);
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
- status = cy_readb(base_addr + (CyMSVR1 << index));
- status |= cy_readb(base_addr + (CyMSVR2 << index));
- CY_UNLOCK(info, flags);
+ status = readb(base_addr + (CyMSVR1 << index));
+ status |= readb(base_addr + (CyMSVR2 << index));
+ spin_unlock_irqrestore(&card->card_lock, flags);
if (info->rtsdtr_inv) {
result = ((status & CyRTS) ? TIOCM_DTR : 0) |
@@ -3637,19 +3570,14 @@
((status & CyDSR) ? TIOCM_DSR : 0) |
((status & CyCTS) ? TIOCM_CTS : 0);
} else {
- base_addr = cy_card[card].base_addr;
-
- if (cy_card[card].num_chips != -1) {
- return -EINVAL;
- }
-
- firm_id = cy_card[card].base_addr + ID_ADDRESS;
- if (ISZLOADED(cy_card[card])) {
- zfw_ctrl = cy_card[card].base_addr +
- (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
+ base_addr = card->base_addr;
+ firm_id = card->base_addr + ID_ADDRESS;
+ if (ISZLOADED(*card)) {
+ zfw_ctrl = card->base_addr +
+ (readl(&firm_id->zfwctrl_addr) & 0xfffff);
board_ctrl = &zfw_ctrl->board_ctrl;
ch_ctrl = zfw_ctrl->ch_ctrl;
- lstatus = cy_readl(&ch_ctrl[channel].rs_status);
+ lstatus = readl(&ch_ctrl[channel].rs_status);
result = ((lstatus & C_RS_RTS) ? TIOCM_RTS : 0) |
((lstatus & C_RS_DTR) ? TIOCM_DTR : 0) |
((lstatus & C_RS_DCD) ? TIOCM_CAR : 0) |
@@ -3669,8 +3597,9 @@
cy_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
- int card, chip, channel, index;
+ struct cyclades_port *info = tty->driver_data;
+ struct cyclades_card *card;
+ int chip, channel, index;
void __iomem *base_addr;
unsigned long flags;
struct FIRM_ID __iomem *firm_id;
@@ -3683,16 +3612,15 @@
return -ENODEV;
card = info->card;
- channel = (info->line) - (cy_card[card].first_line);
- if (!IS_CYC_Z(cy_card[card])) {
+ channel = (info->line) - (card->first_line);
+ if (!IS_CYC_Z(*card)) {
chip = channel >> 2;
channel &= 0x03;
- index = cy_card[card].bus_index;
- base_addr =
- cy_card[card].base_addr + (cy_chip_offset[chip] << index);
+ index = card->bus_index;
+ base_addr = card->base_addr + (cy_chip_offset[chip] << index);
if (set & TIOCM_RTS) {
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writeb(base_addr + (CyCAR << index),
(u_char) channel);
if (info->rtsdtr_inv) {
@@ -3702,10 +3630,10 @@
cy_writeb(base_addr + (CyMSVR1 << index),
CyRTS);
}
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
}
if (clear & TIOCM_RTS) {
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writeb(base_addr + (CyCAR << index),
(u_char) channel);
if (info->rtsdtr_inv) {
@@ -3715,10 +3643,10 @@
cy_writeb(base_addr + (CyMSVR1 << index),
~CyRTS);
}
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
}
if (set & TIOCM_DTR) {
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writeb(base_addr + (CyCAR << index),
(u_char) channel);
if (info->rtsdtr_inv) {
@@ -3729,15 +3657,15 @@
CyDTR);
}
#ifdef CY_DEBUG_DTR
- printk("cyc:set_modem_info raising DTR\n");
- printk(" status: 0x%x, 0x%x\n",
- cy_readb(base_addr + (CyMSVR1 << index)),
- cy_readb(base_addr + (CyMSVR2 << index)));
+ printk(KERN_DEBUG "cyc:set_modem_info raising DTR\n");
+ printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
+ readb(base_addr + (CyMSVR1 << index)),
+ readb(base_addr + (CyMSVR2 << index)));
#endif
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
}
if (clear & TIOCM_DTR) {
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writeb(base_addr + (CyCAR << index),
(u_char) channel);
if (info->rtsdtr_inv) {
@@ -3749,68 +3677,69 @@
}
#ifdef CY_DEBUG_DTR
- printk("cyc:set_modem_info dropping DTR\n");
- printk(" status: 0x%x, 0x%x\n",
- cy_readb(base_addr + (CyMSVR1 << index)),
- cy_readb(base_addr + (CyMSVR2 << index)));
+ printk(KERN_DEBUG "cyc:set_modem_info dropping DTR\n");
+ printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
+ readb(base_addr + (CyMSVR1 << index)),
+ readb(base_addr + (CyMSVR2 << index)));
#endif
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
}
} else {
- base_addr = cy_card[card].base_addr;
+ base_addr = card->base_addr;
- firm_id = cy_card[card].base_addr + ID_ADDRESS;
- if (ISZLOADED(cy_card[card])) {
- zfw_ctrl = cy_card[card].base_addr +
- (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
+ firm_id = card->base_addr + ID_ADDRESS;
+ if (ISZLOADED(*card)) {
+ zfw_ctrl = card->base_addr +
+ (readl(&firm_id->zfwctrl_addr) & 0xfffff);
board_ctrl = &zfw_ctrl->board_ctrl;
ch_ctrl = zfw_ctrl->ch_ctrl;
if (set & TIOCM_RTS) {
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writel(&ch_ctrl[channel].rs_control,
- cy_readl(&ch_ctrl[channel].
- rs_control) | C_RS_RTS);
- CY_UNLOCK(info, flags);
+ readl(&ch_ctrl[channel].rs_control) |
+ C_RS_RTS);
+ spin_unlock_irqrestore(&card->card_lock, flags);
}
if (clear & TIOCM_RTS) {
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writel(&ch_ctrl[channel].rs_control,
- cy_readl(&ch_ctrl[channel].
- rs_control) & ~C_RS_RTS);
- CY_UNLOCK(info, flags);
+ readl(&ch_ctrl[channel].rs_control) &
+ ~C_RS_RTS);
+ spin_unlock_irqrestore(&card->card_lock, flags);
}
if (set & TIOCM_DTR) {
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writel(&ch_ctrl[channel].rs_control,
- cy_readl(&ch_ctrl[channel].
- rs_control) | C_RS_DTR);
+ readl(&ch_ctrl[channel].rs_control) |
+ C_RS_DTR);
#ifdef CY_DEBUG_DTR
- printk("cyc:set_modem_info raising Z DTR\n");
+ printk(KERN_DEBUG "cyc:set_modem_info raising "
+ "Z DTR\n");
#endif
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
}
if (clear & TIOCM_DTR) {
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writel(&ch_ctrl[channel].rs_control,
- cy_readl(&ch_ctrl[channel].
- rs_control) & ~C_RS_DTR);
+ readl(&ch_ctrl[channel].rs_control) &
+ ~C_RS_DTR);
#ifdef CY_DEBUG_DTR
- printk("cyc:set_modem_info clearing Z DTR\n");
+ printk(KERN_DEBUG "cyc:set_modem_info clearing "
+ "Z DTR\n");
#endif
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
}
} else {
return -ENODEV;
}
- CY_LOCK(info, flags);
- retval = cyz_issue_cmd(&cy_card[info->card],
- channel, C_CM_IOCTLM, 0L);
+ spin_lock_irqsave(&card->card_lock, flags);
+ retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM, 0L);
if (retval != 0) {
- printk("cyc:set_modem_info retval on ttyC%d was %x\n",
- info->line, retval);
+ printk(KERN_ERR "cyc:set_modem_info retval on ttyC%d "
+ "was %x\n", info->line, retval);
}
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
}
return 0;
} /* cy_tiocmset */
@@ -3820,14 +3749,17 @@
*/
static void cy_break(struct tty_struct *tty, int break_state)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ struct cyclades_port *info = tty->driver_data;
+ struct cyclades_card *card;
unsigned long flags;
if (serial_paranoia_check(info, tty->name, "cy_break"))
return;
- CY_LOCK(info, flags);
- if (!IS_CYC_Z(cy_card[info->card])) {
+ card = info->card;
+
+ spin_lock_irqsave(&card->card_lock, flags);
+ if (!IS_CYC_Z(*card)) {
/* Let the transmit ISR take care of this (since it
requires stuffing characters into the output stream).
*/
@@ -3835,18 +3767,18 @@
if (!info->breakon) {
info->breakon = 1;
if (!info->xmit_cnt) {
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
start_xmit(info);
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
}
}
} else {
if (!info->breakoff) {
info->breakoff = 1;
if (!info->xmit_cnt) {
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
start_xmit(info);
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
}
}
}
@@ -3854,24 +3786,25 @@
int retval;
if (break_state == -1) {
- retval = cyz_issue_cmd(&cy_card[info->card],
- info->line - cy_card[info->card].first_line,
+ retval = cyz_issue_cmd(card,
+ info->line - card->first_line,
C_CM_SET_BREAK, 0L);
if (retval != 0) {
- printk("cyc:cy_break (set) retval on ttyC%d "
- "was %x\n", info->line, retval);
+ printk(KERN_ERR "cyc:cy_break (set) retval on "
+ "ttyC%d was %x\n", info->line, retval);
}
} else {
- retval = cyz_issue_cmd(&cy_card[info->card],
- info->line - cy_card[info->card].first_line,
+ retval = cyz_issue_cmd(card,
+ info->line - card->first_line,
C_CM_CLR_BREAK, 0L);
if (retval != 0) {
- printk("cyc:cy_break (clr) retval on ttyC%d "
- "was %x\n", info->line, retval);
+ printk(KERN_DEBUG "cyc:cy_break (clr) retval "
+ "on ttyC%d was %x\n", info->line,
+ retval);
}
}
}
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
} /* cy_break */
static int
@@ -3889,28 +3822,27 @@
static int set_threshold(struct cyclades_port *info, unsigned long value)
{
+ struct cyclades_card *card;
void __iomem *base_addr;
- int card, channel, chip, index;
+ int channel, chip, index;
unsigned long flags;
card = info->card;
- channel = info->line - cy_card[card].first_line;
- if (!IS_CYC_Z(cy_card[card])) {
+ channel = info->line - card->first_line;
+ if (!IS_CYC_Z(*card)) {
chip = channel >> 2;
channel &= 0x03;
- index = cy_card[card].bus_index;
+ index = card->bus_index;
base_addr =
- cy_card[card].base_addr + (cy_chip_offset[chip] << index);
+ card->base_addr + (cy_chip_offset[chip] << index);
info->cor3 &= ~CyREC_FIFO;
info->cor3 |= value & CyREC_FIFO;
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writeb(base_addr + (CyCOR3 << index), info->cor3);
cyy_issue_cmd(base_addr, CyCOR_CHANGE | CyCOR3ch, index);
- CY_UNLOCK(info, flags);
- } else {
- /* Nothing to do! */
+ spin_unlock_irqrestore(&card->card_lock, flags);
}
return 0;
} /* set_threshold */
@@ -3918,25 +3850,23 @@
static int
get_threshold(struct cyclades_port *info, unsigned long __user * value)
{
+ struct cyclades_card *card;
void __iomem *base_addr;
- int card, channel, chip, index;
+ int channel, chip, index;
unsigned long tmp;
card = info->card;
- channel = info->line - cy_card[card].first_line;
- if (!IS_CYC_Z(cy_card[card])) {
+ channel = info->line - card->first_line;
+ if (!IS_CYC_Z(*card)) {
chip = channel >> 2;
channel &= 0x03;
- index = cy_card[card].bus_index;
- base_addr =
- cy_card[card].base_addr + (cy_chip_offset[chip] << index);
+ index = card->bus_index;
+ base_addr = card->base_addr + (cy_chip_offset[chip] << index);
- tmp = cy_readb(base_addr + (CyCOR3 << index)) & CyREC_FIFO;
+ tmp = readb(base_addr + (CyCOR3 << index)) & CyREC_FIFO;
return put_user(tmp, value);
- } else {
- /* Nothing to do! */
- return 0;
}
+ return 0;
} /* get_threshold */
static int
@@ -3954,49 +3884,45 @@
static int set_timeout(struct cyclades_port *info, unsigned long value)
{
+ struct cyclades_card *card;
void __iomem *base_addr;
- int card, channel, chip, index;
+ int channel, chip, index;
unsigned long flags;
card = info->card;
- channel = info->line - cy_card[card].first_line;
- if (!IS_CYC_Z(cy_card[card])) {
+ channel = info->line - card->first_line;
+ if (!IS_CYC_Z(*card)) {
chip = channel >> 2;
channel &= 0x03;
- index = cy_card[card].bus_index;
- base_addr =
- cy_card[card].base_addr + (cy_chip_offset[chip] << index);
+ index = card->bus_index;
+ base_addr = card->base_addr + (cy_chip_offset[chip] << index);
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writeb(base_addr + (CyRTPR << index), value & 0xff);
- CY_UNLOCK(info, flags);
- } else {
- /* Nothing to do! */
+ spin_unlock_irqrestore(&card->card_lock, flags);
}
return 0;
} /* set_timeout */
static int get_timeout(struct cyclades_port *info, unsigned long __user * value)
{
+ struct cyclades_card *card;
void __iomem *base_addr;
- int card, channel, chip, index;
+ int channel, chip, index;
unsigned long tmp;
card = info->card;
- channel = info->line - cy_card[card].first_line;
- if (!IS_CYC_Z(cy_card[card])) {
+ channel = info->line - card->first_line;
+ if (!IS_CYC_Z(*card)) {
chip = channel >> 2;
channel &= 0x03;
- index = cy_card[card].bus_index;
- base_addr =
- cy_card[card].base_addr + (cy_chip_offset[chip] << index);
+ index = card->bus_index;
+ base_addr = card->base_addr + (cy_chip_offset[chip] << index);
- tmp = cy_readb(base_addr + (CyRTPR << index));
+ tmp = readb(base_addr + (CyRTPR << index));
return put_user(tmp, value);
- } else {
- /* Nothing to do! */
- return 0;
}
+ return 0;
} /* get_timeout */
static int set_default_timeout(struct cyclades_port *info, unsigned long value)
@@ -4020,7 +3946,7 @@
cy_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ struct cyclades_port *info = tty->driver_data;
struct cyclades_icount cprev, cnow; /* kernel counter temps */
struct serial_icounter_struct __user *p_cuser; /* user space */
int ret_val = 0;
@@ -4031,7 +3957,8 @@
return -ENODEV;
#ifdef CY_DEBUG_OTHER
- printk("cyc:cy_ioctl ttyC%d, cmd = %x arg = %lx\n", info->line, cmd, arg); /* */
+ printk(KERN_DEBUG "cyc:cy_ioctl ttyC%d, cmd = %x arg = %lx\n",
+ info->line, cmd, arg);
#endif
switch (cmd) {
@@ -4076,14 +4003,6 @@
case CYGETRTSDTR_INV:
ret_val = info->rtsdtr_inv;
break;
- case CYGETCARDINFO:
- if (copy_to_user(argp, &cy_card[info->card],
- sizeof(struct cyclades_card))) {
- ret_val = -EFAULT;
- break;
- }
- ret_val = 0;
- break;
case CYGETCD1400VER:
ret_val = info->chip_rev;
break;
@@ -4119,34 +4038,22 @@
* Caller should use TIOCGICOUNT to see which one it was
*/
case TIOCMIWAIT:
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&info->card->card_lock, flags);
/* note the counters on entry */
- cprev = info->icount;
- CY_UNLOCK(info, flags);
- while (1) {
- interruptible_sleep_on(&info->delta_msr_wait);
- /* see if a signal did it */
- if (signal_pending(current)) {
- return -ERESTARTSYS;
- }
-
- CY_LOCK(info, flags);
- cnow = info->icount; /* atomic copy */
- CY_UNLOCK(info, flags);
-
- if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
- cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) {
- return -EIO; /* no change => error */
- }
- if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
- ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
- ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
- ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) {
- return 0;
- }
+ cnow = info->icount;
+ spin_unlock_irqrestore(&info->card->card_lock, flags);
+ ret_val = wait_event_interruptible(info->delta_msr_wait, ({
cprev = cnow;
- }
- /* NOTREACHED */
+ spin_lock_irqsave(&info->card->card_lock, flags);
+ cnow = info->icount; /* atomic copy */
+ spin_unlock_irqrestore(&info->card->card_lock, flags);
+
+ ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
+ ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
+ ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
+ ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts));
+ }));
+ break;
/*
* Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
@@ -4155,9 +4062,9 @@
* RI where only 0->1 is counted.
*/
case TIOCGICOUNT:
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&info->card->card_lock, flags);
cnow = info->icount;
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&info->card->card_lock, flags);
p_cuser = argp;
ret_val = put_user(cnow.cts, &p_cuser->cts);
if (ret_val)
@@ -4199,7 +4106,7 @@
}
#ifdef CY_DEBUG_OTHER
- printk(" cyc:cy_ioctl done\n");
+ printk(KERN_DEBUG "cyc:cy_ioctl done\n");
#endif
return ret_val;
@@ -4213,10 +4120,10 @@
*/
static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ struct cyclades_port *info = tty->driver_data;
#ifdef CY_DEBUG_OTHER
- printk("cyc:cy_set_termios ttyC%d\n", info->line);
+ printk(KERN_DEBUG "cyc:cy_set_termios ttyC%d\n", info->line);
#endif
if (tty->termios->c_cflag == old_termios->c_cflag &&
@@ -4248,8 +4155,9 @@
*/
static void cy_send_xchar(struct tty_struct *tty, char ch)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
- int card, channel;
+ struct cyclades_port *info = tty->driver_data;
+ struct cyclades_card *card;
+ int channel;
if (serial_paranoia_check(info, tty->name, "cy_send_xchar"))
return;
@@ -4260,15 +4168,13 @@
cy_start(tty);
card = info->card;
- channel = info->line - cy_card[card].first_line;
+ channel = info->line - card->first_line;
- if (IS_CYC_Z(cy_card[card])) {
+ if (IS_CYC_Z(*card)) {
if (ch == STOP_CHAR(tty))
- cyz_issue_cmd(&cy_card[card], channel, C_CM_SENDXOFF,
- 0L);
+ cyz_issue_cmd(card, channel, C_CM_SENDXOFF, 0L);
else if (ch == START_CHAR(tty))
- cyz_issue_cmd(&cy_card[card], channel, C_CM_SENDXON,
- 0L);
+ cyz_issue_cmd(card, channel, C_CM_SENDXON, 0L);
}
}
@@ -4278,15 +4184,16 @@
*/
static void cy_throttle(struct tty_struct *tty)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ struct cyclades_port *info = tty->driver_data;
+ struct cyclades_card *card;
unsigned long flags;
void __iomem *base_addr;
- int card, chip, channel, index;
+ int chip, channel, index;
#ifdef CY_DEBUG_THROTTLE
char buf[64];
- printk("cyc:throttle %s: %d....ttyC%d\n", tty_name(tty, buf),
+ printk(KERN_DEBUG "cyc:throttle %s: %ld...ttyC%d\n", tty_name(tty, buf),
tty->ldisc.chars_in_buffer(tty), info->line);
#endif
@@ -4297,22 +4204,22 @@
card = info->card;
if (I_IXOFF(tty)) {
- if (!IS_CYC_Z(cy_card[card]))
+ if (!IS_CYC_Z(*card))
cy_send_xchar(tty, STOP_CHAR(tty));
else
info->throttle = 1;
}
if (tty->termios->c_cflag & CRTSCTS) {
- channel = info->line - cy_card[card].first_line;
- if (!IS_CYC_Z(cy_card[card])) {
+ channel = info->line - card->first_line;
+ if (!IS_CYC_Z(*card)) {
chip = channel >> 2;
channel &= 0x03;
- index = cy_card[card].bus_index;
- base_addr = cy_card[card].base_addr +
+ index = card->bus_index;
+ base_addr = card->base_addr +
(cy_chip_offset[chip] << index);
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writeb(base_addr + (CyCAR << index),
(u_char) channel);
if (info->rtsdtr_inv) {
@@ -4322,7 +4229,7 @@
cy_writeb(base_addr + (CyMSVR1 << index),
~CyRTS);
}
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
} else {
info->throttle = 1;
}
@@ -4336,16 +4243,17 @@
*/
static void cy_unthrottle(struct tty_struct *tty)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ struct cyclades_port *info = tty->driver_data;
+ struct cyclades_card *card;
unsigned long flags;
void __iomem *base_addr;
- int card, chip, channel, index;
+ int chip, channel, index;
#ifdef CY_DEBUG_THROTTLE
char buf[64];
- printk("cyc:unthrottle %s: %d....ttyC%d\n", tty_name(tty, buf),
- tty->ldisc.chars_in_buffer(tty), info->line);
+ printk(KERN_DEBUG "cyc:unthrottle %s: %ld...ttyC%d\n",
+ tty_name(tty, buf), tty->ldisc.chars_in_buffer(tty),info->line);
#endif
if (serial_paranoia_check(info, tty->name, "cy_unthrottle")) {
@@ -4361,15 +4269,15 @@
if (tty->termios->c_cflag & CRTSCTS) {
card = info->card;
- channel = info->line - cy_card[card].first_line;
- if (!IS_CYC_Z(cy_card[card])) {
+ channel = info->line - card->first_line;
+ if (!IS_CYC_Z(*card)) {
chip = channel >> 2;
channel &= 0x03;
- index = cy_card[card].bus_index;
- base_addr = cy_card[card].base_addr +
+ index = card->bus_index;
+ base_addr = card->base_addr +
(cy_chip_offset[chip] << index);
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writeb(base_addr + (CyCAR << index),
(u_char) channel);
if (info->rtsdtr_inv) {
@@ -4379,7 +4287,7 @@
cy_writeb(base_addr + (CyMSVR1 << index),
CyRTS);
}
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
} else {
info->throttle = 0;
}
@@ -4392,102 +4300,96 @@
static void cy_stop(struct tty_struct *tty)
{
struct cyclades_card *cinfo;
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ struct cyclades_port *info = tty->driver_data;
void __iomem *base_addr;
int chip, channel, index;
unsigned long flags;
#ifdef CY_DEBUG_OTHER
- printk("cyc:cy_stop ttyC%d\n", info->line); /* */
+ printk(KERN_DEBUG "cyc:cy_stop ttyC%d\n", info->line);
#endif
if (serial_paranoia_check(info, tty->name, "cy_stop"))
return;
- cinfo = &cy_card[info->card];
+ cinfo = info->card;
channel = info->line - cinfo->first_line;
if (!IS_CYC_Z(*cinfo)) {
index = cinfo->bus_index;
chip = channel >> 2;
channel &= 0x03;
- base_addr = cy_card[info->card].base_addr +
- (cy_chip_offset[chip] << index);
+ base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index);
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&cinfo->card_lock, flags);
cy_writeb(base_addr + (CyCAR << index),
(u_char)(channel & 0x0003)); /* index channel */
cy_writeb(base_addr + (CySRER << index),
- cy_readb(base_addr + (CySRER << index)) & ~CyTxRdy);
- CY_UNLOCK(info, flags);
- } else {
- /* Nothing to do! */
+ readb(base_addr + (CySRER << index)) & ~CyTxRdy);
+ spin_unlock_irqrestore(&cinfo->card_lock, flags);
}
} /* cy_stop */
static void cy_start(struct tty_struct *tty)
{
struct cyclades_card *cinfo;
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ struct cyclades_port *info = tty->driver_data;
void __iomem *base_addr;
int chip, channel, index;
unsigned long flags;
#ifdef CY_DEBUG_OTHER
- printk("cyc:cy_start ttyC%d\n", info->line); /* */
+ printk(KERN_DEBUG "cyc:cy_start ttyC%d\n", info->line);
#endif
if (serial_paranoia_check(info, tty->name, "cy_start"))
return;
- cinfo = &cy_card[info->card];
+ cinfo = info->card;
channel = info->line - cinfo->first_line;
index = cinfo->bus_index;
if (!IS_CYC_Z(*cinfo)) {
chip = channel >> 2;
channel &= 0x03;
- base_addr = cy_card[info->card].base_addr +
- (cy_chip_offset[chip] << index);
+ base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index);
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&cinfo->card_lock, flags);
cy_writeb(base_addr + (CyCAR << index), (u_char) (channel & 0x0003)); /* index channel */
cy_writeb(base_addr + (CySRER << index),
- cy_readb(base_addr + (CySRER << index)) | CyTxRdy);
- CY_UNLOCK(info, flags);
- } else {
- /* Nothing to do! */
+ readb(base_addr + (CySRER << index)) | CyTxRdy);
+ spin_unlock_irqrestore(&cinfo->card_lock, flags);
}
} /* cy_start */
static void cy_flush_buffer(struct tty_struct *tty)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
- int card, channel, retval;
+ struct cyclades_port *info = tty->driver_data;
+ struct cyclades_card *card;
+ int channel, retval;
unsigned long flags;
#ifdef CY_DEBUG_IO
- printk("cyc:cy_flush_buffer ttyC%d\n", info->line); /* */
+ printk(KERN_DEBUG "cyc:cy_flush_buffer ttyC%d\n", info->line);
#endif
if (serial_paranoia_check(info, tty->name, "cy_flush_buffer"))
return;
card = info->card;
- channel = (info->line) - (cy_card[card].first_line);
+ channel = info->line - card->first_line;
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
- if (IS_CYC_Z(cy_card[card])) { /* If it is a Z card, flush the on-board
+ if (IS_CYC_Z(*card)) { /* If it is a Z card, flush the on-board
buffers as well */
- CY_LOCK(info, flags);
- retval =
- cyz_issue_cmd(&cy_card[card], channel, C_CM_FLUSH_TX, 0L);
+ spin_lock_irqsave(&card->card_lock, flags);
+ retval = cyz_issue_cmd(card, channel, C_CM_FLUSH_TX, 0L);
if (retval != 0) {
- printk("cyc: flush_buffer retval on ttyC%d was %x\n",
- info->line, retval);
+ printk(KERN_ERR "cyc: flush_buffer retval on ttyC%d "
+ "was %x\n", info->line, retval);
}
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
}
tty_wakeup(tty);
} /* cy_flush_buffer */
@@ -4497,10 +4399,10 @@
*/
static void cy_hangup(struct tty_struct *tty)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ struct cyclades_port *info = tty->driver_data;
#ifdef CY_DEBUG_OTHER
- printk("cyc:cy_hangup ttyC%d\n", info->line); /* */
+ printk(KERN_DEBUG "cyc:cy_hangup ttyC%d\n", info->line);
#endif
if (serial_paranoia_check(info, tty->name, "cy_hangup"))
@@ -4511,7 +4413,8 @@
info->event = 0;
info->count = 0;
#ifdef CY_DEBUG_COUNT
- printk("cyc:cy_hangup (%d): setting count to 0\n", current->pid);
+ printk(KERN_DEBUG "cyc:cy_hangup (%d): setting count to 0\n",
+ current->pid);
#endif
info->tty = NULL;
info->flags &= ~ASYNC_NORMAL_ACTIVE;
@@ -4526,10 +4429,107 @@
* ---------------------------------------------------------------------
*/
+static int __devinit cy_init_card(struct cyclades_card *cinfo)
+{
+ struct cyclades_port *info;
+ u32 mailbox;
+ unsigned int nports;
+ unsigned short chip_number;
+ int index, port;
+
+ spin_lock_init(&cinfo->card_lock);
+
+ if (IS_CYC_Z(*cinfo)) { /* Cyclades-Z */
+ mailbox = readl(&((struct RUNTIME_9060 __iomem *)
+ cinfo->ctl_addr)->mail_box_0);
+ nports = (mailbox == ZE_V1) ? ZE_V1_NPORTS : 8;
+ cinfo->intr_enabled = 0;
+ cinfo->nports = 0; /* Will be correctly set later, after
+ Z FW is loaded */
+ } else {
+ index = cinfo->bus_index;
+ nports = cinfo->nports = CyPORTS_PER_CHIP * cinfo->num_chips;
+ }
+
+ cinfo->ports = kzalloc(sizeof(*cinfo->ports) * nports, GFP_KERNEL);
+ if (cinfo->ports == NULL) {
+ printk(KERN_ERR "Cyclades: cannot allocate ports\n");
+ cinfo->nports = 0;
+ return -ENOMEM;
+ }
+
+ for (port = cinfo->first_line; port < cinfo->first_line + nports;
+ port++) {
+ info = &cinfo->ports[port - cinfo->first_line];
+ info->magic = CYCLADES_MAGIC;
+ info->card = cinfo;
+ info->line = port;
+ info->flags = STD_COM_FLAGS;
+ info->closing_wait = CLOSING_WAIT_DELAY;
+ info->close_delay = 5 * HZ / 10;
+
+ INIT_WORK(&info->tqueue, do_softint);
+ init_waitqueue_head(&info->open_wait);
+ init_waitqueue_head(&info->close_wait);
+ init_completion(&info->shutdown_wait);
+ init_waitqueue_head(&info->delta_msr_wait);
+
+ if (IS_CYC_Z(*cinfo)) {
+ info->type = PORT_STARTECH;
+ if (mailbox == ZO_V1)
+ info->xmit_fifo_size = CYZ_FIFO_SIZE;
+ else
+ info->xmit_fifo_size = 4 * CYZ_FIFO_SIZE;
+#ifdef CONFIG_CYZ_INTR
+ setup_timer(&cyz_rx_full_timer[port],
+ cyz_rx_restart, (unsigned long)info);
+#endif
+ } else {
+ info->type = PORT_CIRRUS;
+ info->xmit_fifo_size = CyMAX_CHAR_FIFO;
+ info->cor1 = CyPARITY_NONE | Cy_1_STOP | Cy_8_BITS;
+ info->cor2 = CyETC;
+ info->cor3 = 0x08; /* _very_ small rcv threshold */
+
+ chip_number = (port - cinfo->first_line) / 4;
+ if ((info->chip_rev = readb(cinfo->base_addr +
+ (cy_chip_offset[chip_number] <<
+ index) + (CyGFRCR << index))) >=
+ CD1400_REV_J) {
+ /* It is a CD1400 rev. J or later */
+ info->tbpr = baud_bpr_60[13]; /* Tx BPR */
+ info->tco = baud_co_60[13]; /* Tx CO */
+ info->rbpr = baud_bpr_60[13]; /* Rx BPR */
+ info->rco = baud_co_60[13]; /* Rx CO */
+ info->rtsdtr_inv = 1;
+ } else {
+ info->tbpr = baud_bpr_25[13]; /* Tx BPR */
+ info->tco = baud_co_25[13]; /* Tx CO */
+ info->rbpr = baud_bpr_25[13]; /* Rx BPR */
+ info->rco = baud_co_25[13]; /* Rx CO */
+ info->rtsdtr_inv = 0;
+ }
+ info->read_status_mask = CyTIMEOUT | CySPECHAR |
+ CyBREAK | CyPARITY | CyFRAME | CyOVERRUN;
+ }
+
+ }
+
+#ifndef CONFIG_CYZ_INTR
+ if (IS_CYC_Z(*cinfo) && !timer_pending(&cyz_timerlist)) {
+ mod_timer(&cyz_timerlist, jiffies + 1);
+#ifdef CY_PCI_DEBUG
+ printk(KERN_DEBUG "Cyclades-Z polling initialized\n");
+#endif
+ }
+#endif
+ return 0;
+}
+
/* initialize chips on Cyclom-Y card -- return number of valid
chips (which is number of ports/4) */
-static unsigned short __init
-cyy_init_card(void __iomem * true_base_addr, int index)
+static unsigned short __devinit cyy_init_card(void __iomem *true_base_addr,
+ int index)
{
unsigned int chip_number;
void __iomem *base_addr;
@@ -4544,7 +4544,7 @@
base_addr =
true_base_addr + (cy_chip_offset[chip_number] << index);
mdelay(1);
- if (cy_readb(base_addr + (CyCCR << index)) != 0x00) {
+ if (readb(base_addr + (CyCCR << index)) != 0x00) {
/*************
printk(" chip #%d at %#6lx is never idle (CCR != 0)\n",
chip_number, (unsigned long)base_addr);
@@ -4561,7 +4561,7 @@
chip 4 GFRCR register appears at chip 0, there is no chip 4
and this must be a Cyclom-16Y, not a Cyclom-32Ye.
*/
- if (chip_number == 4 && cy_readb(true_base_addr +
+ if (chip_number == 4 && readb(true_base_addr +
(cy_chip_offset[0] << index) +
(CyGFRCR << index)) == 0) {
return chip_number;
@@ -4570,7 +4570,7 @@
cy_writeb(base_addr + (CyCCR << index), CyCHIP_RESET);
mdelay(1);
- if (cy_readb(base_addr + (CyGFRCR << index)) == 0x00) {
+ if (readb(base_addr + (CyGFRCR << index)) == 0x00) {
/*
printk(" chip #%d at %#6lx is not responding ",
chip_number, (unsigned long)base_addr);
@@ -4578,7 +4578,7 @@
*/
return chip_number;
}
- if ((0xf0 & (cy_readb(base_addr + (CyGFRCR << index)))) !=
+ if ((0xf0 & (readb(base_addr + (CyGFRCR << index)))) !=
0x40) {
/*
printk(" chip #%d at %#6lx is not valid (GFRCR == "
@@ -4589,7 +4589,7 @@
return chip_number;
}
cy_writeb(base_addr + (CyGCR << index), CyCH0_SERIAL);
- if (cy_readb(base_addr + (CyGFRCR << index)) >= CD1400_REV_J) {
+ if (readb(base_addr + (CyGFRCR << index)) >= CD1400_REV_J) {
/* It is a CD1400 rev. J or later */
/* Impossible to reach 5ms with this chip.
Changed to 2ms instead (f = 500 Hz). */
@@ -4602,7 +4602,7 @@
/*
printk(" chip #%d at %#6lx is rev 0x%2x\n",
chip_number, (unsigned long)base_addr,
- cy_readb(base_addr+(CyGFRCR<<index)));
+ readb(base_addr+(CyGFRCR<<index)));
*/
}
return chip_number;
@@ -4647,9 +4647,15 @@
/* probe for CD1400... */
cy_isa_address = ioremap(isa_address, CyISA_Ywin);
+ if (cy_isa_address == NULL) {
+ printk(KERN_ERR "Cyclom-Y/ISA: can't remap base "
+ "address\n");
+ continue;
+ }
cy_isa_nchan = CyPORTS_PER_CHIP *
cyy_init_card(cy_isa_address, 0);
if (cy_isa_nchan == 0) {
+ iounmap(cy_isa_address);
continue;
}
#ifdef MODULE
@@ -4660,40 +4666,42 @@
/* find out the board's irq by probing */
cy_isa_irq = detect_isa_irq(cy_isa_address);
if (cy_isa_irq == 0) {
- printk("Cyclom-Y/ISA found at 0x%lx ",
+ printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but the "
+ "IRQ could not be detected.\n",
(unsigned long)cy_isa_address);
- printk("but the IRQ could not be detected.\n");
+ iounmap(cy_isa_address);
continue;
}
if ((cy_next_channel + cy_isa_nchan) > NR_PORTS) {
- printk("Cyclom-Y/ISA found at 0x%lx ",
+ printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but no "
+ "more channels are available. Change NR_PORTS "
+ "in cyclades.c and recompile kernel.\n",
(unsigned long)cy_isa_address);
- printk("but no more channels are available.\n");
- printk("Change NR_PORTS in cyclades.c and recompile "
- "kernel.\n");
+ iounmap(cy_isa_address);
return nboard;
}
/* fill the next cy_card structure available */
for (j = 0; j < NR_CARDS; j++) {
- if (cy_card[j].base_addr == 0)
+ if (cy_card[j].base_addr == NULL)
break;
}
if (j == NR_CARDS) { /* no more cy_cards available */
- printk("Cyclom-Y/ISA found at 0x%lx ",
+ printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but no "
+ "more cards can be used. Change NR_CARDS in "
+ "cyclades.c and recompile kernel.\n",
(unsigned long)cy_isa_address);
- printk("but no more cards can be used .\n");
- printk("Change NR_CARDS in cyclades.c and recompile "
- "kernel.\n");
+ iounmap(cy_isa_address);
return nboard;
}
/* allocate IRQ */
if (request_irq(cy_isa_irq, cyy_interrupt,
IRQF_DISABLED, "Cyclom-Y", &cy_card[j])) {
- printk("Cyclom-Y/ISA found at 0x%lx ",
- (unsigned long)cy_isa_address);
- printk("but could not allocate IRQ#%d.\n", cy_isa_irq);
+ printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but "
+ "could not allocate IRQ#%d.\n",
+ (unsigned long)cy_isa_address, cy_isa_irq);
+ iounmap(cy_isa_address);
return nboard;
}
@@ -4704,15 +4712,23 @@
cy_card[j].bus_index = 0;
cy_card[j].first_line = cy_next_channel;
cy_card[j].num_chips = cy_isa_nchan / 4;
+ if (cy_init_card(&cy_card[j])) {
+ cy_card[j].base_addr = NULL;
+ free_irq(cy_isa_irq, &cy_card[j]);
+ iounmap(cy_isa_address);
+ continue;
+ }
nboard++;
- /* print message */
- printk("Cyclom-Y/ISA #%d: 0x%lx-0x%lx, IRQ%d, ",
+ printk(KERN_INFO "Cyclom-Y/ISA #%d: 0x%lx-0x%lx, IRQ%d found: "
+ "%d channels starting from port %d\n",
j + 1, (unsigned long)cy_isa_address,
(unsigned long)(cy_isa_address + (CyISA_Ywin - 1)),
- cy_isa_irq);
- printk("%d channels starting from port %d.\n",
- cy_isa_nchan, cy_next_channel);
+ cy_isa_irq, cy_isa_nchan, cy_next_channel);
+
+ for (j = cy_next_channel;
+ j < cy_next_channel + cy_isa_nchan; j++)
+ tty_register_device(cy_serial_driver, j, NULL);
cy_next_channel += cy_isa_nchan;
}
return nboard;
@@ -4721,510 +4737,310 @@
#endif /* CONFIG_ISA */
} /* cy_detect_isa */
-static void plx_init(void __iomem * addr, uclong initctl)
+#ifdef CONFIG_PCI
+static void __devinit plx_init(void __iomem * addr, __u32 initctl)
{
/* Reset PLX */
- cy_writel(addr + initctl, cy_readl(addr + initctl) | 0x40000000);
+ cy_writel(addr + initctl, readl(addr + initctl) | 0x40000000);
udelay(100L);
- cy_writel(addr + initctl, cy_readl(addr + initctl) & ~0x40000000);
+ cy_writel(addr + initctl, readl(addr + initctl) & ~0x40000000);
/* Reload Config. Registers from EEPROM */
- cy_writel(addr + initctl, cy_readl(addr + initctl) | 0x20000000);
+ cy_writel(addr + initctl, readl(addr + initctl) | 0x20000000);
udelay(100L);
- cy_writel(addr + initctl, cy_readl(addr + initctl) & ~0x20000000);
+ cy_writel(addr + initctl, readl(addr + initctl) & ~0x20000000);
}
-/*
- * ---------------------------------------------------------------------
- * cy_detect_pci() - Test PCI bus presence and Cyclom-Ye/PCI.
- * sets global variables and return the number of PCI boards found.
- * ---------------------------------------------------------------------
- */
-static int __init cy_detect_pci(void)
+static int __devinit cy_pci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
-#ifdef CONFIG_PCI
+ void __iomem *addr0 = NULL, *addr2 = NULL;
+ char *card_name = NULL;
+ u32 mailbox;
+ unsigned int device_id, nchan = 0, card_no, i;
+ unsigned char plx_ver;
+ int retval, irq;
- struct pci_dev *pdev = NULL;
- unsigned char cyy_rev_id;
- unsigned char cy_pci_irq = 0;
- uclong cy_pci_phys0, cy_pci_phys2;
- void __iomem *cy_pci_addr0, *cy_pci_addr2;
- unsigned short i, j, cy_pci_nchan, plx_ver;
- unsigned short device_id, dev_index = 0;
- uclong mailbox;
- uclong ZeIndex = 0;
- void __iomem *Ze_addr0[NR_CARDS], *Ze_addr2[NR_CARDS];
- uclong Ze_phys0[NR_CARDS], Ze_phys2[NR_CARDS];
- unsigned char Ze_irq[NR_CARDS];
- struct pci_dev *Ze_pdev[NR_CARDS];
+ retval = pci_enable_device(pdev);
+ if (retval) {
+ dev_err(&pdev->dev, "cannot enable device\n");
+ goto err;
+ }
- for (i = 0; i < NR_CARDS; i++) {
- /* look for a Cyclades card by vendor and device id */
- while ((device_id = cy_pci_dev_id[dev_index].device) != 0) {
- if ((pdev = pci_get_device(PCI_VENDOR_ID_CYCLADES,
- device_id, pdev)) == NULL) {
- dev_index++; /* try next device id */
- } else {
- break; /* found a board */
- }
+ /* read PCI configuration area */
+ irq = pdev->irq;
+ device_id = pdev->device & ~PCI_DEVICE_ID_MASK;
+
+#if defined(__alpha__)
+ if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */
+ dev_err(&pdev->dev, "Cyclom-Y/PCI not supported for low "
+ "addresses on Alpha systems.\n");
+ retval = -EIO;
+ goto err_dis;
+ }
+#endif
+ if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Lo) {
+ dev_err(&pdev->dev, "Cyclades-Z/PCI not supported for low "
+ "addresses\n");
+ retval = -EIO;
+ goto err_dis;
+ }
+
+ if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) {
+ dev_warn(&pdev->dev, "PCI I/O bit incorrectly set. Ignoring "
+ "it...\n");
+ pdev->resource[2].flags &= ~IORESOURCE_IO;
+ }
+
+ retval = pci_request_regions(pdev, "cyclades");
+ if (retval) {
+ dev_err(&pdev->dev, "failed to reserve resources\n");
+ goto err_dis;
+ }
+
+ retval = -EIO;
+ if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo ||
+ device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) {
+ card_name = "Cyclom-Y";
+
+ addr0 = pci_iomap(pdev, 0, CyPCI_Yctl);
+ if (addr0 == NULL) {
+ dev_err(&pdev->dev, "can't remap ctl region\n");
+ goto err_reg;
+ }
+ addr2 = pci_iomap(pdev, 2, CyPCI_Ywin);
+ if (addr2 == NULL) {
+ dev_err(&pdev->dev, "can't remap base region\n");
+ goto err_unmap;
}
- if (device_id == 0)
- break;
+ nchan = CyPORTS_PER_CHIP * cyy_init_card(addr2, 1);
+ if (nchan == 0) {
+ dev_err(&pdev->dev, "Cyclom-Y PCI host card with no "
+ "Serial-Modules\n");
+ return -EIO;
+ }
+ } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi) {
+ struct RUNTIME_9060 __iomem *ctl_addr;
- if (pci_enable_device(pdev))
- continue;
+ ctl_addr = addr0 = pci_iomap(pdev, 0, CyPCI_Zctl);
+ if (addr0 == NULL) {
+ dev_err(&pdev->dev, "can't remap ctl region\n");
+ goto err_reg;
+ }
- /* read PCI configuration area */
- cy_pci_irq = pdev->irq;
- cy_pci_phys0 = pci_resource_start(pdev, 0);
- cy_pci_phys2 = pci_resource_start(pdev, 2);
- pci_read_config_byte(pdev, PCI_REVISION_ID, &cyy_rev_id);
+ /* Disable interrupts on the PLX before resetting it */
+ cy_writew(addr0 + 0x68,
+ readw(addr0 + 0x68) & ~0x0900);
- device_id &= ~PCI_DEVICE_ID_MASK;
+ plx_init(addr0, 0x6c);
+ /* For some yet unknown reason, once the PLX9060 reloads
+ the EEPROM, the IRQ is lost and, thus, we have to
+ re-write it to the PCI config. registers.
+ This will remain here until we find a permanent
+ fix. */
+ pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, irq);
- if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo ||
- device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) {
-#ifdef CY_PCI_DEBUG
- printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ",
- pdev->bus->number, pdev->devfn);
- printk("rev_id=%d) IRQ%d\n",
- cyy_rev_id, (int)cy_pci_irq);
- printk("Cyclom-Y/PCI:found winaddr=0x%lx "
- "ctladdr=0x%lx\n",
- (ulong)cy_pci_phys2, (ulong)cy_pci_phys0);
-#endif
+ mailbox = (u32)readl(&ctl_addr->mail_box_0);
- if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) {
- printk(" Warning: PCI I/O bit incorrectly "
- "set. Ignoring it...\n");
- pdev->resource[2].flags &= ~IORESOURCE_IO;
- }
+ addr2 = pci_iomap(pdev, 2, mailbox == ZE_V1 ?
+ CyPCI_Ze_win : CyPCI_Zwin);
+ if (addr2 == NULL) {
+ dev_err(&pdev->dev, "can't remap base region\n");
+ goto err_unmap;
+ }
- /* Although we don't use this I/O region, we should
- request it from the kernel anyway, to avoid problems
- with other drivers accessing it. */
- if (pci_request_regions(pdev, "Cyclom-Y") != 0) {
- printk(KERN_ERR "cyclades: failed to reserve "
- "PCI resources\n");
- continue;
- }
-#if defined(__alpha__)
- if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */
- printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ",
- pdev->bus->number, pdev->devfn);
- printk("rev_id=%d) IRQ%d\n",
- cyy_rev_id, (int)cy_pci_irq);
- printk("Cyclom-Y/PCI:found winaddr=0x%lx "
- "ctladdr=0x%lx\n",
- (ulong)cy_pci_phys2,
- (ulong)cy_pci_phys0);
- printk("Cyclom-Y/PCI not supported for low "
- "addresses in Alpha systems.\n");
- i--;
- continue;
- }
-#endif
- cy_pci_addr0 = ioremap(cy_pci_phys0, CyPCI_Yctl);
- cy_pci_addr2 = ioremap(cy_pci_phys2, CyPCI_Ywin);
+ if (mailbox == ZE_V1) {
+ card_name = "Cyclades-Ze";
+
+ readl(&ctl_addr->mail_box_0);
+ nchan = ZE_V1_NPORTS;
+ } else {
+ card_name = "Cyclades-8Zo";
#ifdef CY_PCI_DEBUG
- printk("Cyclom-Y/PCI: relocate winaddr=0x%lx "
- "ctladdr=0x%lx\n",
- (u_long)cy_pci_addr2, (u_long)cy_pci_addr0);
-#endif
- cy_pci_nchan = (unsigned short)(CyPORTS_PER_CHIP *
- cyy_init_card(cy_pci_addr2, 1));
- if (cy_pci_nchan == 0) {
- printk("Cyclom-Y PCI host card with ");
- printk("no Serial-Modules at 0x%lx.\n",
- (ulong) cy_pci_phys2);
- i--;
- continue;
- }
- if ((cy_next_channel + cy_pci_nchan) > NR_PORTS) {
- printk("Cyclom-Y/PCI found at 0x%lx ",
- (ulong) cy_pci_phys2);
- printk("but no channels are available.\n");
- printk("Change NR_PORTS in cyclades.c and "
- "recompile kernel.\n");
- return i;
- }
- /* fill the next cy_card structure available */
- for (j = 0; j < NR_CARDS; j++) {
- if (cy_card[j].base_addr == 0)
- break;
- }
- if (j == NR_CARDS) { /* no more cy_cards available */
- printk("Cyclom-Y/PCI found at 0x%lx ",
- (ulong) cy_pci_phys2);
- printk("but no more cards can be used.\n");
- printk("Change NR_CARDS in cyclades.c and "
- "recompile kernel.\n");
- return i;
- }
-
- /* allocate IRQ */
- if (request_irq(cy_pci_irq, cyy_interrupt,
- IRQF_SHARED, "Cyclom-Y", &cy_card[j])) {
- printk("Cyclom-Y/PCI found at 0x%lx ",
- (ulong) cy_pci_phys2);
- printk("but could not allocate IRQ%d.\n",
- cy_pci_irq);
- return i;
- }
-
- /* set cy_card */
- cy_card[j].base_phys = (ulong) cy_pci_phys2;
- cy_card[j].ctl_phys = (ulong) cy_pci_phys0;
- cy_card[j].base_addr = cy_pci_addr2;
- cy_card[j].ctl_addr = cy_pci_addr0;
- cy_card[j].irq = (int)cy_pci_irq;
- cy_card[j].bus_index = 1;
- cy_card[j].first_line = cy_next_channel;
- cy_card[j].num_chips = cy_pci_nchan / 4;
- cy_card[j].pdev = pdev;
-
- /* enable interrupts in the PCI interface */
- plx_ver = cy_readb(cy_pci_addr2 + CyPLX_VER) & 0x0f;
- switch (plx_ver) {
- case PLX_9050:
-
- cy_writeb(cy_pci_addr0 + 0x4c, 0x43);
- break;
-
- case PLX_9060:
- case PLX_9080:
- default: /* Old boards, use PLX_9060 */
-
- plx_init(cy_pci_addr0, 0x6c);
- /* For some yet unknown reason, once the PLX9060 reloads
- the EEPROM, the IRQ is lost and, thus, we have to
- re-write it to the PCI config. registers.
- This will remain here until we find a permanent
- fix. */
- pci_write_config_byte(pdev, PCI_INTERRUPT_LINE,
- cy_pci_irq);
-
- cy_writew(cy_pci_addr0 + 0x68,
- cy_readw(cy_pci_addr0 +
- 0x68) | 0x0900);
- break;
- }
-
- /* print message */
- printk("Cyclom-Y/PCI #%d: 0x%lx-0x%lx, IRQ%d, ",
- j + 1, (ulong)cy_pci_phys2,
- (ulong) (cy_pci_phys2 + CyPCI_Ywin - 1),
- (int)cy_pci_irq);
- printk("%d channels starting from port %d.\n",
- cy_pci_nchan, cy_next_channel);
-
- cy_next_channel += cy_pci_nchan;
- } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Lo) {
- /* print message */
- printk("Cyclades-Z/PCI (bus=0x0%x, pci_id=0x%x, ",
- pdev->bus->number, pdev->devfn);
- printk("rev_id=%d) IRQ%d\n",
- cyy_rev_id, (int)cy_pci_irq);
- printk("Cyclades-Z/PCI: found winaddr=0x%lx "
- "ctladdr=0x%lx\n",
- (ulong)cy_pci_phys2, (ulong)cy_pci_phys0);
- printk("Cyclades-Z/PCI not supported for low "
- "addresses\n");
- break;
- } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi) {
-#ifdef CY_PCI_DEBUG
- printk("Cyclades-Z/PCI (bus=0x0%x, pci_id=0x%x, ",
- pdev->bus->number, pdev->devfn);
- printk("rev_id=%d) IRQ%d\n",
- cyy_rev_id, (int)cy_pci_irq);
- printk("Cyclades-Z/PCI: found winaddr=0x%lx "
- "ctladdr=0x%lx\n",
- (ulong) cy_pci_phys2, (ulong) cy_pci_phys0);
-#endif
- cy_pci_addr0 = ioremap(cy_pci_phys0, CyPCI_Zctl);
-
- /* Disable interrupts on the PLX before resetting it */
- cy_writew(cy_pci_addr0 + 0x68,
- cy_readw(cy_pci_addr0 + 0x68) & ~0x0900);
-
- plx_init(cy_pci_addr0, 0x6c);
- /* For some yet unknown reason, once the PLX9060 reloads
- the EEPROM, the IRQ is lost and, thus, we have to
- re-write it to the PCI config. registers.
- This will remain here until we find a permanent
- fix. */
- pci_write_config_byte(pdev, PCI_INTERRUPT_LINE,
- cy_pci_irq);
-
- mailbox =
- (uclong)cy_readl(&((struct RUNTIME_9060 __iomem *)
- cy_pci_addr0)->mail_box_0);
-
- if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) {
- printk(" Warning: PCI I/O bit incorrectly "
- "set. Ignoring it...\n");
- pdev->resource[2].flags &= ~IORESOURCE_IO;
- }
-
- /* Although we don't use this I/O region, we should
- request it from the kernel anyway, to avoid problems
- with other drivers accessing it. */
- if (pci_request_regions(pdev, "Cyclades-Z") != 0) {
- printk(KERN_ERR "cyclades: failed to reserve "
- "PCI resources\n");
- continue;
- }
-
- if (mailbox == ZE_V1) {
- cy_pci_addr2 = ioremap(cy_pci_phys2,
- CyPCI_Ze_win);
- if (ZeIndex == NR_CARDS) {
- printk("Cyclades-Ze/PCI found at "
- "0x%lx but no more cards can "
- "be used.\nChange NR_CARDS in "
- "cyclades.c and recompile "
- "kernel.\n",
- (ulong)cy_pci_phys2);
- } else {
- Ze_phys0[ZeIndex] = cy_pci_phys0;
- Ze_phys2[ZeIndex] = cy_pci_phys2;
- Ze_addr0[ZeIndex] = cy_pci_addr0;
- Ze_addr2[ZeIndex] = cy_pci_addr2;
- Ze_irq[ZeIndex] = cy_pci_irq;
- Ze_pdev[ZeIndex] = pdev;
- ZeIndex++;
- }
- i--;
- continue;
- } else {
- cy_pci_addr2 = ioremap(cy_pci_phys2,CyPCI_Zwin);
- }
-
-#ifdef CY_PCI_DEBUG
- printk("Cyclades-Z/PCI: relocate winaddr=0x%lx "
- "ctladdr=0x%lx\n",
- (ulong) cy_pci_addr2, (ulong) cy_pci_addr0);
if (mailbox == ZO_V1) {
- cy_writel(&((struct RUNTIME_9060 *)
- (cy_pci_addr0))->loc_addr_base,
- WIN_CREG);
- PAUSE;
- printk("Cyclades-8Zo/PCI: FPGA id %lx, ver "
- "%lx\n", (ulong) (0xff &
- cy_readl(&((struct CUSTOM_REG *)
- (cy_pci_addr2))->fpga_id)),
- (ulong)(0xff &
- cy_readl(&((struct CUSTOM_REG *)
- (cy_pci_addr2))->
- fpga_version)));
- cy_writel(&((struct RUNTIME_9060 *)
- (cy_pci_addr0))->loc_addr_base,
- WIN_RAM);
+ cy_writel(&ctl_addr->loc_addr_base, WIN_CREG);
+ dev_info(&pdev->dev, "Cyclades-8Zo/PCI: FPGA "
+ "id %lx, ver %lx\n", (ulong)(0xff &
+ readl(&((struct CUSTOM_REG *)addr2)->
+ fpga_id)), (ulong)(0xff &
+ readl(&((struct CUSTOM_REG *)addr2)->
+ fpga_version)));
+ cy_writel(&ctl_addr->loc_addr_base, WIN_RAM);
} else {
- printk("Cyclades-Z/PCI: New Cyclades-Z board. "
- "FPGA not loaded\n");
+ dev_info(&pdev->dev, "Cyclades-Z/PCI: New "
+ "Cyclades-Z board. FPGA not loaded\n");
}
#endif
/* The following clears the firmware id word. This
ensures that the driver will not attempt to talk to
the board until it has been properly initialized.
*/
- PAUSE;
if ((mailbox == ZO_V1) || (mailbox == ZO_V2))
- cy_writel(cy_pci_addr2 + ID_ADDRESS, 0L);
+ cy_writel(addr2 + ID_ADDRESS, 0L);
/* This must be a Cyclades-8Zo/PCI. The extendable
version will have a different device_id and will
be allocated its maximum number of ports. */
- cy_pci_nchan = 8;
-
- if ((cy_next_channel + cy_pci_nchan) > NR_PORTS) {
- printk("Cyclades-8Zo/PCI found at 0x%lx but"
- "no channels are available.\nChange "
- "NR_PORTS in cyclades.c and recompile "
- "kernel.\n", (ulong)cy_pci_phys2);
- return i;
- }
-
- /* fill the next cy_card structure available */
- for (j = 0; j < NR_CARDS; j++) {
- if (cy_card[j].base_addr == 0)
- break;
- }
- if (j == NR_CARDS) { /* no more cy_cards available */
- printk("Cyclades-8Zo/PCI found at 0x%lx but"
- "no more cards can be used.\nChange "
- "NR_CARDS in cyclades.c and recompile "
- "kernel.\n", (ulong)cy_pci_phys2);
- return i;
- }
-#ifdef CONFIG_CYZ_INTR
- /* allocate IRQ only if board has an IRQ */
- if ((cy_pci_irq != 0) && (cy_pci_irq != 255)) {
- if (request_irq(cy_pci_irq, cyz_interrupt,
- IRQF_SHARED, "Cyclades-Z",
- &cy_card[j])) {
- printk("Cyclom-8Zo/PCI found at 0x%lx "
- "but could not allocate "
- "IRQ%d.\n", (ulong)cy_pci_phys2,
- cy_pci_irq);
- return i;
- }
- }
-#endif /* CONFIG_CYZ_INTR */
-
- /* set cy_card */
- cy_card[j].base_phys = cy_pci_phys2;
- cy_card[j].ctl_phys = cy_pci_phys0;
- cy_card[j].base_addr = cy_pci_addr2;
- cy_card[j].ctl_addr = cy_pci_addr0;
- cy_card[j].irq = (int)cy_pci_irq;
- cy_card[j].bus_index = 1;
- cy_card[j].first_line = cy_next_channel;
- cy_card[j].num_chips = -1;
- cy_card[j].pdev = pdev;
-
- /* print message */
-#ifdef CONFIG_CYZ_INTR
- /* don't report IRQ if board is no IRQ */
- if ((cy_pci_irq != 0) && (cy_pci_irq != 255))
- printk("Cyclades-8Zo/PCI #%d: 0x%lx-0x%lx, "
- "IRQ%d, ", j + 1, (ulong)cy_pci_phys2,
- (ulong) (cy_pci_phys2 + CyPCI_Zwin - 1),
- (int)cy_pci_irq);
- else
-#endif /* CONFIG_CYZ_INTR */
- printk("Cyclades-8Zo/PCI #%d: 0x%lx-0x%lx, ",
- j + 1, (ulong)cy_pci_phys2,
- (ulong)(cy_pci_phys2 + CyPCI_Zwin - 1));
-
- printk("%d channels starting from port %d.\n",
- cy_pci_nchan, cy_next_channel);
- cy_next_channel += cy_pci_nchan;
+ nchan = 8;
}
}
- for (; ZeIndex != 0 && i < NR_CARDS; i++) {
- cy_pci_phys0 = Ze_phys0[0];
- cy_pci_phys2 = Ze_phys2[0];
- cy_pci_addr0 = Ze_addr0[0];
- cy_pci_addr2 = Ze_addr2[0];
- cy_pci_irq = Ze_irq[0];
- pdev = Ze_pdev[0];
- for (j = 0; j < ZeIndex - 1; j++) {
- Ze_phys0[j] = Ze_phys0[j + 1];
- Ze_phys2[j] = Ze_phys2[j + 1];
- Ze_addr0[j] = Ze_addr0[j + 1];
- Ze_addr2[j] = Ze_addr2[j + 1];
- Ze_irq[j] = Ze_irq[j + 1];
- Ze_pdev[j] = Ze_pdev[j + 1];
- }
- ZeIndex--;
- mailbox = (uclong)cy_readl(&((struct RUNTIME_9060 __iomem *)
- cy_pci_addr0)->mail_box_0);
-#ifdef CY_PCI_DEBUG
- printk("Cyclades-Z/PCI: relocate winaddr=0x%lx ctladdr=0x%lx\n",
- (ulong)cy_pci_addr2, (ulong)cy_pci_addr0);
- printk("Cyclades-Z/PCI: New Cyclades-Z board. FPGA not "
- "loaded\n");
-#endif
- PAUSE;
- /* This must be the new Cyclades-Ze/PCI. */
- cy_pci_nchan = ZE_V1_NPORTS;
+ if ((cy_next_channel + nchan) > NR_PORTS) {
+ dev_err(&pdev->dev, "Cyclades-8Zo/PCI found, but no "
+ "channels are available. Change NR_PORTS in "
+ "cyclades.c and recompile kernel.\n");
+ goto err_unmap;
+ }
+ /* fill the next cy_card structure available */
+ for (card_no = 0; card_no < NR_CARDS; card_no++) {
+ if (cy_card[card_no].base_addr == NULL)
+ break;
+ }
+ if (card_no == NR_CARDS) { /* no more cy_cards available */
+ dev_err(&pdev->dev, "Cyclades-8Zo/PCI found, but no "
+ "more cards can be used. Change NR_CARDS in "
+ "cyclades.c and recompile kernel.\n");
+ goto err_unmap;
+ }
- if ((cy_next_channel + cy_pci_nchan) > NR_PORTS) {
- printk("Cyclades-Ze/PCI found at 0x%lx but no channels "
- "are available.\nChange NR_PORTS in cyclades.c "
- "and recompile kernel.\n",
- (ulong) cy_pci_phys2);
- return i;
+ if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo ||
+ device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) {
+ /* allocate IRQ */
+ retval = request_irq(irq, cyy_interrupt,
+ IRQF_SHARED, "Cyclom-Y", &cy_card[card_no]);
+ if (retval) {
+ dev_err(&pdev->dev, "could not allocate IRQ\n");
+ goto err_unmap;
}
-
- /* fill the next cy_card structure available */
- for (j = 0; j < NR_CARDS; j++) {
- if (cy_card[j].base_addr == 0)
- break;
- }
- if (j == NR_CARDS) { /* no more cy_cards available */
- printk("Cyclades-Ze/PCI found at 0x%lx but no more "
- "cards can be used.\nChange NR_CARDS in "
- "cyclades.c and recompile kernel.\n",
- (ulong) cy_pci_phys2);
- return i;
- }
+ cy_card[card_no].num_chips = nchan / 4;
+ } else {
#ifdef CONFIG_CYZ_INTR
/* allocate IRQ only if board has an IRQ */
- if ((cy_pci_irq != 0) && (cy_pci_irq != 255)) {
- if (request_irq(cy_pci_irq, cyz_interrupt,
+ if (irq != 0 && irq != 255) {
+ retval = request_irq(irq, cyz_interrupt,
IRQF_SHARED, "Cyclades-Z",
- &cy_card[j])) {
- printk("Cyclom-Ze/PCI found at 0x%lx ",
- (ulong) cy_pci_phys2);
- printk("but could not allocate IRQ%d.\n",
- cy_pci_irq);
- return i;
+ &cy_card[card_no]);
+ if (retval) {
+ dev_err(&pdev->dev, "could not allocate IRQ\n");
+ goto err_unmap;
}
}
#endif /* CONFIG_CYZ_INTR */
-
- /* set cy_card */
- cy_card[j].base_phys = cy_pci_phys2;
- cy_card[j].ctl_phys = cy_pci_phys0;
- cy_card[j].base_addr = cy_pci_addr2;
- cy_card[j].ctl_addr = cy_pci_addr0;
- cy_card[j].irq = (int)cy_pci_irq;
- cy_card[j].bus_index = 1;
- cy_card[j].first_line = cy_next_channel;
- cy_card[j].num_chips = -1;
- cy_card[j].pdev = pdev;
-
- /* print message */
-#ifdef CONFIG_CYZ_INTR
- /* don't report IRQ if board is no IRQ */
- if ((cy_pci_irq != 0) && (cy_pci_irq != 255))
- printk("Cyclades-Ze/PCI #%d: 0x%lx-0x%lx, IRQ%d, ",
- j + 1, (ulong) cy_pci_phys2,
- (ulong) (cy_pci_phys2 + CyPCI_Ze_win - 1),
- (int)cy_pci_irq);
- else
-#endif /* CONFIG_CYZ_INTR */
- printk("Cyclades-Ze/PCI #%d: 0x%lx-0x%lx, ",
- j + 1, (ulong) cy_pci_phys2,
- (ulong) (cy_pci_phys2 + CyPCI_Ze_win - 1));
-
- printk("%d channels starting from port %d.\n",
- cy_pci_nchan, cy_next_channel);
- cy_next_channel += cy_pci_nchan;
+ cy_card[card_no].num_chips = -1;
}
- if (ZeIndex != 0) {
- printk("Cyclades-Ze/PCI found at 0x%x but no more cards can be "
- "used.\nChange NR_CARDS in cyclades.c and recompile "
- "kernel.\n", (unsigned int)Ze_phys2[0]);
+
+ /* set cy_card */
+ cy_card[card_no].base_addr = addr2;
+ cy_card[card_no].ctl_addr = addr0;
+ cy_card[card_no].irq = irq;
+ cy_card[card_no].bus_index = 1;
+ cy_card[card_no].first_line = cy_next_channel;
+ retval = cy_init_card(&cy_card[card_no]);
+ if (retval)
+ goto err_null;
+
+ pci_set_drvdata(pdev, &cy_card[card_no]);
+
+ if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo ||
+ device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) {
+ /* enable interrupts in the PCI interface */
+ plx_ver = readb(addr2 + CyPLX_VER) & 0x0f;
+ switch (plx_ver) {
+ case PLX_9050:
+
+ cy_writeb(addr0 + 0x4c, 0x43);
+ break;
+
+ case PLX_9060:
+ case PLX_9080:
+ default: /* Old boards, use PLX_9060 */
+
+ plx_init(addr0, 0x6c);
+ /* For some yet unknown reason, once the PLX9060 reloads
+ the EEPROM, the IRQ is lost and, thus, we have to
+ re-write it to the PCI config. registers.
+ This will remain here until we find a permanent
+ fix. */
+ pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, irq);
+
+ cy_writew(addr0 + 0x68, readw(addr0 + 0x68) | 0x0900);
+ break;
+ }
}
- return i;
-#else
+
+ dev_info(&pdev->dev, "%s/PCI #%d found: %d channels starting from "
+ "port %d.\n", card_name, card_no + 1, nchan, cy_next_channel);
+ for (i = cy_next_channel; i < cy_next_channel + nchan; i++)
+ tty_register_device(cy_serial_driver, i, &pdev->dev);
+ cy_next_channel += nchan;
+
return 0;
-#endif /* ifdef CONFIG_PCI */
-} /* cy_detect_pci */
+err_null:
+ cy_card[card_no].base_addr = NULL;
+ free_irq(irq, &cy_card[card_no]);
+err_unmap:
+ pci_iounmap(pdev, addr0);
+ if (addr2)
+ pci_iounmap(pdev, addr2);
+err_reg:
+ pci_release_regions(pdev);
+err_dis:
+ pci_disable_device(pdev);
+err:
+ return retval;
+}
-/*
- * This routine prints out the appropriate serial driver version number
- * and identifies which options were configured into this driver.
- */
-static inline void show_version(void)
+static void __devexit cy_pci_remove(struct pci_dev *pdev)
{
- printk("Cyclades driver " CY_VERSION "\n");
- printk(" built %s %s\n", __DATE__, __TIME__);
-} /* show_version */
+ struct cyclades_card *cinfo = pci_get_drvdata(pdev);
+ unsigned int i;
+
+ /* non-Z with old PLX */
+ if (!IS_CYC_Z(*cinfo) && (readb(cinfo->base_addr + CyPLX_VER) & 0x0f) ==
+ PLX_9050)
+ cy_writeb(cinfo->ctl_addr + 0x4c, 0);
+ else
+#ifndef CONFIG_CYZ_INTR
+ if (!IS_CYC_Z(*cinfo))
+#endif
+ cy_writew(cinfo->ctl_addr + 0x68,
+ readw(cinfo->ctl_addr + 0x68) & ~0x0900);
+
+ pci_iounmap(pdev, cinfo->base_addr);
+ if (cinfo->ctl_addr)
+ pci_iounmap(pdev, cinfo->ctl_addr);
+ if (cinfo->irq
+#ifndef CONFIG_CYZ_INTR
+ && !IS_CYC_Z(*cinfo)
+#endif /* CONFIG_CYZ_INTR */
+ )
+ free_irq(cinfo->irq, cinfo);
+ pci_release_regions(pdev);
+
+ cinfo->base_addr = NULL;
+ for (i = cinfo->first_line; i < cinfo->first_line +
+ cinfo->nports; i++)
+ tty_unregister_device(cy_serial_driver, i);
+ cinfo->nports = 0;
+ kfree(cinfo->ports);
+}
+
+static struct pci_driver cy_pci_driver = {
+ .name = "cyclades",
+ .id_table = cy_pci_dev_id,
+ .probe = cy_pci_probe,
+ .remove = __devexit_p(cy_pci_remove)
+};
+#endif
static int
cyclades_get_proc_info(char *buf, char **start, off_t offset, int length,
int *eof, void *data)
{
struct cyclades_port *info;
- int i;
+ unsigned int i, j;
int len = 0;
off_t begin = 0;
off_t pos = 0;
@@ -5238,33 +5054,34 @@
len += size;
/* Output one line for each known port */
- for (i = 0; i < NR_PORTS && cy_port[i].line >= 0; i++) {
- info = &cy_port[i];
+ for (i = 0; i < NR_CARDS; i++)
+ for (j = 0; j < cy_card[i].nports; j++) {
+ info = &cy_card[i].ports[j];
- if (info->count)
- size = sprintf(buf + len, "%3d %8lu %10lu %8lu %10lu "
- "%8lu %9lu %6ld\n", info->line,
- (cur_jifs - info->idle_stats.in_use) / HZ,
- info->idle_stats.xmit_bytes,
- (cur_jifs - info->idle_stats.xmit_idle) / HZ,
- info->idle_stats.recv_bytes,
- (cur_jifs - info->idle_stats.recv_idle) / HZ,
- info->idle_stats.overruns,
- (long)info->tty->ldisc.num);
- else
- size = sprintf(buf + len, "%3d %8lu %10lu %8lu %10lu "
- "%8lu %9lu %6ld\n",
- info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L);
- len += size;
- pos = begin + len;
+ if (info->count)
+ size = sprintf(buf + len, "%3d %8lu %10lu %8lu "
+ "%10lu %8lu %9lu %6ld\n", info->line,
+ (cur_jifs - info->idle_stats.in_use) /
+ HZ, info->idle_stats.xmit_bytes,
+ (cur_jifs - info->idle_stats.xmit_idle)/
+ HZ, info->idle_stats.recv_bytes,
+ (cur_jifs - info->idle_stats.recv_idle)/
+ HZ, info->idle_stats.overruns,
+ (long)info->tty->ldisc.num);
+ else
+ size = sprintf(buf + len, "%3d %8lu %10lu %8lu "
+ "%10lu %8lu %9lu %6ld\n",
+ info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L);
+ len += size;
+ pos = begin + len;
- if (pos < offset) {
- len = 0;
- begin = pos;
+ if (pos < offset) {
+ len = 0;
+ begin = pos;
+ }
+ if (pos > offset + length)
+ goto done;
}
- if (pos > offset + length)
- goto done;
- }
*eof = 1;
done:
*start = buf + (offset - begin); /* Start of wanted data */
@@ -5319,18 +5136,15 @@
static int __init cy_init(void)
{
- struct cyclades_port *info;
- struct cyclades_card *cinfo;
- int number_z_boards = 0;
- int board, port, i, index;
- unsigned long mailbox;
- unsigned short chip_number;
- int nports;
+ unsigned int nboards;
+ int retval = -ENOMEM;
cy_serial_driver = alloc_tty_driver(NR_PORTS);
if (!cy_serial_driver)
- return -ENOMEM;
- show_version();
+ goto err;
+
+ printk(KERN_INFO "Cyclades driver " CY_VERSION " (built %s %s)\n",
+ __DATE__, __TIME__);
/* Initialize the tty_driver structure */
@@ -5344,15 +5158,13 @@
cy_serial_driver->init_termios = tty_std_termios;
cy_serial_driver->init_termios.c_cflag =
B9600 | CS8 | CREAD | HUPCL | CLOCAL;
- cy_serial_driver->flags = TTY_DRIVER_REAL_RAW;
+ cy_serial_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
tty_set_operations(cy_serial_driver, &cy_ops);
- if (tty_register_driver(cy_serial_driver))
- panic("Couldn't register Cyclades serial driver\n");
-
- for (i = 0; i < NR_CARDS; i++) {
- /* base_addr=0 indicates board not found */
- cy_card[i].base_addr = NULL;
+ retval = tty_register_driver(cy_serial_driver);
+ if (retval) {
+ printk(KERN_ERR "Couldn't register Cyclades serial driver\n");
+ goto err_frtty;
}
/* the code below is responsible to find the boards. Each different
@@ -5363,223 +5175,68 @@
the cy_next_channel. */
/* look for isa boards */
- cy_isa_nboard = cy_detect_isa();
+ nboards = cy_detect_isa();
+#ifdef CONFIG_PCI
/* look for pci boards */
- cy_pci_nboard = cy_detect_pci();
-
- cy_nboard = cy_isa_nboard + cy_pci_nboard;
-
- /* invalidate remaining cy_card structures */
- for (i = 0; i < NR_CARDS; i++) {
- if (cy_card[i].base_addr == 0) {
- cy_card[i].first_line = -1;
- cy_card[i].ctl_addr = NULL;
- cy_card[i].irq = 0;
- cy_card[i].bus_index = 0;
- cy_card[i].first_line = 0;
- cy_card[i].num_chips = 0;
- }
- }
- /* invalidate remaining cy_port structures */
- for (i = cy_next_channel; i < NR_PORTS; i++) {
- cy_port[i].line = -1;
- cy_port[i].magic = -1;
- }
-
- /* initialize per-port data structures for each valid board found */
- for (board = 0; board < cy_nboard; board++) {
- cinfo = &cy_card[board];
- if (cinfo->num_chips == -1) { /* Cyclades-Z */
- number_z_boards++;
- mailbox = cy_readl(&((struct RUNTIME_9060 __iomem *)
- cy_card[board].ctl_addr)->
- mail_box_0);
- nports = (mailbox == ZE_V1) ? ZE_V1_NPORTS : 8;
- cinfo->intr_enabled = 0;
- cinfo->nports = 0; /* Will be correctly set later, after
- Z FW is loaded */
- spin_lock_init(&cinfo->card_lock);
- for (port = cinfo->first_line;
- port < cinfo->first_line + nports; port++) {
- info = &cy_port[port];
- info->magic = CYCLADES_MAGIC;
- info->type = PORT_STARTECH;
- info->card = board;
- info->line = port;
- info->chip_rev = 0;
- info->flags = STD_COM_FLAGS;
- info->tty = NULL;
- if (mailbox == ZO_V1)
- info->xmit_fifo_size = CYZ_FIFO_SIZE;
- else
- info->xmit_fifo_size =
- 4 * CYZ_FIFO_SIZE;
- info->cor1 = 0;
- info->cor2 = 0;
- info->cor3 = 0;
- info->cor4 = 0;
- info->cor5 = 0;
- info->tbpr = 0;
- info->tco = 0;
- info->rbpr = 0;
- info->rco = 0;
- info->custom_divisor = 0;
- info->close_delay = 5 * HZ / 10;
- info->closing_wait = CLOSING_WAIT_DELAY;
- info->icount.cts = info->icount.dsr =
- info->icount.rng = info->icount.dcd = 0;
- info->icount.rx = info->icount.tx = 0;
- info->icount.frame = info->icount.parity = 0;
- info->icount.overrun = info->icount.brk = 0;
- info->x_char = 0;
- info->event = 0;
- info->count = 0;
- info->blocked_open = 0;
- info->default_threshold = 0;
- info->default_timeout = 0;
- INIT_WORK(&info->tqueue, do_softint);
- init_waitqueue_head(&info->open_wait);
- init_waitqueue_head(&info->close_wait);
- init_waitqueue_head(&info->shutdown_wait);
- init_waitqueue_head(&info->delta_msr_wait);
- /* info->session */
- /* info->pgrp */
- info->read_status_mask = 0;
- /* info->timeout */
- /* Bentson's vars */
- info->jiffies[0] = 0;
- info->jiffies[1] = 0;
- info->jiffies[2] = 0;
- info->rflush_count = 0;
-#ifdef CONFIG_CYZ_INTR
- init_timer(&cyz_rx_full_timer[port]);
- cyz_rx_full_timer[port].function = NULL;
+ retval = pci_register_driver(&cy_pci_driver);
+ if (retval && !nboards)
+ goto err_unr;
#endif
- }
- continue;
- } else { /* Cyclom-Y of some kind */
- index = cinfo->bus_index;
- spin_lock_init(&cinfo->card_lock);
- cinfo->nports = CyPORTS_PER_CHIP * cinfo->num_chips;
- for (port = cinfo->first_line;
- port < cinfo->first_line + cinfo->nports; port++) {
- info = &cy_port[port];
- info->magic = CYCLADES_MAGIC;
- info->type = PORT_CIRRUS;
- info->card = board;
- info->line = port;
- info->flags = STD_COM_FLAGS;
- info->tty = NULL;
- info->xmit_fifo_size = CyMAX_CHAR_FIFO;
- info->cor1 =
- CyPARITY_NONE | Cy_1_STOP | Cy_8_BITS;
- info->cor2 = CyETC;
- info->cor3 = 0x08; /* _very_ small rcv threshold */
- info->cor4 = 0;
- info->cor5 = 0;
- info->custom_divisor = 0;
- info->close_delay = 5 * HZ / 10;
- info->closing_wait = CLOSING_WAIT_DELAY;
- info->icount.cts = info->icount.dsr =
- info->icount.rng = info->icount.dcd = 0;
- info->icount.rx = info->icount.tx = 0;
- info->icount.frame = info->icount.parity = 0;
- info->icount.overrun = info->icount.brk = 0;
- chip_number = (port - cinfo->first_line) / 4;
- if ((info->chip_rev =
- cy_readb(cinfo->base_addr +
- (cy_chip_offset[chip_number] <<
- index) + (CyGFRCR << index))) >=
- CD1400_REV_J) {
- /* It is a CD1400 rev. J or later */
- info->tbpr = baud_bpr_60[13]; /* Tx BPR */
- info->tco = baud_co_60[13]; /* Tx CO */
- info->rbpr = baud_bpr_60[13]; /* Rx BPR */
- info->rco = baud_co_60[13]; /* Rx CO */
- info->rflow = 0;
- info->rtsdtr_inv = 1;
- } else {
- info->tbpr = baud_bpr_25[13]; /* Tx BPR */
- info->tco = baud_co_25[13]; /* Tx CO */
- info->rbpr = baud_bpr_25[13]; /* Rx BPR */
- info->rco = baud_co_25[13]; /* Rx CO */
- info->rflow = 0;
- info->rtsdtr_inv = 0;
- }
- info->x_char = 0;
- info->event = 0;
- info->count = 0;
- info->blocked_open = 0;
- info->default_threshold = 0;
- info->default_timeout = 0;
- INIT_WORK(&info->tqueue, do_softint);
- init_waitqueue_head(&info->open_wait);
- init_waitqueue_head(&info->close_wait);
- init_waitqueue_head(&info->shutdown_wait);
- init_waitqueue_head(&info->delta_msr_wait);
- /* info->session */
- /* info->pgrp */
- info->read_status_mask =
- CyTIMEOUT | CySPECHAR | CyBREAK
- | CyPARITY | CyFRAME | CyOVERRUN;
- /* info->timeout */
- }
- }
- }
-
-#ifndef CONFIG_CYZ_INTR
- if (number_z_boards && !cyz_timeron) {
- cyz_timeron++;
- cyz_timerlist.expires = jiffies + 1;
- add_timer(&cyz_timerlist);
-#ifdef CY_PCI_DEBUG
- printk("Cyclades-Z polling initialized\n");
-#endif
- }
-#endif /* CONFIG_CYZ_INTR */
return 0;
-
+err_unr:
+ tty_unregister_driver(cy_serial_driver);
+err_frtty:
+ put_tty_driver(cy_serial_driver);
+err:
+ return retval;
} /* cy_init */
static void __exit cy_cleanup_module(void)
{
+ struct cyclades_card *card;
int i, e1;
#ifndef CONFIG_CYZ_INTR
- if (cyz_timeron){
- cyz_timeron = 0;
- del_timer(&cyz_timerlist);
- }
+ del_timer_sync(&cyz_timerlist);
#endif /* CONFIG_CYZ_INTR */
if ((e1 = tty_unregister_driver(cy_serial_driver)))
- printk("cyc: failed to unregister Cyclades serial driver(%d)\n",
- e1);
+ printk(KERN_ERR "failed to unregister Cyclades serial "
+ "driver(%d)\n", e1);
- put_tty_driver(cy_serial_driver);
+#ifdef CONFIG_PCI
+ pci_unregister_driver(&cy_pci_driver);
+#endif
for (i = 0; i < NR_CARDS; i++) {
- if (cy_card[i].base_addr) {
- iounmap(cy_card[i].base_addr);
- if (cy_card[i].ctl_addr)
- iounmap(cy_card[i].ctl_addr);
- if (cy_card[i].irq
+ card = &cy_card[i];
+ if (card->base_addr) {
+ /* clear interrupt */
+ cy_writeb(card->base_addr + Cy_ClrIntr, 0);
+ iounmap(card->base_addr);
+ if (card->ctl_addr)
+ iounmap(card->ctl_addr);
+ if (card->irq
#ifndef CONFIG_CYZ_INTR
- && cy_card[i].num_chips != -1 /* not a Z card */
+ && !IS_CYC_Z(*card)
#endif /* CONFIG_CYZ_INTR */
)
- free_irq(cy_card[i].irq, &cy_card[i]);
-#ifdef CONFIG_PCI
- if (cy_card[i].pdev)
- pci_release_regions(cy_card[i].pdev);
-#endif
+ free_irq(card->irq, card);
+ for (e1 = card->first_line;
+ e1 < card->first_line +
+ card->nports; e1++)
+ tty_unregister_device(cy_serial_driver, e1);
+ kfree(card->ports);
}
}
+
+ put_tty_driver(cy_serial_driver);
} /* cy_cleanup_module */
module_init(cy_init);
module_exit(cy_cleanup_module);
MODULE_LICENSE("GPL");
+MODULE_VERSION(CY_VERSION);
diff --git a/drivers/char/digi.h b/drivers/char/digi.h
deleted file mode 100644
index 19df0e8..0000000
--- a/drivers/char/digi.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* Definitions for DigiBoard ditty(1) command. */
-
-#if !defined(TIOCMODG)
-#define TIOCMODG (('d'<<8) | 250) /* get modem ctrl state */
-#define TIOCMODS (('d'<<8) | 251) /* set modem ctrl state */
-#endif
-
-#if !defined(TIOCMSET)
-#define TIOCMSET (('d'<<8) | 252) /* set modem ctrl state */
-#define TIOCMGET (('d'<<8) | 253) /* set modem ctrl state */
-#endif
-
-#if !defined(TIOCMBIC)
-#define TIOCMBIC (('d'<<8) | 254) /* set modem ctrl state */
-#define TIOCMBIS (('d'<<8) | 255) /* set modem ctrl state */
-#endif
-
-#if !defined(TIOCSDTR)
-#define TIOCSDTR (('e'<<8) | 0) /* set DTR */
-#define TIOCCDTR (('e'<<8) | 1) /* clear DTR */
-#endif
-
-/************************************************************************
- * Ioctl command arguments for DIGI parameters.
- ************************************************************************/
-#define DIGI_GETA (('e'<<8) | 94) /* Read params */
-
-#define DIGI_SETA (('e'<<8) | 95) /* Set params */
-#define DIGI_SETAW (('e'<<8) | 96) /* Drain & set params */
-#define DIGI_SETAF (('e'<<8) | 97) /* Drain, flush & set params */
-
-#define DIGI_GETFLOW (('e'<<8) | 99) /* Get startc/stopc flow */
- /* control characters */
-#define DIGI_SETFLOW (('e'<<8) | 100) /* Set startc/stopc flow */
- /* control characters */
-#define DIGI_GETAFLOW (('e'<<8) | 101) /* Get Aux. startc/stopc */
- /* flow control chars */
-#define DIGI_SETAFLOW (('e'<<8) | 102) /* Set Aux. startc/stopc */
- /* flow control chars */
-
-struct digiflow_struct {
- unsigned char startc; /* flow cntl start char */
- unsigned char stopc; /* flow cntl stop char */
-};
-
-typedef struct digiflow_struct digiflow_t;
-
-
-/************************************************************************
- * Values for digi_flags
- ************************************************************************/
-#define DIGI_IXON 0x0001 /* Handle IXON in the FEP */
-#define DIGI_FAST 0x0002 /* Fast baud rates */
-#define RTSPACE 0x0004 /* RTS input flow control */
-#define CTSPACE 0x0008 /* CTS output flow control */
-#define DSRPACE 0x0010 /* DSR output flow control */
-#define DCDPACE 0x0020 /* DCD output flow control */
-#define DTRPACE 0x0040 /* DTR input flow control */
-#define DIGI_FORCEDCD 0x0100 /* Force carrier */
-#define DIGI_ALTPIN 0x0200 /* Alternate RJ-45 pin config */
-#define DIGI_AIXON 0x0400 /* Aux flow control in fep */
-
-
-/************************************************************************
- * Structure used with ioctl commands for DIGI parameters.
- ************************************************************************/
-struct digi_struct {
- unsigned short digi_flags; /* Flags (see above) */
-};
-
-typedef struct digi_struct digi_t;
diff --git a/drivers/char/ds1620.c b/drivers/char/ds1620.c
index 3d7efc2..334ad5b 100644
--- a/drivers/char/ds1620.c
+++ b/drivers/char/ds1620.c
@@ -4,7 +4,6 @@
*/
#include <linux/module.h>
#include <linux/miscdevice.h>
-#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/capability.h>
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c
index db984e4..9b8278e 100644
--- a/drivers/char/dsp56k.c
+++ b/drivers/char/dsp56k.c
@@ -32,7 +32,6 @@
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/device.h>
#include <asm/atarihw.h>
diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c
index d8dbdb9..abde6dd 100644
--- a/drivers/char/dtlk.c
+++ b/drivers/char/dtlk.c
@@ -62,7 +62,6 @@
#include <linux/init.h> /* for __init, module_{init,exit} */
#include <linux/poll.h> /* for POLLIN, etc. */
#include <linux/dtlk.h> /* local header file for DoubleTalk values */
-#include <linux/smp_lock.h>
#ifdef TRACING
#define TRACE_TEXT(str) printk(str);
@@ -325,16 +324,22 @@
static int __init dtlk_init(void)
{
+ int err;
+
dtlk_port_lpc = 0;
dtlk_port_tts = 0;
dtlk_busy = 0;
dtlk_major = register_chrdev(0, "dtlk", &dtlk_fops);
- if (dtlk_major == 0) {
+ if (dtlk_major < 0) {
printk(KERN_ERR "DoubleTalk PC - cannot register device\n");
- return 0;
+ return dtlk_major;
}
- if (dtlk_dev_probe() == 0)
- printk(", MAJOR %d\n", dtlk_major);
+ err = dtlk_dev_probe();
+ if (err) {
+ unregister_chrdev(dtlk_major, "dtlk");
+ return err;
+ }
+ printk(", MAJOR %d\n", dtlk_major);
init_waitqueue_head(&dtlk_process_list);
diff --git a/drivers/char/ec3104_keyb.c b/drivers/char/ec3104_keyb.c
index 77f58ed..0200114 100644
--- a/drivers/char/ec3104_keyb.c
+++ b/drivers/char/ec3104_keyb.c
@@ -41,7 +41,6 @@
#include <linux/miscdevice.h>
#include <linux/slab.h>
#include <linux/kbd_kern.h>
-#include <linux/smp_lock.h>
#include <linux/bitops.h>
#include <asm/keyboard.h>
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index de5be30..c6c56fb 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -949,7 +949,7 @@
} /* End forever while */
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(&ch->open_wait, &wait);
if (!tty_hung_up_p(filp))
ch->count++;
diff --git a/drivers/char/genrtc.c b/drivers/char/genrtc.c
index 23b25ad..49f914e 100644
--- a/drivers/char/genrtc.c
+++ b/drivers/char/genrtc.c
@@ -207,7 +207,7 @@
sizeof(unsigned long);
}
out:
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(&gen_rtc_wait, &wait);
return retval;
diff --git a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c
index ae76a9f..f0e7263 100644
--- a/drivers/char/hangcheck-timer.c
+++ b/drivers/char/hangcheck-timer.c
@@ -44,7 +44,6 @@
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/reboot.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index 0f9ed7b..322bc5f 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -111,7 +111,7 @@
* lock held. If successful, this function increments the kobject reference
* count against the target hvc_struct so it should be released when finished.
*/
-struct hvc_struct *hvc_get_by_index(int index)
+static struct hvc_struct *hvc_get_by_index(int index)
{
struct hvc_struct *hp;
unsigned long flags;
@@ -150,7 +150,8 @@
* hvc_console_setup() finds adapters.
*/
-void hvc_console_print(struct console *co, const char *b, unsigned count)
+static void hvc_console_print(struct console *co, const char *b,
+ unsigned count)
{
char c[N_OUTBUF] __ALIGNED__;
unsigned i = 0, n = 0;
@@ -208,7 +209,7 @@
return 0;
}
-struct console hvc_con_driver = {
+static struct console hvc_con_driver = {
.name = "hvc",
.write = hvc_console_print,
.device = hvc_console_device,
@@ -278,7 +279,6 @@
return 0;
}
-EXPORT_SYMBOL(hvc_instantiate);
/* Wake the sleeping khvcd */
static void hvc_kick(void)
@@ -792,7 +792,6 @@
return hp;
}
-EXPORT_SYMBOL(hvc_alloc);
int __devexit hvc_remove(struct hvc_struct *hp)
{
@@ -828,11 +827,10 @@
tty_hangup(tty);
return 0;
}
-EXPORT_SYMBOL(hvc_remove);
/* Driver initialization. Follow console initialization. This is where the TTY
* interfaces start to become available. */
-int __init hvc_init(void)
+static int __init hvc_init(void)
{
struct tty_driver *drv;
diff --git a/drivers/char/hvc_iseries.c b/drivers/char/hvc_iseries.c
index ec420fe..b37f1d5 100644
--- a/drivers/char/hvc_iseries.c
+++ b/drivers/char/hvc_iseries.c
@@ -579,7 +579,7 @@
if (!vtermno)
continue;
- if (!device_is_compatible(vty, "IBM,iSeries-vty"))
+ if (!of_device_is_compatible(vty, "IBM,iSeries-vty"))
continue;
if (num_found == 0)
diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c
index 94a542e..79711aa 100644
--- a/drivers/char/hvc_vio.c
+++ b/drivers/char/hvc_vio.c
@@ -157,7 +157,7 @@
if (!vtermno)
continue;
- if (device_is_compatible(vty, "hvterm1")) {
+ if (of_device_is_compatible(vty, "hvterm1")) {
hvc_instantiate(*vtermno, num_found, &hvc_get_put_ops);
++num_found;
}
diff --git a/drivers/char/hw_random/intel-rng.c b/drivers/char/hw_random/intel-rng.c
index cc1046e..4ae9811 100644
--- a/drivers/char/hw_random/intel-rng.c
+++ b/drivers/char/hw_random/intel-rng.c
@@ -24,10 +24,11 @@
* warranty of any kind, whether express or implied.
*/
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
#include <linux/hw_random.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/stop_machine.h>
#include <asm/io.h>
@@ -217,30 +218,117 @@
.data_read = intel_rng_data_read,
};
+struct intel_rng_hw {
+ struct pci_dev *dev;
+ void __iomem *mem;
+ u8 bios_cntl_off;
+ u8 bios_cntl_val;
+ u8 fwh_dec_en1_off;
+ u8 fwh_dec_en1_val;
+};
-#ifdef CONFIG_SMP
-static char __initdata waitflag;
-
-static void __init intel_init_wait(void *unused)
+static int __init intel_rng_hw_init(void *_intel_rng_hw)
{
- while (waitflag)
- cpu_relax();
+ struct intel_rng_hw *intel_rng_hw = _intel_rng_hw;
+ u8 mfc, dvc;
+
+ /* interrupts disabled in stop_machine_run call */
+
+ if (!(intel_rng_hw->fwh_dec_en1_val & FWH_F8_EN_MASK))
+ pci_write_config_byte(intel_rng_hw->dev,
+ intel_rng_hw->fwh_dec_en1_off,
+ intel_rng_hw->fwh_dec_en1_val |
+ FWH_F8_EN_MASK);
+ if (!(intel_rng_hw->bios_cntl_val & BIOS_CNTL_WRITE_ENABLE_MASK))
+ pci_write_config_byte(intel_rng_hw->dev,
+ intel_rng_hw->bios_cntl_off,
+ intel_rng_hw->bios_cntl_val |
+ BIOS_CNTL_WRITE_ENABLE_MASK);
+
+ writeb(INTEL_FWH_RESET_CMD, intel_rng_hw->mem);
+ writeb(INTEL_FWH_READ_ID_CMD, intel_rng_hw->mem);
+ mfc = readb(intel_rng_hw->mem + INTEL_FWH_MANUFACTURER_CODE_ADDRESS);
+ dvc = readb(intel_rng_hw->mem + INTEL_FWH_DEVICE_CODE_ADDRESS);
+ writeb(INTEL_FWH_RESET_CMD, intel_rng_hw->mem);
+
+ if (!(intel_rng_hw->bios_cntl_val &
+ (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK)))
+ pci_write_config_byte(intel_rng_hw->dev,
+ intel_rng_hw->bios_cntl_off,
+ intel_rng_hw->bios_cntl_val);
+ if (!(intel_rng_hw->fwh_dec_en1_val & FWH_F8_EN_MASK))
+ pci_write_config_byte(intel_rng_hw->dev,
+ intel_rng_hw->fwh_dec_en1_off,
+ intel_rng_hw->fwh_dec_en1_val);
+
+ if (mfc != INTEL_FWH_MANUFACTURER_CODE ||
+ (dvc != INTEL_FWH_DEVICE_CODE_8M &&
+ dvc != INTEL_FWH_DEVICE_CODE_4M)) {
+ printk(KERN_ERR PFX "FWH not detected\n");
+ return -ENODEV;
+ }
+
+ return 0;
}
-#endif
+
+static int __init intel_init_hw_struct(struct intel_rng_hw *intel_rng_hw,
+ struct pci_dev *dev)
+{
+ intel_rng_hw->bios_cntl_val = 0xff;
+ intel_rng_hw->fwh_dec_en1_val = 0xff;
+ intel_rng_hw->dev = dev;
+
+ /* Check for Intel 82802 */
+ if (dev->device < 0x2640) {
+ intel_rng_hw->fwh_dec_en1_off = FWH_DEC_EN1_REG_OLD;
+ intel_rng_hw->bios_cntl_off = BIOS_CNTL_REG_OLD;
+ } else {
+ intel_rng_hw->fwh_dec_en1_off = FWH_DEC_EN1_REG_NEW;
+ intel_rng_hw->bios_cntl_off = BIOS_CNTL_REG_NEW;
+ }
+
+ pci_read_config_byte(dev, intel_rng_hw->fwh_dec_en1_off,
+ &intel_rng_hw->fwh_dec_en1_val);
+ pci_read_config_byte(dev, intel_rng_hw->bios_cntl_off,
+ &intel_rng_hw->bios_cntl_val);
+
+ if ((intel_rng_hw->bios_cntl_val &
+ (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK))
+ == BIOS_CNTL_LOCK_ENABLE_MASK) {
+ static __initdata /*const*/ char warning[] =
+ KERN_WARNING PFX "Firmware space is locked read-only. "
+ KERN_WARNING PFX "If you can't or\n don't want to "
+ KERN_WARNING PFX "disable this in firmware setup, and "
+ KERN_WARNING PFX "if\n you are certain that your "
+ KERN_WARNING PFX "system has a functional\n RNG, try"
+ KERN_WARNING PFX "using the 'no_fwh_detect' option.\n";
+
+ if (no_fwh_detect)
+ return -ENODEV;
+ printk(warning);
+ return -EBUSY;
+ }
+
+ intel_rng_hw->mem = ioremap_nocache(INTEL_FWH_ADDR, INTEL_FWH_ADDR_LEN);
+ if (intel_rng_hw->mem == NULL)
+ return -EBUSY;
+
+ return 0;
+}
+
static int __init mod_init(void)
{
int err = -ENODEV;
- unsigned i;
+ int i;
struct pci_dev *dev = NULL;
- void __iomem *mem;
- unsigned long flags;
- u8 bios_cntl_off, fwh_dec_en1_off;
- u8 bios_cntl_val = 0xff, fwh_dec_en1_val = 0xff;
- u8 hw_status, mfc, dvc;
+ void __iomem *mem = mem;
+ u8 hw_status;
+ struct intel_rng_hw *intel_rng_hw;
for (i = 0; !dev && pci_tbl[i].vendor; ++i)
- dev = pci_get_device(pci_tbl[i].vendor, pci_tbl[i].device, NULL);
+ dev = pci_get_device(pci_tbl[i].vendor, pci_tbl[i].device,
+ NULL);
if (!dev)
goto out; /* Device not found. */
@@ -250,39 +338,18 @@
goto fwh_done;
}
- /* Check for Intel 82802 */
- if (dev->device < 0x2640) {
- fwh_dec_en1_off = FWH_DEC_EN1_REG_OLD;
- bios_cntl_off = BIOS_CNTL_REG_OLD;
- } else {
- fwh_dec_en1_off = FWH_DEC_EN1_REG_NEW;
- bios_cntl_off = BIOS_CNTL_REG_NEW;
- }
-
- pci_read_config_byte(dev, fwh_dec_en1_off, &fwh_dec_en1_val);
- pci_read_config_byte(dev, bios_cntl_off, &bios_cntl_val);
-
- if ((bios_cntl_val &
- (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK))
- == BIOS_CNTL_LOCK_ENABLE_MASK) {
- static __initdata /*const*/ char warning[] =
- KERN_WARNING PFX "Firmware space is locked read-only. If you can't or\n"
- KERN_WARNING PFX "don't want to disable this in firmware setup, and if\n"
- KERN_WARNING PFX "you are certain that your system has a functional\n"
- KERN_WARNING PFX "RNG, try using the 'no_fwh_detect' option.\n";
-
+ intel_rng_hw = kmalloc(sizeof(*intel_rng_hw), GFP_KERNEL);
+ if (!intel_rng_hw) {
pci_dev_put(dev);
- if (no_fwh_detect)
- goto fwh_done;
- printk(warning);
- err = -EBUSY;
goto out;
}
- mem = ioremap_nocache(INTEL_FWH_ADDR, INTEL_FWH_ADDR_LEN);
- if (mem == NULL) {
+ err = intel_init_hw_struct(intel_rng_hw, dev);
+ if (err) {
pci_dev_put(dev);
- err = -EBUSY;
+ kfree(intel_rng_hw);
+ if (err == -ENODEV)
+ goto fwh_done;
goto out;
}
@@ -290,59 +357,18 @@
* Since the BIOS code/data is going to disappear from its normal
* location with the Read ID command, all activity on the system
* must be stopped until the state is back to normal.
+ *
+ * Use stop_machine_run because IPIs can be blocked by disabling
+ * interrupts.
*/
-#ifdef CONFIG_SMP
- set_mb(waitflag, 1);
- if (smp_call_function(intel_init_wait, NULL, 1, 0) != 0) {
- set_mb(waitflag, 0);
- pci_dev_put(dev);
- printk(KERN_ERR PFX "cannot run on all processors\n");
- err = -EAGAIN;
- goto err_unmap;
- }
-#endif
- local_irq_save(flags);
-
- if (!(fwh_dec_en1_val & FWH_F8_EN_MASK))
- pci_write_config_byte(dev,
- fwh_dec_en1_off,
- fwh_dec_en1_val | FWH_F8_EN_MASK);
- if (!(bios_cntl_val & BIOS_CNTL_WRITE_ENABLE_MASK))
- pci_write_config_byte(dev,
- bios_cntl_off,
- bios_cntl_val | BIOS_CNTL_WRITE_ENABLE_MASK);
-
- writeb(INTEL_FWH_RESET_CMD, mem);
- writeb(INTEL_FWH_READ_ID_CMD, mem);
- mfc = readb(mem + INTEL_FWH_MANUFACTURER_CODE_ADDRESS);
- dvc = readb(mem + INTEL_FWH_DEVICE_CODE_ADDRESS);
- writeb(INTEL_FWH_RESET_CMD, mem);
-
- if (!(bios_cntl_val &
- (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK)))
- pci_write_config_byte(dev, bios_cntl_off, bios_cntl_val);
- if (!(fwh_dec_en1_val & FWH_F8_EN_MASK))
- pci_write_config_byte(dev, fwh_dec_en1_off, fwh_dec_en1_val);
-
- local_irq_restore(flags);
-#ifdef CONFIG_SMP
- /* Tell other CPUs to resume. */
- set_mb(waitflag, 0);
-#endif
-
- iounmap(mem);
+ err = stop_machine_run(intel_rng_hw_init, intel_rng_hw, NR_CPUS);
pci_dev_put(dev);
-
- if (mfc != INTEL_FWH_MANUFACTURER_CODE ||
- (dvc != INTEL_FWH_DEVICE_CODE_8M &&
- dvc != INTEL_FWH_DEVICE_CODE_4M)) {
- printk(KERN_ERR PFX "FWH not detected\n");
- err = -ENODEV;
+ iounmap(intel_rng_hw->mem);
+ kfree(intel_rng_hw);
+ if (err)
goto out;
- }
fwh_done:
-
err = -ENOMEM;
mem = ioremap(INTEL_RNG_ADDR, INTEL_RNG_ADDR_LEN);
if (!mem)
@@ -352,22 +378,21 @@
/* Check for Random Number Generator */
err = -ENODEV;
hw_status = hwstatus_get(mem);
- if ((hw_status & INTEL_RNG_PRESENT) == 0)
- goto err_unmap;
+ if ((hw_status & INTEL_RNG_PRESENT) == 0) {
+ iounmap(mem);
+ goto out;
+ }
printk(KERN_INFO "Intel 82802 RNG detected\n");
err = hwrng_register(&intel_rng);
if (err) {
printk(KERN_ERR PFX "RNG registering failed (%d)\n",
err);
- goto err_unmap;
+ iounmap(mem);
}
out:
return err;
-err_unmap:
- iounmap(mem);
- goto out;
}
static void __exit mod_exit(void)
diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
index 353d9f3..0289705 100644
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -22,6 +22,7 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/dmi.h>
+#include <linux/capability.h>
#include <asm/uaccess.h>
#include <asm/io.h>
diff --git a/drivers/char/ip27-rtc.c b/drivers/char/ip27-rtc.c
index a48da02..932264a 100644
--- a/drivers/char/ip27-rtc.c
+++ b/drivers/char/ip27-rtc.c
@@ -35,7 +35,6 @@
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/proc_fs.h>
-#include <linux/smp_lock.h>
#include <asm/m48t35.h>
#include <asm/sn/ioc3.h>
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index e221465..6c5d15d 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -9,6 +9,7 @@
* source@mvista.com
*
* Copyright 2002 MontaVista Software Inc.
+ * Copyright 2006 IBM Corp., Christian Krafft <krafft@de.ibm.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -64,6 +65,11 @@
#include <linux/string.h>
#include <linux/ctype.h>
+#ifdef CONFIG_PPC_OF
+#include <asm/of_device.h>
+#include <asm/of_platform.h>
+#endif
+
#define PFX "ipmi_si: "
/* Measure times between events in the driver. */
@@ -76,6 +82,12 @@
#define SI_SHORT_TIMEOUT_USEC 250 /* .25ms when the SM request a
short timeout */
+/* Bit for BMC global enables. */
+#define IPMI_BMC_RCV_MSG_INTR 0x01
+#define IPMI_BMC_EVT_MSG_INTR 0x02
+#define IPMI_BMC_EVT_MSG_BUFF 0x04
+#define IPMI_BMC_SYS_LOG 0x08
+
enum si_intf_state {
SI_NORMAL,
SI_GETTING_FLAGS,
@@ -84,7 +96,9 @@
SI_CLEARING_FLAGS_THEN_SET_IRQ,
SI_GETTING_MESSAGES,
SI_ENABLE_INTERRUPTS1,
- SI_ENABLE_INTERRUPTS2
+ SI_ENABLE_INTERRUPTS2,
+ SI_DISABLE_INTERRUPTS1,
+ SI_DISABLE_INTERRUPTS2
/* FIXME - add watchdog stuff. */
};
@@ -333,6 +347,17 @@
smi_info->si_state = SI_ENABLE_INTERRUPTS1;
}
+static void start_disable_irq(struct smi_info *smi_info)
+{
+ unsigned char msg[2];
+
+ msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
+ msg[1] = IPMI_GET_BMC_GLOBAL_ENABLES_CMD;
+
+ smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2);
+ smi_info->si_state = SI_DISABLE_INTERRUPTS1;
+}
+
static void start_clear_flags(struct smi_info *smi_info)
{
unsigned char msg[3];
@@ -353,7 +378,7 @@
static inline void disable_si_irq(struct smi_info *smi_info)
{
if ((smi_info->irq) && (!smi_info->interrupt_disabled)) {
- disable_irq_nosync(smi_info->irq);
+ start_disable_irq(smi_info);
smi_info->interrupt_disabled = 1;
}
}
@@ -361,7 +386,7 @@
static inline void enable_si_irq(struct smi_info *smi_info)
{
if ((smi_info->irq) && (smi_info->interrupt_disabled)) {
- enable_irq(smi_info->irq);
+ start_enable_irq(smi_info);
smi_info->interrupt_disabled = 0;
}
}
@@ -583,7 +608,9 @@
} else {
msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD;
- msg[2] = msg[3] | 1; /* enable msg queue int */
+ msg[2] = (msg[3] |
+ IPMI_BMC_RCV_MSG_INTR |
+ IPMI_BMC_EVT_MSG_INTR);
smi_info->handlers->start_transaction(
smi_info->si_sm, msg, 3);
smi_info->si_state = SI_ENABLE_INTERRUPTS2;
@@ -605,6 +632,45 @@
smi_info->si_state = SI_NORMAL;
break;
}
+
+ case SI_DISABLE_INTERRUPTS1:
+ {
+ unsigned char msg[4];
+
+ /* We got the flags from the SMI, now handle them. */
+ smi_info->handlers->get_result(smi_info->si_sm, msg, 4);
+ if (msg[2] != 0) {
+ printk(KERN_WARNING
+ "ipmi_si: Could not disable interrupts"
+ ", failed get.\n");
+ smi_info->si_state = SI_NORMAL;
+ } else {
+ msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
+ msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD;
+ msg[2] = (msg[3] &
+ ~(IPMI_BMC_RCV_MSG_INTR |
+ IPMI_BMC_EVT_MSG_INTR));
+ smi_info->handlers->start_transaction(
+ smi_info->si_sm, msg, 3);
+ smi_info->si_state = SI_DISABLE_INTERRUPTS2;
+ }
+ break;
+ }
+
+ case SI_DISABLE_INTERRUPTS2:
+ {
+ unsigned char msg[4];
+
+ /* We got the flags from the SMI, now handle them. */
+ smi_info->handlers->get_result(smi_info->si_sm, msg, 4);
+ if (msg[2] != 0) {
+ printk(KERN_WARNING
+ "ipmi_si: Could not disable interrupts"
+ ", failed set.\n");
+ }
+ smi_info->si_state = SI_NORMAL;
+ break;
+ }
}
}
@@ -858,9 +924,6 @@
struct timeval t;
#endif
- if (atomic_read(&smi_info->stop_operation))
- return;
-
spin_lock_irqsave(&(smi_info->si_lock), flags);
#ifdef DEBUG_TIMING
do_gettimeofday(&t);
@@ -916,15 +979,11 @@
smi_info->interrupts++;
spin_unlock(&smi_info->count_lock);
- if (atomic_read(&smi_info->stop_operation))
- goto out;
-
#ifdef DEBUG_TIMING
do_gettimeofday(&t);
printk("**Interrupt: %d.%9.9d\n", t.tv_sec, t.tv_usec);
#endif
smi_event_handler(smi_info, 0);
- out:
spin_unlock_irqrestore(&(smi_info->si_lock), flags);
return IRQ_HANDLED;
}
@@ -1006,6 +1065,7 @@
static int smi_num; /* Used to sequence the SMIs */
#define DEFAULT_REGSPACING 1
+#define DEFAULT_REGSIZE 1
static int si_trydefaults = 1;
static char *si_type[SI_MAX_PARMS];
@@ -1111,7 +1171,7 @@
if (info->si_type == SI_BT) {
rv = request_irq(info->irq,
si_bt_irq_handler,
- IRQF_DISABLED,
+ IRQF_SHARED | IRQF_DISABLED,
DEVICE_NAME,
info);
if (!rv)
@@ -1121,7 +1181,7 @@
} else
rv = request_irq(info->irq,
si_irq_handler,
- IRQF_DISABLED,
+ IRQF_SHARED | IRQF_DISABLED,
DEVICE_NAME,
info);
if (rv) {
@@ -1701,15 +1761,11 @@
smi_info->interrupts++;
spin_unlock(&smi_info->count_lock);
- if (atomic_read(&smi_info->stop_operation))
- goto out;
-
#ifdef DEBUG_TIMING
do_gettimeofday(&t);
printk("**ACPI_GPE: %d.%9.9d\n", t.tv_sec, t.tv_usec);
#endif
smi_event_handler(smi_info, 0);
- out:
spin_unlock_irqrestore(&(smi_info->si_lock), flags);
return ACPI_INTERRUPT_HANDLED;
@@ -2133,12 +2189,15 @@
info->irq_setup = std_irq_setup;
info->dev = &pdev->dev;
+ pci_set_drvdata(pdev, info);
return try_smi_init(info);
}
static void __devexit ipmi_pci_remove(struct pci_dev *pdev)
{
+ struct smi_info *info = pci_get_drvdata(pdev);
+ cleanup_one_si(info);
}
#ifdef CONFIG_PM
@@ -2172,6 +2231,99 @@
#endif /* CONFIG_PCI */
+#ifdef CONFIG_PPC_OF
+static int __devinit ipmi_of_probe(struct of_device *dev,
+ const struct of_device_id *match)
+{
+ struct smi_info *info;
+ struct resource resource;
+ const int *regsize, *regspacing, *regshift;
+ struct device_node *np = dev->node;
+ int ret;
+ int proplen;
+
+ dev_info(&dev->dev, PFX "probing via device tree\n");
+
+ ret = of_address_to_resource(np, 0, &resource);
+ if (ret) {
+ dev_warn(&dev->dev, PFX "invalid address from OF\n");
+ return ret;
+ }
+
+ regsize = get_property(np, "reg-size", &proplen);
+ if (regsize && proplen != 4) {
+ dev_warn(&dev->dev, PFX "invalid regsize from OF\n");
+ return -EINVAL;
+ }
+
+ regspacing = get_property(np, "reg-spacing", &proplen);
+ if (regspacing && proplen != 4) {
+ dev_warn(&dev->dev, PFX "invalid regspacing from OF\n");
+ return -EINVAL;
+ }
+
+ regshift = get_property(np, "reg-shift", &proplen);
+ if (regshift && proplen != 4) {
+ dev_warn(&dev->dev, PFX "invalid regshift from OF\n");
+ return -EINVAL;
+ }
+
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
+
+ if (!info) {
+ dev_err(&dev->dev,
+ PFX "could not allocate memory for OF probe\n");
+ return -ENOMEM;
+ }
+
+ info->si_type = (enum si_type) match->data;
+ info->addr_source = "device-tree";
+ info->io_setup = mem_setup;
+ info->irq_setup = std_irq_setup;
+
+ info->io.addr_type = IPMI_MEM_ADDR_SPACE;
+ info->io.addr_data = resource.start;
+
+ info->io.regsize = regsize ? *regsize : DEFAULT_REGSIZE;
+ info->io.regspacing = regspacing ? *regspacing : DEFAULT_REGSPACING;
+ info->io.regshift = regshift ? *regshift : 0;
+
+ info->irq = irq_of_parse_and_map(dev->node, 0);
+ info->dev = &dev->dev;
+
+ dev_dbg(&dev->dev, "addr 0x%lx regsize %ld spacing %ld irq %x\n",
+ info->io.addr_data, info->io.regsize, info->io.regspacing,
+ info->irq);
+
+ dev->dev.driver_data = (void*) info;
+
+ return try_smi_init(info);
+}
+
+static int __devexit ipmi_of_remove(struct of_device *dev)
+{
+ cleanup_one_si(dev->dev.driver_data);
+ return 0;
+}
+
+static struct of_device_id ipmi_match[] =
+{
+ { .type = "ipmi", .compatible = "ipmi-kcs", .data = (void *)(unsigned long) SI_KCS },
+ { .type = "ipmi", .compatible = "ipmi-smic", .data = (void *)(unsigned long) SI_SMIC },
+ { .type = "ipmi", .compatible = "ipmi-bt", .data = (void *)(unsigned long) SI_BT },
+ {},
+};
+
+static struct of_platform_driver ipmi_of_platform_driver =
+{
+ .name = "ipmi",
+ .match_table = ipmi_match,
+ .probe = ipmi_of_probe,
+ .remove = __devexit_p(ipmi_of_remove),
+};
+#endif /* CONFIG_PPC_OF */
+
+
static int try_get_dev_id(struct smi_info *smi_info)
{
unsigned char msg[2];
@@ -2801,6 +2953,10 @@
}
#endif
+#ifdef CONFIG_PPC_OF
+ of_register_platform_driver(&ipmi_of_platform_driver);
+#endif
+
if (si_trydefaults) {
mutex_lock(&smi_infos_lock);
if (list_empty(&smi_infos)) {
@@ -2838,28 +2994,33 @@
list_del(&to_clean->link);
- /* Tell the timer and interrupt handlers that we are shutting
- down. */
- spin_lock_irqsave(&(to_clean->si_lock), flags);
- spin_lock(&(to_clean->msg_lock));
-
+ /* Tell the driver that we are shutting down. */
atomic_inc(&to_clean->stop_operation);
- if (to_clean->irq_cleanup)
- to_clean->irq_cleanup(to_clean);
-
- spin_unlock(&(to_clean->msg_lock));
- spin_unlock_irqrestore(&(to_clean->si_lock), flags);
-
- /* Wait until we know that we are out of any interrupt
- handlers might have been running before we freed the
- interrupt. */
- synchronize_sched();
-
+ /* Make sure the timer and thread are stopped and will not run
+ again. */
wait_for_timer_and_thread(to_clean);
- /* Interrupts and timeouts are stopped, now make sure the
- interface is in a clean state. */
+ /* Timeouts are stopped, now make sure the interrupts are off
+ for the device. A little tricky with locks to make sure
+ there are no races. */
+ spin_lock_irqsave(&to_clean->si_lock, flags);
+ while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) {
+ spin_unlock_irqrestore(&to_clean->si_lock, flags);
+ poll(to_clean);
+ schedule_timeout_uninterruptible(1);
+ spin_lock_irqsave(&to_clean->si_lock, flags);
+ }
+ disable_si_irq(to_clean);
+ spin_unlock_irqrestore(&to_clean->si_lock, flags);
+ while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) {
+ poll(to_clean);
+ schedule_timeout_uninterruptible(1);
+ }
+
+ /* Clean up interrupts and make sure that everything is done. */
+ if (to_clean->irq_cleanup)
+ to_clean->irq_cleanup(to_clean);
while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) {
poll(to_clean);
schedule_timeout_uninterruptible(1);
@@ -2898,6 +3059,10 @@
pci_unregister_driver(&ipmi_pci_driver);
#endif
+#ifdef CONFIG_PPC_OF
+ of_unregister_platform_driver(&ipmi_of_platform_driver);
+#endif
+
mutex_lock(&smi_infos_lock);
list_for_each_entry_safe(e, tmp_e, &smi_infos, link)
cleanup_one_si(e);
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index 6b634e8..147c120 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -39,6 +39,7 @@
#include <linux/miscdevice.h>
#include <linux/init.h>
#include <linux/completion.h>
+#include <linux/kdebug.h>
#include <linux/rwsem.h>
#include <linux/errno.h>
#include <asm/uaccess.h>
@@ -49,9 +50,18 @@
#include <linux/poll.h>
#include <linux/string.h>
#include <linux/ctype.h>
+#include <linux/delay.h>
#include <asm/atomic.h>
-#ifdef CONFIG_X86_LOCAL_APIC
-#include <asm/apic.h>
+
+#ifdef CONFIG_X86
+/* This is ugly, but I've determined that x86 is the only architecture
+ that can reasonably support the IPMI NMI watchdog timeout at this
+ time. If another architecture adds this capability somehow, it
+ will have to be a somewhat different mechanism and I have no idea
+ how it will work. So in the unlikely event that another
+ architecture supports this, we can figure out a good generic
+ mechanism for it at that time. */
+#define HAVE_DIE_NMI_POST
#endif
#define PFX "IPMI Watchdog: "
@@ -317,6 +327,11 @@
/* If a pretimeout occurs, this is used to allow only one panic to happen. */
static atomic_t preop_panic_excl = ATOMIC_INIT(-1);
+#ifdef HAVE_DIE_NMI_POST
+static int testing_nmi;
+static int nmi_handler_registered;
+#endif
+
static int ipmi_heartbeat(void);
static void panic_halt_ipmi_heartbeat(void);
@@ -358,6 +373,10 @@
int hbnow = 0;
+ /* These can be cleared as we are setting the timeout. */
+ ipmi_start_timer_on_heartbeat = 0;
+ pretimeout_since_last_heartbeat = 0;
+
data[0] = 0;
WDOG_SET_TIMER_USE(data[0], WDOG_TIMER_USE_SMS_OS);
@@ -432,13 +451,12 @@
wait_for_completion(&set_timeout_wait);
+ mutex_unlock(&set_timeout_lock);
+
if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB)
|| ((send_heartbeat_now)
&& (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY)))
- {
rv = ipmi_heartbeat();
- }
- mutex_unlock(&set_timeout_lock);
out:
return rv;
@@ -518,12 +536,10 @@
int rv;
struct ipmi_system_interface_addr addr;
- if (ipmi_ignore_heartbeat) {
+ if (ipmi_ignore_heartbeat)
return 0;
- }
if (ipmi_start_timer_on_heartbeat) {
- ipmi_start_timer_on_heartbeat = 0;
ipmi_watchdog_state = action_val;
return ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB);
} else if (pretimeout_since_last_heartbeat) {
@@ -531,7 +547,6 @@
We don't want to set the action, though, we want to
leave that alone (thus it can't be combined with the
above operation. */
- pretimeout_since_last_heartbeat = 0;
return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
}
@@ -919,6 +934,45 @@
printk(KERN_CRIT PFX "Unable to register misc device\n");
}
+#ifdef HAVE_DIE_NMI_POST
+ if (nmi_handler_registered) {
+ int old_pretimeout = pretimeout;
+ int old_timeout = timeout;
+ int old_preop_val = preop_val;
+
+ /* Set the pretimeout to go off in a second and give
+ ourselves plenty of time to stop the timer. */
+ ipmi_watchdog_state = WDOG_TIMEOUT_RESET;
+ preop_val = WDOG_PREOP_NONE; /* Make sure nothing happens */
+ pretimeout = 99;
+ timeout = 100;
+
+ testing_nmi = 1;
+
+ rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB);
+ if (rv) {
+ printk(KERN_WARNING PFX "Error starting timer to"
+ " test NMI: 0x%x. The NMI pretimeout will"
+ " likely not work\n", rv);
+ rv = 0;
+ goto out_restore;
+ }
+
+ msleep(1500);
+
+ if (testing_nmi != 2) {
+ printk(KERN_WARNING PFX "IPMI NMI didn't seem to"
+ " occur. The NMI pretimeout will"
+ " likely not work\n");
+ }
+ out_restore:
+ testing_nmi = 0;
+ preop_val = old_preop_val;
+ pretimeout = old_pretimeout;
+ timeout = old_timeout;
+ }
+#endif
+
out:
up_write(®ister_sem);
@@ -928,6 +982,10 @@
ipmi_watchdog_state = action_val;
ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB);
printk(KERN_INFO PFX "Starting now!\n");
+ } else {
+ /* Stop the timer now. */
+ ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
+ ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB);
}
}
@@ -964,17 +1022,28 @@
up_write(®ister_sem);
}
-#ifdef HAVE_NMI_HANDLER
+#ifdef HAVE_DIE_NMI_POST
static int
-ipmi_nmi(void *dev_id, int cpu, int handled)
+ipmi_nmi(struct notifier_block *self, unsigned long val, void *data)
{
+ if (val != DIE_NMI_POST)
+ return NOTIFY_OK;
+
+ if (testing_nmi) {
+ testing_nmi = 2;
+ return NOTIFY_STOP;
+ }
+
/* If we are not expecting a timeout, ignore it. */
if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE)
- return NOTIFY_DONE;
+ return NOTIFY_OK;
+
+ if (preaction_val != WDOG_PRETIMEOUT_NMI)
+ return NOTIFY_OK;
/* If no one else handled the NMI, we assume it was the IPMI
watchdog. */
- if ((!handled) && (preop_val == WDOG_PREOP_PANIC)) {
+ if (preop_val == WDOG_PREOP_PANIC) {
/* On some machines, the heartbeat will give
an error and not work unless we re-enable
the timer. So do so. */
@@ -983,18 +1052,12 @@
panic(PFX "pre-timeout");
}
- return NOTIFY_DONE;
+ return NOTIFY_STOP;
}
-static struct nmi_handler ipmi_nmi_handler =
-{
- .link = LIST_HEAD_INIT(ipmi_nmi_handler.link),
- .dev_name = "ipmi_watchdog",
- .dev_id = NULL,
- .handler = ipmi_nmi,
- .priority = 0, /* Call us last. */
+static struct notifier_block ipmi_nmi_handler = {
+ .notifier_call = ipmi_nmi
};
-int nmi_handler_registered;
#endif
static int wdog_reboot_handler(struct notifier_block *this,
@@ -1111,7 +1174,7 @@
preaction_val = WDOG_PRETIMEOUT_NONE;
else if (strcmp(inval, "pre_smi") == 0)
preaction_val = WDOG_PRETIMEOUT_SMI;
-#ifdef HAVE_NMI_HANDLER
+#ifdef HAVE_DIE_NMI_POST
else if (strcmp(inval, "pre_nmi") == 0)
preaction_val = WDOG_PRETIMEOUT_NMI;
#endif
@@ -1145,7 +1208,7 @@
static void check_parms(void)
{
-#ifdef HAVE_NMI_HANDLER
+#ifdef HAVE_DIE_NMI_POST
int do_nmi = 0;
int rv;
@@ -1158,20 +1221,9 @@
preop_op("preop_none", NULL);
do_nmi = 0;
}
-#ifdef CONFIG_X86_LOCAL_APIC
- if (nmi_watchdog == NMI_IO_APIC) {
- printk(KERN_WARNING PFX "nmi_watchdog is set to IO APIC"
- " mode (value is %d), that is incompatible"
- " with using NMI in the IPMI watchdog."
- " Disabling IPMI nmi pretimeout.\n",
- nmi_watchdog);
- preaction_val = WDOG_PRETIMEOUT_NONE;
- do_nmi = 0;
- }
-#endif
}
if (do_nmi && !nmi_handler_registered) {
- rv = request_nmi(&ipmi_nmi_handler);
+ rv = register_die_notifier(&ipmi_nmi_handler);
if (rv) {
printk(KERN_WARNING PFX
"Can't register nmi handler\n");
@@ -1179,7 +1231,7 @@
} else
nmi_handler_registered = 1;
} else if (!do_nmi && nmi_handler_registered) {
- release_nmi(&ipmi_nmi_handler);
+ unregister_die_notifier(&ipmi_nmi_handler);
nmi_handler_registered = 0;
}
#endif
@@ -1215,9 +1267,9 @@
rv = ipmi_smi_watcher_register(&smi_watcher);
if (rv) {
-#ifdef HAVE_NMI_HANDLER
- if (preaction_val == WDOG_PRETIMEOUT_NMI)
- release_nmi(&ipmi_nmi_handler);
+#ifdef HAVE_DIE_NMI_POST
+ if (nmi_handler_registered)
+ unregister_die_notifier(&ipmi_nmi_handler);
#endif
atomic_notifier_chain_unregister(&panic_notifier_list,
&wdog_panic_notifier);
@@ -1236,9 +1288,9 @@
ipmi_smi_watcher_unregister(&smi_watcher);
ipmi_unregister_watchdog(watchdog_ifnum);
-#ifdef HAVE_NMI_HANDLER
+#ifdef HAVE_DIE_NMI_POST
if (nmi_handler_registered)
- release_nmi(&ipmi_nmi_handler);
+ unregister_die_notifier(&ipmi_nmi_handler);
#endif
atomic_notifier_chain_unregister(&panic_notifier_list,
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 43ab9ed..761f777 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -137,11 +137,10 @@
#define InterruptTheCard(base) outw(0, (base) + 0xc)
#define ClearInterrupt(base) inw((base) + 0x0a)
+#define pr_dbg(str...) pr_debug("ISICOM: " str)
#ifdef DEBUG
-#define pr_dbg(str...) printk(KERN_DEBUG "ISICOM: " str)
#define isicom_paranoia_check(a, b, c) __isicom_paranoia_check((a), (b), (c))
#else
-#define pr_dbg(str...) do { } while (0)
#define isicom_paranoia_check(a, b, c) 0
#endif
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index c06e86a..1b09450 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -109,7 +109,7 @@
static struct kbd_struct *kbd = kbd_table;
struct vt_spawn_console vt_spawn_con = {
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(vt_spawn_con.lock),
.pid = NULL,
.sig = 0,
};
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index b51d08b..62051f8 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -118,7 +118,6 @@
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/sched.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/fcntl.h>
#include <linux/delay.h>
@@ -139,9 +138,6 @@
/* if you have more than 8 printers, remember to increase LP_NO */
#define LP_NO 8
-/* ROUND_UP macro from fs/select.c */
-#define ROUND_UP(x,y) (((x)+(y)-1)/(y))
-
static struct lp_struct lp_table[LP_NO];
static unsigned int lp_count = 0;
@@ -652,7 +648,7 @@
(par_timeout.tv_usec < 0)) {
return -EINVAL;
}
- to_jiffies = ROUND_UP(par_timeout.tv_usec, 1000000/HZ);
+ to_jiffies = DIV_ROUND_UP(par_timeout.tv_usec, 1000000/HZ);
to_jiffies += par_timeout.tv_sec * (long) HZ;
if (to_jiffies <= 0) {
return -EINVAL;
@@ -803,7 +799,7 @@
if (reset)
lp_reset(nr);
- class_device_create(lp_class, NULL, MKDEV(LP_MAJOR, nr), NULL,
+ class_device_create(lp_class, NULL, MKDEV(LP_MAJOR, nr), port->dev,
"lp%d", nr);
printk(KERN_INFO "lp%d: using %s (%s).\n", nr, port->name,
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 5f06696..cc9a9d0 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -18,7 +18,6 @@
#include <linux/raw.h>
#include <linux/tty.h>
#include <linux/capability.h>
-#include <linux/smp_lock.h>
#include <linux/ptrace.h>
#include <linux/device.h>
#include <linux/highmem.h>
@@ -552,7 +551,7 @@
return virtr + wrote;
}
-#if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__)
+#ifdef CONFIG_DEVPORT
static ssize_t read_port(struct file * file, char __user * buf,
size_t count, loff_t *ppos)
{
@@ -835,7 +834,7 @@
.splice_write = splice_write_null,
};
-#if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__)
+#ifdef CONFIG_DEVPORT
static const struct file_operations port_fops = {
.llseek = memory_lseek,
.read = read_port,
@@ -913,7 +912,7 @@
case 3:
filp->f_op = &null_fops;
break;
-#if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__)
+#ifdef CONFIG_DEVPORT
case 4:
filp->f_op = &port_fops;
break;
@@ -960,7 +959,7 @@
{1, "mem", S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops},
{2, "kmem", S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops},
{3, "null", S_IRUGO | S_IWUGO, &null_fops},
-#if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__)
+#ifdef CONFIG_DEVPORT
{4, "port", S_IRUSR | S_IWUSR | S_IRGRP, &port_fops},
#endif
{5, "zero", S_IRUGO | S_IWUGO, &zero_fops},
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index 7e975f6..4e6fb96 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -41,6 +41,7 @@
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/slab.h>
+#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/stat.h>
@@ -53,7 +54,7 @@
* Head entry for the doubly linked miscdevice list
*/
static LIST_HEAD(misc_list);
-static DECLARE_MUTEX(misc_sem);
+static DEFINE_MUTEX(misc_mtx);
/*
* Assigned numbers, used for dynamic minors
@@ -69,7 +70,7 @@
struct miscdevice *p;
loff_t off = 0;
- down(&misc_sem);
+ mutex_lock(&misc_mtx);
list_for_each_entry(p, &misc_list, list) {
if (*pos == off++)
return p;
@@ -89,7 +90,7 @@
static void misc_seq_stop(struct seq_file *seq, void *v)
{
- up(&misc_sem);
+ mutex_unlock(&misc_mtx);
}
static int misc_seq_show(struct seq_file *seq, void *v)
@@ -129,7 +130,7 @@
int err = -ENODEV;
const struct file_operations *old_fops, *new_fops = NULL;
- down(&misc_sem);
+ mutex_lock(&misc_mtx);
list_for_each_entry(c, &misc_list, list) {
if (c->minor == minor) {
@@ -139,9 +140,9 @@
}
if (!new_fops) {
- up(&misc_sem);
+ mutex_unlock(&misc_mtx);
request_module("char-major-%d-%d", MISC_MAJOR, minor);
- down(&misc_sem);
+ mutex_lock(&misc_mtx);
list_for_each_entry(c, &misc_list, list) {
if (c->minor == minor) {
@@ -165,7 +166,7 @@
}
fops_put(old_fops);
fail:
- up(&misc_sem);
+ mutex_unlock(&misc_mtx);
return err;
}
@@ -201,10 +202,10 @@
INIT_LIST_HEAD(&misc->list);
- down(&misc_sem);
+ mutex_lock(&misc_mtx);
list_for_each_entry(c, &misc_list, list) {
if (c->minor == misc->minor) {
- up(&misc_sem);
+ mutex_unlock(&misc_mtx);
return -EBUSY;
}
}
@@ -215,7 +216,7 @@
if ( (misc_minors[i>>3] & (1 << (i&7))) == 0)
break;
if (i<0) {
- up(&misc_sem);
+ mutex_unlock(&misc_mtx);
return -EBUSY;
}
misc->minor = i;
@@ -238,7 +239,7 @@
*/
list_add(&misc->list, &misc_list);
out:
- up(&misc_sem);
+ mutex_unlock(&misc_mtx);
return err;
}
@@ -259,13 +260,13 @@
if (list_empty(&misc->list))
return -EINVAL;
- down(&misc_sem);
+ mutex_lock(&misc_mtx);
list_del(&misc->list);
device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor));
if (i < DYNAMIC_MINORS && i>0) {
misc_minors[i>>3] &= ~(1 << (misc->minor & 7));
}
- up(&misc_sem);
+ mutex_unlock(&misc_mtx);
return 0;
}
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index 7dbaee8..e0d35c2 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -1582,7 +1582,7 @@
if(copy_from_user(&dltmp, argp, sizeof(struct dl_str)))
return -EFAULT;
- if(dltmp.cardno < 0 || dltmp.cardno >= MAX_BOARDS)
+ if(dltmp.cardno < 0 || dltmp.cardno >= MAX_BOARDS || dltmp.len < 0)
return -EINVAL;
switch(cmd)
@@ -2529,6 +2529,8 @@
void __iomem *baseAddr;
int i;
+ if(len < 0 || len > sizeof(moxaBuff))
+ return -EINVAL;
if(copy_from_user(moxaBuff, tmp, len))
return -EFAULT;
baseAddr = moxa_boards[cardno].basemem;
@@ -2576,7 +2578,7 @@
void __iomem *baseAddr;
int i;
- if(len > sizeof(moxaBuff))
+ if(len < 0 || len > sizeof(moxaBuff))
return -EINVAL;
if(copy_from_user(moxaBuff, tmp, len))
return -EFAULT;
@@ -2596,6 +2598,8 @@
void __iomem *baseAddr, *ofsAddr;
int retval, port, i;
+ if(len < 0 || len > sizeof(moxaBuff))
+ return -EINVAL;
if(copy_from_user(moxaBuff, tmp, len))
return -EFAULT;
baseAddr = moxa_boards[cardno].basemem;
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 80a0115..5953a45 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -54,7 +54,6 @@
#include <linux/gfp.h>
#include <linux/ioport.h>
#include <linux/mm.h>
-#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <linux/pci.h>
diff --git a/drivers/char/mxser_new.c b/drivers/char/mxser_new.c
index f7603b6..6cde448 100644
--- a/drivers/char/mxser_new.c
+++ b/drivers/char/mxser_new.c
@@ -37,7 +37,6 @@
#include <linux/gfp.h>
#include <linux/ioport.h>
#include <linux/mm.h>
-#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <linux/pci.h>
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c
index 65f2d3a..14557a4 100644
--- a/drivers/char/n_r3964.c
+++ b/drivers/char/n_r3964.c
@@ -1088,13 +1088,13 @@
/* block until there is a message: */
add_wait_queue(&pInfo->read_wait, &wait);
repeat:
- current->state = TASK_INTERRUPTIBLE;
+ __set_current_state(TASK_INTERRUPTIBLE);
pMsg = remove_msg(pInfo, pClient);
if (!pMsg && !signal_pending(current)) {
schedule();
goto repeat;
}
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(&pInfo->read_wait, &wait);
}
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
index 4abd1ef..84ac64f 100644
--- a/drivers/char/ppdev.c
+++ b/drivers/char/ppdev.c
@@ -66,7 +66,6 @@
#include <linux/poll.h>
#include <linux/major.h>
#include <linux/ppdev.h>
-#include <linux/smp_lock.h>
#include <linux/device.h>
#include <asm/uaccess.h>
@@ -752,7 +751,7 @@
static void pp_attach(struct parport *port)
{
- device_create(ppdev_class, NULL, MKDEV(PP_MAJOR, port->number),
+ device_create(ppdev_class, port->dev, MKDEV(PP_MAJOR, port->number),
"parport%d", port->number);
}
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c
index 7014525..3494e3f 100644
--- a/drivers/char/riscom8.c
+++ b/drivers/char/riscom8.c
@@ -980,7 +980,7 @@
}
schedule();
}
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(&port->open_wait, &wait);
if (!tty_hung_up_p(filp))
port->count++;
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index 76357c8..61a63da 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -65,10 +65,6 @@
/****** Kernel includes ******/
-#ifdef MODVERSIONS
-#include <config/modversions.h>
-#endif
-
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/major.h>
@@ -85,6 +81,7 @@
#include <linux/string.h>
#include <linux/fcntl.h>
#include <linux/ptrace.h>
+#include <linux/mutex.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/wait.h>
@@ -93,7 +90,6 @@
#include <asm/atomic.h>
#include <linux/bitops.h>
#include <linux/spinlock.h>
-#include <asm/semaphore.h>
#include <linux/init.h>
/****** RocketPort includes ******/
@@ -702,7 +698,7 @@
}
}
spin_lock_init(&info->slock);
- sema_init(&info->write_sem, 1);
+ mutex_init(&info->write_mtx);
rp_table[line] = info;
if (pci_dev)
tty_register_device(rocket_driver, line, &pci_dev->dev);
@@ -947,7 +943,7 @@
#endif
schedule(); /* Don't hold spinlock here, will hang PC */
}
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(&info->open_wait, &wait);
spin_lock_irqsave(&info->slock, flags);
@@ -1602,7 +1598,7 @@
if (signal_pending(current))
break;
}
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
#ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
printk(KERN_INFO "txcnt = %d (jiff=%lu)...done\n", txcnt, jiffies);
#endif
@@ -1661,8 +1657,11 @@
if (rocket_paranoia_check(info, "rp_put_char"))
return;
- /* Grab the port write semaphore, locking out other processes that try to write to this port */
- down(&info->write_sem);
+ /*
+ * Grab the port write mutex, locking out other processes that try to
+ * write to this port
+ */
+ mutex_lock(&info->write_mtx);
#ifdef ROCKET_DEBUG_WRITE
printk(KERN_INFO "rp_put_char %c...", ch);
@@ -1684,12 +1683,12 @@
info->xmit_fifo_room--;
}
spin_unlock_irqrestore(&info->slock, flags);
- up(&info->write_sem);
+ mutex_unlock(&info->write_mtx);
}
/*
* Exception handler - write routine, called when user app writes to the device.
- * A per port write semaphore is used to protect from another process writing to
+ * A per port write mutex is used to protect from another process writing to
* this port at the same time. This other process could be running on the other CPU
* or get control of the CPU if the copy_from_user() blocks due to a page fault (swapped out).
* Spinlocks protect the info xmit members.
@@ -1706,7 +1705,7 @@
if (count <= 0 || rocket_paranoia_check(info, "rp_write"))
return 0;
- down_interruptible(&info->write_sem);
+ mutex_lock_interruptible(&info->write_mtx);
#ifdef ROCKET_DEBUG_WRITE
printk(KERN_INFO "rp_write %d chars...", count);
@@ -1777,7 +1776,7 @@
wake_up_interruptible(&tty->poll_wait);
#endif
}
- up(&info->write_sem);
+ mutex_unlock(&info->write_mtx);
return retval;
}
@@ -1852,6 +1851,12 @@
#ifdef CONFIG_PCI
+static struct pci_device_id __devinitdata rocket_pci_ids[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_ANY_ID) },
+ { }
+};
+MODULE_DEVICE_TABLE(pci, rocket_pci_ids);
+
/*
* Called when a PCI card is found. Retrieves and stores model information,
* init's aiopic and serial port hardware.
diff --git a/drivers/char/rocket_int.h b/drivers/char/rocket_int.h
index 3a8bcc8..89b4d7b 100644
--- a/drivers/char/rocket_int.h
+++ b/drivers/char/rocket_int.h
@@ -15,6 +15,8 @@
#define ROCKET_TYPE_MODEMIII 3
#define ROCKET_TYPE_PC104 4
+#include <linux/mutex.h>
+
#include <asm/io.h>
#include <asm/byteorder.h>
@@ -1171,7 +1173,7 @@
struct wait_queue *close_wait;
#endif
spinlock_t slock;
- struct semaphore write_sem;
+ struct mutex write_mtx;
};
#define RPORT_MAGIC 0x525001
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index c7dac9b..20380a2 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -388,7 +388,7 @@
if (!retval)
retval = count;
out:
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(&rtc_wait, &wait);
return retval;
diff --git a/drivers/char/selection.c b/drivers/char/selection.c
index 74cff83..a69f094 100644
--- a/drivers/char/selection.c
+++ b/drivers/char/selection.c
@@ -299,7 +299,7 @@
pasted += count;
}
remove_wait_queue(&vc->paste_wait, &wait);
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
tty_ldisc_deref(ld);
return 0;
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c
index 5fd314a..c585b47 100644
--- a/drivers/char/serial167.c
+++ b/drivers/char/serial167.c
@@ -1892,7 +1892,7 @@
#endif
schedule();
}
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(&info->open_wait, &wait);
if (!tty_hung_up_p(filp)) {
info->count++;
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index ce4db6f..f02a079 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -4010,8 +4010,13 @@
for ( i=0; i<info->num_tx_holding_buffers; ++i) {
info->tx_holding_buffers[i].buffer =
kmalloc(info->max_frame_size, GFP_KERNEL);
- if ( info->tx_holding_buffers[i].buffer == NULL )
+ if (info->tx_holding_buffers[i].buffer == NULL) {
+ for (--i; i >= 0; i--) {
+ kfree(info->tx_holding_buffers[i].buffer);
+ info->tx_holding_buffers[i].buffer = NULL;
+ }
return -ENOMEM;
+ }
}
return 0;
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 0a367cd..2a7736b 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -3415,6 +3415,9 @@
}
}
}
+
+ for (i=0; i < port_count; ++i)
+ tty_register_device(serial_driver, port_array[i]->line, &(port_array[i]->pdev->dev));
}
static int __devinit init_one(struct pci_dev *dev,
@@ -3466,6 +3469,8 @@
printk("unload %s %s\n", driver_name, driver_version);
if (serial_driver) {
+ for (info=slgt_device_list ; info != NULL ; info=info->next_device)
+ tty_unregister_device(serial_driver, info->line);
if ((rc = tty_unregister_driver(serial_driver)))
DBGERR(("tty_unregister_driver error=%d\n", rc));
put_tty_driver(serial_driver);
@@ -3506,23 +3511,10 @@
printk("%s %s\n", driver_name, driver_version);
- slgt_device_count = 0;
- if ((rc = pci_register_driver(&pci_driver)) < 0) {
- printk("%s pci_register_driver error=%d\n", driver_name, rc);
- return rc;
- }
- pci_registered = 1;
-
- if (!slgt_device_list) {
- printk("%s no devices found\n",driver_name);
- pci_unregister_driver(&pci_driver);
- return -ENODEV;
- }
-
serial_driver = alloc_tty_driver(MAX_DEVICES);
if (!serial_driver) {
- rc = -ENOMEM;
- goto error;
+ printk("%s can't allocate tty driver\n", driver_name);
+ return -ENOMEM;
}
/* Initialize the tty_driver structure */
@@ -3539,7 +3531,7 @@
B9600 | CS8 | CREAD | HUPCL | CLOCAL;
serial_driver->init_termios.c_ispeed = 9600;
serial_driver->init_termios.c_ospeed = 9600;
- serial_driver->flags = TTY_DRIVER_REAL_RAW;
+ serial_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
tty_set_operations(serial_driver, &ops);
if ((rc = tty_register_driver(serial_driver)) < 0) {
DBGERR(("%s can't register serial driver\n", driver_name));
@@ -3552,6 +3544,16 @@
driver_name, driver_version,
serial_driver->major);
+ slgt_device_count = 0;
+ if ((rc = pci_register_driver(&pci_driver)) < 0) {
+ printk("%s pci_register_driver error=%d\n", driver_name, rc);
+ goto error;
+ }
+ pci_registered = 1;
+
+ if (!slgt_device_list)
+ printk("%s no devices found\n",driver_name);
+
return 0;
error:
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index 1d8c4ae6..39cc318 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -24,7 +24,6 @@
#include <linux/sysrq.h>
#include <linux/kbd_kern.h>
#include <linux/quotaops.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/suspend.h>
diff --git a/drivers/char/tipar.c b/drivers/char/tipar.c
index 47fb20f..35b40b9 100644
--- a/drivers/char/tipar.c
+++ b/drivers/char/tipar.c
@@ -442,7 +442,7 @@
}
class_device_create(tipar_class, NULL, MKDEV(TIPAR_MAJOR,
- TIPAR_MINOR + nr), NULL, "par%d", nr);
+ TIPAR_MINOR + nr), port->dev, "par%d", nr);
/* Display informations */
pr_info("tipar%d: using %s (%s)\n", nr, port->name, (port->irq ==
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index e5a254a..9bb5429 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -24,7 +24,9 @@
*/
#include <linux/poll.h>
+#include <linux/mutex.h>
#include <linux/spinlock.h>
+
#include "tpm.h"
enum tpm_const {
@@ -328,10 +330,10 @@
{
struct tpm_chip *chip = container_of(work, struct tpm_chip, work);
- down(&chip->buffer_mutex);
+ mutex_lock(&chip->buffer_mutex);
atomic_set(&chip->data_pending, 0);
memset(chip->data_buffer, 0, TPM_BUFSIZE);
- up(&chip->buffer_mutex);
+ mutex_unlock(&chip->buffer_mutex);
}
/*
@@ -380,7 +382,7 @@
return -E2BIG;
}
- down(&chip->tpm_mutex);
+ mutex_lock(&chip->tpm_mutex);
if ((rc = chip->vendor.send(chip, (u8 *) buf, count)) < 0) {
dev_err(chip->dev,
@@ -419,7 +421,7 @@
dev_err(chip->dev,
"tpm_transmit: tpm_recv: error %zd\n", rc);
out:
- up(&chip->tpm_mutex);
+ mutex_unlock(&chip->tpm_mutex);
return rc;
}
@@ -942,12 +944,12 @@
{
struct tpm_chip *chip = file->private_data;
+ flush_scheduled_work();
spin_lock(&driver_lock);
file->private_data = NULL;
- chip->num_opens--;
del_singleshot_timer_sync(&chip->user_read_timer);
- flush_scheduled_work();
atomic_set(&chip->data_pending, 0);
+ chip->num_opens--;
put_device(chip->dev);
kfree(chip->data_buffer);
spin_unlock(&driver_lock);
@@ -966,14 +968,14 @@
while (atomic_read(&chip->data_pending) != 0)
msleep(TPM_TIMEOUT);
- down(&chip->buffer_mutex);
+ mutex_lock(&chip->buffer_mutex);
if (in_size > TPM_BUFSIZE)
in_size = TPM_BUFSIZE;
if (copy_from_user
(chip->data_buffer, (void __user *) buf, in_size)) {
- up(&chip->buffer_mutex);
+ mutex_unlock(&chip->buffer_mutex);
return -EFAULT;
}
@@ -981,7 +983,7 @@
out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE);
atomic_set(&chip->data_pending, out_size);
- up(&chip->buffer_mutex);
+ mutex_unlock(&chip->buffer_mutex);
/* Set a timeout by which the reader must come claim the result */
mod_timer(&chip->user_read_timer, jiffies + (60 * HZ));
@@ -1004,10 +1006,10 @@
if (size < ret_size)
ret_size = size;
- down(&chip->buffer_mutex);
+ mutex_lock(&chip->buffer_mutex);
if (copy_to_user(buf, chip->data_buffer, ret_size))
ret_size = -EFAULT;
- up(&chip->buffer_mutex);
+ mutex_unlock(&chip->buffer_mutex);
}
return ret_size;
@@ -1097,11 +1099,16 @@
/* Driver specific per-device data */
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL)
- return NULL;
+ devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL);
- init_MUTEX(&chip->buffer_mutex);
- init_MUTEX(&chip->tpm_mutex);
+ if (chip == NULL || devname == NULL) {
+ kfree(chip);
+ kfree(devname);
+ return NULL;
+ }
+
+ mutex_init(&chip->buffer_mutex);
+ mutex_init(&chip->tpm_mutex);
INIT_LIST_HEAD(&chip->list);
INIT_WORK(&chip->work, timeout_work);
@@ -1124,7 +1131,6 @@
set_bit(chip->dev_num, dev_mask);
- devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL);
scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num);
chip->vendor.miscdev.name = devname;
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 9f273f0..b2e2b00 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -21,6 +21,7 @@
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/fs.h>
+#include <linux/mutex.h>
#include <linux/sched.h>
#include <linux/miscdevice.h>
#include <linux/platform_device.h>
@@ -94,11 +95,11 @@
/* Data passed to and from the tpm via the read/write calls */
u8 *data_buffer;
atomic_t data_pending;
- struct semaphore buffer_mutex;
+ struct mutex buffer_mutex;
struct timer_list user_read_timer; /* user needs to claim result */
struct work_struct work;
- struct semaphore tpm_mutex; /* tpm is processing */
+ struct mutex tpm_mutex; /* tpm is processing */
struct tpm_vendor_specific vendor;
diff --git a/drivers/char/tpm/tpm_atmel.h b/drivers/char/tpm/tpm_atmel.h
index 3c85200..c912d86 100644
--- a/drivers/char/tpm/tpm_atmel.h
+++ b/drivers/char/tpm/tpm_atmel.h
@@ -47,12 +47,12 @@
if (!dn)
return NULL;
- if (!device_is_compatible(dn, "AT97SC3201")) {
+ if (!of_device_is_compatible(dn, "AT97SC3201")) {
of_node_put(dn);
return NULL;
}
- reg = get_property(dn, "reg", ®len);
+ reg = of_get_property(dn, "reg", ®len);
naddrc = of_n_addr_cells(dn);
nsizec = of_n_size_cells(dn);
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c
index 1353b5a..967002a 100644
--- a/drivers/char/tpm/tpm_infineon.c
+++ b/drivers/char/tpm/tpm_infineon.c
@@ -30,12 +30,60 @@
#define TPM_MAX_TRIES 5000
#define TPM_INFINEON_DEV_VEN_VALUE 0x15D1
-/* These values will be filled after PnP-call */
-static int TPM_INF_DATA;
-static int TPM_INF_ADDR;
-static int TPM_INF_BASE;
-static int TPM_INF_ADDR_LEN;
-static int TPM_INF_PORT_LEN;
+#define TPM_INF_IO_PORT 0x0
+#define TPM_INF_IO_MEM 0x1
+
+#define TPM_INF_ADDR 0x0
+#define TPM_INF_DATA 0x1
+
+struct tpm_inf_dev {
+ int iotype;
+
+ void __iomem *mem_base; /* MMIO ioremap'd addr */
+ unsigned long map_base; /* phys MMIO base */
+ unsigned long map_size; /* MMIO region size */
+ unsigned int index_off; /* index register offset */
+
+ unsigned int data_regs; /* Data registers */
+ unsigned int data_size;
+
+ unsigned int config_port; /* IO Port config index reg */
+ unsigned int config_size;
+};
+
+static struct tpm_inf_dev tpm_dev;
+
+static inline void tpm_data_out(unsigned char data, unsigned char offset)
+{
+ if (tpm_dev.iotype == TPM_INF_IO_PORT)
+ outb(data, tpm_dev.data_regs + offset);
+ else
+ writeb(data, tpm_dev.mem_base + tpm_dev.data_regs + offset);
+}
+
+static inline unsigned char tpm_data_in(unsigned char offset)
+{
+ if (tpm_dev.iotype == TPM_INF_IO_PORT)
+ return inb(tpm_dev.data_regs + offset);
+ else
+ return readb(tpm_dev.mem_base + tpm_dev.data_regs + offset);
+}
+
+static inline void tpm_config_out(unsigned char data, unsigned char offset)
+{
+ if (tpm_dev.iotype == TPM_INF_IO_PORT)
+ outb(data, tpm_dev.config_port + offset);
+ else
+ writeb(data, tpm_dev.mem_base + tpm_dev.index_off + offset);
+}
+
+static inline unsigned char tpm_config_in(unsigned char offset)
+{
+ if (tpm_dev.iotype == TPM_INF_IO_PORT)
+ return inb(tpm_dev.config_port + offset);
+ else
+ return readb(tpm_dev.mem_base + tpm_dev.index_off + offset);
+}
/* TPM header definitions */
enum infineon_tpm_header {
@@ -105,7 +153,7 @@
if (clear_wrfifo) {
for (i = 0; i < 4096; i++) {
- status = inb(chip->vendor.base + WRFIFO);
+ status = tpm_data_in(WRFIFO);
if (status == 0xff) {
if (check == 5)
break;
@@ -125,8 +173,8 @@
*/
i = 0;
do {
- status = inb(chip->vendor.base + RDFIFO);
- status = inb(chip->vendor.base + STAT);
+ status = tpm_data_in(RDFIFO);
+ status = tpm_data_in(STAT);
i++;
if (i == TPM_MAX_TRIES)
return -EIO;
@@ -139,7 +187,7 @@
int status;
int i;
for (i = 0; i < TPM_MAX_TRIES; i++) {
- status = inb(chip->vendor.base + STAT);
+ status = tpm_data_in(STAT);
/* check the status-register if wait_for_bit is set */
if (status & 1 << wait_for_bit)
break;
@@ -158,7 +206,7 @@
static void wait_and_send(struct tpm_chip *chip, u8 sendbyte)
{
wait(chip, STAT_XFE);
- outb(sendbyte, chip->vendor.base + WRFIFO);
+ tpm_data_out(sendbyte, WRFIFO);
}
/* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more
@@ -205,7 +253,7 @@
ret = wait(chip, STAT_RDA);
if (ret)
return -EIO;
- buf[i] = inb(chip->vendor.base + RDFIFO);
+ buf[i] = tpm_data_in(RDFIFO);
}
if (buf[0] != TPM_VL_VER) {
@@ -220,7 +268,7 @@
for (i = 0; i < size; i++) {
wait(chip, STAT_RDA);
- buf[i] = inb(chip->vendor.base + RDFIFO);
+ buf[i] = tpm_data_in(RDFIFO);
}
if ((size == 0x6D00) && (buf[1] == 0x80)) {
@@ -269,7 +317,7 @@
u8 count_high, count_low, count_4, count_3, count_2, count_1;
/* Disabling Reset, LP and IRQC */
- outb(RESET_LP_IRQC_DISABLE, chip->vendor.base + CMD);
+ tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
ret = empty_fifo(chip, 1);
if (ret) {
@@ -320,7 +368,7 @@
static u8 tpm_inf_status(struct tpm_chip *chip)
{
- return inb(chip->vendor.base + STAT);
+ return tpm_data_in(STAT);
}
static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
@@ -381,51 +429,88 @@
/* read IO-ports through PnP */
if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
!(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) {
- TPM_INF_ADDR = pnp_port_start(dev, 0);
- TPM_INF_ADDR_LEN = pnp_port_len(dev, 0);
- TPM_INF_DATA = (TPM_INF_ADDR + 1);
- TPM_INF_BASE = pnp_port_start(dev, 1);
- TPM_INF_PORT_LEN = pnp_port_len(dev, 1);
- if ((TPM_INF_PORT_LEN < 4) || (TPM_INF_ADDR_LEN < 2)) {
+
+ tpm_dev.iotype = TPM_INF_IO_PORT;
+
+ tpm_dev.config_port = pnp_port_start(dev, 0);
+ tpm_dev.config_size = pnp_port_len(dev, 0);
+ tpm_dev.data_regs = pnp_port_start(dev, 1);
+ tpm_dev.data_size = pnp_port_len(dev, 1);
+ if ((tpm_dev.data_size < 4) || (tpm_dev.config_size < 2)) {
rc = -EINVAL;
goto err_last;
}
dev_info(&dev->dev, "Found %s with ID %s\n",
dev->name, dev_id->id);
- if (!((TPM_INF_BASE >> 8) & 0xff)) {
+ if (!((tpm_dev.data_regs >> 8) & 0xff)) {
rc = -EINVAL;
goto err_last;
}
/* publish my base address and request region */
- if (request_region
- (TPM_INF_BASE, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) {
+ if (request_region(tpm_dev.data_regs, tpm_dev.data_size,
+ "tpm_infineon0") == NULL) {
rc = -EINVAL;
goto err_last;
}
- if (request_region
- (TPM_INF_ADDR, TPM_INF_ADDR_LEN, "tpm_infineon0") == NULL) {
+ if (request_region(tpm_dev.config_port, tpm_dev.config_size,
+ "tpm_infineon0") == NULL) {
+ release_region(tpm_dev.data_regs, tpm_dev.data_size);
rc = -EINVAL;
goto err_last;
}
+ } else if (pnp_mem_valid(dev, 0) &&
+ !(pnp_mem_flags(dev, 0) & IORESOURCE_DISABLED)) {
+
+ tpm_dev.iotype = TPM_INF_IO_MEM;
+
+ tpm_dev.map_base = pnp_mem_start(dev, 0);
+ tpm_dev.map_size = pnp_mem_len(dev, 0);
+
+ dev_info(&dev->dev, "Found %s with ID %s\n",
+ dev->name, dev_id->id);
+
+ /* publish my base address and request region */
+ if (request_mem_region(tpm_dev.map_base, tpm_dev.map_size,
+ "tpm_infineon0") == NULL) {
+ rc = -EINVAL;
+ goto err_last;
+ }
+
+ tpm_dev.mem_base = ioremap(tpm_dev.map_base, tpm_dev.map_size);
+ if (tpm_dev.mem_base == NULL) {
+ release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
+ rc = -EINVAL;
+ goto err_last;
+ }
+
+ /*
+ * The only known MMIO based Infineon TPM system provides
+ * a single large mem region with the device config
+ * registers at the default TPM_ADDR. The data registers
+ * seem like they could be placed anywhere within the MMIO
+ * region, but lets just put them at zero offset.
+ */
+ tpm_dev.index_off = TPM_ADDR;
+ tpm_dev.data_regs = 0x0;
} else {
rc = -EINVAL;
goto err_last;
}
/* query chip for its vendor, its version number a.s.o. */
- outb(ENABLE_REGISTER_PAIR, TPM_INF_ADDR);
- outb(IDVENL, TPM_INF_ADDR);
- vendorid[1] = inb(TPM_INF_DATA);
- outb(IDVENH, TPM_INF_ADDR);
- vendorid[0] = inb(TPM_INF_DATA);
- outb(IDPDL, TPM_INF_ADDR);
- productid[1] = inb(TPM_INF_DATA);
- outb(IDPDH, TPM_INF_ADDR);
- productid[0] = inb(TPM_INF_DATA);
- outb(CHIP_ID1, TPM_INF_ADDR);
- version[1] = inb(TPM_INF_DATA);
- outb(CHIP_ID2, TPM_INF_ADDR);
- version[0] = inb(TPM_INF_DATA);
+ tpm_config_out(ENABLE_REGISTER_PAIR, TPM_INF_ADDR);
+ tpm_config_out(IDVENL, TPM_INF_ADDR);
+ vendorid[1] = tpm_config_in(TPM_INF_DATA);
+ tpm_config_out(IDVENH, TPM_INF_ADDR);
+ vendorid[0] = tpm_config_in(TPM_INF_DATA);
+ tpm_config_out(IDPDL, TPM_INF_ADDR);
+ productid[1] = tpm_config_in(TPM_INF_DATA);
+ tpm_config_out(IDPDH, TPM_INF_ADDR);
+ productid[0] = tpm_config_in(TPM_INF_DATA);
+ tpm_config_out(CHIP_ID1, TPM_INF_ADDR);
+ version[1] = tpm_config_in(TPM_INF_DATA);
+ tpm_config_out(CHIP_ID2, TPM_INF_ADDR);
+ version[0] = tpm_config_in(TPM_INF_DATA);
switch ((productid[0] << 8) | productid[1]) {
case 6:
@@ -442,51 +527,54 @@
if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) {
/* configure TPM with IO-ports */
- outb(IOLIMH, TPM_INF_ADDR);
- outb(((TPM_INF_BASE >> 8) & 0xff), TPM_INF_DATA);
- outb(IOLIML, TPM_INF_ADDR);
- outb((TPM_INF_BASE & 0xff), TPM_INF_DATA);
+ tpm_config_out(IOLIMH, TPM_INF_ADDR);
+ tpm_config_out((tpm_dev.data_regs >> 8) & 0xff, TPM_INF_DATA);
+ tpm_config_out(IOLIML, TPM_INF_ADDR);
+ tpm_config_out((tpm_dev.data_regs & 0xff), TPM_INF_DATA);
/* control if IO-ports are set correctly */
- outb(IOLIMH, TPM_INF_ADDR);
- ioh = inb(TPM_INF_DATA);
- outb(IOLIML, TPM_INF_ADDR);
- iol = inb(TPM_INF_DATA);
+ tpm_config_out(IOLIMH, TPM_INF_ADDR);
+ ioh = tpm_config_in(TPM_INF_DATA);
+ tpm_config_out(IOLIML, TPM_INF_ADDR);
+ iol = tpm_config_in(TPM_INF_DATA);
- if ((ioh << 8 | iol) != TPM_INF_BASE) {
+ if ((ioh << 8 | iol) != tpm_dev.data_regs) {
dev_err(&dev->dev,
- "Could not set IO-ports to 0x%x\n",
- TPM_INF_BASE);
+ "Could not set IO-data registers to 0x%x\n",
+ tpm_dev.data_regs);
rc = -EIO;
goto err_release_region;
}
/* activate register */
- outb(TPM_DAR, TPM_INF_ADDR);
- outb(0x01, TPM_INF_DATA);
- outb(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
+ tpm_config_out(TPM_DAR, TPM_INF_ADDR);
+ tpm_config_out(0x01, TPM_INF_DATA);
+ tpm_config_out(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
/* disable RESET, LP and IRQC */
- outb(RESET_LP_IRQC_DISABLE, TPM_INF_BASE + CMD);
+ tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
/* Finally, we're done, print some infos */
dev_info(&dev->dev, "TPM found: "
- "config base 0x%x, "
- "io base 0x%x, "
+ "config base 0x%lx, "
+ "data base 0x%lx, "
"chip version 0x%02x%02x, "
"vendor id 0x%x%x (Infineon), "
"product id 0x%02x%02x"
"%s\n",
- TPM_INF_ADDR,
- TPM_INF_BASE,
+ tpm_dev.iotype == TPM_INF_IO_PORT ?
+ tpm_dev.config_port :
+ tpm_dev.map_base + tpm_dev.index_off,
+ tpm_dev.iotype == TPM_INF_IO_PORT ?
+ tpm_dev.data_regs :
+ tpm_dev.map_base + tpm_dev.data_regs,
version[0], version[1],
vendorid[0], vendorid[1],
productid[0], productid[1], chipname);
- if (!(chip = tpm_register_hardware(&dev->dev, &tpm_inf))) {
+ if (!(chip = tpm_register_hardware(&dev->dev, &tpm_inf)))
goto err_release_region;
- }
- chip->vendor.base = TPM_INF_BASE;
+
return 0;
} else {
rc = -ENODEV;
@@ -494,8 +582,13 @@
}
err_release_region:
- release_region(TPM_INF_BASE, TPM_INF_PORT_LEN);
- release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN);
+ if (tpm_dev.iotype == TPM_INF_IO_PORT) {
+ release_region(tpm_dev.data_regs, tpm_dev.data_size);
+ release_region(tpm_dev.config_port, tpm_dev.config_size);
+ } else {
+ iounmap(tpm_dev.mem_base);
+ release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
+ }
err_last:
return rc;
@@ -506,8 +599,14 @@
struct tpm_chip *chip = pnp_get_drvdata(dev);
if (chip) {
- release_region(TPM_INF_BASE, TPM_INF_PORT_LEN);
- release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN);
+ if (tpm_dev.iotype == TPM_INF_IO_PORT) {
+ release_region(tpm_dev.data_regs, tpm_dev.data_size);
+ release_region(tpm_dev.config_port,
+ tpm_dev.config_size);
+ } else {
+ iounmap(tpm_dev.mem_base);
+ release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
+ }
tpm_remove_hardware(chip->dev);
}
}
@@ -539,5 +638,5 @@
MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>");
MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
-MODULE_VERSION("1.8");
+MODULE_VERSION("1.9");
MODULE_LICENSE("GPL");
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 389da36..7710a6a 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -141,8 +141,6 @@
static int ptmx_open(struct inode *, struct file *);
#endif
-extern void disable_early_printk(void);
-
static void initialize_tty_struct(struct tty_struct *tty);
static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *);
@@ -155,8 +153,8 @@
unsigned int cmd, unsigned long arg);
static int tty_fasync(int fd, struct file * filp, int on);
static void release_tty(struct tty_struct *tty, int idx);
-static struct pid *__proc_set_tty(struct task_struct *tsk,
- struct tty_struct *tty);
+static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty);
+static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty);
/**
* alloc_tty_struct - allocate a tty object
@@ -1534,10 +1532,9 @@
}
spin_lock_irq(¤t->sighand->siglock);
- tty_pgrp = current->signal->tty_old_pgrp;
+ put_pid(current->signal->tty_old_pgrp);
current->signal->tty_old_pgrp = NULL;
spin_unlock_irq(¤t->sighand->siglock);
- put_pid(tty_pgrp);
mutex_lock(&tty_mutex);
/* It is possible that do_tty_hangup has free'd this tty */
@@ -1562,6 +1559,18 @@
unlock_kernel();
}
+/**
+ *
+ * no_tty - Ensure the current process does not have a controlling tty
+ */
+void no_tty(void)
+{
+ struct task_struct *tsk = current;
+ if (tsk->signal->leader)
+ disassociate_ctty(0);
+ proc_clear_tty(tsk);
+}
+
/**
* stop_tty - propogate flow control
@@ -2508,7 +2517,6 @@
int index;
dev_t device = inode->i_rdev;
unsigned short saved_flags = filp->f_flags;
- struct pid *old_pgrp;
nonseekable_open(inode, filp);
@@ -2602,17 +2610,15 @@
goto retry_open;
}
- old_pgrp = NULL;
mutex_lock(&tty_mutex);
spin_lock_irq(¤t->sighand->siglock);
if (!noctty &&
current->signal->leader &&
!current->signal->tty &&
tty->session == NULL)
- old_pgrp = __proc_set_tty(current, tty);
+ __proc_set_tty(current, tty);
spin_unlock_irq(¤t->sighand->siglock);
mutex_unlock(&tty_mutex);
- put_pid(old_pgrp);
return 0;
}
@@ -3287,9 +3293,7 @@
case TIOCNOTTY:
if (current->signal->tty != tty)
return -ENOTTY;
- if (current->signal->leader)
- disassociate_ctty(0);
- proc_clear_tty(current);
+ no_tty();
return 0;
case TIOCSCTTY:
return tiocsctty(tty, arg);
@@ -3766,7 +3770,9 @@
if (!driver->put_char)
driver->put_char = tty_default_put_char;
+ mutex_lock(&tty_mutex);
list_add(&driver->tty_drivers, &tty_drivers);
+ mutex_unlock(&tty_mutex);
if ( !(driver->flags & TTY_DRIVER_DYNAMIC_DEV) ) {
for(i = 0; i < driver->num; i++)
@@ -3792,8 +3798,9 @@
unregister_chrdev_region(MKDEV(driver->major, driver->minor_start),
driver->num);
-
+ mutex_lock(&tty_mutex);
list_del(&driver->tty_drivers);
+ mutex_unlock(&tty_mutex);
/*
* Free the termios and termios_locked structures because
@@ -3836,11 +3843,9 @@
p->signal->tty = NULL;
spin_unlock_irq(&p->sighand->siglock);
}
-EXPORT_SYMBOL(proc_clear_tty);
-static struct pid *__proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
+static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
{
- struct pid *old_pgrp;
if (tty) {
/* We should not have a session or pgrp to here but.... */
put_pid(tty->session);
@@ -3848,21 +3853,16 @@
tty->session = get_pid(task_session(tsk));
tty->pgrp = get_pid(task_pgrp(tsk));
}
- old_pgrp = tsk->signal->tty_old_pgrp;
+ put_pid(tsk->signal->tty_old_pgrp);
tsk->signal->tty = tty;
tsk->signal->tty_old_pgrp = NULL;
- return old_pgrp;
}
-void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
+static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
{
- struct pid *old_pgrp;
-
spin_lock_irq(&tsk->sighand->siglock);
- old_pgrp = __proc_set_tty(tsk, tty);
+ __proc_set_tty(tsk, tty);
spin_unlock_irq(&tsk->sighand->siglock);
-
- put_pid(old_pgrp);
}
struct tty_struct *get_current_tty(void)
@@ -3897,9 +3897,6 @@
* set up the console device so that later boot sequences can
* inform about problems etc..
*/
-#ifdef CONFIG_EARLY_PRINTK
- disable_early_printk();
-#endif
call = __con_initcall_start;
while (call < __con_initcall_end) {
(*call)();
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c
index 7919303..83aeedd 100644
--- a/drivers/char/vc_screen.c
+++ b/drivers/char/vc_screen.c
@@ -28,12 +28,13 @@
#include <linux/interrupt.h>
#include <linux/mm.h>
#include <linux/init.h>
+#include <linux/mutex.h>
#include <linux/vt_kern.h>
#include <linux/selection.h>
#include <linux/kbd_kern.h>
#include <linux/console.h>
-#include <linux/smp_lock.h>
#include <linux/device.h>
+
#include <asm/uaccess.h>
#include <asm/byteorder.h>
#include <asm/unaligned.h>
@@ -70,11 +71,11 @@
{
int size;
- down(&con_buf_sem);
+ mutex_lock(&con_buf_mtx);
size = vcs_size(file->f_path.dentry->d_inode);
switch (orig) {
default:
- up(&con_buf_sem);
+ mutex_unlock(&con_buf_mtx);
return -EINVAL;
case 2:
offset += size;
@@ -85,11 +86,11 @@
break;
}
if (offset < 0 || offset > size) {
- up(&con_buf_sem);
+ mutex_unlock(&con_buf_mtx);
return -EINVAL;
}
file->f_pos = offset;
- up(&con_buf_sem);
+ mutex_unlock(&con_buf_mtx);
return file->f_pos;
}
@@ -106,7 +107,7 @@
unsigned short *org = NULL;
ssize_t ret;
- down(&con_buf_sem);
+ mutex_lock(&con_buf_mtx);
pos = *ppos;
@@ -263,7 +264,7 @@
ret = read;
unlock_out:
release_console_sem();
- up(&con_buf_sem);
+ mutex_unlock(&con_buf_mtx);
return ret;
}
@@ -280,7 +281,7 @@
u16 *org0 = NULL, *org = NULL;
size_t ret;
- down(&con_buf_sem);
+ mutex_lock(&con_buf_mtx);
pos = *ppos;
@@ -450,7 +451,7 @@
unlock_out:
release_console_sem();
- up(&con_buf_sem);
+ mutex_unlock(&con_buf_mtx);
return ret;
}
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 1bbb45b..bbd9fc4 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -86,6 +86,7 @@
#include <linux/mm.h>
#include <linux/console.h>
#include <linux/init.h>
+#include <linux/mutex.h>
#include <linux/vt_kern.h>
#include <linux/selection.h>
#include <linux/tiocl.h>
@@ -157,6 +158,8 @@
static void set_palette(struct vc_data *vc);
static int printable; /* Is console ready for printing? */
+static int default_utf8;
+module_param(default_utf8, int, S_IRUGO | S_IWUSR);
/*
* ignore_poke: don't unblank the screen when things are typed. This is
@@ -348,10 +351,12 @@
/* Structure of attributes is hardware-dependent */
-static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink, u8 _underline, u8 _reverse)
+static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink,
+ u8 _underline, u8 _reverse, u8 _italic)
{
if (vc->vc_sw->con_build_attr)
- return vc->vc_sw->con_build_attr(vc, _color, _intensity, _blink, _underline, _reverse);
+ return vc->vc_sw->con_build_attr(vc, _color, _intensity,
+ _blink, _underline, _reverse, _italic);
#ifndef VT_BUF_VRAM_ONLY
/*
@@ -368,10 +373,13 @@
u8 a = vc->vc_color;
if (!vc->vc_can_do_color)
return _intensity |
+ (_italic ? 2 : 0) |
(_underline ? 4 : 0) |
(_reverse ? 8 : 0) |
(_blink ? 0x80 : 0);
- if (_underline)
+ if (_italic)
+ a = (a & 0xF0) | vc->vc_itcolor;
+ else if (_underline)
a = (a & 0xf0) | vc->vc_ulcolor;
else if (_intensity == 0)
a = (a & 0xf0) | vc->vc_ulcolor;
@@ -392,8 +400,10 @@
static void update_attr(struct vc_data *vc)
{
- vc->vc_attr = build_attr(vc, vc->vc_color, vc->vc_intensity, vc->vc_blink, vc->vc_underline, vc->vc_reverse ^ vc->vc_decscnm);
- vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm) << 8) | ' ';
+ vc->vc_attr = build_attr(vc, vc->vc_color, vc->vc_intensity,
+ vc->vc_blink, vc->vc_underline,
+ vc->vc_reverse ^ vc->vc_decscnm, vc->vc_italic);
+ vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm, 0) << 8) | ' ';
}
/* Note: inverting the screen twice should revert to the original state */
@@ -934,6 +944,10 @@
int default_blu[] = {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa,
0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff};
+module_param_array(default_red, int, NULL, S_IRUGO | S_IWUSR);
+module_param_array(default_grn, int, NULL, S_IRUGO | S_IWUSR);
+module_param_array(default_blu, int, NULL, S_IRUGO | S_IWUSR);
+
/*
* gotoxy() must verify all boundaries, because the arguments
* might also be negative. If the given position is out of
@@ -1132,6 +1146,7 @@
static void default_attr(struct vc_data *vc)
{
vc->vc_intensity = 1;
+ vc->vc_italic = 0;
vc->vc_underline = 0;
vc->vc_reverse = 0;
vc->vc_blink = 0;
@@ -1154,6 +1169,9 @@
case 2:
vc->vc_intensity = 0;
break;
+ case 3:
+ vc->vc_italic = 1;
+ break;
case 4:
vc->vc_underline = 1;
break;
@@ -1194,6 +1212,9 @@
case 22:
vc->vc_intensity = 1;
break;
+ case 23:
+ vc->vc_italic = 0;
+ break;
case 24:
vc->vc_underline = 0;
break;
@@ -1454,6 +1475,7 @@
vc->vc_saved_x = vc->vc_x;
vc->vc_saved_y = vc->vc_y;
vc->vc_s_intensity = vc->vc_intensity;
+ vc->vc_s_italic = vc->vc_italic;
vc->vc_s_underline = vc->vc_underline;
vc->vc_s_blink = vc->vc_blink;
vc->vc_s_reverse = vc->vc_reverse;
@@ -1468,6 +1490,7 @@
{
gotoxy(vc, vc->vc_saved_x, vc->vc_saved_y);
vc->vc_intensity = vc->vc_s_intensity;
+ vc->vc_italic = vc->vc_s_italic;
vc->vc_underline = vc->vc_s_underline;
vc->vc_blink = vc->vc_s_blink;
vc->vc_reverse = vc->vc_s_reverse;
@@ -1497,7 +1520,7 @@
vc->vc_charset = 0;
vc->vc_need_wrap = 0;
vc->vc_report_mouse = 0;
- vc->vc_utf = 0;
+ vc->vc_utf = default_utf8;
vc->vc_utf_count = 0;
vc->vc_disp_ctrl = 0;
@@ -1930,7 +1953,47 @@
* kernel memory allocation is available.
*/
char con_buf[CON_BUF_SIZE];
-DECLARE_MUTEX(con_buf_sem);
+DEFINE_MUTEX(con_buf_mtx);
+
+/* is_double_width() is based on the wcwidth() implementation by
+ * Markus Kuhn -- 2003-05-20 (Unicode 4.0)
+ * Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
+ */
+struct interval {
+ uint32_t first;
+ uint32_t last;
+};
+
+static int bisearch(uint32_t ucs, const struct interval *table, int max)
+{
+ int min = 0;
+ int mid;
+
+ if (ucs < table[0].first || ucs > table[max].last)
+ return 0;
+ while (max >= min) {
+ mid = (min + max) / 2;
+ if (ucs > table[mid].last)
+ min = mid + 1;
+ else if (ucs < table[mid].first)
+ max = mid - 1;
+ else
+ return 1;
+ }
+ return 0;
+}
+
+static int is_double_width(uint32_t ucs)
+{
+ static const struct interval double_width[] = {
+ { 0x1100, 0x115F }, { 0x2329, 0x232A }, { 0x2E80, 0x303E },
+ { 0x3040, 0xA4CF }, { 0xAC00, 0xD7A3 }, { 0xF900, 0xFAFF },
+ { 0xFE30, 0xFE6F }, { 0xFF00, 0xFF60 }, { 0xFFE0, 0xFFE6 },
+ { 0x20000, 0x2FFFD }, { 0x30000, 0x3FFFD }
+ };
+ return bisearch(ucs, double_width,
+ sizeof(double_width) / sizeof(*double_width) - 1);
+}
/* acquires console_sem */
static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int count)
@@ -1948,6 +2011,10 @@
unsigned int currcons;
unsigned long draw_from = 0, draw_to = 0;
struct vc_data *vc;
+ unsigned char vc_attr;
+ uint8_t rescan;
+ uint8_t inverse;
+ uint8_t width;
u16 himask, charmask;
const unsigned char *orig_buf = NULL;
int orig_count;
@@ -1983,7 +2050,7 @@
/* At this point 'buf' is guaranteed to be a kernel buffer
* and therefore no access to userspace (and therefore sleeping)
- * will be needed. The con_buf_sem serializes all tty based
+ * will be needed. The con_buf_mtx serializes all tty based
* console rendering and vcs write/read operations. We hold
* the console spinlock during the entire write.
*/
@@ -2010,53 +2077,86 @@
buf++;
n++;
count--;
+ rescan = 0;
+ inverse = 0;
+ width = 1;
/* Do no translation at all in control states */
if (vc->vc_state != ESnormal) {
tc = c;
} else if (vc->vc_utf && !vc->vc_disp_ctrl) {
- /* Combine UTF-8 into Unicode */
- /* Malformed sequences as sequences of replacement glyphs */
+ /* Combine UTF-8 into Unicode in vc_utf_char.
+ * vc_utf_count is the number of continuation bytes still
+ * expected to arrive.
+ * vc_npar is the number of continuation bytes arrived so
+ * far
+ */
rescan_last_byte:
- if(c > 0x7f) {
+ if ((c & 0xc0) == 0x80) {
+ /* Continuation byte received */
+ static const uint32_t utf8_length_changes[] = { 0x0000007f, 0x000007ff, 0x0000ffff, 0x001fffff, 0x03ffffff, 0x7fffffff };
if (vc->vc_utf_count) {
- if ((c & 0xc0) == 0x80) {
- vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f);
- if (--vc->vc_utf_count) {
- vc->vc_npar++;
- continue;
- }
- tc = c = vc->vc_utf_char;
- } else
- goto replacement_glyph;
- } else {
- vc->vc_npar = 0;
- if ((c & 0xe0) == 0xc0) {
- vc->vc_utf_count = 1;
- vc->vc_utf_char = (c & 0x1f);
- } else if ((c & 0xf0) == 0xe0) {
- vc->vc_utf_count = 2;
- vc->vc_utf_char = (c & 0x0f);
- } else if ((c & 0xf8) == 0xf0) {
- vc->vc_utf_count = 3;
- vc->vc_utf_char = (c & 0x07);
- } else if ((c & 0xfc) == 0xf8) {
- vc->vc_utf_count = 4;
- vc->vc_utf_char = (c & 0x03);
- } else if ((c & 0xfe) == 0xfc) {
- vc->vc_utf_count = 5;
- vc->vc_utf_char = (c & 0x01);
- } else
- goto replacement_glyph;
+ vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f);
+ vc->vc_npar++;
+ if (--vc->vc_utf_count) {
+ /* Still need some bytes */
continue;
- }
+ }
+ /* Got a whole character */
+ c = vc->vc_utf_char;
+ /* Reject overlong sequences */
+ if (c <= utf8_length_changes[vc->vc_npar - 1] ||
+ c > utf8_length_changes[vc->vc_npar])
+ c = 0xfffd;
+ } else {
+ /* Unexpected continuation byte */
+ vc->vc_utf_count = 0;
+ c = 0xfffd;
+ }
} else {
- if (vc->vc_utf_count)
- goto replacement_glyph;
- tc = c;
+ /* Single ASCII byte or first byte of a sequence received */
+ if (vc->vc_utf_count) {
+ /* Continuation byte expected */
+ rescan = 1;
+ vc->vc_utf_count = 0;
+ c = 0xfffd;
+ } else if (c > 0x7f) {
+ /* First byte of a multibyte sequence received */
+ vc->vc_npar = 0;
+ if ((c & 0xe0) == 0xc0) {
+ vc->vc_utf_count = 1;
+ vc->vc_utf_char = (c & 0x1f);
+ } else if ((c & 0xf0) == 0xe0) {
+ vc->vc_utf_count = 2;
+ vc->vc_utf_char = (c & 0x0f);
+ } else if ((c & 0xf8) == 0xf0) {
+ vc->vc_utf_count = 3;
+ vc->vc_utf_char = (c & 0x07);
+ } else if ((c & 0xfc) == 0xf8) {
+ vc->vc_utf_count = 4;
+ vc->vc_utf_char = (c & 0x03);
+ } else if ((c & 0xfe) == 0xfc) {
+ vc->vc_utf_count = 5;
+ vc->vc_utf_char = (c & 0x01);
+ } else {
+ /* 254 and 255 are invalid */
+ c = 0xfffd;
+ }
+ if (vc->vc_utf_count) {
+ /* Still need some bytes */
+ continue;
+ }
+ }
+ /* Nothing to do if an ASCII byte was received */
}
+ /* End of UTF-8 decoding. */
+ /* c is the received character, or U+FFFD for invalid sequences. */
+ /* Replace invalid Unicode code points with U+FFFD too */
+ if ((c >= 0xd800 && c <= 0xdfff) || c == 0xfffe || c == 0xffff)
+ c = 0xfffd;
+ tc = c;
} else { /* no utf or alternate charset mode */
- tc = vc->vc_translate[vc->vc_toggle_meta ? (c | 0x80) : c];
+ tc = vc->vc_translate[vc->vc_toggle_meta ? (c | 0x80) : c];
}
/* If the original code was a control character we
@@ -2076,56 +2176,80 @@
&& (c != 128+27);
if (vc->vc_state == ESnormal && ok) {
+ if (vc->vc_utf && !vc->vc_disp_ctrl) {
+ if (is_double_width(c))
+ width = 2;
+ }
/* Now try to find out how to display it */
tc = conv_uni_to_pc(vc, tc);
if (tc & ~charmask) {
- if ( tc == -4 ) {
- /* If we got -4 (not found) then see if we have
- defined a replacement character (U+FFFD) */
-replacement_glyph:
- tc = conv_uni_to_pc(vc, 0xfffd);
- if (!(tc & ~charmask))
- goto display_glyph;
- } else if ( tc != -3 )
- continue; /* nothing to display */
- /* no hash table or no replacement --
- * hope for the best */
- if ( c & ~charmask )
- tc = '?';
- else
- tc = c;
+ if (tc == -1 || tc == -2) {
+ continue; /* nothing to display */
+ }
+ /* Glyph not found */
+ if (!(vc->vc_utf && !vc->vc_disp_ctrl) && !(c & ~charmask)) {
+ /* In legacy mode use the glyph we get by a 1:1 mapping.
+ This would make absolutely no sense with Unicode in mind. */
+ tc = c;
+ } else {
+ /* Display U+FFFD. If it's not found, display an inverse question mark. */
+ tc = conv_uni_to_pc(vc, 0xfffd);
+ if (tc < 0) {
+ inverse = 1;
+ tc = conv_uni_to_pc(vc, '?');
+ if (tc < 0) tc = '?';
+ }
+ }
}
-display_glyph:
- if (vc->vc_need_wrap || vc->vc_decim)
- FLUSH
- if (vc->vc_need_wrap) {
- cr(vc);
- lf(vc);
- }
- if (vc->vc_decim)
- insert_char(vc, 1);
- scr_writew(himask ?
- ((vc->vc_attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) :
- (vc->vc_attr << 8) + tc,
- (u16 *) vc->vc_pos);
- if (DO_UPDATE(vc) && draw_x < 0) {
- draw_x = vc->vc_x;
- draw_from = vc->vc_pos;
- }
- if (vc->vc_x == vc->vc_cols - 1) {
- vc->vc_need_wrap = vc->vc_decawm;
- draw_to = vc->vc_pos + 2;
+ if (!inverse) {
+ vc_attr = vc->vc_attr;
} else {
- vc->vc_x++;
- draw_to = (vc->vc_pos += 2);
- }
- if (vc->vc_utf_count) {
- if (vc->vc_npar) {
- vc->vc_npar--;
- goto display_glyph;
+ /* invert vc_attr */
+ if (!vc->vc_can_do_color) {
+ vc_attr = (vc->vc_attr) ^ 0x08;
+ } else if (vc->vc_hi_font_mask == 0x100) {
+ vc_attr = ((vc->vc_attr) & 0x11) | (((vc->vc_attr) & 0xe0) >> 4) | (((vc->vc_attr) & 0x0e) << 4);
+ } else {
+ vc_attr = ((vc->vc_attr) & 0x88) | (((vc->vc_attr) & 0x70) >> 4) | (((vc->vc_attr) & 0x07) << 4);
}
- vc->vc_utf_count = 0;
+ }
+
+ while (1) {
+ if (vc->vc_need_wrap || vc->vc_decim)
+ FLUSH
+ if (vc->vc_need_wrap) {
+ cr(vc);
+ lf(vc);
+ }
+ if (vc->vc_decim)
+ insert_char(vc, 1);
+ scr_writew(himask ?
+ ((vc_attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) :
+ (vc_attr << 8) + tc,
+ (u16 *) vc->vc_pos);
+ if (DO_UPDATE(vc) && draw_x < 0) {
+ draw_x = vc->vc_x;
+ draw_from = vc->vc_pos;
+ }
+ if (vc->vc_x == vc->vc_cols - 1) {
+ vc->vc_need_wrap = vc->vc_decawm;
+ draw_to = vc->vc_pos + 2;
+ } else {
+ vc->vc_x++;
+ draw_to = (vc->vc_pos += 2);
+ }
+
+ if (!--width) break;
+
+ tc = conv_uni_to_pc(vc, ' '); /* A space is printed in the second column */
+ if (tc < 0) tc = ' ';
+ }
+
+ if (rescan) {
+ rescan = 0;
+ inverse = 0;
+ width = 1;
c = orig;
goto rescan_last_byte;
}
@@ -2581,6 +2705,11 @@
mutex_unlock(&tty_mutex);
}
+static int default_italic_color = 2; // green (ASCII)
+static int default_underline_color = 3; // cyan (ASCII)
+module_param_named(italic, default_italic_color, int, S_IRUGO | S_IWUSR);
+module_param_named(underline, default_underline_color, int, S_IRUGO | S_IWUSR);
+
static void vc_init(struct vc_data *vc, unsigned int rows,
unsigned int cols, int do_clear)
{
@@ -2600,7 +2729,8 @@
vc->vc_palette[k++] = default_blu[j] ;
}
vc->vc_def_color = 0x07; /* white */
- vc->vc_ulcolor = 0x0f; /* bold white */
+ vc->vc_ulcolor = default_underline_color;
+ vc->vc_itcolor = default_italic_color;
vc->vc_halfcolor = 0x08; /* grey */
init_waitqueue_head(&vc->paste_wait);
reset_terminal(vc, do_clear);
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index c9f2dd6..c6f6f42 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -1061,7 +1061,7 @@
schedule();
}
remove_wait_queue(&vt_activate_queue, &wait);
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
return retval;
}
diff --git a/drivers/char/watchdog/omap_wdt.c b/drivers/char/watchdog/omap_wdt.c
index 84074a6..b36fa8d 100644
--- a/drivers/char/watchdog/omap_wdt.c
+++ b/drivers/char/watchdog/omap_wdt.c
@@ -34,7 +34,6 @@
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/reboot.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/platform_device.h>
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 8d053f5..8532bb7 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -470,7 +470,7 @@
dbs_info->enable = 1;
ondemand_powersave_bias_init();
dbs_info->sample_type = DBS_NORMAL_SAMPLE;
- INIT_DELAYED_WORK(&dbs_info->work, do_dbs_timer);
+ INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer);
queue_delayed_work_on(dbs_info->cpu, kondemand_wq, &dbs_info->work,
delay);
}
diff --git a/drivers/edac/i82875p_edac.c b/drivers/edac/i82875p_edac.c
index 161fe09..2800b3e 100644
--- a/drivers/edac/i82875p_edac.c
+++ b/drivers/edac/i82875p_edac.c
@@ -261,10 +261,6 @@
i82875p_process_error_info(mci, &info, 1);
}
-#ifdef CONFIG_PROC_FS
-extern int pci_proc_attach_device(struct pci_dev *);
-#endif
-
/* Return 0 on success or 1 on failure. */
static int i82875p_setup_overfl_dev(struct pci_dev *pdev,
struct pci_dev **ovrfl_pdev, void __iomem **ovrfl_window)
@@ -287,17 +283,12 @@
if (dev == NULL)
return 1;
+
+ pci_bus_add_device(dev);
}
*ovrfl_pdev = dev;
-#ifdef CONFIG_PROC_FS
- if ((dev->procent == NULL) && pci_proc_attach_device(dev)) {
- i82875p_printk(KERN_ERR, "%s(): Failed to attach overflow "
- "device\n", __func__);
- return 1;
- }
-#endif /* CONFIG_PROC_FS */
if (pci_enable_device(dev)) {
i82875p_printk(KERN_ERR, "%s(): Failed to enable overflow "
"device\n", __func__);
diff --git a/drivers/eisa/virtual_root.c b/drivers/eisa/virtual_root.c
index 9b4fcac..3074879 100644
--- a/drivers/eisa/virtual_root.c
+++ b/drivers/eisa/virtual_root.c
@@ -47,7 +47,7 @@
/* nothing really to do here */
}
-static int virtual_eisa_root_init (void)
+static int __init virtual_eisa_root_init (void)
{
int r;
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 62e21cc..6ec04e7 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -20,7 +20,6 @@
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/mm.h>
-#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <asm/unaligned.h>
#include <asm/byteorder.h>
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 6d105a1..25b72a4 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -594,6 +594,30 @@
Say Y here if you have an applicable laptop and want to experience
the awesome power of hdaps.
+config SENSORS_APPLESMC
+ tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)"
+ depends on HWMON && INPUT && X86
+ select NEW_LEDS
+ select LEDS_CLASS
+ default n
+ help
+ This driver provides support for the Apple System Management
+ Controller, which provides an accelerometer (Apple Sudden Motion
+ Sensor), light sensors, temperature sensors, keyboard backlight
+ control and fan control.
+
+ Only Intel-based Apple's computers are supported (MacBook Pro,
+ MacBook, MacMini).
+
+ Data from the different sensors, keyboard backlight control and fan
+ control are accessible via sysfs.
+
+ This driver also provides an absolute input class device, allowing
+ the laptop to act as a pinball machine-esque joystick.
+
+ Say Y here if you have an applicable laptop and want to experience
+ the awesome power of applesmc.
+
config HWMON_DEBUG_CHIP
bool "Hardware Monitoring Chip debugging messages"
depends on HWMON
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 4165c27..544f8d8 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -20,6 +20,7 @@
obj-$(CONFIG_SENSORS_ADM1029) += adm1029.o
obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o
obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o
+obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o
obj-$(CONFIG_SENSORS_AMS) += ams/
obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o
obj-$(CONFIG_SENSORS_DS1621) += ds1621.o
diff --git a/drivers/hwmon/ams/ams-core.c b/drivers/hwmon/ams/ams-core.c
index f5ebad5..dbe6a32 100644
--- a/drivers/hwmon/ams/ams-core.c
+++ b/drivers/hwmon/ams/ams-core.c
@@ -144,7 +144,7 @@
const u32 *prop;
/* Get orientation */
- prop = get_property(ams_info.of_node, "orientation", NULL);
+ prop = of_get_property(ams_info.of_node, "orientation", NULL);
if (!prop)
return -ENODEV;
ams_info.orient1 = *prop;
@@ -208,14 +208,14 @@
#ifdef CONFIG_SENSORS_AMS_I2C
np = of_find_node_by_name(NULL, "accelerometer");
- if (np && device_is_compatible(np, "AAPL,accelerometer_1"))
+ if (np && of_device_is_compatible(np, "AAPL,accelerometer_1"))
/* Found I2C motion sensor */
return ams_i2c_init(np);
#endif
#ifdef CONFIG_SENSORS_AMS_PMU
np = of_find_node_by_name(NULL, "sms");
- if (np && device_is_compatible(np, "sms"))
+ if (np && of_device_is_compatible(np, "sms"))
/* Found PMU motion sensor */
return ams_pmu_init(np);
#endif
diff --git a/drivers/hwmon/ams/ams-i2c.c b/drivers/hwmon/ams/ams-i2c.c
index 485d333..ccd5cef 100644
--- a/drivers/hwmon/ams/ams-i2c.c
+++ b/drivers/hwmon/ams/ams-i2c.c
@@ -276,7 +276,7 @@
ams_info.bustype = BUS_I2C;
/* look for bus either using "reg" or by path */
- prop = get_property(ams_info.of_node, "reg", NULL);
+ prop = of_get_property(ams_info.of_node, "reg", NULL);
if (!prop) {
result = -ENODEV;
diff --git a/drivers/hwmon/ams/ams-pmu.c b/drivers/hwmon/ams/ams-pmu.c
index 1b01c21..9463e97 100644
--- a/drivers/hwmon/ams/ams-pmu.c
+++ b/drivers/hwmon/ams/ams-pmu.c
@@ -160,7 +160,7 @@
ams_info.bustype = BUS_HOST;
/* Get PMU command, should be 0x4e, but we can never know */
- prop = get_property(ams_info.of_node, "reg", NULL);
+ prop = of_get_property(ams_info.of_node, "reg", NULL);
if (!prop) {
result = -ENODEV;
goto exit;
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
new file mode 100644
index 0000000..3215f9c
--- /dev/null
+++ b/drivers/hwmon/applesmc.c
@@ -0,0 +1,1339 @@
+/*
+ * drivers/hwmon/applesmc.c - driver for Apple's SMC (accelerometer, temperature
+ * sensors, fan control, keyboard backlight control) used in Intel-based Apple
+ * computers.
+ *
+ * Copyright (C) 2007 Nicolas Boichat <nicolas@boichat.ch>
+ *
+ * Based on hdaps.c driver:
+ * Copyright (C) 2005 Robert Love <rml@novell.com>
+ * Copyright (C) 2005 Jesper Juhl <jesper.juhl@gmail.com>
+ *
+ * Fan control based on smcFanControl:
+ * Copyright (C) 2006 Hendrik Holtmann <holtmann@mac.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License v2 as published by the
+ * Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/timer.h>
+#include <linux/dmi.h>
+#include <linux/mutex.h>
+#include <linux/hwmon-sysfs.h>
+#include <asm/io.h>
+#include <linux/leds.h>
+#include <linux/hwmon.h>
+#include <linux/workqueue.h>
+
+/* data port used by Apple SMC */
+#define APPLESMC_DATA_PORT 0x300
+/* command/status port used by Apple SMC */
+#define APPLESMC_CMD_PORT 0x304
+
+#define APPLESMC_NR_PORTS 32 /* 0x300-0x31f */
+
+#define APPLESMC_MAX_DATA_LENGTH 32
+
+#define APPLESMC_STATUS_MASK 0x0f
+#define APPLESMC_READ_CMD 0x10
+#define APPLESMC_WRITE_CMD 0x11
+#define APPLESMC_GET_KEY_BY_INDEX_CMD 0x12
+#define APPLESMC_GET_KEY_TYPE_CMD 0x13
+
+#define KEY_COUNT_KEY "#KEY" /* r-o ui32 */
+
+#define LIGHT_SENSOR_LEFT_KEY "ALV0" /* r-o {alv (6 bytes) */
+#define LIGHT_SENSOR_RIGHT_KEY "ALV1" /* r-o {alv (6 bytes) */
+#define BACKLIGHT_KEY "LKSB" /* w-o {lkb (2 bytes) */
+
+#define CLAMSHELL_KEY "MSLD" /* r-o ui8 (unused) */
+
+#define MOTION_SENSOR_X_KEY "MO_X" /* r-o sp78 (2 bytes) */
+#define MOTION_SENSOR_Y_KEY "MO_Y" /* r-o sp78 (2 bytes) */
+#define MOTION_SENSOR_Z_KEY "MO_Z" /* r-o sp78 (2 bytes) */
+#define MOTION_SENSOR_KEY "MOCN" /* r/w ui16 */
+
+#define FANS_COUNT "FNum" /* r-o ui8 */
+#define FANS_MANUAL "FS! " /* r-w ui16 */
+#define FAN_ACTUAL_SPEED "F0Ac" /* r-o fpe2 (2 bytes) */
+#define FAN_MIN_SPEED "F0Mn" /* r-o fpe2 (2 bytes) */
+#define FAN_MAX_SPEED "F0Mx" /* r-o fpe2 (2 bytes) */
+#define FAN_SAFE_SPEED "F0Sf" /* r-o fpe2 (2 bytes) */
+#define FAN_TARGET_SPEED "F0Tg" /* r-w fpe2 (2 bytes) */
+#define FAN_POSITION "F0ID" /* r-o char[16] */
+
+/*
+ * Temperature sensors keys (sp78 - 2 bytes).
+ * First set for Macbook(Pro), second for Macmini.
+ */
+static const char* temperature_sensors_sets[][13] = {
+ { "TA0P", "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "Th0H",
+ "Th1H", "Tm0P", "Ts0P", "Ts1P", NULL },
+ { "TC0D", "TC0P", NULL }
+};
+
+/* List of keys used to read/write fan speeds */
+static const char* fan_speed_keys[] = {
+ FAN_ACTUAL_SPEED,
+ FAN_MIN_SPEED,
+ FAN_MAX_SPEED,
+ FAN_SAFE_SPEED,
+ FAN_TARGET_SPEED
+};
+
+#define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */
+#define INIT_WAIT_MSECS 50 /* ... in 50ms increments */
+
+#define APPLESMC_POLL_PERIOD (HZ/20) /* poll for input every 1/20s */
+#define APPLESMC_INPUT_FUZZ 4 /* input event threshold */
+#define APPLESMC_INPUT_FLAT 4
+
+#define SENSOR_X 0
+#define SENSOR_Y 1
+#define SENSOR_Z 2
+
+/* Structure to be passed to DMI_MATCH function */
+struct dmi_match_data {
+/* Indicates whether this computer has an accelerometer. */
+ int accelerometer;
+/* Indicates whether this computer has light sensors and keyboard backlight. */
+ int light;
+/* Indicates which temperature sensors set to use. */
+ int temperature_set;
+};
+
+static const int debug;
+static struct platform_device *pdev;
+static s16 rest_x;
+static s16 rest_y;
+static struct timer_list applesmc_timer;
+static struct input_dev *applesmc_idev;
+static struct class_device *hwmon_class_dev;
+
+/* Indicates whether this computer has an accelerometer. */
+static unsigned int applesmc_accelerometer;
+
+/* Indicates whether this computer has light sensors and keyboard backlight. */
+static unsigned int applesmc_light;
+
+/* Indicates which temperature sensors set to use. */
+static unsigned int applesmc_temperature_set;
+
+static struct mutex applesmc_lock;
+
+/*
+ * Last index written to key_at_index sysfs file, and value to use for all other
+ * key_at_index_* sysfs files.
+ */
+static unsigned int key_at_index;
+
+static struct workqueue_struct *applesmc_led_wq;
+
+/*
+ * __wait_status - Wait up to 2ms for the status port to get a certain value
+ * (masked with 0x0f), returning zero if the value is obtained. Callers must
+ * hold applesmc_lock.
+ */
+static int __wait_status(u8 val)
+{
+ unsigned int i;
+
+ val = val & APPLESMC_STATUS_MASK;
+
+ for (i = 0; i < 200; i++) {
+ if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) {
+ if (debug)
+ printk(KERN_DEBUG
+ "Waited %d us for status %x\n",
+ i*10, val);
+ return 0;
+ }
+ udelay(10);
+ }
+
+ printk(KERN_WARNING "applesmc: wait status failed: %x != %x\n",
+ val, inb(APPLESMC_CMD_PORT));
+
+ return -EIO;
+}
+
+/*
+ * applesmc_read_key - reads len bytes from a given key, and put them in buffer.
+ * Returns zero on success or a negative error on failure. Callers must
+ * hold applesmc_lock.
+ */
+static int applesmc_read_key(const char* key, u8* buffer, u8 len)
+{
+ int i;
+
+ if (len > APPLESMC_MAX_DATA_LENGTH) {
+ printk(KERN_ERR "applesmc_read_key: cannot read more than "
+ "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
+ return -EINVAL;
+ }
+
+ outb(APPLESMC_READ_CMD, APPLESMC_CMD_PORT);
+ if (__wait_status(0x0c))
+ return -EIO;
+
+ for (i = 0; i < 4; i++) {
+ outb(key[i], APPLESMC_DATA_PORT);
+ if (__wait_status(0x04))
+ return -EIO;
+ }
+ if (debug)
+ printk(KERN_DEBUG "<%s", key);
+
+ outb(len, APPLESMC_DATA_PORT);
+ if (debug)
+ printk(KERN_DEBUG ">%x", len);
+
+ for (i = 0; i < len; i++) {
+ if (__wait_status(0x05))
+ return -EIO;
+ buffer[i] = inb(APPLESMC_DATA_PORT);
+ if (debug)
+ printk(KERN_DEBUG "<%x", buffer[i]);
+ }
+ if (debug)
+ printk(KERN_DEBUG "\n");
+
+ return 0;
+}
+
+/*
+ * applesmc_write_key - writes len bytes from buffer to a given key.
+ * Returns zero on success or a negative error on failure. Callers must
+ * hold applesmc_lock.
+ */
+static int applesmc_write_key(const char* key, u8* buffer, u8 len)
+{
+ int i;
+
+ if (len > APPLESMC_MAX_DATA_LENGTH) {
+ printk(KERN_ERR "applesmc_write_key: cannot write more than "
+ "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
+ return -EINVAL;
+ }
+
+ outb(APPLESMC_WRITE_CMD, APPLESMC_CMD_PORT);
+ if (__wait_status(0x0c))
+ return -EIO;
+
+ for (i = 0; i < 4; i++) {
+ outb(key[i], APPLESMC_DATA_PORT);
+ if (__wait_status(0x04))
+ return -EIO;
+ }
+
+ outb(len, APPLESMC_DATA_PORT);
+
+ for (i = 0; i < len; i++) {
+ if (__wait_status(0x04))
+ return -EIO;
+ outb(buffer[i], APPLESMC_DATA_PORT);
+ }
+
+ return 0;
+}
+
+/*
+ * applesmc_get_key_at_index - get key at index, and put the result in key
+ * (char[6]). Returns zero on success or a negative error on failure. Callers
+ * must hold applesmc_lock.
+ */
+static int applesmc_get_key_at_index(int index, char* key)
+{
+ int i;
+ u8 readkey[4];
+ readkey[0] = index >> 24;
+ readkey[1] = index >> 16;
+ readkey[2] = index >> 8;
+ readkey[3] = index;
+
+ outb(APPLESMC_GET_KEY_BY_INDEX_CMD, APPLESMC_CMD_PORT);
+ if (__wait_status(0x0c))
+ return -EIO;
+
+ for (i = 0; i < 4; i++) {
+ outb(readkey[i], APPLESMC_DATA_PORT);
+ if (__wait_status(0x04))
+ return -EIO;
+ }
+
+ outb(4, APPLESMC_DATA_PORT);
+
+ for (i = 0; i < 4; i++) {
+ if (__wait_status(0x05))
+ return -EIO;
+ key[i] = inb(APPLESMC_DATA_PORT);
+ }
+ key[4] = 0;
+
+ return 0;
+}
+
+/*
+ * applesmc_get_key_type - get key type, and put the result in type (char[6]).
+ * Returns zero on success or a negative error on failure. Callers must
+ * hold applesmc_lock.
+ */
+static int applesmc_get_key_type(char* key, char* type)
+{
+ int i;
+
+ outb(APPLESMC_GET_KEY_TYPE_CMD, APPLESMC_CMD_PORT);
+ if (__wait_status(0x0c))
+ return -EIO;
+
+ for (i = 0; i < 4; i++) {
+ outb(key[i], APPLESMC_DATA_PORT);
+ if (__wait_status(0x04))
+ return -EIO;
+ }
+
+ outb(5, APPLESMC_DATA_PORT);
+
+ for (i = 0; i < 6; i++) {
+ if (__wait_status(0x05))
+ return -EIO;
+ type[i] = inb(APPLESMC_DATA_PORT);
+ }
+ type[5] = 0;
+
+ return 0;
+}
+
+/*
+ * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). Callers must
+ * hold applesmc_lock.
+ */
+static int applesmc_read_motion_sensor(int index, s16* value)
+{
+ u8 buffer[2];
+ int ret;
+
+ switch (index) {
+ case SENSOR_X:
+ ret = applesmc_read_key(MOTION_SENSOR_X_KEY, buffer, 2);
+ break;
+ case SENSOR_Y:
+ ret = applesmc_read_key(MOTION_SENSOR_Y_KEY, buffer, 2);
+ break;
+ case SENSOR_Z:
+ ret = applesmc_read_key(MOTION_SENSOR_Z_KEY, buffer, 2);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ *value = ((s16)buffer[0] << 8) | buffer[1];
+
+ return ret;
+}
+
+/*
+ * applesmc_device_init - initialize the accelerometer. Returns zero on success
+ * and negative error code on failure. Can sleep.
+ */
+static int applesmc_device_init(void)
+{
+ int total, ret = -ENXIO;
+ u8 buffer[2];
+
+ if (!applesmc_accelerometer)
+ return 0;
+
+ mutex_lock(&applesmc_lock);
+
+ for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) {
+ if (debug)
+ printk(KERN_DEBUG "applesmc try %d\n", total);
+ if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) &&
+ (buffer[0] != 0x00 || buffer[1] != 0x00)) {
+ if (total == INIT_TIMEOUT_MSECS) {
+ printk(KERN_DEBUG "applesmc: device has"
+ " already been initialized"
+ " (0x%02x, 0x%02x).\n",
+ buffer[0], buffer[1]);
+ } else {
+ printk(KERN_DEBUG "applesmc: device"
+ " successfully initialized"
+ " (0x%02x, 0x%02x).\n",
+ buffer[0], buffer[1]);
+ }
+ ret = 0;
+ goto out;
+ }
+ buffer[0] = 0xe0;
+ buffer[1] = 0x00;
+ applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2);
+ msleep(INIT_WAIT_MSECS);
+ }
+
+ printk(KERN_WARNING "applesmc: failed to init the device\n");
+
+out:
+ mutex_unlock(&applesmc_lock);
+ return ret;
+}
+
+/*
+ * applesmc_get_fan_count - get the number of fans. Callers must NOT hold
+ * applesmc_lock.
+ */
+static int applesmc_get_fan_count(void)
+{
+ int ret;
+ u8 buffer[1];
+
+ mutex_lock(&applesmc_lock);
+
+ ret = applesmc_read_key(FANS_COUNT, buffer, 1);
+
+ mutex_unlock(&applesmc_lock);
+ if (ret)
+ return ret;
+ else
+ return buffer[0];
+}
+
+/* Device model stuff */
+static int applesmc_probe(struct platform_device *dev)
+{
+ int ret;
+
+ ret = applesmc_device_init();
+ if (ret)
+ return ret;
+
+ printk(KERN_INFO "applesmc: device successfully initialized.\n");
+ return 0;
+}
+
+static int applesmc_resume(struct platform_device *dev)
+{
+ return applesmc_device_init();
+}
+
+static struct platform_driver applesmc_driver = {
+ .probe = applesmc_probe,
+ .resume = applesmc_resume,
+ .driver = {
+ .name = "applesmc",
+ .owner = THIS_MODULE,
+ },
+};
+
+/*
+ * applesmc_calibrate - Set our "resting" values. Callers must
+ * hold applesmc_lock.
+ */
+static void applesmc_calibrate(void)
+{
+ applesmc_read_motion_sensor(SENSOR_X, &rest_x);
+ applesmc_read_motion_sensor(SENSOR_Y, &rest_y);
+ rest_x = -rest_x;
+}
+
+static int applesmc_idev_open(struct input_dev *dev)
+{
+ add_timer(&applesmc_timer);
+
+ return 0;
+}
+
+static void applesmc_idev_close(struct input_dev *dev)
+{
+ del_timer_sync(&applesmc_timer);
+}
+
+static void applesmc_idev_poll(unsigned long unused)
+{
+ s16 x, y;
+
+ /* Cannot sleep. Try nonblockingly. If we fail, try again later. */
+ if (!mutex_trylock(&applesmc_lock)) {
+ mod_timer(&applesmc_timer, jiffies + APPLESMC_POLL_PERIOD);
+ return;
+ }
+
+ if (applesmc_read_motion_sensor(SENSOR_X, &x))
+ goto out;
+ if (applesmc_read_motion_sensor(SENSOR_Y, &y))
+ goto out;
+
+ x = -x;
+ input_report_abs(applesmc_idev, ABS_X, x - rest_x);
+ input_report_abs(applesmc_idev, ABS_Y, y - rest_y);
+ input_sync(applesmc_idev);
+
+out:
+ mod_timer(&applesmc_timer, jiffies + APPLESMC_POLL_PERIOD);
+
+ mutex_unlock(&applesmc_lock);
+}
+
+/* Sysfs Files */
+
+static ssize_t applesmc_position_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int ret;
+ s16 x, y, z;
+
+ mutex_lock(&applesmc_lock);
+
+ ret = applesmc_read_motion_sensor(SENSOR_X, &x);
+ if (ret)
+ goto out;
+ ret = applesmc_read_motion_sensor(SENSOR_Y, &y);
+ if (ret)
+ goto out;
+ ret = applesmc_read_motion_sensor(SENSOR_Z, &z);
+ if (ret)
+ goto out;
+
+out:
+ mutex_unlock(&applesmc_lock);
+ if (ret)
+ return ret;
+ else
+ return snprintf(buf, PAGE_SIZE, "(%d,%d,%d)\n", x, y, z);
+}
+
+static ssize_t applesmc_light_show(struct device *dev,
+ struct device_attribute *attr, char *sysfsbuf)
+{
+ int ret;
+ u8 left = 0, right = 0;
+ u8 buffer[6];
+
+ mutex_lock(&applesmc_lock);
+
+ ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, 6);
+ left = buffer[2];
+ if (ret)
+ goto out;
+ ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, 6);
+ right = buffer[2];
+
+out:
+ mutex_unlock(&applesmc_lock);
+ if (ret)
+ return ret;
+ else
+ return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", left, right);
+}
+
+/* Displays degree Celsius * 1000 */
+static ssize_t applesmc_show_temperature(struct device *dev,
+ struct device_attribute *devattr, char *sysfsbuf)
+{
+ int ret;
+ u8 buffer[2];
+ unsigned int temp;
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ const char* key =
+ temperature_sensors_sets[applesmc_temperature_set][attr->index];
+
+ mutex_lock(&applesmc_lock);
+
+ ret = applesmc_read_key(key, buffer, 2);
+ temp = buffer[0]*1000;
+ temp += (buffer[1] >> 6) * 250;
+
+ mutex_unlock(&applesmc_lock);
+
+ if (ret)
+ return ret;
+ else
+ return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", temp);
+}
+
+static ssize_t applesmc_show_fan_speed(struct device *dev,
+ struct device_attribute *attr, char *sysfsbuf)
+{
+ int ret;
+ unsigned int speed = 0;
+ char newkey[5];
+ u8 buffer[2];
+ struct sensor_device_attribute_2 *sensor_attr =
+ to_sensor_dev_attr_2(attr);
+
+ newkey[0] = fan_speed_keys[sensor_attr->nr][0];
+ newkey[1] = '0' + sensor_attr->index;
+ newkey[2] = fan_speed_keys[sensor_attr->nr][2];
+ newkey[3] = fan_speed_keys[sensor_attr->nr][3];
+ newkey[4] = 0;
+
+ mutex_lock(&applesmc_lock);
+
+ ret = applesmc_read_key(newkey, buffer, 2);
+ speed = ((buffer[0] << 8 | buffer[1]) >> 2);
+
+ mutex_unlock(&applesmc_lock);
+ if (ret)
+ return ret;
+ else
+ return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", speed);
+}
+
+static ssize_t applesmc_store_fan_speed(struct device *dev,
+ struct device_attribute *attr,
+ const char *sysfsbuf, size_t count)
+{
+ int ret;
+ u32 speed;
+ char newkey[5];
+ u8 buffer[2];
+ struct sensor_device_attribute_2 *sensor_attr =
+ to_sensor_dev_attr_2(attr);
+
+ speed = simple_strtoul(sysfsbuf, NULL, 10);
+
+ if (speed > 0x4000) /* Bigger than a 14-bit value */
+ return -EINVAL;
+
+ newkey[0] = fan_speed_keys[sensor_attr->nr][0];
+ newkey[1] = '0' + sensor_attr->index;
+ newkey[2] = fan_speed_keys[sensor_attr->nr][2];
+ newkey[3] = fan_speed_keys[sensor_attr->nr][3];
+ newkey[4] = 0;
+
+ mutex_lock(&applesmc_lock);
+
+ buffer[0] = (speed >> 6) & 0xff;
+ buffer[1] = (speed << 2) & 0xff;
+ ret = applesmc_write_key(newkey, buffer, 2);
+
+ mutex_unlock(&applesmc_lock);
+ if (ret)
+ return ret;
+ else
+ return count;
+}
+
+static ssize_t applesmc_show_fan_manual(struct device *dev,
+ struct device_attribute *devattr, char *sysfsbuf)
+{
+ int ret;
+ u16 manual = 0;
+ u8 buffer[2];
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+
+ mutex_lock(&applesmc_lock);
+
+ ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
+ manual = ((buffer[0] << 8 | buffer[1]) >> attr->index) & 0x01;
+
+ mutex_unlock(&applesmc_lock);
+ if (ret)
+ return ret;
+ else
+ return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", manual);
+}
+
+static ssize_t applesmc_store_fan_manual(struct device *dev,
+ struct device_attribute *devattr,
+ const char *sysfsbuf, size_t count)
+{
+ int ret;
+ u8 buffer[2];
+ u32 input;
+ u16 val;
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+
+ input = simple_strtoul(sysfsbuf, NULL, 10);
+
+ mutex_lock(&applesmc_lock);
+
+ ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
+ val = (buffer[0] << 8 | buffer[1]);
+ if (ret)
+ goto out;
+
+ if (input)
+ val = val | (0x01 << attr->index);
+ else
+ val = val & ~(0x01 << attr->index);
+
+ buffer[0] = (val >> 8) & 0xFF;
+ buffer[1] = val & 0xFF;
+
+ ret = applesmc_write_key(FANS_MANUAL, buffer, 2);
+
+out:
+ mutex_unlock(&applesmc_lock);
+ if (ret)
+ return ret;
+ else
+ return count;
+}
+
+static ssize_t applesmc_show_fan_position(struct device *dev,
+ struct device_attribute *attr, char *sysfsbuf)
+{
+ int ret;
+ char newkey[5];
+ u8 buffer[17];
+ struct sensor_device_attribute_2 *sensor_attr =
+ to_sensor_dev_attr_2(attr);
+
+ newkey[0] = FAN_POSITION[0];
+ newkey[1] = '0' + sensor_attr->index;
+ newkey[2] = FAN_POSITION[2];
+ newkey[3] = FAN_POSITION[3];
+ newkey[4] = 0;
+
+ mutex_lock(&applesmc_lock);
+
+ ret = applesmc_read_key(newkey, buffer, 16);
+ buffer[16] = 0;
+
+ mutex_unlock(&applesmc_lock);
+ if (ret)
+ return ret;
+ else
+ return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", buffer+4);
+}
+
+static ssize_t applesmc_calibrate_show(struct device *dev,
+ struct device_attribute *attr, char *sysfsbuf)
+{
+ return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", rest_x, rest_y);
+}
+
+static ssize_t applesmc_calibrate_store(struct device *dev,
+ struct device_attribute *attr, const char *sysfsbuf, size_t count)
+{
+ mutex_lock(&applesmc_lock);
+ applesmc_calibrate();
+ mutex_unlock(&applesmc_lock);
+
+ return count;
+}
+
+/* Store the next backlight value to be written by the work */
+static unsigned int backlight_value;
+
+static void applesmc_backlight_set(struct work_struct *work)
+{
+ u8 buffer[2];
+
+ mutex_lock(&applesmc_lock);
+ buffer[0] = backlight_value;
+ buffer[1] = 0x00;
+ applesmc_write_key(BACKLIGHT_KEY, buffer, 2);
+ mutex_unlock(&applesmc_lock);
+}
+static DECLARE_WORK(backlight_work, &applesmc_backlight_set);
+
+static void applesmc_brightness_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ int ret;
+
+ backlight_value = value;
+ ret = queue_work(applesmc_led_wq, &backlight_work);
+
+ if (debug && (!ret))
+ printk(KERN_DEBUG "applesmc: work was already on the queue.\n");
+}
+
+static ssize_t applesmc_key_count_show(struct device *dev,
+ struct device_attribute *attr, char *sysfsbuf)
+{
+ int ret;
+ u8 buffer[4];
+ u32 count;
+
+ mutex_lock(&applesmc_lock);
+
+ ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4);
+ count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) +
+ ((u32)buffer[2]<<8) + buffer[3];
+
+ mutex_unlock(&applesmc_lock);
+ if (ret)
+ return ret;
+ else
+ return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", count);
+}
+
+static ssize_t applesmc_key_at_index_read_show(struct device *dev,
+ struct device_attribute *attr, char *sysfsbuf)
+{
+ char key[5];
+ char info[6];
+ int ret;
+
+ mutex_lock(&applesmc_lock);
+
+ ret = applesmc_get_key_at_index(key_at_index, key);
+
+ if (ret || !key[0]) {
+ mutex_unlock(&applesmc_lock);
+
+ return -EINVAL;
+ }
+
+ ret = applesmc_get_key_type(key, info);
+
+ if (ret) {
+ mutex_unlock(&applesmc_lock);
+
+ return ret;
+ }
+
+ /*
+ * info[0] maximum value (APPLESMC_MAX_DATA_LENGTH) is much lower than
+ * PAGE_SIZE, so we don't need any checks before writing to sysfsbuf.
+ */
+ ret = applesmc_read_key(key, sysfsbuf, info[0]);
+
+ mutex_unlock(&applesmc_lock);
+
+ if (!ret) {
+ return info[0];
+ }
+ else {
+ return ret;
+ }
+}
+
+static ssize_t applesmc_key_at_index_data_length_show(struct device *dev,
+ struct device_attribute *attr, char *sysfsbuf)
+{
+ char key[5];
+ char info[6];
+ int ret;
+
+ mutex_lock(&applesmc_lock);
+
+ ret = applesmc_get_key_at_index(key_at_index, key);
+
+ if (ret || !key[0]) {
+ mutex_unlock(&applesmc_lock);
+
+ return -EINVAL;
+ }
+
+ ret = applesmc_get_key_type(key, info);
+
+ mutex_unlock(&applesmc_lock);
+
+ if (!ret)
+ return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", info[0]);
+ else
+ return ret;
+}
+
+static ssize_t applesmc_key_at_index_type_show(struct device *dev,
+ struct device_attribute *attr, char *sysfsbuf)
+{
+ char key[5];
+ char info[6];
+ int ret;
+
+ mutex_lock(&applesmc_lock);
+
+ ret = applesmc_get_key_at_index(key_at_index, key);
+
+ if (ret || !key[0]) {
+ mutex_unlock(&applesmc_lock);
+
+ return -EINVAL;
+ }
+
+ ret = applesmc_get_key_type(key, info);
+
+ mutex_unlock(&applesmc_lock);
+
+ if (!ret)
+ return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", info+1);
+ else
+ return ret;
+}
+
+static ssize_t applesmc_key_at_index_name_show(struct device *dev,
+ struct device_attribute *attr, char *sysfsbuf)
+{
+ char key[5];
+ int ret;
+
+ mutex_lock(&applesmc_lock);
+
+ ret = applesmc_get_key_at_index(key_at_index, key);
+
+ mutex_unlock(&applesmc_lock);
+
+ if (!ret && key[0])
+ return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key);
+ else
+ return -EINVAL;
+}
+
+static ssize_t applesmc_key_at_index_show(struct device *dev,
+ struct device_attribute *attr, char *sysfsbuf)
+{
+ return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", key_at_index);
+}
+
+static ssize_t applesmc_key_at_index_store(struct device *dev,
+ struct device_attribute *attr, const char *sysfsbuf, size_t count)
+{
+ mutex_lock(&applesmc_lock);
+
+ key_at_index = simple_strtoul(sysfsbuf, NULL, 10);
+
+ mutex_unlock(&applesmc_lock);
+
+ return count;
+}
+
+static struct led_classdev applesmc_backlight = {
+ .name = "smc:kbd_backlight",
+ .default_trigger = "nand-disk",
+ .brightness_set = applesmc_brightness_set,
+};
+
+static DEVICE_ATTR(position, 0444, applesmc_position_show, NULL);
+static DEVICE_ATTR(calibrate, 0644,
+ applesmc_calibrate_show, applesmc_calibrate_store);
+
+static struct attribute *accelerometer_attributes[] = {
+ &dev_attr_position.attr,
+ &dev_attr_calibrate.attr,
+ NULL
+};
+
+static const struct attribute_group accelerometer_attributes_group =
+ { .attrs = accelerometer_attributes };
+
+static DEVICE_ATTR(light, 0444, applesmc_light_show, NULL);
+
+static DEVICE_ATTR(key_count, 0444, applesmc_key_count_show, NULL);
+static DEVICE_ATTR(key_at_index, 0644,
+ applesmc_key_at_index_show, applesmc_key_at_index_store);
+static DEVICE_ATTR(key_at_index_name, 0444,
+ applesmc_key_at_index_name_show, NULL);
+static DEVICE_ATTR(key_at_index_type, 0444,
+ applesmc_key_at_index_type_show, NULL);
+static DEVICE_ATTR(key_at_index_data_length, 0444,
+ applesmc_key_at_index_data_length_show, NULL);
+static DEVICE_ATTR(key_at_index_data, 0444,
+ applesmc_key_at_index_read_show, NULL);
+
+static struct attribute *key_enumeration_attributes[] = {
+ &dev_attr_key_count.attr,
+ &dev_attr_key_at_index.attr,
+ &dev_attr_key_at_index_name.attr,
+ &dev_attr_key_at_index_type.attr,
+ &dev_attr_key_at_index_data_length.attr,
+ &dev_attr_key_at_index_data.attr,
+ NULL
+};
+
+static const struct attribute_group key_enumeration_group =
+ { .attrs = key_enumeration_attributes };
+
+/*
+ * Macro defining SENSOR_DEVICE_ATTR for a fan sysfs entries.
+ * - show actual speed
+ * - show/store minimum speed
+ * - show maximum speed
+ * - show safe speed
+ * - show/store target speed
+ * - show/store manual mode
+ */
+#define sysfs_fan_speeds_offset(offset) \
+static SENSOR_DEVICE_ATTR_2(fan##offset##_input, S_IRUGO, \
+ applesmc_show_fan_speed, NULL, 0, offset-1); \
+\
+static SENSOR_DEVICE_ATTR_2(fan##offset##_min, S_IRUGO | S_IWUSR, \
+ applesmc_show_fan_speed, applesmc_store_fan_speed, 1, offset-1); \
+\
+static SENSOR_DEVICE_ATTR_2(fan##offset##_max, S_IRUGO, \
+ applesmc_show_fan_speed, NULL, 2, offset-1); \
+\
+static SENSOR_DEVICE_ATTR_2(fan##offset##_safe, S_IRUGO, \
+ applesmc_show_fan_speed, NULL, 3, offset-1); \
+\
+static SENSOR_DEVICE_ATTR_2(fan##offset##_output, S_IRUGO | S_IWUSR, \
+ applesmc_show_fan_speed, applesmc_store_fan_speed, 4, offset-1); \
+\
+static SENSOR_DEVICE_ATTR(fan##offset##_manual, S_IRUGO | S_IWUSR, \
+ applesmc_show_fan_manual, applesmc_store_fan_manual, offset-1); \
+\
+static SENSOR_DEVICE_ATTR(fan##offset##_position, S_IRUGO, \
+ applesmc_show_fan_position, NULL, offset-1); \
+\
+static struct attribute *fan##offset##_attributes[] = { \
+ &sensor_dev_attr_fan##offset##_input.dev_attr.attr, \
+ &sensor_dev_attr_fan##offset##_min.dev_attr.attr, \
+ &sensor_dev_attr_fan##offset##_max.dev_attr.attr, \
+ &sensor_dev_attr_fan##offset##_safe.dev_attr.attr, \
+ &sensor_dev_attr_fan##offset##_output.dev_attr.attr, \
+ &sensor_dev_attr_fan##offset##_manual.dev_attr.attr, \
+ &sensor_dev_attr_fan##offset##_position.dev_attr.attr, \
+ NULL \
+};
+
+/*
+ * Create the needed functions for each fan using the macro defined above
+ * (2 fans are supported)
+ */
+sysfs_fan_speeds_offset(1);
+sysfs_fan_speeds_offset(2);
+
+static const struct attribute_group fan_attribute_groups[] = {
+ { .attrs = fan1_attributes },
+ { .attrs = fan2_attributes }
+};
+
+/*
+ * Temperature sensors sysfs entries.
+ */
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 1);
+static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 3);
+static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 4);
+static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 5);
+static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 6);
+static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 7);
+static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 8);
+static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 9);
+static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 10);
+static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 11);
+
+static struct attribute *temperature_attributes[] = {
+ &sensor_dev_attr_temp1_input.dev_attr.attr,
+ &sensor_dev_attr_temp2_input.dev_attr.attr,
+ &sensor_dev_attr_temp3_input.dev_attr.attr,
+ &sensor_dev_attr_temp4_input.dev_attr.attr,
+ &sensor_dev_attr_temp5_input.dev_attr.attr,
+ &sensor_dev_attr_temp6_input.dev_attr.attr,
+ &sensor_dev_attr_temp7_input.dev_attr.attr,
+ &sensor_dev_attr_temp8_input.dev_attr.attr,
+ &sensor_dev_attr_temp9_input.dev_attr.attr,
+ &sensor_dev_attr_temp10_input.dev_attr.attr,
+ &sensor_dev_attr_temp11_input.dev_attr.attr,
+ &sensor_dev_attr_temp12_input.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group temperature_attributes_group =
+ { .attrs = temperature_attributes };
+
+/* Module stuff */
+
+/*
+ * applesmc_dmi_match - found a match. return one, short-circuiting the hunt.
+ */
+static int applesmc_dmi_match(struct dmi_system_id *id)
+{
+ int i = 0;
+ struct dmi_match_data* dmi_data = id->driver_data;
+ printk(KERN_INFO "applesmc: %s detected:\n", id->ident);
+ applesmc_accelerometer = dmi_data->accelerometer;
+ printk(KERN_INFO "applesmc: - Model %s accelerometer\n",
+ applesmc_accelerometer ? "with" : "without");
+ applesmc_light = dmi_data->light;
+ printk(KERN_INFO "applesmc: - Model %s light sensors and backlight\n",
+ applesmc_light ? "with" : "without");
+
+ applesmc_temperature_set = dmi_data->temperature_set;
+ while (temperature_sensors_sets[applesmc_temperature_set][i] != NULL)
+ i++;
+ printk(KERN_INFO "applesmc: - Model with %d temperature sensors\n", i);
+ return 1;
+}
+
+/* Create accelerometer ressources */
+static int applesmc_create_accelerometer(void)
+{
+ int ret;
+
+ ret = sysfs_create_group(&pdev->dev.kobj,
+ &accelerometer_attributes_group);
+ if (ret)
+ goto out;
+
+ applesmc_idev = input_allocate_device();
+ if (!applesmc_idev) {
+ ret = -ENOMEM;
+ goto out_sysfs;
+ }
+
+ /* initial calibrate for the input device */
+ applesmc_calibrate();
+
+ /* initialize the input class */
+ applesmc_idev->name = "applesmc";
+ applesmc_idev->id.bustype = BUS_HOST;
+ applesmc_idev->cdev.dev = &pdev->dev;
+ applesmc_idev->evbit[0] = BIT(EV_ABS);
+ applesmc_idev->open = applesmc_idev_open;
+ applesmc_idev->close = applesmc_idev_close;
+ input_set_abs_params(applesmc_idev, ABS_X,
+ -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
+ input_set_abs_params(applesmc_idev, ABS_Y,
+ -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
+
+ ret = input_register_device(applesmc_idev);
+ if (ret)
+ goto out_idev;
+
+ /* start up our timer for the input device */
+ init_timer(&applesmc_timer);
+ applesmc_timer.function = applesmc_idev_poll;
+ applesmc_timer.expires = jiffies + APPLESMC_POLL_PERIOD;
+
+ return 0;
+
+out_idev:
+ input_free_device(applesmc_idev);
+
+out_sysfs:
+ sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
+
+out:
+ printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
+ return ret;
+}
+
+/* Release all ressources used by the accelerometer */
+static void applesmc_release_accelerometer(void)
+{
+ del_timer_sync(&applesmc_timer);
+ input_unregister_device(applesmc_idev);
+ sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
+}
+
+static __initdata struct dmi_match_data applesmc_dmi_data[] = {
+/* MacBook Pro: accelerometer, backlight and temperature set 0 */
+ { .accelerometer = 1, .light = 1, .temperature_set = 0 },
+/* MacBook: accelerometer and temperature set 0 */
+ { .accelerometer = 1, .light = 0, .temperature_set = 0 },
+/* MacBook: temperature set 1 */
+ { .accelerometer = 0, .light = 0, .temperature_set = 1 }
+};
+
+/* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
+ * So we need to put "Apple MacBook Pro" before "Apple MacBook". */
+static __initdata struct dmi_system_id applesmc_whitelist[] = {
+ { applesmc_dmi_match, "Apple MacBook Pro", {
+ DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
+ DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") },
+ (void*)&applesmc_dmi_data[0]},
+ { applesmc_dmi_match, "Apple MacBook", {
+ DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
+ DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") },
+ (void*)&applesmc_dmi_data[1]},
+ { applesmc_dmi_match, "Apple Macmini", {
+ DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
+ DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") },
+ (void*)&applesmc_dmi_data[2]},
+ { .ident = NULL }
+};
+
+static int __init applesmc_init(void)
+{
+ int ret;
+ int count;
+ int i;
+
+ mutex_init(&applesmc_lock);
+
+ if (!dmi_check_system(applesmc_whitelist)) {
+ printk(KERN_WARNING "applesmc: supported laptop not found!\n");
+ ret = -ENODEV;
+ goto out;
+ }
+
+ if (!request_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS,
+ "applesmc")) {
+ ret = -ENXIO;
+ goto out;
+ }
+
+ ret = platform_driver_register(&applesmc_driver);
+ if (ret)
+ goto out_region;
+
+ pdev = platform_device_register_simple("applesmc", -1, NULL, 0);
+ if (IS_ERR(pdev)) {
+ ret = PTR_ERR(pdev);
+ goto out_driver;
+ }
+
+ /* Create key enumeration sysfs files */
+ ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group);
+ if (ret)
+ goto out_device;
+
+ /* create fan files */
+ count = applesmc_get_fan_count();
+ if (count < 0) {
+ printk(KERN_ERR "applesmc: Cannot get the number of fans.\n");
+ } else {
+ printk(KERN_INFO "applesmc: %d fans found.\n", count);
+
+ switch (count) {
+ default:
+ printk(KERN_WARNING "applesmc: More than 2 fans found,"
+ " but at most 2 fans are supported"
+ " by the driver.\n");
+ case 2:
+ ret = sysfs_create_group(&pdev->dev.kobj,
+ &fan_attribute_groups[1]);
+ if (ret)
+ goto out_key_enumeration;
+ case 1:
+ ret = sysfs_create_group(&pdev->dev.kobj,
+ &fan_attribute_groups[0]);
+ if (ret)
+ goto out_fan_1;
+ case 0:
+ ;
+ }
+ }
+
+ for (i = 0;
+ temperature_sensors_sets[applesmc_temperature_set][i] != NULL;
+ i++) {
+ if (temperature_attributes[i] == NULL) {
+ printk(KERN_ERR "applesmc: More temperature sensors "
+ "in temperature_sensors_sets (at least %i)"
+ "than available sysfs files in "
+ "temperature_attributes (%i), please report "
+ "this bug.\n", i, i-1);
+ goto out_temperature;
+ }
+ ret = sysfs_create_file(&pdev->dev.kobj,
+ temperature_attributes[i]);
+ if (ret)
+ goto out_temperature;
+ }
+
+ if (applesmc_accelerometer) {
+ ret = applesmc_create_accelerometer();
+ if (ret)
+ goto out_temperature;
+ }
+
+ if (applesmc_light) {
+ /* Add light sensor file */
+ ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_light.attr);
+ if (ret)
+ goto out_accelerometer;
+
+ /* Create the workqueue */
+ applesmc_led_wq = create_singlethread_workqueue("applesmc-led");
+ if (!applesmc_led_wq) {
+ ret = -ENOMEM;
+ goto out_light_sysfs;
+ }
+
+ /* register as a led device */
+ ret = led_classdev_register(&pdev->dev, &applesmc_backlight);
+ if (ret < 0)
+ goto out_light_wq;
+ }
+
+ hwmon_class_dev = hwmon_device_register(&pdev->dev);
+ if (IS_ERR(hwmon_class_dev)) {
+ ret = PTR_ERR(hwmon_class_dev);
+ goto out_light_ledclass;
+ }
+
+ printk(KERN_INFO "applesmc: driver successfully loaded.\n");
+
+ return 0;
+
+out_light_ledclass:
+ if (applesmc_light)
+ led_classdev_unregister(&applesmc_backlight);
+out_light_wq:
+ if (applesmc_light)
+ destroy_workqueue(applesmc_led_wq);
+out_light_sysfs:
+ if (applesmc_light)
+ sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
+out_accelerometer:
+ if (applesmc_accelerometer)
+ applesmc_release_accelerometer();
+out_temperature:
+ sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
+ sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
+out_fan_1:
+ sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
+out_key_enumeration:
+ sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
+out_device:
+ platform_device_unregister(pdev);
+out_driver:
+ platform_driver_unregister(&applesmc_driver);
+out_region:
+ release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
+out:
+ printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
+ return ret;
+}
+
+static void __exit applesmc_exit(void)
+{
+ hwmon_device_unregister(hwmon_class_dev);
+ if (applesmc_light) {
+ led_classdev_unregister(&applesmc_backlight);
+ destroy_workqueue(applesmc_led_wq);
+ sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
+ }
+ if (applesmc_accelerometer)
+ applesmc_release_accelerometer();
+ sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
+ sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
+ sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
+ sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
+ platform_device_unregister(pdev);
+ platform_driver_unregister(&applesmc_driver);
+ release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
+
+ printk(KERN_INFO "applesmc: driver unloaded.\n");
+}
+
+module_init(applesmc_init);
+module_exit(applesmc_exit);
+
+MODULE_AUTHOR("Nicolas Boichat");
+MODULE_DESCRIPTION("Apple SMC");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c
index bf759ea..f82fa2d 100644
--- a/drivers/hwmon/hdaps.c
+++ b/drivers/hwmon/hdaps.c
@@ -30,10 +30,12 @@
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/kernel.h>
+#include <linux/mutex.h>
#include <linux/module.h>
#include <linux/timer.h>
#include <linux/dmi.h>
#include <linux/jiffies.h>
+
#include <asm/io.h>
#define HDAPS_LOW_PORT 0x1600 /* first port used by hdaps */
@@ -71,10 +73,10 @@
static int rest_x;
static int rest_y;
-static DECLARE_MUTEX(hdaps_sem);
+static DEFINE_MUTEX(hdaps_mtx);
/*
- * __get_latch - Get the value from a given port. Callers must hold hdaps_sem.
+ * __get_latch - Get the value from a given port. Callers must hold hdaps_mtx.
*/
static inline u8 __get_latch(u16 port)
{
@@ -83,7 +85,7 @@
/*
* __check_latch - Check a port latch for a given value. Returns zero if the
- * port contains the given value. Callers must hold hdaps_sem.
+ * port contains the given value. Callers must hold hdaps_mtx.
*/
static inline int __check_latch(u16 port, u8 val)
{
@@ -94,7 +96,7 @@
/*
* __wait_latch - Wait up to 100us for a port latch to get a certain value,
- * returning zero if the value is obtained. Callers must hold hdaps_sem.
+ * returning zero if the value is obtained. Callers must hold hdaps_mtx.
*/
static int __wait_latch(u16 port, u8 val)
{
@@ -111,7 +113,7 @@
/*
* __device_refresh - request a refresh from the accelerometer. Does not wait
- * for refresh to complete. Callers must hold hdaps_sem.
+ * for refresh to complete. Callers must hold hdaps_mtx.
*/
static void __device_refresh(void)
{
@@ -125,7 +127,7 @@
/*
* __device_refresh_sync - request a synchronous refresh from the
* accelerometer. We wait for the refresh to complete. Returns zero if
- * successful and nonzero on error. Callers must hold hdaps_sem.
+ * successful and nonzero on error. Callers must hold hdaps_mtx.
*/
static int __device_refresh_sync(void)
{
@@ -135,7 +137,7 @@
/*
* __device_complete - indicate to the accelerometer that we are done reading
- * data, and then initiate an async refresh. Callers must hold hdaps_sem.
+ * data, and then initiate an async refresh. Callers must hold hdaps_mtx.
*/
static inline void __device_complete(void)
{
@@ -153,7 +155,7 @@
{
int ret;
- down(&hdaps_sem);
+ mutex_lock(&hdaps_mtx);
/* do a sync refresh -- we need to be sure that we read fresh data */
ret = __device_refresh_sync();
@@ -164,7 +166,7 @@
__device_complete();
out:
- up(&hdaps_sem);
+ mutex_unlock(&hdaps_mtx);
return ret;
}
@@ -199,9 +201,9 @@
{
int ret;
- down(&hdaps_sem);
+ mutex_lock(&hdaps_mtx);
ret = __hdaps_read_pair(port1, port2, val1, val2);
- up(&hdaps_sem);
+ mutex_unlock(&hdaps_mtx);
return ret;
}
@@ -214,7 +216,7 @@
{
int total, ret = -ENXIO;
- down(&hdaps_sem);
+ mutex_lock(&hdaps_mtx);
outb(0x13, 0x1610);
outb(0x01, 0x161f);
@@ -280,7 +282,7 @@
}
out:
- up(&hdaps_sem);
+ mutex_unlock(&hdaps_mtx);
return ret;
}
@@ -314,7 +316,7 @@
};
/*
- * hdaps_calibrate - Set our "resting" values. Callers must hold hdaps_sem.
+ * hdaps_calibrate - Set our "resting" values. Callers must hold hdaps_mtx.
*/
static void hdaps_calibrate(void)
{
@@ -326,7 +328,7 @@
int x, y;
/* Cannot sleep. Try nonblockingly. If we fail, try again later. */
- if (down_trylock(&hdaps_sem)) {
+ if (mutex_trylock(&hdaps_mtx)) {
mod_timer(&hdaps_timer,jiffies + HDAPS_POLL_PERIOD);
return;
}
@@ -341,7 +343,7 @@
mod_timer(&hdaps_timer, jiffies + HDAPS_POLL_PERIOD);
out:
- up(&hdaps_sem);
+ mutex_unlock(&hdaps_mtx);
}
@@ -421,9 +423,9 @@
struct device_attribute *attr,
const char *buf, size_t count)
{
- down(&hdaps_sem);
+ mutex_lock(&hdaps_mtx);
hdaps_calibrate();
- up(&hdaps_sem);
+ mutex_unlock(&hdaps_mtx);
return count;
}
diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c
index 8c95370..039a07f 100644
--- a/drivers/i2c/busses/i2c-parport.c
+++ b/drivers/i2c/busses/i2c-parport.c
@@ -175,6 +175,7 @@
}
adapter->algo_data.data = port;
adapter->adapter.algo_data = &adapter->algo_data;
+ adapter->adapter.dev.parent = port->physport->dev;
if (parport_claim_or_block(adapter->pdev) < 0) {
printk(KERN_ERR "i2c-parport: Could not claim parallel port\n");
diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c
index 0db56e7..0d6bd4f 100644
--- a/drivers/i2c/busses/scx200_acb.c
+++ b/drivers/i2c/busses/scx200_acb.c
@@ -28,7 +28,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/i2c.h>
-#include <linux/smp_lock.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/mutex.h>
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index cb4fa9b..e7a7097 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -30,7 +30,6 @@
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/i2c.h>
diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c
index 2da5cbb..2cdd629 100644
--- a/drivers/ide/pci/pdc202xx_new.c
+++ b/drivers/ide/pci/pdc202xx_new.c
@@ -395,7 +395,7 @@
unsigned int class_rev = 0;
u8 conf;
- if (np == NULL || !device_is_compatible(np, "kiwi-root"))
+ if (np == NULL || !of_device_is_compatible(np, "kiwi-root"))
return;
pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev);
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index 071a030..a49ebe4 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -1157,32 +1157,32 @@
pmif->cable_80 = 0;
pmif->broken_dma = pmif->broken_dma_warn = 0;
- if (device_is_compatible(np, "shasta-ata"))
+ if (of_device_is_compatible(np, "shasta-ata"))
pmif->kind = controller_sh_ata6;
- else if (device_is_compatible(np, "kauai-ata"))
+ else if (of_device_is_compatible(np, "kauai-ata"))
pmif->kind = controller_un_ata6;
- else if (device_is_compatible(np, "K2-UATA"))
+ else if (of_device_is_compatible(np, "K2-UATA"))
pmif->kind = controller_k2_ata6;
- else if (device_is_compatible(np, "keylargo-ata")) {
+ else if (of_device_is_compatible(np, "keylargo-ata")) {
if (strcmp(np->name, "ata-4") == 0)
pmif->kind = controller_kl_ata4;
else
pmif->kind = controller_kl_ata3;
- } else if (device_is_compatible(np, "heathrow-ata"))
+ } else if (of_device_is_compatible(np, "heathrow-ata"))
pmif->kind = controller_heathrow;
else {
pmif->kind = controller_ohare;
pmif->broken_dma = 1;
}
- bidp = get_property(np, "AAPL,bus-id", NULL);
+ bidp = of_get_property(np, "AAPL,bus-id", NULL);
pmif->aapl_bus_id = bidp ? *bidp : 0;
/* Get cable type from device-tree */
if (pmif->kind == controller_kl_ata4 || pmif->kind == controller_un_ata6
|| pmif->kind == controller_k2_ata6
|| pmif->kind == controller_sh_ata6) {
- const char* cable = get_property(np, "cable-type", NULL);
+ const char* cable = of_get_property(np, "cable-type", NULL);
if (cable && !strncmp(cable, "80-", 3))
pmif->cable_80 = 1;
}
@@ -1190,8 +1190,8 @@
* they have a 80 conductor cable, this seem to be always the case unless
* the user mucked around
*/
- if (device_is_compatible(np, "K2-UATA") ||
- device_is_compatible(np, "shasta-ata"))
+ if (of_device_is_compatible(np, "K2-UATA") ||
+ of_device_is_compatible(np, "shasta-ata"))
pmif->cable_80 = 1;
/* On Kauai-type controllers, we make sure the FCR is correct */
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
index 026e38f..2081413 100644
--- a/drivers/ieee1394/dv1394.c
+++ b/drivers/ieee1394/dv1394.c
@@ -94,7 +94,6 @@
#include <linux/pci.h>
#include <linux/fs.h>
#include <linux/poll.h>
-#include <linux/smp_lock.h>
#include <linux/mutex.h>
#include <linux/bitops.h>
#include <asm/byteorder.h>
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index c6aefd9..d382500 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -35,7 +35,6 @@
#include <linux/poll.h>
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/vmalloc.h>
#include <linux/cdev.h>
diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c
index 95ca26d..87ebd08 100644
--- a/drivers/ieee1394/video1394.c
+++ b/drivers/ieee1394/video1394.c
@@ -39,7 +39,6 @@
#include <linux/pci.h>
#include <linux/fs.h>
#include <linux/poll.h>
-#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <linux/bitops.h>
#include <linux/types.h>
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index 2d37054..fe90e74 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -570,7 +570,7 @@
struct ib_pd *ibpd;
int ret;
- handle = get_property(dev->ofdev.node, "ibm,hca-handle", NULL);
+ handle = of_get_property(dev->ofdev.node, "ibm,hca-handle", NULL);
if (!handle) {
ehca_gen_err("Cannot get eHCA handle for adapter: %s.",
dev->ofdev.node->full_name);
diff --git a/drivers/infiniband/hw/ipath/ipath_fs.c b/drivers/infiniband/hw/ipath/ipath_fs.c
index 036ed1e..ebd5c7b 100644
--- a/drivers/infiniband/hw/ipath/ipath_fs.c
+++ b/drivers/infiniband/hw/ipath/ipath_fs.c
@@ -523,7 +523,7 @@
int ret;
static struct tree_descr files[] = {
- [1] = {"atomic_stats", &atomic_stats_ops, S_IRUGO},
+ [2] = {"atomic_stats", &atomic_stats_ops, S_IRUGO},
{""},
};
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index 89d6008..3702e23 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -35,7 +35,6 @@
#include <asm/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <linux/version.h>
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
index 9623231..0e9b695 100644
--- a/drivers/input/Kconfig
+++ b/drivers/input/Kconfig
@@ -153,6 +153,8 @@
source "drivers/input/joystick/Kconfig"
+source "drivers/input/tablet/Kconfig"
+
source "drivers/input/touchscreen/Kconfig"
source "drivers/input/misc/Kconfig"
diff --git a/drivers/input/Makefile b/drivers/input/Makefile
index b4cd106..8a2dd98 100644
--- a/drivers/input/Makefile
+++ b/drivers/input/Makefile
@@ -18,6 +18,7 @@
obj-$(CONFIG_INPUT_KEYBOARD) += keyboard/
obj-$(CONFIG_INPUT_MOUSE) += mouse/
obj-$(CONFIG_INPUT_JOYSTICK) += joystick/
+obj-$(CONFIG_INPUT_TABLET) += tablet/
obj-$(CONFIG_INPUT_TOUCHSCREEN) += touchscreen/
obj-$(CONFIG_INPUT_MISC) += misc/
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 1f6fcec..55a7259 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -18,7 +18,6 @@
#include <linux/init.h>
#include <linux/input.h>
#include <linux/major.h>
-#include <linux/smp_lock.h>
#include <linux/device.h>
#include <linux/compat.h>
@@ -512,7 +511,7 @@
if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0,0))) {
- long *bits;
+ unsigned long *bits;
int len;
switch (_IOC_NR(cmd) & EV_MAX) {
@@ -557,7 +556,7 @@
if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) {
- int t = _IOC_NR(cmd) & ABS_MAX;
+ t = _IOC_NR(cmd) & ABS_MAX;
abs.value = dev->abs[t];
abs.minimum = dev->absmin[t];
@@ -577,7 +576,7 @@
if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) {
- int t = _IOC_NR(cmd) & ABS_MAX;
+ t = _IOC_NR(cmd) & ABS_MAX;
if (copy_from_user(&abs, p, sizeof(struct input_absinfo)))
return -EFAULT;
diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c
index 783b341..eebc724 100644
--- a/drivers/input/ff-core.c
+++ b/drivers/input/ff-core.c
@@ -281,7 +281,8 @@
break;
default:
- ff->playback(dev, code, value);
+ if (check_effect_access(ff, code, NULL) == 0)
+ ff->playback(dev, code, value);
break;
}
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 915e9ab..ccd8aba 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -11,7 +11,6 @@
*/
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/input.h>
#include <linux/module.h>
#include <linux/random.h>
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index 9bcc542..06f0541 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -24,7 +24,6 @@
#include <linux/module.h>
#include <linux/poll.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/device.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig
index 2712634..82f563e 100644
--- a/drivers/input/joystick/Kconfig
+++ b/drivers/input/joystick/Kconfig
@@ -2,7 +2,7 @@
# Joystick driver configuration
#
menuconfig INPUT_JOYSTICK
- bool "Joysticks"
+ bool "Joysticks/Gamepads"
help
If you have a joystick, 6dof controller, gamepad, steering wheel,
weapon control system or something like that you can say Y here
@@ -196,7 +196,7 @@
config JOYSTICK_DB9
tristate "Multisystem, Sega Genesis, Saturn joysticks and gamepads"
depends on PARPORT
- ---help---
+ help
Say Y here if you have a Sega Master System gamepad, Sega Genesis
gamepad, Sega Saturn gamepad, or a Multisystem -- Atari, Amiga,
Commodore, Amstrad CPC joystick connected to your parallel port.
@@ -253,4 +253,18 @@
To compile this driver as a module, choose M here: the
module will be called joydump.
+config JOYSTICK_XPAD
+ tristate "X-Box gamepad support"
+ select USB
+ help
+ Say Y here if you want to use the X-Box pad with your computer.
+ Make sure to say Y to "Joystick support" (CONFIG_INPUT_JOYDEV)
+ and/or "Event interface support" (CONFIG_INPUT_EVDEV) as well.
+
+ For information about how to connect the X-Box pad to USB, see
+ <file:Documentation/input/xpad.txt>.
+
+ To compile this driver as a module, choose M here: the
+ module will be called xpad.
+
endif
diff --git a/drivers/input/joystick/Makefile b/drivers/input/joystick/Makefile
index 5231f6f..e855abb 100644
--- a/drivers/input/joystick/Makefile
+++ b/drivers/input/joystick/Makefile
@@ -26,5 +26,6 @@
obj-$(CONFIG_JOYSTICK_TURBOGRAFX) += turbografx.o
obj-$(CONFIG_JOYSTICK_TWIDJOY) += twidjoy.o
obj-$(CONFIG_JOYSTICK_WARRIOR) += warrior.o
+obj-$(CONFIG_JOYSTICK_XPAD) += xpad.o
obj-$(CONFIG_JOYSTICK_IFORCE) += iforce/
diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c
index 1c1afb5..bdd157c 100644
--- a/drivers/input/joystick/analog.c
+++ b/drivers/input/joystick/analog.c
@@ -53,7 +53,7 @@
#define ANALOG_PORTS 16
static char *js[ANALOG_PORTS];
-static int js_nargs;
+static unsigned int js_nargs;
static int analog_options[ANALOG_PORTS];
module_param_array_named(map, js, charp, &js_nargs, 0);
MODULE_PARM_DESC(map, "Describes analog joysticks type/capabilities");
diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c
index c27593b..86ad102 100644
--- a/drivers/input/joystick/db9.c
+++ b/drivers/input/joystick/db9.c
@@ -46,17 +46,17 @@
struct db9_config {
int args[2];
- int nargs;
+ unsigned int nargs;
};
#define DB9_MAX_PORTS 3
-static struct db9_config db9[DB9_MAX_PORTS] __initdata;
+static struct db9_config db9_cfg[DB9_MAX_PORTS] __initdata;
-module_param_array_named(dev, db9[0].args, int, &db9[0].nargs, 0);
+module_param_array_named(dev, db9_cfg[0].args, int, &db9_cfg[0].nargs, 0);
MODULE_PARM_DESC(dev, "Describes first attached device (<parport#>,<type>)");
-module_param_array_named(dev2, db9[1].args, int, &db9[0].nargs, 0);
+module_param_array_named(dev2, db9_cfg[1].args, int, &db9_cfg[0].nargs, 0);
MODULE_PARM_DESC(dev2, "Describes second attached device (<parport#>,<type>)");
-module_param_array_named(dev3, db9[2].args, int, &db9[2].nargs, 0);
+module_param_array_named(dev3, db9_cfg[2].args, int, &db9_cfg[2].nargs, 0);
MODULE_PARM_DESC(dev3, "Describes third attached device (<parport#>,<type>)");
#define DB9_ARG_PARPORT 0
@@ -680,17 +680,17 @@
int err = 0;
for (i = 0; i < DB9_MAX_PORTS; i++) {
- if (db9[i].nargs == 0 || db9[i].args[DB9_ARG_PARPORT] < 0)
+ if (db9_cfg[i].nargs == 0 || db9_cfg[i].args[DB9_ARG_PARPORT] < 0)
continue;
- if (db9[i].nargs < 2) {
+ if (db9_cfg[i].nargs < 2) {
printk(KERN_ERR "db9.c: Device type must be specified.\n");
err = -EINVAL;
break;
}
- db9_base[i] = db9_probe(db9[i].args[DB9_ARG_PARPORT],
- db9[i].args[DB9_ARG_MODE]);
+ db9_base[i] = db9_probe(db9_cfg[i].args[DB9_ARG_PARPORT],
+ db9_cfg[i].args[DB9_ARG_MODE]);
if (IS_ERR(db9_base[i])) {
err = PTR_ERR(db9_base[i]);
break;
diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c
index c71b58f..1a452e0 100644
--- a/drivers/input/joystick/gamecon.c
+++ b/drivers/input/joystick/gamecon.c
@@ -48,16 +48,16 @@
struct gc_config {
int args[GC_MAX_DEVICES + 1];
- int nargs;
+ unsigned int nargs;
};
-static struct gc_config gc[GC_MAX_PORTS] __initdata;
+static struct gc_config gc_cfg[GC_MAX_PORTS] __initdata;
-module_param_array_named(map, gc[0].args, int, &gc[0].nargs, 0);
+module_param_array_named(map, gc_cfg[0].args, int, &gc_cfg[0].nargs, 0);
MODULE_PARM_DESC(map, "Describes first set of devices (<parport#>,<pad1>,<pad2>,..<pad5>)");
-module_param_array_named(map2, gc[1].args, int, &gc[1].nargs, 0);
+module_param_array_named(map2, gc_cfg[1].args, int, &gc_cfg[1].nargs, 0);
MODULE_PARM_DESC(map2, "Describes second set of devices");
-module_param_array_named(map3, gc[2].args, int, &gc[2].nargs, 0);
+module_param_array_named(map3, gc_cfg[2].args, int, &gc_cfg[2].nargs, 0);
MODULE_PARM_DESC(map3, "Describes third set of devices");
/* see also gs_psx_delay parameter in PSX support section */
@@ -810,16 +810,17 @@
int err = 0;
for (i = 0; i < GC_MAX_PORTS; i++) {
- if (gc[i].nargs == 0 || gc[i].args[0] < 0)
+ if (gc_cfg[i].nargs == 0 || gc_cfg[i].args[0] < 0)
continue;
- if (gc[i].nargs < 2) {
+ if (gc_cfg[i].nargs < 2) {
printk(KERN_ERR "gamecon.c: at least one device must be specified\n");
err = -EINVAL;
break;
}
- gc_base[i] = gc_probe(gc[i].args[0], gc[i].args + 1, gc[i].nargs - 1);
+ gc_base[i] = gc_probe(gc_cfg[i].args[0],
+ gc_cfg[i].args + 1, gc_cfg[i].nargs - 1);
if (IS_ERR(gc_base[i])) {
err = PTR_ERR(gc_base[i]);
break;
diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h
index dadcf4f..40a853a 100644
--- a/drivers/input/joystick/iforce/iforce.h
+++ b/drivers/input/joystick/iforce/iforce.h
@@ -124,7 +124,7 @@
/* Buffer used for asynchronous sending of bytes to the device */
struct circ_buf xmit;
unsigned char xmit_data[XMIT_SIZE];
- long xmit_flags[1];
+ unsigned long xmit_flags[1];
/* Force Feedback */
wait_queue_head_t wait;
diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c
index 0f2c608..8381c6f 100644
--- a/drivers/input/joystick/turbografx.c
+++ b/drivers/input/joystick/turbografx.c
@@ -48,16 +48,16 @@
struct tgfx_config {
int args[TGFX_MAX_DEVICES + 1];
- int nargs;
+ unsigned int nargs;
};
-static struct tgfx_config tgfx[TGFX_MAX_PORTS] __initdata;
+static struct tgfx_config tgfx_cfg[TGFX_MAX_PORTS] __initdata;
-module_param_array_named(map, tgfx[0].args, int, &tgfx[0].nargs, 0);
+module_param_array_named(map, tgfx_cfg[0].args, int, &tgfx_cfg[0].nargs, 0);
MODULE_PARM_DESC(map, "Describes first set of devices (<parport#>,<js1>,<js2>,..<js7>");
-module_param_array_named(map2, tgfx[1].args, int, &tgfx[1].nargs, 0);
+module_param_array_named(map2, tgfx_cfg[1].args, int, &tgfx_cfg[1].nargs, 0);
MODULE_PARM_DESC(map2, "Describes second set of devices");
-module_param_array_named(map3, tgfx[2].args, int, &tgfx[2].nargs, 0);
+module_param_array_named(map3, tgfx_cfg[2].args, int, &tgfx_cfg[2].nargs, 0);
MODULE_PARM_DESC(map3, "Describes third set of devices");
#define TGFX_REFRESH_TIME HZ/100 /* 10 ms */
@@ -283,16 +283,18 @@
int err = 0;
for (i = 0; i < TGFX_MAX_PORTS; i++) {
- if (tgfx[i].nargs == 0 || tgfx[i].args[0] < 0)
+ if (tgfx_cfg[i].nargs == 0 || tgfx_cfg[i].args[0] < 0)
continue;
- if (tgfx[i].nargs < 2) {
+ if (tgfx_cfg[i].nargs < 2) {
printk(KERN_ERR "turbografx.c: at least one joystick must be specified\n");
err = -EINVAL;
break;
}
- tgfx_base[i] = tgfx_probe(tgfx[i].args[0], tgfx[i].args + 1, tgfx[i].nargs - 1);
+ tgfx_base[i] = tgfx_probe(tgfx_cfg[i].args[0],
+ tgfx_cfg[i].args + 1,
+ tgfx_cfg[i].nargs - 1);
if (IS_ERR(tgfx_base[i])) {
err = PTR_ERR(tgfx_base[i]);
break;
diff --git a/drivers/usb/input/xpad.c b/drivers/input/joystick/xpad.c
similarity index 99%
rename from drivers/usb/input/xpad.c
rename to drivers/input/joystick/xpad.c
index 7357239..8c8cd95 100644
--- a/drivers/usb/input/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -74,7 +74,6 @@
#include <linux/stat.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
-#include <linux/smp_lock.h>
#include <linux/usb/input.h>
#define DRIVER_VERSION "v0.0.6"
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 9f42e4d..bd707b8 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -226,6 +226,7 @@
config KEYBOARD_AAED2000
tristate "AAED-2000 keyboard"
depends on MACH_AAED2000
+ select INPUT_POLLDEV
default y
help
Say Y here to enable the keyboard on the Agilent AAED-2000
diff --git a/drivers/input/keyboard/aaed2000_kbd.c b/drivers/input/keyboard/aaed2000_kbd.c
index 3a37505..63d6ead 100644
--- a/drivers/input/keyboard/aaed2000_kbd.c
+++ b/drivers/input/keyboard/aaed2000_kbd.c
@@ -14,12 +14,11 @@
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/init.h>
-#include <linux/input.h>
+#include <linux/input-polldev.h>
#include <linux/interrupt.h>
#include <linux/jiffies.h>
#include <linux/module.h>
#include <linux/slab.h>
-#include <linux/workqueue.h>
#include <asm/arch/hardware.h>
#include <asm/arch/aaed2000.h>
@@ -46,8 +45,7 @@
struct aaedkbd {
unsigned char keycode[ARRAY_SIZE(aaedkbd_keycode)];
- struct input_dev *input;
- struct work_struct workq;
+ struct input_polled_dev *poll_dev;
int kbdscan_state[KB_COLS];
int kbdscan_count[KB_COLS];
};
@@ -64,14 +62,15 @@
scancode = SCANCODE(row, col);
pressed = rowd & KB_ROWMASK(row);
- input_report_key(aaedkbd->input, aaedkbd->keycode[scancode], pressed);
+ input_report_key(aaedkbd->poll_dev->input,
+ aaedkbd->keycode[scancode], pressed);
}
}
/* Scan the hardware keyboard and push any changes up through the input layer */
-static void aaedkbd_work(void *data)
+static void aaedkbd_poll(struct input_polled_dev *dev)
{
- struct aaedkbd *aaedkbd = data;
+ struct aaedkbd *aaedkbd = dev->private;
unsigned int col, rowd;
col = 0;
@@ -90,51 +89,34 @@
} while (col < KB_COLS);
AAEC_GPIO_KSCAN = 0x07;
- input_sync(aaedkbd->input);
-
- schedule_delayed_work(&aaedkbd->workq, msecs_to_jiffies(SCAN_INTERVAL));
-}
-
-static int aaedkbd_open(struct input_dev *indev)
-{
- struct aaedkbd *aaedkbd = input_get_drvdata(indev);
-
- schedule_delayed_work(&aaedkbd->workq, msecs_to_jiffies(SCAN_INTERVAL));
-
- return 0;
-}
-
-static void aaedkbd_close(struct input_dev *indev)
-{
- struct aaedkbd *aaedkbd = input_get_drvdata(indev);
-
- cancel_delayed_work(&aaedkbd->workq);
- flush_scheduled_work();
+ input_sync(dev->input);
}
static int __devinit aaedkbd_probe(struct platform_device *pdev)
{
struct aaedkbd *aaedkbd;
+ struct input_polled_dev *poll_dev;
struct input_dev *input_dev;
int i;
int error;
aaedkbd = kzalloc(sizeof(struct aaedkbd), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!aaedkbd || !input_dev) {
+ poll_dev = input_allocate_polled_device();
+ if (!aaedkbd || !poll_dev) {
error = -ENOMEM;
goto fail;
}
platform_set_drvdata(pdev, aaedkbd);
- aaedkbd->input = input_dev;
-
- /* Init keyboard rescan workqueue */
- INIT_WORK(&aaedkbd->workq, aaedkbd_work, aaedkbd);
-
+ aaedkbd->poll_dev = poll_dev;
memcpy(aaedkbd->keycode, aaedkbd_keycode, sizeof(aaedkbd->keycode));
+ poll_dev->private = aaedkbd;
+ poll_dev->poll = aaedkbd_poll;
+ poll_dev->poll_interval = SCAN_INTERVAL;
+
+ input_dev = poll_dev->input;
input_dev->name = "AAED-2000 Keyboard";
input_dev->phys = "aaedkbd/input0";
input_dev->id.bustype = BUS_HOST;
@@ -143,8 +125,6 @@
input_dev->id.version = 0x0100;
input_dev->dev.parent = &pdev->dev;
- input_set_drvdata(input_dev, aaedkbd);
-
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
input_dev->keycode = aaedkbd->keycode;
input_dev->keycodesize = sizeof(unsigned char);
@@ -154,17 +134,14 @@
set_bit(aaedkbd->keycode[i], input_dev->keybit);
clear_bit(0, input_dev->keybit);
- input_dev->open = aaedkbd_open;
- input_dev->close = aaedkbd_close;
-
- error = input_register_device(aaedkbd->input);
+ error = input_register_polled_device(aaedkbd->poll_dev);
if (error)
goto fail;
return 0;
fail: kfree(aaedkbd);
- input_free_device(input_dev);
+ input_free_polled_device(poll_dev);
return error;
}
@@ -172,7 +149,8 @@
{
struct aaedkbd *aaedkbd = platform_get_drvdata(pdev);
- input_unregister_device(aaedkbd->input);
+ input_unregister_polled_device(aaedkbd->poll_dev);
+ input_free_polled_device(aaedkbd->poll_dev);
kfree(aaedkbd);
return 0;
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 1d0d3e7..6013ace 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -40,6 +40,18 @@
tristate "M68k Beeper support"
depends on M68K
+config INPUT_IXP4XX_BEEPER
+ tristate "IXP4XX Beeper support"
+ depends on ARCH_IXP4XX
+ help
+ If you say yes here, you can connect a beeper to the
+ ixp4xx gpio pins. This is used by the LinkSys NSLU2.
+
+ If unsure, say Y.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ixp4xx-beeper.
+
config INPUT_COBALT_BTNS
tristate "Cobalt button interface"
depends on MIPS_COBALT
@@ -70,17 +82,79 @@
To compile this driver as a module, choose M here: the module will
be called atlas_btns.
-config INPUT_IXP4XX_BEEPER
- tristate "IXP4XX Beeper support"
- depends on ARCH_IXP4XX
+config INPUT_ATI_REMOTE
+ tristate "ATI / X10 USB RF remote control"
+ select USB
help
- If you say yes here, you can connect a beeper to the
- ixp4xx gpio pins. This is used by the LinkSys NSLU2.
+ Say Y here if you want to use an ATI or X10 "Lola" USB remote control.
+ These are RF remotes with USB receivers.
+ The ATI remote comes with many of ATI's All-In-Wonder video cards.
+ The X10 "Lola" remote is available at:
+ <http://www.x10.com/products/lola_sg1.htm>
+ This driver provides mouse pointer, left and right mouse buttons,
+ and maps all the other remote buttons to keypress events.
- If unsure, say Y.
+ To compile this driver as a module, choose M here: the module will be
+ called ati_remote.
+
+config INPUT_ATI_REMOTE2
+ tristate "ATI / Philips USB RF remote control"
+ select USB
+ help
+ Say Y here if you want to use an ATI or Philips USB RF remote control.
+ These are RF remotes with USB receivers.
+ ATI Remote Wonder II comes with some ATI's All-In-Wonder video cards
+ and is also available as a separate product.
+ This driver provides mouse pointer, left and right mouse buttons,
+ and maps all the other remote buttons to keypress events.
+
+ To compile this driver as a module, choose M here: the module will be
+ called ati_remote2.
+
+config INPUT_KEYSPAN_REMOTE
+ tristate "Keyspan DMR USB remote control (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
+ select USB
+ help
+ Say Y here if you want to use a Keyspan DMR USB remote control.
+ Currently only the UIA-11 type of receiver has been tested. The tag
+ on the receiver that connects to the USB port should have a P/N that
+ will tell you what type of DMR you have. The UIA-10 type is not
+ supported at this time. This driver maps all buttons to keypress
+ events.
+
+ To compile this driver as a module, choose M here: the module will
+ be called keyspan_remote.
+
+config INPUT_POWERMATE
+ tristate "Griffin PowerMate and Contour Jog support"
+ select USB
+ help
+ Say Y here if you want to use Griffin PowerMate or Contour Jog devices.
+ These are aluminum dials which can measure clockwise and anticlockwise
+ rotation. The dial also acts as a pushbutton. The base contains an LED
+ which can be instructed to pulse or to switch to a particular intensity.
+
+ You can download userspace tools from
+ <http://sowerbutts.com/powermate/>.
To compile this driver as a module, choose M here: the
- module will be called ixp4xx-beeper.
+ module will be called powermate.
+
+config INPUT_YEALINK
+ tristate "Yealink usb-p1k voip phone"
+ depends EXPERIMENTAL
+ select USB
+ help
+ Say Y here if you want to enable keyboard and LCD functions of the
+ Yealink usb-p1k usb phones. The audio part is enabled by the generic
+ usb sound driver, so you might want to enable that as well.
+
+ For information about how to use these additional functions, see
+ <file:Documentation/input/yealink.txt>.
+
+ To compile this driver as a module, choose M here: the module will be
+ called yealink.
config INPUT_UINPUT
tristate "User level driver support"
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 21e3cca..8b2f779 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -8,9 +8,14 @@
obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o
obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o
obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o
-obj-$(CONFIG_INPUT_UINPUT) += uinput.o
+obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o
obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o
obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o
obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o
+obj-$(CONFIG_INPUT_ATI_REMOTE) += ati_remote.o
+obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o
+obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o
+obj-$(CONFIG_INPUT_POWERMATE) += powermate.o
+obj-$(CONFIG_INPUT_YEALINK) += yealink.o
obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o
-obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o
+obj-$(CONFIG_INPUT_UINPUT) += uinput.o
diff --git a/drivers/usb/input/ati_remote.c b/drivers/input/misc/ati_remote.c
similarity index 100%
rename from drivers/usb/input/ati_remote.c
rename to drivers/input/misc/ati_remote.c
diff --git a/drivers/usb/input/ati_remote2.c b/drivers/input/misc/ati_remote2.c
similarity index 98%
rename from drivers/usb/input/ati_remote2.c
rename to drivers/input/misc/ati_remote2.c
index a9032aa..1031543 100644
--- a/drivers/usb/input/ati_remote2.c
+++ b/drivers/input/misc/ati_remote2.c
@@ -405,9 +405,7 @@
for (i = 0; i < 2; i++) {
usb_free_urb(ar2->urb[i]);
-
- if (ar2->buf[i])
- usb_buffer_free(ar2->udev, 4, ar2->buf[i], ar2->buf_dma[i]);
+ usb_buffer_free(ar2->udev, 4, ar2->buf[i], ar2->buf_dma[i]);
}
}
diff --git a/drivers/usb/input/keyspan_remote.c b/drivers/input/misc/keyspan_remote.c
similarity index 100%
rename from drivers/usb/input/keyspan_remote.c
rename to drivers/input/misc/keyspan_remote.c
diff --git a/drivers/usb/input/map_to_7segment.h b/drivers/input/misc/map_to_7segment.h
similarity index 100%
rename from drivers/usb/input/map_to_7segment.h
rename to drivers/input/misc/map_to_7segment.h
diff --git a/drivers/usb/input/powermate.c b/drivers/input/misc/powermate.c
similarity index 98%
rename from drivers/usb/input/powermate.c
rename to drivers/input/misc/powermate.c
index 4f93a76..448a470 100644
--- a/drivers/usb/input/powermate.c
+++ b/drivers/input/misc/powermate.c
@@ -291,12 +291,10 @@
static void powermate_free_buffers(struct usb_device *udev, struct powermate_device *pm)
{
- if (pm->data)
- usb_buffer_free(udev, POWERMATE_PAYLOAD_SIZE_MAX,
- pm->data, pm->data_dma);
- if (pm->configcr)
- usb_buffer_free(udev, sizeof(*(pm->configcr)),
- pm->configcr, pm->configcr_dma);
+ usb_buffer_free(udev, POWERMATE_PAYLOAD_SIZE_MAX,
+ pm->data, pm->data_dma);
+ usb_buffer_free(udev, sizeof(*(pm->configcr)),
+ pm->configcr, pm->configcr_dma);
}
/* Called whenever a USB device matching one in our supported devices table is connected */
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index 031467e..a56ad4b 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -33,7 +33,6 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/input.h>
#include <linux/smp_lock.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
diff --git a/drivers/usb/input/yealink.c b/drivers/input/misc/yealink.c
similarity index 97%
rename from drivers/usb/input/yealink.c
rename to drivers/input/misc/yealink.c
index c54f1a5..ab15880 100644
--- a/drivers/usb/input/yealink.c
+++ b/drivers/input/misc/yealink.c
@@ -29,7 +29,7 @@
* This driver is based on:
* - the usbb2k-api http://savannah.nongnu.org/projects/usbb2k-api/
* - information from http://memeteau.free.fr/usbb2k
- * - the xpad-driver drivers/usb/input/xpad.c
+ * - the xpad-driver drivers/input/joystick/xpad.c
*
* Thanks to:
* - Olivier Vandorpe, for providing the usbb2k-api.
@@ -818,18 +818,17 @@
else
input_unregister_device(yld->idev);
}
- if (yld->ctl_req)
- usb_buffer_free(yld->udev, sizeof(*(yld->ctl_req)),
- yld->ctl_req, yld->ctl_req_dma);
- if (yld->ctl_data)
- usb_buffer_free(yld->udev, USB_PKT_LEN,
- yld->ctl_data, yld->ctl_dma);
- if (yld->irq_data)
- usb_buffer_free(yld->udev, USB_PKT_LEN,
- yld->irq_data, yld->irq_dma);
- usb_free_urb(yld->urb_irq); /* parameter validation in core/urb */
- usb_free_urb(yld->urb_ctl); /* parameter validation in core/urb */
+ usb_free_urb(yld->urb_irq);
+ usb_free_urb(yld->urb_ctl);
+
+ usb_buffer_free(yld->udev, sizeof(*(yld->ctl_req)),
+ yld->ctl_req, yld->ctl_req_dma);
+ usb_buffer_free(yld->udev, USB_PKT_LEN,
+ yld->ctl_data, yld->ctl_dma);
+ usb_buffer_free(yld->udev, USB_PKT_LEN,
+ yld->irq_data, yld->irq_dma);
+
kfree(yld);
return err;
}
diff --git a/drivers/usb/input/yealink.h b/drivers/input/misc/yealink.h
similarity index 100%
rename from drivers/usb/input/yealink.h
rename to drivers/input/misc/yealink.h
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
index 81dd8c7..2ccc114 100644
--- a/drivers/input/mouse/Kconfig
+++ b/drivers/input/mouse/Kconfig
@@ -2,7 +2,7 @@
# Mouse driver configuration
#
menuconfig INPUT_MOUSE
- bool "Mouse"
+ bool "Mice"
default y
help
Say Y here, and a list of supported mice will be displayed.
@@ -19,7 +19,7 @@
select SERIO_LIBPS2
select SERIO_I8042 if X86_PC
select SERIO_GSCPS2 if GSC
- ---help---
+ help
Say Y here if you have a PS/2 mouse connected to your system. This
includes the standard 2 or 3-button PS/2 mouse, as well as PS/2
mice with wheels and extra buttons, Microsoft, Logitech or Genius
@@ -41,7 +41,7 @@
bool "ALPS PS/2 mouse protocol extension" if EMBEDDED
default y
depends on MOUSE_PS2
- ---help---
+ help
Say Y here if you have an ALPS PS/2 touchpad connected to
your system.
@@ -51,7 +51,7 @@
bool "Logictech PS/2++ mouse protocol extension" if EMBEDDED
default y
depends on MOUSE_PS2
- ---help---
+ help
Say Y here if you have a Logictech PS/2++ mouse connected to
your system.
@@ -61,7 +61,7 @@
bool "Synaptics PS/2 mouse protocol extension" if EMBEDDED
default y
depends on MOUSE_PS2
- ---help---
+ help
Say Y here if you have a Synaptics PS/2 TouchPad connected to
your system.
@@ -71,7 +71,7 @@
bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EMBEDDED
default y
depends on MOUSE_PS2
- ---help---
+ help
Say Y here if you have a Fujitsu B-series Lifebook PS/2
TouchScreen connected to your system.
@@ -81,7 +81,7 @@
bool "IBM Trackpoint PS/2 mouse protocol extension" if EMBEDDED
default y
depends on MOUSE_PS2
- ---help---
+ help
Say Y here if you have an IBM Trackpoint PS/2 mouse connected
to your system.
@@ -90,7 +90,7 @@
config MOUSE_PS2_TOUCHKIT
bool "eGalax TouchKit PS/2 protocol extension"
depends on MOUSE_PS2
- ---help---
+ help
Say Y here if you have an eGalax TouchKit PS/2 touchscreen
connected to your system.
@@ -99,7 +99,7 @@
config MOUSE_SERIAL
tristate "Serial mouse"
select SERIO
- ---help---
+ help
Say Y here if you have a serial (RS-232, COM port) mouse connected
to your system. This includes Sun, MouseSystems, Microsoft,
Logitech and all other compatible serial mice.
@@ -109,6 +109,26 @@
To compile this driver as a module, choose M here: the
module will be called sermouse.
+config MOUSE_APPLETOUCH
+ tristate "Apple USB Touchpad support"
+ select USB
+ help
+ Say Y here if you want to use an Apple USB Touchpad.
+
+ These are the touchpads that can be found on post-February 2005
+ Apple Powerbooks (prior models have a Synaptics touchpad connected
+ to the ADB bus).
+
+ This driver provides a basic mouse driver but can be interfaced
+ with the synaptics X11 driver to provide acceleration and
+ scrolling in X11.
+
+ For further information, see
+ <file:Documentation/input/appletouch.txt>.
+
+ To compile this driver as a module, choose M here: the
+ module will be called appletouch.
+
config MOUSE_INPORT
tristate "InPort/MS/ATIXL busmouse"
depends on ISA
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile
index 6a8f622..aa4ba87 100644
--- a/drivers/input/mouse/Makefile
+++ b/drivers/input/mouse/Makefile
@@ -5,6 +5,7 @@
# Each configuration option enables a list of files.
obj-$(CONFIG_MOUSE_AMIGA) += amimouse.o
+obj-$(CONFIG_MOUSE_APPLETOUCH) += appletouch.o
obj-$(CONFIG_MOUSE_ATARI) += atarimouse.o
obj-$(CONFIG_MOUSE_RISCPC) += rpcmouse.o
obj-$(CONFIG_MOUSE_INPORT) += inport.o
diff --git a/drivers/usb/input/appletouch.c b/drivers/input/mouse/appletouch.c
similarity index 100%
rename from drivers/usb/input/appletouch.c
rename to drivers/input/mouse/appletouch.c
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index c77788b..666ad3a 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -185,7 +185,7 @@
int retries = 0;
while ((retries++ < 3) && psmouse_reset(psmouse))
- printk(KERN_ERR "synaptics reset failed\n");
+ /* empty */;
if (synaptics_identify(psmouse))
return -1;
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index 7678e98..8675f95 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -19,7 +19,6 @@
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/input.h>
-#include <linux/smp_lock.h>
#include <linux/random.h>
#include <linux/major.h>
#include <linux/device.h>
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 7c17377..3888dc3 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -526,6 +526,33 @@
return IRQ_HANDLED;
}
+/*
+ * i8042_toggle_aux - enables or disables AUX port on i8042 via command and
+ * verifies success by readinng CTR. Used when testing for presence of AUX
+ * port.
+ */
+static int __devinit i8042_toggle_aux(int on)
+{
+ unsigned char param;
+ int i;
+
+ if (i8042_command(¶m,
+ on ? I8042_CMD_AUX_ENABLE : I8042_CMD_AUX_DISABLE))
+ return -1;
+
+ /* some chips need some time to set the I8042_CTR_AUXDIS bit */
+ for (i = 0; i < 100; i++) {
+ udelay(50);
+
+ if (i8042_command(¶m, I8042_CMD_CTL_RCTR))
+ return -1;
+
+ if (!(param & I8042_CTR_AUXDIS) == on)
+ return 0;
+ }
+
+ return -1;
+}
/*
* i8042_check_aux() applies as much paranoia as it can at detecting
@@ -580,16 +607,12 @@
* Bit assignment test - filters out PS/2 i8042's in AT mode
*/
- if (i8042_command(¶m, I8042_CMD_AUX_DISABLE))
- return -1;
- if (i8042_command(¶m, I8042_CMD_CTL_RCTR) || (~param & I8042_CTR_AUXDIS)) {
+ if (i8042_toggle_aux(0)) {
printk(KERN_WARNING "Failed to disable AUX port, but continuing anyway... Is this a SiS?\n");
printk(KERN_WARNING "If AUX port is really absent please use the 'i8042.noaux' option.\n");
}
- if (i8042_command(¶m, I8042_CMD_AUX_ENABLE))
- return -1;
- if (i8042_command(¶m, I8042_CMD_CTL_RCTR) || (param & I8042_CTR_AUXDIS))
+ if (i8042_toggle_aux(1))
return -1;
/*
diff --git a/drivers/input/tablet/Kconfig b/drivers/input/tablet/Kconfig
new file mode 100644
index 0000000..12dfb0e
--- /dev/null
+++ b/drivers/input/tablet/Kconfig
@@ -0,0 +1,74 @@
+#
+# Tablet driver configuration
+#
+menuconfig INPUT_TABLET
+ bool "Tablets"
+ help
+ Say Y here, and a list of supported tablets will be displayed.
+ This option doesn't affect the kernel.
+
+ If unsure, say Y.
+
+if INPUT_TABLET
+
+config TABLET_USB_ACECAD
+ tristate "Acecad Flair tablet support (USB)"
+ select USB
+ help
+ Say Y here if you want to use the USB version of the Acecad Flair
+ tablet. Make sure to say Y to "Mouse support"
+ (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
+ (CONFIG_INPUT_EVDEV) as well.
+
+ To compile this driver as a module, choose M here: the
+ module will be called acecad.
+
+config TABLET_USB_AIPTEK
+ tristate "Aiptek 6000U/8000U tablet support (USB)"
+ select USB
+ help
+ Say Y here if you want to use the USB version of the Aiptek 6000U
+ or Aiptek 8000U tablet. Make sure to say Y to "Mouse support"
+ (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
+ (CONFIG_INPUT_EVDEV) as well.
+
+ To compile this driver as a module, choose M here: the
+ module will be called aiptek.
+
+config TABLET_USB_GTCO
+ tristate "GTCO CalComp/InterWrite USB Support"
+ depends on USB && INPUT
+ help
+ Say Y here if you want to use the USB version of the GTCO
+ CalComp/InterWrite Tablet. Make sure to say Y to "Mouse support"
+ (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
+ (CONFIG_INPUT_EVDEV) as well.
+
+ To compile this driver as a module, choose M here: the
+ module will be called gtco.
+
+config TABLET_USB_KBTAB
+ tristate "KB Gear JamStudio tablet support (USB)"
+ select USB
+ help
+ Say Y here if you want to use the USB version of the KB Gear
+ JamStudio tablet. Make sure to say Y to "Mouse support"
+ (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
+ (CONFIG_INPUT_EVDEV) as well.
+
+ To compile this driver as a module, choose M here: the
+ module will be called kbtab.
+
+config TABLET_USB_WACOM
+ tristate "Wacom Intuos/Graphire tablet support (USB)"
+ select USB
+ help
+ Say Y here if you want to use the USB version of the Wacom Intuos
+ or Graphire tablet. Make sure to say Y to "Mouse support"
+ (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
+ (CONFIG_INPUT_EVDEV) as well.
+
+ To compile this driver as a module, choose M here: the
+ module will be called wacom.
+
+endif
diff --git a/drivers/input/tablet/Makefile b/drivers/input/tablet/Makefile
new file mode 100644
index 0000000..ce8b9a9
--- /dev/null
+++ b/drivers/input/tablet/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for the tablet drivers
+#
+
+# Multipart objects.
+wacom-objs := wacom_wac.o wacom_sys.o
+
+obj-$(CONFIG_TABLET_USB_ACECAD) += acecad.o
+obj-$(CONFIG_TABLET_USB_AIPTEK) += aiptek.o
+obj-$(CONFIG_TABLET_USB_GTCO) += gtco.o
+obj-$(CONFIG_TABLET_USB_KBTAB) += kbtab.o
+obj-$(CONFIG_TABLET_USB_WACOM) += wacom.o
diff --git a/drivers/usb/input/acecad.c b/drivers/input/tablet/acecad.c
similarity index 99%
rename from drivers/usb/input/acecad.c
rename to drivers/input/tablet/acecad.c
index be8e924..dd231045 100644
--- a/drivers/usb/input/acecad.c
+++ b/drivers/input/tablet/acecad.c
@@ -54,7 +54,7 @@
struct input_dev *input;
struct urb *irq;
- signed char *data;
+ unsigned char *data;
dma_addr_t data_dma;
};
diff --git a/drivers/usb/input/aiptek.c b/drivers/input/tablet/aiptek.c
similarity index 100%
rename from drivers/usb/input/aiptek.c
rename to drivers/input/tablet/aiptek.c
diff --git a/drivers/usb/input/gtco.c b/drivers/input/tablet/gtco.c
similarity index 100%
rename from drivers/usb/input/gtco.c
rename to drivers/input/tablet/gtco.c
diff --git a/drivers/usb/input/kbtab.c b/drivers/input/tablet/kbtab.c
similarity index 99%
rename from drivers/usb/input/kbtab.c
rename to drivers/input/tablet/kbtab.c
index c4781b9..91e6d00 100644
--- a/drivers/usb/input/kbtab.c
+++ b/drivers/input/tablet/kbtab.c
@@ -29,7 +29,7 @@
MODULE_PARM_DESC(kb_pressure_click, "pressure threshold for clicks");
struct kbtab {
- signed char *data;
+ unsigned char *data;
dma_addr_t data_dma;
struct input_dev *dev;
struct usb_device *usbdev;
diff --git a/drivers/usb/input/wacom.h b/drivers/input/tablet/wacom.h
similarity index 99%
rename from drivers/usb/input/wacom.h
rename to drivers/input/tablet/wacom.h
index d85abfc..ef01a80 100644
--- a/drivers/usb/input/wacom.h
+++ b/drivers/input/tablet/wacom.h
@@ -1,5 +1,5 @@
/*
- * drivers/usb/input/wacom.h
+ * drivers/input/tablet/wacom.h
*
* USB Wacom Graphire and Wacom Intuos tablet support
*
diff --git a/drivers/usb/input/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
similarity index 99%
rename from drivers/usb/input/wacom_sys.c
rename to drivers/input/tablet/wacom_sys.c
index 1fe4820..83bddef 100644
--- a/drivers/usb/input/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -1,5 +1,5 @@
/*
- * drivers/usb/input/wacom_sys.c
+ * drivers/input/tablet/wacom_sys.c
*
* USB Wacom Graphire and Wacom Intuos tablet support - system specific code
*/
diff --git a/drivers/usb/input/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
similarity index 99%
rename from drivers/usb/input/wacom_wac.c
rename to drivers/input/tablet/wacom_wac.c
index 4f3e9bc..7661f03 100644
--- a/drivers/usb/input/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -1,5 +1,5 @@
/*
- * drivers/usb/input/wacom_wac.c
+ * drivers/input/tablet/wacom_wac.c
*
* USB Wacom Graphire and Wacom Intuos tablet support - Wacom specific code
*
diff --git a/drivers/usb/input/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
similarity index 92%
rename from drivers/usb/input/wacom_wac.h
rename to drivers/input/tablet/wacom_wac.h
index a230222..a5e12e8 100644
--- a/drivers/usb/input/wacom_wac.h
+++ b/drivers/input/tablet/wacom_wac.h
@@ -1,5 +1,5 @@
/*
- * drivers/usb/input/wacom_wac.h
+ * drivers/input/tablet/wacom_wac.h
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -39,7 +39,7 @@
};
struct wacom_wac {
- signed char *data;
+ unsigned char *data;
int tool[2];
int id[2];
__u32 serial[2];
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 9716180..5e640ae 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -1,5 +1,5 @@
#
-# Mouse driver configuration
+# Touchscreen driver configuration
#
menuconfig INPUT_TOUCHSCREEN
bool "Touchscreens"
@@ -44,9 +44,9 @@
config TOUCHSCREEN_CORGI
tristate "SharpSL (Corgi and Spitz series) touchscreen driver"
depends on PXA_SHARPSL
- default y
+ default y
help
- Say Y here to enable the driver for the touchscreen on the
+ Say Y here to enable the driver for the touchscreen on the
Sharp SL-C7xx and SL-Cxx00 series of PDAs.
If unsure, say N.
@@ -164,4 +164,58 @@
To compile this driver as a module, choose M here: the
module will be called ucb1400_ts.
+config TOUCHSCREEN_USB_COMPOSITE
+ tristate "USB Touchscreen Driver"
+ select USB
+ help
+ USB Touchscreen driver for:
+ - eGalax Touchkit USB (also includes eTurboTouch CT-410/510/700)
+ - PanJit TouchSet USB
+ - 3M MicroTouch USB (EX II series)
+ - ITM
+ - some other eTurboTouch
+ - Gunze AHL61
+ - DMC TSC-10/25
+
+ Have a look at <http://linux.chapter7.ch/touchkit/> for
+ a usage description and the required user-space stuff.
+
+ To compile this driver as a module, choose M here: the
+ module will be called usbtouchscreen.
+
+config TOUCHSCREEN_USB_EGALAX
+ default y
+ bool "eGalax, eTurboTouch CT-410/510/700 device support" if EMBEDDED
+ depends on TOUCHSCREEN_USB_COMPOSITE
+
+config TOUCHSCREEN_USB_PANJIT
+ default y
+ bool "PanJit device support" if EMBEDDED
+ depends on TOUCHSCREEN_USB_COMPOSITE
+
+config TOUCHSCREEN_USB_3M
+ default y
+ bool "3M/Microtouch EX II series device support" if EMBEDDED
+ depends on TOUCHSCREEN_USB_COMPOSITE
+
+config TOUCHSCREEN_USB_ITM
+ default y
+ bool "ITM device support" if EMBEDDED
+ depends on TOUCHSCREEN_USB_COMPOSITE
+
+config TOUCHSCREEN_USB_ETURBO
+ default y
+ bool "eTurboTouch (non-eGalax compatible) device support" if EMBEDDED
+ depends on TOUCHSCREEN_USB_COMPOSITE
+
+config TOUCHSCREEN_USB_GUNZE
+ default y
+ bool "Gunze AHL61 device support" if EMBEDDED
+ depends on TOUCHSCREEN_USB_COMPOSITE
+
+config TOUCHSCREEN_USB_DMC_TSC10
+ default y
+ bool "DMC TSC-10/25 device support" if EMBEDDED
+ depends on TOUCHSCREEN_USB_COMPOSITE
+
endif
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 30e6e22..2f86d6a 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -1,17 +1,18 @@
#
-# Makefile for the mouse drivers.
+# Makefile for the touchscreen drivers.
#
# Each configuration option enables a list of files.
obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o
-obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o
-obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o
-obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o
-obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o
-obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o
-obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o
-obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o
+obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o
+obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o
+obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o
+obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o
+obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o
+obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o
+obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o
+obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o
obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o
obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o
obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o
diff --git a/drivers/usb/input/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
similarity index 98%
rename from drivers/usb/input/usbtouchscreen.c
rename to drivers/input/touchscreen/usbtouchscreen.c
index e082941..8e18e6c 100644
--- a/drivers/usb/input/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -668,9 +668,8 @@
static void usbtouch_free_buffers(struct usb_device *udev,
struct usbtouch_usb *usbtouch)
{
- if (usbtouch->data)
- usb_buffer_free(udev, usbtouch->type->rept_size,
- usbtouch->data, usbtouch->data_dma);
+ usb_buffer_free(udev, usbtouch->type->rept_size,
+ usbtouch->data, usbtouch->data_dma);
kfree(usbtouch->buffer);
}
diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c
index 5e5b5c9..8238b13 100644
--- a/drivers/input/tsdev.c
+++ b/drivers/input/tsdev.c
@@ -48,7 +48,6 @@
#include <linux/init.h>
#include <linux/input.h>
#include <linux/major.h>
-#include <linux/smp_lock.h>
#include <linux/random.h>
#include <linux/time.h>
#include <linux/device.h>
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index db1260f..81661b8 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -18,8 +18,8 @@
#include <linux/fcntl.h>
#include <linux/fs.h>
#include <linux/signal.h>
+#include <linux/mutex.h>
#include <linux/mm.h>
-#include <linux/smp_lock.h>
#include <linux/timer.h>
#include <linux/wait.h>
#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
@@ -147,7 +147,7 @@
struct capincci *nccis;
- struct semaphore ncci_list_sem;
+ struct mutex ncci_list_mtx;
};
/* -------- global variables ---------------------------------------- */
@@ -395,7 +395,7 @@
if (!cdev)
return NULL;
- init_MUTEX(&cdev->ncci_list_sem);
+ mutex_init(&cdev->ncci_list_mtx);
skb_queue_head_init(&cdev->recvqueue);
init_waitqueue_head(&cdev->recvwait);
write_lock_irqsave(&capidev_list_lock, flags);
@@ -414,9 +414,9 @@
}
skb_queue_purge(&cdev->recvqueue);
- down(&cdev->ncci_list_sem);
+ mutex_lock(&cdev->ncci_list_mtx);
capincci_free(cdev, 0xffffffff);
- up(&cdev->ncci_list_sem);
+ mutex_unlock(&cdev->ncci_list_mtx);
write_lock_irqsave(&capidev_list_lock, flags);
list_del(&cdev->list);
@@ -603,15 +603,15 @@
if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_CONF) {
u16 info = CAPIMSG_U16(skb->data, 12); // Info field
if (info == 0) {
- down(&cdev->ncci_list_sem);
+ mutex_lock(&cdev->ncci_list_mtx);
capincci_alloc(cdev, CAPIMSG_NCCI(skb->data));
- up(&cdev->ncci_list_sem);
+ mutex_unlock(&cdev->ncci_list_mtx);
}
}
if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_IND) {
- down(&cdev->ncci_list_sem);
+ mutex_lock(&cdev->ncci_list_mtx);
capincci_alloc(cdev, CAPIMSG_NCCI(skb->data));
- up(&cdev->ncci_list_sem);
+ mutex_unlock(&cdev->ncci_list_mtx);
}
spin_lock_irqsave(&workaround_lock, flags);
if (CAPIMSG_COMMAND(skb->data) != CAPI_DATA_B3) {
@@ -752,9 +752,9 @@
CAPIMSG_SETAPPID(skb->data, cdev->ap.applid);
if (CAPIMSG_CMD(skb->data) == CAPI_DISCONNECT_B3_RESP) {
- down(&cdev->ncci_list_sem);
+ mutex_lock(&cdev->ncci_list_mtx);
capincci_free(cdev, CAPIMSG_NCCI(skb->data));
- up(&cdev->ncci_list_sem);
+ mutex_unlock(&cdev->ncci_list_mtx);
}
cdev->errcode = capi20_put_message(&cdev->ap, skb);
@@ -939,9 +939,9 @@
if (copy_from_user(&ncci, argp, sizeof(ncci)))
return -EFAULT;
- down(&cdev->ncci_list_sem);
+ mutex_lock(&cdev->ncci_list_mtx);
if ((nccip = capincci_find(cdev, (u32) ncci)) == 0) {
- up(&cdev->ncci_list_sem);
+ mutex_unlock(&cdev->ncci_list_mtx);
return 0;
}
#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
@@ -949,7 +949,7 @@
count += atomic_read(&mp->ttyopencount);
}
#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
- up(&cdev->ncci_list_sem);
+ mutex_unlock(&cdev->ncci_list_mtx);
return count;
}
return 0;
@@ -964,14 +964,14 @@
if (copy_from_user(&ncci, argp,
sizeof(ncci)))
return -EFAULT;
- down(&cdev->ncci_list_sem);
+ mutex_lock(&cdev->ncci_list_mtx);
nccip = capincci_find(cdev, (u32) ncci);
if (!nccip || (mp = nccip->minorp) == 0) {
- up(&cdev->ncci_list_sem);
+ mutex_unlock(&cdev->ncci_list_mtx);
return -ESRCH;
}
unit = mp->minor;
- up(&cdev->ncci_list_sem);
+ mutex_unlock(&cdev->ncci_list_mtx);
return unit;
}
return 0;
diff --git a/drivers/isdn/capi/capiutil.c b/drivers/isdn/capi/capiutil.c
index ad1e270..22379b9 100644
--- a/drivers/isdn/capi/capiutil.c
+++ b/drivers/isdn/capi/capiutil.c
@@ -855,7 +855,7 @@
static u_long g_debbuf_lock;
static _cmsg *g_cmsg;
-_cdebbuf *cdebbuf_alloc(void)
+static _cdebbuf *cdebbuf_alloc(void)
{
_cdebbuf *cdb;
@@ -989,11 +989,6 @@
return &g_debbuf;
}
-_cdebbuf *cdebbuf_alloc(void)
-{
- return &g_debbuf;
-}
-
void cdebbuf_free(_cdebbuf *cdb)
{
}
@@ -1009,7 +1004,6 @@
#endif
-EXPORT_SYMBOL(cdebbuf_alloc);
EXPORT_SYMBOL(cdebbuf_free);
EXPORT_SYMBOL(capi_cmsg2message);
EXPORT_SYMBOL(capi_message2cmsg);
diff --git a/drivers/isdn/divert/divert_procfs.c b/drivers/isdn/divert/divert_procfs.c
index 53a1890..be77ee6 100644
--- a/drivers/isdn/divert/divert_procfs.c
+++ b/drivers/isdn/divert/divert_procfs.c
@@ -11,7 +11,6 @@
#include <linux/module.h>
#include <linux/poll.h>
-#include <linux/smp_lock.h>
#ifdef CONFIG_PROC_FS
#include <linux/proc_fs.h>
#else
diff --git a/drivers/isdn/hardware/eicon/capimain.c b/drivers/isdn/hardware/eicon/capimain.c
index 7a74ed3..98fcdfc 100644
--- a/drivers/isdn/hardware/eicon/capimain.c
+++ b/drivers/isdn/hardware/eicon/capimain.c
@@ -13,7 +13,6 @@
#include <linux/module.h>
#include <linux/init.h>
#include <asm/uaccess.h>
-#include <linux/smp_lock.h>
#include <linux/skbuff.h>
#include "os_capi.h"
diff --git a/drivers/isdn/hardware/eicon/dbgioctl.h b/drivers/isdn/hardware/eicon/dbgioctl.h
deleted file mode 100644
index 0fb6f5e..0000000
--- a/drivers/isdn/hardware/eicon/dbgioctl.h
+++ /dev/null
@@ -1,198 +0,0 @@
-
-/*
- *
- Copyright (c) Eicon Technology Corporation, 2000.
- *
- This source file is supplied for the use with Eicon
- Technology Corporation's range of DIVA Server Adapters.
- *
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
- *
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
- *
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-/*------------------------------------------------------------------*/
-/* file: dbgioctl.h */
-/*------------------------------------------------------------------*/
-
-#if !defined(__DBGIOCTL_H__)
-
-#define __DBGIOCTL_H__
-
-#ifdef NOT_YET_NEEDED
-/*
- * The requested operation is passed in arg0 of DbgIoctlArgs,
- * additional arguments (if any) in arg1, arg2 and arg3.
- */
-
-typedef struct
-{ ULONG arg0 ;
- ULONG arg1 ;
- ULONG arg2 ;
- ULONG arg3 ;
-} DbgIoctlArgs ;
-
-#define DBG_COPY_LOGS 0 /* copy debugs to user until buffer full */
- /* arg1: size threshold */
- /* arg2: timeout in milliseconds */
-
-#define DBG_FLUSH_LOGS 1 /* flush pending debugs to user buffer */
- /* arg1: internal driver id */
-
-#define DBG_LIST_DRVS 2 /* return the list of registered drivers */
-
-#define DBG_GET_MASK 3 /* get current debug mask of driver */
- /* arg1: internal driver id */
-
-#define DBG_SET_MASK 4 /* set/change debug mask of driver */
- /* arg1: internal driver id */
- /* arg2: new debug mask */
-
-#define DBG_GET_BUFSIZE 5 /* get current buffer size of driver */
- /* arg1: internal driver id */
- /* arg2: new debug mask */
-
-#define DBG_SET_BUFSIZE 6 /* set new buffer size of driver */
- /* arg1: new buffer size */
-
-/*
- * common internal debug message structure
- */
-
-typedef struct
-{ unsigned short id ; /* virtual driver id */
- unsigned short type ; /* special message type */
- unsigned long seq ; /* sequence number of message */
- unsigned long size ; /* size of message in bytes */
- unsigned long next ; /* offset to next buffered message */
- LARGE_INTEGER NTtime ; /* 100 ns since 1.1.1601 */
- unsigned char data[4] ;/* message data */
-} OldDbgMessage ;
-
-typedef struct
-{ LARGE_INTEGER NTtime ; /* 100 ns since 1.1.1601 */
- unsigned short size ; /* size of message in bytes */
- unsigned short ffff ; /* always 0xffff to indicate new msg */
- unsigned short id ; /* virtual driver id */
- unsigned short type ; /* special message type */
- unsigned long seq ; /* sequence number of message */
- unsigned char data[4] ;/* message data */
-} DbgMessage ;
-
-#endif
-
-#define DRV_ID_UNKNOWN 0x0C /* for messages via prtComp() */
-
-#define MSG_PROC_FLAG 0x80
-#define MSG_PROC_NO_GET(x) (((x) & MSG_PROC_FLAG) ? (((x) >> 4) & 7) : -1)
-#define MSG_PROC_NO_SET(x) (MSG_PROC_FLAG | (((x) & 7) << 4))
-
-#define MSG_TYPE_DRV_ID 0x0001
-#define MSG_TYPE_FLAGS 0x0002
-#define MSG_TYPE_STRING 0x0003
-#define MSG_TYPE_BINARY 0x0004
-
-#define MSG_HEAD_SIZE ((unsigned long)&(((DbgMessage *)0)->data[0]))
-#define MSG_ALIGN(len) (((unsigned long)(len) + MSG_HEAD_SIZE + 3) & ~3)
-#define MSG_SIZE(pMsg) MSG_ALIGN((pMsg)->size)
-#define MSG_NEXT(pMsg) ((DbgMessage *)( ((char *)(pMsg)) + MSG_SIZE(pMsg) ))
-
-#define OLD_MSG_HEAD_SIZE ((unsigned long)&(((OldDbgMessage *)0)->data[0]))
-#define OLD_MSG_ALIGN(len) (((unsigned long)(len)+OLD_MSG_HEAD_SIZE+3) & ~3)
-
-/*
- * manifest constants
- */
-
-#define MSG_FRAME_MAX_SIZE 2150 /* maximum size of B1 frame */
-#define MSG_TEXT_MAX_SIZE 1024 /* maximum size of msg text */
-#define MSG_MAX_SIZE MSG_ALIGN(MSG_FRAME_MAX_SIZE)
-#define DBG_MIN_BUFFER_SIZE 0x00008000 /* minimal total buffer size 32 KB */
-#define DBG_DEF_BUFFER_SIZE 0x00020000 /* default total buffer size 128 KB */
-#define DBG_MAX_BUFFER_SIZE 0x00400000 /* maximal total buffer size 4 MB */
-
-#define DBGDRV_NAME "Diehl_DIMAINT"
-#define UNIDBG_DRIVER L"\\Device\\Diehl_DIMAINT" /* UNICODE name for kernel */
-#define DEBUG_DRIVER "\\\\.\\" DBGDRV_NAME /* traditional string for apps */
-#define DBGVXD_NAME "DIMAINT"
-#define DEBUG_VXD "\\\\.\\" DBGVXD_NAME /* traditional string for apps */
-
-/*
- * Special IDI interface debug construction
- */
-
-#define DBG_IDI_SIG_REQ (unsigned long)0xF479C402
-#define DBG_IDI_SIG_IND (unsigned long)0xF479C403
-#define DBG_IDI_NL_REQ (unsigned long)0xF479C404
-#define DBG_IDI_NL_IND (unsigned long)0xF479C405
-
-typedef struct
-{ unsigned long magic_type ;
- unsigned short data_len ;
- unsigned char layer_ID ;
- unsigned char entity_ID ;
- unsigned char request ;
- unsigned char ret_code ;
- unsigned char indication ;
- unsigned char complete ;
- unsigned char data[4] ;
-} DbgIdiAct, *DbgIdiAction ;
-
-/*
- * We want to use the same IOCTL codes in Win95 and WinNT.
- * The official constructor for IOCTL codes is the CTL_CODE macro
- * from <winoctl.h> (<devioctl.h> in WinNT DDK environment).
- * The problem here is that we don't know how to get <winioctl.h>
- * working in a Win95 DDK environment!
- */
-
-# ifdef CTL_CODE /*{*/
-
-/* Assert that we have the same idea of the CTL_CODE macro. */
-
-#define CTL_CODE( DeviceType, Function, Method, Access ) ( \
- ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
-)
-
-# else /* !CTL_CODE */ /*}{*/
-
-/* Use the definitions stolen from <winioctl.h>. */
-
-#define CTL_CODE( DeviceType, Function, Method, Access ) ( \
- ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
-)
-
-#define METHOD_BUFFERED 0
-#define METHOD_IN_DIRECT 1
-#define METHOD_OUT_DIRECT 2
-#define METHOD_NEITHER 3
-
-#define FILE_ANY_ACCESS 0
-#define FILE_READ_ACCESS ( 0x0001 ) // file & pipe
-#define FILE_WRITE_ACCESS ( 0x0002 ) // file & pipe
-
-# endif /* CTL_CODE */ /*}*/
-
-/*
- * Now we can define WinNT/Win95 DeviceIoControl codes.
- *
- * These codes are defined in di_defs.h too, a possible mismatch will be
- * detected when the dbgtool is compiled.
- */
-
-#define IOCTL_DRIVER_LNK \
- CTL_CODE(0x8001U,0x701,METHOD_OUT_DIRECT,FILE_ANY_ACCESS)
-#define IOCTL_DRIVER_DBG \
- CTL_CODE(0x8001U,0x702,METHOD_OUT_DIRECT,FILE_ANY_ACCESS)
-
-#endif /* __DBGIOCTL_H__ */
diff --git a/drivers/isdn/hardware/eicon/divamnt.c b/drivers/isdn/hardware/eicon/divamnt.c
index 4aba5c5..c909289 100644
--- a/drivers/isdn/hardware/eicon/divamnt.c
+++ b/drivers/isdn/hardware/eicon/divamnt.c
@@ -13,7 +13,6 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
-#include <linux/smp_lock.h>
#include <linux/poll.h>
#include <asm/uaccess.h>
diff --git a/drivers/isdn/hardware/eicon/divasi.c b/drivers/isdn/hardware/eicon/divasi.c
index 556b196..78f141e 100644
--- a/drivers/isdn/hardware/eicon/divasi.c
+++ b/drivers/isdn/hardware/eicon/divasi.c
@@ -14,7 +14,6 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
-#include <linux/smp_lock.h>
#include <linux/poll.h>
#include <linux/proc_fs.h>
#include <linux/skbuff.h>
diff --git a/drivers/isdn/hardware/eicon/divasmain.c b/drivers/isdn/hardware/eicon/divasmain.c
index 5e862e2..6d39f93 100644
--- a/drivers/isdn/hardware/eicon/divasmain.c
+++ b/drivers/isdn/hardware/eicon/divasmain.c
@@ -17,7 +17,6 @@
#include <linux/ioport.h>
#include <linux/workqueue.h>
#include <linux/pci.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/poll.h>
diff --git a/drivers/isdn/hardware/eicon/main_if.h b/drivers/isdn/hardware/eicon/main_if.h
deleted file mode 100644
index 0ea339a..0000000
--- a/drivers/isdn/hardware/eicon/main_if.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- *
- Copyright (c) Eicon Technology Corporation, 2000.
- *
- This source file is supplied for the use with Eicon
- Technology Corporation's range of DIVA Server Adapters.
- *
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
- *
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
- *
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-/*------------------------------------------------------------------*/
-/* file: main_if.h */
-/*------------------------------------------------------------------*/
-# ifndef MAIN_IF___H
-# define MAIN_IF___H
-
-# include "debug_if.h"
-
-void DI_lock (void) ;
-void DI_unlock (void) ;
-
-#ifdef NOT_YET_NEEDED
-void DI_nttime (LARGE_INTEGER *NTtime) ;
-void DI_ntlcltime(LARGE_INTEGER *NTtime, LARGE_INTEGER *lclNTtime) ;
-void DI_nttimefields(LARGE_INTEGER *NTtime, TIME_FIELDS *TimeFields);
-unsigned long DI_wintime(LARGE_INTEGER *NTtime) ;
-
-unsigned short DiInsertProcessorNumber (int type) ;
-void DiProcessEventLog (unsigned short id, unsigned long msgID, va_list ap);
-
-void StartIoctlTimer (void (*Handler)(void), unsigned long msec) ;
-void StopIoctlTimer (void) ;
-void UnpendIoctl (DbgRequest *pDbgReq) ;
-#endif
-
-void add_to_q(int, char* , unsigned int);
-# endif /* MAIN_IF___H */
-
diff --git a/drivers/isdn/hardware/eicon/platform.h b/drivers/isdn/hardware/eicon/platform.h
index ff09f07..15d4942 100644
--- a/drivers/isdn/hardware/eicon/platform.h
+++ b/drivers/isdn/hardware/eicon/platform.h
@@ -26,7 +26,6 @@
#include <linux/vmalloc.h>
#include <linux/proc_fs.h>
#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <linux/list.h>
#include <asm/types.h>
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c
index 9f44d3e..99e70d4 100644
--- a/drivers/isdn/hisax/hfc_usb.c
+++ b/drivers/isdn/hisax/hfc_usb.c
@@ -37,7 +37,6 @@
#include <linux/kernel_stat.h>
#include <linux/usb.h>
#include <linux/kernel.h>
-#include <linux/smp_lock.h>
#include "hisax.h"
#include "hisax_if.h"
#include "hfc_usb.h"
diff --git a/drivers/isdn/hysdn/boardergo.c b/drivers/isdn/hysdn/boardergo.c
index 84dccd5..6cdbad3 100644
--- a/drivers/isdn/hysdn/boardergo.c
+++ b/drivers/isdn/hysdn/boardergo.c
@@ -443,7 +443,7 @@
card->waitpofready = ergo_waitpofready;
card->set_errlog_state = ergo_set_errlog_state;
INIT_WORK(&card->irq_queue, ergo_irq_bh);
- card->hysdn_lock = SPIN_LOCK_UNLOCKED;
+ spin_lock_init(&card->hysdn_lock);
return (0);
} /* ergo_inithardware */
diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c
index 4c7deda..27b3991 100644
--- a/drivers/isdn/hysdn/hysdn_proclog.c
+++ b/drivers/isdn/hysdn/hysdn_proclog.c
@@ -297,8 +297,6 @@
struct procdata *pd;
hysdn_card *card;
int retval = 0;
- unsigned long flags;
- spinlock_t hysdn_lock = SPIN_LOCK_UNLOCKED;
lock_kernel();
if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) {
@@ -308,7 +306,6 @@
/* read access -> log/debug read, mark one further file as closed */
pd = NULL;
- spin_lock_irqsave(&hysdn_lock, flags);
inf = *((struct log_data **) filep->private_data); /* get first log entry */
if (inf)
pd = (struct procdata *) inf->proc_ctrl; /* still entries there */
@@ -331,7 +328,6 @@
inf->usage_cnt--; /* decrement usage count for buffers */
inf = inf->next;
}
- spin_unlock_irqrestore(&hysdn_lock, flags);
if (pd)
if (pd->if_used <= 0) /* delete buffers if last file closed */
diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c
index e93ad59..bb92e3c 100644
--- a/drivers/isdn/isdnloop/isdnloop.c
+++ b/drivers/isdn/isdnloop/isdnloop.c
@@ -1462,7 +1462,7 @@
skb_queue_head_init(&card->bqueue[i]);
}
skb_queue_head_init(&card->dqueue);
- card->isdnloop_lock = SPIN_LOCK_UNLOCKED;
+ spin_lock_init(&card->isdnloop_lock);
card->next = cards;
cards = card;
if (!register_isdn(&card->interface)) {
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig
index 1a86387..a32c91e 100644
--- a/drivers/macintosh/Kconfig
+++ b/drivers/macintosh/Kconfig
@@ -1,6 +1,10 @@
-menu "Macintosh device drivers"
+menuconfig MACINTOSH_DRIVERS
+ bool "Macintosh device drivers"
depends on PPC || MAC || X86
+ default y
+
+if MACINTOSH_DRIVERS
config ADB
bool "Apple Desktop Bus (ADB) support"
@@ -109,7 +113,9 @@
config PMAC_APM_EMU
tristate "APM emulation"
- depends on PPC_PMAC && PPC32 && PM && ADB_PMU
+ select SYS_SUPPORTS_APM_EMULATION
+ select APM_EMULATION
+ depends on ADB_PMU && PM
config PMAC_MEDIABAY
bool "Support PowerBook hotswap media bay"
@@ -234,4 +240,4 @@
This driver procides some support to control the front panel
blue LEDs "vu-meter" of the XServer macs.
-endmenu
+endif # MACINTOSH_DRIVERS
diff --git a/drivers/macintosh/apm_emu.c b/drivers/macintosh/apm_emu.c
index cdb0bea..9821e63 100644
--- a/drivers/macintosh/apm_emu.c
+++ b/drivers/macintosh/apm_emu.c
@@ -1,9 +1,7 @@
-/* APM emulation layer for PowerMac
- *
- * Copyright 2001 Benjamin Herrenschmidt (benh@kernel.crashing.org)
+/*
+ * APM emulation for PMU-based machines
*
- * Lots of code inherited from apm.c, see appropriate notice in
- * arch/i386/kernel/apm.c
+ * Copyright 2001 Benjamin Herrenschmidt (benh@kernel.crashing.org)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -18,429 +16,39 @@
*
*/
-#include <linux/module.h>
-
-#include <linux/poll.h>
-#include <linux/types.h>
-#include <linux/stddef.h>
-#include <linux/timer.h>
-#include <linux/fcntl.h>
-#include <linux/slab.h>
-#include <linux/stat.h>
-#include <linux/proc_fs.h>
-#include <linux/miscdevice.h>
-#include <linux/apm_bios.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/pm.h>
#include <linux/kernel.h>
-#include <linux/smp_lock.h>
-
+#include <linux/module.h>
+#include <linux/apm-emulation.h>
#include <linux/adb.h>
#include <linux/pmu.h>
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <asm/machdep.h>
-
-#undef DEBUG
-
-#ifdef DEBUG
-#define DBG(args...) printk(KERN_DEBUG args)
-//#define DBG(args...) xmon_printf(args)
-#else
-#define DBG(args...) do { } while (0)
-#endif
-
-/*
- * The apm_bios device is one of the misc char devices.
- * This is its minor number.
- */
-#define APM_MINOR_DEV 134
-
-/*
- * Maximum number of events stored
- */
-#define APM_MAX_EVENTS 20
-
-#define FAKE_APM_BIOS_VERSION 0x0101
-
-#define APM_USER_NOTIFY_TIMEOUT (5*HZ)
-
-/*
- * The per-file APM data
- */
-struct apm_user {
- int magic;
- struct apm_user * next;
- int suser: 1;
- int suspend_waiting: 1;
- int suspends_pending;
- int suspends_read;
- int event_head;
- int event_tail;
- apm_event_t events[APM_MAX_EVENTS];
-};
-
-/*
- * The magic number in apm_user
- */
-#define APM_BIOS_MAGIC 0x4101
-
-/*
- * Local variables
- */
-static int suspends_pending;
-
-static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue);
-static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
-static struct apm_user * user_list;
-
-static void apm_notify_sleep(struct pmu_sleep_notifier *self, int when);
-static struct pmu_sleep_notifier apm_sleep_notifier = {
- apm_notify_sleep,
- SLEEP_LEVEL_USERLAND,
-};
-
-static const char driver_version[] = "0.5"; /* no spaces */
-
-#ifdef DEBUG
-static char * apm_event_name[] = {
- "system standby",
- "system suspend",
- "normal resume",
- "critical resume",
- "low battery",
- "power status change",
- "update time",
- "critical suspend",
- "user standby",
- "user suspend",
- "system standby resume",
- "capabilities change"
-};
-#define NR_APM_EVENT_NAME \
- (sizeof(apm_event_name) / sizeof(apm_event_name[0]))
-
-#endif
-
-static int queue_empty(struct apm_user *as)
-{
- return as->event_head == as->event_tail;
-}
-
-static apm_event_t get_queued_event(struct apm_user *as)
-{
- as->event_tail = (as->event_tail + 1) % APM_MAX_EVENTS;
- return as->events[as->event_tail];
-}
-
-static void queue_event(apm_event_t event, struct apm_user *sender)
-{
- struct apm_user * as;
-
- DBG("apm_emu: queue_event(%s)\n", apm_event_name[event-1]);
- if (user_list == NULL)
- return;
- for (as = user_list; as != NULL; as = as->next) {
- if (as == sender)
- continue;
- as->event_head = (as->event_head + 1) % APM_MAX_EVENTS;
- if (as->event_head == as->event_tail) {
- static int notified;
-
- if (notified++ == 0)
- printk(KERN_ERR "apm_emu: an event queue overflowed\n");
- as->event_tail = (as->event_tail + 1) % APM_MAX_EVENTS;
- }
- as->events[as->event_head] = event;
- if (!as->suser)
- continue;
- switch (event) {
- case APM_SYS_SUSPEND:
- case APM_USER_SUSPEND:
- as->suspends_pending++;
- suspends_pending++;
- break;
- case APM_NORMAL_RESUME:
- as->suspend_waiting = 0;
- break;
- }
- }
- wake_up_interruptible(&apm_waitqueue);
-}
-
-static int check_apm_user(struct apm_user *as, const char *func)
-{
- if ((as == NULL) || (as->magic != APM_BIOS_MAGIC)) {
- printk(KERN_ERR "apm_emu: %s passed bad filp\n", func);
- return 1;
- }
- return 0;
-}
-
-static ssize_t do_read(struct file *fp, char __user *buf, size_t count, loff_t *ppos)
-{
- struct apm_user * as;
- size_t i;
- apm_event_t event;
- DECLARE_WAITQUEUE(wait, current);
-
- as = fp->private_data;
- if (check_apm_user(as, "read"))
- return -EIO;
- if (count < sizeof(apm_event_t))
- return -EINVAL;
- if (queue_empty(as)) {
- if (fp->f_flags & O_NONBLOCK)
- return -EAGAIN;
- add_wait_queue(&apm_waitqueue, &wait);
-repeat:
- set_current_state(TASK_INTERRUPTIBLE);
- if (queue_empty(as) && !signal_pending(current)) {
- schedule();
- goto repeat;
- }
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&apm_waitqueue, &wait);
- }
- i = count;
- while ((i >= sizeof(event)) && !queue_empty(as)) {
- event = get_queued_event(as);
- DBG("apm_emu: do_read, returning: %s\n", apm_event_name[event-1]);
- if (copy_to_user(buf, &event, sizeof(event))) {
- if (i < count)
- break;
- return -EFAULT;
- }
- switch (event) {
- case APM_SYS_SUSPEND:
- case APM_USER_SUSPEND:
- as->suspends_read++;
- break;
- }
- buf += sizeof(event);
- i -= sizeof(event);
- }
- if (i < count)
- return count - i;
- if (signal_pending(current))
- return -ERESTARTSYS;
- return 0;
-}
-
-static unsigned int do_poll(struct file *fp, poll_table * wait)
-{
- struct apm_user * as;
-
- as = fp->private_data;
- if (check_apm_user(as, "poll"))
- return 0;
- poll_wait(fp, &apm_waitqueue, wait);
- if (!queue_empty(as))
- return POLLIN | POLLRDNORM;
- return 0;
-}
-
-static int do_ioctl(struct inode * inode, struct file *filp,
- u_int cmd, u_long arg)
-{
- struct apm_user * as;
- DECLARE_WAITQUEUE(wait, current);
-
- as = filp->private_data;
- if (check_apm_user(as, "ioctl"))
- return -EIO;
- if (!as->suser)
- return -EPERM;
- switch (cmd) {
- case APM_IOC_SUSPEND:
- /* If a suspend message was sent to userland, we
- * consider this as a confirmation message
- */
- if (as->suspends_read > 0) {
- as->suspends_read--;
- as->suspends_pending--;
- suspends_pending--;
- } else {
- // Route to PMU suspend ?
- break;
- }
- as->suspend_waiting = 1;
- add_wait_queue(&apm_waitqueue, &wait);
- DBG("apm_emu: ioctl waking up sleep waiter !\n");
- wake_up(&apm_suspend_waitqueue);
- mb();
- while(as->suspend_waiting && !signal_pending(current)) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule();
- }
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&apm_waitqueue, &wait);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int do_release(struct inode * inode, struct file * filp)
-{
- struct apm_user * as;
-
- as = filp->private_data;
- if (check_apm_user(as, "release"))
- return 0;
- filp->private_data = NULL;
- lock_kernel();
- if (as->suspends_pending > 0) {
- suspends_pending -= as->suspends_pending;
- if (suspends_pending <= 0)
- wake_up(&apm_suspend_waitqueue);
- }
- if (user_list == as)
- user_list = as->next;
- else {
- struct apm_user * as1;
-
- for (as1 = user_list;
- (as1 != NULL) && (as1->next != as);
- as1 = as1->next)
- ;
- if (as1 == NULL)
- printk(KERN_ERR "apm: filp not in user list\n");
- else
- as1->next = as->next;
- }
- unlock_kernel();
- kfree(as);
- return 0;
-}
-
-static int do_open(struct inode * inode, struct file * filp)
-{
- struct apm_user * as;
-
- as = kmalloc(sizeof(*as), GFP_KERNEL);
- if (as == NULL) {
- printk(KERN_ERR "apm: cannot allocate struct of size %d bytes\n",
- sizeof(*as));
- return -ENOMEM;
- }
- as->magic = APM_BIOS_MAGIC;
- as->event_tail = as->event_head = 0;
- as->suspends_pending = 0;
- as->suspends_read = 0;
- /*
- * XXX - this is a tiny bit broken, when we consider BSD
- * process accounting. If the device is opened by root, we
- * instantly flag that we used superuser privs. Who knows,
- * we might close the device immediately without doing a
- * privileged operation -- cevans
- */
- as->suser = capable(CAP_SYS_ADMIN);
- as->next = user_list;
- user_list = as;
- filp->private_data = as;
-
- DBG("apm_emu: opened by %s, suser: %d\n", current->comm, (int)as->suser);
-
- return 0;
-}
-
-/* Wait for all clients to ack the suspend request. APM API
- * doesn't provide a way to NAK, but this could be added
- * here.
- */
-static void wait_all_suspend(void)
-{
- DECLARE_WAITQUEUE(wait, current);
-
- add_wait_queue(&apm_suspend_waitqueue, &wait);
- DBG("apm_emu: wait_all_suspend(), suspends_pending: %d\n", suspends_pending);
- while(suspends_pending > 0) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule();
- }
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&apm_suspend_waitqueue, &wait);
-
- DBG("apm_emu: wait_all_suspend() - complete !\n");
-}
-
-static void apm_notify_sleep(struct pmu_sleep_notifier *self, int when)
-{
- switch(when) {
- case PBOOK_SLEEP_REQUEST:
- queue_event(APM_SYS_SUSPEND, NULL);
- wait_all_suspend();
- break;
- case PBOOK_WAKE:
- queue_event(APM_NORMAL_RESUME, NULL);
- break;
- }
-}
-
#define APM_CRITICAL 10
#define APM_LOW 30
-static int apm_emu_get_info(char *buf, char **start, off_t fpos, int length)
+static void pmu_apm_get_power_status(struct apm_power_info *info)
{
- /* Arguments, with symbols from linux/apm_bios.h. Information is
- from the Get Power Status (0x0a) call unless otherwise noted.
+ int percentage = -1;
+ int batteries = 0;
+ int time_units = -1;
+ int real_count = 0;
+ int i;
+ char charging = 0;
+ long charge = -1;
+ long amperage = 0;
+ unsigned long btype = 0;
- 0) Linux driver version (this will change if format changes)
- 1) APM BIOS Version. Usually 1.0, 1.1 or 1.2.
- 2) APM flags from APM Installation Check (0x00):
- bit 0: APM_16_BIT_SUPPORT
- bit 1: APM_32_BIT_SUPPORT
- bit 2: APM_IDLE_SLOWS_CLOCK
- bit 3: APM_BIOS_DISABLED
- bit 4: APM_BIOS_DISENGAGED
- 3) AC line status
- 0x00: Off-line
- 0x01: On-line
- 0x02: On backup power (BIOS >= 1.1 only)
- 0xff: Unknown
- 4) Battery status
- 0x00: High
- 0x01: Low
- 0x02: Critical
- 0x03: Charging
- 0x04: Selected battery not present (BIOS >= 1.2 only)
- 0xff: Unknown
- 5) Battery flag
- bit 0: High
- bit 1: Low
- bit 2: Critical
- bit 3: Charging
- bit 7: No system battery
- 0xff: Unknown
- 6) Remaining battery life (percentage of charge):
- 0-100: valid
- -1: Unknown
- 7) Remaining battery life (time units):
- Number of remaining minutes or seconds
- -1: Unknown
- 8) min = minutes; sec = seconds */
+ info->battery_status = APM_BATTERY_STATUS_UNKNOWN;
+ info->battery_flag = APM_BATTERY_FLAG_UNKNOWN;
+ info->units = APM_UNITS_MINS;
- unsigned short ac_line_status;
- unsigned short battery_status = 0;
- unsigned short battery_flag = 0xff;
- int percentage = -1;
- int time_units = -1;
- int real_count = 0;
- int i;
- char * p = buf;
- char charging = 0;
- long charge = -1;
- long amperage = 0;
- unsigned long btype = 0;
+ if (pmu_power_flags & PMU_PWR_AC_PRESENT)
+ info->ac_line_status = APM_AC_ONLINE;
+ else
+ info->ac_line_status = APM_AC_OFFLINE;
- ac_line_status = ((pmu_power_flags & PMU_PWR_AC_PRESENT) != 0);
for (i=0; i<pmu_battery_count; i++) {
if (pmu_batteries[i].flags & PMU_BATT_PRESENT) {
- battery_status++;
+ batteries++;
if (percentage < 0)
percentage = 0;
if (charge < 0)
@@ -456,9 +64,9 @@
charging++;
}
}
- if (0 == battery_status)
- ac_line_status = 1;
- battery_status = 0xff;
+ if (batteries == 0)
+ info->ac_line_status = APM_AC_ONLINE;
+
if (real_count) {
if (amperage < 0) {
if (btype == PMU_BATT_TYPE_SMART)
@@ -468,85 +76,44 @@
}
percentage /= real_count;
if (charging > 0) {
- battery_status = 0x03;
- battery_flag = 0x08;
+ info->battery_status = APM_BATTERY_STATUS_CHARGING;
+ info->battery_flag = APM_BATTERY_FLAG_CHARGING;
} else if (percentage <= APM_CRITICAL) {
- battery_status = 0x02;
- battery_flag = 0x04;
+ info->battery_status = APM_BATTERY_STATUS_CRITICAL;
+ info->battery_flag = APM_BATTERY_FLAG_CRITICAL;
} else if (percentage <= APM_LOW) {
- battery_status = 0x01;
- battery_flag = 0x02;
+ info->battery_status = APM_BATTERY_STATUS_LOW;
+ info->battery_flag = APM_BATTERY_FLAG_LOW;
} else {
- battery_status = 0x00;
- battery_flag = 0x01;
+ info->battery_status = APM_BATTERY_STATUS_HIGH;
+ info->battery_flag = APM_BATTERY_FLAG_HIGH;
}
}
- p += sprintf(p, "%s %d.%d 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s\n",
- driver_version,
- (FAKE_APM_BIOS_VERSION >> 8) & 0xff,
- FAKE_APM_BIOS_VERSION & 0xff,
- 0,
- ac_line_status,
- battery_status,
- battery_flag,
- percentage,
- time_units,
- "min");
- return p - buf;
+ info->battery_life = percentage;
+ info->time = time_units;
}
-static const struct file_operations apm_bios_fops = {
- .owner = THIS_MODULE,
- .read = do_read,
- .poll = do_poll,
- .ioctl = do_ioctl,
- .open = do_open,
- .release = do_release,
-};
-
-static struct miscdevice apm_device = {
- APM_MINOR_DEV,
- "apm_bios",
- &apm_bios_fops
-};
-
static int __init apm_emu_init(void)
{
- struct proc_dir_entry *apm_proc;
+ apm_get_power_status = pmu_apm_get_power_status;
- if (sys_ctrler != SYS_CTRLER_PMU) {
- printk(KERN_INFO "apm_emu: Requires a machine with a PMU.\n");
- return -ENODEV;
- }
-
- apm_proc = create_proc_info_entry("apm", 0, NULL, apm_emu_get_info);
- if (apm_proc)
- apm_proc->owner = THIS_MODULE;
-
- if (misc_register(&apm_device) != 0)
- printk(KERN_INFO "Could not create misc. device for apm\n");
-
- pmu_register_sleep_notifier(&apm_sleep_notifier);
-
- printk(KERN_INFO "apm_emu: APM Emulation %s initialized.\n", driver_version);
+ printk(KERN_INFO "apm_emu: PMU APM Emulation initialized.\n");
return 0;
}
static void __exit apm_emu_exit(void)
{
- pmu_unregister_sleep_notifier(&apm_sleep_notifier);
- misc_deregister(&apm_device);
- remove_proc_entry("apm", NULL);
+ if (apm_get_power_status == pmu_apm_get_power_status)
+ apm_get_power_status = NULL;
- printk(KERN_INFO "apm_emu: APM Emulation removed.\n");
+ printk(KERN_INFO "apm_emu: PMU APM Emulation removed.\n");
}
module_init(apm_emu_init);
module_exit(apm_emu_exit);
MODULE_AUTHOR("Benjamin Herrenschmidt");
-MODULE_DESCRIPTION("APM emulation layer for PowerMac");
+MODULE_DESCRIPTION("APM emulation for PowerMac");
MODULE_LICENSE("GPL");
-
diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c
index 1599dc3..76c1e8e 100644
--- a/drivers/macintosh/mac_hid.c
+++ b/drivers/macintosh/mac_hid.c
@@ -24,7 +24,7 @@
#if defined(CONFIG_SYSCTL)
/* file(s) in /proc/sys/dev/mac_hid */
-ctl_table mac_hid_files[] = {
+static ctl_table mac_hid_files[] = {
{
.ctl_name = DEV_MAC_HID_MOUSE_BUTTON_EMULATION,
.procname = "mouse_button_emulation",
@@ -53,7 +53,7 @@
};
/* dir in /proc/sys/dev */
-ctl_table mac_hid_dir[] = {
+static ctl_table mac_hid_dir[] = {
{
.ctl_name = DEV_MAC_HID,
.procname = "mac_hid",
@@ -65,7 +65,7 @@
};
/* /proc/sys/dev itself, in case that is not there yet */
-ctl_table mac_hid_root_dir[] = {
+static ctl_table mac_hid_root_dir[] = {
{
.ctl_name = CTL_DEV,
.procname = "dev",
@@ -127,7 +127,7 @@
return ret;
}
-int __init mac_hid_init(void)
+static int __init mac_hid_init(void)
{
int err;
diff --git a/drivers/macintosh/macio_sysfs.c b/drivers/macintosh/macio_sysfs.c
index cc82679..112e5ef 100644
--- a/drivers/macintosh/macio_sysfs.c
+++ b/drivers/macintosh/macio_sysfs.c
@@ -41,28 +41,15 @@
static ssize_t modalias_show (struct device *dev, struct device_attribute *attr,
char *buf)
{
- struct of_device *of;
- const char *compat;
- int cplen;
- int length;
+ struct of_device *ofdev = to_of_device(dev);
+ int len;
- of = &to_macio_device (dev)->ofdev;
- compat = of_get_property(of->node, "compatible", &cplen);
- if (!compat) compat = "", cplen = 1;
- length = sprintf (buf, "of:N%sT%s", of->node->name, of->node->type);
- buf += length;
- while (cplen > 0) {
- int l;
- l = sprintf (buf, "C%s", compat);
- length += l;
- buf += l;
- l = strlen (compat) + 1;
- compat += l;
- cplen -= l;
- }
- length += sprintf(buf, "\n");
+ len = of_device_get_modalias(ofdev, buf, PAGE_SIZE);
- return length;
+ buf[len] = '\n';
+ buf[len+1] = 0;
+
+ return len+1;
}
macio_config_of_attr (name, "%s\n");
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c
index a98a328..f8e1a13 100644
--- a/drivers/macintosh/smu.c
+++ b/drivers/macintosh/smu.c
@@ -606,7 +606,7 @@
struct device_node *np;
for (np = NULL; (np = of_get_next_child(smu->of_node, np)) != NULL;)
- if (device_is_compatible(np, "smu-sensors"))
+ if (of_device_is_compatible(np, "smu-sensors"))
of_platform_device_create(np, "smu-sensors",
&smu->of_dev->dev);
}
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
index 2289034..bd55e6a 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -19,7 +19,6 @@
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
#include <linux/wait.h>
#include <linux/suspend.h>
#include <linux/kthread.h>
@@ -560,9 +559,9 @@
np = of_find_node_by_name(NULL, "fan");
if (!np)
return -ENODEV;
- if (device_is_compatible(np, "adt7460"))
+ if (of_device_is_compatible(np, "adt7460"))
therm_type = ADT7460;
- else if (device_is_compatible(np, "adt7467"))
+ else if (of_device_is_compatible(np, "adt7467"))
therm_type = ADT7467;
else
return -ENODEV;
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
index 78ff186..dbb2240 100644
--- a/drivers/macintosh/therm_pm72.c
+++ b/drivers/macintosh/therm_pm72.c
@@ -117,7 +117,6 @@
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
#include <linux/wait.h>
#include <linux/reboot.h>
#include <linux/kmod.h>
diff --git a/drivers/macintosh/via-pmu-led.c b/drivers/macintosh/via-pmu-led.c
index fc89a70..55ad956 100644
--- a/drivers/macintosh/via-pmu-led.c
+++ b/drivers/macintosh/via-pmu-led.c
@@ -31,7 +31,6 @@
static struct adb_request pmu_blink_req;
/* -1: no change, 0: request off, 1: request on */
static int requested_change;
-static int sleeping;
static void pmu_req_done(struct adb_request * req)
{
@@ -41,7 +40,7 @@
/* if someone requested a change in the meantime
* (we only see the last one which is fine)
* then apply it now */
- if (requested_change != -1 && !sleeping)
+ if (requested_change != -1 && !pmu_sys_suspended)
pmu_request(&pmu_blink_req, NULL, 4, 0xee, 4, 0, requested_change);
/* reset requested change */
requested_change = -1;
@@ -66,7 +65,7 @@
break;
}
/* if request isn't done, then don't do anything */
- if (pmu_blink_req.complete && !sleeping)
+ if (pmu_blink_req.complete && !pmu_sys_suspended)
pmu_request(&pmu_blink_req, NULL, 4, 0xee, 4, 0, requested_change);
out:
spin_unlock_irqrestore(&pmu_blink_lock, flags);
@@ -80,32 +79,6 @@
.brightness_set = pmu_led_set,
};
-#ifdef CONFIG_PM
-static void pmu_led_sleep_call(struct pmu_sleep_notifier *self, int when)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&pmu_blink_lock, flags);
-
- switch (when) {
- case PBOOK_SLEEP_REQUEST:
- sleeping = 1;
- break;
- case PBOOK_WAKE:
- sleeping = 0;
- break;
- default:
- /* do nothing */
- break;
- }
- spin_unlock_irqrestore(&pmu_blink_lock, flags);
-}
-
-static struct pmu_sleep_notifier via_pmu_led_sleep_notif = {
- .notifier_call = pmu_led_sleep_call,
-};
-#endif
-
static int __init via_pmu_led_init(void)
{
struct device_node *dt;
@@ -135,9 +108,7 @@
/* no outstanding req */
pmu_blink_req.complete = 1;
pmu_blink_req.done = pmu_req_done;
-#ifdef CONFIG_PM
- pmu_register_sleep_notifier(&via_pmu_led_sleep_notif);
-#endif
+
return led_classdev_register(NULL, &pmu_led);
}
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index 1729d3f..157080b 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -310,14 +310,14 @@
PMU_INT_TICK;
if (vias->parent->name && ((strcmp(vias->parent->name, "ohare") == 0)
- || device_is_compatible(vias->parent, "ohare")))
+ || of_device_is_compatible(vias->parent, "ohare")))
pmu_kind = PMU_OHARE_BASED;
- else if (device_is_compatible(vias->parent, "paddington"))
+ else if (of_device_is_compatible(vias->parent, "paddington"))
pmu_kind = PMU_PADDINGTON_BASED;
- else if (device_is_compatible(vias->parent, "heathrow"))
+ else if (of_device_is_compatible(vias->parent, "heathrow"))
pmu_kind = PMU_HEATHROW_BASED;
- else if (device_is_compatible(vias->parent, "Keylargo")
- || device_is_compatible(vias->parent, "K2-Keylargo")) {
+ else if (of_device_is_compatible(vias->parent, "Keylargo")
+ || of_device_is_compatible(vias->parent, "K2-Keylargo")) {
struct device_node *gpiop;
struct device_node *adbp;
u64 gaddr = OF_BAD_ADDR;
@@ -2759,7 +2759,7 @@
#if defined(CONFIG_PM) && defined(CONFIG_PPC32)
-static int pmu_sys_suspended;
+int pmu_sys_suspended;
static int pmu_sys_suspend(struct sys_device *sysdev, pm_message_t state)
{
diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c
index 94c117e..192b26e 100644
--- a/drivers/macintosh/windfarm_core.c
+++ b/drivers/macintosh/windfarm_core.c
@@ -27,7 +27,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
#include <linux/kthread.h>
#include <linux/jiffies.h>
#include <linux/reboot.h>
diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c
index ab4d1b6..a0fabf3 100644
--- a/drivers/macintosh/windfarm_lm75_sensor.c
+++ b/drivers/macintosh/windfarm_lm75_sensor.c
@@ -188,10 +188,10 @@
if (loc == NULL || addr == 0)
continue;
/* real lm75 */
- if (device_is_compatible(dev, "lm75"))
+ if (of_device_is_compatible(dev, "lm75"))
wf_lm75_create(adapter, addr, 0, loc);
/* ds1775 (compatible, better resolution */
- else if (device_is_compatible(dev, "ds1775"))
+ else if (of_device_is_compatible(dev, "ds1775"))
wf_lm75_create(adapter, addr, 1, loc);
}
return 0;
diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c
index eaa74af..5f03aab 100644
--- a/drivers/macintosh/windfarm_max6690_sensor.c
+++ b/drivers/macintosh/windfarm_max6690_sensor.c
@@ -131,7 +131,7 @@
*/
if (!pmac_i2c_match_adapter(dev, adapter))
continue;
- if (!device_is_compatible(dev, "max6690"))
+ if (!of_device_is_compatible(dev, "max6690"))
continue;
addr = pmac_i2c_get_dev_addr(dev);
loc = of_get_property(dev, "hwsensor-location", NULL);
diff --git a/drivers/macintosh/windfarm_smu_controls.c b/drivers/macintosh/windfarm_smu_controls.c
index ff398ad..58c2590 100644
--- a/drivers/macintosh/windfarm_smu_controls.c
+++ b/drivers/macintosh/windfarm_smu_controls.c
@@ -263,7 +263,7 @@
/* Look for RPM fans */
for (fans = NULL; (fans = of_get_next_child(smu, fans)) != NULL;)
if (!strcmp(fans->name, "rpm-fans") ||
- device_is_compatible(fans, "smu-rpm-fans"))
+ of_device_is_compatible(fans, "smu-rpm-fans"))
break;
for (fan = NULL;
fans && (fan = of_get_next_child(fans, fan)) != NULL;) {
diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c
index 9a6c2cf..1043b39 100644
--- a/drivers/macintosh/windfarm_smu_sat.c
+++ b/drivers/macintosh/windfarm_smu_sat.c
@@ -380,7 +380,7 @@
busnode = pmac_i2c_get_bus_node(bus);
while ((dev = of_get_next_child(busnode, dev)) != NULL)
- if (device_is_compatible(dev, "smu-sat"))
+ if (of_device_is_compatible(dev, "smu-sat"))
wf_sat_create(adapter, dev);
return 0;
}
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index e61e0ef..5a4a74c 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -1456,10 +1456,10 @@
bitmap->offset = mddev->bitmap_offset;
if (file) {
get_file(file);
- do_sync_file_range(file, 0, LLONG_MAX,
- SYNC_FILE_RANGE_WAIT_BEFORE |
- SYNC_FILE_RANGE_WRITE |
- SYNC_FILE_RANGE_WAIT_AFTER);
+ do_sync_mapping_range(file->f_mapping, 0, LLONG_MAX,
+ SYNC_FILE_RANGE_WAIT_BEFORE |
+ SYNC_FILE_RANGE_WRITE |
+ SYNC_FILE_RANGE_WAIT_AFTER);
}
/* read superblock from bitmap file (this sets bitmap->chunksize) */
err = bitmap_read_sb(bitmap);
diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/dvb/bt8xx/dst_common.h
index 3bf084f..87623d2 100644
--- a/drivers/media/dvb/bt8xx/dst_common.h
+++ b/drivers/media/dvb/bt8xx/dst_common.h
@@ -22,7 +22,6 @@
#ifndef DST_COMMON_H
#define DST_COMMON_H
-#include <linux/smp_lock.h>
#include <linux/dvb/frontend.h>
#include <linux/device.h>
#include <linux/mutex.h>
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c
index 654c9e9..58678c0 100644
--- a/drivers/media/dvb/ttpci/av7110_av.c
+++ b/drivers/media/dvb/ttpci/av7110_av.c
@@ -32,7 +32,6 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/delay.h>
-#include <linux/smp_lock.h>
#include <linux/fs.h>
#include "av7110.h"
diff --git a/drivers/media/dvb/ttpci/av7110_ca.c b/drivers/media/dvb/ttpci/av7110_ca.c
index e9b4e88..e1c1294 100644
--- a/drivers/media/dvb/ttpci/av7110_ca.c
+++ b/drivers/media/dvb/ttpci/av7110_ca.c
@@ -34,7 +34,6 @@
#include <linux/fs.h>
#include <linux/timer.h>
#include <linux/poll.h>
-#include <linux/smp_lock.h>
#include "av7110.h"
#include "av7110_hw.h"
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c
index 4d7150e..70aee4e 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.c
+++ b/drivers/media/dvb/ttpci/av7110_hw.c
@@ -33,7 +33,6 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/delay.h>
-#include <linux/smp_lock.h>
#include <linux/fs.h>
#include "av7110.h"
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c
index cde5d3a..fcd9994 100644
--- a/drivers/media/dvb/ttpci/av7110_v4l.c
+++ b/drivers/media/dvb/ttpci/av7110_v4l.c
@@ -31,7 +31,6 @@
#include <linux/fs.h>
#include <linux/timer.h>
#include <linux/poll.h>
-#include <linux/smp_lock.h>
#include "av7110.h"
#include "av7110_hw.h"
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c
index df8d052..449df1b 100644
--- a/drivers/media/radio/dsbr100.c
+++ b/drivers/media/radio/dsbr100.c
@@ -79,7 +79,6 @@
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <linux/usb.h>
-#include <linux/smp_lock.h>
/*
* Version Information
diff --git a/drivers/media/video/cpia.h b/drivers/media/video/cpia.h
index 6eaa692..78392fb 100644
--- a/drivers/media/video/cpia.h
+++ b/drivers/media/video/cpia.h
@@ -47,7 +47,6 @@
#include <linux/videodev.h>
#include <media/v4l2-common.h>
#include <linux/list.h>
-#include <linux/smp_lock.h>
#include <linux/mutex.h>
struct cpia_camera_ops
diff --git a/drivers/media/video/cpia_pp.c b/drivers/media/video/cpia_pp.c
index 19711aa..c431df8 100644
--- a/drivers/media/video/cpia_pp.c
+++ b/drivers/media/video/cpia_pp.c
@@ -34,7 +34,6 @@
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/workqueue.h>
-#include <linux/smp_lock.h>
#include <linux/sched.h>
#include <linux/kmod.h>
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
index e627062..259ea08 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -49,7 +49,6 @@
#include <linux/interrupt.h>
#include <linux/vmalloc.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <linux/kthread.h>
diff --git a/drivers/media/video/dabusb.c b/drivers/media/video/dabusb.c
index ff4b238..a5731f9 100644
--- a/drivers/media/video/dabusb.c
+++ b/drivers/media/video/dabusb.c
@@ -37,7 +37,6 @@
#include <asm/atomic.h>
#include <linux/delay.h>
#include <linux/usb.h>
-#include <linux/smp_lock.h>
#include <linux/mutex.h>
#include "dabusb.h"
diff --git a/drivers/media/video/ov511.h b/drivers/media/video/ov511.h
index 68b082b..18c6422 100644
--- a/drivers/media/video/ov511.h
+++ b/drivers/media/video/ov511.h
@@ -4,7 +4,6 @@
#include <asm/uaccess.h>
#include <linux/videodev.h>
#include <media/v4l2-common.h>
-#include <linux/smp_lock.h>
#include <linux/usb.h>
#include <linux/mutex.h>
diff --git a/drivers/media/video/pvrusb2/pvrusb2-main.c b/drivers/media/video/pvrusb2/pvrusb2-main.c
index e976c48..9ea41c6 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-main.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-main.c
@@ -25,7 +25,6 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
-#include <linux/smp_lock.h>
#include <linux/usb.h>
#include <linux/videodev2.h>
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c
index dd759d6..7b56041 100644
--- a/drivers/media/video/saa7134/saa7134-tvaudio.c
+++ b/drivers/media/video/saa7134/saa7134-tvaudio.c
@@ -27,7 +27,6 @@
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/delay.h>
-#include <linux/smp_lock.h>
#include <asm/div64.h>
#include "saa7134-reg.h"
diff --git a/drivers/media/video/se401.h b/drivers/media/video/se401.h
index c0891b3..835ef87 100644
--- a/drivers/media/video/se401.h
+++ b/drivers/media/video/se401.h
@@ -5,7 +5,6 @@
#include <asm/uaccess.h>
#include <linux/videodev.h>
#include <media/v4l2-common.h>
-#include <linux/smp_lock.h>
#include <linux/mutex.h>
#define se401_DEBUG /* Turn on debug messages */
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index a2da5d2..c9bf9db 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -26,7 +26,6 @@
#include <linux/videodev.h>
#include <linux/i2c.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/kthread.h>
#include <linux/freezer.h>
diff --git a/drivers/media/video/usbvideo/usbvideo.c b/drivers/media/video/usbvideo/usbvideo.c
index 687f026..37ce36b 100644
--- a/drivers/media/video/usbvideo/usbvideo.c
+++ b/drivers/media/video/usbvideo/usbvideo.c
@@ -20,7 +20,6 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/mm.h>
-#include <linux/smp_lock.h>
#include <linux/vmalloc.h>
#include <linux/init.h>
#include <linux/spinlock.h>
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
index bcb551a..9118a62 100644
--- a/drivers/media/video/usbvision/usbvision-core.c
+++ b/drivers/media/video/usbvision/usbvision-core.c
@@ -30,7 +30,6 @@
#include <linux/mm.h>
#include <linux/utsname.h>
#include <linux/highmem.h>
-#include <linux/smp_lock.h>
#include <linux/videodev.h>
#include <linux/vmalloc.h>
#include <linux/module.h>
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index 2167041..aa3258b 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -52,7 +52,6 @@
#include <linux/mm.h>
#include <linux/utsname.h>
#include <linux/highmem.h>
-#include <linux/smp_lock.h>
#include <linux/videodev.h>
#include <linux/vmalloc.h>
#include <linux/module.h>
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index d2c1ae0..a861e15 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -23,7 +23,6 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
-#include <linux/smp_lock.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/file.h>
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index 49f1df7..13ee550 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -47,7 +47,6 @@
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
-#include <linux/smp_lock.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/errno.h>
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c
index 80ac5f8..5263b50 100644
--- a/drivers/media/video/videodev.c
+++ b/drivers/media/video/videodev.c
@@ -30,7 +30,6 @@
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
-#include <linux/smp_lock.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/errno.h>
diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c
index 0743237..cf0ed6c 100644
--- a/drivers/media/video/zoran_driver.c
+++ b/drivers/media/video/zoran_driver.c
@@ -2034,7 +2034,7 @@
* but moving the free code outside the munmap() handler fixes
* all this... If someone knows why, please explain me (Ronald)
*/
- if (!!mutex_trylock(&zr->resource_lock)) {
+ if (mutex_trylock(&zr->resource_lock)) {
/* we obtained it! Let's try to free some things */
if (fh->jpg_buffers.ready_to_be_freed)
jpg_fbuffer_free(file);
diff --git a/drivers/message/i2o/i2o_lan.h b/drivers/message/i2o/i2o_lan.h
deleted file mode 100644
index 6502b81..0000000
--- a/drivers/message/i2o/i2o_lan.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * i2o_lan.h I2O LAN Class definitions
- *
- * I2O LAN CLASS OSM May 26th 2000
- *
- * (C) Copyright 1999, 2000 University of Helsinki,
- * Department of Computer Science
- *
- * This code is still under development / test.
- *
- * Author: Auvo Häkkinen <Auvo.Hakkinen@cs.Helsinki.FI>
- * Juha Sievänen <Juha.Sievanen@cs.Helsinki.FI>
- * Taneli Vähäkangas <Taneli.Vahakangas@cs.Helsinki.FI>
- */
-
-#ifndef _I2O_LAN_H
-#define _I2O_LAN_H
-
-/* Default values for tunable parameters first */
-
-#define I2O_LAN_MAX_BUCKETS_OUT 96
-#define I2O_LAN_BUCKET_THRESH 18 /* 9 buckets in one message */
-#define I2O_LAN_RX_COPYBREAK 200
-#define I2O_LAN_TX_TIMEOUT (1*HZ)
-#define I2O_LAN_TX_BATCH_MODE 2 /* 2=automatic, 1=on, 0=off */
-#define I2O_LAN_EVENT_MASK 0 /* 0=None, 0xFFC00002=All */
-
-/* LAN types */
-#define I2O_LAN_ETHERNET 0x0030
-#define I2O_LAN_100VG 0x0040
-#define I2O_LAN_TR 0x0050
-#define I2O_LAN_FDDI 0x0060
-#define I2O_LAN_FIBRE_CHANNEL 0x0070
-#define I2O_LAN_UNKNOWN 0x00000000
-
-/* Connector types */
-
-/* Ethernet */
-#define I2O_LAN_AUI (I2O_LAN_ETHERNET << 4) + 0x00000001
-#define I2O_LAN_10BASE5 (I2O_LAN_ETHERNET << 4) + 0x00000002
-#define I2O_LAN_FIORL (I2O_LAN_ETHERNET << 4) + 0x00000003
-#define I2O_LAN_10BASE2 (I2O_LAN_ETHERNET << 4) + 0x00000004
-#define I2O_LAN_10BROAD36 (I2O_LAN_ETHERNET << 4) + 0x00000005
-#define I2O_LAN_10BASE_T (I2O_LAN_ETHERNET << 4) + 0x00000006
-#define I2O_LAN_10BASE_FP (I2O_LAN_ETHERNET << 4) + 0x00000007
-#define I2O_LAN_10BASE_FB (I2O_LAN_ETHERNET << 4) + 0x00000008
-#define I2O_LAN_10BASE_FL (I2O_LAN_ETHERNET << 4) + 0x00000009
-#define I2O_LAN_100BASE_TX (I2O_LAN_ETHERNET << 4) + 0x0000000A
-#define I2O_LAN_100BASE_FX (I2O_LAN_ETHERNET << 4) + 0x0000000B
-#define I2O_LAN_100BASE_T4 (I2O_LAN_ETHERNET << 4) + 0x0000000C
-#define I2O_LAN_1000BASE_SX (I2O_LAN_ETHERNET << 4) + 0x0000000D
-#define I2O_LAN_1000BASE_LX (I2O_LAN_ETHERNET << 4) + 0x0000000E
-#define I2O_LAN_1000BASE_CX (I2O_LAN_ETHERNET << 4) + 0x0000000F
-#define I2O_LAN_1000BASE_T (I2O_LAN_ETHERNET << 4) + 0x00000010
-
-/* AnyLAN */
-#define I2O_LAN_100VG_ETHERNET (I2O_LAN_100VG << 4) + 0x00000001
-#define I2O_LAN_100VG_TR (I2O_LAN_100VG << 4) + 0x00000002
-
-/* Token Ring */
-#define I2O_LAN_4MBIT (I2O_LAN_TR << 4) + 0x00000001
-#define I2O_LAN_16MBIT (I2O_LAN_TR << 4) + 0x00000002
-
-/* FDDI */
-#define I2O_LAN_125MBAUD (I2O_LAN_FDDI << 4) + 0x00000001
-
-/* Fibre Channel */
-#define I2O_LAN_POINT_POINT (I2O_LAN_FIBRE_CHANNEL << 4) + 0x00000001
-#define I2O_LAN_ARB_LOOP (I2O_LAN_FIBRE_CHANNEL << 4) + 0x00000002
-#define I2O_LAN_PUBLIC_LOOP (I2O_LAN_FIBRE_CHANNEL << 4) + 0x00000003
-#define I2O_LAN_FABRIC (I2O_LAN_FIBRE_CHANNEL << 4) + 0x00000004
-
-#define I2O_LAN_EMULATION 0x00000F00
-#define I2O_LAN_OTHER 0x00000F01
-#define I2O_LAN_DEFAULT 0xFFFFFFFF
-
-/* LAN class functions */
-
-#define LAN_PACKET_SEND 0x3B
-#define LAN_SDU_SEND 0x3D
-#define LAN_RECEIVE_POST 0x3E
-#define LAN_RESET 0x35
-#define LAN_SUSPEND 0x37
-
-/* LAN DetailedStatusCode defines */
-#define I2O_LAN_DSC_SUCCESS 0x00
-#define I2O_LAN_DSC_DEVICE_FAILURE 0x01
-#define I2O_LAN_DSC_DESTINATION_NOT_FOUND 0x02
-#define I2O_LAN_DSC_TRANSMIT_ERROR 0x03
-#define I2O_LAN_DSC_TRANSMIT_ABORTED 0x04
-#define I2O_LAN_DSC_RECEIVE_ERROR 0x05
-#define I2O_LAN_DSC_RECEIVE_ABORTED 0x06
-#define I2O_LAN_DSC_DMA_ERROR 0x07
-#define I2O_LAN_DSC_BAD_PACKET_DETECTED 0x08
-#define I2O_LAN_DSC_OUT_OF_MEMORY 0x09
-#define I2O_LAN_DSC_BUCKET_OVERRUN 0x0A
-#define I2O_LAN_DSC_IOP_INTERNAL_ERROR 0x0B
-#define I2O_LAN_DSC_CANCELED 0x0C
-#define I2O_LAN_DSC_INVALID_TRANSACTION_CONTEXT 0x0D
-#define I2O_LAN_DSC_DEST_ADDRESS_DETECTED 0x0E
-#define I2O_LAN_DSC_DEST_ADDRESS_OMITTED 0x0F
-#define I2O_LAN_DSC_PARTIAL_PACKET_RETURNED 0x10
-#define I2O_LAN_DSC_SUSPENDED 0x11
-
-struct i2o_packet_info {
- u32 offset:24;
- u32 flags:8;
- u32 len:24;
- u32 status:8;
-};
-
-struct i2o_bucket_descriptor {
- u32 context; /* FIXME: 64bit support */
- struct i2o_packet_info packet_info[1];
-};
-
-/* Event Indicator Mask Flags for LAN OSM */
-
-#define I2O_LAN_EVT_LINK_DOWN 0x01
-#define I2O_LAN_EVT_LINK_UP 0x02
-#define I2O_LAN_EVT_MEDIA_CHANGE 0x04
-
-#include <linux/netdevice.h>
-#include <linux/fddidevice.h>
-
-struct i2o_lan_local {
- u8 unit;
- struct i2o_device *i2o_dev;
-
- struct fddi_statistics stats; /* see also struct net_device_stats */
- unsigned short (*type_trans) (struct sk_buff *, struct net_device *);
- atomic_t buckets_out; /* nbr of unused buckets on DDM */
- atomic_t tx_out; /* outstanding TXes */
- u8 tx_count; /* packets in one TX message frame */
- u16 tx_max_out; /* DDM's Tx queue len */
- u8 sgl_max; /* max SGLs in one message frame */
- u32 m; /* IOP address of the batch msg frame */
-
- struct work_struct i2o_batch_send_task;
- int send_active;
- struct sk_buff **i2o_fbl; /* Free bucket list (to reuse skbs) */
- int i2o_fbl_tail;
- spinlock_t fbl_lock;
-
- spinlock_t tx_lock;
-
- u32 max_size_mc_table; /* max number of multicast addresses */
-
- /* LAN OSM configurable parameters are here: */
-
- u16 max_buckets_out; /* max nbr of buckets to send to DDM */
- u16 bucket_thresh; /* send more when this many used */
- u16 rx_copybreak;
-
- u8 tx_batch_mode; /* Set when using batch mode sends */
- u32 i2o_event_mask; /* To turn on interesting event flags */
-};
-
-#endif /* _I2O_LAN_H */
diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c
index ce1a481..cb8c264 100644
--- a/drivers/mfd/ucb1x00-ts.c
+++ b/drivers/mfd/ucb1x00-ts.c
@@ -21,7 +21,6 @@
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/sched.h>
#include <linux/completion.h>
#include <linux/delay.h>
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index a3c525b..877e790 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -25,6 +25,15 @@
information on the specific driver level and support statement
for your IBM server.
+config PHANTOM
+ tristate "Sensable PHANToM"
+ depends on PCI
+ help
+ Say Y here if you want to build a driver for Sensable PHANToM device.
+
+ If you choose to build module, its name will be phantom. If unsure,
+ say N here.
+
If unsure, say N.
@@ -178,4 +187,13 @@
If you are not sure, say Y here.
+config BLINK
+ tristate "Keyboard blink driver"
+ help
+ Driver that when loaded will blink the keyboard LEDs continuously.
+ This is useful for debugging and for kernels that cannot necessarily
+ output something to the screen like kexec kernels to give the user
+ a visual indication that the kernel is doing something.
+
+
endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index e325164..5b6d46d 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -7,9 +7,11 @@
obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/
obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o
obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o
+obj-$(CONFIG_BLINK) += blink.o
obj-$(CONFIG_LKDTM) += lkdtm.o
obj-$(CONFIG_TIFM_CORE) += tifm_core.o
obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o
+obj-$(CONFIG_PHANTOM) += phantom.o
obj-$(CONFIG_SGI_IOC4) += ioc4.o
obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o
obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o
diff --git a/drivers/misc/blink.c b/drivers/misc/blink.c
new file mode 100644
index 0000000..634431c
--- /dev/null
+++ b/drivers/misc/blink.c
@@ -0,0 +1,27 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/timer.h>
+#include <linux/jiffies.h>
+
+static void do_blink(unsigned long data);
+
+static DEFINE_TIMER(blink_timer, do_blink, 0 ,0);
+
+static void do_blink(unsigned long data)
+{
+ static long count;
+ if (panic_blink)
+ panic_blink(count++);
+ blink_timer.expires = jiffies + msecs_to_jiffies(1);
+ add_timer(&blink_timer);
+}
+
+static int blink_init(void)
+{
+ printk(KERN_INFO "Enabling keyboard blinking\n");
+ do_blink(0);
+ return 0;
+}
+
+module_init(blink_init);
+
diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c
new file mode 100644
index 0000000..35b139b
--- /dev/null
+++ b/drivers/misc/phantom.c
@@ -0,0 +1,463 @@
+/*
+ * Copyright (C) 2005-2007 Jiri Slaby <jirislaby@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * You need an userspace library to cooperate with this driver. It (and other
+ * info) may be obtained here:
+ * http://www.fi.muni.cz/~xslaby/phantom.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/pci.h>
+#include <linux/fs.h>
+#include <linux/poll.h>
+#include <linux/interrupt.h>
+#include <linux/cdev.h>
+#include <linux/phantom.h>
+
+#include <asm/atomic.h>
+#include <asm/io.h>
+
+#define PHANTOM_VERSION "n0.9.5"
+
+#define PHANTOM_MAX_MINORS 8
+
+#define PHN_IRQCTL 0x4c /* irq control in caddr space */
+
+#define PHB_RUNNING 1
+
+static struct class *phantom_class;
+static int phantom_major;
+
+struct phantom_device {
+ unsigned int opened;
+ void __iomem *caddr;
+ u32 __iomem *iaddr;
+ u32 __iomem *oaddr;
+ unsigned long status;
+ atomic_t counter;
+
+ wait_queue_head_t wait;
+ struct cdev cdev;
+
+ struct mutex open_lock;
+};
+
+static unsigned char phantom_devices[PHANTOM_MAX_MINORS];
+
+static int phantom_status(struct phantom_device *dev, unsigned long newstat)
+{
+ pr_debug("phantom_status %lx %lx\n", dev->status, newstat);
+
+ if (!(dev->status & PHB_RUNNING) && (newstat & PHB_RUNNING)) {
+ atomic_set(&dev->counter, 0);
+ iowrite32(PHN_CTL_IRQ, dev->iaddr + PHN_CONTROL);
+ iowrite32(0x43, dev->caddr + PHN_IRQCTL);
+ } else if ((dev->status & PHB_RUNNING) && !(newstat & PHB_RUNNING))
+ iowrite32(0, dev->caddr + PHN_IRQCTL);
+
+ dev->status = newstat;
+
+ return 0;
+}
+
+/*
+ * File ops
+ */
+
+static int phantom_ioctl(struct inode *inode, struct file *file, u_int cmd,
+ u_long arg)
+{
+ struct phantom_device *dev = file->private_data;
+ struct phm_regs rs;
+ struct phm_reg r;
+ void __user *argp = (void __user *)arg;
+ unsigned int i;
+
+ if (_IOC_TYPE(cmd) != PH_IOC_MAGIC ||
+ _IOC_NR(cmd) > PH_IOC_MAXNR)
+ return -ENOTTY;
+
+ switch (cmd) {
+ case PHN_SET_REG:
+ if (copy_from_user(&r, argp, sizeof(r)))
+ return -EFAULT;
+
+ if (r.reg > 7)
+ return -EINVAL;
+
+ if (r.reg == PHN_CONTROL && (r.value & PHN_CTL_IRQ) &&
+ phantom_status(dev, dev->status | PHB_RUNNING))
+ return -ENODEV;
+
+ pr_debug("phantom: writing %x to %u\n", r.value, r.reg);
+ iowrite32(r.value, dev->iaddr + r.reg);
+
+ if (r.reg == PHN_CONTROL && !(r.value & PHN_CTL_IRQ))
+ phantom_status(dev, dev->status & ~PHB_RUNNING);
+ break;
+ case PHN_SET_REGS:
+ if (copy_from_user(&rs, argp, sizeof(rs)))
+ return -EFAULT;
+
+ pr_debug("phantom: SRS %u regs %x\n", rs.count, rs.mask);
+ for (i = 0; i < min(rs.count, 8U); i++)
+ if ((1 << i) & rs.mask)
+ iowrite32(rs.values[i], dev->oaddr + i);
+ break;
+ case PHN_GET_REG:
+ if (copy_from_user(&r, argp, sizeof(r)))
+ return -EFAULT;
+
+ if (r.reg > 7)
+ return -EINVAL;
+
+ r.value = ioread32(dev->iaddr + r.reg);
+
+ if (copy_to_user(argp, &r, sizeof(r)))
+ return -EFAULT;
+ break;
+ case PHN_GET_REGS:
+ if (copy_from_user(&rs, argp, sizeof(rs)))
+ return -EFAULT;
+
+ pr_debug("phantom: GRS %u regs %x\n", rs.count, rs.mask);
+ for (i = 0; i < min(rs.count, 8U); i++)
+ if ((1 << i) & rs.mask)
+ rs.values[i] = ioread32(dev->iaddr + i);
+
+ if (copy_to_user(argp, &rs, sizeof(rs)))
+ return -EFAULT;
+ break;
+ default:
+ return -ENOTTY;
+ }
+
+ return 0;
+}
+
+static int phantom_open(struct inode *inode, struct file *file)
+{
+ struct phantom_device *dev = container_of(inode->i_cdev,
+ struct phantom_device, cdev);
+
+ nonseekable_open(inode, file);
+
+ if (mutex_lock_interruptible(&dev->open_lock))
+ return -ERESTARTSYS;
+
+ if (dev->opened) {
+ mutex_unlock(&dev->open_lock);
+ return -EINVAL;
+ }
+
+ file->private_data = dev;
+
+ dev->opened++;
+ mutex_unlock(&dev->open_lock);
+
+ return 0;
+}
+
+static int phantom_release(struct inode *inode, struct file *file)
+{
+ struct phantom_device *dev = file->private_data;
+
+ mutex_lock(&dev->open_lock);
+
+ dev->opened = 0;
+ phantom_status(dev, dev->status & ~PHB_RUNNING);
+
+ mutex_unlock(&dev->open_lock);
+
+ return 0;
+}
+
+static unsigned int phantom_poll(struct file *file, poll_table *wait)
+{
+ struct phantom_device *dev = file->private_data;
+ unsigned int mask = 0;
+
+ pr_debug("phantom_poll: %d\n", atomic_read(&dev->counter));
+ poll_wait(file, &dev->wait, wait);
+ if (atomic_read(&dev->counter)) {
+ mask = POLLIN | POLLRDNORM;
+ atomic_dec(&dev->counter);
+ } else if ((dev->status & PHB_RUNNING) == 0)
+ mask = POLLIN | POLLRDNORM | POLLERR;
+ pr_debug("phantom_poll end: %x/%d\n", mask, atomic_read(&dev->counter));
+
+ return mask;
+}
+
+static struct file_operations phantom_file_ops = {
+ .open = phantom_open,
+ .release = phantom_release,
+ .ioctl = phantom_ioctl,
+ .poll = phantom_poll,
+};
+
+static irqreturn_t phantom_isr(int irq, void *data)
+{
+ struct phantom_device *dev = data;
+
+ if (!(ioread32(dev->iaddr + PHN_CONTROL) & PHN_CTL_IRQ))
+ return IRQ_NONE;
+
+ iowrite32(0, dev->iaddr);
+ iowrite32(0xc0, dev->iaddr);
+
+ atomic_inc(&dev->counter);
+ wake_up_interruptible(&dev->wait);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * Init and deinit driver
+ */
+
+static unsigned int __devinit phantom_get_free(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < PHANTOM_MAX_MINORS; i++)
+ if (phantom_devices[i] == 0)
+ break;
+
+ return i;
+}
+
+static int __devinit phantom_probe(struct pci_dev *pdev,
+ const struct pci_device_id *pci_id)
+{
+ struct phantom_device *pht;
+ unsigned int minor;
+ int retval;
+
+ retval = pci_enable_device(pdev);
+ if (retval)
+ goto err;
+
+ minor = phantom_get_free();
+ if (minor == PHANTOM_MAX_MINORS) {
+ dev_err(&pdev->dev, "too many devices found!\n");
+ retval = -EIO;
+ goto err_dis;
+ }
+
+ phantom_devices[minor] = 1;
+
+ retval = pci_request_regions(pdev, "phantom");
+ if (retval)
+ goto err_null;
+
+ retval = -ENOMEM;
+ pht = kzalloc(sizeof(*pht), GFP_KERNEL);
+ if (pht == NULL) {
+ dev_err(&pdev->dev, "unable to allocate device\n");
+ goto err_reg;
+ }
+
+ pht->caddr = pci_iomap(pdev, 0, 0);
+ if (pht->caddr == NULL) {
+ dev_err(&pdev->dev, "can't remap conf space\n");
+ goto err_fr;
+ }
+ pht->iaddr = pci_iomap(pdev, 2, 0);
+ if (pht->iaddr == NULL) {
+ dev_err(&pdev->dev, "can't remap input space\n");
+ goto err_unmc;
+ }
+ pht->oaddr = pci_iomap(pdev, 3, 0);
+ if (pht->oaddr == NULL) {
+ dev_err(&pdev->dev, "can't remap output space\n");
+ goto err_unmi;
+ }
+
+ mutex_init(&pht->open_lock);
+ init_waitqueue_head(&pht->wait);
+ cdev_init(&pht->cdev, &phantom_file_ops);
+ pht->cdev.owner = THIS_MODULE;
+
+ iowrite32(0, pht->caddr + PHN_IRQCTL);
+ retval = request_irq(pdev->irq, phantom_isr,
+ IRQF_SHARED | IRQF_DISABLED, "phantom", pht);
+ if (retval) {
+ dev_err(&pdev->dev, "can't establish ISR\n");
+ goto err_unmo;
+ }
+
+ retval = cdev_add(&pht->cdev, MKDEV(phantom_major, minor), 1);
+ if (retval) {
+ dev_err(&pdev->dev, "chardev registration failed\n");
+ goto err_irq;
+ }
+
+ if (IS_ERR(device_create(phantom_class, &pdev->dev, MKDEV(phantom_major,
+ minor), "phantom%u", minor)))
+ dev_err(&pdev->dev, "can't create device\n");
+
+ pci_set_drvdata(pdev, pht);
+
+ return 0;
+err_irq:
+ free_irq(pdev->irq, pht);
+err_unmo:
+ pci_iounmap(pdev, pht->oaddr);
+err_unmi:
+ pci_iounmap(pdev, pht->iaddr);
+err_unmc:
+ pci_iounmap(pdev, pht->caddr);
+err_fr:
+ kfree(pht);
+err_reg:
+ pci_release_regions(pdev);
+err_null:
+ phantom_devices[minor] = 0;
+err_dis:
+ pci_disable_device(pdev);
+err:
+ return retval;
+}
+
+static void __devexit phantom_remove(struct pci_dev *pdev)
+{
+ struct phantom_device *pht = pci_get_drvdata(pdev);
+ unsigned int minor = MINOR(pht->cdev.dev);
+
+ device_destroy(phantom_class, MKDEV(phantom_major, minor));
+
+ cdev_del(&pht->cdev);
+
+ iowrite32(0, pht->caddr + PHN_IRQCTL);
+ free_irq(pdev->irq, pht);
+
+ pci_iounmap(pdev, pht->oaddr);
+ pci_iounmap(pdev, pht->iaddr);
+ pci_iounmap(pdev, pht->caddr);
+
+ kfree(pht);
+
+ pci_release_regions(pdev);
+
+ phantom_devices[minor] = 0;
+
+ pci_disable_device(pdev);
+}
+
+#ifdef CONFIG_PM
+static int phantom_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct phantom_device *dev = pci_get_drvdata(pdev);
+
+ iowrite32(0, dev->caddr + PHN_IRQCTL);
+
+ return 0;
+}
+
+static int phantom_resume(struct pci_dev *pdev)
+{
+ struct phantom_device *dev = pci_get_drvdata(pdev);
+
+ iowrite32(0, dev->caddr + PHN_IRQCTL);
+
+ return 0;
+}
+#else
+#define phantom_suspend NULL
+#define phantom_resume NULL
+#endif
+
+static struct pci_device_id phantom_pci_tbl[] __devinitdata = {
+ { PCI_DEVICE(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050),
+ .class = PCI_CLASS_BRIDGE_OTHER << 8, .class_mask = 0xffff00 },
+ { 0, }
+};
+MODULE_DEVICE_TABLE(pci, phantom_pci_tbl);
+
+static struct pci_driver phantom_pci_driver = {
+ .name = "phantom",
+ .id_table = phantom_pci_tbl,
+ .probe = phantom_probe,
+ .remove = __devexit_p(phantom_remove),
+ .suspend = phantom_suspend,
+ .resume = phantom_resume
+};
+
+static ssize_t phantom_show_version(struct class *cls, char *buf)
+{
+ return sprintf(buf, PHANTOM_VERSION "\n");
+}
+
+static CLASS_ATTR(version, 0444, phantom_show_version, NULL);
+
+static int __init phantom_init(void)
+{
+ int retval;
+ dev_t dev;
+
+ phantom_class = class_create(THIS_MODULE, "phantom");
+ if (IS_ERR(phantom_class)) {
+ retval = PTR_ERR(phantom_class);
+ printk(KERN_ERR "phantom: can't register phantom class\n");
+ goto err;
+ }
+ retval = class_create_file(phantom_class, &class_attr_version);
+ if (retval) {
+ printk(KERN_ERR "phantom: can't create sysfs version file\n");
+ goto err_class;
+ }
+
+ retval = alloc_chrdev_region(&dev, 0, PHANTOM_MAX_MINORS, "phantom");
+ if (retval) {
+ printk(KERN_ERR "phantom: can't register character device\n");
+ goto err_attr;
+ }
+ phantom_major = MAJOR(dev);
+
+ retval = pci_register_driver(&phantom_pci_driver);
+ if (retval) {
+ printk(KERN_ERR "phantom: can't register pci driver\n");
+ goto err_unchr;
+ }
+
+ printk(KERN_INFO "Phantom Linux Driver, version " PHANTOM_VERSION ", "
+ "init OK\n");
+
+ return 0;
+err_unchr:
+ unregister_chrdev_region(dev, PHANTOM_MAX_MINORS);
+err_attr:
+ class_remove_file(phantom_class, &class_attr_version);
+err_class:
+ class_destroy(phantom_class);
+err:
+ return retval;
+}
+
+static void __exit phantom_exit(void)
+{
+ pci_unregister_driver(&phantom_pci_driver);
+
+ unregister_chrdev_region(MKDEV(phantom_major, 0), PHANTOM_MAX_MINORS);
+
+ class_remove_file(phantom_class, &class_attr_version);
+ class_destroy(phantom_class);
+
+ pr_debug("phantom: module successfully removed\n");
+}
+
+module_init(phantom_init);
+module_exit(phantom_exit);
+
+MODULE_AUTHOR("Jiri Slaby <jirislaby@gmail.com>");
+MODULE_DESCRIPTION("Sensable Phantom driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(PHANTOM_VERSION);
diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c
index 7efe744..72107dc 100644
--- a/drivers/mtd/maps/physmap_of.c
+++ b/drivers/mtd/maps/physmap_of.c
@@ -48,7 +48,7 @@
const u32 *part;
const char *name;
- part = get_property(node, "partitions", &plen);
+ part = of_get_property(node, "partitions", &plen);
if (part == NULL)
goto err;
@@ -59,7 +59,7 @@
goto err;
}
- name = get_property(node, "partition-names", &plen);
+ name = of_get_property(node, "partition-names", &plen);
for (i = 0; i < retval; i++) {
(*parts)[i].offset = *part++;
@@ -153,7 +153,7 @@
goto err_out;
}
- width = get_property(dp, "bank-width", NULL);
+ width = of_get_property(dp, "bank-width", NULL);
if (width == NULL) {
dev_err(&dev->dev, "Can't get the flash bank width!\n");
err = -EINVAL;
@@ -174,7 +174,7 @@
simple_map_init(&info->map);
- of_probe = get_property(dp, "probe-type", NULL);
+ of_probe = of_get_property(dp, "probe-type", NULL);
if (of_probe == NULL) {
probe_type = rom_probe_types;
for (; info->mtd == NULL && *probe_type != NULL; probe_type++)
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 524b83b..51bc7e2 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -216,7 +216,7 @@
int last_devnum = -1;
struct gendisk *gd;
- if (!!mutex_trylock(&mtd_table_mutex)) {
+ if (mutex_trylock(&mtd_table_mutex)) {
mutex_unlock(&mtd_table_mutex);
BUG();
}
@@ -294,7 +294,7 @@
int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
{
- if (!!mutex_trylock(&mtd_table_mutex)) {
+ if (mutex_trylock(&mtd_table_mutex)) {
mutex_unlock(&mtd_table_mutex);
BUG();
}
diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c
index 4612725..9b8d7d9 100644
--- a/drivers/net/bmac.c
+++ b/drivers/net/bmac.c
@@ -1260,9 +1260,10 @@
printk(KERN_ERR "BMAC: can't use, need 3 addrs and 3 intrs\n");
return -ENODEV;
}
- prop_addr = get_property(macio_get_of_node(mdev), "mac-address", NULL);
+ prop_addr = of_get_property(macio_get_of_node(mdev),
+ "mac-address", NULL);
if (prop_addr == NULL) {
- prop_addr = get_property(macio_get_of_node(mdev),
+ prop_addr = of_get_property(macio_get_of_node(mdev),
"local-mac-address", NULL);
if (prop_addr == NULL) {
printk(KERN_ERR "BMAC: Can't get mac-address\n");
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index c7a5614..a1bd2d8 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -2603,14 +2603,13 @@
{
struct device_node *lhea_dn;
struct device_node *eth_dn = NULL;
-
- u32 *dn_log_port_id;
+ const u32 *dn_log_port_id;
int i = 0;
lhea_dn = adapter->ebus_dev->ofdev.node;
while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) {
- dn_log_port_id = (u32*)get_property(eth_dn, "ibm,hea-port-no",
+ dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no",
NULL);
if (!dn_log_port_id) {
ehea_error("bad device node: eth_dn name=%s",
@@ -2645,12 +2644,12 @@
{
struct device_node *lhea_dn;
struct device_node *eth_dn = NULL;
- u32 *dn_log_port_id;
+ const u32 *dn_log_port_id;
lhea_dn = adapter->ebus_dev->ofdev.node;
while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) {
- dn_log_port_id = (u32*)get_property(eth_dn, "ibm,hea-port-no",
+ dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no",
NULL);
if (dn_log_port_id)
if (*dn_log_port_id == logical_port_id)
@@ -2774,7 +2773,7 @@
const struct of_device_id *id)
{
struct ehea_adapter *adapter;
- u64 *adapter_handle;
+ const u64 *adapter_handle;
int ret;
if (!dev || !dev->ofdev.node) {
@@ -2791,7 +2790,7 @@
adapter->ebus_dev = dev;
- adapter_handle = (u64*)get_property(dev->ofdev.node, "ibm,hea-handle",
+ adapter_handle = of_get_property(dev->ofdev.node, "ibm,hea-handle",
NULL);
if (adapter_handle)
adapter->handle = *adapter_handle;
diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c
index 17b0c3a..9d6c8f3 100644
--- a/drivers/net/irda/sir_dev.c
+++ b/drivers/net/irda/sir_dev.c
@@ -14,7 +14,6 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <net/irda/irda.h>
diff --git a/drivers/net/irda/sir_dongle.c b/drivers/net/irda/sir_dongle.c
index d7e32d9..25d5b8a 100644
--- a/drivers/net/irda/sir_dongle.c
+++ b/drivers/net/irda/sir_dongle.c
@@ -14,7 +14,6 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/kmod.h>
#include <linux/mutex.h>
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c
index 198bf3b..9043bf4 100644
--- a/drivers/net/irda/smsc-ircc2.c
+++ b/drivers/net/irda/smsc-ircc2.c
@@ -79,11 +79,17 @@
MODULE_DESCRIPTION("SMC IrCC SIR/FIR controller driver");
MODULE_LICENSE("GPL");
-static int ircc_dma = 255;
+static int smsc_nopnp;
+module_param_named(nopnp, smsc_nopnp, bool, 0);
+MODULE_PARM_DESC(nopnp, "Do not use PNP to detect controller settings");
+
+#define DMA_INVAL 255
+static int ircc_dma = DMA_INVAL;
module_param(ircc_dma, int, 0);
MODULE_PARM_DESC(ircc_dma, "DMA channel");
-static int ircc_irq = 255;
+#define IRQ_INVAL 255
+static int ircc_irq = IRQ_INVAL;
module_param(ircc_irq, int, 0);
MODULE_PARM_DESC(ircc_irq, "IRQ line");
@@ -360,7 +366,6 @@
iobase + IRCC_MASTER);
}
-#ifdef CONFIG_PNP
/* PNP hotplug support */
static const struct pnp_device_id smsc_ircc_pnp_table[] = {
{ .id = "SMCf010", .driver_data = 0 },
@@ -368,7 +373,35 @@
{ }
};
MODULE_DEVICE_TABLE(pnp, smsc_ircc_pnp_table);
-#endif
+
+static int pnp_driver_registered;
+
+static int __init smsc_ircc_pnp_probe(struct pnp_dev *dev,
+ const struct pnp_device_id *dev_id)
+{
+ unsigned int firbase, sirbase;
+ u8 dma, irq;
+
+ if (!(pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
+ pnp_dma_valid(dev, 0) && pnp_irq_valid(dev, 0)))
+ return -EINVAL;
+
+ sirbase = pnp_port_start(dev, 0);
+ firbase = pnp_port_start(dev, 1);
+ dma = pnp_dma(dev, 0);
+ irq = pnp_irq(dev, 0);
+
+ if (smsc_ircc_open(firbase, sirbase, dma, irq))
+ return -ENODEV;
+
+ return 0;
+}
+
+static struct pnp_driver smsc_ircc_pnp_driver = {
+ .name = "smsc-ircc2",
+ .id_table = smsc_ircc_pnp_table,
+ .probe = smsc_ircc_pnp_probe,
+};
/*******************************************************************************
@@ -379,6 +412,35 @@
*
*******************************************************************************/
+static int __init smsc_ircc_legacy_probe(void)
+{
+ int ret = 0;
+
+ if (ircc_fir > 0 && ircc_sir > 0) {
+ IRDA_MESSAGE(" Overriding FIR address 0x%04x\n", ircc_fir);
+ IRDA_MESSAGE(" Overriding SIR address 0x%04x\n", ircc_sir);
+
+ if (smsc_ircc_open(ircc_fir, ircc_sir, ircc_dma, ircc_irq))
+ ret = -ENODEV;
+ } else {
+ ret = -ENODEV;
+
+ /* try user provided configuration register base address */
+ if (ircc_cfg > 0) {
+ IRDA_MESSAGE(" Overriding configuration address "
+ "0x%04x\n", ircc_cfg);
+ if (!smsc_superio_fdc(ircc_cfg))
+ ret = 0;
+ if (!smsc_superio_lpc(ircc_cfg))
+ ret = 0;
+ }
+
+ if (smsc_ircc_look_for_chips() > 0)
+ ret = 0;
+ }
+ return ret;
+}
+
/*
* Function smsc_ircc_init ()
*
@@ -406,31 +468,20 @@
dev_count = 0;
- if (ircc_fir > 0 && ircc_sir > 0) {
- IRDA_MESSAGE(" Overriding FIR address 0x%04x\n", ircc_fir);
- IRDA_MESSAGE(" Overriding SIR address 0x%04x\n", ircc_sir);
-
- if (smsc_ircc_open(ircc_fir, ircc_sir, ircc_dma, ircc_irq))
- ret = -ENODEV;
+ if (smsc_nopnp || !pnp_platform_devices ||
+ ircc_cfg || ircc_fir || ircc_sir ||
+ ircc_dma != DMA_INVAL || ircc_irq != IRQ_INVAL) {
+ ret = smsc_ircc_legacy_probe();
} else {
- ret = -ENODEV;
-
- /* try user provided configuration register base address */
- if (ircc_cfg > 0) {
- IRDA_MESSAGE(" Overriding configuration address "
- "0x%04x\n", ircc_cfg);
- if (!smsc_superio_fdc(ircc_cfg))
- ret = 0;
- if (!smsc_superio_lpc(ircc_cfg))
- ret = 0;
- }
-
- if (smsc_ircc_look_for_chips() > 0)
- ret = 0;
+ if (pnp_register_driver(&smsc_ircc_pnp_driver) == 0)
+ pnp_driver_registered = 1;
}
- if (ret)
+ if (ret) {
+ if (pnp_driver_registered)
+ pnp_unregister_driver(&smsc_ircc_pnp_driver);
platform_driver_unregister(&smsc_ircc_driver);
+ }
return ret;
}
@@ -646,7 +697,7 @@
self->io.fifo_size = SMSC_IRCC2_FIFO_SIZE;
self->io.speed = SMSC_IRCC2_C_IRDA_FALLBACK_SPEED;
- if (irq < 255) {
+ if (irq != IRQ_INVAL) {
if (irq != chip_irq)
IRDA_MESSAGE("%s, Overriding IRQ - chip says %d, using %d\n",
driver_name, chip_irq, irq);
@@ -654,7 +705,7 @@
} else
self->io.irq = chip_irq;
- if (dma < 255) {
+ if (dma != DMA_INVAL) {
if (dma != chip_dma)
IRDA_MESSAGE("%s, Overriding DMA - chip says %d, using %d\n",
driver_name, chip_dma, dma);
@@ -1840,6 +1891,9 @@
smsc_ircc_close(dev_self[i]);
}
+ if (pnp_driver_registered)
+ pnp_unregister_driver(&smsc_ircc_pnp_driver);
+
platform_driver_unregister(&smsc_ircc_driver);
}
@@ -2836,9 +2890,9 @@
tmpconf.fir_io = ircc_fir;
if (ircc_sir != 0)
tmpconf.sir_io = ircc_sir;
- if (ircc_dma != 0xff)
+ if (ircc_dma != DMA_INVAL)
tmpconf.fir_dma = ircc_dma;
- if (ircc_irq != 0xff)
+ if (ircc_irq != IRQ_INVAL)
tmpconf.fir_irq = ircc_irq;
IRDA_MESSAGE("Detected unconfigured %s SMSC IrDA chip, pre-configuring device.\n", conf->name);
diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c
index c4be973..bf78ef1 100644
--- a/drivers/net/irda/vlsi_ir.c
+++ b/drivers/net/irda/vlsi_ir.c
@@ -44,7 +44,6 @@
#include <linux/time.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
-#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/byteorder.h>
diff --git a/drivers/net/mace.c b/drivers/net/mace.c
index b3bd623..52b9332 100644
--- a/drivers/net/mace.c
+++ b/drivers/net/mace.c
@@ -110,9 +110,9 @@
return -ENODEV;
}
- addr = get_property(mace, "mac-address", NULL);
+ addr = of_get_property(mace, "mac-address", NULL);
if (addr == NULL) {
- addr = get_property(mace, "local-mac-address", NULL);
+ addr = of_get_property(mace, "local-mac-address", NULL);
if (addr == NULL) {
printk(KERN_ERR "Can't get mac-address for MACE %s\n",
mace->full_name);
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index 6a32338..3439f8c 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -104,7 +104,6 @@
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/delay.h>
-#include <linux/smp_lock.h>
#include <linux/workqueue.h>
#include <linux/init.h>
#include <linux/ip.h> /* for iph */
diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c
index 76fe9dd..07eb9b2 100644
--- a/drivers/net/pasemi_mac.c
+++ b/drivers/net/pasemi_mac.c
@@ -80,7 +80,7 @@
return -ENOENT;
}
- maddr = get_property(dn, "mac-address", NULL);
+ maddr = of_get_property(dn, "mac-address", NULL);
if (maddr == NULL) {
dev_warn(&pdev->dev,
"no mac address in device tree, not configuring\n");
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 6d596ca..5411687 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -40,7 +40,6 @@
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
#include <linux/rwsem.h>
#include <linux/stddef.h>
#include <linux/device.h>
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index 230da14..c15e972 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -1830,7 +1830,7 @@
if (!dn)
goto out_err;
- fw_prop = get_property(dn, "firmware", &fw_size);
+ fw_prop = of_get_property(dn, "firmware", &fw_size);
if (!fw_prop)
goto out_err;
@@ -2236,7 +2236,7 @@
if (!dn)
return -EIO;
- mac = get_property(dn, "local-mac-address", NULL);
+ mac = of_get_property(dn, "local-mac-address", NULL);
if (!mac)
return -EIO;
memcpy(addr.sa_data, mac, ETH_ALEN);
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index 5da7321..4328038 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -2903,7 +2903,7 @@
struct net_device *dev = gp->dev;
const unsigned char *addr;
- addr = get_property(gp->of_node, "local-mac-address", NULL);
+ addr = of_get_property(gp->of_node, "local-mac-address", NULL);
if (addr == NULL) {
#ifdef CONFIG_SPARC
addr = idprom->id_ethaddr;
diff --git a/drivers/net/sungem_phy.c b/drivers/net/sungem_phy.c
index 56a110c..61843fd 100644
--- a/drivers/net/sungem_phy.c
+++ b/drivers/net/sungem_phy.c
@@ -451,7 +451,7 @@
if (phy->platform_data) {
struct device_node *np = of_get_parent(phy->platform_data);
int can_low_power = 1;
- if (np == NULL || get_property(np, "no-autolowpower", NULL))
+ if (np == NULL || of_get_property(np, "no-autolowpower", NULL))
can_low_power = 0;
if (can_low_power) {
/* Enable automatic low-power */
diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c
index 0bfc2c9..1aabc91 100644
--- a/drivers/net/tsi108_eth.c
+++ b/drivers/net/tsi108_eth.c
@@ -82,6 +82,7 @@
unsigned int phy; /* Index of PHY for this interface */
unsigned int irq_num;
unsigned int id;
+ unsigned int phy_type;
struct timer_list timer;/* Timer that triggers the check phy function */
unsigned int rxtail; /* Next entry in rxring to read */
@@ -1256,11 +1257,11 @@
if (i == 0)
printk(KERN_ERR "%s function time out \n", __FUNCTION__);
-#if (TSI108_PHY_TYPE == PHY_BCM54XX) /* Broadcom BCM54xx PHY */
- tsi108_write_mii(data, 0x09, 0x0300);
- tsi108_write_mii(data, 0x10, 0x1020);
- tsi108_write_mii(data, 0x1c, 0x8c00);
-#endif
+ if (data->phy_type == TSI108_PHY_BCM54XX) {
+ tsi108_write_mii(data, 0x09, 0x0300);
+ tsi108_write_mii(data, 0x10, 0x1020);
+ tsi108_write_mii(data, 0x1c, 0x8c00);
+ }
tsi108_write_mii(data,
MII_BMCR,
@@ -1587,6 +1588,7 @@
data->mii_if.supports_gmii = mii_check_gmii_support(&data->mii_if);
data->phy = einfo->phy;
+ data->phy_type = einfo->phy_type;
data->irq_num = einfo->irq_num;
data->id = pdev->id;
dev->open = tsi108_open;
diff --git a/drivers/net/tsi108_eth.h b/drivers/net/tsi108_eth.h
index 77a769d..5a77ae6 100644
--- a/drivers/net/tsi108_eth.h
+++ b/drivers/net/tsi108_eth.h
@@ -43,15 +43,6 @@
in_be32((data->phyregs + (offset)))
/*
- * PHY Configuration Options
- *
- * NOTE: Enable set of definitions corresponding to your board type
- */
-#define PHY_MV88E 1 /* Marvel 88Exxxx PHY */
-#define PHY_BCM54XX 2 /* Broardcom BCM54xx PHY */
-#define TSI108_PHY_TYPE PHY_MV88E
-
-/*
* TSI108 GIGE port registers
*/
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 16b9acd..d7aff81 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -3787,7 +3787,7 @@
ugeth_vdbg("%s: IN", __FUNCTION__);
- prop = get_property(np, "device-id", NULL);
+ prop = of_get_property(np, "device-id", NULL);
ucc_num = *prop - 1;
if ((ucc_num < 0) || (ucc_num > 7))
return -ENODEV;
@@ -3795,9 +3795,9 @@
ug_info = &ugeth_info[ucc_num];
ug_info->uf_info.ucc_num = ucc_num;
- prop = get_property(np, "rx-clock", NULL);
+ prop = of_get_property(np, "rx-clock", NULL);
ug_info->uf_info.rx_clock = *prop;
- prop = get_property(np, "tx-clock", NULL);
+ prop = of_get_property(np, "tx-clock", NULL);
ug_info->uf_info.tx_clock = *prop;
err = of_address_to_resource(np, 0, &res);
if (err)
@@ -3806,23 +3806,23 @@
ug_info->uf_info.regs = res.start;
ug_info->uf_info.irq = irq_of_parse_and_map(np, 0);
- ph = get_property(np, "phy-handle", NULL);
+ ph = of_get_property(np, "phy-handle", NULL);
phy = of_find_node_by_phandle(*ph);
if (phy == NULL)
return -ENODEV;
/* set the PHY address */
- prop = get_property(phy, "reg", NULL);
+ prop = of_get_property(phy, "reg", NULL);
if (prop == NULL)
return -1;
ug_info->phy_address = *prop;
/* get the phy interface type, or default to MII */
- prop = get_property(np, "interface-type", NULL);
+ prop = of_get_property(np, "interface-type", NULL);
if (!prop) {
/* handle interface property present in old trees */
- prop = get_property(phy, "interface", NULL);
+ prop = of_get_property(phy, "interface", NULL);
if (prop != NULL)
phy_interface = enet_to_phy_interface[*prop];
else
@@ -3832,10 +3832,10 @@
}
/* get speed, or derive from interface */
- prop = get_property(np, "max-speed", NULL);
+ prop = of_get_property(np, "max-speed", NULL);
if (!prop) {
/* handle interface property present in old trees */
- prop = get_property(phy, "interface", NULL);
+ prop = of_get_property(phy, "interface", NULL);
if (prop != NULL)
max_speed = enet_to_speed[*prop];
} else {
diff --git a/drivers/net/ucc_geth_mii.c b/drivers/net/ucc_geth_mii.c
index 73b5a53..27a1ef3 100644
--- a/drivers/net/ucc_geth_mii.c
+++ b/drivers/net/ucc_geth_mii.c
@@ -172,7 +172,7 @@
while ((child = of_get_next_child(np, child)) != NULL) {
int irq = irq_of_parse_and_map(child, 0);
if (irq != NO_IRQ) {
- const u32 *id = get_property(child, "reg", NULL);
+ const u32 *id = of_get_property(child, "reg", NULL);
new_bus->irq[*id] = irq;
}
}
@@ -203,7 +203,7 @@
if ((res.start >= tempres.start) &&
(res.end <= tempres.end)) {
/* set this UCC to be the MII master */
- const u32 *id = get_property(tempnp, "device-id", NULL);
+ const u32 *id = of_get_property(tempnp, "device-id", NULL);
if (id == NULL)
goto bus_register_fail;
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index 2346473..9ef49ce 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -90,7 +90,6 @@
#include <linux/ioport.h>
#include <linux/netdevice.h>
#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
#include <linux/device.h>
#undef COSA_SLOW_IO /* for testing purposes only */
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index f21bbaf..2d3a180 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -25,7 +25,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
-#include <linux/smp_lock.h>
#include <linux/sched.h>
#include <linux/ptrace.h>
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index cb08bc5..cdea7f7 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -1,7 +1,6 @@
/* ioctl() (mostly Linux Wireless Extensions) routines for Host AP driver */
#include <linux/types.h>
-#include <linux/smp_lock.h>
#include <linux/ethtool.h>
#include <net/ieee80211_crypt.h>
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
index 21c4c29..5b86ee5 100644
--- a/drivers/parisc/lba_pci.c
+++ b/drivers/parisc/lba_pci.c
@@ -38,7 +38,6 @@
#include <linux/pci.h>
#include <linux/ioport.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <asm/byteorder.h>
#include <asm/pdc.h>
diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c
index 316c06f..8b7d84e 100644
--- a/drivers/parport/parport_cs.c
+++ b/drivers/parport/parport_cs.c
@@ -201,7 +201,7 @@
p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2,
link->irq.AssignedIRQ, PARPORT_DMA_NONE,
- NULL);
+ &link->dev);
if (p == NULL) {
printk(KERN_NOTICE "parport_cs: parport_pc_probe_port() at "
"0x%3x, irq %u failed\n", link->io.BasePort1,
diff --git a/drivers/parport/parport_mfc3.c b/drivers/parport/parport_mfc3.c
index e5b0a54..77726fc 100644
--- a/drivers/parport/parport_mfc3.c
+++ b/drivers/parport/parport_mfc3.c
@@ -356,6 +356,7 @@
if (request_irq(IRQ_AMIGA_PORTS, mfc3_interrupt, IRQF_SHARED, p->name, &pp_mfc3_ops))
goto out_irq;
}
+ p->dev = &z->dev;
this_port[pias++] = p;
printk(KERN_INFO "%s: Multiface III port using irq\n", p->name);
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
index 3de2623..02c0d52 100644
--- a/drivers/parport/parport_pc.c
+++ b/drivers/parport/parport_pc.c
@@ -53,6 +53,7 @@
#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/pnp.h>
+#include <linux/platform_device.h>
#include <linux/sysctl.h>
#include <asm/io.h>
@@ -620,6 +621,7 @@
unsigned long dmaflag;
size_t left = length;
const struct parport_pc_private *priv = port->physport->private_data;
+ struct device *dev = port->physport->dev;
dma_addr_t dma_addr, dma_handle;
size_t maxlen = 0x10000; /* max 64k per DMA transfer */
unsigned long start = (unsigned long) buf;
@@ -631,8 +633,8 @@
if ((start ^ end) & ~0xffffUL)
maxlen = 0x10000 - (start & 0xffff);
- dma_addr = dma_handle = pci_map_single(priv->dev, (void *)buf, length,
- PCI_DMA_TODEVICE);
+ dma_addr = dma_handle = dma_map_single(dev, (void *)buf, length,
+ DMA_TO_DEVICE);
} else {
/* above 16 MB we use a bounce buffer as ISA-DMA is not possible */
maxlen = PAGE_SIZE; /* sizeof(priv->dma_buf) */
@@ -728,9 +730,9 @@
/* Turn off DMA mode */
frob_econtrol (port, 1<<3, 0);
-
+
if (dma_handle)
- pci_unmap_single(priv->dev, dma_handle, length, PCI_DMA_TODEVICE);
+ dma_unmap_single(dev, dma_handle, length, DMA_TO_DEVICE);
dump_parport_state ("leave fifo_write_block_dma", port);
return length - left;
@@ -2146,7 +2148,7 @@
struct parport *parport_pc_probe_port (unsigned long int base,
unsigned long int base_hi,
int irq, int dma,
- struct pci_dev *dev)
+ struct device *dev)
{
struct parport_pc_private *priv;
struct parport_operations *ops;
@@ -2155,6 +2157,17 @@
struct resource *base_res;
struct resource *ECR_res = NULL;
struct resource *EPP_res = NULL;
+ struct platform_device *pdev = NULL;
+
+ if (!dev) {
+ /* We need a physical device to attach to, but none was
+ * provided. Create our own. */
+ pdev = platform_device_register_simple("parport_pc",
+ base, NULL, 0);
+ if (IS_ERR(pdev))
+ return NULL;
+ dev = &pdev->dev;
+ }
ops = kmalloc(sizeof (struct parport_operations), GFP_KERNEL);
if (!ops)
@@ -2180,9 +2193,10 @@
priv->fifo_depth = 0;
priv->dma_buf = NULL;
priv->dma_handle = 0;
- priv->dev = dev;
INIT_LIST_HEAD(&priv->list);
priv->port = p;
+
+ p->dev = dev;
p->base_hi = base_hi;
p->modes = PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT;
p->private_data = priv;
@@ -2305,9 +2319,10 @@
p->dma = PARPORT_DMA_NONE;
} else {
priv->dma_buf =
- pci_alloc_consistent(priv->dev,
+ dma_alloc_coherent(dev,
PAGE_SIZE,
- &priv->dma_handle);
+ &priv->dma_handle,
+ GFP_KERNEL);
if (! priv->dma_buf) {
printk (KERN_WARNING "%s: "
"cannot get buffer for DMA, "
@@ -2356,6 +2371,8 @@
out2:
kfree (ops);
out1:
+ if (pdev)
+ platform_device_unregister(pdev);
return NULL;
}
@@ -2383,7 +2400,7 @@
release_region(p->base_hi, 3);
#if defined(CONFIG_PARPORT_PC_FIFO) && defined(HAS_DMA)
if (priv->dma_buf)
- pci_free_consistent(priv->dev, PAGE_SIZE,
+ dma_free_coherent(p->physport->dev, PAGE_SIZE,
priv->dma_buf,
priv->dma_handle);
#endif
@@ -2489,7 +2506,7 @@
*/
release_resource(base_res);
if (parport_pc_probe_port (ite8872_lpt, ite8872_lpthi,
- irq, PARPORT_DMA_NONE, NULL)) {
+ irq, PARPORT_DMA_NONE, &pdev->dev)) {
printk (KERN_INFO
"parport_pc: ITE 8872 parallel port: io=0x%X",
ite8872_lpt);
@@ -2672,7 +2689,7 @@
}
/* finally, do the probe with values obtained */
- if (parport_pc_probe_port (port1, port2, irq, dma, NULL)) {
+ if (parport_pc_probe_port (port1, port2, irq, dma, &pdev->dev)) {
printk (KERN_INFO
"parport_pc: VIA parallel port: io=0x%X", port1);
if (irq != PARPORT_IRQ_NONE)
@@ -2970,7 +2987,7 @@
parport_pc_pci_tbl[i + last_sio].device, io_lo, io_hi);
data->ports[count] =
parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE,
- PARPORT_DMA_NONE, dev);
+ PARPORT_DMA_NONE, &dev->dev);
if (data->ports[count])
count++;
}
@@ -3077,8 +3094,8 @@
} else
dma = PARPORT_DMA_NONE;
- printk(KERN_INFO "parport: PnPBIOS parport detected.\n");
- if (!(pdata = parport_pc_probe_port (io_lo, io_hi, irq, dma, NULL)))
+ dev_info(&dev->dev, "reported by %s\n", dev->protocol->name);
+ if (!(pdata = parport_pc_probe_port (io_lo, io_hi, irq, dma, &dev->dev)))
return -ENODEV;
pnp_set_drvdata(dev,pdata);
@@ -3103,6 +3120,21 @@
};
+static int __devinit parport_pc_platform_probe(struct platform_device *pdev)
+{
+ /* Always succeed, the actual probing is done in
+ * parport_pc_probe_port(). */
+ return 0;
+}
+
+static struct platform_driver parport_pc_platform_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "parport_pc",
+ },
+ .probe = parport_pc_platform_probe,
+};
+
/* This is called by parport_pc_find_nonpci_ports (in asm/parport.h) */
static int __devinit __attribute__((unused))
parport_pc_find_isa_ports (int autoirq, int autodma)
@@ -3378,9 +3410,15 @@
static int __init parport_pc_init(void)
{
+ int err;
+
if (parse_parport_params())
return -EINVAL;
+ err = platform_driver_register(&parport_pc_platform_driver);
+ if (err)
+ return err;
+
if (io[0]) {
int i;
/* Only probe the ports we were given. */
@@ -3405,6 +3443,7 @@
pci_unregister_driver (&parport_pc_pci_driver);
if (pnp_registered_parport)
pnp_unregister_driver (&parport_pc_pnp_driver);
+ platform_driver_unregister(&parport_pc_platform_driver);
spin_lock(&ports_lock);
while (!list_empty(&ports_list)) {
@@ -3413,6 +3452,9 @@
priv = list_entry(ports_list.next,
struct parport_pc_private, list);
port = priv->port;
+ if (port->dev && port->dev->bus == &platform_bus_type)
+ platform_device_unregister(
+ to_platform_device(port->dev));
spin_unlock(&ports_lock);
parport_pc_unregister_port(port);
spin_lock(&ports_lock);
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c
index 78c0a26..90ea3b8 100644
--- a/drivers/parport/parport_serial.c
+++ b/drivers/parport/parport_serial.c
@@ -305,7 +305,7 @@
dev_dbg(&dev->dev, "PCI parallel port detected: I/O at "
"%#lx(%#lx)\n", io_lo, io_hi);
port = parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE,
- PARPORT_DMA_NONE, dev);
+ PARPORT_DMA_NONE, &dev->dev);
if (port) {
priv->port[priv->num_par++] = port;
success = 1;
@@ -392,6 +392,7 @@
static int parport_serial_pci_resume(struct pci_dev *dev)
{
struct parport_serial_private *priv = pci_get_drvdata(dev);
+ int err;
pci_set_power_state(dev, PCI_D0);
pci_restore_state(dev);
@@ -399,7 +400,12 @@
/*
* The device may have been disabled. Re-enable it.
*/
- pci_enable_device(dev);
+ err = pci_enable_device(dev);
+ if (err) {
+ printk(KERN_ERR "parport_serial: %s: error enabling "
+ "device for resume (%d)\n", pci_name(dev), err);
+ return err;
+ }
if (priv->serial)
pciserial_resume_ports(priv->serial);
diff --git a/drivers/parport/parport_sunbpp.c b/drivers/parport/parport_sunbpp.c
index 400bb90..d27019c 100644
--- a/drivers/parport/parport_sunbpp.c
+++ b/drivers/parport/parport_sunbpp.c
@@ -322,6 +322,7 @@
goto out_free_ops;
p->size = size;
+ p->dev = &sdev->ofdev.dev;
if ((err = request_irq(p->irq, parport_sunbpp_interrupt,
IRQF_SHARED, p->name, p)) != 0) {
diff --git a/drivers/parport/share.c b/drivers/parport/share.c
index fd9129e..cd66442 100644
--- a/drivers/parport/share.c
+++ b/drivers/parport/share.c
@@ -365,6 +365,11 @@
parport_daisy_init(port);
#endif
+ if (!port->dev)
+ printk(KERN_WARNING "%s: fix this legacy "
+ "no-device port driver!\n",
+ port->name);
+
parport_proc_register(port);
mutex_lock(®istration_lock);
spin_lock_irq(&parportlist_lock);
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c
index 40c79b0..fa5c019 100644
--- a/drivers/pci/hotplug/acpiphp_core.c
+++ b/drivers/pci/hotplug/acpiphp_core.c
@@ -40,7 +40,6 @@
#include <linux/pci_hotplug.h>
#include <linux/slab.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include "acpiphp.h"
#define MY_NAME "acpiphp"
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index fca978f..9ef4e98 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -46,7 +46,6 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/pci_hotplug.h>
-#include <linux/smp_lock.h>
#include <linux/mutex.h>
#include "../pci.h"
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c
index 5939294..0316eea 100644
--- a/drivers/pci/hotplug/ibmphp_core.c
+++ b/drivers/pci/hotplug/ibmphp_core.c
@@ -34,7 +34,6 @@
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/wait.h>
-#include <linux/smp_lock.h>
#include "../pci.h"
#include "../../../arch/i386/pci/pci.h" /* for struct irq_routing_table */
#include "ibmphp.h"
diff --git a/drivers/pci/hotplug/ibmphp_hpc.c b/drivers/pci/hotplug/ibmphp_hpc.c
index f55ac38..46abaa8 100644
--- a/drivers/pci/hotplug/ibmphp_hpc.c
+++ b/drivers/pci/hotplug/ibmphp_hpc.c
@@ -32,7 +32,6 @@
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/pci.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/mutex.h>
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c
index 63f3bd1..bd433ef 100644
--- a/drivers/pci/hotplug/pci_hotplug_core.c
+++ b/drivers/pci/hotplug/pci_hotplug_core.c
@@ -34,7 +34,6 @@
#include <linux/sysfs.h>
#include <linux/pagemap.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/mount.h>
#include <linux/namei.h>
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c
index 847936f..458c08e 100644
--- a/drivers/pci/hotplug/rpaphp_core.c
+++ b/drivers/pci/hotplug/rpaphp_core.c
@@ -29,7 +29,6 @@
#include <linux/pci_hotplug.h>
#include <linux/slab.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <asm/eeh.h> /* for eeh_add_device() */
#include <asm/rtas.h> /* rtas_call */
@@ -170,10 +169,10 @@
{
const int *indexes, *names, *types, *domains;
- indexes = get_property(dn, "ibm,drc-indexes", NULL);
- names = get_property(dn, "ibm,drc-names", NULL);
- types = get_property(dn, "ibm,drc-types", NULL);
- domains = get_property(dn, "ibm,drc-power-domains", NULL);
+ indexes = of_get_property(dn, "ibm,drc-indexes", NULL);
+ names = of_get_property(dn, "ibm,drc-names", NULL);
+ types = of_get_property(dn, "ibm,drc-types", NULL);
+ domains = of_get_property(dn, "ibm,drc-power-domains", NULL);
if (!indexes || !names || !types || !domains) {
/* Slot does not have dynamically-removable children */
@@ -206,7 +205,7 @@
char *name_tmp, *type_tmp;
int i, rc;
- my_index = get_property(dn, "ibm,my-drc-index", NULL);
+ my_index = of_get_property(dn, "ibm,my-drc-index", NULL);
if (!my_index) {
/* Node isn't DLPAR/hotplug capable */
return -EINVAL;
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c
index 2c94d44..d2fc355 100644
--- a/drivers/pci/hotplug/shpchp_ctrl.c
+++ b/drivers/pci/hotplug/shpchp_ctrl.c
@@ -30,7 +30,6 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
-#include <linux/smp_lock.h>
#include <linux/pci.h>
#include <linux/workqueue.h>
#include "../pci.h"
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 9e1321d..e6740d1 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -12,7 +12,6 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/ioport.h>
-#include <linux/smp_lock.h>
#include <linux/pci.h>
#include <linux/proc_fs.h>
#include <linux/msi.h>
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index ed87aa5..0425a7b 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -11,7 +11,6 @@
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
-#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/byteorder.h>
diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c
index fda0694..383107b 100644
--- a/drivers/pcmcia/pxa2xx_mainstone.c
+++ b/drivers/pcmcia/pxa2xx_mainstone.c
@@ -175,6 +175,7 @@
if (!mst_pcmcia_device)
return -ENOMEM;
+ mst_pcmcia_device->dev.uevent_suppress = 0;
mst_pcmcia_device->dev.platform_data = &mst_pcmcia_ops;
ret = platform_device_add(mst_pcmcia_device);
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c
index b7b9e14..a2daa3f 100644
--- a/drivers/pcmcia/pxa2xx_sharpsl.c
+++ b/drivers/pcmcia/pxa2xx_sharpsl.c
@@ -261,6 +261,7 @@
if (!sharpsl_pcmcia_device)
return -ENOMEM;
+ sharpsl_pcmcia_device->dev.uevent_suppress = 0;
sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops;
sharpsl_pcmcia_device->dev.parent = platform_scoop_config->devs[0].dev;
diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c
index aec83ec..3e20b1c 100644
--- a/drivers/pnp/core.c
+++ b/drivers/pnp/core.c
@@ -14,6 +14,7 @@
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/errno.h>
+#include <linux/dma-mapping.h>
#include "base.h"
@@ -22,6 +23,14 @@
LIST_HEAD(pnp_global);
DEFINE_SPINLOCK(pnp_lock);
+/*
+ * ACPI or PNPBIOS should tell us about all platform devices, so we can
+ * skip some blind probes. ISAPNP typically enumerates only plug-in ISA
+ * devices, not built-in things like COM ports.
+ */
+int pnp_platform_devices;
+EXPORT_SYMBOL(pnp_platform_devices);
+
void *pnp_alloc(long size)
{
void *result;
@@ -114,6 +123,8 @@
int ret;
pnp_fixup_device(dev);
dev->dev.bus = &pnp_bus_type;
+ dev->dev.dma_mask = &dev->dma_mask;
+ dev->dma_mask = dev->dev.coherent_dma_mask = DMA_24BIT_MASK;
dev->dev.release = &pnp_release_device;
dev->status = PNP_READY;
spin_lock(&pnp_lock);
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index 62eda5d..a005487 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2004 Matthieu Castet <castet.matthieu@free.fr>
* Copyright (c) 2004 Li Shaohua <shaohua.li@intel.com>
- *
+ *
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
@@ -18,7 +18,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-
+
#include <linux/acpi.h>
#include <linux/pnp.h>
#include <acpi/acpi_bus.h>
@@ -82,7 +82,7 @@
static int pnpacpi_get_resources(struct pnp_dev * dev, struct pnp_resource_table * res)
{
acpi_status status;
- status = pnpacpi_parse_allocated_resource((acpi_handle)dev->data,
+ status = pnpacpi_parse_allocated_resource((acpi_handle)dev->data,
&dev->res);
return ACPI_FAILURE(status) ? -ENODEV : 0;
}
@@ -112,9 +112,9 @@
static int pnpacpi_disable_resources(struct pnp_dev *dev)
{
acpi_status status;
-
+
/* acpi_unregister_gsi(pnp_irq(dev, 0)); */
- status = acpi_evaluate_object((acpi_handle)dev->data,
+ status = acpi_evaluate_object((acpi_handle)dev->data,
"_DIS", NULL, NULL);
return ACPI_FAILURE(status) ? -ENODEV : 0;
}
@@ -167,7 +167,7 @@
strncpy(dev->name, acpi_device_bid(device), sizeof(dev->name));
dev->number = num;
-
+
/* set the initial values for the PnP device */
dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
if (!dev_id)
@@ -185,14 +185,14 @@
}
if(dev->capabilities & PNP_CONFIGURABLE) {
- status = pnpacpi_parse_resource_option_data(device->handle,
+ status = pnpacpi_parse_resource_option_data(device->handle,
dev);
if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
pnp_err("PnPACPI: METHOD_NAME__PRS failure for %s", dev_id->id);
goto err1;
}
}
-
+
/* parse compatible ids */
if (device->flags.compatible_ids) {
struct acpi_compatible_id_list *cid_list = device->pnp.cid_list;
@@ -236,6 +236,42 @@
return AE_OK;
}
+static int __init acpi_pnp_match(struct device *dev, void *_pnp)
+{
+ struct acpi_device *acpi = to_acpi_device(dev);
+ struct pnp_dev *pnp = _pnp;
+
+ /* true means it matched */
+ return acpi->flags.hardware_id
+ && !acpi_get_physical_device(acpi->handle)
+ && compare_pnp_id(pnp->id, acpi->pnp.hardware_id);
+}
+
+static int __init acpi_pnp_find_device(struct device *dev, acpi_handle *handle)
+{
+ struct device *adev;
+ struct acpi_device *acpi;
+
+ adev = bus_find_device(&acpi_bus_type, NULL,
+ to_pnp_dev(dev),
+ acpi_pnp_match);
+ if (!adev)
+ return -ENODEV;
+
+ acpi = to_acpi_device(adev);
+ *handle = acpi->handle;
+ put_device(adev);
+ return 0;
+}
+
+/* complete initialization of a PNPACPI device includes having
+ * pnpdev->dev.archdata.acpi_handle point to its ACPI sibling.
+ */
+static struct acpi_bus_type __initdata acpi_pnp_bus = {
+ .bus = &pnp_bus_type,
+ .find_device = acpi_pnp_find_device,
+};
+
int pnpacpi_disabled __initdata;
static int __init pnpacpi_init(void)
{
@@ -245,8 +281,11 @@
}
pnp_info("PnP ACPI init");
pnp_register_protocol(&pnpacpi_protocol);
+ register_acpi_bus_type(&acpi_pnp_bus);
acpi_get_devices(NULL, pnpacpi_add_device_handler, NULL, NULL);
pnp_info("PnP ACPI: found %d devices", num);
+ unregister_acpi_bus_type(&acpi_pnp_bus);
+ pnp_platform_devices = 1;
return 0;
}
subsys_initcall(pnpacpi_init);
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c
index 95738db..3a201b7 100644
--- a/drivers/pnp/pnpbios/core.c
+++ b/drivers/pnp/pnpbios/core.c
@@ -62,6 +62,7 @@
#include <linux/delay.h>
#include <linux/acpi.h>
#include <linux/freezer.h>
+#include <linux/kthread.h>
#include <asm/page.h>
#include <asm/desc.h>
@@ -159,9 +160,7 @@
{
static struct pnp_docking_station_info now;
int docked = -1, d = 0;
- daemonize("kpnpbiosd");
- allow_signal(SIGKILL);
- while(!unloading && !signal_pending(current))
+ while (!unloading)
{
int status;
@@ -170,11 +169,8 @@
*/
msleep_interruptible(2000);
- if(signal_pending(current)) {
- if (try_to_freeze())
- continue;
- break;
- }
+ if (try_to_freeze())
+ continue;
status = pnp_bios_dock_station_info(&now);
@@ -574,6 +570,7 @@
/* scan for pnpbios devices */
build_devlist();
+ pnp_platform_devices = 1;
return 0;
}
@@ -581,6 +578,7 @@
static int __init pnpbios_thread_init(void)
{
+ struct task_struct *task;
#if defined(CONFIG_PPC_MERGE)
if (check_legacy_ioport(PNPBIOS_BASE))
return 0;
@@ -589,7 +587,8 @@
return 0;
#ifdef CONFIG_HOTPLUG
init_completion(&unload_sem);
- if (kernel_thread(pnp_dock_thread, NULL, CLONE_KERNEL) > 0)
+ task = kthread_run(pnp_dock_thread, NULL, "kpnpbiosd");
+ if (!IS_ERR(task))
unloading = 0;
#endif
return 0;
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
index e97ecef..277df50 100644
--- a/drivers/pnp/quirks.c
+++ b/drivers/pnp/quirks.c
@@ -16,6 +16,7 @@
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/pnp.h>
+#include <linux/io.h>
#include "base.h"
@@ -106,6 +107,34 @@
return;
}
+static void quirk_smc_enable(struct pnp_dev *dev)
+{
+ unsigned int firbase;
+
+ if (!dev->active || !pnp_port_valid(dev, 1))
+ return;
+
+ /*
+ * On the HP/Compaq nw8240 (and probably other similar machines),
+ * there is an SMCF010 device with two I/O port regions:
+ *
+ * 0x3e8-0x3ef SIR
+ * 0x100-0x10f FIR
+ *
+ * _STA reports the device is enabled, but in fact, the BIOS
+ * neglects to enable the FIR range. Fortunately, it does fully
+ * enable the device if we call _SRS.
+ */
+ firbase = pnp_port_start(dev, 1);
+ if (inb(firbase + 0x7 /* IRCC_MASTER */) == 0xff) {
+ pnp_err("%s (%s) enabled but not responding, disabling and "
+ "re-enabling", dev->dev.bus_id, pnp_dev_name(dev));
+ pnp_disable_dev(dev);
+ pnp_activate_dev(dev);
+ }
+}
+
+
/*
* PnP Quirks
* Cards or devices that need some tweaking due to incomplete resource info
@@ -126,6 +155,7 @@
{ "CTL0043", quirk_sb16audio_resources },
{ "CTL0044", quirk_sb16audio_resources },
{ "CTL0045", quirk_sb16audio_resources },
+ { "SMCf010", quirk_smc_enable },
{ "" }
};
diff --git a/drivers/ps3/vuart.c b/drivers/ps3/vuart.c
index 7d7cab1..ec2d36a 100644
--- a/drivers/ps3/vuart.c
+++ b/drivers/ps3/vuart.c
@@ -886,12 +886,12 @@
if (++vuart_bus_priv.use_count == 1) {
- result = ps3_alloc_vuart_irq(PS3_BINDING_CPU_ANY,
+ result = ps3_vuart_irq_setup(PS3_BINDING_CPU_ANY,
(void*)&vuart_bus_priv.bmp.status, &vuart_bus_priv.virq);
if (result) {
dev_dbg(&dev->core,
- "%s:%d: ps3_alloc_vuart_irq failed (%d)\n",
+ "%s:%d: ps3_vuart_irq_setup failed (%d)\n",
__func__, __LINE__, result);
result = -EPERM;
goto fail_alloc_irq;
@@ -937,7 +937,7 @@
fail_probe:
ps3_vuart_set_interrupt_mask(dev, 0);
fail_request_irq:
- ps3_free_vuart_irq(vuart_bus_priv.virq);
+ ps3_vuart_irq_destroy(vuart_bus_priv.virq);
vuart_bus_priv.virq = NO_IRQ;
fail_alloc_irq:
--vuart_bus_priv.use_count;
@@ -975,7 +975,7 @@
if (--vuart_bus_priv.use_count == 0) {
BUG();
free_irq(vuart_bus_priv.virq, &vuart_bus_priv);
- ps3_free_vuart_irq(vuart_bus_priv.virq);
+ ps3_vuart_irq_destroy(vuart_bus_priv.virq);
vuart_bus_priv.virq = NO_IRQ;
}
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index ef1eae9..5e43983 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -21,21 +21,31 @@
will be called rtc-class.
config RTC_HCTOSYS
- bool "Set system time from RTC on startup"
+ bool "Set system time from RTC on startup and resume"
depends on RTC_CLASS = y
default y
help
- If you say yes here, the system time will be set using
- the value read from the specified RTC device. This is useful
- in order to avoid unnecessary fsck runs.
+ If you say yes here, the system time (wall clock) will be set using
+ the value read from a specified RTC device. This is useful to avoid
+ unnecessary fsck runs at boot time, and to network better.
config RTC_HCTOSYS_DEVICE
- string "The RTC to read the time from"
+ string "RTC used to set the system time"
depends on RTC_HCTOSYS = y
default "rtc0"
help
- The RTC device that will be used as the source for
- the system time, usually rtc0.
+ The RTC device that will be used to (re)initialize the system
+ clock, usually rtc0. Initialization is done when the system
+ starts up, and when it resumes from a low power state.
+
+ This clock should be battery-backed, so that it reads the correct
+ time when the system boots from a power-off state. Otherwise, your
+ system will need an external clock source (like an NTP server).
+
+ If the clock you specify here is not battery backed, it may still
+ be useful to reinitialize system time when resuming from system
+ sleep states. Do not specify an RTC here unless it stays powered
+ during all this system's supported sleep states.
config RTC_DEBUG
bool "RTC debug support"
@@ -48,7 +58,7 @@
depends on RTC_CLASS
config RTC_INTF_SYSFS
- tristate "sysfs"
+ boolean "sysfs"
depends on RTC_CLASS && SYSFS
default RTC_CLASS
help
@@ -59,7 +69,7 @@
will be called rtc-sysfs.
config RTC_INTF_PROC
- tristate "proc"
+ boolean "proc"
depends on RTC_CLASS && PROC_FS
default RTC_CLASS
help
@@ -71,7 +81,7 @@
will be called rtc-proc.
config RTC_INTF_DEV
- tristate "dev"
+ boolean "dev"
depends on RTC_CLASS
default RTC_CLASS
help
@@ -92,7 +102,140 @@
driver does not expose RTC_UIE ioctls. Those requests generate
once-per-second update interrupts, used for synchronization.
-comment "RTC drivers"
+config RTC_DRV_TEST
+ tristate "Test driver/device"
+ depends on RTC_CLASS
+ help
+ If you say yes here you get support for the
+ RTC test driver. It's a software RTC which can be
+ used to test the RTC subsystem APIs. It gets
+ the time from the system clock.
+ You want this driver only if you are doing development
+ on the RTC subsystem. Please read the source code
+ for further details.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-test.
+
+comment "I2C RTC drivers"
+ depends on RTC_CLASS
+
+config RTC_DRV_DS1307
+ tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00"
+ depends on RTC_CLASS && I2C
+ help
+ If you say yes here you get support for various compatible RTC
+ chips (often with battery backup) connected with I2C. This driver
+ should handle DS1307, DS1337, DS1338, DS1339, DS1340, ST M41T00,
+ and probably other chips. In some cases the RTC must already
+ have been initialized (by manufacturing or a bootloader).
+
+ The first seven registers on these chips hold an RTC, and other
+ registers may add features such as NVRAM, a trickle charger for
+ the RTC/NVRAM backup power, and alarms. This driver may not
+ expose all those available chip features.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-ds1307.
+
+config RTC_DRV_DS1672
+ tristate "Dallas/Maxim DS1672"
+ depends on RTC_CLASS && I2C
+ help
+ If you say yes here you get support for the
+ Dallas/Maxim DS1672 timekeeping chip.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-ds1672.
+
+config RTC_DRV_MAX6900
+ tristate "Maxim 6900"
+ depends on RTC_CLASS && I2C
+ help
+ If you say yes here you will get support for the
+ Maxim MAX6900 I2C RTC chip.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-max6900.
+
+config RTC_DRV_RS5C372
+ tristate "Ricoh RS5C372A/B"
+ depends on RTC_CLASS && I2C
+ help
+ If you say yes here you get support for the
+ Ricoh RS5C372A and RS5C372B RTC chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-rs5c372.
+
+config RTC_DRV_ISL1208
+ tristate "Intersil 1208"
+ depends on RTC_CLASS && I2C
+ help
+ If you say yes here you get support for the
+ Intersil 1208 RTC chip.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-isl1208.
+
+config RTC_DRV_X1205
+ tristate "Xicor/Intersil X1205"
+ depends on RTC_CLASS && I2C
+ help
+ If you say yes here you get support for the
+ Xicor/Intersil X1205 RTC chip.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-x1205.
+
+config RTC_DRV_PCF8563
+ tristate "Philips PCF8563/Epson RTC8564"
+ depends on RTC_CLASS && I2C
+ help
+ If you say yes here you get support for the
+ Philips PCF8563 RTC chip. The Epson RTC8564
+ should work as well.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-pcf8563.
+
+config RTC_DRV_PCF8583
+ tristate "Philips PCF8583"
+ depends on RTC_CLASS && I2C
+ help
+ If you say yes here you get support for the Philips PCF8583
+ RTC chip found on Acorn RiscPCs. This driver supports the
+ platform specific method of retrieving the current year from
+ the RTC's SRAM. It will work on other platforms with the same
+ chip, but the year will probably have to be tweaked.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-pcf8583.
+
+comment "SPI RTC drivers"
+ depends on RTC_CLASS
+
+config RTC_DRV_RS5C348
+ tristate "Ricoh RS5C348A/B"
+ depends on RTC_CLASS && SPI
+ help
+ If you say yes here you get support for the
+ Ricoh RS5C348A and RS5C348B RTC chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-rs5c348.
+
+config RTC_DRV_MAX6902
+ tristate "Maxim 6902"
+ depends on RTC_CLASS && SPI
+ help
+ If you say yes here you will get support for the
+ Maxim MAX6902 SPI RTC chip.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-max6902.
+
+comment "Platform RTC drivers"
depends on RTC_CLASS
# this 'CMOS' RTC driver is arch dependent because <asm-generic/rtc.h>
@@ -100,7 +243,7 @@
# global rtc_lock ... it's not yet just another platform_device.
config RTC_DRV_CMOS
- tristate "PC-style 'CMOS' real time clock"
+ tristate "PC-style 'CMOS'"
depends on RTC_CLASS && (X86 || ALPHA || ARM26 || ARM \
|| M32R || ATARI || POWERPC)
help
@@ -118,34 +261,6 @@
This driver can also be built as a module. If so, the module
will be called rtc-cmos.
-config RTC_DRV_X1205
- tristate "Xicor/Intersil X1205"
- depends on RTC_CLASS && I2C
- help
- If you say yes here you get support for the
- Xicor/Intersil X1205 RTC chip.
-
- This driver can also be built as a module. If so, the module
- will be called rtc-x1205.
-
-config RTC_DRV_DS1307
- tristate "Dallas/Maxim DS1307 and similar I2C RTC chips"
- depends on RTC_CLASS && I2C
- help
- If you say yes here you get support for various compatible RTC
- chips (often with battery backup) connected with I2C. This driver
- should handle DS1307, DS1337, DS1338, DS1339, DS1340, ST M41T00,
- and probably other chips. In some cases the RTC must already
- have been initialized (by manufacturing or a bootloader).
-
- The first seven registers on these chips hold an RTC, and other
- registers may add features such as NVRAM, a trickle charger for
- the RTC/NVRAM backup power, and alarms. This driver may not
- expose all those available chip features.
-
- This driver can also be built as a module. If so, the module
- will be called rtc-ds1307.
-
config RTC_DRV_DS1553
tristate "Dallas DS1553"
depends on RTC_CLASS
@@ -156,26 +271,6 @@
This driver can also be built as a module. If so, the module
will be called rtc-ds1553.
-config RTC_DRV_ISL1208
- tristate "Intersil 1208"
- depends on RTC_CLASS && I2C
- help
- If you say yes here you get support for the
- Intersil 1208 RTC chip.
-
- This driver can also be built as a module. If so, the module
- will be called rtc-isl1208.
-
-config RTC_DRV_DS1672
- tristate "Dallas/Maxim DS1672"
- depends on RTC_CLASS && I2C
- help
- If you say yes here you get support for the
- Dallas/Maxim DS1672 timekeeping chip.
-
- This driver can also be built as a module. If so, the module
- will be called rtc-ds1672.
-
config RTC_DRV_DS1742
tristate "Dallas DS1742/1743"
depends on RTC_CLASS
@@ -186,6 +281,29 @@
This driver can also be built as a module. If so, the module
will be called rtc-ds1742.
+config RTC_DRV_M48T86
+ tristate "ST M48T86/Dallas DS12887"
+ depends on RTC_CLASS
+ help
+ If you say Y here you will get support for the
+ ST M48T86 and Dallas DS12887 RTC chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-m48t86.
+
+config RTC_DRV_V3020
+ tristate "EM Microelectronic V3020"
+ depends on RTC_CLASS
+ help
+ If you say yes here you will get support for the
+ EM Microelectronic v3020 RTC chip.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-v3020.
+
+comment "on-CPU RTC drivers"
+ depends on RTC_CLASS
+
config RTC_DRV_OMAP
tristate "TI OMAP1"
depends on RTC_CLASS && ( \
@@ -194,49 +312,6 @@
Say "yes" here to support the real time clock on TI OMAP1 chips.
This driver can also be built as a module called rtc-omap.
-config RTC_DRV_PCF8563
- tristate "Philips PCF8563/Epson RTC8564"
- depends on RTC_CLASS && I2C
- help
- If you say yes here you get support for the
- Philips PCF8563 RTC chip. The Epson RTC8564
- should work as well.
-
- This driver can also be built as a module. If so, the module
- will be called rtc-pcf8563.
-
-config RTC_DRV_PCF8583
- tristate "Philips PCF8583"
- depends on RTC_CLASS && I2C && ARCH_RPC
- help
- If you say yes here you get support for the Philips PCF8583
- RTC chip found on Acorn RiscPCs. This driver supports the
- platform specific method of retrieving the current year from
- the RTC's SRAM.
-
- This driver can also be built as a module. If so, the module
- will be called rtc-pcf8583.
-
-config RTC_DRV_RS5C348
- tristate "Ricoh RS5C348A/B"
- depends on RTC_CLASS && SPI
- help
- If you say yes here you get support for the
- Ricoh RS5C348A and RS5C348B RTC chips.
-
- This driver can also be built as a module. If so, the module
- will be called rtc-rs5c348.
-
-config RTC_DRV_RS5C372
- tristate "Ricoh RS5C372A/B"
- depends on RTC_CLASS && I2C
- help
- If you say yes here you get support for the
- Ricoh RS5C372A and RS5C372B RTC chips.
-
- This driver can also be built as a module. If so, the module
- will be called rtc-rs5c372.
-
config RTC_DRV_S3C
tristate "Samsung S3C series SoC RTC"
depends on RTC_CLASS && ARCH_S3C2410
@@ -253,16 +328,6 @@
This driver can also be build as a module. If so, the module
will be called rtc-s3c.
-config RTC_DRV_M48T86
- tristate "ST M48T86/Dallas DS12887"
- depends on RTC_CLASS
- help
- If you say Y here you will get support for the
- ST M48T86 and Dallas DS12887 RTC chips.
-
- This driver can also be built as a module. If so, the module
- will be called rtc-m48t86.
-
config RTC_DRV_EP93XX
tristate "Cirrus Logic EP93XX"
depends on RTC_CLASS && ARCH_EP93XX
@@ -308,7 +373,7 @@
depends on RTC_CLASS && ARM_AMBA
help
If you say Y here you will get access to ARM AMBA
- PrimeCell PL031 UART found on certain ARM SOCs.
+ PrimeCell PL031 RTC found on certain ARM SOCs.
To compile this driver as a module, choose M here: the
module will be called rtc-pl031.
@@ -319,41 +384,6 @@
help
Driver for the Atmel AT91RM9200's internal RTC (Realtime Clock).
-config RTC_DRV_TEST
- tristate "Test driver/device"
- depends on RTC_CLASS
- help
- If you say yes here you get support for the
- RTC test driver. It's a software RTC which can be
- used to test the RTC subsystem APIs. It gets
- the time from the system clock.
- You want this driver only if you are doing development
- on the RTC subsystem. Please read the source code
- for further details.
-
- This driver can also be built as a module. If so, the module
- will be called rtc-test.
-
-config RTC_DRV_MAX6902
- tristate "Maxim 6902"
- depends on RTC_CLASS && SPI
- help
- If you say yes here you will get support for the
- Maxim MAX6902 spi RTC chip.
-
- This driver can also be built as a module. If so, the module
- will be called rtc-max6902.
-
-config RTC_DRV_V3020
- tristate "EM Microelectronic V3020"
- depends on RTC_CLASS
- help
- If you say yes here you will get support for the
- EM Microelectronic v3020 RTC chip.
-
- This driver can also be built as a module. If so, the module
- will be called rtc-v3020.
-
config RTC_DRV_BFIN
tristate "Blackfin On-Chip RTC"
depends on RTC_CLASS && BFIN
@@ -364,4 +394,10 @@
This driver can also be built as a module. If so, the module
will be called rtc-bfin.
+config RTC_DRV_RS5C313
+ tristate "Ricoh RS5C313"
+ depends on RTC_CLASS && BROKEN
+ help
+ If you say yes here you get support for the Ricoh RS5C313 RTC chips.
+
endmenu
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 9218cf2..a1afbc2 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -11,9 +11,9 @@
obj-$(CONFIG_RTC_CLASS) += rtc-core.o
rtc-core-y := class.o interface.o
-obj-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o
-obj-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o
-obj-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o
+rtc-core-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o
+rtc-core-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o
+rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o
obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o
obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o
@@ -30,10 +30,12 @@
obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o
obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o
obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o
+obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o
obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o
obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o
obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o
obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o
+obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o
obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o
obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o
obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index 04aaa63..8b3cd31 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -16,19 +16,94 @@
#include <linux/kdev_t.h>
#include <linux/idr.h>
+#include "rtc-core.h"
+
+
static DEFINE_IDR(rtc_idr);
static DEFINE_MUTEX(idr_lock);
struct class *rtc_class;
-static void rtc_device_release(struct class_device *class_dev)
+static void rtc_device_release(struct device *dev)
{
- struct rtc_device *rtc = to_rtc_device(class_dev);
+ struct rtc_device *rtc = to_rtc_device(dev);
mutex_lock(&idr_lock);
idr_remove(&rtc_idr, rtc->id);
mutex_unlock(&idr_lock);
kfree(rtc);
}
+#if defined(CONFIG_PM) && defined(CONFIG_RTC_HCTOSYS_DEVICE)
+
+/*
+ * On suspend(), measure the delta between one RTC and the
+ * system's wall clock; restore it on resume().
+ */
+
+static struct timespec delta;
+static time_t oldtime;
+
+static int rtc_suspend(struct device *dev, pm_message_t mesg)
+{
+ struct rtc_device *rtc = to_rtc_device(dev);
+ struct rtc_time tm;
+
+ if (strncmp(rtc->dev.bus_id,
+ CONFIG_RTC_HCTOSYS_DEVICE,
+ BUS_ID_SIZE) != 0)
+ return 0;
+
+ rtc_read_time(rtc, &tm);
+ rtc_tm_to_time(&tm, &oldtime);
+
+ /* RTC precision is 1 second; adjust delta for avg 1/2 sec err */
+ set_normalized_timespec(&delta,
+ xtime.tv_sec - oldtime,
+ xtime.tv_nsec - (NSEC_PER_SEC >> 1));
+
+ return 0;
+}
+
+static int rtc_resume(struct device *dev)
+{
+ struct rtc_device *rtc = to_rtc_device(dev);
+ struct rtc_time tm;
+ time_t newtime;
+ struct timespec time;
+
+ if (strncmp(rtc->dev.bus_id,
+ CONFIG_RTC_HCTOSYS_DEVICE,
+ BUS_ID_SIZE) != 0)
+ return 0;
+
+ rtc_read_time(rtc, &tm);
+ if (rtc_valid_tm(&tm) != 0) {
+ pr_debug("%s: bogus resume time\n", rtc->dev.bus_id);
+ return 0;
+ }
+ rtc_tm_to_time(&tm, &newtime);
+ if (newtime <= oldtime) {
+ if (newtime < oldtime)
+ pr_debug("%s: time travel!\n", rtc->dev.bus_id);
+ return 0;
+ }
+
+ /* restore wall clock using delta against this RTC;
+ * adjust again for avg 1/2 second RTC sampling error
+ */
+ set_normalized_timespec(&time,
+ newtime + delta.tv_sec,
+ (NSEC_PER_SEC >> 1) + delta.tv_nsec);
+ do_settimeofday(&time);
+
+ return 0;
+}
+
+#else
+#define rtc_suspend NULL
+#define rtc_resume NULL
+#endif
+
+
/**
* rtc_device_register - register w/ RTC class
* @dev: the device to register
@@ -70,23 +145,29 @@
rtc->ops = ops;
rtc->owner = owner;
rtc->max_user_freq = 64;
- rtc->class_dev.dev = dev;
- rtc->class_dev.class = rtc_class;
- rtc->class_dev.release = rtc_device_release;
+ rtc->dev.parent = dev;
+ rtc->dev.class = rtc_class;
+ rtc->dev.release = rtc_device_release;
mutex_init(&rtc->ops_lock);
spin_lock_init(&rtc->irq_lock);
spin_lock_init(&rtc->irq_task_lock);
strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE);
- snprintf(rtc->class_dev.class_id, BUS_ID_SIZE, "rtc%d", id);
+ snprintf(rtc->dev.bus_id, BUS_ID_SIZE, "rtc%d", id);
- err = class_device_register(&rtc->class_dev);
+ rtc_dev_prepare(rtc);
+
+ err = device_register(&rtc->dev);
if (err)
goto exit_kfree;
+ rtc_dev_add_device(rtc);
+ rtc_sysfs_add_device(rtc);
+ rtc_proc_add_device(rtc);
+
dev_info(dev, "rtc core: registered %s as %s\n",
- rtc->name, rtc->class_dev.class_id);
+ rtc->name, rtc->dev.bus_id);
return rtc;
@@ -113,26 +194,22 @@
*/
void rtc_device_unregister(struct rtc_device *rtc)
{
- if (class_device_get(&rtc->class_dev) != NULL) {
+ if (get_device(&rtc->dev) != NULL) {
mutex_lock(&rtc->ops_lock);
/* remove innards of this RTC, then disable it, before
* letting any rtc_class_open() users access it again
*/
- class_device_unregister(&rtc->class_dev);
+ rtc_sysfs_del_device(rtc);
+ rtc_dev_del_device(rtc);
+ rtc_proc_del_device(rtc);
+ device_unregister(&rtc->dev);
rtc->ops = NULL;
mutex_unlock(&rtc->ops_lock);
- class_device_put(&rtc->class_dev);
+ put_device(&rtc->dev);
}
}
EXPORT_SYMBOL_GPL(rtc_device_unregister);
-int rtc_interface_register(struct class_interface *intf)
-{
- intf->class = rtc_class;
- return class_interface_register(intf);
-}
-EXPORT_SYMBOL_GPL(rtc_interface_register);
-
static int __init rtc_init(void)
{
rtc_class = class_create(THIS_MODULE, "rtc");
@@ -140,11 +217,16 @@
printk(KERN_ERR "%s: couldn't create class\n", __FILE__);
return PTR_ERR(rtc_class);
}
+ rtc_class->suspend = rtc_suspend;
+ rtc_class->resume = rtc_resume;
+ rtc_dev_init();
+ rtc_sysfs_init(rtc_class);
return 0;
}
static void __exit rtc_exit(void)
{
+ rtc_dev_exit();
class_destroy(rtc_class);
}
diff --git a/drivers/rtc/hctosys.c b/drivers/rtc/hctosys.c
index d02fe9a..1785272 100644
--- a/drivers/rtc/hctosys.c
+++ b/drivers/rtc/hctosys.c
@@ -26,15 +26,15 @@
{
int err;
struct rtc_time tm;
- struct class_device *class_dev = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
+ struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
- if (class_dev == NULL) {
+ if (rtc == NULL) {
printk("%s: unable to open rtc device (%s)\n",
__FILE__, CONFIG_RTC_HCTOSYS_DEVICE);
return -ENODEV;
}
- err = rtc_read_time(class_dev, &tm);
+ err = rtc_read_time(rtc, &tm);
if (err == 0) {
err = rtc_valid_tm(&tm);
if (err == 0) {
@@ -46,7 +46,7 @@
do_settimeofday(&tv);
- dev_info(class_dev->dev,
+ dev_info(rtc->dev.parent,
"setting the system clock to "
"%d-%02d-%02d %02d:%02d:%02d (%u)\n",
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
@@ -54,14 +54,14 @@
(unsigned int) tv.tv_sec);
}
else
- dev_err(class_dev->dev,
+ dev_err(rtc->dev.parent,
"hctosys: invalid date/time\n");
}
else
- dev_err(class_dev->dev,
+ dev_err(rtc->dev.parent,
"hctosys: unable to read the hardware clock\n");
- rtc_class_close(class_dev);
+ rtc_class_close(rtc);
return 0;
}
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index ef40df0..ad66c6e 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -13,10 +13,9 @@
#include <linux/rtc.h>
-int rtc_read_time(struct class_device *class_dev, struct rtc_time *tm)
+int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm)
{
int err;
- struct rtc_device *rtc = to_rtc_device(class_dev);
err = mutex_lock_interruptible(&rtc->ops_lock);
if (err)
@@ -28,7 +27,7 @@
err = -EINVAL;
else {
memset(tm, 0, sizeof(struct rtc_time));
- err = rtc->ops->read_time(class_dev->dev, tm);
+ err = rtc->ops->read_time(rtc->dev.parent, tm);
}
mutex_unlock(&rtc->ops_lock);
@@ -36,10 +35,9 @@
}
EXPORT_SYMBOL_GPL(rtc_read_time);
-int rtc_set_time(struct class_device *class_dev, struct rtc_time *tm)
+int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm)
{
int err;
- struct rtc_device *rtc = to_rtc_device(class_dev);
err = rtc_valid_tm(tm);
if (err != 0)
@@ -54,17 +52,16 @@
else if (!rtc->ops->set_time)
err = -EINVAL;
else
- err = rtc->ops->set_time(class_dev->dev, tm);
+ err = rtc->ops->set_time(rtc->dev.parent, tm);
mutex_unlock(&rtc->ops_lock);
return err;
}
EXPORT_SYMBOL_GPL(rtc_set_time);
-int rtc_set_mmss(struct class_device *class_dev, unsigned long secs)
+int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs)
{
int err;
- struct rtc_device *rtc = to_rtc_device(class_dev);
err = mutex_lock_interruptible(&rtc->ops_lock);
if (err)
@@ -73,11 +70,11 @@
if (!rtc->ops)
err = -ENODEV;
else if (rtc->ops->set_mmss)
- err = rtc->ops->set_mmss(class_dev->dev, secs);
+ err = rtc->ops->set_mmss(rtc->dev.parent, secs);
else if (rtc->ops->read_time && rtc->ops->set_time) {
struct rtc_time new, old;
- err = rtc->ops->read_time(class_dev->dev, &old);
+ err = rtc->ops->read_time(rtc->dev.parent, &old);
if (err == 0) {
rtc_time_to_tm(secs, &new);
@@ -89,7 +86,8 @@
*/
if (!((old.tm_hour == 23 && old.tm_min == 59) ||
(new.tm_hour == 23 && new.tm_min == 59)))
- err = rtc->ops->set_time(class_dev->dev, &new);
+ err = rtc->ops->set_time(rtc->dev.parent,
+ &new);
}
}
else
@@ -101,10 +99,9 @@
}
EXPORT_SYMBOL_GPL(rtc_set_mmss);
-int rtc_read_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm)
+int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
{
int err;
- struct rtc_device *rtc = to_rtc_device(class_dev);
err = mutex_lock_interruptible(&rtc->ops_lock);
if (err)
@@ -116,7 +113,7 @@
err = -EINVAL;
else {
memset(alarm, 0, sizeof(struct rtc_wkalrm));
- err = rtc->ops->read_alarm(class_dev->dev, alarm);
+ err = rtc->ops->read_alarm(rtc->dev.parent, alarm);
}
mutex_unlock(&rtc->ops_lock);
@@ -124,10 +121,13 @@
}
EXPORT_SYMBOL_GPL(rtc_read_alarm);
-int rtc_set_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm)
+int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
{
int err;
- struct rtc_device *rtc = to_rtc_device(class_dev);
+
+ err = rtc_valid_tm(&alarm->time);
+ if (err != 0)
+ return err;
err = mutex_lock_interruptible(&rtc->ops_lock);
if (err)
@@ -138,7 +138,7 @@
else if (!rtc->ops->set_alarm)
err = -EINVAL;
else
- err = rtc->ops->set_alarm(class_dev->dev, alarm);
+ err = rtc->ops->set_alarm(rtc->dev.parent, alarm);
mutex_unlock(&rtc->ops_lock);
return err;
@@ -147,16 +147,14 @@
/**
* rtc_update_irq - report RTC periodic, alarm, and/or update irqs
- * @class_dev: the rtc's class device
+ * @rtc: the rtc device
* @num: how many irqs are being reported (usually one)
* @events: mask of RTC_IRQF with one or more of RTC_PF, RTC_AF, RTC_UF
* Context: in_interrupt(), irqs blocked
*/
-void rtc_update_irq(struct class_device *class_dev,
+void rtc_update_irq(struct rtc_device *rtc,
unsigned long num, unsigned long events)
{
- struct rtc_device *rtc = to_rtc_device(class_dev);
-
spin_lock(&rtc->irq_lock);
rtc->irq_data = (rtc->irq_data + (num << 8)) | events;
spin_unlock(&rtc->irq_lock);
@@ -171,40 +169,43 @@
}
EXPORT_SYMBOL_GPL(rtc_update_irq);
-struct class_device *rtc_class_open(char *name)
+struct rtc_device *rtc_class_open(char *name)
{
- struct class_device *class_dev = NULL,
- *class_dev_tmp;
+ struct device *dev;
+ struct rtc_device *rtc = NULL;
down(&rtc_class->sem);
- list_for_each_entry(class_dev_tmp, &rtc_class->children, node) {
- if (strncmp(class_dev_tmp->class_id, name, BUS_ID_SIZE) == 0) {
- class_dev = class_device_get(class_dev_tmp);
+ list_for_each_entry(dev, &rtc_class->devices, node) {
+ if (strncmp(dev->bus_id, name, BUS_ID_SIZE) == 0) {
+ dev = get_device(dev);
+ if (dev)
+ rtc = to_rtc_device(dev);
break;
}
}
- if (class_dev) {
- if (!try_module_get(to_rtc_device(class_dev)->owner))
- class_dev = NULL;
+ if (rtc) {
+ if (!try_module_get(rtc->owner)) {
+ put_device(dev);
+ rtc = NULL;
+ }
}
up(&rtc_class->sem);
- return class_dev;
+ return rtc;
}
EXPORT_SYMBOL_GPL(rtc_class_open);
-void rtc_class_close(struct class_device *class_dev)
+void rtc_class_close(struct rtc_device *rtc)
{
- module_put(to_rtc_device(class_dev)->owner);
- class_device_put(class_dev);
+ module_put(rtc->owner);
+ put_device(&rtc->dev);
}
EXPORT_SYMBOL_GPL(rtc_class_close);
-int rtc_irq_register(struct class_device *class_dev, struct rtc_task *task)
+int rtc_irq_register(struct rtc_device *rtc, struct rtc_task *task)
{
int retval = -EBUSY;
- struct rtc_device *rtc = to_rtc_device(class_dev);
if (task == NULL || task->func == NULL)
return -EINVAL;
@@ -220,9 +221,8 @@
}
EXPORT_SYMBOL_GPL(rtc_irq_register);
-void rtc_irq_unregister(struct class_device *class_dev, struct rtc_task *task)
+void rtc_irq_unregister(struct rtc_device *rtc, struct rtc_task *task)
{
- struct rtc_device *rtc = to_rtc_device(class_dev);
spin_lock_irq(&rtc->irq_task_lock);
if (rtc->irq_task == task)
@@ -231,11 +231,10 @@
}
EXPORT_SYMBOL_GPL(rtc_irq_unregister);
-int rtc_irq_set_state(struct class_device *class_dev, struct rtc_task *task, int enabled)
+int rtc_irq_set_state(struct rtc_device *rtc, struct rtc_task *task, int enabled)
{
int err = 0;
unsigned long flags;
- struct rtc_device *rtc = to_rtc_device(class_dev);
if (rtc->ops->irq_set_state == NULL)
return -ENXIO;
@@ -246,17 +245,16 @@
spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
if (err == 0)
- err = rtc->ops->irq_set_state(class_dev->dev, enabled);
+ err = rtc->ops->irq_set_state(rtc->dev.parent, enabled);
return err;
}
EXPORT_SYMBOL_GPL(rtc_irq_set_state);
-int rtc_irq_set_freq(struct class_device *class_dev, struct rtc_task *task, int freq)
+int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq)
{
int err = 0;
unsigned long flags;
- struct rtc_device *rtc = to_rtc_device(class_dev);
if (rtc->ops->irq_set_freq == NULL)
return -ENXIO;
@@ -267,7 +265,7 @@
spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
if (err == 0) {
- err = rtc->ops->irq_set_freq(class_dev->dev, freq);
+ err = rtc->ops->irq_set_freq(rtc->dev.parent, freq);
if (err == 0)
rtc->irq_freq = freq;
}
diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c
index ac0e68e..33795e5 100644
--- a/drivers/rtc/rtc-at91rm9200.c
+++ b/drivers/rtc/rtc-at91rm9200.c
@@ -263,7 +263,7 @@
at91_sys_write(AT91_RTC_SCCR, rtsr); /* clear status reg */
- rtc_update_irq(&rtc->class_dev, 1, events);
+ rtc_update_irq(rtc, 1, events);
pr_debug("%s(): num=%ld, events=0x%02lx\n", __FUNCTION__,
events >> 8, events & 0x000000FF);
@@ -348,21 +348,10 @@
/* AT91RM9200 RTC Power management control */
-static struct timespec at91_rtc_delta;
static u32 at91_rtc_imr;
static int at91_rtc_suspend(struct platform_device *pdev, pm_message_t state)
{
- struct rtc_time tm;
- struct timespec time;
-
- time.tv_nsec = 0;
-
- /* calculate time delta for suspend */
- at91_rtc_readtime(&pdev->dev, &tm);
- rtc_tm_to_time(&tm, &time.tv_sec);
- save_time_delta(&at91_rtc_delta, &time);
-
/* this IRQ is shared with DBGU and other hardware which isn't
* necessarily doing PM like we are...
*/
@@ -374,36 +363,17 @@
else
at91_sys_write(AT91_RTC_IDR, at91_rtc_imr);
}
-
- pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__,
- 1900 + tm.tm_year, tm.tm_mon, tm.tm_mday,
- tm.tm_hour, tm.tm_min, tm.tm_sec);
-
return 0;
}
static int at91_rtc_resume(struct platform_device *pdev)
{
- struct rtc_time tm;
- struct timespec time;
-
- time.tv_nsec = 0;
-
- at91_rtc_readtime(&pdev->dev, &tm);
- rtc_tm_to_time(&tm, &time.tv_sec);
- restore_time_delta(&at91_rtc_delta, &time);
-
if (at91_rtc_imr) {
if (device_may_wakeup(&pdev->dev))
disable_irq_wake(AT91_ID_SYS);
else
at91_sys_write(AT91_RTC_IER, at91_rtc_imr);
}
-
- pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__,
- 1900 + tm.tm_year, tm.tm_mon, tm.tm_mday,
- tm.tm_hour, tm.tm_min, tm.tm_sec);
-
return 0;
}
#else
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index 7c0d609..6085261 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -46,6 +46,10 @@
int irq;
struct resource *iomem;
+ void (*wake_on)(struct device *);
+ void (*wake_off)(struct device *);
+
+ u8 enabled_wake;
u8 suspend_ctrl;
/* newer hardware extends the original register set */
@@ -203,7 +207,7 @@
rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF;
if (is_intr(rtc_intr))
- rtc_update_irq(&cmos->rtc->class_dev, 1, rtc_intr);
+ rtc_update_irq(cmos->rtc, 1, rtc_intr);
/* update alarm */
CMOS_WRITE(hrs, RTC_HOURS_ALARM);
@@ -223,7 +227,7 @@
rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF;
if (is_intr(rtc_intr))
- rtc_update_irq(&cmos->rtc->class_dev, 1, rtc_intr);
+ rtc_update_irq(cmos->rtc, 1, rtc_intr);
}
spin_unlock_irq(&rtc_lock);
@@ -304,7 +308,7 @@
rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF;
if (is_intr(rtc_intr))
- rtc_update_irq(&cmos->rtc->class_dev, 1, rtc_intr);
+ rtc_update_irq(cmos->rtc, 1, rtc_intr);
spin_unlock_irqrestore(&rtc_lock, flags);
return 0;
}
@@ -379,12 +383,12 @@
return IRQ_NONE;
}
-#ifdef CONFIG_PNPACPI
-#define is_pnpacpi() 1
+#ifdef CONFIG_PNP
+#define is_pnp() 1
#define INITSECTION
#else
-#define is_pnpacpi() 0
+#define is_pnp() 0
#define INITSECTION __init
#endif
@@ -405,13 +409,20 @@
cmos_rtc.irq = rtc_irq;
cmos_rtc.iomem = ports;
- /* For ACPI systems the info comes from the FADT. On others,
- * board specific setup provides it as appropriate.
+ /* For ACPI systems extension info comes from the FADT. On others,
+ * board specific setup provides it as appropriate. Systems where
+ * the alarm IRQ isn't automatically a wakeup IRQ (like ACPI, and
+ * some almost-clones) can provide hooks to make that behave.
*/
if (info) {
cmos_rtc.day_alrm = info->rtc_day_alarm;
cmos_rtc.mon_alrm = info->rtc_mon_alarm;
cmos_rtc.century = info->rtc_century;
+
+ if (info->wake_on && info->wake_off) {
+ cmos_rtc.wake_on = info->wake_on;
+ cmos_rtc.wake_off = info->wake_off;
+ }
}
cmos_rtc.rtc = rtc_device_register(driver_name, dev,
@@ -427,14 +438,14 @@
* REVISIT for non-x86 systems we may need to handle io memory
* resources: ioremap them, and request_mem_region().
*/
- if (is_pnpacpi()) {
+ if (is_pnp()) {
retval = request_resource(&ioport_resource, ports);
if (retval < 0) {
dev_dbg(dev, "i/o registers already in use\n");
goto cleanup0;
}
}
- rename_region(ports, cmos_rtc.rtc->class_dev.class_id);
+ rename_region(ports, cmos_rtc.rtc->dev.bus_id);
spin_lock_irq(&rtc_lock);
@@ -470,8 +481,8 @@
if (is_valid_irq(rtc_irq))
retval = request_irq(rtc_irq, cmos_interrupt, IRQF_DISABLED,
- cmos_rtc.rtc->class_dev.class_id,
- &cmos_rtc.rtc->class_dev);
+ cmos_rtc.rtc->dev.bus_id,
+ cmos_rtc.rtc);
if (retval < 0) {
dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq);
goto cleanup1;
@@ -483,7 +494,7 @@
*/
pr_info("%s: alarms up to one %s%s\n",
- cmos_rtc.rtc->class_dev.class_id,
+ cmos_rtc.rtc->dev.bus_id,
is_valid_irq(rtc_irq)
? (cmos_rtc.mon_alrm
? "year"
@@ -520,12 +531,12 @@
cmos_do_shutdown();
- if (is_pnpacpi())
+ if (is_pnp())
release_resource(cmos->iomem);
rename_region(cmos->iomem, NULL);
if (is_valid_irq(cmos->irq))
- free_irq(cmos->irq, &cmos_rtc.rtc->class_dev);
+ free_irq(cmos->irq, cmos_rtc.rtc);
rtc_device_unregister(cmos_rtc.rtc);
@@ -555,16 +566,20 @@
irqstat = CMOS_READ(RTC_INTR_FLAGS);
irqstat &= (tmp & RTC_IRQMASK) | RTC_IRQF;
if (is_intr(irqstat))
- rtc_update_irq(&cmos->rtc->class_dev, 1, irqstat);
+ rtc_update_irq(cmos->rtc, 1, irqstat);
}
spin_unlock_irq(&rtc_lock);
- /* ACPI HOOK: enable ACPI_EVENT_RTC when (tmp & RTC_AIE)
- * ... it'd be best if we could do that under rtc_lock.
- */
+ if (tmp & RTC_AIE) {
+ cmos->enabled_wake = 1;
+ if (cmos->wake_on)
+ cmos->wake_on(dev);
+ else
+ enable_irq_wake(cmos->irq);
+ }
pr_debug("%s: suspend%s, ctrl %02x\n",
- cmos_rtc.rtc->class_dev.class_id,
+ cmos_rtc.rtc->dev.bus_id,
(tmp & RTC_AIE) ? ", alarm may wake" : "",
tmp);
@@ -576,26 +591,28 @@
struct cmos_rtc *cmos = dev_get_drvdata(dev);
unsigned char tmp = cmos->suspend_ctrl;
- /* REVISIT: a mechanism to resync the system clock (jiffies)
- * on resume should be portable between platforms ...
- */
-
/* re-enable any irqs previously active */
if (tmp & (RTC_PIE|RTC_AIE|RTC_UIE)) {
- /* ACPI HOOK: disable ACPI_EVENT_RTC when (tmp & RTC_AIE) */
+ if (cmos->enabled_wake) {
+ if (cmos->wake_off)
+ cmos->wake_off(dev);
+ else
+ disable_irq_wake(cmos->irq);
+ cmos->enabled_wake = 0;
+ }
spin_lock_irq(&rtc_lock);
CMOS_WRITE(tmp, RTC_CONTROL);
tmp = CMOS_READ(RTC_INTR_FLAGS);
tmp &= (cmos->suspend_ctrl & RTC_IRQMASK) | RTC_IRQF;
if (is_intr(tmp))
- rtc_update_irq(&cmos->rtc->class_dev, 1, tmp);
+ rtc_update_irq(cmos->rtc, 1, tmp);
spin_unlock_irq(&rtc_lock);
}
pr_debug("%s: resume, ctrl %02x\n",
- cmos_rtc.rtc->class_dev.class_id,
+ cmos_rtc.rtc->dev.bus_id,
cmos->suspend_ctrl);
@@ -613,7 +630,7 @@
* the device node will always be created as a PNPACPI device.
*/
-#ifdef CONFIG_PNPACPI
+#ifdef CONFIG_PNP
#include <linux/pnp.h>
@@ -684,11 +701,11 @@
}
module_exit(cmos_exit);
-#else /* no PNPACPI */
+#else /* no PNP */
/*----------------------------------------------------------------*/
-/* Platform setup should have set up an RTC device, when PNPACPI is
+/* Platform setup should have set up an RTC device, when PNP is
* unavailable ... this could happen even on (older) PCs.
*/
@@ -734,7 +751,7 @@
module_exit(cmos_exit);
-#endif /* !PNPACPI */
+#endif /* !PNP */
MODULE_AUTHOR("David Brownell");
MODULE_DESCRIPTION("Driver for PC-style 'CMOS' RTCs");
diff --git a/drivers/rtc/rtc-core.h b/drivers/rtc/rtc-core.h
new file mode 100644
index 0000000..5f9df74
--- /dev/null
+++ b/drivers/rtc/rtc-core.h
@@ -0,0 +1,70 @@
+#ifdef CONFIG_RTC_INTF_DEV
+
+extern void __init rtc_dev_init(void);
+extern void __exit rtc_dev_exit(void);
+extern void rtc_dev_prepare(struct rtc_device *rtc);
+extern void rtc_dev_add_device(struct rtc_device *rtc);
+extern void rtc_dev_del_device(struct rtc_device *rtc);
+
+#else
+
+static inline void rtc_dev_init(void)
+{
+}
+
+static inline void rtc_dev_exit(void)
+{
+}
+
+static inline void rtc_dev_prepare(struct rtc_device *rtc)
+{
+}
+
+static inline void rtc_dev_add_device(struct rtc_device *rtc)
+{
+}
+
+static inline void rtc_dev_del_device(struct rtc_device *rtc)
+{
+}
+
+#endif
+
+#ifdef CONFIG_RTC_INTF_PROC
+
+extern void rtc_proc_add_device(struct rtc_device *rtc);
+extern void rtc_proc_del_device(struct rtc_device *rtc);
+
+#else
+
+static inline void rtc_proc_add_device(struct rtc_device *rtc)
+{
+}
+
+static inline void rtc_proc_del_device(struct rtc_device *rtc)
+{
+}
+
+#endif
+
+#ifdef CONFIG_RTC_INTF_SYSFS
+
+extern void __init rtc_sysfs_init(struct class *);
+extern void rtc_sysfs_add_device(struct rtc_device *rtc);
+extern void rtc_sysfs_del_device(struct rtc_device *rtc);
+
+#else
+
+static inline void rtc_sysfs_init(struct class *rtc)
+{
+}
+
+static inline void rtc_sysfs_add_device(struct rtc_device *rtc)
+{
+}
+
+static inline void rtc_sysfs_del_device(struct rtc_device *rtc)
+{
+}
+
+#endif
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c
index 137330b..f4e5f00 100644
--- a/drivers/rtc/rtc-dev.c
+++ b/drivers/rtc/rtc-dev.c
@@ -13,8 +13,8 @@
#include <linux/module.h>
#include <linux/rtc.h>
+#include "rtc-core.h"
-static struct class *rtc_dev_class;
static dev_t rtc_devt;
#define RTC_DEV_MAX 16 /* 16 RTCs should be enough for everyone... */
@@ -32,9 +32,9 @@
if (!(mutex_trylock(&rtc->char_lock)))
return -EBUSY;
- file->private_data = &rtc->class_dev;
+ file->private_data = rtc;
- err = ops->open ? ops->open(rtc->class_dev.dev) : 0;
+ err = ops->open ? ops->open(rtc->dev.parent) : 0;
if (err == 0) {
spin_lock_irq(&rtc->irq_lock);
rtc->irq_data = 0;
@@ -61,7 +61,7 @@
int num = 0;
int err;
- err = rtc_read_time(&rtc->class_dev, &tm);
+ err = rtc_read_time(rtc, &tm);
local_irq_disable();
spin_lock(&rtc->irq_lock);
@@ -79,7 +79,7 @@
}
spin_unlock(&rtc->irq_lock);
if (num)
- rtc_update_irq(&rtc->class_dev, num, RTC_UF | RTC_IRQF);
+ rtc_update_irq(rtc, num, RTC_UF | RTC_IRQF);
local_irq_enable();
}
static void rtc_uie_timer(unsigned long data)
@@ -121,7 +121,7 @@
struct rtc_time tm;
int err;
- err = rtc_read_time(&rtc->class_dev, &tm);
+ err = rtc_read_time(rtc, &tm);
if (err)
return err;
spin_lock_irq(&rtc->irq_lock);
@@ -180,7 +180,7 @@
if (ret == 0) {
/* Check for any data updates */
if (rtc->ops->read_callback)
- data = rtc->ops->read_callback(rtc->class_dev.dev,
+ data = rtc->ops->read_callback(rtc->dev.parent,
data);
if (sizeof(int) != sizeof(long) &&
@@ -210,8 +210,7 @@
unsigned int cmd, unsigned long arg)
{
int err = 0;
- struct class_device *class_dev = file->private_data;
- struct rtc_device *rtc = to_rtc_device(class_dev);
+ struct rtc_device *rtc = file->private_data;
const struct rtc_class_ops *ops = rtc->ops;
struct rtc_time tm;
struct rtc_wkalrm alarm;
@@ -252,7 +251,7 @@
/* try the driver's ioctl interface */
if (ops->ioctl) {
- err = ops->ioctl(class_dev->dev, cmd, arg);
+ err = ops->ioctl(rtc->dev.parent, cmd, arg);
if (err != -ENOIOCTLCMD)
return err;
}
@@ -264,7 +263,7 @@
switch (cmd) {
case RTC_ALM_READ:
- err = rtc_read_alarm(class_dev, &alarm);
+ err = rtc_read_alarm(rtc, &alarm);
if (err < 0)
return err;
@@ -278,17 +277,53 @@
alarm.enabled = 0;
alarm.pending = 0;
- alarm.time.tm_mday = -1;
- alarm.time.tm_mon = -1;
- alarm.time.tm_year = -1;
alarm.time.tm_wday = -1;
alarm.time.tm_yday = -1;
alarm.time.tm_isdst = -1;
- err = rtc_set_alarm(class_dev, &alarm);
+
+ /* RTC_ALM_SET alarms may be up to 24 hours in the future.
+ * Rather than expecting every RTC to implement "don't care"
+ * for day/month/year fields, just force the alarm to have
+ * the right values for those fields.
+ *
+ * RTC_WKALM_SET should be used instead. Not only does it
+ * eliminate the need for a separate RTC_AIE_ON call, it
+ * doesn't have the "alarm 23:59:59 in the future" race.
+ *
+ * NOTE: some legacy code may have used invalid fields as
+ * wildcards, exposing hardware "periodic alarm" capabilities.
+ * Not supported here.
+ */
+ {
+ unsigned long now, then;
+
+ err = rtc_read_time(rtc, &tm);
+ if (err < 0)
+ return err;
+ rtc_tm_to_time(&tm, &now);
+
+ alarm.time.tm_mday = tm.tm_mday;
+ alarm.time.tm_mon = tm.tm_mon;
+ alarm.time.tm_year = tm.tm_year;
+ err = rtc_valid_tm(&alarm.time);
+ if (err < 0)
+ return err;
+ rtc_tm_to_time(&alarm.time, &then);
+
+ /* alarm may need to wrap into tomorrow */
+ if (then < now) {
+ rtc_time_to_tm(now + 24 * 60 * 60, &tm);
+ alarm.time.tm_mday = tm.tm_mday;
+ alarm.time.tm_mon = tm.tm_mon;
+ alarm.time.tm_year = tm.tm_year;
+ }
+ }
+
+ err = rtc_set_alarm(rtc, &alarm);
break;
case RTC_RD_TIME:
- err = rtc_read_time(class_dev, &tm);
+ err = rtc_read_time(rtc, &tm);
if (err < 0)
return err;
@@ -300,7 +335,7 @@
if (copy_from_user(&tm, uarg, sizeof(tm)))
return -EFAULT;
- err = rtc_set_time(class_dev, &tm);
+ err = rtc_set_time(rtc, &tm);
break;
case RTC_IRQP_READ:
@@ -310,7 +345,7 @@
case RTC_IRQP_SET:
if (ops->irq_set_freq)
- err = rtc_irq_set_freq(class_dev, rtc->irq_task, arg);
+ err = rtc_irq_set_freq(rtc, rtc->irq_task, arg);
break;
#if 0
@@ -336,11 +371,11 @@
if (copy_from_user(&alarm, uarg, sizeof(alarm)))
return -EFAULT;
- err = rtc_set_alarm(class_dev, &alarm);
+ err = rtc_set_alarm(rtc, &alarm);
break;
case RTC_WKALM_RD:
- err = rtc_read_alarm(class_dev, &alarm);
+ err = rtc_read_alarm(rtc, &alarm);
if (err < 0)
return err;
@@ -372,7 +407,7 @@
clear_uie(rtc);
#endif
if (rtc->ops->release)
- rtc->ops->release(rtc->class_dev.dev);
+ rtc->ops->release(rtc->dev.parent);
mutex_unlock(&rtc->char_lock);
return 0;
@@ -397,17 +432,18 @@
/* insertion/removal hooks */
-static int rtc_dev_add_device(struct class_device *class_dev,
- struct class_interface *class_intf)
+void rtc_dev_prepare(struct rtc_device *rtc)
{
- int err = 0;
- struct rtc_device *rtc = to_rtc_device(class_dev);
+ if (!rtc_devt)
+ return;
if (rtc->id >= RTC_DEV_MAX) {
- dev_err(class_dev->dev, "too many RTCs\n");
- return -EINVAL;
+ pr_debug("%s: too many RTC devices\n", rtc->name);
+ return;
}
+ rtc->dev.devt = MKDEV(MAJOR(rtc_devt), rtc->id);
+
mutex_init(&rtc->char_lock);
spin_lock_init(&rtc->irq_lock);
init_waitqueue_head(&rtc->irq_queue);
@@ -418,100 +454,36 @@
cdev_init(&rtc->char_dev, &rtc_dev_fops);
rtc->char_dev.owner = rtc->owner;
-
- if (cdev_add(&rtc->char_dev, MKDEV(MAJOR(rtc_devt), rtc->id), 1)) {
- dev_err(class_dev->dev,
- "failed to add char device %d:%d\n",
- MAJOR(rtc_devt), rtc->id);
- return -ENODEV;
- }
-
- rtc->rtc_dev = class_device_create(rtc_dev_class, NULL,
- MKDEV(MAJOR(rtc_devt), rtc->id),
- class_dev->dev, "rtc%d", rtc->id);
- if (IS_ERR(rtc->rtc_dev)) {
- dev_err(class_dev->dev, "cannot create rtc_dev device\n");
- err = PTR_ERR(rtc->rtc_dev);
- goto err_cdev_del;
- }
-
- dev_dbg(class_dev->dev, "rtc intf: dev (%d:%d)\n",
- MAJOR(rtc->rtc_dev->devt),
- MINOR(rtc->rtc_dev->devt));
-
- return 0;
-
-err_cdev_del:
-
- cdev_del(&rtc->char_dev);
- return err;
}
-static void rtc_dev_remove_device(struct class_device *class_dev,
- struct class_interface *class_intf)
+void rtc_dev_add_device(struct rtc_device *rtc)
{
- struct rtc_device *rtc = to_rtc_device(class_dev);
-
- if (rtc->rtc_dev) {
- dev_dbg(class_dev->dev, "removing char %d:%d\n",
- MAJOR(rtc->rtc_dev->devt),
- MINOR(rtc->rtc_dev->devt));
-
- class_device_unregister(rtc->rtc_dev);
- cdev_del(&rtc->char_dev);
- }
+ if (cdev_add(&rtc->char_dev, rtc->dev.devt, 1))
+ printk(KERN_WARNING "%s: failed to add char device %d:%d\n",
+ rtc->name, MAJOR(rtc_devt), rtc->id);
+ else
+ pr_debug("%s: dev (%d:%d)\n", rtc->name,
+ MAJOR(rtc_devt), rtc->id);
}
-/* interface registration */
+void rtc_dev_del_device(struct rtc_device *rtc)
+{
+ if (rtc->dev.devt)
+ cdev_del(&rtc->char_dev);
+}
-static struct class_interface rtc_dev_interface = {
- .add = &rtc_dev_add_device,
- .remove = &rtc_dev_remove_device,
-};
-
-static int __init rtc_dev_init(void)
+void __init rtc_dev_init(void)
{
int err;
- rtc_dev_class = class_create(THIS_MODULE, "rtc-dev");
- if (IS_ERR(rtc_dev_class))
- return PTR_ERR(rtc_dev_class);
-
err = alloc_chrdev_region(&rtc_devt, 0, RTC_DEV_MAX, "rtc");
- if (err < 0) {
+ if (err < 0)
printk(KERN_ERR "%s: failed to allocate char dev region\n",
__FILE__);
- goto err_destroy_class;
- }
-
- err = rtc_interface_register(&rtc_dev_interface);
- if (err < 0) {
- printk(KERN_ERR "%s: failed to register the interface\n",
- __FILE__);
- goto err_unregister_chrdev;
- }
-
- return 0;
-
-err_unregister_chrdev:
- unregister_chrdev_region(rtc_devt, RTC_DEV_MAX);
-
-err_destroy_class:
- class_destroy(rtc_dev_class);
-
- return err;
}
-static void __exit rtc_dev_exit(void)
+void __exit rtc_dev_exit(void)
{
- class_interface_unregister(&rtc_dev_interface);
- class_destroy(rtc_dev_class);
- unregister_chrdev_region(rtc_devt, RTC_DEV_MAX);
+ if (rtc_devt)
+ unregister_chrdev_region(rtc_devt, RTC_DEV_MAX);
}
-
-subsys_initcall(rtc_dev_init);
-module_exit(rtc_dev_exit);
-
-MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
-MODULE_DESCRIPTION("RTC class dev interface");
-MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c
index e27176c..afa64c7 100644
--- a/drivers/rtc/rtc-ds1553.c
+++ b/drivers/rtc/rtc-ds1553.c
@@ -203,7 +203,7 @@
events |= RTC_UF;
else
events |= RTC_AF;
- rtc_update_irq(&pdata->rtc->class_dev, 1, events);
+ rtc_update_irq(pdata->rtc, 1, events);
return IRQ_HANDLED;
}
diff --git a/drivers/rtc/rtc-lib.c b/drivers/rtc/rtc-lib.c
index 7bbc26a..ba795a4 100644
--- a/drivers/rtc/rtc-lib.c
+++ b/drivers/rtc/rtc-lib.c
@@ -117,85 +117,4 @@
}
EXPORT_SYMBOL(rtc_tm_to_time);
-
-/* Merge the valid (i.e. non-negative) fields of alarm into the current
- * time. If the valid alarm fields are earlier than the equivalent
- * fields in the time, carry one into the least significant invalid
- * field, so that the alarm expiry is in the future. It assumes that the
- * least significant invalid field is more significant than the most
- * significant valid field, and that the seconds field is valid.
- *
- * This is used by alarms that take relative (rather than absolute)
- * times, and/or have a simple binary second counter instead of
- * day/hour/minute/sec registers.
- */
-void rtc_merge_alarm(struct rtc_time *now, struct rtc_time *alarm)
-{
- int *alarmp = &alarm->tm_sec;
- int *timep = &now->tm_sec;
- int carry_into, i;
-
- /* Ignore everything past the 6th element (tm_year). */
- for (i = 5; i > 0; i--) {
- if (alarmp[i] < 0)
- alarmp[i] = timep[i];
- else
- break;
- }
-
- /* No carry needed if all fields are valid. */
- if (i == 5)
- return;
-
- for (carry_into = i + 1; i >= 0; i--) {
- if (alarmp[i] < timep[i])
- break;
-
- if (alarmp[i] > timep[i])
- return;
- }
-
- switch (carry_into) {
- case 1:
- alarm->tm_min++;
-
- if (alarm->tm_min < 60)
- return;
-
- alarm->tm_min = 0;
- /* fall-through */
-
- case 2:
- alarm->tm_hour++;
-
- if (alarm->tm_hour < 60)
- return;
-
- alarm->tm_hour = 0;
- /* fall-through */
-
- case 3:
- alarm->tm_mday++;
-
- if (alarm->tm_mday <= rtc_days_in_month[alarm->tm_mon])
- return;
-
- alarm->tm_mday = 1;
- /* fall-through */
-
- case 4:
- alarm->tm_mon++;
-
- if (alarm->tm_mon <= 12)
- return;
-
- alarm->tm_mon = 1;
- /* fall-through */
-
- case 5:
- alarm->tm_year++;
- }
-}
-EXPORT_SYMBOL(rtc_merge_alarm);
-
MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-max6900.c b/drivers/rtc/rtc-max6900.c
new file mode 100644
index 0000000..eee4ee5
--- /dev/null
+++ b/drivers/rtc/rtc-max6900.c
@@ -0,0 +1,311 @@
+/*
+ * rtc class driver for the Maxim MAX6900 chip
+ *
+ * Author: Dale Farnsworth <dale@farnsworth.org>
+ *
+ * based on previously existing rtc class drivers
+ *
+ * 2007 (c) MontaVista, Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/bcd.h>
+#include <linux/rtc.h>
+#include <linux/delay.h>
+
+#define DRV_NAME "max6900"
+#define DRV_VERSION "0.1"
+
+/*
+ * register indices
+ */
+#define MAX6900_REG_SC 0 /* seconds 00-59 */
+#define MAX6900_REG_MN 1 /* minutes 00-59 */
+#define MAX6900_REG_HR 2 /* hours 00-23 */
+#define MAX6900_REG_DT 3 /* day of month 00-31 */
+#define MAX6900_REG_MO 4 /* month 01-12 */
+#define MAX6900_REG_DW 5 /* day of week 1-7 */
+#define MAX6900_REG_YR 6 /* year 00-99 */
+#define MAX6900_REG_CT 7 /* control */
+#define MAX6900_REG_LEN 8
+
+#define MAX6900_REG_CT_WP (1 << 7) /* Write Protect */
+
+/*
+ * register read/write commands
+ */
+#define MAX6900_REG_CONTROL_WRITE 0x8e
+#define MAX6900_REG_BURST_READ 0xbf
+#define MAX6900_REG_BURST_WRITE 0xbe
+#define MAX6900_REG_RESERVED_READ 0x96
+
+#define MAX6900_IDLE_TIME_AFTER_WRITE 3 /* specification says 2.5 mS */
+
+#define MAX6900_I2C_ADDR 0xa0
+
+static unsigned short normal_i2c[] = {
+ MAX6900_I2C_ADDR >> 1,
+ I2C_CLIENT_END
+};
+
+I2C_CLIENT_INSMOD; /* defines addr_data */
+
+static int max6900_probe(struct i2c_adapter *adapter, int addr, int kind);
+
+static int max6900_i2c_read_regs(struct i2c_client *client, u8 *buf)
+{
+ u8 reg_addr[1] = { MAX6900_REG_BURST_READ };
+ struct i2c_msg msgs[2] = {
+ {
+ .addr = client->addr,
+ .flags = 0, /* write */
+ .len = sizeof(reg_addr),
+ .buf = reg_addr
+ },
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = MAX6900_REG_LEN,
+ .buf = buf
+ }
+ };
+ int rc;
+
+ rc = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+ if (rc != ARRAY_SIZE(msgs)) {
+ dev_err(&client->dev, "%s: register read failed\n",
+ __FUNCTION__);
+ return -EIO;
+ }
+ return 0;
+}
+
+static int max6900_i2c_write_regs(struct i2c_client *client, u8 const *buf)
+{
+ u8 i2c_buf[MAX6900_REG_LEN + 1] = { MAX6900_REG_BURST_WRITE };
+ struct i2c_msg msgs[1] = {
+ {
+ .addr = client->addr,
+ .flags = 0, /* write */
+ .len = MAX6900_REG_LEN + 1,
+ .buf = i2c_buf
+ }
+ };
+ int rc;
+
+ memcpy(&i2c_buf[1], buf, MAX6900_REG_LEN);
+
+ rc = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+ if (rc != ARRAY_SIZE(msgs)) {
+ dev_err(&client->dev, "%s: register write failed\n",
+ __FUNCTION__);
+ return -EIO;
+ }
+ msleep(MAX6900_IDLE_TIME_AFTER_WRITE);
+ return 0;
+}
+
+static int max6900_i2c_validate_client(struct i2c_client *client)
+{
+ u8 regs[MAX6900_REG_LEN];
+ u8 zero_mask[MAX6900_REG_LEN] = {
+ 0x80, /* seconds */
+ 0x80, /* minutes */
+ 0x40, /* hours */
+ 0xc0, /* day of month */
+ 0xe0, /* month */
+ 0xf8, /* day of week */
+ 0x00, /* year */
+ 0x7f, /* control */
+ };
+ int i;
+ int rc;
+ int reserved;
+
+ reserved = i2c_smbus_read_byte_data(client, MAX6900_REG_RESERVED_READ);
+ if (reserved != 0x07)
+ return -ENODEV;
+
+ rc = max6900_i2c_read_regs(client, regs);
+ if (rc < 0)
+ return rc;
+
+ for (i = 0; i < MAX6900_REG_LEN; ++i) {
+ if (regs[i] & zero_mask[i])
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static int max6900_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
+{
+ int rc;
+ u8 regs[MAX6900_REG_LEN];
+
+ rc = max6900_i2c_read_regs(client, regs);
+ if (rc < 0)
+ return rc;
+
+ tm->tm_sec = BCD2BIN(regs[MAX6900_REG_SC]);
+ tm->tm_min = BCD2BIN(regs[MAX6900_REG_MN]);
+ tm->tm_hour = BCD2BIN(regs[MAX6900_REG_HR] & 0x3f);
+ tm->tm_mday = BCD2BIN(regs[MAX6900_REG_DT]);
+ tm->tm_mon = BCD2BIN(regs[MAX6900_REG_MO]) - 1;
+ tm->tm_year = BCD2BIN(regs[MAX6900_REG_YR]) + 100;
+ tm->tm_wday = BCD2BIN(regs[MAX6900_REG_DW]);
+
+ return 0;
+}
+
+static int max6900_i2c_clear_write_protect(struct i2c_client *client)
+{
+ int rc;
+ rc = i2c_smbus_write_byte_data (client, MAX6900_REG_CONTROL_WRITE, 0);
+ if (rc < 0) {
+ dev_err(&client->dev, "%s: control register write failed\n",
+ __FUNCTION__);
+ return -EIO;
+ }
+ return 0;
+}
+
+static int max6900_i2c_set_time(struct i2c_client *client,
+ struct rtc_time const *tm)
+{
+ u8 regs[MAX6900_REG_LEN];
+ int rc;
+
+ rc = max6900_i2c_clear_write_protect(client);
+ if (rc < 0)
+ return rc;
+
+ regs[MAX6900_REG_SC] = BIN2BCD(tm->tm_sec);
+ regs[MAX6900_REG_MN] = BIN2BCD(tm->tm_min);
+ regs[MAX6900_REG_HR] = BIN2BCD(tm->tm_hour);
+ regs[MAX6900_REG_DT] = BIN2BCD(tm->tm_mday);
+ regs[MAX6900_REG_MO] = BIN2BCD(tm->tm_mon + 1);
+ regs[MAX6900_REG_YR] = BIN2BCD(tm->tm_year - 100);
+ regs[MAX6900_REG_DW] = BIN2BCD(tm->tm_wday);
+ regs[MAX6900_REG_CT] = MAX6900_REG_CT_WP; /* set write protect */
+
+ rc = max6900_i2c_write_regs(client, regs);
+ if (rc < 0)
+ return rc;
+
+ return 0;
+}
+
+static int max6900_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ return max6900_i2c_read_time(to_i2c_client(dev), tm);
+}
+
+static int max6900_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+ return max6900_i2c_set_time(to_i2c_client(dev), tm);
+}
+
+static int max6900_attach_adapter(struct i2c_adapter *adapter)
+{
+ return i2c_probe(adapter, &addr_data, max6900_probe);
+}
+
+static int max6900_detach_client(struct i2c_client *client)
+{
+ struct rtc_device *const rtc = i2c_get_clientdata(client);
+
+ if (rtc)
+ rtc_device_unregister(rtc);
+
+ return i2c_detach_client(client);
+}
+
+static struct i2c_driver max6900_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ },
+ .id = I2C_DRIVERID_MAX6900,
+ .attach_adapter = max6900_attach_adapter,
+ .detach_client = max6900_detach_client,
+};
+
+static const struct rtc_class_ops max6900_rtc_ops = {
+ .read_time = max6900_rtc_read_time,
+ .set_time = max6900_rtc_set_time,
+};
+
+static int max6900_probe(struct i2c_adapter *adapter, int addr, int kind)
+{
+ int rc = 0;
+ struct i2c_client *client = NULL;
+ struct rtc_device *rtc = NULL;
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
+ rc = -ENODEV;
+ goto failout;
+ }
+
+ client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ if (client == NULL) {
+ rc = -ENOMEM;
+ goto failout;
+ }
+
+ client->addr = addr;
+ client->adapter = adapter;
+ client->driver = &max6900_driver;
+ strlcpy(client->name, DRV_NAME, I2C_NAME_SIZE);
+
+ if (kind < 0) {
+ rc = max6900_i2c_validate_client(client);
+ if (rc < 0)
+ goto failout;
+ }
+
+ rc = i2c_attach_client(client);
+ if (rc < 0)
+ goto failout;
+
+ dev_info(&client->dev,
+ "chip found, driver version " DRV_VERSION "\n");
+
+ rtc = rtc_device_register(max6900_driver.driver.name,
+ &client->dev,
+ &max6900_rtc_ops, THIS_MODULE);
+ if (IS_ERR(rtc)) {
+ rc = PTR_ERR(rtc);
+ goto failout_detach;
+ }
+
+ i2c_set_clientdata(client, rtc);
+
+ return 0;
+
+failout_detach:
+ i2c_detach_client(client);
+failout:
+ kfree(client);
+ return rc;
+}
+
+static int __init max6900_init(void)
+{
+ return i2c_add_driver(&max6900_driver);
+}
+
+static void __exit max6900_exit(void)
+{
+ i2c_del_driver(&max6900_driver);
+}
+
+MODULE_DESCRIPTION("Maxim MAX6900 RTC driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+
+module_init(max6900_init);
+module_exit(max6900_exit);
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 9de8d67..60a8a4b 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -124,7 +124,7 @@
/* now we have ~15 usec to read/write various registers */
}
-static irqreturn_t rtc_irq(int irq, void *class_dev)
+static irqreturn_t rtc_irq(int irq, void *rtc)
{
unsigned long events = 0;
u8 irq_data;
@@ -141,7 +141,7 @@
if (irq_data & OMAP_RTC_STATUS_1S_EVENT)
events |= RTC_IRQF | RTC_UF;
- rtc_update_irq(class_dev, 1, events);
+ rtc_update_irq(rtc, 1, events);
return IRQ_HANDLED;
}
@@ -289,34 +289,6 @@
{
u8 reg;
- /* Much userspace code uses RTC_ALM_SET, thus "don't care" for
- * day/month/year specifies alarms up to 24 hours in the future.
- * So we need to handle that ... but let's ignore the "don't care"
- * values for hours/minutes/seconds.
- */
- if (alm->time.tm_mday <= 0
- && alm->time.tm_mon < 0
- && alm->time.tm_year < 0) {
- struct rtc_time tm;
- unsigned long now, then;
-
- omap_rtc_read_time(dev, &tm);
- rtc_tm_to_time(&tm, &now);
-
- alm->time.tm_mday = tm.tm_mday;
- alm->time.tm_mon = tm.tm_mon;
- alm->time.tm_year = tm.tm_year;
- rtc_tm_to_time(&alm->time, &then);
-
- /* sometimes the alarm wraps into tomorrow */
- if (then < now) {
- rtc_time_to_tm(now + 24 * 60 * 60, &tm);
- alm->time.tm_mday = tm.tm_mday;
- alm->time.tm_mon = tm.tm_mon;
- alm->time.tm_year = tm.tm_year;
- }
- }
-
if (tm2bcd(&alm->time) < 0)
return -EINVAL;
@@ -399,7 +371,7 @@
goto fail;
}
platform_set_drvdata(pdev, rtc);
- class_set_devdata(&rtc->class_dev, mem);
+ dev_set_devdata(&rtc->dev, mem);
/* clear pending irqs, and set 1/second periodic,
* which we'll use instead of update irqs
@@ -418,13 +390,13 @@
/* handle periodic and alarm irqs */
if (request_irq(omap_rtc_timer, rtc_irq, IRQF_DISABLED,
- rtc->class_dev.class_id, &rtc->class_dev)) {
+ rtc->dev.bus_id, rtc)) {
pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n",
pdev->name, omap_rtc_timer);
goto fail0;
}
if (request_irq(omap_rtc_alarm, rtc_irq, IRQF_DISABLED,
- rtc->class_dev.class_id, &rtc->class_dev)) {
+ rtc->dev.bus_id, rtc)) {
pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n",
pdev->name, omap_rtc_alarm);
goto fail1;
@@ -481,26 +453,17 @@
free_irq(omap_rtc_timer, rtc);
free_irq(omap_rtc_alarm, rtc);
- release_resource(class_get_devdata(&rtc->class_dev));
+ release_resource(dev_get_devdata(&rtc->dev));
rtc_device_unregister(rtc);
return 0;
}
#ifdef CONFIG_PM
-static struct timespec rtc_delta;
static u8 irqstat;
static int omap_rtc_suspend(struct platform_device *pdev, pm_message_t state)
{
- struct rtc_time rtc_tm;
- struct timespec time;
-
- time.tv_nsec = 0;
- omap_rtc_read_time(NULL, &rtc_tm);
- rtc_tm_to_time(&rtc_tm, &time.tv_sec);
-
- save_time_delta(&rtc_delta, &time);
irqstat = rtc_read(OMAP_RTC_INTERRUPTS_REG);
/* FIXME the RTC alarm is not currently acting as a wakeup event
@@ -517,14 +480,6 @@
static int omap_rtc_resume(struct platform_device *pdev)
{
- struct rtc_time rtc_tm;
- struct timespec time;
-
- time.tv_nsec = 0;
- omap_rtc_read_time(NULL, &rtc_tm);
- rtc_tm_to_time(&rtc_tm, &time.tv_sec);
-
- restore_time_delta(&rtc_delta, &time);
if (device_may_wakeup(&pdev->dev))
disable_irq_wake(omap_rtc_alarm);
else
diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c
index f13daa9..e4bf68c 100644
--- a/drivers/rtc/rtc-pl031.c
+++ b/drivers/rtc/rtc-pl031.c
@@ -51,7 +51,7 @@
{
struct rtc_device *rtc = dev_id;
- rtc_update_irq(&rtc->class_dev, 1, RTC_AF);
+ rtc_update_irq(rtc, 1, RTC_AF);
return IRQ_HANDLED;
}
diff --git a/drivers/rtc/rtc-proc.c b/drivers/rtc/rtc-proc.c
index 1bd624f..8d300e6 100644
--- a/drivers/rtc/rtc-proc.c
+++ b/drivers/rtc/rtc-proc.c
@@ -16,18 +16,18 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
-static struct class_device *rtc_dev = NULL;
-static DEFINE_MUTEX(rtc_lock);
+#include "rtc-core.h"
+
static int rtc_proc_show(struct seq_file *seq, void *offset)
{
int err;
- struct class_device *class_dev = seq->private;
- const struct rtc_class_ops *ops = to_rtc_device(class_dev)->ops;
+ struct rtc_device *rtc = seq->private;
+ const struct rtc_class_ops *ops = rtc->ops;
struct rtc_wkalrm alrm;
struct rtc_time tm;
- err = rtc_read_time(class_dev, &tm);
+ err = rtc_read_time(rtc, &tm);
if (err == 0) {
seq_printf(seq,
"rtc_time\t: %02d:%02d:%02d\n"
@@ -36,7 +36,7 @@
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
}
- err = rtc_read_alarm(class_dev, &alrm);
+ err = rtc_read_alarm(rtc, &alrm);
if (err == 0) {
seq_printf(seq, "alrm_time\t: ");
if ((unsigned int)alrm.time.tm_hour <= 24)
@@ -74,19 +74,19 @@
seq_printf(seq, "24hr\t\t: yes\n");
if (ops->proc)
- ops->proc(class_dev->dev, seq);
+ ops->proc(rtc->dev.parent, seq);
return 0;
}
static int rtc_proc_open(struct inode *inode, struct file *file)
{
- struct class_device *class_dev = PDE(inode)->data;
+ struct rtc_device *rtc = PDE(inode)->data;
if (!try_module_get(THIS_MODULE))
return -ENODEV;
- return single_open(file, rtc_proc_show, class_dev);
+ return single_open(file, rtc_proc_show, rtc);
}
static int rtc_proc_release(struct inode *inode, struct file *file)
@@ -103,62 +103,22 @@
.release = rtc_proc_release,
};
-static int rtc_proc_add_device(struct class_device *class_dev,
- struct class_interface *class_intf)
+void rtc_proc_add_device(struct rtc_device *rtc)
{
- mutex_lock(&rtc_lock);
- if (rtc_dev == NULL) {
+ if (rtc->id == 0) {
struct proc_dir_entry *ent;
- rtc_dev = class_dev;
-
ent = create_proc_entry("driver/rtc", 0, NULL);
if (ent) {
- struct rtc_device *rtc = to_rtc_device(class_dev);
-
ent->proc_fops = &rtc_proc_fops;
ent->owner = rtc->owner;
- ent->data = class_dev;
-
- dev_dbg(class_dev->dev, "rtc intf: proc\n");
+ ent->data = rtc;
}
- else
- rtc_dev = NULL;
}
- mutex_unlock(&rtc_lock);
-
- return 0;
}
-static void rtc_proc_remove_device(struct class_device *class_dev,
- struct class_interface *class_intf)
+void rtc_proc_del_device(struct rtc_device *rtc)
{
- mutex_lock(&rtc_lock);
- if (rtc_dev == class_dev) {
+ if (rtc->id == 0)
remove_proc_entry("driver/rtc", NULL);
- rtc_dev = NULL;
- }
- mutex_unlock(&rtc_lock);
}
-
-static struct class_interface rtc_proc_interface = {
- .add = &rtc_proc_add_device,
- .remove = &rtc_proc_remove_device,
-};
-
-static int __init rtc_proc_init(void)
-{
- return rtc_interface_register(&rtc_proc_interface);
-}
-
-static void __exit rtc_proc_exit(void)
-{
- class_interface_unregister(&rtc_proc_interface);
-}
-
-subsys_initcall(rtc_proc_init);
-module_exit(rtc_proc_exit);
-
-MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
-MODULE_DESCRIPTION("RTC class proc interface");
-MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-rs5c313.c b/drivers/rtc/rtc-rs5c313.c
new file mode 100644
index 0000000..9d6de37
--- /dev/null
+++ b/drivers/rtc/rtc-rs5c313.c
@@ -0,0 +1,405 @@
+/*
+ * Ricoh RS5C313 RTC device/driver
+ * Copyright (C) 2007 Nobuhiro Iwamatsu
+ *
+ * 2005-09-19 modifed by kogiidena
+ *
+ * Based on the old drivers/char/rs5c313_rtc.c by:
+ * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
+ * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka
+ *
+ * Based on code written by Paul Gortmaker.
+ * Copyright (C) 1996 Paul Gortmaker
+ *
+ * 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.
+ *
+ * Based on other minimal char device drivers, like Alan's
+ * watchdog, Ted's random, etc. etc.
+ *
+ * 1.07 Paul Gortmaker.
+ * 1.08 Miquel van Smoorenburg: disallow certain things on the
+ * DEC Alpha as the CMOS clock is also used for other things.
+ * 1.09 Nikita Schmidt: epoch support and some Alpha cleanup.
+ * 1.09a Pete Zaitcev: Sun SPARC
+ * 1.09b Jeff Garzik: Modularize, init cleanup
+ * 1.09c Jeff Garzik: SMP cleanup
+ * 1.10 Paul Barton-Davis: add support for async I/O
+ * 1.10a Andrea Arcangeli: Alpha updates
+ * 1.10b Andrew Morton: SMP lock fix
+ * 1.10c Cesar Barros: SMP locking fixes and cleanup
+ * 1.10d Paul Gortmaker: delete paranoia check in rtc_exit
+ * 1.10e Maciej W. Rozycki: Handle DECstation's year weirdness.
+ * 1.11 Takashi Iwai: Kernel access functions
+ * rtc_register/rtc_unregister/rtc_control
+ * 1.11a Daniele Bellucci: Audit create_proc_read_entry in rtc_init
+ * 1.12 Venkatesh Pallipadi: Hooks for emulating rtc on HPET base-timer
+ * CONFIG_HPET_EMULATE_RTC
+ * 1.13 Nobuhiro Iwamatsu: Updata driver.
+ */
+
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/rtc.h>
+#include <linux/platform_device.h>
+#include <linux/bcd.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+
+#define DRV_NAME "rs5c313"
+#define DRV_VERSION "1.13"
+
+#ifdef CONFIG_SH_LANDISK
+/*****************************************************/
+/* LANDISK dependence part of RS5C313 */
+/*****************************************************/
+
+#define SCSMR1 0xFFE00000
+#define SCSCR1 0xFFE00008
+#define SCSMR1_CA 0x80
+#define SCSCR1_CKE 0x03
+#define SCSPTR1 0xFFE0001C
+#define SCSPTR1_EIO 0x80
+#define SCSPTR1_SPB1IO 0x08
+#define SCSPTR1_SPB1DT 0x04
+#define SCSPTR1_SPB0IO 0x02
+#define SCSPTR1_SPB0DT 0x01
+
+#define SDA_OEN SCSPTR1_SPB1IO
+#define SDA SCSPTR1_SPB1DT
+#define SCL_OEN SCSPTR1_SPB0IO
+#define SCL SCSPTR1_SPB0DT
+
+/* RICOH RS5C313 CE port */
+#define RS5C313_CE 0xB0000003
+
+/* RICOH RS5C313 CE port bit */
+#define RS5C313_CE_RTCCE 0x02
+
+/* SCSPTR1 data */
+unsigned char scsptr1_data;
+
+#define RS5C313_CEENABLE ctrl_outb(RS5C313_CE_RTCCE, RS5C313_CE);
+#define RS5C313_CEDISABLE ctrl_outb(0x00, RS5C313_CE)
+#define RS5C313_MISCOP ctrl_outb(0x02, 0xB0000008)
+
+static void rs5c313_init_port(void)
+{
+ /* Set SCK as I/O port and Initialize SCSPTR1 data & I/O port. */
+ ctrl_outb(ctrl_inb(SCSMR1) & ~SCSMR1_CA, SCSMR1);
+ ctrl_outb(ctrl_inb(SCSCR1) & ~SCSCR1_CKE, SCSCR1);
+
+ /* And Initialize SCL for RS5C313 clock */
+ scsptr1_data = ctrl_inb(SCSPTR1) | SCL; /* SCL:H */
+ ctrl_outb(scsptr1_data, SCSPTR1);
+ scsptr1_data = ctrl_inb(SCSPTR1) | SCL_OEN; /* SCL output enable */
+ ctrl_outb(scsptr1_data, SCSPTR1);
+ RS5C313_CEDISABLE; /* CE:L */
+}
+
+static void rs5c313_write_data(unsigned char data)
+{
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ /* SDA:Write Data */
+ scsptr1_data = (scsptr1_data & ~SDA) |
+ ((((0x80 >> i) & data) >> (7 - i)) << 2);
+ ctrl_outb(scsptr1_data, SCSPTR1);
+ if (i == 0) {
+ scsptr1_data |= SDA_OEN; /* SDA:output enable */
+ ctrl_outb(scsptr1_data, SCSPTR1);
+ }
+ ndelay(700);
+ scsptr1_data &= ~SCL; /* SCL:L */
+ ctrl_outb(scsptr1_data, SCSPTR1);
+ ndelay(700);
+ scsptr1_data |= SCL; /* SCL:H */
+ ctrl_outb(scsptr1_data, SCSPTR1);
+ }
+
+ scsptr1_data &= ~SDA_OEN; /* SDA:output disable */
+ ctrl_outb(scsptr1_data, SCSPTR1);
+}
+
+static unsigned char rs5c313_read_data(void)
+{
+ int i;
+ unsigned char data;
+
+ for (i = 0; i < 8; i++) {
+ ndelay(700);
+ /* SDA:Read Data */
+ data |= ((ctrl_inb(SCSPTR1) & SDA) >> 2) << (7 - i);
+ scsptr1_data &= ~SCL; /* SCL:L */
+ ctrl_outb(scsptr1_data, SCSPTR1);
+ ndelay(700);
+ scsptr1_data |= SCL; /* SCL:H */
+ ctrl_outb(scsptr1_data, SCSPTR1);
+ }
+ return data & 0x0F;
+}
+
+#endif /* CONFIG_SH_LANDISK */
+
+/*****************************************************/
+/* machine independence part of RS5C313 */
+/*****************************************************/
+
+/* RICOH RS5C313 address */
+#define RS5C313_ADDR_SEC 0x00
+#define RS5C313_ADDR_SEC10 0x01
+#define RS5C313_ADDR_MIN 0x02
+#define RS5C313_ADDR_MIN10 0x03
+#define RS5C313_ADDR_HOUR 0x04
+#define RS5C313_ADDR_HOUR10 0x05
+#define RS5C313_ADDR_WEEK 0x06
+#define RS5C313_ADDR_INTINTVREG 0x07
+#define RS5C313_ADDR_DAY 0x08
+#define RS5C313_ADDR_DAY10 0x09
+#define RS5C313_ADDR_MON 0x0A
+#define RS5C313_ADDR_MON10 0x0B
+#define RS5C313_ADDR_YEAR 0x0C
+#define RS5C313_ADDR_YEAR10 0x0D
+#define RS5C313_ADDR_CNTREG 0x0E
+#define RS5C313_ADDR_TESTREG 0x0F
+
+/* RICOH RS5C313 control register */
+#define RS5C313_CNTREG_ADJ_BSY 0x01
+#define RS5C313_CNTREG_WTEN_XSTP 0x02
+#define RS5C313_CNTREG_12_24 0x04
+#define RS5C313_CNTREG_CTFG 0x08
+
+/* RICOH RS5C313 test register */
+#define RS5C313_TESTREG_TEST 0x01
+
+/* RICOH RS5C313 control bit */
+#define RS5C313_CNTBIT_READ 0x40
+#define RS5C313_CNTBIT_AD 0x20
+#define RS5C313_CNTBIT_DT 0x10
+
+static unsigned char rs5c313_read_reg(unsigned char addr)
+{
+
+ rs5c313_write_data(addr | RS5C313_CNTBIT_READ | RS5C313_CNTBIT_AD);
+ return rs5c313_read_data();
+}
+
+static void rs5c313_write_reg(unsigned char addr, unsigned char data)
+{
+ data &= 0x0f;
+ rs5c313_write_data(addr | RS5C313_CNTBIT_AD);
+ rs5c313_write_data(data | RS5C313_CNTBIT_DT);
+ return;
+}
+
+static inline unsigned char rs5c313_read_cntreg(unsigned char addr)
+{
+ return rs5c313_read_reg(RS5C313_ADDR_CNTREG);
+}
+
+static inline void rs5c313_write_cntreg(unsigned char data)
+{
+ rs5c313_write_reg(RS5C313_ADDR_CNTREG, data);
+}
+
+static inline void rs5c313_write_intintvreg(unsigned char data)
+{
+ rs5c313_write_reg(RS5C313_ADDR_INTINTVREG, data);
+}
+
+static int rs5c313_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ int data;
+
+ while (1) {
+ RS5C313_CEENABLE; /* CE:H */
+
+ /* Initialize control reg. 24 hour */
+ rs5c313_write_cntreg(0x04);
+
+ if (!(rs5c313_read_cntreg() & RS5C313_CNTREG_ADJ_BSY))
+ break;
+
+ RS5C313_CEDISABLE;
+ ndelay(700); /* CE:L */
+
+ }
+
+ data = rs5c313_read_reg(RS5C313_ADDR_SEC);
+ data |= (rs5c313_read_reg(RS5C313_ADDR_SEC10) << 4);
+ tm->tm_sec = BCD2BIN(data);
+
+ data = rs5c313_read_reg(RS5C313_ADDR_MIN);
+ data |= (rs5c313_read_reg(RS5C313_ADDR_MIN10) << 4);
+ tm->tm_min = BCD2BIN(data);
+
+ data = rs5c313_read_reg(RS5C313_ADDR_HOUR);
+ data |= (rs5c313_read_reg(RS5C313_ADDR_HOUR10) << 4);
+ tm->tm_hour = BCD2BIN(data);
+
+ data = rs5c313_read_reg(RS5C313_ADDR_DAY);
+ data |= (rs5c313_read_reg(RS5C313_ADDR_DAY10) << 4);
+ tm->tm_mday = BCD2BIN(data);
+
+ data = rs5c313_read_reg(RS5C313_ADDR_MON);
+ data |= (rs5c313_read_reg(RS5C313_ADDR_MON10) << 4);
+ tm->tm_mon = BCD2BIN(data) - 1;
+
+ data = rs5c313_read_reg(RS5C313_ADDR_YEAR);
+ data |= (rs5c313_read_reg(RS5C313_ADDR_YEAR10) << 4);
+ tm->tm_year = BCD2BIN(data);
+
+ if (tm->tm_year < 70)
+ tm->tm_year += 100;
+
+ data = rs5c313_read_reg(RS5C313_ADDR_WEEK);
+ tm->tm_wday = BCD2BIN(data);
+
+ RS5C313_CEDISABLE;
+ ndelay(700); /* CE:L */
+
+ return 0;
+}
+
+static int rs5c313_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+ int data;
+
+ /* busy check. */
+ while (1) {
+ RS5C313_CEENABLE; /* CE:H */
+
+ /* Initiatlize control reg. 24 hour */
+ rs5c313_write_cntreg(0x04);
+
+ if (!(rs5c313_read_cntreg() & RS5C313_CNTREG_ADJ_BSY))
+ break;
+ RS5C313_MISCOP;
+ RS5C313_CEDISABLE;
+ ndelay(700); /* CE:L */
+ }
+
+ data = BIN2BCD(tm->tm_sec);
+ rs5c313_write_reg(RS5C313_ADDR_SEC, data);
+ rs5c313_write_reg(RS5C313_ADDR_SEC10, (data >> 4));
+
+ data = BIN2BCD(tm->tm_min);
+ rs5c313_write_reg(RS5C313_ADDR_MIN, data );
+ rs5c313_write_reg(RS5C313_ADDR_MIN10, (data >> 4));
+
+ data = BIN2BCD(tm->tm_hour);
+ rs5c313_write_reg(RS5C313_ADDR_HOUR, data);
+ rs5c313_write_reg(RS5C313_ADDR_HOUR10, (data >> 4));
+
+ data = BIN2BCD(tm->tm_mday);
+ rs5c313_write_reg(RS5C313_ADDR_DAY, data);
+ rs5c313_write_reg(RS5C313_ADDR_DAY10, (data>> 4));
+
+ data = BIN2BCD(tm->tm_mon + 1);
+ rs5c313_write_reg(RS5C313_ADDR_MON, data);
+ rs5c313_write_reg(RS5C313_ADDR_MON10, (data >> 4));
+
+ data = BIN2BCD(tm->tm_year % 100);
+ rs5c313_write_reg(RS5C313_ADDR_YEAR, data);
+ rs5c313_write_reg(RS5C313_ADDR_YEAR10, (data >> 4));
+
+ data = BIN2BCD(tm->tm_wday);
+ rs5c313_write_reg(RS5C313_ADDR_WEEK, data);
+
+ RS5C313_CEDISABLE; /* CE:H */
+ ndelay(700);
+
+ return 0;
+}
+
+static void rs5c313_check_xstp_bit(void)
+{
+ struct rtc_time tm;
+
+ RS5C313_CEENABLE; /* CE:H */
+ if (rs5c313_read_cntreg() & RS5C313_CNTREG_WTEN_XSTP) {
+ /* INT interval reg. OFF */
+ rs5c313_write_intintvreg(0x00);
+ /* Initialize control reg. 24 hour & adjust */
+ rs5c313_write_cntreg(0x07);
+
+ /* busy check. */
+ while (rs5c313_read_cntreg() & RS5C313_CNTREG_ADJ_BSY)
+ RS5C313_MISCOP;
+
+ memset(&tm, 0, sizeof(struct rtc_time));
+ tm.tm_mday = 1;
+ tm.tm_mon = 1;
+
+ rs5c313_rtc_set_time(NULL, &tm);
+ printk(KERN_ERR "RICHO RS5C313: invalid value, resetting to "
+ "1 Jan 2000\n");
+ }
+ RS5C313_CEDISABLE;
+ ndelay(700); /* CE:L */
+}
+
+static const struct rtc_class_ops rs5c313_rtc_ops = {
+ .read_time = rs5c313_rtc_read_time,
+ .set_time = rs5c313_rtc_set_time,
+};
+
+static int rs5c313_rtc_probe(struct platform_device *pdev)
+{
+ struct rtc_device *rtc = rtc_device_register("rs5c313", &pdev->dev,
+ &rs5c313_rtc_ops, THIS_MODULE);
+
+ if (IS_ERR(rtc))
+ return PTR_ERR(rtc);
+
+ platform_set_drvdata(pdev, rtc);
+
+ return err;
+}
+
+static int __devexit rs5c313_rtc_remove(struct platform_device *pdev)
+{
+ struct rtc_device *rtc = platform_get_drvdata( pdev );
+
+ rtc_device_unregister(rtc);
+
+ return 0;
+}
+
+static struct platform_driver rs5c313_rtc_platform_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = rs5c313_rtc_probe,
+ .remove = __devexit_p( rs5c313_rtc_remove ),
+};
+
+static int __init rs5c313_rtc_init(void)
+{
+ int err;
+
+ err = platform_driver_register(&rs5c313_rtc_platform_driver);
+ if (err)
+ return err;
+
+ rs5c313_init_port();
+ rs5c313_check_xstp_bit();
+
+ return 0;
+}
+
+static void __exit rs5c313_rtc_exit(void)
+{
+ platform_driver_unregister( &rs5c313_rtc_platform_driver );
+}
+
+module_init(rs5c313_rtc_init);
+module_exit(rs5c313_rtc_exit);
+
+MODULE_VERSION(DRV_VERSION);
+MODULE_AUTHOR("kogiidena , Nobuhiro Iwamatsu <iwamatsu@nigauri.org>");
+MODULE_DESCRIPTION("Ricoh RS5C313 RTC device driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index 9a79a24..54b6130 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -50,7 +50,7 @@
{
struct rtc_device *rdev = id;
- rtc_update_irq(&rdev->class_dev, 1, RTC_AF | RTC_IRQF);
+ rtc_update_irq(rdev, 1, RTC_AF | RTC_IRQF);
return IRQ_HANDLED;
}
@@ -58,7 +58,7 @@
{
struct rtc_device *rdev = id;
- rtc_update_irq(&rdev->class_dev, tick_count++, RTC_PF | RTC_IRQF);
+ rtc_update_irq(rdev, tick_count++, RTC_PF | RTC_IRQF);
return IRQ_HANDLED;
}
@@ -548,37 +548,15 @@
static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state)
{
- struct rtc_time tm;
- struct timespec time;
-
- time.tv_nsec = 0;
-
/* save TICNT for anyone using periodic interrupts */
-
ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT);
-
- /* calculate time delta for suspend */
-
- s3c_rtc_gettime(&pdev->dev, &tm);
- rtc_tm_to_time(&tm, &time.tv_sec);
- save_time_delta(&s3c_rtc_delta, &time);
s3c_rtc_enable(pdev, 0);
-
return 0;
}
static int s3c_rtc_resume(struct platform_device *pdev)
{
- struct rtc_time tm;
- struct timespec time;
-
- time.tv_nsec = 0;
-
s3c_rtc_enable(pdev, 1);
- s3c_rtc_gettime(&pdev->dev, &tm);
- rtc_tm_to_time(&tm, &time.tv_sec);
- restore_time_delta(&s3c_rtc_delta, &time);
-
writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT);
return 0;
}
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c
index 677bae8..0918b78 100644
--- a/drivers/rtc/rtc-sa1100.c
+++ b/drivers/rtc/rtc-sa1100.c
@@ -93,7 +93,7 @@
if (rtsr & RTSR_HZ)
events |= RTC_UF | RTC_IRQF;
- rtc_update_irq(&rtc->class_dev, 1, events);
+ rtc_update_irq(rtc, 1, events);
if (rtsr & RTSR_AL && rtc_periodic_alarm(&rtc_alarm))
rtc_update_alarm(&rtc_alarm);
@@ -119,7 +119,7 @@
*/
OSSR = OSSR_M1; /* clear match on timer1 */
- rtc_update_irq(&rtc->class_dev, rtc_timer1_count, RTC_PF | RTC_IRQF);
+ rtc_update_irq(rtc, rtc_timer1_count, RTC_PF | RTC_IRQF);
if (rtc_timer1_count == 1)
rtc_timer1_count = (rtc_freq * ((1<<30)/(TIMER_FREQ>>2)));
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c
index 198b9f2..6abf481 100644
--- a/drivers/rtc/rtc-sh.c
+++ b/drivers/rtc/rtc-sh.c
@@ -104,7 +104,7 @@
writeb(tmp, rtc->regbase + RCR1);
- rtc_update_irq(&rtc->rtc_dev->class_dev, 1, events);
+ rtc_update_irq(&rtc->rtc_dev, 1, events);
spin_unlock(&rtc->lock);
@@ -139,7 +139,7 @@
rtc->rearm_aie = 1;
- rtc_update_irq(&rtc->rtc_dev->class_dev, 1, events);
+ rtc_update_irq(&rtc->rtc_dev, 1, events);
}
spin_unlock(&rtc->lock);
@@ -153,7 +153,7 @@
spin_lock(&rtc->lock);
- rtc_update_irq(&rtc->rtc_dev->class_dev, 1, RTC_PF | RTC_IRQF);
+ rtc_update_irq(&rtc->rtc_dev, 1, RTC_PF | RTC_IRQF);
spin_unlock(&rtc->lock);
diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c
index 899ab8c..69df94b 100644
--- a/drivers/rtc/rtc-sysfs.c
+++ b/drivers/rtc/rtc-sysfs.c
@@ -12,20 +12,26 @@
#include <linux/module.h>
#include <linux/rtc.h>
+#include "rtc-core.h"
+
+
/* device attributes */
-static ssize_t rtc_sysfs_show_name(struct class_device *dev, char *buf)
+static ssize_t
+rtc_sysfs_show_name(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
return sprintf(buf, "%s\n", to_rtc_device(dev)->name);
}
-static CLASS_DEVICE_ATTR(name, S_IRUGO, rtc_sysfs_show_name, NULL);
-static ssize_t rtc_sysfs_show_date(struct class_device *dev, char *buf)
+static ssize_t
+rtc_sysfs_show_date(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
ssize_t retval;
struct rtc_time tm;
- retval = rtc_read_time(dev, &tm);
+ retval = rtc_read_time(to_rtc_device(dev), &tm);
if (retval == 0) {
retval = sprintf(buf, "%04d-%02d-%02d\n",
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
@@ -33,14 +39,15 @@
return retval;
}
-static CLASS_DEVICE_ATTR(date, S_IRUGO, rtc_sysfs_show_date, NULL);
-static ssize_t rtc_sysfs_show_time(struct class_device *dev, char *buf)
+static ssize_t
+rtc_sysfs_show_time(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
ssize_t retval;
struct rtc_time tm;
- retval = rtc_read_time(dev, &tm);
+ retval = rtc_read_time(to_rtc_device(dev), &tm);
if (retval == 0) {
retval = sprintf(buf, "%02d:%02d:%02d\n",
tm.tm_hour, tm.tm_min, tm.tm_sec);
@@ -48,14 +55,15 @@
return retval;
}
-static CLASS_DEVICE_ATTR(time, S_IRUGO, rtc_sysfs_show_time, NULL);
-static ssize_t rtc_sysfs_show_since_epoch(struct class_device *dev, char *buf)
+static ssize_t
+rtc_sysfs_show_since_epoch(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
ssize_t retval;
struct rtc_time tm;
- retval = rtc_read_time(dev, &tm);
+ retval = rtc_read_time(to_rtc_device(dev), &tm);
if (retval == 0) {
unsigned long time;
rtc_tm_to_time(&tm, &time);
@@ -64,23 +72,18 @@
return retval;
}
-static CLASS_DEVICE_ATTR(since_epoch, S_IRUGO, rtc_sysfs_show_since_epoch, NULL);
-static struct attribute *rtc_attrs[] = {
- &class_device_attr_name.attr,
- &class_device_attr_date.attr,
- &class_device_attr_time.attr,
- &class_device_attr_since_epoch.attr,
- NULL,
+static struct device_attribute rtc_attrs[] = {
+ __ATTR(name, S_IRUGO, rtc_sysfs_show_name, NULL),
+ __ATTR(date, S_IRUGO, rtc_sysfs_show_date, NULL),
+ __ATTR(time, S_IRUGO, rtc_sysfs_show_time, NULL),
+ __ATTR(since_epoch, S_IRUGO, rtc_sysfs_show_since_epoch, NULL),
+ { },
};
-static struct attribute_group rtc_attr_group = {
- .attrs = rtc_attrs,
-};
-
-
static ssize_t
-rtc_sysfs_show_wakealarm(struct class_device *dev, char *buf)
+rtc_sysfs_show_wakealarm(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
ssize_t retval;
unsigned long alarm;
@@ -94,7 +97,7 @@
* REVISIT maybe we should require RTC implementations to
* disable the RTC alarm after it triggers, for uniformity.
*/
- retval = rtc_read_alarm(dev, &alm);
+ retval = rtc_read_alarm(to_rtc_device(dev), &alm);
if (retval == 0 && alm.enabled) {
rtc_tm_to_time(&alm.time, &alarm);
retval = sprintf(buf, "%lu\n", alarm);
@@ -104,16 +107,18 @@
}
static ssize_t
-rtc_sysfs_set_wakealarm(struct class_device *dev, const char *buf, size_t n)
+rtc_sysfs_set_wakealarm(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t n)
{
ssize_t retval;
unsigned long now, alarm;
struct rtc_wkalrm alm;
+ struct rtc_device *rtc = to_rtc_device(dev);
/* Only request alarms that trigger in the future. Disable them
* by writing another time, e.g. 0 meaning Jan 1 1970 UTC.
*/
- retval = rtc_read_time(dev, &alm.time);
+ retval = rtc_read_time(rtc, &alm.time);
if (retval < 0)
return retval;
rtc_tm_to_time(&alm.time, &now);
@@ -124,7 +129,7 @@
* entirely prevent that here, without even the minimal
* locking from the /dev/rtcN api.
*/
- retval = rtc_read_alarm(dev, &alm);
+ retval = rtc_read_alarm(rtc, &alm);
if (retval < 0)
return retval;
if (alm.enabled)
@@ -141,10 +146,10 @@
}
rtc_time_to_tm(alarm, &alm.time);
- retval = rtc_set_alarm(dev, &alm);
+ retval = rtc_set_alarm(rtc, &alm);
return (retval < 0) ? retval : n;
}
-static const CLASS_DEVICE_ATTR(wakealarm, S_IRUGO | S_IWUSR,
+static DEVICE_ATTR(wakealarm, S_IRUGO | S_IWUSR,
rtc_sysfs_show_wakealarm, rtc_sysfs_set_wakealarm);
@@ -153,71 +158,37 @@
* suspend-to-disk. So: no attribute unless that side effect is possible.
* (Userspace may disable that mechanism later.)
*/
-static inline int rtc_does_wakealarm(struct class_device *class_dev)
+static inline int rtc_does_wakealarm(struct rtc_device *rtc)
{
- struct rtc_device *rtc;
-
- if (!device_can_wakeup(class_dev->dev))
+ if (!device_can_wakeup(rtc->dev.parent))
return 0;
- rtc = to_rtc_device(class_dev);
return rtc->ops->set_alarm != NULL;
}
-static int rtc_sysfs_add_device(struct class_device *class_dev,
- struct class_interface *class_intf)
+void rtc_sysfs_add_device(struct rtc_device *rtc)
{
int err;
- dev_dbg(class_dev->dev, "rtc intf: sysfs\n");
+ /* not all RTCs support both alarms and wakeup */
+ if (!rtc_does_wakealarm(rtc))
+ return;
- err = sysfs_create_group(&class_dev->kobj, &rtc_attr_group);
+ err = device_create_file(&rtc->dev, &dev_attr_wakealarm);
if (err)
- dev_err(class_dev->dev, "failed to create %s\n",
- "sysfs attributes");
- else if (rtc_does_wakealarm(class_dev)) {
- /* not all RTCs support both alarms and wakeup */
- err = class_device_create_file(class_dev,
- &class_device_attr_wakealarm);
- if (err) {
- dev_err(class_dev->dev, "failed to create %s\n",
- "alarm attribute");
- sysfs_remove_group(&class_dev->kobj, &rtc_attr_group);
- }
- }
-
- return err;
+ dev_err(rtc->dev.parent, "failed to create "
+ "alarm attribute, %d",
+ err);
}
-static void rtc_sysfs_remove_device(struct class_device *class_dev,
- struct class_interface *class_intf)
+void rtc_sysfs_del_device(struct rtc_device *rtc)
{
- if (rtc_does_wakealarm(class_dev))
- class_device_remove_file(class_dev,
- &class_device_attr_wakealarm);
- sysfs_remove_group(&class_dev->kobj, &rtc_attr_group);
+ /* REVISIT did we add it successfully? */
+ if (rtc_does_wakealarm(rtc))
+ device_remove_file(&rtc->dev, &dev_attr_wakealarm);
}
-/* interface registration */
-
-static struct class_interface rtc_sysfs_interface = {
- .add = &rtc_sysfs_add_device,
- .remove = &rtc_sysfs_remove_device,
-};
-
-static int __init rtc_sysfs_init(void)
+void __init rtc_sysfs_init(struct class *rtc_class)
{
- return rtc_interface_register(&rtc_sysfs_interface);
+ rtc_class->dev_attrs = rtc_attrs;
}
-
-static void __exit rtc_sysfs_exit(void)
-{
- class_interface_unregister(&rtc_sysfs_interface);
-}
-
-subsys_initcall(rtc_sysfs_init);
-module_exit(rtc_sysfs_exit);
-
-MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
-MODULE_DESCRIPTION("RTC class sysfs interface");
-MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c
index f50a1b8..254c9fc 100644
--- a/drivers/rtc/rtc-test.c
+++ b/drivers/rtc/rtc-test.c
@@ -101,11 +101,11 @@
retval = count;
local_irq_disable();
if (strncmp(buf, "tick", 4) == 0)
- rtc_update_irq(&rtc->class_dev, 1, RTC_PF | RTC_IRQF);
+ rtc_update_irq(rtc, 1, RTC_PF | RTC_IRQF);
else if (strncmp(buf, "alarm", 5) == 0)
- rtc_update_irq(&rtc->class_dev, 1, RTC_AF | RTC_IRQF);
+ rtc_update_irq(rtc, 1, RTC_AF | RTC_IRQF);
else if (strncmp(buf, "update", 6) == 0)
- rtc_update_irq(&rtc->class_dev, 1, RTC_UF | RTC_IRQF);
+ rtc_update_irq(rtc, 1, RTC_UF | RTC_IRQF);
else
retval = -EINVAL;
local_irq_enable();
diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c
index e40322b..af7596e 100644
--- a/drivers/rtc/rtc-vr41xx.c
+++ b/drivers/rtc/rtc-vr41xx.c
@@ -97,6 +97,7 @@
static char rtc_name[] = "RTC";
static unsigned long periodic_frequency;
static unsigned long periodic_count;
+static unsigned int alarm_enabled;
struct resource rtc_resource[2] = {
{ .name = rtc_name,
@@ -188,6 +189,7 @@
low = rtc1_read(ECMPLREG);
mid = rtc1_read(ECMPMREG);
high = rtc1_read(ECMPHREG);
+ wkalrm->enabled = alarm_enabled;
spin_unlock_irq(&rtc_lock);
@@ -206,10 +208,18 @@
spin_lock_irq(&rtc_lock);
+ if (alarm_enabled)
+ disable_irq(ELAPSEDTIME_IRQ);
+
rtc1_write(ECMPLREG, (uint16_t)(alarm_sec << 15));
rtc1_write(ECMPMREG, (uint16_t)(alarm_sec >> 1));
rtc1_write(ECMPHREG, (uint16_t)(alarm_sec >> 17));
+ if (wkalrm->enabled)
+ enable_irq(ELAPSEDTIME_IRQ);
+
+ alarm_enabled = wkalrm->enabled;
+
spin_unlock_irq(&rtc_lock);
return 0;
@@ -221,10 +231,24 @@
switch (cmd) {
case RTC_AIE_ON:
- enable_irq(ELAPSEDTIME_IRQ);
+ spin_lock_irq(&rtc_lock);
+
+ if (!alarm_enabled) {
+ enable_irq(ELAPSEDTIME_IRQ);
+ alarm_enabled = 1;
+ }
+
+ spin_unlock_irq(&rtc_lock);
break;
case RTC_AIE_OFF:
- disable_irq(ELAPSEDTIME_IRQ);
+ spin_lock_irq(&rtc_lock);
+
+ if (alarm_enabled) {
+ disable_irq(ELAPSEDTIME_IRQ);
+ alarm_enabled = 0;
+ }
+
+ spin_unlock_irq(&rtc_lock);
break;
case RTC_PIE_ON:
enable_irq(RTCLONG1_IRQ);
@@ -275,7 +299,7 @@
rtc2_write(RTCINTREG, ELAPSEDTIME_INT);
- rtc_update_irq(&rtc->class_dev, 1, RTC_AF);
+ rtc_update_irq(rtc, 1, RTC_AF);
return IRQ_HANDLED;
}
@@ -291,7 +315,7 @@
rtc1_write(RTCL1LREG, count);
rtc1_write(RTCL1HREG, count >> 16);
- rtc_update_irq(&rtc->class_dev, 1, RTC_PF);
+ rtc_update_irq(rtc, 1, RTC_PF);
return IRQ_HANDLED;
}
diff --git a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c
index a39ee80..74b999d 100644
--- a/drivers/sbus/char/bpp.c
+++ b/drivers/sbus/char/bpp.c
@@ -15,7 +15,6 @@
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/sched.h>
-#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/timer.h>
#include <linux/ioport.h>
diff --git a/drivers/sbus/char/rtc.c b/drivers/sbus/char/rtc.c
index 94d1858..18d18f1 100644
--- a/drivers/sbus/char/rtc.c
+++ b/drivers/sbus/char/rtc.c
@@ -19,7 +19,6 @@
#include <linux/fcntl.h>
#include <linux/poll.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <asm/io.h>
#include <asm/mostek.h>
#include <asm/system.h>
diff --git a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c
index c3135e2..6afc7e5 100644
--- a/drivers/sbus/char/vfc_dev.c
+++ b/drivers/sbus/char/vfc_dev.c
@@ -20,7 +20,6 @@
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/fs.h>
-#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h
index 9218f29..ad9761b 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.h
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.h
@@ -47,7 +47,6 @@
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/pci.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/slab.h>
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h
index 85ae5d8..8fee7ed 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.h
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h
@@ -64,7 +64,6 @@
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/pci.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/slab.h>
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index f7b9dbd..fb6433a 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -55,7 +55,6 @@
#include <linux/sched.h>
#include <linux/reboot.h>
#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
#include <linux/dma-mapping.h>
#include <linux/timer.h>
diff --git a/drivers/scsi/ibmvscsi/ibmvstgt.c b/drivers/scsi/ibmvscsi/ibmvstgt.c
index 6d223dd..8ba7dd0 100644
--- a/drivers/scsi/ibmvscsi/ibmvstgt.c
+++ b/drivers/scsi/ibmvscsi/ibmvstgt.c
@@ -892,16 +892,16 @@
if (!rootdn)
return -ENOENT;
- model = get_property(rootdn, "model", NULL);
- id = get_property(rootdn, "system-id", NULL);
+ model = of_get_property(rootdn, "model", NULL);
+ id = of_get_property(rootdn, "system-id", NULL);
if (model && id)
snprintf(system_id, sizeof(system_id), "%s-%s", model, id);
- name = get_property(rootdn, "ibm,partition-name", NULL);
+ name = of_get_property(rootdn, "ibm,partition-name", NULL);
if (name)
strncpy(partition_name, name, sizeof(partition_name));
- num = get_property(rootdn, "ibm,partition-no", NULL);
+ num = of_get_property(rootdn, "ibm,partition-no", NULL);
if (num)
partition_number = *num;
diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c
index 0a533f3..d8700aa 100644
--- a/drivers/scsi/ibmvscsi/rpa_vscsi.c
+++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c
@@ -162,11 +162,11 @@
return;
}
- ppartition_name = get_property(rootdn, "ibm,partition-name", NULL);
+ ppartition_name = of_get_property(rootdn, "ibm,partition-name", NULL);
if (ppartition_name)
strncpy(partition_name, ppartition_name,
sizeof(partition_name));
- p_number_ptr = get_property(rootdn, "ibm,partition-no", NULL);
+ p_number_ptr = of_get_property(rootdn, "ibm,partition-no", NULL);
if (p_number_ptr)
partition_number = *p_number_ptr;
of_node_put(rootdn);
diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c
index 753d883..5806ede 100644
--- a/drivers/scsi/mac53c94.c
+++ b/drivers/scsi/mac53c94.c
@@ -471,7 +471,7 @@
goto out_free;
}
- clkprop = get_property(node, "clock-frequency", &proplen);
+ clkprop = of_get_property(node, "clock-frequency", &proplen);
if (clkprop == NULL || proplen != sizeof(int)) {
printk(KERN_ERR "%s: can't get clock frequency, "
"assuming 25MHz\n", node->full_name);
diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c
index 1fd3c75..cf3666d 100644
--- a/drivers/scsi/mesh.c
+++ b/drivers/scsi/mesh.c
@@ -1947,7 +1947,7 @@
ms->tgts[tgt].current_req = NULL;
}
- if ((cfp = get_property(mesh, "clock-frequency", NULL)))
+ if ((cfp = of_get_property(mesh, "clock-frequency", NULL)))
ms->clk_freq = *cfp;
else {
printk(KERN_INFO "mesh: assuming 50MHz clock frequency\n");
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 3e2930b..06229f2 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -36,7 +36,6 @@
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
-#include <linux/smp_lock.h>
#include <linux/vmalloc.h>
#include <linux/moduleparam.h>
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 570977c..0c691a6 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -41,7 +41,6 @@
#include <linux/fcntl.h>
#include <linux/init.h>
#include <linux/poll.h>
-#include <linux/smp_lock.h>
#include <linux/moduleparam.h>
#include <linux/cdev.h>
#include <linux/seq_file.h>
diff --git a/drivers/scsi/sni_53c710.c b/drivers/scsi/sni_53c710.c
index 6bc5051..a7dfb65 100644
--- a/drivers/scsi/sni_53c710.c
+++ b/drivers/scsi/sni_53c710.c
@@ -98,7 +98,7 @@
host->this_id = 7;
host->base = base;
host->irq = platform_get_irq(dev, 0);
- if(request_irq(host->irq, NCR_700_intr, SA_SHIRQ, "snirm710", host)) {
+ if(request_irq(host->irq, NCR_700_intr, IRQF_SHARED, "snirm710", host)) {
printk(KERN_ERR "snirm710: request_irq failed!\n");
goto out_put_host;
}
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index c9832d9..48e259a 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -994,7 +994,6 @@
* be frobbing the chips IRQ enable register to see if it exists.
*/
spin_lock_irqsave(&up->port.lock, flags);
-// save_flags(flags); cli();
up->capabilities = 0;
up->bugs = 0;
@@ -1151,7 +1150,6 @@
out:
spin_unlock_irqrestore(&up->port.lock, flags);
-// restore_flags(flags);
DEBUG_AUTOCONF("type=%s\n", uart_config[up->port.type].name);
}
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 924e9bd..e8efe93 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -73,17 +73,21 @@
depends on SERIAL_8250 && PCI
default SERIAL_8250
help
- This builds standard PCI serial support. You may be able to
- disable this feature if you only need legacy serial support.
- Saves about 9K.
+ Say Y here if you have PCI serial ports.
+
+ To compile this driver as a module, choose M here: the module
+ will be called 8250_pci.
config SERIAL_8250_PNP
tristate "8250/16550 PNP device support" if EMBEDDED
depends on SERIAL_8250 && PNP
default SERIAL_8250
help
- This builds standard PNP serial support. You may be able to
- disable this feature if you only need legacy serial support.
+ Say Y here if you have serial ports described by PNPBIOS or ACPI.
+ These are typically ports built into the system board.
+
+ To compile this driver as a module, choose M here: the module
+ will be called 8250_pnp.
config SERIAL_8250_HP300
tristate
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index 7a3b97f..f23972b 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -934,7 +934,7 @@
.irq = SMC1_IRQ,
.ops = &cpm_uart_pops,
.iotype = UPIO_MEM,
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SMC1].port.lock),
},
.flags = FLAG_SMC,
.tx_nrfifos = TX_NUM_FIFO,
@@ -948,7 +948,7 @@
.irq = SMC2_IRQ,
.ops = &cpm_uart_pops,
.iotype = UPIO_MEM,
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SMC2].port.lock),
},
.flags = FLAG_SMC,
.tx_nrfifos = TX_NUM_FIFO,
@@ -965,7 +965,7 @@
.irq = SCC1_IRQ,
.ops = &cpm_uart_pops,
.iotype = UPIO_MEM,
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC1].port.lock),
},
.tx_nrfifos = TX_NUM_FIFO,
.tx_fifosize = TX_BUF_SIZE,
@@ -979,7 +979,7 @@
.irq = SCC2_IRQ,
.ops = &cpm_uart_pops,
.iotype = UPIO_MEM,
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC2].port.lock),
},
.tx_nrfifos = TX_NUM_FIFO,
.tx_fifosize = TX_BUF_SIZE,
@@ -993,7 +993,7 @@
.irq = SCC3_IRQ,
.ops = &cpm_uart_pops,
.iotype = UPIO_MEM,
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC3].port.lock),
},
.tx_nrfifos = TX_NUM_FIFO,
.tx_fifosize = TX_BUF_SIZE,
@@ -1007,7 +1007,7 @@
.irq = SCC4_IRQ,
.ops = &cpm_uart_pops,
.iotype = UPIO_MEM,
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC4].port.lock),
},
.tx_nrfifos = TX_NUM_FIFO,
.tx_fifosize = TX_BUF_SIZE,
diff --git a/drivers/serial/icom.c b/drivers/serial/icom.c
index 246c557..6202995 100644
--- a/drivers/serial/icom.c
+++ b/drivers/serial/icom.c
@@ -47,7 +47,6 @@
#include <linux/pci.h>
#include <linux/vmalloc.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/kobject.h>
#include <linux/firmware.h>
diff --git a/drivers/serial/jsm/jsm_neo.c b/drivers/serial/jsm/jsm_neo.c
index 8be8da3..b2d6f5b 100644
--- a/drivers/serial/jsm/jsm_neo.c
+++ b/drivers/serial/jsm/jsm_neo.c
@@ -581,8 +581,13 @@
return;
/* Scrub off lower bits. They signify delta's, which I don't care about */
- msignals &= 0xf0;
+ /* Keep DDCD and DDSR though */
+ msignals &= 0xf8;
+ if (msignals & UART_MSR_DDCD)
+ uart_handle_dcd_change(&ch->uart_port, msignals & UART_MSR_DCD);
+ if (msignals & UART_MSR_DDSR)
+ uart_handle_cts_change(&ch->uart_port, msignals & UART_MSR_CTS);
if (msignals & UART_MSR_DCD)
ch->ch_mistat |= UART_MSR_DCD;
else
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c
index be22bbd..281f23a 100644
--- a/drivers/serial/jsm/jsm_tty.c
+++ b/drivers/serial/jsm/jsm_tty.c
@@ -448,6 +448,7 @@
continue;
brd->channels[i]->uart_port.irq = brd->irq;
+ brd->channels[i]->uart_port.uartclk = 14745600;
brd->channels[i]->uart_port.type = PORT_JSM;
brd->channels[i]->uart_port.iotype = UPIO_MEM;
brd->channels[i]->uart_port.membase = brd->re_map_membase;
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 8d24cd5..35f8b86 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -257,9 +257,10 @@
{
struct mpc52xx_psc __iomem *psc = PSC(port);
- /* Shut down the port, interrupt and all */
+ /* Shut down the port. Leave TX active if on a console port */
out_8(&psc->command,MPC52xx_PSC_RST_RX);
- out_8(&psc->command,MPC52xx_PSC_RST_TX);
+ if (!uart_console(port))
+ out_8(&psc->command,MPC52xx_PSC_RST_TX);
port->read_status_mask = 0;
out_be16(&psc->mpc52xx_psc_imr,port->read_status_mask);
@@ -1069,7 +1070,7 @@
continue;
/* Is a particular device number requested? */
- devno = get_property(np, "port-number", NULL);
+ devno = of_get_property(np, "port-number", NULL);
mpc52xx_uart_of_assign(of_node_get(np), devno ? *devno : -1);
}
diff --git a/drivers/serial/of_serial.c b/drivers/serial/of_serial.c
index 336d0f4..7ffdaea 100644
--- a/drivers/serial/of_serial.c
+++ b/drivers/serial/of_serial.c
@@ -29,8 +29,8 @@
int ret;
memset(port, 0, sizeof *port);
- spd = get_property(np, "current-speed", NULL);
- clk = get_property(np, "clock-frequency", NULL);
+ spd = of_get_property(np, "current-speed", NULL);
+ clk = of_get_property(np, "clock-frequency", NULL);
if (!clk) {
dev_warn(&ofdev->dev, "no clock-frequency property set\n");
return -ENODEV;
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c
index be8d757..0fa9f67 100644
--- a/drivers/serial/pmac_zilog.c
+++ b/drivers/serial/pmac_zilog.c
@@ -1450,14 +1450,14 @@
/*
* Detect port type
*/
- if (device_is_compatible(np, "cobalt"))
+ if (of_device_is_compatible(np, "cobalt"))
uap->flags |= PMACZILOG_FLAG_IS_INTMODEM;
- conn = get_property(np, "AAPL,connector", &len);
+ conn = of_get_property(np, "AAPL,connector", &len);
if (conn && (strcmp(conn, "infrared") == 0))
uap->flags |= PMACZILOG_FLAG_IS_IRDA;
uap->port_type = PMAC_SCC_ASYNC;
/* 1999 Powerbook G3 has slot-names property instead */
- slots = get_property(np, "slot-names", &len);
+ slots = of_get_property(np, "slot-names", &len);
if (slots && slots->count > 0) {
if (strcmp(slots->name, "IrDA") == 0)
uap->flags |= PMACZILOG_FLAG_IS_IRDA;
@@ -1471,7 +1471,7 @@
of_find_node_by_name(NULL, "i2c-modem");
if (i2c_modem) {
const char* mid =
- get_property(i2c_modem, "modem-id", NULL);
+ of_get_property(i2c_modem, "modem-id", NULL);
if (mid) switch(*mid) {
case 0x04 :
case 0x05 :
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index 3ba9208..10bc020 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -957,7 +957,7 @@
static struct s3c24xx_uart_port s3c24xx_serial_ports[NR_PORTS] = {
[0] = {
.port = {
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[0].port.lock),
.iotype = UPIO_MEM,
.irq = IRQ_S3CUART_RX0,
.uartclk = 0,
@@ -969,7 +969,7 @@
},
[1] = {
.port = {
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[1].port.lock),
.iotype = UPIO_MEM,
.irq = IRQ_S3CUART_RX1,
.uartclk = 0,
@@ -983,7 +983,7 @@
[2] = {
.port = {
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[2].port.lock),
.iotype = UPIO_MEM,
.irq = IRQ_S3CUART_RX2,
.uartclk = 0,
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index 509ace7..1deb576 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -15,31 +15,6 @@
* published by the Free Software Foundation.
*
* Serial driver for TX3927/TX4927/TX4925/TX4938 internal SIO controller
- *
- * Revision History:
- * 0.30 Initial revision. (Renamed from serial_txx927.c)
- * 0.31 Use save_flags instead of local_irq_save.
- * 0.32 Support SCLK.
- * 0.33 Switch TXX9_TTY_NAME by CONFIG_SERIAL_TXX9_STDSERIAL.
- * Support TIOCSERGETLSR.
- * 0.34 Support slow baudrate.
- * 0.40 Merge codes from mainstream kernel (2.4.22).
- * 0.41 Fix console checking in rs_shutdown_port().
- * Disable flow-control in serial_console_write().
- * 0.42 Fix minor compiler warning.
- * 1.00 Kernel 2.6. Converted to new serial core (based on 8250.c).
- * 1.01 Set fifosize to make tx_empry called properly.
- * Use standard uart_get_divisor.
- * 1.02 Cleanup. (import 8250.c changes)
- * 1.03 Fix low-latency mode. (import 8250.c changes)
- * 1.04 Remove usage of deprecated functions, cleanup.
- * 1.05 More strict check in verify_port. Cleanup.
- * 1.06 Do not insert a char caused previous overrun.
- * Fix some spin_locks.
- * Do not call uart_add_one_port for absent ports.
- * 1.07 Use CONFIG_SERIAL_TXX9_NR_UARTS. Cleanup.
- * 1.08 Use platform_device.
- * Fix and cleanup suspend/resume/initialization codes.
*/
#if defined(CONFIG_SERIAL_TXX9_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
@@ -62,7 +37,7 @@
#include <asm/io.h>
-static char *serial_version = "1.08";
+static char *serial_version = "1.09";
static char *serial_name = "TX39/49 Serial driver";
#define PASS_LIMIT 256
@@ -70,13 +45,14 @@
#if !defined(CONFIG_SERIAL_TXX9_STDSERIAL)
/* "ttyS" is used for standard serial driver */
#define TXX9_TTY_NAME "ttyTX"
-#define TXX9_TTY_MINOR_START (64 + 64) /* ttyTX0(128), ttyTX1(129) */
+#define TXX9_TTY_MINOR_START 196
+#define TXX9_TTY_MAJOR 204
#else
/* acts like standard serial driver */
#define TXX9_TTY_NAME "ttyS"
#define TXX9_TTY_MINOR_START 64
-#endif
#define TXX9_TTY_MAJOR TTY_MAJOR
+#endif
/* flag aliases */
#define UPF_TXX9_HAVE_CTS_LINE UPF_BUGGY_UART
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 4a012d9a..07c587e 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -64,6 +64,17 @@
help
This is the SPI controller master driver for Blackfin 5xx processor.
+config SPI_AU1550
+ tristate "Au1550/Au12x0 SPI Controller"
+ depends on SPI_MASTER && (SOC_AU1550 || SOC_AU1200) && EXPERIMENTAL
+ select SPI_BITBANG
+ help
+ If you say yes to this option, support will be included for the
+ Au1550 SPI controller (may also work with Au1200,Au1210,Au1250).
+
+ This driver can also be built as a module. If so, the module
+ will be called au1550_spi.
+
config SPI_BITBANG
tristate "Bitbanging SPI master"
depends on SPI_MASTER && EXPERIMENTAL
@@ -159,6 +170,15 @@
This driver can also be built as a module. If so, the module
will be called at25.
+config SPI_SPIDEV
+ tristate "User mode SPI device driver support"
+ depends on SPI_MASTER && EXPERIMENTAL
+ help
+ This supports user mode SPI protocol drivers.
+
+ Note that this application programming interface is EXPERIMENTAL
+ and hence SUBJECT TO CHANGE WITHOUT NOTICE while it stabilizes.
+
#
# Add new SPI protocol masters in alphabetical order above this line
#
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index a95ade8..624b636 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -14,6 +14,7 @@
obj-$(CONFIG_SPI_ATMEL) += atmel_spi.o
obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx.o
obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o
+obj-$(CONFIG_SPI_AU1550) += au1550_spi.o
obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o
obj-$(CONFIG_SPI_IMX) += spi_imx.o
obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o
@@ -25,6 +26,7 @@
# SPI protocol drivers (device/link on bus)
obj-$(CONFIG_SPI_AT25) += at25.o
+obj-$(CONFIG_SPI_SPIDEV) += spidev.o
# ... add above this line ...
# SPI slave controller drivers (upstream link)
diff --git a/drivers/spi/au1550_spi.c b/drivers/spi/au1550_spi.c
new file mode 100644
index 0000000..ae2b1af
--- /dev/null
+++ b/drivers/spi/au1550_spi.c
@@ -0,0 +1,974 @@
+/*
+ * au1550_spi.c - au1550 psc spi controller driver
+ * may work also with au1200, au1210, au1250
+ * will not work on au1000, au1100 and au1500 (no full spi controller there)
+ *
+ * Copyright (c) 2006 ATRON electronic GmbH
+ * Author: Jan Nikitenko <jan.nikitenko@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_bitbang.h>
+#include <linux/dma-mapping.h>
+#include <linux/completion.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-au1x00/au1xxx_psc.h>
+#include <asm/mach-au1x00/au1xxx_dbdma.h>
+
+#include <asm/mach-au1x00/au1550_spi.h>
+
+static unsigned usedma = 1;
+module_param(usedma, uint, 0644);
+
+/*
+#define AU1550_SPI_DEBUG_LOOPBACK
+*/
+
+
+#define AU1550_SPI_DBDMA_DESCRIPTORS 1
+#define AU1550_SPI_DMA_RXTMP_MINSIZE 2048U
+
+struct au1550_spi {
+ struct spi_bitbang bitbang;
+
+ volatile psc_spi_t __iomem *regs;
+ int irq;
+ unsigned freq_max;
+ unsigned freq_min;
+
+ unsigned len;
+ unsigned tx_count;
+ unsigned rx_count;
+ const u8 *tx;
+ u8 *rx;
+
+ void (*rx_word)(struct au1550_spi *hw);
+ void (*tx_word)(struct au1550_spi *hw);
+ int (*txrx_bufs)(struct spi_device *spi, struct spi_transfer *t);
+ irqreturn_t (*irq_callback)(struct au1550_spi *hw);
+
+ struct completion master_done;
+
+ unsigned usedma;
+ u32 dma_tx_id;
+ u32 dma_rx_id;
+ u32 dma_tx_ch;
+ u32 dma_rx_ch;
+
+ u8 *dma_rx_tmpbuf;
+ unsigned dma_rx_tmpbuf_size;
+ u32 dma_rx_tmpbuf_addr;
+
+ struct spi_master *master;
+ struct device *dev;
+ struct au1550_spi_info *pdata;
+};
+
+
+/* we use an 8-bit memory device for dma transfers to/from spi fifo */
+static dbdev_tab_t au1550_spi_mem_dbdev =
+{
+ .dev_id = DBDMA_MEM_CHAN,
+ .dev_flags = DEV_FLAGS_ANYUSE|DEV_FLAGS_SYNC,
+ .dev_tsize = 0,
+ .dev_devwidth = 8,
+ .dev_physaddr = 0x00000000,
+ .dev_intlevel = 0,
+ .dev_intpolarity = 0
+};
+
+static void au1550_spi_bits_handlers_set(struct au1550_spi *hw, int bpw);
+
+
+/**
+ * compute BRG and DIV bits to setup spi clock based on main input clock rate
+ * that was specified in platform data structure
+ * according to au1550 datasheet:
+ * psc_tempclk = psc_mainclk / (2 << DIV)
+ * spiclk = psc_tempclk / (2 * (BRG + 1))
+ * BRG valid range is 4..63
+ * DIV valid range is 0..3
+ */
+static u32 au1550_spi_baudcfg(struct au1550_spi *hw, unsigned speed_hz)
+{
+ u32 mainclk_hz = hw->pdata->mainclk_hz;
+ u32 div, brg;
+
+ for (div = 0; div < 4; div++) {
+ brg = mainclk_hz / speed_hz / (4 << div);
+ /* now we have BRG+1 in brg, so count with that */
+ if (brg < (4 + 1)) {
+ brg = (4 + 1); /* speed_hz too big */
+ break; /* set lowest brg (div is == 0) */
+ }
+ if (brg <= (63 + 1))
+ break; /* we have valid brg and div */
+ }
+ if (div == 4) {
+ div = 3; /* speed_hz too small */
+ brg = (63 + 1); /* set highest brg and div */
+ }
+ brg--;
+ return PSC_SPICFG_SET_BAUD(brg) | PSC_SPICFG_SET_DIV(div);
+}
+
+static inline void au1550_spi_mask_ack_all(struct au1550_spi *hw)
+{
+ hw->regs->psc_spimsk =
+ PSC_SPIMSK_MM | PSC_SPIMSK_RR | PSC_SPIMSK_RO
+ | PSC_SPIMSK_RU | PSC_SPIMSK_TR | PSC_SPIMSK_TO
+ | PSC_SPIMSK_TU | PSC_SPIMSK_SD | PSC_SPIMSK_MD;
+ au_sync();
+
+ hw->regs->psc_spievent =
+ PSC_SPIEVNT_MM | PSC_SPIEVNT_RR | PSC_SPIEVNT_RO
+ | PSC_SPIEVNT_RU | PSC_SPIEVNT_TR | PSC_SPIEVNT_TO
+ | PSC_SPIEVNT_TU | PSC_SPIEVNT_SD | PSC_SPIEVNT_MD;
+ au_sync();
+}
+
+static void au1550_spi_reset_fifos(struct au1550_spi *hw)
+{
+ u32 pcr;
+
+ hw->regs->psc_spipcr = PSC_SPIPCR_RC | PSC_SPIPCR_TC;
+ au_sync();
+ do {
+ pcr = hw->regs->psc_spipcr;
+ au_sync();
+ } while (pcr != 0);
+}
+
+/*
+ * dma transfers are used for the most common spi word size of 8-bits
+ * we cannot easily change already set up dma channels' width, so if we wanted
+ * dma support for more than 8-bit words (up to 24 bits), we would need to
+ * setup dma channels from scratch on each spi transfer, based on bits_per_word
+ * instead we have pre set up 8 bit dma channels supporting spi 4 to 8 bits
+ * transfers, and 9 to 24 bits spi transfers will be done in pio irq based mode
+ * callbacks to handle dma or pio are set up in au1550_spi_bits_handlers_set()
+ */
+static void au1550_spi_chipsel(struct spi_device *spi, int value)
+{
+ struct au1550_spi *hw = spi_master_get_devdata(spi->master);
+ unsigned cspol = spi->mode & SPI_CS_HIGH ? 1 : 0;
+ u32 cfg, stat;
+
+ switch (value) {
+ case BITBANG_CS_INACTIVE:
+ if (hw->pdata->deactivate_cs)
+ hw->pdata->deactivate_cs(hw->pdata, spi->chip_select,
+ cspol);
+ break;
+
+ case BITBANG_CS_ACTIVE:
+ au1550_spi_bits_handlers_set(hw, spi->bits_per_word);
+
+ cfg = hw->regs->psc_spicfg;
+ au_sync();
+ hw->regs->psc_spicfg = cfg & ~PSC_SPICFG_DE_ENABLE;
+ au_sync();
+
+ if (spi->mode & SPI_CPOL)
+ cfg |= PSC_SPICFG_BI;
+ else
+ cfg &= ~PSC_SPICFG_BI;
+ if (spi->mode & SPI_CPHA)
+ cfg &= ~PSC_SPICFG_CDE;
+ else
+ cfg |= PSC_SPICFG_CDE;
+
+ if (spi->mode & SPI_LSB_FIRST)
+ cfg |= PSC_SPICFG_MLF;
+ else
+ cfg &= ~PSC_SPICFG_MLF;
+
+ if (hw->usedma && spi->bits_per_word <= 8)
+ cfg &= ~PSC_SPICFG_DD_DISABLE;
+ else
+ cfg |= PSC_SPICFG_DD_DISABLE;
+ cfg = PSC_SPICFG_CLR_LEN(cfg);
+ cfg |= PSC_SPICFG_SET_LEN(spi->bits_per_word);
+
+ cfg = PSC_SPICFG_CLR_BAUD(cfg);
+ cfg &= ~PSC_SPICFG_SET_DIV(3);
+ cfg |= au1550_spi_baudcfg(hw, spi->max_speed_hz);
+
+ hw->regs->psc_spicfg = cfg | PSC_SPICFG_DE_ENABLE;
+ au_sync();
+ do {
+ stat = hw->regs->psc_spistat;
+ au_sync();
+ } while ((stat & PSC_SPISTAT_DR) == 0);
+
+ if (hw->pdata->activate_cs)
+ hw->pdata->activate_cs(hw->pdata, spi->chip_select,
+ cspol);
+ break;
+ }
+}
+
+static int au1550_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t)
+{
+ struct au1550_spi *hw = spi_master_get_devdata(spi->master);
+ unsigned bpw, hz;
+ u32 cfg, stat;
+
+ bpw = t ? t->bits_per_word : spi->bits_per_word;
+ hz = t ? t->speed_hz : spi->max_speed_hz;
+
+ if (bpw < 4 || bpw > 24) {
+ dev_err(&spi->dev, "setupxfer: invalid bits_per_word=%d\n",
+ bpw);
+ return -EINVAL;
+ }
+ if (hz > spi->max_speed_hz || hz > hw->freq_max || hz < hw->freq_min) {
+ dev_err(&spi->dev, "setupxfer: clock rate=%d out of range\n",
+ hz);
+ return -EINVAL;
+ }
+
+ au1550_spi_bits_handlers_set(hw, spi->bits_per_word);
+
+ cfg = hw->regs->psc_spicfg;
+ au_sync();
+ hw->regs->psc_spicfg = cfg & ~PSC_SPICFG_DE_ENABLE;
+ au_sync();
+
+ if (hw->usedma && bpw <= 8)
+ cfg &= ~PSC_SPICFG_DD_DISABLE;
+ else
+ cfg |= PSC_SPICFG_DD_DISABLE;
+ cfg = PSC_SPICFG_CLR_LEN(cfg);
+ cfg |= PSC_SPICFG_SET_LEN(bpw);
+
+ cfg = PSC_SPICFG_CLR_BAUD(cfg);
+ cfg &= ~PSC_SPICFG_SET_DIV(3);
+ cfg |= au1550_spi_baudcfg(hw, hz);
+
+ hw->regs->psc_spicfg = cfg;
+ au_sync();
+
+ if (cfg & PSC_SPICFG_DE_ENABLE) {
+ do {
+ stat = hw->regs->psc_spistat;
+ au_sync();
+ } while ((stat & PSC_SPISTAT_DR) == 0);
+ }
+
+ au1550_spi_reset_fifos(hw);
+ au1550_spi_mask_ack_all(hw);
+ return 0;
+}
+
+static int au1550_spi_setup(struct spi_device *spi)
+{
+ struct au1550_spi *hw = spi_master_get_devdata(spi->master);
+
+ if (spi->bits_per_word == 0)
+ spi->bits_per_word = 8;
+ if (spi->bits_per_word < 4 || spi->bits_per_word > 24) {
+ dev_err(&spi->dev, "setup: invalid bits_per_word=%d\n",
+ spi->bits_per_word);
+ return -EINVAL;
+ }
+
+ if (spi->max_speed_hz == 0)
+ spi->max_speed_hz = hw->freq_max;
+ if (spi->max_speed_hz > hw->freq_max
+ || spi->max_speed_hz < hw->freq_min)
+ return -EINVAL;
+ /*
+ * NOTE: cannot change speed and other hw settings immediately,
+ * otherwise sharing of spi bus is not possible,
+ * so do not call setupxfer(spi, NULL) here
+ */
+ return 0;
+}
+
+/*
+ * for dma spi transfers, we have to setup rx channel, otherwise there is
+ * no reliable way how to recognize that spi transfer is done
+ * dma complete callbacks are called before real spi transfer is finished
+ * and if only tx dma channel is set up (and rx fifo overflow event masked)
+ * spi master done event irq is not generated unless rx fifo is empty (emptied)
+ * so we need rx tmp buffer to use for rx dma if user does not provide one
+ */
+static int au1550_spi_dma_rxtmp_alloc(struct au1550_spi *hw, unsigned size)
+{
+ hw->dma_rx_tmpbuf = kmalloc(size, GFP_KERNEL);
+ if (!hw->dma_rx_tmpbuf)
+ return -ENOMEM;
+ hw->dma_rx_tmpbuf_size = size;
+ hw->dma_rx_tmpbuf_addr = dma_map_single(hw->dev, hw->dma_rx_tmpbuf,
+ size, DMA_FROM_DEVICE);
+ if (dma_mapping_error(hw->dma_rx_tmpbuf_addr)) {
+ kfree(hw->dma_rx_tmpbuf);
+ hw->dma_rx_tmpbuf = 0;
+ hw->dma_rx_tmpbuf_size = 0;
+ return -EFAULT;
+ }
+ return 0;
+}
+
+static void au1550_spi_dma_rxtmp_free(struct au1550_spi *hw)
+{
+ dma_unmap_single(hw->dev, hw->dma_rx_tmpbuf_addr,
+ hw->dma_rx_tmpbuf_size, DMA_FROM_DEVICE);
+ kfree(hw->dma_rx_tmpbuf);
+ hw->dma_rx_tmpbuf = 0;
+ hw->dma_rx_tmpbuf_size = 0;
+}
+
+static int au1550_spi_dma_txrxb(struct spi_device *spi, struct spi_transfer *t)
+{
+ struct au1550_spi *hw = spi_master_get_devdata(spi->master);
+ dma_addr_t dma_tx_addr;
+ dma_addr_t dma_rx_addr;
+ u32 res;
+
+ hw->len = t->len;
+ hw->tx_count = 0;
+ hw->rx_count = 0;
+
+ hw->tx = t->tx_buf;
+ hw->rx = t->rx_buf;
+ dma_tx_addr = t->tx_dma;
+ dma_rx_addr = t->rx_dma;
+
+ /*
+ * check if buffers are already dma mapped, map them otherwise
+ * use rx buffer in place of tx if tx buffer was not provided
+ * use temp rx buffer (preallocated or realloc to fit) for rx dma
+ */
+ if (t->rx_buf) {
+ if (t->rx_dma == 0) { /* if DMA_ADDR_INVALID, map it */
+ dma_rx_addr = dma_map_single(hw->dev,
+ (void *)t->rx_buf,
+ t->len, DMA_FROM_DEVICE);
+ if (dma_mapping_error(dma_rx_addr))
+ dev_err(hw->dev, "rx dma map error\n");
+ }
+ } else {
+ if (t->len > hw->dma_rx_tmpbuf_size) {
+ int ret;
+
+ au1550_spi_dma_rxtmp_free(hw);
+ ret = au1550_spi_dma_rxtmp_alloc(hw, max(t->len,
+ AU1550_SPI_DMA_RXTMP_MINSIZE));
+ if (ret < 0)
+ return ret;
+ }
+ hw->rx = hw->dma_rx_tmpbuf;
+ dma_rx_addr = hw->dma_rx_tmpbuf_addr;
+ dma_sync_single_for_device(hw->dev, dma_rx_addr,
+ t->len, DMA_FROM_DEVICE);
+ }
+ if (t->tx_buf) {
+ if (t->tx_dma == 0) { /* if DMA_ADDR_INVALID, map it */
+ dma_tx_addr = dma_map_single(hw->dev,
+ (void *)t->tx_buf,
+ t->len, DMA_TO_DEVICE);
+ if (dma_mapping_error(dma_tx_addr))
+ dev_err(hw->dev, "tx dma map error\n");
+ }
+ } else {
+ dma_sync_single_for_device(hw->dev, dma_rx_addr,
+ t->len, DMA_BIDIRECTIONAL);
+ hw->tx = hw->rx;
+ }
+
+ /* put buffers on the ring */
+ res = au1xxx_dbdma_put_dest(hw->dma_rx_ch, hw->rx, t->len);
+ if (!res)
+ dev_err(hw->dev, "rx dma put dest error\n");
+
+ res = au1xxx_dbdma_put_source(hw->dma_tx_ch, (void *)hw->tx, t->len);
+ if (!res)
+ dev_err(hw->dev, "tx dma put source error\n");
+
+ au1xxx_dbdma_start(hw->dma_rx_ch);
+ au1xxx_dbdma_start(hw->dma_tx_ch);
+
+ /* by default enable nearly all events interrupt */
+ hw->regs->psc_spimsk = PSC_SPIMSK_SD;
+ au_sync();
+
+ /* start the transfer */
+ hw->regs->psc_spipcr = PSC_SPIPCR_MS;
+ au_sync();
+
+ wait_for_completion(&hw->master_done);
+
+ au1xxx_dbdma_stop(hw->dma_tx_ch);
+ au1xxx_dbdma_stop(hw->dma_rx_ch);
+
+ if (!t->rx_buf) {
+ /* using the temporal preallocated and premapped buffer */
+ dma_sync_single_for_cpu(hw->dev, dma_rx_addr, t->len,
+ DMA_FROM_DEVICE);
+ }
+ /* unmap buffers if mapped above */
+ if (t->rx_buf && t->rx_dma == 0 )
+ dma_unmap_single(hw->dev, dma_rx_addr, t->len,
+ DMA_FROM_DEVICE);
+ if (t->tx_buf && t->tx_dma == 0 )
+ dma_unmap_single(hw->dev, dma_tx_addr, t->len,
+ DMA_TO_DEVICE);
+
+ return hw->rx_count < hw->tx_count ? hw->rx_count : hw->tx_count;
+}
+
+static irqreturn_t au1550_spi_dma_irq_callback(struct au1550_spi *hw)
+{
+ u32 stat, evnt;
+
+ stat = hw->regs->psc_spistat;
+ evnt = hw->regs->psc_spievent;
+ au_sync();
+ if ((stat & PSC_SPISTAT_DI) == 0) {
+ dev_err(hw->dev, "Unexpected IRQ!\n");
+ return IRQ_NONE;
+ }
+
+ if ((evnt & (PSC_SPIEVNT_MM | PSC_SPIEVNT_RO
+ | PSC_SPIEVNT_RU | PSC_SPIEVNT_TO
+ | PSC_SPIEVNT_TU | PSC_SPIEVNT_SD))
+ != 0) {
+ /*
+ * due to an spi error we consider transfer as done,
+ * so mask all events until before next transfer start
+ * and stop the possibly running dma immediatelly
+ */
+ au1550_spi_mask_ack_all(hw);
+ au1xxx_dbdma_stop(hw->dma_rx_ch);
+ au1xxx_dbdma_stop(hw->dma_tx_ch);
+
+ /* get number of transfered bytes */
+ hw->rx_count = hw->len - au1xxx_get_dma_residue(hw->dma_rx_ch);
+ hw->tx_count = hw->len - au1xxx_get_dma_residue(hw->dma_tx_ch);
+
+ au1xxx_dbdma_reset(hw->dma_rx_ch);
+ au1xxx_dbdma_reset(hw->dma_tx_ch);
+ au1550_spi_reset_fifos(hw);
+
+ dev_err(hw->dev,
+ "Unexpected SPI error: event=0x%x stat=0x%x!\n",
+ evnt, stat);
+
+ complete(&hw->master_done);
+ return IRQ_HANDLED;
+ }
+
+ if ((evnt & PSC_SPIEVNT_MD) != 0) {
+ /* transfer completed successfully */
+ au1550_spi_mask_ack_all(hw);
+ hw->rx_count = hw->len;
+ hw->tx_count = hw->len;
+ complete(&hw->master_done);
+ }
+ return IRQ_HANDLED;
+}
+
+
+/* routines to handle different word sizes in pio mode */
+#define AU1550_SPI_RX_WORD(size, mask) \
+static void au1550_spi_rx_word_##size(struct au1550_spi *hw) \
+{ \
+ u32 fifoword = hw->regs->psc_spitxrx & (u32)(mask); \
+ au_sync(); \
+ if (hw->rx) { \
+ *(u##size *)hw->rx = (u##size)fifoword; \
+ hw->rx += (size) / 8; \
+ } \
+ hw->rx_count += (size) / 8; \
+}
+
+#define AU1550_SPI_TX_WORD(size, mask) \
+static void au1550_spi_tx_word_##size(struct au1550_spi *hw) \
+{ \
+ u32 fifoword = 0; \
+ if (hw->tx) { \
+ fifoword = *(u##size *)hw->tx & (u32)(mask); \
+ hw->tx += (size) / 8; \
+ } \
+ hw->tx_count += (size) / 8; \
+ if (hw->tx_count >= hw->len) \
+ fifoword |= PSC_SPITXRX_LC; \
+ hw->regs->psc_spitxrx = fifoword; \
+ au_sync(); \
+}
+
+AU1550_SPI_RX_WORD(8,0xff)
+AU1550_SPI_RX_WORD(16,0xffff)
+AU1550_SPI_RX_WORD(32,0xffffff)
+AU1550_SPI_TX_WORD(8,0xff)
+AU1550_SPI_TX_WORD(16,0xffff)
+AU1550_SPI_TX_WORD(32,0xffffff)
+
+static int au1550_spi_pio_txrxb(struct spi_device *spi, struct spi_transfer *t)
+{
+ u32 stat, mask;
+ struct au1550_spi *hw = spi_master_get_devdata(spi->master);
+
+ hw->tx = t->tx_buf;
+ hw->rx = t->rx_buf;
+ hw->len = t->len;
+ hw->tx_count = 0;
+ hw->rx_count = 0;
+
+ /* by default enable nearly all events after filling tx fifo */
+ mask = PSC_SPIMSK_SD;
+
+ /* fill the transmit FIFO */
+ while (hw->tx_count < hw->len) {
+
+ hw->tx_word(hw);
+
+ if (hw->tx_count >= hw->len) {
+ /* mask tx fifo request interrupt as we are done */
+ mask |= PSC_SPIMSK_TR;
+ }
+
+ stat = hw->regs->psc_spistat;
+ au_sync();
+ if (stat & PSC_SPISTAT_TF)
+ break;
+ }
+
+ /* enable event interrupts */
+ hw->regs->psc_spimsk = mask;
+ au_sync();
+
+ /* start the transfer */
+ hw->regs->psc_spipcr = PSC_SPIPCR_MS;
+ au_sync();
+
+ wait_for_completion(&hw->master_done);
+
+ return hw->rx_count < hw->tx_count ? hw->rx_count : hw->tx_count;
+}
+
+static irqreturn_t au1550_spi_pio_irq_callback(struct au1550_spi *hw)
+{
+ int busy;
+ u32 stat, evnt;
+
+ stat = hw->regs->psc_spistat;
+ evnt = hw->regs->psc_spievent;
+ au_sync();
+ if ((stat & PSC_SPISTAT_DI) == 0) {
+ dev_err(hw->dev, "Unexpected IRQ!\n");
+ return IRQ_NONE;
+ }
+
+ if ((evnt & (PSC_SPIEVNT_MM | PSC_SPIEVNT_RO
+ | PSC_SPIEVNT_RU | PSC_SPIEVNT_TO
+ | PSC_SPIEVNT_TU | PSC_SPIEVNT_SD))
+ != 0) {
+ dev_err(hw->dev,
+ "Unexpected SPI error: event=0x%x stat=0x%x!\n",
+ evnt, stat);
+ /*
+ * due to an error we consider transfer as done,
+ * so mask all events until before next transfer start
+ */
+ au1550_spi_mask_ack_all(hw);
+ au1550_spi_reset_fifos(hw);
+ complete(&hw->master_done);
+ return IRQ_HANDLED;
+ }
+
+ /*
+ * while there is something to read from rx fifo
+ * or there is a space to write to tx fifo:
+ */
+ do {
+ busy = 0;
+ stat = hw->regs->psc_spistat;
+ au_sync();
+
+ if ((stat & PSC_SPISTAT_RE) == 0 && hw->rx_count < hw->len) {
+ hw->rx_word(hw);
+ /* ack the receive request event */
+ hw->regs->psc_spievent = PSC_SPIEVNT_RR;
+ au_sync();
+ busy = 1;
+ }
+
+ if ((stat & PSC_SPISTAT_TF) == 0 && hw->tx_count < hw->len) {
+ hw->tx_word(hw);
+ /* ack the transmit request event */
+ hw->regs->psc_spievent = PSC_SPIEVNT_TR;
+ au_sync();
+ busy = 1;
+ }
+ } while (busy);
+
+ evnt = hw->regs->psc_spievent;
+ au_sync();
+
+ if (hw->rx_count >= hw->len || (evnt & PSC_SPIEVNT_MD) != 0) {
+ /* transfer completed successfully */
+ au1550_spi_mask_ack_all(hw);
+ complete(&hw->master_done);
+ }
+ return IRQ_HANDLED;
+}
+
+static int au1550_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
+{
+ struct au1550_spi *hw = spi_master_get_devdata(spi->master);
+ return hw->txrx_bufs(spi, t);
+}
+
+static irqreturn_t au1550_spi_irq(int irq, void *dev, struct pt_regs *regs)
+{
+ struct au1550_spi *hw = dev;
+ return hw->irq_callback(hw);
+}
+
+static void au1550_spi_bits_handlers_set(struct au1550_spi *hw, int bpw)
+{
+ if (bpw <= 8) {
+ if (hw->usedma) {
+ hw->txrx_bufs = &au1550_spi_dma_txrxb;
+ hw->irq_callback = &au1550_spi_dma_irq_callback;
+ } else {
+ hw->rx_word = &au1550_spi_rx_word_8;
+ hw->tx_word = &au1550_spi_tx_word_8;
+ hw->txrx_bufs = &au1550_spi_pio_txrxb;
+ hw->irq_callback = &au1550_spi_pio_irq_callback;
+ }
+ } else if (bpw <= 16) {
+ hw->rx_word = &au1550_spi_rx_word_16;
+ hw->tx_word = &au1550_spi_tx_word_16;
+ hw->txrx_bufs = &au1550_spi_pio_txrxb;
+ hw->irq_callback = &au1550_spi_pio_irq_callback;
+ } else {
+ hw->rx_word = &au1550_spi_rx_word_32;
+ hw->tx_word = &au1550_spi_tx_word_32;
+ hw->txrx_bufs = &au1550_spi_pio_txrxb;
+ hw->irq_callback = &au1550_spi_pio_irq_callback;
+ }
+}
+
+static void __init au1550_spi_setup_psc_as_spi(struct au1550_spi *hw)
+{
+ u32 stat, cfg;
+
+ /* set up the PSC for SPI mode */
+ hw->regs->psc_ctrl = PSC_CTRL_DISABLE;
+ au_sync();
+ hw->regs->psc_sel = PSC_SEL_PS_SPIMODE;
+ au_sync();
+
+ hw->regs->psc_spicfg = 0;
+ au_sync();
+
+ hw->regs->psc_ctrl = PSC_CTRL_ENABLE;
+ au_sync();
+
+ do {
+ stat = hw->regs->psc_spistat;
+ au_sync();
+ } while ((stat & PSC_SPISTAT_SR) == 0);
+
+
+ cfg = hw->usedma ? 0 : PSC_SPICFG_DD_DISABLE;
+ cfg |= PSC_SPICFG_SET_LEN(8);
+ cfg |= PSC_SPICFG_RT_FIFO8 | PSC_SPICFG_TT_FIFO8;
+ /* use minimal allowed brg and div values as initial setting: */
+ cfg |= PSC_SPICFG_SET_BAUD(4) | PSC_SPICFG_SET_DIV(0);
+
+#ifdef AU1550_SPI_DEBUG_LOOPBACK
+ cfg |= PSC_SPICFG_LB;
+#endif
+
+ hw->regs->psc_spicfg = cfg;
+ au_sync();
+
+ au1550_spi_mask_ack_all(hw);
+
+ hw->regs->psc_spicfg |= PSC_SPICFG_DE_ENABLE;
+ au_sync();
+
+ do {
+ stat = hw->regs->psc_spistat;
+ au_sync();
+ } while ((stat & PSC_SPISTAT_DR) == 0);
+}
+
+
+static int __init au1550_spi_probe(struct platform_device *pdev)
+{
+ struct au1550_spi *hw;
+ struct spi_master *master;
+ int err = 0;
+
+ master = spi_alloc_master(&pdev->dev, sizeof(struct au1550_spi));
+ if (master == NULL) {
+ dev_err(&pdev->dev, "No memory for spi_master\n");
+ err = -ENOMEM;
+ goto err_nomem;
+ }
+
+ hw = spi_master_get_devdata(master);
+
+ hw->master = spi_master_get(master);
+ hw->pdata = pdev->dev.platform_data;
+ hw->dev = &pdev->dev;
+
+ if (hw->pdata == NULL) {
+ dev_err(&pdev->dev, "No platform data supplied\n");
+ err = -ENOENT;
+ goto err_no_pdata;
+ }
+
+ platform_set_drvdata(pdev, hw);
+
+ init_completion(&hw->master_done);
+
+ hw->bitbang.master = hw->master;
+ hw->bitbang.setup_transfer = au1550_spi_setupxfer;
+ hw->bitbang.chipselect = au1550_spi_chipsel;
+ hw->bitbang.master->setup = au1550_spi_setup;
+ hw->bitbang.txrx_bufs = au1550_spi_txrx_bufs;
+
+ switch (hw->pdata->bus_num) {
+ case 0:
+ hw->irq = AU1550_PSC0_INT;
+ hw->regs = (volatile psc_spi_t *)PSC0_BASE_ADDR;
+ hw->dma_rx_id = DSCR_CMD0_PSC0_RX;
+ hw->dma_tx_id = DSCR_CMD0_PSC0_TX;
+ break;
+ case 1:
+ hw->irq = AU1550_PSC1_INT;
+ hw->regs = (volatile psc_spi_t *)PSC1_BASE_ADDR;
+ hw->dma_rx_id = DSCR_CMD0_PSC1_RX;
+ hw->dma_tx_id = DSCR_CMD0_PSC1_TX;
+ break;
+ case 2:
+ hw->irq = AU1550_PSC2_INT;
+ hw->regs = (volatile psc_spi_t *)PSC2_BASE_ADDR;
+ hw->dma_rx_id = DSCR_CMD0_PSC2_RX;
+ hw->dma_tx_id = DSCR_CMD0_PSC2_TX;
+ break;
+ case 3:
+ hw->irq = AU1550_PSC3_INT;
+ hw->regs = (volatile psc_spi_t *)PSC3_BASE_ADDR;
+ hw->dma_rx_id = DSCR_CMD0_PSC3_RX;
+ hw->dma_tx_id = DSCR_CMD0_PSC3_TX;
+ break;
+ default:
+ dev_err(&pdev->dev, "Wrong bus_num of SPI\n");
+ err = -ENOENT;
+ goto err_no_pdata;
+ }
+
+ if (request_mem_region((unsigned long)hw->regs, sizeof(psc_spi_t),
+ pdev->name) == NULL) {
+ dev_err(&pdev->dev, "Cannot reserve iomem region\n");
+ err = -ENXIO;
+ goto err_no_iores;
+ }
+
+
+ if (usedma) {
+ if (pdev->dev.dma_mask == NULL)
+ dev_warn(&pdev->dev, "no dma mask\n");
+ else
+ hw->usedma = 1;
+ }
+
+ if (hw->usedma) {
+ /*
+ * create memory device with 8 bits dev_devwidth
+ * needed for proper byte ordering to spi fifo
+ */
+ int memid = au1xxx_ddma_add_device(&au1550_spi_mem_dbdev);
+ if (!memid) {
+ dev_err(&pdev->dev,
+ "Cannot create dma 8 bit mem device\n");
+ err = -ENXIO;
+ goto err_dma_add_dev;
+ }
+
+ hw->dma_tx_ch = au1xxx_dbdma_chan_alloc(memid,
+ hw->dma_tx_id, NULL, (void *)hw);
+ if (hw->dma_tx_ch == 0) {
+ dev_err(&pdev->dev,
+ "Cannot allocate tx dma channel\n");
+ err = -ENXIO;
+ goto err_no_txdma;
+ }
+ au1xxx_dbdma_set_devwidth(hw->dma_tx_ch, 8);
+ if (au1xxx_dbdma_ring_alloc(hw->dma_tx_ch,
+ AU1550_SPI_DBDMA_DESCRIPTORS) == 0) {
+ dev_err(&pdev->dev,
+ "Cannot allocate tx dma descriptors\n");
+ err = -ENXIO;
+ goto err_no_txdma_descr;
+ }
+
+
+ hw->dma_rx_ch = au1xxx_dbdma_chan_alloc(hw->dma_rx_id,
+ memid, NULL, (void *)hw);
+ if (hw->dma_rx_ch == 0) {
+ dev_err(&pdev->dev,
+ "Cannot allocate rx dma channel\n");
+ err = -ENXIO;
+ goto err_no_rxdma;
+ }
+ au1xxx_dbdma_set_devwidth(hw->dma_rx_ch, 8);
+ if (au1xxx_dbdma_ring_alloc(hw->dma_rx_ch,
+ AU1550_SPI_DBDMA_DESCRIPTORS) == 0) {
+ dev_err(&pdev->dev,
+ "Cannot allocate rx dma descriptors\n");
+ err = -ENXIO;
+ goto err_no_rxdma_descr;
+ }
+
+ err = au1550_spi_dma_rxtmp_alloc(hw,
+ AU1550_SPI_DMA_RXTMP_MINSIZE);
+ if (err < 0) {
+ dev_err(&pdev->dev,
+ "Cannot allocate initial rx dma tmp buffer\n");
+ goto err_dma_rxtmp_alloc;
+ }
+ }
+
+ au1550_spi_bits_handlers_set(hw, 8);
+
+ err = request_irq(hw->irq, au1550_spi_irq, 0, pdev->name, hw);
+ if (err) {
+ dev_err(&pdev->dev, "Cannot claim IRQ\n");
+ goto err_no_irq;
+ }
+
+ master->bus_num = hw->pdata->bus_num;
+ master->num_chipselect = hw->pdata->num_chipselect;
+
+ /*
+ * precompute valid range for spi freq - from au1550 datasheet:
+ * psc_tempclk = psc_mainclk / (2 << DIV)
+ * spiclk = psc_tempclk / (2 * (BRG + 1))
+ * BRG valid range is 4..63
+ * DIV valid range is 0..3
+ * round the min and max frequencies to values that would still
+ * produce valid brg and div
+ */
+ {
+ int min_div = (2 << 0) * (2 * (4 + 1));
+ int max_div = (2 << 3) * (2 * (63 + 1));
+ hw->freq_max = hw->pdata->mainclk_hz / min_div;
+ hw->freq_min = hw->pdata->mainclk_hz / (max_div + 1) + 1;
+ }
+
+ au1550_spi_setup_psc_as_spi(hw);
+
+ err = spi_bitbang_start(&hw->bitbang);
+ if (err) {
+ dev_err(&pdev->dev, "Failed to register SPI master\n");
+ goto err_register;
+ }
+
+ dev_info(&pdev->dev,
+ "spi master registered: bus_num=%d num_chipselect=%d\n",
+ master->bus_num, master->num_chipselect);
+
+ return 0;
+
+err_register:
+ free_irq(hw->irq, hw);
+
+err_no_irq:
+ au1550_spi_dma_rxtmp_free(hw);
+
+err_dma_rxtmp_alloc:
+err_no_rxdma_descr:
+ if (hw->usedma)
+ au1xxx_dbdma_chan_free(hw->dma_rx_ch);
+
+err_no_rxdma:
+err_no_txdma_descr:
+ if (hw->usedma)
+ au1xxx_dbdma_chan_free(hw->dma_tx_ch);
+
+err_no_txdma:
+err_dma_add_dev:
+ release_mem_region((unsigned long)hw->regs, sizeof(psc_spi_t));
+
+err_no_iores:
+err_no_pdata:
+ spi_master_put(hw->master);
+
+err_nomem:
+ return err;
+}
+
+static int __exit au1550_spi_remove(struct platform_device *pdev)
+{
+ struct au1550_spi *hw = platform_get_drvdata(pdev);
+
+ dev_info(&pdev->dev, "spi master remove: bus_num=%d\n",
+ hw->master->bus_num);
+
+ spi_bitbang_stop(&hw->bitbang);
+ free_irq(hw->irq, hw);
+ release_mem_region((unsigned long)hw->regs, sizeof(psc_spi_t));
+
+ if (hw->usedma) {
+ au1550_spi_dma_rxtmp_free(hw);
+ au1xxx_dbdma_chan_free(hw->dma_rx_ch);
+ au1xxx_dbdma_chan_free(hw->dma_tx_ch);
+ }
+
+ platform_set_drvdata(pdev, NULL);
+
+ spi_master_put(hw->master);
+ return 0;
+}
+
+static struct platform_driver au1550_spi_drv = {
+ .remove = __exit_p(au1550_spi_remove),
+ .driver = {
+ .name = "au1550-spi",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init au1550_spi_init(void)
+{
+ return platform_driver_probe(&au1550_spi_drv, au1550_spi_probe);
+}
+module_init(au1550_spi_init);
+
+static void __exit au1550_spi_exit(void)
+{
+ platform_driver_unregister(&au1550_spi_drv);
+}
+module_exit(au1550_spi_exit);
+
+MODULE_DESCRIPTION("Au1550 PSC SPI Driver");
+MODULE_AUTHOR("Jan Nikitenko <jan.nikitenko@gmail.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 6657331..c3219b2 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -152,6 +152,11 @@
sdrv->shutdown(to_spi_device(dev));
}
+/**
+ * spi_register_driver - register a SPI driver
+ * @sdrv: the driver to register
+ * Context: can sleep
+ */
int spi_register_driver(struct spi_driver *sdrv)
{
sdrv->driver.bus = &spi_bus_type;
@@ -183,7 +188,13 @@
static DECLARE_MUTEX(board_lock);
-/* On typical mainboards, this is purely internal; and it's not needed
+/**
+ * spi_new_device - instantiate one new SPI device
+ * @master: Controller to which device is connected
+ * @chip: Describes the SPI device
+ * Context: can sleep
+ *
+ * On typical mainboards, this is purely internal; and it's not needed
* after board init creates the hard-wired devices. Some development
* platforms may not be able to use spi_register_board_info though, and
* this is exported so that for example a USB or parport based adapter
@@ -251,7 +262,12 @@
}
EXPORT_SYMBOL_GPL(spi_new_device);
-/*
+/**
+ * spi_register_board_info - register SPI devices for a given board
+ * @info: array of chip descriptors
+ * @n: how many descriptors are provided
+ * Context: can sleep
+ *
* Board-specific early init code calls this (probably during arch_initcall)
* with segments of the SPI device table. Any device nodes are created later,
* after the relevant parent SPI controller (bus_num) is defined. We keep
@@ -337,9 +353,10 @@
/**
* spi_alloc_master - allocate SPI master controller
* @dev: the controller, possibly using the platform_bus
- * @size: how much driver-private data to preallocate; the pointer to this
+ * @size: how much zeroed driver-private data to allocate; the pointer to this
* memory is in the class_data field of the returned class_device,
* accessible with spi_master_get_devdata().
+ * Context: can sleep
*
* This call is used only by SPI master controller drivers, which are the
* only ones directly touching chip registers. It's how they allocate
@@ -375,6 +392,7 @@
/**
* spi_register_master - register SPI master controller
* @master: initialized master, originally from spi_alloc_master()
+ * Context: can sleep
*
* SPI master controllers connect to their drivers using some non-SPI bus,
* such as the platform bus. The final stage of probe() in that code
@@ -437,6 +455,7 @@
/**
* spi_unregister_master - unregister SPI master controller
* @master: the master being unregistered
+ * Context: can sleep
*
* This call is used only by SPI master controller drivers, which are the
* only ones directly touching chip registers.
@@ -455,6 +474,7 @@
/**
* spi_busnum_to_master - look up master associated with bus_num
* @bus_num: the master's bus number
+ * Context: can sleep
*
* This call may be used with devices that are registered after
* arch init time. It returns a refcounted pointer to the relevant
@@ -492,6 +512,7 @@
* spi_sync - blocking/synchronous SPI data transfers
* @spi: device with which data will be exchanged
* @message: describes the data transfers
+ * Context: can sleep
*
* This call may only be used from a context that may sleep. The sleep
* is non-interruptible, and has no timeout. Low-overhead controller
@@ -508,7 +529,7 @@
*
* The return value is a negative error code if the message could not be
* submitted, else zero. When the value is zero, then message->status is
- * also defined: it's the completion code for the transfer, either zero
+ * also defined; it's the completion code for the transfer, either zero
* or a negative error code from the controller driver.
*/
int spi_sync(struct spi_device *spi, struct spi_message *message)
@@ -538,6 +559,7 @@
* @n_tx: size of txbuf, in bytes
* @rxbuf: buffer into which data will be read
* @n_rx: size of rxbuf, in bytes (need not be dma-safe)
+ * Context: can sleep
*
* This performs a half duplex MicroWire style transaction with the
* device, sending txbuf and then reading rxbuf. The return value
@@ -545,7 +567,8 @@
* This call may only be used from a context that may sleep.
*
* Parameters to this routine are always copied using a small buffer;
- * performance-sensitive or bulk transfer code should instead use
+ * portable code should never use this for more than 32 bytes.
+ * Performance-sensitive or bulk transfer code should instead use
* spi_{async,sync}() calls with dma-safe buffers.
*/
int spi_write_then_read(struct spi_device *spi,
diff --git a/drivers/spi/spi_butterfly.c b/drivers/spi/spi_butterfly.c
index 312987a..0ee2b20 100644
--- a/drivers/spi/spi_butterfly.c
+++ b/drivers/spi/spi_butterfly.c
@@ -20,7 +20,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>
-#include <linux/platform_device.h>
+#include <linux/device.h>
#include <linux/parport.h>
#include <linux/sched.h>
@@ -40,8 +40,6 @@
* and use this custom parallel port cable.
*/
-#undef HAVE_USI /* nyet */
-
/* DATA output bits (pins 2..9 == D0..D7) */
#define butterfly_nreset (1 << 1) /* pin 3 */
@@ -49,19 +47,13 @@
#define spi_sck_bit (1 << 0) /* pin 2 */
#define spi_mosi_bit (1 << 7) /* pin 9 */
-#define usi_sck_bit (1 << 3) /* pin 5 */
-#define usi_mosi_bit (1 << 4) /* pin 6 */
-
#define vcc_bits ((1 << 6) | (1 << 5)) /* pins 7, 8 */
/* STATUS input bits */
#define spi_miso_bit PARPORT_STATUS_BUSY /* pin 11 */
-#define usi_miso_bit PARPORT_STATUS_PAPEROUT /* pin 12 */
-
/* CONTROL output bits */
#define spi_cs_bit PARPORT_CONTROL_SELECT /* pin 17 */
-/* USI uses no chipselect */
@@ -70,15 +62,6 @@
return spi->controller_data;
}
-static inline int is_usidev(struct spi_device *spi)
-{
-#ifdef HAVE_USI
- return spi->chip_select != 1;
-#else
- return 0;
-#endif
-}
-
struct butterfly {
/* REVISIT ... for now, this must be first */
@@ -97,23 +80,13 @@
/*----------------------------------------------------------------------*/
-/*
- * these routines may be slower than necessary because they're hiding
- * the fact that there are two different SPI busses on this cable: one
- * to the DataFlash chip (or AVR SPI controller), the other to the
- * AVR USI controller.
- */
-
static inline void
setsck(struct spi_device *spi, int is_on)
{
struct butterfly *pp = spidev_to_pp(spi);
u8 bit, byte = pp->lastbyte;
- if (is_usidev(spi))
- bit = usi_sck_bit;
- else
- bit = spi_sck_bit;
+ bit = spi_sck_bit;
if (is_on)
byte |= bit;
@@ -129,10 +102,7 @@
struct butterfly *pp = spidev_to_pp(spi);
u8 bit, byte = pp->lastbyte;
- if (is_usidev(spi))
- bit = usi_mosi_bit;
- else
- bit = spi_mosi_bit;
+ bit = spi_mosi_bit;
if (is_on)
byte |= bit;
@@ -148,10 +118,7 @@
int value;
u8 bit;
- if (is_usidev(spi))
- bit = usi_miso_bit;
- else
- bit = spi_miso_bit;
+ bit = spi_miso_bit;
/* only STATUS_BUSY is NOT negated */
value = !(parport_read_status(pp->port) & bit);
@@ -166,10 +133,6 @@
if (value != BITBANG_CS_INACTIVE)
setsck(spi, spi->mode & SPI_CPOL);
- /* no chipselect on this USI link config */
- if (is_usidev(spi))
- return;
-
/* here, value == "activate or not";
* most PARPORT_CONTROL_* bits are negated, so we must
* morph it to value == "bit value to write in control register"
@@ -237,24 +200,16 @@
int status;
struct butterfly *pp;
struct spi_master *master;
- struct platform_device *pdev;
+ struct device *dev = p->physport->dev;
- if (butterfly)
+ if (butterfly || !dev)
return;
/* REVISIT: this just _assumes_ a butterfly is there ... no probe,
* and no way to be selective about what it binds to.
*/
- /* FIXME where should master->cdev.dev come from?
- * e.g. /sys/bus/pnp0/00:0b, some PCI thing, etc
- * setting up a platform device like this is an ugly kluge...
- */
- pdev = platform_device_register_simple("butterfly", -1, NULL, 0);
- if (IS_ERR(pdev))
- return;
-
- master = spi_alloc_master(&pdev->dev, sizeof *pp);
+ master = spi_alloc_master(dev, sizeof *pp);
if (!master) {
status = -ENOMEM;
goto done;
@@ -300,7 +255,7 @@
parport_frob_control(pp->port, spi_cs_bit, 0);
/* stabilize power with chip in reset (nRESET), and
- * both spi_sck_bit and usi_sck_bit clear (CPOL=0)
+ * spi_sck_bit clear (CPOL=0)
*/
pp->lastbyte |= vcc_bits;
parport_write_data(pp->port, pp->lastbyte);
@@ -334,23 +289,6 @@
pr_debug("%s: dataflash at %s\n", p->name,
pp->dataflash->dev.bus_id);
-#ifdef HAVE_USI
- /* Bus 2 is only for talking to the AVR, and it can work no
- * matter who masters bus 1; needs appropriate AVR firmware.
- */
- pp->info[1].max_speed_hz = 10 /* ?? */ * 1000 * 1000;
- strcpy(pp->info[1].modalias, "butterfly");
- // pp->info[1].platform_data = ... TBD ... ;
- pp->info[1].chip_select = 2,
- pp->info[1].controller_data = pp;
- pp->butterfly = spi_new_device(pp->bitbang.master, &pp->info[1]);
- if (pp->butterfly)
- pr_debug("%s: butterfly at %s\n", p->name,
- pp->butterfly->dev.bus_id);
-
- /* FIXME setup ACK for the IRQ line ... */
-#endif
-
// dev_info(_what?_, ...)
pr_info("%s: AVR Butterfly\n", p->name);
butterfly = pp;
@@ -366,14 +304,12 @@
clean0:
(void) spi_master_put(pp->bitbang.master);
done:
- platform_device_unregister(pdev);
pr_debug("%s: butterfly probe, fail %d\n", p->name, status);
}
static void butterfly_detach(struct parport *p)
{
struct butterfly *pp;
- struct platform_device *pdev;
int status;
/* FIXME this global is ugly ... but, how to quickly get from
@@ -386,7 +322,6 @@
butterfly = NULL;
/* stop() unregisters child devices too */
- pdev = to_platform_device(pp->bitbang.master->cdev.dev);
status = spi_bitbang_stop(&pp->bitbang);
/* turn off VCC */
@@ -397,8 +332,6 @@
parport_unregister_device(pp->pd);
(void) spi_master_put(pp->bitbang.master);
-
- platform_device_unregister(pdev);
}
static struct parport_driver butterfly_driver = {
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
new file mode 100644
index 0000000..c0a6dce
--- /dev/null
+++ b/drivers/spi/spidev.c
@@ -0,0 +1,584 @@
+/*
+ * spidev.c -- simple synchronous userspace interface to SPI devices
+ *
+ * Copyright (C) 2006 SWAPP
+ * Andrea Paterniani <a.paterniani@swapp-eng.it>
+ * Copyright (C) 2007 David Brownell (simplification, cleanup)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/ioctl.h>
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/spidev.h>
+
+#include <asm/uaccess.h>
+
+
+/*
+ * This supports acccess to SPI devices using normal userspace I/O calls.
+ * Note that while traditional UNIX/POSIX I/O semantics are half duplex,
+ * and often mask message boundaries, full SPI support requires full duplex
+ * transfers. There are several kinds of of internal message boundaries to
+ * handle chipselect management and other protocol options.
+ *
+ * SPI has a character major number assigned. We allocate minor numbers
+ * dynamically using a bitmask. You must use hotplug tools, such as udev
+ * (or mdev with busybox) to create and destroy the /dev/spidevB.C device
+ * nodes, since there is no fixed association of minor numbers with any
+ * particular SPI bus or device.
+ */
+#define SPIDEV_MAJOR 153 /* assigned */
+#define N_SPI_MINORS 32 /* ... up to 256 */
+
+static unsigned long minors[N_SPI_MINORS / BITS_PER_LONG];
+
+
+/* Bit masks for spi_device.mode management */
+#define SPI_MODE_MASK (SPI_CPHA | SPI_CPOL)
+
+
+struct spidev_data {
+ struct device dev;
+ struct spi_device *spi;
+ struct list_head device_entry;
+
+ struct mutex buf_lock;
+ unsigned users;
+ u8 *buffer;
+};
+
+static LIST_HEAD(device_list);
+static DEFINE_MUTEX(device_list_lock);
+
+static unsigned bufsiz = 4096;
+module_param(bufsiz, uint, S_IRUGO);
+MODULE_PARM_DESC(bufsiz, "data bytes in biggest supported SPI message");
+
+/*-------------------------------------------------------------------------*/
+
+/* Read-only message with current device setup */
+static ssize_t
+spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
+{
+ struct spidev_data *spidev;
+ struct spi_device *spi;
+ ssize_t status = 0;
+
+ /* chipselect only toggles at start or end of operation */
+ if (count > bufsiz)
+ return -EMSGSIZE;
+
+ spidev = filp->private_data;
+ spi = spidev->spi;
+
+ mutex_lock(&spidev->buf_lock);
+ status = spi_read(spi, spidev->buffer, count);
+ if (status == 0) {
+ unsigned long missing;
+
+ missing = copy_to_user(buf, spidev->buffer, count);
+ if (count && missing == count)
+ status = -EFAULT;
+ else
+ status = count - missing;
+ }
+ mutex_unlock(&spidev->buf_lock);
+
+ return status;
+}
+
+/* Write-only message with current device setup */
+static ssize_t
+spidev_write(struct file *filp, const char __user *buf,
+ size_t count, loff_t *f_pos)
+{
+ struct spidev_data *spidev;
+ struct spi_device *spi;
+ ssize_t status = 0;
+ unsigned long missing;
+
+ /* chipselect only toggles at start or end of operation */
+ if (count > bufsiz)
+ return -EMSGSIZE;
+
+ spidev = filp->private_data;
+ spi = spidev->spi;
+
+ mutex_lock(&spidev->buf_lock);
+ missing = copy_from_user(spidev->buffer, buf, count);
+ if (missing == 0) {
+ status = spi_write(spi, spidev->buffer, count);
+ if (status == 0)
+ status = count;
+ } else
+ status = -EFAULT;
+ mutex_unlock(&spidev->buf_lock);
+
+ return status;
+}
+
+static int spidev_message(struct spidev_data *spidev,
+ struct spi_ioc_transfer *u_xfers, unsigned n_xfers)
+{
+ struct spi_message msg;
+ struct spi_transfer *k_xfers;
+ struct spi_transfer *k_tmp;
+ struct spi_ioc_transfer *u_tmp;
+ struct spi_device *spi = spidev->spi;
+ unsigned n, total;
+ u8 *buf;
+ int status = -EFAULT;
+
+ spi_message_init(&msg);
+ k_xfers = kcalloc(n_xfers, sizeof(*k_tmp), GFP_KERNEL);
+ if (k_xfers == NULL)
+ return -ENOMEM;
+
+ /* Construct spi_message, copying any tx data to bounce buffer.
+ * We walk the array of user-provided transfers, using each one
+ * to initialize a kernel version of the same transfer.
+ */
+ mutex_lock(&spidev->buf_lock);
+ buf = spidev->buffer;
+ total = 0;
+ for (n = n_xfers, k_tmp = k_xfers, u_tmp = u_xfers;
+ n;
+ n--, k_tmp++, u_tmp++) {
+ k_tmp->len = u_tmp->len;
+
+ if (u_tmp->rx_buf) {
+ k_tmp->rx_buf = buf;
+ if (!access_ok(VERIFY_WRITE, u_tmp->rx_buf, u_tmp->len))
+ goto done;
+ }
+ if (u_tmp->tx_buf) {
+ k_tmp->tx_buf = buf;
+ if (copy_from_user(buf, (const u8 __user *)u_tmp->tx_buf,
+ u_tmp->len))
+ goto done;
+ }
+
+ total += k_tmp->len;
+ if (total > bufsiz) {
+ status = -EMSGSIZE;
+ goto done;
+ }
+ buf += k_tmp->len;
+
+ k_tmp->cs_change = !!u_tmp->cs_change;
+ k_tmp->bits_per_word = u_tmp->bits_per_word;
+ k_tmp->delay_usecs = u_tmp->delay_usecs;
+ k_tmp->speed_hz = u_tmp->speed_hz;
+#ifdef VERBOSE
+ dev_dbg(&spi->dev,
+ " xfer len %zd %s%s%s%dbits %u usec %uHz\n",
+ u_tmp->len,
+ u_tmp->rx_buf ? "rx " : "",
+ u_tmp->tx_buf ? "tx " : "",
+ u_tmp->cs_change ? "cs " : "",
+ u_tmp->bits_per_word ? : spi->bits_per_word,
+ u_tmp->delay_usecs,
+ u_tmp->speed_hz ? : spi->max_speed_hz);
+#endif
+ spi_message_add_tail(k_tmp, &msg);
+ }
+
+ status = spi_sync(spi, &msg);
+ if (status < 0)
+ goto done;
+
+ /* copy any rx data out of bounce buffer */
+ buf = spidev->buffer;
+ for (n = n_xfers, u_tmp = u_xfers; n; n--, u_tmp++) {
+ if (u_tmp->rx_buf) {
+ if (__copy_to_user((u8 __user *)u_tmp->rx_buf, buf,
+ u_tmp->len)) {
+ status = -EFAULT;
+ goto done;
+ }
+ }
+ buf += u_tmp->len;
+ }
+ status = total;
+
+done:
+ mutex_unlock(&spidev->buf_lock);
+ kfree(k_xfers);
+ return status;
+}
+
+static int
+spidev_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ int err = 0;
+ int retval = 0;
+ struct spidev_data *spidev;
+ struct spi_device *spi;
+ u32 tmp;
+ unsigned n_ioc;
+ struct spi_ioc_transfer *ioc;
+
+ /* Check type and command number */
+ if (_IOC_TYPE(cmd) != SPI_IOC_MAGIC)
+ return -ENOTTY;
+
+ /* Check access direction once here; don't repeat below.
+ * IOC_DIR is from the user perspective, while access_ok is
+ * from the kernel perspective; so they look reversed.
+ */
+ if (_IOC_DIR(cmd) & _IOC_READ)
+ err = !access_ok(VERIFY_WRITE,
+ (void __user *)arg, _IOC_SIZE(cmd));
+ if (err == 0 && _IOC_DIR(cmd) & _IOC_WRITE)
+ err = !access_ok(VERIFY_READ,
+ (void __user *)arg, _IOC_SIZE(cmd));
+ if (err)
+ return -EFAULT;
+
+ spidev = filp->private_data;
+ spi = spidev->spi;
+
+ switch (cmd) {
+ /* read requests */
+ case SPI_IOC_RD_MODE:
+ retval = __put_user(spi->mode & SPI_MODE_MASK,
+ (__u8 __user *)arg);
+ break;
+ case SPI_IOC_RD_LSB_FIRST:
+ retval = __put_user((spi->mode & SPI_LSB_FIRST) ? 1 : 0,
+ (__u8 __user *)arg);
+ break;
+ case SPI_IOC_RD_BITS_PER_WORD:
+ retval = __put_user(spi->bits_per_word, (__u8 __user *)arg);
+ break;
+ case SPI_IOC_RD_MAX_SPEED_HZ:
+ retval = __put_user(spi->max_speed_hz, (__u32 __user *)arg);
+ break;
+
+ /* write requests */
+ case SPI_IOC_WR_MODE:
+ retval = __get_user(tmp, (u8 __user *)arg);
+ if (retval == 0) {
+ u8 save = spi->mode;
+
+ if (tmp & ~SPI_MODE_MASK) {
+ retval = -EINVAL;
+ break;
+ }
+
+ tmp |= spi->mode & ~SPI_MODE_MASK;
+ spi->mode = (u8)tmp;
+ retval = spi_setup(spi);
+ if (retval < 0)
+ spi->mode = save;
+ else
+ dev_dbg(&spi->dev, "spi mode %02x\n", tmp);
+ }
+ break;
+ case SPI_IOC_WR_LSB_FIRST:
+ retval = __get_user(tmp, (__u8 __user *)arg);
+ if (retval == 0) {
+ u8 save = spi->mode;
+
+ if (tmp)
+ spi->mode |= SPI_LSB_FIRST;
+ else
+ spi->mode &= ~SPI_LSB_FIRST;
+ retval = spi_setup(spi);
+ if (retval < 0)
+ spi->mode = save;
+ else
+ dev_dbg(&spi->dev, "%csb first\n",
+ tmp ? 'l' : 'm');
+ }
+ break;
+ case SPI_IOC_WR_BITS_PER_WORD:
+ retval = __get_user(tmp, (__u8 __user *)arg);
+ if (retval == 0) {
+ u8 save = spi->bits_per_word;
+
+ spi->bits_per_word = tmp;
+ retval = spi_setup(spi);
+ if (retval < 0)
+ spi->bits_per_word = save;
+ else
+ dev_dbg(&spi->dev, "%d bits per word\n", tmp);
+ }
+ break;
+ case SPI_IOC_WR_MAX_SPEED_HZ:
+ retval = __get_user(tmp, (__u32 __user *)arg);
+ if (retval == 0) {
+ u32 save = spi->max_speed_hz;
+
+ spi->max_speed_hz = tmp;
+ retval = spi_setup(spi);
+ if (retval < 0)
+ spi->max_speed_hz = save;
+ else
+ dev_dbg(&spi->dev, "%d Hz (max)\n", tmp);
+ }
+ break;
+
+ default:
+ /* segmented and/or full-duplex I/O request */
+ if (_IOC_NR(cmd) != _IOC_NR(SPI_IOC_MESSAGE(0))
+ || _IOC_DIR(cmd) != _IOC_WRITE)
+ return -ENOTTY;
+
+ tmp = _IOC_SIZE(cmd);
+ if ((tmp % sizeof(struct spi_ioc_transfer)) != 0) {
+ retval = -EINVAL;
+ break;
+ }
+ n_ioc = tmp / sizeof(struct spi_ioc_transfer);
+ if (n_ioc == 0)
+ break;
+
+ /* copy into scratch area */
+ ioc = kmalloc(tmp, GFP_KERNEL);
+ if (!ioc) {
+ retval = -ENOMEM;
+ break;
+ }
+ if (__copy_from_user(ioc, (void __user *)arg, tmp)) {
+ retval = -EFAULT;
+ break;
+ }
+
+ /* translate to spi_message, execute */
+ retval = spidev_message(spidev, ioc, n_ioc);
+ kfree(ioc);
+ break;
+ }
+ return retval;
+}
+
+static int spidev_open(struct inode *inode, struct file *filp)
+{
+ struct spidev_data *spidev;
+ int status = -ENXIO;
+
+ mutex_lock(&device_list_lock);
+
+ list_for_each_entry(spidev, &device_list, device_entry) {
+ if (spidev->dev.devt == inode->i_rdev) {
+ status = 0;
+ break;
+ }
+ }
+ if (status == 0) {
+ if (!spidev->buffer) {
+ spidev->buffer = kmalloc(bufsiz, GFP_KERNEL);
+ if (!spidev->buffer) {
+ dev_dbg(&spidev->spi->dev, "open/ENOMEM\n");
+ status = -ENOMEM;
+ }
+ }
+ if (status == 0) {
+ spidev->users++;
+ filp->private_data = spidev;
+ nonseekable_open(inode, filp);
+ }
+ } else
+ pr_debug("spidev: nothing for minor %d\n", iminor(inode));
+
+ mutex_unlock(&device_list_lock);
+ return status;
+}
+
+static int spidev_release(struct inode *inode, struct file *filp)
+{
+ struct spidev_data *spidev;
+ int status = 0;
+
+ mutex_lock(&device_list_lock);
+ spidev = filp->private_data;
+ filp->private_data = NULL;
+ spidev->users--;
+ if (!spidev->users) {
+ kfree(spidev->buffer);
+ spidev->buffer = NULL;
+ }
+ mutex_unlock(&device_list_lock);
+
+ return status;
+}
+
+static struct file_operations spidev_fops = {
+ .owner = THIS_MODULE,
+ /* REVISIT switch to aio primitives, so that userspace
+ * gets more complete API coverage. It'll simplify things
+ * too, except for the locking.
+ */
+ .write = spidev_write,
+ .read = spidev_read,
+ .ioctl = spidev_ioctl,
+ .open = spidev_open,
+ .release = spidev_release,
+};
+
+/*-------------------------------------------------------------------------*/
+
+/* The main reason to have this class is to make mdev/udev create the
+ * /dev/spidevB.C character device nodes exposing our userspace API.
+ * It also simplifies memory management.
+ */
+
+static void spidev_classdev_release(struct device *dev)
+{
+ struct spidev_data *spidev;
+
+ spidev = container_of(dev, struct spidev_data, dev);
+ kfree(spidev);
+}
+
+static struct class spidev_class = {
+ .name = "spidev",
+ .owner = THIS_MODULE,
+ .dev_release = spidev_classdev_release,
+};
+
+/*-------------------------------------------------------------------------*/
+
+static int spidev_probe(struct spi_device *spi)
+{
+ struct spidev_data *spidev;
+ int status;
+ unsigned long minor;
+
+ /* Allocate driver data */
+ spidev = kzalloc(sizeof(*spidev), GFP_KERNEL);
+ if (!spidev)
+ return -ENOMEM;
+
+ /* Initialize the driver data */
+ spidev->spi = spi;
+ mutex_init(&spidev->buf_lock);
+
+ INIT_LIST_HEAD(&spidev->device_entry);
+
+ /* If we can allocate a minor number, hook up this device.
+ * Reusing minors is fine so long as udev or mdev is working.
+ */
+ mutex_lock(&device_list_lock);
+ minor = find_first_zero_bit(minors, ARRAY_SIZE(minors));
+ if (minor < N_SPI_MINORS) {
+ spidev->dev.parent = &spi->dev;
+ spidev->dev.class = &spidev_class;
+ spidev->dev.devt = MKDEV(SPIDEV_MAJOR, minor);
+ snprintf(spidev->dev.bus_id, sizeof spidev->dev.bus_id,
+ "spidev%d.%d",
+ spi->master->bus_num, spi->chip_select);
+ status = device_register(&spidev->dev);
+ } else {
+ dev_dbg(&spi->dev, "no minor number available!\n");
+ status = -ENODEV;
+ }
+ if (status == 0) {
+ set_bit(minor, minors);
+ dev_set_drvdata(&spi->dev, spidev);
+ list_add(&spidev->device_entry, &device_list);
+ }
+ mutex_unlock(&device_list_lock);
+
+ if (status != 0)
+ kfree(spidev);
+
+ return status;
+}
+
+static int spidev_remove(struct spi_device *spi)
+{
+ struct spidev_data *spidev = dev_get_drvdata(&spi->dev);
+
+ mutex_lock(&device_list_lock);
+
+ list_del(&spidev->device_entry);
+ dev_set_drvdata(&spi->dev, NULL);
+ clear_bit(MINOR(spidev->dev.devt), minors);
+ device_unregister(&spidev->dev);
+
+ mutex_unlock(&device_list_lock);
+
+ return 0;
+}
+
+static struct spi_driver spidev_spi = {
+ .driver = {
+ .name = "spidev",
+ .owner = THIS_MODULE,
+ },
+ .probe = spidev_probe,
+ .remove = __devexit_p(spidev_remove),
+
+ /* NOTE: suspend/resume methods are not necessary here.
+ * We don't do anything except pass the requests to/from
+ * the underlying controller. The refrigerator handles
+ * most issues; the controller driver handles the rest.
+ */
+};
+
+/*-------------------------------------------------------------------------*/
+
+static int __init spidev_init(void)
+{
+ int status;
+
+ /* Claim our 256 reserved device numbers. Then register a class
+ * that will key udev/mdev to add/remove /dev nodes. Last, register
+ * the driver which manages those device numbers.
+ */
+ BUILD_BUG_ON(N_SPI_MINORS > 256);
+ status = register_chrdev(SPIDEV_MAJOR, "spi", &spidev_fops);
+ if (status < 0)
+ return status;
+
+ status = class_register(&spidev_class);
+ if (status < 0) {
+ unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name);
+ return status;
+ }
+
+ status = spi_register_driver(&spidev_spi);
+ if (status < 0) {
+ class_unregister(&spidev_class);
+ unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name);
+ }
+ return status;
+}
+module_init(spidev_init);
+
+static void __exit spidev_exit(void)
+{
+ spi_unregister_driver(&spidev_spi);
+ class_unregister(&spidev_class);
+ unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name);
+}
+module_exit(spidev_exit);
+
+MODULE_AUTHOR("Andrea Paterniani, <a.paterniani@swapp-eng.it>");
+MODULE_DESCRIPTION("User mode SPI device interface");
+MODULE_LICENSE("GPL");
diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c
index 71cb64e..c7b0a35 100644
--- a/drivers/telephony/ixj.c
+++ b/drivers/telephony/ixj.c
@@ -7692,7 +7692,7 @@
IXJ *j = NULL;
for (i = 0; i < IXJMAX - *cnt; i++) {
- pci = pci_find_device(PCI_VENDOR_ID_QUICKNET,
+ pci = pci_get_device(PCI_VENDOR_ID_QUICKNET,
PCI_DEVICE_ID_QUICKNET_XJ, pci);
if (!pci)
break;
@@ -7712,6 +7712,7 @@
printk(KERN_INFO "ixj: found Internet PhoneJACK PCI at 0x%x\n", j->DSPbase);
++*cnt;
}
+ pci_dev_put(pci);
return probe;
}
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 9980a4d..b847bbc 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -85,8 +85,6 @@
source "drivers/usb/storage/Kconfig"
-source "drivers/usb/input/Kconfig"
-
source "drivers/usb/image/Kconfig"
source "drivers/usb/net/Kconfig"
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index f5de58a..0ef090b 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -23,15 +23,6 @@
obj-$(CONFIG_USB_STORAGE) += storage/
obj-$(CONFIG_USB) += storage/
-obj-$(CONFIG_USB_ACECAD) += input/
-obj-$(CONFIG_USB_AIPTEK) += input/
-obj-$(CONFIG_USB_ATI_REMOTE) += input/
-obj-$(CONFIG_USB_KBTAB) += input/
-obj-$(CONFIG_USB_MTOUCH) += input/
-obj-$(CONFIG_USB_POWERMATE) += input/
-obj-$(CONFIG_USB_WACOM) += input/
-obj-$(CONFIG_USB_XPAD) += input/
-
obj-$(CONFIG_USB_CATC) += net/
obj-$(CONFIG_USB_KAWETH) += net/
obj-$(CONFIG_USB_PEGASUS) += net/
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c
index b3f779f..b082d95 100644
--- a/drivers/usb/atm/usbatm.c
+++ b/drivers/usb/atm/usbatm.c
@@ -77,7 +77,6 @@
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/stat.h>
#include <linux/timer.h>
#include <linux/wait.h>
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 14de3b1..0081c1d 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -59,7 +59,6 @@
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
#include <linux/module.h>
-#include <linux/smp_lock.h>
#include <linux/mutex.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index 6584cf0..15e740e 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -49,7 +49,6 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
-#include <linux/smp_lock.h>
#include <linux/signal.h>
#include <linux/poll.h>
#include <linux/init.h>
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index bde29ab..f6b74a6 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -16,7 +16,6 @@
#include <linux/sched.h>
#include <linux/list.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/ioctl.h>
#include <linux/usb.h>
#include <linux/usbdevice_fs.h>
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index cddfc62..cd4f111 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -36,7 +36,6 @@
#include <linux/usb.h>
#include <linux/namei.h>
#include <linux/usbdevice_fs.h>
-#include <linux/smp_lock.h>
#include <linux/parser.h>
#include <linux/notifier.h>
#include <asm/byteorder.h>
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index dfd1b5c..18ddc5e 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -31,7 +31,6 @@
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/errno.h>
-#include <linux/smp_lock.h>
#include <linux/usb.h>
#include <linux/mutex.h>
#include <linux/workqueue.h>
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index 2a6e316..ba163f3 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -31,7 +31,6 @@
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/list.h>
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index 7d7909c..fcb5526 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -41,7 +41,6 @@
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 1dd8b57..325bf7c 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -28,7 +28,6 @@
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c
index 65c91d3..ae931af 100644
--- a/drivers/usb/gadget/goku_udc.c
+++ b/drivers/usb/gadget/goku_udc.c
@@ -30,7 +30,6 @@
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
index 49d7377..52779c5 100644
--- a/drivers/usb/gadget/net2280.c
+++ b/drivers/usb/gadget/net2280.c
@@ -54,7 +54,6 @@
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index e552668..f847c34 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -22,7 +22,6 @@
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index 8c85e33..7078374 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -67,7 +67,6 @@
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index c7458f7..099aff6 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -24,7 +24,6 @@
#include <linux/ioport.h>
#include <linux/sched.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c
index 9310745..37b83ba 100644
--- a/drivers/usb/host/ehci-ps3.c
+++ b/drivers/usb/host/ehci-ps3.c
@@ -97,7 +97,7 @@
dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__,
__LINE__, dev->m_region->lpar_addr);
- result = ps3_alloc_io_irq(PS3_BINDING_CPU_ANY, dev->interrupt_id, &virq);
+ result = ps3_io_irq_setup(PS3_BINDING_CPU_ANY, dev->interrupt_id, &virq);
if (result) {
dev_dbg(&dev->core, "%s:%d: ps3_construct_io_irq(%d) failed.\n",
@@ -155,7 +155,7 @@
fail_ioremap:
usb_put_hcd(hcd);
fail_create_hcd:
- ps3_free_io_irq(virq);
+ ps3_io_irq_destroy(virq);
fail_irq:
ps3_free_mmio_region(dev->m_region);
fail_mmio:
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index e8bbe8b..a66637e 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -26,7 +26,6 @@
#include <linux/ioport.h>
#include <linux/sched.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c
index 08e237c..c43b66a 100644
--- a/drivers/usb/host/ohci-ppc-of.c
+++ b/drivers/usb/host/ohci-ppc-of.c
@@ -97,8 +97,8 @@
return -ENODEV;
is_bigendian =
- device_is_compatible(dn, "ohci-bigendian") ||
- device_is_compatible(dn, "ohci-be");
+ of_device_is_compatible(dn, "ohci-bigendian") ||
+ of_device_is_compatible(dn, "ohci-be");
dev_dbg(&op->dev, "initializing PPC-OF USB Controller\n");
diff --git a/drivers/usb/host/ohci-ps3.c b/drivers/usb/host/ohci-ps3.c
index c849f72..d7cf072 100644
--- a/drivers/usb/host/ohci-ps3.c
+++ b/drivers/usb/host/ohci-ps3.c
@@ -99,7 +99,7 @@
dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__,
__LINE__, dev->m_region->lpar_addr);
- result = ps3_alloc_io_irq(PS3_BINDING_CPU_ANY, dev->interrupt_id, &virq);
+ result = ps3_io_irq_setup(PS3_BINDING_CPU_ANY, dev->interrupt_id, &virq);
if (result) {
dev_dbg(&dev->core, "%s:%d: ps3_construct_io_irq(%d) failed.\n",
@@ -157,7 +157,7 @@
fail_ioremap:
usb_put_hcd(hcd);
fail_create_hcd:
- ps3_free_io_irq(virq);
+ ps3_io_irq_destroy(virq);
fail_irq:
ps3_free_mmio_region(dev->m_region);
fail_mmio:
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
index 5fa5647..4cfa3ff 100644
--- a/drivers/usb/host/sl811-hcd.c
+++ b/drivers/usb/host/sl811-hcd.c
@@ -38,7 +38,6 @@
#include <linux/ioport.h>
#include <linux/sched.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c
index a7fa0d7..ff0dba0 100644
--- a/drivers/usb/host/u132-hcd.c
+++ b/drivers/usb/host/u132-hcd.c
@@ -43,7 +43,6 @@
#include <linux/pci_ids.h>
#include <linux/sched.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c
index d308afd..36502a0 100644
--- a/drivers/usb/image/mdc800.c
+++ b/drivers/usb/image/mdc800.c
@@ -94,7 +94,6 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
-#include <linux/smp_lock.h>
#include <linux/wait.h>
#include <linux/mutex.h>
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c
index 896cb2b..51bd80d 100644
--- a/drivers/usb/image/microtek.c
+++ b/drivers/usb/image/microtek.c
@@ -128,7 +128,6 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
#include <linux/usb.h>
#include <linux/proc_fs.h>
diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
deleted file mode 100644
index a792e42..0000000
--- a/drivers/usb/input/Kconfig
+++ /dev/null
@@ -1,225 +0,0 @@
-#
-# USB Input driver configuration
-#
-comment "USB Input Devices"
- depends on USB
-
-config USB_AIPTEK
- tristate "Aiptek 6000U/8000U tablet support"
- depends on USB && INPUT
- help
- Say Y here if you want to use the USB version of the Aiptek 6000U
- or Aiptek 8000U tablet. Make sure to say Y to "Mouse support"
- (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
- (CONFIG_INPUT_EVDEV) as well.
-
- To compile this driver as a module, choose M here: the
- module will be called aiptek.
-
-config USB_WACOM
- tristate "Wacom Intuos/Graphire tablet support"
- depends on USB && INPUT
- help
- Say Y here if you want to use the USB version of the Wacom Intuos
- or Graphire tablet. Make sure to say Y to "Mouse support"
- (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
- (CONFIG_INPUT_EVDEV) as well.
-
- To compile this driver as a module, choose M here: the
- module will be called wacom.
-
-config USB_ACECAD
- tristate "Acecad Flair tablet support"
- depends on USB && INPUT
- help
- Say Y here if you want to use the USB version of the Acecad Flair
- tablet. Make sure to say Y to "Mouse support"
- (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
- (CONFIG_INPUT_EVDEV) as well.
-
- To compile this driver as a module, choose M here: the
- module will be called acecad.
-
-config USB_KBTAB
- tristate "KB Gear JamStudio tablet support"
- depends on USB && INPUT
- help
- Say Y here if you want to use the USB version of the KB Gear
- JamStudio tablet. Make sure to say Y to "Mouse support"
- (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
- (CONFIG_INPUT_EVDEV) as well.
-
- To compile this driver as a module, choose M here: the
- module will be called kbtab.
-
-config USB_POWERMATE
- tristate "Griffin PowerMate and Contour Jog support"
- depends on USB && INPUT
- ---help---
- Say Y here if you want to use Griffin PowerMate or Contour Jog devices.
- These are aluminum dials which can measure clockwise and anticlockwise
- rotation. The dial also acts as a pushbutton. The base contains an LED
- which can be instructed to pulse or to switch to a particular intensity.
-
- You can download userspace tools from
- <http://sowerbutts.com/powermate/>.
-
- To compile this driver as a module, choose M here: the
- module will be called powermate.
-
-config USB_TOUCHSCREEN
- tristate "USB Touchscreen Driver"
- depends on USB && INPUT
- ---help---
- USB Touchscreen driver for:
- - eGalax Touchkit USB (also includes eTurboTouch CT-410/510/700)
- - PanJit TouchSet USB
- - 3M MicroTouch USB (EX II series)
- - ITM
- - some other eTurboTouch
- - Gunze AHL61
- - DMC TSC-10/25
-
- Have a look at <http://linux.chapter7.ch/touchkit/> for
- a usage description and the required user-space stuff.
-
- To compile this driver as a module, choose M here: the
- module will be called usbtouchscreen.
-
-config USB_TOUCHSCREEN_EGALAX
- default y
- bool "eGalax, eTurboTouch CT-410/510/700 device support" if EMBEDDED
- depends on USB_TOUCHSCREEN
-
-config USB_TOUCHSCREEN_PANJIT
- default y
- bool "PanJit device support" if EMBEDDED
- depends on USB_TOUCHSCREEN
-
-config USB_TOUCHSCREEN_3M
- default y
- bool "3M/Microtouch EX II series device support" if EMBEDDED
- depends on USB_TOUCHSCREEN
-
-config USB_TOUCHSCREEN_ITM
- default y
- bool "ITM device support" if EMBEDDED
- depends on USB_TOUCHSCREEN
-
-config USB_TOUCHSCREEN_ETURBO
- default y
- bool "eTurboTouch (non-eGalax compatible) device support" if EMBEDDED
- depends on USB_TOUCHSCREEN
-
-config USB_TOUCHSCREEN_GUNZE
- default y
- bool "Gunze AHL61 device support" if EMBEDDED
- depends on USB_TOUCHSCREEN
-
-config USB_TOUCHSCREEN_DMC_TSC10
- default y
- bool "DMC TSC-10/25 device support" if EMBEDDED
- depends on USB_TOUCHSCREEN
-
-config USB_YEALINK
- tristate "Yealink usb-p1k voip phone"
- depends on USB && INPUT && EXPERIMENTAL
- ---help---
- Say Y here if you want to enable keyboard and LCD functions of the
- Yealink usb-p1k usb phones. The audio part is enabled by the generic
- usb sound driver, so you might want to enable that as well.
-
- For information about how to use these additional functions, see
- <file:Documentation/input/yealink.txt>.
-
- To compile this driver as a module, choose M here: the module will be
- called yealink.
-
-config USB_XPAD
- tristate "X-Box gamepad support"
- depends on USB && INPUT
- ---help---
- Say Y here if you want to use the X-Box pad with your computer.
- Make sure to say Y to "Joystick support" (CONFIG_INPUT_JOYDEV)
- and/or "Event interface support" (CONFIG_INPUT_EVDEV) as well.
-
- For information about how to connect the X-Box pad to USB, see
- <file:Documentation/input/xpad.txt>.
-
- To compile this driver as a module, choose M here: the
- module will be called xpad.
-
-config USB_ATI_REMOTE
- tristate "ATI / X10 USB RF remote control"
- depends on USB && INPUT
- ---help---
- Say Y here if you want to use an ATI or X10 "Lola" USB remote control.
- These are RF remotes with USB receivers.
- The ATI remote comes with many of ATI's All-In-Wonder video cards.
- The X10 "Lola" remote is available at:
- <http://www.x10.com/products/lola_sg1.htm>
- This driver provides mouse pointer, left and right mouse buttons,
- and maps all the other remote buttons to keypress events.
-
- To compile this driver as a module, choose M here: the module will be
- called ati_remote.
-
-config USB_ATI_REMOTE2
- tristate "ATI / Philips USB RF remote control"
- depends on USB && INPUT
- ---help---
- Say Y here if you want to use an ATI or Philips USB RF remote control.
- These are RF remotes with USB receivers.
- ATI Remote Wonder II comes with some ATI's All-In-Wonder video cards
- and is also available as a separate product.
- This driver provides mouse pointer, left and right mouse buttons,
- and maps all the other remote buttons to keypress events.
-
- To compile this driver as a module, choose M here: the module will be
- called ati_remote2.
-
-config USB_KEYSPAN_REMOTE
- tristate "Keyspan DMR USB remote control (EXPERIMENTAL)"
- depends on USB && INPUT && EXPERIMENTAL
- ---help---
- Say Y here if you want to use a Keyspan DMR USB remote control.
- Currently only the UIA-11 type of receiver has been tested. The tag
- on the receiver that connects to the USB port should have a P/N that
- will tell you what type of DMR you have. The UIA-10 type is not
- supported at this time. This driver maps all buttons to keypress
- events.
-
- To compile this driver as a module, choose M here: the module will
- be called keyspan_remote.
-
-config USB_APPLETOUCH
- tristate "Apple USB Touchpad support"
- depends on USB && INPUT
- ---help---
- Say Y here if you want to use an Apple USB Touchpad.
-
- These are the touchpads that can be found on post-February 2005
- Apple Powerbooks (prior models have a Synaptics touchpad connected
- to the ADB bus).
-
- This driver provides a basic mouse driver but can be interfaced
- with the synaptics X11 driver to provide acceleration and
- scrolling in X11.
-
- For further information, see
- <file:Documentation/input/appletouch.txt>.
-
- To compile this driver as a module, choose M here: the
- module will be called appletouch.
-
-config USB_GTCO
- tristate "GTCO CalComp/InterWrite USB Support"
- depends on USB && INPUT
- ---help---
- Say Y here if you want to use the USB version of the GTCO
- CalComp/InterWrite Tablet. Make sure to say Y to "Mouse support"
- (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
- (CONFIG_INPUT_EVDEV) as well.
-
- To compile this driver as a module, choose M here: the
- module will be called gtco.
diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile
deleted file mode 100644
index 284a073..0000000
--- a/drivers/usb/input/Makefile
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# Makefile for the USB input drivers
-#
-
-# Multipart objects.
-wacom-objs := wacom_wac.o wacom_sys.o
-
-obj-$(CONFIG_USB_AIPTEK) += aiptek.o
-obj-$(CONFIG_USB_ATI_REMOTE) += ati_remote.o
-obj-$(CONFIG_USB_ATI_REMOTE2) += ati_remote2.o
-obj-$(CONFIG_USB_KBTAB) += kbtab.o
-obj-$(CONFIG_USB_KEYSPAN_REMOTE) += keyspan_remote.o
-obj-$(CONFIG_USB_TOUCHSCREEN) += usbtouchscreen.o
-obj-$(CONFIG_USB_POWERMATE) += powermate.o
-obj-$(CONFIG_USB_WACOM) += wacom.o
-obj-$(CONFIG_USB_ACECAD) += acecad.o
-obj-$(CONFIG_USB_YEALINK) += yealink.o
-obj-$(CONFIG_USB_XPAD) += xpad.o
-obj-$(CONFIG_USB_APPLETOUCH) += appletouch.o
-obj-$(CONFIG_USB_GTCO) += gtco.o
-
-ifeq ($(CONFIG_USB_DEBUG),y)
-EXTRA_CFLAGS += -DDEBUG
-endif
diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c
index 15c70bd..8d0e360 100644
--- a/drivers/usb/misc/idmouse.c
+++ b/drivers/usb/misc/idmouse.c
@@ -22,7 +22,6 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
-#include <linux/smp_lock.h>
#include <linux/completion.h>
#include <linux/mutex.h>
#include <asm/uaccess.h>
diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c
index 5dce797..1713e19 100644
--- a/drivers/usb/misc/legousbtower.c
+++ b/drivers/usb/misc/legousbtower.c
@@ -80,7 +80,6 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
-#include <linux/smp_lock.h>
#include <linux/completion.h>
#include <linux/mutex.h>
#include <asm/uaccess.h>
diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c
index fdf6847..88f6abe 100644
--- a/drivers/usb/misc/rio500.c
+++ b/drivers/usb/misc/rio500.c
@@ -39,7 +39,6 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/usb.h>
-#include <linux/smp_lock.h>
#include <linux/wait.h>
#include "rio500_usb.h"
diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c
index 1730d86..5947afb 100644
--- a/drivers/usb/misc/sisusbvga/sisusb_con.c
+++ b/drivers/usb/misc/sisusbvga/sisusb_con.c
@@ -62,7 +62,6 @@
#include <linux/selection.h>
#include <linux/spinlock.h>
#include <linux/kref.h>
-#include <linux/smp_lock.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/vmalloc.h>
@@ -322,7 +321,7 @@
/* interface routine */
static u8
sisusbcon_build_attr(struct vc_data *c, u8 color, u8 intensity,
- u8 blink, u8 underline, u8 reverse)
+ u8 blink, u8 underline, u8 reverse, u8 unused)
{
u8 attr = color;
diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c
index 8a1df2c..8977ec0 100644
--- a/drivers/usb/mon/mon_main.c
+++ b/drivers/usb/mon/mon_main.c
@@ -9,7 +9,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/usb.h>
-#include <linux/smp_lock.h>
#include <linux/notifier.h>
#include <linux/mutex.h>
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 7639022..87f3788 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -28,7 +28,6 @@
#include <linux/spinlock.h>
#include <linux/mutex.h>
#include <linux/list.h>
-#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
index 21f3ddb..6dac1ff 100644
--- a/drivers/usb/storage/usb.h
+++ b/drivers/usb/storage/usb.h
@@ -47,7 +47,6 @@
#include <linux/usb.h>
#include <linux/usb_usual.h>
#include <linux/blkdev.h>
-#include <linux/smp_lock.h>
#include <linux/completion.h>
#include <linux/mutex.h>
#include <scsi/scsi_host.h>
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 344c375..1132ba5 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -5,6 +5,11 @@
menu "Graphics support"
source "drivers/video/backlight/Kconfig"
+source "drivers/video/display/Kconfig"
+
+config VGASTATE
+ tristate
+ default n
config FB
tristate "Support for frame buffer devices"
@@ -90,6 +95,43 @@
blitting. This is used by drivers that don't provide their own
(accelerated) version.
+config FB_SYS_FILLRECT
+ tristate
+ depends on FB
+ default n
+ ---help---
+ Include the sys_fillrect function for generic software rectangle
+ filling. This is used by drivers that don't provide their own
+ (accelerated) version and the framebuffer is in system RAM.
+
+config FB_SYS_COPYAREA
+ tristate
+ depends on FB
+ default n
+ ---help---
+ Include the sys_copyarea function for generic software area copying.
+ This is used by drivers that don't provide their own (accelerated)
+ version and the framebuffer is in system RAM.
+
+config FB_SYS_IMAGEBLIT
+ tristate
+ depends on FB
+ default n
+ ---help---
+ Include the sys_imageblit function for generic software image
+ blitting. This is used by drivers that don't provide their own
+ (accelerated) version and the framebuffer is in system RAM.
+
+config FB_SYS_FOPS
+ tristate
+ depends on FB
+ default n
+
+config FB_DEFERRED_IO
+ bool
+ depends on FB
+ default y
+
config FB_SVGALIB
tristate
depends on FB
@@ -375,9 +417,10 @@
config FB_ARC
tristate "Arc Monochrome LCD board support"
depends on FB && X86
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
help
This enables support for the Arc Monochrome LCD board. The board
is based on the KS-108 lcd controller and is typically a matrix
@@ -475,6 +518,8 @@
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
+ select VGASTATE
+ select FONT_8x16 if FRAMEBUFFER_CONSOLE
help
This is the frame buffer device driver for VGA 16 color graphic
cards. Say Y if you have such a card.
@@ -519,15 +564,25 @@
default y
config FB_TGA
- tristate "TGA framebuffer support"
- depends on FB && ALPHA
+ tristate "TGA/SFB+ framebuffer support"
+ depends on FB && (ALPHA || TC)
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select BITREVERSE
- help
- This is the frame buffer device driver for generic TGA graphic
- cards. Say Y if you have one of those.
+ ---help---
+ This is the frame buffer device driver for generic TGA and SFB+
+ graphic cards. These include DEC ZLXp-E1, -E2 and -E3 PCI cards,
+ also known as PBXGA-A, -B and -C, and DEC ZLX-E1, -E2 and -E3
+ TURBOchannel cards, also known as PMAGD-A, -B and -C.
+
+ Due to hardware limitations ZLX-E2 and E3 cards are not supported
+ for DECstation 5000/200 systems. Additionally due to firmware
+ limitations these cards may cause troubles with booting DECstation
+ 5000/240 and /260 systems, but are fully supported under Linux if
+ you manage to get it going. ;-)
+
+ Say Y if you have one of those.
config FB_VESA
bool "VESA VGA graphics support"
@@ -551,6 +606,21 @@
help
This is the frame buffer device driver for the Intel-based Macintosh
+config FB_HECUBA
+ tristate "Hecuba board support"
+ depends on FB && X86 && MMU
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ select FB_DEFERRED_IO
+ help
+ This enables support for the Hecuba board. This driver was tested
+ with an E-Ink 800x600 display and x86 SBCs through a 16 bit GPIO
+ interface (8 bit data, 4 bit control). If you anticpate using
+ this driver, say Y or M; otherwise say N. You must specify the
+ GPIO IO address to be used for setting control and data.
+
config FB_HGA
tristate "Hercules mono graphics support"
depends on FB && X86
@@ -686,6 +756,7 @@
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select BITREVERSE
+ select VGASTATE
help
This driver supports graphics boards with the nVidia chips, TNT
and newer. For very old chipsets, such as the RIVA128, then use
@@ -724,6 +795,7 @@
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select BITREVERSE
+ select VGASTATE
help
This driver supports graphics boards with the nVidia Riva/Geforce
chips.
@@ -770,6 +842,7 @@
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
+ select VGASTATE
help
This driver supports the on-board graphics built in to the Intel 810
and 815 chipsets. Say Y if you have and plan to use such a board.
@@ -809,6 +882,22 @@
select FB_DDC
help
+config FB_LE80578
+ tristate "Intel LE80578 (Vermilion) support"
+ depends on FB && PCI && X86
+ select FB_MODE_HELPERS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This driver supports the LE80578 (Vermilion Range) chipset
+
+config FB_CARILLO_RANCH
+ tristate "Intel Carillo Ranch support"
+ depends on FB_LE80578 && FB && PCI && X86
+ help
+ This driver supports the LE80578 (Carillo Ranch) board
+
config FB_INTEL
tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G support (EXPERIMENTAL)"
depends on FB && EXPERIMENTAL && PCI && X86
@@ -1120,6 +1209,8 @@
select FB_CFB_IMAGEBLIT
select FB_TILEBLITTING
select FB_SVGALIB
+ select VGASTATE
+ select FONT_8x16 if FRAMEBUFFER_CONSOLE
---help---
Driver for graphics boards with S3 Trio / S3 Virge chip.
@@ -1130,6 +1221,7 @@
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
+ select VGASTATE
help
This driver supports notebooks and computers with S3 Savage PCI/AGP
chips.
@@ -1196,6 +1288,7 @@
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
+ select VGASTATE
help
This driver supports notebooks with NeoMagic PCI chips.
Say Y if you have such a graphics card.
@@ -1662,13 +1755,25 @@
The default value can be overridden on the kernel command line
using the "ps3fb" option (e.g. "ps3fb=9M");
-config FB_VIRTUAL
- tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
- depends on FB
+config FB_XILINX
+ tristate "Xilinx frame buffer support"
+ depends on FB && XILINX_VIRTEX
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
---help---
+ Include support for the Xilinx ML300/ML403 reference design
+ framebuffer. ML300 carries a 640*480 LCD display on the board,
+ ML403 uses a standard DB15 VGA connector.
+
+config FB_VIRTUAL
+ tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
+ depends on FB
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ ---help---
This is a `virtual' frame buffer device. It operates on a chunk of
unswappable kernel memory instead of on the memory of a graphics
board. This means you cannot see any output sent to this frame
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 558473d..a916c20 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -4,6 +4,7 @@
# Each configuration option enables a list of files.
+obj-$(CONFIG_VGASTATE) += vgastate.o
obj-y += fb_notify.o
obj-$(CONFIG_FB) += fb.o
fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \
@@ -12,14 +13,19 @@
obj-$(CONFIG_VT) += console/
obj-$(CONFIG_LOGO) += logo/
-obj-y += backlight/
+obj-y += backlight/ display/
obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o
obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o
obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o
+obj-$(CONFIG_FB_SYS_FILLRECT) += sysfillrect.o
+obj-$(CONFIG_FB_SYS_COPYAREA) += syscopyarea.o
+obj-$(CONFIG_FB_SYS_IMAGEBLIT) += sysimgblt.o
+obj-$(CONFIG_FB_SYS_FOPS) += fb_sys_fops.o
obj-$(CONFIG_FB_SVGALIB) += svgalib.o
obj-$(CONFIG_FB_MACMODES) += macmodes.o
obj-$(CONFIG_FB_DDC) += fb_ddc.o
+obj-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o
# Hardware specific drivers go first
obj-$(CONFIG_FB_AMIGA) += amifb.o c2p.o
@@ -30,7 +36,7 @@
obj-$(CONFIG_FB_PM3) += pm3fb.o
obj-$(CONFIG_FB_MATROX) += matrox/
-obj-$(CONFIG_FB_RIVA) += riva/ vgastate.o
+obj-$(CONFIG_FB_RIVA) += riva/
obj-$(CONFIG_FB_NVIDIA) += nvidia/
obj-$(CONFIG_FB_ATY) += aty/ macmodes.o
obj-$(CONFIG_FB_ATY128) += aty/ macmodes.o
@@ -40,8 +46,7 @@
obj-$(CONFIG_FB_SAVAGE) += savage/
obj-$(CONFIG_FB_GEODE) += geode/
obj-$(CONFIG_FB_MBX) += mbx/
-obj-$(CONFIG_FB_I810) += vgastate.o
-obj-$(CONFIG_FB_NEOMAGIC) += neofb.o vgastate.o
+obj-$(CONFIG_FB_NEOMAGIC) += neofb.o
obj-$(CONFIG_FB_3DFX) += tdfxfb.o
obj-$(CONFIG_FB_CONTROL) += controlfb.o
obj-$(CONFIG_FB_PLATINUM) += platinumfb.o
@@ -51,7 +56,8 @@
obj-$(CONFIG_FB_FM2) += fm2fb.o
obj-$(CONFIG_FB_CYBLA) += cyblafb.o
obj-$(CONFIG_FB_TRIDENT) += tridentfb.o
-obj-$(CONFIG_FB_S3) += s3fb.o vgastate.o
+obj-$(CONFIG_FB_LE80578) += vermilion/
+obj-$(CONFIG_FB_S3) += s3fb.o
obj-$(CONFIG_FB_STI) += stifb.o
obj-$(CONFIG_FB_FFB) += ffb.o sbuslib.o
obj-$(CONFIG_FB_CG6) += cg6.o sbuslib.o
@@ -66,6 +72,7 @@
obj-$(CONFIG_FB_ATARI) += atafb.o c2p.o atafb_mfb.o \
atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o
obj-$(CONFIG_FB_MAC) += macfb.o
+obj-$(CONFIG_FB_HECUBA) += hecubafb.o
obj-$(CONFIG_FB_HGA) += hgafb.o
obj-$(CONFIG_FB_XVR500) += sunxvr500.o
obj-$(CONFIG_FB_XVR2500) += sunxvr2500.o
@@ -102,11 +109,12 @@
obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o
obj-$(CONFIG_FB_PS3) += ps3fb.o
obj-$(CONFIG_FB_SM501) += sm501fb.o
+obj-$(CONFIG_FB_XILINX) += xilinxfb.o
# Platform or fallback drivers go here
obj-$(CONFIG_FB_VESA) += vesafb.o
obj-$(CONFIG_FB_IMAC) += imacfb.o
-obj-$(CONFIG_FB_VGA16) += vga16fb.o vgastate.o
+obj-$(CONFIG_FB_VGA16) += vga16fb.o
obj-$(CONFIG_FB_OF) += offb.o
# the test framebuffer is last
diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c
index 30a83697..db15bac 100644
--- a/drivers/video/arcfb.c
+++ b/drivers/video/arcfb.c
@@ -262,7 +262,8 @@
ks108_set_yaddr(par, chipindex, upper/8);
linesize = par->info->var.xres/8;
- src = par->info->screen_base + (left/8) + (upper * linesize);
+ src = (unsigned char __force *) par->info->screen_base + (left/8) +
+ (upper * linesize);
ks108_set_xaddr(par, chipindex, left);
bitmask=1;
@@ -368,7 +369,7 @@
{
struct arcfb_par *par = info->par;
- cfb_fillrect(info, rect);
+ sys_fillrect(info, rect);
/* update the physical lcd */
arcfb_lcd_update(par, rect->dx, rect->dy, rect->width, rect->height);
@@ -379,7 +380,7 @@
{
struct arcfb_par *par = info->par;
- cfb_copyarea(info, area);
+ sys_copyarea(info, area);
/* update the physical lcd */
arcfb_lcd_update(par, area->dx, area->dy, area->width, area->height);
@@ -389,7 +390,7 @@
{
struct arcfb_par *par = info->par;
- cfb_imageblit(info, image);
+ sys_imageblit(info, image);
/* update the physical lcd */
arcfb_lcd_update(par, image->dx, image->dy, image->width,
@@ -439,14 +440,11 @@
* the fb. it's inefficient for them to do anything less than 64*8
* writes since we update the lcd in each write() anyway.
*/
-static ssize_t arcfb_write(struct file *file, const char __user *buf, size_t count,
- loff_t *ppos)
+static ssize_t arcfb_write(struct fb_info *info, const char __user *buf,
+ size_t count, loff_t *ppos)
{
/* modded from epson 1355 */
- struct inode *inode;
- int fbidx;
- struct fb_info *info;
unsigned long p;
int err=-EINVAL;
unsigned int fbmemlength,x,y,w,h, bitppos, startpos, endpos, bitcount;
@@ -454,13 +452,6 @@
unsigned int xres;
p = *ppos;
- inode = file->f_path.dentry->d_inode;
- fbidx = iminor(inode);
- info = registered_fb[fbidx];
-
- if (!info || !info->screen_base)
- return -ENODEV;
-
par = info->par;
xres = info->var.xres;
fbmemlength = (xres * info->var.yres)/8;
@@ -477,7 +468,7 @@
if (count) {
char *base_addr;
- base_addr = info->screen_base;
+ base_addr = (char __force *)info->screen_base;
count -= copy_from_user(base_addr + p, buf, count);
*ppos += count;
err = -EFAULT;
@@ -503,6 +494,7 @@
static struct fb_ops arcfb_ops = {
.owner = THIS_MODULE,
.fb_open = arcfb_open,
+ .fb_read = fb_sys_read,
.fb_write = arcfb_write,
.fb_release = arcfb_release,
.fb_pan_display = arcfb_pan_display,
@@ -603,7 +595,7 @@
if (info) {
unregister_framebuffer(info);
- vfree(info->screen_base);
+ vfree((void __force *)info->screen_base);
framebuffer_release(info);
}
return 0;
diff --git a/drivers/video/aty/ati_ids.h b/drivers/video/aty/ati_ids.h
index 39ab483..90e7df2 100644
--- a/drivers/video/aty/ati_ids.h
+++ b/drivers/video/aty/ati_ids.h
@@ -209,4 +209,4 @@
#define PCI_CHIP_R423_5D57 0x5D57
#define PCI_CHIP_RS350_7834 0x7834
#define PCI_CHIP_RS350_7835 0x7835
-
+#define PCI_CHIP_RS480_5955 0x5955
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index e86d7e0..7fea4d8 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -2165,18 +2165,29 @@
static int aty128fb_blank(int blank, struct fb_info *fb)
{
struct aty128fb_par *par = fb->par;
- u8 state = 0;
+ u8 state;
if (par->lock_blank || par->asleep)
return 0;
- if (blank & FB_BLANK_VSYNC_SUSPEND)
- state |= 2;
- if (blank & FB_BLANK_HSYNC_SUSPEND)
- state |= 1;
- if (blank & FB_BLANK_POWERDOWN)
- state |= 4;
-
+ switch (blank) {
+ case FB_BLANK_NORMAL:
+ state = 4;
+ break;
+ case FB_BLANK_VSYNC_SUSPEND:
+ state = 6;
+ break;
+ case FB_BLANK_HSYNC_SUSPEND:
+ state = 5;
+ break;
+ case FB_BLANK_POWERDOWN:
+ state = 7;
+ break;
+ case FB_BLANK_UNBLANK:
+ default:
+ state = 0;
+ break;
+ }
aty_st_8(CRTC_EXT_CNTL+1, state);
if (par->chip_gen == rage_M3) {
@@ -2430,7 +2441,7 @@
wait_for_idle(par);
/* Blank display and LCD */
- aty128fb_blank(VESA_POWERDOWN, info);
+ aty128fb_blank(FB_BLANK_POWERDOWN, info);
/* Sleep */
par->asleep = 1;
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 8514f2a..ea67dd9 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -2297,20 +2297,6 @@
par->pll_limits.xclk = 53;
}
#endif
- if (pll)
- par->pll_limits.pll_max = pll;
- if (mclk)
- par->pll_limits.mclk = mclk;
- if (xclk)
- par->pll_limits.xclk = xclk;
-
- aty_calc_mem_refresh(par, par->pll_limits.xclk);
- par->pll_per = 1000000/par->pll_limits.pll_max;
- par->mclk_per = 1000000/par->pll_limits.mclk;
- par->xclk_per = 1000000/par->pll_limits.xclk;
-
- par->ref_clk_per = 1000000000000ULL / 14318180;
- xtal = "14.31818";
#ifdef CONFIG_FB_ATY_GX
if (!M64_HAS(INTEGRATED)) {
@@ -2338,6 +2324,7 @@
case DAC_IBMRGB514:
par->dac_ops = &aty_dac_ibm514;
break;
+#ifdef CONFIG_ATARI
case DAC_ATI68860_B:
case DAC_ATI68860_C:
par->dac_ops = &aty_dac_ati68860b;
@@ -2346,6 +2333,7 @@
case DAC_ATT21C498:
par->dac_ops = &aty_dac_att21c498;
break;
+#endif
default:
PRINTKI("aty_init: DAC type not implemented yet!\n");
par->dac_ops = &aty_dac_unsupported;
@@ -2389,8 +2377,29 @@
/* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */
if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM)
par->pll_limits.mclk = 63;
+ /* Mobility + 32bit memory interface need halved XCLK. */
+ if (M64_HAS(MOBIL_BUS) && par->ram_type == SDRAM32)
+ par->pll_limits.xclk = (par->pll_limits.xclk + 1) >> 1;
}
+#endif
+ /* Allow command line to override clocks. */
+ if (pll)
+ par->pll_limits.pll_max = pll;
+ if (mclk)
+ par->pll_limits.mclk = mclk;
+ if (xclk)
+ par->pll_limits.xclk = xclk;
+
+ aty_calc_mem_refresh(par, par->pll_limits.xclk);
+ par->pll_per = 1000000/par->pll_limits.pll_max;
+ par->mclk_per = 1000000/par->pll_limits.mclk;
+ par->xclk_per = 1000000/par->pll_limits.xclk;
+
+ par->ref_clk_per = 1000000000000ULL / 14318180;
+ xtal = "14.31818";
+
+#ifdef CONFIG_FB_ATY_CT
if (M64_HAS(GTB_DSP)) {
u8 pll_ref_div = aty_ld_pll_ct(PLL_REF_DIV, par);
diff --git a/drivers/video/aty/mach64_ct.c b/drivers/video/aty/mach64_ct.c
index 1fdcfdb..cc9e977 100644
--- a/drivers/video/aty/mach64_ct.c
+++ b/drivers/video/aty/mach64_ct.c
@@ -608,12 +608,10 @@
aty_st_pll_ct(SCLK_FB_DIV, pll->ct.sclk_fb_div, par);
aty_st_pll_ct(SPLL_CNTL2, pll->ct.spll_cntl2, par);
/*
- * The sclk has been started. However, I believe the first clock
- * ticks it generates are not very stable. Hope this primitive loop
- * helps for Rage Mobilities that sometimes crash when
- * we switch to sclk. (Daniel Mantione, 13-05-2003)
+ * SCLK has been started. Wait for the PLL to lock. 5 ms
+ * should be enough according to mach64 programmer's guide.
*/
- udelay(500);
+ mdelay(5);
}
aty_st_pll_ct(PLL_REF_DIV, pll->ct.pll_ref_div, par);
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index a4b3fd1..2ce0501 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -100,6 +100,8 @@
{ PCI_VENDOR_ID_ATI, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (flags) | (CHIP_FAMILY_##family) }
static struct pci_device_id radeonfb_pci_table[] = {
+ /* Radeon Xpress 200m */
+ CHIP_DEF(PCI_CHIP_RS480_5955, RS480, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY),
/* Mobility M6 */
CHIP_DEF(PCI_CHIP_RADEON_LY, RV100, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
CHIP_DEF(PCI_CHIP_RADEON_LZ, RV100, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
@@ -422,7 +424,7 @@
if (dp == NULL)
return -ENODEV;
- val = get_property(dp, "ATY,RefCLK", NULL);
+ val = of_get_property(dp, "ATY,RefCLK", NULL);
if (!val || !*val) {
printk(KERN_WARNING "radeonfb: No ATY,RefCLK property !\n");
return -EINVAL;
@@ -430,11 +432,11 @@
rinfo->pll.ref_clk = (*val) / 10;
- val = get_property(dp, "ATY,SCLK", NULL);
+ val = of_get_property(dp, "ATY,SCLK", NULL);
if (val && *val)
rinfo->pll.sclk = (*val) / 10;
- val = get_property(dp, "ATY,MCLK", NULL);
+ val = of_get_property(dp, "ATY,MCLK", NULL);
if (val && *val)
rinfo->pll.mclk = (*val) / 10;
@@ -1994,7 +1996,8 @@
/* framebuffer size */
if ((rinfo->family == CHIP_FAMILY_RS100) ||
(rinfo->family == CHIP_FAMILY_RS200) ||
- (rinfo->family == CHIP_FAMILY_RS300)) {
+ (rinfo->family == CHIP_FAMILY_RS300) ||
+ (rinfo->family == CHIP_FAMILY_RS480) ) {
u32 tom = INREG(NB_TOM);
tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024);
diff --git a/drivers/video/aty/radeon_monitor.c b/drivers/video/aty/radeon_monitor.c
index 737b5c0..2030ed8 100644
--- a/drivers/video/aty/radeon_monitor.c
+++ b/drivers/video/aty/radeon_monitor.c
@@ -70,7 +70,7 @@
int i, mt = MT_NONE;
RTRACE("analyzing OF properties...\n");
- pmt = get_property(dp, "display-type", NULL);
+ pmt = of_get_property(dp, "display-type", NULL);
if (!pmt)
return MT_NONE;
RTRACE("display-type: %s\n", pmt);
@@ -89,7 +89,7 @@
}
for (i = 0; propnames[i] != NULL; ++i) {
- pedid = get_property(dp, propnames[i], NULL);
+ pedid = of_get_property(dp, propnames[i], NULL);
if (pedid != NULL)
break;
}
@@ -98,9 +98,10 @@
* single-head cards have hdno == -1 and skip this step
*/
if (pedid == NULL && dp->parent && (hdno != -1))
- pedid = get_property(dp->parent, (hdno == 0) ? "EDID1" : "EDID2", NULL);
+ pedid = of_get_property(dp->parent,
+ (hdno == 0) ? "EDID1" : "EDID2", NULL);
if (pedid == NULL && dp->parent && (hdno == 0))
- pedid = get_property(dp->parent, "EDID", NULL);
+ pedid = of_get_property(dp->parent, "EDID", NULL);
if (pedid == NULL)
return mt;
@@ -130,7 +131,7 @@
do {
if (!dp)
return MT_NONE;
- pname = get_property(dp, "name", NULL);
+ pname = of_get_property(dp, "name", NULL);
if (!pname)
return MT_NONE;
len = strlen(pname);
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c
index c411293..be1d57b 100644
--- a/drivers/video/aty/radeon_pm.c
+++ b/drivers/video/aty/radeon_pm.c
@@ -1290,7 +1290,7 @@
if (rinfo->of_node != NULL) {
int size;
- mrtable = get_property(rinfo->of_node, "ATY,MRT", &size);
+ mrtable = of_get_property(rinfo->of_node, "ATY,MRT", &size);
if (mrtable)
mrtable_size = size >> 2;
else
@@ -2826,11 +2826,15 @@
rinfo->pm_reg = pci_find_capability(rinfo->pdev, PCI_CAP_ID_PM);
/* Enable/Disable dynamic clocks: TODO add sysfs access */
- rinfo->dynclk = dynclk;
- if (dynclk == 1) {
+ if (rinfo->family == CHIP_FAMILY_RS480)
+ rinfo->dynclk = -1;
+ else
+ rinfo->dynclk = dynclk;
+
+ if (rinfo->dynclk == 1) {
radeon_pm_enable_dynamic_mode(rinfo);
printk("radeonfb: Dynamic Clock Power Management enabled\n");
- } else if (dynclk == 0) {
+ } else if (rinfo->dynclk == 0) {
radeon_pm_disable_dynamic_mode(rinfo);
printk("radeonfb: Dynamic Clock Power Management disabled\n");
}
diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h
index 3190003..7ebffcd 100644
--- a/drivers/video/aty/radeonfb.h
+++ b/drivers/video/aty/radeonfb.h
@@ -48,6 +48,7 @@
CHIP_FAMILY_RV350,
CHIP_FAMILY_RV380, /* RV370/RV380/M22/M24 */
CHIP_FAMILY_R420, /* R420/R423/M18 */
+ CHIP_FAMILY_RS480,
CHIP_FAMILY_LAST,
};
@@ -64,7 +65,8 @@
((rinfo)->family == CHIP_FAMILY_RV350) || \
((rinfo)->family == CHIP_FAMILY_R350) || \
((rinfo)->family == CHIP_FAMILY_RV380) || \
- ((rinfo)->family == CHIP_FAMILY_R420))
+ ((rinfo)->family == CHIP_FAMILY_R420) || \
+ ((rinfo)->family == CHIP_FAMILY_RS480) )
/*
* Chip flags
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 47d15b5..fbef663 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -63,3 +63,11 @@
help
If you have a Frontpath ProGear say Y to enable the
backlight driver.
+
+config BACKLIGHT_CARILLO_RANCH
+ tristate "Intel Carillo Ranch Backlight Driver"
+ depends on BACKLIGHT_CLASS_DEVICE && LCD_CLASS_DEVICE && PCI && X86 && FB_LE80578
+ default n
+ help
+ If you have a Intel LE80578 (Carillo Ranch) say Y to enable the
+ backlight driver.
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 0c3ce46..c6e2266 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -6,3 +6,4 @@
obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o
obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o
+obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
diff --git a/drivers/video/backlight/cr_bllcd.c b/drivers/video/backlight/cr_bllcd.c
new file mode 100644
index 0000000..e9bbc34
--- /dev/null
+++ b/drivers/video/backlight/cr_bllcd.c
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) Intel Corp. 2007.
+ * All Rights Reserved.
+ *
+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ * develop this driver.
+ *
+ * This file is part of the Carillo Ranch video subsystem driver.
+ * The Carillo Ranch video subsystem driver is free software;
+ * you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The Carillo Ranch video subsystem driver is distributed
+ * in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this driver; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors:
+ * Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
+ * Alan Hourihane <alanh-at-tungstengraphics-dot-com>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/lcd.h>
+#include <linux/pci.h>
+#include <asm/uaccess.h>
+
+/* The LVDS- and panel power controls sits on the
+ * GPIO port of the ISA bridge.
+ */
+
+#define CRVML_DEVICE_LPC 0x27B8
+#define CRVML_REG_GPIOBAR 0x48
+#define CRVML_REG_GPIOEN 0x4C
+#define CRVML_GPIOEN_BIT (1 << 4)
+#define CRVML_PANEL_PORT 0x38
+#define CRVML_LVDS_ON 0x00000001
+#define CRVML_PANEL_ON 0x00000002
+#define CRVML_BACKLIGHT_OFF 0x00000004
+
+/* The PLL Clock register sits on Host bridge */
+#define CRVML_DEVICE_MCH 0x5001
+#define CRVML_REG_MCHBAR 0x44
+#define CRVML_REG_MCHEN 0x54
+#define CRVML_MCHEN_BIT (1 << 28)
+#define CRVML_MCHMAP_SIZE 4096
+#define CRVML_REG_CLOCK 0xc3c
+#define CRVML_CLOCK_SHIFT 8
+#define CRVML_CLOCK_MASK 0x00000f00
+
+static struct pci_dev *lpc_dev;
+static u32 gpio_bar;
+
+struct cr_panel {
+ struct backlight_device *cr_backlight_device;
+ struct lcd_device *cr_lcd_device;
+};
+
+static int cr_backlight_set_intensity(struct backlight_device *bd)
+{
+ int intensity = bd->props.brightness;
+ u32 addr = gpio_bar + CRVML_PANEL_PORT;
+ u32 cur = inl(addr);
+
+ if (bd->props.power == FB_BLANK_UNBLANK)
+ intensity = FB_BLANK_UNBLANK;
+ if (bd->props.fb_blank == FB_BLANK_UNBLANK)
+ intensity = FB_BLANK_UNBLANK;
+ if (bd->props.power == FB_BLANK_POWERDOWN)
+ intensity = FB_BLANK_POWERDOWN;
+ if (bd->props.fb_blank == FB_BLANK_POWERDOWN)
+ intensity = FB_BLANK_POWERDOWN;
+
+ if (intensity == FB_BLANK_UNBLANK) { /* FULL ON */
+ cur &= ~CRVML_BACKLIGHT_OFF;
+ outl(cur, addr);
+ } else if (intensity == FB_BLANK_POWERDOWN) { /* OFF */
+ cur |= CRVML_BACKLIGHT_OFF;
+ outl(cur, addr);
+ } /* anything else, don't bother */
+
+ return 0;
+}
+
+static int cr_backlight_get_intensity(struct backlight_device *bd)
+{
+ u32 addr = gpio_bar + CRVML_PANEL_PORT;
+ u32 cur = inl(addr);
+ u8 intensity;
+
+ if (cur & CRVML_BACKLIGHT_OFF)
+ intensity = FB_BLANK_POWERDOWN;
+ else
+ intensity = FB_BLANK_UNBLANK;
+
+ return intensity;
+}
+
+static struct backlight_ops cr_backlight_ops = {
+ .get_brightness = cr_backlight_get_intensity,
+ .update_status = cr_backlight_set_intensity,
+};
+
+static void cr_panel_on(void)
+{
+ u32 addr = gpio_bar + CRVML_PANEL_PORT;
+ u32 cur = inl(addr);
+
+ if (!(cur & CRVML_PANEL_ON)) {
+ /* Make sure LVDS controller is down. */
+ if (cur & 0x00000001) {
+ cur &= ~CRVML_LVDS_ON;
+ outl(cur, addr);
+ }
+ /* Power up Panel */
+ schedule_timeout(HZ / 10);
+ cur |= CRVML_PANEL_ON;
+ outl(cur, addr);
+ }
+
+ /* Power up LVDS controller */
+
+ if (!(cur & CRVML_LVDS_ON)) {
+ schedule_timeout(HZ / 10);
+ outl(cur | CRVML_LVDS_ON, addr);
+ }
+}
+
+static void cr_panel_off(void)
+{
+ u32 addr = gpio_bar + CRVML_PANEL_PORT;
+ u32 cur = inl(addr);
+
+ /* Power down LVDS controller first to avoid high currents */
+ if (cur & CRVML_LVDS_ON) {
+ cur &= ~CRVML_LVDS_ON;
+ outl(cur, addr);
+ }
+ if (cur & CRVML_PANEL_ON) {
+ schedule_timeout(HZ / 10);
+ outl(cur & ~CRVML_PANEL_ON, addr);
+ }
+}
+
+static int cr_lcd_set_power(struct lcd_device *ld, int power)
+{
+ if (power == FB_BLANK_UNBLANK)
+ cr_panel_on();
+ if (power == FB_BLANK_POWERDOWN)
+ cr_panel_off();
+
+ return 0;
+}
+
+static struct lcd_ops cr_lcd_ops = {
+ .set_power = cr_lcd_set_power,
+};
+
+static int cr_backlight_probe(struct platform_device *pdev)
+{
+ struct cr_panel *crp;
+ u8 dev_en;
+
+ crp = kzalloc(sizeof(crp), GFP_KERNEL);
+ if (crp == NULL)
+ return -ENOMEM;
+
+ lpc_dev = pci_get_device(PCI_VENDOR_ID_INTEL,
+ CRVML_DEVICE_LPC, NULL);
+ if (!lpc_dev) {
+ printk("INTEL CARILLO RANCH LPC not found.\n");
+ return -ENODEV;
+ }
+
+ pci_read_config_byte(lpc_dev, CRVML_REG_GPIOEN, &dev_en);
+ if (!(dev_en & CRVML_GPIOEN_BIT)) {
+ printk(KERN_ERR
+ "Carillo Ranch GPIO device was not enabled.\n");
+ pci_dev_put(lpc_dev);
+ return -ENODEV;
+ }
+
+ crp->cr_backlight_device = backlight_device_register("cr-backlight",
+ &pdev->dev, NULL,
+ &cr_backlight_ops);
+ if (IS_ERR(crp->cr_backlight_device)) {
+ pci_dev_put(lpc_dev);
+ return PTR_ERR(crp->cr_backlight_device);
+ }
+
+ crp->cr_lcd_device = lcd_device_register("cr-lcd",
+ &pdev->dev,
+ &cr_lcd_ops);
+
+ if (IS_ERR(crp->cr_lcd_device)) {
+ pci_dev_put(lpc_dev);
+ return PTR_ERR(crp->cr_backlight_device);
+ }
+
+ pci_read_config_dword(lpc_dev, CRVML_REG_GPIOBAR,
+ &gpio_bar);
+ gpio_bar &= ~0x3F;
+
+ crp->cr_backlight_device->props.power = FB_BLANK_UNBLANK;
+ crp->cr_backlight_device->props.brightness = 0;
+ crp->cr_backlight_device->props.max_brightness = 0;
+ cr_backlight_set_intensity(crp->cr_backlight_device);
+
+ cr_lcd_set_power(crp->cr_lcd_device, FB_BLANK_UNBLANK);
+
+ platform_set_drvdata(pdev, crp);
+
+ return 0;
+}
+
+static int cr_backlight_remove(struct platform_device *pdev)
+{
+ struct cr_panel *crp = platform_get_drvdata(pdev);
+ crp->cr_backlight_device->props.power = FB_BLANK_POWERDOWN;
+ crp->cr_backlight_device->props.brightness = 0;
+ crp->cr_backlight_device->props.max_brightness = 0;
+ cr_backlight_set_intensity(crp->cr_backlight_device);
+ cr_lcd_set_power(crp->cr_lcd_device, FB_BLANK_POWERDOWN);
+ backlight_device_unregister(crp->cr_backlight_device);
+ lcd_device_unregister(crp->cr_lcd_device);
+ pci_dev_put(lpc_dev);
+
+ return 0;
+}
+
+static struct platform_driver cr_backlight_driver = {
+ .probe = cr_backlight_probe,
+ .remove = cr_backlight_remove,
+ .driver = {
+ .name = "cr_backlight",
+ },
+};
+
+static struct platform_device *crp;
+
+static int __init cr_backlight_init(void)
+{
+ int ret = platform_driver_register(&cr_backlight_driver);
+
+ if (!ret) {
+ crp = platform_device_alloc("cr_backlight", -1);
+ if (!crp)
+ return -ENOMEM;
+
+ ret = platform_device_add(crp);
+
+ if (ret) {
+ platform_device_put(crp);
+ platform_driver_unregister(&cr_backlight_driver);
+ }
+ }
+
+ printk("Carillo Ranch Backlight Driver Initialized.\n");
+
+ return ret;
+}
+
+static void __exit cr_backlight_exit(void)
+{
+ platform_device_unregister(crp);
+ platform_driver_unregister(&cr_backlight_driver);
+}
+
+module_init(cr_backlight_init);
+module_exit(cr_backlight_exit);
+
+MODULE_AUTHOR("Tungsten Graphics Inc.");
+MODULE_DESCRIPTION("Carillo Ranch Backlight Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/cfbcopyarea.c b/drivers/video/cfbcopyarea.c
index 6faea40..032210f 100644
--- a/drivers/video/cfbcopyarea.c
+++ b/drivers/video/cfbcopyarea.c
@@ -22,8 +22,6 @@
* help moving some redundant computations and branches out of the loop, too.
*/
-
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
@@ -31,6 +29,7 @@
#include <linux/slab.h>
#include <asm/types.h>
#include <asm/io.h>
+#include "fb_draw.h"
#if BITS_PER_LONG == 32
# define FB_WRITEL fb_writel
@@ -41,17 +40,6 @@
#endif
/*
- * Compose two values, using a bitmask as decision value
- * This is equivalent to (a & mask) | (b & ~mask)
- */
-
-static inline unsigned long
-comp(unsigned long a, unsigned long b, unsigned long mask)
-{
- return ((a ^ b) & mask) ^ b;
-}
-
- /*
* Generic bitwise copy algorithm
*/
diff --git a/drivers/video/cfbfillrect.c b/drivers/video/cfbfillrect.c
index f00b50a..71623b4 100644
--- a/drivers/video/cfbfillrect.c
+++ b/drivers/video/cfbfillrect.c
@@ -21,6 +21,7 @@
#include <linux/string.h>
#include <linux/fb.h>
#include <asm/types.h>
+#include "fb_draw.h"
#if BITS_PER_LONG == 32
# define FB_WRITEL fb_writel
@@ -31,73 +32,6 @@
#endif
/*
- * Compose two values, using a bitmask as decision value
- * This is equivalent to (a & mask) | (b & ~mask)
- */
-
-static inline unsigned long
-comp(unsigned long a, unsigned long b, unsigned long mask)
-{
- return ((a ^ b) & mask) ^ b;
-}
-
- /*
- * Create a pattern with the given pixel's color
- */
-
-#if BITS_PER_LONG == 64
-static inline unsigned long
-pixel_to_pat( u32 bpp, u32 pixel)
-{
- switch (bpp) {
- case 1:
- return 0xfffffffffffffffful*pixel;
- case 2:
- return 0x5555555555555555ul*pixel;
- case 4:
- return 0x1111111111111111ul*pixel;
- case 8:
- return 0x0101010101010101ul*pixel;
- case 12:
- return 0x0001001001001001ul*pixel;
- case 16:
- return 0x0001000100010001ul*pixel;
- case 24:
- return 0x0000000001000001ul*pixel;
- case 32:
- return 0x0000000100000001ul*pixel;
- default:
- panic("pixel_to_pat(): unsupported pixelformat\n");
- }
-}
-#else
-static inline unsigned long
-pixel_to_pat( u32 bpp, u32 pixel)
-{
- switch (bpp) {
- case 1:
- return 0xfffffffful*pixel;
- case 2:
- return 0x55555555ul*pixel;
- case 4:
- return 0x11111111ul*pixel;
- case 8:
- return 0x01010101ul*pixel;
- case 12:
- return 0x00001001ul*pixel;
- case 16:
- return 0x00010001ul*pixel;
- case 24:
- return 0x00000001ul*pixel;
- case 32:
- return 0x00000001ul*pixel;
- default:
- panic("pixel_to_pat(): unsupported pixelformat\n");
- }
-}
-#endif
-
- /*
* Aligned pattern fill using 32/64-bit memory accesses
*/
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index 2c4bc62..8269d70 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -98,15 +98,6 @@
#define assert(expr)
#endif
-#ifdef TRUE
-#undef TRUE
-#endif
-#ifdef FALSE
-#undef FALSE
-#endif
-#define TRUE 1
-#define FALSE 0
-
#define MB_ (1024*1024)
#define KB_ (1024)
@@ -146,9 +137,9 @@
char *name; /* ASCII name of chipset */
long maxclock[5]; /* maximum video clock */
/* for 1/4bpp, 8bpp 15/16bpp, 24bpp, 32bpp - numbers from xorg code */
- unsigned init_sr07 : 1; /* init SR07 during init_vgachip() */
- unsigned init_sr1f : 1; /* write SR1F during init_vgachip() */
- unsigned scrn_start_bit19 : 1; /* construct bit 19 of screen start address */
+ bool init_sr07 : 1; /* init SR07 during init_vgachip() */
+ bool init_sr1f : 1; /* write SR1F during init_vgachip() */
+ bool scrn_start_bit19 : 1; /* construct bit 19 of screen start address */
/* initial SR07 value, then for each mode */
unsigned char sr07;
@@ -166,9 +157,9 @@
/* the SD64/P4 have a higher max. videoclock */
140000, 140000, 140000, 140000, 140000,
},
- .init_sr07 = TRUE,
- .init_sr1f = TRUE,
- .scrn_start_bit19 = TRUE,
+ .init_sr07 = true,
+ .init_sr1f = true,
+ .scrn_start_bit19 = true,
.sr07 = 0xF0,
.sr07_1bpp = 0xF0,
.sr07_8bpp = 0xF1,
@@ -180,9 +171,9 @@
/* guess */
90000, 90000, 90000, 90000, 90000
},
- .init_sr07 = TRUE,
- .init_sr1f = TRUE,
- .scrn_start_bit19 = FALSE,
+ .init_sr07 = true,
+ .init_sr1f = true,
+ .scrn_start_bit19 = false,
.sr07 = 0x80,
.sr07_1bpp = 0x80,
.sr07_8bpp = 0x81,
@@ -194,9 +185,9 @@
/* guess */
90000, 90000, 90000, 90000, 90000
},
- .init_sr07 = TRUE,
- .init_sr1f = TRUE,
- .scrn_start_bit19 = FALSE,
+ .init_sr07 = true,
+ .init_sr1f = true,
+ .scrn_start_bit19 = false,
.sr07 = 0x20,
.sr07_1bpp = 0x20,
.sr07_8bpp = 0x21,
@@ -208,9 +199,9 @@
/* guess */
90000, 90000, 90000, 90000, 90000
},
- .init_sr07 = TRUE,
- .init_sr1f = TRUE,
- .scrn_start_bit19 = FALSE,
+ .init_sr07 = true,
+ .init_sr1f = true,
+ .scrn_start_bit19 = false,
.sr07 = 0x80,
.sr07_1bpp = 0x80,
.sr07_8bpp = 0x81,
@@ -221,9 +212,9 @@
.maxclock = {
135100, 135100, 85500, 85500, 0
},
- .init_sr07 = TRUE,
- .init_sr1f = FALSE,
- .scrn_start_bit19 = TRUE,
+ .init_sr07 = true,
+ .init_sr1f = false,
+ .scrn_start_bit19 = true,
.sr07 = 0x20,
.sr07_1bpp = 0x20,
.sr07_8bpp = 0x21,
@@ -235,9 +226,9 @@
/* for the GD5430. GD5446 can do more... */
85500, 85500, 50000, 28500, 0
},
- .init_sr07 = TRUE,
- .init_sr1f = TRUE,
- .scrn_start_bit19 = TRUE,
+ .init_sr07 = true,
+ .init_sr1f = true,
+ .scrn_start_bit19 = true,
.sr07 = 0xA0,
.sr07_1bpp = 0xA1,
.sr07_1bpp_mux = 0xA7,
@@ -250,9 +241,9 @@
.maxclock = {
135100, 200000, 200000, 135100, 135100
},
- .init_sr07 = TRUE,
- .init_sr1f = TRUE,
- .scrn_start_bit19 = TRUE,
+ .init_sr07 = true,
+ .init_sr1f = true,
+ .scrn_start_bit19 = true,
.sr07 = 0x10,
.sr07_1bpp = 0x11,
.sr07_8bpp = 0x11,
@@ -264,9 +255,9 @@
/* guess */
135100, 135100, 135100, 135100, 135100,
},
- .init_sr07 = FALSE,
- .init_sr1f = FALSE,
- .scrn_start_bit19 = TRUE,
+ .init_sr07 = false,
+ .init_sr1f = false,
+ .scrn_start_bit19 = true,
}
};
@@ -815,7 +806,7 @@
default:
DPRINTK("Unsupported bpp size: %d\n", var->bits_per_pixel);
- assert (FALSE);
+ assert(false);
/* should never occur */
break;
}
@@ -886,7 +877,7 @@
default:
DPRINTK("Unsupported bpp size: %d\n", var->bits_per_pixel);
- assert (FALSE);
+ assert(false);
/* should never occur */
break;
}
@@ -3203,7 +3194,7 @@
break;
default:
/* should never occur */
- assert (FALSE);
+ assert(false);
break;
}
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 0429fd2..73813c6 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -107,7 +107,9 @@
static signed char con2fb_map[MAX_NR_CONSOLES];
static signed char con2fb_map_boot[MAX_NR_CONSOLES];
+#ifndef MODULE
static int logo_height;
+#endif
static int logo_lines;
/* logo_shown is an index to vc_cons when >= 0; otherwise follows FBCON_LOGO
enums. */
@@ -576,6 +578,13 @@
return err;
}
+#ifdef MODULE
+static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
+ int cols, int rows, int new_cols, int new_rows)
+{
+ logo_shown = FBCON_LOGO_DONTSHOW;
+}
+#else
static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
int cols, int rows, int new_cols, int new_rows)
{
@@ -584,6 +593,11 @@
int cnt, erase = vc->vc_video_erase_char, step;
unsigned short *save = NULL, *r, *q;
+ if (info->flags & FBINFO_MODULE) {
+ logo_shown = FBCON_LOGO_DONTSHOW;
+ return;
+ }
+
/*
* remove underline attribute from erase character
* if black and white framebuffer.
@@ -618,8 +632,13 @@
r -= cols;
}
if (!save) {
- vc->vc_y += logo_lines;
- vc->vc_pos += logo_lines * vc->vc_size_row;
+ int lines;
+ if (vc->vc_y + logo_lines >= rows)
+ lines = rows - vc->vc_y - 1;
+ else
+ lines = logo_lines;
+ vc->vc_y += lines;
+ vc->vc_pos += lines * vc->vc_size_row;
}
}
scr_memsetw((unsigned short *) vc->vc_origin,
@@ -650,6 +669,7 @@
vc->vc_top = logo_lines;
}
}
+#endif /* MODULE */
#ifdef CONFIG_FB_TILEBLITTING
static void set_blitting_type(struct vc_data *vc, struct fb_info *info)
@@ -665,6 +685,17 @@
fbcon_set_bitops(ops);
}
}
+
+static int fbcon_invalid_charcount(struct fb_info *info, unsigned charcount)
+{
+ int err = 0;
+
+ if (info->flags & FBINFO_MISC_TILEBLITTING &&
+ info->tileops->fb_get_tilemax(info) < charcount)
+ err = 1;
+
+ return err;
+}
#else
static void set_blitting_type(struct vc_data *vc, struct fb_info *info)
{
@@ -675,6 +706,12 @@
fbcon_set_rotation(info);
fbcon_set_bitops(ops);
}
+
+static int fbcon_invalid_charcount(struct fb_info *info, unsigned charcount)
+{
+ return 0;
+}
+
#endif /* CONFIG_MISC_TILEBLITTING */
@@ -968,7 +1005,9 @@
if (!p->fontdata) {
if (!fontname[0] || !(font = find_font(fontname)))
font = get_default_font(info->var.xres,
- info->var.yres);
+ info->var.yres,
+ info->pixmap.blit_x,
+ info->pixmap.blit_y);
vc->vc_font.width = font->width;
vc->vc_font.height = font->height;
vc->vc_font.data = (void *)(p->fontdata = font->data);
@@ -1088,7 +1127,9 @@
if (!fontname[0] || !(font = find_font(fontname)))
font = get_default_font(info->var.xres,
- info->var.yres);
+ info->var.yres,
+ info->pixmap.blit_x,
+ info->pixmap.blit_y);
vc->vc_font.width = font->width;
vc->vc_font.height = font->height;
vc->vc_font.data = (void *)(p->fontdata = font->data);
@@ -1305,7 +1346,7 @@
int y;
int c = scr_readw((u16 *) vc->vc_pos);
- if (fbcon_is_inactive(vc, info))
+ if (fbcon_is_inactive(vc, info) || vc->vc_deccm != 1)
return;
ops->cursor_flash = (mode == CM_ERASE) ? 0 : 1;
@@ -2475,6 +2516,7 @@
static int fbcon_set_font(struct vc_data *vc, struct console_font *font, unsigned flags)
{
+ struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
unsigned charcount = font->charcount;
int w = font->width;
int h = font->height;
@@ -2488,6 +2530,15 @@
if (charcount != 256 && charcount != 512)
return -EINVAL;
+ /* Make sure drawing engine can handle the font */
+ if (!(info->pixmap.blit_x & (1 << (font->width - 1))) ||
+ !(info->pixmap.blit_y & (1 << (font->height - 1))))
+ return -EINVAL;
+
+ /* Make sure driver can handle the font length */
+ if (fbcon_invalid_charcount(info, charcount))
+ return -EINVAL;
+
size = h * pitch * charcount;
new_data = kmalloc(FONT_EXTRA_WORDS * sizeof(int) + size, GFP_USER);
@@ -2532,7 +2583,8 @@
const struct font_desc *f;
if (!name)
- f = get_default_font(info->var.xres, info->var.yres);
+ f = get_default_font(info->var.xres, info->var.yres,
+ info->pixmap.blit_x, info->pixmap.blit_y);
else if (!(f = find_font(name)))
return -ENOENT;
@@ -2829,7 +2881,7 @@
struct fbcon_ops *ops = info->fbcon_par;
struct vc_data *vc;
struct display *p;
- int i, rows, cols;
+ int i, rows, cols, fg = -1;
if (!ops || ops->currcon < 0)
return;
@@ -2840,34 +2892,23 @@
registered_fb[con2fb_map[i]] != info)
continue;
+ if (CON_IS_VISIBLE(vc)) {
+ fg = i;
+ continue;
+ }
+
p = &fb_display[vc->vc_num];
set_blitting_type(vc, info);
var_to_display(p, &info->var, info);
- cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
- rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
+ cols = FBCON_SWAP(p->rotate, info->var.xres, info->var.yres);
+ rows = FBCON_SWAP(p->rotate, info->var.yres, info->var.xres);
cols /= vc->vc_font.width;
rows /= vc->vc_font.height;
vc_resize(vc, cols, rows);
-
- if (CON_IS_VISIBLE(vc)) {
- updatescrollmode(p, info, vc);
- scrollback_max = 0;
- scrollback_current = 0;
-
- if (!fbcon_is_inactive(vc, info)) {
- ops->var.xoffset = ops->var.yoffset =
- p->yscroll = 0;
- ops->update_start(info);
- }
-
- fbcon_set_palette(vc, color_table);
- update_screen(vc);
- if (softback_buf)
- fbcon_update_softback(vc);
- }
}
- ops->p = &fb_display[ops->currcon];
+ if (fg != -1)
+ fbcon_modechanged(info);
}
static int fbcon_mode_deleted(struct fb_info *info,
@@ -3002,6 +3043,42 @@
}
}
+static void fbcon_get_requirement(struct fb_info *info,
+ struct fb_blit_caps *caps)
+{
+ struct vc_data *vc;
+ struct display *p;
+
+ if (caps->flags) {
+ int i, charcnt;
+
+ for (i = first_fb_vc; i <= last_fb_vc; i++) {
+ vc = vc_cons[i].d;
+ if (vc && vc->vc_mode == KD_TEXT &&
+ info->node == con2fb_map[i]) {
+ p = &fb_display[i];
+ caps->x |= 1 << (vc->vc_font.width - 1);
+ caps->y |= 1 << (vc->vc_font.height - 1);
+ charcnt = (p->userfont) ?
+ FNTCHARCNT(p->fontdata) : 256;
+ if (caps->len < charcnt)
+ caps->len = charcnt;
+ }
+ }
+ } else {
+ vc = vc_cons[fg_console].d;
+
+ if (vc && vc->vc_mode == KD_TEXT &&
+ info->node == con2fb_map[fg_console]) {
+ p = &fb_display[fg_console];
+ caps->x = 1 << (vc->vc_font.width - 1);
+ caps->y = 1 << (vc->vc_font.height - 1);
+ caps->len = (p->userfont) ?
+ FNTCHARCNT(p->fontdata) : 256;
+ }
+ }
+}
+
static int fbcon_event_notify(struct notifier_block *self,
unsigned long action, void *data)
{
@@ -3009,6 +3086,7 @@
struct fb_info *info = event->info;
struct fb_videomode *mode;
struct fb_con2fbmap *con2fb;
+ struct fb_blit_caps *caps;
int ret = 0;
/*
@@ -3057,6 +3135,10 @@
case FB_EVENT_NEW_MODELIST:
fbcon_new_modelist(info);
break;
+ case FB_EVENT_GET_REQ:
+ caps = event->data;
+ fbcon_get_requirement(info, caps);
+ break;
}
done:
diff --git a/drivers/video/console/fonts.c b/drivers/video/console/fonts.c
index c960728..a6828d0 100644
--- a/drivers/video/console/fonts.c
+++ b/drivers/video/console/fonts.c
@@ -98,6 +98,8 @@
* get_default_font - get default font
* @xres: screen size of X
* @yres: screen size of Y
+ * @font_w: bit array of supported widths (1 - 32)
+ * @font_h: bit array of supported heights (1 - 32)
*
* Get the default font for a specified screen size.
* Dimensions are in pixels.
@@ -107,7 +109,8 @@
*
*/
-const struct font_desc *get_default_font(int xres, int yres)
+const struct font_desc *get_default_font(int xres, int yres, u32 font_w,
+ u32 font_h)
{
int i, c, cc;
const struct font_desc *f, *g;
@@ -129,6 +132,11 @@
#endif
if ((yres < 400) == (f->height <= 8))
c += 1000;
+
+ if (!(font_w & (1 << (f->width - 1))) ||
+ !(font_w & (1 << (f->height - 1))))
+ c += 1000;
+
if (c > cc) {
cc = c;
g = f;
diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c
index 124ecbe..bd8d995 100644
--- a/drivers/video/console/mdacon.c
+++ b/drivers/video/console/mdacon.c
@@ -384,7 +384,7 @@
}
static u8 mdacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
- u8 blink, u8 underline, u8 reverse)
+ u8 blink, u8 underline, u8 reverse, u8 italic)
{
/* The attribute is just a bit vector:
*
@@ -397,6 +397,7 @@
return (intensity & 3) |
((underline & 1) << 2) |
((reverse & 1) << 3) |
+ (!!italic << 4) |
((blink & 1) << 7);
}
diff --git a/drivers/video/console/promcon.c b/drivers/video/console/promcon.c
index b78eac6..ae02e4e 100644
--- a/drivers/video/console/promcon.c
+++ b/drivers/video/console/promcon.c
@@ -548,7 +548,8 @@
}
#if !(PROMCON_COLOR)
-static u8 promcon_build_attr(struct vc_data *conp, u8 _color, u8 _intensity, u8 _blink, u8 _underline, u8 _reverse)
+static u8 promcon_build_attr(struct vc_data *conp, u8 _color, u8 _intensity,
+ u8 _blink, u8 _underline, u8 _reverse, u8 _italic)
{
return (_reverse) ? 0xf : 0x7;
}
diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c
index 57b21e5..67a682d 100644
--- a/drivers/video/console/sticon.c
+++ b/drivers/video/console/sticon.c
@@ -314,7 +314,7 @@
}
static u8 sticon_build_attr(struct vc_data *conp, u8 color, u8 intens,
- u8 blink, u8 underline, u8 reverse)
+ u8 blink, u8 underline, u8 reverse, u8 italic)
{
u8 attr = ((color & 0x70) >> 1) | ((color & 7));
diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c
index 88e7038..717b360 100644
--- a/drivers/video/console/sticore.c
+++ b/drivers/video/console/sticore.c
@@ -495,7 +495,7 @@
return NULL;
fbfont = find_font(fbfont_name);
if (!fbfont)
- fbfont = get_default_font(1024,768);
+ fbfont = get_default_font(1024,768, ~(u32)0, ~(u32)0);
if (!fbfont)
return NULL;
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 3e67c34..2460b82 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -86,8 +86,6 @@
static void vgacon_save_screen(struct vc_data *c);
static int vgacon_scroll(struct vc_data *c, int t, int b, int dir,
int lines);
-static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
- u8 blink, u8 underline, u8 reverse);
static void vgacon_invert_region(struct vc_data *c, u16 * p, int count);
static unsigned long vgacon_uni_pagedir[2];
@@ -578,12 +576,14 @@
}
static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
- u8 blink, u8 underline, u8 reverse)
+ u8 blink, u8 underline, u8 reverse, u8 italic)
{
u8 attr = color;
if (vga_can_do_color) {
- if (underline)
+ if (italic)
+ attr = (attr & 0xF0) | c->vc_itcolor;
+ else if (underline)
attr = (attr & 0xf0) | c->vc_ulcolor;
else if (intensity == 0)
attr = (attr & 0xf0) | c->vc_halfcolor;
@@ -597,7 +597,9 @@
if (intensity == 2)
attr ^= 0x08;
if (!vga_can_do_color) {
- if (underline)
+ if (italic)
+ attr = (attr & 0xF8) | 0x02;
+ else if (underline)
attr = (attr & 0xf8) | 0x01;
else if (intensity == 0)
attr = (attr & 0xf0) | 0x08;
@@ -658,6 +660,9 @@
static void vgacon_cursor(struct vc_data *c, int mode)
{
+ if (c->vc_mode != KD_TEXT)
+ return;
+
vgacon_restore_screen(c);
switch (mode) {
@@ -1316,7 +1321,7 @@
unsigned long oldo;
unsigned int delta;
- if (t || b != c->vc_rows || vga_is_gfx)
+ if (t || b != c->vc_rows || vga_is_gfx || c->vc_mode != KD_TEXT)
return 0;
if (!vga_hardscroll_enabled || lines >= c->vc_rows / 2)
diff --git a/drivers/video/display/Kconfig b/drivers/video/display/Kconfig
new file mode 100644
index 0000000..f99af93
--- /dev/null
+++ b/drivers/video/display/Kconfig
@@ -0,0 +1,24 @@
+#
+# Display drivers configuration
+#
+
+menu "Display device support"
+
+config DISPLAY_SUPPORT
+ tristate "Display panel/monitor support"
+ ---help---
+ This framework adds support for low-level control of a display.
+ This includes support for power.
+
+ Enable this to be able to choose the drivers for controlling the
+ physical display panel/monitor on some platforms. This not only
+ covers LCD displays for PDAs but also other types of displays
+ such as CRT, TVout etc.
+
+ To have support for your specific display panel you will have to
+ select the proper drivers which depend on this option.
+
+comment "Display hardware drivers"
+ depends on DISPLAY_SUPPORT
+
+endmenu
diff --git a/drivers/video/display/Makefile b/drivers/video/display/Makefile
new file mode 100644
index 0000000..c0ea832
--- /dev/null
+++ b/drivers/video/display/Makefile
@@ -0,0 +1,6 @@
+# Display drivers
+
+display-objs := display-sysfs.o
+
+obj-$(CONFIG_DISPLAY_SUPPORT) += display.o
+
diff --git a/drivers/video/display/display-sysfs.c b/drivers/video/display/display-sysfs.c
new file mode 100644
index 0000000..3547717
--- /dev/null
+++ b/drivers/video/display/display-sysfs.c
@@ -0,0 +1,217 @@
+/*
+ * display-sysfs.c - Display output driver sysfs interface
+ *
+ * Copyright (C) 2007 James Simmons <jsimmons@infradead.org>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+#include <linux/module.h>
+#include <linux/display.h>
+#include <linux/ctype.h>
+#include <linux/idr.h>
+#include <linux/err.h>
+
+static ssize_t display_show_name(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct display_device *dsp = dev_get_drvdata(dev);
+ return snprintf(buf, PAGE_SIZE, "%s\n", dsp->name);
+}
+
+static ssize_t display_show_type(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct display_device *dsp = dev_get_drvdata(dev);
+ return snprintf(buf, PAGE_SIZE, "%s\n", dsp->type);
+}
+
+static ssize_t display_show_contrast(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct display_device *dsp = dev_get_drvdata(dev);
+ ssize_t rc = -ENXIO;
+
+ mutex_lock(&dsp->lock);
+ if (likely(dsp->driver) && dsp->driver->get_contrast)
+ rc = sprintf(buf, "%d\n", dsp->driver->get_contrast(dsp));
+ mutex_unlock(&dsp->lock);
+ return rc;
+}
+
+static ssize_t display_store_contrast(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct display_device *dsp = dev_get_drvdata(dev);
+ ssize_t ret = -EINVAL, size;
+ int contrast;
+ char *endp;
+
+ contrast = simple_strtoul(buf, &endp, 0);
+ size = endp - buf;
+
+ if (*endp && isspace(*endp))
+ size++;
+
+ if (size != count)
+ return ret;
+
+ mutex_lock(&dsp->lock);
+ if (likely(dsp->driver && dsp->driver->set_contrast)) {
+ pr_debug("display: set contrast to %d\n", contrast);
+ dsp->driver->set_contrast(dsp, contrast);
+ ret = count;
+ }
+ mutex_unlock(&dsp->lock);
+ return ret;
+}
+
+static ssize_t display_show_max_contrast(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct display_device *dsp = dev_get_drvdata(dev);
+ ssize_t rc = -ENXIO;
+
+ mutex_lock(&dsp->lock);
+ if (likely(dsp->driver))
+ rc = sprintf(buf, "%d\n", dsp->driver->max_contrast);
+ mutex_unlock(&dsp->lock);
+ return rc;
+}
+
+static struct device_attribute display_attrs[] = {
+ __ATTR(name, S_IRUGO, display_show_name, NULL),
+ __ATTR(type, S_IRUGO, display_show_type, NULL),
+ __ATTR(contrast, S_IRUGO | S_IWUSR, display_show_contrast, display_store_contrast),
+ __ATTR(max_contrast, S_IRUGO, display_show_max_contrast, NULL),
+};
+
+static int display_suspend(struct device *dev, pm_message_t state)
+{
+ struct display_device *dsp = dev_get_drvdata(dev);
+
+ mutex_lock(&dsp->lock);
+ if (likely(dsp->driver->suspend))
+ dsp->driver->suspend(dsp, state);
+ mutex_unlock(&dsp->lock);
+ return 0;
+};
+
+static int display_resume(struct device *dev)
+{
+ struct display_device *dsp = dev_get_drvdata(dev);
+
+ mutex_lock(&dsp->lock);
+ if (likely(dsp->driver->resume))
+ dsp->driver->resume(dsp);
+ mutex_unlock(&dsp->lock);
+ return 0;
+};
+
+static struct mutex allocated_dsp_lock;
+static DEFINE_IDR(allocated_dsp);
+static struct class *display_class;
+
+struct display_device *display_device_register(struct display_driver *driver,
+ struct device *parent, void *devdata)
+{
+ struct display_device *new_dev = NULL;
+ int ret = -EINVAL;
+
+ if (unlikely(!driver))
+ return ERR_PTR(ret);
+
+ mutex_lock(&allocated_dsp_lock);
+ ret = idr_pre_get(&allocated_dsp, GFP_KERNEL);
+ mutex_unlock(&allocated_dsp_lock);
+ if (!ret)
+ return ERR_PTR(ret);
+
+ new_dev = kzalloc(sizeof(struct display_device), GFP_KERNEL);
+ if (likely(new_dev) && unlikely(driver->probe(new_dev, devdata))) {
+ // Reserve the index for this display
+ mutex_lock(&allocated_dsp_lock);
+ ret = idr_get_new(&allocated_dsp, new_dev, &new_dev->idx);
+ mutex_unlock(&allocated_dsp_lock);
+
+ if (!ret) {
+ new_dev->dev = device_create(display_class, parent, 0,
+ "display%d", new_dev->idx);
+ if (!IS_ERR(new_dev->dev)) {
+ dev_set_drvdata(new_dev->dev, new_dev);
+ new_dev->parent = parent;
+ new_dev->driver = driver;
+ mutex_init(&new_dev->lock);
+ return new_dev;
+ }
+ mutex_lock(&allocated_dsp_lock);
+ idr_remove(&allocated_dsp, new_dev->idx);
+ mutex_unlock(&allocated_dsp_lock);
+ ret = -EINVAL;
+ }
+ }
+ kfree(new_dev);
+ return ERR_PTR(ret);
+}
+EXPORT_SYMBOL(display_device_register);
+
+void display_device_unregister(struct display_device *ddev)
+{
+ if (!ddev)
+ return;
+ // Free device
+ mutex_lock(&ddev->lock);
+ device_unregister(ddev->dev);
+ mutex_unlock(&ddev->lock);
+ // Mark device index as avaliable
+ mutex_lock(&allocated_dsp_lock);
+ idr_remove(&allocated_dsp, ddev->idx);
+ mutex_unlock(&allocated_dsp_lock);
+ kfree(ddev);
+}
+EXPORT_SYMBOL(display_device_unregister);
+
+static int __init display_class_init(void)
+{
+ display_class = class_create(THIS_MODULE, "display");
+ if (IS_ERR(display_class)) {
+ printk(KERN_ERR "Failed to create display class\n");
+ display_class = NULL;
+ return -EINVAL;
+ }
+ display_class->dev_attrs = display_attrs;
+ display_class->suspend = display_suspend;
+ display_class->resume = display_resume;
+ mutex_init(&allocated_dsp_lock);
+ return 0;
+}
+
+static void __exit display_class_exit(void)
+{
+ class_destroy(display_class);
+}
+
+module_init(display_class_init);
+module_exit(display_class_exit);
+
+MODULE_DESCRIPTION("Display Hardware handling");
+MODULE_AUTHOR("James Simmons <jsimmons@infradead.org>");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c
index 29e07c1..ca2c54c 100644
--- a/drivers/video/epson1355fb.c
+++ b/drivers/video/epson1355fb.c
@@ -403,17 +403,10 @@
static ssize_t
-epson1355fb_read(struct file *file, char *buf, size_t count, loff_t * ppos)
+epson1355fb_read(struct fb_info *info, char *buf, size_t count, loff_t * ppos)
{
- struct inode *inode = file->f_path.dentry->d_inode;
- int fbidx = iminor(inode);
- struct fb_info *info = registered_fb[fbidx];
unsigned long p = *ppos;
- /* from fbmem.c except for our own copy_*_user */
- if (!info || !info->screen_base)
- return -ENODEV;
-
if (p >= info->fix.smem_len)
return 0;
if (count >= info->fix.smem_len)
@@ -434,20 +427,13 @@
}
static ssize_t
-epson1355fb_write(struct file *file, const char *buf,
+epson1355fb_write(struct fb_info *info, const char *buf,
size_t count, loff_t * ppos)
{
- struct inode *inode = file->f_path.dentry->d_inode;
- int fbidx = iminor(inode);
- struct fb_info *info = registered_fb[fbidx];
unsigned long p = *ppos;
int err;
/* from fbmem.c except for our own copy_*_user */
- if (!info || !info->screen_base)
- return -ENODEV;
-
- /* from fbmem.c except for our own copy_*_user */
if (p > info->fix.smem_len)
return -ENOSPC;
if (count >= info->fix.smem_len)
@@ -650,9 +636,10 @@
}
info = framebuffer_alloc(sizeof(struct epson1355_par) + sizeof(u32) * 256, &dev->dev);
- if (!info)
+ if (!info) {
rc = -ENOMEM;
goto bail;
+ }
default_par = info->par;
default_par->reg_addr = (unsigned long) ioremap(EPSON1355FB_REGS_PHYS, EPSON1355FB_REGS_LEN);
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c
new file mode 100644
index 0000000..1a8643f
--- /dev/null
+++ b/drivers/video/fb_defio.c
@@ -0,0 +1,151 @@
+/*
+ * linux/drivers/video/fb_defio.c
+ *
+ * Copyright (C) 2006 Jaya Kumar
+ *
+ * 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/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/list.h>
+#include <asm/uaccess.h>
+
+/* to support deferred IO */
+#include <linux/rmap.h>
+#include <linux/pagemap.h>
+
+/* this is to find and return the vmalloc-ed fb pages */
+static struct page* fb_deferred_io_nopage(struct vm_area_struct *vma,
+ unsigned long vaddr, int *type)
+{
+ unsigned long offset;
+ struct page *page;
+ struct fb_info *info = vma->vm_private_data;
+ /* info->screen_base is in System RAM */
+ void *screen_base = (void __force *) info->screen_base;
+
+ offset = (vaddr - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT);
+ if (offset >= info->fix.smem_len)
+ return NOPAGE_SIGBUS;
+
+ page = vmalloc_to_page(screen_base + offset);
+ if (!page)
+ return NOPAGE_OOM;
+
+ get_page(page);
+ if (type)
+ *type = VM_FAULT_MINOR;
+ return page;
+}
+
+int fb_deferred_io_fsync(struct file *file, struct dentry *dentry, int datasync)
+{
+ struct fb_info *info = file->private_data;
+
+ /* Kill off the delayed work */
+ cancel_rearming_delayed_work(&info->deferred_work);
+
+ /* Run it immediately */
+ return schedule_delayed_work(&info->deferred_work, 0);
+}
+EXPORT_SYMBOL_GPL(fb_deferred_io_fsync);
+
+/* vm_ops->page_mkwrite handler */
+static int fb_deferred_io_mkwrite(struct vm_area_struct *vma,
+ struct page *page)
+{
+ struct fb_info *info = vma->vm_private_data;
+ struct fb_deferred_io *fbdefio = info->fbdefio;
+
+ /* this is a callback we get when userspace first tries to
+ write to the page. we schedule a workqueue. that workqueue
+ will eventually mkclean the touched pages and execute the
+ deferred framebuffer IO. then if userspace touches a page
+ again, we repeat the same scheme */
+
+ /* protect against the workqueue changing the page list */
+ mutex_lock(&fbdefio->lock);
+ list_add(&page->lru, &fbdefio->pagelist);
+ mutex_unlock(&fbdefio->lock);
+
+ /* come back after delay to process the deferred IO */
+ schedule_delayed_work(&info->deferred_work, fbdefio->delay);
+ return 0;
+}
+
+static struct vm_operations_struct fb_deferred_io_vm_ops = {
+ .nopage = fb_deferred_io_nopage,
+ .page_mkwrite = fb_deferred_io_mkwrite,
+};
+
+static int fb_deferred_io_mmap(struct fb_info *info, struct vm_area_struct *vma)
+{
+ vma->vm_ops = &fb_deferred_io_vm_ops;
+ vma->vm_flags |= ( VM_IO | VM_RESERVED | VM_DONTEXPAND );
+ vma->vm_private_data = info;
+ return 0;
+}
+
+/* workqueue callback */
+static void fb_deferred_io_work(struct work_struct *work)
+{
+ struct fb_info *info = container_of(work, struct fb_info,
+ deferred_work.work);
+ struct list_head *node, *next;
+ struct page *cur;
+ struct fb_deferred_io *fbdefio = info->fbdefio;
+
+ /* here we mkclean the pages, then do all deferred IO */
+ mutex_lock(&fbdefio->lock);
+ list_for_each_entry(cur, &fbdefio->pagelist, lru) {
+ lock_page(cur);
+ page_mkclean(cur);
+ unlock_page(cur);
+ }
+
+ /* driver's callback with pagelist */
+ fbdefio->deferred_io(info, &fbdefio->pagelist);
+
+ /* clear the list */
+ list_for_each_safe(node, next, &fbdefio->pagelist) {
+ list_del(node);
+ }
+ mutex_unlock(&fbdefio->lock);
+}
+
+void fb_deferred_io_init(struct fb_info *info)
+{
+ struct fb_deferred_io *fbdefio = info->fbdefio;
+
+ BUG_ON(!fbdefio);
+ mutex_init(&fbdefio->lock);
+ info->fbops->fb_mmap = fb_deferred_io_mmap;
+ INIT_DELAYED_WORK(&info->deferred_work, fb_deferred_io_work);
+ INIT_LIST_HEAD(&fbdefio->pagelist);
+ if (fbdefio->delay == 0) /* set a default of 1 s */
+ fbdefio->delay = HZ;
+}
+EXPORT_SYMBOL_GPL(fb_deferred_io_init);
+
+void fb_deferred_io_cleanup(struct fb_info *info)
+{
+ struct fb_deferred_io *fbdefio = info->fbdefio;
+
+ BUG_ON(!fbdefio);
+ cancel_delayed_work(&info->deferred_work);
+ flush_scheduled_work();
+}
+EXPORT_SYMBOL_GPL(fb_deferred_io_cleanup);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/fb_draw.h b/drivers/video/fb_draw.h
new file mode 100644
index 0000000..c5c4520
--- /dev/null
+++ b/drivers/video/fb_draw.h
@@ -0,0 +1,72 @@
+#ifndef _FB_DRAW_H
+#define _FB_DRAW_H
+
+#include <asm/types.h>
+
+ /*
+ * Compose two values, using a bitmask as decision value
+ * This is equivalent to (a & mask) | (b & ~mask)
+ */
+
+static inline unsigned long
+comp(unsigned long a, unsigned long b, unsigned long mask)
+{
+ return ((a ^ b) & mask) ^ b;
+}
+
+ /*
+ * Create a pattern with the given pixel's color
+ */
+
+#if BITS_PER_LONG == 64
+static inline unsigned long
+pixel_to_pat( u32 bpp, u32 pixel)
+{
+ switch (bpp) {
+ case 1:
+ return 0xfffffffffffffffful*pixel;
+ case 2:
+ return 0x5555555555555555ul*pixel;
+ case 4:
+ return 0x1111111111111111ul*pixel;
+ case 8:
+ return 0x0101010101010101ul*pixel;
+ case 12:
+ return 0x0001001001001001ul*pixel;
+ case 16:
+ return 0x0001000100010001ul*pixel;
+ case 24:
+ return 0x0000000001000001ul*pixel;
+ case 32:
+ return 0x0000000100000001ul*pixel;
+ default:
+ panic("pixel_to_pat(): unsupported pixelformat\n");
+ }
+}
+#else
+static inline unsigned long
+pixel_to_pat( u32 bpp, u32 pixel)
+{
+ switch (bpp) {
+ case 1:
+ return 0xfffffffful*pixel;
+ case 2:
+ return 0x55555555ul*pixel;
+ case 4:
+ return 0x11111111ul*pixel;
+ case 8:
+ return 0x01010101ul*pixel;
+ case 12:
+ return 0x00001001ul*pixel;
+ case 16:
+ return 0x00010001ul*pixel;
+ case 24:
+ return 0x00000001ul*pixel;
+ case 32:
+ return 0x00000001ul*pixel;
+ default:
+ panic("pixel_to_pat(): unsupported pixelformat\n");
+ }
+}
+#endif
+#endif /* FB_DRAW_H */
diff --git a/drivers/video/fb_sys_fops.c b/drivers/video/fb_sys_fops.c
new file mode 100644
index 0000000..cf2538d
--- /dev/null
+++ b/drivers/video/fb_sys_fops.c
@@ -0,0 +1,104 @@
+/*
+ * linux/drivers/video/fb_sys_read.c - Generic file operations where
+ * framebuffer is in system RAM
+ *
+ * Copyright (C) 2007 Antonino Daplas <adaplas@pol.net>
+ *
+ * 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/fb.h>
+#include <linux/module.h>
+#include <asm/uaccess.h>
+
+ssize_t fb_sys_read(struct fb_info *info, char __user *buf, size_t count,
+ loff_t *ppos)
+{
+ unsigned long p = *ppos;
+ void *src;
+ int err = 0;
+ unsigned long total_size;
+
+ if (info->state != FBINFO_STATE_RUNNING)
+ return -EPERM;
+
+ total_size = info->screen_size;
+
+ if (total_size == 0)
+ total_size = info->fix.smem_len;
+
+ if (p >= total_size)
+ return 0;
+
+ if (count >= total_size)
+ count = total_size;
+
+ if (count + p > total_size)
+ count = total_size - p;
+
+ src = (void __force *)(info->screen_base + p);
+
+ if (info->fbops->fb_sync)
+ info->fbops->fb_sync(info);
+
+ if (copy_to_user(buf, src, count))
+ err = -EFAULT;
+
+ if (!err)
+ *ppos += count;
+
+ return (err) ? err : count;
+}
+EXPORT_SYMBOL_GPL(fb_sys_read);
+
+ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ unsigned long p = *ppos;
+ void *dst;
+ int err = 0;
+ unsigned long total_size;
+
+ if (info->state != FBINFO_STATE_RUNNING)
+ return -EPERM;
+
+ total_size = info->screen_size;
+
+ if (total_size == 0)
+ total_size = info->fix.smem_len;
+
+ if (p > total_size)
+ return -EFBIG;
+
+ if (count > total_size) {
+ err = -EFBIG;
+ count = total_size;
+ }
+
+ if (count + p > total_size) {
+ if (!err)
+ err = -ENOSPC;
+
+ count = total_size - p;
+ }
+
+ dst = (void __force *) (info->screen_base + p);
+
+ if (info->fbops->fb_sync)
+ info->fbops->fb_sync(info);
+
+ if (copy_from_user(dst, buf, count))
+ err = -EFAULT;
+
+ if (!err)
+ *ppos += count;
+
+ return (err) ? err : count;
+}
+EXPORT_SYMBOL_GPL(fb_sys_write);
+
+MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
+MODULE_DESCRIPTION("Generic file read (fb in system RAM)");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 2822526..08d4e11 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -354,59 +354,59 @@
if (rotate == FB_ROTATE_UD) {
fb_rotate_logo_ud(image->data, dst, image->width,
image->height);
- image->dx = info->var.xres - image->width;
- image->dy = info->var.yres - image->height;
+ image->dx = info->var.xres - image->width - image->dx;
+ image->dy = info->var.yres - image->height - image->dy;
} else if (rotate == FB_ROTATE_CW) {
fb_rotate_logo_cw(image->data, dst, image->width,
image->height);
tmp = image->width;
image->width = image->height;
image->height = tmp;
- image->dx = info->var.xres - image->width;
+ tmp = image->dy;
+ image->dy = image->dx;
+ image->dx = info->var.xres - image->width - tmp;
} else if (rotate == FB_ROTATE_CCW) {
fb_rotate_logo_ccw(image->data, dst, image->width,
image->height);
tmp = image->width;
image->width = image->height;
image->height = tmp;
- image->dy = info->var.yres - image->height;
+ tmp = image->dx;
+ image->dx = image->dy;
+ image->dy = info->var.yres - image->height - tmp;
}
image->data = dst;
}
static void fb_do_show_logo(struct fb_info *info, struct fb_image *image,
- int rotate)
+ int rotate, unsigned int num)
{
- int x;
+ unsigned int x;
if (rotate == FB_ROTATE_UR) {
- for (x = 0; x < num_online_cpus() &&
- x * (fb_logo.logo->width + 8) <=
- info->var.xres - fb_logo.logo->width; x++) {
+ for (x = 0;
+ x < num && image->dx + image->width <= info->var.xres;
+ x++) {
info->fbops->fb_imageblit(info, image);
- image->dx += fb_logo.logo->width + 8;
+ image->dx += image->width + 8;
}
} else if (rotate == FB_ROTATE_UD) {
- for (x = 0; x < num_online_cpus() &&
- x * (fb_logo.logo->width + 8) <=
- info->var.xres - fb_logo.logo->width; x++) {
+ for (x = 0; x < num && image->dx >= 0; x++) {
info->fbops->fb_imageblit(info, image);
- image->dx -= fb_logo.logo->width + 8;
+ image->dx -= image->width + 8;
}
} else if (rotate == FB_ROTATE_CW) {
- for (x = 0; x < num_online_cpus() &&
- x * (fb_logo.logo->width + 8) <=
- info->var.yres - fb_logo.logo->width; x++) {
+ for (x = 0;
+ x < num && image->dy + image->height <= info->var.yres;
+ x++) {
info->fbops->fb_imageblit(info, image);
- image->dy += fb_logo.logo->width + 8;
+ image->dy += image->height + 8;
}
} else if (rotate == FB_ROTATE_CCW) {
- for (x = 0; x < num_online_cpus() &&
- x * (fb_logo.logo->width + 8) <=
- info->var.yres - fb_logo.logo->width; x++) {
+ for (x = 0; x < num && image->dy >= 0; x++) {
info->fbops->fb_imageblit(info, image);
- image->dy -= fb_logo.logo->width + 8;
+ image->dy -= image->height + 8;
}
}
}
@@ -418,7 +418,8 @@
memset(&fb_logo, 0, sizeof(struct logo_data));
- if (info->flags & FBINFO_MISC_TILEBLITTING)
+ if (info->flags & FBINFO_MISC_TILEBLITTING ||
+ info->flags & FBINFO_MODULE)
return 0;
if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
@@ -483,7 +484,8 @@
struct fb_image image;
/* Return if the frame buffer is not mapped or suspended */
- if (fb_logo.logo == NULL || info->state != FBINFO_STATE_RUNNING)
+ if (fb_logo.logo == NULL || info->state != FBINFO_STATE_RUNNING ||
+ info->flags & FBINFO_MODULE)
return 0;
image.depth = 8;
@@ -532,7 +534,7 @@
fb_rotate_logo(info, logo_rotate, &image, rotate);
}
- fb_do_show_logo(info, &image, rotate);
+ fb_do_show_logo(info, &image, rotate, num_online_cpus());
kfree(palette);
if (saved_pseudo_palette != NULL)
@@ -586,7 +588,7 @@
return -EPERM;
if (info->fbops->fb_read)
- return info->fbops->fb_read(file, buf, count, ppos);
+ return info->fbops->fb_read(info, buf, count, ppos);
total_size = info->screen_size;
@@ -661,7 +663,7 @@
return -EPERM;
if (info->fbops->fb_write)
- return info->fbops->fb_write(file, buf, count, ppos);
+ return info->fbops->fb_write(info, buf, count, ppos);
total_size = info->screen_size;
@@ -771,14 +773,37 @@
return 0;
}
+static int fb_check_caps(struct fb_info *info, struct fb_var_screeninfo *var,
+ u32 activate)
+{
+ struct fb_event event;
+ struct fb_blit_caps caps, fbcaps;
+ int err = 0;
+
+ memset(&caps, 0, sizeof(caps));
+ memset(&fbcaps, 0, sizeof(fbcaps));
+ caps.flags = (activate & FB_ACTIVATE_ALL) ? 1 : 0;
+ event.info = info;
+ event.data = ∩︀
+ fb_notifier_call_chain(FB_EVENT_GET_REQ, &event);
+ info->fbops->fb_get_caps(info, &fbcaps, var);
+
+ if (((fbcaps.x ^ caps.x) & caps.x) ||
+ ((fbcaps.y ^ caps.y) & caps.y) ||
+ (fbcaps.len < caps.len))
+ err = -EINVAL;
+
+ return err;
+}
+
int
fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
{
- int err, flags = info->flags;
+ int flags = info->flags;
+ int ret = 0;
if (var->activate & FB_ACTIVATE_INV_MODE) {
struct fb_videomode mode1, mode2;
- int ret = 0;
fb_var_to_videomode(&mode1, var);
fb_var_to_videomode(&mode2, &info->var);
@@ -796,40 +821,51 @@
if (!ret)
fb_delete_videomode(&mode1, &info->modelist);
- return ret;
+
+ ret = (ret) ? -EINVAL : 0;
+ goto done;
}
if ((var->activate & FB_ACTIVATE_FORCE) ||
memcmp(&info->var, var, sizeof(struct fb_var_screeninfo))) {
+ u32 activate = var->activate;
+
if (!info->fbops->fb_check_var) {
*var = info->var;
- return 0;
+ goto done;
}
- if ((err = info->fbops->fb_check_var(var, info)))
- return err;
+ ret = info->fbops->fb_check_var(var, info);
+
+ if (ret)
+ goto done;
if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
struct fb_videomode mode;
- int err = 0;
+
+ if (info->fbops->fb_get_caps) {
+ ret = fb_check_caps(info, var, activate);
+
+ if (ret)
+ goto done;
+ }
info->var = *var;
+
if (info->fbops->fb_set_par)
info->fbops->fb_set_par(info);
fb_pan_display(info, &info->var);
-
fb_set_cmap(&info->cmap, info);
-
fb_var_to_videomode(&mode, &info->var);
if (info->modelist.prev && info->modelist.next &&
!list_empty(&info->modelist))
- err = fb_add_videomode(&mode, &info->modelist);
+ ret = fb_add_videomode(&mode, &info->modelist);
- if (!err && (flags & FBINFO_MISC_USEREVENT)) {
+ if (!ret && (flags & FBINFO_MISC_USEREVENT)) {
struct fb_event event;
- int evnt = (var->activate & FB_ACTIVATE_ALL) ?
+ int evnt = (activate & FB_ACTIVATE_ALL) ?
FB_EVENT_MODE_CHANGE_ALL :
FB_EVENT_MODE_CHANGE;
@@ -839,7 +875,9 @@
}
}
}
- return 0;
+
+ done:
+ return ret;
}
int
@@ -1266,6 +1304,9 @@
#ifdef HAVE_ARCH_FB_UNMAPPED_AREA
.get_unmapped_area = get_fb_unmapped_area,
#endif
+#ifdef CONFIG_FB_DEFERRED_IO
+ .fsync = fb_deferred_io_fsync,
+#endif
};
struct class *fb_class;
@@ -1316,6 +1357,12 @@
}
fb_info->pixmap.offset = 0;
+ if (!fb_info->pixmap.blit_x)
+ fb_info->pixmap.blit_x = ~(u32)0;
+
+ if (!fb_info->pixmap.blit_y)
+ fb_info->pixmap.blit_y = ~(u32)0;
+
if (!fb_info->modelist.prev || !fb_info->modelist.next)
INIT_LIST_HEAD(&fb_info->modelist);
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index 6b385c3..438b941 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -48,8 +48,9 @@
#define DPRINTK(fmt, args...)
#endif
-#define FBMON_FIX_HEADER 1
-#define FBMON_FIX_INPUT 2
+#define FBMON_FIX_HEADER 1
+#define FBMON_FIX_INPUT 2
+#define FBMON_FIX_TIMINGS 3
#ifdef CONFIG_FB_MODE_HELPERS
struct broken_edid {
@@ -71,6 +72,12 @@
.model = 0x5a44,
.fix = FBMON_FIX_INPUT,
},
+ /* Sharp UXGA? */
+ {
+ .manufacturer = "SHP",
+ .model = 0x138e,
+ .fix = FBMON_FIX_TIMINGS,
+ },
};
static const unsigned char edid_v1_header[] = { 0x00, 0xff, 0xff, 0xff,
@@ -87,6 +94,55 @@
while (i-- && (*--s == 0x20)) *s = 0;
}
+static int edid_is_serial_block(unsigned char *block)
+{
+ if ((block[0] == 0x00) && (block[1] == 0x00) &&
+ (block[2] == 0x00) && (block[3] == 0xff) &&
+ (block[4] == 0x00))
+ return 1;
+ else
+ return 0;
+}
+
+static int edid_is_ascii_block(unsigned char *block)
+{
+ if ((block[0] == 0x00) && (block[1] == 0x00) &&
+ (block[2] == 0x00) && (block[3] == 0xfe) &&
+ (block[4] == 0x00))
+ return 1;
+ else
+ return 0;
+}
+
+static int edid_is_limits_block(unsigned char *block)
+{
+ if ((block[0] == 0x00) && (block[1] == 0x00) &&
+ (block[2] == 0x00) && (block[3] == 0xfd) &&
+ (block[4] == 0x00))
+ return 1;
+ else
+ return 0;
+}
+
+static int edid_is_monitor_block(unsigned char *block)
+{
+ if ((block[0] == 0x00) && (block[1] == 0x00) &&
+ (block[2] == 0x00) && (block[3] == 0xfc) &&
+ (block[4] == 0x00))
+ return 1;
+ else
+ return 0;
+}
+
+static int edid_is_timing_block(unsigned char *block)
+{
+ if ((block[0] != 0x00) || (block[1] != 0x00) ||
+ (block[2] != 0x00) || (block[4] != 0x00))
+ return 1;
+ else
+ return 0;
+}
+
static int check_edid(unsigned char *edid)
{
unsigned char *block = edid + ID_MANUFACTURER_NAME, manufacturer[4];
@@ -104,9 +160,6 @@
for (i = 0; i < ARRAY_SIZE(brokendb); i++) {
if (!strncmp(manufacturer, brokendb[i].manufacturer, 4) &&
brokendb[i].model == model) {
- printk("fbmon: The EDID Block of "
- "Manufacturer: %s Model: 0x%x is known to "
- "be broken,\n", manufacturer, model);
fix = brokendb[i].fix;
break;
}
@@ -115,8 +168,10 @@
switch (fix) {
case FBMON_FIX_HEADER:
for (i = 0; i < 8; i++) {
- if (edid[i] != edid_v1_header[i])
+ if (edid[i] != edid_v1_header[i]) {
ret = fix;
+ break;
+ }
}
break;
case FBMON_FIX_INPUT:
@@ -126,14 +181,34 @@
if (b[4] & 0x01 && b[0] & 0x80)
ret = fix;
break;
+ case FBMON_FIX_TIMINGS:
+ b = edid + DETAILED_TIMING_DESCRIPTIONS_START;
+ ret = fix;
+
+ for (i = 0; i < 4; i++) {
+ if (edid_is_limits_block(b)) {
+ ret = 0;
+ break;
+ }
+
+ b += DETAILED_TIMING_DESCRIPTION_SIZE;
+ }
+
+ break;
}
+ if (ret)
+ printk("fbmon: The EDID Block of "
+ "Manufacturer: %s Model: 0x%x is known to "
+ "be broken,\n", manufacturer, model);
+
return ret;
}
static void fix_edid(unsigned char *edid, int fix)
{
- unsigned char *b;
+ int i;
+ unsigned char *b, csum = 0;
switch (fix) {
case FBMON_FIX_HEADER:
@@ -145,6 +220,37 @@
b = edid + EDID_STRUCT_DISPLAY;
b[0] &= ~0x80;
edid[127] += 0x80;
+ break;
+ case FBMON_FIX_TIMINGS:
+ printk("fbmon: trying to fix monitor timings\n");
+ b = edid + DETAILED_TIMING_DESCRIPTIONS_START;
+ for (i = 0; i < 4; i++) {
+ if (!(edid_is_serial_block(b) ||
+ edid_is_ascii_block(b) ||
+ edid_is_monitor_block(b) ||
+ edid_is_timing_block(b))) {
+ b[0] = 0x00;
+ b[1] = 0x00;
+ b[2] = 0x00;
+ b[3] = 0xfd;
+ b[4] = 0x00;
+ b[5] = 60; /* vfmin */
+ b[6] = 60; /* vfmax */
+ b[7] = 30; /* hfmin */
+ b[8] = 75; /* hfmax */
+ b[9] = 17; /* pixclock - 170 MHz*/
+ b[10] = 0; /* GTF */
+ break;
+ }
+
+ b += DETAILED_TIMING_DESCRIPTION_SIZE;
+ }
+
+ for (i = 0; i < EDID_LENGTH - 1; i++)
+ csum += edid[i];
+
+ edid[127] = 256 - csum;
+ break;
}
}
@@ -273,46 +379,6 @@
DPRINTK("WhiteY: 0.%03d\n", specs->chroma.whitey);
}
-static int edid_is_serial_block(unsigned char *block)
-{
- if ((block[0] == 0x00) && (block[1] == 0x00) &&
- (block[2] == 0x00) && (block[3] == 0xff) &&
- (block[4] == 0x00))
- return 1;
- else
- return 0;
-}
-
-static int edid_is_ascii_block(unsigned char *block)
-{
- if ((block[0] == 0x00) && (block[1] == 0x00) &&
- (block[2] == 0x00) && (block[3] == 0xfe) &&
- (block[4] == 0x00))
- return 1;
- else
- return 0;
-}
-
-static int edid_is_limits_block(unsigned char *block)
-{
- if ((block[0] == 0x00) && (block[1] == 0x00) &&
- (block[2] == 0x00) && (block[3] == 0xfd) &&
- (block[4] == 0x00))
- return 1;
- else
- return 0;
-}
-
-static int edid_is_monitor_block(unsigned char *block)
-{
- if ((block[0] == 0x00) && (block[1] == 0x00) &&
- (block[2] == 0x00) && (block[3] == 0xfc) &&
- (block[4] == 0x00))
- return 1;
- else
- return 0;
-}
-
static void calc_mode_timings(int xres, int yres, int refresh,
struct fb_videomode *mode)
{
@@ -795,15 +861,6 @@
}
}
-static int edid_is_timing_block(unsigned char *block)
-{
- if ((block[0] != 0x00) || (block[1] != 0x00) ||
- (block[2] != 0x00) || (block[4] != 0x00))
- return 1;
- else
- return 0;
-}
-
int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var)
{
int i;
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index 40c80c8..d4a2c11 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -376,7 +376,7 @@
{
struct fb_info *fb_info = dev_get_drvdata(device);
return snprintf(buf, PAGE_SIZE, "%d,%d\n", fb_info->var.xoffset,
- fb_info->var.xoffset);
+ fb_info->var.yoffset);
}
static ssize_t show_name(struct device *device,
diff --git a/drivers/video/hecubafb.c b/drivers/video/hecubafb.c
new file mode 100644
index 0000000..abfcb50
--- /dev/null
+++ b/drivers/video/hecubafb.c
@@ -0,0 +1,471 @@
+/*
+ * linux/drivers/video/hecubafb.c -- FB driver for Hecuba controller
+ *
+ * Copyright (C) 2006, Jaya Kumar
+ * This work was sponsored by CIS(M) Sdn Bhd
+ *
+ * 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.
+ *
+ * Layout is based on skeletonfb.c by James Simmons and Geert Uytterhoeven.
+ * This work was possible because of apollo display code from E-Ink's website
+ * http://support.eink.com/community
+ * All information used to write this code is from public material made
+ * available by E-Ink on its support site. Some commands such as 0xA4
+ * were found by looping through cmd=0x00 thru 0xFF and supplying random
+ * values. There are other commands that the display is capable of,
+ * beyond the 5 used here but they are more complex.
+ *
+ * This driver is written to be used with the Hecuba display controller
+ * board, and tested with the EInk 800x600 display in 1 bit mode.
+ * The interface between Hecuba and the host is TTL based GPIO. The
+ * GPIO requirements are 8 writable data lines and 6 lines for control.
+ * Only 4 of the controls are actually used here but 6 for future use.
+ * The driver requires the IO addresses for data and control GPIO at
+ * load time. It is also possible to use this display with a standard
+ * PC parallel port.
+ *
+ * General notes:
+ * - User must set hecubafb_enable=1 to enable it
+ * - User must set dio_addr=0xIOADDR cio_addr=0xIOADDR c2io_addr=0xIOADDR
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/list.h>
+#include <asm/uaccess.h>
+
+/* Apollo controller specific defines */
+#define APOLLO_START_NEW_IMG 0xA0
+#define APOLLO_STOP_IMG_DATA 0xA1
+#define APOLLO_DISPLAY_IMG 0xA2
+#define APOLLO_ERASE_DISPLAY 0xA3
+#define APOLLO_INIT_DISPLAY 0xA4
+
+/* Hecuba interface specific defines */
+/* WUP is inverted, CD is inverted, DS is inverted */
+#define HCB_NWUP_BIT 0x01
+#define HCB_NDS_BIT 0x02
+#define HCB_RW_BIT 0x04
+#define HCB_NCD_BIT 0x08
+#define HCB_ACK_BIT 0x80
+
+/* Display specific information */
+#define DPY_W 600
+#define DPY_H 800
+
+struct hecubafb_par {
+ unsigned long dio_addr;
+ unsigned long cio_addr;
+ unsigned long c2io_addr;
+ unsigned char ctl;
+ struct fb_info *info;
+ unsigned int irq;
+};
+
+static struct fb_fix_screeninfo hecubafb_fix __devinitdata = {
+ .id = "hecubafb",
+ .type = FB_TYPE_PACKED_PIXELS,
+ .visual = FB_VISUAL_MONO01,
+ .xpanstep = 0,
+ .ypanstep = 0,
+ .ywrapstep = 0,
+ .accel = FB_ACCEL_NONE,
+};
+
+static struct fb_var_screeninfo hecubafb_var __devinitdata = {
+ .xres = DPY_W,
+ .yres = DPY_H,
+ .xres_virtual = DPY_W,
+ .yres_virtual = DPY_H,
+ .bits_per_pixel = 1,
+ .nonstd = 1,
+};
+
+static unsigned long dio_addr;
+static unsigned long cio_addr;
+static unsigned long c2io_addr;
+static unsigned long splashval;
+static unsigned int nosplash;
+static unsigned int hecubafb_enable;
+static unsigned int irq;
+
+static DECLARE_WAIT_QUEUE_HEAD(hecubafb_waitq);
+
+static void hcb_set_ctl(struct hecubafb_par *par)
+{
+ outb(par->ctl, par->cio_addr);
+}
+
+static unsigned char hcb_get_ctl(struct hecubafb_par *par)
+{
+ return inb(par->c2io_addr);
+}
+
+static void hcb_set_data(struct hecubafb_par *par, unsigned char value)
+{
+ outb(value, par->dio_addr);
+}
+
+static int __devinit apollo_init_control(struct hecubafb_par *par)
+{
+ unsigned char ctl;
+ /* for init, we want the following setup to be set:
+ WUP = lo
+ ACK = hi
+ DS = hi
+ RW = hi
+ CD = lo
+ */
+
+ /* write WUP to lo, DS to hi, RW to hi, CD to lo */
+ par->ctl = HCB_NWUP_BIT | HCB_RW_BIT | HCB_NCD_BIT ;
+ par->ctl &= ~HCB_NDS_BIT;
+ hcb_set_ctl(par);
+
+ /* check ACK is not lo */
+ ctl = hcb_get_ctl(par);
+ if ((ctl & HCB_ACK_BIT)) {
+ printk(KERN_ERR "Fail because ACK is already low\n");
+ return -ENXIO;
+ }
+
+ return 0;
+}
+
+static void hcb_wait_for_ack(struct hecubafb_par *par)
+{
+
+ int timeout;
+ unsigned char ctl;
+
+ timeout=500;
+ do {
+ ctl = hcb_get_ctl(par);
+ if ((ctl & HCB_ACK_BIT))
+ return;
+ udelay(1);
+ } while (timeout--);
+ printk(KERN_ERR "timed out waiting for ack\n");
+}
+
+static void hcb_wait_for_ack_clear(struct hecubafb_par *par)
+{
+
+ int timeout;
+ unsigned char ctl;
+
+ timeout=500;
+ do {
+ ctl = hcb_get_ctl(par);
+ if (!(ctl & HCB_ACK_BIT))
+ return;
+ udelay(1);
+ } while (timeout--);
+ printk(KERN_ERR "timed out waiting for clear\n");
+}
+
+static void apollo_send_data(struct hecubafb_par *par, unsigned char data)
+{
+ /* set data */
+ hcb_set_data(par, data);
+
+ /* set DS low */
+ par->ctl |= HCB_NDS_BIT;
+ hcb_set_ctl(par);
+
+ hcb_wait_for_ack(par);
+
+ /* set DS hi */
+ par->ctl &= ~(HCB_NDS_BIT);
+ hcb_set_ctl(par);
+
+ hcb_wait_for_ack_clear(par);
+}
+
+static void apollo_send_command(struct hecubafb_par *par, unsigned char data)
+{
+ /* command so set CD to high */
+ par->ctl &= ~(HCB_NCD_BIT);
+ hcb_set_ctl(par);
+
+ /* actually strobe with command */
+ apollo_send_data(par, data);
+
+ /* clear CD back to low */
+ par->ctl |= (HCB_NCD_BIT);
+ hcb_set_ctl(par);
+}
+
+/* main hecubafb functions */
+
+static void hecubafb_dpy_update(struct hecubafb_par *par)
+{
+ int i;
+ unsigned char *buf = (unsigned char __force *)par->info->screen_base;
+
+ apollo_send_command(par, 0xA0);
+
+ for (i=0; i < (DPY_W*DPY_H/8); i++) {
+ apollo_send_data(par, *(buf++));
+ }
+
+ apollo_send_command(par, 0xA1);
+ apollo_send_command(par, 0xA2);
+}
+
+/* this is called back from the deferred io workqueue */
+static void hecubafb_dpy_deferred_io(struct fb_info *info,
+ struct list_head *pagelist)
+{
+ hecubafb_dpy_update(info->par);
+}
+
+static void hecubafb_fillrect(struct fb_info *info,
+ const struct fb_fillrect *rect)
+{
+ struct hecubafb_par *par = info->par;
+
+ sys_fillrect(info, rect);
+
+ hecubafb_dpy_update(par);
+}
+
+static void hecubafb_copyarea(struct fb_info *info,
+ const struct fb_copyarea *area)
+{
+ struct hecubafb_par *par = info->par;
+
+ sys_copyarea(info, area);
+
+ hecubafb_dpy_update(par);
+}
+
+static void hecubafb_imageblit(struct fb_info *info,
+ const struct fb_image *image)
+{
+ struct hecubafb_par *par = info->par;
+
+ sys_imageblit(info, image);
+
+ hecubafb_dpy_update(par);
+}
+
+/*
+ * this is the slow path from userspace. they can seek and write to
+ * the fb. it's inefficient to do anything less than a full screen draw
+ */
+static ssize_t hecubafb_write(struct fb_info *info, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ unsigned long p;
+ int err=-EINVAL;
+ struct hecubafb_par *par;
+ unsigned int xres;
+ unsigned int fbmemlength;
+
+ p = *ppos;
+ par = info->par;
+ xres = info->var.xres;
+ fbmemlength = (xres * info->var.yres)/8;
+
+ if (p > fbmemlength)
+ return -ENOSPC;
+
+ err = 0;
+ if ((count + p) > fbmemlength) {
+ count = fbmemlength - p;
+ err = -ENOSPC;
+ }
+
+ if (count) {
+ char *base_addr;
+
+ base_addr = (char __force *)info->screen_base;
+ count -= copy_from_user(base_addr + p, buf, count);
+ *ppos += count;
+ err = -EFAULT;
+ }
+
+ hecubafb_dpy_update(par);
+
+ if (count)
+ return count;
+
+ return err;
+}
+
+static struct fb_ops hecubafb_ops = {
+ .owner = THIS_MODULE,
+ .fb_read = fb_sys_read,
+ .fb_write = hecubafb_write,
+ .fb_fillrect = hecubafb_fillrect,
+ .fb_copyarea = hecubafb_copyarea,
+ .fb_imageblit = hecubafb_imageblit,
+};
+
+static struct fb_deferred_io hecubafb_defio = {
+ .delay = HZ,
+ .deferred_io = hecubafb_dpy_deferred_io,
+};
+
+static int __devinit hecubafb_probe(struct platform_device *dev)
+{
+ struct fb_info *info;
+ int retval = -ENOMEM;
+ int videomemorysize;
+ unsigned char *videomemory;
+ struct hecubafb_par *par;
+
+ videomemorysize = (DPY_W*DPY_H)/8;
+
+ if (!(videomemory = vmalloc(videomemorysize)))
+ return retval;
+
+ memset(videomemory, 0, videomemorysize);
+
+ info = framebuffer_alloc(sizeof(struct hecubafb_par), &dev->dev);
+ if (!info)
+ goto err;
+
+ info->screen_base = (char __iomem *) videomemory;
+ info->fbops = &hecubafb_ops;
+
+ info->var = hecubafb_var;
+ info->fix = hecubafb_fix;
+ info->fix.smem_len = videomemorysize;
+ par = info->par;
+ par->info = info;
+
+ if (!dio_addr || !cio_addr || !c2io_addr) {
+ printk(KERN_WARNING "no IO addresses supplied\n");
+ goto err1;
+ }
+ par->dio_addr = dio_addr;
+ par->cio_addr = cio_addr;
+ par->c2io_addr = c2io_addr;
+ info->flags = FBINFO_FLAG_DEFAULT;
+
+ info->fbdefio = &hecubafb_defio;
+ fb_deferred_io_init(info);
+
+ retval = register_framebuffer(info);
+ if (retval < 0)
+ goto err1;
+ platform_set_drvdata(dev, info);
+
+ printk(KERN_INFO
+ "fb%d: Hecuba frame buffer device, using %dK of video memory\n",
+ info->node, videomemorysize >> 10);
+
+ /* this inits the dpy */
+ apollo_init_control(par);
+
+ apollo_send_command(par, APOLLO_INIT_DISPLAY);
+ apollo_send_data(par, 0x81);
+
+ /* have to wait while display resets */
+ udelay(1000);
+
+ /* if we were told to splash the screen, we just clear it */
+ if (!nosplash) {
+ apollo_send_command(par, APOLLO_ERASE_DISPLAY);
+ apollo_send_data(par, splashval);
+ }
+
+ return 0;
+err1:
+ framebuffer_release(info);
+err:
+ vfree(videomemory);
+ return retval;
+}
+
+static int __devexit hecubafb_remove(struct platform_device *dev)
+{
+ struct fb_info *info = platform_get_drvdata(dev);
+
+ if (info) {
+ fb_deferred_io_cleanup(info);
+ unregister_framebuffer(info);
+ vfree((void __force *)info->screen_base);
+ framebuffer_release(info);
+ }
+ return 0;
+}
+
+static struct platform_driver hecubafb_driver = {
+ .probe = hecubafb_probe,
+ .remove = hecubafb_remove,
+ .driver = {
+ .name = "hecubafb",
+ },
+};
+
+static struct platform_device *hecubafb_device;
+
+static int __init hecubafb_init(void)
+{
+ int ret;
+
+ if (!hecubafb_enable) {
+ printk(KERN_ERR "Use hecubafb_enable to enable the device\n");
+ return -ENXIO;
+ }
+
+ ret = platform_driver_register(&hecubafb_driver);
+ if (!ret) {
+ hecubafb_device = platform_device_alloc("hecubafb", 0);
+ if (hecubafb_device)
+ ret = platform_device_add(hecubafb_device);
+ else
+ ret = -ENOMEM;
+
+ if (ret) {
+ platform_device_put(hecubafb_device);
+ platform_driver_unregister(&hecubafb_driver);
+ }
+ }
+ return ret;
+
+}
+
+static void __exit hecubafb_exit(void)
+{
+ platform_device_unregister(hecubafb_device);
+ platform_driver_unregister(&hecubafb_driver);
+}
+
+module_param(nosplash, uint, 0);
+MODULE_PARM_DESC(nosplash, "Disable doing the splash screen");
+module_param(hecubafb_enable, uint, 0);
+MODULE_PARM_DESC(hecubafb_enable, "Enable communication with Hecuba board");
+module_param(dio_addr, ulong, 0);
+MODULE_PARM_DESC(dio_addr, "IO address for data, eg: 0x480");
+module_param(cio_addr, ulong, 0);
+MODULE_PARM_DESC(cio_addr, "IO address for control, eg: 0x400");
+module_param(c2io_addr, ulong, 0);
+MODULE_PARM_DESC(c2io_addr, "IO address for secondary control, eg: 0x408");
+module_param(splashval, ulong, 0);
+MODULE_PARM_DESC(splashval, "Splash pattern: 0x00 is black, 0x01 is white");
+module_param(irq, uint, 0);
+MODULE_PARM_DESC(irq, "IRQ for the Hecuba board");
+
+module_init(hecubafb_init);
+module_exit(hecubafb_exit);
+
+MODULE_DESCRIPTION("fbdev driver for Hecuba board");
+MODULE_AUTHOR("Jaya Kumar");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/i810/i810.h b/drivers/video/i810/i810.h
index aa65ffc..889e4ea 100644
--- a/drivers/video/i810/i810.h
+++ b/drivers/video/i810/i810.h
@@ -133,7 +133,7 @@
/* Masks (AND ops) and OR's */
#define FB_START_MASK (0x3f << (32 - 6))
#define MMIO_ADDR_MASK (0x1FFF << (32 - 13))
-#define FREQ_MASK 0x1EF
+#define FREQ_MASK (1 << 4)
#define SCR_OFF 0x20
#define DRAM_ON 0x08
#define DRAM_OFF 0xE7
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index c1eb18b..16bc8d7 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -1428,6 +1428,24 @@
static void reset_state(struct intelfb_info *dinfo);
static void do_flush(struct intelfb_info *dinfo);
+static u32 get_ring_space(struct intelfb_info *dinfo)
+{
+ u32 ring_space;
+
+ if (dinfo->ring_tail >= dinfo->ring_head)
+ ring_space = dinfo->ring.size -
+ (dinfo->ring_tail - dinfo->ring_head);
+ else
+ ring_space = dinfo->ring_head - dinfo->ring_tail;
+
+ if (ring_space > RING_MIN_FREE)
+ ring_space -= RING_MIN_FREE;
+ else
+ ring_space = 0;
+
+ return ring_space;
+}
+
static int
wait_ring(struct intelfb_info *dinfo, int n)
{
@@ -1442,13 +1460,8 @@
end = jiffies + (HZ * 3);
while (dinfo->ring_space < n) {
dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK;
- if (dinfo->ring_tail + RING_MIN_FREE < dinfo->ring_head)
- dinfo->ring_space = dinfo->ring_head
- - (dinfo->ring_tail + RING_MIN_FREE);
- else
- dinfo->ring_space = (dinfo->ring.size +
- dinfo->ring_head)
- - (dinfo->ring_tail + RING_MIN_FREE);
+ dinfo->ring_space = get_ring_space(dinfo);
+
if (dinfo->ring_head != last_head) {
end = jiffies + (HZ * 3);
last_head = dinfo->ring_head;
@@ -1513,12 +1526,7 @@
dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK;
dinfo->ring_tail = INREG(PRI_RING_TAIL) & RING_TAIL_MASK;
- if (dinfo->ring_tail + RING_MIN_FREE < dinfo->ring_head)
- dinfo->ring_space = dinfo->ring_head
- - (dinfo->ring_tail + RING_MIN_FREE);
- else
- dinfo->ring_space = (dinfo->ring.size + dinfo->ring_head)
- - (dinfo->ring_tail + RING_MIN_FREE);
+ dinfo->ring_space = get_ring_space(dinfo);
}
static void
diff --git a/drivers/video/logo/Kconfig b/drivers/video/logo/Kconfig
index f0e6512..9397bce 100644
--- a/drivers/video/logo/Kconfig
+++ b/drivers/video/logo/Kconfig
@@ -2,73 +2,69 @@
# Logo configuration
#
-menu "Logo configuration"
-
-config LOGO
+menuconfig LOGO
bool "Bootup logo"
depends on FB || SGI_NEWPORT_CONSOLE
help
Enable and select frame buffer bootup logos.
+if LOGO
+
config LOGO_LINUX_MONO
bool "Standard black and white Linux logo"
- depends on LOGO
default y
config LOGO_LINUX_VGA16
bool "Standard 16-color Linux logo"
- depends on LOGO
default y
config LOGO_LINUX_CLUT224
bool "Standard 224-color Linux logo"
- depends on LOGO
default y
config LOGO_DEC_CLUT224
bool "224-color Digital Equipment Corporation Linux logo"
- depends on LOGO && (MACH_DECSTATION || ALPHA)
+ depends on MACH_DECSTATION || ALPHA
default y
config LOGO_MAC_CLUT224
bool "224-color Macintosh Linux logo"
- depends on LOGO && MAC
+ depends on MAC
default y
config LOGO_PARISC_CLUT224
bool "224-color PA-RISC Linux logo"
- depends on LOGO && PARISC
+ depends on PARISC
default y
config LOGO_SGI_CLUT224
bool "224-color SGI Linux logo"
- depends on LOGO && (SGI_IP22 || SGI_IP27 || SGI_IP32 || X86_VISWS)
+ depends on SGI_IP22 || SGI_IP27 || SGI_IP32 || X86_VISWS
default y
config LOGO_SUN_CLUT224
bool "224-color Sun Linux logo"
- depends on LOGO && SPARC
+ depends on SPARC
default y
config LOGO_SUPERH_MONO
bool "Black and white SuperH Linux logo"
- depends on LOGO && SUPERH
+ depends on SUPERH
default y
config LOGO_SUPERH_VGA16
bool "16-color SuperH Linux logo"
- depends on LOGO && SUPERH
+ depends on SUPERH
default y
config LOGO_SUPERH_CLUT224
bool "224-color SuperH Linux logo"
- depends on LOGO && SUPERH
+ depends on SUPERH
default y
config LOGO_M32R_CLUT224
bool "224-color M32R Linux logo"
- depends on LOGO && M32R
+ depends on M32R
default y
-endmenu
-
+endif # LOGO
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index 3e51794..3741ad7 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -395,7 +395,7 @@
for (;; name++) {
switch (*name) {
- case '0'...'9':
+ case '0' ... '9':
val = 10*val+(*name-'0');
break;
default:
@@ -548,7 +548,7 @@
} else
goto done;
break;
- case '0'...'9':
+ case '0' ... '9':
break;
case 'M':
if (!yres_specified)
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c
index 395cced..bd30aba 100644
--- a/drivers/video/neofb.c
+++ b/drivers/video/neofb.c
@@ -665,6 +665,7 @@
var->red.msb_right = 0;
var->green.msb_right = 0;
var->blue.msb_right = 0;
+ var->transp.msb_right = 0;
switch (var->bits_per_pixel) {
case 8: /* PSEUDOCOLOUR, 256 */
diff --git a/drivers/video/nvidia/nv_accel.c b/drivers/video/nvidia/nv_accel.c
index 9efb8a3..fa4821c 100644
--- a/drivers/video/nvidia/nv_accel.c
+++ b/drivers/video/nvidia/nv_accel.c
@@ -69,27 +69,38 @@
0x5A, /* invert */
};
-static inline void NVFlush(struct nvidia_par *par)
+static inline void nvidiafb_safe_mode(struct fb_info *info)
{
+ struct nvidia_par *par = info->par;
+
+ touch_softlockup_watchdog();
+ info->pixmap.scan_align = 1;
+ par->lockup = 1;
+}
+
+static inline void NVFlush(struct fb_info *info)
+{
+ struct nvidia_par *par = info->par;
int count = 1000000000;
while (--count && READ_GET(par) != par->dmaPut) ;
if (!count) {
printk("nvidiafb: DMA Flush lockup\n");
- par->lockup = 1;
+ nvidiafb_safe_mode(info);
}
}
-static inline void NVSync(struct nvidia_par *par)
+static inline void NVSync(struct fb_info *info)
{
+ struct nvidia_par *par = info->par;
int count = 1000000000;
while (--count && NV_RD32(par->PGRAPH, 0x0700)) ;
if (!count) {
printk("nvidiafb: DMA Sync lockup\n");
- par->lockup = 1;
+ nvidiafb_safe_mode(info);
}
}
@@ -101,8 +112,9 @@
}
}
-static void NVDmaWait(struct nvidia_par *par, int size)
+static void NVDmaWait(struct fb_info *info, int size)
{
+ struct nvidia_par *par = info->par;
int dmaGet;
int count = 1000000000, cnt;
size++;
@@ -135,34 +147,38 @@
}
if (!count) {
- printk("DMA Wait Lockup\n");
- par->lockup = 1;
+ printk("nvidiafb: DMA Wait Lockup\n");
+ nvidiafb_safe_mode(info);
}
}
-static void NVSetPattern(struct nvidia_par *par, u32 clr0, u32 clr1,
+static void NVSetPattern(struct fb_info *info, u32 clr0, u32 clr1,
u32 pat0, u32 pat1)
{
- NVDmaStart(par, PATTERN_COLOR_0, 4);
+ struct nvidia_par *par = info->par;
+
+ NVDmaStart(info, par, PATTERN_COLOR_0, 4);
NVDmaNext(par, clr0);
NVDmaNext(par, clr1);
NVDmaNext(par, pat0);
NVDmaNext(par, pat1);
}
-static void NVSetRopSolid(struct nvidia_par *par, u32 rop, u32 planemask)
+static void NVSetRopSolid(struct fb_info *info, u32 rop, u32 planemask)
{
+ struct nvidia_par *par = info->par;
+
if (planemask != ~0) {
- NVSetPattern(par, 0, planemask, ~0, ~0);
+ NVSetPattern(info, 0, planemask, ~0, ~0);
if (par->currentRop != (rop + 32)) {
- NVDmaStart(par, ROP_SET, 1);
+ NVDmaStart(info, par, ROP_SET, 1);
NVDmaNext(par, NVCopyROP_PM[rop]);
par->currentRop = rop + 32;
}
} else if (par->currentRop != rop) {
if (par->currentRop >= 16)
- NVSetPattern(par, ~0, ~0, ~0, ~0);
- NVDmaStart(par, ROP_SET, 1);
+ NVSetPattern(info, ~0, ~0, ~0, ~0);
+ NVDmaStart(info, par, ROP_SET, 1);
NVDmaNext(par, NVCopyROP[rop]);
par->currentRop = rop;
}
@@ -175,7 +191,7 @@
int h = y2 - y1 + 1;
int w = x2 - x1 + 1;
- NVDmaStart(par, CLIP_POINT, 2);
+ NVDmaStart(info, par, CLIP_POINT, 2);
NVDmaNext(par, (y1 << 16) | x1);
NVDmaNext(par, (h << 16) | w);
}
@@ -237,23 +253,23 @@
break;
}
- NVDmaStart(par, SURFACE_FORMAT, 4);
+ NVDmaStart(info, par, SURFACE_FORMAT, 4);
NVDmaNext(par, surfaceFormat);
NVDmaNext(par, pitch | (pitch << 16));
NVDmaNext(par, 0);
NVDmaNext(par, 0);
- NVDmaStart(par, PATTERN_FORMAT, 1);
+ NVDmaStart(info, par, PATTERN_FORMAT, 1);
NVDmaNext(par, patternFormat);
- NVDmaStart(par, RECT_FORMAT, 1);
+ NVDmaStart(info, par, RECT_FORMAT, 1);
NVDmaNext(par, rectFormat);
- NVDmaStart(par, LINE_FORMAT, 1);
+ NVDmaStart(info, par, LINE_FORMAT, 1);
NVDmaNext(par, lineFormat);
par->currentRop = ~0; /* set to something invalid */
- NVSetRopSolid(par, ROP_COPY, ~0);
+ NVSetRopSolid(info, ROP_COPY, ~0);
NVSetClippingRectangle(info, 0, 0, info->var.xres_virtual,
info->var.yres_virtual);
@@ -269,10 +285,10 @@
return 0;
if (!par->lockup)
- NVFlush(par);
+ NVFlush(info);
if (!par->lockup)
- NVSync(par);
+ NVSync(info);
return 0;
}
@@ -287,7 +303,7 @@
if (par->lockup)
return cfb_copyarea(info, region);
- NVDmaStart(par, BLIT_POINT_SRC, 3);
+ NVDmaStart(info, par, BLIT_POINT_SRC, 3);
NVDmaNext(par, (region->sy << 16) | region->sx);
NVDmaNext(par, (region->dy << 16) | region->dx);
NVDmaNext(par, (region->height << 16) | region->width);
@@ -312,19 +328,19 @@
color = ((u32 *) info->pseudo_palette)[rect->color];
if (rect->rop != ROP_COPY)
- NVSetRopSolid(par, rect->rop, ~0);
+ NVSetRopSolid(info, rect->rop, ~0);
- NVDmaStart(par, RECT_SOLID_COLOR, 1);
+ NVDmaStart(info, par, RECT_SOLID_COLOR, 1);
NVDmaNext(par, color);
- NVDmaStart(par, RECT_SOLID_RECTS(0), 2);
+ NVDmaStart(info, par, RECT_SOLID_RECTS(0), 2);
NVDmaNext(par, (rect->dx << 16) | rect->dy);
NVDmaNext(par, (rect->width << 16) | rect->height);
NVDmaKickoff(par);
if (rect->rop != ROP_COPY)
- NVSetRopSolid(par, ROP_COPY, ~0);
+ NVSetRopSolid(info, ROP_COPY, ~0);
}
static void nvidiafb_mono_color_expand(struct fb_info *info,
@@ -346,7 +362,7 @@
bg = ((u32 *) info->pseudo_palette)[image->bg_color] | mask;
}
- NVDmaStart(par, RECT_EXPAND_TWO_COLOR_CLIP, 7);
+ NVDmaStart(info, par, RECT_EXPAND_TWO_COLOR_CLIP, 7);
NVDmaNext(par, (image->dy << 16) | (image->dx & 0xffff));
NVDmaNext(par, ((image->dy + image->height) << 16) |
((image->dx + image->width) & 0xffff));
@@ -357,7 +373,7 @@
NVDmaNext(par, (image->dy << 16) | (image->dx & 0xffff));
while (dsize >= RECT_EXPAND_TWO_COLOR_DATA_MAX_DWORDS) {
- NVDmaStart(par, RECT_EXPAND_TWO_COLOR_DATA(0),
+ NVDmaStart(info, par, RECT_EXPAND_TWO_COLOR_DATA(0),
RECT_EXPAND_TWO_COLOR_DATA_MAX_DWORDS);
for (j = RECT_EXPAND_TWO_COLOR_DATA_MAX_DWORDS; j--;) {
@@ -370,7 +386,7 @@
}
if (dsize) {
- NVDmaStart(par, RECT_EXPAND_TWO_COLOR_DATA(0), dsize);
+ NVDmaStart(info, par, RECT_EXPAND_TWO_COLOR_DATA(0), dsize);
for (j = dsize; j--;) {
tmp = data[k++];
diff --git a/drivers/video/nvidia/nv_hw.c b/drivers/video/nvidia/nv_hw.c
index ea42611..f297c7b 100644
--- a/drivers/video/nvidia/nv_hw.c
+++ b/drivers/video/nvidia/nv_hw.c
@@ -686,7 +686,7 @@
if ((par->Chipset & 0x0FF0) == 0x01A0) {
unsigned int uMClkPostDiv;
- dev = pci_find_slot(0, 3);
+ dev = pci_get_bus_and_slot(0, 3);
pci_read_config_dword(dev, 0x6C, &uMClkPostDiv);
uMClkPostDiv = (uMClkPostDiv >> 8) & 0xf;
@@ -694,11 +694,11 @@
uMClkPostDiv = 4;
MClk = 400000 / uMClkPostDiv;
} else {
- dev = pci_find_slot(0, 5);
+ dev = pci_get_bus_and_slot(0, 5);
pci_read_config_dword(dev, 0x4c, &MClk);
MClk /= 1000;
}
-
+ pci_dev_put(dev);
pll = NV_RD32(par->PRAMDAC0, 0x0500);
M = (pll >> 0) & 0xFF;
N = (pll >> 8) & 0xFF;
@@ -707,19 +707,21 @@
sim_data.pix_bpp = (char)pixelDepth;
sim_data.enable_video = 0;
sim_data.enable_mp = 0;
- pci_find_slot(0, 1);
+ dev = pci_get_bus_and_slot(0, 1);
pci_read_config_dword(dev, 0x7C, &sim_data.memory_type);
+ pci_dev_put(dev);
sim_data.memory_type = (sim_data.memory_type >> 12) & 1;
sim_data.memory_width = 64;
- dev = pci_find_slot(0, 3);
+ dev = pci_get_bus_and_slot(0, 3);
pci_read_config_dword(dev, 0, &memctrl);
+ pci_dev_put(dev);
memctrl >>= 16;
if ((memctrl == 0x1A9) || (memctrl == 0x1AB) || (memctrl == 0x1ED)) {
int dimm[3];
- pci_find_slot(0, 2);
+ dev = pci_get_bus_and_slot(0, 2);
pci_read_config_dword(dev, 0x40, &dimm[0]);
dimm[0] = (dimm[0] >> 8) & 0x4f;
pci_read_config_dword(dev, 0x44, &dimm[1]);
@@ -731,6 +733,7 @@
printk("nvidiafb: your nForce DIMMs are not arranged "
"in optimal banks!\n");
}
+ pci_dev_put(dev);
}
sim_data.mem_latency = 3;
diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/nvidia/nv_i2c.c
index b858897..afe4567 100644
--- a/drivers/video/nvidia/nv_i2c.c
+++ b/drivers/video/nvidia/nv_i2c.c
@@ -30,16 +30,14 @@
struct nvidia_par *par = chan->par;
u32 val;
- VGA_WR08(par->PCIO, 0x3d4, chan->ddc_base + 1);
- val = VGA_RD08(par->PCIO, 0x3d5) & 0xf0;
+ val = NVReadCrtc(par, chan->ddc_base + 1) & 0xf0;
if (state)
val |= 0x20;
else
val &= ~0x20;
- VGA_WR08(par->PCIO, 0x3d4, chan->ddc_base + 1);
- VGA_WR08(par->PCIO, 0x3d5, val | 0x1);
+ NVWriteCrtc(par, chan->ddc_base + 1, val | 0x01);
}
static void nvidia_gpio_setsda(void *data, int state)
@@ -48,16 +46,14 @@
struct nvidia_par *par = chan->par;
u32 val;
- VGA_WR08(par->PCIO, 0x3d4, chan->ddc_base + 1);
- val = VGA_RD08(par->PCIO, 0x3d5) & 0xf0;
+ val = NVReadCrtc(par, chan->ddc_base + 1) & 0xf0;
if (state)
val |= 0x10;
else
val &= ~0x10;
- VGA_WR08(par->PCIO, 0x3d4, chan->ddc_base + 1);
- VGA_WR08(par->PCIO, 0x3d5, val | 0x1);
+ NVWriteCrtc(par, chan->ddc_base + 1, val | 0x01);
}
static int nvidia_gpio_getscl(void *data)
@@ -66,12 +62,9 @@
struct nvidia_par *par = chan->par;
u32 val = 0;
- VGA_WR08(par->PCIO, 0x3d4, chan->ddc_base);
- if (VGA_RD08(par->PCIO, 0x3d5) & 0x04)
+ if (NVReadCrtc(par, chan->ddc_base) & 0x04)
val = 1;
- val = VGA_RD08(par->PCIO, 0x3d5);
-
return val;
}
@@ -81,20 +74,21 @@
struct nvidia_par *par = chan->par;
u32 val = 0;
- VGA_WR08(par->PCIO, 0x3d4, chan->ddc_base);
- if (VGA_RD08(par->PCIO, 0x3d5) & 0x08)
+ if (NVReadCrtc(par, chan->ddc_base) & 0x08)
val = 1;
return val;
}
-static int nvidia_setup_i2c_bus(struct nvidia_i2c_chan *chan, const char *name)
+static int nvidia_setup_i2c_bus(struct nvidia_i2c_chan *chan, const char *name,
+ unsigned int i2c_class)
{
int rc;
strcpy(chan->adapter.name, name);
chan->adapter.owner = THIS_MODULE;
chan->adapter.id = I2C_HW_B_NVIDIA;
+ chan->adapter.class = i2c_class;
chan->adapter.algo_data = &chan->algo;
chan->adapter.dev.parent = &chan->par->pci_dev->dev;
chan->algo.setsda = nvidia_gpio_setsda;
@@ -127,83 +121,39 @@
void nvidia_create_i2c_busses(struct nvidia_par *par)
{
- par->bus = 3;
-
par->chan[0].par = par;
par->chan[1].par = par;
par->chan[2].par = par;
- par->chan[0].ddc_base = 0x3e;
- nvidia_setup_i2c_bus(&par->chan[0], "nvidia #0");
+ par->chan[0].ddc_base = 0x36;
+ nvidia_setup_i2c_bus(&par->chan[0], "nvidia #0", I2C_CLASS_HWMON);
- par->chan[1].ddc_base = 0x36;
- nvidia_setup_i2c_bus(&par->chan[1], "nvidia #1");
+ par->chan[1].ddc_base = 0x3e;
+ nvidia_setup_i2c_bus(&par->chan[1], "nvidia #1", 0);
par->chan[2].ddc_base = 0x50;
- nvidia_setup_i2c_bus(&par->chan[2], "nvidia #2");
+ nvidia_setup_i2c_bus(&par->chan[2], "nvidia #2", 0);
}
void nvidia_delete_i2c_busses(struct nvidia_par *par)
{
- if (par->chan[0].par)
- i2c_del_adapter(&par->chan[0].adapter);
- par->chan[0].par = NULL;
+ int i;
- if (par->chan[1].par)
- i2c_del_adapter(&par->chan[1].adapter);
- par->chan[1].par = NULL;
-
- if (par->chan[2].par)
- i2c_del_adapter(&par->chan[2].adapter);
- par->chan[2].par = NULL;
-
-}
-
-static u8 *nvidia_do_probe_i2c_edid(struct nvidia_i2c_chan *chan)
-{
- u8 start = 0x0;
- struct i2c_msg msgs[] = {
- {
- .addr = 0x50,
- .len = 1,
- .buf = &start,
- }, {
- .addr = 0x50,
- .flags = I2C_M_RD,
- .len = EDID_LENGTH,
- },
- };
- u8 *buf;
-
- if (!chan->par)
- return NULL;
-
- buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
- if (!buf) {
- dev_warn(&chan->par->pci_dev->dev, "Out of memory!\n");
- return NULL;
+ for (i = 0; i < 3; i++) {
+ if (!par->chan[i].par)
+ continue;
+ i2c_del_adapter(&par->chan[i].adapter);
+ par->chan[i].par = NULL;
}
- msgs[1].buf = buf;
-
- if (i2c_transfer(&chan->adapter, msgs, 2) == 2)
- return buf;
- dev_dbg(&chan->par->pci_dev->dev, "Unable to read EDID block.\n");
- kfree(buf);
- return NULL;
}
int nvidia_probe_i2c_connector(struct fb_info *info, int conn, u8 **out_edid)
{
struct nvidia_par *par = info->par;
u8 *edid = NULL;
- int i;
- for (i = 0; i < 3; i++) {
- /* Do the real work */
- edid = nvidia_do_probe_i2c_edid(&par->chan[conn - 1]);
- if (edid)
- break;
- }
+ if (par->chan[conn - 1].par)
+ edid = fb_ddc_read(&par->chan[conn - 1].adapter);
if (!edid && conn == 1) {
/* try to get from firmware */
diff --git a/drivers/video/nvidia/nv_local.h b/drivers/video/nvidia/nv_local.h
index e009d24..68e508d 100644
--- a/drivers/video/nvidia/nv_local.h
+++ b/drivers/video/nvidia/nv_local.h
@@ -73,9 +73,9 @@
#define NVDmaNext(par, data) \
NV_WR32(&(par)->dmaBase[(par)->dmaCurrent++], 0, (data))
-#define NVDmaStart(par, tag, size) { \
+#define NVDmaStart(info, par, tag, size) { \
if((par)->dmaFree <= (size)) \
- NVDmaWait(par, size); \
+ NVDmaWait(info, size); \
NVDmaNext(par, ((size) << 18) | (tag)); \
(par)->dmaFree -= ((size) + 1); \
}
diff --git a/drivers/video/nvidia/nv_of.c b/drivers/video/nvidia/nv_of.c
index 163a774..73afd7e 100644
--- a/drivers/video/nvidia/nv_of.c
+++ b/drivers/video/nvidia/nv_of.c
@@ -46,15 +46,15 @@
for (dp = NULL;
(dp = of_get_next_child(parent, dp)) != NULL;) {
- pname = get_property(dp, "name", NULL);
+ pname = of_get_property(dp, "name", NULL);
if (!pname)
continue;
len = strlen(pname);
if ((pname[len-1] == 'A' && conn == 1) ||
(pname[len-1] == 'B' && conn == 2)) {
for (i = 0; propnames[i] != NULL; ++i) {
- pedid = get_property(dp, propnames[i],
- NULL);
+ pedid = of_get_property(dp,
+ propnames[i], NULL);
if (pedid != NULL)
break;
}
@@ -65,7 +65,7 @@
}
if (pedid == NULL) {
for (i = 0; propnames[i] != NULL; ++i) {
- pedid = get_property(parent, propnames[i], NULL);
+ pedid = of_get_property(parent, propnames[i], NULL);
if (pedid != NULL)
break;
}
diff --git a/drivers/video/nvidia/nv_setup.c b/drivers/video/nvidia/nv_setup.c
index eab3e28..707e2c8 100644
--- a/drivers/video/nvidia/nv_setup.c
+++ b/drivers/video/nvidia/nv_setup.c
@@ -261,7 +261,7 @@
}
#endif
- dev = pci_find_slot(0, 1);
+ dev = pci_get_bus_and_slot(0, 1);
if ((par->Chipset & 0xffff) == 0x01a0) {
int amt = 0;
@@ -276,6 +276,7 @@
par->RamAmountKBytes =
(NV_RD32(par->PFB, 0x020C) & 0xFFF00000) >> 10;
}
+ pci_dev_put(dev);
par->CrystalFreqKHz = (NV_RD32(par->PEXTDEV, 0x0000) & (1 << 6)) ?
14318 : 13500;
@@ -656,7 +657,7 @@
par->LVDS = 0;
if (par->FlatPanel && par->twoHeads) {
NV_WR32(par->PRAMDAC0, 0x08B0, 0x00010004);
- if (par->PRAMDAC0[0x08b4] & 1)
+ if (NV_RD32(par->PRAMDAC0, 0x08b4) & 1)
par->LVDS = 1;
printk("nvidiafb: Panel is %s\n", par->LVDS ? "LVDS" : "TMDS");
}
diff --git a/drivers/video/nvidia/nv_type.h b/drivers/video/nvidia/nv_type.h
index 86e65de..38f7cc0 100644
--- a/drivers/video/nvidia/nv_type.h
+++ b/drivers/video/nvidia/nv_type.h
@@ -4,8 +4,9 @@
#include <linux/fb.h>
#include <linux/types.h>
#include <linux/i2c.h>
-#include <linux/i2c-id.h>
#include <linux/i2c-algo-bit.h>
+#include <linux/mutex.h>
+#include <video/vga.h>
#define NV_ARCH_04 0x04
#define NV_ARCH_10 0x10
@@ -94,13 +95,15 @@
struct nvidia_par {
RIVA_HW_STATE SavedReg;
RIVA_HW_STATE ModeReg;
+ RIVA_HW_STATE initial_state;
RIVA_HW_STATE *CurrentState;
+ struct vgastate vgastate;
+ struct mutex open_lock;
u32 pseudo_palette[16];
struct pci_dev *pci_dev;
u32 Architecture;
u32 CursorStart;
int Chipset;
- int bus;
unsigned long FbAddress;
u8 __iomem *FbStart;
u32 FbMapSize;
@@ -143,6 +146,7 @@
int BlendingPossible;
u32 paletteEnabled;
u32 forceCRTC;
+ u32 open_count;
u8 DDCBase;
#ifdef CONFIG_MTRR
struct {
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index b97ec69..7c36b5f 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -200,7 +200,7 @@
return tweak;
}
-static void nvidia_vga_protect(struct nvidia_par *par, int on)
+static void nvidia_screen_off(struct nvidia_par *par, int on)
{
unsigned char tmp;
@@ -649,7 +649,7 @@
NVLockUnlock(par, 0);
}
- nvidia_vga_protect(par, 1);
+ nvidia_screen_off(par, 1);
nvidia_write_regs(par, &par->ModeReg);
NVSetStartAddress(par, 0);
@@ -687,7 +687,7 @@
par->cursor_reset = 1;
- nvidia_vga_protect(par, 0);
+ nvidia_screen_off(par, 0);
#ifdef CONFIG_BOOTX_TEXT
/* Update debug text engine */
@@ -696,6 +696,7 @@
info->var.bits_per_pixel, info->fix.line_length);
#endif
+ NVLockUnlock(par, 0);
NVTRACE_LEAVE();
return 0;
}
@@ -948,8 +949,80 @@
return 0;
}
+/*
+ * Because the VGA registers are not mapped linearly in its MMIO space,
+ * restrict VGA register saving and restore to x86 only, where legacy VGA IO
+ * access is legal. Consequently, we must also check if the device is the
+ * primary display.
+ */
+#ifdef CONFIG_X86
+static void save_vga_x86(struct nvidia_par *par)
+{
+ struct resource *res= &par->pci_dev->resource[PCI_ROM_RESOURCE];
+
+ if (res && res->flags & IORESOURCE_ROM_SHADOW) {
+ memset(&par->vgastate, 0, sizeof(par->vgastate));
+ par->vgastate.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS |
+ VGA_SAVE_CMAP;
+ save_vga(&par->vgastate);
+ }
+}
+
+static void restore_vga_x86(struct nvidia_par *par)
+{
+ struct resource *res= &par->pci_dev->resource[PCI_ROM_RESOURCE];
+
+ if (res && res->flags & IORESOURCE_ROM_SHADOW)
+ restore_vga(&par->vgastate);
+}
+#else
+#define save_vga_x86(x) do {} while (0)
+#define restore_vga_x86(x) do {} while (0)
+#endif /* X86 */
+
+static int nvidiafb_open(struct fb_info *info, int user)
+{
+ struct nvidia_par *par = info->par;
+
+ mutex_lock(&par->open_lock);
+
+ if (!par->open_count) {
+ save_vga_x86(par);
+ nvidia_save_vga(par, &par->initial_state);
+ }
+
+ par->open_count++;
+ mutex_unlock(&par->open_lock);
+ return 0;
+}
+
+static int nvidiafb_release(struct fb_info *info, int user)
+{
+ struct nvidia_par *par = info->par;
+ int err = 0;
+
+ mutex_lock(&par->open_lock);
+
+ if (!par->open_count) {
+ err = -EINVAL;
+ goto done;
+ }
+
+ if (par->open_count == 1) {
+ nvidia_write_regs(par, &par->initial_state);
+ restore_vga_x86(par);
+ }
+
+ par->open_count--;
+done:
+ mutex_unlock(&par->open_lock);
+ return err;
+}
+
static struct fb_ops nvidia_fb_ops = {
.owner = THIS_MODULE,
+ .fb_open = nvidiafb_open,
+ .fb_release = nvidiafb_release,
.fb_check_var = nvidiafb_check_var,
.fb_set_par = nvidiafb_set_par,
.fb_setcolreg = nvidiafb_setcolreg,
@@ -1207,7 +1280,7 @@
par = info->par;
par->pci_dev = pd;
-
+ mutex_init(&par->open_lock);
info->pixmap.addr = kzalloc(8 * 1024, GFP_KERNEL);
if (info->pixmap.addr == NULL)
diff --git a/drivers/video/offb.c b/drivers/video/offb.c
index 9576a55..885b428 100644
--- a/drivers/video/offb.c
+++ b/drivers/video/offb.c
@@ -322,8 +322,8 @@
ioremap(base + 0x7ff000, 0x1000) + 0xcc0;
par->cmap_data = par->cmap_adr + 1;
par->cmap_type = cmap_m64;
- } else if (dp && (device_is_compatible(dp, "pci1014,b7") ||
- device_is_compatible(dp, "pci1014,21c"))) {
+ } else if (dp && (of_device_is_compatible(dp, "pci1014,b7") ||
+ of_device_is_compatible(dp, "pci1014,21c"))) {
par->cmap_adr = offb_map_reg(dp, 0, 0x6000, 0x1000);
if (par->cmap_adr)
par->cmap_type = cmap_gxt2000;
@@ -425,27 +425,27 @@
const u32 *pp, *addrp, *up;
u64 asize;
- pp = get_property(dp, "linux,bootx-depth", &len);
+ pp = of_get_property(dp, "linux,bootx-depth", &len);
if (pp == NULL)
- pp = get_property(dp, "depth", &len);
+ pp = of_get_property(dp, "depth", &len);
if (pp && len == sizeof(u32))
depth = *pp;
- pp = get_property(dp, "linux,bootx-width", &len);
+ pp = of_get_property(dp, "linux,bootx-width", &len);
if (pp == NULL)
- pp = get_property(dp, "width", &len);
+ pp = of_get_property(dp, "width", &len);
if (pp && len == sizeof(u32))
width = *pp;
- pp = get_property(dp, "linux,bootx-height", &len);
+ pp = of_get_property(dp, "linux,bootx-height", &len);
if (pp == NULL)
- pp = get_property(dp, "height", &len);
+ pp = of_get_property(dp, "height", &len);
if (pp && len == sizeof(u32))
height = *pp;
- pp = get_property(dp, "linux,bootx-linebytes", &len);
+ pp = of_get_property(dp, "linux,bootx-linebytes", &len);
if (pp == NULL)
- pp = get_property(dp, "linebytes", &len);
+ pp = of_get_property(dp, "linebytes", &len);
if (pp && len == sizeof(u32) && (*pp != 0xffffffffu))
pitch = *pp;
else
@@ -463,9 +463,9 @@
* ranges and pick one that is both big enough and if possible encloses
* the "address" property. If none match, we pick the biggest
*/
- up = get_property(dp, "linux,bootx-addr", &len);
+ up = of_get_property(dp, "linux,bootx-addr", &len);
if (up == NULL)
- up = get_property(dp, "address", &len);
+ up = of_get_property(dp, "address", &len);
if (up && len == sizeof(u32))
addr_prop = *up;
@@ -521,7 +521,7 @@
return -ENODEV;
/* Check if we have a MacOS display without a node spec */
- if (get_property(of_chosen, "linux,bootx-noscreen", NULL) != NULL) {
+ if (of_get_property(of_chosen, "linux,bootx-noscreen", NULL) != NULL) {
/* The old code tried to work out which node was the MacOS
* display based on the address. I'm dropping that since the
* lack of a node spec only happens with old BootX versions
@@ -532,14 +532,14 @@
}
for (dp = NULL; (dp = of_find_node_by_type(dp, "display"));) {
- if (get_property(dp, "linux,opened", NULL) &&
- get_property(dp, "linux,boot-display", NULL)) {
+ if (of_get_property(dp, "linux,opened", NULL) &&
+ of_get_property(dp, "linux,boot-display", NULL)) {
boot_disp = dp;
offb_init_nodriver(dp, 0);
}
}
for (dp = NULL; (dp = of_find_node_by_type(dp, "display"));) {
- if (get_property(dp, "linux,opened", NULL) &&
+ if (of_get_property(dp, "linux,opened", NULL) &&
dp != boot_disp)
offb_init_nodriver(dp, 0);
}
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
index a560a22..1ac5264 100644
--- a/drivers/video/pm2fb.c
+++ b/drivers/video/pm2fb.c
@@ -81,8 +81,6 @@
struct pm2fb_par
{
pm2type_t type; /* Board type */
- u32 fb_size; /* framebuffer memory size */
- unsigned char __iomem *v_fb; /* virtual address of frame buffer */
unsigned char __iomem *v_regs;/* virtual address of p_regs */
u32 memclock; /* memclock */
u32 video; /* video flags before blanking */
@@ -103,7 +101,7 @@
.xpanstep = 1,
.ypanstep = 1,
.ywrapstep = 0,
- .accel = FB_ACCEL_NONE,
+ .accel = FB_ACCEL_3DLABS_PERMEDIA2,
};
/*
@@ -206,6 +204,17 @@
}
#endif
+static void wait_pm2(struct pm2fb_par* par) {
+
+ WAIT_FIFO(par, 1);
+ pm2_WR(par, PM2R_SYNC, 0);
+ mb();
+ do {
+ while (pm2_RD(par, PM2R_OUT_FIFO_WORDS) == 0);
+ rmb();
+ } while (pm2_RD(par, PM2R_OUT_FIFO) != PM2TAG(PM2R_SYNC));
+}
+
/*
* partial products for the supported horizontal resolutions.
*/
@@ -302,10 +311,10 @@
s32 delta = 1000;
*mm = *nn = *pp = 0;
- for (n = 1; n; n++) {
- for ( m = 1; m; m++) {
+ for ( m = 1; m < 128; m++) {
+ for (n = 2 * m + 1; n; n++) {
for ( p = 0; p < 2; p++) {
- f = PM2_REFERENCE_CLOCK * n / (m * (1 << (p + 1)));
+ f = ( PM2_REFERENCE_CLOCK >> ( p + 1 )) * n / m;
if ( clk > f - delta && clk < f + delta ) {
delta = ( clk > f ) ? clk - f : f - clk;
*mm=m;
@@ -462,21 +471,43 @@
int i;
unsigned char m, n, p;
- pm2_mnp(clk, &m, &n, &p);
- WAIT_FIFO(par, 10);
- pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 6);
- wmb();
- pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_1, m);
- pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_2, n);
- wmb();
- pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 8|p);
- wmb();
- pm2_RDAC_RD(par, PM2I_RD_MEMORY_CLOCK_STATUS);
- rmb();
- for (i = 256;
- i && !(pm2_RD(par, PM2R_RD_INDEXED_DATA) & PM2F_PLL_LOCKED);
- i--)
- ;
+ switch (par->type) {
+ case PM2_TYPE_PERMEDIA2V:
+ pm2v_mnp(clk/2, &m, &n, &p);
+ WAIT_FIFO(par, 8);
+ pm2_WR(par, PM2VR_RD_INDEX_HIGH, PM2VI_RD_MCLK_CONTROL >> 8);
+ pm2v_RDAC_WR(par, PM2VI_RD_MCLK_CONTROL, 0);
+ wmb();
+ pm2v_RDAC_WR(par, PM2VI_RD_MCLK_PRESCALE, m);
+ pm2v_RDAC_WR(par, PM2VI_RD_MCLK_FEEDBACK, n);
+ pm2v_RDAC_WR(par, PM2VI_RD_MCLK_POSTSCALE, p);
+ wmb();
+ pm2v_RDAC_WR(par, PM2VI_RD_MCLK_CONTROL, 1);
+ rmb();
+ for (i = 256;
+ i && !(pm2_RDAC_RD(par, PM2VI_RD_MCLK_CONTROL) & 2);
+ i--)
+ ;
+ pm2_WR(par, PM2VR_RD_INDEX_HIGH, 0);
+ break;
+ case PM2_TYPE_PERMEDIA2:
+ pm2_mnp(clk, &m, &n, &p);
+ WAIT_FIFO(par, 10);
+ pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 6);
+ wmb();
+ pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_1, m);
+ pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_2, n);
+ wmb();
+ pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 8|p);
+ wmb();
+ pm2_RDAC_RD(par, PM2I_RD_MEMORY_CLOCK_STATUS);
+ rmb();
+ for (i = 256;
+ i && !(pm2_RD(par, PM2R_RD_INDEXED_DATA) & PM2F_PLL_LOCKED);
+ i--)
+ ;
+ break;
+ }
}
static void set_pixclock(struct pm2fb_par* par, u32 clk)
@@ -623,6 +654,8 @@
return -EINVAL;
}
+ var->transp.offset = 0;
+ var->transp.length = 0;
switch(var->bits_per_pixel) {
case 8:
var->red.length = var->green.length = var->blue.length = 8;
@@ -1017,6 +1050,117 @@
return 0;
}
+/*
+ * block operation. copy=0: rectangle fill, copy=1: rectangle copy.
+ */
+static void pm2fb_block_op(struct pm2fb_par* par, int copy,
+ s32 xsrc, s32 ysrc,
+ s32 x, s32 y, s32 w, s32 h,
+ u32 color) {
+
+ if (!w || !h)
+ return;
+ WAIT_FIFO(par, 6);
+ pm2_WR(par, PM2R_CONFIG, PM2F_CONFIG_FB_WRITE_ENABLE |
+ PM2F_CONFIG_FB_READ_SOURCE_ENABLE);
+ pm2_WR(par, PM2R_FB_PIXEL_OFFSET, 0);
+ if (copy)
+ pm2_WR(par, PM2R_FB_SOURCE_DELTA,
+ ((ysrc-y) & 0xfff) << 16 | ((xsrc-x) & 0xfff));
+ else
+ pm2_WR(par, PM2R_FB_BLOCK_COLOR, color);
+ pm2_WR(par, PM2R_RECTANGLE_ORIGIN, (y << 16) | x);
+ pm2_WR(par, PM2R_RECTANGLE_SIZE, (h << 16) | w);
+ wmb();
+ pm2_WR(par, PM2R_RENDER,PM2F_RENDER_RECTANGLE |
+ (x<xsrc ? PM2F_INCREASE_X : 0) |
+ (y<ysrc ? PM2F_INCREASE_Y : 0) |
+ (copy ? 0 : PM2F_RENDER_FASTFILL));
+ wait_pm2(par);
+}
+
+static void pm2fb_fillrect (struct fb_info *info,
+ const struct fb_fillrect *region)
+{
+ struct pm2fb_par *par = info->par;
+ struct fb_fillrect modded;
+ int vxres, vyres;
+ u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ?
+ ((u32*)info->pseudo_palette)[region->color] : region->color;
+
+ if (info->state != FBINFO_STATE_RUNNING)
+ return;
+ if ((info->flags & FBINFO_HWACCEL_DISABLED) ||
+ region->rop != ROP_COPY ) {
+ cfb_fillrect(info, region);
+ return;
+ }
+
+ vxres = info->var.xres_virtual;
+ vyres = info->var.yres_virtual;
+
+ memcpy(&modded, region, sizeof(struct fb_fillrect));
+
+ if(!modded.width || !modded.height ||
+ modded.dx >= vxres || modded.dy >= vyres)
+ return;
+
+ if(modded.dx + modded.width > vxres)
+ modded.width = vxres - modded.dx;
+ if(modded.dy + modded.height > vyres)
+ modded.height = vyres - modded.dy;
+
+ if(info->var.bits_per_pixel == 8)
+ color |= color << 8;
+ if(info->var.bits_per_pixel <= 16)
+ color |= color << 16;
+
+ if(info->var.bits_per_pixel != 24)
+ pm2fb_block_op(par, 0, 0, 0,
+ modded.dx, modded.dy,
+ modded.width, modded.height, color);
+ else
+ cfb_fillrect(info, region);
+}
+
+static void pm2fb_copyarea(struct fb_info *info,
+ const struct fb_copyarea *area)
+{
+ struct pm2fb_par *par = info->par;
+ struct fb_copyarea modded;
+ u32 vxres, vyres;
+
+ if (info->state != FBINFO_STATE_RUNNING)
+ return;
+ if (info->flags & FBINFO_HWACCEL_DISABLED) {
+ cfb_copyarea(info, area);
+ return;
+ }
+
+ memcpy(&modded, area, sizeof(struct fb_copyarea));
+
+ vxres = info->var.xres_virtual;
+ vyres = info->var.yres_virtual;
+
+ if(!modded.width || !modded.height ||
+ modded.sx >= vxres || modded.sy >= vyres ||
+ modded.dx >= vxres || modded.dy >= vyres)
+ return;
+
+ if(modded.sx + modded.width > vxres)
+ modded.width = vxres - modded.sx;
+ if(modded.dx + modded.width > vxres)
+ modded.width = vxres - modded.dx;
+ if(modded.sy + modded.height > vyres)
+ modded.height = vyres - modded.sy;
+ if(modded.dy + modded.height > vyres)
+ modded.height = vyres - modded.dy;
+
+ pm2fb_block_op(par, 1, modded.sx, modded.sy,
+ modded.dx, modded.dy,
+ modded.width, modded.height, 0);
+}
+
/* ------------ Hardware Independent Functions ------------ */
/*
@@ -1030,8 +1174,8 @@
.fb_setcolreg = pm2fb_setcolreg,
.fb_blank = pm2fb_blank,
.fb_pan_display = pm2fb_pan_display,
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = cfb_copyarea,
+ .fb_fillrect = pm2fb_fillrect,
+ .fb_copyarea = pm2fb_copyarea,
.fb_imageblit = cfb_imageblit,
};
@@ -1119,38 +1263,47 @@
if(default_par->mem_control == 0 &&
default_par->boot_address == 0x31 &&
- default_par->mem_config == 0x259fffff &&
- pdev->subsystem_vendor == 0x1048 &&
- pdev->subsystem_device == 0x0a31) {
- DPRINTK("subsystem_vendor: %04x, subsystem_device: %04x\n",
- pdev->subsystem_vendor, pdev->subsystem_device);
- DPRINTK("We have not been initialized by VGA BIOS "
- "and are running on an Elsa Winner 2000 Office\n");
- DPRINTK("Initializing card timings manually...\n");
+ default_par->mem_config == 0x259fffff) {
+ default_par->memclock = CVPPC_MEMCLOCK;
default_par->mem_control=0;
default_par->boot_address=0x20;
default_par->mem_config=0xe6002021;
- default_par->memclock=100000;
+ if (pdev->subsystem_vendor == 0x1048 &&
+ pdev->subsystem_device == 0x0a31) {
+ DPRINTK("subsystem_vendor: %04x, subsystem_device: %04x\n",
+ pdev->subsystem_vendor, pdev->subsystem_device);
+ DPRINTK("We have not been initialized by VGA BIOS "
+ "and are running on an Elsa Winner 2000 Office\n");
+ DPRINTK("Initializing card timings manually...\n");
+ default_par->memclock=70000;
+ }
+ if (pdev->subsystem_vendor == 0x3d3d &&
+ pdev->subsystem_device == 0x0100) {
+ DPRINTK("subsystem_vendor: %04x, subsystem_device: %04x\n",
+ pdev->subsystem_vendor, pdev->subsystem_device);
+ DPRINTK("We have not been initialized by VGA BIOS "
+ "and are running on an 3dlabs reference board\n");
+ DPRINTK("Initializing card timings manually...\n");
+ default_par->memclock=74894;
+ }
}
/* Now work out how big lfb is going to be. */
switch(default_par->mem_config & PM2F_MEM_CONFIG_RAM_MASK) {
case PM2F_MEM_BANKS_1:
- default_par->fb_size=0x200000;
+ pm2fb_fix.smem_len=0x200000;
break;
case PM2F_MEM_BANKS_2:
- default_par->fb_size=0x400000;
+ pm2fb_fix.smem_len=0x400000;
break;
case PM2F_MEM_BANKS_3:
- default_par->fb_size=0x600000;
+ pm2fb_fix.smem_len=0x600000;
break;
case PM2F_MEM_BANKS_4:
- default_par->fb_size=0x800000;
+ pm2fb_fix.smem_len=0x800000;
break;
}
- default_par->memclock = CVPPC_MEMCLOCK;
pm2fb_fix.smem_start = pci_resource_start(pdev, 1);
- pm2fb_fix.smem_len = default_par->fb_size;
/* Linear frame buffer - request region and map it. */
if ( !request_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len,
@@ -1158,9 +1311,9 @@
printk(KERN_WARNING "pm2fb: Can't reserve smem.\n");
goto err_exit_mmio;
}
- info->screen_base = default_par->v_fb =
+ info->screen_base =
ioremap_nocache(pm2fb_fix.smem_start, pm2fb_fix.smem_len);
- if ( !default_par->v_fb ) {
+ if ( !info->screen_base ) {
printk(KERN_WARNING "pm2fb: Can't ioremap smem area.\n");
release_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len);
goto err_exit_mmio;
@@ -1170,7 +1323,9 @@
info->fix = pm2fb_fix;
info->pseudo_palette = default_par->palette;
info->flags = FBINFO_DEFAULT |
- FBINFO_HWACCEL_YPAN;
+ FBINFO_HWACCEL_YPAN |
+ FBINFO_HWACCEL_COPYAREA |
+ FBINFO_HWACCEL_FILLRECT;
if (!mode)
mode = "640x480@60";
@@ -1180,13 +1335,13 @@
info->var = pm2fb_var;
if (fb_alloc_cmap(&info->cmap, 256, 0) < 0)
- goto err_exit_all;
-
- if (register_framebuffer(info) < 0)
goto err_exit_both;
+ if (register_framebuffer(info) < 0)
+ goto err_exit_all;
+
printk(KERN_INFO "fb%d: %s frame buffer device, memory = %dK.\n",
- info->node, info->fix.id, default_par->fb_size / 1024);
+ info->node, info->fix.id, pm2fb_fix.smem_len / 1024);
/*
* Our driver data
@@ -1242,6 +1397,9 @@
{ PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2V,
PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
0xff0000, 0 },
+ { PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2V,
+ PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NOT_DEFINED_VGA << 8,
+ 0xff00, 0 },
{ 0, }
};
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c
index 07d1979..9756a72 100644
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -898,8 +898,8 @@
}
ps3fb.dev = dev;
- error = ps3_alloc_irq(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet,
- &ps3fb.irq_no);
+ error = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet,
+ &ps3fb.irq_no);
if (error) {
printk(KERN_ERR "%s: ps3_alloc_irq failed %d\n", __func__,
error);
@@ -911,7 +911,7 @@
if (error) {
printk(KERN_ERR "%s: request_irq failed %d\n", __func__,
error);
- ps3_free_irq(ps3fb.irq_no);
+ ps3_irq_plug_destroy(ps3fb.irq_no);
return error;
}
@@ -1083,7 +1083,7 @@
framebuffer_release(info);
err_free_irq:
free_irq(ps3fb.irq_no, ps3fb.dev);
- ps3_free_irq(ps3fb.irq_no);
+ ps3_irq_plug_destroy(ps3fb.irq_no);
err_iounmap_dinfo:
iounmap((u8 __iomem *)ps3fb.dinfo);
err_gpu_context_free:
@@ -1099,7 +1099,7 @@
ps3fb_flip_ctl(0); /* flip off */
ps3fb.dinfo->irq.mask = 0;
free_irq(ps3fb.irq_no, ps3fb.dev);
- ps3_free_irq(ps3fb.irq_no);
+ ps3_irq_plug_destroy(ps3fb.irq_no);
iounmap((u8 __iomem *)ps3fb.dinfo);
}
@@ -1114,7 +1114,7 @@
}
if (ps3fb.irq_no) {
free_irq(ps3fb.irq_no, ps3fb.dev);
- ps3_free_irq(ps3fb.irq_no);
+ ps3_irq_plug_destroy(ps3fb.irq_no);
}
iounmap((u8 __iomem *)ps3fb.dinfo);
diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c
index a93618b..df2909a 100644
--- a/drivers/video/pvr2fb.c
+++ b/drivers/video/pvr2fb.c
@@ -214,7 +214,7 @@
static int pvr2_get_param(const struct pvr2_params *p, const char *s,
int val, int size);
#ifdef CONFIG_SH_DMA
-static ssize_t pvr2fb_write(struct file *file, const char *buf,
+static ssize_t pvr2fb_write(struct fb_info *info, const char *buf,
size_t count, loff_t *ppos);
#endif
@@ -674,7 +674,7 @@
}
#ifdef CONFIG_SH_DMA
-static ssize_t pvr2fb_write(struct file *file, const char *buf,
+static ssize_t pvr2fb_write(struct fb_info *info, const char *buf,
size_t count, loff_t *ppos)
{
unsigned long dst, start, end, len;
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 0b195f3..81e571d 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -1203,7 +1203,7 @@
} else
goto done;
break;
- case '0'...'9':
+ case '0' ... '9':
break;
default:
goto done;
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index d7ece8d..0fe5478 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -317,15 +317,15 @@
else
level = bd->props.brightness;
- tmp_pmc = par->riva.PMC[0x10F0/4] & 0x0000FFFF;
- tmp_pcrt = par->riva.PCRTC0[0x081C/4] & 0xFFFFFFFC;
+ tmp_pmc = NV_RD32(par->riva.PMC, 0x10F0) & 0x0000FFFF;
+ tmp_pcrt = NV_RD32(par->riva.PCRTC0, 0x081C) & 0xFFFFFFFC;
if(level > 0) {
tmp_pcrt |= 0x1;
tmp_pmc |= (1 << 31); /* backlight bit */
tmp_pmc |= riva_bl_get_level_brightness(par, level) << 16; /* level */
}
- par->riva.PCRTC0[0x081C/4] = tmp_pcrt;
- par->riva.PMC[0x10F0/4] = tmp_pmc;
+ NV_WR32(par->riva.PCRTC0, 0x081C, tmp_pcrt);
+ NV_WR32(par->riva.PMC, 0x10F0, tmp_pmc);
return 0;
}
@@ -1760,13 +1760,13 @@
NVTRACE_ENTER();
dp = pci_device_to_OF_node(pd);
for (; dp != NULL; dp = dp->child) {
- disptype = get_property(dp, "display-type", NULL);
+ disptype = of_get_property(dp, "display-type", NULL);
if (disptype == NULL)
continue;
if (strncmp(disptype, "LCD", 3) != 0)
continue;
for (i = 0; propnames[i] != NULL; ++i) {
- pedid = get_property(dp, propnames[i], NULL);
+ pedid = of_get_property(dp, propnames[i], NULL);
if (pedid != NULL) {
par->EDID = (unsigned char *)pedid;
NVTRACE("LCD found.\n");
@@ -1788,8 +1788,10 @@
NVTRACE_ENTER();
riva_create_i2c_busses(par);
- for (i = 0; i < par->bus; i++) {
- riva_probe_i2c_connector(par, i+1, &par->EDID);
+ for (i = 0; i < 3; i++) {
+ if (!par->chan[i].par)
+ continue;
+ riva_probe_i2c_connector(par, i, &par->EDID);
if (par->EDID && !fb_parse_edid(par->EDID, &var)) {
printk(PFX "Found EDID Block from BUS %i\n", i);
break;
@@ -2104,7 +2106,7 @@
return ret;
}
-static void __exit rivafb_remove(struct pci_dev *pd)
+static void __devexit rivafb_remove(struct pci_dev *pd)
{
struct fb_info *info = pci_get_drvdata(pd);
struct riva_par *par = info->par;
@@ -2185,7 +2187,7 @@
.name = "rivafb",
.id_table = rivafb_pci_tbl,
.probe = rivafb_probe,
- .remove = __exit_p(rivafb_remove),
+ .remove = __devexit_p(rivafb_remove),
};
diff --git a/drivers/video/riva/nv4ref.h b/drivers/video/riva/nv4ref.h
deleted file mode 100644
index 3b5f911..0000000
--- a/drivers/video/riva/nv4ref.h
+++ /dev/null
@@ -1,2445 +0,0 @@
- /***************************************************************************\
-|* *|
-|* Copyright 1993-1998 NVIDIA, Corporation. All rights reserved. *|
-|* *|
-|* NOTICE TO USER: The source code is copyrighted under U.S. and *|
-|* international laws. Users and possessors of this source code are *|
-|* hereby granted a nonexclusive, royalty-free copyright license to *|
-|* use this code in individual and commercial software. *|
-|* *|
-|* Any use of this source code must include, in the user documenta- *|
-|* tion and internal comments to the code, notices to the end user *|
-|* as follows: *|
-|* *|
-|* Copyright 1993-1998 NVIDIA, Corporation. All rights reserved. *|
-|* *|
-|* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
-|* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
-|* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
-|* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
-|* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
-|* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
-|* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
-|* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
-|* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *|
-|* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *|
-|* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *|
-|* *|
-|* U.S. Government End Users. This source code is a "commercial *|
-|* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
-|* consisting of "commercial computer software" and "commercial *|
-|* computer software documentation," as such terms are used in *|
-|* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
-|* ment only as a commercial end item. Consistent with 48 C.F.R. *|
-|* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
-|* all U.S. Government End Users acquire the source code with only *|
-|* those rights set forth herein. *|
-|* *|
- \***************************************************************************/
-
-/*
- * GPL licensing note -- nVidia is allowing a liberal interpretation of
- * the documentation restriction above, to merely say that this nVidia's
- * copyright and disclaimer should be included with all code derived
- * from this source. -- Jeff Garzik <jgarzik@pobox.com>, 01/Nov/99
- */
-
- /***************************************************************************\
-|* Modified 1999 by Fredrik Reite (fredrik@reite.com) *|
- \***************************************************************************/
-
-
-#ifndef __NV4REF_H__
-#define __NV4REF_H__
-
-/* Magic values to lock/unlock extended regs */
-#define NV_CIO_SR_LOCK_INDEX 0x0000001F /* */
-#define NV_CIO_SR_UNLOCK_RW_VALUE 0x00000057 /* */
-#define NV_CIO_SR_UNLOCK_RO_VALUE 0x00000075 /* */
-#define NV_CIO_SR_LOCK_VALUE 0x00000099 /* */
-
-#define UNLOCK_EXT_MAGIC 0x57
-#define LOCK_EXT_MAGIC 0x99 /* Any value other than 0x57 will do */
-
-#define LOCK_EXT_INDEX 0x6
-
-#define NV_PCRTC_HORIZ_TOTAL 0x00
-#define NV_PCRTC_HORIZ_DISPLAY_END 0x01
-#define NV_PCRTC_HORIZ_BLANK_START 0x02
-
-#define NV_PCRTC_HORIZ_BLANK_END 0x03
-#define NV_PCRTC_HORIZ_BLANK_END_EVRA 7:7
-#define NV_PCRTC_HORIZ_BLANK_END_DISPLAY_END_SKEW 6:5
-#define NV_PCRTC_HORIZ_BLANK_END_HORIZ_BLANK_END 4:0
-
-#define NV_PCRTC_HORIZ_RETRACE_START 0x04
-
-#define NV_PCRTC_HORIZ_RETRACE_END 0x05
-#define NV_PCRTC_HORIZ_RETRACE_END_HORIZ_BLANK_END_5 7:7
-#define NV_PCRTC_HORIZ_RETRACE_END_HORIZ_RETRACE_SKEW 6:5
-#define NV_PCRTC_HORIZ_RETRACE_END_HORIZ_RETRACE_END 4:0
-
-#define NV_PCRTC_VERT_TOTAL 0x06
-
-#define NV_PCRTC_OVERFLOW 0x07
-#define NV_PCRTC_OVERFLOW_VERT_RETRACE_START_9 7:7
-#define NV_PCRTC_OVERFLOW_VERT_DISPLAY_END_9 6:6
-#define NV_PCRTC_OVERFLOW_VERT_TOTAL_9 5:5
-#define NV_PCRTC_OVERFLOW_LINE_COMPARE_8 4:4
-#define NV_PCRTC_OVERFLOW_VERT_BLANK_START_8 3:3
-#define NV_PCRTC_OVERFLOW_VERT_RETRACE_START_8 2:2
-#define NV_PCRTC_OVERFLOW_VERT_DISPLAY_END_8 1:1
-#define NV_PCRTC_OVERFLOW_VERT_TOTAL_8 0:0
-
-#define NV_PCRTC_PRESET_ROW_SCAN 0x08
-
-#define NV_PCRTC_MAX_SCAN_LINE 0x09
-#define NV_PCRTC_MAX_SCAN_LINE_DOUBLE_SCAN 7:7
-#define NV_PCRTC_MAX_SCAN_LINE_LINE_COMPARE_9 6:6
-#define NV_PCRTC_MAX_SCAN_LINE_VERT_BLANK_START_9 5:5
-#define NV_PCRTC_MAX_SCAN_LINE_MAX_SCAN_LINE 4:0
-
-#define NV_PCRTC_CURSOR_START 0x0A
-#define NV_PCRTC_CURSOR_END 0x0B
-#define NV_PCRTC_START_ADDR_HIGH 0x0C
-#define NV_PCRTC_START_ADDR_LOW 0x0D
-#define NV_PCRTC_CURSOR_LOCATION_HIGH 0x0E
-#define NV_PCRTC_CURSOR_LOCATION_LOW 0x0F
-
-#define NV_PCRTC_VERT_RETRACE_START 0x10
-#define NV_PCRTC_VERT_RETRACE_END 0x11
-#define NV_PCRTC_VERT_DISPLAY_END 0x12
-#define NV_PCRTC_OFFSET 0x13
-#define NV_PCRTC_UNDERLINE_LOCATION 0x14
-#define NV_PCRTC_VERT_BLANK_START 0x15
-#define NV_PCRTC_VERT_BLANK_END 0x16
-#define NV_PCRTC_MODE_CONTROL 0x17
-#define NV_PCRTC_LINE_COMPARE 0x18
-
-/* Extended offset and start address */
-#define NV_PCRTC_REPAINT0 0x19
-#define NV_PCRTC_REPAINT0_OFFSET_10_8 7:5
-#define NV_PCRTC_REPAINT0_START_ADDR_20_16 4:0
-
-/* Horizonal extended bits */
-#define NV_PCRTC_HORIZ_EXTRA 0x2d
-#define NV_PCRTC_HORIZ_EXTRA_INTER_HALF_START_8 4:4
-#define NV_PCRTC_HORIZ_EXTRA_HORIZ_RETRACE_START_8 3:3
-#define NV_PCRTC_HORIZ_EXTRA_HORIZ_BLANK_START_8 2:2
-#define NV_PCRTC_HORIZ_EXTRA_DISPLAY_END_8 1:1
-#define NV_PCRTC_HORIZ_EXTRA_DISPLAY_TOTAL_8 0:0
-
-/* Assorted extra bits */
-#define NV_PCRTC_EXTRA 0x25
-#define NV_PCRTC_EXTRA_OFFSET_11 5:5
-#define NV_PCRTC_EXTRA_HORIZ_BLANK_END_6 4:4
-#define NV_PCRTC_EXTRA_VERT_BLANK_START_10 3:3
-#define NV_PCRTC_EXTRA_VERT_RETRACE_START_10 2:2
-#define NV_PCRTC_EXTRA_VERT_DISPLAY_END_10 1:1
-#define NV_PCRTC_EXTRA_VERT_TOTAL_10 0:0
-
-/* Controls how much data the refresh fifo requests */
-#define NV_PCRTC_FIFO_CONTROL 0x1b
-#define NV_PCRTC_FIFO_CONTROL_UNDERFLOW_WARN 7:7
-#define NV_PCRTC_FIFO_CONTROL_BURST_LENGTH 2:0
-#define NV_PCRTC_FIFO_CONTROL_BURST_LENGTH_8 0x0
-#define NV_PCRTC_FIFO_CONTROL_BURST_LENGTH_32 0x1
-#define NV_PCRTC_FIFO_CONTROL_BURST_LENGTH_64 0x2
-#define NV_PCRTC_FIFO_CONTROL_BURST_LENGTH_128 0x3
-#define NV_PCRTC_FIFO_CONTROL_BURST_LENGTH_256 0x4
-
-/* When the fifo occupancy falls below *twice* the watermark,
- * the refresh fifo will start to be refilled. If this value is
- * too low, you will get junk on the screen. Too high, and performance
- * will suffer. Watermark in units of 8 bytes
- */
-#define NV_PCRTC_FIFO 0x20
-#define NV_PCRTC_FIFO_RESET 7:7
-#define NV_PCRTC_FIFO_WATERMARK 5:0
-
-/* Various flags */
-#define NV_PCRTC_REPAINT1 0x1a
-#define NV_PCRTC_REPAINT1_HSYNC 7:7
-#define NV_PCRTC_REPAINT1_HYSNC_DISABLE 0x01
-#define NV_PCRTC_REPAINT1_HYSNC_ENABLE 0x00
-#define NV_PCRTC_REPAINT1_VSYNC 6:6
-#define NV_PCRTC_REPAINT1_VYSNC_DISABLE 0x01
-#define NV_PCRTC_REPAINT1_VYSNC_ENABLE 0x00
-#define NV_PCRTC_REPAINT1_COMPATIBLE_TEXT 4:4
-#define NV_PCRTC_REPAINT1_COMPATIBLE_TEXT_ENABLE 0x01
-#define NV_PCRTC_REPAINT1_COMPATIBLE_TEXT_DISABLE 0x00
-#define NV_PCRTC_REPAINT1_LARGE_SCREEN 2:2
-#define NV_PCRTC_REPAINT1_LARGE_SCREEN_DISABLE 0x01
-#define NV_PCRTC_REPAINT1_LARGE_SCREEN_ENABLE 0x00 /* >=1280 */
-#define NV_PCRTC_REPAINT1_PALETTE_WIDTH 1:1
-#define NV_PCRTC_REPAINT1_PALETTE_WIDTH_8BITS 0x00
-#define NV_PCRTC_REPAINT1_PALETTE_WIDTH_6BITS 0x01
-
-#define NV_PCRTC_GRCURSOR0 0x30
-#define NV_PCRTC_GRCURSOR0_START_ADDR_21_16 5:0
-
-#define NV_PCRTC_GRCURSOR1 0x31
-#define NV_PCRTC_GRCURSOR1_START_ADDR_15_11 7:3
-#define NV_PCRTC_GRCURSOR1_SCAN_DBL 1:1
-#define NV_PCRTC_GRCURSOR1_SCAN_DBL_DISABLE 0
-#define NV_PCRTC_GRCURSOR1_SCAN_DBL_ENABLE 1
-#define NV_PCRTC_GRCURSOR1_CURSOR 0:0
-#define NV_PCRTC_GRCURSOR1_CURSOR_DISABLE 0
-#define NV_PCRTC_GRCURSOR1_CURSOR_ENABLE 1
-
-/* Controls what the format of the framebuffer is */
-#define NV_PCRTC_PIXEL 0x28
-#define NV_PCRTC_PIXEL_MODE 7:7
-#define NV_PCRTC_PIXEL_MODE_TV 0x01
-#define NV_PCRTC_PIXEL_MODE_VGA 0x00
-#define NV_PCRTC_PIXEL_TV_MODE 6:6
-#define NV_PCRTC_PIXEL_TV_MODE_NTSC 0x00
-#define NV_PCRTC_PIXEL_TV_MODE_PAL 0x01
-#define NV_PCRTC_PIXEL_TV_HORIZ_ADJUST 5:3
-#define NV_PCRTC_PIXEL_FORMAT 1:0
-#define NV_PCRTC_PIXEL_FORMAT_VGA 0x00
-#define NV_PCRTC_PIXEL_FORMAT_8BPP 0x01
-#define NV_PCRTC_PIXEL_FORMAT_16BPP 0x02
-#define NV_PCRTC_PIXEL_FORMAT_32BPP 0x03
-
-/* RAMDAC registers and fields */
-#define NV_PRAMDAC 0x00680FFF:0x00680000 /* RW--D */
-#define NV_PRAMDAC_GRCURSOR_START_POS 0x00680300 /* RW-4R */
-#define NV_PRAMDAC_GRCURSOR_START_POS_X 11:0 /* RWXSF */
-#define NV_PRAMDAC_GRCURSOR_START_POS_Y 27:16 /* RWXSF */
-#define NV_PRAMDAC_NVPLL_COEFF 0x00680500 /* RW-4R */
-#define NV_PRAMDAC_NVPLL_COEFF_MDIV 7:0 /* RWIUF */
-#define NV_PRAMDAC_NVPLL_COEFF_NDIV 15:8 /* RWIUF */
-#define NV_PRAMDAC_NVPLL_COEFF_PDIV 18:16 /* RWIVF */
-#define NV_PRAMDAC_MPLL_COEFF 0x00680504 /* RW-4R */
-#define NV_PRAMDAC_MPLL_COEFF_MDIV 7:0 /* RWIUF */
-#define NV_PRAMDAC_MPLL_COEFF_NDIV 15:8 /* RWIUF */
-#define NV_PRAMDAC_MPLL_COEFF_PDIV 18:16 /* RWIVF */
-#define NV_PRAMDAC_VPLL_COEFF 0x00680508 /* RW-4R */
-#define NV_PRAMDAC_VPLL_COEFF_MDIV 7:0 /* RWIUF */
-#define NV_PRAMDAC_VPLL_COEFF_NDIV 15:8 /* RWIUF */
-#define NV_PRAMDAC_VPLL_COEFF_PDIV 18:16 /* RWIVF */
-#define NV_PRAMDAC_PLL_COEFF_SELECT 0x0068050C /* RW-4R */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_DLL_BYPASS 4:4 /* RWIVF */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_DLL_BYPASS_FALSE 0x00000000 /* RWI-V */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_DLL_BYPASS_TRUE 0x00000001 /* RW--V */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_MPLL_SOURCE 8:8 /* RWIVF */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_MPLL_SOURCE_DEFAULT 0x00000000 /* RWI-V */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_MPLL_SOURCE_PROG 0x00000001 /* RW--V */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_MPLL_BYPASS 12:12 /* RWIVF */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_MPLL_BYPASS_FALSE 0x00000000 /* RWI-V */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_MPLL_BYPASS_TRUE 0x00000001 /* RW--V */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_VPLL_SOURCE 16:16 /* RWIVF */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_VPLL_SOURCE_DEFAULT 0x00000000 /* RWI-V */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_VPLL_SOURCE_PROG 0x00000001 /* RW--V */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_VPLL_BYPASS 20:20 /* RWIVF */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_VPLL_BYPASS_FALSE 0x00000000 /* RWI-V */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_VPLL_BYPASS_TRUE 0x00000001 /* RW--V */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_PCLK_SOURCE 25:24 /* RWIVF */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_PCLK_SOURCE_VPLL 0x00000000 /* RWI-V */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_PCLK_SOURCE_VIP 0x00000001 /* RW--V */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_PCLK_SOURCE_XTALOSC 0x00000002 /* RW--V */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_VCLK_RATIO 28:28 /* RWIVF */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_VCLK_RATIO_DB1 0x00000000 /* RWI-V */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_VCLK_RATIO_DB2 0x00000001 /* RW--V */
-#define NV_PRAMDAC_GENERAL_CONTROL 0x00680600 /* RW-4R */
-#define NV_PRAMDAC_GENERAL_CONTROL_FF_COEFF 1:0 /* RWIVF */
-#define NV_PRAMDAC_GENERAL_CONTROL_FF_COEFF_DEF 0x00000000 /* RWI-V */
-#define NV_PRAMDAC_GENERAL_CONTROL_IDC_MODE 4:4 /* RWIVF */
-#define NV_PRAMDAC_GENERAL_CONTROL_IDC_MODE_GAMMA 0x00000000 /* RWI-V */
-#define NV_PRAMDAC_GENERAL_CONTROL_IDC_MODE_INDEX 0x00000001 /* RW--V */
-#define NV_PRAMDAC_GENERAL_CONTROL_VGA_STATE 8:8 /* RWIVF */
-#define NV_PRAMDAC_GENERAL_CONTROL_VGA_STATE_NOTSE 0x00000000 /* RWI-V */
-#define NV_PRAMDAC_GENERAL_CONTROL_VGA_STATE_SEL 0x00000001 /* RW--V */
-#define NV_PRAMDAC_GENERAL_CONTROL_565_MODE 12:12 /* RWIVF */
-#define NV_PRAMDAC_GENERAL_CONTROL_565_MODE_NOTSEL 0x00000000 /* RWI-V */
-#define NV_PRAMDAC_GENERAL_CONTROL_565_MODE_SEL 0x00000001 /* RW--V */
-#define NV_PRAMDAC_GENERAL_CONTROL_BLK_PEDSTL 16:16 /* RWIVF */
-#define NV_PRAMDAC_GENERAL_CONTROL_BLK_PEDSTL_OFF 0x00000000 /* RWI-V */
-#define NV_PRAMDAC_GENERAL_CONTROL_BLK_PEDSTL_ON 0x00000001 /* RW--V */
-#define NV_PRAMDAC_GENERAL_CONTROL_TERMINATION 17:17 /* RWIVF */
-#define NV_PRAMDAC_GENERAL_CONTROL_TERMINATION_37OHM 0x00000000 /* RWI-V */
-#define NV_PRAMDAC_GENERAL_CONTROL_TERMINATION_75OHM 0x00000001 /* RW--V */
-#define NV_PRAMDAC_GENERAL_CONTROL_BPC 20:20 /* RWIVF */
-#define NV_PRAMDAC_GENERAL_CONTROL_BPC_6BITS 0x00000000 /* RWI-V */
-#define NV_PRAMDAC_GENERAL_CONTROL_BPC_8BITS 0x00000001 /* RW--V */
-#define NV_PRAMDAC_GENERAL_CONTROL_DAC_SLEEP 24:24 /* RWIVF */
-#define NV_PRAMDAC_GENERAL_CONTROL_DAC_SLEEP_DIS 0x00000000 /* RWI-V */
-#define NV_PRAMDAC_GENERAL_CONTROL_DAC_SLEEP_EN 0x00000001 /* RW--V */
-#define NV_PRAMDAC_GENERAL_CONTROL_PALETTE_CLK 28:28 /* RWIVF */
-#define NV_PRAMDAC_GENERAL_CONTROL_PALETTE_CLK_EN 0x00000000 /* RWI-V */
-#define NV_PRAMDAC_GENERAL_CONTROL_PALETTE_CLK_DIS 0x00000001 /* RW--V */
-
-/* Master Control */
-#define NV_PMC 0x00000FFF:0x00000000 /* RW--D */
-#define NV_PMC_BOOT_0 0x00000000 /* R--4R */
-#define NV_PMC_BOOT_0_MINOR_REVISION 3:0 /* C--VF */
-#define NV_PMC_BOOT_0_MINOR_REVISION_0 0x00000000 /* C---V */
-#define NV_PMC_BOOT_0_MAJOR_REVISION 7:4 /* C--VF */
-#define NV_PMC_BOOT_0_MAJOR_REVISION_A 0x00000000 /* C---V */
-#define NV_PMC_BOOT_0_MAJOR_REVISION_B 0x00000001 /* ----V */
-#define NV_PMC_BOOT_0_IMPLEMENTATION 11:8 /* C--VF */
-#define NV_PMC_BOOT_0_IMPLEMENTATION_NV4_0 0x00000000 /* C---V */
-#define NV_PMC_BOOT_0_ARCHITECTURE 15:12 /* C--VF */
-#define NV_PMC_BOOT_0_ARCHITECTURE_NV0 0x00000000 /* ----V */
-#define NV_PMC_BOOT_0_ARCHITECTURE_NV1 0x00000001 /* ----V */
-#define NV_PMC_BOOT_0_ARCHITECTURE_NV2 0x00000002 /* ----V */
-#define NV_PMC_BOOT_0_ARCHITECTURE_NV3 0x00000003 /* ----V */
-#define NV_PMC_BOOT_0_ARCHITECTURE_NV4 0x00000004 /* C---V */
-#define NV_PMC_BOOT_0_FIB_REVISION 19:16 /* C--VF */
-#define NV_PMC_BOOT_0_FIB_REVISION_0 0x00000000 /* C---V */
-#define NV_PMC_BOOT_0_MASK_REVISION 23:20 /* C--VF */
-#define NV_PMC_BOOT_0_MASK_REVISION_A 0x00000000 /* C---V */
-#define NV_PMC_BOOT_0_MASK_REVISION_B 0x00000001 /* ----V */
-#define NV_PMC_BOOT_0_MANUFACTURER 27:24 /* C--UF */
-#define NV_PMC_BOOT_0_MANUFACTURER_NVIDIA 0x00000000 /* C---V */
-#define NV_PMC_BOOT_0_FOUNDRY 31:28 /* C--VF */
-#define NV_PMC_BOOT_0_FOUNDRY_SGS 0x00000000 /* ----V */
-#define NV_PMC_BOOT_0_FOUNDRY_HELIOS 0x00000001 /* ----V */
-#define NV_PMC_BOOT_0_FOUNDRY_TSMC 0x00000002 /* C---V */
-#define NV_PMC_INTR_0 0x00000100 /* RW-4R */
-#define NV_PMC_INTR_0_PMEDIA 4:4 /* R--VF */
-#define NV_PMC_INTR_0_PMEDIA_NOT_PENDING 0x00000000 /* R---V */
-#define NV_PMC_INTR_0_PMEDIA_PENDING 0x00000001 /* R---V */
-#define NV_PMC_INTR_0_PFIFO 8:8 /* R--VF */
-#define NV_PMC_INTR_0_PFIFO_NOT_PENDING 0x00000000 /* R---V */
-#define NV_PMC_INTR_0_PFIFO_PENDING 0x00000001 /* R---V */
-#define NV_PMC_INTR_0_PGRAPH 12:12 /* R--VF */
-#define NV_PMC_INTR_0_PGRAPH_NOT_PENDING 0x00000000 /* R---V */
-#define NV_PMC_INTR_0_PGRAPH_PENDING 0x00000001 /* R---V */
-#define NV_PMC_INTR_0_PVIDEO 16:16 /* R--VF */
-#define NV_PMC_INTR_0_PVIDEO_NOT_PENDING 0x00000000 /* R---V */
-#define NV_PMC_INTR_0_PVIDEO_PENDING 0x00000001 /* R---V */
-#define NV_PMC_INTR_0_PTIMER 20:20 /* R--VF */
-#define NV_PMC_INTR_0_PTIMER_NOT_PENDING 0x00000000 /* R---V */
-#define NV_PMC_INTR_0_PTIMER_PENDING 0x00000001 /* R---V */
-#define NV_PMC_INTR_0_PCRTC 24:24 /* R--VF */
-#define NV_PMC_INTR_0_PCRTC_NOT_PENDING 0x00000000 /* R---V */
-#define NV_PMC_INTR_0_PCRTC_PENDING 0x00000001 /* R---V */
-#define NV_PMC_INTR_0_PBUS 28:28 /* R--VF */
-#define NV_PMC_INTR_0_PBUS_NOT_PENDING 0x00000000 /* R---V */
-#define NV_PMC_INTR_0_PBUS_PENDING 0x00000001 /* R---V */
-#define NV_PMC_INTR_0_SOFTWARE 31:31 /* RWIVF */
-#define NV_PMC_INTR_0_SOFTWARE_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PMC_INTR_0_SOFTWARE_PENDING 0x00000001 /* RW--V */
-#define NV_PMC_INTR_EN_0 0x00000140 /* RW-4R */
-#define NV_PMC_INTR_EN_0_INTA 1:0 /* RWIVF */
-#define NV_PMC_INTR_EN_0_INTA_DISABLED 0x00000000 /* RWI-V */
-#define NV_PMC_INTR_EN_0_INTA_HARDWARE 0x00000001 /* RW--V */
-#define NV_PMC_INTR_EN_0_INTA_SOFTWARE 0x00000002 /* RW--V */
-#define NV_PMC_INTR_READ_0 0x00000160 /* R--4R */
-#define NV_PMC_INTR_READ_0_INTA 0:0 /* R--VF */
-#define NV_PMC_INTR_READ_0_INTA_LOW 0x00000000 /* R---V */
-#define NV_PMC_INTR_READ_0_INTA_HIGH 0x00000001 /* R---V */
-#define NV_PMC_ENABLE 0x00000200 /* RW-4R */
-#define NV_PMC_ENABLE_PMEDIA 4:4 /* RWIVF */
-#define NV_PMC_ENABLE_PMEDIA_DISABLED 0x00000000 /* RWI-V */
-#define NV_PMC_ENABLE_PMEDIA_ENABLED 0x00000001 /* RW--V */
-#define NV_PMC_ENABLE_PFIFO 8:8 /* RWIVF */
-#define NV_PMC_ENABLE_PFIFO_DISABLED 0x00000000 /* RWI-V */
-#define NV_PMC_ENABLE_PFIFO_ENABLED 0x00000001 /* RW--V */
-#define NV_PMC_ENABLE_PGRAPH 12:12 /* RWIVF */
-#define NV_PMC_ENABLE_PGRAPH_DISABLED 0x00000000 /* RWI-V */
-#define NV_PMC_ENABLE_PGRAPH_ENABLED 0x00000001 /* RW--V */
-#define NV_PMC_ENABLE_PPMI 16:16 /* RWIVF */
-#define NV_PMC_ENABLE_PPMI_DISABLED 0x00000000 /* RWI-V */
-#define NV_PMC_ENABLE_PPMI_ENABLED 0x00000001 /* RW--V */
-#define NV_PMC_ENABLE_PFB 20:20 /* RWIVF */
-#define NV_PMC_ENABLE_PFB_DISABLED 0x00000000 /* RW--V */
-#define NV_PMC_ENABLE_PFB_ENABLED 0x00000001 /* RWI-V */
-#define NV_PMC_ENABLE_PCRTC 24:24 /* RWIVF */
-#define NV_PMC_ENABLE_PCRTC_DISABLED 0x00000000 /* RW--V */
-#define NV_PMC_ENABLE_PCRTC_ENABLED 0x00000001 /* RWI-V */
-#define NV_PMC_ENABLE_PVIDEO 28:28 /* RWIVF */
-#define NV_PMC_ENABLE_PVIDEO_DISABLED 0x00000000 /* RWI-V */
-#define NV_PMC_ENABLE_PVIDEO_ENABLED 0x00000001 /* RW--V */
-
-/* dev_timer.ref */
-#define NV_PTIMER 0x00009FFF:0x00009000 /* RW--D */
-#define NV_PTIMER_INTR_0 0x00009100 /* RW-4R */
-#define NV_PTIMER_INTR_0_ALARM 0:0 /* RWXVF */
-#define NV_PTIMER_INTR_0_ALARM_NOT_PENDING 0x00000000 /* R---V */
-#define NV_PTIMER_INTR_0_ALARM_PENDING 0x00000001 /* R---V */
-#define NV_PTIMER_INTR_0_ALARM_RESET 0x00000001 /* -W--V */
-#define NV_PTIMER_INTR_EN_0 0x00009140 /* RW-4R */
-#define NV_PTIMER_INTR_EN_0_ALARM 0:0 /* RWIVF */
-#define NV_PTIMER_INTR_EN_0_ALARM_DISABLED 0x00000000 /* RWI-V */
-#define NV_PTIMER_INTR_EN_0_ALARM_ENABLED 0x00000001 /* RW--V */
-#define NV_PTIMER_NUMERATOR 0x00009200 /* RW-4R */
-#define NV_PTIMER_NUMERATOR_VALUE 15:0 /* RWIUF */
-#define NV_PTIMER_NUMERATOR_VALUE_0 0x00000000 /* RWI-V */
-#define NV_PTIMER_DENOMINATOR 0x00009210 /* RW-4R */
-#define NV_PTIMER_DENOMINATOR_VALUE 15:0 /* RWIUF */
-#define NV_PTIMER_DENOMINATOR_VALUE_0 0x00000000 /* RWI-V */
-#define NV_PTIMER_TIME_0 0x00009400 /* RW-4R */
-#define NV_PTIMER_TIME_0_NSEC 31:5 /* RWXUF */
-#define NV_PTIMER_TIME_1 0x00009410 /* RW-4R */
-#define NV_PTIMER_TIME_1_NSEC 28:0 /* RWXUF */
-#define NV_PTIMER_ALARM_0 0x00009420 /* RW-4R */
-#define NV_PTIMER_ALARM_0_NSEC 31:5 /* RWXUF */
-
-/* dev_fifo.ref */
-#define NV_PFIFO 0x00003FFF:0x00002000 /* RW--D */
-#define NV_PFIFO_DELAY_0 0x00002040 /* RW-4R */
-#define NV_PFIFO_DELAY_0_WAIT_RETRY 9:0 /* RWIUF */
-#define NV_PFIFO_DELAY_0_WAIT_RETRY_0 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_TIMESLICE 0x00002044 /* RW-4R */
-#define NV_PFIFO_DMA_TIMESLICE_SELECT 16:0 /* RWIUF */
-#define NV_PFIFO_DMA_TIMESLICE_SELECT_1 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_TIMESLICE_SELECT_16K 0x00003fff /* RW--V */
-#define NV_PFIFO_DMA_TIMESLICE_SELECT_32K 0x00007fff /* RW--V */
-#define NV_PFIFO_DMA_TIMESLICE_SELECT_64K 0x0000ffff /* RW--V */
-#define NV_PFIFO_DMA_TIMESLICE_SELECT_128K 0x0001ffff /* RW--V */
-#define NV_PFIFO_DMA_TIMESLICE_TIMEOUT 24:24 /* RWIUF */
-#define NV_PFIFO_DMA_TIMESLICE_TIMEOUT_DISABLED 0x00000000 /* RW--V */
-#define NV_PFIFO_DMA_TIMESLICE_TIMEOUT_ENABLED 0x00000001 /* RWI-V */
-#define NV_PFIFO_PIO_TIMESLICE 0x00002048 /* RW-4R */
-#define NV_PFIFO_PIO_TIMESLICE_SELECT 16:0 /* RWIUF */
-#define NV_PFIFO_PIO_TIMESLICE_SELECT_1 0x00000000 /* RWI-V */
-#define NV_PFIFO_PIO_TIMESLICE_SELECT_16K 0x00003fff /* RW--V */
-#define NV_PFIFO_PIO_TIMESLICE_SELECT_32K 0x00007fff /* RW--V */
-#define NV_PFIFO_PIO_TIMESLICE_SELECT_64K 0x0000ffff /* RW--V */
-#define NV_PFIFO_PIO_TIMESLICE_SELECT_128K 0x0001ffff /* RW--V */
-#define NV_PFIFO_PIO_TIMESLICE_TIMEOUT 24:24 /* RWIUF */
-#define NV_PFIFO_PIO_TIMESLICE_TIMEOUT_DISABLED 0x00000000 /* RW--V */
-#define NV_PFIFO_PIO_TIMESLICE_TIMEOUT_ENABLED 0x00000001 /* RWI-V */
-#define NV_PFIFO_TIMESLICE 0x0000204C /* RW-4R */
-#define NV_PFIFO_TIMESLICE_TIMER 17:0 /* RWIUF */
-#define NV_PFIFO_TIMESLICE_TIMER_EXPIRED 0x0003FFFF /* RWI-V */
-#define NV_PFIFO_NEXT_CHANNEL 0x00002050 /* RW-4R */
-#define NV_PFIFO_NEXT_CHANNEL_CHID 3:0 /* RWXUF */
-#define NV_PFIFO_NEXT_CHANNEL_MODE 8:8 /* RWXVF */
-#define NV_PFIFO_NEXT_CHANNEL_MODE_PIO 0x00000000 /* RW--V */
-#define NV_PFIFO_NEXT_CHANNEL_MODE_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_NEXT_CHANNEL_SWITCH 12:12 /* RWIVF */
-#define NV_PFIFO_NEXT_CHANNEL_SWITCH_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_NEXT_CHANNEL_SWITCH_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_DEBUG_0 0x00002080 /* R--4R */
-#define NV_PFIFO_DEBUG_0_CACHE_ERROR0 0:0 /* R-XVF */
-#define NV_PFIFO_DEBUG_0_CACHE_ERROR0_NOT_PENDING 0x00000000 /* R---V */
-#define NV_PFIFO_DEBUG_0_CACHE_ERROR0_PENDING 0x00000001 /* R---V */
-#define NV_PFIFO_DEBUG_0_CACHE_ERROR1 4:4 /* R-XVF */
-#define NV_PFIFO_DEBUG_0_CACHE_ERROR1_NOT_PENDING 0x00000000 /* R---V */
-#define NV_PFIFO_DEBUG_0_CACHE_ERROR1_PENDING 0x00000001 /* R---V */
-#define NV_PFIFO_INTR_0 0x00002100 /* RW-4R */
-#define NV_PFIFO_INTR_0_CACHE_ERROR 0:0 /* RWXVF */
-#define NV_PFIFO_INTR_0_CACHE_ERROR_NOT_PENDING 0x00000000 /* R---V */
-#define NV_PFIFO_INTR_0_CACHE_ERROR_PENDING 0x00000001 /* R---V */
-#define NV_PFIFO_INTR_0_CACHE_ERROR_RESET 0x00000001 /* -W--V */
-#define NV_PFIFO_INTR_0_RUNOUT 4:4 /* RWXVF */
-#define NV_PFIFO_INTR_0_RUNOUT_NOT_PENDING 0x00000000 /* R---V */
-#define NV_PFIFO_INTR_0_RUNOUT_PENDING 0x00000001 /* R---V */
-#define NV_PFIFO_INTR_0_RUNOUT_RESET 0x00000001 /* -W--V */
-#define NV_PFIFO_INTR_0_RUNOUT_OVERFLOW 8:8 /* RWXVF */
-#define NV_PFIFO_INTR_0_RUNOUT_OVERFLOW_NOT_PENDING 0x00000000 /* R---V */
-#define NV_PFIFO_INTR_0_RUNOUT_OVERFLOW_PENDING 0x00000001 /* R---V */
-#define NV_PFIFO_INTR_0_RUNOUT_OVERFLOW_RESET 0x00000001 /* -W--V */
-#define NV_PFIFO_INTR_0_DMA_PUSHER 12:12 /* RWXVF */
-#define NV_PFIFO_INTR_0_DMA_PUSHER_NOT_PENDING 0x00000000 /* R---V */
-#define NV_PFIFO_INTR_0_DMA_PUSHER_PENDING 0x00000001 /* R---V */
-#define NV_PFIFO_INTR_0_DMA_PUSHER_RESET 0x00000001 /* -W--V */
-#define NV_PFIFO_INTR_0_DMA_PT 16:16 /* RWXVF */
-#define NV_PFIFO_INTR_0_DMA_PT_NOT_PENDING 0x00000000 /* R---V */
-#define NV_PFIFO_INTR_0_DMA_PT_PENDING 0x00000001 /* R---V */
-#define NV_PFIFO_INTR_0_DMA_PT_RESET 0x00000001 /* -W--V */
-#define NV_PFIFO_INTR_EN_0 0x00002140 /* RW-4R */
-#define NV_PFIFO_INTR_EN_0_CACHE_ERROR 0:0 /* RWIVF */
-#define NV_PFIFO_INTR_EN_0_CACHE_ERROR_DISABLED 0x00000000 /* RWI-V */
-#define NV_PFIFO_INTR_EN_0_CACHE_ERROR_ENABLED 0x00000001 /* RW--V */
-#define NV_PFIFO_INTR_EN_0_RUNOUT 4:4 /* RWIVF */
-#define NV_PFIFO_INTR_EN_0_RUNOUT_DISABLED 0x00000000 /* RWI-V */
-#define NV_PFIFO_INTR_EN_0_RUNOUT_ENABLED 0x00000001 /* RW--V */
-#define NV_PFIFO_INTR_EN_0_RUNOUT_OVERFLOW 8:8 /* RWIVF */
-#define NV_PFIFO_INTR_EN_0_RUNOUT_OVERFLOW_DISABLED 0x00000000 /* RWI-V */
-#define NV_PFIFO_INTR_EN_0_RUNOUT_OVERFLOW_ENABLED 0x00000001 /* RW--V */
-#define NV_PFIFO_INTR_EN_0_DMA_PUSHER 12:12 /* RWIVF */
-#define NV_PFIFO_INTR_EN_0_DMA_PUSHER_DISABLED 0x00000000 /* RWI-V */
-#define NV_PFIFO_INTR_EN_0_DMA_PUSHER_ENABLED 0x00000001 /* RW--V */
-#define NV_PFIFO_INTR_EN_0_DMA_PT 16:16 /* RWIVF */
-#define NV_PFIFO_INTR_EN_0_DMA_PT_DISABLED 0x00000000 /* RWI-V */
-#define NV_PFIFO_INTR_EN_0_DMA_PT_ENABLED 0x00000001 /* RW--V */
-#define NV_PFIFO_RAMHT 0x00002210 /* RW-4R */
-#define NV_PFIFO_RAMHT_BASE_ADDRESS 8:4 /* RWIUF */
-#define NV_PFIFO_RAMHT_BASE_ADDRESS_10000 0x00000010 /* RWI-V */
-#define NV_PFIFO_RAMHT_SIZE 17:16 /* RWIUF */
-#define NV_PFIFO_RAMHT_SIZE_4K 0x00000000 /* RWI-V */
-#define NV_PFIFO_RAMHT_SIZE_8K 0x00000001 /* RW--V */
-#define NV_PFIFO_RAMHT_SIZE_16K 0x00000002 /* RW--V */
-#define NV_PFIFO_RAMHT_SIZE_32K 0x00000003 /* RW--V */
-#define NV_PFIFO_RAMHT_SEARCH 25:24 /* RWIUF */
-#define NV_PFIFO_RAMHT_SEARCH_16 0x00000000 /* RWI-V */
-#define NV_PFIFO_RAMHT_SEARCH_32 0x00000001 /* RW--V */
-#define NV_PFIFO_RAMHT_SEARCH_64 0x00000002 /* RW--V */
-#define NV_PFIFO_RAMHT_SEARCH_128 0x00000003 /* RW--V */
-#define NV_PFIFO_RAMFC 0x00002214 /* RW-4R */
-#define NV_PFIFO_RAMFC_BASE_ADDRESS 8:1 /* RWIUF */
-#define NV_PFIFO_RAMFC_BASE_ADDRESS_11000 0x00000088 /* RWI-V */
-#define NV_PFIFO_RAMRO 0x00002218 /* RW-4R */
-#define NV_PFIFO_RAMRO_BASE_ADDRESS 8:1 /* RWIUF */
-#define NV_PFIFO_RAMRO_BASE_ADDRESS_11200 0x00000089 /* RWI-V */
-#define NV_PFIFO_RAMRO_BASE_ADDRESS_12000 0x00000090 /* RW--V */
-#define NV_PFIFO_RAMRO_SIZE 16:16 /* RWIVF */
-#define NV_PFIFO_RAMRO_SIZE_512 0x00000000 /* RWI-V */
-#define NV_PFIFO_RAMRO_SIZE_8K 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHES 0x00002500 /* RW-4R */
-#define NV_PFIFO_CACHES_REASSIGN 0:0 /* RWIVF */
-#define NV_PFIFO_CACHES_REASSIGN_DISABLED 0x00000000 /* RWI-V */
-#define NV_PFIFO_CACHES_REASSIGN_ENABLED 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHES_DMA_SUSPEND 4:4 /* R--VF */
-#define NV_PFIFO_CACHES_DMA_SUSPEND_IDLE 0x00000000 /* R---V */
-#define NV_PFIFO_CACHES_DMA_SUSPEND_BUSY 0x00000001 /* R---V */
-#define NV_PFIFO_MODE 0x00002504 /* RW-4R */
-#define NV_PFIFO_MODE_CHANNEL_0 0:0 /* RWIVF */
-#define NV_PFIFO_MODE_CHANNEL_0_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_MODE_CHANNEL_0_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_MODE_CHANNEL_1 1:1 /* RWIVF */
-#define NV_PFIFO_MODE_CHANNEL_1_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_MODE_CHANNEL_1_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_MODE_CHANNEL_2 2:2 /* RWIVF */
-#define NV_PFIFO_MODE_CHANNEL_2_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_MODE_CHANNEL_2_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_MODE_CHANNEL_3 3:3 /* RWIVF */
-#define NV_PFIFO_MODE_CHANNEL_3_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_MODE_CHANNEL_3_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_MODE_CHANNEL_4 4:4 /* RWIVF */
-#define NV_PFIFO_MODE_CHANNEL_4_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_MODE_CHANNEL_4_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_MODE_CHANNEL_5 5:5 /* RWIVF */
-#define NV_PFIFO_MODE_CHANNEL_5_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_MODE_CHANNEL_5_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_MODE_CHANNEL_6 6:6 /* RWIVF */
-#define NV_PFIFO_MODE_CHANNEL_6_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_MODE_CHANNEL_6_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_MODE_CHANNEL_7 7:7 /* RWIVF */
-#define NV_PFIFO_MODE_CHANNEL_7_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_MODE_CHANNEL_7_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_MODE_CHANNEL_8 8:8 /* RWIVF */
-#define NV_PFIFO_MODE_CHANNEL_8_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_MODE_CHANNEL_8_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_MODE_CHANNEL_9 9:9 /* RWIVF */
-#define NV_PFIFO_MODE_CHANNEL_9_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_MODE_CHANNEL_9_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_MODE_CHANNEL_10 10:10 /* RWIVF */
-#define NV_PFIFO_MODE_CHANNEL_10_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_MODE_CHANNEL_10_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_MODE_CHANNEL_11 11:11 /* RWIVF */
-#define NV_PFIFO_MODE_CHANNEL_11_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_MODE_CHANNEL_11_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_MODE_CHANNEL_12 12:12 /* RWIVF */
-#define NV_PFIFO_MODE_CHANNEL_12_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_MODE_CHANNEL_12_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_MODE_CHANNEL_13 13:13 /* RWIVF */
-#define NV_PFIFO_MODE_CHANNEL_13_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_MODE_CHANNEL_13_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_MODE_CHANNEL_14 14:14 /* RWIVF */
-#define NV_PFIFO_MODE_CHANNEL_14_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_MODE_CHANNEL_14_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_MODE_CHANNEL_15 15:15 /* RWIVF */
-#define NV_PFIFO_MODE_CHANNEL_15_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_MODE_CHANNEL_15_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_DMA 0x00002508 /* RW-4R */
-#define NV_PFIFO_DMA_CHANNEL_0 0:0 /* RWIVF */
-#define NV_PFIFO_DMA_CHANNEL_0_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_CHANNEL_0_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_DMA_CHANNEL_1 1:1 /* RWIVF */
-#define NV_PFIFO_DMA_CHANNEL_1_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_CHANNEL_1_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_DMA_CHANNEL_2 2:2 /* RWIVF */
-#define NV_PFIFO_DMA_CHANNEL_2_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_CHANNEL_2_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_DMA_CHANNEL_3 3:3 /* RWIVF */
-#define NV_PFIFO_DMA_CHANNEL_3_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_CHANNEL_3_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_DMA_CHANNEL_4 4:4 /* RWIVF */
-#define NV_PFIFO_DMA_CHANNEL_4_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_CHANNEL_4_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_DMA_CHANNEL_5 5:5 /* RWIVF */
-#define NV_PFIFO_DMA_CHANNEL_5_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_CHANNEL_5_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_DMA_CHANNEL_6 6:6 /* RWIVF */
-#define NV_PFIFO_DMA_CHANNEL_6_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_CHANNEL_6_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_DMA_CHANNEL_7 7:7 /* RWIVF */
-#define NV_PFIFO_DMA_CHANNEL_7_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_CHANNEL_7_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_DMA_CHANNEL_8 8:8 /* RWIVF */
-#define NV_PFIFO_DMA_CHANNEL_8_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_CHANNEL_8_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_DMA_CHANNEL_9 9:9 /* RWIVF */
-#define NV_PFIFO_DMA_CHANNEL_9_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_CHANNEL_9_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_DMA_CHANNEL_10 10:10 /* RWIVF */
-#define NV_PFIFO_DMA_CHANNEL_10_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_CHANNEL_10_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_DMA_CHANNEL_11 11:11 /* RWIVF */
-#define NV_PFIFO_DMA_CHANNEL_11_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_CHANNEL_11_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_DMA_CHANNEL_12 12:12 /* RWIVF */
-#define NV_PFIFO_DMA_CHANNEL_12_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_CHANNEL_12_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_DMA_CHANNEL_13 13:13 /* RWIVF */
-#define NV_PFIFO_DMA_CHANNEL_13_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_CHANNEL_13_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_DMA_CHANNEL_14 14:14 /* RWIVF */
-#define NV_PFIFO_DMA_CHANNEL_14_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_CHANNEL_14_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_DMA_CHANNEL_15 15:15 /* RWIVF */
-#define NV_PFIFO_DMA_CHANNEL_15_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_CHANNEL_15_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_SIZE 0x0000250C /* RW-4R */
-#define NV_PFIFO_SIZE_CHANNEL_0 0:0 /* RWIVF */
-#define NV_PFIFO_SIZE_CHANNEL_0_124_BYTES 0x00000000 /* RWI-V */
-#define NV_PFIFO_SIZE_CHANNEL_0_512_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_SIZE_CHANNEL_1 1:1 /* RWIVF */
-#define NV_PFIFO_SIZE_CHANNEL_1_124_BYTES 0x00000000 /* RWI-V */
-#define NV_PFIFO_SIZE_CHANNEL_1_512_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_SIZE_CHANNEL_2 2:2 /* RWIVF */
-#define NV_PFIFO_SIZE_CHANNEL_2_124_BYTES 0x00000000 /* RWI-V */
-#define NV_PFIFO_SIZE_CHANNEL_2_512_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_SIZE_CHANNEL_3 3:3 /* RWIVF */
-#define NV_PFIFO_SIZE_CHANNEL_3_124_BYTES 0x00000000 /* RWI-V */
-#define NV_PFIFO_SIZE_CHANNEL_3_512_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_SIZE_CHANNEL_4 4:4 /* RWIVF */
-#define NV_PFIFO_SIZE_CHANNEL_4_124_BYTES 0x00000000 /* RWI-V */
-#define NV_PFIFO_SIZE_CHANNEL_4_512_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_SIZE_CHANNEL_5 5:5 /* RWIVF */
-#define NV_PFIFO_SIZE_CHANNEL_5_124_BYTES 0x00000000 /* RWI-V */
-#define NV_PFIFO_SIZE_CHANNEL_5_512_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_SIZE_CHANNEL_6 6:6 /* RWIVF */
-#define NV_PFIFO_SIZE_CHANNEL_6_124_BYTES 0x00000000 /* RWI-V */
-#define NV_PFIFO_SIZE_CHANNEL_6_512_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_SIZE_CHANNEL_7 7:7 /* RWIVF */
-#define NV_PFIFO_SIZE_CHANNEL_7_124_BYTES 0x00000000 /* RWI-V */
-#define NV_PFIFO_SIZE_CHANNEL_7_512_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_SIZE_CHANNEL_8 8:8 /* RWIVF */
-#define NV_PFIFO_SIZE_CHANNEL_8_124_BYTES 0x00000000 /* RWI-V */
-#define NV_PFIFO_SIZE_CHANNEL_8_512_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_SIZE_CHANNEL_9 9:9 /* RWIVF */
-#define NV_PFIFO_SIZE_CHANNEL_9_124_BYTES 0x00000000 /* RWI-V */
-#define NV_PFIFO_SIZE_CHANNEL_9_512_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_SIZE_CHANNEL_10 10:10 /* RWIVF */
-#define NV_PFIFO_SIZE_CHANNEL_10_124_BYTES 0x00000000 /* RWI-V */
-#define NV_PFIFO_SIZE_CHANNEL_10_512_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_SIZE_CHANNEL_11 11:11 /* RWIVF */
-#define NV_PFIFO_SIZE_CHANNEL_11_124_BYTES 0x00000000 /* RWI-V */
-#define NV_PFIFO_SIZE_CHANNEL_11_512_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_SIZE_CHANNEL_12 12:12 /* RWIVF */
-#define NV_PFIFO_SIZE_CHANNEL_12_124_BYTES 0x00000000 /* RWI-V */
-#define NV_PFIFO_SIZE_CHANNEL_12_512_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_SIZE_CHANNEL_13 13:13 /* RWIVF */
-#define NV_PFIFO_SIZE_CHANNEL_13_124_BYTES 0x00000000 /* RWI-V */
-#define NV_PFIFO_SIZE_CHANNEL_13_512_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_SIZE_CHANNEL_14 14:14 /* RWIVF */
-#define NV_PFIFO_SIZE_CHANNEL_14_124_BYTES 0x00000000 /* RWI-V */
-#define NV_PFIFO_SIZE_CHANNEL_14_512_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_SIZE_CHANNEL_15 15:15 /* RWIVF */
-#define NV_PFIFO_SIZE_CHANNEL_15_124_BYTES 0x00000000 /* RWI-V */
-#define NV_PFIFO_SIZE_CHANNEL_15_512_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE0_PUSH0 0x00003000 /* RW-4R */
-#define NV_PFIFO_CACHE0_PUSH0_ACCESS 0:0 /* RWIVF */
-#define NV_PFIFO_CACHE0_PUSH0_ACCESS_DISABLED 0x00000000 /* RWI-V */
-#define NV_PFIFO_CACHE0_PUSH0_ACCESS_ENABLED 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_PUSH0 0x00003200 /* RW-4R */
-#define NV_PFIFO_CACHE1_PUSH0_ACCESS 0:0 /* RWIVF */
-#define NV_PFIFO_CACHE1_PUSH0_ACCESS_DISABLED 0x00000000 /* RWI-V */
-#define NV_PFIFO_CACHE1_PUSH0_ACCESS_ENABLED 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE0_PUSH1 0x00003004 /* RW-4R */
-#define NV_PFIFO_CACHE0_PUSH1_CHID 3:0 /* RWXUF */
-#define NV_PFIFO_CACHE1_PUSH1 0x00003204 /* RW-4R */
-#define NV_PFIFO_CACHE1_PUSH1_CHID 3:0 /* RWXUF */
-#define NV_PFIFO_CACHE1_PUSH1_MODE 8:8 /* RWIVF */
-#define NV_PFIFO_CACHE1_PUSH1_MODE_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_CACHE1_PUSH1_MODE_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_PUSH 0x00003220 /* RW-4R */
-#define NV_PFIFO_CACHE1_DMA_PUSH_ACCESS 0:0 /* RWIVF */
-#define NV_PFIFO_CACHE1_DMA_PUSH_ACCESS_DISABLED 0x00000000 /* RWI-V */
-#define NV_PFIFO_CACHE1_DMA_PUSH_ACCESS_ENABLED 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_PUSH_STATE 4:4 /* R--VF */
-#define NV_PFIFO_CACHE1_DMA_PUSH_STATE_IDLE 0x00000000 /* R---V */
-#define NV_PFIFO_CACHE1_DMA_PUSH_STATE_BUSY 0x00000001 /* R---V */
-#define NV_PFIFO_CACHE1_DMA_PUSH_BUFFER 8:8 /* R--VF */
-#define NV_PFIFO_CACHE1_DMA_PUSH_BUFFER_NOT_EMPTY 0x00000000 /* R---V */
-#define NV_PFIFO_CACHE1_DMA_PUSH_BUFFER_EMPTY 0x00000001 /* R---V */
-#define NV_PFIFO_CACHE1_DMA_PUSH_STATUS 12:12 /* RWIVF */
-#define NV_PFIFO_CACHE1_DMA_PUSH_STATUS_RUNNING 0x00000000 /* RWI-V */
-#define NV_PFIFO_CACHE1_DMA_PUSH_STATUS_SUSPENDED 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH 0x00003224 /* RW-4R */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG 7:3 /* RWIUF */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_8_BYTES 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_16_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_24_BYTES 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_32_BYTES 0x00000003 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_40_BYTES 0x00000004 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_48_BYTES 0x00000005 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_56_BYTES 0x00000006 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_64_BYTES 0x00000007 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_72_BYTES 0x00000008 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_80_BYTES 0x00000009 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_88_BYTES 0x0000000A /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_96_BYTES 0x0000000B /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_104_BYTES 0x0000000C /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_112_BYTES 0x0000000D /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_120_BYTES 0x0000000E /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES 0x0000000F /* RWI-V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_136_BYTES 0x00000010 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_144_BYTES 0x00000011 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_152_BYTES 0x00000012 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_160_BYTES 0x00000013 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_168_BYTES 0x00000014 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_176_BYTES 0x00000015 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_184_BYTES 0x00000016 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_192_BYTES 0x00000017 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_200_BYTES 0x00000018 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_208_BYTES 0x00000019 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_216_BYTES 0x0000001A /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_224_BYTES 0x0000001B /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_232_BYTES 0x0000001C /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_240_BYTES 0x0000001D /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_248_BYTES 0x0000001E /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_256_BYTES 0x0000001F /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE 15:13 /* RWIUF */
-#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_32_BYTES 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_64_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_96_BYTES 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES 0x00000003 /* RWI-V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_160_BYTES 0x00000004 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_192_BYTES 0x00000005 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_224_BYTES 0x00000006 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_256_BYTES 0x00000007 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS 19:16 /* RWIUF */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_0 0x00000000 /* RWI-V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_1 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_2 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_3 0x00000003 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_4 0x00000004 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_5 0x00000005 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_6 0x00000006 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_7 0x00000007 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 0x00000008 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_9 0x00000009 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_10 0x0000000A /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_11 0x0000000B /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_12 0x0000000C /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_13 0x0000000D /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_14 0x0000000E /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_15 0x0000000F /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_PUT 0x00003240 /* RW-4R */
-#define NV_PFIFO_CACHE1_DMA_PUT_OFFSET 28:2 /* RWXUF */
-#define NV_PFIFO_CACHE1_DMA_GET 0x00003244 /* RW-4R */
-#define NV_PFIFO_CACHE1_DMA_GET_OFFSET 28:2 /* RWXUF */
-#define NV_PFIFO_CACHE1_DMA_STATE 0x00003228 /* RW-4R */
-#define NV_PFIFO_CACHE1_DMA_STATE_METHOD 12:2 /* RWXUF */
-#define NV_PFIFO_CACHE1_DMA_STATE_SUBCHANNEL 15:13 /* RWXUF */
-#define NV_PFIFO_CACHE1_DMA_STATE_METHOD_COUNT 28:18 /* RWIUF */
-#define NV_PFIFO_CACHE1_DMA_STATE_METHOD_COUNT_0 0x00000000 /* RWI-V */
-#define NV_PFIFO_CACHE1_DMA_STATE_ERROR 31:30 /* RWXUF */
-#define NV_PFIFO_CACHE1_DMA_STATE_ERROR_NONE 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_STATE_ERROR_NON_CACHE 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_STATE_ERROR_RESERVED_CMD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_STATE_ERROR_PROTECTION 0x00000003 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_INSTANCE 0x0000322C /* RW-4R */
-#define NV_PFIFO_CACHE1_DMA_INSTANCE_ADDRESS 15:0 /* RWXUF */
-#define NV_PFIFO_CACHE1_DMA_CTL 0x00003230 /* RW-4R */
-#define NV_PFIFO_CACHE1_DMA_CTL_ADJUST 11:2 /* RWXUF */
-#define NV_PFIFO_CACHE1_DMA_CTL_PAGE_TABLE 12:12 /* RWXUF */
-#define NV_PFIFO_CACHE1_DMA_CTL_PAGE_TABLE_NOT_PRESENT 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_CTL_PAGE_TABLE_PRESENT 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_CTL_PAGE_ENTRY 13:13 /* RWXUF */
-#define NV_PFIFO_CACHE1_DMA_CTL_PAGE_ENTRY_NOT_LINEAR 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_CTL_PAGE_ENTRY_LINEAR 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_CTL_TARGET_NODE 17:16 /* RWXUF */
-#define NV_PFIFO_CACHE1_DMA_CTL_TARGET_NODE_PCI 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_CTL_TARGET_NODE_AGP 0x00000003 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_CTL_AT_INFO 31:31 /* RWIUF */
-#define NV_PFIFO_CACHE1_DMA_CTL_AT_INFO_INVALID 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_CTL_AT_INFO_VALID 0x00000001 /* RWI-V */
-#define NV_PFIFO_CACHE1_DMA_LIMIT 0x00003234 /* RW-4R */
-#define NV_PFIFO_CACHE1_DMA_LIMIT_OFFSET 28:2 /* RWXUF */
-#define NV_PFIFO_CACHE1_DMA_TLB_TAG 0x00003238 /* RW-4R */
-#define NV_PFIFO_CACHE1_DMA_TLB_TAG_ADDRESS 28:12 /* RWXUF */
-#define NV_PFIFO_CACHE1_DMA_TLB_TAG_STATE 0:0 /* RWIUF */
-#define NV_PFIFO_CACHE1_DMA_TLB_TAG_STATE_INVALID 0x00000000 /* RWI-V */
-#define NV_PFIFO_CACHE1_DMA_TLB_TAG_STATE_VALID 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_TLB_PTE 0x0000323C /* RW-4R */
-#define NV_PFIFO_CACHE1_DMA_TLB_PTE_FRAME_ADDRESS 31:12 /* RWXUF */
-#define NV_PFIFO_CACHE0_PULL0 0x00003050 /* RW-4R */
-#define NV_PFIFO_CACHE0_PULL0_ACCESS 0:0 /* RWIVF */
-#define NV_PFIFO_CACHE0_PULL0_ACCESS_DISABLED 0x00000000 /* RWI-V */
-#define NV_PFIFO_CACHE0_PULL0_ACCESS_ENABLED 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE0_PULL0_HASH 4:4 /* R-XVF */
-#define NV_PFIFO_CACHE0_PULL0_HASH_SUCCEEDED 0x00000000 /* R---V */
-#define NV_PFIFO_CACHE0_PULL0_HASH_FAILED 0x00000001 /* R---V */
-#define NV_PFIFO_CACHE0_PULL0_DEVICE 8:8 /* R-XVF */
-#define NV_PFIFO_CACHE0_PULL0_DEVICE_HARDWARE 0x00000000 /* R---V */
-#define NV_PFIFO_CACHE0_PULL0_DEVICE_SOFTWARE 0x00000001 /* R---V */
-#define NV_PFIFO_CACHE0_PULL0_HASH_STATE 12:12 /* R-XVF */
-#define NV_PFIFO_CACHE0_PULL0_HASH_STATE_IDLE 0x00000000 /* R---V */
-#define NV_PFIFO_CACHE0_PULL0_HASH_STATE_BUSY 0x00000001 /* R---V */
-#define NV_PFIFO_CACHE1_PULL0 0x00003250 /* RW-4R */
-#define NV_PFIFO_CACHE1_PULL0_ACCESS 0:0 /* RWIVF */
-#define NV_PFIFO_CACHE1_PULL0_ACCESS_DISABLED 0x00000000 /* RWI-V */
-#define NV_PFIFO_CACHE1_PULL0_ACCESS_ENABLED 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_PULL0_HASH 4:4 /* R-XVF */
-#define NV_PFIFO_CACHE1_PULL0_HASH_SUCCEEDED 0x00000000 /* R---V */
-#define NV_PFIFO_CACHE1_PULL0_HASH_FAILED 0x00000001 /* R---V */
-#define NV_PFIFO_CACHE1_PULL0_DEVICE 8:8 /* R-XVF */
-#define NV_PFIFO_CACHE1_PULL0_DEVICE_HARDWARE 0x00000000 /* R---V */
-#define NV_PFIFO_CACHE1_PULL0_DEVICE_SOFTWARE 0x00000001 /* R---V */
-#define NV_PFIFO_CACHE1_PULL0_HASH_STATE 12:12 /* R-XVF */
-#define NV_PFIFO_CACHE1_PULL0_HASH_STATE_IDLE 0x00000000 /* R---V */
-#define NV_PFIFO_CACHE1_PULL0_HASH_STATE_BUSY 0x00000001 /* R---V */
-#define NV_PFIFO_CACHE0_PULL1 0x00003054 /* RW-4R */
-#define NV_PFIFO_CACHE0_PULL1_ENGINE 1:0 /* RWXUF */
-#define NV_PFIFO_CACHE0_PULL1_ENGINE_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE0_PULL1_ENGINE_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE0_PULL1_ENGINE_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE1_PULL1 0x00003254 /* RW-4R */
-#define NV_PFIFO_CACHE1_PULL1_ENGINE 1:0 /* RWXUF */
-#define NV_PFIFO_CACHE1_PULL1_ENGINE_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE1_PULL1_ENGINE_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_PULL1_ENGINE_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE0_HASH 0x00003058 /* RW-4R */
-#define NV_PFIFO_CACHE0_HASH_INSTANCE 15:0 /* RWXUF */
-#define NV_PFIFO_CACHE0_HASH_VALID 16:16 /* RWXVF */
-#define NV_PFIFO_CACHE1_HASH 0x00003258 /* RW-4R */
-#define NV_PFIFO_CACHE1_HASH_INSTANCE 15:0 /* RWXUF */
-#define NV_PFIFO_CACHE1_HASH_VALID 16:16 /* RWXVF */
-#define NV_PFIFO_CACHE0_STATUS 0x00003014 /* R--4R */
-#define NV_PFIFO_CACHE0_STATUS_LOW_MARK 4:4 /* R--VF */
-#define NV_PFIFO_CACHE0_STATUS_LOW_MARK_NOT_EMPTY 0x00000000 /* R---V */
-#define NV_PFIFO_CACHE0_STATUS_LOW_MARK_EMPTY 0x00000001 /* R---V */
-#define NV_PFIFO_CACHE0_STATUS_HIGH_MARK 8:8 /* R--VF */
-#define NV_PFIFO_CACHE0_STATUS_HIGH_MARK_NOT_FULL 0x00000000 /* R---V */
-#define NV_PFIFO_CACHE0_STATUS_HIGH_MARK_FULL 0x00000001 /* R---V */
-#define NV_PFIFO_CACHE1_STATUS 0x00003214 /* R--4R */
-#define NV_PFIFO_CACHE1_STATUS_LOW_MARK 4:4 /* R--VF */
-#define NV_PFIFO_CACHE1_STATUS_LOW_MARK_NOT_EMPTY 0x00000000 /* R---V */
-#define NV_PFIFO_CACHE1_STATUS_LOW_MARK_EMPTY 0x00000001 /* R---V */
-#define NV_PFIFO_CACHE1_STATUS_HIGH_MARK 8:8 /* R--VF */
-#define NV_PFIFO_CACHE1_STATUS_HIGH_MARK_NOT_FULL 0x00000000 /* R---V */
-#define NV_PFIFO_CACHE1_STATUS_HIGH_MARK_FULL 0x00000001 /* R---V */
-#define NV_PFIFO_CACHE1_STATUS1 0x00003218 /* R--4R */
-#define NV_PFIFO_CACHE1_STATUS1_RANOUT 0:0 /* R-XVF */
-#define NV_PFIFO_CACHE1_STATUS1_RANOUT_FALSE 0x00000000 /* R---V */
-#define NV_PFIFO_CACHE1_STATUS1_RANOUT_TRUE 0x00000001 /* R---V */
-#define NV_PFIFO_CACHE0_PUT 0x00003010 /* RW-4R */
-#define NV_PFIFO_CACHE0_PUT_ADDRESS 2:2 /* RWXUF */
-#define NV_PFIFO_CACHE1_PUT 0x00003210 /* RW-4R */
-#define NV_PFIFO_CACHE1_PUT_ADDRESS 9:2 /* RWXUF */
-#define NV_PFIFO_CACHE0_GET 0x00003070 /* RW-4R */
-#define NV_PFIFO_CACHE0_GET_ADDRESS 2:2 /* RWXUF */
-#define NV_PFIFO_CACHE1_GET 0x00003270 /* RW-4R */
-#define NV_PFIFO_CACHE1_GET_ADDRESS 9:2 /* RWXUF */
-#define NV_PFIFO_CACHE0_ENGINE 0x00003080 /* RW-4R */
-#define NV_PFIFO_CACHE0_ENGINE_0 1:0 /* RWXUF */
-#define NV_PFIFO_CACHE0_ENGINE_0_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_0_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_0_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_1 5:4 /* RWXUF */
-#define NV_PFIFO_CACHE0_ENGINE_1_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_1_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_1_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_2 9:8 /* RWXUF */
-#define NV_PFIFO_CACHE0_ENGINE_2_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_2_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_2_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_3 13:12 /* RWXUF */
-#define NV_PFIFO_CACHE0_ENGINE_3_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_3_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_3_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_4 17:16 /* RWXUF */
-#define NV_PFIFO_CACHE0_ENGINE_4_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_4_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_4_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_5 21:20 /* RWXUF */
-#define NV_PFIFO_CACHE0_ENGINE_5_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_5_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_5_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_6 25:24 /* RWXUF */
-#define NV_PFIFO_CACHE0_ENGINE_6_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_6_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_6_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_7 29:28 /* RWXUF */
-#define NV_PFIFO_CACHE0_ENGINE_7_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_7_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_7_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE 0x00003280 /* RW-4R */
-#define NV_PFIFO_CACHE1_ENGINE_0 1:0 /* RWXUF */
-#define NV_PFIFO_CACHE1_ENGINE_0_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_0_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_0_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_1 5:4 /* RWXUF */
-#define NV_PFIFO_CACHE1_ENGINE_1_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_1_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_1_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_2 9:8 /* RWXUF */
-#define NV_PFIFO_CACHE1_ENGINE_2_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_2_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_2_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_3 13:12 /* RWXUF */
-#define NV_PFIFO_CACHE1_ENGINE_3_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_3_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_3_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_4 17:16 /* RWXUF */
-#define NV_PFIFO_CACHE1_ENGINE_4_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_4_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_4_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_5 21:20 /* RWXUF */
-#define NV_PFIFO_CACHE1_ENGINE_5_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_5_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_5_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_6 25:24 /* RWXUF */
-#define NV_PFIFO_CACHE1_ENGINE_6_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_6_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_6_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_7 29:28 /* RWXUF */
-#define NV_PFIFO_CACHE1_ENGINE_7_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_7_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_7_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE0_METHOD(i) (0x00003100+(i)*8) /* RW-4A */
-#define NV_PFIFO_CACHE0_METHOD__SIZE_1 1 /* */
-#define NV_PFIFO_CACHE0_METHOD_ADDRESS 12:2 /* RWXUF */
-#define NV_PFIFO_CACHE0_METHOD_SUBCHANNEL 15:13 /* RWXUF */
-#define NV_PFIFO_CACHE1_METHOD(i) (0x00003800+(i)*8) /* RW-4A */
-#define NV_PFIFO_CACHE1_METHOD__SIZE_1 128 /* */
-#define NV_PFIFO_CACHE1_METHOD_ADDRESS 12:2 /* RWXUF */
-#define NV_PFIFO_CACHE1_METHOD_SUBCHANNEL 15:13 /* RWXUF */
-#define NV_PFIFO_CACHE1_METHOD_ALIAS(i) (0x00003C00+(i)*8) /* RW-4A */
-#define NV_PFIFO_CACHE1_METHOD_ALIAS__SIZE_1 128 /* */
-#define NV_PFIFO_CACHE0_DATA(i) (0x00003104+(i)*8) /* RW-4A */
-#define NV_PFIFO_CACHE0_DATA__SIZE_1 1 /* */
-#define NV_PFIFO_CACHE0_DATA_VALUE 31:0 /* RWXVF */
-#define NV_PFIFO_CACHE1_DATA(i) (0x00003804+(i)*8) /* RW-4A */
-#define NV_PFIFO_CACHE1_DATA__SIZE_1 128 /* */
-#define NV_PFIFO_CACHE1_DATA_VALUE 31:0 /* RWXVF */
-#define NV_PFIFO_CACHE1_DATA_ALIAS(i) (0x00003C04+(i)*8) /* RW-4A */
-#define NV_PFIFO_CACHE1_DATA_ALIAS__SIZE_1 128 /* */
-#define NV_PFIFO_DEVICE(i) (0x00002800+(i)*4) /* R--4A */
-#define NV_PFIFO_DEVICE__SIZE_1 128 /* */
-#define NV_PFIFO_DEVICE_CHID 3:0 /* R--UF */
-#define NV_PFIFO_DEVICE_SWITCH 24:24 /* R--VF */
-#define NV_PFIFO_DEVICE_SWITCH_UNAVAILABLE 0x00000000 /* R---V */
-#define NV_PFIFO_DEVICE_SWITCH_AVAILABLE 0x00000001 /* R---V */
-#define NV_PFIFO_RUNOUT_STATUS 0x00002400 /* R--4R */
-#define NV_PFIFO_RUNOUT_STATUS_RANOUT 0:0 /* R--VF */
-#define NV_PFIFO_RUNOUT_STATUS_RANOUT_FALSE 0x00000000 /* R---V */
-#define NV_PFIFO_RUNOUT_STATUS_RANOUT_TRUE 0x00000001 /* R---V */
-#define NV_PFIFO_RUNOUT_STATUS_LOW_MARK 4:4 /* R--VF */
-#define NV_PFIFO_RUNOUT_STATUS_LOW_MARK_NOT_EMPTY 0x00000000 /* R---V */
-#define NV_PFIFO_RUNOUT_STATUS_LOW_MARK_EMPTY 0x00000001 /* R---V */
-#define NV_PFIFO_RUNOUT_STATUS_HIGH_MARK 8:8 /* R--VF */
-#define NV_PFIFO_RUNOUT_STATUS_HIGH_MARK_NOT_FULL 0x00000000 /* R---V */
-#define NV_PFIFO_RUNOUT_STATUS_HIGH_MARK_FULL 0x00000001 /* R---V */
-#define NV_PFIFO_RUNOUT_PUT 0x00002410 /* RW-4R */
-#define NV_PFIFO_RUNOUT_PUT_ADDRESS 12:3 /* RWXUF */
-#define NV_PFIFO_RUNOUT_PUT_ADDRESS__SIZE_0 8:3 /* RWXUF */
-#define NV_PFIFO_RUNOUT_PUT_ADDRESS__SIZE_1 12:3 /* RWXUF */
-#define NV_PFIFO_RUNOUT_GET 0x00002420 /* RW-4R */
-#define NV_PFIFO_RUNOUT_GET_ADDRESS 13:3 /* RWXUF */
-/* dev_graphics.ref */
-#define NV_PGRAPH 0x00401FFF:0x00400000 /* RW--D */
-#define NV_PGRAPH_DEBUG_0 0x00400080 /* RW-4R */
-#define NV_PGRAPH_DEBUG_1 0x00400084 /* RW-4R */
-#define NV_PGRAPH_DEBUG_2 0x00400088 /* RW-4R */
-#define NV_PGRAPH_DEBUG_3 0x0040008C /* RW-4R */
-#define NV_PGRAPH_INTR 0x00400100 /* RW-4R */
-#define NV_PGRAPH_INTR_NOTIFY 0:0 /* RWIVF */
-#define NV_PGRAPH_INTR_NOTIFY_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_INTR_NOTIFY_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_INTR_NOTIFY_RESET 0x00000001 /* -W--C */
-#define NV_PGRAPH_INTR_MISSING_HW 4:4 /* RWIVF */
-#define NV_PGRAPH_INTR_MISSING_HW_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_INTR_MISSING_HW_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_INTR_MISSING_HW_RESET 0x00000001 /* -W--C */
-#define NV_PGRAPH_INTR_TLB_PRESENT_A 8:8 /* RWIVF */
-#define NV_PGRAPH_INTR_TLB_PRESENT_A_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_INTR_TLB_PRESENT_A_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_INTR_TLB_PRESENT_A_RESET 0x00000001 /* -W--C */
-#define NV_PGRAPH_INTR_TLB_PRESENT_B 9:9 /* RWIVF */
-#define NV_PGRAPH_INTR_TLB_PRESENT_B_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_INTR_TLB_PRESENT_B_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_INTR_TLB_PRESENT_B_RESET 0x00000001 /* -W--C */
-#define NV_PGRAPH_INTR_CONTEXT_SWITCH 12:12 /* RWIVF */
-#define NV_PGRAPH_INTR_CONTEXT_SWITCH_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_INTR_CONTEXT_SWITCH_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_INTR_CONTEXT_SWITCH_RESET 0x00000001 /* -W--C */
-#define NV_PGRAPH_INTR_BUFFER_NOTIFY 16:16 /* RWIVF */
-#define NV_PGRAPH_INTR_BUFFER_NOTIFY_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_INTR_BUFFER_NOTIFY_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_INTR_BUFFER_NOTIFY_RESET 0x00000001 /* -W--C */
-#define NV_PGRAPH_NSTATUS 0x00400104 /* RW-4R */
-#define NV_PGRAPH_NSTATUS_STATE_IN_USE 11:11 /* RWIVF */
-#define NV_PGRAPH_NSTATUS_STATE_IN_USE_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PGRAPH_NSTATUS_STATE_IN_USE_PENDING 0x00000001 /* RW--V */
-#define NV_PGRAPH_NSTATUS_INVALID_STATE 12:12 /* RWIVF */
-#define NV_PGRAPH_NSTATUS_INVALID_STATE_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PGRAPH_NSTATUS_INVALID_STATE_PENDING 0x00000001 /* RW--V */
-#define NV_PGRAPH_NSTATUS_BAD_ARGUMENT 13:13 /* RWIVF */
-#define NV_PGRAPH_NSTATUS_BAD_ARGUMENT_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PGRAPH_NSTATUS_BAD_ARGUMENT_PENDING 0x00000001 /* RW--V */
-#define NV_PGRAPH_NSTATUS_PROTECTION_FAULT 14:14 /* RWIVF */
-#define NV_PGRAPH_NSTATUS_PROTECTION_FAULT_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PGRAPH_NSTATUS_PROTECTION_FAULT_PENDING 0x00000001 /* RW--V */
-#define NV_PGRAPH_NSOURCE 0x00400108 /* R--4R */
-#define NV_PGRAPH_NSOURCE_NOTIFICATION 0:0 /* R-IVF */
-#define NV_PGRAPH_NSOURCE_NOTIFICATION_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_NSOURCE_NOTIFICATION_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_NSOURCE_DATA_ERROR 1:1 /* R-IVF */
-#define NV_PGRAPH_NSOURCE_DATA_ERROR_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_NSOURCE_DATA_ERROR_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_NSOURCE_PROTECTION_ERROR 2:2 /* R-IVF */
-#define NV_PGRAPH_NSOURCE_PROTECTION_ERROR_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_NSOURCE_PROTECTION_ERROR_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_NSOURCE_RANGE_EXCEPTION 3:3 /* R-IVF */
-#define NV_PGRAPH_NSOURCE_RANGE_EXCEPTION_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_NSOURCE_RANGE_EXCEPTION_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_NSOURCE_LIMIT_COLOR 4:4 /* R-IVF */
-#define NV_PGRAPH_NSOURCE_LIMIT_COLOR_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_NSOURCE_LIMIT_COLOR_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_NSOURCE_LIMIT_ZETA_ 5:5 /* R-IVF */
-#define NV_PGRAPH_NSOURCE_LIMIT_ZETA_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_NSOURCE_LIMIT_ZETA_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_NSOURCE_ILLEGAL_MTHD 6:6 /* R-IVF */
-#define NV_PGRAPH_NSOURCE_ILLEGAL_MTHD_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_NSOURCE_ILLEGAL_MTHD_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_NSOURCE_DMA_R_PROTECTION 7:7 /* R-IVF */
-#define NV_PGRAPH_NSOURCE_DMA_R_PROTECTION_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_NSOURCE_DMA_R_PROTECTION_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_NSOURCE_DMA_W_PROTECTION 8:8 /* R-IVF */
-#define NV_PGRAPH_NSOURCE_DMA_W_PROTECTION_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_NSOURCE_DMA_W_PROTECTION_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_NSOURCE_FORMAT_EXCEPTION 9:9 /* R-IVF */
-#define NV_PGRAPH_NSOURCE_FORMAT_EXCEPTION_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_NSOURCE_FORMAT_EXCEPTION_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_NSOURCE_PATCH_EXCEPTION 10:10 /* R-IVF */
-#define NV_PGRAPH_NSOURCE_PATCH_EXCEPTION_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_NSOURCE_PATCH_EXCEPTION_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_NSOURCE_STATE_INVALID 11:11 /* R-IVF */
-#define NV_PGRAPH_NSOURCE_STATE_INVALID_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_NSOURCE_STATE_INVALID_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_NSOURCE_DOUBLE_NOTIFY 12:12 /* R-IVF */
-#define NV_PGRAPH_NSOURCE_DOUBLE_NOTIFY_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_NSOURCE_DOUBLE_NOTIFY_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_NSOURCE_NOTIFY_IN_USE 13:13 /* R-IVF */
-#define NV_PGRAPH_NSOURCE_NOTIFY_IN_USE_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_NSOURCE_NOTIFY_IN_USE_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_NSOURCE_METHOD_CNT 14:14 /* R-IVF */
-#define NV_PGRAPH_NSOURCE_METHOD_CNT_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_NSOURCE_METHOD_CNT_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_NSOURCE_BFR_NOTIFICATION 15:15 /* R-IVF */
-#define NV_PGRAPH_NSOURCE_BFR_NOTIFICATION_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_NSOURCE_BFR_NOTIFICATION_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_INTR_EN 0x00400140 /* RW-4R */
-#define NV_PGRAPH_INTR_EN_NOTIFY 0:0 /* RWIVF */
-#define NV_PGRAPH_INTR_EN_NOTIFY_DISABLED 0x00000000 /* RWI-V */
-#define NV_PGRAPH_INTR_EN_NOTIFY_ENABLED 0x00000001 /* RW--V */
-#define NV_PGRAPH_INTR_EN_MISSING_HW 4:4 /* RWIVF */
-#define NV_PGRAPH_INTR_EN_MISSING_HW_DISABLED 0x00000000 /* RWI-V */
-#define NV_PGRAPH_INTR_EN_MISSING_HW_ENABLED 0x00000001 /* RW--V */
-#define NV_PGRAPH_INTR_EN_TLB_PRESENT_A 8:8 /* RWIVF */
-#define NV_PGRAPH_INTR_EN_TLB_PRESENT_A_DISABLED 0x00000000 /* RWI-V */
-#define NV_PGRAPH_INTR_EN_TLB_PRESENT_A_ENABLED 0x00000001 /* RW--V */
-#define NV_PGRAPH_INTR_EN_TLB_PRESENT_B 9:9 /* RWIVF */
-#define NV_PGRAPH_INTR_EN_TLB_PRESENT_B_DISABLED 0x00000000 /* RWI-V */
-#define NV_PGRAPH_INTR_EN_TLB_PRESENT_B_ENABLED 0x00000001 /* RW--V */
-#define NV_PGRAPH_INTR_EN_CONTEXT_SWITCH 12:12 /* RWIVF */
-#define NV_PGRAPH_INTR_EN_CONTEXT_SWITCH_DISABLED 0x00000000 /* RWI-V */
-#define NV_PGRAPH_INTR_EN_CONTEXT_SWITCH_ENABLED 0x00000001 /* RW--V */
-#define NV_PGRAPH_INTR_EN_BUFFER_NOTIFY 16:16 /* RWIVF */
-#define NV_PGRAPH_INTR_EN_BUFFER_NOTIFY_DISABLED 0x00000000 /* RWI-V */
-#define NV_PGRAPH_INTR_EN_BUFFER_NOTIFY_ENABLED 0x00000001 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1 0x00400160 /* RW-4R */
-#define NV_PGRAPH_CTX_SWITCH1_GRCLASS 7:0 /* RWXVF */
-#define NV_PGRAPH_CTX_SWITCH1_CHROMA_KEY 12:12 /* RWXUF */
-#define NV_PGRAPH_CTX_SWITCH1_CHROMA_KEY_DISABLE 0x00000000 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1_CHROMA_KEY_ENABLE 0x00000001 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1_USER_CLIP 13:13 /* RWXUF */
-#define NV_PGRAPH_CTX_SWITCH1_USER_CLIP_DISABLE 0x00000000 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1_USER_CLIP_ENABLE 0x00000001 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1_SWIZZLE 14:14 /* RWXUF */
-#define NV_PGRAPH_CTX_SWITCH1_SWIZZLE_DISABLE 0x00000000 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1_SWIZZLE_ENABLE 0x00000001 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG 17:15 /* RWXUF */
-#define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_SRCCOPY_AND 0x00000000 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_ROP_AND 0x00000001 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_BLEND_AND 0x00000002 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_SRCCOPY 0x00000003 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_SRCCOPY_PRE 0x00000004 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_BLEND_PRE 0x00000005 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1_PATCH_STATUS 24:24 /* RWXUF */
-#define NV_PGRAPH_CTX_SWITCH1_PATCH_STATUS_INVALID 0x00000000 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1_PATCH_STATUS_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1_CONTEXT_SURFACE 25:25 /* RWXUF */
-#define NV_PGRAPH_CTX_SWITCH1_CONTEXT_SURFACE_INVALID 0x00000000 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1_CONTEXT_SURFACE_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1_VOLATILE_RESET 31:31 /* CWIVF */
-#define NV_PGRAPH_CTX_SWITCH1_VOLATILE_RESET_IGNORE 0x00000000 /* CWI-V */
-#define NV_PGRAPH_CTX_SWITCH1_VOLATILE_RESET_ENABLED 0x00000001 /* -W--T */
-#define NV_PGRAPH_CTX_SWITCH2 0x00400164 /* RW-4R */
-#define NV_PGRAPH_CTX_SWITCH2_MONO_FORMAT 1:0 /* RWXUF */
-#define NV_PGRAPH_CTX_SWITCH2_MONO_FORMAT_INVALID 0x00 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_MONO_FORMAT_CGA6_M1 0x01 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_MONO_FORMAT_LE_M1 0x02 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT 13:8 /* RWXUF */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_INVALID 0x00 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_Y8 0x01 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X16A8Y8 0x02 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X24Y8 0x03 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_A1R5G5B5 0x06 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X1R5G5B5 0x07 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X16A1R5G5B5 0x08 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X17R5G5B5 0x09 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_R5G6B5 0x0A /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_A16R5G6B5 0x0B /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X16R5G6B5 0x0C /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_A8R8G8B8 0x0D /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X8R8G8B8 0x0E /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_Y16 0x0F /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_A16Y16 0x10 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X16Y16 0x11 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_V8YB8U8YA8 0x12 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_YB8V8YA8U8 0x13 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_Y32 0x14 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_NOTIFY_INSTANCE 31:16 /* RWXUF */
-#define NV_PGRAPH_CTX_SWITCH2_NOTIFY_INSTANCE_INVALID 0x0000 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH3 0x00400168 /* RW-4R */
-#define NV_PGRAPH_CTX_SWITCH3_DMA_INSTANCE_0 15:0 /* RWXUF */
-#define NV_PGRAPH_CTX_SWITCH3_DMA_INSTANCE_0_INVALID 0x0000 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH3_DMA_INSTANCE_1 31:16 /* RWXUF */
-#define NV_PGRAPH_CTX_SWITCH3_DMA_INSTANCE_1_INVALID 0x0000 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH4 0x0040016C /* RW-4R */
-#define NV_PGRAPH_CTX_SWITCH4_USER_INSTANCE 15:0 /* RWXUF */
-#define NV_PGRAPH_CTX_SWITCH4_USER_INSTANCE_INVALID 0x0000 /* RW--V */
-#define NV_PGRAPH_CTX_CACHE1(i) (0x00400180+(i)*4) /* RW-4A */
-#define NV_PGRAPH_CTX_CACHE1__SIZE_1 8 /* */
-#define NV_PGRAPH_CTX_CACHE1_GRCLASS 7:0 /* RWXVF */
-#define NV_PGRAPH_CTX_CACHE1_CHROMA_KEY 12:12 /* RWXVF */
-#define NV_PGRAPH_CTX_CACHE1_USER_CLIP 13:13 /* RWXVF */
-#define NV_PGRAPH_CTX_CACHE1_SWIZZLE 14:14 /* RWXVF */
-#define NV_PGRAPH_CTX_CACHE1_PATCH_CONFIG 19:15 /* RWXVF */
-#define NV_PGRAPH_CTX_CACHE1_SPARE1 20:20 /* RWXVF */
-#define NV_PGRAPH_CTX_CACHE1_PATCH_STATUS 24:24 /* RWXVF */
-#define NV_PGRAPH_CTX_CACHE1_CONTEXT_SURFACE 25:25 /* RWXVF */
-#define NV_PGRAPH_CTX_CACHE2(i) (0x004001a0+(i)*4) /* RW-4A */
-#define NV_PGRAPH_CTX_CACHE2__SIZE_1 8 /* */
-#define NV_PGRAPH_CTX_CACHE2_MONO_FORMAT 1:0 /* RWXVF */
-#define NV_PGRAPH_CTX_CACHE2_COLOR_FORMAT 13:8 /* RWXVF */
-#define NV_PGRAPH_CTX_CACHE2_NOTIFY_INSTANCE 31:16 /* RWXVF */
-#define NV_PGRAPH_CTX_CACHE3(i) (0x004001c0+(i)*4) /* RW-4A */
-#define NV_PGRAPH_CTX_CACHE3__SIZE_1 8 /* */
-#define NV_PGRAPH_CTX_CACHE3_DMA_INSTANCE_0 15:0 /* RWXVF */
-#define NV_PGRAPH_CTX_CACHE3_DMA_INSTANCE_1 31:16 /* RWXVF */
-#define NV_PGRAPH_CTX_CACHE4(i) (0x004001e0+(i)*4) /* RW-4A */
-#define NV_PGRAPH_CTX_CACHE4__SIZE_1 8 /* */
-#define NV_PGRAPH_CTX_CACHE4_USER_INSTANCE 15:0 /* RWXVF */
-#define NV_PGRAPH_CTX_CONTROL 0x00400170 /* RW-4R */
-#define NV_PGRAPH_CTX_CONTROL_MINIMUM_TIME 1:0 /* RWIVF */
-#define NV_PGRAPH_CTX_CONTROL_MINIMUM_TIME_33US 0x00000000 /* RWI-V */
-#define NV_PGRAPH_CTX_CONTROL_MINIMUM_TIME_262US 0x00000001 /* RW--V */
-#define NV_PGRAPH_CTX_CONTROL_MINIMUM_TIME_2MS 0x00000002 /* RW--V */
-#define NV_PGRAPH_CTX_CONTROL_MINIMUM_TIME_17MS 0x00000003 /* RW--V */
-#define NV_PGRAPH_CTX_CONTROL_TIME 8:8 /* RWIVF */
-#define NV_PGRAPH_CTX_CONTROL_TIME_EXPIRED 0x00000000 /* RWI-V */
-#define NV_PGRAPH_CTX_CONTROL_TIME_NOT_EXPIRED 0x00000001 /* RW--V */
-#define NV_PGRAPH_CTX_CONTROL_CHID 16:16 /* RWIVF */
-#define NV_PGRAPH_CTX_CONTROL_CHID_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_CTX_CONTROL_CHID_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_CTX_CONTROL_CHANGE 20:20 /* R--VF */
-#define NV_PGRAPH_CTX_CONTROL_CHANGE_UNAVAILABLE 0x00000000 /* R---V */
-#define NV_PGRAPH_CTX_CONTROL_CHANGE_AVAILABLE 0x00000001 /* R---V */
-#define NV_PGRAPH_CTX_CONTROL_SWITCHING 24:24 /* RWIVF */
-#define NV_PGRAPH_CTX_CONTROL_SWITCHING_IDLE 0x00000000 /* RWI-V */
-#define NV_PGRAPH_CTX_CONTROL_SWITCHING_BUSY 0x00000001 /* RW--V */
-#define NV_PGRAPH_CTX_CONTROL_DEVICE 28:28 /* RWIVF */
-#define NV_PGRAPH_CTX_CONTROL_DEVICE_DISABLED 0x00000000 /* RWI-V */
-#define NV_PGRAPH_CTX_CONTROL_DEVICE_ENABLED 0x00000001 /* RW--V */
-#define NV_PGRAPH_CTX_USER 0x00400174 /* RW-4R */
-#define NV_PGRAPH_CTX_USER_SUBCH 15:13 /* RWIVF */
-#define NV_PGRAPH_CTX_USER_SUBCH_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_CTX_USER_CHID 27:24 /* RWIVF */
-#define NV_PGRAPH_CTX_USER_CHID_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_FIFO 0x00400720 /* RW-4R */
-#define NV_PGRAPH_FIFO_ACCESS 0:0 /* RWIVF */
-#define NV_PGRAPH_FIFO_ACCESS_DISABLED 0x00000000 /* RW--V */
-#define NV_PGRAPH_FIFO_ACCESS_ENABLED 0x00000001 /* RWI-V */
-#define NV_PGRAPH_FFINTFC_FIFO_0(i) (0x00400730+(i)*4) /* RW-4A */
-#define NV_PGRAPH_FFINTFC_FIFO_0__SIZE_1 4 /* */
-#define NV_PGRAPH_FFINTFC_FIFO_0_TAG 0:0 /* RWXVF */
-#define NV_PGRAPH_FFINTFC_FIFO_0_TAG_MTHD 0x00000000 /* RW--V */
-#define NV_PGRAPH_FFINTFC_FIFO_0_TAG_CHSW 0x00000001 /* RW--V */
-#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH 3:1 /* RWXVF */
-#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_0 0x00000000 /* RW--V */
-#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_1 0x00000001 /* RW--V */
-#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_2 0x00000002 /* RW--V */
-#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_3 0x00000003 /* RW--V */
-#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_4 0x00000004 /* RW--V */
-#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_5 0x00000005 /* RW--V */
-#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_6 0x00000006 /* RW--V */
-#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_7 0x00000007 /* RW--V */
-#define NV_PGRAPH_FFINTFC_FIFO_0_MTHD 14:4 /* RWXVF */
-#define NV_PGRAPH_FFINTFC_FIFO_0_MTHD_CTX_SWITCH 0x00000000 /* RW--V */
-#define NV_PGRAPH_FFINTFC_FIFO_1(i) (0x00400740+(i)*4) /* RW-4A */
-#define NV_PGRAPH_FFINTFC_FIFO_1__SIZE_1 4 /* */
-#define NV_PGRAPH_FFINTFC_FIFO_1_ARGUMENT 31:0 /* RWXVF */
-#define NV_PGRAPH_FFINTFC_FIFO_PTR 0x00400750 /* RW-4R */
-#define NV_PGRAPH_FFINTFC_FIFO_PTR_WRITE 2:0 /* RWIVF */
-#define NV_PGRAPH_FFINTFC_FIFO_PTR_WRITE_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_FFINTFC_FIFO_PTR_READ 6:4 /* RWIVF */
-#define NV_PGRAPH_FFINTFC_FIFO_PTR_READ_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_FFINTFC_ST2 0x00400754 /* RW-4R */
-#define NV_PGRAPH_FFINTFC_ST2_STATUS 0:0 /* RWIVF */
-#define NV_PGRAPH_FFINTFC_ST2_STATUS_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_FFINTFC_ST2_STATUS_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_MTHD 11:1 /* RWIVF */
-#define NV_PGRAPH_FFINTFC_ST2_MTHD_CTX_SWITCH 0x00000000 /* RWI-V */
-#define NV_PGRAPH_FFINTFC_ST2_SUBCH 14:12 /* RWIVF */
-#define NV_PGRAPH_FFINTFC_ST2_SUBCH_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_FFINTFC_ST2_SUBCH_1 0x00000001 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_SUBCH_2 0x00000002 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_SUBCH_3 0x00000003 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_SUBCH_4 0x00000004 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_SUBCH_5 0x00000005 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_SUBCH_6 0x00000006 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_SUBCH_7 0x00000007 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID 18:15 /* RWIVF */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_1 0x00000001 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_2 0x00000002 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_3 0x00000003 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_4 0x00000004 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_5 0x00000005 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_6 0x00000006 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_7 0x00000007 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_8 0x00000008 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_9 0x00000009 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_10 0x0000000A /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_11 0x0000000B /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_12 0x0000000C /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_13 0x0000000D /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_14 0x0000000E /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_15 0x0000000F /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_STATUS 19:19 /* RWIVF */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_STATUS_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_STATUS_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_D 0x00400758 /* RW-4R */
-#define NV_PGRAPH_FFINTFC_ST2_D_ARGUMENT 31:0 /* RWIVF */
-#define NV_PGRAPH_FFINTFC_ST2_D_ARGUMENT_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATUS 0x00400700 /* R--4R */
-#define NV_PGRAPH_STATUS_STATE 0:0 /* R-IVF */
-#define NV_PGRAPH_STATUS_STATE_IDLE 0x00000000 /* R-I-V */
-#define NV_PGRAPH_STATUS_STATE_BUSY 0x00000001 /* R---V */
-#define NV_PGRAPH_STATUS_XY_LOGIC 4:4 /* R-IVF */
-#define NV_PGRAPH_STATUS_XY_LOGIC_IDLE 0x00000000 /* R-I-V */
-#define NV_PGRAPH_STATUS_XY_LOGIC_BUSY 0x00000001 /* R---V */
-#define NV_PGRAPH_STATUS_FE 5:5 /* R-IVF */
-#define NV_PGRAPH_STATUS_FE_IDLE 0x00000000 /* R-I-V */
-#define NV_PGRAPH_STATUS_FE_BUSY 0x00000001 /* R---V */
-#define NV_PGRAPH_STATUS_RASTERIZER 6:6 /* R-IVF */
-#define NV_PGRAPH_STATUS_RASTERIZER_IDLE 0x00000000 /* R-I-V */
-#define NV_PGRAPH_STATUS_RASTERIZER_BUSY 0x00000001 /* R---V */
-#define NV_PGRAPH_STATUS_PORT_NOTIFY 8:8 /* R-IVF */
-#define NV_PGRAPH_STATUS_PORT_NOTIFY_IDLE 0x00000000 /* R-I-V */
-#define NV_PGRAPH_STATUS_PORT_NOTIFY_BUSY 0x00000001 /* R---V */
-#define NV_PGRAPH_STATUS_PORT_REGISTER 12:12 /* R-IVF */
-#define NV_PGRAPH_STATUS_PORT_REGISTER_IDLE 0x00000000 /* R-I-V */
-#define NV_PGRAPH_STATUS_PORT_REGISTER_BUSY 0x00000001 /* R---V */
-#define NV_PGRAPH_STATUS_PORT_DMA 16:16 /* R-IVF */
-#define NV_PGRAPH_STATUS_PORT_DMA_IDLE 0x00000000 /* R-I-V */
-#define NV_PGRAPH_STATUS_PORT_DMA_BUSY 0x00000001 /* R---V */
-#define NV_PGRAPH_STATUS_DMA_ENGINE 17:17 /* R-IVF */
-#define NV_PGRAPH_STATUS_DMA_ENGINE_IDLE 0x00000000 /* R-I-V */
-#define NV_PGRAPH_STATUS_DMA_ENGINE_BUSY 0x00000001 /* R---V */
-#define NV_PGRAPH_STATUS_DMA_NOTIFY 20:20 /* R-IVF */
-#define NV_PGRAPH_STATUS_DMA_NOTIFY_IDLE 0x00000000 /* R-I-V */
-#define NV_PGRAPH_STATUS_DMA_NOTIFY_BUSY 0x00000001 /* R---V */
-#define NV_PGRAPH_STATUS_DMA_BUFFER_NOTIFY 21:21 /* R-IVF */
-#define NV_PGRAPH_STATUS_DMA_BUFFER_NOTIFY_IDLE 0x00000000 /* R-I-V */
-#define NV_PGRAPH_STATUS_DMA_BUFFER_NOTIFY_BUSY 0x00000001 /* R---V */
-#define NV_PGRAPH_STATUS_D3D 24:24 /* R-IVF */
-#define NV_PGRAPH_STATUS_D3D_IDLE 0x00000000 /* R-I-V */
-#define NV_PGRAPH_STATUS_D3D_BUSY 0x00000001 /* R---V */
-#define NV_PGRAPH_STATUS_CACHE 25:25 /* R-IVF */
-#define NV_PGRAPH_STATUS_CACHE_IDLE 0x00000000 /* R-I-V */
-#define NV_PGRAPH_STATUS_CACHE_BUSY 0x00000001 /* R---V */
-#define NV_PGRAPH_STATUS_LIGHTING 26:26 /* R-IVF */
-#define NV_PGRAPH_STATUS_LIGHTING_IDLE 0x00000000 /* R-I-V */
-#define NV_PGRAPH_STATUS_LIGHTING_BUSY 0x00000001 /* R---V */
-#define NV_PGRAPH_STATUS_PREROP 27:27 /* R-IVF */
-#define NV_PGRAPH_STATUS_PREROP_IDLE 0x00000000 /* R-I-V */
-#define NV_PGRAPH_STATUS_PREROP_BUSY 0x00000001 /* R---V */
-#define NV_PGRAPH_STATUS_ROP 28:28 /* R-IVF */
-#define NV_PGRAPH_STATUS_ROP_IDLE 0x00000000 /* R-I-V */
-#define NV_PGRAPH_STATUS_ROP_BUSY 0x00000001 /* R---V */
-#define NV_PGRAPH_STATUS_PORT_USER 29:29 /* R-IVF */
-#define NV_PGRAPH_STATUS_PORT_USER_IDLE 0x00000000 /* R-I-V */
-#define NV_PGRAPH_STATUS_PORT_USER_BUSY 0x00000001 /* R---V */
-#define NV_PGRAPH_TRAPPED_ADDR 0x00400704 /* R--4R */
-#define NV_PGRAPH_TRAPPED_ADDR_MTHD 12:2 /* R-XUF */
-#define NV_PGRAPH_TRAPPED_ADDR_SUBCH 15:13 /* R-XUF */
-#define NV_PGRAPH_TRAPPED_ADDR_CHID 27:24 /* R-XUF */
-#define NV_PGRAPH_TRAPPED_DATA 0x00400708 /* R--4R */
-#define NV_PGRAPH_TRAPPED_DATA_VALUE 31:0 /* R-XVF */
-#define NV_PGRAPH_SURFACE 0x0040070C /* RW-4R */
-#define NV_PGRAPH_SURFACE_TYPE 1:0 /* RWIVF */
-#define NV_PGRAPH_SURFACE_TYPE_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_SURFACE_TYPE_NON_SWIZZLE 0x00000001 /* RW--V */
-#define NV_PGRAPH_SURFACE_TYPE_SWIZZLE 0x00000002 /* RW--V */
-#define NV_PGRAPH_NOTIFY 0x00400714 /* RW-4R */
-#define NV_PGRAPH_NOTIFY_BUFFER_REQ 0:0 /* RWIVF */
-#define NV_PGRAPH_NOTIFY_BUFFER_REQ_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PGRAPH_NOTIFY_BUFFER_REQ_PENDING 0x00000001 /* RW--V */
-#define NV_PGRAPH_NOTIFY_BUFFER_STYLE 8:8 /* RWIVF */
-#define NV_PGRAPH_NOTIFY_BUFFER_STYLE_WRITE_ONLY 0x00000000 /* RWI-V */
-#define NV_PGRAPH_NOTIFY_BUFFER_STYLE_WRITE_THEN_AWAKEN 0x00000001 /* RW--V */
-#define NV_PGRAPH_NOTIFY_REQ 16:16 /* RWIVF */
-#define NV_PGRAPH_NOTIFY_REQ_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PGRAPH_NOTIFY_REQ_PENDING 0x00000001 /* RW--V */
-#define NV_PGRAPH_NOTIFY_STYLE 20:20 /* RWIVF */
-#define NV_PGRAPH_NOTIFY_STYLE_WRITE_ONLY 0x00000000 /* RWI-V */
-#define NV_PGRAPH_NOTIFY_STYLE_WRITE_THEN_AWAKEN 0x00000001 /* RW--V */
-#define NV_PGRAPH_BOFFSET(i) (0x00400640+(i)*4) /* RW-4A */
-#define NV_PGRAPH_BOFFSET__SIZE_1 6 /* */
-#define NV_PGRAPH_BOFFSET_LINADRS 23:0 /* RWIUF */
-#define NV_PGRAPH_BOFFSET_LINADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BOFFSET0 0x00400640 /* RW-4R */
-#define NV_PGRAPH_BOFFSET0__ALIAS_1 NV_PGRAPH_BOFFSET(0) /* */
-#define NV_PGRAPH_BOFFSET0_LINADRS 23:0 /* RWIUF */
-#define NV_PGRAPH_BOFFSET0_LINADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BOFFSET1 0x00400644 /* RW-4R */
-#define NV_PGRAPH_BOFFSET1__ALIAS_1 NV_PGRAPH_BOFFSET(1) /* */
-#define NV_PGRAPH_BOFFSET1_LINADRS 23:0 /* RWIUF */
-#define NV_PGRAPH_BOFFSET1_LINADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BOFFSET2 0x00400648 /* RW-4R */
-#define NV_PGRAPH_BOFFSET2__ALIAS_1 NV_PGRAPH_BOFFSET(2) /* */
-#define NV_PGRAPH_BOFFSET2_LINADRS 23:0 /* RWIUF */
-#define NV_PGRAPH_BOFFSET2_LINADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BOFFSET3 0x0040064C /* RW-4R */
-#define NV_PGRAPH_BOFFSET3__ALIAS_1 NV_PGRAPH_BOFFSET(3) /* */
-#define NV_PGRAPH_BOFFSET3_LINADRS 23:0 /* RWIUF */
-#define NV_PGRAPH_BOFFSET3_LINADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BOFFSET4 0x00400650 /* RW-4R */
-#define NV_PGRAPH_BOFFSET4__ALIAS_1 NV_PGRAPH_BOFFSET(4) /* */
-#define NV_PGRAPH_BOFFSET4_LINADRS 23:0 /* RWIUF */
-#define NV_PGRAPH_BOFFSET4_LINADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BOFFSET5 0x00400654 /* RW-4R */
-#define NV_PGRAPH_BOFFSET5__ALIAS_1 NV_PGRAPH_BOFFSET(5) /* */
-#define NV_PGRAPH_BOFFSET5_LINADRS 23:0 /* RWIUF */
-#define NV_PGRAPH_BOFFSET5_LINADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BBASE(i) (0x00400658+(i)*4) /* RW-4A */
-#define NV_PGRAPH_BBASE__SIZE_1 6 /* */
-#define NV_PGRAPH_BBASE_LINADRS 23:0 /* RWIUF */
-#define NV_PGRAPH_BBASE_LINADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BBASE0 0x00400658 /* RW-4R */
-#define NV_PGRAPH_BBASE0__ALIAS_1 NV_PGRAPH_BBASE(0) /* */
-#define NV_PGRAPH_BBASE0_LINADRS 23:0 /* RWIUF */
-#define NV_PGRAPH_BBASE0_LINADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BBASE1 0x0040065c /* RW-4R */
-#define NV_PGRAPH_BBASE1__ALIAS_1 NV_PGRAPH_BBASE(1) /* */
-#define NV_PGRAPH_BBASE1_LINADRS 23:0 /* RWIUF */
-#define NV_PGRAPH_BBASE1_LINADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BBASE2 0x00400660 /* RW-4R */
-#define NV_PGRAPH_BBASE2__ALIAS_1 NV_PGRAPH_BBASE(2) /* */
-#define NV_PGRAPH_BBASE2_LINADRS 23:0 /* RWIUF */
-#define NV_PGRAPH_BBASE2_LINADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BBASE3 0x00400664 /* RW-4R */
-#define NV_PGRAPH_BBASE3__ALIAS_1 NV_PGRAPH_BBASE(3) /* */
-#define NV_PGRAPH_BBASE3_LINADRS 23:0 /* RWIUF */
-#define NV_PGRAPH_BBASE3_LINADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BBASE4 0x00400668 /* RW-4R */
-#define NV_PGRAPH_BBASE4__ALIAS_1 NV_PGRAPH_BBASE(4) /* */
-#define NV_PGRAPH_BBASE4_LINADRS 23:0 /* RWIUF */
-#define NV_PGRAPH_BBASE4_LINADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BBASE5 0x0040066C /* RW-4R */
-#define NV_PGRAPH_BBASE5__ALIAS_1 NV_PGRAPH_BBASE(5) /* */
-#define NV_PGRAPH_BBASE5_LINADRS 23:0 /* RWIUF */
-#define NV_PGRAPH_BBASE5_LINADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BPITCH(i) (0x00400670+(i)*4) /* RW-4A */
-#define NV_PGRAPH_BPITCH__SIZE_1 5 /* */
-#define NV_PGRAPH_BPITCH_VALUE 12:0 /* RWIUF */
-#define NV_PGRAPH_BPITCH_VALUE_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BPITCH0 0x00400670 /* RW-4R */
-#define NV_PGRAPH_BPITCH0__ALIAS_1 NV_PGRAPH_BPITCH(0) /* */
-#define NV_PGRAPH_BPITCH0_VALUE 12:0 /* RWIUF */
-#define NV_PGRAPH_BPITCH0_VALUE_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BPITCH1 0x00400674 /* RW-4R */
-#define NV_PGRAPH_BPITCH1__ALIAS_1 NV_PGRAPH_BPITCH(1) /* */
-#define NV_PGRAPH_BPITCH1_VALUE 12:0 /* RWIUF */
-#define NV_PGRAPH_BPITCH1_VALUE_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BPITCH2 0x00400678 /* RW-4R */
-#define NV_PGRAPH_BPITCH2__ALIAS_1 NV_PGRAPH_BPITCH(2) /* */
-#define NV_PGRAPH_BPITCH2_VALUE 12:0 /* RWIUF */
-#define NV_PGRAPH_BPITCH2_VALUE_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BPITCH3 0x0040067C /* RW-4R */
-#define NV_PGRAPH_BPITCH3__ALIAS_1 NV_PGRAPH_BPITCH(3) /* */
-#define NV_PGRAPH_BPITCH3_VALUE 12:0 /* RWIUF */
-#define NV_PGRAPH_BPITCH3_VALUE_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BPITCH4 0x00400680 /* RW-4R */
-#define NV_PGRAPH_BPITCH4__ALIAS_1 NV_PGRAPH_BPITCH(4) /* */
-#define NV_PGRAPH_BPITCH4_VALUE 12:0 /* RWIUF */
-#define NV_PGRAPH_BPITCH4_VALUE_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BLIMIT(i) (0x00400684+(i)*4) /* RW-4A */
-#define NV_PGRAPH_BLIMIT__SIZE_1 6 /* */
-#define NV_PGRAPH_BLIMIT_VALUE 23:0 /* RWXUF */
-#define NV_PGRAPH_BLIMIT_TYPE 31:31 /* RWIVF */
-#define NV_PGRAPH_BLIMIT_TYPE_IN_MEMORY 0x00000000 /* RW--V */
-#define NV_PGRAPH_BLIMIT_TYPE_NULL 0x00000001 /* RWI-V */
-#define NV_PGRAPH_BLIMIT0 0x00400684 /* RW-4R */
-#define NV_PGRAPH_BLIMIT0__ALIAS_1 NV_PGRAPH_BLIMIT(0) /* */
-#define NV_PGRAPH_BLIMIT0_VALUE 23:0 /* RWXUF */
-#define NV_PGRAPH_BLIMIT0_TYPE 31:31 /* RWIVF */
-#define NV_PGRAPH_BLIMIT0_TYPE_IN_MEMORY 0x00000000 /* RW--V */
-#define NV_PGRAPH_BLIMIT0_TYPE_NULL 0x00000001 /* RWI-V */
-#define NV_PGRAPH_BLIMIT1 0x00400688 /* RW-4R */
-#define NV_PGRAPH_BLIMIT1__ALIAS_1 NV_PGRAPH_BLIMIT(1) /* */
-#define NV_PGRAPH_BLIMIT1_VALUE 23:0 /* RWXUF */
-#define NV_PGRAPH_BLIMIT1_TYPE 31:31 /* RWIVF */
-#define NV_PGRAPH_BLIMIT1_TYPE_IN_MEMORY 0x00000000 /* RW--V */
-#define NV_PGRAPH_BLIMIT1_TYPE_NULL 0x00000001 /* RWI-V */
-#define NV_PGRAPH_BLIMIT2 0x0040068c /* RW-4R */
-#define NV_PGRAPH_BLIMIT2__ALIAS_1 NV_PGRAPH_BLIMIT(2) /* */
-#define NV_PGRAPH_BLIMIT2_VALUE 23:0 /* RWXUF */
-#define NV_PGRAPH_BLIMIT2_TYPE 31:31 /* RWIVF */
-#define NV_PGRAPH_BLIMIT2_TYPE_IN_MEMORY 0x00000000 /* RW--V */
-#define NV_PGRAPH_BLIMIT2_TYPE_NULL 0x00000001 /* RWI-V */
-#define NV_PGRAPH_BLIMIT3 0x00400690 /* RW-4R */
-#define NV_PGRAPH_BLIMIT3__ALIAS_1 NV_PGRAPH_BLIMIT(3) /* */
-#define NV_PGRAPH_BLIMIT3_VALUE 23:0 /* RWXUF */
-#define NV_PGRAPH_BLIMIT3_TYPE 31:31 /* RWIVF */
-#define NV_PGRAPH_BLIMIT3_TYPE_IN_MEMORY 0x00000000 /* RW--V */
-#define NV_PGRAPH_BLIMIT3_TYPE_NULL 0x00000001 /* RWI-V */
-#define NV_PGRAPH_BLIMIT4 0x00400694 /* RW-4R */
-#define NV_PGRAPH_BLIMIT4__ALIAS_1 NV_PGRAPH_BLIMIT(4) /* */
-#define NV_PGRAPH_BLIMIT4_VALUE 23:0 /* RWXUF */
-#define NV_PGRAPH_BLIMIT4_TYPE 31:31 /* RWIVF */
-#define NV_PGRAPH_BLIMIT4_TYPE_IN_MEMORY 0x00000000 /* RW--V */
-#define NV_PGRAPH_BLIMIT4_TYPE_NULL 0x00000001 /* RWI-V */
-#define NV_PGRAPH_BLIMIT5 0x00400698 /* RW-4R */
-#define NV_PGRAPH_BLIMIT5__ALIAS_1 NV_PGRAPH_BLIMIT(5) /* */
-#define NV_PGRAPH_BLIMIT5_VALUE 23:0 /* RWXUF */
-#define NV_PGRAPH_BLIMIT5_TYPE 31:31 /* RWIVF */
-#define NV_PGRAPH_BLIMIT5_TYPE_IN_MEMORY 0x00000000 /* RW--V */
-#define NV_PGRAPH_BLIMIT5_TYPE_NULL 0x00000001 /* RWI-V */
-#define NV_PGRAPH_BSWIZZLE2 0x0040069c /* RW-4R */
-#define NV_PGRAPH_BSWIZZLE2_WIDTH 19:16 /* RWIUF */
-#define NV_PGRAPH_BSWIZZLE2_WIDTH_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BSWIZZLE2_HEIGHT 27:24 /* RWIUF */
-#define NV_PGRAPH_BSWIZZLE2_HEIGHT_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BSWIZZLE5 0x004006a0 /* RW-4R */
-#define NV_PGRAPH_BSWIZZLE5_WIDTH 19:16 /* RWIUF */
-#define NV_PGRAPH_BSWIZZLE5_WIDTH_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BSWIZZLE5_HEIGHT 27:24 /* RWIUF */
-#define NV_PGRAPH_BSWIZZLE5_HEIGHT_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BPIXEL 0x00400724 /* RW-4R */
-#define NV_PGRAPH_BPIXEL_DEPTH0 3:0 /* RWIVF */
-#define NV_PGRAPH_BPIXEL_DEPTH0_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BPIXEL_DEPTH0_Y8 0x00000001 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH0_X1R5G5B5_Z1R5G5B5 0x00000002 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH0_X1R5G5B5_O1R5G5B5 0x00000003 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH0_A1R5G5B5 0x00000004 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH0_R5G6B5 0x00000005 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH0_Y16 0x00000006 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH0_X8R8G8B8_Z8R8G8B8 0x00000007 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH0_X8R8G8B8_O1Z7R8G8B8 0x00000008 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH0_X1A7R8G8B8_Z1A7R8G8B8 0x00000009 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH0_X1A7R8G8B8_O1A7R8G8B8 0x0000000a /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH0_X8R8G8B8_O8R8G8B8 0x0000000b /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH0_A8R8G8B8 0x0000000c /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH0_Y32 0x0000000d /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH0_V8YB8U8YA8 0x0000000e /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH0_YB8V8YA8U8 0x0000000f /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH1 7:4 /* RWIVF */
-#define NV_PGRAPH_BPIXEL_DEPTH1_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BPIXEL_DEPTH1_Y8 0x00000001 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH1_X1R5G5B5_Z1R5G5B5 0x00000002 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH1_X1R5G5B5_O1R5G5B5 0x00000003 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH1_A1R5G5B5 0x00000004 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH1_R5G6B5 0x00000005 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH1_Y16 0x00000006 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH1_X8R8G8B8_Z8R8G8B8 0x00000007 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH1_X8R8G8B8_O1Z7R8G8B8 0x00000008 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH1_X1A7R8G8B8_Z1A7R8G8B8 0x00000009 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH1_X1A7R8G8B8_O1A7R8G8B8 0x0000000a /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH1_X8R8G8B8_O8R8G8B8 0x0000000b /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH1_A8R8G8B8 0x0000000c /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH1_Y32 0x0000000d /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH1_V8YB8U8YA8 0x0000000e /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH1_YB8V8YA8U8 0x0000000f /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH2 11:8 /* RWIVF */
-#define NV_PGRAPH_BPIXEL_DEPTH2_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BPIXEL_DEPTH2_Y8 0x00000001 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH2_X1R5G5B5_Z1R5G5B5 0x00000002 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH2_X1R5G5B5_O1R5G5B5 0x00000003 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH2_A1R5G5B5 0x00000004 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH2_R5G6B5 0x00000005 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH2_Y16 0x00000006 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH2_X8R8G8B8_Z8R8G8B8 0x00000007 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH2_X8R8G8B8_O1Z7R8G8B8 0x00000008 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH2_X1A7R8G8B8_Z1A7R8G8B8 0x00000009 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH2_X1A7R8G8B8_O1A7R8G8B8 0x0000000a /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH2_X8R8G8B8_O8R8G8B8 0x0000000b /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH2_A8R8G8B8 0x0000000c /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH2_Y32 0x0000000d /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH2_V8YB8U8YA8 0x0000000e /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH2_YB8V8YA8U8 0x0000000f /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH3 15:12 /* RWIVF */
-#define NV_PGRAPH_BPIXEL_DEPTH3_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BPIXEL_DEPTH3_Y8 0x00000001 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH3_X1R5G5B5_Z1R5G5B5 0x00000002 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH3_X1R5G5B5_O1R5G5B5 0x00000003 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH3_A1R5G5B5 0x00000004 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH3_R5G6B5 0x00000005 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH3_Y16 0x00000006 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH3_X8R8G8B8_Z8R8G8B8 0x00000007 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH3_X8R8G8B8_O1Z7R8G8B8 0x00000008 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH3_X1A7R8G8B8_Z1A7R8G8B8 0x00000009 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH3_X1A7R8G8B8_O1A7R8G8B8 0x0000000a /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH3_X8R8G8B8_O8R8G8B8 0x0000000b /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH3_A8R8G8B8 0x0000000c /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH3_Y32 0x0000000d /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH3_V8YB8U8YA8 0x0000000e /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH3_YB8V8YA8U8 0x0000000f /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH4 19:16 /* RWIVF */
-#define NV_PGRAPH_BPIXEL_DEPTH4_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BPIXEL_DEPTH4_Y8 0x00000001 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH4_X1R5G5B5_Z1R5G5B5 0x00000002 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH4_X1R5G5B5_O1R5G5B5 0x00000003 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH4_A1R5G5B5 0x00000004 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH4_R5G6B5 0x00000005 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH4_Y16 0x00000006 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH4_X8R8G8B8_Z8R8G8B8 0x00000007 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH4_X8R8G8B8_O1Z7R8G8B8 0x00000008 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH4_X1A7R8G8B8_Z1A7R8G8B8 0x00000009 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH4_X1A7R8G8B8_O1A7R8G8B8 0x0000000a /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH4_X8R8G8B8_O8R8G8B8 0x0000000b /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH4_A8R8G8B8 0x0000000c /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH4_Y32 0x0000000d /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH4_V8YB8U8YA8 0x0000000e /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH4_YB8V8YA8U8 0x0000000f /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH5 23:20 /* RWIVF */
-#define NV_PGRAPH_BPIXEL_DEPTH5_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BPIXEL_DEPTH5_Y8 0x00000001 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH5_X1R5G5B5_Z1R5G5B5 0x00000002 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH5_X1R5G5B5_O1R5G5B5 0x00000003 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH5_A1R5G5B5 0x00000004 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH5_R5G6B5 0x00000005 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH5_Y16 0x00000006 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH5_X8R8G8B8_Z8R8G8B8 0x00000007 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH5_X8R8G8B8_O1Z7R8G8B8 0x00000008 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH5_X1A7R8G8B8_Z1A7R8G8B8 0x00000009 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH5_X1A7R8G8B8_O1A7R8G8B8 0x0000000a /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH5_X8R8G8B8_O8R8G8B8 0x0000000b /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH5_A8R8G8B8 0x0000000c /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH5_Y32 0x0000000d /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH5_V8YB8U8YA8 0x0000000e /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH5_YB8V8YA8U8 0x0000000f /* RW--V */
-#define NV_PGRAPH_LIMIT_VIOL_PIX 0x00400610 /* RW-4R */
-#define NV_PGRAPH_LIMIT_VIOL_PIX_ADRS 23:0 /* RWIVF */
-#define NV_PGRAPH_LIMIT_VIOL_PIX_ADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_LIMIT_VIOL_PIX_BLIT 29:29 /* RWIVF */
-#define NV_PGRAPH_LIMIT_VIOL_PIX_BLIT_NO_VIOL 0x00000000 /* RWI-V */
-#define NV_PGRAPH_LIMIT_VIOL_PIX_BLIT_VIOL 0x00000001 /* RW--V */
-#define NV_PGRAPH_LIMIT_VIOL_PIX_LIMIT 30:30 /* RWIVF */
-#define NV_PGRAPH_LIMIT_VIOL_PIX_LIMIT_NO_VIOL 0x00000000 /* RWI-V */
-#define NV_PGRAPH_LIMIT_VIOL_PIX_LIMIT_VIOL 0x00000001 /* RW--V */
-#define NV_PGRAPH_LIMIT_VIOL_PIX_OVRFLW 31:31 /* RWIVF */
-#define NV_PGRAPH_LIMIT_VIOL_PIX_OVRFLW_NO_VIOL 0x00000000 /* RWI-V */
-#define NV_PGRAPH_LIMIT_VIOL_PIX_OVRFLW_VIOL 0x00000001 /* RW--V */
-#define NV_PGRAPH_LIMIT_VIOL_Z 0x00400614 /* RW-4R */
-#define NV_PGRAPH_LIMIT_VIOL_Z_ADRS 23:0 /* RWIVF */
-#define NV_PGRAPH_LIMIT_VIOL_Z_ADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_LIMIT_VIOL_Z_LIMIT 30:30 /* RWIVF */
-#define NV_PGRAPH_LIMIT_VIOL_Z_LIMIT_NO_VIOL 0x00000000 /* RWI-V */
-#define NV_PGRAPH_LIMIT_VIOL_Z_LIMIT_VIOL 0x00000001 /* RW--V */
-#define NV_PGRAPH_LIMIT_VIOL_Z_OVRFLW 31:31 /* RWIVF */
-#define NV_PGRAPH_LIMIT_VIOL_Z_OVRFLW_NO_VIOL 0x00000000 /* RWI-V */
-#define NV_PGRAPH_LIMIT_VIOL_Z_OVRFLW_VIOL 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE 0x00400710 /* RW-4R */
-#define NV_PGRAPH_STATE_BUFFER_0 0:0 /* RWIVF */
-#define NV_PGRAPH_STATE_BUFFER_0_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_BUFFER_0_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_BUFFER_1 1:1 /* RWIVF */
-#define NV_PGRAPH_STATE_BUFFER_1_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_BUFFER_1_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_BUFFER_2 2:2 /* RWIVF */
-#define NV_PGRAPH_STATE_BUFFER_2_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_BUFFER_2_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_BUFFER_3 3:3 /* RWIVF */
-#define NV_PGRAPH_STATE_BUFFER_3_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_BUFFER_3_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_BUFFER_4 4:4 /* RWIVF */
-#define NV_PGRAPH_STATE_BUFFER_4_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_BUFFER_4_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_BUFFER_5 5:5 /* RWIVF */
-#define NV_PGRAPH_STATE_BUFFER_5_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_BUFFER_5_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_PITCH_0 8:8 /* RWIVF */
-#define NV_PGRAPH_STATE_PITCH_0_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_PITCH_0_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_PITCH_1 9:9 /* RWIVF */
-#define NV_PGRAPH_STATE_PITCH_1_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_PITCH_1_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_PITCH_2 10:10 /* RWIVF */
-#define NV_PGRAPH_STATE_PITCH_2_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_PITCH_2_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_PITCH_3 11:11 /* RWIVF */
-#define NV_PGRAPH_STATE_PITCH_3_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_PITCH_3_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_PITCH_4 12:12 /* RWIVF */
-#define NV_PGRAPH_STATE_PITCH_4_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_PITCH_4_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_CHROMA_COLOR 16:16 /* RWIVF */
-#define NV_PGRAPH_STATE_CHROMA_COLOR_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_CHROMA_COLOR_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_CHROMA_COLORFMT 17:17 /* RWIVF */
-#define NV_PGRAPH_STATE_CHROMA_COLORFMT_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_CHROMA_COLORFMT_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_CPATTERN_COLORFMT 20:20 /* RWIVF */
-#define NV_PGRAPH_STATE_CPATTERN_COLORFMT_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_CPATTERN_COLORFMT_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_CPATTERN_MONOFMT 21:21 /* RWIVF */
-#define NV_PGRAPH_STATE_CPATTERN_MONOFMT_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_CPATTERN_MONOFMT_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_CPATTERN_SELECT 22:22 /* RWIVF */
-#define NV_PGRAPH_STATE_CPATTERN_SELECT_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_CPATTERN_SELECT_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_PATTERN_COLOR0 24:24 /* RWIVF */
-#define NV_PGRAPH_STATE_PATTERN_COLOR0_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_PATTERN_COLOR0_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_PATTERN_COLOR1 25:25 /* RWIVF */
-#define NV_PGRAPH_STATE_PATTERN_COLOR1_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_PATTERN_COLOR1_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_PATTERN_PATT0 26:26 /* RWIVF */
-#define NV_PGRAPH_STATE_PATTERN_PATT0_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_PATTERN_PATT0_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_PATTERN_PATT1 27:27 /* RWIVF */
-#define NV_PGRAPH_STATE_PATTERN_PATT1_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_PATTERN_PATT1_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_CACHE_INDEX 0x00400728 /* RW-4R */
-#define NV_PGRAPH_CACHE_INDEX_BANK 2:2 /* RWXVF */
-#define NV_PGRAPH_CACHE_INDEX_BANK_10 0x00000000 /* RW--V */
-#define NV_PGRAPH_CACHE_INDEX_BANK_32 0x00000001 /* RW--V */
-#define NV_PGRAPH_CACHE_INDEX_ADRS 12:3 /* RWXVF */
-#define NV_PGRAPH_CACHE_INDEX_ADRS_0 0x00000000 /* RW--V */
-#define NV_PGRAPH_CACHE_INDEX_ADRS_1024 0x00000400 /* RW--V */
-#define NV_PGRAPH_CACHE_INDEX_OP 14:13 /* RWXVF */
-#define NV_PGRAPH_CACHE_INDEX_OP_WR_CACHE 0x00000000 /* RW--V */
-#define NV_PGRAPH_CACHE_INDEX_OP_RD_CACHE 0x00000001 /* RW--V */
-#define NV_PGRAPH_CACHE_INDEX_OP_RD_INDEX 0x00000002 /* RW--V */
-#define NV_PGRAPH_CACHE_RAM 0x0040072c /* RW-4R */
-#define NV_PGRAPH_CACHE_RAM_VALUE 31:0 /* RWXVF */
-#define NV_PGRAPH_DMA_PITCH 0x00400760 /* RW-4R */
-#define NV_PGRAPH_DMA_PITCH_S0 15:0 /* RWXSF */
-#define NV_PGRAPH_DMA_PITCH_S1 31:16 /* RWXSF */
-#define NV_PGRAPH_DVD_COLORFMT 0x00400764 /* RW-4R */
-#define NV_PGRAPH_DVD_COLORFMT_IMAGE 5:0 /* RWNVF */
-#define NV_PGRAPH_DVD_COLORFMT_IMAGE_FORMAT_INVALID 0x00 /* RWN-V */
-#define NV_PGRAPH_DVD_COLORFMT_IMAGE_FORMAT_LE_V8YB8U8YA8 0x12 /* RW--V */
-#define NV_PGRAPH_DVD_COLORFMT_IMAGE_FORMAT_LE_YB8V8YA8U8 0x13 /* RW--V */
-#define NV_PGRAPH_DVD_COLORFMT_OVLY 9:8 /* RWNVF */
-#define NV_PGRAPH_DVD_COLORFMT_OVLY_FORMAT_INVALID 0x00 /* RWN-V */
-#define NV_PGRAPH_DVD_COLORFMT_OVLY_FORMAT_LE_A8Y8U8V8 0x01 /* RW--V */
-#define NV_PGRAPH_DVD_COLORFMT_OVLY_FORMAT_LE_A4V6YB6A4U6YA6 0x02 /* RW--V */
-#define NV_PGRAPH_DVD_COLORFMT_OVLY_FORMAT_TRANSPARENT 0x03 /* RW--V */
-#define NV_PGRAPH_SCALED_FORMAT 0x00400768 /* RW-4R */
-#define NV_PGRAPH_SCALED_FORMAT_ORIGIN 17:16 /* RWIVF */
-#define NV_PGRAPH_SCALED_FORMAT_ORIGIN_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_SCALED_FORMAT_ORIGIN_CENTER 0x00000001 /* RW--V */
-#define NV_PGRAPH_SCALED_FORMAT_ORIGIN_CORNER 0x00000002 /* RW--V */
-#define NV_PGRAPH_SCALED_FORMAT_INTERPOLATOR 24:24 /* RWIVF */
-#define NV_PGRAPH_SCALED_FORMAT_INTERPOLATOR_ZOH 0x00000000 /* RWI-V */
-#define NV_PGRAPH_SCALED_FORMAT_INTERPOLATOR_FOH 0x00000001 /* RW--V */
-#define NV_PGRAPH_PATT_COLOR0 0x00400800 /* RW-4R */
-#define NV_PGRAPH_PATT_COLOR0_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_PATT_COLOR1 0x00400804 /* RW-4R */
-#define NV_PGRAPH_PATT_COLOR1_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_PATT_COLORRAM(i) (0x00400900+(i)*4) /* R--4A */
-#define NV_PGRAPH_PATT_COLORRAM__SIZE_1 64 /* */
-#define NV_PGRAPH_PATT_COLORRAM_VALUE 23:0 /* R--UF */
-#define NV_PGRAPH_PATTERN(i) (0x00400808+(i)*4) /* RW-4A */
-#define NV_PGRAPH_PATTERN__SIZE_1 2 /* */
-#define NV_PGRAPH_PATTERN_BITMAP 31:0 /* RWXVF */
-#define NV_PGRAPH_PATTERN_SHAPE 0x00400810 /* RW-4R */
-#define NV_PGRAPH_PATTERN_SHAPE_VALUE 1:0 /* RWXVF */
-#define NV_PGRAPH_PATTERN_SHAPE_VALUE_8X_8Y 0x00000000 /* RW--V */
-#define NV_PGRAPH_PATTERN_SHAPE_VALUE_64X_1Y 0x00000001 /* RW--V */
-#define NV_PGRAPH_PATTERN_SHAPE_VALUE_1X_64Y 0x00000002 /* RW--V */
-#define NV_PGRAPH_PATTERN_SHAPE_SELECT 4:4 /* RWXVF */
-#define NV_PGRAPH_PATTERN_SHAPE_SELECT_2COLOR 0x00000000 /* RW--V */
-#define NV_PGRAPH_PATTERN_SHAPE_SELECT_FULLCOLOR 0x00000001 /* RW--V */
-#define NV_PGRAPH_MONO_COLOR0 0x00400600 /* RW-4R */
-#define NV_PGRAPH_MONO_COLOR0_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_ROP3 0x00400604 /* RW-4R */
-#define NV_PGRAPH_ROP3_VALUE 7:0 /* RWXVF */
-#define NV_PGRAPH_CHROMA 0x00400814 /* RW-4R */
-#define NV_PGRAPH_CHROMA_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_BETA_AND 0x00400608 /* RW-4R */
-#define NV_PGRAPH_BETA_AND_VALUE_FRACTION 30:23 /* RWXUF */
-#define NV_PGRAPH_BETA_PREMULT 0x0040060c /* RW-4R */
-#define NV_PGRAPH_BETA_PREMULT_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_CONTROL0 0x00400818 /* RW-4R */
-#define NV_PGRAPH_CONTROL1 0x0040081c /* RW-4R */
-#define NV_PGRAPH_CONTROL2 0x00400820 /* RW-4R */
-#define NV_PGRAPH_BLEND 0x00400824 /* RW-4R */
-#define NV_PGRAPH_DPRAM_INDEX 0x00400828 /* RW-4R */
-#define NV_PGRAPH_DPRAM_INDEX_ADRS 6:0 /* RWIVF */
-#define NV_PGRAPH_DPRAM_INDEX_ADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_DPRAM_INDEX_SELECT 10:8 /* RWIVF */
-#define NV_PGRAPH_DPRAM_INDEX_SELECT_ADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_DPRAM_INDEX_SELECT_ADRS_1 0x00000001 /* RW--V */
-#define NV_PGRAPH_DPRAM_INDEX_SELECT_DATA_0 0x00000002 /* RW--V */
-#define NV_PGRAPH_DPRAM_INDEX_SELECT_DATA_1 0x00000003 /* RW--V */
-#define NV_PGRAPH_DPRAM_INDEX_SELECT_WE_0 0x00000004 /* RW--V */
-#define NV_PGRAPH_DPRAM_INDEX_SELECT_WE_1 0x00000005 /* RW--V */
-#define NV_PGRAPH_DPRAM_INDEX_SELECT_ALPHA_0 0x00000006 /* RW--V */
-#define NV_PGRAPH_DPRAM_INDEX_SELECT_ALPHA_1 0x00000007 /* RW--V */
-#define NV_PGRAPH_DPRAM_DATA 0x0040082c /* RW-4R */
-#define NV_PGRAPH_DPRAM_DATA_VALUE 31:0 /* RWXVF */
-#define NV_PGRAPH_DPRAM_ADRS_0 0x0040082c /* RW-4R */
-#define NV_PGRAPH_DPRAM_ADRS_0__ALIAS_1 NV_PGRAPH_DPRAM_DATA /* */
-#define NV_PGRAPH_DPRAM_ADRS_0_VALUE 19:0 /* RWXVF */
-#define NV_PGRAPH_DPRAM_ADRS_1 0x0040082c /* RW-4R */
-#define NV_PGRAPH_DPRAM_ADRS_1__ALIAS_1 NV_PGRAPH_DPRAM_DATA /* */
-#define NV_PGRAPH_DPRAM_ADRS_1_VALUE 19:0 /* RWXVF */
-#define NV_PGRAPH_DPRAM_DATA_0 0x0040082c /* RW-4R */
-#define NV_PGRAPH_DPRAM_DATA_0__ALIAS_1 NV_PGRAPH_DPRAM_DATA /* */
-#define NV_PGRAPH_DPRAM_DATA_0_VALUE 31:0 /* RWXVF */
-#define NV_PGRAPH_DPRAM_DATA_1 0x0040082c /* RW-4R */
-#define NV_PGRAPH_DPRAM_DATA_1__ALIAS_1 NV_PGRAPH_DPRAM_DATA /* */
-#define NV_PGRAPH_DPRAM_DATA_1_VALUE 31:0 /* RWXVF */
-#define NV_PGRAPH_DPRAM_WE_0 0x0040082c /* RW-4R */
-#define NV_PGRAPH_DPRAM_WE_0__ALIAS_1 NV_PGRAPH_DPRAM_DATA /* */
-#define NV_PGRAPH_DPRAM_WE_0_VALUE 23:0 /* RWXVF */
-#define NV_PGRAPH_DPRAM_WE_1 0x0040082c /* RW-4R */
-#define NV_PGRAPH_DPRAM_WE_1__ALIAS_1 NV_PGRAPH_DPRAM_DATA /* */
-#define NV_PGRAPH_DPRAM_WE_1_VALUE 23:0 /* RWXVF */
-#define NV_PGRAPH_DPRAM_ALPHA_0 0x0040082c /* RW-4R */
-#define NV_PGRAPH_DPRAM_ALPHA_0__ALIAS_1 NV_PGRAPH_DPRAM_DATA /* */
-#define NV_PGRAPH_DPRAM_ALPHA_0_VALUE 31:0 /* RWXVF */
-#define NV_PGRAPH_DPRAM_ALPHA_1 0x0040082c /* RW-4R */
-#define NV_PGRAPH_DPRAM_ALPHA_1__ALIAS_1 NV_PGRAPH_DPRAM_DATA /* */
-#define NV_PGRAPH_DPRAM_ALPHA_1_VALUE 31:0 /* RWXVF */
-#define NV_PGRAPH_STORED_FMT 0x00400830 /* RW-4R */
-#define NV_PGRAPH_STORED_FMT_MONO0 5:0 /* RWXVF */
-#define NV_PGRAPH_STORED_FMT_PATT0 13:8 /* RWXVF */
-#define NV_PGRAPH_STORED_FMT_PATT1 21:16 /* RWXVF */
-#define NV_PGRAPH_STORED_FMT_CHROMA 29:24 /* RWXVF */
-#define NV_PGRAPH_FORMATS 0x00400618 /* RW-4R */
-#define NV_PGRAPH_FORMATS_ROP 2:0 /* R-XVF */
-#define NV_PGRAPH_FORMATS_ROP_Y8 0x00000000 /* -W--V */
-#define NV_PGRAPH_FORMATS_ROP_RGB15 0x00000001 /* -W--V */
-#define NV_PGRAPH_FORMATS_ROP_RGB16 0x00000002 /* -W--V */
-#define NV_PGRAPH_FORMATS_ROP_Y16 0x00000003 /* -W--V */
-#define NV_PGRAPH_FORMATS_ROP_INVALID 0x00000004 /* -W--V */
-#define NV_PGRAPH_FORMATS_ROP_RGB24 0x00000005 /* -W--V */
-#define NV_PGRAPH_FORMATS_ROP_RGB30 0x00000006 /* -W--V */
-#define NV_PGRAPH_FORMATS_ROP_Y32 0x00000007 /* -W--V */
-#define NV_PGRAPH_FORMATS_SRC 9:4 /* R-XVF */
-#define NV_PGRAPH_FORMATS_SRC_INVALID 0x00000000 /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_Y8 0x00000001 /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_X16A8Y8 0x00000002 /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_X24Y8 0x00000003 /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_A1R5G5B5 0x00000006 /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_X1R5G5B5 0x00000007 /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_X16A1R5G5B5 0x00000008 /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_X17R5G5B5 0x00000009 /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_R5G6B5 0x0000000A /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_A16R5G6B5 0x0000000B /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_X16R5G6B5 0x0000000C /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_A8R8G8B8 0x0000000D /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_X8R8G8B8 0x0000000E /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_Y16 0x0000000F /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_A16Y16 0x00000010 /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_X16Y16 0x00000011 /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_V8YB8U8YA8 0x00000012 /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_YB8V8YA8U8 0x00000013 /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_Y32 0x00000014 /* RW--V */
-#define NV_PGRAPH_FORMATS_FB 15:12 /* R-XVF */
-#define NV_PGRAPH_FORMATS_FB_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_FORMATS_FB_Y8 0x00000001 /* RW--V */
-#define NV_PGRAPH_FORMATS_FB_X1R5G5B5_Z1R5G5B5 0x00000002 /* RW--V */
-#define NV_PGRAPH_FORMATS_FB_X1R5G5B5_O1R5G5B5 0x00000003 /* RW--V */
-#define NV_PGRAPH_FORMATS_FB_A1R5G5B5 0x00000004 /* RW--V */
-#define NV_PGRAPH_FORMATS_FB_R5G6B5 0x00000005 /* RW--V */
-#define NV_PGRAPH_FORMATS_FB_Y16 0x00000006 /* RW--V */
-#define NV_PGRAPH_FORMATS_FB_X8R8G8B8_Z8R8G8B8 0x00000007 /* RW--V */
-#define NV_PGRAPH_FORMATS_FB_X8R8G8B8_O1Z7R8G8B8 0x00000008 /* RW--V */
-#define NV_PGRAPH_FORMATS_FB_X1A7R8G8B8_Z1A7R8G8B8 0x00000009 /* RW--V */
-#define NV_PGRAPH_FORMATS_FB_X1A7R8G8B8_O1A7R8G8B8 0x0000000a /* RW--V */
-#define NV_PGRAPH_FORMATS_FB_X8R8G8B8_O8R8G8B8 0x0000000b /* RW--V */
-#define NV_PGRAPH_FORMATS_FB_A8R8G8B8 0x0000000c /* RW--V */
-#define NV_PGRAPH_FORMATS_FB_Y32 0x0000000d /* RW--V */
-#define NV_PGRAPH_FORMATS_FB_V8YB8U8YA8 0x0000000e /* RW--V */
-#define NV_PGRAPH_FORMATS_FB_YB8V8YA8U8 0x0000000f /* RW--V */
-#define NV_PGRAPH_ABS_X_RAM(i) (0x00400400+(i)*4) /* RW-4A */
-#define NV_PGRAPH_ABS_X_RAM__SIZE_1 32 /* */
-#define NV_PGRAPH_ABS_X_RAM_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_X_RAM_BPORT(i) (0x00400c00+(i)*4) /* R--4A */
-#define NV_PGRAPH_X_RAM_BPORT__SIZE_1 32 /* */
-#define NV_PGRAPH_X_RAM_BPORT_VALUE 31:0 /* R--UF */
-#define NV_PGRAPH_ABS_Y_RAM(i) (0x00400480+(i)*4) /* RW-4A */
-#define NV_PGRAPH_ABS_Y_RAM__SIZE_1 32 /* */
-#define NV_PGRAPH_ABS_Y_RAM_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_Y_RAM_BPORT(i) (0x00400c80+(i)*4) /* R--4A */
-#define NV_PGRAPH_Y_RAM_BPORT__SIZE_1 32 /* */
-#define NV_PGRAPH_Y_RAM_BPORT_VALUE 31:0 /* R--UF */
-#define NV_PGRAPH_XY_LOGIC_MISC0 0x00400514 /* RW-4R */
-#define NV_PGRAPH_XY_LOGIC_MISC0_COUNTER 17:0 /* RWBUF */
-#define NV_PGRAPH_XY_LOGIC_MISC0_COUNTER_0 0x00000000 /* RWB-V */
-#define NV_PGRAPH_XY_LOGIC_MISC0_DIMENSION 20:20 /* RWVVF */
-#define NV_PGRAPH_XY_LOGIC_MISC0_DIMENSION_NONZERO 0x00000000 /* RWV-V */
-#define NV_PGRAPH_XY_LOGIC_MISC0_DIMENSION_ZERO 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC0_INDEX 31:28 /* RWBUF */
-#define NV_PGRAPH_XY_LOGIC_MISC0_INDEX_0 0x00000000 /* RWB-V */
-#define NV_PGRAPH_XY_LOGIC_MISC1 0x00400518 /* RW-4R */
-#define NV_PGRAPH_XY_LOGIC_MISC1_INITIAL 0:0 /* RWNVF */
-#define NV_PGRAPH_XY_LOGIC_MISC1_INITIAL_NEEDED 0x00000000 /* RWN-V */
-#define NV_PGRAPH_XY_LOGIC_MISC1_INITIAL_DONE 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC1_XTRACLIPX 4:4 /* RWIVF */
-#define NV_PGRAPH_XY_LOGIC_MISC1_XTRACLIPX_NOTNULL 0x00000000 /* RWI-V */
-#define NV_PGRAPH_XY_LOGIC_MISC1_XTRACLIPX_NULL 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC1_XTRACLIPY 5:5 /* RWIVF */
-#define NV_PGRAPH_XY_LOGIC_MISC1_XTRACLIPY_NOTNULL 0x00000000 /* RWI-V */
-#define NV_PGRAPH_XY_LOGIC_MISC1_XTRACLIPY_NULL 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_XIMAX 12:12 /* RWIVF */
-#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_XIMAX_UUMAX 0x00000000 /* RWI-V */
-#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_XIMAX_IMAGEMAX 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_YIMAX 16:16 /* RWIVF */
-#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_YIMAX_UUMAX 0x00000000 /* RWI-V */
-#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_YIMAX_IMAGEMAX 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_XXTRA 20:20 /* RWIVF */
-#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_XXTRA_CLIPMAX 0x00000000 /* RWI-V */
-#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_XXTRA_IMAGEMAX 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC2 0x0040051C /* RW-4R */
-#define NV_PGRAPH_XY_LOGIC_MISC2_HANDOFF 0:0 /* RWIVF */
-#define NV_PGRAPH_XY_LOGIC_MISC2_HANDOFF_DISABLE 0x00000000 /* RWI-V */
-#define NV_PGRAPH_XY_LOGIC_MISC2_HANDOFF_ENABLE 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC2_XTRACLIPX 4:4 /* RWIVF */
-#define NV_PGRAPH_XY_LOGIC_MISC2_XTRACLIPX_NOTNULL 0x00000000 /* RWI-V */
-#define NV_PGRAPH_XY_LOGIC_MISC2_XTRACLIPX_NULL 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC2_XTRACLIPY 5:5 /* RWIVF */
-#define NV_PGRAPH_XY_LOGIC_MISC2_XTRACLIPY_NOTNULL 0x00000000 /* RWI-V */
-#define NV_PGRAPH_XY_LOGIC_MISC2_XTRACLIPY_NULL 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_XIMAX 12:12 /* RWIVF */
-#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_XIMAX_UCMAX 0x00000000 /* RWI-V */
-#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_XIMAX_IMAGEMAX 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_YIMAX 16:16 /* RWIVF */
-#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_YIMAX_UCMAX 0x00000000 /* RWI-V */
-#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_YIMAX_IMAGEMAX 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_XXTRA 20:20 /* RWIVF */
-#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_XXTRA_CLIPMAX 0x00000000 /* RWI-V */
-#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_XXTRA_IMAGEMAX 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC3 0x00400520 /* RW-4R */
-#define NV_PGRAPH_XY_LOGIC_MISC3_WDIMY_EQ_0 0:0 /* RWXVF */
-#define NV_PGRAPH_XY_LOGIC_MISC3_WDIMY_EQ_0_NULL 0x00000000 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC3_WDIMY_EQ_0_TRUE 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC3_RELOAD_WDIMY 4:4 /* RWXVF */
-#define NV_PGRAPH_XY_LOGIC_MISC3_RELOAD_WDIMY_NULL 0x00000000 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC3_RELOAD_WDIMY_TRUE 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC3_RELOAD_WX 8:8 /* RWIVF */
-#define NV_PGRAPH_XY_LOGIC_MISC3_RELOAD_WX_NULL 0x00000000 /* RWI-V */
-#define NV_PGRAPH_XY_LOGIC_MISC3_RELOAD_WX_TRUE 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_ALG 12:12 /* RWIVF */
-#define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_ALG_NULL 0x00000000 /* RWI-V */
-#define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_ALG_TRUE 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_DIMX 22:16 /* RWXUF */
-#define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_DIMX_0 0x00000000 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_WDIMX 30:24 /* RWXUF */
-#define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_WDIMX_0 0x00000000 /* RW--V */
-#define NV_PGRAPH_X_MISC 0x00400500 /* RW-4R */
-#define NV_PGRAPH_X_MISC_BIT33_0 0:0 /* RWNVF */
-#define NV_PGRAPH_X_MISC_BIT33_0_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_X_MISC_BIT33_1 1:1 /* RWNVF */
-#define NV_PGRAPH_X_MISC_BIT33_1_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_X_MISC_BIT33_2 2:2 /* RWNVF */
-#define NV_PGRAPH_X_MISC_BIT33_2_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_X_MISC_BIT33_3 3:3 /* RWNVF */
-#define NV_PGRAPH_X_MISC_BIT33_3_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_X_MISC_RANGE_0 4:4 /* RWNVF */
-#define NV_PGRAPH_X_MISC_RANGE_0_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_X_MISC_RANGE_1 5:5 /* RWNVF */
-#define NV_PGRAPH_X_MISC_RANGE_1_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_X_MISC_RANGE_2 6:6 /* RWNVF */
-#define NV_PGRAPH_X_MISC_RANGE_2_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_X_MISC_RANGE_3 7:7 /* RWNVF */
-#define NV_PGRAPH_X_MISC_RANGE_3_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_X_MISC_ADDER_OUTPUT 29:28 /* RWXVF */
-#define NV_PGRAPH_X_MISC_ADDER_OUTPUT_EQ_0 0x00000000 /* RW--V */
-#define NV_PGRAPH_X_MISC_ADDER_OUTPUT_LT_0 0x00000001 /* RW--V */
-#define NV_PGRAPH_X_MISC_ADDER_OUTPUT_GT_0 0x00000002 /* RW--V */
-#define NV_PGRAPH_Y_MISC 0x00400504 /* RW-4R */
-#define NV_PGRAPH_Y_MISC_BIT33_0 0:0 /* RWNVF */
-#define NV_PGRAPH_Y_MISC_BIT33_0_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_Y_MISC_BIT33_1 1:1 /* RWNVF */
-#define NV_PGRAPH_Y_MISC_BIT33_1_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_Y_MISC_BIT33_2 2:2 /* RWNVF */
-#define NV_PGRAPH_Y_MISC_BIT33_2_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_Y_MISC_BIT33_3 3:3 /* RWNVF */
-#define NV_PGRAPH_Y_MISC_BIT33_3_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_Y_MISC_RANGE_0 4:4 /* RWNVF */
-#define NV_PGRAPH_Y_MISC_RANGE_0_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_Y_MISC_RANGE_1 5:5 /* RWNVF */
-#define NV_PGRAPH_Y_MISC_RANGE_1_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_Y_MISC_RANGE_2 6:6 /* RWNVF */
-#define NV_PGRAPH_Y_MISC_RANGE_2_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_Y_MISC_RANGE_3 7:7 /* RWNVF */
-#define NV_PGRAPH_Y_MISC_RANGE_3_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_Y_MISC_ADDER_OUTPUT 29:28 /* RWXVF */
-#define NV_PGRAPH_Y_MISC_ADDER_OUTPUT_EQ_0 0x00000000 /* RW--V */
-#define NV_PGRAPH_Y_MISC_ADDER_OUTPUT_LT_0 0x00000001 /* RW--V */
-#define NV_PGRAPH_Y_MISC_ADDER_OUTPUT_GT_0 0x00000002 /* RW--V */
-#define NV_PGRAPH_ABS_UCLIP_XMIN 0x0040053C /* RW-4R */
-#define NV_PGRAPH_ABS_UCLIP_XMIN_VALUE 15:0 /* RWXSF */
-#define NV_PGRAPH_ABS_UCLIP_XMAX 0x00400544 /* RW-4R */
-#define NV_PGRAPH_ABS_UCLIP_XMAX_VALUE 17:0 /* RWXSF */
-#define NV_PGRAPH_ABS_UCLIP_YMIN 0x00400540 /* RW-4R */
-#define NV_PGRAPH_ABS_UCLIP_YMIN_VALUE 15:0 /* RWXSF */
-#define NV_PGRAPH_ABS_UCLIP_YMAX 0x00400548 /* RW-4R */
-#define NV_PGRAPH_ABS_UCLIP_YMAX_VALUE 17:0 /* RWXSF */
-#define NV_PGRAPH_ABS_UCLIPA_XMIN 0x00400560 /* RW-4R */
-#define NV_PGRAPH_ABS_UCLIPA_XMIN_VALUE 15:0 /* RWXSF */
-#define NV_PGRAPH_ABS_UCLIPA_XMAX 0x00400568 /* RW-4R */
-#define NV_PGRAPH_ABS_UCLIPA_XMAX_VALUE 17:0 /* RWXSF */
-#define NV_PGRAPH_ABS_UCLIPA_YMIN 0x00400564 /* RW-4R */
-#define NV_PGRAPH_ABS_UCLIPA_YMIN_VALUE 15:0 /* RWXSF */
-#define NV_PGRAPH_ABS_UCLIPA_YMAX 0x0040056C /* RW-4R */
-#define NV_PGRAPH_ABS_UCLIPA_YMAX_VALUE 17:0 /* RWXSF */
-#define NV_PGRAPH_SOURCE_COLOR 0x0040050C /* RW-4R */
-#define NV_PGRAPH_SOURCE_COLOR_VALUE 31:0 /* RWNVF */
-#define NV_PGRAPH_SOURCE_COLOR_VALUE_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_VALID1 0x00400508 /* RW-4R */
-#define NV_PGRAPH_VALID1_VLD 22:0 /* RWNVF */
-#define NV_PGRAPH_VALID1_VLD_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_VALID1_CLIP_MIN 28:28 /* RWIVF */
-#define NV_PGRAPH_VALID1_CLIP_MIN_NO_ERROR 0x00000000 /* RWI-V */
-#define NV_PGRAPH_VALID1_CLIP_MIN_ONLY 0x00000001 /* RW--V */
-#define NV_PGRAPH_VALID1_CLIPA_MIN 29:29 /* RWIVF */
-#define NV_PGRAPH_VALID1_CLIPA_MIN_NO_ERROR 0x00000000 /* RWI-V */
-#define NV_PGRAPH_VALID1_CLIPA_MIN_ONLY 0x00000001 /* RW--V */
-#define NV_PGRAPH_VALID1_CLIP_MAX 30:30 /* RWIVF */
-#define NV_PGRAPH_VALID1_CLIP_MAX_NO_ERROR 0x00000000 /* RWI-V */
-#define NV_PGRAPH_VALID1_CLIP_MAX_ONLY 0x00000001 /* RW--V */
-#define NV_PGRAPH_VALID1_CLIPA_MAX 31:31 /* RWIVF */
-#define NV_PGRAPH_VALID1_CLIPA_MAX_NO_ERROR 0x00000000 /* RWI-V */
-#define NV_PGRAPH_VALID1_CLIPA_MAX_ONLY 0x00000001 /* RW--V */
-#define NV_PGRAPH_VALID2 0x00400578 /* RW-4R */
-#define NV_PGRAPH_VALID2_VLD2 28:0 /* RWNVF */
-#define NV_PGRAPH_VALID2_VLD2_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_ABS_ICLIP_XMAX 0x00400534 /* RW-4R */
-#define NV_PGRAPH_ABS_ICLIP_XMAX_VALUE 17:0 /* RWXSF */
-#define NV_PGRAPH_ABS_ICLIP_YMAX 0x00400538 /* RW-4R */
-#define NV_PGRAPH_ABS_ICLIP_YMAX_VALUE 17:0 /* RWXSF */
-#define NV_PGRAPH_CLIPX_0 0x00400524 /* RW-4R */
-#define NV_PGRAPH_CLIPX_0_CLIP0_MIN 1:0 /* RWNVF */
-#define NV_PGRAPH_CLIPX_0_CLIP0_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP0_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_0_CLIP0_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP0_MAX 3:2 /* RWNVF */
-#define NV_PGRAPH_CLIPX_0_CLIP0_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP0_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_0_CLIP0_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP1_MIN 5:4 /* RWNVF */
-#define NV_PGRAPH_CLIPX_0_CLIP1_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP1_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_0_CLIP1_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP1_MAX 7:6 /* RWNVF */
-#define NV_PGRAPH_CLIPX_0_CLIP1_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP1_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_0_CLIP1_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP2_MIN 9:8 /* RWNVF */
-#define NV_PGRAPH_CLIPX_0_CLIP2_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP2_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_0_CLIP2_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP2_MAX 11:10 /* RWNVF */
-#define NV_PGRAPH_CLIPX_0_CLIP2_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP2_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_0_CLIP2_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP3_MIN 13:12 /* RWNVF */
-#define NV_PGRAPH_CLIPX_0_CLIP3_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP3_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_0_CLIP3_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP3_MAX 15:14 /* RWNVF */
-#define NV_PGRAPH_CLIPX_0_CLIP3_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP3_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_0_CLIP3_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP4_MIN 17:16 /* RWNVF */
-#define NV_PGRAPH_CLIPX_0_CLIP4_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP4_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_0_CLIP4_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP4_MAX 19:18 /* RWNVF */
-#define NV_PGRAPH_CLIPX_0_CLIP4_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP4_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_0_CLIP4_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP5_MIN 21:20 /* RWNVF */
-#define NV_PGRAPH_CLIPX_0_CLIP5_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP5_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_0_CLIP5_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP5_MAX 23:22 /* RWNVF */
-#define NV_PGRAPH_CLIPX_0_CLIP5_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP5_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_0_CLIP5_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP6_MIN 25:24 /* RWNVF */
-#define NV_PGRAPH_CLIPX_0_CLIP6_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP6_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_0_CLIP6_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP6_MAX 27:26 /* RWNVF */
-#define NV_PGRAPH_CLIPX_0_CLIP6_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP6_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_0_CLIP6_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP7_MIN 29:28 /* RWNVF */
-#define NV_PGRAPH_CLIPX_0_CLIP7_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP7_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_0_CLIP7_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP7_MAX 31:30 /* RWNVF */
-#define NV_PGRAPH_CLIPX_0_CLIP7_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP7_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_0_CLIP7_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_1 0x00400528 /* RW-4R */
-#define NV_PGRAPH_CLIPX_1_CLIP8_MIN 1:0 /* RWNVF */
-#define NV_PGRAPH_CLIPX_1_CLIP8_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP8_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_1_CLIP8_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP8_MAX 3:2 /* RWNVF */
-#define NV_PGRAPH_CLIPX_1_CLIP8_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP8_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_1_CLIP8_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP9_MIN 5:4 /* RWNVF */
-#define NV_PGRAPH_CLIPX_1_CLIP9_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP9_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_1_CLIP9_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP9_MAX 7:6 /* RWNVF */
-#define NV_PGRAPH_CLIPX_1_CLIP9_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP9_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_1_CLIP9_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP10_MIN 9:8 /* RWNVF */
-#define NV_PGRAPH_CLIPX_1_CLIP10_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP10_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_1_CLIP10_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP10_MAX 11:10 /* RWNVF */
-#define NV_PGRAPH_CLIPX_1_CLIP10_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP10_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_1_CLIP10_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP11_MIN 13:12 /* RWNVF */
-#define NV_PGRAPH_CLIPX_1_CLIP11_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP11_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_1_CLIP11MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP11_MAX 15:14 /* RWNVF */
-#define NV_PGRAPH_CLIPX_1_CLIP11_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP11_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_1_CLIP11_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP12_MIN 17:16 /* RWNVF */
-#define NV_PGRAPH_CLIPX_1_CLIP12_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP12_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_1_CLIP12_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP12_MAX 19:18 /* RWNVF */
-#define NV_PGRAPH_CLIPX_1_CLIP12_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP12_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_1_CLIP12_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP13_MIN 21:20 /* RWNVF */
-#define NV_PGRAPH_CLIPX_1_CLIP13_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP13_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_1_CLIP13_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP13_MAX 23:22 /* RWNVF */
-#define NV_PGRAPH_CLIPX_1_CLIP13_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP13_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_1_CLIP13_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP14_MIN 25:24 /* RWNVF */
-#define NV_PGRAPH_CLIPX_1_CLIP14_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP14_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_1_CLIP14_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP14_MAX 27:26 /* RWNVF */
-#define NV_PGRAPH_CLIPX_1_CLIP14_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP14_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_1_CLIP14_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP15_MIN 29:28 /* RWNVF */
-#define NV_PGRAPH_CLIPX_1_CLIP15_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP15_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_1_CLIP15_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP15_MAX 31:30 /* RWNVF */
-#define NV_PGRAPH_CLIPX_1_CLIP15_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP15_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_1_CLIP15_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_0 0x0040052c /* RW-4R */
-#define NV_PGRAPH_CLIPY_0_CLIP0_MIN 1:0 /* RWNVF */
-#define NV_PGRAPH_CLIPY_0_CLIP0_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP0_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_0_CLIP0_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP0_MAX 3:2 /* RWNVF */
-#define NV_PGRAPH_CLIPY_0_CLIP0_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP0_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_0_CLIP0_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP1_MIN 5:4 /* RWNVF */
-#define NV_PGRAPH_CLIPY_0_CLIP1_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP1_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_0_CLIP1_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP1_MAX 7:6 /* RWNVF */
-#define NV_PGRAPH_CLIPY_0_CLIP1_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP1_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_0_CLIP1_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP2_MIN 9:8 /* RWNVF */
-#define NV_PGRAPH_CLIPY_0_CLIP2_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP2_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_0_CLIP2_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP2_MAX 11:10 /* RWNVF */
-#define NV_PGRAPH_CLIPY_0_CLIP2_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP2_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_0_CLIP2_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP3_MIN 13:12 /* RWNVF */
-#define NV_PGRAPH_CLIPY_0_CLIP3_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP3_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_0_CLIP3_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP3_MAX 15:14 /* RWNVF */
-#define NV_PGRAPH_CLIPY_0_CLIP3_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP3_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_0_CLIP3_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP4_MIN 17:16 /* RWNVF */
-#define NV_PGRAPH_CLIPY_0_CLIP4_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP4_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_0_CLIP4_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP4_MAX 19:18 /* RWNVF */
-#define NV_PGRAPH_CLIPY_0_CLIP4_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP4_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_0_CLIP4_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP5_MIN 21:20 /* RWNVF */
-#define NV_PGRAPH_CLIPY_0_CLIP5_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP5_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_0_CLIP5_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP5_MAX 23:22 /* RWNVF */
-#define NV_PGRAPH_CLIPY_0_CLIP5_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP5_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_0_CLIP5_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP6_MIN 25:24 /* RWNVF */
-#define NV_PGRAPH_CLIPY_0_CLIP6_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP6_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_0_CLIP6_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP6_MAX 27:26 /* RWNVF */
-#define NV_PGRAPH_CLIPY_0_CLIP6_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP6_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_0_CLIP6_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP7_MIN 29:28 /* RWNVF */
-#define NV_PGRAPH_CLIPY_0_CLIP7_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP7_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_0_CLIP7_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP7_MAX 31:30 /* RWNVF */
-#define NV_PGRAPH_CLIPY_0_CLIP7_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP7_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_0_CLIP7_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_1 0x00400530 /* RW-4R */
-#define NV_PGRAPH_CLIPY_1_CLIP8_MIN 1:0 /* RWNVF */
-#define NV_PGRAPH_CLIPY_1_CLIP8_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP8_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_1_CLIP8_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP8_MAX 3:2 /* RWNVF */
-#define NV_PGRAPH_CLIPY_1_CLIP8_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP8_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_1_CLIP8_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP9_MIN 5:4 /* RWNVF */
-#define NV_PGRAPH_CLIPY_1_CLIP9_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP9_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_1_CLIP9_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP9_MAX 7:6 /* RWNVF */
-#define NV_PGRAPH_CLIPY_1_CLIP9_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP9_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_1_CLIP9_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP10_MIN 9:8 /* RWNVF */
-#define NV_PGRAPH_CLIPY_1_CLIP10_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP10_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_1_CLIP10_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP10_MAX 11:10 /* RWNVF */
-#define NV_PGRAPH_CLIPY_1_CLIP10_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP10_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_1_CLIP10_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP11_MIN 13:12 /* RWNVF */
-#define NV_PGRAPH_CLIPY_1_CLIP11_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP11_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_1_CLIP11MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP11_MAX 15:14 /* RWNVF */
-#define NV_PGRAPH_CLIPY_1_CLIP11_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP11_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_1_CLIP11_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP12_MIN 17:16 /* RWNVF */
-#define NV_PGRAPH_CLIPY_1_CLIP12_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP12_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_1_CLIP12_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP12_MAX 19:18 /* RWNVF */
-#define NV_PGRAPH_CLIPY_1_CLIP12_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP12_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_1_CLIP12_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP13_MIN 21:20 /* RWNVF */
-#define NV_PGRAPH_CLIPY_1_CLIP13_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP13_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_1_CLIP13_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP13_MAX 23:22 /* RWNVF */
-#define NV_PGRAPH_CLIPY_1_CLIP13_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP13_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_1_CLIP13_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP14_MIN 25:24 /* RWNVF */
-#define NV_PGRAPH_CLIPY_1_CLIP14_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP14_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_1_CLIP14_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP14_MAX 27:26 /* RWNVF */
-#define NV_PGRAPH_CLIPY_1_CLIP14_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP14_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_1_CLIP14_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP15_MIN 29:28 /* RWNVF */
-#define NV_PGRAPH_CLIPY_1_CLIP15_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP15_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_1_CLIP15_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP15_MAX 31:30 /* RWNVF */
-#define NV_PGRAPH_CLIPY_1_CLIP15_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP15_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_1_CLIP15_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_MISC24_0 0x00400510 /* RW-4R */
-#define NV_PGRAPH_MISC24_0_VALUE 23:0 /* RWXUF */
-#define NV_PGRAPH_MISC24_1 0x00400570 /* RW-4R */
-#define NV_PGRAPH_MISC24_1_VALUE 23:0 /* RWXUF */
-#define NV_PGRAPH_MISC24_2 0x00400574 /* RW-4R */
-#define NV_PGRAPH_MISC24_2_VALUE 23:0 /* RWXUF */
-#define NV_PGRAPH_PASSTHRU_0 0x0040057C /* RW-4R */
-#define NV_PGRAPH_PASSTHRU_0_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_PASSTHRU_1 0x00400580 /* RW-4R */
-#define NV_PGRAPH_PASSTHRU_1_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_PASSTHRU_2 0x00400584 /* RW-4R */
-#define NV_PGRAPH_PASSTHRU_2_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_U_RAM(i) (0x00400d00+(i)*4) /* RW-4A */
-#define NV_PGRAPH_U_RAM__SIZE_1 16 /* */
-#define NV_PGRAPH_U_RAM_VALUE 31:6 /* RWXFF */
-#define NV_PGRAPH_V_RAM(i) (0x00400d40+(i)*4) /* RW-4A */
-#define NV_PGRAPH_V_RAM__SIZE_1 16 /* */
-#define NV_PGRAPH_V_RAM_VALUE 31:6 /* RWXFF */
-#define NV_PGRAPH_M_RAM(i) (0x00400d80+(i)*4) /* RW-4A */
-#define NV_PGRAPH_M_RAM__SIZE_1 16 /* */
-#define NV_PGRAPH_M_RAM_VALUE 31:6 /* RWXFF */
-#define NV_PGRAPH_DMA_START_0 0x00401000 /* RW-4R */
-#define NV_PGRAPH_DMA_START_0_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_DMA_START_1 0x00401004 /* RW-4R */
-#define NV_PGRAPH_DMA_START_1_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_DMA_LENGTH 0x00401008 /* RW-4R */
-#define NV_PGRAPH_DMA_LENGTH_VALUE 21:0 /* RWXUF */
-#define NV_PGRAPH_DMA_MISC 0x0040100C /* RW-4R */
-#define NV_PGRAPH_DMA_MISC_COUNT 15:0 /* RWXUF */
-#define NV_PGRAPH_DMA_MISC_FMT_SRC 18:16 /* RWXVF */
-#define NV_PGRAPH_DMA_MISC_FMT_DST 22:20 /* RWXVF */
-#define NV_PGRAPH_DMA_DATA_0 0x00401020 /* RW-4R */
-#define NV_PGRAPH_DMA_DATA_0_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_DMA_DATA_1 0x00401024 /* RW-4R */
-#define NV_PGRAPH_DMA_DATA_1_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_DMA_RM 0x00401030 /* RW-4R */
-#define NV_PGRAPH_DMA_RM_ASSIST_A 0:0 /* RWIVF */
-#define NV_PGRAPH_DMA_RM_ASSIST_A_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_DMA_RM_ASSIST_A_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_DMA_RM_ASSIST_A_RESET 0x00000001 /* -W--C */
-#define NV_PGRAPH_DMA_RM_ASSIST_B 1:1 /* RWIVF */
-#define NV_PGRAPH_DMA_RM_ASSIST_B_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_DMA_RM_ASSIST_B_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_DMA_RM_ASSIST_B_RESET 0x00000001 /* -W--C */
-#define NV_PGRAPH_DMA_RM_WRITE_REQ 4:4 /* CWIVF */
-#define NV_PGRAPH_DMA_RM_WRITE_REQ_NOT_PENDING 0x00000000 /* CWI-V */
-#define NV_PGRAPH_DMA_RM_WRITE_REQ_PENDING 0x00000001 /* -W--T */
-#define NV_PGRAPH_DMA_A_XLATE_INST 0x00401040 /* RW-4R */
-#define NV_PGRAPH_DMA_A_XLATE_INST_VALUE 15:0 /* RWXUF */
-#define NV_PGRAPH_DMA_A_CONTROL 0x00401044 /* RW-4R */
-#define NV_PGRAPH_DMA_A_CONTROL_PAGE_TABLE 12:12 /* RWIVF */
-#define NV_PGRAPH_DMA_A_CONTROL_PAGE_TABLE_NOT_PRESENT 0x00000000 /* RWI-V */
-#define NV_PGRAPH_DMA_A_CONTROL_PAGE_TABLE_PRESENT 0x00000001 /* RW--V */
-#define NV_PGRAPH_DMA_A_CONTROL_PAGE_ENTRY 13:13 /* RWXVF */
-#define NV_PGRAPH_DMA_A_CONTROL_PAGE_ENTRY_NOT_LINEAR 0x00000000 /* RW--V */
-#define NV_PGRAPH_DMA_A_CONTROL_PAGE_ENTRY_LINEAR 0x00000001 /* RW--V */
-#define NV_PGRAPH_DMA_A_CONTROL_TARGET_NODE 17:16 /* RWXUF */
-#define NV_PGRAPH_DMA_A_CONTROL_TARGET_NODE_NVM 0x00000000 /* RW--V */
-#define NV_PGRAPH_DMA_A_CONTROL_TARGET_NODE_PCI 0x00000002 /* RW--V */
-#define NV_PGRAPH_DMA_A_CONTROL_TARGET_NODE_AGP 0x00000003 /* RW--V */
-#define NV_PGRAPH_DMA_A_CONTROL_ADJUST 31:20 /* RWXUF */
-#define NV_PGRAPH_DMA_A_LIMIT 0x00401048 /* RW-4R */
-#define NV_PGRAPH_DMA_A_LIMIT_OFFSET 31:0 /* RWXUF */
-#define NV_PGRAPH_DMA_A_TLB_PTE 0x0040104C /* RW-4R */
-#define NV_PGRAPH_DMA_A_TLB_PTE_ACCESS 1:1 /* RWXVF */
-#define NV_PGRAPH_DMA_A_TLB_PTE_ACCESS_READ_ONLY 0x00000000 /* RW--V */
-#define NV_PGRAPH_DMA_A_TLB_PTE_ACCESS_READ_WRITE 0x00000001 /* RW--V */
-#define NV_PGRAPH_DMA_A_TLB_PTE_FRAME_ADDRESS 31:12 /* RWXUF */
-#define NV_PGRAPH_DMA_A_TLB_TAG 0x00401050 /* RW-4R */
-#define NV_PGRAPH_DMA_A_TLB_TAG_ADDRESS 31:12 /* RWXUF */
-#define NV_PGRAPH_DMA_A_ADJ_OFFSET 0x00401054 /* RW-4R */
-#define NV_PGRAPH_DMA_A_ADJ_OFFSET_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_DMA_A_OFFSET 0x00401058 /* RW-4R */
-#define NV_PGRAPH_DMA_A_OFFSET_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_DMA_A_SIZE 0x0040105C /* RW-4R */
-#define NV_PGRAPH_DMA_A_SIZE_VALUE 24:0 /* RWXUF */
-#define NV_PGRAPH_DMA_A_Y_SIZE 0x00401060 /* RW-4R */
-#define NV_PGRAPH_DMA_A_Y_SIZE_VALUE 10:0 /* RWXUF */
-#define NV_PGRAPH_DMA_B_XLATE_INST 0x00401080 /* RW-4R */
-#define NV_PGRAPH_DMA_B_XLATE_INST_VALUE 15:0 /* RWXUF */
-#define NV_PGRAPH_DMA_B_CONTROL 0x00401084 /* RW-4R */
-#define NV_PGRAPH_DMA_B_CONTROL_PAGE_TABLE 12:12 /* RWIVF */
-#define NV_PGRAPH_DMA_B_CONTROL_PAGE_TABLE_NOT_PRESENT 0x00000000 /* RWI-V */
-#define NV_PGRAPH_DMA_B_CONTROL_PAGE_TABLE_PRESENT 0x00000001 /* RW--V */
-#define NV_PGRAPH_DMA_B_CONTROL_PAGE_ENTRY 13:13 /* RWXVF */
-#define NV_PGRAPH_DMA_B_CONTROL_PAGE_ENTRY_NOT_LINEAR 0x00000000 /* RW--V */
-#define NV_PGRAPH_DMA_B_CONTROL_PAGE_ENTRY_LINEAR 0x00000001 /* RW--V */
-#define NV_PGRAPH_DMA_B_CONTROL_TARGET_NODE 17:16 /* RWXUF */
-#define NV_PGRAPH_DMA_B_CONTROL_TARGET_NODE_NVM 0x00000000 /* RW--V */
-#define NV_PGRAPH_DMA_B_CONTROL_TARGET_NODE_PCI 0x00000002 /* RW--V */
-#define NV_PGRAPH_DMA_B_CONTROL_TARGET_NODE_AGP 0x00000003 /* RW--V */
-#define NV_PGRAPH_DMA_B_CONTROL_ADJUST 31:20 /* RWXUF */
-#define NV_PGRAPH_DMA_B_LIMIT 0x00401088 /* RW-4R */
-#define NV_PGRAPH_DMA_B_LIMIT_OFFSET 31:0 /* RWXUF */
-#define NV_PGRAPH_DMA_B_TLB_PTE 0x0040108C /* RW-4R */
-#define NV_PGRAPH_DMA_B_TLB_PTE_ACCESS 1:1 /* RWXVF */
-#define NV_PGRAPH_DMA_B_TLB_PTE_ACCESS_READ_ONLY 0x00000000 /* RW--V */
-#define NV_PGRAPH_DMA_B_TLB_PTE_ACCESS_READ_WRITE 0x00000001 /* RW--V */
-#define NV_PGRAPH_DMA_B_TLB_PTE_FRAME_ADDRESS 31:12 /* RWXUF */
-#define NV_PGRAPH_DMA_B_TLB_TAG 0x00401090 /* RW-4R */
-#define NV_PGRAPH_DMA_B_TLB_TAG_ADDRESS 31:12 /* RWXUF */
-#define NV_PGRAPH_DMA_B_ADJ_OFFSET 0x00401094 /* RW-4R */
-#define NV_PGRAPH_DMA_B_ADJ_OFFSET_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_DMA_B_OFFSET 0x00401098 /* RW-4R */
-#define NV_PGRAPH_DMA_B_OFFSET_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_DMA_B_SIZE 0x0040109C /* RW-4R */
-#define NV_PGRAPH_DMA_B_SIZE_VALUE 24:0 /* RWXUF */
-#define NV_PGRAPH_DMA_B_Y_SIZE 0x004010A0 /* RW-4R */
-#define NV_PGRAPH_DMA_B_Y_SIZE_VALUE 10:0 /* RWXUF */
-
-/* Framebuffer registers */
-#define NV_PFB 0x00100FFF:0x00100000 /* RW--D */
-#define NV_PFB_BOOT_0 0x00100000 /* RW-4R */
-#define NV_PFB_BOOT_0_RAM_AMOUNT 1:0 /* RW-VF */
-#define NV_PFB_BOOT_0_RAM_AMOUNT_32MB 0x00000000 /* RW--V */
-#define NV_PFB_BOOT_0_RAM_AMOUNT_4MB 0x00000001 /* RW--V */
-#define NV_PFB_BOOT_0_RAM_AMOUNT_8MB 0x00000002 /* RW--V */
-#define NV_PFB_BOOT_0_RAM_AMOUNT_16MB 0x00000003 /* RW--V */
-#define NV_PFB_BOOT_0_RAM_WIDTH_128 2:2 /* RW-VF */
-#define NV_PFB_BOOT_0_RAM_WIDTH_128_OFF 0x00000000 /* RW--V */
-#define NV_PFB_BOOT_0_RAM_WIDTH_128_ON 0x00000001 /* RW--V */
-#define NV_PFB_BOOT_0_RAM_TYPE 4:3 /* RW-VF */
-#define NV_PFB_BOOT_0_RAM_TYPE_256K 0x00000000 /* RW--V */
-#define NV_PFB_BOOT_0_RAM_TYPE_512K_2BANK 0x00000001 /* RW--V */
-#define NV_PFB_BOOT_0_RAM_TYPE_512K_4BANK 0x00000002 /* RW--V */
-#define NV_PFB_BOOT_0_RAM_TYPE_1024K_2BANK 0x00000003 /* RW--V */
-#define NV_PFB_CONFIG_0 0x00100200 /* RW-4R */
-#define NV_PFB_CONFIG_0_TYPE 14:0 /* RWIVF */
-#define NV_PFB_CONFIG_0_TYPE_OLD1024_FIXED_8BPP 0x00000120 /* RW--V */
-#define NV_PFB_CONFIG_0_TYPE_OLD1024_FIXED_16BPP 0x00000220 /* RW--V */
-#define NV_PFB_CONFIG_0_TYPE_OLD1024_FIXED_32BPP 0x00000320 /* RW--V */
-#define NV_PFB_CONFIG_0_TYPE_OLD1024_VAR_8BPP 0x00004120 /* RW--V */
-#define NV_PFB_CONFIG_0_TYPE_OLD1024_VAR_16BPP 0x00004220 /* RW--V */
-#define NV_PFB_CONFIG_0_TYPE_OLD1024_VAR_32BPP 0x00004320 /* RW--V */
-#define NV_PFB_CONFIG_0_TYPE_TETRIS 0x00002000 /* RW--V */
-#define NV_PFB_CONFIG_0_TYPE_NOTILING 0x00001114 /* RWI-V */
-#define NV_PFB_CONFIG_0_TETRIS_MODE 17:15 /* RWI-F */
-#define NV_PFB_CONFIG_0_TETRIS_MODE_PASS 0x00000000 /* RWI-V */
-#define NV_PFB_CONFIG_0_TETRIS_MODE_1 0x00000001 /* RW--V */
-#define NV_PFB_CONFIG_0_TETRIS_MODE_2 0x00000002 /* RW--V */
-#define NV_PFB_CONFIG_0_TETRIS_MODE_3 0x00000003 /* RW--V */
-#define NV_PFB_CONFIG_0_TETRIS_MODE_4 0x00000004 /* RW--V */
-#define NV_PFB_CONFIG_0_TETRIS_MODE_5 0x00000005 /* RW--V */
-#define NV_PFB_CONFIG_0_TETRIS_MODE_6 0x00000006 /* RW--V */
-#define NV_PFB_CONFIG_0_TETRIS_MODE_7 0x00000007 /* RW--V */
-#define NV_PFB_CONFIG_0_TETRIS_SHIFT 19:18 /* RWI-F */
-#define NV_PFB_CONFIG_0_TETRIS_SHIFT_0 0x00000000 /* RWI-V */
-#define NV_PFB_CONFIG_0_TETRIS_SHIFT_1 0x00000001 /* RW--V */
-#define NV_PFB_CONFIG_0_TETRIS_SHIFT_2 0x00000002 /* RW--V */
-#define NV_PFB_CONFIG_0_BANK_SWAP 22:20 /* RWI-F */
-#define NV_PFB_CONFIG_0_BANK_SWAP_OFF 0x00000000 /* RWI-V */
-#define NV_PFB_CONFIG_0_BANK_SWAP_1M 0x00000001 /* RW--V */
-#define NV_PFB_CONFIG_0_BANK_SWAP_2M 0x00000005 /* RW--V */
-#define NV_PFB_CONFIG_0_BANK_SWAP_4M 0x00000007 /* RW--V */
-#define NV_PFB_CONFIG_0_UNUSED 23:23 /* RW-VF */
-#define NV_PFB_CONFIG_0_SCRAMBLE_EN 29:29 /* RWIVF */
-#define NV_PFB_CONFIG_0_SCRAMBLE_EN_INIT 0x00000000 /* RW--V */
-#define NV_PFB_CONFIG_0_SCRAMBLE_ACTIVE 0x00000001 /* RW--V */
-#define NV_PFB_CONFIG_0_PRAMIN_WR 28:28 /* RWIVF */
-#define NV_PFB_CONFIG_0_PRAMIN_WR_INIT 0x00000000 /* RW--V */
-#define NV_PFB_CONFIG_0_PRAMIN_WR_DISABLED 0x00000001 /* RW--V */
-#define NV_PFB_CONFIG_0_PRAMIN_WR_MASK 27:24 /* RWIVF */
-#define NV_PFB_CONFIG_0_PRAMIN_WR_MASK_INIT 0x00000000 /* RWI-V */
-#define NV_PFB_CONFIG_0_PRAMIN_WR_MASK_CLEAR 0x0000000f /* RWI-V */
-#define NV_PFB_CONFIG_1 0x00100204 /* RW-4R */
-#define NV_PFB_RTL 0x00100300 /* RW-4R */
-#define NV_PFB_RTL_H 0:0 /* RWIUF */
-#define NV_PFB_RTL_H_DEFAULT 0x00000000 /* RWI-V */
-#define NV_PFB_RTL_MC 1:1 /* RWIUF */
-#define NV_PFB_RTL_MC_DEFAULT 0x00000000 /* RWI-V */
-#define NV_PFB_RTL_V 2:2 /* RWIUF */
-#define NV_PFB_RTL_V_DEFAULT 0x00000000 /* RWI-V */
-#define NV_PFB_RTL_G 3:3 /* RWIUF */
-#define NV_PFB_RTL_G_DEFAULT 0x00000000 /* RWI-V */
-#define NV_PFB_RTL_GB 4:4 /* RWIUF */
-#define NV_PFB_RTL_GB_DEFAULT 0x00000000 /* RWI-V */
-#define NV_PFB_CONFIG_0_RESOLUTION 5:0 /* RWIVF */
-#define NV_PFB_CONFIG_0_RESOLUTION_320_PIXELS 0x0000000a /* RW--V */
-#define NV_PFB_CONFIG_0_RESOLUTION_400_PIXELS 0x0000000d /* RW--V */
-#define NV_PFB_CONFIG_0_RESOLUTION_480_PIXELS 0x0000000f /* RW--V */
-#define NV_PFB_CONFIG_0_RESOLUTION_512_PIXELS 0x00000010 /* RW--V */
-#define NV_PFB_CONFIG_0_RESOLUTION_640_PIXELS 0x00000014 /* RW--V */
-#define NV_PFB_CONFIG_0_RESOLUTION_800_PIXELS 0x00000019 /* RW--V */
-#define NV_PFB_CONFIG_0_RESOLUTION_960_PIXELS 0x0000001e /* RW--V */
-#define NV_PFB_CONFIG_0_RESOLUTION_1024_PIXELS 0x00000020 /* RW--V */
-#define NV_PFB_CONFIG_0_RESOLUTION_1152_PIXELS 0x00000024 /* RW--V */
-#define NV_PFB_CONFIG_0_RESOLUTION_1280_PIXELS 0x00000028 /* RW--V */
-#define NV_PFB_CONFIG_0_RESOLUTION_1600_PIXELS 0x00000032 /* RW--V */
-#define NV_PFB_CONFIG_0_RESOLUTION_DEFAULT 0x00000014 /* RWI-V */
-#define NV_PFB_CONFIG_0_PIXEL_DEPTH 9:8 /* RWIVF */
-#define NV_PFB_CONFIG_0_PIXEL_DEPTH_8_BITS 0x00000001 /* RW--V */
-#define NV_PFB_CONFIG_0_PIXEL_DEPTH_16_BITS 0x00000002 /* RW--V */
-#define NV_PFB_CONFIG_0_PIXEL_DEPTH_32_BITS 0x00000003 /* RW--V */
-#define NV_PFB_CONFIG_0_PIXEL_DEPTH_DEFAULT 0x00000001 /* RWI-V */
-#define NV_PFB_CONFIG_0_TILING 12:12 /* RWIVF */
-#define NV_PFB_CONFIG_0_TILING_ENABLED 0x00000000 /* RW--V */
-#define NV_PFB_CONFIG_0_TILING_DISABLED 0x00000001 /* RWI-V */
-#define NV_PFB_CONFIG_1_SGRAM100 3:3 /* RWIVF */
-#define NV_PFB_CONFIG_1_SGRAM100_ENABLED 0x00000000 /* RWI-V */
-#define NV_PFB_CONFIG_1_SGRAM100_DISABLED 0x00000001 /* RW--V */
-#define NV_PFB_DEBUG_0_CKE_ALWAYSON 29:29 /* RWIVF */
-#define NV_PFB_DEBUG_0_CKE_ALWAYSON_OFF 0x00000000 /* RW--V */
-#define NV_PFB_DEBUG_0_CKE_ALWAYSON_ON 0x00000001 /* RWI-V */
-
-#define NV_PEXTDEV 0x00101FFF:0x00101000 /* RW--D */
-#define NV_PEXTDEV_BOOT_0 0x00101000 /* R--4R */
-#define NV_PEXTDEV_BOOT_0_STRAP_BUS_SPEED 0:0 /* R-XVF */
-#define NV_PEXTDEV_BOOT_0_STRAP_BUS_SPEED_33MHZ 0x00000000 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_BUS_SPEED_66MHZ 0x00000001 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_SUB_VENDOR 1:1 /* R-XVF */
-#define NV_PEXTDEV_BOOT_0_STRAP_SUB_VENDOR_NO_BIOS 0x00000000 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_SUB_VENDOR_BIOS 0x00000001 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_RAM_TYPE 3:2 /* R-XVF */
-#define NV_PEXTDEV_BOOT_0_STRAP_RAM_TYPE_SGRAM_256K 0x00000000 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_RAM_TYPE_SGRAM_512K_2BANK 0x00000001 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_RAM_TYPE_SGRAM_512K_4BANK 0x00000002 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_RAM_TYPE_1024K_2BANK 0x00000003 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_RAM_WIDTH 4:4 /* R-XVF */
-#define NV_PEXTDEV_BOOT_0_STRAP_RAM_WIDTH_64 0x00000000 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_RAM_WIDTH_128 0x00000001 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_BUS_TYPE 5:5 /* R-XVF */
-#define NV_PEXTDEV_BOOT_0_STRAP_BUS_TYPE_PCI 0x00000000 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_BUS_TYPE_AGP 0x00000001 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_CRYSTAL 6:6 /* R-XVF */
-#define NV_PEXTDEV_BOOT_0_STRAP_CRYSTAL_13500K 0x00000000 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_CRYSTAL_14318180 0x00000001 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_TVMODE 8:7 /* R-XVF */
-#define NV_PEXTDEV_BOOT_0_STRAP_TVMODE_SECAM 0x00000000 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_TVMODE_NTSC 0x00000001 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_TVMODE_PAL 0x00000002 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_TVMODE_DISABLED 0x00000003 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_OVERWRITE 11:11 /* RWIVF */
-#define NV_PEXTDEV_BOOT_0_STRAP_OVERWRITE_DISABLED 0x00000000 /* RWI-V */
-#define NV_PEXTDEV_BOOT_0_STRAP_OVERWRITE_ENABLED 0x00000001 /* RW--V */
-
-/* Extras */
-#define NV_PRAMIN 0x007FFFFF:0x00700000 /* RW--M */
-/*#define NV_PRAMIN 0x00FFFFFF:0x00C00000*/
-#define NV_PNVM 0x01FFFFFF:0x01000000 /* RW--M */
-/*#define NV_PNVM 0x00BFFFFF:0x00800000*/
-#define NV_CHAN0 0x0080ffff:0x00800000
-
-/* FIFO subchannels */
-#define NV_UROP 0x43
-#define NV_UCHROMA 0x57
-#define NV_UCLIP 0x19
-#define NV_UPATT 0x18
-#define NV_ULIN 0x5C
-#define NV_UTRI 0x5D
-#define NV_URECT 0x5E
-#define NV_UBLIT 0x5F
-#define NV_UGLYPH 0x4B
-
-#endif /*__NV4REF_H__*/
-
diff --git a/drivers/video/riva/nv_driver.c b/drivers/video/riva/nv_driver.c
index be630a0..a110268 100644
--- a/drivers/video/riva/nv_driver.c
+++ b/drivers/video/riva/nv_driver.c
@@ -231,12 +231,14 @@
case NV_ARCH_30:
if(chipset == NV_CHIP_IGEFORCE2) {
- dev = pci_find_slot(0, 1);
+ dev = pci_get_bus_and_slot(0, 1);
pci_read_config_dword(dev, 0x7C, &amt);
+ pci_dev_put(dev);
memlen = (((amt >> 6) & 31) + 1) * 1024;
} else if (chipset == NV_CHIP_0x01F0) {
- dev = pci_find_slot(0, 1);
+ dev = pci_get_bus_and_slot(0, 1);
pci_read_config_dword(dev, 0x84, &amt);
+ pci_dev_put(dev);
memlen = (((amt >> 4) & 127) + 1) * 1024;
} else {
switch ((NV_RD32(chip->PFB, 0x0000020C) >> 20) &
diff --git a/drivers/video/riva/riva_hw.c b/drivers/video/riva/riva_hw.c
index e0b8c52..70bfd78 100644
--- a/drivers/video/riva/riva_hw.c
+++ b/drivers/video/riva/riva_hw.c
@@ -1118,8 +1118,9 @@
unsigned int uMClkPostDiv;
struct pci_dev *dev;
- dev = pci_find_slot(0, 3);
+ dev = pci_get_bus_and_slot(0, 3);
pci_read_config_dword(dev, 0x6C, &uMClkPostDiv);
+ pci_dev_put(dev);
uMClkPostDiv = (uMClkPostDiv >> 8) & 0xf;
if(!uMClkPostDiv) uMClkPostDiv = 4;
@@ -1132,8 +1133,9 @@
sim_data.enable_video = 0;
sim_data.enable_mp = 0;
- dev = pci_find_slot(0, 1);
+ dev = pci_get_bus_and_slot(0, 1);
pci_read_config_dword(dev, 0x7C, &sim_data.memory_type);
+ pci_dev_put(dev);
sim_data.memory_type = (sim_data.memory_type >> 12) & 1;
sim_data.memory_width = 64;
@@ -2112,12 +2114,14 @@
* Fill in chip configuration.
*/
if(chipset == NV_CHIP_IGEFORCE2) {
- dev = pci_find_slot(0, 1);
+ dev = pci_get_bus_and_slot(0, 1);
pci_read_config_dword(dev, 0x7C, &amt);
+ pci_dev_put(dev);
chip->RamAmountKBytes = (((amt >> 6) & 31) + 1) * 1024;
} else if(chipset == NV_CHIP_0x01F0) {
- dev = pci_find_slot(0, 1);
+ dev = pci_get_bus_and_slot(0, 1);
pci_read_config_dword(dev, 0x84, &amt);
+ pci_dev_put(dev);
chip->RamAmountKBytes = (((amt >> 4) & 127) + 1) * 1024;
} else {
switch ((NV_RD32(chip->PFB, 0x0000020C) >> 20) & 0x000000FF)
diff --git a/drivers/video/riva/rivafb-i2c.c b/drivers/video/riva/rivafb-i2c.c
index 0405e83..76e6ce3 100644
--- a/drivers/video/riva/rivafb-i2c.c
+++ b/drivers/video/riva/rivafb-i2c.c
@@ -88,13 +88,16 @@
return val;
}
-static int riva_setup_i2c_bus(struct riva_i2c_chan *chan, const char *name)
+static int __devinit riva_setup_i2c_bus(struct riva_i2c_chan *chan,
+ const char *name,
+ unsigned int i2c_class)
{
int rc;
strcpy(chan->adapter.name, name);
chan->adapter.owner = THIS_MODULE;
chan->adapter.id = I2C_HW_B_RIVA;
+ chan->adapter.class = i2c_class;
chan->adapter.algo_data = &chan->algo;
chan->adapter.dev.parent = &chan->par->pdev->dev;
chan->algo.setsda = riva_gpio_setsda;
@@ -124,42 +127,38 @@
return rc;
}
-void riva_create_i2c_busses(struct riva_par *par)
+void __devinit riva_create_i2c_busses(struct riva_par *par)
{
- par->bus = 3;
-
par->chan[0].par = par;
par->chan[1].par = par;
par->chan[2].par = par;
- par->chan[0].ddc_base = 0x3e;
- par->chan[1].ddc_base = 0x36;
+ par->chan[0].ddc_base = 0x36;
+ par->chan[1].ddc_base = 0x3e;
par->chan[2].ddc_base = 0x50;
- riva_setup_i2c_bus(&par->chan[0], "BUS1");
- riva_setup_i2c_bus(&par->chan[1], "BUS2");
- riva_setup_i2c_bus(&par->chan[2], "BUS3");
+ riva_setup_i2c_bus(&par->chan[0], "BUS1", I2C_CLASS_HWMON);
+ riva_setup_i2c_bus(&par->chan[1], "BUS2", 0);
+ riva_setup_i2c_bus(&par->chan[2], "BUS3", 0);
}
void riva_delete_i2c_busses(struct riva_par *par)
{
- if (par->chan[0].par)
- i2c_del_adapter(&par->chan[0].adapter);
- par->chan[0].par = NULL;
+ int i;
- if (par->chan[1].par)
- i2c_del_adapter(&par->chan[1].adapter);
- par->chan[1].par = NULL;
-
- if (par->chan[2].par)
- i2c_del_adapter(&par->chan[2].adapter);
- par->chan[2].par = NULL;
+ for (i = 0; i < 3; i++) {
+ if (!par->chan[i].par)
+ continue;
+ i2c_del_adapter(&par->chan[i].adapter);
+ par->chan[i].par = NULL;
+ }
}
-int riva_probe_i2c_connector(struct riva_par *par, int conn, u8 **out_edid)
+int __devinit riva_probe_i2c_connector(struct riva_par *par, int conn, u8 **out_edid)
{
u8 *edid = NULL;
- edid = fb_ddc_read(&par->chan[conn-1].adapter);
+ if (par->chan[conn].par)
+ edid = fb_ddc_read(&par->chan[conn].adapter);
if (out_edid)
*out_edid = edid;
diff --git a/drivers/video/riva/rivafb.h b/drivers/video/riva/rivafb.h
index 48ead6d..d9f107b 100644
--- a/drivers/video/riva/rivafb.h
+++ b/drivers/video/riva/rivafb.h
@@ -4,7 +4,6 @@
#include <linux/fb.h>
#include <video/vga.h>
#include <linux/i2c.h>
-#include <linux/i2c-id.h>
#include <linux/i2c-algo-bit.h>
#include "riva_hw.h"
@@ -61,7 +60,6 @@
Bool SecondCRTC;
int FlatPanel;
struct pci_dev *pdev;
- int bus;
int cursor_reset;
#ifdef CONFIG_MTRR
struct { int vram; int vram_valid; } mtrr;
diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c
index 3091b20..756fafb 100644
--- a/drivers/video/s3fb.c
+++ b/drivers/video/s3fb.c
@@ -65,7 +65,7 @@
static const struct svga_pll s3_pll = {3, 129, 3, 33, 0, 3,
- 60000, 240000, 14318};
+ 35000, 240000, 14318};
static const int s3_memsizes[] = {4096, 0, 3072, 8192, 2048, 6144, 1024, 512};
@@ -164,7 +164,7 @@
static void s3fb_settile_fast(struct fb_info *info, struct fb_tilemap *map)
{
const u8 *font = map->data;
- u8* fb = (u8 *) info->screen_base;
+ u8 __iomem *fb = (u8 __iomem *) info->screen_base;
int i, c;
if ((map->width != 8) || (map->height != 16) ||
@@ -177,20 +177,19 @@
fb += 2;
for (i = 0; i < map->height; i++) {
for (c = 0; c < map->length; c++) {
- fb[c * 4] = font[c * map->height + i];
+ fb_writeb(font[c * map->height + i], fb + c * 4);
}
fb += 1024;
}
}
-
-
static struct fb_tile_ops s3fb_tile_ops = {
.fb_settile = svga_settile,
.fb_tilecopy = svga_tilecopy,
.fb_tilefill = svga_tilefill,
.fb_tileblit = svga_tileblit,
.fb_tilecursor = svga_tilecursor,
+ .fb_get_tilemax = svga_get_tilemax,
};
static struct fb_tile_ops s3fb_fast_tile_ops = {
@@ -199,6 +198,7 @@
.fb_tilefill = svga_tilefill,
.fb_tileblit = svga_tileblit,
.fb_tilecursor = svga_tilecursor,
+ .fb_get_tilemax = svga_get_tilemax,
};
@@ -326,8 +326,13 @@
{
u16 m, n, r;
u8 regval;
+ int rv;
- svga_compute_pll(&s3_pll, 1000000000 / pixclock, &m, &n, &r, info->node);
+ rv = svga_compute_pll(&s3_pll, 1000000000 / pixclock, &m, &n, &r, info->node);
+ if (rv < 0) {
+ printk(KERN_ERR "fb%d: cannot set requested pixclock, keeping old value\n", info->node);
+ return;
+ }
/* Set VGA misc register */
regval = vga_r(NULL, VGA_MIS_R);
@@ -449,6 +454,10 @@
info->flags &= ~FBINFO_MISC_TILEBLITTING;
info->tileops = NULL;
+ /* in 4bpp supports 8p wide tiles only, any tiles otherwise */
+ info->pixmap.blit_x = (bpp == 4) ? (1 << (8 - 1)) : (~(u32)0);
+ info->pixmap.blit_y = ~(u32)0;
+
offset_value = (info->var.xres_virtual * bpp) / 64;
screen_size = info->var.yres_virtual * info->fix.line_length;
} else {
@@ -458,6 +467,10 @@
info->flags |= FBINFO_MISC_TILEBLITTING;
info->tileops = fasttext ? &s3fb_fast_tile_ops : &s3fb_tile_ops;
+ /* supports 8x16 tiles only */
+ info->pixmap.blit_x = 1 << (8 - 1);
+ info->pixmap.blit_y = 1 << (16 - 1);
+
offset_value = info->var.xres_virtual / 16;
screen_size = (info->var.xres_virtual * info->var.yres_virtual) / 64;
}
@@ -656,7 +669,7 @@
value = ((value * hmul) / 8) - 5;
vga_wcrt(NULL, 0x3C, (value + 1) / 2);
- memset((u8*)info->screen_base, 0x00, screen_size);
+ memset_io(info->screen_base, 0x00, screen_size);
/* Device and screen back on */
svga_wcrt_mask(0x17, 0x80, 0x80);
svga_wseq_mask(0x01, 0x00, 0x20);
@@ -699,7 +712,7 @@
break;
case 16:
if (regno >= 16)
- return -EINVAL;
+ return 0;
if (fb->var.green.length == 5)
((u32*)fb->pseudo_palette)[regno] = ((red & 0xF800) >> 1) |
@@ -712,9 +725,9 @@
case 24:
case 32:
if (regno >= 16)
- return -EINVAL;
+ return 0;
- ((u32*)fb->pseudo_palette)[regno] = ((transp & 0xFF00) << 16) | ((red & 0xFF00) << 8) |
+ ((u32*)fb->pseudo_palette)[regno] = ((red & 0xFF00) << 8) |
(green & 0xFF00) | ((blue & 0xFF00) >> 8);
break;
default:
@@ -767,12 +780,6 @@
unsigned int offset;
- /* Validate the offsets */
- if ((var->xoffset + var->xres) > var->xres_virtual)
- return -EINVAL;
- if ((var->yoffset + var->yres) > var->yres_virtual)
- return -EINVAL;
-
/* Calculate the offset */
if (var->bits_per_pixel == 0) {
offset = (var->yoffset / 16) * (var->xres_virtual / 2) + (var->xoffset / 2);
@@ -789,6 +796,23 @@
return 0;
}
+/* Get capabilities of accelerator based on the mode */
+
+static void s3fb_get_caps(struct fb_info *info, struct fb_blit_caps *caps,
+ struct fb_var_screeninfo *var)
+{
+ if (var->bits_per_pixel == 0) {
+ /* can only support 256 8x16 bitmap */
+ caps->x = 1 << (8 - 1);
+ caps->y = 1 << (16 - 1);
+ caps->len = 256;
+ } else {
+ caps->x = ~(u32)0;
+ caps->y = ~(u32)0;
+ caps->len = ~(u32)0;
+ }
+}
+
/* ------------------------------------------------------------------------- */
/* Frame buffer operations */
@@ -805,6 +829,7 @@
.fb_fillrect = s3fb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = s3fb_imageblit,
+ .fb_get_caps = s3fb_get_caps,
};
/* ------------------------------------------------------------------------- */
@@ -1061,6 +1086,7 @@
{
struct fb_info *info = pci_get_drvdata(dev);
struct s3fb_info *par = info->par;
+ int err;
dev_info(&(dev->dev), "resume\n");
@@ -1075,7 +1101,13 @@
pci_set_power_state(dev, PCI_D0);
pci_restore_state(dev);
- pci_enable_device(dev);
+ err = pci_enable_device(dev);
+ if (err) {
+ mutex_unlock(&(par->open_lock));
+ release_console_sem();
+ dev_err(&(dev->dev), "error %d enabling device for resume\n", err);
+ return err;
+ }
pci_set_master(dev);
s3fb_set_par(info);
diff --git a/drivers/video/savage/savagefb-i2c.c b/drivers/video/savage/savagefb-i2c.c
index 8db066c..35c1ce6 100644
--- a/drivers/video/savage/savagefb-i2c.c
+++ b/drivers/video/savage/savagefb-i2c.c
@@ -41,10 +41,6 @@
#define SAVAGE4_I2C_SCL_IN 0x00000008
#define SAVAGE4_I2C_SDA_IN 0x00000010
-#define SET_CR_IX(base, val) writeb((val), base + 0x8000 + VGA_CR_IX)
-#define SET_CR_DATA(base, val) writeb((val), base + 0x8000 + VGA_CR_DATA)
-#define GET_CR_DATA(base) readb(base + 0x8000 + VGA_CR_DATA)
-
static void savage4_gpio_setscl(void *data, int val)
{
struct savagefb_i2c_chan *chan = data;
@@ -92,15 +88,15 @@
struct savagefb_i2c_chan *chan = data;
u32 r;
- SET_CR_IX(chan->ioaddr, chan->reg);
- r = GET_CR_DATA(chan->ioaddr);
+ r = VGArCR(chan->reg, chan->par);
r |= PROSAVAGE_I2C_ENAB;
if (val) {
r |= PROSAVAGE_I2C_SCL_OUT;
} else {
r &= ~PROSAVAGE_I2C_SCL_OUT;
}
- SET_CR_DATA(chan->ioaddr, r);
+
+ VGAwCR(chan->reg, r, chan->par);
}
static void prosavage_gpio_setsda(void* data, int val)
@@ -108,31 +104,29 @@
struct savagefb_i2c_chan *chan = data;
unsigned int r;
- SET_CR_IX(chan->ioaddr, chan->reg);
- r = GET_CR_DATA(chan->ioaddr);
+ r = VGArCR(chan->reg, chan->par);
r |= PROSAVAGE_I2C_ENAB;
if (val) {
r |= PROSAVAGE_I2C_SDA_OUT;
} else {
r &= ~PROSAVAGE_I2C_SDA_OUT;
}
- SET_CR_DATA(chan->ioaddr, r);
+
+ VGAwCR(chan->reg, r, chan->par);
}
static int prosavage_gpio_getscl(void* data)
{
struct savagefb_i2c_chan *chan = data;
- SET_CR_IX(chan->ioaddr, chan->reg);
- return (0 != (GET_CR_DATA(chan->ioaddr) & PROSAVAGE_I2C_SCL_IN));
+ return (VGArCR(chan->reg, chan->par) & PROSAVAGE_I2C_SCL_IN) ? 1 : 0;
}
static int prosavage_gpio_getsda(void* data)
{
struct savagefb_i2c_chan *chan = data;
- SET_CR_IX(chan->ioaddr, chan->reg);
- return (0 != (GET_CR_DATA(chan->ioaddr) & PROSAVAGE_I2C_SDA_IN));
+ return (VGArCR(chan->reg, chan->par) & PROSAVAGE_I2C_SDA_IN) ? 1 : 0;
}
static int savage_setup_i2c_bus(struct savagefb_i2c_chan *chan,
diff --git a/drivers/video/savage/savagefb.h b/drivers/video/savage/savagefb.h
index e648a6c..8bfdfc3 100644
--- a/drivers/video/savage/savagefb.h
+++ b/drivers/video/savage/savagefb.h
@@ -15,6 +15,8 @@
#include <linux/i2c.h>
#include <linux/i2c-id.h>
#include <linux/i2c-algo-bit.h>
+#include <linux/mutex.h>
+#include <video/vga.h>
#include "../edid.h"
#ifdef SAVAGEFB_DEBUG
@@ -189,8 +191,12 @@
struct savagefb_i2c_chan chan;
struct savage_reg state;
struct savage_reg save;
+ struct savage_reg initial;
+ struct vgastate vgastate;
+ struct mutex open_lock;
unsigned char *edid;
u32 pseudo_palette[16];
+ u32 open_count;
int paletteEnabled;
int pm_state;
int display_type;
@@ -203,7 +209,7 @@
int clock[4];
int MCLK, REFCLK, LCDclk;
struct {
- u8 __iomem *vbase;
+ void __iomem *vbase;
u32 pbase;
u32 len;
#ifdef CONFIG_MTRR
@@ -212,7 +218,7 @@
} video;
struct {
- volatile u8 __iomem *vbase;
+ void __iomem *vbase;
u32 pbase;
u32 len;
} mmio;
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c
index 0166ec2..3d7507a 100644
--- a/drivers/video/savage/savagefb_driver.c
+++ b/drivers/video/savage/savagefb_driver.c
@@ -1623,8 +1623,46 @@
savagefb_blank(FB_BLANK_UNBLANK, info);
}
+static int savagefb_open(struct fb_info *info, int user)
+{
+ struct savagefb_par *par = info->par;
+
+ mutex_lock(&par->open_lock);
+
+ if (!par->open_count) {
+ memset(&par->vgastate, 0, sizeof(par->vgastate));
+ par->vgastate.flags = VGA_SAVE_CMAP | VGA_SAVE_FONTS |
+ VGA_SAVE_MODE;
+ par->vgastate.vgabase = par->mmio.vbase + 0x8000;
+ save_vga(&par->vgastate);
+ savage_get_default_par(par, &par->initial);
+ }
+
+ par->open_count++;
+ mutex_unlock(&par->open_lock);
+ return 0;
+}
+
+static int savagefb_release(struct fb_info *info, int user)
+{
+ struct savagefb_par *par = info->par;
+
+ mutex_lock(&par->open_lock);
+
+ if (par->open_count == 1) {
+ savage_set_default_par(par, &par->initial);
+ restore_vga(&par->vgastate);
+ }
+
+ par->open_count--;
+ mutex_unlock(&par->open_lock);
+ return 0;
+}
+
static struct fb_ops savagefb_ops = {
.owner = THIS_MODULE,
+ .fb_open = savagefb_open,
+ .fb_release = savagefb_release,
.fb_check_var = savagefb_check_var,
.fb_set_par = savagefb_set_par,
.fb_setcolreg = savagefb_setcolreg,
@@ -2173,6 +2211,7 @@
if (!info)
return -ENOMEM;
par = info->par;
+ mutex_init(&par->open_lock);
err = pci_enable_device(dev);
if (err)
goto failed_enable;
diff --git a/drivers/video/sis/osdef.h b/drivers/video/sis/osdef.h
index d048bd3..c149278 100644
--- a/drivers/video/sis/osdef.h
+++ b/drivers/video/sis/osdef.h
@@ -58,9 +58,6 @@
#define SIS_LINUX_KERNEL /* Linux kernel framebuffer */
#undef SIS_XORG_XF86 /* XFree86/X.org */
-#undef SIS_LINUX_KERNEL_24
-#undef SIS_LINUX_KERNEL_26
-
#ifdef OutPortByte
#undef OutPortByte
#endif
@@ -100,8 +97,6 @@
#define SIS315H
#endif
-#define SIS_LINUX_KERNEL_26
-
#if !defined(SIS300) && !defined(SIS315H)
#warning Neither CONFIG_FB_SIS_300 nor CONFIG_FB_SIS_315 is set
#warning sisfb will not work!
diff --git a/drivers/video/sis/sis.h b/drivers/video/sis/sis.h
index 7d5ee21..d5e2d9c 100644
--- a/drivers/video/sis/sis.h
+++ b/drivers/video/sis/sis.h
@@ -27,11 +27,7 @@
#include <linux/version.h>
#include "osdef.h"
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
#include <video/sisfb.h>
-#else
-#include <linux/sisfb.h>
-#endif
#include "vgatypes.h"
#include "vstruct.h"
@@ -40,33 +36,17 @@
#define VER_MINOR 8
#define VER_LEVEL 9
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
#include <linux/spinlock.h>
-#define SIS_PCI_GET_CLASS(a, b) pci_get_class(a, b)
-#define SIS_PCI_GET_DEVICE(a,b,c) pci_get_device(a,b,c)
-#define SIS_PCI_GET_SLOT(a,b) pci_get_slot(a,b)
-#define SIS_PCI_PUT_DEVICE(a) pci_dev_put(a)
+
#ifdef CONFIG_COMPAT
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,10)
#include <linux/ioctl32.h>
#define SIS_OLD_CONFIG_COMPAT
#else
-#include <linux/smp_lock.h>
#define SIS_NEW_CONFIG_COMPAT
#endif
#endif /* CONFIG_COMPAT */
-#else /* 2.4 */
-#define SIS_PCI_GET_CLASS(a, b) pci_find_class(a, b)
-#define SIS_PCI_GET_DEVICE(a,b,c) pci_find_device(a,b,c)
-#define SIS_PCI_GET_SLOT(a,b) pci_find_slot(a,b)
-#define SIS_PCI_PUT_DEVICE(a)
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19)
-#ifdef __x86_64__ /* Shouldn't we check for CONFIG_IA32_EMULATION here? */
-#include <asm/ioctl32.h>
-#define SIS_OLD_CONFIG_COMPAT
-#endif
-#endif
-#endif /* 2.4 */
+
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
#define SIS_IOTYPE1 void __iomem
#define SIS_IOTYPE2 __iomem
@@ -498,26 +478,8 @@
struct fb_var_screeninfo default_var;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
struct fb_fix_screeninfo sisfb_fix;
u32 pseudo_palette[17];
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- struct display sis_disp;
- struct display_switch sisfb_sw;
- struct {
- u16 red, green, blue, pad;
- } sis_palette[256];
- union {
-#ifdef FBCON_HAS_CFB16
- u16 cfb16[16];
-#endif
-#ifdef FBCON_HAS_CFB32
- u32 cfb32[16];
-#endif
- } sis_fbcon_cmap;
-#endif
struct sisfb_monitor {
u16 hmin;
@@ -538,10 +500,6 @@
int mni; /* Mode number index */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- int currcon;
-#endif
-
unsigned long video_size;
unsigned long video_base;
unsigned long mmio_size;
@@ -578,9 +536,6 @@
int sisfb_tvplug;
int sisfb_tvstd;
int sisfb_nocrt2rate;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- int sisfb_inverse;
-#endif
u32 heapstart; /* offset */
SIS_IOTYPE1 *sisfb_heap_start; /* address */
@@ -646,9 +601,7 @@
int modechanged;
unsigned char modeprechange;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
u8 sisfb_lastrates[128];
-#endif
int newrom;
int haveXGIROM;
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 01197d7..a30e1e1 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -37,7 +37,6 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
-#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/errno.h>
#include <linux/string.h>
@@ -1948,7 +1947,7 @@
default: return NULL;
}
for(i = 0; i < nbridgenum; i++) {
- if((pdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI,
+ if((pdev = pci_get_device(PCI_VENDOR_ID_SI,
nbridgeids[nbridgeidx+i], NULL)))
break;
}
@@ -4613,9 +4612,9 @@
unsigned short temp;
int ret = 0;
- while((pdev = SIS_PCI_GET_CLASS(PCI_CLASS_BRIDGE_HOST, pdev))) {
+ while((pdev = pci_get_class(PCI_CLASS_BRIDGE_HOST, pdev))) {
temp = pdev->vendor;
- SIS_PCI_PUT_DEVICE(pdev);
+ pci_dev_put(pdev);
if(temp == pcivendor) {
ret = 1;
break;
@@ -5154,24 +5153,24 @@
if(reg & 0x80) v2 |= 0x80;
v2 |= 0x01;
- if((mypdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0730, NULL))) {
- SIS_PCI_PUT_DEVICE(mypdev);
+ if((mypdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0730, NULL))) {
+ pci_dev_put(mypdev);
if(((v2 & 0x06) == 2) || ((v2 & 0x06) == 4))
v2 &= 0xf9;
v2 |= 0x08;
v1 &= 0xfe;
} else {
- mypdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0735, NULL);
+ mypdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0735, NULL);
if(!mypdev)
- mypdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0645, NULL);
+ mypdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0645, NULL);
if(!mypdev)
- mypdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0650, NULL);
+ mypdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0650, NULL);
if(mypdev) {
pci_read_config_dword(mypdev, 0x94, ®d);
regd &= 0xfffffeff;
pci_write_config_dword(mypdev, 0x94, regd);
v1 &= 0xfe;
- SIS_PCI_PUT_DEVICE(mypdev);
+ pci_dev_put(mypdev);
} else if(sisfb_find_host_bridge(ivideo, pdev, PCI_VENDOR_ID_SI)) {
v1 &= 0xfe;
} else if(sisfb_find_host_bridge(ivideo, pdev, 0x1106) ||
@@ -5194,13 +5193,13 @@
if( (!(v1 & 0x02)) && (v2 & 0x30) && (regd < 0xcf) )
setSISIDXREG(SISCR, 0x5f, 0xf1, 0x01);
- if((mypdev = SIS_PCI_GET_DEVICE(0x10de, 0x01e0, NULL))) {
+ if((mypdev = pci_get_device(0x10de, 0x01e0, NULL))) {
/* TODO: set CR5f &0xf1 | 0x01 for version 6570
* of nforce 2 ROM
*/
if(0)
setSISIDXREG(SISCR, 0x5f, 0xf1, 0x01);
- SIS_PCI_PUT_DEVICE(mypdev);
+ pci_dev_put(mypdev);
}
}
@@ -5236,9 +5235,9 @@
setSISIDXREG(SISCR, 0x75, 0xe0, bios[0x4ff] & 0x1f);
setSISIDXREG(SISCR, 0x76, 0xe0, bios[0x500] & 0x1f);
v1 = bios[0x501];
- if((mypdev = SIS_PCI_GET_DEVICE(0x8086, 0x2530, NULL))) {
+ if((mypdev = pci_get_device(0x8086, 0x2530, NULL))) {
v1 = 0xf0;
- SIS_PCI_PUT_DEVICE(mypdev);
+ pci_dev_put(mypdev);
}
outSISIDXREG(SISCR, 0x77, v1);
}
@@ -5947,7 +5946,7 @@
if(!ivideo->sisvga_enabled) {
if(pci_enable_device(pdev)) {
- if(ivideo->nbridge) SIS_PCI_PUT_DEVICE(ivideo->nbridge);
+ if(ivideo->nbridge) pci_dev_put(ivideo->nbridge);
pci_set_drvdata(pdev, NULL);
kfree(sis_fb_info);
return -EIO;
@@ -5974,7 +5973,7 @@
"requiring Chrontel/GPIO setup\n",
mychswtable[i].vendorName,
mychswtable[i].cardName);
- ivideo->lpcdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0008, NULL);
+ ivideo->lpcdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0008, NULL);
break;
}
i++;
@@ -5984,7 +5983,7 @@
#ifdef CONFIG_FB_SIS_315
if((ivideo->chip == SIS_760) && (ivideo->nbridge)) {
- ivideo->lpcdev = SIS_PCI_GET_SLOT(ivideo->nbridge->bus, (2 << 3));
+ ivideo->lpcdev = pci_get_slot(ivideo->nbridge->bus, (2 << 3));
}
#endif
@@ -6149,9 +6148,9 @@
error_2: release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
error_3: vfree(ivideo->bios_abase);
if(ivideo->lpcdev)
- SIS_PCI_PUT_DEVICE(ivideo->lpcdev);
+ pci_dev_put(ivideo->lpcdev);
if(ivideo->nbridge)
- SIS_PCI_PUT_DEVICE(ivideo->nbridge);
+ pci_dev_put(ivideo->nbridge);
pci_set_drvdata(pdev, NULL);
if(!ivideo->sisvga_enabled)
pci_disable_device(pdev);
@@ -6331,70 +6330,6 @@
sisfb_set_vparms(ivideo);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-
- /* ---------------- For 2.4: Now switch the mode ------------------ */
-
- printk(KERN_INFO "sisfb: Setting mode %dx%dx%d (%dHz)\n",
- ivideo->video_width, ivideo->video_height, ivideo->video_bpp,
- ivideo->refresh_rate);
-
- /* Determine whether or not acceleration is to be
- * used. Need to know before pre/post_set_mode()
- */
- ivideo->accel = 0;
- ivideo->default_var.accel_flags &= ~FB_ACCELF_TEXT;
- if(ivideo->sisfb_accel) {
- ivideo->accel = -1;
- ivideo->default_var.accel_flags |= FB_ACCELF_TEXT;
- }
-
- /* Now switch the mode */
- sisfb_pre_setmode(ivideo);
-
- if(SiSSetMode(&ivideo->SiS_Pr, ivideo->mode_no) == 0) {
- printk(KERN_ERR "sisfb: Fatal error: Setting mode[0x%x] failed\n",
- ivideo->mode_no);
- ret = -EINVAL;
- iounmap(ivideo->mmio_vbase);
- goto error_0;
- }
-
- outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
-
- sisfb_post_setmode(ivideo);
-
- /* Maximize regardless of sisfb_max at startup */
- ivideo->default_var.yres_virtual = 32767;
-
- /* Force reset of x virtual in crtc_to_var */
- ivideo->default_var.xres_virtual = 0;
-
- /* Copy mode timing to var */
- sisfb_crtc_to_var(ivideo, &ivideo->default_var);
-
- /* Find out about screen pitch */
- sisfb_calc_pitch(ivideo, &ivideo->default_var);
- sisfb_set_pitch(ivideo);
-
- /* Init the accelerator (does nothing currently) */
- sisfb_initaccel(ivideo);
-
- /* Init some fbinfo entries */
- sis_fb_info->node = -1;
- sis_fb_info->flags = FBINFO_FLAG_DEFAULT;
- sis_fb_info->fbops = &sisfb_ops;
- sis_fb_info->disp = &ivideo->sis_disp;
- sis_fb_info->blank = &sisfb_blank;
- sis_fb_info->switch_con = &sisfb_switch;
- sis_fb_info->updatevar = &sisfb_update_var;
- sis_fb_info->changevar = NULL;
- strcpy(sis_fb_info->fontname, sisfb_fontname);
-
- sisfb_set_disp(-1, &ivideo->default_var, sis_fb_info);
-
-#else /* --------- For 2.6: Setup a somewhat sane default var ------------ */
-
printk(KERN_INFO "sisfb: Default mode is %dx%dx%d (%dHz)\n",
ivideo->video_width, ivideo->video_height, ivideo->video_bpp,
ivideo->refresh_rate);
@@ -6454,7 +6389,6 @@
sis_fb_info->pseudo_palette = ivideo->pseudo_palette;
fb_alloc_cmap(&sis_fb_info->cmap, 256 , 0);
-#endif /* 2.6 */
printk(KERN_DEBUG "sisfb: Initial vbflags 0x%x\n", (int)ivideo->vbflags);
@@ -6564,10 +6498,10 @@
vfree(ivideo->bios_abase);
if(ivideo->lpcdev)
- SIS_PCI_PUT_DEVICE(ivideo->lpcdev);
+ pci_dev_put(ivideo->lpcdev);
if(ivideo->nbridge)
- SIS_PCI_PUT_DEVICE(ivideo->nbridge);
+ pci_dev_put(ivideo->nbridge);
#ifdef CONFIG_MTRR
/* Release MTRR region */
diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c
index bb96cb6..842b5cd 100644
--- a/drivers/video/skeletonfb.c
+++ b/drivers/video/skeletonfb.c
@@ -51,6 +51,7 @@
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/init.h>
+#include <linux/pci.h>
/*
* This is just simple sample code.
@@ -60,6 +61,11 @@
*/
/*
+ * Driver data
+ */
+static char *mode_option __devinitdata;
+
+/*
* If your driver supports multiple boards, you should make the
* below data types arrays, or allocate them dynamically (using kmalloc()).
*/
@@ -78,7 +84,7 @@
* if we don't use modedb. If we do use modedb see xxxfb_init how to use it
* to get a fb_var_screeninfo. Otherwise define a default var as well.
*/
-static struct fb_fix_screeninfo xxxfb_fix __initdata = {
+static struct fb_fix_screeninfo xxxfb_fix __devinitdata = {
.id = "FB's name",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_PSEUDOCOLOR,
@@ -142,7 +148,7 @@
*
* Returns negative errno on error, or zero on success.
*/
-static int xxxfb_open(const struct fb_info *info, int user)
+static int xxxfb_open(struct fb_info *info, int user)
{
return 0;
}
@@ -161,7 +167,7 @@
*
* Returns negative errno on error, or zero on success.
*/
-static int xxxfb_release(const struct fb_info *info, int user)
+static int xxxfb_release(struct fb_info *info, int user)
{
return 0;
}
@@ -278,7 +284,7 @@
*/
static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
unsigned blue, unsigned transp,
- const struct fb_info *info)
+ struct fb_info *info)
{
if (regno >= 256) /* no. of hw registers */
return -EINVAL;
@@ -416,7 +422,7 @@
* Returns negative errno on error, or zero on success.
*/
static int xxxfb_pan_display(struct fb_var_screeninfo *var,
- const struct fb_info *info)
+ struct fb_info *info)
{
/*
* If your hardware does not support panning, _do_ _not_ implement this
@@ -454,7 +460,7 @@
* Return !0 for any modes that are unimplemented.
*
*/
-static int xxxfb_blank(int blank_mode, const struct fb_info *info)
+static int xxxfb_blank(int blank_mode, struct fb_info *info)
{
/* ... */
return 0;
@@ -483,7 +489,7 @@
* depending on the rastering operation with the value of color which
* is in the current color depth format.
*/
-void xxfb_fillrect(struct fb_info *p, const struct fb_fillrect *region)
+void xxxfb_fillrect(struct fb_info *p, const struct fb_fillrect *region)
{
/* Meaning of struct fb_fillrect
*
@@ -623,19 +629,6 @@
}
/**
- * xxxfb_poll - NOT a required function. The purpose of this
- * function is to provide a way for some process
- * to wait until a specific hardware event occurs
- * for the framebuffer device.
- *
- * @info: frame buffer structure that represents a single frame buffer
- * @wait: poll table where we store process that await a event.
- */
-void xxxfb_poll(struct fb_info *info, poll_table *wait)
-{
-}
-
-/**
* xxxfb_sync - NOT a required function. Normally the accel engine
* for a graphics card take a specific amount of time.
* Often we have to wait for the accelerator to finish
@@ -647,21 +640,49 @@
* If the driver has implemented its own hardware-based drawing function,
* implementing this function is highly recommended.
*/
-void xxxfb_sync(struct fb_info *info)
+int xxxfb_sync(struct fb_info *info)
{
+ return 0;
}
/*
+ * Frame buffer operations
+ */
+
+static struct fb_ops xxxfb_ops = {
+ .owner = THIS_MODULE,
+ .fb_open = xxxfb_open,
+ .fb_read = xxxfb_read,
+ .fb_write = xxxfb_write,
+ .fb_release = xxxfb_release,
+ .fb_check_var = xxxfb_check_var,
+ .fb_set_par = xxxfb_set_par,
+ .fb_setcolreg = xxxfb_setcolreg,
+ .fb_blank = xxxfb_blank,
+ .fb_pan_display = xxxfb_pan_display,
+ .fb_fillrect = xxxfb_fillrect, /* Needed !!! */
+ .fb_copyarea = xxxfb_copyarea, /* Needed !!! */
+ .fb_imageblit = xxxfb_imageblit, /* Needed !!! */
+ .fb_cursor = xxxfb_cursor, /* Optional !!! */
+ .fb_rotate = xxxfb_rotate,
+ .fb_sync = xxxfb_sync,
+ .fb_ioctl = xxxfb_ioctl,
+ .fb_mmap = xxxfb_mmap,
+};
+
+/* ------------------------------------------------------------------------- */
+
+ /*
* Initialization
*/
/* static int __init xxfb_probe (struct device *device) -- for platform devs */
-static int __init xxxfb_probe(struct pci_dev *dev,
- const_struct pci_device_id *ent)
+static int __devinit xxxfb_probe(struct pci_dev *dev,
+ const struct pci_device_id *ent)
{
struct fb_info *info;
struct xxx_par *par;
- struct device = &dev->dev; /* for pci drivers */
+ struct device* device = &dev->dev; /* for pci drivers */
int cmap_len, retval;
/*
@@ -684,7 +705,7 @@
info->screen_base = framebuffer_virtual_memory;
info->fbops = &xxxfb_ops;
info->fix = xxxfb_fix; /* this will be the only time xxxfb_fix will be
- * used, so mark it as __initdata
+ * used, so mark it as __devinitdata
*/
info->pseudo_palette = pseudo_palette; /* The pseudopalette is an
* 16-member array
@@ -760,7 +781,7 @@
*
* NOTE: This field is currently unused.
*/
- info->pixmap.scan_align = 32
+ info->pixmap.scan_align = 32;
/***************************** End optional stage ***************************/
/*
@@ -770,13 +791,13 @@
if (!mode_option)
mode_option = "640x480@60";
- retval = fb_find_mode(info->var, info, mode_option, NULL, 0, NULL, 8);
+ retval = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);
if (!retval || retval == 4)
return -EINVAL;
/* This has to been done !!! */
- fb_alloc_cmap(info->cmap, cmap_len, 0);
+ fb_alloc_cmap(&info->cmap, cmap_len, 0);
/*
* The following is done in the case of having hardware with a static
@@ -811,34 +832,77 @@
/*
* Cleanup
*/
-/* static void __exit xxxfb_remove(struct device *device) */
-static void __exit xxxfb_remove(struct pci_dev *dev)
+/* static void __devexit xxxfb_remove(struct device *device) */
+static void __devexit xxxfb_remove(struct pci_dev *dev)
{
- struct fb_info *info = pci_get_drv_data(dev);
- /* or dev_get_drv_data(device); */
+ struct fb_info *info = pci_get_drvdata(dev);
+ /* or dev_get_drvdata(device); */
if (info) {
unregister_framebuffer(info);
- fb_dealloc_cmap(&info.cmap);
+ fb_dealloc_cmap(&info->cmap);
/* ... */
framebuffer_release(info);
}
+}
+#ifdef CONFIG_PCI
+#ifdef CONFIG_PM
+/**
+ * xxxfb_suspend - Optional but recommended function. Suspend the device.
+ * @dev: PCI device
+ * @msg: the suspend event code.
+ *
+ * See Documentation/power/devices.txt for more information
+ */
+static int xxxfb_suspend(struct pci_dev *dev, pm_message_t msg)
+{
+ struct fb_info *info = pci_get_drvdata(dev);
+ struct xxxfb_par *par = info->par;
+
+ /* suspend here */
return 0;
}
-#if CONFIG_PCI
+/**
+ * xxxfb_resume - Optional but recommended function. Resume the device.
+ * @dev: PCI device
+ *
+ * See Documentation/power/devices.txt for more information
+ */
+static int xxxfb_resume(struct pci_dev *dev)
+{
+ struct fb_info *info = pci_get_drvdata(dev);
+ struct xxxfb_par *par = info->par;
+
+ /* resume here */
+ return 0;
+}
+#else
+#define xxxfb_suspend NULL
+#define xxxfb_resume NULL
+#endif /* CONFIG_PM */
+
+static struct pci_device_id xxxfb_id_table[] = {
+ { PCI_VENDOR_ID_XXX, PCI_DEVICE_ID_XXX,
+ PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
+ PCI_CLASS_MASK, 0 },
+ { 0, }
+};
+
/* For PCI drivers */
static struct pci_driver xxxfb_driver = {
.name = "xxxfb",
- .id_table = xxxfb_devices,
+ .id_table = xxxfb_id_table,
.probe = xxxfb_probe,
.remove = __devexit_p(xxxfb_remove),
- .suspend = xxxfb_suspend, /* optional */
- .resume = xxxfb_resume, /* optional */
+ .suspend = xxxfb_suspend, /* optional but recommended */
+ .resume = xxxfb_resume, /* optional but recommended */
};
-static int __init xxxfb_init(void)
+MODULE_DEVICE_TABLE(pci, xxxfb_id_table);
+
+int __init xxxfb_init(void)
{
/*
* For kernel boot options (in 'video=xxxfb:<options>' format)
@@ -858,16 +922,53 @@
{
pci_unregister_driver(&xxxfb_driver);
}
-#else
+#else /* non PCI, platform drivers */
#include <linux/platform_device.h>
/* for platform devices */
+
+#ifdef CONFIG_PM
+/**
+ * xxxfb_suspend - Optional but recommended function. Suspend the device.
+ * @dev: platform device
+ * @msg: the suspend event code.
+ *
+ * See Documentation/power/devices.txt for more information
+ */
+static int xxxfb_suspend(struct platform_device *dev, pm_message_t msg)
+{
+ struct fb_info *info = platform_get_drvdata(dev);
+ struct xxxfb_par *par = info->par;
+
+ /* suspend here */
+ return 0;
+}
+
+/**
+ * xxxfb_resume - Optional but recommended function. Resume the device.
+ * @dev: platform device
+ *
+ * See Documentation/power/devices.txt for more information
+ */
+static int xxxfb_resume(struct platform_dev *dev)
+{
+ struct fb_info *info = platform_get_drvdata(dev);
+ struct xxxfb_par *par = info->par;
+
+ /* resume here */
+ return 0;
+}
+#else
+#define xxxfb_suspend NULL
+#define xxxfb_resume NULL
+#endif /* CONFIG_PM */
+
static struct device_driver xxxfb_driver = {
.name = "xxxfb",
.bus = &platform_bus_type,
.probe = xxxfb_probe,
.remove = xxxfb_remove,
- .suspend = xxxfb_suspend, /* optional */
- .resume = xxxfb_resume, /* optional */
+ .suspend = xxxfb_suspend, /* optional but recommended */
+ .resume = xxxfb_resume, /* optional but recommended */
};
static struct platform_device xxxfb_device = {
@@ -903,8 +1004,9 @@
platform_device_unregister(&xxxfb_device);
driver_unregister(&xxxfb_driver);
}
-#endif
+#endif /* CONFIG_PCI */
+#ifdef MODULE
/*
* Setup
*/
@@ -917,34 +1019,7 @@
{
/* Parse user speficied options (`video=xxxfb:') */
}
-
-/* ------------------------------------------------------------------------- */
-
- /*
- * Frame buffer operations
- */
-
-static struct fb_ops xxxfb_ops = {
- .owner = THIS_MODULE,
- .fb_open = xxxfb_open,
- .fb_read = xxxfb_read,
- .fb_write = xxxfb_write,
- .fb_release = xxxfb_release,
- .fb_check_var = xxxfb_check_var,
- .fb_set_par = xxxfb_set_par,
- .fb_setcolreg = xxxfb_setcolreg,
- .fb_blank = xxxfb_blank,
- .fb_pan_display = xxxfb_pan_display,
- .fb_fillrect = xxxfb_fillrect, /* Needed !!! */
- .fb_copyarea = xxxfb_copyarea, /* Needed !!! */
- .fb_imageblit = xxxfb_imageblit, /* Needed !!! */
- .fb_cursor = xxxfb_cursor, /* Optional !!! */
- .fb_rotate = xxxfb_rotate,
- .fb_poll = xxxfb_poll,
- .fb_sync = xxxfb_sync,
- .fb_ioctl = xxxfb_ioctl,
- .fb_mmap = xxxfb_mmap,
-};
+#endif /* MODULE */
/* ------------------------------------------------------------------------- */
@@ -954,6 +1029,6 @@
*/
module_init(xxxfb_init);
-module_exit(xxxfb_cleanup);
+module_exit(xxxfb_remove);
MODULE_LICENSE("GPL");
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c
index 0a44c44..c86df12 100644
--- a/drivers/video/sm501fb.c
+++ b/drivers/video/sm501fb.c
@@ -989,7 +989,7 @@
((info->cmap.green[fg_col] & 0xFC) << 3) |
((info->cmap.blue[fg_col] & 0xF8) >> 3);
- dev_dbg(fbi->dev, "fgcol %08x, bgcol %08x\n", fg, bg);
+ dev_dbg(fbi->dev, "fgcol %08lx, bgcol %08lx\n", fg, bg);
writel(bg, base + SM501_OFF_HWC_COLOR_1_2);
writel(fg, base + SM501_OFF_HWC_COLOR_3);
diff --git a/drivers/video/svgalib.c b/drivers/video/svgalib.c
index 68b30d9..079cdc9 100644
--- a/drivers/video/svgalib.c
+++ b/drivers/video/svgalib.c
@@ -194,7 +194,7 @@
void svga_settile(struct fb_info *info, struct fb_tilemap *map)
{
const u8 *font = map->data;
- u8* fb = (u8 *) info->screen_base;
+ u8 __iomem *fb = (u8 __iomem *)info->screen_base;
int i, c;
if ((map->width != 8) || (map->height != 16) ||
@@ -207,7 +207,8 @@
fb += 2;
for (c = 0; c < map->length; c++) {
for (i = 0; i < map->height; i++) {
- fb[i * 4] = font[i];
+ fb_writeb(font[i], fb + i * 4);
+// fb[i * 4] = font[i];
}
fb += 128;
font += map->height;
@@ -221,8 +222,8 @@
/* colstride is halved in this function because u16 are used */
int colstride = 1 << (info->fix.type_aux & FB_AUX_TEXT_SVGA_MASK);
int rowstride = colstride * (info->var.xres_virtual / 8);
- u16 *fb = (u16 *) info->screen_base;
- u16 *src, *dst;
+ u16 __iomem *fb = (u16 __iomem *) info->screen_base;
+ u16 __iomem *src, *dst;
if ((area->sy > area->dy) ||
((area->sy == area->dy) && (area->sx > area->dx))) {
@@ -239,10 +240,11 @@
}
for (dy = 0; dy < area->height; dy++) {
- u16* src2 = src;
- u16* dst2 = dst;
+ u16 __iomem *src2 = src;
+ u16 __iomem *dst2 = dst;
for (dx = 0; dx < area->width; dx++) {
- *dst2 = *src2;
+ fb_writew(fb_readw(src2), dst2);
+// *dst2 = *src2;
src2 += colstride;
dst2 += colstride;
}
@@ -258,14 +260,14 @@
int colstride = 2 << (info->fix.type_aux & FB_AUX_TEXT_SVGA_MASK);
int rowstride = colstride * (info->var.xres_virtual / 8);
int attr = (0x0F & rect->bg) << 4 | (0x0F & rect->fg);
- u8 *fb = (u8 *) info->screen_base;
+ u8 __iomem *fb = (u8 __iomem *)info->screen_base;
fb += rect->sx * colstride + rect->sy * rowstride;
for (dy = 0; dy < rect->height; dy++) {
- u8* fb2 = fb;
+ u8 __iomem *fb2 = fb;
for (dx = 0; dx < rect->width; dx++) {
- fb2[0] = rect->index;
- fb2[1] = attr;
+ fb_writeb(rect->index, fb2);
+ fb_writeb(attr, fb2 + 1);
fb2 += colstride;
}
fb += rowstride;
@@ -279,15 +281,15 @@
int colstride = 2 << (info->fix.type_aux & FB_AUX_TEXT_SVGA_MASK);
int rowstride = colstride * (info->var.xres_virtual / 8);
int attr = (0x0F & blit->bg) << 4 | (0x0F & blit->fg);
- u8* fb = (u8 *) info->screen_base;
+ u8 __iomem *fb = (u8 __iomem *)info->screen_base;
fb += blit->sx * colstride + blit->sy * rowstride;
i=0;
for (dy=0; dy < blit->height; dy ++) {
- u8* fb2 = fb;
+ u8 __iomem *fb2 = fb;
for (dx = 0; dx < blit->width; dx ++) {
- fb2[0] = blit->indices[i];
- fb2[1] = attr;
+ fb_writeb(blit->indices[i], fb2);
+ fb_writeb(attr, fb2 + 1);
fb2 += colstride;
i ++;
if (i == blit->length) return;
@@ -340,6 +342,11 @@
vga_wcrt(NULL, 0x0A, cs); /* set cursor start and enable it */
}
+int svga_get_tilemax(struct fb_info *info)
+{
+ return 256;
+}
+
/* ------------------------------------------------------------------------- */
@@ -621,6 +628,7 @@
EXPORT_SYMBOL(svga_tilefill);
EXPORT_SYMBOL(svga_tileblit);
EXPORT_SYMBOL(svga_tilecursor);
+EXPORT_SYMBOL(svga_get_tilemax);
EXPORT_SYMBOL(svga_compute_pll);
EXPORT_SYMBOL(svga_check_timings);
diff --git a/drivers/video/syscopyarea.c b/drivers/video/syscopyarea.c
new file mode 100644
index 0000000..37af10a
--- /dev/null
+++ b/drivers/video/syscopyarea.c
@@ -0,0 +1,378 @@
+/*
+ * Generic Bit Block Transfer for frame buffers located in system RAM with
+ * packed pixels of any depth.
+ *
+ * Based almost entirely from cfbcopyarea.c (which is based almost entirely
+ * on Geert Uytterhoeven's copyarea routine)
+ *
+ * Copyright (C) 2007 Antonino Daplas <adaplas@pol.net>
+ *
+ * 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/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/fb.h>
+#include <linux/slab.h>
+#include <asm/types.h>
+#include <asm/io.h>
+#include "fb_draw.h"
+
+ /*
+ * Generic bitwise copy algorithm
+ */
+
+static void
+bitcpy(unsigned long *dst, int dst_idx, const unsigned long *src,
+ int src_idx, int bits, unsigned n)
+{
+ unsigned long first, last;
+ int const shift = dst_idx-src_idx;
+ int left, right;
+
+ first = FB_SHIFT_HIGH(~0UL, dst_idx);
+ last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits));
+
+ if (!shift) {
+ /* Same alignment for source and dest */
+ if (dst_idx+n <= bits) {
+ /* Single word */
+ if (last)
+ first &= last;
+ *dst = comp(*src, *dst, first);
+ } else {
+ /* Multiple destination words */
+ /* Leading bits */
+ if (first != ~0UL) {
+ *dst = comp(*src, *dst, first);
+ dst++;
+ src++;
+ n -= bits - dst_idx;
+ }
+
+ /* Main chunk */
+ n /= bits;
+ while (n >= 8) {
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ n -= 8;
+ }
+ while (n--)
+ *dst++ = *src++;
+
+ /* Trailing bits */
+ if (last)
+ *dst = comp(*src, *dst, last);
+ }
+ } else {
+ unsigned long d0, d1;
+ int m;
+
+ /* Different alignment for source and dest */
+ right = shift & (bits - 1);
+ left = -shift & (bits - 1);
+
+ if (dst_idx+n <= bits) {
+ /* Single destination word */
+ if (last)
+ first &= last;
+ if (shift > 0) {
+ /* Single source word */
+ *dst = comp(*src >> right, *dst, first);
+ } else if (src_idx+n <= bits) {
+ /* Single source word */
+ *dst = comp(*src << left, *dst, first);
+ } else {
+ /* 2 source words */
+ d0 = *src++;
+ d1 = *src;
+ *dst = comp(d0 << left | d1 >> right, *dst,
+ first);
+ }
+ } else {
+ /* Multiple destination words */
+ /** We must always remember the last value read,
+ because in case SRC and DST overlap bitwise (e.g.
+ when moving just one pixel in 1bpp), we always
+ collect one full long for DST and that might
+ overlap with the current long from SRC. We store
+ this value in 'd0'. */
+ d0 = *src++;
+ /* Leading bits */
+ if (shift > 0) {
+ /* Single source word */
+ *dst = comp(d0 >> right, *dst, first);
+ dst++;
+ n -= bits - dst_idx;
+ } else {
+ /* 2 source words */
+ d1 = *src++;
+ *dst = comp(d0 << left | *dst >> right, *dst, first);
+ d0 = d1;
+ dst++;
+ n -= bits - dst_idx;
+ }
+
+ /* Main chunk */
+ m = n % bits;
+ n /= bits;
+ while (n >= 4) {
+ d1 = *src++;
+ *dst++ = d0 << left | d1 >> right;
+ d0 = d1;
+ d1 = *src++;
+ *dst++ = d0 << left | d1 >> right;
+ d0 = d1;
+ d1 = *src++;
+ *dst++ = d0 << left | d1 >> right;
+ d0 = d1;
+ d1 = *src++;
+ *dst++ = d0 << left | d1 >> right;
+ d0 = d1;
+ n -= 4;
+ }
+ while (n--) {
+ d1 = *src++;
+ *dst++ = d0 << left | d1 >> right;
+ d0 = d1;
+ }
+
+ /* Trailing bits */
+ if (last) {
+ if (m <= right) {
+ /* Single source word */
+ *dst = comp(d0 << left, *dst, last);
+ } else {
+ /* 2 source words */
+ d1 = *src;
+ *dst = comp(d0 << left | d1 >> right,
+ *dst, last);
+ }
+ }
+ }
+ }
+}
+
+ /*
+ * Generic bitwise copy algorithm, operating backward
+ */
+
+static void
+bitcpy_rev(unsigned long *dst, int dst_idx, const unsigned long *src,
+ int src_idx, int bits, unsigned n)
+{
+ unsigned long first, last;
+ int shift;
+
+ dst += (n-1)/bits;
+ src += (n-1)/bits;
+ if ((n-1) % bits) {
+ dst_idx += (n-1) % bits;
+ dst += dst_idx >> (ffs(bits) - 1);
+ dst_idx &= bits - 1;
+ src_idx += (n-1) % bits;
+ src += src_idx >> (ffs(bits) - 1);
+ src_idx &= bits - 1;
+ }
+
+ shift = dst_idx-src_idx;
+
+ first = FB_SHIFT_LOW(~0UL, bits - 1 - dst_idx);
+ last = ~(FB_SHIFT_LOW(~0UL, bits - 1 - ((dst_idx-n) % bits)));
+
+ if (!shift) {
+ /* Same alignment for source and dest */
+ if ((unsigned long)dst_idx+1 >= n) {
+ /* Single word */
+ if (last)
+ first &= last;
+ *dst = comp(*src, *dst, first);
+ } else {
+ /* Multiple destination words */
+
+ /* Leading bits */
+ if (first != ~0UL) {
+ *dst = comp(*src, *dst, first);
+ dst--;
+ src--;
+ n -= dst_idx+1;
+ }
+
+ /* Main chunk */
+ n /= bits;
+ while (n >= 8) {
+ *dst-- = *src--;
+ *dst-- = *src--;
+ *dst-- = *src--;
+ *dst-- = *src--;
+ *dst-- = *src--;
+ *dst-- = *src--;
+ *dst-- = *src--;
+ *dst-- = *src--;
+ n -= 8;
+ }
+ while (n--)
+ *dst-- = *src--;
+ /* Trailing bits */
+ if (last)
+ *dst = comp(*src, *dst, last);
+ }
+ } else {
+ /* Different alignment for source and dest */
+
+ int const left = -shift & (bits-1);
+ int const right = shift & (bits-1);
+
+ if ((unsigned long)dst_idx+1 >= n) {
+ /* Single destination word */
+ if (last)
+ first &= last;
+ if (shift < 0) {
+ /* Single source word */
+ *dst = comp(*src << left, *dst, first);
+ } else if (1+(unsigned long)src_idx >= n) {
+ /* Single source word */
+ *dst = comp(*src >> right, *dst, first);
+ } else {
+ /* 2 source words */
+ *dst = comp(*src >> right | *(src-1) << left,
+ *dst, first);
+ }
+ } else {
+ /* Multiple destination words */
+ /** We must always remember the last value read,
+ because in case SRC and DST overlap bitwise (e.g.
+ when moving just one pixel in 1bpp), we always
+ collect one full long for DST and that might
+ overlap with the current long from SRC. We store
+ this value in 'd0'. */
+ unsigned long d0, d1;
+ int m;
+
+ d0 = *src--;
+ /* Leading bits */
+ if (shift < 0) {
+ /* Single source word */
+ *dst = comp(d0 << left, *dst, first);
+ } else {
+ /* 2 source words */
+ d1 = *src--;
+ *dst = comp(d0 >> right | d1 << left, *dst,
+ first);
+ d0 = d1;
+ }
+ dst--;
+ n -= dst_idx+1;
+
+ /* Main chunk */
+ m = n % bits;
+ n /= bits;
+ while (n >= 4) {
+ d1 = *src--;
+ *dst-- = d0 >> right | d1 << left;
+ d0 = d1;
+ d1 = *src--;
+ *dst-- = d0 >> right | d1 << left;
+ d0 = d1;
+ d1 = *src--;
+ *dst-- = d0 >> right | d1 << left;
+ d0 = d1;
+ d1 = *src--;
+ *dst-- = d0 >> right | d1 << left;
+ d0 = d1;
+ n -= 4;
+ }
+ while (n--) {
+ d1 = *src--;
+ *dst-- = d0 >> right | d1 << left;
+ d0 = d1;
+ }
+
+ /* Trailing bits */
+ if (last) {
+ if (m <= left) {
+ /* Single source word */
+ *dst = comp(d0 >> right, *dst, last);
+ } else {
+ /* 2 source words */
+ d1 = *src;
+ *dst = comp(d0 >> right | d1 << left,
+ *dst, last);
+ }
+ }
+ }
+ }
+}
+
+void sys_copyarea(struct fb_info *p, const struct fb_copyarea *area)
+{
+ u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy;
+ u32 height = area->height, width = area->width;
+ unsigned long const bits_per_line = p->fix.line_length*8u;
+ unsigned long *dst = NULL, *src = NULL;
+ int bits = BITS_PER_LONG, bytes = bits >> 3;
+ int dst_idx = 0, src_idx = 0, rev_copy = 0;
+
+ if (p->state != FBINFO_STATE_RUNNING)
+ return;
+
+ /* if the beginning of the target area might overlap with the end of
+ the source area, be have to copy the area reverse. */
+ if ((dy == sy && dx > sx) || (dy > sy)) {
+ dy += height;
+ sy += height;
+ rev_copy = 1;
+ }
+
+ /* split the base of the framebuffer into a long-aligned address and
+ the index of the first bit */
+ dst = src = (unsigned long *)((unsigned long)p->screen_base &
+ ~(bytes-1));
+ dst_idx = src_idx = 8*((unsigned long)p->screen_base & (bytes-1));
+ /* add offset of source and target area */
+ dst_idx += dy*bits_per_line + dx*p->var.bits_per_pixel;
+ src_idx += sy*bits_per_line + sx*p->var.bits_per_pixel;
+
+ if (p->fbops->fb_sync)
+ p->fbops->fb_sync(p);
+
+ if (rev_copy) {
+ while (height--) {
+ dst_idx -= bits_per_line;
+ src_idx -= bits_per_line;
+ dst += dst_idx >> (ffs(bits) - 1);
+ dst_idx &= (bytes - 1);
+ src += src_idx >> (ffs(bits) - 1);
+ src_idx &= (bytes - 1);
+ bitcpy_rev(dst, dst_idx, src, src_idx, bits,
+ width*p->var.bits_per_pixel);
+ }
+ } else {
+ while (height--) {
+ dst += dst_idx >> (ffs(bits) - 1);
+ dst_idx &= (bytes - 1);
+ src += src_idx >> (ffs(bits) - 1);
+ src_idx &= (bytes - 1);
+ bitcpy(dst, dst_idx, src, src_idx, bits,
+ width*p->var.bits_per_pixel);
+ dst_idx += bits_per_line;
+ src_idx += bits_per_line;
+ }
+ }
+}
+
+EXPORT_SYMBOL(sys_copyarea);
+
+MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
+MODULE_DESCRIPTION("Generic copyarea (sys-to-sys)");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/video/sysfillrect.c b/drivers/video/sysfillrect.c
new file mode 100644
index 0000000..a261e9e
--- /dev/null
+++ b/drivers/video/sysfillrect.c
@@ -0,0 +1,334 @@
+/*
+ * Generic fillrect for frame buffers in system RAM with packed pixels of
+ * any depth.
+ *
+ * Based almost entirely from cfbfillrect.c (which is based almost entirely
+ * on Geert Uytterhoeven's fillrect routine)
+ *
+ * Copyright (C) 2007 Antonino Daplas <adaplas@pol.net>
+ *
+ * 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/module.h>
+#include <linux/string.h>
+#include <linux/fb.h>
+#include <asm/types.h>
+#include "fb_draw.h"
+
+ /*
+ * Aligned pattern fill using 32/64-bit memory accesses
+ */
+
+static void
+bitfill_aligned(unsigned long *dst, int dst_idx, unsigned long pat,
+ unsigned n, int bits)
+{
+ unsigned long first, last;
+
+ if (!n)
+ return;
+
+ first = FB_SHIFT_HIGH(~0UL, dst_idx);
+ last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits));
+
+ if (dst_idx+n <= bits) {
+ /* Single word */
+ if (last)
+ first &= last;
+ *dst = comp(pat, *dst, first);
+ } else {
+ /* Multiple destination words */
+
+ /* Leading bits */
+ if (first!= ~0UL) {
+ *dst = comp(pat, *dst, first);
+ dst++;
+ n -= bits - dst_idx;
+ }
+
+ /* Main chunk */
+ n /= bits;
+ while (n >= 8) {
+ *dst++ = pat;
+ *dst++ = pat;
+ *dst++ = pat;
+ *dst++ = pat;
+ *dst++ = pat;
+ *dst++ = pat;
+ *dst++ = pat;
+ *dst++ = pat;
+ n -= 8;
+ }
+ while (n--)
+ *dst++ = pat;
+ /* Trailing bits */
+ if (last)
+ *dst = comp(pat, *dst, last);
+ }
+}
+
+
+ /*
+ * Unaligned generic pattern fill using 32/64-bit memory accesses
+ * The pattern must have been expanded to a full 32/64-bit value
+ * Left/right are the appropriate shifts to convert to the pattern to be
+ * used for the next 32/64-bit word
+ */
+
+static void
+bitfill_unaligned(unsigned long *dst, int dst_idx, unsigned long pat,
+ int left, int right, unsigned n, int bits)
+{
+ unsigned long first, last;
+
+ if (!n)
+ return;
+
+ first = FB_SHIFT_HIGH(~0UL, dst_idx);
+ last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits));
+
+ if (dst_idx+n <= bits) {
+ /* Single word */
+ if (last)
+ first &= last;
+ *dst = comp(pat, *dst, first);
+ } else {
+ /* Multiple destination words */
+ /* Leading bits */
+ if (first) {
+ *dst = comp(pat, *dst, first);
+ dst++;
+ pat = pat << left | pat >> right;
+ n -= bits - dst_idx;
+ }
+
+ /* Main chunk */
+ n /= bits;
+ while (n >= 4) {
+ *dst++ = pat;
+ pat = pat << left | pat >> right;
+ *dst++ = pat;
+ pat = pat << left | pat >> right;
+ *dst++ = pat;
+ pat = pat << left | pat >> right;
+ *dst++ = pat;
+ pat = pat << left | pat >> right;
+ n -= 4;
+ }
+ while (n--) {
+ *dst++ = pat;
+ pat = pat << left | pat >> right;
+ }
+
+ /* Trailing bits */
+ if (last)
+ *dst = comp(pat, *dst, first);
+ }
+}
+
+ /*
+ * Aligned pattern invert using 32/64-bit memory accesses
+ */
+static void
+bitfill_aligned_rev(unsigned long *dst, int dst_idx, unsigned long pat,
+ unsigned n, int bits)
+{
+ unsigned long val = pat;
+ unsigned long first, last;
+
+ if (!n)
+ return;
+
+ first = FB_SHIFT_HIGH(~0UL, dst_idx);
+ last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits));
+
+ if (dst_idx+n <= bits) {
+ /* Single word */
+ if (last)
+ first &= last;
+ *dst = comp(*dst ^ val, *dst, first);
+ } else {
+ /* Multiple destination words */
+ /* Leading bits */
+ if (first!=0UL) {
+ *dst = comp(*dst ^ val, *dst, first);
+ dst++;
+ n -= bits - dst_idx;
+ }
+
+ /* Main chunk */
+ n /= bits;
+ while (n >= 8) {
+ *dst++ ^= val;
+ *dst++ ^= val;
+ *dst++ ^= val;
+ *dst++ ^= val;
+ *dst++ ^= val;
+ *dst++ ^= val;
+ *dst++ ^= val;
+ *dst++ ^= val;
+ n -= 8;
+ }
+ while (n--)
+ *dst++ ^= val;
+ /* Trailing bits */
+ if (last)
+ *dst = comp(*dst ^ val, *dst, last);
+ }
+}
+
+
+ /*
+ * Unaligned generic pattern invert using 32/64-bit memory accesses
+ * The pattern must have been expanded to a full 32/64-bit value
+ * Left/right are the appropriate shifts to convert to the pattern to be
+ * used for the next 32/64-bit word
+ */
+
+static void
+bitfill_unaligned_rev(unsigned long *dst, int dst_idx, unsigned long pat,
+ int left, int right, unsigned n, int bits)
+{
+ unsigned long first, last;
+
+ if (!n)
+ return;
+
+ first = FB_SHIFT_HIGH(~0UL, dst_idx);
+ last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits));
+
+ if (dst_idx+n <= bits) {
+ /* Single word */
+ if (last)
+ first &= last;
+ *dst = comp(*dst ^ pat, *dst, first);
+ } else {
+ /* Multiple destination words */
+
+ /* Leading bits */
+ if (first != 0UL) {
+ *dst = comp(*dst ^ pat, *dst, first);
+ dst++;
+ pat = pat << left | pat >> right;
+ n -= bits - dst_idx;
+ }
+
+ /* Main chunk */
+ n /= bits;
+ while (n >= 4) {
+ *dst++ ^= pat;
+ pat = pat << left | pat >> right;
+ *dst++ ^= pat;
+ pat = pat << left | pat >> right;
+ *dst++ ^= pat;
+ pat = pat << left | pat >> right;
+ *dst++ ^= pat;
+ pat = pat << left | pat >> right;
+ n -= 4;
+ }
+ while (n--) {
+ *dst ^= pat;
+ pat = pat << left | pat >> right;
+ }
+
+ /* Trailing bits */
+ if (last)
+ *dst = comp(*dst ^ pat, *dst, last);
+ }
+}
+
+void sys_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
+{
+ unsigned long pat, fg;
+ unsigned long width = rect->width, height = rect->height;
+ int bits = BITS_PER_LONG, bytes = bits >> 3;
+ u32 bpp = p->var.bits_per_pixel;
+ unsigned long *dst;
+ int dst_idx, left;
+
+ if (p->state != FBINFO_STATE_RUNNING)
+ return;
+
+ if (p->fix.visual == FB_VISUAL_TRUECOLOR ||
+ p->fix.visual == FB_VISUAL_DIRECTCOLOR )
+ fg = ((u32 *) (p->pseudo_palette))[rect->color];
+ else
+ fg = rect->color;
+
+ pat = pixel_to_pat( bpp, fg);
+
+ dst = (unsigned long *)((unsigned long)p->screen_base & ~(bytes-1));
+ dst_idx = ((unsigned long)p->screen_base & (bytes - 1))*8;
+ dst_idx += rect->dy*p->fix.line_length*8+rect->dx*bpp;
+ /* FIXME For now we support 1-32 bpp only */
+ left = bits % bpp;
+ if (p->fbops->fb_sync)
+ p->fbops->fb_sync(p);
+ if (!left) {
+ void (*fill_op32)(unsigned long *dst, int dst_idx,
+ unsigned long pat, unsigned n, int bits) =
+ NULL;
+
+ switch (rect->rop) {
+ case ROP_XOR:
+ fill_op32 = bitfill_aligned_rev;
+ break;
+ case ROP_COPY:
+ fill_op32 = bitfill_aligned;
+ break;
+ default:
+ printk( KERN_ERR "cfb_fillrect(): unknown rop, "
+ "defaulting to ROP_COPY\n");
+ fill_op32 = bitfill_aligned;
+ break;
+ }
+ while (height--) {
+ dst += dst_idx >> (ffs(bits) - 1);
+ dst_idx &= (bits - 1);
+ fill_op32(dst, dst_idx, pat, width*bpp, bits);
+ dst_idx += p->fix.line_length*8;
+ }
+ } else {
+ int right;
+ int r;
+ int rot = (left-dst_idx) % bpp;
+ void (*fill_op)(unsigned long *dst, int dst_idx,
+ unsigned long pat, int left, int right,
+ unsigned n, int bits) = NULL;
+
+ /* rotate pattern to correct start position */
+ pat = pat << rot | pat >> (bpp-rot);
+
+ right = bpp-left;
+ switch (rect->rop) {
+ case ROP_XOR:
+ fill_op = bitfill_unaligned_rev;
+ break;
+ case ROP_COPY:
+ fill_op = bitfill_unaligned;
+ break;
+ default:
+ printk(KERN_ERR "cfb_fillrect(): unknown rop, "
+ "defaulting to ROP_COPY\n");
+ fill_op = bitfill_unaligned;
+ break;
+ }
+ while (height--) {
+ dst += dst_idx >> (ffs(bits) - 1);
+ dst_idx &= (bits - 1);
+ fill_op(dst, dst_idx, pat, left, right,
+ width*bpp, bits);
+ r = (p->fix.line_length*8) % bpp;
+ pat = pat << (bpp-r) | pat >> r;
+ dst_idx += p->fix.line_length*8;
+ }
+ }
+}
+
+EXPORT_SYMBOL(sys_fillrect);
+
+MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
+MODULE_DESCRIPTION("Generic fill rectangle (sys-to-sys)");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/sysimgblt.c b/drivers/video/sysimgblt.c
new file mode 100644
index 0000000..bd7e7e9
--- /dev/null
+++ b/drivers/video/sysimgblt.c
@@ -0,0 +1,291 @@
+/*
+ * Generic 1-bit or 8-bit source to 1-32 bit destination expansion
+ * for frame buffer located in system RAM with packed pixels of any depth.
+ *
+ * Based almost entirely on cfbimgblt.c
+ *
+ * Copyright (C) April 2007 Antonino Daplas <adaplas@pol.net>
+ *
+ * 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/module.h>
+#include <linux/string.h>
+#include <linux/fb.h>
+#include <asm/types.h>
+
+#define DEBUG
+
+#ifdef DEBUG
+#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt,__FUNCTION__,## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+static const u32 cfb_tab8[] = {
+#if defined(__BIG_ENDIAN)
+ 0x00000000,0x000000ff,0x0000ff00,0x0000ffff,
+ 0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff,
+ 0xff000000,0xff0000ff,0xff00ff00,0xff00ffff,
+ 0xffff0000,0xffff00ff,0xffffff00,0xffffffff
+#elif defined(__LITTLE_ENDIAN)
+ 0x00000000,0xff000000,0x00ff0000,0xffff0000,
+ 0x0000ff00,0xff00ff00,0x00ffff00,0xffffff00,
+ 0x000000ff,0xff0000ff,0x00ff00ff,0xffff00ff,
+ 0x0000ffff,0xff00ffff,0x00ffffff,0xffffffff
+#else
+#error FIXME: No endianness??
+#endif
+};
+
+static const u32 cfb_tab16[] = {
+#if defined(__BIG_ENDIAN)
+ 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff
+#elif defined(__LITTLE_ENDIAN)
+ 0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff
+#else
+#error FIXME: No endianness??
+#endif
+};
+
+static const u32 cfb_tab32[] = {
+ 0x00000000, 0xffffffff
+};
+
+static void color_imageblit(const struct fb_image *image, struct fb_info *p,
+ void *dst1, u32 start_index, u32 pitch_index)
+{
+ /* Draw the penguin */
+ u32 *dst, *dst2;
+ u32 color = 0, val, shift;
+ int i, n, bpp = p->var.bits_per_pixel;
+ u32 null_bits = 32 - bpp;
+ u32 *palette = (u32 *) p->pseudo_palette;
+ const u8 *src = image->data;
+
+ dst2 = dst1;
+ for (i = image->height; i--; ) {
+ n = image->width;
+ dst = dst1;
+ shift = 0;
+ val = 0;
+
+ if (start_index) {
+ u32 start_mask = ~(FB_SHIFT_HIGH(~(u32)0,
+ start_index));
+ val = *dst & start_mask;
+ shift = start_index;
+ }
+ while (n--) {
+ if (p->fix.visual == FB_VISUAL_TRUECOLOR ||
+ p->fix.visual == FB_VISUAL_DIRECTCOLOR )
+ color = palette[*src];
+ else
+ color = *src;
+ color <<= FB_LEFT_POS(bpp);
+ val |= FB_SHIFT_HIGH(color, shift);
+ if (shift >= null_bits) {
+ *dst++ = val;
+
+ val = (shift == null_bits) ? 0 :
+ FB_SHIFT_LOW(color, 32 - shift);
+ }
+ shift += bpp;
+ shift &= (32 - 1);
+ src++;
+ }
+ if (shift) {
+ u32 end_mask = FB_SHIFT_HIGH(~(u32)0, shift);
+
+ *dst &= end_mask;
+ *dst |= val;
+ }
+ dst1 += p->fix.line_length;
+ if (pitch_index) {
+ dst2 += p->fix.line_length;
+ dst1 = (u8 *)((long)dst2 & ~(sizeof(u32) - 1));
+
+ start_index += pitch_index;
+ start_index &= 32 - 1;
+ }
+ }
+}
+
+static void slow_imageblit(const struct fb_image *image, struct fb_info *p,
+ void *dst1, u32 fgcolor, u32 bgcolor,
+ u32 start_index, u32 pitch_index)
+{
+ u32 shift, color = 0, bpp = p->var.bits_per_pixel;
+ u32 *dst, *dst2;
+ u32 val, pitch = p->fix.line_length;
+ u32 null_bits = 32 - bpp;
+ u32 spitch = (image->width+7)/8;
+ const u8 *src = image->data, *s;
+ u32 i, j, l;
+
+ dst2 = dst1;
+ fgcolor <<= FB_LEFT_POS(bpp);
+ bgcolor <<= FB_LEFT_POS(bpp);
+
+ for (i = image->height; i--; ) {
+ shift = val = 0;
+ l = 8;
+ j = image->width;
+ dst = dst1;
+ s = src;
+
+ /* write leading bits */
+ if (start_index) {
+ u32 start_mask = ~(FB_SHIFT_HIGH(~(u32)0,start_index));
+ val = *dst & start_mask;
+ shift = start_index;
+ }
+
+ while (j--) {
+ l--;
+ color = (*s & (1 << l)) ? fgcolor : bgcolor;
+ val |= FB_SHIFT_HIGH(color, shift);
+
+ /* Did the bitshift spill bits to the next long? */
+ if (shift >= null_bits) {
+ *dst++ = val;
+ val = (shift == null_bits) ? 0 :
+ FB_SHIFT_LOW(color,32 - shift);
+ }
+ shift += bpp;
+ shift &= (32 - 1);
+ if (!l) { l = 8; s++; };
+ }
+
+ /* write trailing bits */
+ if (shift) {
+ u32 end_mask = FB_SHIFT_HIGH(~(u32)0, shift);
+
+ *dst &= end_mask;
+ *dst |= val;
+ }
+
+ dst1 += pitch;
+ src += spitch;
+ if (pitch_index) {
+ dst2 += pitch;
+ dst1 = (u8 *)((long)dst2 & ~(sizeof(u32) - 1));
+ start_index += pitch_index;
+ start_index &= 32 - 1;
+ }
+
+ }
+}
+
+/*
+ * fast_imageblit - optimized monochrome color expansion
+ *
+ * Only if: bits_per_pixel == 8, 16, or 32
+ * image->width is divisible by pixel/dword (ppw);
+ * fix->line_legth is divisible by 4;
+ * beginning and end of a scanline is dword aligned
+ */
+static void fast_imageblit(const struct fb_image *image, struct fb_info *p,
+ void *dst1, u32 fgcolor, u32 bgcolor)
+{
+ u32 fgx = fgcolor, bgx = bgcolor, bpp = p->var.bits_per_pixel;
+ u32 ppw = 32/bpp, spitch = (image->width + 7)/8;
+ u32 bit_mask, end_mask, eorx, shift;
+ const char *s = image->data, *src;
+ u32 *dst;
+ const u32 *tab = NULL;
+ int i, j, k;
+
+ switch (bpp) {
+ case 8:
+ tab = cfb_tab8;
+ break;
+ case 16:
+ tab = cfb_tab16;
+ break;
+ case 32:
+ default:
+ tab = cfb_tab32;
+ break;
+ }
+
+ for (i = ppw-1; i--; ) {
+ fgx <<= bpp;
+ bgx <<= bpp;
+ fgx |= fgcolor;
+ bgx |= bgcolor;
+ }
+
+ bit_mask = (1 << ppw) - 1;
+ eorx = fgx ^ bgx;
+ k = image->width/ppw;
+
+ for (i = image->height; i--; ) {
+ dst = dst1;
+ shift = 8;
+ src = s;
+
+ for (j = k; j--; ) {
+ shift -= ppw;
+ end_mask = tab[(*src >> shift) & bit_mask];
+ *dst++ = (end_mask & eorx) ^ bgx;
+ if (!shift) {
+ shift = 8;
+ src++;
+ }
+ }
+ dst1 += p->fix.line_length;
+ s += spitch;
+ }
+}
+
+void sys_imageblit(struct fb_info *p, const struct fb_image *image)
+{
+ u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0;
+ u32 bpl = sizeof(u32), bpp = p->var.bits_per_pixel;
+ u32 width = image->width;
+ u32 dx = image->dx, dy = image->dy;
+ void *dst1;
+
+ if (p->state != FBINFO_STATE_RUNNING)
+ return;
+
+ bitstart = (dy * p->fix.line_length * 8) + (dx * bpp);
+ start_index = bitstart & (32 - 1);
+ pitch_index = (p->fix.line_length & (bpl - 1)) * 8;
+
+ bitstart /= 8;
+ bitstart &= ~(bpl - 1);
+ dst1 = (void __force *)p->screen_base + bitstart;
+
+ if (p->fbops->fb_sync)
+ p->fbops->fb_sync(p);
+
+ if (image->depth == 1) {
+ if (p->fix.visual == FB_VISUAL_TRUECOLOR ||
+ p->fix.visual == FB_VISUAL_DIRECTCOLOR) {
+ fgcolor = ((u32*)(p->pseudo_palette))[image->fg_color];
+ bgcolor = ((u32*)(p->pseudo_palette))[image->bg_color];
+ } else {
+ fgcolor = image->fg_color;
+ bgcolor = image->bg_color;
+ }
+
+ if (32 % bpp == 0 && !start_index && !pitch_index &&
+ ((width & (32/bpp-1)) == 0) &&
+ bpp >= 8 && bpp <= 32)
+ fast_imageblit(image, p, dst1, fgcolor, bgcolor);
+ else
+ slow_imageblit(image, p, dst1, fgcolor, bgcolor,
+ start_index, pitch_index);
+ } else
+ color_imageblit(image, p, dst1, start_index, pitch_index);
+}
+
+EXPORT_SYMBOL(sys_imageblit);
+
+MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
+MODULE_DESCRIPTION("1-bit/8-bit to 1-32 bit color expansion (sys-to-sys)");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c
index 7478d0e..f0fde6e 100644
--- a/drivers/video/tgafb.c
+++ b/drivers/video/tgafb.c
@@ -5,27 +5,45 @@
* Copyright (C) 1997 Geert Uytterhoeven
* Copyright (C) 1999,2000 Martin Lucina, Tom Zerucha
* Copyright (C) 2002 Richard Henderson
+ * Copyright (C) 2006 Maciej W. Rozycki
*
* 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/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
+#include <linux/bitrev.h>
#include <linux/delay.h>
-#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/errno.h>
#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/module.h>
#include <linux/pci.h>
#include <linux/selection.h>
-#include <linux/bitrev.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/tc.h>
+
#include <asm/io.h>
+
#include <video/tgafb.h>
+#ifdef CONFIG_PCI
+#define TGA_BUS_PCI(dev) (dev->bus == &pci_bus_type)
+#else
+#define TGA_BUS_PCI(dev) 0
+#endif
+
+#ifdef CONFIG_TC
+#define TGA_BUS_TC(dev) (dev->bus == &tc_bus_type)
+#else
+#define TGA_BUS_TC(dev) 0
+#endif
+
/*
* Local functions.
*/
@@ -41,14 +59,19 @@
static void tgafb_imageblit(struct fb_info *, const struct fb_image *);
static void tgafb_fillrect(struct fb_info *, const struct fb_fillrect *);
static void tgafb_copyarea(struct fb_info *, const struct fb_copyarea *);
+static int tgafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info);
-static int __devinit tgafb_pci_register(struct pci_dev *,
- const struct pci_device_id *);
-static void __devexit tgafb_pci_unregister(struct pci_dev *);
+static int __devinit tgafb_register(struct device *dev);
+static void __devexit tgafb_unregister(struct device *dev);
-static const char *mode_option = "640x480@60";
+static const char *mode_option;
+static const char *mode_option_pci = "640x480@60";
+static const char *mode_option_tc = "1280x1024@72";
+static struct pci_driver tgafb_pci_driver;
+static struct tc_driver tgafb_tc_driver;
+
/*
* Frame buffer operations
*/
@@ -59,15 +82,20 @@
.fb_set_par = tgafb_set_par,
.fb_setcolreg = tgafb_setcolreg,
.fb_blank = tgafb_blank,
+ .fb_pan_display = tgafb_pan_display,
.fb_fillrect = tgafb_fillrect,
.fb_copyarea = tgafb_copyarea,
.fb_imageblit = tgafb_imageblit,
};
+#ifdef CONFIG_PCI
/*
* PCI registration operations
*/
+static int __devinit tgafb_pci_register(struct pci_dev *,
+ const struct pci_device_id *);
+static void __devexit tgafb_pci_unregister(struct pci_dev *);
static struct pci_device_id const tgafb_pci_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TGA) },
@@ -75,13 +103,68 @@
};
MODULE_DEVICE_TABLE(pci, tgafb_pci_table);
-static struct pci_driver tgafb_driver = {
+static struct pci_driver tgafb_pci_driver = {
.name = "tgafb",
.id_table = tgafb_pci_table,
.probe = tgafb_pci_register,
.remove = __devexit_p(tgafb_pci_unregister),
};
+static int __devinit
+tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ return tgafb_register(&pdev->dev);
+}
+
+static void __devexit
+tgafb_pci_unregister(struct pci_dev *pdev)
+{
+ tgafb_unregister(&pdev->dev);
+}
+#endif /* CONFIG_PCI */
+
+#ifdef CONFIG_TC
+/*
+ * TC registration operations
+ */
+static int __devinit tgafb_tc_register(struct device *);
+static int __devexit tgafb_tc_unregister(struct device *);
+
+static struct tc_device_id const tgafb_tc_table[] = {
+ { "DEC ", "PMAGD-AA" },
+ { "DEC ", "PMAGD " },
+ { }
+};
+MODULE_DEVICE_TABLE(tc, tgafb_tc_table);
+
+static struct tc_driver tgafb_tc_driver = {
+ .id_table = tgafb_tc_table,
+ .driver = {
+ .name = "tgafb",
+ .bus = &tc_bus_type,
+ .probe = tgafb_tc_register,
+ .remove = __devexit_p(tgafb_tc_unregister),
+ },
+};
+
+static int __devinit
+tgafb_tc_register(struct device *dev)
+{
+ int status = tgafb_register(dev);
+ if (!status)
+ get_device(dev);
+ return status;
+}
+
+static int __devexit
+tgafb_tc_unregister(struct device *dev)
+{
+ put_device(dev);
+ tgafb_unregister(dev);
+ return 0;
+}
+#endif /* CONFIG_TC */
+
/**
* tgafb_check_var - Optional function. Validates a var passed in.
@@ -132,10 +215,10 @@
tgafb_set_par(struct fb_info *info)
{
static unsigned int const deep_presets[4] = {
- 0x00014000,
- 0x0001440d,
+ 0x00004000,
+ 0x0000440d,
0xffffffff,
- 0x0001441d
+ 0x0000441d
};
static unsigned int const rasterop_presets[4] = {
0x00000003,
@@ -157,6 +240,8 @@
};
struct tga_par *par = (struct tga_par *) info->par;
+ int tga_bus_pci = TGA_BUS_PCI(par->dev);
+ int tga_bus_tc = TGA_BUS_TC(par->dev);
u32 htimings, vtimings, pll_freq;
u8 tga_type;
int i;
@@ -221,7 +306,7 @@
TGA_WRITE_REG(par, vtimings, TGA_VERT_REG);
/* Initalise RAMDAC. */
- if (tga_type == TGA_TYPE_8PLANE) {
+ if (tga_type == TGA_TYPE_8PLANE && tga_bus_pci) {
/* Init BT485 RAMDAC registers. */
BT485_WRITE(par, 0xa2 | (par->sync_on_green ? 0x8 : 0x0),
@@ -236,21 +321,7 @@
BT485_WRITE(par, 0x00, BT485_ADDR_PAL_WRITE);
TGA_WRITE_REG(par, BT485_DATA_PAL, TGA_RAMDAC_SETUP_REG);
-#ifdef CONFIG_HW_CONSOLE
- for (i = 0; i < 16; i++) {
- int j = color_table[i];
-
- TGA_WRITE_REG(par, default_red[j]|(BT485_DATA_PAL<<8),
- TGA_RAMDAC_REG);
- TGA_WRITE_REG(par, default_grn[j]|(BT485_DATA_PAL<<8),
- TGA_RAMDAC_REG);
- TGA_WRITE_REG(par, default_blu[j]|(BT485_DATA_PAL<<8),
- TGA_RAMDAC_REG);
- }
- for (i = 0; i < 240 * 3; i += 4) {
-#else
for (i = 0; i < 256 * 3; i += 4) {
-#endif
TGA_WRITE_REG(par, 0x55 | (BT485_DATA_PAL << 8),
TGA_RAMDAC_REG);
TGA_WRITE_REG(par, 0x00 | (BT485_DATA_PAL << 8),
@@ -261,6 +332,27 @@
TGA_RAMDAC_REG);
}
+ } else if (tga_type == TGA_TYPE_8PLANE && tga_bus_tc) {
+
+ /* Init BT459 RAMDAC registers. */
+ BT459_WRITE(par, BT459_REG_ACC, BT459_CMD_REG_0, 0x40);
+ BT459_WRITE(par, BT459_REG_ACC, BT459_CMD_REG_1, 0x00);
+ BT459_WRITE(par, BT459_REG_ACC, BT459_CMD_REG_2,
+ (par->sync_on_green ? 0xc0 : 0x40));
+
+ BT459_WRITE(par, BT459_REG_ACC, BT459_CUR_CMD_REG, 0x00);
+
+ /* Fill the palette. */
+ BT459_LOAD_ADDR(par, 0x0000);
+ TGA_WRITE_REG(par, BT459_PALETTE << 2, TGA_RAMDAC_SETUP_REG);
+
+ for (i = 0; i < 256 * 3; i += 4) {
+ TGA_WRITE_REG(par, 0x55, TGA_RAMDAC_REG);
+ TGA_WRITE_REG(par, 0x00, TGA_RAMDAC_REG);
+ TGA_WRITE_REG(par, 0x00, TGA_RAMDAC_REG);
+ TGA_WRITE_REG(par, 0x00, TGA_RAMDAC_REG);
+ }
+
} else { /* 24-plane or 24plusZ */
/* Init BT463 RAMDAC registers. */
@@ -431,6 +523,8 @@
unsigned transp, struct fb_info *info)
{
struct tga_par *par = (struct tga_par *) info->par;
+ int tga_bus_pci = TGA_BUS_PCI(par->dev);
+ int tga_bus_tc = TGA_BUS_TC(par->dev);
if (regno > 255)
return 1;
@@ -438,12 +532,18 @@
green >>= 8;
blue >>= 8;
- if (par->tga_type == TGA_TYPE_8PLANE) {
+ if (par->tga_type == TGA_TYPE_8PLANE && tga_bus_pci) {
BT485_WRITE(par, regno, BT485_ADDR_PAL_WRITE);
TGA_WRITE_REG(par, BT485_DATA_PAL, TGA_RAMDAC_SETUP_REG);
TGA_WRITE_REG(par, red|(BT485_DATA_PAL<<8),TGA_RAMDAC_REG);
TGA_WRITE_REG(par, green|(BT485_DATA_PAL<<8),TGA_RAMDAC_REG);
TGA_WRITE_REG(par, blue|(BT485_DATA_PAL<<8),TGA_RAMDAC_REG);
+ } else if (par->tga_type == TGA_TYPE_8PLANE && tga_bus_tc) {
+ BT459_LOAD_ADDR(par, regno);
+ TGA_WRITE_REG(par, BT459_PALETTE << 2, TGA_RAMDAC_SETUP_REG);
+ TGA_WRITE_REG(par, red, TGA_RAMDAC_REG);
+ TGA_WRITE_REG(par, green, TGA_RAMDAC_REG);
+ TGA_WRITE_REG(par, blue, TGA_RAMDAC_REG);
} else {
if (regno < 16) {
u32 value = (regno << 16) | (regno << 8) | regno;
@@ -523,16 +623,8 @@
* Acceleration.
*/
-/**
- * tgafb_imageblit - REQUIRED function. Can use generic routines if
- * non acclerated hardware and packed pixel based.
- * Copies a image from system memory to the screen.
- *
- * @info: frame buffer structure that represents a single frame buffer
- * @image: structure defining the image.
- */
static void
-tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
+tgafb_mono_imageblit(struct fb_info *info, const struct fb_image *image)
{
struct tga_par *par = (struct tga_par *) info->par;
u32 fgcolor, bgcolor, dx, dy, width, height, vxres, vyres, pixelmask;
@@ -542,6 +634,17 @@
void __iomem *regs_base;
void __iomem *fb_base;
+ is8bpp = info->var.bits_per_pixel == 8;
+
+ /* For copies that aren't pixel expansion, there's little we
+ can do better than the generic code. */
+ /* ??? There is a DMA write mode; I wonder if that could be
+ made to pull the data from the image buffer... */
+ if (image->depth > 1) {
+ cfb_imageblit(info, image);
+ return;
+ }
+
dx = image->dx;
dy = image->dy;
width = image->width;
@@ -559,18 +662,8 @@
if (dy + height > vyres)
height = vyres - dy;
- /* For copies that aren't pixel expansion, there's little we
- can do better than the generic code. */
- /* ??? There is a DMA write mode; I wonder if that could be
- made to pull the data from the image buffer... */
- if (image->depth > 1) {
- cfb_imageblit(info, image);
- return;
- }
-
regs_base = par->tga_regs_base;
fb_base = par->tga_fb_base;
- is8bpp = info->var.bits_per_pixel == 8;
/* Expand the color values to fill 32-bits. */
/* ??? Would be nice to notice colour changes elsewhere, so
@@ -748,6 +841,85 @@
regs_base + TGA_MODE_REG);
}
+static void
+tgafb_clut_imageblit(struct fb_info *info, const struct fb_image *image)
+{
+ struct tga_par *par = (struct tga_par *) info->par;
+ u32 color, dx, dy, width, height, vxres, vyres;
+ u32 *palette = ((u32 *)info->pseudo_palette);
+ unsigned long pos, line_length, i, j;
+ const unsigned char *data;
+ void *regs_base, *fb_base;
+
+ dx = image->dx;
+ dy = image->dy;
+ width = image->width;
+ height = image->height;
+ vxres = info->var.xres_virtual;
+ vyres = info->var.yres_virtual;
+ line_length = info->fix.line_length;
+
+ /* Crop the image to the screen. */
+ if (dx > vxres || dy > vyres)
+ return;
+ if (dx + width > vxres)
+ width = vxres - dx;
+ if (dy + height > vyres)
+ height = vyres - dy;
+
+ regs_base = par->tga_regs_base;
+ fb_base = par->tga_fb_base;
+
+ pos = dy * line_length + (dx * 4);
+ data = image->data;
+
+ /* Now copy the image, color_expanding via the palette. */
+ for (i = 0; i < height; i++) {
+ for (j = 0; j < width; j++) {
+ color = palette[*data++];
+ __raw_writel(color, fb_base + pos + j*4);
+ }
+ pos += line_length;
+ }
+}
+
+/**
+ * tgafb_imageblit - REQUIRED function. Can use generic routines if
+ * non acclerated hardware and packed pixel based.
+ * Copies a image from system memory to the screen.
+ *
+ * @info: frame buffer structure that represents a single frame buffer
+ * @image: structure defining the image.
+ */
+static void
+tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
+{
+ unsigned int is8bpp = info->var.bits_per_pixel == 8;
+
+ /* If a mono image, regardless of FB depth, go do it. */
+ if (image->depth == 1) {
+ tgafb_mono_imageblit(info, image);
+ return;
+ }
+
+ /* For copies that aren't pixel expansion, there's little we
+ can do better than the generic code. */
+ /* ??? There is a DMA write mode; I wonder if that could be
+ made to pull the data from the image buffer... */
+ if (image->depth == info->var.bits_per_pixel) {
+ cfb_imageblit(info, image);
+ return;
+ }
+
+ /* If 24-plane FB and the image is 8-plane with CLUT, we can do it. */
+ if (!is8bpp && image->depth == 8) {
+ tgafb_clut_imageblit(info, image);
+ return;
+ }
+
+ /* Silently return... */
+}
+
/**
* tgafb_fillrect - REQUIRED function. Can use generic routines if
* non acclerated hardware and packed pixel based.
@@ -1309,18 +1481,29 @@
tgafb_init_fix(struct fb_info *info)
{
struct tga_par *par = (struct tga_par *)info->par;
+ int tga_bus_pci = TGA_BUS_PCI(par->dev);
+ int tga_bus_tc = TGA_BUS_TC(par->dev);
u8 tga_type = par->tga_type;
- const char *tga_type_name;
+ const char *tga_type_name = NULL;
switch (tga_type) {
case TGA_TYPE_8PLANE:
- tga_type_name = "Digital ZLXp-E1";
+ if (tga_bus_pci)
+ tga_type_name = "Digital ZLXp-E1";
+ if (tga_bus_tc)
+ tga_type_name = "Digital ZLX-E1";
break;
case TGA_TYPE_24PLANE:
- tga_type_name = "Digital ZLXp-E2";
+ if (tga_bus_pci)
+ tga_type_name = "Digital ZLXp-E2";
+ if (tga_bus_tc)
+ tga_type_name = "Digital ZLX-E2";
break;
case TGA_TYPE_24PLUSZ:
- tga_type_name = "Digital ZLXp-E3";
+ if (tga_bus_pci)
+ tga_type_name = "Digital ZLXp-E3";
+ if (tga_bus_tc)
+ tga_type_name = "Digital ZLX-E3";
break;
default:
tga_type_name = "Unknown";
@@ -1346,11 +1529,37 @@
info->fix.ywrapstep = 0;
info->fix.accel = FB_ACCEL_DEC_TGA;
+
+ /*
+ * These are needed by fb_set_logo_truepalette(), so we
+ * set them here for 24-plane cards.
+ */
+ if (tga_type != TGA_TYPE_8PLANE) {
+ info->var.red.length = 8;
+ info->var.green.length = 8;
+ info->var.blue.length = 8;
+ info->var.red.offset = 16;
+ info->var.green.offset = 8;
+ info->var.blue.offset = 0;
+ }
}
-static __devinit int
-tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int tgafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
{
+ /* We just use this to catch switches out of graphics mode. */
+ tgafb_set_par(info); /* A bit of overkill for BASE_ADDR reset. */
+ return 0;
+}
+
+static int __devinit
+tgafb_register(struct device *dev)
+{
+ static const struct fb_videomode modedb_tc = {
+ /* 1280x1024 @ 72 Hz, 76.8 kHz hsync */
+ "1280x1024@72", 0, 1280, 1024, 7645, 224, 28, 33, 3, 160, 3,
+ FB_SYNC_ON_GREEN, FB_VMODE_NONINTERLACED
+ };
+
static unsigned int const fb_offset_presets[4] = {
TGA_8PLANE_FB_OFFSET,
TGA_24PLANE_FB_OFFSET,
@@ -1358,40 +1567,51 @@
TGA_24PLUSZ_FB_OFFSET
};
+ const struct fb_videomode *modedb_tga = NULL;
+ resource_size_t bar0_start = 0, bar0_len = 0;
+ const char *mode_option_tga = NULL;
+ int tga_bus_pci = TGA_BUS_PCI(dev);
+ int tga_bus_tc = TGA_BUS_TC(dev);
+ unsigned int modedbsize_tga = 0;
void __iomem *mem_base;
- unsigned long bar0_start, bar0_len;
struct fb_info *info;
struct tga_par *par;
u8 tga_type;
- int ret;
+ int ret = 0;
/* Enable device in PCI config. */
- if (pci_enable_device(pdev)) {
+ if (tga_bus_pci && pci_enable_device(to_pci_dev(dev))) {
printk(KERN_ERR "tgafb: Cannot enable PCI device\n");
return -ENODEV;
}
/* Allocate the fb and par structures. */
- info = framebuffer_alloc(sizeof(struct tga_par), &pdev->dev);
+ info = framebuffer_alloc(sizeof(struct tga_par), dev);
if (!info) {
printk(KERN_ERR "tgafb: Cannot allocate memory\n");
return -ENOMEM;
}
par = info->par;
- pci_set_drvdata(pdev, info);
+ dev_set_drvdata(dev, info);
/* Request the mem regions. */
- bar0_start = pci_resource_start(pdev, 0);
- bar0_len = pci_resource_len(pdev, 0);
ret = -ENODEV;
+ if (tga_bus_pci) {
+ bar0_start = pci_resource_start(to_pci_dev(dev), 0);
+ bar0_len = pci_resource_len(to_pci_dev(dev), 0);
+ }
+ if (tga_bus_tc) {
+ bar0_start = to_tc_dev(dev)->resource.start;
+ bar0_len = to_tc_dev(dev)->resource.end - bar0_start + 1;
+ }
if (!request_mem_region (bar0_start, bar0_len, "tgafb")) {
printk(KERN_ERR "tgafb: cannot reserve FB region\n");
goto err0;
}
/* Map the framebuffer. */
- mem_base = ioremap(bar0_start, bar0_len);
+ mem_base = ioremap_nocache(bar0_start, bar0_len);
if (!mem_base) {
printk(KERN_ERR "tgafb: Cannot map MMIO\n");
goto err1;
@@ -1399,12 +1619,16 @@
/* Grab info about the card. */
tga_type = (readl(mem_base) >> 12) & 0x0f;
- par->pdev = pdev;
+ par->dev = dev;
par->tga_mem_base = mem_base;
par->tga_fb_base = mem_base + fb_offset_presets[tga_type];
par->tga_regs_base = mem_base + TGA_REGS_OFFSET;
par->tga_type = tga_type;
- pci_read_config_byte(pdev, PCI_REVISION_ID, &par->tga_chip_rev);
+ if (tga_bus_pci)
+ pci_read_config_byte(to_pci_dev(dev), PCI_REVISION_ID,
+ &par->tga_chip_rev);
+ if (tga_bus_tc)
+ par->tga_chip_rev = TGA_READ_REG(par, TGA_START_REG) & 0xff;
/* Setup framebuffer. */
info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA |
@@ -1414,8 +1638,17 @@
info->pseudo_palette = (void *)(par + 1);
/* This should give a reasonable default video mode. */
-
- ret = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL,
+ if (tga_bus_pci) {
+ mode_option_tga = mode_option_pci;
+ }
+ if (tga_bus_tc) {
+ mode_option_tga = mode_option_tc;
+ modedb_tga = &modedb_tc;
+ modedbsize_tga = 1;
+ }
+ ret = fb_find_mode(&info->var, info,
+ mode_option ? mode_option : mode_option_tga,
+ modedb_tga, modedbsize_tga, NULL,
tga_type == TGA_TYPE_8PLANE ? 8 : 32);
if (ret == 0 || ret == 4) {
printk(KERN_ERR "tgafb: Could not find valid video mode\n");
@@ -1438,13 +1671,19 @@
goto err1;
}
- printk(KERN_INFO "tgafb: DC21030 [TGA] detected, rev=0x%02x\n",
- par->tga_chip_rev);
- printk(KERN_INFO "tgafb: at PCI bus %d, device %d, function %d\n",
- pdev->bus->number, PCI_SLOT(pdev->devfn),
- PCI_FUNC(pdev->devfn));
- printk(KERN_INFO "fb%d: %s frame buffer device at 0x%lx\n",
- info->node, info->fix.id, bar0_start);
+ if (tga_bus_pci) {
+ pr_info("tgafb: DC21030 [TGA] detected, rev=0x%02x\n",
+ par->tga_chip_rev);
+ pr_info("tgafb: at PCI bus %d, device %d, function %d\n",
+ to_pci_dev(dev)->bus->number,
+ PCI_SLOT(to_pci_dev(dev)->devfn),
+ PCI_FUNC(to_pci_dev(dev)->devfn));
+ }
+ if (tga_bus_tc)
+ pr_info("tgafb: SFB+ detected, rev=0x%02x\n",
+ par->tga_chip_rev);
+ pr_info("fb%d: %s frame buffer device at 0x%lx\n",
+ info->node, info->fix.id, (long)bar0_start);
return 0;
@@ -1458,25 +1697,39 @@
}
static void __devexit
-tgafb_pci_unregister(struct pci_dev *pdev)
+tgafb_unregister(struct device *dev)
{
- struct fb_info *info = pci_get_drvdata(pdev);
- struct tga_par *par = info->par;
+ resource_size_t bar0_start = 0, bar0_len = 0;
+ int tga_bus_pci = TGA_BUS_PCI(dev);
+ int tga_bus_tc = TGA_BUS_TC(dev);
+ struct fb_info *info = NULL;
+ struct tga_par *par;
+ info = dev_get_drvdata(dev);
if (!info)
return;
+
+ par = info->par;
unregister_framebuffer(info);
fb_dealloc_cmap(&info->cmap);
iounmap(par->tga_mem_base);
- release_mem_region(pci_resource_start(pdev, 0),
- pci_resource_len(pdev, 0));
+ if (tga_bus_pci) {
+ bar0_start = pci_resource_start(to_pci_dev(dev), 0);
+ bar0_len = pci_resource_len(to_pci_dev(dev), 0);
+ }
+ if (tga_bus_tc) {
+ bar0_start = to_tc_dev(dev)->resource.start;
+ bar0_len = to_tc_dev(dev)->resource.end - bar0_start + 1;
+ }
+ release_mem_region(bar0_start, bar0_len);
framebuffer_release(info);
}
static void __devexit
tgafb_exit(void)
{
- pci_unregister_driver(&tgafb_driver);
+ tc_unregister_driver(&tgafb_tc_driver);
+ pci_unregister_driver(&tgafb_pci_driver);
}
#ifndef MODULE
@@ -1505,6 +1758,7 @@
static int __devinit
tgafb_init(void)
{
+ int status;
#ifndef MODULE
char *option = NULL;
@@ -1512,7 +1766,10 @@
return -ENODEV;
tgafb_setup(option);
#endif
- return pci_register_driver(&tgafb_driver);
+ status = pci_register_driver(&tgafb_pci_driver);
+ if (!status)
+ status = tc_register_driver(&tgafb_tc_driver);
+ return status;
}
/*
@@ -1522,5 +1779,5 @@
module_init(tgafb_init);
module_exit(tgafb_exit);
-MODULE_DESCRIPTION("framebuffer driver for TGA chipset");
+MODULE_DESCRIPTION("Framebuffer driver for TGA/SFB+ chipset");
MODULE_LICENSE("GPL");
diff --git a/drivers/video/vermilion/Makefile b/drivers/video/vermilion/Makefile
new file mode 100644
index 0000000..cc21a65
--- /dev/null
+++ b/drivers/video/vermilion/Makefile
@@ -0,0 +1,5 @@
+obj-$(CONFIG_FB_LE80578) += vmlfb.o
+obj-$(CONFIG_FB_CARILLO_RANCH) += crvml.o
+
+vmlfb-objs := vermilion.o
+crvml-objs := cr_pll.o
diff --git a/drivers/video/vermilion/cr_pll.c b/drivers/video/vermilion/cr_pll.c
new file mode 100644
index 0000000..ebc6e6e
--- /dev/null
+++ b/drivers/video/vermilion/cr_pll.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) Intel Corp. 2007.
+ * All Rights Reserved.
+ *
+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ * develop this driver.
+ *
+ * This file is part of the Carillo Ranch video subsystem driver.
+ * The Carillo Ranch video subsystem driver is free software;
+ * you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The Carillo Ranch video subsystem driver is distributed
+ * in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this driver; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors:
+ * Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
+ * Alan Hourihane <alanh-at-tungstengraphics-dot-com>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/errno.h>
+#include <linux/fb.h>
+#include "vermilion.h"
+
+/* The PLL Clock register sits on Host bridge */
+#define CRVML_DEVICE_MCH 0x5001
+#define CRVML_REG_MCHBAR 0x44
+#define CRVML_REG_MCHEN 0x54
+#define CRVML_MCHEN_BIT (1 << 28)
+#define CRVML_MCHMAP_SIZE 4096
+#define CRVML_REG_CLOCK 0xc3c
+#define CRVML_CLOCK_SHIFT 8
+#define CRVML_CLOCK_MASK 0x00000f00
+
+static struct pci_dev *mch_dev;
+static u32 mch_bar;
+static void __iomem *mch_regs_base;
+static u32 saved_clock;
+
+static const unsigned crvml_clocks[] = {
+ 6750,
+ 13500,
+ 27000,
+ 29700,
+ 37125,
+ 54000,
+ 59400,
+ 74250,
+ 120000
+ /*
+ * There are more clocks, but they are disabled on the CR board.
+ */
+};
+
+static const u32 crvml_clock_bits[] = {
+ 0x0a,
+ 0x09,
+ 0x08,
+ 0x07,
+ 0x06,
+ 0x05,
+ 0x04,
+ 0x03,
+ 0x0b
+};
+
+static const unsigned crvml_num_clocks = ARRAY_SIZE(crvml_clocks);
+
+static int crvml_sys_restore(struct vml_sys *sys)
+{
+ void __iomem *clock_reg = mch_regs_base + CRVML_REG_CLOCK;
+
+ iowrite32(saved_clock, clock_reg);
+ ioread32(clock_reg);
+
+ return 0;
+}
+
+static int crvml_sys_save(struct vml_sys *sys)
+{
+ void __iomem *clock_reg = mch_regs_base + CRVML_REG_CLOCK;
+
+ saved_clock = ioread32(clock_reg);
+
+ return 0;
+}
+
+static int crvml_nearest_index(const struct vml_sys *sys, int clock)
+{
+ int i;
+ int cur_index = 0;
+ int cur_diff;
+ int diff;
+
+ cur_diff = clock - crvml_clocks[0];
+ cur_diff = (cur_diff < 0) ? -cur_diff : cur_diff;
+ for (i = 1; i < crvml_num_clocks; ++i) {
+ diff = clock - crvml_clocks[i];
+ diff = (diff < 0) ? -diff : diff;
+ if (diff < cur_diff) {
+ cur_index = i;
+ cur_diff = diff;
+ }
+ }
+ return cur_index;
+}
+
+static int crvml_nearest_clock(const struct vml_sys *sys, int clock)
+{
+ return crvml_clocks[crvml_nearest_index(sys, clock)];
+}
+
+static int crvml_set_clock(struct vml_sys *sys, int clock)
+{
+ void __iomem *clock_reg = mch_regs_base + CRVML_REG_CLOCK;
+ int index;
+ u32 clock_val;
+
+ index = crvml_nearest_index(sys, clock);
+
+ if (crvml_clocks[index] != clock)
+ return -EINVAL;
+
+ clock_val = ioread32(clock_reg) & ~CRVML_CLOCK_MASK;
+ clock_val = crvml_clock_bits[index] << CRVML_CLOCK_SHIFT;
+ iowrite32(clock_val, clock_reg);
+ ioread32(clock_reg);
+
+ return 0;
+}
+
+static struct vml_sys cr_pll_ops = {
+ .name = "Carillo Ranch",
+ .save = crvml_sys_save,
+ .restore = crvml_sys_restore,
+ .set_clock = crvml_set_clock,
+ .nearest_clock = crvml_nearest_clock,
+};
+
+static int __init cr_pll_init(void)
+{
+ int err;
+ u32 dev_en;
+
+ mch_dev = pci_get_device(PCI_VENDOR_ID_INTEL,
+ CRVML_DEVICE_MCH, NULL);
+ if (!mch_dev) {
+ printk(KERN_ERR
+ "Could not find Carillo Ranch MCH device.\n");
+ return -ENODEV;
+ }
+
+ pci_read_config_dword(mch_dev, CRVML_REG_MCHEN, &dev_en);
+ if (!(dev_en & CRVML_MCHEN_BIT)) {
+ printk(KERN_ERR
+ "Carillo Ranch MCH device was not enabled.\n");
+ pci_dev_put(mch_dev);
+ return -ENODEV;
+ }
+
+ pci_read_config_dword(mch_dev, CRVML_REG_MCHBAR,
+ &mch_bar);
+ mch_regs_base =
+ ioremap_nocache(mch_bar, CRVML_MCHMAP_SIZE);
+ if (!mch_regs_base) {
+ printk(KERN_ERR
+ "Carillo Ranch MCH device was not enabled.\n");
+ pci_dev_put(mch_dev);
+ return -ENODEV;
+ }
+
+ err = vmlfb_register_subsys(&cr_pll_ops);
+ if (err) {
+ printk(KERN_ERR
+ "Carillo Ranch failed to initialize vml_sys.\n");
+ pci_dev_put(mch_dev);
+ return err;
+ }
+
+ return 0;
+}
+
+static void __exit cr_pll_exit(void)
+{
+ vmlfb_unregister_subsys(&cr_pll_ops);
+
+ iounmap(mch_regs_base);
+ pci_dev_put(mch_dev);
+}
+
+module_init(cr_pll_init);
+module_exit(cr_pll_exit);
+
+MODULE_AUTHOR("Tungsten Graphics Inc.");
+MODULE_DESCRIPTION("Carillo Ranch PLL Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/vermilion/vermilion.c b/drivers/video/vermilion/vermilion.c
new file mode 100644
index 0000000..de531c9
--- /dev/null
+++ b/drivers/video/vermilion/vermilion.c
@@ -0,0 +1,1195 @@
+/*
+ * Copyright (c) Intel Corp. 2007.
+ * All Rights Reserved.
+ *
+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ * develop this driver.
+ *
+ * This file is part of the Vermilion Range fb driver.
+ * The Vermilion Range fb driver is free software;
+ * you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The Vermilion Range fb driver is distributed
+ * in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this driver; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors:
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ * Michel Dänzer <michel-at-tungstengraphics-dot-com>
+ * Alan Hourihane <alanh-at-tungstengraphics-dot-com>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <linux/fb.h>
+#include <linux/pci.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+#include <linux/mmzone.h>
+#include <asm/uaccess.h>
+
+/* #define VERMILION_DEBUG */
+
+#include "vermilion.h"
+
+#define MODULE_NAME "vmlfb"
+
+#define VML_TOHW(_val, _width) ((((_val) << (_width)) + 0x7FFF - (_val)) >> 16)
+
+static struct mutex vml_mutex;
+static struct list_head global_no_mode;
+static struct list_head global_has_mode;
+static struct fb_ops vmlfb_ops;
+static struct vml_sys *subsys = NULL;
+static char *vml_default_mode = "1024x768@60";
+static struct fb_videomode defaultmode = {
+ NULL, 60, 1024, 768, 12896, 144, 24, 29, 3, 136, 6,
+ 0, FB_VMODE_NONINTERLACED
+};
+
+static u32 vml_mem_requested = (10 * 1024 * 1024);
+static u32 vml_mem_contig = (4 * 1024 * 1024);
+static u32 vml_mem_min = (4 * 1024 * 1024);
+
+static u32 vml_clocks[] = {
+ 6750,
+ 13500,
+ 27000,
+ 29700,
+ 37125,
+ 54000,
+ 59400,
+ 74250,
+ 120000,
+ 148500
+};
+
+static u32 vml_num_clocks = ARRAY_SIZE(vml_clocks);
+
+/*
+ * Allocate a contiguous vram area and make its linear kernel map
+ * uncached.
+ */
+
+static int vmlfb_alloc_vram_area(struct vram_area *va, unsigned max_order,
+ unsigned min_order)
+{
+ gfp_t flags;
+ unsigned long i;
+ pgprot_t wc_pageprot;
+
+ wc_pageprot = PAGE_KERNEL_NOCACHE;
+ max_order++;
+ do {
+ /*
+ * Really try hard to get the needed memory.
+ * We need memory below the first 32MB, so we
+ * add the __GFP_DMA flag that guarantees that we are
+ * below the first 16MB.
+ */
+
+ flags = __GFP_DMA | __GFP_HIGH;
+ va->logical =
+ __get_free_pages(flags, --max_order);
+ } while (va->logical == 0 && max_order > min_order);
+
+ if (!va->logical)
+ return -ENOMEM;
+
+ va->phys = virt_to_phys((void *)va->logical);
+ va->size = PAGE_SIZE << max_order;
+ va->order = max_order;
+
+ /*
+ * It seems like __get_free_pages only ups the usage count
+ * of the first page. This doesn't work with nopage mapping, so
+ * up the usage count once more.
+ */
+
+ memset((void *)va->logical, 0x00, va->size);
+ for (i = va->logical; i < va->logical + va->size; i += PAGE_SIZE) {
+ get_page(virt_to_page(i));
+ }
+
+ /*
+ * Change caching policy of the linear kernel map to avoid
+ * mapping type conflicts with user-space mappings.
+ * The first global_flush_tlb() is really only there to do a global
+ * wbinvd().
+ */
+
+ global_flush_tlb();
+ change_page_attr(virt_to_page(va->logical), va->size >> PAGE_SHIFT,
+ wc_pageprot);
+ global_flush_tlb();
+
+ printk(KERN_DEBUG MODULE_NAME
+ ": Allocated %ld bytes vram area at 0x%08lx\n",
+ va->size, va->phys);
+
+ return 0;
+}
+
+/*
+ * Free a contiguous vram area and reset its linear kernel map
+ * mapping type.
+ */
+
+static void vmlfb_free_vram_area(struct vram_area *va)
+{
+ unsigned long j;
+
+ if (va->logical) {
+
+ /*
+ * Reset the linear kernel map caching policy.
+ */
+
+ change_page_attr(virt_to_page(va->logical),
+ va->size >> PAGE_SHIFT, PAGE_KERNEL);
+ global_flush_tlb();
+
+ /*
+ * Decrease the usage count on the pages we've used
+ * to compensate for upping when allocating.
+ */
+
+ for (j = va->logical; j < va->logical + va->size;
+ j += PAGE_SIZE) {
+ (void)put_page_testzero(virt_to_page(j));
+ }
+
+ printk(KERN_DEBUG MODULE_NAME
+ ": Freeing %ld bytes vram area at 0x%08lx\n",
+ va->size, va->phys);
+ free_pages(va->logical, va->order);
+
+ va->logical = 0;
+ }
+}
+
+/*
+ * Free allocated vram.
+ */
+
+static void vmlfb_free_vram(struct vml_info *vinfo)
+{
+ int i;
+
+ for (i = 0; i < vinfo->num_areas; ++i) {
+ vmlfb_free_vram_area(&vinfo->vram[i]);
+ }
+ vinfo->num_areas = 0;
+}
+
+/*
+ * Allocate vram. Currently we try to allocate contiguous areas from the
+ * __GFP_DMA zone and puzzle them together. A better approach would be to
+ * allocate one contiguous area for scanout and use one-page allocations for
+ * offscreen areas. This requires user-space and GPU virtual mappings.
+ */
+
+static int vmlfb_alloc_vram(struct vml_info *vinfo,
+ size_t requested,
+ size_t min_total, size_t min_contig)
+{
+ int i, j;
+ int order;
+ int contiguous;
+ int err;
+ struct vram_area *va;
+ struct vram_area *va2;
+
+ vinfo->num_areas = 0;
+ for (i = 0; i < VML_VRAM_AREAS; ++i) {
+ va = &vinfo->vram[i];
+ order = 0;
+
+ while (requested > (PAGE_SIZE << order) && order < MAX_ORDER)
+ order++;
+
+ err = vmlfb_alloc_vram_area(va, order, 0);
+
+ if (err)
+ break;
+
+ if (i == 0) {
+ vinfo->vram_start = va->phys;
+ vinfo->vram_logical = (void __iomem *) va->logical;
+ vinfo->vram_contig_size = va->size;
+ vinfo->num_areas = 1;
+ } else {
+ contiguous = 0;
+
+ for (j = 0; j < i; ++j) {
+ va2 = &vinfo->vram[j];
+ if (va->phys + va->size == va2->phys ||
+ va2->phys + va2->size == va->phys) {
+ contiguous = 1;
+ break;
+ }
+ }
+
+ if (contiguous) {
+ vinfo->num_areas++;
+ if (va->phys < vinfo->vram_start) {
+ vinfo->vram_start = va->phys;
+ vinfo->vram_logical =
+ (void __iomem *)va->logical;
+ }
+ vinfo->vram_contig_size += va->size;
+ } else {
+ vmlfb_free_vram_area(va);
+ break;
+ }
+ }
+
+ if (requested < va->size)
+ break;
+ else
+ requested -= va->size;
+ }
+
+ if (vinfo->vram_contig_size > min_total &&
+ vinfo->vram_contig_size > min_contig) {
+
+ printk(KERN_DEBUG MODULE_NAME
+ ": Contiguous vram: %ld bytes at physical 0x%08lx.\n",
+ (unsigned long)vinfo->vram_contig_size,
+ (unsigned long)vinfo->vram_start);
+
+ return 0;
+ }
+
+ printk(KERN_ERR MODULE_NAME
+ ": Could not allocate requested minimal amount of vram.\n");
+
+ vmlfb_free_vram(vinfo);
+
+ return -ENOMEM;
+}
+
+/*
+ * Find the GPU to use with our display controller.
+ */
+
+static int vmlfb_get_gpu(struct vml_par *par)
+{
+ mutex_lock(&vml_mutex);
+
+ par->gpu = pci_get_device(PCI_VENDOR_ID_INTEL, VML_DEVICE_GPU, NULL);
+
+ if (!par->gpu) {
+ mutex_unlock(&vml_mutex);
+ return -ENODEV;
+ }
+
+ mutex_unlock(&vml_mutex);
+
+ if (pci_enable_device(par->gpu) < 0)
+ return -ENODEV;
+
+ return 0;
+}
+
+/*
+ * Find a contiguous vram area that contains a given offset from vram start.
+ */
+static int vmlfb_vram_offset(struct vml_info *vinfo, unsigned long offset)
+{
+ unsigned long aoffset;
+ unsigned i;
+
+ for (i = 0; i < vinfo->num_areas; ++i) {
+ aoffset = offset - (vinfo->vram[i].phys - vinfo->vram_start);
+
+ if (aoffset < vinfo->vram[i].size) {
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+/*
+ * Remap the MMIO register spaces of the VDC and the GPU.
+ */
+
+static int vmlfb_enable_mmio(struct vml_par *par)
+{
+ int err;
+
+ par->vdc_mem_base = pci_resource_start(par->vdc, 0);
+ par->vdc_mem_size = pci_resource_len(par->vdc, 0);
+ if (!request_mem_region(par->vdc_mem_base, par->vdc_mem_size, "vmlfb")) {
+ printk(KERN_ERR MODULE_NAME
+ ": Could not claim display controller MMIO.\n");
+ return -EBUSY;
+ }
+ par->vdc_mem = ioremap_nocache(par->vdc_mem_base, par->vdc_mem_size);
+ if (par->vdc_mem == NULL) {
+ printk(KERN_ERR MODULE_NAME
+ ": Could not map display controller MMIO.\n");
+ err = -ENOMEM;
+ goto out_err_0;
+ }
+
+ par->gpu_mem_base = pci_resource_start(par->gpu, 0);
+ par->gpu_mem_size = pci_resource_len(par->gpu, 0);
+ if (!request_mem_region(par->gpu_mem_base, par->gpu_mem_size, "vmlfb")) {
+ printk(KERN_ERR MODULE_NAME ": Could not claim GPU MMIO.\n");
+ err = -EBUSY;
+ goto out_err_1;
+ }
+ par->gpu_mem = ioremap_nocache(par->gpu_mem_base, par->gpu_mem_size);
+ if (par->gpu_mem == NULL) {
+ printk(KERN_ERR MODULE_NAME ": Could not map GPU MMIO.\n");
+ err = -ENOMEM;
+ goto out_err_2;
+ }
+
+ return 0;
+
+out_err_2:
+ release_mem_region(par->gpu_mem_base, par->gpu_mem_size);
+out_err_1:
+ iounmap(par->vdc_mem);
+out_err_0:
+ release_mem_region(par->vdc_mem_base, par->vdc_mem_size);
+ return err;
+}
+
+/*
+ * Unmap the VDC and GPU register spaces.
+ */
+
+static void vmlfb_disable_mmio(struct vml_par *par)
+{
+ iounmap(par->gpu_mem);
+ release_mem_region(par->gpu_mem_base, par->gpu_mem_size);
+ iounmap(par->vdc_mem);
+ release_mem_region(par->vdc_mem_base, par->vdc_mem_size);
+}
+
+/*
+ * Release and uninit the VDC and GPU.
+ */
+
+static void vmlfb_release_devices(struct vml_par *par)
+{
+ if (atomic_dec_and_test(&par->refcount)) {
+ pci_set_drvdata(par->vdc, NULL);
+ pci_disable_device(par->gpu);
+ pci_disable_device(par->vdc);
+ }
+}
+
+/*
+ * Free up allocated resources for a device.
+ */
+
+static void __devexit vml_pci_remove(struct pci_dev *dev)
+{
+ struct fb_info *info;
+ struct vml_info *vinfo;
+ struct vml_par *par;
+
+ info = pci_get_drvdata(dev);
+ if (info) {
+ vinfo = container_of(info, struct vml_info, info);
+ par = vinfo->par;
+ mutex_lock(&vml_mutex);
+ unregister_framebuffer(info);
+ fb_dealloc_cmap(&info->cmap);
+ vmlfb_free_vram(vinfo);
+ vmlfb_disable_mmio(par);
+ vmlfb_release_devices(par);
+ kfree(vinfo);
+ kfree(par);
+ mutex_unlock(&vml_mutex);
+ }
+}
+
+static void vmlfb_set_pref_pixel_format(struct fb_var_screeninfo *var)
+{
+ switch (var->bits_per_pixel) {
+ case 16:
+ var->blue.offset = 0;
+ var->blue.length = 5;
+ var->green.offset = 5;
+ var->green.length = 5;
+ var->red.offset = 10;
+ var->red.length = 5;
+ var->transp.offset = 15;
+ var->transp.length = 1;
+ break;
+ case 32:
+ var->blue.offset = 0;
+ var->blue.length = 8;
+ var->green.offset = 8;
+ var->green.length = 8;
+ var->red.offset = 16;
+ var->red.length = 8;
+ var->transp.offset = 24;
+ var->transp.length = 0;
+ break;
+ default:
+ break;
+ }
+
+ var->blue.msb_right = var->green.msb_right =
+ var->red.msb_right = var->transp.msb_right = 0;
+}
+
+/*
+ * Device initialization.
+ * We initialize one vml_par struct per device and one vml_info
+ * struct per pipe. Currently we have only one pipe.
+ */
+
+static int __devinit vml_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *id)
+{
+ struct vml_info *vinfo;
+ struct fb_info *info;
+ struct vml_par *par;
+ int err = 0;
+
+ par = kzalloc(sizeof(*par), GFP_KERNEL);
+ if (par == NULL)
+ return -ENOMEM;
+
+ vinfo = kzalloc(sizeof(*vinfo), GFP_KERNEL);
+ if (vinfo == NULL) {
+ err = -ENOMEM;
+ goto out_err_0;
+ }
+
+ vinfo->par = par;
+ par->vdc = dev;
+ atomic_set(&par->refcount, 1);
+
+ switch (id->device) {
+ case VML_DEVICE_VDC:
+ if ((err = vmlfb_get_gpu(par)))
+ goto out_err_1;
+ pci_set_drvdata(dev, &vinfo->info);
+ break;
+ default:
+ err = -ENODEV;
+ goto out_err_1;
+ break;
+ }
+
+ info = &vinfo->info;
+ info->flags = FBINFO_DEFAULT | FBINFO_PARTIAL_PAN_OK;
+
+ err = vmlfb_enable_mmio(par);
+ if (err)
+ goto out_err_2;
+
+ err = vmlfb_alloc_vram(vinfo, vml_mem_requested,
+ vml_mem_contig, vml_mem_min);
+ if (err)
+ goto out_err_3;
+
+ strcpy(info->fix.id, "Vermilion Range");
+ info->fix.mmio_start = 0;
+ info->fix.mmio_len = 0;
+ info->fix.smem_start = vinfo->vram_start;
+ info->fix.smem_len = vinfo->vram_contig_size;
+ info->fix.type = FB_TYPE_PACKED_PIXELS;
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+ info->fix.ypanstep = 1;
+ info->fix.xpanstep = 1;
+ info->fix.ywrapstep = 0;
+ info->fix.accel = FB_ACCEL_NONE;
+ info->screen_base = vinfo->vram_logical;
+ info->pseudo_palette = vinfo->pseudo_palette;
+ info->par = par;
+ info->fbops = &vmlfb_ops;
+ info->device = &dev->dev;
+
+ INIT_LIST_HEAD(&vinfo->head);
+ vinfo->pipe_disabled = 1;
+ vinfo->cur_blank_mode = FB_BLANK_UNBLANK;
+
+ info->var.grayscale = 0;
+ info->var.bits_per_pixel = 16;
+ vmlfb_set_pref_pixel_format(&info->var);
+
+ if (!fb_find_mode
+ (&info->var, info, vml_default_mode, NULL, 0, &defaultmode, 16)) {
+ printk(KERN_ERR MODULE_NAME ": Could not find initial mode\n");
+ }
+
+ if (fb_alloc_cmap(&info->cmap, 256, 1) < 0) {
+ err = -ENOMEM;
+ goto out_err_4;
+ }
+
+ err = register_framebuffer(info);
+ if (err) {
+ printk(KERN_ERR MODULE_NAME ": Register framebuffer error.\n");
+ goto out_err_5;
+ }
+
+ printk("Initialized vmlfb\n");
+
+ return 0;
+
+out_err_5:
+ fb_dealloc_cmap(&info->cmap);
+out_err_4:
+ vmlfb_free_vram(vinfo);
+out_err_3:
+ vmlfb_disable_mmio(par);
+out_err_2:
+ vmlfb_release_devices(par);
+out_err_1:
+ kfree(vinfo);
+out_err_0:
+ kfree(par);
+ return err;
+}
+
+static int vmlfb_open(struct fb_info *info, int user)
+{
+ /*
+ * Save registers here?
+ */
+ return 0;
+}
+
+static int vmlfb_release(struct fb_info *info, int user)
+{
+ /*
+ * Restore registers here.
+ */
+
+ return 0;
+}
+
+static int vml_nearest_clock(int clock)
+{
+
+ int i;
+ int cur_index;
+ int cur_diff;
+ int diff;
+
+ cur_index = 0;
+ cur_diff = clock - vml_clocks[0];
+ cur_diff = (cur_diff < 0) ? -cur_diff : cur_diff;
+ for (i = 1; i < vml_num_clocks; ++i) {
+ diff = clock - vml_clocks[i];
+ diff = (diff < 0) ? -diff : diff;
+ if (diff < cur_diff) {
+ cur_index = i;
+ cur_diff = diff;
+ }
+ }
+ return vml_clocks[cur_index];
+}
+
+static int vmlfb_check_var_locked(struct fb_var_screeninfo *var,
+ struct vml_info *vinfo)
+{
+ u32 pitch;
+ u64 mem;
+ int nearest_clock;
+ int clock;
+ int clock_diff;
+ struct fb_var_screeninfo v;
+
+ v = *var;
+ clock = PICOS2KHZ(var->pixclock);
+
+ if (subsys && subsys->nearest_clock) {
+ nearest_clock = subsys->nearest_clock(subsys, clock);
+ } else {
+ nearest_clock = vml_nearest_clock(clock);
+ }
+
+ /*
+ * Accept a 20% diff.
+ */
+
+ clock_diff = nearest_clock - clock;
+ clock_diff = (clock_diff < 0) ? -clock_diff : clock_diff;
+ if (clock_diff > clock / 5) {
+#if 0
+ printk(KERN_DEBUG MODULE_NAME ": Diff failure. %d %d\n",clock_diff,clock);
+#endif
+ return -EINVAL;
+ }
+
+ v.pixclock = KHZ2PICOS(nearest_clock);
+
+ if (var->xres > VML_MAX_XRES || var->yres > VML_MAX_YRES) {
+ printk(KERN_DEBUG MODULE_NAME ": Resolution failure.\n");
+ return -EINVAL;
+ }
+ if (var->xres_virtual > VML_MAX_XRES_VIRTUAL) {
+ printk(KERN_DEBUG MODULE_NAME
+ ": Virtual resolution failure.\n");
+ return -EINVAL;
+ }
+ switch (v.bits_per_pixel) {
+ case 0 ... 16:
+ v.bits_per_pixel = 16;
+ break;
+ case 17 ... 32:
+ v.bits_per_pixel = 32;
+ break;
+ default:
+ printk(KERN_DEBUG MODULE_NAME ": Invalid bpp: %d.\n",
+ var->bits_per_pixel);
+ return -EINVAL;
+ }
+
+ pitch = __ALIGN_MASK((var->xres * var->bits_per_pixel) >> 3, 0x3F);
+ mem = pitch * var->yres_virtual;
+ if (mem > vinfo->vram_contig_size) {
+ return -ENOMEM;
+ }
+
+ switch (v.bits_per_pixel) {
+ case 16:
+ if (var->blue.offset != 0 ||
+ var->blue.length != 5 ||
+ var->green.offset != 5 ||
+ var->green.length != 5 ||
+ var->red.offset != 10 ||
+ var->red.length != 5 ||
+ var->transp.offset != 15 || var->transp.length != 1) {
+ vmlfb_set_pref_pixel_format(&v);
+ }
+ break;
+ case 32:
+ if (var->blue.offset != 0 ||
+ var->blue.length != 8 ||
+ var->green.offset != 8 ||
+ var->green.length != 8 ||
+ var->red.offset != 16 ||
+ var->red.length != 8 ||
+ (var->transp.length != 0 && var->transp.length != 8) ||
+ (var->transp.length == 8 && var->transp.offset != 24)) {
+ vmlfb_set_pref_pixel_format(&v);
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ *var = v;
+
+ return 0;
+}
+
+static int vmlfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+ struct vml_info *vinfo = container_of(info, struct vml_info, info);
+ int ret;
+
+ mutex_lock(&vml_mutex);
+ ret = vmlfb_check_var_locked(var, vinfo);
+ mutex_unlock(&vml_mutex);
+
+ return ret;
+}
+
+static void vml_wait_vblank(struct vml_info *vinfo)
+{
+ /* Wait for vblank. For now, just wait for a 50Hz cycle (20ms)) */
+ mdelay(20);
+}
+
+static void vmlfb_disable_pipe(struct vml_info *vinfo)
+{
+ struct vml_par *par = vinfo->par;
+
+ /* Disable the MDVO pad */
+ VML_WRITE32(par, VML_RCOMPSTAT, 0);
+ while (!(VML_READ32(par, VML_RCOMPSTAT) & VML_MDVO_VDC_I_RCOMP)) ;
+
+ /* Disable display planes */
+ VML_WRITE32(par, VML_DSPCCNTR,
+ VML_READ32(par, VML_DSPCCNTR) & ~VML_GFX_ENABLE);
+ (void)VML_READ32(par, VML_DSPCCNTR);
+ /* Wait for vblank for the disable to take effect */
+ vml_wait_vblank(vinfo);
+
+ /* Next, disable display pipes */
+ VML_WRITE32(par, VML_PIPEACONF, 0);
+ (void)VML_READ32(par, VML_PIPEACONF);
+
+ vinfo->pipe_disabled = 1;
+}
+
+#ifdef VERMILION_DEBUG
+static void vml_dump_regs(struct vml_info *vinfo)
+{
+ struct vml_par *par = vinfo->par;
+
+ printk(KERN_DEBUG MODULE_NAME ": Modesetting register dump:\n");
+ printk(KERN_DEBUG MODULE_NAME ": \tHTOTAL_A : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_HTOTAL_A));
+ printk(KERN_DEBUG MODULE_NAME ": \tHBLANK_A : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_HBLANK_A));
+ printk(KERN_DEBUG MODULE_NAME ": \tHSYNC_A : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_HSYNC_A));
+ printk(KERN_DEBUG MODULE_NAME ": \tVTOTAL_A : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_VTOTAL_A));
+ printk(KERN_DEBUG MODULE_NAME ": \tVBLANK_A : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_VBLANK_A));
+ printk(KERN_DEBUG MODULE_NAME ": \tVSYNC_A : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_VSYNC_A));
+ printk(KERN_DEBUG MODULE_NAME ": \tDSPCSTRIDE : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_DSPCSTRIDE));
+ printk(KERN_DEBUG MODULE_NAME ": \tDSPCSIZE : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_DSPCSIZE));
+ printk(KERN_DEBUG MODULE_NAME ": \tDSPCPOS : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_DSPCPOS));
+ printk(KERN_DEBUG MODULE_NAME ": \tDSPARB : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_DSPARB));
+ printk(KERN_DEBUG MODULE_NAME ": \tDSPCADDR : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_DSPCADDR));
+ printk(KERN_DEBUG MODULE_NAME ": \tBCLRPAT_A : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_BCLRPAT_A));
+ printk(KERN_DEBUG MODULE_NAME ": \tCANVSCLR_A : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_CANVSCLR_A));
+ printk(KERN_DEBUG MODULE_NAME ": \tPIPEASRC : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_PIPEASRC));
+ printk(KERN_DEBUG MODULE_NAME ": \tPIPEACONF : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_PIPEACONF));
+ printk(KERN_DEBUG MODULE_NAME ": \tDSPCCNTR : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_DSPCCNTR));
+ printk(KERN_DEBUG MODULE_NAME ": \tRCOMPSTAT : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_RCOMPSTAT));
+ printk(KERN_DEBUG MODULE_NAME ": End of modesetting register dump.\n");
+}
+#endif
+
+static int vmlfb_set_par_locked(struct vml_info *vinfo)
+{
+ struct vml_par *par = vinfo->par;
+ struct fb_info *info = &vinfo->info;
+ struct fb_var_screeninfo *var = &info->var;
+ u32 htotal, hactive, hblank_start, hblank_end, hsync_start, hsync_end;
+ u32 vtotal, vactive, vblank_start, vblank_end, vsync_start, vsync_end;
+ u32 dspcntr;
+ int clock;
+
+ vinfo->bytes_per_pixel = var->bits_per_pixel >> 3;
+ vinfo->stride =
+ __ALIGN_MASK(var->xres_virtual * vinfo->bytes_per_pixel, 0x3F);
+ info->fix.line_length = vinfo->stride;
+
+ if (!subsys)
+ return 0;
+
+ htotal =
+ var->xres + var->right_margin + var->hsync_len + var->left_margin;
+ hactive = var->xres;
+ hblank_start = var->xres;
+ hblank_end = htotal;
+ hsync_start = hactive + var->right_margin;
+ hsync_end = hsync_start + var->hsync_len;
+
+ vtotal =
+ var->yres + var->lower_margin + var->vsync_len + var->upper_margin;
+ vactive = var->yres;
+ vblank_start = var->yres;
+ vblank_end = vtotal;
+ vsync_start = vactive + var->lower_margin;
+ vsync_end = vsync_start + var->vsync_len;
+
+ dspcntr = VML_GFX_ENABLE | VML_GFX_GAMMABYPASS;
+ clock = PICOS2KHZ(var->pixclock);
+
+ if (subsys->nearest_clock) {
+ clock = subsys->nearest_clock(subsys, clock);
+ } else {
+ clock = vml_nearest_clock(clock);
+ }
+ printk(KERN_DEBUG MODULE_NAME
+ ": Set mode Hfreq : %d kHz, Vfreq : %d Hz.\n", clock / htotal,
+ ((clock / htotal) * 1000) / vtotal);
+
+ switch (var->bits_per_pixel) {
+ case 16:
+ dspcntr |= VML_GFX_ARGB1555;
+ break;
+ case 32:
+ if (var->transp.length == 8)
+ dspcntr |= VML_GFX_ARGB8888 | VML_GFX_ALPHAMULT;
+ else
+ dspcntr |= VML_GFX_RGB0888;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ vmlfb_disable_pipe(vinfo);
+ mb();
+
+ if (subsys->set_clock)
+ subsys->set_clock(subsys, clock);
+ else
+ return -EINVAL;
+
+ VML_WRITE32(par, VML_HTOTAL_A, ((htotal - 1) << 16) | (hactive - 1));
+ VML_WRITE32(par, VML_HBLANK_A,
+ ((hblank_end - 1) << 16) | (hblank_start - 1));
+ VML_WRITE32(par, VML_HSYNC_A,
+ ((hsync_end - 1) << 16) | (hsync_start - 1));
+ VML_WRITE32(par, VML_VTOTAL_A, ((vtotal - 1) << 16) | (vactive - 1));
+ VML_WRITE32(par, VML_VBLANK_A,
+ ((vblank_end - 1) << 16) | (vblank_start - 1));
+ VML_WRITE32(par, VML_VSYNC_A,
+ ((vsync_end - 1) << 16) | (vsync_start - 1));
+ VML_WRITE32(par, VML_DSPCSTRIDE, vinfo->stride);
+ VML_WRITE32(par, VML_DSPCSIZE,
+ ((var->yres - 1) << 16) | (var->xres - 1));
+ VML_WRITE32(par, VML_DSPCPOS, 0x00000000);
+ VML_WRITE32(par, VML_DSPARB, VML_FIFO_DEFAULT);
+ VML_WRITE32(par, VML_BCLRPAT_A, 0x00000000);
+ VML_WRITE32(par, VML_CANVSCLR_A, 0x00000000);
+ VML_WRITE32(par, VML_PIPEASRC,
+ ((var->xres - 1) << 16) | (var->yres - 1));
+
+ wmb();
+ VML_WRITE32(par, VML_PIPEACONF, VML_PIPE_ENABLE);
+ wmb();
+ VML_WRITE32(par, VML_DSPCCNTR, dspcntr);
+ wmb();
+ VML_WRITE32(par, VML_DSPCADDR, (u32) vinfo->vram_start +
+ var->yoffset * vinfo->stride +
+ var->xoffset * vinfo->bytes_per_pixel);
+
+ VML_WRITE32(par, VML_RCOMPSTAT, VML_MDVO_PAD_ENABLE);
+
+ while (!(VML_READ32(par, VML_RCOMPSTAT) &
+ (VML_MDVO_VDC_I_RCOMP | VML_MDVO_PAD_ENABLE))) ;
+
+ vinfo->pipe_disabled = 0;
+#ifdef VERMILION_DEBUG
+ vml_dump_regs(vinfo);
+#endif
+
+ return 0;
+}
+
+static int vmlfb_set_par(struct fb_info *info)
+{
+ struct vml_info *vinfo = container_of(info, struct vml_info, info);
+ int ret;
+
+ mutex_lock(&vml_mutex);
+ list_del(&vinfo->head);
+ list_add(&vinfo->head, (subsys) ? &global_has_mode : &global_no_mode);
+ ret = vmlfb_set_par_locked(vinfo);
+
+ mutex_unlock(&vml_mutex);
+ return ret;
+}
+
+static int vmlfb_blank_locked(struct vml_info *vinfo)
+{
+ struct vml_par *par = vinfo->par;
+ u32 cur = VML_READ32(par, VML_PIPEACONF);
+
+ switch (vinfo->cur_blank_mode) {
+ case FB_BLANK_UNBLANK:
+ if (vinfo->pipe_disabled) {
+ vmlfb_set_par_locked(vinfo);
+ }
+ VML_WRITE32(par, VML_PIPEACONF, cur & ~VML_PIPE_FORCE_BORDER);
+ (void)VML_READ32(par, VML_PIPEACONF);
+ break;
+ case FB_BLANK_NORMAL:
+ if (vinfo->pipe_disabled) {
+ vmlfb_set_par_locked(vinfo);
+ }
+ VML_WRITE32(par, VML_PIPEACONF, cur | VML_PIPE_FORCE_BORDER);
+ (void)VML_READ32(par, VML_PIPEACONF);
+ break;
+ case FB_BLANK_VSYNC_SUSPEND:
+ case FB_BLANK_HSYNC_SUSPEND:
+ if (!vinfo->pipe_disabled) {
+ vmlfb_disable_pipe(vinfo);
+ }
+ break;
+ case FB_BLANK_POWERDOWN:
+ if (!vinfo->pipe_disabled) {
+ vmlfb_disable_pipe(vinfo);
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int vmlfb_blank(int blank_mode, struct fb_info *info)
+{
+ struct vml_info *vinfo = container_of(info, struct vml_info, info);
+ int ret;
+
+ mutex_lock(&vml_mutex);
+ vinfo->cur_blank_mode = blank_mode;
+ ret = vmlfb_blank_locked(vinfo);
+ mutex_unlock(&vml_mutex);
+ return ret;
+}
+
+static int vmlfb_pan_display(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ struct vml_info *vinfo = container_of(info, struct vml_info, info);
+ struct vml_par *par = vinfo->par;
+
+ mutex_lock(&vml_mutex);
+ VML_WRITE32(par, VML_DSPCADDR, (u32) vinfo->vram_start +
+ var->yoffset * vinfo->stride +
+ var->xoffset * vinfo->bytes_per_pixel);
+ (void)VML_READ32(par, VML_DSPCADDR);
+ mutex_unlock(&vml_mutex);
+
+ return 0;
+}
+
+static int vmlfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int transp, struct fb_info *info)
+{
+ u32 v;
+
+ if (regno >= 16)
+ return -EINVAL;
+
+ if (info->var.grayscale) {
+ red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
+ }
+
+ if (info->fix.visual != FB_VISUAL_TRUECOLOR)
+ return -EINVAL;
+
+ red = VML_TOHW(red, info->var.red.length);
+ blue = VML_TOHW(blue, info->var.blue.length);
+ green = VML_TOHW(green, info->var.green.length);
+ transp = VML_TOHW(transp, info->var.transp.length);
+
+ v = (red << info->var.red.offset) |
+ (green << info->var.green.offset) |
+ (blue << info->var.blue.offset) |
+ (transp << info->var.transp.offset);
+
+ switch (info->var.bits_per_pixel) {
+ case 16:
+ ((u32 *) info->pseudo_palette)[regno] = v;
+ break;
+ case 24:
+ case 32:
+ ((u32 *) info->pseudo_palette)[regno] = v;
+ break;
+ }
+ return 0;
+}
+
+static int vmlfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
+{
+ struct vml_info *vinfo = container_of(info, struct vml_info, info);
+ unsigned long size = vma->vm_end - vma->vm_start;
+ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+ int ret;
+
+ if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
+ return -EINVAL;
+ if (offset + size > vinfo->vram_contig_size)
+ return -EINVAL;
+ ret = vmlfb_vram_offset(vinfo, offset);
+ if (ret)
+ return -EINVAL;
+ offset += vinfo->vram_start;
+ pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
+ pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT;
+ vma->vm_flags |= VM_RESERVED | VM_IO;
+ if (remap_pfn_range(vma, vma->vm_start, offset >> PAGE_SHIFT,
+ size, vma->vm_page_prot))
+ return -EAGAIN;
+ return 0;
+}
+
+static int vmlfb_sync(struct fb_info *info)
+{
+ return 0;
+}
+
+static int vmlfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
+{
+ return -EINVAL; /* just to force soft_cursor() call */
+}
+
+static struct fb_ops vmlfb_ops = {
+ .owner = THIS_MODULE,
+ .fb_open = vmlfb_open,
+ .fb_release = vmlfb_release,
+ .fb_check_var = vmlfb_check_var,
+ .fb_set_par = vmlfb_set_par,
+ .fb_blank = vmlfb_blank,
+ .fb_pan_display = vmlfb_pan_display,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+ .fb_cursor = vmlfb_cursor,
+ .fb_sync = vmlfb_sync,
+ .fb_mmap = vmlfb_mmap,
+ .fb_setcolreg = vmlfb_setcolreg
+};
+
+static struct pci_device_id vml_ids[] = {
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, VML_DEVICE_VDC)},
+ {0}
+};
+
+static struct pci_driver vmlfb_pci_driver = {
+ .name = "vmlfb",
+ .id_table = vml_ids,
+ .probe = vml_pci_probe,
+ .remove = __devexit_p(vml_pci_remove)
+};
+
+static void __exit vmlfb_cleanup(void)
+{
+ pci_unregister_driver(&vmlfb_pci_driver);
+}
+
+static int __init vmlfb_init(void)
+{
+
+#ifndef MODULE
+ char *option = NULL;
+
+ if (fb_get_options(MODULE_NAME, &option))
+ return -ENODEV;
+#endif
+
+ printk(KERN_DEBUG MODULE_NAME ": initializing\n");
+ mutex_init(&vml_mutex);
+ INIT_LIST_HEAD(&global_no_mode);
+ INIT_LIST_HEAD(&global_has_mode);
+
+ return pci_register_driver(&vmlfb_pci_driver);
+}
+
+int vmlfb_register_subsys(struct vml_sys *sys)
+{
+ struct vml_info *entry;
+ struct list_head *list;
+ u32 save_activate;
+
+ mutex_lock(&vml_mutex);
+ if (subsys != NULL) {
+ subsys->restore(subsys);
+ }
+ subsys = sys;
+ subsys->save(subsys);
+
+ /*
+ * We need to restart list traversal for each item, since we
+ * release the list mutex in the loop.
+ */
+
+ list = global_no_mode.next;
+ while (list != &global_no_mode) {
+ list_del_init(list);
+ entry = list_entry(list, struct vml_info, head);
+
+ /*
+ * First, try the current mode which might not be
+ * completely validated with respect to the pixel clock.
+ */
+
+ if (!vmlfb_check_var_locked(&entry->info.var, entry)) {
+ vmlfb_set_par_locked(entry);
+ list_add_tail(list, &global_has_mode);
+ } else {
+
+ /*
+ * Didn't work. Try to find another mode,
+ * that matches this subsys.
+ */
+
+ mutex_unlock(&vml_mutex);
+ save_activate = entry->info.var.activate;
+ entry->info.var.bits_per_pixel = 16;
+ vmlfb_set_pref_pixel_format(&entry->info.var);
+ if (fb_find_mode(&entry->info.var,
+ &entry->info,
+ vml_default_mode, NULL, 0, NULL, 16)) {
+ entry->info.var.activate |=
+ FB_ACTIVATE_FORCE | FB_ACTIVATE_NOW;
+ fb_set_var(&entry->info, &entry->info.var);
+ } else {
+ printk(KERN_ERR MODULE_NAME
+ ": Sorry. no mode found for this subsys.\n");
+ }
+ entry->info.var.activate = save_activate;
+ mutex_lock(&vml_mutex);
+ }
+ vmlfb_blank_locked(entry);
+ list = global_no_mode.next;
+ }
+ mutex_unlock(&vml_mutex);
+
+ printk(KERN_DEBUG MODULE_NAME ": Registered %s subsystem.\n",
+ subsys->name ? subsys->name : "unknown");
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(vmlfb_register_subsys);
+
+void vmlfb_unregister_subsys(struct vml_sys *sys)
+{
+ struct vml_info *entry, *next;
+
+ mutex_lock(&vml_mutex);
+ if (subsys != sys) {
+ mutex_unlock(&vml_mutex);
+ return;
+ }
+ subsys->restore(subsys);
+ subsys = NULL;
+ list_for_each_entry_safe(entry, next, &global_has_mode, head) {
+ printk(KERN_DEBUG MODULE_NAME ": subsys disable pipe\n");
+ vmlfb_disable_pipe(entry);
+ list_del(&entry->head);
+ list_add_tail(&entry->head, &global_no_mode);
+ }
+ mutex_unlock(&vml_mutex);
+}
+
+EXPORT_SYMBOL_GPL(vmlfb_unregister_subsys);
+
+module_init(vmlfb_init);
+module_exit(vmlfb_cleanup);
+
+MODULE_AUTHOR("Tungsten Graphics");
+MODULE_DESCRIPTION("Initialization of the Vermilion display devices");
+MODULE_VERSION("1.0.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/vermilion/vermilion.h b/drivers/video/vermilion/vermilion.h
new file mode 100644
index 0000000..1fc6695
--- /dev/null
+++ b/drivers/video/vermilion/vermilion.h
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) Intel Corp. 2007.
+ * All Rights Reserved.
+ *
+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ * develop this driver.
+ *
+ * This file is part of the Vermilion Range fb driver.
+ * The Vermilion Range fb driver is free software;
+ * you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The Vermilion Range fb driver is distributed
+ * in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this driver; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors:
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ */
+
+#ifndef _VERMILION_H_
+#define _VERMILION_H_
+
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/pci.h>
+#include <asm/atomic.h>
+#include <linux/mutex.h>
+
+#define VML_DEVICE_GPU 0x5002
+#define VML_DEVICE_VDC 0x5009
+
+#define VML_VRAM_AREAS 3
+#define VML_MAX_XRES 1024
+#define VML_MAX_YRES 768
+#define VML_MAX_XRES_VIRTUAL 1040
+
+/*
+ * Display controller registers:
+ */
+
+/* Display controller 10-bit color representation */
+
+#define VML_R_MASK 0x3FF00000
+#define VML_R_SHIFT 20
+#define VML_G_MASK 0x000FFC00
+#define VML_G_SHIFT 10
+#define VML_B_MASK 0x000003FF
+#define VML_B_SHIFT 0
+
+/* Graphics plane control */
+#define VML_DSPCCNTR 0x00072180
+#define VML_GFX_ENABLE 0x80000000
+#define VML_GFX_GAMMABYPASS 0x40000000
+#define VML_GFX_ARGB1555 0x0C000000
+#define VML_GFX_RGB0888 0x18000000
+#define VML_GFX_ARGB8888 0x1C000000
+#define VML_GFX_ALPHACONST 0x02000000
+#define VML_GFX_ALPHAMULT 0x01000000
+#define VML_GFX_CONST_ALPHA 0x000000FF
+
+/* Graphics plane start address. Pixel aligned. */
+#define VML_DSPCADDR 0x00072184
+
+/* Graphics plane stride register. */
+#define VML_DSPCSTRIDE 0x00072188
+
+/* Graphics plane position register. */
+#define VML_DSPCPOS 0x0007218C
+#define VML_POS_YMASK 0x0FFF0000
+#define VML_POS_YSHIFT 16
+#define VML_POS_XMASK 0x00000FFF
+#define VML_POS_XSHIFT 0
+
+/* Graphics plane height and width */
+#define VML_DSPCSIZE 0x00072190
+#define VML_SIZE_HMASK 0x0FFF0000
+#define VML_SIZE_HSHIFT 16
+#define VML_SISE_WMASK 0x00000FFF
+#define VML_SIZE_WSHIFT 0
+
+/* Graphics plane gamma correction lookup table registers (129 * 32 bits) */
+#define VML_DSPCGAMLUT 0x00072200
+
+/* Pixel video output configuration register */
+#define VML_PVOCONFIG 0x00061140
+#define VML_CONFIG_BASE 0x80000000
+#define VML_CONFIG_PIXEL_SWAP 0x04000000
+#define VML_CONFIG_DE_INV 0x01000000
+#define VML_CONFIG_HREF_INV 0x00400000
+#define VML_CONFIG_VREF_INV 0x00100000
+#define VML_CONFIG_CLK_INV 0x00040000
+#define VML_CONFIG_CLK_DIV2 0x00010000
+#define VML_CONFIG_ESTRB_INV 0x00008000
+
+/* Pipe A Horizontal total register */
+#define VML_HTOTAL_A 0x00060000
+#define VML_HTOTAL_MASK 0x1FFF0000
+#define VML_HTOTAL_SHIFT 16
+#define VML_HTOTAL_VAL 8192
+#define VML_HACTIVE_MASK 0x000007FF
+#define VML_HACTIVE_SHIFT 0
+#define VML_HACTIVE_VAL 4096
+
+/* Pipe A Horizontal Blank register */
+#define VML_HBLANK_A 0x00060004
+#define VML_HBLANK_END_MASK 0x1FFF0000
+#define VML_HBLANK_END_SHIFT 16
+#define VML_HBLANK_END_VAL 8192
+#define VML_HBLANK_START_MASK 0x00001FFF
+#define VML_HBLANK_START_SHIFT 0
+#define VML_HBLANK_START_VAL 8192
+
+/* Pipe A Horizontal Sync register */
+#define VML_HSYNC_A 0x00060008
+#define VML_HSYNC_END_MASK 0x1FFF0000
+#define VML_HSYNC_END_SHIFT 16
+#define VML_HSYNC_END_VAL 8192
+#define VML_HSYNC_START_MASK 0x00001FFF
+#define VML_HSYNC_START_SHIFT 0
+#define VML_HSYNC_START_VAL 8192
+
+/* Pipe A Vertical total register */
+#define VML_VTOTAL_A 0x0006000C
+#define VML_VTOTAL_MASK 0x1FFF0000
+#define VML_VTOTAL_SHIFT 16
+#define VML_VTOTAL_VAL 8192
+#define VML_VACTIVE_MASK 0x000007FF
+#define VML_VACTIVE_SHIFT 0
+#define VML_VACTIVE_VAL 4096
+
+/* Pipe A Vertical Blank register */
+#define VML_VBLANK_A 0x00060010
+#define VML_VBLANK_END_MASK 0x1FFF0000
+#define VML_VBLANK_END_SHIFT 16
+#define VML_VBLANK_END_VAL 8192
+#define VML_VBLANK_START_MASK 0x00001FFF
+#define VML_VBLANK_START_SHIFT 0
+#define VML_VBLANK_START_VAL 8192
+
+/* Pipe A Vertical Sync register */
+#define VML_VSYNC_A 0x00060014
+#define VML_VSYNC_END_MASK 0x1FFF0000
+#define VML_VSYNC_END_SHIFT 16
+#define VML_VSYNC_END_VAL 8192
+#define VML_VSYNC_START_MASK 0x00001FFF
+#define VML_VSYNC_START_SHIFT 0
+#define VML_VSYNC_START_VAL 8192
+
+/* Pipe A Source Image size (minus one - equal to active size)
+ * Programmable while pipe is enabled.
+ */
+#define VML_PIPEASRC 0x0006001C
+#define VML_PIPEASRC_HMASK 0x0FFF0000
+#define VML_PIPEASRC_HSHIFT 16
+#define VML_PIPEASRC_VMASK 0x00000FFF
+#define VML_PIPEASRC_VSHIFT 0
+
+/* Pipe A Border Color Pattern register (10 bit color) */
+#define VML_BCLRPAT_A 0x00060020
+
+/* Pipe A Canvas Color register (10 bit color) */
+#define VML_CANVSCLR_A 0x00060024
+
+/* Pipe A Configuration register */
+#define VML_PIPEACONF 0x00070008
+#define VML_PIPE_BASE 0x00000000
+#define VML_PIPE_ENABLE 0x80000000
+#define VML_PIPE_FORCE_BORDER 0x02000000
+#define VML_PIPE_PLANES_OFF 0x00080000
+#define VML_PIPE_ARGB_OUTPUT_MODE 0x00040000
+
+/* Pipe A FIFO setting */
+#define VML_DSPARB 0x00070030
+#define VML_FIFO_DEFAULT 0x00001D9C
+
+/* MDVO rcomp status & pads control register */
+#define VML_RCOMPSTAT 0x00070048
+#define VML_MDVO_VDC_I_RCOMP 0x80000000
+#define VML_MDVO_POWERSAVE_OFF 0x00000008
+#define VML_MDVO_PAD_ENABLE 0x00000004
+#define VML_MDVO_PULLDOWN_ENABLE 0x00000001
+
+struct vml_par {
+ struct pci_dev *vdc;
+ u64 vdc_mem_base;
+ u64 vdc_mem_size;
+ char __iomem *vdc_mem;
+
+ struct pci_dev *gpu;
+ u64 gpu_mem_base;
+ u64 gpu_mem_size;
+ char __iomem *gpu_mem;
+
+ atomic_t refcount;
+};
+
+struct vram_area {
+ unsigned long logical;
+ unsigned long phys;
+ unsigned long size;
+ unsigned order;
+};
+
+struct vml_info {
+ struct fb_info info;
+ struct vml_par *par;
+ struct list_head head;
+ struct vram_area vram[VML_VRAM_AREAS];
+ u64 vram_start;
+ u64 vram_contig_size;
+ u32 num_areas;
+ void __iomem *vram_logical;
+ u32 pseudo_palette[16];
+ u32 stride;
+ u32 bytes_per_pixel;
+ atomic_t vmas;
+ int cur_blank_mode;
+ int pipe_disabled;
+};
+
+/*
+ * Subsystem
+ */
+
+struct vml_sys {
+ char *name;
+
+ /*
+ * Save / Restore;
+ */
+
+ int (*save) (struct vml_sys * sys);
+ int (*restore) (struct vml_sys * sys);
+
+ /*
+ * PLL programming;
+ */
+
+ int (*set_clock) (struct vml_sys * sys, int clock);
+ int (*nearest_clock) (const struct vml_sys * sys, int clock);
+};
+
+extern int vmlfb_register_subsys(struct vml_sys *sys);
+extern void vmlfb_unregister_subsys(struct vml_sys *sys);
+
+#define VML_READ32(_par, _offset) \
+ (ioread32((_par)->vdc_mem + (_offset)))
+#define VML_WRITE32(_par, _offset, _value) \
+ iowrite32(_value, (_par)->vdc_mem + (_offset))
+
+#endif
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index a9b99b0..64ee78c 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -84,13 +84,15 @@
struct vm_area_struct *vma);
static struct fb_ops vfb_ops = {
+ .fb_read = fb_sys_read,
+ .fb_write = fb_sys_write,
.fb_check_var = vfb_check_var,
.fb_set_par = vfb_set_par,
.fb_setcolreg = vfb_setcolreg,
.fb_pan_display = vfb_pan_display,
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = cfb_copyarea,
- .fb_imageblit = cfb_imageblit,
+ .fb_fillrect = sys_fillrect,
+ .fb_copyarea = sys_copyarea,
+ .fb_imageblit = sys_imageblit,
.fb_mmap = vfb_mmap,
};
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
index ec4c7dc..2a14d28 100644
--- a/drivers/video/vga16fb.c
+++ b/drivers/video/vga16fb.c
@@ -1378,6 +1378,8 @@
info->fbops = &vga16fb_ops;
info->var = vga16fb_defined;
info->fix = vga16fb_fix;
+ /* supports rectangles with widths of multiples of 8 */
+ info->pixmap.blit_x = 1 << 7 | 1 << 15 | 1 << 23 | 1 << 31;
info->flags = FBINFO_FLAG_DEFAULT |
FBINFO_HWACCEL_YPAN;
diff --git a/drivers/video/vgastate.c b/drivers/video/vgastate.c
index d94efaf..b91c466 100644
--- a/drivers/video/vgastate.c
+++ b/drivers/video/vgastate.c
@@ -50,23 +50,28 @@
struct regstate *saved = (struct regstate *) state->vidstate;
int i;
u8 misc, attr10, gr4, gr5, gr6, seq1, seq2, seq4;
+ unsigned short iobase;
/* if in graphics mode, no need to save */
+ misc = vga_r(state->vgabase, VGA_MIS_R);
+ iobase = (misc & 1) ? 0x3d0 : 0x3b0;
+
+ vga_r(state->vgabase, iobase + 0xa);
+ vga_w(state->vgabase, VGA_ATT_W, 0x00);
attr10 = vga_rattr(state->vgabase, 0x10);
+ vga_r(state->vgabase, iobase + 0xa);
+ vga_w(state->vgabase, VGA_ATT_W, 0x20);
+
if (attr10 & 1)
return;
-
+
/* save regs */
- misc = vga_r(state->vgabase, VGA_MIS_R);
gr4 = vga_rgfx(state->vgabase, VGA_GFX_PLANE_READ);
gr5 = vga_rgfx(state->vgabase, VGA_GFX_MODE);
gr6 = vga_rgfx(state->vgabase, VGA_GFX_MISC);
seq2 = vga_rseq(state->vgabase, VGA_SEQ_PLANE_WRITE);
seq4 = vga_rseq(state->vgabase, VGA_SEQ_MEMORY_MODE);
- /* force graphics mode */
- vga_w(state->vgabase, VGA_MIS_W, misc | 1);
-
/* blank screen */
seq1 = vga_rseq(state->vgabase, VGA_SEQ_CLOCK_MODE);
vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1);
@@ -115,15 +120,12 @@
}
/* restore regs */
- vga_wattr(state->vgabase, 0x10, attr10);
-
vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, seq2);
vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, seq4);
vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, gr4);
vga_wgfx(state->vgabase, VGA_GFX_MODE, gr5);
vga_wgfx(state->vgabase, VGA_GFX_MISC, gr6);
- vga_w(state->vgabase, VGA_MIS_W, misc);
/* unblank screen */
vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1);
@@ -137,11 +139,10 @@
{
struct regstate *saved = (struct regstate *) state->vidstate;
int i;
- u8 misc, gr1, gr3, gr4, gr5, gr6, gr8;
+ u8 gr1, gr3, gr4, gr5, gr6, gr8;
u8 seq1, seq2, seq4;
/* save regs */
- misc = vga_r(state->vgabase, VGA_MIS_R);
gr1 = vga_rgfx(state->vgabase, VGA_GFX_SR_ENABLE);
gr3 = vga_rgfx(state->vgabase, VGA_GFX_DATA_ROTATE);
gr4 = vga_rgfx(state->vgabase, VGA_GFX_PLANE_READ);
@@ -151,9 +152,6 @@
seq2 = vga_rseq(state->vgabase, VGA_SEQ_PLANE_WRITE);
seq4 = vga_rseq(state->vgabase, VGA_SEQ_MEMORY_MODE);
- /* force graphics mode */
- vga_w(state->vgabase, VGA_MIS_W, misc | 1);
-
/* blank screen */
seq1 = vga_rseq(state->vgabase, VGA_SEQ_CLOCK_MODE);
vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1);
@@ -213,8 +211,6 @@
vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x3);
/* restore regs */
- vga_w(state->vgabase, VGA_MIS_W, misc);
-
vga_wgfx(state->vgabase, VGA_GFX_SR_ENABLE, gr1);
vga_wgfx(state->vgabase, VGA_GFX_DATA_ROTATE, gr3);
vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, gr4);
diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c
new file mode 100644
index 0000000..1d29a89
--- /dev/null
+++ b/drivers/video/xilinxfb.c
@@ -0,0 +1,381 @@
+/*
+ * xilinxfb.c
+ *
+ * Xilinx TFT LCD frame buffer driver
+ *
+ * Author: MontaVista Software, Inc.
+ * source@mvista.com
+ *
+ * 2002-2007 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is licensed
+ * "as is" without any warranty of any kind, whether express or implied.
+ */
+
+/*
+ * This driver was based on au1100fb.c by MontaVista rewritten for 2.6
+ * by Embedded Alley Solutions <source@embeddedalley.com>, which in turn
+ * was based on skeletonfb.c, Skeleton for a frame buffer device by
+ * Geert Uytterhoeven.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+
+#include <asm/io.h>
+#include <syslib/virtex_devices.h>
+
+#define DRIVER_NAME "xilinxfb"
+#define DRIVER_DESCRIPTION "Xilinx TFT LCD frame buffer driver"
+
+/*
+ * Xilinx calls it "PLB TFT LCD Controller" though it can also be used for
+ * the VGA port on the Xilinx ML40x board. This is a hardware display controller
+ * for a 640x480 resolution TFT or VGA screen.
+ *
+ * The interface to the framebuffer is nice and simple. There are two
+ * control registers. The first tells the LCD interface where in memory
+ * the frame buffer is (only the 11 most significant bits are used, so
+ * don't start thinking about scrolling). The second allows the LCD to
+ * be turned on or off as well as rotated 180 degrees.
+ */
+#define NUM_REGS 2
+#define REG_FB_ADDR 0
+#define REG_CTRL 1
+#define REG_CTRL_ENABLE 0x0001
+#define REG_CTRL_ROTATE 0x0002
+
+/*
+ * The hardware only handles a single mode: 640x480 24 bit true
+ * color. Each pixel gets a word (32 bits) of memory. Within each word,
+ * the 8 most significant bits are ignored, the next 8 bits are the red
+ * level, the next 8 bits are the green level and the 8 least
+ * significant bits are the blue level. Each row of the LCD uses 1024
+ * words, but only the first 640 pixels are displayed with the other 384
+ * words being ignored. There are 480 rows.
+ */
+#define BYTES_PER_PIXEL 4
+#define BITS_PER_PIXEL (BYTES_PER_PIXEL * 8)
+#define XRES 640
+#define YRES 480
+#define XRES_VIRTUAL 1024
+#define YRES_VIRTUAL YRES
+#define LINE_LENGTH (XRES_VIRTUAL * BYTES_PER_PIXEL)
+#define FB_SIZE (YRES_VIRTUAL * LINE_LENGTH)
+
+#define RED_SHIFT 16
+#define GREEN_SHIFT 8
+#define BLUE_SHIFT 0
+
+#define PALETTE_ENTRIES_NO 16 /* passed to fb_alloc_cmap() */
+
+/*
+ * Here are the default fb_fix_screeninfo and fb_var_screeninfo structures
+ */
+static struct fb_fix_screeninfo xilinx_fb_fix __initdata = {
+ .id = "Xilinx",
+ .type = FB_TYPE_PACKED_PIXELS,
+ .visual = FB_VISUAL_TRUECOLOR,
+ .smem_len = FB_SIZE,
+ .line_length = LINE_LENGTH,
+ .accel = FB_ACCEL_NONE
+};
+
+static struct fb_var_screeninfo xilinx_fb_var __initdata = {
+ .xres = XRES,
+ .yres = YRES,
+ .xres_virtual = XRES_VIRTUAL,
+ .yres_virtual = YRES_VIRTUAL,
+
+ .bits_per_pixel = BITS_PER_PIXEL,
+
+ .red = { RED_SHIFT, 8, 0 },
+ .green = { GREEN_SHIFT, 8, 0 },
+ .blue = { BLUE_SHIFT, 8, 0 },
+ .transp = { 0, 0, 0 },
+
+ .activate = FB_ACTIVATE_NOW
+};
+
+struct xilinxfb_drvdata {
+
+ struct fb_info info; /* FB driver info record */
+
+ u32 regs_phys; /* phys. address of the control registers */
+ u32 __iomem *regs; /* virt. address of the control registers */
+
+ unsigned char __iomem *fb_virt; /* virt. address of the frame buffer */
+ dma_addr_t fb_phys; /* phys. address of the frame buffer */
+
+ u32 reg_ctrl_default;
+
+ u32 pseudo_palette[PALETTE_ENTRIES_NO];
+ /* Fake palette of 16 colors */
+};
+
+#define to_xilinxfb_drvdata(_info) \
+ container_of(_info, struct xilinxfb_drvdata, info)
+
+/*
+ * The LCD controller has DCR interface to its registers, but all
+ * the boards and configurations the driver has been tested with
+ * use opb2dcr bridge. So the registers are seen as memory mapped.
+ * This macro is to make it simple to add the direct DCR access
+ * when it's needed.
+ */
+#define xilinx_fb_out_be32(driverdata, offset, val) \
+ out_be32(driverdata->regs + offset, val)
+
+static int
+xilinx_fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
+ unsigned transp, struct fb_info *fbi)
+{
+ u32 *palette = fbi->pseudo_palette;
+
+ if (regno >= PALETTE_ENTRIES_NO)
+ return -EINVAL;
+
+ if (fbi->var.grayscale) {
+ /* Convert color to grayscale.
+ * grayscale = 0.30*R + 0.59*G + 0.11*B */
+ red = green = blue =
+ (red * 77 + green * 151 + blue * 28 + 127) >> 8;
+ }
+
+ /* fbi->fix.visual is always FB_VISUAL_TRUECOLOR */
+
+ /* We only handle 8 bits of each color. */
+ red >>= 8;
+ green >>= 8;
+ blue >>= 8;
+ palette[regno] = (red << RED_SHIFT) | (green << GREEN_SHIFT) |
+ (blue << BLUE_SHIFT);
+
+ return 0;
+}
+
+static int
+xilinx_fb_blank(int blank_mode, struct fb_info *fbi)
+{
+ struct xilinxfb_drvdata *drvdata = to_xilinxfb_drvdata(fbi);
+
+ switch (blank_mode) {
+ case FB_BLANK_UNBLANK:
+ /* turn on panel */
+ xilinx_fb_out_be32(drvdata, REG_CTRL, drvdata->reg_ctrl_default);
+ break;
+
+ case FB_BLANK_NORMAL:
+ case FB_BLANK_VSYNC_SUSPEND:
+ case FB_BLANK_HSYNC_SUSPEND:
+ case FB_BLANK_POWERDOWN:
+ /* turn off panel */
+ xilinx_fb_out_be32(drvdata, REG_CTRL, 0);
+ default:
+ break;
+
+ }
+ return 0; /* success */
+}
+
+static struct fb_ops xilinxfb_ops =
+{
+ .owner = THIS_MODULE,
+ .fb_setcolreg = xilinx_fb_setcolreg,
+ .fb_blank = xilinx_fb_blank,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+};
+
+/* === The device driver === */
+
+static int
+xilinxfb_drv_probe(struct device *dev)
+{
+ struct platform_device *pdev;
+ struct xilinxfb_platform_data *pdata;
+ struct xilinxfb_drvdata *drvdata;
+ struct resource *regs_res;
+ int retval;
+
+ if (!dev)
+ return -EINVAL;
+
+ pdev = to_platform_device(dev);
+ pdata = pdev->dev.platform_data;
+
+ if (pdata == NULL) {
+ printk(KERN_ERR "Couldn't find platform data.\n");
+ return -EFAULT;
+ }
+
+ drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
+ if (!drvdata) {
+ printk(KERN_ERR "Couldn't allocate device private record\n");
+ return -ENOMEM;
+ }
+ dev_set_drvdata(dev, drvdata);
+
+ /* Map the control registers in */
+ regs_res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ if (!regs_res || (regs_res->end - regs_res->start + 1 < 8)) {
+ printk(KERN_ERR "Couldn't get registers resource\n");
+ retval = -EFAULT;
+ goto failed1;
+ }
+
+ if (!request_mem_region(regs_res->start, 8, DRIVER_NAME)) {
+ printk(KERN_ERR
+ "Couldn't lock memory region at 0x%08X\n",
+ regs_res->start);
+ retval = -EBUSY;
+ goto failed1;
+ }
+ drvdata->regs = (u32 __iomem*) ioremap(regs_res->start, 8);
+ drvdata->regs_phys = regs_res->start;
+
+ /* Allocate the framebuffer memory */
+ drvdata->fb_virt = dma_alloc_coherent(dev, PAGE_ALIGN(FB_SIZE),
+ &drvdata->fb_phys, GFP_KERNEL);
+ if (!drvdata->fb_virt) {
+ printk(KERN_ERR "Could not allocate frame buffer memory\n");
+ retval = -ENOMEM;
+ goto failed2;
+ }
+
+ /* Clear (turn to black) the framebuffer */
+ memset_io((void *) drvdata->fb_virt, 0, FB_SIZE);
+
+ /* Tell the hardware where the frame buffer is */
+ xilinx_fb_out_be32(drvdata, REG_FB_ADDR, drvdata->fb_phys);
+
+ /* Turn on the display */
+ if (pdata->rotate_screen) {
+ drvdata->reg_ctrl_default = REG_CTRL_ENABLE | REG_CTRL_ROTATE;
+ } else {
+ drvdata->reg_ctrl_default = REG_CTRL_ENABLE;
+ }
+ xilinx_fb_out_be32(drvdata, REG_CTRL, drvdata->reg_ctrl_default);
+
+ /* Fill struct fb_info */
+ drvdata->info.device = dev;
+ drvdata->info.screen_base = drvdata->fb_virt;
+ drvdata->info.fbops = &xilinxfb_ops;
+ drvdata->info.fix = xilinx_fb_fix;
+ drvdata->info.fix.smem_start = drvdata->fb_phys;
+ drvdata->info.pseudo_palette = drvdata->pseudo_palette;
+
+ if (fb_alloc_cmap(&drvdata->info.cmap, PALETTE_ENTRIES_NO, 0) < 0) {
+ printk(KERN_ERR "Fail to allocate colormap (%d entries)\n",
+ PALETTE_ENTRIES_NO);
+ retval = -EFAULT;
+ goto failed3;
+ }
+
+ drvdata->info.flags = FBINFO_DEFAULT;
+ xilinx_fb_var.height = pdata->screen_height_mm;
+ xilinx_fb_var.width = pdata->screen_width_mm;
+ drvdata->info.var = xilinx_fb_var;
+
+ /* Register new frame buffer */
+ if (register_framebuffer(&drvdata->info) < 0) {
+ printk(KERN_ERR "Could not register frame buffer\n");
+ retval = -EINVAL;
+ goto failed4;
+ }
+
+ return 0; /* success */
+
+failed4:
+ fb_dealloc_cmap(&drvdata->info.cmap);
+
+failed3:
+ dma_free_coherent(dev, PAGE_ALIGN(FB_SIZE), drvdata->fb_virt,
+ drvdata->fb_phys);
+
+ /* Turn off the display */
+ xilinx_fb_out_be32(drvdata, REG_CTRL, 0);
+ iounmap(drvdata->regs);
+
+failed2:
+ release_mem_region(regs_res->start, 8);
+
+failed1:
+ kfree(drvdata);
+ dev_set_drvdata(dev, NULL);
+
+ return retval;
+}
+
+static int
+xilinxfb_drv_remove(struct device *dev)
+{
+ struct xilinxfb_drvdata *drvdata;
+
+ if (!dev)
+ return -ENODEV;
+
+ drvdata = (struct xilinxfb_drvdata *) dev_get_drvdata(dev);
+
+#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
+ xilinx_fb_blank(VESA_POWERDOWN, &drvdata->info);
+#endif
+
+ unregister_framebuffer(&drvdata->info);
+
+ fb_dealloc_cmap(&drvdata->info.cmap);
+
+ dma_free_coherent(dev, PAGE_ALIGN(FB_SIZE), drvdata->fb_virt,
+ drvdata->fb_phys);
+
+ /* Turn off the display */
+ xilinx_fb_out_be32(drvdata, REG_CTRL, 0);
+ iounmap(drvdata->regs);
+
+ release_mem_region(drvdata->regs_phys, 8);
+
+ kfree(drvdata);
+ dev_set_drvdata(dev, NULL);
+
+ return 0;
+}
+
+
+static struct device_driver xilinxfb_driver = {
+ .name = DRIVER_NAME,
+ .bus = &platform_bus_type,
+
+ .probe = xilinxfb_drv_probe,
+ .remove = xilinxfb_drv_remove
+};
+
+static int __init
+xilinxfb_init(void)
+{
+ /*
+ * No kernel boot options used,
+ * so we just need to register the driver
+ */
+ return driver_register(&xilinxfb_driver);
+}
+
+static void __exit
+xilinxfb_cleanup(void)
+{
+ driver_unregister(&xilinxfb_driver);
+}
+
+module_init(xilinxfb_init);
+module_exit(xilinxfb_cleanup);
+
+MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>");
+MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
+MODULE_LICENSE("GPL");
diff --git a/drivers/w1/masters/Kconfig b/drivers/w1/masters/Kconfig
index 2fb4255..8f77933 100644
--- a/drivers/w1/masters/Kconfig
+++ b/drivers/w1/masters/Kconfig
@@ -35,5 +35,13 @@
This driver can also be built as a module. If so, the module
will be called ds2482.
+config W1_MASTER_DS1WM
+ tristate "Maxim DS1WM 1-wire busmaster"
+ depends on W1 && ARM
+ help
+ Say Y here to enable the DS1WM 1-wire driver, such as that
+ in HP iPAQ devices like h5xxx, h2200, and ASIC3-based like
+ hx4700.
+
endmenu
diff --git a/drivers/w1/masters/Makefile b/drivers/w1/masters/Makefile
index 4cee256..11551b3 100644
--- a/drivers/w1/masters/Makefile
+++ b/drivers/w1/masters/Makefile
@@ -5,4 +5,4 @@
obj-$(CONFIG_W1_MASTER_MATROX) += matrox_w1.o
obj-$(CONFIG_W1_MASTER_DS2490) += ds2490.o
obj-$(CONFIG_W1_MASTER_DS2482) += ds2482.o
-
+obj-$(CONFIG_W1_MASTER_DS1WM) += ds1wm.o
diff --git a/drivers/w1/masters/ds1wm.c b/drivers/w1/masters/ds1wm.c
new file mode 100644
index 0000000..763bc73
--- /dev/null
+++ b/drivers/w1/masters/ds1wm.c
@@ -0,0 +1,468 @@
+/*
+ * 1-wire busmaster driver for DS1WM and ASICs with embedded DS1WMs
+ * such as HP iPAQs (including h5xxx, h2200, and devices with ASIC3
+ * like hx4700).
+ *
+ * Copyright (c) 2004-2005, Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>
+ * Copyright (c) 2004-2007, Matt Reimer <mreimer@vpop.net>
+ *
+ * Use consistent with the GNU GPL is permitted,
+ * provided that this copyright notice is
+ * preserved in its entirety in all copies and derived works.
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/pm.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/ds1wm.h>
+
+#include <asm/io.h>
+
+#include "../w1.h"
+#include "../w1_int.h"
+
+
+#define DS1WM_CMD 0x00 /* R/W 4 bits command */
+#define DS1WM_DATA 0x01 /* R/W 8 bits, transmit/receive buffer */
+#define DS1WM_INT 0x02 /* R/W interrupt status */
+#define DS1WM_INT_EN 0x03 /* R/W interrupt enable */
+#define DS1WM_CLKDIV 0x04 /* R/W 5 bits of divisor and pre-scale */
+
+#define DS1WM_CMD_1W_RESET (1 << 0) /* force reset on 1-wire bus */
+#define DS1WM_CMD_SRA (1 << 1) /* enable Search ROM accelerator mode */
+#define DS1WM_CMD_DQ_OUTPUT (1 << 2) /* write only - forces bus low */
+#define DS1WM_CMD_DQ_INPUT (1 << 3) /* read only - reflects state of bus */
+#define DS1WM_CMD_RST (1 << 5) /* software reset */
+#define DS1WM_CMD_OD (1 << 7) /* overdrive */
+
+#define DS1WM_INT_PD (1 << 0) /* presence detect */
+#define DS1WM_INT_PDR (1 << 1) /* presence detect result */
+#define DS1WM_INT_TBE (1 << 2) /* tx buffer empty */
+#define DS1WM_INT_TSRE (1 << 3) /* tx shift register empty */
+#define DS1WM_INT_RBF (1 << 4) /* rx buffer full */
+#define DS1WM_INT_RSRF (1 << 5) /* rx shift register full */
+
+#define DS1WM_INTEN_EPD (1 << 0) /* enable presence detect int */
+#define DS1WM_INTEN_IAS (1 << 1) /* INTR active state */
+#define DS1WM_INTEN_ETBE (1 << 2) /* enable tx buffer empty int */
+#define DS1WM_INTEN_ETMT (1 << 3) /* enable tx shift register empty int */
+#define DS1WM_INTEN_ERBF (1 << 4) /* enable rx buffer full int */
+#define DS1WM_INTEN_ERSRF (1 << 5) /* enable rx shift register full int */
+#define DS1WM_INTEN_DQO (1 << 6) /* enable direct bus driving ops */
+
+
+#define DS1WM_TIMEOUT (HZ * 5)
+
+static struct {
+ unsigned long freq;
+ unsigned long divisor;
+} freq[] = {
+ { 4000000, 0x8 },
+ { 5000000, 0x2 },
+ { 6000000, 0x5 },
+ { 7000000, 0x3 },
+ { 8000000, 0xc },
+ { 10000000, 0x6 },
+ { 12000000, 0x9 },
+ { 14000000, 0x7 },
+ { 16000000, 0x10 },
+ { 20000000, 0xa },
+ { 24000000, 0xd },
+ { 28000000, 0xb },
+ { 32000000, 0x14 },
+ { 40000000, 0xe },
+ { 48000000, 0x11 },
+ { 56000000, 0xf },
+ { 64000000, 0x18 },
+ { 80000000, 0x12 },
+ { 96000000, 0x15 },
+ { 112000000, 0x13 },
+ { 128000000, 0x1c },
+};
+
+struct ds1wm_data {
+ void *map;
+ int bus_shift; /* # of shifts to calc register offsets */
+ struct platform_device *pdev;
+ struct ds1wm_platform_data *pdata;
+ int irq;
+ int active_high;
+ struct clk *clk;
+ int slave_present;
+ void *reset_complete;
+ void *read_complete;
+ void *write_complete;
+ u8 read_byte; /* last byte received */
+};
+
+static inline void ds1wm_write_register(struct ds1wm_data *ds1wm_data, u32 reg,
+ u8 val)
+{
+ __raw_writeb(val, ds1wm_data->map + (reg << ds1wm_data->bus_shift));
+}
+
+static inline u8 ds1wm_read_register(struct ds1wm_data *ds1wm_data, u32 reg)
+{
+ return __raw_readb(ds1wm_data->map + (reg << ds1wm_data->bus_shift));
+}
+
+
+static irqreturn_t ds1wm_isr(int isr, void *data)
+{
+ struct ds1wm_data *ds1wm_data = data;
+ u8 intr = ds1wm_read_register(ds1wm_data, DS1WM_INT);
+
+ ds1wm_data->slave_present = (intr & DS1WM_INT_PDR) ? 0 : 1;
+
+ if ((intr & DS1WM_INT_PD) && ds1wm_data->reset_complete)
+ complete(ds1wm_data->reset_complete);
+
+ if ((intr & DS1WM_INT_TSRE) && ds1wm_data->write_complete)
+ complete(ds1wm_data->write_complete);
+
+ if (intr & DS1WM_INT_RBF) {
+ ds1wm_data->read_byte = ds1wm_read_register(ds1wm_data,
+ DS1WM_DATA);
+ if (ds1wm_data->read_complete)
+ complete(ds1wm_data->read_complete);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int ds1wm_reset(struct ds1wm_data *ds1wm_data)
+{
+ unsigned long timeleft;
+ DECLARE_COMPLETION_ONSTACK(reset_done);
+
+ ds1wm_data->reset_complete = &reset_done;
+
+ ds1wm_write_register(ds1wm_data, DS1WM_INT_EN, DS1WM_INTEN_EPD |
+ (ds1wm_data->active_high ? DS1WM_INTEN_IAS : 0));
+
+ ds1wm_write_register(ds1wm_data, DS1WM_CMD, DS1WM_CMD_1W_RESET);
+
+ timeleft = wait_for_completion_timeout(&reset_done, DS1WM_TIMEOUT);
+ ds1wm_data->reset_complete = NULL;
+ if (!timeleft) {
+ dev_dbg(&ds1wm_data->pdev->dev, "reset failed\n");
+ return 1;
+ }
+
+ /* Wait for the end of the reset. According to the specs, the time
+ * from when the interrupt is asserted to the end of the reset is:
+ * tRSTH - tPDH - tPDL - tPDI
+ * 625 us - 60 us - 240 us - 100 ns = 324.9 us
+ *
+ * We'll wait a bit longer just to be sure.
+ */
+ udelay(500);
+
+ ds1wm_write_register(ds1wm_data, DS1WM_INT_EN,
+ DS1WM_INTEN_ERBF | DS1WM_INTEN_ETMT | DS1WM_INTEN_EPD |
+ (ds1wm_data->active_high ? DS1WM_INTEN_IAS : 0));
+
+ if (!ds1wm_data->slave_present) {
+ dev_dbg(&ds1wm_data->pdev->dev, "reset: no devices found\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+static int ds1wm_write(struct ds1wm_data *ds1wm_data, u8 data)
+{
+ DECLARE_COMPLETION_ONSTACK(write_done);
+ ds1wm_data->write_complete = &write_done;
+
+ ds1wm_write_register(ds1wm_data, DS1WM_DATA, data);
+
+ wait_for_completion_timeout(&write_done, DS1WM_TIMEOUT);
+ ds1wm_data->write_complete = NULL;
+
+ return 0;
+}
+
+static int ds1wm_read(struct ds1wm_data *ds1wm_data, unsigned char write_data)
+{
+ DECLARE_COMPLETION_ONSTACK(read_done);
+ ds1wm_data->read_complete = &read_done;
+
+ ds1wm_write(ds1wm_data, write_data);
+ wait_for_completion_timeout(&read_done, DS1WM_TIMEOUT);
+ ds1wm_data->read_complete = NULL;
+
+ return ds1wm_data->read_byte;
+}
+
+static int ds1wm_find_divisor(int gclk)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(freq); i++)
+ if (gclk <= freq[i].freq)
+ return freq[i].divisor;
+
+ return 0;
+}
+
+static void ds1wm_up(struct ds1wm_data *ds1wm_data)
+{
+ int gclk, divisor;
+
+ if (ds1wm_data->pdata->enable)
+ ds1wm_data->pdata->enable(ds1wm_data->pdev);
+
+ gclk = clk_get_rate(ds1wm_data->clk);
+ clk_enable(ds1wm_data->clk);
+ divisor = ds1wm_find_divisor(gclk);
+ if (divisor == 0) {
+ dev_err(&ds1wm_data->pdev->dev,
+ "no suitable divisor for %dHz clock\n", gclk);
+ return;
+ }
+ ds1wm_write_register(ds1wm_data, DS1WM_CLKDIV, divisor);
+
+ /* Let the w1 clock stabilize. */
+ msleep(1);
+
+ ds1wm_reset(ds1wm_data);
+}
+
+static void ds1wm_down(struct ds1wm_data *ds1wm_data)
+{
+ ds1wm_reset(ds1wm_data);
+
+ /* Disable interrupts. */
+ ds1wm_write_register(ds1wm_data, DS1WM_INT_EN,
+ ds1wm_data->active_high ? DS1WM_INTEN_IAS : 0);
+
+ if (ds1wm_data->pdata->disable)
+ ds1wm_data->pdata->disable(ds1wm_data->pdev);
+
+ clk_disable(ds1wm_data->clk);
+}
+
+/* --------------------------------------------------------------------- */
+/* w1 methods */
+
+static u8 ds1wm_read_byte(void *data)
+{
+ struct ds1wm_data *ds1wm_data = data;
+
+ return ds1wm_read(ds1wm_data, 0xff);
+}
+
+static void ds1wm_write_byte(void *data, u8 byte)
+{
+ struct ds1wm_data *ds1wm_data = data;
+
+ ds1wm_write(ds1wm_data, byte);
+}
+
+static u8 ds1wm_reset_bus(void *data)
+{
+ struct ds1wm_data *ds1wm_data = data;
+
+ ds1wm_reset(ds1wm_data);
+
+ return 0;
+}
+
+static void ds1wm_search(void *data, u8 search_type,
+ w1_slave_found_callback slave_found)
+{
+ struct ds1wm_data *ds1wm_data = data;
+ int i;
+ unsigned long long rom_id;
+
+ /* XXX We need to iterate for multiple devices per the DS1WM docs.
+ * See http://www.maxim-ic.com/appnotes.cfm/appnote_number/120. */
+ if (ds1wm_reset(ds1wm_data))
+ return;
+
+ ds1wm_write(ds1wm_data, search_type);
+ ds1wm_write_register(ds1wm_data, DS1WM_CMD, DS1WM_CMD_SRA);
+
+ for (rom_id = 0, i = 0; i < 16; i++) {
+
+ unsigned char resp, r, d;
+
+ resp = ds1wm_read(ds1wm_data, 0x00);
+
+ r = ((resp & 0x02) >> 1) |
+ ((resp & 0x08) >> 2) |
+ ((resp & 0x20) >> 3) |
+ ((resp & 0x80) >> 4);
+
+ d = ((resp & 0x01) >> 0) |
+ ((resp & 0x04) >> 1) |
+ ((resp & 0x10) >> 2) |
+ ((resp & 0x40) >> 3);
+
+ rom_id |= (unsigned long long) r << (i * 4);
+
+ }
+ dev_dbg(&ds1wm_data->pdev->dev, "found 0x%08llX", rom_id);
+
+ ds1wm_write_register(ds1wm_data, DS1WM_CMD, ~DS1WM_CMD_SRA);
+ ds1wm_reset(ds1wm_data);
+
+ slave_found(ds1wm_data, rom_id);
+}
+
+/* --------------------------------------------------------------------- */
+
+static struct w1_bus_master ds1wm_master = {
+ .read_byte = ds1wm_read_byte,
+ .write_byte = ds1wm_write_byte,
+ .reset_bus = ds1wm_reset_bus,
+ .search = ds1wm_search,
+};
+
+static int ds1wm_probe(struct platform_device *pdev)
+{
+ struct ds1wm_data *ds1wm_data;
+ struct ds1wm_platform_data *plat;
+ struct resource *res;
+ int ret;
+
+ if (!pdev)
+ return -ENODEV;
+
+ ds1wm_data = kzalloc(sizeof (*ds1wm_data), GFP_KERNEL);
+ if (!ds1wm_data)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, ds1wm_data);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ ret = -ENXIO;
+ goto err0;
+ }
+ ds1wm_data->map = ioremap(res->start, res->end - res->start + 1);
+ if (!ds1wm_data->map) {
+ ret = -ENOMEM;
+ goto err0;
+ }
+ plat = pdev->dev.platform_data;
+ ds1wm_data->bus_shift = plat->bus_shift;
+ ds1wm_data->pdev = pdev;
+ ds1wm_data->pdata = plat;
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res) {
+ ret = -ENXIO;
+ goto err1;
+ }
+ ds1wm_data->irq = res->start;
+ ds1wm_data->active_high = (res->flags & IORESOURCE_IRQ_HIGHEDGE) ?
+ 1 : 0;
+
+ set_irq_type(ds1wm_data->irq, ds1wm_data->active_high ?
+ IRQ_TYPE_EDGE_RISING : IRQ_TYPE_EDGE_FALLING);
+
+ ret = request_irq(ds1wm_data->irq, ds1wm_isr, IRQF_DISABLED,
+ "ds1wm", ds1wm_data);
+ if (ret)
+ goto err1;
+
+ ds1wm_data->clk = clk_get(&pdev->dev, "ds1wm");
+ if (!ds1wm_data->clk) {
+ ret = -ENOENT;
+ goto err2;
+ }
+
+ ds1wm_up(ds1wm_data);
+
+ ds1wm_master.data = (void *)ds1wm_data;
+
+ ret = w1_add_master_device(&ds1wm_master);
+ if (ret)
+ goto err3;
+
+ return 0;
+
+err3:
+ ds1wm_down(ds1wm_data);
+ clk_put(ds1wm_data->clk);
+err2:
+ free_irq(ds1wm_data->irq, ds1wm_data);
+err1:
+ iounmap(ds1wm_data->map);
+err0:
+ kfree(ds1wm_data);
+
+ return ret;
+}
+
+#ifdef CONFIG_PM
+static int ds1wm_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct ds1wm_data *ds1wm_data = platform_get_drvdata(pdev);
+
+ ds1wm_down(ds1wm_data);
+
+ return 0;
+}
+
+static int ds1wm_resume(struct platform_device *pdev)
+{
+ struct ds1wm_data *ds1wm_data = platform_get_drvdata(pdev);
+
+ ds1wm_up(ds1wm_data);
+
+ return 0;
+}
+#else
+#define ds1wm_suspend NULL
+#define ds1wm_resume NULL
+#endif
+
+static int ds1wm_remove(struct platform_device *pdev)
+{
+ struct ds1wm_data *ds1wm_data = platform_get_drvdata(pdev);
+
+ w1_remove_master_device(&ds1wm_master);
+ ds1wm_down(ds1wm_data);
+ clk_put(ds1wm_data->clk);
+ free_irq(ds1wm_data->irq, ds1wm_data);
+ iounmap(ds1wm_data->map);
+ kfree(ds1wm_data);
+
+ return 0;
+}
+
+static struct platform_driver ds1wm_driver = {
+ .driver = {
+ .name = "ds1wm",
+ },
+ .probe = ds1wm_probe,
+ .remove = ds1wm_remove,
+ .suspend = ds1wm_suspend,
+ .resume = ds1wm_resume
+};
+
+static int __init ds1wm_init(void)
+{
+ printk("DS1WM w1 busmaster driver - (c) 2004 Szabolcs Gyurko\n");
+ return platform_driver_register(&ds1wm_driver);
+}
+
+static void __exit ds1wm_exit(void)
+{
+ platform_driver_unregister(&ds1wm_driver);
+}
+
+module_init(ds1wm_init);
+module_exit(ds1wm_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>, "
+ "Matt Reimer <mreimer@vpop.net>");
+MODULE_DESCRIPTION("DS1WM w1 busmaster driver");
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index 63c0724..7d6876d 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -459,7 +459,7 @@
(unsigned long long) sl->reg_num.id);
dev_dbg(&sl->dev, "%s: registering %s as %p.\n", __func__,
- &sl->dev.bus_id[0]);
+ &sl->dev.bus_id[0], sl);
err = device_register(&sl->dev);
if (err < 0) {
diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c
index 357a2e0..258defd 100644
--- a/drivers/w1/w1_int.c
+++ b/drivers/w1/w1_int.c
@@ -100,7 +100,8 @@
/* validate minimum functionality */
if (!(master->touch_bit && master->reset_bus) &&
- !(master->write_bit && master->read_bit)) {
+ !(master->write_bit && master->read_bit) &&
+ !(master->write_byte && master->read_byte && master->reset_bus)) {
printk(KERN_ERR "w1_add_master_device: invalid function set\n");
return(-EINVAL);
}
diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c
index bed48fa..3128aa9 100644
--- a/fs/9p/vfs_addr.c
+++ b/fs/9p/vfs_addr.c
@@ -29,7 +29,6 @@
#include <linux/file.h>
#include <linux/stat.h>
#include <linux/string.h>
-#include <linux/smp_lock.h>
#include <linux/inet.h>
#include <linux/pagemap.h>
#include <linux/idr.h>
diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c
index ddffd8a..775e26e 100644
--- a/fs/9p/vfs_dentry.c
+++ b/fs/9p/vfs_dentry.c
@@ -30,7 +30,6 @@
#include <linux/pagemap.h>
#include <linux/stat.h>
#include <linux/string.h>
-#include <linux/smp_lock.h>
#include <linux/inet.h>
#include <linux/namei.h>
#include <linux/idr.h>
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c
index 3129688..1dd86ee 100644
--- a/fs/9p/vfs_dir.c
+++ b/fs/9p/vfs_dir.c
@@ -29,7 +29,6 @@
#include <linux/file.h>
#include <linux/stat.h>
#include <linux/string.h>
-#include <linux/smp_lock.h>
#include <linux/sched.h>
#include <linux/inet.h>
#include <linux/idr.h>
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index c7b6772..6e7678e 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -30,7 +30,6 @@
#include <linux/file.h>
#include <linux/stat.h>
#include <linux/string.h>
-#include <linux/smp_lock.h>
#include <linux/inet.h>
#include <linux/list.h>
#include <asm/uaccess.h>
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index b01b0a4..7624821 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -30,7 +30,6 @@
#include <linux/pagemap.h>
#include <linux/stat.h>
#include <linux/string.h>
-#include <linux/smp_lock.h>
#include <linux/inet.h>
#include <linux/namei.h>
#include <linux/idr.h>
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
index 0ec42f6..8eb9263 100644
--- a/fs/9p/vfs_super.c
+++ b/fs/9p/vfs_super.c
@@ -31,7 +31,6 @@
#include <linux/file.h>
#include <linux/stat.h>
#include <linux/string.h>
-#include <linux/smp_lock.h>
#include <linux/inet.h>
#include <linux/pagemap.h>
#include <linux/seq_file.h>
diff --git a/fs/Kconfig b/fs/Kconfig
index 8ea7b04..4622dab 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -314,7 +314,7 @@
config REISERFS_PROC_INFO
bool "Stats in /proc/fs/reiserfs"
- depends on REISERFS_FS
+ depends on REISERFS_FS && PROC_FS
help
Create under /proc/fs/reiserfs a hierarchy of files, displaying
various ReiserFS statistics and internal data at the expense of
diff --git a/fs/attr.c b/fs/attr.c
index 97de946..a0a0c7b 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -9,7 +9,6 @@
#include <linux/time.h>
#include <linux/mm.h>
#include <linux/string.h>
-#include <linux/smp_lock.h>
#include <linux/capability.h>
#include <linux/fsnotify.h>
#include <linux/fcntl.h>
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index 26063dc..5769a2f 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -18,7 +18,6 @@
#include <linux/pagemap.h>
#include <linux/parser.h>
#include <linux/bitops.h>
-#include <linux/smp_lock.h>
#include <linux/magic.h>
#include "autofs_i.h"
#include <linux/module.h>
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index d0e9b3a..15170f4 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -17,7 +17,6 @@
#include <linux/stat.h>
#include <linux/param.h>
#include <linux/time.h>
-#include <linux/smp_lock.h>
#include "autofs_i.h"
static int autofs4_dir_symlink(struct inode *,struct dentry *,const char *);
diff --git a/fs/bad_inode.c b/fs/bad_inode.c
index efeab2f..329ee47 100644
--- a/fs/bad_inode.c
+++ b/fs/bad_inode.c
@@ -12,7 +12,6 @@
#include <linux/module.h>
#include <linux/stat.h>
#include <linux/time.h>
-#include <linux/smp_lock.h>
#include <linux/namei.h>
#include <linux/poll.h>
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 9cc4f0a..fa8ea33 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -31,7 +31,6 @@
#include <linux/init.h>
#include <linux/highuid.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/compiler.h>
#include <linux/highmem.h>
#include <linux/pagemap.h>
@@ -39,6 +38,7 @@
#include <linux/syscalls.h>
#include <linux/random.h>
#include <linux/elf.h>
+#include <linux/utsname.h>
#include <asm/uaccess.h>
#include <asm/param.h>
#include <asm/page.h>
@@ -871,6 +871,8 @@
elf_prot, elf_flags);
if (BAD_ADDR(error)) {
send_sig(SIGKILL, current, 0);
+ retval = IS_ERR((void *)error) ?
+ PTR_ERR((void*)error) : -EINVAL;
goto out_free_dentry;
}
@@ -900,6 +902,7 @@
TASK_SIZE - elf_ppnt->p_memsz < k) {
/* set_brk can never work. Avoid overflows. */
send_sig(SIGKILL, current, 0);
+ retval = -EINVAL;
goto out_free_dentry;
}
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index f3ddca4..9d62fba 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -30,7 +30,6 @@
#include <linux/personality.h>
#include <linux/ptrace.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/elf.h>
#include <linux/elf-fdpic.h>
#include <linux/elfcore.h>
diff --git a/fs/binfmt_em86.c b/fs/binfmt_em86.c
index 1f2d1ad..576dd7d 100644
--- a/fs/binfmt_em86.c
+++ b/fs/binfmt_em86.c
@@ -12,7 +12,6 @@
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/binfmts.h>
#include <linux/elf.h>
#include <linux/init.h>
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index e6f5799..18657f0 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -727,8 +727,8 @@
static int bm_fill_super(struct super_block * sb, void * data, int silent)
{
static struct tree_descr bm_files[] = {
- [1] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
- [2] = {"register", &bm_register_operations, S_IWUSR},
+ [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
+ [3] = {"register", &bm_register_operations, S_IWUSR},
/* last one */ {""}
};
int err = simple_fill_super(sb, 0x42494e4d, bm_files);
diff --git a/fs/binfmt_script.c b/fs/binfmt_script.c
index 1edbcca..304c885 100644
--- a/fs/binfmt_script.c
+++ b/fs/binfmt_script.c
@@ -12,7 +12,6 @@
#include <linux/binfmts.h>
#include <linux/init.h>
#include <linux/file.h>
-#include <linux/smp_lock.h>
#include <linux/err.h>
#include <linux/fs.h>
diff --git a/fs/block_dev.c b/fs/block_dev.c
index f02b7bd..7428992 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -22,6 +22,7 @@
#include <linux/mount.h>
#include <linux/uio.h>
#include <linux/namei.h>
+#include <linux/log2.h>
#include <asm/uaccess.h>
#include "internal.h"
@@ -67,7 +68,7 @@
int set_blocksize(struct block_device *bdev, int size)
{
/* Size must be a power of two, and between 512 and PAGE_SIZE */
- if (size > PAGE_SIZE || size < 512 || (size & (size-1)))
+ if (size > PAGE_SIZE || size < 512 || !is_power_of_2(size))
return -EINVAL;
/* Size cannot be smaller than the size supported by the device */
diff --git a/fs/buffer.c b/fs/buffer.c
index 7db24b9..eb820b8 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -24,7 +24,6 @@
#include <linux/mm.h>
#include <linux/percpu.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/capability.h>
#include <linux/blkdev.h>
#include <linux/file.h>
@@ -1727,6 +1726,7 @@
} while ((bh = bh->b_this_page) != head);
SetPageError(page);
BUG_ON(PageWriteback(page));
+ mapping_set_error(page->mapping, err);
set_page_writeback(page);
do {
struct buffer_head *next = bh->b_this_page;
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index b570530..94d5b49 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -27,7 +27,6 @@
#include <linux/fcntl.h>
#include <linux/pagemap.h>
#include <linux/pagevec.h>
-#include <linux/smp_lock.h>
#include <linux/writeback.h>
#include <linux/task_io_accounting_ops.h>
#include <linux/delay.h>
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index b5364f90..c08bda9 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -23,7 +23,6 @@
#include <linux/fs.h>
#include <linux/pagemap.h>
#include <linux/stat.h>
-#include <linux/smp_lock.h>
#include "cifspdu.h"
#include "cifsglob.h"
#include "cifsproto.h"
diff --git a/fs/compat.c b/fs/compat.c
index 72e5e69..9cf75df 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -15,6 +15,7 @@
* published by the Free Software Foundation.
*/
+#include <linux/kernel.h>
#include <linux/linkage.h>
#include <linux/compat.h>
#include <linux/errno.h>
@@ -24,10 +25,8 @@
#include <linux/namei.h>
#include <linux/file.h>
#include <linux/vfs.h>
-#include <linux/ioctl32.h>
#include <linux/ioctl.h>
#include <linux/init.h>
-#include <linux/sockios.h> /* for SIOCDEVPRIVATE */
#include <linux/smb.h>
#include <linux/smb_mount.h>
#include <linux/ncp_mount.h>
@@ -45,13 +44,12 @@
#include <linux/personality.h>
#include <linux/rwsem.h>
#include <linux/tsacct_kern.h>
+#include <linux/security.h>
#include <linux/highmem.h>
#include <linux/poll.h>
#include <linux/mm.h>
#include <linux/eventpoll.h>
-#include <net/sock.h> /* siocdevprivate_ioctl */
-
#include <asm/uaccess.h>
#include <asm/mmu_context.h>
#include <asm/ioctls.h>
@@ -79,30 +77,57 @@
*/
asmlinkage long compat_sys_utime(char __user *filename, struct compat_utimbuf __user *t)
{
- struct timeval tv[2];
+ struct timespec tv[2];
if (t) {
if (get_user(tv[0].tv_sec, &t->actime) ||
get_user(tv[1].tv_sec, &t->modtime))
return -EFAULT;
- tv[0].tv_usec = 0;
- tv[1].tv_usec = 0;
+ tv[0].tv_nsec = 0;
+ tv[1].tv_nsec = 0;
}
- return do_utimes(AT_FDCWD, filename, t ? tv : NULL);
+ return do_utimes(AT_FDCWD, filename, t ? tv : NULL, 0);
+}
+
+asmlinkage long compat_sys_utimensat(unsigned int dfd, char __user *filename, struct compat_timespec __user *t, int flags)
+{
+ struct timespec tv[2];
+
+ if (t) {
+ if (get_compat_timespec(&tv[0], &t[0]) ||
+ get_compat_timespec(&tv[1], &t[1]))
+ return -EFAULT;
+
+ if ((tv[0].tv_nsec == UTIME_OMIT || tv[0].tv_nsec == UTIME_NOW)
+ && tv[0].tv_sec != 0)
+ return -EINVAL;
+ if ((tv[1].tv_nsec == UTIME_OMIT || tv[1].tv_nsec == UTIME_NOW)
+ && tv[1].tv_sec != 0)
+ return -EINVAL;
+
+ if (tv[0].tv_nsec == UTIME_OMIT && tv[1].tv_nsec == UTIME_OMIT)
+ return 0;
+ }
+ return do_utimes(dfd, filename, t ? tv : NULL, flags);
}
asmlinkage long compat_sys_futimesat(unsigned int dfd, char __user *filename, struct compat_timeval __user *t)
{
- struct timeval tv[2];
+ struct timespec tv[2];
if (t) {
if (get_user(tv[0].tv_sec, &t[0].tv_sec) ||
- get_user(tv[0].tv_usec, &t[0].tv_usec) ||
+ get_user(tv[0].tv_nsec, &t[0].tv_usec) ||
get_user(tv[1].tv_sec, &t[1].tv_sec) ||
- get_user(tv[1].tv_usec, &t[1].tv_usec))
+ get_user(tv[1].tv_nsec, &t[1].tv_usec))
return -EFAULT;
+ if (tv[0].tv_nsec >= 1000000 || tv[0].tv_nsec < 0 ||
+ tv[1].tv_nsec >= 1000000 || tv[1].tv_nsec < 0)
+ return -EINVAL;
+ tv[0].tv_nsec *= 1000;
+ tv[1].tv_nsec *= 1000;
}
- return do_utimes(dfd, filename, t ? tv : NULL);
+ return do_utimes(dfd, filename, t ? tv : NULL, 0);
}
asmlinkage long compat_sys_utimes(char __user *filename, struct compat_timeval __user *t)
@@ -312,163 +337,6 @@
return error;
}
-/* ioctl32 stuff, used by sparc64, parisc, s390x, ppc64, x86_64, MIPS */
-
-#define IOCTL_HASHSIZE 256
-static struct ioctl_trans *ioctl32_hash_table[IOCTL_HASHSIZE];
-
-static inline unsigned long ioctl32_hash(unsigned long cmd)
-{
- return (((cmd >> 6) ^ (cmd >> 4) ^ cmd)) % IOCTL_HASHSIZE;
-}
-
-static void ioctl32_insert_translation(struct ioctl_trans *trans)
-{
- unsigned long hash;
- struct ioctl_trans *t;
-
- hash = ioctl32_hash (trans->cmd);
- if (!ioctl32_hash_table[hash])
- ioctl32_hash_table[hash] = trans;
- else {
- t = ioctl32_hash_table[hash];
- while (t->next)
- t = t->next;
- trans->next = NULL;
- t->next = trans;
- }
-}
-
-static int __init init_sys32_ioctl(void)
-{
- int i;
-
- for (i = 0; i < ioctl_table_size; i++) {
- if (ioctl_start[i].next != 0) {
- printk("ioctl translation %d bad\n",i);
- return -1;
- }
-
- ioctl32_insert_translation(&ioctl_start[i]);
- }
- return 0;
-}
-
-__initcall(init_sys32_ioctl);
-
-static void compat_ioctl_error(struct file *filp, unsigned int fd,
- unsigned int cmd, unsigned long arg)
-{
- char buf[10];
- char *fn = "?";
- char *path;
-
- /* find the name of the device. */
- path = (char *)__get_free_page(GFP_KERNEL);
- if (path) {
- fn = d_path(filp->f_path.dentry, filp->f_path.mnt, path, PAGE_SIZE);
- if (IS_ERR(fn))
- fn = "?";
- }
-
- sprintf(buf,"'%c'", (cmd>>_IOC_TYPESHIFT) & _IOC_TYPEMASK);
- if (!isprint(buf[1]))
- sprintf(buf, "%02x", buf[1]);
- compat_printk("ioctl32(%s:%d): Unknown cmd fd(%d) "
- "cmd(%08x){t:%s;sz:%u} arg(%08x) on %s\n",
- current->comm, current->pid,
- (int)fd, (unsigned int)cmd, buf,
- (cmd >> _IOC_SIZESHIFT) & _IOC_SIZEMASK,
- (unsigned int)arg, fn);
-
- if (path)
- free_page((unsigned long)path);
-}
-
-asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
- unsigned long arg)
-{
- struct file *filp;
- int error = -EBADF;
- struct ioctl_trans *t;
- int fput_needed;
-
- filp = fget_light(fd, &fput_needed);
- if (!filp)
- goto out;
-
- /* RED-PEN how should LSM module know it's handling 32bit? */
- error = security_file_ioctl(filp, cmd, arg);
- if (error)
- goto out_fput;
-
- /*
- * To allow the compat_ioctl handlers to be self contained
- * we need to check the common ioctls here first.
- * Just handle them with the standard handlers below.
- */
- switch (cmd) {
- case FIOCLEX:
- case FIONCLEX:
- case FIONBIO:
- case FIOASYNC:
- case FIOQSIZE:
- break;
-
- case FIBMAP:
- case FIGETBSZ:
- case FIONREAD:
- if (S_ISREG(filp->f_path.dentry->d_inode->i_mode))
- break;
- /*FALL THROUGH*/
-
- default:
- if (filp->f_op && filp->f_op->compat_ioctl) {
- error = filp->f_op->compat_ioctl(filp, cmd, arg);
- if (error != -ENOIOCTLCMD)
- goto out_fput;
- }
-
- if (!filp->f_op ||
- (!filp->f_op->ioctl && !filp->f_op->unlocked_ioctl))
- goto do_ioctl;
- break;
- }
-
- for (t = ioctl32_hash_table[ioctl32_hash(cmd)]; t; t = t->next) {
- if (t->cmd == cmd)
- goto found_handler;
- }
-
- if (S_ISSOCK(filp->f_path.dentry->d_inode->i_mode) &&
- cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
- error = siocdevprivate_ioctl(fd, cmd, arg);
- } else {
- static int count;
-
- if (++count <= 50)
- compat_ioctl_error(filp, fd, cmd, arg);
- error = -EINVAL;
- }
-
- goto out_fput;
-
- found_handler:
- if (t->handler) {
- lock_kernel();
- error = t->handler(fd, cmd, arg, filp);
- unlock_kernel();
- goto out_fput;
- }
-
- do_ioctl:
- error = vfs_ioctl(filp, fd, cmd, arg);
- out_fput:
- fput_light(filp, fput_needed);
- out:
- return error;
-}
-
static int get_compat_flock(struct flock *kfl, struct compat_flock __user *ufl)
{
if (!access_ok(VERIFY_READ, ufl, sizeof(*ufl)) ||
@@ -902,8 +770,6 @@
}
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
-#define COMPAT_ROUND_UP(x) (((x)+sizeof(compat_long_t)-1) & \
- ~(sizeof(compat_long_t)-1))
struct compat_old_linux_dirent {
compat_ulong_t d_ino;
@@ -991,7 +857,7 @@
struct compat_linux_dirent __user * dirent;
struct compat_getdents_callback *buf = __buf;
compat_ulong_t d_ino;
- int reclen = COMPAT_ROUND_UP(NAME_OFFSET(dirent) + namlen + 2);
+ int reclen = ALIGN(NAME_OFFSET(dirent) + namlen + 2, sizeof(compat_long_t));
buf->error = -EINVAL; /* only used if we fail.. */
if (reclen > buf->count)
@@ -1066,7 +932,6 @@
}
#ifndef __ARCH_OMIT_COMPAT_SYS_GETDENTS64
-#define COMPAT_ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1))
struct compat_getdents_callback64 {
struct linux_dirent64 __user *current_dir;
@@ -1081,7 +946,7 @@
struct linux_dirent64 __user *dirent;
struct compat_getdents_callback64 *buf = __buf;
int jj = NAME_OFFSET(dirent);
- int reclen = COMPAT_ROUND_UP64(jj + namlen + 1);
+ int reclen = ALIGN(jj + namlen + 1, sizeof(u64));
u64 off;
buf->error = -EINVAL; /* only used if we fail.. */
@@ -1594,8 +1459,6 @@
#define __COMPAT_NFDBITS (8 * sizeof(compat_ulong_t))
-#define ROUND_UP(x,y) (((x)+(y)-1)/(y))
-
/*
* Ooo, nasty. We need here to frob 32-bit unsigned longs to
* 64-bit unsigned longs.
@@ -1604,7 +1467,7 @@
int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
unsigned long *fdset)
{
- nr = ROUND_UP(nr, __COMPAT_NFDBITS);
+ nr = DIV_ROUND_UP(nr, __COMPAT_NFDBITS);
if (ufdset) {
unsigned long odd;
@@ -1638,7 +1501,7 @@
unsigned long *fdset)
{
unsigned long odd;
- nr = ROUND_UP(nr, __COMPAT_NFDBITS);
+ nr = DIV_ROUND_UP(nr, __COMPAT_NFDBITS);
if (!ufdset)
return 0;
@@ -1760,7 +1623,7 @@
if ((u64)tv.tv_sec >= (u64)MAX_INT64_SECONDS)
timeout = -1; /* infinite */
else {
- timeout = ROUND_UP(tv.tv_usec, 1000000/HZ);
+ timeout = DIV_ROUND_UP(tv.tv_usec, 1000000/HZ);
timeout += tv.tv_sec * HZ;
}
}
@@ -1828,7 +1691,7 @@
do {
if (tsp) {
if ((unsigned long)ts.tv_sec < MAX_SELECT_SECONDS) {
- timeout = ROUND_UP(ts.tv_nsec, 1000000000/HZ);
+ timeout = DIV_ROUND_UP(ts.tv_nsec, 1000000000/HZ);
timeout += ts.tv_sec * (unsigned long)HZ;
ts.tv_sec = 0;
ts.tv_nsec = 0;
@@ -1924,7 +1787,7 @@
/* We assume that ts.tv_sec is always lower than
the number of seconds that can be expressed in
an s64. Otherwise the compiler bitches at us */
- timeout = ROUND_UP(ts.tv_nsec, 1000000000/HZ);
+ timeout = DIV_ROUND_UP(ts.tv_nsec, 1000000000/HZ);
timeout += ts.tv_sec * HZ;
}
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 464c04a..d92bc3e 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -17,7 +17,6 @@
#include <linux/compiler.h>
#include <linux/sched.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/ioctl.h>
#include <linux/if.h>
#include <linux/if_bridge.h>
@@ -58,7 +57,6 @@
#include <linux/serial.h>
#include <linux/if_tun.h>
#include <linux/ctype.h>
-#include <linux/ioctl32.h>
#include <linux/syscalls.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
@@ -66,7 +64,6 @@
#include <linux/atalk.h>
#include <linux/blktrace_api.h>
-#include <net/sock.h> /* siocdevprivate_ioctl */
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci.h>
#include <net/bluetooth/rfcomm.h>
@@ -475,7 +472,7 @@
};
}
-int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+static int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
{
struct ifreq __user *u_ifreq64;
struct ifreq32 __user *u_ifreq32 = compat_ptr(arg);
@@ -687,8 +684,10 @@
if (!err) {
err = copy_to_user (ugeo, &geo, 4);
err |= __put_user (geo.start, &ugeo->start);
+ if (err)
+ err = -EFAULT;
}
- return err ? -EFAULT : 0;
+ return err;
}
static int hdio_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
@@ -2385,6 +2384,16 @@
return sys_ioctl(fd, cmd, (unsigned long)tn);
}
+
+typedef int (*ioctl_trans_handler_t)(unsigned int, unsigned int,
+ unsigned long, struct file *);
+
+struct ioctl_trans {
+ unsigned long cmd;
+ ioctl_trans_handler_t handler;
+ struct ioctl_trans *next;
+};
+
#define HANDLE_IOCTL(cmd,handler) \
{ (cmd), (ioctl_trans_handler_t)(handler) },
@@ -2405,8 +2414,835 @@
Most other reasons are not valid. */
#define IGNORE_IOCTL(cmd) COMPATIBLE_IOCTL(cmd)
-struct ioctl_trans ioctl_start[] = {
-#include <linux/compat_ioctl.h>
+static struct ioctl_trans ioctl_start[] = {
+/* compatible ioctls first */
+COMPATIBLE_IOCTL(0x4B50) /* KDGHWCLK - not in the kernel, but don't complain */
+COMPATIBLE_IOCTL(0x4B51) /* KDSHWCLK - not in the kernel, but don't complain */
+
+/* Big T */
+COMPATIBLE_IOCTL(TCGETA)
+COMPATIBLE_IOCTL(TCSETA)
+COMPATIBLE_IOCTL(TCSETAW)
+COMPATIBLE_IOCTL(TCSETAF)
+COMPATIBLE_IOCTL(TCSBRK)
+ULONG_IOCTL(TCSBRKP)
+COMPATIBLE_IOCTL(TCXONC)
+COMPATIBLE_IOCTL(TCFLSH)
+COMPATIBLE_IOCTL(TCGETS)
+COMPATIBLE_IOCTL(TCSETS)
+COMPATIBLE_IOCTL(TCSETSW)
+COMPATIBLE_IOCTL(TCSETSF)
+COMPATIBLE_IOCTL(TIOCLINUX)
+COMPATIBLE_IOCTL(TIOCSBRK)
+COMPATIBLE_IOCTL(TIOCCBRK)
+ULONG_IOCTL(TIOCMIWAIT)
+COMPATIBLE_IOCTL(TIOCGICOUNT)
+/* Little t */
+COMPATIBLE_IOCTL(TIOCGETD)
+COMPATIBLE_IOCTL(TIOCSETD)
+COMPATIBLE_IOCTL(TIOCEXCL)
+COMPATIBLE_IOCTL(TIOCNXCL)
+COMPATIBLE_IOCTL(TIOCCONS)
+COMPATIBLE_IOCTL(TIOCGSOFTCAR)
+COMPATIBLE_IOCTL(TIOCSSOFTCAR)
+COMPATIBLE_IOCTL(TIOCSWINSZ)
+COMPATIBLE_IOCTL(TIOCGWINSZ)
+COMPATIBLE_IOCTL(TIOCMGET)
+COMPATIBLE_IOCTL(TIOCMBIC)
+COMPATIBLE_IOCTL(TIOCMBIS)
+COMPATIBLE_IOCTL(TIOCMSET)
+COMPATIBLE_IOCTL(TIOCPKT)
+COMPATIBLE_IOCTL(TIOCNOTTY)
+COMPATIBLE_IOCTL(TIOCSTI)
+COMPATIBLE_IOCTL(TIOCOUTQ)
+COMPATIBLE_IOCTL(TIOCSPGRP)
+COMPATIBLE_IOCTL(TIOCGPGRP)
+ULONG_IOCTL(TIOCSCTTY)
+COMPATIBLE_IOCTL(TIOCGPTN)
+COMPATIBLE_IOCTL(TIOCSPTLCK)
+COMPATIBLE_IOCTL(TIOCSERGETLSR)
+/* Little f */
+COMPATIBLE_IOCTL(FIOCLEX)
+COMPATIBLE_IOCTL(FIONCLEX)
+COMPATIBLE_IOCTL(FIOASYNC)
+COMPATIBLE_IOCTL(FIONBIO)
+COMPATIBLE_IOCTL(FIONREAD) /* This is also TIOCINQ */
+/* 0x00 */
+COMPATIBLE_IOCTL(FIBMAP)
+COMPATIBLE_IOCTL(FIGETBSZ)
+/* 0x03 -- HD/IDE ioctl's used by hdparm and friends.
+ * Some need translations, these do not.
+ */
+COMPATIBLE_IOCTL(HDIO_GET_IDENTITY)
+COMPATIBLE_IOCTL(HDIO_DRIVE_TASK)
+COMPATIBLE_IOCTL(HDIO_DRIVE_CMD)
+ULONG_IOCTL(HDIO_SET_MULTCOUNT)
+ULONG_IOCTL(HDIO_SET_UNMASKINTR)
+ULONG_IOCTL(HDIO_SET_KEEPSETTINGS)
+ULONG_IOCTL(HDIO_SET_32BIT)
+ULONG_IOCTL(HDIO_SET_NOWERR)
+ULONG_IOCTL(HDIO_SET_DMA)
+ULONG_IOCTL(HDIO_SET_PIO_MODE)
+ULONG_IOCTL(HDIO_SET_NICE)
+ULONG_IOCTL(HDIO_SET_WCACHE)
+ULONG_IOCTL(HDIO_SET_ACOUSTIC)
+ULONG_IOCTL(HDIO_SET_BUSSTATE)
+ULONG_IOCTL(HDIO_SET_ADDRESS)
+COMPATIBLE_IOCTL(HDIO_SCAN_HWIF)
+/* 0x330 is reserved -- it used to be HDIO_GETGEO_BIG */
+COMPATIBLE_IOCTL(0x330)
+/* 0x02 -- Floppy ioctls */
+COMPATIBLE_IOCTL(FDMSGON)
+COMPATIBLE_IOCTL(FDMSGOFF)
+COMPATIBLE_IOCTL(FDSETEMSGTRESH)
+COMPATIBLE_IOCTL(FDFLUSH)
+COMPATIBLE_IOCTL(FDWERRORCLR)
+COMPATIBLE_IOCTL(FDSETMAXERRS)
+COMPATIBLE_IOCTL(FDGETMAXERRS)
+COMPATIBLE_IOCTL(FDGETDRVTYP)
+COMPATIBLE_IOCTL(FDEJECT)
+COMPATIBLE_IOCTL(FDCLRPRM)
+COMPATIBLE_IOCTL(FDFMTBEG)
+COMPATIBLE_IOCTL(FDFMTEND)
+COMPATIBLE_IOCTL(FDRESET)
+COMPATIBLE_IOCTL(FDTWADDLE)
+COMPATIBLE_IOCTL(FDFMTTRK)
+COMPATIBLE_IOCTL(FDRAWCMD)
+/* 0x12 */
+#ifdef CONFIG_BLOCK
+COMPATIBLE_IOCTL(BLKRASET)
+COMPATIBLE_IOCTL(BLKROSET)
+COMPATIBLE_IOCTL(BLKROGET)
+COMPATIBLE_IOCTL(BLKRRPART)
+COMPATIBLE_IOCTL(BLKFLSBUF)
+COMPATIBLE_IOCTL(BLKSECTSET)
+COMPATIBLE_IOCTL(BLKSSZGET)
+COMPATIBLE_IOCTL(BLKTRACESTART)
+COMPATIBLE_IOCTL(BLKTRACESTOP)
+COMPATIBLE_IOCTL(BLKTRACESETUP)
+COMPATIBLE_IOCTL(BLKTRACETEARDOWN)
+ULONG_IOCTL(BLKRASET)
+ULONG_IOCTL(BLKFRASET)
+#endif
+/* RAID */
+COMPATIBLE_IOCTL(RAID_VERSION)
+COMPATIBLE_IOCTL(GET_ARRAY_INFO)
+COMPATIBLE_IOCTL(GET_DISK_INFO)
+COMPATIBLE_IOCTL(PRINT_RAID_DEBUG)
+COMPATIBLE_IOCTL(RAID_AUTORUN)
+COMPATIBLE_IOCTL(CLEAR_ARRAY)
+COMPATIBLE_IOCTL(ADD_NEW_DISK)
+ULONG_IOCTL(HOT_REMOVE_DISK)
+COMPATIBLE_IOCTL(SET_ARRAY_INFO)
+COMPATIBLE_IOCTL(SET_DISK_INFO)
+COMPATIBLE_IOCTL(WRITE_RAID_INFO)
+COMPATIBLE_IOCTL(UNPROTECT_ARRAY)
+COMPATIBLE_IOCTL(PROTECT_ARRAY)
+ULONG_IOCTL(HOT_ADD_DISK)
+ULONG_IOCTL(SET_DISK_FAULTY)
+COMPATIBLE_IOCTL(RUN_ARRAY)
+COMPATIBLE_IOCTL(STOP_ARRAY)
+COMPATIBLE_IOCTL(STOP_ARRAY_RO)
+COMPATIBLE_IOCTL(RESTART_ARRAY_RW)
+COMPATIBLE_IOCTL(GET_BITMAP_FILE)
+ULONG_IOCTL(SET_BITMAP_FILE)
+/* DM */
+COMPATIBLE_IOCTL(DM_VERSION_32)
+COMPATIBLE_IOCTL(DM_REMOVE_ALL_32)
+COMPATIBLE_IOCTL(DM_LIST_DEVICES_32)
+COMPATIBLE_IOCTL(DM_DEV_CREATE_32)
+COMPATIBLE_IOCTL(DM_DEV_REMOVE_32)
+COMPATIBLE_IOCTL(DM_DEV_RENAME_32)
+COMPATIBLE_IOCTL(DM_DEV_SUSPEND_32)
+COMPATIBLE_IOCTL(DM_DEV_STATUS_32)
+COMPATIBLE_IOCTL(DM_DEV_WAIT_32)
+COMPATIBLE_IOCTL(DM_TABLE_LOAD_32)
+COMPATIBLE_IOCTL(DM_TABLE_CLEAR_32)
+COMPATIBLE_IOCTL(DM_TABLE_DEPS_32)
+COMPATIBLE_IOCTL(DM_TABLE_STATUS_32)
+COMPATIBLE_IOCTL(DM_LIST_VERSIONS_32)
+COMPATIBLE_IOCTL(DM_TARGET_MSG_32)
+COMPATIBLE_IOCTL(DM_DEV_SET_GEOMETRY_32)
+COMPATIBLE_IOCTL(DM_VERSION)
+COMPATIBLE_IOCTL(DM_REMOVE_ALL)
+COMPATIBLE_IOCTL(DM_LIST_DEVICES)
+COMPATIBLE_IOCTL(DM_DEV_CREATE)
+COMPATIBLE_IOCTL(DM_DEV_REMOVE)
+COMPATIBLE_IOCTL(DM_DEV_RENAME)
+COMPATIBLE_IOCTL(DM_DEV_SUSPEND)
+COMPATIBLE_IOCTL(DM_DEV_STATUS)
+COMPATIBLE_IOCTL(DM_DEV_WAIT)
+COMPATIBLE_IOCTL(DM_TABLE_LOAD)
+COMPATIBLE_IOCTL(DM_TABLE_CLEAR)
+COMPATIBLE_IOCTL(DM_TABLE_DEPS)
+COMPATIBLE_IOCTL(DM_TABLE_STATUS)
+COMPATIBLE_IOCTL(DM_LIST_VERSIONS)
+COMPATIBLE_IOCTL(DM_TARGET_MSG)
+COMPATIBLE_IOCTL(DM_DEV_SET_GEOMETRY)
+/* Big K */
+COMPATIBLE_IOCTL(PIO_FONT)
+COMPATIBLE_IOCTL(GIO_FONT)
+ULONG_IOCTL(KDSIGACCEPT)
+COMPATIBLE_IOCTL(KDGETKEYCODE)
+COMPATIBLE_IOCTL(KDSETKEYCODE)
+ULONG_IOCTL(KIOCSOUND)
+ULONG_IOCTL(KDMKTONE)
+COMPATIBLE_IOCTL(KDGKBTYPE)
+ULONG_IOCTL(KDSETMODE)
+COMPATIBLE_IOCTL(KDGETMODE)
+ULONG_IOCTL(KDSKBMODE)
+COMPATIBLE_IOCTL(KDGKBMODE)
+ULONG_IOCTL(KDSKBMETA)
+COMPATIBLE_IOCTL(KDGKBMETA)
+COMPATIBLE_IOCTL(KDGKBENT)
+COMPATIBLE_IOCTL(KDSKBENT)
+COMPATIBLE_IOCTL(KDGKBSENT)
+COMPATIBLE_IOCTL(KDSKBSENT)
+COMPATIBLE_IOCTL(KDGKBDIACR)
+COMPATIBLE_IOCTL(KDSKBDIACR)
+COMPATIBLE_IOCTL(KDKBDREP)
+COMPATIBLE_IOCTL(KDGKBLED)
+ULONG_IOCTL(KDSKBLED)
+COMPATIBLE_IOCTL(KDGETLED)
+ULONG_IOCTL(KDSETLED)
+COMPATIBLE_IOCTL(GIO_SCRNMAP)
+COMPATIBLE_IOCTL(PIO_SCRNMAP)
+COMPATIBLE_IOCTL(GIO_UNISCRNMAP)
+COMPATIBLE_IOCTL(PIO_UNISCRNMAP)
+COMPATIBLE_IOCTL(PIO_FONTRESET)
+COMPATIBLE_IOCTL(PIO_UNIMAPCLR)
+/* Big S */
+COMPATIBLE_IOCTL(SCSI_IOCTL_GET_IDLUN)
+COMPATIBLE_IOCTL(SCSI_IOCTL_DOORLOCK)
+COMPATIBLE_IOCTL(SCSI_IOCTL_DOORUNLOCK)
+COMPATIBLE_IOCTL(SCSI_IOCTL_TEST_UNIT_READY)
+COMPATIBLE_IOCTL(SCSI_IOCTL_GET_BUS_NUMBER)
+COMPATIBLE_IOCTL(SCSI_IOCTL_SEND_COMMAND)
+COMPATIBLE_IOCTL(SCSI_IOCTL_PROBE_HOST)
+COMPATIBLE_IOCTL(SCSI_IOCTL_GET_PCI)
+/* Big T */
+COMPATIBLE_IOCTL(TUNSETNOCSUM)
+COMPATIBLE_IOCTL(TUNSETDEBUG)
+COMPATIBLE_IOCTL(TUNSETPERSIST)
+COMPATIBLE_IOCTL(TUNSETOWNER)
+/* Big V */
+COMPATIBLE_IOCTL(VT_SETMODE)
+COMPATIBLE_IOCTL(VT_GETMODE)
+COMPATIBLE_IOCTL(VT_GETSTATE)
+COMPATIBLE_IOCTL(VT_OPENQRY)
+ULONG_IOCTL(VT_ACTIVATE)
+ULONG_IOCTL(VT_WAITACTIVE)
+ULONG_IOCTL(VT_RELDISP)
+ULONG_IOCTL(VT_DISALLOCATE)
+COMPATIBLE_IOCTL(VT_RESIZE)
+COMPATIBLE_IOCTL(VT_RESIZEX)
+COMPATIBLE_IOCTL(VT_LOCKSWITCH)
+COMPATIBLE_IOCTL(VT_UNLOCKSWITCH)
+COMPATIBLE_IOCTL(VT_GETHIFONTMASK)
+/* Little p (/dev/rtc, /dev/envctrl, etc.) */
+COMPATIBLE_IOCTL(RTC_AIE_ON)
+COMPATIBLE_IOCTL(RTC_AIE_OFF)
+COMPATIBLE_IOCTL(RTC_UIE_ON)
+COMPATIBLE_IOCTL(RTC_UIE_OFF)
+COMPATIBLE_IOCTL(RTC_PIE_ON)
+COMPATIBLE_IOCTL(RTC_PIE_OFF)
+COMPATIBLE_IOCTL(RTC_WIE_ON)
+COMPATIBLE_IOCTL(RTC_WIE_OFF)
+COMPATIBLE_IOCTL(RTC_ALM_SET)
+COMPATIBLE_IOCTL(RTC_ALM_READ)
+COMPATIBLE_IOCTL(RTC_RD_TIME)
+COMPATIBLE_IOCTL(RTC_SET_TIME)
+COMPATIBLE_IOCTL(RTC_WKALM_SET)
+COMPATIBLE_IOCTL(RTC_WKALM_RD)
+/*
+ * These two are only for the sbus rtc driver, but
+ * hwclock tries them on every rtc device first when
+ * running on sparc. On other architectures the entries
+ * are useless but harmless.
+ */
+COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */
+COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */
+/* Little m */
+COMPATIBLE_IOCTL(MTIOCTOP)
+/* Socket level stuff */
+COMPATIBLE_IOCTL(FIOQSIZE)
+COMPATIBLE_IOCTL(FIOSETOWN)
+COMPATIBLE_IOCTL(SIOCSPGRP)
+COMPATIBLE_IOCTL(FIOGETOWN)
+COMPATIBLE_IOCTL(SIOCGPGRP)
+COMPATIBLE_IOCTL(SIOCATMARK)
+COMPATIBLE_IOCTL(SIOCSIFLINK)
+COMPATIBLE_IOCTL(SIOCSIFENCAP)
+COMPATIBLE_IOCTL(SIOCGIFENCAP)
+COMPATIBLE_IOCTL(SIOCSIFNAME)
+COMPATIBLE_IOCTL(SIOCSARP)
+COMPATIBLE_IOCTL(SIOCGARP)
+COMPATIBLE_IOCTL(SIOCDARP)
+COMPATIBLE_IOCTL(SIOCSRARP)
+COMPATIBLE_IOCTL(SIOCGRARP)
+COMPATIBLE_IOCTL(SIOCDRARP)
+COMPATIBLE_IOCTL(SIOCADDDLCI)
+COMPATIBLE_IOCTL(SIOCDELDLCI)
+COMPATIBLE_IOCTL(SIOCGMIIPHY)
+COMPATIBLE_IOCTL(SIOCGMIIREG)
+COMPATIBLE_IOCTL(SIOCSMIIREG)
+COMPATIBLE_IOCTL(SIOCGIFVLAN)
+COMPATIBLE_IOCTL(SIOCSIFVLAN)
+COMPATIBLE_IOCTL(SIOCBRADDBR)
+COMPATIBLE_IOCTL(SIOCBRDELBR)
+/* SG stuff */
+COMPATIBLE_IOCTL(SG_SET_TIMEOUT)
+COMPATIBLE_IOCTL(SG_GET_TIMEOUT)
+COMPATIBLE_IOCTL(SG_EMULATED_HOST)
+ULONG_IOCTL(SG_SET_TRANSFORM)
+COMPATIBLE_IOCTL(SG_GET_TRANSFORM)
+COMPATIBLE_IOCTL(SG_SET_RESERVED_SIZE)
+COMPATIBLE_IOCTL(SG_GET_RESERVED_SIZE)
+COMPATIBLE_IOCTL(SG_GET_SCSI_ID)
+COMPATIBLE_IOCTL(SG_SET_FORCE_LOW_DMA)
+COMPATIBLE_IOCTL(SG_GET_LOW_DMA)
+COMPATIBLE_IOCTL(SG_SET_FORCE_PACK_ID)
+COMPATIBLE_IOCTL(SG_GET_PACK_ID)
+COMPATIBLE_IOCTL(SG_GET_NUM_WAITING)
+COMPATIBLE_IOCTL(SG_SET_DEBUG)
+COMPATIBLE_IOCTL(SG_GET_SG_TABLESIZE)
+COMPATIBLE_IOCTL(SG_GET_COMMAND_Q)
+COMPATIBLE_IOCTL(SG_SET_COMMAND_Q)
+COMPATIBLE_IOCTL(SG_GET_VERSION_NUM)
+COMPATIBLE_IOCTL(SG_NEXT_CMD_LEN)
+COMPATIBLE_IOCTL(SG_SCSI_RESET)
+COMPATIBLE_IOCTL(SG_GET_REQUEST_TABLE)
+COMPATIBLE_IOCTL(SG_SET_KEEP_ORPHAN)
+COMPATIBLE_IOCTL(SG_GET_KEEP_ORPHAN)
+/* PPP stuff */
+COMPATIBLE_IOCTL(PPPIOCGFLAGS)
+COMPATIBLE_IOCTL(PPPIOCSFLAGS)
+COMPATIBLE_IOCTL(PPPIOCGASYNCMAP)
+COMPATIBLE_IOCTL(PPPIOCSASYNCMAP)
+COMPATIBLE_IOCTL(PPPIOCGUNIT)
+COMPATIBLE_IOCTL(PPPIOCGRASYNCMAP)
+COMPATIBLE_IOCTL(PPPIOCSRASYNCMAP)
+COMPATIBLE_IOCTL(PPPIOCGMRU)
+COMPATIBLE_IOCTL(PPPIOCSMRU)
+COMPATIBLE_IOCTL(PPPIOCSMAXCID)
+COMPATIBLE_IOCTL(PPPIOCGXASYNCMAP)
+COMPATIBLE_IOCTL(PPPIOCSXASYNCMAP)
+COMPATIBLE_IOCTL(PPPIOCXFERUNIT)
+/* PPPIOCSCOMPRESS is translated */
+COMPATIBLE_IOCTL(PPPIOCGNPMODE)
+COMPATIBLE_IOCTL(PPPIOCSNPMODE)
+COMPATIBLE_IOCTL(PPPIOCGDEBUG)
+COMPATIBLE_IOCTL(PPPIOCSDEBUG)
+/* PPPIOCSPASS is translated */
+/* PPPIOCSACTIVE is translated */
+/* PPPIOCGIDLE is translated */
+COMPATIBLE_IOCTL(PPPIOCNEWUNIT)
+COMPATIBLE_IOCTL(PPPIOCATTACH)
+COMPATIBLE_IOCTL(PPPIOCDETACH)
+COMPATIBLE_IOCTL(PPPIOCSMRRU)
+COMPATIBLE_IOCTL(PPPIOCCONNECT)
+COMPATIBLE_IOCTL(PPPIOCDISCONN)
+COMPATIBLE_IOCTL(PPPIOCATTCHAN)
+COMPATIBLE_IOCTL(PPPIOCGCHAN)
+/* PPPOX */
+COMPATIBLE_IOCTL(PPPOEIOCSFWD)
+COMPATIBLE_IOCTL(PPPOEIOCDFWD)
+/* LP */
+COMPATIBLE_IOCTL(LPGETSTATUS)
+/* ppdev */
+COMPATIBLE_IOCTL(PPSETMODE)
+COMPATIBLE_IOCTL(PPRSTATUS)
+COMPATIBLE_IOCTL(PPRCONTROL)
+COMPATIBLE_IOCTL(PPWCONTROL)
+COMPATIBLE_IOCTL(PPFCONTROL)
+COMPATIBLE_IOCTL(PPRDATA)
+COMPATIBLE_IOCTL(PPWDATA)
+COMPATIBLE_IOCTL(PPCLAIM)
+COMPATIBLE_IOCTL(PPRELEASE)
+COMPATIBLE_IOCTL(PPYIELD)
+COMPATIBLE_IOCTL(PPEXCL)
+COMPATIBLE_IOCTL(PPDATADIR)
+COMPATIBLE_IOCTL(PPNEGOT)
+COMPATIBLE_IOCTL(PPWCTLONIRQ)
+COMPATIBLE_IOCTL(PPCLRIRQ)
+COMPATIBLE_IOCTL(PPSETPHASE)
+COMPATIBLE_IOCTL(PPGETMODES)
+COMPATIBLE_IOCTL(PPGETMODE)
+COMPATIBLE_IOCTL(PPGETPHASE)
+COMPATIBLE_IOCTL(PPGETFLAGS)
+COMPATIBLE_IOCTL(PPSETFLAGS)
+/* CDROM stuff */
+COMPATIBLE_IOCTL(CDROMPAUSE)
+COMPATIBLE_IOCTL(CDROMRESUME)
+COMPATIBLE_IOCTL(CDROMPLAYMSF)
+COMPATIBLE_IOCTL(CDROMPLAYTRKIND)
+COMPATIBLE_IOCTL(CDROMREADTOCHDR)
+COMPATIBLE_IOCTL(CDROMREADTOCENTRY)
+COMPATIBLE_IOCTL(CDROMSTOP)
+COMPATIBLE_IOCTL(CDROMSTART)
+COMPATIBLE_IOCTL(CDROMEJECT)
+COMPATIBLE_IOCTL(CDROMVOLCTRL)
+COMPATIBLE_IOCTL(CDROMSUBCHNL)
+ULONG_IOCTL(CDROMEJECT_SW)
+COMPATIBLE_IOCTL(CDROMMULTISESSION)
+COMPATIBLE_IOCTL(CDROM_GET_MCN)
+COMPATIBLE_IOCTL(CDROMRESET)
+COMPATIBLE_IOCTL(CDROMVOLREAD)
+COMPATIBLE_IOCTL(CDROMSEEK)
+COMPATIBLE_IOCTL(CDROMPLAYBLK)
+COMPATIBLE_IOCTL(CDROMCLOSETRAY)
+ULONG_IOCTL(CDROM_SET_OPTIONS)
+ULONG_IOCTL(CDROM_CLEAR_OPTIONS)
+ULONG_IOCTL(CDROM_SELECT_SPEED)
+ULONG_IOCTL(CDROM_SELECT_DISC)
+ULONG_IOCTL(CDROM_MEDIA_CHANGED)
+ULONG_IOCTL(CDROM_DRIVE_STATUS)
+COMPATIBLE_IOCTL(CDROM_DISC_STATUS)
+COMPATIBLE_IOCTL(CDROM_CHANGER_NSLOTS)
+ULONG_IOCTL(CDROM_LOCKDOOR)
+ULONG_IOCTL(CDROM_DEBUG)
+COMPATIBLE_IOCTL(CDROM_GET_CAPABILITY)
+/* Ignore cdrom.h about these next 5 ioctls, they absolutely do
+ * not take a struct cdrom_read, instead they take a struct cdrom_msf
+ * which is compatible.
+ */
+COMPATIBLE_IOCTL(CDROMREADMODE2)
+COMPATIBLE_IOCTL(CDROMREADMODE1)
+COMPATIBLE_IOCTL(CDROMREADRAW)
+COMPATIBLE_IOCTL(CDROMREADCOOKED)
+COMPATIBLE_IOCTL(CDROMREADALL)
+/* DVD ioctls */
+COMPATIBLE_IOCTL(DVD_READ_STRUCT)
+COMPATIBLE_IOCTL(DVD_WRITE_STRUCT)
+COMPATIBLE_IOCTL(DVD_AUTH)
+/* pktcdvd */
+COMPATIBLE_IOCTL(PACKET_CTRL_CMD)
+/* Big A */
+/* sparc only */
+/* Big Q for sound/OSS */
+COMPATIBLE_IOCTL(SNDCTL_SEQ_RESET)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_SYNC)
+COMPATIBLE_IOCTL(SNDCTL_SYNTH_INFO)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_CTRLRATE)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_GETOUTCOUNT)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_GETINCOUNT)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_PERCMODE)
+COMPATIBLE_IOCTL(SNDCTL_FM_LOAD_INSTR)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_TESTMIDI)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_RESETSAMPLES)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_NRSYNTHS)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_NRMIDIS)
+COMPATIBLE_IOCTL(SNDCTL_MIDI_INFO)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_THRESHOLD)
+COMPATIBLE_IOCTL(SNDCTL_SYNTH_MEMAVL)
+COMPATIBLE_IOCTL(SNDCTL_FM_4OP_ENABLE)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_PANIC)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_OUTOFBAND)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_GETTIME)
+COMPATIBLE_IOCTL(SNDCTL_SYNTH_ID)
+COMPATIBLE_IOCTL(SNDCTL_SYNTH_CONTROL)
+COMPATIBLE_IOCTL(SNDCTL_SYNTH_REMOVESAMPLE)
+/* Big T for sound/OSS */
+COMPATIBLE_IOCTL(SNDCTL_TMR_TIMEBASE)
+COMPATIBLE_IOCTL(SNDCTL_TMR_START)
+COMPATIBLE_IOCTL(SNDCTL_TMR_STOP)
+COMPATIBLE_IOCTL(SNDCTL_TMR_CONTINUE)
+COMPATIBLE_IOCTL(SNDCTL_TMR_TEMPO)
+COMPATIBLE_IOCTL(SNDCTL_TMR_SOURCE)
+COMPATIBLE_IOCTL(SNDCTL_TMR_METRONOME)
+COMPATIBLE_IOCTL(SNDCTL_TMR_SELECT)
+/* Little m for sound/OSS */
+COMPATIBLE_IOCTL(SNDCTL_MIDI_PRETIME)
+COMPATIBLE_IOCTL(SNDCTL_MIDI_MPUMODE)
+COMPATIBLE_IOCTL(SNDCTL_MIDI_MPUCMD)
+/* Big P for sound/OSS */
+COMPATIBLE_IOCTL(SNDCTL_DSP_RESET)
+COMPATIBLE_IOCTL(SNDCTL_DSP_SYNC)
+COMPATIBLE_IOCTL(SNDCTL_DSP_SPEED)
+COMPATIBLE_IOCTL(SNDCTL_DSP_STEREO)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETBLKSIZE)
+COMPATIBLE_IOCTL(SNDCTL_DSP_CHANNELS)
+COMPATIBLE_IOCTL(SOUND_PCM_WRITE_FILTER)
+COMPATIBLE_IOCTL(SNDCTL_DSP_POST)
+COMPATIBLE_IOCTL(SNDCTL_DSP_SUBDIVIDE)
+COMPATIBLE_IOCTL(SNDCTL_DSP_SETFRAGMENT)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETFMTS)
+COMPATIBLE_IOCTL(SNDCTL_DSP_SETFMT)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETOSPACE)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETISPACE)
+COMPATIBLE_IOCTL(SNDCTL_DSP_NONBLOCK)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETCAPS)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETTRIGGER)
+COMPATIBLE_IOCTL(SNDCTL_DSP_SETTRIGGER)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETIPTR)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETOPTR)
+/* SNDCTL_DSP_MAPINBUF, XXX needs translation */
+/* SNDCTL_DSP_MAPOUTBUF, XXX needs translation */
+COMPATIBLE_IOCTL(SNDCTL_DSP_SETSYNCRO)
+COMPATIBLE_IOCTL(SNDCTL_DSP_SETDUPLEX)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETODELAY)
+COMPATIBLE_IOCTL(SNDCTL_DSP_PROFILE)
+COMPATIBLE_IOCTL(SOUND_PCM_READ_RATE)
+COMPATIBLE_IOCTL(SOUND_PCM_READ_CHANNELS)
+COMPATIBLE_IOCTL(SOUND_PCM_READ_BITS)
+COMPATIBLE_IOCTL(SOUND_PCM_READ_FILTER)
+/* Big C for sound/OSS */
+COMPATIBLE_IOCTL(SNDCTL_COPR_RESET)
+COMPATIBLE_IOCTL(SNDCTL_COPR_LOAD)
+COMPATIBLE_IOCTL(SNDCTL_COPR_RDATA)
+COMPATIBLE_IOCTL(SNDCTL_COPR_RCODE)
+COMPATIBLE_IOCTL(SNDCTL_COPR_WDATA)
+COMPATIBLE_IOCTL(SNDCTL_COPR_WCODE)
+COMPATIBLE_IOCTL(SNDCTL_COPR_RUN)
+COMPATIBLE_IOCTL(SNDCTL_COPR_HALT)
+COMPATIBLE_IOCTL(SNDCTL_COPR_SENDMSG)
+COMPATIBLE_IOCTL(SNDCTL_COPR_RCVMSG)
+/* Big M for sound/OSS */
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_VOLUME)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_BASS)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_TREBLE)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_SYNTH)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_PCM)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_SPEAKER)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_MIC)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_CD)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_IMIX)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_ALTPCM)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECLEV)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_IGAIN)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_OGAIN)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE1)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE2)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE3)
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL1))
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL2))
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL3))
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_PHONEIN))
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_PHONEOUT))
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_VIDEO))
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_RADIO))
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_MONITOR))
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_MUTE)
+/* SOUND_MIXER_READ_ENHANCE, same value as READ_MUTE */
+/* SOUND_MIXER_READ_LOUD, same value as READ_MUTE */
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECSRC)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_DEVMASK)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECMASK)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_STEREODEVS)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_CAPS)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_VOLUME)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_BASS)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_TREBLE)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_SYNTH)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_PCM)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_SPEAKER)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_MIC)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_CD)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_IMIX)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_ALTPCM)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_RECLEV)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_IGAIN)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_OGAIN)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE1)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE2)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE3)
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL1))
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL2))
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL3))
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_PHONEIN))
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_PHONEOUT))
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_VIDEO))
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_RADIO))
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_MONITOR))
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_MUTE)
+/* SOUND_MIXER_WRITE_ENHANCE, same value as WRITE_MUTE */
+/* SOUND_MIXER_WRITE_LOUD, same value as WRITE_MUTE */
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_RECSRC)
+COMPATIBLE_IOCTL(SOUND_MIXER_INFO)
+COMPATIBLE_IOCTL(SOUND_OLD_MIXER_INFO)
+COMPATIBLE_IOCTL(SOUND_MIXER_ACCESS)
+COMPATIBLE_IOCTL(SOUND_MIXER_AGC)
+COMPATIBLE_IOCTL(SOUND_MIXER_3DSE)
+COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE1)
+COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE2)
+COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE3)
+COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE4)
+COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE5)
+COMPATIBLE_IOCTL(SOUND_MIXER_GETLEVELS)
+COMPATIBLE_IOCTL(SOUND_MIXER_SETLEVELS)
+COMPATIBLE_IOCTL(OSS_GETVERSION)
+/* AUTOFS */
+ULONG_IOCTL(AUTOFS_IOC_READY)
+ULONG_IOCTL(AUTOFS_IOC_FAIL)
+COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC)
+COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER)
+COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE)
+COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE_MULTI)
+COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOSUBVER)
+COMPATIBLE_IOCTL(AUTOFS_IOC_ASKREGHOST)
+COMPATIBLE_IOCTL(AUTOFS_IOC_TOGGLEREGHOST)
+COMPATIBLE_IOCTL(AUTOFS_IOC_ASKUMOUNT)
+/* Raw devices */
+COMPATIBLE_IOCTL(RAW_SETBIND)
+COMPATIBLE_IOCTL(RAW_GETBIND)
+/* SMB ioctls which do not need any translations */
+COMPATIBLE_IOCTL(SMB_IOC_NEWCONN)
+/* Little a */
+COMPATIBLE_IOCTL(ATMSIGD_CTRL)
+COMPATIBLE_IOCTL(ATMARPD_CTRL)
+COMPATIBLE_IOCTL(ATMLEC_CTRL)
+COMPATIBLE_IOCTL(ATMLEC_MCAST)
+COMPATIBLE_IOCTL(ATMLEC_DATA)
+COMPATIBLE_IOCTL(ATM_SETSC)
+COMPATIBLE_IOCTL(SIOCSIFATMTCP)
+COMPATIBLE_IOCTL(SIOCMKCLIP)
+COMPATIBLE_IOCTL(ATMARP_MKIP)
+COMPATIBLE_IOCTL(ATMARP_SETENTRY)
+COMPATIBLE_IOCTL(ATMARP_ENCAP)
+COMPATIBLE_IOCTL(ATMTCP_CREATE)
+COMPATIBLE_IOCTL(ATMTCP_REMOVE)
+COMPATIBLE_IOCTL(ATMMPC_CTRL)
+COMPATIBLE_IOCTL(ATMMPC_DATA)
+/* Watchdog */
+COMPATIBLE_IOCTL(WDIOC_GETSUPPORT)
+COMPATIBLE_IOCTL(WDIOC_GETSTATUS)
+COMPATIBLE_IOCTL(WDIOC_GETBOOTSTATUS)
+COMPATIBLE_IOCTL(WDIOC_GETTEMP)
+COMPATIBLE_IOCTL(WDIOC_SETOPTIONS)
+COMPATIBLE_IOCTL(WDIOC_KEEPALIVE)
+COMPATIBLE_IOCTL(WDIOC_SETTIMEOUT)
+COMPATIBLE_IOCTL(WDIOC_GETTIMEOUT)
+/* Big R */
+COMPATIBLE_IOCTL(RNDGETENTCNT)
+COMPATIBLE_IOCTL(RNDADDTOENTCNT)
+COMPATIBLE_IOCTL(RNDGETPOOL)
+COMPATIBLE_IOCTL(RNDADDENTROPY)
+COMPATIBLE_IOCTL(RNDZAPENTCNT)
+COMPATIBLE_IOCTL(RNDCLEARPOOL)
+/* Bluetooth */
+COMPATIBLE_IOCTL(HCIDEVUP)
+COMPATIBLE_IOCTL(HCIDEVDOWN)
+COMPATIBLE_IOCTL(HCIDEVRESET)
+COMPATIBLE_IOCTL(HCIDEVRESTAT)
+COMPATIBLE_IOCTL(HCIGETDEVLIST)
+COMPATIBLE_IOCTL(HCIGETDEVINFO)
+COMPATIBLE_IOCTL(HCIGETCONNLIST)
+COMPATIBLE_IOCTL(HCIGETCONNINFO)
+COMPATIBLE_IOCTL(HCISETRAW)
+COMPATIBLE_IOCTL(HCISETSCAN)
+COMPATIBLE_IOCTL(HCISETAUTH)
+COMPATIBLE_IOCTL(HCISETENCRYPT)
+COMPATIBLE_IOCTL(HCISETPTYPE)
+COMPATIBLE_IOCTL(HCISETLINKPOL)
+COMPATIBLE_IOCTL(HCISETLINKMODE)
+COMPATIBLE_IOCTL(HCISETACLMTU)
+COMPATIBLE_IOCTL(HCISETSCOMTU)
+COMPATIBLE_IOCTL(HCIINQUIRY)
+COMPATIBLE_IOCTL(HCIUARTSETPROTO)
+COMPATIBLE_IOCTL(HCIUARTGETPROTO)
+COMPATIBLE_IOCTL(RFCOMMCREATEDEV)
+COMPATIBLE_IOCTL(RFCOMMRELEASEDEV)
+COMPATIBLE_IOCTL(RFCOMMGETDEVLIST)
+COMPATIBLE_IOCTL(RFCOMMGETDEVINFO)
+COMPATIBLE_IOCTL(RFCOMMSTEALDLC)
+COMPATIBLE_IOCTL(BNEPCONNADD)
+COMPATIBLE_IOCTL(BNEPCONNDEL)
+COMPATIBLE_IOCTL(BNEPGETCONNLIST)
+COMPATIBLE_IOCTL(BNEPGETCONNINFO)
+COMPATIBLE_IOCTL(CMTPCONNADD)
+COMPATIBLE_IOCTL(CMTPCONNDEL)
+COMPATIBLE_IOCTL(CMTPGETCONNLIST)
+COMPATIBLE_IOCTL(CMTPGETCONNINFO)
+COMPATIBLE_IOCTL(HIDPCONNADD)
+COMPATIBLE_IOCTL(HIDPCONNDEL)
+COMPATIBLE_IOCTL(HIDPGETCONNLIST)
+COMPATIBLE_IOCTL(HIDPGETCONNINFO)
+/* CAPI */
+COMPATIBLE_IOCTL(CAPI_REGISTER)
+COMPATIBLE_IOCTL(CAPI_GET_MANUFACTURER)
+COMPATIBLE_IOCTL(CAPI_GET_VERSION)
+COMPATIBLE_IOCTL(CAPI_GET_SERIAL)
+COMPATIBLE_IOCTL(CAPI_GET_PROFILE)
+COMPATIBLE_IOCTL(CAPI_MANUFACTURER_CMD)
+COMPATIBLE_IOCTL(CAPI_GET_ERRCODE)
+COMPATIBLE_IOCTL(CAPI_INSTALLED)
+COMPATIBLE_IOCTL(CAPI_GET_FLAGS)
+COMPATIBLE_IOCTL(CAPI_SET_FLAGS)
+COMPATIBLE_IOCTL(CAPI_CLR_FLAGS)
+COMPATIBLE_IOCTL(CAPI_NCCI_OPENCOUNT)
+COMPATIBLE_IOCTL(CAPI_NCCI_GETUNIT)
+/* Siemens Gigaset */
+COMPATIBLE_IOCTL(GIGASET_REDIR)
+COMPATIBLE_IOCTL(GIGASET_CONFIG)
+COMPATIBLE_IOCTL(GIGASET_BRKCHARS)
+COMPATIBLE_IOCTL(GIGASET_VERSION)
+/* Misc. */
+COMPATIBLE_IOCTL(0x41545900) /* ATYIO_CLKR */
+COMPATIBLE_IOCTL(0x41545901) /* ATYIO_CLKW */
+COMPATIBLE_IOCTL(PCIIOC_CONTROLLER)
+COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_IO)
+COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_MEM)
+COMPATIBLE_IOCTL(PCIIOC_WRITE_COMBINE)
+/* USB */
+COMPATIBLE_IOCTL(USBDEVFS_RESETEP)
+COMPATIBLE_IOCTL(USBDEVFS_SETINTERFACE)
+COMPATIBLE_IOCTL(USBDEVFS_SETCONFIGURATION)
+COMPATIBLE_IOCTL(USBDEVFS_GETDRIVER)
+COMPATIBLE_IOCTL(USBDEVFS_DISCARDURB)
+COMPATIBLE_IOCTL(USBDEVFS_CLAIMINTERFACE)
+COMPATIBLE_IOCTL(USBDEVFS_RELEASEINTERFACE)
+COMPATIBLE_IOCTL(USBDEVFS_CONNECTINFO)
+COMPATIBLE_IOCTL(USBDEVFS_HUB_PORTINFO)
+COMPATIBLE_IOCTL(USBDEVFS_RESET)
+COMPATIBLE_IOCTL(USBDEVFS_SUBMITURB32)
+COMPATIBLE_IOCTL(USBDEVFS_REAPURB32)
+COMPATIBLE_IOCTL(USBDEVFS_REAPURBNDELAY32)
+COMPATIBLE_IOCTL(USBDEVFS_CLEAR_HALT)
+/* MTD */
+COMPATIBLE_IOCTL(MEMGETINFO)
+COMPATIBLE_IOCTL(MEMERASE)
+COMPATIBLE_IOCTL(MEMLOCK)
+COMPATIBLE_IOCTL(MEMUNLOCK)
+COMPATIBLE_IOCTL(MEMGETREGIONCOUNT)
+COMPATIBLE_IOCTL(MEMGETREGIONINFO)
+COMPATIBLE_IOCTL(MEMGETBADBLOCK)
+COMPATIBLE_IOCTL(MEMSETBADBLOCK)
+/* NBD */
+ULONG_IOCTL(NBD_SET_SOCK)
+ULONG_IOCTL(NBD_SET_BLKSIZE)
+ULONG_IOCTL(NBD_SET_SIZE)
+COMPATIBLE_IOCTL(NBD_DO_IT)
+COMPATIBLE_IOCTL(NBD_CLEAR_SOCK)
+COMPATIBLE_IOCTL(NBD_CLEAR_QUE)
+COMPATIBLE_IOCTL(NBD_PRINT_DEBUG)
+ULONG_IOCTL(NBD_SET_SIZE_BLOCKS)
+COMPATIBLE_IOCTL(NBD_DISCONNECT)
+/* i2c */
+COMPATIBLE_IOCTL(I2C_SLAVE)
+COMPATIBLE_IOCTL(I2C_SLAVE_FORCE)
+COMPATIBLE_IOCTL(I2C_TENBIT)
+COMPATIBLE_IOCTL(I2C_PEC)
+COMPATIBLE_IOCTL(I2C_RETRIES)
+COMPATIBLE_IOCTL(I2C_TIMEOUT)
+/* wireless */
+COMPATIBLE_IOCTL(SIOCSIWCOMMIT)
+COMPATIBLE_IOCTL(SIOCGIWNAME)
+COMPATIBLE_IOCTL(SIOCSIWNWID)
+COMPATIBLE_IOCTL(SIOCGIWNWID)
+COMPATIBLE_IOCTL(SIOCSIWFREQ)
+COMPATIBLE_IOCTL(SIOCGIWFREQ)
+COMPATIBLE_IOCTL(SIOCSIWMODE)
+COMPATIBLE_IOCTL(SIOCGIWMODE)
+COMPATIBLE_IOCTL(SIOCSIWSENS)
+COMPATIBLE_IOCTL(SIOCGIWSENS)
+COMPATIBLE_IOCTL(SIOCSIWRANGE)
+COMPATIBLE_IOCTL(SIOCSIWPRIV)
+COMPATIBLE_IOCTL(SIOCGIWPRIV)
+COMPATIBLE_IOCTL(SIOCSIWSTATS)
+COMPATIBLE_IOCTL(SIOCGIWSTATS)
+COMPATIBLE_IOCTL(SIOCSIWAP)
+COMPATIBLE_IOCTL(SIOCGIWAP)
+COMPATIBLE_IOCTL(SIOCSIWSCAN)
+COMPATIBLE_IOCTL(SIOCSIWRATE)
+COMPATIBLE_IOCTL(SIOCGIWRATE)
+COMPATIBLE_IOCTL(SIOCSIWRTS)
+COMPATIBLE_IOCTL(SIOCGIWRTS)
+COMPATIBLE_IOCTL(SIOCSIWFRAG)
+COMPATIBLE_IOCTL(SIOCGIWFRAG)
+COMPATIBLE_IOCTL(SIOCSIWTXPOW)
+COMPATIBLE_IOCTL(SIOCGIWTXPOW)
+COMPATIBLE_IOCTL(SIOCSIWRETRY)
+COMPATIBLE_IOCTL(SIOCGIWRETRY)
+COMPATIBLE_IOCTL(SIOCSIWPOWER)
+COMPATIBLE_IOCTL(SIOCGIWPOWER)
+/* hiddev */
+COMPATIBLE_IOCTL(HIDIOCGVERSION)
+COMPATIBLE_IOCTL(HIDIOCAPPLICATION)
+COMPATIBLE_IOCTL(HIDIOCGDEVINFO)
+COMPATIBLE_IOCTL(HIDIOCGSTRING)
+COMPATIBLE_IOCTL(HIDIOCINITREPORT)
+COMPATIBLE_IOCTL(HIDIOCGREPORT)
+COMPATIBLE_IOCTL(HIDIOCSREPORT)
+COMPATIBLE_IOCTL(HIDIOCGREPORTINFO)
+COMPATIBLE_IOCTL(HIDIOCGFIELDINFO)
+COMPATIBLE_IOCTL(HIDIOCGUSAGE)
+COMPATIBLE_IOCTL(HIDIOCSUSAGE)
+COMPATIBLE_IOCTL(HIDIOCGUCODE)
+COMPATIBLE_IOCTL(HIDIOCGFLAG)
+COMPATIBLE_IOCTL(HIDIOCSFLAG)
+COMPATIBLE_IOCTL(HIDIOCGCOLLECTIONINDEX)
+COMPATIBLE_IOCTL(HIDIOCGCOLLECTIONINFO)
+/* dvb */
+COMPATIBLE_IOCTL(AUDIO_STOP)
+COMPATIBLE_IOCTL(AUDIO_PLAY)
+COMPATIBLE_IOCTL(AUDIO_PAUSE)
+COMPATIBLE_IOCTL(AUDIO_CONTINUE)
+COMPATIBLE_IOCTL(AUDIO_SELECT_SOURCE)
+COMPATIBLE_IOCTL(AUDIO_SET_MUTE)
+COMPATIBLE_IOCTL(AUDIO_SET_AV_SYNC)
+COMPATIBLE_IOCTL(AUDIO_SET_BYPASS_MODE)
+COMPATIBLE_IOCTL(AUDIO_CHANNEL_SELECT)
+COMPATIBLE_IOCTL(AUDIO_GET_STATUS)
+COMPATIBLE_IOCTL(AUDIO_GET_CAPABILITIES)
+COMPATIBLE_IOCTL(AUDIO_CLEAR_BUFFER)
+COMPATIBLE_IOCTL(AUDIO_SET_ID)
+COMPATIBLE_IOCTL(AUDIO_SET_MIXER)
+COMPATIBLE_IOCTL(AUDIO_SET_STREAMTYPE)
+COMPATIBLE_IOCTL(AUDIO_SET_EXT_ID)
+COMPATIBLE_IOCTL(AUDIO_SET_ATTRIBUTES)
+COMPATIBLE_IOCTL(AUDIO_SET_KARAOKE)
+COMPATIBLE_IOCTL(DMX_START)
+COMPATIBLE_IOCTL(DMX_STOP)
+COMPATIBLE_IOCTL(DMX_SET_FILTER)
+COMPATIBLE_IOCTL(DMX_SET_PES_FILTER)
+COMPATIBLE_IOCTL(DMX_SET_BUFFER_SIZE)
+COMPATIBLE_IOCTL(DMX_GET_PES_PIDS)
+COMPATIBLE_IOCTL(DMX_GET_CAPS)
+COMPATIBLE_IOCTL(DMX_SET_SOURCE)
+COMPATIBLE_IOCTL(DMX_GET_STC)
+COMPATIBLE_IOCTL(FE_GET_INFO)
+COMPATIBLE_IOCTL(FE_DISEQC_RESET_OVERLOAD)
+COMPATIBLE_IOCTL(FE_DISEQC_SEND_MASTER_CMD)
+COMPATIBLE_IOCTL(FE_DISEQC_RECV_SLAVE_REPLY)
+COMPATIBLE_IOCTL(FE_DISEQC_SEND_BURST)
+COMPATIBLE_IOCTL(FE_SET_TONE)
+COMPATIBLE_IOCTL(FE_SET_VOLTAGE)
+COMPATIBLE_IOCTL(FE_ENABLE_HIGH_LNB_VOLTAGE)
+COMPATIBLE_IOCTL(FE_READ_STATUS)
+COMPATIBLE_IOCTL(FE_READ_BER)
+COMPATIBLE_IOCTL(FE_READ_SIGNAL_STRENGTH)
+COMPATIBLE_IOCTL(FE_READ_SNR)
+COMPATIBLE_IOCTL(FE_READ_UNCORRECTED_BLOCKS)
+COMPATIBLE_IOCTL(FE_SET_FRONTEND)
+COMPATIBLE_IOCTL(FE_GET_FRONTEND)
+COMPATIBLE_IOCTL(FE_GET_EVENT)
+COMPATIBLE_IOCTL(FE_DISHNETWORK_SEND_LEGACY_CMD)
+COMPATIBLE_IOCTL(VIDEO_STOP)
+COMPATIBLE_IOCTL(VIDEO_PLAY)
+COMPATIBLE_IOCTL(VIDEO_FREEZE)
+COMPATIBLE_IOCTL(VIDEO_CONTINUE)
+COMPATIBLE_IOCTL(VIDEO_SELECT_SOURCE)
+COMPATIBLE_IOCTL(VIDEO_SET_BLANK)
+COMPATIBLE_IOCTL(VIDEO_GET_STATUS)
+COMPATIBLE_IOCTL(VIDEO_SET_DISPLAY_FORMAT)
+COMPATIBLE_IOCTL(VIDEO_FAST_FORWARD)
+COMPATIBLE_IOCTL(VIDEO_SLOWMOTION)
+COMPATIBLE_IOCTL(VIDEO_GET_CAPABILITIES)
+COMPATIBLE_IOCTL(VIDEO_CLEAR_BUFFER)
+COMPATIBLE_IOCTL(VIDEO_SET_ID)
+COMPATIBLE_IOCTL(VIDEO_SET_STREAMTYPE)
+COMPATIBLE_IOCTL(VIDEO_SET_FORMAT)
+COMPATIBLE_IOCTL(VIDEO_SET_SYSTEM)
+COMPATIBLE_IOCTL(VIDEO_SET_HIGHLIGHT)
+COMPATIBLE_IOCTL(VIDEO_SET_SPU)
+COMPATIBLE_IOCTL(VIDEO_GET_NAVI)
+COMPATIBLE_IOCTL(VIDEO_SET_ATTRIBUTES)
+COMPATIBLE_IOCTL(VIDEO_GET_SIZE)
+COMPATIBLE_IOCTL(VIDEO_GET_FRAME_RATE)
+
+/* now things that need handlers */
HANDLE_IOCTL(MEMREADOOB32, mtd_rw_oob)
HANDLE_IOCTL(MEMWRITEOOB32, mtd_rw_oob)
#ifdef CONFIG_NET
@@ -2638,4 +3474,156 @@
IGNORE_IOCTL(VFAT_IOCTL_READDIR_SHORT32)
};
-int ioctl_table_size = ARRAY_SIZE(ioctl_start);
+#define IOCTL_HASHSIZE 256
+static struct ioctl_trans *ioctl32_hash_table[IOCTL_HASHSIZE];
+
+static inline unsigned long ioctl32_hash(unsigned long cmd)
+{
+ return (((cmd >> 6) ^ (cmd >> 4) ^ cmd)) % IOCTL_HASHSIZE;
+}
+
+static void compat_ioctl_error(struct file *filp, unsigned int fd,
+ unsigned int cmd, unsigned long arg)
+{
+ char buf[10];
+ char *fn = "?";
+ char *path;
+
+ /* find the name of the device. */
+ path = (char *)__get_free_page(GFP_KERNEL);
+ if (path) {
+ fn = d_path(filp->f_path.dentry, filp->f_path.mnt, path, PAGE_SIZE);
+ if (IS_ERR(fn))
+ fn = "?";
+ }
+
+ sprintf(buf,"'%c'", (cmd>>_IOC_TYPESHIFT) & _IOC_TYPEMASK);
+ if (!isprint(buf[1]))
+ sprintf(buf, "%02x", buf[1]);
+ compat_printk("ioctl32(%s:%d): Unknown cmd fd(%d) "
+ "cmd(%08x){t:%s;sz:%u} arg(%08x) on %s\n",
+ current->comm, current->pid,
+ (int)fd, (unsigned int)cmd, buf,
+ (cmd >> _IOC_SIZESHIFT) & _IOC_SIZEMASK,
+ (unsigned int)arg, fn);
+
+ if (path)
+ free_page((unsigned long)path);
+}
+
+asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
+ unsigned long arg)
+{
+ struct file *filp;
+ int error = -EBADF;
+ struct ioctl_trans *t;
+ int fput_needed;
+
+ filp = fget_light(fd, &fput_needed);
+ if (!filp)
+ goto out;
+
+ /* RED-PEN how should LSM module know it's handling 32bit? */
+ error = security_file_ioctl(filp, cmd, arg);
+ if (error)
+ goto out_fput;
+
+ /*
+ * To allow the compat_ioctl handlers to be self contained
+ * we need to check the common ioctls here first.
+ * Just handle them with the standard handlers below.
+ */
+ switch (cmd) {
+ case FIOCLEX:
+ case FIONCLEX:
+ case FIONBIO:
+ case FIOASYNC:
+ case FIOQSIZE:
+ break;
+
+ case FIBMAP:
+ case FIGETBSZ:
+ case FIONREAD:
+ if (S_ISREG(filp->f_path.dentry->d_inode->i_mode))
+ break;
+ /*FALL THROUGH*/
+
+ default:
+ if (filp->f_op && filp->f_op->compat_ioctl) {
+ error = filp->f_op->compat_ioctl(filp, cmd, arg);
+ if (error != -ENOIOCTLCMD)
+ goto out_fput;
+ }
+
+ if (!filp->f_op ||
+ (!filp->f_op->ioctl && !filp->f_op->unlocked_ioctl))
+ goto do_ioctl;
+ break;
+ }
+
+ for (t = ioctl32_hash_table[ioctl32_hash(cmd)]; t; t = t->next) {
+ if (t->cmd == cmd)
+ goto found_handler;
+ }
+
+ if (S_ISSOCK(filp->f_path.dentry->d_inode->i_mode) &&
+ cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
+ error = siocdevprivate_ioctl(fd, cmd, arg);
+ } else {
+ static int count;
+
+ if (++count <= 50)
+ compat_ioctl_error(filp, fd, cmd, arg);
+ error = -EINVAL;
+ }
+
+ goto out_fput;
+
+ found_handler:
+ if (t->handler) {
+ lock_kernel();
+ error = t->handler(fd, cmd, arg, filp);
+ unlock_kernel();
+ goto out_fput;
+ }
+
+ do_ioctl:
+ error = vfs_ioctl(filp, fd, cmd, arg);
+ out_fput:
+ fput_light(filp, fput_needed);
+ out:
+ return error;
+}
+
+static void ioctl32_insert_translation(struct ioctl_trans *trans)
+{
+ unsigned long hash;
+ struct ioctl_trans *t;
+
+ hash = ioctl32_hash (trans->cmd);
+ if (!ioctl32_hash_table[hash])
+ ioctl32_hash_table[hash] = trans;
+ else {
+ t = ioctl32_hash_table[hash];
+ while (t->next)
+ t = t->next;
+ trans->next = NULL;
+ t->next = trans;
+ }
+}
+
+static int __init init_sys32_ioctl(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ioctl_start); i++) {
+ if (ioctl_start[i].next != 0) {
+ printk("ioctl translation %d bad\n",i);
+ return -1;
+ }
+
+ ioctl32_insert_translation(&ioctl_start[i]);
+ }
+ return 0;
+}
+__initcall(init_sys32_ioctl);
diff --git a/fs/dcache.c b/fs/dcache.c
index d1bf5d8..0e73aa0 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -21,7 +21,6 @@
#include <linux/fsnotify.h>
#include <linux/slab.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/hash.h>
#include <linux/cache.h>
#include <linux/module.h>
@@ -121,6 +120,28 @@
}
}
+/**
+ * d_kill - kill dentry and return parent
+ * @dentry: dentry to kill
+ *
+ * Called with dcache_lock and d_lock, releases both. The dentry must
+ * already be unhashed and removed from the LRU.
+ *
+ * If this is the root of the dentry tree, return NULL.
+ */
+static struct dentry *d_kill(struct dentry *dentry)
+{
+ struct dentry *parent;
+
+ list_del(&dentry->d_u.d_child);
+ dentry_stat.nr_dentry--; /* For d_free, below */
+ /*drops the locks, at that point nobody can reach this dentry */
+ dentry_iput(dentry);
+ parent = dentry->d_parent;
+ d_free(dentry);
+ return dentry == parent ? NULL : parent;
+}
+
/*
* This is dput
*
@@ -189,28 +210,17 @@
unhash_it:
__d_drop(dentry);
-
-kill_it: {
- struct dentry *parent;
-
- /* If dentry was on d_lru list
- * delete it from there
- */
- if (!list_empty(&dentry->d_lru)) {
- list_del(&dentry->d_lru);
- dentry_stat.nr_unused--;
- }
- list_del(&dentry->d_u.d_child);
- dentry_stat.nr_dentry--; /* For d_free, below */
- /*drops the locks, at that point nobody can reach this dentry */
- dentry_iput(dentry);
- parent = dentry->d_parent;
- d_free(dentry);
- if (dentry == parent)
- return;
- dentry = parent;
- goto repeat;
+kill_it:
+ /* If dentry was on d_lru list
+ * delete it from there
+ */
+ if (!list_empty(&dentry->d_lru)) {
+ list_del(&dentry->d_lru);
+ dentry_stat.nr_unused--;
}
+ dentry = d_kill(dentry);
+ if (dentry)
+ goto repeat;
}
/**
@@ -371,22 +381,40 @@
* Throw away a dentry - free the inode, dput the parent. This requires that
* the LRU list has already been removed.
*
+ * If prune_parents is true, try to prune ancestors as well.
+ *
* Called with dcache_lock, drops it and then regains.
* Called with dentry->d_lock held, drops it.
*/
-static void prune_one_dentry(struct dentry * dentry)
+static void prune_one_dentry(struct dentry * dentry, int prune_parents)
{
- struct dentry * parent;
-
__d_drop(dentry);
- list_del(&dentry->d_u.d_child);
- dentry_stat.nr_dentry--; /* For d_free, below */
- dentry_iput(dentry);
- parent = dentry->d_parent;
- d_free(dentry);
- if (parent != dentry)
- dput(parent);
+ dentry = d_kill(dentry);
+ if (!prune_parents) {
+ dput(dentry);
+ spin_lock(&dcache_lock);
+ return;
+ }
+
+ /*
+ * Prune ancestors. Locking is simpler than in dput(),
+ * because dcache_lock needs to be taken anyway.
+ */
spin_lock(&dcache_lock);
+ while (dentry) {
+ if (!atomic_dec_and_lock(&dentry->d_count, &dentry->d_lock))
+ return;
+
+ if (dentry->d_op && dentry->d_op->d_delete)
+ dentry->d_op->d_delete(dentry);
+ if (!list_empty(&dentry->d_lru)) {
+ list_del(&dentry->d_lru);
+ dentry_stat.nr_unused--;
+ }
+ __d_drop(dentry);
+ dentry = d_kill(dentry);
+ spin_lock(&dcache_lock);
+ }
}
/**
@@ -394,6 +422,7 @@
* @count: number of entries to try and free
* @sb: if given, ignore dentries for other superblocks
* which are being unmounted.
+ * @prune_parents: if true, try to prune ancestors as well in one go
*
* Shrink the dcache. This is done when we need
* more memory, or simply when we need to unmount
@@ -404,7 +433,7 @@
* all the dentries are in use.
*/
-static void prune_dcache(int count, struct super_block *sb)
+static void prune_dcache(int count, struct super_block *sb, int prune_parents)
{
spin_lock(&dcache_lock);
for (; count ; count--) {
@@ -464,7 +493,7 @@
* without taking the s_umount lock (I already hold it).
*/
if (sb && dentry->d_sb == sb) {
- prune_one_dentry(dentry);
+ prune_one_dentry(dentry, prune_parents);
continue;
}
/*
@@ -479,7 +508,7 @@
s_umount = &dentry->d_sb->s_umount;
if (down_read_trylock(s_umount)) {
if (dentry->d_sb->s_root != NULL) {
- prune_one_dentry(dentry);
+ prune_one_dentry(dentry, prune_parents);
up_read(s_umount);
continue;
}
@@ -550,7 +579,7 @@
spin_unlock(&dentry->d_lock);
continue;
}
- prune_one_dentry(dentry);
+ prune_one_dentry(dentry, 1);
cond_resched_lock(&dcache_lock);
goto repeat;
}
@@ -829,7 +858,7 @@
int found;
while ((found = select_parent(parent)) != 0)
- prune_dcache(found, parent->d_sb);
+ prune_dcache(found, parent->d_sb, 1);
}
/*
@@ -849,7 +878,7 @@
if (nr) {
if (!(gfp_mask & __GFP_FS))
return -1;
- prune_dcache(nr, NULL);
+ prune_dcache(nr, NULL, 1);
}
return (dentry_stat.nr_unused / 100) * sysctl_vfs_cache_pressure;
}
@@ -1823,6 +1852,16 @@
struct vfsmount *rootmnt;
struct dentry *root;
+ /*
+ * We have various synthetic filesystems that never get mounted. On
+ * these filesystems dentries are never used for lookup purposes, and
+ * thus don't need to be hashed. They also don't need a name until a
+ * user wants to identify the object in /proc/pid/fd/. The little hack
+ * below allows us to generate a name for these objects on demand:
+ */
+ if (dentry->d_op && dentry->d_op->d_dname)
+ return dentry->d_op->d_dname(dentry, buf, buflen);
+
read_lock(¤t->fs->lock);
rootmnt = mntget(current->fs->rootmnt);
root = dget(current->fs->root);
@@ -1836,6 +1875,27 @@
}
/*
+ * Helper function for dentry_operations.d_dname() members
+ */
+char *dynamic_dname(struct dentry *dentry, char *buffer, int buflen,
+ const char *fmt, ...)
+{
+ va_list args;
+ char temp[64];
+ int sz;
+
+ va_start(args, fmt);
+ sz = vsnprintf(temp, sizeof(temp), fmt, args) + 1;
+ va_end(args);
+
+ if (sz > sizeof(temp) || sz > buflen)
+ return ERR_PTR(-ENAMETOOLONG);
+
+ buffer += buflen - sz;
+ return memcpy(buffer, temp, sz);
+}
+
+/*
* NOTE! The user-level library version returns a
* character pointer. The kernel system call just
* returns the length of the buffer filled (which
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
index 643e57b..06ef9a2 100644
--- a/fs/devpts/inode.c
+++ b/fs/devpts/inode.c
@@ -19,6 +19,7 @@
#include <linux/tty.h>
#include <linux/devpts_fs.h>
#include <linux/parser.h>
+#include <linux/fsnotify.h>
#define DEVPTS_SUPER_MAGIC 0x1cd1
@@ -178,8 +179,10 @@
inode->i_private = tty;
dentry = get_node(number);
- if (!IS_ERR(dentry) && !dentry->d_inode)
+ if (!IS_ERR(dentry) && !dentry->d_inode) {
d_instantiate(dentry, inode);
+ fsnotify_create(devpts_root->d_inode, dentry);
+ }
mutex_unlock(&devpts_root->d_inode->i_mutex);
diff --git a/fs/dquot.c b/fs/dquot.c
index 0a5febc..3a99584 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -69,7 +69,6 @@
#include <linux/file.h>
#include <linux/slab.h>
#include <linux/sysctl.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
@@ -475,7 +474,7 @@
spin_lock(&dq_list_lock);
dirty = &dqopt->info[cnt].dqi_dirty_list;
while (!list_empty(dirty)) {
- dquot = list_entry(dirty->next, struct dquot, dq_dirty);
+ dquot = list_first_entry(dirty, struct dquot, dq_dirty);
/* Dirty and inactive can be only bad dquot... */
if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {
clear_dquot_dirty(dquot);
@@ -721,7 +720,8 @@
/* Remove references to dquots from inode - add dquot to list for freeing if needed */
/* We can't race with anybody because we hold dqptr_sem for writing... */
-int remove_inode_dquot_ref(struct inode *inode, int type, struct list_head *tofree_head)
+static int remove_inode_dquot_ref(struct inode *inode, int type,
+ struct list_head *tofree_head)
{
struct dquot *dquot = inode->i_dquot[type];
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
index 7a7d25d..9881b5c 100644
--- a/fs/ecryptfs/file.c
+++ b/fs/ecryptfs/file.c
@@ -28,7 +28,6 @@
#include <linux/mount.h>
#include <linux/pagemap.h>
#include <linux/security.h>
-#include <linux/smp_lock.h>
#include <linux/compat.h>
#include <linux/fs_stack.h>
#include "ecryptfs_kernel.h"
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 3ae644e..b5c7ca5 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -22,7 +22,6 @@
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/poll.h>
-#include <linux/smp_lock.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/hash.h>
@@ -185,7 +184,7 @@
/*
* Each file descriptor added to the eventpoll interface will
- * have an entry of this type linked to the hash.
+ * have an entry of this type linked to the "rbr" RB tree.
*/
struct epitem {
/* RB-Tree node used to link this structure to the eventpoll rb-tree */
@@ -217,15 +216,6 @@
/* List header used to link this item to the "struct file" items list */
struct list_head fllink;
-
- /* List header used to link the item to the transfer list */
- struct list_head txlink;
-
- /*
- * This is used during the collection/transfer of events to userspace
- * to pin items empty events set.
- */
- unsigned int revents;
};
/* Wrapper struct used by poll queueing */
@@ -258,11 +248,8 @@
static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync, void *key);
static int ep_eventpoll_close(struct inode *inode, struct file *file);
static unsigned int ep_eventpoll_poll(struct file *file, poll_table *wait);
-static int ep_collect_ready_items(struct eventpoll *ep,
- struct list_head *txlist, int maxevents);
static int ep_send_events(struct eventpoll *ep, struct list_head *txlist,
- struct epoll_event __user *events);
-static void ep_reinject_items(struct eventpoll *ep, struct list_head *txlist);
+ struct epoll_event __user *events, int maxevents);
static int ep_events_transfer(struct eventpoll *ep,
struct epoll_event __user *events,
int maxevents);
@@ -355,17 +342,6 @@
return rb_parent(n) != n;
}
-/*
- * Remove the item from the list and perform its initialization.
- * This is useful for us because we can test if the item is linked
- * using "ep_is_linked(p)".
- */
-static inline void ep_list_del(struct list_head *p)
-{
- list_del(p);
- INIT_LIST_HEAD(p);
-}
-
/* Tells us if the item is currently linked */
static inline int ep_is_linked(struct list_head *p)
{
@@ -385,7 +361,7 @@
}
/* Tells if the epoll_ctl(2) operation needs an event copy from userspace */
-static inline int ep_op_hash_event(int op)
+static inline int ep_op_has_event(int op)
{
return op != EPOLL_CTL_DEL;
}
@@ -477,10 +453,10 @@
mutex_lock(&epmutex);
while (!list_empty(lsthead)) {
- epi = list_entry(lsthead->next, struct epitem, fllink);
+ epi = list_first_entry(lsthead, struct epitem, fllink);
ep = epi->ep;
- ep_list_del(&epi->fllink);
+ list_del_init(&epi->fllink);
down_write(&ep->sem);
ep_remove(ep, epi);
up_write(&ep->sem);
@@ -557,7 +533,7 @@
current, epfd, op, fd, event));
error = -EFAULT;
- if (ep_op_hash_event(op) &&
+ if (ep_op_has_event(op) &&
copy_from_user(&epds, event, sizeof(struct epoll_event)))
goto eexit_1;
@@ -594,7 +570,7 @@
down_write(&ep->sem);
- /* Try to lookup the file inside our hash table */
+ /* Try to lookup the file inside our RB tree */
epi = ep_find(ep, tfile, fd);
error = -EINVAL;
@@ -876,7 +852,7 @@
}
/*
- * Walks through the whole hash by freeing each "struct epitem". At this
+ * Walks through the whole tree by freeing each "struct epitem". At this
* point we are sure no poll callbacks will be lingering around, and also by
* write-holding "sem" we can be sure that no file cleanup code will hit
* us during this operation. So we can avoid the lock on "ep->lock".
@@ -891,7 +867,7 @@
/*
- * Search the file inside the eventpoll hash. It add usage count to
+ * Search the file inside the eventpoll tree. It add usage count to
* the returned item, so the caller must call ep_release_epitem()
* after finished using the "struct epitem".
*/
@@ -1011,7 +987,6 @@
ep_rb_initnode(&epi->rbn);
INIT_LIST_HEAD(&epi->rdllink);
INIT_LIST_HEAD(&epi->fllink);
- INIT_LIST_HEAD(&epi->txlink);
INIT_LIST_HEAD(&epi->pwqlist);
epi->ep = ep;
ep_set_ffd(&epi->ffd, tfile, fd);
@@ -1080,7 +1055,7 @@
*/
write_lock_irqsave(&ep->lock, flags);
if (ep_is_linked(&epi->rdllink))
- ep_list_del(&epi->rdllink);
+ list_del_init(&epi->rdllink);
write_unlock_irqrestore(&ep->lock, flags);
kmem_cache_free(epi_cache, epi);
@@ -1119,7 +1094,7 @@
epi->event.data = event->data;
/*
- * If the item is not linked to the hash it means that it's on its
+ * If the item is not linked to the RB tree it means that it's on its
* way toward the removal. Do nothing in this case.
*/
if (ep_rb_linked(&epi->rbn)) {
@@ -1168,9 +1143,9 @@
if (nwait) {
while (!list_empty(lsthead)) {
- pwq = list_entry(lsthead->next, struct eppoll_entry, llink);
+ pwq = list_first_entry(lsthead, struct eppoll_entry, llink);
- ep_list_del(&pwq->llink);
+ list_del_init(&pwq->llink);
remove_wait_queue(pwq->whead, &pwq->wait);
kmem_cache_free(pwq_cache, pwq);
}
@@ -1213,7 +1188,7 @@
* we want to remove it from this list to avoid stale events.
*/
if (ep_is_linked(&epi->rdllink))
- ep_list_del(&epi->rdllink);
+ list_del_init(&epi->rdllink);
error = 0;
eexit_1:
@@ -1226,7 +1201,7 @@
/*
- * Removes a "struct epitem" from the eventpoll hash and deallocates
+ * Removes a "struct epitem" from the eventpoll RB tree and deallocates
* all the associated resources.
*/
static int ep_remove(struct eventpoll *ep, struct epitem *epi)
@@ -1248,13 +1223,13 @@
/* Remove the current item from the list of epoll hooks */
spin_lock(&file->f_ep_lock);
if (ep_is_linked(&epi->fllink))
- ep_list_del(&epi->fllink);
+ list_del_init(&epi->fllink);
spin_unlock(&file->f_ep_lock);
/* We need to acquire the write IRQ lock before calling ep_unlink() */
write_lock_irqsave(&ep->lock, flags);
- /* Really unlink the item from the hash */
+ /* Really unlink the item from the RB tree */
error = ep_unlink(ep, epi);
write_unlock_irqrestore(&ep->lock, flags);
@@ -1362,71 +1337,30 @@
/*
- * Since we have to release the lock during the __copy_to_user() operation and
- * during the f_op->poll() call, we try to collect the maximum number of items
- * by reducing the irqlock/irqunlock switching rate.
- */
-static int ep_collect_ready_items(struct eventpoll *ep, struct list_head *txlist, int maxevents)
-{
- int nepi;
- unsigned long flags;
- struct list_head *lsthead = &ep->rdllist, *lnk;
- struct epitem *epi;
-
- write_lock_irqsave(&ep->lock, flags);
-
- for (nepi = 0, lnk = lsthead->next; lnk != lsthead && nepi < maxevents;) {
- epi = list_entry(lnk, struct epitem, rdllink);
-
- lnk = lnk->next;
-
- /* If this file is already in the ready list we exit soon */
- if (!ep_is_linked(&epi->txlink)) {
- /*
- * This is initialized in this way so that the default
- * behaviour of the reinjecting code will be to push back
- * the item inside the ready list.
- */
- epi->revents = epi->event.events;
-
- /* Link the ready item into the transfer list */
- list_add(&epi->txlink, txlist);
- nepi++;
-
- /*
- * Unlink the item from the ready list.
- */
- ep_list_del(&epi->rdllink);
- }
- }
-
- write_unlock_irqrestore(&ep->lock, flags);
-
- return nepi;
-}
-
-
-/*
* This function is called without holding the "ep->lock" since the call to
* __copy_to_user() might sleep, and also f_op->poll() might reenable the IRQ
* because of the way poll() is traditionally implemented in Linux.
*/
static int ep_send_events(struct eventpoll *ep, struct list_head *txlist,
- struct epoll_event __user *events)
+ struct epoll_event __user *events, int maxevents)
{
- int eventcnt = 0;
+ int eventcnt, error = -EFAULT, pwake = 0;
unsigned int revents;
- struct list_head *lnk;
+ unsigned long flags;
struct epitem *epi;
+ struct list_head injlist;
+
+ INIT_LIST_HEAD(&injlist);
/*
* We can loop without lock because this is a task private list.
- * The test done during the collection loop will guarantee us that
- * another task will not try to collect this file. Also, items
- * cannot vanish during the loop because we are holding "sem".
+ * We just splice'd out the ep->rdllist in ep_collect_ready_items().
+ * Items cannot vanish during the loop because we are holding "sem" in
+ * read.
*/
- list_for_each(lnk, txlist) {
- epi = list_entry(lnk, struct epitem, txlink);
+ for (eventcnt = 0; !list_empty(txlist) && eventcnt < maxevents;) {
+ epi = list_first_entry(txlist, struct epitem, rdllink);
+ prefetch(epi->rdllink.next);
/*
* Get the ready file event set. We can safely use the file
@@ -1434,64 +1368,65 @@
* guarantee that both the file and the item will not vanish.
*/
revents = epi->ffd.file->f_op->poll(epi->ffd.file, NULL);
+ revents &= epi->event.events;
/*
- * Set the return event set for the current file descriptor.
- * Note that only the task task was successfully able to link
- * the item to its "txlist" will write this field.
+ * Is the event mask intersect the caller-requested one,
+ * deliver the event to userspace. Again, we are holding
+ * "sem" in read, so no operations coming from userspace
+ * can change the item.
*/
- epi->revents = revents & epi->event.events;
-
- if (epi->revents) {
- if (__put_user(epi->revents,
+ if (revents) {
+ if (__put_user(revents,
&events[eventcnt].events) ||
__put_user(epi->event.data,
&events[eventcnt].data))
- return -EFAULT;
+ goto errxit;
if (epi->event.events & EPOLLONESHOT)
epi->event.events &= EP_PRIVATE_BITS;
eventcnt++;
}
- }
- return eventcnt;
-}
-
-
-/*
- * Walk through the transfer list we collected with ep_collect_ready_items()
- * and, if 1) the item is still "alive" 2) its event set is not empty 3) it's
- * not already linked, links it to the ready list. Same as above, we are holding
- * "sem" so items cannot vanish underneath our nose.
- */
-static void ep_reinject_items(struct eventpoll *ep, struct list_head *txlist)
-{
- int ricnt = 0, pwake = 0;
- unsigned long flags;
- struct epitem *epi;
-
- write_lock_irqsave(&ep->lock, flags);
-
- while (!list_empty(txlist)) {
- epi = list_entry(txlist->next, struct epitem, txlink);
-
- /* Unlink the current item from the transfer list */
- ep_list_del(&epi->txlink);
/*
- * If the item is no more linked to the interest set, we don't
- * have to push it inside the ready list because the following
- * ep_release_epitem() is going to drop it. Also, if the current
- * item is set to have an Edge Triggered behaviour, we don't have
- * to push it back either.
+ * This is tricky. We are holding the "sem" in read, and this
+ * means that the operations that can change the "linked" status
+ * of the epoll item (epi->rbn and epi->rdllink), cannot touch
+ * them. Also, since we are "linked" from a epi->rdllink POV
+ * (the item is linked to our transmission list we just
+ * spliced), the ep_poll_callback() cannot touch us either,
+ * because of the check present in there. Another parallel
+ * epoll_wait() will not get the same result set, since we
+ * spliced the ready list before. Note that list_del() still
+ * shows the item as linked to the test in ep_poll_callback().
*/
- if (ep_rb_linked(&epi->rbn) && !(epi->event.events & EPOLLET) &&
- (epi->revents & epi->event.events) && !ep_is_linked(&epi->rdllink)) {
- list_add_tail(&epi->rdllink, &ep->rdllist);
- ricnt++;
+ list_del(&epi->rdllink);
+ if (!(epi->event.events & EPOLLET) &&
+ (revents & epi->event.events))
+ list_add_tail(&epi->rdllink, &injlist);
+ else {
+ /*
+ * Be sure the item is totally detached before re-init
+ * the list_head. After INIT_LIST_HEAD() is committed,
+ * the ep_poll_callback() can requeue the item again,
+ * but we don't care since we are already past it.
+ */
+ smp_mb();
+ INIT_LIST_HEAD(&epi->rdllink);
}
}
+ error = 0;
- if (ricnt) {
+ errxit:
+
+ /*
+ * If the re-injection list or the txlist are not empty, re-splice
+ * them to the ready list and do proper wakeups.
+ */
+ if (!list_empty(&injlist) || !list_empty(txlist)) {
+ write_lock_irqsave(&ep->lock, flags);
+
+ list_splice(txlist, &ep->rdllist);
+ list_splice(&injlist, &ep->rdllist);
/*
* Wake up ( if active ) both the eventpoll wait list and the ->poll()
* wait list.
@@ -1501,13 +1436,15 @@
TASK_INTERRUPTIBLE);
if (waitqueue_active(&ep->poll_wait))
pwake++;
- }
- write_unlock_irqrestore(&ep->lock, flags);
+ write_unlock_irqrestore(&ep->lock, flags);
+ }
/* We have to call this outside the lock */
if (pwake)
ep_poll_safewake(&psw, &ep->poll_wait);
+
+ return eventcnt == 0 ? error: eventcnt;
}
@@ -1517,7 +1454,8 @@
static int ep_events_transfer(struct eventpoll *ep,
struct epoll_event __user *events, int maxevents)
{
- int eventcnt = 0;
+ int eventcnt;
+ unsigned long flags;
struct list_head txlist;
INIT_LIST_HEAD(&txlist);
@@ -1528,14 +1466,17 @@
*/
down_read(&ep->sem);
- /* Collect/extract ready items */
- if (ep_collect_ready_items(ep, &txlist, maxevents) > 0) {
- /* Build result set in userspace */
- eventcnt = ep_send_events(ep, &txlist, events);
+ /*
+ * Steal the ready list, and re-init the original one to the
+ * empty list.
+ */
+ write_lock_irqsave(&ep->lock, flags);
+ list_splice(&ep->rdllist, &txlist);
+ INIT_LIST_HEAD(&ep->rdllist);
+ write_unlock_irqrestore(&ep->lock, flags);
- /* Reinject ready items into the ready list */
- ep_reinject_items(ep, &txlist);
- }
+ /* Build result set in userspace */
+ eventcnt = ep_send_events(ep, &txlist, events, maxevents);
up_read(&ep->sem);
@@ -1612,14 +1553,12 @@
return res;
}
-
static int eventpollfs_delete_dentry(struct dentry *dentry)
{
return 1;
}
-
static struct inode *ep_eventpoll_inode(void)
{
int error = -ENOMEM;
@@ -1647,7 +1586,6 @@
return ERR_PTR(error);
}
-
static int
eventpollfs_get_sb(struct file_system_type *fs_type, int flags,
const char *dev_name, void *data, struct vfsmount *mnt)
diff --git a/fs/exec.c b/fs/exec.c
index 3155e91..1ba85c7 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -100,6 +100,7 @@
while (*tmp) {
if (fmt == *tmp) {
*tmp = fmt->next;
+ fmt->next = NULL;
write_unlock(&binfmt_lock);
return 0;
}
@@ -982,33 +983,51 @@
task_unlock(current);
security_bprm_post_apply_creds(bprm);
}
-
EXPORT_SYMBOL(compute_creds);
+/*
+ * Arguments are '\0' separated strings found at the location bprm->p
+ * points to; chop off the first by relocating brpm->p to right after
+ * the first '\0' encountered.
+ */
void remove_arg_zero(struct linux_binprm *bprm)
{
if (bprm->argc) {
- unsigned long offset;
- char * kaddr;
- struct page *page;
+ char ch;
- offset = bprm->p % PAGE_SIZE;
- goto inside;
+ do {
+ unsigned long offset;
+ unsigned long index;
+ char *kaddr;
+ struct page *page;
- while (bprm->p++, *(kaddr+offset++)) {
- if (offset != PAGE_SIZE)
- continue;
- offset = 0;
- kunmap_atomic(kaddr, KM_USER0);
-inside:
- page = bprm->page[bprm->p/PAGE_SIZE];
+ offset = bprm->p & ~PAGE_MASK;
+ index = bprm->p >> PAGE_SHIFT;
+
+ page = bprm->page[index];
kaddr = kmap_atomic(page, KM_USER0);
- }
- kunmap_atomic(kaddr, KM_USER0);
+
+ /* run through page until we reach end or find NUL */
+ do {
+ ch = *(kaddr + offset);
+
+ /* discard that character... */
+ bprm->p++;
+ offset++;
+ } while (offset < PAGE_SIZE && ch != '\0');
+
+ kunmap_atomic(kaddr, KM_USER0);
+
+ /* free the old page */
+ if (offset == PAGE_SIZE) {
+ __free_page(page);
+ bprm->page[index] = NULL;
+ }
+ } while (ch != '\0');
+
bprm->argc--;
}
}
-
EXPORT_SYMBOL(remove_arg_zero);
/*
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c
index 93e77c3..e98f6cd 100644
--- a/fs/exportfs/expfs.c
+++ b/fs/exportfs/expfs.c
@@ -2,7 +2,6 @@
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/module.h>
-#include <linux/smp_lock.h>
#include <linux/namei.h>
struct export_operations export_op_default;
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
index 1d1e7e3..2bf49d7 100644
--- a/fs/ext2/dir.c
+++ b/fs/ext2/dir.c
@@ -23,7 +23,6 @@
#include "ext2.h"
#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
typedef struct ext2_dir_entry_2 ext2_dirent;
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index e2a0ea5..9fd0ec5 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -133,6 +133,7 @@
extern void ext2_truncate (struct inode *);
extern int ext2_setattr (struct dentry *, struct iattr *);
extern void ext2_set_inode_flags(struct inode *inode);
+extern void ext2_get_inode_flags(struct ext2_inode_info *);
/* ioctl.c */
extern int ext2_ioctl (struct inode *, struct file *, unsigned int,
diff --git a/fs/ext2/fsync.c b/fs/ext2/fsync.c
index 7806b9e..fc66c93 100644
--- a/fs/ext2/fsync.c
+++ b/fs/ext2/fsync.c
@@ -23,7 +23,6 @@
*/
#include "ext2.h"
-#include <linux/smp_lock.h>
#include <linux/buffer_head.h> /* for sync_mapping_buffers() */
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index dd4e14c..0079b2c 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -1055,6 +1055,25 @@
inode->i_flags |= S_DIRSYNC;
}
+/* Propagate flags from i_flags to EXT2_I(inode)->i_flags */
+void ext2_get_inode_flags(struct ext2_inode_info *ei)
+{
+ unsigned int flags = ei->vfs_inode.i_flags;
+
+ ei->i_flags &= ~(EXT2_SYNC_FL|EXT2_APPEND_FL|
+ EXT2_IMMUTABLE_FL|EXT2_NOATIME_FL|EXT2_DIRSYNC_FL);
+ if (flags & S_SYNC)
+ ei->i_flags |= EXT2_SYNC_FL;
+ if (flags & S_APPEND)
+ ei->i_flags |= EXT2_APPEND_FL;
+ if (flags & S_IMMUTABLE)
+ ei->i_flags |= EXT2_IMMUTABLE_FL;
+ if (flags & S_NOATIME)
+ ei->i_flags |= EXT2_NOATIME_FL;
+ if (flags & S_DIRSYNC)
+ ei->i_flags |= EXT2_DIRSYNC_FL;
+}
+
void ext2_read_inode (struct inode * inode)
{
struct ext2_inode_info *ei = EXT2_I(inode);
@@ -1079,9 +1098,9 @@
}
inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
inode->i_size = le32_to_cpu(raw_inode->i_size);
- inode->i_atime.tv_sec = le32_to_cpu(raw_inode->i_atime);
- inode->i_ctime.tv_sec = le32_to_cpu(raw_inode->i_ctime);
- inode->i_mtime.tv_sec = le32_to_cpu(raw_inode->i_mtime);
+ inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime);
+ inode->i_ctime.tv_sec = (signed)le32_to_cpu(raw_inode->i_ctime);
+ inode->i_mtime.tv_sec = (signed)le32_to_cpu(raw_inode->i_mtime);
inode->i_atime.tv_nsec = inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = 0;
ei->i_dtime = le32_to_cpu(raw_inode->i_dtime);
/* We now have enough fields to check if the inode was active or not.
@@ -1188,6 +1207,7 @@
if (ei->i_state & EXT2_STATE_NEW)
memset(raw_inode, 0, EXT2_SB(sb)->s_inode_size);
+ ext2_get_inode_flags(ei);
raw_inode->i_mode = cpu_to_le16(inode->i_mode);
if (!(test_opt(sb, NO_UID32))) {
raw_inode->i_uid_low = cpu_to_le16(low_16_bits(uid));
diff --git a/fs/ext2/ioctl.c b/fs/ext2/ioctl.c
index 4b099d3..e85c482 100644
--- a/fs/ext2/ioctl.c
+++ b/fs/ext2/ioctl.c
@@ -27,6 +27,7 @@
switch (cmd) {
case EXT2_IOC_GETFLAGS:
+ ext2_get_inode_flags(ei);
flags = ei->i_flags & EXT2_FL_USER_VISIBLE;
return put_user(flags, (int __user *) arg);
case EXT2_IOC_SETFLAGS: {
diff --git a/fs/ext2/xattr_security.c b/fs/ext2/xattr_security.c
index a266127..eaa23d2 100644
--- a/fs/ext2/xattr_security.c
+++ b/fs/ext2/xattr_security.c
@@ -6,7 +6,6 @@
#include <linux/module.h>
#include <linux/string.h>
#include <linux/fs.h>
-#include <linux/smp_lock.h>
#include <linux/ext2_fs.h>
#include <linux/security.h>
#include "xattr.h"
diff --git a/fs/ext2/xattr_trusted.c b/fs/ext2/xattr_trusted.c
index f28a6a4..83ee149 100644
--- a/fs/ext2/xattr_trusted.c
+++ b/fs/ext2/xattr_trusted.c
@@ -9,7 +9,6 @@
#include <linux/string.h>
#include <linux/capability.h>
#include <linux/fs.h>
-#include <linux/smp_lock.h>
#include <linux/ext2_fs.h>
#include "xattr.h"
diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c
index 665adee..8528698 100644
--- a/fs/ext3/dir.c
+++ b/fs/ext3/dir.c
@@ -25,7 +25,6 @@
#include <linux/jbd.h>
#include <linux/ext3_fs.h>
#include <linux/buffer_head.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/rbtree.h>
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index a5b150f..e1bb031 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -27,7 +27,6 @@
#include <linux/time.h>
#include <linux/ext3_jbd.h>
#include <linux/jbd.h>
-#include <linux/smp_lock.h>
#include <linux/highuid.h>
#include <linux/pagemap.h>
#include <linux/quotaops.h>
@@ -2581,6 +2580,25 @@
inode->i_flags |= S_DIRSYNC;
}
+/* Propagate flags from i_flags to EXT3_I(inode)->i_flags */
+void ext3_get_inode_flags(struct ext3_inode_info *ei)
+{
+ unsigned int flags = ei->vfs_inode.i_flags;
+
+ ei->i_flags &= ~(EXT3_SYNC_FL|EXT3_APPEND_FL|
+ EXT3_IMMUTABLE_FL|EXT3_NOATIME_FL|EXT3_DIRSYNC_FL);
+ if (flags & S_SYNC)
+ ei->i_flags |= EXT3_SYNC_FL;
+ if (flags & S_APPEND)
+ ei->i_flags |= EXT3_APPEND_FL;
+ if (flags & S_IMMUTABLE)
+ ei->i_flags |= EXT3_IMMUTABLE_FL;
+ if (flags & S_NOATIME)
+ ei->i_flags |= EXT3_NOATIME_FL;
+ if (flags & S_DIRSYNC)
+ ei->i_flags |= EXT3_DIRSYNC_FL;
+}
+
void ext3_read_inode(struct inode * inode)
{
struct ext3_iloc iloc;
@@ -2608,9 +2626,9 @@
}
inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
inode->i_size = le32_to_cpu(raw_inode->i_size);
- inode->i_atime.tv_sec = le32_to_cpu(raw_inode->i_atime);
- inode->i_ctime.tv_sec = le32_to_cpu(raw_inode->i_ctime);
- inode->i_mtime.tv_sec = le32_to_cpu(raw_inode->i_mtime);
+ inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime);
+ inode->i_ctime.tv_sec = (signed)le32_to_cpu(raw_inode->i_ctime);
+ inode->i_mtime.tv_sec = (signed)le32_to_cpu(raw_inode->i_mtime);
inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_mtime.tv_nsec = 0;
ei->i_state = 0;
@@ -2736,6 +2754,7 @@
if (ei->i_state & EXT3_STATE_NEW)
memset(raw_inode, 0, EXT3_SB(inode->i_sb)->s_inode_size);
+ ext3_get_inode_flags(ei);
raw_inode->i_mode = cpu_to_le16(inode->i_mode);
if(!(test_opt(inode->i_sb, NO_UID32))) {
raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid));
diff --git a/fs/ext3/ioctl.c b/fs/ext3/ioctl.c
index 9b8090d..965006d 100644
--- a/fs/ext3/ioctl.c
+++ b/fs/ext3/ioctl.c
@@ -28,6 +28,7 @@
switch (cmd) {
case EXT3_IOC_GETFLAGS:
+ ext3_get_inode_flags(ei);
flags = ei->i_flags & EXT3_FL_USER_VISIBLE;
return put_user(flags, (int __user *) arg);
case EXT3_IOC_SETFLAGS: {
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index 49159f1..9bb046d 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -36,7 +36,6 @@
#include <linux/quotaops.h>
#include <linux/buffer_head.h>
#include <linux/bio.h>
-#include <linux/smp_lock.h>
#include "namei.h"
#include "xattr.h"
@@ -969,6 +968,7 @@
(block<<EXT3_BLOCK_SIZE_BITS(sb))
+((char *)de - bh->b_data))) {
brelse (bh);
+ *err = ERR_BAD_DX_DIR;
goto errout;
}
*res_dir = de;
@@ -1134,9 +1134,9 @@
char *data1 = (*bh)->b_data, *data2;
unsigned split;
struct ext3_dir_entry_2 *de = NULL, *de2;
- int err;
+ int err = 0;
- bh2 = ext3_append (handle, dir, &newblock, error);
+ bh2 = ext3_append (handle, dir, &newblock, &err);
if (!(bh2)) {
brelse(*bh);
*bh = NULL;
@@ -1145,14 +1145,9 @@
BUFFER_TRACE(*bh, "get_write_access");
err = ext3_journal_get_write_access(handle, *bh);
- if (err) {
- journal_error:
- brelse(*bh);
- brelse(bh2);
- *bh = NULL;
- ext3_std_error(dir->i_sb, err);
- goto errout;
- }
+ if (err)
+ goto journal_error;
+
BUFFER_TRACE(frame->bh, "get_write_access");
err = ext3_journal_get_write_access(handle, frame->bh);
if (err)
@@ -1195,8 +1190,16 @@
goto journal_error;
brelse (bh2);
dxtrace(dx_show_index ("frame", frame->entries));
-errout:
return de;
+
+journal_error:
+ brelse(*bh);
+ brelse(bh2);
+ *bh = NULL;
+ ext3_std_error(dir->i_sb, err);
+errout:
+ *error = err;
+ return NULL;
}
#endif
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c
index ecf8990..2c97e09 100644
--- a/fs/ext3/resize.c
+++ b/fs/ext3/resize.c
@@ -11,7 +11,6 @@
#define EXT3FS_DEBUG
-#include <linux/smp_lock.h>
#include <linux/ext3_jbd.h>
#include <linux/errno.h>
diff --git a/fs/ext3/xattr_security.c b/fs/ext3/xattr_security.c
index b9c40c1..821efaf 100644
--- a/fs/ext3/xattr_security.c
+++ b/fs/ext3/xattr_security.c
@@ -6,7 +6,6 @@
#include <linux/module.h>
#include <linux/string.h>
#include <linux/fs.h>
-#include <linux/smp_lock.h>
#include <linux/ext3_jbd.h>
#include <linux/ext3_fs.h>
#include <linux/security.h>
diff --git a/fs/ext3/xattr_trusted.c b/fs/ext3/xattr_trusted.c
index 86d91f1..0327497 100644
--- a/fs/ext3/xattr_trusted.c
+++ b/fs/ext3/xattr_trusted.c
@@ -9,7 +9,6 @@
#include <linux/string.h>
#include <linux/capability.h>
#include <linux/fs.h>
-#include <linux/smp_lock.h>
#include <linux/ext3_jbd.h>
#include <linux/ext3_fs.h>
#include "xattr.h"
diff --git a/fs/ext3/xattr_user.c b/fs/ext3/xattr_user.c
index a85a0a1..1abd8f9 100644
--- a/fs/ext3/xattr_user.c
+++ b/fs/ext3/xattr_user.c
@@ -8,7 +8,6 @@
#include <linux/module.h>
#include <linux/string.h>
#include <linux/fs.h>
-#include <linux/smp_lock.h>
#include <linux/ext3_jbd.h>
#include <linux/ext3_fs.h>
#include "xattr.h"
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
index da80368..e8ad06e 100644
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -25,7 +25,6 @@
#include <linux/jbd2.h>
#include <linux/ext4_fs.h>
#include <linux/buffer_head.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/rbtree.h>
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 7916b50..a0f0c04 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -34,7 +34,6 @@
#include <linux/time.h>
#include <linux/ext4_jbd2.h>
#include <linux/jbd.h>
-#include <linux/smp_lock.h>
#include <linux/highuid.h>
#include <linux/pagemap.h>
#include <linux/quotaops.h>
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 810b6d6..b34182b 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -27,7 +27,6 @@
#include <linux/time.h>
#include <linux/ext4_jbd2.h>
#include <linux/jbd2.h>
-#include <linux/smp_lock.h>
#include <linux/highuid.h>
#include <linux/pagemap.h>
#include <linux/quotaops.h>
@@ -2611,9 +2610,9 @@
}
inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
inode->i_size = le32_to_cpu(raw_inode->i_size);
- inode->i_atime.tv_sec = le32_to_cpu(raw_inode->i_atime);
- inode->i_ctime.tv_sec = le32_to_cpu(raw_inode->i_ctime);
- inode->i_mtime.tv_sec = le32_to_cpu(raw_inode->i_mtime);
+ inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime);
+ inode->i_ctime.tv_sec = (signed)le32_to_cpu(raw_inode->i_ctime);
+ inode->i_mtime.tv_sec = (signed)le32_to_cpu(raw_inode->i_mtime);
inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_mtime.tv_nsec = 0;
ei->i_state = 0;
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index e7e1d79..4ec57be 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -36,7 +36,6 @@
#include <linux/quotaops.h>
#include <linux/buffer_head.h>
#include <linux/bio.h>
-#include <linux/smp_lock.h>
#include "namei.h"
#include "xattr.h"
@@ -967,6 +966,7 @@
(block<<EXT4_BLOCK_SIZE_BITS(sb))
+((char *)de - bh->b_data))) {
brelse (bh);
+ *err = ERR_BAD_DX_DIR;
goto errout;
}
*res_dir = de;
@@ -1132,9 +1132,9 @@
char *data1 = (*bh)->b_data, *data2;
unsigned split;
struct ext4_dir_entry_2 *de = NULL, *de2;
- int err;
+ int err = 0;
- bh2 = ext4_append (handle, dir, &newblock, error);
+ bh2 = ext4_append (handle, dir, &newblock, &err);
if (!(bh2)) {
brelse(*bh);
*bh = NULL;
@@ -1143,14 +1143,9 @@
BUFFER_TRACE(*bh, "get_write_access");
err = ext4_journal_get_write_access(handle, *bh);
- if (err) {
- journal_error:
- brelse(*bh);
- brelse(bh2);
- *bh = NULL;
- ext4_std_error(dir->i_sb, err);
- goto errout;
- }
+ if (err)
+ goto journal_error;
+
BUFFER_TRACE(frame->bh, "get_write_access");
err = ext4_journal_get_write_access(handle, frame->bh);
if (err)
@@ -1193,8 +1188,16 @@
goto journal_error;
brelse (bh2);
dxtrace(dx_show_index ("frame", frame->entries));
-errout:
return de;
+
+journal_error:
+ brelse(*bh);
+ brelse(bh2);
+ *bh = NULL;
+ ext4_std_error(dir->i_sb, err);
+errout:
+ *error = err;
+ return NULL;
}
#endif
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index ea99f6c..aa11d7d 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -11,7 +11,6 @@
#define EXT4FS_DEBUG
-#include <linux/smp_lock.h>
#include <linux/ext4_jbd2.h>
#include <linux/errno.h>
diff --git a/fs/ext4/xattr_security.c b/fs/ext4/xattr_security.c
index b6a6861..f17eaf2 100644
--- a/fs/ext4/xattr_security.c
+++ b/fs/ext4/xattr_security.c
@@ -6,7 +6,6 @@
#include <linux/module.h>
#include <linux/string.h>
#include <linux/fs.h>
-#include <linux/smp_lock.h>
#include <linux/ext4_jbd2.h>
#include <linux/ext4_fs.h>
#include <linux/security.h>
diff --git a/fs/ext4/xattr_trusted.c b/fs/ext4/xattr_trusted.c
index b76f2db..e0f05ac 100644
--- a/fs/ext4/xattr_trusted.c
+++ b/fs/ext4/xattr_trusted.c
@@ -9,7 +9,6 @@
#include <linux/string.h>
#include <linux/capability.h>
#include <linux/fs.h>
-#include <linux/smp_lock.h>
#include <linux/ext4_jbd2.h>
#include <linux/ext4_fs.h>
#include "xattr.h"
diff --git a/fs/ext4/xattr_user.c b/fs/ext4/xattr_user.c
index c53cded..7ed3d8e 100644
--- a/fs/ext4/xattr_user.c
+++ b/fs/ext4/xattr_user.c
@@ -8,7 +8,6 @@
#include <linux/module.h>
#include <linux/string.h>
#include <linux/fs.h>
-#include <linux/smp_lock.h>
#include <linux/ext4_jbd2.h>
#include <linux/ext4_fs.h>
#include "xattr.h"
diff --git a/fs/fat/dir.c b/fs/fat/dir.c
index c16af24..ccf161d 100644
--- a/fs/fat/dir.c
+++ b/fs/fat/dir.c
@@ -422,7 +422,7 @@
EXPORT_SYMBOL_GPL(fat_search_long);
struct fat_ioctl_filldir_callback {
- struct dirent __user *dirent;
+ void __user *dirent;
int result;
/* for dir ioctl */
const char *longname;
@@ -647,62 +647,85 @@
return __fat_readdir(inode, filp, dirent, filldir, 0, 0);
}
-static int fat_ioctl_filldir(void *__buf, const char *name, int name_len,
- loff_t offset, u64 ino, unsigned int d_type)
-{
- struct fat_ioctl_filldir_callback *buf = __buf;
- struct dirent __user *d1 = buf->dirent;
- struct dirent __user *d2 = d1 + 1;
-
- if (buf->result)
- return -EINVAL;
- buf->result++;
-
- if (name != NULL) {
- /* dirent has only short name */
- if (name_len >= sizeof(d1->d_name))
- name_len = sizeof(d1->d_name) - 1;
-
- if (put_user(0, d2->d_name) ||
- put_user(0, &d2->d_reclen) ||
- copy_to_user(d1->d_name, name, name_len) ||
- put_user(0, d1->d_name + name_len) ||
- put_user(name_len, &d1->d_reclen))
- goto efault;
- } else {
- /* dirent has short and long name */
- const char *longname = buf->longname;
- int long_len = buf->long_len;
- const char *shortname = buf->shortname;
- int short_len = buf->short_len;
-
- if (long_len >= sizeof(d1->d_name))
- long_len = sizeof(d1->d_name) - 1;
- if (short_len >= sizeof(d1->d_name))
- short_len = sizeof(d1->d_name) - 1;
-
- if (copy_to_user(d2->d_name, longname, long_len) ||
- put_user(0, d2->d_name + long_len) ||
- put_user(long_len, &d2->d_reclen) ||
- put_user(ino, &d2->d_ino) ||
- put_user(offset, &d2->d_off) ||
- copy_to_user(d1->d_name, shortname, short_len) ||
- put_user(0, d1->d_name + short_len) ||
- put_user(short_len, &d1->d_reclen))
- goto efault;
- }
- return 0;
-efault:
- buf->result = -EFAULT;
- return -EFAULT;
+#define FAT_IOCTL_FILLDIR_FUNC(func, dirent_type) \
+static int func(void *__buf, const char *name, int name_len, \
+ loff_t offset, u64 ino, unsigned int d_type) \
+{ \
+ struct fat_ioctl_filldir_callback *buf = __buf; \
+ struct dirent_type __user *d1 = buf->dirent; \
+ struct dirent_type __user *d2 = d1 + 1; \
+ \
+ if (buf->result) \
+ return -EINVAL; \
+ buf->result++; \
+ \
+ if (name != NULL) { \
+ /* dirent has only short name */ \
+ if (name_len >= sizeof(d1->d_name)) \
+ name_len = sizeof(d1->d_name) - 1; \
+ \
+ if (put_user(0, d2->d_name) || \
+ put_user(0, &d2->d_reclen) || \
+ copy_to_user(d1->d_name, name, name_len) || \
+ put_user(0, d1->d_name + name_len) || \
+ put_user(name_len, &d1->d_reclen)) \
+ goto efault; \
+ } else { \
+ /* dirent has short and long name */ \
+ const char *longname = buf->longname; \
+ int long_len = buf->long_len; \
+ const char *shortname = buf->shortname; \
+ int short_len = buf->short_len; \
+ \
+ if (long_len >= sizeof(d1->d_name)) \
+ long_len = sizeof(d1->d_name) - 1; \
+ if (short_len >= sizeof(d1->d_name)) \
+ short_len = sizeof(d1->d_name) - 1; \
+ \
+ if (copy_to_user(d2->d_name, longname, long_len) || \
+ put_user(0, d2->d_name + long_len) || \
+ put_user(long_len, &d2->d_reclen) || \
+ put_user(ino, &d2->d_ino) || \
+ put_user(offset, &d2->d_off) || \
+ copy_to_user(d1->d_name, shortname, short_len) || \
+ put_user(0, d1->d_name + short_len) || \
+ put_user(short_len, &d1->d_reclen)) \
+ goto efault; \
+ } \
+ return 0; \
+efault: \
+ buf->result = -EFAULT; \
+ return -EFAULT; \
}
-static int fat_dir_ioctl(struct inode * inode, struct file * filp,
- unsigned int cmd, unsigned long arg)
+FAT_IOCTL_FILLDIR_FUNC(fat_ioctl_filldir, dirent)
+
+static int fat_ioctl_readdir(struct inode *inode, struct file *filp,
+ void __user *dirent, filldir_t filldir,
+ int short_only, int both)
{
struct fat_ioctl_filldir_callback buf;
- struct dirent __user *d1;
- int ret, short_only, both;
+ int ret;
+
+ buf.dirent = dirent;
+ buf.result = 0;
+ mutex_lock(&inode->i_mutex);
+ ret = -ENOENT;
+ if (!IS_DEADDIR(inode)) {
+ ret = __fat_readdir(inode, filp, &buf, filldir,
+ short_only, both);
+ }
+ mutex_unlock(&inode->i_mutex);
+ if (ret >= 0)
+ ret = buf.result;
+ return ret;
+}
+
+static int fat_dir_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ struct dirent __user *d1 = (struct dirent __user *)arg;
+ int short_only, both;
switch (cmd) {
case VFAT_IOCTL_READDIR_SHORT:
@@ -717,7 +740,6 @@
return fat_generic_ioctl(inode, filp, cmd, arg);
}
- d1 = (struct dirent __user *)arg;
if (!access_ok(VERIFY_WRITE, d1, sizeof(struct dirent[2])))
return -EFAULT;
/*
@@ -728,69 +750,48 @@
if (put_user(0, &d1->d_reclen))
return -EFAULT;
- buf.dirent = d1;
- buf.result = 0;
- mutex_lock(&inode->i_mutex);
- ret = -ENOENT;
- if (!IS_DEADDIR(inode)) {
- ret = __fat_readdir(inode, filp, &buf, fat_ioctl_filldir,
- short_only, both);
- }
- mutex_unlock(&inode->i_mutex);
- if (ret >= 0)
- ret = buf.result;
- return ret;
+ return fat_ioctl_readdir(inode, filp, d1, fat_ioctl_filldir,
+ short_only, both);
}
#ifdef CONFIG_COMPAT
#define VFAT_IOCTL_READDIR_BOTH32 _IOR('r', 1, struct compat_dirent[2])
#define VFAT_IOCTL_READDIR_SHORT32 _IOR('r', 2, struct compat_dirent[2])
-static long fat_compat_put_dirent32(struct dirent *d,
- struct compat_dirent __user *d32)
-{
- if (!access_ok(VERIFY_WRITE, d32, sizeof(struct compat_dirent)))
- return -EFAULT;
+FAT_IOCTL_FILLDIR_FUNC(fat_compat_ioctl_filldir, compat_dirent)
- __put_user(d->d_ino, &d32->d_ino);
- __put_user(d->d_off, &d32->d_off);
- __put_user(d->d_reclen, &d32->d_reclen);
- if (__copy_to_user(d32->d_name, d->d_name, d->d_reclen))
- return -EFAULT;
-
- return 0;
-}
-
-static long fat_compat_dir_ioctl(struct file *file, unsigned cmd,
+static long fat_compat_dir_ioctl(struct file *filp, unsigned cmd,
unsigned long arg)
{
- struct compat_dirent __user *p = compat_ptr(arg);
- int ret;
- mm_segment_t oldfs = get_fs();
- struct dirent d[2];
+ struct inode *inode = filp->f_path.dentry->d_inode;
+ struct compat_dirent __user *d1 = compat_ptr(arg);
+ int short_only, both;
switch (cmd) {
- case VFAT_IOCTL_READDIR_BOTH32:
- cmd = VFAT_IOCTL_READDIR_BOTH;
- break;
case VFAT_IOCTL_READDIR_SHORT32:
- cmd = VFAT_IOCTL_READDIR_SHORT;
+ short_only = 1;
+ both = 0;
+ break;
+ case VFAT_IOCTL_READDIR_BOTH32:
+ short_only = 0;
+ both = 1;
break;
default:
return -ENOIOCTLCMD;
}
- set_fs(KERNEL_DS);
- lock_kernel();
- ret = fat_dir_ioctl(file->f_path.dentry->d_inode, file,
- cmd, (unsigned long) &d);
- unlock_kernel();
- set_fs(oldfs);
- if (ret >= 0) {
- ret |= fat_compat_put_dirent32(&d[0], p);
- ret |= fat_compat_put_dirent32(&d[1], p + 1);
- }
- return ret;
+ if (!access_ok(VERIFY_WRITE, d1, sizeof(struct compat_dirent[2])))
+ return -EFAULT;
+ /*
+ * Yes, we don't need this put_user() absolutely. However old
+ * code didn't return the right value. So, app use this value,
+ * in order to check whether it is EOF.
+ */
+ if (put_user(0, &d1->d_reclen))
+ return -EFAULT;
+
+ return fat_ioctl_readdir(inode, filp, d1, fat_compat_ioctl_filldir,
+ short_only, both);
}
#endif /* CONFIG_COMPAT */
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 65cb54b..2c55e8d 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -25,6 +25,7 @@
#include <linux/parser.h>
#include <linux/uio.h>
#include <linux/writeback.h>
+#include <linux/log2.h>
#include <asm/unaligned.h>
#ifndef CONFIG_FAT_DEFAULT_IOCHARSET
@@ -824,6 +825,8 @@
}
if (opts->name_check != 'n')
seq_printf(m, ",check=%c", opts->name_check);
+ if (opts->usefree)
+ seq_puts(m, ",usefree");
if (opts->quiet)
seq_puts(m, ",quiet");
if (opts->showexec)
@@ -849,7 +852,7 @@
enum {
Opt_check_n, Opt_check_r, Opt_check_s, Opt_uid, Opt_gid,
- Opt_umask, Opt_dmask, Opt_fmask, Opt_codepage, Opt_nocase,
+ Opt_umask, Opt_dmask, Opt_fmask, Opt_codepage, Opt_usefree, Opt_nocase,
Opt_quiet, Opt_showexec, Opt_debug, Opt_immutable,
Opt_dots, Opt_nodots,
Opt_charset, Opt_shortname_lower, Opt_shortname_win95,
@@ -871,6 +874,7 @@
{Opt_dmask, "dmask=%o"},
{Opt_fmask, "fmask=%o"},
{Opt_codepage, "codepage=%u"},
+ {Opt_usefree, "usefree"},
{Opt_nocase, "nocase"},
{Opt_quiet, "quiet"},
{Opt_showexec, "showexec"},
@@ -950,7 +954,7 @@
opts->quiet = opts->showexec = opts->sys_immutable = opts->dotsOK = 0;
opts->utf8 = opts->unicode_xlate = 0;
opts->numtail = 1;
- opts->nocase = 0;
+ opts->usefree = opts->nocase = 0;
*debug = 0;
if (!options)
@@ -978,6 +982,9 @@
case Opt_check_n:
opts->name_check = 'n';
break;
+ case Opt_usefree:
+ opts->usefree = 1;
+ break;
case Opt_nocase:
if (!is_vfat)
opts->nocase = 1;
@@ -1217,8 +1224,7 @@
}
logical_sector_size =
le16_to_cpu(get_unaligned((__le16 *)&b->sector_size));
- if (!logical_sector_size
- || (logical_sector_size & (logical_sector_size - 1))
+ if (!is_power_of_2(logical_sector_size)
|| (logical_sector_size < 512)
|| (PAGE_CACHE_SIZE < logical_sector_size)) {
if (!silent)
@@ -1228,8 +1234,7 @@
goto out_invalid;
}
sbi->sec_per_clus = b->sec_per_clus;
- if (!sbi->sec_per_clus
- || (sbi->sec_per_clus & (sbi->sec_per_clus - 1))) {
+ if (!is_power_of_2(sbi->sec_per_clus)) {
if (!silent)
printk(KERN_ERR "FAT: bogus sectors per cluster %u\n",
sbi->sec_per_clus);
@@ -1305,7 +1310,9 @@
le32_to_cpu(fsinfo->signature2),
sbi->fsinfo_sector);
} else {
- sbi->free_clusters = le32_to_cpu(fsinfo->free_clusters);
+ if (sbi->options.usefree)
+ sbi->free_clusters =
+ le32_to_cpu(fsinfo->free_clusters);
sbi->prev_free = le32_to_cpu(fsinfo->next_cluster);
}
diff --git a/fs/fifo.c b/fs/fifo.c
index 49035b1..6e7df72 100644
--- a/fs/fifo.c
+++ b/fs/fifo.c
@@ -11,7 +11,6 @@
#include <linux/mm.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/fs.h>
#include <linux/pipe_fs_i.h>
diff --git a/fs/file_table.c b/fs/file_table.c
index 4c17a18..d17fd69 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -10,7 +10,6 @@
#include <linux/file.h>
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/smp_lock.h>
#include <linux/fs.h>
#include <linux/security.h>
#include <linux/eventpoll.h>
diff --git a/fs/filesystems.c b/fs/filesystems.c
index 7a4f61a..f37f872 100644
--- a/fs/filesystems.c
+++ b/fs/filesystems.c
@@ -41,11 +41,12 @@
module_put(fs->owner);
}
-static struct file_system_type **find_filesystem(const char *name)
+static struct file_system_type **find_filesystem(const char *name, unsigned len)
{
struct file_system_type **p;
for (p=&file_systems; *p; p=&(*p)->next)
- if (strcmp((*p)->name,name) == 0)
+ if (strlen((*p)->name) == len &&
+ strncmp((*p)->name, name, len) == 0)
break;
return p;
}
@@ -68,11 +69,12 @@
int res = 0;
struct file_system_type ** p;
+ BUG_ON(strchr(fs->name, '.'));
if (fs->next)
return -EBUSY;
INIT_LIST_HEAD(&fs->fs_supers);
write_lock(&file_systems_lock);
- p = find_filesystem(fs->name);
+ p = find_filesystem(fs->name, strlen(fs->name));
if (*p)
res = -EBUSY;
else
@@ -215,19 +217,26 @@
struct file_system_type *get_fs_type(const char *name)
{
struct file_system_type *fs;
+ const char *dot = strchr(name, '.');
+ unsigned len = dot ? dot - name : strlen(name);
read_lock(&file_systems_lock);
- fs = *(find_filesystem(name));
+ fs = *(find_filesystem(name, len));
if (fs && !try_module_get(fs->owner))
fs = NULL;
read_unlock(&file_systems_lock);
- if (!fs && (request_module("%s", name) == 0)) {
+ if (!fs && (request_module("%.*s", len, name) == 0)) {
read_lock(&file_systems_lock);
- fs = *(find_filesystem(name));
+ fs = *(find_filesystem(name, len));
if (fs && !try_module_get(fs->owner))
fs = NULL;
read_unlock(&file_systems_lock);
}
+
+ if (dot && fs && !(fs->fs_flags & FS_HAS_SUBTYPE)) {
+ put_filesystem(fs);
+ fs = NULL;
+ }
return fs;
}
diff --git a/fs/freevxfs/vxfs_bmap.c b/fs/freevxfs/vxfs_bmap.c
index 2d71128..f86fd3c 100644
--- a/fs/freevxfs/vxfs_bmap.c
+++ b/fs/freevxfs/vxfs_bmap.c
@@ -137,7 +137,7 @@
bp = sb_bread(ip->i_sb,
indir + (i / VXFS_TYPED_PER_BLOCK(ip->i_sb)));
- if (!buffer_mapped(bp))
+ if (!bp || !buffer_mapped(bp))
return 0;
typ = ((struct vxfs_typed *)bp->b_data) +
diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c
index 098a915..d1f7c5b 100644
--- a/fs/freevxfs/vxfs_inode.c
+++ b/fs/freevxfs/vxfs_inode.c
@@ -99,7 +99,7 @@
offset = ((ino % (sbp->s_blocksize / VXFS_ISIZE)) * VXFS_ISIZE);
bp = sb_bread(sbp, block);
- if (buffer_mapped(bp)) {
+ if (bp && buffer_mapped(bp)) {
struct vxfs_inode_info *vip;
struct vxfs_dinode *dip;
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index d8003be..1397018 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -636,6 +636,7 @@
static struct file_system_type fuse_fs_type = {
.owner = THIS_MODULE,
.name = "fuse",
+ .fs_flags = FS_HAS_SUBTYPE,
.get_sb = fuse_get_sb,
.kill_sb = kill_anon_super,
};
@@ -652,6 +653,7 @@
static struct file_system_type fuseblk_fs_type = {
.owner = THIS_MODULE,
.name = "fuseblk",
+ .fs_flags = FS_HAS_SUBTYPE,
.get_sb = fuse_get_sb_blk,
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV,
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index 39c8ae2..7b82657 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -163,10 +163,7 @@
if (ip) {
struct address_space *mapping = ip->i_inode.i_mapping;
int error = filemap_fdatawait(mapping);
- if (error == -ENOSPC)
- set_bit(AS_ENOSPC, &mapping->flags);
- else if (error)
- set_bit(AS_EIO, &mapping->flags);
+ mapping_set_error(mapping, error);
}
clear_bit(GLF_DIRTY, &gl->gl_flags);
gfs2_ail_empty_gl(gl);
diff --git a/fs/gfs2/locking/nolock/main.c b/fs/gfs2/locking/nolock/main.c
index 5cc1dfa..0d149c8c 100644
--- a/fs/gfs2/locking/nolock/main.c
+++ b/fs/gfs2/locking/nolock/main.c
@@ -13,7 +13,6 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/fs.h>
-#include <linux/smp_lock.h>
#include <linux/lm_interface.h>
struct nolock_lockspace {
diff --git a/fs/gfs2/ops_dentry.c b/fs/gfs2/ops_dentry.c
index c6bac6b..a6fdc52 100644
--- a/fs/gfs2/ops_dentry.c
+++ b/fs/gfs2/ops_dentry.c
@@ -11,7 +11,6 @@
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/buffer_head.h>
-#include <linux/smp_lock.h>
#include <linux/gfs2_ondisk.h>
#include <linux/crc32.h>
#include <linux/lm_interface.h>
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c
index 329c4dc..064df88 100644
--- a/fs/gfs2/ops_file.c
+++ b/fs/gfs2/ops_file.c
@@ -15,7 +15,6 @@
#include <linux/uio.h>
#include <linux/blkdev.h>
#include <linux/mm.h>
-#include <linux/smp_lock.h>
#include <linux/fs.h>
#include <linux/gfs2_ondisk.h>
#include <linux/ext2_fs.h>
diff --git a/fs/hfs/btree.c b/fs/hfs/btree.c
index 5fd0ed7..8a3a650 100644
--- a/fs/hfs/btree.c
+++ b/fs/hfs/btree.c
@@ -9,6 +9,7 @@
*/
#include <linux/pagemap.h>
+#include <linux/log2.h>
#include "btree.h"
@@ -76,7 +77,7 @@
tree->depth = be16_to_cpu(head->depth);
size = tree->node_size;
- if (!size || size & (size - 1))
+ if (!is_power_of_2(size))
goto fail_page;
if (!tree->node_count)
goto fail_page;
diff --git a/fs/hfsplus/btree.c b/fs/hfsplus/btree.c
index a9b9e87..90ebab7 100644
--- a/fs/hfsplus/btree.c
+++ b/fs/hfsplus/btree.c
@@ -10,6 +10,7 @@
#include <linux/slab.h>
#include <linux/pagemap.h>
+#include <linux/log2.h>
#include "hfsplus_fs.h"
#include "hfsplus_raw.h"
@@ -69,7 +70,7 @@
}
size = tree->node_size;
- if (!size || size & (size - 1))
+ if (!is_power_of_2(size))
goto fail_page;
if (!tree->node_count)
goto fail_page;
diff --git a/fs/hostfs/hostfs.h b/fs/hostfs/hostfs.h
index 70543b1..06e5930 100644
--- a/fs/hostfs/hostfs.h
+++ b/fs/hostfs/hostfs.h
@@ -55,7 +55,7 @@
int *mode_out, int *nlink_out, int *uid_out, int *gid_out,
unsigned long long *size_out, struct timespec *atime_out,
struct timespec *mtime_out, struct timespec *ctime_out,
- int *blksize_out, unsigned long long *blocks_out);
+ int *blksize_out, unsigned long long *blocks_out, int fd);
extern int access_file(char *path, int r, int w, int x);
extern int open_file(char *path, int r, int w, int append);
extern int file_type(const char *path, int *maj, int *min);
@@ -71,7 +71,7 @@
extern int fsync_file(int fd, int datasync);
extern int file_create(char *name, int ur, int uw, int ux, int gr,
int gw, int gx, int or, int ow, int ox);
-extern int set_attr(const char *file, struct hostfs_iattr *attrs);
+extern int set_attr(const char *file, struct hostfs_iattr *attrs, int fd);
extern int make_symlink(const char *from, const char *to);
extern int unlink_file(const char *file);
extern int do_mkdir(const char *file, int mode);
@@ -87,14 +87,3 @@
long *spare_out);
#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index fd301a9..8286491 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*
* Ported the filesystem routines to 2.5.
@@ -31,14 +31,14 @@
static inline struct hostfs_inode_info *HOSTFS_I(struct inode *inode)
{
- return(list_entry(inode, struct hostfs_inode_info, vfs_inode));
+ return list_entry(inode, struct hostfs_inode_info, vfs_inode);
}
#define FILE_HOSTFS_I(file) HOSTFS_I((file)->f_path.dentry->d_inode)
int hostfs_d_delete(struct dentry *dentry)
{
- return(1);
+ return 1;
}
struct dentry_operations hostfs_dentry_ops = {
@@ -79,7 +79,7 @@
}
options = ptr;
}
- return(0);
+ return 0;
}
__uml_setup("hostfs=", hostfs_args,
@@ -110,7 +110,8 @@
root = HOSTFS_I(parent->d_inode)->host_filename;
len += strlen(root);
name = kmalloc(len + extra + 1, GFP_KERNEL);
- if(name == NULL) return(NULL);
+ if(name == NULL)
+ return NULL;
name[len] = '\0';
parent = dentry;
@@ -122,7 +123,7 @@
parent = parent->d_parent;
}
strncpy(name, root, strlen(root));
- return(name);
+ return name;
}
static char *inode_name(struct inode *ino, int extra)
@@ -130,7 +131,7 @@
struct dentry *dentry;
dentry = list_entry(ino->i_dentry.next, struct dentry, d_alias);
- return(dentry_name(dentry, extra));
+ return dentry_name(dentry, extra);
}
static int read_name(struct inode *ino, char *name)
@@ -147,16 +148,16 @@
err = stat_file(name, &i_ino, &i_mode, &i_nlink, &ino->i_uid,
&ino->i_gid, &i_size, &ino->i_atime, &ino->i_mtime,
- &ino->i_ctime, &i_blksize, &i_blocks);
+ &ino->i_ctime, &i_blksize, &i_blocks, -1);
if(err)
- return(err);
+ return err;
ino->i_ino = i_ino;
ino->i_mode = i_mode;
ino->i_nlink = i_nlink;
ino->i_size = i_size;
ino->i_blocks = i_blocks;
- return(0);
+ return 0;
}
static char *follow_link(char *link)
@@ -181,11 +182,11 @@
goto out_free;
if(*name == '/')
- return(name);
+ return name;
end = strrchr(link, '/');
if(end == NULL)
- return(name);
+ return name;
*(end + 1) = '\0';
len = strlen(link) + strlen(name) + 1;
@@ -199,12 +200,12 @@
sprintf(resolved, "%s%s", link, name);
kfree(name);
kfree(link);
- return(resolved);
+ return resolved;
out_free:
kfree(name);
out:
- return(ERR_PTR(n));
+ return ERR_PTR(n);
}
static int read_inode(struct inode *ino)
@@ -234,7 +235,7 @@
err = read_name(ino, name);
kfree(name);
out:
- return(err);
+ return err;
}
int hostfs_statfs(struct dentry *dentry, struct kstatfs *sf)
@@ -254,14 +255,15 @@
&sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files,
&f_ffree, &sf->f_fsid, sizeof(sf->f_fsid),
&sf->f_namelen, sf->f_spare);
- if(err) return(err);
+ if(err)
+ return err;
sf->f_blocks = f_blocks;
sf->f_bfree = f_bfree;
sf->f_bavail = f_bavail;
sf->f_files = f_files;
sf->f_ffree = f_ffree;
sf->f_type = HOSTFS_SUPER_MAGIC;
- return(0);
+ return 0;
}
static struct inode *hostfs_alloc_inode(struct super_block *sb)
@@ -270,13 +272,13 @@
hi = kmalloc(sizeof(*hi), GFP_KERNEL);
if(hi == NULL)
- return(NULL);
+ return NULL;
*hi = ((struct hostfs_inode_info) { .host_filename = NULL,
.fd = -1,
.mode = 0 });
inode_init_once(&hi->vfs_inode);
- return(&hi->vfs_inode);
+ return &hi->vfs_inode;
}
static void hostfs_delete_inode(struct inode *inode)
@@ -325,10 +327,12 @@
int error, len;
name = dentry_name(file->f_path.dentry, 0);
- if(name == NULL) return(-ENOMEM);
+ if(name == NULL)
+ return -ENOMEM;
dir = open_dir(name, &error);
kfree(name);
- if(dir == NULL) return(-error);
+ if(dir == NULL)
+ return -error;
next = file->f_pos;
while((name = read_dir(dir, &next, &ino, &len)) != NULL){
error = (*filldir)(ent, name, len, file->f_pos,
@@ -337,7 +341,7 @@
file->f_pos = next;
}
close_dir(dir);
- return(0);
+ return 0;
}
int hostfs_file_open(struct inode *ino, struct file *file)
@@ -347,7 +351,7 @@
mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
if((mode & HOSTFS_I(ino)->mode) == mode)
- return(0);
+ return 0;
/* The file may already have been opened, but with the wrong access,
* so this resets things and reopens the file with the new access.
@@ -367,14 +371,15 @@
name = dentry_name(file->f_path.dentry, 0);
if(name == NULL)
- return(-ENOMEM);
+ return -ENOMEM;
fd = open_file(name, r, w, append);
kfree(name);
- if(fd < 0) return(fd);
+ if(fd < 0)
+ return fd;
FILE_HOSTFS_I(file)->fd = fd;
- return(0);
+ return 0;
}
int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync)
@@ -458,7 +463,7 @@
out:
kunmap(page);
unlock_page(page);
- return(err);
+ return err;
}
int hostfs_prepare_write(struct file *file, struct page *page,
@@ -485,7 +490,7 @@
err = 0;
out:
kunmap(page);
- return(err);
+ return err;
}
int hostfs_commit_write(struct file *file, struct page *page, unsigned from,
@@ -511,7 +516,7 @@
inode->i_size = start;
kunmap(page);
- return(err);
+ return err;
}
static const struct address_space_operations hostfs_aops = {
@@ -569,7 +574,7 @@
break;
}
out:
- return(err);
+ return err;
}
int hostfs_create(struct inode *dir, struct dentry *dentry, int mode,
@@ -607,16 +612,16 @@
HOSTFS_I(inode)->fd = fd;
HOSTFS_I(inode)->mode = FMODE_READ | FMODE_WRITE;
d_instantiate(dentry, inode);
- return(0);
+ return 0;
out_put:
iput(inode);
out:
- return(error);
+ return error;
}
struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry,
- struct nameidata *nd)
+ struct nameidata *nd)
{
struct inode *inode;
char *name;
@@ -647,44 +652,45 @@
d_add(dentry, inode);
dentry->d_op = &hostfs_dentry_ops;
- return(NULL);
+ return NULL;
out_put:
iput(inode);
out:
- return(ERR_PTR(err));
+ return ERR_PTR(err);
}
static char *inode_dentry_name(struct inode *ino, struct dentry *dentry)
{
- char *file;
+ char *file;
int len;
file = inode_name(ino, dentry->d_name.len + 1);
- if(file == NULL) return(NULL);
- strcat(file, "/");
+ if(file == NULL)
+ return NULL;
+ strcat(file, "/");
len = strlen(file);
- strncat(file, dentry->d_name.name, dentry->d_name.len);
+ strncat(file, dentry->d_name.name, dentry->d_name.len);
file[len + dentry->d_name.len] = '\0';
- return(file);
+ return file;
}
int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from)
{
- char *from_name, *to_name;
- int err;
+ char *from_name, *to_name;
+ int err;
- if((from_name = inode_dentry_name(ino, from)) == NULL)
- return(-ENOMEM);
- to_name = dentry_name(to, 0);
+ if((from_name = inode_dentry_name(ino, from)) == NULL)
+ return -ENOMEM;
+ to_name = dentry_name(to, 0);
if(to_name == NULL){
kfree(from_name);
- return(-ENOMEM);
+ return -ENOMEM;
}
- err = link_file(to_name, from_name);
- kfree(from_name);
- kfree(to_name);
- return(err);
+ err = link_file(to_name, from_name);
+ kfree(from_name);
+ kfree(to_name);
+ return err;
}
int hostfs_unlink(struct inode *ino, struct dentry *dentry)
@@ -692,13 +698,14 @@
char *file;
int err;
- if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
+ if((file = inode_dentry_name(ino, dentry)) == NULL)
+ return -ENOMEM;
if(append)
- return(-EPERM);
+ return -EPERM;
err = unlink_file(file);
kfree(file);
- return(err);
+ return err;
}
int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to)
@@ -706,10 +713,11 @@
char *file;
int err;
- if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
+ if((file = inode_dentry_name(ino, dentry)) == NULL)
+ return -ENOMEM;
err = make_symlink(file, to);
kfree(file);
- return(err);
+ return err;
}
int hostfs_mkdir(struct inode *ino, struct dentry *dentry, int mode)
@@ -717,10 +725,11 @@
char *file;
int err;
- if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
+ if((file = inode_dentry_name(ino, dentry)) == NULL)
+ return -ENOMEM;
err = do_mkdir(file, mode);
kfree(file);
- return(err);
+ return err;
}
int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
@@ -728,10 +737,11 @@
char *file;
int err;
- if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
+ if((file = inode_dentry_name(ino, dentry)) == NULL)
+ return -ENOMEM;
err = do_rmdir(file);
kfree(file);
- return(err);
+ return err;
}
int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
@@ -764,14 +774,14 @@
goto out_put;
d_instantiate(dentry, inode);
- return(0);
+ return 0;
out_free:
kfree(name);
out_put:
iput(inode);
out:
- return(err);
+ return err;
}
int hostfs_rename(struct inode *from_ino, struct dentry *from,
@@ -781,15 +791,15 @@
int err;
if((from_name = inode_dentry_name(from_ino, from)) == NULL)
- return(-ENOMEM);
+ return -ENOMEM;
if((to_name = inode_dentry_name(to_ino, to)) == NULL){
kfree(from_name);
- return(-ENOMEM);
+ return -ENOMEM;
}
err = rename_file(from_name, to_name);
kfree(from_name);
kfree(to_name);
- return(err);
+ return err;
}
int hostfs_permission(struct inode *ino, int desired, struct nameidata *nd)
@@ -801,7 +811,8 @@
if (desired & MAY_WRITE) w = 1;
if (desired & MAY_EXEC) x = 1;
name = inode_name(ino, 0);
- if (name == NULL) return(-ENOMEM);
+ if (name == NULL)
+ return -ENOMEM;
if (S_ISCHR(ino->i_mode) || S_ISBLK(ino->i_mode) ||
S_ISFIFO(ino->i_mode) || S_ISSOCK(ino->i_mode))
@@ -820,6 +831,8 @@
char *name;
int err;
+ int fd = HOSTFS_I(dentry->d_inode)->fd;
+
err = inode_change_ok(dentry->d_inode, attr);
if (err)
return err;
@@ -863,20 +876,21 @@
attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
}
name = dentry_name(dentry, 0);
- if(name == NULL) return(-ENOMEM);
- err = set_attr(name, &attrs);
+ if(name == NULL)
+ return -ENOMEM;
+ err = set_attr(name, &attrs, fd);
kfree(name);
if(err)
- return(err);
+ return err;
- return(inode_setattr(dentry->d_inode, attr));
+ return inode_setattr(dentry->d_inode, attr);
}
int hostfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat)
{
generic_fillattr(dentry->d_inode, stat);
- return(0);
+ return 0;
}
static const struct inode_operations hostfs_iops = {
@@ -915,7 +929,8 @@
buffer = kmap(page);
name = inode_name(page->mapping->host, 0);
- if(name == NULL) return(-ENOMEM);
+ if(name == NULL)
+ return -ENOMEM;
err = do_readlink(name, buffer, PAGE_CACHE_SIZE);
kfree(name);
if(err == PAGE_CACHE_SIZE)
@@ -928,7 +943,7 @@
}
kunmap(page);
unlock_page(page);
- return(err);
+ return err;
}
static const struct address_space_operations hostfs_link_aops = {
@@ -978,20 +993,20 @@
err = read_inode(root_inode);
if(err){
- /* No iput in this case because the dput does that for us */
- dput(sb->s_root);
- sb->s_root = NULL;
+ /* No iput in this case because the dput does that for us */
+ dput(sb->s_root);
+ sb->s_root = NULL;
goto out;
- }
+ }
- return(0);
+ return 0;
- out_put:
- iput(root_inode);
- out_free:
+out_put:
+ iput(root_inode);
+out_free:
kfree(host_root_path);
- out:
- return(err);
+out:
+ return err;
}
static int hostfs_read_sb(struct file_system_type *type,
@@ -1011,7 +1026,7 @@
static int __init init_hostfs(void)
{
- return(register_filesystem(&hostfs_type));
+ return register_filesystem(&hostfs_type);
}
static void __exit exit_hostfs(void)
@@ -1022,14 +1037,3 @@
module_init(init_hostfs)
module_exit(exit_hostfs)
MODULE_LICENSE("GPL");
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/fs/hostfs/hostfs_user.c b/fs/hostfs/hostfs_user.c
index 1ed5ea3..5625e24 100644
--- a/fs/hostfs/hostfs_user.c
+++ b/fs/hostfs/hostfs_user.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
@@ -21,12 +21,16 @@
int *nlink_out, int *uid_out, int *gid_out,
unsigned long long *size_out, struct timespec *atime_out,
struct timespec *mtime_out, struct timespec *ctime_out,
- int *blksize_out, unsigned long long *blocks_out)
+ int *blksize_out, unsigned long long *blocks_out, int fd)
{
struct stat64 buf;
- if(lstat64(path, &buf) < 0)
- return(-errno);
+ if(fd >= 0) {
+ if (fstat64(fd, &buf) < 0)
+ return -errno;
+ } else if(lstat64(path, &buf) < 0) {
+ return -errno;
+ }
if(inode_out != NULL) *inode_out = buf.st_ino;
if(mode_out != NULL) *mode_out = buf.st_mode;
@@ -48,7 +52,7 @@
}
if(blksize_out != NULL) *blksize_out = buf.st_blksize;
if(blocks_out != NULL) *blocks_out = buf.st_blocks;
- return(0);
+ return 0;
}
int file_type(const char *path, int *maj, int *min)
@@ -56,7 +60,7 @@
struct stat64 buf;
if(lstat64(path, &buf) < 0)
- return(-errno);
+ return -errno;
/*We cannot pass rdev as is because glibc and the kernel disagree
*about its definition.*/
if(maj != NULL)
@@ -64,13 +68,13 @@
if(min != NULL)
*min = minor(buf.st_rdev);
- if(S_ISDIR(buf.st_mode)) return(OS_TYPE_DIR);
- else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK);
- else if(S_ISCHR(buf.st_mode)) return(OS_TYPE_CHARDEV);
- else if(S_ISBLK(buf.st_mode)) return(OS_TYPE_BLOCKDEV);
- else if(S_ISFIFO(buf.st_mode))return(OS_TYPE_FIFO);
- else if(S_ISSOCK(buf.st_mode))return(OS_TYPE_SOCK);
- else return(OS_TYPE_FILE);
+ if(S_ISDIR(buf.st_mode)) return OS_TYPE_DIR;
+ else if(S_ISLNK(buf.st_mode)) return OS_TYPE_SYMLINK;
+ else if(S_ISCHR(buf.st_mode)) return OS_TYPE_CHARDEV;
+ else if(S_ISBLK(buf.st_mode)) return OS_TYPE_BLOCKDEV;
+ else if(S_ISFIFO(buf.st_mode))return OS_TYPE_FIFO;
+ else if(S_ISSOCK(buf.st_mode))return OS_TYPE_SOCK;
+ else return OS_TYPE_FILE;
}
int access_file(char *path, int r, int w, int x)
@@ -80,8 +84,9 @@
if(r) mode = R_OK;
if(w) mode |= W_OK;
if(x) mode |= X_OK;
- if(access(path, mode) != 0) return(-errno);
- else return(0);
+ if(access(path, mode) != 0)
+ return -errno;
+ else return 0;
}
int open_file(char *path, int r, int w, int append)
@@ -99,8 +104,9 @@
if(append)
mode |= O_APPEND;
fd = open64(path, mode);
- if(fd < 0) return(-errno);
- else return(fd);
+ if(fd < 0)
+ return -errno;
+ else return fd;
}
void *open_dir(char *path, int *err_out)
@@ -109,8 +115,9 @@
dir = opendir(path);
*err_out = errno;
- if(dir == NULL) return(NULL);
- return(dir);
+ if(dir == NULL)
+ return NULL;
+ return dir;
}
char *read_dir(void *stream, unsigned long long *pos,
@@ -121,11 +128,12 @@
seekdir(dir, *pos);
ent = readdir(dir);
- if(ent == NULL) return(NULL);
+ if(ent == NULL)
+ return NULL;
*len_out = strlen(ent->d_name);
*ino_out = ent->d_ino;
*pos = telldir(dir);
- return(ent->d_name);
+ return ent->d_name;
}
int read_file(int fd, unsigned long long *offset, char *buf, int len)
@@ -133,9 +141,10 @@
int n;
n = pread64(fd, buf, len, *offset);
- if(n < 0) return(-errno);
+ if(n < 0)
+ return -errno;
*offset += n;
- return(n);
+ return n;
}
int write_file(int fd, unsigned long long *offset, const char *buf, int len)
@@ -143,9 +152,10 @@
int n;
n = pwrite64(fd, buf, len, *offset);
- if(n < 0) return(-errno);
+ if(n < 0)
+ return -errno;
*offset += n;
- return(n);
+ return n;
}
int lseek_file(int fd, long long offset, int whence)
@@ -154,8 +164,8 @@
ret = lseek64(fd, offset, whence);
if(ret < 0)
- return(-errno);
- return(0);
+ return -errno;
+ return 0;
}
int fsync_file(int fd, int datasync)
@@ -198,65 +208,90 @@
mode |= ox ? S_IXOTH : 0;
fd = open64(name, O_CREAT | O_RDWR, mode);
if(fd < 0)
- return(-errno);
- return(fd);
+ return -errno;
+ return fd;
}
-int set_attr(const char *file, struct hostfs_iattr *attrs)
+int set_attr(const char *file, struct hostfs_iattr *attrs, int fd)
{
- struct utimbuf buf;
+ struct timeval times[2];
+ struct timespec atime_ts, mtime_ts;
int err, ma;
- if(attrs->ia_valid & HOSTFS_ATTR_MODE){
- if(chmod(file, attrs->ia_mode) != 0) return(-errno);
+ if (attrs->ia_valid & HOSTFS_ATTR_MODE) {
+ if (fd >= 0) {
+ if (fchmod(fd, attrs->ia_mode) != 0)
+ return (-errno);
+ } else if (chmod(file, attrs->ia_mode) != 0) {
+ return -errno;
+ }
}
- if(attrs->ia_valid & HOSTFS_ATTR_UID){
- if(chown(file, attrs->ia_uid, -1)) return(-errno);
+ if (attrs->ia_valid & HOSTFS_ATTR_UID) {
+ if (fd >= 0) {
+ if (fchown(fd, attrs->ia_uid, -1))
+ return -errno;
+ } else if(chown(file, attrs->ia_uid, -1)) {
+ return -errno;
+ }
}
- if(attrs->ia_valid & HOSTFS_ATTR_GID){
- if(chown(file, -1, attrs->ia_gid)) return(-errno);
+ if (attrs->ia_valid & HOSTFS_ATTR_GID) {
+ if (fd >= 0) {
+ if (fchown(fd, -1, attrs->ia_gid))
+ return -errno;
+ } else if (chown(file, -1, attrs->ia_gid)) {
+ return -errno;
+ }
}
- if(attrs->ia_valid & HOSTFS_ATTR_SIZE){
- if(truncate(file, attrs->ia_size)) return(-errno);
+ if (attrs->ia_valid & HOSTFS_ATTR_SIZE) {
+ if (fd >= 0) {
+ if (ftruncate(fd, attrs->ia_size))
+ return -errno;
+ } else if (truncate(file, attrs->ia_size)) {
+ return -errno;
+ }
}
- ma = HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET;
- if((attrs->ia_valid & ma) == ma){
- buf.actime = attrs->ia_atime.tv_sec;
- buf.modtime = attrs->ia_mtime.tv_sec;
- if(utime(file, &buf) != 0) return(-errno);
- }
- else {
- struct timespec ts;
- if(attrs->ia_valid & HOSTFS_ATTR_ATIME_SET){
- err = stat_file(file, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, &ts, NULL, NULL, NULL);
- if(err != 0)
- return(err);
- buf.actime = attrs->ia_atime.tv_sec;
- buf.modtime = ts.tv_sec;
- if(utime(file, &buf) != 0)
- return(-errno);
+ /* Update accessed and/or modified time, in two parts: first set
+ * times according to the changes to perform, and then call futimes()
+ * or utimes() to apply them. */
+ ma = (HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET);
+ if (attrs->ia_valid & ma) {
+ err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL,
+ &atime_ts, &mtime_ts, NULL, NULL, NULL, fd);
+ if (err != 0)
+ return err;
+
+ times[0].tv_sec = atime_ts.tv_sec;
+ times[0].tv_usec = atime_ts.tv_nsec * 1000;
+ times[1].tv_sec = mtime_ts.tv_sec;
+ times[1].tv_usec = mtime_ts.tv_nsec * 1000;
+
+ if (attrs->ia_valid & HOSTFS_ATTR_ATIME_SET) {
+ times[0].tv_sec = attrs->ia_atime.tv_sec;
+ times[0].tv_usec = attrs->ia_atime.tv_nsec * 1000;
}
- if(attrs->ia_valid & HOSTFS_ATTR_MTIME_SET){
- err = stat_file(file, NULL, NULL, NULL, NULL, NULL,
- NULL, &ts, NULL, NULL, NULL, NULL);
- if(err != 0)
- return(err);
- buf.actime = ts.tv_sec;
- buf.modtime = attrs->ia_mtime.tv_sec;
- if(utime(file, &buf) != 0)
- return(-errno);
+ if (attrs->ia_valid & HOSTFS_ATTR_MTIME_SET) {
+ times[1].tv_sec = attrs->ia_mtime.tv_sec;
+ times[1].tv_usec = attrs->ia_mtime.tv_nsec * 1000;
+ }
+
+ if (fd >= 0) {
+ if (futimes(fd, times) != 0)
+ return -errno;
+ } else if (utimes(file, times) != 0) {
+ return -errno;
}
}
+
if(attrs->ia_valid & HOSTFS_ATTR_CTIME) ;
if(attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)){
err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL,
&attrs->ia_atime, &attrs->ia_mtime, NULL,
- NULL, NULL);
- if(err != 0) return(err);
+ NULL, NULL, fd);
+ if(err != 0)
+ return err;
}
- return(0);
+ return 0;
}
int make_symlink(const char *from, const char *to)
@@ -264,8 +299,9 @@
int err;
err = symlink(to, from);
- if(err) return(-errno);
- return(0);
+ if(err)
+ return -errno;
+ return 0;
}
int unlink_file(const char *file)
@@ -273,8 +309,9 @@
int err;
err = unlink(file);
- if(err) return(-errno);
- return(0);
+ if(err)
+ return -errno;
+ return 0;
}
int do_mkdir(const char *file, int mode)
@@ -282,8 +319,9 @@
int err;
err = mkdir(file, mode);
- if(err) return(-errno);
- return(0);
+ if(err)
+ return -errno;
+ return 0;
}
int do_rmdir(const char *file)
@@ -291,8 +329,9 @@
int err;
err = rmdir(file);
- if(err) return(-errno);
- return(0);
+ if(err)
+ return -errno;
+ return 0;
}
int do_mknod(const char *file, int mode, unsigned int major, unsigned int minor)
@@ -300,8 +339,9 @@
int err;
err = mknod(file, mode, makedev(major, minor));
- if(err) return(-errno);
- return(0);
+ if(err)
+ return -errno;
+ return 0;
}
int link_file(const char *to, const char *from)
@@ -309,8 +349,9 @@
int err;
err = link(to, from);
- if(err) return(-errno);
- return(0);
+ if(err)
+ return -errno;
+ return 0;
}
int do_readlink(char *file, char *buf, int size)
@@ -319,10 +360,10 @@
n = readlink(file, buf, size);
if(n < 0)
- return(-errno);
+ return -errno;
if(n < size)
buf[n] = '\0';
- return(n);
+ return n;
}
int rename_file(char *from, char *to)
@@ -330,8 +371,9 @@
int err;
err = rename(from, to);
- if(err < 0) return(-errno);
- return(0);
+ if(err < 0)
+ return -errno;
+ return 0;
}
int do_statfs(char *root, long *bsize_out, long long *blocks_out,
@@ -344,7 +386,9 @@
int err;
err = statfs64(root, &buf);
- if(err < 0) return(-errno);
+ if(err < 0)
+ return -errno;
+
*bsize_out = buf.f_bsize;
*blocks_out = buf.f_blocks;
*bfree_out = buf.f_bfree;
@@ -360,16 +404,5 @@
spare_out[2] = buf.f_spare[2];
spare_out[3] = buf.f_spare[3];
spare_out[4] = buf.f_spare[4];
- return(0);
+ return 0;
}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/fs/inode.c b/fs/inode.c
index b4296bf..df2ef15 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -250,7 +250,7 @@
BUG_ON(inode->i_state & I_CLEAR);
wait_on_inode(inode);
DQUOT_DROP(inode);
- if (inode->i_sb && inode->i_sb->s_op->clear_inode)
+ if (inode->i_sb->s_op->clear_inode)
inode->i_sb->s_op->clear_inode(inode);
if (S_ISBLK(inode->i_mode) && inode->i_bdev)
bd_forget(inode);
@@ -275,7 +275,7 @@
while (!list_empty(head)) {
struct inode *inode;
- inode = list_entry(head->next, struct inode, i_list);
+ inode = list_first_entry(head, struct inode, i_list);
list_del(&inode->i_list);
if (inode->i_data.nrpages)
@@ -524,7 +524,12 @@
*/
struct inode *new_inode(struct super_block *sb)
{
- static unsigned long last_ino;
+ /*
+ * On a 32bit, non LFS stat() call, glibc will generate an EOVERFLOW
+ * error if st_ino won't fit in target struct field. Use 32bit counter
+ * here to attempt to avoid that.
+ */
+ static unsigned int last_ino;
struct inode * inode;
spin_lock_prefetch(&inode_lock);
@@ -683,27 +688,28 @@
*/
ino_t iunique(struct super_block *sb, ino_t max_reserved)
{
- static ino_t counter;
+ /*
+ * On a 32bit, non LFS stat() call, glibc will generate an EOVERFLOW
+ * error if st_ino won't fit in target struct field. Use 32bit counter
+ * here to attempt to avoid that.
+ */
+ static unsigned int counter;
struct inode *inode;
- struct hlist_head * head;
+ struct hlist_head *head;
ino_t res;
- spin_lock(&inode_lock);
-retry:
- if (counter > max_reserved) {
- head = inode_hashtable + hash(sb,counter);
- res = counter++;
- inode = find_inode_fast(sb, head, res);
- if (!inode) {
- spin_unlock(&inode_lock);
- return res;
- }
- } else {
- counter = max_reserved + 1;
- }
- goto retry;
-
-}
+ spin_lock(&inode_lock);
+ do {
+ if (counter <= max_reserved)
+ counter = max_reserved + 1;
+ res = counter++;
+ head = inode_hashtable + hash(sb, res);
+ inode = find_inode_fast(sb, head, res);
+ } while (inode != NULL);
+ spin_unlock(&inode_lock);
+
+ return res;
+}
EXPORT_SYMBOL(iunique);
struct inode *igrab(struct inode *inode)
@@ -1040,7 +1046,7 @@
if (!(inode->i_state & (I_DIRTY|I_LOCK)))
list_move(&inode->i_list, &inode_unused);
inodes_stat.nr_unused++;
- if (!sb || (sb->s_flags & MS_ACTIVE)) {
+ if (sb->s_flags & MS_ACTIVE) {
spin_unlock(&inode_lock);
return;
}
diff --git a/fs/inotify.c b/fs/inotify.c
index f5099d8..7457501 100644
--- a/fs/inotify.c
+++ b/fs/inotify.c
@@ -509,7 +509,7 @@
mutex_unlock(&ih->mutex);
break;
}
- watch = list_entry(watches->next, struct inotify_watch, h_list);
+ watch = list_first_entry(watches, struct inotify_watch, h_list);
get_inotify_watch(watch);
mutex_unlock(&ih->mutex);
diff --git a/fs/internal.h b/fs/internal.h
index ea00126..392e8cc 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -9,8 +9,6 @@
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/ioctl32.h>
-
struct super_block;
/*
@@ -42,14 +40,6 @@
extern void __init chrdev_init(void);
/*
- * compat_ioctl.c
- */
-#ifdef CONFIG_COMPAT
-extern struct ioctl_trans ioctl_start[];
-extern int ioctl_table_size;
-#endif
-
-/*
* namespace.c
*/
extern int copy_mount_options(const void __user *, unsigned long *);
diff --git a/fs/ioctl.c b/fs/ioctl.c
index ff61772..479c103 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -67,8 +67,6 @@
return put_user(res, p);
}
case FIGETBSZ:
- if (inode->i_sb == NULL)
- return -EBADF;
return put_user(inode->i_sb->s_blocksize, p);
case FIONREAD:
return put_user(i_size_read(inode) - filp->f_pos, p);
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index be4648b..1facfaf 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -20,7 +20,6 @@
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
/*
* Default IO end handler for temporary BJ_IO buffer_heads.
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c
index 10fff94..46fe743 100644
--- a/fs/jbd/journal.c
+++ b/fs/jbd/journal.c
@@ -28,7 +28,6 @@
#include <linux/jbd.h>
#include <linux/errno.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/freezer.h>
@@ -211,10 +210,16 @@
return 0;
}
-static void journal_start_thread(journal_t *journal)
+static int journal_start_thread(journal_t *journal)
{
- kthread_run(kjournald, journal, "kjournald");
+ struct task_struct *t;
+
+ t = kthread_run(kjournald, journal, "kjournald");
+ if (IS_ERR(t))
+ return PTR_ERR(t);
+
wait_event(journal->j_wait_done_commit, journal->j_task != 0);
+ return 0;
}
static void journal_kill_thread(journal_t *journal)
@@ -840,8 +845,7 @@
/* Add the dynamic fields and write it to disk. */
journal_update_superblock(journal, 1);
- journal_start_thread(journal);
- return 0;
+ return journal_start_thread(journal);
}
/**
diff --git a/fs/jbd/revoke.c b/fs/jbd/revoke.c
index d204ab3..a68cbb6 100644
--- a/fs/jbd/revoke.c
+++ b/fs/jbd/revoke.c
@@ -66,7 +66,6 @@
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/list.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#endif
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index cceaf57..f9822fc 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -23,7 +23,6 @@
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/timer.h>
-#include <linux/smp_lock.h>
#include <linux/mm.h>
#include <linux/highmem.h>
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index 6bd8005..2856e11 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -20,7 +20,6 @@
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
/*
* Default IO end handler for temporary BJ_IO buffer_heads.
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 44fc32b..78d63b8 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -28,7 +28,6 @@
#include <linux/jbd2.h>
#include <linux/errno.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/freezer.h>
@@ -211,10 +210,16 @@
return 0;
}
-static void jbd2_journal_start_thread(journal_t *journal)
+static int jbd2_journal_start_thread(journal_t *journal)
{
- kthread_run(kjournald2, journal, "kjournald2");
+ struct task_struct *t;
+
+ t = kthread_run(kjournald2, journal, "kjournald2");
+ if (IS_ERR(t))
+ return PTR_ERR(t);
+
wait_event(journal->j_wait_done_commit, journal->j_task != 0);
+ return 0;
}
static void journal_kill_thread(journal_t *journal)
@@ -840,8 +845,7 @@
/* Add the dynamic fields and write it to disk. */
jbd2_journal_update_superblock(journal, 1);
- jbd2_journal_start_thread(journal);
- return 0;
+ return jbd2_journal_start_thread(journal);
}
/**
diff --git a/fs/jbd2/revoke.c b/fs/jbd2/revoke.c
index f506646..1e864dc 100644
--- a/fs/jbd2/revoke.c
+++ b/fs/jbd2/revoke.c
@@ -66,7 +66,6 @@
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/list.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#endif
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
index 3a87001..e347d8c0 100644
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -23,7 +23,6 @@
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/timer.h>
-#include <linux/smp_lock.h>
#include <linux/mm.h>
#include <linux/highmem.h>
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
index e285022..3467dde 100644
--- a/fs/jfs/inode.c
+++ b/fs/jfs/inode.c
@@ -55,7 +55,6 @@
inode->i_op = &jfs_file_inode_operations;
init_special_inode(inode, inode->i_mode, inode->i_rdev);
}
- jfs_set_inode_flags(inode);
}
/*
diff --git a/fs/jfs/ioctl.c b/fs/jfs/ioctl.c
index ed814b1..fe063af 100644
--- a/fs/jfs/ioctl.c
+++ b/fs/jfs/ioctl.c
@@ -59,6 +59,7 @@
switch (cmd) {
case JFS_IOC_GETFLAGS:
+ jfs_get_inode_flags(jfs_inode);
flags = jfs_inode->mode2 & JFS_FL_USER_VISIBLE;
flags = jfs_map_ext2(flags, 0);
return put_user(flags, (int __user *) arg);
@@ -78,6 +79,7 @@
if (!S_ISDIR(inode->i_mode))
flags &= ~JFS_DIRSYNC_FL;
+ jfs_get_inode_flags(jfs_inode);
oldflags = jfs_inode->mode2;
/*
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c
index aa5124b..c465607 100644
--- a/fs/jfs/jfs_imap.c
+++ b/fs/jfs/jfs_imap.c
@@ -3078,6 +3078,7 @@
jfs_ip->fileset = le32_to_cpu(dip->di_fileset);
jfs_ip->mode2 = le32_to_cpu(dip->di_mode);
+ jfs_set_inode_flags(ip);
ip->i_mode = le32_to_cpu(dip->di_mode) & 0xffff;
if (sbi->umask != -1) {
@@ -3174,6 +3175,7 @@
dip->di_gid = cpu_to_le32(ip->i_gid);
else
dip->di_gid = cpu_to_le32(jfs_ip->saved_gid);
+ jfs_get_inode_flags(jfs_ip);
/*
* mode2 is only needed for storing the higher order bits.
* Trust i_mode for the lower order ones
diff --git a/fs/jfs/jfs_inode.c b/fs/jfs/jfs_inode.c
index 4c67ed9..ed6574b 100644
--- a/fs/jfs/jfs_inode.c
+++ b/fs/jfs/jfs_inode.c
@@ -45,6 +45,24 @@
inode->i_flags |= S_SYNC;
}
+void jfs_get_inode_flags(struct jfs_inode_info *jfs_ip)
+{
+ unsigned int flags = jfs_ip->vfs_inode.i_flags;
+
+ jfs_ip->mode2 &= ~(JFS_IMMUTABLE_FL | JFS_APPEND_FL | JFS_NOATIME_FL |
+ JFS_DIRSYNC_FL | JFS_SYNC_FL);
+ if (flags & S_IMMUTABLE)
+ jfs_ip->mode2 |= JFS_IMMUTABLE_FL;
+ if (flags & S_APPEND)
+ jfs_ip->mode2 |= JFS_APPEND_FL;
+ if (flags & S_NOATIME)
+ jfs_ip->mode2 |= JFS_NOATIME_FL;
+ if (flags & S_DIRSYNC)
+ jfs_ip->mode2 |= JFS_DIRSYNC_FL;
+ if (flags & S_SYNC)
+ jfs_ip->mode2 |= JFS_SYNC_FL;
+}
+
/*
* NAME: ialloc()
*
diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h
index 6802837..2374b59 100644
--- a/fs/jfs/jfs_inode.h
+++ b/fs/jfs/jfs_inode.h
@@ -31,6 +31,7 @@
extern void jfs_truncate_nolock(struct inode *, loff_t);
extern void jfs_free_zero_link(struct inode *);
extern struct dentry *jfs_get_parent(struct dentry *dentry);
+extern void jfs_get_inode_flags(struct jfs_inode_info *);
extern void jfs_set_inode_flags(struct inode *);
extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
diff --git a/fs/jfs/jfs_lock.h b/fs/jfs/jfs_lock.h
index df48ece..ecf0488 100644
--- a/fs/jfs/jfs_lock.h
+++ b/fs/jfs/jfs_lock.h
@@ -45,7 +45,7 @@
io_schedule(); \
lock_cmd; \
} \
- current->state = TASK_RUNNING; \
+ __set_current_state(TASK_RUNNING); \
remove_wait_queue(&wq, &__wait); \
} while (0)
diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c
index 5065baa..6a3f00d 100644
--- a/fs/jfs/jfs_logmgr.c
+++ b/fs/jfs/jfs_logmgr.c
@@ -62,7 +62,6 @@
#include <linux/fs.h>
#include <linux/blkdev.h>
#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
#include <linux/completion.h>
#include <linux/kthread.h>
#include <linux/buffer_head.h> /* for sync_blockdev() */
@@ -1590,7 +1589,7 @@
set_current_state(TASK_UNINTERRUPTIBLE);
LOGGC_UNLOCK(log);
schedule();
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
LOGGC_LOCK(log);
remove_wait_queue(&target->gcwait, &__wait);
}
@@ -2354,14 +2353,15 @@
lbmStartIO(bp);
spin_lock_irq(&log_redrive_lock);
}
- spin_unlock_irq(&log_redrive_lock);
if (freezing(current)) {
+ spin_unlock_irq(&log_redrive_lock);
refrigerator();
} else {
set_current_state(TASK_INTERRUPTIBLE);
+ spin_unlock_irq(&log_redrive_lock);
schedule();
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
}
} while (!kthread_should_stop());
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
index 03893ac..25430d0 100644
--- a/fs/jfs/jfs_txnmgr.c
+++ b/fs/jfs/jfs_txnmgr.c
@@ -44,7 +44,6 @@
#include <linux/fs.h>
#include <linux/vmalloc.h>
-#include <linux/smp_lock.h>
#include <linux/completion.h>
#include <linux/freezer.h>
#include <linux/module.h>
@@ -136,7 +135,7 @@
set_current_state(TASK_UNINTERRUPTIBLE);
TXN_UNLOCK();
io_schedule();
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(event, &wait);
}
@@ -2798,7 +2797,7 @@
set_current_state(TASK_INTERRUPTIBLE);
LAZY_UNLOCK(flags);
schedule();
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(&jfs_commit_thread_wait, &wq);
}
} while (!kthread_should_stop());
@@ -2990,7 +2989,7 @@
set_current_state(TASK_INTERRUPTIBLE);
TXN_UNLOCK();
schedule();
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
}
} while (!kthread_should_stop());
diff --git a/fs/libfs.c b/fs/libfs.c
index d93842d..1247ee9 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -220,6 +220,12 @@
root = new_inode(s);
if (!root)
goto Enomem;
+ /*
+ * since this is the first inode, make it number 1. New inodes created
+ * after this must take care not to collide with it (by passing
+ * max_reserved of 1 to iunique).
+ */
+ root->i_ino = 1;
root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR;
root->i_uid = root->i_gid = 0;
root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME;
@@ -360,6 +366,11 @@
return 0;
}
+/*
+ * the inodes created here are not hashed. If you use iunique to generate
+ * unique inode values later for this filesystem, then you must take care
+ * to pass it an appropriate max_reserved value to avoid collisions.
+ */
int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files)
{
struct inode *inode;
@@ -376,6 +387,11 @@
inode = new_inode(s);
if (!inode)
return -ENOMEM;
+ /*
+ * because the root inode is 1, the files array must not contain an
+ * entry at index 1
+ */
+ inode->i_ino = 1;
inode->i_mode = S_IFDIR | 0755;
inode->i_uid = inode->i_gid = 0;
inode->i_blocks = 0;
@@ -391,6 +407,13 @@
for (i = 0; !files->name || files->name[0]; i++, files++) {
if (!files->name)
continue;
+
+ /* warn if it tries to conflict with the root inode */
+ if (unlikely(i == 1))
+ printk(KERN_WARNING "%s: %s passed in a files array"
+ "with an index of 1!\n", __func__,
+ s->s_type->name);
+
dentry = d_alloc_name(root, files->name);
if (!dentry)
goto out;
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
index a5c019e..a10343b 100644
--- a/fs/lockd/clntproc.c
+++ b/fs/lockd/clntproc.c
@@ -12,7 +12,6 @@
#include <linux/fs.h>
#include <linux/nfs_fs.h>
#include <linux/utsname.h>
-#include <linux/smp_lock.h>
#include <linux/freezer.h>
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/svc.h>
diff --git a/fs/mpage.c b/fs/mpage.c
index 692a3e5..fa2441f 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -663,12 +663,7 @@
/*
* The caller has a ref on the inode, so *mapping is stable
*/
- if (*ret) {
- if (*ret == -ENOSPC)
- set_bit(AS_ENOSPC, &mapping->flags);
- else
- set_bit(AS_EIO, &mapping->flags);
- }
+ mapping_set_error(mapping, *ret);
out:
return bio;
}
@@ -776,14 +771,7 @@
if (writepage) {
ret = (*writepage)(page, wbc);
- if (ret) {
- if (ret == -ENOSPC)
- set_bit(AS_ENOSPC,
- &mapping->flags);
- else
- set_bit(AS_EIO,
- &mapping->flags);
- }
+ mapping_set_error(mapping, ret);
} else {
bio = __mpage_writepage(bio, page, get_block,
&last_block_in_bio, &ret, wbc,
diff --git a/fs/namei.c b/fs/namei.c
index 94b2f60..856b2f5 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -22,7 +22,6 @@
#include <linux/quotaops.h>
#include <linux/pagemap.h>
#include <linux/fsnotify.h>
-#include <linux/smp_lock.h>
#include <linux/personality.h>
#include <linux/security.h>
#include <linux/syscalls.h>
@@ -1350,17 +1349,6 @@
return __lookup_hash_kern(&this, base, NULL);
}
-/*
- * namei()
- *
- * is used by most simple commands to get the inode of a specified name.
- * Open, link etc use their own routines, but this is enough for things
- * like 'chmod' etc.
- *
- * namei exists in two versions: namei/lnamei. The only difference is
- * that namei follows links, while lnamei does not.
- * SMP-safe
- */
int fastcall __user_walk_fd(int dfd, const char __user *name, unsigned flags,
struct nameidata *nd)
{
diff --git a/fs/namespace.c b/fs/namespace.c
index fd999ca..b696e3a 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -377,6 +377,10 @@
seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
seq_putc(m, ' ');
mangle(m, mnt->mnt_sb->s_type->name);
+ if (mnt->mnt_sb->s_subtype && mnt->mnt_sb->s_subtype[0]) {
+ seq_putc(m, '.');
+ mangle(m, mnt->mnt_sb->s_subtype);
+ }
seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? " ro" : " rw");
for (fs_infop = fs_info; fs_infop->flag; fs_infop++) {
if (mnt->mnt_sb->s_flags & fs_infop->flag)
@@ -495,7 +499,7 @@
{
struct vfsmount *mnt;
while (!list_empty(head)) {
- mnt = list_entry(head->next, struct vfsmount, mnt_hash);
+ mnt = list_first_entry(head, struct vfsmount, mnt_hash);
list_del_init(&mnt->mnt_hash);
if (mnt->mnt_parent != mnt) {
struct dentry *dentry;
@@ -882,6 +886,9 @@
int recurse = flag & MS_REC;
int type = flag & ~MS_REC;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
if (nd->dentry != nd->mnt->mnt_root)
return -EINVAL;
@@ -1173,7 +1180,7 @@
while (!list_empty(graveyard)) {
LIST_HEAD(umounts);
- mnt = list_entry(graveyard->next, struct vfsmount, mnt_expire);
+ mnt = list_first_entry(graveyard, struct vfsmount, mnt_expire);
list_del_init(&mnt->mnt_expire);
/* don't do anything if the namespace is dead - all the
@@ -1441,10 +1448,9 @@
* Allocate a new namespace structure and populate it with contents
* copied from the namespace of the passed in task structure.
*/
-struct mnt_namespace *dup_mnt_ns(struct task_struct *tsk,
+static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
struct fs_struct *fs)
{
- struct mnt_namespace *mnt_ns = tsk->nsproxy->mnt_ns;
struct mnt_namespace *new_ns;
struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL;
struct vfsmount *p, *q;
@@ -1509,36 +1515,21 @@
return new_ns;
}
-int copy_mnt_ns(int flags, struct task_struct *tsk)
+struct mnt_namespace *copy_mnt_ns(int flags, struct mnt_namespace *ns,
+ struct fs_struct *new_fs)
{
- struct mnt_namespace *ns = tsk->nsproxy->mnt_ns;
struct mnt_namespace *new_ns;
- int err = 0;
- if (!ns)
- return 0;
-
+ BUG_ON(!ns);
get_mnt_ns(ns);
if (!(flags & CLONE_NEWNS))
- return 0;
+ return ns;
- if (!capable(CAP_SYS_ADMIN)) {
- err = -EPERM;
- goto out;
- }
+ new_ns = dup_mnt_ns(ns, new_fs);
- new_ns = dup_mnt_ns(tsk, tsk->fs);
- if (!new_ns) {
- err = -ENOMEM;
- goto out;
- }
-
- tsk->nsproxy->mnt_ns = new_ns;
-
-out:
put_mnt_ns(ns);
- return err;
+ return new_ns;
}
asmlinkage long sys_mount(char __user * dev_name, char __user * dir_name,
diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c
index 6b1f6d2..addfd31 100644
--- a/fs/ncpfs/file.c
+++ b/fs/ncpfs/file.c
@@ -17,7 +17,6 @@
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
-#include <linux/smp_lock.h>
#include <linux/ncp_fs.h>
#include "ncplib_kernel.h"
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 5bd03b9..50c6821 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -27,7 +27,6 @@
#include <linux/nfs_mount.h>
#include <linux/nfs4_mount.h>
#include <linux/lockd/bind.h>
-#include <linux/smp_lock.h>
#include <linux/seq_file.h>
#include <linux/mount.h>
#include <linux/nfs_idmap.h>
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 889de60..345aa5c 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -41,7 +41,6 @@
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
-#include <linux/smp_lock.h>
#include <linux/file.h>
#include <linux/pagemap.h>
#include <linux/kref.h>
diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c
index 6ef268f..2347785 100644
--- a/fs/nfs/getroot.c
+++ b/fs/nfs/getroot.c
@@ -25,7 +25,6 @@
#include <linux/nfs_mount.h>
#include <linux/nfs4_mount.h>
#include <linux/lockd/bind.h>
-#include <linux/smp_lock.h>
#include <linux/seq_file.h>
#include <linux/mount.h>
#include <linux/nfs_idmap.h>
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index 7d0371e..45268d6 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -16,7 +16,6 @@
#include <linux/nfs_fs.h>
#include <linux/nfs_page.h>
#include <linux/lockd/bind.h>
-#include <linux/smp_lock.h>
#include <linux/nfs_mount.h>
#include "iostat.h"
diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c
index f5f4430..0505ca1 100644
--- a/fs/nfs/nfs4renewd.c
+++ b/fs/nfs/nfs4renewd.c
@@ -43,7 +43,6 @@
* child task framework of the RPC layer?
*/
-#include <linux/smp_lock.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
#include <linux/sunrpc/sched.h>
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index 1dcf56d..7be0ee2 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -43,7 +43,6 @@
#include <linux/nfs_fs.h>
#include <linux/nfs_page.h>
#include <linux/lockd/bind.h>
-#include <linux/smp_lock.h>
#include "internal.h"
#define NFSDBG_FACILITY NFSDBG_PROC
diff --git a/fs/nfs/symlink.c b/fs/nfs/symlink.c
index bc28213..83e865a 100644
--- a/fs/nfs/symlink.c
+++ b/fs/nfs/symlink.c
@@ -22,7 +22,6 @@
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/string.h>
-#include <linux/smp_lock.h>
#include <linux/namei.h>
/* Symlink caching in the page cache is even more simplistic
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 5d44b8b..de92b95 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -21,7 +21,6 @@
#include <linux/backing-dev.h>
#include <asm/uaccess.h>
-#include <linux/smp_lock.h>
#include "delegation.h"
#include "internal.h"
@@ -225,7 +224,7 @@
struct inode *inode = page->mapping->host;
struct nfs_server *nfss = NFS_SERVER(inode);
- if (atomic_inc_return(&nfss->writeback) >
+ if (atomic_long_inc_return(&nfss->writeback) >
NFS_CONGESTION_ON_THRESH)
set_bdi_congested(&nfss->backing_dev_info, WRITE);
}
@@ -238,7 +237,7 @@
struct nfs_server *nfss = NFS_SERVER(inode);
end_page_writeback(page);
- if (atomic_dec_return(&nfss->writeback) < NFS_CONGESTION_OFF_THRESH) {
+ if (atomic_long_dec_return(&nfss->writeback) < NFS_CONGESTION_OFF_THRESH) {
clear_bdi_congested(&nfss->backing_dev_info, WRITE);
congestion_end(WRITE);
}
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c
index e4a83d7..45aa21c 100644
--- a/fs/nfsd/nfs4idmap.c
+++ b/fs/nfsd/nfs4idmap.c
@@ -46,7 +46,6 @@
#include <linux/nfs4.h>
#include <linux/nfs_fs.h>
#include <linux/nfs_page.h>
-#include <linux/smp_lock.h>
#include <linux/sunrpc/cache.h>
#include <linux/nfsd_idmap.h>
#include <linux/list.h>
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 5d090f1..15809df 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -44,7 +44,6 @@
#include <linux/param.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/fs.h>
#include <linux/namei.h>
#include <linux/vfs.h>
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index 8d995bc..739dd3c 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -10,7 +10,6 @@
*/
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/fs.h>
#include <linux/unistd.h>
#include <linux/string.h>
diff --git a/fs/ntfs/dir.c b/fs/ntfs/dir.c
index 74f99a6..34314b3 100644
--- a/fs/ntfs/dir.c
+++ b/fs/ntfs/dir.c
@@ -20,7 +20,6 @@
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
#include "dir.h"
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index dbbac55..621de36 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -2129,28 +2129,13 @@
struct address_space *mapping = file->f_mapping;
struct inode *inode = mapping->host;
loff_t pos;
- unsigned long seg;
size_t count; /* after file limit checks */
ssize_t written, err;
count = 0;
- for (seg = 0; seg < nr_segs; seg++) {
- const struct iovec *iv = &iov[seg];
- /*
- * If any segment has a negative length, or the cumulative
- * length ever wraps negative then return -EINVAL.
- */
- count += iv->iov_len;
- if (unlikely((ssize_t)(count|iv->iov_len) < 0))
- return -EINVAL;
- if (access_ok(VERIFY_READ, iv->iov_base, iv->iov_len))
- continue;
- if (!seg)
- return -EFAULT;
- nr_segs = seg;
- count -= iv->iov_len; /* This segment is no good */
- break;
- }
+ err = generic_segment_checks(iov, &nr_segs, &count, VERIFY_READ);
+ if (err)
+ return err;
pos = *ppos;
vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
/* We can write back this queue in page reclaim. */
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
index f8bf8da..074791c 100644
--- a/fs/ntfs/inode.c
+++ b/fs/ntfs/inode.c
@@ -27,7 +27,6 @@
#include <linux/pagemap.h>
#include <linux/quotaops.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include "aops.h"
#include "attrib.h"
diff --git a/fs/ocfs2/dlm/dlmfs.c b/fs/ocfs2/dlm/dlmfs.c
index d4e46d0..5671cf9 100644
--- a/fs/ocfs2/dlm/dlmfs.c
+++ b/fs/ocfs2/dlm/dlmfs.c
@@ -42,7 +42,6 @@
#include <linux/highmem.h>
#include <linux/init.h>
#include <linux/string.h>
-#include <linux/smp_lock.h>
#include <linux/backing-dev.h>
#include <asm/uaccess.h>
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index 024777a..d1bd305 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -27,7 +27,6 @@
#include <linux/slab.h>
#include <linux/highmem.h>
#include <linux/mm.h>
-#include <linux/smp_lock.h>
#include <linux/crc32.h>
#include <linux/kthread.h>
#include <linux/pagemap.h>
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c
index bc844bf..c53a676 100644
--- a/fs/ocfs2/inode.c
+++ b/fs/ocfs2/inode.c
@@ -28,7 +28,6 @@
#include <linux/slab.h>
#include <linux/highmem.h>
#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
#include <asm/byteorder.h>
diff --git a/fs/ocfs2/slot_map.c b/fs/ocfs2/slot_map.c
index d921a28..d8b7906 100644
--- a/fs/ocfs2/slot_map.c
+++ b/fs/ocfs2/slot_map.c
@@ -26,7 +26,6 @@
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/highmem.h>
-#include <linux/smp_lock.h>
#define MLOG_MASK_PREFIX ML_SUPER
#include <cluster/masklog.h>
diff --git a/fs/ocfs2/vote.c b/fs/ocfs2/vote.c
index 4f82a2f..66a13ee 100644
--- a/fs/ocfs2/vote.c
+++ b/fs/ocfs2/vote.c
@@ -26,7 +26,6 @@
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/highmem.h>
-#include <linux/smp_lock.h>
#include <linux/kthread.h>
#include <cluster/heartbeat.h>
diff --git a/fs/open.c b/fs/open.c
index c989fb4..ca9981c 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -7,7 +7,6 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/file.h>
-#include <linux/smp_lock.h>
#include <linux/quotaops.h>
#include <linux/fsnotify.h>
#include <linux/module.h>
diff --git a/fs/partitions/Kconfig b/fs/partitions/Kconfig
index 6e8bb66..0120704 100644
--- a/fs/partitions/Kconfig
+++ b/fs/partitions/Kconfig
@@ -236,3 +236,12 @@
help
Say Y here if you would like to use hard disks under Linux which
were partitioned using EFI GPT.
+
+config SYSV68_PARTITION
+ bool "SYSV68 partition table support" if PARTITION_ADVANCED
+ default y if M68K
+ help
+ Say Y here if you would like to be able to read the hard disk
+ partition table format used by Motorola Delta machines (using
+ sysv68).
+ Otherwise, say N.
diff --git a/fs/partitions/Makefile b/fs/partitions/Makefile
index 67e665f..03af8ea 100644
--- a/fs/partitions/Makefile
+++ b/fs/partitions/Makefile
@@ -17,3 +17,4 @@
obj-$(CONFIG_IBM_PARTITION) += ibm.o
obj-$(CONFIG_EFI_PARTITION) += efi.o
obj-$(CONFIG_KARMA_PARTITION) += karma.o
+obj-$(CONFIG_SYSV68_PARTITION) += sysv68.o
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 6b9dae3..9a3a058 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -34,6 +34,7 @@
#include "ultrix.h"
#include "efi.h"
#include "karma.h"
+#include "sysv68.h"
#ifdef CONFIG_BLK_DEV_MD
extern void md_autodetect_dev(dev_t dev);
@@ -105,6 +106,9 @@
#ifdef CONFIG_KARMA_PARTITION
karma_partition,
#endif
+#ifdef CONFIG_SYSV68_PARTITION
+ sysv68_partition,
+#endif
NULL
};
diff --git a/fs/partitions/sysv68.c b/fs/partitions/sysv68.c
new file mode 100644
index 0000000..4eba27b
--- /dev/null
+++ b/fs/partitions/sysv68.c
@@ -0,0 +1,92 @@
+/*
+ * fs/partitions/sysv68.c
+ *
+ * Copyright (C) 2007 Philippe De Muyter <phdm@macqel.be>
+ */
+
+#include "check.h"
+#include "sysv68.h"
+
+/*
+ * Volume ID structure: on first 256-bytes sector of disk
+ */
+
+struct volumeid {
+ u8 vid_unused[248];
+ u8 vid_mac[8]; /* ASCII string "MOTOROLA" */
+};
+
+/*
+ * config block: second 256-bytes sector on disk
+ */
+
+struct dkconfig {
+ u8 ios_unused0[128];
+ __be32 ios_slcblk; /* Slice table block number */
+ __be16 ios_slccnt; /* Number of entries in slice table */
+ u8 ios_unused1[122];
+};
+
+/*
+ * combined volumeid and dkconfig block
+ */
+
+struct dkblk0 {
+ struct volumeid dk_vid;
+ struct dkconfig dk_ios;
+};
+
+/*
+ * Slice Table Structure
+ */
+
+struct slice {
+ __be32 nblocks; /* slice size (in blocks) */
+ __be32 blkoff; /* block offset of slice */
+};
+
+
+int sysv68_partition(struct parsed_partitions *state, struct block_device *bdev)
+{
+ int i, slices;
+ int slot = 1;
+ Sector sect;
+ unsigned char *data;
+ struct dkblk0 *b;
+ struct slice *slice;
+
+ data = read_dev_sector(bdev, 0, §);
+ if (!data)
+ return -1;
+
+ b = (struct dkblk0 *)data;
+ if (memcmp(b->dk_vid.vid_mac, "MOTOROLA", sizeof(b->dk_vid.vid_mac))) {
+ put_dev_sector(sect);
+ return 0;
+ }
+ slices = be16_to_cpu(b->dk_ios.ios_slccnt);
+ i = be32_to_cpu(b->dk_ios.ios_slcblk);
+ put_dev_sector(sect);
+
+ data = read_dev_sector(bdev, i, §);
+ if (!data)
+ return -1;
+
+ slices -= 1; /* last slice is the whole disk */
+ printk("sysV68: %s(s%u)", state->name, slices);
+ slice = (struct slice *)data;
+ for (i = 0; i < slices; i++, slice++) {
+ if (slot == state->limit)
+ break;
+ if (be32_to_cpu(slice->nblocks)) {
+ put_partition(state, slot,
+ be32_to_cpu(slice->blkoff),
+ be32_to_cpu(slice->nblocks));
+ printk("(s%u)", i);
+ }
+ slot++;
+ }
+ printk("\n");
+ put_dev_sector(sect);
+ return 1;
+}
diff --git a/fs/partitions/sysv68.h b/fs/partitions/sysv68.h
new file mode 100644
index 0000000..fa733f6
--- /dev/null
+++ b/fs/partitions/sysv68.h
@@ -0,0 +1 @@
+extern int sysv68_partition(struct parsed_partitions *state, struct block_device *bdev);
diff --git a/fs/pipe.c b/fs/pipe.c
index ebafde7..3a89592 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -841,8 +841,18 @@
return 0;
}
+/*
+ * pipefs_dname() is called from d_path().
+ */
+static char *pipefs_dname(struct dentry *dentry, char *buffer, int buflen)
+{
+ return dynamic_dname(dentry, buffer, buflen, "pipe:[%lu]",
+ dentry->d_inode->i_ino);
+}
+
static struct dentry_operations pipefs_dentry_operations = {
.d_delete = pipefs_delete_dentry,
+ .d_dname = pipefs_dname,
};
static struct inode * get_pipe_inode(void)
@@ -888,8 +898,7 @@
struct inode *inode;
struct file *f;
struct dentry *dentry;
- char name[32];
- struct qstr this;
+ struct qstr name = { .name = "" };
f = get_empty_filp();
if (!f)
@@ -899,11 +908,8 @@
if (!inode)
goto err_file;
- this.len = sprintf(name, "[%lu]", inode->i_ino);
- this.name = name;
- this.hash = 0;
err = -ENOMEM;
- dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this);
+ dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &name);
if (!dentry)
goto err_inode;
diff --git a/fs/pnode.c b/fs/pnode.c
index 56aacea..89940f2 100644
--- a/fs/pnode.c
+++ b/fs/pnode.c
@@ -59,7 +59,7 @@
} else {
struct list_head *p = &mnt->mnt_slave_list;
while (!list_empty(p)) {
- slave_mnt = list_entry(p->next,
+ slave_mnt = list_first_entry(p,
struct vfsmount, mnt_slave);
list_del_init(&slave_mnt->mnt_slave);
slave_mnt->mnt_master = NULL;
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 07c9cdb..74f30e0 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -410,9 +410,9 @@
/* convert nsec -> ticks */
start_time = nsec_to_clock_t(start_time);
- res = sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \
+ res = sprintf(buffer,"%d (%s) %c %d %d %d %d %d %u %lu \
%lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \
-%lu %lu %lu %lu %lu %lu %lu %lu %d %d %lu %lu %llu\n",
+%lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu\n",
task->pid,
tcomm,
state,
diff --git a/fs/proc/base.c b/fs/proc/base.c
index ec158dd..3c41149 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -61,9 +61,9 @@
#include <linux/namei.h>
#include <linux/mnt_namespace.h>
#include <linux/mm.h>
-#include <linux/smp_lock.h>
#include <linux/rcupdate.h>
#include <linux/kallsyms.h>
+#include <linux/module.h>
#include <linux/mount.h>
#include <linux/security.h>
#include <linux/ptrace.h>
@@ -90,8 +90,8 @@
#define PROC_NUMBUF 13
struct pid_entry {
- int len;
char *name;
+ int len;
mode_t mode;
const struct inode_operations *iop;
const struct file_operations *fop;
@@ -99,8 +99,8 @@
};
#define NOD(NAME, MODE, IOP, FOP, OP) { \
- .len = sizeof(NAME) - 1, \
.name = (NAME), \
+ .len = sizeof(NAME) - 1, \
.mode = MODE, \
.iop = IOP, \
.fop = FOP, \
@@ -123,6 +123,9 @@
NULL, &proc_info_file_operations, \
{ .proc_read = &proc_##OTYPE } )
+int maps_protect;
+EXPORT_SYMBOL(maps_protect);
+
static struct fs_struct *get_fs_struct(struct task_struct *task)
{
struct fs_struct *fs;
@@ -275,17 +278,15 @@
*/
static int proc_pid_wchan(struct task_struct *task, char *buffer)
{
- char *modname;
- const char *sym_name;
- unsigned long wchan, size, offset;
- char namebuf[KSYM_NAME_LEN+1];
+ unsigned long wchan;
+ char symname[KSYM_NAME_LEN+1];
wchan = get_wchan(task);
- sym_name = kallsyms_lookup(wchan, &size, &offset, &modname, namebuf);
- if (sym_name)
- return sprintf(buffer, "%s", sym_name);
- return sprintf(buffer, "%lu", wchan);
+ if (lookup_symbol_name(wchan, symname) < 0)
+ return sprintf(buffer, "%lu", wchan);
+ else
+ return sprintf(buffer, "%s", symname);
}
#endif /* CONFIG_KALLSYMS */
@@ -310,7 +311,9 @@
struct timespec uptime;
do_posix_clock_monotonic_gettime(&uptime);
+ read_lock(&tasklist_lock);
points = badness(task, uptime.tv_sec);
+ read_unlock(&tasklist_lock);
return sprintf(buffer, "%lu\n", points);
}
@@ -344,11 +347,8 @@
return -EPERM;
error = inode_change_ok(inode, attr);
- if (!error) {
- error = security_inode_setattr(dentry, attr);
- if (!error)
- error = inode_setattr(inode, attr);
- }
+ if (!error)
+ error = inode_setattr(inode, attr);
return error;
}
@@ -660,7 +660,6 @@
char buffer[PROC_NUMBUF];
size_t len;
int oom_adjust;
- loff_t __ppos = *ppos;
if (!task)
return -ESRCH;
@@ -668,14 +667,8 @@
put_task_struct(task);
len = snprintf(buffer, sizeof(buffer), "%i\n", oom_adjust);
- if (__ppos >= len)
- return 0;
- if (count > len-__ppos)
- count = len-__ppos;
- if (copy_to_user(buf, buffer + __ppos, count))
- return -EFAULT;
- *ppos = __ppos + count;
- return count;
+
+ return simple_read_from_buffer(buf, count, ppos, buffer, len);
}
static ssize_t oom_adjust_write(struct file *file, const char __user *buf,
@@ -823,7 +816,6 @@
{
struct task_struct *tsk = get_proc_task(file->f_dentry->d_inode);
char __buf[20];
- loff_t __ppos = *ppos;
size_t len;
if (!tsk)
@@ -831,14 +823,8 @@
/* no need to print the trailing zero, so use only len */
len = sprintf(__buf, "%u\n", tsk->seccomp.mode);
put_task_struct(tsk);
- if (__ppos >= len)
- return 0;
- if (count > len - __ppos)
- count = len - __ppos;
- if (copy_to_user(buf, __buf + __ppos, count))
- return -EFAULT;
- *ppos = __ppos + count;
- return count;
+
+ return simple_read_from_buffer(buf, count, ppos, __buf, len);
}
static ssize_t seccomp_write(struct file *file, const char __user *buf,
@@ -897,7 +883,6 @@
char buffer[PROC_NUMBUF];
size_t len;
int make_it_fail;
- loff_t __ppos = *ppos;
if (!task)
return -ESRCH;
@@ -905,14 +890,8 @@
put_task_struct(task);
len = snprintf(buffer, sizeof(buffer), "%i\n", make_it_fail);
- if (__ppos >= len)
- return 0;
- if (count > len-__ppos)
- count = len-__ppos;
- if (copy_to_user(buf, buffer + __ppos, count))
- return -EFAULT;
- *ppos = __ppos + count;
- return count;
+
+ return simple_read_from_buffer(buf, count, ppos, buffer, len);
}
static ssize_t proc_fault_inject_write(struct file * file,
@@ -975,7 +954,7 @@
if (!tmp)
return -ENOMEM;
-
+
inode = dentry->d_inode;
path = d_path(dentry, mnt, tmp, PAGE_SIZE);
len = PTR_ERR(path);
@@ -1155,7 +1134,8 @@
/* Lookups */
-typedef struct dentry *instantiate_t(struct inode *, struct dentry *, struct task_struct *, void *);
+typedef struct dentry *instantiate_t(struct inode *, struct dentry *,
+ struct task_struct *, const void *);
/*
* Fill a directory entry.
@@ -1171,7 +1151,7 @@
*/
static int proc_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
char *name, int len,
- instantiate_t instantiate, struct task_struct *task, void *ptr)
+ instantiate_t instantiate, struct task_struct *task, const void *ptr)
{
struct dentry *child, *dir = filp->f_path.dentry;
struct inode *inode;
@@ -1233,7 +1213,10 @@
return ~0U;
}
-static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
+#define PROC_FDINFO_MAX 64
+
+static int proc_fd_info(struct inode *inode, struct dentry **dentry,
+ struct vfsmount **mnt, char *info)
{
struct task_struct *task = get_proc_task(inode);
struct files_struct *files = NULL;
@@ -1252,8 +1235,16 @@
spin_lock(&files->file_lock);
file = fcheck_files(files, fd);
if (file) {
- *mnt = mntget(file->f_path.mnt);
- *dentry = dget(file->f_path.dentry);
+ if (mnt)
+ *mnt = mntget(file->f_path.mnt);
+ if (dentry)
+ *dentry = dget(file->f_path.dentry);
+ if (info)
+ snprintf(info, PROC_FDINFO_MAX,
+ "pos:\t%lli\n"
+ "flags:\t0%o\n",
+ (long long) file->f_pos,
+ file->f_flags);
spin_unlock(&files->file_lock);
put_files_struct(files);
return 0;
@@ -1264,6 +1255,12 @@
return -ENOENT;
}
+static int proc_fd_link(struct inode *inode, struct dentry **dentry,
+ struct vfsmount **mnt)
+{
+ return proc_fd_info(inode, dentry, mnt, NULL);
+}
+
static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
{
struct inode *inode = dentry->d_inode;
@@ -1306,9 +1303,9 @@
};
static struct dentry *proc_fd_instantiate(struct inode *dir,
- struct dentry *dentry, struct task_struct *task, void *ptr)
+ struct dentry *dentry, struct task_struct *task, const void *ptr)
{
- unsigned fd = *(unsigned *)ptr;
+ unsigned fd = *(const unsigned *)ptr;
struct file *file;
struct files_struct *files;
struct inode *inode;
@@ -1359,7 +1356,9 @@
goto out;
}
-static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, struct nameidata *nd)
+static struct dentry *proc_lookupfd_common(struct inode *dir,
+ struct dentry *dentry,
+ instantiate_t instantiate)
{
struct task_struct *task = get_proc_task(dir);
unsigned fd = name_to_int(dentry);
@@ -1370,23 +1369,15 @@
if (fd == ~0U)
goto out;
- result = proc_fd_instantiate(dir, dentry, task, &fd);
+ result = instantiate(dir, dentry, task, &fd);
out:
put_task_struct(task);
out_no_task:
return result;
}
-static int proc_fd_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
- struct task_struct *task, int fd)
-{
- char name[PROC_NUMBUF];
- int len = snprintf(name, sizeof(name), "%d", fd);
- return proc_fill_cache(filp, dirent, filldir, name, len,
- proc_fd_instantiate, task, &fd);
-}
-
-static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
+static int proc_readfd_common(struct file * filp, void * dirent,
+ filldir_t filldir, instantiate_t instantiate)
{
struct dentry *dentry = filp->f_path.dentry;
struct inode *inode = dentry->d_inode;
@@ -1422,12 +1413,17 @@
for (fd = filp->f_pos-2;
fd < fdt->max_fds;
fd++, filp->f_pos++) {
+ char name[PROC_NUMBUF];
+ int len;
if (!fcheck_files(files, fd))
continue;
rcu_read_unlock();
- if (proc_fd_fill_cache(filp, dirent, filldir, p, fd) < 0) {
+ len = snprintf(name, sizeof(name), "%d", fd);
+ if (proc_fill_cache(filp, dirent, filldir,
+ name, len, instantiate,
+ p, &fd) < 0) {
rcu_read_lock();
break;
}
@@ -1442,23 +1438,119 @@
return retval;
}
+static struct dentry *proc_lookupfd(struct inode *dir, struct dentry *dentry,
+ struct nameidata *nd)
+{
+ return proc_lookupfd_common(dir, dentry, proc_fd_instantiate);
+}
+
+static int proc_readfd(struct file *filp, void *dirent, filldir_t filldir)
+{
+ return proc_readfd_common(filp, dirent, filldir, proc_fd_instantiate);
+}
+
+static ssize_t proc_fdinfo_read(struct file *file, char __user *buf,
+ size_t len, loff_t *ppos)
+{
+ char tmp[PROC_FDINFO_MAX];
+ int err = proc_fd_info(file->f_path.dentry->d_inode, NULL, NULL, tmp);
+ if (!err)
+ err = simple_read_from_buffer(buf, len, ppos, tmp, strlen(tmp));
+ return err;
+}
+
+static const struct file_operations proc_fdinfo_file_operations = {
+ .open = nonseekable_open,
+ .read = proc_fdinfo_read,
+};
+
static const struct file_operations proc_fd_operations = {
.read = generic_read_dir,
.readdir = proc_readfd,
};
/*
+ * /proc/pid/fd needs a special permission handler so that a process can still
+ * access /proc/self/fd after it has executed a setuid().
+ */
+static int proc_fd_permission(struct inode *inode, int mask,
+ struct nameidata *nd)
+{
+ int rv;
+
+ rv = generic_permission(inode, mask, NULL);
+ if (rv == 0)
+ return 0;
+ if (task_pid(current) == proc_pid(inode))
+ rv = 0;
+ return rv;
+}
+
+/*
* proc directories can do almost nothing..
*/
static const struct inode_operations proc_fd_inode_operations = {
.lookup = proc_lookupfd,
+ .permission = proc_fd_permission,
.setattr = proc_setattr,
};
-static struct dentry *proc_pident_instantiate(struct inode *dir,
- struct dentry *dentry, struct task_struct *task, void *ptr)
+static struct dentry *proc_fdinfo_instantiate(struct inode *dir,
+ struct dentry *dentry, struct task_struct *task, const void *ptr)
{
- struct pid_entry *p = ptr;
+ unsigned fd = *(unsigned *)ptr;
+ struct inode *inode;
+ struct proc_inode *ei;
+ struct dentry *error = ERR_PTR(-ENOENT);
+
+ inode = proc_pid_make_inode(dir->i_sb, task);
+ if (!inode)
+ goto out;
+ ei = PROC_I(inode);
+ ei->fd = fd;
+ inode->i_mode = S_IFREG | S_IRUSR;
+ inode->i_fop = &proc_fdinfo_file_operations;
+ dentry->d_op = &tid_fd_dentry_operations;
+ d_add(dentry, inode);
+ /* Close the race of the process dying before we return the dentry */
+ if (tid_fd_revalidate(dentry, NULL))
+ error = NULL;
+
+ out:
+ return error;
+}
+
+static struct dentry *proc_lookupfdinfo(struct inode *dir,
+ struct dentry *dentry,
+ struct nameidata *nd)
+{
+ return proc_lookupfd_common(dir, dentry, proc_fdinfo_instantiate);
+}
+
+static int proc_readfdinfo(struct file *filp, void *dirent, filldir_t filldir)
+{
+ return proc_readfd_common(filp, dirent, filldir,
+ proc_fdinfo_instantiate);
+}
+
+static const struct file_operations proc_fdinfo_operations = {
+ .read = generic_read_dir,
+ .readdir = proc_readfdinfo,
+};
+
+/*
+ * proc directories can do almost nothing..
+ */
+static const struct inode_operations proc_fdinfo_inode_operations = {
+ .lookup = proc_lookupfdinfo,
+ .setattr = proc_setattr,
+};
+
+
+static struct dentry *proc_pident_instantiate(struct inode *dir,
+ struct dentry *dentry, struct task_struct *task, const void *ptr)
+{
+ const struct pid_entry *p = ptr;
struct inode *inode;
struct proc_inode *ei;
struct dentry *error = ERR_PTR(-EINVAL);
@@ -1487,13 +1579,13 @@
static struct dentry *proc_pident_lookup(struct inode *dir,
struct dentry *dentry,
- struct pid_entry *ents,
+ const struct pid_entry *ents,
unsigned int nents)
{
struct inode *inode;
struct dentry *error;
struct task_struct *task = get_proc_task(dir);
- struct pid_entry *p, *last;
+ const struct pid_entry *p, *last;
error = ERR_PTR(-ENOENT);
inode = NULL;
@@ -1522,8 +1614,8 @@
return error;
}
-static int proc_pident_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
- struct task_struct *task, struct pid_entry *p)
+static int proc_pident_fill_cache(struct file *filp, void *dirent,
+ filldir_t filldir, struct task_struct *task, const struct pid_entry *p)
{
return proc_fill_cache(filp, dirent, filldir, p->name, p->len,
proc_pident_instantiate, task, p);
@@ -1531,14 +1623,14 @@
static int proc_pident_readdir(struct file *filp,
void *dirent, filldir_t filldir,
- struct pid_entry *ents, unsigned int nents)
+ const struct pid_entry *ents, unsigned int nents)
{
int i;
int pid;
struct dentry *dentry = filp->f_path.dentry;
struct inode *inode = dentry->d_inode;
struct task_struct *task = get_proc_task(inode);
- struct pid_entry *p, *last;
+ const struct pid_entry *p, *last;
ino_t ino;
int ret;
@@ -1653,7 +1745,7 @@
.write = proc_pid_attr_write,
};
-static struct pid_entry attr_dir_stuff[] = {
+static const struct pid_entry attr_dir_stuff[] = {
REG("current", S_IRUGO|S_IWUGO, pid_attr),
REG("prev", S_IRUGO, pid_attr),
REG("exec", S_IRUGO|S_IWUGO, pid_attr),
@@ -1719,7 +1811,7 @@
* that properly belong to the /proc filesystem, as they describe
* describe something that is process related.
*/
-static struct pid_entry proc_base_stuff[] = {
+static const struct pid_entry proc_base_stuff[] = {
NOD("self", S_IFLNK|S_IRWXUGO,
&proc_self_inode_operations, NULL, {}),
};
@@ -1748,9 +1840,9 @@
};
static struct dentry *proc_base_instantiate(struct inode *dir,
- struct dentry *dentry, struct task_struct *task, void *ptr)
+ struct dentry *dentry, struct task_struct *task, const void *ptr)
{
- struct pid_entry *p = ptr;
+ const struct pid_entry *p = ptr;
struct inode *inode;
struct proc_inode *ei;
struct dentry *error = ERR_PTR(-EINVAL);
@@ -1798,7 +1890,7 @@
{
struct dentry *error;
struct task_struct *task = get_proc_task(dir);
- struct pid_entry *p, *last;
+ const struct pid_entry *p, *last;
error = ERR_PTR(-ENOENT);
@@ -1824,8 +1916,8 @@
return error;
}
-static int proc_base_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
- struct task_struct *task, struct pid_entry *p)
+static int proc_base_fill_cache(struct file *filp, void *dirent,
+ filldir_t filldir, struct task_struct *task, const struct pid_entry *p)
{
return proc_fill_cache(filp, dirent, filldir, p->name, p->len,
proc_base_instantiate, task, p);
@@ -1862,9 +1954,10 @@
static const struct file_operations proc_task_operations;
static const struct inode_operations proc_task_inode_operations;
-static struct pid_entry tgid_base_stuff[] = {
+static const struct pid_entry tgid_base_stuff[] = {
DIR("task", S_IRUGO|S_IXUGO, task),
DIR("fd", S_IRUSR|S_IXUSR, fd),
+ DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo),
INF("environ", S_IRUSR, pid_environ),
INF("auxv", S_IRUSR, pid_auxv),
INF("status", S_IRUGO, pid_status),
@@ -2005,7 +2098,7 @@
static struct dentry *proc_pid_instantiate(struct inode *dir,
struct dentry * dentry,
- struct task_struct *task, void *ptr)
+ struct task_struct *task, const void *ptr)
{
struct dentry *error = ERR_PTR(-ENOENT);
struct inode *inode;
@@ -2018,7 +2111,7 @@
inode->i_op = &proc_tgid_base_inode_operations;
inode->i_fop = &proc_tgid_base_operations;
inode->i_flags|=S_IMMUTABLE;
- inode->i_nlink = 4;
+ inode->i_nlink = 5;
#ifdef CONFIG_SECURITY
inode->i_nlink += 1;
#endif
@@ -2120,7 +2213,7 @@
goto out_no_task;
for (; nr < ARRAY_SIZE(proc_base_stuff); filp->f_pos++, nr++) {
- struct pid_entry *p = &proc_base_stuff[nr];
+ const struct pid_entry *p = &proc_base_stuff[nr];
if (proc_base_fill_cache(filp, dirent, filldir, reaper, p) < 0)
goto out;
}
@@ -2146,8 +2239,9 @@
/*
* Tasks
*/
-static struct pid_entry tid_base_stuff[] = {
+static const struct pid_entry tid_base_stuff[] = {
DIR("fd", S_IRUSR|S_IXUSR, fd),
+ DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo),
INF("environ", S_IRUSR, pid_environ),
INF("auxv", S_IRUSR, pid_auxv),
INF("status", S_IRUGO, pid_status),
@@ -2216,7 +2310,7 @@
};
static struct dentry *proc_task_instantiate(struct inode *dir,
- struct dentry *dentry, struct task_struct *task, void *ptr)
+ struct dentry *dentry, struct task_struct *task, const void *ptr)
{
struct dentry *error = ERR_PTR(-ENOENT);
struct inode *inode;
@@ -2228,7 +2322,7 @@
inode->i_op = &proc_tid_base_inode_operations;
inode->i_fop = &proc_tid_base_operations;
inode->i_flags|=S_IMMUTABLE;
- inode->i_nlink = 3;
+ inode->i_nlink = 4;
#ifdef CONFIG_SECURITY
inode->i_nlink += 1;
#endif
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index 775fb21..8a40e15 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -398,6 +398,7 @@
if (!memcmp(dentry->d_name.name, de->name, de->namelen)) {
unsigned int ino = de->low_ino;
+ de_get(de);
spin_unlock(&proc_subdir_lock);
error = -EINVAL;
inode = proc_get_inode(dir->i_sb, ino, de);
@@ -414,6 +415,7 @@
d_add(dentry, inode);
return NULL;
}
+ de_put(de);
return ERR_PTR(error);
}
@@ -476,14 +478,21 @@
}
do {
+ struct proc_dir_entry *next;
+
/* filldir passes info to user space */
+ de_get(de);
spin_unlock(&proc_subdir_lock);
if (filldir(dirent, de->name, de->namelen, filp->f_pos,
- de->low_ino, de->mode >> 12) < 0)
+ de->low_ino, de->mode >> 12) < 0) {
+ de_put(de);
goto out;
+ }
spin_lock(&proc_subdir_lock);
filp->f_pos++;
- de = de->next;
+ next = de->next;
+ de_put(de);
+ de = next;
} while (de);
spin_unlock(&proc_subdir_lock);
}
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 22b1158..b817190 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -21,7 +21,7 @@
#include "internal.h"
-static inline struct proc_dir_entry * de_get(struct proc_dir_entry *de)
+struct proc_dir_entry *de_get(struct proc_dir_entry *de)
{
if (de)
atomic_inc(&de->count);
@@ -31,7 +31,7 @@
/*
* Decrements the use count and checks for deferred deletion.
*/
-static void de_put(struct proc_dir_entry *de)
+void de_put(struct proc_dir_entry *de)
{
if (de) {
lock_kernel();
@@ -146,13 +146,6 @@
{
struct inode * inode;
- /*
- * Increment the use count so the dir entry can't disappear.
- */
- de_get(de);
-
- WARN_ON(de && de->deleted);
-
if (de != NULL && !try_module_get(de->owner))
goto out_mod;
@@ -184,7 +177,6 @@
if (de != NULL)
module_put(de->owner);
out_mod:
- de_put(de);
return NULL;
}
@@ -199,6 +191,7 @@
s->s_op = &proc_sops;
s->s_time_gran = 1;
+ de_get(&proc_root);
root_inode = proc_get_inode(s, PROC_ROOT_INO, &proc_root);
if (!root_inode)
goto out_no_root;
@@ -212,6 +205,7 @@
out_no_root:
printk("proc_read_super: get root inode failed\n");
iput(root_inode);
+ de_put(&proc_root);
return -ENOMEM;
}
MODULE_LICENSE("GPL");
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index f771889..b215c35 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -37,6 +37,8 @@
extern int nommu_vma_show(struct seq_file *, struct vm_area_struct *);
#endif
+extern int maps_protect;
+
extern void create_seq_entry(char *name, mode_t mode, const struct file_operations *f);
extern int proc_exe_link(struct inode *, struct dentry **, struct vfsmount **);
extern int proc_tid_stat(struct task_struct *, char *);
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index 75ec652..5fd49e4 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -35,7 +35,6 @@
#include <linux/signal.h>
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/seq_file.h>
#include <linux/times.h>
#include <linux/profile.h>
@@ -429,18 +428,11 @@
return ret;
}
-static int slabstats_release(struct inode *inode, struct file *file)
-{
- struct seq_file *m = file->private_data;
- kfree(m->private);
- return seq_release(inode, file);
-}
-
static const struct file_operations proc_slabstats_operations = {
.open = slabstats_open,
.read = seq_read,
.llseek = seq_lseek,
- .release = slabstats_release,
+ .release = seq_release_private,
};
#endif
#endif
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
index 20e8cbb..680c429 100644
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -429,11 +429,8 @@
return -EPERM;
error = inode_change_ok(inode, attr);
- if (!error) {
- error = security_inode_setattr(dentry, attr);
- if (!error)
- error = inode_setattr(inode, attr);
- }
+ if (!error)
+ error = inode_setattr(inode, attr);
return error;
}
diff --git a/fs/proc/proc_tty.c b/fs/proc/proc_tty.c
index c1bbfbe..b3a473b 100644
--- a/fs/proc/proc_tty.c
+++ b/fs/proc/proc_tty.c
@@ -108,6 +108,8 @@
{
struct list_head *p;
loff_t l = *pos;
+
+ mutex_lock(&tty_mutex);
list_for_each(p, &tty_drivers)
if (!l--)
return list_entry(p, struct tty_driver, tty_drivers);
@@ -124,6 +126,7 @@
static void t_stop(struct seq_file *m, void *v)
{
+ mutex_unlock(&tty_mutex);
}
static struct seq_operations tty_drivers_op = {
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 4008c06..c24d81a 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -3,6 +3,7 @@
#include <linux/mount.h>
#include <linux/seq_file.h>
#include <linux/highmem.h>
+#include <linux/ptrace.h>
#include <linux/pagemap.h>
#include <linux/mempolicy.h>
@@ -142,6 +143,9 @@
dev_t dev = 0;
int len;
+ if (maps_protect && !ptrace_may_attach(task))
+ return -EACCES;
+
if (file) {
struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
dev = inode->i_sb->s_dev;
@@ -512,11 +516,22 @@
#ifdef CONFIG_NUMA
extern int show_numa_map(struct seq_file *m, void *v);
+static int show_numa_map_checked(struct seq_file *m, void *v)
+{
+ struct proc_maps_private *priv = m->private;
+ struct task_struct *task = priv->task;
+
+ if (maps_protect && !ptrace_may_attach(task))
+ return -EACCES;
+
+ return show_numa_map(m, v);
+}
+
static struct seq_operations proc_pid_numa_maps_op = {
.start = m_start,
.next = m_next,
.stop = m_stop,
- .show = show_numa_map
+ .show = show_numa_map_checked
};
static int numa_maps_open(struct inode *inode, struct file *file)
diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
index 7cddf6b..d8b8c71 100644
--- a/fs/proc/task_nommu.c
+++ b/fs/proc/task_nommu.c
@@ -2,6 +2,7 @@
#include <linux/mm.h>
#include <linux/file.h>
#include <linux/mount.h>
+#include <linux/ptrace.h>
#include <linux/seq_file.h>
#include "internal.h"
@@ -143,6 +144,12 @@
static int show_map(struct seq_file *m, void *_vml)
{
struct vm_list_struct *vml = _vml;
+ struct proc_maps_private *priv = m->private;
+ struct task_struct *task = priv->task;
+
+ if (maps_protect && !ptrace_may_attach(task))
+ return -EACCES;
+
return nommu_vma_show(m, vml->vma);
}
diff --git a/fs/quota.c b/fs/quota.c
index b9dae76..e9d88fd0 100644
--- a/fs/quota.c
+++ b/fs/quota.c
@@ -11,7 +11,6 @@
#include <asm/current.h>
#include <asm/uaccess.h>
#include <linux/kernel.h>
-#include <linux/smp_lock.h>
#include <linux/security.h>
#include <linux/syscalls.h>
#include <linux/buffer_head.h>
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c
index d3fd7c6..3b481d5 100644
--- a/fs/ramfs/file-nommu.c
+++ b/fs/ramfs/file-nommu.c
@@ -16,7 +16,6 @@
#include <linux/highmem.h>
#include <linux/init.h>
#include <linux/string.h>
-#include <linux/smp_lock.h>
#include <linux/backing-dev.h>
#include <linux/ramfs.h>
#include <linux/quotaops.h>
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c
index ff1f763..4ace5d7 100644
--- a/fs/ramfs/inode.c
+++ b/fs/ramfs/inode.c
@@ -30,7 +30,6 @@
#include <linux/time.h>
#include <linux/init.h>
#include <linux/string.h>
-#include <linux/smp_lock.h>
#include <linux/backing-dev.h>
#include <linux/ramfs.h>
diff --git a/fs/read_write.c b/fs/read_write.c
index 1f8dc37..4d03008 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -37,10 +37,10 @@
mutex_lock(&inode->i_mutex);
switch (origin) {
- case 2:
+ case SEEK_END:
offset += inode->i_size;
break;
- case 1:
+ case SEEK_CUR:
offset += file->f_pos;
}
retval = -EINVAL;
@@ -63,10 +63,10 @@
lock_kernel();
switch (origin) {
- case 2:
+ case SEEK_END:
offset += i_size_read(file->f_path.dentry->d_inode);
break;
- case 1:
+ case SEEK_CUR:
offset += file->f_pos;
}
retval = -EINVAL;
@@ -94,10 +94,10 @@
lock_kernel();
switch (origin) {
- case 2:
+ case SEEK_END:
offset += i_size_read(file->f_path.dentry->d_inode);
break;
- case 1:
+ case SEEK_CUR:
offset += file->f_pos;
}
retval = -EINVAL;
@@ -139,7 +139,7 @@
goto bad;
retval = -EINVAL;
- if (origin <= 2) {
+ if (origin <= SEEK_MAX) {
loff_t res = vfs_llseek(file, offset, origin);
retval = res;
if (res != (loff_t)retval)
@@ -166,7 +166,7 @@
goto bad;
retval = -EINVAL;
- if (origin > 2)
+ if (origin > SEEK_MAX)
goto out_putf;
offset = vfs_llseek(file, ((loff_t) offset_high << 32) | offset_low,
diff --git a/fs/readdir.c b/fs/readdir.c
index f39f5b3..efe52e6 100644
--- a/fs/readdir.c
+++ b/fs/readdir.c
@@ -4,13 +4,13 @@
* Copyright (C) 1995 Linus Torvalds
*/
+#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/time.h>
#include <linux/mm.h>
#include <linux/errno.h>
#include <linux/stat.h>
#include <linux/file.h>
-#include <linux/smp_lock.h>
#include <linux/fs.h>
#include <linux/dirent.h>
#include <linux/security.h>
@@ -52,7 +52,6 @@
* case (the low-level handlers don't need to care about this).
*/
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
-#define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1))
#ifdef __ARCH_WANT_OLD_READDIR
@@ -147,7 +146,7 @@
struct linux_dirent __user * dirent;
struct getdents_callback * buf = (struct getdents_callback *) __buf;
unsigned long d_ino;
- int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 2);
+ int reclen = ALIGN(NAME_OFFSET(dirent) + namlen + 2, sizeof(long));
buf->error = -EINVAL; /* only used if we fail.. */
if (reclen > buf->count)
@@ -220,8 +219,6 @@
return error;
}
-#define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1))
-
struct getdents_callback64 {
struct linux_dirent64 __user * current_dir;
struct linux_dirent64 __user * previous;
@@ -234,7 +231,7 @@
{
struct linux_dirent64 __user *dirent;
struct getdents_callback64 * buf = (struct getdents_callback64 *) __buf;
- int reclen = ROUND_UP64(NAME_OFFSET(dirent) + namlen + 1);
+ int reclen = ALIGN(NAME_OFFSET(dirent) + namlen + 1, sizeof(u64));
buf->error = -EINVAL; /* only used if we fail.. */
if (reclen > buf->count)
diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c
index 96a2f88..9c23fee 100644
--- a/fs/reiserfs/dir.c
+++ b/fs/reiserfs/dir.c
@@ -7,7 +7,6 @@
#include <linux/fs.h>
#include <linux/reiserfs_fs.h>
#include <linux/stat.h>
-#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
#include <asm/uaccess.h>
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index abfada2..ab45db5 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -6,7 +6,6 @@
#include <linux/reiserfs_fs.h>
#include <linux/reiserfs_acl.h>
#include <linux/reiserfs_xattr.h>
-#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <linux/pagemap.h>
#include <linux/swap.h>
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index 7280a23..e073fd8 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -2918,7 +2918,7 @@
set_current_state(TASK_UNINTERRUPTIBLE);
if (test_bit(J_WRITERS_QUEUED, &journal->j_state))
schedule();
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(&journal->j_join_wait, &wait);
}
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index a216184..b378eea 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -16,7 +16,6 @@
#include <linux/reiserfs_fs.h>
#include <linux/reiserfs_acl.h>
#include <linux/reiserfs_xattr.h>
-#include <linux/smp_lock.h>
#include <linux/quotaops.h>
#define INC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) { inc_nlink(i); if (i->i_nlink >= REISERFS_LINK_MAX) i->i_nlink=1; }
diff --git a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c
index ecc9943..9aa7a06 100644
--- a/fs/reiserfs/procfs.c
+++ b/fs/reiserfs/procfs.c
@@ -16,11 +16,10 @@
#include <asm/uaccess.h>
#include <linux/reiserfs_fs.h>
#include <linux/reiserfs_fs_sb.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
-#if defined( REISERFS_PROC_INFO )
+#ifdef CONFIG_REISERFS_PROC_INFO
/*
* LOCKING:
diff --git a/fs/reiserfs/resize.c b/fs/reiserfs/resize.c
index 3156847..976cc78 100644
--- a/fs/reiserfs/resize.c
+++ b/fs/reiserfs/resize.c
@@ -131,6 +131,10 @@
/* don't use read_bitmap_block since it will cache
* the uninitialized bitmap */
bh = sb_bread(s, i * s->s_blocksize * 8);
+ if (!bh) {
+ vfree(bitmap);
+ return -EIO;
+ }
memset(bh->b_data, 0, sb_blocksize(sb));
reiserfs_test_and_set_le_bit(0, bh->b_data);
reiserfs_cache_bitmap_metadata(s, bh, bitmap + i);
diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c
index afb21ea..b6f1259 100644
--- a/fs/reiserfs/stree.c
+++ b/fs/reiserfs/stree.c
@@ -53,7 +53,6 @@
#include <linux/string.h>
#include <linux/pagemap.h>
#include <linux/reiserfs_fs.h>
-#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
#include <linux/quotaops.h>
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 7054aae..c776214 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -18,7 +18,6 @@
#include <linux/reiserfs_fs.h>
#include <linux/reiserfs_acl.h>
#include <linux/reiserfs_xattr.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/buffer_head.h>
@@ -433,12 +432,13 @@
static void reiserfs_kill_sb(struct super_block *s)
{
if (REISERFS_SB(s)) {
+#ifdef CONFIG_REISERFS_FS_XATTR
if (REISERFS_SB(s)->xattr_root) {
d_invalidate(REISERFS_SB(s)->xattr_root);
dput(REISERFS_SB(s)->xattr_root);
REISERFS_SB(s)->xattr_root = NULL;
}
-
+#endif
if (REISERFS_SB(s)->priv_root) {
d_invalidate(REISERFS_SB(s)->priv_root);
dput(REISERFS_SB(s)->priv_root);
@@ -1562,9 +1562,10 @@
REISERFS_SB(s)->s_alloc_options.preallocmin = 0;
/* Preallocate by 16 blocks (17-1) at once */
REISERFS_SB(s)->s_alloc_options.preallocsize = 17;
+#ifdef CONFIG_REISERFS_FS_XATTR
/* Initialize the rwsem for xattr dir */
init_rwsem(&REISERFS_SB(s)->xattr_dir_sem);
-
+#endif
/* setup default block allocator options */
reiserfs_init_alloc_options(s);
diff --git a/fs/select.c b/fs/select.c
index fe0893a..d862241 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -14,10 +14,10 @@
* of fds to overcome nfds < 16390 descriptors limit (Tigran Aivazian).
*/
+#include <linux/kernel.h>
#include <linux/syscalls.h>
#include <linux/module.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/poll.h>
#include <linux/personality.h> /* for STICKY_TIMEOUTS */
#include <linux/file.h>
@@ -26,7 +26,6 @@
#include <asm/uaccess.h>
-#define ROUND_UP(x,y) (((x)+(y)-1)/(y))
#define DEFAULT_POLLMASK (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)
struct poll_table_page {
@@ -399,7 +398,7 @@
if ((u64)tv.tv_sec >= (u64)MAX_INT64_SECONDS)
timeout = -1; /* infinite */
else {
- timeout = ROUND_UP(tv.tv_usec, USEC_PER_SEC/HZ);
+ timeout = DIV_ROUND_UP(tv.tv_usec, USEC_PER_SEC/HZ);
timeout += tv.tv_sec * HZ;
}
}
@@ -454,7 +453,7 @@
if ((u64)ts.tv_sec >= (u64)MAX_INT64_SECONDS)
timeout = -1; /* infinite */
else {
- timeout = ROUND_UP(ts.tv_nsec, NSEC_PER_SEC/HZ);
+ timeout = DIV_ROUND_UP(ts.tv_nsec, NSEC_PER_SEC/HZ);
timeout += ts.tv_sec * HZ;
}
}
@@ -776,7 +775,7 @@
if ((u64)ts.tv_sec >= (u64)MAX_INT64_SECONDS)
timeout = -1; /* infinite */
else {
- timeout = ROUND_UP(ts.tv_nsec, NSEC_PER_SEC/HZ);
+ timeout = DIV_ROUND_UP(ts.tv_nsec, NSEC_PER_SEC/HZ);
timeout += ts.tv_sec * HZ;
}
}
diff --git a/fs/smbfs/request.c b/fs/smbfs/request.c
index 723f7c6..c288fbe 100644
--- a/fs/smbfs/request.c
+++ b/fs/smbfs/request.c
@@ -6,6 +6,7 @@
* Please add a note about your changes to smbfs in the ChangeLog file.
*/
+#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/slab.h>
@@ -22,8 +23,6 @@
/* #define SMB_SLAB_DEBUG (SLAB_RED_ZONE | SLAB_POISON) */
#define SMB_SLAB_DEBUG 0
-#define ROUND_UP(x) (((x)+3) & ~3)
-
/* cache for request structures */
static struct kmem_cache *req_cachep;
@@ -200,8 +199,8 @@
const int smb_parameters = 15;
const int header = SMB_HEADER_LEN + 2 * smb_parameters + 2;
- const int oparam = ROUND_UP(header + 3);
- const int odata = ROUND_UP(oparam + req->rq_lparm);
+ const int oparam = ALIGN(header + 3, sizeof(u32));
+ const int odata = ALIGN(oparam + req->rq_lparm, sizeof(u32));
const int bcc = (req->rq_data ? odata + req->rq_ldata :
oparam + req->rq_lparm) - header;
diff --git a/fs/smbfs/smbiod.c b/fs/smbfs/smbiod.c
index 89eaf31..67176af 100644
--- a/fs/smbfs/smbiod.c
+++ b/fs/smbfs/smbiod.c
@@ -16,7 +16,6 @@
#include <linux/init.h>
#include <linux/file.h>
#include <linux/dcache.h>
-#include <linux/smp_lock.h>
#include <linux/module.h>
#include <linux/net.h>
#include <linux/kthread.h>
@@ -299,8 +298,6 @@
*/
static int smbiod(void *unused)
{
- allow_signal(SIGKILL);
-
VERBOSE("SMB Kernel thread starting (%d) ...\n", current->pid);
for (;;) {
diff --git a/fs/smbfs/sock.c b/fs/smbfs/sock.c
index 92ea6b2..e48bd82 100644
--- a/fs/smbfs/sock.c
+++ b/fs/smbfs/sock.c
@@ -17,7 +17,6 @@
#include <linux/net.h>
#include <linux/mm.h>
#include <linux/netdevice.h>
-#include <linux/smp_lock.h>
#include <linux/workqueue.h>
#include <net/scm.h>
#include <net/tcp_states.h>
diff --git a/fs/smbfs/symlink.c b/fs/smbfs/symlink.c
index fea20ce..00b2909 100644
--- a/fs/smbfs/symlink.c
+++ b/fs/smbfs/symlink.c
@@ -13,7 +13,6 @@
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
#include <linux/net.h>
#include <linux/namei.h>
diff --git a/fs/splice.c b/fs/splice.c
index 5428b0f..12f2828 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -289,12 +289,10 @@
nr_pages = PIPE_BUFFERS;
/*
- * Initiate read-ahead on this page range. however, don't call into
- * read-ahead if this is a non-zero offset (we are likely doing small
- * chunk splice and the page is already there) for a single page.
+ * Don't try to 2nd guess the read-ahead logic, call into
+ * page_cache_readahead() like the page cache reads would do.
*/
- if (!loff || nr_pages > 1)
- page_cache_readahead(mapping, &in->f_ra, in, index, nr_pages);
+ page_cache_readahead(mapping, &in->f_ra, in, index, nr_pages);
/*
* Now fill in the holes:
@@ -378,10 +376,11 @@
* If in nonblock mode then dont block on waiting
* for an in-flight io page
*/
- if (flags & SPLICE_F_NONBLOCK)
- break;
-
- lock_page(page);
+ if (flags & SPLICE_F_NONBLOCK) {
+ if (TestSetPageLocked(page))
+ break;
+ } else
+ lock_page(page);
/*
* page was truncated, stop here. if this isn't the
diff --git a/fs/stat.c b/fs/stat.c
index 38a8cb2..6851006 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -8,7 +8,6 @@
#include <linux/mm.h>
#include <linux/errno.h>
#include <linux/file.h>
-#include <linux/smp_lock.h>
#include <linux/highuid.h>
#include <linux/fs.h>
#include <linux/namei.h>
diff --git a/fs/super.c b/fs/super.c
index 8341e4e..5260d62 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -107,6 +107,7 @@
static inline void destroy_super(struct super_block *s)
{
security_sb_free(s);
+ kfree(s->s_subtype);
kfree(s);
}
@@ -907,6 +908,29 @@
EXPORT_SYMBOL_GPL(vfs_kern_mount);
+static struct vfsmount *fs_set_subtype(struct vfsmount *mnt, const char *fstype)
+{
+ int err;
+ const char *subtype = strchr(fstype, '.');
+ if (subtype) {
+ subtype++;
+ err = -EINVAL;
+ if (!subtype[0])
+ goto err;
+ } else
+ subtype = "";
+
+ mnt->mnt_sb->s_subtype = kstrdup(subtype, GFP_KERNEL);
+ err = -ENOMEM;
+ if (!mnt->mnt_sb->s_subtype)
+ goto err;
+ return mnt;
+
+ err:
+ mntput(mnt);
+ return ERR_PTR(err);
+}
+
struct vfsmount *
do_kern_mount(const char *fstype, int flags, const char *name, void *data)
{
@@ -915,6 +939,9 @@
if (!type)
return ERR_PTR(-ENODEV);
mnt = vfs_kern_mount(type, flags, name, data);
+ if (!IS_ERR(mnt) && (type->fs_flags & FS_HAS_SUBTYPE) &&
+ !mnt->mnt_sb->s_subtype)
+ mnt = fs_set_subtype(mnt, fstype);
put_filesystem(type);
return mnt;
}
diff --git a/fs/sync.c b/fs/sync.c
index 5cb9e7e..2f97576 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -229,7 +229,7 @@
!S_ISLNK(i_mode))
goto out_put;
- ret = do_sync_file_range(file, offset, endbyte, flags);
+ ret = do_sync_mapping_range(file->f_mapping, offset, endbyte, flags);
out_put:
fput_light(file, fput_needed);
out:
diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c
index 4e48abb..6bd850b 100644
--- a/fs/sysv/namei.c
+++ b/fs/sysv/namei.c
@@ -13,7 +13,6 @@
*/
#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
#include "sysv.h"
static int add_nondir(struct dentry *dentry, struct inode *inode)
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c
index ea521f8..4cec910 100644
--- a/fs/udf/balloc.c
+++ b/fs/udf/balloc.c
@@ -427,9 +427,9 @@
{
struct udf_sb_info *sbi = UDF_SB(sb);
uint32_t start, end;
- uint32_t nextoffset, oextoffset, elen;
- kernel_lb_addr nbloc, obloc, eloc;
- struct buffer_head *obh, *nbh;
+ uint32_t elen;
+ kernel_lb_addr eloc;
+ struct extent_position oepos, epos;
int8_t etype;
int i;
@@ -457,14 +457,13 @@
start = bloc.logicalBlockNum + offset;
end = bloc.logicalBlockNum + offset + count - 1;
- oextoffset = nextoffset = sizeof(struct unallocSpaceEntry);
+ epos.offset = oepos.offset = sizeof(struct unallocSpaceEntry);
elen = 0;
- obloc = nbloc = UDF_I_LOCATION(table);
-
- obh = nbh = NULL;
+ epos.block = oepos.block = UDF_I_LOCATION(table);
+ epos.bh = oepos.bh = NULL;
while (count && (etype =
- udf_next_aext(table, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) != -1)
+ udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1)
{
if (((eloc.logicalBlockNum + (elen >> sb->s_blocksize_bits)) ==
start))
@@ -482,7 +481,7 @@
start += count;
count = 0;
}
- udf_write_aext(table, obloc, &oextoffset, eloc, elen, obh, 1);
+ udf_write_aext(table, &oepos, eloc, elen, 1);
}
else if (eloc.logicalBlockNum == (end + 1))
{
@@ -502,20 +501,20 @@
end -= count;
count = 0;
}
- udf_write_aext(table, obloc, &oextoffset, eloc, elen, obh, 1);
+ udf_write_aext(table, &oepos, eloc, elen, 1);
}
- if (nbh != obh)
+ if (epos.bh != oepos.bh)
{
i = -1;
- obloc = nbloc;
- udf_release_data(obh);
- atomic_inc(&nbh->b_count);
- obh = nbh;
- oextoffset = 0;
+ oepos.block = epos.block;
+ brelse(oepos.bh);
+ get_bh(epos.bh);
+ oepos.bh = epos.bh;
+ oepos.offset = 0;
}
else
- oextoffset = nextoffset;
+ oepos.offset = epos.offset;
}
if (count)
@@ -547,55 +546,53 @@
adsize = sizeof(long_ad);
else
{
- udf_release_data(obh);
- udf_release_data(nbh);
+ brelse(oepos.bh);
+ brelse(epos.bh);
goto error_return;
}
- if (nextoffset + (2 * adsize) > sb->s_blocksize)
+ if (epos.offset + (2 * adsize) > sb->s_blocksize)
{
char *sptr, *dptr;
int loffset;
- udf_release_data(obh);
- obh = nbh;
- obloc = nbloc;
- oextoffset = nextoffset;
+ brelse(oepos.bh);
+ oepos = epos;
/* Steal a block from the extent being free'd */
- nbloc.logicalBlockNum = eloc.logicalBlockNum;
+ epos.block.logicalBlockNum = eloc.logicalBlockNum;
eloc.logicalBlockNum ++;
elen -= sb->s_blocksize;
- if (!(nbh = udf_tread(sb,
- udf_get_lb_pblock(sb, nbloc, 0))))
+ if (!(epos.bh = udf_tread(sb,
+ udf_get_lb_pblock(sb, epos.block, 0))))
{
- udf_release_data(obh);
+ brelse(oepos.bh);
goto error_return;
}
- aed = (struct allocExtDesc *)(nbh->b_data);
- aed->previousAllocExtLocation = cpu_to_le32(obloc.logicalBlockNum);
- if (nextoffset + adsize > sb->s_blocksize)
+ aed = (struct allocExtDesc *)(epos.bh->b_data);
+ aed->previousAllocExtLocation = cpu_to_le32(oepos.block.logicalBlockNum);
+ if (epos.offset + adsize > sb->s_blocksize)
{
- loffset = nextoffset;
+ loffset = epos.offset;
aed->lengthAllocDescs = cpu_to_le32(adsize);
- sptr = UDF_I_DATA(inode) + nextoffset -
+ sptr = UDF_I_DATA(inode) + epos.offset -
udf_file_entry_alloc_offset(inode) +
UDF_I_LENEATTR(inode) - adsize;
- dptr = nbh->b_data + sizeof(struct allocExtDesc);
+ dptr = epos.bh->b_data + sizeof(struct allocExtDesc);
memcpy(dptr, sptr, adsize);
- nextoffset = sizeof(struct allocExtDesc) + adsize;
+ epos.offset = sizeof(struct allocExtDesc) + adsize;
}
else
{
- loffset = nextoffset + adsize;
+ loffset = epos.offset + adsize;
aed->lengthAllocDescs = cpu_to_le32(0);
- sptr = (obh)->b_data + nextoffset;
- nextoffset = sizeof(struct allocExtDesc);
+ sptr = oepos.bh->b_data + epos.offset;
+ epos.offset = sizeof(struct allocExtDesc);
- if (obh)
+ if (oepos.bh)
{
- aed = (struct allocExtDesc *)(obh)->b_data;
+ aed = (struct allocExtDesc *)oepos.bh->b_data;
aed->lengthAllocDescs =
cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
}
@@ -606,11 +603,11 @@
}
}
if (UDF_SB_UDFREV(sb) >= 0x0200)
- udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1,
- nbloc.logicalBlockNum, sizeof(tag));
+ udf_new_tag(epos.bh->b_data, TAG_IDENT_AED, 3, 1,
+ epos.block.logicalBlockNum, sizeof(tag));
else
- udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1,
- nbloc.logicalBlockNum, sizeof(tag));
+ udf_new_tag(epos.bh->b_data, TAG_IDENT_AED, 2, 1,
+ epos.block.logicalBlockNum, sizeof(tag));
switch (UDF_I_ALLOCTYPE(table))
{
case ICBTAG_FLAG_AD_SHORT:
@@ -619,7 +616,7 @@
sad->extLength = cpu_to_le32(
EXT_NEXT_EXTENT_ALLOCDECS |
sb->s_blocksize);
- sad->extPosition = cpu_to_le32(nbloc.logicalBlockNum);
+ sad->extPosition = cpu_to_le32(epos.block.logicalBlockNum);
break;
}
case ICBTAG_FLAG_AD_LONG:
@@ -628,14 +625,14 @@
lad->extLength = cpu_to_le32(
EXT_NEXT_EXTENT_ALLOCDECS |
sb->s_blocksize);
- lad->extLocation = cpu_to_lelb(nbloc);
+ lad->extLocation = cpu_to_lelb(epos.block);
break;
}
}
- if (obh)
+ if (oepos.bh)
{
- udf_update_tag(obh->b_data, loffset);
- mark_buffer_dirty(obh);
+ udf_update_tag(oepos.bh->b_data, loffset);
+ mark_buffer_dirty(oepos.bh);
}
else
mark_inode_dirty(table);
@@ -643,26 +640,26 @@
if (elen) /* It's possible that stealing the block emptied the extent */
{
- udf_write_aext(table, nbloc, &nextoffset, eloc, elen, nbh, 1);
+ udf_write_aext(table, &epos, eloc, elen, 1);
- if (!nbh)
+ if (!epos.bh)
{
UDF_I_LENALLOC(table) += adsize;
mark_inode_dirty(table);
}
else
{
- aed = (struct allocExtDesc *)nbh->b_data;
+ aed = (struct allocExtDesc *)epos.bh->b_data;
aed->lengthAllocDescs =
cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
- udf_update_tag(nbh->b_data, nextoffset);
- mark_buffer_dirty(nbh);
+ udf_update_tag(epos.bh->b_data, epos.offset);
+ mark_buffer_dirty(epos.bh);
}
}
}
- udf_release_data(nbh);
- udf_release_data(obh);
+ brelse(epos.bh);
+ brelse(oepos.bh);
error_return:
sb->s_dirt = 1;
@@ -677,9 +674,9 @@
{
struct udf_sb_info *sbi = UDF_SB(sb);
int alloc_count = 0;
- uint32_t extoffset, elen, adsize;
- kernel_lb_addr bloc, eloc;
- struct buffer_head *bh;
+ uint32_t elen, adsize;
+ kernel_lb_addr eloc;
+ struct extent_position epos;
int8_t etype = -1;
if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
@@ -693,14 +690,13 @@
return 0;
mutex_lock(&sbi->s_alloc_mutex);
- extoffset = sizeof(struct unallocSpaceEntry);
- bloc = UDF_I_LOCATION(table);
-
- bh = NULL;
+ epos.offset = sizeof(struct unallocSpaceEntry);
+ epos.block = UDF_I_LOCATION(table);
+ epos.bh = NULL;
eloc.logicalBlockNum = 0xFFFFFFFF;
while (first_block != eloc.logicalBlockNum && (etype =
- udf_next_aext(table, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1)
+ udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1)
{
udf_debug("eloc=%d, elen=%d, first_block=%d\n",
eloc.logicalBlockNum, elen, first_block);
@@ -709,7 +705,7 @@
if (first_block == eloc.logicalBlockNum)
{
- extoffset -= adsize;
+ epos.offset -= adsize;
alloc_count = (elen >> sb->s_blocksize_bits);
if (inode && DQUOT_PREALLOC_BLOCK(inode, alloc_count > block_count ? block_count : alloc_count))
@@ -719,15 +715,15 @@
alloc_count = block_count;
eloc.logicalBlockNum += alloc_count;
elen -= (alloc_count << sb->s_blocksize_bits);
- udf_write_aext(table, bloc, &extoffset, eloc, (etype << 30) | elen, bh, 1);
+ udf_write_aext(table, &epos, eloc, (etype << 30) | elen, 1);
}
else
- udf_delete_aext(table, bloc, extoffset, eloc, (etype << 30) | elen, bh);
+ udf_delete_aext(table, epos, eloc, (etype << 30) | elen);
}
else
alloc_count = 0;
- udf_release_data(bh);
+ brelse(epos.bh);
if (alloc_count && UDF_SB_LVIDBH(sb))
{
@@ -747,9 +743,9 @@
struct udf_sb_info *sbi = UDF_SB(sb);
uint32_t spread = 0xFFFFFFFF, nspread = 0xFFFFFFFF;
uint32_t newblock = 0, adsize;
- uint32_t extoffset, goal_extoffset, elen, goal_elen = 0;
- kernel_lb_addr bloc, goal_bloc, eloc, goal_eloc;
- struct buffer_head *bh, *goal_bh;
+ uint32_t elen, goal_elen = 0;
+ kernel_lb_addr eloc, goal_eloc;
+ struct extent_position epos, goal_epos;
int8_t etype;
*err = -ENOSPC;
@@ -770,14 +766,12 @@
We store the buffer_head, bloc, and extoffset of the current closest
match and use that when we are done.
*/
-
- extoffset = sizeof(struct unallocSpaceEntry);
- bloc = UDF_I_LOCATION(table);
-
- goal_bh = bh = NULL;
+ epos.offset = sizeof(struct unallocSpaceEntry);
+ epos.block = UDF_I_LOCATION(table);
+ epos.bh = goal_epos.bh = NULL;
while (spread && (etype =
- udf_next_aext(table, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1)
+ udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1)
{
if (goal >= eloc.logicalBlockNum)
{
@@ -793,24 +787,24 @@
if (nspread < spread)
{
spread = nspread;
- if (goal_bh != bh)
+ if (goal_epos.bh != epos.bh)
{
- udf_release_data(goal_bh);
- goal_bh = bh;
- atomic_inc(&goal_bh->b_count);
+ brelse(goal_epos.bh);
+ goal_epos.bh = epos.bh;
+ get_bh(goal_epos.bh);
}
- goal_bloc = bloc;
- goal_extoffset = extoffset - adsize;
+ goal_epos.block = epos.block;
+ goal_epos.offset = epos.offset - adsize;
goal_eloc = eloc;
goal_elen = (etype << 30) | elen;
}
}
- udf_release_data(bh);
+ brelse(epos.bh);
if (spread == 0xFFFFFFFF)
{
- udf_release_data(goal_bh);
+ brelse(goal_epos.bh);
mutex_unlock(&sbi->s_alloc_mutex);
return 0;
}
@@ -826,17 +820,17 @@
if (inode && DQUOT_ALLOC_BLOCK(inode, 1))
{
- udf_release_data(goal_bh);
+ brelse(goal_epos.bh);
mutex_unlock(&sbi->s_alloc_mutex);
*err = -EDQUOT;
return 0;
}
if (goal_elen)
- udf_write_aext(table, goal_bloc, &goal_extoffset, goal_eloc, goal_elen, goal_bh, 1);
+ udf_write_aext(table, &goal_epos, goal_eloc, goal_elen, 1);
else
- udf_delete_aext(table, goal_bloc, goal_extoffset, goal_eloc, goal_elen, goal_bh);
- udf_release_data(goal_bh);
+ udf_delete_aext(table, goal_epos, goal_eloc, goal_elen);
+ brelse(goal_epos.bh);
if (UDF_SB_LVIDBH(sb))
{
@@ -921,11 +915,14 @@
struct inode * inode,
uint16_t partition, uint32_t goal, int *err)
{
+ int ret;
+
if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
{
- return udf_bitmap_new_block(sb, inode,
+ ret = udf_bitmap_new_block(sb, inode,
UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_bitmap,
partition, goal, err);
+ return ret;
}
else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE)
{
diff --git a/fs/udf/dir.c b/fs/udf/dir.c
index 2391c91..e45f86b 100644
--- a/fs/udf/dir.c
+++ b/fs/udf/dir.c
@@ -111,11 +111,13 @@
uint16_t liu;
uint8_t lfi;
loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
- struct buffer_head * bh = NULL, * tmp, * bha[16];
- kernel_lb_addr bloc, eloc;
- uint32_t extoffset, elen, offset;
+ struct buffer_head *tmp, *bha[16];
+ kernel_lb_addr eloc;
+ uint32_t elen;
+ sector_t offset;
int i, num;
unsigned int dt_type;
+ struct extent_position epos = { NULL, 0, {0, 0}};
if (nf_pos >= size)
return 0;
@@ -127,23 +129,22 @@
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
fibh.sbh = fibh.ebh = NULL;
else if (inode_bmap(dir, nf_pos >> (dir->i_sb->s_blocksize_bits - 2),
- &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30))
+ &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30))
{
- offset >>= dir->i_sb->s_blocksize_bits;
block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
if ((++offset << dir->i_sb->s_blocksize_bits) < elen)
{
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
- extoffset -= sizeof(short_ad);
+ epos.offset -= sizeof(short_ad);
else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
- extoffset -= sizeof(long_ad);
+ epos.offset -= sizeof(long_ad);
}
else
offset = 0;
if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block)))
{
- udf_release_data(bh);
+ brelse(epos.bh);
return -EIO;
}
@@ -171,7 +172,7 @@
}
else
{
- udf_release_data(bh);
+ brelse(epos.bh);
return -ENOENT;
}
@@ -179,14 +180,14 @@
{
filp->f_pos = nf_pos + 1;
- fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh);
+ fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &epos, &eloc, &elen, &offset);
if (!fi)
{
if (fibh.sbh != fibh.ebh)
- udf_release_data(fibh.ebh);
- udf_release_data(fibh.sbh);
- udf_release_data(bh);
+ brelse(fibh.ebh);
+ brelse(fibh.sbh);
+ brelse(epos.bh);
return 0;
}
@@ -244,9 +245,9 @@
if (filldir(dirent, fname, flen, filp->f_pos, iblock, dt_type) < 0)
{
if (fibh.sbh != fibh.ebh)
- udf_release_data(fibh.ebh);
- udf_release_data(fibh.sbh);
- udf_release_data(bh);
+ brelse(fibh.ebh);
+ brelse(fibh.sbh);
+ brelse(epos.bh);
return 0;
}
}
@@ -255,9 +256,9 @@
filp->f_pos = nf_pos + 1;
if (fibh.sbh != fibh.ebh)
- udf_release_data(fibh.ebh);
- udf_release_data(fibh.sbh);
- udf_release_data(bh);
+ brelse(fibh.ebh);
+ brelse(fibh.sbh);
+ brelse(epos.bh);
return 0;
}
diff --git a/fs/udf/directory.c b/fs/udf/directory.c
index fe751a2..198caa3 100644
--- a/fs/udf/directory.c
+++ b/fs/udf/directory.c
@@ -36,14 +36,14 @@
if (!ad)
{
- udf_release_data(*bh);
+ brelse(*bh);
*error = 1;
return NULL;
}
if (*offset == dir->i_sb->s_blocksize)
{
- udf_release_data(*bh);
+ brelse(*bh);
block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos);
if (!block)
return NULL;
@@ -57,7 +57,7 @@
remainder = dir->i_sb->s_blocksize - loffset;
memcpy((uint8_t *)ad, (*bh)->b_data + loffset, remainder);
- udf_release_data(*bh);
+ brelse(*bh);
block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos);
if (!block)
return NULL;
@@ -75,9 +75,9 @@
udf_fileident_read(struct inode *dir, loff_t *nf_pos,
struct udf_fileident_bh *fibh,
struct fileIdentDesc *cfi,
- kernel_lb_addr *bloc, uint32_t *extoffset,
+ struct extent_position *epos,
kernel_lb_addr *eloc, uint32_t *elen,
- uint32_t *offset, struct buffer_head **bh)
+ sector_t *offset)
{
struct fileIdentDesc *fi;
int i, num, block;
@@ -105,13 +105,11 @@
if (fibh->eoffset == dir->i_sb->s_blocksize)
{
- int lextoffset = *extoffset;
+ int lextoffset = epos->offset;
- if (udf_next_aext(dir, bloc, extoffset, eloc, elen, bh, 1) !=
+ if (udf_next_aext(dir, epos, eloc, elen, 1) !=
(EXT_RECORDED_ALLOCATED >> 30))
- {
return NULL;
- }
block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset);
@@ -120,9 +118,9 @@
if ((*offset << dir->i_sb->s_blocksize_bits) >= *elen)
*offset = 0;
else
- *extoffset = lextoffset;
+ epos->offset = lextoffset;
- udf_release_data(fibh->sbh);
+ brelse(fibh->sbh);
if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block)))
return NULL;
fibh->soffset = fibh->eoffset = 0;
@@ -151,7 +149,7 @@
}
else if (fibh->sbh != fibh->ebh)
{
- udf_release_data(fibh->sbh);
+ brelse(fibh->sbh);
fibh->sbh = fibh->ebh;
}
@@ -169,13 +167,11 @@
}
else if (fibh->eoffset > dir->i_sb->s_blocksize)
{
- int lextoffset = *extoffset;
+ int lextoffset = epos->offset;
- if (udf_next_aext(dir, bloc, extoffset, eloc, elen, bh, 1) !=
+ if (udf_next_aext(dir, epos, eloc, elen, 1) !=
(EXT_RECORDED_ALLOCATED >> 30))
- {
return NULL;
- }
block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset);
@@ -184,7 +180,7 @@
if ((*offset << dir->i_sb->s_blocksize_bits) >= *elen)
*offset = 0;
else
- *extoffset = lextoffset;
+ epos->offset = lextoffset;
fibh->soffset -= dir->i_sb->s_blocksize;
fibh->eoffset -= dir->i_sb->s_blocksize;
diff --git a/fs/udf/fsync.c b/fs/udf/fsync.c
index 5887d78..6ded93e 100644
--- a/fs/udf/fsync.c
+++ b/fs/udf/fsync.c
@@ -21,7 +21,6 @@
#include "udfdecl.h"
#include <linux/fs.h>
-#include <linux/smp_lock.h>
static int udf_fsync_inode(struct inode *, int);
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index ae21a0e..c846155 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -49,10 +49,10 @@
static mode_t udf_convert_permissions(struct fileEntry *);
static int udf_update_inode(struct inode *, int);
static void udf_fill_inode(struct inode *, struct buffer_head *);
-static struct buffer_head *inode_getblk(struct inode *, long, int *,
+static struct buffer_head *inode_getblk(struct inode *, sector_t, int *,
long *, int *);
-static int8_t udf_insert_aext(struct inode *, kernel_lb_addr, int,
- kernel_lb_addr, uint32_t, struct buffer_head *);
+static int8_t udf_insert_aext(struct inode *, struct extent_position,
+ kernel_lb_addr, uint32_t);
static void udf_split_extents(struct inode *, int *, int, int,
kernel_long_ad [EXTENT_MERGE_SIZE], int *);
static void udf_prealloc_extents(struct inode *, int, int,
@@ -61,7 +61,7 @@
kernel_long_ad [EXTENT_MERGE_SIZE], int *);
static void udf_update_extents(struct inode *,
kernel_long_ad [EXTENT_MERGE_SIZE], int, int,
- kernel_lb_addr, uint32_t, struct buffer_head **);
+ struct extent_position *);
static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int);
/*
@@ -194,10 +194,11 @@
struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int *err)
{
int newblock;
- struct buffer_head *sbh = NULL, *dbh = NULL;
- kernel_lb_addr bloc, eloc;
- uint32_t elen, extoffset;
+ struct buffer_head *dbh = NULL;
+ kernel_lb_addr eloc;
+ uint32_t elen;
uint8_t alloctype;
+ struct extent_position epos;
struct udf_fileident_bh sfibh, dfibh;
loff_t f_pos = udf_ext0_offset(inode) >> 2;
@@ -237,16 +238,16 @@
mark_buffer_dirty_inode(dbh, inode);
sfibh.soffset = sfibh.eoffset = (f_pos & ((inode->i_sb->s_blocksize - 1) >> 2)) << 2;
- sbh = sfibh.sbh = sfibh.ebh = NULL;
+ sfibh.sbh = sfibh.ebh = NULL;
dfibh.soffset = dfibh.eoffset = 0;
dfibh.sbh = dfibh.ebh = dbh;
while ( (f_pos < size) )
{
UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB;
- sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL, NULL, NULL, NULL, NULL, NULL);
+ sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL, NULL, NULL, NULL);
if (!sfi)
{
- udf_release_data(dbh);
+ brelse(dbh);
return NULL;
}
UDF_I_ALLOCTYPE(inode) = alloctype;
@@ -258,7 +259,7 @@
sfi->fileIdent + le16_to_cpu(sfi->lengthOfImpUse)))
{
UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB;
- udf_release_data(dbh);
+ brelse(dbh);
return NULL;
}
}
@@ -266,16 +267,17 @@
memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), 0, UDF_I_LENALLOC(inode));
UDF_I_LENALLOC(inode) = 0;
- bloc = UDF_I_LOCATION(inode);
eloc.logicalBlockNum = *block;
eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;
elen = inode->i_size;
UDF_I_LENEXTENTS(inode) = elen;
- extoffset = udf_file_entry_alloc_offset(inode);
- udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &sbh, 0);
+ epos.bh = NULL;
+ epos.block = UDF_I_LOCATION(inode);
+ epos.offset = udf_file_entry_alloc_offset(inode);
+ udf_add_aext(inode, &epos, eloc, elen, 0);
/* UniqueID stuff */
- udf_release_data(sbh);
+ brelse(epos.bh);
mark_inode_dirty(inode);
return dbh;
}
@@ -354,53 +356,153 @@
return NULL;
}
-static struct buffer_head * inode_getblk(struct inode * inode, long block,
+/* Extend the file by 'blocks' blocks, return the number of extents added */
+int udf_extend_file(struct inode *inode, struct extent_position *last_pos,
+ kernel_long_ad *last_ext, sector_t blocks)
+{
+ sector_t add;
+ int count = 0, fake = !(last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
+ struct super_block *sb = inode->i_sb;
+ kernel_lb_addr prealloc_loc = {0, 0};
+ int prealloc_len = 0;
+
+ /* The previous extent is fake and we should not extend by anything
+ * - there's nothing to do... */
+ if (!blocks && fake)
+ return 0;
+ /* Round the last extent up to a multiple of block size */
+ if (last_ext->extLength & (sb->s_blocksize - 1)) {
+ last_ext->extLength =
+ (last_ext->extLength & UDF_EXTENT_FLAG_MASK) |
+ (((last_ext->extLength & UDF_EXTENT_LENGTH_MASK) +
+ sb->s_blocksize - 1) & ~(sb->s_blocksize - 1));
+ UDF_I_LENEXTENTS(inode) =
+ (UDF_I_LENEXTENTS(inode) + sb->s_blocksize - 1) &
+ ~(sb->s_blocksize - 1);
+ }
+ /* Last extent are just preallocated blocks? */
+ if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) == EXT_NOT_RECORDED_ALLOCATED) {
+ /* Save the extent so that we can reattach it to the end */
+ prealloc_loc = last_ext->extLocation;
+ prealloc_len = last_ext->extLength;
+ /* Mark the extent as a hole */
+ last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
+ (last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
+ last_ext->extLocation.logicalBlockNum = 0;
+ last_ext->extLocation.partitionReferenceNum = 0;
+ }
+ /* Can we merge with the previous extent? */
+ if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) == EXT_NOT_RECORDED_NOT_ALLOCATED) {
+ add = ((1<<30) - sb->s_blocksize - (last_ext->extLength &
+ UDF_EXTENT_LENGTH_MASK)) >> sb->s_blocksize_bits;
+ if (add > blocks)
+ add = blocks;
+ blocks -= add;
+ last_ext->extLength += add << sb->s_blocksize_bits;
+ }
+
+ if (fake) {
+ udf_add_aext(inode, last_pos, last_ext->extLocation,
+ last_ext->extLength, 1);
+ count++;
+ }
+ else
+ udf_write_aext(inode, last_pos, last_ext->extLocation, last_ext->extLength, 1);
+ /* Managed to do everything necessary? */
+ if (!blocks)
+ goto out;
+
+ /* All further extents will be NOT_RECORDED_NOT_ALLOCATED */
+ last_ext->extLocation.logicalBlockNum = 0;
+ last_ext->extLocation.partitionReferenceNum = 0;
+ add = (1 << (30-sb->s_blocksize_bits)) - 1;
+ last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | (add << sb->s_blocksize_bits);
+ /* Create enough extents to cover the whole hole */
+ while (blocks > add) {
+ blocks -= add;
+ if (udf_add_aext(inode, last_pos, last_ext->extLocation,
+ last_ext->extLength, 1) == -1)
+ return -1;
+ count++;
+ }
+ if (blocks) {
+ last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
+ (blocks << sb->s_blocksize_bits);
+ if (udf_add_aext(inode, last_pos, last_ext->extLocation,
+ last_ext->extLength, 1) == -1)
+ return -1;
+ count++;
+ }
+out:
+ /* Do we have some preallocated blocks saved? */
+ if (prealloc_len) {
+ if (udf_add_aext(inode, last_pos, prealloc_loc, prealloc_len, 1) == -1)
+ return -1;
+ last_ext->extLocation = prealloc_loc;
+ last_ext->extLength = prealloc_len;
+ count++;
+ }
+ /* last_pos should point to the last written extent... */
+ if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
+ last_pos->offset -= sizeof(short_ad);
+ else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG)
+ last_pos->offset -= sizeof(long_ad);
+ else
+ return -1;
+ return count;
+}
+
+static struct buffer_head * inode_getblk(struct inode * inode, sector_t block,
int *err, long *phys, int *new)
{
- struct buffer_head *pbh = NULL, *cbh = NULL, *nbh = NULL, *result = NULL;
+ static sector_t last_block;
+ struct buffer_head *result = NULL;
kernel_long_ad laarr[EXTENT_MERGE_SIZE];
- uint32_t pextoffset = 0, cextoffset = 0, nextoffset = 0;
+ struct extent_position prev_epos, cur_epos, next_epos;
int count = 0, startnum = 0, endnum = 0;
uint32_t elen = 0;
- kernel_lb_addr eloc, pbloc, cbloc, nbloc;
+ kernel_lb_addr eloc;
int c = 1;
- uint64_t lbcount = 0, b_off = 0;
- uint32_t newblocknum, newblock, offset = 0;
+ loff_t lbcount = 0, b_off = 0;
+ uint32_t newblocknum, newblock;
+ sector_t offset = 0;
int8_t etype;
int goal = 0, pgoal = UDF_I_LOCATION(inode).logicalBlockNum;
- char lastblock = 0;
+ int lastblock = 0;
- pextoffset = cextoffset = nextoffset = udf_file_entry_alloc_offset(inode);
- b_off = (uint64_t)block << inode->i_sb->s_blocksize_bits;
- pbloc = cbloc = nbloc = UDF_I_LOCATION(inode);
+ prev_epos.offset = udf_file_entry_alloc_offset(inode);
+ prev_epos.block = UDF_I_LOCATION(inode);
+ prev_epos.bh = NULL;
+ cur_epos = next_epos = prev_epos;
+ b_off = (loff_t)block << inode->i_sb->s_blocksize_bits;
/* find the extent which contains the block we are looking for.
alternate between laarr[0] and laarr[1] for locations of the
current extent, and the previous extent */
do
{
- if (pbh != cbh)
+ if (prev_epos.bh != cur_epos.bh)
{
- udf_release_data(pbh);
- atomic_inc(&cbh->b_count);
- pbh = cbh;
+ brelse(prev_epos.bh);
+ get_bh(cur_epos.bh);
+ prev_epos.bh = cur_epos.bh;
}
- if (cbh != nbh)
+ if (cur_epos.bh != next_epos.bh)
{
- udf_release_data(cbh);
- atomic_inc(&nbh->b_count);
- cbh = nbh;
+ brelse(cur_epos.bh);
+ get_bh(next_epos.bh);
+ cur_epos.bh = next_epos.bh;
}
lbcount += elen;
- pbloc = cbloc;
- cbloc = nbloc;
+ prev_epos.block = cur_epos.block;
+ cur_epos.block = next_epos.block;
- pextoffset = cextoffset;
- cextoffset = nextoffset;
+ prev_epos.offset = cur_epos.offset;
+ cur_epos.offset = next_epos.offset;
- if ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) == -1)
+ if ((etype = udf_next_aext(inode, &next_epos, &eloc, &elen, 1)) == -1)
break;
c = !c;
@@ -418,6 +520,8 @@
b_off -= lbcount;
offset = b_off >> inode->i_sb->s_blocksize_bits;
+ /* Move into indirect extent if we are at a pointer to it */
+ udf_next_aext(inode, &prev_epos, &eloc, &elen, 0);
/* if the extent is allocated and recorded, return the block
if the extent is not a multiple of the blocksize, round up */
@@ -429,54 +533,77 @@
elen = EXT_RECORDED_ALLOCATED |
((elen + inode->i_sb->s_blocksize - 1) &
~(inode->i_sb->s_blocksize - 1));
- etype = udf_write_aext(inode, nbloc, &cextoffset, eloc, elen, nbh, 1);
+ etype = udf_write_aext(inode, &cur_epos, eloc, elen, 1);
}
- udf_release_data(pbh);
- udf_release_data(cbh);
- udf_release_data(nbh);
+ brelse(prev_epos.bh);
+ brelse(cur_epos.bh);
+ brelse(next_epos.bh);
newblock = udf_get_lb_pblock(inode->i_sb, eloc, offset);
*phys = newblock;
return NULL;
}
+ last_block = block;
+ /* Are we beyond EOF? */
if (etype == -1)
{
- endnum = startnum = ((count > 1) ? 1 : count);
- if (laarr[c].extLength & (inode->i_sb->s_blocksize - 1))
- {
- laarr[c].extLength =
- (laarr[c].extLength & UDF_EXTENT_FLAG_MASK) |
- (((laarr[c].extLength & UDF_EXTENT_LENGTH_MASK) +
- inode->i_sb->s_blocksize - 1) &
- ~(inode->i_sb->s_blocksize - 1));
- UDF_I_LENEXTENTS(inode) =
- (UDF_I_LENEXTENTS(inode) + inode->i_sb->s_blocksize - 1) &
- ~(inode->i_sb->s_blocksize - 1);
+ int ret;
+
+ if (count) {
+ if (c)
+ laarr[0] = laarr[1];
+ startnum = 1;
}
- c = !c;
- laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
- ((offset + 1) << inode->i_sb->s_blocksize_bits);
- memset(&laarr[c].extLocation, 0x00, sizeof(kernel_lb_addr));
- count ++;
- endnum ++;
+ else {
+ /* Create a fake extent when there's not one */
+ memset(&laarr[0].extLocation, 0x00, sizeof(kernel_lb_addr));
+ laarr[0].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED;
+ /* Will udf_extend_file() create real extent from a fake one? */
+ startnum = (offset > 0);
+ }
+ /* Create extents for the hole between EOF and offset */
+ ret = udf_extend_file(inode, &prev_epos, laarr, offset);
+ if (ret == -1) {
+ brelse(prev_epos.bh);
+ brelse(cur_epos.bh);
+ brelse(next_epos.bh);
+ /* We don't really know the error here so we just make
+ * something up */
+ *err = -ENOSPC;
+ return NULL;
+ }
+ c = 0;
+ offset = 0;
+ count += ret;
+ /* We are not covered by a preallocated extent? */
+ if ((laarr[0].extLength & UDF_EXTENT_FLAG_MASK) != EXT_NOT_RECORDED_ALLOCATED) {
+ /* Is there any real extent? - otherwise we overwrite
+ * the fake one... */
+ if (count)
+ c = !c;
+ laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
+ inode->i_sb->s_blocksize;
+ memset(&laarr[c].extLocation, 0x00, sizeof(kernel_lb_addr));
+ count ++;
+ endnum ++;
+ }
+ endnum = c+1;
lastblock = 1;
}
- else
+ else {
endnum = startnum = ((count > 2) ? 2 : count);
- /* if the current extent is in position 0, swap it with the previous */
- if (!c && count != 1)
- {
- laarr[2] = laarr[0];
- laarr[0] = laarr[1];
- laarr[1] = laarr[2];
- c = 1;
- }
+ /* if the current extent is in position 0, swap it with the previous */
+ if (!c && count != 1)
+ {
+ laarr[2] = laarr[0];
+ laarr[0] = laarr[1];
+ laarr[1] = laarr[2];
+ c = 1;
+ }
- /* if the current block is located in a extent, read the next extent */
- if (etype != -1)
- {
- if ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 0)) != -1)
+ /* if the current block is located in an extent, read the next extent */
+ if ((etype = udf_next_aext(inode, &next_epos, &eloc, &elen, 0)) != -1)
{
laarr[c+1].extLength = (etype << 30) | elen;
laarr[c+1].extLocation = eloc;
@@ -484,11 +611,10 @@
startnum ++;
endnum ++;
}
- else
+ else {
lastblock = 1;
+ }
}
- udf_release_data(cbh);
- udf_release_data(nbh);
/* if the current extent is not recorded but allocated, get the
block in the extent corresponding to the requested block */
@@ -508,7 +634,7 @@
if (!(newblocknum = udf_new_block(inode->i_sb, inode,
UDF_I_LOCATION(inode).partitionReferenceNum, goal, err)))
{
- udf_release_data(pbh);
+ brelse(prev_epos.bh);
*err = -ENOSPC;
return NULL;
}
@@ -529,11 +655,11 @@
udf_merge_extents(inode, laarr, &endnum);
/* write back the new extents, inserting new extents if the new number
- of extents is greater than the old number, and deleting extents if
- the new number of extents is less than the old number */
- udf_update_extents(inode, laarr, startnum, endnum, pbloc, pextoffset, &pbh);
+ of extents is greater than the old number, and deleting extents if
+ the new number of extents is less than the old number */
+ udf_update_extents(inode, laarr, startnum, endnum, &prev_epos);
- udf_release_data(pbh);
+ brelse(prev_epos.bh);
if (!(newblock = udf_get_pblock(inode->i_sb, newblocknum,
UDF_I_LOCATION(inode).partitionReferenceNum, 0)))
@@ -795,7 +921,7 @@
static void udf_update_extents(struct inode *inode,
kernel_long_ad laarr[EXTENT_MERGE_SIZE], int startnum, int endnum,
- kernel_lb_addr pbloc, uint32_t pextoffset, struct buffer_head **pbh)
+ struct extent_position *epos)
{
int start = 0, i;
kernel_lb_addr tmploc;
@@ -804,28 +930,26 @@
if (startnum > endnum)
{
for (i=0; i<(startnum-endnum); i++)
- {
- udf_delete_aext(inode, pbloc, pextoffset, laarr[i].extLocation,
- laarr[i].extLength, *pbh);
- }
+ udf_delete_aext(inode, *epos, laarr[i].extLocation,
+ laarr[i].extLength);
}
else if (startnum < endnum)
{
for (i=0; i<(endnum-startnum); i++)
{
- udf_insert_aext(inode, pbloc, pextoffset, laarr[i].extLocation,
- laarr[i].extLength, *pbh);
- udf_next_aext(inode, &pbloc, &pextoffset, &laarr[i].extLocation,
- &laarr[i].extLength, pbh, 1);
+ udf_insert_aext(inode, *epos, laarr[i].extLocation,
+ laarr[i].extLength);
+ udf_next_aext(inode, epos, &laarr[i].extLocation,
+ &laarr[i].extLength, 1);
start ++;
}
}
for (i=start; i<endnum; i++)
{
- udf_next_aext(inode, &pbloc, &pextoffset, &tmploc, &tmplen, pbh, 0);
- udf_write_aext(inode, pbloc, &pextoffset, laarr[i].extLocation,
- laarr[i].extLength, *pbh, 1);
+ udf_next_aext(inode, epos, &tmploc, &tmplen, 0);
+ udf_write_aext(inode, epos, laarr[i].extLocation,
+ laarr[i].extLength, 1);
}
}
@@ -931,7 +1055,7 @@
{
printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed ident=%d\n",
inode->i_ino, ident);
- udf_release_data(bh);
+ brelse(bh);
make_bad_inode(inode);
return;
}
@@ -960,35 +1084,36 @@
ident == TAG_IDENT_EFE)
{
memcpy(&UDF_I_LOCATION(inode), &loc, sizeof(kernel_lb_addr));
- udf_release_data(bh);
- udf_release_data(ibh);
- udf_release_data(nbh);
+ brelse(bh);
+ brelse(ibh);
+ brelse(nbh);
__udf_read_inode(inode);
return;
}
else
{
- udf_release_data(nbh);
- udf_release_data(ibh);
+ brelse(nbh);
+ brelse(ibh);
}
}
else
- udf_release_data(ibh);
+ brelse(ibh);
}
}
else
- udf_release_data(ibh);
+ brelse(ibh);
}
else if (le16_to_cpu(fe->icbTag.strategyType) != 4)
{
printk(KERN_ERR "udf: unsupported strategy type: %d\n",
le16_to_cpu(fe->icbTag.strategyType));
- udf_release_data(bh);
+ brelse(bh);
make_bad_inode(inode);
return;
}
udf_fill_inode(inode, bh);
- udf_release_data(bh);
+
+ brelse(bh);
}
static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
@@ -1331,7 +1456,7 @@
use->descTag.tagChecksum += ((uint8_t *)&(use->descTag))[i];
mark_buffer_dirty(bh);
- udf_release_data(bh);
+ brelse(bh);
return err;
}
@@ -1520,7 +1645,7 @@
err = -EIO;
}
}
- udf_release_data(bh);
+ brelse(bh);
return err;
}
@@ -1556,8 +1681,8 @@
return NULL;
}
-int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset,
- kernel_lb_addr eloc, uint32_t elen, struct buffer_head **bh, int inc)
+int8_t udf_add_aext(struct inode *inode, struct extent_position *epos,
+ kernel_lb_addr eloc, uint32_t elen, int inc)
{
int adsize;
short_ad *sad = NULL;
@@ -1566,10 +1691,10 @@
int8_t etype;
uint8_t *ptr;
- if (!*bh)
- ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
+ if (!epos->bh)
+ ptr = UDF_I_DATA(inode) + epos->offset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
else
- ptr = (*bh)->b_data + *extoffset;
+ ptr = epos->bh->b_data + epos->offset;
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
adsize = sizeof(short_ad);
@@ -1578,20 +1703,20 @@
else
return -1;
- if (*extoffset + (2 * adsize) > inode->i_sb->s_blocksize)
+ if (epos->offset + (2 * adsize) > inode->i_sb->s_blocksize)
{
char *sptr, *dptr;
struct buffer_head *nbh;
int err, loffset;
- kernel_lb_addr obloc = *bloc;
+ kernel_lb_addr obloc = epos->block;
- if (!(bloc->logicalBlockNum = udf_new_block(inode->i_sb, NULL,
+ if (!(epos->block.logicalBlockNum = udf_new_block(inode->i_sb, NULL,
obloc.partitionReferenceNum, obloc.logicalBlockNum, &err)))
{
return -1;
}
if (!(nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb,
- *bloc, 0))))
+ epos->block, 0))))
{
return -1;
}
@@ -1604,25 +1729,25 @@
aed = (struct allocExtDesc *)(nbh->b_data);
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT))
aed->previousAllocExtLocation = cpu_to_le32(obloc.logicalBlockNum);
- if (*extoffset + adsize > inode->i_sb->s_blocksize)
+ if (epos->offset + adsize > inode->i_sb->s_blocksize)
{
- loffset = *extoffset;
+ loffset = epos->offset;
aed->lengthAllocDescs = cpu_to_le32(adsize);
sptr = ptr - adsize;
dptr = nbh->b_data + sizeof(struct allocExtDesc);
memcpy(dptr, sptr, adsize);
- *extoffset = sizeof(struct allocExtDesc) + adsize;
+ epos->offset = sizeof(struct allocExtDesc) + adsize;
}
else
{
- loffset = *extoffset + adsize;
+ loffset = epos->offset + adsize;
aed->lengthAllocDescs = cpu_to_le32(0);
sptr = ptr;
- *extoffset = sizeof(struct allocExtDesc);
+ epos->offset = sizeof(struct allocExtDesc);
- if (*bh)
+ if (epos->bh)
{
- aed = (struct allocExtDesc *)(*bh)->b_data;
+ aed = (struct allocExtDesc *)epos->bh->b_data;
aed->lengthAllocDescs =
cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
}
@@ -1634,10 +1759,10 @@
}
if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200)
udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1,
- bloc->logicalBlockNum, sizeof(tag));
+ epos->block.logicalBlockNum, sizeof(tag));
else
udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1,
- bloc->logicalBlockNum, sizeof(tag));
+ epos->block.logicalBlockNum, sizeof(tag));
switch (UDF_I_ALLOCTYPE(inode))
{
case ICBTAG_FLAG_AD_SHORT:
@@ -1646,7 +1771,7 @@
sad->extLength = cpu_to_le32(
EXT_NEXT_EXTENT_ALLOCDECS |
inode->i_sb->s_blocksize);
- sad->extPosition = cpu_to_le32(bloc->logicalBlockNum);
+ sad->extPosition = cpu_to_le32(epos->block.logicalBlockNum);
break;
}
case ICBTAG_FLAG_AD_LONG:
@@ -1655,60 +1780,57 @@
lad->extLength = cpu_to_le32(
EXT_NEXT_EXTENT_ALLOCDECS |
inode->i_sb->s_blocksize);
- lad->extLocation = cpu_to_lelb(*bloc);
+ lad->extLocation = cpu_to_lelb(epos->block);
memset(lad->impUse, 0x00, sizeof(lad->impUse));
break;
}
}
- if (*bh)
+ if (epos->bh)
{
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
- udf_update_tag((*bh)->b_data, loffset);
+ udf_update_tag(epos->bh->b_data, loffset);
else
- udf_update_tag((*bh)->b_data, sizeof(struct allocExtDesc));
- mark_buffer_dirty_inode(*bh, inode);
- udf_release_data(*bh);
+ udf_update_tag(epos->bh->b_data, sizeof(struct allocExtDesc));
+ mark_buffer_dirty_inode(epos->bh, inode);
+ brelse(epos->bh);
}
else
mark_inode_dirty(inode);
- *bh = nbh;
+ epos->bh = nbh;
}
- etype = udf_write_aext(inode, *bloc, extoffset, eloc, elen, *bh, inc);
+ etype = udf_write_aext(inode, epos, eloc, elen, inc);
- if (!*bh)
+ if (!epos->bh)
{
UDF_I_LENALLOC(inode) += adsize;
mark_inode_dirty(inode);
}
else
{
- aed = (struct allocExtDesc *)(*bh)->b_data;
+ aed = (struct allocExtDesc *)epos->bh->b_data;
aed->lengthAllocDescs =
cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
- udf_update_tag((*bh)->b_data, *extoffset + (inc ? 0 : adsize));
+ udf_update_tag(epos->bh->b_data, epos->offset + (inc ? 0 : adsize));
else
- udf_update_tag((*bh)->b_data, sizeof(struct allocExtDesc));
- mark_buffer_dirty_inode(*bh, inode);
+ udf_update_tag(epos->bh->b_data, sizeof(struct allocExtDesc));
+ mark_buffer_dirty_inode(epos->bh, inode);
}
return etype;
}
-int8_t udf_write_aext(struct inode *inode, kernel_lb_addr bloc, int *extoffset,
- kernel_lb_addr eloc, uint32_t elen, struct buffer_head *bh, int inc)
+int8_t udf_write_aext(struct inode *inode, struct extent_position *epos,
+ kernel_lb_addr eloc, uint32_t elen, int inc)
{
int adsize;
uint8_t *ptr;
- if (!bh)
- ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
+ if (!epos->bh)
+ ptr = UDF_I_DATA(inode) + epos->offset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
else
- {
- ptr = bh->b_data + *extoffset;
- atomic_inc(&bh->b_count);
- }
+ ptr = epos->bh->b_data + epos->offset;
switch (UDF_I_ALLOCTYPE(inode))
{
@@ -1733,40 +1855,39 @@
return -1;
}
- if (bh)
+ if (epos->bh)
{
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
{
- struct allocExtDesc *aed = (struct allocExtDesc *)(bh)->b_data;
- udf_update_tag((bh)->b_data,
+ struct allocExtDesc *aed = (struct allocExtDesc *)epos->bh->b_data;
+ udf_update_tag(epos->bh->b_data,
le32_to_cpu(aed->lengthAllocDescs) + sizeof(struct allocExtDesc));
}
- mark_buffer_dirty_inode(bh, inode);
- udf_release_data(bh);
+ mark_buffer_dirty_inode(epos->bh, inode);
}
else
mark_inode_dirty(inode);
if (inc)
- *extoffset += adsize;
+ epos->offset += adsize;
return (elen >> 30);
}
-int8_t udf_next_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset,
- kernel_lb_addr *eloc, uint32_t *elen, struct buffer_head **bh, int inc)
+int8_t udf_next_aext(struct inode *inode, struct extent_position *epos,
+ kernel_lb_addr *eloc, uint32_t *elen, int inc)
{
int8_t etype;
- while ((etype = udf_current_aext(inode, bloc, extoffset, eloc, elen, bh, inc)) ==
+ while ((etype = udf_current_aext(inode, epos, eloc, elen, inc)) ==
(EXT_NEXT_EXTENT_ALLOCDECS >> 30))
{
- *bloc = *eloc;
- *extoffset = sizeof(struct allocExtDesc);
- udf_release_data(*bh);
- if (!(*bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, *bloc, 0))))
+ epos->block = *eloc;
+ epos->offset = sizeof(struct allocExtDesc);
+ brelse(epos->bh);
+ if (!(epos->bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, epos->block, 0))))
{
udf_debug("reading block %d failed!\n",
- udf_get_lb_pblock(inode->i_sb, *bloc, 0));
+ udf_get_lb_pblock(inode->i_sb, epos->block, 0));
return -1;
}
}
@@ -1774,26 +1895,26 @@
return etype;
}
-int8_t udf_current_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset,
- kernel_lb_addr *eloc, uint32_t *elen, struct buffer_head **bh, int inc)
+int8_t udf_current_aext(struct inode *inode, struct extent_position *epos,
+ kernel_lb_addr *eloc, uint32_t *elen, int inc)
{
int alen;
int8_t etype;
uint8_t *ptr;
- if (!*bh)
+ if (!epos->bh)
{
- if (!(*extoffset))
- *extoffset = udf_file_entry_alloc_offset(inode);
- ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
+ if (!epos->offset)
+ epos->offset = udf_file_entry_alloc_offset(inode);
+ ptr = UDF_I_DATA(inode) + epos->offset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
alen = udf_file_entry_alloc_offset(inode) + UDF_I_LENALLOC(inode);
}
else
{
- if (!(*extoffset))
- *extoffset = sizeof(struct allocExtDesc);
- ptr = (*bh)->b_data + *extoffset;
- alen = sizeof(struct allocExtDesc) + le32_to_cpu(((struct allocExtDesc *)(*bh)->b_data)->lengthAllocDescs);
+ if (!epos->offset)
+ epos->offset = sizeof(struct allocExtDesc);
+ ptr = epos->bh->b_data + epos->offset;
+ alen = sizeof(struct allocExtDesc) + le32_to_cpu(((struct allocExtDesc *)epos->bh->b_data)->lengthAllocDescs);
}
switch (UDF_I_ALLOCTYPE(inode))
@@ -1802,7 +1923,7 @@
{
short_ad *sad;
- if (!(sad = udf_get_fileshortad(ptr, alen, extoffset, inc)))
+ if (!(sad = udf_get_fileshortad(ptr, alen, &epos->offset, inc)))
return -1;
etype = le32_to_cpu(sad->extLength) >> 30;
@@ -1815,7 +1936,7 @@
{
long_ad *lad;
- if (!(lad = udf_get_filelongad(ptr, alen, extoffset, inc)))
+ if (!(lad = udf_get_filelongad(ptr, alen, &epos->offset, inc)))
return -1;
etype = le32_to_cpu(lad->extLength) >> 30;
@@ -1834,41 +1955,40 @@
}
static int8_t
-udf_insert_aext(struct inode *inode, kernel_lb_addr bloc, int extoffset,
- kernel_lb_addr neloc, uint32_t nelen, struct buffer_head *bh)
+udf_insert_aext(struct inode *inode, struct extent_position epos,
+ kernel_lb_addr neloc, uint32_t nelen)
{
kernel_lb_addr oeloc;
uint32_t oelen;
int8_t etype;
- if (bh)
- atomic_inc(&bh->b_count);
+ if (epos.bh)
+ get_bh(epos.bh);
- while ((etype = udf_next_aext(inode, &bloc, &extoffset, &oeloc, &oelen, &bh, 0)) != -1)
+ while ((etype = udf_next_aext(inode, &epos, &oeloc, &oelen, 0)) != -1)
{
- udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1);
+ udf_write_aext(inode, &epos, neloc, nelen, 1);
neloc = oeloc;
nelen = (etype << 30) | oelen;
}
- udf_add_aext(inode, &bloc, &extoffset, neloc, nelen, &bh, 1);
- udf_release_data(bh);
+ udf_add_aext(inode, &epos, neloc, nelen, 1);
+ brelse(epos.bh);
return (nelen >> 30);
}
-int8_t udf_delete_aext(struct inode *inode, kernel_lb_addr nbloc, int nextoffset,
- kernel_lb_addr eloc, uint32_t elen, struct buffer_head *nbh)
+int8_t udf_delete_aext(struct inode *inode, struct extent_position epos,
+ kernel_lb_addr eloc, uint32_t elen)
{
- struct buffer_head *obh;
- kernel_lb_addr obloc;
- int oextoffset, adsize;
+ struct extent_position oepos;
+ int adsize;
int8_t etype;
struct allocExtDesc *aed;
- if (nbh)
+ if (epos.bh)
{
- atomic_inc(&nbh->b_count);
- atomic_inc(&nbh->b_count);
+ get_bh(epos.bh);
+ get_bh(epos.bh);
}
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
@@ -1878,80 +1998,77 @@
else
adsize = 0;
- obh = nbh;
- obloc = nbloc;
- oextoffset = nextoffset;
-
- if (udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1) == -1)
+ oepos = epos;
+ if (udf_next_aext(inode, &epos, &eloc, &elen, 1) == -1)
return -1;
- while ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) != -1)
+ while ((etype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1)
{
- udf_write_aext(inode, obloc, &oextoffset, eloc, (etype << 30) | elen, obh, 1);
- if (obh != nbh)
+ udf_write_aext(inode, &oepos, eloc, (etype << 30) | elen, 1);
+ if (oepos.bh != epos.bh)
{
- obloc = nbloc;
- udf_release_data(obh);
- atomic_inc(&nbh->b_count);
- obh = nbh;
- oextoffset = nextoffset - adsize;
+ oepos.block = epos.block;
+ brelse(oepos.bh);
+ get_bh(epos.bh);
+ oepos.bh = epos.bh;
+ oepos.offset = epos.offset - adsize;
}
}
memset(&eloc, 0x00, sizeof(kernel_lb_addr));
elen = 0;
- if (nbh != obh)
+ if (epos.bh != oepos.bh)
{
- udf_free_blocks(inode->i_sb, inode, nbloc, 0, 1);
- udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1);
- udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1);
- if (!obh)
+ udf_free_blocks(inode->i_sb, inode, epos.block, 0, 1);
+ udf_write_aext(inode, &oepos, eloc, elen, 1);
+ udf_write_aext(inode, &oepos, eloc, elen, 1);
+ if (!oepos.bh)
{
UDF_I_LENALLOC(inode) -= (adsize * 2);
mark_inode_dirty(inode);
}
else
{
- aed = (struct allocExtDesc *)(obh)->b_data;
+ aed = (struct allocExtDesc *)oepos.bh->b_data;
aed->lengthAllocDescs =
cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - (2*adsize));
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
- udf_update_tag((obh)->b_data, oextoffset - (2*adsize));
+ udf_update_tag(oepos.bh->b_data, oepos.offset - (2*adsize));
else
- udf_update_tag((obh)->b_data, sizeof(struct allocExtDesc));
- mark_buffer_dirty_inode(obh, inode);
+ udf_update_tag(oepos.bh->b_data, sizeof(struct allocExtDesc));
+ mark_buffer_dirty_inode(oepos.bh, inode);
}
}
else
{
- udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1);
- if (!obh)
+ udf_write_aext(inode, &oepos, eloc, elen, 1);
+ if (!oepos.bh)
{
UDF_I_LENALLOC(inode) -= adsize;
mark_inode_dirty(inode);
}
else
{
- aed = (struct allocExtDesc *)(obh)->b_data;
+ aed = (struct allocExtDesc *)oepos.bh->b_data;
aed->lengthAllocDescs =
cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - adsize);
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
- udf_update_tag((obh)->b_data, oextoffset - adsize);
+ udf_update_tag(oepos.bh->b_data, epos.offset - adsize);
else
- udf_update_tag((obh)->b_data, sizeof(struct allocExtDesc));
- mark_buffer_dirty_inode(obh, inode);
+ udf_update_tag(oepos.bh->b_data, sizeof(struct allocExtDesc));
+ mark_buffer_dirty_inode(oepos.bh, inode);
}
}
- udf_release_data(nbh);
- udf_release_data(obh);
+ brelse(epos.bh);
+ brelse(oepos.bh);
return (elen >> 30);
}
-int8_t inode_bmap(struct inode *inode, int block, kernel_lb_addr *bloc, uint32_t *extoffset,
- kernel_lb_addr *eloc, uint32_t *elen, uint32_t *offset, struct buffer_head **bh)
+int8_t inode_bmap(struct inode *inode, sector_t block, struct extent_position *pos,
+ kernel_lb_addr *eloc, uint32_t *elen, sector_t *offset)
{
- uint64_t lbcount = 0, bcount = (uint64_t)block << inode->i_sb->s_blocksize_bits;
+ loff_t lbcount = 0, bcount = (loff_t)block << inode->i_sb->s_blocksize_bits;
int8_t etype;
if (block < 0)
@@ -1960,42 +2077,44 @@
return -1;
}
- *extoffset = 0;
+ pos->offset = 0;
+ pos->block = UDF_I_LOCATION(inode);
+ pos->bh = NULL;
*elen = 0;
- *bloc = UDF_I_LOCATION(inode);
do
{
- if ((etype = udf_next_aext(inode, bloc, extoffset, eloc, elen, bh, 1)) == -1)
+ if ((etype = udf_next_aext(inode, pos, eloc, elen, 1)) == -1)
{
- *offset = bcount - lbcount;
+ *offset = (bcount - lbcount) >> inode->i_sb->s_blocksize_bits;
UDF_I_LENEXTENTS(inode) = lbcount;
return -1;
}
lbcount += *elen;
} while (lbcount <= bcount);
- *offset = bcount + *elen - lbcount;
+ *offset = (bcount + *elen - lbcount) >> inode->i_sb->s_blocksize_bits;
return etype;
}
-long udf_block_map(struct inode *inode, long block)
+long udf_block_map(struct inode *inode, sector_t block)
{
- kernel_lb_addr eloc, bloc;
- uint32_t offset, extoffset, elen;
- struct buffer_head *bh = NULL;
+ kernel_lb_addr eloc;
+ uint32_t elen;
+ sector_t offset;
+ struct extent_position epos = { NULL, 0, { 0, 0}};
int ret;
lock_kernel();
- if (inode_bmap(inode, block, &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30))
- ret = udf_get_lb_pblock(inode->i_sb, eloc, offset >> inode->i_sb->s_blocksize_bits);
+ if (inode_bmap(inode, block, &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30))
+ ret = udf_get_lb_pblock(inode->i_sb, eloc, offset);
else
ret = 0;
unlock_kernel();
- udf_release_data(bh);
+ brelse(epos.bh);
if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV))
return udf_fixed_to_variable(ret);
diff --git a/fs/udf/misc.c b/fs/udf/misc.c
index cc8ca32..a2b2a98 100644
--- a/fs/udf/misc.c
+++ b/fs/udf/misc.c
@@ -274,12 +274,6 @@
loc.logicalBlockNum + offset, ident);
}
-void udf_release_data(struct buffer_head *bh)
-{
- if (bh)
- brelse(bh);
-}
-
void udf_update_tag(char *data, int length)
{
tag *tptr = (tag *)data;
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index fe361cd..91df492 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -155,9 +155,10 @@
uint8_t lfi;
uint16_t liu;
loff_t size;
- kernel_lb_addr bloc, eloc;
- uint32_t extoffset, elen, offset;
- struct buffer_head *bh = NULL;
+ kernel_lb_addr eloc;
+ uint32_t elen;
+ sector_t offset;
+ struct extent_position epos = { NULL, 0, { 0, 0}};
size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
f_pos = (udf_ext0_offset(dir) >> 2);
@@ -166,42 +167,41 @@
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
fibh->sbh = fibh->ebh = NULL;
else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
- &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30))
+ &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30))
{
- offset >>= dir->i_sb->s_blocksize_bits;
block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
if ((++offset << dir->i_sb->s_blocksize_bits) < elen)
{
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
- extoffset -= sizeof(short_ad);
+ epos.offset -= sizeof(short_ad);
else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
- extoffset -= sizeof(long_ad);
+ epos.offset -= sizeof(long_ad);
}
else
offset = 0;
if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block)))
{
- udf_release_data(bh);
+ brelse(epos.bh);
return NULL;
}
}
else
{
- udf_release_data(bh);
+ brelse(epos.bh);
return NULL;
}
while ( (f_pos < size) )
{
- fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh);
+ fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc, &elen, &offset);
if (!fi)
{
if (fibh->sbh != fibh->ebh)
- udf_release_data(fibh->ebh);
- udf_release_data(fibh->sbh);
- udf_release_data(bh);
+ brelse(fibh->ebh);
+ brelse(fibh->sbh);
+ brelse(epos.bh);
return NULL;
}
@@ -247,15 +247,15 @@
{
if (udf_match(flen, fname, dentry->d_name.len, dentry->d_name.name))
{
- udf_release_data(bh);
+ brelse(epos.bh);
return fi;
}
}
}
if (fibh->sbh != fibh->ebh)
- udf_release_data(fibh->ebh);
- udf_release_data(fibh->sbh);
- udf_release_data(bh);
+ brelse(fibh->ebh);
+ brelse(fibh->sbh);
+ brelse(epos.bh);
return NULL;
}
@@ -321,8 +321,8 @@
if (udf_find_entry(dir, dentry, &fibh, &cfi))
{
if (fibh.sbh != fibh.ebh)
- udf_release_data(fibh.ebh);
- udf_release_data(fibh.sbh);
+ brelse(fibh.ebh);
+ brelse(fibh.sbh);
inode = udf_iget(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation));
if ( !inode )
@@ -353,9 +353,10 @@
uint8_t lfi;
uint16_t liu;
int block;
- kernel_lb_addr bloc, eloc;
- uint32_t extoffset, elen, offset;
- struct buffer_head *bh = NULL;
+ kernel_lb_addr eloc;
+ uint32_t elen;
+ sector_t offset;
+ struct extent_position epos = { NULL, 0, { 0, 0 }};
sb = dir->i_sb;
@@ -384,23 +385,22 @@
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
fibh->sbh = fibh->ebh = NULL;
else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
- &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30))
+ &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30))
{
- offset >>= dir->i_sb->s_blocksize_bits;
block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
if ((++offset << dir->i_sb->s_blocksize_bits) < elen)
{
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
- extoffset -= sizeof(short_ad);
+ epos.offset -= sizeof(short_ad);
else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
- extoffset -= sizeof(long_ad);
+ epos.offset -= sizeof(long_ad);
}
else
offset = 0;
if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block)))
{
- udf_release_data(bh);
+ brelse(epos.bh);
*err = -EIO;
return NULL;
}
@@ -418,14 +418,14 @@
while ( (f_pos < size) )
{
- fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh);
+ fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc, &elen, &offset);
if (!fi)
{
if (fibh->sbh != fibh->ebh)
- udf_release_data(fibh->ebh);
- udf_release_data(fibh->sbh);
- udf_release_data(bh);
+ brelse(fibh->ebh);
+ brelse(fibh->sbh);
+ brelse(epos.bh);
*err = -EIO;
return NULL;
}
@@ -455,7 +455,7 @@
{
if (((sizeof(struct fileIdentDesc) + liu + lfi + 3) & ~3) == nfidlen)
{
- udf_release_data(bh);
+ brelse(epos.bh);
cfi->descTag.tagSerialNum = cpu_to_le16(1);
cfi->fileVersionNum = cpu_to_le16(1);
cfi->fileCharacteristics = 0;
@@ -478,9 +478,9 @@
udf_match(flen, fname, dentry->d_name.len, dentry->d_name.name))
{
if (fibh->sbh != fibh->ebh)
- udf_release_data(fibh->ebh);
- udf_release_data(fibh->sbh);
- udf_release_data(bh);
+ brelse(fibh->ebh);
+ brelse(fibh->sbh);
+ brelse(epos.bh);
*err = -EEXIST;
return NULL;
}
@@ -492,25 +492,25 @@
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB &&
sb->s_blocksize - fibh->eoffset < nfidlen)
{
- udf_release_data(bh);
- bh = NULL;
+ brelse(epos.bh);
+ epos.bh = NULL;
fibh->soffset -= udf_ext0_offset(dir);
fibh->eoffset -= udf_ext0_offset(dir);
f_pos -= (udf_ext0_offset(dir) >> 2);
if (fibh->sbh != fibh->ebh)
- udf_release_data(fibh->ebh);
- udf_release_data(fibh->sbh);
+ brelse(fibh->ebh);
+ brelse(fibh->sbh);
if (!(fibh->sbh = fibh->ebh = udf_expand_dir_adinicb(dir, &block, err)))
return NULL;
- bloc = UDF_I_LOCATION(dir);
+ epos.block = UDF_I_LOCATION(dir);
eloc.logicalBlockNum = block;
eloc.partitionReferenceNum = UDF_I_LOCATION(dir).partitionReferenceNum;
elen = dir->i_sb->s_blocksize;
- extoffset = udf_file_entry_alloc_offset(dir);
+ epos.offset = udf_file_entry_alloc_offset(dir);
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
- extoffset += sizeof(short_ad);
+ epos.offset += sizeof(short_ad);
else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
- extoffset += sizeof(long_ad);
+ epos.offset += sizeof(long_ad);
}
if (sb->s_blocksize - fibh->eoffset >= nfidlen)
@@ -519,7 +519,7 @@
fibh->eoffset += nfidlen;
if (fibh->sbh != fibh->ebh)
{
- udf_release_data(fibh->sbh);
+ brelse(fibh->sbh);
fibh->sbh = fibh->ebh;
}
@@ -541,7 +541,7 @@
fibh->eoffset += nfidlen - sb->s_blocksize;
if (fibh->sbh != fibh->ebh)
{
- udf_release_data(fibh->sbh);
+ brelse(fibh->sbh);
fibh->sbh = fibh->ebh;
}
@@ -550,14 +550,14 @@
if (!(fibh->ebh = udf_bread(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), 1, err)))
{
- udf_release_data(bh);
- udf_release_data(fibh->sbh);
+ brelse(epos.bh);
+ brelse(fibh->sbh);
return NULL;
}
if (!(fibh->soffset))
{
- if (udf_next_aext(dir, &bloc, &extoffset, &eloc, &elen, &bh, 1) ==
+ if (udf_next_aext(dir, &epos, &eloc, &elen, 1) ==
(EXT_RECORDED_ALLOCATED >> 30))
{
block = eloc.logicalBlockNum + ((elen - 1) >>
@@ -566,7 +566,7 @@
else
block ++;
- udf_release_data(fibh->sbh);
+ brelse(fibh->sbh);
fibh->sbh = fibh->ebh;
fi = (struct fileIdentDesc *)(fibh->sbh->b_data);
}
@@ -587,7 +587,7 @@
cfi->lengthOfImpUse = cpu_to_le16(0);
if (!udf_write_fi(dir, cfi, fi, fibh, NULL, name))
{
- udf_release_data(bh);
+ brelse(epos.bh);
dir->i_size += nfidlen;
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
UDF_I_LENALLOC(dir) += nfidlen;
@@ -596,10 +596,10 @@
}
else
{
- udf_release_data(bh);
+ brelse(epos.bh);
if (fibh->sbh != fibh->ebh)
- udf_release_data(fibh->ebh);
- udf_release_data(fibh->sbh);
+ brelse(fibh->ebh);
+ brelse(fibh->sbh);
*err = -EIO;
return NULL;
}
@@ -656,8 +656,8 @@
mark_inode_dirty(dir);
}
if (fibh.sbh != fibh.ebh)
- udf_release_data(fibh.ebh);
- udf_release_data(fibh.sbh);
+ brelse(fibh.ebh);
+ brelse(fibh.sbh);
unlock_kernel();
d_instantiate(dentry, inode);
return 0;
@@ -701,8 +701,8 @@
mark_inode_dirty(inode);
if (fibh.sbh != fibh.ebh)
- udf_release_data(fibh.ebh);
- udf_release_data(fibh.sbh);
+ brelse(fibh.ebh);
+ brelse(fibh.sbh);
d_instantiate(dentry, inode);
err = 0;
out:
@@ -743,7 +743,7 @@
cpu_to_le32(UDF_I_UNIQUE(dir) & 0x00000000FFFFFFFFUL);
cfi.fileCharacteristics = FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT;
udf_write_fi(inode, &cfi, fi, &fibh, NULL, NULL);
- udf_release_data(fibh.sbh);
+ brelse(fibh.sbh);
inode->i_mode = S_IFDIR | mode;
if (dir->i_mode & S_ISGID)
inode->i_mode |= S_ISGID;
@@ -766,8 +766,8 @@
mark_inode_dirty(dir);
d_instantiate(dentry, inode);
if (fibh.sbh != fibh.ebh)
- udf_release_data(fibh.ebh);
- udf_release_data(fibh.sbh);
+ brelse(fibh.ebh);
+ brelse(fibh.sbh);
err = 0;
out:
unlock_kernel();
@@ -781,9 +781,10 @@
loff_t f_pos;
loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
int block;
- kernel_lb_addr bloc, eloc;
- uint32_t extoffset, elen, offset;
- struct buffer_head *bh = NULL;
+ kernel_lb_addr eloc;
+ uint32_t elen;
+ sector_t offset;
+ struct extent_position epos = { NULL, 0, { 0, 0}};
f_pos = (udf_ext0_offset(dir) >> 2);
@@ -792,59 +793,58 @@
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
fibh.sbh = fibh.ebh = NULL;
else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
- &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30))
+ &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30))
{
- offset >>= dir->i_sb->s_blocksize_bits;
block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
if ((++offset << dir->i_sb->s_blocksize_bits) < elen)
{
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
- extoffset -= sizeof(short_ad);
+ epos.offset -= sizeof(short_ad);
else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
- extoffset -= sizeof(long_ad);
+ epos.offset -= sizeof(long_ad);
}
else
offset = 0;
if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block)))
{
- udf_release_data(bh);
+ brelse(epos.bh);
return 0;
}
}
else
{
- udf_release_data(bh);
+ brelse(epos.bh);
return 0;
}
while ( (f_pos < size) )
{
- fi = udf_fileident_read(dir, &f_pos, &fibh, &cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh);
+ fi = udf_fileident_read(dir, &f_pos, &fibh, &cfi, &epos, &eloc, &elen, &offset);
if (!fi)
{
if (fibh.sbh != fibh.ebh)
- udf_release_data(fibh.ebh);
- udf_release_data(fibh.sbh);
- udf_release_data(bh);
+ brelse(fibh.ebh);
+ brelse(fibh.sbh);
+ brelse(epos.bh);
return 0;
}
if (cfi.lengthFileIdent && (cfi.fileCharacteristics & FID_FILE_CHAR_DELETED) == 0)
{
if (fibh.sbh != fibh.ebh)
- udf_release_data(fibh.ebh);
- udf_release_data(fibh.sbh);
- udf_release_data(bh);
+ brelse(fibh.ebh);
+ brelse(fibh.sbh);
+ brelse(epos.bh);
return 0;
}
}
if (fibh.sbh != fibh.ebh)
- udf_release_data(fibh.ebh);
- udf_release_data(fibh.sbh);
- udf_release_data(bh);
+ brelse(fibh.ebh);
+ brelse(fibh.sbh);
+ brelse(epos.bh);
return 1;
}
@@ -878,14 +878,14 @@
inode->i_nlink);
clear_nlink(inode);
inode->i_size = 0;
- inode_dec_link_count(inode);
+ inode_dec_link_count(dir);
inode->i_ctime = dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb);
mark_inode_dirty(dir);
end_rmdir:
if (fibh.sbh != fibh.ebh)
- udf_release_data(fibh.ebh);
- udf_release_data(fibh.sbh);
+ brelse(fibh.ebh);
+ brelse(fibh.sbh);
out:
unlock_kernel();
return retval;
@@ -928,8 +928,8 @@
end_unlink:
if (fibh.sbh != fibh.ebh)
- udf_release_data(fibh.ebh);
- udf_release_data(fibh.sbh);
+ brelse(fibh.ebh);
+ brelse(fibh.sbh);
out:
unlock_kernel();
return retval;
@@ -941,7 +941,7 @@
struct pathComponent *pc;
char *compstart;
struct udf_fileident_bh fibh;
- struct buffer_head *bh = NULL;
+ struct extent_position epos = { NULL, 0, {0, 0}};
int eoffset, elen = 0;
struct fileIdentDesc *fi;
struct fileIdentDesc cfi;
@@ -961,33 +961,33 @@
if (UDF_I_ALLOCTYPE(inode) != ICBTAG_FLAG_AD_IN_ICB)
{
- struct buffer_head *bh = NULL;
- kernel_lb_addr bloc, eloc;
- uint32_t elen, extoffset;
+ kernel_lb_addr eloc;
+ uint32_t elen;
block = udf_new_block(inode->i_sb, inode,
UDF_I_LOCATION(inode).partitionReferenceNum,
UDF_I_LOCATION(inode).logicalBlockNum, &err);
if (!block)
goto out_no_entry;
- bloc = UDF_I_LOCATION(inode);
+ epos.block = UDF_I_LOCATION(inode);
+ epos.offset = udf_file_entry_alloc_offset(inode);
+ epos.bh = NULL;
eloc.logicalBlockNum = block;
eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;
elen = inode->i_sb->s_blocksize;
UDF_I_LENEXTENTS(inode) = elen;
- extoffset = udf_file_entry_alloc_offset(inode);
- udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 0);
- udf_release_data(bh);
+ udf_add_aext(inode, &epos, eloc, elen, 0);
+ brelse(epos.bh);
block = udf_get_pblock(inode->i_sb, block,
UDF_I_LOCATION(inode).partitionReferenceNum, 0);
- bh = udf_tread(inode->i_sb, block);
- lock_buffer(bh);
- memset(bh->b_data, 0x00, inode->i_sb->s_blocksize);
- set_buffer_uptodate(bh);
- unlock_buffer(bh);
- mark_buffer_dirty_inode(bh, inode);
- ea = bh->b_data + udf_ext0_offset(inode);
+ epos.bh = udf_tread(inode->i_sb, block);
+ lock_buffer(epos.bh);
+ memset(epos.bh->b_data, 0x00, inode->i_sb->s_blocksize);
+ set_buffer_uptodate(epos.bh);
+ unlock_buffer(epos.bh);
+ mark_buffer_dirty_inode(epos.bh, inode);
+ ea = epos.bh->b_data + udf_ext0_offset(inode);
}
else
ea = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode);
@@ -1060,7 +1060,7 @@
}
}
- udf_release_data(bh);
+ brelse(epos.bh);
inode->i_size = elen;
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
UDF_I_LENALLOC(inode) = inode->i_size;
@@ -1089,8 +1089,8 @@
mark_inode_dirty(dir);
}
if (fibh.sbh != fibh.ebh)
- udf_release_data(fibh.ebh);
- udf_release_data(fibh.sbh);
+ brelse(fibh.ebh);
+ brelse(fibh.sbh);
d_instantiate(dentry, inode);
err = 0;
@@ -1145,8 +1145,8 @@
mark_inode_dirty(dir);
}
if (fibh.sbh != fibh.ebh)
- udf_release_data(fibh.ebh);
- udf_release_data(fibh.sbh);
+ brelse(fibh.ebh);
+ brelse(fibh.sbh);
inc_nlink(inode);
inode->i_ctime = current_fs_time(inode->i_sb);
mark_inode_dirty(inode);
@@ -1174,8 +1174,8 @@
if ((ofi = udf_find_entry(old_dir, old_dentry, &ofibh, &ocfi)))
{
if (ofibh.sbh != ofibh.ebh)
- udf_release_data(ofibh.ebh);
- udf_release_data(ofibh.sbh);
+ brelse(ofibh.ebh);
+ brelse(ofibh.sbh);
}
tloc = lelb_to_cpu(ocfi.icb.extLocation);
if (!ofi || udf_get_lb_pblock(old_dir->i_sb, tloc, 0)
@@ -1188,8 +1188,8 @@
if (!new_inode)
{
if (nfibh.sbh != nfibh.ebh)
- udf_release_data(nfibh.ebh);
- udf_release_data(nfibh.sbh);
+ brelse(nfibh.ebh);
+ brelse(nfibh.sbh);
nfi = NULL;
}
}
@@ -1290,19 +1290,19 @@
if (ofi)
{
if (ofibh.sbh != ofibh.ebh)
- udf_release_data(ofibh.ebh);
- udf_release_data(ofibh.sbh);
+ brelse(ofibh.ebh);
+ brelse(ofibh.sbh);
}
retval = 0;
end_rename:
- udf_release_data(dir_bh);
+ brelse(dir_bh);
if (nfi)
{
if (nfibh.sbh != nfibh.ebh)
- udf_release_data(nfibh.ebh);
- udf_release_data(nfibh.sbh);
+ brelse(nfibh.ebh);
+ brelse(nfibh.sbh);
}
unlock_kernel();
return retval;
diff --git a/fs/udf/partition.c b/fs/udf/partition.c
index dabf2b8..467a261 100644
--- a/fs/udf/partition.c
+++ b/fs/udf/partition.c
@@ -81,7 +81,7 @@
loc = le32_to_cpu(((__le32 *)bh->b_data)[index]);
- udf_release_data(bh);
+ brelse(bh);
if (UDF_I_LOCATION(UDF_SB_VAT(sb)).partitionReferenceNum == partition)
{
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 023b304..9b8644a 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -563,7 +563,7 @@
if (vsd->stdIdent[0] == 0)
{
- udf_release_data(bh);
+ brelse(bh);
break;
}
else if (!strncmp(vsd->stdIdent, VSD_STD_ID_CD001, VSD_STD_ID_LEN))
@@ -596,7 +596,7 @@
}
else if (!strncmp(vsd->stdIdent, VSD_STD_ID_TEA01, VSD_STD_ID_LEN))
{
- udf_release_data(bh);
+ brelse(bh);
break;
}
else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR02, VSD_STD_ID_LEN))
@@ -607,7 +607,7 @@
{
nsr03 = sector;
}
- udf_release_data(bh);
+ brelse(bh);
}
if (nsr03)
@@ -673,7 +673,7 @@
{
ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
- udf_release_data(bh);
+ brelse(bh);
}
if (ident == TAG_IDENT_AVDP)
@@ -708,7 +708,7 @@
{
ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
- udf_release_data(bh);
+ brelse(bh);
}
if (ident == TAG_IDENT_AVDP &&
@@ -727,7 +727,7 @@
{
ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
- udf_release_data(bh);
+ brelse(bh);
}
if (ident == TAG_IDENT_AVDP &&
@@ -749,7 +749,7 @@
{
ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
- udf_release_data(bh);
+ brelse(bh);
if (ident == TAG_IDENT_AVDP && location == 256)
UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
@@ -766,7 +766,7 @@
}
else
{
- udf_release_data(bh);
+ brelse(bh);
if ((ident != TAG_IDENT_AVDP) && (i ||
(ident != TAG_IDENT_FE && ident != TAG_IDENT_EFE)))
{
@@ -795,7 +795,7 @@
return 1;
else if (ident != TAG_IDENT_FSD)
{
- udf_release_data(bh);
+ brelse(bh);
return 1;
}
@@ -834,7 +834,7 @@
newfileset.logicalBlockNum += 1 +
((le32_to_cpu(sp->numOfBytes) + sizeof(struct spaceBitmapDesc) - 1)
>> sb->s_blocksize_bits);
- udf_release_data(bh);
+ brelse(bh);
break;
}
case TAG_IDENT_FSD:
@@ -845,7 +845,7 @@
default:
{
newfileset.logicalBlockNum ++;
- udf_release_data(bh);
+ brelse(bh);
bh = NULL;
break;
}
@@ -865,7 +865,7 @@
UDF_SB_PARTITION(sb) = fileset->partitionReferenceNum;
udf_load_fileset(sb, bh, root);
- udf_release_data(bh);
+ brelse(bh);
return 0;
}
return 1;
@@ -1083,7 +1083,7 @@
if (ident != 0 ||
strncmp(st->sparingIdent.ident, UDF_ID_SPARING, strlen(UDF_ID_SPARING)))
{
- udf_release_data(UDF_SB_TYPESPAR(sb,i).s_spar_map[j]);
+ brelse(UDF_SB_TYPESPAR(sb,i).s_spar_map[j]);
UDF_SB_TYPESPAR(sb,i).s_spar_map[j] = NULL;
}
}
@@ -1137,12 +1137,12 @@
udf_load_logicalvolint(sb, leea_to_cpu(UDF_SB_LVID(sb)->nextIntegrityExt));
if (UDF_SB_LVIDBH(sb) != bh)
- udf_release_data(bh);
+ brelse(bh);
loc.extLength -= sb->s_blocksize;
loc.extLocation ++;
}
if (UDF_SB_LVIDBH(sb) != bh)
- udf_release_data(bh);
+ brelse(bh);
}
/*
@@ -1245,7 +1245,7 @@
done = 1;
break;
}
- udf_release_data(bh);
+ brelse(bh);
}
for (i=0; i<VDS_POS_LENGTH; i++)
{
@@ -1267,10 +1267,10 @@
gd = (struct generic_desc *)bh2->b_data;
if (ident == TAG_IDENT_PD)
udf_load_partdesc(sb, bh2);
- udf_release_data(bh2);
+ brelse(bh2);
}
}
- udf_release_data(bh);
+ brelse(bh);
}
}
@@ -1333,7 +1333,7 @@
reserve_e = reserve_e >> sb->s_blocksize_bits;
reserve_e += reserve_s;
- udf_release_data(bh);
+ brelse(bh);
/* Process the main & reserve sequences */
/* responsible for finding the PartitionDesc(s) */
@@ -1403,12 +1403,14 @@
pos = udf_block_map(UDF_SB_VAT(sb), 0);
bh = sb_bread(sb, pos);
+ if (!bh)
+ return 1;
UDF_SB_TYPEVIRT(sb,i).s_start_offset =
le16_to_cpu(((struct virtualAllocationTable20 *)bh->b_data + udf_ext0_offset(UDF_SB_VAT(sb)))->lengthHeader) +
udf_ext0_offset(UDF_SB_VAT(sb));
UDF_SB_TYPEVIRT(sb,i).s_num_entries = (UDF_SB_VAT(sb)->i_size -
UDF_SB_TYPEVIRT(sb,i).s_start_offset) >> 2;
- udf_release_data(bh);
+ brelse(bh);
}
UDF_SB_PARTROOT(sb,i) = udf_get_pblock(sb, 0, i, 0);
UDF_SB_PARTLEN(sb,i) = UDF_SB_PARTLEN(sb,ino.partitionReferenceNum);
@@ -1661,7 +1663,7 @@
iput(inode);
goto error_out;
}
- sb->s_maxbytes = 1<<30;
+ sb->s_maxbytes = MAX_LFS_FILESIZE;
return 0;
error_out:
@@ -1680,7 +1682,7 @@
if (UDF_SB_PARTTYPE(sb, UDF_SB_PARTITION(sb)) == UDF_SPARABLE_MAP15)
{
for (i=0; i<4; i++)
- udf_release_data(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]);
+ brelse(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]);
}
}
#ifdef CONFIG_UDF_NLS
@@ -1689,7 +1691,7 @@
#endif
if (!(sb->s_flags & MS_RDONLY))
udf_close_lvid(sb);
- udf_release_data(UDF_SB_LVIDBH(sb));
+ brelse(UDF_SB_LVIDBH(sb));
UDF_SB_FREE(sb);
kfree(sbi);
sb->s_fs_info = NULL;
@@ -1758,7 +1760,7 @@
if (UDF_SB_PARTTYPE(sb, UDF_SB_PARTITION(sb)) == UDF_SPARABLE_MAP15)
{
for (i=0; i<4; i++)
- udf_release_data(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]);
+ brelse(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]);
}
}
#ifdef CONFIG_UDF_NLS
@@ -1767,7 +1769,7 @@
#endif
if (!(sb->s_flags & MS_RDONLY))
udf_close_lvid(sb);
- udf_release_data(UDF_SB_LVIDBH(sb));
+ brelse(UDF_SB_LVIDBH(sb));
UDF_SB_FREE(sb);
kfree(sb->s_fs_info);
sb->s_fs_info = NULL;
@@ -1837,7 +1839,7 @@
}
else if (ident != TAG_IDENT_SBD)
{
- udf_release_data(bh);
+ brelse(bh);
printk(KERN_ERR "udf: udf_count_free failed\n");
goto out;
}
@@ -1859,7 +1861,7 @@
}
if ( bytes )
{
- udf_release_data(bh);
+ brelse(bh);
newblock = udf_get_lb_pblock(sb, loc, ++block);
bh = udf_tread(sb, newblock);
if (!bh)
@@ -1871,7 +1873,7 @@
ptr = (uint8_t *)bh->b_data;
}
}
- udf_release_data(bh);
+ brelse(bh);
out:
unlock_kernel();
@@ -1883,21 +1885,20 @@
udf_count_free_table(struct super_block *sb, struct inode * table)
{
unsigned int accum = 0;
- uint32_t extoffset, elen;
- kernel_lb_addr bloc, eloc;
+ uint32_t elen;
+ kernel_lb_addr eloc;
int8_t etype;
- struct buffer_head *bh = NULL;
+ struct extent_position epos;
lock_kernel();
- bloc = UDF_I_LOCATION(table);
- extoffset = sizeof(struct unallocSpaceEntry);
+ epos.block = UDF_I_LOCATION(table);
+ epos.offset = sizeof(struct unallocSpaceEntry);
+ epos.bh = NULL;
- while ((etype = udf_next_aext(table, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1)
- {
+ while ((etype = udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1)
accum += (elen >> table->i_sb->s_blocksize_bits);
- }
- udf_release_data(bh);
+ brelse(epos.bh);
unlock_kernel();
diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c
index ba068a7..12613b6 100644
--- a/fs/udf/symlink.c
+++ b/fs/udf/symlink.c
@@ -95,7 +95,7 @@
}
udf_pc_to_char(inode->i_sb, symlink, inode->i_size, p);
- udf_release_data(bh);
+ brelse(bh);
unlock_kernel();
SetPageUptodate(page);
diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c
index 0abd66c..77975ae 100644
--- a/fs/udf/truncate.c
+++ b/fs/udf/truncate.c
@@ -28,8 +28,8 @@
#include "udf_i.h"
#include "udf_sb.h"
-static void extent_trunc(struct inode * inode, kernel_lb_addr bloc, int extoffset,
- kernel_lb_addr eloc, int8_t etype, uint32_t elen, struct buffer_head *bh, uint32_t nelen)
+static void extent_trunc(struct inode * inode, struct extent_position *epos,
+ kernel_lb_addr eloc, int8_t etype, uint32_t elen, uint32_t nelen)
{
kernel_lb_addr neloc = { 0, 0 };
int last_block = (elen + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
@@ -49,7 +49,7 @@
if (elen != nelen)
{
- udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 0);
+ udf_write_aext(inode, epos, neloc, nelen, 0);
if (last_block - first_block > 0)
{
if (etype == (EXT_RECORDED_ALLOCATED >> 30))
@@ -63,18 +63,16 @@
void udf_discard_prealloc(struct inode * inode)
{
- kernel_lb_addr bloc, eloc;
- uint32_t extoffset = 0, elen, nelen;
+ struct extent_position epos = { NULL, 0, {0, 0}};
+ kernel_lb_addr eloc;
+ uint32_t elen, nelen;
uint64_t lbcount = 0;
int8_t etype = -1, netype;
- struct buffer_head *bh = NULL;
int adsize;
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB ||
inode->i_size == UDF_I_LENEXTENTS(inode))
- {
return;
- }
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
adsize = sizeof(short_ad);
@@ -83,52 +81,58 @@
else
adsize = 0;
- bloc = UDF_I_LOCATION(inode);
+ epos.block = UDF_I_LOCATION(inode);
- while ((netype = udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1)
+ /* Find the last extent in the file */
+ while ((netype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1)
{
etype = netype;
lbcount += elen;
- if (lbcount > inode->i_size && lbcount - inode->i_size < inode->i_sb->s_blocksize)
+ if (lbcount > inode->i_size && lbcount - elen < inode->i_size)
{
+ WARN_ON(lbcount - inode->i_size >= inode->i_sb->s_blocksize);
nelen = elen - (lbcount - inode->i_size);
- extent_trunc(inode, bloc, extoffset-adsize, eloc, etype, elen, bh, nelen);
+ epos.offset -= adsize;
+ extent_trunc(inode, &epos, eloc, etype, elen, nelen);
+ epos.offset += adsize;
lbcount = inode->i_size;
}
}
- if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
- {
- extoffset -= adsize;
+ if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) {
+ epos.offset -= adsize;
lbcount -= elen;
- extent_trunc(inode, bloc, extoffset, eloc, etype, elen, bh, 0);
- if (!bh)
+ extent_trunc(inode, &epos, eloc, etype, elen, 0);
+ if (!epos.bh)
{
- UDF_I_LENALLOC(inode) = extoffset - udf_file_entry_alloc_offset(inode);
+ UDF_I_LENALLOC(inode) = epos.offset - udf_file_entry_alloc_offset(inode);
mark_inode_dirty(inode);
}
else
{
- struct allocExtDesc *aed = (struct allocExtDesc *)(bh->b_data);
- aed->lengthAllocDescs = cpu_to_le32(extoffset - sizeof(struct allocExtDesc));
+ struct allocExtDesc *aed = (struct allocExtDesc *)(epos.bh->b_data);
+ aed->lengthAllocDescs = cpu_to_le32(epos.offset - sizeof(struct allocExtDesc));
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
- udf_update_tag(bh->b_data, extoffset);
+ udf_update_tag(epos.bh->b_data, epos.offset);
else
- udf_update_tag(bh->b_data, sizeof(struct allocExtDesc));
- mark_buffer_dirty_inode(bh, inode);
+ udf_update_tag(epos.bh->b_data, sizeof(struct allocExtDesc));
+ mark_buffer_dirty_inode(epos.bh, inode);
}
}
UDF_I_LENEXTENTS(inode) = lbcount;
- udf_release_data(bh);
+ WARN_ON(lbcount != inode->i_size);
+ brelse(epos.bh);
}
void udf_truncate_extents(struct inode * inode)
{
- kernel_lb_addr bloc, eloc, neloc = { 0, 0 };
- uint32_t extoffset, elen, offset, nelen = 0, lelen = 0, lenalloc;
+ struct extent_position epos;
+ kernel_lb_addr eloc, neloc = { 0, 0 };
+ uint32_t elen, nelen = 0, indirect_ext_len = 0, lenalloc;
int8_t etype;
- int first_block = inode->i_size >> inode->i_sb->s_blocksize_bits;
- struct buffer_head *bh = NULL;
+ struct super_block *sb = inode->i_sb;
+ sector_t first_block = inode->i_size >> sb->s_blocksize_bits, offset;
+ loff_t byte_offset;
int adsize;
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
@@ -136,158 +140,130 @@
else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG)
adsize = sizeof(long_ad);
else
- adsize = 0;
+ BUG();
- etype = inode_bmap(inode, first_block, &bloc, &extoffset, &eloc, &elen, &offset, &bh);
- offset += (inode->i_size & (inode->i_sb->s_blocksize - 1));
+ etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset);
+ byte_offset = (offset << sb->s_blocksize_bits) + (inode->i_size & (sb->s_blocksize-1));
if (etype != -1)
{
- extoffset -= adsize;
- extent_trunc(inode, bloc, extoffset, eloc, etype, elen, bh, offset);
- extoffset += adsize;
-
- if (offset)
- lenalloc = extoffset;
+ epos.offset -= adsize;
+ extent_trunc(inode, &epos, eloc, etype, elen, byte_offset);
+ epos.offset += adsize;
+ if (byte_offset)
+ lenalloc = epos.offset;
else
- lenalloc = extoffset - adsize;
+ lenalloc = epos.offset - adsize;
- if (!bh)
+ if (!epos.bh)
lenalloc -= udf_file_entry_alloc_offset(inode);
else
lenalloc -= sizeof(struct allocExtDesc);
- while ((etype = udf_current_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 0)) != -1)
+ while ((etype = udf_current_aext(inode, &epos, &eloc, &elen, 0)) != -1)
{
if (etype == (EXT_NEXT_EXTENT_ALLOCDECS >> 30))
{
- udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 0);
- extoffset = 0;
- if (lelen)
+ udf_write_aext(inode, &epos, neloc, nelen, 0);
+ if (indirect_ext_len)
{
- if (!bh)
+ /* We managed to free all extents in the
+ * indirect extent - free it too */
+ if (!epos.bh)
BUG();
- else
- memset(bh->b_data, 0x00, sizeof(struct allocExtDesc));
- udf_free_blocks(inode->i_sb, inode, bloc, 0, lelen);
+ udf_free_blocks(sb, inode, epos.block, 0, indirect_ext_len);
}
else
{
- if (!bh)
+ if (!epos.bh)
{
UDF_I_LENALLOC(inode) = lenalloc;
mark_inode_dirty(inode);
}
else
{
- struct allocExtDesc *aed = (struct allocExtDesc *)(bh->b_data);
+ struct allocExtDesc *aed = (struct allocExtDesc *)(epos.bh->b_data);
aed->lengthAllocDescs = cpu_to_le32(lenalloc);
- if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
- udf_update_tag(bh->b_data, lenalloc +
+ if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(sb) >= 0x0201)
+ udf_update_tag(epos.bh->b_data, lenalloc +
sizeof(struct allocExtDesc));
else
- udf_update_tag(bh->b_data, sizeof(struct allocExtDesc));
- mark_buffer_dirty_inode(bh, inode);
+ udf_update_tag(epos.bh->b_data, sizeof(struct allocExtDesc));
+ mark_buffer_dirty_inode(epos.bh, inode);
}
}
-
- udf_release_data(bh);
- extoffset = sizeof(struct allocExtDesc);
- bloc = eloc;
- bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, bloc, 0));
+ brelse(epos.bh);
+ epos.offset = sizeof(struct allocExtDesc);
+ epos.block = eloc;
+ epos.bh = udf_tread(sb, udf_get_lb_pblock(sb, eloc, 0));
if (elen)
- lelen = (elen + inode->i_sb->s_blocksize - 1) >>
- inode->i_sb->s_blocksize_bits;
+ indirect_ext_len = (elen +
+ sb->s_blocksize - 1) >>
+ sb->s_blocksize_bits;
else
- lelen = 1;
+ indirect_ext_len = 1;
}
else
{
- extent_trunc(inode, bloc, extoffset, eloc, etype, elen, bh, 0);
- extoffset += adsize;
+ extent_trunc(inode, &epos, eloc, etype, elen, 0);
+ epos.offset += adsize;
}
}
- if (lelen)
+ if (indirect_ext_len)
{
- if (!bh)
+ if (!epos.bh)
BUG();
- else
- memset(bh->b_data, 0x00, sizeof(struct allocExtDesc));
- udf_free_blocks(inode->i_sb, inode, bloc, 0, lelen);
+ udf_free_blocks(sb, inode, epos.block, 0, indirect_ext_len);
}
else
{
- if (!bh)
+ if (!epos.bh)
{
UDF_I_LENALLOC(inode) = lenalloc;
mark_inode_dirty(inode);
}
else
{
- struct allocExtDesc *aed = (struct allocExtDesc *)(bh->b_data);
+ struct allocExtDesc *aed = (struct allocExtDesc *)(epos.bh->b_data);
aed->lengthAllocDescs = cpu_to_le32(lenalloc);
- if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
- udf_update_tag(bh->b_data, lenalloc +
+ if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(sb) >= 0x0201)
+ udf_update_tag(epos.bh->b_data, lenalloc +
sizeof(struct allocExtDesc));
else
- udf_update_tag(bh->b_data, sizeof(struct allocExtDesc));
- mark_buffer_dirty_inode(bh, inode);
+ udf_update_tag(epos.bh->b_data, sizeof(struct allocExtDesc));
+ mark_buffer_dirty_inode(epos.bh, inode);
}
}
}
else if (inode->i_size)
{
- if (offset)
+ if (byte_offset)
{
+ kernel_long_ad extent;
+
/*
* OK, there is not extent covering inode->i_size and
* no extent above inode->i_size => truncate is
- * extending the file by 'offset'.
+ * extending the file by 'offset' blocks.
*/
- if ((!bh && extoffset == udf_file_entry_alloc_offset(inode)) ||
- (bh && extoffset == sizeof(struct allocExtDesc))) {
- /* File has no extents at all! */
- memset(&eloc, 0x00, sizeof(kernel_lb_addr));
- elen = EXT_NOT_RECORDED_NOT_ALLOCATED | offset;
- udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1);
+ if ((!epos.bh && epos.offset == udf_file_entry_alloc_offset(inode)) ||
+ (epos.bh && epos.offset == sizeof(struct allocExtDesc))) {
+ /* File has no extents at all or has empty last
+ * indirect extent! Create a fake extent... */
+ extent.extLocation.logicalBlockNum = 0;
+ extent.extLocation.partitionReferenceNum = 0;
+ extent.extLength = EXT_NOT_RECORDED_NOT_ALLOCATED;
}
else {
- extoffset -= adsize;
- etype = udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 1);
- if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
- {
- extoffset -= adsize;
- elen = EXT_NOT_RECORDED_NOT_ALLOCATED | (elen + offset);
- udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 0);
- }
- else if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
- {
- kernel_lb_addr neloc = { 0, 0 };
- extoffset -= adsize;
- nelen = EXT_NOT_RECORDED_NOT_ALLOCATED |
- ((elen + offset + inode->i_sb->s_blocksize - 1) &
- ~(inode->i_sb->s_blocksize - 1));
- udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1);
- udf_add_aext(inode, &bloc, &extoffset, eloc, (etype << 30) | elen, &bh, 1);
- }
- else
- {
- if (elen & (inode->i_sb->s_blocksize - 1))
- {
- extoffset -= adsize;
- elen = EXT_RECORDED_ALLOCATED |
- ((elen + inode->i_sb->s_blocksize - 1) &
- ~(inode->i_sb->s_blocksize - 1));
- udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 1);
- }
- memset(&eloc, 0x00, sizeof(kernel_lb_addr));
- elen = EXT_NOT_RECORDED_NOT_ALLOCATED | offset;
- udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1);
- }
+ epos.offset -= adsize;
+ etype = udf_next_aext(inode, &epos,
+ &extent.extLocation, &extent.extLength, 0);
+ extent.extLength |= etype << 30;
}
+ udf_extend_file(inode, &epos, &extent, offset+((inode->i_size & (sb->s_blocksize-1)) != 0));
}
}
UDF_I_LENEXTENTS(inode) = inode->i_size;
- udf_release_data(bh);
+ brelse(epos.bh);
}
diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h
index 110f8d6..3b2e6c8 100644
--- a/fs/udf/udf_sb.h
+++ b/fs/udf/udf_sb.h
@@ -93,7 +93,7 @@
for (i=0; i<nr_groups; i++)\
{\
if (UDF_SB_BITMAP(X,Y,Z,i))\
- udf_release_data(UDF_SB_BITMAP(X,Y,Z,i));\
+ brelse(UDF_SB_BITMAP(X,Y,Z,i));\
}\
if (size <= PAGE_SIZE)\
kfree(UDF_SB_PARTMAPS(X)[Y].Z.s_bitmap);\
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h
index ee1dece..67ded28 100644
--- a/fs/udf/udfdecl.h
+++ b/fs/udf/udfdecl.h
@@ -77,6 +77,13 @@
uint8_t u_len;
};
+struct extent_position {
+ struct buffer_head *bh;
+ uint32_t offset;
+ kernel_lb_addr block;
+};
+
+
/* super.c */
extern void udf_error(struct super_block *, const char *, const char *, ...);
extern void udf_warning(struct super_block *, const char *, const char *, ...);
@@ -98,13 +105,14 @@
extern void udf_delete_inode(struct inode *);
extern void udf_clear_inode(struct inode *);
extern int udf_write_inode(struct inode *, int);
-extern long udf_block_map(struct inode *, long);
-extern int8_t inode_bmap(struct inode *, int, kernel_lb_addr *, uint32_t *, kernel_lb_addr *, uint32_t *, uint32_t *, struct buffer_head **);
-extern int8_t udf_add_aext(struct inode *, kernel_lb_addr *, int *, kernel_lb_addr, uint32_t, struct buffer_head **, int);
-extern int8_t udf_write_aext(struct inode *, kernel_lb_addr, int *, kernel_lb_addr, uint32_t, struct buffer_head *, int);
-extern int8_t udf_delete_aext(struct inode *, kernel_lb_addr, int, kernel_lb_addr, uint32_t, struct buffer_head *);
-extern int8_t udf_next_aext(struct inode *, kernel_lb_addr *, int *, kernel_lb_addr *, uint32_t *, struct buffer_head **, int);
-extern int8_t udf_current_aext(struct inode *, kernel_lb_addr *, int *, kernel_lb_addr *, uint32_t *, struct buffer_head **, int);
+extern long udf_block_map(struct inode *, sector_t);
+extern int udf_extend_file(struct inode *, struct extent_position *, kernel_long_ad *, sector_t);
+extern int8_t inode_bmap(struct inode *, sector_t, struct extent_position *, kernel_lb_addr *, uint32_t *, sector_t *);
+extern int8_t udf_add_aext(struct inode *, struct extent_position *, kernel_lb_addr, uint32_t, int);
+extern int8_t udf_write_aext(struct inode *, struct extent_position *, kernel_lb_addr, uint32_t, int);
+extern int8_t udf_delete_aext(struct inode *, struct extent_position, kernel_lb_addr, uint32_t);
+extern int8_t udf_next_aext(struct inode *, struct extent_position *, kernel_lb_addr *, uint32_t *, int);
+extern int8_t udf_current_aext(struct inode *, struct extent_position *, kernel_lb_addr *, uint32_t *, int);
/* misc.c */
extern struct buffer_head *udf_tgetblk(struct super_block *, int);
@@ -113,7 +121,6 @@
extern struct genericFormat *udf_get_extendedattr(struct inode *, uint32_t, uint8_t);
extern struct buffer_head *udf_read_tagged(struct super_block *, uint32_t, uint32_t, uint16_t *);
extern struct buffer_head *udf_read_ptagged(struct super_block *, kernel_lb_addr, uint32_t, uint16_t *);
-extern void udf_release_data(struct buffer_head *);
extern void udf_update_tag(char *, int);
extern void udf_new_tag(char *, uint16_t, uint16_t, uint16_t, uint32_t, int);
@@ -151,7 +158,7 @@
extern int udf_fsync_file(struct file *, struct dentry *, int);
/* directory.c */
-extern struct fileIdentDesc * udf_fileident_read(struct inode *, loff_t *, struct udf_fileident_bh *, struct fileIdentDesc *, kernel_lb_addr *, uint32_t *, kernel_lb_addr *, uint32_t *, uint32_t *, struct buffer_head **);
+extern struct fileIdentDesc * udf_fileident_read(struct inode *, loff_t *, struct udf_fileident_bh *, struct fileIdentDesc *, struct extent_position *, kernel_lb_addr *, uint32_t *, sector_t *);
extern struct fileIdentDesc * udf_get_fileident(void * buffer, int bufsize, int * offset);
extern long_ad * udf_get_filelongad(uint8_t *, int, int *, int);
extern short_ad * udf_get_fileshortad(uint8_t *, int, int *, int);
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
index 4fb8b2e..1544521 100644
--- a/fs/ufs/dir.c
+++ b/fs/ufs/dir.c
@@ -19,7 +19,6 @@
#include <linux/time.h>
#include <linux/fs.h>
#include <linux/ufs_fs.h>
-#include <linux/smp_lock.h>
#include "swab.h"
#include "util.h"
diff --git a/fs/utimes.c b/fs/utimes.c
index 99cf2cb..480f7c8 100644
--- a/fs/utimes.c
+++ b/fs/utimes.c
@@ -1,8 +1,10 @@
#include <linux/compiler.h>
+#include <linux/file.h>
#include <linux/fs.h>
#include <linux/linkage.h>
#include <linux/namei.h>
#include <linux/sched.h>
+#include <linux/stat.h>
#include <linux/utime.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
@@ -20,54 +22,18 @@
* must be owner or have write permission.
* Else, update from *times, must be owner or super user.
*/
-asmlinkage long sys_utime(char __user * filename, struct utimbuf __user * times)
+asmlinkage long sys_utime(char __user *filename, struct utimbuf __user *times)
{
- int error;
- struct nameidata nd;
- struct inode * inode;
- struct iattr newattrs;
+ struct timespec tv[2];
- error = user_path_walk(filename, &nd);
- if (error)
- goto out;
- inode = nd.dentry->d_inode;
-
- error = -EROFS;
- if (IS_RDONLY(inode))
- goto dput_and_out;
-
- /* Don't worry, the checks are done in inode_change_ok() */
- newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
if (times) {
- error = -EPERM;
- if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
- goto dput_and_out;
-
- error = get_user(newattrs.ia_atime.tv_sec, ×->actime);
- newattrs.ia_atime.tv_nsec = 0;
- if (!error)
- error = get_user(newattrs.ia_mtime.tv_sec, ×->modtime);
- newattrs.ia_mtime.tv_nsec = 0;
- if (error)
- goto dput_and_out;
-
- newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
- } else {
- error = -EACCES;
- if (IS_IMMUTABLE(inode))
- goto dput_and_out;
-
- if (current->fsuid != inode->i_uid &&
- (error = vfs_permission(&nd, MAY_WRITE)) != 0)
- goto dput_and_out;
+ if (get_user(tv[0].tv_sec, ×->actime) ||
+ get_user(tv[1].tv_sec, ×->modtime))
+ return -EFAULT;
+ tv[0].tv_nsec = 0;
+ tv[1].tv_nsec = 0;
}
- mutex_lock(&inode->i_mutex);
- error = notify_change(nd.dentry, &newattrs);
- mutex_unlock(&inode->i_mutex);
-dput_and_out:
- path_release(&nd);
-out:
- return error;
+ return do_utimes(AT_FDCWD, filename, times ? tv : NULL, 0);
}
#endif
@@ -76,18 +42,38 @@
* must be owner or have write permission.
* Else, update from *times, must be owner or super user.
*/
-long do_utimes(int dfd, char __user *filename, struct timeval *times)
+long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags)
{
int error;
struct nameidata nd;
- struct inode * inode;
+ struct dentry *dentry;
+ struct inode *inode;
struct iattr newattrs;
+ struct file *f = NULL;
- error = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW, &nd);
-
- if (error)
+ error = -EINVAL;
+ if (flags & ~AT_SYMLINK_NOFOLLOW)
goto out;
- inode = nd.dentry->d_inode;
+
+ if (filename == NULL && dfd != AT_FDCWD) {
+ error = -EINVAL;
+ if (flags & AT_SYMLINK_NOFOLLOW)
+ goto out;
+
+ error = -EBADF;
+ f = fget(dfd);
+ if (!f)
+ goto out;
+ dentry = f->f_path.dentry;
+ } else {
+ error = __user_walk_fd(dfd, filename, (flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW, &nd);
+ if (error)
+ goto out;
+
+ dentry = nd.dentry;
+ }
+
+ inode = dentry->d_inode;
error = -EROFS;
if (IS_RDONLY(inode))
@@ -100,11 +86,21 @@
if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
goto dput_and_out;
- newattrs.ia_atime.tv_sec = times[0].tv_sec;
- newattrs.ia_atime.tv_nsec = times[0].tv_usec * 1000;
- newattrs.ia_mtime.tv_sec = times[1].tv_sec;
- newattrs.ia_mtime.tv_nsec = times[1].tv_usec * 1000;
- newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
+ if (times[0].tv_nsec == UTIME_OMIT)
+ newattrs.ia_valid &= ~ATTR_ATIME;
+ else if (times[0].tv_nsec != UTIME_NOW) {
+ newattrs.ia_atime.tv_sec = times[0].tv_sec;
+ newattrs.ia_atime.tv_nsec = times[0].tv_nsec;
+ newattrs.ia_valid |= ATTR_ATIME_SET;
+ }
+
+ if (times[1].tv_nsec == UTIME_OMIT)
+ newattrs.ia_valid &= ~ATTR_MTIME;
+ else if (times[1].tv_nsec != UTIME_NOW) {
+ newattrs.ia_mtime.tv_sec = times[1].tv_sec;
+ newattrs.ia_mtime.tv_nsec = times[1].tv_nsec;
+ newattrs.ia_valid |= ATTR_MTIME_SET;
+ }
} else {
error = -EACCES;
if (IS_IMMUTABLE(inode))
@@ -115,21 +111,67 @@
goto dput_and_out;
}
mutex_lock(&inode->i_mutex);
- error = notify_change(nd.dentry, &newattrs);
+ error = notify_change(dentry, &newattrs);
mutex_unlock(&inode->i_mutex);
dput_and_out:
- path_release(&nd);
+ if (f)
+ fput(f);
+ else
+ path_release(&nd);
out:
return error;
}
+asmlinkage long sys_utimensat(int dfd, char __user *filename, struct timespec __user *utimes, int flags)
+{
+ struct timespec tstimes[2];
+
+ if (utimes) {
+ if (copy_from_user(&tstimes, utimes, sizeof(tstimes)))
+ return -EFAULT;
+ if ((tstimes[0].tv_nsec == UTIME_OMIT ||
+ tstimes[0].tv_nsec == UTIME_NOW) &&
+ tstimes[0].tv_sec != 0)
+ return -EINVAL;
+ if ((tstimes[1].tv_nsec == UTIME_OMIT ||
+ tstimes[1].tv_nsec == UTIME_NOW) &&
+ tstimes[1].tv_sec != 0)
+ return -EINVAL;
+
+ /* Nothing to do, we must not even check the path. */
+ if (tstimes[0].tv_nsec == UTIME_OMIT &&
+ tstimes[1].tv_nsec == UTIME_OMIT)
+ return 0;
+ }
+
+ return do_utimes(dfd, filename, utimes ? tstimes : NULL, flags);
+}
+
asmlinkage long sys_futimesat(int dfd, char __user *filename, struct timeval __user *utimes)
{
struct timeval times[2];
+ struct timespec tstimes[2];
- if (utimes && copy_from_user(×, utimes, sizeof(times)))
- return -EFAULT;
- return do_utimes(dfd, filename, utimes ? times : NULL);
+ if (utimes) {
+ if (copy_from_user(×, utimes, sizeof(times)))
+ return -EFAULT;
+
+ /* This test is needed to catch all invalid values. If we
+ would test only in do_utimes we would miss those invalid
+ values truncated by the multiplication with 1000. Note
+ that we also catch UTIME_{NOW,OMIT} here which are only
+ valid for utimensat. */
+ if (times[0].tv_usec >= 1000000 || times[0].tv_usec < 0 ||
+ times[1].tv_usec >= 1000000 || times[1].tv_usec < 0)
+ return -EINVAL;
+
+ tstimes[0].tv_sec = times[0].tv_sec;
+ tstimes[0].tv_nsec = 1000 * times[0].tv_usec;
+ tstimes[1].tv_sec = times[1].tv_sec;
+ tstimes[1].tv_nsec = 1000 * times[1].tv_usec;
+ }
+
+ return do_utimes(dfd, filename, utimes ? tstimes : NULL, 0);
}
asmlinkage long sys_utimes(char __user *filename, struct timeval __user *utimes)
diff --git a/fs/xattr.c b/fs/xattr.c
index 3864613..9f4568b 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -9,7 +9,6 @@
*/
#include <linux/fs.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/file.h>
#include <linux/xattr.h>
#include <linux/namei.h>
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index ff8d64e..558076d 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -639,7 +639,6 @@
xfs_fsize_t isize, new_size;
xfs_iocore_t *io;
bhv_vnode_t *vp;
- unsigned long seg;
int iolock;
int eventsent = 0;
bhv_vrwlock_t locktype;
@@ -652,24 +651,9 @@
vp = BHV_TO_VNODE(bdp);
xip = XFS_BHVTOI(bdp);
- for (seg = 0; seg < segs; seg++) {
- const struct iovec *iv = &iovp[seg];
-
- /*
- * If any segment has a negative length, or the cumulative
- * length ever wraps negative then return -EINVAL.
- */
- ocount += iv->iov_len;
- if (unlikely((ssize_t)(ocount|iv->iov_len) < 0))
- return -EINVAL;
- if (access_ok(VERIFY_READ, iv->iov_base, iv->iov_len))
- continue;
- if (seg == 0)
- return -EFAULT;
- segs = seg;
- ocount -= iv->iov_len; /* This segment is no good */
- break;
- }
+ error = generic_segment_checks(iovp, &segs, &ocount, VERIFY_READ);
+ if (error)
+ return error;
count = ocount;
pos = *offset;
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 16c3c44..9cfd5b1 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -303,6 +303,9 @@
#define to_acpi_device(d) container_of(d, struct acpi_device, dev)
#define to_acpi_driver(d) container_of(d, struct acpi_driver, drv)
+/* acpi_device.dev.bus == &acpi_bus_type */
+extern struct bus_type acpi_bus_type;
+
/*
* Events
* ------
diff --git a/include/asm-alpha/atomic.h b/include/asm-alpha/atomic.h
index fc77f74..f5cb7b8 100644
--- a/include/asm-alpha/atomic.h
+++ b/include/asm-alpha/atomic.h
@@ -2,6 +2,7 @@
#define _ALPHA_ATOMIC_H
#include <asm/barrier.h>
+#include <asm/system.h>
/*
* Atomic operations that C can't guarantee us. Useful for
@@ -175,19 +176,64 @@
return result;
}
-#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+#define atomic64_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new))
+#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
+
+#define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new))
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
-#define atomic_add_unless(v, a, u) \
-({ \
- int c, old; \
- c = atomic_read(v); \
- while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
- c = old; \
- c != (u); \
-})
+/**
+ * atomic_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
+ */
+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int c, old;
+ c = atomic_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+/**
+ * atomic64_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic64_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
+ */
+static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+{
+ long c, old;
+ c = atomic64_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic64_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
+#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
#define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0)
diff --git a/include/asm-alpha/kdebug.h b/include/asm-alpha/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-alpha/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-alpha/local.h b/include/asm-alpha/local.h
index 90a510f..6ad3ea6 100644
--- a/include/asm-alpha/local.h
+++ b/include/asm-alpha/local.h
@@ -4,37 +4,115 @@
#include <linux/percpu.h>
#include <asm/atomic.h>
-typedef atomic64_t local_t;
+typedef struct
+{
+ atomic_long_t a;
+} local_t;
-#define LOCAL_INIT(i) ATOMIC64_INIT(i)
-#define local_read(v) atomic64_read(v)
-#define local_set(v,i) atomic64_set(v,i)
+#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) }
+#define local_read(l) atomic_long_read(&(l)->a)
+#define local_set(l,i) atomic_long_set(&(l)->a, (i))
+#define local_inc(l) atomic_long_inc(&(l)->a)
+#define local_dec(l) atomic_long_dec(&(l)->a)
+#define local_add(i,l) atomic_long_add((i),(&(l)->a))
+#define local_sub(i,l) atomic_long_sub((i),(&(l)->a))
-#define local_inc(v) atomic64_inc(v)
-#define local_dec(v) atomic64_dec(v)
-#define local_add(i, v) atomic64_add(i, v)
-#define local_sub(i, v) atomic64_sub(i, v)
+static __inline__ long local_add_return(long i, local_t * l)
+{
+ long temp, result;
+ __asm__ __volatile__(
+ "1: ldq_l %0,%1\n"
+ " addq %0,%3,%2\n"
+ " addq %0,%3,%0\n"
+ " stq_c %0,%1\n"
+ " beq %0,2f\n"
+ ".subsection 2\n"
+ "2: br 1b\n"
+ ".previous"
+ :"=&r" (temp), "=m" (l->a.counter), "=&r" (result)
+ :"Ir" (i), "m" (l->a.counter) : "memory");
+ return result;
+}
-#define __local_inc(v) ((v)->counter++)
-#define __local_dec(v) ((v)->counter++)
-#define __local_add(i,v) ((v)->counter+=(i))
-#define __local_sub(i,v) ((v)->counter-=(i))
+static __inline__ long local_sub_return(long i, local_t * l)
+{
+ long temp, result;
+ __asm__ __volatile__(
+ "1: ldq_l %0,%1\n"
+ " subq %0,%3,%2\n"
+ " subq %0,%3,%0\n"
+ " stq_c %0,%1\n"
+ " beq %0,2f\n"
+ ".subsection 2\n"
+ "2: br 1b\n"
+ ".previous"
+ :"=&r" (temp), "=m" (l->a.counter), "=&r" (result)
+ :"Ir" (i), "m" (l->a.counter) : "memory");
+ return result;
+}
+
+#define local_cmpxchg(l, o, n) \
+ (cmpxchg_local(&((l)->a.counter), (o), (n)))
+#define local_xchg(l, n) (xchg_local(&((l)->a.counter), (n)))
+
+/**
+ * local_add_unless - add unless the number is a given value
+ * @l: pointer of type local_t
+ * @a: the amount to add to l...
+ * @u: ...unless l is equal to u.
+ *
+ * Atomically adds @a to @l, so long as it was not @u.
+ * Returns non-zero if @l was not @u, and zero otherwise.
+ */
+#define local_add_unless(l, a, u) \
+({ \
+ long c, old; \
+ c = local_read(l); \
+ for (;;) { \
+ if (unlikely(c == (u))) \
+ break; \
+ old = local_cmpxchg((l), c, c + (a)); \
+ if (likely(old == c)) \
+ break; \
+ c = old; \
+ } \
+ c != (u); \
+})
+#define local_inc_not_zero(l) local_add_unless((l), 1, 0)
+
+#define local_add_negative(a, l) (local_add_return((a), (l)) < 0)
+
+#define local_dec_return(l) local_sub_return(1,(l))
+
+#define local_inc_return(l) local_add_return(1,(l))
+
+#define local_sub_and_test(i,l) (local_sub_return((i), (l)) == 0)
+
+#define local_inc_and_test(l) (local_add_return(1, (l)) == 0)
+
+#define local_dec_and_test(l) (local_sub_return(1, (l)) == 0)
+
+/* Verify if faster than atomic ops */
+#define __local_inc(l) ((l)->a.counter++)
+#define __local_dec(l) ((l)->a.counter++)
+#define __local_add(i,l) ((l)->a.counter+=(i))
+#define __local_sub(i,l) ((l)->a.counter-=(i))
/* Use these for per-cpu local_t variables: on some archs they are
* much more efficient than these naive implementations. Note they take
* a variable, not an address.
*/
-#define cpu_local_read(v) local_read(&__get_cpu_var(v))
-#define cpu_local_set(v, i) local_set(&__get_cpu_var(v), (i))
+#define cpu_local_read(l) local_read(&__get_cpu_var(l))
+#define cpu_local_set(l, i) local_set(&__get_cpu_var(l), (i))
-#define cpu_local_inc(v) local_inc(&__get_cpu_var(v))
-#define cpu_local_dec(v) local_dec(&__get_cpu_var(v))
-#define cpu_local_add(i, v) local_add((i), &__get_cpu_var(v))
-#define cpu_local_sub(i, v) local_sub((i), &__get_cpu_var(v))
+#define cpu_local_inc(l) local_inc(&__get_cpu_var(l))
+#define cpu_local_dec(l) local_dec(&__get_cpu_var(l))
+#define cpu_local_add(i, l) local_add((i), &__get_cpu_var(l))
+#define cpu_local_sub(i, l) local_sub((i), &__get_cpu_var(l))
-#define __cpu_local_inc(v) __local_inc(&__get_cpu_var(v))
-#define __cpu_local_dec(v) __local_dec(&__get_cpu_var(v))
-#define __cpu_local_add(i, v) __local_add((i), &__get_cpu_var(v))
-#define __cpu_local_sub(i, v) __local_sub((i), &__get_cpu_var(v))
+#define __cpu_local_inc(l) __local_inc(&__get_cpu_var(l))
+#define __cpu_local_dec(l) __local_dec(&__get_cpu_var(l))
+#define __cpu_local_add(i, l) __local_add((i), &__get_cpu_var(l))
+#define __cpu_local_sub(i, l) __local_sub((i), &__get_cpu_var(l))
#endif /* _ALPHA_LOCAL_H */
diff --git a/include/asm-alpha/pgtable.h b/include/asm-alpha/pgtable.h
index 49ac9be..616d206 100644
--- a/include/asm-alpha/pgtable.h
+++ b/include/asm-alpha/pgtable.h
@@ -345,10 +345,6 @@
#define io_remap_pfn_range(vma, start, pfn, size, prot) \
remap_pfn_range(vma, start, pfn, size, prot)
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
#define pte_ERROR(e) \
printk("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e))
#define pmd_ERROR(e) \
diff --git a/include/asm-alpha/system.h b/include/asm-alpha/system.h
index 03e9c0e..cf1021a 100644
--- a/include/asm-alpha/system.h
+++ b/include/asm-alpha/system.h
@@ -443,8 +443,110 @@
(__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, sizeof(*(ptr))); \
})
-#define tas(ptr) (xchg((ptr),1))
+static inline unsigned long
+__xchg_u8_local(volatile char *m, unsigned long val)
+{
+ unsigned long ret, tmp, addr64;
+ __asm__ __volatile__(
+ " andnot %4,7,%3\n"
+ " insbl %1,%4,%1\n"
+ "1: ldq_l %2,0(%3)\n"
+ " extbl %2,%4,%0\n"
+ " mskbl %2,%4,%2\n"
+ " or %1,%2,%2\n"
+ " stq_c %2,0(%3)\n"
+ " beq %2,2f\n"
+ ".subsection 2\n"
+ "2: br 1b\n"
+ ".previous"
+ : "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
+ : "r" ((long)m), "1" (val) : "memory");
+
+ return ret;
+}
+
+static inline unsigned long
+__xchg_u16_local(volatile short *m, unsigned long val)
+{
+ unsigned long ret, tmp, addr64;
+
+ __asm__ __volatile__(
+ " andnot %4,7,%3\n"
+ " inswl %1,%4,%1\n"
+ "1: ldq_l %2,0(%3)\n"
+ " extwl %2,%4,%0\n"
+ " mskwl %2,%4,%2\n"
+ " or %1,%2,%2\n"
+ " stq_c %2,0(%3)\n"
+ " beq %2,2f\n"
+ ".subsection 2\n"
+ "2: br 1b\n"
+ ".previous"
+ : "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
+ : "r" ((long)m), "1" (val) : "memory");
+
+ return ret;
+}
+
+static inline unsigned long
+__xchg_u32_local(volatile int *m, unsigned long val)
+{
+ unsigned long dummy;
+
+ __asm__ __volatile__(
+ "1: ldl_l %0,%4\n"
+ " bis $31,%3,%1\n"
+ " stl_c %1,%2\n"
+ " beq %1,2f\n"
+ ".subsection 2\n"
+ "2: br 1b\n"
+ ".previous"
+ : "=&r" (val), "=&r" (dummy), "=m" (*m)
+ : "rI" (val), "m" (*m) : "memory");
+
+ return val;
+}
+
+static inline unsigned long
+__xchg_u64_local(volatile long *m, unsigned long val)
+{
+ unsigned long dummy;
+
+ __asm__ __volatile__(
+ "1: ldq_l %0,%4\n"
+ " bis $31,%3,%1\n"
+ " stq_c %1,%2\n"
+ " beq %1,2f\n"
+ ".subsection 2\n"
+ "2: br 1b\n"
+ ".previous"
+ : "=&r" (val), "=&r" (dummy), "=m" (*m)
+ : "rI" (val), "m" (*m) : "memory");
+
+ return val;
+}
+
+#define __xchg_local(ptr, x, size) \
+({ \
+ unsigned long __xchg__res; \
+ volatile void *__xchg__ptr = (ptr); \
+ switch (size) { \
+ case 1: __xchg__res = __xchg_u8_local(__xchg__ptr, x); break; \
+ case 2: __xchg__res = __xchg_u16_local(__xchg__ptr, x); break; \
+ case 4: __xchg__res = __xchg_u32_local(__xchg__ptr, x); break; \
+ case 8: __xchg__res = __xchg_u64_local(__xchg__ptr, x); break; \
+ default: __xchg_called_with_bad_pointer(); __xchg__res = x; \
+ } \
+ __xchg__res; \
+})
+
+#define xchg_local(ptr,x) \
+ ({ \
+ __typeof__(*(ptr)) _x_ = (x); \
+ (__typeof__(*(ptr))) __xchg_local((ptr), (unsigned long)_x_, \
+ sizeof(*(ptr))); \
+ })
/*
* Atomic compare and exchange. Compare OLD with MEM, if identical,
@@ -596,6 +698,128 @@
(unsigned long)_n_, sizeof(*(ptr))); \
})
+static inline unsigned long
+__cmpxchg_u8_local(volatile char *m, long old, long new)
+{
+ unsigned long prev, tmp, cmp, addr64;
+
+ __asm__ __volatile__(
+ " andnot %5,7,%4\n"
+ " insbl %1,%5,%1\n"
+ "1: ldq_l %2,0(%4)\n"
+ " extbl %2,%5,%0\n"
+ " cmpeq %0,%6,%3\n"
+ " beq %3,2f\n"
+ " mskbl %2,%5,%2\n"
+ " or %1,%2,%2\n"
+ " stq_c %2,0(%4)\n"
+ " beq %2,3f\n"
+ "2:\n"
+ ".subsection 2\n"
+ "3: br 1b\n"
+ ".previous"
+ : "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
+ : "r" ((long)m), "Ir" (old), "1" (new) : "memory");
+
+ return prev;
+}
+
+static inline unsigned long
+__cmpxchg_u16_local(volatile short *m, long old, long new)
+{
+ unsigned long prev, tmp, cmp, addr64;
+
+ __asm__ __volatile__(
+ " andnot %5,7,%4\n"
+ " inswl %1,%5,%1\n"
+ "1: ldq_l %2,0(%4)\n"
+ " extwl %2,%5,%0\n"
+ " cmpeq %0,%6,%3\n"
+ " beq %3,2f\n"
+ " mskwl %2,%5,%2\n"
+ " or %1,%2,%2\n"
+ " stq_c %2,0(%4)\n"
+ " beq %2,3f\n"
+ "2:\n"
+ ".subsection 2\n"
+ "3: br 1b\n"
+ ".previous"
+ : "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
+ : "r" ((long)m), "Ir" (old), "1" (new) : "memory");
+
+ return prev;
+}
+
+static inline unsigned long
+__cmpxchg_u32_local(volatile int *m, int old, int new)
+{
+ unsigned long prev, cmp;
+
+ __asm__ __volatile__(
+ "1: ldl_l %0,%5\n"
+ " cmpeq %0,%3,%1\n"
+ " beq %1,2f\n"
+ " mov %4,%1\n"
+ " stl_c %1,%2\n"
+ " beq %1,3f\n"
+ "2:\n"
+ ".subsection 2\n"
+ "3: br 1b\n"
+ ".previous"
+ : "=&r"(prev), "=&r"(cmp), "=m"(*m)
+ : "r"((long) old), "r"(new), "m"(*m) : "memory");
+
+ return prev;
+}
+
+static inline unsigned long
+__cmpxchg_u64_local(volatile long *m, unsigned long old, unsigned long new)
+{
+ unsigned long prev, cmp;
+
+ __asm__ __volatile__(
+ "1: ldq_l %0,%5\n"
+ " cmpeq %0,%3,%1\n"
+ " beq %1,2f\n"
+ " mov %4,%1\n"
+ " stq_c %1,%2\n"
+ " beq %1,3f\n"
+ "2:\n"
+ ".subsection 2\n"
+ "3: br 1b\n"
+ ".previous"
+ : "=&r"(prev), "=&r"(cmp), "=m"(*m)
+ : "r"((long) old), "r"(new), "m"(*m) : "memory");
+
+ return prev;
+}
+
+static __always_inline unsigned long
+__cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new,
+ int size)
+{
+ switch (size) {
+ case 1:
+ return __cmpxchg_u8_local(ptr, old, new);
+ case 2:
+ return __cmpxchg_u16_local(ptr, old, new);
+ case 4:
+ return __cmpxchg_u32_local(ptr, old, new);
+ case 8:
+ return __cmpxchg_u64_local(ptr, old, new);
+ }
+ __cmpxchg_called_with_bad_pointer();
+ return old;
+}
+
+#define cmpxchg_local(ptr,o,n) \
+ ({ \
+ __typeof__(*(ptr)) _o_ = (o); \
+ __typeof__(*(ptr)) _n_ = (n); \
+ (__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_, \
+ (unsigned long)_n_, sizeof(*(ptr))); \
+ })
+
#endif /* __ASSEMBLY__ */
#define arch_align_stack(x) (x)
diff --git a/include/asm-arm/atomic.h b/include/asm-arm/atomic.h
index f266c27..3b59f94 100644
--- a/include/asm-arm/atomic.h
+++ b/include/asm-arm/atomic.h
@@ -12,6 +12,7 @@
#define __ASM_ARM_ATOMIC_H
#include <linux/compiler.h>
+#include <asm/system.h>
typedef struct { volatile int counter; } atomic_t;
diff --git a/include/asm-arm/kdebug.h b/include/asm-arm/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-arm/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-arm/kexec.h b/include/asm-arm/kexec.h
index 8c1c616..b5b030e 100644
--- a/include/asm-arm/kexec.h
+++ b/include/asm-arm/kexec.h
@@ -16,8 +16,6 @@
#ifndef __ASSEMBLY__
-#define MAX_NOTE_BYTES 1024
-
struct kimage;
/* Provide a dummy definition to avoid build failures. */
static inline void crash_setup_regs(struct pt_regs *newregs,
diff --git a/include/asm-arm/pgtable-nommu.h b/include/asm-arm/pgtable-nommu.h
index 7b1c9ac..0c8be19 100644
--- a/include/asm-arm/pgtable-nommu.h
+++ b/include/asm-arm/pgtable-nommu.h
@@ -83,10 +83,6 @@
#define io_remap_page_range remap_page_range
#define io_remap_pfn_range remap_pfn_range
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
/*
* All 32bit addresses are effectively valid for vmalloc...
diff --git a/include/asm-arm/pgtable.h b/include/asm-arm/pgtable.h
index 7b2bafc..21dec9f 100644
--- a/include/asm-arm/pgtable.h
+++ b/include/asm-arm/pgtable.h
@@ -395,10 +395,6 @@
#define io_remap_pfn_range(vma,from,pfn,size,prot) \
remap_pfn_range(vma, from, pfn, size, prot)
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
#define pgtable_cache_init() do { } while (0)
#endif /* !__ASSEMBLY__ */
diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h
index 63b3080..f2da3b6 100644
--- a/include/asm-arm/system.h
+++ b/include/asm-arm/system.h
@@ -93,7 +93,7 @@
__attribute__((noreturn));
struct siginfo;
-void notify_die(const char *str, struct pt_regs *regs, struct siginfo *info,
+void arm_notify_die(const char *str, struct pt_regs *regs, struct siginfo *info,
unsigned long err, unsigned long trap);
void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
@@ -103,8 +103,6 @@
#define xchg(ptr,x) \
((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
-#define tas(ptr) (xchg((ptr),1))
-
extern asmlinkage void __backtrace(void);
extern asmlinkage void c_backtrace(unsigned long fp, int pmode);
diff --git a/include/asm-arm26/atomic.h b/include/asm-arm26/atomic.h
index 97e944f..d6dd423 100644
--- a/include/asm-arm26/atomic.h
+++ b/include/asm-arm26/atomic.h
@@ -20,7 +20,6 @@
#ifndef __ASM_ARM_ATOMIC_H
#define __ASM_ARM_ATOMIC_H
-
#ifdef CONFIG_SMP
#error SMP is NOT supported
#endif
diff --git a/include/asm-arm26/kdebug.h b/include/asm-arm26/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-arm26/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-arm26/pgtable.h b/include/asm-arm26/pgtable.h
index 63a8881..2b20e9f 100644
--- a/include/asm-arm26/pgtable.h
+++ b/include/asm-arm26/pgtable.h
@@ -297,10 +297,6 @@
#define io_remap_pfn_range(vma,from,pfn,size,prot) \
remap_pfn_range(vma, from, pfn, size, prot)
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
#endif /* !__ASSEMBLY__ */
#endif /* _ASMARM_PGTABLE_H */
diff --git a/include/asm-arm26/system.h b/include/asm-arm26/system.h
index 00ae32a..4703593 100644
--- a/include/asm-arm26/system.h
+++ b/include/asm-arm26/system.h
@@ -52,8 +52,6 @@
#define xchg(ptr,x) \
((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
-#define tas(ptr) (xchg((ptr),1))
-
extern asmlinkage void __backtrace(void);
#define set_cr(x) \
diff --git a/include/asm-avr32/kdebug.h b/include/asm-avr32/kdebug.h
index f583b64..de41927 100644
--- a/include/asm-avr32/kdebug.h
+++ b/include/asm-avr32/kdebug.h
@@ -3,19 +3,6 @@
#include <linux/notifier.h>
-struct pt_regs;
-
-struct die_args {
- struct pt_regs *regs;
- int trapnr;
-};
-
-int register_die_notifier(struct notifier_block *nb);
-int unregister_die_notifier(struct notifier_block *nb);
-int register_page_fault_notifier(struct notifier_block *nb);
-int unregister_page_fault_notifier(struct notifier_block *nb);
-extern struct atomic_notifier_head avr32_die_chain;
-
/* Grossly misnamed. */
enum die_val {
DIE_FAULT,
@@ -24,15 +11,7 @@
DIE_PAGE_FAULT,
};
-static inline int notify_die(enum die_val val, struct pt_regs *regs,
- int trap, int sig)
-{
- struct die_args args = {
- .regs = regs,
- .trapnr = trap,
- };
-
- return atomic_notifier_call_chain(&avr32_die_chain, val, &args);
-}
+int register_page_fault_notifier(struct notifier_block *nb);
+int unregister_page_fault_notifier(struct notifier_block *nb);
#endif /* __ASM_AVR32_KDEBUG_H */
diff --git a/include/asm-avr32/pgtable.h b/include/asm-avr32/pgtable.h
index 6b8ca9d..f6cc2b0 100644
--- a/include/asm-avr32/pgtable.h
+++ b/include/asm-avr32/pgtable.h
@@ -394,10 +394,6 @@
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
/* No page table caches to initialize (?) */
#define pgtable_cache_init() do { } while(0)
diff --git a/include/asm-blackfin/system.h b/include/asm-blackfin/system.h
index 758bac7..b5bf6e7 100644
--- a/include/asm-blackfin/system.h
+++ b/include/asm-blackfin/system.h
@@ -138,7 +138,6 @@
#endif
#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
-#define tas(ptr) ((void)xchg((ptr),1))
struct __xchg_dummy {
unsigned long a[100];
diff --git a/include/asm-cris/kdebug.h b/include/asm-cris/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-cris/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-frv/atomic.h b/include/asm-frv/atomic.h
index 066386a..d425d8d 100644
--- a/include/asm-frv/atomic.h
+++ b/include/asm-frv/atomic.h
@@ -16,6 +16,7 @@
#include <linux/types.h>
#include <asm/spr-regs.h>
+#include <asm/system.h>
#ifdef CONFIG_SMP
#error not SMP safe
@@ -258,85 +259,23 @@
#define tas(ptr) (xchg((ptr), 1))
-/*****************************************************************************/
-/*
- * compare and conditionally exchange value with memory
- * - if (*ptr == test) then orig = *ptr; *ptr = test;
- * - if (*ptr != test) then orig = *ptr;
- */
-#ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
-
-#define cmpxchg(ptr, test, new) \
-({ \
- __typeof__(ptr) __xg_ptr = (ptr); \
- __typeof__(*(ptr)) __xg_orig, __xg_tmp; \
- __typeof__(*(ptr)) __xg_test = (test); \
- __typeof__(*(ptr)) __xg_new = (new); \
- \
- switch (sizeof(__xg_orig)) { \
- case 4: \
- asm volatile( \
- "0: \n" \
- " orcc gr0,gr0,gr0,icc3 \n" \
- " ckeq icc3,cc7 \n" \
- " ld.p %M0,%1 \n" \
- " orcr cc7,cc7,cc3 \n" \
- " sub%I4cc %1,%4,%2,icc0 \n" \
- " bne icc0,#0,1f \n" \
- " cst.p %3,%M0 ,cc3,#1 \n" \
- " corcc gr29,gr29,gr0 ,cc3,#1 \n" \
- " beq icc3,#0,0b \n" \
- "1: \n" \
- : "+U"(*__xg_ptr), "=&r"(__xg_orig), "=&r"(__xg_tmp) \
- : "r"(__xg_new), "NPr"(__xg_test) \
- : "memory", "cc7", "cc3", "icc3", "icc0" \
- ); \
- break; \
- \
- default: \
- __xg_orig = 0; \
- asm volatile("break"); \
- break; \
- } \
- \
- __xg_orig; \
-})
-
-#else
-
-extern uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new);
-
-#define cmpxchg(ptr, test, new) \
-({ \
- __typeof__(ptr) __xg_ptr = (ptr); \
- __typeof__(*(ptr)) __xg_orig; \
- __typeof__(*(ptr)) __xg_test = (test); \
- __typeof__(*(ptr)) __xg_new = (new); \
- \
- switch (sizeof(__xg_orig)) { \
- case 4: __xg_orig = __cmpxchg_32(__xg_ptr, __xg_test, __xg_new); break; \
- default: \
- __xg_orig = 0; \
- asm volatile("break"); \
- break; \
- } \
- \
- __xg_orig; \
-})
-
-#endif
-
#define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new))
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
-#define atomic_add_unless(v, a, u) \
-({ \
- int c, old; \
- c = atomic_read(v); \
- while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
- c = old; \
- c != (u); \
-})
+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int c, old;
+ c = atomic_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
diff --git a/include/asm-frv/kdebug.h b/include/asm-frv/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-frv/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-frv/pgtable.h b/include/asm-frv/pgtable.h
index 8a05aa1..2687c77 100644
--- a/include/asm-frv/pgtable.h
+++ b/include/asm-frv/pgtable.h
@@ -509,10 +509,6 @@
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
diff --git a/include/asm-frv/semaphore.h b/include/asm-frv/semaphore.h
index 907c5c3..0958652 100644
--- a/include/asm-frv/semaphore.h
+++ b/include/asm-frv/semaphore.h
@@ -20,8 +20,6 @@
#include <linux/spinlock.h>
#include <linux/rwsem.h>
-#define SEMAPHORE_DEBUG 0
-
/*
* the semaphore definition
* - if counter is >0 then there are tokens available on the semaphore for down to collect
@@ -32,12 +30,12 @@
unsigned counter;
spinlock_t wait_lock;
struct list_head wait_list;
-#if SEMAPHORE_DEBUG
+#ifdef CONFIG_DEBUG_SEMAPHORE
unsigned __magic;
#endif
};
-#if SEMAPHORE_DEBUG
+#ifdef CONFIG_DEBUG_SEMAPHORE
# define __SEM_DEBUG_INIT(name) , (long)&(name).__magic
#else
# define __SEM_DEBUG_INIT(name)
@@ -76,7 +74,7 @@
{
unsigned long flags;
-#if SEMAPHORE_DEBUG
+#ifdef CONFIG_DEBUG_SEMAPHORE
CHECK_MAGIC(sem->__magic);
#endif
@@ -95,7 +93,7 @@
unsigned long flags;
int ret = 0;
-#if SEMAPHORE_DEBUG
+#ifdef CONFIG_DEBUG_SEMAPHORE
CHECK_MAGIC(sem->__magic);
#endif
@@ -119,7 +117,7 @@
unsigned long flags;
int success = 0;
-#if SEMAPHORE_DEBUG
+#ifdef CONFIG_DEBUG_SEMAPHORE
CHECK_MAGIC(sem->__magic);
#endif
@@ -136,7 +134,7 @@
{
unsigned long flags;
-#if SEMAPHORE_DEBUG
+#ifdef CONFIG_DEBUG_SEMAPHORE
CHECK_MAGIC(sem->__magic);
#endif
diff --git a/include/asm-frv/system.h b/include/asm-frv/system.h
index 1166899..be303b3 100644
--- a/include/asm-frv/system.h
+++ b/include/asm-frv/system.h
@@ -13,7 +13,6 @@
#define _ASM_SYSTEM_H
#include <linux/linkage.h>
-#include <asm/atomic.h>
struct thread_struct;
@@ -197,4 +196,73 @@
#define arch_align_stack(x) (x)
+/*****************************************************************************/
+/*
+ * compare and conditionally exchange value with memory
+ * - if (*ptr == test) then orig = *ptr; *ptr = test;
+ * - if (*ptr != test) then orig = *ptr;
+ */
+#ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
+
+#define cmpxchg(ptr, test, new) \
+({ \
+ __typeof__(ptr) __xg_ptr = (ptr); \
+ __typeof__(*(ptr)) __xg_orig, __xg_tmp; \
+ __typeof__(*(ptr)) __xg_test = (test); \
+ __typeof__(*(ptr)) __xg_new = (new); \
+ \
+ switch (sizeof(__xg_orig)) { \
+ case 4: \
+ asm volatile( \
+ "0: \n" \
+ " orcc gr0,gr0,gr0,icc3 \n" \
+ " ckeq icc3,cc7 \n" \
+ " ld.p %M0,%1 \n" \
+ " orcr cc7,cc7,cc3 \n" \
+ " sub%I4cc %1,%4,%2,icc0 \n" \
+ " bne icc0,#0,1f \n" \
+ " cst.p %3,%M0 ,cc3,#1 \n" \
+ " corcc gr29,gr29,gr0 ,cc3,#1 \n" \
+ " beq icc3,#0,0b \n" \
+ "1: \n" \
+ : "+U"(*__xg_ptr), "=&r"(__xg_orig), "=&r"(__xg_tmp) \
+ : "r"(__xg_new), "NPr"(__xg_test) \
+ : "memory", "cc7", "cc3", "icc3", "icc0" \
+ ); \
+ break; \
+ \
+ default: \
+ __xg_orig = 0; \
+ asm volatile("break"); \
+ break; \
+ } \
+ \
+ __xg_orig; \
+})
+
+#else
+
+extern uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new);
+
+#define cmpxchg(ptr, test, new) \
+({ \
+ __typeof__(ptr) __xg_ptr = (ptr); \
+ __typeof__(*(ptr)) __xg_orig; \
+ __typeof__(*(ptr)) __xg_test = (test); \
+ __typeof__(*(ptr)) __xg_new = (new); \
+ \
+ switch (sizeof(__xg_orig)) { \
+ case 4: __xg_orig = __cmpxchg_32(__xg_ptr, __xg_test, __xg_new); break; \
+ default: \
+ __xg_orig = 0; \
+ asm volatile("break"); \
+ break; \
+ } \
+ \
+ __xg_orig; \
+})
+
+#endif
+
+
#endif /* _ASM_SYSTEM_H */
diff --git a/include/asm-generic/atomic.h b/include/asm-generic/atomic.h
index b7e4a04..85fd0aa 100644
--- a/include/asm-generic/atomic.h
+++ b/include/asm-generic/atomic.h
@@ -66,6 +66,76 @@
atomic64_sub(i, v);
}
+static inline int atomic_long_sub_and_test(long i, atomic_long_t *l)
+{
+ atomic64_t *v = (atomic64_t *)l;
+
+ return atomic64_sub_and_test(i, v);
+}
+
+static inline int atomic_long_dec_and_test(atomic_long_t *l)
+{
+ atomic64_t *v = (atomic64_t *)l;
+
+ return atomic64_dec_and_test(v);
+}
+
+static inline int atomic_long_inc_and_test(atomic_long_t *l)
+{
+ atomic64_t *v = (atomic64_t *)l;
+
+ return atomic64_inc_and_test(v);
+}
+
+static inline int atomic_long_add_negative(long i, atomic_long_t *l)
+{
+ atomic64_t *v = (atomic64_t *)l;
+
+ return atomic64_add_negative(i, v);
+}
+
+static inline long atomic_long_add_return(long i, atomic_long_t *l)
+{
+ atomic64_t *v = (atomic64_t *)l;
+
+ return (long)atomic64_add_return(i, v);
+}
+
+static inline long atomic_long_sub_return(long i, atomic_long_t *l)
+{
+ atomic64_t *v = (atomic64_t *)l;
+
+ return (long)atomic64_sub_return(i, v);
+}
+
+static inline long atomic_long_inc_return(atomic_long_t *l)
+{
+ atomic64_t *v = (atomic64_t *)l;
+
+ return (long)atomic64_inc_return(v);
+}
+
+static inline long atomic_long_dec_return(atomic_long_t *l)
+{
+ atomic64_t *v = (atomic64_t *)l;
+
+ return (long)atomic64_dec_return(v);
+}
+
+static inline long atomic_long_add_unless(atomic_long_t *l, long a, long u)
+{
+ atomic64_t *v = (atomic64_t *)l;
+
+ return (long)atomic64_add_unless(v, a, u);
+}
+
+#define atomic_long_inc_not_zero(l) atomic64_inc_not_zero((atomic64_t *)(l))
+
+#define atomic_long_cmpxchg(l, old, new) \
+ (atomic_cmpxchg((atomic64_t *)(l), (old), (new)))
+#define atomic_long_xchg(v, new) \
+ (atomic_xchg((atomic64_t *)(l), (new)))
+
#else /* BITS_PER_LONG == 64 */
typedef atomic_t atomic_long_t;
@@ -113,6 +183,76 @@
atomic_sub(i, v);
}
+static inline int atomic_long_sub_and_test(long i, atomic_long_t *l)
+{
+ atomic_t *v = (atomic_t *)l;
+
+ return atomic_sub_and_test(i, v);
+}
+
+static inline int atomic_long_dec_and_test(atomic_long_t *l)
+{
+ atomic_t *v = (atomic_t *)l;
+
+ return atomic_dec_and_test(v);
+}
+
+static inline int atomic_long_inc_and_test(atomic_long_t *l)
+{
+ atomic_t *v = (atomic_t *)l;
+
+ return atomic_inc_and_test(v);
+}
+
+static inline int atomic_long_add_negative(long i, atomic_long_t *l)
+{
+ atomic_t *v = (atomic_t *)l;
+
+ return atomic_add_negative(i, v);
+}
+
+static inline long atomic_long_add_return(long i, atomic_long_t *l)
+{
+ atomic_t *v = (atomic_t *)l;
+
+ return (long)atomic_add_return(i, v);
+}
+
+static inline long atomic_long_sub_return(long i, atomic_long_t *l)
+{
+ atomic_t *v = (atomic_t *)l;
+
+ return (long)atomic_sub_return(i, v);
+}
+
+static inline long atomic_long_inc_return(atomic_long_t *l)
+{
+ atomic_t *v = (atomic_t *)l;
+
+ return (long)atomic_inc_return(v);
+}
+
+static inline long atomic_long_dec_return(atomic_long_t *l)
+{
+ atomic_t *v = (atomic_t *)l;
+
+ return (long)atomic_dec_return(v);
+}
+
+static inline long atomic_long_add_unless(atomic_long_t *l, long a, long u)
+{
+ atomic_t *v = (atomic_t *)l;
+
+ return (long)atomic_add_unless(v, a, u);
+}
+
+#define atomic_long_inc_not_zero(l) atomic_inc_not_zero((atomic_t *)(l))
+
+#define atomic_long_cmpxchg(l, old, new) \
+ (atomic_cmpxchg((atomic_t *)(l), (old), (new)))
+#define atomic_long_xchg(v, new) \
+ (atomic_xchg((atomic_t *)(l), (new)))
+
#endif /* BITS_PER_LONG == 64 */
#endif /* _ASM_GENERIC_ATOMIC_H */
diff --git a/include/asm-generic/kdebug.h b/include/asm-generic/kdebug.h
new file mode 100644
index 0000000..2b799c9
--- /dev/null
+++ b/include/asm-generic/kdebug.h
@@ -0,0 +1,8 @@
+#ifndef _ASM_GENERIC_KDEBUG_H
+#define _ASM_GENERIC_KDEBUG_H
+
+enum die_val {
+ DIE_UNUSED,
+};
+
+#endif /* _ASM_GENERIC_KDEBUG_H */
diff --git a/include/asm-generic/local.h b/include/asm-generic/local.h
index ab46929..33d7d04 100644
--- a/include/asm-generic/local.h
+++ b/include/asm-generic/local.h
@@ -33,6 +33,19 @@
#define local_add(i,l) atomic_long_add((i),(&(l)->a))
#define local_sub(i,l) atomic_long_sub((i),(&(l)->a))
+#define local_sub_and_test(i, l) atomic_long_sub_and_test((i), (&(l)->a))
+#define local_dec_and_test(l) atomic_long_dec_and_test(&(l)->a)
+#define local_inc_and_test(l) atomic_long_inc_and_test(&(l)->a)
+#define local_add_negative(i, l) atomic_long_add_negative((i), (&(l)->a))
+#define local_add_return(i, l) atomic_long_add_return((i), (&(l)->a))
+#define local_sub_return(i, l) atomic_long_sub_return((i), (&(l)->a))
+#define local_inc_return(l) atomic_long_inc_return(&(l)->a)
+
+#define local_cmpxchg(l, o, n) atomic_long_cmpxchg((&(l)->a), (o), (n))
+#define local_xchg(l, n) atomic_long_xchg((&(l)->a), (n))
+#define local_add_unless(l, a, u) atomic_long_add_unless((&(l)->a), (a), (u))
+#define local_inc_not_zero(l) atomic_long_inc_not_zero(&(l)->a)
+
/* Non-atomic variants, ie. preemption disabled and won't be touched
* in interrupt, etc. Some archs can optimize this case well. */
#define __local_inc(l) local_set((l), local_read(l) + 1)
@@ -44,19 +57,19 @@
* much more efficient than these naive implementations. Note they take
* a variable (eg. mystruct.foo), not an address.
*/
-#define cpu_local_read(v) local_read(&__get_cpu_var(v))
-#define cpu_local_set(v, i) local_set(&__get_cpu_var(v), (i))
-#define cpu_local_inc(v) local_inc(&__get_cpu_var(v))
-#define cpu_local_dec(v) local_dec(&__get_cpu_var(v))
-#define cpu_local_add(i, v) local_add((i), &__get_cpu_var(v))
-#define cpu_local_sub(i, v) local_sub((i), &__get_cpu_var(v))
+#define cpu_local_read(l) local_read(&__get_cpu_var(l))
+#define cpu_local_set(l, i) local_set(&__get_cpu_var(l), (i))
+#define cpu_local_inc(l) local_inc(&__get_cpu_var(l))
+#define cpu_local_dec(l) local_dec(&__get_cpu_var(l))
+#define cpu_local_add(i, l) local_add((i), &__get_cpu_var(l))
+#define cpu_local_sub(i, l) local_sub((i), &__get_cpu_var(l))
/* Non-atomic increments, ie. preemption disabled and won't be touched
* in interrupt, etc. Some archs can optimize this case well.
*/
-#define __cpu_local_inc(v) __local_inc(&__get_cpu_var(v))
-#define __cpu_local_dec(v) __local_dec(&__get_cpu_var(v))
-#define __cpu_local_add(i, v) __local_add((i), &__get_cpu_var(v))
-#define __cpu_local_sub(i, v) __local_sub((i), &__get_cpu_var(v))
+#define __cpu_local_inc(l) __local_inc(&__get_cpu_var(l))
+#define __cpu_local_dec(l) __local_dec(&__get_cpu_var(l))
+#define __cpu_local_add(i, l) __local_add((i), &__get_cpu_var(l))
+#define __cpu_local_sub(i, l) __local_sub((i), &__get_cpu_var(l))
#endif /* _ASM_GENERIC_LOCAL_H */
diff --git a/include/asm-h8300/kdebug.h b/include/asm-h8300/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-h8300/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-h8300/pgtable.h b/include/asm-h8300/pgtable.h
index ddd07f4..a09230a 100644
--- a/include/asm-h8300/pgtable.h
+++ b/include/asm-h8300/pgtable.h
@@ -55,10 +55,6 @@
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
/*
* All 32bit addresses are effectively valid for vmalloc...
* Sort of meaningless for non-VM targets.
diff --git a/include/asm-h8300/system.h b/include/asm-h8300/system.h
index 5084a9d..7807018 100644
--- a/include/asm-h8300/system.h
+++ b/include/asm-h8300/system.h
@@ -98,7 +98,6 @@
#endif
#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
-#define tas(ptr) (xchg((ptr),1))
struct __xchg_dummy { unsigned long a[100]; };
#define __xg(x) ((volatile struct __xchg_dummy *)(x))
diff --git a/include/asm-i386/atomic.h b/include/asm-i386/atomic.h
index 4dd2723..0baa2f8 100644
--- a/include/asm-i386/atomic.h
+++ b/include/asm-i386/atomic.h
@@ -3,6 +3,7 @@
#include <linux/compiler.h>
#include <asm/processor.h>
+#include <asm/cmpxchg.h>
/*
* Atomic operations that C can't guarantee us. Useful for
@@ -51,7 +52,7 @@
}
/**
- * atomic_sub - subtract the atomic variable
+ * atomic_sub - subtract integer from atomic variable
* @i: integer value to subtract
* @v: pointer of type atomic_t
*
@@ -170,7 +171,7 @@
}
/**
- * atomic_add_return - add and return
+ * atomic_add_return - add integer and return
* @v: pointer of type atomic_t
* @i: integer value to add
*
@@ -202,13 +203,20 @@
#endif
}
+/**
+ * atomic_sub_return - subtract integer and return
+ * @v: pointer of type atomic_t
+ * @i: integer value to subtract
+ *
+ * Atomically subtracts @i from @v and returns @v - @i
+ */
static __inline__ int atomic_sub_return(int i, atomic_t *v)
{
return atomic_add_return(-i,v);
}
-#define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new))
-#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+#define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), (old), (new)))
+#define atomic_xchg(v, new) (xchg(&((v)->counter), (new)))
/**
* atomic_add_unless - add unless the number is already a given value
@@ -219,20 +227,21 @@
* Atomically adds @a to @v, so long as @v was not already @u.
* Returns non-zero if @v was not @u, and zero otherwise.
*/
-#define atomic_add_unless(v, a, u) \
-({ \
- int c, old; \
- c = atomic_read(v); \
- for (;;) { \
- if (unlikely(c == (u))) \
- break; \
- old = atomic_cmpxchg((v), c, c + (a)); \
- if (likely(old == c)) \
- break; \
- c = old; \
- } \
- c != (u); \
-})
+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int c, old;
+ c = atomic_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
#define atomic_inc_return(v) (atomic_add_return(1,v))
diff --git a/include/asm-i386/cmpxchg.h b/include/asm-i386/cmpxchg.h
new file mode 100644
index 0000000..7adcef0
--- /dev/null
+++ b/include/asm-i386/cmpxchg.h
@@ -0,0 +1,293 @@
+#ifndef __ASM_CMPXCHG_H
+#define __ASM_CMPXCHG_H
+
+#include <linux/bitops.h> /* for LOCK_PREFIX */
+
+#define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
+
+struct __xchg_dummy { unsigned long a[100]; };
+#define __xg(x) ((struct __xchg_dummy *)(x))
+
+
+#ifdef CONFIG_X86_CMPXCHG64
+
+/*
+ * The semantics of XCHGCMP8B are a bit strange, this is why
+ * there is a loop and the loading of %%eax and %%edx has to
+ * be inside. This inlines well in most cases, the cached
+ * cost is around ~38 cycles. (in the future we might want
+ * to do an SIMD/3DNOW!/MMX/FPU 64-bit store here, but that
+ * might have an implicit FPU-save as a cost, so it's not
+ * clear which path to go.)
+ *
+ * cmpxchg8b must be used with the lock prefix here to allow
+ * the instruction to be executed atomically, see page 3-102
+ * of the instruction set reference 24319102.pdf. We need
+ * the reader side to see the coherent 64bit value.
+ */
+static inline void __set_64bit (unsigned long long * ptr,
+ unsigned int low, unsigned int high)
+{
+ __asm__ __volatile__ (
+ "\n1:\t"
+ "movl (%0), %%eax\n\t"
+ "movl 4(%0), %%edx\n\t"
+ "lock cmpxchg8b (%0)\n\t"
+ "jnz 1b"
+ : /* no outputs */
+ : "D"(ptr),
+ "b"(low),
+ "c"(high)
+ : "ax","dx","memory");
+}
+
+static inline void __set_64bit_constant (unsigned long long *ptr,
+ unsigned long long value)
+{
+ __set_64bit(ptr,(unsigned int)(value), (unsigned int)((value)>>32ULL));
+}
+#define ll_low(x) *(((unsigned int*)&(x))+0)
+#define ll_high(x) *(((unsigned int*)&(x))+1)
+
+static inline void __set_64bit_var (unsigned long long *ptr,
+ unsigned long long value)
+{
+ __set_64bit(ptr,ll_low(value), ll_high(value));
+}
+
+#define set_64bit(ptr,value) \
+(__builtin_constant_p(value) ? \
+ __set_64bit_constant(ptr, value) : \
+ __set_64bit_var(ptr, value) )
+
+#define _set_64bit(ptr,value) \
+(__builtin_constant_p(value) ? \
+ __set_64bit(ptr, (unsigned int)(value), (unsigned int)((value)>>32ULL) ) : \
+ __set_64bit(ptr, ll_low(value), ll_high(value)) )
+
+#endif
+
+/*
+ * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
+ * Note 2: xchg has side effect, so that attribute volatile is necessary,
+ * but generally the primitive is invalid, *ptr is output argument. --ANK
+ */
+static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
+{
+ switch (size) {
+ case 1:
+ __asm__ __volatile__("xchgb %b0,%1"
+ :"=q" (x)
+ :"m" (*__xg(ptr)), "0" (x)
+ :"memory");
+ break;
+ case 2:
+ __asm__ __volatile__("xchgw %w0,%1"
+ :"=r" (x)
+ :"m" (*__xg(ptr)), "0" (x)
+ :"memory");
+ break;
+ case 4:
+ __asm__ __volatile__("xchgl %0,%1"
+ :"=r" (x)
+ :"m" (*__xg(ptr)), "0" (x)
+ :"memory");
+ break;
+ }
+ return x;
+}
+
+/*
+ * Atomic compare and exchange. Compare OLD with MEM, if identical,
+ * store NEW in MEM. Return the initial value in MEM. Success is
+ * indicated by comparing RETURN with OLD.
+ */
+
+#ifdef CONFIG_X86_CMPXCHG
+#define __HAVE_ARCH_CMPXCHG 1
+#define cmpxchg(ptr,o,n)\
+ ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
+ (unsigned long)(n),sizeof(*(ptr))))
+#define sync_cmpxchg(ptr,o,n)\
+ ((__typeof__(*(ptr)))__sync_cmpxchg((ptr),(unsigned long)(o),\
+ (unsigned long)(n),sizeof(*(ptr))))
+#define cmpxchg_local(ptr,o,n)\
+ ((__typeof__(*(ptr)))__cmpxchg_local((ptr),(unsigned long)(o),\
+ (unsigned long)(n),sizeof(*(ptr))))
+#endif
+
+static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
+ unsigned long new, int size)
+{
+ unsigned long prev;
+ switch (size) {
+ case 1:
+ __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
+ : "=a"(prev)
+ : "q"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ case 2:
+ __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
+ : "=a"(prev)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ case 4:
+ __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
+ : "=a"(prev)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ }
+ return old;
+}
+
+/*
+ * Always use locked operations when touching memory shared with a
+ * hypervisor, since the system may be SMP even if the guest kernel
+ * isn't.
+ */
+static inline unsigned long __sync_cmpxchg(volatile void *ptr,
+ unsigned long old,
+ unsigned long new, int size)
+{
+ unsigned long prev;
+ switch (size) {
+ case 1:
+ __asm__ __volatile__("lock; cmpxchgb %b1,%2"
+ : "=a"(prev)
+ : "q"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ case 2:
+ __asm__ __volatile__("lock; cmpxchgw %w1,%2"
+ : "=a"(prev)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ case 4:
+ __asm__ __volatile__("lock; cmpxchgl %1,%2"
+ : "=a"(prev)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ }
+ return old;
+}
+
+static inline unsigned long __cmpxchg_local(volatile void *ptr,
+ unsigned long old, unsigned long new, int size)
+{
+ unsigned long prev;
+ switch (size) {
+ case 1:
+ __asm__ __volatile__("cmpxchgb %b1,%2"
+ : "=a"(prev)
+ : "q"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ case 2:
+ __asm__ __volatile__("cmpxchgw %w1,%2"
+ : "=a"(prev)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ case 4:
+ __asm__ __volatile__("cmpxchgl %1,%2"
+ : "=a"(prev)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ }
+ return old;
+}
+
+#ifndef CONFIG_X86_CMPXCHG
+/*
+ * Building a kernel capable running on 80386. It may be necessary to
+ * simulate the cmpxchg on the 80386 CPU. For that purpose we define
+ * a function for each of the sizes we support.
+ */
+
+extern unsigned long cmpxchg_386_u8(volatile void *, u8, u8);
+extern unsigned long cmpxchg_386_u16(volatile void *, u16, u16);
+extern unsigned long cmpxchg_386_u32(volatile void *, u32, u32);
+
+static inline unsigned long cmpxchg_386(volatile void *ptr, unsigned long old,
+ unsigned long new, int size)
+{
+ switch (size) {
+ case 1:
+ return cmpxchg_386_u8(ptr, old, new);
+ case 2:
+ return cmpxchg_386_u16(ptr, old, new);
+ case 4:
+ return cmpxchg_386_u32(ptr, old, new);
+ }
+ return old;
+}
+
+#define cmpxchg(ptr,o,n) \
+({ \
+ __typeof__(*(ptr)) __ret; \
+ if (likely(boot_cpu_data.x86 > 3)) \
+ __ret = __cmpxchg((ptr), (unsigned long)(o), \
+ (unsigned long)(n), sizeof(*(ptr))); \
+ else \
+ __ret = cmpxchg_386((ptr), (unsigned long)(o), \
+ (unsigned long)(n), sizeof(*(ptr))); \
+ __ret; \
+})
+#define cmpxchg_local(ptr,o,n) \
+({ \
+ __typeof__(*(ptr)) __ret; \
+ if (likely(boot_cpu_data.x86 > 3)) \
+ __ret = __cmpxchg_local((ptr), (unsigned long)(o), \
+ (unsigned long)(n), sizeof(*(ptr))); \
+ else \
+ __ret = cmpxchg_386((ptr), (unsigned long)(o), \
+ (unsigned long)(n), sizeof(*(ptr))); \
+ __ret; \
+})
+#endif
+
+#ifdef CONFIG_X86_CMPXCHG64
+
+static inline unsigned long long __cmpxchg64(volatile void *ptr, unsigned long long old,
+ unsigned long long new)
+{
+ unsigned long long prev;
+ __asm__ __volatile__(LOCK_PREFIX "cmpxchg8b %3"
+ : "=A"(prev)
+ : "b"((unsigned long)new),
+ "c"((unsigned long)(new >> 32)),
+ "m"(*__xg(ptr)),
+ "0"(old)
+ : "memory");
+ return prev;
+}
+
+static inline unsigned long long __cmpxchg64_local(volatile void *ptr,
+ unsigned long long old, unsigned long long new)
+{
+ unsigned long long prev;
+ __asm__ __volatile__("cmpxchg8b %3"
+ : "=A"(prev)
+ : "b"((unsigned long)new),
+ "c"((unsigned long)(new >> 32)),
+ "m"(*__xg(ptr)),
+ "0"(old)
+ : "memory");
+ return prev;
+}
+
+#define cmpxchg64(ptr,o,n)\
+ ((__typeof__(*(ptr)))__cmpxchg64((ptr),(unsigned long long)(o),\
+ (unsigned long long)(n)))
+#define cmpxchg64_local(ptr,o,n)\
+ ((__typeof__(*(ptr)))__cmpxchg64_local((ptr),(unsigned long long)(o),\
+ (unsigned long long)(n)))
+#endif
+
+#endif
diff --git a/include/asm-i386/elf.h b/include/asm-i386/elf.h
index d304ab4..b32df3a 100644
--- a/include/asm-i386/elf.h
+++ b/include/asm-i386/elf.h
@@ -9,8 +9,6 @@
#include <asm/user.h>
#include <asm/auxvec.h>
-#include <linux/utsname.h>
-
#define R_386_NONE 0
#define R_386_32 1
#define R_386_PC32 2
diff --git a/include/asm-i386/ioctls.h b/include/asm-i386/ioctls.h
index f962fad..ef58787 100644
--- a/include/asm-i386/ioctls.h
+++ b/include/asm-i386/ioctls.h
@@ -47,6 +47,10 @@
#define TIOCSBRK 0x5427 /* BSD compatibility */
#define TIOCCBRK 0x5428 /* BSD compatibility */
#define TIOCGSID 0x5429 /* Return the session ID of FD */
+#define TCGETS2 _IOR('T',0x2A, struct termios2)
+#define TCSETS2 _IOW('T',0x2B, struct termios2)
+#define TCSETSW2 _IOW('T',0x2C, struct termios2)
+#define TCSETSF2 _IOW('T',0x2D, struct termios2)
#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */
diff --git a/include/asm-i386/kdebug.h b/include/asm-i386/kdebug.h
index d18cdb9..05c3117 100644
--- a/include/asm-i386/kdebug.h
+++ b/include/asm-i386/kdebug.h
@@ -9,19 +9,8 @@
struct pt_regs;
-struct die_args {
- struct pt_regs *regs;
- const char *str;
- long err;
- int trapnr;
- int signr;
-};
-
-extern int register_die_notifier(struct notifier_block *);
-extern int unregister_die_notifier(struct notifier_block *);
extern int register_page_fault_notifier(struct notifier_block *);
extern int unregister_page_fault_notifier(struct notifier_block *);
-extern struct atomic_notifier_head i386die_chain;
/* Grossly misnamed. */
@@ -38,20 +27,8 @@
DIE_GPF,
DIE_CALL,
DIE_NMI_IPI,
+ DIE_NMI_POST,
DIE_PAGE_FAULT,
};
-static inline int notify_die(enum die_val val, const char *str,
- struct pt_regs *regs, long err, int trap, int sig)
-{
- struct die_args args = {
- .regs = regs,
- .str = str,
- .err = err,
- .trapnr = trap,
- .signr = sig
- };
- return atomic_notifier_call_chain(&i386die_chain, val, &args);
-}
-
#endif
diff --git a/include/asm-i386/kexec.h b/include/asm-i386/kexec.h
index bcb5b21..4b9dc9e 100644
--- a/include/asm-i386/kexec.h
+++ b/include/asm-i386/kexec.h
@@ -45,8 +45,6 @@
/* We can also handle crash dumps from 64 bit kernel. */
#define vmcore_elf_check_arch_cross(x) ((x)->e_machine == EM_X86_64)
-#define MAX_NOTE_BYTES 1024
-
/* CPU does not save ss and esp on stack if execution is already
* running in kernel mode at the time of NMI occurrence. This code
* fixes it.
diff --git a/include/asm-i386/local.h b/include/asm-i386/local.h
index 12060e2..e13d3e9 100644
--- a/include/asm-i386/local.h
+++ b/include/asm-i386/local.h
@@ -2,47 +2,198 @@
#define _ARCH_I386_LOCAL_H
#include <linux/percpu.h>
+#include <asm/system.h>
+#include <asm/atomic.h>
typedef struct
{
- volatile long counter;
+ atomic_long_t a;
} local_t;
-#define LOCAL_INIT(i) { (i) }
+#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) }
-#define local_read(v) ((v)->counter)
-#define local_set(v,i) (((v)->counter) = (i))
+#define local_read(l) atomic_long_read(&(l)->a)
+#define local_set(l,i) atomic_long_set(&(l)->a, (i))
-static __inline__ void local_inc(local_t *v)
+static __inline__ void local_inc(local_t *l)
{
__asm__ __volatile__(
"incl %0"
- :"+m" (v->counter));
+ :"+m" (l->a.counter));
}
-static __inline__ void local_dec(local_t *v)
+static __inline__ void local_dec(local_t *l)
{
__asm__ __volatile__(
"decl %0"
- :"+m" (v->counter));
+ :"+m" (l->a.counter));
}
-static __inline__ void local_add(long i, local_t *v)
+static __inline__ void local_add(long i, local_t *l)
{
__asm__ __volatile__(
"addl %1,%0"
- :"+m" (v->counter)
+ :"+m" (l->a.counter)
:"ir" (i));
}
-static __inline__ void local_sub(long i, local_t *v)
+static __inline__ void local_sub(long i, local_t *l)
{
__asm__ __volatile__(
"subl %1,%0"
- :"+m" (v->counter)
+ :"+m" (l->a.counter)
:"ir" (i));
}
+/**
+ * local_sub_and_test - subtract value from variable and test result
+ * @i: integer value to subtract
+ * @l: pointer of type local_t
+ *
+ * Atomically subtracts @i from @l and returns
+ * true if the result is zero, or false for all
+ * other cases.
+ */
+static __inline__ int local_sub_and_test(long i, local_t *l)
+{
+ unsigned char c;
+
+ __asm__ __volatile__(
+ "subl %2,%0; sete %1"
+ :"+m" (l->a.counter), "=qm" (c)
+ :"ir" (i) : "memory");
+ return c;
+}
+
+/**
+ * local_dec_and_test - decrement and test
+ * @l: pointer of type local_t
+ *
+ * Atomically decrements @l by 1 and
+ * returns true if the result is 0, or false for all other
+ * cases.
+ */
+static __inline__ int local_dec_and_test(local_t *l)
+{
+ unsigned char c;
+
+ __asm__ __volatile__(
+ "decl %0; sete %1"
+ :"+m" (l->a.counter), "=qm" (c)
+ : : "memory");
+ return c != 0;
+}
+
+/**
+ * local_inc_and_test - increment and test
+ * @l: pointer of type local_t
+ *
+ * Atomically increments @l by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+static __inline__ int local_inc_and_test(local_t *l)
+{
+ unsigned char c;
+
+ __asm__ __volatile__(
+ "incl %0; sete %1"
+ :"+m" (l->a.counter), "=qm" (c)
+ : : "memory");
+ return c != 0;
+}
+
+/**
+ * local_add_negative - add and test if negative
+ * @l: pointer of type local_t
+ * @i: integer value to add
+ *
+ * Atomically adds @i to @l and returns true
+ * if the result is negative, or false when
+ * result is greater than or equal to zero.
+ */
+static __inline__ int local_add_negative(long i, local_t *l)
+{
+ unsigned char c;
+
+ __asm__ __volatile__(
+ "addl %2,%0; sets %1"
+ :"+m" (l->a.counter), "=qm" (c)
+ :"ir" (i) : "memory");
+ return c;
+}
+
+/**
+ * local_add_return - add and return
+ * @l: pointer of type local_t
+ * @i: integer value to add
+ *
+ * Atomically adds @i to @l and returns @i + @l
+ */
+static __inline__ long local_add_return(long i, local_t *l)
+{
+ long __i;
+#ifdef CONFIG_M386
+ unsigned long flags;
+ if(unlikely(boot_cpu_data.x86==3))
+ goto no_xadd;
+#endif
+ /* Modern 486+ processor */
+ __i = i;
+ __asm__ __volatile__(
+ "xaddl %0, %1;"
+ :"+r" (i), "+m" (l->a.counter)
+ : : "memory");
+ return i + __i;
+
+#ifdef CONFIG_M386
+no_xadd: /* Legacy 386 processor */
+ local_irq_save(flags);
+ __i = local_read(l);
+ local_set(l, i + __i);
+ local_irq_restore(flags);
+ return i + __i;
+#endif
+}
+
+static __inline__ long local_sub_return(long i, local_t *l)
+{
+ return local_add_return(-i,l);
+}
+
+#define local_inc_return(l) (local_add_return(1,l))
+#define local_dec_return(l) (local_sub_return(1,l))
+
+#define local_cmpxchg(l, o, n) \
+ (cmpxchg_local(&((l)->a.counter), (o), (n)))
+/* Always has a lock prefix */
+#define local_xchg(l, n) (xchg(&((l)->a.counter), (n)))
+
+/**
+ * local_add_unless - add unless the number is a given value
+ * @l: pointer of type local_t
+ * @a: the amount to add to l...
+ * @u: ...unless l is equal to u.
+ *
+ * Atomically adds @a to @l, so long as it was not @u.
+ * Returns non-zero if @l was not @u, and zero otherwise.
+ */
+#define local_add_unless(l, a, u) \
+({ \
+ long c, old; \
+ c = local_read(l); \
+ for (;;) { \
+ if (unlikely(c == (u))) \
+ break; \
+ old = local_cmpxchg((l), c, c + (a)); \
+ if (likely(old == c)) \
+ break; \
+ c = old; \
+ } \
+ c != (u); \
+})
+#define local_inc_not_zero(l) local_add_unless((l), 1, 0)
+
/* On x86, these are no better than the atomic variants. */
#define __local_inc(l) local_inc(l)
#define __local_dec(l) local_dec(l)
@@ -56,27 +207,27 @@
/* Need to disable preemption for the cpu local counters otherwise we could
still access a variable of a previous CPU in a non atomic way. */
-#define cpu_local_wrap_v(v) \
+#define cpu_local_wrap_v(l) \
({ local_t res__; \
preempt_disable(); \
- res__ = (v); \
+ res__ = (l); \
preempt_enable(); \
res__; })
-#define cpu_local_wrap(v) \
+#define cpu_local_wrap(l) \
({ preempt_disable(); \
- v; \
+ l; \
preempt_enable(); }) \
-#define cpu_local_read(v) cpu_local_wrap_v(local_read(&__get_cpu_var(v)))
-#define cpu_local_set(v, i) cpu_local_wrap(local_set(&__get_cpu_var(v), (i)))
-#define cpu_local_inc(v) cpu_local_wrap(local_inc(&__get_cpu_var(v)))
-#define cpu_local_dec(v) cpu_local_wrap(local_dec(&__get_cpu_var(v)))
-#define cpu_local_add(i, v) cpu_local_wrap(local_add((i), &__get_cpu_var(v)))
-#define cpu_local_sub(i, v) cpu_local_wrap(local_sub((i), &__get_cpu_var(v)))
+#define cpu_local_read(l) cpu_local_wrap_v(local_read(&__get_cpu_var(l)))
+#define cpu_local_set(l, i) cpu_local_wrap(local_set(&__get_cpu_var(l), (i)))
+#define cpu_local_inc(l) cpu_local_wrap(local_inc(&__get_cpu_var(l)))
+#define cpu_local_dec(l) cpu_local_wrap(local_dec(&__get_cpu_var(l)))
+#define cpu_local_add(i, l) cpu_local_wrap(local_add((i), &__get_cpu_var(l)))
+#define cpu_local_sub(i, l) cpu_local_wrap(local_sub((i), &__get_cpu_var(l)))
-#define __cpu_local_inc(v) cpu_local_inc(v)
-#define __cpu_local_dec(v) cpu_local_dec(v)
-#define __cpu_local_add(i, v) cpu_local_add((i), (v))
-#define __cpu_local_sub(i, v) cpu_local_sub((i), (v))
+#define __cpu_local_inc(l) cpu_local_inc(l)
+#define __cpu_local_dec(l) cpu_local_dec(l)
+#define __cpu_local_add(i, l) cpu_local_add((i), (l))
+#define __cpu_local_sub(i, l) cpu_local_sub((i), (l))
#endif /* _ARCH_I386_LOCAL_H */
diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h
index e16359f..edce9d5 100644
--- a/include/asm-i386/pgtable.h
+++ b/include/asm-i386/pgtable.h
@@ -243,8 +243,6 @@
static inline pte_t pte_mkwrite(pte_t pte) { (pte).pte_low |= _PAGE_RW; return pte; }
static inline pte_t pte_mkhuge(pte_t pte) { (pte).pte_low |= _PAGE_PSE; return pte; }
-extern void vmalloc_sync_all(void);
-
#ifdef CONFIG_X86_PAE
# include <asm/pgtable-3level.h>
#else
@@ -544,10 +542,6 @@
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
#include <asm-generic/pgtable.h>
#endif /* _I386_PGTABLE_H */
diff --git a/include/asm-i386/serial.h b/include/asm-i386/serial.h
index bd67480..57a4306 100644
--- a/include/asm-i386/serial.h
+++ b/include/asm-i386/serial.h
@@ -11,19 +11,3 @@
* megabits/second; but this requires the faster clock.
*/
#define BASE_BAUD ( 1843200 / 16 )
-
-/* Standard COM flags (except for COM4, because of the 8514 problem) */
-#ifdef CONFIG_SERIAL_DETECT_IRQ
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ)
-#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ)
-#else
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
-#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
-#endif
-
-#define SERIAL_PORT_DFNS \
- /* UART CLK PORT IRQ FLAGS */ \
- { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \
- { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \
- { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \
- { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */
diff --git a/include/asm-i386/system.h b/include/asm-i386/system.h
index c3a58c0..94ed3686 100644
--- a/include/asm-i386/system.h
+++ b/include/asm-i386/system.h
@@ -4,7 +4,7 @@
#include <linux/kernel.h>
#include <asm/segment.h>
#include <asm/cpufeature.h>
-#include <linux/bitops.h> /* for LOCK_PREFIX */
+#include <asm/cmpxchg.h>
#ifdef __KERNEL__
@@ -195,238 +195,6 @@
#define nop() __asm__ __volatile__ ("nop")
-#define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
-
-#define tas(ptr) (xchg((ptr),1))
-
-struct __xchg_dummy { unsigned long a[100]; };
-#define __xg(x) ((struct __xchg_dummy *)(x))
-
-
-#ifdef CONFIG_X86_CMPXCHG64
-
-/*
- * The semantics of XCHGCMP8B are a bit strange, this is why
- * there is a loop and the loading of %%eax and %%edx has to
- * be inside. This inlines well in most cases, the cached
- * cost is around ~38 cycles. (in the future we might want
- * to do an SIMD/3DNOW!/MMX/FPU 64-bit store here, but that
- * might have an implicit FPU-save as a cost, so it's not
- * clear which path to go.)
- *
- * cmpxchg8b must be used with the lock prefix here to allow
- * the instruction to be executed atomically, see page 3-102
- * of the instruction set reference 24319102.pdf. We need
- * the reader side to see the coherent 64bit value.
- */
-static inline void __set_64bit (unsigned long long * ptr,
- unsigned int low, unsigned int high)
-{
- __asm__ __volatile__ (
- "\n1:\t"
- "movl (%0), %%eax\n\t"
- "movl 4(%0), %%edx\n\t"
- "lock cmpxchg8b (%0)\n\t"
- "jnz 1b"
- : /* no outputs */
- : "D"(ptr),
- "b"(low),
- "c"(high)
- : "ax","dx","memory");
-}
-
-static inline void __set_64bit_constant (unsigned long long *ptr,
- unsigned long long value)
-{
- __set_64bit(ptr,(unsigned int)(value), (unsigned int)((value)>>32ULL));
-}
-#define ll_low(x) *(((unsigned int*)&(x))+0)
-#define ll_high(x) *(((unsigned int*)&(x))+1)
-
-static inline void __set_64bit_var (unsigned long long *ptr,
- unsigned long long value)
-{
- __set_64bit(ptr,ll_low(value), ll_high(value));
-}
-
-#define set_64bit(ptr,value) \
-(__builtin_constant_p(value) ? \
- __set_64bit_constant(ptr, value) : \
- __set_64bit_var(ptr, value) )
-
-#define _set_64bit(ptr,value) \
-(__builtin_constant_p(value) ? \
- __set_64bit(ptr, (unsigned int)(value), (unsigned int)((value)>>32ULL) ) : \
- __set_64bit(ptr, ll_low(value), ll_high(value)) )
-
-#endif
-
-/*
- * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
- * Note 2: xchg has side effect, so that attribute volatile is necessary,
- * but generally the primitive is invalid, *ptr is output argument. --ANK
- */
-static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
-{
- switch (size) {
- case 1:
- __asm__ __volatile__("xchgb %b0,%1"
- :"=q" (x)
- :"m" (*__xg(ptr)), "0" (x)
- :"memory");
- break;
- case 2:
- __asm__ __volatile__("xchgw %w0,%1"
- :"=r" (x)
- :"m" (*__xg(ptr)), "0" (x)
- :"memory");
- break;
- case 4:
- __asm__ __volatile__("xchgl %0,%1"
- :"=r" (x)
- :"m" (*__xg(ptr)), "0" (x)
- :"memory");
- break;
- }
- return x;
-}
-
-/*
- * Atomic compare and exchange. Compare OLD with MEM, if identical,
- * store NEW in MEM. Return the initial value in MEM. Success is
- * indicated by comparing RETURN with OLD.
- */
-
-#ifdef CONFIG_X86_CMPXCHG
-#define __HAVE_ARCH_CMPXCHG 1
-#define cmpxchg(ptr,o,n)\
- ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
- (unsigned long)(n),sizeof(*(ptr))))
-#define sync_cmpxchg(ptr,o,n)\
- ((__typeof__(*(ptr)))__sync_cmpxchg((ptr),(unsigned long)(o),\
- (unsigned long)(n),sizeof(*(ptr))))
-#endif
-
-static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
- unsigned long new, int size)
-{
- unsigned long prev;
- switch (size) {
- case 1:
- __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
- : "=a"(prev)
- : "q"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- case 2:
- __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- case 4:
- __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- }
- return old;
-}
-
-/*
- * Always use locked operations when touching memory shared with a
- * hypervisor, since the system may be SMP even if the guest kernel
- * isn't.
- */
-static inline unsigned long __sync_cmpxchg(volatile void *ptr,
- unsigned long old,
- unsigned long new, int size)
-{
- unsigned long prev;
- switch (size) {
- case 1:
- __asm__ __volatile__("lock; cmpxchgb %b1,%2"
- : "=a"(prev)
- : "q"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- case 2:
- __asm__ __volatile__("lock; cmpxchgw %w1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- case 4:
- __asm__ __volatile__("lock; cmpxchgl %1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- }
- return old;
-}
-
-#ifndef CONFIG_X86_CMPXCHG
-/*
- * Building a kernel capable running on 80386. It may be necessary to
- * simulate the cmpxchg on the 80386 CPU. For that purpose we define
- * a function for each of the sizes we support.
- */
-
-extern unsigned long cmpxchg_386_u8(volatile void *, u8, u8);
-extern unsigned long cmpxchg_386_u16(volatile void *, u16, u16);
-extern unsigned long cmpxchg_386_u32(volatile void *, u32, u32);
-
-static inline unsigned long cmpxchg_386(volatile void *ptr, unsigned long old,
- unsigned long new, int size)
-{
- switch (size) {
- case 1:
- return cmpxchg_386_u8(ptr, old, new);
- case 2:
- return cmpxchg_386_u16(ptr, old, new);
- case 4:
- return cmpxchg_386_u32(ptr, old, new);
- }
- return old;
-}
-
-#define cmpxchg(ptr,o,n) \
-({ \
- __typeof__(*(ptr)) __ret; \
- if (likely(boot_cpu_data.x86 > 3)) \
- __ret = __cmpxchg((ptr), (unsigned long)(o), \
- (unsigned long)(n), sizeof(*(ptr))); \
- else \
- __ret = cmpxchg_386((ptr), (unsigned long)(o), \
- (unsigned long)(n), sizeof(*(ptr))); \
- __ret; \
-})
-#endif
-
-#ifdef CONFIG_X86_CMPXCHG64
-
-static inline unsigned long long __cmpxchg64(volatile void *ptr, unsigned long long old,
- unsigned long long new)
-{
- unsigned long long prev;
- __asm__ __volatile__(LOCK_PREFIX "cmpxchg8b %3"
- : "=A"(prev)
- : "b"((unsigned long)new),
- "c"((unsigned long)(new >> 32)),
- "m"(*__xg(ptr)),
- "0"(old)
- : "memory");
- return prev;
-}
-
-#define cmpxchg64(ptr,o,n)\
- ((__typeof__(*(ptr)))__cmpxchg64((ptr),(unsigned long long)(o),\
- (unsigned long long)(n)))
-
-#endif
-
/*
* Force strict CPU ordering.
* And yes, this is required on UP too when we're talking
diff --git a/include/asm-i386/termbits.h b/include/asm-i386/termbits.h
index 2e623769..a217003 100644
--- a/include/asm-i386/termbits.h
+++ b/include/asm-i386/termbits.h
@@ -17,6 +17,17 @@
cc_t c_cc[NCCS]; /* control characters */
};
+struct termios2 {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[NCCS]; /* control characters */
+ speed_t c_ispeed; /* input speed */
+ speed_t c_ospeed; /* output speed */
+};
+
struct ktermios {
tcflag_t c_iflag; /* input mode flags */
tcflag_t c_oflag; /* output mode flags */
@@ -129,6 +140,7 @@
#define HUPCL 0002000
#define CLOCAL 0004000
#define CBAUDEX 0010000
+#define BOTHER 0010000
#define B57600 0010001
#define B115200 0010002
#define B230400 0010003
@@ -148,6 +160,8 @@
#define CMSPAR 010000000000 /* mark or space (stick) parity */
#define CRTSCTS 020000000000 /* flow control */
+#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */
+
/* c_lflag bits */
#define ISIG 0000001
#define ICANON 0000002
diff --git a/include/asm-i386/termios.h b/include/asm-i386/termios.h
index 7c99678..f520b7c 100644
--- a/include/asm-i386/termios.h
+++ b/include/asm-i386/termios.h
@@ -81,8 +81,10 @@
copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
})
-#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
-#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios2))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios2))
+#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios))
#endif /* __KERNEL__ */
diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h
index 833fa17..bd21e79 100644
--- a/include/asm-i386/unistd.h
+++ b/include/asm-i386/unistd.h
@@ -325,10 +325,11 @@
#define __NR_move_pages 317
#define __NR_getcpu 318
#define __NR_epoll_pwait 319
+#define __NR_utimensat 320
#ifdef __KERNEL__
-#define NR_syscalls 320
+#define NR_syscalls 321
#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
diff --git a/include/asm-ia64/atomic.h b/include/asm-ia64/atomic.h
index 569ec75..1fc3b83 100644
--- a/include/asm-ia64/atomic.h
+++ b/include/asm-ia64/atomic.h
@@ -15,6 +15,7 @@
#include <linux/types.h>
#include <asm/intrinsics.h>
+#include <asm/system.h>
/*
* On IA-64, counter must always be volatile to ensure that that the
@@ -88,25 +89,47 @@
return new;
}
-#define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new))
+#define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new))
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
-#define atomic_add_unless(v, a, u) \
-({ \
- int c, old; \
- c = atomic_read(v); \
- for (;;) { \
- if (unlikely(c == (u))) \
- break; \
- old = atomic_cmpxchg((v), c, c + (a)); \
- if (likely(old == c)) \
- break; \
- c = old; \
- } \
- c != (u); \
-})
+#define atomic64_cmpxchg(v, old, new) \
+ (cmpxchg(&((v)->counter), old, new))
+#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
+
+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int c, old;
+ c = atomic_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+{
+ long c, old;
+ c = atomic64_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic64_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
+#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
#define atomic_add_return(i,v) \
({ \
int __ia64_aar_i = (i); \
diff --git a/include/asm-ia64/kdebug.h b/include/asm-ia64/kdebug.h
index aed7142..ba211e0 100644
--- a/include/asm-ia64/kdebug.h
+++ b/include/asm-ia64/kdebug.h
@@ -28,21 +28,8 @@
*/
#include <linux/notifier.h>
-struct pt_regs;
-
-struct die_args {
- struct pt_regs *regs;
- const char *str;
- long err;
- int trapnr;
- int signr;
-};
-
-extern int register_die_notifier(struct notifier_block *);
-extern int unregister_die_notifier(struct notifier_block *);
extern int register_page_fault_notifier(struct notifier_block *);
extern int unregister_page_fault_notifier(struct notifier_block *);
-extern struct atomic_notifier_head ia64die_chain;
enum die_val {
DIE_BREAK = 1,
@@ -74,18 +61,4 @@
DIE_KDUMP_LEAVE,
};
-static inline int notify_die(enum die_val val, char *str, struct pt_regs *regs,
- long err, int trap, int sig)
-{
- struct die_args args = {
- .regs = regs,
- .str = str,
- .err = err,
- .trapnr = trap,
- .signr = sig
- };
-
- return atomic_notifier_call_chain(&ia64die_chain, val, &args);
-}
-
#endif
diff --git a/include/asm-ia64/kexec.h b/include/asm-ia64/kexec.h
index 41299dd..541be83 100644
--- a/include/asm-ia64/kexec.h
+++ b/include/asm-ia64/kexec.h
@@ -14,8 +14,6 @@
/* The native architecture */
#define KEXEC_ARCH KEXEC_ARCH_IA_64
-#define MAX_NOTE_BYTES 1024
-
#define kexec_flush_icache_page(page) do { \
unsigned long page_addr = (unsigned long)page_address(page); \
flush_icache_range(page_addr, page_addr + PAGE_SIZE); \
diff --git a/include/asm-ia64/local.h b/include/asm-ia64/local.h
index dc51909..c11c530 100644
--- a/include/asm-ia64/local.h
+++ b/include/asm-ia64/local.h
@@ -1,50 +1 @@
-#ifndef _ASM_IA64_LOCAL_H
-#define _ASM_IA64_LOCAL_H
-
-/*
- * Copyright (C) 2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-#include <linux/percpu.h>
-
-typedef struct {
- atomic64_t val;
-} local_t;
-
-#define LOCAL_INIT(i) ((local_t) { { (i) } })
-#define local_read(l) atomic64_read(&(l)->val)
-#define local_set(l, i) atomic64_set(&(l)->val, i)
-#define local_inc(l) atomic64_inc(&(l)->val)
-#define local_dec(l) atomic64_dec(&(l)->val)
-#define local_add(i, l) atomic64_add((i), &(l)->val)
-#define local_sub(i, l) atomic64_sub((i), &(l)->val)
-
-/* Non-atomic variants, i.e., preemption disabled and won't be touched in interrupt, etc. */
-
-#define __local_inc(l) (++(l)->val.counter)
-#define __local_dec(l) (--(l)->val.counter)
-#define __local_add(i,l) ((l)->val.counter += (i))
-#define __local_sub(i,l) ((l)->val.counter -= (i))
-
-/*
- * Use these for per-cpu local_t variables. Note they take a variable (eg. mystruct.foo),
- * not an address.
- */
-#define cpu_local_read(v) local_read(&__ia64_per_cpu_var(v))
-#define cpu_local_set(v, i) local_set(&__ia64_per_cpu_var(v), (i))
-#define cpu_local_inc(v) local_inc(&__ia64_per_cpu_var(v))
-#define cpu_local_dec(v) local_dec(&__ia64_per_cpu_var(v))
-#define cpu_local_add(i, v) local_add((i), &__ia64_per_cpu_var(v))
-#define cpu_local_sub(i, v) local_sub((i), &__ia64_per_cpu_var(v))
-
-/*
- * Non-atomic increments, i.e., preemption disabled and won't be touched in interrupt,
- * etc.
- */
-#define __cpu_local_inc(v) __local_inc(&__ia64_per_cpu_var(v))
-#define __cpu_local_dec(v) __local_dec(&__ia64_per_cpu_var(v))
-#define __cpu_local_add(i, v) __local_add((i), &__ia64_per_cpu_var(v))
-#define __cpu_local_sub(i, v) __local_sub((i), &__ia64_per_cpu_var(v))
-
-#endif /* _ASM_IA64_LOCAL_H */
+#include <asm-generic/local.h>
diff --git a/include/asm-ia64/pgtable.h b/include/asm-ia64/pgtable.h
index 5531827..670b706 100644
--- a/include/asm-ia64/pgtable.h
+++ b/include/asm-ia64/pgtable.h
@@ -485,10 +485,6 @@
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
/*
* ZERO_PAGE is a global shared page that is always zero: used
* for zero-mapped memory areas etc..
diff --git a/include/asm-m32r/atomic.h b/include/asm-m32r/atomic.h
index f5a7d73..3a38ffe 100644
--- a/include/asm-m32r/atomic.h
+++ b/include/asm-m32r/atomic.h
@@ -253,14 +253,21 @@
* Atomically adds @a to @v, so long as it was not @u.
* Returns non-zero if @v was not @u, and zero otherwise.
*/
-#define atomic_add_unless(v, a, u) \
-({ \
- int c, old; \
- c = atomic_read(v); \
- while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
- c = old; \
- c != (u); \
-})
+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int c, old;
+ c = atomic_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
static __inline__ void atomic_clear_mask(unsigned long mask, atomic_t *addr)
diff --git a/include/asm-m32r/kdebug.h b/include/asm-m32r/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-m32r/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-m32r/pgtable.h b/include/asm-m32r/pgtable.h
index 1c15ba7..8b2a2f1 100644
--- a/include/asm-m32r/pgtable.h
+++ b/include/asm-m32r/pgtable.h
@@ -381,10 +381,6 @@
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
diff --git a/include/asm-m32r/system.h b/include/asm-m32r/system.h
index 99ee098..06cdece 100644
--- a/include/asm-m32r/system.h
+++ b/include/asm-m32r/system.h
@@ -122,8 +122,6 @@
#define xchg(ptr,x) \
((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
-#define tas(ptr) (xchg((ptr),1))
-
#ifdef CONFIG_SMP
extern void __xchg_called_with_bad_pointer(void);
#endif
diff --git a/include/asm-m68k/atomic.h b/include/asm-m68k/atomic.h
index d5eed64..4915294 100644
--- a/include/asm-m68k/atomic.h
+++ b/include/asm-m68k/atomic.h
@@ -2,7 +2,7 @@
#define __ARCH_M68K_ATOMIC__
-#include <asm/system.h> /* local_irq_XXX() */
+#include <asm/system.h>
/*
* Atomic operations that C can't guarantee us. Useful for
@@ -170,20 +170,21 @@
__asm__ __volatile__("orl %1,%0" : "+m" (*v) : "id" (mask));
}
-#define atomic_add_unless(v, a, u) \
-({ \
- int c, old; \
- c = atomic_read(v); \
- for (;;) { \
- if (unlikely(c == (u))) \
- break; \
- old = atomic_cmpxchg((v), c, c + (a)); \
- if (likely(old == c)) \
- break; \
- c = old; \
- } \
- c != (u); \
-})
+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int c, old;
+ c = atomic_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
/* Atomic operations are already serializing */
diff --git a/include/asm-m68k/kdebug.h b/include/asm-m68k/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-m68k/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-m68k/pgtable.h b/include/asm-m68k/pgtable.h
index f3aa053..555b87a 100644
--- a/include/asm-m68k/pgtable.h
+++ b/include/asm-m68k/pgtable.h
@@ -143,10 +143,6 @@
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
/* MMU-specific headers */
#ifdef CONFIG_SUN3
diff --git a/include/asm-m68k/system.h b/include/asm-m68k/system.h
index 243dd13..198878b 100644
--- a/include/asm-m68k/system.h
+++ b/include/asm-m68k/system.h
@@ -88,7 +88,6 @@
#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
-#define tas(ptr) (xchg((ptr),1))
struct __xchg_dummy { unsigned long a[100]; };
#define __xg(x) ((volatile struct __xchg_dummy *)(x))
diff --git a/include/asm-m68knommu/atomic.h b/include/asm-m68knommu/atomic.h
index 6c4e4b6..d5632a3 100644
--- a/include/asm-m68knommu/atomic.h
+++ b/include/asm-m68knommu/atomic.h
@@ -1,7 +1,7 @@
#ifndef __ARCH_M68KNOMMU_ATOMIC__
#define __ARCH_M68KNOMMU_ATOMIC__
-#include <asm/system.h> /* local_irq_XXX() */
+#include <asm/system.h>
/*
* Atomic operations that C can't guarantee us. Useful for
@@ -131,14 +131,21 @@
#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
-#define atomic_add_unless(v, a, u) \
-({ \
- int c, old; \
- c = atomic_read(v); \
- while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
- c = old; \
- c != (u); \
-})
+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int c, old;
+ c = atomic_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
#define atomic_dec_return(v) atomic_sub_return(1,(v))
diff --git a/include/asm-m68knommu/kdebug.h b/include/asm-m68knommu/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-m68knommu/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-m68knommu/pgtable.h b/include/asm-m68knommu/pgtable.h
index 549ad23..9dfbbc2 100644
--- a/include/asm-m68knommu/pgtable.h
+++ b/include/asm-m68knommu/pgtable.h
@@ -59,10 +59,6 @@
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
/*
* All 32bit addresses are effectively valid for vmalloc...
* Sort of meaningless for non-VM targets.
diff --git a/include/asm-m68knommu/system.h b/include/asm-m68knommu/system.h
index 2a81449..5e5ed18 100644
--- a/include/asm-m68knommu/system.h
+++ b/include/asm-m68knommu/system.h
@@ -120,7 +120,6 @@
#endif
#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
-#define tas(ptr) (xchg((ptr),1))
struct __xchg_dummy { unsigned long a[100]; };
#define __xg(x) ((volatile struct __xchg_dummy *)(x))
diff --git a/include/asm-mips/atomic.h b/include/asm-mips/atomic.h
index 1ac50b6..62daa74 100644
--- a/include/asm-mips/atomic.h
+++ b/include/asm-mips/atomic.h
@@ -18,6 +18,7 @@
#include <asm/barrier.h>
#include <asm/cpu-features.h>
#include <asm/war.h>
+#include <asm/system.h>
typedef struct { volatile int counter; } atomic_t;
@@ -306,8 +307,8 @@
return result;
}
-#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
-#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
+#define atomic_xchg(v, new) (xchg(&((v)->counter), (new)))
/**
* atomic_add_unless - add unless the number is a given value
@@ -318,14 +319,20 @@
* Atomically adds @a to @v, so long as it was not @u.
* Returns non-zero if @v was not @u, and zero otherwise.
*/
-#define atomic_add_unless(v, a, u) \
-({ \
- int c, old; \
- c = atomic_read(v); \
- while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
- c = old; \
- c != (u); \
-})
+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int c, old;
+ c = atomic_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
#define atomic_dec_return(v) atomic_sub_return(1,(v))
@@ -681,6 +688,36 @@
return result;
}
+#define atomic64_cmpxchg(v, o, n) \
+ (((__typeof__((v)->counter)))cmpxchg(&((v)->counter), (o), (n)))
+#define atomic64_xchg(v, new) (xchg(&((v)->counter), (new)))
+
+/**
+ * atomic64_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic64_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
+ */
+static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+{
+ long c, old;
+ c = atomic64_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic64_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
+#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
#define atomic64_dec_return(v) atomic64_sub_return(1,(v))
#define atomic64_inc_return(v) atomic64_add_return(1,(v))
diff --git a/include/asm-mips/kdebug.h b/include/asm-mips/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-mips/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-mips/kexec.h b/include/asm-mips/kexec.h
index b25267e..cdbab43 100644
--- a/include/asm-mips/kexec.h
+++ b/include/asm-mips/kexec.h
@@ -21,8 +21,6 @@
/* The native architecture */
#define KEXEC_ARCH KEXEC_ARCH_MIPS
-#define MAX_NOTE_BYTES 1024
-
static inline void crash_setup_regs(struct pt_regs *newregs,
struct pt_regs *oldregs)
{
diff --git a/include/asm-mips/local.h b/include/asm-mips/local.h
index 9e2d43b..ed882c8 100644
--- a/include/asm-mips/local.h
+++ b/include/asm-mips/local.h
@@ -1,60 +1,288 @@
-#ifndef _ASM_LOCAL_H
-#define _ASM_LOCAL_H
+#ifndef _ARCH_MIPS_LOCAL_H
+#define _ARCH_MIPS_LOCAL_H
#include <linux/percpu.h>
+#include <linux/bitops.h>
#include <asm/atomic.h>
+#include <asm/war.h>
-#ifdef CONFIG_32BIT
+typedef struct
+{
+ atomic_long_t a;
+} local_t;
-typedef atomic_t local_t;
+#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) }
-#define LOCAL_INIT(i) ATOMIC_INIT(i)
-#define local_read(v) atomic_read(v)
-#define local_set(v,i) atomic_set(v,i)
+#define local_read(l) atomic_long_read(&(l)->a)
+#define local_set(l,i) atomic_long_set(&(l)->a, (i))
-#define local_inc(v) atomic_inc(v)
-#define local_dec(v) atomic_dec(v)
-#define local_add(i, v) atomic_add(i, v)
-#define local_sub(i, v) atomic_sub(i, v)
-
-#endif
-
-#ifdef CONFIG_64BIT
-
-typedef atomic64_t local_t;
-
-#define LOCAL_INIT(i) ATOMIC64_INIT(i)
-#define local_read(v) atomic64_read(v)
-#define local_set(v,i) atomic64_set(v,i)
-
-#define local_inc(v) atomic64_inc(v)
-#define local_dec(v) atomic64_dec(v)
-#define local_add(i, v) atomic64_add(i, v)
-#define local_sub(i, v) atomic64_sub(i, v)
-
-#endif
-
-#define __local_inc(v) ((v)->counter++)
-#define __local_dec(v) ((v)->counter--)
-#define __local_add(i,v) ((v)->counter+=(i))
-#define __local_sub(i,v) ((v)->counter-=(i))
+#define local_add(i,l) atomic_long_add((i),(&(l)->a))
+#define local_sub(i,l) atomic_long_sub((i),(&(l)->a))
+#define local_inc(l) atomic_long_inc(&(l)->a)
+#define local_dec(l) atomic_long_dec(&(l)->a)
/*
- * Use these for per-cpu local_t variables: on some archs they are
+ * Same as above, but return the result value
+ */
+static __inline__ long local_add_return(long i, local_t * l)
+{
+ unsigned long result;
+
+ if (cpu_has_llsc && R10000_LLSC_WAR) {
+ unsigned long temp;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1:" __LL "%1, %2 # local_add_return \n"
+ " addu %0, %1, %3 \n"
+ __SC "%0, %2 \n"
+ " beqzl %0, 1b \n"
+ " addu %0, %1, %3 \n"
+ " .set mips0 \n"
+ : "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
+ : "Ir" (i), "m" (l->a.counter)
+ : "memory");
+ } else if (cpu_has_llsc) {
+ unsigned long temp;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1:" __LL "%1, %2 # local_add_return \n"
+ " addu %0, %1, %3 \n"
+ __SC "%0, %2 \n"
+ " beqz %0, 1b \n"
+ " addu %0, %1, %3 \n"
+ " .set mips0 \n"
+ : "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
+ : "Ir" (i), "m" (l->a.counter)
+ : "memory");
+ } else {
+ unsigned long flags;
+
+ local_irq_save(flags);
+ result = l->a.counter;
+ result += i;
+ l->a.counter = result;
+ local_irq_restore(flags);
+ }
+
+ return result;
+}
+
+static __inline__ long local_sub_return(long i, local_t * l)
+{
+ unsigned long result;
+
+ if (cpu_has_llsc && R10000_LLSC_WAR) {
+ unsigned long temp;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1:" __LL "%1, %2 # local_sub_return \n"
+ " subu %0, %1, %3 \n"
+ __SC "%0, %2 \n"
+ " beqzl %0, 1b \n"
+ " subu %0, %1, %3 \n"
+ " .set mips0 \n"
+ : "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
+ : "Ir" (i), "m" (l->a.counter)
+ : "memory");
+ } else if (cpu_has_llsc) {
+ unsigned long temp;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1:" __LL "%1, %2 # local_sub_return \n"
+ " subu %0, %1, %3 \n"
+ __SC "%0, %2 \n"
+ " beqz %0, 1b \n"
+ " subu %0, %1, %3 \n"
+ " .set mips0 \n"
+ : "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
+ : "Ir" (i), "m" (l->a.counter)
+ : "memory");
+ } else {
+ unsigned long flags;
+
+ local_irq_save(flags);
+ result = l->a.counter;
+ result -= i;
+ l->a.counter = result;
+ local_irq_restore(flags);
+ }
+
+ return result;
+}
+
+/*
+ * local_sub_if_positive - conditionally subtract integer from atomic variable
+ * @i: integer value to subtract
+ * @l: pointer of type local_t
+ *
+ * Atomically test @l and subtract @i if @l is greater or equal than @i.
+ * The function returns the old value of @l minus @i.
+ */
+static __inline__ long local_sub_if_positive(long i, local_t * l)
+{
+ unsigned long result;
+
+ if (cpu_has_llsc && R10000_LLSC_WAR) {
+ unsigned long temp;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1:" __LL "%1, %2 # local_sub_if_positive\n"
+ " dsubu %0, %1, %3 \n"
+ " bltz %0, 1f \n"
+ __SC "%0, %2 \n"
+ " .set noreorder \n"
+ " beqzl %0, 1b \n"
+ " dsubu %0, %1, %3 \n"
+ " .set reorder \n"
+ "1: \n"
+ " .set mips0 \n"
+ : "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
+ : "Ir" (i), "m" (l->a.counter)
+ : "memory");
+ } else if (cpu_has_llsc) {
+ unsigned long temp;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1:" __LL "%1, %2 # local_sub_if_positive\n"
+ " dsubu %0, %1, %3 \n"
+ " bltz %0, 1f \n"
+ __SC "%0, %2 \n"
+ " .set noreorder \n"
+ " beqz %0, 1b \n"
+ " dsubu %0, %1, %3 \n"
+ " .set reorder \n"
+ "1: \n"
+ " .set mips0 \n"
+ : "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
+ : "Ir" (i), "m" (l->a.counter)
+ : "memory");
+ } else {
+ unsigned long flags;
+
+ local_irq_save(flags);
+ result = l->a.counter;
+ result -= i;
+ if (result >= 0)
+ l->a.counter = result;
+ local_irq_restore(flags);
+ }
+
+ return result;
+}
+
+#define local_cmpxchg(l, o, n) \
+ ((long)cmpxchg_local(&((l)->a.counter), (o), (n)))
+#define local_xchg(l, n) (xchg_local(&((l)->a.counter),(n)))
+
+/**
+ * local_add_unless - add unless the number is a given value
+ * @l: pointer of type local_t
+ * @a: the amount to add to l...
+ * @u: ...unless l is equal to u.
+ *
+ * Atomically adds @a to @l, so long as it was not @u.
+ * Returns non-zero if @l was not @u, and zero otherwise.
+ */
+#define local_add_unless(l, a, u) \
+({ \
+ long c, old; \
+ c = local_read(l); \
+ while (c != (u) && (old = local_cmpxchg((l), c, c + (a))) != c) \
+ c = old; \
+ c != (u); \
+})
+#define local_inc_not_zero(l) local_add_unless((l), 1, 0)
+
+#define local_dec_return(l) local_sub_return(1,(l))
+#define local_inc_return(l) local_add_return(1,(l))
+
+/*
+ * local_sub_and_test - subtract value from variable and test result
+ * @i: integer value to subtract
+ * @l: pointer of type local_t
+ *
+ * Atomically subtracts @i from @l and returns
+ * true if the result is zero, or false for all
+ * other cases.
+ */
+#define local_sub_and_test(i,l) (local_sub_return((i), (l)) == 0)
+
+/*
+ * local_inc_and_test - increment and test
+ * @l: pointer of type local_t
+ *
+ * Atomically increments @l by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+#define local_inc_and_test(l) (local_inc_return(l) == 0)
+
+/*
+ * local_dec_and_test - decrement by 1 and test
+ * @l: pointer of type local_t
+ *
+ * Atomically decrements @l by 1 and
+ * returns true if the result is 0, or false for all other
+ * cases.
+ */
+#define local_dec_and_test(l) (local_sub_return(1, (l)) == 0)
+
+/*
+ * local_dec_if_positive - decrement by 1 if old value positive
+ * @l: pointer of type local_t
+ */
+#define local_dec_if_positive(l) local_sub_if_positive(1, l)
+
+/*
+ * local_add_negative - add and test if negative
+ * @l: pointer of type local_t
+ * @i: integer value to add
+ *
+ * Atomically adds @i to @l and returns true
+ * if the result is negative, or false when
+ * result is greater than or equal to zero.
+ */
+#define local_add_negative(i,l) (local_add_return(i, (l)) < 0)
+
+/* Use these for per-cpu local_t variables: on some archs they are
* much more efficient than these naive implementations. Note they take
* a variable, not an address.
*/
-#define cpu_local_read(v) local_read(&__get_cpu_var(v))
-#define cpu_local_set(v, i) local_set(&__get_cpu_var(v), (i))
-#define cpu_local_inc(v) local_inc(&__get_cpu_var(v))
-#define cpu_local_dec(v) local_dec(&__get_cpu_var(v))
-#define cpu_local_add(i, v) local_add((i), &__get_cpu_var(v))
-#define cpu_local_sub(i, v) local_sub((i), &__get_cpu_var(v))
+#define __local_inc(l) ((l)->a.counter++)
+#define __local_dec(l) ((l)->a.counter++)
+#define __local_add(i,l) ((l)->a.counter+=(i))
+#define __local_sub(i,l) ((l)->a.counter-=(i))
-#define __cpu_local_inc(v) __local_inc(&__get_cpu_var(v))
-#define __cpu_local_dec(v) __local_dec(&__get_cpu_var(v))
-#define __cpu_local_add(i, v) __local_add((i), &__get_cpu_var(v))
-#define __cpu_local_sub(i, v) __local_sub((i), &__get_cpu_var(v))
+/* Need to disable preemption for the cpu local counters otherwise we could
+ still access a variable of a previous CPU in a non atomic way. */
+#define cpu_local_wrap_v(l) \
+ ({ local_t res__; \
+ preempt_disable(); \
+ res__ = (l); \
+ preempt_enable(); \
+ res__; })
+#define cpu_local_wrap(l) \
+ ({ preempt_disable(); \
+ l; \
+ preempt_enable(); }) \
-#endif /* _ASM_LOCAL_H */
+#define cpu_local_read(l) cpu_local_wrap_v(local_read(&__get_cpu_var(l)))
+#define cpu_local_set(l, i) cpu_local_wrap(local_set(&__get_cpu_var(l), (i)))
+#define cpu_local_inc(l) cpu_local_wrap(local_inc(&__get_cpu_var(l)))
+#define cpu_local_dec(l) cpu_local_wrap(local_dec(&__get_cpu_var(l)))
+#define cpu_local_add(i, l) cpu_local_wrap(local_add((i), &__get_cpu_var(l)))
+#define cpu_local_sub(i, l) cpu_local_wrap(local_sub((i), &__get_cpu_var(l)))
+
+#define __cpu_local_inc(l) cpu_local_inc(l)
+#define __cpu_local_dec(l) cpu_local_dec(l)
+#define __cpu_local_add(i, l) cpu_local_add((i), (l))
+#define __cpu_local_sub(i, l) cpu_local_sub((i), (l))
+
+#endif /* _ARCH_MIPS_LOCAL_H */
diff --git a/include/asm-mips/mach-au1x00/au1550_spi.h b/include/asm-mips/mach-au1x00/au1550_spi.h
new file mode 100644
index 0000000..c2f0466
--- /dev/null
+++ b/include/asm-mips/mach-au1x00/au1550_spi.h
@@ -0,0 +1,16 @@
+/*
+ * au1550_spi.h - au1550 psc spi controller driver - platform data struct
+ */
+
+#ifndef _AU1550_SPI_H_
+#define _AU1550_SPI_H_
+
+struct au1550_spi_info {
+ s16 bus_num; /* defines which PSC and IRQ to use */
+ u32 mainclk_hz; /* main input clock frequency of PSC */
+ u16 num_chipselect; /* number of chipselects supported */
+ void (*activate_cs)(struct au1550_spi_info *spi, int cs, int polarity);
+ void (*deactivate_cs)(struct au1550_spi_info *spi, int cs, int polarity);
+};
+
+#endif
diff --git a/include/asm-mips/pgtable.h b/include/asm-mips/pgtable.h
index 0d3295f..27d77d9 100644
--- a/include/asm-mips/pgtable.h
+++ b/include/asm-mips/pgtable.h
@@ -387,10 +387,6 @@
remap_pfn_range(vma, vaddr, pfn, size, prot)
#endif
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
#include <asm-generic/pgtable.h>
/*
diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h
index 2908870..30f23a2 100644
--- a/include/asm-mips/system.h
+++ b/include/asm-mips/system.h
@@ -201,7 +201,6 @@
}
#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
-#define tas(ptr) (xchg((ptr),1))
#define __HAVE_ARCH_CMPXCHG 1
@@ -262,6 +261,58 @@
return retval;
}
+static inline unsigned long __cmpxchg_u32_local(volatile int * m,
+ unsigned long old, unsigned long new)
+{
+ __u32 retval;
+
+ if (cpu_has_llsc && R10000_LLSC_WAR) {
+ __asm__ __volatile__(
+ " .set push \n"
+ " .set noat \n"
+ " .set mips3 \n"
+ "1: ll %0, %2 # __cmpxchg_u32 \n"
+ " bne %0, %z3, 2f \n"
+ " .set mips0 \n"
+ " move $1, %z4 \n"
+ " .set mips3 \n"
+ " sc $1, %1 \n"
+ " beqzl $1, 1b \n"
+ "2: \n"
+ " .set pop \n"
+ : "=&r" (retval), "=R" (*m)
+ : "R" (*m), "Jr" (old), "Jr" (new)
+ : "memory");
+ } else if (cpu_has_llsc) {
+ __asm__ __volatile__(
+ " .set push \n"
+ " .set noat \n"
+ " .set mips3 \n"
+ "1: ll %0, %2 # __cmpxchg_u32 \n"
+ " bne %0, %z3, 2f \n"
+ " .set mips0 \n"
+ " move $1, %z4 \n"
+ " .set mips3 \n"
+ " sc $1, %1 \n"
+ " beqz $1, 1b \n"
+ "2: \n"
+ " .set pop \n"
+ : "=&r" (retval), "=R" (*m)
+ : "R" (*m), "Jr" (old), "Jr" (new)
+ : "memory");
+ } else {
+ unsigned long flags;
+
+ local_irq_save(flags);
+ retval = *m;
+ if (retval == old)
+ *m = new;
+ local_irq_restore(flags); /* implies memory barrier */
+ }
+
+ return retval;
+}
+
#ifdef CONFIG_64BIT
static inline unsigned long __cmpxchg_u64(volatile int * m, unsigned long old,
unsigned long new)
@@ -315,10 +366,62 @@
return retval;
}
+
+static inline unsigned long __cmpxchg_u64_local(volatile int * m,
+ unsigned long old, unsigned long new)
+{
+ __u64 retval;
+
+ if (cpu_has_llsc && R10000_LLSC_WAR) {
+ __asm__ __volatile__(
+ " .set push \n"
+ " .set noat \n"
+ " .set mips3 \n"
+ "1: lld %0, %2 # __cmpxchg_u64 \n"
+ " bne %0, %z3, 2f \n"
+ " move $1, %z4 \n"
+ " scd $1, %1 \n"
+ " beqzl $1, 1b \n"
+ "2: \n"
+ " .set pop \n"
+ : "=&r" (retval), "=R" (*m)
+ : "R" (*m), "Jr" (old), "Jr" (new)
+ : "memory");
+ } else if (cpu_has_llsc) {
+ __asm__ __volatile__(
+ " .set push \n"
+ " .set noat \n"
+ " .set mips3 \n"
+ "1: lld %0, %2 # __cmpxchg_u64 \n"
+ " bne %0, %z3, 2f \n"
+ " move $1, %z4 \n"
+ " scd $1, %1 \n"
+ " beqz $1, 1b \n"
+ "2: \n"
+ " .set pop \n"
+ : "=&r" (retval), "=R" (*m)
+ : "R" (*m), "Jr" (old), "Jr" (new)
+ : "memory");
+ } else {
+ unsigned long flags;
+
+ local_irq_save(flags);
+ retval = *m;
+ if (retval == old)
+ *m = new;
+ local_irq_restore(flags); /* implies memory barrier */
+ }
+
+ return retval;
+}
+
#else
extern unsigned long __cmpxchg_u64_unsupported_on_32bit_kernels(
volatile int * m, unsigned long old, unsigned long new);
#define __cmpxchg_u64 __cmpxchg_u64_unsupported_on_32bit_kernels
+extern unsigned long __cmpxchg_u64_local_unsupported_on_32bit_kernels(
+ volatile int * m, unsigned long old, unsigned long new);
+#define __cmpxchg_u64_local __cmpxchg_u64_local_unsupported_on_32bit_kernels
#endif
/* This function doesn't exist, so you'll get a linker error
@@ -338,7 +441,26 @@
return old;
}
-#define cmpxchg(ptr,old,new) ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(old), (unsigned long)(new),sizeof(*(ptr))))
+static inline unsigned long __cmpxchg_local(volatile void * ptr,
+ unsigned long old, unsigned long new, int size)
+{
+ switch (size) {
+ case 4:
+ return __cmpxchg_u32_local(ptr, old, new);
+ case 8:
+ return __cmpxchg_u64_local(ptr, old, new);
+ }
+ __cmpxchg_called_with_bad_pointer();
+ return old;
+}
+
+#define cmpxchg(ptr,old,new) \
+ ((__typeof__(*(ptr)))__cmpxchg((ptr), \
+ (unsigned long)(old), (unsigned long)(new),sizeof(*(ptr))))
+
+#define cmpxchg_local(ptr,old,new) \
+ ((__typeof__(*(ptr)))__cmpxchg_local((ptr), \
+ (unsigned long)(old), (unsigned long)(new),sizeof(*(ptr))))
extern void set_handler (unsigned long offset, void *addr, unsigned long len);
extern void set_uncached_handler (unsigned long offset, void *addr, unsigned long len);
diff --git a/include/asm-parisc/atomic.h b/include/asm-parisc/atomic.h
index 7d57d34..e894ee3 100644
--- a/include/asm-parisc/atomic.h
+++ b/include/asm-parisc/atomic.h
@@ -163,7 +163,7 @@
}
/* exported interface */
-#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
/**
@@ -175,14 +175,21 @@
* Atomically adds @a to @v, so long as it was not @u.
* Returns non-zero if @v was not @u, and zero otherwise.
*/
-#define atomic_add_unless(v, a, u) \
-({ \
- int c, old; \
- c = atomic_read(v); \
- while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
- c = old; \
- c != (u); \
-})
+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int c, old;
+ c = atomic_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
#define atomic_add(i,v) ((void)(__atomic_add_return( ((int)i),(v))))
@@ -270,6 +277,37 @@
#define atomic64_dec_and_test(v) (atomic64_dec_return(v) == 0)
#define atomic64_sub_and_test(i,v) (atomic64_sub_return((i),(v)) == 0)
+/* exported interface */
+#define atomic64_cmpxchg(v, o, n) \
+ ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
+#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
+
+/**
+ * atomic64_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic64_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
+ */
+static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+{
+ long c, old;
+ c = atomic64_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic64_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
+#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
#endif /* CONFIG_64BIT */
#include <asm-generic/atomic.h>
diff --git a/include/asm-parisc/kdebug.h b/include/asm-parisc/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-parisc/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-parisc/local.h b/include/asm-parisc/local.h
index d0f5509..c11c530 100644
--- a/include/asm-parisc/local.h
+++ b/include/asm-parisc/local.h
@@ -1,40 +1 @@
-#ifndef _ARCH_PARISC_LOCAL_H
-#define _ARCH_PARISC_LOCAL_H
-
-#include <linux/percpu.h>
-#include <asm/atomic.h>
-
-typedef atomic_long_t local_t;
-
-#define LOCAL_INIT(i) ATOMIC_LONG_INIT(i)
-#define local_read(v) atomic_long_read(v)
-#define local_set(v,i) atomic_long_set(v,i)
-
-#define local_inc(v) atomic_long_inc(v)
-#define local_dec(v) atomic_long_dec(v)
-#define local_add(i, v) atomic_long_add(i, v)
-#define local_sub(i, v) atomic_long_sub(i, v)
-
-#define __local_inc(v) ((v)->counter++)
-#define __local_dec(v) ((v)->counter--)
-#define __local_add(i,v) ((v)->counter+=(i))
-#define __local_sub(i,v) ((v)->counter-=(i))
-
-/* Use these for per-cpu local_t variables: on some archs they are
- * much more efficient than these naive implementations. Note they take
- * a variable, not an address.
- */
-#define cpu_local_read(v) local_read(&__get_cpu_var(v))
-#define cpu_local_set(v, i) local_set(&__get_cpu_var(v), (i))
-
-#define cpu_local_inc(v) local_inc(&__get_cpu_var(v))
-#define cpu_local_dec(v) local_dec(&__get_cpu_var(v))
-#define cpu_local_add(i, v) local_add((i), &__get_cpu_var(v))
-#define cpu_local_sub(i, v) local_sub((i), &__get_cpu_var(v))
-
-#define __cpu_local_inc(v) __local_inc(&__get_cpu_var(v))
-#define __cpu_local_dec(v) __local_dec(&__get_cpu_var(v))
-#define __cpu_local_add(i, v) __local_add((i), &__get_cpu_var(v))
-#define __cpu_local_sub(i, v) __local_sub((i), &__get_cpu_var(v))
-
-#endif /* _ARCH_PARISC_LOCAL_H */
+#include <asm-generic/local.h>
diff --git a/include/asm-parisc/pgtable.h b/include/asm-parisc/pgtable.h
index d7e1b10..beb2adb 100644
--- a/include/asm-parisc/pgtable.h
+++ b/include/asm-parisc/pgtable.h
@@ -528,10 +528,6 @@
#define pgprot_noncached(prot) __pgprot(pgprot_val(prot) | _PAGE_NO_CACHE)
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
/* We provide our own get_unmapped_area to provide cache coherency */
#define HAVE_ARCH_UNMAPPED_AREA
diff --git a/include/asm-powerpc/atomic.h b/include/asm-powerpc/atomic.h
index 2ce4b6b..c44810b 100644
--- a/include/asm-powerpc/atomic.h
+++ b/include/asm-powerpc/atomic.h
@@ -11,6 +11,7 @@
#include <linux/compiler.h>
#include <asm/synch.h>
#include <asm/asm-compat.h>
+#include <asm/system.h>
#define ATOMIC_INIT(i) { (i) }
@@ -165,8 +166,7 @@
return t;
}
-#define atomic_cmpxchg(v, o, n) \
- ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
+#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
/**
@@ -414,8 +414,7 @@
return t;
}
-#define atomic64_cmpxchg(v, o, n) \
- ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
+#define atomic64_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
/**
diff --git a/include/asm-powerpc/bitops.h b/include/asm-powerpc/bitops.h
index 8f757f6..8144a27 100644
--- a/include/asm-powerpc/bitops.h
+++ b/include/asm-powerpc/bitops.h
@@ -39,7 +39,6 @@
#ifdef __KERNEL__
#include <linux/compiler.h>
-#include <asm/atomic.h>
#include <asm/asm-compat.h>
#include <asm/synch.h>
diff --git a/include/asm-powerpc/iommu.h b/include/asm-powerpc/iommu.h
index b2e56b3..870967e 100644
--- a/include/asm-powerpc/iommu.h
+++ b/include/asm-powerpc/iommu.h
@@ -26,6 +26,7 @@
#include <linux/spinlock.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
+#include <asm/machdep.h>
#include <asm/types.h>
#include <asm/bitops.h>
@@ -109,6 +110,19 @@
#endif
extern void alloc_dart_table(void);
+#if defined(CONFIG_PPC64) && defined(CONFIG_PM)
+static inline void iommu_save(void)
+{
+ if (ppc_md.iommu_save)
+ ppc_md.iommu_save();
+}
+
+static inline void iommu_restore(void)
+{
+ if (ppc_md.iommu_restore)
+ ppc_md.iommu_restore();
+}
+#endif
#endif /* __KERNEL__ */
#endif /* _ASM_IOMMU_H */
diff --git a/include/asm-powerpc/kdebug.h b/include/asm-powerpc/kdebug.h
index 532bfee..295f016 100644
--- a/include/asm-powerpc/kdebug.h
+++ b/include/asm-powerpc/kdebug.h
@@ -6,20 +6,19 @@
#include <linux/notifier.h>
-struct pt_regs;
-
-struct die_args {
- struct pt_regs *regs;
- const char *str;
- long err;
- int trapnr;
- int signr;
-};
-
-extern int register_die_notifier(struct notifier_block *);
-extern int unregister_die_notifier(struct notifier_block *);
-extern int register_page_fault_notifier(struct notifier_block *);
-extern int unregister_page_fault_notifier(struct notifier_block *);
+/*
+ * These are only here because kprobes.c wants them to implement a
+ * blatant layering violation. Will hopefully go away soon once all
+ * architectures are updated.
+ */
+static inline int register_page_fault_notifier(struct notifier_block *nb)
+{
+ return 0;
+}
+static inline int unregister_page_fault_notifier(struct notifier_block *nb)
+{
+ return 0;
+}
extern struct atomic_notifier_head powerpc_die_chain;
/* Grossly misnamed. */
@@ -29,14 +28,7 @@
DIE_DABR_MATCH,
DIE_BPT,
DIE_SSTEP,
- DIE_PAGE_FAULT,
};
-static inline int notify_die(enum die_val val,char *str,struct pt_regs *regs,long err,int trap, int sig)
-{
- struct die_args args = { .regs=regs, .str=str, .err=err, .trapnr=trap,.signr=sig };
- return atomic_notifier_call_chain(&powerpc_die_chain, val, &args);
-}
-
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_KDEBUG_H */
diff --git a/include/asm-powerpc/kexec.h b/include/asm-powerpc/kexec.h
index 11cbdf8..b6f817b 100644
--- a/include/asm-powerpc/kexec.h
+++ b/include/asm-powerpc/kexec.h
@@ -108,8 +108,6 @@
struct pt_regs *oldregs) { }
#endif /* !__powerpc64 __ */
-#define MAX_NOTE_BYTES 1024
-
extern void kexec_smp_wait(void); /* get and clear naca physid, wait for
master to copy new code to 0 */
extern int crashing_cpu;
diff --git a/include/asm-powerpc/kprobes.h b/include/asm-powerpc/kprobes.h
index f850ca7..b0e40ff 100644
--- a/include/asm-powerpc/kprobes.h
+++ b/include/asm-powerpc/kprobes.h
@@ -64,6 +64,12 @@
addr = *(kprobe_opcode_t **)addr; \
} else if (name[0] != '.') \
addr = *(kprobe_opcode_t **)addr; \
+ } else { \
+ char dot_name[KSYM_NAME_LEN+1]; \
+ dot_name[0] = '.'; \
+ dot_name[1] = '\0'; \
+ strncat(dot_name, name, KSYM_NAME_LEN); \
+ addr = (kprobe_opcode_t *)kallsyms_lookup_name(dot_name); \
} \
}
@@ -110,5 +116,6 @@
extern int kprobe_exceptions_notify(struct notifier_block *self,
unsigned long val, void *data);
+extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_KPROBES_H */
diff --git a/include/asm-powerpc/local.h b/include/asm-powerpc/local.h
index c11c530..612d832 100644
--- a/include/asm-powerpc/local.h
+++ b/include/asm-powerpc/local.h
@@ -1 +1,200 @@
-#include <asm-generic/local.h>
+#ifndef _ARCH_POWERPC_LOCAL_H
+#define _ARCH_POWERPC_LOCAL_H
+
+#include <linux/percpu.h>
+#include <asm/atomic.h>
+
+typedef struct
+{
+ atomic_long_t a;
+} local_t;
+
+#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) }
+
+#define local_read(l) atomic_long_read(&(l)->a)
+#define local_set(l,i) atomic_long_set(&(l)->a, (i))
+
+#define local_add(i,l) atomic_long_add((i),(&(l)->a))
+#define local_sub(i,l) atomic_long_sub((i),(&(l)->a))
+#define local_inc(l) atomic_long_inc(&(l)->a)
+#define local_dec(l) atomic_long_dec(&(l)->a)
+
+static __inline__ long local_add_return(long a, local_t *l)
+{
+ long t;
+
+ __asm__ __volatile__(
+"1:" PPC_LLARX "%0,0,%2 # local_add_return\n\
+ add %0,%1,%0\n"
+ PPC405_ERR77(0,%2)
+ PPC_STLCX "%0,0,%2 \n\
+ bne- 1b"
+ : "=&r" (t)
+ : "r" (a), "r" (&(l->a.counter))
+ : "cc", "memory");
+
+ return t;
+}
+
+#define local_add_negative(a, l) (local_add_return((a), (l)) < 0)
+
+static __inline__ long local_sub_return(long a, local_t *l)
+{
+ long t;
+
+ __asm__ __volatile__(
+"1:" PPC_LLARX "%0,0,%2 # local_sub_return\n\
+ subf %0,%1,%0\n"
+ PPC405_ERR77(0,%2)
+ PPC_STLCX "%0,0,%2 \n\
+ bne- 1b"
+ : "=&r" (t)
+ : "r" (a), "r" (&(l->a.counter))
+ : "cc", "memory");
+
+ return t;
+}
+
+static __inline__ long local_inc_return(local_t *l)
+{
+ long t;
+
+ __asm__ __volatile__(
+"1:" PPC_LLARX "%0,0,%1 # local_inc_return\n\
+ addic %0,%0,1\n"
+ PPC405_ERR77(0,%1)
+ PPC_STLCX "%0,0,%1 \n\
+ bne- 1b"
+ : "=&r" (t)
+ : "r" (&(l->a.counter))
+ : "cc", "memory");
+
+ return t;
+}
+
+/*
+ * local_inc_and_test - increment and test
+ * @l: pointer of type local_t
+ *
+ * Atomically increments @l by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+#define local_inc_and_test(l) (local_inc_return(l) == 0)
+
+static __inline__ long local_dec_return(local_t *l)
+{
+ long t;
+
+ __asm__ __volatile__(
+"1:" PPC_LLARX "%0,0,%1 # local_dec_return\n\
+ addic %0,%0,-1\n"
+ PPC405_ERR77(0,%1)
+ PPC_STLCX "%0,0,%1\n\
+ bne- 1b"
+ : "=&r" (t)
+ : "r" (&(l->a.counter))
+ : "cc", "memory");
+
+ return t;
+}
+
+#define local_cmpxchg(l, o, n) \
+ (cmpxchg_local(&((l)->a.counter), (o), (n)))
+#define local_xchg(l, n) (xchg_local(&((l)->a.counter), (n)))
+
+/**
+ * local_add_unless - add unless the number is a given value
+ * @l: pointer of type local_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @l, so long as it was not @u.
+ * Returns non-zero if @l was not @u, and zero otherwise.
+ */
+static __inline__ int local_add_unless(local_t *l, long a, long u)
+{
+ long t;
+
+ __asm__ __volatile__ (
+"1:" PPC_LLARX "%0,0,%1 # local_add_unless\n\
+ cmpw 0,%0,%3 \n\
+ beq- 2f \n\
+ add %0,%2,%0 \n"
+ PPC405_ERR77(0,%2)
+ PPC_STLCX "%0,0,%1 \n\
+ bne- 1b \n"
+" subf %0,%2,%0 \n\
+2:"
+ : "=&r" (t)
+ : "r" (&(l->a.counter)), "r" (a), "r" (u)
+ : "cc", "memory");
+
+ return t != u;
+}
+
+#define local_inc_not_zero(l) local_add_unless((l), 1, 0)
+
+#define local_sub_and_test(a, l) (local_sub_return((a), (l)) == 0)
+#define local_dec_and_test(l) (local_dec_return((l)) == 0)
+
+/*
+ * Atomically test *l and decrement if it is greater than 0.
+ * The function returns the old value of *l minus 1.
+ */
+static __inline__ long local_dec_if_positive(local_t *l)
+{
+ long t;
+
+ __asm__ __volatile__(
+"1:" PPC_LLARX "%0,0,%1 # local_dec_if_positive\n\
+ cmpwi %0,1\n\
+ addi %0,%0,-1\n\
+ blt- 2f\n"
+ PPC405_ERR77(0,%1)
+ PPC_STLCX "%0,0,%1\n\
+ bne- 1b"
+ "\n\
+2:" : "=&b" (t)
+ : "r" (&(l->a.counter))
+ : "cc", "memory");
+
+ return t;
+}
+
+/* Use these for per-cpu local_t variables: on some archs they are
+ * much more efficient than these naive implementations. Note they take
+ * a variable, not an address.
+ */
+
+#define __local_inc(l) ((l)->a.counter++)
+#define __local_dec(l) ((l)->a.counter++)
+#define __local_add(i,l) ((l)->a.counter+=(i))
+#define __local_sub(i,l) ((l)->a.counter-=(i))
+
+/* Need to disable preemption for the cpu local counters otherwise we could
+ still access a variable of a previous CPU in a non atomic way. */
+#define cpu_local_wrap_v(l) \
+ ({ local_t res__; \
+ preempt_disable(); \
+ res__ = (l); \
+ preempt_enable(); \
+ res__; })
+#define cpu_local_wrap(l) \
+ ({ preempt_disable(); \
+ l; \
+ preempt_enable(); }) \
+
+#define cpu_local_read(l) cpu_local_wrap_v(local_read(&__get_cpu_var(l)))
+#define cpu_local_set(l, i) cpu_local_wrap(local_set(&__get_cpu_var(l), (i)))
+#define cpu_local_inc(l) cpu_local_wrap(local_inc(&__get_cpu_var(l)))
+#define cpu_local_dec(l) cpu_local_wrap(local_dec(&__get_cpu_var(l)))
+#define cpu_local_add(i, l) cpu_local_wrap(local_add((i), &__get_cpu_var(l)))
+#define cpu_local_sub(i, l) cpu_local_wrap(local_sub((i), &__get_cpu_var(l)))
+
+#define __cpu_local_inc(l) cpu_local_inc(l)
+#define __cpu_local_dec(l) cpu_local_dec(l)
+#define __cpu_local_add(i, l) cpu_local_add((i), (l))
+#define __cpu_local_sub(i, l) cpu_local_sub((i), (l))
+
+#endif /* _ARCH_POWERPC_LOCAL_H */
diff --git a/include/asm-powerpc/machdep.h b/include/asm-powerpc/machdep.h
index b204926..6cf1a83 100644
--- a/include/asm-powerpc/machdep.h
+++ b/include/asm-powerpc/machdep.h
@@ -91,6 +91,11 @@
void __iomem * (*ioremap)(phys_addr_t addr, unsigned long size,
unsigned long flags);
void (*iounmap)(volatile void __iomem *token);
+
+#ifdef CONFIG_PM
+ void (*iommu_save)(void);
+ void (*iommu_restore)(void);
+#endif
#endif /* CONFIG_PPC64 */
int (*probe)(void);
@@ -115,6 +120,14 @@
/* To setup PHBs when using automatic OF platform driver for PCI */
int (*pci_setup_phb)(struct pci_controller *host);
+#ifdef CONFIG_PCI_MSI
+ int (*msi_check_device)(struct pci_dev* dev,
+ int nvec, int type);
+ int (*setup_msi_irqs)(struct pci_dev *dev,
+ int nvec, int type);
+ void (*teardown_msi_irqs)(struct pci_dev *dev);
+#endif
+
void (*restart)(char *cmd);
void (*power_off)(void);
void (*halt)(void);
@@ -240,14 +253,10 @@
*/
void (*machine_kexec)(struct kimage *image);
#endif /* CONFIG_KEXEC */
-
-#ifdef CONFIG_PCI_MSI
- int (*enable_msi)(struct pci_dev *pdev);
- void (*disable_msi)(struct pci_dev *pdev);
-#endif /* CONFIG_PCI_MSI */
};
extern void power4_idle(void);
+extern void power4_cpu_offline_powersave(void);
extern void ppc6xx_idle(void);
/*
diff --git a/include/asm-powerpc/mmu-44x.h b/include/asm-powerpc/mmu-44x.h
new file mode 100644
index 0000000..d5ce7a8
--- /dev/null
+++ b/include/asm-powerpc/mmu-44x.h
@@ -0,0 +1,78 @@
+#ifndef _ASM_POWERPC_MMU_44X_H_
+#define _ASM_POWERPC_MMU_44X_H_
+/*
+ * PPC440 support
+ */
+
+#define PPC44x_MMUCR_TID 0x000000ff
+#define PPC44x_MMUCR_STS 0x00010000
+
+#define PPC44x_TLB_PAGEID 0
+#define PPC44x_TLB_XLAT 1
+#define PPC44x_TLB_ATTRIB 2
+
+/* Page identification fields */
+#define PPC44x_TLB_EPN_MASK 0xfffffc00 /* Effective Page Number */
+#define PPC44x_TLB_VALID 0x00000200 /* Valid flag */
+#define PPC44x_TLB_TS 0x00000100 /* Translation address space */
+#define PPC44x_TLB_1K 0x00000000 /* Page sizes */
+#define PPC44x_TLB_4K 0x00000010
+#define PPC44x_TLB_16K 0x00000020
+#define PPC44x_TLB_64K 0x00000030
+#define PPC44x_TLB_256K 0x00000040
+#define PPC44x_TLB_1M 0x00000050
+#define PPC44x_TLB_16M 0x00000070
+#define PPC44x_TLB_256M 0x00000090
+
+/* Translation fields */
+#define PPC44x_TLB_RPN_MASK 0xfffffc00 /* Real Page Number */
+#define PPC44x_TLB_ERPN_MASK 0x0000000f
+
+/* Storage attribute and access control fields */
+#define PPC44x_TLB_ATTR_MASK 0x0000ff80
+#define PPC44x_TLB_U0 0x00008000 /* User 0 */
+#define PPC44x_TLB_U1 0x00004000 /* User 1 */
+#define PPC44x_TLB_U2 0x00002000 /* User 2 */
+#define PPC44x_TLB_U3 0x00001000 /* User 3 */
+#define PPC44x_TLB_W 0x00000800 /* Caching is write-through */
+#define PPC44x_TLB_I 0x00000400 /* Caching is inhibited */
+#define PPC44x_TLB_M 0x00000200 /* Memory is coherent */
+#define PPC44x_TLB_G 0x00000100 /* Memory is guarded */
+#define PPC44x_TLB_E 0x00000080 /* Memory is guarded */
+
+#define PPC44x_TLB_PERM_MASK 0x0000003f
+#define PPC44x_TLB_UX 0x00000020 /* User execution */
+#define PPC44x_TLB_UW 0x00000010 /* User write */
+#define PPC44x_TLB_UR 0x00000008 /* User read */
+#define PPC44x_TLB_SX 0x00000004 /* Super execution */
+#define PPC44x_TLB_SW 0x00000002 /* Super write */
+#define PPC44x_TLB_SR 0x00000001 /* Super read */
+
+/* Number of TLB entries */
+#define PPC44x_TLB_SIZE 64
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned long long phys_addr_t;
+
+extern phys_addr_t fixup_bigphys_addr(phys_addr_t, phys_addr_t);
+
+typedef struct {
+ unsigned long id;
+ unsigned long vdso_base;
+} mm_context_t;
+
+#endif /* !__ASSEMBLY__ */
+
+#ifndef CONFIG_PPC_EARLY_DEBUG_44x
+#define PPC44x_EARLY_TLBS 1
+#else
+#define PPC44x_EARLY_TLBS 2
+#define PPC44x_EARLY_DEBUG_VIRTADDR (ASM_CONST(0xf0000000) \
+ | (ASM_CONST(CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW) & 0xffff))
+#endif
+
+/* Size of the TLBs used for pinning in lowmem */
+#define PPC_PIN_SIZE (1 << 28) /* 256M */
+
+#endif /* _ASM_POWERPC_MMU_44X_H_ */
diff --git a/include/asm-powerpc/mmu.h b/include/asm-powerpc/mmu.h
index 06b3e6d..fe510ff 100644
--- a/include/asm-powerpc/mmu.h
+++ b/include/asm-powerpc/mmu.h
@@ -5,9 +5,12 @@
#ifdef CONFIG_PPC64
/* 64-bit classic hash table MMU */
# include <asm/mmu-hash64.h>
+#elif defined(CONFIG_44x)
+/* 44x-style software loaded TLB */
+# include <asm/mmu-44x.h>
#else
-/* 32-bit. FIXME: split up the 32-bit MMU types, and revise for
- * arch/powerpc */
+/* Other 32-bit. FIXME: split up the other 32-bit MMU types, and
+ * revise for arch/powerpc */
# include <asm-ppc/mmu.h>
#endif
diff --git a/include/asm-powerpc/mpc52xx.h b/include/asm-powerpc/mpc52xx.h
index 7afd5bf..c4631f6 100644
--- a/include/asm-powerpc/mpc52xx.h
+++ b/include/asm-powerpc/mpc52xx.h
@@ -253,5 +253,16 @@
#endif /* __ASSEMBLY__ */
+#ifdef CONFIG_PM
+struct mpc52xx_suspend {
+ void (*board_suspend_prepare)(void __iomem *mbar);
+ void (*board_resume_finish)(void __iomem *mbar);
+};
+
+extern struct mpc52xx_suspend mpc52xx_suspend;
+extern int __init mpc52xx_pm_init(void);
+extern int mpc52xx_set_wakeup_gpio(u8 pin, u8 level);
+#endif /* CONFIG_PM */
+
#endif /* __ASM_POWERPC_MPC52xx_H__ */
diff --git a/include/asm-powerpc/mpic.h b/include/asm-powerpc/mpic.h
index e4d5fc5..2ffb06a 100644
--- a/include/asm-powerpc/mpic.h
+++ b/include/asm-powerpc/mpic.h
@@ -3,6 +3,7 @@
#ifdef __KERNEL__
#include <linux/irq.h>
+#include <linux/sysdev.h>
#include <asm/dcr.h>
/*
@@ -228,6 +229,14 @@
#endif /* CONFIG_PPC_DCR */
};
+struct mpic_irq_save {
+ u32 vecprio,
+ dest;
+#ifdef CONFIG_MPIC_U3_HT_IRQS
+ u32 fixup_data;
+#endif
+};
+
/* The instance data of a given MPIC */
struct mpic
{
@@ -292,8 +301,19 @@
u32 *hw_set;
#endif
+#ifdef CONFIG_PCI_MSI
+ spinlock_t bitmap_lock;
+ unsigned long *hwirq_bitmap;
+#endif
+
/* link */
struct mpic *next;
+
+ struct sys_device sysdev;
+
+#ifdef CONFIG_PM
+ struct mpic_irq_save *save_data;
+#endif
};
/*
diff --git a/include/asm-powerpc/of_device.h b/include/asm-powerpc/of_device.h
index 4f1aabe..e9af49e 100644
--- a/include/asm-powerpc/of_device.h
+++ b/include/asm-powerpc/of_device.h
@@ -32,6 +32,8 @@
extern void of_device_unregister(struct of_device *ofdev);
extern void of_release_dev(struct device *dev);
+extern ssize_t of_device_get_modalias(struct of_device *ofdev,
+ char *str, ssize_t len);
extern int of_device_uevent(struct device *dev,
char **envp, int num_envp, char *buffer, int buffer_size);
diff --git a/include/asm-powerpc/page.h b/include/asm-powerpc/page.h
index b4d38b0..10c51f4 100644
--- a/include/asm-powerpc/page.h
+++ b/include/asm-powerpc/page.h
@@ -121,6 +121,7 @@
#endif
/* PMD level */
+#ifdef CONFIG_PPC64
typedef struct { unsigned long pmd; } pmd_t;
#define pmd_val(x) ((x).pmd)
#define __pmd(x) ((pmd_t) { (x) })
@@ -130,7 +131,8 @@
typedef struct { unsigned long pud; } pud_t;
#define pud_val(x) ((x).pud)
#define __pud(x) ((pud_t) { (x) })
-#endif
+#endif /* !CONFIG_PPC_64K_PAGES */
+#endif /* CONFIG_PPC64 */
/* PGD level */
typedef struct { unsigned long pgd; } pgd_t;
@@ -159,15 +161,17 @@
#endif
+#ifdef CONFIG_PPC64
typedef unsigned long pmd_t;
#define pmd_val(x) (x)
#define __pmd(x) (x)
-#if defined(CONFIG_PPC64) && !defined(CONFIG_PPC_64K_PAGES)
+#ifndef CONFIG_PPC_64K_PAGES
typedef unsigned long pud_t;
#define pud_val(x) (x)
#define __pud(x) (x)
-#endif
+#endif /* !CONFIG_PPC_64K_PAGES */
+#endif /* CONFIG_PPC64 */
typedef unsigned long pgd_t;
#define pgd_val(x) (x)
diff --git a/include/asm-powerpc/page_32.h b/include/asm-powerpc/page_32.h
index 07f6d3c..374d0db 100644
--- a/include/asm-powerpc/page_32.h
+++ b/include/asm-powerpc/page_32.h
@@ -14,11 +14,9 @@
#ifdef CONFIG_PTE_64BIT
typedef unsigned long long pte_basic_t;
#define PTE_SHIFT (PAGE_SHIFT - 3) /* 512 ptes per page */
-#define PTE_FMT "%16Lx"
#else
typedef unsigned long pte_basic_t;
#define PTE_SHIFT (PAGE_SHIFT - 2) /* 1024 ptes per page */
-#define PTE_FMT "%.8lx"
#endif
struct page;
diff --git a/include/asm-powerpc/parport.h b/include/asm-powerpc/parport.h
index b37b81e..414c50e 100644
--- a/include/asm-powerpc/parport.h
+++ b/include/asm-powerpc/parport.h
@@ -12,11 +12,6 @@
#include <asm/prom.h>
-extern struct parport *parport_pc_probe_port (unsigned long int base,
- unsigned long int base_hi,
- int irq, int dma,
- struct pci_dev *dev);
-
static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma)
{
struct device_node *np;
diff --git a/include/asm-powerpc/pgalloc-32.h b/include/asm-powerpc/pgalloc-32.h
new file mode 100644
index 0000000..e130743
--- /dev/null
+++ b/include/asm-powerpc/pgalloc-32.h
@@ -0,0 +1,41 @@
+#ifndef _ASM_POWERPC_PGALLOC_32_H
+#define _ASM_POWERPC_PGALLOC_32_H
+
+#include <linux/threads.h>
+
+extern void __bad_pte(pmd_t *pmd);
+
+extern pgd_t *pgd_alloc(struct mm_struct *mm);
+extern void pgd_free(pgd_t *pgd);
+
+/*
+ * We don't have any real pmd's, and this code never triggers because
+ * the pgd will always be present..
+ */
+/* #define pmd_alloc_one(mm,address) ({ BUG(); ((pmd_t *)2); }) */
+#define pmd_free(x) do { } while (0)
+#define __pmd_free_tlb(tlb,x) do { } while (0)
+/* #define pgd_populate(mm, pmd, pte) BUG() */
+
+#ifndef CONFIG_BOOKE
+#define pmd_populate_kernel(mm, pmd, pte) \
+ (pmd_val(*(pmd)) = __pa(pte) | _PMD_PRESENT)
+#define pmd_populate(mm, pmd, pte) \
+ (pmd_val(*(pmd)) = (page_to_pfn(pte) << PAGE_SHIFT) | _PMD_PRESENT)
+#else
+#define pmd_populate_kernel(mm, pmd, pte) \
+ (pmd_val(*(pmd)) = (unsigned long)pte | _PMD_PRESENT)
+#define pmd_populate(mm, pmd, pte) \
+ (pmd_val(*(pmd)) = (unsigned long)lowmem_page_address(pte) | _PMD_PRESENT)
+#endif
+
+extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr);
+extern struct page *pte_alloc_one(struct mm_struct *mm, unsigned long addr);
+extern void pte_free_kernel(pte_t *pte);
+extern void pte_free(struct page *pte);
+
+#define __pte_free_tlb(tlb, pte) pte_free((pte))
+
+#define check_pgt_cache() do { } while (0)
+
+#endif /* _ASM_POWERPC_PGALLOC_32_H */
diff --git a/include/asm-powerpc/pgalloc-64.h b/include/asm-powerpc/pgalloc-64.h
new file mode 100644
index 0000000..30b50cf
--- /dev/null
+++ b/include/asm-powerpc/pgalloc-64.h
@@ -0,0 +1,152 @@
+#ifndef _ASM_POWERPC_PGALLOC_64_H
+#define _ASM_POWERPC_PGALLOC_64_H
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/cpumask.h>
+#include <linux/percpu.h>
+
+extern struct kmem_cache *pgtable_cache[];
+
+#ifdef CONFIG_PPC_64K_PAGES
+#define PTE_CACHE_NUM 0
+#define PMD_CACHE_NUM 1
+#define PGD_CACHE_NUM 2
+#define HUGEPTE_CACHE_NUM 3
+#else
+#define PTE_CACHE_NUM 0
+#define PMD_CACHE_NUM 1
+#define PUD_CACHE_NUM 1
+#define PGD_CACHE_NUM 0
+#define HUGEPTE_CACHE_NUM 2
+#endif
+
+static inline pgd_t *pgd_alloc(struct mm_struct *mm)
+{
+ return kmem_cache_alloc(pgtable_cache[PGD_CACHE_NUM], GFP_KERNEL);
+}
+
+static inline void pgd_free(pgd_t *pgd)
+{
+ kmem_cache_free(pgtable_cache[PGD_CACHE_NUM], pgd);
+}
+
+#ifndef CONFIG_PPC_64K_PAGES
+
+#define pgd_populate(MM, PGD, PUD) pgd_set(PGD, PUD)
+
+static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
+{
+ return kmem_cache_alloc(pgtable_cache[PUD_CACHE_NUM],
+ GFP_KERNEL|__GFP_REPEAT);
+}
+
+static inline void pud_free(pud_t *pud)
+{
+ kmem_cache_free(pgtable_cache[PUD_CACHE_NUM], pud);
+}
+
+static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
+{
+ pud_set(pud, (unsigned long)pmd);
+}
+
+#define pmd_populate(mm, pmd, pte_page) \
+ pmd_populate_kernel(mm, pmd, page_address(pte_page))
+#define pmd_populate_kernel(mm, pmd, pte) pmd_set(pmd, (unsigned long)(pte))
+
+
+#else /* CONFIG_PPC_64K_PAGES */
+
+#define pud_populate(mm, pud, pmd) pud_set(pud, (unsigned long)pmd)
+
+static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
+ pte_t *pte)
+{
+ pmd_set(pmd, (unsigned long)pte);
+}
+
+#define pmd_populate(mm, pmd, pte_page) \
+ pmd_populate_kernel(mm, pmd, page_address(pte_page))
+
+#endif /* CONFIG_PPC_64K_PAGES */
+
+static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
+{
+ return kmem_cache_alloc(pgtable_cache[PMD_CACHE_NUM],
+ GFP_KERNEL|__GFP_REPEAT);
+}
+
+static inline void pmd_free(pmd_t *pmd)
+{
+ kmem_cache_free(pgtable_cache[PMD_CACHE_NUM], pmd);
+}
+
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
+ unsigned long address)
+{
+ return kmem_cache_alloc(pgtable_cache[PTE_CACHE_NUM],
+ GFP_KERNEL|__GFP_REPEAT);
+}
+
+static inline struct page *pte_alloc_one(struct mm_struct *mm,
+ unsigned long address)
+{
+ return virt_to_page(pte_alloc_one_kernel(mm, address));
+}
+
+static inline void pte_free_kernel(pte_t *pte)
+{
+ kmem_cache_free(pgtable_cache[PTE_CACHE_NUM], pte);
+}
+
+static inline void pte_free(struct page *ptepage)
+{
+ pte_free_kernel(page_address(ptepage));
+}
+
+#define PGF_CACHENUM_MASK 0x3
+
+typedef struct pgtable_free {
+ unsigned long val;
+} pgtable_free_t;
+
+static inline pgtable_free_t pgtable_free_cache(void *p, int cachenum,
+ unsigned long mask)
+{
+ BUG_ON(cachenum > PGF_CACHENUM_MASK);
+
+ return (pgtable_free_t){.val = ((unsigned long) p & ~mask) | cachenum};
+}
+
+static inline void pgtable_free(pgtable_free_t pgf)
+{
+ void *p = (void *)(pgf.val & ~PGF_CACHENUM_MASK);
+ int cachenum = pgf.val & PGF_CACHENUM_MASK;
+
+ kmem_cache_free(pgtable_cache[cachenum], p);
+}
+
+extern void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf);
+
+#define __pte_free_tlb(tlb, ptepage) \
+ pgtable_free_tlb(tlb, pgtable_free_cache(page_address(ptepage), \
+ PTE_CACHE_NUM, PTE_TABLE_SIZE-1))
+#define __pmd_free_tlb(tlb, pmd) \
+ pgtable_free_tlb(tlb, pgtable_free_cache(pmd, \
+ PMD_CACHE_NUM, PMD_TABLE_SIZE-1))
+#ifndef CONFIG_PPC_64K_PAGES
+#define __pud_free_tlb(tlb, pud) \
+ pgtable_free_tlb(tlb, pgtable_free_cache(pud, \
+ PUD_CACHE_NUM, PUD_TABLE_SIZE-1))
+#endif /* CONFIG_PPC_64K_PAGES */
+
+#define check_pgt_cache() do { } while (0)
+
+#endif /* _ASM_POWERPC_PGALLOC_64_H */
diff --git a/include/asm-powerpc/pgalloc.h b/include/asm-powerpc/pgalloc.h
index b0830db..b4505ed 100644
--- a/include/asm-powerpc/pgalloc.h
+++ b/include/asm-powerpc/pgalloc.h
@@ -2,159 +2,11 @@
#define _ASM_POWERPC_PGALLOC_H
#ifdef __KERNEL__
-#ifndef CONFIG_PPC64
-#include <asm-ppc/pgalloc.h>
+#ifdef CONFIG_PPC64
+#include <asm/pgalloc-64.h>
#else
-
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/cpumask.h>
-#include <linux/percpu.h>
-
-extern struct kmem_cache *pgtable_cache[];
-
-#ifdef CONFIG_PPC_64K_PAGES
-#define PTE_CACHE_NUM 0
-#define PMD_CACHE_NUM 1
-#define PGD_CACHE_NUM 2
-#define HUGEPTE_CACHE_NUM 3
-#else
-#define PTE_CACHE_NUM 0
-#define PMD_CACHE_NUM 1
-#define PUD_CACHE_NUM 1
-#define PGD_CACHE_NUM 0
-#define HUGEPTE_CACHE_NUM 2
+#include <asm/pgalloc-32.h>
#endif
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-static inline pgd_t *pgd_alloc(struct mm_struct *mm)
-{
- return kmem_cache_alloc(pgtable_cache[PGD_CACHE_NUM], GFP_KERNEL);
-}
-
-static inline void pgd_free(pgd_t *pgd)
-{
- kmem_cache_free(pgtable_cache[PGD_CACHE_NUM], pgd);
-}
-
-#ifndef CONFIG_PPC_64K_PAGES
-
-#define pgd_populate(MM, PGD, PUD) pgd_set(PGD, PUD)
-
-static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
-{
- return kmem_cache_alloc(pgtable_cache[PUD_CACHE_NUM],
- GFP_KERNEL|__GFP_REPEAT);
-}
-
-static inline void pud_free(pud_t *pud)
-{
- kmem_cache_free(pgtable_cache[PUD_CACHE_NUM], pud);
-}
-
-static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
-{
- pud_set(pud, (unsigned long)pmd);
-}
-
-#define pmd_populate(mm, pmd, pte_page) \
- pmd_populate_kernel(mm, pmd, page_address(pte_page))
-#define pmd_populate_kernel(mm, pmd, pte) pmd_set(pmd, (unsigned long)(pte))
-
-
-#else /* CONFIG_PPC_64K_PAGES */
-
-#define pud_populate(mm, pud, pmd) pud_set(pud, (unsigned long)pmd)
-
-static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
- pte_t *pte)
-{
- pmd_set(pmd, (unsigned long)pte);
-}
-
-#define pmd_populate(mm, pmd, pte_page) \
- pmd_populate_kernel(mm, pmd, page_address(pte_page))
-
-#endif /* CONFIG_PPC_64K_PAGES */
-
-static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
-{
- return kmem_cache_alloc(pgtable_cache[PMD_CACHE_NUM],
- GFP_KERNEL|__GFP_REPEAT);
-}
-
-static inline void pmd_free(pmd_t *pmd)
-{
- kmem_cache_free(pgtable_cache[PMD_CACHE_NUM], pmd);
-}
-
-static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
- unsigned long address)
-{
- return kmem_cache_alloc(pgtable_cache[PTE_CACHE_NUM],
- GFP_KERNEL|__GFP_REPEAT);
-}
-
-static inline struct page *pte_alloc_one(struct mm_struct *mm,
- unsigned long address)
-{
- return virt_to_page(pte_alloc_one_kernel(mm, address));
-}
-
-static inline void pte_free_kernel(pte_t *pte)
-{
- kmem_cache_free(pgtable_cache[PTE_CACHE_NUM], pte);
-}
-
-static inline void pte_free(struct page *ptepage)
-{
- pte_free_kernel(page_address(ptepage));
-}
-
-#define PGF_CACHENUM_MASK 0x3
-
-typedef struct pgtable_free {
- unsigned long val;
-} pgtable_free_t;
-
-static inline pgtable_free_t pgtable_free_cache(void *p, int cachenum,
- unsigned long mask)
-{
- BUG_ON(cachenum > PGF_CACHENUM_MASK);
-
- return (pgtable_free_t){.val = ((unsigned long) p & ~mask) | cachenum};
-}
-
-static inline void pgtable_free(pgtable_free_t pgf)
-{
- void *p = (void *)(pgf.val & ~PGF_CACHENUM_MASK);
- int cachenum = pgf.val & PGF_CACHENUM_MASK;
-
- kmem_cache_free(pgtable_cache[cachenum], p);
-}
-
-extern void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf);
-
-#define __pte_free_tlb(tlb, ptepage) \
- pgtable_free_tlb(tlb, pgtable_free_cache(page_address(ptepage), \
- PTE_CACHE_NUM, PTE_TABLE_SIZE-1))
-#define __pmd_free_tlb(tlb, pmd) \
- pgtable_free_tlb(tlb, pgtable_free_cache(pmd, \
- PMD_CACHE_NUM, PMD_TABLE_SIZE-1))
-#ifndef CONFIG_PPC_64K_PAGES
-#define __pud_free_tlb(tlb, pud) \
- pgtable_free_tlb(tlb, pgtable_free_cache(pud, \
- PUD_CACHE_NUM, PUD_TABLE_SIZE-1))
-#endif /* CONFIG_PPC_64K_PAGES */
-
-#define check_pgt_cache() do { } while (0)
-
-#endif /* CONFIG_PPC64 */
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_PGALLOC_H */
diff --git a/include/asm-powerpc/pgtable-4k.h b/include/asm-powerpc/pgtable-4k.h
index a28fa8b..1744d6a 100644
--- a/include/asm-powerpc/pgtable-4k.h
+++ b/include/asm-powerpc/pgtable-4k.h
@@ -1,3 +1,5 @@
+#ifndef _ASM_POWERPC_PGTABLE_4K_H
+#define _ASM_POWERPC_PGTABLE_4K_H
/*
* Entries per page directory level. The PTE level must use a 64b record
* for each page table entry. The PMD and PGD level use a 32b record for
@@ -100,3 +102,4 @@
#define remap_4k_pfn(vma, addr, pfn, prot) \
remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, (prot))
+#endif /* _ASM_POWERPC_PGTABLE_4K_H */
diff --git a/include/asm-powerpc/pgtable-64k.h b/include/asm-powerpc/pgtable-64k.h
index 5e84f07..16ef497 100644
--- a/include/asm-powerpc/pgtable-64k.h
+++ b/include/asm-powerpc/pgtable-64k.h
@@ -1,6 +1,5 @@
#ifndef _ASM_POWERPC_PGTABLE_64K_H
#define _ASM_POWERPC_PGTABLE_64K_H
-#ifdef __KERNEL__
#include <asm-generic/pgtable-nopud.h>
@@ -65,8 +64,6 @@
/* Bits to mask out from a PGD/PUD to get to the PMD page */
#define PUD_MASKED_BITS 0x1ff
-#ifndef __ASSEMBLY__
-
/* Manipulate "rpte" values */
#define __real_pte(e,p) ((real_pte_t) { \
(e), pte_val(*((p) + PTRS_PER_PTE)) })
@@ -98,6 +95,4 @@
remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, \
__pgprot(pgprot_val((prot)) | _PAGE_4K_PFN))
-#endif /* __ASSEMBLY__ */
-#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_PGTABLE_64K_H */
diff --git a/include/asm-powerpc/pgtable-ppc32.h b/include/asm-powerpc/pgtable-ppc32.h
new file mode 100644
index 0000000..09662a2
--- /dev/null
+++ b/include/asm-powerpc/pgtable-ppc32.h
@@ -0,0 +1,813 @@
+#ifndef _ASM_POWERPC_PGTABLE_PPC32_H
+#define _ASM_POWERPC_PGTABLE_PPC32_H
+
+#include <asm-generic/pgtable-nopmd.h>
+
+#ifndef __ASSEMBLY__
+#include <linux/sched.h>
+#include <linux/threads.h>
+#include <asm/processor.h> /* For TASK_SIZE */
+#include <asm/mmu.h>
+#include <asm/page.h>
+#include <asm/io.h> /* For sub-arch specific PPC_PIN_SIZE */
+struct mm_struct;
+
+extern unsigned long va_to_phys(unsigned long address);
+extern pte_t *va_to_pte(unsigned long address);
+extern unsigned long ioremap_bot, ioremap_base;
+#endif /* __ASSEMBLY__ */
+
+/*
+ * The PowerPC MMU uses a hash table containing PTEs, together with
+ * a set of 16 segment registers (on 32-bit implementations), to define
+ * the virtual to physical address mapping.
+ *
+ * We use the hash table as an extended TLB, i.e. a cache of currently
+ * active mappings. We maintain a two-level page table tree, much
+ * like that used by the i386, for the sake of the Linux memory
+ * management code. Low-level assembler code in hashtable.S
+ * (procedure hash_page) is responsible for extracting ptes from the
+ * tree and putting them into the hash table when necessary, and
+ * updating the accessed and modified bits in the page table tree.
+ */
+
+/*
+ * The PowerPC MPC8xx uses a TLB with hardware assisted, software tablewalk.
+ * We also use the two level tables, but we can put the real bits in them
+ * needed for the TLB and tablewalk. These definitions require Mx_CTR.PPM = 0,
+ * Mx_CTR.PPCS = 0, and MD_CTR.TWAM = 1. The level 2 descriptor has
+ * additional page protection (when Mx_CTR.PPCS = 1) that allows TLB hit
+ * based upon user/super access. The TLB does not have accessed nor write
+ * protect. We assume that if the TLB get loaded with an entry it is
+ * accessed, and overload the changed bit for write protect. We use
+ * two bits in the software pte that are supposed to be set to zero in
+ * the TLB entry (24 and 25) for these indicators. Although the level 1
+ * descriptor contains the guarded and writethrough/copyback bits, we can
+ * set these at the page level since they get copied from the Mx_TWC
+ * register when the TLB entry is loaded. We will use bit 27 for guard, since
+ * that is where it exists in the MD_TWC, and bit 26 for writethrough.
+ * These will get masked from the level 2 descriptor at TLB load time, and
+ * copied to the MD_TWC before it gets loaded.
+ * Large page sizes added. We currently support two sizes, 4K and 8M.
+ * This also allows a TLB hander optimization because we can directly
+ * load the PMD into MD_TWC. The 8M pages are only used for kernel
+ * mapping of well known areas. The PMD (PGD) entries contain control
+ * flags in addition to the address, so care must be taken that the
+ * software no longer assumes these are only pointers.
+ */
+
+/*
+ * At present, all PowerPC 400-class processors share a similar TLB
+ * architecture. The instruction and data sides share a unified,
+ * 64-entry, fully-associative TLB which is maintained totally under
+ * software control. In addition, the instruction side has a
+ * hardware-managed, 4-entry, fully-associative TLB which serves as a
+ * first level to the shared TLB. These two TLBs are known as the UTLB
+ * and ITLB, respectively (see "mmu.h" for definitions).
+ */
+
+/*
+ * The normal case is that PTEs are 32-bits and we have a 1-page
+ * 1024-entry pgdir pointing to 1-page 1024-entry PTE pages. -- paulus
+ *
+ * For any >32-bit physical address platform, we can use the following
+ * two level page table layout where the pgdir is 8KB and the MS 13 bits
+ * are an index to the second level table. The combined pgdir/pmd first
+ * level has 2048 entries and the second level has 512 64-bit PTE entries.
+ * -Matt
+ */
+/* PGDIR_SHIFT determines what a top-level page table entry can map */
+#define PGDIR_SHIFT (PAGE_SHIFT + PTE_SHIFT)
+#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
+#define PGDIR_MASK (~(PGDIR_SIZE-1))
+
+/*
+ * entries per page directory level: our page-table tree is two-level, so
+ * we don't really have any PMD directory.
+ */
+#define PTRS_PER_PTE (1 << PTE_SHIFT)
+#define PTRS_PER_PMD 1
+#define PTRS_PER_PGD (1 << (32 - PGDIR_SHIFT))
+
+#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE)
+#define FIRST_USER_ADDRESS 0
+
+#define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
+#define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
+
+#define pte_ERROR(e) \
+ printk("%s:%d: bad pte %llx.\n", __FILE__, __LINE__, \
+ (unsigned long long)pte_val(e))
+#define pgd_ERROR(e) \
+ printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 64MB value just means that there will be a 64MB "hole" after the
+ * physical memory until the kernel virtual memory starts. That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ *
+ * We no longer map larger than phys RAM with the BATs so we don't have
+ * to worry about the VMALLOC_OFFSET causing problems. We do have to worry
+ * about clashes between our early calls to ioremap() that start growing down
+ * from ioremap_base being run into the VM area allocations (growing upwards
+ * from VMALLOC_START). For this reason we have ioremap_bot to check when
+ * we actually run into our mappings setup in the early boot with the VM
+ * system. This really does become a problem for machines with good amounts
+ * of RAM. -- Cort
+ */
+#define VMALLOC_OFFSET (0x1000000) /* 16M */
+#ifdef PPC_PIN_SIZE
+#define VMALLOC_START (((_ALIGN((long)high_memory, PPC_PIN_SIZE) + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
+#else
+#define VMALLOC_START ((((long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
+#endif
+#define VMALLOC_END ioremap_bot
+
+/*
+ * Bits in a linux-style PTE. These match the bits in the
+ * (hardware-defined) PowerPC PTE as closely as possible.
+ */
+
+#if defined(CONFIG_40x)
+
+/* There are several potential gotchas here. The 40x hardware TLBLO
+ field looks like this:
+
+ 0 1 2 3 4 ... 18 19 20 21 22 23 24 25 26 27 28 29 30 31
+ RPN..................... 0 0 EX WR ZSEL....... W I M G
+
+ Where possible we make the Linux PTE bits match up with this
+
+ - bits 20 and 21 must be cleared, because we use 4k pages (40x can
+ support down to 1k pages), this is done in the TLBMiss exception
+ handler.
+ - We use only zones 0 (for kernel pages) and 1 (for user pages)
+ of the 16 available. Bit 24-26 of the TLB are cleared in the TLB
+ miss handler. Bit 27 is PAGE_USER, thus selecting the correct
+ zone.
+ - PRESENT *must* be in the bottom two bits because swap cache
+ entries use the top 30 bits. Because 40x doesn't support SMP
+ anyway, M is irrelevant so we borrow it for PAGE_PRESENT. Bit 30
+ is cleared in the TLB miss handler before the TLB entry is loaded.
+ - All other bits of the PTE are loaded into TLBLO without
+ modification, leaving us only the bits 20, 21, 24, 25, 26, 30 for
+ software PTE bits. We actually use use bits 21, 24, 25, and
+ 30 respectively for the software bits: ACCESSED, DIRTY, RW, and
+ PRESENT.
+*/
+
+/* Definitions for 40x embedded chips. */
+#define _PAGE_GUARDED 0x001 /* G: page is guarded from prefetch */
+#define _PAGE_FILE 0x001 /* when !present: nonlinear file mapping */
+#define _PAGE_PRESENT 0x002 /* software: PTE contains a translation */
+#define _PAGE_NO_CACHE 0x004 /* I: caching is inhibited */
+#define _PAGE_WRITETHRU 0x008 /* W: caching is write-through */
+#define _PAGE_USER 0x010 /* matches one of the zone permission bits */
+#define _PAGE_RW 0x040 /* software: Writes permitted */
+#define _PAGE_DIRTY 0x080 /* software: dirty page */
+#define _PAGE_HWWRITE 0x100 /* hardware: Dirty & RW, set in exception */
+#define _PAGE_HWEXEC 0x200 /* hardware: EX permission */
+#define _PAGE_ACCESSED 0x400 /* software: R: page referenced */
+
+#define _PMD_PRESENT 0x400 /* PMD points to page of PTEs */
+#define _PMD_BAD 0x802
+#define _PMD_SIZE 0x0e0 /* size field, != 0 for large-page PMD entry */
+#define _PMD_SIZE_4M 0x0c0
+#define _PMD_SIZE_16M 0x0e0
+#define PMD_PAGE_SIZE(pmdval) (1024 << (((pmdval) & _PMD_SIZE) >> 4))
+
+#elif defined(CONFIG_44x)
+/*
+ * Definitions for PPC440
+ *
+ * Because of the 3 word TLB entries to support 36-bit addressing,
+ * the attribute are difficult to map in such a fashion that they
+ * are easily loaded during exception processing. I decided to
+ * organize the entry so the ERPN is the only portion in the
+ * upper word of the PTE and the attribute bits below are packed
+ * in as sensibly as they can be in the area below a 4KB page size
+ * oriented RPN. This at least makes it easy to load the RPN and
+ * ERPN fields in the TLB. -Matt
+ *
+ * Note that these bits preclude future use of a page size
+ * less than 4KB.
+ *
+ *
+ * PPC 440 core has following TLB attribute fields;
+ *
+ * TLB1:
+ * 0 1 2 3 4 ... 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
+ * RPN................................. - - - - - - ERPN.......
+ *
+ * TLB2:
+ * 0 1 2 3 4 ... 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
+ * - - - - - - U0 U1 U2 U3 W I M G E - UX UW UR SX SW SR
+ *
+ * There are some constrains and options, to decide mapping software bits
+ * into TLB entry.
+ *
+ * - PRESENT *must* be in the bottom three bits because swap cache
+ * entries use the top 29 bits for TLB2.
+ *
+ * - FILE *must* be in the bottom three bits because swap cache
+ * entries use the top 29 bits for TLB2.
+ *
+ * - CACHE COHERENT bit (M) has no effect on PPC440 core, because it
+ * doesn't support SMP. So we can use this as software bit, like
+ * DIRTY.
+ *
+ * With the PPC 44x Linux implementation, the 0-11th LSBs of the PTE are used
+ * for memory protection related functions (see PTE structure in
+ * include/asm-ppc/mmu.h). The _PAGE_XXX definitions in this file map to the
+ * above bits. Note that the bit values are CPU specific, not architecture
+ * specific.
+ *
+ * The kernel PTE entry holds an arch-dependent swp_entry structure under
+ * certain situations. In other words, in such situations some portion of
+ * the PTE bits are used as a swp_entry. In the PPC implementation, the
+ * 3-24th LSB are shared with swp_entry, however the 0-2nd three LSB still
+ * hold protection values. That means the three protection bits are
+ * reserved for both PTE and SWAP entry at the most significant three
+ * LSBs.
+ *
+ * There are three protection bits available for SWAP entry:
+ * _PAGE_PRESENT
+ * _PAGE_FILE
+ * _PAGE_HASHPTE (if HW has)
+ *
+ * So those three bits have to be inside of 0-2nd LSB of PTE.
+ *
+ */
+
+#define _PAGE_PRESENT 0x00000001 /* S: PTE valid */
+#define _PAGE_RW 0x00000002 /* S: Write permission */
+#define _PAGE_FILE 0x00000004 /* S: nonlinear file mapping */
+#define _PAGE_ACCESSED 0x00000008 /* S: Page referenced */
+#define _PAGE_HWWRITE 0x00000010 /* H: Dirty & RW */
+#define _PAGE_HWEXEC 0x00000020 /* H: Execute permission */
+#define _PAGE_USER 0x00000040 /* S: User page */
+#define _PAGE_ENDIAN 0x00000080 /* H: E bit */
+#define _PAGE_GUARDED 0x00000100 /* H: G bit */
+#define _PAGE_DIRTY 0x00000200 /* S: Page dirty */
+#define _PAGE_NO_CACHE 0x00000400 /* H: I bit */
+#define _PAGE_WRITETHRU 0x00000800 /* H: W bit */
+
+/* TODO: Add large page lowmem mapping support */
+#define _PMD_PRESENT 0
+#define _PMD_PRESENT_MASK (PAGE_MASK)
+#define _PMD_BAD (~PAGE_MASK)
+
+/* ERPN in a PTE never gets cleared, ignore it */
+#define _PTE_NONE_MASK 0xffffffff00000000ULL
+
+#elif defined(CONFIG_FSL_BOOKE)
+/*
+ MMU Assist Register 3:
+
+ 32 33 34 35 36 ... 50 51 52 53 54 55 56 57 58 59 60 61 62 63
+ RPN...................... 0 0 U0 U1 U2 U3 UX SX UW SW UR SR
+
+ - PRESENT *must* be in the bottom three bits because swap cache
+ entries use the top 29 bits.
+
+ - FILE *must* be in the bottom three bits because swap cache
+ entries use the top 29 bits.
+*/
+
+/* Definitions for FSL Book-E Cores */
+#define _PAGE_PRESENT 0x00001 /* S: PTE contains a translation */
+#define _PAGE_USER 0x00002 /* S: User page (maps to UR) */
+#define _PAGE_FILE 0x00002 /* S: when !present: nonlinear file mapping */
+#define _PAGE_ACCESSED 0x00004 /* S: Page referenced */
+#define _PAGE_HWWRITE 0x00008 /* H: Dirty & RW, set in exception */
+#define _PAGE_RW 0x00010 /* S: Write permission */
+#define _PAGE_HWEXEC 0x00020 /* H: UX permission */
+
+#define _PAGE_ENDIAN 0x00040 /* H: E bit */
+#define _PAGE_GUARDED 0x00080 /* H: G bit */
+#define _PAGE_COHERENT 0x00100 /* H: M bit */
+#define _PAGE_NO_CACHE 0x00200 /* H: I bit */
+#define _PAGE_WRITETHRU 0x00400 /* H: W bit */
+
+#ifdef CONFIG_PTE_64BIT
+#define _PAGE_DIRTY 0x08000 /* S: Page dirty */
+
+/* ERPN in a PTE never gets cleared, ignore it */
+#define _PTE_NONE_MASK 0xffffffffffff0000ULL
+#else
+#define _PAGE_DIRTY 0x00800 /* S: Page dirty */
+#endif
+
+#define _PMD_PRESENT 0
+#define _PMD_PRESENT_MASK (PAGE_MASK)
+#define _PMD_BAD (~PAGE_MASK)
+
+#elif defined(CONFIG_8xx)
+/* Definitions for 8xx embedded chips. */
+#define _PAGE_PRESENT 0x0001 /* Page is valid */
+#define _PAGE_FILE 0x0002 /* when !present: nonlinear file mapping */
+#define _PAGE_NO_CACHE 0x0002 /* I: cache inhibit */
+#define _PAGE_SHARED 0x0004 /* No ASID (context) compare */
+
+/* These five software bits must be masked out when the entry is loaded
+ * into the TLB.
+ */
+#define _PAGE_EXEC 0x0008 /* software: i-cache coherency required */
+#define _PAGE_GUARDED 0x0010 /* software: guarded access */
+#define _PAGE_DIRTY 0x0020 /* software: page changed */
+#define _PAGE_RW 0x0040 /* software: user write access allowed */
+#define _PAGE_ACCESSED 0x0080 /* software: page referenced */
+
+/* Setting any bits in the nibble with the follow two controls will
+ * require a TLB exception handler change. It is assumed unused bits
+ * are always zero.
+ */
+#define _PAGE_HWWRITE 0x0100 /* h/w write enable: never set in Linux PTE */
+#define _PAGE_USER 0x0800 /* One of the PP bits, the other is USER&~RW */
+
+#define _PMD_PRESENT 0x0001
+#define _PMD_BAD 0x0ff0
+#define _PMD_PAGE_MASK 0x000c
+#define _PMD_PAGE_8M 0x000c
+
+/*
+ * The 8xx TLB miss handler allegedly sets _PAGE_ACCESSED in the PTE
+ * for an address even if _PAGE_PRESENT is not set, as a performance
+ * optimization. This is a bug if you ever want to use swap unless
+ * _PAGE_ACCESSED is 2, which it isn't, or unless you have 8xx-specific
+ * definitions for __swp_entry etc. below, which would be gross.
+ * -- paulus
+ */
+#define _PTE_NONE_MASK _PAGE_ACCESSED
+
+#else /* CONFIG_6xx */
+/* Definitions for 60x, 740/750, etc. */
+#define _PAGE_PRESENT 0x001 /* software: pte contains a translation */
+#define _PAGE_HASHPTE 0x002 /* hash_page has made an HPTE for this pte */
+#define _PAGE_FILE 0x004 /* when !present: nonlinear file mapping */
+#define _PAGE_USER 0x004 /* usermode access allowed */
+#define _PAGE_GUARDED 0x008 /* G: prohibit speculative access */
+#define _PAGE_COHERENT 0x010 /* M: enforce memory coherence (SMP systems) */
+#define _PAGE_NO_CACHE 0x020 /* I: cache inhibit */
+#define _PAGE_WRITETHRU 0x040 /* W: cache write-through */
+#define _PAGE_DIRTY 0x080 /* C: page changed */
+#define _PAGE_ACCESSED 0x100 /* R: page referenced */
+#define _PAGE_EXEC 0x200 /* software: i-cache coherency required */
+#define _PAGE_RW 0x400 /* software: user write access allowed */
+
+#define _PTE_NONE_MASK _PAGE_HASHPTE
+
+#define _PMD_PRESENT 0
+#define _PMD_PRESENT_MASK (PAGE_MASK)
+#define _PMD_BAD (~PAGE_MASK)
+#endif
+
+/*
+ * Some bits are only used on some cpu families...
+ */
+#ifndef _PAGE_HASHPTE
+#define _PAGE_HASHPTE 0
+#endif
+#ifndef _PTE_NONE_MASK
+#define _PTE_NONE_MASK 0
+#endif
+#ifndef _PAGE_SHARED
+#define _PAGE_SHARED 0
+#endif
+#ifndef _PAGE_HWWRITE
+#define _PAGE_HWWRITE 0
+#endif
+#ifndef _PAGE_HWEXEC
+#define _PAGE_HWEXEC 0
+#endif
+#ifndef _PAGE_EXEC
+#define _PAGE_EXEC 0
+#endif
+#ifndef _PMD_PRESENT_MASK
+#define _PMD_PRESENT_MASK _PMD_PRESENT
+#endif
+#ifndef _PMD_SIZE
+#define _PMD_SIZE 0
+#define PMD_PAGE_SIZE(pmd) bad_call_to_PMD_PAGE_SIZE()
+#endif
+
+#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
+
+/*
+ * Note: the _PAGE_COHERENT bit automatically gets set in the hardware
+ * PTE if CONFIG_SMP is defined (hash_page does this); there is no need
+ * to have it in the Linux PTE, and in fact the bit could be reused for
+ * another purpose. -- paulus.
+ */
+
+#ifdef CONFIG_44x
+#define _PAGE_BASE (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_GUARDED)
+#else
+#define _PAGE_BASE (_PAGE_PRESENT | _PAGE_ACCESSED)
+#endif
+#define _PAGE_WRENABLE (_PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE)
+#define _PAGE_KERNEL (_PAGE_BASE | _PAGE_SHARED | _PAGE_WRENABLE)
+
+#ifdef CONFIG_PPC_STD_MMU
+/* On standard PPC MMU, no user access implies kernel read/write access,
+ * so to write-protect kernel memory we must turn on user access */
+#define _PAGE_KERNEL_RO (_PAGE_BASE | _PAGE_SHARED | _PAGE_USER)
+#else
+#define _PAGE_KERNEL_RO (_PAGE_BASE | _PAGE_SHARED)
+#endif
+
+#define _PAGE_IO (_PAGE_KERNEL | _PAGE_NO_CACHE | _PAGE_GUARDED)
+#define _PAGE_RAM (_PAGE_KERNEL | _PAGE_HWEXEC)
+
+#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) || defined(CONFIG_BDI_SWITCH)
+/* We want the debuggers to be able to set breakpoints anywhere, so
+ * don't write protect the kernel text */
+#define _PAGE_RAM_TEXT _PAGE_RAM
+#else
+#define _PAGE_RAM_TEXT (_PAGE_KERNEL_RO | _PAGE_HWEXEC)
+#endif
+
+#define PAGE_NONE __pgprot(_PAGE_BASE)
+#define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER)
+#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
+#define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
+#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
+#define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER)
+#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
+
+#define PAGE_KERNEL __pgprot(_PAGE_RAM)
+#define PAGE_KERNEL_NOCACHE __pgprot(_PAGE_IO)
+
+/*
+ * The PowerPC can only do execute protection on a segment (256MB) basis,
+ * not on a page basis. So we consider execute permission the same as read.
+ * Also, write permissions imply read permissions.
+ * This is the closest we can get..
+ */
+#define __P000 PAGE_NONE
+#define __P001 PAGE_READONLY_X
+#define __P010 PAGE_COPY
+#define __P011 PAGE_COPY_X
+#define __P100 PAGE_READONLY
+#define __P101 PAGE_READONLY_X
+#define __P110 PAGE_COPY
+#define __P111 PAGE_COPY_X
+
+#define __S000 PAGE_NONE
+#define __S001 PAGE_READONLY_X
+#define __S010 PAGE_SHARED
+#define __S011 PAGE_SHARED_X
+#define __S100 PAGE_READONLY
+#define __S101 PAGE_READONLY_X
+#define __S110 PAGE_SHARED
+#define __S111 PAGE_SHARED_X
+
+#ifndef __ASSEMBLY__
+/* Make sure we get a link error if PMD_PAGE_SIZE is ever called on a
+ * kernel without large page PMD support */
+extern unsigned long bad_call_to_PMD_PAGE_SIZE(void);
+
+/*
+ * Conversions between PTE values and page frame numbers.
+ */
+
+/* in some case we want to additionaly adjust where the pfn is in the pte to
+ * allow room for more flags */
+#if defined(CONFIG_FSL_BOOKE) && defined(CONFIG_PTE_64BIT)
+#define PFN_SHIFT_OFFSET (PAGE_SHIFT + 8)
+#else
+#define PFN_SHIFT_OFFSET (PAGE_SHIFT)
+#endif
+
+#define pte_pfn(x) (pte_val(x) >> PFN_SHIFT_OFFSET)
+#define pte_page(x) pfn_to_page(pte_pfn(x))
+
+#define pfn_pte(pfn, prot) __pte(((pte_basic_t)(pfn) << PFN_SHIFT_OFFSET) |\
+ pgprot_val(prot))
+#define mk_pte(page, prot) pfn_pte(page_to_pfn(page), prot)
+
+/*
+ * ZERO_PAGE is a global shared page that is always zero: used
+ * for zero-mapped memory areas etc..
+ */
+extern unsigned long empty_zero_page[1024];
+#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
+
+#endif /* __ASSEMBLY__ */
+
+#define pte_none(pte) ((pte_val(pte) & ~_PTE_NONE_MASK) == 0)
+#define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT)
+#define pte_clear(mm,addr,ptep) do { set_pte_at((mm), (addr), (ptep), __pte(0)); } while (0)
+
+#define pmd_none(pmd) (!pmd_val(pmd))
+#define pmd_bad(pmd) (pmd_val(pmd) & _PMD_BAD)
+#define pmd_present(pmd) (pmd_val(pmd) & _PMD_PRESENT_MASK)
+#define pmd_clear(pmdp) do { pmd_val(*(pmdp)) = 0; } while (0)
+
+#ifndef __ASSEMBLY__
+/*
+ * The following only work if pte_present() is true.
+ * Undefined behaviour if not..
+ */
+static inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_USER; }
+static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; }
+static inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_EXEC; }
+static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
+static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
+static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; }
+
+static inline void pte_uncache(pte_t pte) { pte_val(pte) |= _PAGE_NO_CACHE; }
+static inline void pte_cache(pte_t pte) { pte_val(pte) &= ~_PAGE_NO_CACHE; }
+
+static inline pte_t pte_rdprotect(pte_t pte) {
+ pte_val(pte) &= ~_PAGE_USER; return pte; }
+static inline pte_t pte_wrprotect(pte_t pte) {
+ pte_val(pte) &= ~(_PAGE_RW | _PAGE_HWWRITE); return pte; }
+static inline pte_t pte_exprotect(pte_t pte) {
+ pte_val(pte) &= ~_PAGE_EXEC; return pte; }
+static inline pte_t pte_mkclean(pte_t pte) {
+ pte_val(pte) &= ~(_PAGE_DIRTY | _PAGE_HWWRITE); return pte; }
+static inline pte_t pte_mkold(pte_t pte) {
+ pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
+
+static inline pte_t pte_mkread(pte_t pte) {
+ pte_val(pte) |= _PAGE_USER; return pte; }
+static inline pte_t pte_mkexec(pte_t pte) {
+ pte_val(pte) |= _PAGE_USER | _PAGE_EXEC; return pte; }
+static inline pte_t pte_mkwrite(pte_t pte) {
+ pte_val(pte) |= _PAGE_RW; return pte; }
+static inline pte_t pte_mkdirty(pte_t pte) {
+ pte_val(pte) |= _PAGE_DIRTY; return pte; }
+static inline pte_t pte_mkyoung(pte_t pte) {
+ pte_val(pte) |= _PAGE_ACCESSED; return pte; }
+
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{
+ pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot);
+ return pte;
+}
+
+/*
+ * When flushing the tlb entry for a page, we also need to flush the hash
+ * table entry. flush_hash_pages is assembler (for speed) in hashtable.S.
+ */
+extern int flush_hash_pages(unsigned context, unsigned long va,
+ unsigned long pmdval, int count);
+
+/* Add an HPTE to the hash table */
+extern void add_hash_page(unsigned context, unsigned long va,
+ unsigned long pmdval);
+
+/*
+ * Atomic PTE updates.
+ *
+ * pte_update clears and sets bit atomically, and returns
+ * the old pte value. In the 64-bit PTE case we lock around the
+ * low PTE word since we expect ALL flag bits to be there
+ */
+#ifndef CONFIG_PTE_64BIT
+static inline unsigned long pte_update(pte_t *p, unsigned long clr,
+ unsigned long set)
+{
+ unsigned long old, tmp;
+
+ __asm__ __volatile__("\
+1: lwarx %0,0,%3\n\
+ andc %1,%0,%4\n\
+ or %1,%1,%5\n"
+ PPC405_ERR77(0,%3)
+" stwcx. %1,0,%3\n\
+ bne- 1b"
+ : "=&r" (old), "=&r" (tmp), "=m" (*p)
+ : "r" (p), "r" (clr), "r" (set), "m" (*p)
+ : "cc" );
+ return old;
+}
+#else
+static inline unsigned long long pte_update(pte_t *p, unsigned long clr,
+ unsigned long set)
+{
+ unsigned long long old;
+ unsigned long tmp;
+
+ __asm__ __volatile__("\
+1: lwarx %L0,0,%4\n\
+ lwzx %0,0,%3\n\
+ andc %1,%L0,%5\n\
+ or %1,%1,%6\n"
+ PPC405_ERR77(0,%3)
+" stwcx. %1,0,%4\n\
+ bne- 1b"
+ : "=&r" (old), "=&r" (tmp), "=m" (*p)
+ : "r" (p), "r" ((unsigned long)(p) + 4), "r" (clr), "r" (set), "m" (*p)
+ : "cc" );
+ return old;
+}
+#endif
+
+/*
+ * set_pte stores a linux PTE into the linux page table.
+ * On machines which use an MMU hash table we avoid changing the
+ * _PAGE_HASHPTE bit.
+ */
+static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pte)
+{
+#if _PAGE_HASHPTE != 0
+ pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte) & ~_PAGE_HASHPTE);
+#else
+ *ptep = pte;
+#endif
+}
+
+/*
+ * 2.6 calles this without flushing the TLB entry, this is wrong
+ * for our hash-based implementation, we fix that up here
+ */
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
+static inline int __ptep_test_and_clear_young(unsigned int context, unsigned long addr, pte_t *ptep)
+{
+ unsigned long old;
+ old = pte_update(ptep, _PAGE_ACCESSED, 0);
+#if _PAGE_HASHPTE != 0
+ if (old & _PAGE_HASHPTE) {
+ unsigned long ptephys = __pa(ptep) & PAGE_MASK;
+ flush_hash_pages(context, addr, ptephys, 1);
+ }
+#endif
+ return (old & _PAGE_ACCESSED) != 0;
+}
+#define ptep_test_and_clear_young(__vma, __addr, __ptep) \
+ __ptep_test_and_clear_young((__vma)->vm_mm->context.id, __addr, __ptep)
+
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
+static inline int ptep_test_and_clear_dirty(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep)
+{
+ return (pte_update(ptep, (_PAGE_DIRTY | _PAGE_HWWRITE), 0) & _PAGE_DIRTY) != 0;
+}
+
+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
+static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep)
+{
+ return __pte(pte_update(ptep, ~_PAGE_HASHPTE, 0));
+}
+
+#define __HAVE_ARCH_PTEP_SET_WRPROTECT
+static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep)
+{
+ pte_update(ptep, (_PAGE_RW | _PAGE_HWWRITE), 0);
+}
+
+#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
+static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry, int dirty)
+{
+ unsigned long bits = pte_val(entry) &
+ (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW);
+ pte_update(ptep, 0, bits);
+}
+
+#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
+ do { \
+ __ptep_set_access_flags(__ptep, __entry, __dirty); \
+ flush_tlb_page_nohash(__vma, __address); \
+ } while(0)
+
+/*
+ * Macro to mark a page protection value as "uncacheable".
+ */
+#define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | _PAGE_NO_CACHE | _PAGE_GUARDED))
+
+struct file;
+extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
+ unsigned long size, pgprot_t vma_prot);
+#define __HAVE_PHYS_MEM_ACCESS_PROT
+
+#define __HAVE_ARCH_PTE_SAME
+#define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HASHPTE) == 0)
+
+/*
+ * Note that on Book E processors, the pmd contains the kernel virtual
+ * (lowmem) address of the pte page. The physical address is less useful
+ * because everything runs with translation enabled (even the TLB miss
+ * handler). On everything else the pmd contains the physical address
+ * of the pte page. -- paulus
+ */
+#ifndef CONFIG_BOOKE
+#define pmd_page_vaddr(pmd) \
+ ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
+#define pmd_page(pmd) \
+ (mem_map + (pmd_val(pmd) >> PAGE_SHIFT))
+#else
+#define pmd_page_vaddr(pmd) \
+ ((unsigned long) (pmd_val(pmd) & PAGE_MASK))
+#define pmd_page(pmd) \
+ (mem_map + (__pa(pmd_val(pmd)) >> PAGE_SHIFT))
+#endif
+
+/* to find an entry in a kernel page-table-directory */
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+
+/* to find an entry in a page-table-directory */
+#define pgd_index(address) ((address) >> PGDIR_SHIFT)
+#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
+
+/* Find an entry in the third-level page table.. */
+#define pte_index(address) \
+ (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+#define pte_offset_kernel(dir, addr) \
+ ((pte_t *) pmd_page_vaddr(*(dir)) + pte_index(addr))
+#define pte_offset_map(dir, addr) \
+ ((pte_t *) kmap_atomic(pmd_page(*(dir)), KM_PTE0) + pte_index(addr))
+#define pte_offset_map_nested(dir, addr) \
+ ((pte_t *) kmap_atomic(pmd_page(*(dir)), KM_PTE1) + pte_index(addr))
+
+#define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0)
+#define pte_unmap_nested(pte) kunmap_atomic(pte, KM_PTE1)
+
+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
+
+extern void paging_init(void);
+
+/*
+ * Encode and decode a swap entry.
+ * Note that the bits we use in a PTE for representing a swap entry
+ * must not include the _PAGE_PRESENT bit, the _PAGE_FILE bit, or the
+ *_PAGE_HASHPTE bit (if used). -- paulus
+ */
+#define __swp_type(entry) ((entry).val & 0x1f)
+#define __swp_offset(entry) ((entry).val >> 5)
+#define __swp_entry(type, offset) ((swp_entry_t) { (type) | ((offset) << 5) })
+#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) >> 3 })
+#define __swp_entry_to_pte(x) ((pte_t) { (x).val << 3 })
+
+/* Encode and decode a nonlinear file mapping entry */
+#define PTE_FILE_MAX_BITS 29
+#define pte_to_pgoff(pte) (pte_val(pte) >> 3)
+#define pgoff_to_pte(off) ((pte_t) { ((off) << 3) | _PAGE_FILE })
+
+/* CONFIG_APUS */
+/* For virtual address to physical address conversion */
+extern void cache_clear(__u32 addr, int length);
+extern void cache_push(__u32 addr, int length);
+extern int mm_end_of_chunk (unsigned long addr, int len);
+extern unsigned long iopa(unsigned long addr);
+extern unsigned long mm_ptov(unsigned long addr) __attribute_const__;
+
+/* Values for nocacheflag and cmode */
+/* These are not used by the APUS kernel_map, but prevents
+ compilation errors. */
+#define KERNELMAP_FULL_CACHING 0
+#define KERNELMAP_NOCACHE_SER 1
+#define KERNELMAP_NOCACHE_NONSER 2
+#define KERNELMAP_NO_COPYBACK 3
+
+/*
+ * Map some physical address range into the kernel address space.
+ */
+extern unsigned long kernel_map(unsigned long paddr, unsigned long size,
+ int nocacheflag, unsigned long *memavailp );
+
+/*
+ * Set cache mode of (kernel space) address range.
+ */
+extern void kernel_set_cachemode (unsigned long address, unsigned long size,
+ unsigned int cmode);
+
+/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
+#define kern_addr_valid(addr) (1)
+
+#ifdef CONFIG_PHYS_64BIT
+extern int remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
+ unsigned long paddr, unsigned long size, pgprot_t prot);
+
+static inline int io_remap_pfn_range(struct vm_area_struct *vma,
+ unsigned long vaddr,
+ unsigned long pfn,
+ unsigned long size,
+ pgprot_t prot)
+{
+ phys_addr_t paddr64 = fixup_bigphys_addr(pfn << PAGE_SHIFT, size);
+ return remap_pfn_range(vma, vaddr, paddr64 >> PAGE_SHIFT, size, prot);
+}
+#else
+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
+ remap_pfn_range(vma, vaddr, pfn, size, prot)
+#endif
+
+/*
+ * No page table caches to initialise
+ */
+#define pgtable_cache_init() do { } while (0)
+
+extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep,
+ pmd_t **pmdp);
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_POWERPC_PGTABLE_PPC32_H */
diff --git a/include/asm-powerpc/pgtable-ppc64.h b/include/asm-powerpc/pgtable-ppc64.h
new file mode 100644
index 0000000..704c4e6
--- /dev/null
+++ b/include/asm-powerpc/pgtable-ppc64.h
@@ -0,0 +1,492 @@
+#ifndef _ASM_POWERPC_PGTABLE_PPC64_H_
+#define _ASM_POWERPC_PGTABLE_PPC64_H_
+/*
+ * This file contains the functions and defines necessary to modify and use
+ * the ppc64 hashed page table.
+ */
+
+#ifndef __ASSEMBLY__
+#include <linux/stddef.h>
+#include <asm/processor.h> /* For TASK_SIZE */
+#include <asm/mmu.h>
+#include <asm/page.h>
+#include <asm/tlbflush.h>
+struct mm_struct;
+#endif /* __ASSEMBLY__ */
+
+#ifdef CONFIG_PPC_64K_PAGES
+#include <asm/pgtable-64k.h>
+#else
+#include <asm/pgtable-4k.h>
+#endif
+
+#define FIRST_USER_ADDRESS 0
+
+/*
+ * Size of EA range mapped by our pagetables.
+ */
+#define PGTABLE_EADDR_SIZE (PTE_INDEX_SIZE + PMD_INDEX_SIZE + \
+ PUD_INDEX_SIZE + PGD_INDEX_SIZE + PAGE_SHIFT)
+#define PGTABLE_RANGE (1UL << PGTABLE_EADDR_SIZE)
+
+#if TASK_SIZE_USER64 > PGTABLE_RANGE
+#error TASK_SIZE_USER64 exceeds pagetable range
+#endif
+
+#if TASK_SIZE_USER64 > (1UL << (USER_ESID_BITS + SID_SHIFT))
+#error TASK_SIZE_USER64 exceeds user VSID range
+#endif
+
+/*
+ * Define the address range of the vmalloc VM area.
+ */
+#define VMALLOC_START ASM_CONST(0xD000000000000000)
+#define VMALLOC_SIZE ASM_CONST(0x80000000000)
+#define VMALLOC_END (VMALLOC_START + VMALLOC_SIZE)
+
+/*
+ * Define the address range of the imalloc VM area.
+ */
+#define PHBS_IO_BASE VMALLOC_END
+#define IMALLOC_BASE (PHBS_IO_BASE + 0x80000000ul) /* Reserve 2 gigs for PHBs */
+#define IMALLOC_END (VMALLOC_START + PGTABLE_RANGE)
+
+/*
+ * Region IDs
+ */
+#define REGION_SHIFT 60UL
+#define REGION_MASK (0xfUL << REGION_SHIFT)
+#define REGION_ID(ea) (((unsigned long)(ea)) >> REGION_SHIFT)
+
+#define VMALLOC_REGION_ID (REGION_ID(VMALLOC_START))
+#define KERNEL_REGION_ID (REGION_ID(PAGE_OFFSET))
+#define USER_REGION_ID (0UL)
+
+/*
+ * Common bits in a linux-style PTE. These match the bits in the
+ * (hardware-defined) PowerPC PTE as closely as possible. Additional
+ * bits may be defined in pgtable-*.h
+ */
+#define _PAGE_PRESENT 0x0001 /* software: pte contains a translation */
+#define _PAGE_USER 0x0002 /* matches one of the PP bits */
+#define _PAGE_FILE 0x0002 /* (!present only) software: pte holds file offset */
+#define _PAGE_EXEC 0x0004 /* No execute on POWER4 and newer (we invert) */
+#define _PAGE_GUARDED 0x0008
+#define _PAGE_COHERENT 0x0010 /* M: enforce memory coherence (SMP systems) */
+#define _PAGE_NO_CACHE 0x0020 /* I: cache inhibit */
+#define _PAGE_WRITETHRU 0x0040 /* W: cache write-through */
+#define _PAGE_DIRTY 0x0080 /* C: page changed */
+#define _PAGE_ACCESSED 0x0100 /* R: page referenced */
+#define _PAGE_RW 0x0200 /* software: user write access allowed */
+#define _PAGE_HASHPTE 0x0400 /* software: pte has an associated HPTE */
+#define _PAGE_BUSY 0x0800 /* software: PTE & hash are busy */
+
+#define _PAGE_BASE (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_COHERENT)
+
+#define _PAGE_WRENABLE (_PAGE_RW | _PAGE_DIRTY)
+
+/* __pgprot defined in asm-powerpc/page.h */
+#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
+
+#define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_RW | _PAGE_USER)
+#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_RW | _PAGE_USER | _PAGE_EXEC)
+#define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER)
+#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
+#define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER)
+#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
+#define PAGE_KERNEL __pgprot(_PAGE_BASE | _PAGE_WRENABLE)
+#define PAGE_KERNEL_CI __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \
+ _PAGE_WRENABLE | _PAGE_NO_CACHE | _PAGE_GUARDED)
+#define PAGE_KERNEL_EXEC __pgprot(_PAGE_BASE | _PAGE_WRENABLE | _PAGE_EXEC)
+
+#define PAGE_AGP __pgprot(_PAGE_BASE | _PAGE_WRENABLE | _PAGE_NO_CACHE)
+#define HAVE_PAGE_AGP
+
+/* PTEIDX nibble */
+#define _PTEIDX_SECONDARY 0x8
+#define _PTEIDX_GROUP_IX 0x7
+
+
+/*
+ * POWER4 and newer have per page execute protection, older chips can only
+ * do this on a segment (256MB) basis.
+ *
+ * Also, write permissions imply read permissions.
+ * This is the closest we can get..
+ *
+ * Note due to the way vm flags are laid out, the bits are XWR
+ */
+#define __P000 PAGE_NONE
+#define __P001 PAGE_READONLY
+#define __P010 PAGE_COPY
+#define __P011 PAGE_COPY
+#define __P100 PAGE_READONLY_X
+#define __P101 PAGE_READONLY_X
+#define __P110 PAGE_COPY_X
+#define __P111 PAGE_COPY_X
+
+#define __S000 PAGE_NONE
+#define __S001 PAGE_READONLY
+#define __S010 PAGE_SHARED
+#define __S011 PAGE_SHARED
+#define __S100 PAGE_READONLY_X
+#define __S101 PAGE_READONLY_X
+#define __S110 PAGE_SHARED_X
+#define __S111 PAGE_SHARED_X
+
+#ifndef __ASSEMBLY__
+
+/*
+ * ZERO_PAGE is a global shared page that is always zero: used
+ * for zero-mapped memory areas etc..
+ */
+extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)];
+#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
+#endif /* __ASSEMBLY__ */
+
+#ifdef CONFIG_HUGETLB_PAGE
+
+#define HAVE_ARCH_UNMAPPED_AREA
+#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
+
+#endif
+
+#ifndef __ASSEMBLY__
+
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ *
+ * mk_pte takes a (struct page *) as input
+ */
+#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
+
+static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot)
+{
+ pte_t pte;
+
+
+ pte_val(pte) = (pfn << PTE_RPN_SHIFT) | pgprot_val(pgprot);
+ return pte;
+}
+
+#define pte_modify(_pte, newprot) \
+ (__pte((pte_val(_pte) & _PAGE_CHG_MASK) | pgprot_val(newprot)))
+
+#define pte_none(pte) ((pte_val(pte) & ~_PAGE_HPTEFLAGS) == 0)
+#define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT)
+
+/* pte_clear moved to later in this file */
+
+#define pte_pfn(x) ((unsigned long)((pte_val(x)>>PTE_RPN_SHIFT)))
+#define pte_page(x) pfn_to_page(pte_pfn(x))
+
+#define PMD_BAD_BITS (PTE_TABLE_SIZE-1)
+#define PUD_BAD_BITS (PMD_TABLE_SIZE-1)
+
+#define pmd_set(pmdp, pmdval) (pmd_val(*(pmdp)) = (pmdval))
+#define pmd_none(pmd) (!pmd_val(pmd))
+#define pmd_bad(pmd) (!is_kernel_addr(pmd_val(pmd)) \
+ || (pmd_val(pmd) & PMD_BAD_BITS))
+#define pmd_present(pmd) (pmd_val(pmd) != 0)
+#define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0)
+#define pmd_page_vaddr(pmd) (pmd_val(pmd) & ~PMD_MASKED_BITS)
+#define pmd_page(pmd) virt_to_page(pmd_page_vaddr(pmd))
+
+#define pud_set(pudp, pudval) (pud_val(*(pudp)) = (pudval))
+#define pud_none(pud) (!pud_val(pud))
+#define pud_bad(pud) (!is_kernel_addr(pud_val(pud)) \
+ || (pud_val(pud) & PUD_BAD_BITS))
+#define pud_present(pud) (pud_val(pud) != 0)
+#define pud_clear(pudp) (pud_val(*(pudp)) = 0)
+#define pud_page_vaddr(pud) (pud_val(pud) & ~PUD_MASKED_BITS)
+#define pud_page(pud) virt_to_page(pud_page_vaddr(pud))
+
+#define pgd_set(pgdp, pudp) ({pgd_val(*(pgdp)) = (unsigned long)(pudp);})
+
+/*
+ * Find an entry in a page-table-directory. We combine the address region
+ * (the high order N bits) and the pgd portion of the address.
+ */
+/* to avoid overflow in free_pgtables we don't use PTRS_PER_PGD here */
+#define pgd_index(address) (((address) >> (PGDIR_SHIFT)) & 0x1ff)
+
+#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
+
+#define pmd_offset(pudp,addr) \
+ (((pmd_t *) pud_page_vaddr(*(pudp))) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)))
+
+#define pte_offset_kernel(dir,addr) \
+ (((pte_t *) pmd_page_vaddr(*(dir))) + (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))
+
+#define pte_offset_map(dir,addr) pte_offset_kernel((dir), (addr))
+#define pte_offset_map_nested(dir,addr) pte_offset_kernel((dir), (addr))
+#define pte_unmap(pte) do { } while(0)
+#define pte_unmap_nested(pte) do { } while(0)
+
+/* to find an entry in a kernel page-table-directory */
+/* This now only contains the vmalloc pages */
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+
+/*
+ * The following only work if pte_present() is true.
+ * Undefined behaviour if not..
+ */
+static inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_USER;}
+static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW;}
+static inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_EXEC;}
+static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY;}
+static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED;}
+static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE;}
+
+static inline void pte_uncache(pte_t pte) { pte_val(pte) |= _PAGE_NO_CACHE; }
+static inline void pte_cache(pte_t pte) { pte_val(pte) &= ~_PAGE_NO_CACHE; }
+
+static inline pte_t pte_rdprotect(pte_t pte) {
+ pte_val(pte) &= ~_PAGE_USER; return pte; }
+static inline pte_t pte_exprotect(pte_t pte) {
+ pte_val(pte) &= ~_PAGE_EXEC; return pte; }
+static inline pte_t pte_wrprotect(pte_t pte) {
+ pte_val(pte) &= ~(_PAGE_RW); return pte; }
+static inline pte_t pte_mkclean(pte_t pte) {
+ pte_val(pte) &= ~(_PAGE_DIRTY); return pte; }
+static inline pte_t pte_mkold(pte_t pte) {
+ pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
+static inline pte_t pte_mkread(pte_t pte) {
+ pte_val(pte) |= _PAGE_USER; return pte; }
+static inline pte_t pte_mkexec(pte_t pte) {
+ pte_val(pte) |= _PAGE_USER | _PAGE_EXEC; return pte; }
+static inline pte_t pte_mkwrite(pte_t pte) {
+ pte_val(pte) |= _PAGE_RW; return pte; }
+static inline pte_t pte_mkdirty(pte_t pte) {
+ pte_val(pte) |= _PAGE_DIRTY; return pte; }
+static inline pte_t pte_mkyoung(pte_t pte) {
+ pte_val(pte) |= _PAGE_ACCESSED; return pte; }
+static inline pte_t pte_mkhuge(pte_t pte) {
+ return pte; }
+
+/* Atomic PTE updates */
+static inline unsigned long pte_update(struct mm_struct *mm,
+ unsigned long addr,
+ pte_t *ptep, unsigned long clr,
+ int huge)
+{
+ unsigned long old, tmp;
+
+ __asm__ __volatile__(
+ "1: ldarx %0,0,%3 # pte_update\n\
+ andi. %1,%0,%6\n\
+ bne- 1b \n\
+ andc %1,%0,%4 \n\
+ stdcx. %1,0,%3 \n\
+ bne- 1b"
+ : "=&r" (old), "=&r" (tmp), "=m" (*ptep)
+ : "r" (ptep), "r" (clr), "m" (*ptep), "i" (_PAGE_BUSY)
+ : "cc" );
+
+ if (old & _PAGE_HASHPTE)
+ hpte_need_flush(mm, addr, ptep, old, huge);
+ return old;
+}
+
+static inline int __ptep_test_and_clear_young(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
+{
+ unsigned long old;
+
+ if ((pte_val(*ptep) & (_PAGE_ACCESSED | _PAGE_HASHPTE)) == 0)
+ return 0;
+ old = pte_update(mm, addr, ptep, _PAGE_ACCESSED, 0);
+ return (old & _PAGE_ACCESSED) != 0;
+}
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
+#define ptep_test_and_clear_young(__vma, __addr, __ptep) \
+({ \
+ int __r; \
+ __r = __ptep_test_and_clear_young((__vma)->vm_mm, __addr, __ptep); \
+ __r; \
+})
+
+/*
+ * On RW/DIRTY bit transitions we can avoid flushing the hpte. For the
+ * moment we always flush but we need to fix hpte_update and test if the
+ * optimisation is worth it.
+ */
+static inline int __ptep_test_and_clear_dirty(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
+{
+ unsigned long old;
+
+ if ((pte_val(*ptep) & _PAGE_DIRTY) == 0)
+ return 0;
+ old = pte_update(mm, addr, ptep, _PAGE_DIRTY, 0);
+ return (old & _PAGE_DIRTY) != 0;
+}
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
+#define ptep_test_and_clear_dirty(__vma, __addr, __ptep) \
+({ \
+ int __r; \
+ __r = __ptep_test_and_clear_dirty((__vma)->vm_mm, __addr, __ptep); \
+ __r; \
+})
+
+#define __HAVE_ARCH_PTEP_SET_WRPROTECT
+static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep)
+{
+ unsigned long old;
+
+ if ((pte_val(*ptep) & _PAGE_RW) == 0)
+ return;
+ old = pte_update(mm, addr, ptep, _PAGE_RW, 0);
+}
+
+/*
+ * We currently remove entries from the hashtable regardless of whether
+ * the entry was young or dirty. The generic routines only flush if the
+ * entry was young or dirty which is not good enough.
+ *
+ * We should be more intelligent about this but for the moment we override
+ * these functions and force a tlb flush unconditionally
+ */
+#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
+#define ptep_clear_flush_young(__vma, __address, __ptep) \
+({ \
+ int __young = __ptep_test_and_clear_young((__vma)->vm_mm, __address, \
+ __ptep); \
+ __young; \
+})
+
+#define __HAVE_ARCH_PTEP_CLEAR_DIRTY_FLUSH
+#define ptep_clear_flush_dirty(__vma, __address, __ptep) \
+({ \
+ int __dirty = __ptep_test_and_clear_dirty((__vma)->vm_mm, __address, \
+ __ptep); \
+ __dirty; \
+})
+
+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
+static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
+{
+ unsigned long old = pte_update(mm, addr, ptep, ~0UL, 0);
+ return __pte(old);
+}
+
+static inline void pte_clear(struct mm_struct *mm, unsigned long addr,
+ pte_t * ptep)
+{
+ pte_update(mm, addr, ptep, ~0UL, 0);
+}
+
+/*
+ * set_pte stores a linux PTE into the linux page table.
+ */
+static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pte)
+{
+ if (pte_present(*ptep))
+ pte_clear(mm, addr, ptep);
+ pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
+ *ptep = pte;
+}
+
+/* Set the dirty and/or accessed bits atomically in a linux PTE, this
+ * function doesn't need to flush the hash entry
+ */
+#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
+static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry, int dirty)
+{
+ unsigned long bits = pte_val(entry) &
+ (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
+ unsigned long old, tmp;
+
+ __asm__ __volatile__(
+ "1: ldarx %0,0,%4\n\
+ andi. %1,%0,%6\n\
+ bne- 1b \n\
+ or %0,%3,%0\n\
+ stdcx. %0,0,%4\n\
+ bne- 1b"
+ :"=&r" (old), "=&r" (tmp), "=m" (*ptep)
+ :"r" (bits), "r" (ptep), "m" (*ptep), "i" (_PAGE_BUSY)
+ :"cc");
+}
+#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
+ do { \
+ __ptep_set_access_flags(__ptep, __entry, __dirty); \
+ flush_tlb_page_nohash(__vma, __address); \
+ } while(0)
+
+/*
+ * Macro to mark a page protection value as "uncacheable".
+ */
+#define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | _PAGE_NO_CACHE | _PAGE_GUARDED))
+
+struct file;
+extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
+ unsigned long size, pgprot_t vma_prot);
+#define __HAVE_PHYS_MEM_ACCESS_PROT
+
+#define __HAVE_ARCH_PTE_SAME
+#define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0)
+
+#define pte_ERROR(e) \
+ printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
+#define pmd_ERROR(e) \
+ printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
+#define pgd_ERROR(e) \
+ printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
+
+extern pgd_t swapper_pg_dir[];
+
+extern void paging_init(void);
+
+/* Encode and de-code a swap entry */
+#define __swp_type(entry) (((entry).val >> 1) & 0x3f)
+#define __swp_offset(entry) ((entry).val >> 8)
+#define __swp_entry(type, offset) ((swp_entry_t){((type)<< 1)|((offset)<<8)})
+#define __pte_to_swp_entry(pte) ((swp_entry_t){pte_val(pte) >> PTE_RPN_SHIFT})
+#define __swp_entry_to_pte(x) ((pte_t) { (x).val << PTE_RPN_SHIFT })
+#define pte_to_pgoff(pte) (pte_val(pte) >> PTE_RPN_SHIFT)
+#define pgoff_to_pte(off) ((pte_t) {((off) << PTE_RPN_SHIFT)|_PAGE_FILE})
+#define PTE_FILE_MAX_BITS (BITS_PER_LONG - PTE_RPN_SHIFT)
+
+/*
+ * kern_addr_valid is intended to indicate whether an address is a valid
+ * kernel address. Most 32-bit archs define it as always true (like this)
+ * but most 64-bit archs actually perform a test. What should we do here?
+ * The only use is in fs/ncpfs/dir.c
+ */
+#define kern_addr_valid(addr) (1)
+
+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
+ remap_pfn_range(vma, vaddr, pfn, size, prot)
+
+void pgtable_cache_init(void);
+
+/*
+ * find_linux_pte returns the address of a linux pte for a given
+ * effective address and directory. If not found, it returns zero.
+ */static inline pte_t *find_linux_pte(pgd_t *pgdir, unsigned long ea)
+{
+ pgd_t *pg;
+ pud_t *pu;
+ pmd_t *pm;
+ pte_t *pt = NULL;
+
+ pg = pgdir + pgd_index(ea);
+ if (!pgd_none(*pg)) {
+ pu = pud_offset(pg, ea);
+ if (!pud_none(*pu)) {
+ pm = pmd_offset(pu, ea);
+ if (pmd_present(*pm))
+ pt = pte_offset_kernel(pm, ea);
+ }
+ }
+ return pt;
+}
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_POWERPC_PGTABLE_PPC64_H_ */
diff --git a/include/asm-powerpc/pgtable.h b/include/asm-powerpc/pgtable.h
index 19edb69..78bf4ae 100644
--- a/include/asm-powerpc/pgtable.h
+++ b/include/asm-powerpc/pgtable.h
@@ -2,502 +2,15 @@
#define _ASM_POWERPC_PGTABLE_H
#ifdef __KERNEL__
-#ifndef CONFIG_PPC64
-#include <asm-ppc/pgtable.h>
+#if defined(CONFIG_PPC64)
+# include <asm/pgtable-ppc64.h>
#else
-
-/*
- * This file contains the functions and defines necessary to modify and use
- * the ppc64 hashed page table.
- */
-
-#ifndef __ASSEMBLY__
-#include <linux/stddef.h>
-#include <asm/processor.h> /* For TASK_SIZE */
-#include <asm/mmu.h>
-#include <asm/page.h>
-#include <asm/tlbflush.h>
-struct mm_struct;
-#endif /* __ASSEMBLY__ */
-
-#ifdef CONFIG_PPC_64K_PAGES
-#include <asm/pgtable-64k.h>
-#else
-#include <asm/pgtable-4k.h>
-#endif
-
-#define FIRST_USER_ADDRESS 0
-
-/*
- * Size of EA range mapped by our pagetables.
- */
-#define PGTABLE_EADDR_SIZE (PTE_INDEX_SIZE + PMD_INDEX_SIZE + \
- PUD_INDEX_SIZE + PGD_INDEX_SIZE + PAGE_SHIFT)
-#define PGTABLE_RANGE (1UL << PGTABLE_EADDR_SIZE)
-
-#if TASK_SIZE_USER64 > PGTABLE_RANGE
-#error TASK_SIZE_USER64 exceeds pagetable range
-#endif
-
-#if TASK_SIZE_USER64 > (1UL << (USER_ESID_BITS + SID_SHIFT))
-#error TASK_SIZE_USER64 exceeds user VSID range
-#endif
-
-/*
- * Define the address range of the vmalloc VM area.
- */
-#define VMALLOC_START ASM_CONST(0xD000000000000000)
-#define VMALLOC_SIZE ASM_CONST(0x80000000000)
-#define VMALLOC_END (VMALLOC_START + VMALLOC_SIZE)
-
-/*
- * Define the address range of the imalloc VM area.
- */
-#define PHBS_IO_BASE VMALLOC_END
-#define IMALLOC_BASE (PHBS_IO_BASE + 0x80000000ul) /* Reserve 2 gigs for PHBs */
-#define IMALLOC_END (VMALLOC_START + PGTABLE_RANGE)
-
-/*
- * Region IDs
- */
-#define REGION_SHIFT 60UL
-#define REGION_MASK (0xfUL << REGION_SHIFT)
-#define REGION_ID(ea) (((unsigned long)(ea)) >> REGION_SHIFT)
-
-#define VMALLOC_REGION_ID (REGION_ID(VMALLOC_START))
-#define KERNEL_REGION_ID (REGION_ID(PAGE_OFFSET))
-#define USER_REGION_ID (0UL)
-
-/*
- * Common bits in a linux-style PTE. These match the bits in the
- * (hardware-defined) PowerPC PTE as closely as possible. Additional
- * bits may be defined in pgtable-*.h
- */
-#define _PAGE_PRESENT 0x0001 /* software: pte contains a translation */
-#define _PAGE_USER 0x0002 /* matches one of the PP bits */
-#define _PAGE_FILE 0x0002 /* (!present only) software: pte holds file offset */
-#define _PAGE_EXEC 0x0004 /* No execute on POWER4 and newer (we invert) */
-#define _PAGE_GUARDED 0x0008
-#define _PAGE_COHERENT 0x0010 /* M: enforce memory coherence (SMP systems) */
-#define _PAGE_NO_CACHE 0x0020 /* I: cache inhibit */
-#define _PAGE_WRITETHRU 0x0040 /* W: cache write-through */
-#define _PAGE_DIRTY 0x0080 /* C: page changed */
-#define _PAGE_ACCESSED 0x0100 /* R: page referenced */
-#define _PAGE_RW 0x0200 /* software: user write access allowed */
-#define _PAGE_HASHPTE 0x0400 /* software: pte has an associated HPTE */
-#define _PAGE_BUSY 0x0800 /* software: PTE & hash are busy */
-
-#define _PAGE_BASE (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_COHERENT)
-
-#define _PAGE_WRENABLE (_PAGE_RW | _PAGE_DIRTY)
-
-/* __pgprot defined in asm-powerpc/page.h */
-#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
-
-#define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_RW | _PAGE_USER)
-#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_RW | _PAGE_USER | _PAGE_EXEC)
-#define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER)
-#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
-#define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER)
-#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
-#define PAGE_KERNEL __pgprot(_PAGE_BASE | _PAGE_WRENABLE)
-#define PAGE_KERNEL_CI __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \
- _PAGE_WRENABLE | _PAGE_NO_CACHE | _PAGE_GUARDED)
-#define PAGE_KERNEL_EXEC __pgprot(_PAGE_BASE | _PAGE_WRENABLE | _PAGE_EXEC)
-
-#define PAGE_AGP __pgprot(_PAGE_BASE | _PAGE_WRENABLE | _PAGE_NO_CACHE)
-#define HAVE_PAGE_AGP
-
-/* PTEIDX nibble */
-#define _PTEIDX_SECONDARY 0x8
-#define _PTEIDX_GROUP_IX 0x7
-
-
-/*
- * POWER4 and newer have per page execute protection, older chips can only
- * do this on a segment (256MB) basis.
- *
- * Also, write permissions imply read permissions.
- * This is the closest we can get..
- *
- * Note due to the way vm flags are laid out, the bits are XWR
- */
-#define __P000 PAGE_NONE
-#define __P001 PAGE_READONLY
-#define __P010 PAGE_COPY
-#define __P011 PAGE_COPY
-#define __P100 PAGE_READONLY_X
-#define __P101 PAGE_READONLY_X
-#define __P110 PAGE_COPY_X
-#define __P111 PAGE_COPY_X
-
-#define __S000 PAGE_NONE
-#define __S001 PAGE_READONLY
-#define __S010 PAGE_SHARED
-#define __S011 PAGE_SHARED
-#define __S100 PAGE_READONLY_X
-#define __S101 PAGE_READONLY_X
-#define __S110 PAGE_SHARED_X
-#define __S111 PAGE_SHARED_X
-
-#ifndef __ASSEMBLY__
-
-/*
- * ZERO_PAGE is a global shared page that is always zero: used
- * for zero-mapped memory areas etc..
- */
-extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)];
-#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
-#endif /* __ASSEMBLY__ */
-
-#ifdef CONFIG_HUGETLB_PAGE
-
-#define HAVE_ARCH_UNMAPPED_AREA
-#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
-
+# include <asm/pgtable-ppc32.h>
#endif
#ifndef __ASSEMBLY__
-
-/*
- * Conversion functions: convert a page and protection to a page entry,
- * and a page entry and page directory to the page they refer to.
- *
- * mk_pte takes a (struct page *) as input
- */
-#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
-
-static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot)
-{
- pte_t pte;
-
-
- pte_val(pte) = (pfn << PTE_RPN_SHIFT) | pgprot_val(pgprot);
- return pte;
-}
-
-#define pte_modify(_pte, newprot) \
- (__pte((pte_val(_pte) & _PAGE_CHG_MASK) | pgprot_val(newprot)))
-
-#define pte_none(pte) ((pte_val(pte) & ~_PAGE_HPTEFLAGS) == 0)
-#define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT)
-
-/* pte_clear moved to later in this file */
-
-#define pte_pfn(x) ((unsigned long)((pte_val(x)>>PTE_RPN_SHIFT)))
-#define pte_page(x) pfn_to_page(pte_pfn(x))
-
-#define PMD_BAD_BITS (PTE_TABLE_SIZE-1)
-#define PUD_BAD_BITS (PMD_TABLE_SIZE-1)
-
-#define pmd_set(pmdp, pmdval) (pmd_val(*(pmdp)) = (pmdval))
-#define pmd_none(pmd) (!pmd_val(pmd))
-#define pmd_bad(pmd) (!is_kernel_addr(pmd_val(pmd)) \
- || (pmd_val(pmd) & PMD_BAD_BITS))
-#define pmd_present(pmd) (pmd_val(pmd) != 0)
-#define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0)
-#define pmd_page_vaddr(pmd) (pmd_val(pmd) & ~PMD_MASKED_BITS)
-#define pmd_page(pmd) virt_to_page(pmd_page_vaddr(pmd))
-
-#define pud_set(pudp, pudval) (pud_val(*(pudp)) = (pudval))
-#define pud_none(pud) (!pud_val(pud))
-#define pud_bad(pud) (!is_kernel_addr(pud_val(pud)) \
- || (pud_val(pud) & PUD_BAD_BITS))
-#define pud_present(pud) (pud_val(pud) != 0)
-#define pud_clear(pudp) (pud_val(*(pudp)) = 0)
-#define pud_page_vaddr(pud) (pud_val(pud) & ~PUD_MASKED_BITS)
-#define pud_page(pud) virt_to_page(pud_page_vaddr(pud))
-
-#define pgd_set(pgdp, pudp) ({pgd_val(*(pgdp)) = (unsigned long)(pudp);})
-
-/*
- * Find an entry in a page-table-directory. We combine the address region
- * (the high order N bits) and the pgd portion of the address.
- */
-/* to avoid overflow in free_pgtables we don't use PTRS_PER_PGD here */
-#define pgd_index(address) (((address) >> (PGDIR_SHIFT)) & 0x1ff)
-
-#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
-
-#define pmd_offset(pudp,addr) \
- (((pmd_t *) pud_page_vaddr(*(pudp))) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)))
-
-#define pte_offset_kernel(dir,addr) \
- (((pte_t *) pmd_page_vaddr(*(dir))) + (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))
-
-#define pte_offset_map(dir,addr) pte_offset_kernel((dir), (addr))
-#define pte_offset_map_nested(dir,addr) pte_offset_kernel((dir), (addr))
-#define pte_unmap(pte) do { } while(0)
-#define pte_unmap_nested(pte) do { } while(0)
-
-/* to find an entry in a kernel page-table-directory */
-/* This now only contains the vmalloc pages */
-#define pgd_offset_k(address) pgd_offset(&init_mm, address)
-
-/*
- * The following only work if pte_present() is true.
- * Undefined behaviour if not..
- */
-static inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_USER;}
-static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW;}
-static inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_EXEC;}
-static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY;}
-static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED;}
-static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE;}
-
-static inline void pte_uncache(pte_t pte) { pte_val(pte) |= _PAGE_NO_CACHE; }
-static inline void pte_cache(pte_t pte) { pte_val(pte) &= ~_PAGE_NO_CACHE; }
-
-static inline pte_t pte_rdprotect(pte_t pte) {
- pte_val(pte) &= ~_PAGE_USER; return pte; }
-static inline pte_t pte_exprotect(pte_t pte) {
- pte_val(pte) &= ~_PAGE_EXEC; return pte; }
-static inline pte_t pte_wrprotect(pte_t pte) {
- pte_val(pte) &= ~(_PAGE_RW); return pte; }
-static inline pte_t pte_mkclean(pte_t pte) {
- pte_val(pte) &= ~(_PAGE_DIRTY); return pte; }
-static inline pte_t pte_mkold(pte_t pte) {
- pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
-static inline pte_t pte_mkread(pte_t pte) {
- pte_val(pte) |= _PAGE_USER; return pte; }
-static inline pte_t pte_mkexec(pte_t pte) {
- pte_val(pte) |= _PAGE_USER | _PAGE_EXEC; return pte; }
-static inline pte_t pte_mkwrite(pte_t pte) {
- pte_val(pte) |= _PAGE_RW; return pte; }
-static inline pte_t pte_mkdirty(pte_t pte) {
- pte_val(pte) |= _PAGE_DIRTY; return pte; }
-static inline pte_t pte_mkyoung(pte_t pte) {
- pte_val(pte) |= _PAGE_ACCESSED; return pte; }
-static inline pte_t pte_mkhuge(pte_t pte) {
- return pte; }
-
-/* Atomic PTE updates */
-static inline unsigned long pte_update(struct mm_struct *mm,
- unsigned long addr,
- pte_t *ptep, unsigned long clr,
- int huge)
-{
- unsigned long old, tmp;
-
- __asm__ __volatile__(
- "1: ldarx %0,0,%3 # pte_update\n\
- andi. %1,%0,%6\n\
- bne- 1b \n\
- andc %1,%0,%4 \n\
- stdcx. %1,0,%3 \n\
- bne- 1b"
- : "=&r" (old), "=&r" (tmp), "=m" (*ptep)
- : "r" (ptep), "r" (clr), "m" (*ptep), "i" (_PAGE_BUSY)
- : "cc" );
-
- if (old & _PAGE_HASHPTE)
- hpte_need_flush(mm, addr, ptep, old, huge);
- return old;
-}
-
-static inline int __ptep_test_and_clear_young(struct mm_struct *mm,
- unsigned long addr, pte_t *ptep)
-{
- unsigned long old;
-
- if ((pte_val(*ptep) & (_PAGE_ACCESSED | _PAGE_HASHPTE)) == 0)
- return 0;
- old = pte_update(mm, addr, ptep, _PAGE_ACCESSED, 0);
- return (old & _PAGE_ACCESSED) != 0;
-}
-#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
-#define ptep_test_and_clear_young(__vma, __addr, __ptep) \
-({ \
- int __r; \
- __r = __ptep_test_and_clear_young((__vma)->vm_mm, __addr, __ptep); \
- __r; \
-})
-
-/*
- * On RW/DIRTY bit transitions we can avoid flushing the hpte. For the
- * moment we always flush but we need to fix hpte_update and test if the
- * optimisation is worth it.
- */
-static inline int __ptep_test_and_clear_dirty(struct mm_struct *mm,
- unsigned long addr, pte_t *ptep)
-{
- unsigned long old;
-
- if ((pte_val(*ptep) & _PAGE_DIRTY) == 0)
- return 0;
- old = pte_update(mm, addr, ptep, _PAGE_DIRTY, 0);
- return (old & _PAGE_DIRTY) != 0;
-}
-#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
-#define ptep_test_and_clear_dirty(__vma, __addr, __ptep) \
-({ \
- int __r; \
- __r = __ptep_test_and_clear_dirty((__vma)->vm_mm, __addr, __ptep); \
- __r; \
-})
-
-#define __HAVE_ARCH_PTEP_SET_WRPROTECT
-static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
- pte_t *ptep)
-{
- unsigned long old;
-
- if ((pte_val(*ptep) & _PAGE_RW) == 0)
- return;
- old = pte_update(mm, addr, ptep, _PAGE_RW, 0);
-}
-
-/*
- * We currently remove entries from the hashtable regardless of whether
- * the entry was young or dirty. The generic routines only flush if the
- * entry was young or dirty which is not good enough.
- *
- * We should be more intelligent about this but for the moment we override
- * these functions and force a tlb flush unconditionally
- */
-#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
-#define ptep_clear_flush_young(__vma, __address, __ptep) \
-({ \
- int __young = __ptep_test_and_clear_young((__vma)->vm_mm, __address, \
- __ptep); \
- __young; \
-})
-
-#define __HAVE_ARCH_PTEP_CLEAR_DIRTY_FLUSH
-#define ptep_clear_flush_dirty(__vma, __address, __ptep) \
-({ \
- int __dirty = __ptep_test_and_clear_dirty((__vma)->vm_mm, __address, \
- __ptep); \
- __dirty; \
-})
-
-#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
-static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
- unsigned long addr, pte_t *ptep)
-{
- unsigned long old = pte_update(mm, addr, ptep, ~0UL, 0);
- return __pte(old);
-}
-
-static inline void pte_clear(struct mm_struct *mm, unsigned long addr,
- pte_t * ptep)
-{
- pte_update(mm, addr, ptep, ~0UL, 0);
-}
-
-/*
- * set_pte stores a linux PTE into the linux page table.
- */
-static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
- pte_t *ptep, pte_t pte)
-{
- if (pte_present(*ptep))
- pte_clear(mm, addr, ptep);
- pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
- *ptep = pte;
-}
-
-/* Set the dirty and/or accessed bits atomically in a linux PTE, this
- * function doesn't need to flush the hash entry
- */
-#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
-static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry, int dirty)
-{
- unsigned long bits = pte_val(entry) &
- (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
- unsigned long old, tmp;
-
- __asm__ __volatile__(
- "1: ldarx %0,0,%4\n\
- andi. %1,%0,%6\n\
- bne- 1b \n\
- or %0,%3,%0\n\
- stdcx. %0,0,%4\n\
- bne- 1b"
- :"=&r" (old), "=&r" (tmp), "=m" (*ptep)
- :"r" (bits), "r" (ptep), "m" (*ptep), "i" (_PAGE_BUSY)
- :"cc");
-}
-#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
- do { \
- __ptep_set_access_flags(__ptep, __entry, __dirty); \
- flush_tlb_page_nohash(__vma, __address); \
- } while(0)
-
-/*
- * Macro to mark a page protection value as "uncacheable".
- */
-#define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | _PAGE_NO_CACHE | _PAGE_GUARDED))
-
-struct file;
-extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
- unsigned long size, pgprot_t vma_prot);
-#define __HAVE_PHYS_MEM_ACCESS_PROT
-
-#define __HAVE_ARCH_PTE_SAME
-#define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0)
-
-#define pte_ERROR(e) \
- printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
-#define pmd_ERROR(e) \
- printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
-#define pgd_ERROR(e) \
- printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
-
-extern pgd_t swapper_pg_dir[];
-
-extern void paging_init(void);
-
-/* Encode and de-code a swap entry */
-#define __swp_type(entry) (((entry).val >> 1) & 0x3f)
-#define __swp_offset(entry) ((entry).val >> 8)
-#define __swp_entry(type, offset) ((swp_entry_t){((type)<< 1)|((offset)<<8)})
-#define __pte_to_swp_entry(pte) ((swp_entry_t){pte_val(pte) >> PTE_RPN_SHIFT})
-#define __swp_entry_to_pte(x) ((pte_t) { (x).val << PTE_RPN_SHIFT })
-#define pte_to_pgoff(pte) (pte_val(pte) >> PTE_RPN_SHIFT)
-#define pgoff_to_pte(off) ((pte_t) {((off) << PTE_RPN_SHIFT)|_PAGE_FILE})
-#define PTE_FILE_MAX_BITS (BITS_PER_LONG - PTE_RPN_SHIFT)
-
-/*
- * kern_addr_valid is intended to indicate whether an address is a valid
- * kernel address. Most 32-bit archs define it as always true (like this)
- * but most 64-bit archs actually perform a test. What should we do here?
- * The only use is in fs/ncpfs/dir.c
- */
-#define kern_addr_valid(addr) (1)
-
-#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
- remap_pfn_range(vma, vaddr, pfn, size, prot)
-
-void pgtable_cache_init(void);
-
-/*
- * find_linux_pte returns the address of a linux pte for a given
- * effective address and directory. If not found, it returns zero.
- */static inline pte_t *find_linux_pte(pgd_t *pgdir, unsigned long ea)
-{
- pgd_t *pg;
- pud_t *pu;
- pmd_t *pm;
- pte_t *pt = NULL;
-
- pg = pgdir + pgd_index(ea);
- if (!pgd_none(*pg)) {
- pu = pud_offset(pg, ea);
- if (!pud_none(*pu)) {
- pm = pmd_offset(pu, ea);
- if (pmd_present(*pm))
- pt = pte_offset_kernel(pm, ea);
- }
- }
- return pt;
-}
-
-
#include <asm-generic/pgtable.h>
-
#endif /* __ASSEMBLY__ */
-#endif /* CONFIG_PPC64 */
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_PGTABLE_H */
diff --git a/include/asm-powerpc/pmac_feature.h b/include/asm-powerpc/pmac_feature.h
index d3599cc..d43d91b 100644
--- a/include/asm-powerpc/pmac_feature.h
+++ b/include/asm-powerpc/pmac_feature.h
@@ -146,7 +146,7 @@
static inline long pmac_call_feature(int selector, struct device_node* node,
long param, long value)
{
- if (!ppc_md.feature_call)
+ if (!ppc_md.feature_call || !machine_is(powermac))
return -ENODEV;
return ppc_md.feature_call(selector, node, param, value);
}
diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h
index ec400f6..6845af9 100644
--- a/include/asm-powerpc/prom.h
+++ b/include/asm-powerpc/prom.h
@@ -20,7 +20,6 @@
#include <linux/platform_device.h>
#include <asm/irq.h>
#include <asm/atomic.h>
-#include <asm/io.h>
/* Definitions used by the flattened device tree */
#define OF_DT_HEADER 0xd00dfeed /* marker */
@@ -334,30 +333,17 @@
struct pci_dev;
extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
-static inline int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
-{
- int irq = irq_of_parse_and_map(dev, index);
+extern int of_irq_to_resource(struct device_node *dev, int index,
+ struct resource *r);
- /* Only dereference the resource if both the
- * resource and the irq are valid. */
- if (r && irq != NO_IRQ) {
- r->start = r->end = irq;
- r->flags = IORESOURCE_IRQ;
- }
-
- return irq;
-}
-
-static inline void __iomem *of_iomap(struct device_node *np, int index)
-{
- struct resource res;
-
- if (of_address_to_resource(np, index, &res))
- return NULL;
-
- return ioremap(res.start, 1 + res.end - res.start);
-}
-
+/**
+ * of_iomap - Maps the memory mapped IO for a given device_node
+ * @device: the device whose io range will be mapped
+ * @index: index of the io range
+ *
+ * Returns a pointer to the mapped memory
+ */
+extern void __iomem *of_iomap(struct device_node *device, int index);
#endif /* __KERNEL__ */
#endif /* _POWERPC_PROM_H */
diff --git a/include/asm-powerpc/ps3.h b/include/asm-powerpc/ps3.h
index 821581a..13c372d 100644
--- a/include/asm-powerpc/ps3.h
+++ b/include/asm-powerpc/ps3.h
@@ -167,26 +167,31 @@
PS3_BINDING_CPU_1 = 1,
};
-int ps3_alloc_io_irq(enum ps3_cpu_binding cpu, unsigned int interrupt_id,
+int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
unsigned int *virq);
-int ps3_free_io_irq(unsigned int virq);
-int ps3_alloc_event_irq(enum ps3_cpu_binding cpu, unsigned int *virq);
-int ps3_free_event_irq(unsigned int virq);
+int ps3_virq_destroy(unsigned int virq);
+int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
+ unsigned int *virq);
+int ps3_irq_plug_destroy(unsigned int virq);
+int ps3_event_receive_port_setup(enum ps3_cpu_binding cpu, unsigned int *virq);
+int ps3_event_receive_port_destroy(unsigned int virq);
int ps3_send_event_locally(unsigned int virq);
-int ps3_connect_event_irq(enum ps3_cpu_binding cpu,
+
+int ps3_io_irq_setup(enum ps3_cpu_binding cpu, unsigned int interrupt_id,
+ unsigned int *virq);
+int ps3_io_irq_destroy(unsigned int virq);
+int ps3_vuart_irq_setup(enum ps3_cpu_binding cpu, void* virt_addr_bmp,
+ unsigned int *virq);
+int ps3_vuart_irq_destroy(unsigned int virq);
+int ps3_spe_irq_setup(enum ps3_cpu_binding cpu, unsigned long spe_id,
+ unsigned int class, unsigned int *virq);
+int ps3_spe_irq_destroy(unsigned int virq);
+
+int ps3_sb_event_receive_port_setup(enum ps3_cpu_binding cpu,
const struct ps3_device_id *did, unsigned int interrupt_id,
unsigned int *virq);
-int ps3_disconnect_event_irq(const struct ps3_device_id *did,
+int ps3_sb_event_receive_port_destroy(const struct ps3_device_id *did,
unsigned int interrupt_id, unsigned int virq);
-int ps3_alloc_vuart_irq(enum ps3_cpu_binding cpu, void* virt_addr_bmp,
- unsigned int *virq);
-int ps3_free_vuart_irq(unsigned int virq);
-int ps3_alloc_spe_irq(enum ps3_cpu_binding cpu, unsigned long spe_id,
- unsigned int class, unsigned int *virq);
-int ps3_free_spe_irq(unsigned int virq);
-int ps3_alloc_irq(enum ps3_cpu_binding cpu, unsigned long outlet,
- unsigned int *virq);
-int ps3_free_irq(unsigned int virq);
/* lv1 result codes */
diff --git a/include/asm-powerpc/suspend.h b/include/asm-powerpc/suspend.h
new file mode 100644
index 0000000..cbf2c94
--- /dev/null
+++ b/include/asm-powerpc/suspend.h
@@ -0,0 +1,9 @@
+#ifndef __ASM_POWERPC_SUSPEND_H
+#define __ASM_POWERPC_SUSPEND_H
+
+static inline int arch_prepare_suspend(void) { return 0; }
+
+void save_processor_state(void);
+void restore_processor_state(void);
+
+#endif /* __ASM_POWERPC_SUSPEND_H */
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
index d3e0906..09621f6 100644
--- a/include/asm-powerpc/system.h
+++ b/include/asm-powerpc/system.h
@@ -7,7 +7,6 @@
#include <linux/kernel.h>
#include <asm/hw_irq.h>
-#include <asm/atomic.h>
/*
* Memory barrier.
@@ -227,6 +226,29 @@
return prev;
}
+/*
+ * Atomic exchange
+ *
+ * Changes the memory location '*ptr' to be val and returns
+ * the previous value stored there.
+ */
+static __inline__ unsigned long
+__xchg_u32_local(volatile void *p, unsigned long val)
+{
+ unsigned long prev;
+
+ __asm__ __volatile__(
+"1: lwarx %0,0,%2 \n"
+ PPC405_ERR77(0,%2)
+" stwcx. %3,0,%2 \n\
+ bne- 1b"
+ : "=&r" (prev), "+m" (*(volatile unsigned int *)p)
+ : "r" (p), "r" (val)
+ : "cc", "memory");
+
+ return prev;
+}
+
#ifdef CONFIG_PPC64
static __inline__ unsigned long
__xchg_u64(volatile void *p, unsigned long val)
@@ -246,6 +268,23 @@
return prev;
}
+
+static __inline__ unsigned long
+__xchg_u64_local(volatile void *p, unsigned long val)
+{
+ unsigned long prev;
+
+ __asm__ __volatile__(
+"1: ldarx %0,0,%2 \n"
+ PPC405_ERR77(0,%2)
+" stdcx. %3,0,%2 \n\
+ bne- 1b"
+ : "=&r" (prev), "+m" (*(volatile unsigned long *)p)
+ : "r" (p), "r" (val)
+ : "cc", "memory");
+
+ return prev;
+}
#endif
/*
@@ -269,13 +308,32 @@
return x;
}
+static __inline__ unsigned long
+__xchg_local(volatile void *ptr, unsigned long x, unsigned int size)
+{
+ switch (size) {
+ case 4:
+ return __xchg_u32_local(ptr, x);
+#ifdef CONFIG_PPC64
+ case 8:
+ return __xchg_u64_local(ptr, x);
+#endif
+ }
+ __xchg_called_with_bad_pointer();
+ return x;
+}
#define xchg(ptr,x) \
({ \
__typeof__(*(ptr)) _x_ = (x); \
(__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, sizeof(*(ptr))); \
})
-#define tas(ptr) (xchg((ptr),1))
+#define xchg_local(ptr,x) \
+ ({ \
+ __typeof__(*(ptr)) _x_ = (x); \
+ (__typeof__(*(ptr))) __xchg_local((ptr), \
+ (unsigned long)_x_, sizeof(*(ptr))); \
+ })
/*
* Compare and exchange - if *p == old, set it to new,
@@ -306,6 +364,28 @@
return prev;
}
+static __inline__ unsigned long
+__cmpxchg_u32_local(volatile unsigned int *p, unsigned long old,
+ unsigned long new)
+{
+ unsigned int prev;
+
+ __asm__ __volatile__ (
+"1: lwarx %0,0,%2 # __cmpxchg_u32\n\
+ cmpw 0,%0,%3\n\
+ bne- 2f\n"
+ PPC405_ERR77(0,%2)
+" stwcx. %4,0,%2\n\
+ bne- 1b"
+ "\n\
+2:"
+ : "=&r" (prev), "+m" (*p)
+ : "r" (p), "r" (old), "r" (new)
+ : "cc", "memory");
+
+ return prev;
+}
+
#ifdef CONFIG_PPC64
static __inline__ unsigned long
__cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new)
@@ -328,6 +408,27 @@
return prev;
}
+
+static __inline__ unsigned long
+__cmpxchg_u64_local(volatile unsigned long *p, unsigned long old,
+ unsigned long new)
+{
+ unsigned long prev;
+
+ __asm__ __volatile__ (
+"1: ldarx %0,0,%2 # __cmpxchg_u64\n\
+ cmpd 0,%0,%3\n\
+ bne- 2f\n\
+ stdcx. %4,0,%2\n\
+ bne- 1b"
+ "\n\
+2:"
+ : "=&r" (prev), "+m" (*p)
+ : "r" (p), "r" (old), "r" (new)
+ : "cc", "memory");
+
+ return prev;
+}
#endif
/* This function doesn't exist, so you'll get a linker error
@@ -350,6 +451,22 @@
return old;
}
+static __inline__ unsigned long
+__cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new,
+ unsigned int size)
+{
+ switch (size) {
+ case 4:
+ return __cmpxchg_u32_local(ptr, old, new);
+#ifdef CONFIG_PPC64
+ case 8:
+ return __cmpxchg_u64_local(ptr, old, new);
+#endif
+ }
+ __cmpxchg_called_with_bad_pointer();
+ return old;
+}
+
#define cmpxchg(ptr,o,n) \
({ \
__typeof__(*(ptr)) _o_ = (o); \
@@ -358,6 +475,15 @@
(unsigned long)_n_, sizeof(*(ptr))); \
})
+
+#define cmpxchg_local(ptr,o,n) \
+ ({ \
+ __typeof__(*(ptr)) _o_ = (o); \
+ __typeof__(*(ptr)) _n_ = (n); \
+ (__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_, \
+ (unsigned long)_n_, sizeof(*(ptr))); \
+ })
+
#ifdef CONFIG_PPC64
/*
* We handle most unaligned accesses in hardware. On the other hand
diff --git a/include/asm-powerpc/tsi108.h b/include/asm-powerpc/tsi108.h
index 4e95d15..f8b6079 100644
--- a/include/asm-powerpc/tsi108.h
+++ b/include/asm-powerpc/tsi108.h
@@ -68,8 +68,17 @@
#define TSI108_PB_ERRCS_ES (1 << 1)
#define TSI108_PB_ISR_PBS_RD_ERR (1 << 8)
-#define TSI108_PCI_CFG_BASE_PHYS (0xfb000000)
#define TSI108_PCI_CFG_SIZE (0x01000000)
+
+/*
+ * PHY Configuration Options
+ *
+ * Specify "bcm54xx" in the compatible property of your device tree phy
+ * nodes if your board uses the Broadcom PHYs
+ */
+#define TSI108_PHY_MV88E 0 /* Marvel 88Exxxx PHY */
+#define TSI108_PHY_BCM54XX 1 /* Broardcom BCM54xx PHY */
+
/* Global variables */
extern u32 tsi108_pci_cfg_base;
@@ -93,6 +102,7 @@
u16 phy; /* phy address */
u16 irq_num; /* irq number */
u8 mac_addr[6]; /* phy mac address */
+ u16 phy_type; /* type of phy on board */
} hw_info;
extern u32 get_vir_csrbase(void);
diff --git a/include/asm-powerpc/tsi108_pci.h b/include/asm-powerpc/tsi108_pci.h
new file mode 100644
index 0000000..a9f92f7
--- /dev/null
+++ b/include/asm-powerpc/tsi108_pci.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2007 IBM Corp
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _ASM_PPC_TSI108_PCI_H
+#define _ASM_PPC_TSI108_PCI_H
+
+#include <asm/tsi108.h>
+
+/* Register definitions */
+#define TSI108_PCI_P2O_BAR0 (TSI108_PCI_OFFSET + 0x10)
+#define TSI108_PCI_P2O_BAR0_UPPER (TSI108_PCI_OFFSET + 0x14)
+#define TSI108_PCI_P2O_BAR2 (TSI108_PCI_OFFSET + 0x18)
+#define TSI108_PCI_P2O_BAR2_UPPER (TSI108_PCI_OFFSET + 0x1c)
+#define TSI108_PCI_P2O_PAGE_SIZES (TSI108_PCI_OFFSET + 0x4c)
+#define TSI108_PCI_PFAB_BAR0 (TSI108_PCI_OFFSET + 0x204)
+#define TSI108_PCI_PFAB_BAR0_UPPER (TSI108_PCI_OFFSET + 0x208)
+#define TSI108_PCI_PFAB_IO (TSI108_PCI_OFFSET + 0x20c)
+#define TSI108_PCI_PFAB_IO_UPPER (TSI108_PCI_OFFSET + 0x210)
+#define TSI108_PCI_PFAB_MEM32 (TSI108_PCI_OFFSET + 0x214)
+#define TSI108_PCI_PFAB_PFM3 (TSI108_PCI_OFFSET + 0x220)
+#define TSI108_PCI_PFAB_PFM4 (TSI108_PCI_OFFSET + 0x230)
+
+extern int tsi108_setup_pci(struct device_node *dev, u32 cfg_phys, int primary);
+extern void tsi108_pci_int_init(struct device_node *node);
+extern void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc);
+extern void tsi108_clear_pci_cfg_error(void);
+
+#endif /* _ASM_PPC_TSI108_PCI_H */
diff --git a/include/asm-powerpc/udbg.h b/include/asm-powerpc/udbg.h
index d03d855..ce9d82f 100644
--- a/include/asm-powerpc/udbg.h
+++ b/include/asm-powerpc/udbg.h
@@ -47,6 +47,7 @@
extern void __init udbg_init_rtas_console(void);
extern void __init udbg_init_debug_beat(void);
extern void __init udbg_init_btext(void);
+extern void __init udbg_init_44x_as1(void);
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_UDBG_H */
diff --git a/include/asm-ppc/kdebug.h b/include/asm-ppc/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-ppc/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h
index b1fdbf4..bed452d 100644
--- a/include/asm-ppc/pgtable.h
+++ b/include/asm-ppc/pgtable.h
@@ -827,10 +827,6 @@
remap_pfn_range(vma, vaddr, pfn, size, prot)
#endif
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
/*
* No page table caches to initialise
*/
diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h
index 7389435..d84a3cf 100644
--- a/include/asm-ppc/system.h
+++ b/include/asm-ppc/system.h
@@ -6,7 +6,6 @@
#include <linux/kernel.h>
-#include <asm/atomic.h>
#include <asm/hw_irq.h>
/*
@@ -170,7 +169,6 @@
extern void __xchg_called_with_bad_pointer(void);
#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
-#define tas(ptr) (xchg((ptr),1))
static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
{
diff --git a/include/asm-s390/kdebug.h b/include/asm-s390/kdebug.h
index d2d7ad2..04418af 100644
--- a/include/asm-s390/kdebug.h
+++ b/include/asm-s390/kdebug.h
@@ -8,21 +8,6 @@
struct pt_regs;
-struct die_args {
- struct pt_regs *regs;
- const char *str;
- long err;
- int trapnr;
- int signr;
-};
-
-/* Note - you should never unregister because that can race with NMIs.
- * If you really want to do it first unregister - then synchronize_sched
- * - then free.
- */
-extern int register_die_notifier(struct notifier_block *);
-extern int unregister_die_notifier(struct notifier_block *);
-
/*
* These are only here because kprobes.c wants them to implement a
* blatant layering violation. Will hopefully go away soon once all
@@ -37,8 +22,6 @@
return 0;
}
-extern struct atomic_notifier_head s390die_chain;
-
enum die_val {
DIE_OOPS = 1,
DIE_BPT,
@@ -54,19 +37,6 @@
DIE_NMI_IPI,
};
-static inline int notify_die(enum die_val val, const char *str,
- struct pt_regs *regs, long err, int trap, int sig)
-{
- struct die_args args = {
- .regs = regs,
- .str = str,
- .err = err,
- .trapnr = trap,
- .signr = sig
- };
- return atomic_notifier_call_chain(&s390die_chain, val, &args);
-}
-
extern void die(const char *, struct pt_regs *, long);
#endif
diff --git a/include/asm-s390/kexec.h b/include/asm-s390/kexec.h
index 9c35c8a..7592af7 100644
--- a/include/asm-s390/kexec.h
+++ b/include/asm-s390/kexec.h
@@ -34,8 +34,6 @@
/* The native architecture */
#define KEXEC_ARCH KEXEC_ARCH_S390
-#define MAX_NOTE_BYTES 1024
-
/* Provide a dummy definition to avoid build failures. */
static inline void crash_setup_regs(struct pt_regs *newregs,
struct pt_regs *oldregs) { }
diff --git a/include/asm-sh/kdebug.h b/include/asm-sh/kdebug.h
index ef009ba..493c206 100644
--- a/include/asm-sh/kdebug.h
+++ b/include/asm-sh/kdebug.h
@@ -2,6 +2,7 @@
#define __ASM_SH_KDEBUG_H
#include <linux/notifier.h>
+#include <asm-generic/kdebug.h>
struct pt_regs;
diff --git a/include/asm-sh/kexec.h b/include/asm-sh/kexec.h
index da36a75..00f4260 100644
--- a/include/asm-sh/kexec.h
+++ b/include/asm-sh/kexec.h
@@ -26,8 +26,6 @@
/* The native architecture */
#define KEXEC_ARCH KEXEC_ARCH_SH
-#define MAX_NOTE_BYTES 1024
-
static inline void crash_setup_regs(struct pt_regs *newregs,
struct pt_regs *oldregs)
{
diff --git a/include/asm-sh/pgtable.h b/include/asm-sh/pgtable.h
index 184d7fc..5b523c7 100644
--- a/include/asm-sh/pgtable.h
+++ b/include/asm-sh/pgtable.h
@@ -568,10 +568,6 @@
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
struct mm_struct;
/*
diff --git a/include/asm-sh/system.h b/include/asm-sh/system.h
index 127af30..e7e96ee 100644
--- a/include/asm-sh/system.h
+++ b/include/asm-sh/system.h
@@ -82,16 +82,6 @@
}
#endif
-static inline unsigned long tas(volatile int *m)
-{
- unsigned long retval;
-
- __asm__ __volatile__ ("tas.b @%1\n\t"
- "movt %0"
- : "=r" (retval): "r" (m): "t", "memory");
- return retval;
-}
-
/*
* A brief note on ctrl_barrier(), the control register write barrier.
*
diff --git a/include/asm-sh64/kdebug.h b/include/asm-sh64/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-sh64/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-sh64/pgtable.h b/include/asm-sh64/pgtable.h
index 6b97c4c..b875482 100644
--- a/include/asm-sh64/pgtable.h
+++ b/include/asm-sh64/pgtable.h
@@ -485,10 +485,6 @@
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
#endif /* !__ASSEMBLY__ */
/*
diff --git a/include/asm-sh64/system.h b/include/asm-sh64/system.h
index b1598c2..5ff9464 100644
--- a/include/asm-sh64/system.h
+++ b/include/asm-sh64/system.h
@@ -43,8 +43,6 @@
#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
-#define tas(ptr) (xchg((ptr), 1))
-
extern void __xchg_called_with_bad_pointer(void);
#define mb() __asm__ __volatile__ ("synco": : :"memory")
diff --git a/include/asm-sparc/kdebug.h b/include/asm-sparc/kdebug.h
index fba9248..404d807 100644
--- a/include/asm-sparc/kdebug.h
+++ b/include/asm-sparc/kdebug.h
@@ -66,4 +66,8 @@
#define KDEBUG_DUNNO2_OFF 0x8
#define KDEBUG_TEACH_OFF 0xc
+enum die_val {
+ DIE_UNUSED,
+};
+
#endif /* !(_SPARC_KDEBUG_H) */
diff --git a/include/asm-sparc/system.h b/include/asm-sparc/system.h
index 100c3ea..8b6d9c9 100644
--- a/include/asm-sparc/system.h
+++ b/include/asm-sparc/system.h
@@ -241,7 +241,6 @@
}
#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
-#define tas(ptr) (xchg((ptr),1))
extern void __xchg_called_with_bad_pointer(void);
diff --git a/include/asm-sparc64/Kbuild b/include/asm-sparc64/Kbuild
index a7f4440..854fd3a 100644
--- a/include/asm-sparc64/Kbuild
+++ b/include/asm-sparc64/Kbuild
@@ -8,7 +8,6 @@
header-y += asi.h
header-y += bbc.h
header-y += bpp.h
-header-y += const.h
header-y += display7seg.h
header-y += envctrl.h
header-y += ipc.h
diff --git a/include/asm-sparc64/atomic.h b/include/asm-sparc64/atomic.h
index 2f0bec2..3fb4e1f 100644
--- a/include/asm-sparc64/atomic.h
+++ b/include/asm-sparc64/atomic.h
@@ -9,6 +9,7 @@
#define __ARCH_SPARC64_ATOMIC__
#include <linux/types.h>
+#include <asm/system.h>
typedef struct { volatile int counter; } atomic_t;
typedef struct { volatile __s64 counter; } atomic64_t;
@@ -70,25 +71,47 @@
#define atomic_add_negative(i, v) (atomic_add_ret(i, v) < 0)
#define atomic64_add_negative(i, v) (atomic64_add_ret(i, v) < 0)
-#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
-#define atomic_add_unless(v, a, u) \
-({ \
- int c, old; \
- c = atomic_read(v); \
- for (;;) { \
- if (unlikely(c == (u))) \
- break; \
- old = atomic_cmpxchg((v), c, c + (a)); \
- if (likely(old == c)) \
- break; \
- c = old; \
- } \
- likely(c != (u)); \
-})
+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int c, old;
+ c = atomic_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+#define atomic64_cmpxchg(v, o, n) \
+ ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
+#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
+
+static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+{
+ long c, old;
+ c = atomic64_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic64_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
+#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
/* Atomic operations are already serializing */
#ifdef CONFIG_SMP
#define smp_mb__before_atomic_dec() membar_storeload_loadload();
diff --git a/include/asm-sparc64/const.h b/include/asm-sparc64/const.h
deleted file mode 100644
index 8ad902b..0000000
--- a/include/asm-sparc64/const.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* const.h: Macros for dealing with constants. */
-
-#ifndef _SPARC64_CONST_H
-#define _SPARC64_CONST_H
-
-/* Some constant macros are used in both assembler and
- * C code. Therefore we cannot annotate them always with
- * 'UL' and other type specificers unilaterally. We
- * use the following macros to deal with this.
- */
-
-#ifdef __ASSEMBLY__
-#define _AC(X,Y) X
-#else
-#define _AC(X,Y) (X##Y)
-#endif
-
-
-#endif /* !(_SPARC64_CONST_H) */
diff --git a/include/asm-sparc64/kdebug.h b/include/asm-sparc64/kdebug.h
index 11251bd..f8032e7 100644
--- a/include/asm-sparc64/kdebug.h
+++ b/include/asm-sparc64/kdebug.h
@@ -7,19 +7,8 @@
struct pt_regs;
-struct die_args {
- struct pt_regs *regs;
- const char *str;
- long err;
- int trapnr;
- int signr;
-};
-
-extern int register_die_notifier(struct notifier_block *);
-extern int unregister_die_notifier(struct notifier_block *);
extern int register_page_fault_notifier(struct notifier_block *);
extern int unregister_page_fault_notifier(struct notifier_block *);
-extern struct atomic_notifier_head sparc64die_chain;
extern void bad_trap(struct pt_regs *, long);
@@ -36,16 +25,4 @@
DIE_PAGE_FAULT,
};
-static inline int notify_die(enum die_val val,char *str, struct pt_regs *regs,
- long err, int trap, int sig)
-{
- struct die_args args = { .regs = regs,
- .str = str,
- .err = err,
- .trapnr = trap,
- .signr = sig };
-
- return atomic_notifier_call_chain(&sparc64die_chain, val, &args);
-}
-
#endif
diff --git a/include/asm-sparc64/local.h b/include/asm-sparc64/local.h
index dfde115a..c11c530 100644
--- a/include/asm-sparc64/local.h
+++ b/include/asm-sparc64/local.h
@@ -1,40 +1 @@
-#ifndef _ARCH_SPARC64_LOCAL_H
-#define _ARCH_SPARC64_LOCAL_H
-
-#include <linux/percpu.h>
-#include <asm/atomic.h>
-
-typedef atomic64_t local_t;
-
-#define LOCAL_INIT(i) ATOMIC64_INIT(i)
-#define local_read(v) atomic64_read(v)
-#define local_set(v,i) atomic64_set(v,i)
-
-#define local_inc(v) atomic64_inc(v)
-#define local_dec(v) atomic64_dec(v)
-#define local_add(i, v) atomic64_add(i, v)
-#define local_sub(i, v) atomic64_sub(i, v)
-
-#define __local_inc(v) ((v)->counter++)
-#define __local_dec(v) ((v)->counter--)
-#define __local_add(i,v) ((v)->counter+=(i))
-#define __local_sub(i,v) ((v)->counter-=(i))
-
-/* Use these for per-cpu local_t variables: on some archs they are
- * much more efficient than these naive implementations. Note they take
- * a variable, not an address.
- */
-#define cpu_local_read(v) local_read(&__get_cpu_var(v))
-#define cpu_local_set(v, i) local_set(&__get_cpu_var(v), (i))
-
-#define cpu_local_inc(v) local_inc(&__get_cpu_var(v))
-#define cpu_local_dec(v) local_dec(&__get_cpu_var(v))
-#define cpu_local_add(i, v) local_add((i), &__get_cpu_var(v))
-#define cpu_local_sub(i, v) local_sub((i), &__get_cpu_var(v))
-
-#define __cpu_local_inc(v) __local_inc(&__get_cpu_var(v))
-#define __cpu_local_dec(v) __local_dec(&__get_cpu_var(v))
-#define __cpu_local_add(i, v) __local_add((i), &__get_cpu_var(v))
-#define __cpu_local_sub(i, v) __local_sub((i), &__get_cpu_var(v))
-
-#endif /* _ARCH_SPARC64_LOCAL_H */
+#include <asm-generic/local.h>
diff --git a/include/asm-sparc64/lsu.h b/include/asm-sparc64/lsu.h
index e5329c7..79f1098 100644
--- a/include/asm-sparc64/lsu.h
+++ b/include/asm-sparc64/lsu.h
@@ -2,7 +2,7 @@
#ifndef _SPARC64_LSU_H
#define _SPARC64_LSU_H
-#include <asm/const.h>
+#include <linux/const.h>
/* LSU Control Register */
#define LSU_CONTROL_PM _AC(0x000001fe00000000,UL) /* Phys-watchpoint byte mask*/
diff --git a/include/asm-sparc64/mmu.h b/include/asm-sparc64/mmu.h
index 70af4b6..8abc58f 100644
--- a/include/asm-sparc64/mmu.h
+++ b/include/asm-sparc64/mmu.h
@@ -1,8 +1,8 @@
#ifndef __MMU_H
#define __MMU_H
+#include <linux/const.h>
#include <asm/page.h>
-#include <asm/const.h>
#include <asm/hypervisor.h>
#define CTX_NR_BITS 13
diff --git a/include/asm-sparc64/page.h b/include/asm-sparc64/page.h
index ff736ea..7af1077 100644
--- a/include/asm-sparc64/page.h
+++ b/include/asm-sparc64/page.h
@@ -5,7 +5,7 @@
#ifdef __KERNEL__
-#include <asm/const.h>
+#include <linux/const.h>
#if defined(CONFIG_SPARC64_PAGE_SIZE_8KB)
#define PAGE_SHIFT 13
diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h
index 46705ef..9e80ad4 100644
--- a/include/asm-sparc64/pgtable.h
+++ b/include/asm-sparc64/pgtable.h
@@ -15,13 +15,13 @@
#include <asm-generic/pgtable-nopud.h>
#include <linux/compiler.h>
+#include <linux/const.h>
#include <asm/types.h>
#include <asm/spitfire.h>
#include <asm/asi.h>
#include <asm/system.h>
#include <asm/page.h>
#include <asm/processor.h>
-#include <asm/const.h>
/* The kernel image occupies 0x4000000 to 0x1000000 (4MB --> 32MB).
* The page copy blockops can use 0x2000000 to 0x4000000.
diff --git a/include/asm-sparc64/pstate.h b/include/asm-sparc64/pstate.h
index 49a7924..f3c4548 100644
--- a/include/asm-sparc64/pstate.h
+++ b/include/asm-sparc64/pstate.h
@@ -2,7 +2,7 @@
#ifndef _SPARC64_PSTATE_H
#define _SPARC64_PSTATE_H
-#include <asm/const.h>
+#include <linux/const.h>
/* The V9 PSTATE Register (with SpitFire extensions).
*
diff --git a/include/asm-sparc64/sfafsr.h b/include/asm-sparc64/sfafsr.h
index 2f792c2..e96137b 100644
--- a/include/asm-sparc64/sfafsr.h
+++ b/include/asm-sparc64/sfafsr.h
@@ -1,7 +1,7 @@
#ifndef _SPARC64_SFAFSR_H
#define _SPARC64_SFAFSR_H
-#include <asm/const.h>
+#include <linux/const.h>
/* Spitfire Asynchronous Fault Status register, ASI=0x4C VA<63:0>=0x0 */
diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h
index 32281ac..8ba380e 100644
--- a/include/asm-sparc64/system.h
+++ b/include/asm-sparc64/system.h
@@ -253,7 +253,6 @@
}
#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
-#define tas(ptr) (xchg((ptr),1))
extern void __xchg_called_with_bad_pointer(void);
diff --git a/include/asm-um/cmpxchg.h b/include/asm-um/cmpxchg.h
new file mode 100644
index 0000000..529376a
--- /dev/null
+++ b/include/asm-um/cmpxchg.h
@@ -0,0 +1,6 @@
+#ifndef __UM_CMPXCHG_H
+#define __UM_CMPXCHG_H
+
+#include "asm/arch/cmpxchg.h"
+
+#endif
diff --git a/include/asm-um/kdebug.h b/include/asm-um/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-um/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-v850/kdebug.h b/include/asm-v850/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-v850/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-v850/system.h b/include/asm-v850/system.h
index da39916..0de2481 100644
--- a/include/asm-v850/system.h
+++ b/include/asm-v850/system.h
@@ -76,7 +76,6 @@
#define xchg(ptr, with) \
((__typeof__ (*(ptr)))__xchg ((unsigned long)(with), (ptr), sizeof (*(ptr))))
-#define tas(ptr) (xchg ((ptr), 1))
static inline unsigned long __xchg (unsigned long with,
__volatile__ void *ptr, int size)
diff --git a/include/asm-x86_64/Kbuild b/include/asm-x86_64/Kbuild
index 89ad1fc..75a2def 100644
--- a/include/asm-x86_64/Kbuild
+++ b/include/asm-x86_64/Kbuild
@@ -19,4 +19,3 @@
unifdef-y += msr.h
unifdef-y += mtrr.h
unifdef-y += vsyscall.h
-unifdef-y += const.h
diff --git a/include/asm-x86_64/atomic.h b/include/asm-x86_64/atomic.h
index 706ca4b..f2e6463 100644
--- a/include/asm-x86_64/atomic.h
+++ b/include/asm-x86_64/atomic.h
@@ -2,6 +2,7 @@
#define __ARCH_X86_64_ATOMIC__
#include <asm/alternative.h>
+#include <asm/cmpxchg.h>
/* atomic_t should be 32 bit signed type */
@@ -375,8 +376,8 @@
long __i = i;
__asm__ __volatile__(
LOCK_PREFIX "xaddq %0, %1;"
- :"=r"(i)
- :"m"(v->counter), "0"(i));
+ :"+r" (i), "+m" (v->counter)
+ : : "memory");
return i + __i;
}
@@ -388,7 +389,10 @@
#define atomic64_inc_return(v) (atomic64_add_return(1,v))
#define atomic64_dec_return(v) (atomic64_sub_return(1,v))
-#define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new))
+#define atomic64_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new))
+#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
+
+#define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new))
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
/**
@@ -400,22 +404,49 @@
* Atomically adds @a to @v, so long as it was not @u.
* Returns non-zero if @v was not @u, and zero otherwise.
*/
-#define atomic_add_unless(v, a, u) \
-({ \
- int c, old; \
- c = atomic_read(v); \
- for (;;) { \
- if (unlikely(c == (u))) \
- break; \
- old = atomic_cmpxchg((v), c, c + (a)); \
- if (likely(old == c)) \
- break; \
- c = old; \
- } \
- c != (u); \
-})
+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int c, old;
+ c = atomic_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+/**
+ * atomic64_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic64_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
+ */
+static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+{
+ long c, old;
+ c = atomic64_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic64_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
+#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
/* These are x86-specific, used by some header files */
#define atomic_clear_mask(mask, addr) \
__asm__ __volatile__(LOCK_PREFIX "andl %0,%1" \
diff --git a/include/asm-x86_64/cmpxchg.h b/include/asm-x86_64/cmpxchg.h
new file mode 100644
index 0000000..09a6b6b
--- /dev/null
+++ b/include/asm-x86_64/cmpxchg.h
@@ -0,0 +1,134 @@
+#ifndef __ASM_CMPXCHG_H
+#define __ASM_CMPXCHG_H
+
+#include <asm/alternative.h> /* Provides LOCK_PREFIX */
+
+#define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
+
+#define __xg(x) ((volatile long *)(x))
+
+static inline void set_64bit(volatile unsigned long *ptr, unsigned long val)
+{
+ *ptr = val;
+}
+
+#define _set_64bit set_64bit
+
+/*
+ * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
+ * Note 2: xchg has side effect, so that attribute volatile is necessary,
+ * but generally the primitive is invalid, *ptr is output argument. --ANK
+ */
+static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
+{
+ switch (size) {
+ case 1:
+ __asm__ __volatile__("xchgb %b0,%1"
+ :"=q" (x)
+ :"m" (*__xg(ptr)), "0" (x)
+ :"memory");
+ break;
+ case 2:
+ __asm__ __volatile__("xchgw %w0,%1"
+ :"=r" (x)
+ :"m" (*__xg(ptr)), "0" (x)
+ :"memory");
+ break;
+ case 4:
+ __asm__ __volatile__("xchgl %k0,%1"
+ :"=r" (x)
+ :"m" (*__xg(ptr)), "0" (x)
+ :"memory");
+ break;
+ case 8:
+ __asm__ __volatile__("xchgq %0,%1"
+ :"=r" (x)
+ :"m" (*__xg(ptr)), "0" (x)
+ :"memory");
+ break;
+ }
+ return x;
+}
+
+/*
+ * Atomic compare and exchange. Compare OLD with MEM, if identical,
+ * store NEW in MEM. Return the initial value in MEM. Success is
+ * indicated by comparing RETURN with OLD.
+ */
+
+#define __HAVE_ARCH_CMPXCHG 1
+
+static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
+ unsigned long new, int size)
+{
+ unsigned long prev;
+ switch (size) {
+ case 1:
+ __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
+ : "=a"(prev)
+ : "q"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ case 2:
+ __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
+ : "=a"(prev)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ case 4:
+ __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %k1,%2"
+ : "=a"(prev)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ case 8:
+ __asm__ __volatile__(LOCK_PREFIX "cmpxchgq %1,%2"
+ : "=a"(prev)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ }
+ return old;
+}
+
+static inline unsigned long __cmpxchg_local(volatile void *ptr,
+ unsigned long old, unsigned long new, int size)
+{
+ unsigned long prev;
+ switch (size) {
+ case 1:
+ __asm__ __volatile__("cmpxchgb %b1,%2"
+ : "=a"(prev)
+ : "q"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ case 2:
+ __asm__ __volatile__("cmpxchgw %w1,%2"
+ : "=a"(prev)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ case 4:
+ __asm__ __volatile__("cmpxchgl %k1,%2"
+ : "=a"(prev)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ case 8:
+ __asm__ __volatile__("cmpxchgq %1,%2"
+ : "=a"(prev)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ }
+ return old;
+}
+
+#define cmpxchg(ptr,o,n)\
+ ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
+ (unsigned long)(n),sizeof(*(ptr))))
+#define cmpxchg_local(ptr,o,n)\
+ ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
+ (unsigned long)(n),sizeof(*(ptr))))
+
+#endif
diff --git a/include/asm-x86_64/kdebug.h b/include/asm-x86_64/kdebug.h
index 2b0c088..74feae9 100644
--- a/include/asm-x86_64/kdebug.h
+++ b/include/asm-x86_64/kdebug.h
@@ -5,19 +5,8 @@
struct pt_regs;
-struct die_args {
- struct pt_regs *regs;
- const char *str;
- long err;
- int trapnr;
- int signr;
-};
-
-extern int register_die_notifier(struct notifier_block *);
-extern int unregister_die_notifier(struct notifier_block *);
extern int register_page_fault_notifier(struct notifier_block *);
extern int unregister_page_fault_notifier(struct notifier_block *);
-extern struct atomic_notifier_head die_chain;
/* Grossly misnamed. */
enum die_val {
@@ -33,22 +22,10 @@
DIE_GPF,
DIE_CALL,
DIE_NMI_IPI,
+ DIE_NMI_POST,
DIE_PAGE_FAULT,
};
-static inline int notify_die(enum die_val val, const char *str,
- struct pt_regs *regs, long err, int trap, int sig)
-{
- struct die_args args = {
- .regs = regs,
- .str = str,
- .err = err,
- .trapnr = trap,
- .signr = sig
- };
- return atomic_notifier_call_chain(&die_chain, val, &args);
-}
-
extern void printk_address(unsigned long address);
extern void die(const char *,struct pt_regs *,long);
extern void __die(const char *,struct pt_regs *,long);
diff --git a/include/asm-x86_64/kexec.h b/include/asm-x86_64/kexec.h
index 5fab957..738e581 100644
--- a/include/asm-x86_64/kexec.h
+++ b/include/asm-x86_64/kexec.h
@@ -48,8 +48,6 @@
/* The native architecture */
#define KEXEC_ARCH KEXEC_ARCH_X86_64
-#define MAX_NOTE_BYTES 1024
-
/*
* Saving the registers of the cpu on which panic occured in
* crash_kexec to save a valid sp. The registers of other cpus
diff --git a/include/asm-x86_64/local.h b/include/asm-x86_64/local.h
index e769e62..e87492b 100644
--- a/include/asm-x86_64/local.h
+++ b/include/asm-x86_64/local.h
@@ -2,49 +2,183 @@
#define _ARCH_X8664_LOCAL_H
#include <linux/percpu.h>
+#include <asm/atomic.h>
typedef struct
{
- volatile long counter;
+ atomic_long_t a;
} local_t;
-#define LOCAL_INIT(i) { (i) }
+#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) }
-#define local_read(v) ((v)->counter)
-#define local_set(v,i) (((v)->counter) = (i))
+#define local_read(l) atomic_long_read(&(l)->a)
+#define local_set(l,i) atomic_long_set(&(l)->a, (i))
-static inline void local_inc(local_t *v)
+static inline void local_inc(local_t *l)
{
__asm__ __volatile__(
"incq %0"
- :"=m" (v->counter)
- :"m" (v->counter));
+ :"=m" (l->a.counter)
+ :"m" (l->a.counter));
}
-static inline void local_dec(local_t *v)
+static inline void local_dec(local_t *l)
{
__asm__ __volatile__(
"decq %0"
- :"=m" (v->counter)
- :"m" (v->counter));
+ :"=m" (l->a.counter)
+ :"m" (l->a.counter));
}
-static inline void local_add(long i, local_t *v)
+static inline void local_add(long i, local_t *l)
{
__asm__ __volatile__(
"addq %1,%0"
- :"=m" (v->counter)
- :"ir" (i), "m" (v->counter));
+ :"=m" (l->a.counter)
+ :"ir" (i), "m" (l->a.counter));
}
-static inline void local_sub(long i, local_t *v)
+static inline void local_sub(long i, local_t *l)
{
__asm__ __volatile__(
"subq %1,%0"
- :"=m" (v->counter)
- :"ir" (i), "m" (v->counter));
+ :"=m" (l->a.counter)
+ :"ir" (i), "m" (l->a.counter));
}
+/**
+ * local_sub_and_test - subtract value from variable and test result
+ * @i: integer value to subtract
+ * @l: pointer to type local_t
+ *
+ * Atomically subtracts @i from @l and returns
+ * true if the result is zero, or false for all
+ * other cases.
+ */
+static __inline__ int local_sub_and_test(long i, local_t *l)
+{
+ unsigned char c;
+
+ __asm__ __volatile__(
+ "subq %2,%0; sete %1"
+ :"=m" (l->a.counter), "=qm" (c)
+ :"ir" (i), "m" (l->a.counter) : "memory");
+ return c;
+}
+
+/**
+ * local_dec_and_test - decrement and test
+ * @l: pointer to type local_t
+ *
+ * Atomically decrements @l by 1 and
+ * returns true if the result is 0, or false for all other
+ * cases.
+ */
+static __inline__ int local_dec_and_test(local_t *l)
+{
+ unsigned char c;
+
+ __asm__ __volatile__(
+ "decq %0; sete %1"
+ :"=m" (l->a.counter), "=qm" (c)
+ :"m" (l->a.counter) : "memory");
+ return c != 0;
+}
+
+/**
+ * local_inc_and_test - increment and test
+ * @l: pointer to type local_t
+ *
+ * Atomically increments @l by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+static __inline__ int local_inc_and_test(local_t *l)
+{
+ unsigned char c;
+
+ __asm__ __volatile__(
+ "incq %0; sete %1"
+ :"=m" (l->a.counter), "=qm" (c)
+ :"m" (l->a.counter) : "memory");
+ return c != 0;
+}
+
+/**
+ * local_add_negative - add and test if negative
+ * @i: integer value to add
+ * @l: pointer to type local_t
+ *
+ * Atomically adds @i to @l and returns true
+ * if the result is negative, or false when
+ * result is greater than or equal to zero.
+ */
+static __inline__ int local_add_negative(long i, local_t *l)
+{
+ unsigned char c;
+
+ __asm__ __volatile__(
+ "addq %2,%0; sets %1"
+ :"=m" (l->a.counter), "=qm" (c)
+ :"ir" (i), "m" (l->a.counter) : "memory");
+ return c;
+}
+
+/**
+ * local_add_return - add and return
+ * @i: integer value to add
+ * @l: pointer to type local_t
+ *
+ * Atomically adds @i to @l and returns @i + @l
+ */
+static __inline__ long local_add_return(long i, local_t *l)
+{
+ long __i = i;
+ __asm__ __volatile__(
+ "xaddq %0, %1;"
+ :"+r" (i), "+m" (l->a.counter)
+ : : "memory");
+ return i + __i;
+}
+
+static __inline__ long local_sub_return(long i, local_t *l)
+{
+ return local_add_return(-i,l);
+}
+
+#define local_inc_return(l) (local_add_return(1,l))
+#define local_dec_return(l) (local_sub_return(1,l))
+
+#define local_cmpxchg(l, o, n) \
+ (cmpxchg_local(&((l)->a.counter), (o), (n)))
+/* Always has a lock prefix */
+#define local_xchg(l, n) (xchg(&((l)->a.counter), (n)))
+
+/**
+ * atomic_up_add_unless - add unless the number is a given value
+ * @l: pointer of type local_t
+ * @a: the amount to add to l...
+ * @u: ...unless l is equal to u.
+ *
+ * Atomically adds @a to @l, so long as it was not @u.
+ * Returns non-zero if @l was not @u, and zero otherwise.
+ */
+#define local_add_unless(l, a, u) \
+({ \
+ long c, old; \
+ c = local_read(l); \
+ for (;;) { \
+ if (unlikely(c == (u))) \
+ break; \
+ old = local_cmpxchg((l), c, c + (a)); \
+ if (likely(old == c)) \
+ break; \
+ c = old; \
+ } \
+ c != (u); \
+})
+#define local_inc_not_zero(l) local_add_unless((l), 1, 0)
+
/* On x86-64 these are better than the atomic variants on SMP kernels
because they dont use a lock prefix. */
#define __local_inc(l) local_inc(l)
@@ -62,27 +196,27 @@
/* Need to disable preemption for the cpu local counters otherwise we could
still access a variable of a previous CPU in a non atomic way. */
-#define cpu_local_wrap_v(v) \
+#define cpu_local_wrap_v(l) \
({ local_t res__; \
preempt_disable(); \
- res__ = (v); \
+ res__ = (l); \
preempt_enable(); \
res__; })
-#define cpu_local_wrap(v) \
+#define cpu_local_wrap(l) \
({ preempt_disable(); \
- v; \
+ l; \
preempt_enable(); }) \
-#define cpu_local_read(v) cpu_local_wrap_v(local_read(&__get_cpu_var(v)))
-#define cpu_local_set(v, i) cpu_local_wrap(local_set(&__get_cpu_var(v), (i)))
-#define cpu_local_inc(v) cpu_local_wrap(local_inc(&__get_cpu_var(v)))
-#define cpu_local_dec(v) cpu_local_wrap(local_dec(&__get_cpu_var(v)))
-#define cpu_local_add(i, v) cpu_local_wrap(local_add((i), &__get_cpu_var(v)))
-#define cpu_local_sub(i, v) cpu_local_wrap(local_sub((i), &__get_cpu_var(v)))
+#define cpu_local_read(l) cpu_local_wrap_v(local_read(&__get_cpu_var(l)))
+#define cpu_local_set(l, i) cpu_local_wrap(local_set(&__get_cpu_var(l), (i)))
+#define cpu_local_inc(l) cpu_local_wrap(local_inc(&__get_cpu_var(l)))
+#define cpu_local_dec(l) cpu_local_wrap(local_dec(&__get_cpu_var(l)))
+#define cpu_local_add(i, l) cpu_local_wrap(local_add((i), &__get_cpu_var(l)))
+#define cpu_local_sub(i, l) cpu_local_wrap(local_sub((i), &__get_cpu_var(l)))
-#define __cpu_local_inc(v) cpu_local_inc(v)
-#define __cpu_local_dec(v) cpu_local_dec(v)
-#define __cpu_local_add(i, v) cpu_local_add((i), (v))
-#define __cpu_local_sub(i, v) cpu_local_sub((i), (v))
+#define __cpu_local_inc(l) cpu_local_inc(l)
+#define __cpu_local_dec(l) cpu_local_dec(l)
+#define __cpu_local_add(i, l) cpu_local_add((i), (l))
+#define __cpu_local_sub(i, l) cpu_local_sub((i), (l))
-#endif /* _ARCH_I386_LOCAL_H */
+#endif /* _ARCH_X8664_LOCAL_H */
diff --git a/include/asm-x86_64/page.h b/include/asm-x86_64/page.h
index 4d04e24..dee632f 100644
--- a/include/asm-x86_64/page.h
+++ b/include/asm-x86_64/page.h
@@ -1,7 +1,7 @@
#ifndef _X86_64_PAGE_H
#define _X86_64_PAGE_H
-#include <asm/const.h>
+#include <linux/const.h>
/* PAGE_SHIFT determines the page size */
#define PAGE_SHIFT 12
@@ -79,9 +79,10 @@
#define __PHYSICAL_START CONFIG_PHYSICAL_START
#define __KERNEL_ALIGN 0x200000
+
#define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START)
-#define __START_KERNEL_map 0xffffffff80000000
-#define __PAGE_OFFSET 0xffff810000000000
+#define __START_KERNEL_map _AC(0xffffffff80000000, UL)
+#define __PAGE_OFFSET _AC(0xffff810000000000, UL)
/* to align the pointer to the (next) page boundary */
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
@@ -93,7 +94,7 @@
#define __VIRTUAL_MASK ((_AC(1,UL) << __VIRTUAL_MASK_SHIFT) - 1)
#define KERNEL_TEXT_SIZE (40*1024*1024)
-#define KERNEL_TEXT_START 0xffffffff80000000
+#define KERNEL_TEXT_START _AC(0xffffffff80000000, UL)
#define PAGE_OFFSET __PAGE_OFFSET
#ifndef __ASSEMBLY__
diff --git a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h
index da3390f..08b9831 100644
--- a/include/asm-x86_64/pgtable.h
+++ b/include/asm-x86_64/pgtable.h
@@ -1,7 +1,7 @@
#ifndef _X86_64_PGTABLE_H
#define _X86_64_PGTABLE_H
-#include <asm/const.h>
+#include <linux/const.h>
#ifndef __ASSEMBLY__
/*
@@ -134,11 +134,11 @@
#define USER_PTRS_PER_PGD ((TASK_SIZE-1)/PGDIR_SIZE+1)
#define FIRST_USER_ADDRESS 0
-#define MAXMEM 0x3fffffffffff
-#define VMALLOC_START 0xffffc20000000000
-#define VMALLOC_END 0xffffe1ffffffffff
-#define MODULES_VADDR 0xffffffff88000000
-#define MODULES_END 0xfffffffffff00000
+#define MAXMEM _AC(0x3fffffffffff, UL)
+#define VMALLOC_START _AC(0xffffc20000000000, UL)
+#define VMALLOC_END _AC(0xffffe1ffffffffff, UL)
+#define MODULES_VADDR _AC(0xffffffff88000000, UL)
+#define MODULES_END _AC(0xfffffffffff00000, UL)
#define MODULES_LEN (MODULES_END - MODULES_VADDR)
#define _PAGE_BIT_PRESENT 0
@@ -411,17 +411,12 @@
extern spinlock_t pgd_lock;
extern struct list_head pgd_list;
-void vmalloc_sync_all(void);
extern int kern_addr_valid(unsigned long addr);
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
#define HAVE_ARCH_UNMAPPED_AREA
#define pgtable_cache_init() do { } while (0)
diff --git a/include/asm-x86_64/serial.h b/include/asm-x86_64/serial.h
index b0496e0..8ebd765 100644
--- a/include/asm-x86_64/serial.h
+++ b/include/asm-x86_64/serial.h
@@ -11,19 +11,3 @@
* megabits/second; but this requires the faster clock.
*/
#define BASE_BAUD ( 1843200 / 16 )
-
-/* Standard COM flags (except for COM4, because of the 8514 problem) */
-#ifdef CONFIG_SERIAL_DETECT_IRQ
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ)
-#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ)
-#else
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
-#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
-#endif
-
-#define SERIAL_PORT_DFNS \
- /* UART CLK PORT IRQ FLAGS */ \
- { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \
- { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \
- { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \
- { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */
diff --git a/include/asm-x86_64/system.h b/include/asm-x86_64/system.h
index 213b7fe..b7b8021 100644
--- a/include/asm-x86_64/system.h
+++ b/include/asm-x86_64/system.h
@@ -3,7 +3,7 @@
#include <linux/kernel.h>
#include <asm/segment.h>
-#include <asm/alternative.h>
+#include <asm/cmpxchg.h>
#ifdef __KERNEL__
@@ -124,100 +124,6 @@
#define nop() __asm__ __volatile__ ("nop")
-#define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
-
-#define tas(ptr) (xchg((ptr),1))
-
-#define __xg(x) ((volatile long *)(x))
-
-static inline void set_64bit(volatile unsigned long *ptr, unsigned long val)
-{
- *ptr = val;
-}
-
-#define _set_64bit set_64bit
-
-/*
- * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
- * Note 2: xchg has side effect, so that attribute volatile is necessary,
- * but generally the primitive is invalid, *ptr is output argument. --ANK
- */
-static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
-{
- switch (size) {
- case 1:
- __asm__ __volatile__("xchgb %b0,%1"
- :"=q" (x)
- :"m" (*__xg(ptr)), "0" (x)
- :"memory");
- break;
- case 2:
- __asm__ __volatile__("xchgw %w0,%1"
- :"=r" (x)
- :"m" (*__xg(ptr)), "0" (x)
- :"memory");
- break;
- case 4:
- __asm__ __volatile__("xchgl %k0,%1"
- :"=r" (x)
- :"m" (*__xg(ptr)), "0" (x)
- :"memory");
- break;
- case 8:
- __asm__ __volatile__("xchgq %0,%1"
- :"=r" (x)
- :"m" (*__xg(ptr)), "0" (x)
- :"memory");
- break;
- }
- return x;
-}
-
-/*
- * Atomic compare and exchange. Compare OLD with MEM, if identical,
- * store NEW in MEM. Return the initial value in MEM. Success is
- * indicated by comparing RETURN with OLD.
- */
-
-#define __HAVE_ARCH_CMPXCHG 1
-
-static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
- unsigned long new, int size)
-{
- unsigned long prev;
- switch (size) {
- case 1:
- __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
- : "=a"(prev)
- : "q"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- case 2:
- __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- case 4:
- __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %k1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- case 8:
- __asm__ __volatile__(LOCK_PREFIX "cmpxchgq %1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- }
- return old;
-}
-
-#define cmpxchg(ptr,o,n)\
- ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
- (unsigned long)(n),sizeof(*(ptr))))
-
#ifdef CONFIG_SMP
#define smp_mb() mb()
#define smp_rmb() rmb()
diff --git a/include/asm-x86_64/termbits.h b/include/asm-x86_64/termbits.h
index 6cfc3bb..7405756 100644
--- a/include/asm-x86_64/termbits.h
+++ b/include/asm-x86_64/termbits.h
@@ -160,7 +160,7 @@
#define CMSPAR 010000000000 /* mark or space (stick) parity */
#define CRTSCTS 020000000000 /* flow control */
-#define IBSHIFT 8 /* Shift from CBAUD to CIBAUD */
+#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */
/* c_lflag bits */
#define ISIG 0000001
diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h
index 26e23e0..5957039 100644
--- a/include/asm-x86_64/unistd.h
+++ b/include/asm-x86_64/unistd.h
@@ -619,6 +619,8 @@
__SYSCALL(__NR_vmsplice, sys_vmsplice)
#define __NR_move_pages 279
__SYSCALL(__NR_move_pages, sys_move_pages)
+#define __NR_utimensat 280
+__SYSCALL(__NR_utimensat, sys_utimensat)
#ifndef __NO_STUBS
#define __ARCH_WANT_OLD_READDIR
diff --git a/include/asm-xtensa/atomic.h b/include/asm-xtensa/atomic.h
index 5c26720..b3b2354 100644
--- a/include/asm-xtensa/atomic.h
+++ b/include/asm-xtensa/atomic.h
@@ -234,14 +234,21 @@
* Atomically adds @a to @v, so long as it was not @u.
* Returns non-zero if @v was not @u, and zero otherwise.
*/
-#define atomic_add_unless(v, a, u) \
-({ \
- int c, old; \
- c = atomic_read(v); \
- while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
- c = old; \
- c != (u); \
-})
+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int c, old;
+ c = atomic_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
static inline void atomic_clear_mask(unsigned int mask, atomic_t *v)
diff --git a/include/asm-xtensa/kdebug.h b/include/asm-xtensa/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-xtensa/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-xtensa/system.h b/include/asm-xtensa/system.h
index 4aaed7f..ddc9708 100644
--- a/include/asm-xtensa/system.h
+++ b/include/asm-xtensa/system.h
@@ -183,8 +183,6 @@
return tmp;
}
-#define tas(ptr) (xchg((ptr),1))
-
#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
/*
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 9f05279..94cc04a 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -4,6 +4,7 @@
header-y += isdn/
header-y += nfsd/
header-y += raid/
+header-y += spi/
header-y += sunrpc/
header-y += tc_act/
header-y += netfilter/
@@ -33,7 +34,6 @@
header-y += atm_zatm.h
header-y += auto_fs4.h
header-y += auxvec.h
-header-y += awe_voice.h
header-y += ax25.h
header-y += b1lli.h
header-y += baycom.h
@@ -46,6 +46,7 @@
header-y += coff.h
header-y += comstats.h
header-y += consolemap.h
+header-y += const.h
header-y += cycx_cfm.h
header-y += dlm_device.h
header-y += dm-ioctl.h
@@ -91,7 +92,6 @@
header-y += ipsec.h
header-y += ipx.h
header-y += irda.h
-header-y += isdn_divertif.h
header-y += iso_fs.h
header-y += ixjuser.h
header-y += jffs2.h
@@ -121,6 +121,7 @@
header-y += personality.h
header-y += pfkeyv2.h
header-y += pg.h
+header-y += phantom.h
header-y += pkt_cls.h
header-y += pkt_sched.h
header-y += posix_types.h
@@ -140,6 +141,7 @@
header-y += som.h
header-y += sound.h
header-y += synclink.h
+header-y += taskstats.h
header-y += telephony.h
header-y += termios.h
header-y += ticable.h
@@ -239,6 +241,7 @@
unifdef-y += ipv6_route.h
unifdef-y += isdn.h
unifdef-y += isdnif.h
+unifdef-y += isdn_divertif.h
unifdef-y += isdn_ppp.h
unifdef-y += isicom.h
unifdef-y += jbd.h
diff --git a/include/linux/awe_voice.h b/include/linux/awe_voice.h
deleted file mode 100644
index bf33f17..0000000
--- a/include/linux/awe_voice.h
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
- * include/linux/awe_voice.h
- *
- * Voice information definitions for the low level driver for the
- * AWE32/SB32/AWE64 wave table synth.
- * version 0.4.4; Jan. 4, 2000
- *
- * Copyright (C) 1996-2000 Takashi Iwai
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef AWE_VOICE_H
-#define AWE_VOICE_H
-
-#ifndef SAMPLE_TYPE_AWE32
-#define SAMPLE_TYPE_AWE32 0x20
-#endif
-
-#define _LINUX_PATCHKEY_H_INDIRECT
-#include <linux/patchkey.h>
-#undef _LINUX_PATCHKEY_H_INDIRECT
-
-/*----------------------------------------------------------------
- * patch information record
- *----------------------------------------------------------------*/
-
-/* patch interface header: 16 bytes */
-typedef struct awe_patch_info {
- short key; /* use AWE_PATCH here */
-#define AWE_PATCH _PATCHKEY(0x07)
-
- short device_no; /* synthesizer number */
- unsigned short sf_id; /* file id (should be zero) */
- short optarg; /* optional argument */
- int len; /* data length (without this header) */
-
- short type; /* patch operation type */
-#define AWE_LOAD_INFO 0 /* awe_voice_rec */
-#define AWE_LOAD_DATA 1 /* awe_sample_info */
-#define AWE_OPEN_PATCH 2 /* awe_open_parm */
-#define AWE_CLOSE_PATCH 3 /* none */
-#define AWE_UNLOAD_PATCH 4 /* none */
-#define AWE_REPLACE_DATA 5 /* awe_sample_info (optarg=#channels)*/
-#define AWE_MAP_PRESET 6 /* awe_voice_map */
-/*#define AWE_PROBE_INFO 7*/ /* awe_voice_map (pat only) */
-#define AWE_PROBE_DATA 8 /* optarg=sample */
-#define AWE_REMOVE_INFO 9 /* optarg=(bank<<8)|instr */
-#define AWE_LOAD_CHORUS_FX 0x10 /* awe_chorus_fx_rec (optarg=mode) */
-#define AWE_LOAD_REVERB_FX 0x11 /* awe_reverb_fx_rec (optarg=mode) */
-
- short reserved; /* word alignment data */
-
- /* the actual patch data begins after this */
-#if defined(AWE_COMPAT_030) && AWE_COMPAT_030
- char data[0];
-#endif
-} awe_patch_info;
-
-/*#define AWE_PATCH_INFO_SIZE 16*/
-#define AWE_PATCH_INFO_SIZE sizeof(awe_patch_info)
-
-
-/*----------------------------------------------------------------
- * open patch
- *----------------------------------------------------------------*/
-
-#define AWE_PATCH_NAME_LEN 32
-
-typedef struct _awe_open_parm {
- unsigned short type; /* sample type */
-#define AWE_PAT_TYPE_MISC 0
-#define AWE_PAT_TYPE_GM 1
-#define AWE_PAT_TYPE_GS 2
-#define AWE_PAT_TYPE_MT32 3
-#define AWE_PAT_TYPE_XG 4
-#define AWE_PAT_TYPE_SFX 5
-#define AWE_PAT_TYPE_GUS 6
-#define AWE_PAT_TYPE_MAP 7
-
-#define AWE_PAT_LOCKED 0x100 /* lock the samples */
-#define AWE_PAT_SHARED 0x200 /* sample is shared */
-
- short reserved;
- char name[AWE_PATCH_NAME_LEN];
-} awe_open_parm;
-
-/*#define AWE_OPEN_PARM_SIZE 28*/
-#define AWE_OPEN_PARM_SIZE sizeof(awe_open_parm)
-
-
-/*----------------------------------------------------------------
- * raw voice information record
- *----------------------------------------------------------------*/
-
-/* wave table envelope & effect parameters to control EMU8000 */
-typedef struct _awe_voice_parm {
- unsigned short moddelay; /* modulation delay (0x8000) */
- unsigned short modatkhld; /* modulation attack & hold time (0x7f7f) */
- unsigned short moddcysus; /* modulation decay & sustain (0x7f7f) */
- unsigned short modrelease; /* modulation release time (0x807f) */
- short modkeyhold, modkeydecay; /* envelope change per key (not used) */
- unsigned short voldelay; /* volume delay (0x8000) */
- unsigned short volatkhld; /* volume attack & hold time (0x7f7f) */
- unsigned short voldcysus; /* volume decay & sustain (0x7f7f) */
- unsigned short volrelease; /* volume release time (0x807f) */
- short volkeyhold, volkeydecay; /* envelope change per key (not used) */
- unsigned short lfo1delay; /* LFO1 delay (0x8000) */
- unsigned short lfo2delay; /* LFO2 delay (0x8000) */
- unsigned short pefe; /* modulation pitch & cutoff (0x0000) */
- unsigned short fmmod; /* LFO1 pitch & cutoff (0x0000) */
- unsigned short tremfrq; /* LFO1 volume & freq (0x0000) */
- unsigned short fm2frq2; /* LFO2 pitch & freq (0x0000) */
- unsigned char cutoff; /* initial cutoff (0xff) */
- unsigned char filterQ; /* initial filter Q [0-15] (0x0) */
- unsigned char chorus; /* chorus send (0x00) */
- unsigned char reverb; /* reverb send (0x00) */
- unsigned short reserved[4]; /* not used */
-} awe_voice_parm;
-
-typedef struct _awe_voice_parm_block {
- unsigned short moddelay; /* modulation delay (0x8000) */
- unsigned char modatk, modhld;
- unsigned char moddcy, modsus;
- unsigned char modrel, moddummy;
- short modkeyhold, modkeydecay; /* envelope change per key (not used) */
- unsigned short voldelay; /* volume delay (0x8000) */
- unsigned char volatk, volhld;
- unsigned char voldcy, volsus;
- unsigned char volrel, voldummy;
- short volkeyhold, volkeydecay; /* envelope change per key (not used) */
- unsigned short lfo1delay; /* LFO1 delay (0x8000) */
- unsigned short lfo2delay; /* LFO2 delay (0x8000) */
- unsigned char env1fc, env1pit;
- unsigned char lfo1fc, lfo1pit;
- unsigned char lfo1freq, lfo1vol;
- unsigned char lfo2freq, lfo2pit;
- unsigned char cutoff; /* initial cutoff (0xff) */
- unsigned char filterQ; /* initial filter Q [0-15] (0x0) */
- unsigned char chorus; /* chorus send (0x00) */
- unsigned char reverb; /* reverb send (0x00) */
- unsigned short reserved[4]; /* not used */
-} awe_voice_parm_block;
-
-#define AWE_VOICE_PARM_SIZE 48
-
-
-/* wave table parameters: 92 bytes */
-typedef struct _awe_voice_info {
- unsigned short sf_id; /* file id (should be zero) */
- unsigned short sample; /* sample id */
- int start, end; /* sample offset correction */
- int loopstart, loopend; /* loop offset correction */
- short rate_offset; /* sample rate pitch offset */
- unsigned short mode; /* sample mode */
-#define AWE_MODE_ROMSOUND 0x8000
-#define AWE_MODE_STEREO 1
-#define AWE_MODE_LOOPING 2
-#define AWE_MODE_NORELEASE 4 /* obsolete */
-#define AWE_MODE_INIT_PARM 8
-
- short root; /* midi root key */
- short tune; /* pitch tuning (in cents) */
- signed char low, high; /* key note range */
- signed char vellow, velhigh; /* velocity range */
- signed char fixkey, fixvel; /* fixed key, velocity */
- signed char pan, fixpan; /* panning, fixed panning */
- short exclusiveClass; /* exclusive class (0 = none) */
- unsigned char amplitude; /* sample volume (127 max) */
- unsigned char attenuation; /* attenuation (0.375dB) */
- short scaleTuning; /* pitch scale tuning(%), normally 100 */
- awe_voice_parm parm; /* voice envelope parameters */
- short index; /* internal index (set by driver) */
-} awe_voice_info;
-
-/*#define AWE_VOICE_INFO_SIZE 92*/
-#define AWE_VOICE_INFO_SIZE sizeof(awe_voice_info)
-
-/*----------------------------------------------------------------*/
-
-/* The info entry of awe_voice_rec is changed from 0 to 1
- * for some compilers refusing zero size array.
- * Due to this change, sizeof(awe_voice_rec) becomes different
- * from older versions.
- * Use AWE_VOICE_REC_SIZE instead.
- */
-
-/* instrument info header: 4 bytes */
-typedef struct _awe_voice_rec_hdr {
- unsigned char bank; /* midi bank number */
- unsigned char instr; /* midi preset number */
- char nvoices; /* number of voices */
- char write_mode; /* write mode; normally 0 */
-#define AWE_WR_APPEND 0 /* append anyway */
-#define AWE_WR_EXCLUSIVE 1 /* skip if already exists */
-#define AWE_WR_REPLACE 2 /* replace if already exists */
-} awe_voice_rec_hdr;
-
-/*#define AWE_VOICE_REC_SIZE 4*/
-#define AWE_VOICE_REC_SIZE sizeof(awe_voice_rec_hdr)
-
-/* the standard patch structure for one sample */
-typedef struct _awe_voice_rec_patch {
- awe_patch_info patch;
- awe_voice_rec_hdr hdr;
- awe_voice_info info;
-} awe_voice_rec_patch;
-
-
-/* obsolete data type */
-#if defined(AWE_COMPAT_030) && AWE_COMPAT_030
-#define AWE_INFOARRAY_SIZE 0
-#else
-#define AWE_INFOARRAY_SIZE 1
-#endif
-
-typedef struct _awe_voice_rec {
- unsigned char bank; /* midi bank number */
- unsigned char instr; /* midi preset number */
- short nvoices; /* number of voices */
- /* voice information follows here */
- awe_voice_info info[AWE_INFOARRAY_SIZE];
-} awe_voice_rec;
-
-
-/*----------------------------------------------------------------
- * sample wave information
- *----------------------------------------------------------------*/
-
-/* wave table sample header: 32 bytes */
-typedef struct awe_sample_info {
- unsigned short sf_id; /* file id (should be zero) */
- unsigned short sample; /* sample id */
- int start, end; /* start & end offset */
- int loopstart, loopend; /* loop start & end offset */
- int size; /* size (0 = ROM) */
- short checksum_flag; /* use check sum = 1 */
- unsigned short mode_flags; /* mode flags */
-#define AWE_SAMPLE_8BITS 1 /* wave data is 8bits */
-#define AWE_SAMPLE_UNSIGNED 2 /* wave data is unsigned */
-#define AWE_SAMPLE_NO_BLANK 4 /* no blank loop is attached */
-#define AWE_SAMPLE_SINGLESHOT 8 /* single-shot w/o loop */
-#define AWE_SAMPLE_BIDIR_LOOP 16 /* bidirectional looping */
-#define AWE_SAMPLE_STEREO_LEFT 32 /* stereo left sound */
-#define AWE_SAMPLE_STEREO_RIGHT 64 /* stereo right sound */
-#define AWE_SAMPLE_REVERSE_LOOP 128 /* reverse looping */
- unsigned int checksum; /* check sum */
-#if defined(AWE_COMPAT_030) && AWE_COMPAT_030
- unsigned short data[0]; /* sample data follows here */
-#endif
-} awe_sample_info;
-
-/*#define AWE_SAMPLE_INFO_SIZE 32*/
-#define AWE_SAMPLE_INFO_SIZE sizeof(awe_sample_info)
-
-
-/*----------------------------------------------------------------
- * voice preset mapping
- *----------------------------------------------------------------*/
-
-typedef struct awe_voice_map {
- int map_bank, map_instr, map_key; /* key = -1 means all keys */
- int src_bank, src_instr, src_key;
-} awe_voice_map;
-
-#define AWE_VOICE_MAP_SIZE sizeof(awe_voice_map)
-
-
-/*----------------------------------------------------------------
- * awe hardware controls
- *----------------------------------------------------------------*/
-
-#define _AWE_DEBUG_MODE 0x00
-#define _AWE_REVERB_MODE 0x01
-#define _AWE_CHORUS_MODE 0x02
-#define _AWE_REMOVE_LAST_SAMPLES 0x03
-#define _AWE_INITIALIZE_CHIP 0x04
-#define _AWE_SEND_EFFECT 0x05
-#define _AWE_TERMINATE_CHANNEL 0x06
-#define _AWE_TERMINATE_ALL 0x07
-#define _AWE_INITIAL_VOLUME 0x08
-#define _AWE_INITIAL_ATTEN _AWE_INITIAL_VOLUME
-#define _AWE_RESET_CHANNEL 0x09
-#define _AWE_CHANNEL_MODE 0x0a
-#define _AWE_DRUM_CHANNELS 0x0b
-#define _AWE_MISC_MODE 0x0c
-#define _AWE_RELEASE_ALL 0x0d
-#define _AWE_NOTEOFF_ALL 0x0e
-#define _AWE_CHN_PRESSURE 0x0f
-/*#define _AWE_GET_CURRENT_MODE 0x10*/
-#define _AWE_EQUALIZER 0x11
-/*#define _AWE_GET_MISC_MODE 0x12*/
-/*#define _AWE_GET_FONTINFO 0x13*/
-
-#define _AWE_MODE_FLAG 0x80
-#define _AWE_COOKED_FLAG 0x40 /* not supported */
-#define _AWE_MODE_VALUE_MASK 0x3F
-
-/*----------------------------------------------------------------*/
-
-#define _AWE_SET_CMD(p,dev,voice,cmd,p1,p2) \
-{((char*)(p))[0] = SEQ_PRIVATE;\
- ((char*)(p))[1] = dev;\
- ((char*)(p))[2] = _AWE_MODE_FLAG|(cmd);\
- ((char*)(p))[3] = voice;\
- ((unsigned short*)(p))[2] = p1;\
- ((unsigned short*)(p))[3] = p2;}
-
-/* buffered access */
-#define _AWE_CMD(dev, voice, cmd, p1, p2) \
-{_SEQ_NEEDBUF(8);\
- _AWE_SET_CMD(_seqbuf + _seqbufptr, dev, voice, cmd, p1, p2);\
- _SEQ_ADVBUF(8);}
-
-/* direct access */
-#define _AWE_CMD_NOW(seqfd,dev,voice,cmd,p1,p2) \
-{struct seq_event_rec tmp;\
- _AWE_SET_CMD(&tmp, dev, voice, cmd, p1, p2);\
- ioctl(seqfd, SNDCTL_SEQ_OUTOFBAND, &tmp);}
-
-/*----------------------------------------------------------------*/
-
-/* set debugging mode */
-#define AWE_DEBUG_MODE(dev,p1) _AWE_CMD(dev, 0, _AWE_DEBUG_MODE, p1, 0)
-/* set reverb mode; from 0 to 7 */
-#define AWE_REVERB_MODE(dev,p1) _AWE_CMD(dev, 0, _AWE_REVERB_MODE, p1, 0)
-/* set chorus mode; from 0 to 7 */
-#define AWE_CHORUS_MODE(dev,p1) _AWE_CMD(dev, 0, _AWE_CHORUS_MODE, p1, 0)
-
-/* reset channel */
-#define AWE_RESET_CHANNEL(dev,ch) _AWE_CMD(dev, ch, _AWE_RESET_CHANNEL, 0, 0)
-#define AWE_RESET_CONTROL(dev,ch) _AWE_CMD(dev, ch, _AWE_RESET_CHANNEL, 1, 0)
-
-/* send an effect to all layers */
-#define AWE_SEND_EFFECT(dev,voice,type,value) _AWE_CMD(dev,voice,_AWE_SEND_EFFECT,type,value)
-#define AWE_ADD_EFFECT(dev,voice,type,value) _AWE_CMD(dev,voice,_AWE_SEND_EFFECT,((type)|0x80),value)
-#define AWE_UNSET_EFFECT(dev,voice,type) _AWE_CMD(dev,voice,_AWE_SEND_EFFECT,((type)|0x40),0)
-/* send an effect to a layer */
-#define AWE_SEND_LAYER_EFFECT(dev,voice,layer,type,value) _AWE_CMD(dev,voice,_AWE_SEND_EFFECT,((layer+1)<<8|(type)),value)
-#define AWE_ADD_LAYER_EFFECT(dev,voice,layer,type,value) _AWE_CMD(dev,voice,_AWE_SEND_EFFECT,((layer+1)<<8|(type)|0x80),value)
-#define AWE_UNSET_LAYER_EFFECT(dev,voice,layer,type) _AWE_CMD(dev,voice,_AWE_SEND_EFFECT,((layer+1)<<8|(type)|0x40),0)
-
-/* terminate sound on the channel/voice */
-#define AWE_TERMINATE_CHANNEL(dev,voice) _AWE_CMD(dev,voice,_AWE_TERMINATE_CHANNEL,0,0)
-/* terminate all sounds */
-#define AWE_TERMINATE_ALL(dev) _AWE_CMD(dev, 0, _AWE_TERMINATE_ALL, 0, 0)
-/* release all sounds (w/o sustain effect) */
-#define AWE_RELEASE_ALL(dev) _AWE_CMD(dev, 0, _AWE_RELEASE_ALL, 0, 0)
-/* note off all sounds (w sustain effect) */
-#define AWE_NOTEOFF_ALL(dev) _AWE_CMD(dev, 0, _AWE_NOTEOFF_ALL, 0, 0)
-
-/* set initial attenuation */
-#define AWE_INITIAL_VOLUME(dev,atten) _AWE_CMD(dev, 0, _AWE_INITIAL_VOLUME, atten, 0)
-#define AWE_INITIAL_ATTEN AWE_INITIAL_VOLUME
-/* relative attenuation */
-#define AWE_SET_ATTEN(dev,atten) _AWE_CMD(dev, 0, _AWE_INITIAL_VOLUME, atten, 1)
-
-/* set channel playing mode; mode=0/1/2 */
-#define AWE_SET_CHANNEL_MODE(dev,mode) _AWE_CMD(dev, 0, _AWE_CHANNEL_MODE, mode, 0)
-#define AWE_PLAY_INDIRECT 0 /* indirect voice mode (default) */
-#define AWE_PLAY_MULTI 1 /* multi note voice mode */
-#define AWE_PLAY_DIRECT 2 /* direct single voice mode */
-#define AWE_PLAY_MULTI2 3 /* sequencer2 mode; used internally */
-
-/* set drum channel mask; channels is 32bit long value */
-#define AWE_DRUM_CHANNELS(dev,channels) _AWE_CMD(dev, 0, _AWE_DRUM_CHANNELS, ((channels) & 0xffff), ((channels) >> 16))
-
-/* set bass and treble control; values are from 0 to 11 */
-#define AWE_EQUALIZER(dev,bass,treble) _AWE_CMD(dev, 0, _AWE_EQUALIZER, bass, treble)
-
-/* remove last loaded samples */
-#define AWE_REMOVE_LAST_SAMPLES(seqfd,dev) _AWE_CMD_NOW(seqfd, dev, 0, _AWE_REMOVE_LAST_SAMPLES, 0, 0)
-/* initialize emu8000 chip */
-#define AWE_INITIALIZE_CHIP(seqfd,dev) _AWE_CMD_NOW(seqfd, dev, 0, _AWE_INITIALIZE_CHIP, 0, 0)
-
-/* set miscellaneous modes; meta command */
-#define AWE_MISC_MODE(dev,mode,value) _AWE_CMD(dev, 0, _AWE_MISC_MODE, mode, value)
-/* exclusive sound off; 1=off */
-#define AWE_EXCLUSIVE_SOUND(dev,mode) AWE_MISC_MODE(dev,AWE_MD_EXCLUSIVE_SOUND,mode)
-/* default GUS bank number */
-#define AWE_SET_GUS_BANK(dev,bank) AWE_MISC_MODE(dev,AWE_MD_GUS_BANK,bank)
-/* change panning position in realtime; 0=don't 1=do */
-#define AWE_REALTIME_PAN(dev,mode) AWE_MISC_MODE(dev,AWE_MD_REALTIME_PAN,mode)
-
-/* extended pressure controls; not portable with other sound drivers */
-#define AWE_KEY_PRESSURE(dev,ch,note,vel) SEQ_START_NOTE(dev,ch,(note)+128,vel)
-#define AWE_CHN_PRESSURE(dev,ch,vel) _AWE_CMD(dev,ch,_AWE_CHN_PRESSURE,vel,0)
-
-/*----------------------------------------------------------------*/
-
-/* reverb mode parameters */
-#define AWE_REVERB_ROOM1 0
-#define AWE_REVERB_ROOM2 1
-#define AWE_REVERB_ROOM3 2
-#define AWE_REVERB_HALL1 3
-#define AWE_REVERB_HALL2 4
-#define AWE_REVERB_PLATE 5
-#define AWE_REVERB_DELAY 6
-#define AWE_REVERB_PANNINGDELAY 7
-#define AWE_REVERB_PREDEFINED 8
-/* user can define reverb modes up to 32 */
-#define AWE_REVERB_NUMBERS 32
-
-typedef struct awe_reverb_fx_rec {
- unsigned short parms[28];
-} awe_reverb_fx_rec;
-
-/*----------------------------------------------------------------*/
-
-/* chorus mode parameters */
-#define AWE_CHORUS_1 0
-#define AWE_CHORUS_2 1
-#define AWE_CHORUS_3 2
-#define AWE_CHORUS_4 3
-#define AWE_CHORUS_FEEDBACK 4
-#define AWE_CHORUS_FLANGER 5
-#define AWE_CHORUS_SHORTDELAY 6
-#define AWE_CHORUS_SHORTDELAY2 7
-#define AWE_CHORUS_PREDEFINED 8
-/* user can define chorus modes up to 32 */
-#define AWE_CHORUS_NUMBERS 32
-
-typedef struct awe_chorus_fx_rec {
- unsigned short feedback; /* feedback level (0xE600-0xE6FF) */
- unsigned short delay_offset; /* delay (0-0x0DA3) [1/44100 sec] */
- unsigned short lfo_depth; /* LFO depth (0xBC00-0xBCFF) */
- unsigned int delay; /* right delay (0-0xFFFFFFFF) [1/256/44100 sec] */
- unsigned int lfo_freq; /* LFO freq LFO freq (0-0xFFFFFFFF) */
-} awe_chorus_fx_rec;
-
-/*----------------------------------------------------------------*/
-
-/* misc mode types */
-enum {
-/* 0*/ AWE_MD_EXCLUSIVE_OFF, /* obsolete */
-/* 1*/ AWE_MD_EXCLUSIVE_ON, /* obsolete */
-/* 2*/ AWE_MD_VERSION, /* read only */
-/* 3*/ AWE_MD_EXCLUSIVE_SOUND, /* 0/1: exclusive note on (default=1) */
-/* 4*/ AWE_MD_REALTIME_PAN, /* 0/1: do realtime pan change (default=1) */
-/* 5*/ AWE_MD_GUS_BANK, /* bank number for GUS patches (default=0) */
-/* 6*/ AWE_MD_KEEP_EFFECT, /* 0/1: keep effect values, (default=0) */
-/* 7*/ AWE_MD_ZERO_ATTEN, /* attenuation of max volume (default=32) */
-/* 8*/ AWE_MD_CHN_PRIOR, /* 0/1: set MIDI channel priority mode (default=1) */
-/* 9*/ AWE_MD_MOD_SENSE, /* integer: modwheel sensitivity (def=18) */
-/*10*/ AWE_MD_DEF_PRESET, /* integer: default preset number (def=0) */
-/*11*/ AWE_MD_DEF_BANK, /* integer: default bank number (def=0) */
-/*12*/ AWE_MD_DEF_DRUM, /* integer: default drumset number (def=0) */
-/*13*/ AWE_MD_TOGGLE_DRUM_BANK, /* 0/1: toggle drum flag with bank# (def=0) */
-/*14*/ AWE_MD_NEW_VOLUME_CALC, /* 0/1: volume calculation mode (def=1) */
-/*15*/ AWE_MD_CHORUS_MODE, /* integer: chorus mode (def=2) */
-/*16*/ AWE_MD_REVERB_MODE, /* integer: chorus mode (def=4) */
-/*17*/ AWE_MD_BASS_LEVEL, /* integer: bass level (def=5) */
-/*18*/ AWE_MD_TREBLE_LEVEL, /* integer: treble level (def=9) */
-/*19*/ AWE_MD_DEBUG_MODE, /* integer: debug level (def=0) */
-/*20*/ AWE_MD_PAN_EXCHANGE, /* 0/1: exchange panning direction (def=0) */
- AWE_MD_END,
-};
-
-/*----------------------------------------------------------------*/
-
-/* effect parameters */
-enum {
-
-/* modulation envelope parameters */
-/* 0*/ AWE_FX_ENV1_DELAY, /* WORD: ENVVAL */
-/* 1*/ AWE_FX_ENV1_ATTACK, /* BYTE: up ATKHLD */
-/* 2*/ AWE_FX_ENV1_HOLD, /* BYTE: lw ATKHLD */
-/* 3*/ AWE_FX_ENV1_DECAY, /* BYTE: lw DCYSUS */
-/* 4*/ AWE_FX_ENV1_RELEASE, /* BYTE: lw DCYSUS */
-/* 5*/ AWE_FX_ENV1_SUSTAIN, /* BYTE: up DCYSUS */
-/* 6*/ AWE_FX_ENV1_PITCH, /* BYTE: up PEFE */
-/* 7*/ AWE_FX_ENV1_CUTOFF, /* BYTE: lw PEFE */
-
-/* volume envelope parameters */
-/* 8*/ AWE_FX_ENV2_DELAY, /* WORD: ENVVOL */
-/* 9*/ AWE_FX_ENV2_ATTACK, /* BYTE: up ATKHLDV */
-/*10*/ AWE_FX_ENV2_HOLD, /* BYTE: lw ATKHLDV */
-/*11*/ AWE_FX_ENV2_DECAY, /* BYTE: lw DCYSUSV */
-/*12*/ AWE_FX_ENV2_RELEASE, /* BYTE: lw DCYSUSV */
-/*13*/ AWE_FX_ENV2_SUSTAIN, /* BYTE: up DCYSUSV */
-
-/* LFO1 (tremolo & vibrato) parameters */
-/*14*/ AWE_FX_LFO1_DELAY, /* WORD: LFO1VAL */
-/*15*/ AWE_FX_LFO1_FREQ, /* BYTE: lo TREMFRQ */
-/*16*/ AWE_FX_LFO1_VOLUME, /* BYTE: up TREMFRQ */
-/*17*/ AWE_FX_LFO1_PITCH, /* BYTE: up FMMOD */
-/*18*/ AWE_FX_LFO1_CUTOFF, /* BYTE: lo FMMOD */
-
-/* LFO2 (vibrato) parameters */
-/*19*/ AWE_FX_LFO2_DELAY, /* WORD: LFO2VAL */
-/*20*/ AWE_FX_LFO2_FREQ, /* BYTE: lo FM2FRQ2 */
-/*21*/ AWE_FX_LFO2_PITCH, /* BYTE: up FM2FRQ2 */
-
-/* Other overall effect parameters */
-/*22*/ AWE_FX_INIT_PITCH, /* SHORT: pitch offset */
-/*23*/ AWE_FX_CHORUS, /* BYTE: chorus effects send (0-255) */
-/*24*/ AWE_FX_REVERB, /* BYTE: reverb effects send (0-255) */
-/*25*/ AWE_FX_CUTOFF, /* BYTE: up IFATN */
-/*26*/ AWE_FX_FILTERQ, /* BYTE: up CCCA */
-
-/* Sample / loop offset changes */
-/*27*/ AWE_FX_SAMPLE_START, /* SHORT: offset */
-/*28*/ AWE_FX_LOOP_START, /* SHORT: offset */
-/*29*/ AWE_FX_LOOP_END, /* SHORT: offset */
-/*30*/ AWE_FX_COARSE_SAMPLE_START, /* SHORT: upper word offset */
-/*31*/ AWE_FX_COARSE_LOOP_START, /* SHORT: upper word offset */
-/*32*/ AWE_FX_COARSE_LOOP_END, /* SHORT: upper word offset */
-/*33*/ AWE_FX_ATTEN, /* BYTE: lo IFATN */
-
- AWE_FX_END,
-};
-
-#endif /* AWE_VOICE_H */
diff --git a/include/linux/byteorder/generic.h b/include/linux/byteorder/generic.h
index e86e4a9..3dc715b 100644
--- a/include/linux/byteorder/generic.h
+++ b/include/linux/byteorder/generic.h
@@ -124,19 +124,8 @@
#define be32_to_cpus __be32_to_cpus
#define cpu_to_be16s __cpu_to_be16s
#define be16_to_cpus __be16_to_cpus
-#endif
-
-#if defined(__KERNEL__)
/*
- * Handle ntohl and suches. These have various compatibility
- * issues - like we want to give the prototype even though we
- * also have a macro for them in case some strange program
- * wants to take the address of the thing or something..
- *
- * Note that these used to return a "long" in libc5, even though
- * long is often 64-bit these days.. Thus the casts.
- *
* They have to be macros in order to do the constant folding
* correctly - if the argument passed into a inline function
* it is no longer constant according to gcc..
@@ -147,17 +136,6 @@
#undef htonl
#undef htons
-/*
- * Do the prototypes. Somebody might want to take the
- * address or some such sick thing..
- */
-extern __u32 ntohl(__be32);
-extern __be32 htonl(__u32);
-extern __u16 ntohs(__be16);
-extern __be16 htons(__u16);
-
-#if defined(__GNUC__) && defined(__OPTIMIZE__)
-
#define ___htonl(x) __cpu_to_be32(x)
#define ___htons(x) __cpu_to_be16(x)
#define ___ntohl(x) __be32_to_cpu(x)
@@ -168,9 +146,6 @@
#define htons(x) ___htons(x)
#define ntohs(x) ___ntohs(x)
-#endif /* OPTIMIZE */
-
#endif /* KERNEL */
-
#endif /* _LINUX_BYTEORDER_GENERIC_H */
diff --git a/include/linux/byteorder/swab.h b/include/linux/byteorder/swab.h
index 25f7f32..142134f 100644
--- a/include/linux/byteorder/swab.h
+++ b/include/linux/byteorder/swab.h
@@ -10,6 +10,10 @@
* separated swab functions from cpu_to_XX,
* to clean up support for bizarre-endian architectures.
*
+ * Trent Piepho <xyzzy@speakeasy.org> 2007114
+ * make constant-folding work, provide C versions that
+ * gcc can optimize better, explain different versions
+ *
* See asm-i386/byteorder.h and suches for examples of how to provide
* architecture-dependent optimized versions
*
@@ -17,40 +21,66 @@
#include <linux/compiler.h>
+/* Functions/macros defined, there are a lot:
+ *
+ * ___swabXX
+ * Generic C versions of the swab functions.
+ *
+ * ___constant_swabXX
+ * C versions that gcc can fold into a compile-time constant when
+ * the argument is a compile-time constant.
+ *
+ * __arch__swabXX[sp]?
+ * Architecture optimized versions of all the swab functions
+ * (including the s and p versions). These can be defined in
+ * asm-arch/byteorder.h. Any which are not, are defined here.
+ * __arch__swabXXs() is defined in terms of __arch__swabXXp(), which
+ * is defined in terms of __arch__swabXX(), which is in turn defined
+ * in terms of ___swabXX(x).
+ * These must be macros. They may be unsafe for arguments with
+ * side-effects.
+ *
+ * __fswabXX
+ * Inline function versions of the __arch__ macros. These _are_ safe
+ * if the arguments have side-effects. Note there are no s and p
+ * versions of these.
+ *
+ * __swabXX[sb]
+ * There are the ones you should actually use. The __swabXX versions
+ * will be a constant given a constant argument and use the arch
+ * specific code (if any) for non-constant arguments. The s and p
+ * versions always use the arch specific code (constant folding
+ * doesn't apply). They are safe to use with arguments with
+ * side-effects.
+ *
+ * swabXX[sb]
+ * Nicknames for __swabXX[sb] to use in the kernel.
+ */
+
/* casts are necessary for constants, because we never know how for sure
* how U/UL/ULL map to __u16, __u32, __u64. At least not in a portable way.
*/
-#define ___swab16(x) \
-({ \
- __u16 __x = (x); \
- ((__u16)( \
- (((__u16)(__x) & (__u16)0x00ffU) << 8) | \
- (((__u16)(__x) & (__u16)0xff00U) >> 8) )); \
-})
-#define ___swab32(x) \
-({ \
- __u32 __x = (x); \
- ((__u32)( \
- (((__u32)(__x) & (__u32)0x000000ffUL) << 24) | \
- (((__u32)(__x) & (__u32)0x0000ff00UL) << 8) | \
- (((__u32)(__x) & (__u32)0x00ff0000UL) >> 8) | \
- (((__u32)(__x) & (__u32)0xff000000UL) >> 24) )); \
-})
-
-#define ___swab64(x) \
-({ \
- __u64 __x = (x); \
- ((__u64)( \
- (__u64)(((__u64)(__x) & (__u64)0x00000000000000ffULL) << 56) | \
- (__u64)(((__u64)(__x) & (__u64)0x000000000000ff00ULL) << 40) | \
- (__u64)(((__u64)(__x) & (__u64)0x0000000000ff0000ULL) << 24) | \
- (__u64)(((__u64)(__x) & (__u64)0x00000000ff000000ULL) << 8) | \
- (__u64)(((__u64)(__x) & (__u64)0x000000ff00000000ULL) >> 8) | \
- (__u64)(((__u64)(__x) & (__u64)0x0000ff0000000000ULL) >> 24) | \
- (__u64)(((__u64)(__x) & (__u64)0x00ff000000000000ULL) >> 40) | \
- (__u64)(((__u64)(__x) & (__u64)0xff00000000000000ULL) >> 56) )); \
-})
+static __inline__ __attribute_const__ __u16 ___swab16(__u16 x)
+{
+ return x<<8 | x>>8;
+}
+static __inline__ __attribute_const__ __u32 ___swab32(__u32 x)
+{
+ return x<<24 | x>>24 |
+ (x & (__u32)0x0000ff00UL)<<8 |
+ (x & (__u32)0x00ff0000UL)>>8;
+}
+static __inline__ __attribute_const__ __u64 ___swab64(__u64 x)
+{
+ return x<<56 | x>>56 |
+ (x & (__u64)0x000000000000ff00ULL)<<40 |
+ (x & (__u64)0x0000000000ff0000ULL)<<24 |
+ (x & (__u64)0x00000000ff000000ULL)<< 8 |
+ (x & (__u64)0x000000ff00000000ULL)>> 8 |
+ (x & (__u64)0x0000ff0000000000ULL)>>24 |
+ (x & (__u64)0x00ff000000000000ULL)>>40;
+}
#define ___constant_swab16(x) \
((__u16)( \
@@ -77,13 +107,13 @@
* provide defaults when no architecture-specific optimization is detected
*/
#ifndef __arch__swab16
-# define __arch__swab16(x) ({ __u16 __tmp = (x) ; ___swab16(__tmp); })
+# define __arch__swab16(x) ___swab16(x)
#endif
#ifndef __arch__swab32
-# define __arch__swab32(x) ({ __u32 __tmp = (x) ; ___swab32(__tmp); })
+# define __arch__swab32(x) ___swab32(x)
#endif
#ifndef __arch__swab64
-# define __arch__swab64(x) ({ __u64 __tmp = (x) ; ___swab64(__tmp); })
+# define __arch__swab64(x) ___swab64(x)
#endif
#ifndef __arch__swab16p
@@ -97,13 +127,13 @@
#endif
#ifndef __arch__swab16s
-# define __arch__swab16s(x) do { *(x) = __arch__swab16p((x)); } while (0)
+# define __arch__swab16s(x) ((void)(*(x) = __arch__swab16p(x)))
#endif
#ifndef __arch__swab32s
-# define __arch__swab32s(x) do { *(x) = __arch__swab32p((x)); } while (0)
+# define __arch__swab32s(x) ((void)(*(x) = __arch__swab32p(x)))
#endif
#ifndef __arch__swab64s
-# define __arch__swab64s(x) do { *(x) = __arch__swab64p((x)); } while (0)
+# define __arch__swab64s(x) ((void)(*(x) = __arch__swab64p(x)))
#endif
@@ -113,15 +143,15 @@
#if defined(__GNUC__) && defined(__OPTIMIZE__)
# define __swab16(x) \
(__builtin_constant_p((__u16)(x)) ? \
- ___swab16((x)) : \
+ ___constant_swab16((x)) : \
__fswab16((x)))
# define __swab32(x) \
(__builtin_constant_p((__u32)(x)) ? \
- ___swab32((x)) : \
+ ___constant_swab32((x)) : \
__fswab32((x)))
# define __swab64(x) \
(__builtin_constant_p((__u64)(x)) ? \
- ___swab64((x)) : \
+ ___constant_swab64((x)) : \
__fswab64((x)))
#else
# define __swab16(x) __fswab16(x)
diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
index 4ea7e7b..8486e78 100644
--- a/include/linux/clockchips.h
+++ b/include/linux/clockchips.h
@@ -54,17 +54,17 @@
/**
* struct clock_event_device - clock event device descriptor
* @name: ptr to clock event name
- * @hints: usage hints
+ * @features: features
* @max_delta_ns: maximum delta value in ns
* @min_delta_ns: minimum delta value in ns
* @mult: nanosecond to cycles multiplier
* @shift: nanoseconds to cycles divisor (power of two)
* @rating: variable to rate clock event devices
- * @irq: irq number (only for non cpu local devices)
- * @cpumask: cpumask to indicate for which cpus this device works
- * @set_next_event: set next event
+ * @irq: IRQ number (only for non CPU local devices)
+ * @cpumask: cpumask to indicate for which CPUs this device works
+ * @set_next_event: set next event function
* @set_mode: set mode function
- * @evthandler: Assigned by the framework to be called by the low
+ * @event_handler: Assigned by the framework to be called by the low
* level handler of the event source
* @broadcast: function to broadcast events
* @list: list head for the management code
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
index daa4940..2665ca0 100644
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -12,6 +12,7 @@
#include <linux/timex.h>
#include <linux/time.h>
#include <linux/list.h>
+#include <linux/cache.h>
#include <linux/timer.h>
#include <asm/div64.h>
#include <asm/io.h>
@@ -52,6 +53,9 @@
* @xtime_interval: Used internally by timekeeping core, please ignore.
*/
struct clocksource {
+ /*
+ * First part of structure is read mostly
+ */
char *name;
struct list_head list;
int rating;
@@ -63,8 +67,15 @@
cycle_t (*vread)(void);
/* timekeeping specific data, ignore */
- cycle_t cycle_last, cycle_interval;
- u64 xtime_nsec, xtime_interval;
+ cycle_t cycle_interval;
+ u64 xtime_interval;
+ /*
+ * Second part is written at each timer interrupt
+ * Keep it in a different cache line to dirty no
+ * more than one cache line.
+ */
+ cycle_t cycle_last ____cacheline_aligned_in_smp;
+ u64 xtime_nsec;
s64 error;
#ifdef CONFIG_CLOCKSOURCE_WATCHDOG
diff --git a/include/linux/compat_ioctl.h b/include/linux/compat_ioctl.h
deleted file mode 100644
index c26c3ad..0000000
--- a/include/linux/compat_ioctl.h
+++ /dev/null
@@ -1,830 +0,0 @@
-/* List here explicitly which ioctl's are known to have
- * compatible types passed or none at all... Please include
- * only stuff that is compatible on *all architectures*.
- */
-
-COMPATIBLE_IOCTL(0x4B50) /* KDGHWCLK - not in the kernel, but don't complain */
-COMPATIBLE_IOCTL(0x4B51) /* KDSHWCLK - not in the kernel, but don't complain */
-
-/* Big T */
-COMPATIBLE_IOCTL(TCGETA)
-COMPATIBLE_IOCTL(TCSETA)
-COMPATIBLE_IOCTL(TCSETAW)
-COMPATIBLE_IOCTL(TCSETAF)
-COMPATIBLE_IOCTL(TCSBRK)
-ULONG_IOCTL(TCSBRKP)
-COMPATIBLE_IOCTL(TCXONC)
-COMPATIBLE_IOCTL(TCFLSH)
-COMPATIBLE_IOCTL(TCGETS)
-COMPATIBLE_IOCTL(TCSETS)
-COMPATIBLE_IOCTL(TCSETSW)
-COMPATIBLE_IOCTL(TCSETSF)
-COMPATIBLE_IOCTL(TIOCLINUX)
-COMPATIBLE_IOCTL(TIOCSBRK)
-COMPATIBLE_IOCTL(TIOCCBRK)
-ULONG_IOCTL(TIOCMIWAIT)
-COMPATIBLE_IOCTL(TIOCGICOUNT)
-/* Little t */
-COMPATIBLE_IOCTL(TIOCGETD)
-COMPATIBLE_IOCTL(TIOCSETD)
-COMPATIBLE_IOCTL(TIOCEXCL)
-COMPATIBLE_IOCTL(TIOCNXCL)
-COMPATIBLE_IOCTL(TIOCCONS)
-COMPATIBLE_IOCTL(TIOCGSOFTCAR)
-COMPATIBLE_IOCTL(TIOCSSOFTCAR)
-COMPATIBLE_IOCTL(TIOCSWINSZ)
-COMPATIBLE_IOCTL(TIOCGWINSZ)
-COMPATIBLE_IOCTL(TIOCMGET)
-COMPATIBLE_IOCTL(TIOCMBIC)
-COMPATIBLE_IOCTL(TIOCMBIS)
-COMPATIBLE_IOCTL(TIOCMSET)
-COMPATIBLE_IOCTL(TIOCPKT)
-COMPATIBLE_IOCTL(TIOCNOTTY)
-COMPATIBLE_IOCTL(TIOCSTI)
-COMPATIBLE_IOCTL(TIOCOUTQ)
-COMPATIBLE_IOCTL(TIOCSPGRP)
-COMPATIBLE_IOCTL(TIOCGPGRP)
-ULONG_IOCTL(TIOCSCTTY)
-COMPATIBLE_IOCTL(TIOCGPTN)
-COMPATIBLE_IOCTL(TIOCSPTLCK)
-COMPATIBLE_IOCTL(TIOCSERGETLSR)
-/* Little f */
-COMPATIBLE_IOCTL(FIOCLEX)
-COMPATIBLE_IOCTL(FIONCLEX)
-COMPATIBLE_IOCTL(FIOASYNC)
-COMPATIBLE_IOCTL(FIONBIO)
-COMPATIBLE_IOCTL(FIONREAD) /* This is also TIOCINQ */
-/* 0x00 */
-COMPATIBLE_IOCTL(FIBMAP)
-COMPATIBLE_IOCTL(FIGETBSZ)
-/* 0x03 -- HD/IDE ioctl's used by hdparm and friends.
- * Some need translations, these do not.
- */
-COMPATIBLE_IOCTL(HDIO_GET_IDENTITY)
-COMPATIBLE_IOCTL(HDIO_DRIVE_TASK)
-COMPATIBLE_IOCTL(HDIO_DRIVE_CMD)
-ULONG_IOCTL(HDIO_SET_MULTCOUNT)
-ULONG_IOCTL(HDIO_SET_UNMASKINTR)
-ULONG_IOCTL(HDIO_SET_KEEPSETTINGS)
-ULONG_IOCTL(HDIO_SET_32BIT)
-ULONG_IOCTL(HDIO_SET_NOWERR)
-ULONG_IOCTL(HDIO_SET_DMA)
-ULONG_IOCTL(HDIO_SET_PIO_MODE)
-ULONG_IOCTL(HDIO_SET_NICE)
-ULONG_IOCTL(HDIO_SET_WCACHE)
-ULONG_IOCTL(HDIO_SET_ACOUSTIC)
-ULONG_IOCTL(HDIO_SET_BUSSTATE)
-ULONG_IOCTL(HDIO_SET_ADDRESS)
-COMPATIBLE_IOCTL(HDIO_SCAN_HWIF)
-/* 0x330 is reserved -- it used to be HDIO_GETGEO_BIG */
-COMPATIBLE_IOCTL(0x330)
-/* 0x02 -- Floppy ioctls */
-COMPATIBLE_IOCTL(FDMSGON)
-COMPATIBLE_IOCTL(FDMSGOFF)
-COMPATIBLE_IOCTL(FDSETEMSGTRESH)
-COMPATIBLE_IOCTL(FDFLUSH)
-COMPATIBLE_IOCTL(FDWERRORCLR)
-COMPATIBLE_IOCTL(FDSETMAXERRS)
-COMPATIBLE_IOCTL(FDGETMAXERRS)
-COMPATIBLE_IOCTL(FDGETDRVTYP)
-COMPATIBLE_IOCTL(FDEJECT)
-COMPATIBLE_IOCTL(FDCLRPRM)
-COMPATIBLE_IOCTL(FDFMTBEG)
-COMPATIBLE_IOCTL(FDFMTEND)
-COMPATIBLE_IOCTL(FDRESET)
-COMPATIBLE_IOCTL(FDTWADDLE)
-COMPATIBLE_IOCTL(FDFMTTRK)
-COMPATIBLE_IOCTL(FDRAWCMD)
-/* 0x12 */
-#ifdef CONFIG_BLOCK
-COMPATIBLE_IOCTL(BLKRASET)
-COMPATIBLE_IOCTL(BLKROSET)
-COMPATIBLE_IOCTL(BLKROGET)
-COMPATIBLE_IOCTL(BLKRRPART)
-COMPATIBLE_IOCTL(BLKFLSBUF)
-COMPATIBLE_IOCTL(BLKSECTSET)
-COMPATIBLE_IOCTL(BLKSSZGET)
-COMPATIBLE_IOCTL(BLKTRACESTART)
-COMPATIBLE_IOCTL(BLKTRACESTOP)
-COMPATIBLE_IOCTL(BLKTRACESETUP)
-COMPATIBLE_IOCTL(BLKTRACETEARDOWN)
-ULONG_IOCTL(BLKRASET)
-ULONG_IOCTL(BLKFRASET)
-#endif
-/* RAID */
-COMPATIBLE_IOCTL(RAID_VERSION)
-COMPATIBLE_IOCTL(GET_ARRAY_INFO)
-COMPATIBLE_IOCTL(GET_DISK_INFO)
-COMPATIBLE_IOCTL(PRINT_RAID_DEBUG)
-COMPATIBLE_IOCTL(RAID_AUTORUN)
-COMPATIBLE_IOCTL(CLEAR_ARRAY)
-COMPATIBLE_IOCTL(ADD_NEW_DISK)
-ULONG_IOCTL(HOT_REMOVE_DISK)
-COMPATIBLE_IOCTL(SET_ARRAY_INFO)
-COMPATIBLE_IOCTL(SET_DISK_INFO)
-COMPATIBLE_IOCTL(WRITE_RAID_INFO)
-COMPATIBLE_IOCTL(UNPROTECT_ARRAY)
-COMPATIBLE_IOCTL(PROTECT_ARRAY)
-ULONG_IOCTL(HOT_ADD_DISK)
-ULONG_IOCTL(SET_DISK_FAULTY)
-COMPATIBLE_IOCTL(RUN_ARRAY)
-COMPATIBLE_IOCTL(STOP_ARRAY)
-COMPATIBLE_IOCTL(STOP_ARRAY_RO)
-COMPATIBLE_IOCTL(RESTART_ARRAY_RW)
-COMPATIBLE_IOCTL(GET_BITMAP_FILE)
-ULONG_IOCTL(SET_BITMAP_FILE)
-/* DM */
-COMPATIBLE_IOCTL(DM_VERSION_32)
-COMPATIBLE_IOCTL(DM_REMOVE_ALL_32)
-COMPATIBLE_IOCTL(DM_LIST_DEVICES_32)
-COMPATIBLE_IOCTL(DM_DEV_CREATE_32)
-COMPATIBLE_IOCTL(DM_DEV_REMOVE_32)
-COMPATIBLE_IOCTL(DM_DEV_RENAME_32)
-COMPATIBLE_IOCTL(DM_DEV_SUSPEND_32)
-COMPATIBLE_IOCTL(DM_DEV_STATUS_32)
-COMPATIBLE_IOCTL(DM_DEV_WAIT_32)
-COMPATIBLE_IOCTL(DM_TABLE_LOAD_32)
-COMPATIBLE_IOCTL(DM_TABLE_CLEAR_32)
-COMPATIBLE_IOCTL(DM_TABLE_DEPS_32)
-COMPATIBLE_IOCTL(DM_TABLE_STATUS_32)
-COMPATIBLE_IOCTL(DM_LIST_VERSIONS_32)
-COMPATIBLE_IOCTL(DM_TARGET_MSG_32)
-COMPATIBLE_IOCTL(DM_DEV_SET_GEOMETRY_32)
-COMPATIBLE_IOCTL(DM_VERSION)
-COMPATIBLE_IOCTL(DM_REMOVE_ALL)
-COMPATIBLE_IOCTL(DM_LIST_DEVICES)
-COMPATIBLE_IOCTL(DM_DEV_CREATE)
-COMPATIBLE_IOCTL(DM_DEV_REMOVE)
-COMPATIBLE_IOCTL(DM_DEV_RENAME)
-COMPATIBLE_IOCTL(DM_DEV_SUSPEND)
-COMPATIBLE_IOCTL(DM_DEV_STATUS)
-COMPATIBLE_IOCTL(DM_DEV_WAIT)
-COMPATIBLE_IOCTL(DM_TABLE_LOAD)
-COMPATIBLE_IOCTL(DM_TABLE_CLEAR)
-COMPATIBLE_IOCTL(DM_TABLE_DEPS)
-COMPATIBLE_IOCTL(DM_TABLE_STATUS)
-COMPATIBLE_IOCTL(DM_LIST_VERSIONS)
-COMPATIBLE_IOCTL(DM_TARGET_MSG)
-COMPATIBLE_IOCTL(DM_DEV_SET_GEOMETRY)
-/* Big K */
-COMPATIBLE_IOCTL(PIO_FONT)
-COMPATIBLE_IOCTL(GIO_FONT)
-ULONG_IOCTL(KDSIGACCEPT)
-COMPATIBLE_IOCTL(KDGETKEYCODE)
-COMPATIBLE_IOCTL(KDSETKEYCODE)
-ULONG_IOCTL(KIOCSOUND)
-ULONG_IOCTL(KDMKTONE)
-COMPATIBLE_IOCTL(KDGKBTYPE)
-ULONG_IOCTL(KDSETMODE)
-COMPATIBLE_IOCTL(KDGETMODE)
-ULONG_IOCTL(KDSKBMODE)
-COMPATIBLE_IOCTL(KDGKBMODE)
-ULONG_IOCTL(KDSKBMETA)
-COMPATIBLE_IOCTL(KDGKBMETA)
-COMPATIBLE_IOCTL(KDGKBENT)
-COMPATIBLE_IOCTL(KDSKBENT)
-COMPATIBLE_IOCTL(KDGKBSENT)
-COMPATIBLE_IOCTL(KDSKBSENT)
-COMPATIBLE_IOCTL(KDGKBDIACR)
-COMPATIBLE_IOCTL(KDSKBDIACR)
-COMPATIBLE_IOCTL(KDKBDREP)
-COMPATIBLE_IOCTL(KDGKBLED)
-ULONG_IOCTL(KDSKBLED)
-COMPATIBLE_IOCTL(KDGETLED)
-ULONG_IOCTL(KDSETLED)
-COMPATIBLE_IOCTL(GIO_SCRNMAP)
-COMPATIBLE_IOCTL(PIO_SCRNMAP)
-COMPATIBLE_IOCTL(GIO_UNISCRNMAP)
-COMPATIBLE_IOCTL(PIO_UNISCRNMAP)
-COMPATIBLE_IOCTL(PIO_FONTRESET)
-COMPATIBLE_IOCTL(PIO_UNIMAPCLR)
-/* Big S */
-COMPATIBLE_IOCTL(SCSI_IOCTL_GET_IDLUN)
-COMPATIBLE_IOCTL(SCSI_IOCTL_DOORLOCK)
-COMPATIBLE_IOCTL(SCSI_IOCTL_DOORUNLOCK)
-COMPATIBLE_IOCTL(SCSI_IOCTL_TEST_UNIT_READY)
-COMPATIBLE_IOCTL(SCSI_IOCTL_GET_BUS_NUMBER)
-COMPATIBLE_IOCTL(SCSI_IOCTL_SEND_COMMAND)
-COMPATIBLE_IOCTL(SCSI_IOCTL_PROBE_HOST)
-COMPATIBLE_IOCTL(SCSI_IOCTL_GET_PCI)
-/* Big T */
-COMPATIBLE_IOCTL(TUNSETNOCSUM)
-COMPATIBLE_IOCTL(TUNSETDEBUG)
-COMPATIBLE_IOCTL(TUNSETPERSIST)
-COMPATIBLE_IOCTL(TUNSETOWNER)
-/* Big V */
-COMPATIBLE_IOCTL(VT_SETMODE)
-COMPATIBLE_IOCTL(VT_GETMODE)
-COMPATIBLE_IOCTL(VT_GETSTATE)
-COMPATIBLE_IOCTL(VT_OPENQRY)
-ULONG_IOCTL(VT_ACTIVATE)
-ULONG_IOCTL(VT_WAITACTIVE)
-ULONG_IOCTL(VT_RELDISP)
-ULONG_IOCTL(VT_DISALLOCATE)
-COMPATIBLE_IOCTL(VT_RESIZE)
-COMPATIBLE_IOCTL(VT_RESIZEX)
-COMPATIBLE_IOCTL(VT_LOCKSWITCH)
-COMPATIBLE_IOCTL(VT_UNLOCKSWITCH)
-COMPATIBLE_IOCTL(VT_GETHIFONTMASK)
-/* Little p (/dev/rtc, /dev/envctrl, etc.) */
-COMPATIBLE_IOCTL(RTC_AIE_ON)
-COMPATIBLE_IOCTL(RTC_AIE_OFF)
-COMPATIBLE_IOCTL(RTC_UIE_ON)
-COMPATIBLE_IOCTL(RTC_UIE_OFF)
-COMPATIBLE_IOCTL(RTC_PIE_ON)
-COMPATIBLE_IOCTL(RTC_PIE_OFF)
-COMPATIBLE_IOCTL(RTC_WIE_ON)
-COMPATIBLE_IOCTL(RTC_WIE_OFF)
-COMPATIBLE_IOCTL(RTC_ALM_SET)
-COMPATIBLE_IOCTL(RTC_ALM_READ)
-COMPATIBLE_IOCTL(RTC_RD_TIME)
-COMPATIBLE_IOCTL(RTC_SET_TIME)
-COMPATIBLE_IOCTL(RTC_WKALM_SET)
-COMPATIBLE_IOCTL(RTC_WKALM_RD)
-/*
- * These two are only for the sbus rtc driver, but
- * hwclock tries them on every rtc device first when
- * running on sparc. On other architectures the entries
- * are useless but harmless.
- */
-COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */
-COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */
-/* Little m */
-COMPATIBLE_IOCTL(MTIOCTOP)
-/* Socket level stuff */
-COMPATIBLE_IOCTL(FIOQSIZE)
-COMPATIBLE_IOCTL(FIOSETOWN)
-COMPATIBLE_IOCTL(SIOCSPGRP)
-COMPATIBLE_IOCTL(FIOGETOWN)
-COMPATIBLE_IOCTL(SIOCGPGRP)
-COMPATIBLE_IOCTL(SIOCATMARK)
-COMPATIBLE_IOCTL(SIOCSIFLINK)
-COMPATIBLE_IOCTL(SIOCSIFENCAP)
-COMPATIBLE_IOCTL(SIOCGIFENCAP)
-COMPATIBLE_IOCTL(SIOCSIFNAME)
-COMPATIBLE_IOCTL(SIOCSARP)
-COMPATIBLE_IOCTL(SIOCGARP)
-COMPATIBLE_IOCTL(SIOCDARP)
-COMPATIBLE_IOCTL(SIOCSRARP)
-COMPATIBLE_IOCTL(SIOCGRARP)
-COMPATIBLE_IOCTL(SIOCDRARP)
-COMPATIBLE_IOCTL(SIOCADDDLCI)
-COMPATIBLE_IOCTL(SIOCDELDLCI)
-COMPATIBLE_IOCTL(SIOCGMIIPHY)
-COMPATIBLE_IOCTL(SIOCGMIIREG)
-COMPATIBLE_IOCTL(SIOCSMIIREG)
-COMPATIBLE_IOCTL(SIOCGIFVLAN)
-COMPATIBLE_IOCTL(SIOCSIFVLAN)
-COMPATIBLE_IOCTL(SIOCBRADDBR)
-COMPATIBLE_IOCTL(SIOCBRDELBR)
-/* SG stuff */
-COMPATIBLE_IOCTL(SG_SET_TIMEOUT)
-COMPATIBLE_IOCTL(SG_GET_TIMEOUT)
-COMPATIBLE_IOCTL(SG_EMULATED_HOST)
-ULONG_IOCTL(SG_SET_TRANSFORM)
-COMPATIBLE_IOCTL(SG_GET_TRANSFORM)
-COMPATIBLE_IOCTL(SG_SET_RESERVED_SIZE)
-COMPATIBLE_IOCTL(SG_GET_RESERVED_SIZE)
-COMPATIBLE_IOCTL(SG_GET_SCSI_ID)
-COMPATIBLE_IOCTL(SG_SET_FORCE_LOW_DMA)
-COMPATIBLE_IOCTL(SG_GET_LOW_DMA)
-COMPATIBLE_IOCTL(SG_SET_FORCE_PACK_ID)
-COMPATIBLE_IOCTL(SG_GET_PACK_ID)
-COMPATIBLE_IOCTL(SG_GET_NUM_WAITING)
-COMPATIBLE_IOCTL(SG_SET_DEBUG)
-COMPATIBLE_IOCTL(SG_GET_SG_TABLESIZE)
-COMPATIBLE_IOCTL(SG_GET_COMMAND_Q)
-COMPATIBLE_IOCTL(SG_SET_COMMAND_Q)
-COMPATIBLE_IOCTL(SG_GET_VERSION_NUM)
-COMPATIBLE_IOCTL(SG_NEXT_CMD_LEN)
-COMPATIBLE_IOCTL(SG_SCSI_RESET)
-COMPATIBLE_IOCTL(SG_GET_REQUEST_TABLE)
-COMPATIBLE_IOCTL(SG_SET_KEEP_ORPHAN)
-COMPATIBLE_IOCTL(SG_GET_KEEP_ORPHAN)
-/* PPP stuff */
-COMPATIBLE_IOCTL(PPPIOCGFLAGS)
-COMPATIBLE_IOCTL(PPPIOCSFLAGS)
-COMPATIBLE_IOCTL(PPPIOCGASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCSASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCGUNIT)
-COMPATIBLE_IOCTL(PPPIOCGRASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCSRASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCGMRU)
-COMPATIBLE_IOCTL(PPPIOCSMRU)
-COMPATIBLE_IOCTL(PPPIOCSMAXCID)
-COMPATIBLE_IOCTL(PPPIOCGXASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCSXASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCXFERUNIT)
-/* PPPIOCSCOMPRESS is translated */
-COMPATIBLE_IOCTL(PPPIOCGNPMODE)
-COMPATIBLE_IOCTL(PPPIOCSNPMODE)
-COMPATIBLE_IOCTL(PPPIOCGDEBUG)
-COMPATIBLE_IOCTL(PPPIOCSDEBUG)
-/* PPPIOCSPASS is translated */
-/* PPPIOCSACTIVE is translated */
-/* PPPIOCGIDLE is translated */
-COMPATIBLE_IOCTL(PPPIOCNEWUNIT)
-COMPATIBLE_IOCTL(PPPIOCATTACH)
-COMPATIBLE_IOCTL(PPPIOCDETACH)
-COMPATIBLE_IOCTL(PPPIOCSMRRU)
-COMPATIBLE_IOCTL(PPPIOCCONNECT)
-COMPATIBLE_IOCTL(PPPIOCDISCONN)
-COMPATIBLE_IOCTL(PPPIOCATTCHAN)
-COMPATIBLE_IOCTL(PPPIOCGCHAN)
-/* PPPOX */
-COMPATIBLE_IOCTL(PPPOEIOCSFWD)
-COMPATIBLE_IOCTL(PPPOEIOCDFWD)
-/* LP */
-COMPATIBLE_IOCTL(LPGETSTATUS)
-/* ppdev */
-COMPATIBLE_IOCTL(PPSETMODE)
-COMPATIBLE_IOCTL(PPRSTATUS)
-COMPATIBLE_IOCTL(PPRCONTROL)
-COMPATIBLE_IOCTL(PPWCONTROL)
-COMPATIBLE_IOCTL(PPFCONTROL)
-COMPATIBLE_IOCTL(PPRDATA)
-COMPATIBLE_IOCTL(PPWDATA)
-COMPATIBLE_IOCTL(PPCLAIM)
-COMPATIBLE_IOCTL(PPRELEASE)
-COMPATIBLE_IOCTL(PPYIELD)
-COMPATIBLE_IOCTL(PPEXCL)
-COMPATIBLE_IOCTL(PPDATADIR)
-COMPATIBLE_IOCTL(PPNEGOT)
-COMPATIBLE_IOCTL(PPWCTLONIRQ)
-COMPATIBLE_IOCTL(PPCLRIRQ)
-COMPATIBLE_IOCTL(PPSETPHASE)
-COMPATIBLE_IOCTL(PPGETMODES)
-COMPATIBLE_IOCTL(PPGETMODE)
-COMPATIBLE_IOCTL(PPGETPHASE)
-COMPATIBLE_IOCTL(PPGETFLAGS)
-COMPATIBLE_IOCTL(PPSETFLAGS)
-/* CDROM stuff */
-COMPATIBLE_IOCTL(CDROMPAUSE)
-COMPATIBLE_IOCTL(CDROMRESUME)
-COMPATIBLE_IOCTL(CDROMPLAYMSF)
-COMPATIBLE_IOCTL(CDROMPLAYTRKIND)
-COMPATIBLE_IOCTL(CDROMREADTOCHDR)
-COMPATIBLE_IOCTL(CDROMREADTOCENTRY)
-COMPATIBLE_IOCTL(CDROMSTOP)
-COMPATIBLE_IOCTL(CDROMSTART)
-COMPATIBLE_IOCTL(CDROMEJECT)
-COMPATIBLE_IOCTL(CDROMVOLCTRL)
-COMPATIBLE_IOCTL(CDROMSUBCHNL)
-ULONG_IOCTL(CDROMEJECT_SW)
-COMPATIBLE_IOCTL(CDROMMULTISESSION)
-COMPATIBLE_IOCTL(CDROM_GET_MCN)
-COMPATIBLE_IOCTL(CDROMRESET)
-COMPATIBLE_IOCTL(CDROMVOLREAD)
-COMPATIBLE_IOCTL(CDROMSEEK)
-COMPATIBLE_IOCTL(CDROMPLAYBLK)
-COMPATIBLE_IOCTL(CDROMCLOSETRAY)
-ULONG_IOCTL(CDROM_SET_OPTIONS)
-ULONG_IOCTL(CDROM_CLEAR_OPTIONS)
-ULONG_IOCTL(CDROM_SELECT_SPEED)
-ULONG_IOCTL(CDROM_SELECT_DISC)
-ULONG_IOCTL(CDROM_MEDIA_CHANGED)
-ULONG_IOCTL(CDROM_DRIVE_STATUS)
-COMPATIBLE_IOCTL(CDROM_DISC_STATUS)
-COMPATIBLE_IOCTL(CDROM_CHANGER_NSLOTS)
-ULONG_IOCTL(CDROM_LOCKDOOR)
-ULONG_IOCTL(CDROM_DEBUG)
-COMPATIBLE_IOCTL(CDROM_GET_CAPABILITY)
-/* Ignore cdrom.h about these next 5 ioctls, they absolutely do
- * not take a struct cdrom_read, instead they take a struct cdrom_msf
- * which is compatible.
- */
-COMPATIBLE_IOCTL(CDROMREADMODE2)
-COMPATIBLE_IOCTL(CDROMREADMODE1)
-COMPATIBLE_IOCTL(CDROMREADRAW)
-COMPATIBLE_IOCTL(CDROMREADCOOKED)
-COMPATIBLE_IOCTL(CDROMREADALL)
-/* DVD ioctls */
-COMPATIBLE_IOCTL(DVD_READ_STRUCT)
-COMPATIBLE_IOCTL(DVD_WRITE_STRUCT)
-COMPATIBLE_IOCTL(DVD_AUTH)
-/* pktcdvd */
-COMPATIBLE_IOCTL(PACKET_CTRL_CMD)
-/* Big A */
-/* sparc only */
-/* Big Q for sound/OSS */
-COMPATIBLE_IOCTL(SNDCTL_SEQ_RESET)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_SYNC)
-COMPATIBLE_IOCTL(SNDCTL_SYNTH_INFO)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_CTRLRATE)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_GETOUTCOUNT)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_GETINCOUNT)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_PERCMODE)
-COMPATIBLE_IOCTL(SNDCTL_FM_LOAD_INSTR)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_TESTMIDI)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_RESETSAMPLES)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_NRSYNTHS)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_NRMIDIS)
-COMPATIBLE_IOCTL(SNDCTL_MIDI_INFO)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_THRESHOLD)
-COMPATIBLE_IOCTL(SNDCTL_SYNTH_MEMAVL)
-COMPATIBLE_IOCTL(SNDCTL_FM_4OP_ENABLE)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_PANIC)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_OUTOFBAND)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_GETTIME)
-COMPATIBLE_IOCTL(SNDCTL_SYNTH_ID)
-COMPATIBLE_IOCTL(SNDCTL_SYNTH_CONTROL)
-COMPATIBLE_IOCTL(SNDCTL_SYNTH_REMOVESAMPLE)
-/* Big T for sound/OSS */
-COMPATIBLE_IOCTL(SNDCTL_TMR_TIMEBASE)
-COMPATIBLE_IOCTL(SNDCTL_TMR_START)
-COMPATIBLE_IOCTL(SNDCTL_TMR_STOP)
-COMPATIBLE_IOCTL(SNDCTL_TMR_CONTINUE)
-COMPATIBLE_IOCTL(SNDCTL_TMR_TEMPO)
-COMPATIBLE_IOCTL(SNDCTL_TMR_SOURCE)
-COMPATIBLE_IOCTL(SNDCTL_TMR_METRONOME)
-COMPATIBLE_IOCTL(SNDCTL_TMR_SELECT)
-/* Little m for sound/OSS */
-COMPATIBLE_IOCTL(SNDCTL_MIDI_PRETIME)
-COMPATIBLE_IOCTL(SNDCTL_MIDI_MPUMODE)
-COMPATIBLE_IOCTL(SNDCTL_MIDI_MPUCMD)
-/* Big P for sound/OSS */
-COMPATIBLE_IOCTL(SNDCTL_DSP_RESET)
-COMPATIBLE_IOCTL(SNDCTL_DSP_SYNC)
-COMPATIBLE_IOCTL(SNDCTL_DSP_SPEED)
-COMPATIBLE_IOCTL(SNDCTL_DSP_STEREO)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETBLKSIZE)
-COMPATIBLE_IOCTL(SNDCTL_DSP_CHANNELS)
-COMPATIBLE_IOCTL(SOUND_PCM_WRITE_FILTER)
-COMPATIBLE_IOCTL(SNDCTL_DSP_POST)
-COMPATIBLE_IOCTL(SNDCTL_DSP_SUBDIVIDE)
-COMPATIBLE_IOCTL(SNDCTL_DSP_SETFRAGMENT)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETFMTS)
-COMPATIBLE_IOCTL(SNDCTL_DSP_SETFMT)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETOSPACE)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETISPACE)
-COMPATIBLE_IOCTL(SNDCTL_DSP_NONBLOCK)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETCAPS)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETTRIGGER)
-COMPATIBLE_IOCTL(SNDCTL_DSP_SETTRIGGER)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETIPTR)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETOPTR)
-/* SNDCTL_DSP_MAPINBUF, XXX needs translation */
-/* SNDCTL_DSP_MAPOUTBUF, XXX needs translation */
-COMPATIBLE_IOCTL(SNDCTL_DSP_SETSYNCRO)
-COMPATIBLE_IOCTL(SNDCTL_DSP_SETDUPLEX)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETODELAY)
-COMPATIBLE_IOCTL(SNDCTL_DSP_PROFILE)
-COMPATIBLE_IOCTL(SOUND_PCM_READ_RATE)
-COMPATIBLE_IOCTL(SOUND_PCM_READ_CHANNELS)
-COMPATIBLE_IOCTL(SOUND_PCM_READ_BITS)
-COMPATIBLE_IOCTL(SOUND_PCM_READ_FILTER)
-/* Big C for sound/OSS */
-COMPATIBLE_IOCTL(SNDCTL_COPR_RESET)
-COMPATIBLE_IOCTL(SNDCTL_COPR_LOAD)
-COMPATIBLE_IOCTL(SNDCTL_COPR_RDATA)
-COMPATIBLE_IOCTL(SNDCTL_COPR_RCODE)
-COMPATIBLE_IOCTL(SNDCTL_COPR_WDATA)
-COMPATIBLE_IOCTL(SNDCTL_COPR_WCODE)
-COMPATIBLE_IOCTL(SNDCTL_COPR_RUN)
-COMPATIBLE_IOCTL(SNDCTL_COPR_HALT)
-COMPATIBLE_IOCTL(SNDCTL_COPR_SENDMSG)
-COMPATIBLE_IOCTL(SNDCTL_COPR_RCVMSG)
-/* Big M for sound/OSS */
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_VOLUME)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_BASS)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_TREBLE)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_SYNTH)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_PCM)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_SPEAKER)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_MIC)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_CD)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_IMIX)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_ALTPCM)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECLEV)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_IGAIN)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_OGAIN)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE1)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE2)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE3)
-COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL1))
-COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL2))
-COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL3))
-COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_PHONEIN))
-COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_PHONEOUT))
-COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_VIDEO))
-COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_RADIO))
-COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_MONITOR))
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_MUTE)
-/* SOUND_MIXER_READ_ENHANCE, same value as READ_MUTE */
-/* SOUND_MIXER_READ_LOUD, same value as READ_MUTE */
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECSRC)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_DEVMASK)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECMASK)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_STEREODEVS)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_CAPS)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_VOLUME)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_BASS)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_TREBLE)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_SYNTH)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_PCM)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_SPEAKER)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_MIC)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_CD)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_IMIX)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_ALTPCM)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_RECLEV)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_IGAIN)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_OGAIN)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE1)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE2)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE3)
-COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL1))
-COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL2))
-COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL3))
-COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_PHONEIN))
-COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_PHONEOUT))
-COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_VIDEO))
-COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_RADIO))
-COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_MONITOR))
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_MUTE)
-/* SOUND_MIXER_WRITE_ENHANCE, same value as WRITE_MUTE */
-/* SOUND_MIXER_WRITE_LOUD, same value as WRITE_MUTE */
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_RECSRC)
-COMPATIBLE_IOCTL(SOUND_MIXER_INFO)
-COMPATIBLE_IOCTL(SOUND_OLD_MIXER_INFO)
-COMPATIBLE_IOCTL(SOUND_MIXER_ACCESS)
-COMPATIBLE_IOCTL(SOUND_MIXER_AGC)
-COMPATIBLE_IOCTL(SOUND_MIXER_3DSE)
-COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE1)
-COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE2)
-COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE3)
-COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE4)
-COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE5)
-COMPATIBLE_IOCTL(SOUND_MIXER_GETLEVELS)
-COMPATIBLE_IOCTL(SOUND_MIXER_SETLEVELS)
-COMPATIBLE_IOCTL(OSS_GETVERSION)
-/* AUTOFS */
-ULONG_IOCTL(AUTOFS_IOC_READY)
-ULONG_IOCTL(AUTOFS_IOC_FAIL)
-COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC)
-COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER)
-COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE)
-COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE_MULTI)
-COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOSUBVER)
-COMPATIBLE_IOCTL(AUTOFS_IOC_ASKREGHOST)
-COMPATIBLE_IOCTL(AUTOFS_IOC_TOGGLEREGHOST)
-COMPATIBLE_IOCTL(AUTOFS_IOC_ASKUMOUNT)
-/* Raw devices */
-COMPATIBLE_IOCTL(RAW_SETBIND)
-COMPATIBLE_IOCTL(RAW_GETBIND)
-/* SMB ioctls which do not need any translations */
-COMPATIBLE_IOCTL(SMB_IOC_NEWCONN)
-/* Little a */
-COMPATIBLE_IOCTL(ATMSIGD_CTRL)
-COMPATIBLE_IOCTL(ATMARPD_CTRL)
-COMPATIBLE_IOCTL(ATMLEC_CTRL)
-COMPATIBLE_IOCTL(ATMLEC_MCAST)
-COMPATIBLE_IOCTL(ATMLEC_DATA)
-COMPATIBLE_IOCTL(ATM_SETSC)
-COMPATIBLE_IOCTL(SIOCSIFATMTCP)
-COMPATIBLE_IOCTL(SIOCMKCLIP)
-COMPATIBLE_IOCTL(ATMARP_MKIP)
-COMPATIBLE_IOCTL(ATMARP_SETENTRY)
-COMPATIBLE_IOCTL(ATMARP_ENCAP)
-COMPATIBLE_IOCTL(ATMTCP_CREATE)
-COMPATIBLE_IOCTL(ATMTCP_REMOVE)
-COMPATIBLE_IOCTL(ATMMPC_CTRL)
-COMPATIBLE_IOCTL(ATMMPC_DATA)
-/* Watchdog */
-COMPATIBLE_IOCTL(WDIOC_GETSUPPORT)
-COMPATIBLE_IOCTL(WDIOC_GETSTATUS)
-COMPATIBLE_IOCTL(WDIOC_GETBOOTSTATUS)
-COMPATIBLE_IOCTL(WDIOC_GETTEMP)
-COMPATIBLE_IOCTL(WDIOC_SETOPTIONS)
-COMPATIBLE_IOCTL(WDIOC_KEEPALIVE)
-COMPATIBLE_IOCTL(WDIOC_SETTIMEOUT)
-COMPATIBLE_IOCTL(WDIOC_GETTIMEOUT)
-/* Big R */
-COMPATIBLE_IOCTL(RNDGETENTCNT)
-COMPATIBLE_IOCTL(RNDADDTOENTCNT)
-COMPATIBLE_IOCTL(RNDGETPOOL)
-COMPATIBLE_IOCTL(RNDADDENTROPY)
-COMPATIBLE_IOCTL(RNDZAPENTCNT)
-COMPATIBLE_IOCTL(RNDCLEARPOOL)
-/* Bluetooth */
-COMPATIBLE_IOCTL(HCIDEVUP)
-COMPATIBLE_IOCTL(HCIDEVDOWN)
-COMPATIBLE_IOCTL(HCIDEVRESET)
-COMPATIBLE_IOCTL(HCIDEVRESTAT)
-COMPATIBLE_IOCTL(HCIGETDEVLIST)
-COMPATIBLE_IOCTL(HCIGETDEVINFO)
-COMPATIBLE_IOCTL(HCIGETCONNLIST)
-COMPATIBLE_IOCTL(HCIGETCONNINFO)
-COMPATIBLE_IOCTL(HCISETRAW)
-COMPATIBLE_IOCTL(HCISETSCAN)
-COMPATIBLE_IOCTL(HCISETAUTH)
-COMPATIBLE_IOCTL(HCISETENCRYPT)
-COMPATIBLE_IOCTL(HCISETPTYPE)
-COMPATIBLE_IOCTL(HCISETLINKPOL)
-COMPATIBLE_IOCTL(HCISETLINKMODE)
-COMPATIBLE_IOCTL(HCISETACLMTU)
-COMPATIBLE_IOCTL(HCISETSCOMTU)
-COMPATIBLE_IOCTL(HCIINQUIRY)
-COMPATIBLE_IOCTL(HCIUARTSETPROTO)
-COMPATIBLE_IOCTL(HCIUARTGETPROTO)
-COMPATIBLE_IOCTL(RFCOMMCREATEDEV)
-COMPATIBLE_IOCTL(RFCOMMRELEASEDEV)
-COMPATIBLE_IOCTL(RFCOMMGETDEVLIST)
-COMPATIBLE_IOCTL(RFCOMMGETDEVINFO)
-COMPATIBLE_IOCTL(RFCOMMSTEALDLC)
-COMPATIBLE_IOCTL(BNEPCONNADD)
-COMPATIBLE_IOCTL(BNEPCONNDEL)
-COMPATIBLE_IOCTL(BNEPGETCONNLIST)
-COMPATIBLE_IOCTL(BNEPGETCONNINFO)
-COMPATIBLE_IOCTL(CMTPCONNADD)
-COMPATIBLE_IOCTL(CMTPCONNDEL)
-COMPATIBLE_IOCTL(CMTPGETCONNLIST)
-COMPATIBLE_IOCTL(CMTPGETCONNINFO)
-COMPATIBLE_IOCTL(HIDPCONNADD)
-COMPATIBLE_IOCTL(HIDPCONNDEL)
-COMPATIBLE_IOCTL(HIDPGETCONNLIST)
-COMPATIBLE_IOCTL(HIDPGETCONNINFO)
-/* CAPI */
-COMPATIBLE_IOCTL(CAPI_REGISTER)
-COMPATIBLE_IOCTL(CAPI_GET_MANUFACTURER)
-COMPATIBLE_IOCTL(CAPI_GET_VERSION)
-COMPATIBLE_IOCTL(CAPI_GET_SERIAL)
-COMPATIBLE_IOCTL(CAPI_GET_PROFILE)
-COMPATIBLE_IOCTL(CAPI_MANUFACTURER_CMD)
-COMPATIBLE_IOCTL(CAPI_GET_ERRCODE)
-COMPATIBLE_IOCTL(CAPI_INSTALLED)
-COMPATIBLE_IOCTL(CAPI_GET_FLAGS)
-COMPATIBLE_IOCTL(CAPI_SET_FLAGS)
-COMPATIBLE_IOCTL(CAPI_CLR_FLAGS)
-COMPATIBLE_IOCTL(CAPI_NCCI_OPENCOUNT)
-COMPATIBLE_IOCTL(CAPI_NCCI_GETUNIT)
-/* Siemens Gigaset */
-COMPATIBLE_IOCTL(GIGASET_REDIR)
-COMPATIBLE_IOCTL(GIGASET_CONFIG)
-COMPATIBLE_IOCTL(GIGASET_BRKCHARS)
-COMPATIBLE_IOCTL(GIGASET_VERSION)
-/* Misc. */
-COMPATIBLE_IOCTL(0x41545900) /* ATYIO_CLKR */
-COMPATIBLE_IOCTL(0x41545901) /* ATYIO_CLKW */
-COMPATIBLE_IOCTL(PCIIOC_CONTROLLER)
-COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_IO)
-COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_MEM)
-COMPATIBLE_IOCTL(PCIIOC_WRITE_COMBINE)
-/* USB */
-COMPATIBLE_IOCTL(USBDEVFS_RESETEP)
-COMPATIBLE_IOCTL(USBDEVFS_SETINTERFACE)
-COMPATIBLE_IOCTL(USBDEVFS_SETCONFIGURATION)
-COMPATIBLE_IOCTL(USBDEVFS_GETDRIVER)
-COMPATIBLE_IOCTL(USBDEVFS_DISCARDURB)
-COMPATIBLE_IOCTL(USBDEVFS_CLAIMINTERFACE)
-COMPATIBLE_IOCTL(USBDEVFS_RELEASEINTERFACE)
-COMPATIBLE_IOCTL(USBDEVFS_CONNECTINFO)
-COMPATIBLE_IOCTL(USBDEVFS_HUB_PORTINFO)
-COMPATIBLE_IOCTL(USBDEVFS_RESET)
-COMPATIBLE_IOCTL(USBDEVFS_SUBMITURB32)
-COMPATIBLE_IOCTL(USBDEVFS_REAPURB32)
-COMPATIBLE_IOCTL(USBDEVFS_REAPURBNDELAY32)
-COMPATIBLE_IOCTL(USBDEVFS_CLEAR_HALT)
-/* MTD */
-COMPATIBLE_IOCTL(MEMGETINFO)
-COMPATIBLE_IOCTL(MEMERASE)
-COMPATIBLE_IOCTL(MEMLOCK)
-COMPATIBLE_IOCTL(MEMUNLOCK)
-COMPATIBLE_IOCTL(MEMGETREGIONCOUNT)
-COMPATIBLE_IOCTL(MEMGETREGIONINFO)
-COMPATIBLE_IOCTL(MEMGETBADBLOCK)
-COMPATIBLE_IOCTL(MEMSETBADBLOCK)
-/* NBD */
-ULONG_IOCTL(NBD_SET_SOCK)
-ULONG_IOCTL(NBD_SET_BLKSIZE)
-ULONG_IOCTL(NBD_SET_SIZE)
-COMPATIBLE_IOCTL(NBD_DO_IT)
-COMPATIBLE_IOCTL(NBD_CLEAR_SOCK)
-COMPATIBLE_IOCTL(NBD_CLEAR_QUE)
-COMPATIBLE_IOCTL(NBD_PRINT_DEBUG)
-ULONG_IOCTL(NBD_SET_SIZE_BLOCKS)
-COMPATIBLE_IOCTL(NBD_DISCONNECT)
-/* i2c */
-COMPATIBLE_IOCTL(I2C_SLAVE)
-COMPATIBLE_IOCTL(I2C_SLAVE_FORCE)
-COMPATIBLE_IOCTL(I2C_TENBIT)
-COMPATIBLE_IOCTL(I2C_PEC)
-COMPATIBLE_IOCTL(I2C_RETRIES)
-COMPATIBLE_IOCTL(I2C_TIMEOUT)
-/* wireless */
-COMPATIBLE_IOCTL(SIOCSIWCOMMIT)
-COMPATIBLE_IOCTL(SIOCGIWNAME)
-COMPATIBLE_IOCTL(SIOCSIWNWID)
-COMPATIBLE_IOCTL(SIOCGIWNWID)
-COMPATIBLE_IOCTL(SIOCSIWFREQ)
-COMPATIBLE_IOCTL(SIOCGIWFREQ)
-COMPATIBLE_IOCTL(SIOCSIWMODE)
-COMPATIBLE_IOCTL(SIOCGIWMODE)
-COMPATIBLE_IOCTL(SIOCSIWSENS)
-COMPATIBLE_IOCTL(SIOCGIWSENS)
-COMPATIBLE_IOCTL(SIOCSIWRANGE)
-COMPATIBLE_IOCTL(SIOCSIWPRIV)
-COMPATIBLE_IOCTL(SIOCGIWPRIV)
-COMPATIBLE_IOCTL(SIOCSIWSTATS)
-COMPATIBLE_IOCTL(SIOCGIWSTATS)
-COMPATIBLE_IOCTL(SIOCSIWAP)
-COMPATIBLE_IOCTL(SIOCGIWAP)
-COMPATIBLE_IOCTL(SIOCSIWSCAN)
-COMPATIBLE_IOCTL(SIOCSIWRATE)
-COMPATIBLE_IOCTL(SIOCGIWRATE)
-COMPATIBLE_IOCTL(SIOCSIWRTS)
-COMPATIBLE_IOCTL(SIOCGIWRTS)
-COMPATIBLE_IOCTL(SIOCSIWFRAG)
-COMPATIBLE_IOCTL(SIOCGIWFRAG)
-COMPATIBLE_IOCTL(SIOCSIWTXPOW)
-COMPATIBLE_IOCTL(SIOCGIWTXPOW)
-COMPATIBLE_IOCTL(SIOCSIWRETRY)
-COMPATIBLE_IOCTL(SIOCGIWRETRY)
-COMPATIBLE_IOCTL(SIOCSIWPOWER)
-COMPATIBLE_IOCTL(SIOCGIWPOWER)
-/* hiddev */
-COMPATIBLE_IOCTL(HIDIOCGVERSION)
-COMPATIBLE_IOCTL(HIDIOCAPPLICATION)
-COMPATIBLE_IOCTL(HIDIOCGDEVINFO)
-COMPATIBLE_IOCTL(HIDIOCGSTRING)
-COMPATIBLE_IOCTL(HIDIOCINITREPORT)
-COMPATIBLE_IOCTL(HIDIOCGREPORT)
-COMPATIBLE_IOCTL(HIDIOCSREPORT)
-COMPATIBLE_IOCTL(HIDIOCGREPORTINFO)
-COMPATIBLE_IOCTL(HIDIOCGFIELDINFO)
-COMPATIBLE_IOCTL(HIDIOCGUSAGE)
-COMPATIBLE_IOCTL(HIDIOCSUSAGE)
-COMPATIBLE_IOCTL(HIDIOCGUCODE)
-COMPATIBLE_IOCTL(HIDIOCGFLAG)
-COMPATIBLE_IOCTL(HIDIOCSFLAG)
-COMPATIBLE_IOCTL(HIDIOCGCOLLECTIONINDEX)
-COMPATIBLE_IOCTL(HIDIOCGCOLLECTIONINFO)
-/* dvb */
-COMPATIBLE_IOCTL(AUDIO_STOP)
-COMPATIBLE_IOCTL(AUDIO_PLAY)
-COMPATIBLE_IOCTL(AUDIO_PAUSE)
-COMPATIBLE_IOCTL(AUDIO_CONTINUE)
-COMPATIBLE_IOCTL(AUDIO_SELECT_SOURCE)
-COMPATIBLE_IOCTL(AUDIO_SET_MUTE)
-COMPATIBLE_IOCTL(AUDIO_SET_AV_SYNC)
-COMPATIBLE_IOCTL(AUDIO_SET_BYPASS_MODE)
-COMPATIBLE_IOCTL(AUDIO_CHANNEL_SELECT)
-COMPATIBLE_IOCTL(AUDIO_GET_STATUS)
-COMPATIBLE_IOCTL(AUDIO_GET_CAPABILITIES)
-COMPATIBLE_IOCTL(AUDIO_CLEAR_BUFFER)
-COMPATIBLE_IOCTL(AUDIO_SET_ID)
-COMPATIBLE_IOCTL(AUDIO_SET_MIXER)
-COMPATIBLE_IOCTL(AUDIO_SET_STREAMTYPE)
-COMPATIBLE_IOCTL(AUDIO_SET_EXT_ID)
-COMPATIBLE_IOCTL(AUDIO_SET_ATTRIBUTES)
-COMPATIBLE_IOCTL(AUDIO_SET_KARAOKE)
-COMPATIBLE_IOCTL(DMX_START)
-COMPATIBLE_IOCTL(DMX_STOP)
-COMPATIBLE_IOCTL(DMX_SET_FILTER)
-COMPATIBLE_IOCTL(DMX_SET_PES_FILTER)
-COMPATIBLE_IOCTL(DMX_SET_BUFFER_SIZE)
-COMPATIBLE_IOCTL(DMX_GET_PES_PIDS)
-COMPATIBLE_IOCTL(DMX_GET_CAPS)
-COMPATIBLE_IOCTL(DMX_SET_SOURCE)
-COMPATIBLE_IOCTL(DMX_GET_STC)
-COMPATIBLE_IOCTL(FE_GET_INFO)
-COMPATIBLE_IOCTL(FE_DISEQC_RESET_OVERLOAD)
-COMPATIBLE_IOCTL(FE_DISEQC_SEND_MASTER_CMD)
-COMPATIBLE_IOCTL(FE_DISEQC_RECV_SLAVE_REPLY)
-COMPATIBLE_IOCTL(FE_DISEQC_SEND_BURST)
-COMPATIBLE_IOCTL(FE_SET_TONE)
-COMPATIBLE_IOCTL(FE_SET_VOLTAGE)
-COMPATIBLE_IOCTL(FE_ENABLE_HIGH_LNB_VOLTAGE)
-COMPATIBLE_IOCTL(FE_READ_STATUS)
-COMPATIBLE_IOCTL(FE_READ_BER)
-COMPATIBLE_IOCTL(FE_READ_SIGNAL_STRENGTH)
-COMPATIBLE_IOCTL(FE_READ_SNR)
-COMPATIBLE_IOCTL(FE_READ_UNCORRECTED_BLOCKS)
-COMPATIBLE_IOCTL(FE_SET_FRONTEND)
-COMPATIBLE_IOCTL(FE_GET_FRONTEND)
-COMPATIBLE_IOCTL(FE_GET_EVENT)
-COMPATIBLE_IOCTL(FE_DISHNETWORK_SEND_LEGACY_CMD)
-COMPATIBLE_IOCTL(VIDEO_STOP)
-COMPATIBLE_IOCTL(VIDEO_PLAY)
-COMPATIBLE_IOCTL(VIDEO_FREEZE)
-COMPATIBLE_IOCTL(VIDEO_CONTINUE)
-COMPATIBLE_IOCTL(VIDEO_SELECT_SOURCE)
-COMPATIBLE_IOCTL(VIDEO_SET_BLANK)
-COMPATIBLE_IOCTL(VIDEO_GET_STATUS)
-COMPATIBLE_IOCTL(VIDEO_SET_DISPLAY_FORMAT)
-COMPATIBLE_IOCTL(VIDEO_FAST_FORWARD)
-COMPATIBLE_IOCTL(VIDEO_SLOWMOTION)
-COMPATIBLE_IOCTL(VIDEO_GET_CAPABILITIES)
-COMPATIBLE_IOCTL(VIDEO_CLEAR_BUFFER)
-COMPATIBLE_IOCTL(VIDEO_SET_ID)
-COMPATIBLE_IOCTL(VIDEO_SET_STREAMTYPE)
-COMPATIBLE_IOCTL(VIDEO_SET_FORMAT)
-COMPATIBLE_IOCTL(VIDEO_SET_SYSTEM)
-COMPATIBLE_IOCTL(VIDEO_SET_HIGHLIGHT)
-COMPATIBLE_IOCTL(VIDEO_SET_SPU)
-COMPATIBLE_IOCTL(VIDEO_GET_NAVI)
-COMPATIBLE_IOCTL(VIDEO_SET_ATTRIBUTES)
-COMPATIBLE_IOCTL(VIDEO_GET_SIZE)
-COMPATIBLE_IOCTL(VIDEO_GET_FRAME_RATE)
diff --git a/include/linux/console.h b/include/linux/console.h
index de25ee3..62ef6e1 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -51,7 +51,7 @@
int (*con_scrolldelta)(struct vc_data *, int);
int (*con_set_origin)(struct vc_data *);
void (*con_save_screen)(struct vc_data *);
- u8 (*con_build_attr)(struct vc_data *, u8, u8, u8, u8, u8);
+ u8 (*con_build_attr)(struct vc_data *, u8, u8, u8, u8, u8, u8);
void (*con_invert_region)(struct vc_data *, u16 *, int);
u16 *(*con_screen_pos)(struct vc_data *, int);
unsigned long (*con_getxy)(struct vc_data *, unsigned long, int *, int *);
@@ -92,9 +92,8 @@
#define CON_BOOT (8)
#define CON_ANYTIME (16) /* Safe to call when cpu is offline */
-struct console
-{
- char name[8];
+struct console {
+ char name[16];
void (*write)(struct console *, const char *, unsigned);
int (*read)(struct console *, char *, unsigned);
struct tty_driver *(*device)(struct console *, int *);
diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
index a86162b..a461f76 100644
--- a/include/linux/console_struct.h
+++ b/include/linux/console_struct.h
@@ -37,6 +37,7 @@
unsigned char vc_color; /* Foreground & background */
unsigned char vc_s_color; /* Saved foreground & background */
unsigned char vc_ulcolor; /* Color for underline mode */
+ unsigned char vc_itcolor;
unsigned char vc_halfcolor; /* Color for half intensity mode */
/* cursor */
unsigned int vc_cursor_type;
@@ -71,10 +72,12 @@
unsigned int vc_deccolm : 1; /* 80/132 Column Mode */
/* attribute flags */
unsigned int vc_intensity : 2; /* 0=half-bright, 1=normal, 2=bold */
+ unsigned int vc_italic:1;
unsigned int vc_underline : 1;
unsigned int vc_blink : 1;
unsigned int vc_reverse : 1;
unsigned int vc_s_intensity : 2; /* saved rendition */
+ unsigned int vc_s_italic:1;
unsigned int vc_s_underline : 1;
unsigned int vc_s_blink : 1;
unsigned int vc_s_reverse : 1;
diff --git a/include/asm-x86_64/const.h b/include/linux/const.h
similarity index 70%
rename from include/asm-x86_64/const.h
rename to include/linux/const.h
index 54fb08f..07b300b 100644
--- a/include/asm-x86_64/const.h
+++ b/include/linux/const.h
@@ -1,11 +1,11 @@
/* const.h: Macros for dealing with constants. */
-#ifndef _X86_64_CONST_H
-#define _X86_64_CONST_H
+#ifndef _LINUX_CONST_H
+#define _LINUX_CONST_H
/* Some constant macros are used in both assembler and
* C code. Therefore we cannot annotate them always with
- * 'UL' and other type specificers unilaterally. We
+ * 'UL' and other type specifiers unilaterally. We
* use the following macros to deal with this.
*/
@@ -16,5 +16,4 @@
#define _AC(X,Y) __AC(X,Y)
#endif
-
-#endif /* !(_X86_64_CONST_H) */
+#endif /* !(_LINUX_CONST_H) */
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index c22b0df..3b2df25 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -41,6 +41,9 @@
extern int cpu_add_sysdev_attr_group(struct attribute_group *attrs);
extern void cpu_remove_sysdev_attr_group(struct attribute_group *attrs);
+extern struct sysdev_attribute attr_sched_mc_power_savings;
+extern struct sysdev_attribute attr_sched_smt_power_savings;
+extern int sched_create_sysfs_power_savings_entries(struct sysdev_class *cls);
#ifdef CONFIG_HOTPLUG_CPU
extern void unregister_cpu(struct cpu *cpu);
diff --git a/include/linux/cyclades.h b/include/linux/cyclades.h
index 46d8254..72aa00c 100644
--- a/include/linux/cyclades.h
+++ b/include/linux/cyclades.h
@@ -67,6 +67,8 @@
#ifndef _LINUX_CYCLADES_H
#define _LINUX_CYCLADES_H
+#include <linux/types.h>
+
struct cyclades_monitor {
unsigned long int_count;
unsigned long char_count;
@@ -108,7 +110,6 @@
#define CYZSETPOLLCYCLE 0x43590e
#define CYZGETPOLLCYCLE 0x43590f
#define CYGETCD1400VER 0x435910
-#define CYGETCARDINFO 0x435911
#define CYSETWAIT 0x435912
#define CYGETWAIT 0x435913
@@ -149,14 +150,12 @@
* architectures and compilers.
*/
-#if defined(__alpha__)
-typedef unsigned long ucdouble; /* 64 bits, unsigned */
-typedef unsigned int uclong; /* 32 bits, unsigned */
-#else
-typedef unsigned long uclong; /* 32 bits, unsigned */
-#endif
-typedef unsigned short ucshort; /* 16 bits, unsigned */
-typedef unsigned char ucchar; /* 8 bits, unsigned */
+#include <asm/types.h>
+
+typedef __u64 ucdouble; /* 64 bits, unsigned */
+typedef __u32 uclong; /* 32 bits, unsigned */
+typedef __u16 ucshort; /* 16 bits, unsigned */
+typedef __u8 ucchar; /* 8 bits, unsigned */
/*
* Memory Window Sizes
@@ -174,24 +173,24 @@
*/
struct CUSTOM_REG {
- uclong fpga_id; /* FPGA Identification Register */
- uclong fpga_version; /* FPGA Version Number Register */
- uclong cpu_start; /* CPU start Register (write) */
- uclong cpu_stop; /* CPU stop Register (write) */
- uclong misc_reg; /* Miscelaneous Register */
- uclong idt_mode; /* IDT mode Register */
- uclong uart_irq_status; /* UART IRQ status Register */
- uclong clear_timer0_irq; /* Clear timer interrupt Register */
- uclong clear_timer1_irq; /* Clear timer interrupt Register */
- uclong clear_timer2_irq; /* Clear timer interrupt Register */
- uclong test_register; /* Test Register */
- uclong test_count; /* Test Count Register */
- uclong timer_select; /* Timer select register */
- uclong pr_uart_irq_status; /* Prioritized UART IRQ stat Reg */
- uclong ram_wait_state; /* RAM wait-state Register */
- uclong uart_wait_state; /* UART wait-state Register */
- uclong timer_wait_state; /* timer wait-state Register */
- uclong ack_wait_state; /* ACK wait State Register */
+ __u32 fpga_id; /* FPGA Identification Register */
+ __u32 fpga_version; /* FPGA Version Number Register */
+ __u32 cpu_start; /* CPU start Register (write) */
+ __u32 cpu_stop; /* CPU stop Register (write) */
+ __u32 misc_reg; /* Miscelaneous Register */
+ __u32 idt_mode; /* IDT mode Register */
+ __u32 uart_irq_status; /* UART IRQ status Register */
+ __u32 clear_timer0_irq; /* Clear timer interrupt Register */
+ __u32 clear_timer1_irq; /* Clear timer interrupt Register */
+ __u32 clear_timer2_irq; /* Clear timer interrupt Register */
+ __u32 test_register; /* Test Register */
+ __u32 test_count; /* Test Count Register */
+ __u32 timer_select; /* Timer select register */
+ __u32 pr_uart_irq_status; /* Prioritized UART IRQ stat Reg */
+ __u32 ram_wait_state; /* RAM wait-state Register */
+ __u32 uart_wait_state; /* UART wait-state Register */
+ __u32 timer_wait_state; /* timer wait-state Register */
+ __u32 ack_wait_state; /* ACK wait State Register */
};
/*
@@ -201,34 +200,34 @@
*/
struct RUNTIME_9060 {
- uclong loc_addr_range; /* 00h - Local Address Range */
- uclong loc_addr_base; /* 04h - Local Address Base */
- uclong loc_arbitr; /* 08h - Local Arbitration */
- uclong endian_descr; /* 0Ch - Big/Little Endian Descriptor */
- uclong loc_rom_range; /* 10h - Local ROM Range */
- uclong loc_rom_base; /* 14h - Local ROM Base */
- uclong loc_bus_descr; /* 18h - Local Bus descriptor */
- uclong loc_range_mst; /* 1Ch - Local Range for Master to PCI */
- uclong loc_base_mst; /* 20h - Local Base for Master PCI */
- uclong loc_range_io; /* 24h - Local Range for Master IO */
- uclong pci_base_mst; /* 28h - PCI Base for Master PCI */
- uclong pci_conf_io; /* 2Ch - PCI configuration for Master IO */
- uclong filler1; /* 30h */
- uclong filler2; /* 34h */
- uclong filler3; /* 38h */
- uclong filler4; /* 3Ch */
- uclong mail_box_0; /* 40h - Mail Box 0 */
- uclong mail_box_1; /* 44h - Mail Box 1 */
- uclong mail_box_2; /* 48h - Mail Box 2 */
- uclong mail_box_3; /* 4Ch - Mail Box 3 */
- uclong filler5; /* 50h */
- uclong filler6; /* 54h */
- uclong filler7; /* 58h */
- uclong filler8; /* 5Ch */
- uclong pci_doorbell; /* 60h - PCI to Local Doorbell */
- uclong loc_doorbell; /* 64h - Local to PCI Doorbell */
- uclong intr_ctrl_stat; /* 68h - Interrupt Control/Status */
- uclong init_ctrl; /* 6Ch - EEPROM control, Init Control, etc */
+ __u32 loc_addr_range; /* 00h - Local Address Range */
+ __u32 loc_addr_base; /* 04h - Local Address Base */
+ __u32 loc_arbitr; /* 08h - Local Arbitration */
+ __u32 endian_descr; /* 0Ch - Big/Little Endian Descriptor */
+ __u32 loc_rom_range; /* 10h - Local ROM Range */
+ __u32 loc_rom_base; /* 14h - Local ROM Base */
+ __u32 loc_bus_descr; /* 18h - Local Bus descriptor */
+ __u32 loc_range_mst; /* 1Ch - Local Range for Master to PCI */
+ __u32 loc_base_mst; /* 20h - Local Base for Master PCI */
+ __u32 loc_range_io; /* 24h - Local Range for Master IO */
+ __u32 pci_base_mst; /* 28h - PCI Base for Master PCI */
+ __u32 pci_conf_io; /* 2Ch - PCI configuration for Master IO */
+ __u32 filler1; /* 30h */
+ __u32 filler2; /* 34h */
+ __u32 filler3; /* 38h */
+ __u32 filler4; /* 3Ch */
+ __u32 mail_box_0; /* 40h - Mail Box 0 */
+ __u32 mail_box_1; /* 44h - Mail Box 1 */
+ __u32 mail_box_2; /* 48h - Mail Box 2 */
+ __u32 mail_box_3; /* 4Ch - Mail Box 3 */
+ __u32 filler5; /* 50h */
+ __u32 filler6; /* 54h */
+ __u32 filler7; /* 58h */
+ __u32 filler8; /* 5Ch */
+ __u32 pci_doorbell; /* 60h - PCI to Local Doorbell */
+ __u32 loc_doorbell; /* 64h - Local to PCI Doorbell */
+ __u32 intr_ctrl_stat; /* 68h - Interrupt Control/Status */
+ __u32 init_ctrl; /* 6Ch - EEPROM control, Init Control, etc */
};
/* Values for the Local Base Address re-map register */
@@ -270,8 +269,8 @@
#define ZF_TINACT ZF_TINACT_DEF
struct FIRM_ID {
- uclong signature; /* ZFIRM/U signature */
- uclong zfwctrl_addr; /* pointer to ZFW_CTRL structure */
+ __u32 signature; /* ZFIRM/U signature */
+ __u32 zfwctrl_addr; /* pointer to ZFW_CTRL structure */
};
/* Op. System id */
@@ -408,24 +407,24 @@
*/
struct CH_CTRL {
- uclong op_mode; /* operation mode */
- uclong intr_enable; /* interrupt masking */
- uclong sw_flow; /* SW flow control */
- uclong flow_status; /* output flow status */
- uclong comm_baud; /* baud rate - numerically specified */
- uclong comm_parity; /* parity */
- uclong comm_data_l; /* data length/stop */
- uclong comm_flags; /* other flags */
- uclong hw_flow; /* HW flow control */
- uclong rs_control; /* RS-232 outputs */
- uclong rs_status; /* RS-232 inputs */
- uclong flow_xon; /* xon char */
- uclong flow_xoff; /* xoff char */
- uclong hw_overflow; /* hw overflow counter */
- uclong sw_overflow; /* sw overflow counter */
- uclong comm_error; /* frame/parity error counter */
- uclong ichar;
- uclong filler[7];
+ __u32 op_mode; /* operation mode */
+ __u32 intr_enable; /* interrupt masking */
+ __u32 sw_flow; /* SW flow control */
+ __u32 flow_status; /* output flow status */
+ __u32 comm_baud; /* baud rate - numerically specified */
+ __u32 comm_parity; /* parity */
+ __u32 comm_data_l; /* data length/stop */
+ __u32 comm_flags; /* other flags */
+ __u32 hw_flow; /* HW flow control */
+ __u32 rs_control; /* RS-232 outputs */
+ __u32 rs_status; /* RS-232 inputs */
+ __u32 flow_xon; /* xon char */
+ __u32 flow_xoff; /* xoff char */
+ __u32 hw_overflow; /* hw overflow counter */
+ __u32 sw_overflow; /* sw overflow counter */
+ __u32 comm_error; /* frame/parity error counter */
+ __u32 ichar;
+ __u32 filler[7];
};
@@ -435,18 +434,18 @@
*/
struct BUF_CTRL {
- uclong flag_dma; /* buffers are in Host memory */
- uclong tx_bufaddr; /* address of the tx buffer */
- uclong tx_bufsize; /* tx buffer size */
- uclong tx_threshold; /* tx low water mark */
- uclong tx_get; /* tail index tx buf */
- uclong tx_put; /* head index tx buf */
- uclong rx_bufaddr; /* address of the rx buffer */
- uclong rx_bufsize; /* rx buffer size */
- uclong rx_threshold; /* rx high water mark */
- uclong rx_get; /* tail index rx buf */
- uclong rx_put; /* head index rx buf */
- uclong filler[5]; /* filler to align structures */
+ __u32 flag_dma; /* buffers are in Host memory */
+ __u32 tx_bufaddr; /* address of the tx buffer */
+ __u32 tx_bufsize; /* tx buffer size */
+ __u32 tx_threshold; /* tx low water mark */
+ __u32 tx_get; /* tail index tx buf */
+ __u32 tx_put; /* head index tx buf */
+ __u32 rx_bufaddr; /* address of the rx buffer */
+ __u32 rx_bufsize; /* rx buffer size */
+ __u32 rx_threshold; /* rx high water mark */
+ __u32 rx_get; /* tail index rx buf */
+ __u32 rx_put; /* head index rx buf */
+ __u32 filler[5]; /* filler to align structures */
};
/*
@@ -457,27 +456,27 @@
struct BOARD_CTRL {
/* static info provided by the on-board CPU */
- uclong n_channel; /* number of channels */
- uclong fw_version; /* firmware version */
+ __u32 n_channel; /* number of channels */
+ __u32 fw_version; /* firmware version */
/* static info provided by the driver */
- uclong op_system; /* op_system id */
- uclong dr_version; /* driver version */
+ __u32 op_system; /* op_system id */
+ __u32 dr_version; /* driver version */
/* board control area */
- uclong inactivity; /* inactivity control */
+ __u32 inactivity; /* inactivity control */
/* host to FW commands */
- uclong hcmd_channel; /* channel number */
- uclong hcmd_param; /* pointer to parameters */
+ __u32 hcmd_channel; /* channel number */
+ __u32 hcmd_param; /* pointer to parameters */
/* FW to Host commands */
- uclong fwcmd_channel; /* channel number */
- uclong fwcmd_param; /* pointer to parameters */
- uclong zf_int_queue_addr; /* offset for INT_QUEUE structure */
+ __u32 fwcmd_channel; /* channel number */
+ __u32 fwcmd_param; /* pointer to parameters */
+ __u32 zf_int_queue_addr; /* offset for INT_QUEUE structure */
/* filler so the structures are aligned */
- uclong filler[6];
+ __u32 filler[6];
};
/* Host Interrupt Queue */
@@ -506,11 +505,10 @@
/****************** ****************** *******************/
#endif
+#ifdef __KERNEL__
+
/* Per card data structure */
-struct resource;
struct cyclades_card {
- unsigned long base_phys;
- unsigned long ctl_phys;
void __iomem *base_addr;
void __iomem *ctl_addr;
int irq;
@@ -519,33 +517,18 @@
int nports; /* Number of ports in the card */
int bus_index; /* address shift - 0 for ISA, 1 for PCI */
int intr_enabled; /* FW Interrupt flag - 0 disabled, 1 enabled */
- struct pci_dev *pdev;
-#ifdef __KERNEL__
spinlock_t card_lock;
-#else
- unsigned long filler;
-#endif
+ struct cyclades_port *ports;
};
-struct cyclades_chip {
- int filler;
-};
-
-
-#ifdef __KERNEL__
-
/***************************************
* Memory access functions/macros *
* (required to support Alpha systems) *
***************************************/
-#define cy_writeb(port,val) {writeb((val),(port)); mb();}
-#define cy_writew(port,val) {writew((val),(port)); mb();}
-#define cy_writel(port,val) {writel((val),(port)); mb();}
-
-#define cy_readb(port) readb(port)
-#define cy_readw(port) readw(port)
-#define cy_readl(port) readl(port)
+#define cy_writeb(port,val) do { writeb((val), (port)); mb(); } while (0)
+#define cy_writew(port,val) do { writew((val), (port)); mb(); } while (0)
+#define cy_writel(port,val) do { writel((val), (port)); mb(); } while (0)
/*
* Statistics counters
@@ -567,7 +550,7 @@
struct cyclades_port {
int magic;
- int card;
+ struct cyclades_card *card;
int line;
int flags; /* defined in tty.h */
int type; /* UART type */
@@ -587,7 +570,6 @@
int close_delay;
unsigned short closing_wait;
unsigned long event;
- unsigned long last_active;
int count; /* # of fd on device */
int breakon;
int breakoff;
@@ -598,7 +580,6 @@
int xmit_cnt;
int default_threshold;
int default_timeout;
- unsigned long jiffies[3];
unsigned long rflush_count;
struct cyclades_monitor mon;
struct cyclades_idle_stats idle_stats;
@@ -606,7 +587,7 @@
struct work_struct tqueue;
wait_queue_head_t open_wait;
wait_queue_head_t close_wait;
- wait_queue_head_t shutdown_wait;
+ struct completion shutdown_wait;
wait_queue_head_t delta_msr_wait;
int throttle;
};
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 63f64a9..aab53df 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -133,6 +133,7 @@
int (*d_delete)(struct dentry *);
void (*d_release)(struct dentry *);
void (*d_iput)(struct dentry *, struct inode *);
+ char *(*d_dname)(struct dentry *, char *, int);
};
/* the dentry parameter passed to d_hash and d_compare is the parent
@@ -293,6 +294,11 @@
/* validate "insecure" dentry pointer */
extern int d_validate(struct dentry *, struct dentry *);
+/*
+ * helper function for dentry_operations.d_dname() members
+ */
+extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...);
+
extern char * d_path(struct dentry *, struct vfsmount *, char *, int);
/* Allocation counts.. */
diff --git a/include/linux/device.h b/include/linux/device.h
index 6579068..2e1a298 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -412,12 +412,13 @@
struct klist_node knode_parent; /* node in sibling list */
struct klist_node knode_driver;
struct klist_node knode_bus;
- struct device * parent;
+ struct device *parent;
struct kobject kobj;
char bus_id[BUS_ID_SIZE]; /* position on parent bus */
struct device_type *type;
unsigned is_registered:1;
+ unsigned uevent_suppress:1;
struct device_attribute uevent_attr;
struct device_attribute *devt_attr;
@@ -458,7 +459,6 @@
struct class *class;
dev_t devt; /* dev_t, creates the sysfs "dev" */
struct attribute_group **groups; /* optional groups */
- int uevent_suppress;
void (*release)(struct device * dev);
};
diff --git a/include/linux/display.h b/include/linux/display.h
new file mode 100644
index 0000000..3bf70d6
--- /dev/null
+++ b/include/linux/display.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2006 James Simmons <jsimmons@infradead.org>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#ifndef _LINUX_DISPLAY_H
+#define _LINUX_DISPLAY_H
+
+#include <linux/device.h>
+
+struct display_device;
+
+/* This structure defines all the properties of a Display. */
+struct display_driver {
+ int (*set_contrast)(struct display_device *, unsigned int);
+ int (*get_contrast)(struct display_device *);
+ void (*suspend)(struct display_device *, pm_message_t state);
+ void (*resume)(struct display_device *);
+ int (*probe)(struct display_device *, void *);
+ int (*remove)(struct display_device *);
+ int max_contrast;
+};
+
+struct display_device {
+ struct module *owner; /* Owner module */
+ struct display_driver *driver;
+ struct device *parent; /* This is the parent */
+ struct device *dev; /* This is this display device */
+ struct mutex lock;
+ void *priv_data;
+ char type[16];
+ char *name;
+ int idx;
+};
+
+extern struct display_device *display_device_register(struct display_driver *driver,
+ struct device *dev, void *devdata);
+extern void display_device_unregister(struct display_device *dev);
+
+extern int probe_edid(struct display_device *dev, void *devdata);
+
+#define to_display_device(obj) container_of(obj, struct display_device, class_dev)
+
+#endif
diff --git a/include/linux/ds1wm.h b/include/linux/ds1wm.h
new file mode 100644
index 0000000..31f6e3c
--- /dev/null
+++ b/include/linux/ds1wm.h
@@ -0,0 +1,11 @@
+/* platform data for the DS1WM driver */
+
+struct ds1wm_platform_data {
+ int bus_shift; /* number of shifts needed to calculate the
+ * offset between DS1WM registers;
+ * e.g. on h5xxx and h2200 this is 2
+ * (registers aligned to 4-byte boundaries),
+ * while on hx4700 this is 1 */
+ void (*enable)(struct platform_device *pdev);
+ void (*disable)(struct platform_device *pdev);
+};
diff --git a/include/linux/efi.h b/include/linux/efi.h
index f8ebd7c..0b9579a 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -213,7 +213,6 @@
} efi_config_table_t;
#define EFI_SYSTEM_TABLE_SIGNATURE ((u64)0x5453595320494249ULL)
-#define EFI_SYSTEM_TABLE_REVISION ((1 << 16) | 00)
typedef struct {
efi_table_hdr_t hdr;
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
index 4eb18ac..ece49a8 100644
--- a/include/linux/ext3_fs.h
+++ b/include/linux/ext3_fs.h
@@ -824,6 +824,7 @@
extern int ext3_get_inode_loc(struct inode *, struct ext3_iloc *);
extern void ext3_truncate (struct inode *);
extern void ext3_set_inode_flags(struct inode *);
+extern void ext3_get_inode_flags(struct ext3_inode_info *);
extern void ext3_set_aops(struct inode *inode);
/* ioctl.c */
diff --git a/include/linux/fb.h b/include/linux/fb.h
index be913ec..dff7a728 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -4,6 +4,8 @@
#include <asm/types.h>
#include <linux/i2c.h>
+struct dentry;
+
/* Definitions of frame buffers */
#define FB_MAJOR 29
@@ -525,12 +527,20 @@
#define FB_EVENT_MODE_CHANGE_ALL 0x0B
/* A software display blank change occured */
#define FB_EVENT_CONBLANK 0x0C
+/* Get drawing requirements */
+#define FB_EVENT_GET_REQ 0x0D
struct fb_event {
struct fb_info *info;
void *data;
};
+struct fb_blit_caps {
+ u32 x;
+ u32 y;
+ u32 len;
+ u32 flags;
+};
extern int fb_register_client(struct notifier_block *nb);
extern int fb_unregister_client(struct notifier_block *nb);
@@ -556,11 +566,25 @@
u32 scan_align; /* alignment per scanline */
u32 access_align; /* alignment per read/write (bits) */
u32 flags; /* see FB_PIXMAP_* */
+ u32 blit_x; /* supported bit block dimensions (1-32)*/
+ u32 blit_y; /* Format: blit_x = 1 << (width - 1) */
+ /* blit_y = 1 << (height - 1) */
+ /* if 0, will be set to 0xffffffff (all)*/
/* access methods */
void (*writeio)(struct fb_info *info, void __iomem *dst, void *src, unsigned int size);
void (*readio) (struct fb_info *info, void *dst, void __iomem *src, unsigned int size);
};
+#ifdef CONFIG_FB_DEFERRED_IO
+struct fb_deferred_io {
+ /* delay between mkwrite and deferred handler */
+ unsigned long delay;
+ struct mutex lock; /* mutex that protects the page list */
+ struct list_head pagelist; /* list of touched pages */
+ /* callback */
+ void (*deferred_io)(struct fb_info *info, struct list_head *pagelist);
+};
+#endif
/*
* Frame buffer operations
@@ -579,8 +603,10 @@
/* For framebuffers with strange non linear layouts or that do not
* work with normal memory mapped access
*/
- ssize_t (*fb_read)(struct file *file, char __user *buf, size_t count, loff_t *ppos);
- ssize_t (*fb_write)(struct file *file, const char __user *buf, size_t count, loff_t *ppos);
+ ssize_t (*fb_read)(struct fb_info *info, char __user *buf,
+ size_t count, loff_t *ppos);
+ ssize_t (*fb_write)(struct fb_info *info, const char __user *buf,
+ size_t count, loff_t *ppos);
/* checks var and eventually tweaks it to something supported,
* DO NOT MODIFY PAR */
@@ -634,10 +660,13 @@
/* restore saved state */
void (*fb_restore_state)(struct fb_info *info);
+
+ /* get capability given var */
+ void (*fb_get_caps)(struct fb_info *info, struct fb_blit_caps *caps,
+ struct fb_var_screeninfo *var);
};
#ifdef CONFIG_FB_TILEBLITTING
-
#define FB_TILE_CURSOR_NONE 0
#define FB_TILE_CURSOR_UNDERLINE 1
#define FB_TILE_CURSOR_LOWER_THIRD 2
@@ -709,6 +738,8 @@
/* cursor */
void (*fb_tilecursor)(struct fb_info *info,
struct fb_tilecursor *cursor);
+ /* get maximum length of the tile map */
+ int (*fb_get_tilemax)(struct fb_info *info);
};
#endif /* CONFIG_FB_TILEBLITTING */
@@ -778,6 +809,10 @@
struct mutex bl_curve_mutex;
u8 bl_curve[FB_BACKLIGHT_LEVELS];
#endif
+#ifdef CONFIG_FB_DEFERRED_IO
+ struct delayed_work deferred_work;
+ struct fb_deferred_io *fbdefio;
+#endif
struct fb_ops *fbops;
struct device *device; /* This is the parent */
@@ -879,6 +914,16 @@
extern void cfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
extern void cfb_copyarea(struct fb_info *info, const struct fb_copyarea *area);
extern void cfb_imageblit(struct fb_info *info, const struct fb_image *image);
+/*
+ * Drawing operations where framebuffer is in system RAM
+ */
+extern void sys_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
+extern void sys_copyarea(struct fb_info *info, const struct fb_copyarea *area);
+extern void sys_imageblit(struct fb_info *info, const struct fb_image *image);
+extern ssize_t fb_sys_read(struct fb_info *info, char __user *buf,
+ size_t count, loff_t *ppos);
+extern ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
+ size_t count, loff_t *ppos);
/* drivers/video/fbmem.c */
extern int register_framebuffer(struct fb_info *fb_info);
@@ -913,6 +958,12 @@
}
}
+/* drivers/video/fb_defio.c */
+extern void fb_deferred_io_init(struct fb_info *info);
+extern void fb_deferred_io_cleanup(struct fb_info *info);
+extern int fb_deferred_io_fsync(struct file *file, struct dentry *dentry,
+ int datasync);
+
/* drivers/video/fbsysfs.c */
extern struct fb_info *framebuffer_alloc(size_t size, struct device *dev);
extern void framebuffer_release(struct fb_info *info);
diff --git a/include/linux/font.h b/include/linux/font.h
index 53b129f..40a24ab 100644
--- a/include/linux/font.h
+++ b/include/linux/font.h
@@ -49,7 +49,8 @@
/* Get the default font for a specific screen size */
-extern const struct font_desc *get_default_font(int xres, int yres);
+extern const struct font_desc *get_default_font(int xres, int yres,
+ u32 font_w, u32 font_h);
/* Max. length for the name of a predefined font */
#define MAX_FONT_NAME 32
diff --git a/include/linux/fs.h b/include/linux/fs.h
index bc6d27c..7cf0c54 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -30,6 +30,7 @@
#define SEEK_SET 0 /* seek relative to beginning of file */
#define SEEK_CUR 1 /* seek relative to current file position */
#define SEEK_END 2 /* seek relative to end of file */
+#define SEEK_MAX SEEK_END
/* And dynamically-tunable limits and defaults: */
struct files_stat_struct {
@@ -91,6 +92,7 @@
/* public flags for file_system_type */
#define FS_REQUIRES_DEV 1
#define FS_BINARY_MOUNTDATA 2
+#define FS_HAS_SUBTYPE 4
#define FS_REVAL_DOT 16384 /* Check the paths ".", ".." for staleness */
#define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move()
* during rename() internally.
@@ -847,11 +849,6 @@
/* fs/sync.c */
extern int do_sync_mapping_range(struct address_space *mapping, loff_t offset,
loff_t endbyte, unsigned int flags);
-static inline int do_sync_file_range(struct file *file, loff_t offset,
- loff_t endbyte, unsigned int flags)
-{
- return do_sync_mapping_range(file->f_mapping, offset, endbyte, flags);
-}
/* fs/locks.c */
extern void locks_init_lock(struct file_lock *);
@@ -960,6 +957,12 @@
/* Granularity of c/m/atime in ns.
Cannot be worse than a second */
u32 s_time_gran;
+
+ /*
+ * Filesystem subtype. If non-empty the filesystem type field
+ * in /proc/mounts will be "type.subtype"
+ */
+ char *s_subtype;
};
extern struct timespec current_fs_time(struct super_block *sb);
@@ -1735,6 +1738,8 @@
extern void do_generic_mapping_read(struct address_space *mapping,
struct file_ra_state *, struct file *,
loff_t *, read_descriptor_t *, read_actor_t);
+extern int generic_segment_checks(const struct iovec *iov,
+ unsigned long *nr_segs, size_t *count, int access_flags);
/* fs/splice.c */
extern ssize_t generic_file_splice_read(struct file *, loff_t *,
diff --git a/include/linux/futex.h b/include/linux/futex.h
index 3f153b4..820125c 100644
--- a/include/linux/futex.h
+++ b/include/linux/futex.h
@@ -100,6 +100,35 @@
extern int
handle_futex_death(u32 __user *uaddr, struct task_struct *curr, int pi);
+/*
+ * Futexes are matched on equal values of this key.
+ * The key type depends on whether it's a shared or private mapping.
+ * Don't rearrange members without looking at hash_futex().
+ *
+ * offset is aligned to a multiple of sizeof(u32) (== 4) by definition.
+ * We set bit 0 to indicate if it's an inode-based key.
+ */
+union futex_key {
+ struct {
+ unsigned long pgoff;
+ struct inode *inode;
+ int offset;
+ } shared;
+ struct {
+ unsigned long address;
+ struct mm_struct *mm;
+ int offset;
+ } private;
+ struct {
+ unsigned long word;
+ void *ptr;
+ int offset;
+ } both;
+};
+int get_futex_key(u32 __user *uaddr, union futex_key *key);
+void get_futex_key_refs(union futex_key *key);
+void drop_futex_key_refs(union futex_key *key);
+
#ifdef CONFIG_FUTEX
extern void exit_robust_list(struct task_struct *curr);
extern void exit_pi_state_list(struct task_struct *curr);
diff --git a/include/linux/init.h b/include/linux/init.h
index dbbdbd1..8bc32bb 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -77,7 +77,8 @@
extern unsigned int reset_devices;
/* used by init/main.c */
-extern void setup_arch(char **);
+void setup_arch(char **);
+void prepare_namespace(void);
#endif
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index a2d95ff..7951023 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -138,7 +138,7 @@
.journal_info = NULL, \
.cpu_timers = INIT_CPU_TIMERS(tsk.cpu_timers), \
.fs_excl = ATOMIC_INIT(0), \
- .pi_lock = SPIN_LOCK_UNLOCKED, \
+ .pi_lock = __SPIN_LOCK_UNLOCKED(tsk.pi_lock), \
INIT_TRACE_IRQFLAGS \
INIT_LOCKDEP \
}
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 0319f66..f7b01b9 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -44,6 +44,9 @@
* IRQF_TIMER - Flag to mark this interrupt as timer interrupt
* IRQF_PERCPU - Interrupt is per cpu
* IRQF_NOBALANCING - Flag to exclude this interrupt from irq balancing
+ * IRQF_IRQPOLL - Interrupt is used for polling (only the interrupt that is
+ * registered first in an shared interrupt is considered for
+ * performance reasons)
*/
#define IRQF_DISABLED 0x00000020
#define IRQF_SAMPLE_RANDOM 0x00000040
@@ -52,22 +55,29 @@
#define IRQF_TIMER 0x00000200
#define IRQF_PERCPU 0x00000400
#define IRQF_NOBALANCING 0x00000800
+#define IRQF_IRQPOLL 0x00001000
/*
- * Migration helpers. Scheduled for removal in 1/2007
+ * Migration helpers. Scheduled for removal in 9/2007
* Do not use for new code !
*/
-#define SA_INTERRUPT IRQF_DISABLED
-#define SA_SAMPLE_RANDOM IRQF_SAMPLE_RANDOM
-#define SA_SHIRQ IRQF_SHARED
-#define SA_PROBEIRQ IRQF_PROBE_SHARED
-#define SA_PERCPU IRQF_PERCPU
+static inline
+unsigned long __deprecated deprecated_irq_flag(unsigned long flag)
+{
+ return flag;
+}
-#define SA_TRIGGER_LOW IRQF_TRIGGER_LOW
-#define SA_TRIGGER_HIGH IRQF_TRIGGER_HIGH
-#define SA_TRIGGER_FALLING IRQF_TRIGGER_FALLING
-#define SA_TRIGGER_RISING IRQF_TRIGGER_RISING
-#define SA_TRIGGER_MASK IRQF_TRIGGER_MASK
+#define SA_INTERRUPT deprecated_irq_flag(IRQF_DISABLED)
+#define SA_SAMPLE_RANDOM deprecated_irq_flag(IRQF_SAMPLE_RANDOM)
+#define SA_SHIRQ deprecated_irq_flag(IRQF_SHARED)
+#define SA_PROBEIRQ deprecated_irq_flag(IRQF_PROBE_SHARED)
+#define SA_PERCPU deprecated_irq_flag(IRQF_PERCPU)
+
+#define SA_TRIGGER_LOW deprecated_irq_flag(IRQF_TRIGGER_LOW)
+#define SA_TRIGGER_HIGH deprecated_irq_flag(IRQF_TRIGGER_HIGH)
+#define SA_TRIGGER_FALLING deprecated_irq_flag(IRQF_TRIGGER_FALLING)
+#define SA_TRIGGER_RISING deprecated_irq_flag(IRQF_TRIGGER_RISING)
+#define SA_TRIGGER_MASK deprecated_irq_flag(IRQF_TRIGGER_MASK)
typedef irqreturn_t (*irq_handler_t)(int, void *);
@@ -83,11 +93,11 @@
};
extern irqreturn_t no_action(int cpl, void *dev_id);
-extern int request_irq(unsigned int, irq_handler_t handler,
+extern int __must_check request_irq(unsigned int, irq_handler_t handler,
unsigned long, const char *, void *);
extern void free_irq(unsigned int, void *);
-extern int devm_request_irq(struct device *dev, unsigned int irq,
+extern int __must_check devm_request_irq(struct device *dev, unsigned int irq,
irq_handler_t handler, unsigned long irqflags,
const char *devname, void *dev_id);
extern void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id);
diff --git a/include/linux/ioctl32.h b/include/linux/ioctl32.h
deleted file mode 100644
index 948809d..0000000
--- a/include/linux/ioctl32.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef IOCTL32_H
-#define IOCTL32_H 1
-
-#include <linux/compiler.h> /* for __deprecated */
-
-struct file;
-
-typedef int (*ioctl_trans_handler_t)(unsigned int, unsigned int,
- unsigned long, struct file *);
-
-struct ioctl_trans {
- unsigned long cmd;
- ioctl_trans_handler_t handler;
- struct ioctl_trans *next;
-};
-
-#endif
diff --git a/include/linux/ipc.h b/include/linux/ipc.h
index 6da6772..1980867 100644
--- a/include/linux/ipc.h
+++ b/include/linux/ipc.h
@@ -92,16 +92,19 @@
#ifdef CONFIG_SYSVIPC
#define INIT_IPC_NS(ns) .ns = &init_ipc_ns,
-extern int copy_ipcs(unsigned long flags, struct task_struct *tsk);
+extern struct ipc_namespace *copy_ipcs(unsigned long flags,
+ struct ipc_namespace *ns);
#else
#define INIT_IPC_NS(ns)
-static inline int copy_ipcs(unsigned long flags, struct task_struct *tsk)
-{ return 0; }
+static inline struct ipc_namespace *copy_ipcs(unsigned long flags,
+ struct ipc_namespace *ns)
+{
+ return ns;
+}
#endif
#ifdef CONFIG_IPC_NS
extern void free_ipc_ns(struct kref *kref);
-extern int unshare_ipcs(unsigned long flags, struct ipc_namespace **ns);
#endif
static inline struct ipc_namespace *get_ipc_ns(struct ipc_namespace *ns)
diff --git a/include/linux/irq.h b/include/linux/irq.h
index a689940..1695054 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -147,8 +147,6 @@
* @dir: /proc/irq/ procfs entry
* @affinity_entry: /proc/irq/smp_affinity procfs entry on SMP
* @name: flow handler name for /proc/interrupts output
- *
- * Pad this out to 32 bytes for cache and indexing reasons.
*/
struct irq_desc {
irq_flow_handler_t handle_irq;
@@ -175,7 +173,7 @@
struct proc_dir_entry *dir;
#endif
const char *name;
-} ____cacheline_aligned;
+} ____cacheline_internodealigned_in_smp;
extern struct irq_desc irq_desc[NR_IRQS];
diff --git a/include/linux/isdn/capiutil.h b/include/linux/isdn/capiutil.h
index 63bd9cf..5a52f2c 100644
--- a/include/linux/isdn/capiutil.h
+++ b/include/linux/isdn/capiutil.h
@@ -187,7 +187,6 @@
#define CDEBUG_SIZE 1024
#define CDEBUG_GSIZE 4096
-_cdebbuf *cdebbuf_alloc(void);
void cdebbuf_free(_cdebbuf *cdb);
int cdebug_init(void);
void cdebug_exit(void);
diff --git a/include/linux/isdn_divertif.h b/include/linux/isdn_divertif.h
index 0e7e44c..07821ca 100644
--- a/include/linux/isdn_divertif.h
+++ b/include/linux/isdn_divertif.h
@@ -24,6 +24,10 @@
#define DIVERT_REL_ERR 0x04 /* module not registered */
#define DIVERT_REG_NAME isdn_register_divert
+#ifdef __KERNEL__
+#include <linux/isdnif.h>
+#include <linux/types.h>
+
/***************************************************************/
/* structure exchanging data between isdn hl and divert module */
/***************************************************************/
@@ -40,3 +44,4 @@
/* function register */
/*********************/
extern int DIVERT_REG_NAME(isdn_divert_if *);
+#endif
diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h
index 3e3b92d..12178d2 100644
--- a/include/linux/kallsyms.h
+++ b/include/linux/kallsyms.h
@@ -30,6 +30,9 @@
/* Look up a kernel symbol and print it to the kernel messages. */
extern void __print_symbol(const char *fmt, unsigned long address);
+int lookup_symbol_name(unsigned long addr, char *symname);
+int lookup_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name);
+
#else /* !CONFIG_KALLSYMS */
static inline unsigned long kallsyms_lookup_name(const char *name)
@@ -58,6 +61,16 @@
return 0;
}
+static inline int lookup_symbol_name(unsigned long addr, char *symname)
+{
+ return -ERANGE;
+}
+
+static inline int lookup_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name)
+{
+ return -ERANGE;
+}
+
/* Stupid that this does nothing, but I didn't create this mess. */
#define __print_symbol(fmt, addr)
#endif /*CONFIG_KALLSYMS*/
diff --git a/include/linux/kdebug.h b/include/linux/kdebug.h
new file mode 100644
index 0000000..5db38d6
--- /dev/null
+++ b/include/linux/kdebug.h
@@ -0,0 +1,20 @@
+#ifndef _LINUX_KDEBUG_H
+#define _LINUX_KDEBUG_H
+
+#include <asm/kdebug.h>
+
+struct die_args {
+ struct pt_regs *regs;
+ const char *str;
+ long err;
+ int trapnr;
+ int signr;
+};
+
+int register_die_notifier(struct notifier_block *nb);
+int unregister_die_notifier(struct notifier_block *nb);
+
+int notify_die(enum die_val val, const char *str,
+ struct pt_regs *regs, long err, int trap, int sig);
+
+#endif /* _LINUX_KDEBUG_H */
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 696e5ec..8c2c7fc 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -7,6 +7,8 @@
#include <linux/linkage.h>
#include <linux/compat.h>
#include <linux/ioport.h>
+#include <linux/elfcore.h>
+#include <linux/elf.h>
#include <asm/kexec.h>
/* Verify architecture specific macros are defined */
@@ -31,6 +33,19 @@
#error KEXEC_ARCH not defined
#endif
+#define KEXEC_NOTE_HEAD_BYTES ALIGN(sizeof(struct elf_note), 4)
+#define KEXEC_CORE_NOTE_NAME "CORE"
+#define KEXEC_CORE_NOTE_NAME_BYTES ALIGN(sizeof(KEXEC_CORE_NOTE_NAME), 4)
+#define KEXEC_CORE_NOTE_DESC_BYTES ALIGN(sizeof(struct elf_prstatus), 4)
+/*
+ * The per-cpu notes area is a list of notes terminated by a "NULL"
+ * note header. For kdump, the code in vmcore.c runs in the context
+ * of the second kernel to combine them into one note.
+ */
+#define KEXEC_NOTE_BYTES ( (KEXEC_NOTE_HEAD_BYTES * 2) + \
+ KEXEC_CORE_NOTE_NAME_BYTES + \
+ KEXEC_CORE_NOTE_DESC_BYTES )
+
/*
* This structure is used to hold the arguments that are used when loading
* kernel binaries.
@@ -136,7 +151,7 @@
/* Location of a reserved region to hold the crash kernel.
*/
extern struct resource crashk_res;
-typedef u32 note_buf_t[MAX_NOTE_BYTES/4];
+typedef u32 note_buf_t[KEXEC_NOTE_BYTES/4];
extern note_buf_t *crash_notes;
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
index 769be39..23adf60 100644
--- a/include/linux/kprobes.h
+++ b/include/linux/kprobes.h
@@ -78,7 +78,7 @@
kprobe_opcode_t *addr;
/* Allow user to indicate symbol name of the probe point */
- char *symbol_name;
+ const char *symbol_name;
/* Offset into the symbol */
unsigned int offset;
@@ -123,12 +123,18 @@
DECLARE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
#ifdef ARCH_SUPPORTS_KRETPROBES
-extern void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs);
+extern void arch_prepare_kretprobe(struct kretprobe_instance *ri,
+ struct pt_regs *regs);
+extern int arch_trampoline_kprobe(struct kprobe *p);
#else /* ARCH_SUPPORTS_KRETPROBES */
static inline void arch_prepare_kretprobe(struct kretprobe *rp,
struct pt_regs *regs)
{
}
+static inline int arch_trampoline_kprobe(struct kprobe *p)
+{
+ return 0;
+}
#endif /* ARCH_SUPPORTS_KRETPROBES */
/*
* Function-return probe -
@@ -157,6 +163,16 @@
struct task_struct *task;
};
+static inline void kretprobe_assert(struct kretprobe_instance *ri,
+ unsigned long orig_ret_address, unsigned long trampoline_address)
+{
+ if (!orig_ret_address || (orig_ret_address == trampoline_address)) {
+ printk("kretprobe BUG!: Processing kretprobe %p @ %p\n",
+ ri->rp, ri->rp->kp.addr);
+ BUG();
+ }
+}
+
extern spinlock_t kretprobe_lock;
extern struct mutex kprobe_mutex;
extern int arch_prepare_kprobe(struct kprobe *p);
@@ -199,8 +215,6 @@
int register_kretprobe(struct kretprobe *rp);
void unregister_kretprobe(struct kretprobe *rp);
-struct kretprobe_instance *get_free_rp_inst(struct kretprobe *rp);
-void add_rp_inst(struct kretprobe_instance *ri);
void kprobe_flush_task(struct task_struct *tk);
void recycle_rp_inst(struct kretprobe_instance *ri, struct hlist_head *head);
#else /* CONFIG_KPROBES */
diff --git a/include/linux/list.h b/include/linux/list.h
index f9d71ea..9202703 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -426,6 +426,17 @@
container_of(ptr, type, member)
/**
+ * list_first_entry - get the first element from a list
+ * @ptr: the list head to take the element from.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Note, that list is expected to be not empty.
+ */
+#define list_first_entry(ptr, type, member) \
+ list_entry((ptr)->next, type, member)
+
+/**
* list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop cursor.
* @head: the head for your list.
diff --git a/include/linux/loop.h b/include/linux/loop.h
index 191a595..0b99b31 100644
--- a/include/linux/loop.h
+++ b/include/linux/loop.h
@@ -64,6 +64,8 @@
wait_queue_head_t lo_event;
request_queue_t *lo_queue;
+ struct gendisk *lo_disk;
+ struct list_head lo_list;
};
#endif /* __KERNEL__ */
diff --git a/include/linux/mc146818rtc.h b/include/linux/mc146818rtc.h
index bdc0112..580b3f4 100644
--- a/include/linux/mc146818rtc.h
+++ b/include/linux/mc146818rtc.h
@@ -22,8 +22,15 @@
/* Some RTCs extend the mc146818 register set to support alarms of more
* than 24 hours in the future; or dates that include a century code.
* This platform_data structure can pass this information to the driver.
+ *
+ * Also, some platforms need suspend()/resume() hooks to kick in special
+ * handling of wake alarms, e.g. activating ACPI BIOS hooks or setting up
+ * a separate wakeup alarm used by some almost-clone chips.
*/
struct cmos_rtc_board_info {
+ void (*wake_on)(struct device *dev);
+ void (*wake_off)(struct device *dev);
+
u8 rtc_day_alarm; /* zero, or register index */
u8 rtc_mon_alarm; /* zero, or register index */
u8 rtc_century; /* zero, or register index */
diff --git a/include/linux/mnt_namespace.h b/include/linux/mnt_namespace.h
index 4af0b1f..1fa4d98 100644
--- a/include/linux/mnt_namespace.h
+++ b/include/linux/mnt_namespace.h
@@ -14,10 +14,9 @@
int event;
};
-extern int copy_mnt_ns(int, struct task_struct *);
-extern void __put_mnt_ns(struct mnt_namespace *ns);
-extern struct mnt_namespace *dup_mnt_ns(struct task_struct *,
+extern struct mnt_namespace *copy_mnt_ns(int, struct mnt_namespace *,
struct fs_struct *);
+extern void __put_mnt_ns(struct mnt_namespace *ns);
static inline void put_mnt_ns(struct mnt_namespace *ns)
{
diff --git a/include/linux/module.h b/include/linux/module.h
index f0b0faf..6d3dc9c 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -370,16 +370,14 @@
struct module *__module_text_address(unsigned long addr);
int is_module_address(unsigned long addr);
-/* Returns module and fills in value, defined and namebuf, or NULL if
+/* Returns 0 and fills in value, defined and namebuf, or -ERANGE if
symnum out of range. */
-struct module *module_get_kallsym(unsigned int symnum, unsigned long *value,
- char *type, char *name, size_t namelen);
+int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
+ char *name, char *module_name, int *exported);
/* Look for this name: can be of form module:name. */
unsigned long module_kallsyms_lookup_name(const char *name);
-int is_exported(const char *name, const struct module *mod);
-
extern void __module_put_and_exit(struct module *mod, long code)
__attribute__((noreturn));
#define module_put_and_exit(code) __module_put_and_exit(THIS_MODULE, code);
@@ -456,6 +454,8 @@
unsigned long *symbolsize,
unsigned long *offset,
char **modname);
+int lookup_module_symbol_name(unsigned long addr, char *symname);
+int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name);
/* For extable.c to search modules' exception tables. */
const struct exception_table_entry *search_module_extables(unsigned long addr);
@@ -527,12 +527,21 @@
return NULL;
}
-static inline struct module *module_get_kallsym(unsigned int symnum,
- unsigned long *value,
- char *type, char *name,
- size_t namelen)
+static inline int lookup_module_symbol_name(unsigned long addr, char *symname)
{
- return NULL;
+ return -ERANGE;
+}
+
+static inline int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name)
+{
+ return -ERANGE;
+}
+
+static inline int module_get_kallsym(unsigned int symnum, unsigned long *value,
+ char *type, char *name,
+ char *module_name, int *exported)
+{
+ return -ERANGE;
}
static inline unsigned long module_kallsyms_lookup_name(const char *name)
@@ -540,11 +549,6 @@
return 0;
}
-static inline int is_exported(const char *name, const struct module *mod)
-{
- return 0;
-}
-
static inline int register_module_notifier(struct notifier_block * nb)
{
/* no events will happen anyway, so this can always succeed */
diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h
index fa253fa..0e09c00 100644
--- a/include/linux/msdos_fs.h
+++ b/include/linux/msdos_fs.h
@@ -205,7 +205,8 @@
numtail:1, /* Does first alias have a numeric '~1' type tail? */
atari:1, /* Use Atari GEMDOS variation of MS-DOS fs */
flush:1, /* write things quickly */
- nocase:1; /* Does this need case conversion? 0=need case conversion*/
+ nocase:1, /* Does this need case conversion? 0=need case conversion*/
+ usefree:1; /* Use free_clusters for FAT32 */
};
#define FAT_HASH_BITS 8
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index c95d5e6..52b4378 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -82,7 +82,7 @@
struct rpc_clnt * client_acl; /* ACL RPC client handle */
struct nfs_iostats * io_stats; /* I/O statistics */
struct backing_dev_info backing_dev_info;
- atomic_t writeback; /* number of writeback pages */
+ atomic_long_t writeback; /* number of writeback pages */
int flags; /* various flags */
unsigned int caps; /* server capabilities */
unsigned int rsize; /* read size */
diff --git a/include/linux/nsproxy.h b/include/linux/nsproxy.h
index 0b9f0dc..189e0dc 100644
--- a/include/linux/nsproxy.h
+++ b/include/linux/nsproxy.h
@@ -31,10 +31,11 @@
};
extern struct nsproxy init_nsproxy;
-struct nsproxy *dup_namespaces(struct nsproxy *orig);
int copy_namespaces(int flags, struct task_struct *tsk);
void get_task_namespaces(struct task_struct *tsk);
void free_nsproxy(struct nsproxy *ns);
+int unshare_nsproxy_namespaces(unsigned long, struct nsproxy **,
+ struct fs_struct *);
static inline void put_nsproxy(struct nsproxy *ns)
{
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index b4def5e..8a83537 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -11,6 +11,7 @@
#include <linux/compiler.h>
#include <asm/uaccess.h>
#include <linux/gfp.h>
+#include <linux/bitops.h>
/*
* Bits in mapping->flags. The lower __GFP_BITS_SHIFT bits are the page
@@ -19,6 +20,16 @@
#define AS_EIO (__GFP_BITS_SHIFT + 0) /* IO error on async write */
#define AS_ENOSPC (__GFP_BITS_SHIFT + 1) /* ENOSPC on async write */
+static inline void mapping_set_error(struct address_space *mapping, int error)
+{
+ if (error) {
+ if (error == -ENOSPC)
+ set_bit(AS_ENOSPC, &mapping->flags);
+ else
+ set_bit(AS_EIO, &mapping->flags);
+ }
+}
+
static inline gfp_t mapping_gfp_mask(struct address_space * mapping)
{
return (__force gfp_t)mapping->flags & __GFP_BITS_MASK;
diff --git a/include/linux/parport.h b/include/linux/parport.h
index 80682aa..9cdd694 100644
--- a/include/linux/parport.h
+++ b/include/linux/parport.h
@@ -279,6 +279,10 @@
int dma;
int muxport; /* which muxport (if any) this is */
int portnum; /* which physical parallel port (not mux) */
+ struct device *dev; /* Physical device associated with IO/DMA.
+ * This may unfortulately be null if the
+ * port has a legacy driver.
+ */
struct parport *physport;
/* If this is a non-default mux
@@ -289,7 +293,7 @@
following structure members are
meaningless: devices, cad, muxsel,
waithead, waittail, flags, pdir,
- ieee1284, *_lock.
+ dev, ieee1284, *_lock.
It this is a default mux parport, or
there is no mux involved, this points to
@@ -302,7 +306,7 @@
struct pardevice *waithead;
struct pardevice *waittail;
-
+
struct list_head list;
unsigned int flags;
diff --git a/include/linux/parport_pc.h b/include/linux/parport_pc.h
index 1cc0f6b..ea8c6d8 100644
--- a/include/linux/parport_pc.h
+++ b/include/linux/parport_pc.h
@@ -38,7 +38,6 @@
/* buffer suitable for DMA, if DMA enabled */
char *dma_buf;
dma_addr_t dma_handle;
- struct pci_dev *dev;
struct list_head list;
struct parport *port;
};
@@ -232,7 +231,7 @@
extern struct parport *parport_pc_probe_port (unsigned long base,
unsigned long base_hi,
int irq, int dma,
- struct pci_dev *dev);
+ struct device *dev);
extern void parport_pc_unregister_port (struct parport *p);
#endif
diff --git a/include/linux/phantom.h b/include/linux/phantom.h
new file mode 100644
index 0000000..d3ebbfa
--- /dev/null
+++ b/include/linux/phantom.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2005-2007 Jiri Slaby <jirislaby@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __PHANTOM_H
+#define __PHANTOM_H
+
+#include <asm/types.h>
+
+/* PHN_(G/S)ET_REG param */
+struct phm_reg {
+ __u32 reg;
+ __u32 value;
+};
+
+/* PHN_(G/S)ET_REGS param */
+struct phm_regs {
+ __u32 count;
+ __u32 mask;
+ __u32 values[8];
+};
+
+#define PH_IOC_MAGIC 'p'
+#define PHN_GET_REG _IOWR(PH_IOC_MAGIC, 0, struct phm_reg *)
+#define PHN_SET_REG _IOW (PH_IOC_MAGIC, 1, struct phm_reg *)
+#define PHN_GET_REGS _IOWR(PH_IOC_MAGIC, 2, struct phm_regs *)
+#define PHN_SET_REGS _IOW (PH_IOC_MAGIC, 3, struct phm_regs *)
+#define PH_IOC_MAXNR 3
+
+#define PHN_CONTROL 0x6 /* control byte in iaddr space */
+#define PHN_CTL_AMP 0x1 /* switch after torques change */
+#define PHN_CTL_BUT 0x2 /* is button switched */
+#define PHN_CTL_IRQ 0x10 /* is irq enabled */
+
+#define PHN_ZERO_FORCE 2048 /* zero torque on motor */
+
+#endif
diff --git a/include/linux/pid_namespace.h b/include/linux/pid_namespace.h
index 2833806..169c6c2 100644
--- a/include/linux/pid_namespace.h
+++ b/include/linux/pid_namespace.h
@@ -29,7 +29,7 @@
kref_get(&ns->kref);
}
-extern int copy_pid_ns(int flags, struct task_struct *tsk);
+extern struct pid_namespace *copy_pid_ns(int flags, struct pid_namespace *ns);
extern void free_pid_ns(struct kref *kref);
static inline void put_pid_ns(struct pid_namespace *ns)
diff --git a/include/linux/pmu.h b/include/linux/pmu.h
index b0952e5..37ca573 100644
--- a/include/linux/pmu.h
+++ b/include/linux/pmu.h
@@ -225,4 +225,12 @@
/* Backlight */
extern void pmu_backlight_init(void);
+/* some code needs to know if the PMU was suspended for hibernation */
+#ifdef CONFIG_PM
+extern int pmu_sys_suspended;
+#else
+/* if power management is not configured it can't be suspended */
+#define pmu_sys_suspended 0
+#endif
+
#endif /* __KERNEL__ */
diff --git a/include/linux/pnp.h b/include/linux/pnp.h
index 9a5226f..2a1897e 100644
--- a/include/linux/pnp.h
+++ b/include/linux/pnp.h
@@ -177,6 +177,7 @@
struct pnp_dev {
struct device dev; /* Driver Model device interface */
+ u64 dma_mask;
unsigned char number; /* used as an index, must be unique */
int status;
@@ -363,6 +364,7 @@
int pnp_device_attach(struct pnp_dev *pnp_dev);
void pnp_device_detach(struct pnp_dev *pnp_dev);
extern struct list_head pnp_global;
+extern int pnp_platform_devices;
/* multidevice card support */
int pnp_add_card(struct pnp_card *card);
@@ -410,6 +412,7 @@
static inline int pnp_add_device(struct pnp_dev *dev) { return -ENODEV; }
static inline int pnp_device_attach(struct pnp_dev *pnp_dev) { return -ENODEV; }
static inline void pnp_device_detach(struct pnp_dev *pnp_dev) { ; }
+#define pnp_platform_devices 0
/* multidevice card support */
static inline int pnp_add_card(struct pnp_card *card) { return -ENODEV; }
diff --git a/include/linux/poison.h b/include/linux/poison.h
index 95f518b..d93c300 100644
--- a/include/linux/poison.h
+++ b/include/linux/poison.h
@@ -15,8 +15,8 @@
* Magic nums for obj red zoning.
* Placed in the first word before and the first word after an obj.
*/
-#define RED_INACTIVE 0x5A2CF071UL /* when obj is inactive */
-#define RED_ACTIVE 0x170FC2A5UL /* when obj is active */
+#define RED_INACTIVE 0x09F911029D74E35BULL /* when obj is inactive */
+#define RED_ACTIVE 0xD84156C5635688C0ULL /* when obj is active */
#define SLUB_RED_INACTIVE 0xbb
#define SLUB_RED_ACTIVE 0xcc
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index f4f7a63..3469f96 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -106,6 +106,9 @@
char *task_mem(struct mm_struct *, char *);
void clear_refs_smap(struct mm_struct *mm);
+struct proc_dir_entry *de_get(struct proc_dir_entry *de);
+void de_put(struct proc_dir_entry *de);
+
extern struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
struct proc_dir_entry *parent);
extern void remove_proc_entry(const char *name, struct proc_dir_entry *parent);
diff --git a/include/linux/quota.h b/include/linux/quota.h
index 77db80a..6243982 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -44,8 +44,6 @@
typedef __kernel_uid32_t qid_t; /* Type in which we store ids in memory */
typedef __u64 qsize_t; /* Type in which we store sizes */
-extern spinlock_t dq_data_lock;
-
/* Size of blocks in which are counted size limits */
#define QUOTABLOCK_BITS 10
#define QUOTABLOCK_SIZE (1 << QUOTABLOCK_BITS)
@@ -139,6 +137,8 @@
#include <linux/dqblk_v1.h>
#include <linux/dqblk_v2.h>
+extern spinlock_t dq_data_lock;
+
/* Maximal numbers of writes for quota operation (insert/delete/update)
* (over VFS all formats) */
#define DQUOT_INIT_ALLOC max(V1_INIT_ALLOC, V2_INIT_ALLOC)
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index 90c23f6..5110201 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -37,9 +37,6 @@
extern int dquot_commit_info(struct super_block *sb, int type);
extern int dquot_mark_dquot_dirty(struct dquot *dquot);
-int remove_inode_dquot_ref(struct inode *inode, int type,
- struct list_head *tofree_head);
-
extern int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path);
extern int vfs_quota_on_mount(struct super_block *sb, char *qf_name,
int format_id, int type);
diff --git a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h
index 3a28742..1e5488e 100644
--- a/include/linux/reiserfs_fs_sb.h
+++ b/include/linux/reiserfs_fs_sb.h
@@ -401,9 +401,10 @@
int reserved_blocks; /* amount of blocks reserved for further allocations */
spinlock_t bitmap_lock; /* this lock on now only used to protect reserved_blocks variable */
struct dentry *priv_root; /* root of /.reiserfs_priv */
+#ifdef CONFIG_REISERFS_FS_XATTR
struct dentry *xattr_root; /* root of /.reiserfs_priv/.xa */
struct rw_semaphore xattr_dir_sem;
-
+#endif
int j_errno;
#ifdef CONFIG_QUOTA
char *s_qf_names[MAXQUOTAS];
diff --git a/include/linux/rtc.h b/include/linux/rtc.h
index 5e22d45..6d5e4a4 100644
--- a/include/linux/rtc.h
+++ b/include/linux/rtc.h
@@ -4,7 +4,7 @@
* service. It is used with both the legacy mc146818 and also EFI
* Struct rtc_time and first 12 ioctl by Paul Gortmaker, 1996 - separated out
* from <linux/mc146818rtc.h> to this file for 2.4 kernels.
- *
+ *
* Copyright (C) 1999 Hewlett-Packard Co.
* Copyright (C) 1999 Stephane Eranian <eranian@hpl.hp.com>
*/
@@ -13,7 +13,7 @@
/*
* The struct used to pass data via the following ioctl. Similar to the
- * struct tm in <time.h>, but it needs to be here so that the kernel
+ * struct tm in <time.h>, but it needs to be here so that the kernel
* source is self contained, allowing cross-compiles, etc. etc.
*/
@@ -50,7 +50,7 @@
* pll_value*pll_posmult/pll_clock
* -ve pll_value means clock will run slower by
* pll_value*pll_negmult/pll_clock
- */
+ */
struct rtc_pll_info {
int pll_ctrl; /* placeholder for fancier control */
@@ -106,7 +106,6 @@
extern int rtc_valid_tm(struct rtc_time *tm);
extern int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time);
extern void rtc_time_to_tm(unsigned long time, struct rtc_time *tm);
-extern void rtc_merge_alarm(struct rtc_time *now, struct rtc_time *alarm);
#include <linux/device.h>
#include <linux/seq_file.h>
@@ -136,7 +135,7 @@
struct rtc_device
{
- struct class_device class_dev;
+ struct device dev;
struct module *owner;
int id;
@@ -145,7 +144,6 @@
const struct rtc_class_ops *ops;
struct mutex ops_lock;
- struct class_device *rtc_dev;
struct cdev char_dev;
struct mutex char_lock;
@@ -169,35 +167,34 @@
unsigned int uie_timer_active:1;
#endif
};
-#define to_rtc_device(d) container_of(d, struct rtc_device, class_dev)
+#define to_rtc_device(d) container_of(d, struct rtc_device, dev)
extern struct rtc_device *rtc_device_register(const char *name,
struct device *dev,
const struct rtc_class_ops *ops,
struct module *owner);
-extern void rtc_device_unregister(struct rtc_device *rdev);
-extern int rtc_interface_register(struct class_interface *intf);
+extern void rtc_device_unregister(struct rtc_device *rtc);
-extern int rtc_read_time(struct class_device *class_dev, struct rtc_time *tm);
-extern int rtc_set_time(struct class_device *class_dev, struct rtc_time *tm);
-extern int rtc_set_mmss(struct class_device *class_dev, unsigned long secs);
-extern int rtc_read_alarm(struct class_device *class_dev,
+extern int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm);
+extern int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm);
+extern int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs);
+extern int rtc_read_alarm(struct rtc_device *rtc,
struct rtc_wkalrm *alrm);
-extern int rtc_set_alarm(struct class_device *class_dev,
+extern int rtc_set_alarm(struct rtc_device *rtc,
struct rtc_wkalrm *alrm);
-extern void rtc_update_irq(struct class_device *class_dev,
+extern void rtc_update_irq(struct rtc_device *rtc,
unsigned long num, unsigned long events);
-extern struct class_device *rtc_class_open(char *name);
-extern void rtc_class_close(struct class_device *class_dev);
+extern struct rtc_device *rtc_class_open(char *name);
+extern void rtc_class_close(struct rtc_device *rtc);
-extern int rtc_irq_register(struct class_device *class_dev,
+extern int rtc_irq_register(struct rtc_device *rtc,
struct rtc_task *task);
-extern void rtc_irq_unregister(struct class_device *class_dev,
+extern void rtc_irq_unregister(struct rtc_device *rtc,
struct rtc_task *task);
-extern int rtc_irq_set_state(struct class_device *class_dev,
+extern int rtc_irq_set_state(struct rtc_device *rtc,
struct rtc_task *task, int enabled);
-extern int rtc_irq_set_freq(struct class_device *class_dev,
+extern int rtc_irq_set_freq(struct rtc_device *rtc,
struct rtc_task *task, int freq);
typedef struct rtc_task {
diff --git a/include/linux/sched.h b/include/linux/sched.h
index a170758..3d95c48 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -194,6 +194,14 @@
extern void init_idle(struct task_struct *idle, int cpu);
extern cpumask_t nohz_cpu_mask;
+#if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ)
+extern int select_nohz_load_balancer(int cpu);
+#else
+static inline int select_nohz_load_balancer(int cpu)
+{
+ return 0;
+}
+#endif
/*
* Only dump TASK_* tasks. (0 for all tasks)
@@ -226,6 +234,7 @@
extern void softlockup_tick(void);
extern void spawn_softlockup_task(void);
extern void touch_softlockup_watchdog(void);
+extern void touch_all_softlockup_watchdogs(void);
#else
static inline void softlockup_tick(void)
{
@@ -236,6 +245,9 @@
static inline void touch_softlockup_watchdog(void)
{
}
+static inline void touch_all_softlockup_watchdogs(void)
+{
+}
#endif
@@ -668,8 +680,14 @@
/*
* CPU power of this group, SCHED_LOAD_SCALE being max power for a
* single CPU. This is read only (except for setup, hotplug CPU).
+ * Note : Never change cpu_power without recompute its reciprocal
*/
- unsigned long cpu_power;
+ unsigned int __cpu_power;
+ /*
+ * reciprocal value of cpu_power to avoid expensive divides
+ * (see include/linux/reciprocal_div.h)
+ */
+ u32 reciprocal_cpu_power;
};
struct sched_domain {
@@ -801,8 +819,8 @@
volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
struct thread_info *thread_info;
atomic_t usage;
- unsigned long flags; /* per process flags, defined below */
- unsigned long ptrace;
+ unsigned int flags; /* per process flags, defined below */
+ unsigned int ptrace;
int lock_depth; /* BKL lock depth */
@@ -825,7 +843,7 @@
unsigned long long sched_time; /* sched_clock time spent running */
enum sleep_type sleep_type;
- unsigned long policy;
+ unsigned int policy;
cpumask_t cpus_allowed;
unsigned int time_slice, first_time_slice;
@@ -845,11 +863,11 @@
/* task state */
struct linux_binfmt *binfmt;
- long exit_state;
+ int exit_state;
int exit_code, exit_signal;
int pdeath_signal; /* The signal sent when the parent dies */
/* ??? */
- unsigned long personality;
+ unsigned int personality;
unsigned did_exec:1;
pid_t pid;
pid_t tgid;
@@ -881,7 +899,7 @@
int __user *set_child_tid; /* CLONE_CHILD_SETTID */
int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
- unsigned long rt_priority;
+ unsigned int rt_priority;
cputime_t utime, stime;
unsigned long nvcsw, nivcsw; /* context switch counts */
struct timespec start_time;
@@ -1641,10 +1659,7 @@
extern long sched_setaffinity(pid_t pid, cpumask_t new_mask);
extern long sched_getaffinity(pid_t pid, cpumask_t *mask);
-#include <linux/sysdev.h>
extern int sched_mc_power_savings, sched_smt_power_savings;
-extern struct sysdev_attribute attr_sched_mc_power_savings, attr_sched_smt_power_savings;
-extern int sched_create_sysfs_power_savings_entries(struct sysdev_class *cls);
extern void normalize_rt_tasks(void);
diff --git a/include/linux/spi/Kbuild b/include/linux/spi/Kbuild
new file mode 100644
index 0000000..d375a08
--- /dev/null
+++ b/include/linux/spi/Kbuild
@@ -0,0 +1 @@
+header-y += spidev.h
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 4f0f8c2..b6bedc3 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -32,11 +32,12 @@
* @max_speed_hz: Maximum clock rate to be used with this chip
* (on this board); may be changed by the device's driver.
* The spi_transfer.speed_hz can override this for each transfer.
- * @chip-select: Chipselect, distinguishing chips handled by "master".
+ * @chip_select: Chipselect, distinguishing chips handled by @master.
* @mode: The spi mode defines how data is clocked out and in.
* This may be changed by the device's driver.
- * The "active low" default for chipselect mode can be overridden,
- * as can the "MSB first" default for each word in a transfer.
+ * The "active low" default for chipselect mode can be overridden
+ * (by specifying SPI_CS_HIGH) as can the "MSB first" default for
+ * each word in a transfer (by specifying SPI_LSB_FIRST).
* @bits_per_word: Data transfers involve one or more words; word sizes
* like eight or 12 bits are common. In-memory wordsizes are
* powers of two bytes (e.g. 20 bit samples use 32 bits).
@@ -48,14 +49,18 @@
* @controller_state: Controller's runtime state
* @controller_data: Board-specific definitions for controller, such as
* FIFO initialization parameters; from board_info.controller_data
+ * @modalias: Name of the driver to use with this device, or an alias
+ * for that name. This appears in the sysfs "modalias" attribute
+ * for driver coldplugging, and in uevents used for hotplugging
*
- * An spi_device is used to interchange data between an SPI slave
+ * A @spi_device is used to interchange data between an SPI slave
* (usually a discrete chip) and CPU memory.
*
- * In "dev", the platform_data is used to hold information about this
+ * In @dev, the platform_data is used to hold information about this
* device that's meaningful to the device's protocol driver, but not
* to its controller. One example might be an identifier for a chip
- * variant with slightly different functionality.
+ * variant with slightly different functionality; another might be
+ * information about how this particular board wires the chip's pins.
*/
struct spi_device {
struct device dev;
@@ -77,13 +82,15 @@
void *controller_data;
const char *modalias;
- // likely need more hooks for more protocol options affecting how
- // the controller talks to each chip, like:
- // - memory packing (12 bit samples into low bits, others zeroed)
- // - priority
- // - drop chipselect after each word
- // - chipselect delays
- // - ...
+ /*
+ * likely need more hooks for more protocol options affecting how
+ * the controller talks to each chip, like:
+ * - memory packing (12 bit samples into low bits, others zeroed)
+ * - priority
+ * - drop chipselect after each word
+ * - chipselect delays
+ * - ...
+ */
};
static inline struct spi_device *to_spi_device(struct device *dev)
@@ -146,6 +153,11 @@
extern int spi_register_driver(struct spi_driver *sdrv);
+/**
+ * spi_unregister_driver - reverse effect of spi_register_driver
+ * @sdrv: the driver to unregister
+ * Context: can sleep
+ */
static inline void spi_unregister_driver(struct spi_driver *sdrv)
{
if (sdrv)
@@ -165,18 +177,20 @@
* @setup: updates the device mode and clocking records used by a
* device's SPI controller; protocol code may call this. This
* must fail if an unrecognized or unsupported mode is requested.
+ * It's always safe to call this unless transfers are pending on
+ * the device whose settings are being modified.
* @transfer: adds a message to the controller's transfer queue.
* @cleanup: frees controller-specific state
*
- * Each SPI master controller can communicate with one or more spi_device
+ * Each SPI master controller can communicate with one or more @spi_device
* children. These make a small bus, sharing MOSI, MISO and SCK signals
* but not chip select signals. Each device may be configured to use a
* different clock rate, since those shared signals are ignored unless
* the chip is selected.
*
* The driver for an SPI controller manages access to those devices through
- * a queue of spi_message transactions, copyin data between CPU memory and
- * an SPI slave device). For each such message it queues, it calls the
+ * a queue of spi_message transactions, copying data between CPU memory and
+ * an SPI slave device. For each such message it queues, it calls the
* message's completion function when the transaction completes.
*/
struct spi_master {
@@ -280,27 +294,27 @@
* struct spi_transfer - a read/write buffer pair
* @tx_buf: data to be written (dma-safe memory), or NULL
* @rx_buf: data to be read (dma-safe memory), or NULL
- * @tx_dma: DMA address of tx_buf, if spi_message.is_dma_mapped
- * @rx_dma: DMA address of rx_buf, if spi_message.is_dma_mapped
+ * @tx_dma: DMA address of tx_buf, if @spi_message.is_dma_mapped
+ * @rx_dma: DMA address of rx_buf, if @spi_message.is_dma_mapped
* @len: size of rx and tx buffers (in bytes)
* @speed_hz: Select a speed other then the device default for this
- * transfer. If 0 the default (from spi_device) is used.
+ * transfer. If 0 the default (from @spi_device) is used.
* @bits_per_word: select a bits_per_word other then the device default
- * for this transfer. If 0 the default (from spi_device) is used.
+ * for this transfer. If 0 the default (from @spi_device) is used.
* @cs_change: affects chipselect after this transfer completes
* @delay_usecs: microseconds to delay after this transfer before
* (optionally) changing the chipselect status, then starting
- * the next transfer or completing this spi_message.
- * @transfer_list: transfers are sequenced through spi_message.transfers
+ * the next transfer or completing this @spi_message.
+ * @transfer_list: transfers are sequenced through @spi_message.transfers
*
* SPI transfers always write the same number of bytes as they read.
- * Protocol drivers should always provide rx_buf and/or tx_buf.
+ * Protocol drivers should always provide @rx_buf and/or @tx_buf.
* In some cases, they may also want to provide DMA addresses for
* the data being transferred; that may reduce overhead, when the
* underlying driver uses dma.
*
* If the transmit buffer is null, zeroes will be shifted out
- * while filling rx_buf. If the receive buffer is null, the data
+ * while filling @rx_buf. If the receive buffer is null, the data
* shifted in will be discarded. Only "len" bytes shift out (or in).
* It's an error to try to shift out a partial word. (For example, by
* shifting out three bytes with word size of sixteen or twenty bits;
@@ -309,7 +323,7 @@
* In-memory data values are always in native CPU byte order, translated
* from the wire byte order (big-endian except with SPI_LSB_FIRST). So
* for example when bits_per_word is sixteen, buffers are 2N bytes long
- * and hold N sixteen bit words in CPU byte order.
+ * (@len = 2N) and hold N sixteen bit words in CPU byte order.
*
* When the word size of the SPI transfer is not a power-of-two multiple
* of eight bits, those in-memory words include extra bits. In-memory
@@ -318,7 +332,7 @@
*
* All SPI transfers start with the relevant chipselect active. Normally
* it stays selected until after the last transfer in a message. Drivers
- * can affect the chipselect signal using cs_change:
+ * can affect the chipselect signal using cs_change.
*
* (i) If the transfer isn't the last one in the message, this flag is
* used to make the chipselect briefly go inactive in the middle of the
@@ -372,7 +386,7 @@
* @queue: for use by whichever driver currently owns the message
* @state: for use by whichever driver currently owns the message
*
- * An spi_message is used to execute an atomic sequence of data transfers,
+ * A @spi_message is used to execute an atomic sequence of data transfers,
* each represented by a struct spi_transfer. The sequence is "atomic"
* in the sense that no other spi_message may use that SPI bus until that
* sequence completes. On some systems, many such sequences can execute as
@@ -464,8 +478,9 @@
}
/**
- * spi_setup -- setup SPI mode and clock rate
+ * spi_setup - setup SPI mode and clock rate
* @spi: the device whose settings are being modified
+ * Context: can sleep
*
* SPI protocol drivers may need to update the transfer mode if the
* device doesn't work with the mode 0 default. They may likewise need
@@ -474,7 +489,7 @@
* The changes take effect the next time the device is selected and data
* is transferred to or from it.
*
- * Note that this call wil fail if the protocol driver specifies an option
+ * Note that this call will fail if the protocol driver specifies an option
* that the underlying controller or its driver does not support. For
* example, not all hardware supports wire transfers using nine bit words,
* LSB-first wire encoding, or active-high chipselects.
@@ -487,9 +502,10 @@
/**
- * spi_async -- asynchronous SPI transfer
+ * spi_async - asynchronous SPI transfer
* @spi: device with which data will be exchanged
* @message: describes the data transfers, including completion callback
+ * Context: any (irqs may be blocked, etc)
*
* This call may be used in_irq and other contexts which can't sleep,
* as well as from task contexts which can sleep.
@@ -535,6 +551,7 @@
* @spi: device to which data will be written
* @buf: data buffer
* @len: data buffer size
+ * Context: can sleep
*
* This writes the buffer and returns zero or a negative error code.
* Callable only from contexts that can sleep.
@@ -558,8 +575,9 @@
* @spi: device from which data will be read
* @buf: data buffer
* @len: data buffer size
+ * Context: can sleep
*
- * This writes the buffer and returns zero or a negative error code.
+ * This reads the buffer and returns zero or a negative error code.
* Callable only from contexts that can sleep.
*/
static inline int
@@ -585,6 +603,7 @@
* spi_w8r8 - SPI synchronous 8 bit write followed by 8 bit read
* @spi: device with which data will be exchanged
* @cmd: command to be written before data is read back
+ * Context: can sleep
*
* This returns the (unsigned) eight bit number returned by the
* device, or else a negative error code. Callable only from
@@ -605,6 +624,7 @@
* spi_w8r16 - SPI synchronous 8 bit write followed by 16 bit read
* @spi: device with which data will be exchanged
* @cmd: command to be written before data is read back
+ * Context: can sleep
*
* This returns the (unsigned) sixteen bit number returned by the
* device, or else a negative error code. Callable only from
diff --git a/include/linux/spi/spidev.h b/include/linux/spi/spidev.h
new file mode 100644
index 0000000..7d700be
--- /dev/null
+++ b/include/linux/spi/spidev.h
@@ -0,0 +1,124 @@
+/*
+ * include/linux/spi/spidev.h
+ *
+ * Copyright (C) 2006 SWAPP
+ * Andrea Paterniani <a.paterniani@swapp-eng.it>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef SPIDEV_H
+#define SPIDEV_H
+
+
+/* User space versions of kernel symbols for SPI clocking modes,
+ * matching <linux/spi/spi.h>
+ */
+
+#define SPI_CPHA 0x01
+#define SPI_CPOL 0x02
+
+#define SPI_MODE_0 (0|0)
+#define SPI_MODE_1 (0|SPI_CPHA)
+#define SPI_MODE_2 (SPI_CPOL|0)
+#define SPI_MODE_3 (SPI_CPOL|SPI_CPHA)
+
+
+/*---------------------------------------------------------------------------*/
+
+/* IOCTL commands */
+
+#define SPI_IOC_MAGIC 'k'
+
+/**
+ * struct spi_ioc_transfer - describes a single SPI transfer
+ * @tx_buf: Holds pointer to userspace buffer with transmit data, or null.
+ * If no data is provided, zeroes are shifted out.
+ * @rx_buf: Holds pointer to userspace buffer for receive data, or null.
+ * @len: Length of tx and rx buffers, in bytes.
+ * @speed_hz: Temporary override of the device's bitrate.
+ * @bits_per_word: Temporary override of the device's wordsize.
+ * @delay_usecs: If nonzero, how long to delay after the last bit transfer
+ * before optionally deselecting the device before the next transfer.
+ * @cs_change: True to deselect device before starting the next transfer.
+ *
+ * This structure is mapped directly to the kernel spi_transfer structure;
+ * the fields have the same meanings, except of course that the pointers
+ * are in a different address space (and may be of different sizes in some
+ * cases, such as 32-bit i386 userspace over a 64-bit x86_64 kernel).
+ * Zero-initialize the structure, including currently unused fields, to
+ * accomodate potential future updates.
+ *
+ * SPI_IOC_MESSAGE gives userspace the equivalent of kernel spi_sync().
+ * Pass it an array of related transfers, they'll execute together.
+ * Each transfer may be half duplex (either direction) or full duplex.
+ *
+ * struct spi_ioc_transfer mesg[4];
+ * ...
+ * status = ioctl(fd, SPI_IOC_MESSAGE(4), mesg);
+ *
+ * So for example one transfer might send a nine bit command (right aligned
+ * in a 16-bit word), the next could read a block of 8-bit data before
+ * terminating that command by temporarily deselecting the chip; the next
+ * could send a different nine bit command (re-selecting the chip), and the
+ * last transfer might write some register values.
+ */
+struct spi_ioc_transfer {
+ __u64 tx_buf;
+ __u64 rx_buf;
+
+ __u32 len;
+ __u32 speed_hz;
+
+ __u16 delay_usecs;
+ __u8 bits_per_word;
+ __u8 cs_change;
+ __u32 pad;
+
+ /* If the contents of 'struct spi_ioc_transfer' ever change
+ * incompatibly, then the ioctl number (currently 0) must change;
+ * ioctls with constant size fields get a bit more in the way of
+ * error checking than ones (like this) where that field varies.
+ *
+ * NOTE: struct layout is the same in 64bit and 32bit userspace.
+ */
+};
+
+/* not all platforms use <asm-generic/ioctl.h> or _IOC_TYPECHECK() ... */
+#define SPI_MSGSIZE(N) \
+ ((((N)*(sizeof (struct spi_ioc_transfer))) < (1 << _IOC_SIZEBITS)) \
+ ? ((N)*(sizeof (struct spi_ioc_transfer))) : 0)
+#define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char[SPI_MSGSIZE(N)])
+
+
+/* Read / Write of SPI mode (SPI_MODE_0..SPI_MODE_3) */
+#define SPI_IOC_RD_MODE _IOR(SPI_IOC_MAGIC, 1, __u8)
+#define SPI_IOC_WR_MODE _IOW(SPI_IOC_MAGIC, 1, __u8)
+
+/* Read / Write SPI bit justification */
+#define SPI_IOC_RD_LSB_FIRST _IOR(SPI_IOC_MAGIC, 2, __u8)
+#define SPI_IOC_WR_LSB_FIRST _IOW(SPI_IOC_MAGIC, 2, __u8)
+
+/* Read / Write SPI device word length (1..N) */
+#define SPI_IOC_RD_BITS_PER_WORD _IOR(SPI_IOC_MAGIC, 3, __u8)
+#define SPI_IOC_WR_BITS_PER_WORD _IOW(SPI_IOC_MAGIC, 3, __u8)
+
+/* Read / Write SPI device default max speed hz */
+#define SPI_IOC_RD_MAX_SPEED_HZ _IOR(SPI_IOC_MAGIC, 4, __u32)
+#define SPI_IOC_WR_MAX_SPEED_HZ _IOW(SPI_IOC_MAGIC, 4, __u32)
+
+
+
+#endif /* SPIDEV_H */
diff --git a/include/linux/spinlock_types.h b/include/linux/spinlock_types.h
index dc5fb69..210549b 100644
--- a/include/linux/spinlock_types.h
+++ b/include/linux/spinlock_types.h
@@ -85,6 +85,12 @@
RW_DEP_MAP_INIT(lockname) }
#endif
+/*
+ * SPIN_LOCK_UNLOCKED and RW_LOCK_UNLOCKED defeat lockdep state tracking and
+ * are hence deprecated.
+ * Please use DEFINE_SPINLOCK()/DEFINE_RWLOCK() or
+ * __SPIN_LOCK_UNLOCKED()/__RW_LOCK_UNLOCKED() as appropriate.
+ */
#define SPIN_LOCK_UNLOCKED __SPIN_LOCK_UNLOCKED(old_style_spin_init)
#define RW_LOCK_UNLOCKED __RW_LOCK_UNLOCKED(old_style_rw_init)
diff --git a/include/linux/stacktrace.h b/include/linux/stacktrace.h
index 50e2b01..1d2b084 100644
--- a/include/linux/stacktrace.h
+++ b/include/linux/stacktrace.h
@@ -6,15 +6,13 @@
unsigned int nr_entries, max_entries;
unsigned long *entries;
int skip; /* input argument: How many entries to skip */
- int all_contexts; /* input argument: if true do than one stack */
};
-extern void save_stack_trace(struct stack_trace *trace,
- struct task_struct *task);
+extern void save_stack_trace(struct stack_trace *trace);
extern void print_stack_trace(struct stack_trace *trace, int spaces);
#else
-# define save_stack_trace(trace, task) do { } while (0)
+# define save_stack_trace(trace) do { } while (0)
# define print_stack_trace(trace) do { } while (0)
#endif
diff --git a/include/linux/stat.h b/include/linux/stat.h
index 679ef0d..611c398 100644
--- a/include/linux/stat.h
+++ b/include/linux/stat.h
@@ -53,6 +53,9 @@
#define S_IWUGO (S_IWUSR|S_IWGRP|S_IWOTH)
#define S_IXUGO (S_IXUSR|S_IXGRP|S_IXOTH)
+#define UTIME_NOW ((1l << 30) - 1l)
+#define UTIME_OMIT ((1l << 30) - 2l)
+
#include <linux/types.h>
#include <linux/time.h>
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index 96868be..9d2aa1a 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -1,7 +1,7 @@
#ifndef _LINUX_SWSUSP_H
#define _LINUX_SWSUSP_H
-#if defined(CONFIG_X86) || defined(CONFIG_FRV) || defined(CONFIG_PPC32)
+#if defined(CONFIG_X86) || defined(CONFIG_FRV) || defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
#include <asm/suspend.h>
#endif
#include <linux/swap.h>
diff --git a/include/linux/svga.h b/include/linux/svga.h
index eadb981..e1cc552 100644
--- a/include/linux/svga.h
+++ b/include/linux/svga.h
@@ -112,6 +112,7 @@
void svga_tilefill(struct fb_info *info, struct fb_tilerect *rect);
void svga_tileblit(struct fb_info *info, struct fb_tileblit *blit);
void svga_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor);
+int svga_get_tilemax(struct fb_info *info);
int svga_compute_pll(const struct svga_pll *pll, u32 f_wanted, u16 *m, u16 *n, u16 *r, int node);
int svga_check_timings(const struct svga_timing_regs *tm, struct fb_var_screeninfo *var, int node);
diff --git a/include/linux/sysdev.h b/include/linux/sysdev.h
index 389ccf8..e699ab2 100644
--- a/include/linux/sysdev.h
+++ b/include/linux/sysdev.h
@@ -22,6 +22,7 @@
#define _SYSDEV_H_
#include <linux/kobject.h>
+#include <linux/module.h>
#include <linux/pm.h>
diff --git a/include/linux/time.h b/include/linux/time.h
index 8ea8dea..dda9be6 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -109,7 +109,7 @@
extern int do_settimeofday(struct timespec *tv);
extern int do_sys_settimeofday(struct timespec *tv, struct timezone *tz);
#define do_posix_clock_monotonic_gettime(ts) ktime_get_ts(ts)
-extern long do_utimes(int dfd, char __user *filename, struct timeval *times);
+extern long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags);
struct itimerval;
extern int do_setitimer(int which, struct itimerval *value,
struct itimerval *ovalue);
@@ -119,6 +119,7 @@
extern struct timespec timespec_trunc(struct timespec t, unsigned gran);
extern int timekeeping_is_continuous(void);
+extern void update_wall_time(void);
/**
* timespec_to_ns - Convert timespec to nanoseconds
diff --git a/include/linux/timer.h b/include/linux/timer.h
index 719113b..e0c5c16 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -37,6 +37,7 @@
TIMER_INITIALIZER(_function, _expires, _data)
void fastcall init_timer(struct timer_list * timer);
+void fastcall init_timer_deferrable(struct timer_list *timer);
static inline void setup_timer(struct timer_list * timer,
void (*function)(unsigned long),
diff --git a/include/linux/tty.h b/include/linux/tty.h
index dee72b9..bb45760 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -313,6 +313,7 @@
extern void do_SAK(struct tty_struct *tty);
extern void __do_SAK(struct tty_struct *tty);
extern void disassociate_ctty(int priv);
+extern void no_tty(void);
extern void tty_flip_buffer_push(struct tty_struct *tty);
extern speed_t tty_get_baud_rate(struct tty_struct *tty);
extern speed_t tty_termios_baud_rate(struct ktermios *termios);
@@ -333,7 +334,6 @@
extern dev_t tty_devnum(struct tty_struct *tty);
extern void proc_clear_tty(struct task_struct *p);
-extern void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty);
extern struct tty_struct *get_current_tty(void);
extern struct mutex tty_mutex;
diff --git a/include/linux/uinput.h b/include/linux/uinput.h
index 1fd61ee..a6c1e8e 100644
--- a/include/linux/uinput.h
+++ b/include/linux/uinput.h
@@ -32,6 +32,8 @@
* - first public version
*/
+#include <linux/input.h>
+
#define UINPUT_VERSION 3
#ifdef __KERNEL__
diff --git a/include/linux/utsname.h b/include/linux/utsname.h
index e10267d..f8d3b32 100644
--- a/include/linux/utsname.h
+++ b/include/linux/utsname.h
@@ -49,9 +49,7 @@
}
#ifdef CONFIG_UTS_NS
-extern int unshare_utsname(unsigned long unshare_flags,
- struct uts_namespace **new_uts);
-extern int copy_utsname(int flags, struct task_struct *tsk);
+extern struct uts_namespace *copy_utsname(int flags, struct uts_namespace *ns);
extern void free_uts_ns(struct kref *kref);
static inline void put_uts_ns(struct uts_namespace *ns)
@@ -59,21 +57,12 @@
kref_put(&ns->kref, free_uts_ns);
}
#else
-static inline int unshare_utsname(unsigned long unshare_flags,
- struct uts_namespace **new_uts)
+static inline struct uts_namespace *copy_utsname(int flags,
+ struct uts_namespace *ns)
{
- if (unshare_flags & CLONE_NEWUTS)
- return -EINVAL;
-
- return 0;
+ return ns;
}
-static inline int copy_utsname(int flags, struct task_struct *tsk)
-{
- if (flags & CLONE_NEWUTS)
- return -EINVAL;
- return 0;
-}
static inline void put_uts_ns(struct uts_namespace *ns)
{
}
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index 924e502..4b7ee83 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -53,6 +53,7 @@
extern int remap_vmalloc_range(struct vm_area_struct *vma, void *addr,
unsigned long pgoff);
+void vmalloc_sync_all(void);
/*
* Lowlevel-APIs (not for driver use!)
diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h
index e0db669..d961635 100644
--- a/include/linux/vt_kern.h
+++ b/include/linux/vt_kern.h
@@ -9,6 +9,7 @@
#include <linux/vt.h>
#include <linux/kd.h>
#include <linux/tty.h>
+#include <linux/mutex.h>
#include <linux/console_struct.h>
#include <linux/mm.h>
@@ -82,7 +83,7 @@
#define CON_BUF_SIZE (CONFIG_BASE_SMALL ? 256 : PAGE_SIZE)
extern char con_buf[CON_BUF_SIZE];
-extern struct semaphore con_buf_sem;
+extern struct mutex con_buf_mtx;
extern char vt_dont_switch;
struct vt_spawn_console {
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index b8abfc7..f16ba1e 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -121,6 +121,12 @@
init_timer(&(_work)->timer); \
} while (0)
+#define INIT_DELAYED_WORK_DEFERRABLE(_work, _func) \
+ do { \
+ INIT_WORK(&(_work)->work, (_func)); \
+ init_timer_deferrable(&(_work)->timer); \
+ } while (0)
+
/**
* work_pending - Find out whether a work item is currently pending
* @work: The work item in question
diff --git a/include/math-emu/extended.h b/include/math-emu/extended.h
deleted file mode 100644
index 84770fc..0000000
--- a/include/math-emu/extended.h
+++ /dev/null
@@ -1,396 +0,0 @@
-/* Software floating-point emulation.
- Definitions for IEEE Extended Precision.
- Copyright (C) 1999 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Jakub Jelinek (jj@ultra.linux.cz).
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If
- not, write to the Free Software Foundation, Inc.,
- 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-
-#ifndef __MATH_EMU_EXTENDED_H__
-#define __MATH_EMU_EXTENDED_H__
-
-#if _FP_W_TYPE_SIZE < 32
-#error "Here's a nickel, kid. Go buy yourself a real computer."
-#endif
-
-#if _FP_W_TYPE_SIZE < 64
-#define _FP_FRACTBITS_E (4*_FP_W_TYPE_SIZE)
-#else
-#define _FP_FRACTBITS_E (2*_FP_W_TYPE_SIZE)
-#endif
-
-#define _FP_FRACBITS_E 64
-#define _FP_FRACXBITS_E (_FP_FRACTBITS_E - _FP_FRACBITS_E)
-#define _FP_WFRACBITS_E (_FP_WORKBITS + _FP_FRACBITS_E)
-#define _FP_WFRACXBITS_E (_FP_FRACTBITS_E - _FP_WFRACBITS_E)
-#define _FP_EXPBITS_E 15
-#define _FP_EXPBIAS_E 16383
-#define _FP_EXPMAX_E 32767
-
-#define _FP_QNANBIT_E \
- ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-2) % _FP_W_TYPE_SIZE)
-#define _FP_IMPLBIT_E \
- ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-1) % _FP_W_TYPE_SIZE)
-#define _FP_OVERFLOW_E \
- ((_FP_W_TYPE)1 << (_FP_WFRACBITS_E % _FP_W_TYPE_SIZE))
-
-#if _FP_W_TYPE_SIZE < 64
-
-union _FP_UNION_E
-{
- long double flt;
- struct
- {
-#if __BYTE_ORDER == __BIG_ENDIAN
- unsigned long pad1 : _FP_W_TYPE_SIZE;
- unsigned long pad2 : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E);
- unsigned long sign : 1;
- unsigned long exp : _FP_EXPBITS_E;
- unsigned long frac1 : _FP_W_TYPE_SIZE;
- unsigned long frac0 : _FP_W_TYPE_SIZE;
-#else
- unsigned long frac0 : _FP_W_TYPE_SIZE;
- unsigned long frac1 : _FP_W_TYPE_SIZE;
- unsigned exp : _FP_EXPBITS_E;
- unsigned sign : 1;
-#endif /* not bigendian */
- } bits __attribute__((packed));
-};
-
-
-#define FP_DECL_E(X) _FP_DECL(4,X)
-
-#define FP_UNPACK_RAW_E(X, val) \
- do { \
- union _FP_UNION_E _flo; _flo.flt = (val); \
- \
- X##_f[2] = 0; X##_f[3] = 0; \
- X##_f[0] = _flo.bits.frac0; \
- X##_f[1] = _flo.bits.frac1; \
- X##_e = _flo.bits.exp; \
- X##_s = _flo.bits.sign; \
- if (!X##_e && (X##_f[1] || X##_f[0]) \
- && !(X##_f[1] & _FP_IMPLBIT_E)) \
- { \
- X##_e++; \
- FP_SET_EXCEPTION(FP_EX_DENORM); \
- } \
- } while (0)
-
-#define FP_UNPACK_RAW_EP(X, val) \
- do { \
- union _FP_UNION_E *_flo = \
- (union _FP_UNION_E *)(val); \
- \
- X##_f[2] = 0; X##_f[3] = 0; \
- X##_f[0] = _flo->bits.frac0; \
- X##_f[1] = _flo->bits.frac1; \
- X##_e = _flo->bits.exp; \
- X##_s = _flo->bits.sign; \
- if (!X##_e && (X##_f[1] || X##_f[0]) \
- && !(X##_f[1] & _FP_IMPLBIT_E)) \
- { \
- X##_e++; \
- FP_SET_EXCEPTION(FP_EX_DENORM); \
- } \
- } while (0)
-
-#define FP_PACK_RAW_E(val, X) \
- do { \
- union _FP_UNION_E _flo; \
- \
- if (X##_e) X##_f[1] |= _FP_IMPLBIT_E; \
- else X##_f[1] &= ~(_FP_IMPLBIT_E); \
- _flo.bits.frac0 = X##_f[0]; \
- _flo.bits.frac1 = X##_f[1]; \
- _flo.bits.exp = X##_e; \
- _flo.bits.sign = X##_s; \
- \
- (val) = _flo.flt; \
- } while (0)
-
-#define FP_PACK_RAW_EP(val, X) \
- do { \
- if (!FP_INHIBIT_RESULTS) \
- { \
- union _FP_UNION_E *_flo = \
- (union _FP_UNION_E *)(val); \
- \
- if (X##_e) X##_f[1] |= _FP_IMPLBIT_E; \
- else X##_f[1] &= ~(_FP_IMPLBIT_E); \
- _flo->bits.frac0 = X##_f[0]; \
- _flo->bits.frac1 = X##_f[1]; \
- _flo->bits.exp = X##_e; \
- _flo->bits.sign = X##_s; \
- } \
- } while (0)
-
-#define FP_UNPACK_E(X,val) \
- do { \
- FP_UNPACK_RAW_E(X,val); \
- _FP_UNPACK_CANONICAL(E,4,X); \
- } while (0)
-
-#define FP_UNPACK_EP(X,val) \
- do { \
- FP_UNPACK_RAW_2_P(X,val); \
- _FP_UNPACK_CANONICAL(E,4,X); \
- } while (0)
-
-#define FP_PACK_E(val,X) \
- do { \
- _FP_PACK_CANONICAL(E,4,X); \
- FP_PACK_RAW_E(val,X); \
- } while (0)
-
-#define FP_PACK_EP(val,X) \
- do { \
- _FP_PACK_CANONICAL(E,4,X); \
- FP_PACK_RAW_EP(val,X); \
- } while (0)
-
-#define FP_ISSIGNAN_E(X) _FP_ISSIGNAN(E,4,X)
-#define FP_NEG_E(R,X) _FP_NEG(E,4,R,X)
-#define FP_ADD_E(R,X,Y) _FP_ADD(E,4,R,X,Y)
-#define FP_SUB_E(R,X,Y) _FP_SUB(E,4,R,X,Y)
-#define FP_MUL_E(R,X,Y) _FP_MUL(E,4,R,X,Y)
-#define FP_DIV_E(R,X,Y) _FP_DIV(E,4,R,X,Y)
-#define FP_SQRT_E(R,X) _FP_SQRT(E,4,R,X)
-
-/*
- * Square root algorithms:
- * We have just one right now, maybe Newton approximation
- * should be added for those machines where division is fast.
- * This has special _E version because standard _4 square
- * root would not work (it has to start normally with the
- * second word and not the first), but as we have to do it
- * anyway, we optimize it by doing most of the calculations
- * in two UWtype registers instead of four.
- */
-
-#define _FP_SQRT_MEAT_E(R, S, T, X, q) \
- do { \
- q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \
- _FP_FRAC_SRL_4(X, (_FP_WORKBITS)); \
- while (q) \
- { \
- T##_f[1] = S##_f[1] + q; \
- if (T##_f[1] <= X##_f[1]) \
- { \
- S##_f[1] = T##_f[1] + q; \
- X##_f[1] -= T##_f[1]; \
- R##_f[1] += q; \
- } \
- _FP_FRAC_SLL_2(X, 1); \
- q >>= 1; \
- } \
- q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \
- while (q) \
- { \
- T##_f[0] = S##_f[0] + q; \
- T##_f[1] = S##_f[1]; \
- if (T##_f[1] < X##_f[1] || \
- (T##_f[1] == X##_f[1] && \
- T##_f[0] <= X##_f[0])) \
- { \
- S##_f[0] = T##_f[0] + q; \
- S##_f[1] += (T##_f[0] > S##_f[0]); \
- _FP_FRAC_DEC_2(X, T); \
- R##_f[0] += q; \
- } \
- _FP_FRAC_SLL_2(X, 1); \
- q >>= 1; \
- } \
- _FP_FRAC_SLL_4(R, (_FP_WORKBITS)); \
- if (X##_f[0] | X##_f[1]) \
- { \
- if (S##_f[1] < X##_f[1] || \
- (S##_f[1] == X##_f[1] && \
- S##_f[0] < X##_f[0])) \
- R##_f[0] |= _FP_WORK_ROUND; \
- R##_f[0] |= _FP_WORK_STICKY; \
- } \
- } while (0)
-
-#define FP_CMP_E(r,X,Y,un) _FP_CMP(E,4,r,X,Y,un)
-#define FP_CMP_EQ_E(r,X,Y) _FP_CMP_EQ(E,4,r,X,Y)
-
-#define FP_TO_INT_E(r,X,rsz,rsg) _FP_TO_INT(E,4,r,X,rsz,rsg)
-#define FP_TO_INT_ROUND_E(r,X,rsz,rsg) _FP_TO_INT_ROUND(E,4,r,X,rsz,rsg)
-#define FP_FROM_INT_E(X,r,rs,rt) _FP_FROM_INT(E,4,X,r,rs,rt)
-
-#define _FP_FRAC_HIGH_E(X) (X##_f[2])
-#define _FP_FRAC_HIGH_RAW_E(X) (X##_f[1])
-
-#else /* not _FP_W_TYPE_SIZE < 64 */
-union _FP_UNION_E
-{
- long double flt /* __attribute__((mode(TF))) */ ;
- struct {
-#if __BYTE_ORDER == __BIG_ENDIAN
- unsigned long pad : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E);
- unsigned sign : 1;
- unsigned exp : _FP_EXPBITS_E;
- unsigned long frac : _FP_W_TYPE_SIZE;
-#else
- unsigned long frac : _FP_W_TYPE_SIZE;
- unsigned exp : _FP_EXPBITS_E;
- unsigned sign : 1;
-#endif
- } bits;
-};
-
-#define FP_DECL_E(X) _FP_DECL(2,X)
-
-#define FP_UNPACK_RAW_E(X, val) \
- do { \
- union _FP_UNION_E _flo; _flo.flt = (val); \
- \
- X##_f0 = _flo.bits.frac; \
- X##_f1 = 0; \
- X##_e = _flo.bits.exp; \
- X##_s = _flo.bits.sign; \
- if (!X##_e && X##_f0 && !(X##_f0 & _FP_IMPLBIT_E)) \
- { \
- X##_e++; \
- FP_SET_EXCEPTION(FP_EX_DENORM); \
- } \
- } while (0)
-
-#define FP_UNPACK_RAW_EP(X, val) \
- do { \
- union _FP_UNION_E *_flo = \
- (union _FP_UNION_E *)(val); \
- \
- X##_f0 = _flo->bits.frac; \
- X##_f1 = 0; \
- X##_e = _flo->bits.exp; \
- X##_s = _flo->bits.sign; \
- if (!X##_e && X##_f0 && !(X##_f0 & _FP_IMPLBIT_E)) \
- { \
- X##_e++; \
- FP_SET_EXCEPTION(FP_EX_DENORM); \
- } \
- } while (0)
-
-#define FP_PACK_RAW_E(val, X) \
- do { \
- union _FP_UNION_E _flo; \
- \
- if (X##_e) X##_f0 |= _FP_IMPLBIT_E; \
- else X##_f0 &= ~(_FP_IMPLBIT_E); \
- _flo.bits.frac = X##_f0; \
- _flo.bits.exp = X##_e; \
- _flo.bits.sign = X##_s; \
- \
- (val) = _flo.flt; \
- } while (0)
-
-#define FP_PACK_RAW_EP(fs, val, X) \
- do { \
- if (!FP_INHIBIT_RESULTS) \
- { \
- union _FP_UNION_E *_flo = \
- (union _FP_UNION_E *)(val); \
- \
- if (X##_e) X##_f0 |= _FP_IMPLBIT_E; \
- else X##_f0 &= ~(_FP_IMPLBIT_E); \
- _flo->bits.frac = X##_f0; \
- _flo->bits.exp = X##_e; \
- _flo->bits.sign = X##_s; \
- } \
- } while (0)
-
-
-#define FP_UNPACK_E(X,val) \
- do { \
- FP_UNPACK_RAW_E(X,val); \
- _FP_UNPACK_CANONICAL(E,2,X); \
- } while (0)
-
-#define FP_UNPACK_EP(X,val) \
- do { \
- FP_UNPACK_RAW_EP(X,val); \
- _FP_UNPACK_CANONICAL(E,2,X); \
- } while (0)
-
-#define FP_PACK_E(val,X) \
- do { \
- _FP_PACK_CANONICAL(E,2,X); \
- FP_PACK_RAW_E(val,X); \
- } while (0)
-
-#define FP_PACK_EP(val,X) \
- do { \
- _FP_PACK_CANONICAL(E,2,X); \
- FP_PACK_RAW_EP(val,X); \
- } while (0)
-
-#define FP_ISSIGNAN_E(X) _FP_ISSIGNAN(E,2,X)
-#define FP_NEG_E(R,X) _FP_NEG(E,2,R,X)
-#define FP_ADD_E(R,X,Y) _FP_ADD(E,2,R,X,Y)
-#define FP_SUB_E(R,X,Y) _FP_SUB(E,2,R,X,Y)
-#define FP_MUL_E(R,X,Y) _FP_MUL(E,2,R,X,Y)
-#define FP_DIV_E(R,X,Y) _FP_DIV(E,2,R,X,Y)
-#define FP_SQRT_E(R,X) _FP_SQRT(E,2,R,X)
-
-/*
- * Square root algorithms:
- * We have just one right now, maybe Newton approximation
- * should be added for those machines where division is fast.
- * We optimize it by doing most of the calculations
- * in one UWtype registers instead of two, although we don't
- * have to.
- */
-#define _FP_SQRT_MEAT_E(R, S, T, X, q) \
- do { \
- q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \
- _FP_FRAC_SRL_2(X, (_FP_WORKBITS)); \
- while (q) \
- { \
- T##_f0 = S##_f0 + q; \
- if (T##_f0 <= X##_f0) \
- { \
- S##_f0 = T##_f0 + q; \
- X##_f0 -= T##_f0; \
- R##_f0 += q; \
- } \
- _FP_FRAC_SLL_1(X, 1); \
- q >>= 1; \
- } \
- _FP_FRAC_SLL_2(R, (_FP_WORKBITS)); \
- if (X##_f0) \
- { \
- if (S##_f0 < X##_f0) \
- R##_f0 |= _FP_WORK_ROUND; \
- R##_f0 |= _FP_WORK_STICKY; \
- } \
- } while (0)
-
-#define FP_CMP_E(r,X,Y,un) _FP_CMP(E,2,r,X,Y,un)
-#define FP_CMP_EQ_E(r,X,Y) _FP_CMP_EQ(E,2,r,X,Y)
-
-#define FP_TO_INT_E(r,X,rsz,rsg) _FP_TO_INT(E,2,r,X,rsz,rsg)
-#define FP_TO_INT_ROUND_E(r,X,rsz,rsg) _FP_TO_INT_ROUND(E,2,r,X,rsz,rsg)
-#define FP_FROM_INT_E(X,r,rs,rt) _FP_FROM_INT(E,2,X,r,rs,rt)
-
-#define _FP_FRAC_HIGH_E(X) (X##_f1)
-#define _FP_FRAC_HIGH_RAW_E(X) (X##_f0)
-
-#endif /* not _FP_W_TYPE_SIZE < 64 */
-
-#endif /* __MATH_EMU_EXTENDED_H__ */
diff --git a/include/net/sock.h b/include/net/sock.h
index 25c37e3..689b886 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1361,15 +1361,6 @@
extern __u32 sysctl_wmem_max;
extern __u32 sysctl_rmem_max;
-#ifdef CONFIG_NET
-int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
-#else
-static inline int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- return -ENODEV;
-}
-#endif
-
extern void sk_init(void);
#ifdef CONFIG_SYSCTL
diff --git a/include/video/mach64.h b/include/video/mach64.h
index 09a7f4a..a8332e5 100644
--- a/include/video/mach64.h
+++ b/include/video/mach64.h
@@ -885,6 +885,7 @@
#define SDRAM 4
#define SGRAM 5
#define WRAM 6
+#define SDRAM32 6
#define DAC_INTERNAL 0x00
#define DAC_IBMRGB514 0x01
diff --git a/include/video/permedia2.h b/include/video/permedia2.h
index b95d362..9e49c95 100644
--- a/include/video/permedia2.h
+++ b/include/video/permedia2.h
@@ -154,6 +154,10 @@
#define PM2VI_RD_CLK1_PRESCALE 0x204
#define PM2VI_RD_CLK1_FEEDBACK 0x205
#define PM2VI_RD_CLK1_POSTSCALE 0x206
+#define PM2VI_RD_MCLK_CONTROL 0x20D
+#define PM2VI_RD_MCLK_PRESCALE 0x20E
+#define PM2VI_RD_MCLK_FEEDBACK 0x20F
+#define PM2VI_RD_MCLK_POSTSCALE 0x210
#define PM2VI_RD_CURSOR_PALETTE 0x303
#define PM2VI_RD_CURSOR_PATTERN 0x400
diff --git a/include/video/tgafb.h b/include/video/tgafb.h
index be2b3e9..03d0dbe 100644
--- a/include/video/tgafb.h
+++ b/include/video/tgafb.h
@@ -39,6 +39,7 @@
#define TGA_RASTEROP_REG 0x0034
#define TGA_PIXELSHIFT_REG 0x0038
#define TGA_DEEP_REG 0x0050
+#define TGA_START_REG 0x0054
#define TGA_PIXELMASK_REG 0x005c
#define TGA_CURSOR_BASE_REG 0x0060
#define TGA_HORIZ_REG 0x0064
@@ -140,7 +141,7 @@
/*
- * Useful defines for managing the BT463 on the 24-plane TGAs
+ * Useful defines for managing the BT463 on the 24-plane TGAs/SFB+s
*/
#define BT463_ADDR_LO 0x0
@@ -168,12 +169,35 @@
#define BT463_WINDOW_TYPE_BASE 0x0300
/*
+ * Useful defines for managing the BT459 on the 8-plane SFB+s
+ */
+
+#define BT459_ADDR_LO 0x0
+#define BT459_ADDR_HI 0x1
+#define BT459_REG_ACC 0x2
+#define BT459_PALETTE 0x3
+
+#define BT459_CUR_CLR_1 0x0181
+#define BT459_CUR_CLR_2 0x0182
+#define BT459_CUR_CLR_3 0x0183
+
+#define BT459_CMD_REG_0 0x0201
+#define BT459_CMD_REG_1 0x0202
+#define BT459_CMD_REG_2 0x0203
+
+#define BT459_READ_MASK 0x0204
+
+#define BT459_BLINK_MASK 0x0206
+
+#define BT459_CUR_CMD_REG 0x0300
+
+/*
* The framebuffer driver private data.
*/
struct tga_par {
- /* PCI device. */
- struct pci_dev *pdev;
+ /* PCI/TC device. */
+ struct device *dev;
/* Device dependent information. */
void __iomem *tga_mem_base;
@@ -235,4 +259,21 @@
TGA_WRITE_REG(par, m << 10 | v, TGA_RAMDAC_REG);
}
+static inline void
+BT459_LOAD_ADDR(struct tga_par *par, u16 a)
+{
+ TGA_WRITE_REG(par, BT459_ADDR_LO << 2, TGA_RAMDAC_SETUP_REG);
+ TGA_WRITE_REG(par, a & 0xff, TGA_RAMDAC_REG);
+ TGA_WRITE_REG(par, BT459_ADDR_HI << 2, TGA_RAMDAC_SETUP_REG);
+ TGA_WRITE_REG(par, a >> 8, TGA_RAMDAC_REG);
+}
+
+static inline void
+BT459_WRITE(struct tga_par *par, u32 m, u16 a, u8 v)
+{
+ BT459_LOAD_ADDR(par, a);
+ TGA_WRITE_REG(par, m << 2, TGA_RAMDAC_SETUP_REG);
+ TGA_WRITE_REG(par, v, TGA_RAMDAC_REG);
+}
+
#endif /* TGAFB_H */
diff --git a/init/Kconfig b/init/Kconfig
index ebe04f5..d0edf42 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -266,6 +266,23 @@
This option enables access to the kernel configuration file
through /proc/config.gz.
+config LOG_BUF_SHIFT
+ int "Kernel log buffer size (16 => 64KB, 17 => 128KB)"
+ range 12 21
+ default 17 if S390 || LOCKDEP
+ default 16 if X86_NUMAQ || IA64
+ default 15 if SMP
+ default 14
+ help
+ Select kernel log buffer size as a power of 2.
+ Defaults and Examples:
+ 17 => 128 KB for S/390
+ 16 => 64 KB for x86 NUMAQ or IA-64
+ 15 => 32 KB for SMP
+ 14 => 16 KB for uniprocessor
+ 13 => 8 KB
+ 12 => 4 KB
+
config CPUSETS
bool "Cpuset support"
depends on SMP
diff --git a/init/do_mounts.c b/init/do_mounts.c
index dc1ec08..3f57ed4 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -9,6 +9,7 @@
#include <linux/delay.h>
#include <linux/mount.h>
#include <linux/device.h>
+#include <linux/init.h>
#include <linux/nfs_fs.h>
#include <linux/nfs_fs_sb.h>
diff --git a/init/main.c b/init/main.c
index 0e22f40..c1537e0 100644
--- a/init/main.c
+++ b/init/main.c
@@ -94,7 +94,6 @@
extern void prio_tree_init(void);
extern void radix_tree_init(void);
extern void free_initmem(void);
-extern void prepare_namespace(void);
#ifdef CONFIG_ACPI
extern void acpi_early_init(void);
#else
@@ -649,6 +648,7 @@
int count = preempt_count();
for (call = __initcall_start; call < __initcall_end; call++) {
+ ktime_t t0, t1, delta;
char *msg = NULL;
char msgbuf[40];
int result;
@@ -658,10 +658,26 @@
print_fn_descriptor_symbol(": %s()",
(unsigned long) *call);
printk("\n");
+ t0 = ktime_get();
}
result = (*call)();
+ if (initcall_debug) {
+ t1 = ktime_get();
+ delta = ktime_sub(t1, t0);
+
+ printk("initcall 0x%p", *call);
+ print_fn_descriptor_symbol(": %s()",
+ (unsigned long) *call);
+ printk(" returned %d.\n", result);
+
+ printk("initcall 0x%p ran for %Ld msecs: ",
+ *call, (unsigned long long)delta.tv64 >> 20);
+ print_fn_descriptor_symbol("%s()\n",
+ (unsigned long) *call);
+ }
+
if (result && result != -ENODEV && initcall_debug) {
sprintf(msgbuf, "error code %d", result);
msg = msgbuf;
diff --git a/ipc/compat.c b/ipc/compat.c
index fa18141..8b44aa9 100644
--- a/ipc/compat.c
+++ b/ipc/compat.c
@@ -542,6 +542,8 @@
if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64)))
return -EFAULT;
+ if (smi->shmmax > INT_MAX)
+ smi->shmmax = INT_MAX;
err = __put_user(smi->shmmax, &up64->shmmax);
err |= __put_user(smi->shmmin, &up64->shmmin);
err |= __put_user(smi->shmmni, &up64->shmmni);
@@ -557,6 +559,8 @@
if (!access_ok(VERIFY_WRITE, up, sizeof(*up)))
return -EFAULT;
+ if (smi->shmmax > INT_MAX)
+ smi->shmmax = INT_MAX;
err = __put_user(smi->shmmax, &up->shmmax);
err |= __put_user(smi->shmmin, &up->shmmin);
err |= __put_user(smi->shmmni, &up->shmmni);
diff --git a/ipc/sem.c b/ipc/sem.c
index d3e12ef..9964b22 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -75,7 +75,6 @@
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/time.h>
-#include <linux/smp_lock.h>
#include <linux/security.h>
#include <linux/syscalls.h>
#include <linux/audit.h>
diff --git a/ipc/util.c b/ipc/util.c
index 0b65238..7536a72 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -21,7 +21,6 @@
#include <linux/shm.h>
#include <linux/init.h>
#include <linux/msg.h>
-#include <linux/smp_lock.h>
#include <linux/vmalloc.h>
#include <linux/slab.h>
#include <linux/capability.h>
@@ -85,53 +84,20 @@
return ERR_PTR(err);
}
-int unshare_ipcs(unsigned long unshare_flags, struct ipc_namespace **new_ipc)
+struct ipc_namespace *copy_ipcs(unsigned long flags, struct ipc_namespace *ns)
{
- struct ipc_namespace *new;
-
- if (unshare_flags & CLONE_NEWIPC) {
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- new = clone_ipc_ns(current->nsproxy->ipc_ns);
- if (IS_ERR(new))
- return PTR_ERR(new);
-
- *new_ipc = new;
- }
-
- return 0;
-}
-
-int copy_ipcs(unsigned long flags, struct task_struct *tsk)
-{
- struct ipc_namespace *old_ns = tsk->nsproxy->ipc_ns;
struct ipc_namespace *new_ns;
- int err = 0;
- if (!old_ns)
- return 0;
-
- get_ipc_ns(old_ns);
+ BUG_ON(!ns);
+ get_ipc_ns(ns);
if (!(flags & CLONE_NEWIPC))
- return 0;
+ return ns;
- if (!capable(CAP_SYS_ADMIN)) {
- err = -EPERM;
- goto out;
- }
+ new_ns = clone_ipc_ns(ns);
- new_ns = clone_ipc_ns(old_ns);
- if (!new_ns) {
- err = -ENOMEM;
- goto out;
- }
-
- tsk->nsproxy->ipc_ns = new_ns;
-out:
- put_ipc_ns(old_ns);
- return err;
+ put_ipc_ns(ns);
+ return new_ns;
}
void free_ipc_ns(struct kref *kref)
@@ -145,11 +111,11 @@
kfree(ns);
}
#else
-int copy_ipcs(unsigned long flags, struct task_struct *tsk)
+struct ipc_namespace *copy_ipcs(unsigned long flags, struct ipc_namespace *ns)
{
if (flags & CLONE_NEWIPC)
- return -EINVAL;
- return 0;
+ return ERR_PTR(-EINVAL);
+ return ns;
}
#endif
diff --git a/kernel/Makefile b/kernel/Makefile
index ac6b27a..642d427 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -8,7 +8,7 @@
signal.o sys.o kmod.o workqueue.o pid.o \
rcupdate.o extable.o params.o posix-timers.o \
kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
- hrtimer.o rwsem.o latency.o nsproxy.o srcu.o
+ hrtimer.o rwsem.o latency.o nsproxy.o srcu.o die_notifier.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-y += time/
diff --git a/kernel/audit.c b/kernel/audit.c
index 4e9d208..d13276d 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -515,8 +515,8 @@
err = -EPERM;
break;
case AUDIT_USER:
- case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG:
- case AUDIT_FIRST_USER_MSG2...AUDIT_LAST_USER_MSG2:
+ case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG:
+ case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2:
if (security_netlink_recv(skb, CAP_AUDIT_WRITE))
err = -EPERM;
break;
@@ -614,8 +614,8 @@
loginuid, sid);
break;
case AUDIT_USER:
- case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG:
- case AUDIT_FIRST_USER_MSG2...AUDIT_LAST_USER_MSG2:
+ case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG:
+ case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2:
if (!audit_enabled && msg_type != AUDIT_USER_AVC)
return 0;
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index d240349..88b416d 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -42,7 +42,6 @@
#include <linux/seq_file.h>
#include <linux/security.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/stat.h>
#include <linux/string.h>
@@ -822,11 +821,22 @@
return -EACCES;
trialcs = *cs;
- retval = cpulist_parse(buf, trialcs.cpus_allowed);
- if (retval < 0)
- return retval;
+
+ /*
+ * We allow a cpuset's cpus_allowed to be empty; if it has attached
+ * tasks, we'll catch it later when we validate the change and return
+ * -ENOSPC.
+ */
+ if (!buf[0] || (buf[0] == '\n' && !buf[1])) {
+ cpus_clear(trialcs.cpus_allowed);
+ } else {
+ retval = cpulist_parse(buf, trialcs.cpus_allowed);
+ if (retval < 0)
+ return retval;
+ }
cpus_and(trialcs.cpus_allowed, trialcs.cpus_allowed, cpu_online_map);
- if (cpus_empty(trialcs.cpus_allowed))
+ /* cpus_allowed cannot be empty for a cpuset with attached tasks. */
+ if (atomic_read(&cs->count) && cpus_empty(trialcs.cpus_allowed))
return -ENOSPC;
retval = validate_change(cs, &trialcs);
if (retval < 0)
@@ -919,16 +929,27 @@
return -EACCES;
trialcs = *cs;
- retval = nodelist_parse(buf, trialcs.mems_allowed);
- if (retval < 0)
- goto done;
+
+ /*
+ * We allow a cpuset's mems_allowed to be empty; if it has attached
+ * tasks, we'll catch it later when we validate the change and return
+ * -ENOSPC.
+ */
+ if (!buf[0] || (buf[0] == '\n' && !buf[1])) {
+ nodes_clear(trialcs.mems_allowed);
+ } else {
+ retval = nodelist_parse(buf, trialcs.mems_allowed);
+ if (retval < 0)
+ goto done;
+ }
nodes_and(trialcs.mems_allowed, trialcs.mems_allowed, node_online_map);
oldmem = cs->mems_allowed;
if (nodes_equal(oldmem, trialcs.mems_allowed)) {
retval = 0; /* Too easy - nothing to do */
goto done;
}
- if (nodes_empty(trialcs.mems_allowed)) {
+ /* mems_allowed cannot be empty for a cpuset with attached tasks. */
+ if (atomic_read(&cs->count) && nodes_empty(trialcs.mems_allowed)) {
retval = -ENOSPC;
goto done;
}
@@ -2200,10 +2221,6 @@
* it is holding that mutex while calling check_for_release(),
* which calls kmalloc(), so can't be called holding callback_mutex().
*
- * We don't need to task_lock() this reference to tsk->cpuset,
- * because tsk is already marked PF_EXITING, so attach_task() won't
- * mess with it, or task is a failed fork, never visible to attach_task.
- *
* the_top_cpuset_hack:
*
* Set the exiting tasks cpuset to the root cpuset (top_cpuset).
@@ -2242,8 +2259,10 @@
{
struct cpuset *cs;
+ task_lock(current);
cs = tsk->cpuset;
tsk->cpuset = &top_cpuset; /* the_top_cpuset_hack - see above */
+ task_unlock(current);
if (notify_on_release(cs)) {
char *pathbuf = NULL;
diff --git a/kernel/die_notifier.c b/kernel/die_notifier.c
new file mode 100644
index 0000000..0d98827
--- /dev/null
+++ b/kernel/die_notifier.c
@@ -0,0 +1,38 @@
+
+#include <linux/module.h>
+#include <linux/notifier.h>
+#include <linux/vmalloc.h>
+#include <linux/kdebug.h>
+
+
+static ATOMIC_NOTIFIER_HEAD(die_chain);
+
+int notify_die(enum die_val val, const char *str,
+ struct pt_regs *regs, long err, int trap, int sig)
+{
+ struct die_args args = {
+ .regs = regs,
+ .str = str,
+ .err = err,
+ .trapnr = trap,
+ .signr = sig,
+
+ };
+
+ return atomic_notifier_call_chain(&die_chain, val, &args);
+}
+
+int register_die_notifier(struct notifier_block *nb)
+{
+ vmalloc_sync_all();
+ return atomic_notifier_chain_register(&die_chain, nb);
+}
+EXPORT_SYMBOL_GPL(register_die_notifier);
+
+int unregister_die_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_unregister(&die_chain, nb);
+}
+EXPORT_SYMBOL_GPL(unregister_die_notifier);
+
+
diff --git a/kernel/exit.c b/kernel/exit.c
index 9236924..f5a7abb 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -7,7 +7,6 @@
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
#include <linux/module.h>
#include <linux/capability.h>
#include <linux/completion.h>
diff --git a/kernel/fork.c b/kernel/fork.c
index b7d169d..a8dd75d 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -14,7 +14,6 @@
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/unistd.h>
-#include <linux/smp_lock.h>
#include <linux/module.h>
#include <linux/vmalloc.h>
#include <linux/completion.h>
@@ -1516,26 +1515,6 @@
}
/*
- * Unshare the mnt_namespace structure if it is being shared
- */
-static int unshare_mnt_namespace(unsigned long unshare_flags,
- struct mnt_namespace **new_nsp, struct fs_struct *new_fs)
-{
- struct mnt_namespace *ns = current->nsproxy->mnt_ns;
-
- if ((unshare_flags & CLONE_NEWNS) && ns) {
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- *new_nsp = dup_mnt_ns(current, new_fs ? new_fs : current->fs);
- if (!*new_nsp)
- return -ENOMEM;
- }
-
- return 0;
-}
-
-/*
* Unsharing of sighand is not supported yet
*/
static int unshare_sighand(unsigned long unshare_flags, struct sighand_struct **new_sighp)
@@ -1593,16 +1572,6 @@
return 0;
}
-#ifndef CONFIG_IPC_NS
-static inline int unshare_ipcs(unsigned long flags, struct ipc_namespace **ns)
-{
- if (flags & CLONE_NEWIPC)
- return -EINVAL;
-
- return 0;
-}
-#endif
-
/*
* unshare allows a process to 'unshare' part of the process
* context which was originally shared using clone. copy_*
@@ -1615,14 +1584,11 @@
{
int err = 0;
struct fs_struct *fs, *new_fs = NULL;
- struct mnt_namespace *ns, *new_ns = NULL;
struct sighand_struct *new_sigh = NULL;
struct mm_struct *mm, *new_mm = NULL, *active_mm = NULL;
struct files_struct *fd, *new_fd = NULL;
struct sem_undo_list *new_ulist = NULL;
struct nsproxy *new_nsproxy = NULL, *old_nsproxy = NULL;
- struct uts_namespace *uts, *new_uts = NULL;
- struct ipc_namespace *ipc, *new_ipc = NULL;
check_unshare_flags(&unshare_flags);
@@ -1637,36 +1603,24 @@
goto bad_unshare_out;
if ((err = unshare_fs(unshare_flags, &new_fs)))
goto bad_unshare_cleanup_thread;
- if ((err = unshare_mnt_namespace(unshare_flags, &new_ns, new_fs)))
- goto bad_unshare_cleanup_fs;
if ((err = unshare_sighand(unshare_flags, &new_sigh)))
- goto bad_unshare_cleanup_ns;
+ goto bad_unshare_cleanup_fs;
if ((err = unshare_vm(unshare_flags, &new_mm)))
goto bad_unshare_cleanup_sigh;
if ((err = unshare_fd(unshare_flags, &new_fd)))
goto bad_unshare_cleanup_vm;
if ((err = unshare_semundo(unshare_flags, &new_ulist)))
goto bad_unshare_cleanup_fd;
- if ((err = unshare_utsname(unshare_flags, &new_uts)))
+ if ((err = unshare_nsproxy_namespaces(unshare_flags, &new_nsproxy,
+ new_fs)))
goto bad_unshare_cleanup_semundo;
- if ((err = unshare_ipcs(unshare_flags, &new_ipc)))
- goto bad_unshare_cleanup_uts;
- if (new_ns || new_uts || new_ipc) {
- old_nsproxy = current->nsproxy;
- new_nsproxy = dup_namespaces(old_nsproxy);
- if (!new_nsproxy) {
- err = -ENOMEM;
- goto bad_unshare_cleanup_ipc;
- }
- }
-
- if (new_fs || new_ns || new_mm || new_fd || new_ulist ||
- new_uts || new_ipc) {
+ if (new_fs || new_mm || new_fd || new_ulist || new_nsproxy) {
task_lock(current);
if (new_nsproxy) {
+ old_nsproxy = current->nsproxy;
current->nsproxy = new_nsproxy;
new_nsproxy = old_nsproxy;
}
@@ -1677,12 +1631,6 @@
new_fs = fs;
}
- if (new_ns) {
- ns = current->nsproxy->mnt_ns;
- current->nsproxy->mnt_ns = new_ns;
- new_ns = ns;
- }
-
if (new_mm) {
mm = current->mm;
active_mm = current->active_mm;
@@ -1698,32 +1646,12 @@
new_fd = fd;
}
- if (new_uts) {
- uts = current->nsproxy->uts_ns;
- current->nsproxy->uts_ns = new_uts;
- new_uts = uts;
- }
-
- if (new_ipc) {
- ipc = current->nsproxy->ipc_ns;
- current->nsproxy->ipc_ns = new_ipc;
- new_ipc = ipc;
- }
-
task_unlock(current);
}
if (new_nsproxy)
put_nsproxy(new_nsproxy);
-bad_unshare_cleanup_ipc:
- if (new_ipc)
- put_ipc_ns(new_ipc);
-
-bad_unshare_cleanup_uts:
- if (new_uts)
- put_uts_ns(new_uts);
-
bad_unshare_cleanup_semundo:
bad_unshare_cleanup_fd:
if (new_fd)
@@ -1738,10 +1666,6 @@
if (atomic_dec_and_test(&new_sigh->count))
kmem_cache_free(sighand_cachep, new_sigh);
-bad_unshare_cleanup_ns:
- if (new_ns)
- put_mnt_ns(new_ns);
-
bad_unshare_cleanup_fs:
if (new_fs)
put_fs_struct(new_fs);
diff --git a/kernel/futex.c b/kernel/futex.c
index 5a270b5..600bc9d 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -48,6 +48,7 @@
#include <linux/pagemap.h>
#include <linux/syscalls.h>
#include <linux/signal.h>
+#include <linux/module.h>
#include <asm/futex.h>
#include "rtmutex_common.h"
@@ -55,32 +56,6 @@
#define FUTEX_HASHBITS (CONFIG_BASE_SMALL ? 4 : 8)
/*
- * Futexes are matched on equal values of this key.
- * The key type depends on whether it's a shared or private mapping.
- * Don't rearrange members without looking at hash_futex().
- *
- * offset is aligned to a multiple of sizeof(u32) (== 4) by definition.
- * We set bit 0 to indicate if it's an inode-based key.
- */
-union futex_key {
- struct {
- unsigned long pgoff;
- struct inode *inode;
- int offset;
- } shared;
- struct {
- unsigned long address;
- struct mm_struct *mm;
- int offset;
- } private;
- struct {
- unsigned long word;
- void *ptr;
- int offset;
- } both;
-};
-
-/*
* Priority Inheritance state:
*/
struct futex_pi_state {
@@ -175,7 +150,7 @@
*
* Should be called with ¤t->mm->mmap_sem but NOT any spinlocks.
*/
-static int get_futex_key(u32 __user *uaddr, union futex_key *key)
+int get_futex_key(u32 __user *uaddr, union futex_key *key)
{
unsigned long address = (unsigned long)uaddr;
struct mm_struct *mm = current->mm;
@@ -246,6 +221,7 @@
}
return err;
}
+EXPORT_SYMBOL_GPL(get_futex_key);
/*
* Take a reference to the resource addressed by a key.
@@ -254,7 +230,7 @@
* NOTE: mmap_sem MUST be held between get_futex_key() and calling this
* function, if it is called at all. mmap_sem keeps key->shared.inode valid.
*/
-static inline void get_key_refs(union futex_key *key)
+inline void get_futex_key_refs(union futex_key *key)
{
if (key->both.ptr != 0) {
if (key->both.offset & 1)
@@ -263,12 +239,13 @@
atomic_inc(&key->private.mm->mm_count);
}
}
+EXPORT_SYMBOL_GPL(get_futex_key_refs);
/*
* Drop a reference to the resource addressed by a key.
* The hash bucket spinlock must not be held.
*/
-static void drop_key_refs(union futex_key *key)
+void drop_futex_key_refs(union futex_key *key)
{
if (key->both.ptr != 0) {
if (key->both.offset & 1)
@@ -277,6 +254,7 @@
mmdrop(key->private.mm);
}
}
+EXPORT_SYMBOL_GPL(drop_futex_key_refs);
static inline int get_futex_value_locked(u32 *dest, u32 __user *from)
{
@@ -873,7 +851,7 @@
this->lock_ptr = &hb2->lock;
}
this->key = key2;
- get_key_refs(&key2);
+ get_futex_key_refs(&key2);
drop_count++;
if (ret - nr_wake >= nr_requeue)
@@ -886,9 +864,9 @@
if (hb1 != hb2)
spin_unlock(&hb2->lock);
- /* drop_key_refs() must be called outside the spinlocks. */
+ /* drop_futex_key_refs() must be called outside the spinlocks. */
while (--drop_count >= 0)
- drop_key_refs(&key1);
+ drop_futex_key_refs(&key1);
out:
up_read(¤t->mm->mmap_sem);
@@ -906,7 +884,7 @@
init_waitqueue_head(&q->waiters);
- get_key_refs(&q->key);
+ get_futex_key_refs(&q->key);
hb = hash_futex(&q->key);
q->lock_ptr = &hb->lock;
@@ -925,7 +903,7 @@
queue_unlock(struct futex_q *q, struct futex_hash_bucket *hb)
{
spin_unlock(&hb->lock);
- drop_key_refs(&q->key);
+ drop_futex_key_refs(&q->key);
}
/*
@@ -980,7 +958,7 @@
ret = 1;
}
- drop_key_refs(&q->key);
+ drop_futex_key_refs(&q->key);
return ret;
}
@@ -999,15 +977,18 @@
spin_unlock(&hb->lock);
- drop_key_refs(&q->key);
+ drop_futex_key_refs(&q->key);
}
-static int futex_wait(u32 __user *uaddr, u32 val, unsigned long time)
+static long futex_wait_restart(struct restart_block *restart);
+static int futex_wait_abstime(u32 __user *uaddr, u32 val,
+ int timed, unsigned long abs_time)
{
struct task_struct *curr = current;
DECLARE_WAITQUEUE(wait, curr);
struct futex_hash_bucket *hb;
struct futex_q q;
+ unsigned long time_left = 0;
u32 uval;
int ret;
@@ -1087,8 +1068,21 @@
* !list_empty() is safe here without any lock.
* q.lock_ptr != 0 is not safe, because of ordering against wakeup.
*/
- if (likely(!list_empty(&q.list)))
- time = schedule_timeout(time);
+ time_left = 0;
+ if (likely(!list_empty(&q.list))) {
+ unsigned long rel_time;
+
+ if (timed) {
+ unsigned long now = jiffies;
+ if (time_after(now, abs_time))
+ rel_time = 0;
+ else
+ rel_time = abs_time - now;
+ } else
+ rel_time = MAX_SCHEDULE_TIMEOUT;
+
+ time_left = schedule_timeout(rel_time);
+ }
__set_current_state(TASK_RUNNING);
/*
@@ -1099,13 +1093,25 @@
/* If we were woken (and unqueued), we succeeded, whatever. */
if (!unqueue_me(&q))
return 0;
- if (time == 0)
+ if (time_left == 0)
return -ETIMEDOUT;
+
/*
* We expect signal_pending(current), but another thread may
* have handled it for us already.
*/
- return -EINTR;
+ if (time_left == MAX_SCHEDULE_TIMEOUT)
+ return -ERESTARTSYS;
+ else {
+ struct restart_block *restart;
+ restart = ¤t_thread_info()->restart_block;
+ restart->fn = futex_wait_restart;
+ restart->arg0 = (unsigned long)uaddr;
+ restart->arg1 = (unsigned long)val;
+ restart->arg2 = (unsigned long)timed;
+ restart->arg3 = abs_time;
+ return -ERESTART_RESTARTBLOCK;
+ }
out_unlock_release_sem:
queue_unlock(&q, hb);
@@ -1115,6 +1121,24 @@
return ret;
}
+static int futex_wait(u32 __user *uaddr, u32 val, unsigned long rel_time)
+{
+ int timed = (rel_time != MAX_SCHEDULE_TIMEOUT);
+ return futex_wait_abstime(uaddr, val, timed, jiffies+rel_time);
+}
+
+static long futex_wait_restart(struct restart_block *restart)
+{
+ u32 __user *uaddr = (u32 __user *)restart->arg0;
+ u32 val = (u32)restart->arg1;
+ int timed = (int)restart->arg2;
+ unsigned long abs_time = restart->arg3;
+
+ restart->fn = do_no_restart_syscall;
+ return (long)futex_wait_abstime(uaddr, val, timed, abs_time);
+}
+
+
/*
* Userspace tried a 0 -> TID atomic transition of the futex value
* and failed. The kernel side here does the whole locking operation:
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index 1b30331..c9f4f04 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -669,6 +669,7 @@
return orun;
}
+EXPORT_SYMBOL_GPL(hrtimer_forward);
/*
* enqueue_hrtimer - internal function to (re)start a timer
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index aff1f0f..32e1ab1 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -48,7 +48,7 @@
*
* Controller mappings for all interrupt sources:
*/
-struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned = {
+struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
[0 ... NR_IRQS-1] = {
.status = IRQ_DISABLED,
.chip = &no_irq_chip,
@@ -180,6 +180,8 @@
if (desc->chip->ack)
desc->chip->ack(irq);
action_ret = handle_IRQ_event(irq, desc->action);
+ if (!noirqdebug)
+ note_interrupt(irq, desc, action_ret);
desc->chip->end(irq);
return 1;
}
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 5597c15..203a518 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -317,10 +317,7 @@
}
*p = new;
-#if defined(CONFIG_IRQ_PER_CPU)
- if (new->flags & IRQF_PERCPU)
- desc->status |= IRQ_PER_CPU;
-#endif
+
/* Exclude IRQ from balancing */
if (new->flags & IRQF_NOBALANCING)
desc->status |= IRQ_NO_BALANCING;
@@ -328,6 +325,11 @@
if (!shared) {
irq_chip_set_defaults(desc->chip);
+#if defined(CONFIG_IRQ_PER_CPU)
+ if (new->flags & IRQF_PERCPU)
+ desc->status |= IRQ_PER_CPU;
+#endif
+
/* Setup the type (level, edge polarity) if configured: */
if (new->flags & IRQF_TRIGGER_MASK) {
if (desc->chip && desc->chip->set_type)
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index 2db91eb..ddde0ef 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -66,12 +66,19 @@
{
struct irq_desc *desc = irq_desc + irq;
struct irqaction *action;
+ unsigned long flags;
+ int ret = 1;
- for (action = desc->action ; action; action = action->next)
+ spin_lock_irqsave(&desc->lock, flags);
+ for (action = desc->action ; action; action = action->next) {
if ((action != new_action) && action->name &&
- !strcmp(new_action->name, action->name))
- return 0;
- return 1;
+ !strcmp(new_action->name, action->name)) {
+ ret = 0;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&desc->lock, flags);
+ return ret;
}
void register_handler_proc(unsigned int irq, struct irqaction *action)
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
index 9d8c79b..b0d81aa 100644
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -146,7 +146,9 @@
if (unlikely(irqfixup)) {
/* Don't punish working computers */
- if ((irqfixup == 2 && irq == 0) || action_ret == IRQ_NONE) {
+ if ((irqfixup == 2 && ((irq == 0) ||
+ (desc->action->flags & IRQF_IRQPOLL))) ||
+ action_ret == IRQ_NONE) {
int ok = misrouted_irq(irq);
if (action_ret == IRQ_NONE)
desc->irqs_unhandled -= ok;
diff --git a/kernel/itimer.c b/kernel/itimer.c
index 307c6a6..3205e8e 100644
--- a/kernel/itimer.c
+++ b/kernel/itimer.c
@@ -7,7 +7,6 @@
/* These are all the functions necessary to implement itimers */
#include <linux/mm.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/syscalls.h>
#include <linux/time.h>
@@ -139,59 +138,11 @@
}
/*
- * We do not care about correctness. We just sanitize the values so
- * the ktime_t operations which expect normalized values do not
- * break. This converts negative values to long timeouts similar to
- * the code in kernel versions < 2.6.16
- *
- * Print a limited number of warning messages when an invalid timeval
- * is detected.
- */
-static void fixup_timeval(struct timeval *tv, int interval)
-{
- static int warnlimit = 10;
- unsigned long tmp;
-
- if (warnlimit > 0) {
- warnlimit--;
- printk(KERN_WARNING
- "setitimer: %s (pid = %d) provided "
- "invalid timeval %s: tv_sec = %ld tv_usec = %ld\n",
- current->comm, current->pid,
- interval ? "it_interval" : "it_value",
- tv->tv_sec, (long) tv->tv_usec);
- }
-
- tmp = tv->tv_usec;
- if (tmp >= USEC_PER_SEC) {
- tv->tv_usec = tmp % USEC_PER_SEC;
- tv->tv_sec += tmp / USEC_PER_SEC;
- }
-
- tmp = tv->tv_sec;
- if (tmp > LONG_MAX)
- tv->tv_sec = LONG_MAX;
-}
-
-/*
* Returns true if the timeval is in canonical form
*/
#define timeval_valid(t) \
(((t)->tv_sec >= 0) && (((unsigned long) (t)->tv_usec) < USEC_PER_SEC))
-/*
- * Check for invalid timevals, sanitize them and print a limited
- * number of warnings.
- */
-static void check_itimerval(struct itimerval *value) {
-
- if (unlikely(!timeval_valid(&value->it_value)))
- fixup_timeval(&value->it_value, 0);
-
- if (unlikely(!timeval_valid(&value->it_interval)))
- fixup_timeval(&value->it_interval, 1);
-}
-
int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
{
struct task_struct *tsk = current;
@@ -201,15 +152,10 @@
/*
* Validate the timevals in value.
- *
- * Note: Although the spec requires that invalid values shall
- * return -EINVAL, we just fixup the value and print a limited
- * number of warnings in order not to break users of this
- * historical misfeature.
- *
- * Scheduled for replacement in March 2007
*/
- check_itimerval(value);
+ if (!timeval_valid(&value->it_value) ||
+ !timeval_valid(&value->it_interval))
+ return -EINVAL;
switch (which) {
case ITIMER_REAL:
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index 5a0de84..f1bda23 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -214,8 +214,10 @@
symbol_end = (unsigned long)_etext;
}
- *symbolsize = symbol_end - symbol_start;
- *offset = addr - symbol_start;
+ if (symbolsize)
+ *symbolsize = symbol_end - symbol_start;
+ if (offset)
+ *offset = addr - symbol_start;
return low;
}
@@ -267,6 +269,42 @@
return NULL;
}
+int lookup_symbol_name(unsigned long addr, char *symname)
+{
+ symname[0] = '\0';
+ symname[KSYM_NAME_LEN] = '\0';
+
+ if (is_ksym_addr(addr)) {
+ unsigned long pos;
+
+ pos = get_symbol_pos(addr, NULL, NULL);
+ /* Grab name */
+ kallsyms_expand_symbol(get_symbol_offset(pos), symname);
+ return 0;
+ }
+ /* see if it's in a module */
+ return lookup_module_symbol_name(addr, symname);
+}
+
+int lookup_symbol_attrs(unsigned long addr, unsigned long *size,
+ unsigned long *offset, char *modname, char *name)
+{
+ name[0] = '\0';
+ name[KSYM_NAME_LEN] = '\0';
+
+ if (is_ksym_addr(addr)) {
+ unsigned long pos;
+
+ pos = get_symbol_pos(addr, size, offset);
+ /* Grab name */
+ kallsyms_expand_symbol(get_symbol_offset(pos), name);
+ modname[0] = '\0';
+ return 0;
+ }
+ /* see if it's in a module */
+ return lookup_module_symbol_attrs(addr, size, offset, modname, name);
+}
+
/* Look up a kernel symbol and return it in a text buffer. */
int sprint_symbol(char *buffer, unsigned long address)
{
@@ -301,25 +339,20 @@
struct kallsym_iter
{
loff_t pos;
- struct module *owner;
unsigned long value;
unsigned int nameoff; /* If iterating in core kernel symbols */
char type;
char name[KSYM_NAME_LEN+1];
+ char module_name[MODULE_NAME_LEN + 1];
+ int exported;
};
static int get_ksymbol_mod(struct kallsym_iter *iter)
{
- iter->owner = module_get_kallsym(iter->pos - kallsyms_num_syms,
- &iter->value, &iter->type,
- iter->name, sizeof(iter->name));
- if (iter->owner == NULL)
+ if (module_get_kallsym(iter->pos - kallsyms_num_syms, &iter->value,
+ &iter->type, iter->name, iter->module_name,
+ &iter->exported) < 0)
return 0;
-
- /* Label it "global" if it is exported, "local" if not exported. */
- iter->type = is_exported(iter->name, iter->owner)
- ? toupper(iter->type) : tolower(iter->type);
-
return 1;
}
@@ -328,7 +361,7 @@
{
unsigned off = iter->nameoff;
- iter->owner = NULL;
+ iter->module_name[0] = '\0';
iter->value = kallsyms_addresses[iter->pos];
iter->type = kallsyms_get_symbol_type(off);
@@ -392,12 +425,17 @@
if (!iter->name[0])
return 0;
- if (iter->owner)
+ if (iter->module_name[0]) {
+ char type;
+
+ /* Label it "global" if it is exported,
+ * "local" if not exported. */
+ type = iter->exported ? toupper(iter->type) :
+ tolower(iter->type);
seq_printf(m, "%0*lx %c %s\t[%s]\n",
(int)(2*sizeof(void*)),
- iter->value, iter->type, iter->name,
- module_name(iter->owner));
- else
+ iter->value, type, iter->name, iter->module_name);
+ } else
seq_printf(m, "%0*lx %c %s\n",
(int)(2*sizeof(void*)),
iter->value, iter->type, iter->name);
@@ -432,18 +470,11 @@
return ret;
}
-static int kallsyms_release(struct inode *inode, struct file *file)
-{
- struct seq_file *m = (struct seq_file *)file->private_data;
- kfree(m->private);
- return seq_release(inode, file);
-}
-
static const struct file_operations kallsyms_operations = {
.open = kallsyms_open,
.read = seq_read,
.llseek = seq_lseek,
- .release = kallsyms_release,
+ .release = seq_release_private,
};
static int __init kallsyms_init(void)
diff --git a/kernel/kexec.c b/kernel/kexec.c
index 2a59c8a..25db14b 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -1118,8 +1118,8 @@
memset(&prstatus, 0, sizeof(prstatus));
prstatus.pr_pid = current->pid;
elf_core_copy_regs(&prstatus.pr_reg, regs);
- buf = append_elf_note(buf, "CORE", NT_PRSTATUS, &prstatus,
- sizeof(prstatus));
+ buf = append_elf_note(buf, KEXEC_CORE_NOTE_NAME, NT_PRSTATUS,
+ &prstatus, sizeof(prstatus));
final_note(buf);
}
diff --git a/kernel/kmod.c b/kernel/kmod.c
index 7962761..49cc4b9 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -23,7 +23,6 @@
#include <linux/syscalls.h>
#include <linux/unistd.h>
#include <linux/kmod.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/mnt_namespace.h>
#include <linux/completion.h>
@@ -166,6 +165,12 @@
/* We can run anywhere, unlike our parent keventd(). */
set_cpus_allowed(current, CPU_MASK_ALL);
+ /*
+ * Our parent is keventd, which runs with elevated scheduling priority.
+ * Avoid propagating that into the userspace child.
+ */
+ set_user_nice(current, 0);
+
retval = -EPERM;
if (current->fs->root)
retval = kernel_execve(sub_info->path,
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index d25a9ad..9e47d8c 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -35,16 +35,19 @@
#include <linux/hash.h>
#include <linux/init.h>
#include <linux/slab.h>
+#include <linux/stddef.h>
#include <linux/module.h>
#include <linux/moduleloader.h>
#include <linux/kallsyms.h>
#include <linux/freezer.h>
#include <linux/seq_file.h>
#include <linux/debugfs.h>
+#include <linux/kdebug.h>
+
#include <asm-generic/sections.h>
#include <asm/cacheflush.h>
#include <asm/errno.h>
-#include <asm/kdebug.h>
+#include <asm/uaccess.h>
#define KPROBE_HASH_BITS 6
#define KPROBE_TABLE_SIZE (1 << KPROBE_HASH_BITS)
@@ -63,6 +66,9 @@
static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
static atomic_t kprobe_count;
+/* NOTE: change this value only with kprobe_mutex held */
+static bool kprobe_enabled;
+
DEFINE_MUTEX(kprobe_mutex); /* Protects kprobe_table */
DEFINE_SPINLOCK(kretprobe_lock); /* Protects kretprobe_inst_table */
static DEFINE_PER_CPU(struct kprobe *, kprobe_instance) = NULL;
@@ -132,9 +138,8 @@
struct kprobe_insn_page *kip;
struct hlist_node *pos;
- retry:
- hlist_for_each(pos, &kprobe_insn_pages) {
- kip = hlist_entry(pos, struct kprobe_insn_page, hlist);
+ retry:
+ hlist_for_each_entry(kip, pos, &kprobe_insn_pages, hlist) {
if (kip->nused < INSNS_PER_PAGE) {
int i;
for (i = 0; i < INSNS_PER_PAGE; i++) {
@@ -155,9 +160,8 @@
}
/* All out of space. Need to allocate a new page. Use slot 0. */
kip = kmalloc(sizeof(struct kprobe_insn_page), GFP_KERNEL);
- if (!kip) {
+ if (!kip)
return NULL;
- }
/*
* Use module_alloc so this page is within +/- 2GB of where the
@@ -213,9 +217,8 @@
if (check_safety() != 0)
return -EAGAIN;
- hlist_for_each_safe(pos, next, &kprobe_insn_pages) {
+ hlist_for_each_entry_safe(kip, pos, next, &kprobe_insn_pages, hlist) {
int i;
- kip = hlist_entry(pos, struct kprobe_insn_page, hlist);
if (kip->ngarbage == 0)
continue;
kip->ngarbage = 0; /* we will collect all garbages */
@@ -234,8 +237,7 @@
struct kprobe_insn_page *kip;
struct hlist_node *pos;
- hlist_for_each(pos, &kprobe_insn_pages) {
- kip = hlist_entry(pos, struct kprobe_insn_page, hlist);
+ hlist_for_each_entry(kip, pos, &kprobe_insn_pages, hlist) {
if (kip->insns <= slot &&
slot < kip->insns + (INSNS_PER_PAGE * MAX_INSN_SIZE)) {
int i = (slot - kip->insns) / MAX_INSN_SIZE;
@@ -248,9 +250,9 @@
break;
}
}
- if (dirty && (++kprobe_garbage_slots > INSNS_PER_PAGE)) {
+
+ if (dirty && ++kprobe_garbage_slots > INSNS_PER_PAGE)
collect_garbage_slots();
- }
}
#endif
@@ -316,7 +318,6 @@
reset_kprobe_instance();
}
}
- return;
}
static int __kprobes aggr_fault_handler(struct kprobe *p, struct pt_regs *regs,
@@ -362,46 +363,6 @@
}
/* Called with kretprobe_lock held */
-struct kretprobe_instance __kprobes *get_free_rp_inst(struct kretprobe *rp)
-{
- struct hlist_node *node;
- struct kretprobe_instance *ri;
- hlist_for_each_entry(ri, node, &rp->free_instances, uflist)
- return ri;
- return NULL;
-}
-
-/* Called with kretprobe_lock held */
-static struct kretprobe_instance __kprobes *get_used_rp_inst(struct kretprobe
- *rp)
-{
- struct hlist_node *node;
- struct kretprobe_instance *ri;
- hlist_for_each_entry(ri, node, &rp->used_instances, uflist)
- return ri;
- return NULL;
-}
-
-/* Called with kretprobe_lock held */
-void __kprobes add_rp_inst(struct kretprobe_instance *ri)
-{
- /*
- * Remove rp inst off the free list -
- * Add it back when probed function returns
- */
- hlist_del(&ri->uflist);
-
- /* Add rp inst onto table */
- INIT_HLIST_NODE(&ri->hlist);
- hlist_add_head(&ri->hlist,
- &kretprobe_inst_table[hash_ptr(ri->task, KPROBE_HASH_BITS)]);
-
- /* Also add this rp inst to the used list. */
- INIT_HLIST_NODE(&ri->uflist);
- hlist_add_head(&ri->uflist, &ri->rp->used_instances);
-}
-
-/* Called with kretprobe_lock held */
void __kprobes recycle_rp_inst(struct kretprobe_instance *ri,
struct hlist_head *head)
{
@@ -454,7 +415,9 @@
static inline void free_rp_inst(struct kretprobe *rp)
{
struct kretprobe_instance *ri;
- while ((ri = get_free_rp_inst(rp)) != NULL) {
+ struct hlist_node *pos, *next;
+
+ hlist_for_each_entry_safe(ri, pos, next, &rp->free_instances, uflist) {
hlist_del(&ri->uflist);
kfree(ri);
}
@@ -535,8 +498,8 @@
static int __kprobes in_kprobes_functions(unsigned long addr)
{
- if (addr >= (unsigned long)__kprobes_text_start
- && addr < (unsigned long)__kprobes_text_end)
+ if (addr >= (unsigned long)__kprobes_text_start &&
+ addr < (unsigned long)__kprobes_text_end)
return -EINVAL;
return 0;
}
@@ -563,19 +526,24 @@
return -EINVAL;
p->addr = (kprobe_opcode_t *)(((char *)p->addr)+ p->offset);
- if ((!kernel_text_address((unsigned long) p->addr)) ||
- in_kprobes_functions((unsigned long) p->addr))
+ if (!kernel_text_address((unsigned long) p->addr) ||
+ in_kprobes_functions((unsigned long) p->addr))
return -EINVAL;
p->mod_refcounted = 0;
- /* Check are we probing a module */
- if ((probed_mod = module_text_address((unsigned long) p->addr))) {
+
+ /*
+ * Check if are we probing a module.
+ */
+ probed_mod = module_text_address((unsigned long) p->addr);
+ if (probed_mod) {
struct module *calling_mod = module_text_address(called_from);
- /* We must allow modules to probe themself and
- * in this case avoid incrementing the module refcount,
- * so as to allow unloading of self probing modules.
+ /*
+ * We must allow modules to probe themself and in this case
+ * avoid incrementing the module refcount, so as to allow
+ * unloading of self probing modules.
*/
- if (calling_mod && (calling_mod != probed_mod)) {
+ if (calling_mod && calling_mod != probed_mod) {
if (unlikely(!try_module_get(probed_mod)))
return -EINVAL;
p->mod_refcounted = 1;
@@ -593,19 +561,21 @@
goto out;
}
- if ((ret = arch_prepare_kprobe(p)) != 0)
+ ret = arch_prepare_kprobe(p);
+ if (ret)
goto out;
INIT_HLIST_NODE(&p->hlist);
hlist_add_head_rcu(&p->hlist,
&kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]);
- if (atomic_add_return(1, &kprobe_count) == \
+ if (kprobe_enabled) {
+ if (atomic_add_return(1, &kprobe_count) == \
(ARCH_INACTIVE_KPROBE_COUNT + 1))
- register_page_fault_notifier(&kprobe_page_fault_nb);
+ register_page_fault_notifier(&kprobe_page_fault_nb);
- arch_arm_kprobe(p);
-
+ arch_arm_kprobe(p);
+ }
out:
mutex_unlock(&kprobe_mutex);
@@ -616,8 +586,7 @@
int __kprobes register_kprobe(struct kprobe *p)
{
- return __register_kprobe(p,
- (unsigned long)__builtin_return_address(0));
+ return __register_kprobe(p, (unsigned long)__builtin_return_address(0));
}
void __kprobes unregister_kprobe(struct kprobe *p)
@@ -641,11 +610,16 @@
return;
}
valid_p:
- if ((old_p == p) || ((old_p->pre_handler == aggr_pre_handler) &&
- (p->list.next == &old_p->list) &&
- (p->list.prev == &old_p->list))) {
- /* Only probe on the hash list */
- arch_disarm_kprobe(p);
+ if (old_p == p ||
+ (old_p->pre_handler == aggr_pre_handler &&
+ p->list.next == &old_p->list && p->list.prev == &old_p->list)) {
+ /*
+ * Only probe on the hash list. Disarm only if kprobes are
+ * enabled - otherwise, the breakpoint would already have
+ * been removed. We save on flushing icache.
+ */
+ if (kprobe_enabled)
+ arch_disarm_kprobe(p);
hlist_del_rcu(&old_p->hlist);
cleanup_p = 1;
} else {
@@ -656,9 +630,11 @@
mutex_unlock(&kprobe_mutex);
synchronize_sched();
- if (p->mod_refcounted &&
- (mod = module_text_address((unsigned long)p->addr)))
- module_put(mod);
+ if (p->mod_refcounted) {
+ mod = module_text_address((unsigned long)p->addr);
+ if (mod)
+ module_put(mod);
+ }
if (cleanup_p) {
if (p != old_p) {
@@ -729,7 +705,21 @@
/*TODO: consider to only swap the RA after the last pre_handler fired */
spin_lock_irqsave(&kretprobe_lock, flags);
- arch_prepare_kretprobe(rp, regs);
+ if (!hlist_empty(&rp->free_instances)) {
+ struct kretprobe_instance *ri;
+
+ ri = hlist_entry(rp->free_instances.first,
+ struct kretprobe_instance, uflist);
+ ri->rp = rp;
+ ri->task = current;
+ arch_prepare_kretprobe(ri, regs);
+
+ /* XXX(hch): why is there no hlist_move_head? */
+ hlist_del(&ri->uflist);
+ hlist_add_head(&ri->uflist, &ri->rp->used_instances);
+ hlist_add_head(&ri->hlist, kretprobe_inst_table_head(ri->task));
+ } else
+ rp->nmissed++;
spin_unlock_irqrestore(&kretprobe_lock, flags);
return 0;
}
@@ -792,11 +782,13 @@
{
unsigned long flags;
struct kretprobe_instance *ri;
+ struct hlist_node *pos, *next;
unregister_kprobe(&rp->kp);
+
/* No race here */
spin_lock_irqsave(&kretprobe_lock, flags);
- while ((ri = get_used_rp_inst(rp)) != NULL) {
+ hlist_for_each_entry_safe(ri, pos, next, &rp->used_instances, uflist) {
ri->rp = NULL;
hlist_del(&ri->uflist);
}
@@ -816,6 +808,9 @@
}
atomic_set(&kprobe_count, 0);
+ /* By default, kprobes are enabled */
+ kprobe_enabled = true;
+
err = arch_init_kprobes();
if (!err)
err = register_die_notifier(&kprobe_exceptions_nb);
@@ -825,7 +820,7 @@
#ifdef CONFIG_DEBUG_FS
static void __kprobes report_probe(struct seq_file *pi, struct kprobe *p,
- const char *sym, int offset,char *modname)
+ const char *sym, int offset,char *modname)
{
char *kprobe_type;
@@ -867,13 +862,13 @@
struct kprobe *p, *kp;
const char *sym = NULL;
unsigned int i = *(loff_t *) v;
- unsigned long size, offset = 0;
+ unsigned long offset = 0;
char *modname, namebuf[128];
head = &kprobe_table[i];
preempt_disable();
hlist_for_each_entry_rcu(p, node, head, hlist) {
- sym = kallsyms_lookup((unsigned long)p->addr, &size,
+ sym = kallsyms_lookup((unsigned long)p->addr, NULL,
&offset, &modname, namebuf);
if (p->pre_handler == aggr_pre_handler) {
list_for_each_entry_rcu(kp, &p->list, list)
@@ -904,21 +899,149 @@
.release = seq_release,
};
+static void __kprobes enable_all_kprobes(void)
+{
+ struct hlist_head *head;
+ struct hlist_node *node;
+ struct kprobe *p;
+ unsigned int i;
+
+ mutex_lock(&kprobe_mutex);
+
+ /* If kprobes are already enabled, just return */
+ if (kprobe_enabled)
+ goto already_enabled;
+
+ /*
+ * Re-register the page fault notifier only if there are any
+ * active probes at the time of enabling kprobes globally
+ */
+ if (atomic_read(&kprobe_count) > ARCH_INACTIVE_KPROBE_COUNT)
+ register_page_fault_notifier(&kprobe_page_fault_nb);
+
+ for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
+ head = &kprobe_table[i];
+ hlist_for_each_entry_rcu(p, node, head, hlist)
+ arch_arm_kprobe(p);
+ }
+
+ kprobe_enabled = true;
+ printk(KERN_INFO "Kprobes globally enabled\n");
+
+already_enabled:
+ mutex_unlock(&kprobe_mutex);
+ return;
+}
+
+static void __kprobes disable_all_kprobes(void)
+{
+ struct hlist_head *head;
+ struct hlist_node *node;
+ struct kprobe *p;
+ unsigned int i;
+
+ mutex_lock(&kprobe_mutex);
+
+ /* If kprobes are already disabled, just return */
+ if (!kprobe_enabled)
+ goto already_disabled;
+
+ kprobe_enabled = false;
+ printk(KERN_INFO "Kprobes globally disabled\n");
+ for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
+ head = &kprobe_table[i];
+ hlist_for_each_entry_rcu(p, node, head, hlist) {
+ if (!arch_trampoline_kprobe(p))
+ arch_disarm_kprobe(p);
+ }
+ }
+
+ mutex_unlock(&kprobe_mutex);
+ /* Allow all currently running kprobes to complete */
+ synchronize_sched();
+
+ mutex_lock(&kprobe_mutex);
+ /* Unconditionally unregister the page_fault notifier */
+ unregister_page_fault_notifier(&kprobe_page_fault_nb);
+
+already_disabled:
+ mutex_unlock(&kprobe_mutex);
+ return;
+}
+
+/*
+ * XXX: The debugfs bool file interface doesn't allow for callbacks
+ * when the bool state is switched. We can reuse that facility when
+ * available
+ */
+static ssize_t read_enabled_file_bool(struct file *file,
+ char __user *user_buf, size_t count, loff_t *ppos)
+{
+ char buf[3];
+
+ if (kprobe_enabled)
+ buf[0] = '1';
+ else
+ buf[0] = '0';
+ buf[1] = '\n';
+ buf[2] = 0x00;
+ return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
+}
+
+static ssize_t write_enabled_file_bool(struct file *file,
+ const char __user *user_buf, size_t count, loff_t *ppos)
+{
+ char buf[32];
+ int buf_size;
+
+ buf_size = min(count, (sizeof(buf)-1));
+ if (copy_from_user(buf, user_buf, buf_size))
+ return -EFAULT;
+
+ switch (buf[0]) {
+ case 'y':
+ case 'Y':
+ case '1':
+ enable_all_kprobes();
+ break;
+ case 'n':
+ case 'N':
+ case '0':
+ disable_all_kprobes();
+ break;
+ }
+
+ return count;
+}
+
+static struct file_operations fops_kp = {
+ .read = read_enabled_file_bool,
+ .write = write_enabled_file_bool,
+};
+
static int __kprobes debugfs_kprobe_init(void)
{
struct dentry *dir, *file;
+ unsigned int value = 1;
dir = debugfs_create_dir("kprobes", NULL);
if (!dir)
return -ENOMEM;
- file = debugfs_create_file("list", 0444, dir , 0 ,
+ file = debugfs_create_file("list", 0444, dir, NULL,
&debugfs_kprobes_operations);
if (!file) {
debugfs_remove(dir);
return -ENOMEM;
}
+ file = debugfs_create_file("enabled", 0600, dir,
+ &value, &fops_kp);
+ if (!file) {
+ debugfs_remove(dir);
+ return -ENOMEM;
+ }
+
return 0;
}
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 7065a68..1a5ff22 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -257,9 +257,8 @@
trace->entries = stack_trace + nr_stack_trace_entries;
trace->skip = 3;
- trace->all_contexts = 0;
- save_stack_trace(trace, NULL);
+ save_stack_trace(trace);
trace->max_entries = trace->nr_entries;
@@ -341,10 +340,7 @@
const char * __get_key_name(struct lockdep_subclass_key *key, char *str)
{
- unsigned long offs, size;
- char *modname;
-
- return kallsyms_lookup((unsigned long)key, &size, &offs, &modname, str);
+ return kallsyms_lookup((unsigned long)key, NULL, NULL, NULL, str);
}
void
@@ -1313,8 +1309,9 @@
/*
* Look up a dependency chain. If the key is not present yet then
- * add it and return 0 - in this case the new dependency chain is
- * validated. If the key is already hashed, return 1.
+ * add it and return 1 - in this case the new dependency chain is
+ * validated. If the key is already hashed, return 0.
+ * (On return with 1 graph_lock is held.)
*/
static inline int lookup_chain_cache(u64 chain_key, struct lock_class *class)
{
@@ -1577,7 +1574,7 @@
* Mark a lock with a usage bit, and validate the state transition:
*/
static int mark_lock(struct task_struct *curr, struct held_lock *this,
- enum lock_usage_bit new_bit, unsigned long ip)
+ enum lock_usage_bit new_bit)
{
unsigned int new_mask = 1 << new_bit, ret = 1;
@@ -1600,14 +1597,6 @@
this->class->usage_mask |= new_mask;
-#ifdef CONFIG_TRACE_IRQFLAGS
- if (new_bit == LOCK_ENABLED_HARDIRQS ||
- new_bit == LOCK_ENABLED_HARDIRQS_READ)
- ip = curr->hardirq_enable_ip;
- else if (new_bit == LOCK_ENABLED_SOFTIRQS ||
- new_bit == LOCK_ENABLED_SOFTIRQS_READ)
- ip = curr->softirq_enable_ip;
-#endif
if (!save_trace(this->class->usage_traces + new_bit))
return 0;
@@ -1806,7 +1795,7 @@
* Mark all held locks with a usage bit:
*/
static int
-mark_held_locks(struct task_struct *curr, int hardirq, unsigned long ip)
+mark_held_locks(struct task_struct *curr, int hardirq)
{
enum lock_usage_bit usage_bit;
struct held_lock *hlock;
@@ -1826,7 +1815,7 @@
else
usage_bit = LOCK_ENABLED_SOFTIRQS;
}
- if (!mark_lock(curr, hlock, usage_bit, ip))
+ if (!mark_lock(curr, hlock, usage_bit))
return 0;
}
@@ -1879,7 +1868,7 @@
* We are going to turn hardirqs on, so set the
* usage bit for all held locks:
*/
- if (!mark_held_locks(curr, 1, ip))
+ if (!mark_held_locks(curr, 1))
return;
/*
* If we have softirqs enabled, then set the usage
@@ -1887,7 +1876,7 @@
* this bit from being set before)
*/
if (curr->softirqs_enabled)
- if (!mark_held_locks(curr, 0, ip))
+ if (!mark_held_locks(curr, 0))
return;
curr->hardirq_enable_ip = ip;
@@ -1955,7 +1944,7 @@
* enabled too:
*/
if (curr->hardirqs_enabled)
- mark_held_locks(curr, 0, ip);
+ mark_held_locks(curr, 0);
}
/*
@@ -2093,43 +2082,43 @@
if (read) {
if (curr->hardirq_context)
if (!mark_lock(curr, hlock,
- LOCK_USED_IN_HARDIRQ_READ, ip))
+ LOCK_USED_IN_HARDIRQ_READ))
return 0;
if (curr->softirq_context)
if (!mark_lock(curr, hlock,
- LOCK_USED_IN_SOFTIRQ_READ, ip))
+ LOCK_USED_IN_SOFTIRQ_READ))
return 0;
} else {
if (curr->hardirq_context)
- if (!mark_lock(curr, hlock, LOCK_USED_IN_HARDIRQ, ip))
+ if (!mark_lock(curr, hlock, LOCK_USED_IN_HARDIRQ))
return 0;
if (curr->softirq_context)
- if (!mark_lock(curr, hlock, LOCK_USED_IN_SOFTIRQ, ip))
+ if (!mark_lock(curr, hlock, LOCK_USED_IN_SOFTIRQ))
return 0;
}
}
if (!hardirqs_off) {
if (read) {
if (!mark_lock(curr, hlock,
- LOCK_ENABLED_HARDIRQS_READ, ip))
+ LOCK_ENABLED_HARDIRQS_READ))
return 0;
if (curr->softirqs_enabled)
if (!mark_lock(curr, hlock,
- LOCK_ENABLED_SOFTIRQS_READ, ip))
+ LOCK_ENABLED_SOFTIRQS_READ))
return 0;
} else {
if (!mark_lock(curr, hlock,
- LOCK_ENABLED_HARDIRQS, ip))
+ LOCK_ENABLED_HARDIRQS))
return 0;
if (curr->softirqs_enabled)
if (!mark_lock(curr, hlock,
- LOCK_ENABLED_SOFTIRQS, ip))
+ LOCK_ENABLED_SOFTIRQS))
return 0;
}
}
#endif
/* mark it as used: */
- if (!mark_lock(curr, hlock, LOCK_USED, ip))
+ if (!mark_lock(curr, hlock, LOCK_USED))
return 0;
out_calc_hash:
/*
diff --git a/kernel/module.c b/kernel/module.c
index 1eb8ca5..d36e454 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -19,6 +19,7 @@
#include <linux/module.h>
#include <linux/moduleloader.h>
#include <linux/init.h>
+#include <linux/kallsyms.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
@@ -310,14 +311,14 @@
{
/* Reallocation required? */
if (pcpu_num_used + 1 > pcpu_num_allocated) {
- int *new = kmalloc(sizeof(new[0]) * pcpu_num_allocated*2,
- GFP_KERNEL);
+ int *new;
+
+ new = krealloc(pcpu_size, sizeof(new[0])*pcpu_num_allocated*2,
+ GFP_KERNEL);
if (!new)
return 0;
- memcpy(new, pcpu_size, sizeof(new[0])*pcpu_num_allocated);
pcpu_num_allocated *= 2;
- kfree(pcpu_size);
pcpu_size = new;
}
@@ -1471,7 +1472,7 @@
}
#ifdef CONFIG_KALLSYMS
-int is_exported(const char *name, const struct module *mod)
+static int is_exported(const char *name, const struct module *mod)
{
if (!mod && lookup_symbol(name, __start___ksymtab, __stop___ksymtab))
return 1;
@@ -2097,8 +2098,10 @@
if (!best)
return NULL;
- *size = nextval - mod->symtab[best].st_value;
- *offset = addr - mod->symtab[best].st_value;
+ if (size)
+ *size = nextval - mod->symtab[best].st_value;
+ if (offset)
+ *offset = addr - mod->symtab[best].st_value;
return mod->strtab + mod->symtab[best].st_name;
}
@@ -2123,8 +2126,58 @@
return NULL;
}
-struct module *module_get_kallsym(unsigned int symnum, unsigned long *value,
- char *type, char *name, size_t namelen)
+int lookup_module_symbol_name(unsigned long addr, char *symname)
+{
+ struct module *mod;
+
+ mutex_lock(&module_mutex);
+ list_for_each_entry(mod, &modules, list) {
+ if (within(addr, mod->module_init, mod->init_size) ||
+ within(addr, mod->module_core, mod->core_size)) {
+ const char *sym;
+
+ sym = get_ksymbol(mod, addr, NULL, NULL);
+ if (!sym)
+ goto out;
+ strlcpy(symname, sym, KSYM_NAME_LEN + 1);
+ mutex_unlock(&module_mutex);
+ return 0;
+ }
+ }
+out:
+ mutex_unlock(&module_mutex);
+ return -ERANGE;
+}
+
+int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size,
+ unsigned long *offset, char *modname, char *name)
+{
+ struct module *mod;
+
+ mutex_lock(&module_mutex);
+ list_for_each_entry(mod, &modules, list) {
+ if (within(addr, mod->module_init, mod->init_size) ||
+ within(addr, mod->module_core, mod->core_size)) {
+ const char *sym;
+
+ sym = get_ksymbol(mod, addr, size, offset);
+ if (!sym)
+ goto out;
+ if (modname)
+ strlcpy(modname, mod->name, MODULE_NAME_LEN + 1);
+ if (name)
+ strlcpy(name, sym, KSYM_NAME_LEN + 1);
+ mutex_unlock(&module_mutex);
+ return 0;
+ }
+ }
+out:
+ mutex_unlock(&module_mutex);
+ return -ERANGE;
+}
+
+int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
+ char *name, char *module_name, int *exported)
{
struct module *mod;
@@ -2134,14 +2187,16 @@
*value = mod->symtab[symnum].st_value;
*type = mod->symtab[symnum].st_info;
strlcpy(name, mod->strtab + mod->symtab[symnum].st_name,
- namelen);
+ KSYM_NAME_LEN + 1);
+ strlcpy(module_name, mod->name, MODULE_NAME_LEN + 1);
+ *exported = is_exported(name, mod);
mutex_unlock(&module_mutex);
- return mod;
+ return 0;
}
symnum -= mod->num_symtab;
}
mutex_unlock(&module_mutex);
- return NULL;
+ return -ERANGE;
}
static unsigned long mod_find_symname(struct module *mod, const char *name)
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
index f5b9ee6..1bc4b55 100644
--- a/kernel/nsproxy.c
+++ b/kernel/nsproxy.c
@@ -38,10 +38,8 @@
/*
* creates a copy of "orig" with refcount 1.
- * This does not grab references to the contained namespaces,
- * so that needs to be done by dup_namespaces.
*/
-static inline struct nsproxy *clone_namespaces(struct nsproxy *orig)
+static inline struct nsproxy *clone_nsproxy(struct nsproxy *orig)
{
struct nsproxy *ns;
@@ -52,26 +50,49 @@
}
/*
- * copies the nsproxy, setting refcount to 1, and grabbing a
- * reference to all contained namespaces. Called from
- * sys_unshare()
+ * Create new nsproxy and all of its the associated namespaces.
+ * Return the newly created nsproxy. Do not attach this to the task,
+ * leave it to the caller to do proper locking and attach it to task.
*/
-struct nsproxy *dup_namespaces(struct nsproxy *orig)
+static struct nsproxy *create_new_namespaces(int flags, struct task_struct *tsk,
+ struct fs_struct *new_fs)
{
- struct nsproxy *ns = clone_namespaces(orig);
+ struct nsproxy *new_nsp;
- if (ns) {
- if (ns->mnt_ns)
- get_mnt_ns(ns->mnt_ns);
- if (ns->uts_ns)
- get_uts_ns(ns->uts_ns);
- if (ns->ipc_ns)
- get_ipc_ns(ns->ipc_ns);
- if (ns->pid_ns)
- get_pid_ns(ns->pid_ns);
- }
+ new_nsp = clone_nsproxy(tsk->nsproxy);
+ if (!new_nsp)
+ return ERR_PTR(-ENOMEM);
- return ns;
+ new_nsp->mnt_ns = copy_mnt_ns(flags, tsk->nsproxy->mnt_ns, new_fs);
+ if (IS_ERR(new_nsp->mnt_ns))
+ goto out_ns;
+
+ new_nsp->uts_ns = copy_utsname(flags, tsk->nsproxy->uts_ns);
+ if (IS_ERR(new_nsp->uts_ns))
+ goto out_uts;
+
+ new_nsp->ipc_ns = copy_ipcs(flags, tsk->nsproxy->ipc_ns);
+ if (IS_ERR(new_nsp->ipc_ns))
+ goto out_ipc;
+
+ new_nsp->pid_ns = copy_pid_ns(flags, tsk->nsproxy->pid_ns);
+ if (IS_ERR(new_nsp->pid_ns))
+ goto out_pid;
+
+ return new_nsp;
+
+out_pid:
+ if (new_nsp->ipc_ns)
+ put_ipc_ns(new_nsp->ipc_ns);
+out_ipc:
+ if (new_nsp->uts_ns)
+ put_uts_ns(new_nsp->uts_ns);
+out_uts:
+ if (new_nsp->mnt_ns)
+ put_mnt_ns(new_nsp->mnt_ns);
+out_ns:
+ kfree(new_nsp);
+ return ERR_PTR(-ENOMEM);
}
/*
@@ -92,47 +113,21 @@
if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC)))
return 0;
- new_ns = clone_namespaces(old_ns);
- if (!new_ns) {
- err = -ENOMEM;
+ if (!capable(CAP_SYS_ADMIN)) {
+ err = -EPERM;
+ goto out;
+ }
+
+ new_ns = create_new_namespaces(flags, tsk, tsk->fs);
+ if (IS_ERR(new_ns)) {
+ err = PTR_ERR(new_ns);
goto out;
}
tsk->nsproxy = new_ns;
-
- err = copy_mnt_ns(flags, tsk);
- if (err)
- goto out_ns;
-
- err = copy_utsname(flags, tsk);
- if (err)
- goto out_uts;
-
- err = copy_ipcs(flags, tsk);
- if (err)
- goto out_ipc;
-
- err = copy_pid_ns(flags, tsk);
- if (err)
- goto out_pid;
-
out:
put_nsproxy(old_ns);
return err;
-
-out_pid:
- if (new_ns->ipc_ns)
- put_ipc_ns(new_ns->ipc_ns);
-out_ipc:
- if (new_ns->uts_ns)
- put_uts_ns(new_ns->uts_ns);
-out_uts:
- if (new_ns->mnt_ns)
- put_mnt_ns(new_ns->mnt_ns);
-out_ns:
- tsk->nsproxy = old_ns;
- kfree(new_ns);
- goto out;
}
void free_nsproxy(struct nsproxy *ns)
@@ -147,3 +142,41 @@
put_pid_ns(ns->pid_ns);
kfree(ns);
}
+
+/*
+ * Called from unshare. Unshare all the namespaces part of nsproxy.
+ * On sucess, returns the new nsproxy and a reference to old nsproxy
+ * to make sure it stays around.
+ */
+int unshare_nsproxy_namespaces(unsigned long unshare_flags,
+ struct nsproxy **new_nsp, struct fs_struct *new_fs)
+{
+ struct nsproxy *old_ns = current->nsproxy;
+ int err = 0;
+
+ if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC)))
+ return 0;
+
+#ifndef CONFIG_IPC_NS
+ if (unshare_flags & CLONE_NEWIPC)
+ return -EINVAL;
+#endif
+
+#ifndef CONFIG_UTS_NS
+ if (unshare_flags & CLONE_NEWUTS)
+ return -EINVAL;
+#endif
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ get_nsproxy(old_ns);
+
+ *new_nsp = create_new_namespaces(unshare_flags, current,
+ new_fs ? new_fs : current->fs);
+ if (IS_ERR(*new_nsp)) {
+ err = PTR_ERR(*new_nsp);
+ put_nsproxy(old_ns);
+ }
+ return err;
+}
diff --git a/kernel/params.c b/kernel/params.c
index 3121723..e61c46c 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -269,7 +269,7 @@
return param_get_bool(buffer, &dummy);
}
-/* We cheat here and temporarily mangle the string. */
+/* We break the rule and mangle the string. */
static int param_array(const char *name,
const char *val,
unsigned int min, unsigned int max,
diff --git a/kernel/pid.c b/kernel/pid.c
index 9c80bc2..d3ad724 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -360,16 +360,11 @@
}
EXPORT_SYMBOL_GPL(find_get_pid);
-int copy_pid_ns(int flags, struct task_struct *tsk)
+struct pid_namespace *copy_pid_ns(int flags, struct pid_namespace *old_ns)
{
- struct pid_namespace *old_ns = tsk->nsproxy->pid_ns;
- int err = 0;
-
- if (!old_ns)
- return 0;
-
+ BUG_ON(!old_ns);
get_pid_ns(old_ns);
- return err;
+ return old_ns;
}
void free_pid_ns(struct kref *kref)
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index 657f776..1de710e1 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -971,7 +971,7 @@
maxfire = 20;
tsk->it_prof_expires = cputime_zero;
while (!list_empty(timers)) {
- struct cpu_timer_list *t = list_entry(timers->next,
+ struct cpu_timer_list *t = list_first_entry(timers,
struct cpu_timer_list,
entry);
if (!--maxfire || cputime_lt(prof_ticks(tsk), t->expires.cpu)) {
@@ -986,7 +986,7 @@
maxfire = 20;
tsk->it_virt_expires = cputime_zero;
while (!list_empty(timers)) {
- struct cpu_timer_list *t = list_entry(timers->next,
+ struct cpu_timer_list *t = list_first_entry(timers,
struct cpu_timer_list,
entry);
if (!--maxfire || cputime_lt(virt_ticks(tsk), t->expires.cpu)) {
@@ -1001,7 +1001,7 @@
maxfire = 20;
tsk->it_sched_expires = 0;
while (!list_empty(timers)) {
- struct cpu_timer_list *t = list_entry(timers->next,
+ struct cpu_timer_list *t = list_first_entry(timers,
struct cpu_timer_list,
entry);
if (!--maxfire || tsk->sched_time < t->expires.sched) {
@@ -1057,7 +1057,7 @@
maxfire = 20;
prof_expires = cputime_zero;
while (!list_empty(timers)) {
- struct cpu_timer_list *t = list_entry(timers->next,
+ struct cpu_timer_list *t = list_first_entry(timers,
struct cpu_timer_list,
entry);
if (!--maxfire || cputime_lt(ptime, t->expires.cpu)) {
@@ -1072,7 +1072,7 @@
maxfire = 20;
virt_expires = cputime_zero;
while (!list_empty(timers)) {
- struct cpu_timer_list *t = list_entry(timers->next,
+ struct cpu_timer_list *t = list_first_entry(timers,
struct cpu_timer_list,
entry);
if (!--maxfire || cputime_lt(utime, t->expires.cpu)) {
@@ -1087,7 +1087,7 @@
maxfire = 20;
sched_expires = 0;
while (!list_empty(timers)) {
- struct cpu_timer_list *t = list_entry(timers->next,
+ struct cpu_timer_list *t = list_first_entry(timers,
struct cpu_timer_list,
entry);
if (!--maxfire || sched_time < t->expires.sched) {
@@ -1400,7 +1400,7 @@
*/
head = &tsk->signal->cpu_timers[clock_idx];
if (list_empty(head) ||
- cputime_ge(list_entry(head->next,
+ cputime_ge(list_first_entry(head,
struct cpu_timer_list, entry)->expires.cpu,
*newval)) {
/*
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
index 44318ca..588c99d 100644
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -31,7 +31,6 @@
* POSIX clocks & timers
*/
#include <linux/mm.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/time.h>
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 8777217..495b7d4 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -79,7 +79,7 @@
config SOFTWARE_SUSPEND
bool "Software Suspend (Hibernation)"
- depends on PM && SWAP && ((X86 && (!SMP || SUSPEND_SMP)) || ((FRV || PPC32) && !SMP))
+ depends on PM && SWAP && (((X86 || PPC64_SWSUSP) && (!SMP || SUSPEND_SMP)) || ((FRV || PPC32) && !SMP))
---help---
Enable the suspend to disk (STD) functionality, which is usually
called "hibernation" in user interfaces. STD checkpoints the
@@ -139,7 +139,7 @@
config SUSPEND_SMP
bool
- depends on HOTPLUG_CPU && X86 && PM
+ depends on HOTPLUG_CPU && (X86 || PPC64) && PM
default y
config APM_EMULATION
diff --git a/kernel/power/process.c b/kernel/power/process.c
index 0eb5c42..0884193 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -8,7 +8,6 @@
#undef DEBUG
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/suspend.h>
#include <linux/module.h>
@@ -25,10 +24,9 @@
static inline int freezeable(struct task_struct * p)
{
- if ((p == current) ||
+ if ((p == current) ||
(p->flags & PF_NOFREEZE) ||
- (p->exit_state == EXIT_ZOMBIE) ||
- (p->exit_state == EXIT_DEAD))
+ (p->exit_state != 0))
return 0;
return 1;
}
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index 128da11..b703977 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -14,7 +14,6 @@
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/suspend.h>
-#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <linux/bitops.h>
#include <linux/spinlock.h>
diff --git a/kernel/power/swap.c b/kernel/power/swap.c
index e83ed99..b8b235c 100644
--- a/kernel/power/swap.c
+++ b/kernel/power/swap.c
@@ -12,7 +12,6 @@
*/
#include <linux/module.h>
-#include <linux/smp_lock.h>
#include <linux/file.h>
#include <linux/utsname.h>
#include <linux/version.h>
diff --git a/kernel/printk.c b/kernel/printk.c
index 4b47e59..0bbdeac 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -20,7 +20,6 @@
#include <linux/mm.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
-#include <linux/smp_lock.h>
#include <linux/console.h>
#include <linux/init.h>
#include <linux/module.h>
@@ -931,8 +930,16 @@
{
int i;
unsigned long flags;
+ struct console *bootconsole = NULL;
- if (preferred_console < 0)
+ if (console_drivers) {
+ if (console->flags & CON_BOOT)
+ return;
+ if (console_drivers->flags & CON_BOOT)
+ bootconsole = console_drivers;
+ }
+
+ if (preferred_console < 0 || bootconsole || !console_drivers)
preferred_console = selected_console;
/*
@@ -978,8 +985,11 @@
if (!(console->flags & CON_ENABLED))
return;
- if (console_drivers && (console_drivers->flags & CON_BOOT)) {
- unregister_console(console_drivers);
+ if (bootconsole) {
+ printk(KERN_INFO "console handover: boot [%s%d] -> real [%s%d]\n",
+ bootconsole->name, bootconsole->index,
+ console->name, console->index);
+ unregister_console(bootconsole);
console->flags &= ~CON_PRINTBUFFER;
}
@@ -1030,16 +1040,11 @@
}
}
- /* If last console is removed, we re-enable picking the first
- * one that gets registered. Without that, pmac early boot console
- * would prevent fbcon from taking over.
- *
+ /*
* If this isn't the last console and it has CON_CONSDEV set, we
* need to set it on the next preferred console.
*/
- if (console_drivers == NULL)
- preferred_console = selected_console;
- else if (console->flags & CON_CONSDEV)
+ if (console_drivers != NULL && console->flags & CON_CONSDEV)
console_drivers->flags |= CON_CONSDEV;
release_console_sem();
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
index bcd14e8..55ba82a 100644
--- a/kernel/rcutorture.c
+++ b/kernel/rcutorture.c
@@ -502,10 +502,6 @@
.name = "sched"
};
-static struct rcu_torture_ops *torture_ops[] =
- { &rcu_ops, &rcu_sync_ops, &rcu_bh_ops, &rcu_bh_sync_ops, &srcu_ops,
- &sched_ops, NULL };
-
/*
* RCU torture writer kthread. Repeatedly substitutes a new structure
* for that pointed to by rcu_torture_current, freeing the old structure
@@ -534,7 +530,7 @@
rp->rtort_mbtest = 1;
rcu_assign_pointer(rcu_torture_current, rp);
smp_wmb();
- if (old_rp != NULL) {
+ if (old_rp) {
i = old_rp->rtort_pipe_count;
if (i > RCU_TORTURE_PIPE_LEN)
i = RCU_TORTURE_PIPE_LEN;
@@ -685,7 +681,7 @@
atomic_read(&rcu_torture_wcount[i]));
}
cnt += sprintf(&page[cnt], "\n");
- if (cur_ops->stats != NULL)
+ if (cur_ops->stats)
cnt += cur_ops->stats(&page[cnt]);
return cnt;
}
@@ -749,13 +745,13 @@
set_cpus_allowed(current, tmp_mask);
- if (reader_tasks != NULL) {
+ if (reader_tasks) {
for (i = 0; i < nrealreaders; i++)
if (reader_tasks[i])
set_cpus_allowed(reader_tasks[i], tmp_mask);
}
- if (fakewriter_tasks != NULL) {
+ if (fakewriter_tasks) {
for (i = 0; i < nfakewriters; i++)
if (fakewriter_tasks[i])
set_cpus_allowed(fakewriter_tasks[i], tmp_mask);
@@ -808,21 +804,21 @@
int i;
fullstop = 1;
- if (shuffler_task != NULL) {
+ if (shuffler_task) {
VERBOSE_PRINTK_STRING("Stopping rcu_torture_shuffle task");
kthread_stop(shuffler_task);
}
shuffler_task = NULL;
- if (writer_task != NULL) {
+ if (writer_task) {
VERBOSE_PRINTK_STRING("Stopping rcu_torture_writer task");
kthread_stop(writer_task);
}
writer_task = NULL;
- if (reader_tasks != NULL) {
+ if (reader_tasks) {
for (i = 0; i < nrealreaders; i++) {
- if (reader_tasks[i] != NULL) {
+ if (reader_tasks[i]) {
VERBOSE_PRINTK_STRING(
"Stopping rcu_torture_reader task");
kthread_stop(reader_tasks[i]);
@@ -834,9 +830,9 @@
}
rcu_torture_current = NULL;
- if (fakewriter_tasks != NULL) {
+ if (fakewriter_tasks) {
for (i = 0; i < nfakewriters; i++) {
- if (fakewriter_tasks[i] != NULL) {
+ if (fakewriter_tasks[i]) {
VERBOSE_PRINTK_STRING(
"Stopping rcu_torture_fakewriter task");
kthread_stop(fakewriter_tasks[i]);
@@ -847,7 +843,7 @@
fakewriter_tasks = NULL;
}
- if (stats_task != NULL) {
+ if (stats_task) {
VERBOSE_PRINTK_STRING("Stopping rcu_torture_stats task");
kthread_stop(stats_task);
}
@@ -858,7 +854,7 @@
rcu_torture_stats_print(); /* -After- the stats thread is stopped! */
- if (cur_ops->cleanup != NULL)
+ if (cur_ops->cleanup)
cur_ops->cleanup();
if (atomic_read(&n_rcu_torture_error))
rcu_torture_print_module_parms("End of test: FAILURE");
@@ -866,27 +862,28 @@
rcu_torture_print_module_parms("End of test: SUCCESS");
}
-static int
+static int __init
rcu_torture_init(void)
{
int i;
int cpu;
int firsterr = 0;
+ static struct rcu_torture_ops *torture_ops[] =
+ { &rcu_ops, &rcu_sync_ops, &rcu_bh_ops, &rcu_bh_sync_ops,
+ &srcu_ops, &sched_ops, };
/* Process args and tell the world that the torturer is on the job. */
-
- for (i = 0; cur_ops = torture_ops[i], cur_ops != NULL; i++) {
+ for (i = 0; i < ARRAY_SIZE(torture_ops); i++) {
cur_ops = torture_ops[i];
- if (strcmp(torture_type, cur_ops->name) == 0) {
+ if (strcmp(torture_type, cur_ops->name) == 0)
break;
- }
}
- if (cur_ops == NULL) {
+ if (i == ARRAY_SIZE(torture_ops)) {
printk(KERN_ALERT "rcutorture: invalid torture type: \"%s\"\n",
torture_type);
return (-EINVAL);
}
- if (cur_ops->init != NULL)
+ if (cur_ops->init)
cur_ops->init(); /* no "goto unwind" prior to this point!!! */
if (nreaders >= 0)
@@ -899,7 +896,7 @@
/* Set up the freelist. */
INIT_LIST_HEAD(&rcu_torture_freelist);
- for (i = 0; i < sizeof(rcu_tortures) / sizeof(rcu_tortures[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(rcu_tortures); i++) {
rcu_tortures[i].rtort_mbtest = 0;
list_add_tail(&rcu_tortures[i].rtort_free,
&rcu_torture_freelist);
diff --git a/kernel/rwsem.c b/kernel/rwsem.c
index 291ded5..9a87886 100644
--- a/kernel/rwsem.c
+++ b/kernel/rwsem.c
@@ -60,7 +60,7 @@
int ret = __down_write_trylock(sem);
if (ret == 1)
- rwsem_acquire(&sem->dep_map, 0, 0, _RET_IP_);
+ rwsem_acquire(&sem->dep_map, 0, 1, _RET_IP_);
return ret;
}
diff --git a/kernel/sched.c b/kernel/sched.c
index 0227f16..a3a0408 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -52,8 +52,9 @@
#include <linux/tsacct_kern.h>
#include <linux/kprobes.h>
#include <linux/delayacct.h>
-#include <asm/tlb.h>
+#include <linux/reciprocal_div.h>
+#include <asm/tlb.h>
#include <asm/unistd.h>
/*
@@ -168,7 +169,7 @@
(MAX_BONUS / 2 + DELTA((p)) + 1) / MAX_BONUS - 1))
#define TASK_PREEMPTS_CURR(p, rq) \
- ((p)->prio < (rq)->curr->prio)
+ (((p)->prio < (rq)->curr->prio) && ((p)->array == (rq)->active))
#define SCALE_PRIO(x, prio) \
max(x * (MAX_PRIO - prio) / (MAX_USER_PRIO / 2), MIN_TIMESLICE)
@@ -181,6 +182,27 @@
return SCALE_PRIO(DEF_TIMESLICE, static_prio);
}
+#ifdef CONFIG_SMP
+/*
+ * Divide a load by a sched group cpu_power : (load / sg->__cpu_power)
+ * Since cpu_power is a 'constant', we can use a reciprocal divide.
+ */
+static inline u32 sg_div_cpu_power(const struct sched_group *sg, u32 load)
+{
+ return reciprocal_divide(load, sg->reciprocal_cpu_power);
+}
+
+/*
+ * Each time a sched group cpu_power is changed,
+ * we must compute its reciprocal value
+ */
+static inline void sg_inc_cpu_power(struct sched_group *sg, u32 val)
+{
+ sg->__cpu_power += val;
+ sg->reciprocal_cpu_power = reciprocal_value(sg->__cpu_power);
+}
+#endif
+
/*
* task_timeslice() scales user-nice values [ -20 ... 0 ... 19 ]
* to time slice values: [800ms ... 100ms ... 5ms]
@@ -223,6 +245,10 @@
unsigned long raw_weighted_load;
#ifdef CONFIG_SMP
unsigned long cpu_load[3];
+ unsigned char idle_at_tick;
+#ifdef CONFIG_NO_HZ
+ unsigned char in_nohz_recently;
+#endif
#endif
unsigned long long nr_switches;
@@ -278,7 +304,7 @@
struct lock_class_key rq_lock_key;
};
-static DEFINE_PER_CPU(struct rq, runqueues);
+static DEFINE_PER_CPU(struct rq, runqueues) ____cacheline_aligned_in_smp;
static inline int cpu_of(struct rq *rq)
{
@@ -1049,6 +1075,17 @@
if (!tsk_is_polling(p))
smp_send_reschedule(cpu);
}
+
+static void resched_cpu(int cpu)
+{
+ struct rq *rq = cpu_rq(cpu);
+ unsigned long flags;
+
+ if (!spin_trylock_irqsave(&rq->lock, flags))
+ return;
+ resched_task(cpu_curr(cpu));
+ spin_unlock_irqrestore(&rq->lock, flags);
+}
#else
static inline void resched_task(struct task_struct *p)
{
@@ -1241,7 +1278,8 @@
}
/* Adjust by relative CPU power of the group */
- avg_load = (avg_load * SCHED_LOAD_SCALE) / group->cpu_power;
+ avg_load = sg_div_cpu_power(group,
+ avg_load * SCHED_LOAD_SCALE);
if (local_group) {
this_load = avg_load;
@@ -1368,7 +1406,16 @@
struct sched_domain *sd;
int i;
- if (idle_cpu(cpu))
+ /*
+ * If it is idle, then it is the best cpu to run this task.
+ *
+ * This cpu is also the best, if it has more than one task already.
+ * Siblings must be also busy(in most cases) as they didn't already
+ * pickup the extra load from this cpu and hence we need not check
+ * sibling runqueue info. This will avoid the checks and cache miss
+ * penalities associated with that.
+ */
+ if (idle_cpu(cpu) || cpu_rq(cpu)->nr_running > 1)
return cpu;
for_each_domain(cpu, sd) {
@@ -2352,12 +2399,13 @@
}
total_load += avg_load;
- total_pwr += group->cpu_power;
+ total_pwr += group->__cpu_power;
/* Adjust by relative CPU power of the group */
- avg_load = (avg_load * SCHED_LOAD_SCALE) / group->cpu_power;
+ avg_load = sg_div_cpu_power(group,
+ avg_load * SCHED_LOAD_SCALE);
- group_capacity = group->cpu_power / SCHED_LOAD_SCALE;
+ group_capacity = group->__cpu_power / SCHED_LOAD_SCALE;
if (local_group) {
this_load = avg_load;
@@ -2468,8 +2516,8 @@
max_pull = min(max_load - avg_load, max_load - busiest_load_per_task);
/* How much load to actually move to equalise the imbalance */
- *imbalance = min(max_pull * busiest->cpu_power,
- (avg_load - this_load) * this->cpu_power)
+ *imbalance = min(max_pull * busiest->__cpu_power,
+ (avg_load - this_load) * this->__cpu_power)
/ SCHED_LOAD_SCALE;
/*
@@ -2503,28 +2551,29 @@
* moving them.
*/
- pwr_now += busiest->cpu_power *
- min(busiest_load_per_task, max_load);
- pwr_now += this->cpu_power *
- min(this_load_per_task, this_load);
+ pwr_now += busiest->__cpu_power *
+ min(busiest_load_per_task, max_load);
+ pwr_now += this->__cpu_power *
+ min(this_load_per_task, this_load);
pwr_now /= SCHED_LOAD_SCALE;
/* Amount of load we'd subtract */
- tmp = busiest_load_per_task * SCHED_LOAD_SCALE /
- busiest->cpu_power;
+ tmp = sg_div_cpu_power(busiest,
+ busiest_load_per_task * SCHED_LOAD_SCALE);
if (max_load > tmp)
- pwr_move += busiest->cpu_power *
+ pwr_move += busiest->__cpu_power *
min(busiest_load_per_task, max_load - tmp);
/* Amount of load we'd add */
- if (max_load * busiest->cpu_power <
+ if (max_load * busiest->__cpu_power <
busiest_load_per_task * SCHED_LOAD_SCALE)
- tmp = max_load * busiest->cpu_power / this->cpu_power;
+ tmp = sg_div_cpu_power(this,
+ max_load * busiest->__cpu_power);
else
- tmp = busiest_load_per_task * SCHED_LOAD_SCALE /
- this->cpu_power;
- pwr_move += this->cpu_power *
- min(this_load_per_task, this_load + tmp);
+ tmp = sg_div_cpu_power(this,
+ busiest_load_per_task * SCHED_LOAD_SCALE);
+ pwr_move += this->__cpu_power *
+ min(this_load_per_task, this_load + tmp);
pwr_move /= SCHED_LOAD_SCALE;
/* Move if we gain throughput */
@@ -2657,6 +2706,12 @@
double_rq_unlock(this_rq, busiest);
local_irq_restore(flags);
+ /*
+ * some other cpu did the load balance for us.
+ */
+ if (nr_moved && this_cpu != smp_processor_id())
+ resched_cpu(this_cpu);
+
/* All tasks on this runqueue were pinned by CPU affinity */
if (unlikely(all_pinned)) {
cpu_clear(cpu_of(busiest), cpus);
@@ -2927,32 +2982,98 @@
}
}
+#ifdef CONFIG_NO_HZ
+static struct {
+ atomic_t load_balancer;
+ cpumask_t cpu_mask;
+} nohz ____cacheline_aligned = {
+ .load_balancer = ATOMIC_INIT(-1),
+ .cpu_mask = CPU_MASK_NONE,
+};
+
/*
- * run_rebalance_domains is triggered when needed from the scheduler tick.
+ * This routine will try to nominate the ilb (idle load balancing)
+ * owner among the cpus whose ticks are stopped. ilb owner will do the idle
+ * load balancing on behalf of all those cpus. If all the cpus in the system
+ * go into this tickless mode, then there will be no ilb owner (as there is
+ * no need for one) and all the cpus will sleep till the next wakeup event
+ * arrives...
*
+ * For the ilb owner, tick is not stopped. And this tick will be used
+ * for idle load balancing. ilb owner will still be part of
+ * nohz.cpu_mask..
+ *
+ * While stopping the tick, this cpu will become the ilb owner if there
+ * is no other owner. And will be the owner till that cpu becomes busy
+ * or if all cpus in the system stop their ticks at which point
+ * there is no need for ilb owner.
+ *
+ * When the ilb owner becomes busy, it nominates another owner, during the
+ * next busy scheduler_tick()
+ */
+int select_nohz_load_balancer(int stop_tick)
+{
+ int cpu = smp_processor_id();
+
+ if (stop_tick) {
+ cpu_set(cpu, nohz.cpu_mask);
+ cpu_rq(cpu)->in_nohz_recently = 1;
+
+ /*
+ * If we are going offline and still the leader, give up!
+ */
+ if (cpu_is_offline(cpu) &&
+ atomic_read(&nohz.load_balancer) == cpu) {
+ if (atomic_cmpxchg(&nohz.load_balancer, cpu, -1) != cpu)
+ BUG();
+ return 0;
+ }
+
+ /* time for ilb owner also to sleep */
+ if (cpus_weight(nohz.cpu_mask) == num_online_cpus()) {
+ if (atomic_read(&nohz.load_balancer) == cpu)
+ atomic_set(&nohz.load_balancer, -1);
+ return 0;
+ }
+
+ if (atomic_read(&nohz.load_balancer) == -1) {
+ /* make me the ilb owner */
+ if (atomic_cmpxchg(&nohz.load_balancer, -1, cpu) == -1)
+ return 1;
+ } else if (atomic_read(&nohz.load_balancer) == cpu)
+ return 1;
+ } else {
+ if (!cpu_isset(cpu, nohz.cpu_mask))
+ return 0;
+
+ cpu_clear(cpu, nohz.cpu_mask);
+
+ if (atomic_read(&nohz.load_balancer) == cpu)
+ if (atomic_cmpxchg(&nohz.load_balancer, cpu, -1) != cpu)
+ BUG();
+ }
+ return 0;
+}
+#endif
+
+static DEFINE_SPINLOCK(balancing);
+
+/*
* It checks each scheduling domain to see if it is due to be balanced,
* and initiates a balancing operation if so.
*
* Balancing parameters are set up in arch_init_sched_domains.
*/
-static DEFINE_SPINLOCK(balancing);
-
-static void run_rebalance_domains(struct softirq_action *h)
+static inline void rebalance_domains(int cpu, enum idle_type idle)
{
- int this_cpu = smp_processor_id(), balance = 1;
- struct rq *this_rq = cpu_rq(this_cpu);
+ int balance = 1;
+ struct rq *rq = cpu_rq(cpu);
unsigned long interval;
struct sched_domain *sd;
- /*
- * We are idle if there are no processes running. This
- * is valid even if we are the idle process (SMT).
- */
- enum idle_type idle = !this_rq->nr_running ?
- SCHED_IDLE : NOT_IDLE;
- /* Earliest time when we have to call run_rebalance_domains again */
+ /* Earliest time when we have to do rebalance again */
unsigned long next_balance = jiffies + 60*HZ;
- for_each_domain(this_cpu, sd) {
+ for_each_domain(cpu, sd) {
if (!(sd->flags & SD_LOAD_BALANCE))
continue;
@@ -2971,7 +3092,7 @@
}
if (time_after_eq(jiffies, sd->last_balance + interval)) {
- if (load_balance(this_cpu, this_rq, sd, idle, &balance)) {
+ if (load_balance(cpu, rq, sd, idle, &balance)) {
/*
* We've pulled tasks over so either we're no
* longer idle, or one of our SMT siblings is
@@ -2995,7 +3116,114 @@
if (!balance)
break;
}
- this_rq->next_balance = next_balance;
+ rq->next_balance = next_balance;
+}
+
+/*
+ * run_rebalance_domains is triggered when needed from the scheduler tick.
+ * In CONFIG_NO_HZ case, the idle load balance owner will do the
+ * rebalancing for all the cpus for whom scheduler ticks are stopped.
+ */
+static void run_rebalance_domains(struct softirq_action *h)
+{
+ int local_cpu = smp_processor_id();
+ struct rq *local_rq = cpu_rq(local_cpu);
+ enum idle_type idle = local_rq->idle_at_tick ? SCHED_IDLE : NOT_IDLE;
+
+ rebalance_domains(local_cpu, idle);
+
+#ifdef CONFIG_NO_HZ
+ /*
+ * If this cpu is the owner for idle load balancing, then do the
+ * balancing on behalf of the other idle cpus whose ticks are
+ * stopped.
+ */
+ if (local_rq->idle_at_tick &&
+ atomic_read(&nohz.load_balancer) == local_cpu) {
+ cpumask_t cpus = nohz.cpu_mask;
+ struct rq *rq;
+ int balance_cpu;
+
+ cpu_clear(local_cpu, cpus);
+ for_each_cpu_mask(balance_cpu, cpus) {
+ /*
+ * If this cpu gets work to do, stop the load balancing
+ * work being done for other cpus. Next load
+ * balancing owner will pick it up.
+ */
+ if (need_resched())
+ break;
+
+ rebalance_domains(balance_cpu, SCHED_IDLE);
+
+ rq = cpu_rq(balance_cpu);
+ if (time_after(local_rq->next_balance, rq->next_balance))
+ local_rq->next_balance = rq->next_balance;
+ }
+ }
+#endif
+}
+
+/*
+ * Trigger the SCHED_SOFTIRQ if it is time to do periodic load balancing.
+ *
+ * In case of CONFIG_NO_HZ, this is the place where we nominate a new
+ * idle load balancing owner or decide to stop the periodic load balancing,
+ * if the whole system is idle.
+ */
+static inline void trigger_load_balance(int cpu)
+{
+ struct rq *rq = cpu_rq(cpu);
+#ifdef CONFIG_NO_HZ
+ /*
+ * If we were in the nohz mode recently and busy at the current
+ * scheduler tick, then check if we need to nominate new idle
+ * load balancer.
+ */
+ if (rq->in_nohz_recently && !rq->idle_at_tick) {
+ rq->in_nohz_recently = 0;
+
+ if (atomic_read(&nohz.load_balancer) == cpu) {
+ cpu_clear(cpu, nohz.cpu_mask);
+ atomic_set(&nohz.load_balancer, -1);
+ }
+
+ if (atomic_read(&nohz.load_balancer) == -1) {
+ /*
+ * simple selection for now: Nominate the
+ * first cpu in the nohz list to be the next
+ * ilb owner.
+ *
+ * TBD: Traverse the sched domains and nominate
+ * the nearest cpu in the nohz.cpu_mask.
+ */
+ int ilb = first_cpu(nohz.cpu_mask);
+
+ if (ilb != NR_CPUS)
+ resched_cpu(ilb);
+ }
+ }
+
+ /*
+ * If this cpu is idle and doing idle load balancing for all the
+ * cpus with ticks stopped, is it time for that to stop?
+ */
+ if (rq->idle_at_tick && atomic_read(&nohz.load_balancer) == cpu &&
+ cpus_weight(nohz.cpu_mask) == num_online_cpus()) {
+ resched_cpu(cpu);
+ return;
+ }
+
+ /*
+ * If this cpu is idle and the idle load balancing is done by
+ * someone else, then no need raise the SCHED_SOFTIRQ
+ */
+ if (rq->idle_at_tick && atomic_read(&nohz.load_balancer) != cpu &&
+ cpu_isset(cpu, nohz.cpu_mask))
+ return;
+#endif
+ if (time_after_eq(jiffies, rq->next_balance))
+ raise_softirq(SCHED_SOFTIRQ);
}
#else
/*
@@ -3218,16 +3446,17 @@
unsigned long long now = sched_clock();
struct task_struct *p = current;
int cpu = smp_processor_id();
+ int idle_at_tick = idle_cpu(cpu);
struct rq *rq = cpu_rq(cpu);
update_cpu_clock(p, rq, now);
- if (p != rq->idle)
+ if (!idle_at_tick)
task_running_tick(rq, p);
#ifdef CONFIG_SMP
update_load(rq);
- if (time_after_eq(jiffies, rq->next_balance))
- raise_softirq(SCHED_SOFTIRQ);
+ rq->idle_at_tick = idle_at_tick;
+ trigger_load_balance(cpu);
#endif
}
@@ -3847,13 +4076,13 @@
struct prio_array *array;
unsigned long flags;
struct rq *rq;
- int oldprio;
+ int delta;
BUG_ON(prio < 0 || prio > MAX_PRIO);
rq = task_rq_lock(p, &flags);
- oldprio = p->prio;
+ delta = prio - p->prio;
array = p->array;
if (array)
dequeue_task(p, array);
@@ -3869,13 +4098,11 @@
enqueue_task(p, array);
/*
* Reschedule if we are currently running on this runqueue and
- * our priority decreased, or if we are not currently running on
- * this runqueue and our priority is higher than the current's
+ * our priority decreased, or if our priority became higher
+ * than the current's.
*/
- if (task_running(rq, p)) {
- if (p->prio > oldprio)
- resched_task(rq->curr);
- } else if (TASK_PREEMPTS_CURR(p, rq))
+ if (TASK_PREEMPTS_CURR(p, rq) ||
+ (delta > 0 && task_running(rq, p)))
resched_task(rq->curr);
}
task_rq_unlock(rq, &flags);
@@ -3923,10 +4150,12 @@
enqueue_task(p, array);
inc_raw_weighted_load(rq, p);
/*
- * If the task increased its priority or is running and
- * lowered its priority, then reschedule its CPU:
+ * Reschedule if we are currently running on this runqueue and
+ * our priority decreased, or if our priority became higher
+ * than the current's.
*/
- if (delta < 0 || (delta > 0 && task_running(rq, p)))
+ if (TASK_PREEMPTS_CURR(p, rq) ||
+ (delta > 0 && task_running(rq, p)))
resched_task(rq->curr);
}
out_unlock:
@@ -4153,13 +4382,11 @@
__activate_task(p, rq);
/*
* Reschedule if we are currently running on this runqueue and
- * our priority decreased, or if we are not currently running on
- * this runqueue and our priority is higher than the current's
+ * our priority decreased, or our priority became higher
+ * than the current's.
*/
- if (task_running(rq, p)) {
- if (p->prio > oldprio)
- resched_task(rq->curr);
- } else if (TASK_PREEMPTS_CURR(p, rq))
+ if (TASK_PREEMPTS_CURR(p, rq) ||
+ (task_running(rq, p) && p->prio > oldprio))
resched_task(rq->curr);
}
__task_rq_unlock(rq);
@@ -4750,6 +4977,8 @@
show_task(p);
} while_each_thread(g, p);
+ touch_all_softlockup_watchdogs();
+
read_unlock(&tasklist_lock);
/*
* Only show locks if all tasks are dumped:
@@ -5304,7 +5533,7 @@
break;
}
- if (!group->cpu_power) {
+ if (!group->__cpu_power) {
printk("\n");
printk(KERN_ERR "ERROR: domain->cpu_power not "
"set\n");
@@ -5481,7 +5710,7 @@
continue;
sg->cpumask = CPU_MASK_NONE;
- sg->cpu_power = 0;
+ sg->__cpu_power = 0;
for_each_cpu_mask(j, span) {
if (group_fn(j, cpu_map, NULL) != group)
@@ -6170,7 +6399,7 @@
continue;
}
- sg->cpu_power += sd->groups->cpu_power;
+ sg_inc_cpu_power(sg, sd->groups->__cpu_power);
}
sg = sg->next;
if (sg != group_head)
@@ -6245,6 +6474,8 @@
child = sd->child;
+ sd->groups->__cpu_power = 0;
+
/*
* For perf policy, if the groups in child domain share resources
* (for example cores sharing some portions of the cache hierarchy
@@ -6255,18 +6486,16 @@
if (!child || (!(sd->flags & SD_POWERSAVINGS_BALANCE) &&
(child->flags &
(SD_SHARE_CPUPOWER | SD_SHARE_PKG_RESOURCES)))) {
- sd->groups->cpu_power = SCHED_LOAD_SCALE;
+ sg_inc_cpu_power(sd->groups, SCHED_LOAD_SCALE);
return;
}
- sd->groups->cpu_power = 0;
-
/*
* add cpu_power of each child group to this groups cpu_power
*/
group = child->groups;
do {
- sd->groups->cpu_power += group->cpu_power;
+ sg_inc_cpu_power(sd->groups, group->__cpu_power);
group = group->next;
} while (group != child->groups);
}
@@ -6426,7 +6655,7 @@
sd = &per_cpu(node_domains, j);
sd->groups = sg;
}
- sg->cpu_power = 0;
+ sg->__cpu_power = 0;
sg->cpumask = nodemask;
sg->next = sg;
cpus_or(covered, covered, nodemask);
@@ -6454,7 +6683,7 @@
"Can not alloc domain group for node %d\n", j);
goto error;
}
- sg->cpu_power = 0;
+ sg->__cpu_power = 0;
sg->cpumask = tmp;
sg->next = prev->next;
cpus_or(covered, covered, tmp);
diff --git a/kernel/signal.c b/kernel/signal.c
index 2b4087d..1368e67 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -12,7 +12,6 @@
#include <linux/slab.h>
#include <linux/module.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/fs.h>
diff --git a/kernel/softlockup.c b/kernel/softlockup.c
index 50afeb8..8fa7040 100644
--- a/kernel/softlockup.c
+++ b/kernel/softlockup.c
@@ -34,12 +34,32 @@
.notifier_call = softlock_panic,
};
+/*
+ * Returns seconds, approximately. We don't need nanosecond
+ * resolution, and we don't need to waste time with a big divide when
+ * 2^30ns == 1.074s.
+ */
+static unsigned long get_timestamp(void)
+{
+ return sched_clock() >> 30; /* 2^30 ~= 10^9 */
+}
+
void touch_softlockup_watchdog(void)
{
- __raw_get_cpu_var(touch_timestamp) = jiffies;
+ __raw_get_cpu_var(touch_timestamp) = get_timestamp();
}
EXPORT_SYMBOL(touch_softlockup_watchdog);
+void touch_all_softlockup_watchdogs(void)
+{
+ int cpu;
+
+ /* Cause each CPU to re-update its timestamp rather than complain */
+ for_each_online_cpu(cpu)
+ per_cpu(touch_timestamp, cpu) = 0;
+}
+EXPORT_SYMBOL(touch_all_softlockup_watchdogs);
+
/*
* This callback runs from the timer interrupt, and checks
* whether the watchdog thread has hung or not:
@@ -48,9 +68,18 @@
{
int this_cpu = smp_processor_id();
unsigned long touch_timestamp = per_cpu(touch_timestamp, this_cpu);
+ unsigned long print_timestamp;
+ unsigned long now;
- /* prevent double reports: */
- if (per_cpu(print_timestamp, this_cpu) == touch_timestamp ||
+ if (touch_timestamp == 0) {
+ touch_softlockup_watchdog();
+ return;
+ }
+
+ print_timestamp = per_cpu(print_timestamp, this_cpu);
+
+ /* report at most once a second */
+ if (print_timestamp < (touch_timestamp + 1) ||
did_panic ||
!per_cpu(watchdog_task, this_cpu))
return;
@@ -61,12 +90,14 @@
return;
}
+ now = get_timestamp();
+
/* Wake up the high-prio watchdog task every second: */
- if (time_after(jiffies, touch_timestamp + HZ))
+ if (now > (touch_timestamp + 1))
wake_up_process(per_cpu(watchdog_task, this_cpu));
/* Warn about unreasonable 10+ seconds delays: */
- if (time_after(jiffies, touch_timestamp + 10*HZ)) {
+ if (now > (touch_timestamp + 10)) {
per_cpu(print_timestamp, this_cpu) = touch_timestamp;
spin_lock(&print_lock);
@@ -82,11 +113,14 @@
*/
static int watchdog(void * __bind_cpu)
{
- struct sched_param param = { .sched_priority = 99 };
+ struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
sched_setscheduler(current, SCHED_FIFO, ¶m);
current->flags |= PF_NOFREEZE;
+ /* initialize timestamp */
+ touch_softlockup_watchdog();
+
/*
* Run briefly once per second to reset the softlockup timestamp.
* If this gets delayed for more than 10 seconds then the
@@ -118,7 +152,7 @@
printk("watchdog for %i failed\n", hotcpu);
return NOTIFY_BAD;
}
- per_cpu(touch_timestamp, hotcpu) = jiffies;
+ per_cpu(touch_timestamp, hotcpu) = 0;
per_cpu(watchdog_task, hotcpu) = p;
kthread_bind(p, hotcpu);
break;
diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c
index 1245804..daabb74 100644
--- a/kernel/stop_machine.c
+++ b/kernel/stop_machine.c
@@ -1,11 +1,12 @@
/* Copyright 2005 Rusty Russell rusty@rustcorp.com.au IBM Corporation.
* GPL v2 and any later version.
*/
-#include <linux/stop_machine.h>
-#include <linux/kthread.h>
-#include <linux/sched.h>
#include <linux/cpu.h>
#include <linux/err.h>
+#include <linux/kthread.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/stop_machine.h>
#include <linux/syscalls.h>
#include <asm/atomic.h>
#include <asm/semaphore.h>
@@ -208,3 +209,4 @@
return ret;
}
+EXPORT_SYMBOL_GPL(stop_machine_run);
diff --git a/kernel/sys.c b/kernel/sys.c
index fe1f3ab..926bf9d 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1923,6 +1923,16 @@
if (retval)
return retval;
+ if (resource == RLIMIT_CPU && new_rlim.rlim_cur == 0) {
+ /*
+ * The caller is asking for an immediate RLIMIT_CPU
+ * expiry. But we use the zero value to mean "it was
+ * never set". So let's cheat and make it one second
+ * instead
+ */
+ new_rlim.rlim_cur = 1;
+ }
+
task_lock(current->group_leader);
*old_rlim = new_rlim;
task_unlock(current->group_leader);
@@ -1944,15 +1954,6 @@
unsigned long rlim_cur = new_rlim.rlim_cur;
cputime_t cputime;
- if (rlim_cur == 0) {
- /*
- * The caller is asking for an immediate RLIMIT_CPU
- * expiry. But we use the zero value to mean "it was
- * never set". So let's cheat and make it one second
- * instead
- */
- rlim_cur = 1;
- }
cputime = secs_to_cputime(rlim_cur);
read_lock(&tasklist_lock);
spin_lock_irq(¤t->sighand->siglock);
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index c904748..f0664bd 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -76,6 +76,7 @@
extern int sysctl_drop_caches;
extern int percpu_pagelist_fraction;
extern int compat_log;
+extern int maps_protect;
/* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
static int maxolduid = 65535;
@@ -603,6 +604,16 @@
.proc_handler = &proc_dointvec,
},
#endif
+#ifdef CONFIG_PROC_FS
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "maps_protect",
+ .data = &maps_protect,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
+#endif
{ .ctl_name = 0 }
};
diff --git a/kernel/time.c b/kernel/time.c
index ba18ec4..f04791f 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -31,7 +31,6 @@
#include <linux/timex.h>
#include <linux/capability.h>
#include <linux/errno.h>
-#include <linux/smp_lock.h>
#include <linux/syscalls.h>
#include <linux/security.h>
#include <linux/fs.h>
@@ -247,6 +246,36 @@
}
EXPORT_SYMBOL(current_fs_time);
+/*
+ * Convert jiffies to milliseconds and back.
+ *
+ * Avoid unnecessary multiplications/divisions in the
+ * two most common HZ cases:
+ */
+unsigned int inline jiffies_to_msecs(const unsigned long j)
+{
+#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
+ return (MSEC_PER_SEC / HZ) * j;
+#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
+ return (j + (HZ / MSEC_PER_SEC) - 1)/(HZ / MSEC_PER_SEC);
+#else
+ return (j * MSEC_PER_SEC) / HZ;
+#endif
+}
+EXPORT_SYMBOL(jiffies_to_msecs);
+
+unsigned int inline jiffies_to_usecs(const unsigned long j)
+{
+#if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
+ return (USEC_PER_SEC / HZ) * j;
+#elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC)
+ return (j + (HZ / USEC_PER_SEC) - 1)/(HZ / USEC_PER_SEC);
+#else
+ return (j * USEC_PER_SEC) / HZ;
+#endif
+}
+EXPORT_SYMBOL(jiffies_to_usecs);
+
/**
* timespec_trunc - Truncate timespec to a granularity
* @t: Timespec
@@ -473,36 +502,6 @@
EXPORT_SYMBOL(ns_to_timeval);
/*
- * Convert jiffies to milliseconds and back.
- *
- * Avoid unnecessary multiplications/divisions in the
- * two most common HZ cases:
- */
-unsigned int jiffies_to_msecs(const unsigned long j)
-{
-#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
- return (MSEC_PER_SEC / HZ) * j;
-#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
- return (j + (HZ / MSEC_PER_SEC) - 1)/(HZ / MSEC_PER_SEC);
-#else
- return (j * MSEC_PER_SEC) / HZ;
-#endif
-}
-EXPORT_SYMBOL(jiffies_to_msecs);
-
-unsigned int jiffies_to_usecs(const unsigned long j)
-{
-#if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
- return (USEC_PER_SEC / HZ) * j;
-#elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC)
- return (j + (HZ / USEC_PER_SEC) - 1)/(HZ / USEC_PER_SEC);
-#else
- return (j * USEC_PER_SEC) / HZ;
-#endif
-}
-EXPORT_SYMBOL(jiffies_to_usecs);
-
-/*
* When we convert to jiffies then we interpret incoming values
* the following way:
*
diff --git a/kernel/time/Makefile b/kernel/time/Makefile
index 93bccba..99b6034 100644
--- a/kernel/time/Makefile
+++ b/kernel/time/Makefile
@@ -1,4 +1,4 @@
-obj-y += ntp.o clocksource.o jiffies.o timer_list.o
+obj-y += timekeeping.o ntp.o clocksource.o jiffies.o timer_list.o
obj-$(CONFIG_GENERIC_CLOCKEVENTS) += clockevents.o
obj-$(CONFIG_GENERIC_CLOCKEVENTS) += tick-common.o
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
index bfda3f7..a96ec9a 100644
--- a/kernel/time/tick-common.c
+++ b/kernel/time/tick-common.c
@@ -31,7 +31,7 @@
*/
ktime_t tick_next_period;
ktime_t tick_period;
-static int tick_do_timer_cpu = -1;
+int tick_do_timer_cpu __read_mostly = -1;
DEFINE_SPINLOCK(tick_device_lock);
/*
@@ -295,6 +295,12 @@
clockevents_exchange_device(dev, NULL);
td->evtdev = NULL;
}
+ /* Transfer the do_timer job away from this cpu */
+ if (*cpup == tick_do_timer_cpu) {
+ int cpu = first_cpu(cpu_online_map);
+
+ tick_do_timer_cpu = (cpu != NR_CPUS) ? cpu : -1;
+ }
spin_unlock_irqrestore(&tick_device_lock, flags);
}
diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h
index c9d203b..bb13f27 100644
--- a/kernel/time/tick-internal.h
+++ b/kernel/time/tick-internal.h
@@ -5,6 +5,7 @@
extern spinlock_t tick_device_lock;
extern ktime_t tick_next_period;
extern ktime_t tick_period;
+extern int tick_do_timer_cpu __read_mostly;
extern void tick_setup_periodic(struct clock_event_device *dev, int broadcast);
extern void tick_handle_periodic(struct clock_event_device *dev);
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 51556b9..3483e6c 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -217,10 +217,30 @@
* the scheduler tick in nohz_restart_sched_tick.
*/
if (!ts->tick_stopped) {
+ if (select_nohz_load_balancer(1)) {
+ /*
+ * sched tick not stopped!
+ */
+ cpu_clear(cpu, nohz_cpu_mask);
+ goto out;
+ }
+
ts->idle_tick = ts->sched_timer.expires;
ts->tick_stopped = 1;
ts->idle_jiffies = last_jiffies;
}
+
+ /*
+ * If this cpu is the one which updates jiffies, then
+ * give up the assignment and let it be taken by the
+ * cpu which runs the tick timer next, which might be
+ * this cpu as well. If we don't drop this here the
+ * jiffies might be stale and do_timer() never
+ * invoked.
+ */
+ if (cpu == tick_do_timer_cpu)
+ tick_do_timer_cpu = -1;
+
/*
* calculate the expiry time for the next timer wheel
* timer
@@ -273,6 +293,7 @@
now = ktime_get();
local_irq_disable();
+ select_nohz_load_balancer(0);
tick_do_update_jiffies64(now);
cpu_clear(cpu, nohz_cpu_mask);
@@ -338,12 +359,24 @@
{
struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched);
struct pt_regs *regs = get_irq_regs();
+ int cpu = smp_processor_id();
ktime_t now = ktime_get();
dev->next_event.tv64 = KTIME_MAX;
+ /*
+ * Check if the do_timer duty was dropped. We don't care about
+ * concurrency: This happens only when the cpu in charge went
+ * into a long sleep. If two cpus happen to assign themself to
+ * this duty, then the jiffies update is still serialized by
+ * xtime_lock.
+ */
+ if (unlikely(tick_do_timer_cpu == -1))
+ tick_do_timer_cpu = cpu;
+
/* Check, if the jiffies need an update */
- tick_do_update_jiffies64(now);
+ if (tick_do_timer_cpu == cpu)
+ tick_do_update_jiffies64(now);
/*
* When we are idle and the tick is stopped, we have to touch
@@ -431,9 +464,23 @@
struct hrtimer_cpu_base *base = timer->base->cpu_base;
struct pt_regs *regs = get_irq_regs();
ktime_t now = ktime_get();
+ int cpu = smp_processor_id();
+
+#ifdef CONFIG_NO_HZ
+ /*
+ * Check if the do_timer duty was dropped. We don't care about
+ * concurrency: This happens only when the cpu in charge went
+ * into a long sleep. If two cpus happen to assign themself to
+ * this duty, then the jiffies update is still serialized by
+ * xtime_lock.
+ */
+ if (unlikely(tick_do_timer_cpu == -1))
+ tick_do_timer_cpu = cpu;
+#endif
/* Check, if the jiffies need an update */
- tick_do_update_jiffies64(now);
+ if (tick_do_timer_cpu == cpu)
+ tick_do_update_jiffies64(now);
/*
* Do not call, when we are not in irq context and have
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
new file mode 100644
index 0000000..f9217bf
--- /dev/null
+++ b/kernel/time/timekeeping.c
@@ -0,0 +1,476 @@
+/*
+ * linux/kernel/time/timekeeping.c
+ *
+ * Kernel timekeeping code and accessor functions
+ *
+ * This code was moved from linux/kernel/timer.c.
+ * Please see that file for copyright and history logs.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/percpu.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sysdev.h>
+#include <linux/clocksource.h>
+#include <linux/jiffies.h>
+#include <linux/time.h>
+#include <linux/tick.h>
+
+
+/*
+ * This read-write spinlock protects us from races in SMP while
+ * playing with xtime and avenrun.
+ */
+__attribute__((weak)) __cacheline_aligned_in_smp DEFINE_SEQLOCK(xtime_lock);
+
+EXPORT_SYMBOL(xtime_lock);
+
+
+/*
+ * The current time
+ * wall_to_monotonic is what we need to add to xtime (or xtime corrected
+ * for sub jiffie times) to get to monotonic time. Monotonic is pegged
+ * at zero at system boot time, so wall_to_monotonic will be negative,
+ * however, we will ALWAYS keep the tv_nsec part positive so we can use
+ * the usual normalization.
+ */
+struct timespec xtime __attribute__ ((aligned (16)));
+struct timespec wall_to_monotonic __attribute__ ((aligned (16)));
+
+EXPORT_SYMBOL(xtime);
+
+
+static struct clocksource *clock; /* pointer to current clocksource */
+
+
+#ifdef CONFIG_GENERIC_TIME
+/**
+ * __get_nsec_offset - Returns nanoseconds since last call to periodic_hook
+ *
+ * private function, must hold xtime_lock lock when being
+ * called. Returns the number of nanoseconds since the
+ * last call to update_wall_time() (adjusted by NTP scaling)
+ */
+static inline s64 __get_nsec_offset(void)
+{
+ cycle_t cycle_now, cycle_delta;
+ s64 ns_offset;
+
+ /* read clocksource: */
+ cycle_now = clocksource_read(clock);
+
+ /* calculate the delta since the last update_wall_time: */
+ cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;
+
+ /* convert to nanoseconds: */
+ ns_offset = cyc2ns(clock, cycle_delta);
+
+ return ns_offset;
+}
+
+/**
+ * __get_realtime_clock_ts - Returns the time of day in a timespec
+ * @ts: pointer to the timespec to be set
+ *
+ * Returns the time of day in a timespec. Used by
+ * do_gettimeofday() and get_realtime_clock_ts().
+ */
+static inline void __get_realtime_clock_ts(struct timespec *ts)
+{
+ unsigned long seq;
+ s64 nsecs;
+
+ do {
+ seq = read_seqbegin(&xtime_lock);
+
+ *ts = xtime;
+ nsecs = __get_nsec_offset();
+
+ } while (read_seqretry(&xtime_lock, seq));
+
+ timespec_add_ns(ts, nsecs);
+}
+
+/**
+ * getnstimeofday - Returns the time of day in a timespec
+ * @ts: pointer to the timespec to be set
+ *
+ * Returns the time of day in a timespec.
+ */
+void getnstimeofday(struct timespec *ts)
+{
+ __get_realtime_clock_ts(ts);
+}
+
+EXPORT_SYMBOL(getnstimeofday);
+
+/**
+ * do_gettimeofday - Returns the time of day in a timeval
+ * @tv: pointer to the timeval to be set
+ *
+ * NOTE: Users should be converted to using get_realtime_clock_ts()
+ */
+void do_gettimeofday(struct timeval *tv)
+{
+ struct timespec now;
+
+ __get_realtime_clock_ts(&now);
+ tv->tv_sec = now.tv_sec;
+ tv->tv_usec = now.tv_nsec/1000;
+}
+
+EXPORT_SYMBOL(do_gettimeofday);
+/**
+ * do_settimeofday - Sets the time of day
+ * @tv: pointer to the timespec variable containing the new time
+ *
+ * Sets the time of day to the new time and update NTP and notify hrtimers
+ */
+int do_settimeofday(struct timespec *tv)
+{
+ unsigned long flags;
+ time_t wtm_sec, sec = tv->tv_sec;
+ long wtm_nsec, nsec = tv->tv_nsec;
+
+ if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
+ return -EINVAL;
+
+ write_seqlock_irqsave(&xtime_lock, flags);
+
+ nsec -= __get_nsec_offset();
+
+ wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
+ wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
+
+ set_normalized_timespec(&xtime, sec, nsec);
+ set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
+
+ clock->error = 0;
+ ntp_clear();
+
+ update_vsyscall(&xtime, clock);
+
+ write_sequnlock_irqrestore(&xtime_lock, flags);
+
+ /* signal hrtimers about time change */
+ clock_was_set();
+
+ return 0;
+}
+
+EXPORT_SYMBOL(do_settimeofday);
+
+/**
+ * change_clocksource - Swaps clocksources if a new one is available
+ *
+ * Accumulates current time interval and initializes new clocksource
+ */
+static void change_clocksource(void)
+{
+ struct clocksource *new;
+ cycle_t now;
+ u64 nsec;
+
+ new = clocksource_get_next();
+
+ if (clock == new)
+ return;
+
+ now = clocksource_read(new);
+ nsec = __get_nsec_offset();
+ timespec_add_ns(&xtime, nsec);
+
+ clock = new;
+ clock->cycle_last = now;
+
+ clock->error = 0;
+ clock->xtime_nsec = 0;
+ clocksource_calculate_interval(clock, NTP_INTERVAL_LENGTH);
+
+ tick_clock_notify();
+
+ printk(KERN_INFO "Time: %s clocksource has been installed.\n",
+ clock->name);
+}
+#else
+static inline void change_clocksource(void) { }
+#endif
+
+/**
+ * timekeeping_is_continuous - check to see if timekeeping is free running
+ */
+int timekeeping_is_continuous(void)
+{
+ unsigned long seq;
+ int ret;
+
+ do {
+ seq = read_seqbegin(&xtime_lock);
+
+ ret = clock->flags & CLOCK_SOURCE_VALID_FOR_HRES;
+
+ } while (read_seqretry(&xtime_lock, seq));
+
+ return ret;
+}
+
+/**
+ * read_persistent_clock - Return time in seconds from the persistent clock.
+ *
+ * Weak dummy function for arches that do not yet support it.
+ * Returns seconds from epoch using the battery backed persistent clock.
+ * Returns zero if unsupported.
+ *
+ * XXX - Do be sure to remove it once all arches implement it.
+ */
+unsigned long __attribute__((weak)) read_persistent_clock(void)
+{
+ return 0;
+}
+
+/*
+ * timekeeping_init - Initializes the clocksource and common timekeeping values
+ */
+void __init timekeeping_init(void)
+{
+ unsigned long flags;
+ unsigned long sec = read_persistent_clock();
+
+ write_seqlock_irqsave(&xtime_lock, flags);
+
+ ntp_clear();
+
+ clock = clocksource_get_next();
+ clocksource_calculate_interval(clock, NTP_INTERVAL_LENGTH);
+ clock->cycle_last = clocksource_read(clock);
+
+ xtime.tv_sec = sec;
+ xtime.tv_nsec = 0;
+ set_normalized_timespec(&wall_to_monotonic,
+ -xtime.tv_sec, -xtime.tv_nsec);
+
+ write_sequnlock_irqrestore(&xtime_lock, flags);
+}
+
+/* flag for if timekeeping is suspended */
+static int timekeeping_suspended;
+/* time in seconds when suspend began */
+static unsigned long timekeeping_suspend_time;
+
+/**
+ * timekeeping_resume - Resumes the generic timekeeping subsystem.
+ * @dev: unused
+ *
+ * This is for the generic clocksource timekeeping.
+ * xtime/wall_to_monotonic/jiffies/etc are
+ * still managed by arch specific suspend/resume code.
+ */
+static int timekeeping_resume(struct sys_device *dev)
+{
+ unsigned long flags;
+ unsigned long now = read_persistent_clock();
+
+ write_seqlock_irqsave(&xtime_lock, flags);
+
+ if (now && (now > timekeeping_suspend_time)) {
+ unsigned long sleep_length = now - timekeeping_suspend_time;
+
+ xtime.tv_sec += sleep_length;
+ wall_to_monotonic.tv_sec -= sleep_length;
+ }
+ /* re-base the last cycle value */
+ clock->cycle_last = clocksource_read(clock);
+ clock->error = 0;
+ timekeeping_suspended = 0;
+ write_sequnlock_irqrestore(&xtime_lock, flags);
+
+ touch_softlockup_watchdog();
+
+ clockevents_notify(CLOCK_EVT_NOTIFY_RESUME, NULL);
+
+ /* Resume hrtimers */
+ hres_timers_resume();
+
+ return 0;
+}
+
+static int timekeeping_suspend(struct sys_device *dev, pm_message_t state)
+{
+ unsigned long flags;
+
+ write_seqlock_irqsave(&xtime_lock, flags);
+ timekeeping_suspended = 1;
+ timekeeping_suspend_time = read_persistent_clock();
+ write_sequnlock_irqrestore(&xtime_lock, flags);
+
+ clockevents_notify(CLOCK_EVT_NOTIFY_SUSPEND, NULL);
+
+ return 0;
+}
+
+/* sysfs resume/suspend bits for timekeeping */
+static struct sysdev_class timekeeping_sysclass = {
+ .resume = timekeeping_resume,
+ .suspend = timekeeping_suspend,
+ set_kset_name("timekeeping"),
+};
+
+static struct sys_device device_timer = {
+ .id = 0,
+ .cls = &timekeeping_sysclass,
+};
+
+static int __init timekeeping_init_device(void)
+{
+ int error = sysdev_class_register(&timekeeping_sysclass);
+ if (!error)
+ error = sysdev_register(&device_timer);
+ return error;
+}
+
+device_initcall(timekeeping_init_device);
+
+/*
+ * If the error is already larger, we look ahead even further
+ * to compensate for late or lost adjustments.
+ */
+static __always_inline int clocksource_bigadjust(s64 error, s64 *interval,
+ s64 *offset)
+{
+ s64 tick_error, i;
+ u32 look_ahead, adj;
+ s32 error2, mult;
+
+ /*
+ * Use the current error value to determine how much to look ahead.
+ * The larger the error the slower we adjust for it to avoid problems
+ * with losing too many ticks, otherwise we would overadjust and
+ * produce an even larger error. The smaller the adjustment the
+ * faster we try to adjust for it, as lost ticks can do less harm
+ * here. This is tuned so that an error of about 1 msec is adusted
+ * within about 1 sec (or 2^20 nsec in 2^SHIFT_HZ ticks).
+ */
+ error2 = clock->error >> (TICK_LENGTH_SHIFT + 22 - 2 * SHIFT_HZ);
+ error2 = abs(error2);
+ for (look_ahead = 0; error2 > 0; look_ahead++)
+ error2 >>= 2;
+
+ /*
+ * Now calculate the error in (1 << look_ahead) ticks, but first
+ * remove the single look ahead already included in the error.
+ */
+ tick_error = current_tick_length() >>
+ (TICK_LENGTH_SHIFT - clock->shift + 1);
+ tick_error -= clock->xtime_interval >> 1;
+ error = ((error - tick_error) >> look_ahead) + tick_error;
+
+ /* Finally calculate the adjustment shift value. */
+ i = *interval;
+ mult = 1;
+ if (error < 0) {
+ error = -error;
+ *interval = -*interval;
+ *offset = -*offset;
+ mult = -1;
+ }
+ for (adj = 0; error > i; adj++)
+ error >>= 1;
+
+ *interval <<= adj;
+ *offset <<= adj;
+ return mult << adj;
+}
+
+/*
+ * Adjust the multiplier to reduce the error value,
+ * this is optimized for the most common adjustments of -1,0,1,
+ * for other values we can do a bit more work.
+ */
+static void clocksource_adjust(struct clocksource *clock, s64 offset)
+{
+ s64 error, interval = clock->cycle_interval;
+ int adj;
+
+ error = clock->error >> (TICK_LENGTH_SHIFT - clock->shift - 1);
+ if (error > interval) {
+ error >>= 2;
+ if (likely(error <= interval))
+ adj = 1;
+ else
+ adj = clocksource_bigadjust(error, &interval, &offset);
+ } else if (error < -interval) {
+ error >>= 2;
+ if (likely(error >= -interval)) {
+ adj = -1;
+ interval = -interval;
+ offset = -offset;
+ } else
+ adj = clocksource_bigadjust(error, &interval, &offset);
+ } else
+ return;
+
+ clock->mult += adj;
+ clock->xtime_interval += interval;
+ clock->xtime_nsec -= offset;
+ clock->error -= (interval - offset) <<
+ (TICK_LENGTH_SHIFT - clock->shift);
+}
+
+/**
+ * update_wall_time - Uses the current clocksource to increment the wall time
+ *
+ * Called from the timer interrupt, must hold a write on xtime_lock.
+ */
+void update_wall_time(void)
+{
+ cycle_t offset;
+
+ /* Make sure we're fully resumed: */
+ if (unlikely(timekeeping_suspended))
+ return;
+
+#ifdef CONFIG_GENERIC_TIME
+ offset = (clocksource_read(clock) - clock->cycle_last) & clock->mask;
+#else
+ offset = clock->cycle_interval;
+#endif
+ clock->xtime_nsec += (s64)xtime.tv_nsec << clock->shift;
+
+ /* normally this loop will run just once, however in the
+ * case of lost or late ticks, it will accumulate correctly.
+ */
+ while (offset >= clock->cycle_interval) {
+ /* accumulate one interval */
+ clock->xtime_nsec += clock->xtime_interval;
+ clock->cycle_last += clock->cycle_interval;
+ offset -= clock->cycle_interval;
+
+ if (clock->xtime_nsec >= (u64)NSEC_PER_SEC << clock->shift) {
+ clock->xtime_nsec -= (u64)NSEC_PER_SEC << clock->shift;
+ xtime.tv_sec++;
+ second_overflow();
+ }
+
+ /* interpolator bits */
+ time_interpolator_update(clock->xtime_interval
+ >> clock->shift);
+
+ /* accumulate error between NTP and clock interval */
+ clock->error += current_tick_length();
+ clock->error -= clock->xtime_interval << (TICK_LENGTH_SHIFT - clock->shift);
+ }
+
+ /* correct the clock when NTP error is too big */
+ clocksource_adjust(clock, offset);
+
+ /* store full nanoseconds into xtime */
+ xtime.tv_nsec = (s64)clock->xtime_nsec >> clock->shift;
+ clock->xtime_nsec -= (s64)xtime.tv_nsec << clock->shift;
+
+ /* check to see if there is a new clocksource to use */
+ change_clocksource();
+ update_vsyscall(&xtime, clock);
+}
diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c
index 59df5e8..b734ca4 100644
--- a/kernel/time/timer_list.c
+++ b/kernel/time/timer_list.c
@@ -38,17 +38,12 @@
static void print_name_offset(struct seq_file *m, void *sym)
{
- unsigned long addr = (unsigned long)sym;
- char namebuf[KSYM_NAME_LEN+1];
- unsigned long size, offset;
- const char *sym_name;
- char *modname;
+ char symname[KSYM_NAME_LEN+1];
- sym_name = kallsyms_lookup(addr, &size, &offset, &modname, namebuf);
- if (sym_name)
- SEQ_printf(m, "%s", sym_name);
- else
+ if (lookup_symbol_name((unsigned long)sym, symname) < 0)
SEQ_printf(m, "<%p>", sym);
+ else
+ SEQ_printf(m, "%s", symname);
}
static void
diff --git a/kernel/time/timer_stats.c b/kernel/time/timer_stats.c
index 1bc4882..868f1bc 100644
--- a/kernel/time/timer_stats.c
+++ b/kernel/time/timer_stats.c
@@ -257,16 +257,12 @@
static void print_name_offset(struct seq_file *m, unsigned long addr)
{
- char namebuf[KSYM_NAME_LEN+1];
- unsigned long size, offset;
- const char *sym_name;
- char *modname;
+ char symname[KSYM_NAME_LEN+1];
- sym_name = kallsyms_lookup(addr, &size, &offset, &modname, namebuf);
- if (sym_name)
- seq_printf(m, "%s", sym_name);
- else
+ if (lookup_symbol_name(addr, symname) < 0)
seq_printf(m, "<%p>", (void *)addr);
+ else
+ seq_printf(m, "%s", symname);
}
static int tstats_show(struct seq_file *m, void *v)
diff --git a/kernel/timer.c b/kernel/timer.c
index b22bd39..7a64483 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -1,7 +1,7 @@
/*
* linux/kernel/timer.c
*
- * Kernel internal timers, kernel timekeeping, basic process system calls
+ * Kernel internal timers, basic process system calls
*
* Copyright (C) 1991, 1992 Linus Torvalds
*
@@ -74,7 +74,7 @@
tvec_t tv3;
tvec_t tv4;
tvec_t tv5;
-} ____cacheline_aligned_in_smp;
+} ____cacheline_aligned;
typedef struct tvec_t_base_s tvec_base_t;
@@ -82,6 +82,37 @@
EXPORT_SYMBOL(boot_tvec_bases);
static DEFINE_PER_CPU(tvec_base_t *, tvec_bases) = &boot_tvec_bases;
+/*
+ * Note that all tvec_bases is 2 byte aligned and lower bit of
+ * base in timer_list is guaranteed to be zero. Use the LSB for
+ * the new flag to indicate whether the timer is deferrable
+ */
+#define TBASE_DEFERRABLE_FLAG (0x1)
+
+/* Functions below help us manage 'deferrable' flag */
+static inline unsigned int tbase_get_deferrable(tvec_base_t *base)
+{
+ return ((unsigned int)(unsigned long)base & TBASE_DEFERRABLE_FLAG);
+}
+
+static inline tvec_base_t *tbase_get_base(tvec_base_t *base)
+{
+ return ((tvec_base_t *)((unsigned long)base & ~TBASE_DEFERRABLE_FLAG));
+}
+
+static inline void timer_set_deferrable(struct timer_list *timer)
+{
+ timer->base = ((tvec_base_t *)((unsigned long)(timer->base) |
+ TBASE_DEFERRABLE_FLAG));
+}
+
+static inline void
+timer_set_base(struct timer_list *timer, tvec_base_t *new_base)
+{
+ timer->base = (tvec_base_t *)((unsigned long)(new_base) |
+ tbase_get_deferrable(timer->base));
+}
+
/**
* __round_jiffies - function to round jiffies to a full second
* @j: the time in (absolute) jiffies that should be rounded
@@ -295,6 +326,13 @@
}
EXPORT_SYMBOL(init_timer);
+void fastcall init_timer_deferrable(struct timer_list *timer)
+{
+ init_timer(timer);
+ timer_set_deferrable(timer);
+}
+EXPORT_SYMBOL(init_timer_deferrable);
+
static inline void detach_timer(struct timer_list *timer,
int clear_pending)
{
@@ -325,10 +363,11 @@
tvec_base_t *base;
for (;;) {
- base = timer->base;
+ tvec_base_t *prelock_base = timer->base;
+ base = tbase_get_base(prelock_base);
if (likely(base != NULL)) {
spin_lock_irqsave(&base->lock, *flags);
- if (likely(base == timer->base))
+ if (likely(prelock_base == timer->base))
return base;
/* The timer has migrated to another CPU */
spin_unlock_irqrestore(&base->lock, *flags);
@@ -365,11 +404,11 @@
*/
if (likely(base->running_timer != timer)) {
/* See the comment in lock_timer_base() */
- timer->base = NULL;
+ timer_set_base(timer, NULL);
spin_unlock(&base->lock);
base = new_base;
spin_lock(&base->lock);
- timer->base = base;
+ timer_set_base(timer, base);
}
}
@@ -397,7 +436,7 @@
timer_stats_timer_set_start_info(timer);
BUG_ON(timer_pending(timer) || !timer->function);
spin_lock_irqsave(&base->lock, flags);
- timer->base = base;
+ timer_set_base(timer, base);
internal_add_timer(base, timer);
spin_unlock_irqrestore(&base->lock, flags);
}
@@ -550,7 +589,7 @@
* don't have to detach them individually.
*/
list_for_each_entry_safe(timer, tmp, &tv_list, entry) {
- BUG_ON(timer->base != base);
+ BUG_ON(tbase_get_base(timer->base) != base);
internal_add_timer(base, timer);
}
@@ -590,7 +629,7 @@
void (*fn)(unsigned long);
unsigned long data;
- timer = list_entry(head->next,struct timer_list,entry);
+ timer = list_first_entry(head, struct timer_list,entry);
fn = timer->function;
data = timer->data;
@@ -636,6 +675,9 @@
index = slot = timer_jiffies & TVR_MASK;
do {
list_for_each_entry(nte, base->tv1.vec + slot, entry) {
+ if (tbase_get_deferrable(nte->base))
+ continue;
+
found = 1;
expires = nte->expires;
/* Look at the cascade bucket(s)? */
@@ -752,455 +794,6 @@
#endif
-/******************************************************************/
-
-/*
- * The current time
- * wall_to_monotonic is what we need to add to xtime (or xtime corrected
- * for sub jiffie times) to get to monotonic time. Monotonic is pegged
- * at zero at system boot time, so wall_to_monotonic will be negative,
- * however, we will ALWAYS keep the tv_nsec part positive so we can use
- * the usual normalization.
- */
-struct timespec xtime __attribute__ ((aligned (16)));
-struct timespec wall_to_monotonic __attribute__ ((aligned (16)));
-
-EXPORT_SYMBOL(xtime);
-
-
-/* XXX - all of this timekeeping code should be later moved to time.c */
-#include <linux/clocksource.h>
-static struct clocksource *clock; /* pointer to current clocksource */
-
-#ifdef CONFIG_GENERIC_TIME
-/**
- * __get_nsec_offset - Returns nanoseconds since last call to periodic_hook
- *
- * private function, must hold xtime_lock lock when being
- * called. Returns the number of nanoseconds since the
- * last call to update_wall_time() (adjusted by NTP scaling)
- */
-static inline s64 __get_nsec_offset(void)
-{
- cycle_t cycle_now, cycle_delta;
- s64 ns_offset;
-
- /* read clocksource: */
- cycle_now = clocksource_read(clock);
-
- /* calculate the delta since the last update_wall_time: */
- cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;
-
- /* convert to nanoseconds: */
- ns_offset = cyc2ns(clock, cycle_delta);
-
- return ns_offset;
-}
-
-/**
- * __get_realtime_clock_ts - Returns the time of day in a timespec
- * @ts: pointer to the timespec to be set
- *
- * Returns the time of day in a timespec. Used by
- * do_gettimeofday() and get_realtime_clock_ts().
- */
-static inline void __get_realtime_clock_ts(struct timespec *ts)
-{
- unsigned long seq;
- s64 nsecs;
-
- do {
- seq = read_seqbegin(&xtime_lock);
-
- *ts = xtime;
- nsecs = __get_nsec_offset();
-
- } while (read_seqretry(&xtime_lock, seq));
-
- timespec_add_ns(ts, nsecs);
-}
-
-/**
- * getnstimeofday - Returns the time of day in a timespec
- * @ts: pointer to the timespec to be set
- *
- * Returns the time of day in a timespec.
- */
-void getnstimeofday(struct timespec *ts)
-{
- __get_realtime_clock_ts(ts);
-}
-
-EXPORT_SYMBOL(getnstimeofday);
-
-/**
- * do_gettimeofday - Returns the time of day in a timeval
- * @tv: pointer to the timeval to be set
- *
- * NOTE: Users should be converted to using get_realtime_clock_ts()
- */
-void do_gettimeofday(struct timeval *tv)
-{
- struct timespec now;
-
- __get_realtime_clock_ts(&now);
- tv->tv_sec = now.tv_sec;
- tv->tv_usec = now.tv_nsec/1000;
-}
-
-EXPORT_SYMBOL(do_gettimeofday);
-/**
- * do_settimeofday - Sets the time of day
- * @tv: pointer to the timespec variable containing the new time
- *
- * Sets the time of day to the new time and update NTP and notify hrtimers
- */
-int do_settimeofday(struct timespec *tv)
-{
- unsigned long flags;
- time_t wtm_sec, sec = tv->tv_sec;
- long wtm_nsec, nsec = tv->tv_nsec;
-
- if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
- return -EINVAL;
-
- write_seqlock_irqsave(&xtime_lock, flags);
-
- nsec -= __get_nsec_offset();
-
- wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
- wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
-
- set_normalized_timespec(&xtime, sec, nsec);
- set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
-
- clock->error = 0;
- ntp_clear();
-
- update_vsyscall(&xtime, clock);
-
- write_sequnlock_irqrestore(&xtime_lock, flags);
-
- /* signal hrtimers about time change */
- clock_was_set();
-
- return 0;
-}
-
-EXPORT_SYMBOL(do_settimeofday);
-
-/**
- * change_clocksource - Swaps clocksources if a new one is available
- *
- * Accumulates current time interval and initializes new clocksource
- */
-static void change_clocksource(void)
-{
- struct clocksource *new;
- cycle_t now;
- u64 nsec;
-
- new = clocksource_get_next();
-
- if (clock == new)
- return;
-
- now = clocksource_read(new);
- nsec = __get_nsec_offset();
- timespec_add_ns(&xtime, nsec);
-
- clock = new;
- clock->cycle_last = now;
-
- clock->error = 0;
- clock->xtime_nsec = 0;
- clocksource_calculate_interval(clock, NTP_INTERVAL_LENGTH);
-
- tick_clock_notify();
-
- printk(KERN_INFO "Time: %s clocksource has been installed.\n",
- clock->name);
-}
-#else
-static inline void change_clocksource(void) { }
-#endif
-
-/**
- * timekeeping_is_continuous - check to see if timekeeping is free running
- */
-int timekeeping_is_continuous(void)
-{
- unsigned long seq;
- int ret;
-
- do {
- seq = read_seqbegin(&xtime_lock);
-
- ret = clock->flags & CLOCK_SOURCE_VALID_FOR_HRES;
-
- } while (read_seqretry(&xtime_lock, seq));
-
- return ret;
-}
-
-/**
- * read_persistent_clock - Return time in seconds from the persistent clock.
- *
- * Weak dummy function for arches that do not yet support it.
- * Returns seconds from epoch using the battery backed persistent clock.
- * Returns zero if unsupported.
- *
- * XXX - Do be sure to remove it once all arches implement it.
- */
-unsigned long __attribute__((weak)) read_persistent_clock(void)
-{
- return 0;
-}
-
-/*
- * timekeeping_init - Initializes the clocksource and common timekeeping values
- */
-void __init timekeeping_init(void)
-{
- unsigned long flags;
- unsigned long sec = read_persistent_clock();
-
- write_seqlock_irqsave(&xtime_lock, flags);
-
- ntp_clear();
-
- clock = clocksource_get_next();
- clocksource_calculate_interval(clock, NTP_INTERVAL_LENGTH);
- clock->cycle_last = clocksource_read(clock);
-
- xtime.tv_sec = sec;
- xtime.tv_nsec = 0;
- set_normalized_timespec(&wall_to_monotonic,
- -xtime.tv_sec, -xtime.tv_nsec);
-
- write_sequnlock_irqrestore(&xtime_lock, flags);
-}
-
-/* flag for if timekeeping is suspended */
-static int timekeeping_suspended;
-/* time in seconds when suspend began */
-static unsigned long timekeeping_suspend_time;
-
-/**
- * timekeeping_resume - Resumes the generic timekeeping subsystem.
- * @dev: unused
- *
- * This is for the generic clocksource timekeeping.
- * xtime/wall_to_monotonic/jiffies/etc are
- * still managed by arch specific suspend/resume code.
- */
-static int timekeeping_resume(struct sys_device *dev)
-{
- unsigned long flags;
- unsigned long now = read_persistent_clock();
-
- write_seqlock_irqsave(&xtime_lock, flags);
-
- if (now && (now > timekeeping_suspend_time)) {
- unsigned long sleep_length = now - timekeeping_suspend_time;
-
- xtime.tv_sec += sleep_length;
- wall_to_monotonic.tv_sec -= sleep_length;
- }
- /* re-base the last cycle value */
- clock->cycle_last = clocksource_read(clock);
- clock->error = 0;
- timekeeping_suspended = 0;
- write_sequnlock_irqrestore(&xtime_lock, flags);
-
- touch_softlockup_watchdog();
-
- clockevents_notify(CLOCK_EVT_NOTIFY_RESUME, NULL);
-
- /* Resume hrtimers */
- hres_timers_resume();
-
- return 0;
-}
-
-static int timekeeping_suspend(struct sys_device *dev, pm_message_t state)
-{
- unsigned long flags;
-
- write_seqlock_irqsave(&xtime_lock, flags);
- timekeeping_suspended = 1;
- timekeeping_suspend_time = read_persistent_clock();
- write_sequnlock_irqrestore(&xtime_lock, flags);
-
- clockevents_notify(CLOCK_EVT_NOTIFY_SUSPEND, NULL);
-
- return 0;
-}
-
-/* sysfs resume/suspend bits for timekeeping */
-static struct sysdev_class timekeeping_sysclass = {
- .resume = timekeeping_resume,
- .suspend = timekeeping_suspend,
- set_kset_name("timekeeping"),
-};
-
-static struct sys_device device_timer = {
- .id = 0,
- .cls = &timekeeping_sysclass,
-};
-
-static int __init timekeeping_init_device(void)
-{
- int error = sysdev_class_register(&timekeeping_sysclass);
- if (!error)
- error = sysdev_register(&device_timer);
- return error;
-}
-
-device_initcall(timekeeping_init_device);
-
-/*
- * If the error is already larger, we look ahead even further
- * to compensate for late or lost adjustments.
- */
-static __always_inline int clocksource_bigadjust(s64 error, s64 *interval,
- s64 *offset)
-{
- s64 tick_error, i;
- u32 look_ahead, adj;
- s32 error2, mult;
-
- /*
- * Use the current error value to determine how much to look ahead.
- * The larger the error the slower we adjust for it to avoid problems
- * with losing too many ticks, otherwise we would overadjust and
- * produce an even larger error. The smaller the adjustment the
- * faster we try to adjust for it, as lost ticks can do less harm
- * here. This is tuned so that an error of about 1 msec is adusted
- * within about 1 sec (or 2^20 nsec in 2^SHIFT_HZ ticks).
- */
- error2 = clock->error >> (TICK_LENGTH_SHIFT + 22 - 2 * SHIFT_HZ);
- error2 = abs(error2);
- for (look_ahead = 0; error2 > 0; look_ahead++)
- error2 >>= 2;
-
- /*
- * Now calculate the error in (1 << look_ahead) ticks, but first
- * remove the single look ahead already included in the error.
- */
- tick_error = current_tick_length() >>
- (TICK_LENGTH_SHIFT - clock->shift + 1);
- tick_error -= clock->xtime_interval >> 1;
- error = ((error - tick_error) >> look_ahead) + tick_error;
-
- /* Finally calculate the adjustment shift value. */
- i = *interval;
- mult = 1;
- if (error < 0) {
- error = -error;
- *interval = -*interval;
- *offset = -*offset;
- mult = -1;
- }
- for (adj = 0; error > i; adj++)
- error >>= 1;
-
- *interval <<= adj;
- *offset <<= adj;
- return mult << adj;
-}
-
-/*
- * Adjust the multiplier to reduce the error value,
- * this is optimized for the most common adjustments of -1,0,1,
- * for other values we can do a bit more work.
- */
-static void clocksource_adjust(struct clocksource *clock, s64 offset)
-{
- s64 error, interval = clock->cycle_interval;
- int adj;
-
- error = clock->error >> (TICK_LENGTH_SHIFT - clock->shift - 1);
- if (error > interval) {
- error >>= 2;
- if (likely(error <= interval))
- adj = 1;
- else
- adj = clocksource_bigadjust(error, &interval, &offset);
- } else if (error < -interval) {
- error >>= 2;
- if (likely(error >= -interval)) {
- adj = -1;
- interval = -interval;
- offset = -offset;
- } else
- adj = clocksource_bigadjust(error, &interval, &offset);
- } else
- return;
-
- clock->mult += adj;
- clock->xtime_interval += interval;
- clock->xtime_nsec -= offset;
- clock->error -= (interval - offset) <<
- (TICK_LENGTH_SHIFT - clock->shift);
-}
-
-/**
- * update_wall_time - Uses the current clocksource to increment the wall time
- *
- * Called from the timer interrupt, must hold a write on xtime_lock.
- */
-static void update_wall_time(void)
-{
- cycle_t offset;
-
- /* Make sure we're fully resumed: */
- if (unlikely(timekeeping_suspended))
- return;
-
-#ifdef CONFIG_GENERIC_TIME
- offset = (clocksource_read(clock) - clock->cycle_last) & clock->mask;
-#else
- offset = clock->cycle_interval;
-#endif
- clock->xtime_nsec += (s64)xtime.tv_nsec << clock->shift;
-
- /* normally this loop will run just once, however in the
- * case of lost or late ticks, it will accumulate correctly.
- */
- while (offset >= clock->cycle_interval) {
- /* accumulate one interval */
- clock->xtime_nsec += clock->xtime_interval;
- clock->cycle_last += clock->cycle_interval;
- offset -= clock->cycle_interval;
-
- if (clock->xtime_nsec >= (u64)NSEC_PER_SEC << clock->shift) {
- clock->xtime_nsec -= (u64)NSEC_PER_SEC << clock->shift;
- xtime.tv_sec++;
- second_overflow();
- }
-
- /* interpolator bits */
- time_interpolator_update(clock->xtime_interval
- >> clock->shift);
-
- /* accumulate error between NTP and clock interval */
- clock->error += current_tick_length();
- clock->error -= clock->xtime_interval << (TICK_LENGTH_SHIFT - clock->shift);
- }
-
- /* correct the clock when NTP error is too big */
- clocksource_adjust(clock, offset);
-
- /* store full nanoseconds into xtime */
- xtime.tv_nsec = (s64)clock->xtime_nsec >> clock->shift;
- clock->xtime_nsec -= (s64)xtime.tv_nsec << clock->shift;
-
- /* check to see if there is a new clocksource to use */
- change_clocksource();
- update_vsyscall(&xtime, clock);
-}
-
/*
* Called from the timer interrupt handler to charge one tick to the current
* process. user_tick is 1 if the tick is user time, 0 for system.
@@ -1264,14 +857,6 @@
}
/*
- * This read-write spinlock protects us from races in SMP while
- * playing with xtime and avenrun.
- */
-__attribute__((weak)) __cacheline_aligned_in_smp DEFINE_SEQLOCK(xtime_lock);
-
-EXPORT_SYMBOL(xtime_lock);
-
-/*
* This function runs timers and the timer-tq in bottom half context.
*/
static void run_timer_softirq(struct softirq_action *h)
@@ -1617,6 +1202,13 @@
cpu_to_node(cpu));
if (!base)
return -ENOMEM;
+
+ /* Make sure that tvec_base is 2 byte aligned */
+ if (tbase_get_deferrable(base)) {
+ WARN_ON(1);
+ kfree(base);
+ return -ENOMEM;
+ }
memset(base, 0, sizeof(*base));
per_cpu(tvec_bases, cpu) = base;
} else {
@@ -1656,9 +1248,9 @@
struct timer_list *timer;
while (!list_empty(head)) {
- timer = list_entry(head->next, struct timer_list, entry);
+ timer = list_first_entry(head, struct timer_list, entry);
detach_timer(timer, 0);
- timer->base = new_base;
+ timer_set_base(timer, new_base);
internal_add_timer(new_base, timer);
}
}
diff --git a/kernel/uid16.c b/kernel/uid16.c
index 187e2a4..dd308ba 100644
--- a/kernel/uid16.c
+++ b/kernel/uid16.c
@@ -6,7 +6,6 @@
#include <linux/mm.h>
#include <linux/utsname.h>
#include <linux/mman.h>
-#include <linux/smp_lock.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/prctl.h>
diff --git a/kernel/utsname.c b/kernel/utsname.c
index c859164..160c8c5 100644
--- a/kernel/utsname.c
+++ b/kernel/utsname.c
@@ -32,58 +32,25 @@
}
/*
- * unshare the current process' utsname namespace.
- * called only in sys_unshare()
- */
-int unshare_utsname(unsigned long unshare_flags, struct uts_namespace **new_uts)
-{
- if (unshare_flags & CLONE_NEWUTS) {
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- *new_uts = clone_uts_ns(current->nsproxy->uts_ns);
- if (!*new_uts)
- return -ENOMEM;
- }
-
- return 0;
-}
-
-/*
* Copy task tsk's utsname namespace, or clone it if flags
* specifies CLONE_NEWUTS. In latter case, changes to the
* utsname of this process won't be seen by parent, and vice
* versa.
*/
-int copy_utsname(int flags, struct task_struct *tsk)
+struct uts_namespace *copy_utsname(int flags, struct uts_namespace *old_ns)
{
- struct uts_namespace *old_ns = tsk->nsproxy->uts_ns;
struct uts_namespace *new_ns;
- int err = 0;
- if (!old_ns)
- return 0;
-
+ BUG_ON(!old_ns);
get_uts_ns(old_ns);
if (!(flags & CLONE_NEWUTS))
- return 0;
-
- if (!capable(CAP_SYS_ADMIN)) {
- err = -EPERM;
- goto out;
- }
+ return old_ns;
new_ns = clone_uts_ns(old_ns);
- if (!new_ns) {
- err = -ENOMEM;
- goto out;
- }
- tsk->nsproxy->uts_ns = new_ns;
-out:
put_uts_ns(old_ns);
- return err;
+ return new_ns;
}
void free_uts_ns(struct kref *kref)
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 9a28779..ee05b8a 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -86,23 +86,6 @@
Drivers ought to be able to handle interrupts coming in at those
points; some don't and need to be caught.
-config LOG_BUF_SHIFT
- int "Kernel log buffer size (16 => 64KB, 17 => 128KB)" if DEBUG_KERNEL
- range 12 21
- default 17 if S390 || LOCKDEP
- default 16 if X86_NUMAQ || IA64
- default 15 if SMP
- default 14
- help
- Select kernel log buffer size as a power of 2.
- Defaults and Examples:
- 17 => 128 KB for S/390
- 16 => 64 KB for x86 NUMAQ or IA-64
- 15 => 32 KB for SMP
- 14 => 16 KB for uniprocessor
- 13 => 8 KB
- 12 => 4 KB
-
config DETECT_SOFTLOCKUP
bool "Detect Soft Lockups"
depends on DEBUG_KERNEL && !S390
@@ -201,6 +184,16 @@
This feature allows mutex semantics violations to be detected and
reported.
+config DEBUG_SEMAPHORE
+ bool "Semaphore debugging"
+ depends on DEBUG_KERNEL
+ depends on ALPHA || FRV
+ default n
+ help
+ If you say Y here then semaphore processing will issue lots of
+ verbose debugging messages. If you suspect a semaphore problem or a
+ kernel hacker asks for this option then say Y. Otherwise say N.
+
config DEBUG_LOCK_ALLOC
bool "Lock debugging: detect incorrect freeing of live locks"
depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT
diff --git a/lib/fault-inject.c b/lib/fault-inject.c
index 0fabd12..b18fc2f 100644
--- a/lib/fault-inject.c
+++ b/lib/fault-inject.c
@@ -72,9 +72,8 @@
trace.entries = entries;
trace.max_entries = depth;
trace.skip = 1;
- trace.all_contexts = 0;
- save_stack_trace(&trace, NULL);
+ save_stack_trace(&trace);
for (n = 0; n < trace.nr_entries; n++) {
if (attr->reject_start <= entries[n] &&
entries[n] < attr->reject_end)
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 9970e55..10c13ad 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -778,7 +778,6 @@
return virt_to_bus(io_tlb_end - 1) <= mask;
}
-EXPORT_SYMBOL(swiotlb_init);
EXPORT_SYMBOL(swiotlb_map_single);
EXPORT_SYMBOL(swiotlb_unmap_single);
EXPORT_SYMBOL(swiotlb_map_sg);
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index cbab1df..0172902 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -825,6 +825,17 @@
break;
str = next;
}
+
+ /*
+ * Now we've come all the way through so either the input string or the
+ * format ended. In the former case, there can be a %n at the current
+ * position in the format that needs to be filled.
+ */
+ if (*fmt == '%' && *(fmt + 1) == 'n') {
+ int *p = (int *)va_arg(args, int *);
+ *p = str - buf;
+ }
+
return num;
}
diff --git a/mm/filemap.c b/mm/filemap.c
index 5631d6b..9cbf4fe 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1110,6 +1110,45 @@
return size;
}
+/*
+ * Performs necessary checks before doing a write
+ * @iov: io vector request
+ * @nr_segs: number of segments in the iovec
+ * @count: number of bytes to write
+ * @access_flags: type of access: %VERIFY_READ or %VERIFY_WRITE
+ *
+ * Adjust number of segments and amount of bytes to write (nr_segs should be
+ * properly initialized first). Returns appropriate error code that caller
+ * should return or zero in case that write should be allowed.
+ */
+int generic_segment_checks(const struct iovec *iov,
+ unsigned long *nr_segs, size_t *count, int access_flags)
+{
+ unsigned long seg;
+ size_t cnt = 0;
+ for (seg = 0; seg < *nr_segs; seg++) {
+ const struct iovec *iv = &iov[seg];
+
+ /*
+ * If any segment has a negative length, or the cumulative
+ * length ever wraps negative then return -EINVAL.
+ */
+ cnt += iv->iov_len;
+ if (unlikely((ssize_t)(cnt|iv->iov_len) < 0))
+ return -EINVAL;
+ if (access_ok(access_flags, iv->iov_base, iv->iov_len))
+ continue;
+ if (seg == 0)
+ return -EFAULT;
+ *nr_segs = seg;
+ cnt -= iv->iov_len; /* This segment is no good */
+ break;
+ }
+ *count = cnt;
+ return 0;
+}
+EXPORT_SYMBOL(generic_segment_checks);
+
/**
* generic_file_aio_read - generic filesystem read routine
* @iocb: kernel I/O control block
@@ -1131,24 +1170,9 @@
loff_t *ppos = &iocb->ki_pos;
count = 0;
- for (seg = 0; seg < nr_segs; seg++) {
- const struct iovec *iv = &iov[seg];
-
- /*
- * If any segment has a negative length, or the cumulative
- * length ever wraps negative then return -EINVAL.
- */
- count += iv->iov_len;
- if (unlikely((ssize_t)(count|iv->iov_len) < 0))
- return -EINVAL;
- if (access_ok(VERIFY_WRITE, iv->iov_base, iv->iov_len))
- continue;
- if (seg == 0)
- return -EFAULT;
- nr_segs = seg;
- count -= iv->iov_len; /* This segment is no good */
- break;
- }
+ retval = generic_segment_checks(iov, &nr_segs, &count, VERIFY_WRITE);
+ if (retval)
+ return retval;
/* coalesce the iovecs and go direct-to-BIO for O_DIRECT */
if (filp->f_flags & O_DIRECT) {
@@ -2218,30 +2242,14 @@
size_t ocount; /* original count */
size_t count; /* after file limit checks */
struct inode *inode = mapping->host;
- unsigned long seg;
loff_t pos;
ssize_t written;
ssize_t err;
ocount = 0;
- for (seg = 0; seg < nr_segs; seg++) {
- const struct iovec *iv = &iov[seg];
-
- /*
- * If any segment has a negative length, or the cumulative
- * length ever wraps negative then return -EINVAL.
- */
- ocount += iv->iov_len;
- if (unlikely((ssize_t)(ocount|iv->iov_len) < 0))
- return -EINVAL;
- if (access_ok(VERIFY_READ, iv->iov_base, iv->iov_len))
- continue;
- if (seg == 0)
- return -EFAULT;
- nr_segs = seg;
- ocount -= iv->iov_len; /* This segment is no good */
- break;
- }
+ err = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ);
+ if (err)
+ return err;
count = ocount;
pos = *ppos;
@@ -2301,10 +2309,10 @@
* semantics.
*/
endbyte = pos + written_buffered - written - 1;
- err = do_sync_file_range(file, pos, endbyte,
- SYNC_FILE_RANGE_WAIT_BEFORE|
- SYNC_FILE_RANGE_WRITE|
- SYNC_FILE_RANGE_WAIT_AFTER);
+ err = do_sync_mapping_range(file->f_mapping, pos, endbyte,
+ SYNC_FILE_RANGE_WAIT_BEFORE|
+ SYNC_FILE_RANGE_WRITE|
+ SYNC_FILE_RANGE_WAIT_AFTER);
if (err == 0) {
written = written_buffered;
invalidate_mapping_pages(mapping,
diff --git a/mm/mmap.c b/mm/mmap.c
index 52646d6..cc1f543 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1366,7 +1366,6 @@
get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
unsigned long pgoff, unsigned long flags)
{
- unsigned long ret;
unsigned long (*get_area)(struct file *, unsigned long,
unsigned long, unsigned long, unsigned long);
diff --git a/mm/nommu.c b/mm/nommu.c
index 1f60194..2b16b00 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -262,6 +262,14 @@
}
/*
+ * Implement a stub for vmalloc_sync_all() if the architecture chose not to
+ * have one.
+ */
+void __attribute__((weak)) vmalloc_sync_all(void)
+{
+}
+
+/*
* sys_brk() for the most part doesn't need the global kernel
* lock, except when an application is doing something nasty
* like trying to un-brk an area that has already been mapped
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 029dfad..63cd888 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -683,12 +683,7 @@
}
ret = (*writepage)(page, wbc);
- if (ret) {
- if (ret == -ENOSPC)
- set_bit(AS_ENOSPC, &mapping->flags);
- else
- set_bit(AS_EIO, &mapping->flags);
- }
+ mapping_set_error(mapping, ret);
if (unlikely(ret == AOP_WRITEPAGE_ACTIVATE))
unlock_page(page);
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 5916431..6fd0b74 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -103,7 +103,7 @@
unsigned long __meminitdata nr_kernel_pages;
unsigned long __meminitdata nr_all_pages;
-static unsigned long __initdata dma_reserve;
+static unsigned long __meminitdata dma_reserve;
#ifdef CONFIG_ARCH_POPULATES_NODE_MAP
/*
@@ -126,10 +126,10 @@
#endif
#endif
- struct node_active_region __initdata early_node_map[MAX_ACTIVE_REGIONS];
- int __initdata nr_nodemap_entries;
- unsigned long __initdata arch_zone_lowest_possible_pfn[MAX_NR_ZONES];
- unsigned long __initdata arch_zone_highest_possible_pfn[MAX_NR_ZONES];
+ struct node_active_region __meminitdata early_node_map[MAX_ACTIVE_REGIONS];
+ int __meminitdata nr_nodemap_entries;
+ unsigned long __meminitdata arch_zone_lowest_possible_pfn[MAX_NR_ZONES];
+ unsigned long __meminitdata arch_zone_highest_possible_pfn[MAX_NR_ZONES];
#ifdef CONFIG_MEMORY_HOTPLUG_RESERVE
unsigned long __initdata node_boundary_start_pfn[MAX_NUMNODES];
unsigned long __initdata node_boundary_end_pfn[MAX_NUMNODES];
@@ -2179,7 +2179,7 @@
#endif
-static __meminit
+static __meminit noinline
int zone_wait_table_init(struct zone *zone, unsigned long zone_size_pages)
{
int i;
@@ -2267,7 +2267,7 @@
* Basic iterator support. Return the first range of PFNs for a node
* Note: nid == MAX_NUMNODES returns first region regardless of node
*/
-static int __init first_active_region_index_in_nid(int nid)
+static int __meminit first_active_region_index_in_nid(int nid)
{
int i;
@@ -2282,7 +2282,7 @@
* Basic iterator support. Return the next active range of PFNs for a node
* Note: nid == MAX_NUMNODES returns next region regardles of node
*/
-static int __init next_active_region_index_in_nid(int index, int nid)
+static int __meminit next_active_region_index_in_nid(int index, int nid)
{
for (index = index + 1; index < nr_nodemap_entries; index++)
if (nid == MAX_NUMNODES || early_node_map[index].nid == nid)
@@ -2435,7 +2435,7 @@
* with no available memory, a warning is printed and the start and end
* PFNs will be 0.
*/
-void __init get_pfn_range_for_nid(unsigned int nid,
+void __meminit get_pfn_range_for_nid(unsigned int nid,
unsigned long *start_pfn, unsigned long *end_pfn)
{
int i;
@@ -2460,7 +2460,7 @@
* Return the number of pages a zone spans in a node, including holes
* present_pages = zone_spanned_pages_in_node() - zone_absent_pages_in_node()
*/
-unsigned long __init zone_spanned_pages_in_node(int nid,
+unsigned long __meminit zone_spanned_pages_in_node(int nid,
unsigned long zone_type,
unsigned long *ignored)
{
@@ -2488,7 +2488,7 @@
* Return the number of holes in a range on a node. If nid is MAX_NUMNODES,
* then all holes in the requested range will be accounted for.
*/
-unsigned long __init __absent_pages_in_range(int nid,
+unsigned long __meminit __absent_pages_in_range(int nid,
unsigned long range_start_pfn,
unsigned long range_end_pfn)
{
@@ -2548,7 +2548,7 @@
}
/* Return the number of page frames in holes in a zone on a node */
-unsigned long __init zone_absent_pages_in_node(int nid,
+unsigned long __meminit zone_absent_pages_in_node(int nid,
unsigned long zone_type,
unsigned long *ignored)
{
@@ -2584,7 +2584,7 @@
#endif
-static void __init calculate_node_totalpages(struct pglist_data *pgdat,
+static void __meminit calculate_node_totalpages(struct pglist_data *pgdat,
unsigned long *zones_size, unsigned long *zholes_size)
{
unsigned long realtotalpages, totalpages = 0;
@@ -2692,7 +2692,7 @@
}
}
-static void __init alloc_node_mem_map(struct pglist_data *pgdat)
+static void __meminit alloc_node_mem_map(struct pglist_data *pgdat)
{
/* Skip empty nodes */
if (!pgdat->node_spanned_pages)
diff --git a/mm/rmap.c b/mm/rmap.c
index 75a32be..304f519 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -505,6 +505,7 @@
return ret;
}
+EXPORT_SYMBOL_GPL(page_mkclean);
/**
* page_set_anon_rmap - setup new anonymous rmap
diff --git a/mm/slab.c b/mm/slab.c
index 5920a41..acda7e2 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -148,10 +148,11 @@
* Usually, the kmalloc caches are cache_line_size() aligned, except when
* DEBUG and FORCED_DEBUG are enabled, then they are BYTES_PER_WORD aligned.
* Some archs want to perform DMA into kmalloc caches and need a guaranteed
- * alignment larger than BYTES_PER_WORD. ARCH_KMALLOC_MINALIGN allows that.
- * Note that this flag disables some debug features.
+ * alignment larger than the alignment of a 64-bit integer.
+ * ARCH_KMALLOC_MINALIGN allows that.
+ * Note that increasing this value may disable some debug features.
*/
-#define ARCH_KMALLOC_MINALIGN 0
+#define ARCH_KMALLOC_MINALIGN __alignof__(unsigned long long)
#endif
#ifndef ARCH_SLAB_MINALIGN
@@ -536,19 +537,22 @@
return cachep->obj_size;
}
-static unsigned long *dbg_redzone1(struct kmem_cache *cachep, void *objp)
+static unsigned long long *dbg_redzone1(struct kmem_cache *cachep, void *objp)
{
BUG_ON(!(cachep->flags & SLAB_RED_ZONE));
- return (unsigned long*) (objp+obj_offset(cachep)-BYTES_PER_WORD);
+ return (unsigned long long*) (objp + obj_offset(cachep) -
+ sizeof(unsigned long long));
}
-static unsigned long *dbg_redzone2(struct kmem_cache *cachep, void *objp)
+static unsigned long long *dbg_redzone2(struct kmem_cache *cachep, void *objp)
{
BUG_ON(!(cachep->flags & SLAB_RED_ZONE));
if (cachep->flags & SLAB_STORE_USER)
- return (unsigned long *)(objp + cachep->buffer_size -
- 2 * BYTES_PER_WORD);
- return (unsigned long *)(objp + cachep->buffer_size - BYTES_PER_WORD);
+ return (unsigned long long *)(objp + cachep->buffer_size -
+ sizeof(unsigned long long) -
+ BYTES_PER_WORD);
+ return (unsigned long long *) (objp + cachep->buffer_size -
+ sizeof(unsigned long long));
}
static void **dbg_userword(struct kmem_cache *cachep, void *objp)
@@ -561,8 +565,8 @@
#define obj_offset(x) 0
#define obj_size(cachep) (cachep->buffer_size)
-#define dbg_redzone1(cachep, objp) ({BUG(); (unsigned long *)NULL;})
-#define dbg_redzone2(cachep, objp) ({BUG(); (unsigned long *)NULL;})
+#define dbg_redzone1(cachep, objp) ({BUG(); (unsigned long long *)NULL;})
+#define dbg_redzone2(cachep, objp) ({BUG(); (unsigned long long *)NULL;})
#define dbg_userword(cachep, objp) ({BUG(); (void **)NULL;})
#endif
@@ -1776,7 +1780,7 @@
char *realobj;
if (cachep->flags & SLAB_RED_ZONE) {
- printk(KERN_ERR "Redzone: 0x%lx/0x%lx.\n",
+ printk(KERN_ERR "Redzone: 0x%llx/0x%llx.\n",
*dbg_redzone1(cachep, objp),
*dbg_redzone2(cachep, objp));
}
@@ -2239,7 +2243,7 @@
* is greater than BYTES_PER_WORD.
*/
if (flags & SLAB_RED_ZONE || flags & SLAB_STORE_USER)
- ralign = BYTES_PER_WORD;
+ ralign = __alignof__(unsigned long long);
/* 2) arch mandated alignment */
if (ralign < ARCH_SLAB_MINALIGN) {
@@ -2250,7 +2254,7 @@
ralign = align;
}
/* disable debug if necessary */
- if (ralign > BYTES_PER_WORD)
+ if (ralign > __alignof__(unsigned long long))
flags &= ~(SLAB_RED_ZONE | SLAB_STORE_USER);
/*
* 4) Store it.
@@ -2271,8 +2275,8 @@
*/
if (flags & SLAB_RED_ZONE) {
/* add space for red zone words */
- cachep->obj_offset += BYTES_PER_WORD;
- size += 2 * BYTES_PER_WORD;
+ cachep->obj_offset += sizeof(unsigned long long);
+ size += 2 * sizeof(unsigned long long);
}
if (flags & SLAB_STORE_USER) {
/* user store requires one word storage behind the end of
@@ -2833,7 +2837,7 @@
static inline void verify_redzone_free(struct kmem_cache *cache, void *obj)
{
- unsigned long redzone1, redzone2;
+ unsigned long long redzone1, redzone2;
redzone1 = *dbg_redzone1(cache, obj);
redzone2 = *dbg_redzone2(cache, obj);
@@ -2849,7 +2853,7 @@
else
slab_error(cache, "memory outside object was overwritten");
- printk(KERN_ERR "%p: redzone 1:0x%lx, redzone 2:0x%lx.\n",
+ printk(KERN_ERR "%p: redzone 1:0x%llx, redzone 2:0x%llx.\n",
obj, redzone1, redzone2);
}
@@ -3065,7 +3069,7 @@
slab_error(cachep, "double free, or memory outside"
" object was overwritten");
printk(KERN_ERR
- "%p: redzone 1:0x%lx, redzone 2:0x%lx\n",
+ "%p: redzone 1:0x%llx, redzone 2:0x%llx\n",
objp, *dbg_redzone1(cachep, objp),
*dbg_redzone2(cachep, objp));
}
@@ -4428,16 +4432,12 @@
static void show_symbol(struct seq_file *m, unsigned long address)
{
#ifdef CONFIG_KALLSYMS
- char *modname;
- const char *name;
unsigned long offset, size;
- char namebuf[KSYM_NAME_LEN+1];
+ char modname[MODULE_NAME_LEN + 1], name[KSYM_NAME_LEN + 1];
- name = kallsyms_lookup(address, &size, &offset, &modname, namebuf);
-
- if (name) {
+ if (lookup_symbol_attrs(address, &size, &offset, modname, name) == 0) {
seq_printf(m, "%s+%#lx/%#lx", name, offset, size);
- if (modname)
+ if (modname[0])
seq_printf(m, " [%s]", modname);
return;
}
diff --git a/mm/sparse.c b/mm/sparse.c
index 893e562..6f3fff9 100644
--- a/mm/sparse.c
+++ b/mm/sparse.c
@@ -44,7 +44,7 @@
#endif
#ifdef CONFIG_SPARSEMEM_EXTREME
-static struct mem_section *sparse_index_alloc(int nid)
+static struct mem_section noinline *sparse_index_alloc(int nid)
{
struct mem_section *section = NULL;
unsigned long array_size = SECTIONS_PER_ROOT *
@@ -61,7 +61,7 @@
return section;
}
-static int sparse_index_init(unsigned long section_nr, int nid)
+static int __meminit sparse_index_init(unsigned long section_nr, int nid)
{
static DEFINE_SPINLOCK(index_init_lock);
unsigned long root = SECTION_NR_TO_ROOT(section_nr);
@@ -138,7 +138,7 @@
}
/* Record a memory area against a node. */
-void memory_present(int nid, unsigned long start, unsigned long end)
+void __init memory_present(int nid, unsigned long start, unsigned long end)
{
unsigned long pfn;
@@ -197,7 +197,7 @@
return ((struct page *)coded_mem_map) + section_nr_to_pfn(pnum);
}
-static int sparse_init_one_section(struct mem_section *ms,
+static int __meminit sparse_init_one_section(struct mem_section *ms,
unsigned long pnum, struct page *mem_map)
{
if (!valid_section(ms))
@@ -209,7 +209,7 @@
return 1;
}
-static struct page *sparse_early_mem_map_alloc(unsigned long pnum)
+static struct page __init *sparse_early_mem_map_alloc(unsigned long pnum)
{
struct page *map;
struct mem_section *ms = __nr_to_section(pnum);
@@ -288,6 +288,7 @@
}
}
+#ifdef CONFIG_MEMORY_HOTPLUG
/*
* returns the number of sections whose mem_maps were properly
* set. If this is <=0, then that means that the passed-in
@@ -327,3 +328,4 @@
__kfree_section_memmap(memmap, nr_pages);
return ret;
}
+#endif
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index cb5aabd..faa2a52 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -755,3 +755,10 @@
}
EXPORT_SYMBOL(remap_vmalloc_range);
+/*
+ * Implement a stub for vmalloc_sync_all() if the architecture chose not to
+ * have one.
+ */
+void __attribute__((weak)) vmalloc_sync_all(void)
+{
+}
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 56651a1..1c8e75a1 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -284,12 +284,8 @@
struct page *page, int error)
{
lock_page(page);
- if (page_mapping(page) == mapping) {
- if (error == -ENOSPC)
- set_bit(AS_ENOSPC, &mapping->flags);
- else
- set_bit(AS_EIO, &mapping->flags);
- }
+ if (page_mapping(page) == mapping)
+ mapping_set_error(mapping, error);
unlock_page(page);
}
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index f6a92a0..fbdfb12 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -1844,7 +1844,6 @@
.sendpage = sock_no_sendpage,
};
-#include <linux/smp_lock.h>
SOCKOPS_WRAP(atalk_dgram, PF_APPLETALK);
static struct notifier_block ddp_notifier = {
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 6ded952..429e13a 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -23,7 +23,6 @@
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/string.h>
-#include <linux/smp_lock.h>
#include <linux/sockios.h>
#include <linux/net.h>
#include <net/ax25.h>
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c
index ab2db55..1c8f4a0 100644
--- a/net/bluetooth/bnep/core.c
+++ b/net/bluetooth/bnep/core.c
@@ -37,7 +37,6 @@
#include <linux/init.h>
#include <linux/wait.h>
#include <linux/errno.h>
-#include <linux/smp_lock.h>
#include <linux/net.h>
#include <net/sock.h>
diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c
index ebb0861..0e035d6 100644
--- a/net/bridge/br_stp.c
+++ b/net/bridge/br_stp.c
@@ -13,7 +13,6 @@
* 2 of the License, or (at your option) any later version.
*/
#include <linux/kernel.h>
-#include <linux/smp_lock.h>
#include "br_private.h"
#include "br_private_stp.h"
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
index 3e246b3..a786e78 100644
--- a/net/bridge/br_stp_if.c
+++ b/net/bridge/br_stp_if.c
@@ -14,7 +14,6 @@
*/
#include <linux/kernel.h>
-#include <linux/smp_lock.h>
#include <linux/etherdevice.h>
#include <linux/rtnetlink.h>
diff --git a/net/bridge/br_stp_timer.c b/net/bridge/br_stp_timer.c
index 030aa79..24e0ca4 100644
--- a/net/bridge/br_stp_timer.c
+++ b/net/bridge/br_stp_timer.c
@@ -15,7 +15,6 @@
#include <linux/kernel.h>
#include <linux/times.h>
-#include <linux/smp_lock.h>
#include "br_private.h"
#include "br_private_stp.h"
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index b316435..758dafe 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -9,7 +9,6 @@
* Copyright (C) 2002 Red Hat, Inc.
*/
-#include <linux/smp_lock.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/string.h>
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index b92a322..9cd3a1c 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -117,7 +117,6 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
-#include <linux/smp_lock.h>
#include <linux/mutex.h>
#include <linux/sched.h>
#include <linux/slab.h>
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 16aae8e..041fba3 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -92,7 +92,6 @@
#include <asm/uaccess.h>
#include <asm/system.h>
-#include <linux/smp_lock.h>
#include <linux/inet.h>
#include <linux/igmp.h>
#include <linux/inetdevice.h>
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 8b124ea..bd4c295 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -252,7 +252,6 @@
#include <linux/fcntl.h>
#include <linux/poll.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/fs.h>
#include <linux/random.h>
#include <linux/bootmem.h>
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 0faacf9..53232dd 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -40,7 +40,6 @@
#include <linux/compiler.h>
#include <linux/module.h>
-#include <linux/smp_lock.h>
/* People can turn this off for buggy TCP's found in printers etc. */
int sysctl_tcp_retrans_collapse __read_mostly = 1;
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 18cb928..6dd3772 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -42,7 +42,6 @@
#include <linux/inet.h>
#include <linux/netdevice.h>
#include <linux/icmpv6.h>
-#include <linux/smp_lock.h>
#include <linux/netfilter_ipv6.h>
#include <net/ip.h>
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
index 392f8bc..15419dd 100644
--- a/net/ipx/af_ipx.c
+++ b/net/ipx/af_ipx.c
@@ -1961,7 +1961,6 @@
.sendpage = sock_no_sendpage,
};
-#include <linux/smp_lock.h>
SOCKOPS_WRAP(ipx_dgram, PF_IPX);
static struct packet_type ipx_8023_packet_type = {
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
index 06c97c6..dcd7e32 100644
--- a/net/irda/af_irda.c
+++ b/net/irda/af_irda.c
@@ -2538,7 +2538,6 @@
};
#endif /* CONFIG_IRDA_ULTRA */
-#include <linux/smp_lock.h>
SOCKOPS_WRAP(irda_stream, PF_IRDA);
SOCKOPS_WRAP(irda_seqpacket, PF_IRDA);
SOCKOPS_WRAP(irda_dgram, PF_IRDA);
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 507828d..1f15821 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -45,7 +45,6 @@
#include <linux/rtnetlink.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
-#include <linux/smp_lock.h>
#include <linux/notifier.h>
#include <linux/security.h>
#include <linux/jhash.h>
diff --git a/net/socket.c b/net/socket.c
index 759825b..98a8f67 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -313,8 +313,19 @@
dentry->d_flags |= DCACHE_UNHASHED;
return 0;
}
+
+/*
+ * sockfs_dname() is called from d_path().
+ */
+static char *sockfs_dname(struct dentry *dentry, char *buffer, int buflen)
+{
+ return dynamic_dname(dentry, buffer, buflen, "socket:[%lu]",
+ dentry->d_inode->i_ino);
+}
+
static struct dentry_operations sockfs_dentry_operations = {
.d_delete = sockfs_delete_dentry,
+ .d_dname = sockfs_dname,
};
/*
@@ -354,14 +365,9 @@
static int sock_attach_fd(struct socket *sock, struct file *file)
{
- struct qstr this;
- char name[32];
+ struct qstr name = { .name = "" };
- this.len = sprintf(name, "[%lu]", SOCK_INODE(sock)->i_ino);
- this.name = name;
- this.hash = 0;
-
- file->f_path.dentry = d_alloc(sock_mnt->mnt_sb->s_root, &this);
+ file->f_path.dentry = d_alloc(sock_mnt->mnt_sb->s_root, &name);
if (unlikely(!file->f_path.dentry))
return -ENOMEM;
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index aec8cf1..fc12ba5 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -111,7 +111,6 @@
#include <net/scm.h>
#include <linux/init.h>
#include <linux/poll.h>
-#include <linux/smp_lock.h>
#include <linux/rtnetlink.h>
#include <linux/mount.h>
#include <net/checksum.h>
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index 0d6002fc..479927c 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -1605,7 +1605,6 @@
.sendpage = sock_no_sendpage,
};
-#include <linux/smp_lock.h>
SOCKOPS_WRAP(x25_proto, AF_X25);
static struct packet_type x25_packet_type = {
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index 8be269f..a325a0c 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -159,7 +159,8 @@
my $type_constant = '\%([-_\w]+)';
my $type_func = '(\w+)\(\)';
my $type_param = '\@(\w+)';
-my $type_struct = '\&((struct\s*)?[_\w]+)';
+my $type_struct = '\&((struct\s*)*[_\w]+)';
+my $type_struct_xml = '\\\amp;((struct\s*)*[_\w]+)';
my $type_env = '(\$\w+)';
# Output conversion substitutions.
@@ -168,7 +169,8 @@
# these work fairly well
my %highlights_html = ( $type_constant, "<i>\$1</i>",
$type_func, "<b>\$1</b>",
- $type_struct, "<i>\$1</i>",
+ $type_struct_xml, "<i>\$1</i>",
+ $type_env, "<b><i>\$1</i></b>",
$type_param, "<tt><b>\$1</b></tt>" );
my $blankline_html = "<p>";
@@ -326,12 +328,21 @@
}
}
+# get kernel version from env
+sub get_kernel_version() {
+ my $version;
+
+ if (defined($ENV{'KERNELVERSION'})) {
+ $version = $ENV{'KERNELVERSION'};
+ }
+ return $version;
+}
# generate a sequence of code that will splice in highlighting information
# using the s// operator.
my $dohighlight = "";
foreach my $pattern (keys %highlights) {
-# print "scanning pattern $pattern ($highlights{$pattern})\n";
+# print STDERR "scanning pattern:$pattern, highlight:($highlights{$pattern})\n";
$dohighlight .= "\$contents =~ s:$pattern:$highlights{$pattern}:gs;\n";
}
@@ -378,13 +389,19 @@
# confess "output_highlight got called with no args?\n";
# }
+# print STDERR "contents b4:$contents\n";
eval $dohighlight;
die $@ if $@;
+ if ($output_mode eq "html") {
+ $contents =~ s/\\\\//;
+ }
+# print STDERR "contents af:$contents\n";
+
foreach $line (split "\n", $contents) {
- if ($line eq ""){
+ if ($line eq ""){
print $lineprefix, $blankline;
} else {
- $line =~ s/\\\\\\/\&/g;
+ $line =~ s/\\\\\\/\&/g;
print $lineprefix, $line;
}
print "\n";
@@ -414,7 +431,7 @@
print "<b>enum ".$args{'enum'}."</b> {<br>\n";
$count = 0;
foreach $parameter (@{$args{'parameterlist'}}) {
- print " <b>".$parameter."</b>";
+ print " <b>".$parameter."</b>";
if ($count != $#{$args{'parameterlist'}}) {
$count++;
print ",\n";
@@ -462,15 +479,16 @@
my $parameter_name = $parameter;
$parameter_name =~ s/\[.*//;
- ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
+ ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
$type = $args{'parametertypes'}{$parameter};
if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
# pointer-to-function
- print " <i>$1</i><b>$parameter</b>) <i>($2)</i>;<br>\n";
+ print " <i>$1</i><b>$parameter</b>) <i>($2)</i>;<br>\n";
} elsif ($type =~ m/^(.*?)\s*(:.*)/) {
- print " <i>$1</i> <b>$parameter</b>$2;<br>\n";
+ # bitfield
+ print " <i>$1</i> <b>$parameter</b>$2;<br>\n";
} else {
- print " <i>$type</i> <b>$parameter</b>;<br>\n";
+ print " <i>$type</i> <b>$parameter</b>;<br>\n";
}
}
print "};<br>\n";
@@ -483,7 +501,7 @@
my $parameter_name = $parameter;
$parameter_name =~ s/\[.*//;
- ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
+ ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
print "<dt><b>".$parameter."</b>\n";
print "<dd>";
output_highlight($args{'parameterdescs'}{$parameter_name});
@@ -525,7 +543,7 @@
my $parameter_name = $parameter;
$parameter_name =~ s/\[.*//;
- ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
+ ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
print "<dt><b>".$parameter."</b>\n";
print "<dd>";
output_highlight($args{'parameterdescs'}{$parameter_name});
@@ -592,6 +610,7 @@
print "<refmeta>\n";
print " <refentrytitle><phrase>".$args{'function'}."</phrase></refentrytitle>\n";
print " <manvolnum>9</manvolnum>\n";
+ print " <refmiscinfo class=\"version\">" . get_kernel_version() . "</refmiscinfo>\n";
print "</refmeta>\n";
print "<refnamediv>\n";
print " <refname>".$args{'function'}."</refname>\n";
@@ -668,6 +687,7 @@
print "<refmeta>\n";
print " <refentrytitle><phrase>".$args{'type'}." ".$args{'struct'}."</phrase></refentrytitle>\n";
print " <manvolnum>9</manvolnum>\n";
+ print " <refmiscinfo class=\"version\">" . get_kernel_version() . "</refmiscinfo>\n";
print "</refmeta>\n";
print "<refnamediv>\n";
print " <refname>".$args{'type'}." ".$args{'struct'}."</refname>\n";
@@ -691,7 +711,7 @@
$parameter_name =~ s/\[.*//;
defined($args{'parameterdescs'}{$parameter_name}) || next;
- ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
+ ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
$type = $args{'parametertypes'}{$parameter};
if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
# pointer-to-function
@@ -752,6 +772,7 @@
print "<refmeta>\n";
print " <refentrytitle><phrase>enum ".$args{'enum'}."</phrase></refentrytitle>\n";
print " <manvolnum>9</manvolnum>\n";
+ print " <refmiscinfo class=\"version\">" . get_kernel_version() . "</refmiscinfo>\n";
print "</refmeta>\n";
print "<refnamediv>\n";
print " <refname>enum ".$args{'enum'}."</refname>\n";
@@ -767,11 +788,11 @@
print "enum ".$args{'enum'}." {\n";
$count = 0;
foreach $parameter (@{$args{'parameterlist'}}) {
- print " $parameter";
- if ($count != $#{$args{'parameterlist'}}) {
+ print " $parameter";
+ if ($count != $#{$args{'parameterlist'}}) {
$count++;
print ",";
- }
+ }
print "\n";
}
print "};";
@@ -1007,7 +1028,7 @@
print "enum ".$args{'enum'}." {\n";
$count = 0;
foreach my $parameter (@{$args{'parameterlist'}}) {
- print ".br\n.BI \" $parameter\"\n";
+ print ".br\n.BI \" $parameter\"\n";
if ($count == $#{$args{'parameterlist'}}) {
print "\n};\n";
last;
@@ -1054,7 +1075,7 @@
my $parameter_name = $parameter;
$parameter_name =~ s/\[.*//;
- ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
+ ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
$type = $args{'parametertypes'}{$parameter};
if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
# pointer-to-function
@@ -1077,7 +1098,7 @@
my $parameter_name = $parameter;
$parameter_name =~ s/\[.*//;
- ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
+ ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
print ".IP \"".$parameter."\" 12\n";
output_highlight($args{'parameterdescs'}{$parameter_name});
}
@@ -1187,7 +1208,7 @@
print "enum ".$args{'enum'}." {\n";
$count = 0;
foreach $parameter (@{$args{'parameterlist'}}) {
- print "\t$parameter";
+ print "\t$parameter";
if ($count != $#{$args{'parameterlist'}}) {
$count++;
print ",";
@@ -1232,7 +1253,7 @@
my $parameter_name = $parameter;
$parameter_name =~ s/\[.*//;
- ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
+ ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
$type = $args{'parametertypes'}{$parameter};
if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
# pointer-to-function
@@ -1252,7 +1273,7 @@
my $parameter_name = $parameter;
$parameter_name =~ s/\[.*//;
- ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
+ ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
print "$parameter\n\t";
print $args{'parameterdescs'}{$parameter_name}."\n";
}
@@ -1284,7 +1305,7 @@
( $function_only == 1 && defined($function_table{$name})) ||
( $function_only == 2 && !defined($function_table{$name})))
{
- &$func(@_);
+ &$func(@_);
$section_counter++;
}
}
@@ -1317,8 +1338,8 @@
my $file = shift;
if ($x =~/(struct|union)\s+(\w+)\s*{(.*)}/) {
- $declaration_name = $2;
- my $members = $3;
+ $declaration_name = $2;
+ my $members = $3;
# ignore embedded structs or unions
$members =~ s/{.*?}//g;
@@ -1345,7 +1366,7 @@
});
}
else {
- print STDERR "Error(${file}:$.): Cannot parse struct or union!\n";
+ print STDERR "Error(${file}:$.): Cannot parse struct or union!\n";
++$errors;
}
}
@@ -1356,15 +1377,15 @@
$x =~ s@/\*.*?\*/@@gos; # strip comments.
if ($x =~ /enum\s+(\w+)\s*{(.*)}/) {
- $declaration_name = $1;
- my $members = $2;
+ $declaration_name = $1;
+ my $members = $2;
foreach my $arg (split ',', $members) {
$arg =~ s/^\s*(\w+).*/$1/;
push @parameterlist, $arg;
if (!$parameterdescs{$arg}) {
- $parameterdescs{$arg} = $undescribed;
- print STDERR "Warning(${file}:$.): Enum value '$arg' ".
+ $parameterdescs{$arg} = $undescribed;
+ print STDERR "Warning(${file}:$.): Enum value '$arg' ".
"not described in enum '$declaration_name'\n";
}
@@ -1382,7 +1403,7 @@
});
}
else {
- print STDERR "Error(${file}:$.): Cannot parse enum!\n";
+ print STDERR "Error(${file}:$.): Cannot parse enum!\n";
++$errors;
}
}
@@ -1393,12 +1414,12 @@
$x =~ s@/\*.*?\*/@@gos; # strip comments.
while (($x =~ /\(*.\)\s*;$/) || ($x =~ /\[*.\]\s*;$/)) {
- $x =~ s/\(*.\)\s*;$/;/;
+ $x =~ s/\(*.\)\s*;$/;/;
$x =~ s/\[*.\]\s*;$/;/;
}
if ($x =~ /typedef.*\s+(\w+)\s*;/) {
- $declaration_name = $1;
+ $declaration_name = $1;
output_declaration($declaration_name,
'typedef',
@@ -1410,7 +1431,7 @@
});
}
else {
- print STDERR "Error(${file}:$.): Cannot parse typedef!\n";
+ print STDERR "Error(${file}:$.): Cannot parse typedef!\n";
++$errors;
}
}
@@ -1424,14 +1445,14 @@
# temporarily replace commas inside function pointer definition
while ($args =~ /(\([^\),]+),/) {
- $args =~ s/(\([^\),]+),/$1#/g;
+ $args =~ s/(\([^\),]+),/$1#/g;
}
foreach my $arg (split($splitter, $args)) {
# strip comments
$arg =~ s/\/\*.*\*\///;
- # strip leading/trailing spaces
- $arg =~ s/^\s*//;
+ # strip leading/trailing spaces
+ $arg =~ s/^\s*//;
$arg =~ s/\s*$//;
$arg =~ s/\s+/ /;
@@ -1456,7 +1477,16 @@
if ($args[0] =~ m/\*/) {
$args[0] =~ s/(\*+)\s*/ $1/;
}
- my @first_arg = split('\s+', shift @args);
+
+ my @first_arg;
+ if ($args[0] =~ /^(.*\s+)(.*?\[.*\].*)$/) {
+ shift @args;
+ push(@first_arg, split('\s+', $1));
+ push(@first_arg, $2);
+ } else {
+ @first_arg = split('\s+', shift @args);
+ }
+
unshift(@args, pop @first_arg);
$type = join " ", @first_arg;
@@ -1514,15 +1544,15 @@
$parameterdescs{$param_name} = $undescribed;
if (($type eq 'function') || ($type eq 'enum')) {
- print STDERR "Warning(${file}:$.): Function parameter ".
+ print STDERR "Warning(${file}:$.): Function parameter ".
"or member '$param' not " .
"described in '$declaration_name'\n";
}
print STDERR "Warning(${file}:$.):".
- " No description found for parameter '$param'\n";
+ " No description found for parameter '$param'\n";
++$warnings;
- }
- }
+ }
+ }
push @parameterlist, $param;
$parametertypes{$param} = $type;
@@ -1664,10 +1694,10 @@
# do nothing
}
elsif ($x =~ /([^\{]*)/) {
- $prototype .= $1;
+ $prototype .= $1;
}
if (($x =~ /\{/) || ($x =~ /\#define/) || ($x =~ /;/)) {
- $prototype =~ s@/\*.*?\*/@@gos; # strip comments.
+ $prototype =~ s@/\*.*?\*/@@gos; # strip comments.
$prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
$prototype =~ s@^\s+@@gos; # strip leading spaces
dump_function($prototype,$file);
@@ -1688,17 +1718,17 @@
}
while (1) {
- if ( $x =~ /([^{};]*)([{};])(.*)/ ) {
+ if ( $x =~ /([^{};]*)([{};])(.*)/ ) {
$prototype .= $1 . $2;
($2 eq '{') && $brcount++;
($2 eq '}') && $brcount--;
if (($2 eq ';') && ($brcount == 0)) {
- dump_declaration($prototype,$file);
+ dump_declaration($prototype,$file);
reset_state();
- last;
+ last;
}
$x = $3;
- } else {
+ } else {
$prototype .= $x;
last;
}
@@ -1756,7 +1786,7 @@
} else {
$section = $1;
}
- }
+ }
elsif (/$doc_decl/o) {
$identifier = $1;
if (/\s*([\w\s]+?)\s*-/) {
@@ -1849,13 +1879,13 @@
}
} elsif ($state == 3) { # scanning for function '{' (end of prototype)
if ($decl_type eq 'function') {
- process_state3_function($_, $file);
+ process_state3_function($_, $file);
} else {
- process_state3_type($_, $file);
+ process_state3_type($_, $file);
}
} elsif ($state == 4) {
# Documentation block
- if (/$doc_block/) {
+ if (/$doc_block/) {
dump_section($section, $contents);
output_intro({'sectionlist' => \@sectionlist,
'sections' => \%sections });
@@ -1873,7 +1903,7 @@
} else {
$section = $1;
}
- }
+ }
elsif (/$doc_end/)
{
dump_section($section, $contents);
@@ -1900,8 +1930,8 @@
{
$contents .= $1 . "\n";
}
- }
- }
+ }
+ }
}
if ($initial_section_counter == $section_counter) {
print STDERR "Warning(${file}): no structured comments found\n";
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 4ab36de..480e18b 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -642,6 +642,16 @@
* tosec = .init.text
* fromsec = .paravirtprobe
*
+ * Pattern 9:
+ * Some of functions are common code between boot time and hotplug
+ * time. The bootmem allocater is called only boot time in its
+ * functions. So it's ok to reference.
+ * tosec = .init.text
+ *
+ * Pattern 10:
+ * ia64 has machvec table for each platform. It is mixture of function
+ * pointer of .init.text and .text.
+ * fromsec = .machvec
**/
static int secref_whitelist(const char *modname, const char *tosec,
const char *fromsec, const char *atsym,
@@ -668,6 +678,12 @@
NULL
};
+ const char *pat4sym[] = {
+ "sparse_index_alloc",
+ "zone_wait_table_init",
+ NULL
+ };
+
/* Check for pattern 1 */
if (strcmp(tosec, ".init.data") != 0)
f1 = 0;
@@ -726,6 +742,17 @@
(strcmp(fromsec, ".paravirtprobe") == 0))
return 1;
+ /* Check for pattern 9 */
+ if ((strcmp(tosec, ".init.text") == 0) &&
+ (strcmp(fromsec, ".text") == 0))
+ for (s = pat4sym; *s; s++)
+ if (strcmp(atsym, *s) == 0)
+ return 1;
+
+ /* Check for pattern 10 */
+ if (strcmp(fromsec, ".machvec") == 0)
+ return 1;
+
return 0;
}
diff --git a/security/capability.c b/security/capability.c
index b868e7e..38296a0 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -17,7 +17,6 @@
#include <linux/mman.h>
#include <linux/pagemap.h>
#include <linux/swap.h>
-#include <linux/smp_lock.h>
#include <linux/skbuff.h>
#include <linux/netlink.h>
#include <linux/ptrace.h>
diff --git a/security/commoncap.c b/security/commoncap.c
index 5a5ef5c..384379e 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -17,7 +17,6 @@
#include <linux/mman.h>
#include <linux/pagemap.h>
#include <linux/swap.h>
-#include <linux/smp_lock.h>
#include <linux/skbuff.h>
#include <linux/netlink.h>
#include <linux/ptrace.h>
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 885a9a9..ad8dd4e 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -35,7 +35,6 @@
#include <linux/slab.h>
#include <linux/pagemap.h>
#include <linux/swap.h>
-#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/syscalls.h>
#include <linux/file.h>
@@ -1758,12 +1757,11 @@
}
}
file_list_unlock();
-
- /* Reset controlling tty. */
- if (drop_tty)
- proc_set_tty(current, NULL);
}
mutex_unlock(&tty_mutex);
+ /* Reset controlling tty. */
+ if (drop_tty)
+ no_tty();
/* Revalidate access to inherited open files. */
diff --git a/sound/aoa/codecs/snd-aoa-codec-onyx.c b/sound/aoa/codecs/snd-aoa-codec-onyx.c
index 7f980be..e91f9f6 100644
--- a/sound/aoa/codecs/snd-aoa-codec-onyx.c
+++ b/sound/aoa/codecs/snd-aoa-codec-onyx.c
@@ -1061,7 +1061,7 @@
busnode = pmac_i2c_get_bus_node(bus);
while ((dev = of_get_next_child(busnode, dev)) != NULL) {
- if (device_is_compatible(dev, "pcm3052")) {
+ if (of_device_is_compatible(dev, "pcm3052")) {
const u32 *addr;
printk(KERN_DEBUG PFX "found pcm3052\n");
addr = of_get_property(dev, "reg", NULL);
@@ -1074,7 +1074,7 @@
/* if that didn't work, try desperate mode for older
* machines that have stuff missing from the device tree */
- if (!device_is_compatible(busnode, "k2-i2c"))
+ if (!of_device_is_compatible(busnode, "k2-i2c"))
return -ENODEV;
printk(KERN_DEBUG PFX "found k2-i2c, checking if onyx chip is on it\n");
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas.c b/sound/aoa/codecs/snd-aoa-codec-tas.c
index ceca384..041fe52 100644
--- a/sound/aoa/codecs/snd-aoa-codec-tas.c
+++ b/sound/aoa/codecs/snd-aoa-codec-tas.c
@@ -938,7 +938,7 @@
busnode = pmac_i2c_get_bus_node(bus);
while ((dev = of_get_next_child(busnode, dev)) != NULL) {
- if (device_is_compatible(dev, "tas3004")) {
+ if (of_device_is_compatible(dev, "tas3004")) {
const u32 *addr;
printk(KERN_DEBUG PFX "found tas3004\n");
addr = of_get_property(dev, "reg", NULL);
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-core.c b/sound/aoa/soundbus/i2sbus/i2sbus-core.c
index 79fc4bc..0fccdbf 100644
--- a/sound/aoa/soundbus/i2sbus/i2sbus-core.c
+++ b/sound/aoa/soundbus/i2sbus/i2sbus-core.c
@@ -336,8 +336,8 @@
}
while ((np = of_get_next_child(dev->ofdev.node, np))) {
- if (device_is_compatible(np, "i2sbus") ||
- device_is_compatible(np, "i2s-modem")) {
+ if (of_device_is_compatible(np, "i2sbus") ||
+ of_device_is_compatible(np, "i2s-modem")) {
got += i2sbus_add_dev(dev, control, np);
}
}
diff --git a/sound/core/control.c b/sound/core/control.c
index 86de725..1f1ab9c 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -22,7 +22,6 @@
#include <sound/driver.h>
#include <linux/threads.h>
#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/time.h>
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c
index 96ffdf1..51ad95b 100644
--- a/sound/core/hwdep.c
+++ b/sound/core/hwdep.c
@@ -22,7 +22,6 @@
#include <sound/driver.h>
#include <linux/major.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/mutex.h>
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index 74a2923..fccad8f 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -21,7 +21,6 @@
#include <sound/driver.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/string.h>
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index c4744bb..fc11572 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -28,7 +28,6 @@
#include <sound/driver.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/vmalloc.h>
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 3e276fc..9052348 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -21,7 +21,6 @@
#include <sound/driver.h>
#include <linux/mm.h>
-#include <linux/smp_lock.h>
#include <linux/file.h>
#include <linux/slab.h>
#include <linux/time.h>
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index d14dcbb..e470c3c7 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -23,7 +23,6 @@
#include <sound/core.h>
#include <linux/major.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/time.h>
diff --git a/sound/core/seq/oss/seq_oss.c b/sound/core/seq/oss/seq_oss.c
index 2eb9873..bc09923 100644
--- a/sound/core/seq/oss/seq_oss.c
+++ b/sound/core/seq/oss/seq_oss.c
@@ -22,7 +22,6 @@
#include <sound/driver.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/moduleparam.h>
#include <linux/mutex.h>
#include <sound/core.h>
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index 694efe8..b31b528 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -23,7 +23,6 @@
#include <sound/driver.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/minors.h>
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 160e40e..67520b3 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -22,7 +22,6 @@
#include <sound/driver.h>
#include <linux/delay.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/mutex.h>
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig
index 4c41930..4b30ae6 100644
--- a/sound/oss/Kconfig
+++ b/sound/oss/Kconfig
@@ -5,23 +5,22 @@
#
# Prompt user for primary drivers.
-config OBSOLETE_OSS
+config OSS_OBSOLETE
bool "Obsolete OSS drivers"
depends on SOUND_PRIME
help
This option enables support for obsolete OSS drivers that
- are scheduled for removal in the near future since there
- are ALSA drivers for the same hardware.
+ are scheduled for removal in the near future.
Please contact Adrian Bunk <bunk@stusta.de> if you had to
- say Y here because your soundcard is not properly supported
+ say Y here because your hardware is not properly supported
by ALSA.
If unsure, say N.
config SOUND_BT878
tristate "BT878 audio dma"
- depends on SOUND_PRIME && PCI
+ depends on SOUND_PRIME && PCI && OSS_OBSOLETE
---help---
Audio DMA support for bt878 based grabber boards. As you might have
already noticed, bt878 is listed with two functions in /proc/pci.
@@ -45,22 +44,9 @@
note that CONFIG_KGDB should not be enabled at the same
time, since it also attempts to use this UART port.
-config SOUND_ES1371
- tristate "Creative Ensoniq AudioPCI 97 (ES1371)"
- depends on SOUND_PRIME && PCI && OBSOLETE_OSS
- help
- Say Y or M if you have a PCI sound card utilizing the Ensoniq
- ES1371 chipset, such as Ensoniq's AudioPCI97. To find out if
- your sound card uses an ES1371 without removing your computer's
- cover, use lspci -n and look for the PCI ID 1274:1371. Since
- Ensoniq was bought by Creative Labs, Sound Blaster 64/PCI
- models are either ES1370 or ES1371 based. This driver differs
- slightly from OSS/Free, so PLEASE READ
- <file:Documentation/sound/oss/es1371>.
-
config SOUND_ICH
tristate "Intel ICH (i8xx) audio support"
- depends on SOUND_PRIME && PCI
+ depends on SOUND_PRIME && PCI && OSS_OBSOLETE
help
Support for integral audio in Intel's I/O Controller Hub (ICH)
chipset, as used on the 810/820/840 motherboards.
@@ -362,7 +348,7 @@
config SOUND_VIA82CXXX
tristate "VIA 82C686 Audio Codec"
- depends on SOUND_PRIME && PCI
+ depends on SOUND_PRIME && PCI && OSS_OBSOLETE
help
Say Y here to include support for the audio codec found on VIA
82Cxxx-based chips. Typically these are built into a motherboard.
@@ -416,7 +402,7 @@
config SOUND_CS4232
tristate "Crystal CS4232 based (PnP) cards"
- depends on SOUND_OSS
+ depends on SOUND_OSS && OSS_OBSOLETE
help
Say Y here if you have a card based on the Crystal CS4232 chip set,
which uses its own Plug and Play protocol.
@@ -735,7 +721,7 @@
config SOUND_TVMIXER
tristate "TV card (bt848) mixer support"
- depends on SOUND_PRIME && I2C && VIDEO_V4L1
+ depends on SOUND_PRIME && I2C && VIDEO_V4L1 && OSS_OBSOLETE
help
Support for audio mixer facilities on the BT848 TV frame-grabber
card.
diff --git a/sound/oss/btaudio.c b/sound/oss/btaudio.c
index f813ae9..4d5cf05 100644
--- a/sound/oss/btaudio.c
+++ b/sound/oss/btaudio.c
@@ -344,7 +344,7 @@
if (cmd == SOUND_OLD_MIXER_INFO) {
_old_mixer_info info;
memset(&info,0,sizeof(info));
- strlcpy(info.id,"bt878",sizeof(info.id)-1);
+ strlcpy(info.id, "bt878", sizeof(info.id));
strlcpy(info.name,"Brooktree Bt878 audio",sizeof(info.name));
if (copy_to_user(argp, &info, sizeof(info)))
return -EFAULT;
diff --git a/sound/oss/dmasound/Kconfig b/sound/oss/dmasound/Kconfig
index 18e149f..71b3134 100644
--- a/sound/oss/dmasound/Kconfig
+++ b/sound/oss/dmasound/Kconfig
@@ -12,20 +12,6 @@
want). If you want to compile it as a module, say M here and read
<file:Documentation/kbuild/modules.txt>.
-config DMASOUND_PMAC
- tristate "PowerMac DMA sound support"
- depends on PPC32 && PPC_PMAC && SOUND && I2C && OBSOLETE_OSS
- select DMASOUND
- help
- If you want to use the internal audio of your PowerMac in Linux,
- answer Y to this question. This will provide a Sun-like /dev/audio,
- compatible with the Linux/i386 sound system. Otherwise, say N.
-
- This driver is also available as a module ( = code which can be
- inserted in and removed from the running kernel whenever you
- want). If you want to compile it as a module, say M here and read
- <file:Documentation/kbuild/modules.txt>.
-
config DMASOUND_PAULA
tristate "Amiga DMA sound support"
depends on (AMIGA || APUS) && SOUND
diff --git a/sound/oss/dmasound/dmasound_awacs.c b/sound/oss/dmasound/dmasound_awacs.c
index 730fa1d..8f63880 100644
--- a/sound/oss/dmasound/dmasound_awacs.c
+++ b/sound/oss/dmasound/dmasound_awacs.c
@@ -362,7 +362,7 @@
of_get_property(np,"audio-gpio",NULL);
if (property != 0 && strcmp(property,name) == 0)
break;
- } else if (compatible && device_is_compatible(np, compatible))
+ } else if (compatible && of_device_is_compatible(np, compatible))
break;
np = of_get_next_child(gpiop, np);
}
@@ -2620,17 +2620,17 @@
if (info) {
/* must do awacs first to allow screamer to overide it */
- if (device_is_compatible(info, "awacs"))
+ if (of_device_is_compatible(info, "awacs"))
codec = AWACS_AWACS ;
- if (device_is_compatible(info, "screamer"))
+ if (of_device_is_compatible(info, "screamer"))
codec = AWACS_SCREAMER;
- if (device_is_compatible(info, "burgundy"))
+ if (of_device_is_compatible(info, "burgundy"))
codec = AWACS_BURGUNDY ;
- if (device_is_compatible(info, "daca"))
+ if (of_device_is_compatible(info, "daca"))
codec = AWACS_DACA;
- if (device_is_compatible(info, "tumbler"))
+ if (of_device_is_compatible(info, "tumbler"))
codec = AWACS_TUMBLER;
- if (device_is_compatible(info, "snapper"))
+ if (of_device_is_compatible(info, "snapper"))
codec = AWACS_SNAPPER;
}
return codec ;
@@ -2772,7 +2772,7 @@
for (mio = io->parent; mio ; mio = mio->parent) {
if (strcmp(mio->name, "mac-io") == 0) {
- if (device_is_compatible(mio, "Keylargo"))
+ if (of_device_is_compatible(mio, "Keylargo"))
kl = 1;
break;
}
diff --git a/sound/oss/swarm_cs4297a.c b/sound/oss/swarm_cs4297a.c
index 016b918..a8057f2 100644
--- a/sound/oss/swarm_cs4297a.c
+++ b/sound/oss/swarm_cs4297a.c
@@ -75,7 +75,6 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/poll.h>
-#include <linux/smp_lock.h>
#include <linux/mutex.h>
#include <linux/kernel.h>
diff --git a/sound/oss/trident.c b/sound/oss/trident.c
index 72a8a0e..d98d311 100644
--- a/sound/oss/trident.c
+++ b/sound/oss/trident.c
@@ -207,7 +207,6 @@
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
#include <linux/ac97_codec.h>
#include <linux/bitops.h>
#include <linux/proc_fs.h>
diff --git a/sound/oss/via82cxxx_audio.c b/sound/oss/via82cxxx_audio.c
index 7ab3a73..5d3c037 100644
--- a/sound/oss/via82cxxx_audio.c
+++ b/sound/oss/via82cxxx_audio.c
@@ -32,7 +32,6 @@
#include <linux/poll.h>
#include <linux/soundcard.h>
#include <linux/ac97_codec.h>
-#include <linux/smp_lock.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c
index 2bae9c1..5a2bef4 100644
--- a/sound/ppc/pmac.c
+++ b/sound/ppc/pmac.c
@@ -843,7 +843,7 @@
/* if seems that Keylargo can't byte-swap */
for (mio = chip->node->parent; mio; mio = mio->parent) {
if (strcmp(mio->name, "mac-io") == 0) {
- if (device_is_compatible(mio, "Keylargo"))
+ if (of_device_is_compatible(mio, "Keylargo"))
chip->can_byte_swap = 0;
break;
}
@@ -910,7 +910,7 @@
chip->node = of_find_node_by_name(NULL, "i2s-a");
if (chip->node && chip->node->parent &&
chip->node->parent->parent) {
- if (device_is_compatible(chip->node->parent->parent,
+ if (of_device_is_compatible(chip->node->parent->parent,
"K2-Keylargo"))
chip->is_k2 = 1;
}
@@ -941,22 +941,22 @@
return -ENODEV;
}
/* This should be verified on older screamers */
- if (device_is_compatible(sound, "screamer")) {
+ if (of_device_is_compatible(sound, "screamer")) {
chip->model = PMAC_SCREAMER;
// chip->can_byte_swap = 0; /* FIXME: check this */
}
- if (device_is_compatible(sound, "burgundy")) {
+ if (of_device_is_compatible(sound, "burgundy")) {
chip->model = PMAC_BURGUNDY;
chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */
}
- if (device_is_compatible(sound, "daca")) {
+ if (of_device_is_compatible(sound, "daca")) {
chip->model = PMAC_DACA;
chip->can_capture = 0; /* no capture */
chip->can_duplex = 0;
// chip->can_byte_swap = 0; /* FIXME: check this */
chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */
}
- if (device_is_compatible(sound, "tumbler")) {
+ if (of_device_is_compatible(sound, "tumbler")) {
chip->model = PMAC_TUMBLER;
chip->can_capture = 0; /* no capture */
chip->can_duplex = 0;
@@ -965,7 +965,7 @@
chip->freq_table = tumbler_freqs;
chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */
}
- if (device_is_compatible(sound, "snapper")) {
+ if (of_device_is_compatible(sound, "snapper")) {
chip->model = PMAC_SNAPPER;
// chip->can_byte_swap = 0; /* FIXME: check this */
chip->num_freqs = ARRAY_SIZE(tumbler_freqs);
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c
index 54e333f..5821cdd 100644
--- a/sound/ppc/tumbler.c
+++ b/sound/ppc/tumbler.c
@@ -1060,7 +1060,7 @@
for (np = of_get_next_child(gpiop, NULL); np;
np = of_get_next_child(gpiop, np)) {
- if (device_is_compatible(np, name))
+ if (of_device_is_compatible(np, name))
break;
}
of_node_put(gpiop);