18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright 2011-2012, Meador Inge, Mentor Graphics Corporation.
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#ifndef _ASM_MPIC_MSGR_H
78c2ecf20Sopenharmony_ci#define _ASM_MPIC_MSGR_H
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#include <linux/types.h>
108c2ecf20Sopenharmony_ci#include <linux/spinlock.h>
118c2ecf20Sopenharmony_ci#include <asm/smp.h>
128c2ecf20Sopenharmony_ci#include <asm/io.h>
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_cistruct mpic_msgr {
158c2ecf20Sopenharmony_ci	u32 __iomem *base;
168c2ecf20Sopenharmony_ci	u32 __iomem *mer;
178c2ecf20Sopenharmony_ci	int irq;
188c2ecf20Sopenharmony_ci	unsigned char in_use;
198c2ecf20Sopenharmony_ci	raw_spinlock_t lock;
208c2ecf20Sopenharmony_ci	int num;
218c2ecf20Sopenharmony_ci};
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci/* Get a message register
248c2ecf20Sopenharmony_ci *
258c2ecf20Sopenharmony_ci * @reg_num:	the MPIC message register to get
268c2ecf20Sopenharmony_ci *
278c2ecf20Sopenharmony_ci * A pointer to the message register is returned.  If
288c2ecf20Sopenharmony_ci * the message register asked for is already in use, then
298c2ecf20Sopenharmony_ci * EBUSY is returned.  If the number given is not associated
308c2ecf20Sopenharmony_ci * with an actual message register, then ENODEV is returned.
318c2ecf20Sopenharmony_ci * Successfully getting the register marks it as in use.
328c2ecf20Sopenharmony_ci */
338c2ecf20Sopenharmony_ciextern struct mpic_msgr *mpic_msgr_get(unsigned int reg_num);
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci/* Relinquish a message register
368c2ecf20Sopenharmony_ci *
378c2ecf20Sopenharmony_ci * @msgr:	the message register to return
388c2ecf20Sopenharmony_ci *
398c2ecf20Sopenharmony_ci * Disables the given message register and marks it as free.
408c2ecf20Sopenharmony_ci * After this call has completed successully the message
418c2ecf20Sopenharmony_ci * register is available to be acquired by a call to
428c2ecf20Sopenharmony_ci * mpic_msgr_get.
438c2ecf20Sopenharmony_ci */
448c2ecf20Sopenharmony_ciextern void mpic_msgr_put(struct mpic_msgr *msgr);
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci/* Enable a message register
478c2ecf20Sopenharmony_ci *
488c2ecf20Sopenharmony_ci * @msgr:	the message register to enable
498c2ecf20Sopenharmony_ci *
508c2ecf20Sopenharmony_ci * The given message register is enabled for sending
518c2ecf20Sopenharmony_ci * messages.
528c2ecf20Sopenharmony_ci */
538c2ecf20Sopenharmony_ciextern void mpic_msgr_enable(struct mpic_msgr *msgr);
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci/* Disable a message register
568c2ecf20Sopenharmony_ci *
578c2ecf20Sopenharmony_ci * @msgr:	the message register to disable
588c2ecf20Sopenharmony_ci *
598c2ecf20Sopenharmony_ci * The given message register is disabled for sending
608c2ecf20Sopenharmony_ci * messages.
618c2ecf20Sopenharmony_ci */
628c2ecf20Sopenharmony_ciextern void mpic_msgr_disable(struct mpic_msgr *msgr);
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci/* Write a message to a message register
658c2ecf20Sopenharmony_ci *
668c2ecf20Sopenharmony_ci * @msgr:	the message register to write to
678c2ecf20Sopenharmony_ci * @message:	the message to write
688c2ecf20Sopenharmony_ci *
698c2ecf20Sopenharmony_ci * The given 32-bit message is written to the given message
708c2ecf20Sopenharmony_ci * register.  Writing to an enabled message registers fires
718c2ecf20Sopenharmony_ci * an interrupt.
728c2ecf20Sopenharmony_ci */
738c2ecf20Sopenharmony_cistatic inline void mpic_msgr_write(struct mpic_msgr *msgr, u32 message)
748c2ecf20Sopenharmony_ci{
758c2ecf20Sopenharmony_ci	out_be32(msgr->base, message);
768c2ecf20Sopenharmony_ci}
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci/* Read a message from a message register
798c2ecf20Sopenharmony_ci *
808c2ecf20Sopenharmony_ci * @msgr:	the message register to read from
818c2ecf20Sopenharmony_ci *
828c2ecf20Sopenharmony_ci * Returns the 32-bit value currently in the given message register.
838c2ecf20Sopenharmony_ci * Upon reading the register any interrupts for that register are
848c2ecf20Sopenharmony_ci * cleared.
858c2ecf20Sopenharmony_ci */
868c2ecf20Sopenharmony_cistatic inline u32 mpic_msgr_read(struct mpic_msgr *msgr)
878c2ecf20Sopenharmony_ci{
888c2ecf20Sopenharmony_ci	return in_be32(msgr->base);
898c2ecf20Sopenharmony_ci}
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_ci/* Clear a message register
928c2ecf20Sopenharmony_ci *
938c2ecf20Sopenharmony_ci * @msgr:	the message register to clear
948c2ecf20Sopenharmony_ci *
958c2ecf20Sopenharmony_ci * Clears any interrupts associated with the given message register.
968c2ecf20Sopenharmony_ci */
978c2ecf20Sopenharmony_cistatic inline void mpic_msgr_clear(struct mpic_msgr *msgr)
988c2ecf20Sopenharmony_ci{
998c2ecf20Sopenharmony_ci	(void) mpic_msgr_read(msgr);
1008c2ecf20Sopenharmony_ci}
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci/* Set the destination CPU for the message register
1038c2ecf20Sopenharmony_ci *
1048c2ecf20Sopenharmony_ci * @msgr:	the message register whose destination is to be set
1058c2ecf20Sopenharmony_ci * @cpu_num:	the Linux CPU number to bind the message register to
1068c2ecf20Sopenharmony_ci *
1078c2ecf20Sopenharmony_ci * Note that the CPU number given is the CPU number used by the kernel
1088c2ecf20Sopenharmony_ci * and *not* the actual hardware CPU number.
1098c2ecf20Sopenharmony_ci */
1108c2ecf20Sopenharmony_cistatic inline void mpic_msgr_set_destination(struct mpic_msgr *msgr,
1118c2ecf20Sopenharmony_ci					     u32 cpu_num)
1128c2ecf20Sopenharmony_ci{
1138c2ecf20Sopenharmony_ci	out_be32(msgr->base, 1 << get_hard_smp_processor_id(cpu_num));
1148c2ecf20Sopenharmony_ci}
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ci/* Get the IRQ number for the message register
1178c2ecf20Sopenharmony_ci * @msgr:	the message register whose IRQ is to be returned
1188c2ecf20Sopenharmony_ci *
1198c2ecf20Sopenharmony_ci * Returns the IRQ number associated with the given message register.
1208c2ecf20Sopenharmony_ci * 0 is returned if this message register is not capable of receiving
1218c2ecf20Sopenharmony_ci * interrupts.  What message register can and cannot receive interrupts is
1228c2ecf20Sopenharmony_ci * specified in the device tree for the system.
1238c2ecf20Sopenharmony_ci */
1248c2ecf20Sopenharmony_cistatic inline int mpic_msgr_get_irq(struct mpic_msgr *msgr)
1258c2ecf20Sopenharmony_ci{
1268c2ecf20Sopenharmony_ci	return msgr->irq;
1278c2ecf20Sopenharmony_ci}
1288c2ecf20Sopenharmony_ci
1298c2ecf20Sopenharmony_ci#endif
130