Loading arch/x86/include/asm/iomap.h +3 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,9 @@ #include <asm/pgtable.h> #include <asm/tlbflush.h> int is_io_mapping_possible(resource_size_t base, unsigned long size); void * iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot); Loading arch/x86/mm/iomap_32.c +18 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,24 @@ #include <asm/pat.h> #include <linux/module.h> #ifdef CONFIG_X86_PAE int is_io_mapping_possible(resource_size_t base, unsigned long size) { return 1; } #else int is_io_mapping_possible(resource_size_t base, unsigned long size) { /* There is no way to map greater than 1 << 32 address without PAE */ if (base + size > 0x100000000ULL) return 0; return 1; } #endif /* Map 'pfn' using fixed map 'type' and protections 'prot' */ void * Loading arch/x86/xen/enlighten.c +3 −0 Original line number Diff line number Diff line Loading @@ -940,6 +940,9 @@ asmlinkage void __init xen_start_kernel(void) possible map and a non-dummy shared_info. */ per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0]; local_irq_disable(); early_boot_irqs_off(); xen_raw_console_write("mapping kernel into physical memory\n"); pgd = xen_setup_kernel_pagetable(pgd, xen_start_info->nr_pages); Loading drivers/gpu/drm/i915/i915_dma.c +8 −1 Original line number Diff line number Diff line Loading @@ -1090,6 +1090,11 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) dev_priv->mm.gtt_mapping = io_mapping_create_wc(dev->agp->base, dev->agp->agp_info.aper_size * 1024*1024); if (dev_priv->mm.gtt_mapping == NULL) { ret = -EIO; goto out_rmmap; } /* Set up a WC MTRR for non-PAT systems. This is more common than * one would think, because the kernel disables PAT on first * generation Core chips because WC PAT gets overridden by a UC Loading Loading @@ -1122,7 +1127,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) if (!I915_NEED_GFX_HWS(dev)) { ret = i915_init_phys_hws(dev); if (ret != 0) goto out_rmmap; goto out_iomapfree; } /* On the 945G/GM, the chipset reports the MSI capability on the Loading Loading @@ -1161,6 +1166,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) return 0; out_iomapfree: io_mapping_free(dev_priv->mm.gtt_mapping); out_rmmap: iounmap(dev_priv->regs); free_priv: Loading include/linux/io-mapping.h +35 −11 Original line number Diff line number Diff line Loading @@ -30,11 +30,14 @@ * See Documentation/io_mapping.txt */ /* this struct isn't actually defined anywhere */ struct io_mapping; #ifdef CONFIG_HAVE_ATOMIC_IOMAP struct io_mapping { resource_size_t base; unsigned long size; pgprot_t prot; }; /* * For small address space machines, mapping large objects * into the kernel virtual space isn't practical. Where Loading @@ -43,23 +46,40 @@ struct io_mapping; */ static inline struct io_mapping * io_mapping_create_wc(unsigned long base, unsigned long size) io_mapping_create_wc(resource_size_t base, unsigned long size) { return (struct io_mapping *) base; struct io_mapping *iomap; if (!is_io_mapping_possible(base, size)) return NULL; iomap = kmalloc(sizeof(*iomap), GFP_KERNEL); if (!iomap) return NULL; iomap->base = base; iomap->size = size; iomap->prot = pgprot_writecombine(__pgprot(__PAGE_KERNEL)); return iomap; } static inline void io_mapping_free(struct io_mapping *mapping) { kfree(mapping); } /* Atomic map/unmap */ static inline void * io_mapping_map_atomic_wc(struct io_mapping *mapping, unsigned long offset) { offset += (unsigned long) mapping; return iomap_atomic_prot_pfn(offset >> PAGE_SHIFT, KM_USER0, __pgprot(__PAGE_KERNEL_WC)); resource_size_t phys_addr; unsigned long pfn; BUG_ON(offset >= mapping->size); phys_addr = mapping->base + offset; pfn = (unsigned long) (phys_addr >> PAGE_SHIFT); return iomap_atomic_prot_pfn(pfn, KM_USER0, mapping->prot); } static inline void Loading @@ -71,8 +91,9 @@ io_mapping_unmap_atomic(void *vaddr) static inline void * io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset) { offset += (unsigned long) mapping; return ioremap_wc(offset, PAGE_SIZE); BUG_ON(offset >= mapping->size); resource_size_t phys_addr = mapping->base + offset; return ioremap_wc(phys_addr, PAGE_SIZE); } static inline void Loading @@ -83,9 +104,12 @@ io_mapping_unmap(void *vaddr) #else /* this struct isn't actually defined anywhere */ struct io_mapping; /* Create the io_mapping object*/ static inline struct io_mapping * io_mapping_create_wc(unsigned long base, unsigned long size) io_mapping_create_wc(resource_size_t base, unsigned long size) { return (struct io_mapping *) ioremap_wc(base, size); } Loading Loading
arch/x86/include/asm/iomap.h +3 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,9 @@ #include <asm/pgtable.h> #include <asm/tlbflush.h> int is_io_mapping_possible(resource_size_t base, unsigned long size); void * iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot); Loading
arch/x86/mm/iomap_32.c +18 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,24 @@ #include <asm/pat.h> #include <linux/module.h> #ifdef CONFIG_X86_PAE int is_io_mapping_possible(resource_size_t base, unsigned long size) { return 1; } #else int is_io_mapping_possible(resource_size_t base, unsigned long size) { /* There is no way to map greater than 1 << 32 address without PAE */ if (base + size > 0x100000000ULL) return 0; return 1; } #endif /* Map 'pfn' using fixed map 'type' and protections 'prot' */ void * Loading
arch/x86/xen/enlighten.c +3 −0 Original line number Diff line number Diff line Loading @@ -940,6 +940,9 @@ asmlinkage void __init xen_start_kernel(void) possible map and a non-dummy shared_info. */ per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0]; local_irq_disable(); early_boot_irqs_off(); xen_raw_console_write("mapping kernel into physical memory\n"); pgd = xen_setup_kernel_pagetable(pgd, xen_start_info->nr_pages); Loading
drivers/gpu/drm/i915/i915_dma.c +8 −1 Original line number Diff line number Diff line Loading @@ -1090,6 +1090,11 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) dev_priv->mm.gtt_mapping = io_mapping_create_wc(dev->agp->base, dev->agp->agp_info.aper_size * 1024*1024); if (dev_priv->mm.gtt_mapping == NULL) { ret = -EIO; goto out_rmmap; } /* Set up a WC MTRR for non-PAT systems. This is more common than * one would think, because the kernel disables PAT on first * generation Core chips because WC PAT gets overridden by a UC Loading Loading @@ -1122,7 +1127,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) if (!I915_NEED_GFX_HWS(dev)) { ret = i915_init_phys_hws(dev); if (ret != 0) goto out_rmmap; goto out_iomapfree; } /* On the 945G/GM, the chipset reports the MSI capability on the Loading Loading @@ -1161,6 +1166,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) return 0; out_iomapfree: io_mapping_free(dev_priv->mm.gtt_mapping); out_rmmap: iounmap(dev_priv->regs); free_priv: Loading
include/linux/io-mapping.h +35 −11 Original line number Diff line number Diff line Loading @@ -30,11 +30,14 @@ * See Documentation/io_mapping.txt */ /* this struct isn't actually defined anywhere */ struct io_mapping; #ifdef CONFIG_HAVE_ATOMIC_IOMAP struct io_mapping { resource_size_t base; unsigned long size; pgprot_t prot; }; /* * For small address space machines, mapping large objects * into the kernel virtual space isn't practical. Where Loading @@ -43,23 +46,40 @@ struct io_mapping; */ static inline struct io_mapping * io_mapping_create_wc(unsigned long base, unsigned long size) io_mapping_create_wc(resource_size_t base, unsigned long size) { return (struct io_mapping *) base; struct io_mapping *iomap; if (!is_io_mapping_possible(base, size)) return NULL; iomap = kmalloc(sizeof(*iomap), GFP_KERNEL); if (!iomap) return NULL; iomap->base = base; iomap->size = size; iomap->prot = pgprot_writecombine(__pgprot(__PAGE_KERNEL)); return iomap; } static inline void io_mapping_free(struct io_mapping *mapping) { kfree(mapping); } /* Atomic map/unmap */ static inline void * io_mapping_map_atomic_wc(struct io_mapping *mapping, unsigned long offset) { offset += (unsigned long) mapping; return iomap_atomic_prot_pfn(offset >> PAGE_SHIFT, KM_USER0, __pgprot(__PAGE_KERNEL_WC)); resource_size_t phys_addr; unsigned long pfn; BUG_ON(offset >= mapping->size); phys_addr = mapping->base + offset; pfn = (unsigned long) (phys_addr >> PAGE_SHIFT); return iomap_atomic_prot_pfn(pfn, KM_USER0, mapping->prot); } static inline void Loading @@ -71,8 +91,9 @@ io_mapping_unmap_atomic(void *vaddr) static inline void * io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset) { offset += (unsigned long) mapping; return ioremap_wc(offset, PAGE_SIZE); BUG_ON(offset >= mapping->size); resource_size_t phys_addr = mapping->base + offset; return ioremap_wc(phys_addr, PAGE_SIZE); } static inline void Loading @@ -83,9 +104,12 @@ io_mapping_unmap(void *vaddr) #else /* this struct isn't actually defined anywhere */ struct io_mapping; /* Create the io_mapping object*/ static inline struct io_mapping * io_mapping_create_wc(unsigned long base, unsigned long size) io_mapping_create_wc(resource_size_t base, unsigned long size) { return (struct io_mapping *) ioremap_wc(base, size); } Loading