at86rf230: replace state change sleeps with hrtimer
This patch replace the state change timing relevant sleeps with hrtimers. Currently the sleeps are done in the complete handler of spi_async. The relation of doing the state change timing sleep with a timer will get the sleep functionality out of spi_async complete handler context. Signed-off-by: Alexander Aring <alex.aring@gmail.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This commit is contained in:
parent
e372174900
commit
eb3b435ecd
|
@ -19,6 +19,7 @@
|
|||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/gpio.h>
|
||||
|
@ -64,6 +65,7 @@ struct at86rf230_state_change {
|
|||
struct at86rf230_local *lp;
|
||||
int irq;
|
||||
|
||||
struct hrtimer timer;
|
||||
struct spi_message msg;
|
||||
struct spi_transfer trx;
|
||||
u8 buf[AT86RF2XX_MAX_BUF];
|
||||
|
@ -548,6 +550,19 @@ at86rf230_async_state_assert(void *context)
|
|||
ctx->complete(context);
|
||||
}
|
||||
|
||||
static enum hrtimer_restart at86rf230_async_state_timer(struct hrtimer *timer)
|
||||
{
|
||||
struct at86rf230_state_change *ctx =
|
||||
container_of(timer, struct at86rf230_state_change, timer);
|
||||
struct at86rf230_local *lp = ctx->lp;
|
||||
|
||||
at86rf230_async_read_reg(lp, RG_TRX_STATUS, ctx,
|
||||
at86rf230_async_state_assert,
|
||||
ctx->irq_enable);
|
||||
|
||||
return HRTIMER_NORESTART;
|
||||
}
|
||||
|
||||
/* Do state change timing delay. */
|
||||
static void
|
||||
at86rf230_async_state_delay(void *context)
|
||||
|
@ -556,6 +571,7 @@ at86rf230_async_state_delay(void *context)
|
|||
struct at86rf230_local *lp = ctx->lp;
|
||||
struct at86rf2xx_chip_data *c = lp->data;
|
||||
bool force = false;
|
||||
ktime_t tim;
|
||||
|
||||
/* The force state changes are will show as normal states in the
|
||||
* state status subregister. We change the to_state to the
|
||||
|
@ -579,11 +595,10 @@ at86rf230_async_state_delay(void *context)
|
|||
case STATE_TRX_OFF:
|
||||
switch (ctx->to_state) {
|
||||
case STATE_RX_AACK_ON:
|
||||
usleep_range(c->t_off_to_aack, c->t_off_to_aack + 10);
|
||||
tim = ktime_set(0, c->t_off_to_aack * NSEC_PER_USEC);
|
||||
goto change;
|
||||
case STATE_TX_ON:
|
||||
usleep_range(c->t_off_to_tx_on,
|
||||
c->t_off_to_tx_on + 10);
|
||||
tim = ktime_set(0, c->t_off_to_tx_on * NSEC_PER_USEC);
|
||||
goto change;
|
||||
default:
|
||||
break;
|
||||
|
@ -597,8 +612,8 @@ at86rf230_async_state_delay(void *context)
|
|||
* to TX_ON.
|
||||
*/
|
||||
if (!force) {
|
||||
usleep_range(c->t_frame + c->t_p_ack,
|
||||
c->t_frame + c->t_p_ack + 1000);
|
||||
tim = ktime_set(0, (c->t_frame + c->t_p_ack) *
|
||||
NSEC_PER_USEC);
|
||||
goto change;
|
||||
}
|
||||
break;
|
||||
|
@ -610,7 +625,7 @@ at86rf230_async_state_delay(void *context)
|
|||
case STATE_P_ON:
|
||||
switch (ctx->to_state) {
|
||||
case STATE_TRX_OFF:
|
||||
usleep_range(c->t_reset_to_off, c->t_reset_to_off + 10);
|
||||
tim = ktime_set(0, c->t_reset_to_off * NSEC_PER_USEC);
|
||||
goto change;
|
||||
default:
|
||||
break;
|
||||
|
@ -621,12 +636,10 @@ at86rf230_async_state_delay(void *context)
|
|||
}
|
||||
|
||||
/* Default delay is 1us in the most cases */
|
||||
udelay(1);
|
||||
tim = ktime_set(0, NSEC_PER_USEC);
|
||||
|
||||
change:
|
||||
at86rf230_async_read_reg(lp, RG_TRX_STATUS, ctx,
|
||||
at86rf230_async_state_assert,
|
||||
ctx->irq_enable);
|
||||
hrtimer_start(&ctx->timer, tim, HRTIMER_MODE_REL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1546,6 +1559,8 @@ at86rf230_setup_spi_messages(struct at86rf230_local *lp)
|
|||
lp->state.trx.tx_buf = lp->state.buf;
|
||||
lp->state.trx.rx_buf = lp->state.buf;
|
||||
spi_message_add_tail(&lp->state.trx, &lp->state.msg);
|
||||
hrtimer_init(&lp->state.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
||||
lp->state.timer.function = at86rf230_async_state_timer;
|
||||
|
||||
lp->irq.lp = lp;
|
||||
lp->irq.irq = lp->spi->irq;
|
||||
|
@ -1555,6 +1570,8 @@ at86rf230_setup_spi_messages(struct at86rf230_local *lp)
|
|||
lp->irq.trx.tx_buf = lp->irq.buf;
|
||||
lp->irq.trx.rx_buf = lp->irq.buf;
|
||||
spi_message_add_tail(&lp->irq.trx, &lp->irq.msg);
|
||||
hrtimer_init(&lp->irq.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
||||
lp->irq.timer.function = at86rf230_async_state_timer;
|
||||
|
||||
lp->tx.lp = lp;
|
||||
lp->tx.irq = lp->spi->irq;
|
||||
|
@ -1564,6 +1581,8 @@ at86rf230_setup_spi_messages(struct at86rf230_local *lp)
|
|||
lp->tx.trx.tx_buf = lp->tx.buf;
|
||||
lp->tx.trx.rx_buf = lp->tx.buf;
|
||||
spi_message_add_tail(&lp->tx.trx, &lp->tx.msg);
|
||||
hrtimer_init(&lp->tx.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
||||
lp->tx.timer.function = at86rf230_async_state_timer;
|
||||
}
|
||||
|
||||
static int at86rf230_probe(struct spi_device *spi)
|
||||
|
|
Loading…
Reference in New Issue