lkml.org 
[lkml]   [2016]   [Aug]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 3.16 202/305] can: c_can: Update D_CAN TX and RX functions to 32 bit - fix Altera Cyclone access
    3.16.37-rc1 review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Thor Thayer <tthayer@opensource.altera.com>

    commit 427460c83cdf55069eee49799a0caef7dde8df69 upstream.

    When testing CAN write floods on Altera's CycloneV, the first 2 bytes
    are sometimes 0x00, 0x00 or corrupted instead of the values sent. Also
    observed bytes 4 & 5 were corrupted in some cases.

    The D_CAN Data registers are 32 bits and changing from 16 bit writes to
    32 bit writes fixes the problem.

    Testing performed on Altera CycloneV (D_CAN). Requesting tests on other
    C_CAN & D_CAN platforms.

    Reported-by: Richard Andrysek <richard.andrysek@gomtec.de>
    Signed-off-by: Thor Thayer <tthayer@opensource.altera.com>
    Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
    Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
    ---
    drivers/net/can/c_can/c_can.c | 38 +++++++++++++++++++++++++++++++-------
    1 file changed, 31 insertions(+), 7 deletions(-)

    --- a/drivers/net/can/c_can/c_can.c
    +++ b/drivers/net/can/c_can/c_can.c
    @@ -331,9 +331,23 @@ static void c_can_setup_tx_object(struct

    priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), ctrl);

    - for (i = 0; i < frame->can_dlc; i += 2) {
    - priv->write_reg(priv, C_CAN_IFACE(DATA1_REG, iface) + i / 2,
    - frame->data[i] | (frame->data[i + 1] << 8));
    + if (priv->type == BOSCH_D_CAN) {
    + u32 data = 0, dreg = C_CAN_IFACE(DATA1_REG, iface);
    +
    + for (i = 0; i < frame->can_dlc; i += 4, dreg += 2) {
    + data = (u32)frame->data[i];
    + data |= (u32)frame->data[i + 1] << 8;
    + data |= (u32)frame->data[i + 2] << 16;
    + data |= (u32)frame->data[i + 3] << 24;
    + priv->write_reg32(priv, dreg, data);
    + }
    + } else {
    + for (i = 0; i < frame->can_dlc; i += 2) {
    + priv->write_reg(priv,
    + C_CAN_IFACE(DATA1_REG, iface) + i / 2,
    + frame->data[i] |
    + (frame->data[i + 1] << 8));
    + }
    }
    }

    @@ -401,10 +415,20 @@ static int c_can_read_msg_object(struct
    } else {
    int i, dreg = C_CAN_IFACE(DATA1_REG, iface);

    - for (i = 0; i < frame->can_dlc; i += 2, dreg ++) {
    - data = priv->read_reg(priv, dreg);
    - frame->data[i] = data;
    - frame->data[i + 1] = data >> 8;
    + if (priv->type == BOSCH_D_CAN) {
    + for (i = 0; i < frame->can_dlc; i += 4, dreg += 2) {
    + data = priv->read_reg32(priv, dreg);
    + frame->data[i] = data;
    + frame->data[i + 1] = data >> 8;
    + frame->data[i + 2] = data >> 16;
    + frame->data[i + 3] = data >> 24;
    + }
    + } else {
    + for (i = 0; i < frame->can_dlc; i += 2, dreg++) {
    + data = priv->read_reg(priv, dreg);
    + frame->data[i] = data;
    + frame->data[i + 1] = data >> 8;
    + }
    }
    }

    \
     
     \ /
      Last update: 2016-09-17 09:56    [W:4.079 / U:0.752 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site