| From 6215769d5175a1011eb1d60f0604e9412f78569a Mon Sep 17 00:00:00 2001 |
| From: Mika Westerberg <mika.westerberg@linux.intel.com> |
| Date: Wed, 22 Jan 2020 19:28:04 +0300 |
| Subject: [PATCH] platform/x86: intel_scu_ipc: Fix interrupt support |
| |
| commit e48b72a568bbd641c91dad354138d3c17d03ee6f upstream. |
| |
| Currently the driver has disabled interrupt support for Tangier but |
| actually interrupt works just fine if the command is not written twice |
| in a row. Also we need to ack the interrupt in the handler. |
| |
| Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> |
| Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c |
| index cdab916fbf92..e330ec73c465 100644 |
| --- a/drivers/platform/x86/intel_scu_ipc.c |
| +++ b/drivers/platform/x86/intel_scu_ipc.c |
| @@ -67,26 +67,22 @@ |
| struct intel_scu_ipc_pdata_t { |
| u32 i2c_base; |
| u32 i2c_len; |
| - u8 irq_mode; |
| }; |
| |
| static const struct intel_scu_ipc_pdata_t intel_scu_ipc_lincroft_pdata = { |
| .i2c_base = 0xff12b000, |
| .i2c_len = 0x10, |
| - .irq_mode = 0, |
| }; |
| |
| /* Penwell and Cloverview */ |
| static const struct intel_scu_ipc_pdata_t intel_scu_ipc_penwell_pdata = { |
| .i2c_base = 0xff12b000, |
| .i2c_len = 0x10, |
| - .irq_mode = 1, |
| }; |
| |
| static const struct intel_scu_ipc_pdata_t intel_scu_ipc_tangier_pdata = { |
| .i2c_base = 0xff00d000, |
| .i2c_len = 0x10, |
| - .irq_mode = 0, |
| }; |
| |
| struct intel_scu_ipc_dev { |
| @@ -99,6 +95,9 @@ struct intel_scu_ipc_dev { |
| |
| static struct intel_scu_ipc_dev ipcdev; /* Only one for now */ |
| |
| +#define IPC_STATUS 0x04 |
| +#define IPC_STATUS_IRQ BIT(2) |
| + |
| /* |
| * IPC Read Buffer (Read Only): |
| * 16 byte buffer for receiving data from SCU, if IPC command |
| @@ -120,11 +119,8 @@ static DEFINE_MUTEX(ipclock); /* lock used to prevent multiple call to SCU */ |
| */ |
| static inline void ipc_command(struct intel_scu_ipc_dev *scu, u32 cmd) |
| { |
| - if (scu->irq_mode) { |
| - reinit_completion(&scu->cmd_complete); |
| - writel(cmd | IPC_IOC, scu->ipc_base); |
| - } |
| - writel(cmd, scu->ipc_base); |
| + reinit_completion(&scu->cmd_complete); |
| + writel(cmd | IPC_IOC, scu->ipc_base); |
| } |
| |
| /* |
| @@ -610,9 +606,10 @@ EXPORT_SYMBOL(intel_scu_ipc_i2c_cntrl); |
| static irqreturn_t ioc(int irq, void *dev_id) |
| { |
| struct intel_scu_ipc_dev *scu = dev_id; |
| + int status = ipc_read_status(scu); |
| |
| - if (scu->irq_mode) |
| - complete(&scu->cmd_complete); |
| + writel(status | IPC_STATUS_IRQ, scu->ipc_base + IPC_STATUS); |
| + complete(&scu->cmd_complete); |
| |
| return IRQ_HANDLED; |
| } |
| @@ -638,8 +635,6 @@ static int ipc_probe(struct pci_dev *pdev, const struct pci_device_id *id) |
| if (!pdata) |
| return -ENODEV; |
| |
| - scu->irq_mode = pdata->irq_mode; |
| - |
| err = pcim_enable_device(pdev); |
| if (err) |
| return err; |
| -- |
| 2.7.4 |
| |