diff options
Diffstat (limited to 'arch/powerpc/sysdev/fsl_rmu.c')
-rw-r--r-- | arch/powerpc/sysdev/fsl_rmu.c | 42 |
1 files changed, 22 insertions, 20 deletions
diff --git a/arch/powerpc/sysdev/fsl_rmu.c b/arch/powerpc/sysdev/fsl_rmu.c index 15485789e9db..14bd5221f28a 100644 --- a/arch/powerpc/sysdev/fsl_rmu.c +++ b/arch/powerpc/sysdev/fsl_rmu.c | |||
@@ -100,14 +100,8 @@ | |||
100 | #define DOORBELL_DSR_TE 0x00000080 | 100 | #define DOORBELL_DSR_TE 0x00000080 |
101 | #define DOORBELL_DSR_QFI 0x00000010 | 101 | #define DOORBELL_DSR_QFI 0x00000010 |
102 | #define DOORBELL_DSR_DIQI 0x00000001 | 102 | #define DOORBELL_DSR_DIQI 0x00000001 |
103 | #define DOORBELL_TID_OFFSET 0x02 | ||
104 | #define DOORBELL_SID_OFFSET 0x04 | ||
105 | #define DOORBELL_INFO_OFFSET 0x06 | ||
106 | 103 | ||
107 | #define DOORBELL_MESSAGE_SIZE 0x08 | 104 | #define DOORBELL_MESSAGE_SIZE 0x08 |
108 | #define DBELL_SID(x) (*(u16 *)(x + DOORBELL_SID_OFFSET)) | ||
109 | #define DBELL_TID(x) (*(u16 *)(x + DOORBELL_TID_OFFSET)) | ||
110 | #define DBELL_INF(x) (*(u16 *)(x + DOORBELL_INFO_OFFSET)) | ||
111 | 105 | ||
112 | struct rio_msg_regs { | 106 | struct rio_msg_regs { |
113 | u32 omr; | 107 | u32 omr; |
@@ -193,6 +187,13 @@ struct fsl_rmu { | |||
193 | int rxirq; | 187 | int rxirq; |
194 | }; | 188 | }; |
195 | 189 | ||
190 | struct rio_dbell_msg { | ||
191 | u16 pad1; | ||
192 | u16 tid; | ||
193 | u16 sid; | ||
194 | u16 info; | ||
195 | }; | ||
196 | |||
196 | /** | 197 | /** |
197 | * fsl_rio_tx_handler - MPC85xx outbound message interrupt handler | 198 | * fsl_rio_tx_handler - MPC85xx outbound message interrupt handler |
198 | * @irq: Linux interrupt number | 199 | * @irq: Linux interrupt number |
@@ -311,8 +312,8 @@ fsl_rio_dbell_handler(int irq, void *dev_instance) | |||
311 | 312 | ||
312 | /* XXX Need to check/dispatch until queue empty */ | 313 | /* XXX Need to check/dispatch until queue empty */ |
313 | if (dsr & DOORBELL_DSR_DIQI) { | 314 | if (dsr & DOORBELL_DSR_DIQI) { |
314 | u32 dmsg = | 315 | struct rio_dbell_msg *dmsg = |
315 | (u32) fsl_dbell->dbell_ring.virt + | 316 | fsl_dbell->dbell_ring.virt + |
316 | (in_be32(&fsl_dbell->dbell_regs->dqdpar) & 0xfff); | 317 | (in_be32(&fsl_dbell->dbell_regs->dqdpar) & 0xfff); |
317 | struct rio_dbell *dbell; | 318 | struct rio_dbell *dbell; |
318 | int found = 0; | 319 | int found = 0; |
@@ -320,25 +321,25 @@ fsl_rio_dbell_handler(int irq, void *dev_instance) | |||
320 | pr_debug | 321 | pr_debug |
321 | ("RIO: processing doorbell," | 322 | ("RIO: processing doorbell," |
322 | " sid %2.2x tid %2.2x info %4.4x\n", | 323 | " sid %2.2x tid %2.2x info %4.4x\n", |
323 | DBELL_SID(dmsg), DBELL_TID(dmsg), DBELL_INF(dmsg)); | 324 | dmsg->sid, dmsg->tid, dmsg->info); |
324 | 325 | ||
325 | for (i = 0; i < MAX_PORT_NUM; i++) { | 326 | for (i = 0; i < MAX_PORT_NUM; i++) { |
326 | if (fsl_dbell->mport[i]) { | 327 | if (fsl_dbell->mport[i]) { |
327 | list_for_each_entry(dbell, | 328 | list_for_each_entry(dbell, |
328 | &fsl_dbell->mport[i]->dbells, node) { | 329 | &fsl_dbell->mport[i]->dbells, node) { |
329 | if ((dbell->res->start | 330 | if ((dbell->res->start |
330 | <= DBELL_INF(dmsg)) | 331 | <= dmsg->info) |
331 | && (dbell->res->end | 332 | && (dbell->res->end |
332 | >= DBELL_INF(dmsg))) { | 333 | >= dmsg->info)) { |
333 | found = 1; | 334 | found = 1; |
334 | break; | 335 | break; |
335 | } | 336 | } |
336 | } | 337 | } |
337 | if (found && dbell->dinb) { | 338 | if (found && dbell->dinb) { |
338 | dbell->dinb(fsl_dbell->mport[i], | 339 | dbell->dinb(fsl_dbell->mport[i], |
339 | dbell->dev_id, DBELL_SID(dmsg), | 340 | dbell->dev_id, dmsg->sid, |
340 | DBELL_TID(dmsg), | 341 | dmsg->tid, |
341 | DBELL_INF(dmsg)); | 342 | dmsg->info); |
342 | break; | 343 | break; |
343 | } | 344 | } |
344 | } | 345 | } |
@@ -348,8 +349,8 @@ fsl_rio_dbell_handler(int irq, void *dev_instance) | |||
348 | pr_debug | 349 | pr_debug |
349 | ("RIO: spurious doorbell," | 350 | ("RIO: spurious doorbell," |
350 | " sid %2.2x tid %2.2x info %4.4x\n", | 351 | " sid %2.2x tid %2.2x info %4.4x\n", |
351 | DBELL_SID(dmsg), DBELL_TID(dmsg), | 352 | dmsg->sid, dmsg->tid, |
352 | DBELL_INF(dmsg)); | 353 | dmsg->info); |
353 | } | 354 | } |
354 | setbits32(&fsl_dbell->dbell_regs->dmr, DOORBELL_DMR_DI); | 355 | setbits32(&fsl_dbell->dbell_regs->dmr, DOORBELL_DMR_DI); |
355 | out_be32(&fsl_dbell->dbell_regs->dsr, DOORBELL_DSR_DIQI); | 356 | out_be32(&fsl_dbell->dbell_regs->dsr, DOORBELL_DSR_DIQI); |
@@ -657,7 +658,7 @@ fsl_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox, | |||
657 | int ret = 0; | 658 | int ret = 0; |
658 | 659 | ||
659 | pr_debug("RIO: fsl_add_outb_message(): destid %4.4x mbox %d buffer " \ | 660 | pr_debug("RIO: fsl_add_outb_message(): destid %4.4x mbox %d buffer " \ |
660 | "%8.8x len %8.8x\n", rdev->destid, mbox, (int)buffer, len); | 661 | "%p len %8.8zx\n", rdev->destid, mbox, buffer, len); |
661 | if ((len < 8) || (len > RIO_MAX_MSG_SIZE)) { | 662 | if ((len < 8) || (len > RIO_MAX_MSG_SIZE)) { |
662 | ret = -EINVAL; | 663 | ret = -EINVAL; |
663 | goto out; | 664 | goto out; |
@@ -972,7 +973,8 @@ out: | |||
972 | void *fsl_get_inb_message(struct rio_mport *mport, int mbox) | 973 | void *fsl_get_inb_message(struct rio_mport *mport, int mbox) |
973 | { | 974 | { |
974 | struct fsl_rmu *rmu = GET_RMM_HANDLE(mport); | 975 | struct fsl_rmu *rmu = GET_RMM_HANDLE(mport); |
975 | u32 phys_buf, virt_buf; | 976 | u32 phys_buf; |
977 | void *virt_buf; | ||
976 | void *buf = NULL; | 978 | void *buf = NULL; |
977 | int buf_idx; | 979 | int buf_idx; |
978 | 980 | ||
@@ -982,7 +984,7 @@ void *fsl_get_inb_message(struct rio_mport *mport, int mbox) | |||
982 | if (phys_buf == in_be32(&rmu->msg_regs->ifqepar)) | 984 | if (phys_buf == in_be32(&rmu->msg_regs->ifqepar)) |
983 | goto out2; | 985 | goto out2; |
984 | 986 | ||
985 | virt_buf = (u32) rmu->msg_rx_ring.virt + (phys_buf | 987 | virt_buf = rmu->msg_rx_ring.virt + (phys_buf |
986 | - rmu->msg_rx_ring.phys); | 988 | - rmu->msg_rx_ring.phys); |
987 | buf_idx = (phys_buf - rmu->msg_rx_ring.phys) / RIO_MAX_MSG_SIZE; | 989 | buf_idx = (phys_buf - rmu->msg_rx_ring.phys) / RIO_MAX_MSG_SIZE; |
988 | buf = rmu->msg_rx_ring.virt_buffer[buf_idx]; | 990 | buf = rmu->msg_rx_ring.virt_buffer[buf_idx]; |
@@ -994,7 +996,7 @@ void *fsl_get_inb_message(struct rio_mport *mport, int mbox) | |||
994 | } | 996 | } |
995 | 997 | ||
996 | /* Copy max message size, caller is expected to allocate that big */ | 998 | /* Copy max message size, caller is expected to allocate that big */ |
997 | memcpy(buf, (void *)virt_buf, RIO_MAX_MSG_SIZE); | 999 | memcpy(buf, virt_buf, RIO_MAX_MSG_SIZE); |
998 | 1000 | ||
999 | /* Clear the available buffer */ | 1001 | /* Clear the available buffer */ |
1000 | rmu->msg_rx_ring.virt_buffer[buf_idx] = NULL; | 1002 | rmu->msg_rx_ring.virt_buffer[buf_idx] = NULL; |