diff options
Diffstat (limited to 'arch/x86/kernel/pci-gart_64.c')
-rw-r--r-- | arch/x86/kernel/pci-gart_64.c | 41 |
1 files changed, 15 insertions, 26 deletions
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index c01ffa5b9b87..b117efd24f71 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include <linux/kdebug.h> | 27 | #include <linux/kdebug.h> |
28 | #include <linux/scatterlist.h> | 28 | #include <linux/scatterlist.h> |
29 | #include <linux/iommu-helper.h> | 29 | #include <linux/iommu-helper.h> |
30 | #include <linux/sysdev.h> | 30 | #include <linux/syscore_ops.h> |
31 | #include <linux/io.h> | 31 | #include <linux/io.h> |
32 | #include <linux/gfp.h> | 32 | #include <linux/gfp.h> |
33 | #include <asm/atomic.h> | 33 | #include <asm/atomic.h> |
@@ -81,6 +81,9 @@ static u32 gart_unmapped_entry; | |||
81 | #define AGPEXTERN | 81 | #define AGPEXTERN |
82 | #endif | 82 | #endif |
83 | 83 | ||
84 | /* GART can only remap to physical addresses < 1TB */ | ||
85 | #define GART_MAX_PHYS_ADDR (1ULL << 40) | ||
86 | |||
84 | /* backdoor interface to AGP driver */ | 87 | /* backdoor interface to AGP driver */ |
85 | AGPEXTERN int agp_memory_reserved; | 88 | AGPEXTERN int agp_memory_reserved; |
86 | AGPEXTERN __u32 *agp_gatt_table; | 89 | AGPEXTERN __u32 *agp_gatt_table; |
@@ -212,9 +215,13 @@ static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem, | |||
212 | size_t size, int dir, unsigned long align_mask) | 215 | size_t size, int dir, unsigned long align_mask) |
213 | { | 216 | { |
214 | unsigned long npages = iommu_num_pages(phys_mem, size, PAGE_SIZE); | 217 | unsigned long npages = iommu_num_pages(phys_mem, size, PAGE_SIZE); |
215 | unsigned long iommu_page = alloc_iommu(dev, npages, align_mask); | 218 | unsigned long iommu_page; |
216 | int i; | 219 | int i; |
217 | 220 | ||
221 | if (unlikely(phys_mem + size > GART_MAX_PHYS_ADDR)) | ||
222 | return bad_dma_addr; | ||
223 | |||
224 | iommu_page = alloc_iommu(dev, npages, align_mask); | ||
218 | if (iommu_page == -1) { | 225 | if (iommu_page == -1) { |
219 | if (!nonforced_iommu(dev, phys_mem, size)) | 226 | if (!nonforced_iommu(dev, phys_mem, size)) |
220 | return phys_mem; | 227 | return phys_mem; |
@@ -589,7 +596,7 @@ void set_up_gart_resume(u32 aper_order, u32 aper_alloc) | |||
589 | aperture_alloc = aper_alloc; | 596 | aperture_alloc = aper_alloc; |
590 | } | 597 | } |
591 | 598 | ||
592 | static void gart_fixup_northbridges(struct sys_device *dev) | 599 | static void gart_fixup_northbridges(void) |
593 | { | 600 | { |
594 | int i; | 601 | int i; |
595 | 602 | ||
@@ -613,33 +620,20 @@ static void gart_fixup_northbridges(struct sys_device *dev) | |||
613 | } | 620 | } |
614 | } | 621 | } |
615 | 622 | ||
616 | static int gart_resume(struct sys_device *dev) | 623 | static void gart_resume(void) |
617 | { | 624 | { |
618 | pr_info("PCI-DMA: Resuming GART IOMMU\n"); | 625 | pr_info("PCI-DMA: Resuming GART IOMMU\n"); |
619 | 626 | ||
620 | gart_fixup_northbridges(dev); | 627 | gart_fixup_northbridges(); |
621 | 628 | ||
622 | enable_gart_translations(); | 629 | enable_gart_translations(); |
623 | |||
624 | return 0; | ||
625 | } | 630 | } |
626 | 631 | ||
627 | static int gart_suspend(struct sys_device *dev, pm_message_t state) | 632 | static struct syscore_ops gart_syscore_ops = { |
628 | { | ||
629 | return 0; | ||
630 | } | ||
631 | |||
632 | static struct sysdev_class gart_sysdev_class = { | ||
633 | .name = "gart", | ||
634 | .suspend = gart_suspend, | ||
635 | .resume = gart_resume, | 633 | .resume = gart_resume, |
636 | 634 | ||
637 | }; | 635 | }; |
638 | 636 | ||
639 | static struct sys_device device_gart = { | ||
640 | .cls = &gart_sysdev_class, | ||
641 | }; | ||
642 | |||
643 | /* | 637 | /* |
644 | * Private Northbridge GATT initialization in case we cannot use the | 638 | * Private Northbridge GATT initialization in case we cannot use the |
645 | * AGP driver for some reason. | 639 | * AGP driver for some reason. |
@@ -650,7 +644,7 @@ static __init int init_amd_gatt(struct agp_kern_info *info) | |||
650 | unsigned aper_base, new_aper_base; | 644 | unsigned aper_base, new_aper_base; |
651 | struct pci_dev *dev; | 645 | struct pci_dev *dev; |
652 | void *gatt; | 646 | void *gatt; |
653 | int i, error; | 647 | int i; |
654 | 648 | ||
655 | pr_info("PCI-DMA: Disabling AGP.\n"); | 649 | pr_info("PCI-DMA: Disabling AGP.\n"); |
656 | 650 | ||
@@ -685,12 +679,7 @@ static __init int init_amd_gatt(struct agp_kern_info *info) | |||
685 | 679 | ||
686 | agp_gatt_table = gatt; | 680 | agp_gatt_table = gatt; |
687 | 681 | ||
688 | error = sysdev_class_register(&gart_sysdev_class); | 682 | register_syscore_ops(&gart_syscore_ops); |
689 | if (!error) | ||
690 | error = sysdev_register(&device_gart); | ||
691 | if (error) | ||
692 | panic("Could not register gart_sysdev -- " | ||
693 | "would corrupt data on next suspend"); | ||
694 | 683 | ||
695 | flush_gart(); | 684 | flush_gart(); |
696 | 685 | ||