Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | /* * ADB Miscellaneous stuff */ #include <stdarg.h> #include <linux/types.h> #include <linux/errno.h> #include <linux/miscdevice.h> #include <linux/kernel.h> #include <linux/delay.h> #include <linux/sched.h> #include <linux/malloc.h> #include <linux/mm.h> #include <asm/uaccess.h> #include <asm/io.h> #ifdef CONFIG_ADB_NEW #include <linux/adb.h> #else #include <asm/adb.h> #endif #include <asm/system.h> #include <asm/segment.h> #include <asm/setup.h> #include <asm/macintosh.h> extern void cuda_poll(void); extern int cuda_request(struct adb_request *req, void (*done)(struct adb_request *), int nbytes, ...); /* * Return the current time as the number of seconds since January 1, 1904. * * This method works for both CUDA and IIsi-style ADB. It'll probably * work for PowerBooks too once we have PowerBook ADB working. */ __u32 adb_read_time(void) { volatile struct adb_request req; __u32 time; #ifdef CONFIG_ADB_NEW #ifdef CONFIG_ADB_CUDA cuda_request((struct adb_request *) &req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME); while (!req.complete) cuda_poll(); #endif #else adb_request((struct adb_request *) &req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME); while (!req.complete); #endif time = (req.reply[3] << 24) | (req.reply[4] << 16) | (req.reply[5] << 8) | req.reply[6]; return time; } /* * Set the current system time * * This method works for both CUDA and IIsi-style ADB. It'll probably * work for PowerBooks too once we have PowerBook ADB working. */ void adb_write_time(__u32 data) { volatile struct adb_request req; #ifdef CONFIG_ADB_NEW #ifdef CONFIG_ADB_CUDA cuda_request((struct adb_request *) &req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME, (data >> 24) & 0xFF, (data >> 16) & 0xFF, (data >> 8) & 0xFF, data & 0xFF); while (!req.complete) cuda_poll(); #endif #else adb_request((struct adb_request *) &req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME, (data >> 24) & 0xFF, (data >> 16) & 0xFF, (data >> 8) & 0xFF, data & 0xFF); while (!req.complete); #endif } /* * Initially discovered this technique in the Mach kernel of MkLinux in * osfmk/src/mach_kernel/ppc/POWERMAC/cuda_power.c. Found equivalent LinuxPPC * code in arch/ppc/kernel/setup.c, which also has a PMU technique for * PowerBooks! * * --David Kilzer */ void adb_poweroff(void) { struct adb_request req; /* * Print our "safe" message before we send the request * just in case the request never returns. */ printk ("It is now safe to switch off your machine.\n"); #ifdef CONFIG_ADB_NEW #ifdef CONFIG_ADB_CUDA cuda_request (&req, NULL, 2, CUDA_PACKET, CUDA_POWERDOWN); for (;;) cuda_poll(); #endif #else adb_request (&req, NULL, 2, CUDA_PACKET, CUDA_POWERDOWN); for (;;) ; #endif } /* * Initially discovered this technique in the Mach kernel of MkLinux in * osfmk/src/mach_kernel/ppc/POWERMAC/cuda_power.c. Found equivalent LinuxPPC * code in arch/ppc/kernel/setup.c, which also has a PMU technique! * --David Kilzer * * I suspect the MAC_ADB_CUDA code might work with other ADB types of machines * but have no way to test this myself. --DDK */ void adb_hwreset(void) { struct adb_request req; printk ("Resetting system...\n"); #ifdef CONFIG_ADB_NEW #ifdef CONFIG_ADB_CUDA cuda_request (&req, NULL, 2, CUDA_PACKET, CUDA_RESET_SYSTEM); for (;;) cuda_poll(); #endif #else adb_request (&req, NULL, 2, CUDA_PACKET, CUDA_RESET_SYSTEM); for (;;) ; #endif } |