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/kernel.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/hrtimer.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
|
@ -64,6 +65,7 @@ struct at86rf230_state_change {
|
||||||
struct at86rf230_local *lp;
|
struct at86rf230_local *lp;
|
||||||
int irq;
|
int irq;
|
||||||
|
|
||||||
|
struct hrtimer timer;
|
||||||
struct spi_message msg;
|
struct spi_message msg;
|
||||||
struct spi_transfer trx;
|
struct spi_transfer trx;
|
||||||
u8 buf[AT86RF2XX_MAX_BUF];
|
u8 buf[AT86RF2XX_MAX_BUF];
|
||||||
|
@ -548,6 +550,19 @@ at86rf230_async_state_assert(void *context)
|
||||||
ctx->complete(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. */
|
/* Do state change timing delay. */
|
||||||
static void
|
static void
|
||||||
at86rf230_async_state_delay(void *context)
|
at86rf230_async_state_delay(void *context)
|
||||||
|
@ -556,6 +571,7 @@ at86rf230_async_state_delay(void *context)
|
||||||
struct at86rf230_local *lp = ctx->lp;
|
struct at86rf230_local *lp = ctx->lp;
|
||||||
struct at86rf2xx_chip_data *c = lp->data;
|
struct at86rf2xx_chip_data *c = lp->data;
|
||||||
bool force = false;
|
bool force = false;
|
||||||
|
ktime_t tim;
|
||||||
|
|
||||||
/* The force state changes are will show as normal states in the
|
/* The force state changes are will show as normal states in the
|
||||||
* state status subregister. We change the to_state to 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:
|
case STATE_TRX_OFF:
|
||||||
switch (ctx->to_state) {
|
switch (ctx->to_state) {
|
||||||
case STATE_RX_AACK_ON:
|
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;
|
goto change;
|
||||||
case STATE_TX_ON:
|
case STATE_TX_ON:
|
||||||
usleep_range(c->t_off_to_tx_on,
|
tim = ktime_set(0, c->t_off_to_tx_on * NSEC_PER_USEC);
|
||||||
c->t_off_to_tx_on + 10);
|
|
||||||
goto change;
|
goto change;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -597,8 +612,8 @@ at86rf230_async_state_delay(void *context)
|
||||||
* to TX_ON.
|
* to TX_ON.
|
||||||
*/
|
*/
|
||||||
if (!force) {
|
if (!force) {
|
||||||
usleep_range(c->t_frame + c->t_p_ack,
|
tim = ktime_set(0, (c->t_frame + c->t_p_ack) *
|
||||||
c->t_frame + c->t_p_ack + 1000);
|
NSEC_PER_USEC);
|
||||||
goto change;
|
goto change;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -610,7 +625,7 @@ at86rf230_async_state_delay(void *context)
|
||||||
case STATE_P_ON:
|
case STATE_P_ON:
|
||||||
switch (ctx->to_state) {
|
switch (ctx->to_state) {
|
||||||
case STATE_TRX_OFF:
|
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;
|
goto change;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -621,12 +636,10 @@ at86rf230_async_state_delay(void *context)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Default delay is 1us in the most cases */
|
/* Default delay is 1us in the most cases */
|
||||||
udelay(1);
|
tim = ktime_set(0, NSEC_PER_USEC);
|
||||||
|
|
||||||
change:
|
change:
|
||||||
at86rf230_async_read_reg(lp, RG_TRX_STATUS, ctx,
|
hrtimer_start(&ctx->timer, tim, HRTIMER_MODE_REL);
|
||||||
at86rf230_async_state_assert,
|
|
||||||
ctx->irq_enable);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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.tx_buf = lp->state.buf;
|
||||||
lp->state.trx.rx_buf = lp->state.buf;
|
lp->state.trx.rx_buf = lp->state.buf;
|
||||||
spi_message_add_tail(&lp->state.trx, &lp->state.msg);
|
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.lp = lp;
|
||||||
lp->irq.irq = lp->spi->irq;
|
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.tx_buf = lp->irq.buf;
|
||||||
lp->irq.trx.rx_buf = lp->irq.buf;
|
lp->irq.trx.rx_buf = lp->irq.buf;
|
||||||
spi_message_add_tail(&lp->irq.trx, &lp->irq.msg);
|
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.lp = lp;
|
||||||
lp->tx.irq = lp->spi->irq;
|
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.tx_buf = lp->tx.buf;
|
||||||
lp->tx.trx.rx_buf = lp->tx.buf;
|
lp->tx.trx.rx_buf = lp->tx.buf;
|
||||||
spi_message_add_tail(&lp->tx.trx, &lp->tx.msg);
|
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)
|
static int at86rf230_probe(struct spi_device *spi)
|
||||||
|
|
Loading…
Reference in New Issue