i.MX25 SPI driver read leads crashing the systems completely!

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

i.MX25 SPI driver read leads crashing the systems completely!

3,096 Views
ajithpv
Contributor V

Hi everyone,

I have been trying to implement SPI read by the standard  spi_read API, using Freescales mxc-spi.c driver. The spi_write API works fine for me and I confirmed it with the CRO too. But whenever I tried to implement the read operation, the kernel got crashed!. 
The error log is given below: 

Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = c0004000
[00000000] *pgd=00000000
Internal error: Oops: 17 [#1] PREEMPT
Modules linked in:
CPU: 0 Not tainted (2.6.31-207-g7286c01-svn124 #267)
PC is at mxc_spi_buf_tx_u8+0x4/0x14
LR is at spi_put_tx_data+0x24/0x54
pc : [<c01db5c4>] lr : [<c01db6ac>] psr: 80000013
sp : c3869f38 ip : 00000008 fp : c01db6f4
r10: c3870780 r9 : 00000000 r8 : 00380821
r7 : 00000001 r6 : 00000001 r5 : fc0a4000 r4 : c3877cc0
r3 : 00000000 r2 : c3877cc0 r1 : 00000001 r0 : c3877cc0
Flags: Nzcv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel
Control: 0005317f Table: 83030000 DAC: 00000017
Process mxc_spi.0 (pid: 134, stack limit = 0xc3868270)
Stack: (0xc3869f38 to 0xc386a000)
9f20: 80000013 c3877cc0
9f40: c3035edc c3870780 00000001 c01dbcb0 c3035edc 00000000 c3035eb0 c3868000
9f60: c3877cc0 c01db450 c38783e0 ffffffff c3868000 c3869fa8 c3868000 c3877cc4
9f80: c38e2d40 c38783e0 00000000 c01db2e4 00000000 c00594ec c02d9a08 00000000
9fa0: c38783e0 c005ce48 c3869fa8 c3869fa8 c0059304 c3869fd4 c3819e60 c38e2d40
9fc0: c0059304 00000000 00000000 c005cd80 00000000 00000000 c3869fd8 c3869fd8
9fe0: 00000000 00000000 00000000 00000000 00000000 c00297bc 00000000 00000000
[<c01db5c4>] (mxc_spi_buf_tx_u8+0x4/0x14) from [<c01db6ac>] (spi_put_tx_data+0x24/0x54)
[<c01db6ac>] (spi_put_tx_data+0x24/0x54) from [<c01dbcb0>] (mxc_spi_transfer+0xd4/0x14c)
[<c01dbcb0>] (mxc_spi_transfer+0xd4/0x14c) from [<c01db450>] (bitbang_work+0x16c/0x2cc)
[<c01db450>] (bitbang_work+0x16c/0x2cc) from [<c00594ec>] (worker_thread+0x1e8/0x2ac)
[<c00594ec>] (worker_thread+0x1e8/0x2ac) from [<c005cd80>] (kthread+0x78/0x80)
[<c005cd80>] (kthread+0x78/0x80) from [<c00297bc>] (kernel_thread_exit+0x0/0x8)
Code: e4c31001 e5803050 e12fff1e e590304c (e4d32001)
---[ end trace e59954a84fe6d7df ]---



This is happening only when I'm performing SPI read. 

I refer to the following link "http://forums.freescale.com/t5/i-MX-Microprocessors/i-MX25-SPI-driver-drivers-spi-mxs-spi-c-completely-broken/td-p/60614" and found that some people fixed it already. But I couldn't trace the solution yet. So I hereby request you to provide the patch for fixing this 
critical issue. I would also like to know that whether this issue is already solved in the later releases? 
Looking forward to your reply...

Ajith P V

Tags (2)
0 Kudos
10 Replies

1,537 Views
ajithpv
Contributor V

Thank you so much Rooney for your effective support.

Rooney said:

The problem is that if you perform a read, the transmit function of the mxc_spi.c is called as well to generate the clock. In case of a read the tx_buf is not initialised, therefore you get a null pointer exception.

You could use the following fix for spi_put_tx_data() in mxc_spi.c

for (i = 0; i < count; i++) {
        if(master_drv_data->transfer.tx_buf != NULL)
        {
            data = master_drv_data->transfer.tx_get(master_drv_data);
            __raw_writel(data, base + MXC_CSPITXDATA);
        }
        else
        {
            __raw_writel(data, base + 0x00);
        }
}

0 Kudos

1,537 Views
augusto
Contributor II

The proposed solution seems to not solve the problem.

The root of the problem is in mxc_spi_pio_transfer invoked by mxc_spi_transfer.

An SPI transfer consists in two steps: a write and a subsequent read, specified in two separated spi_transfer structs (see function spi_write_then_read in spi.c).

The problem is that in the first step only tx_buf in spi_transfer struct exists, and in the second step only rx_buf.

This is taken into account in function mxc_spi_dma_transfer but NOT in mxc_spi_pio_transfer.

So, to summarize, instead of the patch above, add in mxc_spi_pio_transfer function this row after "INIT_COMPLETION(master_drv_data->xfer_done);":

if (!t->tx_buf) master_drv_data->transfer.tx_buf = (void *)master_drv_data->tmp_buf;

Just another broken driver.

0 Kudos

1,537 Views
GlennWoodruff
Contributor I

Hi Augusto,

Thanks for the reply, it looks promising but it looks like the mxc_spi driver you're using doesn't correlate with the ones in the  L2.6.31_09.12.00 or L2.6.35_10.12.01 releases, which is what I (probably incorrectly) thought were the only releases with mx25 fsl drivers.  What release are you using?

0 Kudos

1,537 Views
augusto
Contributor II

Sorry, I'm using i.MX53 that's probably different (but buggy as well...)

0 Kudos

1,537 Views
ajithpv
Contributor V

Hi Augusto,

The 'spi_read bug' in L2.6.31_09.12.00_SDK_SOURCE is fixed in later versions (Freescale suggested me to upgrade the version to new one, once I sent the same query). So i.MX53 might be using a "bug fixed" code...

Thank you for your valuable input by the way...

0 Kudos

1,537 Views
GlennWoodruff
Contributor I

Thanks for all the input, but on my side I had better results backporting the mainline spi_imx driver.

0 Kudos

1,537 Views
Rooney
Contributor III

The problem is that if you perform a read, the transmit function of the mxc_spi.c is called as well to generate the clock. In case of a read the tx_buf is not initialised, therefore you get a null pointer exception.

You could use the following fix for spi_put_tx_data() in mxc_spi.c

for (i = 0; i < count; i++) {
        if(master_drv_data->transfer.tx_buf != NULL)
        {
            data = master_drv_data->transfer.tx_get(master_drv_data);
            __raw_writel(data, base + MXC_CSPITXDATA);
        }
        else
        {
            __raw_writel(data, base + 0x00);
        }
}

0 Kudos

1,537 Views
GlennWoodruff
Contributor I

Hi Rooney,

Thanks for posting the proposed fix.  I had the same problem as Aijith and traced it to the tx.buf being NULL, then was just delighted to find your note and your proposed solution here.  I naively dropped your fix into the version of mxc_spi.c that was in the L2.6.31_09.12.00_SDK_SOURCE release but doing so only changed my deref stack dump into a lockup .

Is this same version you were working from, and for that matter is the fix as posted compete or is there something else I need to do?

Thanks,

Glenn

0 Kudos

1,537 Views
ajithpv
Contributor V

Hi Balaji,

I made a wrapper around the spi_read and fixed the bug. Now it's working without any problem.

Best regards,

Ajith P V

iwavesystems

0 Kudos

1,537 Views
Balaji_ng
Contributor III

Hi,

     Were you able to get it working?

Regards

Balaji.V

0 Kudos