aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-04-29 11:19:14 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-29 11:19:14 -0400
commit867a89e0b73af48838c7987e80899a1ff26dd6ff (patch)
treeb4a8830b3e880b9a5133ad1ec3106665819cc8d4 /drivers
parent44473d991332053eb3fea1e08f8a6ee2c6fb409c (diff)
parent6c39103ce5192bdb2195f3daab7323dfa44fb52e (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: [RAPIDIO] Change RapidIO doorbell source and target ID field to 16-bit [RAPIDIO] Add RapidIO connection info print out and re-training for broken connections [RAPIDIO] Add serial RapidIO controller support, which includes MPC8548, MPC8641 [RAPIDIO] Add RapidIO node probing into MPC86xx_HPCN board id table [RAPIDIO] Add RapidIO node into MPC8641HPCN dts file [RAPIDIO] Auto-probe the RapidIO system size [RAPIDIO] Add OF-tree support to RapidIO controller driver [RAPIDIO] Add RapidIO multi mport support [RAPIDIO] Move include/asm-ppc/rio.h to asm-powerpc [RAPIDIO] Add RapidIO option to kernel configuration [RAPIDIO] Change RIO function mpc85xx_ to fsl_ [POWERPC] Provide walk_memory_resource() for powerpc [POWERPC] Update lmb data structures for hotplug memory add/remove [POWERPC] Hotplug memory remove notifications for powerpc [POWERPC] windfarm: Add PowerMac 12,1 support [POWERPC] Fix building of pmac32 when CONFIG_NVRAM=m [POWERPC] Add IRQSTACKS support on ppc32 [POWERPC] Use __always_inline for xchg* and cmpxchg* [POWERPC] Add fast little-endian switch system call
Diffstat (limited to 'drivers')
-rw-r--r--drivers/macintosh/Kconfig8
-rw-r--r--drivers/macintosh/Makefile5
-rw-r--r--drivers/macintosh/windfarm_lm75_sensor.c6
-rw-r--r--drivers/macintosh/windfarm_max6690_sensor.c20
-rw-r--r--drivers/macintosh/windfarm_pm121.c1040
-rw-r--r--drivers/macintosh/windfarm_smu_controls.c4
-rw-r--r--drivers/net/rionet.c16
-rw-r--r--drivers/rapidio/Kconfig8
-rw-r--r--drivers/rapidio/rio-access.c10
-rw-r--r--drivers/rapidio/rio-scan.c55
-rw-r--r--drivers/rapidio/rio-sysfs.c3
-rw-r--r--drivers/rapidio/rio.c2
-rw-r--r--drivers/rapidio/rio.h9
13 files changed, 1140 insertions, 46 deletions
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig
index 77f50b63a970..b52659620d50 100644
--- a/drivers/macintosh/Kconfig
+++ b/drivers/macintosh/Kconfig
@@ -234,6 +234,14 @@ config WINDFARM_PM112
234 which are the recent dual and quad G5 machines using the 234 which are the recent dual and quad G5 machines using the
235 970MP dual-core processor. 235 970MP dual-core processor.
236 236
237config WINDFARM_PM121
238 tristate "Support for thermal management on PowerMac12,1"
239 depends on WINDFARM && I2C && PMAC_SMU
240 select I2C_POWERMAC
241 help
242 This driver provides thermal control for the PowerMac12,1
243 which is the iMac G5 (iSight).
244
237config ANSLCD 245config ANSLCD
238 tristate "Support for ANS LCD display" 246 tristate "Support for ANS LCD display"
239 depends on ADB_CUDA && PPC_PMAC 247 depends on ADB_CUDA && PPC_PMAC
diff --git a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile
index 2dfc3f4eaf42..e3132efa17c0 100644
--- a/drivers/macintosh/Makefile
+++ b/drivers/macintosh/Makefile
@@ -42,4 +42,9 @@ obj-$(CONFIG_WINDFARM_PM112) += windfarm_pm112.o windfarm_smu_sat.o \
42 windfarm_smu_sensors.o \ 42 windfarm_smu_sensors.o \
43 windfarm_max6690_sensor.o \ 43 windfarm_max6690_sensor.o \
44 windfarm_lm75_sensor.o windfarm_pid.o 44 windfarm_lm75_sensor.o windfarm_pid.o
45obj-$(CONFIG_WINDFARM_PM121) += windfarm_pm121.o windfarm_smu_sat.o \
46 windfarm_smu_controls.o \
47 windfarm_smu_sensors.o \
48 windfarm_max6690_sensor.o \
49 windfarm_lm75_sensor.o windfarm_pid.o
45obj-$(CONFIG_PMAC_RACKMETER) += rack-meter.o 50obj-$(CONFIG_PMAC_RACKMETER) += rack-meter.o
diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c
index 7e10c3ab4d50..b92b959fe16e 100644
--- a/drivers/macintosh/windfarm_lm75_sensor.c
+++ b/drivers/macintosh/windfarm_lm75_sensor.c
@@ -127,6 +127,12 @@ static struct wf_lm75_sensor *wf_lm75_create(struct i2c_adapter *adapter,
127 */ 127 */
128 if (!strcmp(loc, "Hard drive") || !strcmp(loc, "DRIVE BAY")) 128 if (!strcmp(loc, "Hard drive") || !strcmp(loc, "DRIVE BAY"))
129 lm->sens.name = "hd-temp"; 129 lm->sens.name = "hd-temp";
130 else if (!strcmp(loc, "Incoming Air Temp"))
131 lm->sens.name = "incoming-air-temp";
132 else if (!strcmp(loc, "ODD Temp"))
133 lm->sens.name = "optical-drive-temp";
134 else if (!strcmp(loc, "HD Temp"))
135 lm->sens.name = "hard-drive-temp";
130 else 136 else
131 goto fail; 137 goto fail;
132 138
diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c
index 5f03aab9fb5d..e207a90d6b27 100644
--- a/drivers/macintosh/windfarm_max6690_sensor.c
+++ b/drivers/macintosh/windfarm_max6690_sensor.c
@@ -77,18 +77,28 @@ static struct wf_sensor_ops wf_max6690_ops = {
77 .owner = THIS_MODULE, 77 .owner = THIS_MODULE,
78}; 78};
79 79
80static void wf_max6690_create(struct i2c_adapter *adapter, u8 addr) 80static void wf_max6690_create(struct i2c_adapter *adapter, u8 addr,
81 const char *loc)
81{ 82{
82 struct wf_6690_sensor *max; 83 struct wf_6690_sensor *max;
83 char *name = "backside-temp"; 84 char *name;
84 85
85 max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL); 86 max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL);
86 if (max == NULL) { 87 if (max == NULL) {
87 printk(KERN_ERR "windfarm: Couldn't create MAX6690 sensor %s: " 88 printk(KERN_ERR "windfarm: Couldn't create MAX6690 sensor %s: "
88 "no memory\n", name); 89 "no memory\n", loc);
89 return; 90 return;
90 } 91 }
91 92
93 if (!strcmp(loc, "BACKSIDE"))
94 name = "backside-temp";
95 else if (!strcmp(loc, "NB Ambient"))
96 name = "north-bridge-temp";
97 else if (!strcmp(loc, "GPU Ambient"))
98 name = "gpu-temp";
99 else
100 goto fail;
101
92 max->sens.ops = &wf_max6690_ops; 102 max->sens.ops = &wf_max6690_ops;
93 max->sens.name = name; 103 max->sens.name = name;
94 max->i2c.addr = addr >> 1; 104 max->i2c.addr = addr >> 1;
@@ -138,9 +148,7 @@ static int wf_max6690_attach(struct i2c_adapter *adapter)
138 if (loc == NULL || addr == 0) 148 if (loc == NULL || addr == 0)
139 continue; 149 continue;
140 printk("found max6690, loc=%s addr=0x%02x\n", loc, addr); 150 printk("found max6690, loc=%s addr=0x%02x\n", loc, addr);
141 if (strcmp(loc, "BACKSIDE")) 151 wf_max6690_create(adapter, addr, loc);
142 continue;
143 wf_max6690_create(adapter, addr);
144 } 152 }
145 153
146 return 0; 154 return 0;
diff --git a/drivers/macintosh/windfarm_pm121.c b/drivers/macintosh/windfarm_pm121.c
new file mode 100644
index 000000000000..66ec4fb115bb
--- /dev/null
+++ b/drivers/macintosh/windfarm_pm121.c
@@ -0,0 +1,1040 @@
1/*
2 * Windfarm PowerMac thermal control. iMac G5 iSight
3 *
4 * (c) Copyright 2007 Étienne Bersac <bersace@gmail.com>
5 *
6 * Bits & pieces from windfarm_pm81.c by (c) Copyright 2005 Benjamin
7 * Herrenschmidt, IBM Corp. <benh@kernel.crashing.org>
8 *
9 * Released under the term of the GNU GPL v2.
10 *
11 *
12 *
13 * PowerMac12,1
14 * ============
15 *
16 *
17 * The algorithm used is the PID control algorithm, used the same way
18 * the published Darwin code does, using the same values that are
19 * present in the Darwin 8.10 snapshot property lists (note however
20 * that none of the code has been re-used, it's a complete
21 * re-implementation
22 *
23 * There is two models using PowerMac12,1. Model 2 is iMac G5 iSight
24 * 17" while Model 3 is iMac G5 20". They do have both the same
25 * controls with a tiny difference. The control-ids of hard-drive-fan
26 * and cpu-fan is swapped.
27 *
28 *
29 * Target Correction :
30 *
31 * controls have a target correction calculated as :
32 *
33 * new_min = ((((average_power * slope) >> 16) + offset) >> 16) + min_value
34 * new_value = max(new_value, max(new_min, 0))
35 *
36 * OD Fan control correction.
37 *
38 * # model_id: 2
39 * offset : -19563152
40 * slope : 1956315
41 *
42 * # model_id: 3
43 * offset : -15650652
44 * slope : 1565065
45 *
46 * HD Fan control correction.
47 *
48 * # model_id: 2
49 * offset : -15650652
50 * slope : 1565065
51 *
52 * # model_id: 3
53 * offset : -19563152
54 * slope : 1956315
55 *
56 * CPU Fan control correction.
57 *
58 * # model_id: 2
59 * offset : -25431900
60 * slope : 2543190
61 *
62 * # model_id: 3
63 * offset : -15650652
64 * slope : 1565065
65 *
66 *
67 * Target rubber-banding :
68 *
69 * Some controls have a target correction which depends on another
70 * control value. The correction is computed in the following way :
71 *
72 * new_min = ref_value * slope + offset
73 *
74 * ref_value is the value of the reference control. If new_min is
75 * greater than 0, then we correct the target value using :
76 *
77 * new_target = max (new_target, new_min >> 16)
78 *
79 *
80 * # model_id : 2
81 * control : cpu-fan
82 * ref : optical-drive-fan
83 * offset : -15650652
84 * slope : 1565065
85 *
86 * # model_id : 3
87 * control : optical-drive-fan
88 * ref : hard-drive-fan
89 * offset : -32768000
90 * slope : 65536
91 *
92 *
93 * In order to have the moste efficient correction with those
94 * dependencies, we must trigger HD loop before OD loop before CPU
95 * loop.
96 *
97 *
98 * The various control loops found in Darwin config file are:
99 *
100 * HD Fan control loop.
101 *
102 * # model_id: 2
103 * control : hard-drive-fan
104 * sensor : hard-drive-temp
105 * PID params : G_d = 0x00000000
106 * G_p = 0x002D70A3
107 * G_r = 0x00019999
108 * History = 2 entries
109 * Input target = 0x370000
110 * Interval = 5s
111 *
112 * # model_id: 3
113 * control : hard-drive-fan
114 * sensor : hard-drive-temp
115 * PID params : G_d = 0x00000000
116 * G_p = 0x002170A3
117 * G_r = 0x00019999
118 * History = 2 entries
119 * Input target = 0x370000
120 * Interval = 5s
121 *
122 * OD Fan control loop.
123 *
124 * # model_id: 2
125 * control : optical-drive-fan
126 * sensor : optical-drive-temp
127 * PID params : G_d = 0x00000000
128 * G_p = 0x001FAE14
129 * G_r = 0x00019999
130 * History = 2 entries
131 * Input target = 0x320000
132 * Interval = 5s
133 *
134 * # model_id: 3
135 * control : optical-drive-fan
136 * sensor : optical-drive-temp
137 * PID params : G_d = 0x00000000
138 * G_p = 0x001FAE14
139 * G_r = 0x00019999
140 * History = 2 entries
141 * Input target = 0x320000
142 * Interval = 5s
143 *
144 * GPU Fan control loop.
145 *
146 * # model_id: 2
147 * control : hard-drive-fan
148 * sensor : gpu-temp
149 * PID params : G_d = 0x00000000
150 * G_p = 0x002A6666
151 * G_r = 0x00019999
152 * History = 2 entries
153 * Input target = 0x5A0000
154 * Interval = 5s
155 *
156 * # model_id: 3
157 * control : cpu-fan
158 * sensor : gpu-temp
159 * PID params : G_d = 0x00000000
160 * G_p = 0x0010CCCC
161 * G_r = 0x00019999
162 * History = 2 entries
163 * Input target = 0x500000
164 * Interval = 5s
165 *
166 * KODIAK (aka northbridge) Fan control loop.
167 *
168 * # model_id: 2
169 * control : optical-drive-fan
170 * sensor : north-bridge-temp
171 * PID params : G_d = 0x00000000
172 * G_p = 0x003BD70A
173 * G_r = 0x00019999
174 * History = 2 entries
175 * Input target = 0x550000
176 * Interval = 5s
177 *
178 * # model_id: 3
179 * control : hard-drive-fan
180 * sensor : north-bridge-temp
181 * PID params : G_d = 0x00000000
182 * G_p = 0x0030F5C2
183 * G_r = 0x00019999
184 * History = 2 entries
185 * Input target = 0x550000
186 * Interval = 5s
187 *
188 * CPU Fan control loop.
189 *
190 * control : cpu-fan
191 * sensors : cpu-temp, cpu-power
192 * PID params : from SDB partition
193 *
194 *
195 * CPU Slew control loop.
196 *
197 * control : cpufreq-clamp
198 * sensor : cpu-temp
199 *
200 */
201
202#undef DEBUG
203
204#include <linux/types.h>
205#include <linux/errno.h>
206#include <linux/kernel.h>
207#include <linux/delay.h>
208#include <linux/slab.h>
209#include <linux/init.h>
210#include <linux/spinlock.h>
211#include <linux/wait.h>
212#include <linux/kmod.h>
213#include <linux/device.h>
214#include <linux/platform_device.h>
215#include <asm/prom.h>
216#include <asm/machdep.h>
217#include <asm/io.h>
218#include <asm/system.h>
219#include <asm/sections.h>
220#include <asm/smu.h>
221
222#include "windfarm.h"
223#include "windfarm_pid.h"
224
225#define VERSION "0.3"
226
227static int pm121_mach_model; /* machine model id */
228
229/* Controls & sensors */
230static struct wf_sensor *sensor_cpu_power;
231static struct wf_sensor *sensor_cpu_temp;
232static struct wf_sensor *sensor_cpu_voltage;
233static struct wf_sensor *sensor_cpu_current;
234static struct wf_sensor *sensor_gpu_temp;
235static struct wf_sensor *sensor_north_bridge_temp;
236static struct wf_sensor *sensor_hard_drive_temp;
237static struct wf_sensor *sensor_optical_drive_temp;
238static struct wf_sensor *sensor_incoming_air_temp; /* unused ! */
239
240enum {
241 FAN_CPU,
242 FAN_HD,
243 FAN_OD,
244 CPUFREQ,
245 N_CONTROLS
246};
247static struct wf_control *controls[N_CONTROLS] = {};
248
249/* Set to kick the control loop into life */
250static int pm121_all_controls_ok, pm121_all_sensors_ok, pm121_started;
251
252enum {
253 FAILURE_FAN = 1 << 0,
254 FAILURE_SENSOR = 1 << 1,
255 FAILURE_OVERTEMP = 1 << 2
256};
257
258/* All sys loops. Note the HD before the OD loop in order to have it
259 run before. */
260enum {
261 LOOP_GPU, /* control = hd or cpu, but luckily,
262 it doesn't matter */
263 LOOP_HD, /* control = hd */
264 LOOP_KODIAK, /* control = hd or od */
265 LOOP_OD, /* control = od */
266 N_LOOPS
267};
268
269static const char *loop_names[N_LOOPS] = {
270 "GPU",
271 "HD",
272 "KODIAK",
273 "OD",
274};
275
276#define PM121_NUM_CONFIGS 2
277
278static unsigned int pm121_failure_state;
279static int pm121_readjust, pm121_skipping;
280static s32 average_power;
281
282struct pm121_correction {
283 int offset;
284 int slope;
285};
286
287static struct pm121_correction corrections[N_CONTROLS][PM121_NUM_CONFIGS] = {
288 /* FAN_OD */
289 {
290 /* MODEL 2 */
291 { .offset = -19563152,
292 .slope = 1956315
293 },
294 /* MODEL 3 */
295 { .offset = -15650652,
296 .slope = 1565065
297 },
298 },
299 /* FAN_HD */
300 {
301 /* MODEL 2 */
302 { .offset = -15650652,
303 .slope = 1565065
304 },
305 /* MODEL 3 */
306 { .offset = -19563152,
307 .slope = 1956315
308 },
309 },
310 /* FAN_CPU */
311 {
312 /* MODEL 2 */
313 { .offset = -25431900,
314 .slope = 2543190
315 },
316 /* MODEL 3 */
317 { .offset = -15650652,
318 .slope = 1565065
319 },
320 },
321 /* CPUFREQ has no correction (and is not implemented at all) */
322};
323
324struct pm121_connection {
325 unsigned int control_id;
326 unsigned int ref_id;
327 struct pm121_correction correction;
328};
329
330static struct pm121_connection pm121_connections[] = {
331 /* MODEL 2 */
332 { .control_id = FAN_CPU,
333 .ref_id = FAN_OD,
334 { .offset = -32768000,
335 .slope = 65536
336 }
337 },
338 /* MODEL 3 */
339 { .control_id = FAN_OD,
340 .ref_id = FAN_HD,
341 { .offset = -32768000,
342 .slope = 65536
343 }
344 },
345};
346
347/* pointer to the current model connection */
348static struct pm121_connection *pm121_connection;
349
350/*
351 * ****** System Fans Control Loop ******
352 *
353 */
354
355/* Since each loop handles only one control and we want to avoid
356 * writing virtual control, we store the control correction with the
357 * loop params. Some data are not set, there are common to all loop
358 * and thus, hardcoded.
359 */
360struct pm121_sys_param {
361 /* purely informative since we use mach_model-2 as index */
362 int model_id;
363 struct wf_sensor **sensor; /* use sensor_id instead ? */
364 s32 gp, itarget;
365 unsigned int control_id;
366};
367
368static struct pm121_sys_param
369pm121_sys_all_params[N_LOOPS][PM121_NUM_CONFIGS] = {
370 /* GPU Fan control loop */
371 {
372 { .model_id = 2,
373 .sensor = &sensor_gpu_temp,
374 .gp = 0x002A6666,
375 .itarget = 0x5A0000,
376 .control_id = FAN_HD,
377 },
378 { .model_id = 3,
379 .sensor = &sensor_gpu_temp,
380 .gp = 0x0010CCCC,
381 .itarget = 0x500000,
382 .control_id = FAN_CPU,
383 },
384 },
385 /* HD Fan control loop */
386 {
387 { .model_id = 2,
388 .sensor = &sensor_hard_drive_temp,
389 .gp = 0x002D70A3,
390 .itarget = 0x370000,
391 .control_id = FAN_HD,
392 },
393 { .model_id = 3,
394 .sensor = &sensor_hard_drive_temp,
395 .gp = 0x002170A3,
396 .itarget = 0x370000,
397 .control_id = FAN_HD,
398 },
399 },
400 /* KODIAK Fan control loop */
401 {
402 { .model_id = 2,
403 .sensor = &sensor_north_bridge_temp,
404 .gp = 0x003BD70A,
405 .itarget = 0x550000,
406 .control_id = FAN_OD,
407 },
408 { .model_id = 3,
409 .sensor = &sensor_north_bridge_temp,
410 .gp = 0x0030F5C2,
411 .itarget = 0x550000,
412 .control_id = FAN_HD,
413 },
414 },
415 /* OD Fan control loop */
416 {
417 { .model_id = 2,
418 .sensor = &sensor_optical_drive_temp,
419 .gp = 0x001FAE14,
420 .itarget = 0x320000,
421 .control_id = FAN_OD,
422 },
423 { .model_id = 3,
424 .sensor = &sensor_optical_drive_temp,
425 .gp = 0x001FAE14,
426 .itarget = 0x320000,
427 .control_id = FAN_OD,
428 },
429 },
430};
431
432/* the hardcoded values */
433#define PM121_SYS_GD 0x00000000
434#define PM121_SYS_GR 0x00019999
435#define PM121_SYS_HISTORY_SIZE 2
436#define PM121_SYS_INTERVAL 5
437
438/* State data used by the system fans control loop
439 */
440struct pm121_sys_state {
441 int ticks;
442 s32 setpoint;
443 struct wf_pid_state pid;
444};
445
446struct pm121_sys_state *pm121_sys_state[N_LOOPS] = {};
447
448/*
449 * ****** CPU Fans Control Loop ******
450 *
451 */
452
453#define PM121_CPU_INTERVAL 1
454
455/* State data used by the cpu fans control loop
456 */
457struct pm121_cpu_state {
458 int ticks;
459 s32 setpoint;
460 struct wf_cpu_pid_state pid;
461};
462
463static struct pm121_cpu_state *pm121_cpu_state;
464
465
466
467/*
468 * ***** Implementation *****
469 *
470 */
471
472/* correction the value using the output-low-bound correction algo */
473static s32 pm121_correct(s32 new_setpoint,
474 unsigned int control_id,
475 s32 min)
476{
477 s32 new_min;
478 struct pm121_correction *correction;
479 correction = &corrections[control_id][pm121_mach_model - 2];
480
481 new_min = (average_power * correction->slope) >> 16;
482 new_min += correction->offset;
483 new_min = (new_min >> 16) + min;
484
485 return max(new_setpoint, max(new_min, 0));
486}
487
488static s32 pm121_connect(unsigned int control_id, s32 setpoint)
489{
490 s32 new_min, value, new_setpoint;
491
492 if (pm121_connection->control_id == control_id) {
493 controls[control_id]->ops->get_value(controls[control_id],
494 &value);
495 new_min = value * pm121_connection->correction.slope;
496 new_min += pm121_connection->correction.offset;
497 if (new_min > 0) {
498 new_setpoint = max(setpoint, (new_min >> 16));
499 if (new_setpoint != setpoint) {
500 pr_debug("pm121: %s depending on %s, "
501 "corrected from %d to %d RPM\n",
502 controls[control_id]->name,
503 controls[pm121_connection->ref_id]->name,
504 (int) setpoint, (int) new_setpoint);
505 }
506 } else
507 new_setpoint = setpoint;
508 }
509 /* no connection */
510 else
511 new_setpoint = setpoint;
512
513 return new_setpoint;
514}
515
516/* FAN LOOPS */
517static void pm121_create_sys_fans(int loop_id)
518{
519 struct pm121_sys_param *param = NULL;
520 struct wf_pid_param pid_param;
521 struct wf_control *control = NULL;
522 int i;
523
524 /* First, locate the params for this model */
525 for (i = 0; i < PM121_NUM_CONFIGS; i++) {
526 if (pm121_sys_all_params[loop_id][i].model_id == pm121_mach_model) {
527 param = &(pm121_sys_all_params[loop_id][i]);
528 break;
529 }
530 }
531
532 /* No params found, put fans to max */
533 if (param == NULL) {
534 printk(KERN_WARNING "pm121: %s fan config not found "
535 " for this machine model\n",
536 loop_names[loop_id]);
537 goto fail;
538 }
539
540 control = controls[param->control_id];
541
542 /* Alloc & initialize state */
543 pm121_sys_state[loop_id] = kmalloc(sizeof(struct pm121_sys_state),
544 GFP_KERNEL);
545 if (pm121_sys_state[loop_id] == NULL) {
546 printk(KERN_WARNING "pm121: Memory allocation error\n");
547 goto fail;
548 }
549 pm121_sys_state[loop_id]->ticks = 1;
550
551 /* Fill PID params */
552 pid_param.gd = PM121_SYS_GD;
553 pid_param.gp = param->gp;
554 pid_param.gr = PM121_SYS_GR;
555 pid_param.interval = PM121_SYS_INTERVAL;
556 pid_param.history_len = PM121_SYS_HISTORY_SIZE;
557 pid_param.itarget = param->itarget;
558 pid_param.min = control->ops->get_min(control);
559 pid_param.max = control->ops->get_max(control);
560
561 wf_pid_init(&pm121_sys_state[loop_id]->pid, &pid_param);
562
563 pr_debug("pm121: %s Fan control loop initialized.\n"
564 " itarged=%d.%03d, min=%d RPM, max=%d RPM\n",
565 loop_names[loop_id], FIX32TOPRINT(pid_param.itarget),
566 pid_param.min, pid_param.max);
567 return;
568
569 fail:
570 /* note that this is not optimal since another loop may still
571 control the same control */
572 printk(KERN_WARNING "pm121: failed to set up %s loop "
573 "setting \"%s\" to max speed.\n",
574 loop_names[loop_id], control->name);
575
576 if (control)
577 wf_control_set_max(control);
578}
579
580static void pm121_sys_fans_tick(int loop_id)
581{
582 struct pm121_sys_param *param;
583 struct pm121_sys_state *st;
584 struct wf_sensor *sensor;
585 struct wf_control *control;
586 s32 temp, new_setpoint;
587 int rc;
588
589 param = &(pm121_sys_all_params[loop_id][pm121_mach_model-2]);
590 st = pm121_sys_state[loop_id];
591 sensor = *(param->sensor);
592 control = controls[param->control_id];
593
594 if (--st->ticks != 0) {
595 if (pm121_readjust)
596 goto readjust;
597 return;
598 }
599 st->ticks = PM121_SYS_INTERVAL;
600
601 rc = sensor->ops->get_value(sensor, &temp);
602 if (rc) {
603 printk(KERN_WARNING "windfarm: %s sensor error %d\n",
604 sensor->name, rc);
605 pm121_failure_state |= FAILURE_SENSOR;
606 return;
607 }
608
609 pr_debug("pm121: %s Fan tick ! %s: %d.%03d\n",
610 loop_names[loop_id], sensor->name,
611 FIX32TOPRINT(temp));
612
613 new_setpoint = wf_pid_run(&st->pid, temp);
614
615 /* correction */
616 new_setpoint = pm121_correct(new_setpoint,
617 param->control_id,
618 st->pid.param.min);
619 /* linked corretion */
620 new_setpoint = pm121_connect(param->control_id, new_setpoint);
621
622 if (new_setpoint == st->setpoint)
623 return;
624 st->setpoint = new_setpoint;
625 pr_debug("pm121: %s corrected setpoint: %d RPM\n",
626 control->name, (int)new_setpoint);
627 readjust:
628 if (control && pm121_failure_state == 0) {
629 rc = control->ops->set_value(control, st->setpoint);
630 if (rc) {
631 printk(KERN_WARNING "windfarm: %s fan error %d\n",
632 control->name, rc);
633 pm121_failure_state |= FAILURE_FAN;
634 }
635 }
636}
637
638
639/* CPU LOOP */
640static void pm121_create_cpu_fans(void)
641{
642 struct wf_cpu_pid_param pid_param;
643 const struct smu_sdbp_header *hdr;
644 struct smu_sdbp_cpupiddata *piddata;
645 struct smu_sdbp_fvt *fvt;
646 struct wf_control *fan_cpu;
647 s32 tmax, tdelta, maxpow, powadj;
648
649 fan_cpu = controls[FAN_CPU];
650
651 /* First, locate the PID params in SMU SBD */
652 hdr = smu_get_sdb_partition(SMU_SDB_CPUPIDDATA_ID, NULL);
653 if (hdr == 0) {
654 printk(KERN_WARNING "pm121: CPU PID fan config not found.\n");
655 goto fail;
656 }
657 piddata = (struct smu_sdbp_cpupiddata *)&hdr[1];
658
659 /* Get the FVT params for operating point 0 (the only supported one
660 * for now) in order to get tmax
661 */
662 hdr = smu_get_sdb_partition(SMU_SDB_FVT_ID, NULL);
663 if (hdr) {
664 fvt = (struct smu_sdbp_fvt *)&hdr[1];
665 tmax = ((s32)fvt->maxtemp) << 16;
666 } else
667 tmax = 0x5e0000; /* 94 degree default */
668
669 /* Alloc & initialize state */
670 pm121_cpu_state = kmalloc(sizeof(struct pm121_cpu_state),
671 GFP_KERNEL);
672 if (pm121_cpu_state == NULL)
673 goto fail;
674 pm121_cpu_state->ticks = 1;
675
676 /* Fill PID params */
677 pid_param.interval = PM121_CPU_INTERVAL;
678 pid_param.history_len = piddata->history_len;
679 if (pid_param.history_len > WF_CPU_PID_MAX_HISTORY) {
680 printk(KERN_WARNING "pm121: History size overflow on "
681 "CPU control loop (%d)\n", piddata->history_len);
682 pid_param.history_len = WF_CPU_PID_MAX_HISTORY;
683 }
684 pid_param.gd = piddata->gd;
685 pid_param.gp = piddata->gp;
686 pid_param.gr = piddata->gr / pid_param.history_len;
687
688 tdelta = ((s32)piddata->target_temp_delta) << 16;
689 maxpow = ((s32)piddata->max_power) << 16;
690 powadj = ((s32)piddata->power_adj) << 16;
691
692 pid_param.tmax = tmax;
693 pid_param.ttarget = tmax - tdelta;
694 pid_param.pmaxadj = maxpow - powadj;
695
696 pid_param.min = fan_cpu->ops->get_min(fan_cpu);
697 pid_param.max = fan_cpu->ops->get_max(fan_cpu);
698
699 wf_cpu_pid_init(&pm121_cpu_state->pid, &pid_param);
700
701 pr_debug("pm121: CPU Fan control initialized.\n");
702 pr_debug(" ttarged=%d.%03d, tmax=%d.%03d, min=%d RPM, max=%d RPM,\n",
703 FIX32TOPRINT(pid_param.ttarget), FIX32TOPRINT(pid_param.tmax),
704 pid_param.min, pid_param.max);
705
706 return;
707
708 fail:
709 printk(KERN_WARNING "pm121: CPU fan config not found, max fan speed\n");
710
711 if (controls[CPUFREQ])
712 wf_control_set_max(controls[CPUFREQ]);
713 if (fan_cpu)
714 wf_control_set_max(fan_cpu);
715}
716
717
718static void pm121_cpu_fans_tick(struct pm121_cpu_state *st)
719{
720 s32 new_setpoint, temp, power;
721 struct wf_control *fan_cpu = NULL;
722 int rc;
723
724 if (--st->ticks != 0) {
725 if (pm121_readjust)
726 goto readjust;
727 return;
728 }
729 st->ticks = PM121_CPU_INTERVAL;
730
731 fan_cpu = controls[FAN_CPU];
732
733 rc = sensor_cpu_temp->ops->get_value(sensor_cpu_temp, &temp);
734 if (rc) {
735 printk(KERN_WARNING "pm121: CPU temp sensor error %d\n",
736 rc);
737 pm121_failure_state |= FAILURE_SENSOR;
738 return;
739 }
740
741 rc = sensor_cpu_power->ops->get_value(sensor_cpu_power, &power);
742 if (rc) {
743 printk(KERN_WARNING "pm121: CPU power sensor error %d\n",
744 rc);
745 pm121_failure_state |= FAILURE_SENSOR;
746 return;
747 }
748
749 pr_debug("pm121: CPU Fans tick ! CPU temp: %d.%03d°C, power: %d.%03d\n",
750 FIX32TOPRINT(temp), FIX32TOPRINT(power));
751
752 if (temp > st->pid.param.tmax)
753 pm121_failure_state |= FAILURE_OVERTEMP;
754
755 new_setpoint = wf_cpu_pid_run(&st->pid, power, temp);
756
757 /* correction */
758 new_setpoint = pm121_correct(new_setpoint,
759 FAN_CPU,
760 st->pid.param.min);
761
762 /* connected correction */
763 new_setpoint = pm121_connect(FAN_CPU, new_setpoint);
764
765 if (st->setpoint == new_setpoint)
766 return;
767 st->setpoint = new_setpoint;
768 pr_debug("pm121: CPU corrected setpoint: %d RPM\n", (int)new_setpoint);
769
770 readjust:
771 if (fan_cpu && pm121_failure_state == 0) {
772 rc = fan_cpu->ops->set_value(fan_cpu, st->setpoint);
773 if (rc) {
774 printk(KERN_WARNING "pm121: %s fan error %d\n",
775 fan_cpu->name, rc);
776 pm121_failure_state |= FAILURE_FAN;
777 }
778 }
779}
780
781/*
782 * ****** Common ******
783 *
784 */
785
786static void pm121_tick(void)
787{
788 unsigned int last_failure = pm121_failure_state;
789 unsigned int new_failure;
790 s32 total_power;
791 int i;
792
793 if (!pm121_started) {
794 pr_debug("pm121: creating control loops !\n");
795 for (i = 0; i < N_LOOPS; i++)
796 pm121_create_sys_fans(i);
797
798 pm121_create_cpu_fans();
799 pm121_started = 1;
800 }
801
802 /* skipping ticks */
803 if (pm121_skipping && --pm121_skipping)
804 return;
805
806 /* compute average power */
807 total_power = 0;
808 for (i = 0; i < pm121_cpu_state->pid.param.history_len; i++)
809 total_power += pm121_cpu_state->pid.powers[i];
810
811 average_power = total_power / pm121_cpu_state->pid.param.history_len;
812
813
814 pm121_failure_state = 0;
815 for (i = 0 ; i < N_LOOPS; i++) {
816 if (pm121_sys_state[i])
817 pm121_sys_fans_tick(i);
818 }
819
820 if (pm121_cpu_state)
821 pm121_cpu_fans_tick(pm121_cpu_state);
822
823 pm121_readjust = 0;
824 new_failure = pm121_failure_state & ~last_failure;
825
826 /* If entering failure mode, clamp cpufreq and ramp all
827 * fans to full speed.
828 */
829 if (pm121_failure_state && !last_failure) {
830 for (i = 0; i < N_CONTROLS; i++) {
831 if (controls[i])
832 wf_control_set_max(controls[i]);
833 }
834 }
835
836 /* If leaving failure mode, unclamp cpufreq and readjust
837 * all fans on next iteration
838 */
839 if (!pm121_failure_state && last_failure) {
840 if (controls[CPUFREQ])
841 wf_control_set_min(controls[CPUFREQ]);
842 pm121_readjust = 1;
843 }
844
845 /* Overtemp condition detected, notify and start skipping a couple
846 * ticks to let the temperature go down
847 */
848 if (new_failure & FAILURE_OVERTEMP) {
849 wf_set_overtemp();
850 pm121_skipping = 2;
851 }
852
853 /* We only clear the overtemp condition if overtemp is cleared
854 * _and_ no other failure is present. Since a sensor error will
855 * clear the overtemp condition (can't measure temperature) at
856 * the control loop levels, but we don't want to keep it clear
857 * here in this case
858 */
859 if (new_failure == 0 && last_failure & FAILURE_OVERTEMP)
860 wf_clear_overtemp();
861}
862
863
864static struct wf_control* pm121_register_control(struct wf_control *ct,
865 const char *match,
866 unsigned int id)
867{
868 if (controls[id] == NULL && !strcmp(ct->name, match)) {
869 if (wf_get_control(ct) == 0)
870 controls[id] = ct;
871 }
872 return controls[id];
873}
874
875static void pm121_new_control(struct wf_control *ct)
876{
877 int all = 1;
878
879 if (pm121_all_controls_ok)
880 return;
881
882 all = pm121_register_control(ct, "optical-drive-fan", FAN_OD) && all;
883 all = pm121_register_control(ct, "hard-drive-fan", FAN_HD) && all;
884 all = pm121_register_control(ct, "cpu-fan", FAN_CPU) && all;
885 all = pm121_register_control(ct, "cpufreq-clamp", CPUFREQ) && all;
886
887 if (all)
888 pm121_all_controls_ok = 1;
889}
890
891
892
893
894static struct wf_sensor* pm121_register_sensor(struct wf_sensor *sensor,
895 const char *match,
896 struct wf_sensor **var)
897{
898 if (*var == NULL && !strcmp(sensor->name, match)) {
899 if (wf_get_sensor(sensor) == 0)
900 *var = sensor;
901 }
902 return *var;
903}
904
905static void pm121_new_sensor(struct wf_sensor *sr)
906{
907 int all = 1;
908
909 if (pm121_all_sensors_ok)
910 return;
911
912 all = pm121_register_sensor(sr, "cpu-temp",
913 &sensor_cpu_temp) && all;
914 all = pm121_register_sensor(sr, "cpu-current",
915 &sensor_cpu_current) && all;
916 all = pm121_register_sensor(sr, "cpu-voltage",
917 &sensor_cpu_voltage) && all;
918 all = pm121_register_sensor(sr, "cpu-power",
919 &sensor_cpu_power) && all;
920 all = pm121_register_sensor(sr, "hard-drive-temp",
921 &sensor_hard_drive_temp) && all;
922 all = pm121_register_sensor(sr, "optical-drive-temp",
923 &sensor_optical_drive_temp) && all;
924 all = pm121_register_sensor(sr, "incoming-air-temp",
925 &sensor_incoming_air_temp) && all;
926 all = pm121_register_sensor(sr, "north-bridge-temp",
927 &sensor_north_bridge_temp) && all;
928 all = pm121_register_sensor(sr, "gpu-temp",
929 &sensor_gpu_temp) && all;
930
931 if (all)
932 pm121_all_sensors_ok = 1;
933}
934
935
936
937static int pm121_notify(struct notifier_block *self,
938 unsigned long event, void *data)
939{
940 switch (event) {
941 case WF_EVENT_NEW_CONTROL:
942 pr_debug("pm121: new control %s detected\n",
943 ((struct wf_control *)data)->name);
944 pm121_new_control(data);
945 break;
946 case WF_EVENT_NEW_SENSOR:
947 pr_debug("pm121: new sensor %s detected\n",
948 ((struct wf_sensor *)data)->name);
949 pm121_new_sensor(data);
950 break;
951 case WF_EVENT_TICK:
952 if (pm121_all_controls_ok && pm121_all_sensors_ok)
953 pm121_tick();
954 break;
955 }
956
957 return 0;
958}
959
960static struct notifier_block pm121_events = {
961 .notifier_call = pm121_notify,
962};
963
964static int pm121_init_pm(void)
965{
966 const struct smu_sdbp_header *hdr;
967
968 hdr = smu_get_sdb_partition(SMU_SDB_SENSORTREE_ID, NULL);
969 if (hdr != 0) {
970 struct smu_sdbp_sensortree *st =
971 (struct smu_sdbp_sensortree *)&hdr[1];
972 pm121_mach_model = st->model_id;
973 }
974
975 pm121_connection = &pm121_connections[pm121_mach_model - 2];
976
977 printk(KERN_INFO "pm121: Initializing for iMac G5 iSight model ID %d\n",
978 pm121_mach_model);
979
980 return 0;
981}
982
983
984static int pm121_probe(struct platform_device *ddev)
985{
986 wf_register_client(&pm121_events);
987
988 return 0;
989}
990
991static int __devexit pm121_remove(struct platform_device *ddev)
992{
993 wf_unregister_client(&pm121_events);
994 return 0;
995}
996
997static struct platform_driver pm121_driver = {
998 .probe = pm121_probe,
999 .remove = __devexit_p(pm121_remove),
1000 .driver = {
1001 .name = "windfarm",
1002 .bus = &platform_bus_type,
1003 },
1004};
1005
1006
1007static int __init pm121_init(void)
1008{
1009 int rc = -ENODEV;
1010
1011 if (machine_is_compatible("PowerMac12,1"))
1012 rc = pm121_init_pm();
1013
1014 if (rc == 0) {
1015 request_module("windfarm_smu_controls");
1016 request_module("windfarm_smu_sensors");
1017 request_module("windfarm_smu_sat");
1018 request_module("windfarm_lm75_sensor");
1019 request_module("windfarm_max6690_sensor");
1020 request_module("windfarm_cpufreq_clamp");
1021 platform_driver_register(&pm121_driver);
1022 }
1023
1024 return rc;
1025}
1026
1027static void __exit pm121_exit(void)
1028{
1029
1030 platform_driver_unregister(&pm121_driver);
1031}
1032
1033
1034module_init(pm121_init);
1035module_exit(pm121_exit);
1036
1037MODULE_AUTHOR("Étienne Bersac <bersace@gmail.com>");
1038MODULE_DESCRIPTION("Thermal control logic for iMac G5 (iSight)");
1039MODULE_LICENSE("GPL");
1040
diff --git a/drivers/macintosh/windfarm_smu_controls.c b/drivers/macintosh/windfarm_smu_controls.c
index 58c2590f05ec..961fa0e7c2cf 100644
--- a/drivers/macintosh/windfarm_smu_controls.c
+++ b/drivers/macintosh/windfarm_smu_controls.c
@@ -218,6 +218,10 @@ static struct smu_fan_control *smu_fan_create(struct device_node *node,
218 fct->ctrl.name = "cpu-fan"; 218 fct->ctrl.name = "cpu-fan";
219 else if (!strcmp(l, "Hard Drive") || !strcmp(l, "Hard drive")) 219 else if (!strcmp(l, "Hard Drive") || !strcmp(l, "Hard drive"))
220 fct->ctrl.name = "drive-bay-fan"; 220 fct->ctrl.name = "drive-bay-fan";
221 else if (!strcmp(l, "HDD Fan")) /* seen on iMac G5 iSight */
222 fct->ctrl.name = "hard-drive-fan";
223 else if (!strcmp(l, "ODD Fan")) /* same */
224 fct->ctrl.name = "optical-drive-fan";
221 225
222 /* Unrecognized fan, bail out */ 226 /* Unrecognized fan, bail out */
223 if (fct->ctrl.name == NULL) 227 if (fct->ctrl.name == NULL)
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index e7fd08adbbac..2b8fd68bc516 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -77,7 +77,7 @@ static int rionet_capable = 1;
77 * could be made into a hash table to save memory depending 77 * could be made into a hash table to save memory depending
78 * on system trade-offs. 78 * on system trade-offs.
79 */ 79 */
80static struct rio_dev *rionet_active[RIO_MAX_ROUTE_ENTRIES]; 80static struct rio_dev **rionet_active;
81 81
82#define is_rionet_capable(pef, src_ops, dst_ops) \ 82#define is_rionet_capable(pef, src_ops, dst_ops) \
83 ((pef & RIO_PEF_INB_MBOX) && \ 83 ((pef & RIO_PEF_INB_MBOX) && \
@@ -195,7 +195,8 @@ static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
195 } 195 }
196 196
197 if (eth->h_dest[0] & 0x01) { 197 if (eth->h_dest[0] & 0x01) {
198 for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++) 198 for (i = 0; i < RIO_MAX_ROUTE_ENTRIES(rnet->mport->sys_size);
199 i++)
199 if (rionet_active[i]) 200 if (rionet_active[i])
200 rionet_queue_tx_msg(skb, ndev, 201 rionet_queue_tx_msg(skb, ndev,
201 rionet_active[i]); 202 rionet_active[i]);
@@ -385,6 +386,8 @@ static void rionet_remove(struct rio_dev *rdev)
385 struct net_device *ndev = NULL; 386 struct net_device *ndev = NULL;
386 struct rionet_peer *peer, *tmp; 387 struct rionet_peer *peer, *tmp;
387 388
389 free_pages((unsigned long)rionet_active, rdev->net->hport->sys_size ?
390 __ilog2(sizeof(void *)) + 4 : 0);
388 unregister_netdev(ndev); 391 unregister_netdev(ndev);
389 kfree(ndev); 392 kfree(ndev);
390 393
@@ -443,6 +446,15 @@ static int rionet_setup_netdev(struct rio_mport *mport)
443 goto out; 446 goto out;
444 } 447 }
445 448
449 rionet_active = (struct rio_dev **)__get_free_pages(GFP_KERNEL,
450 mport->sys_size ? __ilog2(sizeof(void *)) + 4 : 0);
451 if (!rionet_active) {
452 rc = -ENOMEM;
453 goto out;
454 }
455 memset((void *)rionet_active, 0, sizeof(void *) *
456 RIO_MAX_ROUTE_ENTRIES(mport->sys_size));
457
446 /* Set up private area */ 458 /* Set up private area */
447 rnet = (struct rionet_private *)ndev->priv; 459 rnet = (struct rionet_private *)ndev->priv;
448 rnet->mport = mport; 460 rnet->mport = mport;
diff --git a/drivers/rapidio/Kconfig b/drivers/rapidio/Kconfig
index 4142115d298e..c32822ad84a4 100644
--- a/drivers/rapidio/Kconfig
+++ b/drivers/rapidio/Kconfig
@@ -1,14 +1,6 @@
1# 1#
2# RapidIO configuration 2# RapidIO configuration
3# 3#
4config RAPIDIO_8_BIT_TRANSPORT
5 bool "8-bit transport addressing"
6 depends on RAPIDIO
7 ---help---
8 By default, the kernel assumes a 16-bit addressed RapidIO
9 network. By selecting this option, the kernel will support
10 an 8-bit addressed network.
11
12config RAPIDIO_DISC_TIMEOUT 4config RAPIDIO_DISC_TIMEOUT
13 int "Discovery timeout duration (seconds)" 5 int "Discovery timeout duration (seconds)"
14 depends on RAPIDIO 6 depends on RAPIDIO
diff --git a/drivers/rapidio/rio-access.c b/drivers/rapidio/rio-access.c
index 8b56bbdd011e..a3824baca2e5 100644
--- a/drivers/rapidio/rio-access.c
+++ b/drivers/rapidio/rio-access.c
@@ -48,7 +48,7 @@ int __rio_local_read_config_##size \
48 u32 data = 0; \ 48 u32 data = 0; \
49 if (RIO_##size##_BAD) return RIO_BAD_SIZE; \ 49 if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
50 spin_lock_irqsave(&rio_config_lock, flags); \ 50 spin_lock_irqsave(&rio_config_lock, flags); \
51 res = mport->ops->lcread(mport->id, offset, len, &data); \ 51 res = mport->ops->lcread(mport, mport->id, offset, len, &data); \
52 *value = (type)data; \ 52 *value = (type)data; \
53 spin_unlock_irqrestore(&rio_config_lock, flags); \ 53 spin_unlock_irqrestore(&rio_config_lock, flags); \
54 return res; \ 54 return res; \
@@ -71,7 +71,7 @@ int __rio_local_write_config_##size \
71 unsigned long flags; \ 71 unsigned long flags; \
72 if (RIO_##size##_BAD) return RIO_BAD_SIZE; \ 72 if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
73 spin_lock_irqsave(&rio_config_lock, flags); \ 73 spin_lock_irqsave(&rio_config_lock, flags); \
74 res = mport->ops->lcwrite(mport->id, offset, len, value); \ 74 res = mport->ops->lcwrite(mport, mport->id, offset, len, value);\
75 spin_unlock_irqrestore(&rio_config_lock, flags); \ 75 spin_unlock_irqrestore(&rio_config_lock, flags); \
76 return res; \ 76 return res; \
77} 77}
@@ -108,7 +108,7 @@ int rio_mport_read_config_##size \
108 u32 data = 0; \ 108 u32 data = 0; \
109 if (RIO_##size##_BAD) return RIO_BAD_SIZE; \ 109 if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
110 spin_lock_irqsave(&rio_config_lock, flags); \ 110 spin_lock_irqsave(&rio_config_lock, flags); \
111 res = mport->ops->cread(mport->id, destid, hopcount, offset, len, &data); \ 111 res = mport->ops->cread(mport, mport->id, destid, hopcount, offset, len, &data); \
112 *value = (type)data; \ 112 *value = (type)data; \
113 spin_unlock_irqrestore(&rio_config_lock, flags); \ 113 spin_unlock_irqrestore(&rio_config_lock, flags); \
114 return res; \ 114 return res; \
@@ -131,7 +131,7 @@ int rio_mport_write_config_##size \
131 unsigned long flags; \ 131 unsigned long flags; \
132 if (RIO_##size##_BAD) return RIO_BAD_SIZE; \ 132 if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
133 spin_lock_irqsave(&rio_config_lock, flags); \ 133 spin_lock_irqsave(&rio_config_lock, flags); \
134 res = mport->ops->cwrite(mport->id, destid, hopcount, offset, len, value); \ 134 res = mport->ops->cwrite(mport, mport->id, destid, hopcount, offset, len, value); \
135 spin_unlock_irqrestore(&rio_config_lock, flags); \ 135 spin_unlock_irqrestore(&rio_config_lock, flags); \
136 return res; \ 136 return res; \
137} 137}
@@ -166,7 +166,7 @@ int rio_mport_send_doorbell(struct rio_mport *mport, u16 destid, u16 data)
166 unsigned long flags; 166 unsigned long flags;
167 167
168 spin_lock_irqsave(&rio_doorbell_lock, flags); 168 spin_lock_irqsave(&rio_doorbell_lock, flags);
169 res = mport->ops->dsend(mport->id, destid, data); 169 res = mport->ops->dsend(mport, mport->id, destid, data);
170 spin_unlock_irqrestore(&rio_doorbell_lock, flags); 170 spin_unlock_irqrestore(&rio_doorbell_lock, flags);
171 171
172 return res; 172 return res;
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 44420723a359..a926c896475e 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -73,7 +73,7 @@ static u16 rio_get_device_id(struct rio_mport *port, u16 destid, u8 hopcount)
73 73
74 rio_mport_read_config_32(port, destid, hopcount, RIO_DID_CSR, &result); 74 rio_mport_read_config_32(port, destid, hopcount, RIO_DID_CSR, &result);
75 75
76 return RIO_GET_DID(result); 76 return RIO_GET_DID(port->sys_size, result);
77} 77}
78 78
79/** 79/**
@@ -88,7 +88,7 @@ static u16 rio_get_device_id(struct rio_mport *port, u16 destid, u8 hopcount)
88static void rio_set_device_id(struct rio_mport *port, u16 destid, u8 hopcount, u16 did) 88static void rio_set_device_id(struct rio_mport *port, u16 destid, u8 hopcount, u16 did)
89{ 89{
90 rio_mport_write_config_32(port, destid, hopcount, RIO_DID_CSR, 90 rio_mport_write_config_32(port, destid, hopcount, RIO_DID_CSR,
91 RIO_SET_DID(did)); 91 RIO_SET_DID(port->sys_size, did));
92} 92}
93 93
94/** 94/**
@@ -100,7 +100,8 @@ static void rio_set_device_id(struct rio_mport *port, u16 destid, u8 hopcount, u
100 */ 100 */
101static void rio_local_set_device_id(struct rio_mport *port, u16 did) 101static void rio_local_set_device_id(struct rio_mport *port, u16 did)
102{ 102{
103 rio_local_write_config_32(port, RIO_DID_CSR, RIO_SET_DID(did)); 103 rio_local_write_config_32(port, RIO_DID_CSR, RIO_SET_DID(port->sys_size,
104 did));
104} 105}
105 106
106/** 107/**
@@ -350,8 +351,18 @@ static struct rio_dev *rio_setup_device(struct rio_net *net,
350 rswitch->switchid = next_switchid; 351 rswitch->switchid = next_switchid;
351 rswitch->hopcount = hopcount; 352 rswitch->hopcount = hopcount;
352 rswitch->destid = destid; 353 rswitch->destid = destid;
354 rswitch->route_table = kzalloc(sizeof(u8)*
355 RIO_MAX_ROUTE_ENTRIES(port->sys_size),
356 GFP_KERNEL);
357 if (!rswitch->route_table) {
358 kfree(rdev);
359 rdev = NULL;
360 kfree(rswitch);
361 goto out;
362 }
353 /* Initialize switch route table */ 363 /* Initialize switch route table */
354 for (rdid = 0; rdid < RIO_MAX_ROUTE_ENTRIES; rdid++) 364 for (rdid = 0; rdid < RIO_MAX_ROUTE_ENTRIES(port->sys_size);
365 rdid++)
355 rswitch->route_table[rdid] = RIO_INVALID_ROUTE; 366 rswitch->route_table[rdid] = RIO_INVALID_ROUTE;
356 rdev->rswitch = rswitch; 367 rdev->rswitch = rswitch;
357 sprintf(rio_name(rdev), "%02x:s:%04x", rdev->net->id, 368 sprintf(rio_name(rdev), "%02x:s:%04x", rdev->net->id,
@@ -480,7 +491,7 @@ static u16 rio_get_host_deviceid_lock(struct rio_mport *port, u8 hopcount)
480{ 491{
481 u32 result; 492 u32 result;
482 493
483 rio_mport_read_config_32(port, RIO_ANY_DESTID, hopcount, 494 rio_mport_read_config_32(port, RIO_ANY_DESTID(port->sys_size), hopcount,
484 RIO_HOST_DID_LOCK_CSR, &result); 495 RIO_HOST_DID_LOCK_CSR, &result);
485 496
486 return (u16) (result & 0xffff); 497 return (u16) (result & 0xffff);
@@ -571,14 +582,16 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
571 } 582 }
572 583
573 /* Attempt to acquire device lock */ 584 /* Attempt to acquire device lock */
574 rio_mport_write_config_32(port, RIO_ANY_DESTID, hopcount, 585 rio_mport_write_config_32(port, RIO_ANY_DESTID(port->sys_size),
586 hopcount,
575 RIO_HOST_DID_LOCK_CSR, port->host_deviceid); 587 RIO_HOST_DID_LOCK_CSR, port->host_deviceid);
576 while ((tmp = rio_get_host_deviceid_lock(port, hopcount)) 588 while ((tmp = rio_get_host_deviceid_lock(port, hopcount))
577 < port->host_deviceid) { 589 < port->host_deviceid) {
578 /* Delay a bit */ 590 /* Delay a bit */
579 mdelay(1); 591 mdelay(1);
580 /* Attempt to acquire device lock again */ 592 /* Attempt to acquire device lock again */
581 rio_mport_write_config_32(port, RIO_ANY_DESTID, hopcount, 593 rio_mport_write_config_32(port, RIO_ANY_DESTID(port->sys_size),
594 hopcount,
582 RIO_HOST_DID_LOCK_CSR, 595 RIO_HOST_DID_LOCK_CSR,
583 port->host_deviceid); 596 port->host_deviceid);
584 } 597 }
@@ -590,7 +603,9 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
590 } 603 }
591 604
592 /* Setup new RIO device */ 605 /* Setup new RIO device */
593 if ((rdev = rio_setup_device(net, port, RIO_ANY_DESTID, hopcount, 1))) { 606 rdev = rio_setup_device(net, port, RIO_ANY_DESTID(port->sys_size),
607 hopcount, 1);
608 if (rdev) {
594 /* Add device to the global and bus/net specific list. */ 609 /* Add device to the global and bus/net specific list. */
595 list_add_tail(&rdev->net_list, &net->devices); 610 list_add_tail(&rdev->net_list, &net->devices);
596 } else 611 } else
@@ -598,7 +613,8 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
598 613
599 if (rio_is_switch(rdev)) { 614 if (rio_is_switch(rdev)) {
600 next_switchid++; 615 next_switchid++;
601 sw_inport = rio_get_swpinfo_inport(port, RIO_ANY_DESTID, hopcount); 616 sw_inport = rio_get_swpinfo_inport(port,
617 RIO_ANY_DESTID(port->sys_size), hopcount);
602 rio_route_add_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE, 618 rio_route_add_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE,
603 port->host_deviceid, sw_inport); 619 port->host_deviceid, sw_inport);
604 rdev->rswitch->route_table[port->host_deviceid] = sw_inport; 620 rdev->rswitch->route_table[port->host_deviceid] = sw_inport;
@@ -612,7 +628,8 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
612 } 628 }
613 629
614 num_ports = 630 num_ports =
615 rio_get_swpinfo_tports(port, RIO_ANY_DESTID, hopcount); 631 rio_get_swpinfo_tports(port, RIO_ANY_DESTID(port->sys_size),
632 hopcount);
616 pr_debug( 633 pr_debug(
617 "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n", 634 "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n",
618 rio_name(rdev), rdev->vid, rdev->did, num_ports); 635 rio_name(rdev), rdev->vid, rdev->did, num_ports);
@@ -624,13 +641,15 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
624 cur_destid = next_destid; 641 cur_destid = next_destid;
625 642
626 if (rio_sport_is_active 643 if (rio_sport_is_active
627 (port, RIO_ANY_DESTID, hopcount, port_num)) { 644 (port, RIO_ANY_DESTID(port->sys_size), hopcount,
645 port_num)) {
628 pr_debug( 646 pr_debug(
629 "RIO: scanning device on port %d\n", 647 "RIO: scanning device on port %d\n",
630 port_num); 648 port_num);
631 rio_route_add_entry(port, rdev->rswitch, 649 rio_route_add_entry(port, rdev->rswitch,
632 RIO_GLOBAL_TABLE, 650 RIO_GLOBAL_TABLE,
633 RIO_ANY_DESTID, port_num); 651 RIO_ANY_DESTID(port->sys_size),
652 port_num);
634 653
635 if (rio_enum_peer(net, port, hopcount + 1) < 0) 654 if (rio_enum_peer(net, port, hopcount + 1) < 0)
636 return -1; 655 return -1;
@@ -735,7 +754,8 @@ rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid,
735 pr_debug( 754 pr_debug(
736 "RIO: scanning device on port %d\n", 755 "RIO: scanning device on port %d\n",
737 port_num); 756 port_num);
738 for (ndestid = 0; ndestid < RIO_ANY_DESTID; 757 for (ndestid = 0;
758 ndestid < RIO_ANY_DESTID(port->sys_size);
739 ndestid++) { 759 ndestid++) {
740 rio_route_get_entry(port, rdev->rswitch, 760 rio_route_get_entry(port, rdev->rswitch,
741 RIO_GLOBAL_TABLE, 761 RIO_GLOBAL_TABLE,
@@ -917,7 +937,9 @@ static void rio_build_route_tables(void)
917 937
918 list_for_each_entry(rdev, &rio_devices, global_list) 938 list_for_each_entry(rdev, &rio_devices, global_list)
919 if (rio_is_switch(rdev)) 939 if (rio_is_switch(rdev))
920 for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++) { 940 for (i = 0;
941 i < RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size);
942 i++) {
921 if (rio_route_get_entry 943 if (rio_route_get_entry
922 (rdev->net->hport, rdev->rswitch, RIO_GLOBAL_TABLE, 944 (rdev->net->hport, rdev->rswitch, RIO_GLOBAL_TABLE,
923 i, &sport) < 0) 945 i, &sport) < 0)
@@ -981,7 +1003,8 @@ int rio_disc_mport(struct rio_mport *mport)
981 del_timer_sync(&rio_enum_timer); 1003 del_timer_sync(&rio_enum_timer);
982 1004
983 pr_debug("done\n"); 1005 pr_debug("done\n");
984 if (rio_disc_peer(net, mport, RIO_ANY_DESTID, 0) < 0) { 1006 if (rio_disc_peer(net, mport, RIO_ANY_DESTID(mport->sys_size),
1007 0) < 0) {
985 printk(KERN_INFO 1008 printk(KERN_INFO
986 "RIO: master port %d device has failed discovery\n", 1009 "RIO: master port %d device has failed discovery\n",
987 mport->id); 1010 mport->id);
diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c
index 659e31164cf0..97a147f050d6 100644
--- a/drivers/rapidio/rio-sysfs.c
+++ b/drivers/rapidio/rio-sysfs.c
@@ -43,7 +43,8 @@ static ssize_t routes_show(struct device *dev, struct device_attribute *attr, ch
43 if (!rdev->rswitch) 43 if (!rdev->rswitch)
44 goto out; 44 goto out;
45 45
46 for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++) { 46 for (i = 0; i < RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size);
47 i++) {
47 if (rdev->rswitch->route_table[i] == RIO_INVALID_ROUTE) 48 if (rdev->rswitch->route_table[i] == RIO_INVALID_ROUTE)
48 continue; 49 continue;
49 str += 50 str +=
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index 80c5f1ba2e49..680661abbc4b 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -43,7 +43,7 @@ u16 rio_local_get_device_id(struct rio_mport *port)
43 43
44 rio_local_read_config_32(port, RIO_DID_CSR, &result); 44 rio_local_read_config_32(port, RIO_DID_CSR, &result);
45 45
46 return (RIO_GET_DID(result)); 46 return (RIO_GET_DID(port->sys_size, result));
47} 47}
48 48
49/** 49/**
diff --git a/drivers/rapidio/rio.h b/drivers/rapidio/rio.h
index 80e3f03b5041..7786d02581f2 100644
--- a/drivers/rapidio/rio.h
+++ b/drivers/rapidio/rio.h
@@ -51,10 +51,5 @@ extern struct rio_route_ops __end_rio_route_ops[];
51 DECLARE_RIO_ROUTE_SECTION(.rio_route_ops, \ 51 DECLARE_RIO_ROUTE_SECTION(.rio_route_ops, \
52 vid, did, add_hook, get_hook) 52 vid, did, add_hook, get_hook)
53 53
54#ifdef CONFIG_RAPIDIO_8_BIT_TRANSPORT 54#define RIO_GET_DID(size, x) (size ? (x & 0xffff) : ((x & 0x00ff0000) >> 16))
55#define RIO_GET_DID(x) ((x & 0x00ff0000) >> 16) 55#define RIO_SET_DID(size, x) (size ? (x & 0xffff) : ((x & 0x000000ff) << 16))
56#define RIO_SET_DID(x) ((x & 0x000000ff) << 16)
57#else
58#define RIO_GET_DID(x) (x & 0xffff)
59#define RIO_SET_DID(x) (x & 0xffff)
60#endif