diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/macintosh | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'drivers/macintosh')
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 | |||
102 | config ADB_PMU_LED_IDE | 102 | config 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 | ||
260 | config 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 | |||
271 | config 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 | |||
278 | config 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 | |||
259 | endif # MACINTOSH_DRIVERS | 286 | endif # 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 |
50 | obj-$(CONFIG_PMAC_RACKMETER) += rack-meter.o | 50 | obj-$(CONFIG_PMAC_RACKMETER) += rack-meter.o |
51 | |||
52 | obj-$(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) | |||
80 | static void adb_iop_complete(struct iop_msg *msg) | 80 | static 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; | |||
55 | extern struct adb_driver via_pmu_driver; | 54 | extern struct adb_driver via_pmu_driver; |
56 | extern struct adb_driver macio_adb_driver; | 55 | extern struct adb_driver macio_adb_driver; |
57 | 56 | ||
57 | static DEFINE_MUTEX(adb_mutex); | ||
58 | static struct adb_driver *adb_driver_list[] = { | 58 | static 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; | |||
83 | BLOCKING_NOTIFIER_HEAD(adb_client_list); | 83 | BLOCKING_NOTIFIER_HEAD(adb_client_list); |
84 | static int adb_got_sleep; | 84 | static int adb_got_sleep; |
85 | static int adb_inited; | 85 | static int adb_inited; |
86 | static DECLARE_MUTEX(adb_probe_mutex); | 86 | static DEFINE_SEMAPHORE(adb_probe_mutex); |
87 | static int sleepy_trackpad; | 87 | static int sleepy_trackpad; |
88 | static int autopoll_devs; | 88 | static int autopoll_devs; |
89 | int __adb_probe_sync; | 89 | int __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 | ||
667 | out: | 667 | out: |
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 | |||
5 | ams-y := ams-core.o ams-input.o | ||
6 | ams-$(CONFIG_SENSORS_AMS_PMU) += ams-pmu.o | ||
7 | ams-$(CONFIG_SENSORS_AMS_I2C) += ams-i2c.o | ||
8 | obj-$(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 */ | ||
32 | struct ams ams_info; | ||
33 | |||
34 | static unsigned int verbose; | ||
35 | module_param(verbose, bool, 0644); | ||
36 | MODULE_PARM_DESC(verbose, "Show free falls and shocks in kernel output"); | ||
37 | |||
38 | /* Call with ams_info.lock held! */ | ||
39 | void 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 | |||
57 | static 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 | |||
69 | static DEVICE_ATTR(current, S_IRUGO, ams_show_current, NULL); | ||
70 | |||
71 | static 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 | |||
83 | static enum ams_irq ams_freefall_irq_data = AMS_IRQ_FREEFALL; | ||
84 | static struct pmf_irq_client ams_freefall_client = { | ||
85 | .owner = THIS_MODULE, | ||
86 | .handler = ams_handle_irq, | ||
87 | .data = &ams_freefall_irq_data, | ||
88 | }; | ||
89 | |||
90 | static enum ams_irq ams_shock_irq_data = AMS_IRQ_SHOCK; | ||
91 | static 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 | */ | ||
100 | static 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! */ | ||
132 | int 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; | ||
181 | release_device_file: | ||
182 | device_remove_file(&ams_info.of_dev->dev, &dev_attr_current); | ||
183 | release_of: | ||
184 | of_device_unregister(ams_info.of_dev); | ||
185 | release_shock: | ||
186 | pmf_unregister_irq_client(&ams_shock_client); | ||
187 | release_freefall: | ||
188 | pmf_unregister_irq_client(&ams_freefall_client); | ||
189 | return result; | ||
190 | } | ||
191 | |||
192 | int __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 | |||
216 | void 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 | |||
239 | static void __exit ams_exit(void) | ||
240 | { | ||
241 | /* Shut down implementation */ | ||
242 | ams_info.exit(); | ||
243 | } | ||
244 | |||
245 | MODULE_AUTHOR("Stelian Pop, Michael Hanselmann"); | ||
246 | MODULE_DESCRIPTION("Apple Motion Sensor driver"); | ||
247 | MODULE_LICENSE("GPL"); | ||
248 | |||
249 | module_init(ams_init); | ||
250 | module_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 */ | ||
51 | enum 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 | |||
63 | static int ams_i2c_probe(struct i2c_client *client, | ||
64 | const struct i2c_device_id *id); | ||
65 | static int ams_i2c_remove(struct i2c_client *client); | ||
66 | |||
67 | static const struct i2c_device_id ams_id[] = { | ||
68 | { "ams", 0 }, | ||
69 | { } | ||
70 | }; | ||
71 | MODULE_DEVICE_TABLE(i2c, ams_id); | ||
72 | |||
73 | static 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 | |||
83 | static s32 ams_i2c_read(u8 reg) | ||
84 | { | ||
85 | return i2c_smbus_read_byte_data(ams_info.i2c_client, reg); | ||
86 | } | ||
87 | |||
88 | static int ams_i2c_write(u8 reg, u8 value) | ||
89 | { | ||
90 | return i2c_smbus_write_byte_data(ams_info.i2c_client, reg, value); | ||
91 | } | ||
92 | |||
93 | static 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 | |||
112 | static 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 | |||
142 | static 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 | |||
151 | static u8 ams_i2c_get_vendor(void) | ||
152 | { | ||
153 | return ams_i2c_read(AMS_VENDOR); | ||
154 | } | ||
155 | |||
156 | static 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 | |||
163 | static 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 | |||
238 | static 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 | |||
257 | static void ams_i2c_exit(void) | ||
258 | { | ||
259 | i2c_del_driver(&ams_i2c_driver); | ||
260 | } | ||
261 | |||
262 | int __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 | |||
22 | static unsigned int joystick; | ||
23 | module_param(joystick, bool, S_IRUGO); | ||
24 | MODULE_PARM_DESC(joystick, "Enable the input class device on module load"); | ||
25 | |||
26 | static unsigned int invert; | ||
27 | module_param(invert, bool, S_IWUSR | S_IRUGO); | ||
28 | MODULE_PARM_DESC(invert, "Invert input data on X and Y axis"); | ||
29 | |||
30 | static DEFINE_MUTEX(ams_input_mutex); | ||
31 | |||
32 | static 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! */ | ||
55 | static 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 | |||
99 | static 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 | |||
110 | static 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 | |||
116 | static 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 | |||
139 | static DEVICE_ATTR(joystick, S_IRUGO | S_IWUSR, | ||
140 | ams_input_show_joystick, ams_input_store_joystick); | ||
141 | |||
142 | int 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 | |||
150 | void 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 | |||
44 | static u8 ams_pmu_cmd; | ||
45 | |||
46 | static 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 */ | ||
52 | static 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 */ | ||
65 | static 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 */ | ||
83 | static 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 | |||
113 | static 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 | |||
122 | static u8 ams_pmu_get_vendor(void) | ||
123 | { | ||
124 | return ams_pmu_get_register(AMS_VENDOR); | ||
125 | } | ||
126 | |||
127 | static 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 | |||
134 | static 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 | |||
149 | int __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 | |||
9 | enum 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 | |||
19 | struct 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 | |||
60 | extern struct ams ams_info; | ||
61 | |||
62 | extern void ams_sensors(s8 *x, s8 *y, s8 *z); | ||
63 | extern int ams_sensor_attach(void); | ||
64 | extern void ams_sensor_detach(void); | ||
65 | |||
66 | extern int ams_pmu_init(struct device_node *np); | ||
67 | extern int ams_i2c_init(struct device_node *np); | ||
68 | |||
69 | extern int ams_input_init(void); | ||
70 | extern 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 | ||
142 | static struct miscdevice anslcd_dev = { | 143 | static 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 | ||
24 | static struct input_dev *mac_hid_emumouse_dev; | 24 | static struct input_dev *mac_hid_emumouse_dev; |
25 | 25 | ||
26 | static DEFINE_MUTEX(mac_hid_emumouse_mutex); | ||
27 | |||
26 | static int mac_hid_create_emumouse(void) | 28 | static 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 | ||
286 | static void __devexit rackmeter_stop_cpu_sniffer(struct rackmeter *rm) | 286 | static 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 | ||
292 | static int __devinit rackmeter_setup(struct rackmeter *rm) | 292 | static 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 | */ |
99 | static DEFINE_MUTEX(smu_mutex); | ||
100 | static struct smu_device *smu; | 100 | static struct smu_device *smu; |
101 | static DEFINE_MUTEX(smu_part_access); | 101 | static DEFINE_MUTEX(smu_part_access); |
102 | static int smu_irq_inited; | 102 | static int smu_irq_inited; |
@@ -645,8 +645,7 @@ static void smu_expose_childs(struct work_struct *unused) | |||
645 | 645 | ||
646 | static DECLARE_WORK(smu_expose_childs_work, smu_expose_childs); | 646 | static DECLARE_WORK(smu_expose_childs_work, smu_expose_childs); |
647 | 647 | ||
648 | static int smu_platform_probe(struct platform_device* dev, | 648 | static 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 | ||
672 | static struct of_platform_driver smu_of_platform_driver = | 671 | static 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 | ||
668 | static void thermostat_remove_files(void) | 668 | static 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; | |||
153 | static struct i2c_adapter * u3_1; | 153 | static struct i2c_adapter * u3_1; |
154 | static struct i2c_adapter * k2; | 154 | static struct i2c_adapter * k2; |
155 | static struct i2c_client * fcu; | 155 | static struct i2c_client * fcu; |
156 | static struct cpu_pid_state cpu_state[2]; | 156 | static struct cpu_pid_state processor_state[2]; |
157 | static struct basckside_pid_params backside_params; | 157 | static struct basckside_pid_params backside_params; |
158 | static struct backside_pid_state backside_state; | 158 | static struct backside_pid_state backside_state; |
159 | static struct drives_pid_state drives_state; | 159 | static 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 | ||
665 | static void fetch_cpu_pumps_minmax(void) | 665 | static 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 | ||
720 | BUILD_SHOW_FUNC_FIX(cpu0_temperature, cpu_state[0].last_temp) | 720 | BUILD_SHOW_FUNC_FIX(cpu0_temperature, processor_state[0].last_temp) |
721 | BUILD_SHOW_FUNC_FIX(cpu0_voltage, cpu_state[0].voltage) | 721 | BUILD_SHOW_FUNC_FIX(cpu0_voltage, processor_state[0].voltage) |
722 | BUILD_SHOW_FUNC_FIX(cpu0_current, cpu_state[0].current_a) | 722 | BUILD_SHOW_FUNC_FIX(cpu0_current, processor_state[0].current_a) |
723 | BUILD_SHOW_FUNC_INT(cpu0_exhaust_fan_rpm, cpu_state[0].rpm) | 723 | BUILD_SHOW_FUNC_INT(cpu0_exhaust_fan_rpm, processor_state[0].rpm) |
724 | BUILD_SHOW_FUNC_INT(cpu0_intake_fan_rpm, cpu_state[0].intake_rpm) | 724 | BUILD_SHOW_FUNC_INT(cpu0_intake_fan_rpm, processor_state[0].intake_rpm) |
725 | 725 | ||
726 | BUILD_SHOW_FUNC_FIX(cpu1_temperature, cpu_state[1].last_temp) | 726 | BUILD_SHOW_FUNC_FIX(cpu1_temperature, processor_state[1].last_temp) |
727 | BUILD_SHOW_FUNC_FIX(cpu1_voltage, cpu_state[1].voltage) | 727 | BUILD_SHOW_FUNC_FIX(cpu1_voltage, processor_state[1].voltage) |
728 | BUILD_SHOW_FUNC_FIX(cpu1_current, cpu_state[1].current_a) | 728 | BUILD_SHOW_FUNC_FIX(cpu1_current, processor_state[1].current_a) |
729 | BUILD_SHOW_FUNC_INT(cpu1_exhaust_fan_rpm, cpu_state[1].rpm) | 729 | BUILD_SHOW_FUNC_INT(cpu1_exhaust_fan_rpm, processor_state[1].rpm) |
730 | BUILD_SHOW_FUNC_INT(cpu1_intake_fan_rpm, cpu_state[1].intake_rpm) | 730 | BUILD_SHOW_FUNC_INT(cpu1_intake_fan_rpm, processor_state[1].intake_rpm) |
731 | 731 | ||
732 | BUILD_SHOW_FUNC_FIX(backside_temperature, backside_state.last_temp) | 732 | BUILD_SHOW_FUNC_FIX(backside_temperature, backside_state.last_temp) |
733 | BUILD_SHOW_FUNC_INT(backside_fan_pwm, backside_state.pwm) | 733 | BUILD_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 | ||
920 | static void do_monitor_cpu_combined(void) | 920 | static 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 | */ |
1153 | static int init_cpu_state(struct cpu_pid_state *state, int index) | 1153 | static 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 | */ |
1208 | static void dispose_cpu_state(struct cpu_pid_state *state) | 1208 | static 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 | */ |
1886 | static void dispose_control_loops(void) | 1886 | static 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 | ||
2213 | static int fcu_of_probe(struct platform_device* dev, const struct of_device_id *match) | 2213 | static 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 | }; |
2241 | MODULE_DEVICE_TABLE(of, fcu_match); | ||
2238 | 2242 | ||
2239 | static struct of_platform_driver fcu_of_platform_driver = | 2243 | static 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 | */ |
2253 | static int __init therm_pm72_init(void) | 2257 | static 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 | ||
2286 | static void __exit therm_pm72_exit(void) | 2269 | static 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 | ||
2294 | module_init(therm_pm72_init); | 2274 | module_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 | ||
50 | static struct { | 50 | static 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 | ||
446 | static int | 446 | static int therm_of_probe(struct platform_device *dev) |
447 | therm_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 | ||
465 | static struct of_platform_driver therm_of_driver = { | 464 | static 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 | ||
516 | static void __exit | 515 | static void __exit |
517 | g4fan_exit( void ) | 516 | g4fan_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 | ||
18 | static struct backlight_ops pmu_backlight_data; | 18 | static const struct backlight_ops pmu_backlight_data; |
19 | static DEFINE_SPINLOCK(pmu_backlight_lock); | 19 | static DEFINE_SPINLOCK(pmu_backlight_lock); |
20 | static int sleeping, uses_pmu_bl; | 20 | static int sleeping, uses_pmu_bl; |
21 | static u8 bl_curve[FB_BACKLIGHT_LEVELS]; | 21 | static 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 | ||
118 | static struct backlight_ops pmu_backlight_data = { | 118 | static 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 | ||
76 | static DEFINE_MUTEX(pmu_info_proc_mutex); | ||
76 | static volatile unsigned char __iomem *via; | 77 | static 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 | ||
2259 | static struct platform_suspend_ops pmu_pm_ops = { | 2260 | static 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 | ||
2403 | static struct miscdevice pmu_device = { | 2405 | static 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) |
2526 | int pmu_sys_suspended; | 2528 | int pmu_sys_suspended; |
2527 | 2529 | ||
2528 | static int pmu_sys_suspend(struct sys_device *sysdev, pm_message_t state) | 2530 | static 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 | ||
2545 | static int pmu_sys_resume(struct sys_device *sysdev) | 2544 | static 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 */ | 2564 | static struct syscore_ops pmu_syscore_ops = { |
2568 | 2565 | .suspend = pmu_syscore_suspend, | |
2569 | static struct sysdev_class pmu_sysclass = { | 2566 | .resume = pmu_syscore_resume, |
2570 | .name = "pmu", | ||
2571 | }; | ||
2572 | |||
2573 | static struct sys_device device_pmu = { | ||
2574 | .cls = &pmu_sysclass, | ||
2575 | }; | ||
2576 | |||
2577 | static 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 | ||
2584 | static int __init init_pmu_sysfs(void) | 2569 | static 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 | 2575 | subsys_initcall(pmu_syscore_register); | |
2606 | subsys_initcall(init_pmu_sysfs); | 2576 | #endif /* CONFIG_SUSPEND && CONFIG_PPC32 */ |
2607 | 2577 | ||
2608 | EXPORT_SYMBOL(pmu_request); | 2578 | EXPORT_SYMBOL(pmu_request); |
2609 | EXPORT_SYMBOL(pmu_queue_request); | 2579 | EXPORT_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 | ||
488 | static s32 pm121_connect(unsigned int control_id, s32 setpoint) | 488 | static s32 pm121_connect(unsigned int control_id, s32 setpoint) |