diff options
| author | Wim Van Sebroeck <wim@iguana.be> | 2007-05-11 19:03:13 +0000 | 
|---|---|---|
| committer | Wim Van Sebroeck <wim@iguana.be> | 2007-05-11 19:03:13 +0000 | 
| commit | 5c34202b8bf942da411b6599668a76b07449bbfd (patch) | |
| tree | 5719c361321eaddc8e4f1b0c8a7994f0e9a6fdd3 /arch/powerpc/sysdev/dart_iommu.c | |
| parent | 0d4804b31f91cfbcff6d62af0bc09a893a1c8ae0 (diff) | |
| parent | 1f8a6b658a943b4f04a1fc7b3a420360202c86cd (diff) | |
Merge /pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'arch/powerpc/sysdev/dart_iommu.c')
| -rw-r--r-- | arch/powerpc/sysdev/dart_iommu.c | 46 | 
1 files changed, 46 insertions, 0 deletions
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c index 336186dd7f1..a1d2042bb30 100644 --- a/arch/powerpc/sysdev/dart_iommu.c +++ b/arch/powerpc/sysdev/dart_iommu.c @@ -36,6 +36,7 @@  #include <linux/pci.h>  #include <linux/dma-mapping.h>  #include <linux/vmalloc.h> +#include <linux/suspend.h>  #include <asm/io.h>  #include <asm/prom.h>  #include <asm/iommu.h> @@ -54,6 +55,9 @@ static unsigned long dart_tablesize;  /* Virtual base address of the DART table */  static u32 *dart_vbase; +#ifdef CONFIG_PM +static u32 *dart_copy; +#endif  /* Mapped base address for the dart */  static unsigned int __iomem *dart; @@ -346,6 +350,48 @@ void iommu_init_early_dart(void)  	set_pci_dma_ops(&dma_direct_ops);  } +#ifdef CONFIG_PM +static void iommu_dart_save(void) +{ +	memcpy(dart_copy, dart_vbase, 2*1024*1024); +} + +static void iommu_dart_restore(void) +{ +	memcpy(dart_vbase, dart_copy, 2*1024*1024); +	dart_tlb_invalidate_all(); +} + +static int __init iommu_init_late_dart(void) +{ +	unsigned long tbasepfn; +	struct page *p; + +	/* if no dart table exists then we won't need to save it +	 * and the area has also not been reserved */ +	if (!dart_tablebase) +		return 0; + +	tbasepfn = __pa(dart_tablebase) >> PAGE_SHIFT; +	register_nosave_region_late(tbasepfn, +				    tbasepfn + ((1<<24) >> PAGE_SHIFT)); + +	/* For suspend we need to copy the dart contents because +	 * it is not part of the regular mapping (see above) and +	 * thus not saved automatically. The memory for this copy +	 * must be allocated early because we need 2 MB. */ +	p = alloc_pages(GFP_KERNEL, 21 - PAGE_SHIFT); +	BUG_ON(!p); +	dart_copy = page_address(p); + +	ppc_md.iommu_save = iommu_dart_save; +	ppc_md.iommu_restore = iommu_dart_restore; + +	return 0; +} + +late_initcall(iommu_init_late_dart); +#endif  void __init alloc_dart_table(void)  {  | 
