Linux Audio

Check our new training course

Loading...
v5.9
 1// SPDX-License-Identifier: GPL-2.0-or-later
 2/*
 3 * Author: Kumar Gala <galak@kernel.crashing.org>
 4 *
 5 * Copyright 2009 Freescale Semiconductor Inc.
 6 */
 7
 8#include <linux/stddef.h>
 9#include <linux/kernel.h>
10#include <linux/smp.h>
11#include <linux/threads.h>
12#include <linux/hardirq.h>
13
14#include <asm/dbell.h>
15#include <asm/irq_regs.h>
16#include <asm/kvm_ppc.h>
17#include <asm/trace.h>
18
19#ifdef CONFIG_SMP
20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21void doorbell_exception(struct pt_regs *regs)
22{
23	struct pt_regs *old_regs = set_irq_regs(regs);
24
25	irq_enter();
26	trace_doorbell_entry(regs);
27
28	ppc_msgsync();
29
30	may_hard_irq_enable();
31
32	kvmppc_clear_host_ipi(smp_processor_id());
33	__this_cpu_inc(irq_stat.doorbell_irqs);
34
35	smp_ipi_demux_relaxed(); /* already performed the barrier */
36
37	trace_doorbell_exit(regs);
38	irq_exit();
39	set_irq_regs(old_regs);
40}
41#else /* CONFIG_SMP */
42void doorbell_exception(struct pt_regs *regs)
43{
44	printk(KERN_WARNING "Received doorbell on non-smp system\n");
45}
46#endif /* CONFIG_SMP */
47
v5.4
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * Author: Kumar Gala <galak@kernel.crashing.org>
  4 *
  5 * Copyright 2009 Freescale Semiconductor Inc.
  6 */
  7
  8#include <linux/stddef.h>
  9#include <linux/kernel.h>
 10#include <linux/smp.h>
 11#include <linux/threads.h>
 12#include <linux/hardirq.h>
 13
 14#include <asm/dbell.h>
 15#include <asm/irq_regs.h>
 16#include <asm/kvm_ppc.h>
 17#include <asm/trace.h>
 18
 19#ifdef CONFIG_SMP
 20
 21/*
 22 * Doorbells must only be used if CPU_FTR_DBELL is available.
 23 * msgsnd is used in HV, and msgsndp is used in !HV.
 24 *
 25 * These should be used by platform code that is aware of restrictions.
 26 * Other arch code should use ->cause_ipi.
 27 *
 28 * doorbell_global_ipi() sends a dbell to any target CPU.
 29 * Must be used only by architectures that address msgsnd target
 30 * by PIR/get_hard_smp_processor_id.
 31 */
 32void doorbell_global_ipi(int cpu)
 33{
 34	u32 tag = get_hard_smp_processor_id(cpu);
 35
 36	kvmppc_set_host_ipi(cpu);
 37	/* Order previous accesses vs. msgsnd, which is treated as a store */
 38	ppc_msgsnd_sync();
 39	ppc_msgsnd(PPC_DBELL_MSGTYPE, 0, tag);
 40}
 41
 42/*
 43 * doorbell_core_ipi() sends a dbell to a target CPU in the same core.
 44 * Must be used only by architectures that address msgsnd target
 45 * by TIR/cpu_thread_in_core.
 46 */
 47void doorbell_core_ipi(int cpu)
 48{
 49	u32 tag = cpu_thread_in_core(cpu);
 50
 51	kvmppc_set_host_ipi(cpu);
 52	/* Order previous accesses vs. msgsnd, which is treated as a store */
 53	ppc_msgsnd_sync();
 54	ppc_msgsnd(PPC_DBELL_MSGTYPE, 0, tag);
 55}
 56
 57/*
 58 * Attempt to cause a core doorbell if destination is on the same core.
 59 * Returns 1 on success, 0 on failure.
 60 */
 61int doorbell_try_core_ipi(int cpu)
 62{
 63	int this_cpu = get_cpu();
 64	int ret = 0;
 65
 66	if (cpumask_test_cpu(cpu, cpu_sibling_mask(this_cpu))) {
 67		doorbell_core_ipi(cpu);
 68		ret = 1;
 69	}
 70
 71	put_cpu();
 72
 73	return ret;
 74}
 75
 76void doorbell_exception(struct pt_regs *regs)
 77{
 78	struct pt_regs *old_regs = set_irq_regs(regs);
 79
 80	irq_enter();
 81	trace_doorbell_entry(regs);
 82
 83	ppc_msgsync();
 84
 85	may_hard_irq_enable();
 86
 87	kvmppc_clear_host_ipi(smp_processor_id());
 88	__this_cpu_inc(irq_stat.doorbell_irqs);
 89
 90	smp_ipi_demux_relaxed(); /* already performed the barrier */
 91
 92	trace_doorbell_exit(regs);
 93	irq_exit();
 94	set_irq_regs(old_regs);
 95}
 96#else /* CONFIG_SMP */
 97void doorbell_exception(struct pt_regs *regs)
 98{
 99	printk(KERN_WARNING "Received doorbell on non-smp system\n");
100}
101#endif /* CONFIG_SMP */
102