mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-22 10:34:55 +08:00
mrf24j40: change irq trigger type behaviour
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>
This commit is contained in:
parent
8ba4041740
commit
afaf7fdedb
@ -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>
|
||||
|
||||
@ -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.
|
||||
@ -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:
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user