Merge branch 'x86/urgent' into x86/core
Conflicts: arch/x86/mach-voyager/voyager_smp.c
This commit is contained in:
commit
13b2eda64d
5 changed files with 67 additions and 12 deletions
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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…
Reference in a new issue