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 */ 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 */ 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 */ 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 */ 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 */ 124 static inline int mpic_msgr_get_irq(struct mpic_msgr *msgr) 125 { 126 return msgr->irq; 127 } 128 129 #endif 130