diff options
author | Alexander Aring <alex.aring@gmail.com> | 2015-03-09 08:56:10 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2015-03-14 12:11:31 -0400 |
commit | eb3b435ecdb84d05698db862ce316b3c682f9a95 (patch) | |
tree | 57c022f48048b75551cb3e395276383ca0c611e7 | |
parent | e3721749000e11ba3f315efc5c98bf4cd5662f99 (diff) |
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>
-rw-r--r-- | drivers/net/ieee802154/at86rf230.c | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index edf575c88345..4030fa69f176 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c | |||
@@ -19,6 +19,7 @@ | |||
19 | */ | 19 | */ |
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/hrtimer.h> | ||
22 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
23 | #include <linux/irq.h> | 24 | #include <linux/irq.h> |
24 | #include <linux/gpio.h> | 25 | #include <linux/gpio.h> |
@@ -64,6 +65,7 @@ struct at86rf230_state_change { | |||
64 | struct at86rf230_local *lp; | 65 | struct at86rf230_local *lp; |
65 | int irq; | 66 | int irq; |
66 | 67 | ||
68 | struct hrtimer timer; | ||
67 | struct spi_message msg; | 69 | struct spi_message msg; |
68 | struct spi_transfer trx; | 70 | struct spi_transfer trx; |
69 | u8 buf[AT86RF2XX_MAX_BUF]; | 71 | u8 buf[AT86RF2XX_MAX_BUF]; |
@@ -548,6 +550,19 @@ done: | |||
548 | ctx->complete(context); | 550 | ctx->complete(context); |
549 | } | 551 | } |
550 | 552 | ||
553 | static enum hrtimer_restart at86rf230_async_state_timer(struct hrtimer *timer) | ||
554 | { | ||
555 | struct at86rf230_state_change *ctx = | ||
556 | container_of(timer, struct at86rf230_state_change, timer); | ||
557 | struct at86rf230_local *lp = ctx->lp; | ||
558 | |||
559 | at86rf230_async_read_reg(lp, RG_TRX_STATUS, ctx, | ||
560 | at86rf230_async_state_assert, | ||
561 | ctx->irq_enable); | ||
562 | |||
563 | return HRTIMER_NORESTART; | ||
564 | } | ||
565 | |||
551 | /* Do state change timing delay. */ | 566 | /* Do state change timing delay. */ |
552 | static void | 567 | static void |
553 | at86rf230_async_state_delay(void *context) | 568 | at86rf230_async_state_delay(void *context) |
@@ -556,6 +571,7 @@ at86rf230_async_state_delay(void *context) | |||
556 | struct at86rf230_local *lp = ctx->lp; | 571 | struct at86rf230_local *lp = ctx->lp; |
557 | struct at86rf2xx_chip_data *c = lp->data; | 572 | struct at86rf2xx_chip_data *c = lp->data; |
558 | bool force = false; | 573 | bool force = false; |
574 | ktime_t tim; | ||
559 | 575 | ||
560 | /* The force state changes are will show as normal states in the | 576 | /* The force state changes are will show as normal states in the |
561 | * state status subregister. We change the to_state to the | 577 | * state status subregister. We change the to_state to the |
@@ -579,11 +595,10 @@ at86rf230_async_state_delay(void *context) | |||
579 | case STATE_TRX_OFF: | 595 | case STATE_TRX_OFF: |
580 | switch (ctx->to_state) { | 596 | switch (ctx->to_state) { |
581 | case STATE_RX_AACK_ON: | 597 | case STATE_RX_AACK_ON: |
582 | usleep_range(c->t_off_to_aack, c->t_off_to_aack + 10); | 598 | tim = ktime_set(0, c->t_off_to_aack * NSEC_PER_USEC); |
583 | goto change; | 599 | goto change; |
584 | case STATE_TX_ON: | 600 | case STATE_TX_ON: |
585 | usleep_range(c->t_off_to_tx_on, | 601 | tim = ktime_set(0, c->t_off_to_tx_on * NSEC_PER_USEC); |
586 | c->t_off_to_tx_on + 10); | ||
587 | goto change; | 602 | goto change; |
588 | default: | 603 | default: |
589 | break; | 604 | break; |
@@ -597,8 +612,8 @@ at86rf230_async_state_delay(void *context) | |||
597 | * to TX_ON. | 612 | * to TX_ON. |
598 | */ | 613 | */ |
599 | if (!force) { | 614 | if (!force) { |
600 | usleep_range(c->t_frame + c->t_p_ack, | 615 | tim = ktime_set(0, (c->t_frame + c->t_p_ack) * |
601 | c->t_frame + c->t_p_ack + 1000); | 616 | NSEC_PER_USEC); |
602 | goto change; | 617 | goto change; |
603 | } | 618 | } |
604 | break; | 619 | break; |
@@ -610,7 +625,7 @@ at86rf230_async_state_delay(void *context) | |||
610 | case STATE_P_ON: | 625 | case STATE_P_ON: |
611 | switch (ctx->to_state) { | 626 | switch (ctx->to_state) { |
612 | case STATE_TRX_OFF: | 627 | case STATE_TRX_OFF: |
613 | usleep_range(c->t_reset_to_off, c->t_reset_to_off + 10); | 628 | tim = ktime_set(0, c->t_reset_to_off * NSEC_PER_USEC); |
614 | goto change; | 629 | goto change; |
615 | default: | 630 | default: |
616 | break; | 631 | break; |
@@ -621,12 +636,10 @@ at86rf230_async_state_delay(void *context) | |||
621 | } | 636 | } |
622 | 637 | ||
623 | /* Default delay is 1us in the most cases */ | 638 | /* Default delay is 1us in the most cases */ |
624 | udelay(1); | 639 | tim = ktime_set(0, NSEC_PER_USEC); |
625 | 640 | ||
626 | change: | 641 | change: |
627 | at86rf230_async_read_reg(lp, RG_TRX_STATUS, ctx, | 642 | hrtimer_start(&ctx->timer, tim, HRTIMER_MODE_REL); |
628 | at86rf230_async_state_assert, | ||
629 | ctx->irq_enable); | ||
630 | } | 643 | } |
631 | 644 | ||
632 | static void | 645 | static void |
@@ -1546,6 +1559,8 @@ at86rf230_setup_spi_messages(struct at86rf230_local *lp) | |||
1546 | lp->state.trx.tx_buf = lp->state.buf; | 1559 | lp->state.trx.tx_buf = lp->state.buf; |
1547 | lp->state.trx.rx_buf = lp->state.buf; | 1560 | lp->state.trx.rx_buf = lp->state.buf; |
1548 | spi_message_add_tail(&lp->state.trx, &lp->state.msg); | 1561 | spi_message_add_tail(&lp->state.trx, &lp->state.msg); |
1562 | hrtimer_init(&lp->state.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | ||
1563 | lp->state.timer.function = at86rf230_async_state_timer; | ||
1549 | 1564 | ||
1550 | lp->irq.lp = lp; | 1565 | lp->irq.lp = lp; |
1551 | lp->irq.irq = lp->spi->irq; | 1566 | lp->irq.irq = lp->spi->irq; |
@@ -1555,6 +1570,8 @@ at86rf230_setup_spi_messages(struct at86rf230_local *lp) | |||
1555 | lp->irq.trx.tx_buf = lp->irq.buf; | 1570 | lp->irq.trx.tx_buf = lp->irq.buf; |
1556 | lp->irq.trx.rx_buf = lp->irq.buf; | 1571 | lp->irq.trx.rx_buf = lp->irq.buf; |
1557 | spi_message_add_tail(&lp->irq.trx, &lp->irq.msg); | 1572 | spi_message_add_tail(&lp->irq.trx, &lp->irq.msg); |
1573 | hrtimer_init(&lp->irq.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | ||
1574 | lp->irq.timer.function = at86rf230_async_state_timer; | ||
1558 | 1575 | ||
1559 | lp->tx.lp = lp; | 1576 | lp->tx.lp = lp; |
1560 | lp->tx.irq = lp->spi->irq; | 1577 | lp->tx.irq = lp->spi->irq; |
@@ -1564,6 +1581,8 @@ at86rf230_setup_spi_messages(struct at86rf230_local *lp) | |||
1564 | lp->tx.trx.tx_buf = lp->tx.buf; | 1581 | lp->tx.trx.tx_buf = lp->tx.buf; |
1565 | lp->tx.trx.rx_buf = lp->tx.buf; | 1582 | lp->tx.trx.rx_buf = lp->tx.buf; |
1566 | spi_message_add_tail(&lp->tx.trx, &lp->tx.msg); | 1583 | spi_message_add_tail(&lp->tx.trx, &lp->tx.msg); |
1584 | hrtimer_init(&lp->tx.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | ||
1585 | lp->tx.timer.function = at86rf230_async_state_timer; | ||
1567 | } | 1586 | } |
1568 | 1587 | ||
1569 | static int at86rf230_probe(struct spi_device *spi) | 1588 | static int at86rf230_probe(struct spi_device *spi) |