diff options
author | Anton Vorontsov <avorontsov@ru.mvista.com> | 2009-04-18 13:48:52 -0400 |
---|---|---|
committer | Kumar Gala <galak@kernel.crashing.org> | 2009-04-21 16:34:37 -0400 |
commit | 0dbbbf1a0e305ad900b733e2ba1cac304d31696e (patch) | |
tree | 0b8d9d5032bc54e1559f77896ee34747f6e76527 /arch/powerpc/sysdev | |
parent | b71a0c296cee4debaf446760fbd29ead1587a7ac (diff) |
fsl_rio: Pass the proper device to dma mapping routines
The driver should pass a device that specifies internal DMA ops, but
currently NULL pointer is passed, therefore following bug appears
during boot up:
------------[ cut here ]------------
Kernel BUG at c0018a7c [verbose debug info unavailable]
Oops: Exception in kernel mode, sig: 5 [#1]
[...]
NIP [c0018a7c] fsl_rio_doorbell_init+0x34/0x60
LR [c0018a70] fsl_rio_doorbell_init+0x28/0x60
Call Trace:
[ef82bda0] [c0018a70] fsl_rio_doorbell_init+0x28/0x60 (unreliable)
[ef82bdc0] [c0019160] fsl_rio_setup+0x6b8/0x84c
[ef82be20] [c02d28ac] fsl_of_rio_rpn_probe+0x30/0x50
[ef82be40] [c0234f20] of_platform_device_probe+0x5c/0x84
[...]
---[ end trace 561bb236c800851f ]---
This patch fixes the issue.
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/sysdev')
-rw-r--r-- | arch/powerpc/sysdev/fsl_rio.c | 28 |
1 files changed, 17 insertions, 11 deletions
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index a0fa4ebb39c6..abdb124e1e2f 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/types.h> | 18 | #include <linux/types.h> |
19 | #include <linux/dma-mapping.h> | 19 | #include <linux/dma-mapping.h> |
20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
21 | #include <linux/device.h> | ||
21 | #include <linux/rio.h> | 22 | #include <linux/rio.h> |
22 | #include <linux/rio_drv.h> | 23 | #include <linux/rio_drv.h> |
23 | #include <linux/of_platform.h> | 24 | #include <linux/of_platform.h> |
@@ -159,6 +160,7 @@ struct rio_msg_rx_ring { | |||
159 | }; | 160 | }; |
160 | 161 | ||
161 | struct rio_priv { | 162 | struct rio_priv { |
163 | struct device *dev; | ||
162 | void __iomem *regs_win; | 164 | void __iomem *regs_win; |
163 | struct rio_atmu_regs __iomem *atmu_regs; | 165 | struct rio_atmu_regs __iomem *atmu_regs; |
164 | struct rio_atmu_regs __iomem *maint_atmu_regs; | 166 | struct rio_atmu_regs __iomem *maint_atmu_regs; |
@@ -484,13 +486,13 @@ int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entr | |||
484 | 486 | ||
485 | for (i = 0; i < priv->msg_tx_ring.size; i++) { | 487 | for (i = 0; i < priv->msg_tx_ring.size; i++) { |
486 | priv->msg_tx_ring.virt_buffer[i] = | 488 | priv->msg_tx_ring.virt_buffer[i] = |
487 | dma_alloc_coherent(NULL, RIO_MSG_BUFFER_SIZE, | 489 | dma_alloc_coherent(priv->dev, RIO_MSG_BUFFER_SIZE, |
488 | &priv->msg_tx_ring.phys_buffer[i], GFP_KERNEL); | 490 | &priv->msg_tx_ring.phys_buffer[i], GFP_KERNEL); |
489 | if (!priv->msg_tx_ring.virt_buffer[i]) { | 491 | if (!priv->msg_tx_ring.virt_buffer[i]) { |
490 | rc = -ENOMEM; | 492 | rc = -ENOMEM; |
491 | for (j = 0; j < priv->msg_tx_ring.size; j++) | 493 | for (j = 0; j < priv->msg_tx_ring.size; j++) |
492 | if (priv->msg_tx_ring.virt_buffer[j]) | 494 | if (priv->msg_tx_ring.virt_buffer[j]) |
493 | dma_free_coherent(NULL, | 495 | dma_free_coherent(priv->dev, |
494 | RIO_MSG_BUFFER_SIZE, | 496 | RIO_MSG_BUFFER_SIZE, |
495 | priv->msg_tx_ring. | 497 | priv->msg_tx_ring. |
496 | virt_buffer[j], | 498 | virt_buffer[j], |
@@ -501,7 +503,7 @@ int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entr | |||
501 | } | 503 | } |
502 | 504 | ||
503 | /* Initialize outbound message descriptor ring */ | 505 | /* Initialize outbound message descriptor ring */ |
504 | priv->msg_tx_ring.virt = dma_alloc_coherent(NULL, | 506 | priv->msg_tx_ring.virt = dma_alloc_coherent(priv->dev, |
505 | priv->msg_tx_ring.size * RIO_MSG_DESC_SIZE, | 507 | priv->msg_tx_ring.size * RIO_MSG_DESC_SIZE, |
506 | &priv->msg_tx_ring.phys, GFP_KERNEL); | 508 | &priv->msg_tx_ring.phys, GFP_KERNEL); |
507 | if (!priv->msg_tx_ring.virt) { | 509 | if (!priv->msg_tx_ring.virt) { |
@@ -549,12 +551,13 @@ int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entr | |||
549 | return rc; | 551 | return rc; |
550 | 552 | ||
551 | out_irq: | 553 | out_irq: |
552 | dma_free_coherent(NULL, priv->msg_tx_ring.size * RIO_MSG_DESC_SIZE, | 554 | dma_free_coherent(priv->dev, |
555 | priv->msg_tx_ring.size * RIO_MSG_DESC_SIZE, | ||
553 | priv->msg_tx_ring.virt, priv->msg_tx_ring.phys); | 556 | priv->msg_tx_ring.virt, priv->msg_tx_ring.phys); |
554 | 557 | ||
555 | out_dma: | 558 | out_dma: |
556 | for (i = 0; i < priv->msg_tx_ring.size; i++) | 559 | for (i = 0; i < priv->msg_tx_ring.size; i++) |
557 | dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE, | 560 | dma_free_coherent(priv->dev, RIO_MSG_BUFFER_SIZE, |
558 | priv->msg_tx_ring.virt_buffer[i], | 561 | priv->msg_tx_ring.virt_buffer[i], |
559 | priv->msg_tx_ring.phys_buffer[i]); | 562 | priv->msg_tx_ring.phys_buffer[i]); |
560 | 563 | ||
@@ -576,7 +579,8 @@ void rio_close_outb_mbox(struct rio_mport *mport, int mbox) | |||
576 | out_be32(&priv->msg_regs->omr, 0); | 579 | out_be32(&priv->msg_regs->omr, 0); |
577 | 580 | ||
578 | /* Free ring */ | 581 | /* Free ring */ |
579 | dma_free_coherent(NULL, priv->msg_tx_ring.size * RIO_MSG_DESC_SIZE, | 582 | dma_free_coherent(priv->dev, |
583 | priv->msg_tx_ring.size * RIO_MSG_DESC_SIZE, | ||
580 | priv->msg_tx_ring.virt, priv->msg_tx_ring.phys); | 584 | priv->msg_tx_ring.virt, priv->msg_tx_ring.phys); |
581 | 585 | ||
582 | /* Free interrupt */ | 586 | /* Free interrupt */ |
@@ -654,7 +658,7 @@ int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entri | |||
654 | priv->msg_rx_ring.virt_buffer[i] = NULL; | 658 | priv->msg_rx_ring.virt_buffer[i] = NULL; |
655 | 659 | ||
656 | /* Initialize inbound message ring */ | 660 | /* Initialize inbound message ring */ |
657 | priv->msg_rx_ring.virt = dma_alloc_coherent(NULL, | 661 | priv->msg_rx_ring.virt = dma_alloc_coherent(priv->dev, |
658 | priv->msg_rx_ring.size * RIO_MAX_MSG_SIZE, | 662 | priv->msg_rx_ring.size * RIO_MAX_MSG_SIZE, |
659 | &priv->msg_rx_ring.phys, GFP_KERNEL); | 663 | &priv->msg_rx_ring.phys, GFP_KERNEL); |
660 | if (!priv->msg_rx_ring.virt) { | 664 | if (!priv->msg_rx_ring.virt) { |
@@ -673,7 +677,7 @@ int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entri | |||
673 | rc = request_irq(IRQ_RIO_RX(mport), fsl_rio_rx_handler, 0, | 677 | rc = request_irq(IRQ_RIO_RX(mport), fsl_rio_rx_handler, 0, |
674 | "msg_rx", (void *)mport); | 678 | "msg_rx", (void *)mport); |
675 | if (rc < 0) { | 679 | if (rc < 0) { |
676 | dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE, | 680 | dma_free_coherent(priv->dev, RIO_MSG_BUFFER_SIZE, |
677 | priv->msg_tx_ring.virt_buffer[i], | 681 | priv->msg_tx_ring.virt_buffer[i], |
678 | priv->msg_tx_ring.phys_buffer[i]); | 682 | priv->msg_tx_ring.phys_buffer[i]); |
679 | goto out; | 683 | goto out; |
@@ -713,7 +717,7 @@ void rio_close_inb_mbox(struct rio_mport *mport, int mbox) | |||
713 | out_be32(&priv->msg_regs->imr, 0); | 717 | out_be32(&priv->msg_regs->imr, 0); |
714 | 718 | ||
715 | /* Free ring */ | 719 | /* Free ring */ |
716 | dma_free_coherent(NULL, priv->msg_rx_ring.size * RIO_MAX_MSG_SIZE, | 720 | dma_free_coherent(priv->dev, priv->msg_rx_ring.size * RIO_MAX_MSG_SIZE, |
717 | priv->msg_rx_ring.virt, priv->msg_rx_ring.phys); | 721 | priv->msg_rx_ring.virt, priv->msg_rx_ring.phys); |
718 | 722 | ||
719 | /* Free interrupt */ | 723 | /* Free interrupt */ |
@@ -890,7 +894,7 @@ static int fsl_rio_doorbell_init(struct rio_mport *mport) | |||
890 | } | 894 | } |
891 | 895 | ||
892 | /* Initialize inbound doorbells */ | 896 | /* Initialize inbound doorbells */ |
893 | priv->dbell_ring.virt = dma_alloc_coherent(NULL, 512 * | 897 | priv->dbell_ring.virt = dma_alloc_coherent(priv->dev, 512 * |
894 | DOORBELL_MESSAGE_SIZE, &priv->dbell_ring.phys, GFP_KERNEL); | 898 | DOORBELL_MESSAGE_SIZE, &priv->dbell_ring.phys, GFP_KERNEL); |
895 | if (!priv->dbell_ring.virt) { | 899 | if (!priv->dbell_ring.virt) { |
896 | printk(KERN_ERR "RIO: unable allocate inbound doorbell ring\n"); | 900 | printk(KERN_ERR "RIO: unable allocate inbound doorbell ring\n"); |
@@ -911,7 +915,7 @@ static int fsl_rio_doorbell_init(struct rio_mport *mport) | |||
911 | "dbell_rx", (void *)mport); | 915 | "dbell_rx", (void *)mport); |
912 | if (rc < 0) { | 916 | if (rc < 0) { |
913 | iounmap(priv->dbell_win); | 917 | iounmap(priv->dbell_win); |
914 | dma_free_coherent(NULL, 512 * DOORBELL_MESSAGE_SIZE, | 918 | dma_free_coherent(priv->dev, 512 * DOORBELL_MESSAGE_SIZE, |
915 | priv->dbell_ring.virt, priv->dbell_ring.phys); | 919 | priv->dbell_ring.virt, priv->dbell_ring.phys); |
916 | printk(KERN_ERR | 920 | printk(KERN_ERR |
917 | "MPC85xx RIO: unable to request inbound doorbell irq"); | 921 | "MPC85xx RIO: unable to request inbound doorbell irq"); |
@@ -1087,6 +1091,8 @@ int fsl_rio_setup(struct of_device *dev) | |||
1087 | rio_init_mbox_res(&port->riores[RIO_OUTB_MBOX_RESOURCE], 0, 0); | 1091 | rio_init_mbox_res(&port->riores[RIO_OUTB_MBOX_RESOURCE], 0, 0); |
1088 | strcpy(port->name, "RIO0 mport"); | 1092 | strcpy(port->name, "RIO0 mport"); |
1089 | 1093 | ||
1094 | priv->dev = &dev->dev; | ||
1095 | |||
1090 | port->ops = ops; | 1096 | port->ops = ops; |
1091 | port->host_deviceid = fsl_rio_get_hdid(port->id); | 1097 | port->host_deviceid = fsl_rio_get_hdid(port->id); |
1092 | 1098 | ||