Skip to content

Commit 3744161

Browse files
alexaringholtmann
authored andcommitted
mrf24j40: async interrupt handling
This patch removes the threaded irq handling and do a hardirq instead. We need to switch to spi_async for this step for getting the irq status register. Reviewed-by: Stefan Schmidt <stefan@osg.samsung.com> Signed-off-by: Alexander Aring <alex.aring@gmail.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
1 parent c91a301 commit 3744161

File tree

1 file changed

+40
-53
lines changed

1 file changed

+40
-53
lines changed

drivers/net/ieee802154/mrf24j40.c

Lines changed: 40 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,10 @@ struct mrf24j40 {
181181
u8 rx_fifo_buf[RX_FIFO_SIZE];
182182
struct spi_transfer rx_fifo_buf_trx;
183183

184-
struct mutex buffer_mutex; /* only used to protect buf */
185-
u8 *buf; /* 3 bytes. Used for SPI single-register transfers. */
184+
/* isr handling for reading intstat */
185+
struct spi_message irq_msg;
186+
u8 irq_buf[2];
187+
struct spi_transfer irq_trx;
186188
};
187189

188190
/* regmap information for short address register access */
@@ -486,34 +488,6 @@ static const struct regmap_bus mrf24j40_long_regmap_bus = {
486488
.val_format_endian_default = REGMAP_ENDIAN_BIG,
487489
};
488490

489-
static int read_short_reg(struct mrf24j40 *devrec, u8 reg, u8 *val)
490-
{
491-
int ret = -1;
492-
struct spi_message msg;
493-
struct spi_transfer xfer = {
494-
.len = 2,
495-
.tx_buf = devrec->buf,
496-
.rx_buf = devrec->buf,
497-
};
498-
499-
spi_message_init(&msg);
500-
spi_message_add_tail(&xfer, &msg);
501-
502-
mutex_lock(&devrec->buffer_mutex);
503-
devrec->buf[0] = MRF24J40_READSHORT(reg);
504-
devrec->buf[1] = 0;
505-
506-
ret = spi_sync(devrec->spi, &msg);
507-
if (ret)
508-
dev_err(printdev(devrec),
509-
"SPI read Failed for short register 0x%hhx\n", reg);
510-
else
511-
*val = devrec->buf[1];
512-
513-
mutex_unlock(&devrec->buffer_mutex);
514-
return ret;
515-
}
516-
517491
static void write_tx_buf_complete(void *context)
518492
{
519493
struct mrf24j40 *devrec = context;
@@ -812,16 +786,12 @@ static const struct ieee802154_ops mrf24j40_ops = {
812786
.set_hw_addr_filt = mrf24j40_filter,
813787
};
814788

815-
static irqreturn_t mrf24j40_isr(int irq, void *data)
789+
static void mrf24j40_intstat_complete(void *context)
816790
{
817-
struct mrf24j40 *devrec = data;
818-
u8 intstat;
819-
int ret;
791+
struct mrf24j40 *devrec = context;
792+
u8 intstat = devrec->irq_buf[1];
820793

821-
/* Read the interrupt status */
822-
ret = read_short_reg(devrec, REG_INTSTAT, &intstat);
823-
if (ret)
824-
goto out;
794+
enable_irq(devrec->spi->irq);
825795

826796
/* Check for TX complete */
827797
if (intstat & 0x1)
@@ -830,8 +800,23 @@ static irqreturn_t mrf24j40_isr(int irq, void *data)
830800
/* Check for Rx */
831801
if (intstat & 0x8)
832802
mrf24j40_handle_rx(devrec);
803+
}
804+
805+
static irqreturn_t mrf24j40_isr(int irq, void *data)
806+
{
807+
struct mrf24j40 *devrec = data;
808+
int ret;
809+
810+
disable_irq_nosync(irq);
811+
812+
devrec->irq_buf[0] = MRF24J40_READSHORT(REG_INTSTAT);
813+
/* Read the interrupt status */
814+
ret = spi_async(devrec->spi, &devrec->irq_msg);
815+
if (ret) {
816+
enable_irq(irq);
817+
return IRQ_NONE;
818+
}
833819

834-
out:
835820
return IRQ_HANDLED;
836821
}
837822

@@ -978,6 +963,18 @@ mrf24j40_setup_rx_spi_messages(struct mrf24j40 *devrec)
978963
spi_message_add_tail(&devrec->rx_lqi_trx, &devrec->rx_buf_msg);
979964
}
980965

966+
static void
967+
mrf24j40_setup_irq_spi_messages(struct mrf24j40 *devrec)
968+
{
969+
spi_message_init(&devrec->irq_msg);
970+
devrec->irq_msg.context = devrec;
971+
devrec->irq_msg.complete = mrf24j40_intstat_complete;
972+
devrec->irq_trx.len = 2;
973+
devrec->irq_trx.tx_buf = devrec->irq_buf;
974+
devrec->irq_trx.rx_buf = devrec->irq_buf;
975+
spi_message_add_tail(&devrec->irq_trx, &devrec->irq_msg);
976+
}
977+
981978
static void mrf24j40_phy_setup(struct mrf24j40 *devrec)
982979
{
983980
ieee802154_random_extended_addr(&devrec->hw->phy->perm_extended_addr);
@@ -1008,6 +1005,7 @@ static int mrf24j40_probe(struct spi_device *spi)
10081005

10091006
mrf24j40_setup_tx_spi_messages(devrec);
10101007
mrf24j40_setup_rx_spi_messages(devrec);
1008+
mrf24j40_setup_irq_spi_messages(devrec);
10111009

10121010
devrec->regmap_short = devm_regmap_init_spi(spi,
10131011
&mrf24j40_short_regmap);
@@ -1028,32 +1026,21 @@ static int mrf24j40_probe(struct spi_device *spi)
10281026
goto err_register_device;
10291027
}
10301028

1031-
devrec->buf = devm_kzalloc(&spi->dev, 3, GFP_KERNEL);
1032-
if (!devrec->buf)
1033-
goto err_register_device;
1034-
10351029
if (spi->max_speed_hz > MAX_SPI_SPEED_HZ) {
10361030
dev_warn(&spi->dev, "spi clock above possible maximum: %d",
10371031
MAX_SPI_SPEED_HZ);
10381032
return -EINVAL;
10391033
}
10401034

1041-
mutex_init(&devrec->buffer_mutex);
1042-
10431035
ret = mrf24j40_hw_init(devrec);
10441036
if (ret)
10451037
goto err_register_device;
10461038

10471039
mrf24j40_phy_setup(devrec);
10481040

1049-
ret = devm_request_threaded_irq(&spi->dev,
1050-
spi->irq,
1051-
NULL,
1052-
mrf24j40_isr,
1053-
IRQF_TRIGGER_LOW|IRQF_ONESHOT,
1054-
dev_name(&spi->dev),
1055-
devrec);
1056-
1041+
ret = devm_request_irq(&spi->dev, spi->irq, mrf24j40_isr,
1042+
IRQF_TRIGGER_LOW, dev_name(&spi->dev),
1043+
devrec);
10571044
if (ret) {
10581045
dev_err(printdev(devrec), "Unable to get IRQ");
10591046
goto err_register_device;

0 commit comments

Comments
 (0)