diff options
Diffstat (limited to 'arch/i386/kernel/apm.c')
-rw-r--r-- | arch/i386/kernel/apm.c | 70 |
1 files changed, 18 insertions, 52 deletions
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index db99a8948dae..064bbf2861f4 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c | |||
@@ -211,6 +211,7 @@ | |||
211 | #include <linux/slab.h> | 211 | #include <linux/slab.h> |
212 | #include <linux/stat.h> | 212 | #include <linux/stat.h> |
213 | #include <linux/proc_fs.h> | 213 | #include <linux/proc_fs.h> |
214 | #include <linux/seq_file.h> | ||
214 | #include <linux/miscdevice.h> | 215 | #include <linux/miscdevice.h> |
215 | #include <linux/apm_bios.h> | 216 | #include <linux/apm_bios.h> |
216 | #include <linux/init.h> | 217 | #include <linux/init.h> |
@@ -235,7 +236,6 @@ | |||
235 | 236 | ||
236 | #include "io_ports.h" | 237 | #include "io_ports.h" |
237 | 238 | ||
238 | extern unsigned long get_cmos_time(void); | ||
239 | extern void machine_real_restart(unsigned char *, int); | 239 | extern void machine_real_restart(unsigned char *, int); |
240 | 240 | ||
241 | #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT) | 241 | #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT) |
@@ -1175,28 +1175,6 @@ out: | |||
1175 | spin_unlock(&user_list_lock); | 1175 | spin_unlock(&user_list_lock); |
1176 | } | 1176 | } |
1177 | 1177 | ||
1178 | static void set_time(void) | ||
1179 | { | ||
1180 | struct timespec ts; | ||
1181 | if (got_clock_diff) { /* Must know time zone in order to set clock */ | ||
1182 | ts.tv_sec = get_cmos_time() + clock_cmos_diff; | ||
1183 | ts.tv_nsec = 0; | ||
1184 | do_settimeofday(&ts); | ||
1185 | } | ||
1186 | } | ||
1187 | |||
1188 | static void get_time_diff(void) | ||
1189 | { | ||
1190 | #ifndef CONFIG_APM_RTC_IS_GMT | ||
1191 | /* | ||
1192 | * Estimate time zone so that set_time can update the clock | ||
1193 | */ | ||
1194 | clock_cmos_diff = -get_cmos_time(); | ||
1195 | clock_cmos_diff += get_seconds(); | ||
1196 | got_clock_diff = 1; | ||
1197 | #endif | ||
1198 | } | ||
1199 | |||
1200 | static void reinit_timer(void) | 1178 | static void reinit_timer(void) |
1201 | { | 1179 | { |
1202 | #ifdef INIT_TIMER_AFTER_SUSPEND | 1180 | #ifdef INIT_TIMER_AFTER_SUSPEND |
@@ -1236,19 +1214,6 @@ static int suspend(int vetoable) | |||
1236 | local_irq_disable(); | 1214 | local_irq_disable(); |
1237 | device_power_down(PMSG_SUSPEND); | 1215 | device_power_down(PMSG_SUSPEND); |
1238 | 1216 | ||
1239 | /* serialize with the timer interrupt */ | ||
1240 | write_seqlock(&xtime_lock); | ||
1241 | |||
1242 | /* protect against access to timer chip registers */ | ||
1243 | spin_lock(&i8253_lock); | ||
1244 | |||
1245 | get_time_diff(); | ||
1246 | /* | ||
1247 | * Irq spinlock must be dropped around set_system_power_state. | ||
1248 | * We'll undo any timer changes due to interrupts below. | ||
1249 | */ | ||
1250 | spin_unlock(&i8253_lock); | ||
1251 | write_sequnlock(&xtime_lock); | ||
1252 | local_irq_enable(); | 1217 | local_irq_enable(); |
1253 | 1218 | ||
1254 | save_processor_state(); | 1219 | save_processor_state(); |
@@ -1257,7 +1222,6 @@ static int suspend(int vetoable) | |||
1257 | restore_processor_state(); | 1222 | restore_processor_state(); |
1258 | 1223 | ||
1259 | local_irq_disable(); | 1224 | local_irq_disable(); |
1260 | set_time(); | ||
1261 | reinit_timer(); | 1225 | reinit_timer(); |
1262 | 1226 | ||
1263 | if (err == APM_NO_ERROR) | 1227 | if (err == APM_NO_ERROR) |
@@ -1287,11 +1251,6 @@ static void standby(void) | |||
1287 | 1251 | ||
1288 | local_irq_disable(); | 1252 | local_irq_disable(); |
1289 | device_power_down(PMSG_SUSPEND); | 1253 | device_power_down(PMSG_SUSPEND); |
1290 | /* serialize with the timer interrupt */ | ||
1291 | write_seqlock(&xtime_lock); | ||
1292 | /* If needed, notify drivers here */ | ||
1293 | get_time_diff(); | ||
1294 | write_sequnlock(&xtime_lock); | ||
1295 | local_irq_enable(); | 1254 | local_irq_enable(); |
1296 | 1255 | ||
1297 | err = set_system_power_state(APM_STATE_STANDBY); | 1256 | err = set_system_power_state(APM_STATE_STANDBY); |
@@ -1385,7 +1344,6 @@ static void check_events(void) | |||
1385 | ignore_bounce = 1; | 1344 | ignore_bounce = 1; |
1386 | if ((event != APM_NORMAL_RESUME) | 1345 | if ((event != APM_NORMAL_RESUME) |
1387 | || (ignore_normal_resume == 0)) { | 1346 | || (ignore_normal_resume == 0)) { |
1388 | set_time(); | ||
1389 | device_resume(); | 1347 | device_resume(); |
1390 | pm_send_all(PM_RESUME, (void *)0); | 1348 | pm_send_all(PM_RESUME, (void *)0); |
1391 | queue_event(event, NULL); | 1349 | queue_event(event, NULL); |
@@ -1401,7 +1359,6 @@ static void check_events(void) | |||
1401 | break; | 1359 | break; |
1402 | 1360 | ||
1403 | case APM_UPDATE_TIME: | 1361 | case APM_UPDATE_TIME: |
1404 | set_time(); | ||
1405 | break; | 1362 | break; |
1406 | 1363 | ||
1407 | case APM_CRITICAL_SUSPEND: | 1364 | case APM_CRITICAL_SUSPEND: |
@@ -1636,9 +1593,8 @@ static int do_open(struct inode * inode, struct file * filp) | |||
1636 | return 0; | 1593 | return 0; |
1637 | } | 1594 | } |
1638 | 1595 | ||
1639 | static int apm_get_info(char *buf, char **start, off_t fpos, int length) | 1596 | static int proc_apm_show(struct seq_file *m, void *v) |
1640 | { | 1597 | { |
1641 | char * p; | ||
1642 | unsigned short bx; | 1598 | unsigned short bx; |
1643 | unsigned short cx; | 1599 | unsigned short cx; |
1644 | unsigned short dx; | 1600 | unsigned short dx; |
@@ -1650,8 +1606,6 @@ static int apm_get_info(char *buf, char **start, off_t fpos, int length) | |||
1650 | int time_units = -1; | 1606 | int time_units = -1; |
1651 | char *units = "?"; | 1607 | char *units = "?"; |
1652 | 1608 | ||
1653 | p = buf; | ||
1654 | |||
1655 | if ((num_online_cpus() == 1) && | 1609 | if ((num_online_cpus() == 1) && |
1656 | !(error = apm_get_power_status(&bx, &cx, &dx))) { | 1610 | !(error = apm_get_power_status(&bx, &cx, &dx))) { |
1657 | ac_line_status = (bx >> 8) & 0xff; | 1611 | ac_line_status = (bx >> 8) & 0xff; |
@@ -1705,7 +1659,7 @@ static int apm_get_info(char *buf, char **start, off_t fpos, int length) | |||
1705 | -1: Unknown | 1659 | -1: Unknown |
1706 | 8) min = minutes; sec = seconds */ | 1660 | 8) min = minutes; sec = seconds */ |
1707 | 1661 | ||
1708 | p += sprintf(p, "%s %d.%d 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s\n", | 1662 | seq_printf(m, "%s %d.%d 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s\n", |
1709 | driver_version, | 1663 | driver_version, |
1710 | (apm_info.bios.version >> 8) & 0xff, | 1664 | (apm_info.bios.version >> 8) & 0xff, |
1711 | apm_info.bios.version & 0xff, | 1665 | apm_info.bios.version & 0xff, |
@@ -1716,10 +1670,22 @@ static int apm_get_info(char *buf, char **start, off_t fpos, int length) | |||
1716 | percentage, | 1670 | percentage, |
1717 | time_units, | 1671 | time_units, |
1718 | units); | 1672 | units); |
1673 | return 0; | ||
1674 | } | ||
1719 | 1675 | ||
1720 | return p - buf; | 1676 | static int proc_apm_open(struct inode *inode, struct file *file) |
1677 | { | ||
1678 | return single_open(file, proc_apm_show, NULL); | ||
1721 | } | 1679 | } |
1722 | 1680 | ||
1681 | static const struct file_operations apm_file_ops = { | ||
1682 | .owner = THIS_MODULE, | ||
1683 | .open = proc_apm_open, | ||
1684 | .read = seq_read, | ||
1685 | .llseek = seq_lseek, | ||
1686 | .release = single_release, | ||
1687 | }; | ||
1688 | |||
1723 | static int apm(void *unused) | 1689 | static int apm(void *unused) |
1724 | { | 1690 | { |
1725 | unsigned short bx; | 1691 | unsigned short bx; |
@@ -2341,9 +2307,9 @@ static int __init apm_init(void) | |||
2341 | set_base(gdt[APM_DS >> 3], | 2307 | set_base(gdt[APM_DS >> 3], |
2342 | __va((unsigned long)apm_info.bios.dseg << 4)); | 2308 | __va((unsigned long)apm_info.bios.dseg << 4)); |
2343 | 2309 | ||
2344 | apm_proc = create_proc_info_entry("apm", 0, NULL, apm_get_info); | 2310 | apm_proc = create_proc_entry("apm", 0, NULL); |
2345 | if (apm_proc) | 2311 | if (apm_proc) |
2346 | apm_proc->owner = THIS_MODULE; | 2312 | apm_proc->proc_fops = &apm_file_ops; |
2347 | 2313 | ||
2348 | kapmd_task = kthread_create(apm, NULL, "kapmd"); | 2314 | kapmd_task = kthread_create(apm, NULL, "kapmd"); |
2349 | if (IS_ERR(kapmd_task)) { | 2315 | if (IS_ERR(kapmd_task)) { |