Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eb3b435e authored by Alexander Aring's avatar Alexander Aring Committed by Marcel Holtmann
Browse files

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: default avatarAlexander Aring <alex.aring@gmail.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent e3721749
Loading
Loading
Loading
Loading
+29 −10
Original line number Original line Diff line number Diff line
@@ -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)