diff options
211 files changed, 3733 insertions, 2197 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index fa75220f8d34..89a47b5aff07 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -354,14 +354,6 @@ Who: Krzysztof Piotr Oledzki <ole@ans.pl> | |||
354 | 354 | ||
355 | --------------------------- | 355 | --------------------------- |
356 | 356 | ||
357 | What: fscher and fscpos drivers | ||
358 | When: June 2009 | ||
359 | Why: Deprecated by the new fschmd driver. | ||
360 | Who: Hans de Goede <hdegoede@redhat.com> | ||
361 | Jean Delvare <khali@linux-fr.org> | ||
362 | |||
363 | --------------------------- | ||
364 | |||
365 | What: sysfs ui for changing p4-clockmod parameters | 357 | What: sysfs ui for changing p4-clockmod parameters |
366 | When: September 2009 | 358 | When: September 2009 |
367 | Why: See commits 129f8ae9b1b5be94517da76009ea956e89104ce8 and | 359 | Why: See commits 129f8ae9b1b5be94517da76009ea956e89104ce8 and |
diff --git a/Documentation/filesystems/9p.txt b/Documentation/filesystems/9p.txt index 6208f55c44c3..57e0b80a5274 100644 --- a/Documentation/filesystems/9p.txt +++ b/Documentation/filesystems/9p.txt | |||
@@ -18,11 +18,11 @@ the 9p client is available in the form of a USENIX paper: | |||
18 | 18 | ||
19 | Other applications are described in the following papers: | 19 | Other applications are described in the following papers: |
20 | * XCPU & Clustering | 20 | * XCPU & Clustering |
21 | http://www.xcpu.org/xcpu-talk.pdf | 21 | http://xcpu.org/papers/xcpu-talk.pdf |
22 | * KVMFS: control file system for KVM | 22 | * KVMFS: control file system for KVM |
23 | http://www.xcpu.org/kvmfs.pdf | 23 | http://xcpu.org/papers/kvmfs.pdf |
24 | * CellFS: A New ProgrammingModel for the Cell BE | 24 | * CellFS: A New Programming Model for the Cell BE |
25 | http://www.xcpu.org/cellfs-talk.pdf | 25 | http://xcpu.org/papers/cellfs-talk.pdf |
26 | * PROSE I/O: Using 9p to enable Application Partitions | 26 | * PROSE I/O: Using 9p to enable Application Partitions |
27 | http://plan9.escet.urjc.es/iwp9/cready/PROSE_iwp9_2006.pdf | 27 | http://plan9.escet.urjc.es/iwp9/cready/PROSE_iwp9_2006.pdf |
28 | 28 | ||
@@ -48,6 +48,7 @@ OPTIONS | |||
48 | (see rfdno and wfdno) | 48 | (see rfdno and wfdno) |
49 | virtio - connect to the next virtio channel available | 49 | virtio - connect to the next virtio channel available |
50 | (from lguest or KVM with trans_virtio module) | 50 | (from lguest or KVM with trans_virtio module) |
51 | rdma - connect to a specified RDMA channel | ||
51 | 52 | ||
52 | uname=name user name to attempt mount as on the remote server. The | 53 | uname=name user name to attempt mount as on the remote server. The |
53 | server may override or ignore this value. Certain user | 54 | server may override or ignore this value. Certain user |
@@ -59,16 +60,22 @@ OPTIONS | |||
59 | cache=mode specifies a caching policy. By default, no caches are used. | 60 | cache=mode specifies a caching policy. By default, no caches are used. |
60 | loose = no attempts are made at consistency, | 61 | loose = no attempts are made at consistency, |
61 | intended for exclusive, read-only mounts | 62 | intended for exclusive, read-only mounts |
63 | fscache = use FS-Cache for a persistent, read-only | ||
64 | cache backend. | ||
62 | 65 | ||
63 | debug=n specifies debug level. The debug level is a bitmask. | 66 | debug=n specifies debug level. The debug level is a bitmask. |
64 | 0x01 = display verbose error messages | 67 | 0x01 = display verbose error messages |
65 | 0x02 = developer debug (DEBUG_CURRENT) | 68 | 0x02 = developer debug (DEBUG_CURRENT) |
66 | 0x04 = display 9p trace | 69 | 0x04 = display 9p trace |
67 | 0x08 = display VFS trace | 70 | 0x08 = display VFS trace |
68 | 0x10 = display Marshalling debug | 71 | 0x10 = display Marshalling debug |
69 | 0x20 = display RPC debug | 72 | 0x20 = display RPC debug |
70 | 0x40 = display transport debug | 73 | 0x40 = display transport debug |
71 | 0x80 = display allocation debug | 74 | 0x80 = display allocation debug |
75 | 0x100 = display protocol message debug | ||
76 | 0x200 = display Fid debug | ||
77 | 0x400 = display packet debug | ||
78 | 0x800 = display fscache tracing debug | ||
72 | 79 | ||
73 | rfdno=n the file descriptor for reading with trans=fd | 80 | rfdno=n the file descriptor for reading with trans=fd |
74 | 81 | ||
@@ -100,6 +107,10 @@ OPTIONS | |||
100 | any = v9fs does single attach and performs all | 107 | any = v9fs does single attach and performs all |
101 | operations as one user | 108 | operations as one user |
102 | 109 | ||
110 | cachetag cache tag to use the specified persistent cache. | ||
111 | cache tags for existing cache sessions can be listed at | ||
112 | /sys/fs/9p/caches. (applies only to cache=fscache) | ||
113 | |||
103 | RESOURCES | 114 | RESOURCES |
104 | ========= | 115 | ========= |
105 | 116 | ||
@@ -118,7 +129,7 @@ and export. | |||
118 | A Linux version of the 9p server is now maintained under the npfs project | 129 | A Linux version of the 9p server is now maintained under the npfs project |
119 | on sourceforge (http://sourceforge.net/projects/npfs). The currently | 130 | on sourceforge (http://sourceforge.net/projects/npfs). The currently |
120 | maintained version is the single-threaded version of the server (named spfs) | 131 | maintained version is the single-threaded version of the server (named spfs) |
121 | available from the same CVS repository. | 132 | available from the same SVN repository. |
122 | 133 | ||
123 | There are user and developer mailing lists available through the v9fs project | 134 | There are user and developer mailing lists available through the v9fs project |
124 | on sourceforge (http://sourceforge.net/projects/v9fs). | 135 | on sourceforge (http://sourceforge.net/projects/v9fs). |
@@ -126,7 +137,8 @@ on sourceforge (http://sourceforge.net/projects/v9fs). | |||
126 | A stand-alone version of the module (which should build for any 2.6 kernel) | 137 | A stand-alone version of the module (which should build for any 2.6 kernel) |
127 | is available via (http://github.com/ericvh/9p-sac/tree/master) | 138 | is available via (http://github.com/ericvh/9p-sac/tree/master) |
128 | 139 | ||
129 | News and other information is maintained on SWiK (http://swik.net/v9fs). | 140 | News and other information is maintained on SWiK (http://swik.net/v9fs) |
141 | and the Wiki (http://sf.net/apps/mediawiki/v9fs/index.php). | ||
130 | 142 | ||
131 | Bug reports may be issued through the kernel.org bugzilla | 143 | Bug reports may be issued through the kernel.org bugzilla |
132 | (http://bugzilla.kernel.org) | 144 | (http://bugzilla.kernel.org) |
diff --git a/Documentation/hwmon/coretemp b/Documentation/hwmon/coretemp index dbbe6c7025b0..92267b62db59 100644 --- a/Documentation/hwmon/coretemp +++ b/Documentation/hwmon/coretemp | |||
@@ -4,7 +4,9 @@ Kernel driver coretemp | |||
4 | Supported chips: | 4 | Supported chips: |
5 | * All Intel Core family | 5 | * All Intel Core family |
6 | Prefix: 'coretemp' | 6 | Prefix: 'coretemp' |
7 | CPUID: family 0x6, models 0xe, 0xf, 0x16, 0x17 | 7 | CPUID: family 0x6, models 0xe (Pentium M DC), 0xf (Core 2 DC 65nm), |
8 | 0x16 (Core 2 SC 65nm), 0x17 (Penryn 45nm), | ||
9 | 0x1a (Nehalem), 0x1c (Atom), 0x1e (Lynnfield) | ||
8 | Datasheet: Intel 64 and IA-32 Architectures Software Developer's Manual | 10 | Datasheet: Intel 64 and IA-32 Architectures Software Developer's Manual |
9 | Volume 3A: System Programming Guide | 11 | Volume 3A: System Programming Guide |
10 | http://softwarecommunity.intel.com/Wiki/Mobility/720.htm | 12 | http://softwarecommunity.intel.com/Wiki/Mobility/720.htm |
diff --git a/Documentation/hwmon/fscher b/Documentation/hwmon/fscher deleted file mode 100644 index 64031659aff3..000000000000 --- a/Documentation/hwmon/fscher +++ /dev/null | |||
@@ -1,169 +0,0 @@ | |||
1 | Kernel driver fscher | ||
2 | ==================== | ||
3 | |||
4 | Supported chips: | ||
5 | * Fujitsu-Siemens Hermes chip | ||
6 | Prefix: 'fscher' | ||
7 | Addresses scanned: I2C 0x73 | ||
8 | |||
9 | Authors: | ||
10 | Reinhard Nissl <rnissl@gmx.de> based on work | ||
11 | from Hermann Jung <hej@odn.de>, | ||
12 | Frodo Looijaard <frodol@dds.nl>, | ||
13 | Philip Edelbrock <phil@netroedge.com> | ||
14 | |||
15 | Description | ||
16 | ----------- | ||
17 | |||
18 | This driver implements support for the Fujitsu-Siemens Hermes chip. It is | ||
19 | described in the 'Register Set Specification BMC Hermes based Systemboard' | ||
20 | from Fujitsu-Siemens. | ||
21 | |||
22 | The Hermes chip implements a hardware-based system management, e.g. for | ||
23 | controlling fan speed and core voltage. There is also a watchdog counter on | ||
24 | the chip which can trigger an alarm and even shut the system down. | ||
25 | |||
26 | The chip provides three temperature values (CPU, motherboard and | ||
27 | auxiliary), three voltage values (+12V, +5V and battery) and three fans | ||
28 | (power supply, CPU and auxiliary). | ||
29 | |||
30 | Temperatures are measured in degrees Celsius. The resolution is 1 degree. | ||
31 | |||
32 | Fan rotation speeds are reported in RPM (rotations per minute). The value | ||
33 | can be divided by a programmable divider (1, 2 or 4) which is stored on | ||
34 | the chip. | ||
35 | |||
36 | Voltage sensors (also known as "in" sensors) report their values in volts. | ||
37 | |||
38 | All values are reported as final values from the driver. There is no need | ||
39 | for further calculations. | ||
40 | |||
41 | |||
42 | Detailed description | ||
43 | -------------------- | ||
44 | |||
45 | Below you'll find a single line description of all the bit values. With | ||
46 | this information, you're able to decode e. g. alarms, wdog, etc. To make | ||
47 | use of the watchdog, you'll need to set the watchdog time and enable the | ||
48 | watchdog. After that it is necessary to restart the watchdog time within | ||
49 | the specified period of time, or a system reset will occur. | ||
50 | |||
51 | * revision | ||
52 | READING & 0xff = 0x??: HERMES revision identification | ||
53 | |||
54 | * alarms | ||
55 | READING & 0x80 = 0x80: CPU throttling active | ||
56 | READING & 0x80 = 0x00: CPU running at full speed | ||
57 | |||
58 | READING & 0x10 = 0x10: software event (see control:1) | ||
59 | READING & 0x10 = 0x00: no software event | ||
60 | |||
61 | READING & 0x08 = 0x08: watchdog event (see wdog:2) | ||
62 | READING & 0x08 = 0x00: no watchdog event | ||
63 | |||
64 | READING & 0x02 = 0x02: thermal event (see temp*:1) | ||
65 | READING & 0x02 = 0x00: no thermal event | ||
66 | |||
67 | READING & 0x01 = 0x01: fan event (see fan*:1) | ||
68 | READING & 0x01 = 0x00: no fan event | ||
69 | |||
70 | READING & 0x13 ! 0x00: ALERT LED is flashing | ||
71 | |||
72 | * control | ||
73 | READING & 0x01 = 0x01: software event | ||
74 | READING & 0x01 = 0x00: no software event | ||
75 | |||
76 | WRITING & 0x01 = 0x01: set software event | ||
77 | WRITING & 0x01 = 0x00: clear software event | ||
78 | |||
79 | * watchdog_control | ||
80 | READING & 0x80 = 0x80: power off on watchdog event while thermal event | ||
81 | READING & 0x80 = 0x00: watchdog power off disabled (just system reset enabled) | ||
82 | |||
83 | READING & 0x40 = 0x40: watchdog timebase 60 seconds (see also wdog:1) | ||
84 | READING & 0x40 = 0x00: watchdog timebase 2 seconds | ||
85 | |||
86 | READING & 0x10 = 0x10: watchdog enabled | ||
87 | READING & 0x10 = 0x00: watchdog disabled | ||
88 | |||
89 | WRITING & 0x80 = 0x80: enable "power off on watchdog event while thermal event" | ||
90 | WRITING & 0x80 = 0x00: disable "power off on watchdog event while thermal event" | ||
91 | |||
92 | WRITING & 0x40 = 0x40: set watchdog timebase to 60 seconds | ||
93 | WRITING & 0x40 = 0x00: set watchdog timebase to 2 seconds | ||
94 | |||
95 | WRITING & 0x20 = 0x20: disable watchdog | ||
96 | |||
97 | WRITING & 0x10 = 0x10: enable watchdog / restart watchdog time | ||
98 | |||
99 | * watchdog_state | ||
100 | READING & 0x02 = 0x02: watchdog system reset occurred | ||
101 | READING & 0x02 = 0x00: no watchdog system reset occurred | ||
102 | |||
103 | WRITING & 0x02 = 0x02: clear watchdog event | ||
104 | |||
105 | * watchdog_preset | ||
106 | READING & 0xff = 0x??: configured watch dog time in units (see wdog:3 0x40) | ||
107 | |||
108 | WRITING & 0xff = 0x??: configure watch dog time in units | ||
109 | |||
110 | * in* (0: +5V, 1: +12V, 2: onboard 3V battery) | ||
111 | READING: actual voltage value | ||
112 | |||
113 | * temp*_status (1: CPU sensor, 2: onboard sensor, 3: auxiliary sensor) | ||
114 | READING & 0x02 = 0x02: thermal event (overtemperature) | ||
115 | READING & 0x02 = 0x00: no thermal event | ||
116 | |||
117 | READING & 0x01 = 0x01: sensor is working | ||
118 | READING & 0x01 = 0x00: sensor is faulty | ||
119 | |||
120 | WRITING & 0x02 = 0x02: clear thermal event | ||
121 | |||
122 | * temp*_input (1: CPU sensor, 2: onboard sensor, 3: auxiliary sensor) | ||
123 | READING: actual temperature value | ||
124 | |||
125 | * fan*_status (1: power supply fan, 2: CPU fan, 3: auxiliary fan) | ||
126 | READING & 0x04 = 0x04: fan event (fan fault) | ||
127 | READING & 0x04 = 0x00: no fan event | ||
128 | |||
129 | WRITING & 0x04 = 0x04: clear fan event | ||
130 | |||
131 | * fan*_div (1: power supply fan, 2: CPU fan, 3: auxiliary fan) | ||
132 | Divisors 2,4 and 8 are supported, both for reading and writing | ||
133 | |||
134 | * fan*_pwm (1: power supply fan, 2: CPU fan, 3: auxiliary fan) | ||
135 | READING & 0xff = 0x00: fan may be switched off | ||
136 | READING & 0xff = 0x01: fan must run at least at minimum speed (supply: 6V) | ||
137 | READING & 0xff = 0xff: fan must run at maximum speed (supply: 12V) | ||
138 | READING & 0xff = 0x??: fan must run at least at given speed (supply: 6V..12V) | ||
139 | |||
140 | WRITING & 0xff = 0x00: fan may be switched off | ||
141 | WRITING & 0xff = 0x01: fan must run at least at minimum speed (supply: 6V) | ||
142 | WRITING & 0xff = 0xff: fan must run at maximum speed (supply: 12V) | ||
143 | WRITING & 0xff = 0x??: fan must run at least at given speed (supply: 6V..12V) | ||
144 | |||
145 | * fan*_input (1: power supply fan, 2: CPU fan, 3: auxiliary fan) | ||
146 | READING: actual RPM value | ||
147 | |||
148 | |||
149 | Limitations | ||
150 | ----------- | ||
151 | |||
152 | * Measuring fan speed | ||
153 | It seems that the chip counts "ripples" (typical fans produce 2 ripples per | ||
154 | rotation while VERAX fans produce 18) in a 9-bit register. This register is | ||
155 | read out every second, then the ripple prescaler (2, 4 or 8) is applied and | ||
156 | the result is stored in the 8 bit output register. Due to the limitation of | ||
157 | the counting register to 9 bits, it is impossible to measure a VERAX fan | ||
158 | properly (even with a prescaler of 8). At its maximum speed of 3500 RPM the | ||
159 | fan produces 1080 ripples per second which causes the counting register to | ||
160 | overflow twice, leading to only 186 RPM. | ||
161 | |||
162 | * Measuring input voltages | ||
163 | in2 ("battery") reports the voltage of the onboard lithium battery and not | ||
164 | +3.3V from the power supply. | ||
165 | |||
166 | * Undocumented features | ||
167 | Fujitsu-Siemens Computers has not documented all features of the chip so | ||
168 | far. Their software, System Guard, shows that there are a still some | ||
169 | features which cannot be controlled by this implementation. | ||
diff --git a/Documentation/kbuild/kbuild.txt b/Documentation/kbuild/kbuild.txt index f3355b6812df..bb3bf38f03da 100644 --- a/Documentation/kbuild/kbuild.txt +++ b/Documentation/kbuild/kbuild.txt | |||
@@ -65,6 +65,22 @@ INSTALL_PATH | |||
65 | INSTALL_PATH specifies where to place the updated kernel and system map | 65 | INSTALL_PATH specifies where to place the updated kernel and system map |
66 | images. Default is /boot, but you can set it to other values. | 66 | images. Default is /boot, but you can set it to other values. |
67 | 67 | ||
68 | INSTALLKERNEL | ||
69 | -------------------------------------------------- | ||
70 | Install script called when using "make install". | ||
71 | The default name is "installkernel". | ||
72 | |||
73 | The script will be called with the following arguments: | ||
74 | $1 - kernel version | ||
75 | $2 - kernel image file | ||
76 | $3 - kernel map file | ||
77 | $4 - default install path (use root directory if blank) | ||
78 | |||
79 | The implmentation of "make install" is architecture specific | ||
80 | and it may differ from the above. | ||
81 | |||
82 | INSTALLKERNEL is provided to enable the possibility to | ||
83 | specify a custom installer when cross compiling a kernel. | ||
68 | 84 | ||
69 | MODLIB | 85 | MODLIB |
70 | -------------------------------------------------- | 86 | -------------------------------------------------- |
diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt index d76cfd8712e1..71c602d61680 100644 --- a/Documentation/kbuild/makefiles.txt +++ b/Documentation/kbuild/makefiles.txt | |||
@@ -18,6 +18,7 @@ This document describes the Linux kernel Makefiles. | |||
18 | --- 3.9 Dependency tracking | 18 | --- 3.9 Dependency tracking |
19 | --- 3.10 Special Rules | 19 | --- 3.10 Special Rules |
20 | --- 3.11 $(CC) support functions | 20 | --- 3.11 $(CC) support functions |
21 | --- 3.12 $(LD) support functions | ||
21 | 22 | ||
22 | === 4 Host Program support | 23 | === 4 Host Program support |
23 | --- 4.1 Simple Host Program | 24 | --- 4.1 Simple Host Program |
@@ -435,14 +436,14 @@ more details, with real examples. | |||
435 | The second argument is optional, and if supplied will be used | 436 | The second argument is optional, and if supplied will be used |
436 | if first argument is not supported. | 437 | if first argument is not supported. |
437 | 438 | ||
438 | ld-option | 439 | cc-ldoption |
439 | ld-option is used to check if $(CC) when used to link object files | 440 | cc-ldoption is used to check if $(CC) when used to link object files |
440 | supports the given option. An optional second option may be | 441 | supports the given option. An optional second option may be |
441 | specified if first option are not supported. | 442 | specified if first option are not supported. |
442 | 443 | ||
443 | Example: | 444 | Example: |
444 | #arch/i386/kernel/Makefile | 445 | #arch/i386/kernel/Makefile |
445 | vsyscall-flags += $(call ld-option, -Wl$(comma)--hash-style=sysv) | 446 | vsyscall-flags += $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) |
446 | 447 | ||
447 | In the above example, vsyscall-flags will be assigned the option | 448 | In the above example, vsyscall-flags will be assigned the option |
448 | -Wl$(comma)--hash-style=sysv if it is supported by $(CC). | 449 | -Wl$(comma)--hash-style=sysv if it is supported by $(CC). |
@@ -570,6 +571,19 @@ more details, with real examples. | |||
570 | endif | 571 | endif |
571 | endif | 572 | endif |
572 | 573 | ||
574 | --- 3.12 $(LD) support functions | ||
575 | |||
576 | ld-option | ||
577 | ld-option is used to check if $(LD) supports the supplied option. | ||
578 | ld-option takes two options as arguments. | ||
579 | The second argument is an optional option that can be used if the | ||
580 | first option is not supported by $(LD). | ||
581 | |||
582 | Example: | ||
583 | #Makefile | ||
584 | LDFLAGS_vmlinux += $(call really-ld-option, -X) | ||
585 | |||
586 | |||
573 | === 4 Host Program support | 587 | === 4 Host Program support |
574 | 588 | ||
575 | Kbuild supports building executables on the host for use during the | 589 | Kbuild supports building executables on the host for use during the |
@@ -179,9 +179,46 @@ SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \ | |||
179 | # Alternatively CROSS_COMPILE can be set in the environment. | 179 | # Alternatively CROSS_COMPILE can be set in the environment. |
180 | # Default value for CROSS_COMPILE is not to prefix executables | 180 | # Default value for CROSS_COMPILE is not to prefix executables |
181 | # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile | 181 | # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile |
182 | # | ||
183 | # To force ARCH and CROSS_COMPILE settings include kernel.* files | ||
184 | # in the kernel tree - do not patch this file. | ||
182 | export KBUILD_BUILDHOST := $(SUBARCH) | 185 | export KBUILD_BUILDHOST := $(SUBARCH) |
183 | ARCH ?= $(SUBARCH) | 186 | |
184 | CROSS_COMPILE ?= | 187 | # Kbuild save the ARCH and CROSS_COMPILE setting in kernel.* files. |
188 | # Restore these settings and check that user did not specify | ||
189 | # conflicting values. | ||
190 | |||
191 | saved_arch := $(shell cat include/generated/kernel.arch 2> /dev/null) | ||
192 | saved_cross := $(shell cat include/generated/kernel.cross 2> /dev/null) | ||
193 | |||
194 | ifneq ($(CROSS_COMPILE),) | ||
195 | ifneq ($(saved_cross),) | ||
196 | ifneq ($(CROSS_COMPILE),$(saved_cross)) | ||
197 | $(error CROSS_COMPILE changed from \ | ||
198 | "$(saved_cross)" to \ | ||
199 | to "$(CROSS_COMPILE)". \ | ||
200 | Use "make mrproper" to fix it up) | ||
201 | endif | ||
202 | endif | ||
203 | else | ||
204 | CROSS_COMPILE := $(saved_cross) | ||
205 | endif | ||
206 | |||
207 | ifneq ($(ARCH),) | ||
208 | ifneq ($(saved_arch),) | ||
209 | ifneq ($(saved_arch),$(ARCH)) | ||
210 | $(error ARCH changed from \ | ||
211 | "$(saved_arch)" to "$(ARCH)". \ | ||
212 | Use "make mrproper" to fix it up) | ||
213 | endif | ||
214 | endif | ||
215 | else | ||
216 | ifneq ($(saved_arch),) | ||
217 | ARCH := $(saved_arch) | ||
218 | else | ||
219 | ARCH := $(SUBARCH) | ||
220 | endif | ||
221 | endif | ||
185 | 222 | ||
186 | # Architecture as present in compile.h | 223 | # Architecture as present in compile.h |
187 | UTS_MACHINE := $(ARCH) | 224 | UTS_MACHINE := $(ARCH) |
@@ -315,6 +352,7 @@ OBJCOPY = $(CROSS_COMPILE)objcopy | |||
315 | OBJDUMP = $(CROSS_COMPILE)objdump | 352 | OBJDUMP = $(CROSS_COMPILE)objdump |
316 | AWK = awk | 353 | AWK = awk |
317 | GENKSYMS = scripts/genksyms/genksyms | 354 | GENKSYMS = scripts/genksyms/genksyms |
355 | INSTALLKERNEL := installkernel | ||
318 | DEPMOD = /sbin/depmod | 356 | DEPMOD = /sbin/depmod |
319 | KALLSYMS = scripts/kallsyms | 357 | KALLSYMS = scripts/kallsyms |
320 | PERL = perl | 358 | PERL = perl |
@@ -353,7 +391,8 @@ KERNELVERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) | |||
353 | 391 | ||
354 | export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION | 392 | export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION |
355 | export ARCH SRCARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC | 393 | export ARCH SRCARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC |
356 | export CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL UTS_MACHINE | 394 | export CPP AR NM STRIP OBJCOPY OBJDUMP |
395 | export MAKE AWK GENKSYMS INSTALLKERNEL PERL UTS_MACHINE | ||
357 | export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS | 396 | export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS |
358 | 397 | ||
359 | export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS | 398 | export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS |
@@ -444,6 +483,11 @@ ifeq ($(config-targets),1) | |||
444 | include $(srctree)/arch/$(SRCARCH)/Makefile | 483 | include $(srctree)/arch/$(SRCARCH)/Makefile |
445 | export KBUILD_DEFCONFIG KBUILD_KCONFIG | 484 | export KBUILD_DEFCONFIG KBUILD_KCONFIG |
446 | 485 | ||
486 | # save ARCH & CROSS_COMPILE settings | ||
487 | $(shell mkdir -p include/generated && \ | ||
488 | echo $(ARCH) > include/generated/kernel.arch && \ | ||
489 | echo $(CROSS_COMPILE) > include/generated/kernel.cross) | ||
490 | |||
447 | config: scripts_basic outputmakefile FORCE | 491 | config: scripts_basic outputmakefile FORCE |
448 | $(Q)mkdir -p include/linux include/config | 492 | $(Q)mkdir -p include/linux include/config |
449 | $(Q)$(MAKE) $(build)=scripts/kconfig $@ | 493 | $(Q)$(MAKE) $(build)=scripts/kconfig $@ |
@@ -571,6 +615,9 @@ KBUILD_CFLAGS += $(call cc-option,-fno-strict-overflow) | |||
571 | # revert to pre-gcc-4.4 behaviour of .eh_frame | 615 | # revert to pre-gcc-4.4 behaviour of .eh_frame |
572 | KBUILD_CFLAGS += $(call cc-option,-fno-dwarf2-cfi-asm) | 616 | KBUILD_CFLAGS += $(call cc-option,-fno-dwarf2-cfi-asm) |
573 | 617 | ||
618 | # conserve stack if available | ||
619 | KBUILD_CFLAGS += $(call cc-option,-fconserve-stack) | ||
620 | |||
574 | # Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments | 621 | # Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments |
575 | # But warn user when we do so | 622 | # But warn user when we do so |
576 | warn-assign = \ | 623 | warn-assign = \ |
@@ -591,12 +638,12 @@ endif | |||
591 | 638 | ||
592 | # Use --build-id when available. | 639 | # Use --build-id when available. |
593 | LDFLAGS_BUILD_ID = $(patsubst -Wl$(comma)%,%,\ | 640 | LDFLAGS_BUILD_ID = $(patsubst -Wl$(comma)%,%,\ |
594 | $(call ld-option, -Wl$(comma)--build-id,)) | 641 | $(call cc-ldoption, -Wl$(comma)--build-id,)) |
595 | LDFLAGS_MODULE += $(LDFLAGS_BUILD_ID) | 642 | LDFLAGS_MODULE += $(LDFLAGS_BUILD_ID) |
596 | LDFLAGS_vmlinux += $(LDFLAGS_BUILD_ID) | 643 | LDFLAGS_vmlinux += $(LDFLAGS_BUILD_ID) |
597 | 644 | ||
598 | ifeq ($(CONFIG_STRIP_ASM_SYMS),y) | 645 | ifeq ($(CONFIG_STRIP_ASM_SYMS),y) |
599 | LDFLAGS_vmlinux += -X | 646 | LDFLAGS_vmlinux += $(call ld-option, -X,) |
600 | endif | 647 | endif |
601 | 648 | ||
602 | # Default kernel image to build when no specific target is given. | 649 | # Default kernel image to build when no specific target is given. |
@@ -980,11 +1027,6 @@ prepare0: archprepare FORCE | |||
980 | # All the preparing.. | 1027 | # All the preparing.. |
981 | prepare: prepare0 | 1028 | prepare: prepare0 |
982 | 1029 | ||
983 | # Leave this as default for preprocessing vmlinux.lds.S, which is now | ||
984 | # done in arch/$(ARCH)/kernel/Makefile | ||
985 | |||
986 | export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH) | ||
987 | |||
988 | # The asm symlink changes when $(ARCH) changes. | 1030 | # The asm symlink changes when $(ARCH) changes. |
989 | # Detect this and ask user to run make mrproper | 1031 | # Detect this and ask user to run make mrproper |
990 | # If asm is a stale symlink (point to dir that does not exist) remove it | 1032 | # If asm is a stale symlink (point to dir that does not exist) remove it |
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index 3a2fb7a02db4..289039bb6bb2 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/ptrace.h> | 19 | #include <linux/ptrace.h> |
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/user.h> | 21 | #include <linux/user.h> |
22 | #include <linux/utsname.h> | ||
23 | #include <linux/time.h> | 22 | #include <linux/time.h> |
24 | #include <linux/major.h> | 23 | #include <linux/major.h> |
25 | #include <linux/stat.h> | 24 | #include <linux/stat.h> |
diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 54661125a8bf..a73caaf66763 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile | |||
@@ -14,7 +14,7 @@ LDFLAGS_vmlinux :=-p --no-undefined -X | |||
14 | ifeq ($(CONFIG_CPU_ENDIAN_BE8),y) | 14 | ifeq ($(CONFIG_CPU_ENDIAN_BE8),y) |
15 | LDFLAGS_vmlinux += --be8 | 15 | LDFLAGS_vmlinux += --be8 |
16 | endif | 16 | endif |
17 | CPPFLAGS_vmlinux.lds = -DTEXT_OFFSET=$(TEXT_OFFSET) | 17 | |
18 | OBJCOPYFLAGS :=-O binary -R .note -R .note.gnu.build-id -R .comment -S | 18 | OBJCOPYFLAGS :=-O binary -R .note -R .note.gnu.build-id -R .comment -S |
19 | GZFLAGS :=-9 | 19 | GZFLAGS :=-9 |
20 | #KBUILD_CFLAGS +=-pipe | 20 | #KBUILD_CFLAGS +=-pipe |
@@ -279,7 +279,7 @@ define archhelp | |||
279 | echo ' (supply initrd image via make variable INITRD=<path>)' | 279 | echo ' (supply initrd image via make variable INITRD=<path>)' |
280 | echo ' install - Install uncompressed kernel' | 280 | echo ' install - Install uncompressed kernel' |
281 | echo ' zinstall - Install compressed kernel' | 281 | echo ' zinstall - Install compressed kernel' |
282 | echo ' Install using (your) ~/bin/installkernel or' | 282 | echo ' Install using (your) ~/bin/$(INSTALLKERNEL) or' |
283 | echo ' (distribution) /sbin/installkernel or' | 283 | echo ' (distribution) /sbin/$(INSTALLKERNEL) or' |
284 | echo ' install to $$(INSTALL_PATH) and run lilo' | 284 | echo ' install to $$(INSTALL_PATH) and run lilo' |
285 | endef | 285 | endef |
diff --git a/arch/arm/boot/install.sh b/arch/arm/boot/install.sh index 9f9bed207345..06ea7d42ce8e 100644 --- a/arch/arm/boot/install.sh +++ b/arch/arm/boot/install.sh | |||
@@ -21,8 +21,8 @@ | |||
21 | # | 21 | # |
22 | 22 | ||
23 | # User may have a custom install script | 23 | # User may have a custom install script |
24 | if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi | 24 | if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi |
25 | if [ -x /sbin/${CROSS_COMPILE}installkernel ]; then exec /sbin/${CROSS_COMPILE}installkernel "$@"; fi | 25 | if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi |
26 | 26 | ||
27 | if [ "$(basename $2)" = "zImage" ]; then | 27 | if [ "$(basename $2)" = "zImage" ]; then |
28 | # Compressed install | 28 | # Compressed install |
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 3213c9382b17..c446aeff7b89 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile | |||
@@ -2,7 +2,8 @@ | |||
2 | # Makefile for the linux kernel. | 2 | # Makefile for the linux kernel. |
3 | # | 3 | # |
4 | 4 | ||
5 | AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET) | 5 | CPPFLAGS_vmlinux.lds := -DTEXT_OFFSET=$(TEXT_OFFSET) |
6 | AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET) | ||
6 | 7 | ||
7 | ifdef CONFIG_DYNAMIC_FTRACE | 8 | ifdef CONFIG_DYNAMIC_FTRACE |
8 | CFLAGS_REMOVE_ftrace.o = -pg | 9 | CFLAGS_REMOVE_ftrace.o = -pg |
diff --git a/arch/arm/kernel/init_task.c b/arch/arm/kernel/init_task.c index 3f470866bb89..e7cbb50dc356 100644 --- a/arch/arm/kernel/init_task.c +++ b/arch/arm/kernel/init_task.c | |||
@@ -24,9 +24,8 @@ static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | |||
24 | * | 24 | * |
25 | * The things we do for performance.. | 25 | * The things we do for performance.. |
26 | */ | 26 | */ |
27 | union thread_union init_thread_union | 27 | union thread_union init_thread_union __init_task_data = |
28 | __attribute__((__section__(".data.init_task"))) = | 28 | { INIT_THREAD_INFO(init_task) }; |
29 | { INIT_THREAD_INFO(init_task) }; | ||
30 | 29 | ||
31 | /* | 30 | /* |
32 | * Initial task structure. | 31 | * Initial task structure. |
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c index b3ec641b5cf8..78ecaac65206 100644 --- a/arch/arm/kernel/sys_arm.c +++ b/arch/arm/kernel/sys_arm.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/mman.h> | 25 | #include <linux/mman.h> |
26 | #include <linux/fs.h> | 26 | #include <linux/fs.h> |
27 | #include <linux/file.h> | 27 | #include <linux/file.h> |
28 | #include <linux/utsname.h> | ||
29 | #include <linux/ipc.h> | 28 | #include <linux/ipc.h> |
30 | #include <linux/uaccess.h> | 29 | #include <linux/uaccess.h> |
31 | 30 | ||
diff --git a/arch/avr32/kernel/init_task.c b/arch/avr32/kernel/init_task.c index 57ec9f2dcd95..6b2343e6fe33 100644 --- a/arch/avr32/kernel/init_task.c +++ b/arch/avr32/kernel/init_task.c | |||
@@ -18,9 +18,8 @@ static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | |||
18 | /* | 18 | /* |
19 | * Initial thread structure. Must be aligned on an 8192-byte boundary. | 19 | * Initial thread structure. Must be aligned on an 8192-byte boundary. |
20 | */ | 20 | */ |
21 | union thread_union init_thread_union | 21 | union thread_union init_thread_union __init_task_data = |
22 | __attribute__((__section__(".data.init_task"))) = | 22 | { INIT_THREAD_INFO(init_task) }; |
23 | { INIT_THREAD_INFO(init_task) }; | ||
24 | 23 | ||
25 | /* | 24 | /* |
26 | * Initial task structure. | 25 | * Initial task structure. |
diff --git a/arch/avr32/mm/init.c b/arch/avr32/mm/init.c index 376f18c4a6cb..94925641e53e 100644 --- a/arch/avr32/mm/init.c +++ b/arch/avr32/mm/init.c | |||
@@ -24,11 +24,9 @@ | |||
24 | #include <asm/setup.h> | 24 | #include <asm/setup.h> |
25 | #include <asm/sections.h> | 25 | #include <asm/sections.h> |
26 | 26 | ||
27 | #define __page_aligned __attribute__((section(".data.page_aligned"))) | ||
28 | |||
29 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); | 27 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); |
30 | 28 | ||
31 | pgd_t swapper_pg_dir[PTRS_PER_PGD] __page_aligned; | 29 | pgd_t swapper_pg_dir[PTRS_PER_PGD] __page_aligned_data; |
32 | 30 | ||
33 | struct page *empty_zero_page; | 31 | struct page *empty_zero_page; |
34 | EXPORT_SYMBOL(empty_zero_page); | 32 | EXPORT_SYMBOL(empty_zero_page); |
diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile index 6f9533c3d752..f063b772934b 100644 --- a/arch/blackfin/Makefile +++ b/arch/blackfin/Makefile | |||
@@ -155,7 +155,7 @@ define archhelp | |||
155 | echo '* vmImage.gz - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.gz)' | 155 | echo '* vmImage.gz - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.gz)' |
156 | echo ' vmImage.lzma - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.lzma)' | 156 | echo ' vmImage.lzma - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.lzma)' |
157 | echo ' install - Install kernel using' | 157 | echo ' install - Install kernel using' |
158 | echo ' (your) ~/bin/$(CROSS_COMPILE)installkernel or' | 158 | echo ' (your) ~/bin/$(INSTALLKERNEL) or' |
159 | echo ' (distribution) PATH: $(CROSS_COMPILE)installkernel or' | 159 | echo ' (distribution) PATH: $(INSTALLKERNEL) or' |
160 | echo ' install to $$(INSTALL_PATH)' | 160 | echo ' install to $$(INSTALL_PATH)' |
161 | endef | 161 | endef |
diff --git a/arch/blackfin/boot/install.sh b/arch/blackfin/boot/install.sh index 9560a6b29100..e2c6e40902b7 100644 --- a/arch/blackfin/boot/install.sh +++ b/arch/blackfin/boot/install.sh | |||
@@ -36,9 +36,9 @@ verify "$3" | |||
36 | 36 | ||
37 | # User may have a custom install script | 37 | # User may have a custom install script |
38 | 38 | ||
39 | if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi | 39 | if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi |
40 | if which ${CROSS_COMPILE}installkernel >/dev/null 2>&1; then | 40 | if which ${INSTALLKERNEL} >/dev/null 2>&1; then |
41 | exec ${CROSS_COMPILE}installkernel "$@" | 41 | exec ${INSTALLKERNEL} "$@" |
42 | fi | 42 | fi |
43 | 43 | ||
44 | # Default install - same as make zlilo | 44 | # Default install - same as make zlilo |
diff --git a/arch/cris/Makefile b/arch/cris/Makefile index 71e17d3eeddb..29c2ceb38a76 100644 --- a/arch/cris/Makefile +++ b/arch/cris/Makefile | |||
@@ -42,8 +42,6 @@ LD = $(CROSS_COMPILE)ld -mcrislinux | |||
42 | 42 | ||
43 | OBJCOPYFLAGS := -O binary -R .note -R .comment -S | 43 | OBJCOPYFLAGS := -O binary -R .note -R .comment -S |
44 | 44 | ||
45 | CPPFLAGS_vmlinux.lds = -DDRAM_VIRTUAL_BASE=0x$(CONFIG_ETRAX_DRAM_VIRTUAL_BASE) | ||
46 | |||
47 | KBUILD_AFLAGS += -mlinux -march=$(arch-y) $(inc) | 45 | KBUILD_AFLAGS += -mlinux -march=$(arch-y) $(inc) |
48 | KBUILD_CFLAGS += -mlinux -march=$(arch-y) -pipe $(inc) | 46 | KBUILD_CFLAGS += -mlinux -march=$(arch-y) -pipe $(inc) |
49 | KBUILD_CPPFLAGS += $(inc) | 47 | KBUILD_CPPFLAGS += $(inc) |
diff --git a/arch/cris/kernel/Makefile b/arch/cris/kernel/Makefile index ee7bcd4d20b2..b45640b3e600 100644 --- a/arch/cris/kernel/Makefile +++ b/arch/cris/kernel/Makefile | |||
@@ -3,6 +3,7 @@ | |||
3 | # Makefile for the linux kernel. | 3 | # Makefile for the linux kernel. |
4 | # | 4 | # |
5 | 5 | ||
6 | CPPFLAGS_vmlinux.lds := -DDRAM_VIRTUAL_BASE=0x$(CONFIG_ETRAX_DRAM_VIRTUAL_BASE) | ||
6 | extra-y := vmlinux.lds | 7 | extra-y := vmlinux.lds |
7 | 8 | ||
8 | obj-y := process.o traps.o irq.o ptrace.o setup.o time.o sys_cris.o | 9 | obj-y := process.o traps.o irq.o ptrace.o setup.o time.o sys_cris.o |
diff --git a/arch/cris/kernel/process.c b/arch/cris/kernel/process.c index 51dcd04d2777..c99aeab7cef7 100644 --- a/arch/cris/kernel/process.c +++ b/arch/cris/kernel/process.c | |||
@@ -45,9 +45,8 @@ static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | |||
45 | * way process stacks are handled. This is done by having a special | 45 | * way process stacks are handled. This is done by having a special |
46 | * "init_task" linker map entry.. | 46 | * "init_task" linker map entry.. |
47 | */ | 47 | */ |
48 | union thread_union init_thread_union | 48 | union thread_union init_thread_union __init_task_data = |
49 | __attribute__((__section__(".data.init_task"))) = | 49 | { INIT_THREAD_INFO(init_task) }; |
50 | { INIT_THREAD_INFO(init_task) }; | ||
51 | 50 | ||
52 | /* | 51 | /* |
53 | * Initial task structure. | 52 | * Initial task structure. |
diff --git a/arch/frv/kernel/init_task.c b/arch/frv/kernel/init_task.c index 1d3df1d9495c..3c3e0b336a9d 100644 --- a/arch/frv/kernel/init_task.c +++ b/arch/frv/kernel/init_task.c | |||
@@ -19,9 +19,8 @@ static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | |||
19 | * way process stacks are handled. This is done by having a special | 19 | * way process stacks are handled. This is done by having a special |
20 | * "init_task" linker map entry.. | 20 | * "init_task" linker map entry.. |
21 | */ | 21 | */ |
22 | union thread_union init_thread_union | 22 | union thread_union init_thread_union __init_task_data = |
23 | __attribute__((__section__(".data.init_task"))) = | 23 | { INIT_THREAD_INFO(init_task) }; |
24 | { INIT_THREAD_INFO(init_task) }; | ||
25 | 24 | ||
26 | /* | 25 | /* |
27 | * Initial task structure. | 26 | * Initial task structure. |
diff --git a/arch/frv/kernel/sys_frv.c b/arch/frv/kernel/sys_frv.c index baadc97f8627..2b6b5289cdcc 100644 --- a/arch/frv/kernel/sys_frv.c +++ b/arch/frv/kernel/sys_frv.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/stat.h> | 21 | #include <linux/stat.h> |
22 | #include <linux/mman.h> | 22 | #include <linux/mman.h> |
23 | #include <linux/file.h> | 23 | #include <linux/file.h> |
24 | #include <linux/utsname.h> | ||
25 | #include <linux/syscalls.h> | 24 | #include <linux/syscalls.h> |
26 | #include <linux/ipc.h> | 25 | #include <linux/ipc.h> |
27 | 26 | ||
diff --git a/arch/h8300/kernel/init_task.c b/arch/h8300/kernel/init_task.c index 089c65ed6eb3..54c1062ee80e 100644 --- a/arch/h8300/kernel/init_task.c +++ b/arch/h8300/kernel/init_task.c | |||
@@ -31,7 +31,6 @@ EXPORT_SYMBOL(init_task); | |||
31 | * way process stacks are handled. This is done by having a special | 31 | * way process stacks are handled. This is done by having a special |
32 | * "init_task" linker map entry.. | 32 | * "init_task" linker map entry.. |
33 | */ | 33 | */ |
34 | union thread_union init_thread_union | 34 | union thread_union init_thread_union __init_task_data = |
35 | __attribute__((__section__(".data.init_task"))) = | 35 | { INIT_THREAD_INFO(init_task) }; |
36 | { INIT_THREAD_INFO(init_task) }; | ||
37 | 36 | ||
diff --git a/arch/h8300/kernel/sys_h8300.c b/arch/h8300/kernel/sys_h8300.c index 2745656dcc52..8cb5d73a0e35 100644 --- a/arch/h8300/kernel/sys_h8300.c +++ b/arch/h8300/kernel/sys_h8300.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/syscalls.h> | 17 | #include <linux/syscalls.h> |
18 | #include <linux/mman.h> | 18 | #include <linux/mman.h> |
19 | #include <linux/file.h> | 19 | #include <linux/file.h> |
20 | #include <linux/utsname.h> | ||
21 | #include <linux/fs.h> | 20 | #include <linux/fs.h> |
22 | #include <linux/ipc.h> | 21 | #include <linux/ipc.h> |
23 | 22 | ||
diff --git a/arch/ia64/install.sh b/arch/ia64/install.sh index 929e780026d1..0e932f5dcd1a 100644 --- a/arch/ia64/install.sh +++ b/arch/ia64/install.sh | |||
@@ -21,8 +21,8 @@ | |||
21 | 21 | ||
22 | # User may have a custom install script | 22 | # User may have a custom install script |
23 | 23 | ||
24 | if [ -x ~/bin/installkernel ]; then exec ~/bin/installkernel "$@"; fi | 24 | if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi |
25 | if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi | 25 | if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi |
26 | 26 | ||
27 | # Default install - same as make zlilo | 27 | # Default install - same as make zlilo |
28 | 28 | ||
diff --git a/arch/ia64/kernel/Makefile.gate b/arch/ia64/kernel/Makefile.gate index 1d87f84069b3..ab9b03a9adcc 100644 --- a/arch/ia64/kernel/Makefile.gate +++ b/arch/ia64/kernel/Makefile.gate | |||
@@ -10,7 +10,7 @@ quiet_cmd_gate = GATE $@ | |||
10 | cmd_gate = $(CC) -nostdlib $(GATECFLAGS_$(@F)) -Wl,-T,$(filter-out FORCE,$^) -o $@ | 10 | cmd_gate = $(CC) -nostdlib $(GATECFLAGS_$(@F)) -Wl,-T,$(filter-out FORCE,$^) -o $@ |
11 | 11 | ||
12 | GATECFLAGS_gate.so = -shared -s -Wl,-soname=linux-gate.so.1 \ | 12 | GATECFLAGS_gate.so = -shared -s -Wl,-soname=linux-gate.so.1 \ |
13 | $(call ld-option, -Wl$(comma)--hash-style=sysv) | 13 | $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) |
14 | $(obj)/gate.so: $(obj)/gate.lds $(obj)/gate.o FORCE | 14 | $(obj)/gate.so: $(obj)/gate.lds $(obj)/gate.o FORCE |
15 | $(call if_changed,gate) | 15 | $(call if_changed,gate) |
16 | 16 | ||
diff --git a/arch/ia64/kernel/init_task.c b/arch/ia64/kernel/init_task.c index c475fc281be7..e253ab8fcbc8 100644 --- a/arch/ia64/kernel/init_task.c +++ b/arch/ia64/kernel/init_task.c | |||
@@ -33,7 +33,8 @@ union { | |||
33 | struct thread_info thread_info; | 33 | struct thread_info thread_info; |
34 | } s; | 34 | } s; |
35 | unsigned long stack[KERNEL_STACK_SIZE/sizeof (unsigned long)]; | 35 | unsigned long stack[KERNEL_STACK_SIZE/sizeof (unsigned long)]; |
36 | } init_task_mem asm ("init_task") __attribute__((section(".data.init_task"))) = {{ | 36 | } init_task_mem asm ("init_task") __init_task_data = |
37 | {{ | ||
37 | .task = INIT_TASK(init_task_mem.s.task), | 38 | .task = INIT_TASK(init_task_mem.s.task), |
38 | .thread_info = INIT_THREAD_INFO(init_task_mem.s.task) | 39 | .thread_info = INIT_THREAD_INFO(init_task_mem.s.task) |
39 | }}; | 40 | }}; |
diff --git a/arch/m32r/boot/compressed/install.sh b/arch/m32r/boot/compressed/install.sh index 6d72e9e72697..16e5a0a13437 100644 --- a/arch/m32r/boot/compressed/install.sh +++ b/arch/m32r/boot/compressed/install.sh | |||
@@ -24,8 +24,8 @@ | |||
24 | 24 | ||
25 | # User may have a custom install script | 25 | # User may have a custom install script |
26 | 26 | ||
27 | if [ -x /sbin/installkernel ]; then | 27 | if [ -x /sbin/${INSTALLKERNEL} ]; then |
28 | exec /sbin/installkernel "$@" | 28 | exec /sbin/${INSTALLKERNEL} "$@" |
29 | fi | 29 | fi |
30 | 30 | ||
31 | if [ "$2" = "zImage" ]; then | 31 | if [ "$2" = "zImage" ]; then |
diff --git a/arch/m32r/kernel/init_task.c b/arch/m32r/kernel/init_task.c index fce57e5d3f91..6c42d5f8df50 100644 --- a/arch/m32r/kernel/init_task.c +++ b/arch/m32r/kernel/init_task.c | |||
@@ -20,9 +20,8 @@ static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | |||
20 | * way process stacks are handled. This is done by having a special | 20 | * way process stacks are handled. This is done by having a special |
21 | * "init_task" linker map entry.. | 21 | * "init_task" linker map entry.. |
22 | */ | 22 | */ |
23 | union thread_union init_thread_union | 23 | union thread_union init_thread_union __init_task_data = |
24 | __attribute__((__section__(".data.init_task"))) = | 24 | { INIT_THREAD_INFO(init_task) }; |
25 | { INIT_THREAD_INFO(init_task) }; | ||
26 | 25 | ||
27 | /* | 26 | /* |
28 | * Initial task structure. | 27 | * Initial task structure. |
diff --git a/arch/m68k/install.sh b/arch/m68k/install.sh index 9c6bae6112e3..57d640d4382c 100644 --- a/arch/m68k/install.sh +++ b/arch/m68k/install.sh | |||
@@ -33,8 +33,8 @@ verify "$3" | |||
33 | 33 | ||
34 | # User may have a custom install script | 34 | # User may have a custom install script |
35 | 35 | ||
36 | if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi | 36 | if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi |
37 | if [ -x /sbin/${CROSS_COMPILE}installkernel ]; then exec /sbin/${CROSS_COMPILE}installkernel "$@"; fi | 37 | if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi |
38 | 38 | ||
39 | # Default install - same as make zlilo | 39 | # Default install - same as make zlilo |
40 | 40 | ||
diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c index 72bad65dba3a..41230c595a8e 100644 --- a/arch/m68k/kernel/process.c +++ b/arch/m68k/kernel/process.c | |||
@@ -42,9 +42,9 @@ | |||
42 | */ | 42 | */ |
43 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); | 43 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
44 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | 44 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
45 | union thread_union init_thread_union | 45 | union thread_union init_thread_union __init_task_data |
46 | __attribute__((section(".data.init_task"), aligned(THREAD_SIZE))) | 46 | __attribute__((aligned(THREAD_SIZE))) = |
47 | = { INIT_THREAD_INFO(init_task) }; | 47 | { INIT_THREAD_INFO(init_task) }; |
48 | 48 | ||
49 | /* initial task structure */ | 49 | /* initial task structure */ |
50 | struct task_struct init_task = INIT_TASK(init_task); | 50 | struct task_struct init_task = INIT_TASK(init_task); |
diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c index 7f54efaf60bb..7deb402bfc75 100644 --- a/arch/m68k/kernel/sys_m68k.c +++ b/arch/m68k/kernel/sys_m68k.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/syscalls.h> | 20 | #include <linux/syscalls.h> |
21 | #include <linux/mman.h> | 21 | #include <linux/mman.h> |
22 | #include <linux/file.h> | 22 | #include <linux/file.h> |
23 | #include <linux/utsname.h> | ||
24 | #include <linux/ipc.h> | 23 | #include <linux/ipc.h> |
25 | 24 | ||
26 | #include <asm/setup.h> | 25 | #include <asm/setup.h> |
diff --git a/arch/m68knommu/kernel/init_task.c b/arch/m68knommu/kernel/init_task.c index 45e97a207fed..cbf9dc3cc51d 100644 --- a/arch/m68knommu/kernel/init_task.c +++ b/arch/m68knommu/kernel/init_task.c | |||
@@ -31,7 +31,6 @@ EXPORT_SYMBOL(init_task); | |||
31 | * way process stacks are handled. This is done by having a special | 31 | * way process stacks are handled. This is done by having a special |
32 | * "init_task" linker map entry.. | 32 | * "init_task" linker map entry.. |
33 | */ | 33 | */ |
34 | union thread_union init_thread_union | 34 | union thread_union init_thread_union __init_task_data = |
35 | __attribute__((__section__(".data.init_task"))) = | 35 | { INIT_THREAD_INFO(init_task) }; |
36 | { INIT_THREAD_INFO(init_task) }; | ||
37 | 36 | ||
diff --git a/arch/m68knommu/kernel/sys_m68k.c b/arch/m68knommu/kernel/sys_m68k.c index 700281638629..efdd090778a3 100644 --- a/arch/m68knommu/kernel/sys_m68k.c +++ b/arch/m68knommu/kernel/sys_m68k.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/syscalls.h> | 17 | #include <linux/syscalls.h> |
18 | #include <linux/mman.h> | 18 | #include <linux/mman.h> |
19 | #include <linux/file.h> | 19 | #include <linux/file.h> |
20 | #include <linux/utsname.h> | ||
21 | #include <linux/ipc.h> | 20 | #include <linux/ipc.h> |
22 | #include <linux/fs.h> | 21 | #include <linux/fs.h> |
23 | 22 | ||
diff --git a/arch/microblaze/kernel/init_task.c b/arch/microblaze/kernel/init_task.c index 67da22579b62..b5d711f94ff8 100644 --- a/arch/microblaze/kernel/init_task.c +++ b/arch/microblaze/kernel/init_task.c | |||
@@ -19,9 +19,8 @@ | |||
19 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); | 19 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
20 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | 20 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
21 | 21 | ||
22 | union thread_union init_thread_union | 22 | union thread_union init_thread_union __init_task_data = |
23 | __attribute__((__section__(".data.init_task"))) = | 23 | { INIT_THREAD_INFO(init_task) }; |
24 | { INIT_THREAD_INFO(init_task) }; | ||
25 | 24 | ||
26 | struct task_struct init_task = INIT_TASK(init_task); | 25 | struct task_struct init_task = INIT_TASK(init_task); |
27 | EXPORT_SYMBOL(init_task); | 26 | EXPORT_SYMBOL(init_task); |
diff --git a/arch/microblaze/kernel/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c index b96f1682bb24..07cabed4b947 100644 --- a/arch/microblaze/kernel/sys_microblaze.c +++ b/arch/microblaze/kernel/sys_microblaze.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/mman.h> | 23 | #include <linux/mman.h> |
24 | #include <linux/sys.h> | 24 | #include <linux/sys.h> |
25 | #include <linux/ipc.h> | 25 | #include <linux/ipc.h> |
26 | #include <linux/utsname.h> | ||
27 | #include <linux/file.h> | 26 | #include <linux/file.h> |
28 | #include <linux/module.h> | 27 | #include <linux/module.h> |
29 | #include <linux/err.h> | 28 | #include <linux/err.h> |
diff --git a/arch/mips/Makefile b/arch/mips/Makefile index c825b14b4ed0..77f5021218d3 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile | |||
@@ -627,16 +627,6 @@ endif | |||
627 | cflags-y += -I$(srctree)/arch/mips/include/asm/mach-generic | 627 | cflags-y += -I$(srctree)/arch/mips/include/asm/mach-generic |
628 | drivers-$(CONFIG_PCI) += arch/mips/pci/ | 628 | drivers-$(CONFIG_PCI) += arch/mips/pci/ |
629 | 629 | ||
630 | ifdef CONFIG_32BIT | ||
631 | ifdef CONFIG_CPU_LITTLE_ENDIAN | ||
632 | JIFFIES = jiffies_64 | ||
633 | else | ||
634 | JIFFIES = jiffies_64 + 4 | ||
635 | endif | ||
636 | else | ||
637 | JIFFIES = jiffies_64 | ||
638 | endif | ||
639 | |||
640 | # | 630 | # |
641 | # Automatically detect the build format. By default we choose | 631 | # Automatically detect the build format. By default we choose |
642 | # the elf format according to the load address. | 632 | # the elf format according to the load address. |
@@ -660,8 +650,9 @@ ifdef CONFIG_64BIT | |||
660 | endif | 650 | endif |
661 | 651 | ||
662 | KBUILD_AFLAGS += $(cflags-y) | 652 | KBUILD_AFLAGS += $(cflags-y) |
663 | KBUILD_CFLAGS += $(cflags-y) \ | 653 | KBUILD_CFLAGS += $(cflags-y) |
664 | -D"VMLINUX_LOAD_ADDRESS=$(load-y)" | 654 | KBUILD_CPPFLAGS += -D"VMLINUX_LOAD_ADDRESS=$(load-y)" |
655 | KBUILD_CPPFLAGS += -D"DATAOFFSET=$(if $(dataoffset-y),$(dataoffset-y),0)" | ||
665 | 656 | ||
666 | LDFLAGS += -m $(ld-emul) | 657 | LDFLAGS += -m $(ld-emul) |
667 | 658 | ||
@@ -676,18 +667,6 @@ endif | |||
676 | 667 | ||
677 | OBJCOPYFLAGS += --remove-section=.reginfo | 668 | OBJCOPYFLAGS += --remove-section=.reginfo |
678 | 669 | ||
679 | # | ||
680 | # Choosing incompatible machines durings configuration will result in | ||
681 | # error messages during linking. Select a default linkscript if | ||
682 | # none has been choosen above. | ||
683 | # | ||
684 | |||
685 | CPPFLAGS_vmlinux.lds := \ | ||
686 | $(KBUILD_CFLAGS) \ | ||
687 | -D"LOADADDR=$(load-y)" \ | ||
688 | -D"JIFFIES=$(JIFFIES)" \ | ||
689 | -D"DATAOFFSET=$(if $(dataoffset-y),$(dataoffset-y),0)" | ||
690 | |||
691 | head-y := arch/mips/kernel/head.o arch/mips/kernel/init_task.o | 670 | head-y := arch/mips/kernel/head.o arch/mips/kernel/init_task.o |
692 | 671 | ||
693 | libs-y += arch/mips/lib/ | 672 | libs-y += arch/mips/lib/ |
diff --git a/arch/mips/kernel/init_task.c b/arch/mips/kernel/init_task.c index 5b457a40c784..6d6ca5305895 100644 --- a/arch/mips/kernel/init_task.c +++ b/arch/mips/kernel/init_task.c | |||
@@ -21,9 +21,8 @@ static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | |||
21 | * | 21 | * |
22 | * The things we do for performance.. | 22 | * The things we do for performance.. |
23 | */ | 23 | */ |
24 | union thread_union init_thread_union | 24 | union thread_union init_thread_union __init_task_data |
25 | __attribute__((__section__(".data.init_task"), | 25 | __attribute__((__aligned__(THREAD_SIZE))) = |
26 | __aligned__(THREAD_SIZE))) = | ||
27 | { INIT_THREAD_INFO(init_task) }; | 26 | { INIT_THREAD_INFO(init_task) }; |
28 | 27 | ||
29 | /* | 28 | /* |
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 2769bed3d2af..9bf0e3df7c5a 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S | |||
@@ -10,7 +10,16 @@ PHDRS { | |||
10 | text PT_LOAD FLAGS(7); /* RWX */ | 10 | text PT_LOAD FLAGS(7); /* RWX */ |
11 | note PT_NOTE FLAGS(4); /* R__ */ | 11 | note PT_NOTE FLAGS(4); /* R__ */ |
12 | } | 12 | } |
13 | jiffies = JIFFIES; | 13 | |
14 | ifdef CONFIG_32BIT | ||
15 | ifdef CONFIG_CPU_LITTLE_ENDIAN | ||
16 | jiffies = jiffies_64; | ||
17 | else | ||
18 | jiffies = jiffies_64 + 4; | ||
19 | endif | ||
20 | else | ||
21 | jiffies = jiffies_64; | ||
22 | endif | ||
14 | 23 | ||
15 | SECTIONS | 24 | SECTIONS |
16 | { | 25 | { |
@@ -29,7 +38,7 @@ SECTIONS | |||
29 | /* . = 0xa800000000300000; */ | 38 | /* . = 0xa800000000300000; */ |
30 | . = 0xffffffff80300000; | 39 | . = 0xffffffff80300000; |
31 | #endif | 40 | #endif |
32 | . = LOADADDR; | 41 | . = VMLINUX_LOAD_ADDRESS; |
33 | /* read-only */ | 42 | /* read-only */ |
34 | _text = .; /* Text and read-only data */ | 43 | _text = .; /* Text and read-only data */ |
35 | .text : { | 44 | .text : { |
diff --git a/arch/mn10300/kernel/init_task.c b/arch/mn10300/kernel/init_task.c index 80d423b80af3..a481b043bea7 100644 --- a/arch/mn10300/kernel/init_task.c +++ b/arch/mn10300/kernel/init_task.c | |||
@@ -27,9 +27,8 @@ static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | |||
27 | * way process stacks are handled. This is done by having a special | 27 | * way process stacks are handled. This is done by having a special |
28 | * "init_task" linker map entry.. | 28 | * "init_task" linker map entry.. |
29 | */ | 29 | */ |
30 | union thread_union init_thread_union | 30 | union thread_union init_thread_union __init_task_data = |
31 | __attribute__((__section__(".data.init_task"))) = | 31 | { INIT_THREAD_INFO(init_task) }; |
32 | { INIT_THREAD_INFO(init_task) }; | ||
33 | 32 | ||
34 | /* | 33 | /* |
35 | * Initial task structure. | 34 | * Initial task structure. |
diff --git a/arch/mn10300/kernel/sys_mn10300.c b/arch/mn10300/kernel/sys_mn10300.c index 3e52a1054327..8ca5af00334c 100644 --- a/arch/mn10300/kernel/sys_mn10300.c +++ b/arch/mn10300/kernel/sys_mn10300.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/stat.h> | 19 | #include <linux/stat.h> |
20 | #include <linux/mman.h> | 20 | #include <linux/mman.h> |
21 | #include <linux/file.h> | 21 | #include <linux/file.h> |
22 | #include <linux/utsname.h> | ||
23 | #include <linux/tty.h> | 22 | #include <linux/tty.h> |
24 | 23 | ||
25 | #include <asm/uaccess.h> | 24 | #include <asm/uaccess.h> |
diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile index da6f66901c92..55cca1dac431 100644 --- a/arch/parisc/Makefile +++ b/arch/parisc/Makefile | |||
@@ -118,8 +118,8 @@ define archhelp | |||
118 | @echo '* vmlinux - Uncompressed kernel image (./vmlinux)' | 118 | @echo '* vmlinux - Uncompressed kernel image (./vmlinux)' |
119 | @echo ' palo - Bootable image (./lifimage)' | 119 | @echo ' palo - Bootable image (./lifimage)' |
120 | @echo ' install - Install kernel using' | 120 | @echo ' install - Install kernel using' |
121 | @echo ' (your) ~/bin/installkernel or' | 121 | @echo ' (your) ~/bin/$(INSTALLKERNEL) or' |
122 | @echo ' (distribution) /sbin/installkernel or' | 122 | @echo ' (distribution) /sbin/$(INSTALLKERNEL) or' |
123 | @echo ' copy to $$(INSTALL_PATH)' | 123 | @echo ' copy to $$(INSTALL_PATH)' |
124 | endef | 124 | endef |
125 | 125 | ||
diff --git a/arch/parisc/install.sh b/arch/parisc/install.sh index 9632b3e164c7..e593fc8d58bc 100644 --- a/arch/parisc/install.sh +++ b/arch/parisc/install.sh | |||
@@ -21,8 +21,8 @@ | |||
21 | 21 | ||
22 | # User may have a custom install script | 22 | # User may have a custom install script |
23 | 23 | ||
24 | if [ -x ~/bin/installkernel ]; then exec ~/bin/installkernel "$@"; fi | 24 | if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi |
25 | if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi | 25 | if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi |
26 | 26 | ||
27 | # Default install | 27 | # Default install |
28 | 28 | ||
diff --git a/arch/parisc/kernel/init_task.c b/arch/parisc/kernel/init_task.c index 82974b20fc10..d020eae6525c 100644 --- a/arch/parisc/kernel/init_task.c +++ b/arch/parisc/kernel/init_task.c | |||
@@ -43,8 +43,8 @@ static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | |||
43 | * way process stacks are handled. This is done by having a special | 43 | * way process stacks are handled. This is done by having a special |
44 | * "init_task" linker map entry.. | 44 | * "init_task" linker map entry.. |
45 | */ | 45 | */ |
46 | union thread_union init_thread_union | 46 | union thread_union init_thread_union __init_task_data |
47 | __attribute__((aligned(128))) __attribute__((__section__(".data.init_task"))) = | 47 | __attribute__((aligned(128))) = |
48 | { INIT_THREAD_INFO(init_task) }; | 48 | { INIT_THREAD_INFO(init_task) }; |
49 | 49 | ||
50 | #if PT_NLEVELS == 3 | 50 | #if PT_NLEVELS == 3 |
diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c index 92a0acaa0d12..561388b17c91 100644 --- a/arch/parisc/kernel/sys_parisc32.c +++ b/arch/parisc/kernel/sys_parisc32.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/signal.h> | 18 | #include <linux/signal.h> |
19 | #include <linux/resource.h> | 19 | #include <linux/resource.h> |
20 | #include <linux/times.h> | 20 | #include <linux/times.h> |
21 | #include <linux/utsname.h> | ||
22 | #include <linux/time.h> | 21 | #include <linux/time.h> |
23 | #include <linux/smp.h> | 22 | #include <linux/smp.h> |
24 | #include <linux/smp_lock.h> | 23 | #include <linux/smp_lock.h> |
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 952a3963e9e8..aacf629c1a9f 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile | |||
@@ -158,8 +158,6 @@ drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ | |||
158 | # Default to zImage, override when needed | 158 | # Default to zImage, override when needed |
159 | all: zImage | 159 | all: zImage |
160 | 160 | ||
161 | CPPFLAGS_vmlinux.lds := -Upowerpc | ||
162 | |||
163 | BOOT_TARGETS = zImage zImage.initrd uImage zImage% dtbImage% treeImage.% cuImage.% simpleImage.% | 161 | BOOT_TARGETS = zImage zImage.initrd uImage zImage% dtbImage% treeImage.% cuImage.% simpleImage.% |
164 | 162 | ||
165 | PHONY += $(BOOT_TARGETS) | 163 | PHONY += $(BOOT_TARGETS) |
@@ -182,8 +180,8 @@ define archhelp | |||
182 | @echo ' simpleImage.<dt> - Firmware independent image.' | 180 | @echo ' simpleImage.<dt> - Firmware independent image.' |
183 | @echo ' treeImage.<dt> - Support for older IBM 4xx firmware (not U-Boot)' | 181 | @echo ' treeImage.<dt> - Support for older IBM 4xx firmware (not U-Boot)' |
184 | @echo ' install - Install kernel using' | 182 | @echo ' install - Install kernel using' |
185 | @echo ' (your) ~/bin/installkernel or' | 183 | @echo ' (your) ~/bin/$(INSTALLKERNEL) or' |
186 | @echo ' (distribution) /sbin/installkernel or' | 184 | @echo ' (distribution) /sbin/$(INSTALLKERNEL) or' |
187 | @echo ' install to $$(INSTALL_PATH) and run lilo' | 185 | @echo ' install to $$(INSTALL_PATH) and run lilo' |
188 | @echo ' *_defconfig - Select default config from arch/$(ARCH)/configs' | 186 | @echo ' *_defconfig - Select default config from arch/$(ARCH)/configs' |
189 | @echo '' | 187 | @echo '' |
diff --git a/arch/powerpc/boot/install.sh b/arch/powerpc/boot/install.sh index 98312d169c85..b6a256bc96ee 100644 --- a/arch/powerpc/boot/install.sh +++ b/arch/powerpc/boot/install.sh | |||
@@ -23,8 +23,8 @@ set -e | |||
23 | 23 | ||
24 | # User may have a custom install script | 24 | # User may have a custom install script |
25 | 25 | ||
26 | if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi | 26 | if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi |
27 | if [ -x /sbin/${CROSS_COMPILE}installkernel ]; then exec /sbin/${CROSS_COMPILE}installkernel "$@"; fi | 27 | if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi |
28 | 28 | ||
29 | # Default install | 29 | # Default install |
30 | 30 | ||
diff --git a/arch/powerpc/kernel/init_task.c b/arch/powerpc/kernel/init_task.c index ffc4253fef55..2375b7eb1c76 100644 --- a/arch/powerpc/kernel/init_task.c +++ b/arch/powerpc/kernel/init_task.c | |||
@@ -16,9 +16,8 @@ static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | |||
16 | * way process stacks are handled. This is done by having a special | 16 | * way process stacks are handled. This is done by having a special |
17 | * "init_task" linker map entry.. | 17 | * "init_task" linker map entry.. |
18 | */ | 18 | */ |
19 | union thread_union init_thread_union | 19 | union thread_union init_thread_union __init_task_data = |
20 | __attribute__((__section__(".data.init_task"))) = | 20 | { INIT_THREAD_INFO(init_task) }; |
21 | { INIT_THREAD_INFO(init_task) }; | ||
22 | 21 | ||
23 | /* | 22 | /* |
24 | * Initial task structure. | 23 | * Initial task structure. |
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c index 49e705fcee6d..040bd1de8d99 100644 --- a/arch/powerpc/kernel/machine_kexec_64.c +++ b/arch/powerpc/kernel/machine_kexec_64.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/kexec.h> | 13 | #include <linux/kexec.h> |
14 | #include <linux/smp.h> | 14 | #include <linux/smp.h> |
15 | #include <linux/thread_info.h> | 15 | #include <linux/thread_info.h> |
16 | #include <linux/init_task.h> | ||
16 | #include <linux/errno.h> | 17 | #include <linux/errno.h> |
17 | 18 | ||
18 | #include <asm/page.h> | 19 | #include <asm/page.h> |
@@ -249,8 +250,8 @@ static void kexec_prepare_cpus(void) | |||
249 | * We could use a smaller stack if we don't care about anything using | 250 | * We could use a smaller stack if we don't care about anything using |
250 | * current, but that audit has not been performed. | 251 | * current, but that audit has not been performed. |
251 | */ | 252 | */ |
252 | static union thread_union kexec_stack | 253 | static union thread_union kexec_stack __init_task_data = |
253 | __attribute__((__section__(".data.init_task"))) = { }; | 254 | { }; |
254 | 255 | ||
255 | /* Our assembly helper, in kexec_stub.S */ | 256 | /* Our assembly helper, in kexec_stub.S */ |
256 | extern NORET_TYPE void kexec_sequence(void *newstack, unsigned long start, | 257 | extern NORET_TYPE void kexec_sequence(void *newstack, unsigned long start, |
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index 9837d9153c4b..4271f7a655a3 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/seq_file.h> | 24 | #include <linux/seq_file.h> |
25 | #include <linux/ioport.h> | 25 | #include <linux/ioport.h> |
26 | #include <linux/console.h> | 26 | #include <linux/console.h> |
27 | #include <linux/utsname.h> | ||
28 | #include <linux/screen_info.h> | 27 | #include <linux/screen_info.h> |
29 | #include <linux/root_dev.h> | 28 | #include <linux/root_dev.h> |
30 | #include <linux/notifier.h> | 29 | #include <linux/notifier.h> |
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c index 1cc5e9e5da96..b97c2d67f4ac 100644 --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/signal.h> | 22 | #include <linux/signal.h> |
23 | #include <linux/resource.h> | 23 | #include <linux/resource.h> |
24 | #include <linux/times.h> | 24 | #include <linux/times.h> |
25 | #include <linux/utsname.h> | ||
26 | #include <linux/smp.h> | 25 | #include <linux/smp.h> |
27 | #include <linux/smp_lock.h> | 26 | #include <linux/smp_lock.h> |
28 | #include <linux/sem.h> | 27 | #include <linux/sem.h> |
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c index a0abce251d0a..3faaf29bdb29 100644 --- a/arch/powerpc/kernel/vdso.c +++ b/arch/powerpc/kernel/vdso.c | |||
@@ -1,3 +1,4 @@ | |||
1 | |||
1 | /* | 2 | /* |
2 | * Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp. | 3 | * Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp. |
3 | * <benh@kernel.crashing.org> | 4 | * <benh@kernel.crashing.org> |
@@ -74,7 +75,7 @@ static int vdso_ready; | |||
74 | static union { | 75 | static union { |
75 | struct vdso_data data; | 76 | struct vdso_data data; |
76 | u8 page[PAGE_SIZE]; | 77 | u8 page[PAGE_SIZE]; |
77 | } vdso_data_store __attribute__((__section__(".data.page_aligned"))); | 78 | } vdso_data_store __page_aligned_data; |
78 | struct vdso_data *vdso_data = &vdso_data_store.data; | 79 | struct vdso_data *vdso_data = &vdso_data_store.data; |
79 | 80 | ||
80 | /* Format of the patch table */ | 81 | /* Format of the patch table */ |
diff --git a/arch/powerpc/kernel/vdso32/Makefile b/arch/powerpc/kernel/vdso32/Makefile index b54b81688132..51ead52141bd 100644 --- a/arch/powerpc/kernel/vdso32/Makefile +++ b/arch/powerpc/kernel/vdso32/Makefile | |||
@@ -16,7 +16,7 @@ GCOV_PROFILE := n | |||
16 | 16 | ||
17 | EXTRA_CFLAGS := -shared -fno-common -fno-builtin | 17 | EXTRA_CFLAGS := -shared -fno-common -fno-builtin |
18 | EXTRA_CFLAGS += -nostdlib -Wl,-soname=linux-vdso32.so.1 \ | 18 | EXTRA_CFLAGS += -nostdlib -Wl,-soname=linux-vdso32.so.1 \ |
19 | $(call ld-option, -Wl$(comma)--hash-style=sysv) | 19 | $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) |
20 | EXTRA_AFLAGS := -D__VDSO32__ -s | 20 | EXTRA_AFLAGS := -D__VDSO32__ -s |
21 | 21 | ||
22 | obj-y += vdso32_wrapper.o | 22 | obj-y += vdso32_wrapper.o |
diff --git a/arch/powerpc/kernel/vdso32/vdso32_wrapper.S b/arch/powerpc/kernel/vdso32/vdso32_wrapper.S index 556f0caa5d84..6e8f507ed32b 100644 --- a/arch/powerpc/kernel/vdso32/vdso32_wrapper.S +++ b/arch/powerpc/kernel/vdso32/vdso32_wrapper.S | |||
@@ -1,7 +1,8 @@ | |||
1 | #include <linux/init.h> | 1 | #include <linux/init.h> |
2 | #include <linux/linkage.h> | ||
2 | #include <asm/page.h> | 3 | #include <asm/page.h> |
3 | 4 | ||
4 | .section ".data.page_aligned" | 5 | __PAGE_ALIGNED_DATA |
5 | 6 | ||
6 | .globl vdso32_start, vdso32_end | 7 | .globl vdso32_start, vdso32_end |
7 | .balign PAGE_SIZE | 8 | .balign PAGE_SIZE |
diff --git a/arch/powerpc/kernel/vdso64/Makefile b/arch/powerpc/kernel/vdso64/Makefile index dd0c8e936775..79da65d44a2a 100644 --- a/arch/powerpc/kernel/vdso64/Makefile +++ b/arch/powerpc/kernel/vdso64/Makefile | |||
@@ -11,7 +11,7 @@ GCOV_PROFILE := n | |||
11 | 11 | ||
12 | EXTRA_CFLAGS := -shared -fno-common -fno-builtin | 12 | EXTRA_CFLAGS := -shared -fno-common -fno-builtin |
13 | EXTRA_CFLAGS += -nostdlib -Wl,-soname=linux-vdso64.so.1 \ | 13 | EXTRA_CFLAGS += -nostdlib -Wl,-soname=linux-vdso64.so.1 \ |
14 | $(call ld-option, -Wl$(comma)--hash-style=sysv) | 14 | $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) |
15 | EXTRA_AFLAGS := -D__VDSO64__ -s | 15 | EXTRA_AFLAGS := -D__VDSO64__ -s |
16 | 16 | ||
17 | obj-y += vdso64_wrapper.o | 17 | obj-y += vdso64_wrapper.o |
diff --git a/arch/powerpc/kernel/vdso64/vdso64_wrapper.S b/arch/powerpc/kernel/vdso64/vdso64_wrapper.S index 0529cb9e3b97..b8553d62b792 100644 --- a/arch/powerpc/kernel/vdso64/vdso64_wrapper.S +++ b/arch/powerpc/kernel/vdso64/vdso64_wrapper.S | |||
@@ -1,7 +1,8 @@ | |||
1 | #include <linux/init.h> | 1 | #include <linux/init.h> |
2 | #include <linux/linkage.h> | ||
2 | #include <asm/page.h> | 3 | #include <asm/page.h> |
3 | 4 | ||
4 | .section ".data.page_aligned" | 5 | __PAGE_ALIGNED_DATA |
5 | 6 | ||
6 | .globl vdso64_start, vdso64_end | 7 | .globl vdso64_start, vdso64_end |
7 | .balign PAGE_SIZE | 8 | .balign PAGE_SIZE |
diff --git a/arch/s390/boot/install.sh b/arch/s390/boot/install.sh index d4026f62cb06..aed3069699bd 100644 --- a/arch/s390/boot/install.sh +++ b/arch/s390/boot/install.sh | |||
@@ -21,8 +21,8 @@ | |||
21 | 21 | ||
22 | # User may have a custom install script | 22 | # User may have a custom install script |
23 | 23 | ||
24 | if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi | 24 | if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi |
25 | if [ -x /sbin/${CROSS_COMPILE}installkernel ]; then exec /sbin/${CROSS_COMPILE}installkernel "$@"; fi | 25 | if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi |
26 | 26 | ||
27 | # Default install - same as make zlilo | 27 | # Default install - same as make zlilo |
28 | 28 | ||
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 5519cb745106..0debcec23a39 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/signal.h> | 24 | #include <linux/signal.h> |
25 | #include <linux/resource.h> | 25 | #include <linux/resource.h> |
26 | #include <linux/times.h> | 26 | #include <linux/times.h> |
27 | #include <linux/utsname.h> | ||
28 | #include <linux/smp.h> | 27 | #include <linux/smp.h> |
29 | #include <linux/smp_lock.h> | 28 | #include <linux/smp_lock.h> |
30 | #include <linux/sem.h> | 29 | #include <linux/sem.h> |
diff --git a/arch/s390/kernel/init_task.c b/arch/s390/kernel/init_task.c index fe787f9e5f3f..4d1c9fb0b540 100644 --- a/arch/s390/kernel/init_task.c +++ b/arch/s390/kernel/init_task.c | |||
@@ -25,9 +25,8 @@ static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | |||
25 | * way process stacks are handled. This is done by having a special | 25 | * way process stacks are handled. This is done by having a special |
26 | * "init_task" linker map entry.. | 26 | * "init_task" linker map entry.. |
27 | */ | 27 | */ |
28 | union thread_union init_thread_union | 28 | union thread_union init_thread_union __init_task_data = |
29 | __attribute__((__section__(".data.init_task"))) = | 29 | { INIT_THREAD_INFO(init_task) }; |
30 | { INIT_THREAD_INFO(init_task) }; | ||
31 | 30 | ||
32 | /* | 31 | /* |
33 | * Initial task structure. | 32 | * Initial task structure. |
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 59fe6ecc6ed3..5417eb57271a 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/notifier.h> | 29 | #include <linux/notifier.h> |
30 | #include <linux/utsname.h> | ||
31 | #include <linux/tick.h> | 30 | #include <linux/tick.h> |
32 | #include <linux/elfcore.h> | 31 | #include <linux/elfcore.h> |
33 | #include <linux/kernel_stat.h> | 32 | #include <linux/kernel_stat.h> |
diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c index 45e1708b70fd..45a3e9a7ae21 100644 --- a/arch/s390/kernel/vdso.c +++ b/arch/s390/kernel/vdso.c | |||
@@ -75,7 +75,7 @@ __setup("vdso=", vdso_setup); | |||
75 | static union { | 75 | static union { |
76 | struct vdso_data data; | 76 | struct vdso_data data; |
77 | u8 page[PAGE_SIZE]; | 77 | u8 page[PAGE_SIZE]; |
78 | } vdso_data_store __attribute__((__section__(".data.page_aligned"))); | 78 | } vdso_data_store __page_aligned_data; |
79 | struct vdso_data *vdso_data = &vdso_data_store.data; | 79 | struct vdso_data *vdso_data = &vdso_data_store.data; |
80 | 80 | ||
81 | /* | 81 | /* |
diff --git a/arch/s390/kernel/vdso32/Makefile b/arch/s390/kernel/vdso32/Makefile index ca78ad60ba24..d13e8755a8cc 100644 --- a/arch/s390/kernel/vdso32/Makefile +++ b/arch/s390/kernel/vdso32/Makefile | |||
@@ -13,7 +13,7 @@ KBUILD_AFLAGS_31 += -m31 -s | |||
13 | KBUILD_CFLAGS_31 := $(filter-out -m64,$(KBUILD_CFLAGS)) | 13 | KBUILD_CFLAGS_31 := $(filter-out -m64,$(KBUILD_CFLAGS)) |
14 | KBUILD_CFLAGS_31 += -m31 -fPIC -shared -fno-common -fno-builtin | 14 | KBUILD_CFLAGS_31 += -m31 -fPIC -shared -fno-common -fno-builtin |
15 | KBUILD_CFLAGS_31 += -nostdlib -Wl,-soname=linux-vdso32.so.1 \ | 15 | KBUILD_CFLAGS_31 += -nostdlib -Wl,-soname=linux-vdso32.so.1 \ |
16 | $(call ld-option, -Wl$(comma)--hash-style=sysv) | 16 | $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) |
17 | 17 | ||
18 | $(targets:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_31) | 18 | $(targets:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_31) |
19 | $(targets:%=$(obj)/%.dbg): KBUILD_AFLAGS = $(KBUILD_AFLAGS_31) | 19 | $(targets:%=$(obj)/%.dbg): KBUILD_AFLAGS = $(KBUILD_AFLAGS_31) |
diff --git a/arch/s390/kernel/vdso32/vdso32_wrapper.S b/arch/s390/kernel/vdso32/vdso32_wrapper.S index 61639a89e70b..ae42f8ce350b 100644 --- a/arch/s390/kernel/vdso32/vdso32_wrapper.S +++ b/arch/s390/kernel/vdso32/vdso32_wrapper.S | |||
@@ -1,7 +1,8 @@ | |||
1 | #include <linux/init.h> | 1 | #include <linux/init.h> |
2 | #include <linux/linkage.h> | ||
2 | #include <asm/page.h> | 3 | #include <asm/page.h> |
3 | 4 | ||
4 | .section ".data.page_aligned" | 5 | __PAGE_ALIGNED_DATA |
5 | 6 | ||
6 | .globl vdso32_start, vdso32_end | 7 | .globl vdso32_start, vdso32_end |
7 | .balign PAGE_SIZE | 8 | .balign PAGE_SIZE |
diff --git a/arch/s390/kernel/vdso64/Makefile b/arch/s390/kernel/vdso64/Makefile index 6fc8e829258c..449352dda9cd 100644 --- a/arch/s390/kernel/vdso64/Makefile +++ b/arch/s390/kernel/vdso64/Makefile | |||
@@ -13,7 +13,7 @@ KBUILD_AFLAGS_64 += -m64 -s | |||
13 | KBUILD_CFLAGS_64 := $(filter-out -m64,$(KBUILD_CFLAGS)) | 13 | KBUILD_CFLAGS_64 := $(filter-out -m64,$(KBUILD_CFLAGS)) |
14 | KBUILD_CFLAGS_64 += -m64 -fPIC -shared -fno-common -fno-builtin | 14 | KBUILD_CFLAGS_64 += -m64 -fPIC -shared -fno-common -fno-builtin |
15 | KBUILD_CFLAGS_64 += -nostdlib -Wl,-soname=linux-vdso64.so.1 \ | 15 | KBUILD_CFLAGS_64 += -nostdlib -Wl,-soname=linux-vdso64.so.1 \ |
16 | $(call ld-option, -Wl$(comma)--hash-style=sysv) | 16 | $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) |
17 | 17 | ||
18 | $(targets:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_64) | 18 | $(targets:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_64) |
19 | $(targets:%=$(obj)/%.dbg): KBUILD_AFLAGS = $(KBUILD_AFLAGS_64) | 19 | $(targets:%=$(obj)/%.dbg): KBUILD_AFLAGS = $(KBUILD_AFLAGS_64) |
diff --git a/arch/s390/kernel/vdso64/vdso64_wrapper.S b/arch/s390/kernel/vdso64/vdso64_wrapper.S index d8e2ac14d564..c245842b516f 100644 --- a/arch/s390/kernel/vdso64/vdso64_wrapper.S +++ b/arch/s390/kernel/vdso64/vdso64_wrapper.S | |||
@@ -1,7 +1,8 @@ | |||
1 | #include <linux/init.h> | 1 | #include <linux/init.h> |
2 | #include <linux/linkage.h> | ||
2 | #include <asm/page.h> | 3 | #include <asm/page.h> |
3 | 4 | ||
4 | .section ".data.page_aligned" | 5 | __PAGE_ALIGNED_DATA |
5 | 6 | ||
6 | .globl vdso64_start, vdso64_end | 7 | .globl vdso64_start, vdso64_end |
7 | .balign PAGE_SIZE | 8 | .balign PAGE_SIZE |
diff --git a/arch/score/kernel/init_task.c b/arch/score/kernel/init_task.c index ff952f6c63fd..baa03ee217d1 100644 --- a/arch/score/kernel/init_task.c +++ b/arch/score/kernel/init_task.c | |||
@@ -34,9 +34,8 @@ static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | |||
34 | * way process stacks are handled. This is done by having a special | 34 | * way process stacks are handled. This is done by having a special |
35 | * "init_task" linker map entry.. | 35 | * "init_task" linker map entry.. |
36 | */ | 36 | */ |
37 | union thread_union init_thread_union | 37 | union thread_union init_thread_union __init_task_data = |
38 | __attribute__((__section__(".data.init_task"), __aligned__(THREAD_SIZE))) = | 38 | { INIT_THREAD_INFO(init_task) }; |
39 | { INIT_THREAD_INFO(init_task) }; | ||
40 | 39 | ||
41 | /* | 40 | /* |
42 | * Initial task structure. | 41 | * Initial task structure. |
diff --git a/arch/sh/boot/compressed/install.sh b/arch/sh/boot/compressed/install.sh index 90589f0fec12..f9f41818b17e 100644 --- a/arch/sh/boot/compressed/install.sh +++ b/arch/sh/boot/compressed/install.sh | |||
@@ -23,8 +23,8 @@ | |||
23 | 23 | ||
24 | # User may have a custom install script | 24 | # User may have a custom install script |
25 | 25 | ||
26 | if [ -x /sbin/installkernel ]; then | 26 | if [ -x /sbin/${INSTALLKERNEL} ]; then |
27 | exec /sbin/installkernel "$@" | 27 | exec /sbin/${INSTALLKERNEL} "$@" |
28 | fi | 28 | fi |
29 | 29 | ||
30 | if [ "$2" = "zImage" ]; then | 30 | if [ "$2" = "zImage" ]; then |
diff --git a/arch/sh/kernel/init_task.c b/arch/sh/kernel/init_task.c index 1719957c0a69..11f2ea556a6b 100644 --- a/arch/sh/kernel/init_task.c +++ b/arch/sh/kernel/init_task.c | |||
@@ -17,9 +17,8 @@ struct pt_regs fake_swapper_regs; | |||
17 | * way process stacks are handled. This is done by having a special | 17 | * way process stacks are handled. This is done by having a special |
18 | * "init_task" linker map entry.. | 18 | * "init_task" linker map entry.. |
19 | */ | 19 | */ |
20 | union thread_union init_thread_union | 20 | union thread_union init_thread_union __init_task_data = |
21 | __attribute__((__section__(".data.init_task"))) = | 21 | { INIT_THREAD_INFO(init_task) }; |
22 | { INIT_THREAD_INFO(init_task) }; | ||
23 | 22 | ||
24 | /* | 23 | /* |
25 | * Initial task structure. | 24 | * Initial task structure. |
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index 60f8af4497c7..7cb933ba4957 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c | |||
@@ -165,11 +165,9 @@ asmlinkage int do_IRQ(unsigned int irq, struct pt_regs *regs) | |||
165 | } | 165 | } |
166 | 166 | ||
167 | #ifdef CONFIG_IRQSTACKS | 167 | #ifdef CONFIG_IRQSTACKS |
168 | static char softirq_stack[NR_CPUS * THREAD_SIZE] | 168 | static char softirq_stack[NR_CPUS * THREAD_SIZE] __page_aligned_bss; |
169 | __attribute__((__section__(".bss.page_aligned"))); | ||
170 | 169 | ||
171 | static char hardirq_stack[NR_CPUS * THREAD_SIZE] | 170 | static char hardirq_stack[NR_CPUS * THREAD_SIZE] __page_aligned_bss; |
172 | __attribute__((__section__(".bss.page_aligned"))); | ||
173 | 171 | ||
174 | /* | 172 | /* |
175 | * allocate per-cpu stacks for hardirq and for softirq processing | 173 | * allocate per-cpu stacks for hardirq and for softirq processing |
diff --git a/arch/sh/kernel/sys_sh32.c b/arch/sh/kernel/sys_sh32.c index 63ba12836eae..eb68bfdd86e6 100644 --- a/arch/sh/kernel/sys_sh32.c +++ b/arch/sh/kernel/sys_sh32.c | |||
@@ -9,7 +9,6 @@ | |||
9 | #include <linux/syscalls.h> | 9 | #include <linux/syscalls.h> |
10 | #include <linux/mman.h> | 10 | #include <linux/mman.h> |
11 | #include <linux/file.h> | 11 | #include <linux/file.h> |
12 | #include <linux/utsname.h> | ||
13 | #include <linux/module.h> | 12 | #include <linux/module.h> |
14 | #include <linux/fs.h> | 13 | #include <linux/fs.h> |
15 | #include <linux/ipc.h> | 14 | #include <linux/ipc.h> |
diff --git a/arch/sh/kernel/sys_sh64.c b/arch/sh/kernel/sys_sh64.c index 91fb8445a5a0..287235768bc5 100644 --- a/arch/sh/kernel/sys_sh64.c +++ b/arch/sh/kernel/sys_sh64.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/stat.h> | 23 | #include <linux/stat.h> |
24 | #include <linux/mman.h> | 24 | #include <linux/mman.h> |
25 | #include <linux/file.h> | 25 | #include <linux/file.h> |
26 | #include <linux/utsname.h> | ||
27 | #include <linux/syscalls.h> | 26 | #include <linux/syscalls.h> |
28 | #include <linux/ipc.h> | 27 | #include <linux/ipc.h> |
29 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
diff --git a/arch/sh/kernel/vsyscall/Makefile b/arch/sh/kernel/vsyscall/Makefile index 4bbce1cfa359..8f0ea5fc835c 100644 --- a/arch/sh/kernel/vsyscall/Makefile +++ b/arch/sh/kernel/vsyscall/Makefile | |||
@@ -15,7 +15,7 @@ quiet_cmd_syscall = SYSCALL $@ | |||
15 | export CPPFLAGS_vsyscall.lds += -P -C -Ush | 15 | export CPPFLAGS_vsyscall.lds += -P -C -Ush |
16 | 16 | ||
17 | vsyscall-flags = -shared -s -Wl,-soname=linux-gate.so.1 \ | 17 | vsyscall-flags = -shared -s -Wl,-soname=linux-gate.so.1 \ |
18 | $(call ld-option, -Wl$(comma)--hash-style=sysv) | 18 | $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) |
19 | 19 | ||
20 | SYSCFLAGS_vsyscall-trapa.so = $(vsyscall-flags) | 20 | SYSCFLAGS_vsyscall-trapa.so = $(vsyscall-flags) |
21 | 21 | ||
diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile index 467221dd5702..dfe272d14465 100644 --- a/arch/sparc/Makefile +++ b/arch/sparc/Makefile | |||
@@ -31,7 +31,6 @@ export BITS := 32 | |||
31 | #KBUILD_CFLAGS += -g -pipe -fcall-used-g5 -fcall-used-g7 | 31 | #KBUILD_CFLAGS += -g -pipe -fcall-used-g5 -fcall-used-g7 |
32 | KBUILD_CFLAGS += -m32 -pipe -mno-fpu -fcall-used-g5 -fcall-used-g7 | 32 | KBUILD_CFLAGS += -m32 -pipe -mno-fpu -fcall-used-g5 -fcall-used-g7 |
33 | KBUILD_AFLAGS += -m32 | 33 | KBUILD_AFLAGS += -m32 |
34 | CPPFLAGS_vmlinux.lds += -m32 | ||
35 | 34 | ||
36 | #LDFLAGS_vmlinux = -N -Ttext 0xf0004000 | 35 | #LDFLAGS_vmlinux = -N -Ttext 0xf0004000 |
37 | # Since 2.5.40, the first stage is left not btfix-ed. | 36 | # Since 2.5.40, the first stage is left not btfix-ed. |
@@ -45,9 +44,6 @@ else | |||
45 | 44 | ||
46 | CHECKFLAGS += -D__sparc__ -D__sparc_v9__ -D__arch64__ -m64 | 45 | CHECKFLAGS += -D__sparc__ -D__sparc_v9__ -D__arch64__ -m64 |
47 | 46 | ||
48 | # Undefine sparc when processing vmlinux.lds - it is used | ||
49 | # And teach CPP we are doing 64 bit builds (for this case) | ||
50 | CPPFLAGS_vmlinux.lds += -m64 -Usparc | ||
51 | LDFLAGS := -m elf64_sparc | 47 | LDFLAGS := -m elf64_sparc |
52 | export BITS := 64 | 48 | export BITS := 64 |
53 | 49 | ||
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index 3a048fad7ee2..5b47fab9966e 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile | |||
@@ -7,7 +7,11 @@ ccflags-y := -Werror | |||
7 | 7 | ||
8 | extra-y := head_$(BITS).o | 8 | extra-y := head_$(BITS).o |
9 | extra-y += init_task.o | 9 | extra-y += init_task.o |
10 | extra-y += vmlinux.lds | 10 | |
11 | # Undefine sparc when processing vmlinux.lds - it is used | ||
12 | # And teach CPP we are doing $(BITS) builds (for this case) | ||
13 | CPPFLAGS_vmlinux.lds := -Usparc -m$(BITS) | ||
14 | extra-y += vmlinux.lds | ||
11 | 15 | ||
12 | obj-$(CONFIG_SPARC32) += entry.o wof.o wuf.o | 16 | obj-$(CONFIG_SPARC32) += entry.o wof.o wuf.o |
13 | obj-$(CONFIG_SPARC32) += etrap_32.o | 17 | obj-$(CONFIG_SPARC32) += etrap_32.o |
diff --git a/arch/sparc/kernel/init_task.c b/arch/sparc/kernel/init_task.c index 28125c5b3d3c..5fe3d65581f7 100644 --- a/arch/sparc/kernel/init_task.c +++ b/arch/sparc/kernel/init_task.c | |||
@@ -18,6 +18,5 @@ EXPORT_SYMBOL(init_task); | |||
18 | * If this is not aligned on a 8k boundry, then you should change code | 18 | * If this is not aligned on a 8k boundry, then you should change code |
19 | * in etrap.S which assumes it. | 19 | * in etrap.S which assumes it. |
20 | */ | 20 | */ |
21 | union thread_union init_thread_union | 21 | union thread_union init_thread_union __init_task_data = |
22 | __attribute__((section (".data.init_task"))) | 22 | { INIT_THREAD_INFO(init_task) }; |
23 | = { INIT_THREAD_INFO(init_task) }; | ||
diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c index f5000a460c05..04e28b2671c8 100644 --- a/arch/sparc/kernel/sys_sparc32.c +++ b/arch/sparc/kernel/sys_sparc32.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/signal.h> | 16 | #include <linux/signal.h> |
17 | #include <linux/resource.h> | 17 | #include <linux/resource.h> |
18 | #include <linux/times.h> | 18 | #include <linux/times.h> |
19 | #include <linux/utsname.h> | ||
20 | #include <linux/smp.h> | 19 | #include <linux/smp.h> |
21 | #include <linux/smp_lock.h> | 20 | #include <linux/smp_lock.h> |
22 | #include <linux/sem.h> | 21 | #include <linux/sem.h> |
diff --git a/arch/sparc/kernel/systbls.h b/arch/sparc/kernel/systbls.h index 15c2d752b2bc..a63c5d2d9849 100644 --- a/arch/sparc/kernel/systbls.h +++ b/arch/sparc/kernel/systbls.h | |||
@@ -3,10 +3,11 @@ | |||
3 | 3 | ||
4 | #include <linux/kernel.h> | 4 | #include <linux/kernel.h> |
5 | #include <linux/types.h> | 5 | #include <linux/types.h> |
6 | #include <linux/utsname.h> | ||
7 | #include <asm/utrap.h> | 6 | #include <asm/utrap.h> |
8 | #include <asm/signal.h> | 7 | #include <asm/signal.h> |
9 | 8 | ||
9 | struct new_utsname; | ||
10 | |||
10 | extern asmlinkage unsigned long sys_getpagesize(void); | 11 | extern asmlinkage unsigned long sys_getpagesize(void); |
11 | extern asmlinkage unsigned long sparc_brk(unsigned long brk); | 12 | extern asmlinkage unsigned long sparc_brk(unsigned long brk); |
12 | extern asmlinkage long sparc_pipe(struct pt_regs *regs); | 13 | extern asmlinkage long sparc_pipe(struct pt_regs *regs); |
diff --git a/arch/um/Makefile b/arch/um/Makefile index 0728def32234..fc633dbacf84 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile | |||
@@ -96,11 +96,10 @@ CFLAGS_NO_HARDENING := $(call cc-option, -fno-PIC,) $(call cc-option, -fno-pic,) | |||
96 | $(call cc-option, -fno-stack-protector,) \ | 96 | $(call cc-option, -fno-stack-protector,) \ |
97 | $(call cc-option, -fno-stack-protector-all,) | 97 | $(call cc-option, -fno-stack-protector-all,) |
98 | 98 | ||
99 | CONFIG_KERNEL_STACK_ORDER ?= 2 | 99 | # Options used by linker script |
100 | STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] ) | 100 | export LDS_START := $(START) |
101 | 101 | export LDS_ELF_ARCH := $(ELF_ARCH) | |
102 | CPPFLAGS_vmlinux.lds = -U$(SUBARCH) -DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \ | 102 | export LDS_ELF_FORMAT := $(ELF_FORMAT) |
103 | -DELF_FORMAT="$(ELF_FORMAT)" -DKERNEL_STACK_SIZE=$(STACK_SIZE) | ||
104 | 103 | ||
105 | # The wrappers will select whether using "malloc" or the kernel allocator. | 104 | # The wrappers will select whether using "malloc" or the kernel allocator. |
106 | LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc | 105 | LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc |
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile index 388ec0a3ea9b..1119233597a1 100644 --- a/arch/um/kernel/Makefile +++ b/arch/um/kernel/Makefile | |||
@@ -3,6 +3,9 @@ | |||
3 | # Licensed under the GPL | 3 | # Licensed under the GPL |
4 | # | 4 | # |
5 | 5 | ||
6 | CPPFLAGS_vmlinux.lds := -U$(SUBARCH) -DSTART=$(LDS_START) \ | ||
7 | -DELF_ARCH=$(LDS_ELF_ARCH) \ | ||
8 | -DELF_FORMAT=$(LDS_ELF_FORMAT) | ||
6 | extra-y := vmlinux.lds | 9 | extra-y := vmlinux.lds |
7 | clean-files := | 10 | clean-files := |
8 | 11 | ||
diff --git a/arch/um/kernel/init_task.c b/arch/um/kernel/init_task.c index b25121b537d8..8aa77b61a5ff 100644 --- a/arch/um/kernel/init_task.c +++ b/arch/um/kernel/init_task.c | |||
@@ -30,9 +30,8 @@ EXPORT_SYMBOL(init_task); | |||
30 | * "init_task" linker map entry.. | 30 | * "init_task" linker map entry.. |
31 | */ | 31 | */ |
32 | 32 | ||
33 | union thread_union init_thread_union | 33 | union thread_union init_thread_union __init_task_data = |
34 | __attribute__((__section__(".data.init_task"))) = | 34 | { INIT_THREAD_INFO(init_task) }; |
35 | { INIT_THREAD_INFO(init_task) }; | ||
36 | 35 | ||
37 | union thread_union cpu0_irqstack | 36 | union thread_union cpu0_irqstack |
38 | __attribute__((__section__(".data.init_irqstack"))) = | 37 | __attribute__((__section__(".data.init_irqstack"))) = |
diff --git a/arch/um/kernel/vmlinux.lds.S b/arch/um/kernel/vmlinux.lds.S index f8aeb448aab6..16e49bfa2b42 100644 --- a/arch/um/kernel/vmlinux.lds.S +++ b/arch/um/kernel/vmlinux.lds.S | |||
@@ -1,3 +1,6 @@ | |||
1 | |||
2 | KERNEL_STACK_SIZE = 4096 * (1 << CONFIG_KERNEL_STACK_ORDER); | ||
3 | |||
1 | #ifdef CONFIG_LD_SCRIPT_STATIC | 4 | #ifdef CONFIG_LD_SCRIPT_STATIC |
2 | #include "uml.lds.S" | 5 | #include "uml.lds.S" |
3 | #else | 6 | #else |
diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 7983c420eaf2..a012ee8ef803 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile | |||
@@ -179,8 +179,8 @@ archclean: | |||
179 | define archhelp | 179 | define archhelp |
180 | echo '* bzImage - Compressed kernel image (arch/x86/boot/bzImage)' | 180 | echo '* bzImage - Compressed kernel image (arch/x86/boot/bzImage)' |
181 | echo ' install - Install kernel using' | 181 | echo ' install - Install kernel using' |
182 | echo ' (your) ~/bin/installkernel or' | 182 | echo ' (your) ~/bin/$(INSTALLKERNEL) or' |
183 | echo ' (distribution) /sbin/installkernel or' | 183 | echo ' (distribution) /sbin/$(INSTALLKERNEL) or' |
184 | echo ' install to $$(INSTALL_PATH) and run lilo' | 184 | echo ' install to $$(INSTALL_PATH) and run lilo' |
185 | echo ' fdimage - Create 1.4MB boot floppy image (arch/x86/boot/fdimage)' | 185 | echo ' fdimage - Create 1.4MB boot floppy image (arch/x86/boot/fdimage)' |
186 | echo ' fdimage144 - Create 1.4MB boot floppy image (arch/x86/boot/fdimage)' | 186 | echo ' fdimage144 - Create 1.4MB boot floppy image (arch/x86/boot/fdimage)' |
diff --git a/arch/x86/boot/install.sh b/arch/x86/boot/install.sh index 8d60ee15dfd9..d13ec1c38640 100644 --- a/arch/x86/boot/install.sh +++ b/arch/x86/boot/install.sh | |||
@@ -33,8 +33,8 @@ verify "$3" | |||
33 | 33 | ||
34 | # User may have a custom install script | 34 | # User may have a custom install script |
35 | 35 | ||
36 | if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi | 36 | if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi |
37 | if [ -x /sbin/${CROSS_COMPILE}installkernel ]; then exec /sbin/${CROSS_COMPILE}installkernel "$@"; fi | 37 | if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi |
38 | 38 | ||
39 | # Default install - same as make zlilo | 39 | # Default install - same as make zlilo |
40 | 40 | ||
diff --git a/arch/x86/include/asm/cache.h b/arch/x86/include/asm/cache.h index 5d367caa0e36..549860d3be8f 100644 --- a/arch/x86/include/asm/cache.h +++ b/arch/x86/include/asm/cache.h | |||
@@ -1,6 +1,8 @@ | |||
1 | #ifndef _ASM_X86_CACHE_H | 1 | #ifndef _ASM_X86_CACHE_H |
2 | #define _ASM_X86_CACHE_H | 2 | #define _ASM_X86_CACHE_H |
3 | 3 | ||
4 | #include <linux/linkage.h> | ||
5 | |||
4 | /* L1 cache line size */ | 6 | /* L1 cache line size */ |
5 | #define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT) | 7 | #define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT) |
6 | #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) | 8 | #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) |
@@ -13,7 +15,7 @@ | |||
13 | #ifdef CONFIG_SMP | 15 | #ifdef CONFIG_SMP |
14 | #define __cacheline_aligned_in_smp \ | 16 | #define __cacheline_aligned_in_smp \ |
15 | __attribute__((__aligned__(1 << (INTERNODE_CACHE_SHIFT)))) \ | 17 | __attribute__((__aligned__(1 << (INTERNODE_CACHE_SHIFT)))) \ |
16 | __attribute__((__section__(".data.page_aligned"))) | 18 | __page_aligned_data |
17 | #endif | 19 | #endif |
18 | #endif | 20 | #endif |
19 | 21 | ||
diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c index bca5fba91c9e..f7dd2a7c3bf4 100644 --- a/arch/x86/kernel/dumpstack_32.c +++ b/arch/x86/kernel/dumpstack_32.c | |||
@@ -5,7 +5,6 @@ | |||
5 | #include <linux/kallsyms.h> | 5 | #include <linux/kallsyms.h> |
6 | #include <linux/kprobes.h> | 6 | #include <linux/kprobes.h> |
7 | #include <linux/uaccess.h> | 7 | #include <linux/uaccess.h> |
8 | #include <linux/utsname.h> | ||
9 | #include <linux/hardirq.h> | 8 | #include <linux/hardirq.h> |
10 | #include <linux/kdebug.h> | 9 | #include <linux/kdebug.h> |
11 | #include <linux/module.h> | 10 | #include <linux/module.h> |
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c index 54b0a3276766..a071e6be177e 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c | |||
@@ -5,7 +5,6 @@ | |||
5 | #include <linux/kallsyms.h> | 5 | #include <linux/kallsyms.h> |
6 | #include <linux/kprobes.h> | 6 | #include <linux/kprobes.h> |
7 | #include <linux/uaccess.h> | 7 | #include <linux/uaccess.h> |
8 | #include <linux/utsname.h> | ||
9 | #include <linux/hardirq.h> | 8 | #include <linux/hardirq.h> |
10 | #include <linux/kdebug.h> | 9 | #include <linux/kdebug.h> |
11 | #include <linux/module.h> | 10 | #include <linux/module.h> |
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index b766e8c7252d..218aad7ee76e 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S | |||
@@ -608,7 +608,7 @@ ENTRY(initial_code) | |||
608 | /* | 608 | /* |
609 | * BSS section | 609 | * BSS section |
610 | */ | 610 | */ |
611 | .section ".bss.page_aligned","wa" | 611 | __PAGE_ALIGNED_BSS |
612 | .align PAGE_SIZE_asm | 612 | .align PAGE_SIZE_asm |
613 | #ifdef CONFIG_X86_PAE | 613 | #ifdef CONFIG_X86_PAE |
614 | swapper_pg_pmd: | 614 | swapper_pg_pmd: |
@@ -626,7 +626,7 @@ ENTRY(empty_zero_page) | |||
626 | * This starts the data section. | 626 | * This starts the data section. |
627 | */ | 627 | */ |
628 | #ifdef CONFIG_X86_PAE | 628 | #ifdef CONFIG_X86_PAE |
629 | .section ".data.page_aligned","wa" | 629 | __PAGE_ALIGNED_DATA |
630 | /* Page-aligned for the benefit of paravirt? */ | 630 | /* Page-aligned for the benefit of paravirt? */ |
631 | .align PAGE_SIZE_asm | 631 | .align PAGE_SIZE_asm |
632 | ENTRY(swapper_pg_dir) | 632 | ENTRY(swapper_pg_dir) |
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index fa54f78e2a05..d0bc0a13a437 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S | |||
@@ -418,7 +418,7 @@ ENTRY(phys_base) | |||
418 | ENTRY(idt_table) | 418 | ENTRY(idt_table) |
419 | .skip IDT_ENTRIES * 16 | 419 | .skip IDT_ENTRIES * 16 |
420 | 420 | ||
421 | .section .bss.page_aligned, "aw", @nobits | 421 | __PAGE_ALIGNED_BSS |
422 | .align PAGE_SIZE | 422 | .align PAGE_SIZE |
423 | ENTRY(empty_zero_page) | 423 | ENTRY(empty_zero_page) |
424 | .skip PAGE_SIZE | 424 | .skip PAGE_SIZE |
diff --git a/arch/x86/kernel/init_task.c b/arch/x86/kernel/init_task.c index 270ff83efc11..3a54dcb9cd0e 100644 --- a/arch/x86/kernel/init_task.c +++ b/arch/x86/kernel/init_task.c | |||
@@ -20,9 +20,8 @@ static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | |||
20 | * way process stacks are handled. This is done by having a special | 20 | * way process stacks are handled. This is done by having a special |
21 | * "init_task" linker map entry.. | 21 | * "init_task" linker map entry.. |
22 | */ | 22 | */ |
23 | union thread_union init_thread_union | 23 | union thread_union init_thread_union __init_task_data = |
24 | __attribute__((__section__(".data.init_task"))) = | 24 | { INIT_THREAD_INFO(init_task) }; |
25 | { INIT_THREAD_INFO(init_task) }; | ||
26 | 25 | ||
27 | /* | 26 | /* |
28 | * Initial task structure. | 27 | * Initial task structure. |
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 9346e102338d..a665c71352b8 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/spinlock.h> | 14 | #include <linux/spinlock.h> |
15 | #include <linux/kprobes.h> | 15 | #include <linux/kprobes.h> |
16 | #include <linux/uaccess.h> | 16 | #include <linux/uaccess.h> |
17 | #include <linux/utsname.h> | ||
18 | #include <linux/kdebug.h> | 17 | #include <linux/kdebug.h> |
19 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
20 | #include <linux/module.h> | 19 | #include <linux/module.h> |
diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile index 88112b49f02c..6b4ffedb93c9 100644 --- a/arch/x86/vdso/Makefile +++ b/arch/x86/vdso/Makefile | |||
@@ -122,7 +122,7 @@ quiet_cmd_vdso = VDSO $@ | |||
122 | $(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$(filter %.lds,$(^F))) \ | 122 | $(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$(filter %.lds,$(^F))) \ |
123 | -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^) | 123 | -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^) |
124 | 124 | ||
125 | VDSO_LDFLAGS = -fPIC -shared $(call ld-option, -Wl$(comma)--hash-style=sysv) | 125 | VDSO_LDFLAGS = -fPIC -shared $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) |
126 | GCOV_PROFILE := n | 126 | GCOV_PROFILE := n |
127 | 127 | ||
128 | # | 128 | # |
diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile index fe3186de6a33..6f56d95f2c1e 100644 --- a/arch/xtensa/kernel/Makefile +++ b/arch/xtensa/kernel/Makefile | |||
@@ -27,7 +27,8 @@ sed-y = -e 's/(\(\.[a-z]*it\|\.ref\|\)\.text)/(\1.literal \1.text)/g' \ | |||
27 | -e 's/(\(\.text\.[a-z]*\))/(\1.literal \1)/g' | 27 | -e 's/(\(\.text\.[a-z]*\))/(\1.literal \1)/g' |
28 | 28 | ||
29 | quiet_cmd__cpp_lds_S = LDS $@ | 29 | quiet_cmd__cpp_lds_S = LDS $@ |
30 | cmd__cpp_lds_S = $(CPP) $(cpp_flags) -D__ASSEMBLY__ $< | sed $(sed-y) >$@ | 30 | cmd__cpp_lds_S = $(CPP) $(cpp_flags) -P -C -Uxtensa -D__ASSEMBLY__ $< \ |
31 | | sed $(sed-y) >$@ | ||
31 | 32 | ||
32 | $(obj)/vmlinux.lds: $(src)/vmlinux.lds.S FORCE | 33 | $(obj)/vmlinux.lds: $(src)/vmlinux.lds.S FORCE |
33 | $(call if_changed_dep,_cpp_lds_S) | 34 | $(call if_changed_dep,_cpp_lds_S) |
diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S index d9ddc1ba761c..d215adcfd4ea 100644 --- a/arch/xtensa/kernel/head.S +++ b/arch/xtensa/kernel/head.S | |||
@@ -235,7 +235,7 @@ should_never_return: | |||
235 | * BSS section | 235 | * BSS section |
236 | */ | 236 | */ |
237 | 237 | ||
238 | .section ".bss.page_aligned", "w" | 238 | __PAGE_ALIGNED_BSS |
239 | #ifdef CONFIG_MMU | 239 | #ifdef CONFIG_MMU |
240 | ENTRY(swapper_pg_dir) | 240 | ENTRY(swapper_pg_dir) |
241 | .fill PAGE_SIZE, 1, 0 | 241 | .fill PAGE_SIZE, 1, 0 |
diff --git a/arch/xtensa/kernel/init_task.c b/arch/xtensa/kernel/init_task.c index c4302f0e4ba0..cd122fb7e48a 100644 --- a/arch/xtensa/kernel/init_task.c +++ b/arch/xtensa/kernel/init_task.c | |||
@@ -23,9 +23,8 @@ | |||
23 | 23 | ||
24 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); | 24 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); |
25 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | 25 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); |
26 | union thread_union init_thread_union | 26 | union thread_union init_thread_union __init_task_data = |
27 | __attribute__((__section__(".data.init_task"))) = | 27 | { INIT_THREAD_INFO(init_task) }; |
28 | { INIT_THREAD_INFO(init_task) }; | ||
29 | 28 | ||
30 | struct task_struct init_task = INIT_TASK(init_task); | 29 | struct task_struct init_task = INIT_TASK(init_task); |
31 | 30 | ||
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 32b957efa420..45d58002b06c 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
@@ -742,7 +742,7 @@ EXPORT_SYMBOL_GPL(tpm_pcr_read); | |||
742 | * the module usage count. | 742 | * the module usage count. |
743 | */ | 743 | */ |
744 | #define TPM_ORD_PCR_EXTEND cpu_to_be32(20) | 744 | #define TPM_ORD_PCR_EXTEND cpu_to_be32(20) |
745 | #define EXTEND_PCR_SIZE 34 | 745 | #define EXTEND_PCR_RESULT_SIZE 34 |
746 | static struct tpm_input_header pcrextend_header = { | 746 | static struct tpm_input_header pcrextend_header = { |
747 | .tag = TPM_TAG_RQU_COMMAND, | 747 | .tag = TPM_TAG_RQU_COMMAND, |
748 | .length = cpu_to_be32(34), | 748 | .length = cpu_to_be32(34), |
@@ -760,10 +760,9 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash) | |||
760 | return -ENODEV; | 760 | return -ENODEV; |
761 | 761 | ||
762 | cmd.header.in = pcrextend_header; | 762 | cmd.header.in = pcrextend_header; |
763 | BUG_ON(be32_to_cpu(cmd.header.in.length) > EXTEND_PCR_SIZE); | ||
764 | cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx); | 763 | cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx); |
765 | memcpy(cmd.params.pcrextend_in.hash, hash, TPM_DIGEST_SIZE); | 764 | memcpy(cmd.params.pcrextend_in.hash, hash, TPM_DIGEST_SIZE); |
766 | rc = transmit_cmd(chip, &cmd, cmd.header.in.length, | 765 | rc = transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE, |
767 | "attempting extend a PCR value"); | 766 | "attempting extend a PCR value"); |
768 | 767 | ||
769 | module_put(chip->dev->driver->owner); | 768 | module_put(chip->dev->driver->owner); |
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index ed7711d11ae8..6857560144bd 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -325,34 +325,6 @@ config SENSORS_F75375S | |||
325 | This driver can also be built as a module. If so, the module | 325 | This driver can also be built as a module. If so, the module |
326 | will be called f75375s. | 326 | will be called f75375s. |
327 | 327 | ||
328 | config SENSORS_FSCHER | ||
329 | tristate "FSC Hermes (DEPRECATED)" | ||
330 | depends on X86 && I2C | ||
331 | help | ||
332 | This driver is DEPRECATED please use the new merged fschmd | ||
333 | ("FSC Poseidon, Scylla, Hermes, Heimdall and Heracles") driver | ||
334 | instead. | ||
335 | |||
336 | If you say yes here you get support for Fujitsu Siemens | ||
337 | Computers Hermes sensor chips. | ||
338 | |||
339 | This driver can also be built as a module. If so, the module | ||
340 | will be called fscher. | ||
341 | |||
342 | config SENSORS_FSCPOS | ||
343 | tristate "FSC Poseidon (DEPRECATED)" | ||
344 | depends on X86 && I2C | ||
345 | help | ||
346 | This driver is DEPRECATED please use the new merged fschmd | ||
347 | ("FSC Poseidon, Scylla, Hermes, Heimdall and Heracles") driver | ||
348 | instead. | ||
349 | |||
350 | If you say yes here you get support for Fujitsu Siemens | ||
351 | Computers Poseidon sensor chips. | ||
352 | |||
353 | This driver can also be built as a module. If so, the module | ||
354 | will be called fscpos. | ||
355 | |||
356 | config SENSORS_FSCHMD | 328 | config SENSORS_FSCHMD |
357 | tristate "Fujitsu Siemens Computers sensor chips" | 329 | tristate "Fujitsu Siemens Computers sensor chips" |
358 | depends on X86 && I2C | 330 | depends on X86 && I2C |
@@ -401,12 +373,12 @@ config SENSORS_GL520SM | |||
401 | will be called gl520sm. | 373 | will be called gl520sm. |
402 | 374 | ||
403 | config SENSORS_CORETEMP | 375 | config SENSORS_CORETEMP |
404 | tristate "Intel Core (2) Duo/Solo temperature sensor" | 376 | tristate "Intel Core/Core2/Atom temperature sensor" |
405 | depends on X86 && EXPERIMENTAL | 377 | depends on X86 && EXPERIMENTAL |
406 | help | 378 | help |
407 | If you say yes here you get support for the temperature | 379 | If you say yes here you get support for the temperature |
408 | sensor inside your CPU. Supported all are all known variants | 380 | sensor inside your CPU. Most of the family 6 CPUs |
409 | of Intel Core family. | 381 | are supported. Check documentation/driver for details. |
410 | 382 | ||
411 | config SENSORS_IBMAEM | 383 | config SENSORS_IBMAEM |
412 | tristate "IBM Active Energy Manager temperature/power sensors and control" | 384 | tristate "IBM Active Energy Manager temperature/power sensors and control" |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index bcf73a9bb619..9f46cb019cc6 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
@@ -42,9 +42,7 @@ obj-$(CONFIG_SENSORS_DS1621) += ds1621.o | |||
42 | obj-$(CONFIG_SENSORS_F71805F) += f71805f.o | 42 | obj-$(CONFIG_SENSORS_F71805F) += f71805f.o |
43 | obj-$(CONFIG_SENSORS_F71882FG) += f71882fg.o | 43 | obj-$(CONFIG_SENSORS_F71882FG) += f71882fg.o |
44 | obj-$(CONFIG_SENSORS_F75375S) += f75375s.o | 44 | obj-$(CONFIG_SENSORS_F75375S) += f75375s.o |
45 | obj-$(CONFIG_SENSORS_FSCHER) += fscher.o | ||
46 | obj-$(CONFIG_SENSORS_FSCHMD) += fschmd.o | 45 | obj-$(CONFIG_SENSORS_FSCHMD) += fschmd.o |
47 | obj-$(CONFIG_SENSORS_FSCPOS) += fscpos.o | ||
48 | obj-$(CONFIG_SENSORS_G760A) += g760a.o | 46 | obj-$(CONFIG_SENSORS_G760A) += g760a.o |
49 | obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o | 47 | obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o |
50 | obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o | 48 | obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o |
diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c index 789441830cd8..56905955352c 100644 --- a/drivers/hwmon/adm1031.c +++ b/drivers/hwmon/adm1031.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #define ADM1031_REG_PWM (0x22) | 37 | #define ADM1031_REG_PWM (0x22) |
38 | #define ADM1031_REG_FAN_MIN(nr) (0x10 + (nr)) | 38 | #define ADM1031_REG_FAN_MIN(nr) (0x10 + (nr)) |
39 | 39 | ||
40 | #define ADM1031_REG_TEMP_OFFSET(nr) (0x0d + (nr)) | ||
40 | #define ADM1031_REG_TEMP_MAX(nr) (0x14 + 4 * (nr)) | 41 | #define ADM1031_REG_TEMP_MAX(nr) (0x14 + 4 * (nr)) |
41 | #define ADM1031_REG_TEMP_MIN(nr) (0x15 + 4 * (nr)) | 42 | #define ADM1031_REG_TEMP_MIN(nr) (0x15 + 4 * (nr)) |
42 | #define ADM1031_REG_TEMP_CRIT(nr) (0x16 + 4 * (nr)) | 43 | #define ADM1031_REG_TEMP_CRIT(nr) (0x16 + 4 * (nr)) |
@@ -93,6 +94,7 @@ struct adm1031_data { | |||
93 | u8 auto_temp_min[3]; | 94 | u8 auto_temp_min[3]; |
94 | u8 auto_temp_off[3]; | 95 | u8 auto_temp_off[3]; |
95 | u8 auto_temp_max[3]; | 96 | u8 auto_temp_max[3]; |
97 | s8 temp_offset[3]; | ||
96 | s8 temp_min[3]; | 98 | s8 temp_min[3]; |
97 | s8 temp_max[3]; | 99 | s8 temp_max[3]; |
98 | s8 temp_crit[3]; | 100 | s8 temp_crit[3]; |
@@ -145,6 +147,10 @@ adm1031_write_value(struct i2c_client *client, u8 reg, unsigned int value) | |||
145 | 147 | ||
146 | #define TEMP_FROM_REG_EXT(val, ext) (TEMP_FROM_REG(val) + (ext) * 125) | 148 | #define TEMP_FROM_REG_EXT(val, ext) (TEMP_FROM_REG(val) + (ext) * 125) |
147 | 149 | ||
150 | #define TEMP_OFFSET_TO_REG(val) (TEMP_TO_REG(val) & 0x8f) | ||
151 | #define TEMP_OFFSET_FROM_REG(val) TEMP_FROM_REG((val) < 0 ? \ | ||
152 | (val) | 0x70 : (val)) | ||
153 | |||
148 | #define FAN_FROM_REG(reg, div) ((reg) ? (11250 * 60) / ((reg) * (div)) : 0) | 154 | #define FAN_FROM_REG(reg, div) ((reg) ? (11250 * 60) / ((reg) * (div)) : 0) |
149 | 155 | ||
150 | static int FAN_TO_REG(int reg, int div) | 156 | static int FAN_TO_REG(int reg, int div) |
@@ -585,6 +591,14 @@ static ssize_t show_temp(struct device *dev, | |||
585 | (((data->ext_temp[nr] >> ((nr - 1) * 3)) & 7)); | 591 | (((data->ext_temp[nr] >> ((nr - 1) * 3)) & 7)); |
586 | return sprintf(buf, "%d\n", TEMP_FROM_REG_EXT(data->temp[nr], ext)); | 592 | return sprintf(buf, "%d\n", TEMP_FROM_REG_EXT(data->temp[nr], ext)); |
587 | } | 593 | } |
594 | static ssize_t show_temp_offset(struct device *dev, | ||
595 | struct device_attribute *attr, char *buf) | ||
596 | { | ||
597 | int nr = to_sensor_dev_attr(attr)->index; | ||
598 | struct adm1031_data *data = adm1031_update_device(dev); | ||
599 | return sprintf(buf, "%d\n", | ||
600 | TEMP_OFFSET_FROM_REG(data->temp_offset[nr])); | ||
601 | } | ||
588 | static ssize_t show_temp_min(struct device *dev, | 602 | static ssize_t show_temp_min(struct device *dev, |
589 | struct device_attribute *attr, char *buf) | 603 | struct device_attribute *attr, char *buf) |
590 | { | 604 | { |
@@ -606,6 +620,24 @@ static ssize_t show_temp_crit(struct device *dev, | |||
606 | struct adm1031_data *data = adm1031_update_device(dev); | 620 | struct adm1031_data *data = adm1031_update_device(dev); |
607 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit[nr])); | 621 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit[nr])); |
608 | } | 622 | } |
623 | static ssize_t set_temp_offset(struct device *dev, | ||
624 | struct device_attribute *attr, const char *buf, | ||
625 | size_t count) | ||
626 | { | ||
627 | struct i2c_client *client = to_i2c_client(dev); | ||
628 | struct adm1031_data *data = i2c_get_clientdata(client); | ||
629 | int nr = to_sensor_dev_attr(attr)->index; | ||
630 | int val; | ||
631 | |||
632 | val = simple_strtol(buf, NULL, 10); | ||
633 | val = SENSORS_LIMIT(val, -15000, 15000); | ||
634 | mutex_lock(&data->update_lock); | ||
635 | data->temp_offset[nr] = TEMP_OFFSET_TO_REG(val); | ||
636 | adm1031_write_value(client, ADM1031_REG_TEMP_OFFSET(nr), | ||
637 | data->temp_offset[nr]); | ||
638 | mutex_unlock(&data->update_lock); | ||
639 | return count; | ||
640 | } | ||
609 | static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, | 641 | static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, |
610 | const char *buf, size_t count) | 642 | const char *buf, size_t count) |
611 | { | 643 | { |
@@ -661,6 +693,8 @@ static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr, | |||
661 | #define temp_reg(offset) \ | 693 | #define temp_reg(offset) \ |
662 | static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ | 694 | static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ |
663 | show_temp, NULL, offset - 1); \ | 695 | show_temp, NULL, offset - 1); \ |
696 | static SENSOR_DEVICE_ATTR(temp##offset##_offset, S_IRUGO | S_IWUSR, \ | ||
697 | show_temp_offset, set_temp_offset, offset - 1); \ | ||
664 | static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \ | 698 | static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \ |
665 | show_temp_min, set_temp_min, offset - 1); \ | 699 | show_temp_min, set_temp_min, offset - 1); \ |
666 | static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ | 700 | static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ |
@@ -714,6 +748,7 @@ static struct attribute *adm1031_attributes[] = { | |||
714 | &sensor_dev_attr_pwm1.dev_attr.attr, | 748 | &sensor_dev_attr_pwm1.dev_attr.attr, |
715 | &sensor_dev_attr_auto_fan1_channel.dev_attr.attr, | 749 | &sensor_dev_attr_auto_fan1_channel.dev_attr.attr, |
716 | &sensor_dev_attr_temp1_input.dev_attr.attr, | 750 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
751 | &sensor_dev_attr_temp1_offset.dev_attr.attr, | ||
717 | &sensor_dev_attr_temp1_min.dev_attr.attr, | 752 | &sensor_dev_attr_temp1_min.dev_attr.attr, |
718 | &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, | 753 | &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, |
719 | &sensor_dev_attr_temp1_max.dev_attr.attr, | 754 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
@@ -721,6 +756,7 @@ static struct attribute *adm1031_attributes[] = { | |||
721 | &sensor_dev_attr_temp1_crit.dev_attr.attr, | 756 | &sensor_dev_attr_temp1_crit.dev_attr.attr, |
722 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, | 757 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, |
723 | &sensor_dev_attr_temp2_input.dev_attr.attr, | 758 | &sensor_dev_attr_temp2_input.dev_attr.attr, |
759 | &sensor_dev_attr_temp2_offset.dev_attr.attr, | ||
724 | &sensor_dev_attr_temp2_min.dev_attr.attr, | 760 | &sensor_dev_attr_temp2_min.dev_attr.attr, |
725 | &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, | 761 | &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, |
726 | &sensor_dev_attr_temp2_max.dev_attr.attr, | 762 | &sensor_dev_attr_temp2_max.dev_attr.attr, |
@@ -757,6 +793,7 @@ static struct attribute *adm1031_attributes_opt[] = { | |||
757 | &sensor_dev_attr_pwm2.dev_attr.attr, | 793 | &sensor_dev_attr_pwm2.dev_attr.attr, |
758 | &sensor_dev_attr_auto_fan2_channel.dev_attr.attr, | 794 | &sensor_dev_attr_auto_fan2_channel.dev_attr.attr, |
759 | &sensor_dev_attr_temp3_input.dev_attr.attr, | 795 | &sensor_dev_attr_temp3_input.dev_attr.attr, |
796 | &sensor_dev_attr_temp3_offset.dev_attr.attr, | ||
760 | &sensor_dev_attr_temp3_min.dev_attr.attr, | 797 | &sensor_dev_attr_temp3_min.dev_attr.attr, |
761 | &sensor_dev_attr_temp3_min_alarm.dev_attr.attr, | 798 | &sensor_dev_attr_temp3_min_alarm.dev_attr.attr, |
762 | &sensor_dev_attr_temp3_max.dev_attr.attr, | 799 | &sensor_dev_attr_temp3_max.dev_attr.attr, |
@@ -937,6 +974,9 @@ static struct adm1031_data *adm1031_update_device(struct device *dev) | |||
937 | } | 974 | } |
938 | data->temp[chan] = newh; | 975 | data->temp[chan] = newh; |
939 | 976 | ||
977 | data->temp_offset[chan] = | ||
978 | adm1031_read_value(client, | ||
979 | ADM1031_REG_TEMP_OFFSET(chan)); | ||
940 | data->temp_min[chan] = | 980 | data->temp_min[chan] = |
941 | adm1031_read_value(client, | 981 | adm1031_read_value(client, |
942 | ADM1031_REG_TEMP_MIN(chan)); | 982 | ADM1031_REG_TEMP_MIN(chan)); |
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 972cf4ba963c..caef39cda8c8 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c | |||
@@ -157,17 +157,26 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device * | |||
157 | /* The 100C is default for both mobile and non mobile CPUs */ | 157 | /* The 100C is default for both mobile and non mobile CPUs */ |
158 | 158 | ||
159 | int tjmax = 100000; | 159 | int tjmax = 100000; |
160 | int ismobile = 1; | 160 | int tjmax_ee = 85000; |
161 | int usemsr_ee = 1; | ||
161 | int err; | 162 | int err; |
162 | u32 eax, edx; | 163 | u32 eax, edx; |
163 | 164 | ||
164 | /* Early chips have no MSR for TjMax */ | 165 | /* Early chips have no MSR for TjMax */ |
165 | 166 | ||
166 | if ((c->x86_model == 0xf) && (c->x86_mask < 4)) { | 167 | if ((c->x86_model == 0xf) && (c->x86_mask < 4)) { |
167 | ismobile = 0; | 168 | usemsr_ee = 0; |
168 | } | 169 | } |
169 | 170 | ||
170 | if ((c->x86_model > 0xe) && (ismobile)) { | 171 | /* Atoms seems to have TjMax at 90C */ |
172 | |||
173 | if (c->x86_model == 0x1c) { | ||
174 | usemsr_ee = 0; | ||
175 | tjmax = 90000; | ||
176 | } | ||
177 | |||
178 | if ((c->x86_model > 0xe) && (usemsr_ee)) { | ||
179 | u8 platform_id; | ||
171 | 180 | ||
172 | /* Now we can detect the mobile CPU using Intel provided table | 181 | /* Now we can detect the mobile CPU using Intel provided table |
173 | http://softwarecommunity.intel.com/Wiki/Mobility/720.htm | 182 | http://softwarecommunity.intel.com/Wiki/Mobility/720.htm |
@@ -179,13 +188,29 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device * | |||
179 | dev_warn(dev, | 188 | dev_warn(dev, |
180 | "Unable to access MSR 0x17, assuming desktop" | 189 | "Unable to access MSR 0x17, assuming desktop" |
181 | " CPU\n"); | 190 | " CPU\n"); |
182 | ismobile = 0; | 191 | usemsr_ee = 0; |
183 | } else if (!(eax & 0x10000000)) { | 192 | } else if (c->x86_model < 0x17 && !(eax & 0x10000000)) { |
184 | ismobile = 0; | 193 | /* Trust bit 28 up to Penryn, I could not find any |
194 | documentation on that; if you happen to know | ||
195 | someone at Intel please ask */ | ||
196 | usemsr_ee = 0; | ||
197 | } else { | ||
198 | /* Platform ID bits 52:50 (EDX starts at bit 32) */ | ||
199 | platform_id = (edx >> 18) & 0x7; | ||
200 | |||
201 | /* Mobile Penryn CPU seems to be platform ID 7 or 5 | ||
202 | (guesswork) */ | ||
203 | if ((c->x86_model == 0x17) && | ||
204 | ((platform_id == 5) || (platform_id == 7))) { | ||
205 | /* If MSR EE bit is set, set it to 90 degrees C, | ||
206 | otherwise 105 degrees C */ | ||
207 | tjmax_ee = 90000; | ||
208 | tjmax = 105000; | ||
209 | } | ||
185 | } | 210 | } |
186 | } | 211 | } |
187 | 212 | ||
188 | if (ismobile || c->x86_model == 0x1c) { | 213 | if (usemsr_ee) { |
189 | 214 | ||
190 | err = rdmsr_safe_on_cpu(id, 0xee, &eax, &edx); | 215 | err = rdmsr_safe_on_cpu(id, 0xee, &eax, &edx); |
191 | if (err) { | 216 | if (err) { |
@@ -193,9 +218,11 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device * | |||
193 | "Unable to access MSR 0xEE, for Tjmax, left" | 218 | "Unable to access MSR 0xEE, for Tjmax, left" |
194 | " at default"); | 219 | " at default"); |
195 | } else if (eax & 0x40000000) { | 220 | } else if (eax & 0x40000000) { |
196 | tjmax = 85000; | 221 | tjmax = tjmax_ee; |
197 | } | 222 | } |
198 | } else { | 223 | /* if we dont use msr EE it means we are desktop CPU (with exeception |
224 | of Atom) */ | ||
225 | } else if (tjmax == 100000) { | ||
199 | dev_warn(dev, "Using relative temperature scale!\n"); | 226 | dev_warn(dev, "Using relative temperature scale!\n"); |
200 | } | 227 | } |
201 | 228 | ||
@@ -248,9 +275,9 @@ static int __devinit coretemp_probe(struct platform_device *pdev) | |||
248 | platform_set_drvdata(pdev, data); | 275 | platform_set_drvdata(pdev, data); |
249 | 276 | ||
250 | /* read the still undocumented IA32_TEMPERATURE_TARGET it exists | 277 | /* read the still undocumented IA32_TEMPERATURE_TARGET it exists |
251 | on older CPUs but not in this register */ | 278 | on older CPUs but not in this register, Atoms don't have it either */ |
252 | 279 | ||
253 | if (c->x86_model > 0xe) { | 280 | if ((c->x86_model > 0xe) && (c->x86_model != 0x1c)) { |
254 | err = rdmsr_safe_on_cpu(data->id, 0x1a2, &eax, &edx); | 281 | err = rdmsr_safe_on_cpu(data->id, 0x1a2, &eax, &edx); |
255 | if (err) { | 282 | if (err) { |
256 | dev_warn(&pdev->dev, "Unable to read" | 283 | dev_warn(&pdev->dev, "Unable to read" |
@@ -413,11 +440,15 @@ static int __init coretemp_init(void) | |||
413 | for_each_online_cpu(i) { | 440 | for_each_online_cpu(i) { |
414 | struct cpuinfo_x86 *c = &cpu_data(i); | 441 | struct cpuinfo_x86 *c = &cpu_data(i); |
415 | 442 | ||
416 | /* check if family 6, models 0xe, 0xf, 0x16, 0x17, 0x1A */ | 443 | /* check if family 6, models 0xe (Pentium M DC), |
444 | 0xf (Core 2 DC 65nm), 0x16 (Core 2 SC 65nm), | ||
445 | 0x17 (Penryn 45nm), 0x1a (Nehalem), 0x1c (Atom), | ||
446 | 0x1e (Lynnfield) */ | ||
417 | if ((c->cpuid_level < 0) || (c->x86 != 0x6) || | 447 | if ((c->cpuid_level < 0) || (c->x86 != 0x6) || |
418 | !((c->x86_model == 0xe) || (c->x86_model == 0xf) || | 448 | !((c->x86_model == 0xe) || (c->x86_model == 0xf) || |
419 | (c->x86_model == 0x16) || (c->x86_model == 0x17) || | 449 | (c->x86_model == 0x16) || (c->x86_model == 0x17) || |
420 | (c->x86_model == 0x1A) || (c->x86_model == 0x1c))) { | 450 | (c->x86_model == 0x1a) || (c->x86_model == 0x1c) || |
451 | (c->x86_model == 0x1e))) { | ||
421 | 452 | ||
422 | /* supported CPU not found, but report the unknown | 453 | /* supported CPU not found, but report the unknown |
423 | family 6 CPU */ | 454 | family 6 CPU */ |
diff --git a/drivers/hwmon/fscher.c b/drivers/hwmon/fscher.c deleted file mode 100644 index 12c70e402cb2..000000000000 --- a/drivers/hwmon/fscher.c +++ /dev/null | |||
@@ -1,680 +0,0 @@ | |||
1 | /* | ||
2 | * fscher.c - Part of lm_sensors, Linux kernel modules for hardware | ||
3 | * monitoring | ||
4 | * Copyright (C) 2003, 2004 Reinhard Nissl <rnissl@gmx.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | /* | ||
22 | * fujitsu siemens hermes chip, | ||
23 | * module based on fscpos.c | ||
24 | * Copyright (C) 2000 Hermann Jung <hej@odn.de> | ||
25 | * Copyright (C) 1998, 1999 Frodo Looijaard <frodol@dds.nl> | ||
26 | * and Philip Edelbrock <phil@netroedge.com> | ||
27 | */ | ||
28 | |||
29 | #include <linux/module.h> | ||
30 | #include <linux/init.h> | ||
31 | #include <linux/slab.h> | ||
32 | #include <linux/jiffies.h> | ||
33 | #include <linux/i2c.h> | ||
34 | #include <linux/hwmon.h> | ||
35 | #include <linux/err.h> | ||
36 | #include <linux/mutex.h> | ||
37 | #include <linux/sysfs.h> | ||
38 | |||
39 | /* | ||
40 | * Addresses to scan | ||
41 | */ | ||
42 | |||
43 | static const unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END }; | ||
44 | |||
45 | /* | ||
46 | * Insmod parameters | ||
47 | */ | ||
48 | |||
49 | I2C_CLIENT_INSMOD_1(fscher); | ||
50 | |||
51 | /* | ||
52 | * The FSCHER registers | ||
53 | */ | ||
54 | |||
55 | /* chip identification */ | ||
56 | #define FSCHER_REG_IDENT_0 0x00 | ||
57 | #define FSCHER_REG_IDENT_1 0x01 | ||
58 | #define FSCHER_REG_IDENT_2 0x02 | ||
59 | #define FSCHER_REG_REVISION 0x03 | ||
60 | |||
61 | /* global control and status */ | ||
62 | #define FSCHER_REG_EVENT_STATE 0x04 | ||
63 | #define FSCHER_REG_CONTROL 0x05 | ||
64 | |||
65 | /* watchdog */ | ||
66 | #define FSCHER_REG_WDOG_PRESET 0x28 | ||
67 | #define FSCHER_REG_WDOG_STATE 0x23 | ||
68 | #define FSCHER_REG_WDOG_CONTROL 0x21 | ||
69 | |||
70 | /* fan 0 */ | ||
71 | #define FSCHER_REG_FAN0_MIN 0x55 | ||
72 | #define FSCHER_REG_FAN0_ACT 0x0e | ||
73 | #define FSCHER_REG_FAN0_STATE 0x0d | ||
74 | #define FSCHER_REG_FAN0_RIPPLE 0x0f | ||
75 | |||
76 | /* fan 1 */ | ||
77 | #define FSCHER_REG_FAN1_MIN 0x65 | ||
78 | #define FSCHER_REG_FAN1_ACT 0x6b | ||
79 | #define FSCHER_REG_FAN1_STATE 0x62 | ||
80 | #define FSCHER_REG_FAN1_RIPPLE 0x6f | ||
81 | |||
82 | /* fan 2 */ | ||
83 | #define FSCHER_REG_FAN2_MIN 0xb5 | ||
84 | #define FSCHER_REG_FAN2_ACT 0xbb | ||
85 | #define FSCHER_REG_FAN2_STATE 0xb2 | ||
86 | #define FSCHER_REG_FAN2_RIPPLE 0xbf | ||
87 | |||
88 | /* voltage supervision */ | ||
89 | #define FSCHER_REG_VOLT_12 0x45 | ||
90 | #define FSCHER_REG_VOLT_5 0x42 | ||
91 | #define FSCHER_REG_VOLT_BATT 0x48 | ||
92 | |||
93 | /* temperature 0 */ | ||
94 | #define FSCHER_REG_TEMP0_ACT 0x64 | ||
95 | #define FSCHER_REG_TEMP0_STATE 0x71 | ||
96 | |||
97 | /* temperature 1 */ | ||
98 | #define FSCHER_REG_TEMP1_ACT 0x32 | ||
99 | #define FSCHER_REG_TEMP1_STATE 0x81 | ||
100 | |||
101 | /* temperature 2 */ | ||
102 | #define FSCHER_REG_TEMP2_ACT 0x35 | ||
103 | #define FSCHER_REG_TEMP2_STATE 0x91 | ||
104 | |||
105 | /* | ||
106 | * Functions declaration | ||
107 | */ | ||
108 | |||
109 | static int fscher_probe(struct i2c_client *client, | ||
110 | const struct i2c_device_id *id); | ||
111 | static int fscher_detect(struct i2c_client *client, int kind, | ||
112 | struct i2c_board_info *info); | ||
113 | static int fscher_remove(struct i2c_client *client); | ||
114 | static struct fscher_data *fscher_update_device(struct device *dev); | ||
115 | static void fscher_init_client(struct i2c_client *client); | ||
116 | |||
117 | static int fscher_read_value(struct i2c_client *client, u8 reg); | ||
118 | static int fscher_write_value(struct i2c_client *client, u8 reg, u8 value); | ||
119 | |||
120 | /* | ||
121 | * Driver data (common to all clients) | ||
122 | */ | ||
123 | |||
124 | static const struct i2c_device_id fscher_id[] = { | ||
125 | { "fscher", fscher }, | ||
126 | { } | ||
127 | }; | ||
128 | |||
129 | static struct i2c_driver fscher_driver = { | ||
130 | .class = I2C_CLASS_HWMON, | ||
131 | .driver = { | ||
132 | .name = "fscher", | ||
133 | }, | ||
134 | .probe = fscher_probe, | ||
135 | .remove = fscher_remove, | ||
136 | .id_table = fscher_id, | ||
137 | .detect = fscher_detect, | ||
138 | .address_data = &addr_data, | ||
139 | }; | ||
140 | |||
141 | /* | ||
142 | * Client data (each client gets its own) | ||
143 | */ | ||
144 | |||
145 | struct fscher_data { | ||
146 | struct device *hwmon_dev; | ||
147 | struct mutex update_lock; | ||
148 | char valid; /* zero until following fields are valid */ | ||
149 | unsigned long last_updated; /* in jiffies */ | ||
150 | |||
151 | /* register values */ | ||
152 | u8 revision; /* revision of chip */ | ||
153 | u8 global_event; /* global event status */ | ||
154 | u8 global_control; /* global control register */ | ||
155 | u8 watchdog[3]; /* watchdog */ | ||
156 | u8 volt[3]; /* 12, 5, battery voltage */ | ||
157 | u8 temp_act[3]; /* temperature */ | ||
158 | u8 temp_status[3]; /* status of sensor */ | ||
159 | u8 fan_act[3]; /* fans revolutions per second */ | ||
160 | u8 fan_status[3]; /* fan status */ | ||
161 | u8 fan_min[3]; /* fan min value for rps */ | ||
162 | u8 fan_ripple[3]; /* divider for rps */ | ||
163 | }; | ||
164 | |||
165 | /* | ||
166 | * Sysfs stuff | ||
167 | */ | ||
168 | |||
169 | #define sysfs_r(kind, sub, offset, reg) \ | ||
170 | static ssize_t show_##kind##sub (struct fscher_data *, char *, int); \ | ||
171 | static ssize_t show_##kind##offset##sub (struct device *, struct device_attribute *attr, char *); \ | ||
172 | static ssize_t show_##kind##offset##sub (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
173 | { \ | ||
174 | struct fscher_data *data = fscher_update_device(dev); \ | ||
175 | return show_##kind##sub(data, buf, (offset)); \ | ||
176 | } | ||
177 | |||
178 | #define sysfs_w(kind, sub, offset, reg) \ | ||
179 | static ssize_t set_##kind##sub (struct i2c_client *, struct fscher_data *, const char *, size_t, int, int); \ | ||
180 | static ssize_t set_##kind##offset##sub (struct device *, struct device_attribute *attr, const char *, size_t); \ | ||
181 | static ssize_t set_##kind##offset##sub (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ | ||
182 | { \ | ||
183 | struct i2c_client *client = to_i2c_client(dev); \ | ||
184 | struct fscher_data *data = i2c_get_clientdata(client); \ | ||
185 | return set_##kind##sub(client, data, buf, count, (offset), reg); \ | ||
186 | } | ||
187 | |||
188 | #define sysfs_rw_n(kind, sub, offset, reg) \ | ||
189 | sysfs_r(kind, sub, offset, reg) \ | ||
190 | sysfs_w(kind, sub, offset, reg) \ | ||
191 | static DEVICE_ATTR(kind##offset##sub, S_IRUGO | S_IWUSR, show_##kind##offset##sub, set_##kind##offset##sub); | ||
192 | |||
193 | #define sysfs_rw(kind, sub, reg) \ | ||
194 | sysfs_r(kind, sub, 0, reg) \ | ||
195 | sysfs_w(kind, sub, 0, reg) \ | ||
196 | static DEVICE_ATTR(kind##sub, S_IRUGO | S_IWUSR, show_##kind##0##sub, set_##kind##0##sub); | ||
197 | |||
198 | #define sysfs_ro_n(kind, sub, offset, reg) \ | ||
199 | sysfs_r(kind, sub, offset, reg) \ | ||
200 | static DEVICE_ATTR(kind##offset##sub, S_IRUGO, show_##kind##offset##sub, NULL); | ||
201 | |||
202 | #define sysfs_ro(kind, sub, reg) \ | ||
203 | sysfs_r(kind, sub, 0, reg) \ | ||
204 | static DEVICE_ATTR(kind, S_IRUGO, show_##kind##0##sub, NULL); | ||
205 | |||
206 | #define sysfs_fan(offset, reg_status, reg_min, reg_ripple, reg_act) \ | ||
207 | sysfs_rw_n(pwm, , offset, reg_min) \ | ||
208 | sysfs_rw_n(fan, _status, offset, reg_status) \ | ||
209 | sysfs_rw_n(fan, _div , offset, reg_ripple) \ | ||
210 | sysfs_ro_n(fan, _input , offset, reg_act) | ||
211 | |||
212 | #define sysfs_temp(offset, reg_status, reg_act) \ | ||
213 | sysfs_rw_n(temp, _status, offset, reg_status) \ | ||
214 | sysfs_ro_n(temp, _input , offset, reg_act) | ||
215 | |||
216 | #define sysfs_in(offset, reg_act) \ | ||
217 | sysfs_ro_n(in, _input, offset, reg_act) | ||
218 | |||
219 | #define sysfs_revision(reg_revision) \ | ||
220 | sysfs_ro(revision, , reg_revision) | ||
221 | |||
222 | #define sysfs_alarms(reg_events) \ | ||
223 | sysfs_ro(alarms, , reg_events) | ||
224 | |||
225 | #define sysfs_control(reg_control) \ | ||
226 | sysfs_rw(control, , reg_control) | ||
227 | |||
228 | #define sysfs_watchdog(reg_control, reg_status, reg_preset) \ | ||
229 | sysfs_rw(watchdog, _control, reg_control) \ | ||
230 | sysfs_rw(watchdog, _status , reg_status) \ | ||
231 | sysfs_rw(watchdog, _preset , reg_preset) | ||
232 | |||
233 | sysfs_fan(1, FSCHER_REG_FAN0_STATE, FSCHER_REG_FAN0_MIN, | ||
234 | FSCHER_REG_FAN0_RIPPLE, FSCHER_REG_FAN0_ACT) | ||
235 | sysfs_fan(2, FSCHER_REG_FAN1_STATE, FSCHER_REG_FAN1_MIN, | ||
236 | FSCHER_REG_FAN1_RIPPLE, FSCHER_REG_FAN1_ACT) | ||
237 | sysfs_fan(3, FSCHER_REG_FAN2_STATE, FSCHER_REG_FAN2_MIN, | ||
238 | FSCHER_REG_FAN2_RIPPLE, FSCHER_REG_FAN2_ACT) | ||
239 | |||
240 | sysfs_temp(1, FSCHER_REG_TEMP0_STATE, FSCHER_REG_TEMP0_ACT) | ||
241 | sysfs_temp(2, FSCHER_REG_TEMP1_STATE, FSCHER_REG_TEMP1_ACT) | ||
242 | sysfs_temp(3, FSCHER_REG_TEMP2_STATE, FSCHER_REG_TEMP2_ACT) | ||
243 | |||
244 | sysfs_in(0, FSCHER_REG_VOLT_12) | ||
245 | sysfs_in(1, FSCHER_REG_VOLT_5) | ||
246 | sysfs_in(2, FSCHER_REG_VOLT_BATT) | ||
247 | |||
248 | sysfs_revision(FSCHER_REG_REVISION) | ||
249 | sysfs_alarms(FSCHER_REG_EVENTS) | ||
250 | sysfs_control(FSCHER_REG_CONTROL) | ||
251 | sysfs_watchdog(FSCHER_REG_WDOG_CONTROL, FSCHER_REG_WDOG_STATE, FSCHER_REG_WDOG_PRESET) | ||
252 | |||
253 | static struct attribute *fscher_attributes[] = { | ||
254 | &dev_attr_revision.attr, | ||
255 | &dev_attr_alarms.attr, | ||
256 | &dev_attr_control.attr, | ||
257 | |||
258 | &dev_attr_watchdog_status.attr, | ||
259 | &dev_attr_watchdog_control.attr, | ||
260 | &dev_attr_watchdog_preset.attr, | ||
261 | |||
262 | &dev_attr_in0_input.attr, | ||
263 | &dev_attr_in1_input.attr, | ||
264 | &dev_attr_in2_input.attr, | ||
265 | |||
266 | &dev_attr_fan1_status.attr, | ||
267 | &dev_attr_fan1_div.attr, | ||
268 | &dev_attr_fan1_input.attr, | ||
269 | &dev_attr_pwm1.attr, | ||
270 | &dev_attr_fan2_status.attr, | ||
271 | &dev_attr_fan2_div.attr, | ||
272 | &dev_attr_fan2_input.attr, | ||
273 | &dev_attr_pwm2.attr, | ||
274 | &dev_attr_fan3_status.attr, | ||
275 | &dev_attr_fan3_div.attr, | ||
276 | &dev_attr_fan3_input.attr, | ||
277 | &dev_attr_pwm3.attr, | ||
278 | |||
279 | &dev_attr_temp1_status.attr, | ||
280 | &dev_attr_temp1_input.attr, | ||
281 | &dev_attr_temp2_status.attr, | ||
282 | &dev_attr_temp2_input.attr, | ||
283 | &dev_attr_temp3_status.attr, | ||
284 | &dev_attr_temp3_input.attr, | ||
285 | NULL | ||
286 | }; | ||
287 | |||
288 | static const struct attribute_group fscher_group = { | ||
289 | .attrs = fscher_attributes, | ||
290 | }; | ||
291 | |||
292 | /* | ||
293 | * Real code | ||
294 | */ | ||
295 | |||
296 | /* Return 0 if detection is successful, -ENODEV otherwise */ | ||
297 | static int fscher_detect(struct i2c_client *new_client, int kind, | ||
298 | struct i2c_board_info *info) | ||
299 | { | ||
300 | struct i2c_adapter *adapter = new_client->adapter; | ||
301 | |||
302 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
303 | return -ENODEV; | ||
304 | |||
305 | /* Do the remaining detection unless force or force_fscher parameter */ | ||
306 | if (kind < 0) { | ||
307 | if ((i2c_smbus_read_byte_data(new_client, | ||
308 | FSCHER_REG_IDENT_0) != 0x48) /* 'H' */ | ||
309 | || (i2c_smbus_read_byte_data(new_client, | ||
310 | FSCHER_REG_IDENT_1) != 0x45) /* 'E' */ | ||
311 | || (i2c_smbus_read_byte_data(new_client, | ||
312 | FSCHER_REG_IDENT_2) != 0x52)) /* 'R' */ | ||
313 | return -ENODEV; | ||
314 | } | ||
315 | |||
316 | strlcpy(info->type, "fscher", I2C_NAME_SIZE); | ||
317 | |||
318 | return 0; | ||
319 | } | ||
320 | |||
321 | static int fscher_probe(struct i2c_client *new_client, | ||
322 | const struct i2c_device_id *id) | ||
323 | { | ||
324 | struct fscher_data *data; | ||
325 | int err; | ||
326 | |||
327 | data = kzalloc(sizeof(struct fscher_data), GFP_KERNEL); | ||
328 | if (!data) { | ||
329 | err = -ENOMEM; | ||
330 | goto exit; | ||
331 | } | ||
332 | |||
333 | i2c_set_clientdata(new_client, data); | ||
334 | data->valid = 0; | ||
335 | mutex_init(&data->update_lock); | ||
336 | |||
337 | fscher_init_client(new_client); | ||
338 | |||
339 | /* Register sysfs hooks */ | ||
340 | if ((err = sysfs_create_group(&new_client->dev.kobj, &fscher_group))) | ||
341 | goto exit_free; | ||
342 | |||
343 | data->hwmon_dev = hwmon_device_register(&new_client->dev); | ||
344 | if (IS_ERR(data->hwmon_dev)) { | ||
345 | err = PTR_ERR(data->hwmon_dev); | ||
346 | goto exit_remove_files; | ||
347 | } | ||
348 | |||
349 | return 0; | ||
350 | |||
351 | exit_remove_files: | ||
352 | sysfs_remove_group(&new_client->dev.kobj, &fscher_group); | ||
353 | exit_free: | ||
354 | kfree(data); | ||
355 | exit: | ||
356 | return err; | ||
357 | } | ||
358 | |||
359 | static int fscher_remove(struct i2c_client *client) | ||
360 | { | ||
361 | struct fscher_data *data = i2c_get_clientdata(client); | ||
362 | |||
363 | hwmon_device_unregister(data->hwmon_dev); | ||
364 | sysfs_remove_group(&client->dev.kobj, &fscher_group); | ||
365 | |||
366 | kfree(data); | ||
367 | return 0; | ||
368 | } | ||
369 | |||
370 | static int fscher_read_value(struct i2c_client *client, u8 reg) | ||
371 | { | ||
372 | dev_dbg(&client->dev, "read reg 0x%02x\n", reg); | ||
373 | |||
374 | return i2c_smbus_read_byte_data(client, reg); | ||
375 | } | ||
376 | |||
377 | static int fscher_write_value(struct i2c_client *client, u8 reg, u8 value) | ||
378 | { | ||
379 | dev_dbg(&client->dev, "write reg 0x%02x, val 0x%02x\n", | ||
380 | reg, value); | ||
381 | |||
382 | return i2c_smbus_write_byte_data(client, reg, value); | ||
383 | } | ||
384 | |||
385 | /* Called when we have found a new FSC Hermes. */ | ||
386 | static void fscher_init_client(struct i2c_client *client) | ||
387 | { | ||
388 | struct fscher_data *data = i2c_get_clientdata(client); | ||
389 | |||
390 | /* Read revision from chip */ | ||
391 | data->revision = fscher_read_value(client, FSCHER_REG_REVISION); | ||
392 | } | ||
393 | |||
394 | static struct fscher_data *fscher_update_device(struct device *dev) | ||
395 | { | ||
396 | struct i2c_client *client = to_i2c_client(dev); | ||
397 | struct fscher_data *data = i2c_get_clientdata(client); | ||
398 | |||
399 | mutex_lock(&data->update_lock); | ||
400 | |||
401 | if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) { | ||
402 | |||
403 | dev_dbg(&client->dev, "Starting fscher update\n"); | ||
404 | |||
405 | data->temp_act[0] = fscher_read_value(client, FSCHER_REG_TEMP0_ACT); | ||
406 | data->temp_act[1] = fscher_read_value(client, FSCHER_REG_TEMP1_ACT); | ||
407 | data->temp_act[2] = fscher_read_value(client, FSCHER_REG_TEMP2_ACT); | ||
408 | data->temp_status[0] = fscher_read_value(client, FSCHER_REG_TEMP0_STATE); | ||
409 | data->temp_status[1] = fscher_read_value(client, FSCHER_REG_TEMP1_STATE); | ||
410 | data->temp_status[2] = fscher_read_value(client, FSCHER_REG_TEMP2_STATE); | ||
411 | |||
412 | data->volt[0] = fscher_read_value(client, FSCHER_REG_VOLT_12); | ||
413 | data->volt[1] = fscher_read_value(client, FSCHER_REG_VOLT_5); | ||
414 | data->volt[2] = fscher_read_value(client, FSCHER_REG_VOLT_BATT); | ||
415 | |||
416 | data->fan_act[0] = fscher_read_value(client, FSCHER_REG_FAN0_ACT); | ||
417 | data->fan_act[1] = fscher_read_value(client, FSCHER_REG_FAN1_ACT); | ||
418 | data->fan_act[2] = fscher_read_value(client, FSCHER_REG_FAN2_ACT); | ||
419 | data->fan_status[0] = fscher_read_value(client, FSCHER_REG_FAN0_STATE); | ||
420 | data->fan_status[1] = fscher_read_value(client, FSCHER_REG_FAN1_STATE); | ||
421 | data->fan_status[2] = fscher_read_value(client, FSCHER_REG_FAN2_STATE); | ||
422 | data->fan_min[0] = fscher_read_value(client, FSCHER_REG_FAN0_MIN); | ||
423 | data->fan_min[1] = fscher_read_value(client, FSCHER_REG_FAN1_MIN); | ||
424 | data->fan_min[2] = fscher_read_value(client, FSCHER_REG_FAN2_MIN); | ||
425 | data->fan_ripple[0] = fscher_read_value(client, FSCHER_REG_FAN0_RIPPLE); | ||
426 | data->fan_ripple[1] = fscher_read_value(client, FSCHER_REG_FAN1_RIPPLE); | ||
427 | data->fan_ripple[2] = fscher_read_value(client, FSCHER_REG_FAN2_RIPPLE); | ||
428 | |||
429 | data->watchdog[0] = fscher_read_value(client, FSCHER_REG_WDOG_PRESET); | ||
430 | data->watchdog[1] = fscher_read_value(client, FSCHER_REG_WDOG_STATE); | ||
431 | data->watchdog[2] = fscher_read_value(client, FSCHER_REG_WDOG_CONTROL); | ||
432 | |||
433 | data->global_event = fscher_read_value(client, FSCHER_REG_EVENT_STATE); | ||
434 | data->global_control = fscher_read_value(client, | ||
435 | FSCHER_REG_CONTROL); | ||
436 | |||
437 | data->last_updated = jiffies; | ||
438 | data->valid = 1; | ||
439 | } | ||
440 | |||
441 | mutex_unlock(&data->update_lock); | ||
442 | |||
443 | return data; | ||
444 | } | ||
445 | |||
446 | |||
447 | |||
448 | #define FAN_INDEX_FROM_NUM(nr) ((nr) - 1) | ||
449 | |||
450 | static ssize_t set_fan_status(struct i2c_client *client, struct fscher_data *data, | ||
451 | const char *buf, size_t count, int nr, int reg) | ||
452 | { | ||
453 | /* bits 0..1, 3..7 reserved => mask with 0x04 */ | ||
454 | unsigned long v = simple_strtoul(buf, NULL, 10) & 0x04; | ||
455 | |||
456 | mutex_lock(&data->update_lock); | ||
457 | data->fan_status[FAN_INDEX_FROM_NUM(nr)] &= ~v; | ||
458 | fscher_write_value(client, reg, v); | ||
459 | mutex_unlock(&data->update_lock); | ||
460 | return count; | ||
461 | } | ||
462 | |||
463 | static ssize_t show_fan_status(struct fscher_data *data, char *buf, int nr) | ||
464 | { | ||
465 | /* bits 0..1, 3..7 reserved => mask with 0x04 */ | ||
466 | return sprintf(buf, "%u\n", data->fan_status[FAN_INDEX_FROM_NUM(nr)] & 0x04); | ||
467 | } | ||
468 | |||
469 | static ssize_t set_pwm(struct i2c_client *client, struct fscher_data *data, | ||
470 | const char *buf, size_t count, int nr, int reg) | ||
471 | { | ||
472 | unsigned long v = simple_strtoul(buf, NULL, 10); | ||
473 | |||
474 | mutex_lock(&data->update_lock); | ||
475 | data->fan_min[FAN_INDEX_FROM_NUM(nr)] = v > 0xff ? 0xff : v; | ||
476 | fscher_write_value(client, reg, data->fan_min[FAN_INDEX_FROM_NUM(nr)]); | ||
477 | mutex_unlock(&data->update_lock); | ||
478 | return count; | ||
479 | } | ||
480 | |||
481 | static ssize_t show_pwm(struct fscher_data *data, char *buf, int nr) | ||
482 | { | ||
483 | return sprintf(buf, "%u\n", data->fan_min[FAN_INDEX_FROM_NUM(nr)]); | ||
484 | } | ||
485 | |||
486 | static ssize_t set_fan_div(struct i2c_client *client, struct fscher_data *data, | ||
487 | const char *buf, size_t count, int nr, int reg) | ||
488 | { | ||
489 | /* supported values: 2, 4, 8 */ | ||
490 | unsigned long v = simple_strtoul(buf, NULL, 10); | ||
491 | |||
492 | switch (v) { | ||
493 | case 2: v = 1; break; | ||
494 | case 4: v = 2; break; | ||
495 | case 8: v = 3; break; | ||
496 | default: | ||
497 | dev_err(&client->dev, "fan_div value %ld not " | ||
498 | "supported. Choose one of 2, 4 or 8!\n", v); | ||
499 | return -EINVAL; | ||
500 | } | ||
501 | |||
502 | mutex_lock(&data->update_lock); | ||
503 | |||
504 | /* bits 2..7 reserved => mask with 0x03 */ | ||
505 | data->fan_ripple[FAN_INDEX_FROM_NUM(nr)] &= ~0x03; | ||
506 | data->fan_ripple[FAN_INDEX_FROM_NUM(nr)] |= v; | ||
507 | |||
508 | fscher_write_value(client, reg, data->fan_ripple[FAN_INDEX_FROM_NUM(nr)]); | ||
509 | mutex_unlock(&data->update_lock); | ||
510 | return count; | ||
511 | } | ||
512 | |||
513 | static ssize_t show_fan_div(struct fscher_data *data, char *buf, int nr) | ||
514 | { | ||
515 | /* bits 2..7 reserved => mask with 0x03 */ | ||
516 | return sprintf(buf, "%u\n", 1 << (data->fan_ripple[FAN_INDEX_FROM_NUM(nr)] & 0x03)); | ||
517 | } | ||
518 | |||
519 | #define RPM_FROM_REG(val) (val*60) | ||
520 | |||
521 | static ssize_t show_fan_input (struct fscher_data *data, char *buf, int nr) | ||
522 | { | ||
523 | return sprintf(buf, "%u\n", RPM_FROM_REG(data->fan_act[FAN_INDEX_FROM_NUM(nr)])); | ||
524 | } | ||
525 | |||
526 | |||
527 | |||
528 | #define TEMP_INDEX_FROM_NUM(nr) ((nr) - 1) | ||
529 | |||
530 | static ssize_t set_temp_status(struct i2c_client *client, struct fscher_data *data, | ||
531 | const char *buf, size_t count, int nr, int reg) | ||
532 | { | ||
533 | /* bits 2..7 reserved, 0 read only => mask with 0x02 */ | ||
534 | unsigned long v = simple_strtoul(buf, NULL, 10) & 0x02; | ||
535 | |||
536 | mutex_lock(&data->update_lock); | ||
537 | data->temp_status[TEMP_INDEX_FROM_NUM(nr)] &= ~v; | ||
538 | fscher_write_value(client, reg, v); | ||
539 | mutex_unlock(&data->update_lock); | ||
540 | return count; | ||
541 | } | ||
542 | |||
543 | static ssize_t show_temp_status(struct fscher_data *data, char *buf, int nr) | ||
544 | { | ||
545 | /* bits 2..7 reserved => mask with 0x03 */ | ||
546 | return sprintf(buf, "%u\n", data->temp_status[TEMP_INDEX_FROM_NUM(nr)] & 0x03); | ||
547 | } | ||
548 | |||
549 | #define TEMP_FROM_REG(val) (((val) - 128) * 1000) | ||
550 | |||
551 | static ssize_t show_temp_input(struct fscher_data *data, char *buf, int nr) | ||
552 | { | ||
553 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_act[TEMP_INDEX_FROM_NUM(nr)])); | ||
554 | } | ||
555 | |||
556 | /* | ||
557 | * The final conversion is specified in sensors.conf, as it depends on | ||
558 | * mainboard specific values. We export the registers contents as | ||
559 | * pseudo-hundredths-of-Volts (range 0V - 2.55V). Not that it makes much | ||
560 | * sense per se, but it minimizes the conversions count and keeps the | ||
561 | * values within a usual range. | ||
562 | */ | ||
563 | #define VOLT_FROM_REG(val) ((val) * 10) | ||
564 | |||
565 | static ssize_t show_in_input(struct fscher_data *data, char *buf, int nr) | ||
566 | { | ||
567 | return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[nr])); | ||
568 | } | ||
569 | |||
570 | |||
571 | |||
572 | static ssize_t show_revision(struct fscher_data *data, char *buf, int nr) | ||
573 | { | ||
574 | return sprintf(buf, "%u\n", data->revision); | ||
575 | } | ||
576 | |||
577 | |||
578 | |||
579 | static ssize_t show_alarms(struct fscher_data *data, char *buf, int nr) | ||
580 | { | ||
581 | /* bits 2, 5..6 reserved => mask with 0x9b */ | ||
582 | return sprintf(buf, "%u\n", data->global_event & 0x9b); | ||
583 | } | ||
584 | |||
585 | |||
586 | |||
587 | static ssize_t set_control(struct i2c_client *client, struct fscher_data *data, | ||
588 | const char *buf, size_t count, int nr, int reg) | ||
589 | { | ||
590 | /* bits 1..7 reserved => mask with 0x01 */ | ||
591 | unsigned long v = simple_strtoul(buf, NULL, 10) & 0x01; | ||
592 | |||
593 | mutex_lock(&data->update_lock); | ||
594 | data->global_control = v; | ||
595 | fscher_write_value(client, reg, v); | ||
596 | mutex_unlock(&data->update_lock); | ||
597 | return count; | ||
598 | } | ||
599 | |||
600 | static ssize_t show_control(struct fscher_data *data, char *buf, int nr) | ||
601 | { | ||
602 | /* bits 1..7 reserved => mask with 0x01 */ | ||
603 | return sprintf(buf, "%u\n", data->global_control & 0x01); | ||
604 | } | ||
605 | |||
606 | |||
607 | |||
608 | static ssize_t set_watchdog_control(struct i2c_client *client, struct | ||
609 | fscher_data *data, const char *buf, size_t count, | ||
610 | int nr, int reg) | ||
611 | { | ||
612 | /* bits 0..3 reserved => mask with 0xf0 */ | ||
613 | unsigned long v = simple_strtoul(buf, NULL, 10) & 0xf0; | ||
614 | |||
615 | mutex_lock(&data->update_lock); | ||
616 | data->watchdog[2] &= ~0xf0; | ||
617 | data->watchdog[2] |= v; | ||
618 | fscher_write_value(client, reg, data->watchdog[2]); | ||
619 | mutex_unlock(&data->update_lock); | ||
620 | return count; | ||
621 | } | ||
622 | |||
623 | static ssize_t show_watchdog_control(struct fscher_data *data, char *buf, int nr) | ||
624 | { | ||
625 | /* bits 0..3 reserved, bit 5 write only => mask with 0xd0 */ | ||
626 | return sprintf(buf, "%u\n", data->watchdog[2] & 0xd0); | ||
627 | } | ||
628 | |||
629 | static ssize_t set_watchdog_status(struct i2c_client *client, struct fscher_data *data, | ||
630 | const char *buf, size_t count, int nr, int reg) | ||
631 | { | ||
632 | /* bits 0, 2..7 reserved => mask with 0x02 */ | ||
633 | unsigned long v = simple_strtoul(buf, NULL, 10) & 0x02; | ||
634 | |||
635 | mutex_lock(&data->update_lock); | ||
636 | data->watchdog[1] &= ~v; | ||
637 | fscher_write_value(client, reg, v); | ||
638 | mutex_unlock(&data->update_lock); | ||
639 | return count; | ||
640 | } | ||
641 | |||
642 | static ssize_t show_watchdog_status(struct fscher_data *data, char *buf, int nr) | ||
643 | { | ||
644 | /* bits 0, 2..7 reserved => mask with 0x02 */ | ||
645 | return sprintf(buf, "%u\n", data->watchdog[1] & 0x02); | ||
646 | } | ||
647 | |||
648 | static ssize_t set_watchdog_preset(struct i2c_client *client, struct fscher_data *data, | ||
649 | const char *buf, size_t count, int nr, int reg) | ||
650 | { | ||
651 | unsigned long v = simple_strtoul(buf, NULL, 10) & 0xff; | ||
652 | |||
653 | mutex_lock(&data->update_lock); | ||
654 | data->watchdog[0] = v; | ||
655 | fscher_write_value(client, reg, data->watchdog[0]); | ||
656 | mutex_unlock(&data->update_lock); | ||
657 | return count; | ||
658 | } | ||
659 | |||
660 | static ssize_t show_watchdog_preset(struct fscher_data *data, char *buf, int nr) | ||
661 | { | ||
662 | return sprintf(buf, "%u\n", data->watchdog[0]); | ||
663 | } | ||
664 | |||
665 | static int __init sensors_fscher_init(void) | ||
666 | { | ||
667 | return i2c_add_driver(&fscher_driver); | ||
668 | } | ||
669 | |||
670 | static void __exit sensors_fscher_exit(void) | ||
671 | { | ||
672 | i2c_del_driver(&fscher_driver); | ||
673 | } | ||
674 | |||
675 | MODULE_AUTHOR("Reinhard Nissl <rnissl@gmx.de>"); | ||
676 | MODULE_DESCRIPTION("FSC Hermes driver"); | ||
677 | MODULE_LICENSE("GPL"); | ||
678 | |||
679 | module_init(sensors_fscher_init); | ||
680 | module_exit(sensors_fscher_exit); | ||
diff --git a/drivers/hwmon/fscpos.c b/drivers/hwmon/fscpos.c deleted file mode 100644 index 8a7bcf500b4e..000000000000 --- a/drivers/hwmon/fscpos.c +++ /dev/null | |||
@@ -1,654 +0,0 @@ | |||
1 | /* | ||
2 | fscpos.c - Kernel module for hardware monitoring with FSC Poseidon chips | ||
3 | Copyright (C) 2004, 2005 Stefan Ott <stefan@desire.ch> | ||
4 | |||
5 | This program is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or | ||
8 | (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program; if not, write to the Free Software | ||
17 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | */ | ||
19 | |||
20 | /* | ||
21 | fujitsu siemens poseidon chip, | ||
22 | module based on the old fscpos module by Hermann Jung <hej@odn.de> and | ||
23 | the fscher module by Reinhard Nissl <rnissl@gmx.de> | ||
24 | |||
25 | original module based on lm80.c | ||
26 | Copyright (C) 1998, 1999 Frodo Looijaard <frodol@dds.nl> | ||
27 | and Philip Edelbrock <phil@netroedge.com> | ||
28 | |||
29 | Thanks to Jean Delvare for reviewing my code and suggesting a lot of | ||
30 | improvements. | ||
31 | */ | ||
32 | |||
33 | #include <linux/module.h> | ||
34 | #include <linux/slab.h> | ||
35 | #include <linux/jiffies.h> | ||
36 | #include <linux/i2c.h> | ||
37 | #include <linux/init.h> | ||
38 | #include <linux/hwmon.h> | ||
39 | #include <linux/err.h> | ||
40 | #include <linux/mutex.h> | ||
41 | #include <linux/sysfs.h> | ||
42 | |||
43 | /* | ||
44 | * Addresses to scan | ||
45 | */ | ||
46 | static const unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END }; | ||
47 | |||
48 | /* | ||
49 | * Insmod parameters | ||
50 | */ | ||
51 | I2C_CLIENT_INSMOD_1(fscpos); | ||
52 | |||
53 | /* | ||
54 | * The FSCPOS registers | ||
55 | */ | ||
56 | |||
57 | /* chip identification */ | ||
58 | #define FSCPOS_REG_IDENT_0 0x00 | ||
59 | #define FSCPOS_REG_IDENT_1 0x01 | ||
60 | #define FSCPOS_REG_IDENT_2 0x02 | ||
61 | #define FSCPOS_REG_REVISION 0x03 | ||
62 | |||
63 | /* global control and status */ | ||
64 | #define FSCPOS_REG_EVENT_STATE 0x04 | ||
65 | #define FSCPOS_REG_CONTROL 0x05 | ||
66 | |||
67 | /* watchdog */ | ||
68 | #define FSCPOS_REG_WDOG_PRESET 0x28 | ||
69 | #define FSCPOS_REG_WDOG_STATE 0x23 | ||
70 | #define FSCPOS_REG_WDOG_CONTROL 0x21 | ||
71 | |||
72 | /* voltages */ | ||
73 | #define FSCPOS_REG_VOLT_12 0x45 | ||
74 | #define FSCPOS_REG_VOLT_5 0x42 | ||
75 | #define FSCPOS_REG_VOLT_BATT 0x48 | ||
76 | |||
77 | /* fans - the chip does not support minimum speed for fan2 */ | ||
78 | static u8 FSCPOS_REG_PWM[] = { 0x55, 0x65 }; | ||
79 | static u8 FSCPOS_REG_FAN_ACT[] = { 0x0e, 0x6b, 0xab }; | ||
80 | static u8 FSCPOS_REG_FAN_STATE[] = { 0x0d, 0x62, 0xa2 }; | ||
81 | static u8 FSCPOS_REG_FAN_RIPPLE[] = { 0x0f, 0x6f, 0xaf }; | ||
82 | |||
83 | /* temperatures */ | ||
84 | static u8 FSCPOS_REG_TEMP_ACT[] = { 0x64, 0x32, 0x35 }; | ||
85 | static u8 FSCPOS_REG_TEMP_STATE[] = { 0x71, 0x81, 0x91 }; | ||
86 | |||
87 | /* | ||
88 | * Functions declaration | ||
89 | */ | ||
90 | static int fscpos_probe(struct i2c_client *client, | ||
91 | const struct i2c_device_id *id); | ||
92 | static int fscpos_detect(struct i2c_client *client, int kind, | ||
93 | struct i2c_board_info *info); | ||
94 | static int fscpos_remove(struct i2c_client *client); | ||
95 | |||
96 | static int fscpos_read_value(struct i2c_client *client, u8 reg); | ||
97 | static int fscpos_write_value(struct i2c_client *client, u8 reg, u8 value); | ||
98 | static struct fscpos_data *fscpos_update_device(struct device *dev); | ||
99 | static void fscpos_init_client(struct i2c_client *client); | ||
100 | |||
101 | static void reset_fan_alarm(struct i2c_client *client, int nr); | ||
102 | |||
103 | /* | ||
104 | * Driver data (common to all clients) | ||
105 | */ | ||
106 | static const struct i2c_device_id fscpos_id[] = { | ||
107 | { "fscpos", fscpos }, | ||
108 | { } | ||
109 | }; | ||
110 | |||
111 | static struct i2c_driver fscpos_driver = { | ||
112 | .class = I2C_CLASS_HWMON, | ||
113 | .driver = { | ||
114 | .name = "fscpos", | ||
115 | }, | ||
116 | .probe = fscpos_probe, | ||
117 | .remove = fscpos_remove, | ||
118 | .id_table = fscpos_id, | ||
119 | .detect = fscpos_detect, | ||
120 | .address_data = &addr_data, | ||
121 | }; | ||
122 | |||
123 | /* | ||
124 | * Client data (each client gets its own) | ||
125 | */ | ||
126 | struct fscpos_data { | ||
127 | struct device *hwmon_dev; | ||
128 | struct mutex update_lock; | ||
129 | char valid; /* 0 until following fields are valid */ | ||
130 | unsigned long last_updated; /* In jiffies */ | ||
131 | |||
132 | /* register values */ | ||
133 | u8 revision; /* revision of chip */ | ||
134 | u8 global_event; /* global event status */ | ||
135 | u8 global_control; /* global control register */ | ||
136 | u8 wdog_control; /* watchdog control */ | ||
137 | u8 wdog_state; /* watchdog status */ | ||
138 | u8 wdog_preset; /* watchdog preset */ | ||
139 | u8 volt[3]; /* 12, 5, battery current */ | ||
140 | u8 temp_act[3]; /* temperature */ | ||
141 | u8 temp_status[3]; /* status of sensor */ | ||
142 | u8 fan_act[3]; /* fans revolutions per second */ | ||
143 | u8 fan_status[3]; /* fan status */ | ||
144 | u8 pwm[2]; /* fan min value for rps */ | ||
145 | u8 fan_ripple[3]; /* divider for rps */ | ||
146 | }; | ||
147 | |||
148 | /* Temperature */ | ||
149 | #define TEMP_FROM_REG(val) (((val) - 128) * 1000) | ||
150 | |||
151 | static ssize_t show_temp_input(struct fscpos_data *data, char *buf, int nr) | ||
152 | { | ||
153 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_act[nr - 1])); | ||
154 | } | ||
155 | |||
156 | static ssize_t show_temp_status(struct fscpos_data *data, char *buf, int nr) | ||
157 | { | ||
158 | /* bits 2..7 reserved => mask with 0x03 */ | ||
159 | return sprintf(buf, "%u\n", data->temp_status[nr - 1] & 0x03); | ||
160 | } | ||
161 | |||
162 | static ssize_t show_temp_reset(struct fscpos_data *data, char *buf, int nr) | ||
163 | { | ||
164 | return sprintf(buf, "1\n"); | ||
165 | } | ||
166 | |||
167 | static ssize_t set_temp_reset(struct i2c_client *client, struct fscpos_data | ||
168 | *data, const char *buf, size_t count, int nr, int reg) | ||
169 | { | ||
170 | unsigned long v = simple_strtoul(buf, NULL, 10); | ||
171 | if (v != 1) { | ||
172 | dev_err(&client->dev, "temp_reset value %ld not supported. " | ||
173 | "Use 1 to reset the alarm!\n", v); | ||
174 | return -EINVAL; | ||
175 | } | ||
176 | |||
177 | dev_info(&client->dev, "You used the temp_reset feature which has not " | ||
178 | "been proplerly tested. Please report your " | ||
179 | "experience to the module author.\n"); | ||
180 | |||
181 | /* Supported value: 2 (clears the status) */ | ||
182 | fscpos_write_value(client, FSCPOS_REG_TEMP_STATE[nr - 1], 2); | ||
183 | return count; | ||
184 | } | ||
185 | |||
186 | /* Fans */ | ||
187 | #define RPM_FROM_REG(val) ((val) * 60) | ||
188 | |||
189 | static ssize_t show_fan_status(struct fscpos_data *data, char *buf, int nr) | ||
190 | { | ||
191 | /* bits 0..1, 3..7 reserved => mask with 0x04 */ | ||
192 | return sprintf(buf, "%u\n", data->fan_status[nr - 1] & 0x04); | ||
193 | } | ||
194 | |||
195 | static ssize_t show_fan_input(struct fscpos_data *data, char *buf, int nr) | ||
196 | { | ||
197 | return sprintf(buf, "%u\n", RPM_FROM_REG(data->fan_act[nr - 1])); | ||
198 | } | ||
199 | |||
200 | static ssize_t show_fan_ripple(struct fscpos_data *data, char *buf, int nr) | ||
201 | { | ||
202 | /* bits 2..7 reserved => mask with 0x03 */ | ||
203 | return sprintf(buf, "%u\n", data->fan_ripple[nr - 1] & 0x03); | ||
204 | } | ||
205 | |||
206 | static ssize_t set_fan_ripple(struct i2c_client *client, struct fscpos_data | ||
207 | *data, const char *buf, size_t count, int nr, int reg) | ||
208 | { | ||
209 | /* supported values: 2, 4, 8 */ | ||
210 | unsigned long v = simple_strtoul(buf, NULL, 10); | ||
211 | |||
212 | switch (v) { | ||
213 | case 2: v = 1; break; | ||
214 | case 4: v = 2; break; | ||
215 | case 8: v = 3; break; | ||
216 | default: | ||
217 | dev_err(&client->dev, "fan_ripple value %ld not supported. " | ||
218 | "Must be one of 2, 4 or 8!\n", v); | ||
219 | return -EINVAL; | ||
220 | } | ||
221 | |||
222 | mutex_lock(&data->update_lock); | ||
223 | /* bits 2..7 reserved => mask with 0x03 */ | ||
224 | data->fan_ripple[nr - 1] &= ~0x03; | ||
225 | data->fan_ripple[nr - 1] |= v; | ||
226 | |||
227 | fscpos_write_value(client, reg, data->fan_ripple[nr - 1]); | ||
228 | mutex_unlock(&data->update_lock); | ||
229 | return count; | ||
230 | } | ||
231 | |||
232 | static ssize_t show_pwm(struct fscpos_data *data, char *buf, int nr) | ||
233 | { | ||
234 | return sprintf(buf, "%u\n", data->pwm[nr - 1]); | ||
235 | } | ||
236 | |||
237 | static ssize_t set_pwm(struct i2c_client *client, struct fscpos_data *data, | ||
238 | const char *buf, size_t count, int nr, int reg) | ||
239 | { | ||
240 | unsigned long v = simple_strtoul(buf, NULL, 10); | ||
241 | |||
242 | /* Range: 0..255 */ | ||
243 | if (v < 0) v = 0; | ||
244 | if (v > 255) v = 255; | ||
245 | |||
246 | mutex_lock(&data->update_lock); | ||
247 | data->pwm[nr - 1] = v; | ||
248 | fscpos_write_value(client, reg, data->pwm[nr - 1]); | ||
249 | mutex_unlock(&data->update_lock); | ||
250 | return count; | ||
251 | } | ||
252 | |||
253 | static void reset_fan_alarm(struct i2c_client *client, int nr) | ||
254 | { | ||
255 | fscpos_write_value(client, FSCPOS_REG_FAN_STATE[nr], 4); | ||
256 | } | ||
257 | |||
258 | /* Volts */ | ||
259 | #define VOLT_FROM_REG(val, mult) ((val) * (mult) / 255) | ||
260 | |||
261 | static ssize_t show_volt_12(struct device *dev, struct device_attribute *attr, char *buf) | ||
262 | { | ||
263 | struct fscpos_data *data = fscpos_update_device(dev); | ||
264 | return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[0], 14200)); | ||
265 | } | ||
266 | |||
267 | static ssize_t show_volt_5(struct device *dev, struct device_attribute *attr, char *buf) | ||
268 | { | ||
269 | struct fscpos_data *data = fscpos_update_device(dev); | ||
270 | return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[1], 6600)); | ||
271 | } | ||
272 | |||
273 | static ssize_t show_volt_batt(struct device *dev, struct device_attribute *attr, char *buf) | ||
274 | { | ||
275 | struct fscpos_data *data = fscpos_update_device(dev); | ||
276 | return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[2], 3300)); | ||
277 | } | ||
278 | |||
279 | /* Watchdog */ | ||
280 | static ssize_t show_wdog_control(struct fscpos_data *data, char *buf) | ||
281 | { | ||
282 | /* bits 0..3 reserved, bit 6 write only => mask with 0xb0 */ | ||
283 | return sprintf(buf, "%u\n", data->wdog_control & 0xb0); | ||
284 | } | ||
285 | |||
286 | static ssize_t set_wdog_control(struct i2c_client *client, struct fscpos_data | ||
287 | *data, const char *buf, size_t count, int reg) | ||
288 | { | ||
289 | /* bits 0..3 reserved => mask with 0xf0 */ | ||
290 | unsigned long v = simple_strtoul(buf, NULL, 10) & 0xf0; | ||
291 | |||
292 | mutex_lock(&data->update_lock); | ||
293 | data->wdog_control &= ~0xf0; | ||
294 | data->wdog_control |= v; | ||
295 | fscpos_write_value(client, reg, data->wdog_control); | ||
296 | mutex_unlock(&data->update_lock); | ||
297 | return count; | ||
298 | } | ||
299 | |||
300 | static ssize_t show_wdog_state(struct fscpos_data *data, char *buf) | ||
301 | { | ||
302 | /* bits 0, 2..7 reserved => mask with 0x02 */ | ||
303 | return sprintf(buf, "%u\n", data->wdog_state & 0x02); | ||
304 | } | ||
305 | |||
306 | static ssize_t set_wdog_state(struct i2c_client *client, struct fscpos_data | ||
307 | *data, const char *buf, size_t count, int reg) | ||
308 | { | ||
309 | unsigned long v = simple_strtoul(buf, NULL, 10) & 0x02; | ||
310 | |||
311 | /* Valid values: 2 (clear) */ | ||
312 | if (v != 2) { | ||
313 | dev_err(&client->dev, "wdog_state value %ld not supported. " | ||
314 | "Must be 2 to clear the state!\n", v); | ||
315 | return -EINVAL; | ||
316 | } | ||
317 | |||
318 | mutex_lock(&data->update_lock); | ||
319 | data->wdog_state &= ~v; | ||
320 | fscpos_write_value(client, reg, v); | ||
321 | mutex_unlock(&data->update_lock); | ||
322 | return count; | ||
323 | } | ||
324 | |||
325 | static ssize_t show_wdog_preset(struct fscpos_data *data, char *buf) | ||
326 | { | ||
327 | return sprintf(buf, "%u\n", data->wdog_preset); | ||
328 | } | ||
329 | |||
330 | static ssize_t set_wdog_preset(struct i2c_client *client, struct fscpos_data | ||
331 | *data, const char *buf, size_t count, int reg) | ||
332 | { | ||
333 | unsigned long v = simple_strtoul(buf, NULL, 10) & 0xff; | ||
334 | |||
335 | mutex_lock(&data->update_lock); | ||
336 | data->wdog_preset = v; | ||
337 | fscpos_write_value(client, reg, data->wdog_preset); | ||
338 | mutex_unlock(&data->update_lock); | ||
339 | return count; | ||
340 | } | ||
341 | |||
342 | /* Event */ | ||
343 | static ssize_t show_event(struct device *dev, struct device_attribute *attr, char *buf) | ||
344 | { | ||
345 | /* bits 5..7 reserved => mask with 0x1f */ | ||
346 | struct fscpos_data *data = fscpos_update_device(dev); | ||
347 | return sprintf(buf, "%u\n", data->global_event & 0x9b); | ||
348 | } | ||
349 | |||
350 | /* | ||
351 | * Sysfs stuff | ||
352 | */ | ||
353 | #define create_getter(kind, sub) \ | ||
354 | static ssize_t sysfs_show_##kind##sub(struct device *dev, struct device_attribute *attr, char *buf) \ | ||
355 | { \ | ||
356 | struct fscpos_data *data = fscpos_update_device(dev); \ | ||
357 | return show_##kind##sub(data, buf); \ | ||
358 | } | ||
359 | |||
360 | #define create_getter_n(kind, offset, sub) \ | ||
361 | static ssize_t sysfs_show_##kind##offset##sub(struct device *dev, struct device_attribute *attr, char\ | ||
362 | *buf) \ | ||
363 | { \ | ||
364 | struct fscpos_data *data = fscpos_update_device(dev); \ | ||
365 | return show_##kind##sub(data, buf, offset); \ | ||
366 | } | ||
367 | |||
368 | #define create_setter(kind, sub, reg) \ | ||
369 | static ssize_t sysfs_set_##kind##sub (struct device *dev, struct device_attribute *attr, const char \ | ||
370 | *buf, size_t count) \ | ||
371 | { \ | ||
372 | struct i2c_client *client = to_i2c_client(dev); \ | ||
373 | struct fscpos_data *data = i2c_get_clientdata(client); \ | ||
374 | return set_##kind##sub(client, data, buf, count, reg); \ | ||
375 | } | ||
376 | |||
377 | #define create_setter_n(kind, offset, sub, reg) \ | ||
378 | static ssize_t sysfs_set_##kind##offset##sub (struct device *dev, struct device_attribute *attr, \ | ||
379 | const char *buf, size_t count) \ | ||
380 | { \ | ||
381 | struct i2c_client *client = to_i2c_client(dev); \ | ||
382 | struct fscpos_data *data = i2c_get_clientdata(client); \ | ||
383 | return set_##kind##sub(client, data, buf, count, offset, reg);\ | ||
384 | } | ||
385 | |||
386 | #define create_sysfs_device_ro(kind, sub, offset) \ | ||
387 | static DEVICE_ATTR(kind##offset##sub, S_IRUGO, \ | ||
388 | sysfs_show_##kind##offset##sub, NULL); | ||
389 | |||
390 | #define create_sysfs_device_rw(kind, sub, offset) \ | ||
391 | static DEVICE_ATTR(kind##offset##sub, S_IRUGO | S_IWUSR, \ | ||
392 | sysfs_show_##kind##offset##sub, sysfs_set_##kind##offset##sub); | ||
393 | |||
394 | #define sysfs_ro_n(kind, sub, offset) \ | ||
395 | create_getter_n(kind, offset, sub); \ | ||
396 | create_sysfs_device_ro(kind, sub, offset); | ||
397 | |||
398 | #define sysfs_rw_n(kind, sub, offset, reg) \ | ||
399 | create_getter_n(kind, offset, sub); \ | ||
400 | create_setter_n(kind, offset, sub, reg); \ | ||
401 | create_sysfs_device_rw(kind, sub, offset); | ||
402 | |||
403 | #define sysfs_rw(kind, sub, reg) \ | ||
404 | create_getter(kind, sub); \ | ||
405 | create_setter(kind, sub, reg); \ | ||
406 | create_sysfs_device_rw(kind, sub,); | ||
407 | |||
408 | #define sysfs_fan_with_min(offset, reg_status, reg_ripple, reg_min) \ | ||
409 | sysfs_fan(offset, reg_status, reg_ripple); \ | ||
410 | sysfs_rw_n(pwm,, offset, reg_min); | ||
411 | |||
412 | #define sysfs_fan(offset, reg_status, reg_ripple) \ | ||
413 | sysfs_ro_n(fan, _input, offset); \ | ||
414 | sysfs_ro_n(fan, _status, offset); \ | ||
415 | sysfs_rw_n(fan, _ripple, offset, reg_ripple); | ||
416 | |||
417 | #define sysfs_temp(offset, reg_status) \ | ||
418 | sysfs_ro_n(temp, _input, offset); \ | ||
419 | sysfs_ro_n(temp, _status, offset); \ | ||
420 | sysfs_rw_n(temp, _reset, offset, reg_status); | ||
421 | |||
422 | #define sysfs_watchdog(reg_wdog_preset, reg_wdog_state, reg_wdog_control) \ | ||
423 | sysfs_rw(wdog, _control, reg_wdog_control); \ | ||
424 | sysfs_rw(wdog, _preset, reg_wdog_preset); \ | ||
425 | sysfs_rw(wdog, _state, reg_wdog_state); | ||
426 | |||
427 | sysfs_fan_with_min(1, FSCPOS_REG_FAN_STATE[0], FSCPOS_REG_FAN_RIPPLE[0], | ||
428 | FSCPOS_REG_PWM[0]); | ||
429 | sysfs_fan_with_min(2, FSCPOS_REG_FAN_STATE[1], FSCPOS_REG_FAN_RIPPLE[1], | ||
430 | FSCPOS_REG_PWM[1]); | ||
431 | sysfs_fan(3, FSCPOS_REG_FAN_STATE[2], FSCPOS_REG_FAN_RIPPLE[2]); | ||
432 | |||
433 | sysfs_temp(1, FSCPOS_REG_TEMP_STATE[0]); | ||
434 | sysfs_temp(2, FSCPOS_REG_TEMP_STATE[1]); | ||
435 | sysfs_temp(3, FSCPOS_REG_TEMP_STATE[2]); | ||
436 | |||
437 | sysfs_watchdog(FSCPOS_REG_WDOG_PRESET, FSCPOS_REG_WDOG_STATE, | ||
438 | FSCPOS_REG_WDOG_CONTROL); | ||
439 | |||
440 | static DEVICE_ATTR(event, S_IRUGO, show_event, NULL); | ||
441 | static DEVICE_ATTR(in0_input, S_IRUGO, show_volt_12, NULL); | ||
442 | static DEVICE_ATTR(in1_input, S_IRUGO, show_volt_5, NULL); | ||
443 | static DEVICE_ATTR(in2_input, S_IRUGO, show_volt_batt, NULL); | ||
444 | |||
445 | static struct attribute *fscpos_attributes[] = { | ||
446 | &dev_attr_event.attr, | ||
447 | &dev_attr_in0_input.attr, | ||
448 | &dev_attr_in1_input.attr, | ||
449 | &dev_attr_in2_input.attr, | ||
450 | |||
451 | &dev_attr_wdog_control.attr, | ||
452 | &dev_attr_wdog_preset.attr, | ||
453 | &dev_attr_wdog_state.attr, | ||
454 | |||
455 | &dev_attr_temp1_input.attr, | ||
456 | &dev_attr_temp1_status.attr, | ||
457 | &dev_attr_temp1_reset.attr, | ||
458 | &dev_attr_temp2_input.attr, | ||
459 | &dev_attr_temp2_status.attr, | ||
460 | &dev_attr_temp2_reset.attr, | ||
461 | &dev_attr_temp3_input.attr, | ||
462 | &dev_attr_temp3_status.attr, | ||
463 | &dev_attr_temp3_reset.attr, | ||
464 | |||
465 | &dev_attr_fan1_input.attr, | ||
466 | &dev_attr_fan1_status.attr, | ||
467 | &dev_attr_fan1_ripple.attr, | ||
468 | &dev_attr_pwm1.attr, | ||
469 | &dev_attr_fan2_input.attr, | ||
470 | &dev_attr_fan2_status.attr, | ||
471 | &dev_attr_fan2_ripple.attr, | ||
472 | &dev_attr_pwm2.attr, | ||
473 | &dev_attr_fan3_input.attr, | ||
474 | &dev_attr_fan3_status.attr, | ||
475 | &dev_attr_fan3_ripple.attr, | ||
476 | NULL | ||
477 | }; | ||
478 | |||
479 | static const struct attribute_group fscpos_group = { | ||
480 | .attrs = fscpos_attributes, | ||
481 | }; | ||
482 | |||
483 | /* Return 0 if detection is successful, -ENODEV otherwise */ | ||
484 | static int fscpos_detect(struct i2c_client *new_client, int kind, | ||
485 | struct i2c_board_info *info) | ||
486 | { | ||
487 | struct i2c_adapter *adapter = new_client->adapter; | ||
488 | |||
489 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
490 | return -ENODEV; | ||
491 | |||
492 | /* Do the remaining detection unless force or force_fscpos parameter */ | ||
493 | if (kind < 0) { | ||
494 | if ((fscpos_read_value(new_client, FSCPOS_REG_IDENT_0) | ||
495 | != 0x50) /* 'P' */ | ||
496 | || (fscpos_read_value(new_client, FSCPOS_REG_IDENT_1) | ||
497 | != 0x45) /* 'E' */ | ||
498 | || (fscpos_read_value(new_client, FSCPOS_REG_IDENT_2) | ||
499 | != 0x47))/* 'G' */ | ||
500 | return -ENODEV; | ||
501 | } | ||
502 | |||
503 | strlcpy(info->type, "fscpos", I2C_NAME_SIZE); | ||
504 | |||
505 | return 0; | ||
506 | } | ||
507 | |||
508 | static int fscpos_probe(struct i2c_client *new_client, | ||
509 | const struct i2c_device_id *id) | ||
510 | { | ||
511 | struct fscpos_data *data; | ||
512 | int err; | ||
513 | |||
514 | data = kzalloc(sizeof(struct fscpos_data), GFP_KERNEL); | ||
515 | if (!data) { | ||
516 | err = -ENOMEM; | ||
517 | goto exit; | ||
518 | } | ||
519 | |||
520 | i2c_set_clientdata(new_client, data); | ||
521 | data->valid = 0; | ||
522 | mutex_init(&data->update_lock); | ||
523 | |||
524 | /* Inizialize the fscpos chip */ | ||
525 | fscpos_init_client(new_client); | ||
526 | |||
527 | /* Announce that the chip was found */ | ||
528 | dev_info(&new_client->dev, "Found fscpos chip, rev %u\n", data->revision); | ||
529 | |||
530 | /* Register sysfs hooks */ | ||
531 | if ((err = sysfs_create_group(&new_client->dev.kobj, &fscpos_group))) | ||
532 | goto exit_free; | ||
533 | |||
534 | data->hwmon_dev = hwmon_device_register(&new_client->dev); | ||
535 | if (IS_ERR(data->hwmon_dev)) { | ||
536 | err = PTR_ERR(data->hwmon_dev); | ||
537 | goto exit_remove_files; | ||
538 | } | ||
539 | |||
540 | return 0; | ||
541 | |||
542 | exit_remove_files: | ||
543 | sysfs_remove_group(&new_client->dev.kobj, &fscpos_group); | ||
544 | exit_free: | ||
545 | kfree(data); | ||
546 | exit: | ||
547 | return err; | ||
548 | } | ||
549 | |||
550 | static int fscpos_remove(struct i2c_client *client) | ||
551 | { | ||
552 | struct fscpos_data *data = i2c_get_clientdata(client); | ||
553 | |||
554 | hwmon_device_unregister(data->hwmon_dev); | ||
555 | sysfs_remove_group(&client->dev.kobj, &fscpos_group); | ||
556 | |||
557 | kfree(data); | ||
558 | return 0; | ||
559 | } | ||
560 | |||
561 | static int fscpos_read_value(struct i2c_client *client, u8 reg) | ||
562 | { | ||
563 | dev_dbg(&client->dev, "Read reg 0x%02x\n", reg); | ||
564 | return i2c_smbus_read_byte_data(client, reg); | ||
565 | } | ||
566 | |||
567 | static int fscpos_write_value(struct i2c_client *client, u8 reg, u8 value) | ||
568 | { | ||
569 | dev_dbg(&client->dev, "Write reg 0x%02x, val 0x%02x\n", reg, value); | ||
570 | return i2c_smbus_write_byte_data(client, reg, value); | ||
571 | } | ||
572 | |||
573 | /* Called when we have found a new FSCPOS chip */ | ||
574 | static void fscpos_init_client(struct i2c_client *client) | ||
575 | { | ||
576 | struct fscpos_data *data = i2c_get_clientdata(client); | ||
577 | |||
578 | /* read revision from chip */ | ||
579 | data->revision = fscpos_read_value(client, FSCPOS_REG_REVISION); | ||
580 | } | ||
581 | |||
582 | static struct fscpos_data *fscpos_update_device(struct device *dev) | ||
583 | { | ||
584 | struct i2c_client *client = to_i2c_client(dev); | ||
585 | struct fscpos_data *data = i2c_get_clientdata(client); | ||
586 | |||
587 | mutex_lock(&data->update_lock); | ||
588 | |||
589 | if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) { | ||
590 | int i; | ||
591 | |||
592 | dev_dbg(&client->dev, "Starting fscpos update\n"); | ||
593 | |||
594 | for (i = 0; i < 3; i++) { | ||
595 | data->temp_act[i] = fscpos_read_value(client, | ||
596 | FSCPOS_REG_TEMP_ACT[i]); | ||
597 | data->temp_status[i] = fscpos_read_value(client, | ||
598 | FSCPOS_REG_TEMP_STATE[i]); | ||
599 | data->fan_act[i] = fscpos_read_value(client, | ||
600 | FSCPOS_REG_FAN_ACT[i]); | ||
601 | data->fan_status[i] = fscpos_read_value(client, | ||
602 | FSCPOS_REG_FAN_STATE[i]); | ||
603 | data->fan_ripple[i] = fscpos_read_value(client, | ||
604 | FSCPOS_REG_FAN_RIPPLE[i]); | ||
605 | if (i < 2) { | ||
606 | /* fan2_min is not supported by the chip */ | ||
607 | data->pwm[i] = fscpos_read_value(client, | ||
608 | FSCPOS_REG_PWM[i]); | ||
609 | } | ||
610 | /* reset fan status if speed is back to > 0 */ | ||
611 | if (data->fan_status[i] != 0 && data->fan_act[i] > 0) { | ||
612 | reset_fan_alarm(client, i); | ||
613 | } | ||
614 | } | ||
615 | |||
616 | data->volt[0] = fscpos_read_value(client, FSCPOS_REG_VOLT_12); | ||
617 | data->volt[1] = fscpos_read_value(client, FSCPOS_REG_VOLT_5); | ||
618 | data->volt[2] = fscpos_read_value(client, FSCPOS_REG_VOLT_BATT); | ||
619 | |||
620 | data->wdog_preset = fscpos_read_value(client, | ||
621 | FSCPOS_REG_WDOG_PRESET); | ||
622 | data->wdog_state = fscpos_read_value(client, | ||
623 | FSCPOS_REG_WDOG_STATE); | ||
624 | data->wdog_control = fscpos_read_value(client, | ||
625 | FSCPOS_REG_WDOG_CONTROL); | ||
626 | |||
627 | data->global_event = fscpos_read_value(client, | ||
628 | FSCPOS_REG_EVENT_STATE); | ||
629 | |||
630 | data->last_updated = jiffies; | ||
631 | data->valid = 1; | ||
632 | } | ||
633 | mutex_unlock(&data->update_lock); | ||
634 | return data; | ||
635 | } | ||
636 | |||
637 | static int __init sm_fscpos_init(void) | ||
638 | { | ||
639 | return i2c_add_driver(&fscpos_driver); | ||
640 | } | ||
641 | |||
642 | static void __exit sm_fscpos_exit(void) | ||
643 | { | ||
644 | i2c_del_driver(&fscpos_driver); | ||
645 | } | ||
646 | |||
647 | MODULE_AUTHOR("Stefan Ott <stefan@desire.ch> based on work from Hermann Jung " | ||
648 | "<hej@odn.de>, Frodo Looijaard <frodol@dds.nl>" | ||
649 | " and Philip Edelbrock <phil@netroedge.com>"); | ||
650 | MODULE_DESCRIPTION("fujitsu siemens poseidon chip driver"); | ||
651 | MODULE_LICENSE("GPL"); | ||
652 | |||
653 | module_init(sm_fscpos_init); | ||
654 | module_exit(sm_fscpos_exit); | ||
diff --git a/drivers/hwmon/ltc4215.c b/drivers/hwmon/ltc4215.c index 9386e2a39211..6c9a04136e0a 100644 --- a/drivers/hwmon/ltc4215.c +++ b/drivers/hwmon/ltc4215.c | |||
@@ -259,7 +259,7 @@ static int ltc4215_probe(struct i2c_client *client, | |||
259 | mutex_init(&data->update_lock); | 259 | mutex_init(&data->update_lock); |
260 | 260 | ||
261 | /* Initialize the LTC4215 chip */ | 261 | /* Initialize the LTC4215 chip */ |
262 | /* TODO */ | 262 | i2c_smbus_write_byte_data(client, LTC4215_FAULT, 0x00); |
263 | 263 | ||
264 | /* Register sysfs hooks */ | 264 | /* Register sysfs hooks */ |
265 | ret = sysfs_create_group(&client->dev.kobj, <c4215_group); | 265 | ret = sysfs_create_group(&client->dev.kobj, <c4215_group); |
diff --git a/drivers/hwmon/ltc4245.c b/drivers/hwmon/ltc4245.c index 034b2c515848..e38964333612 100644 --- a/drivers/hwmon/ltc4245.c +++ b/drivers/hwmon/ltc4245.c | |||
@@ -382,7 +382,8 @@ static int ltc4245_probe(struct i2c_client *client, | |||
382 | mutex_init(&data->update_lock); | 382 | mutex_init(&data->update_lock); |
383 | 383 | ||
384 | /* Initialize the LTC4245 chip */ | 384 | /* Initialize the LTC4245 chip */ |
385 | /* TODO */ | 385 | i2c_smbus_write_byte_data(client, LTC4245_FAULT1, 0x00); |
386 | i2c_smbus_write_byte_data(client, LTC4245_FAULT2, 0x00); | ||
386 | 387 | ||
387 | /* Register sysfs hooks */ | 388 | /* Register sysfs hooks */ |
388 | ret = sysfs_create_group(&client->dev.kobj, <c4245_group); | 389 | ret = sysfs_create_group(&client->dev.kobj, <c4245_group); |
diff --git a/drivers/input/input.c b/drivers/input/input.c index 556539d617a4..e828aab7dace 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -11,6 +11,7 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/types.h> | ||
14 | #include <linux/input.h> | 15 | #include <linux/input.h> |
15 | #include <linux/module.h> | 16 | #include <linux/module.h> |
16 | #include <linux/random.h> | 17 | #include <linux/random.h> |
@@ -514,7 +515,7 @@ static void input_disconnect_device(struct input_dev *dev) | |||
514 | * that there are no threads in the middle of input_open_device() | 515 | * that there are no threads in the middle of input_open_device() |
515 | */ | 516 | */ |
516 | mutex_lock(&dev->mutex); | 517 | mutex_lock(&dev->mutex); |
517 | dev->going_away = 1; | 518 | dev->going_away = true; |
518 | mutex_unlock(&dev->mutex); | 519 | mutex_unlock(&dev->mutex); |
519 | 520 | ||
520 | spin_lock_irq(&dev->event_lock); | 521 | spin_lock_irq(&dev->event_lock); |
@@ -1259,10 +1260,71 @@ static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env) | |||
1259 | return 0; | 1260 | return 0; |
1260 | } | 1261 | } |
1261 | 1262 | ||
1263 | #define INPUT_DO_TOGGLE(dev, type, bits, on) \ | ||
1264 | do { \ | ||
1265 | int i; \ | ||
1266 | if (!test_bit(EV_##type, dev->evbit)) \ | ||
1267 | break; \ | ||
1268 | for (i = 0; i < type##_MAX; i++) { \ | ||
1269 | if (!test_bit(i, dev->bits##bit) || \ | ||
1270 | !test_bit(i, dev->bits)) \ | ||
1271 | continue; \ | ||
1272 | dev->event(dev, EV_##type, i, on); \ | ||
1273 | } \ | ||
1274 | } while (0) | ||
1275 | |||
1276 | static void input_dev_reset(struct input_dev *dev, bool activate) | ||
1277 | { | ||
1278 | if (!dev->event) | ||
1279 | return; | ||
1280 | |||
1281 | INPUT_DO_TOGGLE(dev, LED, led, activate); | ||
1282 | INPUT_DO_TOGGLE(dev, SND, snd, activate); | ||
1283 | |||
1284 | if (activate && test_bit(EV_REP, dev->evbit)) { | ||
1285 | dev->event(dev, EV_REP, REP_PERIOD, dev->rep[REP_PERIOD]); | ||
1286 | dev->event(dev, EV_REP, REP_DELAY, dev->rep[REP_DELAY]); | ||
1287 | } | ||
1288 | } | ||
1289 | |||
1290 | #ifdef CONFIG_PM | ||
1291 | static int input_dev_suspend(struct device *dev) | ||
1292 | { | ||
1293 | struct input_dev *input_dev = to_input_dev(dev); | ||
1294 | |||
1295 | mutex_lock(&input_dev->mutex); | ||
1296 | input_dev_reset(input_dev, false); | ||
1297 | mutex_unlock(&input_dev->mutex); | ||
1298 | |||
1299 | return 0; | ||
1300 | } | ||
1301 | |||
1302 | static int input_dev_resume(struct device *dev) | ||
1303 | { | ||
1304 | struct input_dev *input_dev = to_input_dev(dev); | ||
1305 | |||
1306 | mutex_lock(&input_dev->mutex); | ||
1307 | input_dev_reset(input_dev, true); | ||
1308 | mutex_unlock(&input_dev->mutex); | ||
1309 | |||
1310 | return 0; | ||
1311 | } | ||
1312 | |||
1313 | static const struct dev_pm_ops input_dev_pm_ops = { | ||
1314 | .suspend = input_dev_suspend, | ||
1315 | .resume = input_dev_resume, | ||
1316 | .poweroff = input_dev_suspend, | ||
1317 | .restore = input_dev_resume, | ||
1318 | }; | ||
1319 | #endif /* CONFIG_PM */ | ||
1320 | |||
1262 | static struct device_type input_dev_type = { | 1321 | static struct device_type input_dev_type = { |
1263 | .groups = input_dev_attr_groups, | 1322 | .groups = input_dev_attr_groups, |
1264 | .release = input_dev_release, | 1323 | .release = input_dev_release, |
1265 | .uevent = input_dev_uevent, | 1324 | .uevent = input_dev_uevent, |
1325 | #ifdef CONFIG_PM | ||
1326 | .pm = &input_dev_pm_ops, | ||
1327 | #endif | ||
1266 | }; | 1328 | }; |
1267 | 1329 | ||
1268 | static char *input_devnode(struct device *dev, mode_t *mode) | 1330 | static char *input_devnode(struct device *dev, mode_t *mode) |
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 3525c19be428..ee98b1bc5d89 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
@@ -24,6 +24,16 @@ config KEYBOARD_AAED2000 | |||
24 | To compile this driver as a module, choose M here: the | 24 | To compile this driver as a module, choose M here: the |
25 | module will be called aaed2000_kbd. | 25 | module will be called aaed2000_kbd. |
26 | 26 | ||
27 | config KEYBOARD_ADP5588 | ||
28 | tristate "ADP5588 I2C QWERTY Keypad and IO Expander" | ||
29 | depends on I2C | ||
30 | help | ||
31 | Say Y here if you want to use a ADP5588 attached to your | ||
32 | system I2C bus. | ||
33 | |||
34 | To compile this driver as a module, choose M here: the | ||
35 | module will be called adp5588-keys. | ||
36 | |||
27 | config KEYBOARD_AMIGA | 37 | config KEYBOARD_AMIGA |
28 | tristate "Amiga keyboard" | 38 | tristate "Amiga keyboard" |
29 | depends on AMIGA | 39 | depends on AMIGA |
@@ -104,6 +114,16 @@ config KEYBOARD_ATKBD_RDI_KEYCODES | |||
104 | right-hand column will be interpreted as the key shown in the | 114 | right-hand column will be interpreted as the key shown in the |
105 | left-hand column. | 115 | left-hand column. |
106 | 116 | ||
117 | config QT2160 | ||
118 | tristate "Atmel AT42QT2160 Touch Sensor Chip" | ||
119 | depends on I2C && EXPERIMENTAL | ||
120 | help | ||
121 | If you say yes here you get support for Atmel AT42QT2160 Touch | ||
122 | Sensor chip as a keyboard input. | ||
123 | |||
124 | This driver can also be built as a module. If so, the module | ||
125 | will be called qt2160. | ||
126 | |||
107 | config KEYBOARD_BFIN | 127 | config KEYBOARD_BFIN |
108 | tristate "Blackfin BF54x keypad support" | 128 | tristate "Blackfin BF54x keypad support" |
109 | depends on (BF54x && !BF544) | 129 | depends on (BF54x && !BF544) |
@@ -251,6 +271,17 @@ config KEYBOARD_MAPLE | |||
251 | To compile this driver as a module, choose M here: the | 271 | To compile this driver as a module, choose M here: the |
252 | module will be called maple_keyb. | 272 | module will be called maple_keyb. |
253 | 273 | ||
274 | config KEYBOARD_MAX7359 | ||
275 | tristate "Maxim MAX7359 Key Switch Controller" | ||
276 | depends on I2C | ||
277 | help | ||
278 | If you say yes here you get support for the Maxim MAX7359 Key | ||
279 | Switch Controller chip. This providers microprocessors with | ||
280 | management of up to 64 key switches | ||
281 | |||
282 | To compile this driver as a module, choose M here: the | ||
283 | module will be called max7359_keypad. | ||
284 | |||
254 | config KEYBOARD_NEWTON | 285 | config KEYBOARD_NEWTON |
255 | tristate "Newton keyboard" | 286 | tristate "Newton keyboard" |
256 | select SERIO | 287 | select SERIO |
@@ -260,6 +291,15 @@ config KEYBOARD_NEWTON | |||
260 | To compile this driver as a module, choose M here: the | 291 | To compile this driver as a module, choose M here: the |
261 | module will be called newtonkbd. | 292 | module will be called newtonkbd. |
262 | 293 | ||
294 | config KEYBOARD_OPENCORES | ||
295 | tristate "OpenCores Keyboard Controller" | ||
296 | help | ||
297 | Say Y here if you want to use the OpenCores Keyboard Controller | ||
298 | http://www.opencores.org/project,keyboardcontroller | ||
299 | |||
300 | To compile this driver as a module, choose M here; the | ||
301 | module will be called opencores-kbd. | ||
302 | |||
263 | config KEYBOARD_PXA27x | 303 | config KEYBOARD_PXA27x |
264 | tristate "PXA27x/PXA3xx keypad support" | 304 | tristate "PXA27x/PXA3xx keypad support" |
265 | depends on PXA27x || PXA3xx | 305 | depends on PXA27x || PXA3xx |
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 8a7a22b30266..babad5e58b77 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile | |||
@@ -5,6 +5,7 @@ | |||
5 | # Each configuration option enables a list of files. | 5 | # Each configuration option enables a list of files. |
6 | 6 | ||
7 | obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o | 7 | obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o |
8 | obj-$(CONFIG_KEYBOARD_ADP5588) += adp5588-keys.o | ||
8 | obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o | 9 | obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o |
9 | obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o | 10 | obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o |
10 | obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o | 11 | obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o |
@@ -21,10 +22,13 @@ obj-$(CONFIG_KEYBOARD_LM8323) += lm8323.o | |||
21 | obj-$(CONFIG_KEYBOARD_LOCOMO) += locomokbd.o | 22 | obj-$(CONFIG_KEYBOARD_LOCOMO) += locomokbd.o |
22 | obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o | 23 | obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o |
23 | obj-$(CONFIG_KEYBOARD_MATRIX) += matrix_keypad.o | 24 | obj-$(CONFIG_KEYBOARD_MATRIX) += matrix_keypad.o |
25 | obj-$(CONFIG_KEYBOARD_MAX7359) += max7359_keypad.o | ||
24 | obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o | 26 | obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o |
25 | obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o | 27 | obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o |
28 | obj-$(CONFIG_KEYBOARD_OPENCORES) += opencores-kbd.o | ||
26 | obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keypad.o | 29 | obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keypad.o |
27 | obj-$(CONFIG_KEYBOARD_PXA930_ROTARY) += pxa930_rotary.o | 30 | obj-$(CONFIG_KEYBOARD_PXA930_ROTARY) += pxa930_rotary.o |
31 | obj-$(CONFIG_KEYBOARD_QT2160) += qt2160.o | ||
28 | obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o | 32 | obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o |
29 | obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o | 33 | obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o |
30 | obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o | 34 | obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o |
diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c new file mode 100644 index 000000000000..d48c808d5928 --- /dev/null +++ b/drivers/input/keyboard/adp5588-keys.c | |||
@@ -0,0 +1,361 @@ | |||
1 | /* | ||
2 | * File: drivers/input/keyboard/adp5588_keys.c | ||
3 | * Description: keypad driver for ADP5588 I2C QWERTY Keypad and IO Expander | ||
4 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | ||
5 | * | ||
6 | * Copyright (C) 2008-2009 Analog Devices Inc. | ||
7 | * Licensed under the GPL-2 or later. | ||
8 | */ | ||
9 | |||
10 | #include <linux/module.h> | ||
11 | #include <linux/version.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/interrupt.h> | ||
14 | #include <linux/irq.h> | ||
15 | #include <linux/workqueue.h> | ||
16 | #include <linux/errno.h> | ||
17 | #include <linux/pm.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/input.h> | ||
20 | #include <linux/i2c.h> | ||
21 | |||
22 | #include <linux/i2c/adp5588.h> | ||
23 | |||
24 | /* Configuration Register1 */ | ||
25 | #define AUTO_INC (1 << 7) | ||
26 | #define GPIEM_CFG (1 << 6) | ||
27 | #define OVR_FLOW_M (1 << 5) | ||
28 | #define INT_CFG (1 << 4) | ||
29 | #define OVR_FLOW_IEN (1 << 3) | ||
30 | #define K_LCK_IM (1 << 2) | ||
31 | #define GPI_IEN (1 << 1) | ||
32 | #define KE_IEN (1 << 0) | ||
33 | |||
34 | /* Interrupt Status Register */ | ||
35 | #define CMP2_INT (1 << 5) | ||
36 | #define CMP1_INT (1 << 4) | ||
37 | #define OVR_FLOW_INT (1 << 3) | ||
38 | #define K_LCK_INT (1 << 2) | ||
39 | #define GPI_INT (1 << 1) | ||
40 | #define KE_INT (1 << 0) | ||
41 | |||
42 | /* Key Lock and Event Counter Register */ | ||
43 | #define K_LCK_EN (1 << 6) | ||
44 | #define LCK21 0x30 | ||
45 | #define KEC 0xF | ||
46 | |||
47 | /* Key Event Register xy */ | ||
48 | #define KEY_EV_PRESSED (1 << 7) | ||
49 | #define KEY_EV_MASK (0x7F) | ||
50 | |||
51 | #define KP_SEL(x) (0xFFFF >> (16 - x)) /* 2^x-1 */ | ||
52 | |||
53 | #define KEYP_MAX_EVENT 10 | ||
54 | |||
55 | /* | ||
56 | * Early pre 4.0 Silicon required to delay readout by at least 25ms, | ||
57 | * since the Event Counter Register updated 25ms after the interrupt | ||
58 | * asserted. | ||
59 | */ | ||
60 | #define WA_DELAYED_READOUT_REVID(rev) ((rev) < 4) | ||
61 | |||
62 | struct adp5588_kpad { | ||
63 | struct i2c_client *client; | ||
64 | struct input_dev *input; | ||
65 | struct delayed_work work; | ||
66 | unsigned long delay; | ||
67 | unsigned short keycode[ADP5588_KEYMAPSIZE]; | ||
68 | }; | ||
69 | |||
70 | static int adp5588_read(struct i2c_client *client, u8 reg) | ||
71 | { | ||
72 | int ret = i2c_smbus_read_byte_data(client, reg); | ||
73 | |||
74 | if (ret < 0) | ||
75 | dev_err(&client->dev, "Read Error\n"); | ||
76 | |||
77 | return ret; | ||
78 | } | ||
79 | |||
80 | static int adp5588_write(struct i2c_client *client, u8 reg, u8 val) | ||
81 | { | ||
82 | return i2c_smbus_write_byte_data(client, reg, val); | ||
83 | } | ||
84 | |||
85 | static void adp5588_work(struct work_struct *work) | ||
86 | { | ||
87 | struct adp5588_kpad *kpad = container_of(work, | ||
88 | struct adp5588_kpad, work.work); | ||
89 | struct i2c_client *client = kpad->client; | ||
90 | int i, key, status, ev_cnt; | ||
91 | |||
92 | status = adp5588_read(client, INT_STAT); | ||
93 | |||
94 | if (status & OVR_FLOW_INT) /* Unlikely and should never happen */ | ||
95 | dev_err(&client->dev, "Event Overflow Error\n"); | ||
96 | |||
97 | if (status & KE_INT) { | ||
98 | ev_cnt = adp5588_read(client, KEY_LCK_EC_STAT) & KEC; | ||
99 | if (ev_cnt) { | ||
100 | for (i = 0; i < ev_cnt; i++) { | ||
101 | key = adp5588_read(client, Key_EVENTA + i); | ||
102 | input_report_key(kpad->input, | ||
103 | kpad->keycode[(key & KEY_EV_MASK) - 1], | ||
104 | key & KEY_EV_PRESSED); | ||
105 | } | ||
106 | input_sync(kpad->input); | ||
107 | } | ||
108 | } | ||
109 | adp5588_write(client, INT_STAT, status); /* Status is W1C */ | ||
110 | } | ||
111 | |||
112 | static irqreturn_t adp5588_irq(int irq, void *handle) | ||
113 | { | ||
114 | struct adp5588_kpad *kpad = handle; | ||
115 | |||
116 | /* | ||
117 | * use keventd context to read the event fifo registers | ||
118 | * Schedule readout at least 25ms after notification for | ||
119 | * REVID < 4 | ||
120 | */ | ||
121 | |||
122 | schedule_delayed_work(&kpad->work, kpad->delay); | ||
123 | |||
124 | return IRQ_HANDLED; | ||
125 | } | ||
126 | |||
127 | static int __devinit adp5588_setup(struct i2c_client *client) | ||
128 | { | ||
129 | struct adp5588_kpad_platform_data *pdata = client->dev.platform_data; | ||
130 | int i, ret; | ||
131 | |||
132 | ret = adp5588_write(client, KP_GPIO1, KP_SEL(pdata->rows)); | ||
133 | ret |= adp5588_write(client, KP_GPIO2, KP_SEL(pdata->cols) & 0xFF); | ||
134 | ret |= adp5588_write(client, KP_GPIO3, KP_SEL(pdata->cols) >> 8); | ||
135 | |||
136 | if (pdata->en_keylock) { | ||
137 | ret |= adp5588_write(client, UNLOCK1, pdata->unlock_key1); | ||
138 | ret |= adp5588_write(client, UNLOCK2, pdata->unlock_key2); | ||
139 | ret |= adp5588_write(client, KEY_LCK_EC_STAT, K_LCK_EN); | ||
140 | } | ||
141 | |||
142 | for (i = 0; i < KEYP_MAX_EVENT; i++) | ||
143 | ret |= adp5588_read(client, Key_EVENTA); | ||
144 | |||
145 | ret |= adp5588_write(client, INT_STAT, CMP2_INT | CMP1_INT | | ||
146 | OVR_FLOW_INT | K_LCK_INT | | ||
147 | GPI_INT | KE_INT); /* Status is W1C */ | ||
148 | |||
149 | ret |= adp5588_write(client, CFG, INT_CFG | OVR_FLOW_IEN | KE_IEN); | ||
150 | |||
151 | if (ret < 0) { | ||
152 | dev_err(&client->dev, "Write Error\n"); | ||
153 | return ret; | ||
154 | } | ||
155 | |||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | static int __devinit adp5588_probe(struct i2c_client *client, | ||
160 | const struct i2c_device_id *id) | ||
161 | { | ||
162 | struct adp5588_kpad *kpad; | ||
163 | struct adp5588_kpad_platform_data *pdata = client->dev.platform_data; | ||
164 | struct input_dev *input; | ||
165 | unsigned int revid; | ||
166 | int ret, i; | ||
167 | int error; | ||
168 | |||
169 | if (!i2c_check_functionality(client->adapter, | ||
170 | I2C_FUNC_SMBUS_BYTE_DATA)) { | ||
171 | dev_err(&client->dev, "SMBUS Byte Data not Supported\n"); | ||
172 | return -EIO; | ||
173 | } | ||
174 | |||
175 | if (!pdata) { | ||
176 | dev_err(&client->dev, "no platform data?\n"); | ||
177 | return -EINVAL; | ||
178 | } | ||
179 | |||
180 | if (!pdata->rows || !pdata->cols || !pdata->keymap) { | ||
181 | dev_err(&client->dev, "no rows, cols or keymap from pdata\n"); | ||
182 | return -EINVAL; | ||
183 | } | ||
184 | |||
185 | if (pdata->keymapsize != ADP5588_KEYMAPSIZE) { | ||
186 | dev_err(&client->dev, "invalid keymapsize\n"); | ||
187 | return -EINVAL; | ||
188 | } | ||
189 | |||
190 | if (!client->irq) { | ||
191 | dev_err(&client->dev, "no IRQ?\n"); | ||
192 | return -EINVAL; | ||
193 | } | ||
194 | |||
195 | kpad = kzalloc(sizeof(*kpad), GFP_KERNEL); | ||
196 | input = input_allocate_device(); | ||
197 | if (!kpad || !input) { | ||
198 | error = -ENOMEM; | ||
199 | goto err_free_mem; | ||
200 | } | ||
201 | |||
202 | kpad->client = client; | ||
203 | kpad->input = input; | ||
204 | INIT_DELAYED_WORK(&kpad->work, adp5588_work); | ||
205 | |||
206 | ret = adp5588_read(client, DEV_ID); | ||
207 | if (ret < 0) { | ||
208 | error = ret; | ||
209 | goto err_free_mem; | ||
210 | } | ||
211 | |||
212 | revid = (u8) ret & ADP5588_DEVICE_ID_MASK; | ||
213 | if (WA_DELAYED_READOUT_REVID(revid)) | ||
214 | kpad->delay = msecs_to_jiffies(30); | ||
215 | |||
216 | input->name = client->name; | ||
217 | input->phys = "adp5588-keys/input0"; | ||
218 | input->dev.parent = &client->dev; | ||
219 | |||
220 | input_set_drvdata(input, kpad); | ||
221 | |||
222 | input->id.bustype = BUS_I2C; | ||
223 | input->id.vendor = 0x0001; | ||
224 | input->id.product = 0x0001; | ||
225 | input->id.version = revid; | ||
226 | |||
227 | input->keycodesize = sizeof(kpad->keycode[0]); | ||
228 | input->keycodemax = pdata->keymapsize; | ||
229 | input->keycode = kpad->keycode; | ||
230 | |||
231 | memcpy(kpad->keycode, pdata->keymap, | ||
232 | pdata->keymapsize * input->keycodesize); | ||
233 | |||
234 | /* setup input device */ | ||
235 | __set_bit(EV_KEY, input->evbit); | ||
236 | |||
237 | if (pdata->repeat) | ||
238 | __set_bit(EV_REP, input->evbit); | ||
239 | |||
240 | for (i = 0; i < input->keycodemax; i++) | ||
241 | __set_bit(kpad->keycode[i] & KEY_MAX, input->keybit); | ||
242 | __clear_bit(KEY_RESERVED, input->keybit); | ||
243 | |||
244 | error = input_register_device(input); | ||
245 | if (error) { | ||
246 | dev_err(&client->dev, "unable to register input device\n"); | ||
247 | goto err_free_mem; | ||
248 | } | ||
249 | |||
250 | error = request_irq(client->irq, adp5588_irq, | ||
251 | IRQF_TRIGGER_FALLING | IRQF_DISABLED, | ||
252 | client->dev.driver->name, kpad); | ||
253 | if (error) { | ||
254 | dev_err(&client->dev, "irq %d busy?\n", client->irq); | ||
255 | goto err_unreg_dev; | ||
256 | } | ||
257 | |||
258 | error = adp5588_setup(client); | ||
259 | if (error) | ||
260 | goto err_free_irq; | ||
261 | |||
262 | device_init_wakeup(&client->dev, 1); | ||
263 | i2c_set_clientdata(client, kpad); | ||
264 | |||
265 | dev_info(&client->dev, "Rev.%d keypad, irq %d\n", revid, client->irq); | ||
266 | return 0; | ||
267 | |||
268 | err_free_irq: | ||
269 | free_irq(client->irq, kpad); | ||
270 | err_unreg_dev: | ||
271 | input_unregister_device(input); | ||
272 | input = NULL; | ||
273 | err_free_mem: | ||
274 | input_free_device(input); | ||
275 | kfree(kpad); | ||
276 | |||
277 | return error; | ||
278 | } | ||
279 | |||
280 | static int __devexit adp5588_remove(struct i2c_client *client) | ||
281 | { | ||
282 | struct adp5588_kpad *kpad = i2c_get_clientdata(client); | ||
283 | |||
284 | adp5588_write(client, CFG, 0); | ||
285 | free_irq(client->irq, kpad); | ||
286 | cancel_delayed_work_sync(&kpad->work); | ||
287 | input_unregister_device(kpad->input); | ||
288 | i2c_set_clientdata(client, NULL); | ||
289 | kfree(kpad); | ||
290 | |||
291 | return 0; | ||
292 | } | ||
293 | |||
294 | #ifdef CONFIG_PM | ||
295 | static int adp5588_suspend(struct device *dev) | ||
296 | { | ||
297 | struct adp5588_kpad *kpad = dev_get_drvdata(dev); | ||
298 | struct i2c_client *client = kpad->client; | ||
299 | |||
300 | disable_irq(client->irq); | ||
301 | cancel_delayed_work_sync(&kpad->work); | ||
302 | |||
303 | if (device_may_wakeup(&client->dev)) | ||
304 | enable_irq_wake(client->irq); | ||
305 | |||
306 | return 0; | ||
307 | } | ||
308 | |||
309 | static int adp5588_resume(struct device *dev) | ||
310 | { | ||
311 | struct adp5588_kpad *kpad = dev_get_drvdata(dev); | ||
312 | struct i2c_client *client = kpad->client; | ||
313 | |||
314 | if (device_may_wakeup(&client->dev)) | ||
315 | disable_irq_wake(client->irq); | ||
316 | |||
317 | enable_irq(client->irq); | ||
318 | |||
319 | return 0; | ||
320 | } | ||
321 | |||
322 | static struct dev_pm_ops adp5588_dev_pm_ops = { | ||
323 | .suspend = adp5588_suspend, | ||
324 | .resume = adp5588_resume, | ||
325 | }; | ||
326 | #endif | ||
327 | |||
328 | static const struct i2c_device_id adp5588_id[] = { | ||
329 | { KBUILD_MODNAME, 0 }, | ||
330 | { } | ||
331 | }; | ||
332 | MODULE_DEVICE_TABLE(i2c, adp5588_id); | ||
333 | |||
334 | static struct i2c_driver adp5588_driver = { | ||
335 | .driver = { | ||
336 | .name = KBUILD_MODNAME, | ||
337 | #ifdef CONFIG_PM | ||
338 | .pm = &adp5588_dev_pm_ops, | ||
339 | #endif | ||
340 | }, | ||
341 | .probe = adp5588_probe, | ||
342 | .remove = __devexit_p(adp5588_remove), | ||
343 | .id_table = adp5588_id, | ||
344 | }; | ||
345 | |||
346 | static int __init adp5588_init(void) | ||
347 | { | ||
348 | return i2c_add_driver(&adp5588_driver); | ||
349 | } | ||
350 | module_init(adp5588_init); | ||
351 | |||
352 | static void __exit adp5588_exit(void) | ||
353 | { | ||
354 | i2c_del_driver(&adp5588_driver); | ||
355 | } | ||
356 | module_exit(adp5588_exit); | ||
357 | |||
358 | MODULE_LICENSE("GPL"); | ||
359 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | ||
360 | MODULE_DESCRIPTION("ADP5588 Keypad driver"); | ||
361 | MODULE_ALIAS("platform:adp5588-keys"); | ||
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index adb09e2ba394..4709e15af607 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -773,23 +773,6 @@ static int atkbd_select_set(struct atkbd *atkbd, int target_set, int allow_extra | |||
773 | static int atkbd_activate(struct atkbd *atkbd) | 773 | static int atkbd_activate(struct atkbd *atkbd) |
774 | { | 774 | { |
775 | struct ps2dev *ps2dev = &atkbd->ps2dev; | 775 | struct ps2dev *ps2dev = &atkbd->ps2dev; |
776 | unsigned char param[1]; | ||
777 | |||
778 | /* | ||
779 | * Set the LEDs to a defined state. | ||
780 | */ | ||
781 | |||
782 | param[0] = 0; | ||
783 | if (ps2_command(ps2dev, param, ATKBD_CMD_SETLEDS)) | ||
784 | return -1; | ||
785 | |||
786 | /* | ||
787 | * Set autorepeat to fastest possible. | ||
788 | */ | ||
789 | |||
790 | param[0] = 0; | ||
791 | if (ps2_command(ps2dev, param, ATKBD_CMD_SETREP)) | ||
792 | return -1; | ||
793 | 776 | ||
794 | /* | 777 | /* |
795 | * Enable the keyboard to receive keystrokes. | 778 | * Enable the keyboard to receive keystrokes. |
@@ -1158,14 +1141,6 @@ static int atkbd_reconnect(struct serio *serio) | |||
1158 | return -1; | 1141 | return -1; |
1159 | 1142 | ||
1160 | atkbd_activate(atkbd); | 1143 | atkbd_activate(atkbd); |
1161 | |||
1162 | /* | ||
1163 | * Restore repeat rate and LEDs (that were reset by atkbd_activate) | ||
1164 | * to pre-resume state | ||
1165 | */ | ||
1166 | if (!atkbd->softrepeat) | ||
1167 | atkbd_set_repeat_rate(atkbd); | ||
1168 | atkbd_set_leds(atkbd); | ||
1169 | } | 1144 | } |
1170 | 1145 | ||
1171 | atkbd_enable(atkbd); | 1146 | atkbd_enable(atkbd); |
diff --git a/drivers/input/keyboard/max7359_keypad.c b/drivers/input/keyboard/max7359_keypad.c new file mode 100644 index 000000000000..3b5b948eba39 --- /dev/null +++ b/drivers/input/keyboard/max7359_keypad.c | |||
@@ -0,0 +1,330 @@ | |||
1 | /* | ||
2 | * max7359_keypad.c - MAX7359 Key Switch Controller Driver | ||
3 | * | ||
4 | * Copyright (C) 2009 Samsung Electronics | ||
5 | * Kim Kyuwon <q1.kim@samsung.com> | ||
6 | * | ||
7 | * Based on pxa27x_keypad.c | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | * Datasheet: http://www.maxim-ic.com/quick_view2.cfm/qv_pk/5456 | ||
14 | */ | ||
15 | |||
16 | #include <linux/module.h> | ||
17 | #include <linux/i2c.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/input.h> | ||
20 | #include <linux/input/matrix_keypad.h> | ||
21 | |||
22 | #define MAX7359_MAX_KEY_ROWS 8 | ||
23 | #define MAX7359_MAX_KEY_COLS 8 | ||
24 | #define MAX7359_MAX_KEY_NUM (MAX7359_MAX_KEY_ROWS * MAX7359_MAX_KEY_COLS) | ||
25 | #define MAX7359_ROW_SHIFT 3 | ||
26 | |||
27 | /* | ||
28 | * MAX7359 registers | ||
29 | */ | ||
30 | #define MAX7359_REG_KEYFIFO 0x00 | ||
31 | #define MAX7359_REG_CONFIG 0x01 | ||
32 | #define MAX7359_REG_DEBOUNCE 0x02 | ||
33 | #define MAX7359_REG_INTERRUPT 0x03 | ||
34 | #define MAX7359_REG_PORTS 0x04 | ||
35 | #define MAX7359_REG_KEYREP 0x05 | ||
36 | #define MAX7359_REG_SLEEP 0x06 | ||
37 | |||
38 | /* | ||
39 | * Configuration register bits | ||
40 | */ | ||
41 | #define MAX7359_CFG_SLEEP (1 << 7) | ||
42 | #define MAX7359_CFG_INTERRUPT (1 << 5) | ||
43 | #define MAX7359_CFG_KEY_RELEASE (1 << 3) | ||
44 | #define MAX7359_CFG_WAKEUP (1 << 1) | ||
45 | #define MAX7359_CFG_TIMEOUT (1 << 0) | ||
46 | |||
47 | /* | ||
48 | * Autosleep register values (ms) | ||
49 | */ | ||
50 | #define MAX7359_AUTOSLEEP_8192 0x01 | ||
51 | #define MAX7359_AUTOSLEEP_4096 0x02 | ||
52 | #define MAX7359_AUTOSLEEP_2048 0x03 | ||
53 | #define MAX7359_AUTOSLEEP_1024 0x04 | ||
54 | #define MAX7359_AUTOSLEEP_512 0x05 | ||
55 | #define MAX7359_AUTOSLEEP_256 0x06 | ||
56 | |||
57 | struct max7359_keypad { | ||
58 | /* matrix key code map */ | ||
59 | unsigned short keycodes[MAX7359_MAX_KEY_NUM]; | ||
60 | |||
61 | struct input_dev *input_dev; | ||
62 | struct i2c_client *client; | ||
63 | }; | ||
64 | |||
65 | static int max7359_write_reg(struct i2c_client *client, u8 reg, u8 val) | ||
66 | { | ||
67 | int ret = i2c_smbus_write_byte_data(client, reg, val); | ||
68 | |||
69 | if (ret < 0) | ||
70 | dev_err(&client->dev, "%s: reg 0x%x, val 0x%x, err %d\n", | ||
71 | __func__, reg, val, ret); | ||
72 | return ret; | ||
73 | } | ||
74 | |||
75 | static int max7359_read_reg(struct i2c_client *client, int reg) | ||
76 | { | ||
77 | int ret = i2c_smbus_read_byte_data(client, reg); | ||
78 | |||
79 | if (ret < 0) | ||
80 | dev_err(&client->dev, "%s: reg 0x%x, err %d\n", | ||
81 | __func__, reg, ret); | ||
82 | return ret; | ||
83 | } | ||
84 | |||
85 | static void max7359_build_keycode(struct max7359_keypad *keypad, | ||
86 | const struct matrix_keymap_data *keymap_data) | ||
87 | { | ||
88 | struct input_dev *input_dev = keypad->input_dev; | ||
89 | int i; | ||
90 | |||
91 | for (i = 0; i < keymap_data->keymap_size; i++) { | ||
92 | unsigned int key = keymap_data->keymap[i]; | ||
93 | unsigned int row = KEY_ROW(key); | ||
94 | unsigned int col = KEY_COL(key); | ||
95 | unsigned int scancode = MATRIX_SCAN_CODE(row, col, | ||
96 | MAX7359_ROW_SHIFT); | ||
97 | unsigned short keycode = KEY_VAL(key); | ||
98 | |||
99 | keypad->keycodes[scancode] = keycode; | ||
100 | __set_bit(keycode, input_dev->keybit); | ||
101 | } | ||
102 | __clear_bit(KEY_RESERVED, input_dev->keybit); | ||
103 | } | ||
104 | |||
105 | /* runs in an IRQ thread -- can (and will!) sleep */ | ||
106 | static irqreturn_t max7359_interrupt(int irq, void *dev_id) | ||
107 | { | ||
108 | struct max7359_keypad *keypad = dev_id; | ||
109 | struct input_dev *input_dev = keypad->input_dev; | ||
110 | int val, row, col, release, code; | ||
111 | |||
112 | val = max7359_read_reg(keypad->client, MAX7359_REG_KEYFIFO); | ||
113 | row = val & 0x7; | ||
114 | col = (val >> 3) & 0x7; | ||
115 | release = val & 0x40; | ||
116 | |||
117 | code = MATRIX_SCAN_CODE(row, col, MAX7359_ROW_SHIFT); | ||
118 | |||
119 | dev_dbg(&keypad->client->dev, | ||
120 | "key[%d:%d] %s\n", row, col, release ? "release" : "press"); | ||
121 | |||
122 | input_event(input_dev, EV_MSC, MSC_SCAN, code); | ||
123 | input_report_key(input_dev, keypad->keycodes[code], !release); | ||
124 | input_sync(input_dev); | ||
125 | |||
126 | return IRQ_HANDLED; | ||
127 | } | ||
128 | |||
129 | /* | ||
130 | * Let MAX7359 fall into a deep sleep: | ||
131 | * If no keys are pressed, enter sleep mode for 8192 ms. And if any | ||
132 | * key is pressed, the MAX7359 returns to normal operating mode. | ||
133 | */ | ||
134 | static inline void max7359_fall_deepsleep(struct i2c_client *client) | ||
135 | { | ||
136 | max7359_write_reg(client, MAX7359_REG_SLEEP, MAX7359_AUTOSLEEP_8192); | ||
137 | } | ||
138 | |||
139 | /* | ||
140 | * Let MAX7359 take a catnap: | ||
141 | * Autosleep just for 256 ms. | ||
142 | */ | ||
143 | static inline void max7359_take_catnap(struct i2c_client *client) | ||
144 | { | ||
145 | max7359_write_reg(client, MAX7359_REG_SLEEP, MAX7359_AUTOSLEEP_256); | ||
146 | } | ||
147 | |||
148 | static int max7359_open(struct input_dev *dev) | ||
149 | { | ||
150 | struct max7359_keypad *keypad = input_get_drvdata(dev); | ||
151 | |||
152 | max7359_take_catnap(keypad->client); | ||
153 | |||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | static void max7359_close(struct input_dev *dev) | ||
158 | { | ||
159 | struct max7359_keypad *keypad = input_get_drvdata(dev); | ||
160 | |||
161 | max7359_fall_deepsleep(keypad->client); | ||
162 | } | ||
163 | |||
164 | static void max7359_initialize(struct i2c_client *client) | ||
165 | { | ||
166 | max7359_write_reg(client, MAX7359_REG_CONFIG, | ||
167 | MAX7359_CFG_INTERRUPT | /* Irq clears after host read */ | ||
168 | MAX7359_CFG_KEY_RELEASE | /* Key release enable */ | ||
169 | MAX7359_CFG_WAKEUP); /* Key press wakeup enable */ | ||
170 | |||
171 | /* Full key-scan functionality */ | ||
172 | max7359_write_reg(client, MAX7359_REG_DEBOUNCE, 0x1F); | ||
173 | |||
174 | /* nINT asserts every debounce cycles */ | ||
175 | max7359_write_reg(client, MAX7359_REG_INTERRUPT, 0x01); | ||
176 | |||
177 | max7359_fall_deepsleep(client); | ||
178 | } | ||
179 | |||
180 | static int __devinit max7359_probe(struct i2c_client *client, | ||
181 | const struct i2c_device_id *id) | ||
182 | { | ||
183 | const struct matrix_keymap_data *keymap_data = client->dev.platform_data; | ||
184 | struct max7359_keypad *keypad; | ||
185 | struct input_dev *input_dev; | ||
186 | int ret; | ||
187 | int error; | ||
188 | |||
189 | if (!client->irq) { | ||
190 | dev_err(&client->dev, "The irq number should not be zero\n"); | ||
191 | return -EINVAL; | ||
192 | } | ||
193 | |||
194 | /* Detect MAX7359: The initial Keys FIFO value is '0x3F' */ | ||
195 | ret = max7359_read_reg(client, MAX7359_REG_KEYFIFO); | ||
196 | if (ret < 0) { | ||
197 | dev_err(&client->dev, "failed to detect device\n"); | ||
198 | return -ENODEV; | ||
199 | } | ||
200 | |||
201 | dev_dbg(&client->dev, "keys FIFO is 0x%02x\n", ret); | ||
202 | |||
203 | keypad = kzalloc(sizeof(struct max7359_keypad), GFP_KERNEL); | ||
204 | input_dev = input_allocate_device(); | ||
205 | if (!keypad || !input_dev) { | ||
206 | dev_err(&client->dev, "failed to allocate memory\n"); | ||
207 | error = -ENOMEM; | ||
208 | goto failed_free_mem; | ||
209 | } | ||
210 | |||
211 | keypad->client = client; | ||
212 | keypad->input_dev = input_dev; | ||
213 | |||
214 | input_dev->name = client->name; | ||
215 | input_dev->id.bustype = BUS_I2C; | ||
216 | input_dev->open = max7359_open; | ||
217 | input_dev->close = max7359_close; | ||
218 | input_dev->dev.parent = &client->dev; | ||
219 | |||
220 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); | ||
221 | input_dev->keycodesize = sizeof(keypad->keycodes[0]); | ||
222 | input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes); | ||
223 | input_dev->keycode = keypad->keycodes; | ||
224 | |||
225 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | ||
226 | input_set_drvdata(input_dev, keypad); | ||
227 | |||
228 | max7359_build_keycode(keypad, keymap_data); | ||
229 | |||
230 | error = request_threaded_irq(client->irq, NULL, max7359_interrupt, | ||
231 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | ||
232 | client->name, keypad); | ||
233 | if (error) { | ||
234 | dev_err(&client->dev, "failed to register interrupt\n"); | ||
235 | goto failed_free_mem; | ||
236 | } | ||
237 | |||
238 | /* Register the input device */ | ||
239 | error = input_register_device(input_dev); | ||
240 | if (error) { | ||
241 | dev_err(&client->dev, "failed to register input device\n"); | ||
242 | goto failed_free_irq; | ||
243 | } | ||
244 | |||
245 | /* Initialize MAX7359 */ | ||
246 | max7359_initialize(client); | ||
247 | |||
248 | i2c_set_clientdata(client, keypad); | ||
249 | device_init_wakeup(&client->dev, 1); | ||
250 | |||
251 | return 0; | ||
252 | |||
253 | failed_free_irq: | ||
254 | free_irq(client->irq, keypad); | ||
255 | failed_free_mem: | ||
256 | input_free_device(input_dev); | ||
257 | kfree(keypad); | ||
258 | return error; | ||
259 | } | ||
260 | |||
261 | static int __devexit max7359_remove(struct i2c_client *client) | ||
262 | { | ||
263 | struct max7359_keypad *keypad = i2c_get_clientdata(client); | ||
264 | |||
265 | free_irq(client->irq, keypad); | ||
266 | input_unregister_device(keypad->input_dev); | ||
267 | i2c_set_clientdata(client, NULL); | ||
268 | kfree(keypad); | ||
269 | |||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | #ifdef CONFIG_PM | ||
274 | static int max7359_suspend(struct i2c_client *client, pm_message_t mesg) | ||
275 | { | ||
276 | max7359_fall_deepsleep(client); | ||
277 | |||
278 | if (device_may_wakeup(&client->dev)) | ||
279 | enable_irq_wake(client->irq); | ||
280 | |||
281 | return 0; | ||
282 | } | ||
283 | |||
284 | static int max7359_resume(struct i2c_client *client) | ||
285 | { | ||
286 | if (device_may_wakeup(&client->dev)) | ||
287 | disable_irq_wake(client->irq); | ||
288 | |||
289 | /* Restore the default setting */ | ||
290 | max7359_take_catnap(client); | ||
291 | |||
292 | return 0; | ||
293 | } | ||
294 | #else | ||
295 | #define max7359_suspend NULL | ||
296 | #define max7359_resume NULL | ||
297 | #endif | ||
298 | |||
299 | static const struct i2c_device_id max7359_ids[] = { | ||
300 | { "max7359", 0 }, | ||
301 | { } | ||
302 | }; | ||
303 | MODULE_DEVICE_TABLE(i2c, max7359_ids); | ||
304 | |||
305 | static struct i2c_driver max7359_i2c_driver = { | ||
306 | .driver = { | ||
307 | .name = "max7359", | ||
308 | }, | ||
309 | .probe = max7359_probe, | ||
310 | .remove = __devexit_p(max7359_remove), | ||
311 | .suspend = max7359_suspend, | ||
312 | .resume = max7359_resume, | ||
313 | .id_table = max7359_ids, | ||
314 | }; | ||
315 | |||
316 | static int __init max7359_init(void) | ||
317 | { | ||
318 | return i2c_add_driver(&max7359_i2c_driver); | ||
319 | } | ||
320 | module_init(max7359_init); | ||
321 | |||
322 | static void __exit max7359_exit(void) | ||
323 | { | ||
324 | i2c_del_driver(&max7359_i2c_driver); | ||
325 | } | ||
326 | module_exit(max7359_exit); | ||
327 | |||
328 | MODULE_AUTHOR("Kim Kyuwon <q1.kim@samsung.com>"); | ||
329 | MODULE_DESCRIPTION("MAX7359 Key Switch Controller Driver"); | ||
330 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/input/keyboard/opencores-kbd.c b/drivers/input/keyboard/opencores-kbd.c new file mode 100644 index 000000000000..78cccddbf551 --- /dev/null +++ b/drivers/input/keyboard/opencores-kbd.c | |||
@@ -0,0 +1,180 @@ | |||
1 | /* | ||
2 | * OpenCores Keyboard Controller Driver | ||
3 | * http://www.opencores.org/project,keyboardcontroller | ||
4 | * | ||
5 | * Copyright 2007-2009 HV Sistemas S.L. | ||
6 | * | ||
7 | * Licensed under the GPL-2 or later. | ||
8 | */ | ||
9 | |||
10 | #include <linux/input.h> | ||
11 | #include <linux/interrupt.h> | ||
12 | #include <linux/io.h> | ||
13 | #include <linux/ioport.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | |||
18 | struct opencores_kbd { | ||
19 | struct input_dev *input; | ||
20 | struct resource *addr_res; | ||
21 | void __iomem *addr; | ||
22 | int irq; | ||
23 | unsigned short keycodes[128]; | ||
24 | }; | ||
25 | |||
26 | static irqreturn_t opencores_kbd_isr(int irq, void *dev_id) | ||
27 | { | ||
28 | struct opencores_kbd *opencores_kbd = dev_id; | ||
29 | struct input_dev *input = opencores_kbd->input; | ||
30 | unsigned char c; | ||
31 | |||
32 | c = readb(opencores_kbd->addr); | ||
33 | input_report_key(input, c & 0x7f, c & 0x80 ? 0 : 1); | ||
34 | input_sync(input); | ||
35 | |||
36 | return IRQ_HANDLED; | ||
37 | } | ||
38 | |||
39 | static int __devinit opencores_kbd_probe(struct platform_device *pdev) | ||
40 | { | ||
41 | struct input_dev *input; | ||
42 | struct opencores_kbd *opencores_kbd; | ||
43 | struct resource *res; | ||
44 | int irq, i, error; | ||
45 | |||
46 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
47 | if (!res) { | ||
48 | dev_err(&pdev->dev, "missing board memory resource\n"); | ||
49 | return -EINVAL; | ||
50 | } | ||
51 | |||
52 | irq = platform_get_irq(pdev, 0); | ||
53 | if (irq < 0) { | ||
54 | dev_err(&pdev->dev, "missing board IRQ resource\n"); | ||
55 | return -EINVAL; | ||
56 | } | ||
57 | |||
58 | opencores_kbd = kzalloc(sizeof(*opencores_kbd), GFP_KERNEL); | ||
59 | input = input_allocate_device(); | ||
60 | if (!opencores_kbd || !input) { | ||
61 | dev_err(&pdev->dev, "failed to allocate device structures\n"); | ||
62 | error = -ENOMEM; | ||
63 | goto err_free_mem; | ||
64 | } | ||
65 | |||
66 | opencores_kbd->addr_res = res; | ||
67 | res = request_mem_region(res->start, resource_size(res), pdev->name); | ||
68 | if (!res) { | ||
69 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | ||
70 | error = -EBUSY; | ||
71 | goto err_free_mem; | ||
72 | } | ||
73 | |||
74 | opencores_kbd->addr = ioremap(res->start, resource_size(res)); | ||
75 | if (!opencores_kbd->addr) { | ||
76 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); | ||
77 | error = -ENXIO; | ||
78 | goto err_rel_mem; | ||
79 | } | ||
80 | |||
81 | opencores_kbd->input = input; | ||
82 | opencores_kbd->irq = irq; | ||
83 | |||
84 | input->name = pdev->name; | ||
85 | input->phys = "opencores-kbd/input0"; | ||
86 | input->dev.parent = &pdev->dev; | ||
87 | |||
88 | input_set_drvdata(input, opencores_kbd); | ||
89 | |||
90 | input->id.bustype = BUS_HOST; | ||
91 | input->id.vendor = 0x0001; | ||
92 | input->id.product = 0x0001; | ||
93 | input->id.version = 0x0100; | ||
94 | |||
95 | input->keycode = opencores_kbd->keycodes; | ||
96 | input->keycodesize = sizeof(opencores_kbd->keycodes[0]); | ||
97 | input->keycodemax = ARRAY_SIZE(opencores_kbd->keycodes); | ||
98 | |||
99 | __set_bit(EV_KEY, input->evbit); | ||
100 | |||
101 | for (i = 0; i < ARRAY_SIZE(opencores_kbd->keycodes); i++) { | ||
102 | /* | ||
103 | * OpenCores controller happens to have scancodes match | ||
104 | * our KEY_* definitions. | ||
105 | */ | ||
106 | opencores_kbd->keycodes[i] = i; | ||
107 | __set_bit(opencores_kbd->keycodes[i], input->keybit); | ||
108 | } | ||
109 | __clear_bit(KEY_RESERVED, input->keybit); | ||
110 | |||
111 | error = request_irq(irq, &opencores_kbd_isr, | ||
112 | IRQF_TRIGGER_RISING, pdev->name, opencores_kbd); | ||
113 | if (error) { | ||
114 | dev_err(&pdev->dev, "unable to claim irq %d\n", irq); | ||
115 | goto err_unmap_mem; | ||
116 | } | ||
117 | |||
118 | error = input_register_device(input); | ||
119 | if (error) { | ||
120 | dev_err(&pdev->dev, "unable to register input device\n"); | ||
121 | goto err_free_irq; | ||
122 | } | ||
123 | |||
124 | platform_set_drvdata(pdev, opencores_kbd); | ||
125 | |||
126 | return 0; | ||
127 | |||
128 | err_free_irq: | ||
129 | free_irq(irq, opencores_kbd); | ||
130 | err_unmap_mem: | ||
131 | iounmap(opencores_kbd->addr); | ||
132 | err_rel_mem: | ||
133 | release_mem_region(res->start, resource_size(res)); | ||
134 | err_free_mem: | ||
135 | input_free_device(input); | ||
136 | kfree(opencores_kbd); | ||
137 | |||
138 | return error; | ||
139 | } | ||
140 | |||
141 | static int __devexit opencores_kbd_remove(struct platform_device *pdev) | ||
142 | { | ||
143 | struct opencores_kbd *opencores_kbd = platform_get_drvdata(pdev); | ||
144 | |||
145 | free_irq(opencores_kbd->irq, opencores_kbd); | ||
146 | |||
147 | iounmap(opencores_kbd->addr); | ||
148 | release_mem_region(opencores_kbd->addr_res->start, | ||
149 | resource_size(opencores_kbd->addr_res)); | ||
150 | input_unregister_device(opencores_kbd->input); | ||
151 | kfree(opencores_kbd); | ||
152 | |||
153 | platform_set_drvdata(pdev, NULL); | ||
154 | |||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | static struct platform_driver opencores_kbd_device_driver = { | ||
159 | .probe = opencores_kbd_probe, | ||
160 | .remove = __devexit_p(opencores_kbd_remove), | ||
161 | .driver = { | ||
162 | .name = "opencores-kbd", | ||
163 | }, | ||
164 | }; | ||
165 | |||
166 | static int __init opencores_kbd_init(void) | ||
167 | { | ||
168 | return platform_driver_register(&opencores_kbd_device_driver); | ||
169 | } | ||
170 | module_init(opencores_kbd_init); | ||
171 | |||
172 | static void __exit opencores_kbd_exit(void) | ||
173 | { | ||
174 | platform_driver_unregister(&opencores_kbd_device_driver); | ||
175 | } | ||
176 | module_exit(opencores_kbd_exit); | ||
177 | |||
178 | MODULE_LICENSE("GPL"); | ||
179 | MODULE_AUTHOR("Javier Herrero <jherrero@hvsistemas.es>"); | ||
180 | MODULE_DESCRIPTION("Keyboard driver for OpenCores Keyboard Controller"); | ||
diff --git a/drivers/input/keyboard/qt2160.c b/drivers/input/keyboard/qt2160.c new file mode 100644 index 000000000000..191cc51d6cf8 --- /dev/null +++ b/drivers/input/keyboard/qt2160.c | |||
@@ -0,0 +1,397 @@ | |||
1 | /* | ||
2 | * qt2160.c - Atmel AT42QT2160 Touch Sense Controller | ||
3 | * | ||
4 | * Copyright (C) 2009 Raphael Derosso Pereira <raphaelpereira@gmail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/jiffies.h> | ||
26 | #include <linux/i2c.h> | ||
27 | #include <linux/irq.h> | ||
28 | #include <linux/interrupt.h> | ||
29 | #include <linux/input.h> | ||
30 | |||
31 | #define QT2160_VALID_CHIPID 0x11 | ||
32 | |||
33 | #define QT2160_CMD_CHIPID 0 | ||
34 | #define QT2160_CMD_CODEVER 1 | ||
35 | #define QT2160_CMD_GSTAT 2 | ||
36 | #define QT2160_CMD_KEYS3 3 | ||
37 | #define QT2160_CMD_KEYS4 4 | ||
38 | #define QT2160_CMD_SLIDE 5 | ||
39 | #define QT2160_CMD_GPIOS 6 | ||
40 | #define QT2160_CMD_SUBVER 7 | ||
41 | #define QT2160_CMD_CALIBRATE 10 | ||
42 | |||
43 | #define QT2160_CYCLE_INTERVAL (2*HZ) | ||
44 | |||
45 | static unsigned char qt2160_key2code[] = { | ||
46 | KEY_0, KEY_1, KEY_2, KEY_3, | ||
47 | KEY_4, KEY_5, KEY_6, KEY_7, | ||
48 | KEY_8, KEY_9, KEY_A, KEY_B, | ||
49 | KEY_C, KEY_D, KEY_E, KEY_F, | ||
50 | }; | ||
51 | |||
52 | struct qt2160_data { | ||
53 | struct i2c_client *client; | ||
54 | struct input_dev *input; | ||
55 | struct delayed_work dwork; | ||
56 | spinlock_t lock; /* Protects canceling/rescheduling of dwork */ | ||
57 | unsigned short keycodes[ARRAY_SIZE(qt2160_key2code)]; | ||
58 | u16 key_matrix; | ||
59 | }; | ||
60 | |||
61 | static int qt2160_read_block(struct i2c_client *client, | ||
62 | u8 inireg, u8 *buffer, unsigned int count) | ||
63 | { | ||
64 | int error, idx = 0; | ||
65 | |||
66 | /* | ||
67 | * Can't use SMBus block data read. Check for I2C functionality to speed | ||
68 | * things up whenever possible. Otherwise we will be forced to read | ||
69 | * sequentially. | ||
70 | */ | ||
71 | if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { | ||
72 | |||
73 | error = i2c_smbus_write_byte(client, inireg + idx); | ||
74 | if (error) { | ||
75 | dev_err(&client->dev, | ||
76 | "couldn't send request. Returned %d\n", error); | ||
77 | return error; | ||
78 | } | ||
79 | |||
80 | error = i2c_master_recv(client, buffer, count); | ||
81 | if (error != count) { | ||
82 | dev_err(&client->dev, | ||
83 | "couldn't read registers. Returned %d bytes\n", error); | ||
84 | return error; | ||
85 | } | ||
86 | } else { | ||
87 | |||
88 | while (count--) { | ||
89 | int data; | ||
90 | |||
91 | error = i2c_smbus_write_byte(client, inireg + idx); | ||
92 | if (error) { | ||
93 | dev_err(&client->dev, | ||
94 | "couldn't send request. Returned %d\n", error); | ||
95 | return error; | ||
96 | } | ||
97 | |||
98 | data = i2c_smbus_read_byte(client); | ||
99 | if (data < 0) { | ||
100 | dev_err(&client->dev, | ||
101 | "couldn't read register. Returned %d\n", data); | ||
102 | return data; | ||
103 | } | ||
104 | |||
105 | buffer[idx++] = data; | ||
106 | } | ||
107 | } | ||
108 | |||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | static int qt2160_get_key_matrix(struct qt2160_data *qt2160) | ||
113 | { | ||
114 | struct i2c_client *client = qt2160->client; | ||
115 | struct input_dev *input = qt2160->input; | ||
116 | u8 regs[6]; | ||
117 | u16 old_matrix, new_matrix; | ||
118 | int ret, i, mask; | ||
119 | |||
120 | dev_dbg(&client->dev, "requesting keys...\n"); | ||
121 | |||
122 | /* | ||
123 | * Read all registers from General Status Register | ||
124 | * to GPIOs register | ||
125 | */ | ||
126 | ret = qt2160_read_block(client, QT2160_CMD_GSTAT, regs, 6); | ||
127 | if (ret) { | ||
128 | dev_err(&client->dev, | ||
129 | "could not perform chip read.\n"); | ||
130 | return ret; | ||
131 | } | ||
132 | |||
133 | old_matrix = qt2160->key_matrix; | ||
134 | qt2160->key_matrix = new_matrix = (regs[2] << 8) | regs[1]; | ||
135 | |||
136 | mask = 0x01; | ||
137 | for (i = 0; i < 16; ++i, mask <<= 1) { | ||
138 | int keyval = new_matrix & mask; | ||
139 | |||
140 | if ((old_matrix & mask) != keyval) { | ||
141 | input_report_key(input, qt2160->keycodes[i], keyval); | ||
142 | dev_dbg(&client->dev, "key %d %s\n", | ||
143 | i, keyval ? "pressed" : "released"); | ||
144 | } | ||
145 | } | ||
146 | |||
147 | input_sync(input); | ||
148 | |||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | static irqreturn_t qt2160_irq(int irq, void *_qt2160) | ||
153 | { | ||
154 | struct qt2160_data *qt2160 = _qt2160; | ||
155 | unsigned long flags; | ||
156 | |||
157 | spin_lock_irqsave(&qt2160->lock, flags); | ||
158 | |||
159 | __cancel_delayed_work(&qt2160->dwork); | ||
160 | schedule_delayed_work(&qt2160->dwork, 0); | ||
161 | |||
162 | spin_unlock_irqrestore(&qt2160->lock, flags); | ||
163 | |||
164 | return IRQ_HANDLED; | ||
165 | } | ||
166 | |||
167 | static void qt2160_schedule_read(struct qt2160_data *qt2160) | ||
168 | { | ||
169 | spin_lock_irq(&qt2160->lock); | ||
170 | schedule_delayed_work(&qt2160->dwork, QT2160_CYCLE_INTERVAL); | ||
171 | spin_unlock_irq(&qt2160->lock); | ||
172 | } | ||
173 | |||
174 | static void qt2160_worker(struct work_struct *work) | ||
175 | { | ||
176 | struct qt2160_data *qt2160 = | ||
177 | container_of(work, struct qt2160_data, dwork.work); | ||
178 | |||
179 | dev_dbg(&qt2160->client->dev, "worker\n"); | ||
180 | |||
181 | qt2160_get_key_matrix(qt2160); | ||
182 | |||
183 | /* Avoid device lock up by checking every so often */ | ||
184 | qt2160_schedule_read(qt2160); | ||
185 | } | ||
186 | |||
187 | static int __devinit qt2160_read(struct i2c_client *client, u8 reg) | ||
188 | { | ||
189 | int ret; | ||
190 | |||
191 | ret = i2c_smbus_write_byte(client, reg); | ||
192 | if (ret) { | ||
193 | dev_err(&client->dev, | ||
194 | "couldn't send request. Returned %d\n", ret); | ||
195 | return ret; | ||
196 | } | ||
197 | |||
198 | ret = i2c_smbus_read_byte(client); | ||
199 | if (ret < 0) { | ||
200 | dev_err(&client->dev, | ||
201 | "couldn't read register. Returned %d\n", ret); | ||
202 | return ret; | ||
203 | } | ||
204 | |||
205 | return ret; | ||
206 | } | ||
207 | |||
208 | static int __devinit qt2160_write(struct i2c_client *client, u8 reg, u8 data) | ||
209 | { | ||
210 | int error; | ||
211 | |||
212 | error = i2c_smbus_write_byte(client, reg); | ||
213 | if (error) { | ||
214 | dev_err(&client->dev, | ||
215 | "couldn't send request. Returned %d\n", error); | ||
216 | return error; | ||
217 | } | ||
218 | |||
219 | error = i2c_smbus_write_byte(client, data); | ||
220 | if (error) { | ||
221 | dev_err(&client->dev, | ||
222 | "couldn't write data. Returned %d\n", error); | ||
223 | return error; | ||
224 | } | ||
225 | |||
226 | return error; | ||
227 | } | ||
228 | |||
229 | |||
230 | static bool __devinit qt2160_identify(struct i2c_client *client) | ||
231 | { | ||
232 | int id, ver, rev; | ||
233 | |||
234 | /* Read Chid ID to check if chip is valid */ | ||
235 | id = qt2160_read(client, QT2160_CMD_CHIPID); | ||
236 | if (id != QT2160_VALID_CHIPID) { | ||
237 | dev_err(&client->dev, "ID %d not supported\n", id); | ||
238 | return false; | ||
239 | } | ||
240 | |||
241 | /* Read chip firmware version */ | ||
242 | ver = qt2160_read(client, QT2160_CMD_CODEVER); | ||
243 | if (ver < 0) { | ||
244 | dev_err(&client->dev, "could not get firmware version\n"); | ||
245 | return false; | ||
246 | } | ||
247 | |||
248 | /* Read chip firmware revision */ | ||
249 | rev = qt2160_read(client, QT2160_CMD_SUBVER); | ||
250 | if (rev < 0) { | ||
251 | dev_err(&client->dev, "could not get firmware revision\n"); | ||
252 | return false; | ||
253 | } | ||
254 | |||
255 | dev_info(&client->dev, "AT42QT2160 firmware version %d.%d.%d\n", | ||
256 | ver >> 4, ver & 0xf, rev); | ||
257 | |||
258 | return true; | ||
259 | } | ||
260 | |||
261 | static int __devinit qt2160_probe(struct i2c_client *client, | ||
262 | const struct i2c_device_id *id) | ||
263 | { | ||
264 | struct qt2160_data *qt2160; | ||
265 | struct input_dev *input; | ||
266 | int i; | ||
267 | int error; | ||
268 | |||
269 | /* Check functionality */ | ||
270 | error = i2c_check_functionality(client->adapter, | ||
271 | I2C_FUNC_SMBUS_BYTE); | ||
272 | if (!error) { | ||
273 | dev_err(&client->dev, "%s adapter not supported\n", | ||
274 | dev_driver_string(&client->adapter->dev)); | ||
275 | return -ENODEV; | ||
276 | } | ||
277 | |||
278 | if (!qt2160_identify(client)) | ||
279 | return -ENODEV; | ||
280 | |||
281 | /* Chip is valid and active. Allocate structure */ | ||
282 | qt2160 = kzalloc(sizeof(struct qt2160_data), GFP_KERNEL); | ||
283 | input = input_allocate_device(); | ||
284 | if (!qt2160 || !input) { | ||
285 | dev_err(&client->dev, "insufficient memory\n"); | ||
286 | error = -ENOMEM; | ||
287 | goto err_free_mem; | ||
288 | } | ||
289 | |||
290 | qt2160->client = client; | ||
291 | qt2160->input = input; | ||
292 | INIT_DELAYED_WORK(&qt2160->dwork, qt2160_worker); | ||
293 | spin_lock_init(&qt2160->lock); | ||
294 | |||
295 | input->name = "AT42QT2160 Touch Sense Keyboard"; | ||
296 | input->id.bustype = BUS_I2C; | ||
297 | |||
298 | input->keycode = qt2160->keycodes; | ||
299 | input->keycodesize = sizeof(qt2160->keycodes[0]); | ||
300 | input->keycodemax = ARRAY_SIZE(qt2160_key2code); | ||
301 | |||
302 | __set_bit(EV_KEY, input->evbit); | ||
303 | __clear_bit(EV_REP, input->evbit); | ||
304 | for (i = 0; i < ARRAY_SIZE(qt2160_key2code); i++) { | ||
305 | qt2160->keycodes[i] = qt2160_key2code[i]; | ||
306 | __set_bit(qt2160_key2code[i], input->keybit); | ||
307 | } | ||
308 | __clear_bit(KEY_RESERVED, input->keybit); | ||
309 | |||
310 | /* Calibrate device */ | ||
311 | error = qt2160_write(client, QT2160_CMD_CALIBRATE, 1); | ||
312 | if (error) { | ||
313 | dev_err(&client->dev, "failed to calibrate device\n"); | ||
314 | goto err_free_mem; | ||
315 | } | ||
316 | |||
317 | if (client->irq) { | ||
318 | error = request_irq(client->irq, qt2160_irq, | ||
319 | IRQF_TRIGGER_FALLING, "qt2160", qt2160); | ||
320 | if (error) { | ||
321 | dev_err(&client->dev, | ||
322 | "failed to allocate irq %d\n", client->irq); | ||
323 | goto err_free_mem; | ||
324 | } | ||
325 | } | ||
326 | |||
327 | error = input_register_device(qt2160->input); | ||
328 | if (error) { | ||
329 | dev_err(&client->dev, | ||
330 | "Failed to register input device\n"); | ||
331 | goto err_free_irq; | ||
332 | } | ||
333 | |||
334 | i2c_set_clientdata(client, qt2160); | ||
335 | qt2160_schedule_read(qt2160); | ||
336 | |||
337 | return 0; | ||
338 | |||
339 | err_free_irq: | ||
340 | if (client->irq) | ||
341 | free_irq(client->irq, qt2160); | ||
342 | err_free_mem: | ||
343 | input_free_device(input); | ||
344 | kfree(qt2160); | ||
345 | return error; | ||
346 | } | ||
347 | |||
348 | static int __devexit qt2160_remove(struct i2c_client *client) | ||
349 | { | ||
350 | struct qt2160_data *qt2160 = i2c_get_clientdata(client); | ||
351 | |||
352 | /* Release IRQ so no queue will be scheduled */ | ||
353 | if (client->irq) | ||
354 | free_irq(client->irq, qt2160); | ||
355 | |||
356 | cancel_delayed_work_sync(&qt2160->dwork); | ||
357 | |||
358 | input_unregister_device(qt2160->input); | ||
359 | kfree(qt2160); | ||
360 | |||
361 | i2c_set_clientdata(client, NULL); | ||
362 | return 0; | ||
363 | } | ||
364 | |||
365 | static struct i2c_device_id qt2160_idtable[] = { | ||
366 | { "qt2160", 0, }, | ||
367 | { } | ||
368 | }; | ||
369 | |||
370 | MODULE_DEVICE_TABLE(i2c, qt2160_idtable); | ||
371 | |||
372 | static struct i2c_driver qt2160_driver = { | ||
373 | .driver = { | ||
374 | .name = "qt2160", | ||
375 | .owner = THIS_MODULE, | ||
376 | }, | ||
377 | |||
378 | .id_table = qt2160_idtable, | ||
379 | .probe = qt2160_probe, | ||
380 | .remove = __devexit_p(qt2160_remove), | ||
381 | }; | ||
382 | |||
383 | static int __init qt2160_init(void) | ||
384 | { | ||
385 | return i2c_add_driver(&qt2160_driver); | ||
386 | } | ||
387 | module_init(qt2160_init); | ||
388 | |||
389 | static void __exit qt2160_cleanup(void) | ||
390 | { | ||
391 | i2c_del_driver(&qt2160_driver); | ||
392 | } | ||
393 | module_exit(qt2160_cleanup); | ||
394 | |||
395 | MODULE_AUTHOR("Raphael Derosso Pereira <raphaelpereira@gmail.com>"); | ||
396 | MODULE_DESCRIPTION("Driver for AT42QT2160 Touch Sensor"); | ||
397 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/misc/dm355evm_keys.c b/drivers/input/misc/dm355evm_keys.c index 0918acae584a..f2b67dc81d80 100644 --- a/drivers/input/misc/dm355evm_keys.c +++ b/drivers/input/misc/dm355evm_keys.c | |||
@@ -96,7 +96,13 @@ static struct { | |||
96 | { 0x3169, KEY_PAUSE, }, | 96 | { 0x3169, KEY_PAUSE, }, |
97 | }; | 97 | }; |
98 | 98 | ||
99 | /* runs in an IRQ thread -- can (and will!) sleep */ | 99 | /* |
100 | * Because we communicate with the MSP430 using I2C, and all I2C calls | ||
101 | * in Linux sleep, we use a threaded IRQ handler. The IRQ itself is | ||
102 | * active low, but we go through the GPIO controller so we can trigger | ||
103 | * on falling edges and not worry about enabling/disabling the IRQ in | ||
104 | * the keypress handling path. | ||
105 | */ | ||
100 | static irqreturn_t dm355evm_keys_irq(int irq, void *_keys) | 106 | static irqreturn_t dm355evm_keys_irq(int irq, void *_keys) |
101 | { | 107 | { |
102 | struct dm355evm_keys *keys = _keys; | 108 | struct dm355evm_keys *keys = _keys; |
@@ -171,18 +177,6 @@ static irqreturn_t dm355evm_keys_irq(int irq, void *_keys) | |||
171 | return IRQ_HANDLED; | 177 | return IRQ_HANDLED; |
172 | } | 178 | } |
173 | 179 | ||
174 | /* | ||
175 | * Because we communicate with the MSP430 using I2C, and all I2C calls | ||
176 | * in Linux sleep, we use a threaded IRQ handler. The IRQ itself is | ||
177 | * active low, but we go through the GPIO controller so we can trigger | ||
178 | * on falling edges and not worry about enabling/disabling the IRQ in | ||
179 | * the keypress handling path. | ||
180 | */ | ||
181 | static irqreturn_t dm355evm_keys_hardirq(int irq, void *_keys) | ||
182 | { | ||
183 | return IRQ_WAKE_THREAD; | ||
184 | } | ||
185 | |||
186 | static int dm355evm_setkeycode(struct input_dev *dev, int index, int keycode) | 180 | static int dm355evm_setkeycode(struct input_dev *dev, int index, int keycode) |
187 | { | 181 | { |
188 | u16 old_keycode; | 182 | u16 old_keycode; |
@@ -257,10 +251,8 @@ static int __devinit dm355evm_keys_probe(struct platform_device *pdev) | |||
257 | 251 | ||
258 | /* REVISIT: flush the event queue? */ | 252 | /* REVISIT: flush the event queue? */ |
259 | 253 | ||
260 | status = request_threaded_irq(keys->irq, | 254 | status = request_threaded_irq(keys->irq, NULL, dm355evm_keys_irq, |
261 | dm355evm_keys_hardirq, dm355evm_keys_irq, | 255 | IRQF_TRIGGER_FALLING, dev_name(&pdev->dev), keys); |
262 | IRQF_TRIGGER_FALLING, | ||
263 | dev_name(&pdev->dev), keys); | ||
264 | if (status < 0) | 256 | if (status < 0) |
265 | goto fail1; | 257 | goto fail1; |
266 | 258 | ||
diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c index 84e2fc04d11b..f84cbd97c884 100644 --- a/drivers/input/mouse/sentelic.c +++ b/drivers/input/mouse/sentelic.c | |||
@@ -92,7 +92,8 @@ static int fsp_reg_read(struct psmouse *psmouse, int reg_addr, int *reg_val) | |||
92 | */ | 92 | */ |
93 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE); | 93 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE); |
94 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); | 94 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); |
95 | mutex_lock(&ps2dev->cmd_mutex); | 95 | |
96 | ps2_begin_command(ps2dev); | ||
96 | 97 | ||
97 | if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) | 98 | if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) |
98 | goto out; | 99 | goto out; |
@@ -126,7 +127,7 @@ static int fsp_reg_read(struct psmouse *psmouse, int reg_addr, int *reg_val) | |||
126 | rc = 0; | 127 | rc = 0; |
127 | 128 | ||
128 | out: | 129 | out: |
129 | mutex_unlock(&ps2dev->cmd_mutex); | 130 | ps2_end_command(ps2dev); |
130 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE); | 131 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE); |
131 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); | 132 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); |
132 | dev_dbg(&ps2dev->serio->dev, "READ REG: 0x%02x is 0x%02x (rc = %d)\n", | 133 | dev_dbg(&ps2dev->serio->dev, "READ REG: 0x%02x is 0x%02x (rc = %d)\n", |
@@ -140,7 +141,7 @@ static int fsp_reg_write(struct psmouse *psmouse, int reg_addr, int reg_val) | |||
140 | unsigned char v; | 141 | unsigned char v; |
141 | int rc = -1; | 142 | int rc = -1; |
142 | 143 | ||
143 | mutex_lock(&ps2dev->cmd_mutex); | 144 | ps2_begin_command(ps2dev); |
144 | 145 | ||
145 | if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) | 146 | if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) |
146 | goto out; | 147 | goto out; |
@@ -179,7 +180,7 @@ static int fsp_reg_write(struct psmouse *psmouse, int reg_addr, int reg_val) | |||
179 | rc = 0; | 180 | rc = 0; |
180 | 181 | ||
181 | out: | 182 | out: |
182 | mutex_unlock(&ps2dev->cmd_mutex); | 183 | ps2_end_command(ps2dev); |
183 | dev_dbg(&ps2dev->serio->dev, "WRITE REG: 0x%02x to 0x%02x (rc = %d)\n", | 184 | dev_dbg(&ps2dev->serio->dev, "WRITE REG: 0x%02x to 0x%02x (rc = %d)\n", |
184 | reg_addr, reg_val, rc); | 185 | reg_addr, reg_val, rc); |
185 | return rc; | 186 | return rc; |
@@ -214,7 +215,8 @@ static int fsp_page_reg_read(struct psmouse *psmouse, int *reg_val) | |||
214 | 215 | ||
215 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE); | 216 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE); |
216 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); | 217 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); |
217 | mutex_lock(&ps2dev->cmd_mutex); | 218 | |
219 | ps2_begin_command(ps2dev); | ||
218 | 220 | ||
219 | if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) | 221 | if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) |
220 | goto out; | 222 | goto out; |
@@ -236,7 +238,7 @@ static int fsp_page_reg_read(struct psmouse *psmouse, int *reg_val) | |||
236 | rc = 0; | 238 | rc = 0; |
237 | 239 | ||
238 | out: | 240 | out: |
239 | mutex_unlock(&ps2dev->cmd_mutex); | 241 | ps2_end_command(ps2dev); |
240 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE); | 242 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE); |
241 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); | 243 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); |
242 | dev_dbg(&ps2dev->serio->dev, "READ PAGE REG: 0x%02x (rc = %d)\n", | 244 | dev_dbg(&ps2dev->serio->dev, "READ PAGE REG: 0x%02x (rc = %d)\n", |
@@ -250,7 +252,7 @@ static int fsp_page_reg_write(struct psmouse *psmouse, int reg_val) | |||
250 | unsigned char v; | 252 | unsigned char v; |
251 | int rc = -1; | 253 | int rc = -1; |
252 | 254 | ||
253 | mutex_lock(&ps2dev->cmd_mutex); | 255 | ps2_begin_command(ps2dev); |
254 | 256 | ||
255 | if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) | 257 | if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) |
256 | goto out; | 258 | goto out; |
@@ -275,7 +277,7 @@ static int fsp_page_reg_write(struct psmouse *psmouse, int reg_val) | |||
275 | rc = 0; | 277 | rc = 0; |
276 | 278 | ||
277 | out: | 279 | out: |
278 | mutex_unlock(&ps2dev->cmd_mutex); | 280 | ps2_end_command(ps2dev); |
279 | dev_dbg(&ps2dev->serio->dev, "WRITE PAGE REG: to 0x%02x (rc = %d)\n", | 281 | dev_dbg(&ps2dev->serio->dev, "WRITE PAGE REG: to 0x%02x (rc = %d)\n", |
280 | reg_val, rc); | 282 | reg_val, rc); |
281 | return rc; | 283 | return rc; |
diff --git a/drivers/input/mouse/synaptics_i2c.c b/drivers/input/mouse/synaptics_i2c.c index eac9fdde7ee9..7283c78044af 100644 --- a/drivers/input/mouse/synaptics_i2c.c +++ b/drivers/input/mouse/synaptics_i2c.c | |||
@@ -203,7 +203,7 @@ MODULE_PARM_DESC(no_filter, "No Filter. Default = 0 (off)"); | |||
203 | * and the irq configuration should be set to Falling Edge Trigger | 203 | * and the irq configuration should be set to Falling Edge Trigger |
204 | */ | 204 | */ |
205 | /* Control IRQ / Polling option */ | 205 | /* Control IRQ / Polling option */ |
206 | static int polling_req; | 206 | static bool polling_req; |
207 | module_param(polling_req, bool, 0444); | 207 | module_param(polling_req, bool, 0444); |
208 | MODULE_PARM_DESC(polling_req, "Request Polling. Default = 0 (use irq)"); | 208 | MODULE_PARM_DESC(polling_req, "Request Polling. Default = 0 (use irq)"); |
209 | 209 | ||
@@ -217,6 +217,7 @@ struct synaptics_i2c { | |||
217 | struct i2c_client *client; | 217 | struct i2c_client *client; |
218 | struct input_dev *input; | 218 | struct input_dev *input; |
219 | struct delayed_work dwork; | 219 | struct delayed_work dwork; |
220 | spinlock_t lock; | ||
220 | int no_data_count; | 221 | int no_data_count; |
221 | int no_decel_param; | 222 | int no_decel_param; |
222 | int reduce_report_param; | 223 | int reduce_report_param; |
@@ -366,17 +367,28 @@ static bool synaptics_i2c_get_input(struct synaptics_i2c *touch) | |||
366 | return xy_delta || gesture; | 367 | return xy_delta || gesture; |
367 | } | 368 | } |
368 | 369 | ||
369 | static irqreturn_t synaptics_i2c_irq(int irq, void *dev_id) | 370 | static void synaptics_i2c_reschedule_work(struct synaptics_i2c *touch, |
371 | unsigned long delay) | ||
370 | { | 372 | { |
371 | struct synaptics_i2c *touch = dev_id; | 373 | unsigned long flags; |
374 | |||
375 | spin_lock_irqsave(&touch->lock, flags); | ||
372 | 376 | ||
373 | /* | 377 | /* |
374 | * We want to have the work run immediately but it might have | 378 | * If work is already scheduled then subsequent schedules will not |
375 | * already been scheduled with a delay, that's why we have to | 379 | * change the scheduled time that's why we have to cancel it first. |
376 | * cancel it first. | ||
377 | */ | 380 | */ |
378 | cancel_delayed_work(&touch->dwork); | 381 | __cancel_delayed_work(&touch->dwork); |
379 | schedule_delayed_work(&touch->dwork, 0); | 382 | schedule_delayed_work(&touch->dwork, delay); |
383 | |||
384 | spin_unlock_irqrestore(&touch->lock, flags); | ||
385 | } | ||
386 | |||
387 | static irqreturn_t synaptics_i2c_irq(int irq, void *dev_id) | ||
388 | { | ||
389 | struct synaptics_i2c *touch = dev_id; | ||
390 | |||
391 | synaptics_i2c_reschedule_work(touch, 0); | ||
380 | 392 | ||
381 | return IRQ_HANDLED; | 393 | return IRQ_HANDLED; |
382 | } | 394 | } |
@@ -452,7 +464,7 @@ static void synaptics_i2c_work_handler(struct work_struct *work) | |||
452 | * We poll the device once in THREAD_IRQ_SLEEP_SECS and | 464 | * We poll the device once in THREAD_IRQ_SLEEP_SECS and |
453 | * if error is detected, we try to reset and reconfigure the touchpad. | 465 | * if error is detected, we try to reset and reconfigure the touchpad. |
454 | */ | 466 | */ |
455 | schedule_delayed_work(&touch->dwork, delay); | 467 | synaptics_i2c_reschedule_work(touch, delay); |
456 | } | 468 | } |
457 | 469 | ||
458 | static int synaptics_i2c_open(struct input_dev *input) | 470 | static int synaptics_i2c_open(struct input_dev *input) |
@@ -465,8 +477,8 @@ static int synaptics_i2c_open(struct input_dev *input) | |||
465 | return ret; | 477 | return ret; |
466 | 478 | ||
467 | if (polling_req) | 479 | if (polling_req) |
468 | schedule_delayed_work(&touch->dwork, | 480 | synaptics_i2c_reschedule_work(touch, |
469 | msecs_to_jiffies(NO_DATA_SLEEP_MSECS)); | 481 | msecs_to_jiffies(NO_DATA_SLEEP_MSECS)); |
470 | 482 | ||
471 | return 0; | 483 | return 0; |
472 | } | 484 | } |
@@ -521,6 +533,7 @@ struct synaptics_i2c *synaptics_i2c_touch_create(struct i2c_client *client) | |||
521 | touch->scan_rate_param = scan_rate; | 533 | touch->scan_rate_param = scan_rate; |
522 | set_scan_rate(touch, scan_rate); | 534 | set_scan_rate(touch, scan_rate); |
523 | INIT_DELAYED_WORK(&touch->dwork, synaptics_i2c_work_handler); | 535 | INIT_DELAYED_WORK(&touch->dwork, synaptics_i2c_work_handler); |
536 | spin_lock_init(&touch->lock); | ||
524 | 537 | ||
525 | return touch; | 538 | return touch; |
526 | } | 539 | } |
@@ -535,14 +548,12 @@ static int __devinit synaptics_i2c_probe(struct i2c_client *client, | |||
535 | if (!touch) | 548 | if (!touch) |
536 | return -ENOMEM; | 549 | return -ENOMEM; |
537 | 550 | ||
538 | i2c_set_clientdata(client, touch); | ||
539 | |||
540 | ret = synaptics_i2c_reset_config(client); | 551 | ret = synaptics_i2c_reset_config(client); |
541 | if (ret) | 552 | if (ret) |
542 | goto err_mem_free; | 553 | goto err_mem_free; |
543 | 554 | ||
544 | if (client->irq < 1) | 555 | if (client->irq < 1) |
545 | polling_req = 1; | 556 | polling_req = true; |
546 | 557 | ||
547 | touch->input = input_allocate_device(); | 558 | touch->input = input_allocate_device(); |
548 | if (!touch->input) { | 559 | if (!touch->input) { |
@@ -563,7 +574,7 @@ static int __devinit synaptics_i2c_probe(struct i2c_client *client, | |||
563 | dev_warn(&touch->client->dev, | 574 | dev_warn(&touch->client->dev, |
564 | "IRQ request failed: %d, " | 575 | "IRQ request failed: %d, " |
565 | "falling back to polling\n", ret); | 576 | "falling back to polling\n", ret); |
566 | polling_req = 1; | 577 | polling_req = true; |
567 | synaptics_i2c_reg_set(touch->client, | 578 | synaptics_i2c_reg_set(touch->client, |
568 | INTERRUPT_EN_REG, 0); | 579 | INTERRUPT_EN_REG, 0); |
569 | } | 580 | } |
@@ -580,12 +591,14 @@ static int __devinit synaptics_i2c_probe(struct i2c_client *client, | |||
580 | "Input device register failed: %d\n", ret); | 591 | "Input device register failed: %d\n", ret); |
581 | goto err_input_free; | 592 | goto err_input_free; |
582 | } | 593 | } |
594 | |||
595 | i2c_set_clientdata(client, touch); | ||
596 | |||
583 | return 0; | 597 | return 0; |
584 | 598 | ||
585 | err_input_free: | 599 | err_input_free: |
586 | input_free_device(touch->input); | 600 | input_free_device(touch->input); |
587 | err_mem_free: | 601 | err_mem_free: |
588 | i2c_set_clientdata(client, NULL); | ||
589 | kfree(touch); | 602 | kfree(touch); |
590 | 603 | ||
591 | return ret; | 604 | return ret; |
@@ -596,7 +609,7 @@ static int __devexit synaptics_i2c_remove(struct i2c_client *client) | |||
596 | struct synaptics_i2c *touch = i2c_get_clientdata(client); | 609 | struct synaptics_i2c *touch = i2c_get_clientdata(client); |
597 | 610 | ||
598 | if (!polling_req) | 611 | if (!polling_req) |
599 | free_irq(touch->client->irq, touch); | 612 | free_irq(client->irq, touch); |
600 | 613 | ||
601 | input_unregister_device(touch->input); | 614 | input_unregister_device(touch->input); |
602 | i2c_set_clientdata(client, NULL); | 615 | i2c_set_clientdata(client, NULL); |
@@ -627,8 +640,8 @@ static int synaptics_i2c_resume(struct i2c_client *client) | |||
627 | if (ret) | 640 | if (ret) |
628 | return ret; | 641 | return ret; |
629 | 642 | ||
630 | schedule_delayed_work(&touch->dwork, | 643 | synaptics_i2c_reschedule_work(touch, |
631 | msecs_to_jiffies(NO_DATA_SLEEP_MSECS)); | 644 | msecs_to_jiffies(NO_DATA_SLEEP_MSECS)); |
632 | 645 | ||
633 | return 0; | 646 | return 0; |
634 | } | 647 | } |
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index eb3ff94af58c..bc56e52b945f 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -87,8 +87,22 @@ static bool i8042_bypass_aux_irq_test; | |||
87 | 87 | ||
88 | #include "i8042.h" | 88 | #include "i8042.h" |
89 | 89 | ||
90 | /* | ||
91 | * i8042_lock protects serialization between i8042_command and | ||
92 | * the interrupt handler. | ||
93 | */ | ||
90 | static DEFINE_SPINLOCK(i8042_lock); | 94 | static DEFINE_SPINLOCK(i8042_lock); |
91 | 95 | ||
96 | /* | ||
97 | * Writers to AUX and KBD ports as well as users issuing i8042_command | ||
98 | * directly should acquire i8042_mutex (by means of calling | ||
99 | * i8042_lock_chip() and i8042_unlock_ship() helpers) to ensure that | ||
100 | * they do not disturb each other (unfortunately in many i8042 | ||
101 | * implementations write to one of the ports will immediately abort | ||
102 | * command that is being processed by another port). | ||
103 | */ | ||
104 | static DEFINE_MUTEX(i8042_mutex); | ||
105 | |||
92 | struct i8042_port { | 106 | struct i8042_port { |
93 | struct serio *serio; | 107 | struct serio *serio; |
94 | int irq; | 108 | int irq; |
@@ -113,6 +127,18 @@ static struct platform_device *i8042_platform_device; | |||
113 | 127 | ||
114 | static irqreturn_t i8042_interrupt(int irq, void *dev_id); | 128 | static irqreturn_t i8042_interrupt(int irq, void *dev_id); |
115 | 129 | ||
130 | void i8042_lock_chip(void) | ||
131 | { | ||
132 | mutex_lock(&i8042_mutex); | ||
133 | } | ||
134 | EXPORT_SYMBOL(i8042_lock_chip); | ||
135 | |||
136 | void i8042_unlock_chip(void) | ||
137 | { | ||
138 | mutex_unlock(&i8042_mutex); | ||
139 | } | ||
140 | EXPORT_SYMBOL(i8042_unlock_chip); | ||
141 | |||
116 | /* | 142 | /* |
117 | * The i8042_wait_read() and i8042_wait_write functions wait for the i8042 to | 143 | * The i8042_wait_read() and i8042_wait_write functions wait for the i8042 to |
118 | * be ready for reading values from it / writing values to it. | 144 | * be ready for reading values from it / writing values to it. |
@@ -1161,6 +1187,21 @@ static void __devexit i8042_unregister_ports(void) | |||
1161 | } | 1187 | } |
1162 | } | 1188 | } |
1163 | 1189 | ||
1190 | /* | ||
1191 | * Checks whether port belongs to i8042 controller. | ||
1192 | */ | ||
1193 | bool i8042_check_port_owner(const struct serio *port) | ||
1194 | { | ||
1195 | int i; | ||
1196 | |||
1197 | for (i = 0; i < I8042_NUM_PORTS; i++) | ||
1198 | if (i8042_ports[i].serio == port) | ||
1199 | return true; | ||
1200 | |||
1201 | return false; | ||
1202 | } | ||
1203 | EXPORT_SYMBOL(i8042_check_port_owner); | ||
1204 | |||
1164 | static void i8042_free_irqs(void) | 1205 | static void i8042_free_irqs(void) |
1165 | { | 1206 | { |
1166 | if (i8042_aux_irq_registered) | 1207 | if (i8042_aux_irq_registered) |
diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c index 3a95b508bf27..769ba65a585a 100644 --- a/drivers/input/serio/libps2.c +++ b/drivers/input/serio/libps2.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
18 | #include <linux/input.h> | 18 | #include <linux/input.h> |
19 | #include <linux/serio.h> | 19 | #include <linux/serio.h> |
20 | #include <linux/i8042.h> | ||
20 | #include <linux/init.h> | 21 | #include <linux/init.h> |
21 | #include <linux/libps2.h> | 22 | #include <linux/libps2.h> |
22 | 23 | ||
@@ -54,6 +55,24 @@ int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout) | |||
54 | } | 55 | } |
55 | EXPORT_SYMBOL(ps2_sendbyte); | 56 | EXPORT_SYMBOL(ps2_sendbyte); |
56 | 57 | ||
58 | void ps2_begin_command(struct ps2dev *ps2dev) | ||
59 | { | ||
60 | mutex_lock(&ps2dev->cmd_mutex); | ||
61 | |||
62 | if (i8042_check_port_owner(ps2dev->serio)) | ||
63 | i8042_lock_chip(); | ||
64 | } | ||
65 | EXPORT_SYMBOL(ps2_begin_command); | ||
66 | |||
67 | void ps2_end_command(struct ps2dev *ps2dev) | ||
68 | { | ||
69 | if (i8042_check_port_owner(ps2dev->serio)) | ||
70 | i8042_unlock_chip(); | ||
71 | |||
72 | mutex_unlock(&ps2dev->cmd_mutex); | ||
73 | } | ||
74 | EXPORT_SYMBOL(ps2_end_command); | ||
75 | |||
57 | /* | 76 | /* |
58 | * ps2_drain() waits for device to transmit requested number of bytes | 77 | * ps2_drain() waits for device to transmit requested number of bytes |
59 | * and discards them. | 78 | * and discards them. |
@@ -66,7 +85,7 @@ void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout) | |||
66 | maxbytes = sizeof(ps2dev->cmdbuf); | 85 | maxbytes = sizeof(ps2dev->cmdbuf); |
67 | } | 86 | } |
68 | 87 | ||
69 | mutex_lock(&ps2dev->cmd_mutex); | 88 | ps2_begin_command(ps2dev); |
70 | 89 | ||
71 | serio_pause_rx(ps2dev->serio); | 90 | serio_pause_rx(ps2dev->serio); |
72 | ps2dev->flags = PS2_FLAG_CMD; | 91 | ps2dev->flags = PS2_FLAG_CMD; |
@@ -76,7 +95,8 @@ void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout) | |||
76 | wait_event_timeout(ps2dev->wait, | 95 | wait_event_timeout(ps2dev->wait, |
77 | !(ps2dev->flags & PS2_FLAG_CMD), | 96 | !(ps2dev->flags & PS2_FLAG_CMD), |
78 | msecs_to_jiffies(timeout)); | 97 | msecs_to_jiffies(timeout)); |
79 | mutex_unlock(&ps2dev->cmd_mutex); | 98 | |
99 | ps2_end_command(ps2dev); | ||
80 | } | 100 | } |
81 | EXPORT_SYMBOL(ps2_drain); | 101 | EXPORT_SYMBOL(ps2_drain); |
82 | 102 | ||
@@ -237,9 +257,9 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) | |||
237 | { | 257 | { |
238 | int rc; | 258 | int rc; |
239 | 259 | ||
240 | mutex_lock(&ps2dev->cmd_mutex); | 260 | ps2_begin_command(ps2dev); |
241 | rc = __ps2_command(ps2dev, param, command); | 261 | rc = __ps2_command(ps2dev, param, command); |
242 | mutex_unlock(&ps2dev->cmd_mutex); | 262 | ps2_end_command(ps2dev); |
243 | 263 | ||
244 | return rc; | 264 | return rc; |
245 | } | 265 | } |
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index ab02d72afbf3..8cc453c85ea7 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
@@ -48,8 +48,8 @@ config TOUCHSCREEN_AD7879_I2C | |||
48 | select TOUCHSCREEN_AD7879 | 48 | select TOUCHSCREEN_AD7879 |
49 | help | 49 | help |
50 | Say Y here if you have a touchscreen interface using the | 50 | Say Y here if you have a touchscreen interface using the |
51 | AD7879-1 controller, and your board-specific initialization | 51 | AD7879-1/AD7889-1 controller, and your board-specific |
52 | code includes that in its table of I2C devices. | 52 | initialization code includes that in its table of I2C devices. |
53 | 53 | ||
54 | If unsure, say N (but it's safe to say "Y"). | 54 | If unsure, say N (but it's safe to say "Y"). |
55 | 55 | ||
@@ -62,7 +62,7 @@ config TOUCHSCREEN_AD7879_SPI | |||
62 | select TOUCHSCREEN_AD7879 | 62 | select TOUCHSCREEN_AD7879 |
63 | help | 63 | help |
64 | Say Y here if you have a touchscreen interface using the | 64 | Say Y here if you have a touchscreen interface using the |
65 | AD7879 controller, and your board-specific initialization | 65 | AD7879/AD7889 controller, and your board-specific initialization |
66 | code includes that in its table of SPI devices. | 66 | code includes that in its table of SPI devices. |
67 | 67 | ||
68 | If unsure, say N (but it's safe to say "Y"). | 68 | If unsure, say N (but it's safe to say "Y"). |
@@ -169,6 +169,17 @@ config TOUCHSCREEN_WACOM_W8001 | |||
169 | To compile this driver as a module, choose M here: the | 169 | To compile this driver as a module, choose M here: the |
170 | module will be called wacom_w8001. | 170 | module will be called wacom_w8001. |
171 | 171 | ||
172 | config TOUCHSCREEN_MCS5000 | ||
173 | tristate "MELFAS MCS-5000 touchscreen" | ||
174 | depends on I2C | ||
175 | help | ||
176 | Say Y here if you have the MELFAS MCS-5000 touchscreen controller | ||
177 | chip in your system. | ||
178 | |||
179 | If unsure, say N. | ||
180 | |||
181 | To compile this driver as a module, choose M here: the | ||
182 | module will be called mcs5000_ts. | ||
172 | 183 | ||
173 | config TOUCHSCREEN_MTOUCH | 184 | config TOUCHSCREEN_MTOUCH |
174 | tristate "MicroTouch serial touchscreens" | 185 | tristate "MicroTouch serial touchscreens" |
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 4599bf7ad819..15fa62cffc77 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile | |||
@@ -17,6 +17,7 @@ obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o | |||
17 | obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o | 17 | obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o |
18 | obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o | 18 | obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o |
19 | obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o | 19 | obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o |
20 | obj-$(CONFIG_TOUCHSCREEN_MCS5000) += mcs5000_ts.o | ||
20 | obj-$(CONFIG_TOUCHSCREEN_MIGOR) += migor_ts.o | 21 | obj-$(CONFIG_TOUCHSCREEN_MIGOR) += migor_ts.o |
21 | obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o | 22 | obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o |
22 | obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o | 23 | obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o |
diff --git a/drivers/input/touchscreen/ad7879.c b/drivers/input/touchscreen/ad7879.c index 19b4db7e974d..f06332c9e21b 100644 --- a/drivers/input/touchscreen/ad7879.c +++ b/drivers/input/touchscreen/ad7879.c | |||
@@ -1,7 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2008 Michael Hennerich, Analog Devices Inc. | 2 | * Copyright (C) 2008-2009 Michael Hennerich, Analog Devices Inc. |
3 | * | 3 | * |
4 | * Description: AD7879 based touchscreen, and GPIO driver (I2C/SPI Interface) | 4 | * Description: AD7879/AD7889 based touchscreen, and GPIO driver |
5 | * (I2C/SPI Interface) | ||
5 | * | 6 | * |
6 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | 7 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ |
7 | * | 8 | * |
@@ -747,6 +748,7 @@ static int __devexit ad7879_remove(struct i2c_client *client) | |||
747 | 748 | ||
748 | static const struct i2c_device_id ad7879_id[] = { | 749 | static const struct i2c_device_id ad7879_id[] = { |
749 | { "ad7879", 0 }, | 750 | { "ad7879", 0 }, |
751 | { "ad7889", 0 }, | ||
750 | { } | 752 | { } |
751 | }; | 753 | }; |
752 | MODULE_DEVICE_TABLE(i2c, ad7879_id); | 754 | MODULE_DEVICE_TABLE(i2c, ad7879_id); |
diff --git a/drivers/input/touchscreen/mcs5000_ts.c b/drivers/input/touchscreen/mcs5000_ts.c new file mode 100644 index 000000000000..4c28b89757f9 --- /dev/null +++ b/drivers/input/touchscreen/mcs5000_ts.c | |||
@@ -0,0 +1,318 @@ | |||
1 | /* | ||
2 | * mcs5000_ts.c - Touchscreen driver for MELFAS MCS-5000 controller | ||
3 | * | ||
4 | * Copyright (C) 2009 Samsung Electronics Co.Ltd | ||
5 | * Author: Joonyoung Shim <jy0922.shim@samsung.com> | ||
6 | * | ||
7 | * Based on wm97xx-core.c | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
12 | * option) any later version. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/module.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/i2c.h> | ||
19 | #include <linux/i2c/mcs5000_ts.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/input.h> | ||
22 | #include <linux/irq.h> | ||
23 | |||
24 | /* Registers */ | ||
25 | #define MCS5000_TS_STATUS 0x00 | ||
26 | #define STATUS_OFFSET 0 | ||
27 | #define STATUS_NO (0 << STATUS_OFFSET) | ||
28 | #define STATUS_INIT (1 << STATUS_OFFSET) | ||
29 | #define STATUS_SENSING (2 << STATUS_OFFSET) | ||
30 | #define STATUS_COORD (3 << STATUS_OFFSET) | ||
31 | #define STATUS_GESTURE (4 << STATUS_OFFSET) | ||
32 | #define ERROR_OFFSET 4 | ||
33 | #define ERROR_NO (0 << ERROR_OFFSET) | ||
34 | #define ERROR_POWER_ON_RESET (1 << ERROR_OFFSET) | ||
35 | #define ERROR_INT_RESET (2 << ERROR_OFFSET) | ||
36 | #define ERROR_EXT_RESET (3 << ERROR_OFFSET) | ||
37 | #define ERROR_INVALID_REG_ADDRESS (8 << ERROR_OFFSET) | ||
38 | #define ERROR_INVALID_REG_VALUE (9 << ERROR_OFFSET) | ||
39 | |||
40 | #define MCS5000_TS_OP_MODE 0x01 | ||
41 | #define RESET_OFFSET 0 | ||
42 | #define RESET_NO (0 << RESET_OFFSET) | ||
43 | #define RESET_EXT_SOFT (1 << RESET_OFFSET) | ||
44 | #define OP_MODE_OFFSET 1 | ||
45 | #define OP_MODE_SLEEP (0 << OP_MODE_OFFSET) | ||
46 | #define OP_MODE_ACTIVE (1 << OP_MODE_OFFSET) | ||
47 | #define GESTURE_OFFSET 4 | ||
48 | #define GESTURE_DISABLE (0 << GESTURE_OFFSET) | ||
49 | #define GESTURE_ENABLE (1 << GESTURE_OFFSET) | ||
50 | #define PROXIMITY_OFFSET 5 | ||
51 | #define PROXIMITY_DISABLE (0 << PROXIMITY_OFFSET) | ||
52 | #define PROXIMITY_ENABLE (1 << PROXIMITY_OFFSET) | ||
53 | #define SCAN_MODE_OFFSET 6 | ||
54 | #define SCAN_MODE_INTERRUPT (0 << SCAN_MODE_OFFSET) | ||
55 | #define SCAN_MODE_POLLING (1 << SCAN_MODE_OFFSET) | ||
56 | #define REPORT_RATE_OFFSET 7 | ||
57 | #define REPORT_RATE_40 (0 << REPORT_RATE_OFFSET) | ||
58 | #define REPORT_RATE_80 (1 << REPORT_RATE_OFFSET) | ||
59 | |||
60 | #define MCS5000_TS_SENS_CTL 0x02 | ||
61 | #define MCS5000_TS_FILTER_CTL 0x03 | ||
62 | #define PRI_FILTER_OFFSET 0 | ||
63 | #define SEC_FILTER_OFFSET 4 | ||
64 | |||
65 | #define MCS5000_TS_X_SIZE_UPPER 0x08 | ||
66 | #define MCS5000_TS_X_SIZE_LOWER 0x09 | ||
67 | #define MCS5000_TS_Y_SIZE_UPPER 0x0A | ||
68 | #define MCS5000_TS_Y_SIZE_LOWER 0x0B | ||
69 | |||
70 | #define MCS5000_TS_INPUT_INFO 0x10 | ||
71 | #define INPUT_TYPE_OFFSET 0 | ||
72 | #define INPUT_TYPE_NONTOUCH (0 << INPUT_TYPE_OFFSET) | ||
73 | #define INPUT_TYPE_SINGLE (1 << INPUT_TYPE_OFFSET) | ||
74 | #define INPUT_TYPE_DUAL (2 << INPUT_TYPE_OFFSET) | ||
75 | #define INPUT_TYPE_PALM (3 << INPUT_TYPE_OFFSET) | ||
76 | #define INPUT_TYPE_PROXIMITY (7 << INPUT_TYPE_OFFSET) | ||
77 | #define GESTURE_CODE_OFFSET 3 | ||
78 | #define GESTURE_CODE_NO (0 << GESTURE_CODE_OFFSET) | ||
79 | |||
80 | #define MCS5000_TS_X_POS_UPPER 0x11 | ||
81 | #define MCS5000_TS_X_POS_LOWER 0x12 | ||
82 | #define MCS5000_TS_Y_POS_UPPER 0x13 | ||
83 | #define MCS5000_TS_Y_POS_LOWER 0x14 | ||
84 | #define MCS5000_TS_Z_POS 0x15 | ||
85 | #define MCS5000_TS_WIDTH 0x16 | ||
86 | #define MCS5000_TS_GESTURE_VAL 0x17 | ||
87 | #define MCS5000_TS_MODULE_REV 0x20 | ||
88 | #define MCS5000_TS_FIRMWARE_VER 0x21 | ||
89 | |||
90 | /* Touchscreen absolute values */ | ||
91 | #define MCS5000_MAX_XC 0x3ff | ||
92 | #define MCS5000_MAX_YC 0x3ff | ||
93 | |||
94 | enum mcs5000_ts_read_offset { | ||
95 | READ_INPUT_INFO, | ||
96 | READ_X_POS_UPPER, | ||
97 | READ_X_POS_LOWER, | ||
98 | READ_Y_POS_UPPER, | ||
99 | READ_Y_POS_LOWER, | ||
100 | READ_BLOCK_SIZE, | ||
101 | }; | ||
102 | |||
103 | /* Each client has this additional data */ | ||
104 | struct mcs5000_ts_data { | ||
105 | struct i2c_client *client; | ||
106 | struct input_dev *input_dev; | ||
107 | const struct mcs5000_ts_platform_data *platform_data; | ||
108 | }; | ||
109 | |||
110 | static irqreturn_t mcs5000_ts_interrupt(int irq, void *dev_id) | ||
111 | { | ||
112 | struct mcs5000_ts_data *data = dev_id; | ||
113 | struct i2c_client *client = data->client; | ||
114 | u8 buffer[READ_BLOCK_SIZE]; | ||
115 | int err; | ||
116 | int x; | ||
117 | int y; | ||
118 | |||
119 | err = i2c_smbus_read_i2c_block_data(client, MCS5000_TS_INPUT_INFO, | ||
120 | READ_BLOCK_SIZE, buffer); | ||
121 | if (err < 0) { | ||
122 | dev_err(&client->dev, "%s, err[%d]\n", __func__, err); | ||
123 | goto out; | ||
124 | } | ||
125 | |||
126 | switch (buffer[READ_INPUT_INFO]) { | ||
127 | case INPUT_TYPE_NONTOUCH: | ||
128 | input_report_key(data->input_dev, BTN_TOUCH, 0); | ||
129 | input_sync(data->input_dev); | ||
130 | break; | ||
131 | |||
132 | case INPUT_TYPE_SINGLE: | ||
133 | x = (buffer[READ_X_POS_UPPER] << 8) | buffer[READ_X_POS_LOWER]; | ||
134 | y = (buffer[READ_Y_POS_UPPER] << 8) | buffer[READ_Y_POS_LOWER]; | ||
135 | |||
136 | input_report_key(data->input_dev, BTN_TOUCH, 1); | ||
137 | input_report_abs(data->input_dev, ABS_X, x); | ||
138 | input_report_abs(data->input_dev, ABS_Y, y); | ||
139 | input_sync(data->input_dev); | ||
140 | break; | ||
141 | |||
142 | case INPUT_TYPE_DUAL: | ||
143 | /* TODO */ | ||
144 | break; | ||
145 | |||
146 | case INPUT_TYPE_PALM: | ||
147 | /* TODO */ | ||
148 | break; | ||
149 | |||
150 | case INPUT_TYPE_PROXIMITY: | ||
151 | /* TODO */ | ||
152 | break; | ||
153 | |||
154 | default: | ||
155 | dev_err(&client->dev, "Unknown ts input type %d\n", | ||
156 | buffer[READ_INPUT_INFO]); | ||
157 | break; | ||
158 | } | ||
159 | |||
160 | out: | ||
161 | return IRQ_HANDLED; | ||
162 | } | ||
163 | |||
164 | static void mcs5000_ts_phys_init(struct mcs5000_ts_data *data) | ||
165 | { | ||
166 | const struct mcs5000_ts_platform_data *platform_data = | ||
167 | data->platform_data; | ||
168 | struct i2c_client *client = data->client; | ||
169 | |||
170 | /* Touch reset & sleep mode */ | ||
171 | i2c_smbus_write_byte_data(client, MCS5000_TS_OP_MODE, | ||
172 | RESET_EXT_SOFT | OP_MODE_SLEEP); | ||
173 | |||
174 | /* Touch size */ | ||
175 | i2c_smbus_write_byte_data(client, MCS5000_TS_X_SIZE_UPPER, | ||
176 | platform_data->x_size >> 8); | ||
177 | i2c_smbus_write_byte_data(client, MCS5000_TS_X_SIZE_LOWER, | ||
178 | platform_data->x_size & 0xff); | ||
179 | i2c_smbus_write_byte_data(client, MCS5000_TS_Y_SIZE_UPPER, | ||
180 | platform_data->y_size >> 8); | ||
181 | i2c_smbus_write_byte_data(client, MCS5000_TS_Y_SIZE_LOWER, | ||
182 | platform_data->y_size & 0xff); | ||
183 | |||
184 | /* Touch active mode & 80 report rate */ | ||
185 | i2c_smbus_write_byte_data(data->client, MCS5000_TS_OP_MODE, | ||
186 | OP_MODE_ACTIVE | REPORT_RATE_80); | ||
187 | } | ||
188 | |||
189 | static int __devinit mcs5000_ts_probe(struct i2c_client *client, | ||
190 | const struct i2c_device_id *id) | ||
191 | { | ||
192 | struct mcs5000_ts_data *data; | ||
193 | struct input_dev *input_dev; | ||
194 | int ret; | ||
195 | |||
196 | if (!client->dev.platform_data) | ||
197 | return -EINVAL; | ||
198 | |||
199 | data = kzalloc(sizeof(struct mcs5000_ts_data), GFP_KERNEL); | ||
200 | input_dev = input_allocate_device(); | ||
201 | if (!data || !input_dev) { | ||
202 | dev_err(&client->dev, "Failed to allocate memory\n"); | ||
203 | ret = -ENOMEM; | ||
204 | goto err_free_mem; | ||
205 | } | ||
206 | |||
207 | data->client = client; | ||
208 | data->input_dev = input_dev; | ||
209 | data->platform_data = client->dev.platform_data; | ||
210 | |||
211 | input_dev->name = "MELPAS MCS-5000 Touchscreen"; | ||
212 | input_dev->id.bustype = BUS_I2C; | ||
213 | input_dev->dev.parent = &client->dev; | ||
214 | |||
215 | __set_bit(EV_ABS, input_dev->evbit); | ||
216 | __set_bit(EV_KEY, input_dev->evbit); | ||
217 | __set_bit(BTN_TOUCH, input_dev->keybit); | ||
218 | input_set_abs_params(input_dev, ABS_X, 0, MCS5000_MAX_XC, 0, 0); | ||
219 | input_set_abs_params(input_dev, ABS_Y, 0, MCS5000_MAX_YC, 0, 0); | ||
220 | |||
221 | input_set_drvdata(input_dev, data); | ||
222 | |||
223 | if (data->platform_data->cfg_pin) | ||
224 | data->platform_data->cfg_pin(); | ||
225 | |||
226 | ret = request_threaded_irq(client->irq, NULL, mcs5000_ts_interrupt, | ||
227 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, "mcs5000_ts", data); | ||
228 | |||
229 | if (ret < 0) { | ||
230 | dev_err(&client->dev, "Failed to register interrupt\n"); | ||
231 | goto err_free_mem; | ||
232 | } | ||
233 | |||
234 | ret = input_register_device(data->input_dev); | ||
235 | if (ret < 0) | ||
236 | goto err_free_irq; | ||
237 | |||
238 | mcs5000_ts_phys_init(data); | ||
239 | i2c_set_clientdata(client, data); | ||
240 | |||
241 | return 0; | ||
242 | |||
243 | err_free_irq: | ||
244 | free_irq(client->irq, data); | ||
245 | err_free_mem: | ||
246 | input_free_device(input_dev); | ||
247 | kfree(data); | ||
248 | return ret; | ||
249 | } | ||
250 | |||
251 | static int __devexit mcs5000_ts_remove(struct i2c_client *client) | ||
252 | { | ||
253 | struct mcs5000_ts_data *data = i2c_get_clientdata(client); | ||
254 | |||
255 | free_irq(client->irq, data); | ||
256 | input_unregister_device(data->input_dev); | ||
257 | kfree(data); | ||
258 | i2c_set_clientdata(client, NULL); | ||
259 | |||
260 | return 0; | ||
261 | } | ||
262 | |||
263 | #ifdef CONFIG_PM | ||
264 | static int mcs5000_ts_suspend(struct i2c_client *client, pm_message_t mesg) | ||
265 | { | ||
266 | /* Touch sleep mode */ | ||
267 | i2c_smbus_write_byte_data(client, MCS5000_TS_OP_MODE, OP_MODE_SLEEP); | ||
268 | |||
269 | return 0; | ||
270 | } | ||
271 | |||
272 | static int mcs5000_ts_resume(struct i2c_client *client) | ||
273 | { | ||
274 | struct mcs5000_ts_data *data = i2c_get_clientdata(client); | ||
275 | |||
276 | mcs5000_ts_phys_init(data); | ||
277 | |||
278 | return 0; | ||
279 | } | ||
280 | #else | ||
281 | #define mcs5000_ts_suspend NULL | ||
282 | #define mcs5000_ts_resume NULL | ||
283 | #endif | ||
284 | |||
285 | static const struct i2c_device_id mcs5000_ts_id[] = { | ||
286 | { "mcs5000_ts", 0 }, | ||
287 | { } | ||
288 | }; | ||
289 | MODULE_DEVICE_TABLE(i2c, mcs5000_ts_id); | ||
290 | |||
291 | static struct i2c_driver mcs5000_ts_driver = { | ||
292 | .probe = mcs5000_ts_probe, | ||
293 | .remove = __devexit_p(mcs5000_ts_remove), | ||
294 | .suspend = mcs5000_ts_suspend, | ||
295 | .resume = mcs5000_ts_resume, | ||
296 | .driver = { | ||
297 | .name = "mcs5000_ts", | ||
298 | }, | ||
299 | .id_table = mcs5000_ts_id, | ||
300 | }; | ||
301 | |||
302 | static int __init mcs5000_ts_init(void) | ||
303 | { | ||
304 | return i2c_add_driver(&mcs5000_ts_driver); | ||
305 | } | ||
306 | |||
307 | static void __exit mcs5000_ts_exit(void) | ||
308 | { | ||
309 | i2c_del_driver(&mcs5000_ts_driver); | ||
310 | } | ||
311 | |||
312 | module_init(mcs5000_ts_init); | ||
313 | module_exit(mcs5000_ts_exit); | ||
314 | |||
315 | /* Module information */ | ||
316 | MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); | ||
317 | MODULE_DESCRIPTION("Touchscreen driver for MELFAS MCS-5000 controller"); | ||
318 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/leds/leds-clevo-mail.c b/drivers/leds/leds-clevo-mail.c index 1813c84ea5fc..f2242db54016 100644 --- a/drivers/leds/leds-clevo-mail.c +++ b/drivers/leds/leds-clevo-mail.c | |||
@@ -93,6 +93,8 @@ static struct dmi_system_id __initdata mail_led_whitelist[] = { | |||
93 | static void clevo_mail_led_set(struct led_classdev *led_cdev, | 93 | static void clevo_mail_led_set(struct led_classdev *led_cdev, |
94 | enum led_brightness value) | 94 | enum led_brightness value) |
95 | { | 95 | { |
96 | i8042_lock_chip(); | ||
97 | |||
96 | if (value == LED_OFF) | 98 | if (value == LED_OFF) |
97 | i8042_command(NULL, CLEVO_MAIL_LED_OFF); | 99 | i8042_command(NULL, CLEVO_MAIL_LED_OFF); |
98 | else if (value <= LED_HALF) | 100 | else if (value <= LED_HALF) |
@@ -100,6 +102,8 @@ static void clevo_mail_led_set(struct led_classdev *led_cdev, | |||
100 | else | 102 | else |
101 | i8042_command(NULL, CLEVO_MAIL_LED_BLINK_1HZ); | 103 | i8042_command(NULL, CLEVO_MAIL_LED_BLINK_1HZ); |
102 | 104 | ||
105 | i8042_unlock_chip(); | ||
106 | |||
103 | } | 107 | } |
104 | 108 | ||
105 | static int clevo_mail_led_blink(struct led_classdev *led_cdev, | 109 | static int clevo_mail_led_blink(struct led_classdev *led_cdev, |
@@ -108,6 +112,8 @@ static int clevo_mail_led_blink(struct led_classdev *led_cdev, | |||
108 | { | 112 | { |
109 | int status = -EINVAL; | 113 | int status = -EINVAL; |
110 | 114 | ||
115 | i8042_lock_chip(); | ||
116 | |||
111 | if (*delay_on == 0 /* ms */ && *delay_off == 0 /* ms */) { | 117 | if (*delay_on == 0 /* ms */ && *delay_off == 0 /* ms */) { |
112 | /* Special case: the leds subsystem requested us to | 118 | /* Special case: the leds subsystem requested us to |
113 | * chose one user friendly blinking of the LED, and | 119 | * chose one user friendly blinking of the LED, and |
@@ -135,6 +141,8 @@ static int clevo_mail_led_blink(struct led_classdev *led_cdev, | |||
135 | *delay_on, *delay_off); | 141 | *delay_on, *delay_off); |
136 | } | 142 | } |
137 | 143 | ||
144 | i8042_unlock_chip(); | ||
145 | |||
138 | return status; | 146 | return status; |
139 | } | 147 | } |
140 | 148 | ||
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c index 6ba16abeebdd..e0f91e4ab653 100644 --- a/drivers/media/video/usbvision/usbvision-core.c +++ b/drivers/media/video/usbvision/usbvision-core.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/timer.h> | 28 | #include <linux/timer.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/mm.h> | 30 | #include <linux/mm.h> |
31 | #include <linux/utsname.h> | ||
32 | #include <linux/highmem.h> | 31 | #include <linux/highmem.h> |
33 | #include <linux/vmalloc.h> | 32 | #include <linux/vmalloc.h> |
34 | #include <linux/module.h> | 33 | #include <linux/module.h> |
diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c index f97fd06d5948..c19f51dba2ee 100644 --- a/drivers/media/video/usbvision/usbvision-i2c.c +++ b/drivers/media/video/usbvision/usbvision-i2c.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/utsname.h> | ||
32 | #include <linux/init.h> | 31 | #include <linux/init.h> |
33 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
34 | #include <linux/ioport.h> | 33 | #include <linux/ioport.h> |
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index 90d9b5c0e9a7..a2a50d608a3f 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c | |||
@@ -52,7 +52,6 @@ | |||
52 | #include <linux/slab.h> | 52 | #include <linux/slab.h> |
53 | #include <linux/smp_lock.h> | 53 | #include <linux/smp_lock.h> |
54 | #include <linux/mm.h> | 54 | #include <linux/mm.h> |
55 | #include <linux/utsname.h> | ||
56 | #include <linux/highmem.h> | 55 | #include <linux/highmem.h> |
57 | #include <linux/vmalloc.h> | 56 | #include <linux/vmalloc.h> |
58 | #include <linux/module.h> | 57 | #include <linux/module.h> |
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index fb45f5ee8df1..454970d2d701 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c | |||
@@ -746,7 +746,9 @@ static acpi_status WMID_set_u32(u32 value, u32 cap, struct wmi_interface *iface) | |||
746 | return AE_BAD_PARAMETER; | 746 | return AE_BAD_PARAMETER; |
747 | if (quirks->mailled == 1) { | 747 | if (quirks->mailled == 1) { |
748 | param = value ? 0x92 : 0x93; | 748 | param = value ? 0x92 : 0x93; |
749 | i8042_lock_chip(); | ||
749 | i8042_command(¶m, 0x1059); | 750 | i8042_command(¶m, 0x1059); |
751 | i8042_unlock_chip(); | ||
750 | return 0; | 752 | return 0; |
751 | } | 753 | } |
752 | break; | 754 | break; |
diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index c431198bdbc4..82daa3c1dc9c 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c | |||
@@ -14,7 +14,6 @@ | |||
14 | 14 | ||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/miscdevice.h> | 16 | #include <linux/miscdevice.h> |
17 | #include <linux/utsname.h> | ||
18 | #include <linux/debugfs.h> | 17 | #include <linux/debugfs.h> |
19 | #include <asm/ipl.h> | 18 | #include <asm/ipl.h> |
20 | #include <asm/sclp.h> | 19 | #include <asm/sclp.h> |
diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c index eb6ddfc20857..6cb29d3df575 100644 --- a/drivers/usb/gadget/f_loopback.c +++ b/drivers/usb/gadget/f_loopback.c | |||
@@ -22,7 +22,6 @@ | |||
22 | /* #define VERBOSE_DEBUG */ | 22 | /* #define VERBOSE_DEBUG */ |
23 | 23 | ||
24 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
25 | #include <linux/utsname.h> | ||
26 | #include <linux/device.h> | 25 | #include <linux/device.h> |
27 | 26 | ||
28 | #include "g_zero.h" | 27 | #include "g_zero.h" |
diff --git a/drivers/usb/gadget/f_obex.c b/drivers/usb/gadget/f_obex.c index 46d6266f30ec..b4a3ba654ea5 100644 --- a/drivers/usb/gadget/f_obex.c +++ b/drivers/usb/gadget/f_obex.c | |||
@@ -24,7 +24,6 @@ | |||
24 | /* #define VERBOSE_DEBUG */ | 24 | /* #define VERBOSE_DEBUG */ |
25 | 25 | ||
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/utsname.h> | ||
28 | #include <linux/device.h> | 27 | #include <linux/device.h> |
29 | 28 | ||
30 | #include "u_serial.h" | 29 | #include "u_serial.h" |
diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c index bffe91d525f9..09cba273d2db 100644 --- a/drivers/usb/gadget/f_sourcesink.c +++ b/drivers/usb/gadget/f_sourcesink.c | |||
@@ -22,7 +22,6 @@ | |||
22 | /* #define VERBOSE_DEBUG */ | 22 | /* #define VERBOSE_DEBUG */ |
23 | 23 | ||
24 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
25 | #include <linux/utsname.h> | ||
26 | #include <linux/device.h> | 25 | #include <linux/device.h> |
27 | 26 | ||
28 | #include "g_zero.h" | 27 | #include "g_zero.h" |
diff --git a/drivers/usb/gadget/u_audio.c b/drivers/usb/gadget/u_audio.c index b5200d551458..8252595d619d 100644 --- a/drivers/usb/gadget/u_audio.c +++ b/drivers/usb/gadget/u_audio.c | |||
@@ -10,7 +10,6 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/utsname.h> | ||
14 | #include <linux/device.h> | 13 | #include <linux/device.h> |
15 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
16 | #include <linux/ctype.h> | 15 | #include <linux/ctype.h> |
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index f8751ff863cd..2fc02bd95848 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c | |||
@@ -23,7 +23,6 @@ | |||
23 | /* #define VERBOSE_DEBUG */ | 23 | /* #define VERBOSE_DEBUG */ |
24 | 24 | ||
25 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
26 | #include <linux/utsname.h> | ||
27 | #include <linux/device.h> | 26 | #include <linux/device.h> |
28 | #include <linux/ctype.h> | 27 | #include <linux/ctype.h> |
29 | #include <linux/etherdevice.h> | 28 | #include <linux/etherdevice.h> |
diff --git a/fs/9p/Kconfig b/fs/9p/Kconfig index 74e0723e90bc..795233702a4e 100644 --- a/fs/9p/Kconfig +++ b/fs/9p/Kconfig | |||
@@ -8,3 +8,12 @@ config 9P_FS | |||
8 | See <http://v9fs.sf.net> for more information. | 8 | See <http://v9fs.sf.net> for more information. |
9 | 9 | ||
10 | If unsure, say N. | 10 | If unsure, say N. |
11 | |||
12 | config 9P_FSCACHE | ||
13 | bool "Enable 9P client caching support (EXPERIMENTAL)" | ||
14 | depends on EXPERIMENTAL | ||
15 | depends on 9P_FS=m && FSCACHE || 9P_FS=y && FSCACHE=y | ||
16 | help | ||
17 | Choose Y here to enable persistent, read-only local | ||
18 | caching support for 9p clients using FS-Cache | ||
19 | |||
diff --git a/fs/9p/Makefile b/fs/9p/Makefile index bc7f0d1551e6..1a940ec7af61 100644 --- a/fs/9p/Makefile +++ b/fs/9p/Makefile | |||
@@ -8,5 +8,6 @@ obj-$(CONFIG_9P_FS) := 9p.o | |||
8 | vfs_dir.o \ | 8 | vfs_dir.o \ |
9 | vfs_dentry.o \ | 9 | vfs_dentry.o \ |
10 | v9fs.o \ | 10 | v9fs.o \ |
11 | fid.o \ | 11 | fid.o |
12 | 12 | ||
13 | 9p-$(CONFIG_9P_FSCACHE) += cache.o | ||
diff --git a/fs/9p/cache.c b/fs/9p/cache.c new file mode 100644 index 000000000000..51c94e26a346 --- /dev/null +++ b/fs/9p/cache.c | |||
@@ -0,0 +1,474 @@ | |||
1 | /* | ||
2 | * V9FS cache definitions. | ||
3 | * | ||
4 | * Copyright (C) 2009 by Abhishek Kulkarni <adkulkar@umail.iu.edu> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to: | ||
17 | * Free Software Foundation | ||
18 | * 51 Franklin Street, Fifth Floor | ||
19 | * Boston, MA 02111-1301 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <linux/jiffies.h> | ||
24 | #include <linux/file.h> | ||
25 | #include <linux/stat.h> | ||
26 | #include <linux/sched.h> | ||
27 | #include <linux/fs.h> | ||
28 | #include <net/9p/9p.h> | ||
29 | |||
30 | #include "v9fs.h" | ||
31 | #include "cache.h" | ||
32 | |||
33 | #define CACHETAG_LEN 11 | ||
34 | |||
35 | struct kmem_cache *vcookie_cache; | ||
36 | |||
37 | struct fscache_netfs v9fs_cache_netfs = { | ||
38 | .name = "9p", | ||
39 | .version = 0, | ||
40 | }; | ||
41 | |||
42 | static void init_once(void *foo) | ||
43 | { | ||
44 | struct v9fs_cookie *vcookie = (struct v9fs_cookie *) foo; | ||
45 | vcookie->fscache = NULL; | ||
46 | vcookie->qid = NULL; | ||
47 | inode_init_once(&vcookie->inode); | ||
48 | } | ||
49 | |||
50 | /** | ||
51 | * v9fs_init_vcookiecache - initialize a cache for vcookies to maintain | ||
52 | * vcookie to inode mapping | ||
53 | * | ||
54 | * Returns 0 on success. | ||
55 | */ | ||
56 | |||
57 | static int v9fs_init_vcookiecache(void) | ||
58 | { | ||
59 | vcookie_cache = kmem_cache_create("vcookie_cache", | ||
60 | sizeof(struct v9fs_cookie), | ||
61 | 0, (SLAB_RECLAIM_ACCOUNT| | ||
62 | SLAB_MEM_SPREAD), | ||
63 | init_once); | ||
64 | if (!vcookie_cache) | ||
65 | return -ENOMEM; | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | /** | ||
71 | * v9fs_destroy_vcookiecache - destroy the cache of vcookies | ||
72 | * | ||
73 | */ | ||
74 | |||
75 | static void v9fs_destroy_vcookiecache(void) | ||
76 | { | ||
77 | kmem_cache_destroy(vcookie_cache); | ||
78 | } | ||
79 | |||
80 | int __v9fs_cache_register(void) | ||
81 | { | ||
82 | int ret; | ||
83 | ret = v9fs_init_vcookiecache(); | ||
84 | if (ret < 0) | ||
85 | return ret; | ||
86 | |||
87 | return fscache_register_netfs(&v9fs_cache_netfs); | ||
88 | } | ||
89 | |||
90 | void __v9fs_cache_unregister(void) | ||
91 | { | ||
92 | v9fs_destroy_vcookiecache(); | ||
93 | fscache_unregister_netfs(&v9fs_cache_netfs); | ||
94 | } | ||
95 | |||
96 | /** | ||
97 | * v9fs_random_cachetag - Generate a random tag to be associated | ||
98 | * with a new cache session. | ||
99 | * | ||
100 | * The value of jiffies is used for a fairly randomly cache tag. | ||
101 | */ | ||
102 | |||
103 | static | ||
104 | int v9fs_random_cachetag(struct v9fs_session_info *v9ses) | ||
105 | { | ||
106 | v9ses->cachetag = kmalloc(CACHETAG_LEN, GFP_KERNEL); | ||
107 | if (!v9ses->cachetag) | ||
108 | return -ENOMEM; | ||
109 | |||
110 | return scnprintf(v9ses->cachetag, CACHETAG_LEN, "%lu", jiffies); | ||
111 | } | ||
112 | |||
113 | static uint16_t v9fs_cache_session_get_key(const void *cookie_netfs_data, | ||
114 | void *buffer, uint16_t bufmax) | ||
115 | { | ||
116 | struct v9fs_session_info *v9ses; | ||
117 | uint16_t klen = 0; | ||
118 | |||
119 | v9ses = (struct v9fs_session_info *)cookie_netfs_data; | ||
120 | P9_DPRINTK(P9_DEBUG_FSC, "session %p buf %p size %u", v9ses, | ||
121 | buffer, bufmax); | ||
122 | |||
123 | if (v9ses->cachetag) | ||
124 | klen = strlen(v9ses->cachetag); | ||
125 | |||
126 | if (klen > bufmax) | ||
127 | return 0; | ||
128 | |||
129 | memcpy(buffer, v9ses->cachetag, klen); | ||
130 | P9_DPRINTK(P9_DEBUG_FSC, "cache session tag %s", v9ses->cachetag); | ||
131 | return klen; | ||
132 | } | ||
133 | |||
134 | const struct fscache_cookie_def v9fs_cache_session_index_def = { | ||
135 | .name = "9P.session", | ||
136 | .type = FSCACHE_COOKIE_TYPE_INDEX, | ||
137 | .get_key = v9fs_cache_session_get_key, | ||
138 | }; | ||
139 | |||
140 | void v9fs_cache_session_get_cookie(struct v9fs_session_info *v9ses) | ||
141 | { | ||
142 | /* If no cache session tag was specified, we generate a random one. */ | ||
143 | if (!v9ses->cachetag) | ||
144 | v9fs_random_cachetag(v9ses); | ||
145 | |||
146 | v9ses->fscache = fscache_acquire_cookie(v9fs_cache_netfs.primary_index, | ||
147 | &v9fs_cache_session_index_def, | ||
148 | v9ses); | ||
149 | P9_DPRINTK(P9_DEBUG_FSC, "session %p get cookie %p", v9ses, | ||
150 | v9ses->fscache); | ||
151 | } | ||
152 | |||
153 | void v9fs_cache_session_put_cookie(struct v9fs_session_info *v9ses) | ||
154 | { | ||
155 | P9_DPRINTK(P9_DEBUG_FSC, "session %p put cookie %p", v9ses, | ||
156 | v9ses->fscache); | ||
157 | fscache_relinquish_cookie(v9ses->fscache, 0); | ||
158 | v9ses->fscache = NULL; | ||
159 | } | ||
160 | |||
161 | |||
162 | static uint16_t v9fs_cache_inode_get_key(const void *cookie_netfs_data, | ||
163 | void *buffer, uint16_t bufmax) | ||
164 | { | ||
165 | const struct v9fs_cookie *vcookie = cookie_netfs_data; | ||
166 | memcpy(buffer, &vcookie->qid->path, sizeof(vcookie->qid->path)); | ||
167 | |||
168 | P9_DPRINTK(P9_DEBUG_FSC, "inode %p get key %llu", &vcookie->inode, | ||
169 | vcookie->qid->path); | ||
170 | return sizeof(vcookie->qid->path); | ||
171 | } | ||
172 | |||
173 | static void v9fs_cache_inode_get_attr(const void *cookie_netfs_data, | ||
174 | uint64_t *size) | ||
175 | { | ||
176 | const struct v9fs_cookie *vcookie = cookie_netfs_data; | ||
177 | *size = i_size_read(&vcookie->inode); | ||
178 | |||
179 | P9_DPRINTK(P9_DEBUG_FSC, "inode %p get attr %llu", &vcookie->inode, | ||
180 | *size); | ||
181 | } | ||
182 | |||
183 | static uint16_t v9fs_cache_inode_get_aux(const void *cookie_netfs_data, | ||
184 | void *buffer, uint16_t buflen) | ||
185 | { | ||
186 | const struct v9fs_cookie *vcookie = cookie_netfs_data; | ||
187 | memcpy(buffer, &vcookie->qid->version, sizeof(vcookie->qid->version)); | ||
188 | |||
189 | P9_DPRINTK(P9_DEBUG_FSC, "inode %p get aux %u", &vcookie->inode, | ||
190 | vcookie->qid->version); | ||
191 | return sizeof(vcookie->qid->version); | ||
192 | } | ||
193 | |||
194 | static enum | ||
195 | fscache_checkaux v9fs_cache_inode_check_aux(void *cookie_netfs_data, | ||
196 | const void *buffer, | ||
197 | uint16_t buflen) | ||
198 | { | ||
199 | const struct v9fs_cookie *vcookie = cookie_netfs_data; | ||
200 | |||
201 | if (buflen != sizeof(vcookie->qid->version)) | ||
202 | return FSCACHE_CHECKAUX_OBSOLETE; | ||
203 | |||
204 | if (memcmp(buffer, &vcookie->qid->version, | ||
205 | sizeof(vcookie->qid->version))) | ||
206 | return FSCACHE_CHECKAUX_OBSOLETE; | ||
207 | |||
208 | return FSCACHE_CHECKAUX_OKAY; | ||
209 | } | ||
210 | |||
211 | static void v9fs_cache_inode_now_uncached(void *cookie_netfs_data) | ||
212 | { | ||
213 | struct v9fs_cookie *vcookie = cookie_netfs_data; | ||
214 | struct pagevec pvec; | ||
215 | pgoff_t first; | ||
216 | int loop, nr_pages; | ||
217 | |||
218 | pagevec_init(&pvec, 0); | ||
219 | first = 0; | ||
220 | |||
221 | for (;;) { | ||
222 | nr_pages = pagevec_lookup(&pvec, vcookie->inode.i_mapping, | ||
223 | first, | ||
224 | PAGEVEC_SIZE - pagevec_count(&pvec)); | ||
225 | if (!nr_pages) | ||
226 | break; | ||
227 | |||
228 | for (loop = 0; loop < nr_pages; loop++) | ||
229 | ClearPageFsCache(pvec.pages[loop]); | ||
230 | |||
231 | first = pvec.pages[nr_pages - 1]->index + 1; | ||
232 | |||
233 | pvec.nr = nr_pages; | ||
234 | pagevec_release(&pvec); | ||
235 | cond_resched(); | ||
236 | } | ||
237 | } | ||
238 | |||
239 | const struct fscache_cookie_def v9fs_cache_inode_index_def = { | ||
240 | .name = "9p.inode", | ||
241 | .type = FSCACHE_COOKIE_TYPE_DATAFILE, | ||
242 | .get_key = v9fs_cache_inode_get_key, | ||
243 | .get_attr = v9fs_cache_inode_get_attr, | ||
244 | .get_aux = v9fs_cache_inode_get_aux, | ||
245 | .check_aux = v9fs_cache_inode_check_aux, | ||
246 | .now_uncached = v9fs_cache_inode_now_uncached, | ||
247 | }; | ||
248 | |||
249 | void v9fs_cache_inode_get_cookie(struct inode *inode) | ||
250 | { | ||
251 | struct v9fs_cookie *vcookie; | ||
252 | struct v9fs_session_info *v9ses; | ||
253 | |||
254 | if (!S_ISREG(inode->i_mode)) | ||
255 | return; | ||
256 | |||
257 | vcookie = v9fs_inode2cookie(inode); | ||
258 | if (vcookie->fscache) | ||
259 | return; | ||
260 | |||
261 | v9ses = v9fs_inode2v9ses(inode); | ||
262 | vcookie->fscache = fscache_acquire_cookie(v9ses->fscache, | ||
263 | &v9fs_cache_inode_index_def, | ||
264 | vcookie); | ||
265 | |||
266 | P9_DPRINTK(P9_DEBUG_FSC, "inode %p get cookie %p", inode, | ||
267 | vcookie->fscache); | ||
268 | } | ||
269 | |||
270 | void v9fs_cache_inode_put_cookie(struct inode *inode) | ||
271 | { | ||
272 | struct v9fs_cookie *vcookie = v9fs_inode2cookie(inode); | ||
273 | |||
274 | if (!vcookie->fscache) | ||
275 | return; | ||
276 | P9_DPRINTK(P9_DEBUG_FSC, "inode %p put cookie %p", inode, | ||
277 | vcookie->fscache); | ||
278 | |||
279 | fscache_relinquish_cookie(vcookie->fscache, 0); | ||
280 | vcookie->fscache = NULL; | ||
281 | } | ||
282 | |||
283 | void v9fs_cache_inode_flush_cookie(struct inode *inode) | ||
284 | { | ||
285 | struct v9fs_cookie *vcookie = v9fs_inode2cookie(inode); | ||
286 | |||
287 | if (!vcookie->fscache) | ||
288 | return; | ||
289 | P9_DPRINTK(P9_DEBUG_FSC, "inode %p flush cookie %p", inode, | ||
290 | vcookie->fscache); | ||
291 | |||
292 | fscache_relinquish_cookie(vcookie->fscache, 1); | ||
293 | vcookie->fscache = NULL; | ||
294 | } | ||
295 | |||
296 | void v9fs_cache_inode_set_cookie(struct inode *inode, struct file *filp) | ||
297 | { | ||
298 | struct v9fs_cookie *vcookie = v9fs_inode2cookie(inode); | ||
299 | struct p9_fid *fid; | ||
300 | |||
301 | if (!vcookie->fscache) | ||
302 | return; | ||
303 | |||
304 | spin_lock(&vcookie->lock); | ||
305 | fid = filp->private_data; | ||
306 | if ((filp->f_flags & O_ACCMODE) != O_RDONLY) | ||
307 | v9fs_cache_inode_flush_cookie(inode); | ||
308 | else | ||
309 | v9fs_cache_inode_get_cookie(inode); | ||
310 | |||
311 | spin_unlock(&vcookie->lock); | ||
312 | } | ||
313 | |||
314 | void v9fs_cache_inode_reset_cookie(struct inode *inode) | ||
315 | { | ||
316 | struct v9fs_cookie *vcookie = v9fs_inode2cookie(inode); | ||
317 | struct v9fs_session_info *v9ses; | ||
318 | struct fscache_cookie *old; | ||
319 | |||
320 | if (!vcookie->fscache) | ||
321 | return; | ||
322 | |||
323 | old = vcookie->fscache; | ||
324 | |||
325 | spin_lock(&vcookie->lock); | ||
326 | fscache_relinquish_cookie(vcookie->fscache, 1); | ||
327 | |||
328 | v9ses = v9fs_inode2v9ses(inode); | ||
329 | vcookie->fscache = fscache_acquire_cookie(v9ses->fscache, | ||
330 | &v9fs_cache_inode_index_def, | ||
331 | vcookie); | ||
332 | |||
333 | P9_DPRINTK(P9_DEBUG_FSC, "inode %p revalidating cookie old %p new %p", | ||
334 | inode, old, vcookie->fscache); | ||
335 | |||
336 | spin_unlock(&vcookie->lock); | ||
337 | } | ||
338 | |||
339 | int __v9fs_fscache_release_page(struct page *page, gfp_t gfp) | ||
340 | { | ||
341 | struct inode *inode = page->mapping->host; | ||
342 | struct v9fs_cookie *vcookie = v9fs_inode2cookie(inode); | ||
343 | |||
344 | BUG_ON(!vcookie->fscache); | ||
345 | |||
346 | if (PageFsCache(page)) { | ||
347 | if (fscache_check_page_write(vcookie->fscache, page)) { | ||
348 | if (!(gfp & __GFP_WAIT)) | ||
349 | return 0; | ||
350 | fscache_wait_on_page_write(vcookie->fscache, page); | ||
351 | } | ||
352 | |||
353 | fscache_uncache_page(vcookie->fscache, page); | ||
354 | ClearPageFsCache(page); | ||
355 | } | ||
356 | |||
357 | return 1; | ||
358 | } | ||
359 | |||
360 | void __v9fs_fscache_invalidate_page(struct page *page) | ||
361 | { | ||
362 | struct inode *inode = page->mapping->host; | ||
363 | struct v9fs_cookie *vcookie = v9fs_inode2cookie(inode); | ||
364 | |||
365 | BUG_ON(!vcookie->fscache); | ||
366 | |||
367 | if (PageFsCache(page)) { | ||
368 | fscache_wait_on_page_write(vcookie->fscache, page); | ||
369 | BUG_ON(!PageLocked(page)); | ||
370 | fscache_uncache_page(vcookie->fscache, page); | ||
371 | ClearPageFsCache(page); | ||
372 | } | ||
373 | } | ||
374 | |||
375 | static void v9fs_vfs_readpage_complete(struct page *page, void *data, | ||
376 | int error) | ||
377 | { | ||
378 | if (!error) | ||
379 | SetPageUptodate(page); | ||
380 | |||
381 | unlock_page(page); | ||
382 | } | ||
383 | |||
384 | /** | ||
385 | * __v9fs_readpage_from_fscache - read a page from cache | ||
386 | * | ||
387 | * Returns 0 if the pages are in cache and a BIO is submitted, | ||
388 | * 1 if the pages are not in cache and -error otherwise. | ||
389 | */ | ||
390 | |||
391 | int __v9fs_readpage_from_fscache(struct inode *inode, struct page *page) | ||
392 | { | ||
393 | int ret; | ||
394 | const struct v9fs_cookie *vcookie = v9fs_inode2cookie(inode); | ||
395 | |||
396 | P9_DPRINTK(P9_DEBUG_FSC, "inode %p page %p", inode, page); | ||
397 | if (!vcookie->fscache) | ||
398 | return -ENOBUFS; | ||
399 | |||
400 | ret = fscache_read_or_alloc_page(vcookie->fscache, | ||
401 | page, | ||
402 | v9fs_vfs_readpage_complete, | ||
403 | NULL, | ||
404 | GFP_KERNEL); | ||
405 | switch (ret) { | ||
406 | case -ENOBUFS: | ||
407 | case -ENODATA: | ||
408 | P9_DPRINTK(P9_DEBUG_FSC, "page/inode not in cache %d", ret); | ||
409 | return 1; | ||
410 | case 0: | ||
411 | P9_DPRINTK(P9_DEBUG_FSC, "BIO submitted"); | ||
412 | return ret; | ||
413 | default: | ||
414 | P9_DPRINTK(P9_DEBUG_FSC, "ret %d", ret); | ||
415 | return ret; | ||
416 | } | ||
417 | } | ||
418 | |||
419 | /** | ||
420 | * __v9fs_readpages_from_fscache - read multiple pages from cache | ||
421 | * | ||
422 | * Returns 0 if the pages are in cache and a BIO is submitted, | ||
423 | * 1 if the pages are not in cache and -error otherwise. | ||
424 | */ | ||
425 | |||
426 | int __v9fs_readpages_from_fscache(struct inode *inode, | ||
427 | struct address_space *mapping, | ||
428 | struct list_head *pages, | ||
429 | unsigned *nr_pages) | ||
430 | { | ||
431 | int ret; | ||
432 | const struct v9fs_cookie *vcookie = v9fs_inode2cookie(inode); | ||
433 | |||
434 | P9_DPRINTK(P9_DEBUG_FSC, "inode %p pages %u", inode, *nr_pages); | ||
435 | if (!vcookie->fscache) | ||
436 | return -ENOBUFS; | ||
437 | |||
438 | ret = fscache_read_or_alloc_pages(vcookie->fscache, | ||
439 | mapping, pages, nr_pages, | ||
440 | v9fs_vfs_readpage_complete, | ||
441 | NULL, | ||
442 | mapping_gfp_mask(mapping)); | ||
443 | switch (ret) { | ||
444 | case -ENOBUFS: | ||
445 | case -ENODATA: | ||
446 | P9_DPRINTK(P9_DEBUG_FSC, "pages/inodes not in cache %d", ret); | ||
447 | return 1; | ||
448 | case 0: | ||
449 | BUG_ON(!list_empty(pages)); | ||
450 | BUG_ON(*nr_pages != 0); | ||
451 | P9_DPRINTK(P9_DEBUG_FSC, "BIO submitted"); | ||
452 | return ret; | ||
453 | default: | ||
454 | P9_DPRINTK(P9_DEBUG_FSC, "ret %d", ret); | ||
455 | return ret; | ||
456 | } | ||
457 | } | ||
458 | |||
459 | /** | ||
460 | * __v9fs_readpage_to_fscache - write a page to the cache | ||
461 | * | ||
462 | */ | ||
463 | |||
464 | void __v9fs_readpage_to_fscache(struct inode *inode, struct page *page) | ||
465 | { | ||
466 | int ret; | ||
467 | const struct v9fs_cookie *vcookie = v9fs_inode2cookie(inode); | ||
468 | |||
469 | P9_DPRINTK(P9_DEBUG_FSC, "inode %p page %p", inode, page); | ||
470 | ret = fscache_write_page(vcookie->fscache, page, GFP_KERNEL); | ||
471 | P9_DPRINTK(P9_DEBUG_FSC, "ret = %d", ret); | ||
472 | if (ret != 0) | ||
473 | v9fs_uncache_page(inode, page); | ||
474 | } | ||
diff --git a/fs/9p/cache.h b/fs/9p/cache.h new file mode 100644 index 000000000000..a94192bfaee8 --- /dev/null +++ b/fs/9p/cache.h | |||
@@ -0,0 +1,176 @@ | |||
1 | /* | ||
2 | * V9FS cache definitions. | ||
3 | * | ||
4 | * Copyright (C) 2009 by Abhishek Kulkarni <adkulkar@umail.iu.edu> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to: | ||
17 | * Free Software Foundation | ||
18 | * 51 Franklin Street, Fifth Floor | ||
19 | * Boston, MA 02111-1301 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #ifndef _9P_CACHE_H | ||
24 | #ifdef CONFIG_9P_FSCACHE | ||
25 | #include <linux/fscache.h> | ||
26 | #include <linux/spinlock.h> | ||
27 | |||
28 | extern struct kmem_cache *vcookie_cache; | ||
29 | |||
30 | struct v9fs_cookie { | ||
31 | spinlock_t lock; | ||
32 | struct inode inode; | ||
33 | struct fscache_cookie *fscache; | ||
34 | struct p9_qid *qid; | ||
35 | }; | ||
36 | |||
37 | static inline struct v9fs_cookie *v9fs_inode2cookie(const struct inode *inode) | ||
38 | { | ||
39 | return container_of(inode, struct v9fs_cookie, inode); | ||
40 | } | ||
41 | |||
42 | extern struct fscache_netfs v9fs_cache_netfs; | ||
43 | extern const struct fscache_cookie_def v9fs_cache_session_index_def; | ||
44 | extern const struct fscache_cookie_def v9fs_cache_inode_index_def; | ||
45 | |||
46 | extern void v9fs_cache_session_get_cookie(struct v9fs_session_info *v9ses); | ||
47 | extern void v9fs_cache_session_put_cookie(struct v9fs_session_info *v9ses); | ||
48 | |||
49 | extern void v9fs_cache_inode_get_cookie(struct inode *inode); | ||
50 | extern void v9fs_cache_inode_put_cookie(struct inode *inode); | ||
51 | extern void v9fs_cache_inode_flush_cookie(struct inode *inode); | ||
52 | extern void v9fs_cache_inode_set_cookie(struct inode *inode, struct file *filp); | ||
53 | extern void v9fs_cache_inode_reset_cookie(struct inode *inode); | ||
54 | |||
55 | extern int __v9fs_cache_register(void); | ||
56 | extern void __v9fs_cache_unregister(void); | ||
57 | |||
58 | extern int __v9fs_fscache_release_page(struct page *page, gfp_t gfp); | ||
59 | extern void __v9fs_fscache_invalidate_page(struct page *page); | ||
60 | extern int __v9fs_readpage_from_fscache(struct inode *inode, | ||
61 | struct page *page); | ||
62 | extern int __v9fs_readpages_from_fscache(struct inode *inode, | ||
63 | struct address_space *mapping, | ||
64 | struct list_head *pages, | ||
65 | unsigned *nr_pages); | ||
66 | extern void __v9fs_readpage_to_fscache(struct inode *inode, struct page *page); | ||
67 | |||
68 | |||
69 | /** | ||
70 | * v9fs_cache_register - Register v9fs file system with the cache | ||
71 | */ | ||
72 | static inline int v9fs_cache_register(void) | ||
73 | { | ||
74 | return __v9fs_cache_register(); | ||
75 | } | ||
76 | |||
77 | /** | ||
78 | * v9fs_cache_unregister - Unregister v9fs from the cache | ||
79 | */ | ||
80 | static inline void v9fs_cache_unregister(void) | ||
81 | { | ||
82 | __v9fs_cache_unregister(); | ||
83 | } | ||
84 | |||
85 | static inline int v9fs_fscache_release_page(struct page *page, | ||
86 | gfp_t gfp) | ||
87 | { | ||
88 | return __v9fs_fscache_release_page(page, gfp); | ||
89 | } | ||
90 | |||
91 | static inline void v9fs_fscache_invalidate_page(struct page *page) | ||
92 | { | ||
93 | __v9fs_fscache_invalidate_page(page); | ||
94 | } | ||
95 | |||
96 | static inline int v9fs_readpage_from_fscache(struct inode *inode, | ||
97 | struct page *page) | ||
98 | { | ||
99 | return __v9fs_readpage_from_fscache(inode, page); | ||
100 | } | ||
101 | |||
102 | static inline int v9fs_readpages_from_fscache(struct inode *inode, | ||
103 | struct address_space *mapping, | ||
104 | struct list_head *pages, | ||
105 | unsigned *nr_pages) | ||
106 | { | ||
107 | return __v9fs_readpages_from_fscache(inode, mapping, pages, | ||
108 | nr_pages); | ||
109 | } | ||
110 | |||
111 | static inline void v9fs_readpage_to_fscache(struct inode *inode, | ||
112 | struct page *page) | ||
113 | { | ||
114 | if (PageFsCache(page)) | ||
115 | __v9fs_readpage_to_fscache(inode, page); | ||
116 | } | ||
117 | |||
118 | static inline void v9fs_uncache_page(struct inode *inode, struct page *page) | ||
119 | { | ||
120 | struct v9fs_cookie *vcookie = v9fs_inode2cookie(inode); | ||
121 | fscache_uncache_page(vcookie->fscache, page); | ||
122 | BUG_ON(PageFsCache(page)); | ||
123 | } | ||
124 | |||
125 | static inline void v9fs_vcookie_set_qid(struct inode *inode, | ||
126 | struct p9_qid *qid) | ||
127 | { | ||
128 | struct v9fs_cookie *vcookie = v9fs_inode2cookie(inode); | ||
129 | spin_lock(&vcookie->lock); | ||
130 | vcookie->qid = qid; | ||
131 | spin_unlock(&vcookie->lock); | ||
132 | } | ||
133 | |||
134 | #else /* CONFIG_9P_FSCACHE */ | ||
135 | |||
136 | static inline int v9fs_cache_register(void) | ||
137 | { | ||
138 | return 1; | ||
139 | } | ||
140 | |||
141 | static inline void v9fs_cache_unregister(void) {} | ||
142 | |||
143 | static inline int v9fs_fscache_release_page(struct page *page, | ||
144 | gfp_t gfp) { | ||
145 | return 1; | ||
146 | } | ||
147 | |||
148 | static inline void v9fs_fscache_invalidate_page(struct page *page) {} | ||
149 | |||
150 | static inline int v9fs_readpage_from_fscache(struct inode *inode, | ||
151 | struct page *page) | ||
152 | { | ||
153 | return -ENOBUFS; | ||
154 | } | ||
155 | |||
156 | static inline int v9fs_readpages_from_fscache(struct inode *inode, | ||
157 | struct address_space *mapping, | ||
158 | struct list_head *pages, | ||
159 | unsigned *nr_pages) | ||
160 | { | ||
161 | return -ENOBUFS; | ||
162 | } | ||
163 | |||
164 | static inline void v9fs_readpage_to_fscache(struct inode *inode, | ||
165 | struct page *page) | ||
166 | {} | ||
167 | |||
168 | static inline void v9fs_uncache_page(struct inode *inode, struct page *page) | ||
169 | {} | ||
170 | |||
171 | static inline void v9fs_vcookie_set_qid(struct inode *inode, | ||
172 | struct p9_qid *qid) | ||
173 | {} | ||
174 | |||
175 | #endif /* CONFIG_9P_FSCACHE */ | ||
176 | #endif /* _9P_CACHE_H */ | ||
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index f7003cfac63d..cf62b05e296a 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c | |||
@@ -34,21 +34,25 @@ | |||
34 | #include <net/9p/transport.h> | 34 | #include <net/9p/transport.h> |
35 | #include "v9fs.h" | 35 | #include "v9fs.h" |
36 | #include "v9fs_vfs.h" | 36 | #include "v9fs_vfs.h" |
37 | #include "cache.h" | ||
38 | |||
39 | static DEFINE_SPINLOCK(v9fs_sessionlist_lock); | ||
40 | static LIST_HEAD(v9fs_sessionlist); | ||
37 | 41 | ||
38 | /* | 42 | /* |
39 | * Option Parsing (code inspired by NFS code) | 43 | * Option Parsing (code inspired by NFS code) |
40 | * NOTE: each transport will parse its own options | 44 | * NOTE: each transport will parse its own options |
41 | */ | 45 | */ |
42 | 46 | ||
43 | enum { | 47 | enum { |
44 | /* Options that take integer arguments */ | 48 | /* Options that take integer arguments */ |
45 | Opt_debug, Opt_dfltuid, Opt_dfltgid, Opt_afid, | 49 | Opt_debug, Opt_dfltuid, Opt_dfltgid, Opt_afid, |
46 | /* String options */ | 50 | /* String options */ |
47 | Opt_uname, Opt_remotename, Opt_trans, | 51 | Opt_uname, Opt_remotename, Opt_trans, Opt_cache, Opt_cachetag, |
48 | /* Options that take no arguments */ | 52 | /* Options that take no arguments */ |
49 | Opt_nodevmap, | 53 | Opt_nodevmap, |
50 | /* Cache options */ | 54 | /* Cache options */ |
51 | Opt_cache_loose, | 55 | Opt_cache_loose, Opt_fscache, |
52 | /* Access options */ | 56 | /* Access options */ |
53 | Opt_access, | 57 | Opt_access, |
54 | /* Error token */ | 58 | /* Error token */ |
@@ -63,8 +67,10 @@ static const match_table_t tokens = { | |||
63 | {Opt_uname, "uname=%s"}, | 67 | {Opt_uname, "uname=%s"}, |
64 | {Opt_remotename, "aname=%s"}, | 68 | {Opt_remotename, "aname=%s"}, |
65 | {Opt_nodevmap, "nodevmap"}, | 69 | {Opt_nodevmap, "nodevmap"}, |
66 | {Opt_cache_loose, "cache=loose"}, | 70 | {Opt_cache, "cache=%s"}, |
67 | {Opt_cache_loose, "loose"}, | 71 | {Opt_cache_loose, "loose"}, |
72 | {Opt_fscache, "fscache"}, | ||
73 | {Opt_cachetag, "cachetag=%s"}, | ||
68 | {Opt_access, "access=%s"}, | 74 | {Opt_access, "access=%s"}, |
69 | {Opt_err, NULL} | 75 | {Opt_err, NULL} |
70 | }; | 76 | }; |
@@ -89,16 +95,16 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts) | |||
89 | v9ses->afid = ~0; | 95 | v9ses->afid = ~0; |
90 | v9ses->debug = 0; | 96 | v9ses->debug = 0; |
91 | v9ses->cache = 0; | 97 | v9ses->cache = 0; |
98 | #ifdef CONFIG_9P_FSCACHE | ||
99 | v9ses->cachetag = NULL; | ||
100 | #endif | ||
92 | 101 | ||
93 | if (!opts) | 102 | if (!opts) |
94 | return 0; | 103 | return 0; |
95 | 104 | ||
96 | options = kstrdup(opts, GFP_KERNEL); | 105 | options = kstrdup(opts, GFP_KERNEL); |
97 | if (!options) { | 106 | if (!options) |
98 | P9_DPRINTK(P9_DEBUG_ERROR, | 107 | goto fail_option_alloc; |
99 | "failed to allocate copy of option string\n"); | ||
100 | return -ENOMEM; | ||
101 | } | ||
102 | 108 | ||
103 | while ((p = strsep(&options, ",")) != NULL) { | 109 | while ((p = strsep(&options, ",")) != NULL) { |
104 | int token; | 110 | int token; |
@@ -143,16 +149,33 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts) | |||
143 | case Opt_cache_loose: | 149 | case Opt_cache_loose: |
144 | v9ses->cache = CACHE_LOOSE; | 150 | v9ses->cache = CACHE_LOOSE; |
145 | break; | 151 | break; |
152 | case Opt_fscache: | ||
153 | v9ses->cache = CACHE_FSCACHE; | ||
154 | break; | ||
155 | case Opt_cachetag: | ||
156 | #ifdef CONFIG_9P_FSCACHE | ||
157 | v9ses->cachetag = match_strdup(&args[0]); | ||
158 | #endif | ||
159 | break; | ||
160 | case Opt_cache: | ||
161 | s = match_strdup(&args[0]); | ||
162 | if (!s) | ||
163 | goto fail_option_alloc; | ||
164 | |||
165 | if (strcmp(s, "loose") == 0) | ||
166 | v9ses->cache = CACHE_LOOSE; | ||
167 | else if (strcmp(s, "fscache") == 0) | ||
168 | v9ses->cache = CACHE_FSCACHE; | ||
169 | else | ||
170 | v9ses->cache = CACHE_NONE; | ||
171 | kfree(s); | ||
172 | break; | ||
146 | 173 | ||
147 | case Opt_access: | 174 | case Opt_access: |
148 | s = match_strdup(&args[0]); | 175 | s = match_strdup(&args[0]); |
149 | if (!s) { | 176 | if (!s) |
150 | P9_DPRINTK(P9_DEBUG_ERROR, | 177 | goto fail_option_alloc; |
151 | "failed to allocate copy" | 178 | |
152 | " of option argument\n"); | ||
153 | ret = -ENOMEM; | ||
154 | break; | ||
155 | } | ||
156 | v9ses->flags &= ~V9FS_ACCESS_MASK; | 179 | v9ses->flags &= ~V9FS_ACCESS_MASK; |
157 | if (strcmp(s, "user") == 0) | 180 | if (strcmp(s, "user") == 0) |
158 | v9ses->flags |= V9FS_ACCESS_USER; | 181 | v9ses->flags |= V9FS_ACCESS_USER; |
@@ -173,6 +196,11 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts) | |||
173 | } | 196 | } |
174 | kfree(options); | 197 | kfree(options); |
175 | return ret; | 198 | return ret; |
199 | |||
200 | fail_option_alloc: | ||
201 | P9_DPRINTK(P9_DEBUG_ERROR, | ||
202 | "failed to allocate copy of option argument\n"); | ||
203 | return -ENOMEM; | ||
176 | } | 204 | } |
177 | 205 | ||
178 | /** | 206 | /** |
@@ -200,6 +228,10 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, | |||
200 | return ERR_PTR(-ENOMEM); | 228 | return ERR_PTR(-ENOMEM); |
201 | } | 229 | } |
202 | 230 | ||
231 | spin_lock(&v9fs_sessionlist_lock); | ||
232 | list_add(&v9ses->slist, &v9fs_sessionlist); | ||
233 | spin_unlock(&v9fs_sessionlist_lock); | ||
234 | |||
203 | v9ses->flags = V9FS_EXTENDED | V9FS_ACCESS_USER; | 235 | v9ses->flags = V9FS_EXTENDED | V9FS_ACCESS_USER; |
204 | strcpy(v9ses->uname, V9FS_DEFUSER); | 236 | strcpy(v9ses->uname, V9FS_DEFUSER); |
205 | strcpy(v9ses->aname, V9FS_DEFANAME); | 237 | strcpy(v9ses->aname, V9FS_DEFANAME); |
@@ -249,6 +281,11 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, | |||
249 | else | 281 | else |
250 | fid->uid = ~0; | 282 | fid->uid = ~0; |
251 | 283 | ||
284 | #ifdef CONFIG_9P_FSCACHE | ||
285 | /* register the session for caching */ | ||
286 | v9fs_cache_session_get_cookie(v9ses); | ||
287 | #endif | ||
288 | |||
252 | return fid; | 289 | return fid; |
253 | 290 | ||
254 | error: | 291 | error: |
@@ -268,8 +305,18 @@ void v9fs_session_close(struct v9fs_session_info *v9ses) | |||
268 | v9ses->clnt = NULL; | 305 | v9ses->clnt = NULL; |
269 | } | 306 | } |
270 | 307 | ||
308 | #ifdef CONFIG_9P_FSCACHE | ||
309 | if (v9ses->fscache) { | ||
310 | v9fs_cache_session_put_cookie(v9ses); | ||
311 | kfree(v9ses->cachetag); | ||
312 | } | ||
313 | #endif | ||
271 | __putname(v9ses->uname); | 314 | __putname(v9ses->uname); |
272 | __putname(v9ses->aname); | 315 | __putname(v9ses->aname); |
316 | |||
317 | spin_lock(&v9fs_sessionlist_lock); | ||
318 | list_del(&v9ses->slist); | ||
319 | spin_unlock(&v9fs_sessionlist_lock); | ||
273 | } | 320 | } |
274 | 321 | ||
275 | /** | 322 | /** |
@@ -286,25 +333,132 @@ void v9fs_session_cancel(struct v9fs_session_info *v9ses) { | |||
286 | 333 | ||
287 | extern int v9fs_error_init(void); | 334 | extern int v9fs_error_init(void); |
288 | 335 | ||
336 | static struct kobject *v9fs_kobj; | ||
337 | |||
338 | #ifdef CONFIG_9P_FSCACHE | ||
289 | /** | 339 | /** |
290 | * v9fs_init - Initialize module | 340 | * caches_show - list caches associated with a session |
341 | * | ||
342 | * Returns the size of buffer written. | ||
343 | */ | ||
344 | |||
345 | static ssize_t caches_show(struct kobject *kobj, | ||
346 | struct kobj_attribute *attr, | ||
347 | char *buf) | ||
348 | { | ||
349 | ssize_t n = 0, count = 0, limit = PAGE_SIZE; | ||
350 | struct v9fs_session_info *v9ses; | ||
351 | |||
352 | spin_lock(&v9fs_sessionlist_lock); | ||
353 | list_for_each_entry(v9ses, &v9fs_sessionlist, slist) { | ||
354 | if (v9ses->cachetag) { | ||
355 | n = snprintf(buf, limit, "%s\n", v9ses->cachetag); | ||
356 | if (n < 0) { | ||
357 | count = n; | ||
358 | break; | ||
359 | } | ||
360 | |||
361 | count += n; | ||
362 | limit -= n; | ||
363 | } | ||
364 | } | ||
365 | |||
366 | spin_unlock(&v9fs_sessionlist_lock); | ||
367 | return count; | ||
368 | } | ||
369 | |||
370 | static struct kobj_attribute v9fs_attr_cache = __ATTR_RO(caches); | ||
371 | #endif /* CONFIG_9P_FSCACHE */ | ||
372 | |||
373 | static struct attribute *v9fs_attrs[] = { | ||
374 | #ifdef CONFIG_9P_FSCACHE | ||
375 | &v9fs_attr_cache.attr, | ||
376 | #endif | ||
377 | NULL, | ||
378 | }; | ||
379 | |||
380 | static struct attribute_group v9fs_attr_group = { | ||
381 | .attrs = v9fs_attrs, | ||
382 | }; | ||
383 | |||
384 | /** | ||
385 | * v9fs_sysfs_init - Initialize the v9fs sysfs interface | ||
386 | * | ||
387 | */ | ||
388 | |||
389 | static int v9fs_sysfs_init(void) | ||
390 | { | ||
391 | v9fs_kobj = kobject_create_and_add("9p", fs_kobj); | ||
392 | if (!v9fs_kobj) | ||
393 | return -ENOMEM; | ||
394 | |||
395 | if (sysfs_create_group(v9fs_kobj, &v9fs_attr_group)) { | ||
396 | kobject_put(v9fs_kobj); | ||
397 | return -ENOMEM; | ||
398 | } | ||
399 | |||
400 | return 0; | ||
401 | } | ||
402 | |||
403 | /** | ||
404 | * v9fs_sysfs_cleanup - Unregister the v9fs sysfs interface | ||
405 | * | ||
406 | */ | ||
407 | |||
408 | static void v9fs_sysfs_cleanup(void) | ||
409 | { | ||
410 | sysfs_remove_group(v9fs_kobj, &v9fs_attr_group); | ||
411 | kobject_put(v9fs_kobj); | ||
412 | } | ||
413 | |||
414 | /** | ||
415 | * init_v9fs - Initialize module | ||
291 | * | 416 | * |
292 | */ | 417 | */ |
293 | 418 | ||
294 | static int __init init_v9fs(void) | 419 | static int __init init_v9fs(void) |
295 | { | 420 | { |
421 | int err; | ||
296 | printk(KERN_INFO "Installing v9fs 9p2000 file system support\n"); | 422 | printk(KERN_INFO "Installing v9fs 9p2000 file system support\n"); |
297 | /* TODO: Setup list of registered trasnport modules */ | 423 | /* TODO: Setup list of registered trasnport modules */ |
298 | return register_filesystem(&v9fs_fs_type); | 424 | err = register_filesystem(&v9fs_fs_type); |
425 | if (err < 0) { | ||
426 | printk(KERN_ERR "Failed to register filesystem\n"); | ||
427 | return err; | ||
428 | } | ||
429 | |||
430 | err = v9fs_cache_register(); | ||
431 | if (err < 0) { | ||
432 | printk(KERN_ERR "Failed to register v9fs for caching\n"); | ||
433 | goto out_fs_unreg; | ||
434 | } | ||
435 | |||
436 | err = v9fs_sysfs_init(); | ||
437 | if (err < 0) { | ||
438 | printk(KERN_ERR "Failed to register with sysfs\n"); | ||
439 | goto out_sysfs_cleanup; | ||
440 | } | ||
441 | |||
442 | return 0; | ||
443 | |||
444 | out_sysfs_cleanup: | ||
445 | v9fs_sysfs_cleanup(); | ||
446 | |||
447 | out_fs_unreg: | ||
448 | unregister_filesystem(&v9fs_fs_type); | ||
449 | |||
450 | return err; | ||
299 | } | 451 | } |
300 | 452 | ||
301 | /** | 453 | /** |
302 | * v9fs_init - shutdown module | 454 | * exit_v9fs - shutdown module |
303 | * | 455 | * |
304 | */ | 456 | */ |
305 | 457 | ||
306 | static void __exit exit_v9fs(void) | 458 | static void __exit exit_v9fs(void) |
307 | { | 459 | { |
460 | v9fs_sysfs_cleanup(); | ||
461 | v9fs_cache_unregister(); | ||
308 | unregister_filesystem(&v9fs_fs_type); | 462 | unregister_filesystem(&v9fs_fs_type); |
309 | } | 463 | } |
310 | 464 | ||
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h index 38762bf102a9..019f4ccb70c1 100644 --- a/fs/9p/v9fs.h +++ b/fs/9p/v9fs.h | |||
@@ -51,6 +51,7 @@ enum p9_session_flags { | |||
51 | enum p9_cache_modes { | 51 | enum p9_cache_modes { |
52 | CACHE_NONE, | 52 | CACHE_NONE, |
53 | CACHE_LOOSE, | 53 | CACHE_LOOSE, |
54 | CACHE_FSCACHE, | ||
54 | }; | 55 | }; |
55 | 56 | ||
56 | /** | 57 | /** |
@@ -60,6 +61,8 @@ enum p9_cache_modes { | |||
60 | * @debug: debug level | 61 | * @debug: debug level |
61 | * @afid: authentication handle | 62 | * @afid: authentication handle |
62 | * @cache: cache mode of type &p9_cache_modes | 63 | * @cache: cache mode of type &p9_cache_modes |
64 | * @cachetag: the tag of the cache associated with this session | ||
65 | * @fscache: session cookie associated with FS-Cache | ||
63 | * @options: copy of options string given by user | 66 | * @options: copy of options string given by user |
64 | * @uname: string user name to mount hierarchy as | 67 | * @uname: string user name to mount hierarchy as |
65 | * @aname: mount specifier for remote hierarchy | 68 | * @aname: mount specifier for remote hierarchy |
@@ -68,7 +71,7 @@ enum p9_cache_modes { | |||
68 | * @dfltgid: default numeric groupid to mount hierarchy as | 71 | * @dfltgid: default numeric groupid to mount hierarchy as |
69 | * @uid: if %V9FS_ACCESS_SINGLE, the numeric uid which mounted the hierarchy | 72 | * @uid: if %V9FS_ACCESS_SINGLE, the numeric uid which mounted the hierarchy |
70 | * @clnt: reference to 9P network client instantiated for this session | 73 | * @clnt: reference to 9P network client instantiated for this session |
71 | * @debugfs_dir: reference to debugfs_dir which can be used for add'l debug | 74 | * @slist: reference to list of registered 9p sessions |
72 | * | 75 | * |
73 | * This structure holds state for each session instance established during | 76 | * This structure holds state for each session instance established during |
74 | * a sys_mount() . | 77 | * a sys_mount() . |
@@ -84,6 +87,10 @@ struct v9fs_session_info { | |||
84 | unsigned short debug; | 87 | unsigned short debug; |
85 | unsigned int afid; | 88 | unsigned int afid; |
86 | unsigned int cache; | 89 | unsigned int cache; |
90 | #ifdef CONFIG_9P_FSCACHE | ||
91 | char *cachetag; | ||
92 | struct fscache_cookie *fscache; | ||
93 | #endif | ||
87 | 94 | ||
88 | char *uname; /* user name to mount as */ | 95 | char *uname; /* user name to mount as */ |
89 | char *aname; /* name of remote hierarchy being mounted */ | 96 | char *aname; /* name of remote hierarchy being mounted */ |
@@ -92,11 +99,9 @@ struct v9fs_session_info { | |||
92 | unsigned int dfltgid; /* default gid for legacy support */ | 99 | unsigned int dfltgid; /* default gid for legacy support */ |
93 | u32 uid; /* if ACCESS_SINGLE, the uid that has access */ | 100 | u32 uid; /* if ACCESS_SINGLE, the uid that has access */ |
94 | struct p9_client *clnt; /* 9p client */ | 101 | struct p9_client *clnt; /* 9p client */ |
95 | struct dentry *debugfs_dir; | 102 | struct list_head slist; /* list of sessions registered with v9fs */ |
96 | }; | 103 | }; |
97 | 104 | ||
98 | extern struct dentry *v9fs_debugfs_root; | ||
99 | |||
100 | struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *, | 105 | struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *, |
101 | char *); | 106 | char *); |
102 | void v9fs_session_close(struct v9fs_session_info *v9ses); | 107 | void v9fs_session_close(struct v9fs_session_info *v9ses); |
diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h index f0c7de78e205..3a7560e35865 100644 --- a/fs/9p/v9fs_vfs.h +++ b/fs/9p/v9fs_vfs.h | |||
@@ -44,7 +44,13 @@ extern const struct file_operations v9fs_dir_operations; | |||
44 | extern const struct dentry_operations v9fs_dentry_operations; | 44 | extern const struct dentry_operations v9fs_dentry_operations; |
45 | extern const struct dentry_operations v9fs_cached_dentry_operations; | 45 | extern const struct dentry_operations v9fs_cached_dentry_operations; |
46 | 46 | ||
47 | #ifdef CONFIG_9P_FSCACHE | ||
48 | struct inode *v9fs_alloc_inode(struct super_block *sb); | ||
49 | void v9fs_destroy_inode(struct inode *inode); | ||
50 | #endif | ||
51 | |||
47 | struct inode *v9fs_get_inode(struct super_block *sb, int mode); | 52 | struct inode *v9fs_get_inode(struct super_block *sb, int mode); |
53 | void v9fs_clear_inode(struct inode *inode); | ||
48 | ino_t v9fs_qid2ino(struct p9_qid *qid); | 54 | ino_t v9fs_qid2ino(struct p9_qid *qid); |
49 | void v9fs_stat2inode(struct p9_wstat *, struct inode *, struct super_block *); | 55 | void v9fs_stat2inode(struct p9_wstat *, struct inode *, struct super_block *); |
50 | int v9fs_dir_release(struct inode *inode, struct file *filp); | 56 | int v9fs_dir_release(struct inode *inode, struct file *filp); |
diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c index 92828281a30b..90e38449f4b3 100644 --- a/fs/9p/vfs_addr.c +++ b/fs/9p/vfs_addr.c | |||
@@ -38,6 +38,7 @@ | |||
38 | 38 | ||
39 | #include "v9fs.h" | 39 | #include "v9fs.h" |
40 | #include "v9fs_vfs.h" | 40 | #include "v9fs_vfs.h" |
41 | #include "cache.h" | ||
41 | 42 | ||
42 | /** | 43 | /** |
43 | * v9fs_vfs_readpage - read an entire page in from 9P | 44 | * v9fs_vfs_readpage - read an entire page in from 9P |
@@ -52,18 +53,31 @@ static int v9fs_vfs_readpage(struct file *filp, struct page *page) | |||
52 | int retval; | 53 | int retval; |
53 | loff_t offset; | 54 | loff_t offset; |
54 | char *buffer; | 55 | char *buffer; |
56 | struct inode *inode; | ||
55 | 57 | ||
58 | inode = page->mapping->host; | ||
56 | P9_DPRINTK(P9_DEBUG_VFS, "\n"); | 59 | P9_DPRINTK(P9_DEBUG_VFS, "\n"); |
60 | |||
61 | BUG_ON(!PageLocked(page)); | ||
62 | |||
63 | retval = v9fs_readpage_from_fscache(inode, page); | ||
64 | if (retval == 0) | ||
65 | return retval; | ||
66 | |||
57 | buffer = kmap(page); | 67 | buffer = kmap(page); |
58 | offset = page_offset(page); | 68 | offset = page_offset(page); |
59 | 69 | ||
60 | retval = v9fs_file_readn(filp, buffer, NULL, PAGE_CACHE_SIZE, offset); | 70 | retval = v9fs_file_readn(filp, buffer, NULL, PAGE_CACHE_SIZE, offset); |
61 | if (retval < 0) | 71 | if (retval < 0) { |
72 | v9fs_uncache_page(inode, page); | ||
62 | goto done; | 73 | goto done; |
74 | } | ||
63 | 75 | ||
64 | memset(buffer + retval, 0, PAGE_CACHE_SIZE - retval); | 76 | memset(buffer + retval, 0, PAGE_CACHE_SIZE - retval); |
65 | flush_dcache_page(page); | 77 | flush_dcache_page(page); |
66 | SetPageUptodate(page); | 78 | SetPageUptodate(page); |
79 | |||
80 | v9fs_readpage_to_fscache(inode, page); | ||
67 | retval = 0; | 81 | retval = 0; |
68 | 82 | ||
69 | done: | 83 | done: |
@@ -72,6 +86,78 @@ done: | |||
72 | return retval; | 86 | return retval; |
73 | } | 87 | } |
74 | 88 | ||
89 | /** | ||
90 | * v9fs_vfs_readpages - read a set of pages from 9P | ||
91 | * | ||
92 | * @filp: file being read | ||
93 | * @mapping: the address space | ||
94 | * @pages: list of pages to read | ||
95 | * @nr_pages: count of pages to read | ||
96 | * | ||
97 | */ | ||
98 | |||
99 | static int v9fs_vfs_readpages(struct file *filp, struct address_space *mapping, | ||
100 | struct list_head *pages, unsigned nr_pages) | ||
101 | { | ||
102 | int ret = 0; | ||
103 | struct inode *inode; | ||
104 | |||
105 | inode = mapping->host; | ||
106 | P9_DPRINTK(P9_DEBUG_VFS, "inode: %p file: %p\n", inode, filp); | ||
107 | |||
108 | ret = v9fs_readpages_from_fscache(inode, mapping, pages, &nr_pages); | ||
109 | if (ret == 0) | ||
110 | return ret; | ||
111 | |||
112 | ret = read_cache_pages(mapping, pages, (void *)v9fs_vfs_readpage, filp); | ||
113 | P9_DPRINTK(P9_DEBUG_VFS, " = %d\n", ret); | ||
114 | return ret; | ||
115 | } | ||
116 | |||
117 | /** | ||
118 | * v9fs_release_page - release the private state associated with a page | ||
119 | * | ||
120 | * Returns 1 if the page can be released, false otherwise. | ||
121 | */ | ||
122 | |||
123 | static int v9fs_release_page(struct page *page, gfp_t gfp) | ||
124 | { | ||
125 | if (PagePrivate(page)) | ||
126 | return 0; | ||
127 | |||
128 | return v9fs_fscache_release_page(page, gfp); | ||
129 | } | ||
130 | |||
131 | /** | ||
132 | * v9fs_invalidate_page - Invalidate a page completely or partially | ||
133 | * | ||
134 | * @page: structure to page | ||
135 | * @offset: offset in the page | ||
136 | */ | ||
137 | |||
138 | static void v9fs_invalidate_page(struct page *page, unsigned long offset) | ||
139 | { | ||
140 | if (offset == 0) | ||
141 | v9fs_fscache_invalidate_page(page); | ||
142 | } | ||
143 | |||
144 | /** | ||
145 | * v9fs_launder_page - Writeback a dirty page | ||
146 | * Since the writes go directly to the server, we simply return a 0 | ||
147 | * here to indicate success. | ||
148 | * | ||
149 | * Returns 0 on success. | ||
150 | */ | ||
151 | |||
152 | static int v9fs_launder_page(struct page *page) | ||
153 | { | ||
154 | return 0; | ||
155 | } | ||
156 | |||
75 | const struct address_space_operations v9fs_addr_operations = { | 157 | const struct address_space_operations v9fs_addr_operations = { |
76 | .readpage = v9fs_vfs_readpage, | 158 | .readpage = v9fs_vfs_readpage, |
159 | .readpages = v9fs_vfs_readpages, | ||
160 | .releasepage = v9fs_release_page, | ||
161 | .invalidatepage = v9fs_invalidate_page, | ||
162 | .launder_page = v9fs_launder_page, | ||
77 | }; | 163 | }; |
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index 68bf2af6c389..3902bf43a088 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/string.h> | 32 | #include <linux/string.h> |
33 | #include <linux/inet.h> | 33 | #include <linux/inet.h> |
34 | #include <linux/list.h> | 34 | #include <linux/list.h> |
35 | #include <linux/pagemap.h> | ||
35 | #include <asm/uaccess.h> | 36 | #include <asm/uaccess.h> |
36 | #include <linux/idr.h> | 37 | #include <linux/idr.h> |
37 | #include <net/9p/9p.h> | 38 | #include <net/9p/9p.h> |
@@ -40,6 +41,7 @@ | |||
40 | #include "v9fs.h" | 41 | #include "v9fs.h" |
41 | #include "v9fs_vfs.h" | 42 | #include "v9fs_vfs.h" |
42 | #include "fid.h" | 43 | #include "fid.h" |
44 | #include "cache.h" | ||
43 | 45 | ||
44 | static const struct file_operations v9fs_cached_file_operations; | 46 | static const struct file_operations v9fs_cached_file_operations; |
45 | 47 | ||
@@ -72,7 +74,7 @@ int v9fs_file_open(struct inode *inode, struct file *file) | |||
72 | return err; | 74 | return err; |
73 | } | 75 | } |
74 | if (omode & P9_OTRUNC) { | 76 | if (omode & P9_OTRUNC) { |
75 | inode->i_size = 0; | 77 | i_size_write(inode, 0); |
76 | inode->i_blocks = 0; | 78 | inode->i_blocks = 0; |
77 | } | 79 | } |
78 | if ((file->f_flags & O_APPEND) && (!v9fs_extended(v9ses))) | 80 | if ((file->f_flags & O_APPEND) && (!v9fs_extended(v9ses))) |
@@ -85,6 +87,10 @@ int v9fs_file_open(struct inode *inode, struct file *file) | |||
85 | /* enable cached file options */ | 87 | /* enable cached file options */ |
86 | if(file->f_op == &v9fs_file_operations) | 88 | if(file->f_op == &v9fs_file_operations) |
87 | file->f_op = &v9fs_cached_file_operations; | 89 | file->f_op = &v9fs_cached_file_operations; |
90 | |||
91 | #ifdef CONFIG_9P_FSCACHE | ||
92 | v9fs_cache_inode_set_cookie(inode, file); | ||
93 | #endif | ||
88 | } | 94 | } |
89 | 95 | ||
90 | return 0; | 96 | return 0; |
@@ -210,6 +216,7 @@ v9fs_file_write(struct file *filp, const char __user * data, | |||
210 | struct p9_client *clnt; | 216 | struct p9_client *clnt; |
211 | struct inode *inode = filp->f_path.dentry->d_inode; | 217 | struct inode *inode = filp->f_path.dentry->d_inode; |
212 | int origin = *offset; | 218 | int origin = *offset; |
219 | unsigned long pg_start, pg_end; | ||
213 | 220 | ||
214 | P9_DPRINTK(P9_DEBUG_VFS, "data %p count %d offset %x\n", data, | 221 | P9_DPRINTK(P9_DEBUG_VFS, "data %p count %d offset %x\n", data, |
215 | (int)count, (int)*offset); | 222 | (int)count, (int)*offset); |
@@ -225,7 +232,7 @@ v9fs_file_write(struct file *filp, const char __user * data, | |||
225 | if (count < rsize) | 232 | if (count < rsize) |
226 | rsize = count; | 233 | rsize = count; |
227 | 234 | ||
228 | n = p9_client_write(fid, NULL, data+total, *offset+total, | 235 | n = p9_client_write(fid, NULL, data+total, origin+total, |
229 | rsize); | 236 | rsize); |
230 | if (n <= 0) | 237 | if (n <= 0) |
231 | break; | 238 | break; |
@@ -234,14 +241,14 @@ v9fs_file_write(struct file *filp, const char __user * data, | |||
234 | } while (count > 0); | 241 | } while (count > 0); |
235 | 242 | ||
236 | if (total > 0) { | 243 | if (total > 0) { |
237 | invalidate_inode_pages2_range(inode->i_mapping, origin, | 244 | pg_start = origin >> PAGE_CACHE_SHIFT; |
238 | origin+total); | 245 | pg_end = (origin + total - 1) >> PAGE_CACHE_SHIFT; |
246 | if (inode->i_mapping && inode->i_mapping->nrpages) | ||
247 | invalidate_inode_pages2_range(inode->i_mapping, | ||
248 | pg_start, pg_end); | ||
239 | *offset += total; | 249 | *offset += total; |
240 | } | 250 | i_size_write(inode, i_size_read(inode) + total); |
241 | 251 | inode->i_blocks = (i_size_read(inode) + 512 - 1) >> 9; | |
242 | if (*offset > inode->i_size) { | ||
243 | inode->i_size = *offset; | ||
244 | inode->i_blocks = (inode->i_size + 512 - 1) >> 9; | ||
245 | } | 252 | } |
246 | 253 | ||
247 | if (n < 0) | 254 | if (n < 0) |
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 06a223d50a81..5947628aefef 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include "v9fs.h" | 40 | #include "v9fs.h" |
41 | #include "v9fs_vfs.h" | 41 | #include "v9fs_vfs.h" |
42 | #include "fid.h" | 42 | #include "fid.h" |
43 | #include "cache.h" | ||
43 | 44 | ||
44 | static const struct inode_operations v9fs_dir_inode_operations; | 45 | static const struct inode_operations v9fs_dir_inode_operations; |
45 | static const struct inode_operations v9fs_dir_inode_operations_ext; | 46 | static const struct inode_operations v9fs_dir_inode_operations_ext; |
@@ -197,6 +198,39 @@ v9fs_blank_wstat(struct p9_wstat *wstat) | |||
197 | wstat->extension = NULL; | 198 | wstat->extension = NULL; |
198 | } | 199 | } |
199 | 200 | ||
201 | #ifdef CONFIG_9P_FSCACHE | ||
202 | /** | ||
203 | * v9fs_alloc_inode - helper function to allocate an inode | ||
204 | * This callback is executed before setting up the inode so that we | ||
205 | * can associate a vcookie with each inode. | ||
206 | * | ||
207 | */ | ||
208 | |||
209 | struct inode *v9fs_alloc_inode(struct super_block *sb) | ||
210 | { | ||
211 | struct v9fs_cookie *vcookie; | ||
212 | vcookie = (struct v9fs_cookie *)kmem_cache_alloc(vcookie_cache, | ||
213 | GFP_KERNEL); | ||
214 | if (!vcookie) | ||
215 | return NULL; | ||
216 | |||
217 | vcookie->fscache = NULL; | ||
218 | vcookie->qid = NULL; | ||
219 | spin_lock_init(&vcookie->lock); | ||
220 | return &vcookie->inode; | ||
221 | } | ||
222 | |||
223 | /** | ||
224 | * v9fs_destroy_inode - destroy an inode | ||
225 | * | ||
226 | */ | ||
227 | |||
228 | void v9fs_destroy_inode(struct inode *inode) | ||
229 | { | ||
230 | kmem_cache_free(vcookie_cache, v9fs_inode2cookie(inode)); | ||
231 | } | ||
232 | #endif | ||
233 | |||
200 | /** | 234 | /** |
201 | * v9fs_get_inode - helper function to setup an inode | 235 | * v9fs_get_inode - helper function to setup an inode |
202 | * @sb: superblock | 236 | * @sb: superblock |
@@ -326,6 +360,21 @@ error: | |||
326 | } | 360 | } |
327 | */ | 361 | */ |
328 | 362 | ||
363 | |||
364 | /** | ||
365 | * v9fs_clear_inode - release an inode | ||
366 | * @inode: inode to release | ||
367 | * | ||
368 | */ | ||
369 | void v9fs_clear_inode(struct inode *inode) | ||
370 | { | ||
371 | filemap_fdatawrite(inode->i_mapping); | ||
372 | |||
373 | #ifdef CONFIG_9P_FSCACHE | ||
374 | v9fs_cache_inode_put_cookie(inode); | ||
375 | #endif | ||
376 | } | ||
377 | |||
329 | /** | 378 | /** |
330 | * v9fs_inode_from_fid - populate an inode by issuing a attribute request | 379 | * v9fs_inode_from_fid - populate an inode by issuing a attribute request |
331 | * @v9ses: session information | 380 | * @v9ses: session information |
@@ -356,8 +405,14 @@ v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, | |||
356 | 405 | ||
357 | v9fs_stat2inode(st, ret, sb); | 406 | v9fs_stat2inode(st, ret, sb); |
358 | ret->i_ino = v9fs_qid2ino(&st->qid); | 407 | ret->i_ino = v9fs_qid2ino(&st->qid); |
408 | |||
409 | #ifdef CONFIG_9P_FSCACHE | ||
410 | v9fs_vcookie_set_qid(ret, &st->qid); | ||
411 | v9fs_cache_inode_get_cookie(ret); | ||
412 | #endif | ||
359 | p9stat_free(st); | 413 | p9stat_free(st); |
360 | kfree(st); | 414 | kfree(st); |
415 | |||
361 | return ret; | 416 | return ret; |
362 | 417 | ||
363 | error: | 418 | error: |
@@ -751,7 +806,7 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, | |||
751 | P9_DPRINTK(P9_DEBUG_VFS, "dentry: %p\n", dentry); | 806 | P9_DPRINTK(P9_DEBUG_VFS, "dentry: %p\n", dentry); |
752 | err = -EPERM; | 807 | err = -EPERM; |
753 | v9ses = v9fs_inode2v9ses(dentry->d_inode); | 808 | v9ses = v9fs_inode2v9ses(dentry->d_inode); |
754 | if (v9ses->cache == CACHE_LOOSE) | 809 | if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) |
755 | return simple_getattr(mnt, dentry, stat); | 810 | return simple_getattr(mnt, dentry, stat); |
756 | 811 | ||
757 | fid = v9fs_fid_lookup(dentry); | 812 | fid = v9fs_fid_lookup(dentry); |
@@ -872,10 +927,10 @@ v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode, | |||
872 | } else | 927 | } else |
873 | inode->i_rdev = 0; | 928 | inode->i_rdev = 0; |
874 | 929 | ||
875 | inode->i_size = stat->length; | 930 | i_size_write(inode, stat->length); |
876 | 931 | ||
877 | /* not real number of blocks, but 512 byte ones ... */ | 932 | /* not real number of blocks, but 512 byte ones ... */ |
878 | inode->i_blocks = (inode->i_size + 512 - 1) >> 9; | 933 | inode->i_blocks = (i_size_read(inode) + 512 - 1) >> 9; |
879 | } | 934 | } |
880 | 935 | ||
881 | /** | 936 | /** |
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index 8961f1a8f668..14a86448572c 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c | |||
@@ -44,21 +44,9 @@ | |||
44 | #include "v9fs_vfs.h" | 44 | #include "v9fs_vfs.h" |
45 | #include "fid.h" | 45 | #include "fid.h" |
46 | 46 | ||
47 | static void v9fs_clear_inode(struct inode *); | ||
48 | static const struct super_operations v9fs_super_ops; | 47 | static const struct super_operations v9fs_super_ops; |
49 | 48 | ||
50 | /** | 49 | /** |
51 | * v9fs_clear_inode - release an inode | ||
52 | * @inode: inode to release | ||
53 | * | ||
54 | */ | ||
55 | |||
56 | static void v9fs_clear_inode(struct inode *inode) | ||
57 | { | ||
58 | filemap_fdatawrite(inode->i_mapping); | ||
59 | } | ||
60 | |||
61 | /** | ||
62 | * v9fs_set_super - set the superblock | 50 | * v9fs_set_super - set the superblock |
63 | * @s: super block | 51 | * @s: super block |
64 | * @data: file system specific data | 52 | * @data: file system specific data |
@@ -220,6 +208,10 @@ v9fs_umount_begin(struct super_block *sb) | |||
220 | } | 208 | } |
221 | 209 | ||
222 | static const struct super_operations v9fs_super_ops = { | 210 | static const struct super_operations v9fs_super_ops = { |
211 | #ifdef CONFIG_9P_FSCACHE | ||
212 | .alloc_inode = v9fs_alloc_inode, | ||
213 | .destroy_inode = v9fs_destroy_inode, | ||
214 | #endif | ||
223 | .statfs = simple_statfs, | 215 | .statfs = simple_statfs, |
224 | .clear_inode = v9fs_clear_inode, | 216 | .clear_inode = v9fs_clear_inode, |
225 | .show_options = generic_show_options, | 217 | .show_options = generic_show_options, |
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c index c3ac18054057..247436c10deb 100644 --- a/fs/gfs2/ops_inode.c +++ b/fs/gfs2/ops_inode.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <linux/completion.h> | 12 | #include <linux/completion.h> |
13 | #include <linux/buffer_head.h> | 13 | #include <linux/buffer_head.h> |
14 | #include <linux/namei.h> | 14 | #include <linux/namei.h> |
15 | #include <linux/utsname.h> | ||
16 | #include <linux/mm.h> | 15 | #include <linux/mm.h> |
17 | #include <linux/xattr.h> | 16 | #include <linux/xattr.h> |
18 | #include <linux/posix_acl.h> | 17 | #include <linux/posix_acl.h> |
diff --git a/fs/lockd/xdr.c b/fs/lockd/xdr.c index 0336f2beacde..b583ab0a4cbb 100644 --- a/fs/lockd/xdr.c +++ b/fs/lockd/xdr.c | |||
@@ -8,7 +8,6 @@ | |||
8 | 8 | ||
9 | #include <linux/types.h> | 9 | #include <linux/types.h> |
10 | #include <linux/sched.h> | 10 | #include <linux/sched.h> |
11 | #include <linux/utsname.h> | ||
12 | #include <linux/nfs.h> | 11 | #include <linux/nfs.h> |
13 | 12 | ||
14 | #include <linux/sunrpc/xdr.h> | 13 | #include <linux/sunrpc/xdr.h> |
diff --git a/fs/lockd/xdr4.c b/fs/lockd/xdr4.c index e1d528653192..ad9dbbc9145d 100644 --- a/fs/lockd/xdr4.c +++ b/fs/lockd/xdr4.c | |||
@@ -9,7 +9,6 @@ | |||
9 | 9 | ||
10 | #include <linux/types.h> | 10 | #include <linux/types.h> |
11 | #include <linux/sched.h> | 11 | #include <linux/sched.h> |
12 | #include <linux/utsname.h> | ||
13 | #include <linux/nfs.h> | 12 | #include <linux/nfs.h> |
14 | 13 | ||
15 | #include <linux/sunrpc/xdr.h> | 14 | #include <linux/sunrpc/xdr.h> |
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 152025358dad..63976c0ccc25 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -648,8 +648,6 @@ static int nfs_start_lockd(struct nfs_server *server) | |||
648 | .hostname = clp->cl_hostname, | 648 | .hostname = clp->cl_hostname, |
649 | .address = (struct sockaddr *)&clp->cl_addr, | 649 | .address = (struct sockaddr *)&clp->cl_addr, |
650 | .addrlen = clp->cl_addrlen, | 650 | .addrlen = clp->cl_addrlen, |
651 | .protocol = server->flags & NFS_MOUNT_TCP ? | ||
652 | IPPROTO_TCP : IPPROTO_UDP, | ||
653 | .nfs_version = clp->rpc_ops->version, | 651 | .nfs_version = clp->rpc_ops->version, |
654 | .noresvport = server->flags & NFS_MOUNT_NORESVPORT ? | 652 | .noresvport = server->flags & NFS_MOUNT_NORESVPORT ? |
655 | 1 : 0, | 653 | 1 : 0, |
@@ -660,6 +658,14 @@ static int nfs_start_lockd(struct nfs_server *server) | |||
660 | if (server->flags & NFS_MOUNT_NONLM) | 658 | if (server->flags & NFS_MOUNT_NONLM) |
661 | return 0; | 659 | return 0; |
662 | 660 | ||
661 | switch (clp->cl_proto) { | ||
662 | default: | ||
663 | nlm_init.protocol = IPPROTO_TCP; | ||
664 | break; | ||
665 | case XPRT_TRANSPORT_UDP: | ||
666 | nlm_init.protocol = IPPROTO_UDP; | ||
667 | } | ||
668 | |||
663 | host = nlmclnt_init(&nlm_init); | 669 | host = nlmclnt_init(&nlm_init); |
664 | if (IS_ERR(host)) | 670 | if (IS_ERR(host)) |
665 | return PTR_ERR(host); | 671 | return PTR_ERR(host); |
@@ -787,7 +793,7 @@ static int nfs_init_server(struct nfs_server *server, | |||
787 | dprintk("--> nfs_init_server()\n"); | 793 | dprintk("--> nfs_init_server()\n"); |
788 | 794 | ||
789 | #ifdef CONFIG_NFS_V3 | 795 | #ifdef CONFIG_NFS_V3 |
790 | if (data->flags & NFS_MOUNT_VER3) | 796 | if (data->version == 3) |
791 | cl_init.rpc_ops = &nfs_v3_clientops; | 797 | cl_init.rpc_ops = &nfs_v3_clientops; |
792 | #endif | 798 | #endif |
793 | 799 | ||
@@ -964,6 +970,7 @@ static void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_serve | |||
964 | target->acdirmin = source->acdirmin; | 970 | target->acdirmin = source->acdirmin; |
965 | target->acdirmax = source->acdirmax; | 971 | target->acdirmax = source->acdirmax; |
966 | target->caps = source->caps; | 972 | target->caps = source->caps; |
973 | target->options = source->options; | ||
967 | } | 974 | } |
968 | 975 | ||
969 | /* | 976 | /* |
diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c index 379be678cb7e..70fad69eb959 100644 --- a/fs/nfs/fscache.c +++ b/fs/nfs/fscache.c | |||
@@ -58,17 +58,34 @@ void nfs_fscache_release_client_cookie(struct nfs_client *clp) | |||
58 | /* | 58 | /* |
59 | * Get the cache cookie for an NFS superblock. We have to handle | 59 | * Get the cache cookie for an NFS superblock. We have to handle |
60 | * uniquification here because the cache doesn't do it for us. | 60 | * uniquification here because the cache doesn't do it for us. |
61 | * | ||
62 | * The default uniquifier is just an empty string, but it may be overridden | ||
63 | * either by the 'fsc=xxx' option to mount, or by inheriting it from the parent | ||
64 | * superblock across an automount point of some nature. | ||
61 | */ | 65 | */ |
62 | void nfs_fscache_get_super_cookie(struct super_block *sb, | 66 | void nfs_fscache_get_super_cookie(struct super_block *sb, const char *uniq, |
63 | struct nfs_parsed_mount_data *data) | 67 | struct nfs_clone_mount *mntdata) |
64 | { | 68 | { |
65 | struct nfs_fscache_key *key, *xkey; | 69 | struct nfs_fscache_key *key, *xkey; |
66 | struct nfs_server *nfss = NFS_SB(sb); | 70 | struct nfs_server *nfss = NFS_SB(sb); |
67 | struct rb_node **p, *parent; | 71 | struct rb_node **p, *parent; |
68 | const char *uniq = data->fscache_uniq ?: ""; | ||
69 | int diff, ulen; | 72 | int diff, ulen; |
70 | 73 | ||
71 | ulen = strlen(uniq); | 74 | if (uniq) { |
75 | ulen = strlen(uniq); | ||
76 | } else if (mntdata) { | ||
77 | struct nfs_server *mnt_s = NFS_SB(mntdata->sb); | ||
78 | if (mnt_s->fscache_key) { | ||
79 | uniq = mnt_s->fscache_key->key.uniquifier; | ||
80 | ulen = mnt_s->fscache_key->key.uniq_len; | ||
81 | } | ||
82 | } | ||
83 | |||
84 | if (!uniq) { | ||
85 | uniq = ""; | ||
86 | ulen = 1; | ||
87 | } | ||
88 | |||
72 | key = kzalloc(sizeof(*key) + ulen, GFP_KERNEL); | 89 | key = kzalloc(sizeof(*key) + ulen, GFP_KERNEL); |
73 | if (!key) | 90 | if (!key) |
74 | return; | 91 | return; |
diff --git a/fs/nfs/fscache.h b/fs/nfs/fscache.h index 6e809bb0ff08..b9c572d0679f 100644 --- a/fs/nfs/fscache.h +++ b/fs/nfs/fscache.h | |||
@@ -74,7 +74,8 @@ extern void nfs_fscache_get_client_cookie(struct nfs_client *); | |||
74 | extern void nfs_fscache_release_client_cookie(struct nfs_client *); | 74 | extern void nfs_fscache_release_client_cookie(struct nfs_client *); |
75 | 75 | ||
76 | extern void nfs_fscache_get_super_cookie(struct super_block *, | 76 | extern void nfs_fscache_get_super_cookie(struct super_block *, |
77 | struct nfs_parsed_mount_data *); | 77 | const char *, |
78 | struct nfs_clone_mount *); | ||
78 | extern void nfs_fscache_release_super_cookie(struct super_block *); | 79 | extern void nfs_fscache_release_super_cookie(struct super_block *); |
79 | 80 | ||
80 | extern void nfs_fscache_init_inode_cookie(struct inode *); | 81 | extern void nfs_fscache_init_inode_cookie(struct inode *); |
@@ -173,7 +174,8 @@ static inline void nfs_fscache_release_client_cookie(struct nfs_client *clp) {} | |||
173 | 174 | ||
174 | static inline void nfs_fscache_get_super_cookie( | 175 | static inline void nfs_fscache_get_super_cookie( |
175 | struct super_block *sb, | 176 | struct super_block *sb, |
176 | struct nfs_parsed_mount_data *data) | 177 | const char *uniq, |
178 | struct nfs_clone_mount *mntdata) | ||
177 | { | 179 | { |
178 | } | 180 | } |
179 | static inline void nfs_fscache_release_super_cookie(struct super_block *sb) {} | 181 | static inline void nfs_fscache_release_super_cookie(struct super_block *sb) {} |
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index c862c9340f9a..5e078b222b4e 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/time.h> | 13 | #include <linux/time.h> |
14 | #include <linux/mm.h> | 14 | #include <linux/mm.h> |
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/utsname.h> | ||
17 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
18 | #include <linux/string.h> | 17 | #include <linux/string.h> |
19 | #include <linux/in.h> | 18 | #include <linux/in.h> |
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index ee6a13f05443..3f8881d1a050 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c | |||
@@ -7,7 +7,6 @@ | |||
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/mm.h> | 9 | #include <linux/mm.h> |
10 | #include <linux/utsname.h> | ||
11 | #include <linux/errno.h> | 10 | #include <linux/errno.h> |
12 | #include <linux/string.h> | 11 | #include <linux/string.h> |
13 | #include <linux/sunrpc/clnt.h> | 12 | #include <linux/sunrpc/clnt.h> |
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index 35869a4921f1..5fe5492fbd29 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c | |||
@@ -10,7 +10,6 @@ | |||
10 | #include <linux/time.h> | 10 | #include <linux/time.h> |
11 | #include <linux/mm.h> | 11 | #include <linux/mm.h> |
12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
13 | #include <linux/utsname.h> | ||
14 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
15 | #include <linux/string.h> | 14 | #include <linux/string.h> |
16 | #include <linux/in.h> | 15 | #include <linux/in.h> |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index be6544aef41f..ed7c269e2514 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -36,7 +36,6 @@ | |||
36 | */ | 36 | */ |
37 | 37 | ||
38 | #include <linux/mm.h> | 38 | #include <linux/mm.h> |
39 | #include <linux/utsname.h> | ||
40 | #include <linux/delay.h> | 39 | #include <linux/delay.h> |
41 | #include <linux/errno.h> | 40 | #include <linux/errno.h> |
42 | #include <linux/string.h> | 41 | #include <linux/string.h> |
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index cfc30d362f94..83ad47cbdd8a 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -39,7 +39,6 @@ | |||
39 | #include <linux/time.h> | 39 | #include <linux/time.h> |
40 | #include <linux/mm.h> | 40 | #include <linux/mm.h> |
41 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
42 | #include <linux/utsname.h> | ||
43 | #include <linux/errno.h> | 42 | #include <linux/errno.h> |
44 | #include <linux/string.h> | 43 | #include <linux/string.h> |
45 | #include <linux/in.h> | 44 | #include <linux/in.h> |
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index 7be72d90d49d..ef583854d8d0 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/time.h> | 33 | #include <linux/time.h> |
34 | #include <linux/mm.h> | 34 | #include <linux/mm.h> |
35 | #include <linux/utsname.h> | ||
36 | #include <linux/errno.h> | 35 | #include <linux/errno.h> |
37 | #include <linux/string.h> | 36 | #include <linux/string.h> |
38 | #include <linux/in.h> | 37 | #include <linux/in.h> |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index f1cc0587cfef..810770f96816 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -728,6 +728,27 @@ static void nfs_umount_begin(struct super_block *sb) | |||
728 | unlock_kernel(); | 728 | unlock_kernel(); |
729 | } | 729 | } |
730 | 730 | ||
731 | static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(int flags) | ||
732 | { | ||
733 | struct nfs_parsed_mount_data *data; | ||
734 | |||
735 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
736 | if (data) { | ||
737 | data->flags = flags; | ||
738 | data->rsize = NFS_MAX_FILE_IO_SIZE; | ||
739 | data->wsize = NFS_MAX_FILE_IO_SIZE; | ||
740 | data->acregmin = NFS_DEF_ACREGMIN; | ||
741 | data->acregmax = NFS_DEF_ACREGMAX; | ||
742 | data->acdirmin = NFS_DEF_ACDIRMIN; | ||
743 | data->acdirmax = NFS_DEF_ACDIRMAX; | ||
744 | data->nfs_server.port = NFS_UNSPEC_PORT; | ||
745 | data->auth_flavors[0] = RPC_AUTH_UNIX; | ||
746 | data->auth_flavor_len = 1; | ||
747 | data->minorversion = 0; | ||
748 | } | ||
749 | return data; | ||
750 | } | ||
751 | |||
731 | /* | 752 | /* |
732 | * Sanity-check a server address provided by the mount command. | 753 | * Sanity-check a server address provided by the mount command. |
733 | * | 754 | * |
@@ -1430,10 +1451,13 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args, | |||
1430 | int status; | 1451 | int status; |
1431 | 1452 | ||
1432 | if (args->mount_server.version == 0) { | 1453 | if (args->mount_server.version == 0) { |
1433 | if (args->flags & NFS_MOUNT_VER3) | 1454 | switch (args->version) { |
1434 | args->mount_server.version = NFS_MNT3_VERSION; | 1455 | default: |
1435 | else | 1456 | args->mount_server.version = NFS_MNT3_VERSION; |
1436 | args->mount_server.version = NFS_MNT_VERSION; | 1457 | break; |
1458 | case 2: | ||
1459 | args->mount_server.version = NFS_MNT_VERSION; | ||
1460 | } | ||
1437 | } | 1461 | } |
1438 | request.version = args->mount_server.version; | 1462 | request.version = args->mount_server.version; |
1439 | 1463 | ||
@@ -1634,20 +1658,6 @@ static int nfs_validate_mount_data(void *options, | |||
1634 | if (data == NULL) | 1658 | if (data == NULL) |
1635 | goto out_no_data; | 1659 | goto out_no_data; |
1636 | 1660 | ||
1637 | args->flags = (NFS_MOUNT_VER3 | NFS_MOUNT_TCP); | ||
1638 | args->rsize = NFS_MAX_FILE_IO_SIZE; | ||
1639 | args->wsize = NFS_MAX_FILE_IO_SIZE; | ||
1640 | args->acregmin = NFS_DEF_ACREGMIN; | ||
1641 | args->acregmax = NFS_DEF_ACREGMAX; | ||
1642 | args->acdirmin = NFS_DEF_ACDIRMIN; | ||
1643 | args->acdirmax = NFS_DEF_ACDIRMAX; | ||
1644 | args->mount_server.port = NFS_UNSPEC_PORT; | ||
1645 | args->nfs_server.port = NFS_UNSPEC_PORT; | ||
1646 | args->nfs_server.protocol = XPRT_TRANSPORT_TCP; | ||
1647 | args->auth_flavors[0] = RPC_AUTH_UNIX; | ||
1648 | args->auth_flavor_len = 1; | ||
1649 | args->minorversion = 0; | ||
1650 | |||
1651 | switch (data->version) { | 1661 | switch (data->version) { |
1652 | case 1: | 1662 | case 1: |
1653 | data->namlen = 0; | 1663 | data->namlen = 0; |
@@ -1778,7 +1788,7 @@ static int nfs_validate_mount_data(void *options, | |||
1778 | } | 1788 | } |
1779 | 1789 | ||
1780 | #ifndef CONFIG_NFS_V3 | 1790 | #ifndef CONFIG_NFS_V3 |
1781 | if (args->flags & NFS_MOUNT_VER3) | 1791 | if (args->version == 3) |
1782 | goto out_v3_not_compiled; | 1792 | goto out_v3_not_compiled; |
1783 | #endif /* !CONFIG_NFS_V3 */ | 1793 | #endif /* !CONFIG_NFS_V3 */ |
1784 | 1794 | ||
@@ -1936,7 +1946,7 @@ static void nfs_fill_super(struct super_block *sb, | |||
1936 | if (data->bsize) | 1946 | if (data->bsize) |
1937 | sb->s_blocksize = nfs_block_size(data->bsize, &sb->s_blocksize_bits); | 1947 | sb->s_blocksize = nfs_block_size(data->bsize, &sb->s_blocksize_bits); |
1938 | 1948 | ||
1939 | if (server->flags & NFS_MOUNT_VER3) { | 1949 | if (server->nfs_client->rpc_ops->version == 3) { |
1940 | /* The VFS shouldn't apply the umask to mode bits. We will do | 1950 | /* The VFS shouldn't apply the umask to mode bits. We will do |
1941 | * so ourselves when necessary. | 1951 | * so ourselves when necessary. |
1942 | */ | 1952 | */ |
@@ -1960,7 +1970,7 @@ static void nfs_clone_super(struct super_block *sb, | |||
1960 | sb->s_blocksize = old_sb->s_blocksize; | 1970 | sb->s_blocksize = old_sb->s_blocksize; |
1961 | sb->s_maxbytes = old_sb->s_maxbytes; | 1971 | sb->s_maxbytes = old_sb->s_maxbytes; |
1962 | 1972 | ||
1963 | if (server->flags & NFS_MOUNT_VER3) { | 1973 | if (server->nfs_client->rpc_ops->version == 3) { |
1964 | /* The VFS shouldn't apply the umask to mode bits. We will do | 1974 | /* The VFS shouldn't apply the umask to mode bits. We will do |
1965 | * so ourselves when necessary. | 1975 | * so ourselves when necessary. |
1966 | */ | 1976 | */ |
@@ -2094,7 +2104,7 @@ static int nfs_get_sb(struct file_system_type *fs_type, | |||
2094 | }; | 2104 | }; |
2095 | int error = -ENOMEM; | 2105 | int error = -ENOMEM; |
2096 | 2106 | ||
2097 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 2107 | data = nfs_alloc_parsed_mount_data(NFS_MOUNT_VER3 | NFS_MOUNT_TCP); |
2098 | mntfh = kzalloc(sizeof(*mntfh), GFP_KERNEL); | 2108 | mntfh = kzalloc(sizeof(*mntfh), GFP_KERNEL); |
2099 | if (data == NULL || mntfh == NULL) | 2109 | if (data == NULL || mntfh == NULL) |
2100 | goto out_free_fh; | 2110 | goto out_free_fh; |
@@ -2144,7 +2154,8 @@ static int nfs_get_sb(struct file_system_type *fs_type, | |||
2144 | if (!s->s_root) { | 2154 | if (!s->s_root) { |
2145 | /* initial superblock/root creation */ | 2155 | /* initial superblock/root creation */ |
2146 | nfs_fill_super(s, data); | 2156 | nfs_fill_super(s, data); |
2147 | nfs_fscache_get_super_cookie(s, data); | 2157 | nfs_fscache_get_super_cookie( |
2158 | s, data ? data->fscache_uniq : NULL, NULL); | ||
2148 | } | 2159 | } |
2149 | 2160 | ||
2150 | mntroot = nfs_get_root(s, mntfh); | 2161 | mntroot = nfs_get_root(s, mntfh); |
@@ -2245,6 +2256,7 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags, | |||
2245 | if (!s->s_root) { | 2256 | if (!s->s_root) { |
2246 | /* initial superblock/root creation */ | 2257 | /* initial superblock/root creation */ |
2247 | nfs_clone_super(s, data->sb); | 2258 | nfs_clone_super(s, data->sb); |
2259 | nfs_fscache_get_super_cookie(s, NULL, data); | ||
2248 | } | 2260 | } |
2249 | 2261 | ||
2250 | mntroot = nfs_get_root(s, data->fh); | 2262 | mntroot = nfs_get_root(s, data->fh); |
@@ -2362,18 +2374,7 @@ static int nfs4_validate_mount_data(void *options, | |||
2362 | if (data == NULL) | 2374 | if (data == NULL) |
2363 | goto out_no_data; | 2375 | goto out_no_data; |
2364 | 2376 | ||
2365 | args->rsize = NFS_MAX_FILE_IO_SIZE; | ||
2366 | args->wsize = NFS_MAX_FILE_IO_SIZE; | ||
2367 | args->acregmin = NFS_DEF_ACREGMIN; | ||
2368 | args->acregmax = NFS_DEF_ACREGMAX; | ||
2369 | args->acdirmin = NFS_DEF_ACDIRMIN; | ||
2370 | args->acdirmax = NFS_DEF_ACDIRMAX; | ||
2371 | args->nfs_server.port = NFS_UNSPEC_PORT; | ||
2372 | args->auth_flavors[0] = RPC_AUTH_UNIX; | ||
2373 | args->auth_flavor_len = 1; | ||
2374 | args->version = 4; | 2377 | args->version = 4; |
2375 | args->minorversion = 0; | ||
2376 | |||
2377 | switch (data->version) { | 2378 | switch (data->version) { |
2378 | case 1: | 2379 | case 1: |
2379 | if (data->host_addrlen > sizeof(args->nfs_server.address)) | 2380 | if (data->host_addrlen > sizeof(args->nfs_server.address)) |
@@ -2508,7 +2509,8 @@ static int nfs4_remote_get_sb(struct file_system_type *fs_type, | |||
2508 | if (!s->s_root) { | 2509 | if (!s->s_root) { |
2509 | /* initial superblock/root creation */ | 2510 | /* initial superblock/root creation */ |
2510 | nfs4_fill_super(s); | 2511 | nfs4_fill_super(s); |
2511 | nfs_fscache_get_super_cookie(s, data); | 2512 | nfs_fscache_get_super_cookie( |
2513 | s, data ? data->fscache_uniq : NULL, NULL); | ||
2512 | } | 2514 | } |
2513 | 2515 | ||
2514 | mntroot = nfs4_get_root(s, mntfh); | 2516 | mntroot = nfs4_get_root(s, mntfh); |
@@ -2656,7 +2658,7 @@ static int nfs4_get_sb(struct file_system_type *fs_type, | |||
2656 | struct nfs_parsed_mount_data *data; | 2658 | struct nfs_parsed_mount_data *data; |
2657 | int error = -ENOMEM; | 2659 | int error = -ENOMEM; |
2658 | 2660 | ||
2659 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 2661 | data = nfs_alloc_parsed_mount_data(0); |
2660 | if (data == NULL) | 2662 | if (data == NULL) |
2661 | goto out_free_data; | 2663 | goto out_free_data; |
2662 | 2664 | ||
@@ -2741,6 +2743,7 @@ static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags, | |||
2741 | if (!s->s_root) { | 2743 | if (!s->s_root) { |
2742 | /* initial superblock/root creation */ | 2744 | /* initial superblock/root creation */ |
2743 | nfs4_clone_super(s, data->sb); | 2745 | nfs4_clone_super(s, data->sb); |
2746 | nfs_fscache_get_super_cookie(s, NULL, data); | ||
2744 | } | 2747 | } |
2745 | 2748 | ||
2746 | mntroot = nfs4_get_root(s, data->fh); | 2749 | mntroot = nfs4_get_root(s, data->fh); |
@@ -2822,6 +2825,7 @@ static int nfs4_remote_referral_get_sb(struct file_system_type *fs_type, | |||
2822 | if (!s->s_root) { | 2825 | if (!s->s_root) { |
2823 | /* initial superblock/root creation */ | 2826 | /* initial superblock/root creation */ |
2824 | nfs4_fill_super(s); | 2827 | nfs4_fill_super(s); |
2828 | nfs_fscache_get_super_cookie(s, NULL, data); | ||
2825 | } | 2829 | } |
2826 | 2830 | ||
2827 | mntroot = nfs4_get_root(s, &mntfh); | 2831 | mntroot = nfs4_get_root(s, &mntfh); |
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c index cdfa86fa1471..ba2c199592fd 100644 --- a/fs/nfsd/nfs4idmap.c +++ b/fs/nfsd/nfs4idmap.c | |||
@@ -38,7 +38,6 @@ | |||
38 | #include <linux/init.h> | 38 | #include <linux/init.h> |
39 | 39 | ||
40 | #include <linux/mm.h> | 40 | #include <linux/mm.h> |
41 | #include <linux/utsname.h> | ||
42 | #include <linux/errno.h> | 41 | #include <linux/errno.h> |
43 | #include <linux/string.h> | 42 | #include <linux/string.h> |
44 | #include <linux/sunrpc/clnt.h> | 43 | #include <linux/sunrpc/clnt.h> |
diff --git a/fs/ocfs2/dlm/dlmast.c b/fs/ocfs2/dlm/dlmast.c index 81eff8e58322..01cf8cc3d286 100644 --- a/fs/ocfs2/dlm/dlmast.c +++ b/fs/ocfs2/dlm/dlmast.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/types.h> | 30 | #include <linux/types.h> |
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
32 | #include <linux/highmem.h> | 32 | #include <linux/highmem.h> |
33 | #include <linux/utsname.h> | ||
34 | #include <linux/init.h> | 33 | #include <linux/init.h> |
35 | #include <linux/sysctl.h> | 34 | #include <linux/sysctl.h> |
36 | #include <linux/random.h> | 35 | #include <linux/random.h> |
diff --git a/fs/ocfs2/dlm/dlmconvert.c b/fs/ocfs2/dlm/dlmconvert.c index 75997b4deaf3..ca96bce50e18 100644 --- a/fs/ocfs2/dlm/dlmconvert.c +++ b/fs/ocfs2/dlm/dlmconvert.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/types.h> | 30 | #include <linux/types.h> |
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
32 | #include <linux/highmem.h> | 32 | #include <linux/highmem.h> |
33 | #include <linux/utsname.h> | ||
34 | #include <linux/init.h> | 33 | #include <linux/init.h> |
35 | #include <linux/sysctl.h> | 34 | #include <linux/sysctl.h> |
36 | #include <linux/random.h> | 35 | #include <linux/random.h> |
diff --git a/fs/ocfs2/dlm/dlmdebug.c b/fs/ocfs2/dlm/dlmdebug.c index c5c88124096d..ca46002ec10e 100644 --- a/fs/ocfs2/dlm/dlmdebug.c +++ b/fs/ocfs2/dlm/dlmdebug.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/types.h> | 27 | #include <linux/types.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/highmem.h> | 29 | #include <linux/highmem.h> |
30 | #include <linux/utsname.h> | ||
31 | #include <linux/sysctl.h> | 30 | #include <linux/sysctl.h> |
32 | #include <linux/spinlock.h> | 31 | #include <linux/spinlock.h> |
33 | #include <linux/debugfs.h> | 32 | #include <linux/debugfs.h> |
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c index 4d9e6b288dd8..0334000676d3 100644 --- a/fs/ocfs2/dlm/dlmdomain.c +++ b/fs/ocfs2/dlm/dlmdomain.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/types.h> | 28 | #include <linux/types.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/highmem.h> | 30 | #include <linux/highmem.h> |
31 | #include <linux/utsname.h> | ||
32 | #include <linux/init.h> | 31 | #include <linux/init.h> |
33 | #include <linux/spinlock.h> | 32 | #include <linux/spinlock.h> |
34 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
diff --git a/fs/ocfs2/dlm/dlmlock.c b/fs/ocfs2/dlm/dlmlock.c index 83a9f2972ac8..437698e9465f 100644 --- a/fs/ocfs2/dlm/dlmlock.c +++ b/fs/ocfs2/dlm/dlmlock.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/types.h> | 30 | #include <linux/types.h> |
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
32 | #include <linux/highmem.h> | 32 | #include <linux/highmem.h> |
33 | #include <linux/utsname.h> | ||
34 | #include <linux/init.h> | 33 | #include <linux/init.h> |
35 | #include <linux/sysctl.h> | 34 | #include <linux/sysctl.h> |
36 | #include <linux/random.h> | 35 | #include <linux/random.h> |
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index f8b653fcd4dd..83bcaf266b35 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/types.h> | 30 | #include <linux/types.h> |
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
32 | #include <linux/highmem.h> | 32 | #include <linux/highmem.h> |
33 | #include <linux/utsname.h> | ||
34 | #include <linux/init.h> | 33 | #include <linux/init.h> |
35 | #include <linux/sysctl.h> | 34 | #include <linux/sysctl.h> |
36 | #include <linux/random.h> | 35 | #include <linux/random.h> |
diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index 43e6e3280569..d9fa3d22e17c 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/types.h> | 30 | #include <linux/types.h> |
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
32 | #include <linux/highmem.h> | 32 | #include <linux/highmem.h> |
33 | #include <linux/utsname.h> | ||
34 | #include <linux/init.h> | 33 | #include <linux/init.h> |
35 | #include <linux/sysctl.h> | 34 | #include <linux/sysctl.h> |
36 | #include <linux/random.h> | 35 | #include <linux/random.h> |
diff --git a/fs/ocfs2/dlm/dlmthread.c b/fs/ocfs2/dlm/dlmthread.c index 98569e86c613..52ec020ea78b 100644 --- a/fs/ocfs2/dlm/dlmthread.c +++ b/fs/ocfs2/dlm/dlmthread.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/types.h> | 30 | #include <linux/types.h> |
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
32 | #include <linux/highmem.h> | 32 | #include <linux/highmem.h> |
33 | #include <linux/utsname.h> | ||
34 | #include <linux/init.h> | 33 | #include <linux/init.h> |
35 | #include <linux/sysctl.h> | 34 | #include <linux/sysctl.h> |
36 | #include <linux/random.h> | 35 | #include <linux/random.h> |
diff --git a/fs/ocfs2/dlm/dlmunlock.c b/fs/ocfs2/dlm/dlmunlock.c index 756f5b0998e0..00f53b2aea76 100644 --- a/fs/ocfs2/dlm/dlmunlock.c +++ b/fs/ocfs2/dlm/dlmunlock.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/types.h> | 30 | #include <linux/types.h> |
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
32 | #include <linux/highmem.h> | 32 | #include <linux/highmem.h> |
33 | #include <linux/utsname.h> | ||
34 | #include <linux/init.h> | 33 | #include <linux/init.h> |
35 | #include <linux/sysctl.h> | 34 | #include <linux/sysctl.h> |
36 | #include <linux/random.h> | 35 | #include <linux/random.h> |
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 24feb449a1dc..4cc3c890a2cd 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/types.h> | 28 | #include <linux/types.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/highmem.h> | 30 | #include <linux/highmem.h> |
31 | #include <linux/utsname.h> | ||
32 | #include <linux/init.h> | 31 | #include <linux/init.h> |
33 | #include <linux/random.h> | 32 | #include <linux/random.h> |
34 | #include <linux/statfs.h> | 33 | #include <linux/statfs.h> |
diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c index 579dd1b1110f..e3421030a69f 100644 --- a/fs/ocfs2/symlink.c +++ b/fs/ocfs2/symlink.c | |||
@@ -38,7 +38,6 @@ | |||
38 | #include <linux/types.h> | 38 | #include <linux/types.h> |
39 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
40 | #include <linux/pagemap.h> | 40 | #include <linux/pagemap.h> |
41 | #include <linux/utsname.h> | ||
42 | #include <linux/namei.h> | 41 | #include <linux/namei.h> |
43 | 42 | ||
44 | #define MLOG_MASK_PREFIX ML_NAMEI | 43 | #define MLOG_MASK_PREFIX ML_NAMEI |
diff --git a/include/linux/cred.h b/include/linux/cred.h index fb371601a3b4..4e3387a89cb9 100644 --- a/include/linux/cred.h +++ b/include/linux/cred.h | |||
@@ -176,23 +176,7 @@ extern void __invalid_creds(const struct cred *, const char *, unsigned); | |||
176 | extern void __validate_process_creds(struct task_struct *, | 176 | extern void __validate_process_creds(struct task_struct *, |
177 | const char *, unsigned); | 177 | const char *, unsigned); |
178 | 178 | ||
179 | static inline bool creds_are_invalid(const struct cred *cred) | 179 | extern bool creds_are_invalid(const struct cred *cred); |
180 | { | ||
181 | if (cred->magic != CRED_MAGIC) | ||
182 | return true; | ||
183 | if (atomic_read(&cred->usage) < atomic_read(&cred->subscribers)) | ||
184 | return true; | ||
185 | #ifdef CONFIG_SECURITY_SELINUX | ||
186 | if (selinux_is_enabled()) { | ||
187 | if ((unsigned long) cred->security < PAGE_SIZE) | ||
188 | return true; | ||
189 | if ((*(u32 *)cred->security & 0xffffff00) == | ||
190 | (POISON_FREE << 24 | POISON_FREE << 16 | POISON_FREE << 8)) | ||
191 | return true; | ||
192 | } | ||
193 | #endif | ||
194 | return false; | ||
195 | } | ||
196 | 180 | ||
197 | static inline void __validate_creds(const struct cred *cred, | 181 | static inline void __validate_creds(const struct cred *cred, |
198 | const char *file, unsigned line) | 182 | const char *file, unsigned line) |
diff --git a/include/linux/i2c/adp5588.h b/include/linux/i2c/adp5588.h new file mode 100644 index 000000000000..fc5db826b48e --- /dev/null +++ b/include/linux/i2c/adp5588.h | |||
@@ -0,0 +1,92 @@ | |||
1 | /* | ||
2 | * Analog Devices ADP5588 I/O Expander and QWERTY Keypad Controller | ||
3 | * | ||
4 | * Copyright 2009 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2 or later. | ||
7 | */ | ||
8 | |||
9 | #ifndef _ADP5588_H | ||
10 | #define _ADP5588_H | ||
11 | |||
12 | #define DEV_ID 0x00 /* Device ID */ | ||
13 | #define CFG 0x01 /* Configuration Register1 */ | ||
14 | #define INT_STAT 0x02 /* Interrupt Status Register */ | ||
15 | #define KEY_LCK_EC_STAT 0x03 /* Key Lock and Event Counter Register */ | ||
16 | #define Key_EVENTA 0x04 /* Key Event Register A */ | ||
17 | #define Key_EVENTB 0x05 /* Key Event Register B */ | ||
18 | #define Key_EVENTC 0x06 /* Key Event Register C */ | ||
19 | #define Key_EVENTD 0x07 /* Key Event Register D */ | ||
20 | #define Key_EVENTE 0x08 /* Key Event Register E */ | ||
21 | #define Key_EVENTF 0x09 /* Key Event Register F */ | ||
22 | #define Key_EVENTG 0x0A /* Key Event Register G */ | ||
23 | #define Key_EVENTH 0x0B /* Key Event Register H */ | ||
24 | #define Key_EVENTI 0x0C /* Key Event Register I */ | ||
25 | #define Key_EVENTJ 0x0D /* Key Event Register J */ | ||
26 | #define KP_LCK_TMR 0x0E /* Keypad Lock1 to Lock2 Timer */ | ||
27 | #define UNLOCK1 0x0F /* Unlock Key1 */ | ||
28 | #define UNLOCK2 0x10 /* Unlock Key2 */ | ||
29 | #define GPIO_INT_STAT1 0x11 /* GPIO Interrupt Status */ | ||
30 | #define GPIO_INT_STAT2 0x12 /* GPIO Interrupt Status */ | ||
31 | #define GPIO_INT_STAT3 0x13 /* GPIO Interrupt Status */ | ||
32 | #define GPIO_DAT_STAT1 0x14 /* GPIO Data Status, Read twice to clear */ | ||
33 | #define GPIO_DAT_STAT2 0x15 /* GPIO Data Status, Read twice to clear */ | ||
34 | #define GPIO_DAT_STAT3 0x16 /* GPIO Data Status, Read twice to clear */ | ||
35 | #define GPIO_DAT_OUT1 0x17 /* GPIO DATA OUT */ | ||
36 | #define GPIO_DAT_OUT2 0x18 /* GPIO DATA OUT */ | ||
37 | #define GPIO_DAT_OUT3 0x19 /* GPIO DATA OUT */ | ||
38 | #define GPIO_INT_EN1 0x1A /* GPIO Interrupt Enable */ | ||
39 | #define GPIO_INT_EN2 0x1B /* GPIO Interrupt Enable */ | ||
40 | #define GPIO_INT_EN3 0x1C /* GPIO Interrupt Enable */ | ||
41 | #define KP_GPIO1 0x1D /* Keypad or GPIO Selection */ | ||
42 | #define KP_GPIO2 0x1E /* Keypad or GPIO Selection */ | ||
43 | #define KP_GPIO3 0x1F /* Keypad or GPIO Selection */ | ||
44 | #define GPI_EM1 0x20 /* GPI Event Mode 1 */ | ||
45 | #define GPI_EM2 0x21 /* GPI Event Mode 2 */ | ||
46 | #define GPI_EM3 0x22 /* GPI Event Mode 3 */ | ||
47 | #define GPIO_DIR1 0x23 /* GPIO Data Direction */ | ||
48 | #define GPIO_DIR2 0x24 /* GPIO Data Direction */ | ||
49 | #define GPIO_DIR3 0x25 /* GPIO Data Direction */ | ||
50 | #define GPIO_INT_LVL1 0x26 /* GPIO Edge/Level Detect */ | ||
51 | #define GPIO_INT_LVL2 0x27 /* GPIO Edge/Level Detect */ | ||
52 | #define GPIO_INT_LVL3 0x28 /* GPIO Edge/Level Detect */ | ||
53 | #define Debounce_DIS1 0x29 /* Debounce Disable */ | ||
54 | #define Debounce_DIS2 0x2A /* Debounce Disable */ | ||
55 | #define Debounce_DIS3 0x2B /* Debounce Disable */ | ||
56 | #define GPIO_PULL1 0x2C /* GPIO Pull Disable */ | ||
57 | #define GPIO_PULL2 0x2D /* GPIO Pull Disable */ | ||
58 | #define GPIO_PULL3 0x2E /* GPIO Pull Disable */ | ||
59 | #define CMP_CFG_STAT 0x30 /* Comparator Configuration and Status Register */ | ||
60 | #define CMP_CONFG_SENS1 0x31 /* Sensor1 Comparator Configuration Register */ | ||
61 | #define CMP_CONFG_SENS2 0x32 /* L2 Light Sensor Reference Level, Output Falling for Sensor 1 */ | ||
62 | #define CMP1_LVL2_TRIP 0x33 /* L2 Light Sensor Hysteresis (Active when Output Rising) for Sensor 1 */ | ||
63 | #define CMP1_LVL2_HYS 0x34 /* L3 Light Sensor Reference Level, Output Falling For Sensor 1 */ | ||
64 | #define CMP1_LVL3_TRIP 0x35 /* L3 Light Sensor Hysteresis (Active when Output Rising) For Sensor 1 */ | ||
65 | #define CMP1_LVL3_HYS 0x36 /* Sensor 2 Comparator Configuration Register */ | ||
66 | #define CMP2_LVL2_TRIP 0x37 /* L2 Light Sensor Reference Level, Output Falling for Sensor 2 */ | ||
67 | #define CMP2_LVL2_HYS 0x38 /* L2 Light Sensor Hysteresis (Active when Output Rising) for Sensor 2 */ | ||
68 | #define CMP2_LVL3_TRIP 0x39 /* L3 Light Sensor Reference Level, Output Falling For Sensor 2 */ | ||
69 | #define CMP2_LVL3_HYS 0x3A /* L3 Light Sensor Hysteresis (Active when Output Rising) For Sensor 2 */ | ||
70 | #define CMP1_ADC_DAT_R1 0x3B /* Comparator 1 ADC data Register1 */ | ||
71 | #define CMP1_ADC_DAT_R2 0x3C /* Comparator 1 ADC data Register2 */ | ||
72 | #define CMP2_ADC_DAT_R1 0x3D /* Comparator 2 ADC data Register1 */ | ||
73 | #define CMP2_ADC_DAT_R2 0x3E /* Comparator 2 ADC data Register2 */ | ||
74 | |||
75 | #define ADP5588_DEVICE_ID_MASK 0xF | ||
76 | |||
77 | /* Put one of these structures in i2c_board_info platform_data */ | ||
78 | |||
79 | #define ADP5588_KEYMAPSIZE 80 | ||
80 | |||
81 | struct adp5588_kpad_platform_data { | ||
82 | int rows; /* Number of rows */ | ||
83 | int cols; /* Number of columns */ | ||
84 | const unsigned short *keymap; /* Pointer to keymap */ | ||
85 | unsigned short keymapsize; /* Keymap size */ | ||
86 | unsigned repeat:1; /* Enable key repeat */ | ||
87 | unsigned en_keylock:1; /* Enable Key Lock feature */ | ||
88 | unsigned short unlock_key1; /* Unlock Key 1 */ | ||
89 | unsigned short unlock_key2; /* Unlock Key 2 */ | ||
90 | }; | ||
91 | |||
92 | #endif | ||
diff --git a/include/linux/i2c/mcs5000_ts.h b/include/linux/i2c/mcs5000_ts.h new file mode 100644 index 000000000000..5a117b5ca15e --- /dev/null +++ b/include/linux/i2c/mcs5000_ts.h | |||
@@ -0,0 +1,24 @@ | |||
1 | /* | ||
2 | * mcs5000_ts.h | ||
3 | * | ||
4 | * Copyright (C) 2009 Samsung Electronics Co.Ltd | ||
5 | * Author: Joonyoung Shim <jy0922.shim@samsung.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #ifndef __LINUX_MCS5000_TS_H | ||
15 | #define __LINUX_MCS5000_TS_H | ||
16 | |||
17 | /* platform data for the MELFAS MCS-5000 touchscreen driver */ | ||
18 | struct mcs5000_ts_platform_data { | ||
19 | void (*cfg_pin)(void); | ||
20 | int x_size; | ||
21 | int y_size; | ||
22 | }; | ||
23 | |||
24 | #endif /* __LINUX_MCS5000_TS_H */ | ||
diff --git a/include/linux/i8042.h b/include/linux/i8042.h index 7907a72403ee..60c3360ef6ad 100644 --- a/include/linux/i8042.h +++ b/include/linux/i8042.h | |||
@@ -7,6 +7,7 @@ | |||
7 | * the Free Software Foundation. | 7 | * the Free Software Foundation. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/types.h> | ||
10 | 11 | ||
11 | /* | 12 | /* |
12 | * Standard commands. | 13 | * Standard commands. |
@@ -30,6 +31,35 @@ | |||
30 | #define I8042_CMD_MUX_PFX 0x0090 | 31 | #define I8042_CMD_MUX_PFX 0x0090 |
31 | #define I8042_CMD_MUX_SEND 0x1090 | 32 | #define I8042_CMD_MUX_SEND 0x1090 |
32 | 33 | ||
34 | struct serio; | ||
35 | |||
36 | #if defined(CONFIG_SERIO_I8042) || defined(CONFIG_SERIO_I8042_MODULE) | ||
37 | |||
38 | void i8042_lock_chip(void); | ||
39 | void i8042_unlock_chip(void); | ||
33 | int i8042_command(unsigned char *param, int command); | 40 | int i8042_command(unsigned char *param, int command); |
41 | bool i8042_check_port_owner(const struct serio *); | ||
42 | |||
43 | #else | ||
44 | |||
45 | void i8042_lock_chip(void) | ||
46 | { | ||
47 | } | ||
48 | |||
49 | void i8042_unlock_chip(void) | ||
50 | { | ||
51 | } | ||
52 | |||
53 | int i8042_command(unsigned char *param, int command) | ||
54 | { | ||
55 | return -ENOSYS; | ||
56 | } | ||
57 | |||
58 | bool i8042_check_port_owner(const struct serio *serio) | ||
59 | { | ||
60 | return false; | ||
61 | } | ||
62 | |||
63 | #endif | ||
34 | 64 | ||
35 | #endif | 65 | #endif |
diff --git a/include/linux/input.h b/include/linux/input.h index 8b3bc3e0d146..0ccfc30cd40f 100644 --- a/include/linux/input.h +++ b/include/linux/input.h | |||
@@ -1123,7 +1123,7 @@ struct input_dev { | |||
1123 | struct mutex mutex; | 1123 | struct mutex mutex; |
1124 | 1124 | ||
1125 | unsigned int users; | 1125 | unsigned int users; |
1126 | int going_away; | 1126 | bool going_away; |
1127 | 1127 | ||
1128 | struct device dev; | 1128 | struct device dev; |
1129 | 1129 | ||
diff --git a/include/linux/libps2.h b/include/linux/libps2.h index fcf5fbe6a50c..79603a6c356f 100644 --- a/include/linux/libps2.h +++ b/include/linux/libps2.h | |||
@@ -44,6 +44,8 @@ struct ps2dev { | |||
44 | void ps2_init(struct ps2dev *ps2dev, struct serio *serio); | 44 | void ps2_init(struct ps2dev *ps2dev, struct serio *serio); |
45 | int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout); | 45 | int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout); |
46 | void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout); | 46 | void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout); |
47 | void ps2_begin_command(struct ps2dev *ps2dev); | ||
48 | void ps2_end_command(struct ps2dev *ps2dev); | ||
47 | int __ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command); | 49 | int __ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command); |
48 | int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command); | 50 | int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command); |
49 | int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data); | 51 | int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data); |
diff --git a/include/linux/linkage.h b/include/linux/linkage.h index 691f59171c6c..5126cceb6ae9 100644 --- a/include/linux/linkage.h +++ b/include/linux/linkage.h | |||
@@ -57,6 +57,7 @@ | |||
57 | 57 | ||
58 | #ifdef __ASSEMBLY__ | 58 | #ifdef __ASSEMBLY__ |
59 | 59 | ||
60 | #ifndef LINKER_SCRIPT | ||
60 | #define ALIGN __ALIGN | 61 | #define ALIGN __ALIGN |
61 | #define ALIGN_STR __ALIGN_STR | 62 | #define ALIGN_STR __ALIGN_STR |
62 | 63 | ||
@@ -66,6 +67,7 @@ | |||
66 | ALIGN; \ | 67 | ALIGN; \ |
67 | name: | 68 | name: |
68 | #endif | 69 | #endif |
70 | #endif /* LINKER_SCRIPT */ | ||
69 | 71 | ||
70 | #ifndef WEAK | 72 | #ifndef WEAK |
71 | #define WEAK(name) \ | 73 | #define WEAK(name) \ |
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index 7da466ba4b0d..f5cc0898bc53 100644 --- a/include/linux/sunrpc/xdr.h +++ b/include/linux/sunrpc/xdr.h | |||
@@ -11,6 +11,7 @@ | |||
11 | 11 | ||
12 | #include <linux/uio.h> | 12 | #include <linux/uio.h> |
13 | #include <asm/byteorder.h> | 13 | #include <asm/byteorder.h> |
14 | #include <asm/unaligned.h> | ||
14 | #include <linux/scatterlist.h> | 15 | #include <linux/scatterlist.h> |
15 | 16 | ||
16 | /* | 17 | /* |
@@ -117,14 +118,14 @@ static inline __be32 *xdr_encode_array(__be32 *p, const void *s, unsigned int le | |||
117 | static inline __be32 * | 118 | static inline __be32 * |
118 | xdr_encode_hyper(__be32 *p, __u64 val) | 119 | xdr_encode_hyper(__be32 *p, __u64 val) |
119 | { | 120 | { |
120 | *(__be64 *)p = cpu_to_be64(val); | 121 | put_unaligned_be64(val, p); |
121 | return p + 2; | 122 | return p + 2; |
122 | } | 123 | } |
123 | 124 | ||
124 | static inline __be32 * | 125 | static inline __be32 * |
125 | xdr_decode_hyper(__be32 *p, __u64 *valp) | 126 | xdr_decode_hyper(__be32 *p, __u64 *valp) |
126 | { | 127 | { |
127 | *valp = be64_to_cpup((__be64 *)p); | 128 | *valp = get_unaligned_be64(p); |
128 | return p + 2; | 129 | return p + 2; |
129 | } | 130 | } |
130 | 131 | ||
diff --git a/include/linux/utsname.h b/include/linux/utsname.h index 3656b300de3a..69f39974c041 100644 --- a/include/linux/utsname.h +++ b/include/linux/utsname.h | |||
@@ -36,7 +36,6 @@ struct new_utsname { | |||
36 | #include <linux/kref.h> | 36 | #include <linux/kref.h> |
37 | #include <linux/nsproxy.h> | 37 | #include <linux/nsproxy.h> |
38 | #include <linux/err.h> | 38 | #include <linux/err.h> |
39 | #include <asm/atomic.h> | ||
40 | 39 | ||
41 | struct uts_namespace { | 40 | struct uts_namespace { |
42 | struct kref kref; | 41 | struct kref kref; |
diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h index b77c1478c99f..a7fb54808a23 100644 --- a/include/net/9p/9p.h +++ b/include/net/9p/9p.h | |||
@@ -38,6 +38,8 @@ | |||
38 | * @P9_DEBUG_SLABS: memory management tracing | 38 | * @P9_DEBUG_SLABS: memory management tracing |
39 | * @P9_DEBUG_FCALL: verbose dump of protocol messages | 39 | * @P9_DEBUG_FCALL: verbose dump of protocol messages |
40 | * @P9_DEBUG_FID: fid allocation/deallocation tracking | 40 | * @P9_DEBUG_FID: fid allocation/deallocation tracking |
41 | * @P9_DEBUG_PKT: packet marshalling/unmarshalling | ||
42 | * @P9_DEBUG_FSC: FS-cache tracing | ||
41 | * | 43 | * |
42 | * These flags are passed at mount time to turn on various levels of | 44 | * These flags are passed at mount time to turn on various levels of |
43 | * verbosity and tracing which will be output to the system logs. | 45 | * verbosity and tracing which will be output to the system logs. |
@@ -54,6 +56,7 @@ enum p9_debug_flags { | |||
54 | P9_DEBUG_FCALL = (1<<8), | 56 | P9_DEBUG_FCALL = (1<<8), |
55 | P9_DEBUG_FID = (1<<9), | 57 | P9_DEBUG_FID = (1<<9), |
56 | P9_DEBUG_PKT = (1<<10), | 58 | P9_DEBUG_PKT = (1<<10), |
59 | P9_DEBUG_FSC = (1<<11), | ||
57 | }; | 60 | }; |
58 | 61 | ||
59 | #ifdef CONFIG_NET_9P_DEBUG | 62 | #ifdef CONFIG_NET_9P_DEBUG |
diff --git a/init/Kconfig b/init/Kconfig index 0aa6579504cc..c7bac39d6c61 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -1006,14 +1006,6 @@ config SLUB_DEBUG | |||
1006 | SLUB sysfs support. /sys/slab will not exist and there will be | 1006 | SLUB sysfs support. /sys/slab will not exist and there will be |
1007 | no support for cache validation etc. | 1007 | no support for cache validation etc. |
1008 | 1008 | ||
1009 | config STRIP_ASM_SYMS | ||
1010 | bool "Strip assembler-generated symbols during link" | ||
1011 | default n | ||
1012 | help | ||
1013 | Strip internal assembler-generated symbols during a link (symbols | ||
1014 | that look like '.Lxxx') so they don't pollute the output of | ||
1015 | get_wchan() and suchlike. | ||
1016 | |||
1017 | config COMPAT_BRK | 1009 | config COMPAT_BRK |
1018 | bool "Disable heap randomization" | 1010 | bool "Disable heap randomization" |
1019 | default y | 1011 | default y |
diff --git a/init/main.c b/init/main.c index 51695cee1864..7449819a4805 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/string.h> | 18 | #include <linux/string.h> |
19 | #include <linux/ctype.h> | 19 | #include <linux/ctype.h> |
20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
21 | #include <linux/utsname.h> | ||
22 | #include <linux/ioport.h> | 21 | #include <linux/ioport.h> |
23 | #include <linux/init.h> | 22 | #include <linux/init.h> |
24 | #include <linux/smp_lock.h> | 23 | #include <linux/smp_lock.h> |
diff --git a/kernel/cred.c b/kernel/cred.c index d7f7a01082eb..dd76cfe5f5b0 100644 --- a/kernel/cred.c +++ b/kernel/cred.c | |||
@@ -782,6 +782,25 @@ EXPORT_SYMBOL(set_create_files_as); | |||
782 | 782 | ||
783 | #ifdef CONFIG_DEBUG_CREDENTIALS | 783 | #ifdef CONFIG_DEBUG_CREDENTIALS |
784 | 784 | ||
785 | bool creds_are_invalid(const struct cred *cred) | ||
786 | { | ||
787 | if (cred->magic != CRED_MAGIC) | ||
788 | return true; | ||
789 | if (atomic_read(&cred->usage) < atomic_read(&cred->subscribers)) | ||
790 | return true; | ||
791 | #ifdef CONFIG_SECURITY_SELINUX | ||
792 | if (selinux_is_enabled()) { | ||
793 | if ((unsigned long) cred->security < PAGE_SIZE) | ||
794 | return true; | ||
795 | if ((*(u32 *)cred->security & 0xffffff00) == | ||
796 | (POISON_FREE << 24 | POISON_FREE << 16 | POISON_FREE << 8)) | ||
797 | return true; | ||
798 | } | ||
799 | #endif | ||
800 | return false; | ||
801 | } | ||
802 | EXPORT_SYMBOL(creds_are_invalid); | ||
803 | |||
785 | /* | 804 | /* |
786 | * dump invalid credentials | 805 | * dump invalid credentials |
787 | */ | 806 | */ |
diff --git a/kernel/kmod.c b/kernel/kmod.c index 689d20f39305..9fcb53a11f87 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c | |||
@@ -143,7 +143,6 @@ struct subprocess_info { | |||
143 | static int ____call_usermodehelper(void *data) | 143 | static int ____call_usermodehelper(void *data) |
144 | { | 144 | { |
145 | struct subprocess_info *sub_info = data; | 145 | struct subprocess_info *sub_info = data; |
146 | enum umh_wait wait = sub_info->wait; | ||
147 | int retval; | 146 | int retval; |
148 | 147 | ||
149 | BUG_ON(atomic_read(&sub_info->cred->usage) != 1); | 148 | BUG_ON(atomic_read(&sub_info->cred->usage) != 1); |
@@ -185,14 +184,10 @@ static int ____call_usermodehelper(void *data) | |||
185 | */ | 184 | */ |
186 | set_user_nice(current, 0); | 185 | set_user_nice(current, 0); |
187 | 186 | ||
188 | if (wait == UMH_WAIT_EXEC) | ||
189 | complete(sub_info->complete); | ||
190 | |||
191 | retval = kernel_execve(sub_info->path, sub_info->argv, sub_info->envp); | 187 | retval = kernel_execve(sub_info->path, sub_info->argv, sub_info->envp); |
192 | 188 | ||
193 | /* Exec failed? */ | 189 | /* Exec failed? */ |
194 | if (wait != UMH_WAIT_EXEC) | 190 | sub_info->retval = retval; |
195 | sub_info->retval = retval; | ||
196 | do_exit(0); | 191 | do_exit(0); |
197 | } | 192 | } |
198 | 193 | ||
@@ -271,14 +266,16 @@ static void __call_usermodehelper(struct work_struct *work) | |||
271 | 266 | ||
272 | switch (wait) { | 267 | switch (wait) { |
273 | case UMH_NO_WAIT: | 268 | case UMH_NO_WAIT: |
274 | case UMH_WAIT_EXEC: | ||
275 | break; | 269 | break; |
276 | 270 | ||
277 | case UMH_WAIT_PROC: | 271 | case UMH_WAIT_PROC: |
278 | if (pid > 0) | 272 | if (pid > 0) |
279 | break; | 273 | break; |
280 | sub_info->retval = pid; | 274 | sub_info->retval = pid; |
281 | break; | 275 | /* FALLTHROUGH */ |
276 | |||
277 | case UMH_WAIT_EXEC: | ||
278 | complete(sub_info->complete); | ||
282 | } | 279 | } |
283 | } | 280 | } |
284 | 281 | ||
diff --git a/kernel/power/swap.c b/kernel/power/swap.c index 8ba052c86d48..b101cdc4df3f 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c | |||
@@ -13,7 +13,6 @@ | |||
13 | 13 | ||
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/file.h> | 15 | #include <linux/file.h> |
16 | #include <linux/utsname.h> | ||
17 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
18 | #include <linux/bitops.h> | 17 | #include <linux/bitops.h> |
19 | #include <linux/genhd.h> | 18 | #include <linux/genhd.h> |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 0dfaa47d7cb6..7f4f57bea4ce 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/proc_fs.h> | 26 | #include <linux/proc_fs.h> |
27 | #include <linux/security.h> | 27 | #include <linux/security.h> |
28 | #include <linux/ctype.h> | 28 | #include <linux/ctype.h> |
29 | #include <linux/utsname.h> | ||
30 | #include <linux/kmemcheck.h> | 29 | #include <linux/kmemcheck.h> |
31 | #include <linux/smp_lock.h> | 30 | #include <linux/smp_lock.h> |
32 | #include <linux/fs.h> | 31 | #include <linux/fs.h> |
diff --git a/kernel/uid16.c b/kernel/uid16.c index 0314501688b9..419209893d87 100644 --- a/kernel/uid16.c +++ b/kernel/uid16.c | |||
@@ -4,7 +4,6 @@ | |||
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <linux/mm.h> | 6 | #include <linux/mm.h> |
7 | #include <linux/utsname.h> | ||
8 | #include <linux/mman.h> | 7 | #include <linux/mman.h> |
9 | #include <linux/notifier.h> | 8 | #include <linux/notifier.h> |
10 | #include <linux/reboot.h> | 9 | #include <linux/reboot.h> |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index d57b12f59c8c..891155817bc6 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -50,6 +50,14 @@ config MAGIC_SYSRQ | |||
50 | keys are documented in <file:Documentation/sysrq.txt>. Don't say Y | 50 | keys are documented in <file:Documentation/sysrq.txt>. Don't say Y |
51 | unless you really know what this hack does. | 51 | unless you really know what this hack does. |
52 | 52 | ||
53 | config STRIP_ASM_SYMS | ||
54 | bool "Strip assembler-generated symbols during link" | ||
55 | default n | ||
56 | help | ||
57 | Strip internal assembler-generated symbols during a link (symbols | ||
58 | that look like '.Lxxx') so they don't pollute the output of | ||
59 | get_wchan() and suchlike. | ||
60 | |||
53 | config UNUSED_SYMBOLS | 61 | config UNUSED_SYMBOLS |
54 | bool "Enable unused/obsolete exported symbols" | 62 | bool "Enable unused/obsolete exported symbols" |
55 | default y if X86 | 63 | default y if X86 |
diff --git a/net/sunrpc/auth_null.c b/net/sunrpc/auth_null.c index c70dd7f5258e..1db618f56ecb 100644 --- a/net/sunrpc/auth_null.c +++ b/net/sunrpc/auth_null.c | |||
@@ -8,7 +8,6 @@ | |||
8 | 8 | ||
9 | #include <linux/types.h> | 9 | #include <linux/types.h> |
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/utsname.h> | ||
12 | #include <linux/sunrpc/clnt.h> | 11 | #include <linux/sunrpc/clnt.h> |
13 | 12 | ||
14 | #ifdef RPC_DEBUG | 13 | #ifdef RPC_DEBUG |
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 858a443f418f..49278f830367 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
@@ -860,7 +860,8 @@ static void rpc_clntdir_depopulate(struct dentry *dentry) | |||
860 | 860 | ||
861 | /** | 861 | /** |
862 | * rpc_create_client_dir - Create a new rpc_client directory in rpc_pipefs | 862 | * rpc_create_client_dir - Create a new rpc_client directory in rpc_pipefs |
863 | * @path: path from the rpc_pipefs root to the new directory | 863 | * @dentry: dentry from the rpc_pipefs root to the new directory |
864 | * @name: &struct qstr for the name | ||
864 | * @rpc_client: rpc client to associate with this directory | 865 | * @rpc_client: rpc client to associate with this directory |
865 | * | 866 | * |
866 | * This creates a directory at the given @path associated with | 867 | * This creates a directory at the given @path associated with |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index bee415465754..37c5475ba258 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -773,6 +773,7 @@ static void xs_close(struct rpc_xprt *xprt) | |||
773 | dprintk("RPC: xs_close xprt %p\n", xprt); | 773 | dprintk("RPC: xs_close xprt %p\n", xprt); |
774 | 774 | ||
775 | xs_reset_transport(transport); | 775 | xs_reset_transport(transport); |
776 | xprt->reestablish_timeout = 0; | ||
776 | 777 | ||
777 | smp_mb__before_clear_bit(); | 778 | smp_mb__before_clear_bit(); |
778 | clear_bit(XPRT_CONNECTION_ABORT, &xprt->state); | 779 | clear_bit(XPRT_CONNECTION_ABORT, &xprt->state); |
@@ -1264,6 +1265,12 @@ static void xs_tcp_data_ready(struct sock *sk, int bytes) | |||
1264 | if (xprt->shutdown) | 1265 | if (xprt->shutdown) |
1265 | goto out; | 1266 | goto out; |
1266 | 1267 | ||
1268 | /* Any data means we had a useful conversation, so | ||
1269 | * the we don't need to delay the next reconnect | ||
1270 | */ | ||
1271 | if (xprt->reestablish_timeout) | ||
1272 | xprt->reestablish_timeout = 0; | ||
1273 | |||
1267 | /* We use rd_desc to pass struct xprt to xs_tcp_data_recv */ | 1274 | /* We use rd_desc to pass struct xprt to xs_tcp_data_recv */ |
1268 | rd_desc.arg.data = xprt; | 1275 | rd_desc.arg.data = xprt; |
1269 | do { | 1276 | do { |
@@ -2034,6 +2041,8 @@ static void xs_connect(struct rpc_task *task) | |||
2034 | &transport->connect_worker, | 2041 | &transport->connect_worker, |
2035 | xprt->reestablish_timeout); | 2042 | xprt->reestablish_timeout); |
2036 | xprt->reestablish_timeout <<= 1; | 2043 | xprt->reestablish_timeout <<= 1; |
2044 | if (xprt->reestablish_timeout < XS_TCP_INIT_REEST_TO) | ||
2045 | xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; | ||
2037 | if (xprt->reestablish_timeout > XS_TCP_MAX_REEST_TO) | 2046 | if (xprt->reestablish_timeout > XS_TCP_MAX_REEST_TO) |
2038 | xprt->reestablish_timeout = XS_TCP_MAX_REEST_TO; | 2047 | xprt->reestablish_timeout = XS_TCP_MAX_REEST_TO; |
2039 | } else { | 2048 | } else { |
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index c29be8f90248..4f9c1908593b 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include | |||
@@ -83,11 +83,12 @@ TMPOUT := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/) | |||
83 | # is automatically cleaned up. | 83 | # is automatically cleaned up. |
84 | try-run = $(shell set -e; \ | 84 | try-run = $(shell set -e; \ |
85 | TMP="$(TMPOUT).$$$$.tmp"; \ | 85 | TMP="$(TMPOUT).$$$$.tmp"; \ |
86 | TMPO="$(TMPOUT).$$$$.o"; \ | ||
86 | if ($(1)) >/dev/null 2>&1; \ | 87 | if ($(1)) >/dev/null 2>&1; \ |
87 | then echo "$(2)"; \ | 88 | then echo "$(2)"; \ |
88 | else echo "$(3)"; \ | 89 | else echo "$(3)"; \ |
89 | fi; \ | 90 | fi; \ |
90 | rm -f "$$TMP") | 91 | rm -f "$$TMP" "$$TMPO") |
91 | 92 | ||
92 | # as-option | 93 | # as-option |
93 | # Usage: cflags-y += $(call as-option,-Wa$(comma)-isa=foo,) | 94 | # Usage: cflags-y += $(call as-option,-Wa$(comma)-isa=foo,) |
@@ -105,12 +106,12 @@ as-instr = $(call try-run,\ | |||
105 | # Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586) | 106 | # Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586) |
106 | 107 | ||
107 | cc-option = $(call try-run,\ | 108 | cc-option = $(call try-run,\ |
108 | $(CC) $(KBUILD_CFLAGS) $(1) -c -xc /dev/null -o "$$TMP",$(1),$(2)) | 109 | $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -xc /dev/null -o "$$TMP",$(1),$(2)) |
109 | 110 | ||
110 | # cc-option-yn | 111 | # cc-option-yn |
111 | # Usage: flag := $(call cc-option-yn,-march=winchip-c6) | 112 | # Usage: flag := $(call cc-option-yn,-march=winchip-c6) |
112 | cc-option-yn = $(call try-run,\ | 113 | cc-option-yn = $(call try-run,\ |
113 | $(CC) $(KBUILD_CFLAGS) $(1) -c -xc /dev/null -o "$$TMP",y,n) | 114 | $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -xc /dev/null -o "$$TMP",y,n) |
114 | 115 | ||
115 | # cc-option-align | 116 | # cc-option-align |
116 | # Prefix align with either -falign or -malign | 117 | # Prefix align with either -falign or -malign |
@@ -130,10 +131,15 @@ cc-fullversion = $(shell $(CONFIG_SHELL) \ | |||
130 | # Usage: EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1) | 131 | # Usage: EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1) |
131 | cc-ifversion = $(shell [ $(call cc-version, $(CC)) $(1) $(2) ] && echo $(3)) | 132 | cc-ifversion = $(shell [ $(call cc-version, $(CC)) $(1) $(2) ] && echo $(3)) |
132 | 133 | ||
134 | # cc-ldoption | ||
135 | # Usage: ldflags += $(call cc-ldoption, -Wl$(comma)--hash-style=both) | ||
136 | cc-ldoption = $(call try-run,\ | ||
137 | $(CC) $(1) -nostdlib -xc /dev/null -o "$$TMP",$(1),$(2)) | ||
138 | |||
133 | # ld-option | 139 | # ld-option |
134 | # Usage: ldflags += $(call ld-option, -Wl$(comma)--hash-style=both) | 140 | # Usage: LDFLAGS += $(call ld-option, -X) |
135 | ld-option = $(call try-run,\ | 141 | ld-option = $(call try-run,\ |
136 | $(CC) $(1) -nostdlib -xc /dev/null -o "$$TMP",$(1),$(2)) | 142 | $(CC) /dev/null -c -o "$$TMPO" ; $(LD) $(1) "$$TMPO" -o "$$TMP",$(1),$(2)) |
137 | 143 | ||
138 | ###### | 144 | ###### |
139 | 145 | ||
diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 5c4b7a400c18..341b58902ffc 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build | |||
@@ -206,7 +206,7 @@ cmd_modversions = \ | |||
206 | endif | 206 | endif |
207 | 207 | ||
208 | ifdef CONFIG_FTRACE_MCOUNT_RECORD | 208 | ifdef CONFIG_FTRACE_MCOUNT_RECORD |
209 | cmd_record_mcount = perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \ | 209 | cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \ |
210 | "$(if $(CONFIG_64BIT),64,32)" \ | 210 | "$(if $(CONFIG_64BIT),64,32)" \ |
211 | "$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" "$(NM)" "$(RM)" "$(MV)" \ | 211 | "$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" "$(NM)" "$(RM)" "$(MV)" \ |
212 | "$(if $(part-of-module),1,0)" "$(@)"; | 212 | "$(if $(part-of-module),1,0)" "$(@)"; |
@@ -216,6 +216,7 @@ define rule_cc_o_c | |||
216 | $(call echo-cmd,checksrc) $(cmd_checksrc) \ | 216 | $(call echo-cmd,checksrc) $(cmd_checksrc) \ |
217 | $(call echo-cmd,cc_o_c) $(cmd_cc_o_c); \ | 217 | $(call echo-cmd,cc_o_c) $(cmd_cc_o_c); \ |
218 | $(cmd_modversions) \ | 218 | $(cmd_modversions) \ |
219 | $(call echo-cmd,record_mcount) \ | ||
219 | $(cmd_record_mcount) \ | 220 | $(cmd_record_mcount) \ |
220 | scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' > \ | 221 | scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' > \ |
221 | $(dot-target).tmp; \ | 222 | $(dot-target).tmp; \ |
@@ -269,7 +270,8 @@ targets += $(extra-y) $(MAKECMDGOALS) $(always) | |||
269 | # Linker scripts preprocessor (.lds.S -> .lds) | 270 | # Linker scripts preprocessor (.lds.S -> .lds) |
270 | # --------------------------------------------------------------------------- | 271 | # --------------------------------------------------------------------------- |
271 | quiet_cmd_cpp_lds_S = LDS $@ | 272 | quiet_cmd_cpp_lds_S = LDS $@ |
272 | cmd_cpp_lds_S = $(CPP) $(cpp_flags) -D__ASSEMBLY__ -o $@ $< | 273 | cmd_cpp_lds_S = $(CPP) $(cpp_flags) -P -C -U$(ARCH) \ |
274 | -D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $< | ||
273 | 275 | ||
274 | $(obj)/%.lds: $(src)/%.lds.S FORCE | 276 | $(obj)/%.lds: $(src)/%.lds.S FORCE |
275 | $(call if_changed_dep,cpp_lds_S) | 277 | $(call if_changed_dep,cpp_lds_S) |
diff --git a/scripts/basic/docproc.c b/scripts/basic/docproc.c index 99ca7a698687..79ab973fb43a 100644 --- a/scripts/basic/docproc.c +++ b/scripts/basic/docproc.c | |||
@@ -71,7 +71,7 @@ FILELINE * docsection; | |||
71 | 71 | ||
72 | static char *srctree, *kernsrctree; | 72 | static char *srctree, *kernsrctree; |
73 | 73 | ||
74 | void usage (void) | 74 | static void usage (void) |
75 | { | 75 | { |
76 | fprintf(stderr, "Usage: docproc {doc|depend} file\n"); | 76 | fprintf(stderr, "Usage: docproc {doc|depend} file\n"); |
77 | fprintf(stderr, "Input is read from file.tmpl. Output is sent to stdout\n"); | 77 | fprintf(stderr, "Input is read from file.tmpl. Output is sent to stdout\n"); |
@@ -84,7 +84,7 @@ void usage (void) | |||
84 | /* | 84 | /* |
85 | * Execute kernel-doc with parameters given in svec | 85 | * Execute kernel-doc with parameters given in svec |
86 | */ | 86 | */ |
87 | void exec_kernel_doc(char **svec) | 87 | static void exec_kernel_doc(char **svec) |
88 | { | 88 | { |
89 | pid_t pid; | 89 | pid_t pid; |
90 | int ret; | 90 | int ret; |
@@ -129,7 +129,7 @@ struct symfile | |||
129 | struct symfile symfilelist[MAXFILES]; | 129 | struct symfile symfilelist[MAXFILES]; |
130 | int symfilecnt = 0; | 130 | int symfilecnt = 0; |
131 | 131 | ||
132 | void add_new_symbol(struct symfile *sym, char * symname) | 132 | static void add_new_symbol(struct symfile *sym, char * symname) |
133 | { | 133 | { |
134 | sym->symbollist = | 134 | sym->symbollist = |
135 | realloc(sym->symbollist, (sym->symbolcnt + 1) * sizeof(char *)); | 135 | realloc(sym->symbollist, (sym->symbolcnt + 1) * sizeof(char *)); |
@@ -137,14 +137,14 @@ void add_new_symbol(struct symfile *sym, char * symname) | |||
137 | } | 137 | } |
138 | 138 | ||
139 | /* Add a filename to the list */ | 139 | /* Add a filename to the list */ |
140 | struct symfile * add_new_file(char * filename) | 140 | static struct symfile * add_new_file(char * filename) |
141 | { | 141 | { |
142 | symfilelist[symfilecnt++].filename = strdup(filename); | 142 | symfilelist[symfilecnt++].filename = strdup(filename); |
143 | return &symfilelist[symfilecnt - 1]; | 143 | return &symfilelist[symfilecnt - 1]; |
144 | } | 144 | } |
145 | 145 | ||
146 | /* Check if file already are present in the list */ | 146 | /* Check if file already are present in the list */ |
147 | struct symfile * filename_exist(char * filename) | 147 | static struct symfile * filename_exist(char * filename) |
148 | { | 148 | { |
149 | int i; | 149 | int i; |
150 | for (i=0; i < symfilecnt; i++) | 150 | for (i=0; i < symfilecnt; i++) |
@@ -157,20 +157,20 @@ struct symfile * filename_exist(char * filename) | |||
157 | * List all files referenced within the template file. | 157 | * List all files referenced within the template file. |
158 | * Files are separated by tabs. | 158 | * Files are separated by tabs. |
159 | */ | 159 | */ |
160 | void adddep(char * file) { printf("\t%s", file); } | 160 | static void adddep(char * file) { printf("\t%s", file); } |
161 | void adddep2(char * file, char * line) { line = line; adddep(file); } | 161 | static void adddep2(char * file, char * line) { line = line; adddep(file); } |
162 | void noaction(char * line) { line = line; } | 162 | static void noaction(char * line) { line = line; } |
163 | void noaction2(char * file, char * line) { file = file; line = line; } | 163 | static void noaction2(char * file, char * line) { file = file; line = line; } |
164 | 164 | ||
165 | /* Echo the line without further action */ | 165 | /* Echo the line without further action */ |
166 | void printline(char * line) { printf("%s", line); } | 166 | static void printline(char * line) { printf("%s", line); } |
167 | 167 | ||
168 | /* | 168 | /* |
169 | * Find all symbols in filename that are exported with EXPORT_SYMBOL & | 169 | * Find all symbols in filename that are exported with EXPORT_SYMBOL & |
170 | * EXPORT_SYMBOL_GPL (& EXPORT_SYMBOL_GPL_FUTURE implicitly). | 170 | * EXPORT_SYMBOL_GPL (& EXPORT_SYMBOL_GPL_FUTURE implicitly). |
171 | * All symbols located are stored in symfilelist. | 171 | * All symbols located are stored in symfilelist. |
172 | */ | 172 | */ |
173 | void find_export_symbols(char * filename) | 173 | static void find_export_symbols(char * filename) |
174 | { | 174 | { |
175 | FILE * fp; | 175 | FILE * fp; |
176 | struct symfile *sym; | 176 | struct symfile *sym; |
@@ -227,7 +227,7 @@ void find_export_symbols(char * filename) | |||
227 | * intfunc uses -nofunction | 227 | * intfunc uses -nofunction |
228 | * extfunc uses -function | 228 | * extfunc uses -function |
229 | */ | 229 | */ |
230 | void docfunctions(char * filename, char * type) | 230 | static void docfunctions(char * filename, char * type) |
231 | { | 231 | { |
232 | int i,j; | 232 | int i,j; |
233 | int symcnt = 0; | 233 | int symcnt = 0; |
@@ -258,15 +258,15 @@ void docfunctions(char * filename, char * type) | |||
258 | fflush(stdout); | 258 | fflush(stdout); |
259 | free(vec); | 259 | free(vec); |
260 | } | 260 | } |
261 | void intfunc(char * filename) { docfunctions(filename, NOFUNCTION); } | 261 | static void intfunc(char * filename) { docfunctions(filename, NOFUNCTION); } |
262 | void extfunc(char * filename) { docfunctions(filename, FUNCTION); } | 262 | static void extfunc(char * filename) { docfunctions(filename, FUNCTION); } |
263 | 263 | ||
264 | /* | 264 | /* |
265 | * Document specific function(s) in a file. | 265 | * Document specific function(s) in a file. |
266 | * Call kernel-doc with the following parameters: | 266 | * Call kernel-doc with the following parameters: |
267 | * kernel-doc -docbook -function function1 [-function function2] | 267 | * kernel-doc -docbook -function function1 [-function function2] |
268 | */ | 268 | */ |
269 | void singfunc(char * filename, char * line) | 269 | static void singfunc(char * filename, char * line) |
270 | { | 270 | { |
271 | char *vec[200]; /* Enough for specific functions */ | 271 | char *vec[200]; /* Enough for specific functions */ |
272 | int i, idx = 0; | 272 | int i, idx = 0; |
@@ -297,7 +297,7 @@ void singfunc(char * filename, char * line) | |||
297 | * Call kernel-doc with the following parameters: | 297 | * Call kernel-doc with the following parameters: |
298 | * kernel-doc -docbook -function "doc section" filename | 298 | * kernel-doc -docbook -function "doc section" filename |
299 | */ | 299 | */ |
300 | void docsect(char *filename, char *line) | 300 | static void docsect(char *filename, char *line) |
301 | { | 301 | { |
302 | char *vec[6]; /* kerneldoc -docbook -function "section" file NULL */ | 302 | char *vec[6]; /* kerneldoc -docbook -function "section" file NULL */ |
303 | char *s; | 303 | char *s; |
@@ -324,7 +324,7 @@ void docsect(char *filename, char *line) | |||
324 | * 5) Lines containing !P | 324 | * 5) Lines containing !P |
325 | * 6) Default lines - lines not matching the above | 325 | * 6) Default lines - lines not matching the above |
326 | */ | 326 | */ |
327 | void parse_file(FILE *infile) | 327 | static void parse_file(FILE *infile) |
328 | { | 328 | { |
329 | char line[MAXLINESZ]; | 329 | char line[MAXLINESZ]; |
330 | char * s; | 330 | char * s; |
diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index 8ab448611680..6bf21f83837d 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c | |||
@@ -124,7 +124,7 @@ char *target; | |||
124 | char *depfile; | 124 | char *depfile; |
125 | char *cmdline; | 125 | char *cmdline; |
126 | 126 | ||
127 | void usage(void) | 127 | static void usage(void) |
128 | { | 128 | { |
129 | fprintf(stderr, "Usage: fixdep <depfile> <target> <cmdline>\n"); | 129 | fprintf(stderr, "Usage: fixdep <depfile> <target> <cmdline>\n"); |
130 | exit(1); | 130 | exit(1); |
@@ -133,7 +133,7 @@ void usage(void) | |||
133 | /* | 133 | /* |
134 | * Print out the commandline prefixed with cmd_<target filename> := | 134 | * Print out the commandline prefixed with cmd_<target filename> := |
135 | */ | 135 | */ |
136 | void print_cmdline(void) | 136 | static void print_cmdline(void) |
137 | { | 137 | { |
138 | printf("cmd_%s := %s\n\n", target, cmdline); | 138 | printf("cmd_%s := %s\n\n", target, cmdline); |
139 | } | 139 | } |
@@ -146,7 +146,7 @@ int len_config = 0; | |||
146 | * Grow the configuration string to a desired length. | 146 | * Grow the configuration string to a desired length. |
147 | * Usually the first growth is plenty. | 147 | * Usually the first growth is plenty. |
148 | */ | 148 | */ |
149 | void grow_config(int len) | 149 | static void grow_config(int len) |
150 | { | 150 | { |
151 | while (len_config + len > size_config) { | 151 | while (len_config + len > size_config) { |
152 | if (size_config == 0) | 152 | if (size_config == 0) |
@@ -162,7 +162,7 @@ void grow_config(int len) | |||
162 | /* | 162 | /* |
163 | * Lookup a value in the configuration string. | 163 | * Lookup a value in the configuration string. |
164 | */ | 164 | */ |
165 | int is_defined_config(const char * name, int len) | 165 | static int is_defined_config(const char * name, int len) |
166 | { | 166 | { |
167 | const char * pconfig; | 167 | const char * pconfig; |
168 | const char * plast = str_config + len_config - len; | 168 | const char * plast = str_config + len_config - len; |
@@ -178,7 +178,7 @@ int is_defined_config(const char * name, int len) | |||
178 | /* | 178 | /* |
179 | * Add a new value to the configuration string. | 179 | * Add a new value to the configuration string. |
180 | */ | 180 | */ |
181 | void define_config(const char * name, int len) | 181 | static void define_config(const char * name, int len) |
182 | { | 182 | { |
183 | grow_config(len + 1); | 183 | grow_config(len + 1); |
184 | 184 | ||
@@ -190,7 +190,7 @@ void define_config(const char * name, int len) | |||
190 | /* | 190 | /* |
191 | * Clear the set of configuration strings. | 191 | * Clear the set of configuration strings. |
192 | */ | 192 | */ |
193 | void clear_config(void) | 193 | static void clear_config(void) |
194 | { | 194 | { |
195 | len_config = 0; | 195 | len_config = 0; |
196 | define_config("", 0); | 196 | define_config("", 0); |
@@ -199,7 +199,7 @@ void clear_config(void) | |||
199 | /* | 199 | /* |
200 | * Record the use of a CONFIG_* word. | 200 | * Record the use of a CONFIG_* word. |
201 | */ | 201 | */ |
202 | void use_config(char *m, int slen) | 202 | static void use_config(char *m, int slen) |
203 | { | 203 | { |
204 | char s[PATH_MAX]; | 204 | char s[PATH_MAX]; |
205 | char *p; | 205 | char *p; |
@@ -220,7 +220,7 @@ void use_config(char *m, int slen) | |||
220 | printf(" $(wildcard include/config/%s.h) \\\n", s); | 220 | printf(" $(wildcard include/config/%s.h) \\\n", s); |
221 | } | 221 | } |
222 | 222 | ||
223 | void parse_config_file(char *map, size_t len) | 223 | static void parse_config_file(char *map, size_t len) |
224 | { | 224 | { |
225 | int *end = (int *) (map + len); | 225 | int *end = (int *) (map + len); |
226 | /* start at +1, so that p can never be < map */ | 226 | /* start at +1, so that p can never be < map */ |
@@ -254,7 +254,7 @@ void parse_config_file(char *map, size_t len) | |||
254 | } | 254 | } |
255 | 255 | ||
256 | /* test is s ends in sub */ | 256 | /* test is s ends in sub */ |
257 | int strrcmp(char *s, char *sub) | 257 | static int strrcmp(char *s, char *sub) |
258 | { | 258 | { |
259 | int slen = strlen(s); | 259 | int slen = strlen(s); |
260 | int sublen = strlen(sub); | 260 | int sublen = strlen(sub); |
@@ -265,7 +265,7 @@ int strrcmp(char *s, char *sub) | |||
265 | return memcmp(s + slen - sublen, sub, sublen); | 265 | return memcmp(s + slen - sublen, sub, sublen); |
266 | } | 266 | } |
267 | 267 | ||
268 | void do_config_file(char *filename) | 268 | static void do_config_file(char *filename) |
269 | { | 269 | { |
270 | struct stat st; | 270 | struct stat st; |
271 | int fd; | 271 | int fd; |
@@ -296,7 +296,7 @@ void do_config_file(char *filename) | |||
296 | close(fd); | 296 | close(fd); |
297 | } | 297 | } |
298 | 298 | ||
299 | void parse_dep_file(void *map, size_t len) | 299 | static void parse_dep_file(void *map, size_t len) |
300 | { | 300 | { |
301 | char *m = map; | 301 | char *m = map; |
302 | char *end = m + len; | 302 | char *end = m + len; |
@@ -336,7 +336,7 @@ void parse_dep_file(void *map, size_t len) | |||
336 | printf("$(deps_%s):\n", target); | 336 | printf("$(deps_%s):\n", target); |
337 | } | 337 | } |
338 | 338 | ||
339 | void print_deps(void) | 339 | static void print_deps(void) |
340 | { | 340 | { |
341 | struct stat st; | 341 | struct stat st; |
342 | int fd; | 342 | int fd; |
@@ -368,7 +368,7 @@ void print_deps(void) | |||
368 | close(fd); | 368 | close(fd); |
369 | } | 369 | } |
370 | 370 | ||
371 | void traps(void) | 371 | static void traps(void) |
372 | { | 372 | { |
373 | static char test[] __attribute__((aligned(sizeof(int)))) = "CONF"; | 373 | static char test[] __attribute__((aligned(sizeof(int)))) = "CONF"; |
374 | int *p = (int *)test; | 374 | int *p = (int *)test; |
diff --git a/scripts/basic/hash.c b/scripts/basic/hash.c index 3299ad7fc8c0..2ef5d3f666b8 100644 --- a/scripts/basic/hash.c +++ b/scripts/basic/hash.c | |||
@@ -21,7 +21,7 @@ static void usage(void) | |||
21 | * http://www.cse.yorku.ca/~oz/hash.html | 21 | * http://www.cse.yorku.ca/~oz/hash.html |
22 | */ | 22 | */ |
23 | 23 | ||
24 | unsigned int djb2_hash(char *str) | 24 | static unsigned int djb2_hash(char *str) |
25 | { | 25 | { |
26 | unsigned long hash = 5381; | 26 | unsigned long hash = 5381; |
27 | int c; | 27 | int c; |
@@ -34,7 +34,7 @@ unsigned int djb2_hash(char *str) | |||
34 | return (unsigned int)(hash & ((1 << DYNAMIC_DEBUG_HASH_BITS) - 1)); | 34 | return (unsigned int)(hash & ((1 << DYNAMIC_DEBUG_HASH_BITS) - 1)); |
35 | } | 35 | } |
36 | 36 | ||
37 | unsigned int r5_hash(char *str) | 37 | static unsigned int r5_hash(char *str) |
38 | { | 38 | { |
39 | unsigned long hash = 0; | 39 | unsigned long hash = 0; |
40 | int c; | 40 | int c; |
diff --git a/scripts/checkincludes.pl b/scripts/checkincludes.pl index 8e6b716c191c..676ddc07d6fa 100755 --- a/scripts/checkincludes.pl +++ b/scripts/checkincludes.pl | |||
@@ -1,24 +1,85 @@ | |||
1 | #!/usr/bin/perl | 1 | #!/usr/bin/perl |
2 | # | 2 | # |
3 | # checkincludes: Find files included more than once in (other) files. | 3 | # checkincludes: find/remove files included more than once |
4 | # | ||
4 | # Copyright abandoned, 2000, Niels Kristian Bech Jensen <nkbj@image.dk>. | 5 | # Copyright abandoned, 2000, Niels Kristian Bech Jensen <nkbj@image.dk>. |
6 | # Copyright 2009 Luis R. Rodriguez <mcgrof@gmail.com> | ||
7 | # | ||
8 | # This script checks for duplicate includes. It also has support | ||
9 | # to remove them in place. Note that this will not take into | ||
10 | # consideration macros so you should run this only if you know | ||
11 | # you do have real dups and do not have them under #ifdef's. You | ||
12 | # could also just review the results. | ||
13 | |||
14 | sub usage { | ||
15 | print "Usage: checkincludes.pl [-r]\n"; | ||
16 | print "By default we just warn of duplicates\n"; | ||
17 | print "To remove duplicated includes in place use -r\n"; | ||
18 | exit 1; | ||
19 | } | ||
20 | |||
21 | my $remove = 0; | ||
22 | |||
23 | if ($#ARGV < 0) { | ||
24 | usage(); | ||
25 | } | ||
26 | |||
27 | if ($#ARGV >= 1) { | ||
28 | if ($ARGV[0] =~ /^-/) { | ||
29 | if ($ARGV[0] eq "-r") { | ||
30 | $remove = 1; | ||
31 | shift; | ||
32 | } else { | ||
33 | usage(); | ||
34 | } | ||
35 | } | ||
36 | } | ||
5 | 37 | ||
6 | foreach $file (@ARGV) { | 38 | foreach $file (@ARGV) { |
7 | open(FILE, $file) or die "Cannot open $file: $!.\n"; | 39 | open(FILE, $file) or die "Cannot open $file: $!.\n"; |
8 | 40 | ||
9 | my %includedfiles = (); | 41 | my %includedfiles = (); |
42 | my @file_lines = (); | ||
10 | 43 | ||
11 | while (<FILE>) { | 44 | while (<FILE>) { |
12 | if (m/^\s*#\s*include\s*[<"](\S*)[>"]/o) { | 45 | if (m/^\s*#\s*include\s*[<"](\S*)[>"]/o) { |
13 | ++$includedfiles{$1}; | 46 | ++$includedfiles{$1}; |
14 | } | 47 | } |
48 | push(@file_lines, $_); | ||
15 | } | 49 | } |
16 | 50 | ||
17 | foreach $filename (keys %includedfiles) { | 51 | close(FILE); |
18 | if ($includedfiles{$filename} > 1) { | 52 | |
19 | print "$file: $filename is included more than once.\n"; | 53 | if (!$remove) { |
54 | foreach $filename (keys %includedfiles) { | ||
55 | if ($includedfiles{$filename} > 1) { | ||
56 | print "$file: $filename is included more than once.\n"; | ||
57 | } | ||
20 | } | 58 | } |
59 | next; | ||
21 | } | 60 | } |
22 | 61 | ||
62 | open(FILE,">$file") || die("Cannot write to $file: $!"); | ||
63 | |||
64 | my $dups = 0; | ||
65 | foreach (@file_lines) { | ||
66 | if (m/^\s*#\s*include\s*[<"](\S*)[>"]/o) { | ||
67 | foreach $filename (keys %includedfiles) { | ||
68 | if ($1 eq $filename) { | ||
69 | if ($includedfiles{$filename} > 1) { | ||
70 | $includedfiles{$filename}--; | ||
71 | $dups++; | ||
72 | } else { | ||
73 | print FILE $_; | ||
74 | } | ||
75 | } | ||
76 | } | ||
77 | } else { | ||
78 | print FILE $_; | ||
79 | } | ||
80 | } | ||
81 | if ($dups > 0) { | ||
82 | print "$file: removed $dups duplicate includes\n"; | ||
83 | } | ||
23 | close(FILE); | 84 | close(FILE); |
24 | } | 85 | } |
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 3baaaecd6b13..9960d1c303f8 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c | |||
@@ -38,14 +38,14 @@ static int conf_cnt; | |||
38 | static char line[128]; | 38 | static char line[128]; |
39 | static struct menu *rootEntry; | 39 | static struct menu *rootEntry; |
40 | 40 | ||
41 | static char nohelp_text[] = N_("Sorry, no help available for this option yet.\n"); | 41 | static void print_help(struct menu *menu) |
42 | |||
43 | static const char *get_help(struct menu *menu) | ||
44 | { | 42 | { |
45 | if (menu_has_help(menu)) | 43 | struct gstr help = str_new(); |
46 | return _(menu_get_help(menu)); | 44 | |
47 | else | 45 | menu_get_ext_help(menu, &help); |
48 | return nohelp_text; | 46 | |
47 | printf("\n%s\n", str_get(&help)); | ||
48 | str_free(&help); | ||
49 | } | 49 | } |
50 | 50 | ||
51 | static void strip(char *str) | 51 | static void strip(char *str) |
@@ -121,7 +121,7 @@ static int conf_askvalue(struct symbol *sym, const char *def) | |||
121 | return 1; | 121 | return 1; |
122 | } | 122 | } |
123 | 123 | ||
124 | int conf_string(struct menu *menu) | 124 | static int conf_string(struct menu *menu) |
125 | { | 125 | { |
126 | struct symbol *sym = menu->sym; | 126 | struct symbol *sym = menu->sym; |
127 | const char *def; | 127 | const char *def; |
@@ -140,7 +140,7 @@ int conf_string(struct menu *menu) | |||
140 | case '?': | 140 | case '?': |
141 | /* print help */ | 141 | /* print help */ |
142 | if (line[1] == '\n') { | 142 | if (line[1] == '\n') { |
143 | printf("\n%s\n", get_help(menu)); | 143 | print_help(menu); |
144 | def = NULL; | 144 | def = NULL; |
145 | break; | 145 | break; |
146 | } | 146 | } |
@@ -220,7 +220,7 @@ static int conf_sym(struct menu *menu) | |||
220 | if (sym_set_tristate_value(sym, newval)) | 220 | if (sym_set_tristate_value(sym, newval)) |
221 | return 0; | 221 | return 0; |
222 | help: | 222 | help: |
223 | printf("\n%s\n", get_help(menu)); | 223 | print_help(menu); |
224 | } | 224 | } |
225 | } | 225 | } |
226 | 226 | ||
@@ -307,7 +307,7 @@ static int conf_choice(struct menu *menu) | |||
307 | fgets(line, 128, stdin); | 307 | fgets(line, 128, stdin); |
308 | strip(line); | 308 | strip(line); |
309 | if (line[0] == '?') { | 309 | if (line[0] == '?') { |
310 | printf("\n%s\n", get_help(menu)); | 310 | print_help(menu); |
311 | continue; | 311 | continue; |
312 | } | 312 | } |
313 | if (!line[0]) | 313 | if (!line[0]) |
@@ -331,7 +331,7 @@ static int conf_choice(struct menu *menu) | |||
331 | if (!child) | 331 | if (!child) |
332 | continue; | 332 | continue; |
333 | if (line[strlen(line) - 1] == '?') { | 333 | if (line[strlen(line) - 1] == '?') { |
334 | printf("\n%s\n", get_help(child)); | 334 | print_help(child); |
335 | continue; | 335 | continue; |
336 | } | 336 | } |
337 | sym_set_choice_value(sym, child->sym); | 337 | sym_set_choice_value(sym, child->sym); |
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index a04da3459f0f..b55e72ff2fc6 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c | |||
@@ -560,7 +560,7 @@ int conf_write(const char *name) | |||
560 | return 0; | 560 | return 0; |
561 | } | 561 | } |
562 | 562 | ||
563 | int conf_split_config(void) | 563 | static int conf_split_config(void) |
564 | { | 564 | { |
565 | const char *name; | 565 | const char *name; |
566 | char path[128]; | 566 | char path[128]; |
diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c index 579ece4fa584..edd3f39a080a 100644 --- a/scripts/kconfig/expr.c +++ b/scripts/kconfig/expr.c | |||
@@ -348,7 +348,7 @@ struct expr *expr_trans_bool(struct expr *e) | |||
348 | /* | 348 | /* |
349 | * e1 || e2 -> ? | 349 | * e1 || e2 -> ? |
350 | */ | 350 | */ |
351 | struct expr *expr_join_or(struct expr *e1, struct expr *e2) | 351 | static struct expr *expr_join_or(struct expr *e1, struct expr *e2) |
352 | { | 352 | { |
353 | struct expr *tmp; | 353 | struct expr *tmp; |
354 | struct symbol *sym1, *sym2; | 354 | struct symbol *sym1, *sym2; |
@@ -412,7 +412,7 @@ struct expr *expr_join_or(struct expr *e1, struct expr *e2) | |||
412 | return NULL; | 412 | return NULL; |
413 | } | 413 | } |
414 | 414 | ||
415 | struct expr *expr_join_and(struct expr *e1, struct expr *e2) | 415 | static struct expr *expr_join_and(struct expr *e1, struct expr *e2) |
416 | { | 416 | { |
417 | struct expr *tmp; | 417 | struct expr *tmp; |
418 | struct symbol *sym1, *sym2; | 418 | struct symbol *sym1, *sym2; |
@@ -1098,6 +1098,8 @@ void expr_fprint(struct expr *e, FILE *out) | |||
1098 | static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str) | 1098 | static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str) |
1099 | { | 1099 | { |
1100 | str_append((struct gstr*)data, str); | 1100 | str_append((struct gstr*)data, str); |
1101 | if (sym) | ||
1102 | str_printf((struct gstr*)data, " [=%s]", sym_get_string_value(sym)); | ||
1101 | } | 1103 | } |
1102 | 1104 | ||
1103 | void expr_gstr_print(struct expr *e, struct gstr *gs) | 1105 | void expr_gstr_print(struct expr *e, struct gstr *gs) |
diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c index 199b22bb49e2..65464366fe38 100644 --- a/scripts/kconfig/gconf.c +++ b/scripts/kconfig/gconf.c | |||
@@ -456,19 +456,9 @@ static void text_insert_help(struct menu *menu) | |||
456 | GtkTextBuffer *buffer; | 456 | GtkTextBuffer *buffer; |
457 | GtkTextIter start, end; | 457 | GtkTextIter start, end; |
458 | const char *prompt = _(menu_get_prompt(menu)); | 458 | const char *prompt = _(menu_get_prompt(menu)); |
459 | gchar *name; | 459 | struct gstr help = str_new(); |
460 | const char *help; | ||
461 | 460 | ||
462 | help = menu_get_help(menu); | 461 | menu_get_ext_help(menu, &help); |
463 | |||
464 | /* Gettextize if the help text not empty */ | ||
465 | if ((help != 0) && (help[0] != 0)) | ||
466 | help = _(help); | ||
467 | |||
468 | if (menu->sym && menu->sym->name) | ||
469 | name = g_strdup_printf(menu->sym->name); | ||
470 | else | ||
471 | name = g_strdup(""); | ||
472 | 462 | ||
473 | buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w)); | 463 | buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w)); |
474 | gtk_text_buffer_get_bounds(buffer, &start, &end); | 464 | gtk_text_buffer_get_bounds(buffer, &start, &end); |
@@ -478,14 +468,11 @@ static void text_insert_help(struct menu *menu) | |||
478 | gtk_text_buffer_get_end_iter(buffer, &end); | 468 | gtk_text_buffer_get_end_iter(buffer, &end); |
479 | gtk_text_buffer_insert_with_tags(buffer, &end, prompt, -1, tag1, | 469 | gtk_text_buffer_insert_with_tags(buffer, &end, prompt, -1, tag1, |
480 | NULL); | 470 | NULL); |
481 | gtk_text_buffer_insert_at_cursor(buffer, " ", 1); | ||
482 | gtk_text_buffer_get_end_iter(buffer, &end); | ||
483 | gtk_text_buffer_insert_with_tags(buffer, &end, name, -1, tag1, | ||
484 | NULL); | ||
485 | gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2); | 471 | gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2); |
486 | gtk_text_buffer_get_end_iter(buffer, &end); | 472 | gtk_text_buffer_get_end_iter(buffer, &end); |
487 | gtk_text_buffer_insert_with_tags(buffer, &end, help, -1, tag2, | 473 | gtk_text_buffer_insert_with_tags(buffer, &end, str_get(&help), -1, tag2, |
488 | NULL); | 474 | NULL); |
475 | str_free(&help); | ||
489 | } | 476 | } |
490 | 477 | ||
491 | 478 | ||
diff --git a/scripts/kconfig/gconf.glade b/scripts/kconfig/gconf.glade index 803233fdd6dd..b1c86c19292c 100644 --- a/scripts/kconfig/gconf.glade +++ b/scripts/kconfig/gconf.glade | |||
@@ -547,7 +547,7 @@ | |||
547 | <property name="headers_visible">True</property> | 547 | <property name="headers_visible">True</property> |
548 | <property name="rules_hint">False</property> | 548 | <property name="rules_hint">False</property> |
549 | <property name="reorderable">False</property> | 549 | <property name="reorderable">False</property> |
550 | <property name="enable_search">True</property> | 550 | <property name="enable_search">False</property> |
551 | <signal name="cursor_changed" handler="on_treeview2_cursor_changed" last_modification_time="Sun, 12 Jan 2003 15:58:22 GMT"/> | 551 | <signal name="cursor_changed" handler="on_treeview2_cursor_changed" last_modification_time="Sun, 12 Jan 2003 15:58:22 GMT"/> |
552 | <signal name="button_press_event" handler="on_treeview1_button_press_event" last_modification_time="Sun, 12 Jan 2003 16:03:52 GMT"/> | 552 | <signal name="button_press_event" handler="on_treeview1_button_press_event" last_modification_time="Sun, 12 Jan 2003 16:03:52 GMT"/> |
553 | <signal name="key_press_event" handler="on_treeview2_key_press_event" last_modification_time="Sun, 12 Jan 2003 16:11:44 GMT"/> | 553 | <signal name="key_press_event" handler="on_treeview2_key_press_event" last_modification_time="Sun, 12 Jan 2003 16:11:44 GMT"/> |
@@ -582,7 +582,7 @@ | |||
582 | <property name="headers_visible">True</property> | 582 | <property name="headers_visible">True</property> |
583 | <property name="rules_hint">False</property> | 583 | <property name="rules_hint">False</property> |
584 | <property name="reorderable">False</property> | 584 | <property name="reorderable">False</property> |
585 | <property name="enable_search">True</property> | 585 | <property name="enable_search">False</property> |
586 | <signal name="cursor_changed" handler="on_treeview2_cursor_changed" last_modification_time="Sun, 12 Jan 2003 15:57:55 GMT"/> | 586 | <signal name="cursor_changed" handler="on_treeview2_cursor_changed" last_modification_time="Sun, 12 Jan 2003 15:57:55 GMT"/> |
587 | <signal name="button_press_event" handler="on_treeview2_button_press_event" last_modification_time="Sun, 12 Jan 2003 15:57:58 GMT"/> | 587 | <signal name="button_press_event" handler="on_treeview2_button_press_event" last_modification_time="Sun, 12 Jan 2003 15:57:58 GMT"/> |
588 | <signal name="key_press_event" handler="on_treeview2_key_press_event" last_modification_time="Sun, 12 Jan 2003 15:58:01 GMT"/> | 588 | <signal name="key_press_event" handler="on_treeview2_key_press_event" last_modification_time="Sun, 12 Jan 2003 15:58:01 GMT"/> |
diff --git a/scripts/kconfig/kxgettext.c b/scripts/kconfig/kxgettext.c index 8d9ce22b0fc5..dcc3fcc0cc9a 100644 --- a/scripts/kconfig/kxgettext.c +++ b/scripts/kconfig/kxgettext.c | |||
@@ -166,7 +166,7 @@ static int message__add(const char *msg, char *option, char *file, int lineno) | |||
166 | return rc; | 166 | return rc; |
167 | } | 167 | } |
168 | 168 | ||
169 | void menu_build_message_list(struct menu *menu) | 169 | static void menu_build_message_list(struct menu *menu) |
170 | { | 170 | { |
171 | struct menu *child; | 171 | struct menu *child; |
172 | 172 | ||
@@ -211,7 +211,7 @@ static void message__print_gettext_msgid_msgstr(struct message *self) | |||
211 | "msgstr \"\"\n", self->msg); | 211 | "msgstr \"\"\n", self->msg); |
212 | } | 212 | } |
213 | 213 | ||
214 | void menu__xgettext(void) | 214 | static void menu__xgettext(void) |
215 | { | 215 | { |
216 | struct message *m = message__list; | 216 | struct message *m = message__list; |
217 | 217 | ||
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h index 8e69461313d1..ffeb532b2cff 100644 --- a/scripts/kconfig/lkc_proto.h +++ b/scripts/kconfig/lkc_proto.h | |||
@@ -17,6 +17,8 @@ P(menu_get_root_menu,struct menu *,(struct menu *menu)); | |||
17 | P(menu_get_parent_menu,struct menu *,(struct menu *menu)); | 17 | P(menu_get_parent_menu,struct menu *,(struct menu *menu)); |
18 | P(menu_has_help,bool,(struct menu *menu)); | 18 | P(menu_has_help,bool,(struct menu *menu)); |
19 | P(menu_get_help,const char *,(struct menu *menu)); | 19 | P(menu_get_help,const char *,(struct menu *menu)); |
20 | P(get_symbol_str,void,(struct gstr *r, struct symbol *sym)); | ||
21 | P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help)); | ||
20 | 22 | ||
21 | /* symbol.c */ | 23 | /* symbol.c */ |
22 | P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]); | 24 | P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]); |
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index 25b60bc117f7..d82953573588 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c | |||
@@ -199,8 +199,6 @@ inputbox_instructions_string[] = N_( | |||
199 | setmod_text[] = N_( | 199 | setmod_text[] = N_( |
200 | "This feature depends on another which has been configured as a module.\n" | 200 | "This feature depends on another which has been configured as a module.\n" |
201 | "As a result, this feature will be built as a module."), | 201 | "As a result, this feature will be built as a module."), |
202 | nohelp_text[] = N_( | ||
203 | "There is no help available for this kernel option.\n"), | ||
204 | load_config_text[] = N_( | 202 | load_config_text[] = N_( |
205 | "Enter the name of the configuration file you wish to load. " | 203 | "Enter the name of the configuration file you wish to load. " |
206 | "Accept the name shown to restore the configuration you " | 204 | "Accept the name shown to restore the configuration you " |
@@ -284,66 +282,6 @@ static void show_textbox(const char *title, const char *text, int r, int c); | |||
284 | static void show_helptext(const char *title, const char *text); | 282 | static void show_helptext(const char *title, const char *text); |
285 | static void show_help(struct menu *menu); | 283 | static void show_help(struct menu *menu); |
286 | 284 | ||
287 | static void get_prompt_str(struct gstr *r, struct property *prop) | ||
288 | { | ||
289 | int i, j; | ||
290 | struct menu *submenu[8], *menu; | ||
291 | |||
292 | str_printf(r, _("Prompt: %s\n"), _(prop->text)); | ||
293 | str_printf(r, _(" Defined at %s:%d\n"), prop->menu->file->name, | ||
294 | prop->menu->lineno); | ||
295 | if (!expr_is_yes(prop->visible.expr)) { | ||
296 | str_append(r, _(" Depends on: ")); | ||
297 | expr_gstr_print(prop->visible.expr, r); | ||
298 | str_append(r, "\n"); | ||
299 | } | ||
300 | menu = prop->menu->parent; | ||
301 | for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) | ||
302 | submenu[i++] = menu; | ||
303 | if (i > 0) { | ||
304 | str_printf(r, _(" Location:\n")); | ||
305 | for (j = 4; --i >= 0; j += 2) { | ||
306 | menu = submenu[i]; | ||
307 | str_printf(r, "%*c-> %s", j, ' ', _(menu_get_prompt(menu))); | ||
308 | if (menu->sym) { | ||
309 | str_printf(r, " (%s [=%s])", menu->sym->name ? | ||
310 | menu->sym->name : _("<choice>"), | ||
311 | sym_get_string_value(menu->sym)); | ||
312 | } | ||
313 | str_append(r, "\n"); | ||
314 | } | ||
315 | } | ||
316 | } | ||
317 | |||
318 | static void get_symbol_str(struct gstr *r, struct symbol *sym) | ||
319 | { | ||
320 | bool hit; | ||
321 | struct property *prop; | ||
322 | |||
323 | if (sym && sym->name) | ||
324 | str_printf(r, "Symbol: %s [=%s]\n", sym->name, | ||
325 | sym_get_string_value(sym)); | ||
326 | for_all_prompts(sym, prop) | ||
327 | get_prompt_str(r, prop); | ||
328 | hit = false; | ||
329 | for_all_properties(sym, prop, P_SELECT) { | ||
330 | if (!hit) { | ||
331 | str_append(r, " Selects: "); | ||
332 | hit = true; | ||
333 | } else | ||
334 | str_printf(r, " && "); | ||
335 | expr_gstr_print(prop->expr, r); | ||
336 | } | ||
337 | if (hit) | ||
338 | str_append(r, "\n"); | ||
339 | if (sym->rev_dep.expr) { | ||
340 | str_append(r, _(" Selected by: ")); | ||
341 | expr_gstr_print(sym->rev_dep.expr, r); | ||
342 | str_append(r, "\n"); | ||
343 | } | ||
344 | str_append(r, "\n\n"); | ||
345 | } | ||
346 | |||
347 | static struct gstr get_relations_str(struct symbol **sym_arr) | 285 | static struct gstr get_relations_str(struct symbol **sym_arr) |
348 | { | 286 | { |
349 | struct symbol *sym; | 287 | struct symbol *sym; |
@@ -699,19 +637,9 @@ static void show_helptext(const char *title, const char *text) | |||
699 | static void show_help(struct menu *menu) | 637 | static void show_help(struct menu *menu) |
700 | { | 638 | { |
701 | struct gstr help = str_new(); | 639 | struct gstr help = str_new(); |
702 | struct symbol *sym = menu->sym; | 640 | |
703 | 641 | menu_get_ext_help(menu, &help); | |
704 | if (menu_has_help(menu)) | 642 | |
705 | { | ||
706 | if (sym->name) { | ||
707 | str_printf(&help, "CONFIG_%s:\n\n", sym->name); | ||
708 | str_append(&help, _(menu_get_help(menu))); | ||
709 | str_append(&help, "\n"); | ||
710 | } | ||
711 | } else { | ||
712 | str_append(&help, nohelp_text); | ||
713 | } | ||
714 | get_symbol_str(&help, sym); | ||
715 | show_helptext(_(menu_get_prompt(menu)), str_get(&help)); | 643 | show_helptext(_(menu_get_prompt(menu)), str_get(&help)); |
716 | str_free(&help); | 644 | str_free(&help); |
717 | } | 645 | } |
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 07ff8d105c9d..059a2465c574 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c | |||
@@ -9,6 +9,9 @@ | |||
9 | #define LKC_DIRECT_LINK | 9 | #define LKC_DIRECT_LINK |
10 | #include "lkc.h" | 10 | #include "lkc.h" |
11 | 11 | ||
12 | static const char nohelp_text[] = N_( | ||
13 | "There is no help available for this kernel option.\n"); | ||
14 | |||
12 | struct menu rootmenu; | 15 | struct menu rootmenu; |
13 | static struct menu **last_entry_ptr; | 16 | static struct menu **last_entry_ptr; |
14 | 17 | ||
@@ -74,7 +77,7 @@ void menu_end_menu(void) | |||
74 | current_menu = current_menu->parent; | 77 | current_menu = current_menu->parent; |
75 | } | 78 | } |
76 | 79 | ||
77 | struct expr *menu_check_dep(struct expr *e) | 80 | static struct expr *menu_check_dep(struct expr *e) |
78 | { | 81 | { |
79 | if (!e) | 82 | if (!e) |
80 | return e; | 83 | return e; |
@@ -184,7 +187,7 @@ static int menu_range_valid_sym(struct symbol *sym, struct symbol *sym2) | |||
184 | (sym2->type == S_UNKNOWN && sym_string_valid(sym, sym2->name)); | 187 | (sym2->type == S_UNKNOWN && sym_string_valid(sym, sym2->name)); |
185 | } | 188 | } |
186 | 189 | ||
187 | void sym_check_prop(struct symbol *sym) | 190 | static void sym_check_prop(struct symbol *sym) |
188 | { | 191 | { |
189 | struct property *prop; | 192 | struct property *prop; |
190 | struct symbol *sym2; | 193 | struct symbol *sym2; |
@@ -451,3 +454,80 @@ const char *menu_get_help(struct menu *menu) | |||
451 | else | 454 | else |
452 | return ""; | 455 | return ""; |
453 | } | 456 | } |
457 | |||
458 | static void get_prompt_str(struct gstr *r, struct property *prop) | ||
459 | { | ||
460 | int i, j; | ||
461 | struct menu *submenu[8], *menu; | ||
462 | |||
463 | str_printf(r, _("Prompt: %s\n"), _(prop->text)); | ||
464 | str_printf(r, _(" Defined at %s:%d\n"), prop->menu->file->name, | ||
465 | prop->menu->lineno); | ||
466 | if (!expr_is_yes(prop->visible.expr)) { | ||
467 | str_append(r, _(" Depends on: ")); | ||
468 | expr_gstr_print(prop->visible.expr, r); | ||
469 | str_append(r, "\n"); | ||
470 | } | ||
471 | menu = prop->menu->parent; | ||
472 | for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) | ||
473 | submenu[i++] = menu; | ||
474 | if (i > 0) { | ||
475 | str_printf(r, _(" Location:\n")); | ||
476 | for (j = 4; --i >= 0; j += 2) { | ||
477 | menu = submenu[i]; | ||
478 | str_printf(r, "%*c-> %s", j, ' ', _(menu_get_prompt(menu))); | ||
479 | if (menu->sym) { | ||
480 | str_printf(r, " (%s [=%s])", menu->sym->name ? | ||
481 | menu->sym->name : _("<choice>"), | ||
482 | sym_get_string_value(menu->sym)); | ||
483 | } | ||
484 | str_append(r, "\n"); | ||
485 | } | ||
486 | } | ||
487 | } | ||
488 | |||
489 | void get_symbol_str(struct gstr *r, struct symbol *sym) | ||
490 | { | ||
491 | bool hit; | ||
492 | struct property *prop; | ||
493 | |||
494 | if (sym && sym->name) | ||
495 | str_printf(r, "Symbol: %s [=%s]\n", sym->name, | ||
496 | sym_get_string_value(sym)); | ||
497 | for_all_prompts(sym, prop) | ||
498 | get_prompt_str(r, prop); | ||
499 | hit = false; | ||
500 | for_all_properties(sym, prop, P_SELECT) { | ||
501 | if (!hit) { | ||
502 | str_append(r, " Selects: "); | ||
503 | hit = true; | ||
504 | } else | ||
505 | str_printf(r, " && "); | ||
506 | expr_gstr_print(prop->expr, r); | ||
507 | } | ||
508 | if (hit) | ||
509 | str_append(r, "\n"); | ||
510 | if (sym->rev_dep.expr) { | ||
511 | str_append(r, _(" Selected by: ")); | ||
512 | expr_gstr_print(sym->rev_dep.expr, r); | ||
513 | str_append(r, "\n"); | ||
514 | } | ||
515 | str_append(r, "\n\n"); | ||
516 | } | ||
517 | |||
518 | void menu_get_ext_help(struct menu *menu, struct gstr *help) | ||
519 | { | ||
520 | struct symbol *sym = menu->sym; | ||
521 | |||
522 | if (menu_has_help(menu)) { | ||
523 | if (sym->name) { | ||
524 | str_printf(help, "CONFIG_%s:\n\n", sym->name); | ||
525 | str_append(help, _(menu_get_help(menu))); | ||
526 | str_append(help, "\n"); | ||
527 | } | ||
528 | } else { | ||
529 | str_append(help, nohelp_text); | ||
530 | } | ||
531 | if (sym) | ||
532 | get_symbol_str(help, sym); | ||
533 | } | ||
diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index ce7d508c7520..00c51507cfcc 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc | |||
@@ -1042,12 +1042,10 @@ void ConfigInfoView::menuInfo(void) | |||
1042 | if (showDebug()) | 1042 | if (showDebug()) |
1043 | debug = debug_info(sym); | 1043 | debug = debug_info(sym); |
1044 | 1044 | ||
1045 | help = menu_get_help(menu); | 1045 | struct gstr help_gstr = str_new(); |
1046 | /* Gettextize if the help text not empty */ | 1046 | menu_get_ext_help(menu, &help_gstr); |
1047 | if (help.isEmpty()) | 1047 | help = print_filter(str_get(&help_gstr)); |
1048 | help = print_filter(menu_get_help(menu)); | 1048 | str_free(&help_gstr); |
1049 | else | ||
1050 | help = print_filter(_(menu_get_help(menu))); | ||
1051 | } else if (menu->prompt) { | 1049 | } else if (menu->prompt) { |
1052 | head += "<big><b>"; | 1050 | head += "<big><b>"; |
1053 | head += print_filter(_(menu->prompt->text)); | 1051 | head += print_filter(_(menu->prompt->text)); |
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 18f3e5c33634..6c8fbbb66ebc 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c | |||
@@ -36,7 +36,7 @@ tristate modules_val; | |||
36 | 36 | ||
37 | struct expr *sym_env_list; | 37 | struct expr *sym_env_list; |
38 | 38 | ||
39 | void sym_add_default(struct symbol *sym, const char *def) | 39 | static void sym_add_default(struct symbol *sym, const char *def) |
40 | { | 40 | { |
41 | struct property *prop = prop_alloc(P_DEFAULT, sym); | 41 | struct property *prop = prop_alloc(P_DEFAULT, sym); |
42 | 42 | ||
@@ -125,7 +125,7 @@ struct property *sym_get_default_prop(struct symbol *sym) | |||
125 | return NULL; | 125 | return NULL; |
126 | } | 126 | } |
127 | 127 | ||
128 | struct property *sym_get_range_prop(struct symbol *sym) | 128 | static struct property *sym_get_range_prop(struct symbol *sym) |
129 | { | 129 | { |
130 | struct property *prop; | 130 | struct property *prop; |
131 | 131 | ||
@@ -943,7 +943,7 @@ const char *prop_get_type_name(enum prop_type type) | |||
943 | return "unknown"; | 943 | return "unknown"; |
944 | } | 944 | } |
945 | 945 | ||
946 | void prop_add_env(const char *env) | 946 | static void prop_add_env(const char *env) |
947 | { | 947 | { |
948 | struct symbol *sym, *sym2; | 948 | struct symbol *sym, *sym2; |
949 | struct property *prop; | 949 | struct property *prop; |
diff --git a/scripts/markup_oops.pl b/scripts/markup_oops.pl index 89774011965d..5f0fcb712e29 100644 --- a/scripts/markup_oops.pl +++ b/scripts/markup_oops.pl | |||
@@ -184,10 +184,7 @@ if ($target eq "0") { | |||
184 | 184 | ||
185 | # if it's a module, we need to find the .ko file and calculate a load offset | 185 | # if it's a module, we need to find the .ko file and calculate a load offset |
186 | if ($module ne "") { | 186 | if ($module ne "") { |
187 | my $dir = dirname($filename); | 187 | my $modulefile = `modinfo $module | grep '^filename:' | awk '{ print \$2 }'`; |
188 | $dir = $dir . "/"; | ||
189 | my $mod = $module . ".ko"; | ||
190 | my $modulefile = `find $dir -name $mod | head -1`; | ||
191 | chomp($modulefile); | 188 | chomp($modulefile); |
192 | $filename = $modulefile; | 189 | $filename = $modulefile; |
193 | if ($filename eq "") { | 190 | if ($filename eq "") { |
diff --git a/scripts/tags.sh b/scripts/tags.sh index 4a34ec591e8c..d52f7a01557c 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh | |||
@@ -101,7 +101,8 @@ exuberant() | |||
101 | -I ____cacheline_aligned_in_smp \ | 101 | -I ____cacheline_aligned_in_smp \ |
102 | -I ____cacheline_internodealigned_in_smp \ | 102 | -I ____cacheline_internodealigned_in_smp \ |
103 | -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \ | 103 | -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \ |
104 | --extra=+f --c-kinds=+px \ | 104 | -I DEFINE_TRACE,EXPORT_TRACEPOINT_SYMBOL,EXPORT_TRACEPOINT_SYMBOL_GPL \ |
105 | --extra=+f --c-kinds=-px \ | ||
105 | --regex-asm='/^ENTRY\(([^)]*)\).*/\1/' \ | 106 | --regex-asm='/^ENTRY\(([^)]*)\).*/\1/' \ |
106 | --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' | 107 | --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' |
107 | 108 | ||
diff --git a/security/keys/gc.c b/security/keys/gc.c index 485fc6233c38..4770be375ffe 100644 --- a/security/keys/gc.c +++ b/security/keys/gc.c | |||
@@ -169,9 +169,9 @@ static void key_garbage_collector(struct work_struct *work) | |||
169 | 169 | ||
170 | /* trawl through the keys looking for keyrings */ | 170 | /* trawl through the keys looking for keyrings */ |
171 | for (;;) { | 171 | for (;;) { |
172 | if (key->expiry > now && key->expiry < new_timer) { | 172 | if (key->expiry > limit && key->expiry < new_timer) { |
173 | kdebug("will expire %x in %ld", | 173 | kdebug("will expire %x in %ld", |
174 | key_serial(key), key->expiry - now); | 174 | key_serial(key), key->expiry - limit); |
175 | new_timer = key->expiry; | 175 | new_timer = key->expiry; |
176 | } | 176 | } |
177 | 177 | ||
diff --git a/security/selinux/avc.c b/security/selinux/avc.c index 1ed0f076aadc..b4b5da1c0a42 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c | |||
@@ -868,8 +868,19 @@ u32 avc_policy_seqno(void) | |||
868 | 868 | ||
869 | void avc_disable(void) | 869 | void avc_disable(void) |
870 | { | 870 | { |
871 | avc_flush(); | 871 | /* |
872 | synchronize_rcu(); | 872 | * If you are looking at this because you have realized that we are |
873 | if (avc_node_cachep) | 873 | * not destroying the avc_node_cachep it might be easy to fix, but |
874 | kmem_cache_destroy(avc_node_cachep); | 874 | * I don't know the memory barrier semantics well enough to know. It's |
875 | * possible that some other task dereferenced security_ops when | ||
876 | * it still pointed to selinux operations. If that is the case it's | ||
877 | * possible that it is about to use the avc and is about to need the | ||
878 | * avc_node_cachep. I know I could wrap the security.c security_ops call | ||
879 | * in an rcu_lock, but seriously, it's not worth it. Instead I just flush | ||
880 | * the cache and get that memory back. | ||
881 | */ | ||
882 | if (avc_node_cachep) { | ||
883 | avc_flush(); | ||
884 | /* kmem_cache_destroy(avc_node_cachep); */ | ||
885 | } | ||
875 | } | 886 | } |
diff --git a/usr/.gitignore b/usr/.gitignore index 69b2e89fa165..8e48117a3f3d 100644 --- a/usr/.gitignore +++ b/usr/.gitignore | |||
@@ -4,5 +4,7 @@ | |||
4 | gen_init_cpio | 4 | gen_init_cpio |
5 | initramfs_data.cpio | 5 | initramfs_data.cpio |
6 | initramfs_data.cpio.gz | 6 | initramfs_data.cpio.gz |
7 | initramfs_data.cpio.bz2 | ||
8 | initramfs_data.cpio.lzma | ||
7 | initramfs_list | 9 | initramfs_list |
8 | include | 10 | include |
diff --git a/usr/Makefile b/usr/Makefile index 245145a99c10..1e6a9e4a72cc 100644 --- a/usr/Makefile +++ b/usr/Makefile | |||
@@ -6,7 +6,7 @@ klibcdirs:; | |||
6 | PHONY += klibcdirs | 6 | PHONY += klibcdirs |
7 | 7 | ||
8 | 8 | ||
9 | # Gzip, but no bzip2 | 9 | # Gzip |
10 | suffix_$(CONFIG_INITRAMFS_COMPRESSION_GZIP) = .gz | 10 | suffix_$(CONFIG_INITRAMFS_COMPRESSION_GZIP) = .gz |
11 | 11 | ||
12 | # Bzip2 | 12 | # Bzip2 |