14 #include <linux/list.h>
16 #include <linux/errno.h>
18 #include <linux/export.h>
19 #include <linux/slab.h>
21 #include <asm/hw_irq.h>
25 #define MPIC_MSGR_REGISTERS_PER_BLOCK 4
26 #define MPIC_MSGR_STRIDE 0x10
27 #define MPIC_MSGR_MER_OFFSET 0x100
32 static unsigned int mpic_msgr_count;
40 static inline u32 _mpic_msgr_mer_read(
struct mpic_msgr *msgr)
45 static inline void _mpic_msgr_disable(
struct mpic_msgr *msgr)
47 u32 mer = _mpic_msgr_mer_read(msgr);
49 _mpic_msgr_mer_write(msgr, mer & ~(1 << msgr->
num));
58 msgr = ERR_PTR(-
EBUSY);
60 if (reg_num >= mpic_msgr_count)
64 msgr = mpic_msgrs[reg_num];
79 _mpic_msgr_disable(msgr);
90 mer = _mpic_msgr_mer_read(msgr);
91 _mpic_msgr_mer_write(msgr, mer | (1 << msgr->
num));
101 _mpic_msgr_disable(msgr);
110 static unsigned int mpic_msgr_number_of_blocks(
void)
122 snprintf(buf,
sizeof(buf),
"mpic-msgr-block%d", count);
133 static unsigned int mpic_msgr_number_of_registers(
void)
141 unsigned int index, number_of_blocks;
144 number_of_blocks = mpic_msgr_number_of_blocks();
149 for (index = 0; index < number_of_blocks; ++
index) {
152 snprintf(buf,
sizeof(buf),
"mpic-msgr-block%d", index);
158 return index == number_of_blocks ? -1 :
index;
169 unsigned int irq_index;
172 const unsigned int *prop;
183 mpic_msgr_count = mpic_msgr_number_of_registers();
184 dev_info(&dev->
dev,
"Found %d message registers\n",
187 mpic_msgrs = kzalloc(
sizeof(
struct mpic_msgr) * mpic_msgr_count,
191 "No memory for message register blocks\n");
199 msgr_block_addr =
ioremap(rsrc.start, rsrc.end - rsrc.start);
200 if (!msgr_block_addr) {
201 dev_err(&dev->
dev,
"Failed to iomap MPIC message registers");
206 block_number = mpic_msgr_block_number(np);
207 if (block_number < 0) {
209 "Failed to find message register block alias\n");
212 dev_info(&dev->
dev,
"Setting up message register block %d\n",
219 receive_mask = (prop) ? *prop : 0xF;
224 unsigned int reg_number;
228 dev_err(&dev->
dev,
"No memory for message register\n");
232 reg_number = block_number * MPIC_MSGR_REGISTERS_PER_BLOCK +
i;
239 if (receive_mask & (1 << i)) {
244 "Missing interrupt specifier");
254 mpic_msgrs[reg_number] = msgr;
256 dev_info(&dev->
dev,
"Register %d initialized: irq %d\n",
257 reg_number, msgr->
irq);
266 .compatible =
"fsl,mpic-v3.1-msgr",
276 .of_match_table = mpic_msgr_ids,
278 .probe = mpic_msgr_probe,
281 static __init int mpic_msgr_init(
void)