~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/ppc/platforms/pmac_feature.c

Version: ~ [ linux-5.0-rc6 ] ~ [ linux-4.20.10 ] ~ [ linux-4.19.23 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.101 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.158 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.174 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.134 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.63 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.39.4 ] ~ [ linux-2.6.38.8 ] ~ [ linux-2.6.37.6 ] ~ [ linux-2.6.36.4 ] ~ [ linux-2.6.35.14 ] ~ [ linux-2.6.34.15 ] ~ [ linux-2.6.33.20 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *  arch/ppc/platforms/pmac_feature.c
  3  *
  4  *  Copyright (C) 1996-2001 Paul Mackerras (paulus@cs.anu.edu.au)
  5  *                          Ben. Herrenschmidt (benh@kernel.crashing.org)
  6  *
  7  *  This program is free software; you can redistribute it and/or
  8  *  modify it under the terms of the GNU General Public License
  9  *  as published by the Free Software Foundation; either version
 10  *  2 of the License, or (at your option) any later version.
 11  *
 12  *  TODO:
 13  *
 14  *   - Replace mdelay with some schedule loop if possible
 15  *   - Shorten some obfuscated delays on some routines (like modem
 16  *     power)
 17  *   - Refcount some clocks (see darwin)
 18  *   - Split split split...
 19  *
 20  */
 21 #include <linux/config.h>
 22 #include <linux/types.h>
 23 #include <linux/init.h>
 24 #include <linux/delay.h>
 25 #include <linux/kernel.h>
 26 #include <linux/sched.h>
 27 #include <linux/spinlock.h>
 28 #include <linux/adb.h>
 29 #include <linux/pmu.h>
 30 #include <linux/ioport.h>
 31 #include <linux/pci.h>
 32 #include <asm/sections.h>
 33 #include <asm/errno.h>
 34 #include <asm/ohare.h>
 35 #include <asm/heathrow.h>
 36 #include <asm/keylargo.h>
 37 #include <asm/uninorth.h>
 38 #include <asm/io.h>
 39 #include <asm/prom.h>
 40 #include <asm/machdep.h>
 41 #include <asm/pmac_feature.h>
 42 #include <asm/dbdma.h>
 43 #include <asm/pci-bridge.h>
 44 
 45 #undef DEBUG_FEATURE
 46 
 47 #ifdef DEBUG_FEATURE
 48 #define DBG(fmt,...) printk(KERN_DEBUG fmt)
 49 #else
 50 #define DBG(fmt,...)
 51 #endif
 52 
 53 /* Exported from arch/ppc/kernel/idle.c */
 54 extern int powersave_lowspeed;
 55 extern int powersave_nap;
 56 
 57 /*
 58  * We use a single global lock to protect accesses. Each driver has
 59  * to take care of its own locking
 60  */
 61 static spinlock_t feature_lock  __pmacdata = SPIN_LOCK_UNLOCKED;
 62 
 63 #define LOCK(flags)     spin_lock_irqsave(&feature_lock, flags);
 64 #define UNLOCK(flags)   spin_unlock_irqrestore(&feature_lock, flags);
 65 
 66 
 67 /*
 68  * Instance of some macio stuffs
 69  */
 70 struct macio_chip macio_chips[MAX_MACIO_CHIPS]  __pmacdata;
 71 
 72 struct macio_chip* __pmac
 73 macio_find(struct device_node* child, int type)
 74 {
 75         while(child) {
 76                 int     i;
 77 
 78                 for (i=0; i < MAX_MACIO_CHIPS && macio_chips[i].of_node; i++)
 79                         if (child == macio_chips[i].of_node &&
 80                             (!type || macio_chips[i].type == type))
 81                                 return &macio_chips[i];
 82                 child = child->parent;
 83         }
 84         return NULL;
 85 }
 86 
 87 static const char* macio_names[] __pmacdata =
 88 {
 89         "Unknown",
 90         "Grand Central",
 91         "OHare",
 92         "OHareII",
 93         "Heathrow",
 94         "Gatwick",
 95         "Paddington",
 96         "Keylargo",
 97         "Pangea",
 98         "Intrepid"
 99 };
100 
101 
102 
103 /*
104  * Uninorth reg. access. Note that Uni-N regs are big endian
105  */
106 
107 #define UN_REG(r)       (uninorth_base + ((r) >> 2))
108 #define UN_IN(r)        (in_be32(UN_REG(r)))
109 #define UN_OUT(r,v)     (out_be32(UN_REG(r), (v)))
110 #define UN_BIS(r,v)     (UN_OUT((r), UN_IN(r) | (v)))
111 #define UN_BIC(r,v)     (UN_OUT((r), UN_IN(r) & ~(v)))
112 
113 static struct device_node* uninorth_node __pmacdata;
114 static u32* uninorth_base __pmacdata;
115 static u32 uninorth_rev __pmacdata;
116 
117 
118 /*
119  * For each motherboard family, we have a table of functions pointers
120  * that handle the various features.
121  */
122 
123 typedef int (*feature_call)(struct device_node* node, int param, int value);
124 
125 struct feature_table_entry {
126         unsigned int    selector;
127         feature_call    function;
128 };
129 
130 struct pmac_mb_def
131 {
132         const char*                     model_string;
133         const char*                     model_name;
134         int                             model_id;
135         struct feature_table_entry*     features;
136         unsigned long                   board_flags;
137 };
138 static struct pmac_mb_def pmac_mb __pmacdata;
139 
140 /*
141  * Here are the chip specific feature functions
142  */
143 
144 static inline int __pmac
145 simple_feature_tweak(struct device_node* node, int type, int reg, u32 mask, int value)
146 {
147         struct macio_chip*      macio;
148         unsigned long           flags;
149 
150         macio = macio_find(node, type);
151         if (!macio)
152                 return -ENODEV;
153         LOCK(flags);
154         if (value)
155                 MACIO_BIS(reg, mask);
156         else
157                 MACIO_BIC(reg, mask);
158         (void)MACIO_IN32(reg);
159         UNLOCK(flags);
160 
161         return 0;
162 }
163 
164 static int __pmac
165 ohare_htw_scc_enable(struct device_node* node, int param, int value)
166 {
167         struct macio_chip*      macio;
168         unsigned long           chan_mask;
169         unsigned long           fcr;
170         unsigned long           flags;
171         int                     htw, trans;
172         unsigned long           rmask;
173 
174         macio = macio_find(node, 0);
175         if (!macio)
176                 return -ENODEV;
177         if (!strcmp(node->name, "ch-a"))
178                 chan_mask = MACIO_FLAG_SCCA_ON;
179         else if (!strcmp(node->name, "ch-b"))
180                 chan_mask = MACIO_FLAG_SCCB_ON;
181         else
182                 return -ENODEV;
183 
184         htw = (macio->type == macio_heathrow || macio->type == macio_paddington
185                 || macio->type == macio_gatwick);
186         /* On these machines, the HRW_SCC_TRANS_EN_N bit mustn't be touched */
187         trans = (pmac_mb.model_id != PMAC_TYPE_YOSEMITE &&
188                  pmac_mb.model_id != PMAC_TYPE_YIKES);
189         if (value) {
190 #ifdef CONFIG_ADB_PMU
191                 if ((param & 0xfff) == PMAC_SCC_IRDA)
192                         pmu_enable_irled(1);
193 #endif /* CONFIG_ADB_PMU */
194                 LOCK(flags);
195                 fcr = MACIO_IN32(OHARE_FCR);
196                 /* Check if scc cell need enabling */
197                 if (!(fcr & OH_SCC_ENABLE)) {
198                         fcr |= OH_SCC_ENABLE;
199                         if (htw) {
200                                 /* Side effect: this will also power up the
201                                  * modem, but it's too messy to figure out on which
202                                  * ports this controls the tranceiver and on which
203                                  * it controls the modem
204                                  */
205                                 if (trans)
206                                         fcr &= ~HRW_SCC_TRANS_EN_N;
207                                 MACIO_OUT32(OHARE_FCR, fcr);
208                                 fcr |= (rmask = HRW_RESET_SCC);
209                                 MACIO_OUT32(OHARE_FCR, fcr);
210                         } else {
211                                 fcr |= (rmask = OH_SCC_RESET);
212                                 MACIO_OUT32(OHARE_FCR, fcr);
213                         }
214                         UNLOCK(flags);
215                         (void)MACIO_IN32(OHARE_FCR);
216                         mdelay(15);
217                         LOCK(flags);
218                         fcr &= ~rmask;
219                         MACIO_OUT32(OHARE_FCR, fcr);
220                 }
221                 if (chan_mask & MACIO_FLAG_SCCA_ON)
222                         fcr |= OH_SCCA_IO;
223                 if (chan_mask & MACIO_FLAG_SCCB_ON)
224                         fcr |= OH_SCCB_IO;
225                 MACIO_OUT32(OHARE_FCR, fcr);
226                 macio->flags |= chan_mask;
227                 UNLOCK(flags);
228                 if (param & PMAC_SCC_FLAG_XMON)
229                         macio->flags |= MACIO_FLAG_SCC_LOCKED;
230         } else {
231                 if (macio->flags & MACIO_FLAG_SCC_LOCKED)
232                         return -EPERM;
233                 LOCK(flags);
234                 fcr = MACIO_IN32(OHARE_FCR);
235                 if (chan_mask & MACIO_FLAG_SCCA_ON)
236                         fcr &= ~OH_SCCA_IO;
237                 if (chan_mask & MACIO_FLAG_SCCB_ON)
238                         fcr &= ~OH_SCCB_IO;
239                 MACIO_OUT32(OHARE_FCR, fcr);
240                 if ((fcr & (OH_SCCA_IO | OH_SCCB_IO)) == 0) {
241                         fcr &= ~OH_SCC_ENABLE;
242                         if (htw && trans)
243                                 fcr |= HRW_SCC_TRANS_EN_N;
244                         MACIO_OUT32(OHARE_FCR, fcr);
245                 }
246                 macio->flags &= ~(chan_mask);
247                 UNLOCK(flags);
248                 mdelay(10);
249 #ifdef CONFIG_ADB_PMU
250                 if ((param & 0xfff) == PMAC_SCC_IRDA)
251                         pmu_enable_irled(0);
252 #endif /* CONFIG_ADB_PMU */
253         }
254         return 0;
255 }
256 
257 static int __pmac
258 ohare_floppy_enable(struct device_node* node, int param, int value)
259 {
260         return simple_feature_tweak(node, macio_ohare,
261                 OHARE_FCR, OH_FLOPPY_ENABLE, value);
262 }
263 
264 static int __pmac
265 ohare_mesh_enable(struct device_node* node, int param, int value)
266 {
267         return simple_feature_tweak(node, macio_ohare,
268                 OHARE_FCR, OH_MESH_ENABLE, value);
269 }
270 
271 static int __pmac
272 ohare_ide_enable(struct device_node* node, int param, int value)
273 {
274         switch(param) {
275             case 0:
276                 /* For some reason, setting the bit in set_initial_features()
277                  * doesn't stick. I'm still investigating... --BenH.
278                  */
279                 if (value)
280                         simple_feature_tweak(node, macio_ohare,
281                                 OHARE_FCR, OH_IOBUS_ENABLE, 1);
282                 return simple_feature_tweak(node, macio_ohare,
283                         OHARE_FCR, OH_IDE0_ENABLE, value);
284             case 1:
285                 return simple_feature_tweak(node, macio_ohare,
286                         OHARE_FCR, OH_BAY_IDE_ENABLE, value);
287             default:
288                 return -ENODEV;
289         }
290 }
291 
292 static int __pmac
293 ohare_ide_reset(struct device_node* node, int param, int value)
294 {
295         switch(param) {
296             case 0:
297                 return simple_feature_tweak(node, macio_ohare,
298                         OHARE_FCR, OH_IDE0_RESET_N, !value);
299             case 1:
300                 return simple_feature_tweak(node, macio_ohare,
301                         OHARE_FCR, OH_IDE1_RESET_N, !value);
302             default:
303                 return -ENODEV;
304         }
305 }
306 
307 static int __pmac
308 ohare_sleep_state(struct device_node* node, int param, int value)
309 {
310         struct macio_chip*      macio = &macio_chips[0];
311 
312         if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0)
313                 return -EPERM;
314         if (value == 1) {
315                 MACIO_BIC(OHARE_FCR, OH_IOBUS_ENABLE);
316         } else if (value == 0) {
317                 MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE);
318         }
319 
320         return 0;
321 }
322 
323 static int __pmac
324 heathrow_modem_enable(struct device_node* node, int param, int value)
325 {
326         struct macio_chip*      macio;
327         u8                      gpio;
328         unsigned long           flags;
329 
330         macio = macio_find(node, macio_unknown);
331         if (!macio)
332                 return -ENODEV;
333         gpio = MACIO_IN8(HRW_GPIO_MODEM_RESET) & ~1;
334         if (!value) {
335                 LOCK(flags);
336                 MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio);
337                 UNLOCK(flags);
338                 (void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
339                 mdelay(250);
340         }
341         if (pmac_mb.model_id != PMAC_TYPE_YOSEMITE &&
342             pmac_mb.model_id != PMAC_TYPE_YIKES) {
343                 LOCK(flags);
344                 if (value)
345                         MACIO_BIC(HEATHROW_FCR, HRW_SCC_TRANS_EN_N);
346                 else
347                         MACIO_BIS(HEATHROW_FCR, HRW_SCC_TRANS_EN_N);
348                 UNLOCK(flags);
349                 (void)MACIO_IN32(HEATHROW_FCR);
350                 mdelay(250);
351         }
352         if (value) {
353                 LOCK(flags);
354                 MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio | 1);
355                 (void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
356                 UNLOCK(flags); mdelay(250); LOCK(flags);
357                 MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio);
358                 (void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
359                 UNLOCK(flags); mdelay(250); LOCK(flags);
360                 MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio | 1);
361                 (void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
362                 UNLOCK(flags); mdelay(250);
363         }
364         return 0;
365 }
366 
367 static int __pmac
368 heathrow_floppy_enable(struct device_node* node, int param, int value)
369 {
370         return simple_feature_tweak(node, macio_unknown,
371                 HEATHROW_FCR,
372                 HRW_SWIM_ENABLE|HRW_BAY_FLOPPY_ENABLE,
373                 value);
374 }
375 
376 static int __pmac
377 heathrow_mesh_enable(struct device_node* node, int param, int value)
378 {
379         struct macio_chip*      macio;
380         unsigned long           flags;
381 
382         macio = macio_find(node, macio_unknown);
383         if (!macio)
384                 return -ENODEV;
385         LOCK(flags);
386         /* Set clear mesh cell enable */
387         if (value)
388                 MACIO_BIS(HEATHROW_FCR, HRW_MESH_ENABLE);
389         else
390                 MACIO_BIC(HEATHROW_FCR, HRW_MESH_ENABLE);
391         (void)MACIO_IN32(HEATHROW_FCR);
392         udelay(10);
393         /* Set/Clear termination power (todo: test ! the bit value
394          * used by Darwin doesn't seem to match what we used so
395          * far. If you experience problems, turn #if 1 into #if 0
396          * and tell me about it --BenH.
397          */
398 #if 1
399         if (value)
400                 MACIO_BIC(HEATHROW_MBCR, 0x00000004);
401         else
402                 MACIO_BIS(HEATHROW_MBCR, 0x00000004);
403 #else
404         if (value)
405                 MACIO_BIC(HEATHROW_MBCR, 0x00040000);
406         else
407                 MACIO_BIS(HEATHROW_MBCR, 0x00040000);
408 #endif
409         (void)MACIO_IN32(HEATHROW_MBCR);
410         udelay(10);
411         UNLOCK(flags);
412 
413         return 0;
414 }
415 
416 static int __pmac
417 heathrow_ide_enable(struct device_node* node, int param, int value)
418 {
419         switch(param) {
420             case 0:
421                 return simple_feature_tweak(node, macio_unknown,
422                         HEATHROW_FCR, HRW_IDE0_ENABLE, value);
423             case 1:
424                 return simple_feature_tweak(node, macio_unknown,
425                         HEATHROW_FCR, HRW_BAY_IDE_ENABLE, value);
426             default:
427                 return -ENODEV;
428         }
429 }
430 
431 static int __pmac
432 heathrow_ide_reset(struct device_node* node, int param, int value)
433 {
434         switch(param) {
435             case 0:
436                 return simple_feature_tweak(node, macio_unknown,
437                         HEATHROW_FCR, HRW_IDE0_RESET_N, !value);
438             case 1:
439                 return simple_feature_tweak(node, macio_unknown,
440                         HEATHROW_FCR, HRW_IDE1_RESET_N, !value);
441             default:
442                 return -ENODEV;
443         }
444 }
445 
446 static int __pmac
447 heathrow_bmac_enable(struct device_node* node, int param, int value)
448 {
449         struct macio_chip*      macio;
450         unsigned long           flags;
451 
452         macio = macio_find(node, 0);
453         if (!macio)
454                 return -ENODEV;
455         if (value) {
456                 LOCK(flags);
457                 MACIO_BIS(HEATHROW_FCR, HRW_BMAC_IO_ENABLE);
458                 MACIO_BIS(HEATHROW_FCR, HRW_BMAC_RESET);
459                 UNLOCK(flags);
460                 (void)MACIO_IN32(HEATHROW_FCR);
461                 mdelay(10);
462                 LOCK(flags);
463                 MACIO_BIC(HEATHROW_FCR, HRW_BMAC_RESET);
464                 UNLOCK(flags);
465                 (void)MACIO_IN32(HEATHROW_FCR);
466                 mdelay(10);
467         } else {
468                 LOCK(flags);
469                 MACIO_BIC(HEATHROW_FCR, HRW_BMAC_IO_ENABLE);
470                 UNLOCK(flags);
471         }
472         return 0;
473 }
474 
475 static int __pmac
476 heathrow_sound_enable(struct device_node* node, int param, int value)
477 {
478         struct macio_chip*      macio;
479         unsigned long           flags;
480 
481         /* B&W G3 and Yikes don't support that properly (the
482          * sound appear to never come back after beeing shut down).
483          */
484         if (pmac_mb.model_id == PMAC_TYPE_YOSEMITE ||
485             pmac_mb.model_id == PMAC_TYPE_YIKES)
486                 return 0;
487 
488         macio = macio_find(node, 0);
489         if (!macio)
490                 return -ENODEV;
491         if (value) {
492                 LOCK(flags);
493                 MACIO_BIS(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
494                 MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N);
495                 UNLOCK(flags);
496                 (void)MACIO_IN32(HEATHROW_FCR);
497         } else {
498                 LOCK(flags);
499                 MACIO_BIS(HEATHROW_FCR, HRW_SOUND_POWER_N);
500                 MACIO_BIC(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
501                 UNLOCK(flags);
502         }
503         return 0;
504 }
505 
506 static u32 save_fcr[6] __pmacdata;
507 static u32 save_mbcr __pmacdata;
508 static u32 save_gpio_levels[2] __pmacdata;
509 static u8 save_gpio_extint[KEYLARGO_GPIO_EXTINT_CNT] __pmacdata;
510 static u8 save_gpio_normal[KEYLARGO_GPIO_CNT] __pmacdata;
511 static u32 save_unin_clock_ctl __pmacdata;
512 static struct dbdma_regs save_dbdma[13] __pmacdata;
513 static struct dbdma_regs save_alt_dbdma[13] __pmacdata;
514 
515 static void __pmac
516 dbdma_save(struct macio_chip* macio, struct dbdma_regs* save)
517 {
518         int i;
519 
520         /* Save state & config of DBDMA channels */
521         for (i=0; i<13; i++) {
522                 volatile struct dbdma_regs* chan = (volatile struct dbdma_regs*)
523                         (macio->base + ((0x8000+i*0x100)>>2));
524                 save[i].cmdptr_hi = in_le32(&chan->cmdptr_hi);
525                 save[i].cmdptr = in_le32(&chan->cmdptr);
526                 save[i].intr_sel = in_le32(&chan->intr_sel);
527                 save[i].br_sel = in_le32(&chan->br_sel);
528                 save[i].wait_sel = in_le32(&chan->wait_sel);
529         }
530 }
531 
532 static void __pmac
533 dbdma_restore(struct macio_chip* macio, struct dbdma_regs* save)
534 {
535         int i;
536 
537         /* Save state & config of DBDMA channels */
538         for (i=0; i<13; i++) {
539                 volatile struct dbdma_regs* chan = (volatile struct dbdma_regs*)
540                         (macio->base + ((0x8000+i*0x100)>>2));
541                 out_le32(&chan->control, (ACTIVE|DEAD|WAKE|FLUSH|PAUSE|RUN)<<16);
542                 while (in_le32(&chan->status) & ACTIVE)
543                         mb();
544                 out_le32(&chan->cmdptr_hi, save[i].cmdptr_hi);
545                 out_le32(&chan->cmdptr, save[i].cmdptr);
546                 out_le32(&chan->intr_sel, save[i].intr_sel);
547                 out_le32(&chan->br_sel, save[i].br_sel);
548                 out_le32(&chan->wait_sel, save[i].wait_sel);
549         }
550 }
551 
552 static void __pmac
553 heathrow_sleep(struct macio_chip* macio, int secondary)
554 {
555         if (secondary) {
556                 dbdma_save(macio, save_alt_dbdma);
557                 save_fcr[2] = MACIO_IN32(0x38);
558                 save_fcr[3] = MACIO_IN32(0x3c);
559         } else {
560                 dbdma_save(macio, save_dbdma);
561                 save_fcr[0] = MACIO_IN32(0x38);
562                 save_fcr[1] = MACIO_IN32(0x3c);
563                 save_mbcr = MACIO_IN32(0x34);
564                 /* Make sure sound is shut down */
565                 MACIO_BIS(HEATHROW_FCR, HRW_SOUND_POWER_N);
566                 MACIO_BIC(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
567                 /* This seems to be necessary as well or the fan
568                  * keeps coming up and battery drains fast */
569                 MACIO_BIC(HEATHROW_FCR, HRW_IOBUS_ENABLE);
570                 MACIO_BIC(HEATHROW_FCR, HRW_IDE0_RESET_N);
571                 /* Make sure eth is down even if module or sleep
572                  * won't work properly */
573                 MACIO_BIC(HEATHROW_FCR, HRW_BMAC_IO_ENABLE | HRW_BMAC_RESET);
574         }
575         /* Make sure modem is shut down */
576         MACIO_OUT8(HRW_GPIO_MODEM_RESET,
577                 MACIO_IN8(HRW_GPIO_MODEM_RESET) & ~1);
578         MACIO_BIS(HEATHROW_FCR, HRW_SCC_TRANS_EN_N);
579         MACIO_BIC(HEATHROW_FCR, OH_SCCA_IO|OH_SCCB_IO|HRW_SCC_ENABLE);
580 
581         /* Let things settle */
582         (void)MACIO_IN32(HEATHROW_FCR);
583         mdelay(1);
584 }
585 
586 static void __pmac
587 heathrow_wakeup(struct macio_chip* macio, int secondary)
588 {
589         if (secondary) {
590                 MACIO_OUT32(0x38, save_fcr[2]);
591                 (void)MACIO_IN32(0x38);
592                 mdelay(1);
593                 MACIO_OUT32(0x3c, save_fcr[3]);
594                 (void)MACIO_IN32(0x38);
595                 mdelay(10);
596                 dbdma_restore(macio, save_alt_dbdma);
597         } else {
598                 MACIO_OUT32(0x38, save_fcr[0] | HRW_IOBUS_ENABLE);
599                 (void)MACIO_IN32(0x38);
600                 mdelay(1);
601                 MACIO_OUT32(0x3c, save_fcr[1]);
602                 (void)MACIO_IN32(0x38);
603                 mdelay(1);
604                 MACIO_OUT32(0x34, save_mbcr);
605                 (void)MACIO_IN32(0x38);
606                 mdelay(10);
607                 dbdma_restore(macio, save_dbdma);
608         }
609 }
610 
611 static int __pmac
612 heathrow_sleep_state(struct device_node* node, int param, int value)
613 {
614         if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0)
615                 return -EPERM;
616         if (value == 1) {
617                 if (macio_chips[1].type == macio_gatwick)
618                         heathrow_sleep(&macio_chips[0], 1);
619                 heathrow_sleep(&macio_chips[0], 0);
620         } else if (value == 0) {
621                 heathrow_wakeup(&macio_chips[0], 0);
622                 if (macio_chips[1].type == macio_gatwick)
623                         heathrow_wakeup(&macio_chips[0], 1);
624         }
625         return 0;
626 }
627 
628 static int __pmac
629 core99_scc_enable(struct device_node* node, int param, int value)
630 {
631         struct macio_chip*      macio;
632         unsigned long           flags;
633         unsigned long           chan_mask;
634         u32                     fcr;
635 
636         macio = macio_find(node, 0);
637         if (!macio)
638                 return -ENODEV;
639         if (!strcmp(node->name, "ch-a"))
640                 chan_mask = MACIO_FLAG_SCCA_ON;
641         else if (!strcmp(node->name, "ch-b"))
642                 chan_mask = MACIO_FLAG_SCCB_ON;
643         else
644                 return -ENODEV;
645 
646         if (value) {
647                 int need_reset_scc = 0;
648                 int need_reset_irda = 0;
649 
650                 LOCK(flags);
651                 fcr = MACIO_IN32(KEYLARGO_FCR0);
652                 /* Check if scc cell need enabling */
653                 if (!(fcr & KL0_SCC_CELL_ENABLE)) {
654                         fcr |= KL0_SCC_CELL_ENABLE;
655                         need_reset_scc = 1;
656                 }
657                 if (chan_mask & MACIO_FLAG_SCCA_ON) {
658                         fcr |= KL0_SCCA_ENABLE;
659                         /* Don't enable line drivers for I2S modem */
660                         if ((param & 0xfff) == PMAC_SCC_I2S1)
661                                 fcr &= ~KL0_SCC_A_INTF_ENABLE;
662                         else
663                                 fcr |= KL0_SCC_A_INTF_ENABLE;
664                 }
665                 if (chan_mask & MACIO_FLAG_SCCB_ON) {
666                         fcr |= KL0_SCCB_ENABLE;
667                         /* Perform irda specific inits */
668                         if ((param & 0xfff) == PMAC_SCC_IRDA) {
669                                 fcr &= ~KL0_SCC_B_INTF_ENABLE;
670                                 fcr |= KL0_IRDA_ENABLE;
671                                 fcr |= KL0_IRDA_CLK32_ENABLE | KL0_IRDA_CLK19_ENABLE;
672                                 fcr |= KL0_IRDA_SOURCE1_SEL;
673                                 fcr &= ~(KL0_IRDA_FAST_CONNECT|KL0_IRDA_DEFAULT1|KL0_IRDA_DEFAULT0);
674                                 fcr &= ~(KL0_IRDA_SOURCE2_SEL|KL0_IRDA_HIGH_BAND);
675                                 need_reset_irda = 1;
676                         } else
677                                 fcr |= KL0_SCC_B_INTF_ENABLE;
678                 }
679                 MACIO_OUT32(KEYLARGO_FCR0, fcr);
680                 macio->flags |= chan_mask;
681                 if (need_reset_scc)  {
682                         MACIO_BIS(KEYLARGO_FCR0, KL0_SCC_RESET);
683                         (void)MACIO_IN32(KEYLARGO_FCR0);
684                         UNLOCK(flags);
685                         mdelay(15);
686                         LOCK(flags);
687                         MACIO_BIC(KEYLARGO_FCR0, KL0_SCC_RESET);
688                 }
689                 if (need_reset_irda)  {
690                         MACIO_BIS(KEYLARGO_FCR0, KL0_IRDA_RESET);
691                         (void)MACIO_IN32(KEYLARGO_FCR0);
692                         UNLOCK(flags);
693                         mdelay(15);
694                         LOCK(flags);
695                         MACIO_BIC(KEYLARGO_FCR0, KL0_IRDA_RESET);
696                 }
697                 UNLOCK(flags);
698                 if (param & PMAC_SCC_FLAG_XMON)
699                         macio->flags |= MACIO_FLAG_SCC_LOCKED;
700         } else {
701                 if (macio->flags & MACIO_FLAG_SCC_LOCKED)
702                         return -EPERM;
703                 LOCK(flags);
704                 fcr = MACIO_IN32(KEYLARGO_FCR0);
705                 if (chan_mask & MACIO_FLAG_SCCA_ON)
706                         fcr &= ~KL0_SCCA_ENABLE;
707                 if (chan_mask & MACIO_FLAG_SCCB_ON) {
708                         fcr &= ~KL0_SCCB_ENABLE;
709                         /* Perform irda specific clears */
710                         if ((param & 0xfff) == PMAC_SCC_IRDA) {
711                                 fcr &= ~KL0_IRDA_ENABLE;
712                                 fcr &= ~(KL0_IRDA_CLK32_ENABLE | KL0_IRDA_CLK19_ENABLE);
713                                 fcr &= ~(KL0_IRDA_FAST_CONNECT|KL0_IRDA_DEFAULT1|KL0_IRDA_DEFAULT0);
714                                 fcr &= ~(KL0_IRDA_SOURCE1_SEL|KL0_IRDA_SOURCE2_SEL|KL0_IRDA_HIGH_BAND);
715                         }
716                 }
717                 MACIO_OUT32(KEYLARGO_FCR0, fcr);
718                 if ((fcr & (KL0_SCCA_ENABLE | KL0_SCCB_ENABLE)) == 0) {
719                         fcr &= ~KL0_SCC_CELL_ENABLE;
720                         MACIO_OUT32(KEYLARGO_FCR0, fcr);
721                 }
722                 macio->flags &= ~(chan_mask);
723                 UNLOCK(flags);
724                 mdelay(10);
725         }
726         return 0;
727 }
728 
729 static int __pmac
730 core99_modem_enable(struct device_node* node, int param, int value)
731 {
732         struct macio_chip*      macio;
733         u8                      gpio;
734         unsigned long           flags;
735 
736         /* Hack for internal USB modem */
737         if (node == NULL) {
738                 if (macio_chips[0].type != macio_keylargo)
739                         return -ENODEV;
740                 node = macio_chips[0].of_node;
741         }
742         macio = macio_find(node, 0);
743         if (!macio)
744                 return -ENODEV;
745         gpio = MACIO_IN8(KL_GPIO_MODEM_RESET);
746         gpio |= KEYLARGO_GPIO_OUTPUT_ENABLE;
747         gpio &= ~KEYLARGO_GPIO_OUTOUT_DATA;
748 
749         if (!value) {
750                 LOCK(flags);
751                 MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
752                 UNLOCK(flags);
753                 (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
754                 mdelay(250);
755         }
756         LOCK(flags);
757         if (value) {
758                 MACIO_BIC(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
759                 UNLOCK(flags);
760                 (void)MACIO_IN32(KEYLARGO_FCR2);
761                 mdelay(250);
762         } else {
763                 MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
764                 UNLOCK(flags);
765         }
766         if (value) {
767                 LOCK(flags);
768                 MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
769                 (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
770                 UNLOCK(flags); mdelay(250); LOCK(flags);
771                 MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
772                 (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
773                 UNLOCK(flags); mdelay(250); LOCK(flags);
774                 MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
775                 (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
776                 UNLOCK(flags); mdelay(250);
777         }
778         return 0;
779 }
780 
781 static int __pmac
782 pangea_modem_enable(struct device_node* node, int param, int value)
783 {
784         struct macio_chip*      macio;
785         u8                      gpio;
786         unsigned long           flags;
787 
788         /* Hack for internal USB modem */
789         if (node == NULL) {
790                 if (macio_chips[0].type != macio_pangea &&
791                     macio_chips[0].type != macio_intrepid)
792                         return -ENODEV;
793                 node = macio_chips[0].of_node;
794         }
795         macio = macio_find(node, 0);
796         if (!macio)
797                 return -ENODEV;
798         gpio = MACIO_IN8(KL_GPIO_MODEM_RESET);
799         gpio |= KEYLARGO_GPIO_OUTPUT_ENABLE;
800         gpio &= ~KEYLARGO_GPIO_OUTOUT_DATA;
801 
802         if (!value) {
803                 LOCK(flags);
804                 MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
805                 UNLOCK(flags);
806                 (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
807                 mdelay(250);
808         }
809         LOCK(flags);
810         if (value) {
811                 MACIO_OUT8(KL_GPIO_MODEM_POWER,
812                         KEYLARGO_GPIO_OUTPUT_ENABLE);
813                 UNLOCK(flags);
814                 (void)MACIO_IN32(KEYLARGO_FCR2);
815                 mdelay(250);
816         } else {
817                 MACIO_OUT8(KL_GPIO_MODEM_POWER,
818                         KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA);
819                 UNLOCK(flags);
820         }
821         if (value) {
822                 LOCK(flags);
823                 MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
824                 (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
825                 UNLOCK(flags); mdelay(250); LOCK(flags);
826                 MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
827                 (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
828                 UNLOCK(flags); mdelay(250); LOCK(flags);
829                 MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
830                 (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
831                 UNLOCK(flags); mdelay(250);
832         }
833         return 0;
834 }
835 
836 static int __pmac
837 core99_ata100_enable(struct device_node* node, int value)
838 {
839         unsigned long flags;
840         struct pci_dev *pdev = NULL;
841         u8 pbus, pid;
842 
843         if (uninorth_rev < 0x24)
844                 return -ENODEV;
845 
846         LOCK(flags);
847         if (value)
848                 UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_ATA100);
849         else
850                 UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_ATA100);
851         (void)UN_IN(UNI_N_CLOCK_CNTL);
852         UNLOCK(flags);
853         udelay(20);
854 
855         if (value) {
856                 if (pci_device_from_OF_node(node, &pbus, &pid) == 0)
857                         pdev = pci_find_slot(pbus, pid);
858                 if (pdev == NULL)
859                         return 0;
860                 pci_enable_device(pdev);
861                 pci_set_master(pdev);
862         }
863         return 0;
864 }
865 
866 static int __pmac
867 core99_ide_enable(struct device_node* node, int param, int value)
868 {
869         /* Bus ID 0 to 2 are KeyLargo based IDE, busID 3 is U2
870          * based ata-100
871          */
872         switch(param) {
873             case 0:
874                 return simple_feature_tweak(node, macio_unknown,
875                         KEYLARGO_FCR1, KL1_EIDE0_ENABLE, value);
876             case 1:
877                 return simple_feature_tweak(node, macio_unknown,
878                         KEYLARGO_FCR1, KL1_EIDE1_ENABLE, value);
879             case 2:
880                 return simple_feature_tweak(node, macio_unknown,
881                         KEYLARGO_FCR1, KL1_UIDE_ENABLE, value);
882             case 3:
883                 return core99_ata100_enable(node, value);
884             default:
885                 return -ENODEV;
886         }
887 }
888 
889 static int __pmac
890 core99_ide_reset(struct device_node* node, int param, int value)
891 {
892         switch(param) {
893             case 0:
894                 return simple_feature_tweak(node, macio_unknown,
895                         KEYLARGO_FCR1, KL1_EIDE0_RESET_N, !value);
896             case 1:
897                 return simple_feature_tweak(node, macio_unknown,
898                         KEYLARGO_FCR1, KL1_EIDE1_RESET_N, !value);
899             case 2:
900                 return simple_feature_tweak(node, macio_unknown,
901                         KEYLARGO_FCR1, KL1_UIDE_RESET_N, !value);
902             default:
903                 return -ENODEV;
904         }
905 }
906 
907 static int __pmac
908 core99_gmac_enable(struct device_node* node, int param, int value)
909 {
910         unsigned long flags;
911 
912         LOCK(flags);
913         if (value)
914                 UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC);
915         else
916                 UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC);
917         (void)UN_IN(UNI_N_CLOCK_CNTL);
918         UNLOCK(flags);
919         udelay(20);
920 
921         return 0;
922 }
923 
924 static int __pmac
925 core99_gmac_phy_reset(struct device_node* node, int param, int value)
926 {
927         unsigned long flags;
928         struct macio_chip* macio;
929 
930         macio = &macio_chips[0];
931         if (macio->type != macio_keylargo && macio->type != macio_pangea &&
932             macio->type != macio_intrepid)
933                 return -ENODEV;
934 
935         LOCK(flags);
936         MACIO_OUT8(KL_GPIO_ETH_PHY_RESET, KEYLARGO_GPIO_OUTPUT_ENABLE);
937         (void)MACIO_IN8(KL_GPIO_ETH_PHY_RESET);
938         UNLOCK(flags);
939         mdelay(10);
940         LOCK(flags);
941         MACIO_OUT8(KL_GPIO_ETH_PHY_RESET, KEYLARGO_GPIO_OUTPUT_ENABLE
942                 | KEYLARGO_GPIO_OUTOUT_DATA);
943         UNLOCK(flags);
944         mdelay(10);
945 
946         return 0;
947 }
948 
949 static int __pmac
950 core99_sound_chip_enable(struct device_node* node, int param, int value)
951 {
952         struct macio_chip*      macio;
953         unsigned long           flags;
954 
955         macio = macio_find(node, 0);
956         if (!macio)
957                 return -ENODEV;
958 
959         /* Do a better probe code, screamer G4 desktops &
960          * iMacs can do that too, add a recalibrate  in
961          * the driver as well
962          */
963         if (pmac_mb.model_id == PMAC_TYPE_PISMO ||
964             pmac_mb.model_id == PMAC_TYPE_TITANIUM) {
965                 LOCK(flags);
966                 if (value)
967                         MACIO_OUT8(KL_GPIO_SOUND_POWER,
968                                 KEYLARGO_GPIO_OUTPUT_ENABLE |
969                                 KEYLARGO_GPIO_OUTOUT_DATA);
970                 else
971                         MACIO_OUT8(KL_GPIO_SOUND_POWER,
972                                 KEYLARGO_GPIO_OUTPUT_ENABLE);
973                 (void)MACIO_IN8(KL_GPIO_SOUND_POWER);
974                 UNLOCK(flags);
975         }
976         return 0;
977 }
978 
979 static int __pmac
980 core99_airport_enable(struct device_node* node, int param, int value)
981 {
982         struct macio_chip*      macio;
983         unsigned long           flags;
984         int                     state;
985 
986         macio = macio_find(node, 0);
987         if (!macio)
988                 return -ENODEV;
989 
990         /* Hint: we allow passing of macio itself for the sake of the
991          * sleep code
992          */
993         if (node != macio->of_node &&
994             (!node->parent || node->parent != macio->of_node))
995                 return -ENODEV;
996         state = (macio->flags & MACIO_FLAG_AIRPORT_ON) != 0;
997         if (value == state)
998                 return 0;
999         if (value) {
1000                 /* This code is a reproduction of OF enable-cardslot
1001                  * and init-wireless methods, slightly hacked until
1002                  * I got it working.
1003                  */
1004                 LOCK(flags);
1005                 MACIO_OUT8(KEYLARGO_GPIO_0+0xf, 5);
1006                 (void)MACIO_IN8(KEYLARGO_GPIO_0+0xf);
1007                 UNLOCK(flags);
1008                 mdelay(10);
1009                 LOCK(flags);
1010                 MACIO_OUT8(KEYLARGO_GPIO_0+0xf, 4);
1011                 (void)MACIO_IN8(KEYLARGO_GPIO_0+0xf);
1012                 UNLOCK(flags);
1013 
1014                 mdelay(10);
1015 
1016                 LOCK(flags);
1017                 MACIO_BIC(KEYLARGO_FCR2, KL2_CARDSEL_16);
1018                 (void)MACIO_IN32(KEYLARGO_FCR2);
1019                 udelay(10);
1020                 MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xb, 0);
1021                 (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xb);
1022                 udelay(10);
1023                 MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xa, 0x28);
1024                 (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xa);
1025                 udelay(10);
1026                 MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xd, 0x28);
1027                 (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xd);
1028                 udelay(10);
1029                 MACIO_OUT8(KEYLARGO_GPIO_0+0xd, 0x28);
1030                 (void)MACIO_IN8(KEYLARGO_GPIO_0+0xd);
1031                 udelay(10);
1032                 MACIO_OUT8(KEYLARGO_GPIO_0+0xe, 0x28);
1033                 (void)MACIO_IN8(KEYLARGO_GPIO_0+0xe);
1034                 UNLOCK(flags);
1035                 udelay(10);
1036                 MACIO_OUT32(0x1c000, 0);
1037                 mdelay(1);
1038                 MACIO_OUT8(0x1a3e0, 0x41);
1039                 (void)MACIO_IN8(0x1a3e0);
1040                 udelay(10);
1041                 LOCK(flags);
1042                 MACIO_BIS(KEYLARGO_FCR2, KL2_CARDSEL_16);
1043                 (void)MACIO_IN32(KEYLARGO_FCR2);
1044                 UNLOCK(flags);
1045                 mdelay(100);
1046 
1047                 macio->flags |= MACIO_FLAG_AIRPORT_ON;
1048         } else {
1049                 LOCK(flags);
1050                 MACIO_BIC(KEYLARGO_FCR2, KL2_CARDSEL_16);
1051                 (void)MACIO_IN32(KEYLARGO_FCR2);
1052                 MACIO_OUT8(KL_GPIO_AIRPORT_0, 0);
1053                 MACIO_OUT8(KL_GPIO_AIRPORT_1, 0);
1054                 MACIO_OUT8(KL_GPIO_AIRPORT_2, 0);
1055                 MACIO_OUT8(KL_GPIO_AIRPORT_3, 0);
1056                 MACIO_OUT8(KL_GPIO_AIRPORT_4, 0);
1057                 (void)MACIO_IN8(KL_GPIO_AIRPORT_4);
1058                 UNLOCK(flags);
1059 
1060                 macio->flags &= ~MACIO_FLAG_AIRPORT_ON;
1061         }
1062         return 0;
1063 }
1064 
1065 #ifdef CONFIG_SMP
1066 static int __pmac
1067 core99_reset_cpu(struct device_node* node, int param, int value)
1068 {
1069         unsigned int reset_io = 0;
1070         unsigned long flags;
1071         struct macio_chip* macio;
1072         struct device_node* np;
1073         const int dflt_reset_lines[] = {        KL_GPIO_RESET_CPU0,
1074                                                 KL_GPIO_RESET_CPU1,
1075                                                 KL_GPIO_RESET_CPU2,
1076                                                 KL_GPIO_RESET_CPU3 };
1077 
1078         macio = &macio_chips[0];
1079         if (macio->type != macio_keylargo)
1080                 return -ENODEV;
1081 
1082         np = find_path_device("/cpus");
1083         if (np == NULL)
1084                 return -ENODEV;
1085         for (np = np->child; np != NULL; np = np->sibling) {
1086                 u32* num = (u32 *)get_property(np, "reg", NULL);
1087                 u32* rst = (u32 *)get_property(np, "soft-reset", NULL);
1088                 if (num == NULL || rst == NULL)
1089                         continue;
1090                 if (param == *num) {
1091                         reset_io = *rst;
1092                         break;
1093                 }
1094         }
1095         if (np == NULL || reset_io == 0)
1096                 reset_io = dflt_reset_lines[param];
1097 
1098         LOCK(flags);
1099         MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE);
1100         (void)MACIO_IN8(reset_io);
1101         udelay(1);
1102         MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTOUT_DATA | KEYLARGO_GPIO_OUTPUT_ENABLE);
1103         (void)MACIO_IN8(reset_io);
1104         UNLOCK(flags);
1105 
1106         return 0;
1107 }
1108 #endif /* CONFIG_SMP */
1109 
1110 static int __pmac
1111 core99_usb_enable(struct device_node* node, int param, int value)
1112 {
1113         struct macio_chip* macio;
1114         unsigned long flags;
1115         char* prop;
1116         int number;
1117         u32 reg;
1118 
1119         macio = &macio_chips[0];
1120         if (macio->type != macio_keylargo && macio->type != macio_pangea &&
1121             macio->type != macio_intrepid)
1122                 return -ENODEV;
1123 
1124         /* XXX Fix handling of 3rd USB controller in Intrepid, move the
1125          * port connect stuff (KL4_*) to the sleep code eventually
1126          */
1127         prop = (char *)get_property(node, "AAPL,clock-id", NULL);
1128         if (!prop)
1129                 return -ENODEV;
1130         if (strncmp(prop, "usb0u048", 8) == 0)
1131                 number = 0;
1132         else if (strncmp(prop, "usb1u148", 8) == 0)
1133                 number = 2;
1134         else
1135                 return -ENODEV;
1136 
1137         /* Sorry for the brute-force locking, but this is only used during
1138          * sleep and the timing seem to be critical
1139          */
1140         LOCK(flags);
1141         if (value) {
1142                 /* Turn ON */
1143                 if (number == 0) {
1144                         MACIO_BIC(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1));
1145                         (void)MACIO_IN32(KEYLARGO_FCR0);
1146                         UNLOCK(flags);
1147                         mdelay(1);
1148                         LOCK(flags);
1149                         MACIO_BIS(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE);
1150                 } else {
1151                         MACIO_BIC(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1));
1152                         UNLOCK(flags);
1153                         (void)MACIO_IN32(KEYLARGO_FCR0);
1154                         mdelay(1);
1155                         LOCK(flags);
1156                         MACIO_BIS(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE);
1157                 }
1158                 reg = MACIO_IN32(KEYLARGO_FCR4);
1159                 reg &=  ~(KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) |
1160                         KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number));
1161                 reg &=  ~(KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) |
1162                         KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1));
1163                 MACIO_OUT32(KEYLARGO_FCR4, reg);
1164                 (void)MACIO_IN32(KEYLARGO_FCR4);
1165                 udelay(10);
1166         } else {
1167                 /* Turn OFF */
1168                 reg = MACIO_IN32(KEYLARGO_FCR4);
1169                 reg |=  KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) |
1170                         KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number);
1171                 reg |=  KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) |
1172                         KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1);
1173                 MACIO_OUT32(KEYLARGO_FCR4, reg);
1174                 (void)MACIO_IN32(KEYLARGO_FCR4);
1175                 udelay(1);
1176                 if (number == 0) {
1177                         MACIO_BIC(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE);
1178                         (void)MACIO_IN32(KEYLARGO_FCR0);
1179                         udelay(1);
1180                         MACIO_BIS(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1));
1181                         (void)MACIO_IN32(KEYLARGO_FCR0);
1182                 } else {
1183                         MACIO_BIC(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE);
1184                         (void)MACIO_IN32(KEYLARGO_FCR0);
1185                         udelay(1);
1186                         MACIO_BIS(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1));
1187                         (void)MACIO_IN32(KEYLARGO_FCR0);
1188                 }
1189                 udelay(1);
1190         }
1191         UNLOCK(flags);
1192 
1193         return 0;
1194 }
1195 
1196 static int __pmac
1197 core99_firewire_enable(struct device_node* node, int param, int value)
1198 {
1199         unsigned long flags;
1200         struct macio_chip* macio;
1201 
1202         macio = &macio_chips[0];
1203         if (macio->type != macio_keylargo && macio->type != macio_pangea &&
1204             macio->type != macio_intrepid)
1205                 return -ENODEV;
1206         if (!(macio->flags & MACIO_FLAG_FW_SUPPORTED))
1207                 return -ENODEV;
1208 
1209         LOCK(flags);
1210         if (value) {
1211                 UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW);
1212                 (void)UN_IN(UNI_N_CLOCK_CNTL);
1213         } else {
1214                 UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW);
1215                 (void)UN_IN(UNI_N_CLOCK_CNTL);
1216         }
1217         UNLOCK(flags);
1218         mdelay(1);
1219 
1220         return 0;
1221 }
1222 
1223 static int __pmac
1224 core99_firewire_cable_power(struct device_node* node, int param, int value)
1225 {
1226         unsigned long flags;
1227         struct macio_chip* macio;
1228 
1229         /* Trick: we allow NULL node */
1230         if ((pmac_mb.board_flags & PMAC_MB_HAS_FW_POWER) == 0)
1231                 return -ENODEV;
1232         macio = &macio_chips[0];
1233         if (macio->type != macio_keylargo && macio->type != macio_pangea &&
1234             macio->type != macio_intrepid)
1235                 return -ENODEV;
1236         if (!(macio->flags & MACIO_FLAG_FW_SUPPORTED))
1237                 return -ENODEV;
1238 
1239         LOCK(flags);
1240         if (value) {
1241                 MACIO_OUT8(KL_GPIO_FW_CABLE_POWER , 0);
1242                 MACIO_IN8(KL_GPIO_FW_CABLE_POWER);
1243                 udelay(10);
1244         } else {
1245                 MACIO_OUT8(KL_GPIO_FW_CABLE_POWER , 4);
1246                 MACIO_IN8(KL_GPIO_FW_CABLE_POWER); udelay(10);
1247         }
1248         UNLOCK(flags);
1249         mdelay(1);
1250 
1251         return 0;
1252 }
1253 
1254 static int __pmac
1255 core99_read_gpio(struct device_node* node, int param, int value)
1256 {
1257         struct macio_chip* macio = &macio_chips[0];
1258 
1259         return MACIO_IN8(param);
1260 }
1261 
1262 
1263 static int __pmac
1264 core99_write_gpio(struct device_node* node, int param, int value)
1265 {
1266         struct macio_chip* macio = &macio_chips[0];
1267 
1268         MACIO_OUT8(param, (u8)(value & 0xff));
1269         return 0;
1270 }
1271 
1272 static void __pmac
1273 keylargo_shutdown(struct macio_chip* macio, int sleep_mode)
1274 {
1275         u32 temp;
1276 
1277         if (sleep_mode) {
1278                 mdelay(1);
1279                 MACIO_BIS(KEYLARGO_FCR0, KL0_USB_REF_SUSPEND);
1280                 (void)MACIO_IN32(KEYLARGO_FCR0);
1281                 mdelay(1);
1282         }
1283 
1284         MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE |
1285                                 KL0_SCC_CELL_ENABLE |
1286                                 KL0_IRDA_ENABLE | KL0_IRDA_CLK32_ENABLE |
1287                                 KL0_IRDA_CLK19_ENABLE);
1288 
1289         MACIO_BIC(KEYLARGO_MBCR, KL_MBCR_MB0_DEV_MASK);
1290         MACIO_BIS(KEYLARGO_MBCR, KL_MBCR_MB0_IDE_ENABLE);
1291 
1292         MACIO_BIC(KEYLARGO_FCR1,
1293                 KL1_AUDIO_SEL_22MCLK | KL1_AUDIO_CLK_ENABLE_BIT |
1294                 KL1_AUDIO_CLK_OUT_ENABLE | KL1_AUDIO_CELL_ENABLE |
1295                 KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT |
1296                 KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE |
1297                 KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE |
1298                 KL1_EIDE0_ENABLE | KL1_EIDE0_RESET_N |
1299                 KL1_EIDE1_ENABLE | KL1_EIDE1_RESET_N |
1300                 KL1_UIDE_ENABLE);
1301 
1302         MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
1303         MACIO_BIC(KEYLARGO_FCR2, KL2_IOBUS_ENABLE);
1304 
1305         temp = MACIO_IN32(KEYLARGO_FCR3);
1306         if (macio->rev >= 2) {
1307                 temp |= KL3_SHUTDOWN_PLL2X;
1308                 if (sleep_mode)
1309                         temp |= KL3_SHUTDOWN_PLL_TOTAL;
1310         }
1311 
1312         temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 |
1313                 KL3_SHUTDOWN_PLLKW35;
1314         if (sleep_mode)
1315                 temp |= KL3_SHUTDOWN_PLLKW12;
1316         temp &= ~(KL3_CLK66_ENABLE | KL3_CLK49_ENABLE | KL3_CLK45_ENABLE
1317                 | KL3_CLK31_ENABLE | KL3_I2S1_CLK18_ENABLE | KL3_I2S0_CLK18_ENABLE);
1318         if (sleep_mode)
1319                 temp &= ~(KL3_TIMER_CLK18_ENABLE | KL3_VIA_CLK16_ENABLE);
1320         MACIO_OUT32(KEYLARGO_FCR3, temp);
1321 
1322         /* Flush posted writes & wait a bit */
1323         (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1);
1324 }
1325 
1326 static void __pmac
1327 pangea_shutdown(struct macio_chip* macio, int sleep_mode)
1328 {
1329         u32 temp;
1330 
1331         MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE |
1332                                 KL0_SCC_CELL_ENABLE |
1333                                 KL0_USB0_CELL_ENABLE | KL0_USB1_CELL_ENABLE);
1334 
1335         MACIO_BIC(KEYLARGO_FCR1,
1336                 KL1_AUDIO_SEL_22MCLK | KL1_AUDIO_CLK_ENABLE_BIT |
1337                 KL1_AUDIO_CLK_OUT_ENABLE | KL1_AUDIO_CELL_ENABLE |
1338                 KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT |
1339                 KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE |
1340                 KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE |
1341                 KL1_UIDE_ENABLE);
1342         if (pmac_mb.board_flags & PMAC_MB_MOBILE)
1343                 MACIO_BIC(KEYLARGO_FCR1, KL1_UIDE_RESET_N);
1344 
1345         MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
1346 
1347         temp = MACIO_IN32(KEYLARGO_FCR3);
1348         temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 |
1349                 KL3_SHUTDOWN_PLLKW35;
1350         temp &= ~(KL3_CLK49_ENABLE | KL3_CLK45_ENABLE | KL3_CLK31_ENABLE
1351                 | KL3_I2S0_CLK18_ENABLE | KL3_I2S1_CLK18_ENABLE);
1352         if (sleep_mode)
1353                 temp &= ~(KL3_VIA_CLK16_ENABLE | KL3_TIMER_CLK18_ENABLE);
1354         MACIO_OUT32(KEYLARGO_FCR3, temp);
1355 
1356         /* Flush posted writes & wait a bit */
1357         (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1);
1358 }
1359 
1360 static void __pmac
1361 intrepid_shutdown(struct macio_chip* macio, int sleep_mode)
1362 {
1363         u32 temp;
1364 
1365         MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE |
1366                                 KL0_SCC_CELL_ENABLE |
1367                                 KL0_USB0_CELL_ENABLE | KL0_USB1_CELL_ENABLE);
1368 
1369         MACIO_BIC(KEYLARGO_FCR1,
1370                 KL1_USB2_CELL_ENABLE |
1371                 KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT |
1372                 KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE |
1373                 KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE);
1374         if (pmac_mb.board_flags & PMAC_MB_MOBILE)
1375                 MACIO_BIC(KEYLARGO_FCR1, KL1_UIDE_RESET_N);
1376 
1377         MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
1378 
1379         temp = MACIO_IN32(KEYLARGO_FCR3);
1380         temp |= KL3_IT_SHUTDOWN_PLL1 | KL3_IT_SHUTDOWN_PLL2 |
1381                 KL3_IT_SHUTDOWN_PLL3;
1382         temp &= ~(KL3_CLK49_ENABLE | KL3_CLK45_ENABLE |
1383                   KL3_I2S1_CLK18_ENABLE | KL3_I2S0_CLK18_ENABLE);
1384         if (sleep_mode)
1385                 temp &= ~(KL3_TIMER_CLK18_ENABLE | KL3_IT_VIA_CLK32_ENABLE);
1386         MACIO_OUT32(KEYLARGO_FCR3, temp);
1387 
1388         /* Flush posted writes & wait a bit */
1389         (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1);
1390 }
1391 
1392 static int __pmac
1393 core99_sleep(void)
1394 {
1395         struct macio_chip* macio;
1396         int i;
1397 
1398         macio = &macio_chips[0];
1399         if (macio->type != macio_keylargo && macio->type != macio_pangea &&
1400             macio->type != macio_intrepid)
1401                 return -ENODEV;
1402 
1403         /* We power off the wireless slot in case it was not done
1404          * by the driver. We don't power it on automatically however
1405          */
1406         if (macio->flags & MACIO_FLAG_AIRPORT_ON)
1407                 core99_airport_enable(macio->of_node, 0, 0);
1408 
1409         /* We power off the FW cable. Should be done by the driver... */
1410         if (macio->flags & MACIO_FLAG_FW_SUPPORTED) {
1411                 core99_firewire_enable(NULL, 0, 0);
1412                 core99_firewire_cable_power(NULL, 0, 0);
1413         }
1414 
1415         /* We make sure int. modem is off (in case driver lost it) */
1416         if (macio->type == macio_keylargo)
1417                 core99_modem_enable(macio->of_node, 0, 0);
1418         else
1419                 pangea_modem_enable(macio->of_node, 0, 0);
1420 
1421         /* We make sure the sound is off as well */
1422         core99_sound_chip_enable(macio->of_node, 0, 0);
1423 
1424         /*
1425          * Save various bits of KeyLargo
1426          */
1427 
1428         /* Save the state of the various GPIOs */
1429         save_gpio_levels[0] = MACIO_IN32(KEYLARGO_GPIO_LEVELS0);
1430         save_gpio_levels[1] = MACIO_IN32(KEYLARGO_GPIO_LEVELS1);
1431         for (i=0; i<KEYLARGO_GPIO_EXTINT_CNT; i++)
1432                 save_gpio_extint[i] = MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+i);
1433         for (i=0; i<KEYLARGO_GPIO_CNT; i++)
1434                 save_gpio_normal[i] = MACIO_IN8(KEYLARGO_GPIO_0+i);
1435 
1436         /* Save the FCRs */
1437         if (macio->type == macio_keylargo)
1438                 save_mbcr = MACIO_IN32(KEYLARGO_MBCR);
1439         save_fcr[0] = MACIO_IN32(KEYLARGO_FCR0);
1440         save_fcr[1] = MACIO_IN32(KEYLARGO_FCR1);
1441         save_fcr[2] = MACIO_IN32(KEYLARGO_FCR2);
1442         save_fcr[3] = MACIO_IN32(KEYLARGO_FCR3);
1443         save_fcr[4] = MACIO_IN32(KEYLARGO_FCR4);
1444         if (macio->type == macio_pangea || macio->type == macio_intrepid)
1445                 save_fcr[5] = MACIO_IN32(KEYLARGO_FCR5);
1446 
1447         /* Save state & config of DBDMA channels */
1448         dbdma_save(macio, save_dbdma);
1449 
1450         /*
1451          * Turn off as much as we can
1452          */
1453         if (macio->type == macio_pangea)
1454                 pangea_shutdown(macio, 1);
1455         else if (macio->type == macio_intrepid)
1456                 intrepid_shutdown(macio, 1);
1457         else if (macio->type == macio_keylargo)
1458                 keylargo_shutdown(macio, 1);
1459 
1460         /*
1461          * Put the host bridge to sleep
1462          */
1463 
1464         save_unin_clock_ctl = UN_IN(UNI_N_CLOCK_CNTL);
1465         UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl &
1466                 ~(UNI_N_CLOCK_CNTL_GMAC|UNI_N_CLOCK_CNTL_FW/*|UNI_N_CLOCK_CNTL_PCI*/));
1467         udelay(100);
1468         UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_SLEEPING);
1469         UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_SLEEP);
1470 
1471         /*
1472          * FIXME: A bit of black magic with OpenPIC (don't ask me why)
1473          */
1474         if (pmac_mb.model_id == PMAC_TYPE_SAWTOOTH) {
1475                 MACIO_BIS(0x506e0, 0x00400000);
1476                 MACIO_BIS(0x506e0, 0x80000000);
1477         }
1478         return 0;
1479 }
1480 
1481 static int __pmac
1482 core99_wake_up(void)
1483 {
1484         struct macio_chip* macio;
1485         int i;
1486 
1487         macio = &macio_chips[0];
1488         if (macio->type != macio_keylargo && macio->type != macio_pangea &&
1489             macio->type != macio_intrepid)
1490                 return -ENODEV;
1491 
1492         /*
1493          * Wakeup the host bridge
1494          */
1495         UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_NORMAL);
1496         udelay(10);
1497         UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_RUNNING);
1498         udelay(10);
1499 
1500         /*
1501          * Restore KeyLargo
1502          */
1503 
1504         if (macio->type == macio_keylargo) {
1505                 MACIO_OUT32(KEYLARGO_MBCR, save_mbcr);
1506                 (void)MACIO_IN32(KEYLARGO_MBCR); udelay(10);
1507         }
1508         MACIO_OUT32(KEYLARGO_FCR0, save_fcr[0]);
1509         (void)MACIO_IN32(KEYLARGO_FCR0); udelay(10);
1510         MACIO_OUT32(KEYLARGO_FCR1, save_fcr[1]);
1511         (void)MACIO_IN32(KEYLARGO_FCR1); udelay(10);
1512         MACIO_OUT32(KEYLARGO_FCR2, save_fcr[2]);
1513         (void)MACIO_IN32(KEYLARGO_FCR2); udelay(10);
1514         MACIO_OUT32(KEYLARGO_FCR3, save_fcr[3]);
1515         (void)MACIO_IN32(KEYLARGO_FCR3); udelay(10);
1516         MACIO_OUT32(KEYLARGO_FCR4, save_fcr[4]);
1517         (void)MACIO_IN32(KEYLARGO_FCR4); udelay(10);
1518         if (macio->type == macio_pangea || macio->type == macio_intrepid) {
1519                 MACIO_OUT32(KEYLARGO_FCR5, save_fcr[5]);
1520                 (void)MACIO_IN32(KEYLARGO_FCR5); udelay(10);
1521         }
1522 
1523         dbdma_restore(macio, save_dbdma);
1524 
1525         MACIO_OUT32(KEYLARGO_GPIO_LEVELS0, save_gpio_levels[0]);
1526         MACIO_OUT32(KEYLARGO_GPIO_LEVELS1, save_gpio_levels[1]);
1527         for (i=0; i<KEYLARGO_GPIO_EXTINT_CNT; i++)
1528                 MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+i, save_gpio_extint[i]);
1529         for (i=0; i<KEYLARGO_GPIO_CNT; i++)
1530                 MACIO_OUT8(KEYLARGO_GPIO_0+i, save_gpio_normal[i]);
1531 
1532         /* FIXME more black magic with OpenPIC ... */
1533         if (pmac_mb.model_id == PMAC_TYPE_SAWTOOTH) {
1534                 MACIO_BIC(0x506e0, 0x00400000);
1535                 MACIO_BIC(0x506e0, 0x80000000);
1536         }
1537 
1538         UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl);
1539         udelay(100);
1540 
1541         return 0;
1542 }
1543 
1544 static int __pmac
1545 core99_sleep_state(struct device_node* node, int param, int value)
1546 {
1547         /* Param == 1 means to enter the "fake sleep" mode that is
1548          * used for CPU speed switch
1549          */
1550         if (param == 1) {
1551                 if (value == 1) {
1552                         UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_SLEEPING);
1553                         UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_IDLE2);
1554                 } else {
1555                         UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_NORMAL);
1556                         udelay(10);
1557                         UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_RUNNING);
1558                         udelay(10);
1559                 }
1560                 return 0;
1561         }
1562         if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0)
1563                 return -EPERM;
1564         if (value == 1)
1565                 return core99_sleep();
1566         else if (value == 0)
1567                 return core99_wake_up();
1568         return 0;
1569 }
1570 
1571 static int __pmac
1572 generic_get_mb_info(struct device_node* node, int param, int value)
1573 {
1574         switch(param) {
1575                 case PMAC_MB_INFO_MODEL:
1576                         return pmac_mb.model_id;
1577                 case PMAC_MB_INFO_FLAGS:
1578                         return pmac_mb.board_flags;
1579                 case PMAC_MB_INFO_NAME:
1580                         /* hack hack hack... but should work */
1581                         *((const char **)value) = pmac_mb.model_name;
1582                         break;
1583         }
1584         return 0;
1585 }
1586 
1587 
1588 /*
1589  * Table definitions
1590  */
1591 
1592 /* Used on any machine
1593  */
1594 static struct feature_table_entry any_features[]  __pmacdata = {
1595         { PMAC_FTR_GET_MB_INFO,         generic_get_mb_info },
1596         { 0, NULL }
1597 };
1598 
1599 /* OHare based motherboards. Currently, we only use these on the
1600  * 2400,3400 and 3500 series powerbooks. Some older desktops seem
1601  * to have issues with turning on/off those asic cells
1602  */
1603 static struct feature_table_entry ohare_features[]  __pmacdata = {
1604         { PMAC_FTR_SCC_ENABLE,          ohare_htw_scc_enable },
1605         { PMAC_FTR_SWIM3_ENABLE,        ohare_floppy_enable },
1606         { PMAC_FTR_MESH_ENABLE,         ohare_mesh_enable },
1607         { PMAC_FTR_IDE_ENABLE,          ohare_ide_enable},
1608         { PMAC_FTR_IDE_RESET,           ohare_ide_reset},
1609         { PMAC_FTR_SLEEP_STATE,         ohare_sleep_state },
1610         { 0, NULL }
1611 };
1612 
1613 /* Heathrow desktop machines (Beige G3).
1614  * Separated as some features couldn't be properly tested
1615  * and the serial port control bits appear to confuse it.
1616  */
1617 static struct feature_table_entry heathrow_desktop_features[]  __pmacdata = {
1618         { PMAC_FTR_SWIM3_ENABLE,        heathrow_floppy_enable },
1619         { PMAC_FTR_MESH_ENABLE,         heathrow_mesh_enable },
1620         { PMAC_FTR_IDE_ENABLE,          heathrow_ide_enable },
1621         { PMAC_FTR_IDE_RESET,           heathrow_ide_reset },
1622         { PMAC_FTR_BMAC_ENABLE,         heathrow_bmac_enable },
1623         { 0, NULL }
1624 };
1625 
1626 /* Heathrow based laptop, that is the Wallstreet and mainstreet
1627  * powerbooks.
1628  */
1629 static struct feature_table_entry heathrow_laptop_features[]  __pmacdata = {
1630         { PMAC_FTR_SCC_ENABLE,          ohare_htw_scc_enable },
1631         { PMAC_FTR_MODEM_ENABLE,        heathrow_modem_enable },
1632         { PMAC_FTR_SWIM3_ENABLE,        heathrow_floppy_enable },
1633         { PMAC_FTR_MESH_ENABLE,         heathrow_mesh_enable },
1634         { PMAC_FTR_IDE_ENABLE,          heathrow_ide_enable },
1635         { PMAC_FTR_IDE_RESET,           heathrow_ide_reset },
1636         { PMAC_FTR_BMAC_ENABLE,         heathrow_bmac_enable },
1637         { PMAC_FTR_SOUND_CHIP_ENABLE,   heathrow_sound_enable },
1638         { PMAC_FTR_SLEEP_STATE,         heathrow_sleep_state },
1639         { 0, NULL }
1640 };
1641 
1642 /* Paddington based machines
1643  * The lombard (101) powerbook, first iMac models, B&W G3 and Yikes G4.
1644  */
1645 static struct feature_table_entry paddington_features[]  __pmacdata = {
1646         { PMAC_FTR_SCC_ENABLE,          ohare_htw_scc_enable },
1647         { PMAC_FTR_MODEM_ENABLE,        heathrow_modem_enable },
1648         { PMAC_FTR_SWIM3_ENABLE,        heathrow_floppy_enable },
1649         { PMAC_FTR_MESH_ENABLE,         heathrow_mesh_enable },
1650         { PMAC_FTR_IDE_ENABLE,          heathrow_ide_enable },
1651         { PMAC_FTR_IDE_RESET,           heathrow_ide_reset },
1652         { PMAC_FTR_BMAC_ENABLE,         heathrow_bmac_enable },
1653         { PMAC_FTR_SOUND_CHIP_ENABLE,   heathrow_sound_enable },
1654         { PMAC_FTR_SLEEP_STATE,         heathrow_sleep_state },
1655         { 0, NULL }
1656 };
1657 
1658 /* Core99 & MacRISC 2 machines (all machines released since the
1659  * iBook (included), that is all AGP machines, except pangea
1660  * chipset. The pangea chipset is the "combo" UniNorth/KeyLargo
1661  * used on iBook2 & iMac "flow power".
1662  */
1663 static struct feature_table_entry core99_features[]  __pmacdata = {
1664         { PMAC_FTR_SCC_ENABLE,          core99_scc_enable },
1665         { PMAC_FTR_MODEM_ENABLE,        core99_modem_enable },
1666         { PMAC_FTR_IDE_ENABLE,          core99_ide_enable },
1667         { PMAC_FTR_IDE_RESET,           core99_ide_reset },
1668         { PMAC_FTR_GMAC_ENABLE,         core99_gmac_enable },
1669         { PMAC_FTR_GMAC_PHY_RESET,      core99_gmac_phy_reset },
1670         { PMAC_FTR_SOUND_CHIP_ENABLE,   core99_sound_chip_enable },
1671         { PMAC_FTR_AIRPORT_ENABLE,      core99_airport_enable },
1672         { PMAC_FTR_USB_ENABLE,          core99_usb_enable },
1673         { PMAC_FTR_1394_ENABLE,         core99_firewire_enable },
1674         { PMAC_FTR_1394_CABLE_POWER,    core99_firewire_cable_power },
1675         { PMAC_FTR_SLEEP_STATE,         core99_sleep_state },
1676 #ifdef CONFIG_SMP
1677         { PMAC_FTR_RESET_CPU,           core99_reset_cpu },
1678 #endif /* CONFIG_SMP */
1679         { PMAC_FTR_READ_GPIO,           core99_read_gpio },
1680         { PMAC_FTR_WRITE_GPIO,          core99_write_gpio },
1681         { 0, NULL }
1682 };
1683 
1684 /* RackMac
1685  */
1686 static struct feature_table_entry rackmac_features[]  __pmacdata = {
1687         { PMAC_FTR_SCC_ENABLE,          core99_scc_enable },
1688         { PMAC_FTR_IDE_ENABLE,          core99_ide_enable },
1689         { PMAC_FTR_IDE_RESET,           core99_ide_reset },
1690         { PMAC_FTR_GMAC_ENABLE,         core99_gmac_enable },
1691         { PMAC_FTR_GMAC_PHY_RESET,      core99_gmac_phy_reset },
1692         { PMAC_FTR_USB_ENABLE,          core99_usb_enable },
1693         { PMAC_FTR_1394_ENABLE,         core99_firewire_enable },
1694         { PMAC_FTR_1394_CABLE_POWER,    core99_firewire_cable_power },
1695         { PMAC_FTR_SLEEP_STATE,         core99_sleep_state },
1696 #ifdef CONFIG_SMP
1697         { PMAC_FTR_RESET_CPU,           core99_reset_cpu },
1698 #endif /* CONFIG_SMP */
1699         { PMAC_FTR_READ_GPIO,           core99_read_gpio },
1700         { PMAC_FTR_WRITE_GPIO,          core99_write_gpio },
1701         { 0, NULL }
1702 };
1703 
1704 /* Pangea features
1705  */
1706 static struct feature_table_entry pangea_features[]  __pmacdata = {
1707         { PMAC_FTR_SCC_ENABLE,          core99_scc_enable },
1708         { PMAC_FTR_MODEM_ENABLE,        pangea_modem_enable },
1709         { PMAC_FTR_IDE_ENABLE,          core99_ide_enable },
1710         { PMAC_FTR_IDE_RESET,           core99_ide_reset },
1711         { PMAC_FTR_GMAC_ENABLE,         core99_gmac_enable },
1712         { PMAC_FTR_GMAC_PHY_RESET,      core99_gmac_phy_reset },
1713         { PMAC_FTR_SOUND_CHIP_ENABLE,   core99_sound_chip_enable },
1714         { PMAC_FTR_AIRPORT_ENABLE,      core99_airport_enable },
1715         { PMAC_FTR_USB_ENABLE,          core99_usb_enable },
1716         { PMAC_FTR_1394_ENABLE,         core99_firewire_enable },
1717         { PMAC_FTR_1394_CABLE_POWER,    core99_firewire_cable_power },
1718         { PMAC_FTR_SLEEP_STATE,         core99_sleep_state },
1719         { PMAC_FTR_READ_GPIO,           core99_read_gpio },
1720         { PMAC_FTR_WRITE_GPIO,          core99_write_gpio },
1721         { 0, NULL }
1722 };
1723 
1724 /* Intrepid features
1725  */
1726 static struct feature_table_entry intrepid_features[]  __pmacdata = {
1727         { PMAC_FTR_SCC_ENABLE,          core99_scc_enable },
1728         { PMAC_FTR_MODEM_ENABLE,        pangea_modem_enable },
1729         { PMAC_FTR_IDE_ENABLE,          core99_ide_enable },
1730         { PMAC_FTR_IDE_RESET,           core99_ide_reset },
1731         { PMAC_FTR_GMAC_ENABLE,         core99_gmac_enable },
1732         { PMAC_FTR_GMAC_PHY_RESET,      core99_gmac_phy_reset },
1733         { PMAC_FTR_SOUND_CHIP_ENABLE,   core99_sound_chip_enable },
1734         { PMAC_FTR_AIRPORT_ENABLE,      core99_airport_enable },
1735         { PMAC_FTR_USB_ENABLE,          core99_usb_enable },
1736         { PMAC_FTR_1394_ENABLE,         core99_firewire_enable },
1737         { PMAC_FTR_1394_CABLE_POWER,    core99_firewire_cable_power },
1738         { PMAC_FTR_SLEEP_STATE,         core99_sleep_state },
1739         { PMAC_FTR_READ_GPIO,           core99_read_gpio },
1740         { PMAC_FTR_WRITE_GPIO,          core99_write_gpio },
1741         { 0, NULL }
1742 };
1743 
1744 static struct pmac_mb_def pmac_mb_defs[] __pmacdata = {
1745         /* Warning: ordering is important as some models may claim
1746          * beeing compatible with several types
1747          */
1748         {       "AAPL,8500",                    "PowerMac 8500/8600",
1749                 PMAC_TYPE_PSURGE,               NULL,
1750                 0
1751         },
1752         {       "AAPL,9500",                    "PowerMac 9500/9600",
1753                 PMAC_TYPE_PSURGE,               NULL,
1754                 0
1755         },
1756         {       "AAPL,7500",                    "PowerMac 7500",
1757                 PMAC_TYPE_PSURGE,               NULL,
1758                 0
1759         },
1760         {       "AAPL,ShinerESB",               "Apple Network Server",
1761                 PMAC_TYPE_ANS,                  NULL,
1762                 0
1763         },
1764         {       "AAPL,e407",                    "Alchemy",
1765                 PMAC_TYPE_ALCHEMY,              NULL,
1766                 0
1767         },
1768         {       "AAPL,e411",                    "Gazelle",
1769                 PMAC_TYPE_GAZELLE,              NULL,
1770                 0
1771         },
1772         {       "AAPL,3400/2400",               "PowerBook 3400",
1773                 PMAC_TYPE_HOOPER,               ohare_features,
1774                 PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
1775         },
1776         {       "AAPL,3500",                    "PowerBook 3500",
1777                 PMAC_TYPE_KANGA,                ohare_features,
1778                 PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
1779         },
1780         {       "AAPL,Gossamer",                "PowerMac G3 (Gossamer)",
1781                 PMAC_TYPE_GOSSAMER,             heathrow_desktop_features,
1782                 0
1783         },
1784         {       "AAPL,PowerMac G3",             "PowerMac G3 (Silk)",
1785                 PMAC_TYPE_SILK,                 heathrow_desktop_features,
1786                 0
1787         },
1788         {       "AAPL,PowerBook1998",           "PowerBook Wallstreet",
1789                 PMAC_TYPE_WALLSTREET,           heathrow_laptop_features,
1790                 PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
1791         },
1792         {       "PowerBook1,1",                 "PowerBook 101 (Lombard)",
1793                 PMAC_TYPE_101_PBOOK,            paddington_features,
1794                 PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
1795         },
1796         {       "iMac,1",                       "iMac (first generation)",
1797                 PMAC_TYPE_ORIG_IMAC,            paddington_features,
1798                 0
1799         },
1800         {       "PowerMac4,1",                  "iMac \"Flower Power\"",
1801                 PMAC_TYPE_PANGEA_IMAC,          pangea_features,
1802                 PMAC_MB_CAN_SLEEP
1803         },
1804         {       "PowerBook4,3",                 "iBook 2 rev. 2",
1805                 PMAC_TYPE_IBOOK2,               pangea_features,
1806                 PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
1807         },
1808         {       "PowerBook4,2",                 "iBook 2",
1809                 PMAC_TYPE_IBOOK2,               pangea_features,
1810                 PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
1811         },
1812         {       "PowerBook4,1",                 "iBook 2",
1813                 PMAC_TYPE_IBOOK2,               pangea_features,
1814                 PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
1815         },
1816         {       "PowerMac4,4",                  "eMac",
1817                 PMAC_TYPE_EMAC,                 core99_features,
1818                 PMAC_MB_CAN_SLEEP
1819         },
1820         {       "PowerMac4,2",                  "Flat panel iMac",
1821                 PMAC_TYPE_FLAT_PANEL_IMAC,      pangea_features,
1822                 PMAC_MB_CAN_SLEEP
1823         },
1824         {       "PowerMac1,1",                  "Blue&White G3",
1825                 PMAC_TYPE_YOSEMITE,             paddington_features,
1826                 0
1827         },
1828         {       "PowerMac1,2",                  "PowerMac G4 PCI Graphics",
1829                 PMAC_TYPE_YIKES,                paddington_features,
1830                 0
1831         },
1832         {       "PowerBook2,1",                 "iBook (first generation)",
1833                 PMAC_TYPE_ORIG_IBOOK,           core99_features,
1834                 PMAC_MB_CAN_SLEEP | PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE
1835         },
1836         {       "PowerMac3,1",                  "PowerMac G4 AGP Graphics",
1837                 PMAC_TYPE_SAWTOOTH,             core99_features,
1838                 PMAC_MB_OLD_CORE99
1839         },
1840         {       "PowerMac3,2",                  "PowerMac G4 AGP Graphics",
1841                 PMAC_TYPE_SAWTOOTH,             core99_features,
1842                 PMAC_MB_OLD_CORE99
1843         },
1844         {       "PowerMac3,3",                  "PowerMac G4 AGP Graphics",
1845                 PMAC_TYPE_SAWTOOTH,             core99_features,
1846                 PMAC_MB_OLD_CORE99
1847         },
1848         {       "PowerMac2,1",                  "iMac FireWire",
1849                 PMAC_TYPE_FW_IMAC,              core99_features,
1850                 PMAC_MB_CAN_SLEEP | PMAC_MB_OLD_CORE99
1851         },
1852         {       "PowerMac2,2",                  "iMac FireWire",
1853                 PMAC_TYPE_FW_IMAC,              core99_features,
1854                 PMAC_MB_CAN_SLEEP | PMAC_MB_OLD_CORE99
1855         },
1856         {       "PowerBook2,2",                 "iBook FireWire",
1857                 PMAC_TYPE_FW_IBOOK,             core99_features,
1858                 PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE
1859         },
1860         {       "PowerMac5,1",                  "PowerMac G4 Cube",
1861                 PMAC_TYPE_CUBE,                 core99_features,
1862                 PMAC_MB_OLD_CORE99
1863         },
1864         {       "PowerMac3,4",                  "PowerMac G4 Silver",
1865                 PMAC_TYPE_QUICKSILVER,          core99_features,
1866                 0
1867         },
1868         {       "PowerMac3,5",                  "PowerMac G4 Silver",
1869                 PMAC_TYPE_QUICKSILVER,          core99_features,
1870                 0
1871         },
1872         {       "PowerBook3,1",                 "PowerBook Pismo",
1873                 PMAC_TYPE_PISMO,                core99_features,
1874                 PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE
1875         },
1876         {       "PowerBook3,2",                 "PowerBook Titanium",
1877                 PMAC_TYPE_TITANIUM,             core99_features,
1878                 PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
1879         },
1880         {       "PowerBook3,3",                 "PowerBook Titanium II",
1881                 PMAC_TYPE_TITANIUM2,            core99_features,
1882                 PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
1883         },
1884         {       "PowerBook3,4",                 "PowerBook Titanium III",
1885                 PMAC_TYPE_TITANIUM3,            core99_features,
1886                 PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
1887         },
1888         {       "PowerBook3,5",                 "PowerBook Titanium IV",
1889                 PMAC_TYPE_TITANIUM4,            core99_features,
1890                 PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
1891         },
1892         {       "RackMac1,1",                   "XServe",
1893                 PMAC_TYPE_RACKMAC,              rackmac_features,
1894                 0,
1895         },
1896         {       "RackMac1,2",                   "XServe rev. 2",
1897                 PMAC_TYPE_RACKMAC,              rackmac_features,
1898                 0,
1899         },
1900         {       "PowerMac3,6",                  "PowerMac G4 Windtunnel",
1901                 PMAC_TYPE_WINDTUNNEL,           rackmac_features,
1902                 0,
1903         },
1904         {       "PowerBook5,1",                 "PowerBook G4 17\"",
1905                 PMAC_TYPE_UNKNOWN_INTREPID,     intrepid_features,
1906                 PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
1907         },
1908         {       "PowerBook6,1",                 "PowerBook G4 12\"",
1909                 PMAC_TYPE_UNKNOWN_INTREPID,     intrepid_features,
1910                 PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
1911         },
1912 };
1913 
1914 /*
1915  * The toplevel feature_call callback
1916  */
1917 int __pmac
1918 pmac_do_feature_call(unsigned int selector, ...)
1919 {
1920         struct device_node* node;
1921         int param, value, i;
1922         feature_call func = NULL;
1923         va_list args;
1924 
1925         if (pmac_mb.features)
1926                 for (i=0; pmac_mb.features[i].function; i++)
1927                         if (pmac_mb.features[i].selector == selector) {
1928                                 func = pmac_mb.features[i].function;
1929                                 break;
1930                         }
1931         if (!func)
1932                 for (i=0; any_features[i].function; i++)
1933                         if (any_features[i].selector == selector) {
1934                                 func = any_features[i].function;
1935                                 break;
1936                         }
1937         if (!func)
1938                 return -ENODEV;
1939 
1940         va_start(args, selector);
1941         node = (struct device_node*)va_arg(args, void*);
1942         param = va_arg(args, int);
1943         value = va_arg(args, int);
1944         va_end(args);
1945 
1946         return func(node, param, value);
1947 }
1948 
1949 static int __init
1950 probe_motherboard(void)
1951 {
1952         int i;
1953         struct macio_chip* macio = &macio_chips[0];
1954         const char* model = NULL;
1955         struct device_node *dt;
1956 
1957         /* Lookup known motherboard type in device-tree. First try an
1958          * exact match on the "model" property, then try a "compatible"
1959          * match is none is found.
1960          */
1961         dt = find_devices("device-tree");
1962         if (dt != NULL)
1963                 model = (const char *) get_property(dt, "model", NULL);
1964         for(i=0; model && i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) {
1965             if (strcmp(model, pmac_mb_defs[i].model_string) == 0) {
1966                 pmac_mb = pmac_mb_defs[i];
1967                 goto found;
1968             }
1969         }
1970         for(i=0; i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) {
1971             if (machine_is_compatible(pmac_mb_defs[i].model_string)) {
1972                 pmac_mb = pmac_mb_defs[i];
1973                 goto found;
1974             }
1975         }
1976 
1977         /* Fallback to selection depending on mac-io chip type */
1978         switch(macio->type) {
1979             case macio_grand_central:
1980                 pmac_mb.model_id = PMAC_TYPE_PSURGE;
1981                 pmac_mb.model_name = "Unknown PowerSurge";
1982                 break;
1983             case macio_ohare:
1984                 pmac_mb.model_id = PMAC_TYPE_UNKNOWN_OHARE;
1985                 pmac_mb.model_name = "Unknown OHare-based";
1986                 break;
1987             case macio_heathrow:
1988                 pmac_mb.model_id = PMAC_TYPE_UNKNOWN_HEATHROW;
1989                 pmac_mb.model_name = "Unknown Heathrow-based";
1990                 pmac_mb.features = heathrow_desktop_features;
1991                 break;
1992             case macio_paddington:
1993                 pmac_mb.model_id = PMAC_TYPE_UNKNOWN_PADDINGTON;
1994                 pmac_mb.model_name = "Unknown Paddington-based";
1995                 pmac_mb.features = paddington_features;
1996                 break;
1997             case macio_keylargo:
1998                 pmac_mb.model_id = PMAC_TYPE_UNKNOWN_CORE99;
1999                 pmac_mb.model_name = "Unknown Keylargo-based";
2000                 pmac_mb.features = core99_features;
2001                 break;
2002             case macio_pangea:
2003                 pmac_mb.model_id = PMAC_TYPE_UNKNOWN_PANGEA;
2004                 pmac_mb.model_name = "Unknown Pangea-based";
2005                 pmac_mb.features = pangea_features;
2006                 break;
2007             case macio_intrepid:
2008                 pmac_mb.model_id = PMAC_TYPE_UNKNOWN_INTREPID;
2009                 pmac_mb.model_name = "Unknown Intrepid-based";
2010                 pmac_mb.features = intrepid_features;
2011                 break;
2012             default:
2013                 return -ENODEV;
2014         }
2015 found:
2016         /* Fixup Hooper vs. Comet */
2017         if (pmac_mb.model_id == PMAC_TYPE_HOOPER) {
2018                 u32* mach_id_ptr = (u32*)ioremap(0xf3000034, 4);
2019                 if (!mach_id_ptr)
2020                         return -ENODEV;
2021                 /* Here, I used to disable the media-bay on comet. It
2022                  * appears this is wrong, the floppy connector is actually
2023                  * a kind of media-bay and works with the current driver.
2024                  */
2025                 if ((*mach_id_ptr) & 0x20000000UL)
2026                         pmac_mb.model_id = PMAC_TYPE_COMET;
2027                 iounmap(mach_id_ptr);
2028         }
2029 
2030 #ifdef CONFIG_6xx
2031         /* Set default value of powersave_nap on machines that support it.
2032          * It appears that uninorth rev 3 has a problem with it, we don't
2033          * enable it on those. In theory, the flush-on-lock property is
2034          * supposed to be set when not supported, but I'm not very confident
2035          * that all Apple OF revs did it properly, I do it the paranoid way.
2036          */
2037         while (uninorth_base && uninorth_rev > 3) {
2038                 struct device_node* np = find_path_device("/cpus");
2039                 if (!np || !np->child) {
2040                         printk(KERN_WARNING "Can't find CPU(s) in device tree !\n");
2041                         break;
2042                 }
2043                 np = np->child;
2044                 /* Nap mode not supported on SMP */
2045                 if (np->sibling)
2046                         break;
2047                 /* Nap mode not supported if flush-on-lock property is present */
2048                 if (get_property(np, "flush-on-lock", NULL))
2049                         break;
2050                 powersave_nap = 1;
2051                 printk(KERN_INFO "Processor NAP mode on idle enabled.\n");
2052                 break;
2053         }
2054 
2055         /* On CPUs that support it (750FX), lowspeed by default during
2056          * NAP mode
2057          */
2058         powersave_lowspeed = 1;
2059 #endif /* CONFIG_6xx */
2060 
2061         /* Check for "mobile" machine */
2062         if (model && (strncmp(model, "PowerBook", 9) == 0
2063                    || strncmp(model, "iBook", 5) == 0))
2064                 pmac_mb.board_flags |= PMAC_MB_MOBILE;
2065 
2066 
2067         printk(KERN_INFO "PowerMac motherboard: %s\n", pmac_mb.model_name);
2068         return 0;
2069 }
2070 
2071 /* Initialize the Core99 UniNorth host bridge and memory controller
2072  */
2073 static void __init
2074 probe_uninorth(void)
2075 {
2076         unsigned long actrl;
2077 
2078         /* Locate core99 Uni-N */
2079         uninorth_node = find_devices("uni-n");
2080         if (uninorth_node && uninorth_node->n_addrs > 0) {
2081                 uninorth_base = ioremap(uninorth_node->addrs[0].address, 0x4000);
2082                 uninorth_rev = in_be32(UN_REG(UNI_N_VERSION));
2083         } else
2084                 uninorth_node = NULL;
2085 
2086         if (!uninorth_node)
2087                 return;
2088 
2089         printk(KERN_INFO "Found Uninorth memory controller & host bridge, revision: %d\n",
2090                         uninorth_rev);
2091         printk(KERN_INFO "Mapped at 0x%08lx\n", (unsigned long)uninorth_base);
2092 
2093         /* Set the arbitrer QAck delay according to what Apple does
2094          */
2095         if (uninorth_rev < 0x11) {
2096                 actrl = UN_IN(UNI_N_ARB_CTRL) & ~UNI_N_ARB_CTRL_QACK_DELAY_MASK;
2097                 actrl |= ((uninorth_rev < 3) ? UNI_N_ARB_CTRL_QACK_DELAY105 :
2098                         UNI_N_ARB_CTRL_QACK_DELAY) << UNI_N_ARB_CTRL_QACK_DELAY_SHIFT;
2099                 UN_OUT(UNI_N_ARB_CTRL, actrl);
2100         }
2101 
2102         /* Some more magic as done by them in recent MacOS X on UniNorth
2103          * revs 1.5 to 2.O and Pangea. Seem to toggle the UniN Maxbus/PCI
2104          * memory timeout
2105          */
2106         if ((uninorth_rev >= 0x11 && uninorth_rev <= 0x24) || uninorth_rev == 0xc0)
2107                 UN_OUT(0x2160, UN_IN(0x2160) & 0x00ffffff);
2108 }
2109 
2110 static void __init
2111 probe_one_macio(const char* name, const char* compat, int type)
2112 {
2113         struct device_node*     node;
2114         int                     i;
2115         volatile u32*           base;
2116         u32*                    revp;
2117 
2118         node = find_devices(name);
2119         if (!node || !node->n_addrs)
2120                 return;
2121         if (compat)
2122                 do {
2123                         if (device_is_compatible(node, compat))
2124                                 break;
2125                         node = node->next;
2126                 } while (node);
2127         if (!node)
2128                 return;
2129         for(i=0; i<MAX_MACIO_CHIPS; i++) {
2130                 if (!macio_chips[i].of_node)
2131                         break;
2132                 if (macio_chips[i].of_node == node)
2133                         return;
2134         }
2135         if (i >= MAX_MACIO_CHIPS) {
2136                 printk(KERN_ERR "pmac_feature: Please increase MAX_MACIO_CHIPS !\n");
2137                 printk(KERN_ERR "pmac_feature: %s skipped\n", node->full_name);
2138                 return;
2139         }
2140         base = (volatile u32*)ioremap(node->addrs[0].address, node->addrs[0].size);
2141         if (!base) {
2142                 printk(KERN_ERR "pmac_feature: Can't map mac-io chip !\n");
2143                 return;
2144         }
2145         if (type == macio_keylargo) {
2146                 u32* did = (u32 *)get_property(node, "device-id", NULL);
2147                 if (*did == 0x00000025)
2148                         type = macio_pangea;
2149                 if (*did == 0x0000003e)
2150                         type = macio_intrepid;
2151         }
2152         macio_chips[i].of_node  = node;
2153         macio_chips[i].type     = type;
2154         macio_chips[i].base     = base;
2155         macio_chips[i].flags    = MACIO_FLAG_SCCB_ON | MACIO_FLAG_SCCB_ON;
2156         macio_chips[i].name     = macio_names[type];
2157         revp = (u32 *)get_property(node, "revision-id", NULL);
2158         if (revp)
2159                 macio_chips[i].rev = *revp;
2160         printk(KERN_INFO "Found a %s mac-io controller, rev: %d, mapped at 0x%p\n",
2161                 macio_names[type], macio_chips[i].rev, macio_chips[i].base);
2162 }
2163 
2164 static int __init
2165 probe_macios(void)
2166 {
2167         /* Warning, ordering is important */
2168         probe_one_macio("gc", NULL, macio_grand_central);
2169         probe_one_macio("ohare", NULL, macio_ohare);
2170         probe_one_macio("pci106b,7", NULL, macio_ohareII);
2171         probe_one_macio("mac-io", "keylargo", macio_keylargo);
2172         probe_one_macio("mac-io", "paddington", macio_paddington);
2173         probe_one_macio("mac-io", "gatwick", macio_gatwick);
2174         probe_one_macio("mac-io", "heathrow", macio_heathrow);
2175 
2176         /* Make sure the "main" macio chip appear first */
2177         if (macio_chips[0].type == macio_gatwick
2178             && macio_chips[1].type == macio_heathrow) {
2179                 struct macio_chip temp = macio_chips[0];
2180                 macio_chips[0] = macio_chips[1];
2181                 macio_chips[1] = temp;
2182         }
2183         if (macio_chips[0].type == macio_ohareII
2184             && macio_chips[1].type == macio_ohare) {
2185                 struct macio_chip temp = macio_chips[0];
2186                 macio_chips[0] = macio_chips[1];
2187                 macio_chips[1] = temp;
2188         }
2189         macio_chips[0].lbus.index = 0;
2190         macio_chips[1].lbus.index = 1;
2191 
2192         return (macio_chips[0].of_node == NULL) ? -ENODEV : 0;
2193 }
2194 
2195 static void __init
2196 initial_serial_shutdown(struct device_node* np)
2197 {
2198         int len;
2199         struct slot_names_prop {
2200                 int     count;
2201                 char    name[1];
2202         } *slots;
2203         char *conn;
2204         int port_type = PMAC_SCC_ASYNC;
2205         int modem = 0;
2206 
2207         slots = (struct slot_names_prop *)get_property(np, "slot-names", &len);
2208         conn = get_property(np, "AAPL,connector", &len);
2209         if (conn && (strcmp(conn, "infrared") == 0))
2210                 port_type = PMAC_SCC_IRDA;
2211         else if (device_is_compatible(np, "cobalt"))
2212                 modem = 1;
2213         else if (slots && slots->count > 0) {
2214                 if (strcmp(slots->name, "IrDA") == 0)
2215                         port_type = PMAC_SCC_IRDA;
2216                 else if (strcmp(slots->name, "Modem") == 0)
2217                         modem = 1;
2218         }
2219         if (modem)
2220                 pmac_call_feature(PMAC_FTR_MODEM_ENABLE, np, 0, 0);
2221         pmac_call_feature(PMAC_FTR_SCC_ENABLE, np, port_type, 0);
2222 }
2223 
2224 static void __init
2225 set_initial_features(void)
2226 {
2227         struct device_node* np;
2228 
2229         /* That hack appears to be necessary for some StarMax motherboards
2230          * but I'm not too sure it was audited for side-effects on other
2231          * ohare based machines...
2232          * Since I still have difficulties figuring the right way to
2233          * differenciate them all and since that hack was there for a long
2234          * time, I'll keep it around
2235          */
2236         if (macio_chips[0].type == macio_ohare && !find_devices("via-pmu")) {
2237                 struct macio_chip* macio = &macio_chips[0];
2238                 MACIO_OUT32(OHARE_FCR, STARMAX_FEATURES);
2239         } else if (macio_chips[0].type == macio_ohare) {
2240                 struct macio_chip* macio = &macio_chips[0];
2241                 MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE);
2242         } else if (macio_chips[1].type == macio_ohare) {
2243                 struct macio_chip* macio = &macio_chips[1];
2244                 MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE);
2245         }
2246 
2247         if (macio_chips[0].type == macio_keylargo ||
2248             macio_chips[0].type == macio_pangea ||
2249             macio_chips[0].type == macio_intrepid) {
2250                 /* Enable GMAC for now for PCI probing. It will be disabled
2251                  * later on after PCI probe
2252                  */
2253                 np = find_devices("ethernet");
2254                 while(np) {
2255                         if (np->parent
2256                             && device_is_compatible(np->parent, "uni-north")
2257                             && device_is_compatible(np, "gmac"))
2258                                 core99_gmac_enable(np, 0, 1);
2259                         np = np->next;
2260                 }
2261 
2262                 /* Enable FW before PCI probe. Will be disabled later on
2263                  * Note: We should have a batter way to check that we are
2264                  * dealing with uninorth internal cell and not a PCI cell
2265                  * on the external PCI. The code below works though.
2266                  */
2267                 np = find_devices("firewire");
2268                 while(np) {
2269                         if (np->parent
2270                             && device_is_compatible(np->parent, "uni-north")
2271                             && (device_is_compatible(np, "pci106b,18") ||
2272                                 device_is_compatible(np, "pci106b,30") ||
2273                                 device_is_compatible(np, "pci11c1,5811"))) {
2274                                 macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED;
2275                                 core99_firewire_enable(np, 0, 1);
2276                         }
2277                         np = np->next;
2278                 }
2279 
2280                 /* Enable ATA-100 before PCI probe. */
2281                 np = find_devices("ata-6");
2282                 while(np) {
2283                         if (np->parent
2284                             && device_is_compatible(np->parent, "uni-north")
2285                             && device_is_compatible(np, "kauai-ata")) {
2286                                 core99_ata100_enable(np, 1);
2287                         }
2288                         np = np->next;
2289                 }
2290 
2291                 /* Switch airport off */
2292                 np = find_devices("radio");
2293                 while(np) {
2294                         if (np && np->parent == macio_chips[0].of_node) {
2295                                 macio_chips[0].flags |= MACIO_FLAG_AIRPORT_ON;
2296                                 core99_airport_enable(np, 0, 0);
2297                         }
2298                         np = np->next;
2299                 }
2300         }
2301 
2302         /* On all machines that support sound PM, switch sound off */
2303         if (macio_chips[0].of_node)
2304                 pmac_do_feature_call(PMAC_FTR_SOUND_CHIP_ENABLE,
2305                         macio_chips[0].of_node, 0, 0);
2306 
2307         /* While on some desktop G3s, we turn it back on */
2308         if (macio_chips[0].of_node && macio_chips[0].type == macio_heathrow
2309                 && (pmac_mb.model_id == PMAC_TYPE_GOSSAMER ||
2310                     pmac_mb.model_id == PMAC_TYPE_SILK)) {
2311                 struct macio_chip* macio = &macio_chips[0];
2312                 MACIO_BIS(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
2313                 MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N);
2314         }
2315 
2316 
2317         /* On all machines, switch modem & serial ports off */
2318         np = find_devices("ch-a");
2319         while(np) {
2320                 initial_serial_shutdown(np);
2321                 np = np->next;
2322         }
2323         np = find_devices("ch-b");
2324         while(np) {
2325                 initial_serial_shutdown(np);
2326                 np = np->next;
2327         }
2328 }
2329 
2330 void __init
2331 pmac_feature_init(void)
2332 {
2333         /* Detect the UniNorth memory controller */
2334         probe_uninorth();
2335 
2336         /* Probe mac-io controllers */
2337         if (probe_macios()) {
2338                 printk(KERN_WARNING "No mac-io chip found\n");
2339                 return;
2340         }
2341 
2342         /* Probe machine type */
2343         if (probe_motherboard())
2344                 printk(KERN_WARNING "Unknown PowerMac !\n");
2345 
2346         /* Set some initial features (turn off some chips that will
2347          * be later turned on)
2348          */
2349         set_initial_features();
2350 }
2351 
2352 int __init
2353 pmac_feature_late_init(void)
2354 {
2355         struct device_node* np;
2356 
2357         /* Request some resources late */
2358         if (uninorth_node)
2359                 request_OF_resource(uninorth_node, 0, NULL);
2360         np = find_devices("hammerhead");
2361         if (np)
2362                 request_OF_resource(np, 0, NULL);
2363         np = find_devices("interrupt-controller");
2364         if (np)
2365                 request_OF_resource(np, 0, NULL);
2366         return 0;
2367 }
2368 
2369 device_initcall(pmac_feature_late_init);
2370 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp