f3c6ea1b06
Some subsystems in the x86 tree need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled and they define sysdev classes and sysdevs or sysdev drivers for this purpose. This leads to unnecessarily complicated code and excessive memory usage, so switch them to using struct syscore_ops objects for this purpose instead. Generally, there are three categories of subsystems that use sysdevs for implementing PM operations: (1) subsystems whose suspend/resume callbacks ignore their arguments entirely (the majority), (2) subsystems whose suspend/resume callbacks use their struct sys_device argument, but don't really need to do that, because they can be implemented differently in an arguably simpler way (io_apic.c), and (3) subsystems whose suspend/resume callbacks use their struct sys_device argument, but the value of that argument is always the same and could be ignored (microcode_core.c). In all of these cases the subsystems in question may be readily converted to using struct syscore_ops objects for power management and shutdown. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Reviewed-by: Thomas Gleixner <tglx@linutronix.de> Acked-by: Ingo Molnar <mingo@elte.hu>
56 lines
1.2 KiB
C
56 lines
1.2 KiB
C
/*
|
|
* 8237A DMA controller suspend functions.
|
|
*
|
|
* Written by Pierre Ossman, 2005.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or (at
|
|
* your option) any later version.
|
|
*/
|
|
|
|
#include <linux/init.h>
|
|
#include <linux/syscore_ops.h>
|
|
|
|
#include <asm/dma.h>
|
|
|
|
/*
|
|
* This module just handles suspend/resume issues with the
|
|
* 8237A DMA controller (used for ISA and LPC).
|
|
* Allocation is handled in kernel/dma.c and normal usage is
|
|
* in asm/dma.h.
|
|
*/
|
|
|
|
static void i8237A_resume(void)
|
|
{
|
|
unsigned long flags;
|
|
int i;
|
|
|
|
flags = claim_dma_lock();
|
|
|
|
dma_outb(0, DMA1_RESET_REG);
|
|
dma_outb(0, DMA2_RESET_REG);
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
set_dma_addr(i, 0x000000);
|
|
/* DMA count is a bit weird so this is not 0 */
|
|
set_dma_count(i, 1);
|
|
}
|
|
|
|
/* Enable cascade DMA or channel 0-3 won't work */
|
|
enable_dma(4);
|
|
|
|
release_dma_lock(flags);
|
|
}
|
|
|
|
static struct syscore_ops i8237_syscore_ops = {
|
|
.resume = i8237A_resume,
|
|
};
|
|
|
|
static int __init i8237A_init_ops(void)
|
|
{
|
|
register_syscore_ops(&i8237_syscore_ops);
|
|
return 0;
|
|
}
|
|
device_initcall(i8237A_init_ops);
|