From patchwork Mon Oct 12 11:19:45 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andy Shevchenko X-Patchwork-Id: 7374101 Return-Path: X-Original-To: patchwork-platform-driver-x86@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id BD56CBEEA4 for ; Mon, 12 Oct 2015 11:19:57 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 8F693206FD for ; Mon, 12 Oct 2015 11:19:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id F311C2070C for ; Mon, 12 Oct 2015 11:19:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751073AbbJLLTy (ORCPT ); Mon, 12 Oct 2015 07:19:54 -0400 Received: from mga02.intel.com ([134.134.136.20]:59220 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751231AbbJLLTw (ORCPT ); Mon, 12 Oct 2015 07:19:52 -0400 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga101.jf.intel.com with ESMTP; 12 Oct 2015 04:19:51 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,672,1437462000"; d="scan'208";a="824862620" Received: from black.fi.intel.com ([10.237.72.93]) by fmsmga002.fm.intel.com with ESMTP; 12 Oct 2015 04:19:50 -0700 Received: by black.fi.intel.com (Postfix, from userid 1003) id 2C9D4117; Mon, 12 Oct 2015 14:19:49 +0300 (EEST) From: Andy Shevchenko To: platform-driver-x86@vger.kernel.org, Darren Hart , linux-kernel@vger.kernel.org Cc: Andy Shevchenko Subject: [PATCH v2 2/5] intel_scu_ipc: propagate pointer to struct intel_scu_ipc_dev Date: Mon, 12 Oct 2015 14:19:45 +0300 Message-Id: <1444648788-74265-3-git-send-email-andriy.shevchenko@linux.intel.com> X-Mailer: git-send-email 2.5.3 In-Reply-To: <1444648788-74265-1-git-send-email-andriy.shevchenko@linux.intel.com> References: <1444648788-74265-1-git-send-email-andriy.shevchenko@linux.intel.com> Sender: platform-driver-x86-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP As much as poosible propagate a pointer to struct intel_scu_ipc_dev. There is no functional change. Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel_scu_ipc.c | 134 +++++++++++++++++++---------------- 1 file changed, 74 insertions(+), 60 deletions(-) diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c index 7148535..6c9367f 100644 --- a/drivers/platform/x86/intel_scu_ipc.c +++ b/drivers/platform/x86/intel_scu_ipc.c @@ -118,28 +118,30 @@ static struct intel_scu_ipc_dev ipcdev; /* Only one for now */ static DEFINE_MUTEX(ipclock); /* lock used to prevent multiple call to SCU */ /* + * Send ipc command * Command Register (Write Only): * A write to this register results in an interrupt to the SCU core processor * Format: * |rfu2(8) | size(8) | command id(4) | rfu1(3) | ioc(1) | command(8)| */ -static inline void ipc_command(u32 cmd) /* Send ipc command */ +static inline void ipc_command(struct intel_scu_ipc_dev *scu, u32 cmd) { - if (ipcdev.irq_mode) { - reinit_completion(&ipcdev.cmd_complete); - writel(cmd | IPC_IOC, ipcdev.ipc_base); + if (scu->irq_mode) { + reinit_completion(&scu->cmd_complete); + writel(cmd | IPC_IOC, scu->ipc_base); } - writel(cmd, ipcdev.ipc_base); + writel(cmd, scu->ipc_base); } /* + * Write ipc data * IPC Write Buffer (Write Only): * 16-byte buffer for sending data associated with IPC command to * SCU. Size of the data is specified in the IPC_COMMAND_REG register */ -static inline void ipc_data_writel(u32 data, u32 offset) /* Write ipc data */ +static inline void ipc_data_writel(struct intel_scu_ipc_dev *scu, u32 data, u32 offset) { - writel(data, ipcdev.ipc_base + 0x80 + offset); + writel(data, scu->ipc_base + 0x80 + offset); } /* @@ -149,35 +151,37 @@ static inline void ipc_data_writel(u32 data, u32 offset) /* Write ipc data */ * Format: * |rfu3(8)|error code(8)|initiator id(8)|cmd id(4)|rfu1(2)|error(1)|busy(1)| */ -static inline u8 ipc_read_status(void) +static inline u8 ipc_read_status(struct intel_scu_ipc_dev *scu) { - return __raw_readl(ipcdev.ipc_base + 0x04); + return __raw_readl(scu->ipc_base + 0x04); } -static inline u8 ipc_data_readb(u32 offset) /* Read ipc byte data */ +/* Read ipc byte data */ +static inline u8 ipc_data_readb(struct intel_scu_ipc_dev *scu, u32 offset) { - return readb(ipcdev.ipc_base + IPC_READ_BUFFER + offset); + return readb(scu->ipc_base + IPC_READ_BUFFER + offset); } -static inline u32 ipc_data_readl(u32 offset) /* Read ipc u32 data */ +/* Read ipc u32 data */ +static inline u32 ipc_data_readl(struct intel_scu_ipc_dev *scu, u32 offset) { - return readl(ipcdev.ipc_base + IPC_READ_BUFFER + offset); + return readl(scu->ipc_base + IPC_READ_BUFFER + offset); } /* Wait till scu status is busy */ -static inline int busy_loop(void) +static inline int busy_loop(struct intel_scu_ipc_dev *scu) { - u32 status = ipc_read_status(); + u32 status = ipc_read_status(scu); u32 loop_count = 100000; /* break if scu doesn't reset busy bit after huge retry */ while ((status & BIT(0)) && --loop_count) { udelay(1); /* scu processing time is in few u secods */ - status = ipc_read_status(); + status = ipc_read_status(scu); } if (status & BIT(0)) { - dev_err(&ipcdev.pdev->dev, "IPC timed out"); + dev_err(&scu->pdev->dev, "IPC timed out"); return -ETIMEDOUT; } @@ -188,31 +192,32 @@ static inline int busy_loop(void) } /* Wait till ipc ioc interrupt is received or timeout in 3 HZ */ -static inline int ipc_wait_for_interrupt(void) +static inline int ipc_wait_for_interrupt(struct intel_scu_ipc_dev *scu) { int status; - if (!wait_for_completion_timeout(&ipcdev.cmd_complete, 3 * HZ)) { - struct device *dev = &ipcdev.pdev->dev; + if (!wait_for_completion_timeout(&scu->cmd_complete, 3 * HZ)) { + struct device *dev = &scu->pdev->dev; dev_err(dev, "IPC timed out\n"); return -ETIMEDOUT; } - status = ipc_read_status(); + status = ipc_read_status(scu); if (status & BIT(1)) return -EIO; return 0; } -static int intel_scu_ipc_check_status(void) +static int intel_scu_ipc_check_status(struct intel_scu_ipc_dev *scu) { - return ipcdev.irq_mode ? ipc_wait_for_interrupt() : busy_loop(); + return scu->irq_mode ? ipc_wait_for_interrupt(scu) : busy_loop(scu); } /* Read/Write power control(PMIC in Langwell, MSIC in PenWell) registers */ static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id) { + struct intel_scu_ipc_dev *scu = &ipcdev; int nc; u32 offset = 0; int err; @@ -223,7 +228,7 @@ static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id) mutex_lock(&ipclock); - if (ipcdev.pdev == NULL) { + if (scu->pdev == NULL) { mutex_unlock(&ipclock); return -ENODEV; } @@ -235,27 +240,27 @@ static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id) if (id == IPC_CMD_PCNTRL_R) { for (nc = 0, offset = 0; nc < count; nc++, offset += 4) - ipc_data_writel(wbuf[nc], offset); - ipc_command((count * 2) << 16 | id << 12 | 0 << 8 | op); + ipc_data_writel(scu, wbuf[nc], offset); + ipc_command(scu, (count * 2) << 16 | id << 12 | 0 << 8 | op); } else if (id == IPC_CMD_PCNTRL_W) { for (nc = 0; nc < count; nc++, offset += 1) cbuf[offset] = data[nc]; for (nc = 0, offset = 0; nc < count; nc++, offset += 4) - ipc_data_writel(wbuf[nc], offset); - ipc_command((count * 3) << 16 | id << 12 | 0 << 8 | op); + ipc_data_writel(scu, wbuf[nc], offset); + ipc_command(scu, (count * 3) << 16 | id << 12 | 0 << 8 | op); } else if (id == IPC_CMD_PCNTRL_M) { cbuf[offset] = data[0]; cbuf[offset + 1] = data[1]; - ipc_data_writel(wbuf[0], 0); /* Write wbuff */ - ipc_command(4 << 16 | id << 12 | 0 << 8 | op); + ipc_data_writel(scu, wbuf[0], 0); /* Write wbuff */ + ipc_command(scu, 4 << 16 | id << 12 | 0 << 8 | op); } - err = intel_scu_ipc_check_status(); + err = intel_scu_ipc_check_status(scu); if (!err && id == IPC_CMD_PCNTRL_R) { /* Read rbuf */ /* Workaround: values are read as 0 without memcpy_fromio */ - memcpy_fromio(cbuf, ipcdev.ipc_base + 0x90, 16); + memcpy_fromio(cbuf, scu->ipc_base + 0x90, 16); for (nc = 0; nc < count; nc++) - data[nc] = ipc_data_readb(nc); + data[nc] = ipc_data_readb(scu, nc); } mutex_unlock(&ipclock); return err; @@ -436,15 +441,16 @@ EXPORT_SYMBOL(intel_scu_ipc_update_register); */ int intel_scu_ipc_simple_command(int cmd, int sub) { + struct intel_scu_ipc_dev *scu = &ipcdev; int err; mutex_lock(&ipclock); - if (ipcdev.pdev == NULL) { + if (scu->pdev == NULL) { mutex_unlock(&ipclock); return -ENODEV; } - ipc_command(sub << 12 | cmd); - err = intel_scu_ipc_check_status(); + ipc_command(scu, sub << 12 | cmd); + err = intel_scu_ipc_check_status(scu); mutex_unlock(&ipclock); return err; } @@ -465,23 +471,24 @@ EXPORT_SYMBOL(intel_scu_ipc_simple_command); int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen, u32 *out, int outlen) { + struct intel_scu_ipc_dev *scu = &ipcdev; int i, err; mutex_lock(&ipclock); - if (ipcdev.pdev == NULL) { + if (scu->pdev == NULL) { mutex_unlock(&ipclock); return -ENODEV; } for (i = 0; i < inlen; i++) - ipc_data_writel(*in++, 4 * i); + ipc_data_writel(scu, *in++, 4 * i); - ipc_command((inlen << 16) | (sub << 12) | cmd); - err = intel_scu_ipc_check_status(); + ipc_command(scu, (inlen << 16) | (sub << 12) | cmd); + err = intel_scu_ipc_check_status(scu); if (!err) { for (i = 0; i < outlen; i++) - *out++ = ipc_data_readl(4 * i); + *out++ = ipc_data_readl(scu, 4 * i); } mutex_unlock(&ipclock); @@ -507,25 +514,26 @@ EXPORT_SYMBOL(intel_scu_ipc_command); */ int intel_scu_ipc_i2c_cntrl(u32 addr, u32 *data) { + struct intel_scu_ipc_dev *scu = &ipcdev; u32 cmd = 0; mutex_lock(&ipclock); - if (ipcdev.pdev == NULL) { + if (scu->pdev == NULL) { mutex_unlock(&ipclock); return -ENODEV; } cmd = (addr >> 24) & 0xFF; if (cmd == IPC_I2C_READ) { - writel(addr, ipcdev.i2c_base + IPC_I2C_CNTRL_ADDR); + writel(addr, scu->i2c_base + IPC_I2C_CNTRL_ADDR); /* Write not getting updated without delay */ mdelay(1); - *data = readl(ipcdev.i2c_base + I2C_DATA_ADDR); + *data = readl(scu->i2c_base + I2C_DATA_ADDR); } else if (cmd == IPC_I2C_WRITE) { - writel(*data, ipcdev.i2c_base + I2C_DATA_ADDR); + writel(*data, scu->i2c_base + I2C_DATA_ADDR); mdelay(1); - writel(addr, ipcdev.i2c_base + IPC_I2C_CNTRL_ADDR); + writel(addr, scu->i2c_base + IPC_I2C_CNTRL_ADDR); } else { - dev_err(&ipcdev.pdev->dev, + dev_err(&scu->pdev->dev, "intel_scu_ipc: I2C INVALID_CMD = 0x%x\n", cmd); mutex_unlock(&ipclock); @@ -545,8 +553,10 @@ EXPORT_SYMBOL(intel_scu_ipc_i2c_cntrl); */ static irqreturn_t ioc(int irq, void *dev_id) { - if (ipcdev.irq_mode) - complete(&ipcdev.cmd_complete); + struct intel_scu_ipc_dev *scu = dev_id; + + if (scu->irq_mode) + complete(&scu->cmd_complete); return IRQ_HANDLED; } @@ -562,15 +572,16 @@ static irqreturn_t ioc(int irq, void *dev_id) static int ipc_probe(struct pci_dev *dev, const struct pci_device_id *id) { int err; + struct intel_scu_ipc_dev *scu = &ipcdev; struct intel_scu_ipc_pdata_t *pdata; - if (ipcdev.pdev) /* We support only one SCU */ + if (scu->pdev) /* We support only one SCU */ return -EBUSY; pdata = (struct intel_scu_ipc_pdata_t *)id->driver_data; - ipcdev.pdev = pci_dev_get(dev); - ipcdev.irq_mode = pdata->irq_mode; + scu->pdev = pci_dev_get(dev); + scu->irq_mode = pdata->irq_mode; err = pcim_enable_device(dev); if (err) @@ -580,21 +591,22 @@ static int ipc_probe(struct pci_dev *dev, const struct pci_device_id *id) if (err) return err; - init_completion(&ipcdev.cmd_complete); + init_completion(&scu->cmd_complete); err = devm_request_irq(&dev->dev, dev->irq, ioc, 0, "intel_scu_ipc", - &ipcdev); + scu); if (err) return err; - ipcdev.ipc_base = pcim_iomap_table(dev)[0]; + scu->ipc_base = pcim_iomap_table(dev)[0]; - ipcdev.i2c_base = ioremap_nocache(pdata->i2c_base, pdata->i2c_len); - if (!ipcdev.i2c_base) + scu->i2c_base = ioremap_nocache(pdata->i2c_base, pdata->i2c_len); + if (!scu->i2c_base) return -ENOMEM; intel_scu_devices_create(); + pci_set_drvdata(dev, scu); return 0; } @@ -610,9 +622,11 @@ static int ipc_probe(struct pci_dev *dev, const struct pci_device_id *id) */ static void ipc_remove(struct pci_dev *pdev) { - pci_dev_put(ipcdev.pdev); - iounmap(ipcdev.i2c_base); - ipcdev.pdev = NULL; + struct intel_scu_ipc_dev *scu = pci_get_drvdata(pdev); + + pci_dev_put(scu->pdev); + scu->pdev = NULL; + iounmap(scu->i2c_base); intel_scu_devices_destroy(); }