Commit 13b2eda6 authored by Ingo Molnar's avatar Ingo Molnar

Merge branch 'x86/urgent' into x86/core

Conflicts:
	arch/x86/mach-voyager/voyager_smp.c
parents a852cbfa 55d80856
...@@ -23,6 +23,9 @@ ...@@ -23,6 +23,9 @@
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/tlbflush.h> #include <asm/tlbflush.h>
int
is_io_mapping_possible(resource_size_t base, unsigned long size);
void * void *
iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot); iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot);
......
...@@ -20,6 +20,24 @@ ...@@ -20,6 +20,24 @@
#include <asm/pat.h> #include <asm/pat.h>
#include <linux/module.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' /* Map 'pfn' using fixed map 'type' and protections 'prot'
*/ */
void * void *
......
...@@ -940,6 +940,9 @@ asmlinkage void __init xen_start_kernel(void) ...@@ -940,6 +940,9 @@ asmlinkage void __init xen_start_kernel(void)
possible map and a non-dummy shared_info. */ possible map and a non-dummy shared_info. */
per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0]; 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"); xen_raw_console_write("mapping kernel into physical memory\n");
pgd = xen_setup_kernel_pagetable(pgd, xen_start_info->nr_pages); pgd = xen_setup_kernel_pagetable(pgd, xen_start_info->nr_pages);
......
...@@ -1090,6 +1090,11 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) ...@@ -1090,6 +1090,11 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
dev_priv->mm.gtt_mapping = dev_priv->mm.gtt_mapping =
io_mapping_create_wc(dev->agp->base, io_mapping_create_wc(dev->agp->base,
dev->agp->agp_info.aper_size * 1024*1024); 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 /* Set up a WC MTRR for non-PAT systems. This is more common than
* one would think, because the kernel disables PAT on first * one would think, because the kernel disables PAT on first
* generation Core chips because WC PAT gets overridden by a UC * generation Core chips because WC PAT gets overridden by a UC
...@@ -1122,7 +1127,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) ...@@ -1122,7 +1127,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
if (!I915_NEED_GFX_HWS(dev)) { if (!I915_NEED_GFX_HWS(dev)) {
ret = i915_init_phys_hws(dev); ret = i915_init_phys_hws(dev);
if (ret != 0) if (ret != 0)
goto out_rmmap; goto out_iomapfree;
} }
/* On the 945G/GM, the chipset reports the MSI capability on the /* On the 945G/GM, the chipset reports the MSI capability on the
...@@ -1161,6 +1166,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) ...@@ -1161,6 +1166,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
return 0; return 0;
out_iomapfree:
io_mapping_free(dev_priv->mm.gtt_mapping);
out_rmmap: out_rmmap:
iounmap(dev_priv->regs); iounmap(dev_priv->regs);
free_priv: free_priv:
......
...@@ -30,11 +30,14 @@ ...@@ -30,11 +30,14 @@
* See Documentation/io_mapping.txt * See Documentation/io_mapping.txt
*/ */
/* this struct isn't actually defined anywhere */
struct io_mapping;
#ifdef CONFIG_HAVE_ATOMIC_IOMAP #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 * For small address space machines, mapping large objects
* into the kernel virtual space isn't practical. Where * into the kernel virtual space isn't practical. Where
...@@ -43,23 +46,40 @@ struct io_mapping; ...@@ -43,23 +46,40 @@ struct io_mapping;
*/ */
static inline 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 static inline void
io_mapping_free(struct io_mapping *mapping) io_mapping_free(struct io_mapping *mapping)
{ {
kfree(mapping);
} }
/* Atomic map/unmap */ /* Atomic map/unmap */
static inline void * static inline void *
io_mapping_map_atomic_wc(struct io_mapping *mapping, unsigned long offset) io_mapping_map_atomic_wc(struct io_mapping *mapping, unsigned long offset)
{ {
offset += (unsigned long) mapping; resource_size_t phys_addr;
return iomap_atomic_prot_pfn(offset >> PAGE_SHIFT, KM_USER0, unsigned long pfn;
__pgprot(__PAGE_KERNEL_WC));
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 static inline void
...@@ -71,8 +91,9 @@ io_mapping_unmap_atomic(void *vaddr) ...@@ -71,8 +91,9 @@ io_mapping_unmap_atomic(void *vaddr)
static inline void * static inline void *
io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset) io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset)
{ {
offset += (unsigned long) mapping; BUG_ON(offset >= mapping->size);
return ioremap_wc(offset, PAGE_SIZE); resource_size_t phys_addr = mapping->base + offset;
return ioremap_wc(phys_addr, PAGE_SIZE);
} }
static inline void static inline void
...@@ -83,9 +104,12 @@ io_mapping_unmap(void *vaddr) ...@@ -83,9 +104,12 @@ io_mapping_unmap(void *vaddr)
#else #else
/* this struct isn't actually defined anywhere */
struct io_mapping;
/* Create the io_mapping object*/ /* Create the io_mapping object*/
static inline 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 *) ioremap_wc(base, size); return (struct io_mapping *) ioremap_wc(base, size);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment