Skip to content

Commit

Permalink
mrf24j40: change irq trigger type behaviour
Browse files Browse the repository at this point in the history
This patch changes the irq trigger type value while calling
devm_request_irq by using IRQF_TRIGGER_LOW when no irq type was given.
Additional we add support for change the irq polarity while hw init if
high level or low level triggered irq type are given.

For rising edge triggered irq's the mrf24j40 can't deal with that, this
races at position of tx completion irq, while the irq is disabled we
readout the irq status registers. This will resets the irq line so other
irq's can occur. Wile readout the irq status register the irq is still
disabled and edge triggered interrupts will be ignored.

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 Sep 22, 2015
1 parent 8ba4041 commit afaf7fd
Showing 1 changed file with 28 additions and 3 deletions.
31 changes: 28 additions & 3 deletions drivers/net/ieee802154/mrf24j40.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/ieee802154.h>
#include <linux/irq.h>
#include <net/cfg802154.h>
#include <net/mac802154.h>

Expand Down Expand Up @@ -992,6 +993,7 @@ static irqreturn_t mrf24j40_isr(int irq, void *data)

static int mrf24j40_hw_init(struct mrf24j40 *devrec)
{
u32 irq_type;
int ret;

/* Initialize the device.
Expand Down Expand Up @@ -1083,6 +1085,25 @@ static int mrf24j40_hw_init(struct mrf24j40 *devrec)
regmap_write(devrec->regmap_long, REG_RFCON3, 0x28);
}

irq_type = irq_get_trigger_type(devrec->spi->irq);
if (irq_type == IRQ_TYPE_EDGE_RISING ||
irq_type == IRQ_TYPE_EDGE_FALLING)
dev_warn(&devrec->spi->dev,
"Using edge triggered irq's are not recommended, because it can cause races and result in a non-functional driver!\n");
switch (irq_type) {
case IRQ_TYPE_EDGE_RISING:
case IRQ_TYPE_LEVEL_HIGH:
/* set interrupt polarity to rising */
ret = regmap_update_bits(devrec->regmap_long, REG_SLPCON0,
0x02, 0x02);
if (ret)
goto err_ret;
break;
default:
/* default is falling edge */
break;
}

return 0;

err_ret:
Expand Down Expand Up @@ -1182,7 +1203,7 @@ static void mrf24j40_phy_setup(struct mrf24j40 *devrec)

static int mrf24j40_probe(struct spi_device *spi)
{
int ret = -ENOMEM;
int ret = -ENOMEM, irq_type;
struct ieee802154_hw *hw;
struct mrf24j40 *devrec;

Expand Down Expand Up @@ -1242,9 +1263,13 @@ static int mrf24j40_probe(struct spi_device *spi)

mrf24j40_phy_setup(devrec);

/* request IRQF_TRIGGER_LOW as fallback default */
irq_type = irq_get_trigger_type(spi->irq);
if (!irq_type)
irq_type = IRQF_TRIGGER_LOW;

ret = devm_request_irq(&spi->dev, spi->irq, mrf24j40_isr,
IRQF_TRIGGER_LOW, dev_name(&spi->dev),
devrec);
irq_type, dev_name(&spi->dev), devrec);
if (ret) {
dev_err(printdev(devrec), "Unable to get IRQ");
goto err_register_device;
Expand Down

0 comments on commit afaf7fd

Please sign in to comment.