summaryrefslogtreecommitdiff
path: root/backport
diff options
context:
space:
mode:
authorHauke Mehrtens <hauke@hauke-m.de>2013-06-06 13:48:04 +0200
committerLuis R. Rodriguez <mcgrof@do-not-panic.com>2013-06-12 14:50:29 -0700
commit2ce5c22448bb45998318267c00b5d6ef9cff3170 (patch)
tree617cc643d30061d8e29f60d82ad1e706595f44f5 /backport
parent3d933ebf704c18ab3b7cdbd489021631fc1efe88 (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.h20
-rw-r--r--backport/backport-include/linux/io.h36
-rw-r--r--backport/compat/Makefile1
-rw-r--r--backport/compat/backport-3.11.c91
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 */