Commit e48b72a5 authored by Mika Westerberg's avatar Mika Westerberg Committed by Andy Shevchenko
Browse files

platform/x86: intel_scu_ipc: Fix interrupt support



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: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
parent 298ef70f
Loading
Loading
Loading
Loading
+8 −13
Original line number Diff line number Diff line
@@ -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,12 +119,9 @@ 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);
}

/*
 * Write ipc data
@@ -610,8 +606,9 @@ 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)
	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;