Skip to content

Commit 873b6e3

Browse files
hramrachgregkh
authored andcommitted
spi: sunxi: fix transfer timeout
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: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent df582d4 commit 873b6e3

2 files changed

Lines changed: 18 additions & 2 deletions

File tree

drivers/spi/spi-sun4i.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ static int sun4i_spi_transfer_one(struct spi_master *master,
170170
{
171171
struct sun4i_spi *sspi = spi_master_get_devdata(master);
172172
unsigned int mclk_rate, div, timeout;
173+
unsigned int start, end, tx_time;
173174
unsigned int tx_len = 0;
174175
int ret = 0;
175176
u32 reg;
@@ -279,9 +280,16 @@ static int sun4i_spi_transfer_one(struct spi_master *master,
279280
reg = sun4i_spi_read(sspi, SUN4I_CTL_REG);
280281
sun4i_spi_write(sspi, SUN4I_CTL_REG, reg | SUN4I_CTL_XCH);
281282

283+
tx_time = max(tfr->len * 8 * 2 / (tfr->speed_hz / 1000), 100U);
284+
start = jiffies;
282285
timeout = wait_for_completion_timeout(&sspi->done,
283-
msecs_to_jiffies(1000));
286+
msecs_to_jiffies(tx_time));
287+
end = jiffies;
284288
if (!timeout) {
289+
dev_warn(&master->dev,
290+
"%s: timeout transferring %u bytes@%iHz for %i(%i)ms",
291+
dev_name(&spi->dev), tfr->len, tfr->speed_hz,
292+
jiffies_to_msecs(end - start), tx_time);
285293
ret = -ETIMEDOUT;
286294
goto out;
287295
}

drivers/spi/spi-sun6i.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
160160
{
161161
struct sun6i_spi *sspi = spi_master_get_devdata(master);
162162
unsigned int mclk_rate, div, timeout;
163+
unsigned int start, end, tx_time;
163164
unsigned int tx_len = 0;
164165
int ret = 0;
165166
u32 reg;
@@ -269,9 +270,16 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
269270
reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG);
270271
sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg | SUN6I_TFR_CTL_XCH);
271272

273+
tx_time = max(tfr->len * 8 * 2 / (tfr->speed_hz / 1000), 100U);
274+
start = jiffies;
272275
timeout = wait_for_completion_timeout(&sspi->done,
273-
msecs_to_jiffies(1000));
276+
msecs_to_jiffies(tx_time));
277+
end = jiffies;
274278
if (!timeout) {
279+
dev_warn(&master->dev,
280+
"%s: timeout transferring %u bytes@%iHz for %i(%i)ms",
281+
dev_name(&spi->dev), tfr->len, tfr->speed_hz,
282+
jiffies_to_msecs(end - start), tx_time);
275283
ret = -ETIMEDOUT;
276284
goto out;
277285
}

0 commit comments

Comments
 (0)