1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3 * Copyright 2011-2012, Meador Inge, Mentor Graphics Corporation.
4 */
5
6 #ifndef _ASM_MPIC_MSGR_H
7 #define _ASM_MPIC_MSGR_H
8
9 #include <linux/types.h>
10 #include <linux/spinlock.h>
11 #include <asm/smp.h>
12 #include <asm/io.h>
13
14 struct mpic_msgr {
15 u32 __iomem *base;
16 u32 __iomem *mer;
17 int irq;
18 unsigned char in_use;
19 raw_spinlock_t lock;
20 int num;
21 };
22
23 /* Get a message register
24 *
25 * @reg_num: the MPIC message register to get
26 *
27 * A pointer to the message register is returned. If
28 * the message register asked for is already in use, then
29 * EBUSY is returned. If the number given is not associated
30 * with an actual message register, then ENODEV is returned.
31 * Successfully getting the register marks it as in use.
32 */
33 extern struct mpic_msgr *mpic_msgr_get(unsigned int reg_num);
34
35 /* Relinquish a message register
36 *
37 * @msgr: the message register to return
38 *
39 * Disables the given message register and marks it as free.
40 * After this call has completed successully the message
41 * register is available to be acquired by a call to
42 * mpic_msgr_get.
43 */
44 extern void mpic_msgr_put(struct mpic_msgr *msgr);
45
46 /* Enable a message register
47 *
48 * @msgr: the message register to enable
49 *
50 * The given message register is enabled for sending
51 * messages.
52 */
53 extern void mpic_msgr_enable(struct mpic_msgr *msgr);
54
55 /* Disable a message register
56 *
57 * @msgr: the message register to disable
58 *
59 * The given message register is disabled for sending
60 * messages.
61 */
62 extern void mpic_msgr_disable(struct mpic_msgr *msgr);
63
64 /* Write a message to a message register
65 *
66 * @msgr: the message register to write to
67 * @message: the message to write
68 *
69 * The given 32-bit message is written to the given message
70 * register. Writing to an enabled message registers fires
71 * an interrupt.
72 */
mpic_msgr_write(struct mpic_msgr * msgr,u32 message)73 static inline void mpic_msgr_write(struct mpic_msgr *msgr, u32 message)
74 {
75 out_be32(msgr->base, message);
76 }
77
78 /* Read a message from a message register
79 *
80 * @msgr: the message register to read from
81 *
82 * Returns the 32-bit value currently in the given message register.
83 * Upon reading the register any interrupts for that register are
84 * cleared.
85 */
mpic_msgr_read(struct mpic_msgr * msgr)86 static inline u32 mpic_msgr_read(struct mpic_msgr *msgr)
87 {
88 return in_be32(msgr->base);
89 }
90
91 /* Clear a message register
92 *
93 * @msgr: the message register to clear
94 *
95 * Clears any interrupts associated with the given message register.
96 */
mpic_msgr_clear(struct mpic_msgr * msgr)97 static inline void mpic_msgr_clear(struct mpic_msgr *msgr)
98 {
99 (void) mpic_msgr_read(msgr);
100 }
101
102 /* Set the destination CPU for the message register
103 *
104 * @msgr: the message register whose destination is to be set
105 * @cpu_num: the Linux CPU number to bind the message register to
106 *
107 * Note that the CPU number given is the CPU number used by the kernel
108 * and *not* the actual hardware CPU number.
109 */
mpic_msgr_set_destination(struct mpic_msgr * msgr,u32 cpu_num)110 static inline void mpic_msgr_set_destination(struct mpic_msgr *msgr,
111 u32 cpu_num)
112 {
113 out_be32(msgr->base, 1 << get_hard_smp_processor_id(cpu_num));
114 }
115
116 /* Get the IRQ number for the message register
117 * @msgr: the message register whose IRQ is to be returned
118 *
119 * Returns the IRQ number associated with the given message register.
120 * 0 is returned if this message register is not capable of receiving
121 * interrupts. What message register can and cannot receive interrupts is
122 * specified in the device tree for the system.
123 */
mpic_msgr_get_irq(struct mpic_msgr * msgr)124 static inline int mpic_msgr_get_irq(struct mpic_msgr *msgr)
125 {
126 return msgr->irq;
127 }
128
129 #endif
130