summaryrefslogtreecommitdiffstats
path: root/arch/tile/kernel/smp.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@osg.samsung.com>2015-04-21 11:33:03 +0200
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2015-04-21 14:44:55 +0200
commit64131a87f2aae2ed9e05d8227c5b009ca6c50d98 (patch)
treefdea23fd59216120bf54a48c60ca24489a733f14 /arch/tile/kernel/smp.c
parentMerge branch 'patchwork' into v4l_for_linus (diff)
parentMerge Linus master into drm-next (diff)
downloadlinux-64131a87f2aae2ed9e05d8227c5b009ca6c50d98.tar.xz
linux-64131a87f2aae2ed9e05d8227c5b009ca6c50d98.zip
Merge branch 'drm-next-merged' of git://people.freedesktop.org/~airlied/linux into v4l_for_linus
* 'drm-next-merged' of git://people.freedesktop.org/~airlied/linux: (9717 commits) media-bus: Fixup RGB444_1X12, RGB565_1X16, and YUV8_1X24 media bus format hexdump: avoid warning in test function fs: take i_mutex during prepare_binprm for set[ug]id executables smp: Fix error case handling in smp_call_function_*() iommu-common: Fix PARISC compile-time warnings sparc: Make LDC use common iommu poll management functions sparc: Make sparc64 use scalable lib/iommu-common.c functions Break up monolithic iommu table/lock into finer graularity pools and lock sparc: Revert generic IOMMU allocator. tools/power turbostat: correct dumped pkg-cstate-limit value tools/power turbostat: calculate TSC frequency from CPUID(0x15) on SKL tools/power turbostat: correct DRAM RAPL units on recent Xeon processors tools/power turbostat: Initial Skylake support tools/power turbostat: Use $(CURDIR) instead of $(PWD) and add support for O= option in Makefile tools/power turbostat: modprobe msr, if needed tools/power turbostat: dump MSR_TURBO_RATIO_LIMIT2 tools/power turbostat: use new MSR_TURBO_RATIO_LIMIT names Bluetooth: hidp: Fix regression with older userspace and flags validation config: Enable NEED_DMA_MAP_STATE by default when SWIOTLB is selected perf/x86/intel/pt: Fix and clean up error handling in pt_event_add() ... That solves several merge conflicts: Documentation/DocBook/media/v4l/subdev-formats.xml Documentation/devicetree/bindings/vendor-prefixes.txt drivers/staging/media/mn88473/mn88473.c include/linux/kconfig.h include/uapi/linux/media-bus-format.h The ones at subdev-formats.xml and media-bus-format.h are not trivial. That's why we opted to merge from DRM.
Diffstat (limited to 'arch/tile/kernel/smp.c')
-rw-r--r--arch/tile/kernel/smp.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/arch/tile/kernel/smp.c b/arch/tile/kernel/smp.c
index d3c4ed780ce2..07e3ff5cc740 100644
--- a/arch/tile/kernel/smp.c
+++ b/arch/tile/kernel/smp.c
@@ -18,6 +18,7 @@
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/irq.h>
+#include <linux/irq_work.h>
#include <linux/module.h>
#include <asm/cacheflush.h>
#include <asm/homecache.h>
@@ -33,6 +34,8 @@ EXPORT_SYMBOL(smp_topology);
static unsigned long __iomem *ipi_mappings[NR_CPUS];
#endif
+/* Does messaging work correctly to the local cpu? */
+bool self_interrupt_ok;
/*
* Top-level send_IPI*() functions to send messages to other cpus.
@@ -147,6 +150,10 @@ void evaluate_message(int tag)
generic_smp_call_function_single_interrupt();
break;
+ case MSG_TAG_IRQ_WORK: /* Invoke IRQ work */
+ irq_work_run();
+ break;
+
default:
panic("Unknown IPI message tag %d", tag);
break;
@@ -186,6 +193,15 @@ void flush_icache_range(unsigned long start, unsigned long end)
EXPORT_SYMBOL(flush_icache_range);
+#ifdef CONFIG_IRQ_WORK
+void arch_irq_work_raise(void)
+{
+ if (arch_irq_work_has_interrupt())
+ send_IPI_single(smp_processor_id(), MSG_TAG_IRQ_WORK);
+}
+#endif
+
+
/* Called when smp_send_reschedule() triggers IRQ_RESCHEDULE. */
static irqreturn_t handle_reschedule_ipi(int irq, void *token)
{
@@ -203,8 +219,22 @@ static struct irqaction resched_action = {
void __init ipi_init(void)
{
+ int cpu = smp_processor_id();
+ HV_Recipient recip = { .y = cpu_y(cpu), .x = cpu_x(cpu),
+ .state = HV_TO_BE_SENT };
+ int tag = MSG_TAG_CALL_FUNCTION_SINGLE;
+
+ /*
+ * Test if we can message ourselves for arch_irq_work_raise.
+ * This functionality is only available in the Tilera hypervisor
+ * in versions 4.3.4 and following.
+ */
+ if (hv_send_message(&recip, 1, (HV_VirtAddr)&tag, sizeof(tag)) == 1)
+ self_interrupt_ok = true;
+ else
+ pr_warn("Older hypervisor: disabling fast irq_work_raise\n");
+
#if CHIP_HAS_IPI()
- int cpu;
/* Map IPI trigger MMIO addresses. */
for_each_possible_cpu(cpu) {
HV_Coord tile;