diff --git a/drivers/spi/spi-kbus.c b/drivers/spi/spi-kbus.c index b083a296bdcc..2f1a1bbc3c6c 100644 --- a/drivers/spi/spi-kbus.c +++ b/drivers/spi/spi-kbus.c @@ -112,9 +112,31 @@ static irqreturn_t kbus_isr(int irq, void *dev) struct kbus_drv_data *kdrvdata = dev_get_drvdata(kbus_device); trace_pxc_kbus(__func__, "kbus-irq:in"); - kdrvdata->kbus_irq_state = 0; /* attention: changed polarisation */ - /* wake_up_interruptible(&kdrvdata->kbus_irq_wq); */ + if (unlikely(kdrvdata->cmdsel)) { + if (kdrvdata->kbus_ign_reset_irq) { + kdrvdata->kbus_ign_reset_irq = 0; + init_waitqueue_head(&kdrvdata->kbus_irq_wq); + // trace for command 0xA3 find in libkbusfwload library + trace_pxc_kbus(__func__, "kbus-irq: edge falling after command\ + SCPU_COMMAND_START_UPDATE [0xa3]: ignore irq"); + return IRQ_HANDLED; + } + + int gpio_value = gpiod_get_value(kdrvdata->gpio_nrdy); + + if (gpio_value) { + trace_pxc_kbus(__func__, "kbus-irq: edge rising"); + } else if (kdrvdata->kbus_ign_irq) { + trace_pxc_kbus(__func__, "kbus-irq: edge falling during command\ + SCPU_COMMAND_START_UPDATE [0xa3]"); + kdrvdata->kbus_ign_reset_irq = 1; + } else { + trace_pxc_kbus(__func__, "kbus-irq: edge falling"); + } + } + + kdrvdata->kbus_irq_state = 0; /* attention: changed polarisation */ wake_up(&kdrvdata->kbus_irq_wq); trace_pxc_kbus(__func__, "kbus-irq:out"); @@ -637,6 +659,7 @@ static long kbus_ioctl(struct file *file, uint cmd, ulong arg) struct kbus_drv_data *kdrvdata = dev_get_drvdata(kbus_device); struct spi_device *spi = kdrvdata->spi; + kdrvdata->kbus_ign_irq = 0; switch (cmd) { case KBUS_IOC_CMD: /* FIXME */ { @@ -657,6 +680,12 @@ static long kbus_ioctl(struct file *file, uint cmd, ulong arg) gpiod_set_value(kdrvdata->gpio_nirq, 0); kcmd_user = (struct kbus_cmd __user *)arg; + + if ((int)*kcmd_user->tx_buf == 0xA3) { + kdrvdata->kbus_ign_irq = 1; + trace_pxc_kbus(__func__, "KCMD: A3: Update cmd"); + } + if (copy_from_user(&kcmd, kcmd_user, sizeof(kcmd))) { /* release the irq pin */ gpiod_set_value(kdrvdata->gpio_nirq, 1); @@ -1123,6 +1152,9 @@ static int kbus_probe(struct spi_device *spi) KBUS_DISABLE_IRQ(kdrvdata->kbus_irq); kdrvdata->kbus_irq_enabled = 0; + /* disable ignore of irq after 0xa3 (update) cmd */ + kdrvdata->kbus_ign_reset_irq = 0; + /* allocate memory */ if (kdrvdata->use_dma) { spi->dev.coherent_dma_mask = ~0; /* why that? */ diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 3ee249d33457..e6a520b26957 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -1568,7 +1568,7 @@ static int omap2_mcspi_transfer_one(struct spi_controller *ctlr, kcmd_txbuf = (u16 *) t->tx_buf; /* wait for READYn IRQ from xe164 */ - trace_pxc_kbus(__func__, "TX0"); + trace_pxc_kbus(__func__, "TX0: Wait for nrdy"); kbus_dbg("%s: irq timeout is %dms\n", __func__, kdrvdata->timeout_ms); tmp_ret = wait_event_interruptible_timeout(kdrvdata->kbus_irq_wq, diff --git a/include/linux/spi/kbus.h b/include/linux/spi/kbus.h index a4b81fb8cc51..4b3612d858f2 100644 --- a/include/linux/spi/kbus.h +++ b/include/linux/spi/kbus.h @@ -76,6 +76,8 @@ struct kbus_drv_data { int kbus_irq; int kbus_irq_enabled; int kbus_irq_state; + int kbus_ign_irq; + int kbus_ign_reset_irq; struct task_struct *dma_task; /* task pointer to boost the dma task if necessary */ bool kbus_dma_boost_en;