Skip to content

Commit

Permalink
powerpc: add support for MPIC message register API
Browse files Browse the repository at this point in the history
Some MPIC implementations contain one or more blocks of message registers
that are used to send messages between cores via IPIs.  A simple API has
been added to access (get/put, read, write, etc ...) these message registers.
The available message registers are initially discovered via nodes in the
device tree.  A separate commit contains a binding for the message register
nodes.

Signed-off-by: Meador Inge <meador_inge@mentor.com>
Signed-off-by: Jia Hongtao <B38951@freescale.com>
Signed-off-by: Li Yang <leoli@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
  • Loading branch information
Jia Hongtao authored and Kumar Gala committed Mar 16, 2012
1 parent da3b6c0 commit 8626816
Show file tree
Hide file tree
Showing 4 changed files with 424 additions and 0 deletions.
132 changes: 132 additions & 0 deletions arch/powerpc/include/asm/mpic_msgr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/*
* Copyright 2011-2012, Meador Inge, Mentor Graphics Corporation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2 of the
* License.
*
*/

#ifndef _ASM_MPIC_MSGR_H
#define _ASM_MPIC_MSGR_H

#include <linux/types.h>
#include <linux/spinlock.h>

struct mpic_msgr {
u32 __iomem *base;
u32 __iomem *mer;
int irq;
unsigned char in_use;
raw_spinlock_t lock;
int num;
};

/* Get a message register
*
* @reg_num: the MPIC message register to get
*
* A pointer to the message register is returned. If
* the message register asked for is already in use, then
* EBUSY is returned. If the number given is not associated
* with an actual message register, then ENODEV is returned.
* Successfully getting the register marks it as in use.
*/
extern struct mpic_msgr *mpic_msgr_get(unsigned int reg_num);

/* Relinquish a message register
*
* @msgr: the message register to return
*
* Disables the given message register and marks it as free.
* After this call has completed successully the message
* register is available to be acquired by a call to
* mpic_msgr_get.
*/
extern void mpic_msgr_put(struct mpic_msgr *msgr);

/* Enable a message register
*
* @msgr: the message register to enable
*
* The given message register is enabled for sending
* messages.
*/
extern void mpic_msgr_enable(struct mpic_msgr *msgr);

/* Disable a message register
*
* @msgr: the message register to disable
*
* The given message register is disabled for sending
* messages.
*/
extern void mpic_msgr_disable(struct mpic_msgr *msgr);

/* Write a message to a message register
*
* @msgr: the message register to write to
* @message: the message to write
*
* The given 32-bit message is written to the given message
* register. Writing to an enabled message registers fires
* an interrupt.
*/
static inline void mpic_msgr_write(struct mpic_msgr *msgr, u32 message)
{
out_be32(msgr->base, message);
}

/* Read a message from a message register
*
* @msgr: the message register to read from
*
* Returns the 32-bit value currently in the given message register.
* Upon reading the register any interrupts for that register are
* cleared.
*/
static inline u32 mpic_msgr_read(struct mpic_msgr *msgr)
{
return in_be32(msgr->base);
}

/* Clear a message register
*
* @msgr: the message register to clear
*
* Clears any interrupts associated with the given message register.
*/
static inline void mpic_msgr_clear(struct mpic_msgr *msgr)
{
(void) mpic_msgr_read(msgr);
}

/* Set the destination CPU for the message register
*
* @msgr: the message register whose destination is to be set
* @cpu_num: the Linux CPU number to bind the message register to
*
* Note that the CPU number given is the CPU number used by the kernel
* and *not* the actual hardware CPU number.
*/
static inline void mpic_msgr_set_destination(struct mpic_msgr *msgr,
u32 cpu_num)
{
out_be32(msgr->base, 1 << get_hard_smp_processor_id(cpu_num));
}

/* Get the IRQ number for the message register
* @msgr: the message register whose IRQ is to be returned
*
* Returns the IRQ number associated with the given message register.
* NO_IRQ is returned if this message register is not capable of
* receiving interrupts. What message register can and cannot receive
* interrupts is specified in the device tree for the system.
*/
static inline int mpic_msgr_get_irq(struct mpic_msgr *msgr)
{
return msgr->irq;
}

#endif
8 changes: 8 additions & 0 deletions arch/powerpc/platforms/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,14 @@ config MPIC_WEIRD
bool
default n

config MPIC_MSGR
bool "MPIC message register support"
depends on MPIC
default n
help
Enables support for the MPIC message registers. These
registers are used for inter-processor communication.

config PPC_I8259
bool
default n
Expand Down
2 changes: 2 additions & 0 deletions arch/powerpc/sysdev/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ ccflags-$(CONFIG_PPC64) := -mno-minimal-toc

mpic-msi-obj-$(CONFIG_PCI_MSI) += mpic_msi.o mpic_u3msi.o mpic_pasemi_msi.o
obj-$(CONFIG_MPIC) += mpic.o $(mpic-msi-obj-y)
mpic-msgr-obj-$(CONFIG_MPIC_MSGR) += mpic_msgr.o
obj-$(CONFIG_MPIC) += mpic.o $(mpic-msi-obj-y) $(mpic-msgr-obj-y)
obj-$(CONFIG_PPC_EPAPR_HV_PIC) += ehv_pic.o
fsl-msi-obj-$(CONFIG_PCI_MSI) += fsl_msi.o
obj-$(CONFIG_PPC_MSI_BITMAP) += msi_bitmap.o
Expand Down
Loading

0 comments on commit 8626816

Please sign in to comment.