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

Linux Cross Reference
Linux-2.6.17/drivers/macintosh/via-pmu.c

Version: ~ [ 2.6.16 ] ~ [ 2.6.17 ] ~
Architecture: ~ [ ia64 ] ~ [ i386 ] ~ [ arm ] ~ [ ppc ] ~ [ sparc64 ] ~

  1 /*
  2  * Device driver for the via-pmu on Apple Powermacs.
  3  *
  4  * The VIA (versatile interface adapter) interfaces to the PMU,
  5  * a 6805 microprocessor core whose primary function is to control
  6  * battery charging and system power on the PowerBook 3400 and 2400.
  7  * The PMU also controls the ADB (Apple Desktop Bus) which connects
  8  * to the keyboard and mouse, as well as the non-volatile RAM
  9  * and the RTC (real time clock) chip.
 10  *
 11  * Copyright (C) 1998 Paul Mackerras and Fabio Riccardi.
 12  * Copyright (C) 2001-2002 Benjamin Herrenschmidt
 13  *
 14  * THIS DRIVER IS BECOMING A TOTAL MESS !
 15  *  - Cleanup atomically disabling reply to PMU events after
 16  *    a sleep or a freq. switch
 17  *  - Move sleep code out of here to pmac_pm, merge into new
 18  *    common PM infrastructure
 19  *  - Move backlight code out as well
 20  *  - Save/Restore PCI space properly
 21  *
 22  */
 23 #include <stdarg.h>
 24 #include <linux/config.h>
 25 #include <linux/types.h>
 26 #include <linux/errno.h>
 27 #include <linux/kernel.h>
 28 #include <linux/delay.h>
 29 #include <linux/sched.h>
 30 #include <linux/miscdevice.h>
 31 #include <linux/blkdev.h>
 32 #include <linux/pci.h>
 33 #include <linux/slab.h>
 34 #include <linux/poll.h>
 35 #include <linux/adb.h>
 36 #include <linux/pmu.h>
 37 #include <linux/cuda.h>
 38 #include <linux/smp_lock.h>
 39 #include <linux/module.h>
 40 #include <linux/spinlock.h>
 41 #include <linux/pm.h>
 42 #include <linux/proc_fs.h>
 43 #include <linux/init.h>
 44 #include <linux/interrupt.h>
 45 #include <linux/device.h>
 46 #include <linux/sysdev.h>
 47 #include <linux/suspend.h>
 48 #include <linux/syscalls.h>
 49 #include <linux/cpu.h>
 50 #include <asm/prom.h>
 51 #include <asm/machdep.h>
 52 #include <asm/io.h>
 53 #include <asm/pgtable.h>
 54 #include <asm/system.h>
 55 #include <asm/sections.h>
 56 #include <asm/irq.h>
 57 #include <asm/pmac_feature.h>
 58 #include <asm/pmac_pfunc.h>
 59 #include <asm/pmac_low_i2c.h>
 60 #include <asm/uaccess.h>
 61 #include <asm/mmu_context.h>
 62 #include <asm/cputable.h>
 63 #include <asm/time.h>
 64 #ifdef CONFIG_PMAC_BACKLIGHT
 65 #include <asm/backlight.h>
 66 #endif
 67 
 68 #ifdef CONFIG_PPC32
 69 #include <asm/open_pic.h>
 70 #endif
 71 
 72 /* Some compile options */
 73 #undef SUSPEND_USES_PMU
 74 #define DEBUG_SLEEP
 75 #undef HACKED_PCI_SAVE
 76 
 77 /* Misc minor number allocated for /dev/pmu */
 78 #define PMU_MINOR               154
 79 
 80 /* How many iterations between battery polls */
 81 #define BATTERY_POLLING_COUNT   2
 82 
 83 static volatile unsigned char __iomem *via;
 84 
 85 /* VIA registers - spaced 0x200 bytes apart */
 86 #define RS              0x200           /* skip between registers */
 87 #define B               0               /* B-side data */
 88 #define A               RS              /* A-side data */
 89 #define DIRB            (2*RS)          /* B-side direction (1=output) */
 90 #define DIRA            (3*RS)          /* A-side direction (1=output) */
 91 #define T1CL            (4*RS)          /* Timer 1 ctr/latch (low 8 bits) */
 92 #define T1CH            (5*RS)          /* Timer 1 counter (high 8 bits) */
 93 #define T1LL            (6*RS)          /* Timer 1 latch (low 8 bits) */
 94 #define T1LH            (7*RS)          /* Timer 1 latch (high 8 bits) */
 95 #define T2CL            (8*RS)          /* Timer 2 ctr/latch (low 8 bits) */
 96 #define T2CH            (9*RS)          /* Timer 2 counter (high 8 bits) */
 97 #define SR              (10*RS)         /* Shift register */
 98 #define ACR             (11*RS)         /* Auxiliary control register */
 99 #define PCR             (12*RS)         /* Peripheral control register */
100 #define IFR             (13*RS)         /* Interrupt flag register */
101 #define IER             (14*RS)         /* Interrupt enable register */
102 #define ANH             (15*RS)         /* A-side data, no handshake */
103 
104 /* Bits in B data register: both active low */
105 #define TACK            0x08            /* Transfer acknowledge (input) */
106 #define TREQ            0x10            /* Transfer request (output) */
107 
108 /* Bits in ACR */
109 #define SR_CTRL         0x1c            /* Shift register control bits */
110 #define SR_EXT          0x0c            /* Shift on external clock */
111 #define SR_OUT          0x10            /* Shift out if 1 */
112 
113 /* Bits in IFR and IER */
114 #define IER_SET         0x80            /* set bits in IER */
115 #define IER_CLR         0               /* clear bits in IER */
116 #define SR_INT          0x04            /* Shift register full/empty */
117 #define CB2_INT         0x08
118 #define CB1_INT         0x10            /* transition on CB1 input */
119 
120 static volatile enum pmu_state {
121         idle,
122         sending,
123         intack,
124         reading,
125         reading_intr,
126         locked,
127 } pmu_state;
128 
129 static volatile enum int_data_state {
130         int_data_empty,
131         int_data_fill,
132         int_data_ready,
133         int_data_flush
134 } int_data_state[2] = { int_data_empty, int_data_empty };
135 
136 static struct adb_request *current_req;
137 static struct adb_request *last_req;
138 static struct adb_request *req_awaiting_reply;
139 static unsigned char interrupt_data[2][32];
140 static int interrupt_data_len[2];
141 static int int_data_last;
142 static unsigned char *reply_ptr;
143 static int data_index;
144 static int data_len;
145 static volatile int adb_int_pending;
146 static volatile int disable_poll;
147 static struct adb_request bright_req_1, bright_req_2;
148 static struct device_node *vias;
149 static int pmu_kind = PMU_UNKNOWN;
150 static int pmu_fully_inited = 0;
151 static int pmu_has_adb;
152 static struct device_node *gpio_node;
153 static unsigned char __iomem *gpio_reg = NULL;
154 static int gpio_irq = -1;
155 static int gpio_irq_enabled = -1;
156 static volatile int pmu_suspended = 0;
157 static spinlock_t pmu_lock;
158 static u8 pmu_intr_mask;
159 static int pmu_version;
160 static int drop_interrupts;
161 #if defined(CONFIG_PM) && defined(CONFIG_PPC32)
162 static int option_lid_wakeup = 1;
163 #endif /* CONFIG_PM && CONFIG_PPC32 */
164 #if (defined(CONFIG_PM)&&defined(CONFIG_PPC32))||defined(CONFIG_PMAC_BACKLIGHT)
165 static int sleep_in_progress;
166 #endif
167 static unsigned long async_req_locks;
168 static unsigned int pmu_irq_stats[11];
169 
170 static struct proc_dir_entry *proc_pmu_root;
171 static struct proc_dir_entry *proc_pmu_info;
172 static struct proc_dir_entry *proc_pmu_irqstats;
173 static struct proc_dir_entry *proc_pmu_options;
174 static int option_server_mode;
175 
176 int pmu_battery_count;
177 int pmu_cur_battery;
178 unsigned int pmu_power_flags;
179 struct pmu_battery_info pmu_batteries[PMU_MAX_BATTERIES];
180 static int query_batt_timer = BATTERY_POLLING_COUNT;
181 static struct adb_request batt_req;
182 static struct proc_dir_entry *proc_pmu_batt[PMU_MAX_BATTERIES];
183 
184 #if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT)
185 extern int disable_kernel_backlight;
186 #endif /* defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) */
187 
188 int __fake_sleep;
189 int asleep;
190 BLOCKING_NOTIFIER_HEAD(sleep_notifier_list);
191 
192 #ifdef CONFIG_ADB
193 static int adb_dev_map = 0;
194 static int pmu_adb_flags;
195 
196 static int pmu_probe(void);
197 static int pmu_init(void);
198 static int pmu_send_request(struct adb_request *req, int sync);
199 static int pmu_adb_autopoll(int devs);
200 static int pmu_adb_reset_bus(void);
201 #endif /* CONFIG_ADB */
202 
203 static int init_pmu(void);
204 static void pmu_start(void);
205 static irqreturn_t via_pmu_interrupt(int irq, void *arg, struct pt_regs *regs);
206 static irqreturn_t gpio1_interrupt(int irq, void *arg, struct pt_regs *regs);
207 static int proc_get_info(char *page, char **start, off_t off,
208                           int count, int *eof, void *data);
209 static int proc_get_irqstats(char *page, char **start, off_t off,
210                           int count, int *eof, void *data);
211 #ifdef CONFIG_PMAC_BACKLIGHT
212 static int pmu_set_backlight_level(int level, void* data);
213 static int pmu_set_backlight_enable(int on, int level, void* data);
214 #endif /* CONFIG_PMAC_BACKLIGHT */
215 static void pmu_pass_intr(unsigned char *data, int len);
216 static int proc_get_batt(char *page, char **start, off_t off,
217                         int count, int *eof, void *data);
218 static int proc_read_options(char *page, char **start, off_t off,
219                         int count, int *eof, void *data);
220 static int proc_write_options(struct file *file, const char __user *buffer,
221                         unsigned long count, void *data);
222 
223 #ifdef CONFIG_ADB
224 struct adb_driver via_pmu_driver = {
225         "PMU",
226         pmu_probe,
227         pmu_init,
228         pmu_send_request,
229         pmu_adb_autopoll,
230         pmu_poll_adb,
231         pmu_adb_reset_bus
232 };
233 #endif /* CONFIG_ADB */
234 
235 extern void low_sleep_handler(void);
236 extern void enable_kernel_altivec(void);
237 extern void enable_kernel_fp(void);
238 
239 #ifdef DEBUG_SLEEP
240 int pmu_polled_request(struct adb_request *req);
241 int pmu_wink(struct adb_request *req);
242 #endif
243 
244 /*
245  * This table indicates for each PMU opcode:
246  * - the number of data bytes to be sent with the command, or -1
247  *   if a length byte should be sent,
248  * - the number of response bytes which the PMU will return, or
249  *   -1 if it will send a length byte.
250  */
251 static const s8 pmu_data_len[256][2] = {
252 /*         0       1       2       3       4       5       6       7  */
253 /*00*/  {-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
254 /*08*/  {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
255 /*10*/  { 1, 0},{ 1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
256 /*18*/  { 0, 1},{ 0, 1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{ 0, 0},
257 /*20*/  {-1, 0},{ 0, 0},{ 2, 0},{ 1, 0},{ 1, 0},{-1, 0},{-1, 0},{-1, 0},
258 /*28*/  { 0,-1},{ 0,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{ 0,-1},
259 /*30*/  { 4, 0},{20, 0},{-1, 0},{ 3, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
260 /*38*/  { 0, 4},{ 0,20},{ 2,-1},{ 2, 1},{ 3,-1},{-1,-1},{-1,-1},{ 4, 0},
261 /*40*/  { 1, 0},{ 1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
262 /*48*/  { 0, 1},{ 0, 1},{-1,-1},{ 1, 0},{ 1, 0},{-1,-1},{-1,-1},{-1,-1},
263 /*50*/  { 1, 0},{ 0, 0},{ 2, 0},{ 2, 0},{-1, 0},{ 1, 0},{ 3, 0},{ 1, 0},
264 /*58*/  { 0, 1},{ 1, 0},{ 0, 2},{ 0, 2},{ 0,-1},{-1,-1},{-1,-1},{-1,-1},
265 /*60*/  { 2, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
266 /*68*/  { 0, 3},{ 0, 3},{ 0, 2},{ 0, 8},{ 0,-1},{ 0,-1},{-1,-1},{-1,-1},
267 /*70*/  { 1, 0},{ 1, 0},{ 1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
268 /*78*/  { 0,-1},{ 0,-1},{-1,-1},{-1,-1},{-1,-1},{ 5, 1},{ 4, 1},{ 4, 1},
269 /*80*/  { 4, 0},{-1, 0},{ 0, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
270 /*88*/  { 0, 5},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
271 /*90*/  { 1, 0},{ 2, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
272 /*98*/  { 0, 1},{ 0, 1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
273 /*a0*/  { 2, 0},{ 2, 0},{ 2, 0},{ 4, 0},{-1, 0},{ 0, 0},{-1, 0},{-1, 0},
274 /*a8*/  { 1, 1},{ 1, 0},{ 3, 0},{ 2, 0},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
275 /*b0*/  {-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
276 /*b8*/  {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
277 /*c0*/  {-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
278 /*c8*/  {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
279 /*d0*/  { 0, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
280 /*d8*/  { 1, 1},{ 1, 1},{-1,-1},{-1,-1},{ 0, 1},{ 0,-1},{-1,-1},{-1,-1},
281 /*e0*/  {-1, 0},{ 4, 0},{ 0, 1},{-1, 0},{-1, 0},{ 4, 0},{-1, 0},{-1, 0},
282 /*e8*/  { 3,-1},{-1,-1},{ 0, 1},{-1,-1},{ 0,-1},{-1,-1},{-1,-1},{ 0, 0},
283 /*f0*/  {-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
284 /*f8*/  {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
285 };
286 
287 static char *pbook_type[] = {
288         "Unknown PowerBook",
289         "PowerBook 2400/3400/3500(G3)",
290         "PowerBook G3 Series",
291         "1999 PowerBook G3",
292         "Core99"
293 };
294 
295 #ifdef CONFIG_PMAC_BACKLIGHT
296 static struct backlight_controller pmu_backlight_controller = {
297         pmu_set_backlight_enable,
298         pmu_set_backlight_level
299 };
300 #endif /* CONFIG_PMAC_BACKLIGHT */
301 
302 int __init find_via_pmu(void)
303 {
304         u64 taddr;
305         u32 *reg;
306 
307         if (via != 0)
308                 return 1;
309         vias = of_find_node_by_name(NULL, "via-pmu");
310         if (vias == NULL)
311                 return 0;
312 
313         reg = (u32 *)get_property(vias, "reg", NULL);
314         if (reg == NULL) {
315                 printk(KERN_ERR "via-pmu: No \"reg\" property !\n");
316                 goto fail;
317         }
318         taddr = of_translate_address(vias, reg);
319         if (taddr == OF_BAD_ADDR) {
320                 printk(KERN_ERR "via-pmu: Can't translate address !\n");
321                 goto fail;
322         }
323 
324         spin_lock_init(&pmu_lock);
325 
326         pmu_has_adb = 1;
327 
328         pmu_intr_mask = PMU_INT_PCEJECT |
329                         PMU_INT_SNDBRT |
330                         PMU_INT_ADB |
331                         PMU_INT_TICK;
332         
333         if (vias->parent->name && ((strcmp(vias->parent->name, "ohare") == 0)
334             || device_is_compatible(vias->parent, "ohare")))
335                 pmu_kind = PMU_OHARE_BASED;
336         else if (device_is_compatible(vias->parent, "paddington"))
337                 pmu_kind = PMU_PADDINGTON_BASED;
338         else if (device_is_compatible(vias->parent, "heathrow"))
339                 pmu_kind = PMU_HEATHROW_BASED;
340         else if (device_is_compatible(vias->parent, "Keylargo")
341                  || device_is_compatible(vias->parent, "K2-Keylargo")) {
342                 struct device_node *gpiop;
343                 u64 gaddr = OF_BAD_ADDR;
344 
345                 pmu_kind = PMU_KEYLARGO_BASED;
346                 pmu_has_adb = (find_type_devices("adb") != NULL);
347                 pmu_intr_mask = PMU_INT_PCEJECT |
348                                 PMU_INT_SNDBRT |
349                                 PMU_INT_ADB |
350                                 PMU_INT_TICK |
351                                 PMU_INT_ENVIRONMENT;
352                 
353                 gpiop = of_find_node_by_name(NULL, "gpio");
354                 if (gpiop) {
355                         reg = (u32 *)get_property(gpiop, "reg", NULL);
356                         if (reg)
357                                 gaddr = of_translate_address(gpiop, reg);
358                         if (gaddr != OF_BAD_ADDR)
359                                 gpio_reg = ioremap(gaddr, 0x10);
360                 }
361                 if (gpio_reg == NULL)
362                         printk(KERN_ERR "via-pmu: Can't find GPIO reg !\n");
363         } else
364                 pmu_kind = PMU_UNKNOWN;
365 
366         via = ioremap(taddr, 0x2000);
367         if (via == NULL) {
368                 printk(KERN_ERR "via-pmu: Can't map address !\n");
369                 goto fail;
370         }
371         
372         out_8(&via[IER], IER_CLR | 0x7f);       /* disable all intrs */
373         out_8(&via[IFR], 0x7f);                 /* clear IFR */
374 
375         pmu_state = idle;
376 
377         if (!init_pmu()) {
378                 via = NULL;
379                 return 0;
380         }
381 
382         printk(KERN_INFO "PMU driver v%d initialized for %s, firmware: %02x\n",
383                PMU_DRIVER_VERSION, pbook_type[pmu_kind], pmu_version);
384                
385         sys_ctrler = SYS_CTRLER_PMU;
386         
387         return 1;
388  fail:
389         of_node_put(vias);
390         vias = NULL;
391         return 0;
392 }
393 
394 #ifdef CONFIG_ADB
395 static int pmu_probe(void)
396 {
397         return vias == NULL? -ENODEV: 0;
398 }
399 
400 static int __init pmu_init(void)
401 {
402         if (vias == NULL)
403                 return -ENODEV;
404         return 0;
405 }
406 #endif /* CONFIG_ADB */
407 
408 /*
409  * We can't wait until pmu_init gets called, that happens too late.
410  * It happens after IDE and SCSI initialization, which can take a few
411  * seconds, and by that time the PMU could have given up on us and
412  * turned us off.
413  * Thus this is called with arch_initcall rather than device_initcall.
414  */
415 static int __init via_pmu_start(void)
416 {
417         if (vias == NULL)
418                 return -ENODEV;
419 
420         bright_req_1.complete = 1;
421         bright_req_2.complete = 1;
422         batt_req.complete = 1;
423 
424 #ifndef CONFIG_PPC_MERGE
425         if (pmu_kind == PMU_KEYLARGO_BASED)
426                 openpic_set_irq_priority(vias->intrs[0].line,
427                                          OPENPIC_PRIORITY_DEFAULT + 1);
428 #endif
429 
430         if (request_irq(vias->intrs[0].line, via_pmu_interrupt, 0, "VIA-PMU",
431                         (void *)0)) {
432                 printk(KERN_ERR "VIA-PMU: can't get irq %d\n",
433                        vias->intrs[0].line);
434                 return -EAGAIN;
435         }
436 
437         if (pmu_kind == PMU_KEYLARGO_BASED) {
438                 gpio_node = of_find_node_by_name(NULL, "extint-gpio1");
439                 if (gpio_node == NULL)
440                         gpio_node = of_find_node_by_name(NULL,
441                                                          "pmu-interrupt");
442                 if (gpio_node && gpio_node->n_intrs > 0)
443                         gpio_irq = gpio_node->intrs[0].line;
444 
445                 if (gpio_irq != -1) {
446                         if (request_irq(gpio_irq, gpio1_interrupt, 0,
447                                         "GPIO1 ADB", (void *)0))
448                                 printk(KERN_ERR "pmu: can't get irq %d"
449                                        " (GPIO1)\n", gpio_irq);
450                         else
451                                 gpio_irq_enabled = 1;
452                 }
453         }
454 
455         /* Enable interrupts */
456         out_8(&via[IER], IER_SET | SR_INT | CB1_INT);
457 
458         pmu_fully_inited = 1;
459 
460         /* Make sure PMU settle down before continuing. This is _very_ important
461          * since the IDE probe may shut interrupts down for quite a bit of time. If
462          * a PMU communication is pending while this happens, the PMU may timeout
463          * Not that on Core99 machines, the PMU keeps sending us environement
464          * messages, we should find a way to either fix IDE or make it call
465          * pmu_suspend() before masking interrupts. This can also happens while
466          * scolling with some fbdevs.
467          */
468         do {
469                 pmu_poll();
470         } while (pmu_state != idle);
471 
472         return 0;
473 }
474 
475 arch_initcall(via_pmu_start);
476 
477 /*
478  * This has to be done after pci_init, which is a subsys_initcall.
479  */
480 static int __init via_pmu_dev_init(void)
481 {
482         if (vias == NULL)
483                 return -ENODEV;
484 
485 #ifdef CONFIG_PMAC_BACKLIGHT
486         /* Enable backlight */
487         register_backlight_controller(&pmu_backlight_controller, NULL, "pmu");
488 #endif /* CONFIG_PMAC_BACKLIGHT */
489 
490 #ifdef CONFIG_PPC32
491         if (machine_is_compatible("AAPL,3400/2400") ||
492                 machine_is_compatible("AAPL,3500")) {
493                 int mb = pmac_call_feature(PMAC_FTR_GET_MB_INFO,
494                         NULL, PMAC_MB_INFO_MODEL, 0);
495                 pmu_battery_count = 1;
496                 if (mb == PMAC_TYPE_COMET)
497                         pmu_batteries[0].flags |= PMU_BATT_TYPE_COMET;
498                 else
499                         pmu_batteries[0].flags |= PMU_BATT_TYPE_HOOPER;
500         } else if (machine_is_compatible("AAPL,PowerBook1998") ||
501                 machine_is_compatible("PowerBook1,1")) {
502                 pmu_battery_count = 2;
503                 pmu_batteries[0].flags |= PMU_BATT_TYPE_SMART;
504                 pmu_batteries[1].flags |= PMU_BATT_TYPE_SMART;
505         } else {
506                 struct device_node* prim = find_devices("power-mgt");
507                 u32 *prim_info = NULL;
508                 if (prim)
509                         prim_info = (u32 *)get_property(prim, "prim-info", NULL);
510                 if (prim_info) {
511                         /* Other stuffs here yet unknown */
512                         pmu_battery_count = (prim_info[6] >> 16) & 0xff;
513                         pmu_batteries[0].flags |= PMU_BATT_TYPE_SMART;
514                         if (pmu_battery_count > 1)
515                                 pmu_batteries[1].flags |= PMU_BATT_TYPE_SMART;
516                 }
517         }
518 #endif /* CONFIG_PPC32 */
519 
520         /* Create /proc/pmu */
521         proc_pmu_root = proc_mkdir("pmu", NULL);
522         if (proc_pmu_root) {
523                 long i;
524 
525                 for (i=0; i<pmu_battery_count; i++) {
526                         char title[16];
527                         sprintf(title, "battery_%ld", i);
528                         proc_pmu_batt[i] = create_proc_read_entry(title, 0, proc_pmu_root,
529                                                 proc_get_batt, (void *)i);
530                 }
531 
532                 proc_pmu_info = create_proc_read_entry("info", 0, proc_pmu_root,
533                                         proc_get_info, NULL);
534                 proc_pmu_irqstats = create_proc_read_entry("interrupts", 0, proc_pmu_root,
535                                         proc_get_irqstats, NULL);
536                 proc_pmu_options = create_proc_entry("options", 0600, proc_pmu_root);
537                 if (proc_pmu_options) {
538                         proc_pmu_options->nlink = 1;
539                         proc_pmu_options->read_proc = proc_read_options;
540                         proc_pmu_options->write_proc = proc_write_options;
541                 }
542         }
543         return 0;
544 }
545 
546 device_initcall(via_pmu_dev_init);
547 
548 static int
549 init_pmu(void)
550 {
551         int timeout;
552         struct adb_request req;
553 
554         out_8(&via[B], via[B] | TREQ);                  /* negate TREQ */
555         out_8(&via[DIRB], (via[DIRB] | TREQ) & ~TACK);  /* TACK in, TREQ out */
556 
557         pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, pmu_intr_mask);
558         timeout =  100000;
559         while (!req.complete) {
560                 if (--timeout < 0) {
561                         printk(KERN_ERR "init_pmu: no response from PMU\n");
562                         return 0;
563                 }
564                 udelay(10);
565                 pmu_poll();
566         }
567 
568         /* ack all pending interrupts */
569         timeout = 100000;
570         interrupt_data[0][0] = 1;
571         while (interrupt_data[0][0] || pmu_state != idle) {
572                 if (--timeout < 0) {
573                         printk(KERN_ERR "init_pmu: timed out acking intrs\n");
574                         return 0;
575                 }
576                 if (pmu_state == idle)
577                         adb_int_pending = 1;
578                 via_pmu_interrupt(0, NULL, NULL);
579                 udelay(10);
580         }
581 
582         /* Tell PMU we are ready.  */
583         if (pmu_kind == PMU_KEYLARGO_BASED) {
584                 pmu_request(&req, NULL, 2, PMU_SYSTEM_READY, 2);
585                 while (!req.complete)
586                         pmu_poll();
587         }
588 
589         /* Read PMU version */
590         pmu_request(&req, NULL, 1, PMU_GET_VERSION);
591         pmu_wait_complete(&req);
592         if (req.reply_len > 0)
593                 pmu_version = req.reply[0];
594         
595         /* Read server mode setting */
596         if (pmu_kind == PMU_KEYLARGO_BASED) {
597                 pmu_request(&req, NULL, 2, PMU_POWER_EVENTS,
598                             PMU_PWR_GET_POWERUP_EVENTS);
599                 pmu_wait_complete(&req);
600                 if (req.reply_len == 2) {
601                         if (req.reply[1] & PMU_PWR_WAKEUP_AC_INSERT)
602                                 option_server_mode = 1;
603                         printk(KERN_INFO "via-pmu: Server Mode is %s\n",
604                                option_server_mode ? "enabled" : "disabled");
605                 }
606         }
607         return 1;
608 }
609 
610 int
611 pmu_get_model(void)
612 {
613         return pmu_kind;
614 }
615 
616 static void pmu_set_server_mode(int server_mode)
617 {
618         struct adb_request req;
619 
620         if (pmu_kind != PMU_KEYLARGO_BASED)
621                 return;
622 
623         option_server_mode = server_mode;
624         pmu_request(&req, NULL, 2, PMU_POWER_EVENTS, PMU_PWR_GET_POWERUP_EVENTS);
625         pmu_wait_complete(&req);
626         if (req.reply_len < 2)
627                 return;
628         if (server_mode)
629                 pmu_request(&req, NULL, 4, PMU_POWER_EVENTS,
630                             PMU_PWR_SET_POWERUP_EVENTS,
631                             req.reply[0], PMU_PWR_WAKEUP_AC_INSERT); 
632         else
633                 pmu_request(&req, NULL, 4, PMU_POWER_EVENTS,
634                             PMU_PWR_CLR_POWERUP_EVENTS,
635                             req.reply[0], PMU_PWR_WAKEUP_AC_INSERT); 
636         pmu_wait_complete(&req);
637 }
638 
639 /* This new version of the code for 2400/3400/3500 powerbooks
640  * is inspired from the implementation in gkrellm-pmu
641  */
642 static void
643 done_battery_state_ohare(struct adb_request* req)
644 {
645         /* format:
646          *  [0]    :  flags
647          *    0x01 :  AC indicator
648          *    0x02 :  charging
649          *    0x04 :  battery exist
650          *    0x08 :  
651          *    0x10 :  
652          *    0x20 :  full charged
653          *    0x40 :  pcharge reset
654          *    0x80 :  battery exist
655          *
656          *  [1][2] :  battery voltage
657          *  [3]    :  CPU temperature
658          *  [4]    :  battery temperature
659          *  [5]    :  current
660          *  [6][7] :  pcharge
661          *              --tkoba
662          */
663         unsigned int bat_flags = PMU_BATT_TYPE_HOOPER;
664         long pcharge, charge, vb, vmax, lmax;
665         long vmax_charging, vmax_charged;
666         long amperage, voltage, time, max;
667         int mb = pmac_call_feature(PMAC_FTR_GET_MB_INFO,
668                         NULL, PMAC_MB_INFO_MODEL, 0);
669 
670         if (req->reply[0] & 0x01)
671                 pmu_power_flags |= PMU_PWR_AC_PRESENT;
672         else
673                 pmu_power_flags &= ~PMU_PWR_AC_PRESENT;
674         
675         if (mb == PMAC_TYPE_COMET) {
676                 vmax_charged = 189;
677                 vmax_charging = 213;
678                 lmax = 6500;
679         } else {
680                 vmax_charged = 330;
681                 vmax_charging = 330;
682                 lmax = 6500;
683         }
684         vmax = vmax_charged;
685 
686         /* If battery installed */
687         if (req->reply[0] & 0x04) {
688                 bat_flags |= PMU_BATT_PRESENT;
689                 if (req->reply[0] & 0x02)
690                         bat_flags |= PMU_BATT_CHARGING;
691                 vb = (req->reply[1] << 8) | req->reply[2];
692                 voltage = (vb * 265 + 72665) / 10;
693                 amperage = req->reply[5];
694                 if ((req->reply[0] & 0x01) == 0) {
695                         if (amperage > 200)
696                                 vb += ((amperage - 200) * 15)/100;
697                 } else if (req->reply[0] & 0x02) {
698                         vb = (vb * 97) / 100;
699                         vmax = vmax_charging;
700                 }
701                 charge = (100 * vb) / vmax;
702                 if (req->reply[0] & 0x40) {
703                         pcharge = (req->reply[6] << 8) + req->reply[7];
704                         if (pcharge > lmax)
705                                 pcharge = lmax;
706                         pcharge *= 100;
707                         pcharge = 100 - pcharge / lmax;
708                         if (pcharge < charge)
709                                 charge = pcharge;
710                 }
711                 if (amperage > 0)
712                         time = (charge * 16440) / amperage;
713                 else
714                         time = 0;
715                 max = 100;
716                 amperage = -amperage;
717         } else
718                 charge = max = amperage = voltage = time = 0;
719 
720         pmu_batteries[pmu_cur_battery].flags = bat_flags;
721         pmu_batteries[pmu_cur_battery].charge = charge;
722         pmu_batteries[pmu_cur_battery].max_charge = max;
723         pmu_batteries[pmu_cur_battery].amperage = amperage;
724         pmu_batteries[pmu_cur_battery].voltage = voltage;
725         pmu_batteries[pmu_cur_battery].time_remaining = time;
726 
727         clear_bit(0, &async_req_locks);
728 }
729 
730 static void
731 done_battery_state_smart(struct adb_request* req)
732 {
733         /* format:
734          *  [0] : format of this structure (known: 3,4,5)
735          *  [1] : flags
736          *  
737          *  format 3 & 4:
738          *  
739          *  [2] : charge
740          *  [3] : max charge
741          *  [4] : current
742          *  [5] : voltage
743          *  
744          *  format 5:
745          *  
746          *  [2][3] : charge
747          *  [4][5] : max charge
748          *  [6][7] : current
749          *  [8][9] : voltage
750          */
751          
752         unsigned int bat_flags = PMU_BATT_TYPE_SMART;
753         int amperage;
754         unsigned int capa, max, voltage;
755         
756         if (req->reply[1] & 0x01)
757                 pmu_power_flags |= PMU_PWR_AC_PRESENT;
758         else
759                 pmu_power_flags &= ~PMU_PWR_AC_PRESENT;
760 
761 
762         capa = max = amperage = voltage = 0;
763         
764         if (req->reply[1] & 0x04) {
765                 bat_flags |= PMU_BATT_PRESENT;
766                 switch(req->reply[0]) {
767                         case 3:
768                         case 4: capa = req->reply[2];
769                                 max = req->reply[3];
770                                 amperage = *((signed char *)&req->reply[4]);
771                                 voltage = req->reply[5];
772                                 break;
773                         case 5: capa = (req->reply[2] << 8) | req->reply[3];
774                                 max = (req->reply[4] << 8) | req->reply[5];
775                                 amperage = *((signed short *)&req->reply[6]);
776                                 voltage = (req->reply[8] << 8) | req->reply[9];
777                                 break;
778                         default:
779                                 printk(KERN_WARNING "pmu.c : unrecognized battery info, len: %d, %02x %02x %02x %02x\n",
780                                         req->reply_len, req->reply[0], req->reply[1], req->reply[2], req->reply[3]);
781                                 break;
782                 }
783         }
784 
785         if ((req->reply[1] & 0x01) && (amperage > 0))
786                 bat_flags |= PMU_BATT_CHARGING;
787 
788         pmu_batteries[pmu_cur_battery].flags = bat_flags;
789         pmu_batteries[pmu_cur_battery].charge = capa;
790         pmu_batteries[pmu_cur_battery].max_charge = max;
791         pmu_batteries[pmu_cur_battery].amperage = amperage;
792         pmu_batteries[pmu_cur_battery].voltage = voltage;
793         if (amperage) {
794                 if ((req->reply[1] & 0x01) && (amperage > 0))
795                         pmu_batteries[pmu_cur_battery].time_remaining
796                                 = ((max-capa) * 3600) / amperage;
797                 else
798                         pmu_batteries[pmu_cur_battery].time_remaining
799                                 = (capa * 3600) / (-amperage);
800         } else
801                 pmu_batteries[pmu_cur_battery].time_remaining = 0;
802 
803         pmu_cur_battery = (pmu_cur_battery + 1) % pmu_battery_count;
804 
805         clear_bit(0, &async_req_locks);
806 }
807 
808 static void
809 query_battery_state(void)
810 {
811         if (test_and_set_bit(0, &async_req_locks))
812                 return;
813         if (pmu_kind == PMU_OHARE_BASED)
814                 pmu_request(&batt_req, done_battery_state_ohare,
815                         1, PMU_BATTERY_STATE);
816         else
817                 pmu_request(&batt_req, done_battery_state_smart,
818                         2, PMU_SMART_BATTERY_STATE, pmu_cur_battery+1);
819 }
820 
821 static int
822 proc_get_info(char *page, char **start, off_t off,
823                 int count, int *eof, void *data)
824 {
825         char* p = page;
826 
827         p += sprintf(p, "PMU driver version     : %d\n", PMU_DRIVER_VERSION);
828         p += sprintf(p, "PMU firmware version   : %02x\n", pmu_version);
829         p += sprintf(p, "AC Power               : %d\n",
830                 ((pmu_power_flags & PMU_PWR_AC_PRESENT) != 0) || pmu_battery_count == 0);
831         p += sprintf(p, "Battery count          : %d\n", pmu_battery_count);
832 
833         return p - page;
834 }
835 
836 static int
837 proc_get_irqstats(char *page, char **start, off_t off,
838                   int count, int *eof, void *data)
839 {
840         int i;
841         char* p = page;
842         static const char *irq_names[] = {
843                 "Total CB1 triggered events",
844                 "Total GPIO1 triggered events",
845                 "PC-Card eject button",
846                 "Sound/Brightness button",
847                 "ADB message",
848                 "Battery state change",
849                 "Environment interrupt",
850                 "Tick timer",
851                 "Ghost interrupt (zero len)",
852                 "Empty interrupt (empty mask)",
853                 "Max irqs in a row"
854         };
855 
856         for (i=0; i<11; i++) {
857                 p += sprintf(p, " %2u: %10u (%s)\n",
858                              i, pmu_irq_stats[i], irq_names[i]);
859         }
860         return p - page;
861 }
862 
863 static int
864 proc_get_batt(char *page, char **start, off_t off,
865                 int count, int *eof, void *data)
866 {
867         long batnum = (long)data;
868         char *p = page;
869         
870         p += sprintf(p, "\n");
871         p += sprintf(p, "flags      : %08x\n",
872                 pmu_batteries[batnum].flags);
873         p += sprintf(p, "charge     : %d\n",
874                 pmu_batteries[batnum].charge);
875         p += sprintf(p, "max_charge : %d\n",
876                 pmu_batteries[batnum].max_charge);
877         p += sprintf(p, "current    : %d\n",
878                 pmu_batteries[batnum].amperage);
879         p += sprintf(p, "voltage    : %d\n",
880                 pmu_batteries[batnum].voltage);
881         p += sprintf(p, "time rem.  : %d\n",
882                 pmu_batteries[batnum].time_remaining);
883 
884         return p - page;
885 }
886 
887 static int
888 proc_read_options(char *page, char **start, off_t off,
889                         int count, int *eof, void *data)
890 {
891         char *p = page;
892 
893 #if defined(CONFIG_PM) && defined(CONFIG_PPC32)
894         if (pmu_kind == PMU_KEYLARGO_BASED &&
895             pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0)
896                 p += sprintf(p, "lid_wakeup=%d\n", option_lid_wakeup);
897 #endif
898         if (pmu_kind == PMU_KEYLARGO_BASED)
899                 p += sprintf(p, "server_mode=%d\n", option_server_mode);
900 
901         return p - page;
902 }
903                         
904 static int
905 proc_write_options(struct file *file, const char __user *buffer,
906                         unsigned long count, void *data)
907 {
908         char tmp[33];
909         char *label, *val;
910         unsigned long fcount = count;
911         
912         if (!count)
913                 return -EINVAL;
914         if (count > 32)
915                 count = 32;
916         if (copy_from_user(tmp, buffer, count))
917                 return -EFAULT;
918         tmp[count] = 0;
919 
920         label = tmp;
921         while(*label == ' ')
922                 label++;
923         val = label;
924         while(*val && (*val != '=')) {
925                 if (*val == ' ')
926                         *val = 0;
927                 val++;
928         }
929         if ((*val) == 0)
930                 return -EINVAL;
931         *(val++) = 0;