2 * Device driver for the via-pmu on Apple Powermacs.
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.
11 * Copyright (C) 1998 Paul Mackerras and Fabio Riccardi.
14 #include <linux/config.h>
15 #include <linux/types.h>
16 #include <linux/errno.h>
17 #include <linux/kernel.h>
18 #include <linux/delay.h>
19 #include <linux/sched.h>
20 #include <linux/miscdevice.h>
21 #include <linux/blkdev.h>
22 #include <linux/pci.h>
23 #include <linux/malloc.h>
29 #include <asm/pgtable.h>
30 #include <asm/system.h>
34 /* Misc minor number allocated for /dev/pmu */
37 static volatile unsigned char *via
;
39 /* VIA registers - spaced 0x200 bytes apart */
40 #define RS 0x200 /* skip between registers */
41 #define B 0 /* B-side data */
42 #define A RS /* A-side data */
43 #define DIRB (2*RS) /* B-side direction (1=output) */
44 #define DIRA (3*RS) /* A-side direction (1=output) */
45 #define T1CL (4*RS) /* Timer 1 ctr/latch (low 8 bits) */
46 #define T1CH (5*RS) /* Timer 1 counter (high 8 bits) */
47 #define T1LL (6*RS) /* Timer 1 latch (low 8 bits) */
48 #define T1LH (7*RS) /* Timer 1 latch (high 8 bits) */
49 #define T2CL (8*RS) /* Timer 2 ctr/latch (low 8 bits) */
50 #define T2CH (9*RS) /* Timer 2 counter (high 8 bits) */
51 #define SR (10*RS) /* Shift register */
52 #define ACR (11*RS) /* Auxiliary control register */
53 #define PCR (12*RS) /* Peripheral control register */
54 #define IFR (13*RS) /* Interrupt flag register */
55 #define IER (14*RS) /* Interrupt enable register */
56 #define ANH (15*RS) /* A-side data, no handshake */
58 /* Bits in B data register: both active low */
59 #define TACK 0x08 /* Transfer acknowledge (input) */
60 #define TREQ 0x10 /* Transfer request (output) */
63 #define SR_CTRL 0x1c /* Shift register control bits */
64 #define SR_EXT 0x0c /* Shift on external clock */
65 #define SR_OUT 0x10 /* Shift out if 1 */
67 /* Bits in IFR and IER */
68 #define IER_SET 0x80 /* set bits in IER */
69 #define IER_CLR 0 /* clear bits in IER */
70 #define SR_INT 0x04 /* Shift register full/empty */
71 #define CB1_INT 0x10 /* transition on CB1 input */
73 static enum pmu_state
{
81 static struct adb_request
*current_req
;
82 static struct adb_request
*last_req
;
83 static struct adb_request
*req_awaiting_reply
;
84 static unsigned char interrupt_data
[32];
85 static unsigned char *reply_ptr
;
86 static int data_index
;
88 static int adb_int_pending
;
89 static int pmu_adb_flags
;
90 static int adb_dev_map
= 0;
91 static struct adb_request bright_req_1
, bright_req_2
;
92 static struct device_node
*vias
;
95 struct notifier_block
*sleep_notifier_list
;
97 static int init_pmu(void);
98 static int pmu_queue_request(struct adb_request
*req
);
99 static void pmu_start(void);
100 static void via_pmu_interrupt(int irq
, void *arg
, struct pt_regs
*regs
);
101 static int pmu_adb_send_request(struct adb_request
*req
, int sync
);
102 static int pmu_adb_autopoll(int on
);
103 static void send_byte(int x
);
104 static void recv_byte(void);
105 static void pmu_sr_intr(struct pt_regs
*regs
);
106 static void pmu_done(struct adb_request
*req
);
107 static void pmu_handle_data(unsigned char *data
, int len
,
108 struct pt_regs
*regs
);
109 static void set_brightness(int level
);
110 static void set_volume(int level
);
113 * This table indicates for each PMU opcode:
114 * - the number of data bytes to be sent with the command, or -1
115 * if a length byte should be sent,
116 * - the number of response bytes which the PMU will return, or
117 * -1 if it will send a length byte.
119 static s8 pmu_data_len
[256][2] = {
120 /* 0 1 2 3 4 5 6 7 */
121 /*00*/ {-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
122 /*08*/ {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
123 /*10*/ { 1, 0},{ 1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
124 /*18*/ { 0, 1},{ 0, 1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{ 0, 0},
125 /*20*/ {-1, 0},{ 0, 0},{ 2, 0},{ 1, 0},{ 1, 0},{-1, 0},{-1, 0},{-1, 0},
126 /*28*/ { 0,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
127 /*30*/ { 4, 0},{20, 0},{ 2, 0},{ 3, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
128 /*38*/ { 0, 4},{ 0,20},{ 1, 1},{ 2, 1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
129 /*40*/ { 1, 0},{ 1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
130 /*48*/ { 0, 1},{ 0, 1},{-1,-1},{-1,-1},{ 1, 0},{-1,-1},{-1,-1},{-1,-1},
131 /*50*/ { 1, 0},{ 0, 0},{ 2, 0},{ 2, 0},{-1, 0},{ 1, 0},{ 3, 0},{ 1, 0},
132 /*58*/ { 0, 1},{ 1, 0},{ 0, 2},{ 0, 2},{ 0,-1},{-1,-1},{-1,-1},{-1,-1},
133 /*60*/ { 2, 0},{-1, 0},{ 2, 0},{ 0, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
134 /*68*/ { 0, 3},{ 0, 3},{ 0, 2},{ 0, 8},{ 0,-1},{ 0,-1},{-1,-1},{-1,-1},
135 /*70*/ { 1, 0},{ 1, 0},{ 1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
136 /*78*/ { 0,-1},{ 0,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{ 4, 1},{ 4, 1},
137 /*80*/ { 4, 0},{-1, 0},{ 0, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
138 /*88*/ { 0, 5},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
139 /*90*/ { 1, 0},{ 2, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
140 /*98*/ { 0, 1},{ 0, 1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
141 /*a0*/ { 2, 0},{ 2, 0},{ 2, 0},{ 4, 0},{-1, 0},{ 0, 0},{-1, 0},{-1, 0},
142 /*a8*/ { 1, 1},{ 1, 0},{ 3, 0},{ 2, 0},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
143 /*b0*/ {-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
144 /*b8*/ {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
145 /*c0*/ {-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
146 /*c8*/ {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
147 /*d0*/ { 0, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
148 /*d8*/ { 1, 1},{ 1, 1},{-1,-1},{-1,-1},{ 0, 1},{ 0,-1},{-1,-1},{-1,-1},
149 /*e0*/ {-1, 0},{ 4, 0},{ 0, 1},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
150 /*e8*/ { 3,-1},{-1,-1},{ 0, 1},{-1,-1},{ 0,-1},{-1,-1},{-1,-1},{ 0, 0},
151 /*f0*/ {-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
152 /*f8*/ {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
160 vias
= find_devices("via-pmu");
164 printk(KERN_WARNING
"Warning: only using 1st via-pmu\n");
169 printk("via_pmu_init: node = %p, addrs =", vias
->node
);
170 for (i
= 0; i
< vias
->n_addrs
; ++i
)
171 printk(" %x(%x)", vias
->addrs
[i
].address
, vias
->addrs
[i
].size
);
173 for (i
= 0; i
< vias
->n_intrs
; ++i
)
174 printk(" %x", vias
->intrs
[i
].line
);
178 if (vias
->n_addrs
!= 1 || vias
->n_intrs
!= 1) {
179 printk(KERN_ERR
"via-pmu: %d addresses, %d interrupts!\n",
180 vias
->n_addrs
, vias
->n_intrs
);
181 if (vias
->n_addrs
< 1 || vias
->n_intrs
< 1)
184 via
= (volatile unsigned char *) ioremap(vias
->addrs
->address
, 0x2000);
186 out_8(&via
[IER
], IER_CLR
| 0x7f); /* disable all intrs */
193 adb_hardware
= ADB_VIAPMU
;
202 bright_req_1
.complete
= 1;
203 bright_req_2
.complete
= 1;
205 if (request_irq(vias
->intrs
[0].line
, via_pmu_interrupt
, 0, "VIA-PMU",
207 printk(KERN_ERR
"VIA-PMU: can't get irq %d\n",
208 vias
->intrs
[0].line
);
212 /* Enable interrupts */
213 out_8(&via
[IER
], IER_SET
| SR_INT
| CB1_INT
);
215 /* Set function pointers */
216 adb_send_request
= pmu_adb_send_request
;
217 adb_autopoll
= pmu_adb_autopoll
;
224 struct adb_request req
;
226 out_8(&via
[B
], via
[B
] | TREQ
); /* negate TREQ */
227 out_8(&via
[DIRB
], (via
[DIRB
] | TREQ
) & ~TACK
); /* TACK in, TREQ out */
229 pmu_request(&req
, NULL
, 2, PMU_SET_INTR_MASK
, 0xff);
231 while (!req
.complete
) {
233 printk(KERN_ERR
"init_pmu: no response from PMU\n");
240 /* ack all pending interrupts */
242 interrupt_data
[0] = 1;
243 while (interrupt_data
[0] || pmu_state
!= idle
) {
245 printk(KERN_ERR
"init_pmu: timed out acking intrs\n");
248 if (pmu_state
== idle
)
250 via_pmu_interrupt(0, 0, 0);
257 /* Send an ADB command */
259 pmu_adb_send_request(struct adb_request
*req
, int sync
)
263 for (i
= req
->nbytes
- 1; i
> 0; --i
)
264 req
->data
[i
+3] = req
->data
[i
];
265 req
->data
[3] = req
->nbytes
- 1;
266 req
->data
[2] = pmu_adb_flags
;
267 req
->data
[1] = req
->data
[0];
268 req
->data
[0] = PMU_ADB_CMD
;
270 req
->reply_expected
= 1;
272 i
= pmu_queue_request(req
);
276 while (!req
->complete
)
282 /* Enable/disable autopolling */
284 pmu_adb_autopoll(int on
)
286 struct adb_request req
;
289 pmu_request(&req
, NULL
, 5, PMU_ADB_CMD
, 0, 0x86,
290 adb_dev_map
>> 8, adb_dev_map
);
293 pmu_request(&req
, NULL
, 1, PMU_ADB_POLL_OFF
);
296 while (!req
.complete
)
301 /* Construct and send a pmu request */
303 pmu_request(struct adb_request
*req
, void (*done
)(struct adb_request
*),
309 if (nbytes
< 0 || nbytes
> 32) {
310 printk(KERN_ERR
"pmu_request: bad nbytes (%d)\n", nbytes
);
314 req
->nbytes
= nbytes
;
316 va_start(list
, nbytes
);
317 for (i
= 0; i
< nbytes
; ++i
)
318 req
->data
[i
] = va_arg(list
, int);
320 if (pmu_data_len
[req
->data
[0]][1] != 0) {
321 req
->reply
[0] = ADB_RET_OK
;
325 req
->reply_expected
= 0;
326 return pmu_queue_request(req
);
330 * This procedure handles requests written to /dev/adb where the
331 * first byte is CUDA_PACKET or PMU_PACKET. For CUDA_PACKET, we
332 * emulate a few CUDA requests.
335 pmu_send_request(struct adb_request
*req
)
339 switch (req
->data
[0]) {
341 for (i
= 0; i
< req
->nbytes
- 1; ++i
)
342 req
->data
[i
] = req
->data
[i
+1];
344 if (pmu_data_len
[req
->data
[0]][1] != 0) {
345 req
->reply
[0] = ADB_RET_OK
;
349 return pmu_queue_request(req
);
351 switch (req
->data
[1]) {
353 if (req
->nbytes
!= 2)
355 req
->data
[0] = PMU_READ_RTC
;
358 req
->reply
[0] = CUDA_PACKET
;
360 req
->reply
[2] = CUDA_GET_TIME
;
361 return pmu_queue_request(req
);
363 if (req
->nbytes
!= 6)
365 req
->data
[0] = PMU_SET_RTC
;
367 for (i
= 1; i
<= 4; ++i
)
368 req
->data
[i
] = req
->data
[i
+1];
370 return pmu_queue_request(req
);
378 pmu_queue_request(struct adb_request
*req
)
387 if (req
->nbytes
<= 0) {
391 nsend
= pmu_data_len
[req
->data
[0]][0];
392 if (nsend
>= 0 && req
->nbytes
!= nsend
+ 1) {
400 save_flags(flags
); cli();
402 if (current_req
!= 0) {
403 last_req
->next
= req
;
408 if (pmu_state
== idle
)
412 restore_flags(flags
);
419 out_8(&via
[ACR
], 0x1c);
421 out_8(&via
[B
], via
[B
] & ~0x10); /* assert TREQ */
427 out_8(&via
[ACR
], 0x0c);
428 in_8(&via
[SR
]); /* resets SR */
429 out_8(&via
[B
], via
[B
] & ~0x10);
436 struct adb_request
*req
;
438 /* assert pmu_state == idle */
439 /* get the packet to send */
440 save_flags(flags
); cli();
442 if (req
== 0 || pmu_state
!= idle
443 || (req
->reply_expected
&& req_awaiting_reply
))
448 data_len
= pmu_data_len
[req
->data
[0]][0];
450 /* set the shift register to shift out and send a byte */
451 send_byte(req
->data
[0]);
454 restore_flags(flags
);
462 ie
= _disable_interrupts();
463 if (via
[IFR
] & (SR_INT
| CB1_INT
))
464 via_pmu_interrupt(0, 0, 0);
465 _enable_interrupts(ie
);
469 via_pmu_interrupt(int irq
, void *arg
, struct pt_regs
*regs
)
474 while ((intr
= (in_8(&via
[IFR
]) & (SR_INT
| CB1_INT
))) != 0) {
475 if (++nloop
> 1000) {
476 printk(KERN_DEBUG
"PMU: stuck in intr loop, "
477 "intr=%x pmu_state=%d\n", intr
, pmu_state
);
482 else if (intr
& CB1_INT
) {
484 out_8(&via
[IFR
], CB1_INT
);
487 if (pmu_state
== idle
) {
488 if (adb_int_pending
) {
490 send_byte(PMU_INT_ACK
);
492 } else if (current_req
) {
499 pmu_sr_intr(struct pt_regs
*regs
)
501 struct adb_request
*req
;
505 printk(KERN_DEBUG
"PMU: sr_intr but ack still high! (%x)\n",
508 /* if reading grab the byte, and reset the interrupt */
509 if ((via
[ACR
] & SR_OUT
) == 0)
510 bite
= in_8(&via
[SR
]);
511 out_8(&via
[IFR
], SR_INT
);
513 /* reset TREQ and wait for TACK to go high */
514 out_8(&via
[B
], via
[B
] | TREQ
);
516 while ((in_8(&via
[B
]) & TACK
) == 0) {
518 printk(KERN_ERR
"PMU not responding (!ack)\n");
528 data_len
= req
->nbytes
- 1;
532 if (data_index
<= data_len
) {
533 send_byte(req
->data
[data_index
++]);
537 data_len
= pmu_data_len
[req
->data
[0]][1];
540 current_req
= req
->next
;
541 if (req
->reply_expected
)
542 req_awaiting_reply
= req
;
548 reply_ptr
= req
->reply
+ req
->reply_len
;
556 pmu_state
= reading_intr
;
557 reply_ptr
= interrupt_data
;
563 if (data_len
== -1) {
566 printk(KERN_ERR
"PMU: bad reply len %d\n",
569 reply_ptr
[data_index
++] = bite
;
571 if (data_index
< data_len
) {
576 if (pmu_state
== reading_intr
) {
577 pmu_handle_data(interrupt_data
, data_index
, regs
);
580 current_req
= req
->next
;
581 req
->reply_len
+= data_index
;
589 printk(KERN_ERR
"via_pmu_interrupt: unknown state %d?\n",
595 pmu_done(struct adb_request
*req
)
602 /* Interrupt data could be the result data from an ADB cmd */
604 pmu_handle_data(unsigned char *data
, int len
, struct pt_regs
*regs
)
606 static int show_pmu_ints
= 1;
613 if (data
[0] & PMU_INT_ADB
) {
614 if ((data
[0] & PMU_INT_ADB_AUTO
) == 0) {
615 struct adb_request
*req
= req_awaiting_reply
;
617 printk(KERN_ERR
"PMU: extra ADB reply\n");
620 req_awaiting_reply
= 0;
624 memcpy(req
->reply
, data
+ 1, len
- 1);
625 req
->reply_len
= len
- 1;
629 adb_input(data
+1, len
-1, regs
, 1);
632 if (data
[0] == 0x08 && len
== 3) {
633 /* sound/brightness buttons pressed */
634 set_brightness(data
[1]);
636 } else if (show_pmu_ints
637 && !(data
[0] == PMU_INT_TICK
&& len
== 1)) {
639 printk(KERN_DEBUG
"pmu intr");
640 for (i
= 0; i
< len
; ++i
)
641 printk(" %.2x", data
[i
]);
647 int backlight_bright
= -1;
648 int backlight_enabled
= 0;
650 #define LEVEL_TO_BRIGHT(lev) ((lev) < 8? 0x7f: 0x4a - ((lev) >> 2))
653 pmu_enable_backlight(int on
)
655 struct adb_request req
;
658 if (backlight_bright
< 0) {
659 pmu_request(&req
, NULL
, 2, 0xd9, 0);
660 while (!req
.complete
)
662 backlight_bright
= LEVEL_TO_BRIGHT(req
.reply
[1]);
664 pmu_request(&req
, NULL
, 2, PMU_BACKLIGHT_BRIGHT
,
666 while (!req
.complete
)
669 pmu_request(&req
, NULL
, 2, PMU_BACKLIGHT_CTRL
, on
? 0x81: 1);
670 while (!req
.complete
)
672 backlight_enabled
= on
;
676 set_brightness(int level
)
678 backlight_bright
= LEVEL_TO_BRIGHT(level
);
679 if (!backlight_enabled
)
681 if (bright_req_1
.complete
)
682 pmu_request(&bright_req_1
, NULL
, 2, PMU_BACKLIGHT_BRIGHT
,
684 if (bright_req_2
.complete
)
685 pmu_request(&bright_req_2
, NULL
, 2, PMU_BACKLIGHT_CTRL
,
686 backlight_bright
< 0x7f? 0x81: 1);
690 set_volume(int level
)
694 #ifdef CONFIG_PMAC_PBOOK
697 * This struct is used to store config register values for
698 * PCI devices which may get powered off when we sleep.
700 static struct pci_save
{
705 static int n_pbook_pci_saves
;
715 for (pd
= pci_devices
; pd
!= NULL
; pd
= pd
->next
)
717 n_pbook_pci_saves
= npci
;
720 ps
= (struct pci_save
*) kmalloc(npci
* sizeof(*ps
), GFP_KERNEL
);
721 pbook_pci_saves
= ps
;
725 for (pd
= pci_devices
; pd
!= NULL
&& npci
!= 0; pd
= pd
->next
) {
726 pci_read_config_word(pd
, PCI_COMMAND
, &ps
->command
);
727 pci_read_config_word(pd
, PCI_CACHE_LINE_SIZE
, &ps
->cache_lat
);
728 pci_read_config_word(pd
, PCI_INTERRUPT_LINE
, &ps
->intr
);
735 pbook_pci_restore(void)
738 struct pci_save
*ps
= pbook_pci_saves
;
742 for (pd
= pci_devices
; pd
!= NULL
; pd
= pd
->next
, ++ps
) {
743 if (ps
->command
== 0)
745 pci_read_config_word(pd
, PCI_COMMAND
, &cmd
);
746 if ((ps
->command
& ~cmd
) == 0)
748 switch (pd
->hdr_type
) {
749 case PCI_HEADER_TYPE_NORMAL
:
750 for (j
= 0; j
< 6; ++j
)
751 pci_write_config_dword(pd
,
752 PCI_BASE_ADDRESS_0
+ j
*4,
753 pd
->base_address
[j
]);
754 pci_write_config_dword(pd
, PCI_ROM_ADDRESS
,
756 pci_write_config_word(pd
, PCI_CACHE_LINE_SIZE
,
758 pci_write_config_word(pd
, PCI_INTERRUPT_LINE
,
760 pci_write_config_word(pd
, PCI_COMMAND
, ps
->command
);
762 /* other header types not restored at present */
768 * Put the powerbook to sleep.
770 #define IRQ_ENABLE ((unsigned int *)0xf3000024)
771 #define MEM_CTRL ((unsigned int *)0xf8000070)
773 int powerbook_sleep(void)
776 static int save_backlight
;
777 static unsigned int save_irqen
;
780 unsigned long p
, wait
;
781 struct adb_request sleep_req
;
783 /* Notify device drivers */
784 ret
= notifier_call_chain(&sleep_notifier_list
, PBOOK_SLEEP
, NULL
);
785 if (ret
& NOTIFY_STOP_MASK
)
788 /* Sync the disks. */
789 /* XXX It would be nice to have some way to ensure that
790 * nobody is dirtying any new buffers while we wait. */
793 /* Turn off the display backlight */
794 save_backlight
= backlight_enabled
;
796 pmu_enable_backlight(0);
798 /* Give the disks a little time to actually finish writing */
799 for (wait
= jiffies
+ (HZ
/4); jiffies
< wait
; )
802 /* Disable all interrupts except pmu */
803 save_irqen
= in_le32(IRQ_ENABLE
);
804 for (i
= 0; i
< 32; ++i
)
805 if (i
!= vias
->intrs
[0].line
&& (save_irqen
& (1 << i
)))
807 asm volatile("mtdec %0" : : "r" (0x7fffffff));
809 /* Save the state of PCI config space for some slots */
812 /* Set the memory controller to keep the memory refreshed
813 while we're asleep */
814 for (i
= 0x403f; i
>= 0x4000; --i
) {
815 out_be32(MEM_CTRL
, i
);
817 x
= (in_be32(MEM_CTRL
) >> 16) & 0x3ff;
823 /* Ask the PMU to put us to sleep */
824 pmu_request(&sleep_req
, NULL
, 5, PMU_SLEEP
, 'M', 'A', 'T', 'T');
825 while (!sleep_req
.complete
)
827 /* displacement-flush the L2 cache - necessary? */
828 for (p
= KERNELBASE
; p
< KERNELBASE
+ 0x100000; p
+= 0x1000)
829 i
= *(volatile int *)p
;
832 /* Put the CPU into sleep mode */
833 asm volatile("mfspr %0,1008" : "=r" (hid0
) :);
834 hid0
= (hid0
& ~(HID0_NAP
| HID0_DOZE
)) | HID0_SLEEP
;
835 asm volatile("mtspr 1008,%0" : : "r" (hid0
));
837 msr
|= MSR_POW
| MSR_EE
;
841 /* OK, we're awake again, start restoring things */
842 out_be32(MEM_CTRL
, 0x3f);
845 /* wait for the PMU interrupt sequence to complete */
849 /* reenable interrupts */
850 for (i
= 0; i
< 32; ++i
)
851 if (i
!= vias
->intrs
[0].line
&& (save_irqen
& (1 << i
)))
855 notifier_call_chain(&sleep_notifier_list
, PBOOK_WAKE
, NULL
);
857 /* reenable ADB autopoll */
860 /* Turn on the screen backlight, if it was on before */
862 pmu_enable_backlight(1);
868 * Support for /dev/pmu device
870 static int pmu_open(struct inode
*inode
, struct file
*file
)
875 static ssize_t
pmu_read(struct file
*file
, char *buf
,
876 size_t count
, loff_t
*ppos
)
881 static ssize_t
pmu_write(struct file
*file
, const char *buf
,
882 size_t count
, loff_t
*ppos
)
887 static int pmu_ioctl(struct inode
* inode
, struct file
*filp
,
888 u_int cmd
, u_long arg
)
892 return powerbook_sleep();
897 static struct file_operations pmu_device_fops
= {
901 NULL
, /* no readdir */
902 NULL
, /* no poll yet */
907 NULL
/* no release */
910 static struct miscdevice pmu_device
= {
911 PMU_MINOR
, "pmu", &pmu_device_fops
914 void pmu_device_init(void)
917 misc_register(&pmu_device
);
919 #endif /* CONFIG_PMAC_PBOOK */