aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/macintosh
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/macintosh
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/macintosh')
-rw-r--r--drivers/macintosh/Kconfig27
-rw-r--r--drivers/macintosh/Makefile2
-rw-r--r--drivers/macintosh/adb-iop.c4
-rw-r--r--drivers/macintosh/adb.c12
-rw-r--r--drivers/macintosh/adbhid.c2
-rw-r--r--drivers/macintosh/ams/Makefile8
-rw-r--r--drivers/macintosh/ams/ams-core.c250
-rw-r--r--drivers/macintosh/ams/ams-i2c.c277
-rw-r--r--drivers/macintosh/ams/ams-input.c157
-rw-r--r--drivers/macintosh/ams/ams-pmu.c201
-rw-r--r--drivers/macintosh/ams/ams.h70
-rw-r--r--drivers/macintosh/ans-lcd.c1
-rw-r--r--drivers/macintosh/mac_hid.c8
-rw-r--r--drivers/macintosh/macio-adb.c2
-rw-r--r--drivers/macintosh/macio_asic.c7
-rw-r--r--drivers/macintosh/rack-meter.c6
-rw-r--r--drivers/macintosh/smu.c13
-rw-r--r--drivers/macintosh/therm_adt746x.c8
-rw-r--r--drivers/macintosh/therm_pm72.c110
-rw-r--r--drivers/macintosh/therm_windtunnel.c11
-rw-r--r--drivers/macintosh/via-pmu-backlight.c5
-rw-r--r--drivers/macintosh/via-pmu-led.c4
-rw-r--r--drivers/macintosh/via-pmu.c70
-rw-r--r--drivers/macintosh/windfarm_pm121.c2
24 files changed, 1104 insertions, 153 deletions
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig
index fd85bde283a0..fa51af11c6f1 100644
--- a/drivers/macintosh/Kconfig
+++ b/drivers/macintosh/Kconfig
@@ -102,6 +102,7 @@ config ADB_PMU_LED
102config ADB_PMU_LED_IDE 102config ADB_PMU_LED_IDE
103 bool "Use front LED as IDE LED by default" 103 bool "Use front LED as IDE LED by default"
104 depends on ADB_PMU_LED 104 depends on ADB_PMU_LED
105 depends on LEDS_CLASS
105 select LEDS_TRIGGERS 106 select LEDS_TRIGGERS
106 select LEDS_TRIGGER_IDE_DISK 107 select LEDS_TRIGGER_IDE_DISK
107 help 108 help
@@ -256,4 +257,30 @@ config PMAC_RACKMETER
256 This driver provides some support to control the front panel 257 This driver provides some support to control the front panel
257 blue LEDs "vu-meter" of the XServer macs. 258 blue LEDs "vu-meter" of the XServer macs.
258 259
260config SENSORS_AMS
261 tristate "Apple Motion Sensor driver"
262 depends on PPC_PMAC && !PPC64 && INPUT && ((ADB_PMU && I2C = y) || (ADB_PMU && !I2C) || I2C) && EXPERIMENTAL
263 select INPUT_POLLDEV
264 help
265 Support for the motion sensor included in PowerBooks. Includes
266 implementations for PMU and I2C.
267
268 This driver can also be built as a module. If so, the module
269 will be called ams.
270
271config SENSORS_AMS_PMU
272 bool "PMU variant"
273 depends on SENSORS_AMS && ADB_PMU
274 default y
275 help
276 PMU variant of motion sensor, found in late 2005 PowerBooks.
277
278config SENSORS_AMS_I2C
279 bool "I2C variant"
280 depends on SENSORS_AMS && I2C
281 default y
282 help
283 I2C variant of motion sensor, found in early 2005 PowerBooks and
284 iBooks.
285
259endif # MACINTOSH_DRIVERS 286endif # MACINTOSH_DRIVERS
diff --git a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile
index e3132efa17c0..6652a6ebb6fa 100644
--- a/drivers/macintosh/Makefile
+++ b/drivers/macintosh/Makefile
@@ -48,3 +48,5 @@ obj-$(CONFIG_WINDFARM_PM121) += windfarm_pm121.o windfarm_smu_sat.o \
48 windfarm_max6690_sensor.o \ 48 windfarm_max6690_sensor.o \
49 windfarm_lm75_sensor.o windfarm_pid.o 49 windfarm_lm75_sensor.o windfarm_pid.o
50obj-$(CONFIG_PMAC_RACKMETER) += rack-meter.o 50obj-$(CONFIG_PMAC_RACKMETER) += rack-meter.o
51
52obj-$(CONFIG_SENSORS_AMS) += ams/
diff --git a/drivers/macintosh/adb-iop.c b/drivers/macintosh/adb-iop.c
index 444696625171..f5f4da3d0b67 100644
--- a/drivers/macintosh/adb-iop.c
+++ b/drivers/macintosh/adb-iop.c
@@ -80,7 +80,7 @@ static void adb_iop_end_req(struct adb_request *req, int state)
80static void adb_iop_complete(struct iop_msg *msg) 80static void adb_iop_complete(struct iop_msg *msg)
81{ 81{
82 struct adb_request *req; 82 struct adb_request *req;
83 uint flags; 83 unsigned long flags;
84 84
85 local_irq_save(flags); 85 local_irq_save(flags);
86 86
@@ -103,7 +103,7 @@ static void adb_iop_listen(struct iop_msg *msg)
103{ 103{
104 struct adb_iopmsg *amsg = (struct adb_iopmsg *) msg->message; 104 struct adb_iopmsg *amsg = (struct adb_iopmsg *) msg->message;
105 struct adb_request *req; 105 struct adb_request *req;
106 uint flags; 106 unsigned long flags;
107#ifdef DEBUG_ADB_IOP 107#ifdef DEBUG_ADB_IOP
108 int i; 108 int i;
109#endif 109#endif
diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c
index 1c4ee6e77937..75049e765191 100644
--- a/drivers/macintosh/adb.c
+++ b/drivers/macintosh/adb.c
@@ -24,7 +24,6 @@
24#include <linux/fs.h> 24#include <linux/fs.h>
25#include <linux/mm.h> 25#include <linux/mm.h>
26#include <linux/sched.h> 26#include <linux/sched.h>
27#include <linux/smp_lock.h>
28#include <linux/adb.h> 27#include <linux/adb.h>
29#include <linux/cuda.h> 28#include <linux/cuda.h>
30#include <linux/pmu.h> 29#include <linux/pmu.h>
@@ -55,6 +54,7 @@ extern struct adb_driver adb_iop_driver;
55extern struct adb_driver via_pmu_driver; 54extern struct adb_driver via_pmu_driver;
56extern struct adb_driver macio_adb_driver; 55extern struct adb_driver macio_adb_driver;
57 56
57static DEFINE_MUTEX(adb_mutex);
58static struct adb_driver *adb_driver_list[] = { 58static struct adb_driver *adb_driver_list[] = {
59#ifdef CONFIG_ADB_MACII 59#ifdef CONFIG_ADB_MACII
60 &via_macii_driver, 60 &via_macii_driver,
@@ -83,7 +83,7 @@ static struct adb_driver *adb_controller;
83BLOCKING_NOTIFIER_HEAD(adb_client_list); 83BLOCKING_NOTIFIER_HEAD(adb_client_list);
84static int adb_got_sleep; 84static int adb_got_sleep;
85static int adb_inited; 85static int adb_inited;
86static DECLARE_MUTEX(adb_probe_mutex); 86static DEFINE_SEMAPHORE(adb_probe_mutex);
87static int sleepy_trackpad; 87static int sleepy_trackpad;
88static int autopoll_devs; 88static int autopoll_devs;
89int __adb_probe_sync; 89int __adb_probe_sync;
@@ -647,7 +647,7 @@ static int adb_open(struct inode *inode, struct file *file)
647 struct adbdev_state *state; 647 struct adbdev_state *state;
648 int ret = 0; 648 int ret = 0;
649 649
650 lock_kernel(); 650 mutex_lock(&adb_mutex);
651 if (iminor(inode) > 0 || adb_controller == NULL) { 651 if (iminor(inode) > 0 || adb_controller == NULL) {
652 ret = -ENXIO; 652 ret = -ENXIO;
653 goto out; 653 goto out;
@@ -665,7 +665,7 @@ static int adb_open(struct inode *inode, struct file *file)
665 state->inuse = 1; 665 state->inuse = 1;
666 666
667out: 667out:
668 unlock_kernel(); 668 mutex_unlock(&adb_mutex);
669 return ret; 669 return ret;
670} 670}
671 671
@@ -674,7 +674,7 @@ static int adb_release(struct inode *inode, struct file *file)
674 struct adbdev_state *state = file->private_data; 674 struct adbdev_state *state = file->private_data;
675 unsigned long flags; 675 unsigned long flags;
676 676
677 lock_kernel(); 677 mutex_lock(&adb_mutex);
678 if (state) { 678 if (state) {
679 file->private_data = NULL; 679 file->private_data = NULL;
680 spin_lock_irqsave(&state->lock, flags); 680 spin_lock_irqsave(&state->lock, flags);
@@ -687,7 +687,7 @@ static int adb_release(struct inode *inode, struct file *file)
687 spin_unlock_irqrestore(&state->lock, flags); 687 spin_unlock_irqrestore(&state->lock, flags);
688 } 688 }
689 } 689 }
690 unlock_kernel(); 690 mutex_unlock(&adb_mutex);
691 return 0; 691 return 0;
692} 692}
693 693
diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c
index 5396c67ba0a4..09d72bb00d12 100644
--- a/drivers/macintosh/adbhid.c
+++ b/drivers/macintosh/adbhid.c
@@ -328,7 +328,7 @@ adbhid_input_keycode(int id, int scancode, int repeat)
328 switch (keycode) { 328 switch (keycode) {
329 case ADB_KEY_CAPSLOCK: 329 case ADB_KEY_CAPSLOCK:
330 if (!restore_capslock_events) { 330 if (!restore_capslock_events) {
331 /* Generate down/up events for CapsLock everytime. */ 331 /* Generate down/up events for CapsLock every time. */
332 input_report_key(ahid->input, KEY_CAPSLOCK, 1); 332 input_report_key(ahid->input, KEY_CAPSLOCK, 1);
333 input_sync(ahid->input); 333 input_sync(ahid->input);
334 input_report_key(ahid->input, KEY_CAPSLOCK, 0); 334 input_report_key(ahid->input, KEY_CAPSLOCK, 0);
diff --git a/drivers/macintosh/ams/Makefile b/drivers/macintosh/ams/Makefile
new file mode 100644
index 000000000000..41c95b2089dc
--- /dev/null
+++ b/drivers/macintosh/ams/Makefile
@@ -0,0 +1,8 @@
1#
2# Makefile for Apple Motion Sensor driver
3#
4
5ams-y := ams-core.o ams-input.o
6ams-$(CONFIG_SENSORS_AMS_PMU) += ams-pmu.o
7ams-$(CONFIG_SENSORS_AMS_I2C) += ams-i2c.o
8obj-$(CONFIG_SENSORS_AMS) += ams.o
diff --git a/drivers/macintosh/ams/ams-core.c b/drivers/macintosh/ams/ams-core.c
new file mode 100644
index 000000000000..399beb1638d1
--- /dev/null
+++ b/drivers/macintosh/ams/ams-core.c
@@ -0,0 +1,250 @@
1/*
2 * Apple Motion Sensor driver
3 *
4 * Copyright (C) 2005 Stelian Pop (stelian@popies.net)
5 * Copyright (C) 2006 Michael Hanselmann (linux-kernel@hansmi.ch)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 */
21
22#include <linux/module.h>
23#include <linux/types.h>
24#include <linux/errno.h>
25#include <linux/init.h>
26#include <linux/of_platform.h>
27#include <asm/pmac_pfunc.h>
28
29#include "ams.h"
30
31/* There is only one motion sensor per machine */
32struct ams ams_info;
33
34static unsigned int verbose;
35module_param(verbose, bool, 0644);
36MODULE_PARM_DESC(verbose, "Show free falls and shocks in kernel output");
37
38/* Call with ams_info.lock held! */
39void ams_sensors(s8 *x, s8 *y, s8 *z)
40{
41 u32 orient = ams_info.vflag? ams_info.orient1 : ams_info.orient2;
42
43 if (orient & 0x80)
44 /* X and Y swapped */
45 ams_info.get_xyz(y, x, z);
46 else
47 ams_info.get_xyz(x, y, z);
48
49 if (orient & 0x04)
50 *z = ~(*z);
51 if (orient & 0x02)
52 *y = ~(*y);
53 if (orient & 0x01)
54 *x = ~(*x);
55}
56
57static ssize_t ams_show_current(struct device *dev,
58 struct device_attribute *attr, char *buf)
59{
60 s8 x, y, z;
61
62 mutex_lock(&ams_info.lock);
63 ams_sensors(&x, &y, &z);
64 mutex_unlock(&ams_info.lock);
65
66 return snprintf(buf, PAGE_SIZE, "%d %d %d\n", x, y, z);
67}
68
69static DEVICE_ATTR(current, S_IRUGO, ams_show_current, NULL);
70
71static void ams_handle_irq(void *data)
72{
73 enum ams_irq irq = *((enum ams_irq *)data);
74
75 spin_lock(&ams_info.irq_lock);
76
77 ams_info.worker_irqs |= irq;
78 schedule_work(&ams_info.worker);
79
80 spin_unlock(&ams_info.irq_lock);
81}
82
83static enum ams_irq ams_freefall_irq_data = AMS_IRQ_FREEFALL;
84static struct pmf_irq_client ams_freefall_client = {
85 .owner = THIS_MODULE,
86 .handler = ams_handle_irq,
87 .data = &ams_freefall_irq_data,
88};
89
90static enum ams_irq ams_shock_irq_data = AMS_IRQ_SHOCK;
91static struct pmf_irq_client ams_shock_client = {
92 .owner = THIS_MODULE,
93 .handler = ams_handle_irq,
94 .data = &ams_shock_irq_data,
95};
96
97/* Once hard disk parking is implemented in the kernel, this function can
98 * trigger it.
99 */
100static void ams_worker(struct work_struct *work)
101{
102 unsigned long flags;
103 u8 irqs_to_clear;
104
105 mutex_lock(&ams_info.lock);
106
107 spin_lock_irqsave(&ams_info.irq_lock, flags);
108 irqs_to_clear = ams_info.worker_irqs;
109
110 if (ams_info.worker_irqs & AMS_IRQ_FREEFALL) {
111 if (verbose)
112 printk(KERN_INFO "ams: freefall detected!\n");
113
114 ams_info.worker_irqs &= ~AMS_IRQ_FREEFALL;
115 }
116
117 if (ams_info.worker_irqs & AMS_IRQ_SHOCK) {
118 if (verbose)
119 printk(KERN_INFO "ams: shock detected!\n");
120
121 ams_info.worker_irqs &= ~AMS_IRQ_SHOCK;
122 }
123
124 spin_unlock_irqrestore(&ams_info.irq_lock, flags);
125
126 ams_info.clear_irq(irqs_to_clear);
127
128 mutex_unlock(&ams_info.lock);
129}
130
131/* Call with ams_info.lock held! */
132int ams_sensor_attach(void)
133{
134 int result;
135 const u32 *prop;
136
137 /* Get orientation */
138 prop = of_get_property(ams_info.of_node, "orientation", NULL);
139 if (!prop)
140 return -ENODEV;
141 ams_info.orient1 = *prop;
142 ams_info.orient2 = *(prop + 1);
143
144 /* Register freefall interrupt handler */
145 result = pmf_register_irq_client(ams_info.of_node,
146 "accel-int-1",
147 &ams_freefall_client);
148 if (result < 0)
149 return -ENODEV;
150
151 /* Reset saved irqs */
152 ams_info.worker_irqs = 0;
153
154 /* Register shock interrupt handler */
155 result = pmf_register_irq_client(ams_info.of_node,
156 "accel-int-2",
157 &ams_shock_client);
158 if (result < 0)
159 goto release_freefall;
160
161 /* Create device */
162 ams_info.of_dev = of_platform_device_create(ams_info.of_node, "ams", NULL);
163 if (!ams_info.of_dev) {
164 result = -ENODEV;
165 goto release_shock;
166 }
167
168 /* Create attributes */
169 result = device_create_file(&ams_info.of_dev->dev, &dev_attr_current);
170 if (result)
171 goto release_of;
172
173 ams_info.vflag = !!(ams_info.get_vendor() & 0x10);
174
175 /* Init input device */
176 result = ams_input_init();
177 if (result)
178 goto release_device_file;
179
180 return result;
181release_device_file:
182 device_remove_file(&ams_info.of_dev->dev, &dev_attr_current);
183release_of:
184 of_device_unregister(ams_info.of_dev);
185release_shock:
186 pmf_unregister_irq_client(&ams_shock_client);
187release_freefall:
188 pmf_unregister_irq_client(&ams_freefall_client);
189 return result;
190}
191
192int __init ams_init(void)
193{
194 struct device_node *np;
195
196 spin_lock_init(&ams_info.irq_lock);
197 mutex_init(&ams_info.lock);
198 INIT_WORK(&ams_info.worker, ams_worker);
199
200#ifdef CONFIG_SENSORS_AMS_I2C
201 np = of_find_node_by_name(NULL, "accelerometer");
202 if (np && of_device_is_compatible(np, "AAPL,accelerometer_1"))
203 /* Found I2C motion sensor */
204 return ams_i2c_init(np);
205#endif
206
207#ifdef CONFIG_SENSORS_AMS_PMU
208 np = of_find_node_by_name(NULL, "sms");
209 if (np && of_device_is_compatible(np, "sms"))
210 /* Found PMU motion sensor */
211 return ams_pmu_init(np);
212#endif
213 return -ENODEV;
214}
215
216void ams_sensor_detach(void)
217{
218 /* Remove input device */
219 ams_input_exit();
220
221 /* Remove attributes */
222 device_remove_file(&ams_info.of_dev->dev, &dev_attr_current);
223
224 /* Flush interrupt worker
225 *
226 * We do this after ams_info.exit(), because an interrupt might
227 * have arrived before disabling them.
228 */
229 flush_work_sync(&ams_info.worker);
230
231 /* Remove device */
232 of_device_unregister(ams_info.of_dev);
233
234 /* Remove handler */
235 pmf_unregister_irq_client(&ams_shock_client);
236 pmf_unregister_irq_client(&ams_freefall_client);
237}
238
239static void __exit ams_exit(void)
240{
241 /* Shut down implementation */
242 ams_info.exit();
243}
244
245MODULE_AUTHOR("Stelian Pop, Michael Hanselmann");
246MODULE_DESCRIPTION("Apple Motion Sensor driver");
247MODULE_LICENSE("GPL");
248
249module_init(ams_init);
250module_exit(ams_exit);
diff --git a/drivers/macintosh/ams/ams-i2c.c b/drivers/macintosh/ams/ams-i2c.c
new file mode 100644
index 000000000000..abeecd27b484
--- /dev/null
+++ b/drivers/macintosh/ams/ams-i2c.c
@@ -0,0 +1,277 @@
1/*
2 * Apple Motion Sensor driver (I2C variant)
3 *
4 * Copyright (C) 2005 Stelian Pop (stelian@popies.net)
5 * Copyright (C) 2006 Michael Hanselmann (linux-kernel@hansmi.ch)
6 *
7 * Clean room implementation based on the reverse engineered Mac OS X driver by
8 * Johannes Berg <johannes@sipsolutions.net>, documentation available at
9 * http://johannes.sipsolutions.net/PowerBook/Apple_Motion_Sensor_Specification
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 */
16
17#include <linux/module.h>
18#include <linux/types.h>
19#include <linux/errno.h>
20#include <linux/init.h>
21#include <linux/delay.h>
22
23#include "ams.h"
24
25/* AMS registers */
26#define AMS_COMMAND 0x00 /* command register */
27#define AMS_STATUS 0x01 /* status register */
28#define AMS_CTRL1 0x02 /* read control 1 (number of values) */
29#define AMS_CTRL2 0x03 /* read control 2 (offset?) */
30#define AMS_CTRL3 0x04 /* read control 3 (size of each value?) */
31#define AMS_DATA1 0x05 /* read data 1 */
32#define AMS_DATA2 0x06 /* read data 2 */
33#define AMS_DATA3 0x07 /* read data 3 */
34#define AMS_DATA4 0x08 /* read data 4 */
35#define AMS_DATAX 0x20 /* data X */
36#define AMS_DATAY 0x21 /* data Y */
37#define AMS_DATAZ 0x22 /* data Z */
38#define AMS_FREEFALL 0x24 /* freefall int control */
39#define AMS_SHOCK 0x25 /* shock int control */
40#define AMS_SENSLOW 0x26 /* sensitivity low limit */
41#define AMS_SENSHIGH 0x27 /* sensitivity high limit */
42#define AMS_CTRLX 0x28 /* control X */
43#define AMS_CTRLY 0x29 /* control Y */
44#define AMS_CTRLZ 0x2A /* control Z */
45#define AMS_UNKNOWN1 0x2B /* unknown 1 */
46#define AMS_UNKNOWN2 0x2C /* unknown 2 */
47#define AMS_UNKNOWN3 0x2D /* unknown 3 */
48#define AMS_VENDOR 0x2E /* vendor */
49
50/* AMS commands - use with the AMS_COMMAND register */
51enum ams_i2c_cmd {
52 AMS_CMD_NOOP = 0,
53 AMS_CMD_VERSION,
54 AMS_CMD_READMEM,
55 AMS_CMD_WRITEMEM,
56 AMS_CMD_ERASEMEM,
57 AMS_CMD_READEE,
58 AMS_CMD_WRITEEE,
59 AMS_CMD_RESET,
60 AMS_CMD_START,
61};
62
63static int ams_i2c_probe(struct i2c_client *client,
64 const struct i2c_device_id *id);
65static int ams_i2c_remove(struct i2c_client *client);
66
67static const struct i2c_device_id ams_id[] = {
68 { "ams", 0 },
69 { }
70};
71MODULE_DEVICE_TABLE(i2c, ams_id);
72
73static struct i2c_driver ams_i2c_driver = {
74 .driver = {
75 .name = "ams",
76 .owner = THIS_MODULE,
77 },
78 .probe = ams_i2c_probe,
79 .remove = ams_i2c_remove,
80 .id_table = ams_id,
81};
82
83static s32 ams_i2c_read(u8 reg)
84{
85 return i2c_smbus_read_byte_data(ams_info.i2c_client, reg);
86}
87
88static int ams_i2c_write(u8 reg, u8 value)
89{
90 return i2c_smbus_write_byte_data(ams_info.i2c_client, reg, value);
91}
92
93static int ams_i2c_cmd(enum ams_i2c_cmd cmd)
94{
95 s32 result;
96 int count = 3;
97
98 ams_i2c_write(AMS_COMMAND, cmd);
99 msleep(5);
100
101 while (count--) {
102 result = ams_i2c_read(AMS_COMMAND);
103 if (result == 0 || result & 0x80)
104 return 0;
105
106 schedule_timeout_uninterruptible(HZ / 20);
107 }
108
109 return -1;
110}
111
112static void ams_i2c_set_irq(enum ams_irq reg, char enable)
113{
114 if (reg & AMS_IRQ_FREEFALL) {
115 u8 val = ams_i2c_read(AMS_CTRLX);
116 if (enable)
117 val |= 0x80;
118 else
119 val &= ~0x80;
120 ams_i2c_write(AMS_CTRLX, val);
121 }
122
123 if (reg & AMS_IRQ_SHOCK) {
124 u8 val = ams_i2c_read(AMS_CTRLY);
125 if (enable)
126 val |= 0x80;
127 else
128 val &= ~0x80;
129 ams_i2c_write(AMS_CTRLY, val);
130 }
131
132 if (reg & AMS_IRQ_GLOBAL) {
133 u8 val = ams_i2c_read(AMS_CTRLZ);
134 if (enable)
135 val |= 0x80;
136 else
137 val &= ~0x80;
138 ams_i2c_write(AMS_CTRLZ, val);
139 }
140}
141
142static void ams_i2c_clear_irq(enum ams_irq reg)
143{
144 if (reg & AMS_IRQ_FREEFALL)
145 ams_i2c_write(AMS_FREEFALL, 0);
146
147 if (reg & AMS_IRQ_SHOCK)
148 ams_i2c_write(AMS_SHOCK, 0);
149}
150
151static u8 ams_i2c_get_vendor(void)
152{
153 return ams_i2c_read(AMS_VENDOR);
154}
155
156static void ams_i2c_get_xyz(s8 *x, s8 *y, s8 *z)
157{
158 *x = ams_i2c_read(AMS_DATAX);
159 *y = ams_i2c_read(AMS_DATAY);
160 *z = ams_i2c_read(AMS_DATAZ);
161}
162
163static int ams_i2c_probe(struct i2c_client *client,
164 const struct i2c_device_id *id)
165{
166 int vmaj, vmin;
167 int result;
168
169 /* There can be only one */
170 if (unlikely(ams_info.has_device))
171 return -ENODEV;
172
173 ams_info.i2c_client = client;
174
175 if (ams_i2c_cmd(AMS_CMD_RESET)) {
176 printk(KERN_INFO "ams: Failed to reset the device\n");
177 return -ENODEV;
178 }
179
180 if (ams_i2c_cmd(AMS_CMD_START)) {
181 printk(KERN_INFO "ams: Failed to start the device\n");
182 return -ENODEV;
183 }
184
185 /* get version/vendor information */
186 ams_i2c_write(AMS_CTRL1, 0x02);
187 ams_i2c_write(AMS_CTRL2, 0x85);
188 ams_i2c_write(AMS_CTRL3, 0x01);
189
190 ams_i2c_cmd(AMS_CMD_READMEM);
191
192 vmaj = ams_i2c_read(AMS_DATA1);
193 vmin = ams_i2c_read(AMS_DATA2);
194 if (vmaj != 1 || vmin != 52) {
195 printk(KERN_INFO "ams: Incorrect device version (%d.%d)\n",
196 vmaj, vmin);
197 return -ENODEV;
198 }
199
200 ams_i2c_cmd(AMS_CMD_VERSION);
201
202 vmaj = ams_i2c_read(AMS_DATA1);
203 vmin = ams_i2c_read(AMS_DATA2);
204 if (vmaj != 0 || vmin != 1) {
205 printk(KERN_INFO "ams: Incorrect firmware version (%d.%d)\n",
206 vmaj, vmin);
207 return -ENODEV;
208 }
209
210 /* Disable interrupts */
211 ams_i2c_set_irq(AMS_IRQ_ALL, 0);
212
213 result = ams_sensor_attach();
214 if (result < 0)
215 return result;
216
217 /* Set default values */
218 ams_i2c_write(AMS_SENSLOW, 0x15);
219 ams_i2c_write(AMS_SENSHIGH, 0x60);
220 ams_i2c_write(AMS_CTRLX, 0x08);
221 ams_i2c_write(AMS_CTRLY, 0x0F);
222 ams_i2c_write(AMS_CTRLZ, 0x4F);
223 ams_i2c_write(AMS_UNKNOWN1, 0x14);
224
225 /* Clear interrupts */
226 ams_i2c_clear_irq(AMS_IRQ_ALL);
227
228 ams_info.has_device = 1;
229
230 /* Enable interrupts */
231 ams_i2c_set_irq(AMS_IRQ_ALL, 1);
232
233 printk(KERN_INFO "ams: Found I2C based motion sensor\n");
234
235 return 0;
236}
237
238static int ams_i2c_remove(struct i2c_client *client)
239{
240 if (ams_info.has_device) {
241 ams_sensor_detach();
242
243 /* Disable interrupts */
244 ams_i2c_set_irq(AMS_IRQ_ALL, 0);
245
246 /* Clear interrupts */
247 ams_i2c_clear_irq(AMS_IRQ_ALL);
248
249 printk(KERN_INFO "ams: Unloading\n");
250
251 ams_info.has_device = 0;
252 }
253
254 return 0;
255}
256
257static void ams_i2c_exit(void)
258{
259 i2c_del_driver(&ams_i2c_driver);
260}
261
262int __init ams_i2c_init(struct device_node *np)
263{
264 int result;
265
266 /* Set implementation stuff */
267 ams_info.of_node = np;
268 ams_info.exit = ams_i2c_exit;
269 ams_info.get_vendor = ams_i2c_get_vendor;
270 ams_info.get_xyz = ams_i2c_get_xyz;
271 ams_info.clear_irq = ams_i2c_clear_irq;
272 ams_info.bustype = BUS_I2C;
273
274 result = i2c_add_driver(&ams_i2c_driver);
275
276 return result;
277}
diff --git a/drivers/macintosh/ams/ams-input.c b/drivers/macintosh/ams/ams-input.c
new file mode 100644
index 000000000000..8a712392cd38
--- /dev/null
+++ b/drivers/macintosh/ams/ams-input.c
@@ -0,0 +1,157 @@
1/*
2 * Apple Motion Sensor driver (joystick emulation)
3 *
4 * Copyright (C) 2005 Stelian Pop (stelian@popies.net)
5 * Copyright (C) 2006 Michael Hanselmann (linux-kernel@hansmi.ch)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <linux/module.h>
14
15#include <linux/types.h>
16#include <linux/errno.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19
20#include "ams.h"
21
22static unsigned int joystick;
23module_param(joystick, bool, S_IRUGO);
24MODULE_PARM_DESC(joystick, "Enable the input class device on module load");
25
26static unsigned int invert;
27module_param(invert, bool, S_IWUSR | S_IRUGO);
28MODULE_PARM_DESC(invert, "Invert input data on X and Y axis");
29
30static DEFINE_MUTEX(ams_input_mutex);
31
32static void ams_idev_poll(struct input_polled_dev *dev)
33{
34 struct input_dev *idev = dev->input;
35 s8 x, y, z;
36
37 mutex_lock(&ams_info.lock);
38
39 ams_sensors(&x, &y, &z);
40
41 x -= ams_info.xcalib;
42 y -= ams_info.ycalib;
43 z -= ams_info.zcalib;
44
45 input_report_abs(idev, ABS_X, invert ? -x : x);
46 input_report_abs(idev, ABS_Y, invert ? -y : y);
47 input_report_abs(idev, ABS_Z, z);
48
49 input_sync(idev);
50
51 mutex_unlock(&ams_info.lock);
52}
53
54/* Call with ams_info.lock held! */
55static int ams_input_enable(void)
56{
57 struct input_dev *input;
58 s8 x, y, z;
59 int error;
60
61 ams_sensors(&x, &y, &z);
62 ams_info.xcalib = x;
63 ams_info.ycalib = y;
64 ams_info.zcalib = z;
65
66 ams_info.idev = input_allocate_polled_device();
67 if (!ams_info.idev)
68 return -ENOMEM;
69
70 ams_info.idev->poll = ams_idev_poll;
71 ams_info.idev->poll_interval = 25;
72
73 input = ams_info.idev->input;
74 input->name = "Apple Motion Sensor";
75 input->id.bustype = ams_info.bustype;
76 input->id.vendor = 0;
77 input->dev.parent = &ams_info.of_dev->dev;
78
79 input_set_abs_params(input, ABS_X, -50, 50, 3, 0);
80 input_set_abs_params(input, ABS_Y, -50, 50, 3, 0);
81 input_set_abs_params(input, ABS_Z, -50, 50, 3, 0);
82
83 set_bit(EV_ABS, input->evbit);
84 set_bit(EV_KEY, input->evbit);
85 set_bit(BTN_TOUCH, input->keybit);
86
87 error = input_register_polled_device(ams_info.idev);
88 if (error) {
89 input_free_polled_device(ams_info.idev);
90 ams_info.idev = NULL;
91 return error;
92 }
93
94 joystick = 1;
95
96 return 0;
97}
98
99static void ams_input_disable(void)
100{
101 if (ams_info.idev) {
102 input_unregister_polled_device(ams_info.idev);
103 input_free_polled_device(ams_info.idev);
104 ams_info.idev = NULL;
105 }
106
107 joystick = 0;
108}
109
110static ssize_t ams_input_show_joystick(struct device *dev,
111 struct device_attribute *attr, char *buf)
112{
113 return sprintf(buf, "%d\n", joystick);
114}
115
116static ssize_t ams_input_store_joystick(struct device *dev,
117 struct device_attribute *attr, const char *buf, size_t count)
118{
119 unsigned long enable;
120 int error = 0;
121
122 if (strict_strtoul(buf, 0, &enable) || enable > 1)
123 return -EINVAL;
124
125 mutex_lock(&ams_input_mutex);
126
127 if (enable != joystick) {
128 if (enable)
129 error = ams_input_enable();
130 else
131 ams_input_disable();
132 }
133
134 mutex_unlock(&ams_input_mutex);
135
136 return error ? error : count;
137}
138
139static DEVICE_ATTR(joystick, S_IRUGO | S_IWUSR,
140 ams_input_show_joystick, ams_input_store_joystick);
141
142int ams_input_init(void)
143{
144 if (joystick)
145 ams_input_enable();
146
147 return device_create_file(&ams_info.of_dev->dev, &dev_attr_joystick);
148}
149
150void ams_input_exit(void)
151{
152 device_remove_file(&ams_info.of_dev->dev, &dev_attr_joystick);
153
154 mutex_lock(&ams_input_mutex);
155 ams_input_disable();
156 mutex_unlock(&ams_input_mutex);
157}
diff --git a/drivers/macintosh/ams/ams-pmu.c b/drivers/macintosh/ams/ams-pmu.c
new file mode 100644
index 000000000000..4f61b3ee1b08
--- /dev/null
+++ b/drivers/macintosh/ams/ams-pmu.c
@@ -0,0 +1,201 @@
1/*
2 * Apple Motion Sensor driver (PMU variant)
3 *
4 * Copyright (C) 2006 Michael Hanselmann (linux-kernel@hansmi.ch)
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
12#include <linux/module.h>
13#include <linux/types.h>
14#include <linux/errno.h>
15#include <linux/init.h>
16#include <linux/adb.h>
17#include <linux/pmu.h>
18
19#include "ams.h"
20
21/* Attitude */
22#define AMS_X 0x00
23#define AMS_Y 0x01
24#define AMS_Z 0x02
25
26/* Not exactly known, maybe chip vendor */
27#define AMS_VENDOR 0x03
28
29/* Freefall registers */
30#define AMS_FF_CLEAR 0x04
31#define AMS_FF_ENABLE 0x05
32#define AMS_FF_LOW_LIMIT 0x06
33#define AMS_FF_DEBOUNCE 0x07
34
35/* Shock registers */
36#define AMS_SHOCK_CLEAR 0x08
37#define AMS_SHOCK_ENABLE 0x09
38#define AMS_SHOCK_HIGH_LIMIT 0x0a
39#define AMS_SHOCK_DEBOUNCE 0x0b
40
41/* Global interrupt and power control register */
42#define AMS_CONTROL 0x0c
43
44static u8 ams_pmu_cmd;
45
46static void ams_pmu_req_complete(struct adb_request *req)
47{
48 complete((struct completion *)req->arg);
49}
50
51/* Only call this function from task context */
52static void ams_pmu_set_register(u8 reg, u8 value)
53{
54 static struct adb_request req;
55 DECLARE_COMPLETION(req_complete);
56
57 req.arg = &req_complete;
58 if (pmu_request(&req, ams_pmu_req_complete, 4, ams_pmu_cmd, 0x00, reg, value))
59 return;
60
61 wait_for_completion(&req_complete);
62}
63
64/* Only call this function from task context */
65static u8 ams_pmu_get_register(u8 reg)
66{
67 static struct adb_request req;
68 DECLARE_COMPLETION(req_complete);
69
70 req.arg = &req_complete;
71 if (pmu_request(&req, ams_pmu_req_complete, 3, ams_pmu_cmd, 0x01, reg))
72 return 0;
73
74 wait_for_completion(&req_complete);
75
76 if (req.reply_len > 0)
77 return req.reply[0];
78 else
79 return 0;
80}
81
82/* Enables or disables the specified interrupts */
83static void ams_pmu_set_irq(enum ams_irq reg, char enable)
84{
85 if (reg & AMS_IRQ_FREEFALL) {
86 u8 val = ams_pmu_get_register(AMS_FF_ENABLE);
87 if (enable)
88 val |= 0x80;
89 else
90 val &= ~0x80;
91 ams_pmu_set_register(AMS_FF_ENABLE, val);
92 }
93
94 if (reg & AMS_IRQ_SHOCK) {
95 u8 val = ams_pmu_get_register(AMS_SHOCK_ENABLE);
96 if (enable)
97 val |= 0x80;
98 else
99 val &= ~0x80;
100 ams_pmu_set_register(AMS_SHOCK_ENABLE, val);
101 }
102
103 if (reg & AMS_IRQ_GLOBAL) {
104 u8 val = ams_pmu_get_register(AMS_CONTROL);
105 if (enable)
106 val |= 0x80;
107 else
108 val &= ~0x80;
109 ams_pmu_set_register(AMS_CONTROL, val);
110 }
111}
112
113static void ams_pmu_clear_irq(enum ams_irq reg)
114{
115 if (reg & AMS_IRQ_FREEFALL)
116 ams_pmu_set_register(AMS_FF_CLEAR, 0x00);
117
118 if (reg & AMS_IRQ_SHOCK)
119 ams_pmu_set_register(AMS_SHOCK_CLEAR, 0x00);
120}
121
122static u8 ams_pmu_get_vendor(void)
123{
124 return ams_pmu_get_register(AMS_VENDOR);
125}
126
127static void ams_pmu_get_xyz(s8 *x, s8 *y, s8 *z)
128{
129 *x = ams_pmu_get_register(AMS_X);
130 *y = ams_pmu_get_register(AMS_Y);
131 *z = ams_pmu_get_register(AMS_Z);
132}
133
134static void ams_pmu_exit(void)
135{
136 ams_sensor_detach();
137
138 /* Disable interrupts */
139 ams_pmu_set_irq(AMS_IRQ_ALL, 0);
140
141 /* Clear interrupts */
142 ams_pmu_clear_irq(AMS_IRQ_ALL);
143
144 ams_info.has_device = 0;
145
146 printk(KERN_INFO "ams: Unloading\n");
147}
148
149int __init ams_pmu_init(struct device_node *np)
150{
151 const u32 *prop;
152 int result;
153
154 /* Set implementation stuff */
155 ams_info.of_node = np;
156 ams_info.exit = ams_pmu_exit;
157 ams_info.get_vendor = ams_pmu_get_vendor;
158 ams_info.get_xyz = ams_pmu_get_xyz;
159 ams_info.clear_irq = ams_pmu_clear_irq;
160 ams_info.bustype = BUS_HOST;
161
162 /* Get PMU command, should be 0x4e, but we can never know */
163 prop = of_get_property(ams_info.of_node, "reg", NULL);
164 if (!prop)
165 return -ENODEV;
166
167 ams_pmu_cmd = ((*prop) >> 8) & 0xff;
168
169 /* Disable interrupts */
170 ams_pmu_set_irq(AMS_IRQ_ALL, 0);
171
172 /* Clear interrupts */
173 ams_pmu_clear_irq(AMS_IRQ_ALL);
174
175 result = ams_sensor_attach();
176 if (result < 0)
177 return result;
178
179 /* Set default values */
180 ams_pmu_set_register(AMS_FF_LOW_LIMIT, 0x15);
181 ams_pmu_set_register(AMS_FF_ENABLE, 0x08);
182 ams_pmu_set_register(AMS_FF_DEBOUNCE, 0x14);
183
184 ams_pmu_set_register(AMS_SHOCK_HIGH_LIMIT, 0x60);
185 ams_pmu_set_register(AMS_SHOCK_ENABLE, 0x0f);
186 ams_pmu_set_register(AMS_SHOCK_DEBOUNCE, 0x14);
187
188 ams_pmu_set_register(AMS_CONTROL, 0x4f);
189
190 /* Clear interrupts */
191 ams_pmu_clear_irq(AMS_IRQ_ALL);
192
193 ams_info.has_device = 1;
194
195 /* Enable interrupts */
196 ams_pmu_set_irq(AMS_IRQ_ALL, 1);
197
198 printk(KERN_INFO "ams: Found PMU based motion sensor\n");
199
200 return 0;
201}
diff --git a/drivers/macintosh/ams/ams.h b/drivers/macintosh/ams/ams.h
new file mode 100644
index 000000000000..90f094d45450
--- /dev/null
+++ b/drivers/macintosh/ams/ams.h
@@ -0,0 +1,70 @@
1#include <linux/i2c.h>
2#include <linux/input-polldev.h>
3#include <linux/kthread.h>
4#include <linux/mutex.h>
5#include <linux/spinlock.h>
6#include <linux/types.h>
7#include <linux/of_device.h>
8
9enum ams_irq {
10 AMS_IRQ_FREEFALL = 0x01,
11 AMS_IRQ_SHOCK = 0x02,
12 AMS_IRQ_GLOBAL = 0x04,
13 AMS_IRQ_ALL =
14 AMS_IRQ_FREEFALL |
15 AMS_IRQ_SHOCK |
16 AMS_IRQ_GLOBAL,
17};
18
19struct ams {
20 /* Locks */
21 spinlock_t irq_lock;
22 struct mutex lock;
23
24 /* General properties */
25 struct device_node *of_node;
26 struct platform_device *of_dev;
27 char has_device;
28 char vflag;
29 u32 orient1;
30 u32 orient2;
31
32 /* Interrupt worker */
33 struct work_struct worker;
34 u8 worker_irqs;
35
36 /* Implementation
37 *
38 * Only call these functions with the main lock held.
39 */
40 void (*exit)(void);
41
42 void (*get_xyz)(s8 *x, s8 *y, s8 *z);
43 u8 (*get_vendor)(void);
44
45 void (*clear_irq)(enum ams_irq reg);
46
47#ifdef CONFIG_SENSORS_AMS_I2C
48 /* I2C properties */
49 struct i2c_client *i2c_client;
50#endif
51
52 /* Joystick emulation */
53 struct input_polled_dev *idev;
54 __u16 bustype;
55
56 /* calibrated null values */
57 int xcalib, ycalib, zcalib;
58};
59
60extern struct ams ams_info;
61
62extern void ams_sensors(s8 *x, s8 *y, s8 *z);
63extern int ams_sensor_attach(void);
64extern void ams_sensor_detach(void);
65
66extern int ams_pmu_init(struct device_node *np);
67extern int ams_i2c_init(struct device_node *np);
68
69extern int ams_input_init(void);
70extern void ams_input_exit(void);
diff --git a/drivers/macintosh/ans-lcd.c b/drivers/macintosh/ans-lcd.c
index a3d25da2f275..1a57e88a38f7 100644
--- a/drivers/macintosh/ans-lcd.c
+++ b/drivers/macintosh/ans-lcd.c
@@ -137,6 +137,7 @@ const struct file_operations anslcd_fops = {
137 .write = anslcd_write, 137 .write = anslcd_write,
138 .unlocked_ioctl = anslcd_ioctl, 138 .unlocked_ioctl = anslcd_ioctl,
139 .open = anslcd_open, 139 .open = anslcd_open,
140 .llseek = default_llseek,
140}; 141};
141 142
142static struct miscdevice anslcd_dev = { 143static struct miscdevice anslcd_dev = {
diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c
index 067f9962f499..6a82388505f0 100644
--- a/drivers/macintosh/mac_hid.c
+++ b/drivers/macintosh/mac_hid.c
@@ -23,6 +23,8 @@ static int mouse_button3_keycode = KEY_RIGHTALT; /* right option key */
23 23
24static struct input_dev *mac_hid_emumouse_dev; 24static struct input_dev *mac_hid_emumouse_dev;
25 25
26static DEFINE_MUTEX(mac_hid_emumouse_mutex);
27
26static int mac_hid_create_emumouse(void) 28static int mac_hid_create_emumouse(void)
27{ 29{
28 static struct lock_class_key mac_hid_emumouse_dev_event_class; 30 static struct lock_class_key mac_hid_emumouse_dev_event_class;
@@ -187,6 +189,10 @@ static int mac_hid_toggle_emumouse(ctl_table *table, int write,
187 int old_val = *valp; 189 int old_val = *valp;
188 int rc; 190 int rc;
189 191
192 rc = mutex_lock_killable(&mac_hid_emumouse_mutex);
193 if (rc)
194 return rc;
195
190 rc = proc_dointvec(table, write, buffer, lenp, ppos); 196 rc = proc_dointvec(table, write, buffer, lenp, ppos);
191 197
192 if (rc == 0 && write && *valp != old_val) { 198 if (rc == 0 && write && *valp != old_val) {
@@ -202,6 +208,8 @@ static int mac_hid_toggle_emumouse(ctl_table *table, int write,
202 if (rc) 208 if (rc)
203 *valp = old_val; 209 *valp = old_val;
204 210
211 mutex_unlock(&mac_hid_emumouse_mutex);
212
205 return rc; 213 return rc;
206} 214}
207 215
diff --git a/drivers/macintosh/macio-adb.c b/drivers/macintosh/macio-adb.c
index bd6da7a9c55b..b6ef8f590764 100644
--- a/drivers/macintosh/macio-adb.c
+++ b/drivers/macintosh/macio-adb.c
@@ -147,7 +147,7 @@ static int macio_adb_reset_bus(void)
147 147
148 /* Hrm... we may want to not lock interrupts for so 148 /* Hrm... we may want to not lock interrupts for so
149 * long ... oh well, who uses that chip anyway ? :) 149 * long ... oh well, who uses that chip anyway ? :)
150 * That function will be seldomly used during boot 150 * That function will be seldom used during boot
151 * on rare machines, so... 151 * on rare machines, so...
152 */ 152 */
153 spin_lock_irqsave(&macio_lock, flags); 153 spin_lock_irqsave(&macio_lock, flags);
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
index b6e7ddc09d76..4daf9e5a7736 100644
--- a/drivers/macintosh/macio_asic.c
+++ b/drivers/macintosh/macio_asic.c
@@ -387,11 +387,10 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip,
387 /* Set the DMA ops to the ones from the PCI device, this could be 387 /* Set the DMA ops to the ones from the PCI device, this could be
388 * fishy if we didn't know that on PowerMac it's always direct ops 388 * fishy if we didn't know that on PowerMac it's always direct ops
389 * or iommu ops that will work fine 389 * or iommu ops that will work fine
390 *
391 * To get all the fields, copy all archdata
390 */ 392 */
391 dev->ofdev.dev.archdata.dma_ops = 393 dev->ofdev.dev.archdata = chip->lbus.pdev->dev.archdata;
392 chip->lbus.pdev->dev.archdata.dma_ops;
393 dev->ofdev.dev.archdata.dma_data =
394 chip->lbus.pdev->dev.archdata.dma_data;
395#endif /* CONFIG_PCI */ 394#endif /* CONFIG_PCI */
396 395
397#ifdef DEBUG 396#ifdef DEBUG
diff --git a/drivers/macintosh/rack-meter.c b/drivers/macintosh/rack-meter.c
index 53cce3a5da23..2637c139777b 100644
--- a/drivers/macintosh/rack-meter.c
+++ b/drivers/macintosh/rack-meter.c
@@ -283,10 +283,10 @@ static void __devinit rackmeter_init_cpu_sniffer(struct rackmeter *rm)
283 } 283 }
284} 284}
285 285
286static void __devexit rackmeter_stop_cpu_sniffer(struct rackmeter *rm) 286static void rackmeter_stop_cpu_sniffer(struct rackmeter *rm)
287{ 287{
288 cancel_rearming_delayed_work(&rm->cpu[0].sniffer); 288 cancel_delayed_work_sync(&rm->cpu[0].sniffer);
289 cancel_rearming_delayed_work(&rm->cpu[1].sniffer); 289 cancel_delayed_work_sync(&rm->cpu[1].sniffer);
290} 290}
291 291
292static int __devinit rackmeter_setup(struct rackmeter *rm) 292static int __devinit rackmeter_setup(struct rackmeter *rm)
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c
index e58c3d33e035..116a49ce74b2 100644
--- a/drivers/macintosh/smu.c
+++ b/drivers/macintosh/smu.c
@@ -19,7 +19,6 @@
19 * the userland interface 19 * the userland interface
20 */ 20 */
21 21
22#include <linux/smp_lock.h>
23#include <linux/types.h> 22#include <linux/types.h>
24#include <linux/kernel.h> 23#include <linux/kernel.h>
25#include <linux/device.h> 24#include <linux/device.h>
@@ -97,6 +96,7 @@ struct smu_device {
97 * I don't think there will ever be more than one SMU, so 96 * I don't think there will ever be more than one SMU, so
98 * for now, just hard code that 97 * for now, just hard code that
99 */ 98 */
99static DEFINE_MUTEX(smu_mutex);
100static struct smu_device *smu; 100static struct smu_device *smu;
101static DEFINE_MUTEX(smu_part_access); 101static DEFINE_MUTEX(smu_part_access);
102static int smu_irq_inited; 102static int smu_irq_inited;
@@ -645,8 +645,7 @@ static void smu_expose_childs(struct work_struct *unused)
645 645
646static DECLARE_WORK(smu_expose_childs_work, smu_expose_childs); 646static DECLARE_WORK(smu_expose_childs_work, smu_expose_childs);
647 647
648static int smu_platform_probe(struct platform_device* dev, 648static int smu_platform_probe(struct platform_device* dev)
649 const struct of_device_id *match)
650{ 649{
651 if (!smu) 650 if (!smu)
652 return -ENODEV; 651 return -ENODEV;
@@ -669,7 +668,7 @@ static const struct of_device_id smu_platform_match[] =
669 {}, 668 {},
670}; 669};
671 670
672static struct of_platform_driver smu_of_platform_driver = 671static struct platform_driver smu_of_platform_driver =
673{ 672{
674 .driver = { 673 .driver = {
675 .name = "smu", 674 .name = "smu",
@@ -689,7 +688,7 @@ static int __init smu_init_sysfs(void)
689 * I'm a bit too far from figuring out how that works with those 688 * I'm a bit too far from figuring out how that works with those
690 * new chipsets, but that will come back and bite us 689 * new chipsets, but that will come back and bite us
691 */ 690 */
692 of_register_platform_driver(&smu_of_platform_driver); 691 platform_driver_register(&smu_of_platform_driver);
693 return 0; 692 return 0;
694} 693}
695 694
@@ -1095,12 +1094,12 @@ static int smu_open(struct inode *inode, struct file *file)
1095 pp->mode = smu_file_commands; 1094 pp->mode = smu_file_commands;
1096 init_waitqueue_head(&pp->wait); 1095 init_waitqueue_head(&pp->wait);
1097 1096
1098 lock_kernel(); 1097 mutex_lock(&smu_mutex);
1099 spin_lock_irqsave(&smu_clist_lock, flags); 1098 spin_lock_irqsave(&smu_clist_lock, flags);
1100 list_add(&pp->list, &smu_clist); 1099 list_add(&pp->list, &smu_clist);
1101 spin_unlock_irqrestore(&smu_clist_lock, flags); 1100 spin_unlock_irqrestore(&smu_clist_lock, flags);
1102 file->private_data = pp; 1101 file->private_data = pp;
1103 unlock_kernel(); 1102 mutex_unlock(&smu_mutex);
1104 1103
1105 return 0; 1104 return 0;
1106} 1105}
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
index d0d221332db0..02367308ff2e 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -3,9 +3,9 @@
3 * 3 *
4 * Copyright (C) 2003, 2004 Colin Leroy, Rasmus Rohde, Benjamin Herrenschmidt 4 * Copyright (C) 2003, 2004 Colin Leroy, Rasmus Rohde, Benjamin Herrenschmidt
5 * 5 *
6 * Documentation from 6 * Documentation from 115254175ADT7467_pra.pdf and 3686221171167ADT7460_b.pdf
7 * http://www.analog.com/UploadedFiles/Data_Sheets/115254175ADT7467_pra.pdf 7 * http://www.onsemi.com/PowerSolutions/product.do?id=ADT7467
8 * http://www.analog.com/UploadedFiles/Data_Sheets/3686221171167ADT7460_b.pdf 8 * http://www.onsemi.com/PowerSolutions/product.do?id=ADT7460
9 * 9 *
10 */ 10 */
11 11
@@ -662,7 +662,7 @@ static void thermostat_create_files(void)
662 err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_fan_speed); 662 err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_fan_speed);
663 if (err) 663 if (err)
664 printk(KERN_WARNING 664 printk(KERN_WARNING
665 "Failed to create tempertaure attribute file(s).\n"); 665 "Failed to create temperature attribute file(s).\n");
666} 666}
667 667
668static void thermostat_remove_files(void) 668static void thermostat_remove_files(void)
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
index 44549272333c..0ff92c208005 100644
--- a/drivers/macintosh/therm_pm72.c
+++ b/drivers/macintosh/therm_pm72.c
@@ -44,11 +44,11 @@
44 * TODO: - Check MPU structure version/signature 44 * TODO: - Check MPU structure version/signature
45 * - Add things like /sbin/overtemp for non-critical 45 * - Add things like /sbin/overtemp for non-critical
46 * overtemp conditions so userland can take some policy 46 * overtemp conditions so userland can take some policy
47 * decisions, like slewing down CPUs 47 * decisions, like slowing down CPUs
48 * - Deal with fan and i2c failures in a better way 48 * - Deal with fan and i2c failures in a better way
49 * - Maybe do a generic PID based on params used for 49 * - Maybe do a generic PID based on params used for
50 * U3 and Drives ? Definitely need to factor code a bit 50 * U3 and Drives ? Definitely need to factor code a bit
51 * bettter... also make sensor detection more robust using 51 * better... also make sensor detection more robust using
52 * the device-tree to probe for them 52 * the device-tree to probe for them
53 * - Figure out how to get the slots consumption and set the 53 * - Figure out how to get the slots consumption and set the
54 * slots fan accordingly 54 * slots fan accordingly
@@ -91,7 +91,7 @@
91 * 91 *
92 * Mar. 10, 2005 : 1.2 92 * Mar. 10, 2005 : 1.2
93 * - Add basic support for Xserve G5 93 * - Add basic support for Xserve G5
94 * - Retreive pumps min/max from EEPROM image in device-tree (broken) 94 * - Retrieve pumps min/max from EEPROM image in device-tree (broken)
95 * - Use min/max macros here or there 95 * - Use min/max macros here or there
96 * - Latest darwin updated U3H min fan speed to 20% PWM 96 * - Latest darwin updated U3H min fan speed to 20% PWM
97 * 97 *
@@ -153,7 +153,7 @@ static struct i2c_adapter * u3_0;
153static struct i2c_adapter * u3_1; 153static struct i2c_adapter * u3_1;
154static struct i2c_adapter * k2; 154static struct i2c_adapter * k2;
155static struct i2c_client * fcu; 155static struct i2c_client * fcu;
156static struct cpu_pid_state cpu_state[2]; 156static struct cpu_pid_state processor_state[2];
157static struct basckside_pid_params backside_params; 157static struct basckside_pid_params backside_params;
158static struct backside_pid_state backside_state; 158static struct backside_pid_state backside_state;
159static struct drives_pid_state drives_state; 159static struct drives_pid_state drives_state;
@@ -375,7 +375,7 @@ static int read_smon_adc(struct cpu_pid_state *state, int chan)
375 rc = i2c_master_send(state->monitor, buf, 2); 375 rc = i2c_master_send(state->monitor, buf, 2);
376 if (rc <= 0) 376 if (rc <= 0)
377 goto error; 377 goto error;
378 /* Wait for convertion */ 378 /* Wait for conversion */
379 msleep(1); 379 msleep(1);
380 /* Switch to data register */ 380 /* Switch to data register */
381 buf[0] = 4; 381 buf[0] = 4;
@@ -443,7 +443,7 @@ static int fan_read_reg(int reg, unsigned char *buf, int nb)
443 tries = 0; 443 tries = 0;
444 for (;;) { 444 for (;;) {
445 nr = i2c_master_recv(fcu, buf, nb); 445 nr = i2c_master_recv(fcu, buf, nb);
446 if (nr > 0 || (nr < 0 && nr != ENODEV) || tries >= 100) 446 if (nr > 0 || (nr < 0 && nr != -ENODEV) || tries >= 100)
447 break; 447 break;
448 msleep(10); 448 msleep(10);
449 ++tries; 449 ++tries;
@@ -464,7 +464,7 @@ static int fan_write_reg(int reg, const unsigned char *ptr, int nb)
464 tries = 0; 464 tries = 0;
465 for (;;) { 465 for (;;) {
466 nw = i2c_master_send(fcu, buf, nb); 466 nw = i2c_master_send(fcu, buf, nb);
467 if (nw > 0 || (nw < 0 && nw != EIO) || tries >= 100) 467 if (nw > 0 || (nw < 0 && nw != -EIO) || tries >= 100)
468 break; 468 break;
469 msleep(10); 469 msleep(10);
470 ++tries; 470 ++tries;
@@ -664,8 +664,8 @@ static int read_eeprom(int cpu, struct mpu_data *out)
664 664
665static void fetch_cpu_pumps_minmax(void) 665static void fetch_cpu_pumps_minmax(void)
666{ 666{
667 struct cpu_pid_state *state0 = &cpu_state[0]; 667 struct cpu_pid_state *state0 = &processor_state[0];
668 struct cpu_pid_state *state1 = &cpu_state[1]; 668 struct cpu_pid_state *state1 = &processor_state[1];
669 u16 pump_min = 0, pump_max = 0xffff; 669 u16 pump_min = 0, pump_max = 0xffff;
670 u16 tmp[4]; 670 u16 tmp[4];
671 671
@@ -717,17 +717,17 @@ static ssize_t show_##name(struct device *dev, struct device_attribute *attr, ch
717 return sprintf(buf, "%d", data); \ 717 return sprintf(buf, "%d", data); \
718} 718}
719 719
720BUILD_SHOW_FUNC_FIX(cpu0_temperature, cpu_state[0].last_temp) 720BUILD_SHOW_FUNC_FIX(cpu0_temperature, processor_state[0].last_temp)
721BUILD_SHOW_FUNC_FIX(cpu0_voltage, cpu_state[0].voltage) 721BUILD_SHOW_FUNC_FIX(cpu0_voltage, processor_state[0].voltage)
722BUILD_SHOW_FUNC_FIX(cpu0_current, cpu_state[0].current_a) 722BUILD_SHOW_FUNC_FIX(cpu0_current, processor_state[0].current_a)
723BUILD_SHOW_FUNC_INT(cpu0_exhaust_fan_rpm, cpu_state[0].rpm) 723BUILD_SHOW_FUNC_INT(cpu0_exhaust_fan_rpm, processor_state[0].rpm)
724BUILD_SHOW_FUNC_INT(cpu0_intake_fan_rpm, cpu_state[0].intake_rpm) 724BUILD_SHOW_FUNC_INT(cpu0_intake_fan_rpm, processor_state[0].intake_rpm)
725 725
726BUILD_SHOW_FUNC_FIX(cpu1_temperature, cpu_state[1].last_temp) 726BUILD_SHOW_FUNC_FIX(cpu1_temperature, processor_state[1].last_temp)
727BUILD_SHOW_FUNC_FIX(cpu1_voltage, cpu_state[1].voltage) 727BUILD_SHOW_FUNC_FIX(cpu1_voltage, processor_state[1].voltage)
728BUILD_SHOW_FUNC_FIX(cpu1_current, cpu_state[1].current_a) 728BUILD_SHOW_FUNC_FIX(cpu1_current, processor_state[1].current_a)
729BUILD_SHOW_FUNC_INT(cpu1_exhaust_fan_rpm, cpu_state[1].rpm) 729BUILD_SHOW_FUNC_INT(cpu1_exhaust_fan_rpm, processor_state[1].rpm)
730BUILD_SHOW_FUNC_INT(cpu1_intake_fan_rpm, cpu_state[1].intake_rpm) 730BUILD_SHOW_FUNC_INT(cpu1_intake_fan_rpm, processor_state[1].intake_rpm)
731 731
732BUILD_SHOW_FUNC_FIX(backside_temperature, backside_state.last_temp) 732BUILD_SHOW_FUNC_FIX(backside_temperature, backside_state.last_temp)
733BUILD_SHOW_FUNC_INT(backside_fan_pwm, backside_state.pwm) 733BUILD_SHOW_FUNC_INT(backside_fan_pwm, backside_state.pwm)
@@ -919,8 +919,8 @@ static void do_cpu_pid(struct cpu_pid_state *state, s32 temp, s32 power)
919 919
920static void do_monitor_cpu_combined(void) 920static void do_monitor_cpu_combined(void)
921{ 921{
922 struct cpu_pid_state *state0 = &cpu_state[0]; 922 struct cpu_pid_state *state0 = &processor_state[0];
923 struct cpu_pid_state *state1 = &cpu_state[1]; 923 struct cpu_pid_state *state1 = &processor_state[1];
924 s32 temp0, power0, temp1, power1; 924 s32 temp0, power0, temp1, power1;
925 s32 temp_combi, power_combi; 925 s32 temp_combi, power_combi;
926 int rc, intake, pump; 926 int rc, intake, pump;
@@ -1150,7 +1150,7 @@ static void do_monitor_cpu_rack(struct cpu_pid_state *state)
1150/* 1150/*
1151 * Initialize the state structure for one CPU control loop 1151 * Initialize the state structure for one CPU control loop
1152 */ 1152 */
1153static int init_cpu_state(struct cpu_pid_state *state, int index) 1153static int init_processor_state(struct cpu_pid_state *state, int index)
1154{ 1154{
1155 int err; 1155 int err;
1156 1156
@@ -1192,7 +1192,7 @@ static int init_cpu_state(struct cpu_pid_state *state, int index)
1192 err |= device_create_file(&of_dev->dev, &dev_attr_cpu1_intake_fan_rpm); 1192 err |= device_create_file(&of_dev->dev, &dev_attr_cpu1_intake_fan_rpm);
1193 } 1193 }
1194 if (err) 1194 if (err)
1195 printk(KERN_WARNING "Failed to create some of the atribute" 1195 printk(KERN_WARNING "Failed to create some of the attribute"
1196 "files for CPU %d\n", index); 1196 "files for CPU %d\n", index);
1197 1197
1198 return 0; 1198 return 0;
@@ -1205,7 +1205,7 @@ static int init_cpu_state(struct cpu_pid_state *state, int index)
1205/* 1205/*
1206 * Dispose of the state data for one CPU control loop 1206 * Dispose of the state data for one CPU control loop
1207 */ 1207 */
1208static void dispose_cpu_state(struct cpu_pid_state *state) 1208static void dispose_processor_state(struct cpu_pid_state *state)
1209{ 1209{
1210 if (state->monitor == NULL) 1210 if (state->monitor == NULL)
1211 return; 1211 return;
@@ -1804,9 +1804,9 @@ static int main_control_loop(void *x)
1804 set_pwm_fan(SLOTS_FAN_PWM_INDEX, SLOTS_FAN_DEFAULT_PWM); 1804 set_pwm_fan(SLOTS_FAN_PWM_INDEX, SLOTS_FAN_DEFAULT_PWM);
1805 1805
1806 /* Initialize ADCs */ 1806 /* Initialize ADCs */
1807 initialize_adc(&cpu_state[0]); 1807 initialize_adc(&processor_state[0]);
1808 if (cpu_state[1].monitor != NULL) 1808 if (processor_state[1].monitor != NULL)
1809 initialize_adc(&cpu_state[1]); 1809 initialize_adc(&processor_state[1]);
1810 1810
1811 fcu_tickle_ticks = FCU_TICKLE_TICKS; 1811 fcu_tickle_ticks = FCU_TICKLE_TICKS;
1812 1812
@@ -1833,14 +1833,14 @@ static int main_control_loop(void *x)
1833 if (cpu_pid_type == CPU_PID_TYPE_COMBINED) 1833 if (cpu_pid_type == CPU_PID_TYPE_COMBINED)
1834 do_monitor_cpu_combined(); 1834 do_monitor_cpu_combined();
1835 else if (cpu_pid_type == CPU_PID_TYPE_RACKMAC) { 1835 else if (cpu_pid_type == CPU_PID_TYPE_RACKMAC) {
1836 do_monitor_cpu_rack(&cpu_state[0]); 1836 do_monitor_cpu_rack(&processor_state[0]);
1837 if (cpu_state[1].monitor != NULL) 1837 if (processor_state[1].monitor != NULL)
1838 do_monitor_cpu_rack(&cpu_state[1]); 1838 do_monitor_cpu_rack(&processor_state[1]);
1839 // better deal with UP 1839 // better deal with UP
1840 } else { 1840 } else {
1841 do_monitor_cpu_split(&cpu_state[0]); 1841 do_monitor_cpu_split(&processor_state[0]);
1842 if (cpu_state[1].monitor != NULL) 1842 if (processor_state[1].monitor != NULL)
1843 do_monitor_cpu_split(&cpu_state[1]); 1843 do_monitor_cpu_split(&processor_state[1]);
1844 // better deal with UP 1844 // better deal with UP
1845 } 1845 }
1846 /* Then, the rest */ 1846 /* Then, the rest */
@@ -1885,8 +1885,8 @@ static int main_control_loop(void *x)
1885 */ 1885 */
1886static void dispose_control_loops(void) 1886static void dispose_control_loops(void)
1887{ 1887{
1888 dispose_cpu_state(&cpu_state[0]); 1888 dispose_processor_state(&processor_state[0]);
1889 dispose_cpu_state(&cpu_state[1]); 1889 dispose_processor_state(&processor_state[1]);
1890 dispose_backside_state(&backside_state); 1890 dispose_backside_state(&backside_state);
1891 dispose_drives_state(&drives_state); 1891 dispose_drives_state(&drives_state);
1892 dispose_slots_state(&slots_state); 1892 dispose_slots_state(&slots_state);
@@ -1928,12 +1928,12 @@ static int create_control_loops(void)
1928 /* Create control loops for everything. If any fail, everything 1928 /* Create control loops for everything. If any fail, everything
1929 * fails 1929 * fails
1930 */ 1930 */
1931 if (init_cpu_state(&cpu_state[0], 0)) 1931 if (init_processor_state(&processor_state[0], 0))
1932 goto fail; 1932 goto fail;
1933 if (cpu_pid_type == CPU_PID_TYPE_COMBINED) 1933 if (cpu_pid_type == CPU_PID_TYPE_COMBINED)
1934 fetch_cpu_pumps_minmax(); 1934 fetch_cpu_pumps_minmax();
1935 1935
1936 if (cpu_count > 1 && init_cpu_state(&cpu_state[1], 1)) 1936 if (cpu_count > 1 && init_processor_state(&processor_state[1], 1))
1937 goto fail; 1937 goto fail;
1938 if (init_backside_state(&backside_state)) 1938 if (init_backside_state(&backside_state))
1939 goto fail; 1939 goto fail;
@@ -2210,9 +2210,12 @@ static void fcu_lookup_fans(struct device_node *fcu_node)
2210 } 2210 }
2211} 2211}
2212 2212
2213static int fcu_of_probe(struct platform_device* dev, const struct of_device_id *match) 2213static int fcu_of_probe(struct platform_device* dev)
2214{ 2214{
2215 state = state_detached; 2215 state = state_detached;
2216 of_dev = dev;
2217
2218 dev_info(&dev->dev, "PowerMac G5 Thermal control driver %s\n", VERSION);
2216 2219
2217 /* Lookup the fans in the device tree */ 2220 /* Lookup the fans in the device tree */
2218 fcu_lookup_fans(dev->dev.of_node); 2221 fcu_lookup_fans(dev->dev.of_node);
@@ -2235,8 +2238,9 @@ static const struct of_device_id fcu_match[] =
2235 }, 2238 },
2236 {}, 2239 {},
2237}; 2240};
2241MODULE_DEVICE_TABLE(of, fcu_match);
2238 2242
2239static struct of_platform_driver fcu_of_platform_driver = 2243static struct platform_driver fcu_of_platform_driver =
2240{ 2244{
2241 .driver = { 2245 .driver = {
2242 .name = "temperature", 2246 .name = "temperature",
@@ -2252,8 +2256,6 @@ static struct of_platform_driver fcu_of_platform_driver =
2252 */ 2256 */
2253static int __init therm_pm72_init(void) 2257static int __init therm_pm72_init(void)
2254{ 2258{
2255 struct device_node *np;
2256
2257 rackmac = of_machine_is_compatible("RackMac3,1"); 2259 rackmac = of_machine_is_compatible("RackMac3,1");
2258 2260
2259 if (!of_machine_is_compatible("PowerMac7,2") && 2261 if (!of_machine_is_compatible("PowerMac7,2") &&
@@ -2261,34 +2263,12 @@ static int __init therm_pm72_init(void)
2261 !rackmac) 2263 !rackmac)
2262 return -ENODEV; 2264 return -ENODEV;
2263 2265
2264 printk(KERN_INFO "PowerMac G5 Thermal control driver %s\n", VERSION); 2266 return platform_driver_register(&fcu_of_platform_driver);
2265
2266 np = of_find_node_by_type(NULL, "fcu");
2267 if (np == NULL) {
2268 /* Some machines have strangely broken device-tree */
2269 np = of_find_node_by_path("/u3@0,f8000000/i2c@f8001000/fan@15e");
2270 if (np == NULL) {
2271 printk(KERN_ERR "Can't find FCU in device-tree !\n");
2272 return -ENODEV;
2273 }
2274 }
2275 of_dev = of_platform_device_create(np, "temperature", NULL);
2276 if (of_dev == NULL) {
2277 printk(KERN_ERR "Can't register FCU platform device !\n");
2278 return -ENODEV;
2279 }
2280
2281 of_register_platform_driver(&fcu_of_platform_driver);
2282
2283 return 0;
2284} 2267}
2285 2268
2286static void __exit therm_pm72_exit(void) 2269static void __exit therm_pm72_exit(void)
2287{ 2270{
2288 of_unregister_platform_driver(&fcu_of_platform_driver); 2271 platform_driver_unregister(&fcu_of_platform_driver);
2289
2290 if (of_dev)
2291 of_device_unregister(of_dev);
2292} 2272}
2293 2273
2294module_init(therm_pm72_init); 2274module_init(therm_pm72_init);
diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c
index c89f396e4c53..46c4e95f10d6 100644
--- a/drivers/macintosh/therm_windtunnel.c
+++ b/drivers/macintosh/therm_windtunnel.c
@@ -45,7 +45,7 @@
45#include <asm/sections.h> 45#include <asm/sections.h>
46#include <asm/macio.h> 46#include <asm/macio.h>
47 47
48#define LOG_TEMP 0 /* continously log temperature */ 48#define LOG_TEMP 0 /* continuously log temperature */
49 49
50static struct { 50static struct {
51 volatile int running; 51 volatile int running;
@@ -443,8 +443,7 @@ static struct i2c_driver g4fan_driver = {
443/* initialization / cleanup */ 443/* initialization / cleanup */
444/************************************************************************/ 444/************************************************************************/
445 445
446static int 446static int therm_of_probe(struct platform_device *dev)
447therm_of_probe( struct platform_device *dev, const struct of_device_id *match )
448{ 447{
449 return i2c_add_driver( &g4fan_driver ); 448 return i2c_add_driver( &g4fan_driver );
450} 449}
@@ -462,7 +461,7 @@ static const struct of_device_id therm_of_match[] = {{
462 }, {} 461 }, {}
463}; 462};
464 463
465static struct of_platform_driver therm_of_driver = { 464static struct platform_driver therm_of_driver = {
466 .driver = { 465 .driver = {
467 .name = "temperature", 466 .name = "temperature",
468 .owner = THIS_MODULE, 467 .owner = THIS_MODULE,
@@ -509,14 +508,14 @@ g4fan_init( void )
509 return -ENODEV; 508 return -ENODEV;
510 } 509 }
511 510
512 of_register_platform_driver( &therm_of_driver ); 511 platform_driver_register( &therm_of_driver );
513 return 0; 512 return 0;
514} 513}
515 514
516static void __exit 515static void __exit
517g4fan_exit( void ) 516g4fan_exit( void )
518{ 517{
519 of_unregister_platform_driver( &therm_of_driver ); 518 platform_driver_unregister( &therm_of_driver );
520 519
521 if( x.of_dev ) 520 if( x.of_dev )
522 of_device_unregister( x.of_dev ); 521 of_device_unregister( x.of_dev );
diff --git a/drivers/macintosh/via-pmu-backlight.c b/drivers/macintosh/via-pmu-backlight.c
index 1cec02f6c431..b1d91170ded0 100644
--- a/drivers/macintosh/via-pmu-backlight.c
+++ b/drivers/macintosh/via-pmu-backlight.c
@@ -15,7 +15,7 @@
15 15
16#define MAX_PMU_LEVEL 0xFF 16#define MAX_PMU_LEVEL 0xFF
17 17
18static struct backlight_ops pmu_backlight_data; 18static const struct backlight_ops pmu_backlight_data;
19static DEFINE_SPINLOCK(pmu_backlight_lock); 19static DEFINE_SPINLOCK(pmu_backlight_lock);
20static int sleeping, uses_pmu_bl; 20static int sleeping, uses_pmu_bl;
21static u8 bl_curve[FB_BACKLIGHT_LEVELS]; 21static u8 bl_curve[FB_BACKLIGHT_LEVELS];
@@ -115,7 +115,7 @@ static int pmu_backlight_get_brightness(struct backlight_device *bd)
115 return bd->props.brightness; 115 return bd->props.brightness;
116} 116}
117 117
118static struct backlight_ops pmu_backlight_data = { 118static const struct backlight_ops pmu_backlight_data = {
119 .get_brightness = pmu_backlight_get_brightness, 119 .get_brightness = pmu_backlight_get_brightness,
120 .update_status = pmu_backlight_update_status, 120 .update_status = pmu_backlight_update_status,
121 121
@@ -163,6 +163,7 @@ void __init pmu_backlight_init()
163 snprintf(name, sizeof(name), "pmubl"); 163 snprintf(name, sizeof(name), "pmubl");
164 164
165 memset(&props, 0, sizeof(struct backlight_properties)); 165 memset(&props, 0, sizeof(struct backlight_properties));
166 props.type = BACKLIGHT_PLATFORM;
166 props.max_brightness = FB_BACKLIGHT_LEVELS - 1; 167 props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
167 bd = backlight_device_register(name, NULL, NULL, &pmu_backlight_data, 168 bd = backlight_device_register(name, NULL, NULL, &pmu_backlight_data,
168 &props); 169 &props);
diff --git a/drivers/macintosh/via-pmu-led.c b/drivers/macintosh/via-pmu-led.c
index d242976bcfe7..19c371809d77 100644
--- a/drivers/macintosh/via-pmu-led.c
+++ b/drivers/macintosh/via-pmu-led.c
@@ -92,8 +92,10 @@ static int __init via_pmu_led_init(void)
92 if (dt == NULL) 92 if (dt == NULL)
93 return -ENODEV; 93 return -ENODEV;
94 model = of_get_property(dt, "model", NULL); 94 model = of_get_property(dt, "model", NULL);
95 if (model == NULL) 95 if (model == NULL) {
96 of_node_put(dt);
96 return -ENODEV; 97 return -ENODEV;
98 }
97 if (strncmp(model, "PowerBook", strlen("PowerBook")) != 0 && 99 if (strncmp(model, "PowerBook", strlen("PowerBook")) != 0 &&
98 strncmp(model, "iBook", strlen("iBook")) != 0 && 100 strncmp(model, "iBook", strlen("iBook")) != 0 &&
99 strcmp(model, "PowerMac7,2") != 0 && 101 strcmp(model, "PowerMac7,2") != 0 &&
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index 2d17e76066bd..6cccd60c594e 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -18,7 +18,7 @@
18 * 18 *
19 */ 19 */
20#include <stdarg.h> 20#include <stdarg.h>
21#include <linux/smp_lock.h> 21#include <linux/mutex.h>
22#include <linux/types.h> 22#include <linux/types.h>
23#include <linux/errno.h> 23#include <linux/errno.h>
24#include <linux/kernel.h> 24#include <linux/kernel.h>
@@ -40,7 +40,7 @@
40#include <linux/init.h> 40#include <linux/init.h>
41#include <linux/interrupt.h> 41#include <linux/interrupt.h>
42#include <linux/device.h> 42#include <linux/device.h>
43#include <linux/sysdev.h> 43#include <linux/syscore_ops.h>
44#include <linux/freezer.h> 44#include <linux/freezer.h>
45#include <linux/syscalls.h> 45#include <linux/syscalls.h>
46#include <linux/suspend.h> 46#include <linux/suspend.h>
@@ -73,6 +73,7 @@
73/* How many iterations between battery polls */ 73/* How many iterations between battery polls */
74#define BATTERY_POLLING_COUNT 2 74#define BATTERY_POLLING_COUNT 2
75 75
76static DEFINE_MUTEX(pmu_info_proc_mutex);
76static volatile unsigned char __iomem *via; 77static volatile unsigned char __iomem *via;
77 78
78/* VIA registers - spaced 0x200 bytes apart */ 79/* VIA registers - spaced 0x200 bytes apart */
@@ -2078,7 +2079,7 @@ pmu_open(struct inode *inode, struct file *file)
2078 pp->rb_get = pp->rb_put = 0; 2079 pp->rb_get = pp->rb_put = 0;
2079 spin_lock_init(&pp->lock); 2080 spin_lock_init(&pp->lock);
2080 init_waitqueue_head(&pp->wait); 2081 init_waitqueue_head(&pp->wait);
2081 lock_kernel(); 2082 mutex_lock(&pmu_info_proc_mutex);
2082 spin_lock_irqsave(&all_pvt_lock, flags); 2083 spin_lock_irqsave(&all_pvt_lock, flags);
2083#if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) 2084#if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT)
2084 pp->backlight_locker = 0; 2085 pp->backlight_locker = 0;
@@ -2086,7 +2087,7 @@ pmu_open(struct inode *inode, struct file *file)
2086 list_add(&pp->list, &all_pmu_pvt); 2087 list_add(&pp->list, &all_pmu_pvt);
2087 spin_unlock_irqrestore(&all_pvt_lock, flags); 2088 spin_unlock_irqrestore(&all_pvt_lock, flags);
2088 file->private_data = pp; 2089 file->private_data = pp;
2089 unlock_kernel(); 2090 mutex_unlock(&pmu_info_proc_mutex);
2090 return 0; 2091 return 0;
2091} 2092}
2092 2093
@@ -2256,7 +2257,7 @@ static int pmu_sleep_valid(suspend_state_t state)
2256 && (pmac_call_feature(PMAC_FTR_SLEEP_STATE, NULL, 0, -1) >= 0); 2257 && (pmac_call_feature(PMAC_FTR_SLEEP_STATE, NULL, 0, -1) >= 0);
2257} 2258}
2258 2259
2259static struct platform_suspend_ops pmu_pm_ops = { 2260static const struct platform_suspend_ops pmu_pm_ops = {
2260 .enter = powerbook_sleep, 2261 .enter = powerbook_sleep,
2261 .valid = pmu_sleep_valid, 2262 .valid = pmu_sleep_valid,
2262}; 2263};
@@ -2343,9 +2344,9 @@ static long pmu_unlocked_ioctl(struct file *filp,
2343{ 2344{
2344 int ret; 2345 int ret;
2345 2346
2346 lock_kernel(); 2347 mutex_lock(&pmu_info_proc_mutex);
2347 ret = pmu_ioctl(filp, cmd, arg); 2348 ret = pmu_ioctl(filp, cmd, arg);
2348 unlock_kernel(); 2349 mutex_unlock(&pmu_info_proc_mutex);
2349 2350
2350 return ret; 2351 return ret;
2351} 2352}
@@ -2398,6 +2399,7 @@ static const struct file_operations pmu_device_fops = {
2398#endif 2399#endif
2399 .open = pmu_open, 2400 .open = pmu_open,
2400 .release = pmu_release, 2401 .release = pmu_release,
2402 .llseek = noop_llseek,
2401}; 2403};
2402 2404
2403static struct miscdevice pmu_device = { 2405static struct miscdevice pmu_device = {
@@ -2525,12 +2527,9 @@ void pmu_blink(int n)
2525#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32) 2527#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32)
2526int pmu_sys_suspended; 2528int pmu_sys_suspended;
2527 2529
2528static int pmu_sys_suspend(struct sys_device *sysdev, pm_message_t state) 2530static int pmu_syscore_suspend(void)
2529{ 2531{
2530 if (state.event != PM_EVENT_SUSPEND || pmu_sys_suspended) 2532 /* Suspend PMU event interrupts */
2531 return 0;
2532
2533 /* Suspend PMU event interrupts */\
2534 pmu_suspend(); 2533 pmu_suspend();
2535 pmu_sys_suspended = 1; 2534 pmu_sys_suspended = 1;
2536 2535
@@ -2542,12 +2541,12 @@ static int pmu_sys_suspend(struct sys_device *sysdev, pm_message_t state)
2542 return 0; 2541 return 0;
2543} 2542}
2544 2543
2545static int pmu_sys_resume(struct sys_device *sysdev) 2544static void pmu_syscore_resume(void)
2546{ 2545{
2547 struct adb_request req; 2546 struct adb_request req;
2548 2547
2549 if (!pmu_sys_suspended) 2548 if (!pmu_sys_suspended)
2550 return 0; 2549 return;
2551 2550
2552 /* Tell PMU we are ready */ 2551 /* Tell PMU we are ready */
2553 pmu_request(&req, NULL, 2, PMU_SYSTEM_READY, 2); 2552 pmu_request(&req, NULL, 2, PMU_SYSTEM_READY, 2);
@@ -2560,50 +2559,21 @@ static int pmu_sys_resume(struct sys_device *sysdev)
2560 /* Resume PMU event interrupts */ 2559 /* Resume PMU event interrupts */
2561 pmu_resume(); 2560 pmu_resume();
2562 pmu_sys_suspended = 0; 2561 pmu_sys_suspended = 0;
2563
2564 return 0;
2565} 2562}
2566 2563
2567#endif /* CONFIG_SUSPEND && CONFIG_PPC32 */ 2564static struct syscore_ops pmu_syscore_ops = {
2568 2565 .suspend = pmu_syscore_suspend,
2569static struct sysdev_class pmu_sysclass = { 2566 .resume = pmu_syscore_resume,
2570 .name = "pmu",
2571};
2572
2573static struct sys_device device_pmu = {
2574 .cls = &pmu_sysclass,
2575};
2576
2577static struct sysdev_driver driver_pmu = {
2578#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32)
2579 .suspend = &pmu_sys_suspend,
2580 .resume = &pmu_sys_resume,
2581#endif /* CONFIG_SUSPEND && CONFIG_PPC32 */
2582}; 2567};
2583 2568
2584static int __init init_pmu_sysfs(void) 2569static int pmu_syscore_register(void)
2585{ 2570{
2586 int rc; 2571 register_syscore_ops(&pmu_syscore_ops);
2587 2572
2588 rc = sysdev_class_register(&pmu_sysclass);
2589 if (rc) {
2590 printk(KERN_ERR "Failed registering PMU sys class\n");
2591 return -ENODEV;
2592 }
2593 rc = sysdev_register(&device_pmu);
2594 if (rc) {
2595 printk(KERN_ERR "Failed registering PMU sys device\n");
2596 return -ENODEV;
2597 }
2598 rc = sysdev_driver_register(&pmu_sysclass, &driver_pmu);
2599 if (rc) {
2600 printk(KERN_ERR "Failed registering PMU sys driver\n");
2601 return -ENODEV;
2602 }
2603 return 0; 2573 return 0;
2604} 2574}
2605 2575subsys_initcall(pmu_syscore_register);
2606subsys_initcall(init_pmu_sysfs); 2576#endif /* CONFIG_SUSPEND && CONFIG_PPC32 */
2607 2577
2608EXPORT_SYMBOL(pmu_request); 2578EXPORT_SYMBOL(pmu_request);
2609EXPORT_SYMBOL(pmu_queue_request); 2579EXPORT_SYMBOL(pmu_queue_request);
diff --git a/drivers/macintosh/windfarm_pm121.c b/drivers/macintosh/windfarm_pm121.c
index 947d4afa25ca..30e6195e19d4 100644
--- a/drivers/macintosh/windfarm_pm121.c
+++ b/drivers/macintosh/windfarm_pm121.c
@@ -482,7 +482,7 @@ static s32 pm121_correct(s32 new_setpoint,
482 new_min += correction->offset; 482 new_min += correction->offset;
483 new_min = (new_min >> 16) + min; 483 new_min = (new_min >> 16) + min;
484 484
485 return max(new_setpoint, max(new_min, 0)); 485 return max3(new_setpoint, new_min, 0);
486} 486}
487 487
488static s32 pm121_connect(unsigned int control_id, s32 setpoint) 488static s32 pm121_connect(unsigned int control_id, s32 setpoint)