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: 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>alistair/sensors
parent
298ef70f3a
commit
e48b72a568
|
@ -67,26 +67,22 @@
|
||||||
struct intel_scu_ipc_pdata_t {
|
struct intel_scu_ipc_pdata_t {
|
||||||
u32 i2c_base;
|
u32 i2c_base;
|
||||||
u32 i2c_len;
|
u32 i2c_len;
|
||||||
u8 irq_mode;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct intel_scu_ipc_pdata_t intel_scu_ipc_lincroft_pdata = {
|
static const struct intel_scu_ipc_pdata_t intel_scu_ipc_lincroft_pdata = {
|
||||||
.i2c_base = 0xff12b000,
|
.i2c_base = 0xff12b000,
|
||||||
.i2c_len = 0x10,
|
.i2c_len = 0x10,
|
||||||
.irq_mode = 0,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Penwell and Cloverview */
|
/* Penwell and Cloverview */
|
||||||
static const struct intel_scu_ipc_pdata_t intel_scu_ipc_penwell_pdata = {
|
static const struct intel_scu_ipc_pdata_t intel_scu_ipc_penwell_pdata = {
|
||||||
.i2c_base = 0xff12b000,
|
.i2c_base = 0xff12b000,
|
||||||
.i2c_len = 0x10,
|
.i2c_len = 0x10,
|
||||||
.irq_mode = 1,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct intel_scu_ipc_pdata_t intel_scu_ipc_tangier_pdata = {
|
static const struct intel_scu_ipc_pdata_t intel_scu_ipc_tangier_pdata = {
|
||||||
.i2c_base = 0xff00d000,
|
.i2c_base = 0xff00d000,
|
||||||
.i2c_len = 0x10,
|
.i2c_len = 0x10,
|
||||||
.irq_mode = 0,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct intel_scu_ipc_dev {
|
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 */
|
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):
|
* IPC Read Buffer (Read Only):
|
||||||
* 16 byte buffer for receiving data from SCU, if IPC command
|
* 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)
|
static inline void ipc_command(struct intel_scu_ipc_dev *scu, u32 cmd)
|
||||||
{
|
{
|
||||||
if (scu->irq_mode) {
|
reinit_completion(&scu->cmd_complete);
|
||||||
reinit_completion(&scu->cmd_complete);
|
writel(cmd | IPC_IOC, scu->ipc_base);
|
||||||
writel(cmd | IPC_IOC, scu->ipc_base);
|
|
||||||
}
|
|
||||||
writel(cmd, scu->ipc_base);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -610,9 +606,10 @@ EXPORT_SYMBOL(intel_scu_ipc_i2c_cntrl);
|
||||||
static irqreturn_t ioc(int irq, void *dev_id)
|
static irqreturn_t ioc(int irq, void *dev_id)
|
||||||
{
|
{
|
||||||
struct intel_scu_ipc_dev *scu = 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);
|
complete(&scu->cmd_complete);
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
@ -638,8 +635,6 @@ static int ipc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||||
if (!pdata)
|
if (!pdata)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
scu->irq_mode = pdata->irq_mode;
|
|
||||||
|
|
||||||
err = pcim_enable_device(pdev);
|
err = pcim_enable_device(pdev);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
Loading…
Reference in New Issue