瀏覽代碼

Merge with Linus' kernel.

Russell King 19 年之前
父節點
當前提交
123656d4cc
共有 100 個文件被更改,包括 3176 次插入1385 次删除
  1. 2 0
      .gitignore
  2. 1 0
      CREDITS
  3. 1 0
      Documentation/DocBook/usb.tmpl
  4. 2 2
      Documentation/SubmittingPatches
  5. 3 9
      Documentation/block/biodoc.txt
  6. 59 3
      Documentation/cpu-freq/governors.txt
  7. 0 20
      Documentation/feature-removal-schedule.txt
  8. 6 2
      Documentation/filesystems/00-INDEX
  9. 434 0
      Documentation/filesystems/configfs/configfs.txt
  10. 474 0
      Documentation/filesystems/configfs/configfs_example.c
  11. 130 0
      Documentation/filesystems/dlmfs.txt
  12. 55 0
      Documentation/filesystems/ocfs2.txt
  13. 2 3
      Documentation/filesystems/vfs.txt
  14. 11 8
      Documentation/hwmon/w83627hf
  15. 2 1
      Documentation/i2c/busses/i2c-nforce2
  16. 1 0
      Documentation/i2c/busses/i2c-parport
  17. 53 37
      Documentation/i2c/porting-clients
  18. 6 14
      Documentation/i2c/writing-clients
  19. 53 13
      Documentation/kbuild/modules.txt
  20. 16 0
      Documentation/kernel-parameters.txt
  21. 0 18
      Documentation/keys.txt
  22. 120 0
      Documentation/md.txt
  23. 72 0
      Documentation/networking/gianfar.txt
  24. 23 0
      Documentation/networking/ip-sysctl.txt
  25. 11 0
      Documentation/pcmcia/driver-changes.txt
  26. 11 0
      Documentation/power/interface.txt
  27. 5 0
      Documentation/power/swsusp.txt
  28. 16 15
      Documentation/powerpc/eeh-pci-error-recovery.txt
  29. 35 0
      Documentation/scsi/ChangeLog.megaraid
  30. 29 10
      Documentation/scsi/scsi_mid_low_api.txt
  31. 130 64
      Documentation/sound/alsa/ALSA-Configuration.txt
  32. 165 164
      Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
  33. 16 0
      Documentation/sound/alsa/Procfile.txt
  34. 7 7
      Documentation/sound/alsa/hda_codec.txt
  35. 1 5
      Documentation/sysrq.txt
  36. 43 20
      MAINTAINERS
  37. 17 13
      Makefile
  38. 13 0
      arch/alpha/Kconfig
  39. 0 1
      arch/alpha/kernel/alpha_ksyms.c
  40. 9 621
      arch/alpha/kernel/irq.c
  41. 3 3
      arch/arm/common/amba.c
  42. 3 4
      arch/arm/mach-pxa/akita-ioexp.c
  43. 21 0
      arch/arm/mach-pxa/mainstone.c
  44. 6 0
      arch/arm/mach-pxa/pxa27x.c
  45. 1 2
      arch/arm26/nwfpe/fpmodule.c
  46. 0 6
      arch/cris/arch-v10/kernel/kgdb.c
  47. 1 0
      arch/frv/kernel/Makefile
  48. 1 1
      arch/frv/kernel/entry.S
  49. 242 0
      arch/frv/kernel/futex.c
  50. 85 70
      arch/frv/kernel/signal.c
  51. 6 2
      arch/i386/Kconfig
  52. 10 4
      arch/i386/Kconfig.cpu
  53. 10 0
      arch/i386/Kconfig.debug
  54. 1 1
      arch/i386/kernel/apic.c
  55. 36 61
      arch/i386/kernel/apm.c
  56. 6 1
      arch/i386/kernel/cpu/amd.c
  57. 0 8
      arch/i386/kernel/cpu/common.c
  58. 2 1
      arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c
  59. 28 22
      arch/i386/kernel/cpu/cpufreq/powernow-k8.c
  60. 5 4
      arch/i386/kernel/cpu/cpufreq/powernow-k8.h
  61. 32 15
      arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
  62. 31 1
      arch/i386/kernel/cpu/cpufreq/speedstep-lib.c
  63. 1 0
      arch/i386/kernel/cpu/cpufreq/speedstep-lib.h
  64. 1 0
      arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
  65. 26 1
      arch/i386/kernel/cpu/cyrix.c
  66. 5 1
      arch/i386/kernel/cpu/proc.c
  67. 1 2
      arch/i386/kernel/cpuid.c
  68. 1 0
      arch/i386/kernel/entry.S
  69. 17 10
      arch/i386/kernel/head.S
  70. 1 2
      arch/i386/kernel/i386_ksyms.c
  71. 2 2
      arch/i386/kernel/io_apic.c
  72. 18 8
      arch/i386/kernel/mpparse.c
  73. 1 2
      arch/i386/kernel/msr.c
  74. 2 14
      arch/i386/kernel/process.c
  75. 6 3
      arch/i386/kernel/ptrace.c
  76. 3 3
      arch/i386/kernel/reboot.c
  77. 8 0
      arch/i386/kernel/setup.c
  78. 6 0
      arch/i386/kernel/smpboot.c
  79. 0 1
      arch/i386/kernel/syscall_table.S
  80. 2 0
      arch/i386/kernel/timers/timer_tsc.c
  81. 30 5
      arch/i386/kernel/traps.c
  82. 24 0
      arch/i386/mm/init.c
  83. 21 6
      arch/i386/mm/pageattr.c
  84. 1 1
      arch/i386/pci/irq.c
  85. 7 1
      arch/ia64/kernel/setup.c
  86. 1 1
      arch/ia64/pci/pci.c
  87. 2 2
      arch/ia64/sn/kernel/tiocx.c
  88. 20 6
      arch/m32r/Kconfig
  89. 5 0
      arch/m32r/boot/compressed/head.S
  90. 21 3
      arch/m32r/boot/setup.S
  91. 1 0
      arch/m32r/kernel/Makefile
  92. 15 4
      arch/m32r/kernel/entry.S
  93. 298 0
      arch/m32r/kernel/io_m32104ut.c
  94. 12 12
      arch/m32r/kernel/io_m32700ut.c
  95. 1 1
      arch/m32r/kernel/io_mappi.c
  96. 12 12
      arch/m32r/kernel/io_mappi2.c
  97. 30 21
      arch/m32r/kernel/io_mappi3.c
  98. 1 1
      arch/m32r/kernel/io_oaks32r.c
  99. 3 3
      arch/m32r/kernel/io_opsput.c
  100. 6 1
      arch/m32r/kernel/setup.c

+ 2 - 0
.gitignore

@@ -10,6 +10,7 @@
 *.a
 *.a
 *.s
 *.s
 *.ko
 *.ko
+*.so
 *.mod.c
 *.mod.c
 
 
 #
 #
@@ -23,6 +24,7 @@ Module.symvers
 # Generated include files
 # Generated include files
 #
 #
 include/asm
 include/asm
+include/asm-*/asm-offsets.h
 include/config
 include/config
 include/linux/autoconf.h
 include/linux/autoconf.h
 include/linux/compile.h
 include/linux/compile.h

+ 1 - 0
CREDITS

@@ -1883,6 +1883,7 @@ N: Jaya Kumar
 E: jayalk@intworks.biz
 E: jayalk@intworks.biz
 W: http://www.intworks.biz
 W: http://www.intworks.biz
 D: Arc monochrome LCD framebuffer driver, x86 reboot fixups
 D: Arc monochrome LCD framebuffer driver, x86 reboot fixups
+D: pirq addr, CS5535 alsa audio driver
 S: Gurgaon, India
 S: Gurgaon, India
 S: Kuala Lumpur, Malaysia
 S: Kuala Lumpur, Malaysia
 
 

+ 1 - 0
Documentation/DocBook/usb.tmpl

@@ -253,6 +253,7 @@
 !Edrivers/usb/core/urb.c
 !Edrivers/usb/core/urb.c
 !Edrivers/usb/core/message.c
 !Edrivers/usb/core/message.c
 !Edrivers/usb/core/file.c
 !Edrivers/usb/core/file.c
+!Edrivers/usb/core/driver.c
 !Edrivers/usb/core/usb.c
 !Edrivers/usb/core/usb.c
 !Edrivers/usb/core/hub.c
 !Edrivers/usb/core/hub.c
     </chapter>
     </chapter>

+ 2 - 2
Documentation/SubmittingPatches

@@ -158,7 +158,7 @@ Even if the maintainer did not respond in step #4, make sure to ALWAYS
 copy the maintainer when you change their code.
 copy the maintainer when you change their code.
 
 
 For small patches you may want to CC the Trivial Patch Monkey
 For small patches you may want to CC the Trivial Patch Monkey
-trivial@rustcorp.com.au set up by Rusty Russell; which collects "trivial"
+trivial@kernel.org managed by Adrian Bunk; which collects "trivial"
 patches. Trivial patches must qualify for one of the following rules:
 patches. Trivial patches must qualify for one of the following rules:
  Spelling fixes in documentation
  Spelling fixes in documentation
  Spelling fixes which could break grep(1).
  Spelling fixes which could break grep(1).
@@ -171,7 +171,7 @@ patches. Trivial patches must qualify for one of the following rules:
  since people copy, as long as it's trivial)
  since people copy, as long as it's trivial)
  Any fix by the author/maintainer of the file. (ie. patch monkey
  Any fix by the author/maintainer of the file. (ie. patch monkey
  in re-transmission mode)
  in re-transmission mode)
-URL: <http://www.kernel.org/pub/linux/kernel/people/rusty/trivial/>
+URL: <http://www.kernel.org/pub/linux/kernel/people/bunk/trivial/>
 
 
 
 
 
 

+ 3 - 9
Documentation/block/biodoc.txt

@@ -31,7 +31,7 @@ The following people helped with review comments and inputs for this
 document:
 document:
 	Christoph Hellwig <hch@infradead.org>
 	Christoph Hellwig <hch@infradead.org>
 	Arjan van de Ven <arjanv@redhat.com>
 	Arjan van de Ven <arjanv@redhat.com>
-	Randy Dunlap <rddunlap@osdl.org>
+	Randy Dunlap <rdunlap@xenotime.net>
 	Andre Hedrick <andre@linux-ide.org>
 	Andre Hedrick <andre@linux-ide.org>
 
 
 The following people helped with fixes/contributions to the bio patches
 The following people helped with fixes/contributions to the bio patches
@@ -263,14 +263,8 @@ A flag in the bio structure, BIO_BARRIER is used to identify a barrier i/o.
 The generic i/o scheduler would make sure that it places the barrier request and
 The generic i/o scheduler would make sure that it places the barrier request and
 all other requests coming after it after all the previous requests in the
 all other requests coming after it after all the previous requests in the
 queue. Barriers may be implemented in different ways depending on the
 queue. Barriers may be implemented in different ways depending on the
-driver. A SCSI driver for example could make use of ordered tags to
-preserve the necessary ordering with a lower impact on throughput. For IDE
-this might be two sync cache flush: a pre and post flush when encountering
-a barrier write.
-
-There is a provision for queues to indicate what kind of barriers they
-can provide. This is as of yet unmerged, details will be added here once it
-is in the kernel.
+driver. For more details regarding I/O barriers, please read barrier.txt
+in this directory.
 
 
 1.2.2 Request Priority/Latency
 1.2.2 Request Priority/Latency
 
 

+ 59 - 3
Documentation/cpu-freq/governors.txt

@@ -27,6 +27,7 @@ Contents:
 2.2  Powersave
 2.2  Powersave
 2.3  Userspace
 2.3  Userspace
 2.4  Ondemand
 2.4  Ondemand
+2.5  Conservative
 
 
 3.   The Governor Interface in the CPUfreq Core
 3.   The Governor Interface in the CPUfreq Core
 
 
@@ -110,9 +111,64 @@ directory.
 
 
 The CPUfreq govenor "ondemand" sets the CPU depending on the
 The CPUfreq govenor "ondemand" sets the CPU depending on the
 current usage. To do this the CPU must have the capability to
 current usage. To do this the CPU must have the capability to
-switch the frequency very fast.
-
-
+switch the frequency very quickly.  There are a number of sysfs file
+accessible parameters:
+
+sampling_rate: measured in uS (10^-6 seconds), this is how often you
+want the kernel to look at the CPU usage and to make decisions on
+what to do about the frequency.  Typically this is set to values of
+around '10000' or more.
+
+show_sampling_rate_(min|max): the minimum and maximum sampling rates
+available that you may set 'sampling_rate' to.
+
+up_threshold: defines what the average CPU usaged between the samplings
+of 'sampling_rate' needs to be for the kernel to make a decision on
+whether it should increase the frequency.  For example when it is set
+to its default value of '80' it means that between the checking
+intervals the CPU needs to be on average more than 80% in use to then
+decide that the CPU frequency needs to be increased.  
+
+sampling_down_factor: this parameter controls the rate that the CPU
+makes a decision on when to decrease the frequency.  When set to its
+default value of '5' it means that at 1/5 the sampling_rate the kernel
+makes a decision to lower the frequency.  Five "lower rate" decisions
+have to be made in a row before the CPU frequency is actually lower.
+If set to '1' then the frequency decreases as quickly as it increases,
+if set to '2' it decreases at half the rate of the increase.
+
+ignore_nice_load: this parameter takes a value of '0' or '1', when set
+to '0' (its default) then all processes are counted towards towards the
+'cpu utilisation' value.   When set to '1' then processes that are
+run with a 'nice' value will not count (and thus be ignored) in the
+overal usage calculation.  This is useful if you are running a CPU
+intensive calculation on your laptop that you do not care how long it
+takes to complete as you can 'nice' it and prevent it from taking part
+in the deciding process of whether to increase your CPU frequency.
+
+
+2.5 Conservative
+----------------
+
+The CPUfreq governor "conservative", much like the "ondemand"
+governor, sets the CPU depending on the current usage.  It differs in
+behaviour in that it gracefully increases and decreases the CPU speed
+rather than jumping to max speed the moment there is any load on the
+CPU.  This behaviour more suitable in a battery powered environment.
+The governor is tweaked in the same manner as the "ondemand" governor
+through sysfs with the addition of:
+
+freq_step: this describes what percentage steps the cpu freq should be
+increased and decreased smoothly by.  By default the cpu frequency will
+increase in 5% chunks of your maximum cpu frequency.  You can change this
+value to anywhere between 0 and 100 where '0' will effectively lock your
+CPU at a speed regardless of its load whilst '100' will, in theory, make
+it behave identically to the "ondemand" governor.
+
+down_threshold: same as the 'up_threshold' found for the "ondemand"
+governor but for the opposite direction.  For example when set to its
+default value of '20' it means that if the CPU usage needs to be below
+20% between samples to have the frequency decreased.
 
 
 3. The Governor Interface in the CPUfreq Core
 3. The Governor Interface in the CPUfreq Core
 =============================================
 =============================================

+ 0 - 20
Documentation/feature-removal-schedule.txt

@@ -47,17 +47,6 @@ Who:	Paul E. McKenney <paulmck@us.ibm.com>
 
 
 ---------------------------
 ---------------------------
 
 
-What:	IEEE1394 Audio and Music Data Transmission Protocol driver,
-	Connection Management Procedures driver
-When:	November 2005
-Files:	drivers/ieee1394/{amdtp,cmp}*
-Why:	These are incomplete, have never worked, and are better implemented
-	in userland via raw1394 (see http://freebob.sourceforge.net/ for
-	example.)
-Who:	Jody McIntyre <scjody@steamballoon.com>
-
----------------------------
-
 What:	raw1394: requests of type RAW1394_REQ_ISO_SEND, RAW1394_REQ_ISO_LISTEN
 What:	raw1394: requests of type RAW1394_REQ_ISO_SEND, RAW1394_REQ_ISO_LISTEN
 When:	November 2005
 When:	November 2005
 Why:	Deprecated in favour of the new ioctl-based rawiso interface, which is
 Why:	Deprecated in favour of the new ioctl-based rawiso interface, which is
@@ -82,15 +71,6 @@ Who:	Mauro Carvalho Chehab <mchehab@brturbo.com.br>
 
 
 ---------------------------
 ---------------------------
 
 
-What:	i2c sysfs name change: in1_ref, vid deprecated in favour of cpu0_vid
-When:	November 2005
-Files:	drivers/i2c/chips/adm1025.c, drivers/i2c/chips/adm1026.c
-Why:	Match the other drivers' name for the same function, duplicate names
-	will be available until removal of old names.
-Who:	Grant Coady <gcoady@gmail.com>
-
----------------------------
-
 What:	remove EXPORT_SYMBOL(panic_timeout)
 What:	remove EXPORT_SYMBOL(panic_timeout)
 When:	April 2006
 When:	April 2006
 Files:	kernel/panic.c
 Files:	kernel/panic.c

+ 6 - 2
Documentation/filesystems/00-INDEX

@@ -12,14 +12,16 @@ cifs.txt
 	- description of the CIFS filesystem
 	- description of the CIFS filesystem
 coda.txt
 coda.txt
 	- description of the CODA filesystem.
 	- description of the CODA filesystem.
+configfs/
+	- directory containing configfs documentation and example code.
 cramfs.txt
 cramfs.txt
 	- info on the cram filesystem for small storage (ROMs etc)
 	- info on the cram filesystem for small storage (ROMs etc)
 devfs/
 devfs/
 	- directory containing devfs documentation.
 	- directory containing devfs documentation.
+dlmfs.txt
+	- info on the userspace interface to the OCFS2 DLM.
 ext2.txt
 ext2.txt
 	- info, mount options and specifications for the Ext2 filesystem.
 	- info, mount options and specifications for the Ext2 filesystem.
-fat_cvf.txt
-	- info on the Compressed Volume Files extension to the FAT filesystem
 hpfs.txt
 hpfs.txt
 	- info and mount options for the OS/2 HPFS.
 	- info and mount options for the OS/2 HPFS.
 isofs.txt
 isofs.txt
@@ -32,6 +34,8 @@ ntfs.txt
 	- info and mount options for the NTFS filesystem (Windows NT).
 	- info and mount options for the NTFS filesystem (Windows NT).
 proc.txt
 proc.txt
 	- info on Linux's /proc filesystem.
 	- info on Linux's /proc filesystem.
+ocfs2.txt
+	- info and mount options for the OCFS2 clustered filesystem.
 romfs.txt
 romfs.txt
 	- Description of the ROMFS filesystem.
 	- Description of the ROMFS filesystem.
 smbfs.txt
 smbfs.txt

+ 434 - 0
Documentation/filesystems/configfs/configfs.txt

@@ -0,0 +1,434 @@
+
+configfs - Userspace-driven kernel object configuation.
+
+Joel Becker <joel.becker@oracle.com>
+
+Updated: 31 March 2005
+
+Copyright (c) 2005 Oracle Corporation,
+	Joel Becker <joel.becker@oracle.com>
+
+
+[What is configfs?]
+
+configfs is a ram-based filesystem that provides the converse of
+sysfs's functionality.  Where sysfs is a filesystem-based view of
+kernel objects, configfs is a filesystem-based manager of kernel
+objects, or config_items.
+
+With sysfs, an object is created in kernel (for example, when a device
+is discovered) and it is registered with sysfs.  Its attributes then
+appear in sysfs, allowing userspace to read the attributes via
+readdir(3)/read(2).  It may allow some attributes to be modified via
+write(2).  The important point is that the object is created and
+destroyed in kernel, the kernel controls the lifecycle of the sysfs
+representation, and sysfs is merely a window on all this.
+
+A configfs config_item is created via an explicit userspace operation:
+mkdir(2).  It is destroyed via rmdir(2).  The attributes appear at
+mkdir(2) time, and can be read or modified via read(2) and write(2).
+As with sysfs, readdir(3) queries the list of items and/or attributes.
+symlink(2) can be used to group items together.  Unlike sysfs, the
+lifetime of the representation is completely driven by userspace.  The
+kernel modules backing the items must respond to this.
+
+Both sysfs and configfs can and should exist together on the same
+system.  One is not a replacement for the other.
+
+[Using configfs]
+
+configfs can be compiled as a module or into the kernel.  You can access
+it by doing
+
+	mount -t configfs none /config
+
+The configfs tree will be empty unless client modules are also loaded.
+These are modules that register their item types with configfs as
+subsystems.  Once a client subsystem is loaded, it will appear as a
+subdirectory (or more than one) under /config.  Like sysfs, the
+configfs tree is always there, whether mounted on /config or not.
+
+An item is created via mkdir(2).  The item's attributes will also
+appear at this time.  readdir(3) can determine what the attributes are,
+read(2) can query their default values, and write(2) can store new
+values.  Like sysfs, attributes should be ASCII text files, preferably
+with only one value per file.  The same efficiency caveats from sysfs
+apply.  Don't mix more than one attribute in one attribute file.
+
+Like sysfs, configfs expects write(2) to store the entire buffer at
+once.  When writing to configfs attributes, userspace processes should
+first read the entire file, modify the portions they wish to change, and
+then write the entire buffer back.  Attribute files have a maximum size
+of one page (PAGE_SIZE, 4096 on i386).
+
+When an item needs to be destroyed, remove it with rmdir(2).  An
+item cannot be destroyed if any other item has a link to it (via
+symlink(2)).  Links can be removed via unlink(2).
+
+[Configuring FakeNBD: an Example]
+
+Imagine there's a Network Block Device (NBD) driver that allows you to
+access remote block devices.  Call it FakeNBD.  FakeNBD uses configfs
+for its configuration.  Obviously, there will be a nice program that
+sysadmins use to configure FakeNBD, but somehow that program has to tell
+the driver about it.  Here's where configfs comes in.
+
+When the FakeNBD driver is loaded, it registers itself with configfs.
+readdir(3) sees this just fine:
+
+	# ls /config
+	fakenbd
+
+A fakenbd connection can be created with mkdir(2).  The name is
+arbitrary, but likely the tool will make some use of the name.  Perhaps
+it is a uuid or a disk name:
+
+	# mkdir /config/fakenbd/disk1
+	# ls /config/fakenbd/disk1
+	target device rw
+
+The target attribute contains the IP address of the server FakeNBD will
+connect to.  The device attribute is the device on the server.
+Predictably, the rw attribute determines whether the connection is
+read-only or read-write.
+
+	# echo 10.0.0.1 > /config/fakenbd/disk1/target
+	# echo /dev/sda1 > /config/fakenbd/disk1/device
+	# echo 1 > /config/fakenbd/disk1/rw
+
+That's it.  That's all there is.  Now the device is configured, via the
+shell no less.
+
+[Coding With configfs]
+
+Every object in configfs is a config_item.  A config_item reflects an
+object in the subsystem.  It has attributes that match values on that
+object.  configfs handles the filesystem representation of that object
+and its attributes, allowing the subsystem to ignore all but the
+basic show/store interaction.
+
+Items are created and destroyed inside a config_group.  A group is a
+collection of items that share the same attributes and operations.
+Items are created by mkdir(2) and removed by rmdir(2), but configfs
+handles that.  The group has a set of operations to perform these tasks
+
+A subsystem is the top level of a client module.  During initialization,
+the client module registers the subsystem with configfs, the subsystem
+appears as a directory at the top of the configfs filesystem.  A
+subsystem is also a config_group, and can do everything a config_group
+can.
+
+[struct config_item]
+
+	struct config_item {
+		char                    *ci_name;
+		char                    ci_namebuf[UOBJ_NAME_LEN];
+		struct kref             ci_kref;
+		struct list_head        ci_entry;
+		struct config_item      *ci_parent;
+		struct config_group     *ci_group;
+		struct config_item_type *ci_type;
+		struct dentry           *ci_dentry;
+	};
+
+	void config_item_init(struct config_item *);
+	void config_item_init_type_name(struct config_item *,
+					const char *name,
+					struct config_item_type *type);
+	struct config_item *config_item_get(struct config_item *);
+	void config_item_put(struct config_item *);
+
+Generally, struct config_item is embedded in a container structure, a
+structure that actually represents what the subsystem is doing.  The
+config_item portion of that structure is how the object interacts with
+configfs.
+
+Whether statically defined in a source file or created by a parent
+config_group, a config_item must have one of the _init() functions
+called on it.  This initializes the reference count and sets up the
+appropriate fields.
+
+All users of a config_item should have a reference on it via
+config_item_get(), and drop the reference when they are done via
+config_item_put().
+
+By itself, a config_item cannot do much more than appear in configfs.
+Usually a subsystem wants the item to display and/or store attributes,
+among other things.  For that, it needs a type.
+
+[struct config_item_type]
+
+	struct configfs_item_operations {
+		void (*release)(struct config_item *);
+		ssize_t (*show_attribute)(struct config_item *,
+					  struct configfs_attribute *,
+					  char *);
+		ssize_t (*store_attribute)(struct config_item *,
+					   struct configfs_attribute *,
+					   const char *, size_t);
+		int (*allow_link)(struct config_item *src,
+				  struct config_item *target);
+		int (*drop_link)(struct config_item *src,
+				 struct config_item *target);
+	};
+
+	struct config_item_type {
+		struct module                           *ct_owner;
+		struct configfs_item_operations         *ct_item_ops;
+		struct configfs_group_operations        *ct_group_ops;
+		struct configfs_attribute               **ct_attrs;
+	};
+
+The most basic function of a config_item_type is to define what
+operations can be performed on a config_item.  All items that have been
+allocated dynamically will need to provide the ct_item_ops->release()
+method.  This method is called when the config_item's reference count
+reaches zero.  Items that wish to display an attribute need to provide
+the ct_item_ops->show_attribute() method.  Similarly, storing a new
+attribute value uses the store_attribute() method.
+
+[struct configfs_attribute]
+
+	struct configfs_attribute {
+		char                    *ca_name;
+		struct module           *ca_owner;
+		mode_t                  ca_mode;
+	};
+
+When a config_item wants an attribute to appear as a file in the item's
+configfs directory, it must define a configfs_attribute describing it.
+It then adds the attribute to the NULL-terminated array
+config_item_type->ct_attrs.  When the item appears in configfs, the
+attribute file will appear with the configfs_attribute->ca_name
+filename.  configfs_attribute->ca_mode specifies the file permissions.
+
+If an attribute is readable and the config_item provides a
+ct_item_ops->show_attribute() method, that method will be called
+whenever userspace asks for a read(2) on the attribute.  The converse
+will happen for write(2).
+
+[struct config_group]
+
+A config_item cannot live in a vaccum.  The only way one can be created
+is via mkdir(2) on a config_group.  This will trigger creation of a
+child item.
+
+	struct config_group {
+		struct config_item		cg_item;
+		struct list_head		cg_children;
+		struct configfs_subsystem 	*cg_subsys;
+		struct config_group		**default_groups;
+	};
+
+	void config_group_init(struct config_group *group);
+	void config_group_init_type_name(struct config_group *group,
+					 const char *name,
+					 struct config_item_type *type);
+
+
+The config_group structure contains a config_item.  Properly configuring
+that item means that a group can behave as an item in its own right.
+However, it can do more: it can create child items or groups.  This is
+accomplished via the group operations specified on the group's
+config_item_type.
+
+	struct configfs_group_operations {
+		struct config_item *(*make_item)(struct config_group *group,
+						 const char *name);
+		struct config_group *(*make_group)(struct config_group *group,
+						   const char *name);
+		int (*commit_item)(struct config_item *item);
+		void (*drop_item)(struct config_group *group,
+				  struct config_item *item);
+	};
+
+A group creates child items by providing the
+ct_group_ops->make_item() method.  If provided, this method is called from mkdir(2) in the group's directory.  The subsystem allocates a new
+config_item (or more likely, its container structure), initializes it,
+and returns it to configfs.  Configfs will then populate the filesystem
+tree to reflect the new item.
+
+If the subsystem wants the child to be a group itself, the subsystem
+provides ct_group_ops->make_group().  Everything else behaves the same,
+using the group _init() functions on the group.
+
+Finally, when userspace calls rmdir(2) on the item or group,
+ct_group_ops->drop_item() is called.  As a config_group is also a
+config_item, it is not necessary for a seperate drop_group() method.
+The subsystem must config_item_put() the reference that was initialized
+upon item allocation.  If a subsystem has no work to do, it may omit
+the ct_group_ops->drop_item() method, and configfs will call
+config_item_put() on the item on behalf of the subsystem.
+
+IMPORTANT: drop_item() is void, and as such cannot fail.  When rmdir(2)
+is called, configfs WILL remove the item from the filesystem tree
+(assuming that it has no children to keep it busy).  The subsystem is
+responsible for responding to this.  If the subsystem has references to
+the item in other threads, the memory is safe.  It may take some time
+for the item to actually disappear from the subsystem's usage.  But it
+is gone from configfs.
+
+A config_group cannot be removed while it still has child items.  This
+is implemented in the configfs rmdir(2) code.  ->drop_item() will not be
+called, as the item has not been dropped.  rmdir(2) will fail, as the
+directory is not empty.
+
+[struct configfs_subsystem]
+
+A subsystem must register itself, ususally at module_init time.  This
+tells configfs to make the subsystem appear in the file tree.
+
+	struct configfs_subsystem {
+		struct config_group	su_group;
+		struct semaphore	su_sem;
+	};
+
+	int configfs_register_subsystem(struct configfs_subsystem *subsys);
+	void configfs_unregister_subsystem(struct configfs_subsystem *subsys);
+
+	A subsystem consists of a toplevel config_group and a semaphore.
+The group is where child config_items are created.  For a subsystem,
+this group is usually defined statically.  Before calling
+configfs_register_subsystem(), the subsystem must have initialized the
+group via the usual group _init() functions, and it must also have
+initialized the semaphore.
+	When the register call returns, the subsystem is live, and it
+will be visible via configfs.  At that point, mkdir(2) can be called and
+the subsystem must be ready for it.
+
+[An Example]
+
+The best example of these basic concepts is the simple_children
+subsystem/group and the simple_child item in configfs_example.c  It
+shows a trivial object displaying and storing an attribute, and a simple
+group creating and destroying these children.
+
+[Hierarchy Navigation and the Subsystem Semaphore]
+
+There is an extra bonus that configfs provides.  The config_groups and
+config_items are arranged in a hierarchy due to the fact that they
+appear in a filesystem.  A subsystem is NEVER to touch the filesystem
+parts, but the subsystem might be interested in this hierarchy.  For
+this reason, the hierarchy is mirrored via the config_group->cg_children
+and config_item->ci_parent structure members.
+
+A subsystem can navigate the cg_children list and the ci_parent pointer
+to see the tree created by the subsystem.  This can race with configfs'
+management of the hierarchy, so configfs uses the subsystem semaphore to
+protect modifications.  Whenever a subsystem wants to navigate the
+hierarchy, it must do so under the protection of the subsystem
+semaphore.
+
+A subsystem will be prevented from acquiring the semaphore while a newly
+allocated item has not been linked into this hierarchy.   Similarly, it
+will not be able to acquire the semaphore while a dropping item has not
+yet been unlinked.  This means that an item's ci_parent pointer will
+never be NULL while the item is in configfs, and that an item will only
+be in its parent's cg_children list for the same duration.  This allows
+a subsystem to trust ci_parent and cg_children while they hold the
+semaphore.
+
+[Item Aggregation Via symlink(2)]
+
+configfs provides a simple group via the group->item parent/child
+relationship.  Often, however, a larger environment requires aggregation
+outside of the parent/child connection.  This is implemented via
+symlink(2).
+
+A config_item may provide the ct_item_ops->allow_link() and
+ct_item_ops->drop_link() methods.  If the ->allow_link() method exists,
+symlink(2) may be called with the config_item as the source of the link.
+These links are only allowed between configfs config_items.  Any
+symlink(2) attempt outside the configfs filesystem will be denied.
+
+When symlink(2) is called, the source config_item's ->allow_link()
+method is called with itself and a target item.  If the source item
+allows linking to target item, it returns 0.  A source item may wish to
+reject a link if it only wants links to a certain type of object (say,
+in its own subsystem).
+
+When unlink(2) is called on the symbolic link, the source item is
+notified via the ->drop_link() method.  Like the ->drop_item() method,
+this is a void function and cannot return failure.  The subsystem is
+responsible for responding to the change.
+
+A config_item cannot be removed while it links to any other item, nor
+can it be removed while an item links to it.  Dangling symlinks are not
+allowed in configfs.
+
+[Automatically Created Subgroups]
+
+A new config_group may want to have two types of child config_items.
+While this could be codified by magic names in ->make_item(), it is much
+more explicit to have a method whereby userspace sees this divergence.
+
+Rather than have a group where some items behave differently than
+others, configfs provides a method whereby one or many subgroups are
+automatically created inside the parent at its creation.  Thus,
+mkdir("parent) results in "parent", "parent/subgroup1", up through
+"parent/subgroupN".  Items of type 1 can now be created in
+"parent/subgroup1", and items of type N can be created in
+"parent/subgroupN".
+
+These automatic subgroups, or default groups, do not preclude other
+children of the parent group.  If ct_group_ops->make_group() exists,
+other child groups can be created on the parent group directly.
+
+A configfs subsystem specifies default groups by filling in the
+NULL-terminated array default_groups on the config_group structure.
+Each group in that array is populated in the configfs tree at the same
+time as the parent group.  Similarly, they are removed at the same time
+as the parent.  No extra notification is provided.  When a ->drop_item()
+method call notifies the subsystem the parent group is going away, it
+also means every default group child associated with that parent group.
+
+As a consequence of this, default_groups cannot be removed directly via
+rmdir(2).  They also are not considered when rmdir(2) on the parent
+group is checking for children.
+
+[Committable Items]
+
+NOTE: Committable items are currently unimplemented.
+
+Some config_items cannot have a valid initial state.  That is, no
+default values can be specified for the item's attributes such that the
+item can do its work.  Userspace must configure one or more attributes,
+after which the subsystem can start whatever entity this item
+represents.
+
+Consider the FakeNBD device from above.  Without a target address *and*
+a target device, the subsystem has no idea what block device to import.
+The simple example assumes that the subsystem merely waits until all the
+appropriate attributes are configured, and then connects.  This will,
+indeed, work, but now every attribute store must check if the attributes
+are initialized.  Every attribute store must fire off the connection if
+that condition is met.
+
+Far better would be an explicit action notifying the subsystem that the
+config_item is ready to go.  More importantly, an explicit action allows
+the subsystem to provide feedback as to whether the attibutes are
+initialized in a way that makes sense.  configfs provides this as
+committable items.
+
+configfs still uses only normal filesystem operations.  An item is
+committed via rename(2).  The item is moved from a directory where it
+can be modified to a directory where it cannot.
+
+Any group that provides the ct_group_ops->commit_item() method has
+committable items.  When this group appears in configfs, mkdir(2) will
+not work directly in the group.  Instead, the group will have two
+subdirectories: "live" and "pending".  The "live" directory does not
+support mkdir(2) or rmdir(2) either.  It only allows rename(2).  The
+"pending" directory does allow mkdir(2) and rmdir(2).  An item is
+created in the "pending" directory.  Its attributes can be modified at
+will.  Userspace commits the item by renaming it into the "live"
+directory.  At this point, the subsystem recieves the ->commit_item()
+callback.  If all required attributes are filled to satisfaction, the
+method returns zero and the item is moved to the "live" directory.
+
+As rmdir(2) does not work in the "live" directory, an item must be
+shutdown, or "uncommitted".  Again, this is done via rename(2), this
+time from the "live" directory back to the "pending" one.  The subsystem
+is notified by the ct_group_ops->uncommit_object() method.
+
+

+ 474 - 0
Documentation/filesystems/configfs/configfs_example.c

@@ -0,0 +1,474 @@
+/*
+ * vim: noexpandtab ts=8 sts=0 sw=8:
+ *
+ * configfs_example.c - This file is a demonstration module containing
+ *      a number of configfs subsystems.
+ *
+ * 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 021110-1307, USA.
+ *
+ * Based on sysfs:
+ * 	sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
+ *
+ * configfs Copyright (C) 2005 Oracle.  All rights reserved.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include <linux/configfs.h>
+
+
+
+/*
+ * 01-childless
+ *
+ * This first example is a childless subsystem.  It cannot create
+ * any config_items.  It just has attributes.
+ *
+ * Note that we are enclosing the configfs_subsystem inside a container.
+ * This is not necessary if a subsystem has no attributes directly
+ * on the subsystem.  See the next example, 02-simple-children, for
+ * such a subsystem.
+ */
+
+struct childless {
+	struct configfs_subsystem subsys;
+	int showme;
+	int storeme;
+};
+
+struct childless_attribute {
+	struct configfs_attribute attr;
+	ssize_t (*show)(struct childless *, char *);
+	ssize_t (*store)(struct childless *, const char *, size_t);
+};
+
+static inline struct childless *to_childless(struct config_item *item)
+{
+	return item ? container_of(to_configfs_subsystem(to_config_group(item)), struct childless, subsys) : NULL;
+}
+
+static ssize_t childless_showme_read(struct childless *childless,
+				     char *page)
+{
+	ssize_t pos;
+
+	pos = sprintf(page, "%d\n", childless->showme);
+	childless->showme++;
+
+	return pos;
+}
+
+static ssize_t childless_storeme_read(struct childless *childless,
+				      char *page)
+{
+	return sprintf(page, "%d\n", childless->storeme);
+}
+
+static ssize_t childless_storeme_write(struct childless *childless,
+				       const char *page,
+				       size_t count)
+{
+	unsigned long tmp;
+	char *p = (char *) page;
+
+	tmp = simple_strtoul(p, &p, 10);
+	if (!p || (*p && (*p != '\n')))
+		return -EINVAL;
+
+	if (tmp > INT_MAX)
+		return -ERANGE;
+
+	childless->storeme = tmp;
+
+	return count;
+}
+
+static ssize_t childless_description_read(struct childless *childless,
+					  char *page)
+{
+	return sprintf(page,
+"[01-childless]\n"
+"\n"
+"The childless subsystem is the simplest possible subsystem in\n"
+"configfs.  It does not support the creation of child config_items.\n"
+"It only has a few attributes.  In fact, it isn't much different\n"
+"than a directory in /proc.\n");
+}
+
+static struct childless_attribute childless_attr_showme = {
+	.attr	= { .ca_owner = THIS_MODULE, .ca_name = "showme", .ca_mode = S_IRUGO },
+	.show	= childless_showme_read,
+};
+static struct childless_attribute childless_attr_storeme = {
+	.attr	= { .ca_owner = THIS_MODULE, .ca_name = "storeme", .ca_mode = S_IRUGO | S_IWUSR },
+	.show	= childless_storeme_read,
+	.store	= childless_storeme_write,
+};
+static struct childless_attribute childless_attr_description = {
+	.attr = { .ca_owner = THIS_MODULE, .ca_name = "description", .ca_mode = S_IRUGO },
+	.show = childless_description_read,
+};
+
+static struct configfs_attribute *childless_attrs[] = {
+	&childless_attr_showme.attr,
+	&childless_attr_storeme.attr,
+	&childless_attr_description.attr,
+	NULL,
+};
+
+static ssize_t childless_attr_show(struct config_item *item,
+				   struct configfs_attribute *attr,
+				   char *page)
+{
+	struct childless *childless = to_childless(item);
+	struct childless_attribute *childless_attr =
+		container_of(attr, struct childless_attribute, attr);
+	ssize_t ret = 0;
+
+	if (childless_attr->show)
+		ret = childless_attr->show(childless, page);
+	return ret;
+}
+
+static ssize_t childless_attr_store(struct config_item *item,
+				    struct configfs_attribute *attr,
+				    const char *page, size_t count)
+{
+	struct childless *childless = to_childless(item);
+	struct childless_attribute *childless_attr =
+		container_of(attr, struct childless_attribute, attr);
+	ssize_t ret = -EINVAL;
+
+	if (childless_attr->store)
+		ret = childless_attr->store(childless, page, count);
+	return ret;
+}
+
+static struct configfs_item_operations childless_item_ops = {
+	.show_attribute		= childless_attr_show,
+	.store_attribute	= childless_attr_store,
+};
+
+static struct config_item_type childless_type = {
+	.ct_item_ops	= &childless_item_ops,
+	.ct_attrs	= childless_attrs,
+	.ct_owner	= THIS_MODULE,
+};
+
+static struct childless childless_subsys = {
+	.subsys = {
+		.su_group = {
+			.cg_item = {
+				.ci_namebuf = "01-childless",
+				.ci_type = &childless_type,
+			},
+		},
+	},
+};
+
+
+/* ----------------------------------------------------------------- */
+
+/*
+ * 02-simple-children
+ *
+ * This example merely has a simple one-attribute child.  Note that
+ * there is no extra attribute structure, as the child's attribute is
+ * known from the get-go.  Also, there is no container for the
+ * subsystem, as it has no attributes of its own.
+ */
+
+struct simple_child {
+	struct config_item item;
+	int storeme;
+};
+
+static inline struct simple_child *to_simple_child(struct config_item *item)
+{
+	return item ? container_of(item, struct simple_child, item) : NULL;
+}
+
+static struct configfs_attribute simple_child_attr_storeme = {
+	.ca_owner = THIS_MODULE,
+	.ca_name = "storeme",
+	.ca_mode = S_IRUGO | S_IWUSR,
+};
+
+static struct configfs_attribute *simple_child_attrs[] = {
+	&simple_child_attr_storeme,
+	NULL,
+};
+
+static ssize_t simple_child_attr_show(struct config_item *item,
+				      struct configfs_attribute *attr,
+				      char *page)
+{
+	ssize_t count;
+	struct simple_child *simple_child = to_simple_child(item);
+
+	count = sprintf(page, "%d\n", simple_child->storeme);
+
+	return count;
+}
+
+static ssize_t simple_child_attr_store(struct config_item *item,
+				       struct configfs_attribute *attr,
+				       const char *page, size_t count)
+{
+	struct simple_child *simple_child = to_simple_child(item);
+	unsigned long tmp;
+	char *p = (char *) page;
+
+	tmp = simple_strtoul(p, &p, 10);
+	if (!p || (*p && (*p != '\n')))
+		return -EINVAL;
+
+	if (tmp > INT_MAX)
+		return -ERANGE;
+
+	simple_child->storeme = tmp;
+
+	return count;
+}
+
+static void simple_child_release(struct config_item *item)
+{
+	kfree(to_simple_child(item));
+}
+
+static struct configfs_item_operations simple_child_item_ops = {
+	.release		= simple_child_release,
+	.show_attribute		= simple_child_attr_show,
+	.store_attribute	= simple_child_attr_store,
+};
+
+static struct config_item_type simple_child_type = {
+	.ct_item_ops	= &simple_child_item_ops,
+	.ct_attrs	= simple_child_attrs,
+	.ct_owner	= THIS_MODULE,
+};
+
+
+static struct config_item *simple_children_make_item(struct config_group *group, const char *name)
+{
+	struct simple_child *simple_child;
+
+	simple_child = kmalloc(sizeof(struct simple_child), GFP_KERNEL);
+	if (!simple_child)
+		return NULL;
+
+	memset(simple_child, 0, sizeof(struct simple_child));
+
+	config_item_init_type_name(&simple_child->item, name,
+				   &simple_child_type);
+
+	simple_child->storeme = 0;
+
+	return &simple_child->item;
+}
+
+static struct configfs_attribute simple_children_attr_description = {
+	.ca_owner = THIS_MODULE,
+	.ca_name = "description",
+	.ca_mode = S_IRUGO,
+};
+
+static struct configfs_attribute *simple_children_attrs[] = {
+	&simple_children_attr_description,
+	NULL,
+};
+
+static ssize_t simple_children_attr_show(struct config_item *item,
+			   		 struct configfs_attribute *attr,
+			   		 char *page)
+{
+	return sprintf(page,
+"[02-simple-children]\n"
+"\n"
+"This subsystem allows the creation of child config_items.  These\n"
+"items have only one attribute that is readable and writeable.\n");
+}
+
+static struct configfs_item_operations simple_children_item_ops = {
+	.show_attribute	= simple_children_attr_show,
+};
+
+/*
+ * Note that, since no extra work is required on ->drop_item(),
+ * no ->drop_item() is provided.
+ */
+static struct configfs_group_operations simple_children_group_ops = {
+	.make_item	= simple_children_make_item,
+};
+
+static struct config_item_type simple_children_type = {
+	.ct_item_ops	= &simple_children_item_ops,
+	.ct_group_ops	= &simple_children_group_ops,
+	.ct_attrs	= simple_children_attrs,
+};
+
+static struct configfs_subsystem simple_children_subsys = {
+	.su_group = {
+		.cg_item = {
+			.ci_namebuf = "02-simple-children",
+			.ci_type = &simple_children_type,
+		},
+	},
+};
+
+
+/* ----------------------------------------------------------------- */
+
+/*
+ * 03-group-children
+ *
+ * This example reuses the simple_children group from above.  However,
+ * the simple_children group is not the subsystem itself, it is a
+ * child of the subsystem.  Creation of a group in the subsystem creates
+ * a new simple_children group.  That group can then have simple_child
+ * children of its own.
+ */
+
+struct simple_children {
+	struct config_group group;
+};
+
+static struct config_group *group_children_make_group(struct config_group *group, const char *name)
+{
+	struct simple_children *simple_children;
+
+	simple_children = kmalloc(sizeof(struct simple_children),
+				  GFP_KERNEL);
+	if (!simple_children)
+		return NULL;
+
+	memset(simple_children, 0, sizeof(struct simple_children));
+
+	config_group_init_type_name(&simple_children->group, name,
+				    &simple_children_type);
+
+	return &simple_children->group;
+}
+
+static struct configfs_attribute group_children_attr_description = {
+	.ca_owner = THIS_MODULE,
+	.ca_name = "description",
+	.ca_mode = S_IRUGO,
+};
+
+static struct configfs_attribute *group_children_attrs[] = {
+	&group_children_attr_description,
+	NULL,
+};
+
+static ssize_t group_children_attr_show(struct config_item *item,
+			   		struct configfs_attribute *attr,
+			   		char *page)
+{
+	return sprintf(page,
+"[03-group-children]\n"
+"\n"
+"This subsystem allows the creation of child config_groups.  These\n"
+"groups are like the subsystem simple-children.\n");
+}
+
+static struct configfs_item_operations group_children_item_ops = {
+	.show_attribute	= group_children_attr_show,
+};
+
+/*
+ * Note that, since no extra work is required on ->drop_item(),
+ * no ->drop_item() is provided.
+ */
+static struct configfs_group_operations group_children_group_ops = {
+	.make_group	= group_children_make_group,
+};
+
+static struct config_item_type group_children_type = {
+	.ct_item_ops	= &group_children_item_ops,
+	.ct_group_ops	= &group_children_group_ops,
+	.ct_attrs	= group_children_attrs,
+};
+
+static struct configfs_subsystem group_children_subsys = {
+	.su_group = {
+		.cg_item = {
+			.ci_namebuf = "03-group-children",
+			.ci_type = &group_children_type,
+		},
+	},
+};
+
+/* ----------------------------------------------------------------- */
+
+/*
+ * We're now done with our subsystem definitions.
+ * For convenience in this module, here's a list of them all.  It
+ * allows the init function to easily register them.  Most modules
+ * will only have one subsystem, and will only call register_subsystem
+ * on it directly.
+ */
+static struct configfs_subsystem *example_subsys[] = {
+	&childless_subsys.subsys,
+	&simple_children_subsys,
+	&group_children_subsys,
+	NULL,
+};
+
+static int __init configfs_example_init(void)
+{
+	int ret;
+	int i;
+	struct configfs_subsystem *subsys;
+
+	for (i = 0; example_subsys[i]; i++) {
+		subsys = example_subsys[i];
+
+		config_group_init(&subsys->su_group);
+		init_MUTEX(&subsys->su_sem);
+		ret = configfs_register_subsystem(subsys);
+		if (ret) {
+			printk(KERN_ERR "Error %d while registering subsystem %s\n",
+			       ret,
+			       subsys->su_group.cg_item.ci_namebuf);
+			goto out_unregister;
+		}
+	}
+
+	return 0;
+
+out_unregister:
+	for (; i >= 0; i--) {
+		configfs_unregister_subsystem(example_subsys[i]);
+	}
+
+	return ret;
+}
+
+static void __exit configfs_example_exit(void)
+{
+	int i;
+
+	for (i = 0; example_subsys[i]; i++) {
+		configfs_unregister_subsystem(example_subsys[i]);
+	}
+}
+
+module_init(configfs_example_init);
+module_exit(configfs_example_exit);
+MODULE_LICENSE("GPL");

+ 130 - 0
Documentation/filesystems/dlmfs.txt

@@ -0,0 +1,130 @@
+dlmfs
+==================
+A minimal DLM userspace interface implemented via a virtual file
+system.
+
+dlmfs is built with OCFS2 as it requires most of its infrastructure.
+
+Project web page:    http://oss.oracle.com/projects/ocfs2
+Tools web page:      http://oss.oracle.com/projects/ocfs2-tools
+OCFS2 mailing lists: http://oss.oracle.com/projects/ocfs2/mailman/
+
+All code copyright 2005 Oracle except when otherwise noted.
+
+CREDITS
+=======
+
+Some code taken from ramfs which is Copyright (C) 2000 Linus Torvalds
+and Transmeta Corp.
+
+Mark Fasheh <mark.fasheh@oracle.com>
+
+Caveats
+=======
+- Right now it only works with the OCFS2 DLM, though support for other
+  DLM implementations should not be a major issue.
+
+Mount options
+=============
+None
+
+Usage
+=====
+
+If you're just interested in OCFS2, then please see ocfs2.txt. The
+rest of this document will be geared towards those who want to use
+dlmfs for easy to setup and easy to use clustered locking in
+userspace.
+
+Setup
+=====
+
+dlmfs requires that the OCFS2 cluster infrastructure be in
+place. Please download ocfs2-tools from the above url and configure a
+cluster.
+
+You'll want to start heartbeating on a volume which all the nodes in
+your lockspace can access. The easiest way to do this is via
+ocfs2_hb_ctl (distributed with ocfs2-tools). Right now it requires
+that an OCFS2 file system be in place so that it can automatically
+find it's heartbeat area, though it will eventually support heartbeat
+against raw disks.
+
+Please see the ocfs2_hb_ctl and mkfs.ocfs2 manual pages distributed
+with ocfs2-tools.
+
+Once you're heartbeating, DLM lock 'domains' can be easily created /
+destroyed and locks within them accessed.
+
+Locking
+=======
+
+Users may access dlmfs via standard file system calls, or they can use
+'libo2dlm' (distributed with ocfs2-tools) which abstracts the file
+system calls and presents a more traditional locking api.
+
+dlmfs handles lock caching automatically for the user, so a lock
+request for an already acquired lock will not generate another DLM
+call. Userspace programs are assumed to handle their own local
+locking.
+
+Two levels of locks are supported - Shared Read, and Exlcusive.
+Also supported is a Trylock operation.
+
+For information on the libo2dlm interface, please see o2dlm.h,
+distributed with ocfs2-tools.
+
+Lock value blocks can be read and written to a resource via read(2)
+and write(2) against the fd obtained via your open(2) call. The
+maximum currently supported LVB length is 64 bytes (though that is an
+OCFS2 DLM limitation). Through this mechanism, users of dlmfs can share
+small amounts of data amongst their nodes.
+
+mkdir(2) signals dlmfs to join a domain (which will have the same name
+as the resulting directory)
+
+rmdir(2) signals dlmfs to leave the domain
+
+Locks for a given domain are represented by regular inodes inside the
+domain directory.  Locking against them is done via the open(2) system
+call.
+
+The open(2) call will not return until your lock has been granted or
+an error has occurred, unless it has been instructed to do a trylock
+operation. If the lock succeeds, you'll get an fd.
+
+open(2) with O_CREAT to ensure the resource inode is created - dlmfs does
+not automatically create inodes for existing lock resources.
+
+Open Flag     Lock Request Type
+---------     -----------------
+O_RDONLY      Shared Read
+O_RDWR        Exclusive
+
+Open Flag     Resulting Locking Behavior
+---------     --------------------------
+O_NONBLOCK    Trylock operation
+
+You must provide exactly one of O_RDONLY or O_RDWR.
+
+If O_NONBLOCK is also provided and the trylock operation was valid but
+could not lock the resource then open(2) will return ETXTBUSY.
+
+close(2) drops the lock associated with your fd.
+
+Modes passed to mkdir(2) or open(2) are adhered to locally. Chown is
+supported locally as well. This means you can use them to restrict
+access to the resources via dlmfs on your local node only.
+
+The resource LVB may be read from the fd in either Shared Read or
+Exclusive modes via the read(2) system call. It can be written via
+write(2) only when open in Exclusive mode.
+
+Once written, an LVB will be visible to other nodes who obtain Read
+Only or higher level locks on the resource.
+
+See Also
+========
+http://opendlm.sourceforge.net/cvsmirror/opendlm/docs/dlmbook_final.pdf
+
+For more information on the VMS distributed locking API.

+ 55 - 0
Documentation/filesystems/ocfs2.txt

@@ -0,0 +1,55 @@
+OCFS2 filesystem
+==================
+OCFS2 is a general purpose extent based shared disk cluster file
+system with many similarities to ext3. It supports 64 bit inode
+numbers, and has automatically extending metadata groups which may
+also make it attractive for non-clustered use.
+
+You'll want to install the ocfs2-tools package in order to at least
+get "mount.ocfs2" and "ocfs2_hb_ctl".
+
+Project web page:    http://oss.oracle.com/projects/ocfs2
+Tools web page:      http://oss.oracle.com/projects/ocfs2-tools
+OCFS2 mailing lists: http://oss.oracle.com/projects/ocfs2/mailman/
+
+All code copyright 2005 Oracle except when otherwise noted.
+
+CREDITS:
+Lots of code taken from ext3 and other projects.
+
+Authors in alphabetical order:
+Joel Becker   <joel.becker@oracle.com>
+Zach Brown    <zach.brown@oracle.com>
+Mark Fasheh   <mark.fasheh@oracle.com>
+Kurt Hackel   <kurt.hackel@oracle.com>
+Sunil Mushran <sunil.mushran@oracle.com>
+Manish Singh  <manish.singh@oracle.com>
+
+Caveats
+=======
+Features which OCFS2 does not support yet:
+	- sparse files
+	- extended attributes
+	- shared writeable mmap
+	- loopback is supported, but data written will not
+	  be cluster coherent.
+	- quotas
+	- cluster aware flock
+	- Directory change notification (F_NOTIFY)
+	- Distributed Caching (F_SETLEASE/F_GETLEASE/break_lease)
+	- POSIX ACLs
+	- readpages / writepages (not user visible)
+
+Mount options
+=============
+
+OCFS2 supports the following mount options:
+(*) == default
+
+barrier=1		This enables/disables barriers. barrier=0 disables it,
+			barrier=1 enables it.
+errors=remount-ro(*)	Remount the filesystem read-only on an error.
+errors=panic		Panic and halt the machine if an error occurs.
+intr		(*)	Allow signals to interrupt cluster operations.
+nointr			Do not allow signals to interrupt cluster
+			operations.

+ 2 - 3
Documentation/filesystems/vfs.txt

@@ -162,9 +162,8 @@ get_sb() method fills in is the "s_op" field. This is a pointer to
 a "struct super_operations" which describes the next level of the
 a "struct super_operations" which describes the next level of the
 filesystem implementation.
 filesystem implementation.
 
 
-Usually, a filesystem uses generic one of the generic get_sb()
-implementations and provides a fill_super() method instead. The
-generic methods are:
+Usually, a filesystem uses one of the generic get_sb() implementations
+and provides a fill_super() method instead. The generic methods are:
 
 
   get_sb_bdev: mount a filesystem residing on a block device
   get_sb_bdev: mount a filesystem residing on a block device
 
 

+ 11 - 8
Documentation/hwmon/w83627hf

@@ -54,13 +54,16 @@ If you really want i2c accesses for these Super I/O chips,
 use the w83781d driver. However this is not the preferred method
 use the w83781d driver. However this is not the preferred method
 now that this ISA driver has been developed.
 now that this ISA driver has been developed.
 
 
-Technically, the w83627thf does not support a VID reading. However, it's
-possible or even likely that your mainboard maker has routed these signals
-to a specific set of general purpose IO pins (the Asus P4C800-E is one such
-board). The w83627thf driver now interprets these as VID. If the VID on
-your board doesn't work, first see doc/vid in the lm_sensors package. If
-that still doesn't help, email us at lm-sensors@lm-sensors.org.
+The w83627_HF_ uses pins 110-106 as VID0-VID4. The w83627_THF_ uses the
+same pins as GPIO[0:4]. Technically, the w83627_THF_ does not support a
+VID reading. However the two chips have the identical 128 pin package. So,
+it is possible or even likely for a w83627thf to have the VID signals routed
+to these pins despite their not being labeled for that purpose. Therefore,
+the w83627thf driver interprets these as VID. If the VID on your board
+doesn't work, first see doc/vid in the lm_sensors package[1]. If that still
+doesn't help, you may just ignore the bogus VID reading with no harm done.
 
 
-For further information on this driver see the w83781d driver
-documentation.
+For further information on this driver see the w83781d driver documentation.
+
+[1] http://www2.lm-sensors.nu/~lm78/cvs/browse.cgi/lm_sensors2/doc/vid
 
 

+ 2 - 1
Documentation/i2c/busses/i2c-nforce2

@@ -5,7 +5,8 @@ Supported adapters:
   * nForce2 Ultra 400 MCP      10de:0084 
   * nForce2 Ultra 400 MCP      10de:0084 
   * nForce3 Pro150 MCP         10de:00D4 
   * nForce3 Pro150 MCP         10de:00D4 
   * nForce3 250Gb MCP          10de:00E4 
   * nForce3 250Gb MCP          10de:00E4 
-  * nForce4 MCP	       	       10de:0052
+  * nForce4 MCP                10de:0052
+  * nForce4 MCP-04             10de:0034
 
 
 Datasheet: not publically available, but seems to be similar to the
 Datasheet: not publically available, but seems to be similar to the
            AMD-8111 SMBus 2.0 adapter.
            AMD-8111 SMBus 2.0 adapter.

+ 1 - 0
Documentation/i2c/busses/i2c-parport

@@ -17,6 +17,7 @@ It currently supports the following devices:
  * Velleman K8000 adapter
  * Velleman K8000 adapter
  * ELV adapter
  * ELV adapter
  * Analog Devices evaluation boards (ADM1025, ADM1030, ADM1031, ADM1032)
  * Analog Devices evaluation boards (ADM1025, ADM1030, ADM1031, ADM1032)
+ * Barco LPT->DVI (K5800236) adapter
 
 
 These devices use different pinout configurations, so you have to tell
 These devices use different pinout configurations, so you have to tell
 the driver what you have, using the type module parameter. There is no
 the driver what you have, using the type module parameter. There is no

+ 53 - 37
Documentation/i2c/porting-clients

@@ -1,10 +1,13 @@
-Revision 5, 2005-07-29
+Revision 6, 2005-11-20
 Jean Delvare <khali@linux-fr.org>
 Jean Delvare <khali@linux-fr.org>
 Greg KH <greg@kroah.com>
 Greg KH <greg@kroah.com>
 
 
 This is a guide on how to convert I2C chip drivers from Linux 2.4 to
 This is a guide on how to convert I2C chip drivers from Linux 2.4 to
 Linux 2.6. I have been using existing drivers (lm75, lm78) as examples.
 Linux 2.6. I have been using existing drivers (lm75, lm78) as examples.
 Then I converted a driver myself (lm83) and updated this document.
 Then I converted a driver myself (lm83) and updated this document.
+Note that this guide is strongly oriented towards hardware monitoring
+drivers. Many points are still valid for other type of drivers, but
+others may be irrelevant.
 
 
 There are two sets of points below. The first set concerns technical
 There are two sets of points below. The first set concerns technical
 changes. The second set concerns coding policy. Both are mandatory.
 changes. The second set concerns coding policy. Both are mandatory.
@@ -22,16 +25,20 @@ Technical changes:
   #include <linux/module.h>
   #include <linux/module.h>
   #include <linux/init.h>
   #include <linux/init.h>
   #include <linux/slab.h>
   #include <linux/slab.h>
+  #include <linux/jiffies.h>
   #include <linux/i2c.h>
   #include <linux/i2c.h>
+  #include <linux/i2c-isa.h>	/* for ISA drivers */
   #include <linux/hwmon.h>	/* for hardware monitoring drivers */
   #include <linux/hwmon.h>	/* for hardware monitoring drivers */
   #include <linux/hwmon-sysfs.h>
   #include <linux/hwmon-sysfs.h>
   #include <linux/hwmon-vid.h>	/* if you need VRM support */
   #include <linux/hwmon-vid.h>	/* if you need VRM support */
+  #include <linux/err.h>	/* for class registration */
   #include <asm/io.h>		/* if you have I/O operations */
   #include <asm/io.h>		/* if you have I/O operations */
   Please respect this inclusion order. Some extra headers may be
   Please respect this inclusion order. Some extra headers may be
   required for a given driver (e.g. "lm75.h").
   required for a given driver (e.g. "lm75.h").
 
 
 * [Addresses] SENSORS_I2C_END becomes I2C_CLIENT_END, ISA addresses
 * [Addresses] SENSORS_I2C_END becomes I2C_CLIENT_END, ISA addresses
-  are no more handled by the i2c core.
+  are no more handled by the i2c core. Address ranges are no more
+  supported either, define each individual address separately.
   SENSORS_INSMOD_<n> becomes I2C_CLIENT_INSMOD_<n>.
   SENSORS_INSMOD_<n> becomes I2C_CLIENT_INSMOD_<n>.
 
 
 * [Client data] Get rid of sysctl_id. Try using standard names for
 * [Client data] Get rid of sysctl_id. Try using standard names for
@@ -48,23 +55,23 @@ Technical changes:
       int kind);
       int kind);
   static void lm75_init_client(struct i2c_client *client);
   static void lm75_init_client(struct i2c_client *client);
   static int lm75_detach_client(struct i2c_client *client);
   static int lm75_detach_client(struct i2c_client *client);
-  static void lm75_update_client(struct i2c_client *client);
+  static struct lm75_data lm75_update_device(struct device *dev);
 
 
 * [Sysctl] All sysctl stuff is of course gone (defines, ctl_table
 * [Sysctl] All sysctl stuff is of course gone (defines, ctl_table
   and functions). Instead, you have to define show and set functions for
   and functions). Instead, you have to define show and set functions for
   each sysfs file. Only define set for writable values. Take a look at an
   each sysfs file. Only define set for writable values. Take a look at an
-  existing 2.6 driver for details (lm78 for example). Don't forget
+  existing 2.6 driver for details (it87 for example). Don't forget
   to define the attributes for each file (this is that step that
   to define the attributes for each file (this is that step that
   links callback functions). Use the file names specified in
   links callback functions). Use the file names specified in
-  Documentation/i2c/sysfs-interface for the individual files. Also
+  Documentation/hwmon/sysfs-interface for the individual files. Also
   convert the units these files read and write to the specified ones.
   convert the units these files read and write to the specified ones.
   If you need to add a new type of file, please discuss it on the
   If you need to add a new type of file, please discuss it on the
   sensors mailing list <lm-sensors@lm-sensors.org> by providing a
   sensors mailing list <lm-sensors@lm-sensors.org> by providing a
-  patch to the Documentation/i2c/sysfs-interface file.
+  patch to the Documentation/hwmon/sysfs-interface file.
 
 
 * [Attach] For I2C drivers, the attach function should make sure
 * [Attach] For I2C drivers, the attach function should make sure
-  that the adapter's class has I2C_CLASS_HWMON, using the
-  following construct:
+  that the adapter's class has I2C_CLASS_HWMON (or whatever class is
+  suitable for your driver), using the following construct:
   if (!(adapter->class & I2C_CLASS_HWMON))
   if (!(adapter->class & I2C_CLASS_HWMON))
           return 0;
           return 0;
   ISA-only drivers of course don't need this.
   ISA-only drivers of course don't need this.
@@ -72,63 +79,72 @@ Technical changes:
 
 
 * [Detect] As mentioned earlier, the flags parameter is gone.
 * [Detect] As mentioned earlier, the flags parameter is gone.
   The type_name and client_name strings are replaced by a single
   The type_name and client_name strings are replaced by a single
-  name string, which will be filled with a lowercase, short string
-  (typically the driver name, e.g. "lm75").
+  name string, which will be filled with a lowercase, short string.
   In i2c-only drivers, drop the i2c_is_isa_adapter check, it's
   In i2c-only drivers, drop the i2c_is_isa_adapter check, it's
   useless. Same for isa-only drivers, as the test would always be
   useless. Same for isa-only drivers, as the test would always be
   true. Only hybrid drivers (which are quite rare) still need it.
   true. Only hybrid drivers (which are quite rare) still need it.
-  The errorN labels are reduced to the number needed. If that number
-  is 2 (i2c-only drivers), it is advised that the labels are named
-  exit and exit_free. For i2c+isa drivers, labels should be named
-  ERROR0, ERROR1 and ERROR2. Don't forget to properly set err before
+  The labels used for error paths are reduced to the number needed.
+  It is advised that the labels are given descriptive names such as
+  exit and exit_free. Don't forget to properly set err before
   jumping to error labels. By the way, labels should be left-aligned.
   jumping to error labels. By the way, labels should be left-aligned.
   Use kzalloc instead of kmalloc.
   Use kzalloc instead of kmalloc.
   Use i2c_set_clientdata to set the client data (as opposed to
   Use i2c_set_clientdata to set the client data (as opposed to
   a direct access to client->data).
   a direct access to client->data).
-  Use strlcpy instead of strcpy to copy the client name.
+  Use strlcpy instead of strcpy or snprintf to copy the client name.
   Replace the sysctl directory registration by calls to
   Replace the sysctl directory registration by calls to
   device_create_file. Move the driver initialization before any
   device_create_file. Move the driver initialization before any
   sysfs file creation.
   sysfs file creation.
+  Register the client with the hwmon class (using hwmon_device_register)
+  if applicable.
   Drop client->id.
   Drop client->id.
   Drop any 24RF08 corruption prevention you find, as this is now done
   Drop any 24RF08 corruption prevention you find, as this is now done
   at the i2c-core level, and doing it twice voids it.
   at the i2c-core level, and doing it twice voids it.
+  Don't add I2C_CLIENT_ALLOW_USE to client->flags, it's the default now.
 
 
 * [Init] Limits must not be set by the driver (can be done later in
 * [Init] Limits must not be set by the driver (can be done later in
   user-space). Chip should not be reset default (although a module
   user-space). Chip should not be reset default (although a module
-  parameter may be used to force is), and initialization should be
+  parameter may be used to force it), and initialization should be
   limited to the strictly necessary steps.
   limited to the strictly necessary steps.
 
 
-* [Detach] Get rid of data, remove the call to
-  i2c_deregister_entry. Do not log an error message if
-  i2c_detach_client fails, as i2c-core will now do it for you.
-
-* [Update] Don't access client->data directly, use
-  i2c_get_clientdata(client) instead.
-
-* [Interface] Init function should not print anything. Make sure
-  there is a MODULE_LICENSE() line, at the bottom of the file
-  (after MODULE_AUTHOR() and MODULE_DESCRIPTION(), in this order).
+* [Detach] Remove the call to i2c_deregister_entry. Do not log an
+  error message if i2c_detach_client fails, as i2c-core will now do
+  it for you.
+  Unregister from the hwmon class if applicable.
+
+* [Update] The function prototype changed, it is now
+  passed a device structure, which you have to convert to a client
+  using to_i2c_client(dev). The update function should return a
+  pointer to the client data.
+  Don't access client->data directly, use i2c_get_clientdata(client)
+  instead.
+  Use time_after() instead of direct jiffies comparison.
+
+* [Interface] Make sure there is a MODULE_LICENSE() line, at the bottom
+  of the file (after MODULE_AUTHOR() and MODULE_DESCRIPTION(), in this
+  order).
+
+* [Driver] The flags field of the i2c_driver structure is gone.
+  I2C_DF_NOTIFY is now the default behavior.
+  The i2c_driver structure has a driver member, which is itself a
+  structure, those name member should be initialized to a driver name
+  string. i2c_driver itself has no name member anymore.
 
 
 Coding policy:
 Coding policy:
 
 
 * [Copyright] Use (C), not (c), for copyright.
 * [Copyright] Use (C), not (c), for copyright.
 
 
 * [Debug/log] Get rid of #ifdef DEBUG/#endif constructs whenever you
 * [Debug/log] Get rid of #ifdef DEBUG/#endif constructs whenever you
-  can. Calls to printk/pr_debug for debugging purposes are replaced
-  by calls to dev_dbg. Here is an example on how to call it (taken
-  from lm75_detect):
+  can. Calls to printk for debugging purposes are replaced by calls to
+  dev_dbg where possible, else to pr_debug. Here is an example of how
+  to call it (taken from lm75_detect):
   dev_dbg(&client->dev, "Starting lm75 update\n");
   dev_dbg(&client->dev, "Starting lm75 update\n");
   Replace other printk calls with the dev_info, dev_err or dev_warn
   Replace other printk calls with the dev_info, dev_err or dev_warn
   function, as appropriate.
   function, as appropriate.
 
 
-* [Constants] Constants defines (registers, conversions, initial
-  values) should be aligned. This greatly improves readability.
-  Same goes for variables declarations. Alignments are achieved by the
-  means of tabs, not spaces. Remember that tabs are set to 8 in the
-  Linux kernel code.
-
-* [Structure definition] The name field should be standardized. All
-  lowercase and as simple as the driver name itself (e.g. "lm75").
+* [Constants] Constants defines (registers, conversions) should be
+  aligned. This greatly improves readability.
+  Alignments are achieved by the means of tabs, not spaces. Remember
+  that tabs are set to 8 in the Linux kernel code.
 
 
 * [Layout] Avoid extra empty lines between comments and what they
 * [Layout] Avoid extra empty lines between comments and what they
   comment. Respect the coding style (see Documentation/CodingStyle),
   comment. Respect the coding style (see Documentation/CodingStyle),

+ 6 - 14
Documentation/i2c/writing-clients

@@ -25,9 +25,9 @@ routines, a client structure specific information like the actual I2C
 address.
 address.
 
 
 static struct i2c_driver foo_driver = {
 static struct i2c_driver foo_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "Foo version 2.3 driver",
-	.flags		= I2C_DF_NOTIFY,
+	.driver = {
+		.name	= "foo",
+	},
 	.attach_adapter	= &foo_attach_adapter,
 	.attach_adapter	= &foo_attach_adapter,
 	.detach_client	= &foo_detach_client,
 	.detach_client	= &foo_detach_client,
 	.command	= &foo_command /* may be NULL */
 	.command	= &foo_command /* may be NULL */
@@ -36,10 +36,6 @@ static struct i2c_driver foo_driver = {
 The name field must match the driver name, including the case. It must not
 The name field must match the driver name, including the case. It must not
 contain spaces, and may be up to 31 characters long.
 contain spaces, and may be up to 31 characters long.
 
 
-Don't worry about the flags field; just put I2C_DF_NOTIFY into it. This
-means that your driver will be notified when new adapters are found.
-This is almost always what you want.
-
 All other fields are for call-back functions which will be explained 
 All other fields are for call-back functions which will be explained 
 below.
 below.
 
 
@@ -496,17 +492,13 @@ Note that some functions are marked by `__init', and some data structures
 by `__init_data'.  Hose functions and structures can be removed after
 by `__init_data'.  Hose functions and structures can be removed after
 kernel booting (or module loading) is completed.
 kernel booting (or module loading) is completed.
 
 
+
 Command function
 Command function
 ================
 ================
 
 
 A generic ioctl-like function call back is supported. You will seldom
 A generic ioctl-like function call back is supported. You will seldom
-need this. You may even set it to NULL.
-
-  /* No commands defined */
-  int foo_command(struct i2c_client *client, unsigned int cmd, void *arg)
-  {
-    return 0;
-  }
+need this, and its use is deprecated anyway, so newer design should not
+use it. Set it to NULL.
 
 
 
 
 Sending and receiving
 Sending and receiving

+ 53 - 13
Documentation/kbuild/modules.txt

@@ -18,6 +18,7 @@ In this document you will find information about:
 	=== 5. Include files
 	=== 5. Include files
 	   --- 5.1 How to include files from the kernel include dir
 	   --- 5.1 How to include files from the kernel include dir
 	   --- 5.2 External modules using an include/ dir
 	   --- 5.2 External modules using an include/ dir
+	   --- 5.3 External modules using several directories
 	=== 6. Module installation
 	=== 6. Module installation
 	   --- 6.1 INSTALL_MOD_PATH
 	   --- 6.1 INSTALL_MOD_PATH
 	   --- 6.2 INSTALL_MOD_DIR
 	   --- 6.2 INSTALL_MOD_DIR
@@ -38,7 +39,7 @@ included in the kernel tree.
 What is covered within this file is mainly information to authors
 What is covered within this file is mainly information to authors
 of modules. The author of an external modules should supply
 of modules. The author of an external modules should supply
 a makefile that hides most of the complexity so one only has to type
 a makefile that hides most of the complexity so one only has to type
-'make' to buld the module. A complete example will be present in
+'make' to build the module. A complete example will be present in
 chapter ¤. Creating a kbuild file for an external module".
 chapter ¤. Creating a kbuild file for an external module".
 
 
 
 
@@ -69,7 +70,7 @@ when building an external module.
 
 
 --- 2.2 Available targets
 --- 2.2 Available targets
 
 
-	$KDIR refers to path to kernel source top-level directory
+	$KDIR refers to the path to the kernel source top-level directory
 
 
 	make -C $KDIR M=`pwd`
 	make -C $KDIR M=`pwd`
 		Will build the module(s) located in current directory.
 		Will build the module(s) located in current directory.
@@ -87,11 +88,11 @@ when building an external module.
 	make -C $KDIR M=$PWD modules_install
 	make -C $KDIR M=$PWD modules_install
 		Install the external module(s).
 		Install the external module(s).
 		Installation default is in /lib/modules/<kernel-version>/extra,
 		Installation default is in /lib/modules/<kernel-version>/extra,
-		but may be prefixed with INSTALL_MOD_PATH - see separate chater.
+		but may be prefixed with INSTALL_MOD_PATH - see separate chapter.
 
 
 	make -C $KDIR M=$PWD clean
 	make -C $KDIR M=$PWD clean
 		Remove all generated files for the module - the kernel
 		Remove all generated files for the module - the kernel
-		source directory is not moddified.
+		source directory is not modified.
 
 
 	make -C $KDIR M=`pwd` help
 	make -C $KDIR M=`pwd` help
 		help will list the available target when building external
 		help will list the available target when building external
@@ -99,7 +100,7 @@ when building an external module.
 
 
 --- 2.3 Available options:
 --- 2.3 Available options:
 
 
-	$KDIR refer to path to kernel src
+	$KDIR refers to the path to the kernel source top-level directory
 
 
 	make -C $KDIR
 	make -C $KDIR
 		Used to specify where to find the kernel source.
 		Used to specify where to find the kernel source.
@@ -206,11 +207,11 @@ following files:
 
 
 		KERNELDIR := /lib/modules/`uname -r`/build
 		KERNELDIR := /lib/modules/`uname -r`/build
 		all::
 		all::
-			$(MAKE) -C $KERNELDIR M=`pwd` $@
+			$(MAKE) -C $(KERNELDIR) M=`pwd` $@
 
 
 		# Module specific targets
 		# Module specific targets
 		genbin:
 		genbin:
-			echo "X" > 8123_bini.o_shipped
+			echo "X" > 8123_bin.o_shipped
 
 
 		endif
 		endif
 
 
@@ -341,13 +342,52 @@ directory and therefore needs to deal with this in their kbuild file.
 		EXTRA_CFLAGS := -Iinclude
 		EXTRA_CFLAGS := -Iinclude
 		8123-y := 8123_if.o 8123_pci.o 8123_bin.o
 		8123-y := 8123_if.o 8123_pci.o 8123_bin.o
 
 
-	Note that in the assingment there is no space between -I and the path.
-	This is a kbuild limitation and no space must be present.
-
+	Note that in the assignment there is no space between -I and the path.
+	This is a kbuild limitation:  there must be no space present.
+
+--- 5.3 External modules using several directories
+
+	If an external module does not follow the usual kernel style but
+	decide to spread files over several directories then kbuild can
+	support this too.
+
+	Consider the following example:
+	
+	|
+	+- src/complex_main.c
+	|   +- hal/hardwareif.c
+	|   +- hal/include/hardwareif.h
+	+- include/complex.h
+	
+	To build a single module named complex.ko we then need the following
+	kbuild file:
+
+	Kbuild:
+		obj-m := complex.o
+		complex-y := src/complex_main.o
+		complex-y += src/hal/hardwareif.o
+
+		EXTRA_CFLAGS := -I$(src)/include
+		EXTRA_CFLAGS += -I$(src)src/hal/include
+
+
+	kbuild knows how to handle .o files located in another directory -
+	although this is NOT reccommended practice. The syntax is to specify
+	the directory relative to the directory where the Kbuild file is
+	located.
+
+	To find the .h files we have to explicitly tell kbuild where to look
+	for the .h files. When kbuild executes current directory is always
+	the root of the kernel tree (argument to -C) and therefore we have to
+	tell kbuild how to find the .h files using absolute paths.
+	$(src) will specify the absolute path to the directory where the
+	Kbuild file are located when being build as an external module.
+	Therefore -I$(src)/ is used to point out the directory of the Kbuild
+	file and any additional path are just appended.
 
 
 === 6. Module installation
 === 6. Module installation
 
 
-Modules which are included in the kernel is installed in the directory:
+Modules which are included in the kernel are installed in the directory:
 
 
 	/lib/modules/$(KERNELRELEASE)/kernel
 	/lib/modules/$(KERNELRELEASE)/kernel
 
 
@@ -365,7 +405,7 @@ External modules are installed in the directory:
 		=> Install dir: /frodo/lib/modules/$(KERNELRELEASE)/kernel
 		=> Install dir: /frodo/lib/modules/$(KERNELRELEASE)/kernel
 
 
 	INSTALL_MOD_PATH may be set as an ordinary shell variable or as in the
 	INSTALL_MOD_PATH may be set as an ordinary shell variable or as in the
-	example above be specified on the commandline when calling make.
+	example above be specified on the command line when calling make.
 	INSTALL_MOD_PATH has effect both when installing modules included in
 	INSTALL_MOD_PATH has effect both when installing modules included in
 	the kernel as well as when installing external modules.
 	the kernel as well as when installing external modules.
 
 
@@ -384,7 +424,7 @@ External modules are installed in the directory:
 
 
 === 7. Module versioning
 === 7. Module versioning
 
 
-Module versioning are enabled by the CONFIG_MODVERSIONS tag.
+Module versioning is enabled by the CONFIG_MODVERSIONS tag.
 
 
 Module versioning is used as a simple ABI consistency check. The Module
 Module versioning is used as a simple ABI consistency check. The Module
 versioning creates a CRC value of the full prototype for an exported symbol and
 versioning creates a CRC value of the full prototype for an exported symbol and

+ 16 - 0
Documentation/kernel-parameters.txt

@@ -633,6 +633,14 @@ running once the system is up.
 	inport.irq=	[HW] Inport (ATI XL and Microsoft) busmouse driver
 	inport.irq=	[HW] Inport (ATI XL and Microsoft) busmouse driver
 			Format: <irq>
 			Format: <irq>
 
 
+	combined_mode=	[HW] control which driver uses IDE ports in combined
+			mode: legacy IDE driver, libata, or both
+			(in the libata case, libata.atapi_enabled=1 may be
+			useful as well).  Note that using the ide or libata
+			options may affect your device naming (e.g. by
+			changing hdc to sdb).
+			Format: combined (default), ide, or libata
+
 	inttest=	[IA64]
 	inttest=	[IA64]
 
 
 	io7=		[HW] IO7 for Marvel based alpha systems
 	io7=		[HW] IO7 for Marvel based alpha systems
@@ -902,6 +910,14 @@ running once the system is up.
 	nfsroot=	[NFS] nfs root filesystem for disk-less boxes.
 	nfsroot=	[NFS] nfs root filesystem for disk-less boxes.
 			See Documentation/nfsroot.txt.
 			See Documentation/nfsroot.txt.
 
 
+	nfs.callback_tcpport=
+			[NFS] set the TCP port on which the NFSv4 callback
+			channel should listen.
+
+	nfs.idmap_cache_timeout=
+			[NFS] set the maximum lifetime for idmapper cache
+			entries.
+
 	nmi_watchdog=	[KNL,BUGS=IA-32] Debugging features for SMP kernels
 	nmi_watchdog=	[KNL,BUGS=IA-32] Debugging features for SMP kernels
 
 
 	no387		[BUGS=IA-32] Tells the kernel to use the 387 maths
 	no387		[BUGS=IA-32] Tells the kernel to use the 387 maths

+ 0 - 18
Documentation/keys.txt

@@ -860,24 +860,6 @@ The structure has a number of fields, some of which are mandatory:
      It is safe to sleep in this method.
      It is safe to sleep in this method.
 
 
 
 
- (*) int (*duplicate)(struct key *key, const struct key *source);
-
-     If this type of key can be duplicated, then this method should be
-     provided. It is called to copy the payload attached to the source into the
-     new key. The data length on the new key will have been updated and the
-     quota adjusted already.
-
-     This method will be called with the source key's semaphore read-locked to
-     prevent its payload from being changed, thus RCU constraints need not be
-     applied to the source key.
-
-     This method does not have to lock the destination key in order to attach a
-     payload. The fact that KEY_FLAG_INSTANTIATED is not set in key->flags
-     prevents anything else from gaining access to the key.
-
-     It is safe to sleep in this method.
-
-
  (*) int (*update)(struct key *key, const void *data, size_t datalen);
  (*) int (*update)(struct key *key, const void *data, size_t datalen);
 
 
      If this type of key can be updated, then this method should be provided.
      If this type of key can be updated, then this method should be provided.

+ 120 - 0
Documentation/md.txt

@@ -51,6 +51,30 @@ superblock can be autodetected and run at boot time.
 The kernel parameter "raid=partitionable" (or "raid=part") means
 The kernel parameter "raid=partitionable" (or "raid=part") means
 that all auto-detected arrays are assembled as partitionable.
 that all auto-detected arrays are assembled as partitionable.
 
 
+Boot time assembly of degraded/dirty arrays
+-------------------------------------------
+
+If a raid5 or raid6 array is both dirty and degraded, it could have
+undetectable data corruption.  This is because the fact that it is
+'dirty' means that the parity cannot be trusted, and the fact that it
+is degraded means that some datablocks are missing and cannot reliably
+be reconstructed (due to no parity).
+
+For this reason, md will normally refuse to start such an array.  This
+requires the sysadmin to take action to explicitly start the array
+desipite possible corruption.  This is normally done with
+   mdadm --assemble --force ....
+
+This option is not really available if the array has the root
+filesystem on it.  In order to support this booting from such an
+array, md supports a module parameter "start_dirty_degraded" which,
+when set to 1, bypassed the checks and will allows dirty degraded
+arrays to be started.
+
+So, to boot with a root filesystem of a dirty degraded raid[56], use
+
+   md-mod.start_dirty_degraded=1
+
 
 
 Superblock formats
 Superblock formats
 ------------------
 ------------------
@@ -141,6 +165,70 @@ All md devices contain:
      in a fully functional array.  If this is not yet known, the file
      in a fully functional array.  If this is not yet known, the file
      will be empty.  If an array is being resized (not currently
      will be empty.  If an array is being resized (not currently
      possible) this will contain the larger of the old and new sizes.
      possible) this will contain the larger of the old and new sizes.
+     Some raid level (RAID1) allow this value to be set while the
+     array is active.  This will reconfigure the array.   Otherwise
+     it can only be set while assembling an array.
+
+  chunk_size
+     This is the size if bytes for 'chunks' and is only relevant to
+     raid levels that involve striping (1,4,5,6,10). The address space
+     of the array is conceptually divided into chunks and consecutive
+     chunks are striped onto neighbouring devices.
+     The size should be atleast PAGE_SIZE (4k) and should be a power
+     of 2.  This can only be set while assembling an array
+
+  component_size
+     For arrays with data redundancy (i.e. not raid0, linear, faulty,
+     multipath), all components must be the same size - or at least
+     there must a size that they all provide space for.  This is a key
+     part or the geometry of the array.  It is measured in sectors
+     and can be read from here.  Writing to this value may resize
+     the array if the personality supports it (raid1, raid5, raid6),
+     and if the component drives are large enough.
+
+  metadata_version
+     This indicates the format that is being used to record metadata
+     about the array.  It can be 0.90 (traditional format), 1.0, 1.1,
+     1.2 (newer format in varying locations) or "none" indicating that
+     the kernel isn't managing metadata at all.
+
+  level
+     The raid 'level' for this array.  The name will often (but not
+     always) be the same as the name of the module that implements the
+     level.  To be auto-loaded the module must have an alias
+        md-$LEVEL  e.g. md-raid5
+     This can be written only while the array is being assembled, not
+     after it is started.
+
+   new_dev
+     This file can be written but not read.  The value written should
+     be a block device number as major:minor.  e.g. 8:0
+     This will cause that device to be attached to the array, if it is
+     available.  It will then appear at md/dev-XXX (depending on the
+     name of the device) and further configuration is then possible.
+
+   sync_speed_min
+   sync_speed_max
+     This are similar to /proc/sys/dev/raid/speed_limit_{min,max}
+     however they only apply to the particular array.
+     If no value has been written to these, of if the word 'system'
+     is written, then the system-wide value is used.  If a value,
+     in kibibytes-per-second is written, then it is used.
+     When the files are read, they show the currently active value
+     followed by "(local)" or "(system)" depending on whether it is
+     a locally set or system-wide value.
+
+   sync_completed
+     This shows the number of sectors that have been completed of
+     whatever the current sync_action is, followed by the number of
+     sectors in total that could need to be processed.  The two
+     numbers are separated by a '/'  thus effectively showing one
+     value, a fraction of the process that is complete.
+
+   sync_speed
+     This shows the current actual speed, in K/sec, of the current
+     sync_action.  It is averaged over the last 30 seconds.
+
 
 
 As component devices are added to an md array, they appear in the 'md'
 As component devices are added to an md array, they appear in the 'md'
 directory as new directories named
 directory as new directories named
@@ -167,6 +255,38 @@ Each directory contains:
 			 of being recoverred to
 			 of being recoverred to
 	This list make grow in future.
 	This list make grow in future.
 
 
+      errors
+	An approximate count of read errors that have been detected on
+	this device but have not caused the device to be evicted from
+	the array (either because they were corrected or because they
+	happened while the array was read-only).  When using version-1
+	metadata, this value persists across restarts of the array.
+
+	This value can be written while assembling an array thus
+	providing an ongoing count for arrays with metadata managed by
+	userspace.
+
+      slot
+        This gives the role that the device has in the array.  It will
+	either be 'none' if the device is not active in the array
+        (i.e. is a spare or has failed) or an integer less than the
+	'raid_disks' number for the array indicating which possition
+	it currently fills.  This can only be set while assembling an
+	array.  A device for which this is set is assumed to be working.
+
+      offset
+        This gives the location in the device (in sectors from the
+        start) where data from the array will be stored.  Any part of
+        the device before this offset us not touched, unless it is
+        used for storing metadata (Formats 1.1 and 1.2).
+
+      size
+        The amount of the device, after the offset, that can be used
+        for storage of data.  This will normally be the same as the
+	component_size.  This can be written while assembling an
+        array.  If a value less than the current component_size is
+        written, component_size will be reduced to this value.
+
 
 
 An active md device will also contain and entry for each active device
 An active md device will also contain and entry for each active device
 in the array.  These are named
 in the array.  These are named

+ 72 - 0
Documentation/networking/gianfar.txt

@@ -0,0 +1,72 @@
+The Gianfar Ethernet Driver
+Sysfs File description
+
+Author: Andy Fleming <afleming@freescale.com>
+Updated: 2005-07-28
+
+SYSFS
+
+Several of the features of the gianfar driver are controlled
+through sysfs files.  These are:
+
+bd_stash:
+To stash RX Buffer Descriptors in the L2, echo 'on' or '1' to
+bd_stash, echo 'off' or '0' to disable
+
+rx_stash_len:
+To stash the first n bytes of the packet in L2, echo the number
+of bytes to buf_stash_len.  echo 0 to disable.
+
+WARNING: You could really screw these up if you set them too low or high!
+fifo_threshold:
+To change the number of bytes the controller needs in the
+fifo before it starts transmission, echo the number of bytes to 
+fifo_thresh.  Range should be 0-511.
+
+fifo_starve:
+When the FIFO has less than this many bytes during a transmit, it
+enters starve mode, and increases the priority of TX memory
+transactions.  To change, echo the number of bytes to
+fifo_starve.  Range should be 0-511.
+
+fifo_starve_off:
+Once in starve mode, the FIFO remains there until it has this
+many bytes.  To change, echo the number of bytes to
+fifo_starve_off.  Range should be 0-511.
+
+CHECKSUM OFFLOADING
+
+The eTSEC controller (first included in parts from late 2005 like
+the 8548) has the ability to perform TCP, UDP, and IP checksums
+in hardware.  The Linux kernel only offloads the TCP and UDP
+checksums (and always performs the pseudo header checksums), so
+the driver only supports checksumming for TCP/IP and UDP/IP
+packets.  Use ethtool to enable or disable this feature for RX
+and TX.
+
+VLAN
+
+In order to use VLAN, please consult Linux documentation on
+configuring VLANs.  The gianfar driver supports hardware insertion and
+extraction of VLAN headers, but not filtering.  Filtering will be
+done by the kernel.
+
+MULTICASTING
+
+The gianfar driver supports using the group hash table on the
+TSEC (and the extended hash table on the eTSEC) for multicast
+filtering.  On the eTSEC, the exact-match MAC registers are used
+before the hash tables.  See Linux documentation on how to join
+multicast groups.
+
+PADDING
+
+The gianfar driver supports padding received frames with 2 bytes
+to align the IP header to a 16-byte boundary, when supported by
+hardware.
+
+ETHTOOL
+
+The gianfar driver supports the use of ethtool for many
+configuration options.  You must run ethtool only on currently
+open interfaces.  See ethtool documentation for details.

+ 23 - 0
Documentation/networking/ip-sysctl.txt

@@ -46,6 +46,29 @@ ipfrag_secret_interval - INTEGER
 	for the hash secret) for IP fragments.
 	for the hash secret) for IP fragments.
 	Default: 600
 	Default: 600
 
 
+ipfrag_max_dist - INTEGER
+	ipfrag_max_dist is a non-negative integer value which defines the 
+	maximum "disorder" which is allowed among fragments which share a 
+	common IP source address. Note that reordering of packets is 
+	not unusual, but if a large number of fragments arrive from a source 
+	IP address while a particular fragment queue remains incomplete, it 
+	probably indicates that one or more fragments belonging to that queue 
+	have been lost. When ipfrag_max_dist is positive, an additional check 
+	is done on fragments before they are added to a reassembly queue - if 
+	ipfrag_max_dist (or more) fragments have arrived from a particular IP 
+	address between additions to any IP fragment queue using that source 
+	address, it's presumed that one or more fragments in the queue are 
+	lost. The existing fragment queue will be dropped, and a new one 
+	started. An ipfrag_max_dist value of zero disables this check.
+
+	Using a very small value, e.g. 1 or 2, for ipfrag_max_dist can
+	result in unnecessarily dropping fragment queues when normal
+	reordering of packets occurs, which could lead to poor application 
+	performance. Using a very large value, e.g. 50000, increases the 
+	likelihood of incorrectly reassembling IP fragments that originate 
+	from different IP datagrams, which could result in data corruption.
+	Default: 64
+
 INET peer storage:
 INET peer storage:
 
 
 inet_peer_threshold - INTEGER
 inet_peer_threshold - INTEGER

+ 11 - 0
Documentation/pcmcia/driver-changes.txt

@@ -1,5 +1,16 @@
 This file details changes in 2.6 which affect PCMCIA card driver authors:
 This file details changes in 2.6 which affect PCMCIA card driver authors:
 
 
+* Unify detach and REMOVAL event code, as well as attach and INSERTION
+  code (as of 2.6.16)
+       void (*remove)          (struct pcmcia_device *dev);
+       int (*probe)            (struct pcmcia_device *dev);
+
+* Move suspend, resume and reset out of event handler (as of 2.6.16)
+       int (*suspend)          (struct pcmcia_device *dev);
+       int (*resume)           (struct pcmcia_device *dev);
+  should be initialized in struct pcmcia_driver, and handle
+  (SUSPEND == RESET_PHYSICAL) and (RESUME == CARD_RESET) events
+
 * event handler initialization in struct pcmcia_driver (as of 2.6.13)
 * event handler initialization in struct pcmcia_driver (as of 2.6.13)
    The event handler is notified of all events, and must be initialized
    The event handler is notified of all events, and must be initialized
    as the event() callback in the driver's struct pcmcia_driver.
    as the event() callback in the driver's struct pcmcia_driver.

+ 11 - 0
Documentation/power/interface.txt

@@ -41,3 +41,14 @@ to. Writing to this file will accept one of
 It will only change to 'firmware' or 'platform' if the system supports
 It will only change to 'firmware' or 'platform' if the system supports
 it. 
 it. 
 
 
+/sys/power/image_size controls the size of the image created by
+the suspend-to-disk mechanism.  It can be written a string
+representing a non-negative integer that will be used as an upper
+limit of the image size, in megabytes.  The suspend-to-disk mechanism will
+do its best to ensure the image size will not exceed that number.  However,
+if this turns out to be impossible, it will try to suspend anyway using the
+smallest image possible.  In particular, if "0" is written to this file, the
+suspend image will be as small as possible.
+
+Reading from this file will display the current image size limit, which
+is set to 500 MB by default.

+ 5 - 0
Documentation/power/swsusp.txt

@@ -27,6 +27,11 @@ echo shutdown > /sys/power/disk; echo disk > /sys/power/state
 
 
 echo platform > /sys/power/disk; echo disk > /sys/power/state
 echo platform > /sys/power/disk; echo disk > /sys/power/state
 
 
+If you want to limit the suspend image size to N megabytes, do
+
+echo N > /sys/power/image_size
+
+before suspend (it is limited to 500 MB by default).
 
 
 Encrypted suspend image:
 Encrypted suspend image:
 ------------------------
 ------------------------

+ 16 - 15
Documentation/powerpc/eeh-pci-error-recovery.txt

@@ -115,7 +115,7 @@ Current PPC64 Linux EEH Implementation
 At this time, a generic EEH recovery mechanism has been implemented,
 At this time, a generic EEH recovery mechanism has been implemented,
 so that individual device drivers do not need to be modified to support
 so that individual device drivers do not need to be modified to support
 EEH recovery.  This generic mechanism piggy-backs on the PCI hotplug
 EEH recovery.  This generic mechanism piggy-backs on the PCI hotplug
-infrastructure,  and percolates events up through the hotplug/udev
+infrastructure,  and percolates events up through the userspace/udev
 infrastructure.  Followiing is a detailed description of how this is
 infrastructure.  Followiing is a detailed description of how this is
 accomplished.
 accomplished.
 
 
@@ -172,7 +172,7 @@ A handler for the EEH notifier_block events is implemented in
 drivers/pci/hotplug/pSeries_pci.c, called handle_eeh_events().
 drivers/pci/hotplug/pSeries_pci.c, called handle_eeh_events().
 It saves the device BAR's and then calls rpaphp_unconfig_pci_adapter().
 It saves the device BAR's and then calls rpaphp_unconfig_pci_adapter().
 This last call causes the device driver for the card to be stopped,
 This last call causes the device driver for the card to be stopped,
-which causes hotplug events to go out to user space. This triggers
+which causes uevents to go out to user space. This triggers
 user-space scripts that might issue commands such as "ifdown eth0"
 user-space scripts that might issue commands such as "ifdown eth0"
 for ethernet cards, and so on.  This handler then sleeps for 5 seconds,
 for ethernet cards, and so on.  This handler then sleeps for 5 seconds,
 hoping to give the user-space scripts enough time to complete.
 hoping to give the user-space scripts enough time to complete.
@@ -258,29 +258,30 @@ rpa_php_unconfig_pci_adapter() {             // in rpaphp_pci.c
     calls
     calls
     pci_destroy_dev (struct pci_dev *) {
     pci_destroy_dev (struct pci_dev *) {
       calls
       calls
-      device_unregister (&dev->dev) {      // in /drivers/base/core.c
+      device_unregister (&dev->dev) {        // in /drivers/base/core.c
         calls
         calls
-        device_del(struct device * dev) {  // in /drivers/base/core.c
+        device_del(struct device * dev) {    // in /drivers/base/core.c
           calls
           calls
-          kobject_del() {                  //in /libs/kobject.c
+          kobject_del() {                    //in /libs/kobject.c
             calls
             calls
-            kobject_hotplug() {            // in /libs/kobject.c
+            kobject_uevent() {               // in /libs/kobject.c
               calls
               calls
-              kset_hotplug() {             // in /lib/kobject.c
+              kset_uevent() {                // in /lib/kobject.c
                 calls
                 calls
-                kset->hotplug_ops->hotplug() which is really just
+                kset->uevent_ops->uevent()   // which is really just
                 a call to
                 a call to
-                dev_hotplug() {           // in /drivers/base/core.c
+                dev_uevent() {               // in /drivers/base/core.c
                   calls
                   calls
-                  dev->bus->hotplug() which is really just a call to
-                  pci_hotplug () {      // in drivers/pci/hotplug.c
+                  dev->bus->uevent() which is really just a call to
+                  pci_uevent () {            // in drivers/pci/hotplug.c
                     which prints device name, etc....
                     which prints device name, etc....
                  }
                  }
                }
                }
-               then kset_hotplug() calls
-                call_usermodehelper () with
-                   argv[0]=hotplug_path[] which is "/sbin/hotplug"
-             --> event to userspace,
+               then kobject_uevent() sends a netlink uevent to userspace
+               --> userspace uevent
+               (during early boot, nobody listens to netlink events and
+               kobject_uevent() executes uevent_helper[], which runs the
+               event process /sbin/hotplug)
            }
            }
          }
          }
          kobject_del() then calls sysfs_remove_dir(), which would
          kobject_del() then calls sysfs_remove_dir(), which would

+ 35 - 0
Documentation/scsi/ChangeLog.megaraid

@@ -1,3 +1,38 @@
+Release Date	: Fri Nov 11 12:27:22 EST 2005 - Seokmann Ju <sju@lsil.com>
+Current Version : 2.20.4.7 (scsi module), 2.20.2.6 (cmm module)
+Older Version	: 2.20.4.6 (scsi module), 2.20.2.6 (cmm module)
+
+1.	Sorted out PCI IDs to remove megaraid support overlaps.
+	Based on the patch from Daniel, sorted out PCI IDs along with
+	charactor node name change from 'megadev' to 'megadev_legacy' to avoid
+	conflict.
+	---
+	Hopefully we'll be getting the build restriction zapped much sooner, 
+	but we should also be thinking about totally removing the hardware 
+	support overlap in the megaraid drivers.
+
+	This patch pencils in a date of Feb 06 for this, and performs some 
+	printk abuse in hope that existing legacy users might pick up on what's
+	going on.
+
+	Signed-off-by: Daniel Drake <dsd@gentoo.org>
+	---
+
+2.	Fixed a issue: megaraid always fails to reset handler.
+	---
+	I found that the megaraid driver always fails to reset the
+	adapter with the following message:
+		megaraid: resetting the host...
+		megaraid mbox: reset sequence completed successfully
+		megaraid: fast sync command timed out
+		megaraid: reservation reset failed
+	when the "Cluster mode" of the adapter BIOS is enabled.
+	So, whenever the reset occurs, the adapter goes to
+	offline and just become unavailable.
+
+	Jun'ichi Nomura [mailto:jnomura@mtc.biglobe.ne.jp]
+	---
+
 Release Date	: Mon Mar 07 12:27:22 EST 2005 - Seokmann Ju <sju@lsil.com>
 Release Date	: Mon Mar 07 12:27:22 EST 2005 - Seokmann Ju <sju@lsil.com>
 Current Version : 2.20.4.6 (scsi module), 2.20.2.6 (cmm module)
 Current Version : 2.20.4.6 (scsi module), 2.20.2.6 (cmm module)
 Older Version	: 2.20.4.5 (scsi module), 2.20.2.5 (cmm module)
 Older Version	: 2.20.4.5 (scsi module), 2.20.2.5 (cmm module)

+ 29 - 10
Documentation/scsi/scsi_mid_low_api.txt

@@ -150,7 +150,8 @@ scsi devices of which only the first 2 respond:
 LLD                   mid level                    LLD
 LLD                   mid level                    LLD
 ===-------------------=========--------------------===------
 ===-------------------=========--------------------===------
 scsi_host_alloc()  -->
 scsi_host_alloc()  -->
-scsi_add_host()  --------+
+scsi_add_host()  ---->
+scsi_scan_host()  -------+
                          |
                          |
                     slave_alloc()
                     slave_alloc()
                     slave_configure() -->  scsi_adjust_queue_depth()
                     slave_configure() -->  scsi_adjust_queue_depth()
@@ -196,7 +197,7 @@ of the issues involved. See the section on reference counting below.
 
 
 
 
 The hotplug concept may be extended to SCSI devices. Currently, when an
 The hotplug concept may be extended to SCSI devices. Currently, when an
-HBA is added, the scsi_add_host() function causes a scan for SCSI devices
+HBA is added, the scsi_scan_host() function causes a scan for SCSI devices
 attached to the HBA's SCSI transport. On newer SCSI transports the HBA
 attached to the HBA's SCSI transport. On newer SCSI transports the HBA
 may become aware of a new SCSI device _after_ the scan has completed.
 may become aware of a new SCSI device _after_ the scan has completed.
 An LLD can use this sequence to make the mid level aware of a SCSI device:
 An LLD can use this sequence to make the mid level aware of a SCSI device:
@@ -372,7 +373,7 @@ names all start with "scsi_".
 Summary:
 Summary:
    scsi_activate_tcq - turn on tag command queueing
    scsi_activate_tcq - turn on tag command queueing
    scsi_add_device - creates new scsi device (lu) instance
    scsi_add_device - creates new scsi device (lu) instance
-   scsi_add_host - perform sysfs registration and SCSI bus scan.
+   scsi_add_host - perform sysfs registration and set up transport class
    scsi_adjust_queue_depth - change the queue depth on a SCSI device
    scsi_adjust_queue_depth - change the queue depth on a SCSI device
    scsi_assign_lock - replace default host_lock with given lock
    scsi_assign_lock - replace default host_lock with given lock
    scsi_bios_ptable - return copy of block device's partition table
    scsi_bios_ptable - return copy of block device's partition table
@@ -386,6 +387,7 @@ Summary:
    scsi_remove_device - detach and remove a SCSI device
    scsi_remove_device - detach and remove a SCSI device
    scsi_remove_host - detach and remove all SCSI devices owned by host
    scsi_remove_host - detach and remove all SCSI devices owned by host
    scsi_report_bus_reset - report scsi _bus_ reset observed
    scsi_report_bus_reset - report scsi _bus_ reset observed
+   scsi_scan_host - scan SCSI bus
    scsi_track_queue_full - track successive QUEUE_FULL events 
    scsi_track_queue_full - track successive QUEUE_FULL events 
    scsi_unblock_requests - allow further commands to be queued to given host
    scsi_unblock_requests - allow further commands to be queued to given host
    scsi_unregister - [calls scsi_host_put()]
    scsi_unregister - [calls scsi_host_put()]
@@ -425,10 +427,10 @@ void scsi_activate_tcq(struct scsi_device *sdev, int depth)
  *      Might block: yes
  *      Might block: yes
  *
  *
  *      Notes: This call is usually performed internally during a scsi
  *      Notes: This call is usually performed internally during a scsi
- *      bus scan when an HBA is added (i.e. scsi_add_host()). So it
+ *      bus scan when an HBA is added (i.e. scsi_scan_host()). So it
  *      should only be called if the HBA becomes aware of a new scsi
  *      should only be called if the HBA becomes aware of a new scsi
- *      device (lu) after scsi_add_host() has completed. If successful
- *      this call we lead to slave_alloc() and slave_configure() callbacks
+ *      device (lu) after scsi_scan_host() has completed. If successful
+ *      this call can lead to slave_alloc() and slave_configure() callbacks
  *      into the LLD.
  *      into the LLD.
  *
  *
  *      Defined in: drivers/scsi/scsi_scan.c
  *      Defined in: drivers/scsi/scsi_scan.c
@@ -439,7 +441,7 @@ struct scsi_device * scsi_add_device(struct Scsi_Host *shost,
 
 
 
 
 /**
 /**
- * scsi_add_host - perform sysfs registration and SCSI bus scan.
+ * scsi_add_host - perform sysfs registration and set up transport class
  * @shost:   pointer to scsi host instance
  * @shost:   pointer to scsi host instance
  * @dev:     pointer to struct device of type scsi class
  * @dev:     pointer to struct device of type scsi class
  *
  *
@@ -448,7 +450,11 @@ struct scsi_device * scsi_add_device(struct Scsi_Host *shost,
  *      Might block: no
  *      Might block: no
  *
  *
  *      Notes: Only required in "hotplug initialization model" after a
  *      Notes: Only required in "hotplug initialization model" after a
- *      successful call to scsi_host_alloc().
+ *      successful call to scsi_host_alloc().  This function does not
+ *	scan the bus; this can be done by calling scsi_scan_host() or
+ *	in some other transport-specific way.  The LLD must set up
+ *	the transport template before calling this function and may only
+ *	access the transport class data after this function has been called.
  *
  *
  *      Defined in: drivers/scsi/hosts.c
  *      Defined in: drivers/scsi/hosts.c
  **/
  **/
@@ -559,7 +565,7 @@ void scsi_deactivate_tcq(struct scsi_device *sdev, int depth)
  *      area for the LLD's exclusive use.
  *      area for the LLD's exclusive use.
  *      Both associated refcounting objects have their refcount set to 1.
  *      Both associated refcounting objects have their refcount set to 1.
  *      Full registration (in sysfs) and a bus scan are performed later when
  *      Full registration (in sysfs) and a bus scan are performed later when
- *      scsi_add_host() is called.
+ *      scsi_add_host() and scsi_scan_host() are called.
  *
  *
  *      Defined in: drivers/scsi/hosts.c .
  *      Defined in: drivers/scsi/hosts.c .
  **/
  **/
@@ -698,6 +704,19 @@ int scsi_remove_host(struct Scsi_Host *shost)
 void scsi_report_bus_reset(struct Scsi_Host * shost, int channel)
 void scsi_report_bus_reset(struct Scsi_Host * shost, int channel)
 
 
 
 
+/**
+ * scsi_scan_host - scan SCSI bus
+ * @shost: a pointer to a scsi host instance
+ *
+ *	Might block: yes
+ *
+ *	Notes: Should be called after scsi_add_host()
+ *
+ *	Defined in: drivers/scsi/scsi_scan.c
+ **/
+void scsi_scan_host(struct Scsi_Host *shost)
+
+
 /**
 /**
  * scsi_track_queue_full - track successive QUEUE_FULL events on given
  * scsi_track_queue_full - track successive QUEUE_FULL events on given
  *                      device to determine if and when there is a need
  *                      device to determine if and when there is a need
@@ -1433,7 +1452,7 @@ The following people have contributed to this document:
         Christoph Hellwig <hch at infradead dot org>
         Christoph Hellwig <hch at infradead dot org>
         Doug Ledford <dledford at redhat dot com>
         Doug Ledford <dledford at redhat dot com>
         Andries Brouwer <Andries dot Brouwer at cwi dot nl>
         Andries Brouwer <Andries dot Brouwer at cwi dot nl>
-        Randy Dunlap <rddunlap at osdl dot org>
+        Randy Dunlap <rdunlap at xenotime dot net>
         Alan Stern <stern at rowland dot harvard dot edu>
         Alan Stern <stern at rowland dot harvard dot edu>
 
 
 
 

+ 130 - 64
Documentation/sound/alsa/ALSA-Configuration.txt

@@ -105,7 +105,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     Each of top level sound card module takes the following options.
     Each of top level sound card module takes the following options.
 
 
     index	- index (slot #) of sound card
     index	- index (slot #) of sound card
-		- Values: 0 through 7 or negative
+		- Values: 0 through 31 or negative
 		- If nonnegative, assign that index number
 		- If nonnegative, assign that index number
                 - if negative, interpret as a bitmask of permissible
                 - if negative, interpret as a bitmask of permissible
 		  indices; the first free permitted index is assigned
 		  indices; the first free permitted index is assigned
@@ -134,7 +134,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     dma2	- second DMA # for AD1816A chip (PnP setup)
     dma2	- second DMA # for AD1816A chip (PnP setup)
     clockfreq   - Clock frequency for AD1816A chip (default = 0, 33000Hz)
     clockfreq   - Clock frequency for AD1816A chip (default = 0, 33000Hz)
     
     
-    Module supports up to 8 cards, autoprobe and PnP.
+    This module supports multiple cards, autoprobe and PnP.
     
     
   Module snd-ad1848
   Module snd-ad1848
   -----------------
   -----------------
@@ -145,9 +145,11 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     irq		- IRQ # for AD1848  chip
     irq		- IRQ # for AD1848  chip
     dma1	- DMA # for AD1848 chip (0,1,3)
     dma1	- DMA # for AD1848 chip (0,1,3)
     
     
-    Module supports up to 8 cards. This module does not support autoprobe
+    This module supports multiple cards.  It does not support autoprobe
     thus main port must be specified!!! Other ports are optional.
     thus main port must be specified!!! Other ports are optional.
     
     
+    The power-management is supported.
+
   Module snd-ad1889
   Module snd-ad1889
   -----------------
   -----------------
 
 
@@ -156,7 +158,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     ac97_quirk  - AC'97 workaround for strange hardware
     ac97_quirk  - AC'97 workaround for strange hardware
                   See the description of intel8x0 module for details.
                   See the description of intel8x0 module for details.
 
 
-    This module supports up to 8 cards.
+    This module supports multiple cards.
 
 
   Module snd-ali5451
   Module snd-ali5451
   ------------------
   ------------------
@@ -184,7 +186,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     mpu_irq	- IRQ # for MPU-401 (PnP setup)
     mpu_irq	- IRQ # for MPU-401 (PnP setup)
     fm_port	- port # for OPL3 FM (PnP setup)
     fm_port	- port # for OPL3 FM (PnP setup)
     
     
-    Module supports up to 8 cards, autoprobe and PnP.
+    This module supports multiple cards, autoprobe and PnP.
+
+    The power-management is supported.
 
 
   Module snd-als4000
   Module snd-als4000
   ------------------
   ------------------
@@ -194,7 +198,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     joystick_port - port # for legacy joystick support.
     joystick_port - port # for legacy joystick support.
                     0 = disabled (default), 1 = auto-detect
                     0 = disabled (default), 1 = auto-detect
     
     
-    Module supports up to 8 cards, autoprobe and PnP.
+    This module supports multiple cards, autoprobe and PnP.
+
+    The power-management is supported.
 
 
   Module snd-atiixp
   Module snd-atiixp
   -----------------
   -----------------
@@ -213,6 +219,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     implementation depends on the motherboard, and you'll need to
     implementation depends on the motherboard, and you'll need to
     choose the correct one via spdif_aclink module option.
     choose the correct one via spdif_aclink module option.
 
 
+    The power-management is supported.
+
   Module snd-atiixp-modem
   Module snd-atiixp-modem
   -----------------------
   -----------------------
 
 
@@ -223,6 +231,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     Note: The default index value of this module is -2, i.e. the first
     Note: The default index value of this module is -2, i.e. the first
           slot is excluded.
           slot is excluded.
 
 
+    The power-management is supported.
+
   Module snd-au8810, snd-au8820, snd-au8830
   Module snd-au8810, snd-au8820, snd-au8830
   -----------------------------------------
   -----------------------------------------
 
 
@@ -263,8 +273,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     dma1	- 1st DMA # for AZT2320 (WSS) chip (PnP setup)
     dma1	- 1st DMA # for AZT2320 (WSS) chip (PnP setup)
     dma2	- 2nd DMA # for AZT2320 (WSS) chip (PnP setup)
     dma2	- 2nd DMA # for AZT2320 (WSS) chip (PnP setup)
     
     
-    Module supports up to 8 cards, PnP and autoprobe.
+    This module supports multiple cards, PnP and autoprobe.
     
     
+    The power-management is supported.
+
   Module snd-azt3328
   Module snd-azt3328
   ------------------
   ------------------
 
 
@@ -272,7 +284,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
 
 
     joystick	- Enable joystick (default off)
     joystick	- Enable joystick (default off)
 
 
-    Module supports up to 8 cards.
+    This module supports multiple cards.
 
 
   Module snd-bt87x
   Module snd-bt87x
   ----------------
   ----------------
@@ -282,7 +294,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     digital_rate - Override the default digital rate (Hz)
     digital_rate - Override the default digital rate (Hz)
     load_all	- Load the driver even if the card model isn't known
     load_all	- Load the driver even if the card model isn't known
 
 
-    Module supports up to 8 cards.
+    This module supports multiple cards.
 
 
     Note: The default index value of this module is -2, i.e. the first
     Note: The default index value of this module is -2, i.e. the first
           slot is excluded.
           slot is excluded.
@@ -292,7 +304,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
 
 
     Module for Creative Audigy LS and SB Live 24bit
     Module for Creative Audigy LS and SB Live 24bit
 
 
-    Module supports up to 8 cards.
+    This module supports multiple cards.
 
 
 
 
   Module snd-cmi8330
   Module snd-cmi8330
@@ -308,7 +320,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     sbdma8	- 8bit DMA # for CMI8330 chip (SB16)
     sbdma8	- 8bit DMA # for CMI8330 chip (SB16)
     sbdma16	- 16bit DMA # for CMI8330 chip (SB16)
     sbdma16	- 16bit DMA # for CMI8330 chip (SB16)
 
 
-    Module supports up to 8 cards and autoprobe.
+    This module supports multiple cards and autoprobe.
+
+    The power-management is supported.
 
 
   Module snd-cmipci
   Module snd-cmipci
   -----------------
   -----------------
@@ -321,8 +335,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
                   (default = 1)
                   (default = 1)
     joystick_port - Joystick port address (0 = disable, 1 = auto-detect)
     joystick_port - Joystick port address (0 = disable, 1 = auto-detect)
 
 
-    Module supports autoprobe and multiple chips (max 8).
+    This module supports autoprobe and multiple cards.
     
     
+    The power-management is supported.
+
   Module snd-cs4231
   Module snd-cs4231
   -----------------
   -----------------
 
 
@@ -335,7 +351,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     dma1	- first DMA # for CS4231 chip
     dma1	- first DMA # for CS4231 chip
     dma2	- second DMA # for CS4231 chip
     dma2	- second DMA # for CS4231 chip
     
     
-    Module supports up to 8 cards. This module does not support autoprobe
+    This module supports multiple cards. This module does not support autoprobe
     thus main port must be specified!!! Other ports are optional.
     thus main port must be specified!!! Other ports are optional.
 
 
     The power-management is supported.
     The power-management is supported.
@@ -355,7 +371,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     dma2	- second DMA # for Yamaha CS4232 chip (0,1,3), -1 = disable
     dma2	- second DMA # for Yamaha CS4232 chip (0,1,3), -1 = disable
     isapnp	- ISA PnP detection - 0 = disable, 1 = enable (default)
     isapnp	- ISA PnP detection - 0 = disable, 1 = enable (default)
     
     
-    Module supports up to 8 cards. This module does not support autoprobe
+    This module supports multiple cards. This module does not support autoprobe
     thus main port must be specified!!! Other ports are optional.
     thus main port must be specified!!! Other ports are optional.
 
 
     The power-management is supported.
     The power-management is supported.
@@ -376,7 +392,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     dma2	- second DMA # for CS4236 chip (0,1,3), -1 = disable
     dma2	- second DMA # for CS4236 chip (0,1,3), -1 = disable
     isapnp	- ISA PnP detection - 0 = disable, 1 = enable (default)
     isapnp	- ISA PnP detection - 0 = disable, 1 = enable (default)
     
     
-    Module supports up to 8 cards. This module does not support autoprobe
+    This module supports multiple cards. This module does not support autoprobe
     (if ISA PnP is not used) thus main port and control port must be
     (if ISA PnP is not used) thus main port and control port must be
     specified!!! Other ports are optional.
     specified!!! Other ports are optional.
 
 
@@ -389,7 +405,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
 
 
     dual_codec	- Secondary codec ID (0 = disable, default)
     dual_codec	- Secondary codec ID (0 = disable, default)
 
 
-    Module supports up to 8 cards.
+    This module supports multiple cards.
 
 
     The power-management is supported.
     The power-management is supported.
 
 
@@ -403,13 +419,20 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     thinkpad         - Force to enable Thinkpad's CLKRUN control.
     thinkpad         - Force to enable Thinkpad's CLKRUN control.
     mmap_valid       - Support OSS mmap mode (default = 0).
     mmap_valid       - Support OSS mmap mode (default = 0).
 
 
-    Module supports up to 8 cards and autoprobe.
+    This module supports multiple cards and autoprobe.
     Usually external amp and CLKRUN controls are detected automatically
     Usually external amp and CLKRUN controls are detected automatically
     from PCI sub vendor/device ids.  If they don't work, give the options
     from PCI sub vendor/device ids.  If they don't work, give the options
     above explicitly.
     above explicitly.
 
 
     The power-management is supported.
     The power-management is supported.
     
     
+  Module snd-cs5535audio
+  ----------------------
+
+    Module for multifunction CS5535 companion PCI device
+
+    This module supports multiple cards.
+
   Module snd-dt019x
   Module snd-dt019x
   -----------------
   -----------------
 
 
@@ -423,9 +446,11 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     mpu_irq	- IRQ # for MPU-401 (PnP setup)
     mpu_irq	- IRQ # for MPU-401 (PnP setup)
     dma8	- DMA # (PnP setup)
     dma8	- DMA # (PnP setup)
 
 
-    Module supports up to 8 cards.  This module is enabled only with
+    This module supports multiple cards.  This module is enabled only with
     ISA PnP support.
     ISA PnP support.
 
 
+    The power-management is supported.
+
   Module snd-dummy
   Module snd-dummy
   ----------------
   ----------------
 
 
@@ -433,6 +458,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     or input, but you may use this module for any application which
     or input, but you may use this module for any application which
     requires a sound card (like RealPlayer).
     requires a sound card (like RealPlayer).
 
 
+    The power-management is supported.
+
   Module snd-emu10k1
   Module snd-emu10k1
   ------------------
   ------------------
 
 
@@ -450,7 +477,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
                        given in MB unit.  Default value is 128.
                        given in MB unit.  Default value is 128.
     enable_ir - enable IR
     enable_ir - enable IR
 
 
-    Module supports up to 8 cards and autoprobe.
+    This module supports multiple cards and autoprobe.
 
 
     Input & Output configurations 			[extin/extout]
     Input & Output configurations 			[extin/extout]
 	* Creative Card wo/Digital out			[0x0003/0x1f03]
 	* Creative Card wo/Digital out			[0x0003/0x1f03]
@@ -466,12 +493,14 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
 	* Creative Card 5.1 (c) 2003			[0x3fc3/0x7cff]
 	* Creative Card 5.1 (c) 2003			[0x3fc3/0x7cff]
         * Creative Card all ins and outs		[0x3fff/0x7fff]
         * Creative Card all ins and outs		[0x3fff/0x7fff]
     
     
+    The power-management is supported.
+
   Module snd-emu10k1x
   Module snd-emu10k1x
   -------------------
   -------------------
 
 
     Module for Creative Emu10k1X (SB Live Dell OEM version)
     Module for Creative Emu10k1X (SB Live Dell OEM version)
 
 
-    Module supports up to 8 cards.
+    This module supports multiple cards.
 
 
   Module snd-ens1370
   Module snd-ens1370
   ------------------
   ------------------
@@ -482,7 +511,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
 
 
     joystick		- Enable joystick (default off)
     joystick		- Enable joystick (default off)
 
 
-    Module supports up to 8 cards and autoprobe.
+    This module supports multiple cards and autoprobe.
     
     
   Module snd-ens1371
   Module snd-ens1371
   ------------------
   ------------------
@@ -495,7 +524,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     joystick_port	- port # for joystick (0x200,0x208,0x210,0x218),
     joystick_port	- port # for joystick (0x200,0x208,0x210,0x218),
 			  0 = disable (default), 1 = auto-detect
 			  0 = disable (default), 1 = auto-detect
 
 
-    Module supports up to 8 cards and autoprobe.
+    This module supports multiple cards and autoprobe.
     
     
   Module snd-es968
   Module snd-es968
   ----------------
   ----------------
@@ -506,8 +535,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     irq		- IRQ # for ES968 (SB8) chip (PnP setup)
     irq		- IRQ # for ES968 (SB8) chip (PnP setup)
     dma1	- DMA # for ES968 (SB8) chip (PnP setup)
     dma1	- DMA # for ES968 (SB8) chip (PnP setup)
     
     
-    Module supports up to 8 cards, PnP and autoprobe.
+    This module supports multiple cards, PnP and autoprobe.
     
     
+    The power-management is supported.
+
   Module snd-es1688
   Module snd-es1688
   -----------------
   -----------------
 
 
@@ -519,7 +550,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     mpu_irq	- IRQ # for MPU-401 port (5,7,9,10)
     mpu_irq	- IRQ # for MPU-401 port (5,7,9,10)
     dma8	- DMA # for ES-1688 chip (0,1,3)
     dma8	- DMA # for ES-1688 chip (0,1,3)
 
 
-    Module supports up to 8 cards and autoprobe (without MPU-401 port).
+    This module supports multiple cards and autoprobe (without MPU-401 port).
 
 
   Module snd-es18xx
   Module snd-es18xx
   -----------------
   -----------------
@@ -534,8 +565,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     dma2	- first DMA # for ES-18xx chip (0,1,3)
     dma2	- first DMA # for ES-18xx chip (0,1,3)
     isapnp	- ISA PnP detection - 0 = disable, 1 = enable (default)
     isapnp	- ISA PnP detection - 0 = disable, 1 = enable (default)
 
 
-    Module supports up to 8 cards ISA PnP and autoprobe (without MPU-401 port
-    if native ISA PnP routines are not used).
+    This module supports multiple cards, ISA PnP and autoprobe (without MPU-401
+    port if native ISA PnP routines are not used).
     When dma2 is equal with dma1, the driver works as half-duplex.
     When dma2 is equal with dma1, the driver works as half-duplex.
 
 
     The power-management is supported.
     The power-management is supported.
@@ -545,7 +576,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
 
 
     Module for sound cards based on ESS Solo-1 (ES1938,ES1946) chips.
     Module for sound cards based on ESS Solo-1 (ES1938,ES1946) chips.
 
 
-    Module supports up to 8 cards and autoprobe.
+    This module supports multiple cards and autoprobe.
+
+    The power-management is supported.
 
 
   Module snd-es1968
   Module snd-es1968
   -----------------
   -----------------
@@ -561,7 +594,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     enable_mpu		- enable MPU401 (0 = off, 1 = on, 2 = auto (default))
     enable_mpu		- enable MPU401 (0 = off, 1 = on, 2 = auto (default))
     joystick		- enable joystick (default off)       
     joystick		- enable joystick (default off)       
 
 
-    Module supports up to 8 cards and autoprobe.
+    This module supports multiple cards and autoprobe.
 
 
     The power-management is supported.
     The power-management is supported.
 
 
@@ -577,8 +610,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
                           - High 16-bits are video (radio) device number + 1
                           - High 16-bits are video (radio) device number + 1
                           - example: 0x10002 (MediaForte 256-PCPR, device 1)
                           - example: 0x10002 (MediaForte 256-PCPR, device 1)
 
 
-    Module supports up to 8 cards and autoprobe.
+    This module supports multiple cards and autoprobe.
     
     
+    The power-management is supported.
+
   Module snd-gusclassic
   Module snd-gusclassic
   ---------------------
   ---------------------
 
 
@@ -592,7 +627,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     voices	- GF1 voices limit (14-32)
     voices	- GF1 voices limit (14-32)
     pcm_voices	- reserved PCM voices
     pcm_voices	- reserved PCM voices
 
 
-    Module supports up to 8 cards and autoprobe.
+    This module supports multiple cards and autoprobe.
 
 
   Module snd-gusextreme
   Module snd-gusextreme
   ---------------------
   ---------------------
@@ -611,7 +646,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     voices	- GF1 voices limit (14-32)
     voices	- GF1 voices limit (14-32)
     pcm_voices	- reserved PCM voices
     pcm_voices	- reserved PCM voices
 
 
-    Module supports up to 8 cards and autoprobe (without MPU-401 port).
+    This module supports multiple cards and autoprobe (without MPU-401 port).
 
 
   Module snd-gusmax
   Module snd-gusmax
   -----------------
   -----------------
@@ -626,7 +661,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     voices	- GF1 voices limit (14-32)
     voices	- GF1 voices limit (14-32)
     pcm_voices	- reserved PCM voices
     pcm_voices	- reserved PCM voices
 
 
-    Module supports up to 8 cards and autoprobe.
+    This module supports multiple cards and autoprobe.
     
     
   Module snd-hda-intel
   Module snd-hda-intel
   --------------------
   --------------------
@@ -688,12 +723,14 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
 	    (Usually SD_LPLIB register is more accurate than the
 	    (Usually SD_LPLIB register is more accurate than the
 	    position buffer.)
 	    position buffer.)
 
 
+    The power-management is supported.
+
   Module snd-hdsp
   Module snd-hdsp
   ---------------
   ---------------
 
 
     Module for RME Hammerfall DSP audio interface(s)
     Module for RME Hammerfall DSP audio interface(s)
 
 
-    Module supports up to 8 cards.
+    This module supports multiple cards.
 
 
     Note: The firmware data can be automatically loaded via hotplug
     Note: The firmware data can be automatically loaded via hotplug
           when CONFIG_FW_LOADER is set.  Otherwise, you need to load
           when CONFIG_FW_LOADER is set.  Otherwise, you need to load
@@ -751,7 +788,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     cs8427_timeout - reset timeout for the CS8427 chip (S/PDIF transciever)
     cs8427_timeout - reset timeout for the CS8427 chip (S/PDIF transciever)
                      in msec resolution, default value is 500 (0.5 sec)
                      in msec resolution, default value is 500 (0.5 sec)
 
 
-    Module supports up to 8 cards and autoprobe. Note: The consumer part
+    This module supports multiple cards and autoprobe. Note: The consumer part
     is not used with all Envy24 based cards (for example in the MidiMan Delta
     is not used with all Envy24 based cards (for example in the MidiMan Delta
     serie).
     serie).
 
 
@@ -787,7 +824,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
 		  aureon71, universe, k8x800, phase22, phase28, ms300,
 		  aureon71, universe, k8x800, phase22, phase28, ms300,
 		  av710
 		  av710
 
 
-    Module supports up to 8 cards and autoprobe.
+    This module supports multiple cards and autoprobe.
 
 
     Note: The supported board is detected by reading EEPROM or PCI
     Note: The supported board is detected by reading EEPROM or PCI
 	  SSID (if EEPROM isn't available).  You can override the
 	  SSID (if EEPROM isn't available).  You can override the
@@ -839,6 +876,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     Note: The default index value of this module is -2, i.e. the first
     Note: The default index value of this module is -2, i.e. the first
           slot is excluded.
           slot is excluded.
 
 
+    The power-management is supported.
+
   Module snd-interwave
   Module snd-interwave
   --------------------
   --------------------
 
 
@@ -855,7 +894,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     effect	- 1 = InterWave effects enable (default 0);
     effect	- 1 = InterWave effects enable (default 0);
                   requires 8 voices
                   requires 8 voices
 
 
-    Module supports up to 8 cards, autoprobe and ISA PnP.
+    This module supports multiple cards, autoprobe and ISA PnP.
 
 
   Module snd-interwave-stb
   Module snd-interwave-stb
   ------------------------
   ------------------------
@@ -875,14 +914,14 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     effect	- 1 = InterWave effects enable (default 0);
     effect	- 1 = InterWave effects enable (default 0);
                   requires 8 voices
                   requires 8 voices
 
 
-    Module supports up to 8 cards, autoprobe and ISA PnP.
+    This module supports multiple cards, autoprobe and ISA PnP.
 
 
   Module snd-korg1212
   Module snd-korg1212
   -------------------
   -------------------
 
 
     Module for Korg 1212 IO PCI card
     Module for Korg 1212 IO PCI card
 
 
-    Module supports up to 8 cards.
+    This module supports multiple cards.
 
 
   Module snd-maestro3
   Module snd-maestro3
   -------------------
   -------------------
@@ -894,7 +933,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
                        -1 for default pin (8 for allegro, 1 for
                        -1 for default pin (8 for allegro, 1 for
                        others) 
                        others) 
 
 
-    Module supports autoprobe and multiple chips (max 8).
+    This module supports autoprobe and multiple chips.
 
 
     Note: the binding of amplifier is dependent on hardware.
     Note: the binding of amplifier is dependent on hardware.
     If there is no sound even though all channels are unmuted, try to
     If there is no sound even though all channels are unmuted, try to
@@ -909,7 +948,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
 
 
     Module for Digigram miXart8 sound cards.
     Module for Digigram miXart8 sound cards.
 
 
-    Module supports multiple cards.
+    This module supports multiple cards.
     Note: One miXart8 board will be represented as 4 alsa cards.
     Note: One miXart8 board will be represented as 4 alsa cards.
           See MIXART.txt for details.
           See MIXART.txt for details.
 
 
@@ -928,7 +967,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     irq		- IRQ number or -1 (disable)
     irq		- IRQ number or -1 (disable)
     pnp		- PnP detection - 0 = disable, 1 = enable (default)
     pnp		- PnP detection - 0 = disable, 1 = enable (default)
 
 
-    Module supports multiple devices (max 8) and PnP.
+    This module supports multiple devices and PnP.
     
     
   Module snd-mtpav
   Module snd-mtpav
   ----------------
   ----------------
@@ -1014,7 +1053,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     dma2	- second DMA # for Yamaha OPL3-SA chip (0,1,3), -1 = disable
     dma2	- second DMA # for Yamaha OPL3-SA chip (0,1,3), -1 = disable
     isapnp	- ISA PnP detection - 0 = disable, 1 = enable (default)
     isapnp	- ISA PnP detection - 0 = disable, 1 = enable (default)
     
     
-    Module supports up to 8 cards and ISA PnP. This module does not support
+    This module supports multiple cards and ISA PnP.  It does not support
     autoprobe (if ISA PnP is not used) thus all ports must be specified!!!
     autoprobe (if ISA PnP is not used) thus all ports must be specified!!!
     
     
     The power-management is supported.
     The power-management is supported.
@@ -1064,6 +1103,13 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
 
 
     This module supports only one card, autoprobe and PnP.
     This module supports only one card, autoprobe and PnP.
 
 
+  Module snd-pcxhr
+  ----------------
+
+    Module for Digigram PCXHR boards
+
+    This module supports multiple cards.
+
   Module snd-powermac (on ppc only)
   Module snd-powermac (on ppc only)
   ---------------------------------
   ---------------------------------
 
 
@@ -1084,20 +1130,22 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
 
 
     For ARM architecture only.
     For ARM architecture only.
 
 
+    The power-management is supported.
+
   Module snd-rme32
   Module snd-rme32
   ----------------
   ----------------
 
 
     Module for RME Digi32, Digi32 Pro and Digi32/8 (Sek'd Prodif32, 
     Module for RME Digi32, Digi32 Pro and Digi32/8 (Sek'd Prodif32, 
     Prodif96 and Prodif Gold) sound cards.
     Prodif96 and Prodif Gold) sound cards.
 
 
-    Module supports up to 8 cards.
+    This module supports multiple cards.
 
 
   Module snd-rme96
   Module snd-rme96
   ----------------
   ----------------
 
 
     Module for RME Digi96, Digi96/8 and Digi96/8 PRO/PAD/PST sound cards.
     Module for RME Digi96, Digi96/8 and Digi96/8 PRO/PAD/PST sound cards.
 
 
-    Module supports up to 8 cards.
+    This module supports multiple cards.
 
 
   Module snd-rme9652
   Module snd-rme9652
   ------------------
   ------------------
@@ -1107,7 +1155,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     precise_ptr	- Enable precise pointer (doesn't work reliably).
     precise_ptr	- Enable precise pointer (doesn't work reliably).
 		  (default = 0)
 		  (default = 0)
 
 
-    Module supports up to 8 cards.
+    This module supports multiple cards.
 
 
     Note: snd-page-alloc module does the job which snd-hammerfall-mem
     Note: snd-page-alloc module does the job which snd-hammerfall-mem
           module did formerly.  It will allocate the buffers in advance
           module did formerly.  It will allocate the buffers in advance
@@ -1124,6 +1172,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     Module supports only one card.
     Module supports only one card.
     Module has no enable and index options.
     Module has no enable and index options.
 
 
+    The power-management is supported.
+
   Module snd-sb8
   Module snd-sb8
   --------------
   --------------
 
 
@@ -1135,8 +1185,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     irq		- IRQ # for SB DSP chip (5,7,9,10)
     irq		- IRQ # for SB DSP chip (5,7,9,10)
     dma8	- DMA # for SB DSP chip (1,3)
     dma8	- DMA # for SB DSP chip (1,3)
 
 
-    Module supports up to 8 cards and autoprobe.
+    This module supports multiple cards and autoprobe.
     
     
+    The power-management is supported.
+
   Module snd-sb16 and snd-sbawe
   Module snd-sb16 and snd-sbawe
   -----------------------------
   -----------------------------
 
 
@@ -1155,7 +1207,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     csp		- ASP/CSP chip support - 0 = disable (default), 1 = enable
     csp		- ASP/CSP chip support - 0 = disable (default), 1 = enable
     isapnp	- ISA PnP detection - 0 = disable, 1 = enable (default)
     isapnp	- ISA PnP detection - 0 = disable, 1 = enable (default)
     
     
-    Module supports up to 8 cards, autoprobe and ISA PnP.
+    This module supports multiple cards, autoprobe and ISA PnP.
 
 
     Note: To use Vibra16X cards in 16-bit half duplex mode, you must
     Note: To use Vibra16X cards in 16-bit half duplex mode, you must
           disable 16bit DMA with dma16 = -1 module parameter.
           disable 16bit DMA with dma16 = -1 module parameter.
@@ -1163,6 +1215,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
           half duplex mode through 8-bit DMA channel by disabling their
           half duplex mode through 8-bit DMA channel by disabling their
           16-bit DMA channel.
           16-bit DMA channel.
     
     
+    The power-management is supported.
+
   Module snd-sgalaxy
   Module snd-sgalaxy
   ------------------
   ------------------
 
 
@@ -1173,7 +1227,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     irq		- IRQ # (7,9,10,11)
     irq		- IRQ # (7,9,10,11)
     dma1	- DMA #
     dma1	- DMA #
 
 
-    Module supports up to 8 cards.
+    This module supports multiple cards.
+
+    The power-management is supported.
 
 
   Module snd-sscape
   Module snd-sscape
   -----------------
   -----------------
@@ -1185,7 +1241,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     mpu_irq	- MPU-401 IRQ # (PnP setup)
     mpu_irq	- MPU-401 IRQ # (PnP setup)
     dma		- DMA # (PnP setup)
     dma		- DMA # (PnP setup)
 
 
-    Module supports up to 8 cards.  ISA PnP must be enabled.
+    This module supports multiple cards.  ISA PnP must be enabled.
     You need sscape_ctl tool in alsa-tools package for loading
     You need sscape_ctl tool in alsa-tools package for loading
     the microcode.
     the microcode.
 
 
@@ -1194,21 +1250,21 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
 
 
     Module for AMD7930 sound chips found on Sparcs.
     Module for AMD7930 sound chips found on Sparcs.
 
 
-    Module supports up to 8 cards.
+    This module supports multiple cards.
 
 
   Module snd-sun-cs4231 (on sparc only)
   Module snd-sun-cs4231 (on sparc only)
   -------------------------------------
   -------------------------------------
 
 
     Module for CS4231 sound chips found on Sparcs.
     Module for CS4231 sound chips found on Sparcs.
 
 
-    Module supports up to 8 cards.
+    This module supports multiple cards.
 
 
   Module snd-sun-dbri (on sparc only)
   Module snd-sun-dbri (on sparc only)
   -----------------------------------
   -----------------------------------
 
 
     Module for DBRI sound chips found on Sparcs.
     Module for DBRI sound chips found on Sparcs.
 
 
-    Module supports up to 8 cards.
+    This module supports multiple cards.
 
 
   Module snd-wavefront
   Module snd-wavefront
   --------------------
   --------------------
@@ -1228,7 +1284,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     dma2            - DMA2 # for CS4232 PCM interface.
     dma2            - DMA2 # for CS4232 PCM interface.
     isapnp          - ISA PnP detection - 0 = disable, 1 = enable (default)
     isapnp          - ISA PnP detection - 0 = disable, 1 = enable (default)
 
 
-    Module supports up to 8 cards and ISA PnP.
+    This module supports multiple cards and ISA PnP.
 
 
   Module snd-sonicvibes
   Module snd-sonicvibes
   ---------------------
   ---------------------
@@ -1240,7 +1296,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
                   - SoundCard must have onboard SRAM for this.
                   - SoundCard must have onboard SRAM for this.
     mge       - Mic Gain Enable - 1 = enable, 0 = disable (default)
     mge       - Mic Gain Enable - 1 = enable, 0 = disable (default)
     
     
-    Module supports up to 8 cards and autoprobe.
+    This module supports multiple cards and autoprobe.
 
 
   Module snd-serial-u16550
   Module snd-serial-u16550
   ------------------------
   ------------------------
@@ -1259,7 +1315,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
                   0 = Soundcanvas, 1 = MS-124T, 2 = MS-124W S/A,
                   0 = Soundcanvas, 1 = MS-124T, 2 = MS-124W S/A,
 		  3 = MS-124W M/B, 4 = Generic
 		  3 = MS-124W M/B, 4 = Generic
     
     
-    Module supports up to 8 cards. This module does not support autoprobe
+    This module supports multiple cards. This module does not support autoprobe
     thus the main port must be specified!!! Other options are optional.
     thus the main port must be specified!!! Other options are optional.
 
 
   Module snd-trident
   Module snd-trident
@@ -1278,7 +1334,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     pcm_channels   - max channels (voices) reserved for PCM
     pcm_channels   - max channels (voices) reserved for PCM
     wavetable_size - max wavetable size in kB (4-?kb)
     wavetable_size - max wavetable size in kB (4-?kb)
 
 
-    Module supports up to 8 cards and autoprobe.
+    This module supports multiple cards and autoprobe.
 
 
     The power-management is supported.
     The power-management is supported.
 
 
@@ -1290,14 +1346,14 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     vid             - Vendor ID for the device (optional)
     vid             - Vendor ID for the device (optional)
     pid             - Product ID for the device (optional)
     pid             - Product ID for the device (optional)
 
 
-    This module supports up to 8 cards, autoprobe and hotplugging.
+    This module supports multiple devices, autoprobe and hotplugging.
 
 
   Module snd-usb-usx2y
   Module snd-usb-usx2y
   --------------------
   --------------------
 
 
     Module for Tascam USB US-122, US-224 and US-428 devices.
     Module for Tascam USB US-122, US-224 and US-428 devices.
 
 
-    This module supports up to 8 cards, autoprobe and hotplugging.
+    This module supports multiple devices, autoprobe and hotplugging.
 
 
     Note: you need to load the firmware via usx2yloader utility included
     Note: you need to load the firmware via usx2yloader utility included
           in alsa-tools and alsa-firmware packages.
           in alsa-tools and alsa-firmware packages.
@@ -1356,6 +1412,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     Note: for the MPU401 on VIA823x, use snd-mpu401 driver
     Note: for the MPU401 on VIA823x, use snd-mpu401 driver
 	  additionally.  The mpu_port option is for VIA686 chips only.
 	  additionally.  The mpu_port option is for VIA686 chips only.
 
 
+    The power-management is supported.
+
   Module snd-via82xx-modem
   Module snd-via82xx-modem
   ------------------------
   ------------------------
 
 
@@ -1368,6 +1426,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     Note: The default index value of this module is -2, i.e. the first
     Note: The default index value of this module is -2, i.e. the first
           slot is excluded.
           slot is excluded.
 
 
+    The power-management is supported.
+
   Module snd-virmidi
   Module snd-virmidi
   ------------------
   ------------------
 
 
@@ -1375,9 +1435,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     This module creates virtual rawmidi devices which communicate
     This module creates virtual rawmidi devices which communicate
     to the corresponding ALSA sequencer ports.
     to the corresponding ALSA sequencer ports.
 
 
-    midi_devs	- MIDI devices # (1-8, default=4)
+    midi_devs	- MIDI devices # (1-4, default=4)
     
     
-    Module supports up to 8 cards.
+    This module supports multiple cards.
 
 
   Module snd-vx222
   Module snd-vx222
   ----------------
   ----------------
@@ -1387,7 +1447,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     mic		- Enable Microphone on V222 Mic (NYI)
     mic		- Enable Microphone on V222 Mic (NYI)
     ibl		- Capture IBL size. (default = 0, minimum size)
     ibl		- Capture IBL size. (default = 0, minimum size)
 
 
-    Module supports up to 8 cards.
+    This module supports multiple cards.
 
 
     When the driver is compiled as a module and the hotplug firmware
     When the driver is compiled as a module and the hotplug firmware
     is supported, the firmware data is loaded via hotplug automatically.
     is supported, the firmware data is loaded via hotplug automatically.
@@ -1406,6 +1466,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     size is chosen.  The possible IBL values can be found in
     size is chosen.  The possible IBL values can be found in
     /proc/asound/cardX/vx-status proc file.
     /proc/asound/cardX/vx-status proc file.
 
 
+    The power-management is supported.
+
   Module snd-vxpocket
   Module snd-vxpocket
   -------------------
   -------------------
 
 
@@ -1413,7 +1475,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
 
 
     ibl      - Capture IBL size. (default = 0, minimum size)
     ibl      - Capture IBL size. (default = 0, minimum size)
 
 
-    Module supports up to 8 cards.  The module is compiled only when
+    This module supports multiple cards.  The module is compiled only when
     PCMCIA is supported on kernel.
     PCMCIA is supported on kernel.
 
 
     With the older 2.6.x kernel, to activate the driver via the card
     With the older 2.6.x kernel, to activate the driver via the card
@@ -1434,6 +1496,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     Note2: snd-vxp440 driver is merged to snd-vxpocket driver since
     Note2: snd-vxp440 driver is merged to snd-vxpocket driver since
            ALSA 1.0.10.
            ALSA 1.0.10.
 
 
+    The power-management is supported.
+
   Module snd-ymfpci
   Module snd-ymfpci
   -----------------
   -----------------
 
 
@@ -1447,7 +1511,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
                     1 (auto-detect)
                     1 (auto-detect)
     rear_switch   - enable shared rear/line-in switch (bool)
     rear_switch   - enable shared rear/line-in switch (bool)
 
 
-    Module supports autoprobe and multiple chips (max 8).
+    This module supports autoprobe and multiple chips.
 
 
     The power-management is supported.
     The power-management is supported.
 
 
@@ -1458,6 +1522,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
 
 
     Note: the driver is build only when CONFIG_ISA is set.
     Note: the driver is build only when CONFIG_ISA is set.
 
 
+    The power-management is supported.
+
 
 
 AC97 Quirk Option
 AC97 Quirk Option
 =================
 =================
@@ -1474,7 +1540,7 @@ the proper value with this option.
 
 
 The following strings are accepted:
 The following strings are accepted:
     - default	Don't override the default setting
     - default	Don't override the default setting
-    - disable	Disable the quirk
+    - none	Disable the quirk
     - hp_only	Bind Master and Headphone controls as a single control
     - hp_only	Bind Master and Headphone controls as a single control
     - swap_hp	Swap headphone and master controls
     - swap_hp	Swap headphone and master controls
     - swap_surround  Swap master and surround controls
     - swap_surround  Swap master and surround controls

文件差異過大導致無法顯示
+ 165 - 164
Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl


+ 16 - 0
Documentation/sound/alsa/Procfile.txt

@@ -138,6 +138,22 @@ card*/codec97#0/ac97#?-?+regs
 	# echo 02 9f1f > /proc/asound/card0/codec97#0/ac97#0-0+regs
 	# echo 02 9f1f > /proc/asound/card0/codec97#0/ac97#0-0+regs
 
 
 
 
+USB Audio Streams
+-----------------
+
+card*/stream*
+	Shows the assignment and the current status of each audio stream
+	of the given card.  This information is very useful for debugging.
+
+
+HD-Audio Codecs
+---------------
+
+card*/codec#*
+	Shows the general codec information and the attribute of each
+	widget node.
+
+
 Sequencer Information
 Sequencer Information
 ---------------------
 ---------------------
 
 

+ 7 - 7
Documentation/sound/alsa/hda_codec.txt

@@ -63,7 +63,7 @@ The bus instance is created via snd_hda_bus_new().  You need to pass
 the card instance, the template, and the pointer to store the
 the card instance, the template, and the pointer to store the
 resultant bus instance.
 resultant bus instance.
 
 
-int snd_hda_bus_new(snd_card_t *card, const struct hda_bus_template *temp,
+int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp,
 		    struct hda_bus **busp);
 		    struct hda_bus **busp);
 
 
 It returns zero if successful.  A negative return value means any
 It returns zero if successful.  A negative return value means any
@@ -166,14 +166,14 @@ The ops field contains the following callback functions:
 
 
 struct hda_pcm_ops {
 struct hda_pcm_ops {
 	int (*open)(struct hda_pcm_stream *info, struct hda_codec *codec,
 	int (*open)(struct hda_pcm_stream *info, struct hda_codec *codec,
-		    snd_pcm_substream_t *substream);
+		    struct snd_pcm_substream *substream);
 	int (*close)(struct hda_pcm_stream *info, struct hda_codec *codec,
 	int (*close)(struct hda_pcm_stream *info, struct hda_codec *codec,
-		     snd_pcm_substream_t *substream);
+		     struct snd_pcm_substream *substream);
 	int (*prepare)(struct hda_pcm_stream *info, struct hda_codec *codec,
 	int (*prepare)(struct hda_pcm_stream *info, struct hda_codec *codec,
 		       unsigned int stream_tag, unsigned int format,
 		       unsigned int stream_tag, unsigned int format,
-		       snd_pcm_substream_t *substream);
+		       struct snd_pcm_substream *substream);
 	int (*cleanup)(struct hda_pcm_stream *info, struct hda_codec *codec,
 	int (*cleanup)(struct hda_pcm_stream *info, struct hda_codec *codec,
-		       snd_pcm_substream_t *substream);
+		       struct snd_pcm_substream *substream);
 };
 };
 
 
 All are non-NULL, so you can call them safely without NULL check.
 All are non-NULL, so you can call them safely without NULL check.
@@ -284,7 +284,7 @@ parameter, and PCI subsystem IDs.  If the matching entry is found, it
 returns the config field value.
 returns the config field value.
 
 
 snd_hda_add_new_ctls() can be used to create and add control entries.
 snd_hda_add_new_ctls() can be used to create and add control entries.
-Pass the zero-terminated array of snd_kcontrol_new_t.  The same array
+Pass the zero-terminated array of struct snd_kcontrol_new.  The same array
 can be passed to snd_hda_resume_ctls() for resume.
 can be passed to snd_hda_resume_ctls() for resume.
 Note that this will call control->put callback of these entries.  So,
 Note that this will call control->put callback of these entries.  So,
 put callback should check codec->in_resume and force to restore the
 put callback should check codec->in_resume and force to restore the
@@ -292,7 +292,7 @@ given value if it's non-zero even if the value is identical with the
 cached value.
 cached value.
 
 
 Macros HDA_CODEC_VOLUME(), HDA_CODEC_MUTE() and their variables can be
 Macros HDA_CODEC_VOLUME(), HDA_CODEC_MUTE() and their variables can be
-used for the entry of snd_kcontrol_new_t.
+used for the entry of struct snd_kcontrol_new.
 
 
 The input MUX helper callbacks for such a control are provided, too:
 The input MUX helper callbacks for such a control are provided, too:
 snd_hda_input_mux_info() and snd_hda_input_mux_put().  See
 snd_hda_input_mux_info() and snd_hda_input_mux_put().  See

+ 1 - 5
Documentation/sysrq.txt

@@ -202,17 +202,13 @@ you must call __handle_sysrq_nolock instead.
 
 
 *  I have more questions, who can I ask?
 *  I have more questions, who can I ask?
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-You may feel free to send email to myrdraal@deathsdoor.com, and I will
-respond as soon as possible.
- -Myrdraal
-
 And I'll answer any questions about the registration system you got, also
 And I'll answer any questions about the registration system you got, also
 responding as soon as possible.
 responding as soon as possible.
  -Crutcher
  -Crutcher
 
 
 *  Credits
 *  Credits
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Written by Mydraal <myrdraal@deathsdoor.com>
+Written by Mydraal <vulpyne@vulpyne.net>
 Updated by Adam Sulmicki <adam@cfar.umd.edu>
 Updated by Adam Sulmicki <adam@cfar.umd.edu>
 Updated by Jeremy M. Dolan <jmd@turbogeek.org> 2001/01/28 10:15:59
 Updated by Jeremy M. Dolan <jmd@turbogeek.org> 2001/01/28 10:15:59
 Added to by Crutcher Dunnavant <crutcher+kernel@datastacks.com>
 Added to by Crutcher Dunnavant <crutcher+kernel@datastacks.com>

+ 43 - 20
MAINTAINERS

@@ -258,6 +258,13 @@ P:	Ivan Kokshaysky
 M:	ink@jurassic.park.msu.ru
 M:	ink@jurassic.park.msu.ru
 S:	Maintained for 2.4; PCI support for 2.6.
 S:	Maintained for 2.4; PCI support for 2.6.
 
 
+AMD GEODE PROCESSOR/CHIPSET SUPPORT
+P:      Jordan Crouse
+M:      info-linux@geode.amd.com
+L:	info-linux@geode.amd.com
+W:	http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html
+S:	Supported
+
 APM DRIVER
 APM DRIVER
 P:	Stephen Rothwell
 P:	Stephen Rothwell
 M:	sfr@canb.auug.org.au
 M:	sfr@canb.auug.org.au
@@ -554,6 +561,11 @@ W:	http://us1.samba.org/samba/Linux_CIFS_client.html
 T:	git kernel.org:/pub/scm/linux/kernel/git/sfrench/cifs-2.6.git
 T:	git kernel.org:/pub/scm/linux/kernel/git/sfrench/cifs-2.6.git
 S:	Supported	
 S:	Supported	
 
 
+CONFIGFS
+P:	Joel Becker
+M:	Joel Becker <joel.becker@oracle.com>
+S:	Supported
+
 CIRRUS LOGIC GENERIC FBDEV DRIVER
 CIRRUS LOGIC GENERIC FBDEV DRIVER
 P:	Jeff Garzik
 P:	Jeff Garzik
 M:	jgarzik@pobox.com
 M:	jgarzik@pobox.com
@@ -650,6 +662,11 @@ L:	linux-crypto@vger.kernel.org
 T:	git kernel.org:/pub/scm/linux/kernel/git/herbert/crypto-2.6.git
 T:	git kernel.org:/pub/scm/linux/kernel/git/herbert/crypto-2.6.git
 S:	Maintained
 S:	Maintained
 
 
+CS5535 Audio ALSA driver
+P:	Jaya Kumar
+M:	jayakumar.alsa@gmail.com
+S:	Maintained
+
 CYBERPRO FB DRIVER
 CYBERPRO FB DRIVER
 P:	Russell King
 P:	Russell King
 M:	rmk@arm.linux.org.uk
 M:	rmk@arm.linux.org.uk
@@ -679,13 +696,6 @@ M:	pc300@cyclades.com
 W:	http://www.cyclades.com/
 W:	http://www.cyclades.com/
 S:	Supported
 S:	Supported
 
 
-DAC960 RAID CONTROLLER DRIVER
-P:	Dave Olien
-M	dmo@osdl.org
-W:	http://www.osdl.org/archive/dmo/DAC960
-L:	linux-kernel@vger.kernel.org
-S:	Maintained
-
 DAMA SLAVE for AX.25
 DAMA SLAVE for AX.25
 P:	Joerg Reuter
 P:	Joerg Reuter
 M:	jreuter@yaina.de
 M:	jreuter@yaina.de
@@ -1225,7 +1235,7 @@ IEEE 1394 SUBSYSTEM
 P:	Ben Collins
 P:	Ben Collins
 M:	bcollins@debian.org
 M:	bcollins@debian.org
 P:	Jody McIntyre
 P:	Jody McIntyre
-M:	scjody@steamballoon.com
+M:	scjody@modernduck.com
 L:	linux1394-devel@lists.sourceforge.net
 L:	linux1394-devel@lists.sourceforge.net
 W:	http://www.linux1394.org/
 W:	http://www.linux1394.org/
 T:	git kernel.org:/pub/scm/linux/kernel/git/scjody/ieee1394.git
 T:	git kernel.org:/pub/scm/linux/kernel/git/scjody/ieee1394.git
@@ -1235,14 +1245,14 @@ IEEE 1394 OHCI DRIVER
 P:	Ben Collins
 P:	Ben Collins
 M:	bcollins@debian.org
 M:	bcollins@debian.org
 P:	Jody McIntyre
 P:	Jody McIntyre
-M:	scjody@steamballoon.com
+M:	scjody@modernduck.com
 L:	linux1394-devel@lists.sourceforge.net
 L:	linux1394-devel@lists.sourceforge.net
 W:	http://www.linux1394.org/
 W:	http://www.linux1394.org/
 S:	Maintained
 S:	Maintained
 
 
 IEEE 1394 PCILYNX DRIVER
 IEEE 1394 PCILYNX DRIVER
 P:	Jody McIntyre
 P:	Jody McIntyre
-M:	scjody@steamballoon.com
+M:	scjody@modernduck.com
 L:	linux1394-devel@lists.sourceforge.net
 L:	linux1394-devel@lists.sourceforge.net
 W:	http://www.linux1394.org/
 W:	http://www.linux1394.org/
 S:	Maintained
 S:	Maintained
@@ -1465,7 +1475,6 @@ P:	Several
 L:	kernel-janitors@osdl.org
 L:	kernel-janitors@osdl.org
 W:	http://www.kerneljanitors.org/
 W:	http://www.kerneljanitors.org/
 W:	http://sf.net/projects/kernel-janitor/
 W:	http://sf.net/projects/kernel-janitor/
-W:	http://developer.osdl.org/rddunlap/kj-patches/
 S:	Maintained
 S:	Maintained
 
 
 KERNEL NFSD
 KERNEL NFSD
@@ -1476,17 +1485,11 @@ W:	http://nfs.sourceforge.net/
 W:	http://www.cse.unsw.edu.au/~neilb/patches/linux-devel/
 W:	http://www.cse.unsw.edu.au/~neilb/patches/linux-devel/
 S:	Maintained
 S:	Maintained
 
 
-KERNEL EVENT LAYER (KOBJECT_UEVENT)
-P:	Robert Love
-M:	rml@novell.com
-L:	linux-kernel@vger.kernel.org
-S:	Maintained
-
 KEXEC
 KEXEC
 P:	Eric Biederman
 P:	Eric Biederman
 P:	Randy Dunlap
 P:	Randy Dunlap
 M:	ebiederm@xmission.com
 M:	ebiederm@xmission.com
-M:	rddunlap@osdl.org
+M:	rdunlap@xenotime.net
 W:	http://www.xmission.com/~ebiederm/files/kexec/
 W:	http://www.xmission.com/~ebiederm/files/kexec/
 L:	linux-kernel@vger.kernel.org
 L:	linux-kernel@vger.kernel.org
 L:	fastboot@osdl.org
 L:	fastboot@osdl.org
@@ -1900,6 +1903,15 @@ M:	ajoshi@shell.unixbox.com
 L:	linux-nvidia@lists.surfsouth.com
 L:	linux-nvidia@lists.surfsouth.com
 S:	Maintained
 S:	Maintained
 
 
+ORACLE CLUSTER FILESYSTEM 2 (OCFS2)
+P:	Mark Fasheh
+M:	mark.fasheh@oracle.com
+P:	Kurt Hackel
+M:	kurt.hackel@oracle.com
+L:	ocfs2-devel@oss.oracle.com
+W:	http://oss.oracle.com/projects/ocfs2/
+S:	Supported	
+
 OLYMPIC NETWORK DRIVER
 OLYMPIC NETWORK DRIVER
 P:	Peter De Shrijver
 P:	Peter De Shrijver
 M:	p2@ace.ulyssis.student.kuleuven.ac.be
 M:	p2@ace.ulyssis.student.kuleuven.ac.be
@@ -2587,7 +2599,6 @@ S:	Maintained
 UDF FILESYSTEM
 UDF FILESYSTEM
 P:	Ben Fennema
 P:	Ben Fennema
 M:	bfennema@falcon.csc.calpoly.edu
 M:	bfennema@falcon.csc.calpoly.edu
-L:	linux_udf@hpesjro.fc.hp.com
 W:	http://linux-udf.sourceforge.net
 W:	http://linux-udf.sourceforge.net
 S:	Maintained
 S:	Maintained
 
 
@@ -2640,6 +2651,12 @@ L:	linux-usb-users@lists.sourceforge.net
 L:	linux-usb-devel@lists.sourceforge.net
 L:	linux-usb-devel@lists.sourceforge.net
 S:	Maintained
 S:	Maintained
 
 
+USB ISP116X DRIVER
+P:	Olav Kongas
+M:	ok@artecdesign.ee
+L:	linux-usb-devel@lists.sourceforge.net
+S:	Maintained
+
 USB KAWASAKI LSI DRIVER
 USB KAWASAKI LSI DRIVER
 P:	Oliver Neukum
 P:	Oliver Neukum
 M:	oliver@neukum.name
 M:	oliver@neukum.name
@@ -2651,7 +2668,7 @@ USB MASS STORAGE DRIVER
 P:	Matthew Dharm
 P:	Matthew Dharm
 M:	mdharm-usb@one-eyed-alien.net
 M:	mdharm-usb@one-eyed-alien.net
 L:	linux-usb-users@lists.sourceforge.net
 L:	linux-usb-users@lists.sourceforge.net
-L:	linux-usb-devel@lists.sourceforge.net
+L:	usb-storage@lists.one-eyed-alien.net
 S:	Maintained
 S:	Maintained
 W:	http://www.one-eyed-alien.net/~mdharm/linux-usb/
 W:	http://www.one-eyed-alien.net/~mdharm/linux-usb/
 
 
@@ -2899,6 +2916,12 @@ W:	http://linuxtv.org
 T:	git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git
 T:	git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git
 S:	Maintained
 S:	Maintained
 
 
+VT8231 HARDWARE MONITOR DRIVER
+P:	Roger Lucas
+M:	roger@planbit.co.uk
+L:	lm-sensors@lm-sensors.org
+S:	Maintained
+
 W1 DALLAS'S 1-WIRE BUS
 W1 DALLAS'S 1-WIRE BUS
 P:	Evgeniy Polyakov
 P:	Evgeniy Polyakov
 M:	johnpol@2ka.mipt.ru
 M:	johnpol@2ka.mipt.ru

+ 17 - 13
Makefile

@@ -286,10 +286,6 @@ export quiet Q KBUILD_VERBOSE
 cc-option = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \
 cc-option = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \
              > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;)
              > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;)
 
 
-# For backward compatibility
-check_gcc = $(warning check_gcc is deprecated - use cc-option) \
-            $(call cc-option, $(1),$(2))
-
 # cc-option-yn
 # cc-option-yn
 # Usage: flag := $(call cc-option-yn, -march=winchip-c6)
 # Usage: flag := $(call cc-option-yn, -march=winchip-c6)
 cc-option-yn = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \
 cc-option-yn = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \
@@ -481,18 +477,20 @@ ifeq ($(dot-config),1)
 
 
 # Read in dependencies to all Kconfig* files, make sure to run
 # Read in dependencies to all Kconfig* files, make sure to run
 # oldconfig if changes are detected.
 # oldconfig if changes are detected.
--include .config.cmd
+-include .kconfig.d
 
 
 include .config
 include .config
 
 
 # If .config needs to be updated, it will be done via the dependency
 # If .config needs to be updated, it will be done via the dependency
 # that autoconf has on .config.
 # that autoconf has on .config.
 # To avoid any implicit rule to kick in, define an empty command
 # To avoid any implicit rule to kick in, define an empty command
-.config: ;
+.config .kconfig.d: ;
 
 
 # If .config is newer than include/linux/autoconf.h, someone tinkered
 # If .config is newer than include/linux/autoconf.h, someone tinkered
-# with it and forgot to run make oldconfig
-include/linux/autoconf.h: .config
+# with it and forgot to run make oldconfig.
+# If kconfig.d is missing then we are probarly in a cleaned tree so
+# we execute the config step to be sure to catch updated Kconfig files
+include/linux/autoconf.h: .kconfig.d .config
 	$(Q)mkdir -p include/linux
 	$(Q)mkdir -p include/linux
 	$(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
 	$(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
 else
 else
@@ -1066,7 +1064,7 @@ help:
 	@echo  '  all		  - Build all targets marked with [*]'
 	@echo  '  all		  - Build all targets marked with [*]'
 	@echo  '* vmlinux	  - Build the bare kernel'
 	@echo  '* vmlinux	  - Build the bare kernel'
 	@echo  '* modules	  - Build all modules'
 	@echo  '* modules	  - Build all modules'
-	@echo  '  modules_install - Install all modules'
+	@echo  '  modules_install - Install all modules to INSTALL_MOD_PATH (default: /)'
 	@echo  '  dir/            - Build all files in dir and below'
 	@echo  '  dir/            - Build all files in dir and below'
 	@echo  '  dir/file.[ois]  - Build specified target only'
 	@echo  '  dir/file.[ois]  - Build specified target only'
 	@echo  '  dir/file.ko     - Build module including final link'
 	@echo  '  dir/file.ko     - Build module including final link'
@@ -1240,8 +1238,11 @@ cscope: FORCE
 quiet_cmd_TAGS = MAKE   $@
 quiet_cmd_TAGS = MAKE   $@
 define cmd_TAGS
 define cmd_TAGS
 	rm -f $@; \
 	rm -f $@; \
-	ETAGSF=`etags --version | grep -i exuberant >/dev/null && echo "-I __initdata,__exitdata,EXPORT_SYMBOL,EXPORT_SYMBOL_GPL --extra=+f"`; \
-	$(all-sources) | xargs etags $$ETAGSF -a
+	ETAGSF=`etags --version | grep -i exuberant >/dev/null &&     \
+                echo "-I __initdata,__exitdata,__acquires,__releases  \
+                      -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL              \
+                      --extra=+f --c-kinds=+px"`;                     \
+                $(all-sources) | xargs etags $$ETAGSF -a
 endef
 endef
 
 
 TAGS: FORCE
 TAGS: FORCE
@@ -1251,8 +1252,11 @@ TAGS: FORCE
 quiet_cmd_tags = MAKE   $@
 quiet_cmd_tags = MAKE   $@
 define cmd_tags
 define cmd_tags
 	rm -f $@; \
 	rm -f $@; \
-	CTAGSF=`ctags --version | grep -i exuberant >/dev/null && echo "-I __initdata,__exitdata,EXPORT_SYMBOL,EXPORT_SYMBOL_GPL --extra=+f"`; \
-	$(all-sources) | xargs ctags $$CTAGSF -a
+	CTAGSF=`ctags --version | grep -i exuberant >/dev/null &&     \
+                echo "-I __initdata,__exitdata,__acquires,__releases  \
+                      -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL              \
+                      --extra=+f --c-kinds=+px"`;                     \
+                $(all-sources) | xargs ctags $$CTAGSF -a
 endef
 endef
 
 
 tags: FORCE
 tags: FORCE

+ 13 - 0
arch/alpha/Kconfig

@@ -40,6 +40,19 @@ config GENERIC_IOMAP
 	bool
 	bool
 	default n
 	default n
 
 
+config GENERIC_HARDIRQS
+	bool
+	default y
+
+config GENERIC_IRQ_PROBE
+	bool
+	default y
+
+config AUTO_IRQ_AFFINITY
+	bool
+	depends on SMP
+	default y
+
 source "init/Kconfig"
 source "init/Kconfig"
 
 
 
 

+ 0 - 1
arch/alpha/kernel/alpha_ksyms.c

@@ -175,7 +175,6 @@ EXPORT_SYMBOL(up);
  */
  */
 
 
 #ifdef CONFIG_SMP
 #ifdef CONFIG_SMP
-EXPORT_SYMBOL(synchronize_irq);
 EXPORT_SYMBOL(flush_tlb_mm);
 EXPORT_SYMBOL(flush_tlb_mm);
 EXPORT_SYMBOL(flush_tlb_range);
 EXPORT_SYMBOL(flush_tlb_range);
 EXPORT_SYMBOL(flush_tlb_page);
 EXPORT_SYMBOL(flush_tlb_page);

+ 9 - 621
arch/alpha/kernel/irq.c

@@ -32,214 +32,25 @@
 #include <asm/io.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/uaccess.h>
 
 
-/*
- * Controller mappings for all interrupt sources:
- */
-irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = {
-	[0 ... NR_IRQS-1] = {
-		.handler = &no_irq_type,
-		.lock = SPIN_LOCK_UNLOCKED
-	}
-};
-
-static void register_irq_proc(unsigned int irq);
-
 volatile unsigned long irq_err_count;
 volatile unsigned long irq_err_count;
 
 
-/*
- * Special irq handlers.
- */
-
-irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs)
-{
-	return IRQ_NONE;
-}
-
-/*
- * Generic no controller code
- */
-
-static void no_irq_enable_disable(unsigned int irq) { }
-static unsigned int no_irq_startup(unsigned int irq) { return 0; }
-
-static void
-no_irq_ack(unsigned int irq)
+void ack_bad_irq(unsigned int irq)
 {
 {
 	irq_err_count++;
 	irq_err_count++;
 	printk(KERN_CRIT "Unexpected IRQ trap at vector %u\n", irq);
 	printk(KERN_CRIT "Unexpected IRQ trap at vector %u\n", irq);
 }
 }
 
 
-struct hw_interrupt_type no_irq_type = {
-	.typename	= "none",
-	.startup	= no_irq_startup,
-	.shutdown	= no_irq_enable_disable,
-	.enable		= no_irq_enable_disable,
-	.disable	= no_irq_enable_disable,
-	.ack		= no_irq_ack,
-	.end		= no_irq_enable_disable,
-};
-
-int
-handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
-		 struct irqaction *action)
-{
-	int status = 1;	/* Force the "do bottom halves" bit */
-	int ret;
-
-	do {
-		if (!(action->flags & SA_INTERRUPT))
-			local_irq_enable();
-		else
-			local_irq_disable();
-
-		ret = action->handler(irq, action->dev_id, regs);
-		if (ret == IRQ_HANDLED)
-			status |= action->flags;
-		action = action->next;
-	} while (action);
-	if (status & SA_SAMPLE_RANDOM)
-		add_interrupt_randomness(irq);
-	local_irq_disable();
-
-	return status;
-}
-
-/*
- * Generic enable/disable code: this just calls
- * down into the PIC-specific version for the actual
- * hardware disable after having gotten the irq
- * controller lock. 
- */
-void inline
-disable_irq_nosync(unsigned int irq)
-{
-	irq_desc_t *desc = irq_desc + irq;
-	unsigned long flags;
-
-	spin_lock_irqsave(&desc->lock, flags);
-	if (!desc->depth++) {
-		desc->status |= IRQ_DISABLED;
-		desc->handler->disable(irq);
-	}
-	spin_unlock_irqrestore(&desc->lock, flags);
-}
-
-/*
- * Synchronous version of the above, making sure the IRQ is
- * no longer running on any other IRQ..
- */
-void
-disable_irq(unsigned int irq)
-{
-	disable_irq_nosync(irq);
-	synchronize_irq(irq);
-}
-
-void
-enable_irq(unsigned int irq)
-{
-	irq_desc_t *desc = irq_desc + irq;
-	unsigned long flags;
-
-	spin_lock_irqsave(&desc->lock, flags);
-	switch (desc->depth) {
-	case 1: {
-		unsigned int status = desc->status & ~IRQ_DISABLED;
-		desc->status = status;
-		if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
-			desc->status = status | IRQ_REPLAY;
-			hw_resend_irq(desc->handler,irq);
-		}
-		desc->handler->enable(irq);
-		/* fall-through */
-	}
-	default:
-		desc->depth--;
-		break;
-	case 0:
-		printk(KERN_ERR "enable_irq() unbalanced from %p\n",
-		       __builtin_return_address(0));
-	}
-	spin_unlock_irqrestore(&desc->lock, flags);
-}
-
-int
-setup_irq(unsigned int irq, struct irqaction * new)
-{
-	int shared = 0;
-	struct irqaction *old, **p;
-	unsigned long flags;
-	irq_desc_t *desc = irq_desc + irq;
-
-        if (desc->handler == &no_irq_type)
-		return -ENOSYS;
-
-	/*
-	 * Some drivers like serial.c use request_irq() heavily,
-	 * so we have to be careful not to interfere with a
-	 * running system.
-	 */
-	if (new->flags & SA_SAMPLE_RANDOM) {
-		/*
-		 * This function might sleep, we want to call it first,
-		 * outside of the atomic block.
-		 * Yes, this might clear the entropy pool if the wrong
-		 * driver is attempted to be loaded, without actually
-		 * installing a new handler, but is this really a problem,
-		 * only the sysadmin is able to do this.
-		 */
-		rand_initialize_irq(irq);
-	}
-
-	/*
-	 * The following block of code has to be executed atomically
-	 */
-	spin_lock_irqsave(&desc->lock,flags);
-	p = &desc->action;
-	if ((old = *p) != NULL) {
-		/* Can't share interrupts unless both agree to */
-		if (!(old->flags & new->flags & SA_SHIRQ)) {
-			spin_unlock_irqrestore(&desc->lock,flags);
-			return -EBUSY;
-		}
-
-		/* add new interrupt at end of irq queue */
-		do {
-			p = &old->next;
-			old = *p;
-		} while (old);
-		shared = 1;
-	}
-
-	*p = new;
-
-	if (!shared) {
-		desc->depth = 0;
-		desc->status &=
-		    ~(IRQ_DISABLED|IRQ_AUTODETECT|IRQ_WAITING|IRQ_INPROGRESS);
-		desc->handler->startup(irq);
-	}
-	spin_unlock_irqrestore(&desc->lock,flags);
-
-	return 0;
-}
-
-static struct proc_dir_entry * root_irq_dir;
-static struct proc_dir_entry * irq_dir[NR_IRQS];
-
 #ifdef CONFIG_SMP 
 #ifdef CONFIG_SMP 
-static struct proc_dir_entry * smp_affinity_entry[NR_IRQS];
 static char irq_user_affinity[NR_IRQS];
 static char irq_user_affinity[NR_IRQS];
-static cpumask_t irq_affinity[NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL };
 
 
-static void
-select_smp_affinity(int irq)
+int
+select_smp_affinity(unsigned int irq)
 {
 {
 	static int last_cpu;
 	static int last_cpu;
 	int cpu = last_cpu + 1;
 	int cpu = last_cpu + 1;
 
 
-	if (! irq_desc[irq].handler->set_affinity || irq_user_affinity[irq])
-		return;
+	if (!irq_desc[irq].handler->set_affinity || irq_user_affinity[irq])
+		return 1;
 
 
 	while (!cpu_possible(cpu))
 	while (!cpu_possible(cpu))
 		cpu = (cpu < (NR_CPUS-1) ? cpu + 1 : 0);
 		cpu = (cpu < (NR_CPUS-1) ? cpu + 1 : 0);
@@ -247,208 +58,10 @@ select_smp_affinity(int irq)
 
 
 	irq_affinity[irq] = cpumask_of_cpu(cpu);
 	irq_affinity[irq] = cpumask_of_cpu(cpu);
 	irq_desc[irq].handler->set_affinity(irq, cpumask_of_cpu(cpu));
 	irq_desc[irq].handler->set_affinity(irq, cpumask_of_cpu(cpu));
+	return 0;
 }
 }
-
-static int
-irq_affinity_read_proc (char *page, char **start, off_t off,
-			int count, int *eof, void *data)
-{
-	int len = cpumask_scnprintf(page, count, irq_affinity[(long)data]);
-	if (count - len < 2)
-		return -EINVAL;
-	len += sprintf(page + len, "\n");
-	return len;
-}
-
-static int
-irq_affinity_write_proc(struct file *file, const char __user *buffer,
-			unsigned long count, void *data)
-{
-	int irq = (long) data, full_count = count, err;
-	cpumask_t new_value;
-
-	if (!irq_desc[irq].handler->set_affinity)
-		return -EIO;
-
-	err = cpumask_parse(buffer, count, new_value);
-
-	/* The special value 0 means release control of the
-	   affinity to kernel.  */
-	cpus_and(new_value, new_value, cpu_online_map);
-	if (cpus_empty(new_value)) {
-		irq_user_affinity[irq] = 0;
-		select_smp_affinity(irq);
-	}
-	/* Do not allow disabling IRQs completely - it's a too easy
-	   way to make the system unusable accidentally :-) At least
-	   one online CPU still has to be targeted.  */
-	else {
-		irq_affinity[irq] = new_value;
-		irq_user_affinity[irq] = 1;
-		irq_desc[irq].handler->set_affinity(irq, new_value);
-	}
-
-	return full_count;
-}
-
 #endif /* CONFIG_SMP */
 #endif /* CONFIG_SMP */
 
 
-#define MAX_NAMELEN 10
-
-static void
-register_irq_proc (unsigned int irq)
-{
-	char name [MAX_NAMELEN];
-
-	if (!root_irq_dir || (irq_desc[irq].handler == &no_irq_type) ||
-	    irq_dir[irq])
-		return;
-
-	memset(name, 0, MAX_NAMELEN);
-	sprintf(name, "%d", irq);
-
-	/* create /proc/irq/1234 */
-	irq_dir[irq] = proc_mkdir(name, root_irq_dir);
-
-#ifdef CONFIG_SMP 
-	if (irq_desc[irq].handler->set_affinity) {
-		struct proc_dir_entry *entry;
-		/* create /proc/irq/1234/smp_affinity */
-		entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
-
-		if (entry) {
-			entry->nlink = 1;
-			entry->data = (void *)(long)irq;
-			entry->read_proc = irq_affinity_read_proc;
-			entry->write_proc = irq_affinity_write_proc;
-		}
-
-		smp_affinity_entry[irq] = entry;
-	}
-#endif
-}
-
-void
-init_irq_proc (void)
-{
-	int i;
-
-	/* create /proc/irq */
-	root_irq_dir = proc_mkdir("irq", NULL);
-
-#ifdef CONFIG_SMP 
-	/* create /proc/irq/prof_cpu_mask */
-	create_prof_cpu_mask(root_irq_dir);
-#endif
-
-	/*
-	 * Create entries for all existing IRQs.
-	 */
-	for (i = 0; i < ACTUAL_NR_IRQS; i++) {
-		if (irq_desc[i].handler == &no_irq_type)
-			continue;
-		register_irq_proc(i);
-	}
-}
-
-int
-request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *),
-	    unsigned long irqflags, const char * devname, void *dev_id)
-{
-	int retval;
-	struct irqaction * action;
-
-	if (irq >= ACTUAL_NR_IRQS)
-		return -EINVAL;
-	if (!handler)
-		return -EINVAL;
-
-#if 1
-	/*
-	 * Sanity-check: shared interrupts should REALLY pass in
-	 * a real dev-ID, otherwise we'll have trouble later trying
-	 * to figure out which interrupt is which (messes up the
-	 * interrupt freeing logic etc).
-	 */
-	if ((irqflags & SA_SHIRQ) && !dev_id) {
-		printk(KERN_ERR
-		       "Bad boy: %s (at %p) called us without a dev_id!\n",
-		       devname, __builtin_return_address(0));
-	}
-#endif
-
-	action = (struct irqaction *)
-			kmalloc(sizeof(struct irqaction), GFP_KERNEL);
-	if (!action)
-		return -ENOMEM;
-
-	action->handler = handler;
-	action->flags = irqflags;
-	cpus_clear(action->mask);
-	action->name = devname;
-	action->next = NULL;
-	action->dev_id = dev_id;
-
-#ifdef CONFIG_SMP
-	select_smp_affinity(irq);
-#endif
-
-	retval = setup_irq(irq, action);
-	if (retval)
-		kfree(action);
-	return retval;
-}
-
-EXPORT_SYMBOL(request_irq);
-
-void
-free_irq(unsigned int irq, void *dev_id)
-{
-	irq_desc_t *desc;
-	struct irqaction **p;
-	unsigned long flags;
-
-	if (irq >= ACTUAL_NR_IRQS) {
-		printk(KERN_CRIT "Trying to free IRQ%d\n", irq);
-		return;
-	}
-
-	desc = irq_desc + irq;
-	spin_lock_irqsave(&desc->lock,flags);
-	p = &desc->action;
-	for (;;) {
-		struct irqaction * action = *p;
-		if (action) {
-			struct irqaction **pp = p;
-			p = &action->next;
-			if (action->dev_id != dev_id)
-				continue;
-
-			/* Found - now remove it from the list of entries.  */
-			*pp = action->next;
-			if (!desc->action) {
-				desc->status |= IRQ_DISABLED;
-				desc->handler->shutdown(irq);
-			}
-			spin_unlock_irqrestore(&desc->lock,flags);
-
-#ifdef CONFIG_SMP
-			/* Wait to make sure it's not being used on
-			   another CPU.  */
-			while (desc->status & IRQ_INPROGRESS)
-				barrier();
-#endif
-			kfree(action);
-			return;
-		}
-		printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
-		spin_unlock_irqrestore(&desc->lock,flags);
-		return;
-	}
-}
-
-EXPORT_SYMBOL(free_irq);
-
 int
 int
 show_interrupts(struct seq_file *p, void *v)
 show_interrupts(struct seq_file *p, void *v)
 {
 {
@@ -531,10 +144,6 @@ handle_irq(int irq, struct pt_regs * regs)
 	 * 0 return value means that this irq is already being
 	 * 0 return value means that this irq is already being
 	 * handled by some other CPU. (or is disabled)
 	 * handled by some other CPU. (or is disabled)
 	 */
 	 */
-	int cpu = smp_processor_id();
-	irq_desc_t *desc = irq_desc + irq;
-	struct irqaction * action;
-	unsigned int status;
 	static unsigned int illegal_count=0;
 	static unsigned int illegal_count=0;
 	
 	
 	if ((unsigned) irq > ACTUAL_NR_IRQS && illegal_count < MAX_ILLEGAL_IRQS ) {
 	if ((unsigned) irq > ACTUAL_NR_IRQS && illegal_count < MAX_ILLEGAL_IRQS ) {
@@ -546,229 +155,8 @@ handle_irq(int irq, struct pt_regs * regs)
 	}
 	}
 
 
 	irq_enter();
 	irq_enter();
-	kstat_cpu(cpu).irqs[irq]++;
-	spin_lock_irq(&desc->lock); /* mask also the higher prio events */
-	desc->handler->ack(irq);
-	/*
-	 * REPLAY is when Linux resends an IRQ that was dropped earlier.
-	 * WAITING is used by probe to mark irqs that are being tested.
-	 */
-	status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
-	status |= IRQ_PENDING; /* we _want_ to handle it */
-
-	/*
-	 * If the IRQ is disabled for whatever reason, we cannot
-	 * use the action we have.
-	 */
-	action = NULL;
-	if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
-		action = desc->action;
-		status &= ~IRQ_PENDING; /* we commit to handling */
-		status |= IRQ_INPROGRESS; /* we are handling it */
-	}
-	desc->status = status;
-
-	/*
-	 * If there is no IRQ handler or it was disabled, exit early.
-	 * Since we set PENDING, if another processor is handling
-	 * a different instance of this same irq, the other processor
-	 * will take care of it.
-	 */
-	if (!action)
-		goto out;
-
-	/*
-	 * Edge triggered interrupts need to remember pending events.
-	 * This applies to any hw interrupts that allow a second
-	 * instance of the same irq to arrive while we are in handle_irq
-	 * or in the handler. But the code here only handles the _second_
-	 * instance of the irq, not the third or fourth. So it is mostly
-	 * useful for irq hardware that does not mask cleanly in an
-	 * SMP environment.
-	 */
-	for (;;) {
-		spin_unlock(&desc->lock);
-		handle_IRQ_event(irq, regs, action);
-		spin_lock(&desc->lock);
-		
-		if (!(desc->status & IRQ_PENDING)
-		    || (desc->status & IRQ_LEVEL))
-			break;
-		desc->status &= ~IRQ_PENDING;
-	}
-	desc->status &= ~IRQ_INPROGRESS;
-out:
-	/*
-	 * The ->end() handler has to deal with interrupts which got
-	 * disabled while the handler was running.
-	 */
-	desc->handler->end(irq);
-	spin_unlock(&desc->lock);
-
+	local_irq_disable();
+	__do_IRQ(irq, regs);
+	local_irq_enable();
 	irq_exit();
 	irq_exit();
 }
 }
-
-/*
- * IRQ autodetection code..
- *
- * This depends on the fact that any interrupt that
- * comes in on to an unassigned handler will get stuck
- * with "IRQ_WAITING" cleared and the interrupt
- * disabled.
- */
-unsigned long
-probe_irq_on(void)
-{
-	int i;
-	irq_desc_t *desc;
-	unsigned long delay;
-	unsigned long val;
-
-	/* Something may have generated an irq long ago and we want to
-	   flush such a longstanding irq before considering it as spurious. */
-	for (i = NR_IRQS-1; i >= 0; i--) {
-		desc = irq_desc + i;
-
-		spin_lock_irq(&desc->lock);
-		if (!irq_desc[i].action) 
-			irq_desc[i].handler->startup(i);
-		spin_unlock_irq(&desc->lock);
-	}
-
-	/* Wait for longstanding interrupts to trigger. */
-	for (delay = jiffies + HZ/50; time_after(delay, jiffies); )
-		/* about 20ms delay */ barrier();
-
-	/* enable any unassigned irqs (we must startup again here because
-	   if a longstanding irq happened in the previous stage, it may have
-	   masked itself) first, enable any unassigned irqs. */
-	for (i = NR_IRQS-1; i >= 0; i--) {
-		desc = irq_desc + i;
-
-		spin_lock_irq(&desc->lock);
-		if (!desc->action) {
-			desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
-			if (desc->handler->startup(i))
-				desc->status |= IRQ_PENDING;
-		}
-		spin_unlock_irq(&desc->lock);
-	}
-
-	/*
-	 * Wait for spurious interrupts to trigger
-	 */
-	for (delay = jiffies + HZ/10; time_after(delay, jiffies); )
-		/* about 100ms delay */ barrier();
-
-	/*
-	 * Now filter out any obviously spurious interrupts
-	 */
-	val = 0;
-	for (i=0; i<NR_IRQS; i++) {
-		irq_desc_t *desc = irq_desc + i;
-		unsigned int status;
-
-		spin_lock_irq(&desc->lock);
-		status = desc->status;
-
-		if (status & IRQ_AUTODETECT) {
-			/* It triggered already - consider it spurious. */
-			if (!(status & IRQ_WAITING)) {
-				desc->status = status & ~IRQ_AUTODETECT;
-				desc->handler->shutdown(i);
-			} else
-				if (i < 32)
-					val |= 1 << i;
-		}
-		spin_unlock_irq(&desc->lock);
-	}
-
-	return val;
-}
-
-EXPORT_SYMBOL(probe_irq_on);
-
-/*
- * Return a mask of triggered interrupts (this
- * can handle only legacy ISA interrupts).
- */
-unsigned int
-probe_irq_mask(unsigned long val)
-{
-	int i;
-	unsigned int mask;
-
-	mask = 0;
-	for (i = 0; i < NR_IRQS; i++) {
-		irq_desc_t *desc = irq_desc + i;
-		unsigned int status;
-
-		spin_lock_irq(&desc->lock);
-		status = desc->status;
-
-		if (status & IRQ_AUTODETECT) {
-			/* We only react to ISA interrupts */
-			if (!(status & IRQ_WAITING)) {
-				if (i < 16)
-					mask |= 1 << i;
-			}
-
-			desc->status = status & ~IRQ_AUTODETECT;
-			desc->handler->shutdown(i);
-		}
-		spin_unlock_irq(&desc->lock);
-	}
-
-	return mask & val;
-}
-
-/*
- * Get the result of the IRQ probe.. A negative result means that
- * we have several candidates (but we return the lowest-numbered
- * one).
- */
-
-int
-probe_irq_off(unsigned long val)
-{
-	int i, irq_found, nr_irqs;
-
-	nr_irqs = 0;
-	irq_found = 0;
-	for (i=0; i<NR_IRQS; i++) {
-		irq_desc_t *desc = irq_desc + i;
-		unsigned int status;
-
-		spin_lock_irq(&desc->lock);
-		status = desc->status;
-
-		if (status & IRQ_AUTODETECT) {
-			if (!(status & IRQ_WAITING)) {
-				if (!nr_irqs)
-					irq_found = i;
-				nr_irqs++;
-			}
-			desc->status = status & ~IRQ_AUTODETECT;
-			desc->handler->shutdown(i);
-		}
-		spin_unlock_irq(&desc->lock);
-	}
-
-	if (nr_irqs > 1)
-		irq_found = -irq_found;
-	return irq_found;
-}
-
-EXPORT_SYMBOL(probe_irq_off);
-
-#ifdef CONFIG_SMP
-void synchronize_irq(unsigned int irq)
-{
-        /* is there anything to synchronize with? */
-	if (!irq_desc[irq].action)
-		return;
-
-	while (irq_desc[irq].status & IRQ_INPROGRESS)
-		barrier();
-}
-#endif

+ 3 - 3
arch/arm/common/amba.c

@@ -45,7 +45,7 @@ static int amba_match(struct device *dev, struct device_driver *drv)
 }
 }
 
 
 #ifdef CONFIG_HOTPLUG
 #ifdef CONFIG_HOTPLUG
-static int amba_hotplug(struct device *dev, char **envp, int nr_env, char *buf, int bufsz)
+static int amba_uevent(struct device *dev, char **envp, int nr_env, char *buf, int bufsz)
 {
 {
 	struct amba_device *pcdev = to_amba_device(dev);
 	struct amba_device *pcdev = to_amba_device(dev);
 
 
@@ -58,7 +58,7 @@ static int amba_hotplug(struct device *dev, char **envp, int nr_env, char *buf,
 	return 0;
 	return 0;
 }
 }
 #else
 #else
-#define amba_hotplug NULL
+#define amba_uevent NULL
 #endif
 #endif
 
 
 static int amba_suspend(struct device *dev, pm_message_t state)
 static int amba_suspend(struct device *dev, pm_message_t state)
@@ -88,7 +88,7 @@ static int amba_resume(struct device *dev)
 static struct bus_type amba_bustype = {
 static struct bus_type amba_bustype = {
 	.name		= "amba",
 	.name		= "amba",
 	.match		= amba_match,
 	.match		= amba_match,
-	.hotplug	= amba_hotplug,
+	.uevent		= amba_uevent,
 	.suspend	= amba_suspend,
 	.suspend	= amba_suspend,
 	.resume		= amba_resume,
 	.resume		= amba_resume,
 };
 };

+ 3 - 4
arch/arm/mach-pxa/akita-ioexp.c

@@ -124,17 +124,16 @@ static int max7310_detach_client(struct i2c_client *client)
 }
 }
 
 
 static struct i2c_driver max7310_i2c_driver = {
 static struct i2c_driver max7310_i2c_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "akita-max7310",
+	.driver = {
+		.name	= "akita-max7310",
+	},
 	.id		= I2C_DRIVERID_AKITAIOEXP,
 	.id		= I2C_DRIVERID_AKITAIOEXP,
-	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter	= max7310_attach_adapter,
 	.attach_adapter	= max7310_attach_adapter,
 	.detach_client	= max7310_detach_client,
 	.detach_client	= max7310_detach_client,
 };
 };
 
 
 static struct i2c_client max7310_template = {
 static struct i2c_client max7310_template = {
 	name:   "akita-max7310",
 	name:   "akita-max7310",
-	flags:  I2C_CLIENT_ALLOW_USE,
 	driver: &max7310_i2c_driver,
 	driver: &max7310_i2c_driver,
 };
 };
 
 

+ 21 - 0
arch/arm/mach-pxa/mainstone.c

@@ -43,6 +43,7 @@
 #include <asm/arch/pxafb.h>
 #include <asm/arch/pxafb.h>
 #include <asm/arch/mmc.h>
 #include <asm/arch/mmc.h>
 #include <asm/arch/irda.h>
 #include <asm/arch/irda.h>
+#include <asm/arch/ohci.h>
 
 
 #include "generic.h"
 #include "generic.h"
 
 
@@ -393,6 +394,25 @@ static struct platform_device *platform_devices[] __initdata = {
 	&mst_flash_device[1],
 	&mst_flash_device[1],
 };
 };
 
 
+static int mainstone_ohci_init(struct device *dev)
+{
+	/* setup Port1 GPIO pin. */
+	pxa_gpio_mode( 88 | GPIO_ALT_FN_1_IN);	/* USBHPWR1 */
+	pxa_gpio_mode( 89 | GPIO_ALT_FN_2_OUT);	/* USBHPEN1 */
+
+	/* Set the Power Control Polarity Low and Power Sense
+	   Polarity Low to active low. */
+	UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
+		~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);
+
+	return 0;
+}
+
+static struct pxaohci_platform_data mainstone_ohci_platform_data = {
+	.port_mode	= PMM_PERPORT_MODE,
+	.init		= mainstone_ohci_init,
+};
+
 static void __init mainstone_init(void)
 static void __init mainstone_init(void)
 {
 {
 	int SW7 = 0;  /* FIXME: get from SCR (Mst doc section 3.2.1.1) */
 	int SW7 = 0;  /* FIXME: get from SCR (Mst doc section 3.2.1.1) */
@@ -430,6 +450,7 @@ static void __init mainstone_init(void)
 
 
 	pxa_set_mci_info(&mainstone_mci_platform_data);
 	pxa_set_mci_info(&mainstone_mci_platform_data);
 	pxa_set_ficp_info(&mainstone_ficp_platform_data);
 	pxa_set_ficp_info(&mainstone_ficp_platform_data);
+	pxa_set_ohci_info(&mainstone_ohci_platform_data);
 }
 }
 
 
 
 

+ 6 - 0
arch/arm/mach-pxa/pxa27x.c

@@ -21,6 +21,7 @@
 #include <asm/hardware.h>
 #include <asm/hardware.h>
 #include <asm/irq.h>
 #include <asm/irq.h>
 #include <asm/arch/pxa-regs.h>
 #include <asm/arch/pxa-regs.h>
+#include <asm/arch/ohci.h>
 
 
 #include "generic.h"
 #include "generic.h"
 
 
@@ -194,6 +195,11 @@ static struct platform_device ohci_device = {
 	.resource       = pxa27x_ohci_resources,
 	.resource       = pxa27x_ohci_resources,
 };
 };
 
 
+void __init pxa_set_ohci_info(struct pxaohci_platform_data *info)
+{
+	ohci_device.dev.platform_data = info;
+}
+
 static struct platform_device *devices[] __initdata = {
 static struct platform_device *devices[] __initdata = {
 	&ohci_device,
 	&ohci_device,
 };
 };

+ 1 - 2
arch/arm26/nwfpe/fpmodule.c

@@ -46,10 +46,9 @@ typedef struct task_struct*	PTASK;
 
 
 #ifdef MODULE
 #ifdef MODULE
 void fp_send_sig(unsigned long sig, PTASK p, int priv);
 void fp_send_sig(unsigned long sig, PTASK p, int priv);
-#if LINUX_VERSION_CODE > 0x20115
+
 MODULE_AUTHOR("Scott Bambrough <scottb@rebel.com>");
 MODULE_AUTHOR("Scott Bambrough <scottb@rebel.com>");
 MODULE_DESCRIPTION("NWFPE floating point emulator");
 MODULE_DESCRIPTION("NWFPE floating point emulator");
-#endif
 
 
 #else
 #else
 #define fp_send_sig	send_sig
 #define fp_send_sig	send_sig

+ 0 - 6
arch/cris/arch-v10/kernel/kgdb.c

@@ -569,12 +569,6 @@ gdb_cris_strtol (const char *s, char **endptr, int base)
 	return x;
 	return x;
 }
 }
 
 
-int
-double_this(int x)
-{
-        return 2 * x;
-}
-
 /********************************* Register image ****************************/
 /********************************* Register image ****************************/
 /* Copy the content of a register image into another. The size n is
 /* Copy the content of a register image into another. The size n is
    the size of the register image. Due to struct assignment generation of
    the size of the register image. Due to struct assignment generation of

+ 1 - 0
arch/frv/kernel/Makefile

@@ -20,3 +20,4 @@ obj-$(CONFIG_FUJITSU_MB93493)	+= irq-mb93493.o
 obj-$(CONFIG_PM)		+= pm.o cmode.o
 obj-$(CONFIG_PM)		+= pm.o cmode.o
 obj-$(CONFIG_MB93093_PDK)	+= pm-mb93093.o
 obj-$(CONFIG_MB93093_PDK)	+= pm-mb93093.o
 obj-$(CONFIG_SYSCTL)		+= sysctl.o
 obj-$(CONFIG_SYSCTL)		+= sysctl.o
+obj-$(CONFIG_FUTEX)		+= futex.o

+ 1 - 1
arch/frv/kernel/entry.S

@@ -1076,7 +1076,7 @@ __entry_work_notifysig:
 	LEDS		0x6410
 	LEDS		0x6410
 	ori.p		gr4,#0,gr8
 	ori.p		gr4,#0,gr8
 	call		do_notify_resume
 	call		do_notify_resume
-	bra		__entry_return_direct
+	bra		__entry_resume_userspace
 
 
 	# perform syscall entry tracing
 	# perform syscall entry tracing
 __syscall_trace_entry:
 __syscall_trace_entry:

+ 242 - 0
arch/frv/kernel/futex.c

@@ -0,0 +1,242 @@
+/* futex.c: futex operations
+ *
+ * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.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.
+ */
+
+#include <linux/futex.h>
+#include <asm/futex.h>
+#include <asm/errno.h>
+#include <asm/uaccess.h>
+
+/*
+ * the various futex operations; MMU fault checking is ignored under no-MMU
+ * conditions
+ */
+static inline int atomic_futex_op_xchg_set(int oparg, int __user *uaddr, int *_oldval)
+{
+	int oldval, ret;
+
+	asm("0:						\n"
+	    "	orcc		gr0,gr0,gr0,icc3	\n"	/* set ICC3.Z */
+	    "	ckeq		icc3,cc7		\n"
+	    "1:	ld.p		%M0,%1			\n"	/* LD.P/ORCR must be atomic */
+	    "	orcr		cc7,cc7,cc3		\n"	/* set CC3 to true */
+	    "2:	cst.p		%3,%M0		,cc3,#1	\n"
+	    "	corcc		gr29,gr29,gr0	,cc3,#1	\n"	/* clear ICC3.Z if store happens */
+	    "	beq		icc3,#0,0b		\n"
+	    "	setlos		0,%2			\n"
+	    "3:						\n"
+	    ".subsection 2				\n"
+	    "4:	setlos		%5,%2			\n"
+	    "	bra		3b			\n"
+	    ".previous					\n"
+	    ".section __ex_table,\"a\"			\n"
+	    "	.balign		8			\n"
+	    "	.long		1b,4b			\n"
+	    "	.long		2b,4b			\n"
+	    ".previous"
+	    : "+U"(*uaddr), "=&r"(oldval), "=&r"(ret), "=r"(oparg)
+	    : "3"(oparg), "i"(-EFAULT)
+	    : "memory", "cc7", "cc3", "icc3"
+	    );
+
+	*_oldval = oldval;
+	return ret;
+}
+
+static inline int atomic_futex_op_xchg_add(int oparg, int __user *uaddr, int *_oldval)
+{
+	int oldval, ret;
+
+	asm("0:						\n"
+	    "	orcc		gr0,gr0,gr0,icc3	\n"	/* set ICC3.Z */
+	    "	ckeq		icc3,cc7		\n"
+	    "1:	ld.p		%M0,%1			\n"	/* LD.P/ORCR must be atomic */
+	    "	orcr		cc7,cc7,cc3		\n"	/* set CC3 to true */
+	    "	add		%1,%3,%3		\n"
+	    "2:	cst.p		%3,%M0		,cc3,#1	\n"
+	    "	corcc		gr29,gr29,gr0	,cc3,#1	\n"	/* clear ICC3.Z if store happens */
+	    "	beq		icc3,#0,0b		\n"
+	    "	setlos		0,%2			\n"
+	    "3:						\n"
+	    ".subsection 2				\n"
+	    "4:	setlos		%5,%2			\n"
+	    "	bra		3b			\n"
+	    ".previous					\n"
+	    ".section __ex_table,\"a\"			\n"
+	    "	.balign		8			\n"
+	    "	.long		1b,4b			\n"
+	    "	.long		2b,4b			\n"
+	    ".previous"
+	    : "+U"(*uaddr), "=&r"(oldval), "=&r"(ret), "=r"(oparg)
+	    : "3"(oparg), "i"(-EFAULT)
+	    : "memory", "cc7", "cc3", "icc3"
+	    );
+
+	*_oldval = oldval;
+	return ret;
+}
+
+static inline int atomic_futex_op_xchg_or(int oparg, int __user *uaddr, int *_oldval)
+{
+	int oldval, ret;
+
+	asm("0:						\n"
+	    "	orcc		gr0,gr0,gr0,icc3	\n"	/* set ICC3.Z */
+	    "	ckeq		icc3,cc7		\n"
+	    "1:	ld.p		%M0,%1			\n"	/* LD.P/ORCR must be atomic */
+	    "	orcr		cc7,cc7,cc3		\n"	/* set CC3 to true */
+	    "	or		%1,%3,%3		\n"
+	    "2:	cst.p		%3,%M0		,cc3,#1	\n"
+	    "	corcc		gr29,gr29,gr0	,cc3,#1	\n"	/* clear ICC3.Z if store happens */
+	    "	beq		icc3,#0,0b		\n"
+	    "	setlos		0,%2			\n"
+	    "3:						\n"
+	    ".subsection 2				\n"
+	    "4:	setlos		%5,%2			\n"
+	    "	bra		3b			\n"
+	    ".previous					\n"
+	    ".section __ex_table,\"a\"			\n"
+	    "	.balign		8			\n"
+	    "	.long		1b,4b			\n"
+	    "	.long		2b,4b			\n"
+	    ".previous"
+	    : "+U"(*uaddr), "=&r"(oldval), "=&r"(ret), "=r"(oparg)
+	    : "3"(oparg), "i"(-EFAULT)
+	    : "memory", "cc7", "cc3", "icc3"
+	    );
+
+	*_oldval = oldval;
+	return ret;
+}
+
+static inline int atomic_futex_op_xchg_and(int oparg, int __user *uaddr, int *_oldval)
+{
+	int oldval, ret;
+
+	asm("0:						\n"
+	    "	orcc		gr0,gr0,gr0,icc3	\n"	/* set ICC3.Z */
+	    "	ckeq		icc3,cc7		\n"
+	    "1:	ld.p		%M0,%1			\n"	/* LD.P/ORCR must be atomic */
+	    "	orcr		cc7,cc7,cc3		\n"	/* set CC3 to true */
+	    "	and		%1,%3,%3		\n"
+	    "2:	cst.p		%3,%M0		,cc3,#1	\n"
+	    "	corcc		gr29,gr29,gr0	,cc3,#1	\n"	/* clear ICC3.Z if store happens */
+	    "	beq		icc3,#0,0b		\n"
+	    "	setlos		0,%2			\n"
+	    "3:						\n"
+	    ".subsection 2				\n"
+	    "4:	setlos		%5,%2			\n"
+	    "	bra		3b			\n"
+	    ".previous					\n"
+	    ".section __ex_table,\"a\"			\n"
+	    "	.balign		8			\n"
+	    "	.long		1b,4b			\n"
+	    "	.long		2b,4b			\n"
+	    ".previous"
+	    : "+U"(*uaddr), "=&r"(oldval), "=&r"(ret), "=r"(oparg)
+	    : "3"(oparg), "i"(-EFAULT)
+	    : "memory", "cc7", "cc3", "icc3"
+	    );
+
+	*_oldval = oldval;
+	return ret;
+}
+
+static inline int atomic_futex_op_xchg_xor(int oparg, int __user *uaddr, int *_oldval)
+{
+	int oldval, ret;
+
+	asm("0:						\n"
+	    "	orcc		gr0,gr0,gr0,icc3	\n"	/* set ICC3.Z */
+	    "	ckeq		icc3,cc7		\n"
+	    "1:	ld.p		%M0,%1			\n"	/* LD.P/ORCR must be atomic */
+	    "	orcr		cc7,cc7,cc3		\n"	/* set CC3 to true */
+	    "	xor		%1,%3,%3		\n"
+	    "2:	cst.p		%3,%M0		,cc3,#1	\n"
+	    "	corcc		gr29,gr29,gr0	,cc3,#1	\n"	/* clear ICC3.Z if store happens */
+	    "	beq		icc3,#0,0b		\n"
+	    "	setlos		0,%2			\n"
+	    "3:						\n"
+	    ".subsection 2				\n"
+	    "4:	setlos		%5,%2			\n"
+	    "	bra		3b			\n"
+	    ".previous					\n"
+	    ".section __ex_table,\"a\"			\n"
+	    "	.balign		8			\n"
+	    "	.long		1b,4b			\n"
+	    "	.long		2b,4b			\n"
+	    ".previous"
+	    : "+U"(*uaddr), "=&r"(oldval), "=&r"(ret), "=r"(oparg)
+	    : "3"(oparg), "i"(-EFAULT)
+	    : "memory", "cc7", "cc3", "icc3"
+	    );
+
+	*_oldval = oldval;
+	return ret;
+}
+
+/*****************************************************************************/
+/*
+ * do the futex operations
+ */
+int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
+{
+	int op = (encoded_op >> 28) & 7;
+	int cmp = (encoded_op >> 24) & 15;
+	int oparg = (encoded_op << 8) >> 20;
+	int cmparg = (encoded_op << 20) >> 20;
+	int oldval = 0, ret;
+
+	if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
+		oparg = 1 << oparg;
+
+	if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
+		return -EFAULT;
+
+	inc_preempt_count();
+
+	switch (op) {
+	case FUTEX_OP_SET:
+		ret = atomic_futex_op_xchg_set(oparg, uaddr, &oldval);
+		break;
+	case FUTEX_OP_ADD:
+		ret = atomic_futex_op_xchg_add(oparg, uaddr, &oldval);
+		break;
+	case FUTEX_OP_OR:
+		ret = atomic_futex_op_xchg_or(oparg, uaddr, &oldval);
+		break;
+	case FUTEX_OP_ANDN:
+		ret = atomic_futex_op_xchg_and(~oparg, uaddr, &oldval);
+		break;
+	case FUTEX_OP_XOR:
+		ret = atomic_futex_op_xchg_xor(oparg, uaddr, &oldval);
+		break;
+	default:
+		ret = -ENOSYS;
+		break;
+	}
+
+	dec_preempt_count();
+
+	if (!ret) {
+		switch (cmp) {
+		case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
+		case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
+		case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
+		case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
+		case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
+		case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
+		default: ret = -ENOSYS; break;
+		}
+	}
+
+	return ret;
+
+} /* end futex_atomic_op_inuser() */

+ 85 - 70
arch/frv/kernel/signal.c

@@ -35,7 +35,7 @@ struct fdpic_func_descriptor {
 	unsigned long	GOT;
 	unsigned long	GOT;
 };
 };
 
 
-asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
+static int do_signal(sigset_t *oldset);
 
 
 /*
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
  * Atomically swap in the new signal mask, and wait for a signal.
@@ -55,7 +55,7 @@ asmlinkage int sys_sigsuspend(int history0, int history1, old_sigset_t mask)
 	while (1) {
 	while (1) {
 		current->state = TASK_INTERRUPTIBLE;
 		current->state = TASK_INTERRUPTIBLE;
 		schedule();
 		schedule();
-		if (do_signal(__frame, &saveset))
+		if (do_signal(&saveset))
 			/* return the signal number as the return value of this function
 			/* return the signal number as the return value of this function
 			 * - this is an utterly evil hack. syscalls should not invoke do_signal()
 			 * - this is an utterly evil hack. syscalls should not invoke do_signal()
 			 *   as entry.S sets regs->gr8 to the return value of the system call
 			 *   as entry.S sets regs->gr8 to the return value of the system call
@@ -91,7 +91,7 @@ asmlinkage int sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize)
 	while (1) {
 	while (1) {
 		current->state = TASK_INTERRUPTIBLE;
 		current->state = TASK_INTERRUPTIBLE;
 		schedule();
 		schedule();
-		if (do_signal(__frame, &saveset))
+		if (do_signal(&saveset))
 			/* return the signal number as the return value of this function
 			/* return the signal number as the return value of this function
 			 * - this is an utterly evil hack. syscalls should not invoke do_signal()
 			 * - this is an utterly evil hack. syscalls should not invoke do_signal()
 			 *   as entry.S sets regs->gr8 to the return value of the system call
 			 *   as entry.S sets regs->gr8 to the return value of the system call
@@ -276,13 +276,12 @@ static int setup_sigcontext(struct sigcontext __user *sc, unsigned long mask)
  * Determine which stack to use..
  * Determine which stack to use..
  */
  */
 static inline void __user *get_sigframe(struct k_sigaction *ka,
 static inline void __user *get_sigframe(struct k_sigaction *ka,
-					struct pt_regs *regs,
 					size_t frame_size)
 					size_t frame_size)
 {
 {
 	unsigned long sp;
 	unsigned long sp;
 
 
 	/* Default to using normal stack */
 	/* Default to using normal stack */
-	sp = regs->sp;
+	sp = __frame->sp;
 
 
 	/* This is the X/Open sanctioned signal stack switching.  */
 	/* This is the X/Open sanctioned signal stack switching.  */
 	if (ka->sa.sa_flags & SA_ONSTACK) {
 	if (ka->sa.sa_flags & SA_ONSTACK) {
@@ -291,18 +290,19 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
 	}
 	}
 
 
 	return (void __user *) ((sp - frame_size) & ~7UL);
 	return (void __user *) ((sp - frame_size) & ~7UL);
+
 } /* end get_sigframe() */
 } /* end get_sigframe() */
 
 
 /*****************************************************************************/
 /*****************************************************************************/
 /*
 /*
  *
  *
  */
  */
-static void setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs * regs)
+static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
 {
 {
 	struct sigframe __user *frame;
 	struct sigframe __user *frame;
 	int rsig;
 	int rsig;
 
 
-	frame = get_sigframe(ka, regs, sizeof(*frame));
+	frame = get_sigframe(ka, sizeof(*frame));
 
 
 	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 		goto give_sigsegv;
 		goto give_sigsegv;
@@ -346,47 +346,51 @@ static void setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, struct p
 	}
 	}
 
 
 	/* set up registers for signal handler */
 	/* set up registers for signal handler */
-	regs->sp   = (unsigned long) frame;
-	regs->lr   = (unsigned long) &frame->retcode;
-	regs->gr8  = sig;
+	__frame->sp   = (unsigned long) frame;
+	__frame->lr   = (unsigned long) &frame->retcode;
+	__frame->gr8  = sig;
 
 
 	if (get_personality & FDPIC_FUNCPTRS) {
 	if (get_personality & FDPIC_FUNCPTRS) {
 		struct fdpic_func_descriptor __user *funcptr =
 		struct fdpic_func_descriptor __user *funcptr =
 			(struct fdpic_func_descriptor *) ka->sa.sa_handler;
 			(struct fdpic_func_descriptor *) ka->sa.sa_handler;
-		__get_user(regs->pc, &funcptr->text);
-		__get_user(regs->gr15, &funcptr->GOT);
+		__get_user(__frame->pc, &funcptr->text);
+		__get_user(__frame->gr15, &funcptr->GOT);
 	} else {
 	} else {
-		regs->pc   = (unsigned long) ka->sa.sa_handler;
-		regs->gr15 = 0;
+		__frame->pc   = (unsigned long) ka->sa.sa_handler;
+		__frame->gr15 = 0;
 	}
 	}
 
 
 	set_fs(USER_DS);
 	set_fs(USER_DS);
 
 
+	/* the tracer may want to single-step inside the handler */
+	if (test_thread_flag(TIF_SINGLESTEP))
+		ptrace_notify(SIGTRAP);
+
 #if DEBUG_SIG
 #if DEBUG_SIG
 	printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
 	printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
-		sig, current->comm, current->pid, frame, regs->pc, frame->pretcode);
+	       sig, current->comm, current->pid, frame, __frame->pc,
+	       frame->pretcode);
 #endif
 #endif
 
 
-	return;
+	return 1;
 
 
 give_sigsegv:
 give_sigsegv:
-	if (sig == SIGSEGV)
-		ka->sa.sa_handler = SIG_DFL;
-
 	force_sig(SIGSEGV, current);
 	force_sig(SIGSEGV, current);
+	return 0;
+
 } /* end setup_frame() */
 } /* end setup_frame() */
 
 
 /*****************************************************************************/
 /*****************************************************************************/
 /*
 /*
  *
  *
  */
  */
-static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
-			   sigset_t *set, struct pt_regs * regs)
+static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+			  sigset_t *set)
 {
 {
 	struct rt_sigframe __user *frame;
 	struct rt_sigframe __user *frame;
 	int rsig;
 	int rsig;
 
 
-	frame = get_sigframe(ka, regs, sizeof(*frame));
+	frame = get_sigframe(ka, sizeof(*frame));
 
 
 	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 		goto give_sigsegv;
 		goto give_sigsegv;
@@ -409,7 +413,7 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 	if (__put_user(0, &frame->uc.uc_flags) ||
 	if (__put_user(0, &frame->uc.uc_flags) ||
 	    __put_user(0, &frame->uc.uc_link) ||
 	    __put_user(0, &frame->uc.uc_link) ||
 	    __put_user((void*)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp) ||
 	    __put_user((void*)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp) ||
-	    __put_user(sas_ss_flags(regs->sp), &frame->uc.uc_stack.ss_flags) ||
+	    __put_user(sas_ss_flags(__frame->sp), &frame->uc.uc_stack.ss_flags) ||
 	    __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size))
 	    __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size))
 		goto give_sigsegv;
 		goto give_sigsegv;
 
 
@@ -440,34 +444,38 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 	}
 	}
 
 
 	/* Set up registers for signal handler */
 	/* Set up registers for signal handler */
-	regs->sp  = (unsigned long) frame;
-	regs->lr   = (unsigned long) &frame->retcode;
-	regs->gr8 = sig;
-	regs->gr9 = (unsigned long) &frame->info;
+	__frame->sp  = (unsigned long) frame;
+	__frame->lr   = (unsigned long) &frame->retcode;
+	__frame->gr8 = sig;
+	__frame->gr9 = (unsigned long) &frame->info;
 
 
 	if (get_personality & FDPIC_FUNCPTRS) {
 	if (get_personality & FDPIC_FUNCPTRS) {
 		struct fdpic_func_descriptor *funcptr =
 		struct fdpic_func_descriptor *funcptr =
 			(struct fdpic_func_descriptor __user *) ka->sa.sa_handler;
 			(struct fdpic_func_descriptor __user *) ka->sa.sa_handler;
-		__get_user(regs->pc, &funcptr->text);
-		__get_user(regs->gr15, &funcptr->GOT);
+		__get_user(__frame->pc, &funcptr->text);
+		__get_user(__frame->gr15, &funcptr->GOT);
 	} else {
 	} else {
-		regs->pc   = (unsigned long) ka->sa.sa_handler;
-		regs->gr15 = 0;
+		__frame->pc   = (unsigned long) ka->sa.sa_handler;
+		__frame->gr15 = 0;
 	}
 	}
 
 
 	set_fs(USER_DS);
 	set_fs(USER_DS);
 
 
+	/* the tracer may want to single-step inside the handler */
+	if (test_thread_flag(TIF_SINGLESTEP))
+		ptrace_notify(SIGTRAP);
+
 #if DEBUG_SIG
 #if DEBUG_SIG
 	printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
 	printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
-		sig, current->comm, current->pid, frame, regs->pc, frame->pretcode);
+	       sig, current->comm, current->pid, frame, __frame->pc,
+	       frame->pretcode);
 #endif
 #endif
 
 
-	return;
+	return 1;
 
 
 give_sigsegv:
 give_sigsegv:
-	if (sig == SIGSEGV)
-		ka->sa.sa_handler = SIG_DFL;
 	force_sig(SIGSEGV, current);
 	force_sig(SIGSEGV, current);
+	return 0;
 
 
 } /* end setup_rt_frame() */
 } /* end setup_rt_frame() */
 
 
@@ -475,43 +483,51 @@ give_sigsegv:
 /*
 /*
  * OK, we're invoking a handler
  * OK, we're invoking a handler
  */
  */
-static void handle_signal(unsigned long sig, siginfo_t *info,
-			  struct k_sigaction *ka, sigset_t *oldset,
-			  struct pt_regs *regs)
+static int handle_signal(unsigned long sig, siginfo_t *info,
+			 struct k_sigaction *ka, sigset_t *oldset)
 {
 {
+	int ret;
+
 	/* Are we from a system call? */
 	/* Are we from a system call? */
-	if (in_syscall(regs)) {
+	if (in_syscall(__frame)) {
 		/* If so, check system call restarting.. */
 		/* If so, check system call restarting.. */
-		switch (regs->gr8) {
+		switch (__frame->gr8) {
 		case -ERESTART_RESTARTBLOCK:
 		case -ERESTART_RESTARTBLOCK:
 		case -ERESTARTNOHAND:
 		case -ERESTARTNOHAND:
-			regs->gr8 = -EINTR;
+			__frame->gr8 = -EINTR;
 			break;
 			break;
 
 
 		case -ERESTARTSYS:
 		case -ERESTARTSYS:
 			if (!(ka->sa.sa_flags & SA_RESTART)) {
 			if (!(ka->sa.sa_flags & SA_RESTART)) {
-				regs->gr8 = -EINTR;
+				__frame->gr8 = -EINTR;
 				break;
 				break;
 			}
 			}
+
 			/* fallthrough */
 			/* fallthrough */
 		case -ERESTARTNOINTR:
 		case -ERESTARTNOINTR:
-			regs->gr8 = regs->orig_gr8;
-			regs->pc -= 4;
+			__frame->gr8 = __frame->orig_gr8;
+			__frame->pc -= 4;
 		}
 		}
 	}
 	}
 
 
 	/* Set up the stack frame */
 	/* Set up the stack frame */
 	if (ka->sa.sa_flags & SA_SIGINFO)
 	if (ka->sa.sa_flags & SA_SIGINFO)
-		setup_rt_frame(sig, ka, info, oldset, regs);
+		ret = setup_rt_frame(sig, ka, info, oldset);
 	else
 	else
-		setup_frame(sig, ka, oldset, regs);
+		ret = setup_frame(sig, ka, oldset);
+
+	if (ret) {
+		spin_lock_irq(&current->sighand->siglock);
+		sigorsets(&current->blocked, &current->blocked,
+			  &ka->sa.sa_mask);
+		if (!(ka->sa.sa_flags & SA_NODEFER))
+			sigaddset(&current->blocked, sig);
+		recalc_sigpending();
+		spin_unlock_irq(&current->sighand->siglock);
+	}
+
+	return ret;
 
 
-	spin_lock_irq(&current->sighand->siglock);
-	sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
-	if (!(ka->sa.sa_flags & SA_NODEFER))
-		sigaddset(&current->blocked, sig);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
 } /* end handle_signal() */
 } /* end handle_signal() */
 
 
 /*****************************************************************************/
 /*****************************************************************************/
@@ -520,7 +536,7 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
  * want to handle. Thus you cannot kill init even with a SIGKILL even by
  * want to handle. Thus you cannot kill init even with a SIGKILL even by
  * mistake.
  * mistake.
  */
  */
-int do_signal(struct pt_regs *regs, sigset_t *oldset)
+static int do_signal(sigset_t *oldset)
 {
 {
 	struct k_sigaction ka;
 	struct k_sigaction ka;
 	siginfo_t info;
 	siginfo_t info;
@@ -532,7 +548,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
 	 * kernel mode. Just return without doing anything
 	 * kernel mode. Just return without doing anything
 	 * if so.
 	 * if so.
 	 */
 	 */
-	if (!user_mode(regs))
+	if (!user_mode(__frame))
 		return 1;
 		return 1;
 
 
 	if (try_to_freeze())
 	if (try_to_freeze())
@@ -541,30 +557,29 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
 	if (!oldset)
 	if (!oldset)
 		oldset = &current->blocked;
 		oldset = &current->blocked;
 
 
-	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-	if (signr > 0) {
-		handle_signal(signr, &info, &ka, oldset, regs);
-		return 1;
-	}
+	signr = get_signal_to_deliver(&info, &ka, __frame, NULL);
+	if (signr > 0)
+		return handle_signal(signr, &info, &ka, oldset);
 
 
- no_signal:
+no_signal:
 	/* Did we come from a system call? */
 	/* Did we come from a system call? */
-	if (regs->syscallno >= 0) {
+	if (__frame->syscallno >= 0) {
 		/* Restart the system call - no handlers present */
 		/* Restart the system call - no handlers present */
-		if (regs->gr8 == -ERESTARTNOHAND ||
-		    regs->gr8 == -ERESTARTSYS ||
-		    regs->gr8 == -ERESTARTNOINTR) {
-			regs->gr8 = regs->orig_gr8;
-			regs->pc -= 4;
+		if (__frame->gr8 == -ERESTARTNOHAND ||
+		    __frame->gr8 == -ERESTARTSYS ||
+		    __frame->gr8 == -ERESTARTNOINTR) {
+			__frame->gr8 = __frame->orig_gr8;
+			__frame->pc -= 4;
 		}
 		}
 
 
-		if (regs->gr8 == -ERESTART_RESTARTBLOCK){
-			regs->gr8 = __NR_restart_syscall;
-			regs->pc -= 4;
+		if (__frame->gr8 == -ERESTART_RESTARTBLOCK){
+			__frame->gr8 = __NR_restart_syscall;
+			__frame->pc -= 4;
 		}
 		}
 	}
 	}
 
 
 	return 0;
 	return 0;
+
 } /* end do_signal() */
 } /* end do_signal() */
 
 
 /*****************************************************************************/
 /*****************************************************************************/
@@ -580,6 +595,6 @@ asmlinkage void do_notify_resume(__u32 thread_info_flags)
 
 
 	/* deal with pending signal delivery */
 	/* deal with pending signal delivery */
 	if (thread_info_flags & _TIF_SIGPENDING)
 	if (thread_info_flags & _TIF_SIGPENDING)
-		do_signal(__frame, NULL);
+		do_signal(NULL);
 
 
 } /* end do_notify_resume() */
 } /* end do_notify_resume() */

+ 6 - 2
arch/i386/Kconfig

@@ -464,7 +464,6 @@ config NUMA
 	depends on SMP && HIGHMEM64G && (X86_NUMAQ || X86_GENERICARCH || (X86_SUMMIT && ACPI))
 	depends on SMP && HIGHMEM64G && (X86_NUMAQ || X86_GENERICARCH || (X86_SUMMIT && ACPI))
 	default n if X86_PC
 	default n if X86_PC
 	default y if (X86_NUMAQ || X86_SUMMIT)
 	default y if (X86_NUMAQ || X86_SUMMIT)
-	select SPARSEMEM_STATIC
 
 
 # Need comments to help the hapless user trying to turn on NUMA support
 # Need comments to help the hapless user trying to turn on NUMA support
 comment "NUMA (NUMA-Q) requires SMP, 64GB highmem support"
 comment "NUMA (NUMA-Q) requires SMP, 64GB highmem support"
@@ -493,6 +492,10 @@ config HAVE_ARCH_ALLOC_REMAP
 	depends on NUMA
 	depends on NUMA
 	default y
 	default y
 
 
+config ARCH_FLATMEM_ENABLE
+	def_bool y
+	depends on (ARCH_SELECT_MEMORY_MODEL && X86_PC)
+
 config ARCH_DISCONTIGMEM_ENABLE
 config ARCH_DISCONTIGMEM_ENABLE
 	def_bool y
 	def_bool y
 	depends on NUMA
 	depends on NUMA
@@ -503,7 +506,8 @@ config ARCH_DISCONTIGMEM_DEFAULT
 
 
 config ARCH_SPARSEMEM_ENABLE
 config ARCH_SPARSEMEM_ENABLE
 	def_bool y
 	def_bool y
-	depends on NUMA
+	depends on (NUMA || (X86_PC && EXPERIMENTAL))
+	select SPARSEMEM_STATIC
 
 
 config ARCH_SELECT_MEMORY_MODEL
 config ARCH_SELECT_MEMORY_MODEL
 	def_bool y
 	def_bool y

+ 10 - 4
arch/i386/Kconfig.cpu

@@ -39,6 +39,7 @@ config M386
 	  - "Winchip-2" for IDT Winchip 2.
 	  - "Winchip-2" for IDT Winchip 2.
 	  - "Winchip-2A" for IDT Winchips with 3dNow! capabilities.
 	  - "Winchip-2A" for IDT Winchips with 3dNow! capabilities.
 	  - "GeodeGX1" for Geode GX1 (Cyrix MediaGX).
 	  - "GeodeGX1" for Geode GX1 (Cyrix MediaGX).
+	  - "Geode GX/LX" For AMD Geode GX and LX processors.
 	  - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3.
 	  - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3.
 	  - "VIA C3-2 for VIA C3-2 "Nehemiah" (model 9 and above).
 	  - "VIA C3-2 for VIA C3-2 "Nehemiah" (model 9 and above).
 
 
@@ -171,6 +172,11 @@ config MGEODEGX1
 	help
 	help
 	  Select this for a Geode GX1 (Cyrix MediaGX) chip.
 	  Select this for a Geode GX1 (Cyrix MediaGX) chip.
 
 
+config MGEODE_LX
+       bool "Geode GX/LX"
+       help
+         Select this for AMD Geode GX and LX processors.
+
 config MCYRIXIII
 config MCYRIXIII
 	bool "CyrixIII/VIA-C3"
 	bool "CyrixIII/VIA-C3"
 	help
 	help
@@ -220,8 +226,8 @@ config X86_XADD
 config X86_L1_CACHE_SHIFT
 config X86_L1_CACHE_SHIFT
 	int
 	int
 	default "7" if MPENTIUM4 || X86_GENERIC
 	default "7" if MPENTIUM4 || X86_GENERIC
-	default "4" if X86_ELAN || M486 || M386
-	default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODEGX1
+	default "4" if X86_ELAN || M486 || M386 || MGEODEGX1
+	default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX
 	default "6" if MK7 || MK8 || MPENTIUMM
 	default "6" if MK7 || MK8 || MPENTIUMM
 
 
 config RWSEM_GENERIC_SPINLOCK
 config RWSEM_GENERIC_SPINLOCK
@@ -290,12 +296,12 @@ config X86_INTEL_USERCOPY
 
 
 config X86_USE_PPRO_CHECKSUM
 config X86_USE_PPRO_CHECKSUM
 	bool
 	bool
-	depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON
+	depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON || MGEODE_LX
 	default y
 	default y
 
 
 config X86_USE_3DNOW
 config X86_USE_3DNOW
 	bool
 	bool
-	depends on MCYRIXIII || MK7
+	depends on MCYRIXIII || MK7 || MGEODE_LX
 	default y
 	default y
 
 
 config X86_OOSTORE
 config X86_OOSTORE

+ 10 - 0
arch/i386/Kconfig.debug

@@ -42,6 +42,16 @@ config DEBUG_PAGEALLOC
 	  This results in a large slowdown, but helps to find certain types
 	  This results in a large slowdown, but helps to find certain types
 	  of memory corruptions.
 	  of memory corruptions.
 
 
+config DEBUG_RODATA
+	bool "Write protect kernel read-only data structures"
+	depends on DEBUG_KERNEL
+	help
+	  Mark the kernel read-only data as write-protected in the pagetables,
+	  in order to catch accidental (and incorrect) writes to such const
+	  data. This option may have a slight performance impact because a
+	  portion of the kernel code won't be covered by a 2MB TLB anymore.
+	  If in doubt, say "N".
+
 config 4KSTACKS
 config 4KSTACKS
 	bool "Use 4Kb for kernel stacks instead of 8Kb"
 	bool "Use 4Kb for kernel stacks instead of 8Kb"
 	depends on DEBUG_KERNEL
 	depends on DEBUG_KERNEL

+ 1 - 1
arch/i386/kernel/apic.c

@@ -721,7 +721,7 @@ static int __init apic_set_verbosity(char *str)
 		apic_verbosity = APIC_VERBOSE;
 		apic_verbosity = APIC_VERBOSE;
 	else
 	else
 		printk(KERN_WARNING "APIC Verbosity level %s not recognised"
 		printk(KERN_WARNING "APIC Verbosity level %s not recognised"
-				" use apic=verbose or apic=debug", str);
+				" use apic=verbose or apic=debug\n", str);
 
 
 	return 0;
 	return 0;
 }
 }

+ 36 - 61
arch/i386/kernel/apm.c

@@ -302,17 +302,6 @@ extern int (*console_blank_hook)(int);
 
 
 #include "apm.h"
 #include "apm.h"
 
 
-/*
- * Define to make all _set_limit calls use 64k limits.  The APM 1.1 BIOS is
- * supposed to provide limit information that it recognizes.  Many machines
- * do this correctly, but many others do not restrict themselves to their
- * claimed limit.  When this happens, they will cause a segmentation
- * violation in the kernel at boot time.  Most BIOS's, however, will
- * respect a 64k limit, so we use that.  If you want to be pedantic and
- * hold your BIOS to its claims, then undefine this.
- */
-#define APM_RELAX_SEGMENTS
-
 /*
 /*
  * Define to re-initialize the interrupt 0 timer to 100 Hz after a suspend.
  * Define to re-initialize the interrupt 0 timer to 100 Hz after a suspend.
  * This patched by Chad Miller <cmiller@surfsouth.com>, original code by
  * This patched by Chad Miller <cmiller@surfsouth.com>, original code by
@@ -1075,22 +1064,23 @@ static int apm_engage_power_management(u_short device, int enable)
  
  
 static int apm_console_blank(int blank)
 static int apm_console_blank(int blank)
 {
 {
-	int	error;
-	u_short	state;
+	int error, i;
+	u_short state;
+	static const u_short dev[3] = { 0x100, 0x1FF, 0x101 };
 
 
 	state = blank ? APM_STATE_STANDBY : APM_STATE_READY;
 	state = blank ? APM_STATE_STANDBY : APM_STATE_READY;
-	/* Blank the first display device */
-	error = set_power_state(0x100, state);
-	if ((error != APM_SUCCESS) && (error != APM_NO_ERROR)) {
-		/* try to blank them all instead */
-		error = set_power_state(0x1ff, state);
-		if ((error != APM_SUCCESS) && (error != APM_NO_ERROR))
-			/* try to blank device one instead */
-			error = set_power_state(0x101, state);
+
+	for (i = 0; i < ARRAY_SIZE(dev); i++) {
+		error = set_power_state(dev[i], state);
+
+		if ((error == APM_SUCCESS) || (error == APM_NO_ERROR))
+			return 1;
+
+		if (error == APM_NOT_ENGAGED)
+			break;
 	}
 	}
-	if ((error == APM_SUCCESS) || (error == APM_NO_ERROR))
-		return 1;
-	if (error == APM_NOT_ENGAGED) {
+
+	if (error == APM_NOT_ENGAGED && state != APM_STATE_READY) {
 		static int tried;
 		static int tried;
 		int eng_error;
 		int eng_error;
 		if (tried++ == 0) {
 		if (tried++ == 0) {
@@ -2233,8 +2223,8 @@ static struct dmi_system_id __initdata apm_dmi_table[] = {
 static int __init apm_init(void)
 static int __init apm_init(void)
 {
 {
 	struct proc_dir_entry *apm_proc;
 	struct proc_dir_entry *apm_proc;
+	struct desc_struct *gdt;
 	int ret;
 	int ret;
-	int i;
 
 
 	dmi_check_system(apm_dmi_table);
 	dmi_check_system(apm_dmi_table);
 
 
@@ -2312,45 +2302,30 @@ static int __init apm_init(void)
 	set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
 	set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
 	_set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
 	_set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
 
 
+	/*
+	 * Set up the long jump entry point to the APM BIOS, which is called
+	 * from inline assembly.
+	 */
 	apm_bios_entry.offset = apm_info.bios.offset;
 	apm_bios_entry.offset = apm_info.bios.offset;
 	apm_bios_entry.segment = APM_CS;
 	apm_bios_entry.segment = APM_CS;
 
 
-	for (i = 0; i < NR_CPUS; i++) {
-		struct desc_struct *gdt = get_cpu_gdt_table(i);
-		set_base(gdt[APM_CS >> 3],
-			 __va((unsigned long)apm_info.bios.cseg << 4));
-		set_base(gdt[APM_CS_16 >> 3],
-			 __va((unsigned long)apm_info.bios.cseg_16 << 4));
-		set_base(gdt[APM_DS >> 3],
-			 __va((unsigned long)apm_info.bios.dseg << 4));
-#ifndef APM_RELAX_SEGMENTS
-		if (apm_info.bios.version == 0x100) {
-#endif
-			/* For ASUS motherboard, Award BIOS rev 110 (and others?) */
-			_set_limit((char *)&gdt[APM_CS >> 3], 64 * 1024 - 1);
-			/* For some unknown machine. */
-			_set_limit((char *)&gdt[APM_CS_16 >> 3], 64 * 1024 - 1);
-			/* For the DEC Hinote Ultra CT475 (and others?) */
-			_set_limit((char *)&gdt[APM_DS >> 3], 64 * 1024 - 1);
-#ifndef APM_RELAX_SEGMENTS
-		} else {
-			_set_limit((char *)&gdt[APM_CS >> 3],
-				(apm_info.bios.cseg_len - 1) & 0xffff);
-			_set_limit((char *)&gdt[APM_CS_16 >> 3],
-				(apm_info.bios.cseg_16_len - 1) & 0xffff);
-			_set_limit((char *)&gdt[APM_DS >> 3],
-				(apm_info.bios.dseg_len - 1) & 0xffff);
-		      /* workaround for broken BIOSes */
-	                if (apm_info.bios.cseg_len <= apm_info.bios.offset)
-        	                _set_limit((char *)&gdt[APM_CS >> 3], 64 * 1024 -1);
-                       if (apm_info.bios.dseg_len <= 0x40) { /* 0x40 * 4kB == 64kB */
-                        	/* for the BIOS that assumes granularity = 1 */
-                        	gdt[APM_DS >> 3].b |= 0x800000;
-                        	printk(KERN_NOTICE "apm: we set the granularity of dseg.\n");
-        	        }
-		}
-#endif
-	}
+	/*
+	 * The APM 1.1 BIOS is supposed to provide limit information that it
+	 * recognizes.  Many machines do this correctly, but many others do
+	 * not restrict themselves to their claimed limit.  When this happens,
+	 * they will cause a segmentation violation in the kernel at boot time.
+	 * Most BIOS's, however, will respect a 64k limit, so we use that.
+	 *
+	 * Note we only set APM segments on CPU zero, since we pin the APM
+	 * code to that CPU.
+	 */
+	gdt = get_cpu_gdt_table(0);
+	set_base(gdt[APM_CS >> 3],
+		 __va((unsigned long)apm_info.bios.cseg << 4));
+	set_base(gdt[APM_CS_16 >> 3],
+		 __va((unsigned long)apm_info.bios.cseg_16 << 4));
+	set_base(gdt[APM_DS >> 3],
+		 __va((unsigned long)apm_info.bios.dseg << 4));
 
 
 	apm_proc = create_proc_info_entry("apm", 0, NULL, apm_get_info);
 	apm_proc = create_proc_info_entry("apm", 0, NULL, apm_get_info);
 	if (apm_proc)
 	if (apm_proc)

+ 6 - 1
arch/i386/kernel/cpu/amd.c

@@ -161,8 +161,13 @@ static void __init init_amd(struct cpuinfo_x86 *c)
 					set_bit(X86_FEATURE_K6_MTRR, c->x86_capability);
 					set_bit(X86_FEATURE_K6_MTRR, c->x86_capability);
 				break;
 				break;
 			}
 			}
-			break;
 
 
+			if (c->x86_model == 10) {
+				/* AMD Geode LX is model 10 */
+				/* placeholder for any needed mods */
+				break;
+			}
+			break;
 		case 6: /* An Athlon/Duron */
 		case 6: /* An Athlon/Duron */
  
  
 			/* Bit 15 of Athlon specific MSR 15, needs to be 0
 			/* Bit 15 of Athlon specific MSR 15, needs to be 0

+ 0 - 8
arch/i386/kernel/cpu/common.c

@@ -18,9 +18,6 @@
 
 
 #include "cpu.h"
 #include "cpu.h"
 
 
-DEFINE_PER_CPU(struct desc_struct, cpu_gdt_table[GDT_ENTRIES]);
-EXPORT_PER_CPU_SYMBOL(cpu_gdt_table);
-
 DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
 DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
 EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack);
 EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack);
 
 
@@ -598,11 +595,6 @@ void __devinit cpu_init(void)
 	load_gdt(&cpu_gdt_descr[cpu]);
 	load_gdt(&cpu_gdt_descr[cpu]);
 	load_idt(&idt_descr);
 	load_idt(&idt_descr);
 
 
-	/*
-	 * Delete NT
-	 */
-	__asm__("pushfl ; andl $0xffffbfff,(%esp) ; popfl");
-
 	/*
 	/*
 	 * Set up and load the per-CPU TSS and LDT
 	 * Set up and load the per-CPU TSS and LDT
 	 */
 	 */

+ 2 - 1
arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c

@@ -177,9 +177,10 @@ static unsigned int nforce2_fsb_read(int bootfsb)
  */
  */
 static int nforce2_set_fsb(unsigned int fsb)
 static int nforce2_set_fsb(unsigned int fsb)
 {
 {
-	u32 pll, temp = 0;
+	u32 temp = 0;
 	unsigned int tfsb;
 	unsigned int tfsb;
 	int diff;
 	int diff;
+	int pll = 0;
 
 
 	if ((fsb > max_fsb) || (fsb < NFORCE2_MIN_FSB)) {
 	if ((fsb > max_fsb) || (fsb < NFORCE2_MIN_FSB)) {
 		printk(KERN_ERR "cpufreq: FSB %d is out of range!\n", fsb);
 		printk(KERN_ERR "cpufreq: FSB %d is out of range!\n", fsb);

+ 28 - 22
arch/i386/kernel/cpu/cpufreq/powernow-k8.c

@@ -45,7 +45,7 @@
 
 
 #define PFX "powernow-k8: "
 #define PFX "powernow-k8: "
 #define BFX PFX "BIOS error: "
 #define BFX PFX "BIOS error: "
-#define VERSION "version 1.50.4"
+#define VERSION "version 1.60.0"
 #include "powernow-k8.h"
 #include "powernow-k8.h"
 
 
 /* serialize freq changes  */
 /* serialize freq changes  */
@@ -216,10 +216,10 @@ static int write_new_vid(struct powernow_k8_data *data, u32 vid)
 
 
 	do {
 	do {
 		wrmsr(MSR_FIDVID_CTL, lo, STOP_GRANT_5NS);
 		wrmsr(MSR_FIDVID_CTL, lo, STOP_GRANT_5NS);
-                if (i++ > 100) {
-                        printk(KERN_ERR PFX "internal error - pending bit very stuck - no further pstate changes possible\n");
-                        return 1;
-                }
+		if (i++ > 100) {
+			printk(KERN_ERR PFX "internal error - pending bit very stuck - no further pstate changes possible\n");
+			return 1;
+		}
 	} while (query_current_values_with_pending_wait(data));
 	} while (query_current_values_with_pending_wait(data));
 
 
 	if (savefid != data->currfid) {
 	if (savefid != data->currfid) {
@@ -336,7 +336,7 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid
 /* Phase 2 - core frequency transition */
 /* Phase 2 - core frequency transition */
 static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
 static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
 {
 {
-	u32 vcoreqfid, vcocurrfid, vcofiddiff, savevid = data->currvid;
+	u32 vcoreqfid, vcocurrfid, vcofiddiff, fid_interval, savevid = data->currvid;
 
 
 	if ((reqfid < HI_FID_TABLE_BOTTOM) && (data->currfid < HI_FID_TABLE_BOTTOM)) {
 	if ((reqfid < HI_FID_TABLE_BOTTOM) && (data->currfid < HI_FID_TABLE_BOTTOM)) {
 		printk(KERN_ERR PFX "ph2: illegal lo-lo transition 0x%x 0x%x\n",
 		printk(KERN_ERR PFX "ph2: illegal lo-lo transition 0x%x 0x%x\n",
@@ -359,9 +359,11 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
 	    : vcoreqfid - vcocurrfid;
 	    : vcoreqfid - vcocurrfid;
 
 
 	while (vcofiddiff > 2) {
 	while (vcofiddiff > 2) {
+		(data->currfid & 1) ? (fid_interval = 1) : (fid_interval = 2);
+
 		if (reqfid > data->currfid) {
 		if (reqfid > data->currfid) {
 			if (data->currfid > LO_FID_TABLE_TOP) {
 			if (data->currfid > LO_FID_TABLE_TOP) {
-				if (write_new_fid(data, data->currfid + 2)) {
+				if (write_new_fid(data, data->currfid + fid_interval)) {
 					return 1;
 					return 1;
 				}
 				}
 			} else {
 			} else {
@@ -371,7 +373,7 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
 				}
 				}
 			}
 			}
 		} else {
 		} else {
-			if (write_new_fid(data, data->currfid - 2))
+			if (write_new_fid(data, data->currfid - fid_interval))
 				return 1;
 				return 1;
 		}
 		}
 
 
@@ -464,7 +466,7 @@ static int check_supported_cpu(unsigned int cpu)
 	set_cpus_allowed(current, cpumask_of_cpu(cpu));
 	set_cpus_allowed(current, cpumask_of_cpu(cpu));
 
 
 	if (smp_processor_id() != cpu) {
 	if (smp_processor_id() != cpu) {
-		printk(KERN_ERR "limiting to cpu %u failed\n", cpu);
+		printk(KERN_ERR PFX "limiting to cpu %u failed\n", cpu);
 		goto out;
 		goto out;
 	}
 	}
 
 
@@ -474,7 +476,7 @@ static int check_supported_cpu(unsigned int cpu)
 	eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
 	eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
 	if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) ||
 	if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) ||
 	    ((eax & CPUID_XFAM) != CPUID_XFAM_K8) ||
 	    ((eax & CPUID_XFAM) != CPUID_XFAM_K8) ||
-	    ((eax & CPUID_XMOD) > CPUID_XMOD_REV_F)) {
+	    ((eax & CPUID_XMOD) > CPUID_XMOD_REV_G)) {
 		printk(KERN_INFO PFX "Processor cpuid %x not supported\n", eax);
 		printk(KERN_INFO PFX "Processor cpuid %x not supported\n", eax);
 		goto out;
 		goto out;
 	}
 	}
@@ -517,22 +519,24 @@ static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst, u8
 			printk(KERN_ERR BFX "maxvid exceeded with pstate %d\n", j);
 			printk(KERN_ERR BFX "maxvid exceeded with pstate %d\n", j);
 			return -ENODEV;
 			return -ENODEV;
 		}
 		}
-		if ((pst[j].fid > MAX_FID)
-		    || (pst[j].fid & 1)
-		    || (j && (pst[j].fid < HI_FID_TABLE_BOTTOM))) {
+		if (pst[j].fid > MAX_FID) {
+			printk(KERN_ERR BFX "maxfid exceeded with pstate %d\n", j);
+			return -ENODEV;
+		}
+		if (j && (pst[j].fid < HI_FID_TABLE_BOTTOM)) {
 			/* Only first fid is allowed to be in "low" range */
 			/* Only first fid is allowed to be in "low" range */
-			printk(KERN_ERR PFX "two low fids - %d : 0x%x\n", j, pst[j].fid);
+			printk(KERN_ERR BFX "two low fids - %d : 0x%x\n", j, pst[j].fid);
 			return -EINVAL;
 			return -EINVAL;
 		}
 		}
 		if (pst[j].fid < lastfid)
 		if (pst[j].fid < lastfid)
 			lastfid = pst[j].fid;
 			lastfid = pst[j].fid;
 	}
 	}
 	if (lastfid & 1) {
 	if (lastfid & 1) {
-		printk(KERN_ERR PFX "lastfid invalid\n");
+		printk(KERN_ERR BFX "lastfid invalid\n");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 	if (lastfid > LO_FID_TABLE_TOP)
 	if (lastfid > LO_FID_TABLE_TOP)
-		printk(KERN_INFO PFX  "first fid not from lo freq table\n");
+		printk(KERN_INFO BFX  "first fid not from lo freq table\n");
 
 
 	return 0;
 	return 0;
 }
 }
@@ -631,7 +635,7 @@ static int find_psb_table(struct powernow_k8_data *data)
 
 
 		dprintk("table vers: 0x%x\n", psb->tableversion);
 		dprintk("table vers: 0x%x\n", psb->tableversion);
 		if (psb->tableversion != PSB_VERSION_1_4) {
 		if (psb->tableversion != PSB_VERSION_1_4) {
-			printk(KERN_INFO BFX "PSB table is not v1.4\n");
+			printk(KERN_ERR BFX "PSB table is not v1.4\n");
 			return -ENODEV;
 			return -ENODEV;
 		}
 		}
 
 
@@ -689,7 +693,7 @@ static int find_psb_table(struct powernow_k8_data *data)
 	 * BIOS and Kernel Developer's Guide, which is available on
 	 * BIOS and Kernel Developer's Guide, which is available on
 	 * www.amd.com
 	 * www.amd.com
 	 */
 	 */
-	printk(KERN_INFO PFX "BIOS error - no PSB or ACPI _PSS objects\n");
+	printk(KERN_ERR PFX "BIOS error - no PSB or ACPI _PSS objects\n");
 	return -ENODEV;
 	return -ENODEV;
 }
 }
 
 
@@ -912,7 +916,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi
 	set_cpus_allowed(current, cpumask_of_cpu(pol->cpu));
 	set_cpus_allowed(current, cpumask_of_cpu(pol->cpu));
 
 
 	if (smp_processor_id() != pol->cpu) {
 	if (smp_processor_id() != pol->cpu) {
-		printk(KERN_ERR "limiting to cpu %u failed\n", pol->cpu);
+		printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu);
 		goto err_out;
 		goto err_out;
 	}
 	}
 
 
@@ -982,6 +986,9 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol)
 	cpumask_t oldmask = CPU_MASK_ALL;
 	cpumask_t oldmask = CPU_MASK_ALL;
 	int rc, i;
 	int rc, i;
 
 
+	if (!cpu_online(pol->cpu))
+		return -ENODEV;
+
 	if (!check_supported_cpu(pol->cpu))
 	if (!check_supported_cpu(pol->cpu))
 		return -ENODEV;
 		return -ENODEV;
 
 
@@ -1021,7 +1028,7 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol)
 	set_cpus_allowed(current, cpumask_of_cpu(pol->cpu));
 	set_cpus_allowed(current, cpumask_of_cpu(pol->cpu));
 
 
 	if (smp_processor_id() != pol->cpu) {
 	if (smp_processor_id() != pol->cpu) {
-		printk(KERN_ERR "limiting to cpu %u failed\n", pol->cpu);
+		printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu);
 		goto err_out;
 		goto err_out;
 	}
 	}
 
 
@@ -1162,10 +1169,9 @@ static void __exit powernowk8_exit(void)
 	cpufreq_unregister_driver(&cpufreq_amd64_driver);
 	cpufreq_unregister_driver(&cpufreq_amd64_driver);
 }
 }
 
 
-MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and Mark Langsdorf <mark.langsdorf@amd.com.");
+MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and Mark Langsdorf <mark.langsdorf@amd.com>");
 MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver.");
 MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver.");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
 
 
 late_initcall(powernowk8_init);
 late_initcall(powernowk8_init);
 module_exit(powernowk8_exit);
 module_exit(powernowk8_exit);
-

+ 5 - 4
arch/i386/kernel/cpu/cpufreq/powernow-k8.h

@@ -42,7 +42,7 @@ struct powernow_k8_data {
 #define CPUID_XFAM			0x0ff00000	/* extended family */
 #define CPUID_XFAM			0x0ff00000	/* extended family */
 #define CPUID_XFAM_K8			0
 #define CPUID_XFAM_K8			0
 #define CPUID_XMOD			0x000f0000	/* extended model */
 #define CPUID_XMOD			0x000f0000	/* extended model */
-#define CPUID_XMOD_REV_F		0x00040000
+#define CPUID_XMOD_REV_G		0x00060000
 #define CPUID_USE_XFAM_XMOD		0x00000f00
 #define CPUID_USE_XFAM_XMOD		0x00000f00
 #define CPUID_GET_MAX_CAPABILITIES	0x80000000
 #define CPUID_GET_MAX_CAPABILITIES	0x80000000
 #define CPUID_FREQ_VOLT_CAPABILITIES	0x80000007
 #define CPUID_FREQ_VOLT_CAPABILITIES	0x80000007
@@ -86,13 +86,14 @@ struct powernow_k8_data {
  *   low fid table
  *   low fid table
  * - lowest entry in the high fid table must be a <= 200MHz + 2 * the entry
  * - lowest entry in the high fid table must be a <= 200MHz + 2 * the entry
  *   in the low fid table
  *   in the low fid table
- * - the parts can only step at 200 MHz intervals, so 1.9 GHz is never valid
+ * - the parts can only step at <= 200 MHz intervals, odd fid values are
+ *   supported in revision G and later revisions.
  * - lowest frequency must be >= interprocessor hypertransport link speed
  * - lowest frequency must be >= interprocessor hypertransport link speed
  *   (only applies to MP systems obviously)
  *   (only applies to MP systems obviously)
  */
  */
 
 
 /* fids (frequency identifiers) are arranged in 2 tables - lo and hi */
 /* fids (frequency identifiers) are arranged in 2 tables - lo and hi */
-#define LO_FID_TABLE_TOP     6	/* fid values marking the boundary    */
+#define LO_FID_TABLE_TOP     7	/* fid values marking the boundary    */
 #define HI_FID_TABLE_BOTTOM  8	/* between the low and high tables    */
 #define HI_FID_TABLE_BOTTOM  8	/* between the low and high tables    */
 
 
 #define LO_VCOFREQ_TABLE_TOP    1400	/* corresponding vco frequency values */
 #define LO_VCOFREQ_TABLE_TOP    1400	/* corresponding vco frequency values */
@@ -106,7 +107,7 @@ struct powernow_k8_data {
 #define MIN_FREQ 800	/* Min and max freqs, per spec */
 #define MIN_FREQ 800	/* Min and max freqs, per spec */
 #define MAX_FREQ 5000
 #define MAX_FREQ 5000
 
 
-#define INVALID_FID_MASK 0xffffffc1  /* not a valid fid if these bits are set */
+#define INVALID_FID_MASK 0xffffffc0  /* not a valid fid if these bits are set */
 #define INVALID_VID_MASK 0xffffffc0  /* not a valid vid if these bits are set */
 #define INVALID_VID_MASK 0xffffffc0  /* not a valid vid if these bits are set */
 
 
 #define VID_OFF 0x3f
 #define VID_OFF 0x3f

+ 32 - 15
arch/i386/kernel/cpu/cpufreq/speedstep-ich.c

@@ -40,6 +40,7 @@ static struct pci_dev *speedstep_chipset_dev;
  */
  */
 static unsigned int speedstep_processor = 0;
 static unsigned int speedstep_processor = 0;
 
 
+static u32 pmbase;
 
 
 /*
 /*
  *   There are only two frequency states for each processor. Values
  *   There are only two frequency states for each processor. Values
@@ -56,34 +57,47 @@ static struct cpufreq_frequency_table speedstep_freqs[] = {
 
 
 
 
 /**
 /**
- * speedstep_set_state - set the SpeedStep state
- * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
+ * speedstep_find_register - read the PMBASE address
  *
  *
- *   Tries to change the SpeedStep state.
+ * Returns: -ENODEV if no register could be found
  */
  */
-static void speedstep_set_state (unsigned int state)
+static int speedstep_find_register (void)
 {
 {
-	u32 pmbase;
-	u8 pm2_blk;
-	u8 value;
-	unsigned long flags;
-
-	if (!speedstep_chipset_dev || (state > 0x1))
-		return;
+	if (!speedstep_chipset_dev)
+		return -ENODEV;
 
 
 	/* get PMBASE */
 	/* get PMBASE */
 	pci_read_config_dword(speedstep_chipset_dev, 0x40, &pmbase);
 	pci_read_config_dword(speedstep_chipset_dev, 0x40, &pmbase);
 	if (!(pmbase & 0x01)) {
 	if (!(pmbase & 0x01)) {
 		printk(KERN_ERR "speedstep-ich: could not find speedstep register\n");
 		printk(KERN_ERR "speedstep-ich: could not find speedstep register\n");
-		return;
+		return -ENODEV;
 	}
 	}
 
 
 	pmbase &= 0xFFFFFFFE;
 	pmbase &= 0xFFFFFFFE;
 	if (!pmbase) {
 	if (!pmbase) {
 		printk(KERN_ERR "speedstep-ich: could not find speedstep register\n");
 		printk(KERN_ERR "speedstep-ich: could not find speedstep register\n");
-		return;
+		return -ENODEV;
 	}
 	}
 
 
+	dprintk("pmbase is 0x%x\n", pmbase);
+	return 0;
+}
+
+/**
+ * speedstep_set_state - set the SpeedStep state
+ * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
+ *
+ *   Tries to change the SpeedStep state.
+ */
+static void speedstep_set_state (unsigned int state)
+{
+	u8 pm2_blk;
+	u8 value;
+	unsigned long flags;
+
+	if (state > 0x1)
+		return;
+
 	/* Disable IRQs */
 	/* Disable IRQs */
 	local_irq_save(flags);
 	local_irq_save(flags);
 
 
@@ -315,10 +329,11 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
 	cpus_allowed = current->cpus_allowed;
 	cpus_allowed = current->cpus_allowed;
 	set_cpus_allowed(current, policy->cpus);
 	set_cpus_allowed(current, policy->cpus);
 
 
-	/* detect low and high frequency */
+	/* detect low and high frequency and transition latency */
 	result = speedstep_get_freqs(speedstep_processor,
 	result = speedstep_get_freqs(speedstep_processor,
 				     &speedstep_freqs[SPEEDSTEP_LOW].frequency,
 				     &speedstep_freqs[SPEEDSTEP_LOW].frequency,
 				     &speedstep_freqs[SPEEDSTEP_HIGH].frequency,
 				     &speedstep_freqs[SPEEDSTEP_HIGH].frequency,
+				     &policy->cpuinfo.transition_latency,
 				     &speedstep_set_state);
 				     &speedstep_set_state);
 	set_cpus_allowed(current, cpus_allowed);
 	set_cpus_allowed(current, cpus_allowed);
 	if (result)
 	if (result)
@@ -335,7 +350,6 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
 
 
 	/* cpuinfo and default policy values */
 	/* cpuinfo and default policy values */
 	policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
 	policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
-	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
 	policy->cur = speed;
 	policy->cur = speed;
 
 
 	result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs);
 	result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs);
@@ -400,6 +414,9 @@ static int __init speedstep_init(void)
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
+	if (speedstep_find_register())
+		return -ENODEV;
+
 	return cpufreq_register_driver(&speedstep_driver);
 	return cpufreq_register_driver(&speedstep_driver);
 }
 }
 
 

+ 31 - 1
arch/i386/kernel/cpu/cpufreq/speedstep-lib.c

@@ -320,11 +320,13 @@ EXPORT_SYMBOL_GPL(speedstep_detect_processor);
 unsigned int speedstep_get_freqs(unsigned int processor,
 unsigned int speedstep_get_freqs(unsigned int processor,
 				  unsigned int *low_speed,
 				  unsigned int *low_speed,
 				  unsigned int *high_speed,
 				  unsigned int *high_speed,
+				  unsigned int *transition_latency,
 				  void (*set_state) (unsigned int state))
 				  void (*set_state) (unsigned int state))
 {
 {
 	unsigned int prev_speed;
 	unsigned int prev_speed;
 	unsigned int ret = 0;
 	unsigned int ret = 0;
 	unsigned long flags;
 	unsigned long flags;
+	struct timeval tv1, tv2;
 
 
 	if ((!processor) || (!low_speed) || (!high_speed) || (!set_state))
 	if ((!processor) || (!low_speed) || (!high_speed) || (!set_state))
 		return -EINVAL;
 		return -EINVAL;
@@ -337,7 +339,7 @@ unsigned int speedstep_get_freqs(unsigned int processor,
 		return -EIO;
 		return -EIO;
 
 
 	dprintk("previous speed is %u\n", prev_speed);
 	dprintk("previous speed is %u\n", prev_speed);
-	
+
 	local_irq_save(flags);
 	local_irq_save(flags);
 
 
 	/* switch to low state */
 	/* switch to low state */
@@ -350,8 +352,17 @@ unsigned int speedstep_get_freqs(unsigned int processor,
 
 
 	dprintk("low speed is %u\n", *low_speed);
 	dprintk("low speed is %u\n", *low_speed);
 
 
+	/* start latency measurement */
+	if (transition_latency)
+		do_gettimeofday(&tv1);
+
 	/* switch to high state */
 	/* switch to high state */
 	set_state(SPEEDSTEP_HIGH);
 	set_state(SPEEDSTEP_HIGH);
+
+	/* end latency measurement */
+	if (transition_latency)
+		do_gettimeofday(&tv2);
+
 	*high_speed = speedstep_get_processor_frequency(processor);
 	*high_speed = speedstep_get_processor_frequency(processor);
 	if (!*high_speed) {
 	if (!*high_speed) {
 		ret = -EIO;
 		ret = -EIO;
@@ -369,6 +380,25 @@ unsigned int speedstep_get_freqs(unsigned int processor,
 	if (*high_speed != prev_speed)
 	if (*high_speed != prev_speed)
 		set_state(SPEEDSTEP_LOW);
 		set_state(SPEEDSTEP_LOW);
 
 
+	if (transition_latency) {
+		*transition_latency = (tv2.tv_sec - tv1.tv_sec) * USEC_PER_SEC +
+			tv2.tv_usec - tv1.tv_usec;
+		dprintk("transition latency is %u uSec\n", *transition_latency);
+
+		/* convert uSec to nSec and add 20% for safety reasons */
+		*transition_latency *= 1200;
+
+		/* check if the latency measurement is too high or too low
+		 * and set it to a safe value (500uSec) in that case
+		 */
+		if (*transition_latency > 10000000 || *transition_latency < 50000) {
+			printk (KERN_WARNING "speedstep: frequency transition measured seems out of "
+					"range (%u nSec), falling back to a safe one of %u nSec.\n",
+					*transition_latency, 500000);
+			*transition_latency = 500000;
+		}
+	}
+
  out:
  out:
 	local_irq_restore(flags);
 	local_irq_restore(flags);
 	return (ret);
 	return (ret);

+ 1 - 0
arch/i386/kernel/cpu/cpufreq/speedstep-lib.h

@@ -44,4 +44,5 @@ extern unsigned int speedstep_get_processor_frequency(unsigned int processor);
 extern unsigned int speedstep_get_freqs(unsigned int processor,
 extern unsigned int speedstep_get_freqs(unsigned int processor,
 	  unsigned int *low_speed,
 	  unsigned int *low_speed,
 	  unsigned int *high_speed,
 	  unsigned int *high_speed,
+	  unsigned int *transition_latency,
 	  void (*set_state) (unsigned int state));
 	  void (*set_state) (unsigned int state));

+ 1 - 0
arch/i386/kernel/cpu/cpufreq/speedstep-smi.c

@@ -269,6 +269,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
 		result = speedstep_get_freqs(speedstep_processor,
 		result = speedstep_get_freqs(speedstep_processor,
 				&speedstep_freqs[SPEEDSTEP_LOW].frequency,
 				&speedstep_freqs[SPEEDSTEP_LOW].frequency,
 				&speedstep_freqs[SPEEDSTEP_HIGH].frequency,
 				&speedstep_freqs[SPEEDSTEP_HIGH].frequency,
+				NULL,
 				&speedstep_set_state);
 				&speedstep_set_state);
 
 
 		if (result) {
 		if (result) {

+ 26 - 1
arch/i386/kernel/cpu/cyrix.c

@@ -342,6 +342,31 @@ static void __init init_cyrix(struct cpuinfo_x86 *c)
 	return;
 	return;
 }
 }
 
 
+/*
+ * Handle National Semiconductor branded processors
+ */
+static void __devinit init_nsc(struct cpuinfo_x86 *c)
+{
+	/* There may be GX1 processors in the wild that are branded
+	 * NSC and not Cyrix.
+	 *
+	 * This function only handles the GX processor, and kicks every
+	 * thing else to the Cyrix init function above - that should
+	 * cover any processors that might have been branded differently
+	 * after NSC aquired Cyrix.
+	 *
+	 * If this breaks your GX1 horribly, please e-mail
+	 * info-linux@ldcmail.amd.com to tell us.
+	 */
+
+	/* Handle the GX (Formally known as the GX2) */
+
+	if (c->x86 == 5 && c->x86_model == 5)
+		display_cacheinfo(c);
+	else
+		init_cyrix(c);
+}
+
 /*
 /*
  * Cyrix CPUs without cpuid or with cpuid not yet enabled can be detected
  * Cyrix CPUs without cpuid or with cpuid not yet enabled can be detected
  * by the fact that they preserve the flags across the division of 5/2.
  * by the fact that they preserve the flags across the division of 5/2.
@@ -422,7 +447,7 @@ int __init cyrix_init_cpu(void)
 static struct cpu_dev nsc_cpu_dev __initdata = {
 static struct cpu_dev nsc_cpu_dev __initdata = {
 	.c_vendor	= "NSC",
 	.c_vendor	= "NSC",
 	.c_ident 	= { "Geode by NSC" },
 	.c_ident 	= { "Geode by NSC" },
-	.c_init		= init_cyrix,
+	.c_init		= init_nsc,
 	.c_identify	= generic_identify,
 	.c_identify	= generic_identify,
 };
 };
 
 

+ 5 - 1
arch/i386/kernel/cpu/proc.c

@@ -3,6 +3,7 @@
 #include <linux/string.h>
 #include <linux/string.h>
 #include <asm/semaphore.h>
 #include <asm/semaphore.h>
 #include <linux/seq_file.h>
 #include <linux/seq_file.h>
+#include <linux/cpufreq.h>
 
 
 /*
 /*
  *	Get CPU information for use by the procfs.
  *	Get CPU information for use by the procfs.
@@ -86,8 +87,11 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 		seq_printf(m, "stepping\t: unknown\n");
 		seq_printf(m, "stepping\t: unknown\n");
 
 
 	if ( cpu_has(c, X86_FEATURE_TSC) ) {
 	if ( cpu_has(c, X86_FEATURE_TSC) ) {
+		unsigned int freq = cpufreq_quick_get(n);
+		if (!freq)
+			freq = cpu_khz;
 		seq_printf(m, "cpu MHz\t\t: %u.%03u\n",
 		seq_printf(m, "cpu MHz\t\t: %u.%03u\n",
-			cpu_khz / 1000, (cpu_khz % 1000));
+			freq / 1000, (freq % 1000));
 	}
 	}
 
 
 	/* Cache size */
 	/* Cache size */

+ 1 - 2
arch/i386/kernel/cpuid.c

@@ -117,14 +117,13 @@ static ssize_t cpuid_read(struct file *file, char __user *buf,
 {
 {
 	char __user *tmp = buf;
 	char __user *tmp = buf;
 	u32 data[4];
 	u32 data[4];
-	size_t rv;
 	u32 reg = *ppos;
 	u32 reg = *ppos;
 	int cpu = iminor(file->f_dentry->d_inode);
 	int cpu = iminor(file->f_dentry->d_inode);
 
 
 	if (count % 16)
 	if (count % 16)
 		return -EINVAL;	/* Invalid chunk size */
 		return -EINVAL;	/* Invalid chunk size */
 
 
-	for (rv = 0; count; count -= 16) {
+	for (; count; count -= 16) {
 		do_cpuid(cpu, reg, data);
 		do_cpuid(cpu, reg, data);
 		if (copy_to_user(tmp, &data, 16))
 		if (copy_to_user(tmp, &data, 16))
 			return -EFAULT;
 			return -EFAULT;

+ 1 - 0
arch/i386/kernel/entry.S

@@ -657,6 +657,7 @@ ENTRY(spurious_interrupt_bug)
 	pushl $do_spurious_interrupt_bug
 	pushl $do_spurious_interrupt_bug
 	jmp error_code
 	jmp error_code
 
 
+.section .rodata,"a"
 #include "syscall_table.S"
 #include "syscall_table.S"
 
 
 syscall_table_size=(.-sys_call_table)
 syscall_table_size=(.-sys_call_table)

+ 17 - 10
arch/i386/kernel/head.S

@@ -504,19 +504,24 @@ ENTRY(cpu_gdt_table)
 	.quad 0x0000000000000000	/* 0x80 TSS descriptor */
 	.quad 0x0000000000000000	/* 0x80 TSS descriptor */
 	.quad 0x0000000000000000	/* 0x88 LDT descriptor */
 	.quad 0x0000000000000000	/* 0x88 LDT descriptor */
 
 
-	/* Segments used for calling PnP BIOS */
-	.quad 0x00c09a0000000000	/* 0x90 32-bit code */
-	.quad 0x00809a0000000000	/* 0x98 16-bit code */
-	.quad 0x0080920000000000	/* 0xa0 16-bit data */
-	.quad 0x0080920000000000	/* 0xa8 16-bit data */
-	.quad 0x0080920000000000	/* 0xb0 16-bit data */
+	/*
+	 * Segments used for calling PnP BIOS have byte granularity.
+	 * They code segments and data segments have fixed 64k limits,
+	 * the transfer segment sizes are set at run time.
+	 */
+	.quad 0x00409a000000ffff	/* 0x90 32-bit code */
+	.quad 0x00009a000000ffff	/* 0x98 16-bit code */
+	.quad 0x000092000000ffff	/* 0xa0 16-bit data */
+	.quad 0x0000920000000000	/* 0xa8 16-bit data */
+	.quad 0x0000920000000000	/* 0xb0 16-bit data */
+
 	/*
 	/*
 	 * The APM segments have byte granularity and their bases
 	 * The APM segments have byte granularity and their bases
-	 * and limits are set at run time.
+	 * are set at run time.  All have 64k limits.
 	 */
 	 */
-	.quad 0x00409a0000000000	/* 0xb8 APM CS    code */
-	.quad 0x00009a0000000000	/* 0xc0 APM CS 16 code (16 bit) */
-	.quad 0x0040920000000000	/* 0xc8 APM DS    data */
+	.quad 0x00409a000000ffff	/* 0xb8 APM CS    code */
+	.quad 0x00009a000000ffff	/* 0xc0 APM CS 16 code (16 bit) */
+	.quad 0x004092000000ffff	/* 0xc8 APM DS    data */
 
 
 	.quad 0x0000920000000000	/* 0xd0 - ESPFIX 16-bit SS */
 	.quad 0x0000920000000000	/* 0xd0 - ESPFIX 16-bit SS */
 	.quad 0x0000000000000000	/* 0xd8 - unused */
 	.quad 0x0000000000000000	/* 0xd8 - unused */
@@ -525,3 +530,5 @@ ENTRY(cpu_gdt_table)
 	.quad 0x0000000000000000	/* 0xf0 - unused */
 	.quad 0x0000000000000000	/* 0xf0 - unused */
 	.quad 0x0000000000000000	/* 0xf8 - GDT entry 31: double-fault TSS */
 	.quad 0x0000000000000000	/* 0xf8 - GDT entry 31: double-fault TSS */
 
 
+	/* Be sure this is zeroed to avoid false validations in Xen */
+	.fill PAGE_SIZE_asm / 8 - GDT_ENTRIES,8,0

+ 1 - 2
arch/i386/kernel/i386_ksyms.c

@@ -3,8 +3,7 @@
 #include <asm/checksum.h>
 #include <asm/checksum.h>
 #include <asm/desc.h>
 #include <asm/desc.h>
 
 
-/* This is definitely a GPL-only symbol */
-EXPORT_SYMBOL_GPL(cpu_gdt_table);
+EXPORT_SYMBOL_GPL(cpu_gdt_descr);
 
 
 EXPORT_SYMBOL(__down_failed);
 EXPORT_SYMBOL(__down_failed);
 EXPORT_SYMBOL(__down_failed_interruptible);
 EXPORT_SYMBOL(__down_failed_interruptible);

+ 2 - 2
arch/i386/kernel/io_apic.c

@@ -1722,8 +1722,8 @@ void disable_IO_APIC(void)
 		entry.dest_mode       = 0; /* Physical */
 		entry.dest_mode       = 0; /* Physical */
 		entry.delivery_mode   = dest_ExtINT; /* ExtInt */
 		entry.delivery_mode   = dest_ExtINT; /* ExtInt */
 		entry.vector          = 0;
 		entry.vector          = 0;
-		entry.dest.physical.physical_dest = 0;
-
+		entry.dest.physical.physical_dest =
+					GET_APIC_ID(apic_read(APIC_ID));
 
 
 		/*
 		/*
 		 * Add it to the IO-APIC irq-routing table:
 		 * Add it to the IO-APIC irq-routing table:

+ 18 - 8
arch/i386/kernel/mpparse.c

@@ -38,6 +38,12 @@
 int smp_found_config;
 int smp_found_config;
 unsigned int __initdata maxcpus = NR_CPUS;
 unsigned int __initdata maxcpus = NR_CPUS;
 
 
+#ifdef CONFIG_HOTPLUG_CPU
+#define CPU_HOTPLUG_ENABLED	(1)
+#else
+#define CPU_HOTPLUG_ENABLED	(0)
+#endif
+
 /*
 /*
  * Various Linux-internal data structures created from the
  * Various Linux-internal data structures created from the
  * MP-table.
  * MP-table.
@@ -219,14 +225,18 @@ static void __devinit MP_processor_info (struct mpc_config_processor *m)
 	cpu_set(num_processors, cpu_possible_map);
 	cpu_set(num_processors, cpu_possible_map);
 	num_processors++;
 	num_processors++;
 
 
-	if ((num_processors > 8) &&
-	    ((APIC_XAPIC(ver) &&
-	     (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)) ||
-	     (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)))
-		def_to_bigsmp = 1;
-	else
-		def_to_bigsmp = 0;
-
+	if (CPU_HOTPLUG_ENABLED || (num_processors > 8)) {
+		switch (boot_cpu_data.x86_vendor) {
+		case X86_VENDOR_INTEL:
+			if (!APIC_XAPIC(ver)) {
+				def_to_bigsmp = 0;
+				break;
+			}
+			/* If P4 and above fall through */
+		case X86_VENDOR_AMD:
+			def_to_bigsmp = 1;
+		}
+	}
 	bios_cpu_apicid[num_processors - 1] = m->mpc_apicid;
 	bios_cpu_apicid[num_processors - 1] = m->mpc_apicid;
 }
 }
 
 

+ 1 - 2
arch/i386/kernel/msr.c

@@ -172,7 +172,6 @@ static ssize_t msr_read(struct file *file, char __user * buf,
 {
 {
 	u32 __user *tmp = (u32 __user *) buf;
 	u32 __user *tmp = (u32 __user *) buf;
 	u32 data[2];
 	u32 data[2];
-	size_t rv;
 	u32 reg = *ppos;
 	u32 reg = *ppos;
 	int cpu = iminor(file->f_dentry->d_inode);
 	int cpu = iminor(file->f_dentry->d_inode);
 	int err;
 	int err;
@@ -180,7 +179,7 @@ static ssize_t msr_read(struct file *file, char __user * buf,
 	if (count % 8)
 	if (count % 8)
 		return -EINVAL;	/* Invalid chunk size */
 		return -EINVAL;	/* Invalid chunk size */
 
 
-	for (rv = 0; count; count -= 8) {
+	for (; count; count -= 8) {
 		err = do_rdmsr(cpu, reg, &data[0], &data[1]);
 		err = do_rdmsr(cpu, reg, &data[0], &data[1]);
 		if (err)
 		if (err)
 			return err;
 			return err;

+ 2 - 14
arch/i386/kernel/process.c

@@ -308,9 +308,7 @@ void show_regs(struct pt_regs * regs)
 	cr0 = read_cr0();
 	cr0 = read_cr0();
 	cr2 = read_cr2();
 	cr2 = read_cr2();
 	cr3 = read_cr3();
 	cr3 = read_cr3();
-	if (current_cpu_data.x86 > 4) {
-		cr4 = read_cr4();
-	}
+	cr4 = read_cr4_safe();
 	printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4);
 	printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4);
 	show_trace(NULL, &regs->esp);
 	show_trace(NULL, &regs->esp);
 }
 }
@@ -404,17 +402,7 @@ void flush_thread(void)
 
 
 void release_thread(struct task_struct *dead_task)
 void release_thread(struct task_struct *dead_task)
 {
 {
-	if (dead_task->mm) {
-		// temporary debugging check
-		if (dead_task->mm->context.size) {
-			printk("WARNING: dead process %8s still has LDT? <%p/%d>\n",
-					dead_task->comm,
-					dead_task->mm->context.ldt,
-					dead_task->mm->context.size);
-			BUG();
-		}
-	}
-
+	BUG_ON(dead_task->mm);
 	release_vm86_irqs(dead_task);
 	release_vm86_irqs(dead_task);
 }
 }
 
 

+ 6 - 3
arch/i386/kernel/ptrace.c

@@ -32,9 +32,12 @@
  * in exit.c or in signal.c.
  * in exit.c or in signal.c.
  */
  */
 
 
-/* determines which flags the user has access to. */
-/* 1 = access 0 = no access */
-#define FLAG_MASK 0x00044dd5
+/*
+ * Determines which flags the user has access to [1 = access, 0 = no access].
+ * Prohibits changing ID(21), VIP(20), VIF(19), VM(17), IOPL(12-13), IF(9).
+ * Also masks reserved bits (31-22, 15, 5, 3, 1).
+ */
+#define FLAG_MASK 0x00054dd5
 
 
 /* set's the trap flag. */
 /* set's the trap flag. */
 #define TRAP_FLAG 0x100
 #define TRAP_FLAG 0x100

+ 3 - 3
arch/i386/kernel/reboot.c

@@ -111,12 +111,12 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2400"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2400"),
 		},
 		},
 	},
 	},
-	{	/* Handle problems with rebooting on HP nc6120 */
+	{	/* Handle problems with rebooting on HP laptops */
 		.callback = set_bios_reboot,
 		.callback = set_bios_reboot,
-		.ident = "HP Compaq nc6120",
+		.ident = "HP Compaq Laptop",
 		.matches = {
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
 			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nc6120"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"),
 		},
 		},
 	},
 	},
 	{ }
 	{ }

+ 8 - 0
arch/i386/kernel/setup.c

@@ -954,6 +954,12 @@ efi_find_max_pfn(unsigned long start, unsigned long end, void *arg)
 	return 0;
 	return 0;
 }
 }
 
 
+static int __init
+efi_memory_present_wrapper(unsigned long start, unsigned long end, void *arg)
+{
+	memory_present(0, start, end);
+	return 0;
+}
 
 
 /*
 /*
  * Find the highest page frame number we have available
  * Find the highest page frame number we have available
@@ -965,6 +971,7 @@ void __init find_max_pfn(void)
 	max_pfn = 0;
 	max_pfn = 0;
 	if (efi_enabled) {
 	if (efi_enabled) {
 		efi_memmap_walk(efi_find_max_pfn, &max_pfn);
 		efi_memmap_walk(efi_find_max_pfn, &max_pfn);
+		efi_memmap_walk(efi_memory_present_wrapper, NULL);
 		return;
 		return;
 	}
 	}
 
 
@@ -979,6 +986,7 @@ void __init find_max_pfn(void)
 			continue;
 			continue;
 		if (end > max_pfn)
 		if (end > max_pfn)
 			max_pfn = end;
 			max_pfn = end;
+		memory_present(0, start, end);
 	}
 	}
 }
 }
 
 

+ 6 - 0
arch/i386/kernel/smpboot.c

@@ -903,6 +903,12 @@ static int __devinit do_boot_cpu(int apicid, int cpu)
 	unsigned long start_eip;
 	unsigned long start_eip;
 	unsigned short nmi_high = 0, nmi_low = 0;
 	unsigned short nmi_high = 0, nmi_low = 0;
 
 
+	if (!cpu_gdt_descr[cpu].address &&
+	    !(cpu_gdt_descr[cpu].address = get_zeroed_page(GFP_KERNEL))) {
+		printk("Failed to allocate GDT for CPU %d\n", cpu);
+		return 1;
+	}
+
 	++cpucount;
 	++cpucount;
 
 
 	/*
 	/*

+ 0 - 1
arch/i386/kernel/syscall_table.S

@@ -1,4 +1,3 @@
-.data
 ENTRY(sys_call_table)
 ENTRY(sys_call_table)
 	.long sys_restart_syscall	/* 0 - old "setup()" system call, used for restarting */
 	.long sys_restart_syscall	/* 0 - old "setup()" system call, used for restarting */
 	.long sys_exit
 	.long sys_exit

+ 2 - 0
arch/i386/kernel/timers/timer_tsc.c

@@ -330,7 +330,9 @@ int recalibrate_cpu_khz(void)
 	unsigned int cpu_khz_old = cpu_khz;
 	unsigned int cpu_khz_old = cpu_khz;
 
 
 	if (cpu_has_tsc) {
 	if (cpu_has_tsc) {
+		local_irq_disable();
 		init_cpu_khz();
 		init_cpu_khz();
+		local_irq_enable();
 		cpu_data[0].loops_per_jiffy =
 		cpu_data[0].loops_per_jiffy =
 		    cpufreq_scale(cpu_data[0].loops_per_jiffy,
 		    cpufreq_scale(cpu_data[0].loops_per_jiffy,
 			          cpu_khz_old,
 			          cpu_khz_old,

+ 30 - 5
arch/i386/kernel/traps.c

@@ -306,14 +306,17 @@ void die(const char * str, struct pt_regs * regs, long err)
 		.lock_owner_depth =	0
 		.lock_owner_depth =	0
 	};
 	};
 	static int die_counter;
 	static int die_counter;
+	unsigned long flags;
 
 
 	if (die.lock_owner != raw_smp_processor_id()) {
 	if (die.lock_owner != raw_smp_processor_id()) {
 		console_verbose();
 		console_verbose();
-		spin_lock_irq(&die.lock);
+		spin_lock_irqsave(&die.lock, flags);
 		die.lock_owner = smp_processor_id();
 		die.lock_owner = smp_processor_id();
 		die.lock_owner_depth = 0;
 		die.lock_owner_depth = 0;
 		bust_spinlocks(1);
 		bust_spinlocks(1);
 	}
 	}
+	else
+		local_save_flags(flags);
 
 
 	if (++die.lock_owner_depth < 3) {
 	if (++die.lock_owner_depth < 3) {
 		int nl = 0;
 		int nl = 0;
@@ -340,7 +343,7 @@ void die(const char * str, struct pt_regs * regs, long err)
 
 
 	bust_spinlocks(0);
 	bust_spinlocks(0);
 	die.lock_owner = -1;
 	die.lock_owner = -1;
-	spin_unlock_irq(&die.lock);
+	spin_unlock_irqrestore(&die.lock, flags);
 
 
 	if (kexec_should_crash(current))
 	if (kexec_should_crash(current))
 		crash_kexec(regs);
 		crash_kexec(regs);
@@ -452,7 +455,7 @@ DO_VM86_ERROR( 3, SIGTRAP, "int3", int3)
 #endif
 #endif
 DO_VM86_ERROR( 4, SIGSEGV, "overflow", overflow)
 DO_VM86_ERROR( 4, SIGSEGV, "overflow", overflow)
 DO_VM86_ERROR( 5, SIGSEGV, "bounds", bounds)
 DO_VM86_ERROR( 5, SIGSEGV, "bounds", bounds)
-DO_ERROR_INFO( 6, SIGILL,  "invalid operand", invalid_op, ILL_ILLOPN, regs->eip)
+DO_ERROR_INFO( 6, SIGILL,  "invalid opcode", invalid_op, ILL_ILLOPN, regs->eip)
 DO_ERROR( 9, SIGFPE,  "coprocessor segment overrun", coprocessor_segment_overrun)
 DO_ERROR( 9, SIGFPE,  "coprocessor segment overrun", coprocessor_segment_overrun)
 DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
 DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
 DO_ERROR(11, SIGBUS,  "segment not present", segment_not_present)
 DO_ERROR(11, SIGBUS,  "segment not present", segment_not_present)
@@ -1075,9 +1078,9 @@ void __init trap_init(void)
 	set_trap_gate(0,&divide_error);
 	set_trap_gate(0,&divide_error);
 	set_intr_gate(1,&debug);
 	set_intr_gate(1,&debug);
 	set_intr_gate(2,&nmi);
 	set_intr_gate(2,&nmi);
-	set_system_intr_gate(3, &int3); /* int3-5 can be called from all */
+	set_system_intr_gate(3, &int3); /* int3/4 can be called from all */
 	set_system_gate(4,&overflow);
 	set_system_gate(4,&overflow);
-	set_system_gate(5,&bounds);
+	set_trap_gate(5,&bounds);
 	set_trap_gate(6,&invalid_op);
 	set_trap_gate(6,&invalid_op);
 	set_trap_gate(7,&device_not_available);
 	set_trap_gate(7,&device_not_available);
 	set_task_gate(8,GDT_ENTRY_DOUBLEFAULT_TSS);
 	set_task_gate(8,GDT_ENTRY_DOUBLEFAULT_TSS);
@@ -1095,6 +1098,28 @@ void __init trap_init(void)
 #endif
 #endif
 	set_trap_gate(19,&simd_coprocessor_error);
 	set_trap_gate(19,&simd_coprocessor_error);
 
 
+	if (cpu_has_fxsr) {
+		/*
+		 * Verify that the FXSAVE/FXRSTOR data will be 16-byte aligned.
+		 * Generates a compile-time "error: zero width for bit-field" if
+		 * the alignment is wrong.
+		 */
+		struct fxsrAlignAssert {
+			int _:!(offsetof(struct task_struct,
+					thread.i387.fxsave) & 15);
+		};
+
+		printk(KERN_INFO "Enabling fast FPU save and restore... ");
+		set_in_cr4(X86_CR4_OSFXSR);
+		printk("done.\n");
+	}
+	if (cpu_has_xmm) {
+		printk(KERN_INFO "Enabling unmasked SIMD FPU exception "
+				"support... ");
+		set_in_cr4(X86_CR4_OSXMMEXCPT);
+		printk("done.\n");
+	}
+
 	set_system_gate(SYSCALL_VECTOR,&system_call);
 	set_system_gate(SYSCALL_VECTOR,&system_call);
 
 
 	/*
 	/*

+ 24 - 0
arch/i386/mm/init.c

@@ -735,6 +735,30 @@ void free_initmem(void)
 	printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (__init_end - __init_begin) >> 10);
 	printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (__init_end - __init_begin) >> 10);
 }
 }
 
 
+#ifdef CONFIG_DEBUG_RODATA
+
+extern char __start_rodata, __end_rodata;
+void mark_rodata_ro(void)
+{
+	unsigned long addr = (unsigned long)&__start_rodata;
+
+	for (; addr < (unsigned long)&__end_rodata; addr += PAGE_SIZE)
+		change_page_attr(virt_to_page(addr), 1, PAGE_KERNEL_RO);
+
+	printk ("Write protecting the kernel read-only data: %luk\n",
+			(unsigned long)(&__end_rodata - &__start_rodata) >> 10);
+
+	/*
+	 * change_page_attr() requires a global_flush_tlb() call after it.
+	 * We do this after the printk so that if something went wrong in the
+	 * change, the printk gets out at least to give a better debug hint
+	 * of who is the culprit.
+	 */
+	global_flush_tlb();
+}
+#endif
+
+
 #ifdef CONFIG_BLK_DEV_INITRD
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
 {

+ 21 - 6
arch/i386/mm/pageattr.c

@@ -13,6 +13,7 @@
 #include <asm/processor.h>
 #include <asm/processor.h>
 #include <asm/tlbflush.h>
 #include <asm/tlbflush.h>
 #include <asm/pgalloc.h>
 #include <asm/pgalloc.h>
+#include <asm/sections.h>
 
 
 static DEFINE_SPINLOCK(cpa_lock);
 static DEFINE_SPINLOCK(cpa_lock);
 static struct list_head df_list = LIST_HEAD_INIT(df_list);
 static struct list_head df_list = LIST_HEAD_INIT(df_list);
@@ -36,7 +37,8 @@ pte_t *lookup_address(unsigned long address)
         return pte_offset_kernel(pmd, address);
         return pte_offset_kernel(pmd, address);
 } 
 } 
 
 
-static struct page *split_large_page(unsigned long address, pgprot_t prot)
+static struct page *split_large_page(unsigned long address, pgprot_t prot,
+					pgprot_t ref_prot)
 { 
 { 
 	int i; 
 	int i; 
 	unsigned long addr;
 	unsigned long addr;
@@ -54,7 +56,7 @@ static struct page *split_large_page(unsigned long address, pgprot_t prot)
 	pbase = (pte_t *)page_address(base);
 	pbase = (pte_t *)page_address(base);
 	for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE) {
 	for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE) {
                set_pte(&pbase[i], pfn_pte(addr >> PAGE_SHIFT,
                set_pte(&pbase[i], pfn_pte(addr >> PAGE_SHIFT,
-                                          addr == address ? prot : PAGE_KERNEL));
+                                          addr == address ? prot : ref_prot));
 	}
 	}
 	return base;
 	return base;
 } 
 } 
@@ -98,11 +100,18 @@ static void set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte)
  */
  */
 static inline void revert_page(struct page *kpte_page, unsigned long address)
 static inline void revert_page(struct page *kpte_page, unsigned long address)
 {
 {
-	pte_t *linear = (pte_t *) 
+	pgprot_t ref_prot;
+	pte_t *linear;
+
+	ref_prot =
+	((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
+		? PAGE_KERNEL_LARGE_EXEC : PAGE_KERNEL_LARGE;
+
+	linear = (pte_t *)
 		pmd_offset(pud_offset(pgd_offset_k(address), address), address);
 		pmd_offset(pud_offset(pgd_offset_k(address), address), address);
 	set_pmd_pte(linear,  address,
 	set_pmd_pte(linear,  address,
 		    pfn_pte((__pa(address) & LARGE_PAGE_MASK) >> PAGE_SHIFT,
 		    pfn_pte((__pa(address) & LARGE_PAGE_MASK) >> PAGE_SHIFT,
-			    PAGE_KERNEL_LARGE));
+			    ref_prot));
 }
 }
 
 
 static int
 static int
@@ -123,10 +132,16 @@ __change_page_attr(struct page *page, pgprot_t prot)
 		if ((pte_val(*kpte) & _PAGE_PSE) == 0) { 
 		if ((pte_val(*kpte) & _PAGE_PSE) == 0) { 
 			set_pte_atomic(kpte, mk_pte(page, prot)); 
 			set_pte_atomic(kpte, mk_pte(page, prot)); 
 		} else {
 		} else {
-			struct page *split = split_large_page(address, prot); 
+			pgprot_t ref_prot;
+			struct page *split;
+
+			ref_prot =
+			((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
+				? PAGE_KERNEL_EXEC : PAGE_KERNEL;
+			split = split_large_page(address, prot, ref_prot);
 			if (!split)
 			if (!split)
 				return -ENOMEM;
 				return -ENOMEM;
-			set_pmd_pte(kpte,address,mk_pte(split, PAGE_KERNEL));
+			set_pmd_pte(kpte,address,mk_pte(split, ref_prot));
 			kpte_page = split;
 			kpte_page = split;
 		}	
 		}	
 		get_page(kpte_page);
 		get_page(kpte_page);

+ 1 - 1
arch/i386/pci/irq.c

@@ -846,7 +846,7 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
 	 * reported by the device if possible.
 	 * reported by the device if possible.
 	 */
 	 */
 	newirq = dev->irq;
 	newirq = dev->irq;
-	if (!((1 << newirq) & mask)) {
+	if (newirq && !((1 << newirq) & mask)) {
 		if ( pci_probe & PCI_USE_PIRQ_MASK) newirq = 0;
 		if ( pci_probe & PCI_USE_PIRQ_MASK) newirq = 0;
 		else printk(KERN_WARNING "PCI: IRQ %i for device %s doesn't match PIRQ mask - try pci=usepirqmask\n", newirq, pci_name(dev));
 		else printk(KERN_WARNING "PCI: IRQ %i for device %s doesn't match PIRQ mask - try pci=usepirqmask\n", newirq, pci_name(dev));
 	}
 	}

+ 7 - 1
arch/ia64/kernel/setup.c

@@ -43,6 +43,7 @@
 #include <linux/initrd.h>
 #include <linux/initrd.h>
 #include <linux/platform.h>
 #include <linux/platform.h>
 #include <linux/pm.h>
 #include <linux/pm.h>
+#include <linux/cpufreq.h>
 
 
 #include <asm/ia32.h>
 #include <asm/ia32.h>
 #include <asm/machvec.h>
 #include <asm/machvec.h>
@@ -517,6 +518,7 @@ show_cpuinfo (struct seq_file *m, void *v)
 	char family[32], features[128], *cp, sep;
 	char family[32], features[128], *cp, sep;
 	struct cpuinfo_ia64 *c = v;
 	struct cpuinfo_ia64 *c = v;
 	unsigned long mask;
 	unsigned long mask;
+	unsigned long proc_freq;
 	int i;
 	int i;
 
 
 	mask = c->features;
 	mask = c->features;
@@ -549,6 +551,10 @@ show_cpuinfo (struct seq_file *m, void *v)
 		sprintf(cp, " 0x%lx", mask);
 		sprintf(cp, " 0x%lx", mask);
 	}
 	}
 
 
+	proc_freq = cpufreq_quick_get(cpunum);
+	if (!proc_freq)
+		proc_freq = c->proc_freq / 1000;
+
 	seq_printf(m,
 	seq_printf(m,
 		   "processor  : %d\n"
 		   "processor  : %d\n"
 		   "vendor     : %s\n"
 		   "vendor     : %s\n"
@@ -565,7 +571,7 @@ show_cpuinfo (struct seq_file *m, void *v)
 		   "BogoMIPS   : %lu.%02lu\n",
 		   "BogoMIPS   : %lu.%02lu\n",
 		   cpunum, c->vendor, family, c->model, c->revision, c->archrev,
 		   cpunum, c->vendor, family, c->model, c->revision, c->archrev,
 		   features, c->ppn, c->number,
 		   features, c->ppn, c->number,
-		   c->proc_freq / 1000000, c->proc_freq % 1000000,
+		   proc_freq / 1000, proc_freq % 1000,
 		   c->itc_freq / 1000000, c->itc_freq % 1000000,
 		   c->itc_freq / 1000000, c->itc_freq % 1000000,
 		   lpj*HZ/500000, (lpj*HZ/5000) % 100);
 		   lpj*HZ/500000, (lpj*HZ/5000) % 100);
 #ifdef CONFIG_SMP
 #ifdef CONFIG_SMP

+ 1 - 1
arch/ia64/pci/pci.c

@@ -700,7 +700,7 @@ int ia64_pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size)
  */
  */
 int ia64_pci_legacy_write(struct pci_dev *bus, u16 port, u32 val, u8 size)
 int ia64_pci_legacy_write(struct pci_dev *bus, u16 port, u32 val, u8 size)
 {
 {
-	int ret = 0;
+	int ret = size;
 
 
 	switch (size) {
 	switch (size) {
 	case 1:
 	case 1:

+ 2 - 2
arch/ia64/sn/kernel/tiocx.c

@@ -65,7 +65,7 @@ static int tiocx_match(struct device *dev, struct device_driver *drv)
 
 
 }
 }
 
 
-static int tiocx_hotplug(struct device *dev, char **envp, int num_envp,
+static int tiocx_uevent(struct device *dev, char **envp, int num_envp,
 			 char *buffer, int buffer_size)
 			 char *buffer, int buffer_size)
 {
 {
 	return -ENODEV;
 	return -ENODEV;
@@ -79,7 +79,7 @@ static void tiocx_bus_release(struct device *dev)
 struct bus_type tiocx_bus_type = {
 struct bus_type tiocx_bus_type = {
 	.name = "tiocx",
 	.name = "tiocx",
 	.match = tiocx_match,
 	.match = tiocx_match,
-	.hotplug = tiocx_hotplug,
+	.uevent = tiocx_uevent,
 };
 };
 
 
 /**
 /**

+ 20 - 6
arch/m32r/Kconfig

@@ -81,6 +81,12 @@ config PLAT_MAPPI2
 config PLAT_MAPPI3
 config PLAT_MAPPI3
        bool "Mappi-III(M3A-2170)"
        bool "Mappi-III(M3A-2170)"
 
 
+config PLAT_M32104UT
+	bool "M32104UT"
+	help
+	  The M3T-M32104UT is an reference board based on uT-Engine
+	  specification.  This board has a M32104 chip.
+
 endchoice
 endchoice
 
 
 choice
 choice
@@ -93,6 +99,10 @@ config CHIP_M32700
 config CHIP_M32102
 config CHIP_M32102
 	bool "M32102"
 	bool "M32102"
 
 
+config CHIP_M32104
+	bool "M32104"
+	depends on PLAT_M32104UT
+
 config CHIP_VDEC2
 config CHIP_VDEC2
        bool "VDEC2"
        bool "VDEC2"
 
 
@@ -115,7 +125,7 @@ config TLB_ENTRIES
 
 
 config ISA_M32R
 config ISA_M32R
         bool
         bool
-	depends on CHIP_M32102
+	depends on CHIP_M32102 || CHIP_M32104
 	default y
 	default y
 
 
 config ISA_M32R2
 config ISA_M32R2
@@ -140,6 +150,7 @@ config BUS_CLOCK
 	default "50000000" if PLAT_MAPPI3
 	default "50000000" if PLAT_MAPPI3
 	default "50000000" if PLAT_M32700UT
 	default "50000000" if PLAT_M32700UT
 	default "50000000" if PLAT_OPSPUT
 	default "50000000" if PLAT_OPSPUT
+	default "54000000" if PLAT_M32104UT
 	default "33333333" if PLAT_OAKS32R
 	default "33333333" if PLAT_OAKS32R
 	default "20000000" if PLAT_MAPPI2
 	default "20000000" if PLAT_MAPPI2
 
 
@@ -157,6 +168,7 @@ config MEMORY_START
 	default "08000000" if PLAT_USRV
 	default "08000000" if PLAT_USRV
 	default "08000000" if PLAT_M32700UT
 	default "08000000" if PLAT_M32700UT
 	default "08000000" if PLAT_OPSPUT
 	default "08000000" if PLAT_OPSPUT
+	default "04000000" if PLAT_M32104UT
 	default "01000000" if PLAT_OAKS32R
 	default "01000000" if PLAT_OAKS32R
 
 
 config MEMORY_SIZE
 config MEMORY_SIZE
@@ -166,6 +178,7 @@ config MEMORY_SIZE
 	default "02000000" if PLAT_USRV
 	default "02000000" if PLAT_USRV
 	default "01000000" if PLAT_M32700UT
 	default "01000000" if PLAT_M32700UT
 	default "01000000" if PLAT_OPSPUT
 	default "01000000" if PLAT_OPSPUT
+	default "01000000" if PLAT_M32104UT
 	default "00800000" if PLAT_OAKS32R
 	default "00800000" if PLAT_OAKS32R
 
 
 config NOHIGHMEM
 config NOHIGHMEM
@@ -174,21 +187,22 @@ config NOHIGHMEM
 
 
 config ARCH_DISCONTIGMEM_ENABLE
 config ARCH_DISCONTIGMEM_ENABLE
 	bool "Internal RAM Support"
 	bool "Internal RAM Support"
-	depends on CHIP_M32700 || CHIP_M32102 || CHIP_VDEC2 || CHIP_OPSP
+	depends on CHIP_M32700 || CHIP_M32102 || CHIP_VDEC2 || CHIP_OPSP || CHIP_M32104
 	default y
 	default y
 
 
 source "mm/Kconfig"
 source "mm/Kconfig"
 
 
 config IRAM_START
 config IRAM_START
 	hex "Internal memory start address (hex)"
 	hex "Internal memory start address (hex)"
-	default "00f00000"
-	depends on (CHIP_M32700 || CHIP_M32102 || CHIP_VDEC2 || CHIP_OPSP) && DISCONTIGMEM
+	default "00f00000" if !CHIP_M32104
+	default "00700000" if CHIP_M32104
+	depends on (CHIP_M32700 || CHIP_M32102 || CHIP_VDEC2 || CHIP_OPSP || CHIP_M32104) && DISCONTIGMEM
 
 
 config IRAM_SIZE
 config IRAM_SIZE
 	hex "Internal memory size (hex)"
 	hex "Internal memory size (hex)"
-	depends on (CHIP_M32700 || CHIP_M32102 || CHIP_VDEC2 || CHIP_OPSP) && DISCONTIGMEM
+	depends on (CHIP_M32700 || CHIP_M32102 || CHIP_VDEC2 || CHIP_OPSP || CHIP_M32104) && DISCONTIGMEM
 	default "00080000" if CHIP_M32700
 	default "00080000" if CHIP_M32700
-	default "00010000" if CHIP_M32102 || CHIP_OPSP
+	default "00010000" if CHIP_M32102 || CHIP_OPSP || CHIP_M32104
 	default "00008000" if CHIP_VDEC2
 	default "00008000" if CHIP_VDEC2
 
 
 #
 #

+ 5 - 0
arch/m32r/boot/compressed/head.S

@@ -143,6 +143,11 @@ startup:
 	ldi	r0, -2
 	ldi	r0, -2
 	ldi	r1, 0x0100	; invalidate
 	ldi	r1, 0x0100	; invalidate
 	stb	r1, @r0
 	stb	r1, @r0
+#elif defined(CONFIG_CHIP_M32104)
+	/* Cache flush */
+	ldi	r0, -2
+	ldi	r1, 0x0700	; invalidate i-cache, copy back d-cache
+	sth	r1, @r0
 #else
 #else
 #error "put your cache flush function, please"
 #error "put your cache flush function, please"
 #endif
 #endif

+ 21 - 3
arch/m32r/boot/setup.S

@@ -1,11 +1,10 @@
 /*
 /*
  *  linux/arch/m32r/boot/setup.S -- A setup code.
  *  linux/arch/m32r/boot/setup.S -- A setup code.
  *
  *
- *  Copyright (C) 2001, 2002  Hiroyuki Kondo, Hirokazu Takata,
- *  and Hitoshi Yamamoto
+ *  Copyright (C) 2001-2005   Hiroyuki Kondo, Hirokazu Takata,
+ *                            Hitoshi Yamamoto, Hayato Fujiwara
  *
  *
  */
  */
-/* $Id$ */
 
 
 #include <linux/linkage.h>
 #include <linux/linkage.h>
 #include <asm/segment.h>
 #include <asm/segment.h>
@@ -80,6 +79,20 @@ ENTRY(boot)
 	ldi	r1, #0x101		; cache on (with invalidation)
 	ldi	r1, #0x101		; cache on (with invalidation)
 ;	ldi	r1, #0x00		; cache off
 ;	ldi	r1, #0x00		; cache off
 	st	r1, @r0
 	st	r1, @r0
+#elif defined(CONFIG_CHIP_M32104)
+	ldi	r0, #-96		; DNCR0
+	seth	r1, #0x0060		;  from 0x00600000
+	or3	r1, r1, #0x0005		;  size 2MB
+	st	r1, @r0
+	seth	r1, #0x0100		;  from 0x01000000
+	or3	r1, r1, #0x0003		;  size 16MB
+	st	r1, @+r0
+	seth	r1, #0x0200		;  from 0x02000000
+	or3	r1, r1, #0x0002		;  size 32MB
+	st	r1, @+r0
+	ldi	r0, #-4              ;LDIMM	(r0, M32R_MCCR)
+	ldi	r1, #0x703		; cache on (with invalidation)
+	st	r1, @r0
 #else
 #else
 #error unknown chip configuration
 #error unknown chip configuration
 #endif
 #endif
@@ -115,10 +128,15 @@ mmu_on:
 	st      r1, @(MATM_offset,r0)		; Set MATM (T bit ON)
 	st      r1, @(MATM_offset,r0)		; Set MATM (T bit ON)
 	ld      r0, @(MATM_offset,r0)		; Check
 	ld      r0, @(MATM_offset,r0)		; Check
 #else
 #else
+#if defined(CONFIG_CHIP_M32700)
 	seth	r0,#high(M32R_MCDCAR)
 	seth	r0,#high(M32R_MCDCAR)
 	or3	r0,r0,#low(M32R_MCDCAR)
 	or3	r0,r0,#low(M32R_MCDCAR)
 	ld24	r1,#0x8080
 	ld24	r1,#0x8080
 	st	r1,@r0
 	st	r1,@r0
+#elif defined(CONFIG_CHIP_M32104)
+	LDIMM	(r2, eit_vector)		; set EVB(cr5)
+	mvtc    r2, cr5
+#endif
 #endif	/* CONFIG_MMU */
 #endif	/* CONFIG_MMU */
 	jmp	r13
 	jmp	r13
 	nop
 	nop

+ 1 - 0
arch/m32r/kernel/Makefile

@@ -16,5 +16,6 @@ obj-$(CONFIG_PLAT_M32700UT)	+= setup_m32700ut.o io_m32700ut.o
 obj-$(CONFIG_PLAT_OPSPUT)	+= setup_opsput.o io_opsput.o
 obj-$(CONFIG_PLAT_OPSPUT)	+= setup_opsput.o io_opsput.o
 obj-$(CONFIG_MODULES)		+= module.o
 obj-$(CONFIG_MODULES)		+= module.o
 obj-$(CONFIG_PLAT_OAKS32R)	+= setup_oaks32r.o io_oaks32r.o
 obj-$(CONFIG_PLAT_OAKS32R)	+= setup_oaks32r.o io_oaks32r.o
+obj-$(CONFIG_PLAT_M32104UT)	+= setup_m32104ut.o io_m32104ut.o
 
 
 EXTRA_AFLAGS	:= -traditional
 EXTRA_AFLAGS	:= -traditional

+ 15 - 4
arch/m32r/kernel/entry.S

@@ -315,7 +315,7 @@ ENTRY(ei_handler)
 	mv	r1, sp			; arg1(regs)
 	mv	r1, sp			; arg1(regs)
 #if defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_XNUX2) \
 #if defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_XNUX2) \
 	|| defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_M32102) \
 	|| defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_M32102) \
-	|| defined(CONFIG_CHIP_OPSP)
+	|| defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_M32104)
 
 
 ;    GET_ICU_STATUS;
 ;    GET_ICU_STATUS;
 	seth	r0, #shigh(M32R_ICU_ISTS_ADDR)
 	seth	r0, #shigh(M32R_ICU_ISTS_ADDR)
@@ -541,7 +541,20 @@ check_int2:
 	bra	check_end
 	bra	check_end
 	.fillinsn
 	.fillinsn
 check_end:
 check_end:
-#endif  /* CONFIG_PLAT_OPSPUT */
+#elif defined(CONFIG_PLAT_M32104UT)
+	add3	r2, r0, #-(M32R_IRQ_INT1)       ; INT1# interrupt
+	bnez	r2, check_end
+	; read ICU status register of PLD
+	seth	r0, #high(PLD_ICUISTS)
+	or3	r0, r0, #low(PLD_ICUISTS)
+	lduh	r0, @r0
+	slli	r0, #21
+	srli	r0, #27                         ; ISN
+	addi	r0, #(M32104UT_PLD_IRQ_BASE)
+	bra	check_end
+	.fillinsn
+check_end:
+#endif  /* CONFIG_PLAT_M32104UT */
 	bl	do_IRQ
 	bl	do_IRQ
 #endif  /* CONFIG_SMP */
 #endif  /* CONFIG_SMP */
 	ld	r14, @sp+
 	ld	r14, @sp+
@@ -651,8 +664,6 @@ ENTRY(rie_handler)
 /* void rie_handler(int error_code) */
 /* void rie_handler(int error_code) */
 	SWITCH_TO_KERNEL_STACK
 	SWITCH_TO_KERNEL_STACK
 	SAVE_ALL
 	SAVE_ALL
-	mvfc	r0, bpc
-	ld	r1, @r0
 	ldi	r1, #0x20			; error_code
 	ldi	r1, #0x20			; error_code
 	mv	r0, sp				; pt_regs
 	mv	r0, sp				; pt_regs
 	bl	do_rie_handler
 	bl	do_rie_handler

+ 298 - 0
arch/m32r/kernel/io_m32104ut.c

@@ -0,0 +1,298 @@
+/*
+ *  linux/arch/m32r/kernel/io_m32104ut.c
+ *
+ *  Typical I/O routines for M32104UT board.
+ *
+ *  Copyright (c) 2001-2005  Hiroyuki Kondo, Hirokazu Takata,
+ *                           Hitoshi Yamamoto, Mamoru Sakugawa,
+ *                           Naoto Sugai, Hayato Fujiwara
+ */
+
+#include <linux/config.h>
+#include <asm/m32r.h>
+#include <asm/page.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+
+#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
+#include <linux/types.h>
+
+#define M32R_PCC_IOMAP_SIZE 0x1000
+
+#define M32R_PCC_IOSTART0 0x1000
+#define M32R_PCC_IOEND0   (M32R_PCC_IOSTART0 + M32R_PCC_IOMAP_SIZE - 1)
+
+extern void pcc_ioread_byte(int, unsigned long, void *, size_t, size_t, int);
+extern void pcc_ioread_word(int, unsigned long, void *, size_t, size_t, int);
+extern void pcc_iowrite_byte(int, unsigned long, void *, size_t, size_t, int);
+extern void pcc_iowrite_word(int, unsigned long, void *, size_t, size_t, int);
+#endif /* CONFIG_PCMCIA && CONFIG_M32R_CFC */
+
+#define PORT2ADDR(port)  _port2addr(port)
+
+static inline void *_port2addr(unsigned long port)
+{
+	return (void *)(port | NONCACHE_OFFSET);
+}
+
+#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
+static inline void *__port2addr_ata(unsigned long port)
+{
+	static int	dummy_reg;
+
+	switch (port) {
+	case 0x1f0:	return (void *)(0x0c002000 | NONCACHE_OFFSET);
+	case 0x1f1:	return (void *)(0x0c012800 | NONCACHE_OFFSET);
+	case 0x1f2:	return (void *)(0x0c012002 | NONCACHE_OFFSET);
+	case 0x1f3:	return (void *)(0x0c012802 | NONCACHE_OFFSET);
+	case 0x1f4:	return (void *)(0x0c012004 | NONCACHE_OFFSET);
+	case 0x1f5:	return (void *)(0x0c012804 | NONCACHE_OFFSET);
+	case 0x1f6:	return (void *)(0x0c012006 | NONCACHE_OFFSET);
+	case 0x1f7:	return (void *)(0x0c012806 | NONCACHE_OFFSET);
+	case 0x3f6:	return (void *)(0x0c01200e | NONCACHE_OFFSET);
+	default: 	return (void *)&dummy_reg;
+	}
+}
+#endif
+
+/*
+ * M32104T-LAN is located in the extended bus space
+ * from 0x01000000 to 0x01ffffff on physical address.
+ * The base address of LAN controller(LAN91C111) is 0x300.
+ */
+#define LAN_IOSTART	(0x300 | NONCACHE_OFFSET)
+#define LAN_IOEND	(0x320 | NONCACHE_OFFSET)
+static inline void *_port2addr_ne(unsigned long port)
+{
+	return (void *)(port + NONCACHE_OFFSET + 0x01000000);
+}
+
+static inline void delay(void)
+{
+	__asm__ __volatile__ ("push r0; \n\t pop r0;" : : :"memory");
+}
+
+/*
+ * NIC I/O function
+ */
+
+#define PORT2ADDR_NE(port)  _port2addr_ne(port)
+
+static inline unsigned char _ne_inb(void *portp)
+{
+	return *(volatile unsigned char *)portp;
+}
+
+static inline unsigned short _ne_inw(void *portp)
+{
+	return (unsigned short)le16_to_cpu(*(volatile unsigned short *)portp);
+}
+
+static inline void _ne_insb(void *portp, void *addr, unsigned long count)
+{
+	unsigned char *buf = (unsigned char *)addr;
+
+	while (count--)
+		*buf++ = _ne_inb(portp);
+}
+
+static inline void _ne_outb(unsigned char b, void *portp)
+{
+	*(volatile unsigned char *)portp = b;
+}
+
+static inline void _ne_outw(unsigned short w, void *portp)
+{
+	*(volatile unsigned short *)portp = cpu_to_le16(w);
+}
+
+unsigned char _inb(unsigned long port)
+{
+	if (port >= LAN_IOSTART && port < LAN_IOEND)
+		return _ne_inb(PORT2ADDR_NE(port));
+
+	return *(volatile unsigned char *)PORT2ADDR(port);
+}
+
+unsigned short _inw(unsigned long port)
+{
+	if (port >= LAN_IOSTART && port < LAN_IOEND)
+		return _ne_inw(PORT2ADDR_NE(port));
+
+	return *(volatile unsigned short *)PORT2ADDR(port);
+}
+
+unsigned long _inl(unsigned long port)
+{
+	return *(volatile unsigned long *)PORT2ADDR(port);
+}
+
+unsigned char _inb_p(unsigned long port)
+{
+	unsigned char v = _inb(port);
+	delay();
+	return (v);
+}
+
+unsigned short _inw_p(unsigned long port)
+{
+	unsigned short v = _inw(port);
+	delay();
+	return (v);
+}
+
+unsigned long _inl_p(unsigned long port)
+{
+	unsigned long v = _inl(port);
+	delay();
+	return (v);
+}
+
+void _outb(unsigned char b, unsigned long port)
+{
+	if (port >= LAN_IOSTART && port < LAN_IOEND)
+		_ne_outb(b, PORT2ADDR_NE(port));
+	else
+		*(volatile unsigned char *)PORT2ADDR(port) = b;
+}
+
+void _outw(unsigned short w, unsigned long port)
+{
+	if (port >= LAN_IOSTART && port < LAN_IOEND)
+		_ne_outw(w, PORT2ADDR_NE(port));
+	else
+		*(volatile unsigned short *)PORT2ADDR(port) = w;
+}
+
+void _outl(unsigned long l, unsigned long port)
+{
+	*(volatile unsigned long *)PORT2ADDR(port) = l;
+}
+
+void _outb_p(unsigned char b, unsigned long port)
+{
+	_outb(b, port);
+	delay();
+}
+
+void _outw_p(unsigned short w, unsigned long port)
+{
+	_outw(w, port);
+	delay();
+}
+
+void _outl_p(unsigned long l, unsigned long port)
+{
+	_outl(l, port);
+	delay();
+}
+
+void _insb(unsigned int port, void *addr, unsigned long count)
+{
+	if (port >= LAN_IOSTART && port < LAN_IOEND)
+		_ne_insb(PORT2ADDR_NE(port), addr, count);
+	else {
+		unsigned char *buf = addr;
+		unsigned char *portp = PORT2ADDR(port);
+		while (count--)
+			*buf++ = *(volatile unsigned char *)portp;
+	}
+}
+
+void _insw(unsigned int port, void *addr, unsigned long count)
+{
+	unsigned short *buf = addr;
+	unsigned short *portp;
+
+	if (port >= LAN_IOSTART && port < LAN_IOEND) {
+		/*
+		 * This portion is only used by smc91111.c to read data
+		 * from the DATA_REG. Do not swap the data.
+		 */
+		portp = PORT2ADDR_NE(port);
+		while (count--)
+			*buf++ = *(volatile unsigned short *)portp;
+#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
+	} else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
+		pcc_ioread_word(9, port, (void *)addr, sizeof(unsigned short),
+				count, 1);
+#endif
+#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
+	} else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
+		portp = __port2addr_ata(port);
+		while (count--)
+			*buf++ = *(volatile unsigned short *)portp;
+#endif
+	} else {
+		portp = PORT2ADDR(port);
+		while (count--)
+			*buf++ = *(volatile unsigned short *)portp;
+	}
+}
+
+void _insl(unsigned int port, void *addr, unsigned long count)
+{
+	unsigned long *buf = addr;
+	unsigned long *portp;
+
+	portp = PORT2ADDR(port);
+	while (count--)
+		*buf++ = *(volatile unsigned long *)portp;
+}
+
+void _outsb(unsigned int port, const void *addr, unsigned long count)
+{
+	const unsigned char *buf = addr;
+	unsigned char *portp;
+
+	if (port >= LAN_IOSTART && port < LAN_IOEND) {
+		portp = PORT2ADDR_NE(port);
+		while (count--)
+			_ne_outb(*buf++, portp);
+	} else {
+		portp = PORT2ADDR(port);
+		while (count--)
+			*(volatile unsigned char *)portp = *buf++;
+	}
+}
+
+void _outsw(unsigned int port, const void *addr, unsigned long count)
+{
+	const unsigned short *buf = addr;
+	unsigned short *portp;
+
+	if (port >= LAN_IOSTART && port < LAN_IOEND) {
+		/*
+		 * This portion is only used by smc91111.c to write data
+		 * into the DATA_REG. Do not swap the data.
+		 */
+		portp = PORT2ADDR_NE(port);
+		while (count--)
+			*(volatile unsigned short *)portp = *buf++;
+#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
+	} else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
+		portp = __port2addr_ata(port);
+		while (count--)
+			*(volatile unsigned short *)portp = *buf++;
+#endif
+#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
+	} else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
+		pcc_iowrite_word(9, port, (void *)addr, sizeof(unsigned short),
+				 count, 1);
+#endif
+	} else {
+		portp = PORT2ADDR(port);
+		while (count--)
+			*(volatile unsigned short *)portp = *buf++;
+	}
+}
+
+void _outsl(unsigned int port, const void *addr, unsigned long count)
+{
+	const unsigned long *buf = addr;
+	unsigned char *portp;
+
+	portp = PORT2ADDR(port);
+	while (count--)
+		*(volatile unsigned long *)portp = *buf++;
+}

+ 12 - 12
arch/m32r/kernel/io_m32700ut.c

@@ -36,7 +36,7 @@ extern void pcc_iowrite_word(int, unsigned long, void *, size_t, size_t, int);
 
 
 static inline void *_port2addr(unsigned long port)
 static inline void *_port2addr(unsigned long port)
 {
 {
-	return (void *)(port + NONCACHE_OFFSET);
+	return (void *)(port | NONCACHE_OFFSET);
 }
 }
 
 
 #if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
 #if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
@@ -45,15 +45,15 @@ static inline void *__port2addr_ata(unsigned long port)
 	static int	dummy_reg;
 	static int	dummy_reg;
 
 
 	switch (port) {
 	switch (port) {
-	case 0x1f0:	return (void *)0xac002000;
-	case 0x1f1:	return (void *)0xac012800;
-	case 0x1f2:	return (void *)0xac012002;
-	case 0x1f3:	return (void *)0xac012802;
-	case 0x1f4:	return (void *)0xac012004;
-	case 0x1f5:	return (void *)0xac012804;
-	case 0x1f6:	return (void *)0xac012006;
-	case 0x1f7:	return (void *)0xac012806;
-	case 0x3f6:	return (void *)0xac01200e;
+	case 0x1f0:	return (void *)(0x0c002000 | NONCACHE_OFFSET);
+	case 0x1f1:	return (void *)(0x0c012800 | NONCACHE_OFFSET);
+	case 0x1f2:	return (void *)(0x0c012002 | NONCACHE_OFFSET);
+	case 0x1f3:	return (void *)(0x0c012802 | NONCACHE_OFFSET);
+	case 0x1f4:	return (void *)(0x0c012004 | NONCACHE_OFFSET);
+	case 0x1f5:	return (void *)(0x0c012804 | NONCACHE_OFFSET);
+	case 0x1f6:	return (void *)(0x0c012006 | NONCACHE_OFFSET);
+	case 0x1f7:	return (void *)(0x0c012806 | NONCACHE_OFFSET);
+	case 0x3f6:	return (void *)(0x0c01200e | NONCACHE_OFFSET);
 	default: 	return (void *)&dummy_reg;
 	default: 	return (void *)&dummy_reg;
 	}
 	}
 }
 }
@@ -64,8 +64,8 @@ static inline void *__port2addr_ata(unsigned long port)
  * from 0x10000000 to 0x13ffffff on physical address.
  * from 0x10000000 to 0x13ffffff on physical address.
  * The base address of LAN controller(LAN91C111) is 0x300.
  * The base address of LAN controller(LAN91C111) is 0x300.
  */
  */
-#define LAN_IOSTART	0xa0000300
-#define LAN_IOEND	0xa0000320
+#define LAN_IOSTART	(0x300 | NONCACHE_OFFSET)
+#define LAN_IOEND	(0x320 | NONCACHE_OFFSET)
 static inline void *_port2addr_ne(unsigned long port)
 static inline void *_port2addr_ne(unsigned long port)
 {
 {
 	return (void *)(port + 0x10000000);
 	return (void *)(port + 0x10000000);

+ 1 - 1
arch/m32r/kernel/io_mappi.c

@@ -31,7 +31,7 @@ extern void pcc_iowrite(int, unsigned long, void *, size_t, size_t, int);
 
 
 static inline void *_port2addr(unsigned long port)
 static inline void *_port2addr(unsigned long port)
 {
 {
-	return (void *)(port | (NONCACHE_OFFSET));
+	return (void *)(port | NONCACHE_OFFSET);
 }
 }
 
 
 static inline void *_port2addr_ne(unsigned long port)
 static inline void *_port2addr_ne(unsigned long port)

+ 12 - 12
arch/m32r/kernel/io_mappi2.c

@@ -33,7 +33,7 @@ extern void pcc_iowrite_word(int, unsigned long, void *, size_t, size_t, int);
 
 
 static inline void *_port2addr(unsigned long port)
 static inline void *_port2addr(unsigned long port)
 {
 {
-	return (void *)(port | (NONCACHE_OFFSET));
+	return (void *)(port | NONCACHE_OFFSET);
 }
 }
 
 
 #if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
 #if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
@@ -42,22 +42,22 @@ static inline void *__port2addr_ata(unsigned long port)
 	static int	dummy_reg;
 	static int	dummy_reg;
 
 
 	switch (port) {
 	switch (port) {
-	case 0x1f0:	return (void *)0xac002000;
-	case 0x1f1:	return (void *)0xac012800;
-	case 0x1f2:	return (void *)0xac012002;
-	case 0x1f3:	return (void *)0xac012802;
-	case 0x1f4:	return (void *)0xac012004;
-	case 0x1f5:	return (void *)0xac012804;
-	case 0x1f6:	return (void *)0xac012006;
-	case 0x1f7:	return (void *)0xac012806;
-	case 0x3f6:	return (void *)0xac01200e;
+	case 0x1f0:	return (void *)(0x0c002000 | NONCACHE_OFFSET);
+	case 0x1f1:	return (void *)(0x0c012800 | NONCACHE_OFFSET);
+	case 0x1f2:	return (void *)(0x0c012002 | NONCACHE_OFFSET);
+	case 0x1f3:	return (void *)(0x0c012802 | NONCACHE_OFFSET);
+	case 0x1f4:	return (void *)(0x0c012004 | NONCACHE_OFFSET);
+	case 0x1f5:	return (void *)(0x0c012804 | NONCACHE_OFFSET);
+	case 0x1f6:	return (void *)(0x0c012006 | NONCACHE_OFFSET);
+	case 0x1f7:	return (void *)(0x0c012806 | NONCACHE_OFFSET);
+	case 0x3f6:	return (void *)(0x0c01200e | NONCACHE_OFFSET);
 	default: 	return (void *)&dummy_reg;
 	default: 	return (void *)&dummy_reg;
 	}
 	}
 }
 }
 #endif
 #endif
 
 
-#define LAN_IOSTART	0xa0000300
-#define LAN_IOEND	0xa0000320
+#define LAN_IOSTART	(0x300 | NONCACHE_OFFSET)
+#define LAN_IOEND	(0x320 | NONCACHE_OFFSET)
 #ifdef CONFIG_CHIP_OPSP
 #ifdef CONFIG_CHIP_OPSP
 static inline void *_port2addr_ne(unsigned long port)
 static inline void *_port2addr_ne(unsigned long port)
 {
 {

+ 30 - 21
arch/m32r/kernel/io_mappi3.c

@@ -33,7 +33,7 @@ extern void pcc_iowrite_word(int, unsigned long, void *, size_t, size_t, int);
 
 
 static inline void *_port2addr(unsigned long port)
 static inline void *_port2addr(unsigned long port)
 {
 {
-	return (void *)(port + NONCACHE_OFFSET);
+	return (void *)(port | NONCACHE_OFFSET);
 }
 }
 
 
 #if defined(CONFIG_IDE)
 #if defined(CONFIG_IDE)
@@ -43,33 +43,42 @@ static inline void *__port2addr_ata(unsigned long port)
 
 
 	switch (port) {
 	switch (port) {
 	  /* IDE0 CF */
 	  /* IDE0 CF */
-	case 0x1f0:	return (void *)0xb4002000;
-	case 0x1f1:	return (void *)0xb4012800;
-	case 0x1f2:	return (void *)0xb4012002;
-	case 0x1f3:	return (void *)0xb4012802;
-	case 0x1f4:	return (void *)0xb4012004;
-	case 0x1f5:	return (void *)0xb4012804;
-	case 0x1f6:	return (void *)0xb4012006;
-	case 0x1f7:	return (void *)0xb4012806;
-	case 0x3f6:	return (void *)0xb401200e;
+	case 0x1f0:	return (void *)(0x14002000 | NONCACHE_OFFSET);
+	case 0x1f1:	return (void *)(0x14012800 | NONCACHE_OFFSET);
+	case 0x1f2:	return (void *)(0x14012002 | NONCACHE_OFFSET);
+	case 0x1f3:	return (void *)(0x14012802 | NONCACHE_OFFSET);
+	case 0x1f4:	return (void *)(0x14012004 | NONCACHE_OFFSET);
+	case 0x1f5:	return (void *)(0x14012804 | NONCACHE_OFFSET);
+	case 0x1f6:	return (void *)(0x14012006 | NONCACHE_OFFSET);
+	case 0x1f7:	return (void *)(0x14012806 | NONCACHE_OFFSET);
+	case 0x3f6:	return (void *)(0x1401200e | NONCACHE_OFFSET);
 	  /* IDE1 IDE */
 	  /* IDE1 IDE */
-	case 0x170:	return (void *)0xb4810000;  /* Data 16bit */
-	case 0x171:	return (void *)0xb4810002;  /* Features / Error */
-	case 0x172:	return (void *)0xb4810004;  /* Sector count */
-	case 0x173:	return (void *)0xb4810006;  /* Sector number */
-	case 0x174:	return (void *)0xb4810008;  /* Cylinder low */
-	case 0x175:	return (void *)0xb481000a;  /* Cylinder high */
-	case 0x176:	return (void *)0xb481000c;  /* Device head */
-	case 0x177:	return (void *)0xb481000e;  /* Command     */
-	case 0x376:	return (void *)0xb480800c;  /* Device control / Alt status */
+	case 0x170:	/* Data 16bit */
+			return (void *)(0x14810000 | NONCACHE_OFFSET);
+	case 0x171:	/* Features / Error */
+			return (void *)(0x14810002 | NONCACHE_OFFSET);
+	case 0x172:	/* Sector count */
+			return (void *)(0x14810004 | NONCACHE_OFFSET);
+	case 0x173:	/* Sector number */
+			return (void *)(0x14810006 | NONCACHE_OFFSET);
+	case 0x174:	/* Cylinder low */
+			return (void *)(0x14810008 | NONCACHE_OFFSET);
+	case 0x175:	/* Cylinder high */
+			return (void *)(0x1481000a | NONCACHE_OFFSET);
+	case 0x176:	/* Device head */
+			return (void *)(0x1481000c | NONCACHE_OFFSET);
+	case 0x177:	/* Command     */
+			return (void *)(0x1481000e | NONCACHE_OFFSET);
+	case 0x376:	/* Device control / Alt status */
+			return (void *)(0x1480800c | NONCACHE_OFFSET);
 
 
 	default: 	return (void *)&dummy_reg;
 	default: 	return (void *)&dummy_reg;
 	}
 	}
 }
 }
 #endif
 #endif
 
 
-#define LAN_IOSTART	0xa0000300
-#define LAN_IOEND	0xa0000320
+#define LAN_IOSTART	(0x300 | NONCACHE_OFFSET)
+#define LAN_IOEND	(0x320 | NONCACHE_OFFSET)
 static inline void *_port2addr_ne(unsigned long port)
 static inline void *_port2addr_ne(unsigned long port)
 {
 {
 	return (void *)(port + 0x10000000);
 	return (void *)(port + 0x10000000);

+ 1 - 1
arch/m32r/kernel/io_oaks32r.c

@@ -16,7 +16,7 @@
 
 
 static inline void *_port2addr(unsigned long port)
 static inline void *_port2addr(unsigned long port)
 {
 {
-	return (void *)(port | (NONCACHE_OFFSET));
+	return (void *)(port | NONCACHE_OFFSET);
 }
 }
 
 
 static inline  void *_port2addr_ne(unsigned long port)
 static inline  void *_port2addr_ne(unsigned long port)

+ 3 - 3
arch/m32r/kernel/io_opsput.c

@@ -36,7 +36,7 @@ extern void pcc_iowrite_word(int, unsigned long, void *, size_t, size_t, int);
 
 
 static inline void *_port2addr(unsigned long port)
 static inline void *_port2addr(unsigned long port)
 {
 {
-	return (void *)(port | (NONCACHE_OFFSET));
+	return (void *)(port | NONCACHE_OFFSET);
 }
 }
 
 
 /*
 /*
@@ -44,8 +44,8 @@ static inline void *_port2addr(unsigned long port)
  * from 0x10000000 to 0x13ffffff on physical address.
  * from 0x10000000 to 0x13ffffff on physical address.
  * The base address of LAN controller(LAN91C111) is 0x300.
  * The base address of LAN controller(LAN91C111) is 0x300.
  */
  */
-#define LAN_IOSTART	0xa0000300
-#define LAN_IOEND	0xa0000320
+#define LAN_IOSTART	(0x300 | NONCACHE_OFFSET)
+#define LAN_IOEND	(0x320 | NONCACHE_OFFSET)
 static inline void *_port2addr_ne(unsigned long port)
 static inline void *_port2addr_ne(unsigned long port)
 {
 {
 	return (void *)(port + 0x10000000);
 	return (void *)(port + 0x10000000);

+ 6 - 1
arch/m32r/kernel/setup.c

@@ -320,6 +320,9 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 #elif defined(CONFIG_CHIP_MP)
 #elif defined(CONFIG_CHIP_MP)
 	seq_printf(m, "cpu family\t: M32R-MP\n"
 	seq_printf(m, "cpu family\t: M32R-MP\n"
 		"cache size\t: I-xxKB/D-xxKB\n");
 		"cache size\t: I-xxKB/D-xxKB\n");
+#elif  defined(CONFIG_CHIP_M32104)
+	seq_printf(m,"cpu family\t: M32104\n"
+		"cache size\t: I-8KB/D-8KB\n");
 #else
 #else
 	seq_printf(m, "cpu family\t: Unknown\n");
 	seq_printf(m, "cpu family\t: Unknown\n");
 #endif
 #endif
@@ -340,6 +343,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 	seq_printf(m, "Machine\t\t: uServer\n");
 	seq_printf(m, "Machine\t\t: uServer\n");
 #elif defined(CONFIG_PLAT_OAKS32R)
 #elif defined(CONFIG_PLAT_OAKS32R)
 	seq_printf(m, "Machine\t\t: OAKS32R\n");
 	seq_printf(m, "Machine\t\t: OAKS32R\n");
+#elif  defined(CONFIG_PLAT_M32104UT)
+	seq_printf(m, "Machine\t\t: M3T-M32104UT uT Engine board\n");
 #else
 #else
 	seq_printf(m, "Machine\t\t: Unknown\n");
 	seq_printf(m, "Machine\t\t: Unknown\n");
 #endif
 #endif
@@ -389,7 +394,7 @@ unsigned long cpu_initialized __initdata = 0;
  */
  */
 #if defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_XNUX2)	\
 #if defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_XNUX2)	\
 	|| defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_M32102) \
 	|| defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_M32102) \
-	|| defined(CONFIG_CHIP_OPSP)
+	|| defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_M32104)
 void __init cpu_init (void)
 void __init cpu_init (void)
 {
 {
 	int cpu_id = smp_processor_id();
 	int cpu_id = smp_processor_id();

部分文件因文件數量過多而無法顯示