Skip to content

Commit

Permalink
at86rf230: replace state change sleeps with hrtimer
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Alexander Aring authored and Marcel Holtmann committed Mar 14, 2015
1 parent e372174 commit eb3b435
Showing 1 changed file with 29 additions and 10 deletions.
39 changes: 29 additions & 10 deletions drivers/net/ieee802154/at86rf230.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -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)
Expand All @@ -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
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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)
Expand Down

0 comments on commit eb3b435

Please sign in to comment.