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 186/305] spi: sunxi: fix transfer timeout
    3.16.37-rc1 review patch.  If anyone has any objections, please let me know.

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

    From: Michal Suchanek <hramrach@gmail.com>

    commit 719bd6542044efd9b338a53dba1bef45f40ca169 upstream.

    The trasfer timeout is fixed at 1000 ms. Reading a 4Mbyte flash over
    1MHz SPI bus takes way longer than that. Calculate the timeout from the
    actual time the transfer is supposed to take and multiply by 2 for good
    measure.

    Signed-off-by: Michal Suchanek <hramrach@gmail.com>
    Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
    Signed-off-by: Mark Brown <broonie@kernel.org>
    Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
    ---
    drivers/spi/spi-sun4i.c | 10 +++++++++-
    drivers/spi/spi-sun6i.c | 10 +++++++++-
    2 files changed, 18 insertions(+), 2 deletions(-)

    --- a/drivers/spi/spi-sun4i.c
    +++ b/drivers/spi/spi-sun4i.c
    @@ -170,6 +170,7 @@ static int sun4i_spi_transfer_one(struct
    {
    struct sun4i_spi *sspi = spi_master_get_devdata(master);
    unsigned int mclk_rate, div, timeout;
    + unsigned int start, end, tx_time;
    unsigned int tx_len = 0;
    int ret = 0;
    u32 reg;
    @@ -286,9 +287,16 @@ static int sun4i_spi_transfer_one(struct
    reg = sun4i_spi_read(sspi, SUN4I_CTL_REG);
    sun4i_spi_write(sspi, SUN4I_CTL_REG, reg | SUN4I_CTL_XCH);

    + tx_time = max(tfr->len * 8 * 2 / (tfr->speed_hz / 1000), 100U);
    + start = jiffies;
    timeout = wait_for_completion_timeout(&sspi->done,
    - msecs_to_jiffies(1000));
    + msecs_to_jiffies(tx_time));
    + end = jiffies;
    if (!timeout) {
    + dev_warn(&master->dev,
    + "%s: timeout transferring %u bytes@%iHz for %i(%i)ms",
    + dev_name(&spi->dev), tfr->len, tfr->speed_hz,
    + jiffies_to_msecs(end - start), tx_time);
    ret = -ETIMEDOUT;
    goto out;
    }
    --- a/drivers/spi/spi-sun6i.c
    +++ b/drivers/spi/spi-sun6i.c
    @@ -160,6 +160,7 @@ static int sun6i_spi_transfer_one(struct
    {
    struct sun6i_spi *sspi = spi_master_get_devdata(master);
    unsigned int mclk_rate, div, timeout;
    + unsigned int start, end, tx_time;
    unsigned int tx_len = 0;
    int ret = 0;
    u32 reg;
    @@ -269,9 +270,16 @@ static int sun6i_spi_transfer_one(struct
    reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG);
    sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg | SUN6I_TFR_CTL_XCH);

    + tx_time = max(tfr->len * 8 * 2 / (tfr->speed_hz / 1000), 100U);
    + start = jiffies;
    timeout = wait_for_completion_timeout(&sspi->done,
    - msecs_to_jiffies(1000));
    + msecs_to_jiffies(tx_time));
    + end = jiffies;
    if (!timeout) {
    + dev_warn(&master->dev,
    + "%s: timeout transferring %u bytes@%iHz for %i(%i)ms",
    + dev_name(&spi->dev), tfr->len, tfr->speed_hz,
    + jiffies_to_msecs(end - start), tx_time);
    ret = -ETIMEDOUT;
    goto out;
    }
    \
     
     \ /
      Last update: 2016-09-17 09:56    [W:4.021 / U:0.408 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site