diff options
author | Hauke Mehrtens <hauke@hauke-m.de> | 2013-06-06 13:48:04 +0200 |
---|---|---|
committer | Luis R. Rodriguez <mcgrof@do-not-panic.com> | 2013-06-12 14:50:29 -0700 |
commit | 2ce5c22448bb45998318267c00b5d6ef9cff3170 (patch) | |
tree | 617cc643d30061d8e29f60d82ad1e706595f44f5 /backport | |
parent | 3d933ebf704c18ab3b7cdbd489021631fc1efe88 (diff) |
backports: backport some memory functions
This includes the following functions needed by some drm drivers:
arch_phys_wc_add()
arch_phys_wc_del()
phys_wc_to_mtrr_index()
This backports the following commit form mainline kernel:
commit d0d98eedee2178c803dd824bb09f52b0e2ac1811
Author: Andy Lutomirski <luto@amacapital.net>
Date: Mon May 13 23:58:40 2013 +0000
Add arch_phys_wc_{add, del} to manipulate WC MTRRs if needed
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Signed-off-by: Luis R. Rodriguez <mcgrof@do-not-panic.com>
Diffstat (limited to 'backport')
-rw-r--r-- | backport/backport-include/asm/mtrr.h | 20 | ||||
-rw-r--r-- | backport/backport-include/linux/io.h | 36 | ||||
-rw-r--r-- | backport/compat/Makefile | 1 | ||||
-rw-r--r-- | backport/compat/backport-3.11.c | 91 |
4 files changed, 148 insertions, 0 deletions
diff --git a/backport/backport-include/asm/mtrr.h b/backport/backport-include/asm/mtrr.h new file mode 100644 index 00000000..cf0f6fd3 --- /dev/null +++ b/backport/backport-include/asm/mtrr.h @@ -0,0 +1,20 @@ +#ifndef __BACKPORT_ASM_MTRR_H +#define __BACKPORT_ASM_MTRR_H +#include_next <asm/mtrr.h> + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0)) +/* + * The following functions are for use by other drivers that cannot use + * arch_phys_wc_add and arch_phys_wc_del. + */ +#ifdef CONFIG_MTRR +extern int phys_wc_to_mtrr_index(int handle); +#else +static inline int phys_wc_to_mtrr_index(int handle) +{ + return -1; +} +#endif /* CONFIG_MTRR */ +#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0)) */ + +#endif /* __BACKPORT_ASM_MTRR_H */ diff --git a/backport/backport-include/linux/io.h b/backport/backport-include/linux/io.h new file mode 100644 index 00000000..9a5b308a --- /dev/null +++ b/backport/backport-include/linux/io.h @@ -0,0 +1,36 @@ +#ifndef __BACKPORT_LINUX_IO_H +#define __BACKPORT_LINUX_IO_H +#include_next <linux/io.h> + +/* + * Some systems (x86 without PAT) have a somewhat reliable way to mark a + * physical address range such that uncached mappings will actually + * end up write-combining. This facility should be used in conjunction + * with pgprot_writecombine, ioremap-wc, or set_memory_wc, since it has + * no effect if the per-page mechanisms are functional. + * (On x86 without PAT, these functions manipulate MTRRs.) + * + * arch_phys_del_wc(0) or arch_phys_del_wc(any error code) is guaranteed + * to have no effect. + */ +#ifndef arch_phys_wc_add +#ifdef CONFIG_MTRR +extern int __must_check arch_phys_wc_add(unsigned long base, + unsigned long size); +extern void arch_phys_wc_del(int handle); +#else +static inline int __must_check arch_phys_wc_add(unsigned long base, + unsigned long size) +{ + return 0; /* It worked (i.e. did nothing). */ +} + +static inline void arch_phys_wc_del(int handle) +{ +} +#endif /* CONFIG_MTRR */ + +#define arch_phys_wc_add arch_phys_wc_add +#endif + +#endif /* __BACKPORT_LINUX_IO_H */ diff --git a/backport/compat/Makefile b/backport/compat/Makefile index 18df1561..252290e3 100644 --- a/backport/compat/Makefile +++ b/backport/compat/Makefile @@ -35,6 +35,7 @@ compat-$(CPTCFG_BACKPORT_KERNEL_3_7) += compat-3.7.o compat-$(CPTCFG_BACKPORT_KERNEL_3_8) += compat-3.8.o compat-$(CPTCFG_BACKPORT_KERNEL_3_9) += compat-3.9.o compat-$(CPTCFG_BACKPORT_KERNEL_3_10) += backport-3.10.o +compat-$(CPTCFG_BACKPORT_KERNEL_3_11) += backport-3.11.o compat-$(CPTCFG_BACKPORT_BUILD_KFIFO) += kfifo.o compat-$(CPTCFG_BACKPORT_BUILD_GENERIC_ATOMIC64) += compat_atomic.o diff --git a/backport/compat/backport-3.11.c b/backport/compat/backport-3.11.c new file mode 100644 index 00000000..72e0800c --- /dev/null +++ b/backport/compat/backport-3.11.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013 Hauke Mehrtens <hauke@hauke-m.de> + * + * Compatibility file for Linux wireless for kernels 3.11. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/export.h> + +#ifdef CONFIG_MTRR + +#include <asm/mtrr.h> +#include <asm/cpufeature.h> +#include <linux/io.h> + +/* arch_phys_wc_add returns an MTRR register index plus this offset. */ +#define MTRR_TO_PHYS_WC_OFFSET 1000 + +/** + * arch_phys_wc_add - add a WC MTRR and handle errors if PAT is unavailable + * @base: Physical base address + * @size: Size of region + * + * If PAT is available, this does nothing. If PAT is unavailable, it + * attempts to add a WC MTRR covering size bytes starting at base and + * logs an error if this fails. + * + * Drivers must store the return value to pass to mtrr_del_wc_if_needed, + * but drivers should not try to interpret that return value. + */ +int arch_phys_wc_add(unsigned long base, unsigned long size) +{ + int ret; + +#if defined(CONFIG_X86_PAT) + if (cpu_has_pat) + return 0; +#endif + + ret = mtrr_add(base, size, MTRR_TYPE_WRCOMB, true); + if (ret < 0) { + pr_warn("Failed to add WC MTRR for [%p-%p]; performance may suffer.", + (void *)base, (void *)(base + size - 1)); + return ret; + } + return ret + MTRR_TO_PHYS_WC_OFFSET; +} +EXPORT_SYMBOL(arch_phys_wc_add); + +/* + * arch_phys_wc_del - undoes arch_phys_wc_add + * @handle: Return value from arch_phys_wc_add + * + * This cleans up after mtrr_add_wc_if_needed. + * + * The API guarantees that mtrr_del_wc_if_needed(error code) and + * mtrr_del_wc_if_needed(0) do nothing. + */ +void arch_phys_wc_del(int handle) +{ + if (handle >= 1) { + WARN_ON(handle < MTRR_TO_PHYS_WC_OFFSET); + mtrr_del(handle - MTRR_TO_PHYS_WC_OFFSET, 0, 0); + } +} +EXPORT_SYMBOL(arch_phys_wc_del); + +/* + * phys_wc_to_mtrr_index - translates arch_phys_wc_add's return value + * @handle: Return value from arch_phys_wc_add + * + * This will turn the return value from arch_phys_wc_add into an mtrr + * index suitable for debugging. + * + * Note: There is no legitimate use for this function, except possibly + * in printk line. Alas there is an illegitimate use in some ancient + * drm ioctls. + */ +int phys_wc_to_mtrr_index(int handle) +{ + if (handle < MTRR_TO_PHYS_WC_OFFSET) + return -1; + else + return handle - MTRR_TO_PHYS_WC_OFFSET; +} +EXPORT_SYMBOL_GPL(phys_wc_to_mtrr_index); + +#endif /* CONFIG_MTRR */ |